diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-17 22:04:52 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-17 22:04:52 +0000 |
commit | b3249f630e95f3235da438ee1a6cd1b867084e9c (patch) | |
tree | 73e6a9cdd97062c471dd4aaa596abd34316c5b6d | |
parent | 9c29504eb71238241f29667bd96fb83c97668e1a (diff) |
target-alpha: convert byte manipulation instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5246 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | target-alpha/helper.h | 18 | ||||
-rw-r--r-- | target-alpha/op.c | 139 | ||||
-rw-r--r-- | target-alpha/op_helper.c | 120 | ||||
-rw-r--r-- | target-alpha/op_helper.h | 23 | ||||
-rw-r--r-- | target-alpha/translate.c | 133 |
5 files changed, 167 insertions, 266 deletions
diff --git a/target-alpha/helper.h b/target-alpha/helper.h index 88b19298e1..d82bf4344d 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -9,3 +9,21 @@ DEF_HELPER(uint64_t, helper_amask, (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)) + +DEF_HELPER(uint64_t, helper_mskbl, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_insbl, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mskwl, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_inswl, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mskll, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_insll, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_zap, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_zapnot, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mskql, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_insql, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_mskwh, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_inswh, (int64_t, uint64_t)) +DEF_HELPER(uint64_t, helper_msklh, (int64_t, uint64_t)) +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)) + diff --git a/target-alpha/op.c b/target-alpha/op.c index 405a05257f..5d0daa9521 100644 --- a/target-alpha/op.c +++ b/target-alpha/op.c @@ -243,145 +243,6 @@ void OPPROTO op_umulh (void) RETURN(); } -/* Logical */ -void OPPROTO op_mskbl (void) -{ - helper_mskbl(); - RETURN(); -} - -void OPPROTO op_extbl (void) -{ - helper_extbl(); - RETURN(); -} - -void OPPROTO op_insbl (void) -{ - helper_insbl(); - RETURN(); -} - -void OPPROTO op_mskwl (void) -{ - helper_mskwl(); - RETURN(); -} - -void OPPROTO op_extwl (void) -{ - helper_extwl(); - RETURN(); -} - -void OPPROTO op_inswl (void) -{ - helper_inswl(); - RETURN(); -} - -void OPPROTO op_mskll (void) -{ - helper_mskll(); - RETURN(); -} - -void OPPROTO op_extll (void) -{ - helper_extll(); - RETURN(); -} - -void OPPROTO op_insll (void) -{ - helper_insll(); - RETURN(); -} - -void OPPROTO op_zap (void) -{ - helper_zap(); - RETURN(); -} - -void OPPROTO op_zapnot (void) -{ - helper_zapnot(); - RETURN(); -} - -void OPPROTO op_mskql (void) -{ - helper_mskql(); - RETURN(); -} - -void OPPROTO op_extql (void) -{ - helper_extql(); - RETURN(); -} - -void OPPROTO op_insql (void) -{ - helper_insql(); - RETURN(); -} - -void OPPROTO op_mskwh (void) -{ - helper_mskwh(); - RETURN(); -} - -void OPPROTO op_inswh (void) -{ - helper_inswh(); - RETURN(); -} - -void OPPROTO op_extwh (void) -{ - helper_extwh(); - RETURN(); -} - -void OPPROTO op_msklh (void) -{ - helper_msklh(); - RETURN(); -} - -void OPPROTO op_inslh (void) -{ - helper_inslh(); - RETURN(); -} - -void OPPROTO op_extlh (void) -{ - helper_extlh(); - RETURN(); -} - -void OPPROTO op_mskqh (void) -{ - helper_mskqh(); - RETURN(); -} - -void OPPROTO op_insqh (void) -{ - helper_insqh(); - RETURN(); -} - -void OPPROTO op_extqh (void) -{ - helper_extqh(); - RETURN(); -} - /* Tests */ void OPPROTO op_cmpult (void) { diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index 745c44df44..194f410850 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -243,133 +243,91 @@ static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb) return op & ~mask; } -void helper_mskbl (void) +uint64_t helper_mskbl(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, 0x01 << (T1 & 7)); + return byte_zap(val, 0x01 << (mask & 7)); } -void helper_extbl (void) +uint64_t helper_insbl(uint64_t val, uint64_t mask) { - T0 >>= (T1 & 7) * 8; - T0 = byte_zap(T0, 0xFE); + val <<= (mask & 7) * 8; + return byte_zap(val, ~(0x01 << (mask & 7))); } -void helper_insbl (void) +uint64_t helper_mskwl(uint64_t val, uint64_t mask) { - T0 <<= (T1 & 7) * 8; - T0 = byte_zap(T0, ~(0x01 << (T1 & 7))); + return byte_zap(val, 0x03 << (mask & 7)); } -void helper_mskwl (void) +uint64_t helper_inswl(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, 0x03 << (T1 & 7)); + val <<= (mask & 7) * 8; + return byte_zap(val, ~(0x03 << (mask & 7))); } -void helper_extwl (void) +uint64_t helper_mskll(uint64_t val, uint64_t mask) { - T0 >>= (T1 & 7) * 8; - T0 = byte_zap(T0, 0xFC); + return byte_zap(val, 0x0F << (mask & 7)); } -void helper_inswl (void) +uint64_t helper_insll(uint64_t val, uint64_t mask) { - T0 <<= (T1 & 7) * 8; - T0 = byte_zap(T0, ~(0x03 << (T1 & 7))); + val <<= (mask & 7) * 8; + return byte_zap(val, ~(0x0F << (mask & 7))); } -void helper_mskll (void) +uint64_t helper_zap(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, 0x0F << (T1 & 7)); + return byte_zap(val, mask); } -void helper_extll (void) +uint64_t helper_zapnot(uint64_t val, uint64_t mask) { - T0 >>= (T1 & 7) * 8; - T0 = byte_zap(T0, 0xF0); + return byte_zap(val, ~mask); } -void helper_insll (void) +uint64_t helper_mskql(uint64_t val, uint64_t mask) { - T0 <<= (T1 & 7) * 8; - T0 = byte_zap(T0, ~(0x0F << (T1 & 7))); + return byte_zap(val, 0xFF << (mask & 7)); } -void helper_zap (void) +uint64_t helper_insql(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, T1); + val <<= (mask & 7) * 8; + return byte_zap(val, ~(0xFF << (mask & 7))); } -void helper_zapnot (void) +uint64_t helper_mskwh(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, ~T1); + return byte_zap(val, (0x03 << (mask & 7)) >> 8); } -void helper_mskql (void) +uint64_t helper_inswh(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, 0xFF << (T1 & 7)); + val >>= 64 - ((mask & 7) * 8); + return byte_zap(val, ~((0x03 << (mask & 7)) >> 8)); } -void helper_extql (void) +uint64_t helper_msklh(uint64_t val, uint64_t mask) { - T0 >>= (T1 & 7) * 8; - T0 = byte_zap(T0, 0x00); + return byte_zap(val, (0x0F << (mask & 7)) >> 8); } -void helper_insql (void) +uint64_t helper_inslh(uint64_t val, uint64_t mask) { - T0 <<= (T1 & 7) * 8; - T0 = byte_zap(T0, ~(0xFF << (T1 & 7))); + val >>= 64 - ((mask & 7) * 8); + return byte_zap(val, ~((0x0F << (mask & 7)) >> 8)); } -void helper_mskwh (void) +uint64_t helper_mskqh(uint64_t val, uint64_t mask) { - T0 = byte_zap(T0, (0x03 << (T1 & 7)) >> 8); + return byte_zap(val, (0xFF << (mask & 7)) >> 8); } -void helper_inswh (void) +uint64_t helper_insqh(uint64_t val, uint64_t mask) { - T0 >>= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, ~((0x03 << (T1 & 7)) >> 8)); -} - -void helper_extwh (void) -{ - T0 <<= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, ~0x07); -} - -void helper_msklh (void) -{ - T0 = byte_zap(T0, (0x0F << (T1 & 7)) >> 8); -} - -void helper_inslh (void) -{ - T0 >>= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, ~((0x0F << (T1 & 7)) >> 8)); -} - -void helper_extlh (void) -{ - T0 <<= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, ~0x0F); -} - -void helper_mskqh (void) -{ - T0 = byte_zap(T0, (0xFF << (T1 & 7)) >> 8); -} - -void helper_insqh (void) -{ - T0 >>= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, ~((0xFF << (T1 & 7)) >> 8)); -} - -void helper_extqh (void) -{ - T0 <<= 64 - ((T1 & 7) * 8); - T0 = byte_zap(T0, 0x00); + val >>= 64 - ((mask & 7) * 8); + return byte_zap(val, ~((0xFF << (mask & 7)) >> 8)); } void helper_cmpbge (void) diff --git a/target-alpha/op_helper.h b/target-alpha/op_helper.h index 56f34a0f24..86c9d21a47 100644 --- a/target-alpha/op_helper.h +++ b/target-alpha/op_helper.h @@ -33,29 +33,6 @@ void helper_subqv (void); void helper_sublv (void); void helper_mullv (void); void helper_mulqv (void); -void helper_mskbl (void); -void helper_extbl (void); -void helper_insbl (void); -void helper_mskwl (void); -void helper_extwl (void); -void helper_inswl (void); -void helper_mskll (void); -void helper_extll (void); -void helper_insll (void); -void helper_zap (void); -void helper_zapnot (void); -void helper_mskql (void); -void helper_extql (void); -void helper_insql (void); -void helper_mskwh (void); -void helper_inswh (void); -void helper_extwh (void); -void helper_msklh (void); -void helper_inslh (void); -void helper_extlh (void); -void helper_mskqh (void); -void helper_insqh (void); -void helper_extqh (void); void helper_cmpbge (void); void helper_cmov_fir (int freg); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 4c6d661bc2..583fa86ba1 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -468,6 +468,93 @@ static always_inline void gen_itf (DisasContext *ctx, gen_store_fir(ctx, rc, 0); } +/* EXTWH, EXTWH, EXTLH, EXTQH */ +static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1), + int ra, int rb, int rc, + int islit, int8_t lit) +{ + if (unlikely(rc == 31)) + return; + + if (ra != 31) { + if (islit) + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8)); + else if (rb != 31) { + TCGv tmp1, tmp2; + tmp1 = tcg_temp_new(TCG_TYPE_I64); + tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7); + tcg_gen_shli_i64(tmp1, tmp1, 3); + tmp2 = tcg_const_i64(64); + tcg_gen_sub_i64(tmp1, tmp2, tmp1); + tcg_temp_free(tmp2); + if (tcg_gen_ext_i64) { + tcg_gen_shl_i64(tmp1, cpu_ir[ra], tmp1); + tcg_gen_ext_i64(cpu_ir[rc], tmp1); + } else + tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1); + tcg_temp_free(tmp1); + } else + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); + } else + tcg_gen_movi_i64(cpu_ir[rc], 0); +} + +/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */ +static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1), + int ra, int rb, int rc, + int islit, int8_t lit) +{ + if (unlikely(rc == 31)) + return; + + if (ra != 31) { + if (islit) + tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8); + else if (rb != 31) { + TCGv tmp = tcg_temp_new(TCG_TYPE_I64); + tcg_gen_andi_i64(tmp, cpu_ir[rb], 7); + tcg_gen_shli_i64(tmp, tmp, 3); + if (tcg_gen_ext_i64) { + tcg_gen_shr_i64(tmp, cpu_ir[ra], tmp); + tcg_gen_ext_i64(cpu_ir[rc], tmp); + } else + tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp); + tcg_temp_free(tmp); + } else + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); + } else + 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) +{ + if (unlikely(rc == 31)) + return; + + if (ra != 31) { + if (islit || rb == 31) { + TCGv tmp = tcg_temp_new(TCG_TYPE_I64); + if (islit) + tcg_gen_movi_i64(tmp, lit); + else + tcg_gen_movi_i64(tmp, 0); + tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], tmp); + 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); +} + static always_inline int translate_one (DisasContext *ctx, uint32_t insn) { uint32_t palcode; @@ -1101,51 +1188,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) switch (fn7) { case 0x02: /* MSKBL */ - gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskbl, ra, rb, rc, islit, lit); break; case 0x06: /* EXTBL */ - gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit); + gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit); break; case 0x0B: /* INSBL */ - gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_insbl, ra, rb, rc, islit, lit); break; case 0x12: /* MSKWL */ - gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskwl, ra, rb, rc, islit, lit); break; case 0x16: /* EXTWL */ - gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit); + gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x1B: /* INSWL */ - gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_inswl, ra, rb, rc, islit, lit); break; case 0x22: /* MSKLL */ - gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskll, ra, rb, rc, islit, lit); break; case 0x26: /* EXTLL */ - gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit); + gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit); break; case 0x2B: /* INSLL */ - gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_insll, ra, rb, rc, islit, lit); break; case 0x30: /* ZAP */ - gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_zap, ra, rb, rc, islit, lit); break; case 0x31: /* ZAPNOT */ - gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_zapnot, ra, rb, rc, islit, lit); break; case 0x32: /* MSKQL */ - gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskql, ra, rb, rc, islit, lit); break; case 0x34: /* SRL */ @@ -1166,7 +1253,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x36: /* EXTQL */ - gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit); + gen_ext_l(NULL, ra, rb, rc, islit, lit); break; case 0x39: /* SLL */ @@ -1187,7 +1274,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x3B: /* INSQL */ - gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_insql, ra, rb, rc, islit, lit); break; case 0x3C: /* SRA */ @@ -1208,39 +1295,39 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x52: /* MSKWH */ - gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskwh, ra, rb, rc, islit, lit); break; case 0x57: /* INSWH */ - gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_inswh, ra, rb, rc, islit, lit); break; case 0x5A: /* EXTWH */ - gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit); + gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x62: /* MSKLH */ - gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_msklh, ra, rb, rc, islit, lit); break; case 0x67: /* INSLH */ - gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_inslh, ra, rb, rc, islit, lit); break; case 0x6A: /* EXTLH */ - gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit); + gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x72: /* MSKQH */ - gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_mskqh, ra, rb, rc, islit, lit); break; case 0x77: /* INSQH */ - gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit); + gen_byte_manipulation(helper_insqh, ra, rb, rc, islit, lit); break; case 0x7A: /* EXTQH */ - gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit); + gen_ext_h(NULL, ra, rb, rc, islit, lit); break; default: goto invalid_opc; |