summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2014-03-31 18:51:43 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2014-03-31 18:51:43 +0000
commit1c056d8be93c2dd3b180fd165c4fbf229343e96c (patch)
tree1856970cf6627afcb2a115c90478775f17828dd6
parent828bfc7350b2055624d42961a1a037144fab7955 (diff)
downloadllvm-1c056d8be93c2dd3b180fd165c4fbf229343e96c.tar.gz
llvm-1c056d8be93c2dd3b180fd165c4fbf229343e96c.tar.bz2
llvm-1c056d8be93c2dd3b180fd165c4fbf229343e96c.tar.xz
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
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp1636
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp52
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp1
-rw-r--r--lib/Target/Mips/MipsISelLowering.h3
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td26
-rw-r--r--lib/Target/Mips/MipsMSAInstrInfo.td50
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td100
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.cpp13
-rw-r--r--test/MC/Mips/cfi.s13
-rw-r--r--test/MC/Mips/mips-register-names-invalid.s2
-rw-r--r--test/MC/Mips/mips3/valid-xfail.s4
-rw-r--r--test/MC/Mips/mips3/valid.s4
-rw-r--r--test/MC/Mips/mips32r2/valid-xfail.s16
-rw-r--r--test/MC/Mips/mips32r2/valid.s14
-rw-r--r--test/MC/Mips/mips4/valid-xfail.s4
-rw-r--r--test/MC/Mips/mips4/valid.s4
-rw-r--r--test/MC/Mips/mips5/valid-xfail.s4
-rw-r--r--test/MC/Mips/mips5/valid.s4
-rw-r--r--test/MC/Mips/mips64/valid-xfail.s4
-rw-r--r--test/MC/Mips/mips64/valid.s4
-rw-r--r--test/MC/Mips/mips64r2/valid-xfail.s17
-rw-r--r--test/MC/Mips/mips64r2/valid.s16
-rw-r--r--test/MC/Mips/set-at-directive-explicit-at.s8
23 files changed, 1070 insertions, 929 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 95e7d09ce0..2b80d3f03d 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<MipsTargetStreamer &>(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<MCParsedAsmOperand *> &Operands);
-
- bool ParseBracketSuffix(StringRef Name,
- SmallVectorImpl<MCParsedAsmOperand *> &Operands);
-
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
@@ -91,36 +85,95 @@ class MipsAsmParser : public MCTargetAsmParser {
bool ParseDirective(AsmToken DirectiveID);
MipsAsmParser::OperandMatchResultTy
+ parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+ int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
- MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
- SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
- SMLoc S);
+ bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+ int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
+ parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
- ParseAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
- SMLoc S);
+ parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
- ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+ parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
- ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+ parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
- ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+ parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
MipsAsmParser::OperandMatchResultTy
- ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+ parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
- bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+ bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+ unsigned RegKind);
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
StringRef Mnemonic);
+ int tryParseRegister(bool is64BitReg);
+
+ bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &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<MCInst> &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<MCConstantExpr>(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<const MCConstantExpr *>(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;
}
- bool isFGRAsmReg() const {
- // AFGR64 is $0-$15 but we handle this in getAFGR64()
- return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
+ void addRegAsmOperands(MCInst &Inst, unsigned N) const {
+ Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
}
- bool isHWRegsAsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
+
+ bool isGPR64Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_GPR64;
}
- bool isCCRAsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
+
+ bool isHWRegsAsm() const {
+ assert((Kind == k_Register) && "Invalid access!");
+ return Reg.Kind == Kind_HWRegs;
}
- bool isFCCAsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
+
+ 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 isACCAsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
+
+ bool isFGR32Asm() const {
+ return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
}
- bool isCOP2AsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
+
+ bool isFGRH32Asm() const {
+ return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
}
- bool isMSA128AsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
+
+ bool isFCCRegsAsm() const {
+ return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
}
- bool isMSACtrlAsmReg() const {
- return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
+
+ bool isACC64DSPAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
+ }
+
+ bool isLO32DSPAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
+ }
+
+ bool isHI32DSPAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
+ }
+
+ bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
+
+ bool isMSA128BAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
+ }
+
+ bool isMSA128HAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
+ }
+
+ bool isMSA128WAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
+ }
+
+ bool isMSA128DAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
+ }
+
+ 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<unsigned>(Tok.getIntVal()),
+ is64BitReg ? Mips::GPR64RegClassID
+ : Mips::GPR32RegClassID);
+ return RegNum;
+}
+
+bool MipsAsmParser::tryParseRegisterOperand(
+ SmallVectorImpl<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *, 1> Operands;
- OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
- if (ResTy == MatchOperand_Success) {
- assert(Operands.size() == 1);
- MipsOperand &Operand = *static_cast<MipsOperand *>(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<MCParsedAsmOperand *> &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<MipsOperand *>(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<MCParsedAsmOperand *> &Operands) {
+bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+ int RegKind) {
+ // If the first token is not '$' we have an error.
+ if (Parser.getTok().isNot(AsmToken::Dollar))
+ return false;
- 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<const MCSymbolRefExpr *>(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<const MCConstantExpr *>(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<MCParsedAsmOperand *> &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));
+MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ MipsOperand::RegisterKind RegKind =
+ isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
+
+ // Parse index register.
+ if (!parsePtrReg(Operands, RegKind))
+ return MatchOperand_NoMatch;
+
+ // Parse '('.
+ if (Parser.getTok().isNot(AsmToken::LParen))
+ return MatchOperand_NoMatch;
+
+ Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
+ Parser.Lex();
+
+ // Parse base register.
+ if (!parsePtrReg(Operands, RegKind))
+ return MatchOperand_NoMatch;
+
+ // Parse ')'.
+ if (Parser.getTok().isNot(AsmToken::RParen))
+ return MatchOperand_NoMatch;
+
+ Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
+ Parser.Lex();
+
+ return MatchOperand_Success;
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+ int RegKind) {
+ 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 = matchFPURegisterName(Identifier);
- if (Index != -1) {
- Parser.Lex();
- Operands.push_back(MipsOperand::CreateFGRReg(
- 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 = matchFCCRegisterName(Identifier);
- if (Index != -1) {
- Parser.Lex();
- Operands.push_back(MipsOperand::CreateFCCReg(
- Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
- return MatchOperand_Success;
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &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 = matchACRegisterName(Identifier);
- if (Index != -1) {
- Parser.Lex();
- Operands.push_back(MipsOperand::CreateACCReg(
- 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 = matchMSA128RegisterName(Identifier);
- if (Index != -1) {
- Parser.Lex();
- Operands.push_back(MipsOperand::CreateMSA128Reg(
- Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
+ MipsOperand *Mnemonic = static_cast<MipsOperand *>(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;
}
- Index = matchMSA128CtrlRegisterName(Identifier);
- if (Index != -1) {
- Parser.Lex();
- Operands.push_back(MipsOperand::CreateMSACtrlReg(
- Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
- return MatchOperand_Success;
+ // 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<MCConstantExpr>(ImmVal);
+ if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
+ Error(VIdx, "invalid immediate value");
+ return MatchOperand_ParseFail;
}
- return MatchOperand_NoMatch;
+ 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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &Operands,
+ int RegKind) {
+ MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
- DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
+ if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
+ return MatchOperand_NoMatch;
- return MatchOperand_NoMatch;
+ if (Parser.getTok().isNot(AsmToken::Dollar))
+ return MatchOperand_ParseFail;
+
+ 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<MCParsedAsmOperand *> &Operands) {
- DEBUG(dbgs() << "ParseAnyRegister\n");
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
- auto Token = Parser.getTok();
+ if (!isGP64())
+ return MatchOperand_NoMatch;
+ return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
+}
- SMLoc S = Token.getLoc();
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
+}
- 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::parseAFGR64Regs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+
+ if (isFP64())
return MatchOperand_NoMatch;
- }
- DEBUG(dbgs() << ".. $\n");
- Parser.Lex();
- Token = Parser.getTok();
+ return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
+}
- 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::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ if (!isFP64())
+ return MatchOperand_NoMatch;
+ return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
}
MipsAsmParser::OperandMatchResultTy
-MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
- switch (getLexer().getKind()) {
- default:
+MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
+}
+
+MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &Operands) {
- DEBUG(dbgs() << "ParseJumpTarget\n");
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &Operands) {
+ return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
+ SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
+}
+
+bool MipsAsmParser::searchSymbolAlias(
+ SmallVectorImpl<MCParsedAsmOperand *> &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<const MCSymbolRefExpr *>(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<const MCConstantExpr *>(Expr);
+ MipsOperand *op =
+ MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
+ Operands.push_back(op);
+ return true;
+ }
+ }
+ return false;
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+ return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
}
MipsAsmParser::OperandMatchResultTy
@@ -1919,12 +2215,12 @@ MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &Operands) {
+MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
switch (getLexer().getKind()) {
default:
return MatchOperand_NoMatch;
@@ -1958,7 +2254,7 @@ MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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<MCParsedAsmOperand *> &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 fc3b922602..a543840132 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 <typename InsnType>
-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 <typename InsnType>
-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 abf36daab4..04520b7a22 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 35dd39617f..5a105ffc89 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 71d0a18d48..af4fa6410c 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<OtherVT> {
let EncoderMethod = "getJumpTargetOpValue";
- let ParserMatchClass = MipsJumpTargetAsmOperand;
}
def brtarget : Operand<OtherVT> {
let EncoderMethod = "getBranchTargetOpValue";
let OperandType = "OPERAND_PCREL";
let DecoderMethod = "DecodeBranchTarget";
- let ParserMatchClass = MipsJumpTargetAsmOperand;
}
def calltarget : Operand<iPTR> {
let EncoderMethod = "getJumpTargetOpValue";
- let ParserMatchClass = MipsJumpTargetAsmOperand;
}
def simm10 : Operand<i32>;
@@ -278,11 +268,6 @@ def simm16_64 : Operand<i64> {
let DecoderMethod = "DecodeSimm16";
}
-// Zero
-def uimmz : Operand<i32> {
- let PrintMethod = "printUnsignedImm";
-}
-
// Unsigned Operand
def uimm5 : Operand<i32> {
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<i32> {
let ParserMatchClass = MipsInvertedImmoperand;
}
@@ -341,7 +332,7 @@ def mem_ea : Operand<iPTR> {
def PtrRC : Operand<iPTR> {
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 : SDNodeXForm<imm, [{
// Plus 1.
def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 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 5722c6cf00..4a30d5ae96 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<i32> {
// 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<ValueType ResTy, ValueType OpTy, CondCode CC> :
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<string instr_asm, SDPatternOperator OpNode,
RegisterOperand ROWD, RegisterOperand ROWS = ROWD,
InstrItinClass itin = NoItinerary> {
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<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32Opnd:$rt))];
+ list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32:$rt))];
InstrItinClass Itinerary = itin;
}
@@ -1438,10 +1425,10 @@ class MSA_3R_SLD_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
RegisterOperand ROWD, RegisterOperand ROWS = ROWD,
InstrItinClass itin = NoItinerary> {
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<dag> 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<string instr_asm, SDPatternOperator OpNode,
RegisterOperand ROWD, RegisterOperand ROWS = ROWD,
InstrItinClass itin = NoItinerary> {
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<dag> 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<vector_insert, v4f32,
class INSERT_FD_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE<vector_insert, v2f64,
MSA128DOpnd, FGR64Opnd>;
-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<string instr_asm, SDPatternOperator OpNode,
@@ -3202,14 +3188,10 @@ def INSERT_D : INSERT_D_ENC, INSERT_D_DESC;
// INSERT_FW_PSEUDO defined after INSVE_W
// INSERT_FD_PSEUDO defined after INSVE_D
-// There is a fourth operand that is not present in the encoding. Use a
-// custom decoder to get a chance to add it.
-let DecoderMethod = "DecodeINSVE_DF" in {
- def INSVE_B : INSVE_B_ENC, INSVE_B_DESC;
- def INSVE_H : INSVE_H_ENC, INSVE_H_DESC;
- def INSVE_W : INSVE_W_ENC, INSVE_W_DESC;
- def INSVE_D : INSVE_D_ENC, INSVE_D_DESC;
-}
+def INSVE_B : INSVE_B_ENC, INSVE_B_DESC;
+def INSVE_H : INSVE_H_ENC, INSVE_H_DESC;
+def INSVE_W : INSVE_W_ENC, INSVE_W_DESC;
+def INSVE_D : INSVE_D_ENC, INSVE_D_DESC;
def INSERT_FW_PSEUDO : INSERT_FW_PSEUDO_DESC;
def INSERT_FD_PSEUDO : INSERT_FD_PSEUDO_DESC;
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index 834e6c5fc7..f5e0bf5f00 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -209,8 +209,7 @@ let Namespace = "Mips" in {
def PC : Register<"pc">;
// 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<GPR32> {
@@ -477,11 +493,13 @@ def CCROpnd : RegisterOperand<CCR> {
}
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<HWRegs> {
@@ -525,22 +543,22 @@ def COP2Opnd : RegisterOperand<COP2> {
}
def MSA128BOpnd : RegisterOperand<MSA128B> {
- let ParserMatchClass = MSA128AsmOperand;
+ let ParserMatchClass = MSA128BAsmOperand;
}
def MSA128HOpnd : RegisterOperand<MSA128H> {
- let ParserMatchClass = MSA128AsmOperand;
+ let ParserMatchClass = MSA128HAsmOperand;
}
def MSA128WOpnd : RegisterOperand<MSA128W> {
- let ParserMatchClass = MSA128AsmOperand;
+ let ParserMatchClass = MSA128WAsmOperand;
}
def MSA128DOpnd : RegisterOperand<MSA128D> {
- let ParserMatchClass = MSA128AsmOperand;
+ let ParserMatchClass = MSA128DAsmOperand;
}
def MSA128CROpnd : RegisterOperand<MSACtrl> {
- let ParserMatchClass = MSACtrlAsmOperand;
+ let ParserMatchClass = MSA128CRAsmOperand;
}
diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp
index 0dac0b7990..218cd15baa 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 a3247b5479..0000000000
--- 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 e6f8416a41..df1054fed4 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 7f802ef765..dd4e482f38 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 703d49a4ea..f5c98f0007 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 5dbb1d3b49..dff3ae43f1 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 29c0807fff..03f5155425 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 26749a9153..7599164af0 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 bcc9f689bf..66886c5794 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 285aabbfe6..10931587e4 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 64c2ff5e78..7665d1f025 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 66f15e03c2..11ed7747b2 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 673754535b..cfd708ce66 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 3e725ea968..7279707ea0 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 4e549af9e7..e1d80199c3 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 1bd26ffa85..71f1a98fae 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