Commit 1497c961af2b6d45bd2a1da5a351be54edcadca2

Authored by pbrook
1 parent 9a119ff6

ARM TCG conversion 4/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4141 c046a42c-6fe2-441c-8c8c-71466251a162
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;