summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2016-02-28 10:35:47 +0100
committerdegasus <wickmarkus@web.de>2016-02-29 08:39:14 +0100
commit4478146c802e059e7e5dc67f57f9265da110f6b4 (patch)
treedc1c56cb32c79e272eea30729a3b705d5405f680 /Source/Core
parent961901daaec87de966ee3eb259060a9c2b651497 (diff)
JitArm64: Split addi from arith_imm.
They ARM assembly has different immediate versions for logic and additions, so there is no use in merging those instructions.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h3
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp97
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp4
3 files changed, 57 insertions, 47 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index a15712d36f..252a9e6004 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -83,6 +83,7 @@ public:
void arith_imm(UGeckoInstruction inst);
void boolX(UGeckoInstruction inst);
void addx(UGeckoInstruction inst);
+ void addix(UGeckoInstruction inst);
void extsXx(UGeckoInstruction inst);
void cntlzwx(UGeckoInstruction inst);
void negx(UGeckoInstruction inst);
@@ -249,6 +250,6 @@ private:
void ComputeCarry();
typedef u32 (*Operation)(u32, u32);
- void reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, ArithOption), bool Rc = false);
+ void reg_imm(u32 d, u32 a, u32 value, Operation do_op, void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, ArithOption), bool Rc = false);
};
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 4e1f26e072..b12d590b55 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -77,11 +77,6 @@ void JitArm64::ComputeCarry()
}
// Following static functions are used in conjunction with reg_imm
-static u32 Add(u32 a, u32 b)
-{
- return a + b;
-}
-
static u32 Or(u32 a, u32 b)
{
return a | b;
@@ -97,38 +92,24 @@ static u32 Xor(u32 a, u32 b)
return a ^ b;
}
-void JitArm64::reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption), bool Rc)
+void JitArm64::reg_imm(u32 d, u32 a, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption), bool Rc)
{
- if (a || binary)
- {
- if (gpr.IsImm(a))
- {
- gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
- if (Rc)
- ComputeRC(gpr.GetImm(d));
- }
- else
- {
- gpr.BindToRegister(d, d == a);
- ARM64Reg WA = gpr.GetReg();
- MOVI2R(WA, value);
- (this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
- gpr.Unlock(WA);
-
- if (Rc)
- ComputeRC(gpr.R(d), 0);
- }
- }
- else if (do_op == Add)
+ if (gpr.IsImm(a))
{
- // a == 0, implies zero register
- gpr.SetImmediate(d, value);
+ gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
if (Rc)
- ComputeRC(value, 0);
+ ComputeRC(gpr.GetImm(d));
}
else
{
- _assert_msg_(DYNA_REC, false, "Hit impossible condition in reg_imm!");
+ gpr.BindToRegister(d, d == a);
+ ARM64Reg WA = gpr.GetReg();
+ MOVI2R(WA, value);
+ (this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
+ gpr.Unlock(WA);
+
+ if (Rc)
+ ComputeRC(gpr.R(d), 0);
}
}
@@ -136,42 +117,70 @@ void JitArm64::arith_imm(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
- u32 d = inst.RD, a = inst.RA, s = inst.RS;
+ u32 a = inst.RA, s = inst.RS;
switch (inst.OPCD)
{
- case 14: // addi
- reg_imm(d, a, false, (u32)(s32)inst.SIMM_16, Add, &ARM64XEmitter::ADD);
- break;
- case 15: // addis
- reg_imm(d, a, false, (u32)inst.SIMM_16 << 16, Add, &ARM64XEmitter::ADD);
- break;
case 24: // ori
if (a == 0 && s == 0 && inst.UIMM == 0 && !inst.Rc) //check for nop
{
// NOP
return;
}
- reg_imm(a, s, true, inst.UIMM, Or, &ARM64XEmitter::ORR);
+ reg_imm(a, s, inst.UIMM, Or, &ARM64XEmitter::ORR);
break;
case 25: // oris
- reg_imm(a, s, true, inst.UIMM << 16, Or, &ARM64XEmitter::ORR);
+ reg_imm(a, s, inst.UIMM << 16, Or, &ARM64XEmitter::ORR);
break;
case 28: // andi
- reg_imm(a, s, true, inst.UIMM, And, &ARM64XEmitter::AND, true);
+ reg_imm(a, s, inst.UIMM, And, &ARM64XEmitter::AND, true);
break;
case 29: // andis
- reg_imm(a, s, true, inst.UIMM << 16, And, &ARM64XEmitter::AND, true);
+ reg_imm(a, s, inst.UIMM << 16, And, &ARM64XEmitter::AND, true);
break;
case 26: // xori
- reg_imm(a, s, true, inst.UIMM, Xor, &ARM64XEmitter::EOR);
+ reg_imm(a, s, inst.UIMM, Xor, &ARM64XEmitter::EOR);
break;
case 27: // xoris
- reg_imm(a, s, true, inst.UIMM << 16, Xor, &ARM64XEmitter::EOR);
+ reg_imm(a, s, inst.UIMM << 16, Xor, &ARM64XEmitter::EOR);
break;
}
}
+void JitArm64::addix(UGeckoInstruction inst)
+{
+ INSTRUCTION_START
+ JITDISABLE(bJITIntegerOff);
+ u32 d = inst.RD, a = inst.RA;
+
+ u32 value = (u32)(s32)inst.SIMM_16;
+
+ if (inst.OPCD == 15)
+ value <<= 16;
+
+ if (a)
+ {
+ if (gpr.IsImm(a))
+ {
+ gpr.SetImmediate(d, gpr.GetImm(a) + value);
+ }
+ else
+ {
+ gpr.BindToRegister(d, d == a);
+
+ ARM64Reg WA = gpr.GetReg();
+ MOVI2R(WA, value);
+ ADD(gpr.R(d), gpr.R(a), WA);
+ gpr.Unlock(WA);
+ }
+ }
+ else
+ {
+ // a == 0, implies zero register
+ gpr.SetImmediate(d, value);
+ }
+}
+
void JitArm64::boolX(UGeckoInstruction inst)
{
INSTRUCTION_START
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
index 700cf42df9..96b3f9046f 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
@@ -49,8 +49,8 @@ static GekkoOPTemplate primarytable[] =
{11, &JitArm64::cmpi}, // cmpi
{12, &JitArm64::addic}, // addic
{13, &JitArm64::addic}, // addic_rc
- {14, &JitArm64::arith_imm}, // addi
- {15, &JitArm64::arith_imm}, // addis
+ {14, &JitArm64::addix}, // addi
+ {15, &JitArm64::addix}, // addis
{20, &JitArm64::rlwimix}, // rlwimix
{21, &JitArm64::rlwinmx}, // rlwinmx