summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Arm64Emitter.cpp
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2021-04-10 12:43:02 +0200
committerJosJuice <josjuice@gmail.com>2021-05-13 10:13:59 +0200
commit749db94dec5d19c4920459f805b8deb398eb67ae (patch)
treeff82caa6cd290ece8ab8d290cdcded500a066f7b /Source/Core/Common/Arm64Emitter.cpp
parent049b92b7ef51b8aaa0f3a9370c3e8bccd44d185b (diff)
Arm64Emitter: Implement more variants of FMOV
Diffstat (limited to 'Source/Core/Common/Arm64Emitter.cpp')
-rw-r--r--Source/Core/Common/Arm64Emitter.cpp43
1 files changed, 23 insertions, 20 deletions
diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp
index 1a718d1e3e..2aa3c99198 100644
--- a/Source/Core/Common/Arm64Emitter.cpp
+++ b/Source/Core/Common/Arm64Emitter.cpp
@@ -3039,28 +3039,31 @@ void ARM64FloatEmitter::FMOV(ARM64Reg Rd, ARM64Reg Rn, bool top)
{
EmitScalar1Source(0, 0, IsDouble(Rd), 0, Rd, Rn);
}
+ else if (IsGPR(Rd) != IsGPR(Rn))
+ {
+ const ARM64Reg gpr = IsGPR(Rn) ? Rn : Rd;
+ const ARM64Reg fpr = IsGPR(Rn) ? Rd : Rn;
+
+ const int sf = Is64Bit(gpr) ? 1 : 0;
+ const int type = Is64Bit(gpr) ? (top ? 2 : 1) : 0;
+ const int rmode = top ? 1 : 0;
+ const int opcode = IsGPR(Rn) ? 7 : 6;
+
+ ASSERT_MSG(DYNA_REC, !top || IsQuad(fpr), "FMOV: top can only be used with quads");
+
+ // TODO: Should this check be more lenient? Sometimes you do want to do things like
+ // read the lower 32 bits of a double
+ ASSERT_MSG(DYNA_REC,
+ (!Is64Bit(gpr) && IsSingle(fpr)) ||
+ (Is64Bit(gpr) && ((IsDouble(fpr) && !top) || (IsQuad(fpr) && top))),
+ "FMOV: Mismatched sizes");
+
+ Write32((sf << 31) | (0x1e << 24) | (type << 22) | (1 << 21) | (rmode << 19) | (opcode << 16) |
+ (DecodeReg(Rn) << 5) | DecodeReg(Rd));
+ }
else
{
- ASSERT_MSG(DYNA_REC, !IsQuad(Rd) && !IsQuad(Rn), "FMOV can't move to/from quads");
- int rmode = 0;
- int opcode = 6;
- int sf = 0;
- if (IsSingle(Rd) && !Is64Bit(Rn) && !top)
- {
- // GPR to scalar single
- opcode |= 1;
- }
- else if (!Is64Bit(Rd) && IsSingle(Rn) && !top)
- {
- // Scalar single to GPR - defaults are correct
- }
- else
- {
- // TODO
- ASSERT_MSG(DYNA_REC, 0, "FMOV: Unhandled case");
- }
- Write32((sf << 31) | (0x1e2 << 20) | (rmode << 19) | (opcode << 16) | (DecodeReg(Rn) << 5) |
- DecodeReg(Rd));
+ ASSERT_MSG(DYNA_REC, 0, "FMOV: Unsupported case");
}
}