[llvm-commits] [llvm] r141046 - in /llvm/trunk: lib/Target/ARM/ARMInstrVFP.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/simple-fp-encoding.s

Jim Grosbach grosbach at apple.com
Mon Oct 3 16:38:41 PDT 2011


Author: grosbach
Date: Mon Oct  3 18:38:36 2011
New Revision: 141046

URL: http://llvm.org/viewvc/llvm-project?rev=141046&view=rev
Log:
ARM assembly parsing and encoding for VMOV immediate.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/simple-fp-encoding.s

Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=141046&r1=141045&r2=141046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Mon Oct  3 18:38:36 2011
@@ -31,6 +31,12 @@
 // 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 @@
       return CurDAG->getTargetConstant(enc, MVT::i32);
     }]>> {
   let PrintMethod = "printFPImmOperand";
+  let ParserMatchClass = FPImmOperand;
 }
 
 def vfp_f64imm : Operand<f64>,
@@ -51,6 +58,7 @@
       return CurDAG->getTargetConstant(enc, MVT::i32);
     }]>> {
   let PrintMethod = "printFPImmOperand";
+  let ParserMatchClass = FPImmOperand;
 }
 
 

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=141046&r1=141045&r2=141046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Oct  3 18:38:36 2011
@@ -158,6 +158,7 @@
   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 @@
     CoprocNum,
     CoprocReg,
     Immediate,
+    FPImmediate,
     MemBarrierOpt,
     Memory,
     PostIndexRegister,
@@ -305,6 +307,10 @@
       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 @@
     case Immediate:
       Imm = o.Imm;
       break;
+    case FPImmediate:
+      FPImm = o.FPImm;
+      break;
     case MemBarrierOpt:
       MBOpt = o.MBOpt;
       break;
@@ -449,6 +458,11 @@
     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 @@
   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 @@
     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 @@
     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 @@
 
 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 @@
   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,

Modified: llvm/trunk/test/MC/ARM/simple-fp-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/simple-fp-encoding.s?rev=141046&r1=141045&r2=141046&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/simple-fp-encoding.s (original)
+++ llvm/trunk/test/MC/ARM/simple-fp-encoding.s Mon Oct  3 18:38:36 2011
@@ -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
-
-@ FIXME: vmov.f32 s0, #3.000000e+00  @ encoding: [0x08,0x0a,0xb0,0xee]
-@        vmov.f32        s0, #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
+
+@ 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]





More information about the llvm-commits mailing list