17
17
* You should have received a copy of the GNU Lesser General Public
18
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
21
21
#include <stdarg.h>
22
22
#include <stdlib.h>
24
24
#include <string.h>
25
25
#include <inttypes.h>
27
28
#include "config.h"
29
30
#include "exec-all.h"
31
#include "m68k-qreg.h"
33
39
//#define DEBUG_DISPATCH 1
41
/* Fake floating point. */
42
#define tcg_gen_mov_f64 tcg_gen_mov_i64
43
#define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64
44
#define tcg_gen_qemu_stf64 tcg_gen_qemu_st64
46
#define DEFO32(name, offset) static TCGv QREG_##name;
47
#define DEFO64(name, offset) static TCGv_i64 QREG_##name;
48
#define DEFF64(name, offset) static TCGv_i64 QREG_##name;
54
static TCGv_ptr cpu_env;
56
static char cpu_reg_names[3*8*3 + 5*4];
57
static TCGv cpu_dregs[8];
58
static TCGv cpu_aregs[8];
59
static TCGv_i64 cpu_fregs[8];
60
static TCGv_i64 cpu_macc[4];
62
#define DREG(insn, pos) cpu_dregs[((insn) >> (pos)) & 7]
63
#define AREG(insn, pos) cpu_aregs[((insn) >> (pos)) & 7]
64
#define FREG(insn, pos) cpu_fregs[((insn) >> (pos)) & 7]
65
#define MACREG(acc) cpu_macc[acc]
66
#define QREG_SP cpu_aregs[7]
68
static TCGv NULL_QREG;
69
#define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG))
70
/* Used to distinguish stores from bad addressing modes. */
71
static TCGv store_dummy;
73
#include "gen-icount.h"
75
void m68k_tcg_init(void)
80
#define DEFO32(name, offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, offset), #name);
81
#define DEFO64(name, offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, offset), #name);
82
#define DEFF64(name, offset) DEFO64(name, offset)
88
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
91
for (i = 0; i < 8; i++) {
93
cpu_dregs[i] = tcg_global_mem_new(TCG_AREG0,
94
offsetof(CPUM68KState, dregs[i]), p);
97
cpu_aregs[i] = tcg_global_mem_new(TCG_AREG0,
98
offsetof(CPUM68KState, aregs[i]), p);
100
sprintf(p, "F%d", i);
101
cpu_fregs[i] = tcg_global_mem_new_i64(TCG_AREG0,
102
offsetof(CPUM68KState, fregs[i]), p);
105
for (i = 0; i < 4; i++) {
106
sprintf(p, "ACC%d", i);
107
cpu_macc[i] = tcg_global_mem_new_i64(TCG_AREG0,
108
offsetof(CPUM68KState, macc[i]), p);
112
NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
113
store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
35
119
static inline void qemu_assert(int cond, const char *msg)
67
153
static void *gen_throws_exception;
68
154
#define gen_last_qop NULL
70
static uint16_t *gen_opc_ptr;
71
static uint32_t *gen_opparam_ptr;
76
#define DEF(s, n, copy_size) INDEX_op_ ## s,
84
#if defined(CONFIG_USER_ONLY)
85
#define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
86
#define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
88
#define gen_st(s, name, addr, val) do { \
90
gen_op_st##name##_user(addr, val); \
92
gen_op_st##name##_kernel(addr, val); \
94
#define gen_ld(s, name, val, addr) do { \
96
gen_op_ld##name##_user(val, addr); \
98
gen_op_ld##name##_kernel(val, addr); \
102
#include "op-hacks.h"
104
156
#define OS_BYTE 0
105
157
#define OS_WORD 1
106
158
#define OS_LONG 2
107
159
#define OS_SINGLE 4
108
160
#define OS_DOUBLE 5
110
#define DREG(insn, pos) (((insn >> pos) & 7) + QREG_D0)
111
#define AREG(insn, pos) (((insn >> pos) & 7) + QREG_A0)
112
#define FREG(insn, pos) (((insn >> pos) & 7) + QREG_F0)
114
162
typedef void (*disas_proc)(DisasContext *, uint16_t);
116
164
#ifdef DEBUG_DISPATCH
117
165
#define DISAS_INSN(name) \
118
166
static void real_disas_##name (DisasContext *s, uint16_t insn); \
119
167
static void disas_##name (DisasContext *s, uint16_t insn) { \
120
if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
168
qemu_log("Dispatch " #name "\n"); \
121
169
real_disas_##name(s, insn); } \
122
170
static void real_disas_##name (DisasContext *s, uint16_t insn)
125
173
static void disas_##name (DisasContext *s, uint16_t insn)
176
/* FIXME: Remove this. */
177
#define gen_im32(val) tcg_const_i32(val)
128
179
/* Generate a load from the specified address. Narrow values are
129
180
sign extended to full register width. */
130
static inline int gen_load(DisasContext * s, int opsize, int addr, int sign)
181
static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
184
int index = IS_USER(s);
186
tmp = tcg_temp_new_i32();
136
tmp = gen_new_qreg(QMODE_I32);
138
gen_ld(s, 8s32, tmp, addr);
190
tcg_gen_qemu_ld8s(tmp, addr, index);
140
gen_ld(s, 8u32, tmp, addr);
192
tcg_gen_qemu_ld8u(tmp, addr, index);
143
tmp = gen_new_qreg(QMODE_I32);
145
gen_ld(s, 16s32, tmp, addr);
196
tcg_gen_qemu_ld16s(tmp, addr, index);
147
gen_ld(s, 16u32, tmp, addr);
198
tcg_gen_qemu_ld16u(tmp, addr, index);
150
tmp = gen_new_qreg(QMODE_I32);
151
gen_ld(s, 32, tmp, addr);
154
tmp = gen_new_qreg(QMODE_F32);
155
gen_ld(s, f32, tmp, addr);
158
tmp = gen_new_qreg(QMODE_F64);
159
gen_ld(s, f64, tmp, addr);
202
tcg_gen_qemu_ld32u(tmp, addr, index);
162
205
qemu_assert(0, "bad load size");
363
440
case OS_DOUBLE: return 8;
365
442
qemu_assert(0, "bad operand size");
369
447
/* Assign value to a register. If the width is less than the register width
370
448
only the low part of the register is set. */
371
static void gen_partset_reg(int opsize, int reg, int val)
449
static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
374
452
switch (opsize) {
376
gen_op_and32(reg, reg, gen_im32(0xffffff00));
377
tmp = gen_new_qreg(QMODE_I32);
378
gen_op_and32(tmp, val, gen_im32(0xff));
379
gen_op_or32(reg, reg, tmp);
454
tcg_gen_andi_i32(reg, reg, 0xffffff00);
455
tmp = tcg_temp_new();
456
tcg_gen_ext8u_i32(tmp, val);
457
tcg_gen_or_i32(reg, reg, tmp);
382
gen_op_and32(reg, reg, gen_im32(0xffff0000));
383
tmp = gen_new_qreg(QMODE_I32);
384
gen_op_and32(tmp, val, gen_im32(0xffff));
385
gen_op_or32(reg, reg, tmp);
460
tcg_gen_andi_i32(reg, reg, 0xffff0000);
461
tmp = tcg_temp_new();
462
tcg_gen_ext16u_i32(tmp, val);
463
tcg_gen_or_i32(reg, reg, tmp);
388
gen_op_mov32(reg, val);
391
gen_op_pack_32_f32(reg, val);
467
tcg_gen_mov_i32(reg, val);
394
470
qemu_assert(0, "Bad operand size");
472
543
offset = read_im32(s);
473
544
return gen_im32(offset);
474
545
case 2: /* pc displacement */
475
tmp = gen_new_qreg(QMODE_I32);
546
tmp = tcg_temp_new();
477
548
offset += ldsw_code(s->pc);
479
550
return gen_im32(offset);
480
551
case 3: /* pc index+displacement. */
481
return gen_lea_indexed(s, opsize, -1);
552
return gen_lea_indexed(s, opsize, NULL_QREG);
482
553
case 4: /* Immediate. */
487
558
/* Should never happen. */
491
562
/* Helper function for gen_ea. Reuse the computed address between the
492
563
for read/write operands. */
493
static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
564
static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
565
TCGv val, TCGv *addrp, ea_what what)
498
if (addrp && val > 0) {
569
if (addrp && what == EA_STORE) {
501
572
tmp = gen_lea(s, insn, opsize);
573
if (IS_NULL_QREG(tmp))
507
return gen_ldst(s, opsize, tmp, val);
578
return gen_ldst(s, opsize, tmp, val, what);
510
581
/* Generate code to load/store a value ito/from an EA. If VAL > 0 this is
511
582
a write otherwise it is a read (0 == sign extend, -1 == zero extend).
512
583
ADDRP is non-null for readwrite operands. */
513
static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val,
584
static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
585
TCGv *addrp, ea_what what)
521
591
switch ((insn >> 3) & 7) {
522
592
case 0: /* Data register direct. */
594
if (what == EA_STORE) {
525
595
gen_partset_reg(opsize, reg, val);
528
return gen_extend(reg, opsize, val);
598
return gen_extend(reg, opsize, what == EA_LOADS);
530
600
case 1: /* Address register direct. */
533
gen_op_mov32(reg, val);
602
if (what == EA_STORE) {
603
tcg_gen_mov_i32(reg, val);
536
return gen_extend(reg, opsize, val);
606
return gen_extend(reg, opsize, what == EA_LOADS);
538
608
case 2: /* Indirect register */
540
return gen_ldst(s, opsize, reg, val);
610
return gen_ldst(s, opsize, reg, val, what);
541
611
case 3: /* Indirect postincrement. */
543
result = gen_ldst(s, opsize, reg, val);
613
result = gen_ldst(s, opsize, reg, val, what);
544
614
/* ??? This is not exception safe. The instruction may still
545
615
fault after this point. */
546
if (val > 0 || !addrp)
547
gen_op_add32(reg, reg, gen_im32(opsize_bytes(opsize)));
616
if (what == EA_STORE || !addrp)
617
tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize));
549
619
case 4: /* Indirect predecrememnt. */
552
if (addrp && val > 0) {
622
if (addrp && what == EA_STORE) {
555
625
tmp = gen_lea(s, insn, opsize);
626
if (IS_NULL_QREG(tmp))
561
result = gen_ldst(s, opsize, tmp, val);
631
result = gen_ldst(s, opsize, tmp, val, what);
562
632
/* ??? This is not exception safe. The instruction may still
563
633
fault after this point. */
564
if (val > 0 || !addrp) {
566
gen_op_mov32(reg, tmp);
634
if (what == EA_STORE || !addrp) {
636
tcg_gen_mov_i32(reg, tmp);
570
640
case 5: /* Indirect displacement. */
571
641
case 6: /* Indirect index + displacement. */
572
return gen_ea_once(s, insn, opsize, val, addrp);
642
return gen_ea_once(s, insn, opsize, val, addrp, what);
573
643
case 7: /* Other */
575
645
case 0: /* Absolute short. */
576
646
case 1: /* Absolute long. */
577
647
case 2: /* pc displacement */
578
648
case 3: /* pc index+displacement. */
579
return gen_ea_once(s, insn, opsize, val, addrp);
649
return gen_ea_once(s, insn, opsize, val, addrp, what);
580
650
case 4: /* Immediate. */
581
651
/* Sign extend values for consistency. */
582
652
switch (opsize) {
654
if (what == EA_LOADS)
585
655
offset = ldsb_code(s->pc + 1);
587
657
offset = ldub_code(s->pc + 1);
661
if (what == EA_LOADS)
592
662
offset = ldsw_code(s->pc);
594
664
offset = lduw_code(s->pc);
601
671
qemu_assert(0, "Bad immediate operand");
603
return gen_im32(offset);
673
return tcg_const_i32(offset);
608
678
/* Should never happen. */
612
static void gen_logic_cc(DisasContext *s, int val)
614
gen_op_logic_cc(val);
615
s->cc_op = CC_OP_LOGIC;
682
/* This generates a conditional branch, clobbering all temporaries. */
618
683
static void gen_jmpcc(DisasContext *s, int cond, int l1)
687
/* TODO: Optimize compare/branch pairs rather than always flushing
688
flag state to CC_OP_FLAGS. */
622
689
gen_flush_flags(s);
629
696
case 2: /* HI (!C && !Z) */
630
tmp = gen_new_qreg(QMODE_I32);
631
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
632
gen_op_jmp_z32(tmp, l1);
697
tmp = tcg_temp_new();
698
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
699
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
634
701
case 3: /* LS (C || Z) */
635
tmp = gen_new_qreg(QMODE_I32);
636
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));
637
gen_op_jmp_nz32(tmp, l1);
702
tmp = tcg_temp_new();
703
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
704
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
639
706
case 4: /* CC (!C) */
640
tmp = gen_new_qreg(QMODE_I32);
641
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
642
gen_op_jmp_z32(tmp, l1);
707
tmp = tcg_temp_new();
708
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
709
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
644
711
case 5: /* CS (C) */
645
tmp = gen_new_qreg(QMODE_I32);
646
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));
647
gen_op_jmp_nz32(tmp, l1);
712
tmp = tcg_temp_new();
713
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
714
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
649
716
case 6: /* NE (!Z) */
650
tmp = gen_new_qreg(QMODE_I32);
651
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
652
gen_op_jmp_z32(tmp, l1);
717
tmp = tcg_temp_new();
718
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
719
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
654
721
case 7: /* EQ (Z) */
655
tmp = gen_new_qreg(QMODE_I32);
656
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
657
gen_op_jmp_nz32(tmp, l1);
722
tmp = tcg_temp_new();
723
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
724
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
659
726
case 8: /* VC (!V) */
660
tmp = gen_new_qreg(QMODE_I32);
661
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
662
gen_op_jmp_z32(tmp, l1);
727
tmp = tcg_temp_new();
728
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
729
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
664
731
case 9: /* VS (V) */
665
tmp = gen_new_qreg(QMODE_I32);
666
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));
667
gen_op_jmp_nz32(tmp, l1);
732
tmp = tcg_temp_new();
733
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
734
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
669
736
case 10: /* PL (!N) */
670
tmp = gen_new_qreg(QMODE_I32);
671
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
672
gen_op_jmp_z32(tmp, l1);
737
tmp = tcg_temp_new();
738
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
739
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
674
741
case 11: /* MI (N) */
675
tmp = gen_new_qreg(QMODE_I32);
676
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));
677
gen_op_jmp_nz32(tmp, l1);
742
tmp = tcg_temp_new();
743
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
744
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
679
746
case 12: /* GE (!(N ^ V)) */
680
tmp = gen_new_qreg(QMODE_I32);
681
gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
682
gen_op_xor32(tmp, tmp, QREG_CC_DEST);
683
gen_op_and32(tmp, tmp, gen_im32(CCF_V));
684
gen_op_jmp_z32(tmp, l1);
747
tmp = tcg_temp_new();
748
assert(CCF_V == (CCF_N >> 2));
749
tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
750
tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
751
tcg_gen_andi_i32(tmp, tmp, CCF_V);
752
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
686
754
case 13: /* LT (N ^ V) */
687
tmp = gen_new_qreg(QMODE_I32);
688
gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
689
gen_op_xor32(tmp, tmp, QREG_CC_DEST);
690
gen_op_and32(tmp, tmp, gen_im32(CCF_V));
691
gen_op_jmp_nz32(tmp, l1);
755
tmp = tcg_temp_new();
756
assert(CCF_V == (CCF_N >> 2));
757
tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
758
tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
759
tcg_gen_andi_i32(tmp, tmp, CCF_V);
760
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
693
762
case 14: /* GT (!(Z || (N ^ V))) */
696
l2 = gen_new_label();
697
tmp = gen_new_qreg(QMODE_I32);
698
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
699
gen_op_jmp_nz32(tmp, l2);
700
tmp = gen_new_qreg(QMODE_I32);
701
gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
702
gen_op_xor32(tmp, tmp, QREG_CC_DEST);
703
gen_op_and32(tmp, tmp, gen_im32(CCF_V));
704
gen_op_jmp_nz32(tmp, l2);
763
tmp = tcg_temp_new();
764
assert(CCF_V == (CCF_N >> 2));
765
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
766
tcg_gen_shri_i32(tmp, tmp, 2);
767
tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
768
tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
769
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
709
771
case 15: /* LE (Z || (N ^ V)) */
710
tmp = gen_new_qreg(QMODE_I32);
711
gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));
712
gen_op_jmp_nz32(tmp, l1);
713
tmp = gen_new_qreg(QMODE_I32);
714
gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));
715
gen_op_xor32(tmp, tmp, QREG_CC_DEST);
716
gen_op_and32(tmp, tmp, gen_im32(CCF_V));
717
gen_op_jmp_nz32(tmp, l1);
772
tmp = tcg_temp_new();
773
assert(CCF_V == (CCF_N >> 2));
774
tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
775
tcg_gen_shri_i32(tmp, tmp, 2);
776
tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
777
tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);
778
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
720
781
/* Should ever happen. */
830
899
sign = (insn & 0x100) != 0;
831
900
reg = DREG(insn, 9);
832
tmp = gen_new_qreg(QMODE_I32);
901
tmp = tcg_temp_new();
834
gen_op_ext16s32(tmp, reg);
903
tcg_gen_ext16s_i32(tmp, reg);
836
gen_op_ext16u32(tmp, reg);
837
SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
838
gen_op_mul32(tmp, tmp, src);
839
gen_op_mov32(reg, tmp);
905
tcg_gen_ext16u_i32(tmp, reg);
906
SRC_EA(src, OS_WORD, sign, NULL);
907
tcg_gen_mul_i32(tmp, tmp, src);
908
tcg_gen_mov_i32(reg, tmp);
840
909
/* Unlike m68k, coldfire always clears the overflow bit. */
841
910
gen_logic_cc(s, tmp);
851
920
sign = (insn & 0x100) != 0;
852
921
reg = DREG(insn, 9);
854
gen_op_ext16s32(QREG_DIV1, reg);
923
tcg_gen_ext16s_i32(QREG_DIV1, reg);
856
gen_op_ext16u32(QREG_DIV1, reg);
925
tcg_gen_ext16u_i32(QREG_DIV1, reg);
858
SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);
859
gen_op_mov32(QREG_DIV2, src);
927
SRC_EA(src, OS_WORD, sign, NULL);
928
tcg_gen_mov_i32(QREG_DIV2, src);
930
gen_helper_divs(cpu_env, tcg_const_i32(1));
932
gen_helper_divu(cpu_env, tcg_const_i32(1));
866
tmp = gen_new_qreg(QMODE_I32);
867
src = gen_new_qreg(QMODE_I32);
868
gen_op_ext16u32(tmp, QREG_DIV1);
869
gen_op_shl32(src, QREG_DIV2, gen_im32(16));
870
gen_op_or32(reg, tmp, src);
935
tmp = tcg_temp_new();
936
src = tcg_temp_new();
937
tcg_gen_ext16u_i32(tmp, QREG_DIV1);
938
tcg_gen_shli_i32(src, QREG_DIV2, 16);
939
tcg_gen_or_i32(reg, tmp, src);
872
940
s->cc_op = CC_OP_FLAGS;
882
950
ext = lduw_code(s->pc);
946
1013
/* Reverse the order of the bits in REG. */
947
1014
DISAS_INSN(bitrev)
954
val = gen_new_qreg(QMODE_I32);
955
tmp1 = gen_new_qreg(QMODE_I32);
956
tmp2 = gen_new_qreg(QMODE_I32);
957
1017
reg = DREG(insn, 0);
958
gen_op_mov32(val, reg);
959
/* Reverse bits within each nibble. */
960
gen_op_shl32(tmp1, val, gen_im32(3));
961
gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));
962
gen_op_shl32(tmp2, val, gen_im32(1));
963
gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));
964
gen_op_or32(tmp1, tmp1, tmp2);
965
gen_op_shr32(tmp2, val, gen_im32(1));
966
gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));
967
gen_op_or32(tmp1, tmp1, tmp2);
968
gen_op_shr32(tmp2, val, gen_im32(3));
969
gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));
970
gen_op_or32(tmp1, tmp1, tmp2);
971
/* Reverse nibbles withing bytes. */
972
gen_op_shl32(val, tmp1, gen_im32(4));
973
gen_op_and32(val, val, gen_im32(0xf0f0f0f0));
974
gen_op_shr32(tmp2, tmp1, gen_im32(4));
975
gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));
976
gen_op_or32(val, val, tmp2);
978
gen_op_bswap32(reg, val);
979
gen_op_mov32(reg, val);
1018
gen_helper_bitrev(reg, reg);
982
1021
DISAS_INSN(bitop_reg)
992
1031
if ((insn & 0x38) != 0)
993
1032
opsize = OS_BYTE;
996
1035
op = (insn >> 6) & 3;
997
1036
SRC_EA(src1, opsize, 0, op ? &addr: NULL);
998
1037
src2 = DREG(insn, 9);
999
dest = gen_new_qreg(QMODE_I32);
1038
dest = tcg_temp_new();
1001
1040
gen_flush_flags(s);
1002
tmp = gen_new_qreg(QMODE_I32);
1041
tmp = tcg_temp_new();
1003
1042
if (opsize == OS_BYTE)
1004
gen_op_and32(tmp, src2, gen_im32(7));
1043
tcg_gen_andi_i32(tmp, src2, 7);
1006
gen_op_and32(tmp, src2, gen_im32(31));
1045
tcg_gen_andi_i32(tmp, src2, 31);
1008
tmp = gen_new_qreg(QMODE_I32);
1009
gen_op_shl32(tmp, gen_im32(1), src2);
1047
tmp = tcg_temp_new();
1048
tcg_gen_shr_i32(tmp, src1, src2);
1049
tcg_gen_andi_i32(tmp, tmp, 1);
1050
tcg_gen_shli_i32(tmp, tmp, 2);
1051
/* Clear CCF_Z if bit set. */
1052
tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1053
tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1011
gen_op_btest(src1, tmp);
1055
tcg_gen_shl_i32(tmp, tcg_const_i32(1), src2);
1013
1057
case 1: /* bchg */
1014
gen_op_xor32(dest, src1, tmp);
1058
tcg_gen_xor_i32(dest, src1, tmp);
1016
1060
case 2: /* bclr */
1017
gen_op_not32(tmp, tmp);
1018
gen_op_and32(dest, src1, tmp);
1061
tcg_gen_not_i32(tmp, tmp);
1062
tcg_gen_and_i32(dest, src1, tmp);
1020
1064
case 3: /* bset */
1021
gen_op_or32(dest, src1, tmp);
1065
tcg_gen_or_i32(dest, src1, tmp);
1023
1067
default: /* btst */
1121
1153
SRC_EA(src1, opsize, 0, op ? &addr: NULL);
1123
1155
gen_flush_flags(s);
1124
tmp = gen_new_qreg(QMODE_I32);
1125
1156
if (opsize == OS_BYTE)
1129
1160
mask = 1 << bitnum;
1131
gen_op_btest(src1, gen_im32(mask));
1133
dest = gen_new_qreg(QMODE_I32);
1162
tmp = tcg_temp_new();
1163
assert (CCF_Z == (1 << 2));
1165
tcg_gen_shri_i32(tmp, src1, bitnum - 2);
1166
else if (bitnum < 2)
1167
tcg_gen_shli_i32(tmp, src1, 2 - bitnum);
1139
gen_op_xor32(dest, src1, gen_im32(mask));
1142
gen_op_and32(dest, src1, gen_im32(~mask));
1145
gen_op_or32(dest, src1, gen_im32(mask));
1169
tcg_gen_mov_i32(tmp, src1);
1170
tcg_gen_andi_i32(tmp, tmp, CCF_Z);
1171
/* Clear CCF_Z if bit set. */
1172
tcg_gen_ori_i32(QREG_CC_DEST, QREG_CC_DEST, CCF_Z);
1173
tcg_gen_xor_i32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1177
tcg_gen_xori_i32(tmp, src1, mask);
1180
tcg_gen_andi_i32(tmp, src1, ~mask);
1183
tcg_gen_ori_i32(tmp, src1, mask);
1188
DEST_EA(insn, opsize, tmp, &addr);
1151
DEST_EA(insn, opsize, dest, &addr);
1154
1192
DISAS_INSN(arith_im)
1162
1200
op = (insn >> 9) & 7;
1163
1201
SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
1164
src2 = gen_im32(read_im32(s));
1165
dest = gen_new_qreg(QMODE_I32);
1203
dest = tcg_temp_new();
1167
1205
case 0: /* ori */
1168
gen_op_or32(dest, src1, src2);
1206
tcg_gen_ori_i32(dest, src1, im);
1169
1207
gen_logic_cc(s, dest);
1171
1209
case 1: /* andi */
1172
gen_op_and32(dest, src1, src2);
1210
tcg_gen_andi_i32(dest, src1, im);
1173
1211
gen_logic_cc(s, dest);
1175
1213
case 2: /* subi */
1176
gen_op_mov32(dest, src1);
1177
gen_op_update_xflag_lt(dest, src2);
1178
gen_op_sub32(dest, dest, src2);
1179
gen_op_update_cc_add(dest, src2);
1214
tcg_gen_mov_i32(dest, src1);
1215
gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
1216
tcg_gen_subi_i32(dest, dest, im);
1217
gen_update_cc_add(dest, gen_im32(im));
1180
1218
s->cc_op = CC_OP_SUB;
1182
1220
case 3: /* addi */
1183
gen_op_mov32(dest, src1);
1184
gen_op_add32(dest, dest, src2);
1185
gen_op_update_cc_add(dest, src2);
1186
gen_op_update_xflag_lt(dest, src2);
1221
tcg_gen_mov_i32(dest, src1);
1222
tcg_gen_addi_i32(dest, dest, im);
1223
gen_update_cc_add(dest, gen_im32(im));
1224
gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
1187
1225
s->cc_op = CC_OP_ADD;
1189
1227
case 5: /* eori */
1190
gen_op_xor32(dest, src1, src2);
1228
tcg_gen_xori_i32(dest, src1, im);
1191
1229
gen_logic_cc(s, dest);
1193
1231
case 6: /* cmpi */
1194
gen_op_mov32(dest, src1);
1195
gen_op_sub32(dest, dest, src2);
1196
gen_op_update_cc_add(dest, src2);
1232
tcg_gen_mov_i32(dest, src1);
1233
tcg_gen_subi_i32(dest, dest, im);
1234
gen_update_cc_add(dest, gen_im32(im));
1197
1235
s->cc_op = CC_OP_SUB;
1332
1355
DISAS_INSN(neg)
1337
1360
reg = DREG(insn, 0);
1338
src1 = gen_new_qreg(QMODE_I32);
1339
gen_op_mov32(src1, reg);
1340
gen_op_neg32(reg, src1);
1361
src1 = tcg_temp_new();
1362
tcg_gen_mov_i32(src1, reg);
1363
tcg_gen_neg_i32(reg, src1);
1341
1364
s->cc_op = CC_OP_SUB;
1342
gen_op_update_cc_add(reg, src1);
1343
gen_op_update_xflag_lt(gen_im32(0), src1);
1365
gen_update_cc_add(reg, src1);
1366
gen_helper_xflag_lt(QREG_CC_X, tcg_const_i32(0), src1);
1344
1367
s->cc_op = CC_OP_SUB;
1347
1370
static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1349
gen_op_logic_cc(gen_im32(val & 0xf));
1350
gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1372
tcg_gen_movi_i32(QREG_CC_DEST, val & 0xf);
1373
tcg_gen_movi_i32(QREG_CC_X, (val & 0x10) >> 4);
1351
1374
if (!ccr_only) {
1352
gen_op_set_sr(gen_im32(val & 0xff00));
1375
gen_helper_set_sr(cpu_env, tcg_const_i32(val & 0xff00));
1356
1379
static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1361
1384
s->cc_op = CC_OP_FLAGS;
1362
1385
if ((insn & 0x38) == 0)
1364
src1 = gen_new_qreg(QMODE_I32);
1387
tmp = tcg_temp_new();
1365
1388
reg = DREG(insn, 0);
1366
gen_op_and32(src1, reg, gen_im32(0xf));
1367
gen_op_logic_cc(src1);
1368
gen_op_shr32(src1, reg, gen_im32(4));
1369
gen_op_and32(src1, src1, gen_im32(1));
1370
gen_op_update_xflag_tst(src1);
1389
tcg_gen_andi_i32(QREG_CC_DEST, reg, 0xf);
1390
tcg_gen_shri_i32(tmp, reg, 4);
1391
tcg_gen_andi_i32(QREG_CC_X, tmp, 1);
1371
1392
if (!ccr_only) {
1393
gen_helper_set_sr(cpu_env, reg);
1375
1396
else if ((insn & 0x3f) == 0x3c)
1582
1600
DISAS_INSN(addsubq)
1590
1608
SRC_EA(src1, OS_LONG, 0, &addr);
1591
1609
val = (insn >> 9) & 7;
1594
src2 = gen_im32(val);
1595
dest = gen_new_qreg(QMODE_I32);
1596
gen_op_mov32(dest, src1);
1612
dest = tcg_temp_new();
1613
tcg_gen_mov_i32(dest, src1);
1597
1614
if ((insn & 0x38) == 0x08) {
1598
1615
/* Don't update condition codes if the destination is an
1599
1616
address register. */
1600
1617
if (insn & 0x0100) {
1601
gen_op_sub32(dest, dest, src2);
1618
tcg_gen_subi_i32(dest, dest, val);
1603
gen_op_add32(dest, dest, src2);
1620
tcg_gen_addi_i32(dest, dest, val);
1623
src2 = gen_im32(val);
1606
1624
if (insn & 0x0100) {
1607
gen_op_update_xflag_lt(dest, src2);
1608
gen_op_sub32(dest, dest, src2);
1625
gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1626
tcg_gen_subi_i32(dest, dest, val);
1609
1627
s->cc_op = CC_OP_SUB;
1611
gen_op_add32(dest, dest, src2);
1612
gen_op_update_xflag_lt(dest, src2);
1629
tcg_gen_addi_i32(dest, dest, val);
1630
gen_helper_xflag_lt(QREG_CC_X, dest, src2);
1613
1631
s->cc_op = CC_OP_ADD;
1615
gen_op_update_cc_add(dest, src2);
1633
gen_update_cc_add(dest, src2);
1617
1635
DEST_EA(insn, OS_LONG, dest, &addr);
1670
1688
DISAS_INSN(moveq)
1674
tmp = gen_im32((int8_t)insn);
1675
gen_op_mov32(DREG(insn, 9), tmp);
1676
gen_logic_cc(s, tmp);
1693
tcg_gen_movi_i32(DREG(insn, 9), val);
1694
gen_logic_cc(s, tcg_const_i32(val));
1679
1697
DISAS_INSN(mvzs)
1685
1703
if (insn & 0x40)
1686
1704
opsize = OS_WORD;
1688
1706
opsize = OS_BYTE;
1689
SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL);
1707
SRC_EA(src, opsize, (insn & 0x80) == 0, NULL);
1690
1708
reg = DREG(insn, 9);
1691
gen_op_mov32(reg, src);
1709
tcg_gen_mov_i32(reg, src);
1692
1710
gen_logic_cc(s, src);
1702
1720
reg = DREG(insn, 9);
1703
dest = gen_new_qreg(QMODE_I32);
1721
dest = tcg_temp_new();
1704
1722
if (insn & 0x100) {
1705
1723
SRC_EA(src, OS_LONG, 0, &addr);
1706
gen_op_or32(dest, src, reg);
1724
tcg_gen_or_i32(dest, src, reg);
1707
1725
DEST_EA(insn, OS_LONG, dest, &addr);
1709
1727
SRC_EA(src, OS_LONG, 0, NULL);
1710
gen_op_or32(dest, src, reg);
1711
gen_op_mov32(reg, dest);
1728
tcg_gen_or_i32(dest, src, reg);
1729
tcg_gen_mov_i32(reg, dest);
1713
1731
gen_logic_cc(s, dest);
1716
1734
DISAS_INSN(suba)
1721
1739
SRC_EA(src, OS_LONG, 0, NULL);
1722
1740
reg = AREG(insn, 9);
1723
gen_op_sub32(reg, reg, src);
1741
tcg_gen_sub_i32(reg, reg, src);
1726
1744
DISAS_INSN(subx)
1733
1749
gen_flush_flags(s);
1734
1750
reg = DREG(insn, 9);
1735
1751
src = DREG(insn, 0);
1736
dest = gen_new_qreg(QMODE_I32);
1737
gen_op_mov32 (dest, reg);
1738
gen_op_subx_cc(dest, src);
1740
tmp = gen_new_qreg(QMODE_I32);
1741
gen_op_mov32 (tmp, QREG_CC_DEST);
1742
gen_op_update_cc_add(dest, src);
1743
gen_op_mov32(reg, dest);
1744
s->cc_op = CC_OP_DYNAMIC;
1746
gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1747
gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1748
s->cc_op = CC_OP_FLAGS;
1752
gen_helper_subx_cc(reg, cpu_env, reg, src);
1751
1755
DISAS_INSN(mov3q)
1756
1760
val = (insn >> 9) & 7;
1789
SRC_EA(src, opsize, -1, NULL);
1793
SRC_EA(src, opsize, 1, NULL);
1790
1794
reg = DREG(insn, 9);
1791
dest = gen_new_qreg(QMODE_I32);
1792
gen_op_sub32(dest, reg, src);
1793
gen_op_update_cc_add(dest, src);
1795
dest = tcg_temp_new();
1796
tcg_gen_sub_i32(dest, reg, src);
1797
gen_update_cc_add(dest, src);
1796
1800
DISAS_INSN(cmpa)
1803
1807
if (insn & 0x100) {
1804
1808
opsize = OS_LONG;
1806
1810
opsize = OS_WORD;
1808
SRC_EA(src, opsize, -1, NULL);
1812
SRC_EA(src, opsize, 1, NULL);
1809
1813
reg = AREG(insn, 9);
1810
dest = gen_new_qreg(QMODE_I32);
1811
gen_op_sub32(dest, reg, src);
1812
gen_op_update_cc_add(dest, src);
1814
dest = tcg_temp_new();
1815
tcg_gen_sub_i32(dest, reg, src);
1816
gen_update_cc_add(dest, src);
1813
1817
s->cc_op = CC_OP_SUB;
1816
1820
DISAS_INSN(eor)
1823
1827
SRC_EA(src, OS_LONG, 0, &addr);
1824
1828
reg = DREG(insn, 9);
1825
dest = gen_new_qreg(QMODE_I32);
1826
gen_op_xor32(dest, src, reg);
1829
dest = tcg_temp_new();
1830
tcg_gen_xor_i32(dest, src, reg);
1827
1831
gen_logic_cc(s, dest);
1828
1832
DEST_EA(insn, OS_LONG, dest, &addr);
1831
1835
DISAS_INSN(and)
1838
1842
reg = DREG(insn, 9);
1839
dest = gen_new_qreg(QMODE_I32);
1843
dest = tcg_temp_new();
1840
1844
if (insn & 0x100) {
1841
1845
SRC_EA(src, OS_LONG, 0, &addr);
1842
gen_op_and32(dest, src, reg);
1846
tcg_gen_and_i32(dest, src, reg);
1843
1847
DEST_EA(insn, OS_LONG, dest, &addr);
1845
1849
SRC_EA(src, OS_LONG, 0, NULL);
1846
gen_op_and32(dest, src, reg);
1847
gen_op_mov32(reg, dest);
1850
tcg_gen_and_i32(dest, src, reg);
1851
tcg_gen_mov_i32(reg, dest);
1849
1853
gen_logic_cc(s, dest);
1852
1856
DISAS_INSN(adda)
1857
1861
SRC_EA(src, OS_LONG, 0, NULL);
1858
1862
reg = AREG(insn, 9);
1859
gen_op_add32(reg, reg, src);
1863
tcg_gen_add_i32(reg, reg, src);
1862
1866
DISAS_INSN(addx)
1869
1871
gen_flush_flags(s);
1870
1872
reg = DREG(insn, 9);
1871
1873
src = DREG(insn, 0);
1872
dest = gen_new_qreg(QMODE_I32);
1873
gen_op_mov32 (dest, reg);
1874
gen_op_addx_cc(dest, src);
1876
tmp = gen_new_qreg(QMODE_I32);
1877
gen_op_mov32 (tmp, QREG_CC_DEST);
1878
gen_op_update_cc_add(dest, src);
1879
gen_op_mov32(reg, dest);
1880
s->cc_op = CC_OP_DYNAMIC;
1882
gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));
1883
gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);
1874
gen_helper_addx_cc(reg, cpu_env, reg, src);
1884
1875
s->cc_op = CC_OP_FLAGS;
1878
/* TODO: This could be implemented without helper functions. */
1887
1879
DISAS_INSN(shift_im)
1892
1885
reg = DREG(insn, 0);
1893
1886
tmp = (insn >> 9) & 7;
1889
shift = gen_im32(tmp);
1890
/* No need to flush flags becuse we know we will set C flag. */
1896
1891
if (insn & 0x100) {
1897
gen_op_shl_im_cc(reg, tmp);
1898
s->cc_op = CC_OP_SHL;
1892
gen_helper_shl_cc(reg, cpu_env, reg, shift);
1900
1894
if (insn & 8) {
1901
gen_op_shr_im_cc(reg, tmp);
1902
s->cc_op = CC_OP_SHR;
1895
gen_helper_shr_cc(reg, cpu_env, reg, shift);
1904
gen_op_sar_im_cc(reg, tmp);
1905
s->cc_op = CC_OP_SAR;
1897
gen_helper_sar_cc(reg, cpu_env, reg, shift);
1900
s->cc_op = CC_OP_SHIFT;
1910
1903
DISAS_INSN(shift_reg)
1916
1908
reg = DREG(insn, 0);
1917
src = DREG(insn, 9);
1918
tmp = gen_new_qreg(QMODE_I32);
1919
gen_op_and32(tmp, src, gen_im32(63));
1909
shift = DREG(insn, 9);
1910
/* Shift by zero leaves C flag unmodified. */
1920
1912
if (insn & 0x100) {
1921
gen_op_shl_cc(reg, tmp);
1922
s->cc_op = CC_OP_SHL;
1913
gen_helper_shl_cc(reg, cpu_env, reg, shift);
1924
1915
if (insn & 8) {
1925
gen_op_shr_cc(reg, tmp);
1926
s->cc_op = CC_OP_SHR;
1916
gen_helper_shr_cc(reg, cpu_env, reg, shift);
1928
gen_op_sar_cc(reg, tmp);
1929
s->cc_op = CC_OP_SAR;
1918
gen_helper_sar_cc(reg, cpu_env, reg, shift);
1921
s->cc_op = CC_OP_SHIFT;
1934
1924
DISAS_INSN(ff1)
1937
1927
reg = DREG(insn, 0);
1938
1928
gen_logic_cc(s, reg);
1939
gen_op_ff1(reg, reg);
1929
gen_helper_ff1(reg, reg);
1942
static int gen_get_sr(DisasContext *s)
1932
static TCGv gen_get_sr(DisasContext *s)
1947
1937
ccr = gen_get_ccr(s);
1948
sr = gen_new_qreg(QMODE_I32);
1949
gen_op_and32(sr, QREG_SR, gen_im32(0xffe0));
1950
gen_op_or32(sr, sr, ccr);
1938
sr = tcg_temp_new();
1939
tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
1940
tcg_gen_or_i32(sr, sr, ccr);
2132
2124
case 3: /* fmove out */
2133
2125
src = FREG(ext, 7);
2126
tmp32 = tcg_temp_new_i32();
2135
2128
/* ??? TODO: Proper behavior on overflow. */
2136
2129
switch ((ext >> 10) & 7) {
2138
2131
opsize = OS_LONG;
2139
res = gen_new_qreg(QMODE_I32);
2140
gen_op_f64_to_i32(res, src);
2132
gen_helper_f64_to_i32(tmp32, cpu_env, src);
2143
2135
opsize = OS_SINGLE;
2144
res = gen_new_qreg(QMODE_F32);
2145
gen_op_f64_to_f32(res, src);
2136
gen_helper_f64_to_f32(tmp32, cpu_env, src);
2148
2139
opsize = OS_WORD;
2149
res = gen_new_qreg(QMODE_I32);
2150
gen_op_f64_to_i32(res, src);
2140
gen_helper_f64_to_i32(tmp32, cpu_env, src);
2142
case 5: /* OS_DOUBLE */
2143
tcg_gen_mov_i32(tmp32, AREG(insn, 0));
2144
switch ((insn >> 3) & 7) {
2149
tcg_gen_addi_i32(tmp32, tmp32, -8);
2152
offset = ldsw_code(s->pc);
2154
tcg_gen_addi_i32(tmp32, tmp32, offset);
2159
gen_store64(s, tmp32, src);
2160
switch ((insn >> 3) & 7) {
2162
tcg_gen_addi_i32(tmp32, tmp32, 8);
2163
tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2166
tcg_gen_mov_i32(AREG(insn, 0), tmp32);
2169
tcg_temp_free_i32(tmp32);
2157
2172
opsize = OS_BYTE;
2158
res = gen_new_qreg(QMODE_I32);
2159
gen_op_f64_to_i32(res, src);
2173
gen_helper_f64_to_i32(tmp32, cpu_env, src);
2164
DEST_EA(insn, opsize, res, NULL);
2178
DEST_EA(insn, opsize, tmp32, NULL);
2179
tcg_temp_free_i32(tmp32);
2166
2181
case 4: /* fmove to control register. */
2167
2182
switch ((ext >> 10) & 7) {
2259
2306
src = FREG(ext, 10);
2261
2308
dest = FREG(ext, 7);
2262
res = gen_new_qreg(QMODE_F64);
2309
res = tcg_temp_new_i64();
2263
2310
if (opmode != 0x3a)
2264
gen_op_movf64(res, dest);
2311
tcg_gen_mov_f64(res, dest);
2266
2314
switch (opmode) {
2267
2315
case 0: case 0x40: case 0x44: /* fmove */
2268
gen_op_movf64(res, src);
2316
tcg_gen_mov_f64(res, src);
2270
2318
case 1: /* fint */
2271
gen_op_iround_f64(res, src);
2319
gen_helper_iround_f64(res, cpu_env, src);
2274
2322
case 3: /* fintrz */
2275
gen_op_itrunc_f64(res, src);
2323
gen_helper_itrunc_f64(res, cpu_env, src);
2278
2326
case 4: case 0x41: case 0x45: /* fsqrt */
2279
gen_op_sqrtf64(res, src);
2327
gen_helper_sqrt_f64(res, cpu_env, src);
2281
2329
case 0x18: case 0x58: case 0x5c: /* fabs */
2282
gen_op_absf64(res, src);
2330
gen_helper_abs_f64(res, src);
2284
2332
case 0x1a: case 0x5a: case 0x5e: /* fneg */
2285
gen_op_chsf64(res, src);
2333
gen_helper_chs_f64(res, src);
2287
2335
case 0x20: case 0x60: case 0x64: /* fdiv */
2288
gen_op_divf64(res, res, src);
2336
gen_helper_div_f64(res, cpu_env, res, src);
2290
2338
case 0x22: case 0x62: case 0x66: /* fadd */
2291
gen_op_addf64(res, res, src);
2339
gen_helper_add_f64(res, cpu_env, res, src);
2293
2341
case 0x23: case 0x63: case 0x67: /* fmul */
2294
gen_op_mulf64(res, res, src);
2342
gen_helper_mul_f64(res, cpu_env, res, src);
2296
2344
case 0x28: case 0x68: case 0x6c: /* fsub */
2297
gen_op_subf64(res, res, src);
2345
gen_helper_sub_f64(res, cpu_env, res, src);
2299
2347
case 0x38: /* fcmp */
2300
gen_op_sub_cmpf64(res, res, src);
2348
gen_helper_sub_cmp_f64(res, cpu_env, res, src);
2304
2352
case 0x3a: /* ftst */
2305
gen_op_movf64(res, src);
2353
tcg_gen_mov_f64(res, src);
2360
if (ext & (1 << 14)) {
2361
tcg_temp_free_i64(src);
2313
2364
if (opmode & 0x40) {
2314
2365
if ((opmode & 0x4) != 0)
2353
2404
l1 = gen_new_label();
2354
2405
/* TODO: Raise BSUN exception. */
2355
flag = gen_new_qreg(QMODE_I32);
2356
zero = gen_new_qreg(QMODE_F64);
2357
gen_op_zerof64(zero);
2358
gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);
2406
flag = tcg_temp_new();
2407
gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
2359
2408
/* Jump to l1 if condition is true. */
2360
2409
switch (insn & 0xf) {
2361
2410
case 0: /* f */
2363
2412
case 1: /* eq (=0) */
2364
gen_op_jmp_z32(flag, l1);
2413
tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2366
2415
case 2: /* ogt (=1) */
2367
gen_op_sub32(flag, flag, gen_im32(1));
2368
gen_op_jmp_z32(flag, l1);
2416
tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(1), l1);
2370
2418
case 3: /* oge (=0 or =1) */
2371
gen_op_jmp_z32(flag, l1);
2372
gen_op_sub32(flag, flag, gen_im32(1));
2373
gen_op_jmp_z32(flag, l1);
2419
tcg_gen_brcond_i32(TCG_COND_LEU, flag, tcg_const_i32(1), l1);
2375
2421
case 4: /* olt (=-1) */
2376
gen_op_jmp_s32(flag, l1);
2422
tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(0), l1);
2378
2424
case 5: /* ole (=-1 or =0) */
2379
gen_op_jmp_s32(flag, l1);
2380
gen_op_jmp_z32(flag, l1);
2425
tcg_gen_brcond_i32(TCG_COND_LE, flag, tcg_const_i32(0), l1);
2382
2427
case 6: /* ogl (=-1 or =1) */
2383
gen_op_jmp_s32(flag, l1);
2384
gen_op_sub32(flag, flag, gen_im32(1));
2385
gen_op_jmp_z32(flag, l1);
2428
tcg_gen_andi_i32(flag, flag, 1);
2429
tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2387
2431
case 7: /* or (=2) */
2388
gen_op_sub32(flag, flag, gen_im32(2));
2389
gen_op_jmp_z32(flag, l1);
2432
tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(2), l1);
2391
2434
case 8: /* un (<2) */
2392
gen_op_sub32(flag, flag, gen_im32(2));
2393
gen_op_jmp_s32(flag, l1);
2435
tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(2), l1);
2395
2437
case 9: /* ueq (=0 or =2) */
2396
gen_op_jmp_z32(flag, l1);
2397
gen_op_sub32(flag, flag, gen_im32(2));
2398
gen_op_jmp_z32(flag, l1);
2438
tcg_gen_andi_i32(flag, flag, 1);
2439
tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1);
2400
2441
case 10: /* ugt (>0) */
2401
/* ??? Add jmp_gtu. */
2402
gen_op_sub32(flag, flag, gen_im32(1));
2403
gen_op_jmp_ns32(flag, l1);
2442
tcg_gen_brcond_i32(TCG_COND_GT, flag, tcg_const_i32(0), l1);
2405
2444
case 11: /* uge (>=0) */
2406
gen_op_jmp_ns32(flag, l1);
2445
tcg_gen_brcond_i32(TCG_COND_GE, flag, tcg_const_i32(0), l1);
2408
2447
case 12: /* ult (=-1 or =2) */
2409
gen_op_jmp_s32(flag, l1);
2410
gen_op_sub32(flag, flag, gen_im32(2));
2411
gen_op_jmp_z32(flag, l1);
2448
tcg_gen_brcond_i32(TCG_COND_GEU, flag, tcg_const_i32(2), l1);
2413
2450
case 13: /* ule (!=1) */
2414
gen_op_sub32(flag, flag, gen_im32(1));
2415
gen_op_jmp_nz32(flag, l1);
2451
tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(1), l1);
2417
2453
case 14: /* ne (!=0) */
2418
gen_op_jmp_nz32(flag, l1);
2454
tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1);
2420
2456
case 15: /* t */
2421
gen_op_mov32(flag, gen_im32(1));
2424
2460
gen_jmp_tb(s, 0, s->pc);
2438
2474
qemu_assert(0, "FSAVE not implemented");
2441
static inline int gen_mac_extract_word(DisasContext *s, int val, int upper)
2477
static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
2443
int tmp = gen_new_qreg(QMODE_I32);
2479
TCGv tmp = tcg_temp_new();
2444
2480
if (s->env->macsr & MACSR_FI) {
2446
gen_op_and32(tmp, val, gen_im32(0xffff0000));
2482
tcg_gen_andi_i32(tmp, val, 0xffff0000);
2448
gen_op_shl32(tmp, val, gen_im32(16));
2484
tcg_gen_shli_i32(tmp, val, 16);
2449
2485
} else if (s->env->macsr & MACSR_SU) {
2451
gen_op_sar32(tmp, val, gen_im32(16));
2487
tcg_gen_sari_i32(tmp, val, 16);
2453
gen_op_ext16s32(tmp, val);
2489
tcg_gen_ext16s_i32(tmp, val);
2456
gen_op_shr32(tmp, val, gen_im32(16));
2492
tcg_gen_shri_i32(tmp, val, 16);
2458
gen_op_ext16u32(tmp, val);
2494
tcg_gen_ext16u_i32(tmp, val);
2499
static void gen_mac_clear_flags(void)
2501
tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR,
2502
~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV));
2463
2505
DISAS_INSN(mac)
2474
int saved_flags = -1;
2518
s->mactmp = tcg_temp_new_i64();
2476
2522
ext = lduw_code(s->pc);
2516
2565
ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);
2518
2567
if (s->env->macsr & MACSR_FI) {
2519
gen_op_macmulf(rx, ry);
2568
gen_helper_macmulf(s->mactmp, cpu_env, rx, ry);
2521
2570
if (s->env->macsr & MACSR_SU)
2522
gen_op_macmuls(rx, ry);
2571
gen_helper_macmuls(s->mactmp, cpu_env, rx, ry);
2524
gen_op_macmulu(rx, ry);
2573
gen_helper_macmulu(s->mactmp, cpu_env, rx, ry);
2525
2574
switch ((ext >> 9) & 3) {
2576
tcg_gen_shli_i64(s->mactmp, s->mactmp, 1);
2579
tcg_gen_shri_i64(s->mactmp, s->mactmp, 1);
2536
2585
/* Save the overflow flag from the multiply. */
2537
saved_flags = gen_new_qreg(QMODE_I32);
2538
gen_op_mov32(saved_flags, QREG_MACSR);
2586
saved_flags = tcg_temp_new();
2587
tcg_gen_mov_i32(saved_flags, QREG_MACSR);
2589
saved_flags = NULL_QREG;
2593
/* Disabled because conditional branches clobber temporary vars. */
2541
2594
if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
2542
2595
/* Skip the accumulate if the value is already saturated. */
2543
2596
l1 = gen_new_label();
2544
tmp = gen_new_qreg(QMODE_I32);
2597
tmp = tcg_temp_new();
2545
2598
gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2546
2599
gen_op_jmp_nz32(tmp, l1);
2549
2603
if (insn & 0x100)
2604
tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2606
tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2554
2608
if (s->env->macsr & MACSR_FI)
2555
gen_op_macsatf(acc);
2609
gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2556
2610
else if (s->env->macsr & MACSR_SU)
2557
gen_op_macsats(acc);
2611
gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2559
gen_op_macsatu(acc);
2613
gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2616
/* Disabled because conditional branches clobber temporary vars. */
2562
2618
gen_set_label(l1);
2565
2622
/* Dual accumulate variant. */
2566
2623
acc = (ext >> 2) & 3;
2567
2624
/* Restore the overflow flag from the multiplier. */
2568
gen_op_mov32(QREG_MACSR, saved_flags);
2625
tcg_gen_mov_i32(QREG_MACSR, saved_flags);
2627
/* Disabled because conditional branches clobber temporary vars. */
2569
2628
if ((s->env->macsr & MACSR_OMC) != 0) {
2570
2629
/* Skip the accumulate if the value is already saturated. */
2571
2630
l1 = gen_new_label();
2572
tmp = gen_new_qreg(QMODE_I32);
2631
tmp = tcg_temp_new();
2573
2632
gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
2574
2633
gen_op_jmp_nz32(tmp, l1);
2637
tcg_gen_sub_i64(MACREG(acc), MACREG(acc), s->mactmp);
2639
tcg_gen_add_i64(MACREG(acc), MACREG(acc), s->mactmp);
2580
2640
if (s->env->macsr & MACSR_FI)
2581
gen_op_macsatf(acc);
2641
gen_helper_macsatf(cpu_env, tcg_const_i32(acc));
2582
2642
else if (s->env->macsr & MACSR_SU)
2583
gen_op_macsats(acc);
2643
gen_helper_macsats(cpu_env, tcg_const_i32(acc));
2585
gen_op_macsatu(acc);
2645
gen_helper_macsatu(cpu_env, tcg_const_i32(acc));
2647
/* Disabled because conditional branches clobber temporary vars. */
2587
2649
gen_set_label(l1);
2589
gen_op_mac_set_flags(acc);
2652
gen_helper_mac_set_flags(cpu_env, tcg_const_i32(acc));
2591
2654
if (insn & 0x30) {
2593
2656
rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
2594
gen_op_mov32(rw, loadval);
2657
tcg_gen_mov_i32(rw, loadval);
2595
2658
/* FIXME: Should address writeback happen with the masked or
2596
2659
unmasked value? */
2597
2660
switch ((insn >> 3) & 7) {
2598
2661
case 3: /* Post-increment. */
2599
gen_op_add32(AREG(insn, 0), addr, gen_im32(4));
2662
tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
2601
2664
case 4: /* Pre-decrement. */
2602
gen_op_mov32(AREG(insn, 0), addr);
2665
tcg_gen_mov_i32(AREG(insn, 0), addr);
2607
2670
DISAS_INSN(from_mac)
2612
2676
rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2613
acc = (insn >> 9) & 3;
2677
accnum = (insn >> 9) & 3;
2678
acc = MACREG(accnum);
2614
2679
if (s->env->macsr & MACSR_FI) {
2615
gen_op_get_macf(rx, acc);
2680
gen_helper_get_macf(rx, cpu_env, acc);
2616
2681
} else if ((s->env->macsr & MACSR_OMC) == 0) {
2617
gen_op_get_maci(rx, acc);
2682
tcg_gen_trunc_i64_i32(rx, acc);
2618
2683
} else if (s->env->macsr & MACSR_SU) {
2619
gen_op_get_macs(rx, acc);
2684
gen_helper_get_macs(rx, acc);
2621
gen_op_get_macu(rx, acc);
2624
gen_op_clear_mac(acc);
2686
gen_helper_get_macu(rx, acc);
2689
tcg_gen_movi_i64(acc, 0);
2690
tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2627
2694
DISAS_INSN(move_mac)
2696
/* FIXME: This can be done without a helper. */
2631
2699
src = insn & 3;
2632
dest = (insn >> 9) & 3;
2633
gen_op_move_mac(dest, src);
2634
gen_op_mac_clear_flags();
2635
gen_op_mac_set_flags(dest);
2700
dest = tcg_const_i32((insn >> 9) & 3);
2701
gen_helper_mac_move(cpu_env, dest, tcg_const_i32(src));
2702
gen_mac_clear_flags();
2703
gen_helper_mac_set_flags(cpu_env, dest);
2638
2706
DISAS_INSN(from_macsr)
2642
2710
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2643
gen_op_mov32(reg, QREG_MACSR);
2711
tcg_gen_mov_i32(reg, QREG_MACSR);
2646
2714
DISAS_INSN(from_mask)
2649
2717
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2650
gen_op_mov32(reg, QREG_MAC_MASK);
2718
tcg_gen_mov_i32(reg, QREG_MAC_MASK);
2653
2721
DISAS_INSN(from_mext)
2657
2725
reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
2658
acc = (insn & 0x400) ? 2 : 0;
2726
acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2659
2727
if (s->env->macsr & MACSR_FI)
2660
gen_op_get_mac_extf(reg, acc);
2728
gen_helper_get_mac_extf(reg, cpu_env, acc);
2662
gen_op_get_mac_exti(reg, acc);
2730
gen_helper_get_mac_exti(reg, cpu_env, acc);
2665
2733
DISAS_INSN(macsr_to_ccr)
2667
gen_op_mov32(QREG_CC_X, gen_im32(0));
2668
gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));
2735
tcg_gen_movi_i32(QREG_CC_X, 0);
2736
tcg_gen_andi_i32(QREG_CC_DEST, QREG_MACSR, 0xf);
2669
2737
s->cc_op = CC_OP_FLAGS;
2672
2740
DISAS_INSN(to_mac)
2676
acc = (insn >>9) & 3;
2745
accnum = (insn >> 9) & 3;
2746
acc = MACREG(accnum);
2677
2747
SRC_EA(val, OS_LONG, 0, NULL);
2678
2748
if (s->env->macsr & MACSR_FI) {
2679
gen_op_set_macf(val, acc);
2749
tcg_gen_ext_i32_i64(acc, val);
2750
tcg_gen_shli_i64(acc, acc, 8);
2680
2751
} else if (s->env->macsr & MACSR_SU) {
2681
gen_op_set_macs(val, acc);
2752
tcg_gen_ext_i32_i64(acc, val);
2683
gen_op_set_macu(val, acc);
2754
tcg_gen_extu_i32_i64(acc, val);
2685
gen_op_mac_clear_flags();
2686
gen_op_mac_set_flags(acc);
2756
tcg_gen_andi_i32(QREG_MACSR, QREG_MACSR, ~(MACSR_PAV0 << accnum));
2757
gen_mac_clear_flags();
2758
gen_helper_mac_set_flags(cpu_env, tcg_const_i32(accnum));
2689
2761
DISAS_INSN(to_macsr)
2692
2764
SRC_EA(val, OS_LONG, 0, NULL);
2693
gen_op_set_macsr(val);
2765
gen_helper_set_macsr(cpu_env, val);
2694
2766
gen_lookup_tb(s);
2697
2769
DISAS_INSN(to_mask)
2700
2772
SRC_EA(val, OS_LONG, 0, NULL);
2701
gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));
2773
tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
2704
2776
DISAS_INSN(to_mext)
2708
2780
SRC_EA(val, OS_LONG, 0, NULL);
2709
acc = (insn & 0x400) ? 2 : 0;
2781
acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
2710
2782
if (s->env->macsr & MACSR_FI)
2711
gen_op_set_mac_extf(val, acc);
2783
gen_helper_set_mac_extf(cpu_env, val, acc);
2712
2784
else if (s->env->macsr & MACSR_SU)
2713
gen_op_set_mac_exts(val, acc);
2785
gen_helper_set_mac_exts(cpu_env, val, acc);
2715
gen_op_set_mac_extu(val, acc);
2787
gen_helper_set_mac_extu(cpu_env, val, acc);
2718
2790
static disas_proc opcode_table[65536];
2888
2960
opcode_table[insn](s, insn);
2892
/* Save the result of a floating point operation. */
2893
static void expand_op_fp_result(qOP *qop)
2895
gen_op_movf64(QREG_FP_RESULT, qop->args[0]);
2898
/* Dummy op to indicate that the flags have been set. */
2899
static void expand_op_flags_set(qOP *qop)
2903
/* Convert the confition codes into CC_OP_FLAGS format. */
2904
static void expand_op_flush_flags(qOP *qop)
2908
if (qop->args[0] == CC_OP_DYNAMIC)
2909
cc_opreg = QREG_CC_OP;
2911
cc_opreg = gen_im32(qop->args[0]);
2912
gen_op_helper32(QREG_NULL, cc_opreg, HELPER_flush_flags);
2915
/* Set CC_DEST after a logical or direct flag setting operation. */
2916
static void expand_op_logic_cc(qOP *qop)
2918
gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2921
/* Set CC_SRC and CC_DEST after an arithmetic operation. */
2922
static void expand_op_update_cc_add(qOP *qop)
2924
gen_op_mov32(QREG_CC_DEST, qop->args[0]);
2925
gen_op_mov32(QREG_CC_SRC, qop->args[1]);
2928
/* Update the X flag. */
2929
static void expand_op_update_xflag(qOP *qop)
2934
arg0 = qop->args[0];
2935
arg1 = qop->args[1];
2936
if (arg1 == QREG_NULL) {
2938
gen_op_mov32(QREG_CC_X, arg0);
2940
/* CC_X = arg0 < (unsigned)arg1. */
2941
gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
2945
/* Set arg0 to the contents of the X flag. */
2946
static void expand_op_get_xflag(qOP *qop)
2948
gen_op_mov32(qop->args[0], QREG_CC_X);
2951
/* Expand a shift by immediate. The ISA only allows shifts by 1-8, so we
2952
already know the shift is within range. */
2953
static inline void expand_shift_im(qOP *qop, int right, int arith)
2963
val = gen_new_qreg(QMODE_I32);
2964
gen_op_mov32(val, reg);
2965
gen_op_mov32(QREG_CC_DEST, val);
2966
gen_op_mov32(QREG_CC_SRC, tmp);
2969
gen_op_sar32(reg, val, tmp);
2971
gen_op_shr32(reg, val, tmp);
2976
tmp = gen_im32(im - 1);
2978
gen_op_shl32(reg, val, tmp);
2979
tmp = gen_im32(32 - im);
2981
if (tmp != QREG_NULL)
2982
gen_op_shr32(val, val, tmp);
2983
gen_op_and32(QREG_CC_X, val, gen_im32(1));
2986
static void expand_op_shl_im_cc(qOP *qop)
2988
expand_shift_im(qop, 0, 0);
2991
static void expand_op_shr_im_cc(qOP *qop)
2993
expand_shift_im(qop, 1, 0);
2996
static void expand_op_sar_im_cc(qOP *qop)
2998
expand_shift_im(qop, 1, 1);
3001
/* Expand a shift by register. */
3002
/* ??? This gives incorrect answers for shifts by 0 or >= 32 */
3003
static inline void expand_shift_reg(qOP *qop, int right, int arith)
3011
shift = qop->args[1];
3012
val = gen_new_qreg(QMODE_I32);
3013
gen_op_mov32(val, reg);
3014
gen_op_mov32(QREG_CC_DEST, val);
3015
gen_op_mov32(QREG_CC_SRC, shift);
3016
tmp = gen_new_qreg(QMODE_I32);
3019
gen_op_sar32(reg, val, shift);
3021
gen_op_shr32(reg, val, shift);
3023
gen_op_sub32(tmp, shift, gen_im32(1));
3025
gen_op_shl32(reg, val, shift);
3026
gen_op_sub32(tmp, gen_im32(31), shift);
3028
gen_op_shl32(val, val, tmp);
3029
gen_op_and32(QREG_CC_X, val, gen_im32(1));
3032
static void expand_op_shl_cc(qOP *qop)
3034
expand_shift_reg(qop, 0, 0);
3037
static void expand_op_shr_cc(qOP *qop)
3039
expand_shift_reg(qop, 1, 0);
3042
static void expand_op_sar_cc(qOP *qop)
3044
expand_shift_reg(qop, 1, 1);
3047
/* Set the Z flag to (arg0 & arg1) == 0. */
3048
static void expand_op_btest(qOP *qop)
3053
l1 = gen_new_label();
3054
tmp = gen_new_qreg(QMODE_I32);
3055
gen_op_and32(tmp, qop->args[0], qop->args[1]);
3056
gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(~(uint32_t)CCF_Z));
3057
gen_op_jmp_nz32(tmp, l1);
3058
gen_op_or32(QREG_CC_DEST, QREG_CC_DEST, gen_im32(CCF_Z));
3062
/* arg0 += arg1 + CC_X */
3063
static void expand_op_addx_cc(qOP *qop)
3065
int arg0 = qop->args[0];
3066
int arg1 = qop->args[1];
3069
gen_op_add32 (arg0, arg0, arg1);
3070
l1 = gen_new_label();
3071
l2 = gen_new_label();
3072
gen_op_jmp_z32(QREG_CC_X, l1);
3073
gen_op_add32(arg0, arg0, gen_im32(1));
3074
gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
3075
gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3078
gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
3079
gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3083
/* arg0 -= arg1 + CC_X */
3084
static void expand_op_subx_cc(qOP *qop)
3086
int arg0 = qop->args[0];
3087
int arg1 = qop->args[1];
3090
l1 = gen_new_label();
3091
l2 = gen_new_label();
3092
gen_op_jmp_z32(QREG_CC_X, l1);
3093
gen_op_set_leu32(QREG_CC_X, arg0, arg1);
3094
gen_op_sub32(arg0, arg0, gen_im32(1));
3095
gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
3098
gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
3099
gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
3101
gen_op_sub32 (arg0, arg0, arg1);
3104
/* Expand target specific ops to generic qops. */
3105
static void expand_target_qops(void)
3111
/* Copy the list of qops, expanding target specific ops as we go. */
3112
qop = gen_first_qop;
3113
gen_first_qop = NULL;
3114
gen_last_qop = NULL;
3115
for (; qop; qop = next) {
3118
if (c < FIRST_TARGET_OP) {
3119
qop->prev = gen_last_qop;
3122
gen_last_qop->next = qop;
3124
gen_first_qop = qop;
3129
#define DEF(name, nargs, barrier) \
3130
case INDEX_op_##name: \
3131
expand_op_##name(qop); \
3133
#include "qop-target.def"
3136
cpu_abort(NULL, "Unexpanded target qop");
3141
/* ??? Implement this. */
3143
optimize_flags(void)
3148
2963
/* generate intermediate code for basic block 'tb'. */
3150
2965
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3153
2968
DisasContext dc1, *dc = &dc1;
3154
2969
uint16_t *gen_opc_end;
3156
2972
target_ulong pc_start;
3158
2974
int last_cc_op;
3160
2978
/* generate intermediate code */
3161
2979
pc_start = tb->pc;
3165
gen_opc_ptr = gen_opc_buf;
3166
2983
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3167
gen_opparam_ptr = gen_opparam_buf;
3170
2986
dc->is_jmp = DISAS_NEXT;