diff options
Diffstat (limited to 'target-alpha')
-rw-r--r-- | target-alpha/cpu.h | 2 | ||||
-rw-r--r-- | target-alpha/exec.h | 2 | ||||
-rw-r--r-- | target-alpha/helper.h | 9 | ||||
-rw-r--r-- | target-alpha/op.c | 52 | ||||
-rw-r--r-- | target-alpha/op_helper.c | 64 | ||||
-rw-r--r-- | target-alpha/op_helper.h | 7 | ||||
-rw-r--r-- | target-alpha/translate.c | 97 |
7 files changed, 87 insertions, 146 deletions
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 4e98c3b..a3458a4 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -275,7 +275,7 @@ struct CPUAlphaState { /* temporary fixed-point registers * used to emulate 64 bits target on 32 bits hosts */ - target_ulong t0, t1, t2; + target_ulong t0, t1; #endif /* */ double ft0, ft1, ft2; diff --git a/target-alpha/exec.h b/target-alpha/exec.h index ec2f8ef..574ef13 100644 --- a/target-alpha/exec.h +++ b/target-alpha/exec.h @@ -34,13 +34,11 @@ register struct CPUAlphaState *env asm(AREG0); /* no registers can be used */ #define T0 (env->t0) #define T1 (env->t1) -#define T2 (env->t2) #else register uint64_t T0 asm(AREG1); register uint64_t T1 asm(AREG2); -register uint64_t T2 asm(AREG3); #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ diff --git a/target-alpha/helper.h b/target-alpha/helper.h index c397999..4b07f58 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -11,6 +11,14 @@ DEF_HELPER(uint64_t, helper_load_implver, (void)) DEF_HELPER(uint64_t, helper_rc, (void)) DEF_HELPER(uint64_t, helper_rs, (void)) +DEF_HELPER(uint64_t, helper_addqv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_addlv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_subqv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_sublv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mullv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mulqv, (uint64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_umulh, (uint64_t, uint64_t)) + DEF_HELPER(uint64_t, helper_ctpop, (uint64_t)) DEF_HELPER(uint64_t, helper_ctlz, (uint64_t)) DEF_HELPER(uint64_t, helper_cttz, (uint64_t)) @@ -32,3 +40,4 @@ DEF_HELPER(uint64_t, helper_inslh, (int64_t, uint64_t)) DEF_HELPER(uint64_t, helper_mskqh, (int64_t, uint64_t)) DEF_HELPER(uint64_t, helper_insqh, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_cmpbge, (uint64_t, uint64_t)) diff --git a/target-alpha/op.c b/target-alpha/op.c index 68812a0..2896c1d 100644 --- a/target-alpha/op.c +++ b/target-alpha/op.c @@ -161,59 +161,7 @@ void OPPROTO op_store_fpcr (void) RETURN(); } -/* Arithmetic */ -void OPPROTO op_addqv (void) -{ - helper_addqv(); - RETURN(); -} - -void OPPROTO op_addlv (void) -{ - helper_addlv(); - RETURN(); -} - -void OPPROTO op_subqv (void) -{ - helper_subqv(); - RETURN(); -} - -void OPPROTO op_sublv (void) -{ - helper_sublv(); - RETURN(); -} - -void OPPROTO op_mullv (void) -{ - helper_mullv(); - RETURN(); -} - -void OPPROTO op_mulqv (void) -{ - helper_mulqv(); - RETURN(); -} - -void OPPROTO op_umulh (void) -{ - uint64_t tl, th; - - mulu64(&tl, &th, T0, T1); - T0 = th; - RETURN(); -} - /* Tests */ -void OPPROTO op_cmpbge (void) -{ - helper_cmpbge(); - RETURN(); -} - #if 0 // Qemu does not know how to do this... void OPPROTO op_bcond (void) { diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index c6dcead..b883048 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -163,62 +163,74 @@ uint64_t helper_rc(void) return tmp; } -void helper_addqv (void) +uint64_t helper_addqv (uint64_t op1, uint64_t op2) { - T2 = T0; - T0 += T1; - if (unlikely((T2 ^ T1 ^ (-1ULL)) & (T2 ^ T0) & (1ULL << 63))) { + uint64_t tmp = op1; + op1 += op2; + if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } + return op1; } -void helper_addlv (void) +uint64_t helper_addlv (uint64_t op1, uint64_t op2) { - T2 = T0; - T0 = (uint32_t)(T0 + T1); - if (unlikely((T2 ^ T1 ^ (-1UL)) & (T2 ^ T0) & (1UL << 31))) { + uint64_t tmp = op1; + op1 = (uint32_t)(op1 + op2); + if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } + return op1; } -void helper_subqv (void) +uint64_t helper_subqv (uint64_t op1, uint64_t op2) { - T2 = T0; - T0 -= T1; - if (unlikely(((~T2) ^ T0 ^ (-1ULL)) & ((~T2) ^ T1) & (1ULL << 63))) { + uint64_t tmp = op1; + op1 -= op2; + if (unlikely(((~tmp) ^ op1 ^ (-1ULL)) & ((~tmp) ^ op2) & (1ULL << 63))) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } + return op1; } -void helper_sublv (void) +uint64_t helper_sublv (uint64_t op1, uint64_t op2) { - T2 = T0; - T0 = (uint32_t)(T0 - T1); - if (unlikely(((~T2) ^ T0 ^ (-1UL)) & ((~T2) ^ T1) & (1UL << 31))) { + uint64_t tmp = op1; + op1 = (uint32_t)(op1 - op2); + if (unlikely(((~tmp) ^ op1 ^ (-1UL)) & ((~tmp) ^ op2) & (1UL << 31))) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } + return op1; } -void helper_mullv (void) +uint64_t helper_mullv (uint64_t op1, uint64_t op2) { - int64_t res = (int64_t)T0 * (int64_t)T1; + int64_t res = (int64_t)op1 * (int64_t)op2; if (unlikely((int32_t)res != res)) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } - T0 = (int64_t)((int32_t)res); + return (int64_t)((int32_t)res); } -void helper_mulqv () +uint64_t helper_mulqv (uint64_t op1, uint64_t op2) { uint64_t tl, th; - muls64(&tl, &th, T0, T1); + muls64(&tl, &th, op1, op2); /* If th != 0 && th != -1, then we had an overflow */ if (unlikely((th + 1) > 1)) { helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); } - T0 = tl; + return tl; +} + +uint64_t helper_umulh (uint64_t op1, uint64_t op2) +{ + uint64_t tl, th; + + mulu64(&tl, &th, op1, op2); + return th; } uint64_t helper_ctpop (uint64_t arg) @@ -340,19 +352,19 @@ uint64_t helper_insqh(uint64_t val, uint64_t mask) return byte_zap(val, ~((0xFF << (mask & 7)) >> 8)); } -void helper_cmpbge (void) +uint64_t helper_cmpbge (uint64_t op1, uint64_t op2) { uint8_t opa, opb, res; int i; res = 0; for (i = 0; i < 7; i++) { - opa = T0 >> (i * 8); - opb = T1 >> (i * 8); + opa = op1 >> (i * 8); + opb = op2 >> (i * 8); if (opa >= opb) res |= 1 << i; } - T0 = res; + return res; } void helper_cmov_fir (int freg) diff --git a/target-alpha/op_helper.h b/target-alpha/op_helper.h index 9c1eb47..bcc488e 100644 --- a/target-alpha/op_helper.h +++ b/target-alpha/op_helper.h @@ -21,13 +21,6 @@ void helper_call_pal (uint32_t palcode); void helper_load_fpcr (void); void helper_store_fpcr (void); -void helper_addqv (void); -void helper_addlv (void); -void helper_subqv (void); -void helper_sublv (void); -void helper_mullv (void); -void helper_mulqv (void); -void helper_cmpbge (void); void helper_cmov_fir (int freg); double helper_ldff_raw (target_ulong ea); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 6b2c7b2..2ca1985 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -51,7 +51,7 @@ static TCGv cpu_ir[31]; static TCGv cpu_pc; /* dyngen register indexes */ -static TCGv cpu_T[3]; +static TCGv cpu_T[2]; /* register names */ static char cpu_reg_names[10*4+21*5]; @@ -74,12 +74,9 @@ static void alpha_translate_init(void) offsetof(CPUState, t0), "T0"); cpu_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, t1), "T1"); - cpu_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, - offsetof(CPUState, t2), "T2"); #else cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I64, TCG_AREG1, "T0"); cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I64, TCG_AREG2, "T1"); - cpu_T[2] = tcg_global_reg_new(TCG_TYPE_I64, TCG_AREG3, "T2"); #endif p = cpu_reg_names; @@ -367,24 +364,6 @@ static always_inline void gen_fbcond (DisasContext *ctx, _gen_op_bcond(ctx); } -static always_inline void gen_arith3 (DisasContext *ctx, - void (*gen_arith_op)(void), - int ra, int rb, int rc, - int islit, uint8_t lit) -{ - if (ra != 31) - tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]); - else - tcg_gen_movi_i64(cpu_T[0], 0); - if (islit) - tcg_gen_movi_i64(cpu_T[1], lit); - else - tcg_gen_mov_i64(cpu_T[1], cpu_ir[rb]); - (*gen_arith_op)(); - if (rc != 31) - tcg_gen_mov_i64(cpu_ir[rc], cpu_T[0]); -} - static always_inline void gen_cmov (DisasContext *ctx, TCGCond inv_cond, int ra, int rb, int rc, @@ -525,16 +504,10 @@ static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1), tcg_gen_movi_i64(cpu_ir[rc], 0); } -/* Code to call byte manipulation helpers, used by: - INSWH, INSLH, INSQH, INSBL, INSWL, INSLL, INSQL, - MSKWH, MSKLH, MSKQH, MSKBL, MSKWL, MSKLL, MSKQL, - ZAP, ZAPNOT - - WARNING: it assumes that when ra31 is used, the result is 0. -*/ -static always_inline void gen_byte_manipulation(void *helper, - int ra, int rb, int rc, - int islit, uint8_t lit) +/* Code to call arith3 helpers */ +static always_inline void gen_arith3_helper(void *helper, + int ra, int rb, int rc, + int islit, uint8_t lit) { if (unlikely(rc == 31)) return; @@ -546,8 +519,16 @@ static always_inline void gen_byte_manipulation(void *helper, tcg_temp_free(tmp); } else tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); - } else - tcg_gen_movi_i64(cpu_ir[rc], 0); + } else { + TCGv tmp1 = tcg_const_i64(0); + if (islit) { + TCGv tmp2 = tcg_const_i64(lit); + tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, tmp2); + tcg_temp_free(tmp2); + } else + tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, cpu_ir[rb]); + tcg_temp_free(tmp1); + } } static always_inline void gen_cmp(TCGCond cond, @@ -791,7 +772,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x0F: /* CMPBGE */ - gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_cmpbge, ra, rb, rc, islit, lit); break; case 0x12: /* S8ADDL */ @@ -957,11 +938,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x40: /* ADDL/V */ - gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_addlv, ra, rb, rc, islit, lit); break; case 0x49: /* SUBL/V */ - gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_sublv, ra, rb, rc, islit, lit); break; case 0x4D: /* CMPLT */ @@ -969,11 +950,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x60: /* ADDQ/V */ - gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_addqv, ra, rb, rc, islit, lit); break; case 0x69: /* SUBQ/V */ - gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_subqv, ra, rb, rc, islit, lit); break; case 0x6D: /* CMPLE */ @@ -1138,7 +1119,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) switch (fn7) { case 0x02: /* MSKBL */ - gen_byte_manipulation(helper_mskbl, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskbl, ra, rb, rc, islit, lit); break; case 0x06: /* EXTBL */ @@ -1146,11 +1127,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x0B: /* INSBL */ - gen_byte_manipulation(helper_insbl, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_insbl, ra, rb, rc, islit, lit); break; case 0x12: /* MSKWL */ - gen_byte_manipulation(helper_mskwl, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskwl, ra, rb, rc, islit, lit); break; case 0x16: /* EXTWL */ @@ -1158,11 +1139,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x1B: /* INSWL */ - gen_byte_manipulation(helper_inswl, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_inswl, ra, rb, rc, islit, lit); break; case 0x22: /* MSKLL */ - gen_byte_manipulation(helper_mskll, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskll, ra, rb, rc, islit, lit); break; case 0x26: /* EXTLL */ @@ -1170,19 +1151,19 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x2B: /* INSLL */ - gen_byte_manipulation(helper_insll, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_insll, ra, rb, rc, islit, lit); break; case 0x30: /* ZAP */ - gen_byte_manipulation(helper_zap, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_zap, ra, rb, rc, islit, lit); break; case 0x31: /* ZAPNOT */ - gen_byte_manipulation(helper_zapnot, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_zapnot, ra, rb, rc, islit, lit); break; case 0x32: /* MSKQL */ - gen_byte_manipulation(helper_mskql, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskql, ra, rb, rc, islit, lit); break; case 0x34: /* SRL */ @@ -1222,7 +1203,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x3B: /* INSQL */ - gen_byte_manipulation(helper_insql, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_insql, ra, rb, rc, islit, lit); break; case 0x3C: /* SRA */ @@ -1242,11 +1223,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x52: /* MSKWH */ - gen_byte_manipulation(helper_mskwh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskwh, ra, rb, rc, islit, lit); break; case 0x57: /* INSWH */ - gen_byte_manipulation(helper_inswh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_inswh, ra, rb, rc, islit, lit); break; case 0x5A: /* EXTWH */ @@ -1254,11 +1235,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x62: /* MSKLH */ - gen_byte_manipulation(helper_msklh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_msklh, ra, rb, rc, islit, lit); break; case 0x67: /* INSLH */ - gen_byte_manipulation(helper_inslh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_inslh, ra, rb, rc, islit, lit); break; case 0x6A: /* EXTLH */ @@ -1266,11 +1247,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x72: /* MSKQH */ - gen_byte_manipulation(helper_mskqh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mskqh, ra, rb, rc, islit, lit); break; case 0x77: /* INSQH */ - gen_byte_manipulation(helper_insqh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_insqh, ra, rb, rc, islit, lit); break; case 0x7A: /* EXTQH */ @@ -1309,15 +1290,15 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x30: /* UMULH */ - gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_umulh, ra, rb, rc, islit, lit); break; case 0x40: /* MULL/V */ - gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mullv, ra, rb, rc, islit, lit); break; case 0x60: /* MULQ/V */ - gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit); + gen_arith3_helper(helper_mulqv, ra, rb, rc, islit, lit); break; default: goto invalid_opc; |