aboutsummaryrefslogtreecommitdiffstats
path: root/tcg/ppc64/tcg-target.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcg/ppc64/tcg-target.c')
-rw-r--r--tcg/ppc64/tcg-target.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 6b16efa..a2f85ff 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -42,6 +42,7 @@ static uint8_t *tb_ret_addr;
#define CMP_L (1<<21)
#endif
+#ifndef NDEBUG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"r0",
"r1",
@@ -76,6 +77,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"r30",
"r31"
};
+#endif
static const int tcg_target_reg_alloc_order[] = {
TCG_REG_R14,
@@ -102,10 +104,6 @@ static const int tcg_target_reg_alloc_order[] = {
TCG_REG_R10,
TCG_REG_R11,
TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
@@ -138,6 +136,11 @@ static const int tcg_target_callee_save_regs[] = {
TCG_REG_R21,
TCG_REG_R22,
TCG_REG_R23,
+ TCG_REG_R24,
+ TCG_REG_R25,
+ TCG_REG_R26,
+ /* TCG_REG_R27, */ /* currently used for the global env, so no
+ need to save */
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
@@ -197,7 +200,7 @@ static void patch_reloc (uint8_t *code_ptr, int type,
/* maximum number of register used for input function arguments */
static int tcg_target_get_call_iarg_regs_count (int flags)
{
- return sizeof (tcg_target_call_iarg_regs) / sizeof (tcg_target_call_iarg_regs[0]);
+ return ARRAY_SIZE (tcg_target_call_iarg_regs);
}
/* parse target specific constraints */
@@ -303,6 +306,7 @@ static int tcg_target_const_match (tcg_target_long val,
#define RLDICL XO30( 0)
#define RLDICR XO30( 1)
+#define RLDIMI XO30( 3)
#define BCLR XO19( 16)
#define BCCTR XO19(528)
@@ -365,9 +369,6 @@ static int tcg_target_const_match (tcg_target_long val,
#define SRAD XO31(794)
#define SRADI XO31(413<<1)
-#define LMW OPCD( 46)
-#define STMW OPCD( 47)
-
#define TW XO31( 4)
#define TRAP (TW | TO (31))
@@ -494,6 +495,17 @@ static void tcg_out_ldst (TCGContext *s, int ret, int addr,
}
}
+static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
+ int offset, int op1, int op2)
+{
+ if (offset == (int16_t) (offset & ~3))
+ tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
+ else {
+ tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
+ tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
+ }
+}
+
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
{
tcg_target_long disp;
@@ -691,11 +703,10 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
break;
case 3:
if (bswap) {
- tcg_out32 (s, LWBRX | RT (0) | RB (r0));
- tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r1));
- tcg_out_rld (s, RLDICR, data_reg, data_reg, 32, 31);
- tcg_out32 (s, OR | SAB (0, data_reg, data_reg));
+ tcg_out_movi32 (s, 0, 4);
+ tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
+ tcg_out32 (s, LWBRX | RT ( r1) | RA (r0));
+ tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
}
else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
break;
@@ -858,7 +869,7 @@ static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
if (type == TCG_TYPE_I32)
tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
else
- tcg_out_ldst (s, ret, arg1, arg2, LD, LDX);
+ tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
}
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
@@ -867,7 +878,7 @@ static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
if (type == TCG_TYPE_I32)
tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
else
- tcg_out_ldst (s, arg, arg1, arg2, STD, STDX);
+ tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX);
}
static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
@@ -888,7 +899,7 @@ static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
{
/* XXX: suboptimal */
if (si == (int16_t) si
- || (((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0)
+ || ((((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0))
ppc_addi32 (s, rt, ra, si);
else {
tcg_out_movi (s, TCG_TYPE_I64, 0, si);
@@ -1086,10 +1097,10 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
break;
case INDEX_op_ld32s_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LWA, LWAX);
+ tcg_out_ldsta (s, args[0], args[1], args[2], LWA, LWAX);
break;
case INDEX_op_ld_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LD, LDX);
+ tcg_out_ldsta (s, args[0], args[1], args[2], LD, LDX);
break;
case INDEX_op_st8_i32:
case INDEX_op_st8_i64:
@@ -1104,7 +1115,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
break;
case INDEX_op_st_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], STD, STDX);
+ tcg_out_ldsta (s, args[0], args[1], args[2], STD, STDX);
break;
case INDEX_op_add_i32: