aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRSDuck <rsduck@users.noreply.github.com>2019-07-12 16:42:42 +0200
committerRSDuck <rsduck@users.noreply.github.com>2020-04-26 13:03:00 +0200
commit9b3c14b58abd987d9eb992b04f1f10ee8a6c91f7 (patch)
treef3c17ea3aca69b710cb0a689c9a5c5ead4dce0e0
parent2efab201e936ab0f60baf1de8e957080141d2d93 (diff)
jit: SMULL and SMLAL
-rw-r--r--src/ARMJIT_x64/ARMJIT_ALU.cpp56
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.cpp2
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.h1
3 files changed, 55 insertions, 4 deletions
diff --git a/src/ARMJIT_x64/ARMJIT_ALU.cpp b/src/ARMJIT_x64/ARMJIT_ALU.cpp
index cbe67fd..4afafed 100644
--- a/src/ARMJIT_x64/ARMJIT_ALU.cpp
+++ b/src/ARMJIT_x64/ARMJIT_ALU.cpp
@@ -290,6 +290,59 @@ void Compiler::A_Comp_MUL_MLA()
Comp_MulOp(S, add, rd, rm, rs, rn);
}
+void Compiler::A_Comp_SMULL_SMLAL()
+{
+ bool S = CurInstr.Instr & (1 << 20);
+ bool add = CurInstr.Instr & (1 << 21);
+ OpArg rd = MapReg(CurInstr.A_Reg(16));
+ OpArg rm = MapReg(CurInstr.A_Reg(0));
+ OpArg rs = MapReg(CurInstr.A_Reg(8));
+ OpArg rn = MapReg(CurInstr.A_Reg(12));
+
+ if (Num == 0)
+ Comp_AddCycles_CI(S ? 3 : 1);
+ else
+ {
+ XOR(32, R(RSCRATCH), R(RSCRATCH));
+ MOV(32, R(RSCRATCH3), rs);
+ TEST(32, R(RSCRATCH3), R(RSCRATCH3));
+ FixupBranch zeroBSR = J_CC(CC_Z);
+ BSR(32, RSCRATCH2, R(RSCRATCH3));
+ NOT(32, R(RSCRATCH3));
+ BSR(32, RSCRATCH, R(RSCRATCH3));
+ CMP(32, R(RSCRATCH2), R(RSCRATCH));
+ CMOVcc(32, RSCRATCH, R(RSCRATCH2), CC_L);
+ SHR(32, R(RSCRATCH), Imm8(3));
+ SetJumpTarget(zeroBSR); // fortunately that's even right
+ Comp_AddCycles_CI(RSCRATCH, 2);
+ }
+
+ MOVSX(64, 32, RSCRATCH2, rm);
+ MOVSX(64, 32, RSCRATCH3, rs);
+ if (add)
+ {
+ MOV(32, R(RSCRATCH), rd);
+ SHL(64, R(RSCRATCH), Imm8(32));
+ OR(64, R(RSCRATCH), rn);
+
+ IMUL(64, RSCRATCH2, R(RSCRATCH3));
+ ADD(64, R(RSCRATCH2), R(RSCRATCH));
+ }
+ else
+ {
+ IMUL(64, RSCRATCH2, R(RSCRATCH3));
+ if (S)
+ TEST(64, R(RSCRATCH2), R(RSCRATCH2));
+ }
+
+ if (S)
+ Comp_RetriveFlags(false, false, false);
+
+ MOV(32, rn, R(RSCRATCH2));
+ SHR(64, R(RSCRATCH2), Imm8(32));
+ MOV(32, rd, R(RSCRATCH2));
+}
+
void Compiler::Comp_RetriveFlags(bool sign, bool retriveCV, bool carryUsed)
{
CPSRDirty = true;
@@ -302,9 +355,6 @@ void Compiler::Comp_RetriveFlags(bool sign, bool retriveCV, bool carryUsed)
LEA(32, RSCRATCH2, MComplex(RSCRATCH, RSCRATCH3, SCALE_2, 0));
}
- if (carryUsed == 983298)
- printf("etwas ist faul im lande daenemark %x\n", CurInstr.Instr);
-
SETcc(CC_S, R(RSCRATCH));
SETcc(CC_Z, R(RSCRATCH3));
LEA(32, RSCRATCH, MComplex(RSCRATCH3, RSCRATCH, SCALE_2, 0));
diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
index 8a895d1..b6dd529 100644
--- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp
+++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
@@ -375,7 +375,7 @@ CompileFunc Compiler::GetCompFunc(int kind)
// CMN
A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp, A_Comp_CmpOp,
// Mul
- A_Comp_MUL_MLA, A_Comp_MUL_MLA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ A_Comp_MUL_MLA, A_Comp_MUL_MLA, NULL, NULL, NULL, A_Comp_SMULL_SMLAL, NULL, NULL, NULL, NULL, NULL,
// ARMv5 stuff
A_Comp_CLZ, NULL, NULL, NULL, NULL,
// STR
diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.h b/src/ARMJIT_x64/ARMJIT_Compiler.h
index 89dfe28..f9bc227 100644
--- a/src/ARMJIT_x64/ARMJIT_Compiler.h
+++ b/src/ARMJIT_x64/ARMJIT_Compiler.h
@@ -57,6 +57,7 @@ private:
void A_Comp_CmpOp();
void A_Comp_MUL_MLA();
+ void A_Comp_SMULL_SMLAL();
void A_Comp_CLZ();