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 | e7fbce7acbee659c317828ee6795a06183db34b0 (patch) | |
| tree | 75a96bf0be0368654e38346f4f96899ac3d9561a | |
| parent | 208d54ce0940e2c17be86bd9555c3e8980842e0c (diff) | |
| download | bcm5719-llvm-e7fbce7acbee659c317828ee6795a06183db34b0.tar.gz bcm5719-llvm-e7fbce7acbee659c317828ee6795a06183db34b0.zip  | |
ARM assembly parsing and encoding for VMOV immediate.
llvm-svn: 141046
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrVFP.td | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 76 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/simple-fp-encoding.s | 14 | 
3 files changed, 93 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td index 7115db581fe..e746cf20d03 100644 --- a/llvm/lib/Target/ARM/ARMInstrVFP.td +++ b/llvm/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/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 81a67868049..56f9955cf53 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/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, diff --git a/llvm/test/MC/ARM/simple-fp-encoding.s b/llvm/test/MC/ARM/simple-fp-encoding.s index 969cc8aa2ed..e7d452a2849 100644 --- a/llvm/test/MC/ARM/simple-fp-encoding.s +++ b/llvm/test/MC/ARM/simple-fp-encoding.s @@ -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]  | 

