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 #define DEF_HELPER(name, ret, args) ret glue(helper_,name) args; 1 #define DEF_HELPER(name, ret, args) ret glue(helper_,name) args;
2 2
3 #ifdef GEN_HELPER 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 #define DEF_HELPER_1_1(name, ret, args) \ 28 #define DEF_HELPER_1_1(name, ret, args) \
5 DEF_HELPER(name, ret, args) \ 29 DEF_HELPER(name, ret, args) \
6 static inline void gen_helper_##name(TCGv ret, TCGv arg1) \ 30 static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
@@ -21,6 +45,10 @@ static inline void gen_helper_##name(TCGv ret, \ @@ -21,6 +45,10 @@ static inline void gen_helper_##name(TCGv ret, \
21 tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \ 45 tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \
22 } 46 }
23 #else /* !GEN_HELPER */ 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 #define DEF_HELPER_1_1 DEF_HELPER 52 #define DEF_HELPER_1_1 DEF_HELPER
25 #define DEF_HELPER_1_2 DEF_HELPER 53 #define DEF_HELPER_1_2 DEF_HELPER
26 #define DEF_HELPER_1_3 DEF_HELPER 54 #define DEF_HELPER_1_3 DEF_HELPER
@@ -74,8 +102,18 @@ DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t)) @@ -74,8 +102,18 @@ DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t))
74 DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t)) 102 DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t))
75 103
76 DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t)) 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 #undef DEF_HELPER 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 #undef DEF_HELPER_1_1 116 #undef DEF_HELPER_1_1
80 #undef DEF_HELPER_1_2 117 #undef DEF_HELPER_1_2
  118 +#undef DEF_HELPER_1_3
