Commit d9ba48308d50ae08e87dc4ea24cb9783b0568c08

Authored by pbrook
1 parent 6ddbc6e4

ARM TCG conversion 8/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4145 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/helpers.h
1 1 #define DEF_HELPER(name, ret, args) ret glue(helper_,name) args;
2 2  
3 3 #ifdef GEN_HELPER
  4 +#define DEF_HELPER_0_0(name, ret, args) \
  5 +DEF_HELPER(name, ret, args) \
  6 +static inline void gen_helper_##name(void) \
  7 +{ \
  8 + tcg_gen_helper_0_0(helper_##name); \
  9 +}
  10 +#define DEF_HELPER_0_1(name, ret, args) \
  11 +DEF_HELPER(name, ret, args) \
  12 +static inline void gen_helper_##name(TCGv arg1) \
  13 +{ \
  14 + tcg_gen_helper_0_1(helper_##name, arg1); \
  15 +}
  16 +#define DEF_HELPER_0_2(name, ret, args) \
  17 +DEF_HELPER(name, ret, args) \
  18 +static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \
  19 +{ \
  20 + tcg_gen_helper_0_2(helper_##name, arg1, arg2); \
  21 +}
  22 +#define DEF_HELPER_1_0(name, ret, args) \
  23 +DEF_HELPER(name, ret, args) \
  24 +static inline void gen_helper_##name(TCGv ret) \
  25 +{ \
  26 + tcg_gen_helper_1_0(helper_##name, ret); \
  27 +}
4 28 #define DEF_HELPER_1_1(name, ret, args) \
5 29 DEF_HELPER(name, ret, args) \
6 30 static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
... ... @@ -21,6 +45,10 @@ static inline void gen_helper_##name(TCGv ret, \
21 45 tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \
22 46 }
23 47 #else /* !GEN_HELPER */
  48 +#define DEF_HELPER_0_0 DEF_HELPER
  49 +#define DEF_HELPER_0_1 DEF_HELPER
  50 +#define DEF_HELPER_0_2 DEF_HELPER
  51 +#define DEF_HELPER_1_0 DEF_HELPER
24 52 #define DEF_HELPER_1_1 DEF_HELPER
25 53 #define DEF_HELPER_1_2 DEF_HELPER
26 54 #define DEF_HELPER_1_3 DEF_HELPER
... ... @@ -74,8 +102,18 @@ DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t))
74 102 DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t))
75 103  
76 104 DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t))
  105 +DEF_HELPER_0_1(exception, void, (uint32_t))
  106 +DEF_HELPER_0_0(wfi, void, (void))
  107 +
  108 +DEF_HELPER_0_2(cpsr_write, void, (uint32_t, uint32_t))
  109 +DEF_HELPER_1_0(cpsr_read, uint32_t, (void))
77 110  
78 111 #undef DEF_HELPER
  112 +#undef DEF_HELPER_0_0
  113 +#undef DEF_HELPER_0_1
  114 +#undef DEF_HELPER_0_2
  115 +#undef DEF_HELPER_1_0
79 116 #undef DEF_HELPER_1_1
80 117 #undef DEF_HELPER_1_2
  118 +#undef DEF_HELPER_1_3
81 119 #undef GEN_HELPER
... ...
target-arm/op.c
... ... @@ -80,151 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1)
80 80  
81 81 OPSUB(rsb, rsc, T0, T1, T0)
82 82  
83   -#define EIP (env->regs[15])
84   -
85   -void OPPROTO op_test_eq(void)
86   -{
87   - if (env->NZF == 0)
88   - GOTO_LABEL_PARAM(1);;
89   - FORCE_RET();
90   -}
91   -
92   -void OPPROTO op_test_ne(void)
93   -{
94   - if (env->NZF != 0)
95   - GOTO_LABEL_PARAM(1);;
96   - FORCE_RET();
97   -}
98   -
99   -void OPPROTO op_test_cs(void)
100   -{
101   - if (env->CF != 0)
102   - GOTO_LABEL_PARAM(1);
103   - FORCE_RET();
104   -}
105   -
106   -void OPPROTO op_test_cc(void)
107   -{
108   - if (env->CF == 0)
109   - GOTO_LABEL_PARAM(1);
110   - FORCE_RET();
111   -}
112   -
113   -void OPPROTO op_test_mi(void)
114   -{
115   - if ((env->NZF & 0x80000000) != 0)
116   - GOTO_LABEL_PARAM(1);
117   - FORCE_RET();
118   -}
119   -
120   -void OPPROTO op_test_pl(void)
121   -{
122   - if ((env->NZF & 0x80000000) == 0)
123   - GOTO_LABEL_PARAM(1);
124   - FORCE_RET();
125   -}
126   -
127   -void OPPROTO op_test_vs(void)
128   -{
129   - if ((env->VF & 0x80000000) != 0)
130   - GOTO_LABEL_PARAM(1);
131   - FORCE_RET();
132   -}
133   -
134   -void OPPROTO op_test_vc(void)
135   -{
136   - if ((env->VF & 0x80000000) == 0)
137   - GOTO_LABEL_PARAM(1);
138   - FORCE_RET();
139   -}
140   -
141   -void OPPROTO op_test_hi(void)
142   -{
143   - if (env->CF != 0 && env->NZF != 0)
144   - GOTO_LABEL_PARAM(1);
145   - FORCE_RET();
146   -}
147   -
148   -void OPPROTO op_test_ls(void)
149   -{
150   - if (env->CF == 0 || env->NZF == 0)
151   - GOTO_LABEL_PARAM(1);
152   - FORCE_RET();
153   -}
154   -
155   -void OPPROTO op_test_ge(void)
156   -{
157   - if (((env->VF ^ env->NZF) & 0x80000000) == 0)
158   - GOTO_LABEL_PARAM(1);
159   - FORCE_RET();
160   -}
161   -
162   -void OPPROTO op_test_lt(void)
163   -{
164   - if (((env->VF ^ env->NZF) & 0x80000000) != 0)
165   - GOTO_LABEL_PARAM(1);
166   - FORCE_RET();
167   -}
168   -
169   -void OPPROTO op_test_gt(void)
170   -{
171   - if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
172   - GOTO_LABEL_PARAM(1);
173   - FORCE_RET();
174   -}
175   -
176   -void OPPROTO op_test_le(void)
177   -{
178   - if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
179   - GOTO_LABEL_PARAM(1);
180   - FORCE_RET();
181   -}
182   -
183   -void OPPROTO op_test_T0(void)
184   -{
185   - if (T0)
186   - GOTO_LABEL_PARAM(1);
187   - FORCE_RET();
188   -}
189   -void OPPROTO op_testn_T0(void)
190   -{
191   - if (!T0)
192   - GOTO_LABEL_PARAM(1);
193   - FORCE_RET();
194   -}
195   -
196   -void OPPROTO op_movl_T0_cpsr(void)
197   -{
198   - /* Execution state bits always read as zero. */
199   - T0 = cpsr_read(env) & ~CPSR_EXEC;
200   - FORCE_RET();
201   -}
202   -
203   -void OPPROTO op_movl_T0_spsr(void)
204   -{
205   - T0 = env->spsr;
206   -}
207   -
208   -void OPPROTO op_movl_spsr_T0(void)
209   -{
210   - uint32_t mask = PARAM1;
211   - env->spsr = (env->spsr & ~mask) | (T0 & mask);
212   -}
213   -
214   -void OPPROTO op_movl_cpsr_T0(void)
215   -{
216   - cpsr_write(env, T0, PARAM1);
217   - FORCE_RET();
218   -}
219   -
220   -/* 48 bit signed mul, top 32 bits */
221   -void OPPROTO op_imulw_T0_T1(void)
222   -{
223   - uint64_t res;
224   - res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
225   - T0 = res >> 16;
226   -}
227   -
228 83 void OPPROTO op_addq_T0_T1(void)
229 84 {
230 85 uint64_t res;
... ... @@ -397,45 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void)
397 252 FORCE_RET();
398 253 }
399 254  
400   -/* exceptions */
401   -
402   -void OPPROTO op_swi(void)
403   -{
404   - env->exception_index = EXCP_SWI;
405   - cpu_loop_exit();
406   -}
407   -
408   -void OPPROTO op_undef_insn(void)
409   -{
410   - env->exception_index = EXCP_UDEF;
411   - cpu_loop_exit();
412   -}
413   -
414   -void OPPROTO op_debug(void)
415   -{
416   - env->exception_index = EXCP_DEBUG;
417   - cpu_loop_exit();
418   -}
419   -
420   -void OPPROTO op_wfi(void)
421   -{
422   - env->exception_index = EXCP_HLT;
423   - env->halted = 1;
424   - cpu_loop_exit();
425   -}
426   -
427   -void OPPROTO op_bkpt(void)
428   -{
429   - env->exception_index = EXCP_BKPT;
430   - cpu_loop_exit();
431   -}
432   -
433   -void OPPROTO op_exception_exit(void)
434   -{
435   - env->exception_index = EXCP_EXCEPTION_EXIT;
436   - cpu_loop_exit();
437   -}
438   -
439 255 /* VFP support. We follow the convention used for VFP instrunctions:
440 256 Single precition routines have a "s" suffix, double precision a
441 257 "d" suffix. */
... ...
target-arm/op_helper.c
... ... @@ -436,3 +436,26 @@ uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
436 436 res |= do_usat(((int32_t)x) >> 16, shift) << 16;
437 437 return res;
438 438 }
  439 +
  440 +void HELPER(wfi)(void)
  441 +{
  442 + env->exception_index = EXCP_HLT;
  443 + env->halted = 1;
  444 + cpu_loop_exit();
  445 +}
  446 +
  447 +void HELPER(exception)(uint32_t excp)
  448 +{
  449 + env->exception_index = excp;
  450 + cpu_loop_exit();
  451 +}
  452 +
  453 +uint32_t HELPER(cpsr_read)(void)
  454 +{
  455 + return cpsr_read(env) & ~CPSR_EXEC;
  456 +}
  457 +
  458 +void HELPER(cpsr_write)(uint32_t val, uint32_t mask)
  459 +{
  460 + cpsr_write(env, val, mask);
  461 +}
