diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 93 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsDSPInstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFPU.td | 66 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 7 | 
5 files changed, 143 insertions, 49 deletions
| diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e92d58a879d..7214cb565a8 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -88,6 +88,11 @@ class MipsAsmParser : public MCTargetAsmParser {    MipsAsmParser::OperandMatchResultTy    parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); +  bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind); + +  MipsAsmParser::OperandMatchResultTy +  parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands); +    MipsAsmParser::OperandMatchResultTy    parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); @@ -179,6 +184,10 @@ class MipsAsmParser : public MCTargetAsmParser {      return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;    } +  bool isN64() const { +    return STI.getFeatureBits() & Mips::FeatureN64; +  } +    int matchRegisterName(StringRef Symbol, bool is64BitReg);    int matchCPURegisterName(StringRef Symbol); @@ -245,6 +254,7 @@ private:      k_Memory,      k_PostIndexRegister,      k_Register, +    k_PtrReg,      k_Token    } Kind; @@ -284,6 +294,11 @@ public:      Inst.addOperand(MCOperand::CreateReg(getReg()));    } +  void addPtrRegOperands(MCInst &Inst, unsigned N) const { +    assert(N == 1 && "Invalid number of operands!"); +    Inst.addOperand(MCOperand::CreateReg(getPtrReg())); +  } +    void addExpr(MCInst &Inst, const MCExpr *Expr) const{      // Add as immediate when possible.  Null MCExpr = 0.      if (Expr == 0) @@ -313,6 +328,7 @@ public:    bool isImm() const { return Kind == k_Immediate; }    bool isToken() const { return Kind == k_Token; }    bool isMem() const { return Kind == k_Memory; } +  bool isPtrReg() const { return Kind == k_PtrReg; }    StringRef getToken() const {      assert(Kind == k_Token && "Invalid access!"); @@ -324,8 +340,13 @@ public:      return Reg.RegNum;    } +  unsigned getPtrReg() const { +    assert((Kind == k_PtrReg) && "Invalid access!"); +    return Reg.RegNum; +  } +    void setRegKind(RegisterKind RegKind) { -    assert((Kind == k_Register) && "Invalid access!"); +    assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");      Reg.Kind = RegKind;    } @@ -361,6 +382,14 @@ public:      return Op;    } +  static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { +    MipsOperand *Op = new MipsOperand(k_PtrReg); +    Op->Reg.RegNum = RegNum; +    Op->StartLoc = S; +    Op->EndLoc = E; +    return Op; +  } +    static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {      MipsOperand *Op = new MipsOperand(k_Immediate);      Op->Imm.Val = Val; @@ -1289,6 +1318,68 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(    return MatchOperand_Success;  } +bool +MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, +                           int RegKind) { +  // If the first token is not '$' we have an error. +  if (Parser.getTok().isNot(AsmToken::Dollar)) +    return false; + +  SMLoc S = Parser.getTok().getLoc(); +  Parser.Lex(); +  AsmToken::TokenKind TkKind = getLexer().getKind(); +  int Reg; + +  if (TkKind == AsmToken::Integer) { +    Reg = matchRegisterByNumber(Parser.getTok().getIntVal(), +                                regKindToRegClass(RegKind)); +    if (Reg == -1) +      return false; +  } else if (TkKind == AsmToken::Identifier) { +    if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) +      return false; +    Reg = getReg(regKindToRegClass(RegKind), Reg); +  } else { +    return false; +  } + +  MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc()); +  Op->setRegKind((MipsOperand::RegisterKind)RegKind); +  Operands.push_back(Op); +  Parser.Lex(); +  return true; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { +  MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 : +                                                MipsOperand::Kind_GPR32; + +  // Parse index register. +  if (!parsePtrReg(Operands, RegKind)) +    return MatchOperand_NoMatch; + +  // Parse '('. +  if (Parser.getTok().isNot(AsmToken::LParen)) +    return MatchOperand_NoMatch; + +  Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); +  Parser.Lex(); + +  // Parse base register. +  if (!parsePtrReg(Operands, RegKind)) +    return MatchOperand_NoMatch; + +  // Parse ')'. +  if (Parser.getTok().isNot(AsmToken::RParen)) +    return MatchOperand_NoMatch; + +  Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); +  Parser.Lex(); + +  return MatchOperand_Success; +} +  MipsAsmParser::OperandMatchResultTy  MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,                           int RegKind) { diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index c6f3babec9b..6e12a5d5e5c 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -35,14 +35,18 @@ public:    ///    MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,                         bool bigEndian) : -    MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} +    MCDisassembler(STI), RegInfo(Info), +    IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}    virtual ~MipsDisassemblerBase() {}    const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } +  bool isN64() const { return IsN64; } +  private:    OwningPtr<const MCRegisterInfo> RegInfo; +  bool IsN64;  protected:    bool isBigEndian;  }; @@ -103,6 +107,11 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,                                               uint64_t Address,                                               const void *Decoder); +static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, +                                           unsigned Insn, +                                           uint64_t Address, +                                           const void *Decoder); +  static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,                                              unsigned RegNo,                                              uint64_t Address, @@ -364,6 +373,16 @@ static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, +                                           unsigned RegNo, +                                           uint64_t Address, +                                           const void *Decoder) { +  if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) +    return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); + +  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); +} +  static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,                                              unsigned RegNo,                                              uint64_t Address, diff --git a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td index 53e3389c2ee..b3e01b19f87 100644 --- a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td @@ -348,10 +348,9 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,  class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode,                     InstrItinClass itin> {    dag OutOperandList = (outs GPR32Opnd:$rd); -  dag InOperandList = (ins GPR32Opnd:$base, GPR32Opnd:$index); +  dag InOperandList = (ins PtrRC:$base, PtrRC:$index);    string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})"); -  list<dag> Pattern = [(set GPR32Opnd:$rd, -                       (OpNode GPR32Opnd:$base, GPR32Opnd:$index))]; +  list<dag> Pattern = [(set GPR32Opnd:$rd, (OpNode iPTR:$base, iPTR:$index))];    InstrItinClass Itinerary = itin;    bit mayLoad = 1;  } diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td index ccf3458e1d9..536dff610c3 100644 --- a/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -171,19 +171,19 @@ class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,           [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],           Itin, FrmFR>; -class LWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC, +class LWXC1_FT<string opstr, RegisterOperand DRC,                 InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : -  InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index), +  InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index),           !strconcat(opstr, "\t$fd, ${index}(${base})"), -         [(set DRC:$fd, (OpNode (add PRC:$base, PRC:$index)))], Itin, FrmFI> { +         [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin, FrmFI> {    let AddedComplexity = 20;  } -class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC, +class SWXC1_FT<string opstr, RegisterOperand DRC,                 InstrItinClass Itin, SDPatternOperator OpNode = null_frag> : -  InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index), +  InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index),           !strconcat(opstr, "\t$fs, ${index}(${base})"), -         [(OpNode DRC:$fs, (add PRC:$base, PRC:$index))], Itin, FrmFI> { +         [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin, FrmFI> {    let AddedComplexity = 20;  } @@ -378,52 +378,30 @@ let Predicates = [NotFP64bit, HasStdEnc] in {  // Indexed loads and stores.  let Predicates = [HasFPIdx, HasStdEnc] in { -  def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR32Opnd, IIFLoad, load>, -              LWXC1_FM<0>; -  def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, GPR32Opnd, IIFStore, store>, -              SWXC1_FM<8>; +  def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>; +  def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, SWXC1_FM<8>;  } -let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in { -  def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, GPR32Opnd, IIFLoad, load>, -              LWXC1_FM<1>; -  def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, GPR32Opnd, IIFStore, store>, -              SWXC1_FM<9>; +let Predicates = [HasFPIdx, NotFP64bit, HasStdEnc] in { +  def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, IIFLoad, load>, LWXC1_FM<1>; +  def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, IIFStore, store>, SWXC1_FM<9>;  } -let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in { -  def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR32Opnd, IIFLoad, load>, -                LWXC1_FM<1>; -  def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR32Opnd, IIFStore, store>, -                SWXC1_FM<9>; +let Predicates = [HasFPIdx, IsFP64bit, HasStdEnc], +    DecoderNamespace="Mips64" in { +  def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, IIFLoad, load>, LWXC1_FM<1>; +  def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, IIFStore, store>, SWXC1_FM<9>;  } -// n64 -let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in { -  def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32Opnd, GPR64Opnd, IIFLoad, load>, -                 LWXC1_FM<0>; -  def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64Opnd, GPR64Opnd, IIFLoad, -                             load>, LWXC1_FM<1>; -  def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32Opnd, GPR64Opnd, IIFStore, -                          store>, SWXC1_FM<8>; -  def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64Opnd, GPR64Opnd, IIFStore, -                            store>, SWXC1_FM<9>; +// Load/store doubleword indexed unaligned. +let Predicates = [NotFP64bit, HasStdEnc] in { +  def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; +  def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, SWXC1_FM<0xd>;  } -// Load/store doubleword indexed unaligned. -let Predicates = [NotMips64, HasStdEnc] in { -  def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, GPR32Opnd, IIFLoad>, -              LWXC1_FM<0x5>; -  def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, GPR32Opnd, IIFStore>, -              SWXC1_FM<0xd>; -} - -let Predicates = [HasMips64, HasStdEnc], -  DecoderNamespace="Mips64" in { -  def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, GPR32Opnd, IIFLoad>, -                LWXC1_FM<0x5>; -  def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, GPR32Opnd, IIFStore>, -                SWXC1_FM<0xd>; +let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace="Mips64" in { +  def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; +  def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, IIFStore>, SWXC1_FM<0xd>;  }  /// Floating-point Aritmetic diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 714c7a8055c..5518b8c5328 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -279,6 +279,11 @@ def MipsMemAsmOperand : AsmOperandClass {    let ParserMethod = "parseMemOperand";  } +def PtrRegAsmOperand : AsmOperandClass { +  let Name = "PtrReg"; +  let ParserMethod = "parsePtrReg"; +} +  // Address operand  def mem : Operand<iPTR> {    let PrintMethod = "printMemOperand"; @@ -297,6 +302,8 @@ def mem_ea : Operand<iPTR> {  def PtrRC : Operand<iPTR> {    let MIOperandInfo = (ops ptr_rc); +  let DecoderMethod = "DecodePtrRegisterClass"; +  let ParserMatchClass = PtrRegAsmOperand;  }  // size operand of ext instruction | 

