Arm64Emitter: Implement more variants of FMOV

This commit is contained in:
JosJuice 2021-04-10 12:43:02 +02:00
parent 049b92b7ef
commit 749db94dec
1 changed files with 23 additions and 20 deletions

View File

@ -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");
}
}