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 322 env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
323 323 }
324 324  
325   -#define HELPER(x) helper_##x
326 325 /* Sign/zero extend */
327 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 1893 }
1895 1894  
1896 1895 #endif
1897   -
... ...
target-arm/helpers.h
1   -#ifndef DEF_HELPER
2 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 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 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 428 /* exceptions */
528 429  
529 430 void OPPROTO op_swi(void)
... ...
target-arm/op_helper.c
... ... @@ -18,6 +18,7 @@
18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19 */
20 20 #include "exec.h"
  21 +#include "helpers.h"
21 22  
22 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 304 env = saved_env;
304 305 }
305 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 9 /* Note that for NEON an "l" prefix means it is a wide operation, unlike
10 10 scalar arm ops where it means a word size operation. */
11 11  
  12 +#define SIGNBIT (uint32_t)0x80000000
12 13 /* ??? NEON ops should probably have their own float status. */
13 14 #define NFS &env->vfp.fp_status
14 15 #define NEON_OP(name) void OPPROTO op_neon_##name (void)
... ...
target-arm/translate.c
... ... @@ -29,6 +29,8 @@
29 29 #include "exec-all.h"
30 30 #include "disas.h"
31 31 #include "tcg-op.h"
  32 +
  33 +#define GEN_HELPER 1
32 34 #include "helpers.h"
33 35  
34 36 #define ENABLE_ARCH_5J 0
... ... @@ -200,13 +202,19 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
200 202 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
201 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 219 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
212 220 tmp = (t0 ^ t1) & 0x8000;
... ... @@ -4526,7 +4534,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4526 4534 switch (size) {
4527 4535 case 0: gen_op_neon_clz_u8(); break;
4528 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 4538 default: return 1;
4531 4539 }
4532 4540 break;
... ... @@ -5021,9 +5029,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5021 5029 } else if (op1 == 3) {
5022 5030 /* clz */
5023 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 5035 } else {
5028 5036 goto illegal_op;
5029 5037 }
... ... @@ -5055,7 +5063,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5055 5063 gen_movl_T0_reg(s, rm);
5056 5064 gen_movl_T1_reg(s, rn);
5057 5065 if (op1 & 2)
5058   - gen_op_double_T1_saturate();
  5066 + gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
5059 5067 if (op1 & 1)
5060 5068 gen_op_subl_T0_T1_saturate();
5061 5069 else
... ... @@ -6317,7 +6325,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6317 6325 gen_movl_T0_reg(s, rm);
6318 6326 gen_movl_T1_reg(s, rn);
6319 6327 if (op & 2)
6320   - gen_op_double_T1_saturate();
  6328 + gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
6321 6329 if (op & 1)
6322 6330 gen_op_subl_T0_T1_saturate();
6323 6331 else
... ... @@ -6342,7 +6350,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6342 6350 gen_op_sel_T0_T1();
6343 6351 break;
6344 6352 case 0x18: /* clz */
6345   - gen_op_clz_T0();
  6353 + gen_helper_clz(cpu_T[0], cpu_T[0]);
6346 6354 break;
6347 6355 default:
6348 6356 goto illegal_op;
... ...