summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-10-03 23:38:36 +0000
committerJim Grosbach <grosbach@apple.com>2011-10-03 23:38:36 +0000
commit9d39036f62674606565217a10db28171b9594bc7 (patch)
tree0838a0ef005b9ec40b38b8200dff725c1d4c4fd8 /lib/Target
parent2a3f19d7e3f77d4d2f8e2b030d6ec1fa11b2abea (diff)
downloadllvm-9d39036f62674606565217a10db28171b9594bc7.tar.gz
llvm-9d39036f62674606565217a10db28171b9594bc7.tar.bz2
llvm-9d39036f62674606565217a10db28171b9594bc7.tar.xz
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
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td8
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp76
2 files changed, 84 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index 7115db581f..e746cf20d0 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -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;
}
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 81a6786804..56f9955cf5 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -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,