ARM assembly parsing and encoding for VMOV immediate.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141046 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-10-03 23:38:36 +00:00
parent 2a3f19d7e3
commit 9d39036f62
3 changed files with 92 additions and 4 deletions

View File

@ -31,6 +31,12 @@ def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
// Operand Definitions.
//
// 8-bit floating-point immediate encodings.
def FPImmOperand : AsmOperandClass {
let Name = "FPImm";
let ParserMethod = "parseFPImm";
}
def vfp_f32imm : Operand<f32>,
PatLeaf<(f32 fpimm), [{
return ARM_AM::getFP32Imm(N->getValueAPF()) != -1;
@ -40,6 +46,7 @@ def vfp_f32imm : Operand<f32>,
return CurDAG->getTargetConstant(enc, MVT::i32);
}]>> {
let PrintMethod = "printFPImmOperand";
let ParserMatchClass = FPImmOperand;
}
def vfp_f64imm : Operand<f64>,
@ -51,6 +58,7 @@ def vfp_f64imm : Operand<f64>,
return CurDAG->getTargetConstant(enc, MVT::i32);
}]>> {
let PrintMethod = "printFPImmOperand";
let ParserMatchClass = FPImmOperand;
}

View File

@ -158,6 +158,7 @@ class ARMAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
// Asm Match Converter Methods
bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
@ -247,6 +248,7 @@ class ARMOperand : public MCParsedAsmOperand {
CoprocNum,
CoprocReg,
Immediate,
FPImmediate,
MemBarrierOpt,
Memory,
PostIndexRegister,
@ -305,6 +307,10 @@ class ARMOperand : public MCParsedAsmOperand {
const MCExpr *Val;
} Imm;
struct {
unsigned Val; // encoded 8-bit representation
} FPImm;
/// Combined record for all forms of ARM address expressions.
struct {
unsigned BaseRegNum;
@ -380,6 +386,9 @@ public:
case Immediate:
Imm = o.Imm;
break;
case FPImmediate:
FPImm = o.FPImm;
break;
case MemBarrierOpt:
MBOpt = o.MBOpt;
break;
@ -449,6 +458,11 @@ public:
return Imm.Val;
}
unsigned getFPImm() const {
assert(Kind == FPImmediate && "Invalid access!");
return FPImm.Val;
}
ARM_MB::MemBOpt getMemBarrierOpt() const {
assert(Kind == MemBarrierOpt && "Invalid access!");
return MBOpt.Val;
@ -471,6 +485,7 @@ public:
bool isITMask() const { return Kind == ITCondMask; }
bool isITCondCode() const { return Kind == CondCode; }
bool isImm() const { return Kind == Immediate; }
bool isFPImm() const { return Kind == FPImmediate; }
bool isImm8s4() const {
if (Kind != Immediate)
return false;
@ -952,6 +967,11 @@ public:
addExpr(Inst, getImm());
}
void addFPImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateImm(getFPImm()));
}
void addImm8s4Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
// FIXME: We really want to scale the value here, but the LDRD/STRD
@ -1467,6 +1487,14 @@ public:
return Op;
}
static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
ARMOperand *Op = new ARMOperand(FPImmediate);
Op->FPImm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
}
static ARMOperand *CreateMem(unsigned BaseRegNum,
const MCConstantExpr *OffsetImm,
unsigned OffsetRegNum,
@ -1529,6 +1557,10 @@ public:
void ARMOperand::print(raw_ostream &OS) const {
switch (Kind) {
case FPImmediate:
OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
<< ") >";
break;
case CondCode:
OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
break;
@ -3024,6 +3056,50 @@ bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
return false;
}
/// parseFPImm - A floating point immediate expression operand.
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
if (Parser.getTok().isNot(AsmToken::Hash))
return MatchOperand_NoMatch;
Parser.Lex(); // Eat the '#'.
// Handle negation, as that still comes through as a separate token.
bool isNegative = false;
if (Parser.getTok().is(AsmToken::Minus)) {
isNegative = true;
Parser.Lex();
}
const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Real)) {
APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
// If we had a '-' in front, toggle the sign bit.
IntVal ^= (uint64_t)isNegative << 63;
int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
Parser.Lex(); // Eat the token.
if (Val == -1) {
TokError("floating point value out of range");
return MatchOperand_ParseFail;
}
Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
return MatchOperand_Success;
}
if (Tok.is(AsmToken::Integer)) {
int64_t Val = Tok.getIntVal();
Parser.Lex(); // Eat the token.
if (Val > 255 || Val < 0) {
TokError("encoded floating point value out of range");
return MatchOperand_ParseFail;
}
Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
return MatchOperand_Success;
}
TokError("invalid floating point immediate");
return MatchOperand_ParseFail;
}
/// Parse a arm instruction operand. For now this parses the operand regardless
/// of the mnemonic.
bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,

View File

@ -141,11 +141,15 @@
@ CHECK: vmsr fpsid, r0 @ encoding: [0x10,0x0a,0xe0,0xee]
vmsr fpsid, r0
@ FIXME: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee]
@ vmov.f64 d16, #3.000000e+00
vmov.f64 d16, #3.000000e+00
vmov.f32 s0, #3.000000e+00
vmov.f64 d16, #-3.000000e+00
vmov.f32 s0, #-3.000000e+00
@ FIXME: vmov.f32 s0, #3.000000e+00 @ encoding: [0x08,0x0a,0xb0,0xee]
@ vmov.f32 s0, #3.000000e+00
@ CHECK: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee]
@ CHECK: vmov.f32 s0, #3.000000e+00 @ encoding: [0x08,0x0a,0xb0,0xee]
@ CHECK: vmov.f64 d16, #-3.000000e+00 @ encoding: [0x08,0x0b,0xf8,0xee]
@ CHECK: vmov.f32 s0, #-3.000000e+00 @ encoding: [0x08,0x0a,0xb8,0xee]
@ CHECK: vmov s0, r0 @ encoding: [0x10,0x0a,0x00,0xee]
@ CHECK: vmov s1, r1 @ encoding: [0x90,0x1a,0x00,0xee]