diff options
Diffstat (limited to 'lib/Target/Sparc/AsmParser/SparcAsmParser.cpp')
| -rw-r--r-- | lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 99 | 
1 files changed, 91 insertions, 8 deletions
diff --git a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index a55274744fd1c..b2003b8f101be 100644 --- a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -7,18 +7,18 @@  //  //===----------------------------------------------------------------------===// -#include "MCTargetDesc/SparcMCTargetDesc.h"  #include "MCTargetDesc/SparcMCExpr.h" +#include "MCTargetDesc/SparcMCTargetDesc.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/MC/MCContext.h"  #include "llvm/MC/MCInst.h"  #include "llvm/MC/MCObjectFileInfo.h"  #include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCParser/MCTargetAsmParser.h"  #include "llvm/MC/MCRegisterInfo.h"  #include "llvm/MC/MCStreamer.h"  #include "llvm/MC/MCSubtargetInfo.h"  #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCTargetAsmParser.h"  #include "llvm/Support/TargetRegistry.h"  using namespace llvm; @@ -150,6 +150,22 @@ public:      Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,      Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7}; +  static const MCPhysReg CoprocRegs[32] = { +    Sparc::C0,  Sparc::C1,  Sparc::C2,  Sparc::C3, +    Sparc::C4,  Sparc::C5,  Sparc::C6,  Sparc::C7, +    Sparc::C8,  Sparc::C9,  Sparc::C10, Sparc::C11, +    Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15, +    Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19, +    Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23, +    Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27, +    Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 }; + +  static const MCPhysReg CoprocPairRegs[] = { +    Sparc::C0_C1,   Sparc::C2_C3,   Sparc::C4_C5,   Sparc::C6_C7, +    Sparc::C8_C9,   Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15, +    Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23, +    Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31}; +    /// SparcOperand - Instances of this class represent a parsed Sparc machine  /// instruction.  class SparcOperand : public MCParsedAsmOperand { @@ -161,6 +177,8 @@ public:      rk_FloatReg,      rk_DoubleReg,      rk_QuadReg, +    rk_CoprocReg, +    rk_CoprocPairReg,      rk_Special,    }; @@ -224,6 +242,9 @@ public:                                     || Reg.Kind == rk_DoubleReg));    } +  bool isCoprocReg() const { +    return (Kind == k_Register && Reg.Kind == rk_CoprocReg); +  }    StringRef getToken() const {      assert(Kind == k_Token && "Invalid access!"); @@ -398,6 +419,19 @@ public:      return true;    } +  static bool MorphToCoprocPairReg(SparcOperand &Op) { +    unsigned Reg = Op.getReg(); +    assert(Op.Reg.Kind == rk_CoprocReg); +    unsigned regIdx = 32; +    if (Reg >= Sparc::C0 && Reg <= Sparc::C31) +      regIdx = Reg - Sparc::C0; +    if (regIdx % 2 || regIdx > 31) +      return false; +    Op.Reg.RegNum = CoprocPairRegs[regIdx / 2]; +    Op.Reg.Kind = rk_CoprocPairReg; +    return true; +  } +      static std::unique_ptr<SparcOperand>    MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {      unsigned offsetReg = Op->getReg(); @@ -602,8 +636,12 @@ bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,        return Error(Loc, "unexpected token");      } -    while (getLexer().is(AsmToken::Comma)) { -      Parser.Lex(); // Eat the comma. +    while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) { +      if (getLexer().is(AsmToken::Plus)) { +      // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them. +        Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc())); +      } +      Parser.Lex(); // Eat the comma or plus.        // Parse and remember the operand.        if (parseOperand(Operands, Name) != MatchOperand_Success) {          SMLoc Loc = getLexer().getLoc(); @@ -646,6 +684,12 @@ ParseDirective(AsmToken DirectiveID)      Parser.eatToEndOfStatement();      return false;    } +  if (IDVal == ".proc") { +    // For compatibility, ignore this directive. +    // (It's supposed to be an "optimization" in the Sun assembler) +    Parser.eatToEndOfStatement(); +    return false; +  }    // Let the MC layer to handle other directives.    return true; @@ -728,7 +772,7 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {                                                   Parser.getTok().getLoc()));      Parser.Lex(); // Eat the [ -    if (Mnemonic == "cas" || Mnemonic == "casx") { +    if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {        SMLoc S = Parser.getTok().getLoc();        if (getLexer().getKind() != AsmToken::Percent)          return MatchOperand_NoMatch; @@ -809,6 +853,15 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,        case Sparc::FSR:          Op = SparcOperand::CreateToken("%fsr", S);          break; +      case Sparc::FQ: +        Op = SparcOperand::CreateToken("%fq", S); +        break; +      case Sparc::CPSR: +        Op = SparcOperand::CreateToken("%csr", S); +        break; +      case Sparc::CPQ: +        Op = SparcOperand::CreateToken("%cq", S); +        break;        case Sparc::WIM:          Op = SparcOperand::CreateToken("%wim", S);          break; @@ -846,8 +899,7 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,        const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,                                                    getContext()); -      if (isCall && -          getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) +      if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())          Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,                                    getContext());        Op = SparcOperand::CreateImm(Res, S, E); @@ -941,6 +993,24 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,        return true;      } +    if (name.equals("fq")) { +      RegNo = Sparc::FQ; +      RegKind = SparcOperand::rk_Special; +      return true; +    } + +    if (name.equals("csr")) { +      RegNo = Sparc::CPSR; +      RegKind = SparcOperand::rk_Special; +      return true; +    } + +    if (name.equals("cq")) { +      RegNo = Sparc::CPQ; +      RegKind = SparcOperand::rk_Special; +      return true; +    } +          if (name.equals("wim")) {        RegNo = Sparc::WIM;        RegKind = SparcOperand::rk_Special; @@ -1025,6 +1095,15 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,        return true;      } +    // %c0 - %c31 +    if (name.substr(0, 1).equals_lower("c") +        && !name.substr(1).getAsInteger(10, intVal) +        && intVal < 32) { +      RegNo = CoprocRegs[intVal]; +      RegKind = SparcOperand::rk_CoprocReg; +      return true; +    } +          if (name.equals("tpc")) {        RegNo = Sparc::TPC;        RegKind = SparcOperand::rk_Special; @@ -1141,7 +1220,7 @@ SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,    // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted    // as %got10 or %got22 relocation. -  if (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) { +  if (getContext().getObjectFileInfo()->isPositionIndependent()) {      switch(VK) {      default: break;      case SparcMCExpr::VK_Sparc_LO: @@ -1215,5 +1294,9 @@ unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,      if (SparcOperand::MorphToIntPairReg(Op))        return MCTargetAsmParser::Match_Success;    } +  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) { +     if (SparcOperand::MorphToCoprocPairReg(Op)) +       return MCTargetAsmParser::Match_Success; +   }    return Match_InvalidOperand;  }  | 