... ...
target-arm/translate.c
... ... @@ -130,6 +130,24 @@ static void dead_tmp(TCGv tmp)
130 130 temps[i] = tmp;
131 131 }
132 132  
  133 +static inline TCGv load_cpu_offset(int offset)
  134 +{
  135 + TCGv tmp = new_tmp();
  136 + tcg_gen_ld_i32(tmp, cpu_env, offset);
  137 + return tmp;
  138 +}
  139 +
  140 +#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
  141 +
  142 +static inline void store_cpu_offset(TCGv var, int offset)
  143 +{
  144 + tcg_gen_st_i32(var, cpu_env, offset);
  145 + dead_tmp(var);
  146 +}
  147 +
  148 +#define store_cpu_field(var, name) \
  149 + store_cpu_offset(var, offsetof(CPUState, name))
  150 +
133 151 /* Set a variable to the value of a CPU register. */
134 152 static void load_reg_var(DisasContext *s, TCGv var, int reg)
135 153 {
... ... @@ -222,6 +240,18 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
222 240 /* Copy the most significant bit of T0 to all bits of T1. */
223 241 #define gen_op_signbit_T1_T0() tcg_gen_sari_i32(cpu_T[1], cpu_T[0], 31)
224 242  
  243 +#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
  244 +/* Set NZCV flags from the high 4 bits of var. */
  245 +#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
  246 +
  247 +static void gen_exception(int excp)
  248 +{
  249 + TCGv tmp = new_tmp();
  250 + tcg_gen_movi_i32(tmp, excp);
  251 + gen_helper_exception(tmp);
  252 + dead_tmp(tmp);
  253 +}
  254 +
225 255 static void gen_smul_dual(TCGv a, TCGv b)
226 256 {
227 257 TCGv tmp1 = new_tmp();
... ... @@ -293,10 +323,11 @@ static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
293 323 tcg_gen_or_i32(dest, base, val);
294 324 }
295 325  
296   -static void gen_op_roundqd_T0_T1(void)
  326 +/* Round the top 32 bits of a 64-bit value. */
  327 +static void gen_roundqd(TCGv a, TCGv b)
297 328 {
298   - tcg_gen_shri_i32(cpu_T[0], cpu_T[0], 31);
299   - tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
  329 + tcg_gen_shri_i32(a, a, 31);
  330 + tcg_gen_add_i32(a, a, b);
300 331 }
301 332  
302 333 /* FIXME: Most targets have native widening multiplication.
... ... @@ -316,17 +347,27 @@ static void gen_op_mull_T0_T1(void)
316 347 }
317 348  
318 349 /* Signed 32x32->64 multiply. */
319   -static void gen_op_imull_T0_T1(void)
  350 +static void gen_imull(TCGv a, TCGv b)
320 351 {
321 352 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
322 353 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
323 354  
324   - tcg_gen_ext_i32_i64(tmp1, cpu_T[0]);
325   - tcg_gen_ext_i32_i64(tmp2, cpu_T[1]);
  355 + tcg_gen_ext_i32_i64(tmp1, a);
  356 + tcg_gen_ext_i32_i64(tmp2, b);
326 357 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
327   - tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
  358 + tcg_gen_trunc_i64_i32(a, tmp1);
328 359 tcg_gen_shri_i64(tmp1, tmp1, 32);
329   - tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
  360 + tcg_gen_trunc_i64_i32(b, tmp1);
  361 +}
  362 +#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
  363 +
  364 +/* Signed 32x16 multiply, top 32 bits. */
  365 +static void gen_imulw(TCGv a, TCGv b)
  366 +{
  367 + gen_imull(a, b);
  368 + tcg_gen_shri_i32(a, a, 16);
  369 + tcg_gen_shli_i32(b, b, 16);
  370 + tcg_gen_or_i32(a, a, b);
330 371 }
331 372  
332 373 /* Swap low and high halfwords. */
... ... @@ -379,9 +420,9 @@ static inline void gen_logic_CC(TCGv var)
379 420 /* T0 += T1 + CF. */
380 421 static void gen_adc_T0_T1(void)
381 422 {
382   - TCGv tmp = new_tmp();
  423 + TCGv tmp;
383 424 gen_op_addl_T0_T1();
384   - tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF));
  425 + tmp = load_cpu_field(CF);
