Commit 3c3a1d200c801d35de689325cd32766db5b11f0c
1 parent
94d45e44
fixed qemu_st8 insn - prologue saved too many registers
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4418 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
6 additions
and
8 deletions
tcg/x86_64/tcg-target.c
@@ -215,7 +215,7 @@ static inline int tcg_target_const_match(tcg_target_long val, | @@ -215,7 +215,7 @@ static inline int tcg_target_const_match(tcg_target_long val, | ||
215 | 215 | ||
216 | #define P_EXT 0x100 /* 0x0f opcode prefix */ | 216 | #define P_EXT 0x100 /* 0x0f opcode prefix */ |
217 | #define P_REXW 0x200 /* set rex.w = 1 */ | 217 | #define P_REXW 0x200 /* set rex.w = 1 */ |
218 | -#define P_REX 0x400 /* force rex usage */ | 218 | +#define P_REXB 0x400 /* force rex use for byte registers */ |
219 | 219 | ||
220 | static const uint8_t tcg_cond_to_jcc[10] = { | 220 | static const uint8_t tcg_cond_to_jcc[10] = { |
221 | [TCG_COND_EQ] = JCC_JE, | 221 | [TCG_COND_EQ] = JCC_JE, |
@@ -235,7 +235,7 @@ static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x) | @@ -235,7 +235,7 @@ static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x) | ||
235 | int rex; | 235 | int rex; |
236 | rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) | | 236 | rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) | |
237 | ((x >> 2) & 2) | ((rm >> 3) & 1); | 237 | ((x >> 2) & 2) | ((rm >> 3) & 1); |
238 | - if (rex || (opc & P_REX)) { | 238 | + if (rex || ((opc & P_REXB) && r >= 4)) { |
239 | tcg_out8(s, rex | 0x40); | 239 | tcg_out8(s, rex | 0x40); |
240 | } | 240 | } |
241 | if (opc & P_EXT) | 241 | if (opc & P_EXT) |
@@ -748,7 +748,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | @@ -748,7 +748,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | ||
748 | switch(opc) { | 748 | switch(opc) { |
749 | case 0: | 749 | case 0: |
750 | /* movzbl */ | 750 | /* movzbl */ |
751 | - tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_RSI, data_reg); | 751 | + tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg); |
752 | break; | 752 | break; |
753 | case 1: | 753 | case 1: |
754 | /* movzwl */ | 754 | /* movzwl */ |
@@ -791,7 +791,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | @@ -791,7 +791,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | ||
791 | switch(opc) { | 791 | switch(opc) { |
792 | case 0: | 792 | case 0: |
793 | /* movb */ | 793 | /* movb */ |
794 | - tcg_out_modrm_offset(s, 0x88 | P_REX, data_reg, r0, 0); | 794 | + tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0); |
795 | break; | 795 | break; |
796 | case 1: | 796 | case 1: |
797 | if (bswap) { | 797 | if (bswap) { |
@@ -929,7 +929,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, | @@ -929,7 +929,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, | ||
929 | case INDEX_op_st8_i32: | 929 | case INDEX_op_st8_i32: |
930 | case INDEX_op_st8_i64: | 930 | case INDEX_op_st8_i64: |
931 | /* movb */ | 931 | /* movb */ |
932 | - tcg_out_modrm_offset(s, 0x88 | P_REX, args[0], args[1], args[2]); | 932 | + tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]); |
933 | break; | 933 | break; |
934 | case INDEX_op_st16_i32: | 934 | case INDEX_op_st16_i32: |
935 | case INDEX_op_st16_i64: | 935 | case INDEX_op_st16_i64: |
@@ -1133,8 +1133,6 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, | @@ -1133,8 +1133,6 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, | ||
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | static int tcg_target_callee_save_regs[] = { | 1135 | static int tcg_target_callee_save_regs[] = { |
1136 | - TCG_REG_R10, | ||
1137 | - TCG_REG_R11, | ||
1138 | TCG_REG_RBP, | 1136 | TCG_REG_RBP, |
1139 | TCG_REG_RBX, | 1137 | TCG_REG_RBX, |
1140 | TCG_REG_R12, | 1138 | TCG_REG_R12, |
@@ -1286,6 +1284,6 @@ void tcg_target_init(TCGContext *s) | @@ -1286,6 +1284,6 @@ void tcg_target_init(TCGContext *s) | ||
1286 | 1284 | ||
1287 | tcg_regset_clear(s->reserved_regs); | 1285 | tcg_regset_clear(s->reserved_regs); |
1288 | tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP); | 1286 | tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP); |
1289 | - | 1287 | + |
1290 | tcg_add_target_add_op_defs(x86_64_op_defs); | 1288 | tcg_add_target_add_op_defs(x86_64_op_defs); |
1291 | } | 1289 | } |