Commit 1497c961af2b6d45bd2a1da5a351be54edcadca2
1 parent
9a119ff6
ARM TCG conversion 4/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4141 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
121 additions
and
118 deletions
target-arm/helper.c
@@ -322,7 +322,6 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | @@ -322,7 +322,6 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | ||
322 | env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); | 322 | env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); |
323 | } | 323 | } |
324 | 324 | ||
325 | -#define HELPER(x) helper_##x | ||
326 | /* Sign/zero extend */ | 325 | /* Sign/zero extend */ |
327 | uint32_t HELPER(sxtb16)(uint32_t x) | 326 | uint32_t HELPER(sxtb16)(uint32_t x) |
328 | { | 327 | { |
@@ -1894,4 +1893,3 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, | @@ -1894,4 +1893,3 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, | ||
1894 | } | 1893 | } |
1895 | 1894 | ||
1896 | #endif | 1895 | #endif |
1897 | - |
target-arm/helpers.h
1 | -#ifndef DEF_HELPER | ||
2 | #define DEF_HELPER(name, ret, args) ret helper_##name args; | 1 | #define DEF_HELPER(name, ret, args) ret helper_##name args; |
2 | + | ||
3 | +#ifdef GEN_HELPER | ||
4 | +#define DEF_HELPER_1_1(name, ret, args) \ | ||
5 | +DEF_HELPER(name, ret, args) \ | ||
6 | +static inline void gen_helper_##name(TCGv ret, TCGv arg1) \ | ||
7 | +{ \ | ||
8 | + tcg_gen_helper_1_1(helper_##name, ret, arg1); \ | ||
9 | +} | ||
10 | +#define DEF_HELPER_1_2(name, ret, args) \ | ||
11 | +DEF_HELPER(name, ret, args) \ | ||
12 | +static inline void gen_helper_##name(TCGv ret, TCGv arg1, TCGv arg2) \ | ||
13 | +{ \ | ||
14 | + tcg_gen_helper_1_2(helper_##name, ret, arg1, arg2); \ | ||
15 | +} | ||
16 | +#else /* !GEN_HELPER */ | ||
17 | +#define DEF_HELPER_1_1 DEF_HELPER | ||
18 | +#define DEF_HELPER_1_2 DEF_HELPER | ||
19 | +#define HELPER(x) helper_##x | ||
3 | #endif | 20 | #endif |
4 | 21 | ||
5 | -DEF_HELPER(clz, uint32_t, (uint32_t)) | ||
6 | -DEF_HELPER(sxtb16, uint32_t, (uint32_t)) | ||
7 | -DEF_HELPER(uxtb16, uint32_t, (uint32_t)) | 22 | +DEF_HELPER_1_1(clz, uint32_t, (uint32_t)) |
23 | +DEF_HELPER_1_1(sxtb16, uint32_t, (uint32_t)) | ||
24 | +DEF_HELPER_1_1(uxtb16, uint32_t, (uint32_t)) | ||
25 | + | ||
26 | +DEF_HELPER_1_2(add_setq, uint32_t, (uint32_t, uint32_t)) | ||
27 | +DEF_HELPER_1_2(add_saturate, uint32_t, (uint32_t, uint32_t)) | ||
28 | +DEF_HELPER_1_2(sub_saturate, uint32_t, (uint32_t, uint32_t)) | ||
29 | +DEF_HELPER_1_2(add_usaturate, uint32_t, (uint32_t, uint32_t)) | ||
30 | +DEF_HELPER_1_2(sub_usaturate, uint32_t, (uint32_t, uint32_t)) | ||
31 | +DEF_HELPER_1_1(double_saturate, uint32_t, (int32_t)) | ||
32 | + | ||
33 | +#undef DEF_HELPER | ||
34 | +#undef DEF_HELPER_1_1 | ||
35 | +#undef DEF_HELPER_1_2 | ||
36 | +#undef GEN_HELPER |
target-arm/op.c
@@ -425,105 +425,6 @@ void OPPROTO op_rorl_T1_T0_cc(void) | @@ -425,105 +425,6 @@ void OPPROTO op_rorl_T1_T0_cc(void) | ||
425 | FORCE_RET(); | 425 | FORCE_RET(); |
426 | } | 426 | } |
427 | 427 | ||
428 | -/* misc */ | ||
429 | -#define SIGNBIT (uint32_t)0x80000000 | ||
430 | -/* saturating arithmetic */ | ||
431 | -void OPPROTO op_addl_T0_T1_setq(void) | ||
432 | -{ | ||
433 | - uint32_t res; | ||
434 | - | ||
435 | - res = T0 + T1; | ||
436 | - if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) | ||
437 | - env->QF = 1; | ||
438 | - | ||
439 | - T0 = res; | ||
440 | - FORCE_RET(); | ||
441 | -} | ||
442 | - | ||
443 | -void OPPROTO op_addl_T0_T1_saturate(void) | ||
444 | -{ | ||
445 | - uint32_t res; | ||
446 | - | ||
447 | - res = T0 + T1; | ||
448 | - if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) { | ||
449 | - env->QF = 1; | ||
450 | - if (T0 & SIGNBIT) | ||
451 | - T0 = 0x80000000; | ||
452 | - else | ||
453 | - T0 = 0x7fffffff; | ||
454 | - } | ||
455 | - else | ||
456 | - T0 = res; | ||
457 | - | ||
458 | - FORCE_RET(); | ||
459 | -} | ||
460 | - | ||
461 | -void OPPROTO op_subl_T0_T1_saturate(void) | ||
462 | -{ | ||
463 | - uint32_t res; | ||
464 | - | ||
465 | - res = T0 - T1; | ||
466 | - if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) { | ||
467 | - env->QF = 1; | ||
468 | - if (T0 & SIGNBIT) | ||
469 | - T0 = 0x80000000; | ||
470 | - else | ||
471 | - T0 = 0x7fffffff; | ||
472 | - } | ||
473 | - else | ||
474 | - T0 = res; | ||
475 | - | ||
476 | - FORCE_RET(); | ||
477 | -} | ||
478 | - | ||
479 | -void OPPROTO op_double_T1_saturate(void) | ||
480 | -{ | ||
481 | - int32_t val; | ||
482 | - | ||
483 | - val = T1; | ||
484 | - if (val >= 0x40000000) { | ||
485 | - T1 = 0x7fffffff; | ||
486 | - env->QF = 1; | ||
487 | - } else if (val <= (int32_t)0xc0000000) { | ||
488 | - T1 = 0x80000000; | ||
489 | - env->QF = 1; | ||
490 | - } else { | ||
491 | - T1 = val << 1; | ||
492 | - } | ||
493 | - FORCE_RET(); | ||
494 | -} | ||
495 | - | ||
496 | -/* Unsigned saturating arithmetic for NEON. */ | ||
497 | -void OPPROTO op_addl_T0_T1_usaturate(void) | ||
498 | -{ | ||
499 | - uint32_t res; | ||
500 | - | ||
501 | - res = T0 + T1; | ||
502 | - if (res < T0) { | ||
503 | - env->QF = 1; | ||
504 | - T0 = 0xffffffff; | ||
505 | - } else { | ||
506 | - T0 = res; | ||
507 | - } | ||
508 | - | ||
509 | - FORCE_RET(); | ||
510 | -} | ||
511 | - | ||
512 | -void OPPROTO op_subl_T0_T1_usaturate(void) | ||
513 | -{ | ||
514 | - uint32_t res; | ||
515 | - | ||
516 | - res = T0 - T1; | ||
517 | - if (res > T0) { | ||
518 | - env->QF = 1; | ||
519 | - T0 = 0; | ||
520 | - } else { | ||
521 | - T0 = res; | ||
522 | - } | ||
523 | - | ||
524 | - FORCE_RET(); | ||
525 | -} | ||
526 | - | ||
527 | /* exceptions */ | 428 | /* exceptions */ |
528 | 429 | ||
529 | void OPPROTO op_swi(void) | 430 | void OPPROTO op_swi(void) |
target-arm/op_helper.c
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include "exec.h" | 20 | #include "exec.h" |
21 | +#include "helpers.h" | ||
21 | 22 | ||
22 | void raise_exception(int tt) | 23 | void raise_exception(int tt) |
23 | { | 24 | { |
@@ -303,3 +304,68 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) | @@ -303,3 +304,68 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) | ||
303 | env = saved_env; | 304 | env = saved_env; |
304 | } | 305 | } |
305 | #endif | 306 | #endif |
307 | + | ||
308 | +#define SIGNBIT (uint32_t)0x80000000 | ||
309 | +uint32_t HELPER(add_setq)(uint32_t a, uint32_t b) | ||
310 | +{ | ||
311 | + uint32_t res = a + b; | ||
312 | + if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) | ||
313 | + env->QF = 1; | ||
314 | + return res; | ||
315 | +} | ||
316 | + | ||
317 | +uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b) | ||
318 | +{ | ||
319 | + uint32_t res = a + b; | ||
320 | + if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) { | ||
321 | + env->QF = 1; | ||
322 | + res = ~(((int32_t)a >> 31) ^ SIGNBIT); | ||
323 | + } | ||
324 | + return res; | ||
325 | +} | ||
326 | + | ||
327 | +uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b) | ||
328 | +{ | ||
329 | + uint32_t res = a - b; | ||
330 | + if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) { | ||
331 | + env->QF = 1; | ||
332 | + res = ~(((int32_t)a >> 31) ^ SIGNBIT); | ||
333 | + } | ||
334 | + return res; | ||
335 | +} | ||
336 | + | ||
337 | +uint32_t HELPER(double_saturate)(int32_t val) | ||
338 | +{ | ||
339 | + uint32_t res; | ||
340 | + if (val >= 0x40000000) { | ||
341 | + res = ~SIGNBIT; | ||
342 | + env->QF = 1; | ||
343 | + } else if (val <= (int32_t)0xc0000000) { | ||
344 | + res = SIGNBIT; | ||
345 | + env->QF = 1; | ||
346 | + } else { | ||
347 | + res = val << 1; | ||
348 | + } | ||
349 | + return res; | ||
350 | +} | ||
351 | + | ||
352 | +uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b) | ||
353 | +{ | ||
354 | + uint32_t res = a + b; | ||
355 | + if (res < a) { | ||
356 | + env->QF = 1; | ||
357 | + res = ~0; | ||
358 | + } | ||
359 | + return res; | ||
360 | +} | ||
361 | + | ||
362 | +uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b) | ||
363 | +{ | ||
364 | + uint32_t res = a - b; | ||
365 | + if (res > a) { | ||
366 | + env->QF = 1; | ||
367 | + res = 0; | ||
368 | + } | ||
369 | + return res; | ||
370 | +} | ||
371 | + |
target-arm/op_neon.h
@@ -9,6 +9,7 @@ | @@ -9,6 +9,7 @@ | ||
9 | /* Note that for NEON an "l" prefix means it is a wide operation, unlike | 9 | /* Note that for NEON an "l" prefix means it is a wide operation, unlike |
10 | scalar arm ops where it means a word size operation. */ | 10 | scalar arm ops where it means a word size operation. */ |
11 | 11 | ||
12 | +#define SIGNBIT (uint32_t)0x80000000 | ||
12 | /* ??? NEON ops should probably have their own float status. */ | 13 | /* ??? NEON ops should probably have their own float status. */ |
13 | #define NFS &env->vfp.fp_status | 14 | #define NFS &env->vfp.fp_status |
14 | #define NEON_OP(name) void OPPROTO op_neon_##name (void) | 15 | #define NEON_OP(name) void OPPROTO op_neon_##name (void) |
target-arm/translate.c
@@ -29,6 +29,8 @@ | @@ -29,6 +29,8 @@ | ||
29 | #include "exec-all.h" | 29 | #include "exec-all.h" |
30 | #include "disas.h" | 30 | #include "disas.h" |
31 | #include "tcg-op.h" | 31 | #include "tcg-op.h" |
32 | + | ||
33 | +#define GEN_HELPER 1 | ||
32 | #include "helpers.h" | 34 | #include "helpers.h" |
33 | 35 | ||
34 | #define ENABLE_ARCH_5J 0 | 36 | #define ENABLE_ARCH_5J 0 |
@@ -200,13 +202,19 @@ static void store_reg(DisasContext *s, int reg, TCGv var) | @@ -200,13 +202,19 @@ static void store_reg(DisasContext *s, int reg, TCGv var) | ||
200 | #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) | 202 | #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) |
201 | #define gen_sxth(var) tcg_gen_ext16s_i32(var, var) | 203 | #define gen_sxth(var) tcg_gen_ext16s_i32(var, var) |
202 | 204 | ||
203 | -#define HELPER_ADDR(x) helper_##x | ||
204 | - | ||
205 | -#define gen_sxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(sxtb16), var, var) | ||
206 | -#define gen_uxtb16(var) tcg_gen_helper_1_1(HELPER_ADDR(uxtb16), var, var) | 205 | +#define gen_sxtb16(var) gen_helper_sxtb16(var, var) |
206 | +#define gen_uxtb16(var) gen_helper_uxtb16(var, var) | ||
207 | 207 | ||
208 | -#define gen_op_clz_T0(var) \ | ||
209 | - tcg_gen_helper_1_1(HELPER_ADDR(clz), cpu_T[0], cpu_T[0]) | 208 | +#define gen_op_addl_T0_T1_setq() \ |
209 | + gen_helper_add_setq(cpu_T[0], cpu_T[0], cpu_T[1]) | ||
210 | +#define gen_op_addl_T0_T1_saturate() \ | ||
211 | + gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1]) | ||
212 | +#define gen_op_subl_T0_T1_saturate() \ | ||
213 | + gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1]) | ||
214 | +#define gen_op_addl_T0_T1_usaturate() \ | ||
215 | + gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]) | ||
216 | +#define gen_op_subl_T0_T1_usaturate() \ | ||
217 | + gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]) | ||
210 | 218 | ||
211 | /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. | 219 | /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. |
212 | tmp = (t0 ^ t1) & 0x8000; | 220 | tmp = (t0 ^ t1) & 0x8000; |
@@ -4526,7 +4534,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | @@ -4526,7 +4534,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | ||
4526 | switch (size) { | 4534 | switch (size) { |
4527 | case 0: gen_op_neon_clz_u8(); break; | 4535 | case 0: gen_op_neon_clz_u8(); break; |
4528 | case 1: gen_op_neon_clz_u16(); break; | 4536 | case 1: gen_op_neon_clz_u16(); break; |
4529 | - case 2: gen_op_clz_T0(); break; | 4537 | + case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break; |
4530 | default: return 1; | 4538 | default: return 1; |
4531 | } | 4539 | } |
4532 | break; | 4540 | break; |
@@ -5021,9 +5029,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -5021,9 +5029,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5021 | } else if (op1 == 3) { | 5029 | } else if (op1 == 3) { |
5022 | /* clz */ | 5030 | /* clz */ |
5023 | rd = (insn >> 12) & 0xf; | 5031 | rd = (insn >> 12) & 0xf; |
5024 | - gen_movl_T0_reg(s, rm); | ||
5025 | - gen_op_clz_T0(); | ||
5026 | - gen_movl_reg_T0(s, rd); | 5032 | + tmp = load_reg(s, rm); |
5033 | + gen_helper_clz(tmp, tmp); | ||
5034 | + store_reg(s, rd, tmp); | ||
5027 | } else { | 5035 | } else { |
5028 | goto illegal_op; | 5036 | goto illegal_op; |
5029 | } | 5037 | } |
@@ -5055,7 +5063,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -5055,7 +5063,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5055 | gen_movl_T0_reg(s, rm); | 5063 | gen_movl_T0_reg(s, rm); |
5056 | gen_movl_T1_reg(s, rn); | 5064 | gen_movl_T1_reg(s, rn); |
5057 | if (op1 & 2) | 5065 | if (op1 & 2) |
5058 | - gen_op_double_T1_saturate(); | 5066 | + gen_helper_double_saturate(cpu_T[1], cpu_T[1]); |
5059 | if (op1 & 1) | 5067 | if (op1 & 1) |
5060 | gen_op_subl_T0_T1_saturate(); | 5068 | gen_op_subl_T0_T1_saturate(); |
5061 | else | 5069 | else |
@@ -6317,7 +6325,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -6317,7 +6325,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
6317 | gen_movl_T0_reg(s, rm); | 6325 | gen_movl_T0_reg(s, rm); |
6318 | gen_movl_T1_reg(s, rn); | 6326 | gen_movl_T1_reg(s, rn); |
6319 | if (op & 2) | 6327 | if (op & 2) |
6320 | - gen_op_double_T1_saturate(); | 6328 | + gen_helper_double_saturate(cpu_T[1], cpu_T[1]); |
6321 | if (op & 1) | 6329 | if (op & 1) |
6322 | gen_op_subl_T0_T1_saturate(); | 6330 | gen_op_subl_T0_T1_saturate(); |
6323 | else | 6331 | else |
@@ -6342,7 +6350,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -6342,7 +6350,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
6342 | gen_op_sel_T0_T1(); | 6350 | gen_op_sel_T0_T1(); |
6343 | break; | 6351 | break; |
6344 | case 0x18: /* clz */ | 6352 | case 0x18: /* clz */ |
6345 | - gen_op_clz_T0(); | 6353 | + gen_helper_clz(cpu_T[0], cpu_T[0]); |
6346 | break; | 6354 | break; |
6347 | default: | 6355 | default: |
6348 | goto illegal_op; | 6356 | goto illegal_op; |