385 426 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
386 427 dead_tmp(tmp);
387 428 }
... ... @@ -389,9 +430,9 @@ static void gen_adc_T0_T1(void)
389 430 /* dest = T0 - T1 + CF - 1. */
390 431 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
391 432 {
392   - TCGv tmp = new_tmp();
  433 + TCGv tmp;
393 434 tcg_gen_sub_i32(dest, t0, t1);
394   - tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF));
  435 + tmp = load_cpu_field(CF);
395 436 tcg_gen_add_i32(dest, dest, tmp);
396 437 tcg_gen_subi_i32(dest, dest, 1);
397 438 dead_tmp(tmp);
... ... @@ -482,8 +523,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
482 523 shifter_out_im(var, shift - 1);
483 524 tcg_gen_rori_i32(var, var, shift); break;
484 525 } else {
485   - TCGv tmp = new_tmp();
486   - tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF));
  526 + TCGv tmp = load_cpu_field(CF);
487 527 if (flags)
488 528 shifter_out_im(var, 0);
489 529 tcg_gen_shri_i32(var, var, 1);
... ... @@ -503,7 +543,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
503 543 case 4: gen_pas_helper(glue(pfx,add8)); break; \
504 544 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
505 545 }
506   -void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
  546 +static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
507 547 {
508 548 TCGv tmp;
509 549  
... ... @@ -548,7 +588,7 @@ void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
548 588 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
549 589 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
550 590 }
551   -void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
  591 +static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
552 592 {
553 593 TCGv tmp;
554 594  
... ... @@ -583,22 +623,105 @@ void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
583 623 }
584 624 #undef PAS_OP
585 625  
586   -static GenOpFunc1 *gen_test_cc[14] = {
587   - gen_op_test_eq,
588   - gen_op_test_ne,
589   - gen_op_test_cs,
590   - gen_op_test_cc,
591   - gen_op_test_mi,
592   - gen_op_test_pl,
593   - gen_op_test_vs,
594   - gen_op_test_vc,
595   - gen_op_test_hi,
596   - gen_op_test_ls,
597   - gen_op_test_ge,
598   - gen_op_test_lt,
599   - gen_op_test_gt,
600   - gen_op_test_le,
601   -};
  626 +static void gen_test_cc(int cc, int label)
  627 +{
  628 + TCGv tmp;
  629 + TCGv tmp2;
  630 + TCGv zero;
  631 + int inv;
  632 +
  633 + zero = tcg_const_i32(0);
  634 + switch (cc) {
  635 + case 0: /* eq: Z */
  636 + tmp = load_cpu_field(NZF);
  637 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
  638 + break;
  639 + case 1: /* ne: !Z */
  640 + tmp = load_cpu_field(NZF);
  641 + tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
  642 + break;
  643 + case 2: /* cs: C */
  644 + tmp = load_cpu_field(CF);
  645 + tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
  646 + break;
  647 + case 3: /* cc: !C */
  648 + tmp = load_cpu_field(CF);
  649 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
  650 + break;
  651 + case 4: /* mi: N */
  652 + tmp = load_cpu_field(NZF);
  653 + tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
  654 + break;
  655 + case 5: /* pl: !N */
  656 + tmp = load_cpu_field(NZF);
  657 + tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
  658 + break;
  659 + case 6: /* vs: V */
  660 + tmp = load_cpu_field(VF);
  661 + tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
  662 + break;
  663 + case 7: /* vc: !V */
  664 + tmp = load_cpu_field(VF);
  665 + tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
  666 + break;
  667 + case 8: /* hi: C && !Z */
  668 + inv = gen_new_label();
  669 + tmp = load_cpu_field(CF);
  670 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
  671 + dead_tmp(tmp);
  672 + tmp = load_cpu_field(NZF);
  673 + tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
  674 + gen_set_label(inv);
  675 + break;
  676 + case 9: /* ls: !C || Z */
  677 + tmp = load_cpu_field(CF);
  678 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
  679 + dead_tmp(tmp);
  680 + tmp = load_cpu_field(NZF);
  681 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
  682 + break;
  683 + case 10: /* ge: N == V -> N ^ V == 0 */
  684 + tmp = load_cpu_field(VF);
  685 + tmp2 = load_cpu_field(NZF);
  686 + tcg_gen_xor_i32(tmp, tmp, tmp2);
  687 + dead_tmp(tmp2);
  688 + tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
  689 + break;
  690 + case 11: /* lt: N != V -> N ^ V != 0 */
  691 + tmp = load_cpu_field(VF);
  692 + tmp2 = load_cpu_field(NZF);
  693 + tcg_gen_xor_i32(tmp, tmp, tmp2);
  694 + dead_tmp(tmp2);
  695 + tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
  696 + break;
  697 + case 12: /* gt: !Z && N == V */
  698 + inv = gen_new_label();
  699 + tmp = load_cpu_field(NZF);
  700 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
  701 + dead_tmp(tmp);
  702 + tmp = load_cpu_field(VF);
  703 + tmp2 = load_cpu_field(NZF);
  704 + tcg_gen_xor_i32(tmp, tmp, tmp2);
  705 + dead_tmp(tmp2);
  706 + tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
  707 + gen_set_label(inv);
  708 + break;
  709 + case 13: /* le: Z || N != V */
  710 + tmp = load_cpu_field(NZF);
  711 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
  712 + dead_tmp(tmp);
  713 + tmp = load_cpu_field(VF);
  714 + tmp2 = load_cpu_field(NZF);
  715 + tcg_gen_xor_i32(tmp, tmp, tmp2);
  716 + dead_tmp(tmp2);
  717 + tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
  718 + break;
  719 + default:
  720 + fprintf(stderr, "Bad condition code 0x%x\n", cc);
  721 + abort();
  722 + }
  723 + dead_tmp(tmp);
  724 +}
