aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2010-04-28 10:38:04 -0700
committerAurelien Jarno <aurelien@aurel32.net>2010-05-20 21:09:08 +0200
commitf53dba010162a5ae57776084013e2d3ae32b0889 (patch)
treef4924eb5f0f3b43e8c119c9f13f844e4042e9458 /tcg
parentfcb5dac1f79d48788d61a25630b713e1c31061cd (diff)
tcg-i386: Tidy shift operations.
Define OPC_SHIFT_{1,Ib,cl}. Factor opcode emission to a function. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/i386/tcg-target.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 1ce42b9d5d..8987f32681 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -159,6 +159,9 @@ static inline int tcg_target_const_match(tcg_target_long val,
#define P_EXT 0x100 /* 0x0f opcode prefix */
#define OPC_BSWAP (0xc8 | P_EXT)
+#define OPC_SHIFT_1 (0xd1)
+#define OPC_SHIFT_Ib (0xc1)
+#define OPC_SHIFT_cl (0xd3)
#define ARITH_ADD 0
#define ARITH_OR 1
@@ -287,6 +290,16 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2);
}
+static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
+{
+ if (count == 1) {
+ tcg_out_modrm(s, OPC_SHIFT_1, subopc, reg);
+ } else {
+ tcg_out_modrm(s, OPC_SHIFT_Ib, subopc, reg);
+ tcg_out8(s, count);
+ }
+}
+
static inline void tcg_out_bswap32(TCGContext *s, int reg)
{
tcg_out_opc(s, OPC_BSWAP + reg);
@@ -295,8 +308,7 @@ static inline void tcg_out_bswap32(TCGContext *s, int reg)
static inline void tcg_out_rolw_8(TCGContext *s, int reg)
{
tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, reg);
- tcg_out8(s, 8);
+ tcg_out_shifti(s, SHIFT_ROL, reg, 8);
}
static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val, int cf)
@@ -593,9 +605,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out_mov(s, r0, addr_reg);
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
+ tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+
tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
@@ -797,9 +808,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
tcg_out_mov(s, r0, addr_reg);
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
+ tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+
tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
@@ -1100,14 +1110,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
c = SHIFT_SHL;
gen_shift32:
if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1, c, args[0]);
- tcg_out8(s, args[2]);
- }
+ tcg_out_shifti(s, c, args[0], args[2]);
} else {
- tcg_out_modrm(s, 0xd3, c, args[0]);
+ tcg_out_modrm(s, OPC_SHIFT_cl, c, args[0]);
}
break;
case INDEX_op_shr_i32: