diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-10-03 23:38:36 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-10-03 23:38:36 +0000 |
commit | 9d39036f62674606565217a10db28171b9594bc7 (patch) | |
tree | 0838a0ef005b9ec40b38b8200dff725c1d4c4fd8 /lib/Target | |
parent | 2a3f19d7e3f77d4d2f8e2b030d6ec1fa11b2abea (diff) | |
download | llvm-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.td | 8 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 76 |
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, |