602 725  
603 726 const uint8_t table_logic_cc[16] = {
604 727 1, /* and */
... ... @@ -633,18 +756,41 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = {
633 756 gen_op_rorl_T1_T0_cc,
634 757 };
635 758  
636   -/* Set PC and thumb state from T0. Clobbers T0. */
637   -static inline void gen_bx(DisasContext *s)
  759 +/* Set PC and Thumb state from an immediate address. */
  760 +static inline void gen_bx_im(DisasContext *s, uint32_t addr)
638 761 {
639 762 TCGv tmp;
640 763  
641 764 s->is_jmp = DISAS_UPDATE;
642 765 tmp = new_tmp();
643   - tcg_gen_andi_i32(tmp, cpu_T[0], 1);
644   - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
  766 + if (s->thumb != (addr & 1)) {
  767 + tcg_gen_movi_i32(tmp, addr & 1);
  768 + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
  769 + }
  770 + tcg_gen_movi_i32(tmp, addr & ~1);
  771 + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
645 772 dead_tmp(tmp);
646   - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~1);
647   - tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15]));
  773 +}
  774 +
  775 +/* Set PC and Thumb state from var. var is marked as dead. */
  776 +static inline void gen_bx(DisasContext *s, TCGv var)
  777 +{
  778 + TCGv tmp;
  779 +
  780 + s->is_jmp = DISAS_UPDATE;
  781 + tmp = new_tmp();
  782 + tcg_gen_andi_i32(tmp, var, 1);
  783 + store_cpu_field(tmp, thumb);
  784 + tcg_gen_andi_i32(var, var, ~1);
  785 + store_cpu_field(var, regs[15]);
  786 +}
  787 +
  788 +/* TODO: This should be removed. Use gen_bx instead. */
  789 +static inline void gen_bx_T0(DisasContext *s)
  790 +{
  791 + TCGv tmp = new_tmp();
  792 + tcg_gen_mov_i32(tmp, cpu_T[0]);
  793 + gen_bx(s, tmp);
648 794 }
649 795  
650 796 #if defined(CONFIG_USER_ONLY)
... ... @@ -1312,8 +1458,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1312 1458 return 1;
1313 1459 }
1314 1460 gen_op_shll_T1_im(28);
1315   - gen_op_movl_T0_T1();
1316   - gen_op_movl_cpsr_T0(0xf0000000);
  1461 + gen_set_nzcv(cpu_T[1]);
1317 1462 break;
1318 1463 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1319 1464 rd = (insn >> 12) & 0xf;
... ... @@ -1359,7 +1504,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1359 1504 case 3:
1360 1505 return 1;
1361 1506 }
1362   - gen_op_movl_cpsr_T0(0xf0000000);
  1507 + gen_set_nzcv(cpu_T[0]);
1363 1508 break;
1364 1509 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1365 1510 wrd = (insn >> 12) & 0xf;
... ... @@ -1405,9 +1550,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1405 1550 case 3:
1406 1551 return 1;
1407 1552 }
1408   - gen_op_movl_T1_im(0xf0000000);
1409   - gen_op_andl_T0_T1();
1410   - gen_op_movl_cpsr_T0(0xf0000000);
  1553 + gen_set_nzcv(cpu_T[0]);
1411 1554 break;
1412 1555 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1413 1556 rd = (insn >> 12) & 0xf;
... ... @@ -2246,7 +2389,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2246 2389 }
2247 2390 if (rd == 15) {
2248 2391 /* Set the 4 flag bits in the CPSR. */
2249   - gen_op_movl_cpsr_T0(0xf0000000);
  2392 + gen_set_nzcv(cpu_T[0]);
2250 2393 } else
2251 2394 gen_movl_reg_T0(s, rd);
2252 2395 } else {
... ... @@ -2745,26 +2888,25 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
2745 2888 if (__builtin_expect(s->singlestep_enabled, 0)) {
2746 2889 /* An indirect jump so that we still trigger the debug exception. */
2747 2890 if (s->thumb)
2748   - dest |= 1;
2749   - gen_op_movl_T0_im(dest);
2750   - gen_bx(s);
  2891 + dest |= 1;
  2892 + gen_bx_im(s, dest);
2751 2893 } else {
2752 2894 gen_goto_tb(s, 0, dest);
2753 2895 s->is_jmp = DISAS_TB_JUMP;
2754 2896 }
2755 2897 }
2756 2898  
2757   -static inline void gen_mulxy(int x, int y)
  2899 +static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
2758 2900 {
2759 2901 if (x)
2760   - tcg_gen_sari_i32(cpu_T[0], cpu_T[0], 16);
  2902 + tcg_gen_sari_i32(t0, t0, 16);
2761 2903 else
2762   - gen_sxth(cpu_T[0]);
  2904 + gen_sxth(t0);
2763 2905 if (y)
2764   - gen_op_sarl_T1_im(16);
  2906 + tcg_gen_sari_i32(t1, t1, 16);
2765 2907 else
2766   - gen_sxth(cpu_T[1]);
2767   - gen_op_mul_T0_T1();
  2908 + gen_sxth(t1);
  2909 + tcg_gen_mul_i32(t0, t0, t1);
2768 2910 }
2769 2911  
2770 2912 /* Return the mask of PSR bits set by a MSR instruction. */
... ... @@ -2799,13 +2941,19 @@ static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
2799 2941 /* Returns nonzero if access to the PSR is not permitted. */
2800 2942 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
2801 2943 {
  2944 + TCGv tmp;
2802 2945 if (spsr) {
2803 2946 /* ??? This is also undefined in system mode. */
2804 2947 if (IS_USER(s))
2805 2948 return 1;
2806   - gen_op_movl_spsr_T0(mask);
  2949 +
  2950 + tmp = load_cpu_field(spsr);
  2951 + tcg_gen_andi_i32(tmp, tmp, ~mask);
  2952 + tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
  2953 + tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
  2954 + store_cpu_field(tmp, spsr);
2807 2955 } else {
2808   - gen_op_movl_cpsr_T0(mask);
  2956 + gen_set_cpsr(cpu_T[0], mask);
2809 2957 }
2810 2958 gen_lookup_tb(s);
2811 2959 return 0;
... ... @@ -2814,16 +2962,18 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
2814 2962 /* Generate an old-style exception return. */
2815 2963 static void gen_exception_return(DisasContext *s)
2816 2964 {
  2965 + TCGv tmp;
2817 2966 gen_set_pc_T0();
2818   - gen_op_movl_T0_spsr();
2819   - gen_op_movl_cpsr_T0(0xffffffff);
  2967 + tmp = load_cpu_field(spsr);
  2968 + gen_set_cpsr(tmp, 0xffffffff);
  2969 + dead_tmp(tmp);
2820 2970 s->is_jmp = DISAS_UPDATE;
2821 2971 }
2822 2972  
2823 2973 /* Generate a v6 exception return. */
2824 2974 static void gen_rfe(DisasContext *s)
2825 2975 {
2826   - gen_op_movl_cpsr_T0(0xffffffff);
  2976 + gen_set_cpsr(cpu_T[0], 0xffffffff);
2827 2977 gen_op_movl_T0_T2();
2828 2978 gen_set_pc_T0();
2829 2979 s->is_jmp = DISAS_UPDATE;
... ... @@ -2836,8 +2986,7 @@ gen_set_condexec (DisasContext *s)
2836 2986 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
2837 2987 TCGv tmp = new_tmp();
2838 2988 tcg_gen_movi_i32(tmp, val);
2839   - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, condexec_bits));
2840   - dead_tmp(tmp);
  2989 + store_cpu_field(tmp, condexec_bits);
2841 2990 }
2842 2991 }
2843 2992  
... ... @@ -5027,7 +5176,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5027 5176 gen_op_addl_T1_im(offset);
5028 5177 gen_movl_T0_reg(s, 14);
5029 5178 gen_ldst(stl, s);
5030   - gen_op_movl_T0_cpsr();
  5179 + gen_helper_cpsr_read(cpu_T[0]);
