|
|
5544c1 |
From 83b25655bcd988054a2bb2a0a38dc662d4901b08 Mon Sep 17 00:00:00 2001
|
|
|
5544c1 |
From: Aurelien Jarno <aurelien@aurel32.net>
|
|
|
5544c1 |
Date: Mon, 10 Sep 2012 13:56:24 +0200
|
|
|
5544c1 |
Subject: [PATCH] tcg/i386: allow constants in load/store ops
|
|
|
5544c1 |
|
|
|
5544c1 |
On x86, it is possible to move a constant value to memory. Add code to
|
|
|
5544c1 |
handle a constant argument to load/store ops.
|
|
|
5544c1 |
|
|
|
5544c1 |
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
|
5544c1 |
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
|
|
5544c1 |
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
|
5544c1 |
---
|
|
|
5544c1 |
tcg/i386/tcg-target.c | 50 +++++++++++++++++++++++++++++++++++++-------------
|
|
|
5544c1 |
1 file changed, 37 insertions(+), 13 deletions(-)
|
|
|
5544c1 |
|
|
|
5544c1 |
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
|
|
|
5544c1 |
index 34c2df8..3017858 100644
|
|
|
5544c1 |
--- a/tcg/i386/tcg-target.c
|
|
|
5544c1 |
+++ b/tcg/i386/tcg-target.c
|
|
|
5544c1 |
@@ -263,6 +263,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
|
|
5544c1 |
#define OPC_MOVB_EvGv (0x88) /* stores, more or less */
|
|
|
5544c1 |
#define OPC_MOVL_EvGv (0x89) /* stores, more or less */
|
|
|
5544c1 |
#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
|
|
|
5544c1 |
+#define OPC_MOVB_EvIz (0xc6)
|
|
|
5544c1 |
#define OPC_MOVL_EvIz (0xc7)
|
|
|
5544c1 |
#define OPC_MOVL_Iv (0xb8)
|
|
|
5544c1 |
#define OPC_MOVSBL (0xbe | P_EXT)
|
|
|
5544c1 |
@@ -1543,18 +1544,35 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
|
|
|
5544c1 |
OP_32_64(st8):
|
|
|
5544c1 |
- tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
|
|
|
5544c1 |
- args[0], args[1], args[2]);
|
|
|
5544c1 |
+ if (const_args[0]) {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
|
|
|
5544c1 |
+ 0, args[1], args[2]);
|
|
|
5544c1 |
+ tcg_out8(s, args[0]);
|
|
|
5544c1 |
+ } else {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
|
|
|
5544c1 |
+ args[0], args[1], args[2]);
|
|
|
5544c1 |
+ }
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
OP_32_64(st16):
|
|
|
5544c1 |
- tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
|
|
|
5544c1 |
- args[0], args[1], args[2]);
|
|
|
5544c1 |
+ if (const_args[0]) {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
|
|
|
5544c1 |
+ 0, args[1], args[2]);
|
|
|
5544c1 |
+ tcg_out16(s, args[0]);
|
|
|
5544c1 |
+ } else {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
|
|
|
5544c1 |
+ args[0], args[1], args[2]);
|
|
|
5544c1 |
+ }
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
#if TCG_TARGET_REG_BITS == 64
|
|
|
5544c1 |
case INDEX_op_st32_i64:
|
|
|
5544c1 |
#endif
|
|
|
5544c1 |
case INDEX_op_st_i32:
|
|
|
5544c1 |
- tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
|
|
|
5544c1 |
+ if (const_args[0]) {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
|
|
|
5544c1 |
+ tcg_out32(s, args[0]);
|
|
|
5544c1 |
+ } else {
|
|
|
5544c1 |
+ tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
|
|
|
5544c1 |
+ }
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
|
|
|
5544c1 |
OP_32_64(add):
|
|
|
5544c1 |
@@ -1758,7 +1776,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
|
|
5544c1 |
tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
case INDEX_op_st_i64:
|
|
|
5544c1 |
- tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
|
|
5544c1 |
+ if (const_args[0]) {
|
|
|
5544c1 |
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
|
|
|
5544c1 |
+ 0, args[1], args[2]);
|
|
|
5544c1 |
+ tcg_out32(s, args[0]);
|
|
|
5544c1 |
+ } else {
|
|
|
5544c1 |
+ tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
|
|
5544c1 |
+ }
|
|
|
5544c1 |
break;
|
|
|
5544c1 |
case INDEX_op_qemu_ld32s:
|
|
|
5544c1 |
tcg_out_qemu_ld(s, args, 2 | 4);
|
|
|
5544c1 |
@@ -1820,9 +1844,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
|
|
5544c1 |
{ INDEX_op_ld16u_i32, { "r", "r" } },
|
|
|
5544c1 |
{ INDEX_op_ld16s_i32, { "r", "r" } },
|
|
|
5544c1 |
{ INDEX_op_ld_i32, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st8_i32, { "q", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st16_i32, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st_i32, { "r", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st8_i32, { "qi", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st16_i32, { "ri", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st_i32, { "ri", "r" } },
|
|
|
5544c1 |
|
|
|
5544c1 |
{ INDEX_op_add_i32, { "r", "r", "ri" } },
|
|
|
5544c1 |
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
|
|
|
5544c1 |
@@ -1873,10 +1897,10 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
|
|
5544c1 |
{ INDEX_op_ld32u_i64, { "r", "r" } },
|
|
|
5544c1 |
{ INDEX_op_ld32s_i64, { "r", "r" } },
|
|
|
5544c1 |
{ INDEX_op_ld_i64, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st8_i64, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st16_i64, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st32_i64, { "r", "r" } },
|
|
|
5544c1 |
- { INDEX_op_st_i64, { "r", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st8_i64, { "ri", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st16_i64, { "ri", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st32_i64, { "ri", "r" } },
|
|
|
5544c1 |
+ { INDEX_op_st_i64, { "re", "r" } },
|
|
|
5544c1 |
|
|
|
5544c1 |
{ INDEX_op_add_i64, { "r", "0", "re" } },
|
|
|
5544c1 |
{ INDEX_op_mul_i64, { "r", "0", "re" } },
|
|
|
5544c1 |
--
|
|
|
5544c1 |
1.7.12.1
|
|
|
5544c1 |
|