From 1c056d8be93c2dd3b180fd165c4fbf229343e96c Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Mon, 31 Mar 2014 18:51:43 +0000 Subject: [PATCH] Revert: [mips] Rewrite MipsAsmParser and MipsOperand.' due to buildbot errors in lld tests. It's currently unable to parse 'sym + imm' without surrounding parenthesis. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205237 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 1638 ++++++++++++--------- lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 52 +- lib/Target/Mips/MipsISelLowering.cpp | 1 - lib/Target/Mips/MipsISelLowering.h | 3 - lib/Target/Mips/MipsInstrInfo.td | 26 +- lib/Target/Mips/MipsMSAInstrInfo.td | 50 +- lib/Target/Mips/MipsRegisterInfo.td | 100 +- lib/Target/Mips/MipsSEISelLowering.cpp | 13 +- test/MC/Mips/cfi.s | 13 - test/MC/Mips/mips-register-names-invalid.s | 2 +- test/MC/Mips/mips3/valid-xfail.s | 4 + test/MC/Mips/mips3/valid.s | 4 - test/MC/Mips/mips32r2/valid-xfail.s | 16 +- test/MC/Mips/mips32r2/valid.s | 14 - test/MC/Mips/mips4/valid-xfail.s | 4 + test/MC/Mips/mips4/valid.s | 4 - test/MC/Mips/mips5/valid-xfail.s | 4 + test/MC/Mips/mips5/valid.s | 4 - test/MC/Mips/mips64/valid-xfail.s | 4 + test/MC/Mips/mips64/valid.s | 4 - test/MC/Mips/mips64r2/valid-xfail.s | 17 + test/MC/Mips/mips64r2/valid.s | 16 - test/MC/Mips/set-at-directive-explicit-at.s | 8 +- 23 files changed, 1071 insertions(+), 930 deletions(-) delete mode 100644 test/MC/Mips/cfi.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 95e7d09ce0c..2b80d3f03de 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -23,7 +23,6 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" @@ -58,6 +57,7 @@ private: namespace { class MipsAsmParser : public MCTargetAsmParser { + MipsTargetStreamer &getTargetStreamer() { MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); return static_cast(TS); @@ -66,6 +66,7 @@ class MipsAsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI; MCAsmParser &Parser; MipsAssemblerOptions Options; + bool hasConsumedDollar; #define GET_ASSEMBLER_HEADER #include "MipsGenAsmMatcher.inc" @@ -75,15 +76,8 @@ class MipsAsmParser : public MCTargetAsmParser { MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm); - /// Parse a register as used in CFI directives bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); - bool ParseParenSuffix(StringRef Name, - SmallVectorImpl &Operands); - - bool ParseBracketSuffix(StringRef Name, - SmallVectorImpl &Operands); - bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, SmallVectorImpl &Operands); @@ -91,36 +85,95 @@ class MipsAsmParser : public MCTargetAsmParser { bool ParseDirective(AsmToken DirectiveID); MipsAsmParser::OperandMatchResultTy + parseRegs(SmallVectorImpl &Operands, int RegKind); + + MipsAsmParser::OperandMatchResultTy + parseMSARegs(SmallVectorImpl &Operands, int RegKind); + + MipsAsmParser::OperandMatchResultTy + parseMSACtrlRegs(SmallVectorImpl &Operands, + int RegKind); + + MipsAsmParser::OperandMatchResultTy parseMemOperand(SmallVectorImpl &Operands); - MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar( - SmallVectorImpl &Operands, StringRef Identifier, - SMLoc S); + bool parsePtrReg(SmallVectorImpl &Operands, + int RegKind); + + MipsAsmParser::OperandMatchResultTy + parsePtrReg(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseGPR32(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseGPR64(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseHWRegs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseCCRRegs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseAFGR64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGR32Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFGRH32Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseFCCRegs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseACC64DSP(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseLO32DSP(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseHI32DSP(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseCOP2(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseMSA128BRegs(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy - ParseAnyRegisterWithoutDollar(SmallVectorImpl &Operands, - SMLoc S); + parseMSA128HRegs(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy - ParseAnyRegister(SmallVectorImpl &Operands); + parseMSA128WRegs(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy - ParseImm(SmallVectorImpl &Operands); + parseMSA128DRegs(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy - ParseJumpTarget(SmallVectorImpl &Operands); + parseMSA128CtrlRegs(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy parseInvNum(SmallVectorImpl &Operands); MipsAsmParser::OperandMatchResultTy - ParseLSAImm(SmallVectorImpl &Operands); + parseLSAImm(SmallVectorImpl &Operands); - bool searchSymbolAlias(SmallVectorImpl &Operands); + bool searchSymbolAlias(SmallVectorImpl &Operands, + unsigned RegKind); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); + int tryParseRegister(bool is64BitReg); + + bool tryParseRegisterOperand(SmallVectorImpl &Operands, + bool is64BitReg); + bool needsExpansion(MCInst &Inst); void expandInstruction(MCInst &Inst, SMLoc IDLoc, @@ -182,6 +235,8 @@ class MipsAsmParser : public MCTargetAsmParser { bool eatComma(StringRef ErrorStr); + int matchRegisterName(StringRef Symbol, bool is64BitReg); + int matchCPURegisterName(StringRef Symbol); int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); @@ -196,12 +251,17 @@ class MipsAsmParser : public MCTargetAsmParser { int matchMSA128CtrlRegisterName(StringRef Name); + int regKindToRegClass(int RegKind); + unsigned getReg(int RC, int RegNo); unsigned getGPR(int RegNo); int getATReg(); + // Warn if RegNo is the current assembler temporary. + void warnIfAssemblerTemporary(int RegNo); + bool processInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -227,7 +287,8 @@ class MipsAsmParser : public MCTargetAsmParser { public: MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII) - : MCTargetAsmParser(), STI(sti), Parser(parser) { + : MCTargetAsmParser(), STI(sti), Parser(parser), + hasConsumedDollar(false) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); @@ -240,9 +301,6 @@ public: MCAsmParser &getParser() const { return Parser; } MCAsmLexer &getLexer() const { return Parser.getLexer(); } - - /// Warn if RegNo is the current assembler temporary. - void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc); }; } @@ -251,56 +309,53 @@ namespace { /// MipsOperand - Instances of this class represent a parsed Mips machine /// instruction. class MipsOperand : public MCParsedAsmOperand { + public: - /// Broad categories of register classes - /// The exact class is finalized by the render method. - enum RegKind { - RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64()) - RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and - /// isFP64()) - RegKind_FCC = 4, /// FCC - RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) - RegKind_MSACtrl = 16, /// MSA control registers - RegKind_COP2 = 32, /// COP2 - RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on - /// context). - RegKind_CCR = 128, /// CCR - RegKind_HWRegs = 256, /// HWRegs - - /// Potentially any (e.g. $1) - RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | - RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | - RegKind_CCR | RegKind_HWRegs + enum RegisterKind { + Kind_None, + Kind_GPR32, + Kind_GPR64, + Kind_HWRegs, + Kind_FGR32Regs, + Kind_FGRH32Regs, + Kind_FGR64Regs, + Kind_AFGR64Regs, + Kind_CCRRegs, + Kind_FCCRegs, + Kind_ACC64DSP, + Kind_LO32DSP, + Kind_HI32DSP, + Kind_COP2, + Kind_MSA128BRegs, + Kind_MSA128HRegs, + Kind_MSA128WRegs, + Kind_MSA128DRegs, + Kind_MSA128CtrlRegs }; private: enum KindTy { + k_CondCode, + k_CoprocNum, k_Immediate, k_Memory, - k_PhysRegister, - k_RegisterIndex, - k_Token + k_PostIndexRegister, + k_Register, + k_PtrReg, + k_Token, + k_LSAImm } Kind; - MipsOperand(KindTy K, MipsAsmParser &Parser) - : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} - - /// For diagnostics, and checking the assembler temporary - MipsAsmParser &AsmParser; + MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} struct Token { const char *Data; unsigned Length; }; - struct PhysRegOp { - unsigned Num; /// Register Number - }; - - struct RegIdxOp { - unsigned Index; /// Index into the register class - RegKind Kind; /// Bitfield of the kinds it could possibly be - const MCRegisterInfo *RegInfo; + struct RegOp { + unsigned RegNum; + RegisterKind Kind; }; struct ImmOp { @@ -308,161 +363,30 @@ private: }; struct MemOp { - MipsOperand *Base; + unsigned Base; const MCExpr *Off; }; union { struct Token Tok; - struct PhysRegOp PhysReg; - struct RegIdxOp RegIdx; + struct RegOp Reg; struct ImmOp Imm; struct MemOp Mem; }; SMLoc StartLoc, EndLoc; - /// Internal constructor for register kinds - static MipsOperand *CreateReg(unsigned Index, RegKind RegKind, - const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, - MipsAsmParser &Parser) { - MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser); - Op->RegIdx.Index = Index; - Op->RegIdx.RegInfo = RegInfo; - Op->RegIdx.Kind = RegKind; - Op->StartLoc = S; - Op->EndLoc = E; - return Op; - } - public: - /// Coerce the register to GPR32 and return the real register for the current - /// target. - unsigned getGPR32Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); - AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc); - unsigned ClassID = Mips::GPR32RegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to GPR64 and return the real register for the current - /// target. - unsigned getGPR64Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); - unsigned ClassID = Mips::GPR64RegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + void addRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getReg())); } -private: - /// Coerce the register to AFGR64 and return the real register for the current - /// target. - unsigned getAFGR64Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); - if (RegIdx.Index % 2 != 0) - AsmParser.Warning(StartLoc, "Float register should be even."); - return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) - .getRegister(RegIdx.Index / 2); - } - - /// Coerce the register to FGR64 and return the real register for the current - /// target. - unsigned getFGR64Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); - return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) - .getRegister(RegIdx.Index); - } - - /// Coerce the register to FGR32 and return the real register for the current - /// target. - unsigned getFGR32Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); - return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) - .getRegister(RegIdx.Index); - } - - /// Coerce the register to FGRH32 and return the real register for the current - /// target. - unsigned getFGRH32Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); - return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) - .getRegister(RegIdx.Index); - } - - /// Coerce the register to FCC and return the real register for the current - /// target. - unsigned getFCCReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); - return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) - .getRegister(RegIdx.Index); - } - - /// Coerce the register to MSA128 and return the real register for the current - /// target. - unsigned getMSA128Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); - // It doesn't matter which of the MSA128[BHWD] classes we use. They are all - // identical - unsigned ClassID = Mips::MSA128BRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to MSACtrl and return the real register for the - /// current target. - unsigned getMSACtrlReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); - unsigned ClassID = Mips::MSACtrlRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to COP2 and return the real register for the - /// current target. - unsigned getCOP2Reg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); - unsigned ClassID = Mips::COP2RegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to ACC64DSP and return the real register for the - /// current target. - unsigned getACC64DSPReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); - unsigned ClassID = Mips::ACC64DSPRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to HI32DSP and return the real register for the - /// current target. - unsigned getHI32DSPReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); - unsigned ClassID = Mips::HI32DSPRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to LO32DSP and return the real register for the - /// current target. - unsigned getLO32DSPReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); - unsigned ClassID = Mips::LO32DSPRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to CCR and return the real register for the - /// current target. - unsigned getCCRReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); - unsigned ClassID = Mips::CCRRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); - } - - /// Coerce the register to HWRegs and return the real register for the - /// current target. - unsigned getHWRegsReg() const { - assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); - unsigned ClassID = Mips::HWRegsRegClassID; - return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + void addPtrRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getPtrReg())); } -public: void addExpr(MCInst &Inst, const MCExpr *Expr) const { // Add as immediate when possible. Null MCExpr = 0. if (Expr == 0) @@ -473,85 +397,6 @@ public: Inst.addOperand(MCOperand::CreateExpr(Expr)); } - void addRegOperands(MCInst &Inst, unsigned N) const { - llvm_unreachable("Use a custom parser instead"); - } - - void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); - } - - void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); - } - - void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); - } - - void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); - } - - void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); - } - - void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); - } - - void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getFCCReg())); - } - - void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); - } - - void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); - } - - void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); - } - - void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); - } - - void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); - } - - void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); - } - - void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getCCRReg())); - } - - void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); - } - void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCExpr *Expr = getImm(); @@ -561,38 +406,19 @@ public: void addMemOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); + Inst.addOperand(MCOperand::CreateReg(getMemBase())); const MCExpr *Expr = getMemOff(); addExpr(Inst, Expr); } - bool isReg() const { - // As a special case until we sort out the definition of div/divu, pretend - // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. - if (isGPRAsmReg() && RegIdx.Index == 0) - return true; - - return Kind == k_PhysRegister; - } - bool isRegIdx() const { return Kind == k_RegisterIndex; } + bool isReg() const { return Kind == k_Register; } bool isImm() const { return Kind == k_Immediate; } - bool isConstantImm() const { - return isImm() && dyn_cast(getImm()); - } - bool isToken() const { - // Note: It's not possible to pretend that other operand kinds are tokens. - // The matcher emitter checks tokens first. - return Kind == k_Token; - } + bool isToken() const { return Kind == k_Token; } bool isMem() const { return Kind == k_Memory; } + bool isPtrReg() const { return Kind == k_PtrReg; } bool isInvNum() const { return Kind == k_Immediate; } - bool isLSAImm() const { - if (!isConstantImm()) - return false; - int64_t Val = getConstantImm(); - return 1 <= Val && Val <= 4; - } + bool isLSAImm() const { return Kind == k_LSAImm; } StringRef getToken() const { assert(Kind == k_Token && "Invalid access!"); @@ -600,27 +426,26 @@ public: } unsigned getReg() const { - // As a special case until we sort out the definition of div/divu, pretend - // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. - if (Kind == k_RegisterIndex && RegIdx.Index == 0 && - RegIdx.Kind & RegKind_GPR) - return getGPR32Reg(); // FIXME: GPR64 too + assert((Kind == k_Register) && "Invalid access!"); + return Reg.RegNum; + } - assert(Kind == k_PhysRegister && "Invalid access!"); - return PhysReg.Num; + unsigned getPtrReg() const { + assert((Kind == k_PtrReg) && "Invalid access!"); + return Reg.RegNum; } - const MCExpr *getImm() const { - assert((Kind == k_Immediate) && "Invalid access!"); - return Imm.Val; + void setRegKind(RegisterKind RegKind) { + assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!"); + Reg.Kind = RegKind; } - int64_t getConstantImm() const { - const MCExpr *Val = getImm(); - return static_cast(Val)->getValue(); + const MCExpr *getImm() const { + assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!"); + return Imm.Val; } - MipsOperand *getMemBase() const { + unsigned getMemBase() const { assert((Kind == k_Memory) && "Invalid access!"); return Mem.Base; } @@ -630,9 +455,8 @@ public: return Mem.Off; } - static MipsOperand *CreateToken(StringRef Str, SMLoc S, - MipsAsmParser &Parser) { - MipsOperand *Op = new MipsOperand(k_Token, Parser); + static MipsOperand *CreateToken(StringRef Str, SMLoc S) { + MipsOperand *Op = new MipsOperand(k_Token); Op->Tok.Data = Str.data(); Op->Tok.Length = Str.size(); Op->StartLoc = S; @@ -640,75 +464,43 @@ public: return Op; } - /// Create a numeric register (e.g. $1). The exact register remains - /// unresolved until an instruction successfully matches - static MipsOperand *CreateNumericReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n"); - return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); - } - - /// Create a register that is definitely a GPR. - /// This is typically only used for named registers such as $gp. - static MipsOperand *CreateGPRReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); - } - - /// Create a register that is definitely a FGR. - /// This is typically only used for named registers such as $f0. - static MipsOperand *CreateFGRReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); - } - - /// Create a register that is definitely an FCC. - /// This is typically only used for named registers such as $fcc0. - static MipsOperand *CreateFCCReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); - } - - /// Create a register that is definitely an ACC. - /// This is typically only used for named registers such as $ac0. - static MipsOperand *CreateACCReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); + static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_Register); + Op->Reg.RegNum = RegNum; + Op->Reg.Kind = Kind_None; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; } - /// Create a register that is definitely an MSA128. - /// This is typically only used for named registers such as $w0. - static MipsOperand *CreateMSA128Reg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); + static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_PtrReg); + Op->Reg.RegNum = RegNum; + Op->Reg.Kind = Kind_None; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; } - /// Create a register that is definitely an MSACtrl. - /// This is typically only used for named registers such as $msaaccess. - static MipsOperand *CreateMSACtrlReg(unsigned Index, - const MCRegisterInfo *RegInfo, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); + static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_Immediate); + Op->Imm.Val = Val; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; } - static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, - MipsAsmParser &Parser) { - MipsOperand *Op = new MipsOperand(k_Immediate, Parser); + static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) { + MipsOperand *Op = new MipsOperand(k_LSAImm); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; return Op; } - static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S, - SMLoc E, MipsAsmParser &Parser) { - MipsOperand *Op = new MipsOperand(k_Memory, Parser); + static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, + SMLoc E) { + MipsOperand *Op = new MipsOperand(k_Memory); Op->Mem.Base = Base; Op->Mem.Off = Off; Op->StartLoc = S; @@ -716,33 +508,79 @@ public: return Op; } - bool isGPRAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; + bool isGPR32Asm() const { + return Kind == k_Register && Reg.Kind == Kind_GPR32; + } + void addRegAsmOperands(MCInst &Inst, unsigned N) const { + Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); + } + + bool isGPR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_GPR64; + } + + bool isHWRegsAsm() const { + assert((Kind == k_Register) && "Invalid access!"); + return Reg.Kind == Kind_HWRegs; + } + + bool isCCRAsm() const { + assert((Kind == k_Register) && "Invalid access!"); + return Reg.Kind == Kind_CCRRegs; + } + + bool isAFGR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; + } + + bool isFGR64Asm() const { + return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; + } + + bool isFGR32Asm() const { + return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; + } + + bool isFGRH32Asm() const { + return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs; + } + + bool isFCCRegsAsm() const { + return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; } - bool isFGRAsmReg() const { - // AFGR64 is $0-$15 but we handle this in getAFGR64() - return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; + + bool isACC64DSPAsm() const { + return Kind == k_Register && Reg.Kind == Kind_ACC64DSP; } - bool isHWRegsAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; + + bool isLO32DSPAsm() const { + return Kind == k_Register && Reg.Kind == Kind_LO32DSP; } - bool isCCRAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; + + bool isHI32DSPAsm() const { + return Kind == k_Register && Reg.Kind == Kind_HI32DSP; } - bool isFCCAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7; + + bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; } + + bool isMSA128BAsm() const { + return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs; } - bool isACCAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; + + bool isMSA128HAsm() const { + return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs; } - bool isCOP2AsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; + + bool isMSA128WAsm() const { + return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs; } - bool isMSA128AsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; + + bool isMSA128DAsm() const { + return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs; } - bool isMSACtrlAsmReg() const { - return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; + + bool isMSA128CRAsm() const { + return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs; } /// getStartLoc - Get the location of the first token of this operand. @@ -751,29 +589,7 @@ public: SMLoc getEndLoc() const { return EndLoc; } virtual void print(raw_ostream &OS) const { - switch (Kind) { - case k_Immediate: - OS << "Imm<"; - Imm.Val->print(OS); - OS << ">"; - break; - case k_Memory: - OS << "Mem<"; - Mem.Base->print(OS); - OS << ", "; - Mem.Off->print(OS); - OS << ">"; - break; - case k_PhysRegister: - OS << "PhysReg<" << PhysReg.Num << ">"; - break; - case k_RegisterIndex: - OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; - break; - case k_Token: - OS << Tok.Data; - break; - } + llvm_unreachable("unimplemented!"); } }; // class MipsOperand } // namespace @@ -800,8 +616,6 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, break; case Mips::BEQ: case Mips::BNE: - case Mips::BEQ_MM: - case Mips::BNE_MM: assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); Offset = Inst.getOperand(2); if (!Offset.isImm()) @@ -819,14 +633,6 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case Mips::BLTZAL: case Mips::BC1F: case Mips::BC1T: - case Mips::BGEZ_MM: - case Mips::BGTZ_MM: - case Mips::BLEZ_MM: - case Mips::BLTZ_MM: - case Mips::BGEZAL_MM: - case Mips::BLTZAL_MM: - case Mips::BC1F_MM: - case Mips::BC1T_MM: assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); Offset = Inst.getOperand(1); if (!Offset.isImm()) @@ -1190,13 +996,14 @@ bool MipsAsmParser::MatchAndEmitInstruction( return true; } -void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { - if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) { - if (RegIndex == 1) - Warning(Loc, "Used $at without \".set noat\""); +void MipsAsmParser::warnIfAssemblerTemporary(int RegNo) { + if ((RegNo != 0) && ((int)Options.getATRegNum() == RegNo)) { + if (RegNo == 1) + Warning(getLexer().getLoc(), "Used $at without \".set noat\""); else - Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" + - Twine(RegIndex) + "\""); + Warning(getLexer().getLoc(), Twine("Used $") + Twine(RegNo) + + " with \".set at=$" + Twine(RegNo) + + "\""); } } @@ -1257,6 +1064,8 @@ int MipsAsmParser::matchCPURegisterName(StringRef Name) { .Default(-1); } + warnIfAssemblerTemporary(CC); + return CC; } @@ -1331,6 +1140,59 @@ int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { return CC; } +int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { + + int CC; + CC = matchCPURegisterName(Name); + if (CC != -1) + return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); + CC = matchFPURegisterName(Name); + // TODO: decide about fpu register class + if (CC != -1) + return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID + : Mips::FGR32RegClassID); + return matchMSA128RegisterName(Name); +} + +int MipsAsmParser::regKindToRegClass(int RegKind) { + + switch (RegKind) { + case MipsOperand::Kind_GPR32: + return Mips::GPR32RegClassID; + case MipsOperand::Kind_GPR64: + return Mips::GPR64RegClassID; + case MipsOperand::Kind_HWRegs: + return Mips::HWRegsRegClassID; + case MipsOperand::Kind_FGR32Regs: + return Mips::FGR32RegClassID; + case MipsOperand::Kind_FGRH32Regs: + return Mips::FGRH32RegClassID; + case MipsOperand::Kind_FGR64Regs: + return Mips::FGR64RegClassID; + case MipsOperand::Kind_AFGR64Regs: + return Mips::AFGR64RegClassID; + case MipsOperand::Kind_CCRRegs: + return Mips::CCRRegClassID; + case MipsOperand::Kind_ACC64DSP: + return Mips::ACC64DSPRegClassID; + case MipsOperand::Kind_FCCRegs: + return Mips::FCCRegClassID; + case MipsOperand::Kind_MSA128BRegs: + return Mips::MSA128BRegClassID; + case MipsOperand::Kind_MSA128HRegs: + return Mips::MSA128HRegClassID; + case MipsOperand::Kind_MSA128WRegs: + return Mips::MSA128WRegClassID; + case MipsOperand::Kind_MSA128DRegs: + return Mips::MSA128DRegClassID; + case MipsOperand::Kind_MSA128CtrlRegs: + return Mips::MSACtrlRegClassID; + default: + return -1; + } +} + bool MipsAssemblerOptions::setATReg(unsigned Reg) { if (Reg > 31) return false; @@ -1360,14 +1222,45 @@ int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) return -1; + if (RegClass == Mips::GPR32RegClassID || RegClass == Mips::GPR64RegClassID) + warnIfAssemblerTemporary(RegNum); + return getReg(RegClass, RegNum); } +int MipsAsmParser::tryParseRegister(bool is64BitReg) { + const AsmToken &Tok = Parser.getTok(); + int RegNum = -1; + + if (Tok.is(AsmToken::Identifier)) { + std::string lowerCase = Tok.getString().lower(); + RegNum = matchRegisterName(lowerCase, is64BitReg); + } else if (Tok.is(AsmToken::Integer)) + RegNum = matchRegisterByNumber(static_cast(Tok.getIntVal()), + is64BitReg ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); + return RegNum; +} + +bool MipsAsmParser::tryParseRegisterOperand( + SmallVectorImpl &Operands, bool is64BitReg) { + + SMLoc S = Parser.getTok().getLoc(); + int RegNo = -1; + + RegNo = tryParseRegister(is64BitReg); + if (RegNo == -1) + return true; + + Operands.push_back( + MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); + Parser.Lex(); // Eat register token. + return false; +} + bool MipsAsmParser::ParseOperand(SmallVectorImpl &Operands, StringRef Mnemonic) { - DEBUG(dbgs() << "ParseOperand\n"); - // Check if the current operand has a custom associated parser, if so, try to // custom parse the operand, or fallback to the general approach. OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); @@ -1379,8 +1272,6 @@ MipsAsmParser::ParseOperand(SmallVectorImpl &Operands, if (ResTy == MatchOperand_ParseFail) return true; - DEBUG(dbgs() << ".. Generic Parser\n"); - switch (getLexer().getKind()) { default: Error(Parser.getTok().getLoc(), "unexpected token in operand"); @@ -1388,15 +1279,29 @@ MipsAsmParser::ParseOperand(SmallVectorImpl &Operands, case AsmToken::Dollar: { // Parse the register. SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat dollar token. + // Parse the register operand. + if (!tryParseRegisterOperand(Operands, isGP64())) { + if (getLexer().is(AsmToken::LParen)) { + // Check if it is indexed addressing operand. + Operands.push_back(MipsOperand::CreateToken("(", S)); + Parser.Lex(); // Eat the parenthesis. + if (getLexer().isNot(AsmToken::Dollar)) + return true; - // Almost all registers have been parsed by custom parsers. There is only - // one exception to this. $zero (and it's alias $0) will reach this point - // for div, divu, and similar instructions because it is not an operand - // to the instruction definition but an explicit register. Special case - // this situation for now. - if (ParseAnyRegister(Operands) != MatchOperand_NoMatch) - return false; + Parser.Lex(); // Eat the dollar + if (tryParseRegisterOperand(Operands, isGP64())) + return true; + + if (!getLexer().is(AsmToken::RParen)) + return true; + S = Parser.getTok().getLoc(); + Operands.push_back(MipsOperand::CreateToken(")", S)); + Parser.Lex(); + } + return false; + } // Maybe it is a symbol reference. StringRef Identifier; if (Parser.parseIdentifier(Identifier)) @@ -1408,18 +1313,47 @@ MipsAsmParser::ParseOperand(SmallVectorImpl &Operands, const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); - Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); + Operands.push_back(MipsOperand::CreateImm(Res, S, E)); return false; } + case AsmToken::Identifier: + // For instruction aliases like "bc1f $Label" dedicated parser will + // eat the '$' sign before failing. So in order to look for appropriate + // label we must check first if we have already consumed '$'. + if (hasConsumedDollar) { + hasConsumedDollar = false; + SMLoc S = Parser.getTok().getLoc(); + StringRef Identifier; + if (Parser.parseIdentifier(Identifier)) + return true; + SMLoc E = + SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); + // Create a symbol reference. + const MCExpr *Res = + MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); + + Operands.push_back(MipsOperand::CreateImm(Res, S, E)); + return false; + } + // Look for the existing symbol, we should check if + // we need to assign the proper RegisterKind. + if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) + return false; // Else drop to expression parsing. case AsmToken::LParen: case AsmToken::Minus: case AsmToken::Plus: case AsmToken::Integer: case AsmToken::String: { - DEBUG(dbgs() << ".. generic integer\n"); - OperandMatchResultTy ResTy = ParseImm(Operands); - return ResTy != MatchOperand_Success; + // Quoted label names. + const MCExpr *IdVal; + SMLoc S = Parser.getTok().getLoc(); + if (getParser().parseExpression(IdVal)) + return true; + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); + return false; } case AsmToken::Percent: { // It is a symbol reference or constant expression. @@ -1430,7 +1364,7 @@ MipsAsmParser::ParseOperand(SmallVectorImpl &Operands, SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); return false; } // case AsmToken::Percent } // switch(getLexer().getKind()) @@ -1562,27 +1496,9 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { - SmallVector Operands; - OperandMatchResultTy ResTy = ParseAnyRegister(Operands); - if (ResTy == MatchOperand_Success) { - assert(Operands.size() == 1); - MipsOperand &Operand = *static_cast(Operands.front()); - StartLoc = Operand.getStartLoc(); - EndLoc = Operand.getEndLoc(); - - // AFAIK, we only support numeric registers and named GPR's in CFI - // directives. - // Don't worry about eating tokens before failing. Using an unrecognised - // register is a parse error. - if (Operand.isGPRAsmReg()) { - // Resolve to GPR32 or GPR64 appropriately. - RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); - } - - return (RegNo == (unsigned)-1); - } - - assert(Operands.size() == 0); + StartLoc = Parser.getTok().getLoc(); + RegNo = tryParseRegister(isGP64()); + EndLoc = Parser.getTok().getLoc(); return (RegNo == (unsigned)-1); } @@ -1616,7 +1532,7 @@ bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( SmallVectorImpl &Operands) { - DEBUG(dbgs() << "parseMemOperand\n"); + const MCExpr *IdVal = 0; SMLoc S; bool isParenExpr = false; @@ -1639,7 +1555,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( if (Mnemonic->getToken() == "la") { SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); return MatchOperand_Success; } if (Tok.is(AsmToken::EndOfStatement)) { @@ -1647,9 +1563,8 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); // Zero register assumed, add a memory operand with ZERO as its base. - MipsOperand *Base = MipsOperand::CreateGPRReg( - 0, getContext().getRegisterInfo(), S, E, *this); - Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateMem( + isGP64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E)); return MatchOperand_Success; } Error(Parser.getTok().getLoc(), "'(' expected"); @@ -1659,7 +1574,8 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( Parser.Lex(); // Eat the '(' token. } - Res = ParseAnyRegister(Operands); + Res = parseRegs(Operands, isGP64() ? (int)MipsOperand::Kind_GPR64 + : (int)MipsOperand::Kind_GPR32); if (Res != MatchOperand_Success) return Res; @@ -1677,6 +1593,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( // Replace the register operand with the memory operand. MipsOperand *op = static_cast(Operands.back()); + int RegNo = op->getReg(); // Remove the register from the operands. Operands.pop_back(); // Add the memory operand. @@ -1689,220 +1606,599 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( getContext()); } - Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this)); + Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); + delete op; return MatchOperand_Success; } -bool MipsAsmParser::searchSymbolAlias( - SmallVectorImpl &Operands) { +bool MipsAsmParser::parsePtrReg(SmallVectorImpl &Operands, + int RegKind) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return false; - MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); - if (Sym) { - SMLoc S = Parser.getTok().getLoc(); - const MCExpr *Expr; - if (Sym->isVariable()) - Expr = Sym->getVariableValue(); - else + 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; - if (Expr->getKind() == MCExpr::SymbolRef) { - const MCSymbolRefExpr *Ref = static_cast(Expr); - const StringRef DefSymbol = Ref->getSymbol().getName(); - if (DefSymbol.startswith("$")) { - OperandMatchResultTy ResTy = - MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); - if (ResTy == MatchOperand_Success) - return true; - else if (ResTy == MatchOperand_ParseFail) - llvm_unreachable("Should never ParseFail"); - return false; - } - } else if (Expr->getKind() == MCExpr::Constant) { - Parser.Lex(); - const MCConstantExpr *Const = static_cast(Expr); - MipsOperand *op = - MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this); - Operands.push_back(op); - return true; - } + } else if (TkKind == AsmToken::Identifier) { + if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) + return false; + Reg = getReg(regKindToRegClass(RegKind), Reg); + } else { + return false; } - 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::MatchAnyRegisterNameWithoutDollar( - SmallVectorImpl &Operands, StringRef Identifier, - SMLoc S) { - int Index = matchCPURegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateGPRReg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); - return MatchOperand_Success; - } +MipsAsmParser::parsePtrReg(SmallVectorImpl &Operands) { + MipsOperand::RegisterKind RegKind = + isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32; - Index = matchFPURegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateFGRReg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); + // 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 &Operands, + int RegKind) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; + if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) { + if (searchSymbolAlias(Operands, Kind)) + return MatchOperand_Success; + return MatchOperand_NoMatch; + } + SMLoc S = Parser.getTok().getLoc(); + // If the first token is not '$', we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar) + return MatchOperand_NoMatch; + if (!hasConsumedDollar) { + Parser.Lex(); // Eat the '$' + hasConsumedDollar = true; + } + if (getLexer().getKind() == AsmToken::Identifier) { + int RegNum = -1; + std::string RegName = Parser.getTok().getString().lower(); + // Match register by name + switch (RegKind) { + case MipsOperand::Kind_GPR32: + case MipsOperand::Kind_GPR64: + RegNum = matchCPURegisterName(RegName); + break; + case MipsOperand::Kind_AFGR64Regs: + case MipsOperand::Kind_FGR64Regs: + case MipsOperand::Kind_FGR32Regs: + case MipsOperand::Kind_FGRH32Regs: + RegNum = matchFPURegisterName(RegName); + if (RegKind == MipsOperand::Kind_AFGR64Regs) + RegNum /= 2; + else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64()) + if (RegNum != -1 && RegNum % 2 != 0) + Warning(S, "Float register should be even."); + break; + case MipsOperand::Kind_FCCRegs: + RegNum = matchFCCRegisterName(RegName); + break; + case MipsOperand::Kind_ACC64DSP: + RegNum = matchACRegisterName(RegName); + break; + default: + break; // No match, value is set to -1. + } + // No match found, return _NoMatch to give a chance to other round. + if (RegNum < 0) + return MatchOperand_NoMatch; + + int RegVal = getReg(regKindToRegClass(Kind), RegNum); + if (RegVal == -1) + return MatchOperand_NoMatch; + + MipsOperand *Op = + MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); + Op->setRegKind(Kind); + Operands.push_back(Op); + hasConsumedDollar = false; + Parser.Lex(); // Eat the register name. + return MatchOperand_Success; + } else if (getLexer().getKind() == AsmToken::Integer) { + unsigned RegNum = Parser.getTok().getIntVal(); + if (Kind == MipsOperand::Kind_HWRegs) { + if (RegNum != 29) + return MatchOperand_NoMatch; + // Only hwreg 29 is supported, found at index 0. + RegNum = 0; + } + int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind)); + if (Reg == -1) + return MatchOperand_NoMatch; + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(Kind); + Operands.push_back(Op); + hasConsumedDollar = false; + Parser.Lex(); // Eat the register number. + if ((RegKind == MipsOperand::Kind_GPR32) && + (getLexer().is(AsmToken::LParen))) { + // Check if it is indexed addressing operand. + Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); + Parser.Lex(); // Eat the parenthesis. + if (parseRegs(Operands, RegKind) != MatchOperand_Success) + return MatchOperand_NoMatch; + if (getLexer().isNot(AsmToken::RParen)) + return MatchOperand_NoMatch; + Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); + Parser.Lex(); + } return MatchOperand_Success; } + return MatchOperand_NoMatch; +} - Index = matchFCCRegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateFCCReg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); - return MatchOperand_Success; +bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; + + if (Val < 0) + return false; + + switch (Kind) { + default: + return false; + case MipsOperand::Kind_MSA128BRegs: + return Val < 16; + case MipsOperand::Kind_MSA128HRegs: + return Val < 8; + case MipsOperand::Kind_MSA128WRegs: + return Val < 4; + case MipsOperand::Kind_MSA128DRegs: + return Val < 2; } +} - Index = matchACRegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateACCReg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); - return MatchOperand_Success; +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseMSARegs(SmallVectorImpl &Operands, + int RegKind) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; + SMLoc S = Parser.getTok().getLoc(); + std::string RegName; + + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + + switch (RegKind) { + default: + return MatchOperand_ParseFail; + case MipsOperand::Kind_MSA128BRegs: + case MipsOperand::Kind_MSA128HRegs: + case MipsOperand::Kind_MSA128WRegs: + case MipsOperand::Kind_MSA128DRegs: + break; } - Index = matchMSA128RegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateMSA128Reg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); + Parser.Lex(); // Eat the '$'. + if (getLexer().getKind() == AsmToken::Identifier) + RegName = Parser.getTok().getString().lower(); + else + return MatchOperand_ParseFail; + + int RegNum = matchMSA128RegisterName(RegName); + + if (RegNum < 0 || RegNum > 31) + return MatchOperand_ParseFail; + + int RegVal = getReg(regKindToRegClass(Kind), RegNum); + if (RegVal == -1) + return MatchOperand_ParseFail; + + MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); + Op->setRegKind(Kind); + Operands.push_back(Op); + + Parser.Lex(); // Eat the register identifier. + + // MSA registers may be suffixed with an index in the form of: + // 1) Immediate expression. + // 2) General Purpose Register. + // Examples: + // 1) copy_s.b $29,$w0[0] + // 2) sld.b $w0,$w1[$1] + + if (Parser.getTok().isNot(AsmToken::LBrac)) return MatchOperand_Success; - } - Index = matchMSA128CtrlRegisterName(Identifier); - if (Index != -1) { - Parser.Lex(); - Operands.push_back(MipsOperand::CreateMSACtrlReg( - Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); + MipsOperand *Mnemonic = static_cast(Operands[0]); + + Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc())); + Parser.Lex(); // Parse the '[' token. + + if (Parser.getTok().is(AsmToken::Dollar)) { + // This must be a GPR. + MipsOperand *RegOp; + SMLoc VIdx = Parser.getTok().getLoc(); + Parser.Lex(); // Parse the '$' token. + + // GPR have aliases and we must account for that. Example: $30 == $fp + if (getLexer().getKind() == AsmToken::Integer) { + unsigned RegNum = Parser.getTok().getIntVal(); + int Reg = matchRegisterByNumber( + RegNum, regKindToRegClass(MipsOperand::Kind_GPR32)); + if (Reg == -1) { + Error(VIdx, "invalid general purpose register"); + return MatchOperand_ParseFail; + } + + RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc()); + } else if (getLexer().getKind() == AsmToken::Identifier) { + int RegNum = -1; + std::string RegName = Parser.getTok().getString().lower(); + + RegNum = matchCPURegisterName(RegName); + if (RegNum == -1) { + Error(VIdx, "general purpose register expected"); + return MatchOperand_ParseFail; + } + RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum); + RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc()); + } else + return MatchOperand_ParseFail; + + RegOp->setRegKind(MipsOperand::Kind_GPR32); + Operands.push_back(RegOp); + Parser.Lex(); // Eat the register identifier. + + if (Parser.getTok().isNot(AsmToken::RBrac)) + return MatchOperand_ParseFail; + + Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc())); + Parser.Lex(); // Parse the ']' token. + return MatchOperand_Success; } - return MatchOperand_NoMatch; + // The index must be a constant expression then. + SMLoc VIdx = Parser.getTok().getLoc(); + const MCExpr *ImmVal; + + if (getParser().parseExpression(ImmVal)) + return MatchOperand_ParseFail; + + const MCConstantExpr *expr = dyn_cast(ImmVal); + if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) { + Error(VIdx, "invalid immediate value"); + return MatchOperand_ParseFail; + } + + SMLoc E = Parser.getTok().getEndLoc(); + + if (Parser.getTok().isNot(AsmToken::RBrac)) + return MatchOperand_ParseFail; + + bool insve = + Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" || + Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d"; + + // The second vector index of insve instructions is always 0. + if (insve && Operands.size() > 6) { + if (expr->getValue() != 0) { + Error(VIdx, "immediate value must be 0"); + return MatchOperand_ParseFail; + } + Operands.push_back(MipsOperand::CreateToken("0", VIdx)); + } else + Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E)); + + Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc())); + + Parser.Lex(); // Parse the ']' token. + + return MatchOperand_Success; } MipsAsmParser::OperandMatchResultTy -MipsAsmParser::ParseAnyRegisterWithoutDollar( - SmallVectorImpl &Operands, SMLoc S) { - auto Token = Parser.getTok(); - - if (Token.is(AsmToken::Identifier)) { - DEBUG(dbgs() << ".. identifier\n"); - StringRef Identifier = Token.getIdentifier(); - return MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S); - } else if (Token.is(AsmToken::Integer)) { - DEBUG(dbgs() << ".. integer\n"); - Operands.push_back(MipsOperand::CreateNumericReg( - Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), - *this)); - Parser.Lex(); - return MatchOperand_Success; - } +MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl &Operands, + int RegKind) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; + + if (Kind != MipsOperand::Kind_MSA128CtrlRegs) + return MatchOperand_NoMatch; - DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_ParseFail; - return MatchOperand_NoMatch; + SMLoc S = Parser.getTok().getLoc(); + + Parser.Lex(); // Eat the '$' symbol. + + int RegNum = -1; + if (getLexer().getKind() == AsmToken::Identifier) + RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower()); + else if (getLexer().getKind() == AsmToken::Integer) + RegNum = Parser.getTok().getIntVal(); + else + return MatchOperand_ParseFail; + + if (RegNum < 0 || RegNum > 7) + return MatchOperand_ParseFail; + + int RegVal = getReg(regKindToRegClass(Kind), RegNum); + if (RegVal == -1) + return MatchOperand_ParseFail; + + MipsOperand *RegOp = + MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); + RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs); + Operands.push_back(RegOp); + Parser.Lex(); // Eat the register identifier. + + return MatchOperand_Success; } -MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister( - SmallVectorImpl &Operands) { - DEBUG(dbgs() << "ParseAnyRegister\n"); +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseGPR64(SmallVectorImpl &Operands) { + + if (!isGP64()) + return MatchOperand_NoMatch; + return parseRegs(Operands, (int)MipsOperand::Kind_GPR64); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseGPR32(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_GPR32); +} - auto Token = Parser.getTok(); +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs( + SmallVectorImpl &Operands) { - SMLoc S = Token.getLoc(); + if (isFP64()) + return MatchOperand_NoMatch; + return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs); +} - if (Token.isNot(AsmToken::Dollar)) { - DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); - if (Token.is(AsmToken::Identifier)) { - if (searchSymbolAlias(Operands)) - return MatchOperand_Success; - } - DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseFGR64Regs(SmallVectorImpl &Operands) { + if (!isFP64()) return MatchOperand_NoMatch; - } - DEBUG(dbgs() << ".. $\n"); - Parser.Lex(); - Token = Parser.getTok(); + return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseFGR32Regs(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs); +} - OperandMatchResultTy ResTy = ParseAnyRegisterWithoutDollar(Operands, S); - if (ResTy == MatchOperand_NoMatch) - return MatchOperand_ParseFail; // We ate the $ so NoMatch isn't valid - return ResTy; +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs( + SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs); } MipsAsmParser::OperandMatchResultTy -MipsAsmParser::ParseImm(SmallVectorImpl &Operands) { - switch (getLexer().getKind()) { - default: +MipsAsmParser::parseFCCRegs(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseACC64DSP(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseLO32DSP(SmallVectorImpl &Operands) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) return MatchOperand_NoMatch; - case AsmToken::LParen: - case AsmToken::Minus: - case AsmToken::Plus: - case AsmToken::Integer: - case AsmToken::String: - break; - } - const MCExpr *IdVal; SMLoc S = Parser.getTok().getLoc(); - if (getParser().parseExpression(IdVal)) - return MatchOperand_ParseFail; + Parser.Lex(); // Eat the '$' - SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); + const AsmToken &Tok = Parser.getTok(); // Get next token. + + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; + + if (!Tok.getIdentifier().startswith("ac")) + return MatchOperand_NoMatch; + + StringRef NumString = Tok.getIdentifier().substr(2); + + unsigned IntVal; + if (NumString.getAsInteger(10, IntVal)) + return MatchOperand_NoMatch; + + unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID); + + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_LO32DSP); + Operands.push_back(Op); + + Parser.Lex(); // Eat the register number. return MatchOperand_Success; } -MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget( - SmallVectorImpl &Operands) { - DEBUG(dbgs() << "ParseJumpTarget\n"); +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseHI32DSP(SmallVectorImpl &Operands) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; - SMLoc S = getLexer().getLoc(); + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the '$' - // Integers and expressions are acceptable - OperandMatchResultTy ResTy = ParseImm(Operands); - if (ResTy != MatchOperand_NoMatch) - return ResTy; + const AsmToken &Tok = Parser.getTok(); // Get next token. - // Consume the $ if there is one. We'll add it to the symbol below. - bool hasConsumedDollar = false; - if (getLexer().is(AsmToken::Dollar)) { - Parser.Lex(); - hasConsumedDollar = true; + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; - // We have an unfortunate conflict between '$sym' and '$reg' so give - // registers a chance before we try symbols. - // The conflict is between 'bc1t $offset', and 'bc1t $fcc, $offset'. - OperandMatchResultTy ResTy = ParseAnyRegisterWithoutDollar(Operands, S); - if (ResTy != MatchOperand_NoMatch) - return ResTy; - } + if (!Tok.getIdentifier().startswith("ac")) + return MatchOperand_NoMatch; - StringRef Identifier; - if (Parser.parseIdentifier(Identifier)) - return hasConsumedDollar ? MatchOperand_ParseFail : MatchOperand_NoMatch; + StringRef NumString = Tok.getIdentifier().substr(2); - if (hasConsumedDollar) - Identifier = StringRef("$" + Identifier.str()); + unsigned IntVal; + if (NumString.getAsInteger(10, IntVal)) + return MatchOperand_NoMatch; - SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); + unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID); - // Create a symbol reference. - const MCExpr *Res = - MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_HI32DSP); + Operands.push_back(Op); - Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); + Parser.Lex(); // Eat the register number. return MatchOperand_Success; - // // Look for the existing symbol, we should check if - // // we need to assign the proper RegisterKind. - // if (searchSymbolAlias(Operands)) - // return false; +} - return MatchOperand_NoMatch; +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseCOP2(SmallVectorImpl &Operands) { + // If the first token is not '$' we have an error. + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the '$' + + const AsmToken &Tok = Parser.getTok(); // Get next token. + + if (Tok.isNot(AsmToken::Integer)) + return MatchOperand_NoMatch; + + unsigned IntVal = Tok.getIntVal(); + + unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID); + + MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); + Op->setRegKind(MipsOperand::Kind_COP2); + Operands.push_back(Op); + + Parser.Lex(); // Eat the register number. + return MatchOperand_Success; +} + +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs( + SmallVectorImpl &Operands) { + return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs); +} + +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs( + SmallVectorImpl &Operands) { + return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs); +} + +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs( + SmallVectorImpl &Operands) { + return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs); +} + +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs( + SmallVectorImpl &Operands) { + return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs); +} + +MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs( + SmallVectorImpl &Operands) { + return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs); +} + +bool MipsAsmParser::searchSymbolAlias( + SmallVectorImpl &Operands, unsigned RegKind) { + + MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); + if (Sym) { + SMLoc S = Parser.getTok().getLoc(); + const MCExpr *Expr; + if (Sym->isVariable()) + Expr = Sym->getVariableValue(); + else + return false; + if (Expr->getKind() == MCExpr::SymbolRef) { + MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; + const MCSymbolRefExpr *Ref = static_cast(Expr); + const StringRef DefSymbol = Ref->getSymbol().getName(); + if (DefSymbol.startswith("$")) { + int RegNum = -1; + APInt IntVal(32, -1); + if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) + RegNum = matchRegisterByNumber(IntVal.getZExtValue(), + isGP64() ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID); + else { + // Lookup for the register with the corresponding name. + switch (Kind) { + case MipsOperand::Kind_AFGR64Regs: + case MipsOperand::Kind_FGR64Regs: + RegNum = matchFPURegisterName(DefSymbol.substr(1)); + break; + case MipsOperand::Kind_FGR32Regs: + RegNum = matchFPURegisterName(DefSymbol.substr(1)); + break; + case MipsOperand::Kind_GPR64: + case MipsOperand::Kind_GPR32: + default: + RegNum = matchCPURegisterName(DefSymbol.substr(1)); + break; + } + if (RegNum > -1) + RegNum = getReg(regKindToRegClass(Kind), RegNum); + } + if (RegNum > -1) { + Parser.Lex(); + MipsOperand *op = + MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc()); + op->setRegKind(Kind); + Operands.push_back(op); + return true; + } + } + } else if (Expr->getKind() == MCExpr::Constant) { + Parser.Lex(); + const MCConstantExpr *Const = static_cast(Expr); + MipsOperand *op = + MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc()); + Operands.push_back(op); + return true; + } + } + return false; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseHWRegs(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs); +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseCCRRegs(SmallVectorImpl &Operands) { + return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs); } MipsAsmParser::OperandMatchResultTy @@ -1919,12 +2215,12 @@ MipsAsmParser::parseInvNum(SmallVectorImpl &Operands) { int64_t Val = MCE->getValue(); SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(MipsOperand::CreateImm( - MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); + MCConstantExpr::Create(0 - Val, getContext()), S, E)); return MatchOperand_Success; } MipsAsmParser::OperandMatchResultTy -MipsAsmParser::ParseLSAImm(SmallVectorImpl &Operands) { +MipsAsmParser::parseLSAImm(SmallVectorImpl &Operands) { switch (getLexer().getKind()) { default: return MatchOperand_NoMatch; @@ -1958,7 +2254,7 @@ MipsAsmParser::ParseLSAImm(SmallVectorImpl &Operands) { } Operands.push_back( - MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); + MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc())); return MatchOperand_Success; } @@ -1996,74 +2292,16 @@ MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { return VK; } -/// Sometimes (i.e. load/stores) the operand may be followed immediately by -/// either this. -/// ::= '(', register, ')' -/// handle it before we iterate so we don't get tripped up by the lack of -/// a comma. -bool MipsAsmParser::ParseParenSuffix( - StringRef Name, SmallVectorImpl &Operands) { - if (getLexer().is(AsmToken::LParen)) { - Operands.push_back( - MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); - Parser.Lex(); - if (ParseOperand(Operands, Name)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - if (Parser.getTok().isNot(AsmToken::RParen)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token, expected ')'"); - } - Operands.push_back( - MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); - Parser.Lex(); - } - return false; -} - -/// Sometimes (i.e. in MSA) the operand may be followed immediately by -/// either one of these. -/// ::= '[', register, ']' -/// ::= '[', integer, ']' -/// handle it before we iterate so we don't get tripped up by the lack of -/// a comma. -bool MipsAsmParser::ParseBracketSuffix( - StringRef Name, SmallVectorImpl &Operands) { - if (getLexer().is(AsmToken::LBrac)) { - Operands.push_back( - MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); - Parser.Lex(); - if (ParseOperand(Operands, Name)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token in argument list"); - } - if (Parser.getTok().isNot(AsmToken::RBrac)) { - SMLoc Loc = getLexer().getLoc(); - Parser.eatToEndOfStatement(); - return Error(Loc, "unexpected token, expected ']'"); - } - Operands.push_back( - MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); - Parser.Lex(); - } - return false; -} - bool MipsAsmParser::ParseInstruction( ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, SmallVectorImpl &Operands) { - DEBUG(dbgs() << "ParseInstruction\n"); // Check if we have valid mnemonic if (!mnemonicIsValid(Name, 0)) { Parser.eatToEndOfStatement(); return Error(NameLoc, "Unknown instruction"); } // First operand in MCInst is instruction mnemonic. - Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); + Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); // Read the remaining operands. if (getLexer().isNot(AsmToken::EndOfStatement)) { @@ -2073,9 +2311,6 @@ bool MipsAsmParser::ParseInstruction( Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token in argument list"); } - if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands)) - return true; - // AFAIK, parenthesis suffixes are never on the first operand while (getLexer().is(AsmToken::Comma)) { Parser.Lex(); // Eat the comma. @@ -2085,13 +2320,6 @@ bool MipsAsmParser::ParseInstruction( Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token in argument list"); } - // Parse bracket and parenthesis suffixes before we iterate - if (getLexer().is(AsmToken::LBrac)) { - if (ParseBracketSuffix(Name, Operands)) - return true; - } else if (getLexer().is(AsmToken::LParen) && - ParseParenSuffix(Name, Operands)) - return true; } } if (getLexer().isNot(AsmToken::EndOfStatement)) { diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index fc3b922602c..a5438401323 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -263,11 +263,6 @@ static DecodeStatus DecodeExtSize(MCInst &Inst, uint64_t Address, const void *Decoder); -/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't -/// handle. -template -static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder); namespace llvm { extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, TheMips64elTarget; @@ -309,53 +304,8 @@ extern "C" void LLVMInitializeMipsDisassembler() { createMips64elDisassembler); } -#include "MipsGenDisassemblerTables.inc" - -template -static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, - const void *Decoder) { - typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); - // The size of the n field depends on the element size - // The register class also depends on this. - InsnType tmp = fieldFromInstruction(insn, 17, 5); - unsigned NSize = 0; - DecodeFN RegDecoder = nullptr; - if ((tmp & 0x18) == 0x00) { // INSVE_B - NSize = 4; - RegDecoder = DecodeMSA128BRegisterClass; - } else if ((tmp & 0x1c) == 0x10) { // INSVE_H - NSize = 3; - RegDecoder = DecodeMSA128HRegisterClass; - } else if ((tmp & 0x1e) == 0x18) { // INSVE_W - NSize = 2; - RegDecoder = DecodeMSA128WRegisterClass; - } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D - NSize = 1; - RegDecoder = DecodeMSA128DRegisterClass; - } else - llvm_unreachable("Invalid encoding"); - - assert(NSize != 0 && RegDecoder != nullptr); - - // $wd - tmp = fieldFromInstruction(insn, 6, 5); - if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) - return MCDisassembler::Fail; - // $wd_in - if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) - return MCDisassembler::Fail; - // $n - tmp = fieldFromInstruction(insn, 16, NSize); - MI.addOperand(MCOperand::CreateImm(tmp)); - // $ws - tmp = fieldFromInstruction(insn, 11, 5); - if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) - return MCDisassembler::Fail; - // $n2 - MI.addOperand(MCOperand::CreateImm(0)); - return MCDisassembler::Success; -} +#include "MipsGenDisassemblerTables.inc" /// readInstruction - read four bytes from the MemoryObject /// and return 32 bit word sorted according to the given endianess diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index abf36daab41..04520b7a221 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -197,7 +197,6 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::ILVR: return "MipsISD::ILVR"; case MipsISD::PCKEV: return "MipsISD::PCKEV"; case MipsISD::PCKOD: return "MipsISD::PCKOD"; - case MipsISD::INSVE: return "MipsISD::INSVE"; default: return NULL; } } diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 35dd39617fb..5a105ffc893 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -184,9 +184,6 @@ namespace llvm { PCKEV, // Pack even elements PCKOD, // Pack odd elements - // Vector Lane Copy - INSVE, // Copy element from one vector to another - // Combined (XOR (OR $a, $b), -1) VNOR, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 71d0a18d48c..af4fa6410c8 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -236,27 +236,17 @@ include "MipsInstrFormats.td" // Mips Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// -def MipsJumpTargetAsmOperand : AsmOperandClass { - let Name = "JumpTarget"; - let ParserMethod = "ParseJumpTarget"; - let PredicateMethod = "isImm"; - let RenderMethod = "addImmOperands"; -} - // Instruction operand types def jmptarget : Operand { let EncoderMethod = "getJumpTargetOpValue"; - let ParserMatchClass = MipsJumpTargetAsmOperand; } def brtarget : Operand { let EncoderMethod = "getBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; let DecoderMethod = "DecodeBranchTarget"; - let ParserMatchClass = MipsJumpTargetAsmOperand; } def calltarget : Operand { let EncoderMethod = "getJumpTargetOpValue"; - let ParserMatchClass = MipsJumpTargetAsmOperand; } def simm10 : Operand; @@ -278,11 +268,6 @@ def simm16_64 : Operand { let DecoderMethod = "DecodeSimm16"; } -// Zero -def uimmz : Operand { - let PrintMethod = "printUnsignedImm"; -} - // Unsigned Operand def uimm5 : Operand { let PrintMethod = "printUnsignedImm"; @@ -310,6 +295,12 @@ def MipsInvertedImmoperand : AsmOperandClass { let ParserMethod = "parseInvNum"; } +def PtrRegAsmOperand : AsmOperandClass { + let Name = "PtrReg"; + let ParserMethod = "parsePtrReg"; +} + + def InvertedImOperand : Operand { let ParserMatchClass = MipsInvertedImmoperand; } @@ -341,7 +332,7 @@ def mem_ea : Operand { def PtrRC : Operand { let MIOperandInfo = (ops ptr_rc); let DecoderMethod = "DecodePtrRegisterClass"; - let ParserMatchClass = GPR32AsmOperand; + let ParserMatchClass = PtrRegAsmOperand; } // size operand of ext instruction @@ -369,9 +360,6 @@ def HI16 : SDNodeXFormgetSExtValue() + 1); }]>; -// Node immediate is zero (e.g. insve.d) -def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>; - // Node immediate fits as 16-bit sign extended on target immediate. // e.g. addi, andi def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>; diff --git a/lib/Target/Mips/MipsMSAInstrInfo.td b/lib/Target/Mips/MipsMSAInstrInfo.td index 5722c6cf00b..4a30d5ae969 100644 --- a/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/lib/Target/Mips/MipsMSAInstrInfo.td @@ -27,9 +27,6 @@ def SDT_SHF : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, SDTCisVT<1, i32>, SDTCisSameAs<0, 2>]>; def SDT_ILV : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; -def SDT_INSVE : SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCisSameAs<0, 1>, - SDTCisVT<2, i32>, SDTCisSameAs<0, 3>, - SDTCisVT<4, i32>]>; def MipsVAllNonZero : SDNode<"MipsISD::VALL_NONZERO", SDT_MipsVecCond>; def MipsVAnyNonZero : SDNode<"MipsISD::VANY_NONZERO", SDT_MipsVecCond>; @@ -53,7 +50,6 @@ def MipsILVL : SDNode<"MipsISD::ILVL", SDT_ILV>; def MipsILVR : SDNode<"MipsISD::ILVR", SDT_ILV>; def MipsPCKEV : SDNode<"MipsISD::PCKEV", SDT_ILV>; def MipsPCKOD : SDNode<"MipsISD::PCKOD", SDT_ILV>; -def MipsINSVE : SDNode<"MipsISD::INSVE", SDT_INSVE>; def vsetcc : SDNode<"ISD::SETCC", SDT_VSetCC>; def vfsetcc : SDNode<"ISD::SETCC", SDT_VFSetCC>; @@ -73,7 +69,7 @@ def uimm2 : Operand { // as the encoded value should be subtracted by one. def uimm2LSAAsmOperand : AsmOperandClass { let Name = "LSAImm"; - let ParserMethod = "ParseLSAImm"; + let ParserMethod = "parseLSAImm"; let RenderMethod = "addImmOperands"; } @@ -160,15 +156,6 @@ def vinsert_v4i32 : PatFrag<(ops node:$vec, node:$val, node:$idx), def vinsert_v2i64 : PatFrag<(ops node:$vec, node:$val, node:$idx), (v2i64 (vector_insert node:$vec, node:$val, node:$idx))>; -def insve_v16i8 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), - (v16i8 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; -def insve_v8i16 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), - (v8i16 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; -def insve_v4i32 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), - (v4i32 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; -def insve_v2i64 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), - (v2i64 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; - class vfsetcc_type : PatFrag<(ops node:$lhs, node:$rhs), (ResTy (vfsetcc (OpTy node:$lhs), (OpTy node:$rhs), CC))>; @@ -1415,9 +1402,9 @@ class MSA_3R_SPLAT_DESC_BASE { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWS:$ws, GPR32Opnd:$rt); + dag InOperandList = (ins ROWS:$ws, GPR32:$rt); string AsmString = !strconcat(instr_asm, "\t$wd, $ws[$rt]"); - list Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32Opnd:$rt))]; + list Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32:$rt))]; InstrItinClass Itinerary = itin; } @@ -1438,10 +1425,10 @@ class MSA_3R_SLD_DESC_BASE { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, GPR32Opnd:$rt); + dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, GPR32:$rt); string AsmString = !strconcat(instr_asm, "\t$wd, $ws[$rt]"); list Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, ROWS:$ws, - GPR32Opnd:$rt))]; + GPR32:$rt))]; InstrItinClass Itinerary = itin; string Constraints = "$wd = $wd_in"; } @@ -1509,12 +1496,11 @@ class MSA_INSVE_DESC_BASE { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWD:$wd_in, uimm6:$n, ROWS:$ws, uimmz:$n2); - string AsmString = !strconcat(instr_asm, "\t$wd[$n], $ws[$n2]"); + dag InOperandList = (ins ROWD:$wd_in, uimm6:$n, ROWS:$ws); + string AsmString = !strconcat(instr_asm, "\t$wd[$n], $ws[0]"); list Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, immZExt6:$n, - ROWS:$ws, - immz:$n2))]; + ROWS:$ws))]; InstrItinClass Itinerary = itin; string Constraints = "$wd = $wd_in"; } @@ -2305,13 +2291,13 @@ class INSERT_FW_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE; -class INSVE_B_DESC : MSA_INSVE_DESC_BASE<"insve.b", insve_v16i8, +class INSVE_B_DESC : MSA_INSVE_DESC_BASE<"insve.b", int_mips_insve_b, MSA128BOpnd>; -class INSVE_H_DESC : MSA_INSVE_DESC_BASE<"insve.h", insve_v8i16, +class INSVE_H_DESC : MSA_INSVE_DESC_BASE<"insve.h", int_mips_insve_h, MSA128HOpnd>; -class INSVE_W_DESC : MSA_INSVE_DESC_BASE<"insve.w", insve_v4i32, +class INSVE_W_DESC : MSA_INSVE_DESC_BASE<"insve.w", int_mips_insve_w, MSA128WOpnd>; -class INSVE_D_DESC : MSA_INSVE_DESC_BASE<"insve.d", insve_v2i64, +class INSVE_D_DESC : MSA_INSVE_DESC_BASE<"insve.d", int_mips_insve_d, MSA128DOpnd>; class LD_DESC_BASE; // Hardware register $29 - foreach I = 0-31 in - def HWR#I : MipsReg<#I, ""#I>; + def HWR29 : MipsReg<29, "29">; // Accum registers foreach I = 0-3 in @@ -365,8 +364,7 @@ def LO64 : RegisterClass<"Mips", [i64], 64, (add LO0_64)>; def HI64 : RegisterClass<"Mips", [i64], 64, (add HI0_64)>; // Hardware registers -def HWRegs : RegisterClass<"Mips", [i32], 32, (sequence "HWR%u", 0, 31)>, - Unallocatable; +def HWRegs : RegisterClass<"Mips", [i32], 32, (add HWR29)>, Unallocatable; // Accumulator Registers def ACC64 : RegisterClass<"Mips", [untyped], 64, (add AC0)> { @@ -396,68 +394,86 @@ def OCTEON_P : RegisterClass<"Mips", [i64], 64, (add P0, P1, P2)>, // Register Operands. class MipsAsmRegOperand : AsmOperandClass { - let ParserMethod = "ParseAnyRegister"; + let RenderMethod = "addRegAsmOperands"; } - -def GPR64AsmOperand : MipsAsmRegOperand { - let Name = "GPR64AsmReg"; - let PredicateMethod = "isGPRAsmReg"; +def GPR32AsmOperand : MipsAsmRegOperand { + let Name = "GPR32Asm"; + let ParserMethod = "parseGPR32"; } -def GPR32AsmOperand : MipsAsmRegOperand { - let Name = "GPR32AsmReg"; - let PredicateMethod = "isGPRAsmReg"; +def GPR64AsmOperand : MipsAsmRegOperand { + let Name = "GPR64Asm"; + let ParserMethod = "parseGPR64"; } def ACC64DSPAsmOperand : MipsAsmRegOperand { - let Name = "ACC64DSPAsmReg"; - let PredicateMethod = "isACCAsmReg"; + let Name = "ACC64DSPAsm"; + let ParserMethod = "parseACC64DSP"; } -def HI32DSPAsmOperand : MipsAsmRegOperand { - let Name = "HI32DSPAsmReg"; - let PredicateMethod = "isACCAsmReg"; +def LO32DSPAsmOperand : MipsAsmRegOperand { + let Name = "LO32DSPAsm"; + let ParserMethod = "parseLO32DSP"; } -def LO32DSPAsmOperand : MipsAsmRegOperand { - let Name = "LO32DSPAsmReg"; - let PredicateMethod = "isACCAsmReg"; +def HI32DSPAsmOperand : MipsAsmRegOperand { + let Name = "HI32DSPAsm"; + let ParserMethod = "parseHI32DSP"; } def CCRAsmOperand : MipsAsmRegOperand { - let Name = "CCRAsmReg"; + let Name = "CCRAsm"; + let ParserMethod = "parseCCRRegs"; } def AFGR64AsmOperand : MipsAsmRegOperand { - let Name = "AFGR64AsmReg"; - let PredicateMethod = "isFGRAsmReg"; + let Name = "AFGR64Asm"; + let ParserMethod = "parseAFGR64Regs"; } def FGR64AsmOperand : MipsAsmRegOperand { - let Name = "FGR64AsmReg"; - let PredicateMethod = "isFGRAsmReg"; + let Name = "FGR64Asm"; + let ParserMethod = "parseFGR64Regs"; } def FGR32AsmOperand : MipsAsmRegOperand { - let Name = "FGR32AsmReg"; - let PredicateMethod = "isFGRAsmReg"; + let Name = "FGR32Asm"; + let ParserMethod = "parseFGR32Regs"; } def FGRH32AsmOperand : MipsAsmRegOperand { - let Name = "FGRH32AsmReg"; - let PredicateMethod = "isFGRAsmReg"; + let Name = "FGRH32Asm"; + let ParserMethod = "parseFGRH32Regs"; } def FCCRegsAsmOperand : MipsAsmRegOperand { - let Name = "FCCAsmReg"; + let Name = "FCCRegsAsm"; + let ParserMethod = "parseFCCRegs"; +} + +def MSA128BAsmOperand : MipsAsmRegOperand { + let Name = "MSA128BAsm"; + let ParserMethod = "parseMSA128BRegs"; +} + +def MSA128HAsmOperand : MipsAsmRegOperand { + let Name = "MSA128HAsm"; + let ParserMethod = "parseMSA128HRegs"; +} + +def MSA128WAsmOperand : MipsAsmRegOperand { + let Name = "MSA128WAsm"; + let ParserMethod = "parseMSA128WRegs"; } -def MSA128AsmOperand : MipsAsmRegOperand { - let Name = "MSA128AsmReg"; +def MSA128DAsmOperand : MipsAsmRegOperand { + let Name = "MSA128DAsm"; + let ParserMethod = "parseMSA128DRegs"; } -def MSACtrlAsmOperand : MipsAsmRegOperand { - let Name = "MSACtrlAsmReg"; +def MSA128CRAsmOperand : MipsAsmRegOperand { + let Name = "MSA128CRAsm"; + let ParserMethod = "parseMSA128CtrlRegs"; } def GPR32Opnd : RegisterOperand { @@ -477,11 +493,13 @@ def CCROpnd : RegisterOperand { } def HWRegsAsmOperand : MipsAsmRegOperand { - let Name = "HWRegsAsmReg"; + let Name = "HWRegsAsm"; + let ParserMethod = "parseHWRegs"; } def COP2AsmOperand : MipsAsmRegOperand { - let Name = "COP2AsmReg"; + let Name = "COP2Asm"; + let ParserMethod = "parseCOP2"; } def HWRegsOpnd : RegisterOperand { @@ -525,22 +543,22 @@ def COP2Opnd : RegisterOperand { } def MSA128BOpnd : RegisterOperand { - let ParserMatchClass = MSA128AsmOperand; + let ParserMatchClass = MSA128BAsmOperand; } def MSA128HOpnd : RegisterOperand { - let ParserMatchClass = MSA128AsmOperand; + let ParserMatchClass = MSA128HAsmOperand; } def MSA128WOpnd : RegisterOperand { - let ParserMatchClass = MSA128AsmOperand; + let ParserMatchClass = MSA128WAsmOperand; } def MSA128DOpnd : RegisterOperand { - let ParserMatchClass = MSA128AsmOperand; + let ParserMatchClass = MSA128DAsmOperand; } def MSA128CROpnd : RegisterOperand { - let ParserMatchClass = MSACtrlAsmOperand; + let ParserMatchClass = MSA128CRAsmOperand; } diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 0dac0b79909..218cd15baa9 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -1810,13 +1810,6 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::mips_insert_d: return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0), Op->getOperand(1), Op->getOperand(3), Op->getOperand(2)); - case Intrinsic::mips_insve_b: - case Intrinsic::mips_insve_h: - case Intrinsic::mips_insve_w: - case Intrinsic::mips_insve_d: - return DAG.getNode(MipsISD::INSVE, DL, Op->getValueType(0), - Op->getOperand(1), Op->getOperand(2), Op->getOperand(3), - DAG.getConstant(0, MVT::i32)); case Intrinsic::mips_ldi_b: case Intrinsic::mips_ldi_h: case Intrinsic::mips_ldi_w: @@ -2844,8 +2837,7 @@ MipsSETargetLowering::emitINSERT_FW(MachineInstr *MI, BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd) .addReg(Wd_in) .addImm(Lane) - .addReg(Wt) - .addImm(0); + .addReg(Wt); MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; @@ -2878,8 +2870,7 @@ MipsSETargetLowering::emitINSERT_FD(MachineInstr *MI, BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd) .addReg(Wd_in) .addImm(Lane) - .addReg(Wt) - .addImm(0); + .addReg(Wt); MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; diff --git a/test/MC/Mips/cfi.s b/test/MC/Mips/cfi.s deleted file mode 100644 index a3247b5479a..00000000000 --- a/test/MC/Mips/cfi.s +++ /dev/null @@ -1,13 +0,0 @@ -# RUN: llvm-mc %s -triple=mips-unknown-unknown -show-encoding -mcpu=mips32 | \ -# RUN: FileCheck %s -# RUN: llvm-mc %s -triple=mips64-unknown-unknown -show-encoding -mcpu=mips64 | \ -# RUN: FileCheck %s - -# Check that we can accept register names in CFI directives and that they are -# canonicalised to their DWARF register numbers. - - .cfi_startproc # CHECK: .cfi_startproc - .cfi_register $6, $5 # CHECK: .cfi_register 6, 5 - .cfi_def_cfa $fp, 8 # CHECK: .cfi_def_cfa 30, 8 - .cfi_def_cfa $2, 16 # CHECK: .cfi_def_cfa 2, 16 - .cfi_endproc # CHECK: .cfi_endproc diff --git a/test/MC/Mips/mips-register-names-invalid.s b/test/MC/Mips/mips-register-names-invalid.s index e6f8416a41e..df1054fed42 100644 --- a/test/MC/Mips/mips-register-names-invalid.s +++ b/test/MC/Mips/mips-register-names-invalid.s @@ -4,5 +4,5 @@ # $32 used to trigger an assertion instead of the usual error message due to # an off-by-one bug. -# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction +# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction add $32, $0, $0 diff --git a/test/MC/Mips/mips3/valid-xfail.s b/test/MC/Mips/mips3/valid-xfail.s index 7f802ef765f..dd4e482f381 100644 --- a/test/MC/Mips/mips3/valid-xfail.s +++ b/test/MC/Mips/mips3/valid-xfail.s @@ -8,6 +8,10 @@ # XFAIL: * .set noat + ddiv $zero,$k0,$s3 + ddivu $zero,$s0,$s1 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 ehb lwc3 $10,-32265($k0) ssnop diff --git a/test/MC/Mips/mips3/valid.s b/test/MC/Mips/mips3/valid.s index 703d49a4ea7..f5c98f0007e 100644 --- a/test/MC/Mips/mips3/valid.s +++ b/test/MC/Mips/mips3/valid.s @@ -35,12 +35,8 @@ dadd $s3,$at,$ra daddi $sp,$s4,-27705 daddiu $k0,$s6,-4586 - ddiv $zero,$k0,$s3 - ddivu $zero,$s0,$s1 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 dmfc1 $t4,$f13 dmtc1 $s0,$f14 dmult $s7,$t1 diff --git a/test/MC/Mips/mips32r2/valid-xfail.s b/test/MC/Mips/mips32r2/valid-xfail.s index 5dbb1d3b497..dff3ae43f1e 100644 --- a/test/MC/Mips/mips32r2/valid-xfail.s +++ b/test/MC/Mips/mips32r2/valid-xfail.s @@ -2,7 +2,7 @@ # they aren't implemented yet). # This test is set up to XPASS if any instruction generates an encoding. # -# RUN: not llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | not FileCheck %s +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | FileCheck %s # CHECK-NOT: encoding # XFAIL: * @@ -48,6 +48,7 @@ c.nge.d $fcc5,$f21,$f16 c.nge.ps $f1,$f26 c.nge.s $fcc3,$f11,$f8 + c.ngl.d $f29,$f29 c.ngl.ps $f21,$f30 c.ngl.s $fcc2,$f31,$f23 c.ngle.ps $fcc7,$f12,$f20 @@ -65,6 +66,7 @@ c.seq.ps $fcc6,$f31,$f14 c.seq.s $fcc7,$f1,$f25 c.sf.ps $fcc6,$f4,$f6 + c.sf.s $f14,$f22 c.ueq.d $fcc4,$f13,$f25 c.ueq.ps $fcc1,$f5,$f29 c.ueq.s $fcc6,$f3,$f30 @@ -94,10 +96,14 @@ cmpu.lt.qb $at,$a3 ctcmsa $31,$s7 cvt.d.l $f4,$f16 + cvt.l.d $f24,$f15 + cvt.l.s $f11,$f29 cvt.ps.s $f3,$f18,$f19 cvt.s.l $f15,$f30 cvt.s.pl $f30,$f1 cvt.s.pu $f14,$f25 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 dmt $k0 dpa.w.ph $ac1,$s7,$k0 dpaq_s.w.ph $ac2,$a0,$t5 @@ -146,6 +152,8 @@ flog2.w $w19,$w23 floor.l.d $f26,$f7 floor.l.s $f12,$f5 + floor.w.d $f14,$f11 + floor.w.s $f8,$f9 fork $s2,$t0,$a0 frcp.d $w12,$w4 frcp.w $w30,$w8 @@ -220,8 +228,12 @@ nlzc.d $w14,$w14 nlzc.h $w24,$w24 nlzc.w $w10,$w4 + nmadd.d $f18,$f9,$f14,$f19 nmadd.ps $f27,$f4,$f9,$f25 + nmadd.s $f0,$f5,$f25,$f12 + nmsub.d $f30,$f8,$f16,$f30 nmsub.ps $f6,$f12,$f14,$f17 + nmsub.s $f1,$f24,$f19,$f4 nor.v $w20,$w20,$w15 or.v $w13,$w23,$w12 packrl.ph $ra,$t8,$t6 @@ -252,6 +264,7 @@ pul.ps $f9,$f30,$f26 puu.ps $f24,$f9,$f2 raddu.w.qb $t9,$s3 + rdhwr $sp,$11 rdpgpr $s3,$t1 recip.d $f19,$f6 recip.s $f3,$f30 @@ -298,6 +311,7 @@ swe $t8,94($k0) swle $v1,-209($gp) swre $k0,-202($s2) + swxc1 $f19,$t4($k0) synci 20023($s0) tlbginv tlbginvf diff --git a/test/MC/Mips/mips32r2/valid.s b/test/MC/Mips/mips32r2/valid.s index 29c0807fff1..03f51554250 100644 --- a/test/MC/Mips/mips32r2/valid.s +++ b/test/MC/Mips/mips32r2/valid.s @@ -11,10 +11,8 @@ addi $t5,$t1,26322 addu $t1,$a0,$a2 and $s7,$v0,$t4 - c.ngl.d $f29,$f29 c.ngle.d $f0,$f16 c.sf.d $f30,$f0 - c.sf.s $f14,$f22 ceil.w.d $f11,$f25 ceil.w.s $f6,$f20 cfc1 $s1,$21 @@ -23,22 +21,16 @@ ctc1 $a2,$26 cvt.d.s $f22,$f28 cvt.d.w $f26,$f11 - cvt.l.d $f24,$f15 - cvt.l.s $f11,$f29 cvt.s.d $f26,$f8 cvt.s.w $f22,$f15 cvt.w.d $f20,$f14 cvt.w.s $f20,$f24 deret di $s8 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 ei $t6 eret - floor.w.d $f14,$f11 - floor.w.s $f8,$f9 lb $t8,-14515($t2) lbu $t0,30195($v1) ldc1 $f11,16391($s0) @@ -102,14 +94,9 @@ multu $t1,$s2 neg.d $f27,$f18 neg.s $f1,$f15 - nmadd.d $f18,$f9,$f14,$f19 - nmadd.s $f0,$f5,$f25,$f12 - nmsub.d $f30,$f8,$f16,$f30 - nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 or $t4,$s0,$sp - rdhwr $sp,$11 round.w.d $f6,$f4 round.w.s $f27,$f28 sb $s6,-19857($t6) @@ -139,7 +126,6 @@ swc2 $25,24880($s0) swl $t7,13694($s3) swr $s1,-26590($t6) - swxc1 $f19,$t4($k0) teqi $s5,-17504 tgei $s1,5025 tgeiu $sp,-28621 diff --git a/test/MC/Mips/mips4/valid-xfail.s b/test/MC/Mips/mips4/valid-xfail.s index 26749a91532..7599164af0b 100644 --- a/test/MC/Mips/mips4/valid-xfail.s +++ b/test/MC/Mips/mips4/valid-xfail.s @@ -36,6 +36,10 @@ c.ult.s $fcc7,$f24,$f10 c.un.d $fcc6,$f23,$f24 c.un.s $fcc1,$f30,$f4 + ddiv $zero,$k0,$s3 + ddivu $zero,$s0,$s1 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 ehb madd.d $f18,$f19,$f26,$f20 madd.s $f1,$f31,$f19,$f25 diff --git a/test/MC/Mips/mips4/valid.s b/test/MC/Mips/mips4/valid.s index bcc9f689bfa..66886c5794e 100644 --- a/test/MC/Mips/mips4/valid.s +++ b/test/MC/Mips/mips4/valid.s @@ -35,12 +35,8 @@ dadd $s3,$at,$ra daddi $sp,$s4,-27705 daddiu $k0,$s6,-4586 - ddiv $zero,$k0,$s3 - ddivu $zero,$s0,$s1 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 dmfc1 $t4,$f13 dmtc1 $s0,$f14 dmult $s7,$t1 diff --git a/test/MC/Mips/mips5/valid-xfail.s b/test/MC/Mips/mips5/valid-xfail.s index 285aabbfe6b..10931587e45 100644 --- a/test/MC/Mips/mips5/valid-xfail.s +++ b/test/MC/Mips/mips5/valid-xfail.s @@ -58,6 +58,10 @@ cvt.ps.s $f3,$f18,$f19 cvt.s.pl $f30,$f1 cvt.s.pu $f14,$f25 + ddiv $zero,$k0,$s3 + ddivu $zero,$s0,$s1 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 ehb madd.d $f18,$f19,$f26,$f20 madd.ps $f22,$f3,$f14,$f3 diff --git a/test/MC/Mips/mips5/valid.s b/test/MC/Mips/mips5/valid.s index 64c2ff5e789..7665d1f025e 100644 --- a/test/MC/Mips/mips5/valid.s +++ b/test/MC/Mips/mips5/valid.s @@ -35,12 +35,8 @@ dadd $s3,$at,$ra daddi $sp,$s4,-27705 daddiu $k0,$s6,-4586 - ddiv $zero,$k0,$s3 - ddivu $zero,$s0,$s1 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 dmfc1 $t4,$f13 dmtc1 $s0,$f14 dmult $s7,$t1 diff --git a/test/MC/Mips/mips64/valid-xfail.s b/test/MC/Mips/mips64/valid-xfail.s index 66f15e03c24..11ed7747b24 100644 --- a/test/MC/Mips/mips64/valid-xfail.s +++ b/test/MC/Mips/mips64/valid-xfail.s @@ -60,6 +60,10 @@ cvt.ps.s $f3,$f18,$f19 cvt.s.pl $f30,$f1 cvt.s.pu $f14,$f25 + ddiv $zero,$k0,$s3 + ddivu $zero,$s0,$s1 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 dmfc0 $t2,c0_watchhi,2 dmtc0 $t7,c0_datalo ehb diff --git a/test/MC/Mips/mips64/valid.s b/test/MC/Mips/mips64/valid.s index 673754535bc..cfd708ce667 100644 --- a/test/MC/Mips/mips64/valid.s +++ b/test/MC/Mips/mips64/valid.s @@ -39,12 +39,8 @@ dclo $s2,$a2 dclz $s0,$t9 deret - ddiv $zero,$k0,$s3 - ddivu $zero,$s0,$s1 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 dmfc1 $t4,$f13 dmtc1 $s0,$f14 dmult $s7,$t1 diff --git a/test/MC/Mips/mips64r2/valid-xfail.s b/test/MC/Mips/mips64r2/valid-xfail.s index 3e725ea9683..7279707ea0b 100644 --- a/test/MC/Mips/mips64r2/valid-xfail.s +++ b/test/MC/Mips/mips64r2/valid-xfail.s @@ -5,6 +5,7 @@ # RUN: not llvm-mc %s -triple=mips64-unknown-linux -show-encoding -mcpu=mips64r2 | not FileCheck %s # CHECK-NOT: encoding # XFAIL: * +# REQUIRES: asserts .set noat abs.ps $f22,$f8 @@ -51,6 +52,7 @@ c.nge.d $fcc5,$f21,$f16 c.nge.ps $f1,$f26 c.nge.s $fcc3,$f11,$f8 + c.ngl.d $f29,$f29 c.ngl.ps $f21,$f30 c.ngl.s $fcc2,$f31,$f23 c.ngle.ps $fcc7,$f12,$f20 @@ -68,6 +70,7 @@ c.seq.ps $fcc6,$f31,$f14 c.seq.s $fcc7,$f1,$f25 c.sf.ps $fcc6,$f4,$f6 + c.sf.s $f14,$f22 c.ueq.d $fcc4,$f13,$f25 c.ueq.ps $fcc1,$f5,$f29 c.ueq.s $fcc6,$f3,$f30 @@ -95,6 +98,10 @@ cmpu.lt.qb $at,$a3 cvt.s.pl $f30,$f1 cvt.s.pu $f14,$f25 + ddiv $zero,$k0,$s3 + ddivu $zero,$s0,$s1 + div $zero,$t9,$t3 + divu $zero,$t9,$t7 dmfc0 $t2,c0_watchhi,2 dmfgc0 $gp,c0_perfcnt,6 dmt $k0 @@ -117,6 +124,8 @@ dpsu.h.qbr $ac2,$a1,$s6 dpsx.w.ph $ac0,$s7,$gp drorv $at,$a1,$s7 + dsbh $v1,$t6 + dshd $v0,$sp dvpe $s6 ehb emt $t0 @@ -179,6 +188,7 @@ lwx $t4,$t4($s4) madd.d $f18,$f19,$f26,$f20 madd.ps $f22,$f3,$f14,$f3 + madd.s $f1,$f31,$f19,$f25 maq_s.w.phl $ac2,$t9,$t3 maq_s.w.phr $ac0,$t2,$t9 maq_sa.w.phl $ac3,$a1,$v1 @@ -196,6 +206,7 @@ msub $ac2,$sp,$t6 msub.d $f10,$f1,$f31,$f18 msub.ps $f12,$f14,$f29,$f17 + msub.s $f12,$f19,$f10,$f16 msubu $ac2,$a1,$t8 mtc0 $t1,c0_datahi1 mtgc0 $s4,$21,7 @@ -225,8 +236,10 @@ nlzc.w $w10,$w4 nmadd.d $f18,$f9,$f14,$f19 nmadd.ps $f27,$f4,$f9,$f25 + nmadd.s $f0,$f5,$f25,$f12 nmsub.d $f30,$f8,$f16,$f30 nmsub.ps $f6,$f12,$f14,$f17 + nmsub.s $f1,$f24,$f19,$f4 nor.v $w20,$w20,$w15 or.v $w13,$w23,$w12 packrl.ph $ra,$t8,$t6 @@ -257,6 +270,7 @@ pul.ps $f9,$f30,$f26 puu.ps $f24,$f9,$f2 raddu.w.qb $t9,$s3 + rdhwr $sp,$11 rdpgpr $s3,$t1 recip.d $f19,$f6 recip.s $f3,$f30 @@ -268,6 +282,8 @@ rsqrt.s $f4,$f8 sbe $s7,33($s1) sce $sp,189($t2) + seb $t9,$t7 + seh $v1,$t4 she $t8,105($v0) shilo $ac1,26 shilov $ac2,$t2 @@ -314,5 +330,6 @@ tlbwi tlbwr wrpgpr $zero,$t5 + wsbh $k1,$t1 xor.v $w20,$w21,$w30 yield $v1,$s0 diff --git a/test/MC/Mips/mips64r2/valid.s b/test/MC/Mips/mips64r2/valid.s index 4e549af9e79..e1d80199c34 100644 --- a/test/MC/Mips/mips64r2/valid.s +++ b/test/MC/Mips/mips64r2/valid.s @@ -11,10 +11,8 @@ addi $t5,$t1,26322 addu $t1,$a0,$a2 and $s7,$v0,$t4 - c.ngl.d $f29,$f29 c.ngle.d $f0,$f16 c.sf.d $f30,$f0 - c.sf.s $f14,$f22 ceil.l.d $f1,$f3 ceil.l.s $f18,$f13 ceil.w.d $f11,$f25 @@ -40,18 +38,12 @@ dclz $s0,$t9 deret di $s8 - ddiv $zero,$k0,$s3 - ddivu $zero,$s0,$s1 - div $zero,$t9,$t3 div.d $f29,$f20,$f27 div.s $f4,$f5,$f15 - divu $zero,$t9,$t7 dmfc1 $t4,$f13 dmtc1 $s0,$f14 dmult $s7,$t1 dmultu $a1,$a2 - dsbh $v1,$t6 - dshd $v0,$sp dsllv $zero,$s4,$t4 dsrav $gp,$s2,$s3 dsrlv $s3,$t6,$s4 @@ -87,7 +79,6 @@ lwxc1 $f12,$s1($s8) madd $s6,$t5 madd $zero,$t1 - madd.s $f1,$f31,$f19,$f25 maddu $s3,$gp maddu $t8,$s2 mfc0 $a2,$14,1 @@ -115,7 +106,6 @@ movz.d $f12,$f29,$t1 movz.s $f25,$f7,$v1 msub $s7,$k1 - msub.s $f12,$f19,$f10,$f16 msubu $t7,$a1 mtc1 $s8,$f9 mthc1 $zero,$f16 @@ -131,12 +121,9 @@ multu $t1,$s2 neg.d $f27,$f18 neg.s $f1,$f15 - nmadd.s $f0,$f5,$f25,$f12 - nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 or $t4,$s0,$sp - rdhwr $sp,$11 round.l.d $f12,$f1 round.l.s $f25,$f5 round.w.d $f6,$f4 @@ -150,8 +137,6 @@ sdl $a3,-20961($s8) sdr $t3,-20423($t4) sdxc1 $f11,$t2($t6) - seb $t9,$t7 - seh $v1,$t4 sh $t6,-6704($t7) sllv $a3,$zero,$t1 slt $s7,$t3,$k1 @@ -184,4 +169,3 @@ trunc.w.d $f22,$f15 trunc.w.s $f28,$f30 xor $s2,$a0,$s8 - wsbh $k1,$t1 diff --git a/test/MC/Mips/set-at-directive-explicit-at.s b/test/MC/Mips/set-at-directive-explicit-at.s index 1bd26ffa855..71f1a98fae4 100644 --- a/test/MC/Mips/set-at-directive-explicit-at.s +++ b/test/MC/Mips/set-at-directive-explicit-at.s @@ -7,12 +7,12 @@ .text foo: # CHECK: jr $1 # encoding: [0x08,0x00,0x20,0x00] -# WARNINGS: :[[@LINE+2]]:11: warning: Used $at without ".set noat" +# WARNINGS: :[[@LINE+2]]:12: warning: Used $at without ".set noat" .set at=$1 jr $at # CHECK: jr $1 # encoding: [0x08,0x00,0x20,0x00] -# WARNINGS: :[[@LINE+2]]:11: warning: Used $at without ".set noat" +# WARNINGS: :[[@LINE+2]]:12: warning: Used $at without ".set noat" .set at=$1 jr $1 # WARNINGS-NOT: warning: Used $at without ".set noat" @@ -31,12 +31,12 @@ foo: jr $at # CHECK: jr $16 # encoding: [0x08,0x00,0x00,0x02] -# WARNINGS: :[[@LINE+2]]:11: warning: Used $16 with ".set at=$16" +# WARNINGS: :[[@LINE+2]]:12: warning: Used $16 with ".set at=$16" .set at=$16 jr $s0 # CHECK: jr $16 # encoding: [0x08,0x00,0x00,0x02] -# WARNINGS: :[[@LINE+2]]:11: warning: Used $16 with ".set at=$16" +# WARNINGS: :[[@LINE+2]]:12: warning: Used $16 with ".set at=$16" .set at=$16 jr $16 # WARNINGS-NOT: warning -- 2.11.0