5031 5180 gen_op_addl_T1_im(4);
5032 5181 gen_ldst(stl, s);
5033 5182 if (insn & (1 << 21)) {
... ... @@ -5089,16 +5238,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5089 5238 int32_t offset;
5090 5239  
5091 5240 val = (uint32_t)s->pc;
5092   - gen_op_movl_T0_im(val);
5093   - gen_movl_reg_T0(s, 14);
  5241 + tmp = new_tmp();
  5242 + tcg_gen_movi_i32(tmp, val);
  5243 + store_reg(s, 14, tmp);
5094 5244 /* Sign-extend the 24-bit offset */
5095 5245 offset = (((int32_t)insn) << 8) >> 8;
5096 5246 /* offset * 4 + bit24 * 2 + (thumb bit) */
5097 5247 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5098 5248 /* pipeline offset */
5099 5249 val += 4;
5100   - gen_op_movl_T0_im(val);
5101   - gen_bx(s);
  5250 + gen_bx_im(s, val);
5102 5251 return;
5103 5252 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5104 5253 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
... ... @@ -5144,7 +5293,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5144 5293 /* if not always execute, we generate a conditional jump to
5145 5294 next instruction */
5146 5295 s->condlabel = gen_new_label();
5147   - gen_test_cc[cond ^ 1](s->condlabel);
  5296 + gen_test_cc(cond ^ 1, s->condlabel);
5148 5297 s->condjmp = 1;
5149 5298 }
5150 5299 if ((insn & 0x0f900000) == 0x03000000) {
... ... @@ -5201,18 +5350,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5201 5350 if (op1 & 2) {
5202 5351 if (IS_USER(s))
5203 5352 goto illegal_op;
5204   - gen_op_movl_T0_spsr();
  5353 + tmp = load_cpu_field(spsr);
5205 5354 } else {
5206   - gen_op_movl_T0_cpsr();
  5355 + tmp = new_tmp();
  5356 + gen_helper_cpsr_read(tmp);
5207 5357 }
5208   - gen_movl_reg_T0(s, rd);
  5358 + store_reg(s, rd, tmp);
5209 5359 }
5210 5360 break;
5211 5361 case 0x1:
5212 5362 if (op1 == 1) {
5213 5363 /* branch/exchange thumb (bx). */
5214   - gen_movl_T0_reg(s, rm);
5215   - gen_bx(s);
  5364 + tmp = load_reg(s, rm);
  5365 + gen_bx(s, tmp);
5216 5366 } else if (op1 == 3) {
5217 5367 /* clz */
5218 5368 rd = (insn >> 12) & 0xf;
... ... @@ -5227,8 +5377,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5227 5377 if (op1 == 1) {
5228 5378 ARCH(5J); /* bxj */
5229 5379 /* Trivial implementation equivalent to bx. */
5230   - gen_movl_T0_reg(s, rm);
5231   - gen_bx(s);
  5380 + tmp = load_reg(s, rm);
  5381 + gen_bx(s, tmp);
5232 5382 } else {
5233 5383 goto illegal_op;
5234 5384 }
... ... @@ -5238,11 +5388,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5238 5388 goto illegal_op;
5239 5389  
5240 5390 /* branch link/exchange thumb (blx) */
5241   - val = (uint32_t)s->pc;
5242   - gen_op_movl_T1_im(val);
5243   - gen_movl_T0_reg(s, rm);
5244   - gen_movl_reg_T1(s, 14);
5245   - gen_bx(s);
  5391 + tmp = load_reg(s, rm);
  5392 + tmp2 = new_tmp();
  5393 + tcg_gen_movi_i32(tmp2, s->pc);
  5394 + store_reg(s, 14, tmp2);
  5395 + gen_bx(s, tmp);
5246 5396 break;
5247 5397 case 0x5: /* saturating add/subtract */
5248 5398 rd = (insn >> 12) & 0xf;
... ... @@ -5261,7 +5411,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5261 5411 gen_set_condexec(s);
5262 5412 gen_op_movl_T0_im((long)s->pc - 4);
5263 5413 gen_set_pc_T0();
5264   - gen_op_bkpt();
  5414 + gen_exception(EXCP_BKPT);
5265 5415 s->is_jmp = DISAS_JUMP;
5266 5416 break;
5267 5417 case 0x8: /* signed multiply */
... ... @@ -5279,7 +5429,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5279 5429 gen_op_sarl_T1_im(16);
5280 5430 else
5281 5431 gen_sxth(cpu_T[1]);
5282   - gen_op_imulw_T0_T1();
  5432 + gen_imulw(cpu_T[0], cpu_T[1]);
5283 5433 if ((sh & 2) == 0) {
5284 5434 gen_movl_T1_reg(s, rn);
5285 5435 gen_op_addl_T0_T1_setq();
... ... @@ -5289,7 +5439,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5289 5439 /* 16 * 16 */
5290 5440 gen_movl_T0_reg(s, rm);
5291 5441 gen_movl_T1_reg(s, rs);
5292   - gen_mulxy(sh & 2, sh & 4);
  5442 + gen_mulxy(cpu_T[0], cpu_T[1], sh & 2, sh & 4);
5293 5443 if (op1 == 2) {
5294 5444 gen_op_signbit_T1_T0();
5295 5445 gen_op_addq_T0_T1(rn, rd);
... ... @@ -5758,7 +5908,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5758 5908 /* Signed multiply most significant [accumulate]. */
5759 5909 gen_op_imull_T0_T1();
5760 5910 if (insn & (1 << 5))
5761   - gen_op_roundqd_T0_T1();
  5911 + gen_roundqd(cpu_T[0], cpu_T[1]);
5762 5912 else
5763 5913 gen_op_movl_T0_T1();
5764 5914 if (rn != 15) {
... ... @@ -5926,7 +6076,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5926 6076 if (insn & (1 << 20)) {
5927 6077 /* Complete the load. */
5928 6078 if (rd == 15)
5929   - gen_bx(s);
  6079 + gen_bx_T0(s);
5930 6080 else
5931 6081 gen_movl_reg_T0(s, rd);
5932 6082 }
... ... @@ -5980,7 +6130,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5980 6130 /* load */
5981 6131 gen_ldst(ldl, s);
5982 6132 if (i == 15) {
5983   - gen_bx(s);
  6133 + gen_bx_T0(s);
5984 6134 } else if (user) {
5985 6135 gen_op_movl_user_T0(i);
5986 6136 } else if (i == rn) {
... ... @@ -6035,8 +6185,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6035 6185 }
6036 6186 if ((insn & (1 << 22)) && !user) {
6037 6187 /* Restore CPSR from SPSR. */
6038   - gen_op_movl_T0_spsr();
6039   - gen_op_movl_cpsr_T0(0xffffffff);
  6188 + tmp = load_cpu_field(spsr);
  6189 + gen_set_cpsr(tmp, 0xffffffff);
  6190 + dead_tmp(tmp);
6040 6191 s->is_jmp = DISAS_UPDATE;
6041 6192 }
6042 6193 }
... ... @@ -6075,7 +6226,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6075 6226 gen_set_condexec(s);
6076 6227 gen_op_movl_T0_im((long)s->pc - 4);
6077 6228 gen_set_pc_T0();
6078   - gen_op_undef_insn();
  6229 + gen_exception(EXCP_UDEF);
6079 6230 s->is_jmp = DISAS_JUMP;
6080 6231 break;
6081 6232 }
... ... @@ -6186,29 +6337,28 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6186 6337 if ((insn & (1 << 12)) == 0) {
6187 6338 /* Second half of blx. */
6188 6339 offset = ((insn & 0x7ff) << 1);
6189   - gen_movl_T0_reg(s, 14);
6190   - gen_op_movl_T1_im(offset);
6191   - gen_op_addl_T0_T1();
6192   - gen_op_movl_T1_im(0xfffffffc);
6193   - gen_op_andl_T0_T1();
  6340 + tmp = load_reg(s, 14);
  6341 + tcg_gen_addi_i32(tmp, tmp, offset);
  6342 + tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6194 6343  
6195 6344 addr = (uint32_t)s->pc;
6196   - gen_op_movl_T1_im(addr | 1);
6197   - gen_movl_reg_T1(s, 14);
6198   - gen_bx(s);
  6345 + tmp2 = new_tmp();
  6346 + tcg_gen_movi_i32(tmp2, addr | 1);
  6347 + store_reg(s, 14, tmp2);
  6348 + gen_bx(s, tmp);
6199 6349 return 0;
6200 6350 }
6201 6351 if (insn & (1 << 11)) {
6202 6352 /* Second half of bl. */
6203 6353 offset = ((insn & 0x7ff) << 1) | 1;
6204   - gen_movl_T0_reg(s, 14);
6205   - gen_op_movl_T1_im(offset);
6206   - gen_op_addl_T0_T1();
  6354 + tmp = load_reg(s, 14);
  6355 + tcg_gen_addi_i32(tmp, tmp, 14);
6207 6356  
6208 6357 addr = (uint32_t)s->pc;
6209   - gen_op_movl_T1_im(addr | 1);
6210   - gen_movl_reg_T1(s, 14);
6211   - gen_bx(s);
  6358 + tmp2 = new_tmp();
  6359 + tcg_gen_movi_i32(tmp2, addr | 1);
  6360 + store_reg(s, 14, tmp2);
  6361 + gen_bx(s, tmp);
6212 6362 return 0;
6213 6363 }
6214 6364 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
... ... @@ -6388,7 +6538,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6388 6538 }
6389 6539 gen_movl_T0_reg(s, 14);
6390 6540 gen_ldst(stl, s);
6391   - gen_op_movl_T0_cpsr();
  6541 + gen_helper_cpsr_read(cpu_T[0]);
6392 6542 gen_op_addl_T1_im(4);
6393 6543 gen_ldst(stl, s);
6394 6544 if (insn & (1 << 21)) {
... ... @@ -6424,7 +6574,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6424 6574 /* Load. */
6425 6575 gen_ldst(ldl, s);
6426 6576 if (i == 15) {
6427   - gen_bx(s);
  6577 + gen_bx_T0(s);
6428 6578 } else {
6429 6579 gen_movl_reg_T0(s, i);
6430 6580 }
... ... @@ -6527,125 +6677,136 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6527 6677 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
6528 6678 if (op < 4) {
6529 6679 /* Saturating add/subtract. */
6530   - gen_movl_T0_reg(s, rm);
6531   - gen_movl_T1_reg(s, rn);
  6680 + tmp = load_reg(s, rn);
  6681 + tmp2 = load_reg(s, rm);
6532 6682 if (op & 2)
6533   - gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
  6683 + gen_helper_double_saturate(tmp, tmp);
6534 6684 if (op & 1)
6535   - gen_op_subl_T0_T1_saturate();
  6685 + gen_helper_sub_saturate(tmp, tmp2, tmp);
6536 6686 else
6537   - gen_op_addl_T0_T1_saturate();
  6687 + gen_helper_add_saturate(tmp, tmp, tmp2);
  6688 + dead_tmp(tmp2);
6538 6689 } else {
6539   - gen_movl_T0_reg(s, rn);
  6690 + tmp = load_reg(s, rn);
6540 6691 switch (op) {
6541 6692 case 0x0a: /* rbit */
6542   - gen_helper_rbit(cpu_T[0], cpu_T[0]);
  6693 + gen_helper_rbit(tmp, tmp);
6543 6694 break;
6544 6695 case 0x08: /* rev */
6545   - gen_op_rev_T0();
  6696 + tcg_gen_bswap_i32(tmp, tmp);
6546 6697 break;
6547 6698 case 0x09: /* rev16 */
6548   - gen_rev16(cpu_T[0]);
  6699 + gen_rev16(tmp);
6549 6700 break;
6550 6701 case 0x0b: /* revsh */
6551   - gen_revsh(cpu_T[0]);
  6702 + gen_revsh(tmp);
6552 6703 break;
6553 6704 case 0x10: /* sel */
6554   - gen_movl_T1_reg(s, rm);
  6705 + tmp2 = load_reg(s, rm);
6555 6706 tmp3 = new_tmp();
6556 6707 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6557   - gen_helper_sel_flags(cpu_T[0], tmp3, cpu_T[0], cpu_T[1]);
  6708 + gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6558 6709 dead_tmp(tmp3);
  6710 + dead_tmp(tmp2);
6559 6711 break;
6560 6712 case 0x18: /* clz */
6561   - gen_helper_clz(cpu_T[0], cpu_T[0]);
  6713 + gen_helper_clz(tmp, tmp);
6562 6714 break;
6563 6715 default:
6564 6716 goto illegal_op;
6565 6717 }
6566 6718 }
6567   - gen_movl_reg_T0(s, rd);
  6719 + store_reg(s, rd, tmp);
6568 6720 break;
6569 6721 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
6570 6722 op = (insn >> 4) & 0xf;
6571   - gen_movl_T0_reg(s, rn);
6572   - gen_movl_T1_reg(s, rm);
  6723 + tmp = load_reg(s, rn);
  6724 + tmp2 = load_reg(s, rm);
6573 6725 switch ((insn >> 20) & 7) {
6574 6726 case 0: /* 32 x 32 -> 32 */
6575   - gen_op_mul_T0_T1();
  6727 + tcg_gen_mul_i32(tmp, tmp, tmp2);
  6728 + dead_tmp(tmp2);
6576 6729 if (rs != 15) {
6577   - gen_movl_T1_reg(s, rs);
  6730 + tmp2 = load_reg(s, rs);
6578 6731 if (op)
6579   - gen_op_rsbl_T0_T1();
  6732 + tcg_gen_sub_i32(tmp, tmp2, tmp);
6580 6733 else
6581   - gen_op_addl_T0_T1();
  6734 + tcg_gen_add_i32(tmp, tmp, tmp2);
  6735 + dead_tmp(tmp2);
6582 6736 }
6583   - gen_movl_reg_T0(s, rd);
6584 6737 break;
6585 6738 case 1: /* 16 x 16 -> 32 */
6586   - gen_mulxy(op & 2, op & 1);
  6739 + gen_mulxy(tmp, tmp2, op & 2, op & 1);
  6740 + dead_tmp(tmp2);
6587 6741 if (rs != 15) {
6588   - gen_movl_T1_reg(s, rs);
6589   - gen_op_addl_T0_T1_setq();
  6742 + tmp2 = load_reg(s, rs);
  6743 + gen_helper_add_setq(tmp, tmp, tmp2);
  6744 + dead_tmp(tmp2);
6590 6745 }
6591   - gen_movl_reg_T0(s, rd);
6592 6746 break;
6593 6747 case 2: /* Dual multiply add. */
6594 6748 case 4: /* Dual multiply subtract. */
6595 6749 if (op)
6596   - gen_swap_half(cpu_T[1]);
6597   - gen_smul_dual(cpu_T[0], cpu_T[1]);
  6750 + gen_swap_half(tmp2);
  6751 + gen_smul_dual(tmp, tmp2);
6598 6752 /* This addition cannot overflow. */
6599 6753 if (insn & (1 << 22)) {
6600   - gen_op_subl_T0_T1();
  6754 + tcg_gen_sub_i32(tmp, tmp, tmp2);
6601 6755 } else {
6602   - gen_op_addl_T0_T1();
  6756 + tcg_gen_add_i32(tmp, tmp, tmp2);
6603 6757 }
  6758 + dead_tmp(tmp2);
6604 6759 if (rs != 15)
6605 6760 {
6606   - gen_movl_T1_reg(s, rs);
6607   - gen_op_addl_T0_T1_setq();
  6761 + tmp2 = load_reg(s, rs);
  6762 + gen_helper_add_setq(tmp, tmp, tmp2);
  6763 + dead_tmp(tmp2);
6608 6764 }
6609   - gen_movl_reg_T0(s, rd);
6610 6765 break;
6611 6766 case 3: /* 32 * 16 -> 32msb */
6612 6767 if (op)
6613   - gen_op_sarl_T1_im(16);
  6768 + tcg_gen_sari_i32(tmp2, tmp2, 16);
6614 6769 else
6615   - gen_sxth(cpu_T[1]);
6616   - gen_op_imulw_T0_T1();
  6770 + gen_sxth(tmp2);
  6771 + gen_imulw(tmp, tmp2);
  6772 + dead_tmp(tmp2);
6617 6773 if (rs != 15)
6618 6774 {
6619   - gen_movl_T1_reg(s, rs);
6620   - gen_op_addl_T0_T1_setq();
  6775 + tmp2 = load_reg(s, rs);
  6776 + gen_helper_add_setq(tmp, tmp, tmp2);
  6777 + dead_tmp(tmp2);
6621 6778 }
6622   - gen_movl_reg_T0(s, rd);
6623 6779 break;
6624 6780 case 5: case 6: /* 32 * 32 -> 32msb */
6625   - gen_op_imull_T0_T1();
6626   - if (insn & (1 << 5))
6627   - gen_op_roundqd_T0_T1();
6628   - else
6629   - gen_op_movl_T0_T1();
  6781 + gen_imull(tmp, tmp2);
  6782 + if (insn & (1 << 5)) {
  6783 + gen_roundqd(tmp, tmp2);
  6784 + dead_tmp(tmp2);
  6785 + } else {
  6786 + dead_tmp(tmp);
  6787 + tmp = tmp2;
  6788 + }
6630 6789 if (rs != 15) {
6631   - gen_movl_T1_reg(s, rs);
  6790 + tmp2 = load_reg(s, rs);
6632 6791 if (insn & (1 << 21)) {
6633   - gen_op_addl_T0_T1();
  6792 + tcg_gen_add_i32(tmp, tmp, tmp2);
6634 6793 } else {
6635   - gen_op_rsbl_T0_T1();
  6794 + tcg_gen_sub_i32(tmp, tmp2, tmp);
6636 6795 }
  6796 + dead_tmp(tmp2);
6637 6797 }
6638   - gen_movl_reg_T0(s, rd);
6639 6798 break;
6640 6799 case 7: /* Unsigned sum of absolute differences. */
6641   - gen_helper_usad8(cpu_T[0], cpu_T[0], cpu_T[1]);
  6800 + gen_helper_usad8(tmp, tmp, tmp2);
  6801 + dead_tmp(tmp2);
6642 6802 if (rs != 15) {
6643   - gen_movl_T1_reg(s, rs);
6644   - gen_op_addl_T0_T1();
  6803 + tmp2 = load_reg(s, rs);
  6804 + tcg_gen_add_i32(tmp, tmp, tmp2);
  6805 + dead_tmp(tmp2);
6645 6806 }
6646   - gen_movl_reg_T0(s, rd);
6647 6807 break;
6648 6808 }
  6809 + store_reg(s, rd, tmp);
6649 6810 break;
6650 6811 case 6: case 7: /* 64-bit multiply, Divide. */
6651 6812 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
... ... @@ -6681,7 +6842,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6681 6842 } else {
6682 6843 if (op & 8) {
6683 6844 /* smlalxy */
6684   - gen_mulxy(op & 2, op & 1);
  6845 + gen_mulxy(cpu_T[0], cpu_T[1], op & 2, op & 1);
6685 6846 gen_op_signbit_T1_T0();
6686 6847 } else {
6687 6848 /* Signed 64-bit multiply */
... ... @@ -6745,8 +6906,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6745 6906 } else {
6746 6907 /* blx */
6747 6908 addr &= ~(uint32_t)2;
6748   - gen_op_movl_T0_im(addr);
6749   - gen_bx(s);
  6909 + gen_bx_im(s, addr);
6750 6910 }
6751 6911 } else if (((insn >> 23) & 7) == 7) {
6752 6912 /* Misc control */
... ... @@ -6822,8 +6982,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6822 6982 break;
6823 6983 case 4: /* bxj */
6824 6984 /* Trivial implementation equivalent to bx. */
6825   - gen_movl_T0_reg(s, rn);
6826   - gen_bx(s);
  6985 + tmp = load_reg(s, rn);
  6986 + gen_bx(s, tmp);
6827 6987 break;
6828 6988 case 5: /* Exception return. */
6829 6989 /* Unpredictable in user mode. */
... ... @@ -6832,7 +6992,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6832 6992 if (IS_M(env)) {
6833 6993 gen_op_v7m_mrs_T0(insn & 0xff);
6834 6994 } else {
6835   - gen_op_movl_T0_cpsr();
  6995 + gen_helper_cpsr_read(cpu_T[0]);
6836 6996 }
6837 6997 gen_movl_reg_T0(s, rd);
6838 6998 break;
... ... @@ -6840,8 +7000,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6840 7000 /* Not accessible in user mode. */
6841 7001 if (IS_USER(s) || IS_M(env))
6842 7002 goto illegal_op;
6843   - gen_op_movl_T0_spsr();
6844   - gen_movl_reg_T0(s, rd);
  7003 + tmp = load_cpu_field(spsr);
  7004 + store_reg(s, rd, tmp);
6845 7005 break;
6846 7006 }
6847 7007 }
... ... @@ -6850,7 +7010,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6850 7010 op = (insn >> 22) & 0xf;
6851 7011 /* Generate a conditional jump to next instruction. */
6852 7012 s->condlabel = gen_new_label();
6853   - gen_test_cc[op ^ 1](s->condlabel);
  7013 + gen_test_cc(op ^ 1, s->condlabel);