81 #undef GEN_HELPER 119 #undef GEN_HELPER
target-arm/op.c
@@ -80,151 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1) @@ -80,151 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1)
80 80
81 OPSUB(rsb, rsc, T0, T1, T0) 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 void OPPROTO op_addq_T0_T1(void) 83 void OPPROTO op_addq_T0_T1(void)
229 { 84 {
230 uint64_t res; 85 uint64_t res;
@@ -397,45 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void) @@ -397,45 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void)
397 FORCE_RET(); 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 /* VFP support. We follow the convention used for VFP instrunctions: 255 /* VFP support. We follow the convention used for VFP instrunctions:
440 Single precition routines have a "s" suffix, double precision a 256 Single precition routines have a "s" suffix, double precision a
441 "d" suffix. */ 257 "d" suffix. */
target-arm/op_helper.c
@@ -436,3 +436,26 @@ uint32_t HELPER(usat16)(uint32_t x, uint32_t shift) @@ -436,3 +436,26 @@ uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
436 res |= do_usat(((int32_t)x) >> 16, shift) << 16; 436 res |= do_usat(((int32_t)x) >> 16, shift) << 16;
437 return res; 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,6 +130,24 @@ static void dead_tmp(TCGv tmp)
130 temps[i] = tmp; 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 /* Set a variable to the value of a CPU register. */ 151 /* Set a variable to the value of a CPU register. */
134 static void load_reg_var(DisasContext *s, TCGv var, int reg) 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,6 +240,18 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
222 /* Copy the most significant bit of T0 to all bits of T1. */ 240 /* Copy the most significant bit of T0 to all bits of T1. */
223 #define gen_op_signbit_T1_T0() tcg_gen_sari_i32(cpu_T[1], cpu_T[0], 31) 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 static void gen_smul_dual(TCGv a, TCGv b) 255 static void gen_smul_dual(TCGv a, TCGv b)
226 { 256 {
227 TCGv tmp1 = new_tmp(); 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,10 +323,11 @@ static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
293 tcg_gen_or_i32(dest, base, val); 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 /* FIXME: Most targets have native widening multiplication. 333 /* FIXME: Most targets have native widening multiplication.
@@ -316,17 +347,27 @@ static void gen_op_mull_T0_T1(void) @@ -316,17 +347,27 @@ static void gen_op_mull_T0_T1(void)
316 } 347 }
317 348
318 /* Signed 32x32->64 multiply. */ 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 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64); 352 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
322 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64); 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 tcg_gen_mul_i64(tmp1, tmp1, tmp2); 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 tcg_gen_shri_i64(tmp1, tmp1, 32); 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 /* Swap low and high halfwords. */ 373 /* Swap low and high halfwords. */
@@ -379,9 +420,9 @@ static inline void gen_logic_CC(TCGv var) @@ -379,9 +420,9 @@ static inline void gen_logic_CC(TCGv var)
379 /* T0 += T1 + CF. */ 420 /* T0 += T1 + CF. */
380 static void gen_adc_T0_T1(void) 421 static void gen_adc_T0_T1(void)
381 { 422 {
382 - TCGv tmp = new_tmp(); 423 + TCGv tmp;
383 gen_op_addl_T0_T1(); 424 gen_op_addl_T0_T1();
384 - tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); 425 + tmp = load_cpu_field(CF);
385 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp); 426 tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
386 dead_tmp(tmp); 427 dead_tmp(tmp);
387 } 428 }
@@ -389,9 +430,9 @@ static void gen_adc_T0_T1(void) @@ -389,9 +430,9 @@ static void gen_adc_T0_T1(void)
389 /* dest = T0 - T1 + CF - 1. */ 430 /* dest = T0 - T1 + CF - 1. */
390 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) 431 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
391 { 432 {
392 - TCGv tmp = new_tmp(); 433 + TCGv tmp;
393 tcg_gen_sub_i32(dest, t0, t1); 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 tcg_gen_add_i32(dest, dest, tmp); 436 tcg_gen_add_i32(dest, dest, tmp);
396 tcg_gen_subi_i32(dest, dest, 1); 437 tcg_gen_subi_i32(dest, dest, 1);
397 dead_tmp(tmp); 438 dead_tmp(tmp);
@@ -482,8 +523,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) @@ -482,8 +523,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
482 shifter_out_im(var, shift - 1); 523 shifter_out_im(var, shift - 1);
483 tcg_gen_rori_i32(var, var, shift); break; 524 tcg_gen_rori_i32(var, var, shift); break;
484 } else { 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 if (flags) 527 if (flags)
488 shifter_out_im(var, 0); 528 shifter_out_im(var, 0);
489 tcg_gen_shri_i32(var, var, 1); 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,7 +543,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
503 case 4: gen_pas_helper(glue(pfx,add8)); break; \ 543 case 4: gen_pas_helper(glue(pfx,add8)); break; \
504 case 7: gen_pas_helper(glue(pfx,sub8)); break; \ 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 TCGv tmp; 548 TCGv tmp;
509 549
@@ -548,7 +588,7 @@ void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b) @@ -548,7 +588,7 @@ void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
548 case 5: gen_pas_helper(glue(pfx,sub16)); break; \ 588 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
549 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \ 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 TCGv tmp; 593 TCGv tmp;
554 594
@@ -583,22 +623,105 @@ void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) @@ -583,22 +623,105 @@ void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
583 } 623 }
584 #undef PAS_OP 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 const uint8_t table_logic_cc[16] = { 726 const uint8_t table_logic_cc[16] = {
604 1, /* and */ 727 1, /* and */
@@ -633,18 +756,41 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = { @@ -633,18 +756,41 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = {
633 gen_op_rorl_T1_T0_cc, 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 TCGv tmp; 762 TCGv tmp;
640 763
641 s->is_jmp = DISAS_UPDATE; 764 s->is_jmp = DISAS_UPDATE;
642 tmp = new_tmp(); 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 dead_tmp(tmp); 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 #if defined(CONFIG_USER_ONLY) 796 #if defined(CONFIG_USER_ONLY)
@@ -1312,8 +1458,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1312,8 +1458,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1312 return 1; 1458 return 1;
1313 } 1459 }
1314 gen_op_shll_T1_im(28); 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 break; 1462 break;
1318 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ 1463 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1319 rd = (insn >> 12) & 0xf; 1464 rd = (insn >> 12) & 0xf;
@@ -1359,7 +1504,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1359,7 +1504,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1359 case 3: 1504 case 3:
1360 return 1; 1505 return 1;
1361 } 1506 }
1362 - gen_op_movl_cpsr_T0(0xf0000000); 1507 + gen_set_nzcv(cpu_T[0]);
1363 break; 1508 break;
1364 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ 1509 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1365 wrd = (insn >> 12) & 0xf; 1510 wrd = (insn >> 12) & 0xf;
@@ -1405,9 +1550,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1405,9 +1550,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1405 case 3: 1550 case 3:
1406 return 1; 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 break; 1554 break;
1412 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ 1555 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1413 rd = (insn >> 12) & 0xf; 1556 rd = (insn >> 12) & 0xf;
@@ -2246,7 +2389,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -2246,7 +2389,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2246 } 2389 }
2247 if (rd == 15) { 2390 if (rd == 15) {
2248 /* Set the 4 flag bits in the CPSR. */ 2391 /* Set the 4 flag bits in the CPSR. */
2249 - gen_op_movl_cpsr_T0(0xf0000000); 2392 + gen_set_nzcv(cpu_T[0]);
2250 } else 2393 } else
2251 gen_movl_reg_T0(s, rd); 2394 gen_movl_reg_T0(s, rd);
2252 } else { 2395 } else {
@@ -2745,26 +2888,25 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) @@ -2745,26 +2888,25 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
2745 if (__builtin_expect(s->singlestep_enabled, 0)) { 2888 if (__builtin_expect(s->singlestep_enabled, 0)) {
2746 /* An indirect jump so that we still trigger the debug exception. */ 2889 /* An indirect jump so that we still trigger the debug exception. */
2747 if (s->thumb) 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 } else { 2893 } else {
2752 gen_goto_tb(s, 0, dest); 2894 gen_goto_tb(s, 0, dest);
2753 s->is_jmp = DISAS_TB_JUMP; 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 if (x) 2901 if (x)
2760 - tcg_gen_sari_i32(cpu_T[0], cpu_T[0], 16); 2902 + tcg_gen_sari_i32(t0, t0, 16);
2761 else 2903 else
2762 - gen_sxth(cpu_T[0]); 2904 + gen_sxth(t0);
2763 if (y) 2905 if (y)
2764 - gen_op_sarl_T1_im(16); 2906 + tcg_gen_sari_i32(t1, t1, 16);
2765 else 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 /* Return the mask of PSR bits set by a MSR instruction. */ 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,13 +2941,19 @@ static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
2799 /* Returns nonzero if access to the PSR is not permitted. */ 2941 /* Returns nonzero if access to the PSR is not permitted. */
2800 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr) 2942 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
2801 { 2943 {
  2944 + TCGv tmp;
2802 if (spsr) { 2945 if (spsr) {
2803 /* ??? This is also undefined in system mode. */ 2946 /* ??? This is also undefined in system mode. */
2804 if (IS_USER(s)) 2947 if (IS_USER(s))
2805 return 1; 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 } else { 2955 } else {
2808 - gen_op_movl_cpsr_T0(mask); 2956 + gen_set_cpsr(cpu_T[0], mask);
2809 } 2957 }
2810 gen_lookup_tb(s); 2958 gen_lookup_tb(s);
2811 return 0; 2959 return 0;
@@ -2814,16 +2962,18 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr) @@ -2814,16 +2962,18 @@ static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
2814 /* Generate an old-style exception return. */ 2962 /* Generate an old-style exception return. */
2815 static void gen_exception_return(DisasContext *s) 2963 static void gen_exception_return(DisasContext *s)
2816 { 2964 {
  2965 + TCGv tmp;
2817 gen_set_pc_T0(); 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 s->is_jmp = DISAS_UPDATE; 2970 s->is_jmp = DISAS_UPDATE;
2821 } 2971 }
2822 2972
2823 /* Generate a v6 exception return. */ 2973 /* Generate a v6 exception return. */
2824 static void gen_rfe(DisasContext *s) 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 gen_op_movl_T0_T2(); 2977 gen_op_movl_T0_T2();
2828 gen_set_pc_T0(); 2978 gen_set_pc_T0();
2829 s->is_jmp = DISAS_UPDATE; 2979 s->is_jmp = DISAS_UPDATE;
@@ -2836,8 +2986,7 @@ gen_set_condexec (DisasContext *s) @@ -2836,8 +2986,7 @@ gen_set_condexec (DisasContext *s)
2836 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); 2986 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
2837 TCGv tmp = new_tmp(); 2987 TCGv tmp = new_tmp();
2838 tcg_gen_movi_i32(tmp, val); 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,7 +5176,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5027 gen_op_addl_T1_im(offset); 5176 gen_op_addl_T1_im(offset);
5028 gen_movl_T0_reg(s, 14); 5177 gen_movl_T0_reg(s, 14);
5029 gen_ldst(stl, s); 5178 gen_ldst(stl, s);
5030 - gen_op_movl_T0_cpsr(); 5179 + gen_helper_cpsr_read(cpu_T[0]);
5031 gen_op_addl_T1_im(4); 5180 gen_op_addl_T1_im(4);
5032 gen_ldst(stl, s); 5181 gen_ldst(stl, s);
5033 if (insn & (1 << 21)) { 5182 if (insn & (1 << 21)) {
@@ -5089,16 +5238,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5089,16 +5238,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5089 int32_t offset; 5238 int32_t offset;
5090 5239
5091 val = (uint32_t)s->pc; 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 /* Sign-extend the 24-bit offset */ 5244 /* Sign-extend the 24-bit offset */
5095 offset = (((int32_t)insn) << 8) >> 8; 5245 offset = (((int32_t)insn) << 8) >> 8;
5096 /* offset * 4 + bit24 * 2 + (thumb bit) */ 5246 /* offset * 4 + bit24 * 2 + (thumb bit) */
5097 val += (offset << 2) | ((insn >> 23) & 2) | 1; 5247 val += (offset << 2) | ((insn >> 23) & 2) | 1;
5098 /* pipeline offset */ 5248 /* pipeline offset */
5099 val += 4; 5249 val += 4;
5100 - gen_op_movl_T0_im(val);  
5101 - gen_bx(s); 5250 + gen_bx_im(s, val);
5102 return; 5251 return;
5103 } else if ((insn & 0x0e000f00) == 0x0c000100) { 5252 } else if ((insn & 0x0e000f00) == 0x0c000100) {
5104 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 5253 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
@@ -5144,7 +5293,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5144,7 +5293,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5144 /* if not always execute, we generate a conditional jump to 5293 /* if not always execute, we generate a conditional jump to
5145 next instruction */ 5294 next instruction */
5146 s->condlabel = gen_new_label(); 5295 s->condlabel = gen_new_label();
5147 - gen_test_cc[cond ^ 1](s->condlabel); 5296 + gen_test_cc(cond ^ 1, s->condlabel);
5148 s->condjmp = 1; 5297 s->condjmp = 1;
5149 } 5298 }
5150 if ((insn & 0x0f900000) == 0x03000000) { 5299 if ((insn & 0x0f900000) == 0x03000000) {
@@ -5201,18 +5350,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5201,18 +5350,19 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5201 if (op1 & 2) { 5350 if (op1 & 2) {
5202 if (IS_USER(s)) 5351 if (IS_USER(s))
5203 goto illegal_op; 5352 goto illegal_op;
5204 - gen_op_movl_T0_spsr(); 5353 + tmp = load_cpu_field(spsr);
5205 } else { 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 break; 5360 break;
5211 case 0x1: 5361 case 0x1:
5212 if (op1 == 1) { 5362 if (op1 == 1) {
5213 /* branch/exchange thumb (bx). */ 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 } else if (op1 == 3) { 5366 } else if (op1 == 3) {
5217 /* clz */ 5367 /* clz */
5218 rd = (insn >> 12) & 0xf; 5368 rd = (insn >> 12) & 0xf;
@@ -5227,8 +5377,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5227,8 +5377,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5227 if (op1 == 1) { 5377 if (op1 == 1) {
5228 ARCH(5J); /* bxj */ 5378 ARCH(5J); /* bxj */
5229 /* Trivial implementation equivalent to bx. */ 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 } else { 5382 } else {
5233 goto illegal_op; 5383 goto illegal_op;
5234 } 5384 }
@@ -5238,11 +5388,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5238,11 +5388,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5238 goto illegal_op; 5388 goto illegal_op;
5239 5389
5240 /* branch link/exchange thumb (blx) */ 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 break; 5396 break;
5247 case 0x5: /* saturating add/subtract */ 5397 case 0x5: /* saturating add/subtract */
5248 rd = (insn >> 12) & 0xf; 5398 rd = (insn >> 12) & 0xf;
@@ -5261,7 +5411,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5261,7 +5411,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5261 gen_set_condexec(s); 5411 gen_set_condexec(s);
5262 gen_op_movl_T0_im((long)s->pc - 4); 5412 gen_op_movl_T0_im((long)s->pc - 4);
5263 gen_set_pc_T0(); 5413 gen_set_pc_T0();
5264 - gen_op_bkpt(); 5414 + gen_exception(EXCP_BKPT);
5265 s->is_jmp = DISAS_JUMP; 5415 s->is_jmp = DISAS_JUMP;
5266 break; 5416 break;
5267 case 0x8: /* signed multiply */ 5417 case 0x8: /* signed multiply */
@@ -5279,7 +5429,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5279,7 +5429,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5279 gen_op_sarl_T1_im(16); 5429 gen_op_sarl_T1_im(16);
5280 else 5430 else
5281 gen_sxth(cpu_T[1]); 5431 gen_sxth(cpu_T[1]);
5282 - gen_op_imulw_T0_T1(); 5432 + gen_imulw(cpu_T[0], cpu_T[1]);
5283 if ((sh & 2) == 0) { 5433 if ((sh & 2) == 0) {
5284 gen_movl_T1_reg(s, rn); 5434 gen_movl_T1_reg(s, rn);
5285 gen_op_addl_T0_T1_setq(); 5435 gen_op_addl_T0_T1_setq();
@@ -5289,7 +5439,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5289,7 +5439,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5289 /* 16 * 16 */ 5439 /* 16 * 16 */
5290 gen_movl_T0_reg(s, rm); 5440 gen_movl_T0_reg(s, rm);
5291 gen_movl_T1_reg(s, rs); 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 if (op1 == 2) { 5443 if (op1 == 2) {
5294 gen_op_signbit_T1_T0(); 5444 gen_op_signbit_T1_T0();
5295 gen_op_addq_T0_T1(rn, rd); 5445 gen_op_addq_T0_T1(rn, rd);
@@ -5758,7 +5908,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5758,7 +5908,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5758 /* Signed multiply most significant [accumulate]. */ 5908 /* Signed multiply most significant [accumulate]. */
5759 gen_op_imull_T0_T1(); 5909 gen_op_imull_T0_T1();
5760 if (insn & (1 << 5)) 5910 if (insn & (1 << 5))
5761 - gen_op_roundqd_T0_T1(); 5911 + gen_roundqd(cpu_T[0], cpu_T[1]);
5762 else 5912 else
5763 gen_op_movl_T0_T1(); 5913 gen_op_movl_T0_T1();
5764 if (rn != 15) { 5914 if (rn != 15) {
@@ -5926,7 +6076,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5926,7 +6076,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5926 if (insn & (1 << 20)) { 6076 if (insn & (1 << 20)) {
5927 /* Complete the load. */ 6077 /* Complete the load. */
5928 if (rd == 15) 6078 if (rd == 15)
5929 - gen_bx(s); 6079 + gen_bx_T0(s);
5930 else 6080 else
5931 gen_movl_reg_T0(s, rd); 6081 gen_movl_reg_T0(s, rd);
5932 } 6082 }
@@ -5980,7 +6130,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5980,7 +6130,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5980 /* load */ 6130 /* load */
5981 gen_ldst(ldl, s); 6131 gen_ldst(ldl, s);
5982 if (i == 15) { 6132 if (i == 15) {
5983 - gen_bx(s); 6133 + gen_bx_T0(s);
5984 } else if (user) { 6134 } else if (user) {
5985 gen_op_movl_user_T0(i); 6135 gen_op_movl_user_T0(i);
5986 } else if (i == rn) { 6136 } else if (i == rn) {
@@ -6035,8 +6185,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6035,8 +6185,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6035 } 6185 }
6036 if ((insn & (1 << 22)) && !user) { 6186 if ((insn & (1 << 22)) && !user) {
6037 /* Restore CPSR from SPSR. */ 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 s->is_jmp = DISAS_UPDATE; 6191 s->is_jmp = DISAS_UPDATE;
6041 } 6192 }
6042 } 6193 }
@@ -6075,7 +6226,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6075,7 +6226,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6075 gen_set_condexec(s); 6226 gen_set_condexec(s);
6076 gen_op_movl_T0_im((long)s->pc - 4); 6227 gen_op_movl_T0_im((long)s->pc - 4);
6077 gen_set_pc_T0(); 6228 gen_set_pc_T0();
6078 - gen_op_undef_insn(); 6229 + gen_exception(EXCP_UDEF);
6079 s->is_jmp = DISAS_JUMP; 6230 s->is_jmp = DISAS_JUMP;
6080 break; 6231 break;
6081 } 6232 }
@@ -6186,29 +6337,28 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6186,29 +6337,28 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6186 if ((insn & (1 << 12)) == 0) { 6337 if ((insn & (1 << 12)) == 0) {
6187 /* Second half of blx. */ 6338 /* Second half of blx. */
6188 offset = ((insn & 0x7ff) << 1); 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 addr = (uint32_t)s->pc; 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 return 0; 6349 return 0;
6200 } 6350 }
6201 if (insn & (1 << 11)) { 6351 if (insn & (1 << 11)) {
6202 /* Second half of bl. */ 6352 /* Second half of bl. */
6203 offset = ((insn & 0x7ff) << 1) | 1; 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 addr = (uint32_t)s->pc; 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 return 0; 6362 return 0;
6213 } 6363 }
6214 if ((s->pc & ~TARGET_PAGE_MASK) == 0) { 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,7 +6538,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6388 } 6538 }
6389 gen_movl_T0_reg(s, 14); 6539 gen_movl_T0_reg(s, 14);
6390 gen_ldst(stl, s); 6540 gen_ldst(stl, s);
6391 - gen_op_movl_T0_cpsr(); 6541 + gen_helper_cpsr_read(cpu_T[0]);
6392 gen_op_addl_T1_im(4); 6542 gen_op_addl_T1_im(4);
6393 gen_ldst(stl, s); 6543 gen_ldst(stl, s);
6394 if (insn & (1 << 21)) { 6544 if (insn & (1 << 21)) {
@@ -6424,7 +6574,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6424,7 +6574,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6424 /* Load. */ 6574 /* Load. */
6425 gen_ldst(ldl, s); 6575 gen_ldst(ldl, s);
6426 if (i == 15) { 6576 if (i == 15) {
6427 - gen_bx(s); 6577 + gen_bx_T0(s);
6428 } else { 6578 } else {
6429 gen_movl_reg_T0(s, i); 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,125 +6677,136 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6527 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); 6677 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
6528 if (op < 4) { 6678 if (op < 4) {
6529 /* Saturating add/subtract. */ 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 if (op & 2) 6682 if (op & 2)
6533 - gen_helper_double_saturate(cpu_T[1], cpu_T[1]); 6683 + gen_helper_double_saturate(tmp, tmp);
6534 if (op & 1) 6684 if (op & 1)
6535 - gen_op_subl_T0_T1_saturate(); 6685 + gen_helper_sub_saturate(tmp, tmp2, tmp);
6536 else 6686 else
6537 - gen_op_addl_T0_T1_saturate(); 6687 + gen_helper_add_saturate(tmp, tmp, tmp2);
  6688 + dead_tmp(tmp2);
6538 } else { 6689 } else {
6539 - gen_movl_T0_reg(s, rn); 6690 + tmp = load_reg(s, rn);
6540 switch (op) { 6691 switch (op) {
6541 case 0x0a: /* rbit */ 6692 case 0x0a: /* rbit */
6542 - gen_helper_rbit(cpu_T[0], cpu_T[0]); 6693 + gen_helper_rbit(tmp, tmp);
6543 break; 6694 break;
6544 case 0x08: /* rev */ 6695 case 0x08: /* rev */
6545 - gen_op_rev_T0(); 6696 + tcg_gen_bswap_i32(tmp, tmp);
6546 break; 6697 break;
6547 case 0x09: /* rev16 */ 6698 case 0x09: /* rev16 */
6548 - gen_rev16(cpu_T[0]); 6699 + gen_rev16(tmp);
6549 break; 6700 break;
6550 case 0x0b: /* revsh */ 6701 case 0x0b: /* revsh */
6551 - gen_revsh(cpu_T[0]); 6702 + gen_revsh(tmp);
6552 break; 6703 break;
6553 case 0x10: /* sel */ 6704 case 0x10: /* sel */
6554 - gen_movl_T1_reg(s, rm); 6705 + tmp2 = load_reg(s, rm);
6555 tmp3 = new_tmp(); 6706 tmp3 = new_tmp();
6556 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE)); 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 dead_tmp(tmp3); 6709 dead_tmp(tmp3);
  6710 + dead_tmp(tmp2);
6559 break; 6711 break;
6560 case 0x18: /* clz */ 6712 case 0x18: /* clz */
6561 - gen_helper_clz(cpu_T[0], cpu_T[0]); 6713 + gen_helper_clz(tmp, tmp);
6562 break; 6714 break;
6563 default: 6715 default:
6564 goto illegal_op; 6716 goto illegal_op;
6565 } 6717 }
6566 } 6718 }
6567 - gen_movl_reg_T0(s, rd); 6719 + store_reg(s, rd, tmp);
6568 break; 6720 break;
6569 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ 6721 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
6570 op = (insn >> 4) & 0xf; 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 switch ((insn >> 20) & 7) { 6725 switch ((insn >> 20) & 7) {
6574 case 0: /* 32 x 32 -> 32 */ 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 if (rs != 15) { 6729 if (rs != 15) {
6577 - gen_movl_T1_reg(s, rs); 6730 + tmp2 = load_reg(s, rs);
6578 if (op) 6731 if (op)
6579 - gen_op_rsbl_T0_T1(); 6732 + tcg_gen_sub_i32(tmp, tmp2, tmp);
6580 else 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 break; 6737 break;
6585 case 1: /* 16 x 16 -> 32 */ 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 if (rs != 15) { 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 break; 6746 break;
6593 case 2: /* Dual multiply add. */ 6747 case 2: /* Dual multiply add. */
6594 case 4: /* Dual multiply subtract. */ 6748 case 4: /* Dual multiply subtract. */
6595 if (op) 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 /* This addition cannot overflow. */ 6752 /* This addition cannot overflow. */
6599 if (insn & (1 << 22)) { 6753 if (insn & (1 << 22)) {
6600 - gen_op_subl_T0_T1(); 6754 + tcg_gen_sub_i32(tmp, tmp, tmp2);
6601 } else { 6755 } else {
6602 - gen_op_addl_T0_T1(); 6756 + tcg_gen_add_i32(tmp, tmp, tmp2);
6603 } 6757 }
  6758 + dead_tmp(tmp2);
6604 if (rs != 15) 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 break; 6765 break;
6611 case 3: /* 32 * 16 -> 32msb */ 6766 case 3: /* 32 * 16 -> 32msb */
6612 if (op) 6767 if (op)
6613 - gen_op_sarl_T1_im(16); 6768 + tcg_gen_sari_i32(tmp2, tmp2, 16);
6614 else 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 if (rs != 15) 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 break; 6779 break;
6624 case 5: case 6: /* 32 * 32 -> 32msb */ 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 if (rs != 15) { 6789 if (rs != 15) {
6631 - gen_movl_T1_reg(s, rs); 6790 + tmp2 = load_reg(s, rs);
6632 if (insn & (1 << 21)) { 6791 if (insn & (1 << 21)) {
6633 - gen_op_addl_T0_T1(); 6792 + tcg_gen_add_i32(tmp, tmp, tmp2);
6634 } else { 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 break; 6798 break;
6640 case 7: /* Unsigned sum of absolute differences. */ 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 if (rs != 15) { 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 break; 6807 break;
6648 } 6808 }
  6809 + store_reg(s, rd, tmp);
6649 break; 6810 break;
6650 case 6: case 7: /* 64-bit multiply, Divide. */ 6811 case 6: case 7: /* 64-bit multiply, Divide. */
6651 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); 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,7 +6842,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6681 } else { 6842 } else {
6682 if (op & 8) { 6843 if (op & 8) {
6683 /* smlalxy */ 6844 /* smlalxy */
6684 - gen_mulxy(op & 2, op & 1); 6845 + gen_mulxy(cpu_T[0], cpu_T[1], op & 2, op & 1);
6685 gen_op_signbit_T1_T0(); 6846 gen_op_signbit_T1_T0();
6686 } else { 6847 } else {
6687 /* Signed 64-bit multiply */ 6848 /* Signed 64-bit multiply */
@@ -6745,8 +6906,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6745,8 +6906,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6745 } else { 6906 } else {
6746 /* blx */ 6907 /* blx */
6747 addr &= ~(uint32_t)2; 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 } else if (((insn >> 23) & 7) == 7) { 6911 } else if (((insn >> 23) & 7) == 7) {
6752 /* Misc control */ 6912 /* Misc control */
@@ -6822,8 +6982,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6822,8 +6982,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6822 break; 6982 break;
6823 case 4: /* bxj */ 6983 case 4: /* bxj */
6824 /* Trivial implementation equivalent to bx. */ 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 break; 6987 break;
6828 case 5: /* Exception return. */ 6988 case 5: /* Exception return. */
6829 /* Unpredictable in user mode. */ 6989 /* Unpredictable in user mode. */
@@ -6832,7 +6992,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6832,7 +6992,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6832 if (IS_M(env)) { 6992 if (IS_M(env)) {
6833 gen_op_v7m_mrs_T0(insn & 0xff); 6993 gen_op_v7m_mrs_T0(insn & 0xff);
6834 } else { 6994 } else {
6835 - gen_op_movl_T0_cpsr(); 6995 + gen_helper_cpsr_read(cpu_T[0]);
6836 } 6996 }
6837 gen_movl_reg_T0(s, rd); 6997 gen_movl_reg_T0(s, rd);
6838 break; 6998 break;
@@ -6840,8 +7000,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6840,8 +7000,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6840 /* Not accessible in user mode. */ 7000 /* Not accessible in user mode. */
6841 if (IS_USER(s) || IS_M(env)) 7001 if (IS_USER(s) || IS_M(env))
6842 goto illegal_op; 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 break; 7005 break;
6846 } 7006 }
6847 } 7007 }
@@ -6850,7 +7010,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) @@ -6850,7 +7010,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6850 op = (insn >> 22) & 0xf; 7010 op = (insn >> 22) & 0xf;
6851 /* Generate a conditional jump to next instruction. */ 7011 /* Generate a conditional jump to next instruction. */
6852 s->condlabel = gen_new_label(); 7012 s->condlabel = gen_new_label();
6853 - gen_test_cc[op ^ 1](s->condlabel); 7013 + gen_test_cc(op ^ 1, s->condlabel);
6854 s->condjmp = 1; 7014 s->condjmp = 1;
6855 7015
6856 /* offset[11:1] = insn[10:0] */ 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,7 +7255,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7095 default: goto illegal_op; 7255 default: goto illegal_op;
7096 } 7256 }
7097 if (rs == 15) { 7257 if (rs == 15) {
7098 - gen_bx(s); 7258 + gen_bx_T0(s);
7099 } else { 7259 } else {
7100 gen_movl_reg_T0(s, rs); 7260 gen_movl_reg_T0(s, rs);
7101 } 7261 }
@@ -7132,11 +7292,12 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7132,11 +7292,12 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7132 int32_t offset; 7292 int32_t offset;
7133 int i; 7293 int i;
7134 TCGv tmp; 7294 TCGv tmp;
  7295 + TCGv tmp2;
7135 7296
7136 if (s->condexec_mask) { 7297 if (s->condexec_mask) {
7137 cond = s->condexec_cond; 7298 cond = s->condexec_cond;
7138 s->condlabel = gen_new_label(); 7299 s->condlabel = gen_new_label();
7139 - gen_test_cc[cond ^ 1](s->condlabel); 7300 + gen_test_cc(cond ^ 1, s->condlabel);
7140 s->condjmp = 1; 7301 s->condjmp = 1;
7141 } 7302 }
7142 7303
@@ -7254,8 +7415,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7254,8 +7415,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7254 gen_op_movl_T1_im(val); 7415 gen_op_movl_T1_im(val);
7255 gen_movl_reg_T1(s, 14); 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 break; 7420 break;
7260 } 7421 }
7261 break; 7422 break;
@@ -7597,19 +7758,20 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7597,19 +7758,20 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7597 gen_movl_reg_T1(s, 13); 7758 gen_movl_reg_T1(s, 13);
7598 /* set the new PC value */ 7759 /* set the new PC value */
7599 if ((insn & 0x0900) == 0x0900) 7760 if ((insn & 0x0900) == 0x0900)
7600 - gen_bx(s); 7761 + gen_bx_T0(s);
7601 break; 7762 break;
7602 7763
7603 case 1: case 3: case 9: case 11: /* czb */ 7764 case 1: case 3: case 9: case 11: /* czb */
7604 rm = insn & 7; 7765 rm = insn & 7;
7605 - gen_movl_T0_reg(s, rm); 7766 + tmp = load_reg(s, rm);
  7767 + tmp2 = tcg_const_i32(0);
7606 s->condlabel = gen_new_label(); 7768 s->condlabel = gen_new_label();
7607 s->condjmp = 1; 7769 s->condjmp = 1;
7608 if (insn & (1 << 11)) 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 else 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 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; 7775 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
7614 val = (uint32_t)s->pc + 2; 7776 val = (uint32_t)s->pc + 2;
7615 val += offset; 7777 val += offset;
@@ -7631,7 +7793,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7631,7 +7793,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7631 gen_set_condexec(s); 7793 gen_set_condexec(s);
7632 gen_op_movl_T0_im((long)s->pc - 2); 7794 gen_op_movl_T0_im((long)s->pc - 2);
7633 gen_set_pc_T0(); 7795 gen_set_pc_T0();
7634 - gen_op_bkpt(); 7796 + gen_exception(EXCP_BKPT);
7635 s->is_jmp = DISAS_JUMP; 7797 s->is_jmp = DISAS_JUMP;
7636 break; 7798 break;
7637 7799
@@ -7722,7 +7884,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -7722,7 +7884,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
7722 } 7884 }
7723 /* generate a conditional jump to next instruction */ 7885 /* generate a conditional jump to next instruction */
7724 s->condlabel = gen_new_label(); 7886 s->condlabel = gen_new_label();
7725 - gen_test_cc[cond ^ 1](s->condlabel); 7887 + gen_test_cc(cond ^ 1, s->condlabel);
7726 s->condjmp = 1; 7888 s->condjmp = 1;
7727 gen_movl_T1_reg(s, 15); 7889 gen_movl_T1_reg(s, 15);
7728 7890
@@ -7756,7 +7918,7 @@ undef32: @@ -7756,7 +7918,7 @@ undef32:
7756 gen_set_condexec(s); 7918 gen_set_condexec(s);
7757 gen_op_movl_T0_im((long)s->pc - 4); 7919 gen_op_movl_T0_im((long)s->pc - 4);
7758 gen_set_pc_T0(); 7920 gen_set_pc_T0();
7759 - gen_op_undef_insn(); 7921 + gen_exception(EXCP_UDEF);
7760 s->is_jmp = DISAS_JUMP; 7922 s->is_jmp = DISAS_JUMP;
7761 return; 7923 return;
7762 illegal_op: 7924 illegal_op:
@@ -7764,7 +7926,7 @@ undef: @@ -7764,7 +7926,7 @@ undef:
7764 gen_set_condexec(s); 7926 gen_set_condexec(s);
7765 gen_op_movl_T0_im((long)s->pc - 2); 7927 gen_op_movl_T0_im((long)s->pc - 2);
7766 gen_set_pc_T0(); 7928 gen_set_pc_T0();
7767 - gen_op_undef_insn(); 7929 + gen_exception(EXCP_UDEF);
7768 s->is_jmp = DISAS_JUMP; 7930 s->is_jmp = DISAS_JUMP;
7769 } 7931 }
7770 7932
@@ -7814,15 +7976,14 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -7814,15 +7976,14 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7814 { 7976 {
7815 TCGv tmp = new_tmp(); 7977 TCGv tmp = new_tmp();
7816 tcg_gen_movi_i32(tmp, 0); 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 do { 7981 do {
7821 #ifndef CONFIG_USER_ONLY 7982 #ifndef CONFIG_USER_ONLY
7822 if (dc->pc >= 0xfffffff0 && IS_M(env)) { 7983 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
7823 /* We always get here via a jump, so know we are not in a 7984 /* We always get here via a jump, so know we are not in a
7824 conditional execution block. */ 7985 conditional execution block. */
7825 - gen_op_exception_exit(); 7986 + gen_exception(EXCP_EXCEPTION_EXIT);
7826 } 7987 }
7827 #endif 7988 #endif
7828 7989
@@ -7832,7 +7993,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -7832,7 +7993,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7832 gen_set_condexec(dc); 7993 gen_set_condexec(dc);
7833 gen_op_movl_T0_im((long)dc->pc); 7994 gen_op_movl_T0_im((long)dc->pc);
7834 gen_set_pc_T0(); 7995 gen_set_pc_T0();
7835 - gen_op_debug(); 7996 + gen_exception(EXCP_DEBUG);
7836 dc->is_jmp = DISAS_JUMP; 7997 dc->is_jmp = DISAS_JUMP;
7837 /* Advance PC so that clearing the breakpoint will 7998 /* Advance PC so that clearing the breakpoint will
7838 invalidate this TB. */ 7999 invalidate this TB. */
@@ -7897,9 +8058,9 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -7897,9 +8058,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7897 if (dc->condjmp) { 8058 if (dc->condjmp) {
7898 gen_set_condexec(dc); 8059 gen_set_condexec(dc);
7899 if (dc->is_jmp == DISAS_SWI) { 8060 if (dc->is_jmp == DISAS_SWI) {
7900 - gen_op_swi(); 8061 + gen_exception(EXCP_SWI);
7901 } else { 8062 } else {
7902 - gen_op_debug(); 8063 + gen_exception(EXCP_DEBUG);
7903 } 8064 }
7904 gen_set_label(dc->condlabel); 8065 gen_set_label(dc->condlabel);
7905 } 8066 }
@@ -7910,11 +8071,11 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -7910,11 +8071,11 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7910 } 8071 }
7911 gen_set_condexec(dc); 8072 gen_set_condexec(dc);
7912 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) { 8073 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
7913 - gen_op_swi(); 8074 + gen_exception(EXCP_SWI);
7914 } else { 8075 } else {
7915 /* FIXME: Single stepping a WFI insn will not halt 8076 /* FIXME: Single stepping a WFI insn will not halt
7916 the CPU. */ 8077 the CPU. */
7917 - gen_op_debug(); 8078 + gen_exception(EXCP_DEBUG);
7918 } 8079 }
7919 } else { 8080 } else {
7920 /* While branches must always occur at the end of an IT block, 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,10 +8101,10 @@ static inline int gen_intermediate_code_internal(CPUState *env,
7940 /* nothing more to generate */ 8101 /* nothing more to generate */
7941 break; 8102 break;
7942 case DISAS_WFI: 8103 case DISAS_WFI:
7943 - gen_op_wfi(); 8104 + gen_helper_wfi();
7944 break; 8105 break;
7945 case DISAS_SWI: 8106 case DISAS_SWI:
7946 - gen_op_swi(); 8107 + gen_exception(EXCP_SWI);
7947 break; 8108 break;
7948 } 8109 }
7949 if (dc->condjmp) { 8110 if (dc->condjmp) {