Commit d9ba48308d50ae08e87dc4ea24cb9783b0568c08
1 parent
6ddbc6e4
ARM TCG conversion 8/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4145 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
409 additions
and
371 deletions
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) { | ... | ... |