6854 7014 s->condjmp = 1;
6855 7015  
6856 7016 /* offset[11:1] = insn[10:0] */
... ... @@ -7095,7 +7255,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7095 7255 default: goto illegal_op;
7096 7256 }
7097 7257 if (rs == 15) {
7098   - gen_bx(s);
  7258 + gen_bx_T0(s);
7099 7259 } else {
7100 7260 gen_movl_reg_T0(s, rs);
7101 7261 }
... ... @@ -7132,11 +7292,12 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7132 7292 int32_t offset;
7133 7293 int i;
7134 7294 TCGv tmp;
  7295 + TCGv tmp2;
7135 7296  
7136 7297 if (s->condexec_mask) {
7137 7298 cond = s->condexec_cond;
7138 7299 s->condlabel = gen_new_label();
7139   - gen_test_cc[cond ^ 1](s->condlabel);
  7300 + gen_test_cc(cond ^ 1, s->condlabel);
7140 7301 s->condjmp = 1;
7141 7302 }
7142 7303  
... ... @@ -7254,8 +7415,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7254 7415 gen_op_movl_T1_im(val);
7255 7416 gen_movl_reg_T1(s, 14);
7256 7417 }
7257   - gen_movl_T0_reg(s, rm);
7258   - gen_bx(s);
  7418 + tmp = load_reg(s, rm);
  7419 + gen_bx(s, tmp);
