mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
Add ARM fconsts/fconstd aliases for vmov.f32/vmov.f64
This commit adds the pre-UAL aliases of fconsts and fconstd for vmov.f32 and vmov.f64. They use an InstAlias rather than a MnemonicAlias to properly support the predicate operand. We need to support encoded 8-bit constants in order to implement the pre-UAL fconsts/fconstd aliases for vmov.f32/vmov.f64, so this commit also fixes parsing of encoded floating point constants used in vmov.f32/vmov.f64 instructions. Now we can support assembly code like this: fconsts s0, #0x70 which is equivalent to vmov.f32 s0, #1.0. Most of the code was already in place to support this feature. Previously the code was trying to accept encoded 8-bit float constants for the vmov.f32/vmov.f64 instructions. It looks like the support for parsing encoded floats was lost in a refactoring in commit r148556 and we did not have any tests in place to catch it. The change in this commit is to keep the parsed value as a 32-bit float instead of a 64-bit double because that is what the isFPImm() function expects to find. There is no loss of precision by using a 32-bit float here because we are still limited to an 8-bit encoded value in the end. Additionally, we explicitly reject encoded 8-bit floats for vmovf.32/64. This is the same as the current behavior, but we now do it explicitly rather than accidently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198697 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -4620,8 +4620,12 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
// for these:
|
||||
// vmov.i{8|16|32|64} <dreg|qreg>, #imm
|
||||
ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
|
||||
if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
|
||||
TyOp->getToken() != ".f64"))
|
||||
bool isVmovf = TyOp->isToken() && (TyOp->getToken() == ".f32" ||
|
||||
TyOp->getToken() == ".f64");
|
||||
ARMOperand *Mnemonic = static_cast<ARMOperand*>(Operands[0]);
|
||||
bool isFconst = Mnemonic->isToken() && (Mnemonic->getToken() == "fconstd" ||
|
||||
Mnemonic->getToken() == "fconsts");
|
||||
if (!(isVmovf || isFconst))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
Parser.Lex(); // Eat '#' or '$'.
|
||||
@@ -4634,7 +4638,7 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
}
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc Loc = Tok.getLoc();
|
||||
if (Tok.is(AsmToken::Real)) {
|
||||
if (Tok.is(AsmToken::Real) && isVmovf) {
|
||||
APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
|
||||
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
|
||||
// If we had a '-' in front, toggle the sign bit.
|
||||
@@ -4647,15 +4651,16 @@ parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
}
|
||||
// Also handle plain integers. Instructions which allow floating point
|
||||
// immediates also allow a raw encoded 8-bit value.
|
||||
if (Tok.is(AsmToken::Integer)) {
|
||||
if (Tok.is(AsmToken::Integer) && isFconst) {
|
||||
int64_t Val = Tok.getIntVal();
|
||||
Parser.Lex(); // Eat the token.
|
||||
if (Val > 255 || Val < 0) {
|
||||
Error(Loc, "encoded floating point value out of range");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
double RealVal = ARM_AM::getFPImmFloat(Val);
|
||||
Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
|
||||
float RealVal = ARM_AM::getFPImmFloat(Val);
|
||||
Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
|
||||
|
||||
Operands.push_back(ARMOperand::CreateImm(
|
||||
MCConstantExpr::Create(Val, getContext()), S,
|
||||
Parser.getTok().getLoc()));
|
||||
@@ -4910,7 +4915,7 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
|
||||
Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
|
||||
Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
|
||||
Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
|
||||
Mnemonic == "vfms" || Mnemonic == "vfnms" ||
|
||||
Mnemonic == "vfms" || Mnemonic == "vfnms" || Mnemonic == "fconsts" ||
|
||||
(Mnemonic == "movs" && isThumb()))) {
|
||||
Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
|
||||
CarrySetting = true;
|
||||
|
Reference in New Issue
Block a user