7259 7420 break;
7260 7421 }
7261 7422 break;
... ... @@ -7597,19 +7758,20 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7597 7758 gen_movl_reg_T1(s, 13);
7598 7759 /* set the new PC value */
7599 7760 if ((insn & 0x0900) == 0x0900)
7600   - gen_bx(s);
  7761 + gen_bx_T0(s);
7601 7762 break;
7602 7763  
7603 7764 case 1: case 3: case 9: case 11: /* czb */
7604 7765 rm = insn & 7;
7605   - gen_movl_T0_reg(s, rm);
  7766 + tmp = load_reg(s, rm);
  7767 + tmp2 = tcg_const_i32(0);
7606 7768 s->condlabel = gen_new_label();
7607 7769 s->condjmp = 1;
7608 7770 if (insn & (1 << 11))
7609   - gen_op_testn_T0(s->condlabel);
  7771 + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
7610 7772 else
7611   - gen_op_test_T0(s->condlabel);
7612   -
  7773 + tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
  7774 + dead_tmp(tmp);
7613 7775 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
7614 7776 val = (uint32_t)s->pc + 2;
7615 7777 val += offset;
... ... @@ -7631,7 +7793,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7631 7793 gen_set_condexec(s);
7632 7794 gen_op_movl_T0_im((long)s->pc - 2);
7633 7795 gen_set_pc_T0();
7634   - gen_op_bkpt();
  7796 + gen_exception(EXCP_BKPT);
7635 7797 s->is_jmp = DISAS_JUMP;
7636 7798 break;
7637 7799  
... ... @@ -7722,7 +7884,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7722 7884 }
7723 7885 /* generate a conditional jump to next instruction */
7724 7886 s->condlabel = gen_new_label();
7725   - gen_test_cc[cond ^ 1](s->condlabel);
  7887 + gen_test_cc(cond ^ 1, s->condlabel);
7726 7888 s->condjmp = 1;
7727 7889 gen_movl_T1_reg(s, 15);
7728 7890  
... ... @@ -7756,7 +7918,7 @@ undef32:
7756 7918 gen_set_condexec(s);
7757 7919 gen_op_movl_T0_im((long)s->pc - 4);
7758 7920 gen_set_pc_T0();
7759   - gen_op_undef_insn();
  7921 + gen_exception(EXCP_UDEF);
7760 7922 s->is_jmp = DISAS_JUMP;
7761 7923 return;
7762 7924 illegal_op:
... ... @@ -7764,7 +7926,7 @@ undef:
7764 7926 gen_set_condexec(s);
7765 7927 gen_op_movl_T0_im((long)s->pc - 2);
7766 7928 gen_set_pc_T0();
7767   - gen_op_undef_insn();
  7929 + gen_exception(EXCP_UDEF);
7768 7930 s->is_jmp = DISAS_JUMP;
7769 7931 }
7770 7932  
... ... @@ -7814,15 +7976,14 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7814 7976 {
7815 7977 TCGv tmp = new_tmp();
7816 7978 tcg_gen_movi_i32(tmp, 0);
7817   - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, condexec_bits));
7818   - dead_tmp(tmp);
  7979 + store_cpu_field(tmp, condexec_bits);
7819 7980 }
7820 7981 do {
7821 7982 #ifndef CONFIG_USER_ONLY
7822 7983 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
7823 7984 /* We always get here via a jump, so know we are not in a
7824 7985 conditional execution block. */
7825   - gen_op_exception_exit();
  7986 + gen_exception(EXCP_EXCEPTION_EXIT);
7826 7987 }
7827 7988 #endif
7828 7989  
... ... @@ -7832,7 +7993,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7832 7993 gen_set_condexec(dc);
7833 7994 gen_op_movl_T0_im((long)dc->pc);
7834 7995 gen_set_pc_T0();
7835   - gen_op_debug();
  7996 + gen_exception(EXCP_DEBUG);
7836 7997 dc->is_jmp = DISAS_JUMP;
7837 7998 /* Advance PC so that clearing the breakpoint will
7838 7999 invalidate this TB. */
... ... @@ -7897,9 +8058,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7897 8058 if (dc->condjmp) {
7898 8059 gen_set_condexec(dc);
7899 8060 if (dc->is_jmp == DISAS_SWI) {
7900   - gen_op_swi();
  8061 + gen_exception(EXCP_SWI);
7901 8062 } else {
7902   - gen_op_debug();
  8063 + gen_exception(EXCP_DEBUG);
7903 8064 }
7904 8065 gen_set_label(dc->condlabel);
7905 8066 }
... ... @@ -7910,11 +8071,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7910 8071 }
7911 8072 gen_set_condexec(dc);
7912 8073 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
7913   - gen_op_swi();
  8074 + gen_exception(EXCP_SWI);
7914 8075 } else {
7915 8076 /* FIXME: Single stepping a WFI insn will not halt
7916 8077 the CPU. */
7917   - gen_op_debug();
  8078 + gen_exception(EXCP_DEBUG);
7918 8079 }
7919 8080 } else {
7920 8081 /* While branches must always occur at the end of an IT block,
... ... @@ -7940,10 +8101,10 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7940 8101 /* nothing more to generate */
7941 8102 break;
7942 8103 case DISAS_WFI:
7943   - gen_op_wfi();
  8104 + gen_helper_wfi();
7944 8105 break;
7945 8106 case DISAS_SWI:
7946   - gen_op_swi();
  8107 + gen_exception(EXCP_SWI);
7947 8108 break;
7948 8109 }
7949 8110 if (dc->condjmp) {
... ...