aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Mips
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
committerStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
commitfab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch)
tree268ebfd1963fd98ba412e76819afdf95a7d4267b /lib/Target/Mips
parent8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff)
parent10251753b6897adcd22cc981c0cc42f348c109de (diff)
downloadexternal_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.zip
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.gz
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.bz2
Merge commit '10251753b6897adcd22cc981c0cc42f348c109de' into merge-20130807
Conflicts: lib/Archive/ArchiveReader.cpp lib/Support/Unix/PathV2.inc Change-Id: I29d8c1e321a4a380b6013f00bac6a8e4b593cc4e
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp475
-rw-r--r--lib/Target/Mips/CMakeLists.txt3
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp115
-rw-r--r--lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp71
-rw-r--r--lib/Target/Mips/InstPrinter/MipsInstPrinter.h7
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp4
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp2
-rw-r--r--lib/Target/Mips/MicroMipsInstrInfo.td76
-rw-r--r--lib/Target/Mips/Mips.td1
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.cpp16
-rw-r--r--lib/Target/Mips/Mips16HardFloat.cpp9
-rw-r--r--lib/Target/Mips/Mips16ISelDAGToDAG.cpp8
-rw-r--r--lib/Target/Mips/Mips16ISelLowering.cpp175
-rw-r--r--lib/Target/Mips/Mips16ISelLowering.h2
-rw-r--r--lib/Target/Mips/Mips16InstrFormats.td14
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.cpp141
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.h9
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.td42
-rw-r--r--lib/Target/Mips/Mips16RegisterInfo.cpp4
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td374
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp23
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.h1
-rw-r--r--lib/Target/Mips/MipsCondMov.td221
-rw-r--r--lib/Target/Mips/MipsDSPInstrInfo.td154
-rw-r--r--lib/Target/Mips/MipsDelaySlotFiller.cpp4
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp3
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp51
-rw-r--r--lib/Target/Mips/MipsISelLowering.h6
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td409
-rw-r--r--lib/Target/Mips/MipsInstrFormats.td65
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp9
-rw-r--r--lib/Target/Mips/MipsInstrInfo.h5
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td564
-rw-r--r--lib/Target/Mips/MipsJITInfo.cpp6
-rw-r--r--lib/Target/Mips/MipsLongBranch.cpp2
-rw-r--r--lib/Target/Mips/MipsMachineFunction.cpp6
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp18
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td204
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp22
-rw-r--r--lib/Target/Mips/MipsSEISelDAGToDAG.cpp6
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.cpp74
-rw-r--r--lib/Target/Mips/MipsSEInstrInfo.cpp35
-rw-r--r--lib/Target/Mips/MipsSERegisterInfo.cpp4
-rw-r--r--lib/Target/Mips/MipsSchedule.td15
-rw-r--r--lib/Target/Mips/MipsSubtarget.cpp2
-rw-r--r--lib/Target/Mips/MipsSubtarget.h1
-rw-r--r--lib/Target/Mips/MipsTargetMachine.cpp4
-rw-r--r--lib/Target/Mips/MipsTargetMachine.h6
48 files changed, 1947 insertions, 1521 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index d1d69d8..3dd6562 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -78,19 +78,20 @@ class MipsAsmParser : public MCTargetAsmParser {
SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
- bool parseMathOperation(StringRef Name, SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands);
-
bool ParseDirective(AsmToken DirectiveID);
MipsAsmParser::OperandMatchResultTy
+ parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int RegKind);
+
+ MipsAsmParser::OperandMatchResultTy
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
- parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
- parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MipsAsmParser::OperandMatchResultTy
parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
@@ -101,8 +102,23 @@ class MipsAsmParser : public MCTargetAsmParser {
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
+ parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
+ MipsAsmParser::OperandMatchResultTy
+ parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- unsigned RegisterClass);
+ unsigned RegKind);
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
StringRef Mnemonic);
@@ -162,6 +178,8 @@ class MipsAsmParser : public MCTargetAsmParser {
int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
+ int matchFPURegisterName(StringRef Name, FpFormatTy Format);
+
void setFpFormat(FpFormatTy Format) {
FpFormat = Format;
}
@@ -172,8 +190,6 @@ class MipsAsmParser : public MCTargetAsmParser {
FpFormatTy getFpFormat() {return FpFormat;}
- bool requestsDoubleOperand(StringRef Mnemonic);
-
unsigned getReg(int RC, int RegNo);
int getATReg();
@@ -202,14 +218,16 @@ class MipsOperand : public MCParsedAsmOperand {
public:
enum RegisterKind {
Kind_None,
- Kind_CPURegs,
- Kind_CPU64Regs,
+ Kind_GPR32,
+ Kind_GPR64,
Kind_HWRegs,
Kind_HW64Regs,
Kind_FGR32Regs,
Kind_FGR64Regs,
Kind_AFGR64Regs,
- Kind_CCRRegs
+ Kind_CCRRegs,
+ Kind_FCCRegs,
+ Kind_ACRegsDSP
};
private:
@@ -354,45 +372,52 @@ public:
return Op;
}
- bool isCPURegsAsm() const {
- return Kind == k_Register && Reg.Kind == Kind_CPURegs;
+ bool isGPR32Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_GPR32;
}
- void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const {
+ void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
}
- bool isCPU64RegsAsm() const {
- return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
- }
- void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const {
- Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
+ bool isGPR64Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_GPR64;
}
bool isHWRegsAsm() const {
assert((Kind == k_Register) && "Invalid access!");
return Reg.Kind == Kind_HWRegs;
}
- void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const {
- Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
- }
bool isHW64RegsAsm() const {
assert((Kind == k_Register) && "Invalid access!");
return Reg.Kind == Kind_HW64Regs;
}
- void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const {
- Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
- }
-
- void addCCRAsmOperands(MCInst &Inst, unsigned N) const {
- Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
- }
bool isCCRAsm() const {
assert((Kind == k_Register) && "Invalid access!");
return Reg.Kind == Kind_CCRRegs;
}
+ bool isAFGR64Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
+ }
+
+ bool isFGR64Asm() const {
+ return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
+ }
+
+ bool isFGR32Asm() const {
+ return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
+ }
+
+ bool isFCCRegsAsm() const {
+ return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
+ }
+
+ bool isACRegsDSPAsm() const {
+ return Kind == k_Register && Reg.Kind == Kind_ACRegsDSP;
+ }
+
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const {
return StartLoc;
@@ -624,8 +649,8 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
unsigned ImmOffset, HiOffset, LoOffset;
const MCExpr *ExprOffset;
unsigned TmpRegNum;
- unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID
- : Mips::CPURegsRegClassID, getATReg());
+ unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
+ : Mips::GPR32RegClassID, getATReg());
// 1st operand is either the source or destination register.
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
unsigned RegOpNum = Inst.getOperand(0).getReg();
@@ -800,16 +825,7 @@ int MipsAsmParser::matchCPURegisterName(StringRef Name) {
return CC;
}
-int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
-
- if (Name.equals("fcc0"))
- return Mips::FCC0;
-
- int CC;
- CC = matchCPURegisterName(Name);
- if (CC != -1)
- return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID
- : Mips::CPURegsRegClassID);
+int MipsAsmParser::matchFPURegisterName(StringRef Name, FpFormatTy Format) {
if (Name[0] == 'f') {
StringRef NumString = Name.substr(1);
@@ -819,8 +835,6 @@ int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
if (IntVal > 31)
return -1;
- FpFormatTy Format = getFpFormat();
-
if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
return getReg(Mips::FGR32RegClassID, IntVal);
if (Format == FP_FORMAT_D) {
@@ -833,10 +847,22 @@ int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
return getReg(Mips::AFGR64RegClassID, IntVal / 2);
}
}
-
return -1;
}
+int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
+
+ if (Name.equals("fcc0"))
+ return Mips::FCC0;
+
+ int CC;
+ CC = matchCPURegisterName(Name);
+ if (CC != -1)
+ return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
+ : Mips::GPR32RegClassID);
+ return matchFPURegisterName(Name, getFpFormat());
+}
+
void MipsAsmParser::setDefaultFpFormat() {
if (isMips64() || isFP64())
@@ -845,18 +871,6 @@ void MipsAsmParser::setDefaultFpFormat() {
FpFormat = FP_FORMAT_S;
}
-bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
-
- bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
- .Case("ldxc1", true)
- .Case("ldc1", true)
- .Case("sdxc1", true)
- .Case("sdc1", true)
- .Default(false);
-
- return IsDouble;
-}
-
void MipsAsmParser::setFpFormat(StringRef Format) {
FpFormat = StringSwitch<FpFormatTy>(Format.lower())
@@ -880,7 +894,7 @@ int MipsAsmParser::getATReg() {
}
unsigned MipsAsmParser::getReg(int RC, int RegNo) {
- return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
+ return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
}
int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
@@ -900,7 +914,7 @@ int MipsAsmParser::tryParseRegister(bool is64BitReg) {
RegNum = matchRegisterName(lowerCase, is64BitReg);
} else if (Tok.is(AsmToken::Integer))
RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
- is64BitReg ? Mips::CPU64RegsRegClassID : Mips::CPURegsRegClassID);
+ is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
return RegNum;
}
@@ -1253,12 +1267,11 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
}
MipsAsmParser::OperandMatchResultTy
-MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-
- if (!isMips64())
- return MatchOperand_NoMatch;
+MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int RegKind) {
+ MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
if (getLexer().getKind() == AsmToken::Identifier) {
- if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs))
+ if (searchSymbolAlias(Operands, Kind))
return MatchOperand_Success;
return MatchOperand_NoMatch;
}
@@ -1267,17 +1280,137 @@ MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_NoMatch;
Parser.Lex(); // Eat $
- if (!tryParseRegisterOperand(Operands, true)) {
+ if (!tryParseRegisterOperand(Operands,
+ RegKind == MipsOperand::Kind_GPR64)) {
// Set the proper register kind.
MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
- op->setRegKind(MipsOperand::Kind_CPU64Regs);
+ op->setRegKind(Kind);
+ if ((Kind == 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;
}
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+
+ if (!isMips64())
+ return MatchOperand_NoMatch;
+ return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+
+ if (isFP64())
+ return MatchOperand_NoMatch;
+ // Double operand is expected, set appropriate format
+ setFpFormat(FP_FORMAT_D);
+
+ return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ if (!isFP64())
+ return MatchOperand_NoMatch;
+ // Double operand is expected, set appropriate format
+ setFpFormat(FP_FORMAT_D);
+
+ return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ // Single operand is expected, set appropriate format
+ setFpFormat(FP_FORMAT_S);
+ return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseFCCRegs(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::Identifier))
+ return MatchOperand_NoMatch;
+
+ if (!Tok.getIdentifier().startswith("fcc"))
+ return MatchOperand_NoMatch;
+
+ StringRef NumString = Tok.getIdentifier().substr(3);
+
+ unsigned IntVal;
+ if (NumString.getAsInteger(10, IntVal))
+ return MatchOperand_NoMatch;
+
+ unsigned Reg = matchRegisterByNumber(IntVal, Mips::FCCRegClassID);
+
+ MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
+ Op->setRegKind(MipsOperand::Kind_FCCRegs);
+ Operands.push_back(Op);
+
+ Parser.Lex(); // Eat the register number.
+ return MatchOperand_Success;
+}
+
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseACRegsDSP(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::Identifier))
+ return MatchOperand_NoMatch;
+
+ if (!Tok.getIdentifier().startswith("acc"))
+ return MatchOperand_NoMatch;
+
+ StringRef NumString = Tok.getIdentifier().substr(3);
+
+ unsigned IntVal;
+ if (NumString.getAsInteger(10, IntVal))
+ return MatchOperand_NoMatch;
+
+ unsigned Reg = matchRegisterByNumber(IntVal, Mips::ACRegsDSPRegClassID);
+
+ MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
+ Op->setRegKind(MipsOperand::Kind_ACRegsDSP);
+ Operands.push_back(Op);
+
+ Parser.Lex(); // Eat the register number.
+ return MatchOperand_Success;
+}
+
bool MipsAsmParser::searchSymbolAlias(
- SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) {
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
if (Sym) {
@@ -1288,6 +1421,7 @@ bool MipsAsmParser::searchSymbolAlias(
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("$")) {
@@ -1295,17 +1429,31 @@ bool MipsAsmParser::searchSymbolAlias(
APInt IntVal(32, -1);
if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
- isMips64()
- ? Mips::CPU64RegsRegClassID
- : Mips::CPURegsRegClassID);
- else
- // Lookup for the register with corresponding name
- RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
+ isMips64()
+ ? 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), FP_FORMAT_D);
+ break;
+ case MipsOperand::Kind_FGR32Regs:
+ RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S);
+ break;
+ case MipsOperand::Kind_GPR64:
+ case MipsOperand::Kind_GPR32:
+ default:
+ RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
+ break;
+ }
+ }
if (RegNum > -1) {
Parser.Lex();
MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
Parser.getTok().getLoc());
- op->setRegKind((MipsOperand::RegisterKind) RegisterKind);
+ op->setRegKind(Kind);
Operands.push_back(op);
return true;
}
@@ -1314,7 +1462,7 @@ bool MipsAsmParser::searchSymbolAlias(
Parser.Lex();
const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
MipsOperand *op = MipsOperand::CreateImm(Const, S,
- Parser.getTok().getLoc());
+ Parser.getTok().getLoc());
Operands.push_back(op);
return true;
}
@@ -1323,33 +1471,8 @@ bool MipsAsmParser::searchSymbolAlias(
}
MipsAsmParser::OperandMatchResultTy
-MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-
- if (getLexer().getKind() == AsmToken::Identifier) {
- if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs))
- return MatchOperand_Success;
- return MatchOperand_NoMatch;
- }
- // If the first token is not '$' we have an error.
- if (Parser.getTok().isNot(AsmToken::Dollar))
- return MatchOperand_NoMatch;
-
- Parser.Lex(); // Eat $
- if (!tryParseRegisterOperand(Operands, false)) {
- // Set the proper register kind.
- MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
- op->setRegKind(MipsOperand::Kind_CPURegs);
- return MatchOperand_Success;
- }
- return MatchOperand_NoMatch;
-}
-
-MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- if (isMips64())
- return MatchOperand_NoMatch;
-
// If the first token is not '$' we have error.
if (Parser.getTok().isNot(AsmToken::Dollar))
return MatchOperand_NoMatch;
@@ -1406,30 +1529,23 @@ MipsAsmParser::parseHW64Regs(
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- unsigned RegNum;
// 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.is(AsmToken::Integer)) {
- RegNum = Tok.getIntVal();
- // At the moment only fcc0 is supported.
- if (RegNum != 0)
- return MatchOperand_ParseFail;
- } else if (Tok.is(AsmToken::Identifier)) {
- // At the moment only fcc0 is supported.
- if (Tok.getIdentifier() != "fcc0")
- return MatchOperand_ParseFail;
- } else
+
+ if (Tok.isNot(AsmToken::Integer))
return MatchOperand_NoMatch;
- MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
- Parser.getTok().getLoc());
- op->setRegKind(MipsOperand::Kind_CCRRegs);
- Operands.push_back(op);
+ unsigned Reg = matchRegisterByNumber(Tok.getIntVal(), Mips::CCRRegClassID);
+
+ MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
+ Op->setRegKind(MipsOperand::Kind_CCRRegs);
+ Operands.push_back(Op);
Parser.Lex(); // Eat the register number.
return MatchOperand_Success;
@@ -1460,136 +1576,22 @@ MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
return VK;
}
-// Converts condition string to immediate operand value.
-static int ConvertCcString(StringRef CondString) {
- int CC = StringSwitch<unsigned>(CondString)
- .Case(".f", 0)
- .Case(".un", 1)
- .Case(".eq", 2)
- .Case(".ueq", 3)
- .Case(".olt", 4)
- .Case(".ult", 5)
- .Case(".ole", 6)
- .Case(".ule", 7)
- .Case(".sf", 8)
- .Case(".ngle", 9)
- .Case(".seq", 10)
- .Case(".ngl", 11)
- .Case(".lt", 12)
- .Case(".nge", 13)
- .Case(".le", 14)
- .Case(".ngt", 15)
- .Default(-1);
-
- return CC;
-}
-
-bool MipsAsmParser::
-parseMathOperation(StringRef Name, SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- // Split the format.
- size_t Start = Name.find('.'), Next = Name.rfind('.');
- StringRef Format1 = Name.slice(Start, Next);
- // Add the first format to the operands.
- Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
- // Now for the second format.
- StringRef Format2 = Name.slice(Next, StringRef::npos);
- Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
-
- // Set the format for the first register.
- setFpFormat(Format1);
-
- // Read the remaining operands.
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- // Read the first operand.
- if (ParseOperand(Operands, Name)) {
- SMLoc Loc = getLexer().getLoc();
- Parser.eatToEndOfStatement();
- return Error(Loc, "unexpected token in argument list");
- }
-
- if (getLexer().isNot(AsmToken::Comma)) {
- SMLoc Loc = getLexer().getLoc();
- Parser.eatToEndOfStatement();
- return Error(Loc, "unexpected token in argument list");
- }
- Parser.Lex(); // Eat the comma.
-
- // Set the format for the first register
- setFpFormat(Format2);
-
- // Parse and remember the operand.
- if (ParseOperand(Operands, Name)) {
- SMLoc Loc = getLexer().getLoc();
- Parser.eatToEndOfStatement();
- return Error(Loc, "unexpected token in argument list");
- }
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- SMLoc Loc = getLexer().getLoc();
- Parser.eatToEndOfStatement();
- return Error(Loc, "unexpected token in argument list");
- }
-
- Parser.Lex(); // Consume the EndOfStatement.
- return false;
-}
bool MipsAsmParser::
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- StringRef Mnemonic;
- // Floating point instructions: Should the register be treated as a double?
- if (requestsDoubleOperand(Name)) {
- setFpFormat(FP_FORMAT_D);
- Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
- Mnemonic = Name;
- } else {
- setDefaultFpFormat();
- // Create the leading tokens for the mnemonic, split by '.' characters.
- size_t Start = 0, Next = Name.find('.');
- Mnemonic = Name.slice(Start, Next);
-
- Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
-
- if (Next != StringRef::npos) {
- // There is a format token in mnemonic.
- size_t Dot = Name.find('.', Next + 1);
- StringRef Format = Name.slice(Next, Dot);
- if (Dot == StringRef::npos) // Only one '.' in a string, it's a format.
- Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
- else {
- if (Name.startswith("c.")) {
- // Floating point compare, add '.' and immediate represent for cc.
- Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
- int Cc = ConvertCcString(Format);
- if (Cc == -1) {
- return Error(NameLoc, "Invalid conditional code");
- }
- SMLoc E = SMLoc::getFromPointer(
- Parser.getTok().getLoc().getPointer() - 1);
- Operands.push_back(
- MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()),
- NameLoc, E));
- } else {
- // trunc, ceil, floor ...
- return parseMathOperation(Name, NameLoc, Operands);
- }
-
- // The rest is a format.
- Format = Name.slice(Dot, StringRef::npos);
- Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
- }
-
- setFpFormat(Format);
- }
+ // 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));
// Read the remaining operands.
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
- if (ParseOperand(Operands, Mnemonic)) {
+ if (ParseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
@@ -1597,7 +1599,6 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
while (getLexer().is(AsmToken::Comma)) {
Parser.Lex(); // Eat the comma.
-
// Parse and remember the operand.
if (ParseOperand(Operands, Name)) {
SMLoc Loc = getLexer().getLoc();
@@ -1606,13 +1607,11 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
}
}
}
-
if (getLexer().isNot(AsmToken::EndOfStatement)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
}
-
Parser.Lex(); // Consume the EndOfStatement.
return false;
}
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt
index 834a998..aedb78b 100644
--- a/lib/Target/Mips/CMakeLists.txt
+++ b/lib/Target/Mips/CMakeLists.txt
@@ -48,10 +48,11 @@ add_llvm_target(MipsCodeGen
MipsSelectionDAGInfo.cpp
)
-add_dependencies(LLVMMipsCodeGen intrinsics_gen)
+add_dependencies(LLVMMipsCodeGen MipsCommonTableGen intrinsics_gen)
add_subdirectory(InstPrinter)
add_subdirectory(Disassembler)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)
add_subdirectory(AsmParser)
+
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index 4af6703..d99df4d 100644
--- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -39,10 +39,10 @@ public:
virtual ~MipsDisassemblerBase() {}
- const MCRegisterInfo *getRegInfo() const { return RegInfo; }
+ const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
private:
- const MCRegisterInfo *RegInfo;
+ OwningPtr<const MCRegisterInfo> RegInfo;
protected:
bool isBigEndian;
};
@@ -88,20 +88,20 @@ public:
// Forward declare these because the autogenerated code will reference them.
// Definitions are further down.
-static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
@@ -123,6 +123,11 @@ static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
unsigned Insn,
uint64_t Address,
@@ -133,11 +138,6 @@ static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder);
-
static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@@ -158,12 +158,6 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeBC1(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder);
-
-
static DecodeStatus DecodeJumpTarget(MCInst &Inst,
unsigned Insn,
uint64_t Address,
@@ -183,11 +177,6 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeCondCode(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder);
-
static DecodeStatus DecodeInsSize(MCInst &Inst,
unsigned Insn,
uint64_t Address,
@@ -346,26 +335,26 @@ static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
}
-static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder) {
+static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
- unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
+ unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Inst.addOperand(MCOperand::CreateReg(Reg));
return MCDisassembler::Success;
}
-static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder) {
+static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
- unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
+ unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Inst.addOperand(MCOperand::CreateReg(Reg));
return MCDisassembler::Success;
}
@@ -374,7 +363,7 @@ static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
- return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
+ return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
}
static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
@@ -405,7 +394,21 @@ static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
- Inst.addOperand(MCOperand::CreateReg(RegNo));
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+ unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 7)
+ return MCDisassembler::Fail;
+ unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Reg));
return MCDisassembler::Success;
}
@@ -417,8 +420,8 @@ static DecodeStatus DecodeMem(MCInst &Inst,
unsigned Reg = fieldFromInstruction(Insn, 16, 5);
unsigned Base = fieldFromInstruction(Insn, 21, 5);
- Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
- Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
+ Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
+ Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
if(Inst.getOpcode() == Mips::SC){
Inst.addOperand(MCOperand::CreateReg(Reg));
@@ -440,7 +443,7 @@ static DecodeStatus DecodeFMem(MCInst &Inst,
unsigned Base = fieldFromInstruction(Insn, 21, 5);
Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
- Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
+ Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Inst.addOperand(MCOperand::CreateReg(Reg));
Inst.addOperand(MCOperand::CreateReg(Base));
@@ -461,15 +464,6 @@ static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeCondCode(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder) {
- int CondCode = Insn & 0xf;
- Inst.addOperand(MCOperand::CreateImm(CondCode));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@@ -483,17 +477,6 @@ static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
- unsigned RegNo,
- uint64_t Address,
- const void *Decoder) {
- //Currently only hardware register 29 is supported
- if (RegNo != 29)
- return MCDisassembler::Fail;
- Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@@ -540,16 +523,6 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeBC1(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder) {
- unsigned BranchOffset = Insn & 0xffff;
- BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
- Inst.addOperand(MCOperand::CreateImm(BranchOffset));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeJumpTarget(MCInst &Inst,
unsigned Insn,
uint64_t Address,
diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
index fc23cd3..369fece 100644
--- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
@@ -26,6 +26,12 @@ using namespace llvm;
#define PRINT_ALIAS_INSTR
#include "MipsGenAsmWriter.inc"
+template<unsigned R>
+static bool isReg(const MCInst &MI, unsigned OpNo) {
+ assert(MI.getOperand(OpNo).isReg() && "Register operand expected.");
+ return MI.getOperand(OpNo).getReg() == R;
+}
+
const char* Mips::MipsFCCToString(Mips::CondCode CC) {
switch (CC) {
case FCOND_F:
@@ -80,7 +86,7 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
}
// Try to print any aliases first.
- if (!printAliasInstr(MI, O))
+ if (!printAliasInstr(MI, O) && !printAlias(*MI, O))
printInstruction(MI, O);
printAnnotation(O, Annot);
@@ -152,11 +158,6 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
OS << ')';
}
-void MipsInstPrinter::printCPURegs(const MCInst *MI, unsigned OpNo,
- raw_ostream &O) {
- printRegName(O, MI->getOperand(OpNo).getReg());
-}
-
void MipsInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
@@ -209,3 +210,61 @@ printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) {
const MCOperand& MO = MI->getOperand(opNum);
O << MipsFCCToString((Mips::CondCode)MO.getImm());
}
+
+bool MipsInstPrinter::printAlias(const char *Str, const MCInst &MI,
+ unsigned OpNo, raw_ostream &OS) {
+ OS << "\t" << Str << "\t";
+ printOperand(&MI, OpNo, OS);
+ return true;
+}
+
+bool MipsInstPrinter::printAlias(const char *Str, const MCInst &MI,
+ unsigned OpNo0, unsigned OpNo1,
+ raw_ostream &OS) {
+ printAlias(Str, MI, OpNo0, OS);
+ OS << ", ";
+ printOperand(&MI, OpNo1, OS);
+ return true;
+}
+
+bool MipsInstPrinter::printAlias(const MCInst &MI, raw_ostream &OS) {
+ switch (MI.getOpcode()) {
+ case Mips::BEQ:
+ // beq $r0, $zero, $L2 => beqz $r0, $L2
+ return isReg<Mips::ZERO>(MI, 1) && printAlias("beqz", MI, 0, 2, OS);
+ case Mips::BEQ64:
+ // beq $r0, $zero, $L2 => beqz $r0, $L2
+ return isReg<Mips::ZERO_64>(MI, 1) && printAlias("beqz", MI, 0, 2, OS);
+ case Mips::BNE:
+ // bne $r0, $zero, $L2 => bnez $r0, $L2
+ return isReg<Mips::ZERO>(MI, 1) && printAlias("bnez", MI, 0, 2, OS);
+ case Mips::BNE64:
+ // bne $r0, $zero, $L2 => bnez $r0, $L2
+ return isReg<Mips::ZERO_64>(MI, 1) && printAlias("bnez", MI, 0, 2, OS);
+ case Mips::BGEZAL:
+ // bgezal $zero, $L1 => bal $L1
+ return isReg<Mips::ZERO>(MI, 0) && printAlias("bal", MI, 1, OS);
+ case Mips::BC1T:
+ // bc1t $fcc0, $L1 => bc1t $L1
+ return isReg<Mips::FCC0>(MI, 0) && printAlias("bc1t", MI, 1, OS);
+ case Mips::BC1F:
+ // bc1f $fcc0, $L1 => bc1f $L1
+ return isReg<Mips::FCC0>(MI, 0) && printAlias("bc1f", MI, 1, OS);
+ case Mips::JALR:
+ // jalr $ra, $r1 => jalr $r1
+ return isReg<Mips::RA>(MI, 0) && printAlias("jalr", MI, 1, OS);
+ case Mips::JALR64:
+ // jalr $ra, $r1 => jalr $r1
+ return isReg<Mips::RA_64>(MI, 0) && printAlias("jalr", MI, 1, OS);
+ case Mips::NOR:
+ // nor $r0, $r1, $zero => not $r0, $r1
+ return isReg<Mips::ZERO>(MI, 2) && printAlias("not", MI, 0, 1, OS);
+ case Mips::NOR64:
+ // nor $r0, $r1, $zero => not $r0, $r1
+ return isReg<Mips::ZERO_64>(MI, 2) && printAlias("not", MI, 0, 1, OS);
+ case Mips::OR:
+ // or $r0, $r1, $zero => move $r0, $r1
+ return isReg<Mips::ZERO>(MI, 2) && printAlias("move", MI, 0, 1, OS);
+ default: return false;
+ }
+}
diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
index d1b561f..1253ab0 100644
--- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
+++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
@@ -87,7 +87,6 @@ public:
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
- void printCPURegs(const MCInst *MI, unsigned OpNo, raw_ostream &O);
bool printAliasInstr(const MCInst *MI, raw_ostream &OS);
@@ -97,6 +96,12 @@ private:
void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O);
void printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O);
void printFCCOperand(const MCInst *MI, int opNum, raw_ostream &O);
+
+ bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo,
+ raw_ostream &OS);
+ bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo0,
+ unsigned OpNo1, raw_ostream &OS);
+ bool printAlias(const MCInst &MI, raw_ostream &OS);
};
} // end namespace llvm
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index c33bc9a..cfcb877 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -36,6 +36,10 @@ namespace llvm {
MCAssembler& MCA = getAssembler();
unsigned EFlags = MCA.getELFHeaderEFlags();
+ // TODO: Need to add -mabicalls and -mno-abicalls flags.
+ // Currently we assume that -mabicalls is the default.
+ EFlags |= ELF::EF_MIPS_CPIC;
+
if (Subtarget.inMips16Mode())
EFlags |= ELF::EF_MIPS_ARCH_ASE_M16;
else
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index a464dfe..4dc6917 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -380,7 +380,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups) const {
if (MO.isReg()) {
unsigned Reg = MO.getReg();
- unsigned RegNo = Ctx.getRegisterInfo().getEncodingValue(Reg);
+ unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
return RegNo;
} else if (MO.isImm()) {
return static_cast<unsigned>(MO.getImm());
diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td
index 7a42719..249d712 100644
--- a/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -1,69 +1,67 @@
let isCodeGenOnly = 1 in {
/// Arithmetic Instructions (ALU Immediate)
- def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd>,
+ def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>,
ADDI_FM_MM<0xc>;
- def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>,
+ def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>,
ADDI_FM_MM<0x4>;
- def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>,
+ def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
SLTI_FM_MM<0x24>;
- def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>,
+ def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
SLTI_FM_MM<0x2c>;
- def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16,
- and>,
+ def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>,
ADDI_FM_MM<0x34>;
- def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>,
+ def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>,
ADDI_FM_MM<0x14>;
- def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16,
- xor>,
+ def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd>,
ADDI_FM_MM<0x1c>;
- def LUi_MM : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM_MM;
+ def LUi_MM : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM_MM;
/// Arithmetic Instructions (3-Operand, R-Type)
- def ADDu_MM : MMRel, ArithLogicR<"addu", CPURegsOpnd>, ADD_FM_MM<0, 0x150>;
- def SUBu_MM : MMRel, ArithLogicR<"subu", CPURegsOpnd>, ADD_FM_MM<0, 0x1d0>;
- def MUL_MM : MMRel, ArithLogicR<"mul", CPURegsOpnd>, ADD_FM_MM<0, 0x210>;
- def ADD_MM : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM_MM<0, 0x110>;
- def SUB_MM : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM_MM<0, 0x190>;
- def SLT_MM : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM_MM<0, 0x350>;
- def SLTu_MM : MMRel, SetCC_R<"sltu", setult, CPURegs>,
+ def ADDu_MM : MMRel, ArithLogicR<"addu", GPR32Opnd>, ADD_FM_MM<0, 0x150>;
+ def SUBu_MM : MMRel, ArithLogicR<"subu", GPR32Opnd>, ADD_FM_MM<0, 0x1d0>;
+ def MUL_MM : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>;
+ def ADD_MM : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>;
+ def SUB_MM : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>;
+ def SLT_MM : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>;
+ def SLTu_MM : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>,
ADD_FM_MM<0, 0x390>;
- def AND_MM : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>,
+ def AND_MM : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IIAlu, and>,
ADD_FM_MM<0, 0x250>;
- def OR_MM : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>,
+ def OR_MM : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IIAlu, or>,
ADD_FM_MM<0, 0x290>;
- def XOR_MM : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>,
+ def XOR_MM : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IIAlu, xor>,
ADD_FM_MM<0, 0x310>;
- def NOR_MM : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM_MM<0, 0x2d0>;
- def MULT_MM : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>,
+ def NOR_MM : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM_MM<0, 0x2d0>;
+ def MULT_MM : MMRel, Mult<"mult", IIImul, GPR32Opnd, [HI, LO]>,
MULT_FM_MM<0x22c>;
- def MULTu_MM : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>,
+ def MULTu_MM : MMRel, Mult<"multu", IIImul, GPR32Opnd, [HI, LO]>,
MULT_FM_MM<0x26c>;
/// Shift Instructions
- def SLL_MM : MMRel, shift_rotate_imm<"sll", shamt, CPURegsOpnd>,
+ def SLL_MM : MMRel, shift_rotate_imm<"sll", shamt, GPR32Opnd>,
SRA_FM_MM<0, 0>;
- def SRL_MM : MMRel, shift_rotate_imm<"srl", shamt, CPURegsOpnd>,
+ def SRL_MM : MMRel, shift_rotate_imm<"srl", shamt, GPR32Opnd>,
SRA_FM_MM<0x40, 0>;
- def SRA_MM : MMRel, shift_rotate_imm<"sra", shamt, CPURegsOpnd>,
+ def SRA_MM : MMRel, shift_rotate_imm<"sra", shamt, GPR32Opnd>,
SRA_FM_MM<0x80, 0>;
- def SLLV_MM : MMRel, shift_rotate_reg<"sllv", CPURegsOpnd>,
+ def SLLV_MM : MMRel, shift_rotate_reg<"sllv", GPR32Opnd>,
SRLV_FM_MM<0x10, 0>;
- def SRLV_MM : MMRel, shift_rotate_reg<"srlv", CPURegsOpnd>,
+ def SRLV_MM : MMRel, shift_rotate_reg<"srlv", GPR32Opnd>,
SRLV_FM_MM<0x50, 0>;
- def SRAV_MM : MMRel, shift_rotate_reg<"srav", CPURegsOpnd>,
+ def SRAV_MM : MMRel, shift_rotate_reg<"srav", GPR32Opnd>,
SRLV_FM_MM<0x90, 0>;
- def ROTR_MM : MMRel, shift_rotate_imm<"rotr", shamt, CPURegsOpnd>,
+ def ROTR_MM : MMRel, shift_rotate_imm<"rotr", shamt, GPR32Opnd>,
SRA_FM_MM<0xc0, 0>;
- def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", CPURegsOpnd>,
+ def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd>,
SRLV_FM_MM<0xd0, 0>;
/// Load and Store Instructions - aligned
- defm LB_MM : LoadM<"lb", CPURegs, sextloadi8>, MMRel, LW_FM_MM<0x7>;
- defm LBu_MM : LoadM<"lbu", CPURegs, zextloadi8>, MMRel, LW_FM_MM<0x5>;
- defm LH_MM : LoadM<"lh", CPURegs, sextloadi16>, MMRel, LW_FM_MM<0xf>;
- defm LHu_MM : LoadM<"lhu", CPURegs, zextloadi16>, MMRel, LW_FM_MM<0xd>;
- defm LW_MM : LoadM<"lw", CPURegs>, MMRel, LW_FM_MM<0x3f>;
- defm SB_MM : StoreM<"sb", CPURegs, truncstorei8>, MMRel, LW_FM_MM<0x6>;
- defm SH_MM : StoreM<"sh", CPURegs, truncstorei16>, MMRel, LW_FM_MM<0xe>;
- defm SW_MM : StoreM<"sw", CPURegs>, MMRel, LW_FM_MM<0x3e>;
+ defm LB_MM : LoadM<"lb", GPR32Opnd, sextloadi8>, MMRel, LW_FM_MM<0x7>;
+ defm LBu_MM : LoadM<"lbu", GPR32Opnd, zextloadi8>, MMRel, LW_FM_MM<0x5>;
+ defm LH_MM : LoadM<"lh", GPR32Opnd, sextloadi16>, MMRel, LW_FM_MM<0xf>;
+ defm LHu_MM : LoadM<"lhu", GPR32Opnd, zextloadi16>, MMRel, LW_FM_MM<0xd>;
+ defm LW_MM : LoadM<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>;
+ defm SB_MM : StoreM<"sb", GPR32Opnd, truncstorei8>, MMRel, LW_FM_MM<0x6>;
+ defm SH_MM : StoreM<"sh", GPR32Opnd, truncstorei16>, MMRel, LW_FM_MM<0xe>;
+ defm SW_MM : StoreM<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>;
}
diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td
index eefb02a..2595e41 100644
--- a/lib/Target/Mips/Mips.td
+++ b/lib/Target/Mips/Mips.td
@@ -101,6 +101,7 @@ def MipsAsmWriter : AsmWriter {
def MipsAsmParser : AsmParser {
let ShouldEmitMatchRegisterName = 0;
+ let MnemonicContainsDot = 1;
}
def MipsAsmParserVariant : AsmParserVariant {
diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp
index e180c49..6655ff9 100644
--- a/lib/Target/Mips/Mips16FrameLowering.cpp
+++ b/lib/Target/Mips/Mips16FrameLowering.cpp
@@ -40,7 +40,7 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const {
if (StackSize == 0 && !MFI->adjustsStack()) return;
MachineModuleInfo &MMI = MF.getMMI();
- const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo();
+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
MachineLocation DstML, SrcML;
// Adjust stack.
@@ -56,13 +56,16 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const {
MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
- unsigned S1 = MRI.getDwarfRegNum(Mips::S1, true);
- MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -8));
+ unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true);
+ MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8));
- unsigned S0 = MRI.getDwarfRegNum(Mips::S0, true);
- MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -12));
+ unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true);
+ MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12));
- unsigned RA = MRI.getDwarfRegNum(Mips::RA, true);
+ unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true);
+ MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16));
+
+ unsigned RA = MRI->getDwarfRegNum(Mips::RA, true);
MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4));
if (hasFP(MF))
@@ -168,6 +171,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
MF.getRegInfo().setPhysRegUsed(Mips::RA);
MF.getRegInfo().setPhysRegUsed(Mips::S0);
MF.getRegInfo().setPhysRegUsed(Mips::S1);
+ MF.getRegInfo().setPhysRegUsed(Mips::S2);
}
const MipsFrameLowering *
diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp
index 45dd5d7..7e456aa 100644
--- a/lib/Target/Mips/Mips16HardFloat.cpp
+++ b/lib/Target/Mips/Mips16HardFloat.cpp
@@ -247,7 +247,7 @@ static void assureFPCallStub(Function &F, Module *M,
bool LE = Subtarget.isLittle();
std::string Name = F.getName();
std::string SectionName = ".mips16.call.fp." + Name;
- std::string StubName = "__call_stub_" + Name;
+ std::string StubName = "__call_stub_fp_" + Name;
//
// see if we already have the stub
//
@@ -257,11 +257,13 @@ static void assureFPCallStub(Function &F, Module *M,
Function::InternalLinkage, StubName, M);
FStub->addFnAttr("mips16_fp_stub");
FStub->addFnAttr(llvm::Attribute::Naked);
+ FStub->addFnAttr(llvm::Attribute::NoInline);
FStub->addFnAttr(llvm::Attribute::NoUnwind);
FStub->addFnAttr("nomips16");
FStub->setSection(SectionName);
BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
InlineAsmHelper IAH(Context, BB);
+ IAH.Out(".set reorder");
FPReturnVariant RV = whichFPReturnVariant(FStub->getReturnType());
FPParamVariant PV = whichFPParamVariantNeeded(F);
swapFPIntParams(PV, M, IAH, LE, true);
@@ -361,6 +363,8 @@ static bool fixupFPReturnAndCall
"__Mips16RetHelper");
A = A.addAttribute(C, AttributeSet::FunctionIndex,
Attribute::ReadNone);
+ A = A.addAttribute(C, AttributeSet::FunctionIndex,
+ Attribute::NoInline);
Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL));
CallInst::Create(F, Params, "", &Inst );
} else if (const CallInst *CI = dyn_cast<CallInst>(I)) {
@@ -389,10 +393,11 @@ static void createFPFnStub(Function *F, Module *M, FPParamVariant PV,
std::string LocalName = "__fn_local_" + Name;
Function *FStub = Function::Create
(F->getFunctionType(),
- Function::ExternalLinkage, StubName, M);
+ Function::InternalLinkage, StubName, M);
FStub->addFnAttr("mips16_fp_stub");
FStub->addFnAttr(llvm::Attribute::Naked);
FStub->addFnAttr(llvm::Attribute::NoUnwind);
+ FStub->addFnAttr(llvm::Attribute::NoInline);
FStub->addFnAttr("nomips16");
FStub->setSection(SectionName);
BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
diff --git a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
index f70abda..0caa277 100644
--- a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
+++ b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp
@@ -118,11 +118,13 @@ void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() {
unsigned Mips16SPAliasReg =
MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg();
- return CurDAG->getRegister(Mips16SPAliasReg, TLI->getPointerTy());
+ return CurDAG->getRegister(Mips16SPAliasReg,
+ getTargetLowering()->getPointerTy());
}
void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {
- SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI->getPointerTy());
+ SDValue AliasFPReg = CurDAG->getRegister(Mips::S0,
+ getTargetLowering()->getPointerTy());
if (Parent) {
switch (Parent->getOpcode()) {
case ISD::LOAD: {
@@ -149,7 +151,7 @@ void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {
}
}
}
- AliasReg = CurDAG->getRegister(Mips::SP, TLI->getPointerTy());
+ AliasReg = CurDAG->getRegister(Mips::SP, getTargetLowering()->getPointerTy());
return;
}
diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp
index d8dd88c..6ed1d9e 100644
--- a/lib/Target/Mips/Mips16ISelLowering.cpp
+++ b/lib/Target/Mips/Mips16ISelLowering.cpp
@@ -18,7 +18,6 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
-#include <set>
using namespace llvm;
@@ -30,15 +29,97 @@ static cl::opt<bool> DontExpandCondPseudos16(
cl::Hidden);
namespace {
- std::set<const char*, MipsTargetLowering::LTStr> NoHelperNeeded;
+struct Mips16Libcall {
+ RTLIB::Libcall Libcall;
+ const char *Name;
+
+ bool operator<(const Mips16Libcall &RHS) const {
+ return std::strcmp(Name, RHS.Name) < 0;
+ }
+};
+
+struct Mips16IntrinsicHelperType{
+ const char* Name;
+ const char* Helper;
+
+ bool operator<(const Mips16IntrinsicHelperType &RHS) const {
+ return std::strcmp(Name, RHS.Name) < 0;
+ }
+ bool operator==(const Mips16IntrinsicHelperType &RHS) const {
+ return std::strcmp(Name, RHS.Name) == 0;
+ }
+};
}
+// Libcalls for which no helper is generated. Sorted by name for binary search.
+static const Mips16Libcall HardFloatLibCalls[] = {
+ { RTLIB::ADD_F64, "__mips16_adddf3" },
+ { RTLIB::ADD_F32, "__mips16_addsf3" },
+ { RTLIB::DIV_F64, "__mips16_divdf3" },
+ { RTLIB::DIV_F32, "__mips16_divsf3" },
+ { RTLIB::OEQ_F64, "__mips16_eqdf2" },
+ { RTLIB::OEQ_F32, "__mips16_eqsf2" },
+ { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" },
+ { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" },
+ { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" },
+ { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" },
+ { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" },
+ { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" },
+ { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" },
+ { RTLIB::OGE_F64, "__mips16_gedf2" },
+ { RTLIB::OGE_F32, "__mips16_gesf2" },
+ { RTLIB::OGT_F64, "__mips16_gtdf2" },
+ { RTLIB::OGT_F32, "__mips16_gtsf2" },
+ { RTLIB::OLE_F64, "__mips16_ledf2" },
+ { RTLIB::OLE_F32, "__mips16_lesf2" },
+ { RTLIB::OLT_F64, "__mips16_ltdf2" },
+ { RTLIB::OLT_F32, "__mips16_ltsf2" },
+ { RTLIB::MUL_F64, "__mips16_muldf3" },
+ { RTLIB::MUL_F32, "__mips16_mulsf3" },
+ { RTLIB::UNE_F64, "__mips16_nedf2" },
+ { RTLIB::UNE_F32, "__mips16_nesf2" },
+ { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall.
+ { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall.
+ { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall.
+ { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall.
+ { RTLIB::SUB_F64, "__mips16_subdf3" },
+ { RTLIB::SUB_F32, "__mips16_subsf3" },
+ { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" },
+ { RTLIB::UO_F64, "__mips16_unorddf2" },
+ { RTLIB::UO_F32, "__mips16_unordsf2" }
+};
+
+static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
+ {"ceil", "__mips16_call_stub_df_2"},
+ {"ceilf", "__mips16_call_stub_sf_1"},
+ {"copysign", "__mips16_call_stub_df_10"},
+ {"copysignf", "__mips16_call_stub_sf_5"},
+ {"cos", "__mips16_call_stub_df_2"},
+ {"cosf", "__mips16_call_stub_sf_1"},
+ {"exp2", "__mips16_call_stub_df_2"},
+ {"exp2f", "__mips16_call_stub_sf_1"},
+ {"floor", "__mips16_call_stub_df_2"},
+ {"floorf", "__mips16_call_stub_sf_1"},
+ {"log2", "__mips16_call_stub_df_2"},
+ {"log2f", "__mips16_call_stub_sf_1"},
+ {"nearbyint", "__mips16_call_stub_df_2"},
+ {"nearbyintf", "__mips16_call_stub_sf_1"},
+ {"rint", "__mips16_call_stub_df_2"},
+ {"rintf", "__mips16_call_stub_sf_1"},
+ {"sin", "__mips16_call_stub_df_2"},
+ {"sinf", "__mips16_call_stub_sf_1"},
+ {"sqrt", "__mips16_call_stub_df_2"},
+ {"sqrtf", "__mips16_call_stub_sf_1"},
+ {"trunc", "__mips16_call_stub_df_2"},
+ {"truncf", "__mips16_call_stub_sf_1"},
+};
+
Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM)
: MipsTargetLowering(TM) {
//
// set up as if mips32 and then revert so we can test the mechanism
// for switching
- addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
+ addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
computeRegisterProperties();
clearRegisterClasses();
@@ -46,13 +127,9 @@ Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM)
// Set up the register classes
addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
- if (Subtarget->inMips16HardFloat()) {
+ if (Subtarget->inMips16HardFloat())
setMips16HardFloatLibCalls();
- NoHelperNeeded.insert("__mips16_ret_sf");
- NoHelperNeeded.insert("__mips16_ret_df");
- NoHelperNeeded.insert("__mips16_ret_sc");
- NoHelperNeeded.insert("__mips16_ret_dc");
- }
+
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Expand);
setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Expand);
@@ -166,47 +243,17 @@ isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
return false;
}
-void Mips16TargetLowering::setMips16LibcallName
- (RTLIB::Libcall L, const char *Name) {
- setLibcallName(L, Name);
- NoHelperNeeded.insert(Name);
-}
-
void Mips16TargetLowering::setMips16HardFloatLibCalls() {
- setMips16LibcallName(RTLIB::ADD_F32, "__mips16_addsf3");
- setMips16LibcallName(RTLIB::ADD_F64, "__mips16_adddf3");
- setMips16LibcallName(RTLIB::SUB_F32, "__mips16_subsf3");
- setMips16LibcallName(RTLIB::SUB_F64, "__mips16_subdf3");
- setMips16LibcallName(RTLIB::MUL_F32, "__mips16_mulsf3");
- setMips16LibcallName(RTLIB::MUL_F64, "__mips16_muldf3");
- setMips16LibcallName(RTLIB::DIV_F32, "__mips16_divsf3");
- setMips16LibcallName(RTLIB::DIV_F64, "__mips16_divdf3");
- setMips16LibcallName(RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2");
- setMips16LibcallName(RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2");
- setMips16LibcallName(RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi");
- setMips16LibcallName(RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi");
- setMips16LibcallName(RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf");
- setMips16LibcallName(RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf");
- setMips16LibcallName(RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf");
- setMips16LibcallName(RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf");
- setMips16LibcallName(RTLIB::OEQ_F32, "__mips16_eqsf2");
- setMips16LibcallName(RTLIB::OEQ_F64, "__mips16_eqdf2");
- setMips16LibcallName(RTLIB::UNE_F32, "__mips16_nesf2");
- setMips16LibcallName(RTLIB::UNE_F64, "__mips16_nedf2");
- setMips16LibcallName(RTLIB::OGE_F32, "__mips16_gesf2");
- setMips16LibcallName(RTLIB::OGE_F64, "__mips16_gedf2");
- setMips16LibcallName(RTLIB::OLT_F32, "__mips16_ltsf2");
- setMips16LibcallName(RTLIB::OLT_F64, "__mips16_ltdf2");
- setMips16LibcallName(RTLIB::OLE_F32, "__mips16_lesf2");
- setMips16LibcallName(RTLIB::OLE_F64, "__mips16_ledf2");
- setMips16LibcallName(RTLIB::OGT_F32, "__mips16_gtsf2");
- setMips16LibcallName(RTLIB::OGT_F64, "__mips16_gtdf2");
- setMips16LibcallName(RTLIB::UO_F32, "__mips16_unordsf2");
- setMips16LibcallName(RTLIB::UO_F64, "__mips16_unorddf2");
- setMips16LibcallName(RTLIB::O_F32, "__mips16_unordsf2");
- setMips16LibcallName(RTLIB::O_F64, "__mips16_unorddf2");
-}
+ for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) {
+ assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
+ "Array not sorted!");
+ if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL)
+ setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name);
+ }
+ setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
+ setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
+}
//
// The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
@@ -383,16 +430,34 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
//
bool LookupHelper = true;
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
- if (NoHelperNeeded.find(S->getSymbol()) != NoHelperNeeded.end()) {
+ Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
+
+ if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
+ Find))
LookupHelper = false;
+ else {
+ Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
+ // one more look at list of intrinsics
+ if (std::binary_search(Mips16IntrinsicHelper,
+ array_endof(Mips16IntrinsicHelper),
+ IntrinsicFind)) {
+ const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper,
+ array_endof(Mips16IntrinsicHelper),
+ IntrinsicFind));
+ Mips16HelperFunction = h->Helper;
+ NeedMips16Helper = true;
+ LookupHelper = false;
+ }
+
}
- }
- else if (GlobalAddressSDNode *G =
- dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
- if (NoHelperNeeded.find(G->getGlobal()->getName().data()) !=
- NoHelperNeeded.end()) {
+ } else if (GlobalAddressSDNode *G =
+ dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
+ Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
+ G->getGlobal()->getName().data() };
+
+ if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
+ Find))
LookupHelper = false;
- }
}
if (LookupHelper) Mips16HelperFunction =
getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper);
diff --git a/lib/Target/Mips/Mips16ISelLowering.h b/lib/Target/Mips/Mips16ISelLowering.h
index d3c7028..33b953f 100644
--- a/lib/Target/Mips/Mips16ISelLowering.h
+++ b/lib/Target/Mips/Mips16ISelLowering.h
@@ -32,8 +32,6 @@ namespace llvm {
unsigned NextStackOffset,
const MipsFunctionInfo& FI) const;
- void setMips16LibcallName(RTLIB::Libcall, const char *Name);
-
void setMips16HardFloatLibCalls();
unsigned int
diff --git a/lib/Target/Mips/Mips16InstrFormats.td b/lib/Target/Mips/Mips16InstrFormats.td
index 1e49934..da3a1f1 100644
--- a/lib/Target/Mips/Mips16InstrFormats.td
+++ b/lib/Target/Mips/Mips16InstrFormats.td
@@ -148,6 +148,20 @@ class FRR16<bits<5> _funct, dag outs, dag ins, string asmstr,
let Inst{4-0} = funct;
}
+class FRRBreak16<dag outs, dag ins, string asmstr,
+ list<dag> pattern, InstrItinClass itin>:
+ MipsInst16<outs, ins, asmstr, pattern, itin>
+{
+ bits<6> Code;
+ bits<5> funct;
+
+ let Opcode = 0b11101;
+ let funct = 0b00101;
+
+ let Inst{10-5} = Code;
+ let Inst{4-0} = funct;
+}
+
//
// For conversion functions.
//
diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp
index c2a496c..05e70ab 100644
--- a/lib/Target/Mips/Mips16InstrInfo.cpp
+++ b/lib/Target/Mips/Mips16InstrInfo.cpp
@@ -10,7 +10,7 @@
// This file contains the Mips16 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
-
+#include <stdio.h>
#include "Mips16InstrInfo.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MipsMachineFunction.h"
@@ -72,9 +72,9 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
unsigned Opc = 0;
if (Mips::CPU16RegsRegClass.contains(DestReg) &&
- Mips::CPURegsRegClass.contains(SrcReg))
+ Mips::GPR32RegClass.contains(SrcReg))
Opc = Mips::MoveR3216;
- else if (Mips::CPURegsRegClass.contains(DestReg) &&
+ else if (Mips::GPR32RegClass.contains(DestReg) &&
Mips::CPU16RegsRegClass.contains(SrcReg))
Opc = Mips::Move32R16;
else if ((SrcReg == Mips::HI) &&
@@ -109,8 +109,9 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
Opc = Mips::SwRxSpImmX16;
assert(Opc && "Register class not handled!");
- BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
- .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
+ BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)).
+ addFrameIndex(FI).addImm(Offset)
+ .addMemOperand(MMO);
}
void Mips16InstrInfo::
@@ -323,48 +324,88 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg,
//
RegScavenger rs;
int32_t lo = Imm & 0xFFFF;
- int32_t hi = ((Imm >> 16) + (lo >> 15)) & 0xFFFF;
NewImm = lo;
- unsigned Reg =0;
- unsigned SpReg = 0;
+ int Reg =0;
+ int SpReg = 0;
+
rs.enterBasicBlock(&MBB);
rs.forward(II);
//
+ // We need to know which registers can be used, in the case where there
+ // are not enough free registers. We exclude all registers that
+ // are used in the instruction that we are helping.
+ // // Consider all allocatable registers in the register class initially
+ BitVector Candidates =
+ RI.getAllocatableSet
+ (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
+ // Exclude all the registers being used by the instruction.
+ for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = II->getOperand(i);
+ if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
+ !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+ Candidates.reset(MO.getReg());
+ }
+ //
+ // If the same register was used and defined in an instruction, then
+ // it will not be in the list of candidates.
+ //
+ // we need to analyze the instruction that we are helping.
+ // we need to know if it defines register x but register x is not
+ // present as an operand of the instruction. this tells
+ // whether the register is live before the instruction. if it's not
+ // then we don't need to save it in case there are no free registers.
+ //
+ int DefReg = 0;
+ for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = II->getOperand(i);
+ if (MO.isReg() && MO.isDef()) {
+ DefReg = MO.getReg();
+ break;
+ }
+ }
+ //
+ BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass);
+
+ Available &= Candidates;
+ //
// we use T0 for the first register, if we need to save something away.
// we use T1 for the second register, if we need to save something away.
//
unsigned FirstRegSaved =0, SecondRegSaved=0;
unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
- Reg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass);
- if (Reg == 0) {
- FirstRegSaved = Reg = Mips::V0;
- FirstRegSavedTo = Mips::T0;
- copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true);
+
+ Reg = Available.find_first();
+
+ if (Reg == -1) {
+ Reg = Candidates.find_first();
+ Candidates.reset(Reg);
+ if (DefReg != Reg) {
+ FirstRegSaved = Reg;
+ FirstRegSavedTo = Mips::T0;
+ copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true);
+ }
}
else
- rs.setUsed(Reg);
- BuildMI(MBB, II, DL, get(Mips::LiRxImmX16), Reg).addImm(hi);
- BuildMI(MBB, II, DL, get(Mips::SllX16), Reg).addReg(Reg).
- addImm(16);
+ Available.reset(Reg);
+ BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm);
+ NewImm = 0;
if (FrameReg == Mips::SP) {
- SpReg = rs.FindUnusedReg(&Mips::CPU16RegsRegClass);
- if (SpReg == 0) {
- if (Reg != Mips::V1) {
- SecondRegSaved = SpReg = Mips::V1;
+ SpReg = Available.find_first();
+ if (SpReg == -1) {
+ SpReg = Candidates.find_first();
+ // Candidates.reset(SpReg); // not really needed
+ if (DefReg!= SpReg) {
+ SecondRegSaved = SpReg;
SecondRegSavedTo = Mips::T1;
}
- else {
- SecondRegSaved = SpReg = Mips::V0;
- SecondRegSavedTo = Mips::T0;
- }
- copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true);
+ if (SecondRegSaved)
+ copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true);
}
- else
- rs.setUsed(SpReg);
-
+ else
+ Available.reset(SpReg);
copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false);
- BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg)
+ BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill)
.addReg(Reg);
}
else
@@ -380,6 +421,22 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg,
return Reg;
}
+/// This function generates the sequence of instructions needed to get the
+/// result of adding register REG and immediate IMM.
+unsigned
+Mips16InstrInfo::basicLoadImmediate(
+ unsigned FrameReg,
+ int64_t Imm, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator II, DebugLoc DL,
+ unsigned &NewImm) const {
+ const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass;
+ MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
+ unsigned Reg = RegInfo.createVirtualRegister(RC);
+ BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm);
+ NewImm = 0;
+ return Reg;
+}
+
unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 ||
Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 ||
@@ -415,3 +472,27 @@ void Mips16InstrInfo::BuildAddiuSpImm
const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) {
return new Mips16InstrInfo(TM);
}
+
+#include <stdio.h>
+bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg,
+ int64_t Amount) {
+ switch (Opcode) {
+ case Mips::LbRxRyOffMemX16:
+ case Mips::LbuRxRyOffMemX16:
+ case Mips::LhRxRyOffMemX16:
+ case Mips::LhuRxRyOffMemX16:
+ case Mips::SbRxRyOffMemX16:
+ case Mips::ShRxRyOffMemX16:
+ case Mips::LwRxRyOffMemX16:
+ case Mips::SwRxRyOffMemX16:
+ case Mips::SwRxSpImmX16:
+ case Mips::LwRxSpImmX16:
+ return isInt<16>(Amount);
+ case Mips::AddiuRxRyOffMemX16:
+ if ((Reg == Mips::PC) || (Reg == Mips::SP))
+ return isInt<16>(Amount);
+ return isInt<15>(Amount);
+ }
+ printf("Unexpected opcode %i \n", Opcode);
+ llvm_unreachable("unexpected Opcode in validImmediate");
+}
diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h
index a3bd31e..118d258 100644
--- a/lib/Target/Mips/Mips16InstrInfo.h
+++ b/lib/Target/Mips/Mips16InstrInfo.h
@@ -68,7 +68,7 @@ public:
// Adjust SP by FrameSize bytes. Save RA, S0, S1
void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const;
+ MachineBasicBlock::iterator I) const;
// Adjust SP by FrameSize bytes. Restore RA, S0, S1
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB,
@@ -88,6 +88,13 @@ public:
MachineBasicBlock::iterator II, DebugLoc DL,
unsigned &NewImm) const;
+ unsigned basicLoadImmediate(unsigned FrameReg,
+ int64_t Imm, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator II, DebugLoc DL,
+ unsigned &NewImm) const;
+
+ static bool validImmediate(unsigned Opcode, unsigned Reg, int64_t Amount);
+
static bool validSpImm8(int offset) {
return ((offset & 7) == 0) && isInt<11>(offset);
}
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td
index aa51aaf..aef4e92 100644
--- a/lib/Target/Mips/Mips16InstrInfo.td
+++ b/lib/Target/Mips/Mips16InstrInfo.td
@@ -21,13 +21,13 @@ def addr16 :
// Address operand
def mem16 : Operand<i32> {
let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops CPU16Regs, simm16, CPU16Regs);
+ let MIOperandInfo = (ops CPU16Regs, simm16, CPU16RegsPlusSP);
let EncoderMethod = "getMemEncoding";
}
def mem16_ea : Operand<i32> {
let PrintMethod = "printMemOperandEA";
- let MIOperandInfo = (ops CPU16Regs, simm16);
+ let MIOperandInfo = (ops CPU16RegsPlusSP, simm16);
let EncoderMethod = "getMemEncoding";
}
@@ -187,6 +187,11 @@ class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
!strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
+class FEXT_RI16_SP_Store_explicit_ins<bits<5> _op, string asmstr,
+ InstrItinClass itin>:
+ FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, CPUSPReg:$ry, simm16:$imm),
+ !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
+
//
// EXT-RRI instruction format
//
@@ -248,7 +253,7 @@ class FEXT_T8I8I16_ins<string asmstr, string asmstr2>:
// I8_MOVR32 instruction format (used only by the MOVR32 instructio
//
class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>:
- FI8_MOVR3216<(outs CPU16Regs:$rz), (ins CPURegs:$r32),
+ FI8_MOVR3216<(outs CPU16Regs:$rz), (ins GPR32:$r32),
!strconcat(asmstr, "\t$rz, $r32"), [], itin>;
//
@@ -256,7 +261,7 @@ class FI8_MOVR3216_ins<string asmstr, InstrItinClass itin>:
//
class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>:
- FI8_MOV32R16<(outs CPURegs:$r32), (ins CPU16Regs:$rz),
+ FI8_MOV32R16<(outs GPR32:$r32), (ins CPU16Regs:$rz),
!strconcat(asmstr, "\t$r32, $rz"), [], itin>;
//
@@ -287,6 +292,11 @@ class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
}
+class FRRBreakNull16_ins<string asmstr, InstrItinClass itin> :
+ FRRBreak16<(outs), (ins), asmstr, [], itin> {
+ let Code=0;
+}
+
class FRR16R_ins<bits<5> f, string asmstr, InstrItinClass itin> :
FRR16<f, (outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
@@ -437,7 +447,7 @@ def Constant32:
MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>;
def LwConstant32:
- MipsPseudo16<(outs), (ins CPU16Regs:$rx, imm32:$imm),
+ MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm),
"lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;
@@ -569,6 +579,13 @@ def BnezRxImm16: FRI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
//
def BnezRxImmX16: FEXT_RI16_B_ins<0b00101, "bnez", IIAlu>, cbranch16;
+
+//
+//Format: BREAK immediate
+// Purpose: Breakpoint
+// To cause a Breakpoint exception.
+
+def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>;
//
// Format: BTEQZ offset MIPS16e
// Purpose: Branch on T Equal to Zero (Extended)
@@ -671,6 +688,7 @@ def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> {
let hasDelaySlot = 0; // not true, but we add the nop for now
let isTerminator=1;
let isBarrier=1;
+ let isCall=1;
}
//
@@ -878,9 +896,9 @@ def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>;
let ra=1, s=0,s0=1,s1=1 in
def RestoreRaF16:
FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
- "restore\t$$ra, $$s0, $$s1, $frame_size", [], IILoad >, MayLoad {
+ "restore\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IILoad >, MayLoad {
let isCodeGenOnly = 1;
- let Defs = [S0, S1, RA, SP];
+ let Defs = [S0, S1, S2, RA, SP];
let Uses = [SP];
}
@@ -906,9 +924,9 @@ def RestoreIncSpF16:
let ra=1, s=1,s0=1,s1=1 in
def SaveRaF16:
FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size),
- "save\t$$ra, $$s0, $$s1, $frame_size", [], IIStore >, MayStore {
+ "save\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IIStore >, MayStore {
let isCodeGenOnly = 1;
- let Uses = [RA, SP, S0, S1];
+ let Uses = [RA, SP, S0, S1, S2];
let Defs = [SP];
}
@@ -1195,7 +1213,8 @@ def SwRxRyOffMemX16:
// Purpose: Store Word rx (SP-Relative)
// To store an SP-relative word to memory.
//
-def SwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b11010, "sw", IIStore>, MayStore;
+def SwRxSpImmX16: FEXT_RI16_SP_Store_explicit_ins
+ <0b11010, "sw", IIStore>, MayStore;
//
//
@@ -1789,3 +1808,6 @@ def : Mips16Pat<(i32 (extloadi8 addr16:$src)),
(LbuRxRyOffMemX16 addr16:$src)>;
def : Mips16Pat<(i32 (extloadi16 addr16:$src)),
(LhuRxRyOffMemX16 addr16:$src)>;
+
+def: Mips16Pat<(trap), (Break16)>;
+
diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp
index 018f56c..9d0f2c9 100644
--- a/lib/Target/Mips/Mips16RegisterInfo.cpp
+++ b/lib/Target/Mips/Mips16RegisterInfo.cpp
@@ -134,8 +134,8 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
- if (!MI.isDebugValue() && ( ((FrameReg != Mips::SP) && !isInt<16>(Offset)) ||
- ((FrameReg == Mips::SP) && !isInt<15>(Offset)) )) {
+ if (!MI.isDebugValue() &&
+ !Mips16InstrInfo::validImmediate(MI.getOpcode(), FrameReg, Offset)) {
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
unsigned NewImm;
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index df717fe..a752ab8 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -37,21 +37,15 @@ def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>;
let DecoderNamespace = "Mips64" in {
multiclass Atomic2Ops64<PatFrag Op> {
- def NAME : Atomic2Ops<Op, CPU64Regs, CPURegs>,
- Requires<[NotN64, HasStdEnc]>;
- def _P8 : Atomic2Ops<Op, CPU64Regs, CPU64Regs>,
- Requires<[IsN64, HasStdEnc]> {
- let isCodeGenOnly = 1;
- }
+ def NAME : Atomic2Ops<Op, GPR64, GPR32>, Requires<[NotN64, HasStdEnc]>;
+ def _P8 : Atomic2Ops<Op, GPR64, GPR64>, Requires<[IsN64, HasStdEnc]>;
}
multiclass AtomicCmpSwap64<PatFrag Op> {
- def NAME : AtomicCmpSwap<Op, CPU64Regs, CPURegs>,
+ def NAME : AtomicCmpSwap<Op, GPR64, GPR32>,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : AtomicCmpSwap<Op, CPU64Regs, CPU64Regs>,
- Requires<[IsN64, HasStdEnc]> {
- let isCodeGenOnly = 1;
- }
+ def _P8 : AtomicCmpSwap<Op, GPR64, GPR64>,
+ Requires<[IsN64, HasStdEnc]>;
}
}
let usesCustomInserter = 1, Predicates = [HasStdEnc],
@@ -67,9 +61,9 @@ let usesCustomInserter = 1, Predicates = [HasStdEnc],
}
/// Pseudo instructions for loading and storing accumulator registers.
-let isPseudo = 1 in {
- defm LOAD_AC128 : LoadM<"load_ac128", ACRegs128>;
- defm STORE_AC128 : StoreM<"store_ac128", ACRegs128>;
+let isPseudo = 1, isCodeGenOnly = 1 in {
+ defm LOAD_AC128 : LoadM<"", ACRegs128>;
+ defm STORE_AC128 : StoreM<"", ACRegs128>;
}
//===----------------------------------------------------------------------===//
@@ -77,166 +71,179 @@ let isPseudo = 1 in {
//===----------------------------------------------------------------------===//
let DecoderNamespace = "Mips64" in {
/// Arithmetic Instructions (ALU Immediate)
-def DADDi : ArithLogicI<"daddi", simm16_64, CPU64RegsOpnd>, ADDI_FM<0x18>;
-def DADDiu : ArithLogicI<"daddiu", simm16_64, CPU64RegsOpnd, immSExt16, add>,
+def DADDi : ArithLogicI<"daddi", simm16_64, GPR64Opnd>, ADDI_FM<0x18>;
+def DADDiu : ArithLogicI<"daddiu", simm16_64, GPR64Opnd, IIArith,
+ immSExt16, add>,
ADDI_FM<0x19>, IsAsCheapAsAMove;
-def DANDi : ArithLogicI<"andi", uimm16_64, CPU64RegsOpnd, immZExt16, and>,
- ADDI_FM<0xc>;
-def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, CPU64Regs>,
+
+let isCodeGenOnly = 1 in {
+def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd>,
SLTI_FM<0xa>;
-def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, CPU64Regs>,
+def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd>,
SLTI_FM<0xb>;
-def ORi64 : ArithLogicI<"ori", uimm16_64, CPU64RegsOpnd, immZExt16, or>,
+def ANDi64 : ArithLogicI<"andi", uimm16_64, GPR64Opnd, IILogic, immZExt16,
+ and>,
+ ADDI_FM<0xc>;
+def ORi64 : ArithLogicI<"ori", uimm16_64, GPR64Opnd, IILogic, immZExt16,
+ or>,
ADDI_FM<0xd>;
-def XORi64 : ArithLogicI<"xori", uimm16_64, CPU64RegsOpnd, immZExt16, xor>,
+def XORi64 : ArithLogicI<"xori", uimm16_64, GPR64Opnd, IILogic, immZExt16,
+ xor>,
ADDI_FM<0xe>;
-def LUi64 : LoadUpper<"lui", CPU64Regs, uimm16_64>, LUI_FM;
+def LUi64 : LoadUpper<"lui", GPR64Opnd, uimm16_64>, LUI_FM;
+}
/// Arithmetic Instructions (3-Operand, R-Type)
-def DADD : ArithLogicR<"dadd", CPU64RegsOpnd>, ADD_FM<0, 0x2c>;
-def DADDu : ArithLogicR<"daddu", CPU64RegsOpnd, 1, IIAlu, add>,
+def DADD : ArithLogicR<"dadd", GPR64Opnd>, ADD_FM<0, 0x2c>;
+def DADDu : ArithLogicR<"daddu", GPR64Opnd, 1, IIArith, add>,
ADD_FM<0, 0x2d>;
-def DSUBu : ArithLogicR<"dsubu", CPU64RegsOpnd, 0, IIAlu, sub>,
+def DSUBu : ArithLogicR<"dsubu", GPR64Opnd, 0, IIArith, sub>,
ADD_FM<0, 0x2f>;
-def SLT64 : SetCC_R<"slt", setlt, CPU64Regs>, ADD_FM<0, 0x2a>;
-def SLTu64 : SetCC_R<"sltu", setult, CPU64Regs>, ADD_FM<0, 0x2b>;
-def AND64 : ArithLogicR<"and", CPU64RegsOpnd, 1, IIAlu, and>, ADD_FM<0, 0x24>;
-def OR64 : ArithLogicR<"or", CPU64RegsOpnd, 1, IIAlu, or>, ADD_FM<0, 0x25>;
-def XOR64 : ArithLogicR<"xor", CPU64RegsOpnd, 1, IIAlu, xor>, ADD_FM<0, 0x26>;
-def NOR64 : LogicNOR<"nor", CPU64RegsOpnd>, ADD_FM<0, 0x27>;
+
+let isCodeGenOnly = 1 in {
+def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>;
+def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd>, ADD_FM<0, 0x2b>;
+def AND64 : ArithLogicR<"and", GPR64Opnd, 1, IIArith, and>, ADD_FM<0, 0x24>;
+def OR64 : ArithLogicR<"or", GPR64Opnd, 1, IIArith, or>, ADD_FM<0, 0x25>;
+def XOR64 : ArithLogicR<"xor", GPR64Opnd, 1, IIArith, xor>, ADD_FM<0, 0x26>;
+def NOR64 : LogicNOR<"nor", GPR64Opnd>, ADD_FM<0, 0x27>;
+}
/// Shift Instructions
-def DSLL : shift_rotate_imm<"dsll", shamt, CPU64RegsOpnd, shl, immZExt6>,
+def DSLL : shift_rotate_imm<"dsll", shamt, GPR64Opnd, shl, immZExt6>,
SRA_FM<0x38, 0>;
-def DSRL : shift_rotate_imm<"dsrl", shamt, CPU64RegsOpnd, srl, immZExt6>,
+def DSRL : shift_rotate_imm<"dsrl", shamt, GPR64Opnd, srl, immZExt6>,
SRA_FM<0x3a, 0>;
-def DSRA : shift_rotate_imm<"dsra", shamt, CPU64RegsOpnd, sra, immZExt6>,
+def DSRA : shift_rotate_imm<"dsra", shamt, GPR64Opnd, sra, immZExt6>,
SRA_FM<0x3b, 0>;
-def DSLLV : shift_rotate_reg<"dsllv", CPU64RegsOpnd, shl>, SRLV_FM<0x14, 0>;
-def DSRLV : shift_rotate_reg<"dsrlv", CPU64RegsOpnd, srl>, SRLV_FM<0x16, 0>;
-def DSRAV : shift_rotate_reg<"dsrav", CPU64RegsOpnd, sra>, SRLV_FM<0x17, 0>;
-def DSLL32 : shift_rotate_imm<"dsll32", shamt, CPU64RegsOpnd>, SRA_FM<0x3c, 0>;
-def DSRL32 : shift_rotate_imm<"dsrl32", shamt, CPU64RegsOpnd>, SRA_FM<0x3e, 0>;
-def DSRA32 : shift_rotate_imm<"dsra32", shamt, CPU64RegsOpnd>, SRA_FM<0x3f, 0>;
-}
+def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, shl>, SRLV_FM<0x14, 0>;
+def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, srl>, SRLV_FM<0x16, 0>;
+def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, sra>, SRLV_FM<0x17, 0>;
+def DSLL32 : shift_rotate_imm<"dsll32", shamt, GPR64Opnd>, SRA_FM<0x3c, 0>;
+def DSRL32 : shift_rotate_imm<"dsrl32", shamt, GPR64Opnd>, SRA_FM<0x3e, 0>;
+def DSRA32 : shift_rotate_imm<"dsra32", shamt, GPR64Opnd>, SRA_FM<0x3f, 0>;
+
// Rotate Instructions
-let Predicates = [HasMips64r2, HasStdEnc],
- DecoderNamespace = "Mips64" in {
- def DROTR : shift_rotate_imm<"drotr", shamt, CPU64RegsOpnd, rotr, immZExt6>,
+let Predicates = [HasMips64r2, HasStdEnc] in {
+ def DROTR : shift_rotate_imm<"drotr", shamt, GPR64Opnd, rotr, immZExt6>,
SRA_FM<0x3a, 1>;
- def DROTRV : shift_rotate_reg<"drotrv", CPU64RegsOpnd, rotr>,
+ def DROTRV : shift_rotate_reg<"drotrv", GPR64Opnd, rotr>,
SRLV_FM<0x16, 1>;
}
-let DecoderNamespace = "Mips64" in {
/// Load and Store Instructions
/// aligned
-defm LB64 : LoadM<"lb", CPU64Regs, sextloadi8>, LW_FM<0x20>;
-defm LBu64 : LoadM<"lbu", CPU64Regs, zextloadi8>, LW_FM<0x24>;
-defm LH64 : LoadM<"lh", CPU64Regs, sextloadi16>, LW_FM<0x21>;
-defm LHu64 : LoadM<"lhu", CPU64Regs, zextloadi16>, LW_FM<0x25>;
-defm LW64 : LoadM<"lw", CPU64Regs, sextloadi32>, LW_FM<0x23>;
-defm LWu64 : LoadM<"lwu", CPU64Regs, zextloadi32>, LW_FM<0x27>;
-defm SB64 : StoreM<"sb", CPU64Regs, truncstorei8>, LW_FM<0x28>;
-defm SH64 : StoreM<"sh", CPU64Regs, truncstorei16>, LW_FM<0x29>;
-defm SW64 : StoreM<"sw", CPU64Regs, truncstorei32>, LW_FM<0x2b>;
-defm LD : LoadM<"ld", CPU64Regs, load>, LW_FM<0x37>;
-defm SD : StoreM<"sd", CPU64Regs, store>, LW_FM<0x3f>;
+let isCodeGenOnly = 1 in {
+defm LB64 : LoadM<"lb", GPR64Opnd, sextloadi8, IILoad>, LW_FM<0x20>;
+defm LBu64 : LoadM<"lbu", GPR64Opnd, zextloadi8, IILoad>, LW_FM<0x24>;
+defm LH64 : LoadM<"lh", GPR64Opnd, sextloadi16, IILoad>, LW_FM<0x21>;
+defm LHu64 : LoadM<"lhu", GPR64Opnd, zextloadi16, IILoad>, LW_FM<0x25>;
+defm LW64 : LoadM<"lw", GPR64Opnd, sextloadi32, IILoad>, LW_FM<0x23>;
+defm SB64 : StoreM<"sb", GPR64Opnd, truncstorei8, IIStore>, LW_FM<0x28>;
+defm SH64 : StoreM<"sh", GPR64Opnd, truncstorei16, IIStore>, LW_FM<0x29>;
+defm SW64 : StoreM<"sw", GPR64Opnd, truncstorei32, IIStore>, LW_FM<0x2b>;
+}
+
+defm LWu : LoadM<"lwu", GPR64Opnd, zextloadi32, IILoad>, LW_FM<0x27>;
+defm LD : LoadM<"ld", GPR64Opnd, load, IILoad>, LW_FM<0x37>;
+defm SD : StoreM<"sd", GPR64Opnd, store, IIStore>, LW_FM<0x3f>;
/// load/store left/right
-defm LWL64 : LoadLeftRightM<"lwl", MipsLWL, CPU64Regs>, LW_FM<0x22>;
-defm LWR64 : LoadLeftRightM<"lwr", MipsLWR, CPU64Regs>, LW_FM<0x26>;
-defm SWL64 : StoreLeftRightM<"swl", MipsSWL, CPU64Regs>, LW_FM<0x2a>;
-defm SWR64 : StoreLeftRightM<"swr", MipsSWR, CPU64Regs>, LW_FM<0x2e>;
+let isCodeGenOnly = 1 in {
+defm LWL64 : LoadLeftRightM<"lwl", MipsLWL, GPR64Opnd>, LW_FM<0x22>;
+defm LWR64 : LoadLeftRightM<"lwr", MipsLWR, GPR64Opnd>, LW_FM<0x26>;
+defm SWL64 : StoreLeftRightM<"swl", MipsSWL, GPR64Opnd>, LW_FM<0x2a>;
+defm SWR64 : StoreLeftRightM<"swr", MipsSWR, GPR64Opnd>, LW_FM<0x2e>;
+}
-defm LDL : LoadLeftRightM<"ldl", MipsLDL, CPU64Regs>, LW_FM<0x1a>;
-defm LDR : LoadLeftRightM<"ldr", MipsLDR, CPU64Regs>, LW_FM<0x1b>;
-defm SDL : StoreLeftRightM<"sdl", MipsSDL, CPU64Regs>, LW_FM<0x2c>;
-defm SDR : StoreLeftRightM<"sdr", MipsSDR, CPU64Regs>, LW_FM<0x2d>;
+defm LDL : LoadLeftRightM<"ldl", MipsLDL, GPR64Opnd>, LW_FM<0x1a>;
+defm LDR : LoadLeftRightM<"ldr", MipsLDR, GPR64Opnd>, LW_FM<0x1b>;
+defm SDL : StoreLeftRightM<"sdl", MipsSDL, GPR64Opnd>, LW_FM<0x2c>;
+defm SDR : StoreLeftRightM<"sdr", MipsSDR, GPR64Opnd>, LW_FM<0x2d>;
/// Load-linked, Store-conditional
let Predicates = [NotN64, HasStdEnc] in {
- def LLD : LLBase<"lld", CPU64RegsOpnd, mem>, LW_FM<0x34>;
- def SCD : SCBase<"scd", CPU64RegsOpnd, mem>, LW_FM<0x3c>;
+ def LLD : LLBase<"lld", GPR64Opnd, mem>, LW_FM<0x34>;
+ def SCD : SCBase<"scd", GPR64Opnd, mem>, LW_FM<0x3c>;
}
let Predicates = [IsN64, HasStdEnc], isCodeGenOnly = 1 in {
- def LLD_P8 : LLBase<"lld", CPU64RegsOpnd, mem64>, LW_FM<0x34>;
- def SCD_P8 : SCBase<"scd", CPU64RegsOpnd, mem64>, LW_FM<0x3c>;
+ def LLD_P8 : LLBase<"lld", GPR64Opnd, mem64>, LW_FM<0x34>;
+ def SCD_P8 : SCBase<"scd", GPR64Opnd, mem64>, LW_FM<0x3c>;
}
/// Jump and Branch Instructions
-def JR64 : IndirectBranch<CPU64Regs>, MTLO_FM<8>;
-def BEQ64 : CBranch<"beq", seteq, CPU64RegsOpnd>, BEQ_FM<4>;
-def BNE64 : CBranch<"bne", setne, CPU64RegsOpnd>, BEQ_FM<5>;
-def BGEZ64 : CBranchZero<"bgez", setge, CPU64RegsOpnd>, BGEZ_FM<1, 1>;
-def BGTZ64 : CBranchZero<"bgtz", setgt, CPU64RegsOpnd>, BGEZ_FM<7, 0>;
-def BLEZ64 : CBranchZero<"blez", setle, CPU64RegsOpnd>, BGEZ_FM<6, 0>;
-def BLTZ64 : CBranchZero<"bltz", setlt, CPU64RegsOpnd>, BGEZ_FM<1, 0>;
+let isCodeGenOnly = 1 in {
+def JR64 : IndirectBranch<GPR64Opnd>, MTLO_FM<8>;
+def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>;
+def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>;
+def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>;
+def BGTZ64 : CBranchZero<"bgtz", setgt, GPR64Opnd>, BGEZ_FM<7, 0>;
+def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>;
+def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
+def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM;
+def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
+def TAILCALL64_R : JumpFR<GPR64Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall;
}
-let DecoderNamespace = "Mips64" in
-def JALR64 : JumpLinkReg<"jalr", CPU64Regs>, JALR_FM;
-def JALR64Pseudo : JumpLinkRegPseudo<CPU64Regs, JALR64, RA_64>;
-def TAILCALL64_R : JumpFR<CPU64Regs, MipsTailCall>, MTLO_FM<8>, IsTailCall;
-let DecoderNamespace = "Mips64" in {
/// Multiply and Divide Instructions.
-def DMULT : Mult<"dmult", IIImul, CPU64RegsOpnd, [HI64, LO64]>,
+def DMULT : Mult<"dmult", IIImult, GPR64Opnd, [HI64, LO64]>,
MULT_FM<0, 0x1c>;
-def DMULTu : Mult<"dmultu", IIImul, CPU64RegsOpnd, [HI64, LO64]>,
+def DMULTu : Mult<"dmultu", IIImult, GPR64Opnd, [HI64, LO64]>,
MULT_FM<0, 0x1d>;
-def PseudoDMULT : MultDivPseudo<DMULT, ACRegs128, CPU64RegsOpnd, MipsMult,
- IIImul>;
-def PseudoDMULTu : MultDivPseudo<DMULTu, ACRegs128, CPU64RegsOpnd, MipsMultu,
- IIImul>;
-def DSDIV : Div<"ddiv", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1e>;
-def DUDIV : Div<"ddivu", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1f>;
-def PseudoDSDIV : MultDivPseudo<DSDIV, ACRegs128, CPU64RegsOpnd, MipsDivRem,
+def PseudoDMULT : MultDivPseudo<DMULT, ACRegs128, GPR64Opnd, MipsMult,
+ IIImult>;
+def PseudoDMULTu : MultDivPseudo<DMULTu, ACRegs128, GPR64Opnd, MipsMultu,
+ IIImult>;
+def DSDIV : Div<"ddiv", IIIdiv, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1e>;
+def DUDIV : Div<"ddivu", IIIdiv, GPR64Opnd, [HI64, LO64]>, MULT_FM<0, 0x1f>;
+def PseudoDSDIV : MultDivPseudo<DSDIV, ACRegs128, GPR64Opnd, MipsDivRem,
IIIdiv, 0, 1, 1>;
-def PseudoDUDIV : MultDivPseudo<DUDIV, ACRegs128, CPU64RegsOpnd, MipsDivRemU,
+def PseudoDUDIV : MultDivPseudo<DUDIV, ACRegs128, GPR64Opnd, MipsDivRemU,
IIIdiv, 0, 1, 1>;
-def MTHI64 : MoveToLOHI<"mthi", CPU64Regs, [HI64]>, MTLO_FM<0x11>;
-def MTLO64 : MoveToLOHI<"mtlo", CPU64Regs, [LO64]>, MTLO_FM<0x13>;
-def MFHI64 : MoveFromLOHI<"mfhi", CPU64Regs, [HI64]>, MFLO_FM<0x10>;
-def MFLO64 : MoveFromLOHI<"mflo", CPU64Regs, [LO64]>, MFLO_FM<0x12>;
+let isCodeGenOnly = 1 in {
+def MTHI64 : MoveToLOHI<"mthi", GPR64Opnd, [HI64]>, MTLO_FM<0x11>;
+def MTLO64 : MoveToLOHI<"mtlo", GPR64Opnd, [LO64]>, MTLO_FM<0x13>;
+def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, [HI64]>, MFLO_FM<0x10>;
+def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, [LO64]>, MFLO_FM<0x12>;
/// Sign Ext In Register Instructions.
-def SEB64 : SignExtInReg<"seb", i8, CPU64Regs>, SEB_FM<0x10, 0x20>;
-def SEH64 : SignExtInReg<"seh", i16, CPU64Regs>, SEB_FM<0x18, 0x20>;
+def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd>, SEB_FM<0x10, 0x20>;
+def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd>, SEB_FM<0x18, 0x20>;
+}
/// Count Leading
-def DCLZ : CountLeading0<"dclz", CPU64RegsOpnd>, CLO_FM<0x24>;
-def DCLO : CountLeading1<"dclo", CPU64RegsOpnd>, CLO_FM<0x25>;
+def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>;
+def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>;
/// Double Word Swap Bytes/HalfWords
-def DSBH : SubwordSwap<"dsbh", CPU64RegsOpnd>, SEB_FM<2, 0x24>;
-def DSHD : SubwordSwap<"dshd", CPU64RegsOpnd>, SEB_FM<5, 0x24>;
+def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>;
+def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>;
-def LEA_ADDiu64 : EffectiveAddress<"daddiu", CPU64Regs, mem_ea_64>, LW_FM<0x19>;
+def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd, mem_ea_64>, LW_FM<0x19>;
-}
-let DecoderNamespace = "Mips64" in {
-def RDHWR64 : ReadHardware<CPU64Regs, HW64RegsOpnd>, RDHWR_FM;
+let isCodeGenOnly = 1 in
+def RDHWR64 : ReadHardware<GPR64Opnd, HW64RegsOpnd>, RDHWR_FM;
-def DEXT : ExtBase<"dext", CPU64RegsOpnd>, EXT_FM<3>;
+def DEXT : ExtBase<"dext", GPR64Opnd>, EXT_FM<3>;
let Pattern = []<dag> in {
- def DEXTU : ExtBase<"dextu", CPU64RegsOpnd>, EXT_FM<2>;
- def DEXTM : ExtBase<"dextm", CPU64RegsOpnd>, EXT_FM<1>;
+ def DEXTU : ExtBase<"dextu", GPR64Opnd>, EXT_FM<2>;
+ def DEXTM : ExtBase<"dextm", GPR64Opnd>, EXT_FM<1>;
}
-def DINS : InsBase<"dins", CPU64RegsOpnd>, EXT_FM<7>;
+def DINS : InsBase<"dins", GPR64Opnd>, EXT_FM<7>;
let Pattern = []<dag> in {
- def DINSU : InsBase<"dinsu", CPU64RegsOpnd>, EXT_FM<6>;
- def DINSM : InsBase<"dinsm", CPU64RegsOpnd>, EXT_FM<5>;
+ def DINSU : InsBase<"dinsu", GPR64Opnd>, EXT_FM<6>;
+ def DINSM : InsBase<"dinsm", GPR64Opnd>, EXT_FM<5>;
}
let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
- def DSLL64_32 : FR<0x00, 0x3c, (outs CPU64Regs:$rd), (ins CPURegs:$rt),
- "dsll\t$rd, $rt, 32", [], IIAlu>;
- def SLL64_32 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPURegs:$rt),
- "sll\t$rd, $rt, 0", [], IIAlu>;
- def SLL64_64 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt),
- "sll\t$rd, $rt, 0", [], IIAlu>;
+ def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt),
+ "dsll\t$rd, $rt, 32", [], IIArith>;
+ def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt),
+ "sll\t$rd, $rt, 0", [], IIArith>;
+ def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt),
+ "sll\t$rd, $rt, 0", [], IIArith>;
}
}
//===----------------------------------------------------------------------===//
@@ -273,25 +280,25 @@ def : MipsPat<(MipsLo tglobaltlsaddr:$in),
(DADDiu ZERO_64, tglobaltlsaddr:$in)>;
def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>;
-def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaladdr:$lo)),
- (DADDiu CPU64Regs:$hi, tglobaladdr:$lo)>;
-def : MipsPat<(add CPU64Regs:$hi, (MipsLo tblockaddress:$lo)),
- (DADDiu CPU64Regs:$hi, tblockaddress:$lo)>;
-def : MipsPat<(add CPU64Regs:$hi, (MipsLo tjumptable:$lo)),
- (DADDiu CPU64Regs:$hi, tjumptable:$lo)>;
-def : MipsPat<(add CPU64Regs:$hi, (MipsLo tconstpool:$lo)),
- (DADDiu CPU64Regs:$hi, tconstpool:$lo)>;
-def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaltlsaddr:$lo)),
- (DADDiu CPU64Regs:$hi, tglobaltlsaddr:$lo)>;
-
-def : WrapperPat<tglobaladdr, DADDiu, CPU64Regs>;
-def : WrapperPat<tconstpool, DADDiu, CPU64Regs>;
-def : WrapperPat<texternalsym, DADDiu, CPU64Regs>;
-def : WrapperPat<tblockaddress, DADDiu, CPU64Regs>;
-def : WrapperPat<tjumptable, DADDiu, CPU64Regs>;
-def : WrapperPat<tglobaltlsaddr, DADDiu, CPU64Regs>;
-
-defm : BrcondPats<CPU64Regs, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64,
+def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)),
+ (DADDiu GPR64:$hi, tglobaladdr:$lo)>;
+def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)),
+ (DADDiu GPR64:$hi, tblockaddress:$lo)>;
+def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)),
+ (DADDiu GPR64:$hi, tjumptable:$lo)>;
+def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)),
+ (DADDiu GPR64:$hi, tconstpool:$lo)>;
+def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)),
+ (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+
+def : WrapperPat<tglobaladdr, DADDiu, GPR64>;
+def : WrapperPat<tconstpool, DADDiu, GPR64>;
+def : WrapperPat<texternalsym, DADDiu, GPR64>;
+def : WrapperPat<tblockaddress, DADDiu, GPR64>;
+def : WrapperPat<tjumptable, DADDiu, GPR64>;
+def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>;
+
+defm : BrcondPats<GPR64, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64,
ZERO_64>;
def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst),
@@ -300,28 +307,28 @@ def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst),
(BGEZ64 i64:$lhs, bb:$dst)>;
// setcc patterns
-defm : SeteqPats<CPU64Regs, SLTiu64, XOR64, SLTu64, ZERO_64>;
-defm : SetlePats<CPU64Regs, SLT64, SLTu64>;
-defm : SetgtPats<CPU64Regs, SLT64, SLTu64>;
-defm : SetgePats<CPU64Regs, SLT64, SLTu64>;
-defm : SetgeImmPats<CPU64Regs, SLTi64, SLTiu64>;
+defm : SeteqPats<GPR64, SLTiu64, XOR64, SLTu64, ZERO_64>;
+defm : SetlePats<GPR64, SLT64, SLTu64>;
+defm : SetgtPats<GPR64, SLT64, SLTu64>;
+defm : SetgePats<GPR64, SLT64, SLTu64>;
+defm : SetgeImmPats<GPR64, SLTi64, SLTiu64>;
// truncate
-def : MipsPat<(i32 (trunc CPU64Regs:$src)),
- (SLL (EXTRACT_SUBREG CPU64Regs:$src, sub_32), 0)>,
+def : MipsPat<(i32 (trunc GPR64:$src)),
+ (SLL (EXTRACT_SUBREG GPR64:$src, sub_32), 0)>,
Requires<[IsN64, HasStdEnc]>;
// 32-to-64-bit extension
-def : MipsPat<(i64 (anyext CPURegs:$src)), (SLL64_32 CPURegs:$src)>;
-def : MipsPat<(i64 (zext CPURegs:$src)), (DSRL (DSLL64_32 CPURegs:$src), 32)>;
-def : MipsPat<(i64 (sext CPURegs:$src)), (SLL64_32 CPURegs:$src)>;
+def : MipsPat<(i64 (anyext GPR32:$src)), (SLL64_32 GPR32:$src)>;
+def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>;
+def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>;
// Sign extend in register
-def : MipsPat<(i64 (sext_inreg CPU64Regs:$src, i32)),
- (SLL64_64 CPU64Regs:$src)>;
+def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)),
+ (SLL64_64 GPR64:$src)>;
// bswap MipsPattern
-def : MipsPat<(bswap CPU64Regs:$rt), (DSHD (DSBH CPU64Regs:$rt))>;
+def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>;
// mflo/hi patterns.
def : MipsPat<(i64 (ExtractLOHI ACRegs128:$ac, imm:$lohi_idx)),
@@ -331,71 +338,38 @@ def : MipsPat<(i64 (ExtractLOHI ACRegs128:$ac, imm:$lohi_idx)),
// Instruction aliases
//===----------------------------------------------------------------------===//
def : InstAlias<"move $dst, $src",
- (DADDu CPU64RegsOpnd:$dst, CPU64RegsOpnd:$src, ZERO_64), 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"move $dst, $src",
- (OR64 CPU64RegsOpnd:$dst, CPU64RegsOpnd:$src, ZERO_64), 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"and $rs, $rt, $imm",
- (DANDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm),
- 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"slt $rs, $rt, $imm",
- (SLTi64 CPURegsOpnd:$rs, CPU64Regs:$rt, simm16_64:$imm), 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"xor $rs, $rt, $imm",
- (XORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm),
- 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"not $rt, $rs",
- (NOR64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rs, ZERO_64), 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"j $rs", (JR64 CPU64Regs:$rs), 0>, Requires<[HasMips64]>;
-def : InstAlias<"jalr $rs", (JALR64 RA_64, CPU64Regs:$rs)>,
+ (DADDu GPR64Opnd:$dst, GPR64Opnd:$src, ZERO_64), 1>,
Requires<[HasMips64]>;
-def : InstAlias<"jal $rs", (JALR64 RA_64, CPU64Regs:$rs), 0>,
- Requires<[HasMips64]>;
-def : InstAlias<"jal $rd,$rs", (JALR64 CPU64Regs:$rd, CPU64Regs:$rs), 0>,
- Requires<[HasMips64]>;
def : InstAlias<"daddu $rs, $rt, $imm",
- (DADDiu CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm),
- 1>;
+ (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm),
+ 0>;
def : InstAlias<"dadd $rs, $rt, $imm",
- (DADDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm),
- 1>;
-def : InstAlias<"or $rs, $rt, $imm",
- (ORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm),
- 1>, Requires<[HasMips64]>;
-def : InstAlias<"bnez $rs,$offset",
- (BNE64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>,
- Requires<[HasMips64]>;
-def : InstAlias<"beqz $rs,$offset",
- (BEQ64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>,
- Requires<[HasMips64]>;
+ (DADDi GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm),
+ 0>;
/// Move between CPU and coprocessor registers
let DecoderNamespace = "Mips64" in {
-def DMFC0_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rt),
- (ins CPU64RegsOpnd:$rd, uimm16:$sel),
+def DMFC0_3OP64 : MFC3OP<(outs GPR64Opnd:$rt),
+ (ins GPR64Opnd:$rd, uimm16:$sel),
"dmfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 1>;
-def DMTC0_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rd, uimm16:$sel),
- (ins CPU64RegsOpnd:$rt),
+def DMTC0_3OP64 : MFC3OP<(outs GPR64Opnd:$rd, uimm16:$sel),
+ (ins GPR64Opnd:$rt),
"dmtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 5>;
-def DMFC2_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rt),
- (ins CPU64RegsOpnd:$rd, uimm16:$sel),
+def DMFC2_3OP64 : MFC3OP<(outs GPR64Opnd:$rt),
+ (ins GPR64Opnd:$rd, uimm16:$sel),
"dmfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 1>;
-def DMTC2_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rd, uimm16:$sel),
- (ins CPU64RegsOpnd:$rt),
+def DMTC2_3OP64 : MFC3OP<(outs GPR64Opnd:$rd, uimm16:$sel),
+ (ins GPR64Opnd:$rt),
"dmtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 5>;
}
// Two operand (implicit 0 selector) versions:
def : InstAlias<"dmfc0 $rt, $rd",
- (DMFC0_3OP64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rd, 0), 0>;
+ (DMFC0_3OP64 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>;
def : InstAlias<"dmtc0 $rt, $rd",
- (DMTC0_3OP64 CPU64RegsOpnd:$rd, 0, CPU64RegsOpnd:$rt), 0>;
+ (DMTC0_3OP64 GPR64Opnd:$rd, 0, GPR64Opnd:$rt), 0>;
def : InstAlias<"dmfc2 $rt, $rd",
- (DMFC2_3OP64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rd, 0), 0>;
+ (DMFC2_3OP64 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>;
def : InstAlias<"dmtc2 $rt, $rd",
- (DMTC2_3OP64 CPU64RegsOpnd:$rd, 0, CPU64RegsOpnd:$rt), 0>;
+ (DMTC2_3OP64 GPR64Opnd:$rd, 0, GPR64Opnd:$rt), 0>;
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 6e4feda..1dc3326 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -141,7 +141,7 @@ void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
const MachineFrameInfo *MFI = MF->getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
// size of stack area to which FP callee-saved regs are saved.
- unsigned CPURegSize = Mips::CPURegsRegClass.getSize();
+ unsigned CPURegSize = Mips::GPR32RegClass.getSize();
unsigned FGR32RegSize = Mips::FGR32RegClass.getSize();
unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize();
bool HasAFGR64Reg = false;
@@ -151,7 +151,7 @@ void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
// Set FPU Bitmask.
for (i = 0; i != e; ++i) {
unsigned Reg = CSI[i].getReg();
- if (Mips::CPURegsRegClass.contains(Reg))
+ if (Mips::GPR32RegClass.contains(Reg))
break;
unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
@@ -557,6 +557,15 @@ printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
// FIXME: Use SwitchSection.
+ // TODO: Need to add -mabicalls and -mno-abicalls flags.
+ // Currently we assume that -mabicalls is the default.
+ if (OutStreamer.hasRawTextSupport()) {
+ OutStreamer.EmitRawText(StringRef("\t.abicalls"));
+ Reloc::Model RM = Subtarget->getRelocationModel();
+ if (RM == Reloc::Static && !Subtarget->hasMips64())
+ OutStreamer.EmitRawText(StringRef("\t.option\tpic0"));
+ }
+
// Tell the assembler which ABI we are using
if (OutStreamer.hasRawTextSupport())
OutStreamer.EmitRawText("\t.section .mdebug." +
@@ -589,16 +598,6 @@ void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
MES->emitELFHeaderFlagsCG(*Subtarget);
}
-MachineLocation
-MipsAsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
- // Handles frame addresses emitted in MipsInstrInfo::emitFrameIndexDebugValue.
- assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
- assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() &&
- "Unexpected MachineOperand types");
- return MachineLocation(MI->getOperand(0).getReg(),
- MI->getOperand(1).getImm());
-}
-
void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
raw_ostream &OS) {
// TODO: implement
diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h
index dbdaf26..4d1d624 100644
--- a/lib/Target/Mips/MipsAsmPrinter.h
+++ b/lib/Target/Mips/MipsAsmPrinter.h
@@ -81,7 +81,6 @@ public:
const char *Modifier = 0);
void EmitStartOfAsmFile(Module &M);
void EmitEndOfAsmFile(Module &M);
- virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
};
}
diff --git a/lib/Target/Mips/MipsCondMov.td b/lib/Target/Mips/MipsCondMov.td
index 42e4c99..39862b3 100644
--- a/lib/Target/Mips/MipsCondMov.td
+++ b/lib/Target/Mips/MipsCondMov.td
@@ -16,7 +16,7 @@
// MipsISelLowering::EmitInstrWithCustomInserter if target does not have
// conditional move instructions.
// cond:int, data:int
-class CMov_I_I_FT<string opstr, RegisterClass CRC, RegisterClass DRC,
+class CMov_I_I_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC,
InstrItinClass Itin> :
InstSE<(outs DRC:$rd), (ins DRC:$rs, CRC:$rt, DRC:$F),
!strconcat(opstr, "\t$rd, $rs, $rt"), [], Itin, FrmFR> {
@@ -24,7 +24,7 @@ class CMov_I_I_FT<string opstr, RegisterClass CRC, RegisterClass DRC,
}
// cond:int, data:float
-class CMov_I_F_FT<string opstr, RegisterClass CRC, RegisterClass DRC,
+class CMov_I_F_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC,
InstrItinClass Itin> :
InstSE<(outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F),
!strconcat(opstr, "\t$fd, $fs, $rt"), [], Itin, FrmFR> {
@@ -32,22 +32,22 @@ class CMov_I_F_FT<string opstr, RegisterClass CRC, RegisterClass DRC,
}
// cond:float, data:int
-class CMov_F_I_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class CMov_F_I_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
SDPatternOperator OpNode = null_frag> :
- InstSE<(outs RC:$rd), (ins RC:$rs, RC:$F),
- !strconcat(opstr, "\t$rd, $rs, $$fcc0"),
- [(set RC:$rd, (OpNode RC:$rs, RC:$F))], Itin, FrmFR> {
- let Uses = [FCR31];
+ InstSE<(outs RC:$rd), (ins RC:$rs, FCCRegsOpnd:$fcc, RC:$F),
+ !strconcat(opstr, "\t$rd, $rs, $fcc"),
+ [(set RC:$rd, (OpNode RC:$rs, FCCRegsOpnd:$fcc, RC:$F))],
+ Itin, FrmFR> {
let Constraints = "$F = $rd";
}
// cond:float, data:float
-class CMov_F_F_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class CMov_F_F_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
SDPatternOperator OpNode = null_frag> :
- InstSE<(outs RC:$fd), (ins RC:$fs, RC:$F),
- !strconcat(opstr, "\t$fd, $fs, $$fcc0"),
- [(set RC:$fd, (OpNode RC:$fs, RC:$F))], Itin, FrmFR> {
- let Uses = [FCR31];
+ InstSE<(outs RC:$fd), (ins RC:$fs, FCCRegsOpnd:$fcc, RC:$F),
+ !strconcat(opstr, "\t$fd, $fs, $fcc"),
+ [(set RC:$fd, (OpNode RC:$fs, FCCRegsOpnd:$fcc, RC:$F))],
+ Itin, FrmFR> {
let Constraints = "$F = $fd";
}
@@ -103,151 +103,140 @@ multiclass MovnPats<RegisterClass CRC, RegisterClass DRC, Instruction MOVNInst,
}
// Instantiation of instructions.
-def MOVZ_I_I : CMov_I_I_FT<"movz", CPURegs, CPURegs, NoItinerary>,
+def MOVZ_I_I : CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, NoItinerary>,
ADD_FM<0, 0xa>;
-let Predicates = [HasStdEnc],
- DecoderNamespace = "Mips64" in {
- def MOVZ_I_I64 : CMov_I_I_FT<"movz", CPURegs, CPU64Regs, NoItinerary>,
- ADD_FM<0, 0xa>;
- def MOVZ_I64_I : CMov_I_I_FT<"movz", CPU64Regs, CPURegs, NoItinerary>,
- ADD_FM<0, 0xa> {
- let isCodeGenOnly = 1;
- }
- def MOVZ_I64_I64 : CMov_I_I_FT<"movz", CPU64Regs, CPU64Regs, NoItinerary>,
- ADD_FM<0, 0xa> {
- let isCodeGenOnly = 1;
- }
-}
-
-def MOVN_I_I : CMov_I_I_FT<"movn", CPURegs, CPURegs, NoItinerary>,
- ADD_FM<0, 0xb>;
-let Predicates = [HasStdEnc],
- DecoderNamespace = "Mips64" in {
- def MOVN_I_I64 : CMov_I_I_FT<"movn", CPURegs, CPU64Regs, NoItinerary>,
- ADD_FM<0, 0xb>;
- def MOVN_I64_I : CMov_I_I_FT<"movn", CPU64Regs, CPURegs, NoItinerary>,
- ADD_FM<0, 0xb> {
- let isCodeGenOnly = 1;
- }
- def MOVN_I64_I64 : CMov_I_I_FT<"movn", CPU64Regs, CPU64Regs, NoItinerary>,
- ADD_FM<0, 0xb> {
- let isCodeGenOnly = 1;
- }
-}
-
-def MOVZ_I_S : CMov_I_F_FT<"movz.s", CPURegs, FGR32, IIFmove>,
- CMov_I_F_FM<18, 16>;
-def MOVZ_I64_S : CMov_I_F_FT<"movz.s", CPU64Regs, FGR32, IIFmove>,
- CMov_I_F_FM<18, 16>, Requires<[HasMips64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
+
+let Predicates = [HasStdEnc], isCodeGenOnly = 1 in {
+ def MOVZ_I_I64 : CMov_I_I_FT<"movz", GPR32Opnd, GPR64Opnd,
+ NoItinerary>, ADD_FM<0, 0xa>;
+ def MOVZ_I64_I : CMov_I_I_FT<"movz", GPR64Opnd, GPR32Opnd,
+ NoItinerary>, ADD_FM<0, 0xa>;
+ def MOVZ_I64_I64 : CMov_I_I_FT<"movz", GPR64Opnd, GPR64Opnd,
+ NoItinerary>, ADD_FM<0, 0xa>;
}
-def MOVN_I_S : CMov_I_F_FT<"movn.s", CPURegs, FGR32, IIFmove>,
- CMov_I_F_FM<19, 16>;
-def MOVN_I64_S : CMov_I_F_FT<"movn.s", CPU64Regs, FGR32, IIFmove>,
- CMov_I_F_FM<19, 16>, Requires<[HasMips64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
+def MOVN_I_I : CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd,
+ NoItinerary>, ADD_FM<0, 0xb>;
+
+let Predicates = [HasStdEnc], isCodeGenOnly = 1 in {
+ def MOVN_I_I64 : CMov_I_I_FT<"movn", GPR32Opnd, GPR64Opnd,
+ NoItinerary>, ADD_FM<0, 0xb>;
+ def MOVN_I64_I : CMov_I_I_FT<"movn", GPR64Opnd, GPR32Opnd,
+ NoItinerary>, ADD_FM<0, 0xb>;
+ def MOVN_I64_I64 : CMov_I_I_FT<"movn", GPR64Opnd, GPR64Opnd,
+ NoItinerary>, ADD_FM<0, 0xb>;
}
+def MOVZ_I_S : CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32RegsOpnd, IIFmove>,
+ CMov_I_F_FM<18, 16>;
+
+let isCodeGenOnly = 1 in
+def MOVZ_I64_S : CMov_I_F_FT<"movz.s", GPR64Opnd, FGR32RegsOpnd, IIFmove>,
+ CMov_I_F_FM<18, 16>, Requires<[HasMips64, HasStdEnc]>;
+
+def MOVN_I_S : CMov_I_F_FT<"movn.s", GPR32Opnd, FGR32RegsOpnd, IIFmove>,
+ CMov_I_F_FM<19, 16>;
+
+let isCodeGenOnly = 1 in
+def MOVN_I64_S : CMov_I_F_FT<"movn.s", GPR64Opnd, FGR32RegsOpnd, IIFmove>,
+ CMov_I_F_FM<19, 16>, Requires<[HasMips64, HasStdEnc]>;
+
let Predicates = [NotFP64bit, HasStdEnc] in {
- def MOVZ_I_D32 : CMov_I_F_FT<"movz.d", CPURegs, AFGR64, IIFmove>,
+ def MOVZ_I_D32 : CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64RegsOpnd, IIFmove>,
CMov_I_F_FM<18, 17>;
- def MOVN_I_D32 : CMov_I_F_FT<"movn.d", CPURegs, AFGR64, IIFmove>,
+ def MOVN_I_D32 : CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64RegsOpnd, IIFmove>,
CMov_I_F_FM<19, 17>;
}
-let Predicates = [IsFP64bit, HasStdEnc],
- DecoderNamespace = "Mips64" in {
- def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", CPURegs, FGR64, IIFmove>,
+
+let Predicates = [IsFP64bit, HasStdEnc], isCodeGenOnly = 1 in {
+ def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", GPR32Opnd, FGR64RegsOpnd, IIFmove>,
CMov_I_F_FM<18, 17>;
- def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", CPU64Regs, FGR64, IIFmove>,
- CMov_I_F_FM<18, 17> {
- let isCodeGenOnly = 1;
- }
- def MOVN_I_D64 : CMov_I_F_FT<"movn.d", CPURegs, FGR64, IIFmove>,
+ def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", GPR64Opnd, FGR64RegsOpnd,
+ IIFmove>, CMov_I_F_FM<18, 17>;
+ def MOVN_I_D64 : CMov_I_F_FT<"movn.d", GPR32Opnd, FGR64RegsOpnd, IIFmove>,
CMov_I_F_FM<19, 17>;
- def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", CPU64Regs, FGR64, IIFmove>,
- CMov_I_F_FM<19, 17> {
- let isCodeGenOnly = 1;
- }
+ def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", GPR64Opnd, FGR64RegsOpnd,
+ IIFmove>, CMov_I_F_FM<19, 17>;
}
-def MOVT_I : CMov_F_I_FT<"movt", CPURegs, IIAlu, MipsCMovFP_T>, CMov_F_I_FM<1>;
-def MOVT_I64 : CMov_F_I_FT<"movt", CPU64Regs, IIAlu, MipsCMovFP_T>,
- CMov_F_I_FM<1>, Requires<[HasMips64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
-}
+def MOVT_I : CMov_F_I_FT<"movt", GPR32Opnd, IIArith, MipsCMovFP_T>,
+ CMov_F_I_FM<1>;
-def MOVF_I : CMov_F_I_FT<"movf", CPURegs, IIAlu, MipsCMovFP_F>, CMov_F_I_FM<0>;
-def MOVF_I64 : CMov_F_I_FT<"movf", CPU64Regs, IIAlu, MipsCMovFP_F>,
- CMov_F_I_FM<0>, Requires<[HasMips64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
-}
+let isCodeGenOnly = 1 in
+def MOVT_I64 : CMov_F_I_FT<"movt", GPR64Opnd, IIArith, MipsCMovFP_T>,
+ CMov_F_I_FM<1>, Requires<[HasMips64, HasStdEnc]>;
+
+def MOVF_I : CMov_F_I_FT<"movf", GPR32Opnd, IIArith, MipsCMovFP_F>,
+ CMov_F_I_FM<0>;
+
+let isCodeGenOnly = 1 in
+def MOVF_I64 : CMov_F_I_FT<"movf", GPR64Opnd, IIArith, MipsCMovFP_F>,
+ CMov_F_I_FM<0>, Requires<[HasMips64, HasStdEnc]>;
-def MOVT_S : CMov_F_F_FT<"movt.s", FGR32, IIFmove, MipsCMovFP_T>,
+def MOVT_S : CMov_F_F_FT<"movt.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_T>,
CMov_F_F_FM<16, 1>;
-def MOVF_S : CMov_F_F_FT<"movf.s", FGR32, IIFmove, MipsCMovFP_F>,
+def MOVF_S : CMov_F_F_FT<"movf.s", FGR32RegsOpnd, IIFmove, MipsCMovFP_F>,
CMov_F_F_FM<16, 0>;
let Predicates = [NotFP64bit, HasStdEnc] in {
- def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64, IIFmove, MipsCMovFP_T>,
+ def MOVT_D32 : CMov_F_F_FT<"movt.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_T>,
CMov_F_F_FM<17, 1>;
- def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64, IIFmove, MipsCMovFP_F>,
+ def MOVF_D32 : CMov_F_F_FT<"movf.d", AFGR64RegsOpnd, IIFmove, MipsCMovFP_F>,
CMov_F_F_FM<17, 0>;
}
-let Predicates = [IsFP64bit, HasStdEnc],
- DecoderNamespace = "Mips64" in {
- def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64, IIFmove, MipsCMovFP_T>,
+let Predicates = [IsFP64bit, HasStdEnc], isCodeGenOnly = 1 in {
+ def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_T>,
CMov_F_F_FM<17, 1>;
- def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64, IIFmove, MipsCMovFP_F>,
+ def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64RegsOpnd, IIFmove, MipsCMovFP_F>,
CMov_F_F_FM<17, 0>;
}
// Instantiation of conditional move patterns.
-defm : MovzPats0<CPURegs, CPURegs, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu>;
-defm : MovzPats1<CPURegs, CPURegs, MOVZ_I_I, XOR>;
-defm : MovzPats2<CPURegs, CPURegs, MOVZ_I_I, XORi>;
+defm : MovzPats0<GPR32, GPR32, MOVZ_I_I, SLT, SLTu, SLTi, SLTiu>;
+defm : MovzPats1<GPR32, GPR32, MOVZ_I_I, XOR>;
+defm : MovzPats2<GPR32, GPR32, MOVZ_I_I, XORi>;
let Predicates = [HasMips64, HasStdEnc] in {
- defm : MovzPats0<CPURegs, CPU64Regs, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu>;
- defm : MovzPats0<CPU64Regs, CPURegs, MOVZ_I_I, SLT64, SLTu64, SLTi64,
+ defm : MovzPats0<GPR32, GPR64, MOVZ_I_I64, SLT, SLTu, SLTi, SLTiu>;
+ defm : MovzPats0<GPR64, GPR32, MOVZ_I_I, SLT64, SLTu64, SLTi64,
SLTiu64>;
- defm : MovzPats0<CPU64Regs, CPU64Regs, MOVZ_I_I64, SLT64, SLTu64, SLTi64,
+ defm : MovzPats0<GPR64, GPR64, MOVZ_I_I64, SLT64, SLTu64, SLTi64,
SLTiu64>;
- defm : MovzPats1<CPURegs, CPU64Regs, MOVZ_I_I64, XOR>;
- defm : MovzPats1<CPU64Regs, CPURegs, MOVZ_I64_I, XOR64>;
- defm : MovzPats1<CPU64Regs, CPU64Regs, MOVZ_I64_I64, XOR64>;
- defm : MovzPats2<CPURegs, CPU64Regs, MOVZ_I_I64, XORi>;
- defm : MovzPats2<CPU64Regs, CPURegs, MOVZ_I64_I, XORi64>;
- defm : MovzPats2<CPU64Regs, CPU64Regs, MOVZ_I64_I64, XORi64>;
+ defm : MovzPats1<GPR32, GPR64, MOVZ_I_I64, XOR>;
+ defm : MovzPats1<GPR64, GPR32, MOVZ_I64_I, XOR64>;
+ defm : MovzPats1<GPR64, GPR64, MOVZ_I64_I64, XOR64>;
+ defm : MovzPats2<GPR32, GPR64, MOVZ_I_I64, XORi>;
+ defm : MovzPats2<GPR64, GPR32, MOVZ_I64_I, XORi64>;
+ defm : MovzPats2<GPR64, GPR64, MOVZ_I64_I64, XORi64>;
}
-defm : MovnPats<CPURegs, CPURegs, MOVN_I_I, XOR>;
+defm : MovnPats<GPR32, GPR32, MOVN_I_I, XOR>;
let Predicates = [HasMips64, HasStdEnc] in {
- defm : MovnPats<CPURegs, CPU64Regs, MOVN_I_I64, XOR>;
- defm : MovnPats<CPU64Regs, CPURegs, MOVN_I64_I, XOR64>;
- defm : MovnPats<CPU64Regs, CPU64Regs, MOVN_I64_I64, XOR64>;
+ defm : MovnPats<GPR32, GPR64, MOVN_I_I64, XOR>;
+ defm : MovnPats<GPR64, GPR32, MOVN_I64_I, XOR64>;
+ defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64>;
}
-defm : MovzPats0<CPURegs, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>;
-defm : MovzPats1<CPURegs, FGR32, MOVZ_I_S, XOR>;
-defm : MovnPats<CPURegs, FGR32, MOVN_I_S, XOR>;
+defm : MovzPats0<GPR32, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>;
+defm : MovzPats1<GPR32, FGR32, MOVZ_I_S, XOR>;
+defm : MovnPats<GPR32, FGR32, MOVN_I_S, XOR>;
let Predicates = [HasMips64, HasStdEnc] in {
- defm : MovzPats0<CPU64Regs, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64,
+ defm : MovzPats0<GPR64, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64,
SLTiu64>;
- defm : MovzPats1<CPU64Regs, FGR32, MOVZ_I64_S, XOR64>;
- defm : MovnPats<CPU64Regs, FGR32, MOVN_I64_S, XOR64>;
+ defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64>;
+ defm : MovnPats<GPR64, FGR32, MOVN_I64_S, XOR64>;
}
let Predicates = [NotFP64bit, HasStdEnc] in {
- defm : MovzPats0<CPURegs, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu>;
- defm : MovzPats1<CPURegs, AFGR64, MOVZ_I_D32, XOR>;
- defm : MovnPats<CPURegs, AFGR64, MOVN_I_D32, XOR>;
+ defm : MovzPats0<GPR32, AFGR64, MOVZ_I_D32, SLT, SLTu, SLTi, SLTiu>;
+ defm : MovzPats1<GPR32, AFGR64, MOVZ_I_D32, XOR>;
+ defm : MovnPats<GPR32, AFGR64, MOVN_I_D32, XOR>;
}
let Predicates = [IsFP64bit, HasStdEnc] in {
- defm : MovzPats0<CPURegs, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu>;
- defm : MovzPats0<CPU64Regs, FGR64, MOVZ_I_D64, SLT64, SLTu64, SLTi64,
+ defm : MovzPats0<GPR32, FGR64, MOVZ_I_D64, SLT, SLTu, SLTi, SLTiu>;
+ defm : MovzPats0<GPR64, FGR64, MOVZ_I_D64, SLT64, SLTu64, SLTi64,
SLTiu64>;
- defm : MovzPats1<CPURegs, FGR64, MOVZ_I_D64, XOR>;
- defm : MovzPats1<CPU64Regs, FGR64, MOVZ_I64_D64, XOR64>;
- defm : MovnPats<CPURegs, FGR64, MOVN_I_D64, XOR>;
- defm : MovnPats<CPU64Regs, FGR64, MOVN_I64_D64, XOR64>;
+ defm : MovzPats1<GPR32, FGR64, MOVZ_I_D64, XOR>;
+ defm : MovzPats1<GPR64, FGR64, MOVZ_I64_D64, XOR64>;
+ defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR>;
+ defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>;
}
diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td
index c12878a..526821a 100644
--- a/lib/Target/Mips/MipsDSPInstrInfo.td
+++ b/lib/Target/Mips/MipsDSPInstrInfo.td
@@ -328,9 +328,9 @@ class REPL_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class SHLL_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin, RegisterClass RC> {
dag OutOperandList = (outs RC:$rd);
- dag InOperandList = (ins RC:$rt, CPURegs:$rs_sa);
+ dag InOperandList = (ins RC:$rt, GPR32:$rs_sa);
string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs_sa");
- list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, CPURegs:$rs_sa))];
+ list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, GPR32:$rs_sa))];
InstrItinClass Itinerary = itin;
}
@@ -347,11 +347,11 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rd);
- dag InOperandList = (ins CPURegs:$base, CPURegs:$index);
+ dag OutOperandList = (outs GPR32:$rd);
+ dag InOperandList = (ins GPR32:$base, GPR32:$index);
string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})");
- list<dag> Pattern = [(set CPURegs:$rd,
- (OpNode CPURegs:$base, CPURegs:$index))];
+ list<dag> Pattern = [(set GPR32:$rd,
+ (OpNode GPR32:$base, GPR32:$index))];
InstrItinClass Itinerary = itin;
bit mayLoad = 1;
}
@@ -368,26 +368,26 @@ class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
SDPatternOperator ImmOp, InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rt);
- dag InOperandList = (ins CPURegs:$rs, shamt:$sa, CPURegs:$src);
+ dag OutOperandList = (outs GPR32:$rt);
+ dag InOperandList = (ins GPR32:$rs, shamt:$sa, GPR32:$src);
string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa");
- list<dag> Pattern = [(set CPURegs:$rt,
- (OpNode CPURegs:$src, CPURegs:$rs, ImmOp:$sa))];
+ list<dag> Pattern = [(set GPR32:$rt,
+ (OpNode GPR32:$src, GPR32:$rs, ImmOp:$sa))];
InstrItinClass Itinerary = itin;
string Constraints = "$src = $rt";
}
class EXTR_W_TY1_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rt);
- dag InOperandList = (ins ACRegsDSP:$ac, CPURegs:$shift_rs);
+ dag OutOperandList = (outs GPR32:$rt);
+ dag InOperandList = (ins ACRegsDSP:$ac, GPR32:$shift_rs);
string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs");
InstrItinClass Itinerary = itin;
}
class EXTR_W_TY1_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rt);
+ dag OutOperandList = (outs GPR32:$rt);
dag InOperandList = (ins ACRegsDSP:$ac, uimm16:$shift_rs);
string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs");
InstrItinClass Itinerary = itin;
@@ -404,55 +404,55 @@ class SHILO_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode> {
class SHILO_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode> {
dag OutOperandList = (outs ACRegsDSP:$ac);
- dag InOperandList = (ins CPURegs:$rs, ACRegsDSP:$acin);
+ dag InOperandList = (ins GPR32:$rs, ACRegsDSP:$acin);
string AsmString = !strconcat(instr_asm, "\t$ac, $rs");
list<dag> Pattern = [(set ACRegsDSP:$ac,
- (OpNode CPURegs:$rs, ACRegsDSP:$acin))];
+ (OpNode GPR32:$rs, ACRegsDSP:$acin))];
string Constraints = "$acin = $ac";
}
class MTHLIP_DESC_BASE<string instr_asm, SDPatternOperator OpNode> {
dag OutOperandList = (outs ACRegsDSP:$ac);
- dag InOperandList = (ins CPURegs:$rs, ACRegsDSP:$acin);
+ dag InOperandList = (ins GPR32:$rs, ACRegsDSP:$acin);
string AsmString = !strconcat(instr_asm, "\t$rs, $ac");
list<dag> Pattern = [(set ACRegsDSP:$ac,
- (OpNode CPURegs:$rs, ACRegsDSP:$acin))];
+ (OpNode GPR32:$rs, ACRegsDSP:$acin))];
string Constraints = "$acin = $ac";
}
class RDDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rd);
+ dag OutOperandList = (outs GPR32:$rd);
dag InOperandList = (ins uimm16:$mask);
string AsmString = !strconcat(instr_asm, "\t$rd, $mask");
- list<dag> Pattern = [(set CPURegs:$rd, (OpNode immZExt10:$mask))];
+ list<dag> Pattern = [(set GPR32:$rd, (OpNode immZExt10:$mask))];
InstrItinClass Itinerary = itin;
}
class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
dag OutOperandList = (outs);
- dag InOperandList = (ins CPURegs:$rs, uimm16:$mask);
+ dag InOperandList = (ins GPR32:$rs, uimm16:$mask);
string AsmString = !strconcat(instr_asm, "\t$rs, $mask");
- list<dag> Pattern = [(OpNode CPURegs:$rs, immZExt10:$mask)];
+ list<dag> Pattern = [(OpNode GPR32:$rs, immZExt10:$mask)];
InstrItinClass Itinerary = itin;
}
class DPA_W_PH_DESC_BASE<string instr_asm, SDPatternOperator OpNode> {
dag OutOperandList = (outs ACRegsDSP:$ac);
- dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin);
+ dag InOperandList = (ins GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin);
string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt");
list<dag> Pattern = [(set ACRegsDSP:$ac,
- (OpNode CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin))];
+ (OpNode GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin))];
string Constraints = "$acin = $ac";
}
class MULT_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
dag OutOperandList = (outs ACRegsDSP:$ac);
- dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt);
+ dag InOperandList = (ins GPR32:$rs, GPR32:$rt);
string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt");
- list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode CPURegs:$rs, CPURegs:$rt))];
+ list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode GPR32:$rs, GPR32:$rt))];
InstrItinClass Itinerary = itin;
int AddedComplexity = 20;
bit isCommutable = 1;
@@ -461,17 +461,17 @@ class MULT_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class MADD_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
dag OutOperandList = (outs ACRegsDSP:$ac);
- dag InOperandList = (ins CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin);
+ dag InOperandList = (ins GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin);
string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt");
list<dag> Pattern = [(set ACRegsDSP:$ac,
- (OpNode CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin))];
+ (OpNode GPR32:$rs, GPR32:$rt, ACRegsDSP:$acin))];
InstrItinClass Itinerary = itin;
int AddedComplexity = 20;
string Constraints = "$acin = $ac";
}
class MFHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rd);
+ dag OutOperandList = (outs GPR32:$rd);
dag InOperandList = (ins RC:$ac);
string AsmString = !strconcat(instr_asm, "\t$rd, $ac");
InstrItinClass Itinerary = itin;
@@ -479,13 +479,13 @@ class MFHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> {
class MTHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> {
dag OutOperandList = (outs RC:$ac);
- dag InOperandList = (ins CPURegs:$rs);
+ dag InOperandList = (ins GPR32:$rs);
string AsmString = !strconcat(instr_asm, "\t$rs, $ac");
InstrItinClass Itinerary = itin;
}
class BPOSGE32_PSEUDO_DESC_BASE<SDPatternOperator OpNode, InstrItinClass itin> :
- MipsPseudo<(outs CPURegs:$dst), (ins), [(set CPURegs:$dst, (OpNode))]> {
+ MipsPseudo<(outs GPR32:$dst), (ins), [(set GPR32:$dst, (OpNode))]> {
bit usesCustomInserter = 1;
}
@@ -501,10 +501,10 @@ class BPOSGE32_DESC_BASE<string instr_asm, InstrItinClass itin> {
class INSV_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin> {
- dag OutOperandList = (outs CPURegs:$rt);
- dag InOperandList = (ins CPURegs:$src, CPURegs:$rs);
+ dag OutOperandList = (outs GPR32:$rt);
+ dag InOperandList = (ins GPR32:$src, GPR32:$rs);
string AsmString = !strconcat(instr_asm, "\t$rt, $rs");
- list<dag> Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs))];
+ list<dag> Pattern = [(set GPR32:$rt, (OpNode GPR32:$src, GPR32:$rs))];
InstrItinClass Itinerary = itin;
string Constraints = "$src = $rt";
}
@@ -547,26 +547,26 @@ class SUBQ_S_PH_DESC : ADDU_QB_DESC_BASE<"subq_s.ph", int_mips_subq_s_ph,
Defs<[DSPOutFlag20]>;
class ADDQ_S_W_DESC : ADDU_QB_DESC_BASE<"addq_s.w", int_mips_addq_s_w,
- NoItinerary, CPURegs, CPURegs>,
+ NoItinerary, GPR32, GPR32>,
IsCommutable, Defs<[DSPOutFlag20]>;
class SUBQ_S_W_DESC : ADDU_QB_DESC_BASE<"subq_s.w", int_mips_subq_s_w,
- NoItinerary, CPURegs, CPURegs>,
+ NoItinerary, GPR32, GPR32>,
Defs<[DSPOutFlag20]>;
class ADDSC_DESC : ADDU_QB_DESC_BASE<"addsc", null_frag, NoItinerary,
- CPURegs, CPURegs>, IsCommutable,
+ GPR32, GPR32>, IsCommutable,
Defs<[DSPCarry]>;
class ADDWC_DESC : ADDU_QB_DESC_BASE<"addwc", null_frag, NoItinerary,
- CPURegs, CPURegs>,
+ GPR32, GPR32>,
IsCommutable, Uses<[DSPCarry]>, Defs<[DSPOutFlag20]>;
class MODSUB_DESC : ADDU_QB_DESC_BASE<"modsub", int_mips_modsub, NoItinerary,
- CPURegs, CPURegs>;
+ GPR32, GPR32>;
class RADDU_W_QB_DESC : RADDU_W_QB_DESC_BASE<"raddu.w.qb", int_mips_raddu_w_qb,
- NoItinerary, CPURegs, DSPRegs>;
+ NoItinerary, GPR32, DSPRegs>;
// Absolute value
class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph,
@@ -574,7 +574,7 @@ class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph,
Defs<[DSPOutFlag20]>;
class ABSQ_S_W_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.w", int_mips_absq_s_w,
- NoItinerary, CPURegs>,
+ NoItinerary, GPR32>,
Defs<[DSPOutFlag20]>;
// Precision reduce/expand
@@ -584,12 +584,12 @@ class PRECRQ_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.qb.ph",
class PRECRQ_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.ph.w",
int_mips_precrq_ph_w,
- NoItinerary, DSPRegs, CPURegs>;
+ NoItinerary, DSPRegs, GPR32>;
class PRECRQ_RS_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq_rs.ph.w",
int_mips_precrq_rs_ph_w,
NoItinerary, DSPRegs,
- CPURegs>,
+ GPR32>,
Defs<[DSPOutFlag22]>;
class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph",
@@ -600,11 +600,11 @@ class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph",
class PRECEQ_W_PHL_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phl",
int_mips_preceq_w_phl,
- NoItinerary, CPURegs, DSPRegs>;
+ NoItinerary, GPR32, DSPRegs>;
class PRECEQ_W_PHR_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phr",
int_mips_preceq_w_phr,
- NoItinerary, CPURegs, DSPRegs>;
+ NoItinerary, GPR32, DSPRegs>;
class PRECEQU_PH_QBL_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbl",
int_mips_precequ_ph_qbl,
@@ -682,18 +682,18 @@ class SHRAV_R_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.ph", int_mips_shra_r_ph,
NoItinerary, DSPRegs>;
class SHLL_S_W_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.w", int_mips_shll_s_w,
- immZExt5, NoItinerary, CPURegs>,
+ immZExt5, NoItinerary, GPR32>,
Defs<[DSPOutFlag22]>;
class SHLLV_S_W_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.w", int_mips_shll_s_w,
- NoItinerary, CPURegs>,
+ NoItinerary, GPR32>,
Defs<[DSPOutFlag22]>;
class SHRA_R_W_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.w", int_mips_shra_r_w,
- immZExt5, NoItinerary, CPURegs>;
+ immZExt5, NoItinerary, GPR32>;
class SHRAV_R_W_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.w", int_mips_shra_r_w,
- NoItinerary, CPURegs>;
+ NoItinerary, GPR32>;
// Multiplication
class MULEU_S_PH_QBL_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbl",
@@ -708,12 +708,12 @@ class MULEU_S_PH_QBR_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbr",
class MULEQ_S_W_PHL_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phl",
int_mips_muleq_s_w_phl,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
IsCommutable, Defs<[DSPOutFlag21]>;
class MULEQ_S_W_PHR_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phr",
int_mips_muleq_s_w_phr,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
IsCommutable, Defs<[DSPOutFlag21]>;
class MULQ_RS_PH_DESC : ADDU_QB_DESC_BASE<"mulq_rs.ph", int_mips_mulq_rs_ph,
@@ -786,16 +786,16 @@ class CMPU_LE_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.le.qb",
class CMPGU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.eq.qb",
int_mips_cmpgu_eq_qb,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
IsCommutable;
class CMPGU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.lt.qb",
int_mips_cmpgu_lt_qb,
- NoItinerary, CPURegs, DSPRegs>;
+ NoItinerary, GPR32, DSPRegs>;
class CMPGU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.le.qb",
int_mips_cmpgu_le_qb,
- NoItinerary, CPURegs, DSPRegs>;
+ NoItinerary, GPR32, DSPRegs>;
class CMP_EQ_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.eq.ph", int_mips_cmp_eq_ph,
NoItinerary, DSPRegs>,
@@ -811,7 +811,7 @@ class CMP_LE_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.le.ph", int_mips_cmp_le_ph,
// Misc
class BITREV_DESC : ABSQ_S_PH_R2_DESC_BASE<"bitrev", int_mips_bitrev,
- NoItinerary, CPURegs>;
+ NoItinerary, GPR32>;
class PACKRL_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"packrl.ph", int_mips_packrl_ph,
NoItinerary, DSPRegs, DSPRegs>;
@@ -823,10 +823,10 @@ class REPL_PH_DESC : REPL_DESC_BASE<"repl.ph", int_mips_repl_ph, immZExt10,
NoItinerary, DSPRegs>;
class REPLV_QB_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.qb", int_mips_repl_qb,
- NoItinerary, DSPRegs, CPURegs>;
+ NoItinerary, DSPRegs, GPR32>;
class REPLV_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.ph", int_mips_repl_ph,
- NoItinerary, DSPRegs, CPURegs>;
+ NoItinerary, DSPRegs, GPR32>;
class PICK_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.qb", int_mips_pick_qb,
NoItinerary, DSPRegs, DSPRegs>,
@@ -945,31 +945,31 @@ class SUBQH_R_PH_DESC : ADDUH_QB_DESC_BASE<"subqh_r.ph", int_mips_subqh_r_ph,
NoItinerary, DSPRegs>;
class ADDQH_W_DESC : ADDUH_QB_DESC_BASE<"addqh.w", int_mips_addqh_w,
- NoItinerary, CPURegs>, IsCommutable;
+ NoItinerary, GPR32>, IsCommutable;
class ADDQH_R_W_DESC : ADDUH_QB_DESC_BASE<"addqh_r.w", int_mips_addqh_r_w,
- NoItinerary, CPURegs>, IsCommutable;
+ NoItinerary, GPR32>, IsCommutable;
class SUBQH_W_DESC : ADDUH_QB_DESC_BASE<"subqh.w", int_mips_subqh_w,
- NoItinerary, CPURegs>;
+ NoItinerary, GPR32>;
class SUBQH_R_W_DESC : ADDUH_QB_DESC_BASE<"subqh_r.w", int_mips_subqh_r_w,
- NoItinerary, CPURegs>;
+ NoItinerary, GPR32>;
// Comparison
class CMPGDU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.eq.qb",
int_mips_cmpgdu_eq_qb,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
IsCommutable, Defs<[DSPCCond]>;
class CMPGDU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.lt.qb",
int_mips_cmpgdu_lt_qb,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
Defs<[DSPCCond]>;
class CMPGDU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.le.qb",
int_mips_cmpgdu_le_qb,
- NoItinerary, CPURegs, DSPRegs>,
+ NoItinerary, GPR32, DSPRegs>,
Defs<[DSPCCond]>;
// Absolute
@@ -987,11 +987,11 @@ class MUL_S_PH_DESC : ADDUH_QB_DESC_BASE<"mul_s.ph", int_mips_mul_s_ph,
Defs<[DSPOutFlag21]>;
class MULQ_S_W_DESC : ADDUH_QB_DESC_BASE<"mulq_s.w", int_mips_mulq_s_w,
- NoItinerary, CPURegs>, IsCommutable,
+ NoItinerary, GPR32>, IsCommutable,
Defs<[DSPOutFlag21]>;
class MULQ_RS_W_DESC : ADDUH_QB_DESC_BASE<"mulq_rs.w", int_mips_mulq_rs_w,
- NoItinerary, CPURegs>, IsCommutable,
+ NoItinerary, GPR32>, IsCommutable,
Defs<[DSPOutFlag21]>;
class MULQ_S_PH_DESC : ADDU_QB_DESC_BASE<"mulq_s.ph", int_mips_mulq_s_ph,
@@ -1031,12 +1031,12 @@ class PRECR_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precr.qb.ph",
class PRECR_SRA_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra.ph.w",
int_mips_precr_sra_ph_w,
NoItinerary, DSPRegs,
- CPURegs>;
+ GPR32>;
class PRECR_SRA_R_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra_r.ph.w",
int_mips_precr_sra_r_ph_w,
NoItinerary, DSPRegs,
- CPURegs>;
+ GPR32>;
// Shift
class SHRA_QB_DESC : SHLL_QB_R2_DESC_BASE<"shra.qb", null_frag, immZExt3,
@@ -1242,8 +1242,8 @@ def PREPEND : PREPEND_ENC, PREPEND_DESC;
// Pseudos.
let isPseudo = 1 in {
// Pseudo instructions for loading and storing accumulator registers.
- defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSP>;
- defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSP>;
+ defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSPOpnd>;
+ defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSPOpnd>;
// Pseudos for loading and storing ccond field of DSP control register.
defm LOAD_CCOND_DSP : LoadM<"load_ccond_dsp", DSPCC>;
@@ -1279,19 +1279,19 @@ class BitconvertPat<ValueType DstVT, ValueType SrcVT, RegisterClass DstRC,
DSPPat<(DstVT (bitconvert (SrcVT SrcRC:$src))),
(COPY_TO_REGCLASS SrcRC:$src, DstRC)>;
-def : BitconvertPat<i32, v2i16, CPURegs, DSPRegs>;
-def : BitconvertPat<i32, v4i8, CPURegs, DSPRegs>;
-def : BitconvertPat<v2i16, i32, DSPRegs, CPURegs>;
-def : BitconvertPat<v4i8, i32, DSPRegs, CPURegs>;
+def : BitconvertPat<i32, v2i16, GPR32, DSPRegs>;
+def : BitconvertPat<i32, v4i8, GPR32, DSPRegs>;
+def : BitconvertPat<v2i16, i32, DSPRegs, GPR32>;
+def : BitconvertPat<v4i8, i32, DSPRegs, GPR32>;
def : DSPPat<(v2i16 (load addr:$a)),
(v2i16 (COPY_TO_REGCLASS (LW addr:$a), DSPRegs))>;
def : DSPPat<(v4i8 (load addr:$a)),
(v4i8 (COPY_TO_REGCLASS (LW addr:$a), DSPRegs))>;
def : DSPPat<(store (v2i16 DSPRegs:$val), addr:$a),
- (SW (COPY_TO_REGCLASS DSPRegs:$val, CPURegs), addr:$a)>;
+ (SW (COPY_TO_REGCLASS DSPRegs:$val, GPR32), addr:$a)>;
def : DSPPat<(store (v4i8 DSPRegs:$val), addr:$a),
- (SW (COPY_TO_REGCLASS DSPRegs:$val, CPURegs), addr:$a)>;
+ (SW (COPY_TO_REGCLASS DSPRegs:$val, GPR32), addr:$a)>;
// Binary operations.
class DSPBinPat<Instruction Inst, ValueType ValTy, SDPatternOperator Node,
@@ -1384,8 +1384,8 @@ def : DSPSelectCCPatInv<PseudoCMPU_LE_QB, PseudoPICK_QB, v4i8, SETUGT>;
// Extr patterns.
class EXTR_W_TY1_R2_Pat<SDPatternOperator OpNode, Instruction Instr> :
- DSPPat<(i32 (OpNode CPURegs:$rs, ACRegsDSP:$ac)),
- (Instr ACRegsDSP:$ac, CPURegs:$rs)>;
+ DSPPat<(i32 (OpNode GPR32:$rs, ACRegsDSP:$ac)),
+ (Instr ACRegsDSP:$ac, GPR32:$rs)>;
class EXTR_W_TY1_R1_Pat<SDPatternOperator OpNode, Instruction Instr> :
DSPPat<(i32 (OpNode immZExt5:$shift, ACRegsDSP:$ac)),
diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 928a43d..545a38d 100644
--- a/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -437,7 +437,7 @@ bool MemDefsUses::hasHazard_(const MachineInstr &MI) {
// Check underlying object list.
if (getUnderlyingObjects(MI, Objs)) {
- for (SmallVector<const Value *, 4>::const_iterator I = Objs.begin();
+ for (SmallVectorImpl<const Value *>::const_iterator I = Objs.begin();
I != Objs.end(); ++I)
HasHazard |= updateDefsUses(*I, MI.mayStore());
@@ -473,7 +473,7 @@ getUnderlyingObjects(const MachineInstr &MI,
SmallVector<Value *, 4> Objs;
GetUnderlyingObjects(const_cast<Value *>(V), Objs);
- for (SmallVector<Value*, 4>::iterator I = Objs.begin(), E = Objs.end();
+ for (SmallVectorImpl<Value *>::iterator I = Objs.begin(), E = Objs.end();
I != E; ++I) {
if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(*I)) {
if (PSV->isAliased(MFI))
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index a1de174..0002a5f 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -57,7 +57,8 @@ bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
/// GOT address into a register.
SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
- return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy()).getNode();
+ return CurDAG->getRegister(GlobalBaseReg,
+ getTargetLowering()->getPointerTy()).getNode();
}
/// ComplexPattern used on MipsInstrInfo
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 6351073..a62e84f 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -346,11 +346,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::FNEG, MVT::f64, Expand);
}
- setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
- setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand);
- setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
- setOperationAction(ISD::EHSELECTION, MVT::i64, Expand);
-
setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
setOperationAction(ISD::VAARG, MVT::Other, Expand);
@@ -390,6 +385,8 @@ MipsTargetLowering(MipsTargetMachine &TM)
setTruncStoreAction(MVT::i64, MVT::i32, Custom);
}
+ setOperationAction(ISD::TRAP, MVT::Other, Legal);
+
setTargetDAGCombine(ISD::SDIVREM);
setTargetDAGCombine(ISD::UDIVREM);
setTargetDAGCombine(ISD::SELECT);
@@ -524,9 +521,10 @@ static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True,
SDValue False, SDLoc DL) {
ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2));
bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue());
+ SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,
- True.getValueType(), True, False, Cond);
+ True.getValueType(), True, FCC0, False, Cond);
}
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
@@ -1084,9 +1082,9 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI,
BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
.addReg(Mips::ZERO).addImm(MaskImm);
BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
- .addReg(ShiftAmt).addReg(MaskUpper);
+ .addReg(MaskUpper).addReg(ShiftAmt);
BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
- BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(ShiftAmt).addReg(Incr);
+ BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt);
// atomic.load.binop
// loopMBB:
@@ -1147,7 +1145,7 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI,
BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1)
.addReg(OldVal).addReg(Mask);
BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes)
- .addReg(ShiftAmt).addReg(MaskedOldVal1);
+ .addReg(MaskedOldVal1).addReg(ShiftAmt);
BuildMI(BB, DL, TII->get(Mips::SLL), SllRes)
.addReg(SrlRes).addImm(ShiftImm);
BuildMI(BB, DL, TII->get(Mips::SRA), Dest)
@@ -1334,16 +1332,16 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI,
BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)
.addReg(Mips::ZERO).addImm(MaskImm);
BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)
- .addReg(ShiftAmt).addReg(MaskUpper);
+ .addReg(MaskUpper).addReg(ShiftAmt);
BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal)
.addReg(CmpVal).addImm(MaskImm);
BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal)
- .addReg(ShiftAmt).addReg(MaskedCmpVal);
+ .addReg(MaskedCmpVal).addReg(ShiftAmt);
BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal)
.addReg(NewVal).addImm(MaskImm);
BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal)
- .addReg(ShiftAmt).addReg(MaskedNewVal);
+ .addReg(MaskedNewVal).addReg(ShiftAmt);
// loop1MBB:
// ll oldval,0(alginedaddr)
@@ -1379,7 +1377,7 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI,
int64_t ShiftImm = (Size == 1) ? 24 : 16;
BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes)
- .addReg(ShiftAmt).addReg(MaskedOldVal0);
+ .addReg(MaskedOldVal0).addReg(ShiftAmt);
BuildMI(BB, DL, TII->get(Mips::SLL), SllRes)
.addReg(SrlRes).addImm(ShiftImm);
BuildMI(BB, DL, TII->get(Mips::SRA), Dest)
@@ -1443,8 +1441,9 @@ lowerBRCOND(SDValue Op, SelectionDAG &DAG) const
(Mips::CondCode)cast<ConstantSDNode>(CCNode)->getZExtValue();
unsigned Opc = invertFPCondCodeUser(CC) ? Mips::BRANCH_F : Mips::BRANCH_T;
SDValue BrCode = DAG.getConstant(Opc, MVT::i32);
+ SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,
- Dest, CondRes);
+ FCC0, Dest, CondRes);
}
SDValue MipsTargetLowering::
@@ -2328,9 +2327,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc DL = CLI.DL;
- SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
- SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
+ SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
+ SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
bool &IsTailCall = CLI.IsTailCall;
@@ -2620,9 +2619,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
if (RegVT == MVT::i32)
RC = Subtarget->inMips16Mode()? &Mips::CPU16RegsRegClass :
- &Mips::CPURegsRegClass;
+ &Mips::GPR32RegClass;
else if (RegVT == MVT::i64)
- RC = &Mips::CPU64RegsRegClass;
+ RC = &Mips::GPR64RegClass;
else if (RegVT == MVT::f32)
RC = &Mips::FGR32RegClass;
else if (RegVT == MVT::f64)
@@ -2885,7 +2884,7 @@ MipsTargetLowering::getSingleConstraintMatchWeight(
/// to an LLVM register class, return a register of 0 and the register class
/// pointer.
std::pair<unsigned, const TargetRegisterClass*> MipsTargetLowering::
-getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
+getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const
{
if (Constraint.size() == 1) {
switch (Constraint[0]) {
@@ -2895,12 +2894,12 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) {
if (Subtarget->inMips16Mode())
return std::make_pair(0U, &Mips::CPU16RegsRegClass);
- return std::make_pair(0U, &Mips::CPURegsRegClass);
+ return std::make_pair(0U, &Mips::GPR32RegClass);
}
if (VT == MVT::i64 && !HasMips64)
- return std::make_pair(0U, &Mips::CPURegsRegClass);
+ return std::make_pair(0U, &Mips::GPR32RegClass);
if (VT == MVT::i64 && HasMips64)
- return std::make_pair(0U, &Mips::CPU64RegsRegClass);
+ return std::make_pair(0U, &Mips::GPR64RegClass);
// This will generate an error message
return std::make_pair(0u, static_cast<const TargetRegisterClass*>(0));
case 'f':
@@ -2914,9 +2913,9 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
break;
case 'c': // register suitable for indirect jump
if (VT == MVT::i32)
- return std::make_pair((unsigned)Mips::T9, &Mips::CPURegsRegClass);
+ return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass);
assert(VT == MVT::i64 && "Unexpected type.");
- return std::make_pair((unsigned)Mips::T9_64, &Mips::CPU64RegsRegClass);
+ return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);
case 'l': // register suitable for indirect jump
if (VT == MVT::i32)
return std::make_pair((unsigned)Mips::LO, &Mips::LORegsRegClass);
@@ -3388,7 +3387,7 @@ copyByValRegs(SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains,
void MipsTargetLowering::
passByValArg(SDValue Chain, SDLoc DL,
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
- SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr,
+ SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg,
const MipsCC &CC, const ByValArgInfo &ByVal,
const ISD::ArgFlagsTy &Flags, bool isLittle) const {
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index fe043ae..123a2a6 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -282,7 +282,7 @@ namespace llvm {
/// Return pointer to array of integer argument registers.
const uint16_t *intArgRegs() const;
- typedef SmallVector<ByValArgInfo, 2>::const_iterator byval_iterator;
+ typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator;
byval_iterator byval_begin() const { return ByValArgs.begin(); }
byval_iterator byval_end() const { return ByValArgs.end(); }
@@ -386,7 +386,7 @@ namespace llvm {
/// passByValArg - Pass a byval argument in registers or on stack.
void passByValArg(SDValue Chain, SDLoc DL,
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
- SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr,
+ SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg,
const MipsCC &CC, const ByValArgInfo &ByVal,
const ISD::ArgFlagsTy &Flags, bool isLittle) const;
@@ -435,7 +435,7 @@ namespace llvm {
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
+ MVT VT) const;
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. If hasMemory is
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index e2acf28..b992e77 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -24,12 +24,13 @@
//===----------------------------------------------------------------------===//
// Floating Point Compare and Branch
-def SDT_MipsFPBrcond : SDTypeProfile<0, 2, [SDTCisInt<0>,
- SDTCisVT<1, OtherVT>]>;
+def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisInt<0>,
+ SDTCisVT<1, i32>,
+ SDTCisVT<2, OtherVT>]>;
def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>,
SDTCisVT<2, i32>]>;
-def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
- SDTCisSameAs<1, 2>]>;
+def SDT_MipsCMovFP : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisVT<2, i32>,
+ SDTCisSameAs<1, 3>]>;
def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
SDTCisVT<1, i32>,
@@ -88,7 +89,7 @@ def fpimm0neg : PatLeaf<(fpimm), [{
// Only S32 and D32 are supported right now.
//===----------------------------------------------------------------------===//
-class ADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, bit IsComm,
+class ADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, bit IsComm,
SDPatternOperator OpNode= null_frag> :
InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft),
!strconcat(opstr, "\t$fd, $fs, $ft"),
@@ -98,15 +99,15 @@ class ADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, bit IsComm,
multiclass ADDS_M<string opstr, InstrItinClass Itin, bit IsComm,
SDPatternOperator OpNode = null_frag> {
- def _D32 : ADDS_FT<opstr, AFGR64, Itin, IsComm, OpNode>,
+ def _D32 : ADDS_FT<opstr, AFGR64RegsOpnd, Itin, IsComm, OpNode>,
Requires<[NotFP64bit, HasStdEnc]>;
- def _D64 : ADDS_FT<opstr, FGR64, Itin, IsComm, OpNode>,
+ def _D64 : ADDS_FT<opstr, FGR64RegsOpnd, Itin, IsComm, OpNode>,
Requires<[IsFP64bit, HasStdEnc]> {
string DecoderNamespace = "Mips64";
}
}
-class ABSS_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC,
+class ABSS_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"),
[(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR>,
@@ -114,44 +115,34 @@ class ABSS_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC,
multiclass ABSS_M<string opstr, InstrItinClass Itin,
SDPatternOperator OpNode= null_frag> {
- def _D32 : ABSS_FT<opstr, AFGR64, AFGR64, Itin, OpNode>,
+ def _D32 : ABSS_FT<opstr, AFGR64RegsOpnd, AFGR64RegsOpnd, Itin, OpNode>,
Requires<[NotFP64bit, HasStdEnc]>;
- def _D64 : ABSS_FT<opstr, FGR64, FGR64, Itin, OpNode>,
+ def _D64 : ABSS_FT<opstr, FGR64RegsOpnd, FGR64RegsOpnd, Itin, OpNode>,
Requires<[IsFP64bit, HasStdEnc]> {
string DecoderNamespace = "Mips64";
}
}
multiclass ROUND_M<string opstr, InstrItinClass Itin> {
- def _D32 : ABSS_FT<opstr, FGR32, AFGR64, Itin>,
+ def _D32 : ABSS_FT<opstr, FGR32RegsOpnd, AFGR64RegsOpnd, Itin>,
Requires<[NotFP64bit, HasStdEnc]>;
- def _D64 : ABSS_FT<opstr, FGR32, FGR64, Itin>,
+ def _D64 : ABSS_FT<opstr, FGR32RegsOpnd, FGR64RegsOpnd, Itin>,
Requires<[IsFP64bit, HasStdEnc]> {
let DecoderNamespace = "Mips64";
}
}
-class MFC1_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC,
+class MFC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"),
[(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>;
-class MTC1_FT<string opstr, RegisterClass DstRC, RegisterClass SrcRC,
+class MTC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
[(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>;
-class MFC1_FT_CCR<string opstr, RegisterClass DstRC, RegisterOperand SrcRC,
- InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
- InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"),
- [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>;
-
-class MTC1_FT_CCR<string opstr, RegisterOperand DstRC, RegisterClass SrcRC,
- InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
- InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
- [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>;
-
-class LW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class LW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
Operand MemOpnd, SDPatternOperator OpNode= null_frag> :
InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
[(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> {
@@ -159,7 +150,7 @@ class LW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
let mayLoad = 1;
}
-class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class SW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
Operand MemOpnd, SDPatternOperator OpNode= null_frag> :
InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
[(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> {
@@ -167,20 +158,20 @@ class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
let mayStore = 1;
}
-class MADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class MADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
SDPatternOperator OpNode = null_frag> :
InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
!strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
[(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))], Itin, FrmFR>;
-class NMADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin,
+class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
SDPatternOperator OpNode = null_frag> :
InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
!strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
[(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],
Itin, FrmFR>;
-class LWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
+class LWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs DRC:$fd), (ins PRC:$base, PRC:$index),
!strconcat(opstr, "\t$fd, ${index}(${base})"),
@@ -188,7 +179,7 @@ class LWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
let AddedComplexity = 20;
}
-class SWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
+class SWXC1_FT<string opstr, RegisterOperand DRC, RegisterOperand PRC,
InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
InstSE<(outs), (ins DRC:$fs, PRC:$base, PRC:$index),
!strconcat(opstr, "\t$fs, ${index}(${base})"),
@@ -198,13 +189,13 @@ class SWXC1_FT<string opstr, RegisterClass DRC, RegisterClass PRC,
class BC1F_FT<string opstr, InstrItinClass Itin,
SDPatternOperator Op = null_frag> :
- InstSE<(outs), (ins brtarget:$offset), !strconcat(opstr, "\t$offset"),
- [(MipsFPBrcond Op, bb:$offset)], Itin, FrmFI> {
+ InstSE<(outs), (ins FCCRegsOpnd:$fcc, brtarget:$offset),
+ !strconcat(opstr, "\t$fcc, $offset"),
+ [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, FrmFI> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
let Defs = [AT];
- let Uses = [FCR31];
}
class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin,
@@ -212,17 +203,53 @@ class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin,
InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond),
!strconcat("c.$cond.", typestr, "\t$fs, $ft"),
[(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR> {
- let Defs = [FCR31];
-}
+ let Defs = [FCC0];
+ let isCodeGenOnly = 1;
+}
+
+class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC> :
+ InstSE<(outs), (ins RC:$fs, RC:$ft),
+ !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], IIFcmp,
+ FrmFR>;
+
+multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt> {
+ def C_F_#NAME : C_COND_FT<"f", TypeStr, RC>, C_COND_FM<fmt, 0>;
+ def C_UN_#NAME : C_COND_FT<"un", TypeStr, RC>, C_COND_FM<fmt, 1>;
+ def C_EQ_#NAME : C_COND_FT<"eq", TypeStr, RC>, C_COND_FM<fmt, 2>;
+ def C_UEQ_#NAME : C_COND_FT<"ueq", TypeStr, RC>, C_COND_FM<fmt, 3>;
+ def C_OLT_#NAME : C_COND_FT<"olt", TypeStr, RC>, C_COND_FM<fmt, 4>;
+ def C_ULT_#NAME : C_COND_FT<"ult", TypeStr, RC>, C_COND_FM<fmt, 5>;
+ def C_OLE_#NAME : C_COND_FT<"ole", TypeStr, RC>, C_COND_FM<fmt, 6>;
+ def C_ULE_#NAME : C_COND_FT<"ule", TypeStr, RC>, C_COND_FM<fmt, 7>;
+ def C_SF_#NAME : C_COND_FT<"sf", TypeStr, RC>, C_COND_FM<fmt, 8>;
+ def C_NGLE_#NAME : C_COND_FT<"ngle", TypeStr, RC>, C_COND_FM<fmt, 9>;
+ def C_SEQ_#NAME : C_COND_FT<"seq", TypeStr, RC>, C_COND_FM<fmt, 10>;
+ def C_NGL_#NAME : C_COND_FT<"ngl", TypeStr, RC>, C_COND_FM<fmt, 11>;
+ def C_LT_#NAME : C_COND_FT<"lt", TypeStr, RC>, C_COND_FM<fmt, 12>;
+ def C_NGE_#NAME : C_COND_FT<"nge", TypeStr, RC>, C_COND_FM<fmt, 13>;
+ def C_LE_#NAME : C_COND_FT<"le", TypeStr, RC>, C_COND_FM<fmt, 14>;
+ def C_NGT_#NAME : C_COND_FT<"ngt", TypeStr, RC>, C_COND_FM<fmt, 15>;
+}
+
+defm S : C_COND_M<"s", FGR32RegsOpnd, 16>;
+defm D32 : C_COND_M<"d", AFGR64RegsOpnd, 17>,
+ Requires<[NotFP64bit, HasStdEnc]>;
+let DecoderNamespace = "Mips64" in
+defm D64 : C_COND_M<"d", FGR64RegsOpnd, 17>, Requires<[IsFP64bit, HasStdEnc]>;
//===----------------------------------------------------------------------===//
// Floating Point Instructions
//===----------------------------------------------------------------------===//
-def ROUND_W_S : ABSS_FT<"round.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xc, 16>;
-def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xd, 16>;
-def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xe, 16>;
-def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0xf, 16>;
-def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32, FGR32, IIFcvt>, ABSS_FM<0x24, 16>;
+def ROUND_W_S : ABSS_FT<"round.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xc, 16>;
+def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xd, 16>;
+def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xe, 16>;
+def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xf, 16>;
+def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x24, 16>;
defm ROUND_W : ROUND_M<"round.w.d", IIFcvt>, ABSS_FM<0xc, 17>;
defm TRUNC_W : ROUND_M<"trunc.w.d", IIFcvt>, ABSS_FM<0xd, 17>;
@@ -231,54 +258,72 @@ defm FLOOR_W : ROUND_M<"floor.w.d", IIFcvt>, ABSS_FM<0xf, 17>;
defm CVT_W : ROUND_M<"cvt.w.d", IIFcvt>, ABSS_FM<0x24, 17>;
let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in {
- def ROUND_L_S : ABSS_FT<"round.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x8, 16>;
- def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64, FGR64, IIFcvt>,
+ def ROUND_L_S : ABSS_FT<"round.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x8, 16>;
+ def ROUND_L_D64 : ABSS_FT<"round.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
ABSS_FM<0x8, 17>;
- def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x9, 16>;
- def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64, FGR64, IIFcvt>,
+ def TRUNC_L_S : ABSS_FT<"trunc.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x9, 16>;
+ def TRUNC_L_D64 : ABSS_FT<"trunc.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
ABSS_FM<0x9, 17>;
- def CEIL_L_S : ABSS_FT<"ceil.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xa, 16>;
- def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0xa, 17>;
- def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0xb, 16>;
- def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64, FGR64, IIFcvt>,
+ def CEIL_L_S : ABSS_FT<"ceil.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xa, 16>;
+ def CEIL_L_D64 : ABSS_FT<"ceil.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0xa, 17>;
+ def FLOOR_L_S : ABSS_FT<"floor.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0xb, 16>;
+ def FLOOR_L_D64 : ABSS_FT<"floor.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
ABSS_FM<0xb, 17>;
}
-def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32, FGR32, IIFcvt>, ABSS_FM<0x20, 20>;
-def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x25, 16>;
-def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64, FGR64, IIFcvt>, ABSS_FM<0x25, 17>;
+def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x20, 20>;
+def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x25, 16>;
+def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0x25, 17>;
let Predicates = [NotFP64bit, HasStdEnc] in {
- def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32, AFGR64, IIFcvt>, ABSS_FM<0x20, 17>;
- def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>;
- def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>;
+ def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32RegsOpnd, AFGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0x20, 17>;
+ def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x21, 20>;
+ def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x21, 16>;
}
let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in {
- def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 17>;
- def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 21>;
- def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>;
- def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>;
- def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>;
+ def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32RegsOpnd, FGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0x20, 17>;
+ def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32RegsOpnd, FGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0x20, 21>;
+ def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x21, 20>;
+ def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64RegsOpnd, FGR32RegsOpnd, IIFcvt>,
+ ABSS_FM<0x21, 16>;
+ def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64RegsOpnd, FGR64RegsOpnd, IIFcvt>,
+ ABSS_FM<0x21, 21>;
}
let isPseudo = 1, isCodeGenOnly = 1 in {
- def PseudoCVT_S_W : ABSS_FT<"", FGR32, CPURegs, IIFcvt>;
- def PseudoCVT_D32_W : ABSS_FT<"", AFGR64, CPURegs, IIFcvt>;
- def PseudoCVT_S_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>;
- def PseudoCVT_D64_W : ABSS_FT<"", FGR64, CPURegs, IIFcvt>;
- def PseudoCVT_D64_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>;
+ def PseudoCVT_S_W : ABSS_FT<"", FGR32RegsOpnd, GPR32Opnd, IIFcvt>;
+ def PseudoCVT_D32_W : ABSS_FT<"", AFGR64RegsOpnd, GPR32Opnd, IIFcvt>;
+ def PseudoCVT_S_L : ABSS_FT<"", FGR64RegsOpnd, GPR64Opnd, IIFcvt>;
+ def PseudoCVT_D64_W : ABSS_FT<"", FGR64RegsOpnd, GPR32Opnd, IIFcvt>;
+ def PseudoCVT_D64_L : ABSS_FT<"", FGR64RegsOpnd, GPR64Opnd, IIFcvt>;
}
let Predicates = [NoNaNsFPMath, HasStdEnc] in {
- def FABS_S : ABSS_FT<"abs.s", FGR32, FGR32, IIFcvt, fabs>, ABSS_FM<0x5, 16>;
- def FNEG_S : ABSS_FT<"neg.s", FGR32, FGR32, IIFcvt, fneg>, ABSS_FM<0x7, 16>;
+ def FABS_S : ABSS_FT<"abs.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt, fabs>,
+ ABSS_FM<0x5, 16>;
+ def FNEG_S : ABSS_FT<"neg.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFcvt, fneg>,
+ ABSS_FM<0x7, 16>;
defm FABS : ABSS_M<"abs.d", IIFcvt, fabs>, ABSS_FM<0x5, 17>;
defm FNEG : ABSS_M<"neg.d", IIFcvt, fneg>, ABSS_FM<0x7, 17>;
}
-def FSQRT_S : ABSS_FT<"sqrt.s", FGR32, FGR32, IIFsqrtSingle, fsqrt>,
- ABSS_FM<0x4, 16>;
+def FSQRT_S : ABSS_FT<"sqrt.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFsqrtSingle,
+ fsqrt>, ABSS_FM<0x4, 16>;
defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>;
// The odd-numbered registers are only referenced when doing loads,
@@ -287,134 +332,166 @@ defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>;
// regardless of register aliasing.
/// Move Control Registers From/To CPU Registers
-def CFC1 : MFC1_FT_CCR<"cfc1", CPURegs, CCROpnd, IIFmove>, MFC1_FM<2>;
-def CTC1 : MTC1_FT_CCR<"ctc1", CCROpnd, CPURegs, IIFmove>, MFC1_FM<6>;
-def MFC1 : MFC1_FT<"mfc1", CPURegs, FGR32, IIFmove, bitconvert>, MFC1_FM<0>;
-def MTC1 : MTC1_FT<"mtc1", FGR32, CPURegs, IIFmove, bitconvert>, MFC1_FM<4>;
-def DMFC1 : MFC1_FT<"dmfc1", CPU64Regs, FGR64, IIFmove, bitconvert>, MFC1_FM<1>;
-def DMTC1 : MTC1_FT<"dmtc1", FGR64, CPU64Regs, IIFmove, bitconvert>, MFC1_FM<5>;
-
-def FMOV_S : ABSS_FT<"mov.s", FGR32, FGR32, IIFmove>, ABSS_FM<0x6, 16>;
-def FMOV_D32 : ABSS_FT<"mov.d", AFGR64, AFGR64, IIFmove>, ABSS_FM<0x6, 17>,
- Requires<[NotFP64bit, HasStdEnc]>;
-def FMOV_D64 : ABSS_FT<"mov.d", FGR64, FGR64, IIFmove>, ABSS_FM<0x6, 17>,
- Requires<[IsFP64bit, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
+def CFC1 : MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, IIFmove>, MFC1_FM<2>;
+def CTC1 : MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, IIFmove>, MFC1_FM<6>;
+def MFC1 : MFC1_FT<"mfc1", GPR32Opnd, FGR32RegsOpnd, IIFmoveC1, bitconvert>,
+ MFC1_FM<0>;
+def MTC1 : MTC1_FT<"mtc1", FGR32RegsOpnd, GPR32Opnd, IIFmoveC1, bitconvert>,
+ MFC1_FM<4>;
+def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64RegsOpnd, IIFmoveC1,
+ bitconvert>, MFC1_FM<1>;
+def DMTC1 : MTC1_FT<"dmtc1", FGR64RegsOpnd, GPR64Opnd, IIFmoveC1,
+ bitconvert>, MFC1_FM<5>;
+
+def FMOV_S : ABSS_FT<"mov.s", FGR32RegsOpnd, FGR32RegsOpnd, IIFmove>,
+ ABSS_FM<0x6, 16>;
+def FMOV_D32 : ABSS_FT<"mov.d", AFGR64RegsOpnd, AFGR64RegsOpnd, IIFmove>,
+ ABSS_FM<0x6, 17>, Requires<[NotFP64bit, HasStdEnc]>;
+def FMOV_D64 : ABSS_FT<"mov.d", FGR64RegsOpnd, FGR64RegsOpnd, IIFmove>,
+ ABSS_FM<0x6, 17>, Requires<[IsFP64bit, HasStdEnc]> {
+ let DecoderNamespace = "Mips64";
}
/// Floating Point Memory Instructions
let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in {
- def LWC1_P8 : LW_FT<"lwc1", FGR32, IILoad, mem64, load>, LW_FM<0x31>;
- def SWC1_P8 : SW_FT<"swc1", FGR32, IIStore, mem64, store>, LW_FM<0x39>;
- def LDC164_P8 : LW_FT<"ldc1", FGR64, IILoad, mem64, load>, LW_FM<0x35> {
+ def LWC1_P8 : LW_FT<"lwc1", FGR32RegsOpnd, IIFLoad, mem64, load>,
+ LW_FM<0x31>;
+ def SWC1_P8 : SW_FT<"swc1", FGR32RegsOpnd, IIFStore, mem64, store>,
+ LW_FM<0x39>;
+ def LDC164_P8 : LW_FT<"ldc1", FGR64RegsOpnd, IIFLoad, mem64, load>,
+ LW_FM<0x35> {
let isCodeGenOnly =1;
}
- def SDC164_P8 : SW_FT<"sdc1", FGR64, IIStore, mem64, store>, LW_FM<0x3d> {
+ def SDC164_P8 : SW_FT<"sdc1", FGR64RegsOpnd, IIFStore, mem64, store>,
+ LW_FM<0x3d> {
let isCodeGenOnly =1;
}
}
let Predicates = [NotN64, HasStdEnc] in {
- def LWC1 : LW_FT<"lwc1", FGR32, IILoad, mem, load>, LW_FM<0x31>;
- def SWC1 : SW_FT<"swc1", FGR32, IIStore, mem, store>, LW_FM<0x39>;
+ def LWC1 : LW_FT<"lwc1", FGR32RegsOpnd, IIFLoad, mem, load>, LW_FM<0x31>;
+ def SWC1 : SW_FT<"swc1", FGR32RegsOpnd, IIFStore, mem, store>, LW_FM<0x39>;
}
let Predicates = [NotN64, HasMips64, HasStdEnc],
DecoderNamespace = "Mips64" in {
- def LDC164 : LW_FT<"ldc1", FGR64, IILoad, mem, load>, LW_FM<0x35>;
- def SDC164 : SW_FT<"sdc1", FGR64, IIStore, mem, store>, LW_FM<0x3d>;
+ def LDC164 : LW_FT<"ldc1", FGR64RegsOpnd, IIFLoad, mem, load>, LW_FM<0x35>;
+ def SDC164 : SW_FT<"sdc1", FGR64RegsOpnd, IIFStore, mem, store>, LW_FM<0x3d>;
}
let Predicates = [NotN64, NotMips64, HasStdEnc] in {
let isPseudo = 1, isCodeGenOnly = 1 in {
- def PseudoLDC1 : LW_FT<"", AFGR64, IILoad, mem, load>;
- def PseudoSDC1 : SW_FT<"", AFGR64, IIStore, mem, store>;
+ def PseudoLDC1 : LW_FT<"", AFGR64RegsOpnd, IIFLoad, mem, load>;
+ def PseudoSDC1 : SW_FT<"", AFGR64RegsOpnd, IIFStore, mem, store>;
}
- def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem>, LW_FM<0x35>;
- def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem>, LW_FM<0x3d>;
+ def LDC1 : LW_FT<"ldc1", AFGR64RegsOpnd, IIFLoad, mem>, LW_FM<0x35>;
+ def SDC1 : SW_FT<"sdc1", AFGR64RegsOpnd, IIFStore, mem>, LW_FM<0x3d>;
}
// Indexed loads and stores.
let Predicates = [HasFPIdx, HasStdEnc] in {
- def LWXC1 : LWXC1_FT<"lwxc1", FGR32, CPURegs, IILoad, load>, LWXC1_FM<0>;
- def SWXC1 : SWXC1_FT<"swxc1", FGR32, CPURegs, IIStore, store>, SWXC1_FM<8>;
+ def LWXC1 : LWXC1_FT<"lwxc1", FGR32RegsOpnd, GPR32Opnd, IIFLoad, load>,
+ LWXC1_FM<0>;
+ def SWXC1 : SWXC1_FT<"swxc1", FGR32RegsOpnd, GPR32Opnd, IIFStore, store>,
+ SWXC1_FM<8>;
}
let Predicates = [HasMips32r2, NotMips64, HasStdEnc] in {
- def LDXC1 : LWXC1_FT<"ldxc1", AFGR64, CPURegs, IILoad, load>, LWXC1_FM<1>;
- def SDXC1 : SWXC1_FT<"sdxc1", AFGR64, CPURegs, IIStore, store>, SWXC1_FM<9>;
+ def LDXC1 : LWXC1_FT<"ldxc1", AFGR64RegsOpnd, GPR32Opnd, IIFLoad, load>,
+ LWXC1_FM<1>;
+ def SDXC1 : SWXC1_FT<"sdxc1", AFGR64RegsOpnd, GPR32Opnd, IIFStore, store>,
+ SWXC1_FM<9>;
}
let Predicates = [HasMips64, NotN64, HasStdEnc], DecoderNamespace="Mips64" in {
- def LDXC164 : LWXC1_FT<"ldxc1", FGR64, CPURegs, IILoad, load>, LWXC1_FM<1>;
- def SDXC164 : SWXC1_FT<"sdxc1", FGR64, CPURegs, IIStore, store>, SWXC1_FM<9>;
+ def LDXC164 : LWXC1_FT<"ldxc1", FGR64RegsOpnd, GPR32Opnd, IIFLoad, load>,
+ LWXC1_FM<1>;
+ def SDXC164 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, GPR32Opnd, IIFStore, store>,
+ SWXC1_FM<9>;
}
// n64
let Predicates = [IsN64, HasStdEnc], isCodeGenOnly=1 in {
- def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32, CPU64Regs, IILoad, load>, LWXC1_FM<0>;
- def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64, CPU64Regs, IILoad, load>,
- LWXC1_FM<1>;
- def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32, CPU64Regs, IIStore, store>,
- SWXC1_FM<8>;
- def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64, CPU64Regs, IIStore, store>,
- SWXC1_FM<9>;
+ def LWXC1_P8 : LWXC1_FT<"lwxc1", FGR32RegsOpnd, GPR64Opnd, IIFLoad, load>,
+ LWXC1_FM<0>;
+ def LDXC164_P8 : LWXC1_FT<"ldxc1", FGR64RegsOpnd, GPR64Opnd, IIFLoad,
+ load>, LWXC1_FM<1>;
+ def SWXC1_P8 : SWXC1_FT<"swxc1", FGR32RegsOpnd, GPR64Opnd, IIFStore,
+ store>, SWXC1_FM<8>;
+ def SDXC164_P8 : SWXC1_FT<"sdxc1", FGR64RegsOpnd, GPR64Opnd, IIFStore,
+ store>, SWXC1_FM<9>;
}
// Load/store doubleword indexed unaligned.
let Predicates = [NotMips64, HasStdEnc] in {
- def LUXC1 : LWXC1_FT<"luxc1", AFGR64, CPURegs, IILoad>, LWXC1_FM<0x5>;
- def SUXC1 : SWXC1_FT<"suxc1", AFGR64, CPURegs, IIStore>, SWXC1_FM<0xd>;
+ def LUXC1 : LWXC1_FT<"luxc1", AFGR64RegsOpnd, GPR32Opnd, IIFLoad>,
+ LWXC1_FM<0x5>;
+ def SUXC1 : SWXC1_FT<"suxc1", AFGR64RegsOpnd, GPR32Opnd, IIFStore>,
+ SWXC1_FM<0xd>;
}
let Predicates = [HasMips64, HasStdEnc],
DecoderNamespace="Mips64" in {
- def LUXC164 : LWXC1_FT<"luxc1", FGR64, CPURegs, IILoad>, LWXC1_FM<0x5>;
- def SUXC164 : SWXC1_FT<"suxc1", FGR64, CPURegs, IIStore>, SWXC1_FM<0xd>;
+ def LUXC164 : LWXC1_FT<"luxc1", FGR64RegsOpnd, GPR32Opnd, IIFLoad>,
+ LWXC1_FM<0x5>;
+ def SUXC164 : SWXC1_FT<"suxc1", FGR64RegsOpnd, GPR32Opnd, IIFStore>,
+ SWXC1_FM<0xd>;
}
/// Floating-point Aritmetic
-def FADD_S : ADDS_FT<"add.s", FGR32, IIFadd, 1, fadd>, ADDS_FM<0x00, 16>;
-defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>;
-def FDIV_S : ADDS_FT<"div.s", FGR32, IIFdivSingle, 0, fdiv>, ADDS_FM<0x03, 16>;
-defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>;
-def FMUL_S : ADDS_FT<"mul.s", FGR32, IIFmulSingle, 1, fmul>, ADDS_FM<0x02, 16>;
-defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>;
-def FSUB_S : ADDS_FT<"sub.s", FGR32, IIFadd, 0, fsub>, ADDS_FM<0x01, 16>;
-defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>;
+def FADD_S : ADDS_FT<"add.s", FGR32RegsOpnd, IIFadd, 1, fadd>,
+ ADDS_FM<0x00, 16>;
+defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>;
+def FDIV_S : ADDS_FT<"div.s", FGR32RegsOpnd, IIFdivSingle, 0, fdiv>,
+ ADDS_FM<0x03, 16>;
+defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>;
+def FMUL_S : ADDS_FT<"mul.s", FGR32RegsOpnd, IIFmulSingle, 1, fmul>,
+ ADDS_FM<0x02, 16>;
+defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>;
+def FSUB_S : ADDS_FT<"sub.s", FGR32RegsOpnd, IIFadd, 0, fsub>,
+ ADDS_FM<0x01, 16>;
+defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>;
let Predicates = [HasMips32r2, HasStdEnc] in {
- def MADD_S : MADDS_FT<"madd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<4, 0>;
- def MSUB_S : MADDS_FT<"msub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<5, 0>;
+ def MADD_S : MADDS_FT<"madd.s", FGR32RegsOpnd, IIFmulSingle, fadd>,
+ MADDS_FM<4, 0>;
+ def MSUB_S : MADDS_FT<"msub.s", FGR32RegsOpnd, IIFmulSingle, fsub>,
+ MADDS_FM<5, 0>;
}
let Predicates = [HasMips32r2, NoNaNsFPMath, HasStdEnc] in {
- def NMADD_S : NMADDS_FT<"nmadd.s", FGR32, IIFmulSingle, fadd>, MADDS_FM<6, 0>;
- def NMSUB_S : NMADDS_FT<"nmsub.s", FGR32, IIFmulSingle, fsub>, MADDS_FM<7, 0>;
+ def NMADD_S : NMADDS_FT<"nmadd.s", FGR32RegsOpnd, IIFmulSingle, fadd>,
+ MADDS_FM<6, 0>;
+ def NMSUB_S : NMADDS_FT<"nmsub.s", FGR32RegsOpnd, IIFmulSingle, fsub>,
+ MADDS_FM<7, 0>;
}
let Predicates = [HasMips32r2, NotFP64bit, HasStdEnc] in {
- def MADD_D32 : MADDS_FT<"madd.d", AFGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>;
- def MSUB_D32 : MADDS_FT<"msub.d", AFGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>;
+ def MADD_D32 : MADDS_FT<"madd.d", AFGR64RegsOpnd, IIFmulDouble, fadd>,
+ MADDS_FM<4, 1>;
+ def MSUB_D32 : MADDS_FT<"msub.d", AFGR64RegsOpnd, IIFmulDouble, fsub>,
+ MADDS_FM<5, 1>;
}
let Predicates = [HasMips32r2, NotFP64bit, NoNaNsFPMath, HasStdEnc] in {
- def NMADD_D32 : NMADDS_FT<"nmadd.d", AFGR64, IIFmulDouble, fadd>,
+ def NMADD_D32 : NMADDS_FT<"nmadd.d", AFGR64RegsOpnd, IIFmulDouble, fadd>,
MADDS_FM<6, 1>;
- def NMSUB_D32 : NMADDS_FT<"nmsub.d", AFGR64, IIFmulDouble, fsub>,
+ def NMSUB_D32 : NMADDS_FT<"nmsub.d", AFGR64RegsOpnd, IIFmulDouble, fsub>,
MADDS_FM<7, 1>;
}
let Predicates = [HasMips32r2, IsFP64bit, HasStdEnc], isCodeGenOnly=1 in {
- def MADD_D64 : MADDS_FT<"madd.d", FGR64, IIFmulDouble, fadd>, MADDS_FM<4, 1>;
- def MSUB_D64 : MADDS_FT<"msub.d", FGR64, IIFmulDouble, fsub>, MADDS_FM<5, 1>;
+ def MADD_D64 : MADDS_FT<"madd.d", FGR64RegsOpnd, IIFmulDouble, fadd>,
+ MADDS_FM<4, 1>;
+ def MSUB_D64 : MADDS_FT<"msub.d", FGR64RegsOpnd, IIFmulDouble, fsub>,
+ MADDS_FM<5, 1>;
}
let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc],
isCodeGenOnly=1 in {
- def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64, IIFmulDouble, fadd>,
+ def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64RegsOpnd, IIFmulDouble, fadd>,
MADDS_FM<6, 1>;
- def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64, IIFmulDouble, fsub>,
+ def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64RegsOpnd, IIFmulDouble, fsub>,
MADDS_FM<7, 1>;
}
@@ -426,10 +503,9 @@ let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc],
def MIPS_BRANCH_F : PatLeaf<(i32 0)>;
def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
-let DecoderMethod = "DecodeBC1" in {
def BC1F : BC1F_FT<"bc1f", IIBranch, MIPS_BRANCH_F>, BC1F_FM<0, 0>;
def BC1T : BC1F_FT<"bc1t", IIBranch, MIPS_BRANCH_T>, BC1F_FM<0, 1>;
-}
+
//===----------------------------------------------------------------------===//
// Floating Point Flag Conditions
//===----------------------------------------------------------------------===//
@@ -463,22 +539,29 @@ def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>,
//===----------------------------------------------------------------------===//
// Floating Point Pseudo-Instructions
//===----------------------------------------------------------------------===//
-def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCROpnd:$src), []>;
// This pseudo instr gets expanded into 2 mtc1 instrs after register
// allocation.
def BuildPairF64 :
- PseudoSE<(outs AFGR64:$dst),
- (ins CPURegs:$lo, CPURegs:$hi),
- [(set AFGR64:$dst, (MipsBuildPairF64 CPURegs:$lo, CPURegs:$hi))]>;
+ PseudoSE<(outs AFGR64RegsOpnd:$dst),
+ (ins GPR32Opnd:$lo, GPR32Opnd:$hi),
+ [(set AFGR64RegsOpnd:$dst,
+ (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
// This pseudo instr gets expanded into 2 mfc1 instrs after register
// allocation.
// if n is 0, lower part of src is extracted.
// if n is 1, higher part of src is extracted.
def ExtractElementF64 :
- PseudoSE<(outs CPURegs:$dst), (ins AFGR64:$src, i32imm:$n),
- [(set CPURegs:$dst, (MipsExtractElementF64 AFGR64:$src, imm:$n))]>;
+ PseudoSE<(outs GPR32Opnd:$dst), (ins AFGR64RegsOpnd:$src, i32imm:$n),
+ [(set GPR32Opnd:$dst,
+ (MipsExtractElementF64 AFGR64RegsOpnd:$src, imm:$n))]>;
+
+//===----------------------------------------------------------------------===//
+// InstAliases.
+//===----------------------------------------------------------------------===//
+def : InstAlias<"bc1t $offset", (BC1T FCC0, brtarget:$offset)>;
+def : InstAlias<"bc1f $offset", (BC1F FCC0, brtarget:$offset)>;
//===----------------------------------------------------------------------===//
// Floating Point Patterns
@@ -486,34 +569,44 @@ def ExtractElementF64 :
def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>;
def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>;
-def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>;
-def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_W_S FGR32:$src)>;
+def : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)),
+ (PseudoCVT_S_W GPR32Opnd:$src)>;
+def : MipsPat<(MipsTruncIntFP FGR32RegsOpnd:$src),
+ (TRUNC_W_S FGR32RegsOpnd:$src)>;
let Predicates = [NotFP64bit, HasStdEnc] in {
- def : MipsPat<(f64 (sint_to_fp CPURegs:$src)),
- (PseudoCVT_D32_W CPURegs:$src)>;
- def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>;
- def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>;
- def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>;
+ def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
+ (PseudoCVT_D32_W GPR32Opnd:$src)>;
+ def : MipsPat<(MipsTruncIntFP AFGR64RegsOpnd:$src),
+ (TRUNC_W_D32 AFGR64RegsOpnd:$src)>;
+ def : MipsPat<(f32 (fround AFGR64RegsOpnd:$src)),
+ (CVT_S_D32 AFGR64RegsOpnd:$src)>;
+ def : MipsPat<(f64 (fextend FGR32RegsOpnd:$src)),
+ (CVT_D32_S FGR32RegsOpnd:$src)>;
}
let Predicates = [IsFP64bit, HasStdEnc] in {
def : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>;
def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>;
- def : MipsPat<(f64 (sint_to_fp CPURegs:$src)),
- (PseudoCVT_D64_W CPURegs:$src)>;
- def : MipsPat<(f32 (sint_to_fp CPU64Regs:$src)),
- (EXTRACT_SUBREG (PseudoCVT_S_L CPU64Regs:$src), sub_32)>;
- def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)),
- (PseudoCVT_D64_L CPU64Regs:$src)>;
-
- def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>;
- def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>;
- def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>;
-
- def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>;
- def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>;
+ def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
+ (PseudoCVT_D64_W GPR32Opnd:$src)>;
+ def : MipsPat<(f32 (sint_to_fp GPR64Opnd:$src)),
+ (EXTRACT_SUBREG (PseudoCVT_S_L GPR64Opnd:$src), sub_32)>;
+ def : MipsPat<(f64 (sint_to_fp GPR64Opnd:$src)),
+ (PseudoCVT_D64_L GPR64Opnd:$src)>;
+
+ def : MipsPat<(MipsTruncIntFP FGR64RegsOpnd:$src),
+ (TRUNC_W_D64 FGR64RegsOpnd:$src)>;
+ def : MipsPat<(MipsTruncIntFP FGR32RegsOpnd:$src),
+ (TRUNC_L_S FGR32RegsOpnd:$src)>;
+ def : MipsPat<(MipsTruncIntFP FGR64RegsOpnd:$src),
+ (TRUNC_L_D64 FGR64RegsOpnd:$src)>;
+
+ def : MipsPat<(f32 (fround FGR64RegsOpnd:$src)),
+ (CVT_S_D64 FGR64RegsOpnd:$src)>;
+ def : MipsPat<(f64 (fextend FGR32RegsOpnd:$src)),
+ (CVT_D64_S FGR32RegsOpnd:$src)>;
}
// Patterns for loads/stores with a reg+imm operand.
diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td
index 14cfcf9..1322784 100644
--- a/lib/Target/Mips/MipsInstrFormats.td
+++ b/lib/Target/Mips/MipsInstrFormats.td
@@ -400,17 +400,6 @@ class JALR_FM {
let Inst{5-0} = 9;
}
-class BAL_FM {
- bits<16> offset;
-
- bits<32> Inst;
-
- let Inst{31-26} = 1;
- let Inst{25-21} = 0;
- let Inst{20-16} = 0x11;
- let Inst{15-0} = offset;
-}
-
class BGEZAL_FM<bits<5> funct> {
bits<5> rs;
bits<16> offset;
@@ -491,6 +480,47 @@ class TEQ_FM<bits<6> funct> {
}
//===----------------------------------------------------------------------===//
+// System calls format <op|code_|funct>
+//===----------------------------------------------------------------------===//
+
+class SYS_FM<bits<6> funct>
+{
+ bits<20> code_;
+ bits<32> Inst;
+ let Inst{31-26} = 0x0;
+ let Inst{25-6} = code_;
+ let Inst{5-0} = funct;
+}
+
+//===----------------------------------------------------------------------===//
+// Break instruction format <op|code_1|funct>
+//===----------------------------------------------------------------------===//
+
+class BRK_FM<bits<6> funct>
+{
+ bits<10> code_1;
+ bits<10> code_2;
+ bits<32> Inst;
+ let Inst{31-26} = 0x0;
+ let Inst{25-16} = code_1;
+ let Inst{15-6} = code_2;
+ let Inst{5-0} = funct;
+}
+
+//===----------------------------------------------------------------------===//
+// Exception return format <Cop0|1|0|funct>
+//===----------------------------------------------------------------------===//
+
+class ER_FM<bits<6> funct>
+{
+ bits<32> Inst;
+ let Inst{31-26} = 0x10;
+ let Inst{25} = 1;
+ let Inst{24-6} = 0;
+ let Inst{5-0} = funct;
+}
+
+//===----------------------------------------------------------------------===//
//
// FLOATING POINT INSTRUCTION FORMATS
//
@@ -623,13 +653,14 @@ class SWXC1_FM<bits<6> funct> {
}
class BC1F_FM<bit nd, bit tf> {
+ bits<3> fcc;
bits<16> offset;
bits<32> Inst;
let Inst{31-26} = 0x11;
let Inst{25-21} = 0x8;
- let Inst{20-18} = 0; // cc
+ let Inst{20-18} = fcc;
let Inst{17} = nd;
let Inst{16} = tf;
let Inst{15-0} = offset;
@@ -651,6 +682,10 @@ class CEQS_FM<bits<5> fmt> {
let Inst{3-0} = cond;
}
+class C_COND_FM<bits<5> fmt, bits<4> c> : CEQS_FM<fmt> {
+ let cond = c;
+}
+
class CMov_I_F_FM<bits<6> funct, bits<5> fmt> {
bits<5> fd;
bits<5> fs;
@@ -669,12 +704,13 @@ class CMov_I_F_FM<bits<6> funct, bits<5> fmt> {
class CMov_F_I_FM<bit tf> {
bits<5> rd;
bits<5> rs;
+ bits<3> fcc;
bits<32> Inst;
let Inst{31-26} = 0;
let Inst{25-21} = rs;
- let Inst{20-18} = 0; // cc
+ let Inst{20-18} = fcc;
let Inst{17} = 0;
let Inst{16} = tf;
let Inst{15-11} = rd;
@@ -685,12 +721,13 @@ class CMov_F_I_FM<bit tf> {
class CMov_F_F_FM<bits<5> fmt, bit tf> {
bits<5> fd;
bits<5> fs;
+ bits<3> fcc;
bits<32> Inst;
let Inst{31-26} = 0x11;
let Inst{25-21} = fmt;
- let Inst{20-18} = 0; // cc
+ let Inst{20-18} = fcc;
let Inst{17} = 0;
let Inst{16} = tf;
let Inst{15-11} = fs;
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 3144dae..eae05a3 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -61,15 +61,6 @@ MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI,
MFI.getObjectSize(FI), Align);
}
-MachineInstr*
-MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
- uint64_t Offset, const MDNode *MDPtr,
- DebugLoc DL) const {
- MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE))
- .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
- return &*MIB;
-}
-
//===----------------------------------------------------------------------===//
// Branch Analysis
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h
index 0f075ec..b6480ef 100644
--- a/lib/Target/Mips/MipsInstrInfo.h
+++ b/lib/Target/Mips/MipsInstrInfo.h
@@ -67,11 +67,6 @@ public:
bool AllowModify,
SmallVectorImpl<MachineInstr*> &BranchInstrs) const;
- virtual MachineInstr* emitFrameIndexDebugValue(MachineFunction &MF,
- int FrameIx, uint64_t Offset,
- const MDNode *MDPtr,
- DebugLoc DL) const;
-
/// Insert nop instruction when hazard condition is found
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index dc3e4be..b9e8895 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -250,6 +250,12 @@ def simm16 : Operand<i32> {
def simm20 : Operand<i32> {
}
+def uimm20 : Operand<i32> {
+}
+
+def uimm10 : Operand<i32> {
+}
+
def simm16_64 : Operand<i64>;
def shamt : Operand<i32>;
@@ -266,7 +272,7 @@ def MipsMemAsmOperand : AsmOperandClass {
// Address operand
def mem : Operand<i32> {
let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops CPURegs, simm16);
+ let MIOperandInfo = (ops GPR32, simm16);
let EncoderMethod = "getMemEncoding";
let ParserMatchClass = MipsMemAsmOperand;
let OperandType = "OPERAND_MEMORY";
@@ -274,7 +280,7 @@ def mem : Operand<i32> {
def mem64 : Operand<i64> {
let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops CPU64Regs, simm16_64);
+ let MIOperandInfo = (ops GPR64, simm16_64);
let EncoderMethod = "getMemEncoding";
let ParserMatchClass = MipsMemAsmOperand;
let OperandType = "OPERAND_MEMORY";
@@ -282,14 +288,14 @@ def mem64 : Operand<i64> {
def mem_ea : Operand<i32> {
let PrintMethod = "printMemOperandEA";
- let MIOperandInfo = (ops CPURegs, simm16);
+ let MIOperandInfo = (ops GPR32, simm16);
let EncoderMethod = "getMemEncoding";
let OperandType = "OPERAND_MEMORY";
}
def mem_ea_64 : Operand<i64> {
let PrintMethod = "printMemOperandEA";
- let MIOperandInfo = (ops CPU64Regs, simm16_64);
+ let MIOperandInfo = (ops GPR64, simm16_64);
let EncoderMethod = "getMemEncoding";
let OperandType = "OPERAND_MEMORY";
}
@@ -384,51 +390,52 @@ class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
// Arithmetic and logical instructions with 2 register operands.
class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
+ InstrItinClass Itin = NoItinerary,
SDPatternOperator imm_type = null_frag,
SDPatternOperator OpNode = null_frag> :
InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
!strconcat(opstr, "\t$rt, $rs, $imm16"),
[(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
- IIAlu, FrmI, opstr> {
+ Itin, FrmI, opstr> {
let isReMaterializable = 1;
let TwoOperandAliasConstraint = "$rs = $rt";
}
// Arithmetic Multiply ADD/SUB
class MArithR<string opstr, bit isComm = 0> :
- InstSE<(outs), (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt),
- !strconcat(opstr, "\t$rs, $rt"), [], IIImul, FrmR> {
+ InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
+ !strconcat(opstr, "\t$rs, $rt"), [], IIImult, FrmR> {
let Defs = [HI, LO];
let Uses = [HI, LO];
let isCommutable = isComm;
}
// Logical
-class LogicNOR<string opstr, RegisterOperand RC>:
- InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt),
+class LogicNOR<string opstr, RegisterOperand RO>:
+ InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
!strconcat(opstr, "\t$rd, $rs, $rt"),
- [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR, opstr> {
+ [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], IIArith, FrmR, opstr> {
let isCommutable = 1;
}
// Shifts
class shift_rotate_imm<string opstr, Operand ImmOpnd,
- RegisterOperand RC, SDPatternOperator OpNode = null_frag,
+ RegisterOperand RO, SDPatternOperator OpNode = null_frag,
SDPatternOperator PF = null_frag> :
- InstSE<(outs RC:$rd), (ins RC:$rt, ImmOpnd:$shamt),
+ InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
!strconcat(opstr, "\t$rd, $rt, $shamt"),
- [(set RC:$rd, (OpNode RC:$rt, PF:$shamt))], IIAlu, FrmR, opstr>;
+ [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], IIArith, FrmR, opstr>;
-class shift_rotate_reg<string opstr, RegisterOperand RC,
+class shift_rotate_reg<string opstr, RegisterOperand RO,
SDPatternOperator OpNode = null_frag>:
- InstSE<(outs RC:$rd), (ins CPURegsOpnd:$rs, RC:$rt),
+ InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
!strconcat(opstr, "\t$rd, $rt, $rs"),
- [(set RC:$rd, (OpNode RC:$rt, CPURegsOpnd:$rs))], IIAlu, FrmR, opstr>;
+ [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], IIArith, FrmR, opstr>;
// Load Upper Imediate
-class LoadUpper<string opstr, RegisterClass RC, Operand Imm>:
- InstSE<(outs RC:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
- [], IIAlu, FrmI>, IsAsCheapAsAMove {
+class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
+ InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
+ [], IIArith, FrmI>, IsAsCheapAsAMove {
let neverHasSideEffects = 1;
let isReMaterializable = 1;
}
@@ -442,43 +449,47 @@ class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
}
// Memory Load/Store
-class Load<string opstr, SDPatternOperator OpNode, RegisterClass RC,
- Operand MemOpnd, ComplexPattern Addr, string ofsuffix> :
- InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
- [(set RC:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI,
+class Load<string opstr, SDPatternOperator OpNode, DAGOperand RO,
+ InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr,
+ string ofsuffix> :
+ InstSE<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
+ [(set RO:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI,
!strconcat(opstr, ofsuffix)> {
let DecoderMethod = "DecodeMem";
let canFoldAsLoad = 1;
let mayLoad = 1;
}
-class Store<string opstr, SDPatternOperator OpNode, RegisterClass RC,
- Operand MemOpnd, ComplexPattern Addr, string ofsuffix> :
- InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
- [(OpNode RC:$rt, Addr:$addr)], NoItinerary, FrmI,
+class Store<string opstr, SDPatternOperator OpNode, DAGOperand RO,
+ InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr,
+ string ofsuffix> :
+ InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
+ [(OpNode RO:$rt, Addr:$addr)], NoItinerary, FrmI,
!strconcat(opstr, ofsuffix)> {
let DecoderMethod = "DecodeMem";
let mayStore = 1;
}
-multiclass LoadM<string opstr, RegisterClass RC,
+multiclass LoadM<string opstr, DAGOperand RO,
SDPatternOperator OpNode = null_frag,
+ InstrItinClass Itin = NoItinerary,
ComplexPattern Addr = addr> {
- def NAME : Load<opstr, OpNode, RC, mem, Addr, "">,
+ def NAME : Load<opstr, OpNode, RO, Itin, mem, Addr, "">,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : Load<opstr, OpNode, RC, mem64, Addr, "_p8">,
+ def _P8 : Load<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">,
Requires<[IsN64, HasStdEnc]> {
let DecoderNamespace = "Mips64";
let isCodeGenOnly = 1;
}
}
-multiclass StoreM<string opstr, RegisterClass RC,
+multiclass StoreM<string opstr, DAGOperand RO,
SDPatternOperator OpNode = null_frag,
+ InstrItinClass Itin = NoItinerary,
ComplexPattern Addr = addr> {
- def NAME : Store<opstr, OpNode, RC, mem, Addr, "">,
+ def NAME : Store<opstr, OpNode, RO, Itin, mem, Addr, "">,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : Store<opstr, OpNode, RC, mem64, Addr, "_p8">,
+ def _P8 : Store<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">,
Requires<[IsN64, HasStdEnc]> {
let DecoderNamespace = "Mips64";
let isCodeGenOnly = 1;
@@ -487,36 +498,36 @@ multiclass StoreM<string opstr, RegisterClass RC,
// Load/Store Left/Right
let canFoldAsLoad = 1 in
-class LoadLeftRight<string opstr, SDNode OpNode, RegisterClass RC,
+class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
Operand MemOpnd> :
- InstSE<(outs RC:$rt), (ins MemOpnd:$addr, RC:$src),
+ InstSE<(outs RO:$rt), (ins MemOpnd:$addr, RO:$src),
!strconcat(opstr, "\t$rt, $addr"),
- [(set RC:$rt, (OpNode addr:$addr, RC:$src))], NoItinerary, FrmI> {
+ [(set RO:$rt, (OpNode addr:$addr, RO:$src))], NoItinerary, FrmI> {
let DecoderMethod = "DecodeMem";
string Constraints = "$src = $rt";
}
-class StoreLeftRight<string opstr, SDNode OpNode, RegisterClass RC,
+class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
Operand MemOpnd>:
- InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
- [(OpNode RC:$rt, addr:$addr)], NoItinerary, FrmI> {
+ InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
+ [(OpNode RO:$rt, addr:$addr)], NoItinerary, FrmI> {
let DecoderMethod = "DecodeMem";
}
-multiclass LoadLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> {
- def NAME : LoadLeftRight<opstr, OpNode, RC, mem>,
+multiclass LoadLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> {
+ def NAME : LoadLeftRight<opstr, OpNode, RO, mem>,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : LoadLeftRight<opstr, OpNode, RC, mem64>,
+ def _P8 : LoadLeftRight<opstr, OpNode, RO, mem64>,
Requires<[IsN64, HasStdEnc]> {
let DecoderNamespace = "Mips64";
let isCodeGenOnly = 1;
}
}
-multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> {
- def NAME : StoreLeftRight<opstr, OpNode, RC, mem>,
+multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> {
+ def NAME : StoreLeftRight<opstr, OpNode, RO, mem>,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : StoreLeftRight<opstr, OpNode, RC, mem64>,
+ def _P8 : StoreLeftRight<opstr, OpNode, RO, mem64>,
Requires<[IsN64, HasStdEnc]> {
let DecoderNamespace = "Mips64";
let isCodeGenOnly = 1;
@@ -524,10 +535,10 @@ multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> {
}
// Conditional Branch
-class CBranch<string opstr, PatFrag cond_op, RegisterOperand RC> :
- InstSE<(outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
+class CBranch<string opstr, PatFrag cond_op, RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset),
!strconcat(opstr, "\t$rs, $rt, $offset"),
- [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch,
+ [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
FrmI> {
let isBranch = 1;
let isTerminator = 1;
@@ -535,10 +546,10 @@ class CBranch<string opstr, PatFrag cond_op, RegisterOperand RC> :
let Defs = [AT];
}
-class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RC> :
- InstSE<(outs), (ins RC:$rs, brtarget:$offset),
+class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, brtarget:$offset),
!strconcat(opstr, "\t$rs, $offset"),
- [(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch, FrmI> {
+ [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
@@ -546,18 +557,18 @@ class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RC> :
}
// SetCC
-class SetCC_R<string opstr, PatFrag cond_op, RegisterClass RC> :
- InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt),
+class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
+ InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
!strconcat(opstr, "\t$rd, $rs, $rt"),
- [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))],
- IIAlu, FrmR, opstr>;
+ [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
+ IIslt, FrmR, opstr>;
class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
- RegisterClass RC>:
- InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16),
+ RegisterOperand RO>:
+ InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
!strconcat(opstr, "\t$rt, $rs, $imm16"),
- [(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))],
- IIAlu, FrmI, opstr>;
+ [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
+ IIslt, FrmI, opstr>;
// Jump
class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
@@ -585,17 +596,17 @@ class UncondBranch<string opstr> :
// Base class for indirect branch and return instruction classes.
let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
-class JumpFR<RegisterClass RC, SDPatternOperator operator = null_frag>:
- InstSE<(outs), (ins RC:$rs), "jr\t$rs", [(operator RC:$rs)], IIBranch, FrmR>;
+class JumpFR<RegisterOperand RO, SDPatternOperator operator = null_frag>:
+ InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, FrmR>;
// Indirect branch
-class IndirectBranch<RegisterClass RC>: JumpFR<RC, brind> {
+class IndirectBranch<RegisterOperand RO>: JumpFR<RO, brind> {
let isBranch = 1;
let isIndirectBranch = 1;
}
// Return instruction
-class RetBase<RegisterClass RC>: JumpFR<RC> {
+class RetBase<RegisterOperand RO>: JumpFR<RO> {
let isReturn = 1;
let isCodeGenOnly = 1;
let hasCtrlDep = 1;
@@ -610,13 +621,13 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in {
let DecoderMethod = "DecodeJumpTarget";
}
- class JumpLinkRegPseudo<RegisterClass RC, Instruction JALRInst,
- Register RetReg>:
- PseudoSE<(outs), (ins RC:$rs), [(MipsJmpLink RC:$rs)], IIBranch>,
- PseudoInstExpansion<(JALRInst RetReg, RC:$rs)>;
+ class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
+ Register RetReg, RegisterOperand ResRO = RO>:
+ PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
+ PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
- class JumpLinkReg<string opstr, RegisterClass RC>:
- InstSE<(outs RC:$rd), (ins RC:$rs), !strconcat(opstr, "\t$rd, $rs"),
+ class JumpLinkReg<string opstr, RegisterOperand RO>:
+ InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
[], IIBranch, FrmR>;
class BGEZAL_FT<string opstr, RegisterOperand RO> :
@@ -625,8 +636,9 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in {
}
-class BAL_FT :
- InstSE<(outs), (ins brtarget:$offset), "bal\t$offset", [], IIBranch, FrmI> {
+class BAL_BR_Pseudo<Instruction RealInst> :
+ PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
+ PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
let isBranch = 1;
let isTerminator = 1;
let isBarrier = 1;
@@ -634,6 +646,20 @@ class BAL_FT :
let Defs = [RA];
}
+// Syscall
+class SYS_FT<string opstr> :
+ InstSE<(outs), (ins uimm20:$code_),
+ !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>;
+// Break
+class BRK_FT<string opstr> :
+ InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
+ !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>;
+
+// (D)Eret
+class ER_FT<string opstr> :
+ InstSE<(outs), (ins),
+ opstr, [], NoItinerary, FrmOther>;
+
// Sync
let hasSideEffects = 1 in
class SYNC_FT :
@@ -673,11 +699,11 @@ class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
// operands.
class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode>
: PseudoSE<(outs ACRegs:$ac),
- (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin),
+ (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACRegs:$acin),
[(set ACRegs:$ac,
- (OpNode CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin))],
- IIImul>,
- PseudoInstExpansion<(RealInst CPURegsOpnd:$rs, CPURegsOpnd:$rt)> {
+ (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACRegs:$acin))],
+ IIImult>,
+ PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
string Constraints = "$acin = $ac";
}
@@ -689,21 +715,21 @@ class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
}
// Move from Hi/Lo
-class MoveFromLOHI<string opstr, RegisterClass RC, list<Register> UseRegs>:
- InstSE<(outs RC:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> {
+class MoveFromLOHI<string opstr, RegisterOperand RO, list<Register> UseRegs>:
+ InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> {
let Uses = UseRegs;
let neverHasSideEffects = 1;
}
-class MoveToLOHI<string opstr, RegisterClass RC, list<Register> DefRegs>:
- InstSE<(outs), (ins RC:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> {
+class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
+ InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> {
let Defs = DefRegs;
let neverHasSideEffects = 1;
}
-class EffectiveAddress<string opstr, RegisterClass RC, Operand Mem> :
- InstSE<(outs RC:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
- [(set RC:$rt, addr:$addr)], NoItinerary, FrmI> {
+class EffectiveAddress<string opstr, RegisterOperand RO, Operand Mem> :
+ InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
+ [(set RO:$rt, addr:$addr)], NoItinerary, FrmI> {
let isCodeGenOnly = 1;
let DecoderMethod = "DecodeMem";
}
@@ -711,19 +737,19 @@ class EffectiveAddress<string opstr, RegisterClass RC, Operand Mem> :
// Count Leading Ones/Zeros in Word
class CountLeading0<string opstr, RegisterOperand RO>:
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
- [(set RO:$rd, (ctlz RO:$rs))], IIAlu, FrmR>,
+ [(set RO:$rd, (ctlz RO:$rs))], IIArith, FrmR>,
Requires<[HasBitCount, HasStdEnc]>;
class CountLeading1<string opstr, RegisterOperand RO>:
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
- [(set RO:$rd, (ctlz (not RO:$rs)))], IIAlu, FrmR>,
+ [(set RO:$rd, (ctlz (not RO:$rs)))], IIArith, FrmR>,
Requires<[HasBitCount, HasStdEnc]>;
// Sign Extend in Register.
-class SignExtInReg<string opstr, ValueType vt, RegisterClass RC> :
- InstSE<(outs RC:$rd), (ins RC:$rt), !strconcat(opstr, "\t$rd, $rt"),
- [(set RC:$rd, (sext_inreg RC:$rt, vt))], NoItinerary, FrmR> {
+class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO> :
+ InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
+ [(set RO:$rd, (sext_inreg RO:$rt, vt))], IIseb, FrmR> {
let Predicates = [HasSEInReg, HasStdEnc];
}
@@ -736,9 +762,9 @@ class SubwordSwap<string opstr, RegisterOperand RO>:
}
// Read Hardware
-class ReadHardware<RegisterClass CPURegClass, RegisterOperand RO> :
- InstSE<(outs CPURegClass:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
- IIAlu, FrmR>;
+class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
+ InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
+ IIArith, FrmR>;
// Ext and Ins
class ExtBase<string opstr, RegisterOperand RO>:
@@ -764,11 +790,8 @@ class Atomic2Ops<PatFrag Op, RegisterClass DRC, RegisterClass PRC> :
[(set DRC:$dst, (Op PRC:$ptr, DRC:$incr))]>;
multiclass Atomic2Ops32<PatFrag Op> {
- def NAME : Atomic2Ops<Op, CPURegs, CPURegs>, Requires<[NotN64, HasStdEnc]>;
- def _P8 : Atomic2Ops<Op, CPURegs, CPU64Regs>,
- Requires<[IsN64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
- }
+ def NAME : Atomic2Ops<Op, GPR32, GPR32>, Requires<[NotN64, HasStdEnc]>;
+ def _P8 : Atomic2Ops<Op, GPR32, GPR64>, Requires<[IsN64, HasStdEnc]>;
}
// Atomic Compare & Swap.
@@ -777,12 +800,10 @@ class AtomicCmpSwap<PatFrag Op, RegisterClass DRC, RegisterClass PRC> :
[(set DRC:$dst, (Op PRC:$ptr, DRC:$cmp, DRC:$swap))]>;
multiclass AtomicCmpSwap32<PatFrag Op> {
- def NAME : AtomicCmpSwap<Op, CPURegs, CPURegs>,
+ def NAME : AtomicCmpSwap<Op, GPR32, GPR32>,
Requires<[NotN64, HasStdEnc]>;
- def _P8 : AtomicCmpSwap<Op, CPURegs, CPU64Regs>,
- Requires<[IsN64, HasStdEnc]> {
- let DecoderNamespace = "Mips64";
- }
+ def _P8 : AtomicCmpSwap<Op, GPR32, GPR64>,
+ Requires<[IsN64, HasStdEnc]>;
}
class LLBase<string opstr, RegisterOperand RO, Operand Mem> :
@@ -803,6 +824,11 @@ class SCBase<string opstr, RegisterOperand RO, Operand Mem> :
class MFC3OP<dag outs, dag ins, string asmstr> :
InstSE<outs, ins, asmstr, [], NoItinerary, FrmFR>;
+let isBarrier = 1, isTerminator = 1, isCodeGenOnly = 1 in
+def TRAP : InstSE<(outs), (ins), "break", [(trap)], NoItinerary, FrmOther> {
+ let Inst = 0x0000000d;
+}
+
//===----------------------------------------------------------------------===//
// Pseudo instructions
//===----------------------------------------------------------------------===//
@@ -848,9 +874,9 @@ let usesCustomInserter = 1 in {
}
/// Pseudo instructions for loading and storing accumulator registers.
-let isPseudo = 1 in {
- defm LOAD_AC64 : LoadM<"load_ac64", ACRegs>;
- defm STORE_AC64 : StoreM<"store_ac64", ACRegs>;
+let isPseudo = 1, isCodeGenOnly = 1 in {
+ defm LOAD_AC64 : LoadM<"", ACRegs>;
+ defm STORE_AC64 : StoreM<"", ACRegs>;
}
//===----------------------------------------------------------------------===//
@@ -861,114 +887,125 @@ let isPseudo = 1 in {
//===----------------------------------------------------------------------===//
/// Arithmetic Instructions (ALU Immediate)
-def ADDiu : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>,
+def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, IIArith, immSExt16,
+ add>,
ADDI_FM<0x9>, IsAsCheapAsAMove;
-def ADDi : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>;
-def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>,
+def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>;
+def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
SLTI_FM<0xa>;
-def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>,
+def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
SLTI_FM<0xb>;
-def ANDi : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>,
+def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, IILogic, immZExt16,
+ and>,
ADDI_FM<0xc>;
-def ORi : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>,
+def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, IILogic, immZExt16,
+ or>,
ADDI_FM<0xd>;
-def XORi : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>,
+def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, IILogic, immZExt16,
+ xor>,
ADDI_FM<0xe>;
-def LUi : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM;
+def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
/// Arithmetic Instructions (3-Operand, R-Type)
-def ADDu : MMRel, ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>,
+def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, IIArith, add>,
ADD_FM<0, 0x21>;
-def SUBu : MMRel, ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>,
+def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, IIArith, sub>,
ADD_FM<0, 0x23>;
-def MUL : MMRel, ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>,
+def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, IIImul, mul>,
ADD_FM<0x1c, 2>;
-def ADD : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>;
-def SUB : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>;
-def SLT : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>;
-def SLTu : MMRel, SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>;
-def AND : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>,
+def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
+def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
+def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
+def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
+def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IILogic, and>,
ADD_FM<0, 0x24>;
-def OR : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>,
+def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IILogic, or>,
ADD_FM<0, 0x25>;
-def XOR : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>,
+def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IILogic, xor>,
ADD_FM<0, 0x26>;
-def NOR : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>;
+def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
/// Shift Instructions
-def SLL : MMRel, shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>,
+def SLL : MMRel, shift_rotate_imm<"sll", shamt, GPR32Opnd, shl, immZExt5>,
SRA_FM<0, 0>;
-def SRL : MMRel, shift_rotate_imm<"srl", shamt, CPURegsOpnd, srl, immZExt5>,
+def SRL : MMRel, shift_rotate_imm<"srl", shamt, GPR32Opnd, srl, immZExt5>,
SRA_FM<2, 0>;
-def SRA : MMRel, shift_rotate_imm<"sra", shamt, CPURegsOpnd, sra, immZExt5>,
+def SRA : MMRel, shift_rotate_imm<"sra", shamt, GPR32Opnd, sra, immZExt5>,
SRA_FM<3, 0>;
-def SLLV : MMRel, shift_rotate_reg<"sllv", CPURegsOpnd, shl>, SRLV_FM<4, 0>;
-def SRLV : MMRel, shift_rotate_reg<"srlv", CPURegsOpnd, srl>, SRLV_FM<6, 0>;
-def SRAV : MMRel, shift_rotate_reg<"srav", CPURegsOpnd, sra>, SRLV_FM<7, 0>;
+def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, shl>, SRLV_FM<4, 0>;
+def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, srl>, SRLV_FM<6, 0>;
+def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, sra>, SRLV_FM<7, 0>;
// Rotate Instructions
let Predicates = [HasMips32r2, HasStdEnc] in {
- def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, CPURegsOpnd, rotr,
+ def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, GPR32Opnd, rotr,
immZExt5>,
SRA_FM<2, 1>;
- def ROTRV : MMRel, shift_rotate_reg<"rotrv", CPURegsOpnd, rotr>,
+ def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, rotr>,
SRLV_FM<6, 1>;
}
/// Load and Store Instructions
/// aligned
-defm LB : LoadM<"lb", CPURegs, sextloadi8>, MMRel, LW_FM<0x20>;
-defm LBu : LoadM<"lbu", CPURegs, zextloadi8, addrDefault>, MMRel, LW_FM<0x24>;
-defm LH : LoadM<"lh", CPURegs, sextloadi16, addrDefault>, MMRel, LW_FM<0x21>;
-defm LHu : LoadM<"lhu", CPURegs, zextloadi16>, MMRel, LW_FM<0x25>;
-defm LW : LoadM<"lw", CPURegs, load, addrDefault>, MMRel, LW_FM<0x23>;
-defm SB : StoreM<"sb", CPURegs, truncstorei8>, MMRel, LW_FM<0x28>;
-defm SH : StoreM<"sh", CPURegs, truncstorei16>, MMRel, LW_FM<0x29>;
-defm SW : StoreM<"sw", CPURegs, store>, MMRel, LW_FM<0x2b>;
+defm LB : LoadM<"lb", GPR32Opnd, sextloadi8, IILoad>, MMRel, LW_FM<0x20>;
+defm LBu : LoadM<"lbu", GPR32Opnd, zextloadi8, IILoad, addrDefault>, MMRel,
+ LW_FM<0x24>;
+defm LH : LoadM<"lh", GPR32Opnd, sextloadi16, IILoad, addrDefault>, MMRel,
+ LW_FM<0x21>;
+defm LHu : LoadM<"lhu", GPR32Opnd, zextloadi16, IILoad>, MMRel, LW_FM<0x25>;
+defm LW : LoadM<"lw", GPR32Opnd, load, IILoad, addrDefault>, MMRel, LW_FM<0x23>;
+defm SB : StoreM<"sb", GPR32Opnd, truncstorei8, IIStore>, MMRel, LW_FM<0x28>;
+defm SH : StoreM<"sh", GPR32Opnd, truncstorei16, IIStore>, MMRel, LW_FM<0x29>;
+defm SW : StoreM<"sw", GPR32Opnd, store, IIStore>, MMRel, LW_FM<0x2b>;
/// load/store left/right
-defm LWL : LoadLeftRightM<"lwl", MipsLWL, CPURegs>, LW_FM<0x22>;
-defm LWR : LoadLeftRightM<"lwr", MipsLWR, CPURegs>, LW_FM<0x26>;
-defm SWL : StoreLeftRightM<"swl", MipsSWL, CPURegs>, LW_FM<0x2a>;
-defm SWR : StoreLeftRightM<"swr", MipsSWR, CPURegs>, LW_FM<0x2e>;
+defm LWL : LoadLeftRightM<"lwl", MipsLWL, GPR32Opnd>, LW_FM<0x22>;
+defm LWR : LoadLeftRightM<"lwr", MipsLWR, GPR32Opnd>, LW_FM<0x26>;
+defm SWL : StoreLeftRightM<"swl", MipsSWL, GPR32Opnd>, LW_FM<0x2a>;
+defm SWR : StoreLeftRightM<"swr", MipsSWR, GPR32Opnd>, LW_FM<0x2e>;
def SYNC : SYNC_FT, SYNC_FM;
-def TEQ : TEQ_FT<"teq", CPURegsOpnd>, TEQ_FM<0x34>;
+def TEQ : TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
+
+def BREAK : BRK_FT<"break">, BRK_FM<0xd>;
+def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>;
+
+def ERET : ER_FT<"eret">, ER_FM<0x18>;
+def DERET : ER_FT<"deret">, ER_FM<0x1f>;
/// Load-linked, Store-conditional
let Predicates = [NotN64, HasStdEnc] in {
- def LL : LLBase<"ll", CPURegsOpnd, mem>, LW_FM<0x30>;
- def SC : SCBase<"sc", CPURegsOpnd, mem>, LW_FM<0x38>;
+ def LL : LLBase<"ll", GPR32Opnd, mem>, LW_FM<0x30>;
+ def SC : SCBase<"sc", GPR32Opnd, mem>, LW_FM<0x38>;
}
let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in {
- def LL_P8 : LLBase<"ll", CPURegsOpnd, mem64>, LW_FM<0x30>;
- def SC_P8 : SCBase<"sc", CPURegsOpnd, mem64>, LW_FM<0x38>;
+ def LL_P8 : LLBase<"ll", GPR32Opnd, mem64>, LW_FM<0x30>;
+ def SC_P8 : SCBase<"sc", GPR32Opnd, mem64>, LW_FM<0x38>;
}
/// Jump and Branch Instructions
def J : JumpFJ<jmptarget, "j", br, bb>, FJ<2>,
Requires<[RelocStatic, HasStdEnc]>, IsBranch;
-def JR : IndirectBranch<CPURegs>, MTLO_FM<8>;
+def JR : IndirectBranch<GPR32Opnd>, MTLO_FM<8>;
def B : UncondBranch<"b">, B_FM;
-def BEQ : CBranch<"beq", seteq, CPURegsOpnd>, BEQ_FM<4>;
-def BNE : CBranch<"bne", setne, CPURegsOpnd>, BEQ_FM<5>;
-def BGEZ : CBranchZero<"bgez", setge, CPURegsOpnd>, BGEZ_FM<1, 1>;
-def BGTZ : CBranchZero<"bgtz", setgt, CPURegsOpnd>, BGEZ_FM<7, 0>;
-def BLEZ : CBranchZero<"blez", setle, CPURegsOpnd>, BGEZ_FM<6, 0>;
-def BLTZ : CBranchZero<"bltz", setlt, CPURegsOpnd>, BGEZ_FM<1, 0>;
-
-def BAL_BR: BAL_FT, BAL_FM;
+def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>;
+def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>;
+def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>;
+def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>;
+def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>;
+def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>;
def JAL : JumpLink<"jal">, FJ<3>;
-def JALR : JumpLinkReg<"jalr", CPURegs>, JALR_FM;
-def JALRPseudo : JumpLinkRegPseudo<CPURegs, JALR, RA>;
-def BGEZAL : BGEZAL_FT<"bgezal", CPURegsOpnd>, BGEZAL_FM<0x11>;
-def BLTZAL : BGEZAL_FT<"bltzal", CPURegsOpnd>, BGEZAL_FM<0x10>;
+def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
+def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
+def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>;
+def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>;
+def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
def TAILCALL : JumpFJ<calltarget, "j", MipsTailCall, imm>, FJ<2>, IsTailCall;
-def TAILCALL_R : JumpFR<CPURegs, MipsTailCall>, MTLO_FM<8>, IsTailCall;
+def TAILCALL_R : JumpFR<GPR32Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall;
-def RET : RetBase<CPURegs>, MTLO_FM<8>;
+def RET : RetBase<GPR32Opnd>, MTLO_FM<8>;
// Exception handling related node and instructions.
// The conversion sequence is:
@@ -984,42 +1021,42 @@ def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
- def MIPSeh_return32 : MipsPseudo<(outs), (ins CPURegs:$spoff, CPURegs:$dst),
- [(MIPSehret CPURegs:$spoff, CPURegs:$dst)]>;
- def MIPSeh_return64 : MipsPseudo<(outs), (ins CPU64Regs:$spoff,
- CPU64Regs:$dst),
- [(MIPSehret CPU64Regs:$spoff, CPU64Regs:$dst)]>;
+ def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
+ [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
+ def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
+ GPR64:$dst),
+ [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
}
/// Multiply and Divide Instructions.
-def MULT : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>,
+def MULT : MMRel, Mult<"mult", IIImult, GPR32Opnd, [HI, LO]>,
MULT_FM<0, 0x18>;
-def MULTu : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>,
+def MULTu : MMRel, Mult<"multu", IIImult, GPR32Opnd, [HI, LO]>,
MULT_FM<0, 0x19>;
-def PseudoMULT : MultDivPseudo<MULT, ACRegs, CPURegsOpnd, MipsMult, IIImul>;
-def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, CPURegsOpnd, MipsMultu, IIImul>;
-def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>;
-def UDIV : Div<"divu", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1b>;
-def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, CPURegsOpnd, MipsDivRem, IIIdiv,
+def PseudoMULT : MultDivPseudo<MULT, ACRegs, GPR32Opnd, MipsMult, IIImult>;
+def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, GPR32Opnd, MipsMultu, IIImult>;
+def SDIV : Div<"div", IIIdiv, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x1a>;
+def UDIV : Div<"divu", IIIdiv, GPR32Opnd, [HI, LO]>, MULT_FM<0, 0x1b>;
+def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, GPR32Opnd, MipsDivRem, IIIdiv,
0, 1, 1>;
-def PseudoUDIV : MultDivPseudo<UDIV, ACRegs, CPURegsOpnd, MipsDivRemU, IIIdiv,
+def PseudoUDIV : MultDivPseudo<UDIV, ACRegs, GPR32Opnd, MipsDivRemU, IIIdiv,
0, 1, 1>;
-def MTHI : MoveToLOHI<"mthi", CPURegs, [HI]>, MTLO_FM<0x11>;
-def MTLO : MoveToLOHI<"mtlo", CPURegs, [LO]>, MTLO_FM<0x13>;
-def MFHI : MoveFromLOHI<"mfhi", CPURegs, [HI]>, MFLO_FM<0x10>;
-def MFLO : MoveFromLOHI<"mflo", CPURegs, [LO]>, MFLO_FM<0x12>;
+def MTHI : MoveToLOHI<"mthi", GPR32Opnd, [HI]>, MTLO_FM<0x11>;
+def MTLO : MoveToLOHI<"mtlo", GPR32Opnd, [LO]>, MTLO_FM<0x13>;
+def MFHI : MoveFromLOHI<"mfhi", GPR32Opnd, [HI]>, MFLO_FM<0x10>;
+def MFLO : MoveFromLOHI<"mflo", GPR32Opnd, [LO]>, MFLO_FM<0x12>;
/// Sign Ext In Register Instructions.
-def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10, 0x20>;
-def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18, 0x20>;
+def SEB : SignExtInReg<"seb", i8, GPR32Opnd>, SEB_FM<0x10, 0x20>;
+def SEH : SignExtInReg<"seh", i16, GPR32Opnd>, SEB_FM<0x18, 0x20>;
/// Count Leading
-def CLZ : CountLeading0<"clz", CPURegsOpnd>, CLO_FM<0x20>;
-def CLO : CountLeading1<"clo", CPURegsOpnd>, CLO_FM<0x21>;
+def CLZ : CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>;
+def CLO : CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>;
/// Word Swap Bytes Within Halfwords
-def WSBH : SubwordSwap<"wsbh", CPURegsOpnd>, SEB_FM<2, 0x20>;
+def WSBH : SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>;
/// No operation.
def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
@@ -1028,7 +1065,7 @@ def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
// instructions. The same not happens for stack address copies, so an
// add op with mem ComplexPattern is used and the stack address copy
// can be matched. It's similar to Sparc LEA_ADDRi
-def LEA_ADDiu : EffectiveAddress<"addiu", CPURegs, mem_ea>, LW_FM<9>;
+def LEA_ADDiu : EffectiveAddress<"addiu", GPR32Opnd, mem_ea>, LW_FM<9>;
// MADD*/MSUB*
def MADD : MArithR<"madd", 1>, MULT_FM<0x1c, 0>;
@@ -1040,79 +1077,74 @@ def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu>;
def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub>;
def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu>;
-def RDHWR : ReadHardware<CPURegs, HWRegsOpnd>, RDHWR_FM;
+def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
-def EXT : ExtBase<"ext", CPURegsOpnd>, EXT_FM<0>;
-def INS : InsBase<"ins", CPURegsOpnd>, EXT_FM<4>;
+def EXT : ExtBase<"ext", GPR32Opnd>, EXT_FM<0>;
+def INS : InsBase<"ins", GPR32Opnd>, EXT_FM<4>;
/// Move Control Registers From/To CPU Registers
-def MFC0_3OP : MFC3OP<(outs CPURegsOpnd:$rt),
- (ins CPURegsOpnd:$rd, uimm16:$sel),
+def MFC0_3OP : MFC3OP<(outs GPR32Opnd:$rt),
+ (ins GPR32Opnd:$rd, uimm16:$sel),
"mfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 0>;
-def MTC0_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel),
- (ins CPURegsOpnd:$rt),
+def MTC0_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel),
+ (ins GPR32Opnd:$rt),
"mtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 4>;
-def MFC2_3OP : MFC3OP<(outs CPURegsOpnd:$rt),
- (ins CPURegsOpnd:$rd, uimm16:$sel),
+def MFC2_3OP : MFC3OP<(outs GPR32Opnd:$rt),
+ (ins GPR32Opnd:$rd, uimm16:$sel),
"mfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 0>;
-def MTC2_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel),
- (ins CPURegsOpnd:$rt),
+def MTC2_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel),
+ (ins GPR32Opnd:$rt),
"mtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 4>;
//===----------------------------------------------------------------------===//
// Instruction aliases
//===----------------------------------------------------------------------===//
def : InstAlias<"move $dst, $src",
- (ADDu CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>,
- Requires<[NotMips64]>;
-def : InstAlias<"move $dst, $src",
- (OR CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>,
+ (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
Requires<[NotMips64]>;
-def : InstAlias<"bal $offset", (BGEZAL RA, brtarget:$offset), 1>;
+def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
def : InstAlias<"addu $rs, $rt, $imm",
- (ADDiu CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>;
+ (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
def : InstAlias<"add $rs, $rt, $imm",
- (ADDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>;
+ (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
def : InstAlias<"and $rs, $rt, $imm",
- (ANDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>;
-def : InstAlias<"j $rs", (JR CPURegs:$rs), 0>,
- Requires<[NotMips64]>;
-def : InstAlias<"jalr $rs", (JALR RA, CPURegs:$rs)>, Requires<[NotMips64]>;
-def : InstAlias<"jal $rs", (JALR RA, CPURegs:$rs), 0>, Requires<[NotMips64]>;
-def : InstAlias<"jal $rd,$rs", (JALR CPURegs:$rd, CPURegs:$rs), 0>,
- Requires<[NotMips64]>;
+ (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
+def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
+def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
+def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
+def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
def : InstAlias<"not $rt, $rs",
- (NOR CPURegsOpnd:$rt, CPURegsOpnd:$rs, ZERO), 1>;
+ (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
def : InstAlias<"neg $rt, $rs",
- (SUB CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>;
+ (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
def : InstAlias<"negu $rt, $rs",
- (SUBu CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>;
+ (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
def : InstAlias<"slt $rs, $rt, $imm",
- (SLTi CPURegsOpnd:$rs, CPURegs:$rt, simm16:$imm), 0>;
+ (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
def : InstAlias<"xor $rs, $rt, $imm",
- (XORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>,
- Requires<[NotMips64]>;
+ (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
def : InstAlias<"or $rs, $rt, $imm",
- (ORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>,
- Requires<[NotMips64]>;
+ (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
def : InstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
def : InstAlias<"mfc0 $rt, $rd",
- (MFC0_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>;
+ (MFC0_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
def : InstAlias<"mtc0 $rt, $rd",
- (MTC0_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>;
+ (MTC0_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>;
def : InstAlias<"mfc2 $rt, $rd",
- (MFC2_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>;
+ (MFC2_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
def : InstAlias<"mtc2 $rt, $rd",
- (MTC2_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>;
+ (MTC2_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>;
def : InstAlias<"bnez $rs,$offset",
- (BNE CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>,
- Requires<[NotMips64]>;
+ (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
def : InstAlias<"beqz $rs,$offset",
- (BEQ CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>,
- Requires<[NotMips64]>;
+ (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
+def : InstAlias<"syscall", (SYSCALL 0), 1>;
+
+def : InstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
+def : InstAlias<"break", (BREAK 0, 0), 1>;
//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions
//===----------------------------------------------------------------------===//
@@ -1120,17 +1152,17 @@ def : InstAlias<"beqz $rs,$offset",
class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> :
MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
!strconcat(instr_asm, "\t$rt, $imm32")> ;
-def LoadImm32Reg : LoadImm32<"li", shamt,CPURegsOpnd>;
+def LoadImm32Reg : LoadImm32<"li", shamt,GPR32Opnd>;
class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> :
MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
!strconcat(instr_asm, "\t$rt, $addr")> ;
-def LoadAddr32Reg : LoadAddress<"la", mem, CPURegsOpnd>;
+def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>;
class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> :
MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
!strconcat(instr_asm, "\t$rt, $imm32")> ;
-def LoadAddr32Imm : LoadAddressImm<"la", shamt,CPURegsOpnd>;
+def LoadAddr32Imm : LoadAddressImm<"la", shamt,GPR32Opnd>;
@@ -1158,13 +1190,13 @@ def : MipsPat<(i32 imm:$imm),
(ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
// Carry MipsPatterns
-def : MipsPat<(subc CPURegs:$lhs, CPURegs:$rhs),
- (SUBu CPURegs:$lhs, CPURegs:$rhs)>;
+def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
+ (SUBu GPR32:$lhs, GPR32:$rhs)>;
let Predicates = [HasStdEnc, NotDSP] in {
- def : MipsPat<(addc CPURegs:$lhs, CPURegs:$rhs),
- (ADDu CPURegs:$lhs, CPURegs:$rhs)>;
- def : MipsPat<(addc CPURegs:$src, immSExt16:$imm),
- (ADDiu CPURegs:$src, imm:$imm)>;
+ def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
+ (ADDu GPR32:$lhs, GPR32:$rhs)>;
+ def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
+ (ADDiu GPR32:$src, imm:$imm)>;
}
// Call
@@ -1172,8 +1204,8 @@ def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
(JAL tglobaladdr:$dst)>;
def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
(JAL texternalsym:$dst)>;
-//def : MipsPat<(MipsJmpLink CPURegs:$dst),
-// (JALR CPURegs:$dst)>;
+//def : MipsPat<(MipsJmpLink GPR32:$dst),
+// (JALR GPR32:$dst)>;
// Tail call
def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
@@ -1195,38 +1227,38 @@ def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
-def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
- (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
-def : MipsPat<(add CPURegs:$hi, (MipsLo tblockaddress:$lo)),
- (ADDiu CPURegs:$hi, tblockaddress:$lo)>;
-def : MipsPat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
- (ADDiu CPURegs:$hi, tjumptable:$lo)>;
-def : MipsPat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)),
- (ADDiu CPURegs:$hi, tconstpool:$lo)>;
-def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaltlsaddr:$lo)),
- (ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>;
+def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
+ (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
+def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
+ (ADDiu GPR32:$hi, tblockaddress:$lo)>;
+def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
+ (ADDiu GPR32:$hi, tjumptable:$lo)>;
+def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
+ (ADDiu GPR32:$hi, tconstpool:$lo)>;
+def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
+ (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
// gp_rel relocs
-def : MipsPat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
- (ADDiu CPURegs:$gp, tglobaladdr:$in)>;
-def : MipsPat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
- (ADDiu CPURegs:$gp, tconstpool:$in)>;
+def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
+ (ADDiu GPR32:$gp, tglobaladdr:$in)>;
+def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
+ (ADDiu GPR32:$gp, tconstpool:$in)>;
// wrapper_pic
class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
MipsPat<(MipsWrapper RC:$gp, node:$in),
(ADDiuOp RC:$gp, node:$in)>;
-def : WrapperPat<tglobaladdr, ADDiu, CPURegs>;
-def : WrapperPat<tconstpool, ADDiu, CPURegs>;
-def : WrapperPat<texternalsym, ADDiu, CPURegs>;
-def : WrapperPat<tblockaddress, ADDiu, CPURegs>;
-def : WrapperPat<tjumptable, ADDiu, CPURegs>;
-def : WrapperPat<tglobaltlsaddr, ADDiu, CPURegs>;
+def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
+def : WrapperPat<tconstpool, ADDiu, GPR32>;
+def : WrapperPat<texternalsym, ADDiu, GPR32>;
+def : WrapperPat<tblockaddress, ADDiu, GPR32>;
+def : WrapperPat<tjumptable, ADDiu, GPR32>;
+def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
// Mips does not have "not", so we expand our way
-def : MipsPat<(not CPURegs:$in),
- (NOR CPURegsOpnd:$in, ZERO)>;
+def : MipsPat<(not GPR32:$in),
+ (NOR GPR32Opnd:$in, ZERO)>;
// extended loads
let Predicates = [NotN64, HasStdEnc] in {
@@ -1279,7 +1311,7 @@ def : MipsPat<(brcond RC:$cond, bb:$dst),
(BNEOp RC:$cond, ZEROReg, bb:$dst)>;
}
-defm : BrcondPats<CPURegs, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
+defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
(BLEZ i32:$lhs, bb:$dst)>;
@@ -1328,14 +1360,14 @@ multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
(XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
}
-defm : SeteqPats<CPURegs, SLTiu, XOR, SLTu, ZERO>;
-defm : SetlePats<CPURegs, SLT, SLTu>;
-defm : SetgtPats<CPURegs, SLT, SLTu>;
-defm : SetgePats<CPURegs, SLT, SLTu>;
-defm : SetgeImmPats<CPURegs, SLTi, SLTiu>;
+defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
+defm : SetlePats<GPR32, SLT, SLTu>;
+defm : SetgtPats<GPR32, SLT, SLTu>;
+defm : SetgePats<GPR32, SLT, SLTu>;
+defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
// bswap pattern
-def : MipsPat<(bswap CPURegs:$rt), (ROTR (WSBH CPURegs:$rt), 16)>;
+def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
// mflo/hi patterns.
def : MipsPat<(i32 (ExtractLOHI ACRegs:$ac, imm:$lohi_idx)),
diff --git a/lib/Target/Mips/MipsJITInfo.cpp b/lib/Target/Mips/MipsJITInfo.cpp
index 1b2a325..d76cb1d 100644
--- a/lib/Target/Mips/MipsJITInfo.cpp
+++ b/lib/Target/Mips/MipsJITInfo.cpp
@@ -218,9 +218,9 @@ void *MipsJITInfo::emitFunctionStub(const Function *F, void *Fn,
Hi++;
int Lo = (int)(EmittedAddr & 0xffff);
- // lui t9, %hi(EmittedAddr)
- // addiu t9, t9, %lo(EmittedAddr)
- // jalr t8, t9
+ // lui $t9, %hi(EmittedAddr)
+ // addiu $t9, $t9, %lo(EmittedAddr)
+ // jalr $t8, $t9
// nop
if (IsLittleEndian) {
JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi);
diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp
index 073daba..971176e 100644
--- a/lib/Target/Mips/MipsLongBranch.cpp
+++ b/lib/Target/Mips/MipsLongBranch.cpp
@@ -420,7 +420,7 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
MF = &F;
initMBBInfo();
- SmallVector<MBBInfo, 16>::iterator I, E = MBBInfos.end();
+ SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end();
bool EverMadeChange = false, MadeChange = true;
while (MadeChange) {
diff --git a/lib/Target/Mips/MipsMachineFunction.cpp b/lib/Target/Mips/MipsMachineFunction.cpp
index 59b23f7..a7299d7 100644
--- a/lib/Target/Mips/MipsMachineFunction.cpp
+++ b/lib/Target/Mips/MipsMachineFunction.cpp
@@ -38,8 +38,8 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() {
RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
else
RC = ST.isABI_N64() ?
- (const TargetRegisterClass*)&Mips::CPU64RegsRegClass :
- (const TargetRegisterClass*)&Mips::CPURegsRegClass;
+ (const TargetRegisterClass*)&Mips::GPR64RegClass :
+ (const TargetRegisterClass*)&Mips::GPR32RegClass;
return GlobalBaseReg = MF.getRegInfo().createVirtualRegister(RC);
}
@@ -60,7 +60,7 @@ void MipsFunctionInfo::createEhDataRegsFI() {
for (int I = 0; I < 4; ++I) {
const MipsSubtarget &ST = MF.getTarget().getSubtarget<MipsSubtarget>();
const TargetRegisterClass *RC = ST.isABI_N64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
EhDataRegFI[I] = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
RC->getAlignment(), false);
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index ae25e45..0b5fc33 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -54,8 +54,8 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
switch (RC->getID()) {
default:
return 0;
- case Mips::CPURegsRegClassID:
- case Mips::CPU64RegsRegClassID:
+ case Mips::GPR32RegClassID:
+ case Mips::GPR64RegClassID:
case Mips::DSPRegsRegClassID: {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
return 28 - TFI->hasFP(MF);
@@ -106,22 +106,22 @@ const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
BitVector MipsRegisterInfo::
getReservedRegs(const MachineFunction &MF) const {
- static const uint16_t ReservedCPURegs[] = {
+ static const uint16_t ReservedGPR32[] = {
Mips::ZERO, Mips::K0, Mips::K1, Mips::SP
};
- static const uint16_t ReservedCPU64Regs[] = {
+ static const uint16_t ReservedGPR64[] = {
Mips::ZERO_64, Mips::K0_64, Mips::K1_64, Mips::SP_64
};
BitVector Reserved(getNumRegs());
typedef TargetRegisterClass::const_iterator RegIter;
- for (unsigned I = 0; I < array_lengthof(ReservedCPURegs); ++I)
- Reserved.set(ReservedCPURegs[I]);
+ for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
+ Reserved.set(ReservedGPR32[I]);
- for (unsigned I = 0; I < array_lengthof(ReservedCPU64Regs); ++I)
- Reserved.set(ReservedCPU64Regs[I]);
+ for (unsigned I = 0; I < array_lengthof(ReservedGPR64); ++I)
+ Reserved.set(ReservedGPR64[I]);
if (Subtarget.hasMips64()) {
// Reserve all registers in AFGR64.
@@ -159,6 +159,8 @@ getReservedRegs(const MachineFunction &MF) const {
if (Subtarget.inMips16Mode()) {
Reserved.set(Mips::RA);
Reserved.set(Mips::RA_64);
+ Reserved.set(Mips::T0);
+ Reserved.set(Mips::T1);
}
// Reserve GP if small section is used.
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index ad6912c..c72c30d 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -147,91 +147,20 @@ let Namespace = "Mips" in {
def RA_64 : Mips64GPRReg< 31, "ra", [RA]>, DwarfRegNum<[31]>;
/// Mips Single point precision FPU Registers
- def F0 : FPR< 0, "f0">, DwarfRegNum<[32]>;
- def F1 : FPR< 1, "f1">, DwarfRegNum<[33]>;
- def F2 : FPR< 2, "f2">, DwarfRegNum<[34]>;
- def F3 : FPR< 3, "f3">, DwarfRegNum<[35]>;
- def F4 : FPR< 4, "f4">, DwarfRegNum<[36]>;
- def F5 : FPR< 5, "f5">, DwarfRegNum<[37]>;
- def F6 : FPR< 6, "f6">, DwarfRegNum<[38]>;
- def F7 : FPR< 7, "f7">, DwarfRegNum<[39]>;
- def F8 : FPR< 8, "f8">, DwarfRegNum<[40]>;
- def F9 : FPR< 9, "f9">, DwarfRegNum<[41]>;
- def F10 : FPR<10, "f10">, DwarfRegNum<[42]>;
- def F11 : FPR<11, "f11">, DwarfRegNum<[43]>;
- def F12 : FPR<12, "f12">, DwarfRegNum<[44]>;
- def F13 : FPR<13, "f13">, DwarfRegNum<[45]>;
- def F14 : FPR<14, "f14">, DwarfRegNum<[46]>;
- def F15 : FPR<15, "f15">, DwarfRegNum<[47]>;
- def F16 : FPR<16, "f16">, DwarfRegNum<[48]>;
- def F17 : FPR<17, "f17">, DwarfRegNum<[49]>;
- def F18 : FPR<18, "f18">, DwarfRegNum<[50]>;
- def F19 : FPR<19, "f19">, DwarfRegNum<[51]>;
- def F20 : FPR<20, "f20">, DwarfRegNum<[52]>;
- def F21 : FPR<21, "f21">, DwarfRegNum<[53]>;
- def F22 : FPR<22, "f22">, DwarfRegNum<[54]>;
- def F23 : FPR<23, "f23">, DwarfRegNum<[55]>;
- def F24 : FPR<24, "f24">, DwarfRegNum<[56]>;
- def F25 : FPR<25, "f25">, DwarfRegNum<[57]>;
- def F26 : FPR<26, "f26">, DwarfRegNum<[58]>;
- def F27 : FPR<27, "f27">, DwarfRegNum<[59]>;
- def F28 : FPR<28, "f28">, DwarfRegNum<[60]>;
- def F29 : FPR<29, "f29">, DwarfRegNum<[61]>;
- def F30 : FPR<30, "f30">, DwarfRegNum<[62]>;
- def F31 : FPR<31, "f31">, DwarfRegNum<[63]>;
+ foreach I = 0-31 in
+ def F#I : FPR<I, "f"#I>, DwarfRegNum<[!add(I, 32)]>;
/// Mips Double point precision FPU Registers (aliased
/// with the single precision to hold 64 bit values)
- def D0 : AFPR< 0, "f0", [F0, F1]>;
- def D1 : AFPR< 2, "f2", [F2, F3]>;
- def D2 : AFPR< 4, "f4", [F4, F5]>;
- def D3 : AFPR< 6, "f6", [F6, F7]>;
- def D4 : AFPR< 8, "f8", [F8, F9]>;
- def D5 : AFPR<10, "f10", [F10, F11]>;
- def D6 : AFPR<12, "f12", [F12, F13]>;
- def D7 : AFPR<14, "f14", [F14, F15]>;
- def D8 : AFPR<16, "f16", [F16, F17]>;
- def D9 : AFPR<18, "f18", [F18, F19]>;
- def D10 : AFPR<20, "f20", [F20, F21]>;
- def D11 : AFPR<22, "f22", [F22, F23]>;
- def D12 : AFPR<24, "f24", [F24, F25]>;
- def D13 : AFPR<26, "f26", [F26, F27]>;
- def D14 : AFPR<28, "f28", [F28, F29]>;
- def D15 : AFPR<30, "f30", [F30, F31]>;
+ foreach I = 0-15 in
+ def D#I : AFPR<!shl(I, 1), "f"#!shl(I, 1),
+ [!cast<FPR>("F"#!shl(I, 1)),
+ !cast<FPR>("F"#!add(!shl(I, 1), 1))]>;
/// Mips Double point precision FPU Registers in MFP64 mode.
- def D0_64 : AFPR64<0, "f0", [F0]>, DwarfRegNum<[32]>;
- def D1_64 : AFPR64<1, "f1", [F1]>, DwarfRegNum<[33]>;
- def D2_64 : AFPR64<2, "f2", [F2]>, DwarfRegNum<[34]>;
- def D3_64 : AFPR64<3, "f3", [F3]>, DwarfRegNum<[35]>;
- def D4_64 : AFPR64<4, "f4", [F4]>, DwarfRegNum<[36]>;
- def D5_64 : AFPR64<5, "f5", [F5]>, DwarfRegNum<[37]>;
- def D6_64 : AFPR64<6, "f6", [F6]>, DwarfRegNum<[38]>;
- def D7_64 : AFPR64<7, "f7", [F7]>, DwarfRegNum<[39]>;
- def D8_64 : AFPR64<8, "f8", [F8]>, DwarfRegNum<[40]>;
- def D9_64 : AFPR64<9, "f9", [F9]>, DwarfRegNum<[41]>;
- def D10_64 : AFPR64<10, "f10", [F10]>, DwarfRegNum<[42]>;
- def D11_64 : AFPR64<11, "f11", [F11]>, DwarfRegNum<[43]>;
- def D12_64 : AFPR64<12, "f12", [F12]>, DwarfRegNum<[44]>;
- def D13_64 : AFPR64<13, "f13", [F13]>, DwarfRegNum<[45]>;
- def D14_64 : AFPR64<14, "f14", [F14]>, DwarfRegNum<[46]>;
- def D15_64 : AFPR64<15, "f15", [F15]>, DwarfRegNum<[47]>;
- def D16_64 : AFPR64<16, "f16", [F16]>, DwarfRegNum<[48]>;
- def D17_64 : AFPR64<17, "f17", [F17]>, DwarfRegNum<[49]>;
- def D18_64 : AFPR64<18, "f18", [F18]>, DwarfRegNum<[50]>;
- def D19_64 : AFPR64<19, "f19", [F19]>, DwarfRegNum<[51]>;
- def D20_64 : AFPR64<20, "f20", [F20]>, DwarfRegNum<[52]>;
- def D21_64 : AFPR64<21, "f21", [F21]>, DwarfRegNum<[53]>;
- def D22_64 : AFPR64<22, "f22", [F22]>, DwarfRegNum<[54]>;
- def D23_64 : AFPR64<23, "f23", [F23]>, DwarfRegNum<[55]>;
- def D24_64 : AFPR64<24, "f24", [F24]>, DwarfRegNum<[56]>;
- def D25_64 : AFPR64<25, "f25", [F25]>, DwarfRegNum<[57]>;
- def D26_64 : AFPR64<26, "f26", [F26]>, DwarfRegNum<[58]>;
- def D27_64 : AFPR64<27, "f27", [F27]>, DwarfRegNum<[59]>;
- def D28_64 : AFPR64<28, "f28", [F28]>, DwarfRegNum<[60]>;
- def D29_64 : AFPR64<29, "f29", [F29]>, DwarfRegNum<[61]>;
- def D30_64 : AFPR64<30, "f30", [F30]>, DwarfRegNum<[62]>;
- def D31_64 : AFPR64<31, "f31", [F31]>, DwarfRegNum<[63]>;
+ foreach I = 0-31 in
+ def D#I#_64 : AFPR64<I, "f"#I, [!cast<FPR>("F"#I)]>,
+ DwarfRegNum<[!add(I, 32)]>;
// Hi/Lo registers
def HI : Register<"ac0">, DwarfRegNum<[64]>;
@@ -248,11 +177,13 @@ let Namespace = "Mips" in {
def LO64 : RegisterWithSubRegs<"lo", [LO]>;
}
- // Status flags register
- def FCR31 : Register<"31">;
+ // FP control registers.
+ foreach I = 0-31 in
+ def FCR#I : MipsReg<#I, ""#I>;
- // fcc0 register
- def FCC0 : MipsReg<0, "fcc0">;
+ // FP condition code registers.
+ foreach I = 0-7 in
+ def FCC#I : MipsReg<#I, "fcc"#I>;
// PC register
def PC : Register<"pc">;
@@ -292,7 +223,7 @@ let Namespace = "Mips" in {
// Register Classes
//===----------------------------------------------------------------------===//
-class CPURegsClass<list<ValueType> regTypes> :
+class GPR32Class<list<ValueType> regTypes> :
RegisterClass<"Mips", regTypes, 32, (add
// Reserved
ZERO, AT,
@@ -307,10 +238,10 @@ class CPURegsClass<list<ValueType> regTypes> :
// Reserved
K0, K1, GP, SP, FP, RA)>;
-def CPURegs : CPURegsClass<[i32]>;
-def DSPRegs : CPURegsClass<[v4i8, v2i16]>;
+def GPR32 : GPR32Class<[i32]>;
+def DSPRegs : GPR32Class<[v4i8, v2i16]>;
-def CPU64Regs : RegisterClass<"Mips", [i64], 64, (add
+def GPR64 : RegisterClass<"Mips", [i64], 64, (add
// Reserved
ZERO_64, AT_64,
// Return Values and Arguments
@@ -330,6 +261,13 @@ def CPU16Regs : RegisterClass<"Mips", [i32], 32, (add
// Callee save
S0, S1)>;
+def CPU16RegsPlusSP : RegisterClass<"Mips", [i32], 32, (add
+ // Return Values and Arguments
+ V0, V1, A0, A1, A2, A3,
+ // Callee save
+ S0, S1,
+ SP)>;
+
def CPURAReg : RegisterClass<"Mips", [i32], 32, (add RA)>, Unallocatable;
def CPUSPReg : RegisterClass<"Mips", [i32], 32, (add SP)>, Unallocatable;
@@ -357,8 +295,13 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64, (add
def FGR64 : RegisterClass<"Mips", [f64], 64, (sequence "D%u_64", 0, 31)>;
-// Condition Register for floating point operations
-def CCR : RegisterClass<"Mips", [i32], 32, (add FCR31,FCC0)>, Unallocatable;
+// FP control registers.
+def CCR : RegisterClass<"Mips", [i32], 32, (sequence "FCR%u", 0, 31)>,
+ Unallocatable;
+
+// FP condition code registers.
+def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>,
+ Unallocatable;
// Hi/Lo Registers
def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>;
@@ -388,47 +331,96 @@ def ACRegsDSP : RegisterClass<"Mips", [untyped], 64, (sequence "AC%u", 0, 3)> {
def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>;
// Register Operands.
-def CPURegsAsmOperand : AsmOperandClass {
- let Name = "CPURegsAsm";
- let ParserMethod = "parseCPURegs";
+
+class MipsAsmRegOperand : AsmOperandClass {
+ let RenderMethod = "addRegAsmOperands";
+}
+def GPR32AsmOperand : MipsAsmRegOperand {
+ let Name = "GPR32Asm";
+ let ParserMethod = "parseGPR32";
}
-def CPU64RegsAsmOperand : AsmOperandClass {
- let Name = "CPU64RegsAsm";
- let ParserMethod = "parseCPU64Regs";
+def GPR64AsmOperand : MipsAsmRegOperand {
+ let Name = "GPR64Asm";
+ let ParserMethod = "parseGPR64";
}
-def CCRAsmOperand : AsmOperandClass {
+def ACRegsDSPAsmOperand : MipsAsmRegOperand {
+ let Name = "ACRegsDSPAsm";
+ let ParserMethod = "parseACRegsDSP";
+}
+
+def CCRAsmOperand : MipsAsmRegOperand {
let Name = "CCRAsm";
let ParserMethod = "parseCCRRegs";
}
-def CPURegsOpnd : RegisterOperand<CPURegs, "printCPURegs"> {
- let ParserMatchClass = CPURegsAsmOperand;
+def AFGR64AsmOperand : MipsAsmRegOperand {
+ let Name = "AFGR64Asm";
+ let ParserMethod = "parseAFGR64Regs";
+}
+
+def FGR64AsmOperand : MipsAsmRegOperand {
+ let Name = "FGR64Asm";
+ let ParserMethod = "parseFGR64Regs";
}
-def CPU64RegsOpnd : RegisterOperand<CPU64Regs, "printCPURegs"> {
- let ParserMatchClass = CPU64RegsAsmOperand;
+def FGR32AsmOperand : MipsAsmRegOperand {
+ let Name = "FGR32Asm";
+ let ParserMethod = "parseFGR32Regs";
}
-def CCROpnd : RegisterOperand<CCR, "printCPURegs"> {
+def FCCRegsAsmOperand : MipsAsmRegOperand {
+ let Name = "FCCRegsAsm";
+ let ParserMethod = "parseFCCRegs";
+}
+
+def GPR32Opnd : RegisterOperand<GPR32> {
+ let ParserMatchClass = GPR32AsmOperand;
+}
+
+def GPR64Opnd : RegisterOperand<GPR64> {
+ let ParserMatchClass = GPR64AsmOperand;
+}
+
+def CCROpnd : RegisterOperand<CCR> {
let ParserMatchClass = CCRAsmOperand;
}
-def HWRegsAsmOperand : AsmOperandClass {
+def HWRegsAsmOperand : MipsAsmRegOperand {
let Name = "HWRegsAsm";
let ParserMethod = "parseHWRegs";
}
-def HW64RegsAsmOperand : AsmOperandClass {
+def HW64RegsAsmOperand : MipsAsmRegOperand {
let Name = "HW64RegsAsm";
let ParserMethod = "parseHW64Regs";
}
-def HWRegsOpnd : RegisterOperand<HWRegs, "printCPURegs"> {
+def HWRegsOpnd : RegisterOperand<HWRegs> {
let ParserMatchClass = HWRegsAsmOperand;
}
-def HW64RegsOpnd : RegisterOperand<HWRegs64, "printCPURegs"> {
+def HW64RegsOpnd : RegisterOperand<HWRegs64> {
let ParserMatchClass = HW64RegsAsmOperand;
}
+
+def AFGR64RegsOpnd : RegisterOperand<AFGR64> {
+ let ParserMatchClass = AFGR64AsmOperand;
+}
+
+def FGR64RegsOpnd : RegisterOperand<FGR64> {
+ let ParserMatchClass = FGR64AsmOperand;
+}
+
+def FGR32RegsOpnd : RegisterOperand<FGR32> {
+ let ParserMatchClass = FGR32AsmOperand;
+}
+
+def FCCRegsOpnd : RegisterOperand<FCC> {
+ let ParserMatchClass = FCCRegsAsmOperand;
+}
+
+def ACRegsDSPOpnd : RegisterOperand<ACRegsDSP> {
+ let ParserMatchClass = ACRegsDSPAsmOperand;
+}
diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp
index 91ffb94..d9e0fa4 100644
--- a/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -285,7 +285,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
if (StackSize == 0 && !MFI->adjustsStack()) return;
MachineModuleInfo &MMI = MF.getMMI();
- const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo();
+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
MachineLocation DstML, SrcML;
// Adjust stack.
@@ -321,9 +321,9 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
// one for each of the paired single precision registers.
if (Mips::AFGR64RegClass.contains(Reg)) {
unsigned Reg0 =
- MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true);
+ MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true);
unsigned Reg1 =
- MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true);
+ MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true);
if (!STI.isLittle())
std::swap(Reg0, Reg1);
@@ -333,16 +333,16 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
MMI.addFrameInst(
MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4));
} else {
- // Reg is either in CPURegs or FGR32.
+ // Reg is either in GPR32 or FGR32.
MMI.addFrameInst(MCCFIInstruction::createOffset(
- CSLabel, MRI.getDwarfRegNum(Reg, 1), Offset));
+ CSLabel, MRI->getDwarfRegNum(Reg, 1), Offset));
}
}
}
if (MipsFI->callsEhReturn()) {
const TargetRegisterClass *RC = STI.isABI_N64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
// Insert instructions that spill eh data registers.
for (int I = 0; I < 4; ++I) {
@@ -358,7 +358,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
for (int I = 0; I < 4; ++I) {
int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
- unsigned Reg = MRI.getDwarfRegNum(ehDataReg(I), true);
+ unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true);
MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset));
}
}
@@ -373,7 +373,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
- SetFPLabel, MRI.getDwarfRegNum(FP, true)));
+ SetFPLabel, MRI->getDwarfRegNum(FP, true)));
}
}
@@ -408,7 +408,7 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
if (MipsFI->callsEhReturn()) {
const TargetRegisterClass *RC = STI.isABI_N64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
// Find first instruction that restores a callee-saved register.
MachineBasicBlock::iterator I = MBBI;
@@ -516,7 +516,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// The spill slot should be half the size of the accumulator. If target is
// mips64, it should be 64-bit, otherwise it should be 32-bt.
const TargetRegisterClass *RC = STI.hasMips64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
RC->getAlignment(), false);
RS->addScavengingFrameIndex(FI);
@@ -530,7 +530,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
return;
const TargetRegisterClass *RC = STI.isABI_N64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
RC->getAlignment(), false);
RS->addScavengingFrameIndex(FI);
diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 7684bec..3b6480a 100644
--- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -119,9 +119,9 @@ void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
const TargetRegisterClass *RC;
if (Subtarget.isABI_N64())
- RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass;
+ RC = (const TargetRegisterClass*)&Mips::GPR64RegClass;
else
- RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass;
+ RC = (const TargetRegisterClass*)&Mips::GPR32RegClass;
V0 = RegInfo.createVirtualRegister(RC);
V1 = RegInfo.createVirtualRegister(RC);
@@ -402,7 +402,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) {
}
case MipsISD::ThreadPointer: {
- EVT PtrVT = TLI->getPointerTy();
+ EVT PtrVT = getTargetLowering()->getPointerTy();
unsigned RdhwrOpc, SrcReg, DestReg;
if (PtrVT == MVT::i32) {
diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp
index f640ecc..a0aacb5 100644
--- a/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -31,10 +31,10 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
clearRegisterClasses();
- addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
+ addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
if (HasMips64)
- addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
+ addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
if (Subtarget->hasDSP()) {
MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
@@ -53,6 +53,20 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::BITCAST, VecTys[i], Legal);
}
+ // Expand all truncating stores and extending loads.
+ unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
+ unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
+
+ for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
+ for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
+ setTruncStoreAction((MVT::SimpleValueType)VT0,
+ (MVT::SimpleValueType)VT1, Expand);
+
+ setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
+ setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
+ setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
+ }
+
setTargetDAGCombine(ISD::SHL);
setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SRL);
@@ -99,6 +113,7 @@ MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
setTargetDAGCombine(ISD::ADDE);
setTargetDAGCombine(ISD::SUBE);
+ setTargetDAGCombine(ISD::MUL);
computeRegisterProperties();
}
@@ -320,6 +335,57 @@ static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
+ EVT ShiftTy, SelectionDAG &DAG) {
+ // Clear the upper (64 - VT.sizeInBits) bits.
+ C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
+
+ // Return 0.
+ if (C == 0)
+ return DAG.getConstant(0, VT);
+
+ // Return x.
+ if (C == 1)
+ return X;
+
+ // If c is power of 2, return (shl x, log2(c)).
+ if (isPowerOf2_64(C))
+ return DAG.getNode(ISD::SHL, DL, VT, X,
+ DAG.getConstant(Log2_64(C), ShiftTy));
+
+ unsigned Log2Ceil = Log2_64_Ceil(C);
+ uint64_t Floor = 1LL << Log2_64(C);
+ uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
+
+ // If |c - floor_c| <= |c - ceil_c|,
+ // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
+ // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
+ if (C - Floor <= Ceil - C) {
+ SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
+ SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
+ return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
+ }
+
+ // If |c - floor_c| > |c - ceil_c|,
+ // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
+ SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
+ SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
+ return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
+}
+
+static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
+ const TargetLowering::DAGCombinerInfo &DCI,
+ const MipsSETargetLowering *TL) {
+ EVT VT = N->getValueType(0);
+
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
+ if (!VT.isVector())
+ return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
+ VT, TL->getScalarShiftAmountTy(VT), DAG);
+
+ return SDValue(N, 0);
+}
+
static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
SelectionDAG &DAG,
const MipsSubtarget *Subtarget) {
@@ -432,6 +498,8 @@ MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
return performADDECombine(N, DAG, DCI, Subtarget);
case ISD::SUBE:
return performSUBECombine(N, DAG, DCI, Subtarget);
+ case ISD::MUL:
+ return performMULCombine(N, DAG, DCI, this);
case ISD::SHL:
return performSHLCombine(N, DAG, DCI, Subtarget);
case ISD::SRA:
@@ -701,7 +769,7 @@ emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
- const TargetRegisterClass *RC = &Mips::CPURegsRegClass;
+ const TargetRegisterClass *RC = &Mips::GPR32RegClass;
DebugLoc DL = MI->getDebugLoc();
const BasicBlock *LLVM_BB = BB->getBasicBlock();
MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp
index e2a33dd..9521043 100644
--- a/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -94,9 +94,9 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool KillSrc) const {
unsigned Opc = 0, ZeroReg = 0;
- if (Mips::CPURegsRegClass.contains(DestReg)) { // Copy to CPU Reg.
- if (Mips::CPURegsRegClass.contains(SrcReg))
- Opc = Mips::OR, ZeroReg = Mips::ZERO;
+ if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.
+ if (Mips::GPR32RegClass.contains(SrcReg))
+ Opc = Mips::ADDu, ZeroReg = Mips::ZERO;
else if (Mips::CCRRegClass.contains(SrcReg))
Opc = Mips::CFC1;
else if (Mips::FGR32RegClass.contains(SrcReg))
@@ -115,7 +115,7 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
return;
}
}
- else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg.
+ else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.
if (Mips::CCRRegClass.contains(DestReg))
Opc = Mips::CTC1;
else if (Mips::FGR32RegClass.contains(DestReg))
@@ -141,11 +141,9 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Opc = Mips::FMOV_D32;
else if (Mips::FGR64RegClass.contains(DestReg, SrcReg))
Opc = Mips::FMOV_D64;
- else if (Mips::CCRRegClass.contains(DestReg, SrcReg))
- Opc = Mips::MOVCCRToCCR;
- else if (Mips::CPU64RegsRegClass.contains(DestReg)) { // Copy to CPU64 Reg.
- if (Mips::CPU64RegsRegClass.contains(SrcReg))
- Opc = Mips::OR64, ZeroReg = Mips::ZERO_64;
+ else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg.
+ if (Mips::GPR64RegClass.contains(SrcReg))
+ Opc = Mips::DADDu, ZeroReg = Mips::ZERO_64;
else if (Mips::HIRegs64RegClass.contains(SrcReg))
Opc = Mips::MFHI64, SrcReg = 0;
else if (Mips::LORegs64RegClass.contains(SrcReg))
@@ -153,7 +151,7 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else if (Mips::FGR64RegClass.contains(SrcReg))
Opc = Mips::DMFC1;
}
- else if (Mips::CPU64RegsRegClass.contains(SrcReg)) { // Copy from CPU64 Reg.
+ else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg.
if (Mips::HIRegs64RegClass.contains(DestReg))
Opc = Mips::MTHI64, DestReg = 0;
else if (Mips::LORegs64RegClass.contains(DestReg))
@@ -187,9 +185,9 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned Opc = 0;
- if (Mips::CPURegsRegClass.hasSubClassEq(RC))
+ if (Mips::GPR32RegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::SW_P8 : Mips::SW;
- else if (Mips::CPU64RegsRegClass.hasSubClassEq(RC))
+ else if (Mips::GPR64RegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::SD_P8 : Mips::SD;
else if (Mips::ACRegsRegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::STORE_AC64_P8 : Mips::STORE_AC64;
@@ -220,9 +218,9 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
unsigned Opc = 0;
- if (Mips::CPURegsRegClass.hasSubClassEq(RC))
+ if (Mips::GPR32RegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::LW_P8 : Mips::LW;
- else if (Mips::CPU64RegsRegClass.hasSubClassEq(RC))
+ else if (Mips::GPR64RegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::LD_P8 : Mips::LD;
else if (Mips::ACRegsRegClass.hasSubClassEq(RC))
Opc = IsN64 ? Mips::LOAD_AC64_P8 : Mips::LOAD_AC64;
@@ -342,7 +340,7 @@ MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
const TargetRegisterClass *RC = STI.isABI_N64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
bool LastInstrIsADDiu = NewImm;
const MipsAnalyzeImmediate::InstSeq &Seq =
@@ -513,7 +511,6 @@ void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
// indirect jump to TargetReg
const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
unsigned ADDU = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
- unsigned OR = STI.isABI_N64() ? Mips::OR64 : Mips::OR;
unsigned JR = STI.isABI_N64() ? Mips::JR64 : Mips::JR;
unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA;
@@ -522,13 +519,13 @@ void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
unsigned OffsetReg = I->getOperand(0).getReg();
unsigned TargetReg = I->getOperand(1).getReg();
- // or $ra, $v0, $zero
+ // addu $ra, $v0, $zero
// addu $sp, $sp, $v1
// jr $ra
if (TM.getRelocationModel() == Reloc::PIC_)
- BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), T9)
+ BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), T9)
.addReg(TargetReg).addReg(ZERO);
- BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), RA)
+ BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), RA)
.addReg(TargetReg).addReg(ZERO);
BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), SP)
.addReg(SP).addReg(OffsetReg);
diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp
index 9763f85..286a2e2 100644
--- a/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ b/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -56,10 +56,10 @@ requiresFrameIndexScavenging(const MachineFunction &MF) const {
const TargetRegisterClass *
MipsSERegisterInfo::intRegClass(unsigned Size) const {
if (Size == 4)
- return &Mips::CPURegsRegClass;
+ return &Mips::GPR32RegClass;
assert(Size == 8);
- return &Mips::CPU64RegsRegClass;
+ return &Mips::GPR64RegClass;
}
void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
diff --git a/lib/Target/Mips/MipsSchedule.td b/lib/Target/Mips/MipsSchedule.td
index 1add02f..2779064 100644
--- a/lib/Target/Mips/MipsSchedule.td
+++ b/lib/Target/Mips/MipsSchedule.td
@@ -17,13 +17,18 @@ def IMULDIV : FuncUnit;
// Instruction Itinerary classes used for Mips
//===----------------------------------------------------------------------===//
def IIAlu : InstrItinClass;
+def IIArith : InstrItinClass;
+def IILogic : InstrItinClass;
def IILoad : InstrItinClass;
def IIStore : InstrItinClass;
def IIXfer : InstrItinClass;
def IIBranch : InstrItinClass;
def IIHiLo : InstrItinClass;
def IIImul : InstrItinClass;
+def IIImult : InstrItinClass;
def IIIdiv : InstrItinClass;
+def IIseb : InstrItinClass;
+def IIslt : InstrItinClass;
def IIFcvt : InstrItinClass;
def IIFmove : InstrItinClass;
def IIFcmp : InstrItinClass;
@@ -35,6 +40,9 @@ def IIFdivDouble : InstrItinClass;
def IIFsqrtSingle : InstrItinClass;
def IIFsqrtDouble : InstrItinClass;
def IIFrecipFsqrtStep : InstrItinClass;
+def IIFLoad : InstrItinClass;
+def IIFStore : InstrItinClass;
+def IIFmoveC1 : InstrItinClass;
def IIPseudo : InstrItinClass;
//===----------------------------------------------------------------------===//
@@ -42,6 +50,8 @@ def IIPseudo : InstrItinClass;
//===----------------------------------------------------------------------===//
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IIArith , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IILogic , [InstrStage<1, [ALU]>]>,
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
InstrItinData<IIXfer , [InstrStage<2, [ALU]>]>,
@@ -59,5 +69,8 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<IIFdivDouble , [InstrStage<36, [ALU]>]>,
InstrItinData<IIFsqrtSingle , [InstrStage<54, [ALU]>]>,
InstrItinData<IIFsqrtDouble , [InstrStage<12, [ALU]>]>,
- InstrItinData<IIFrecipFsqrtStep , [InstrStage<5, [ALU]>]>
+ InstrItinData<IIFrecipFsqrtStep , [InstrStage<5, [ALU]>]>,
+ InstrItinData<IIFLoad , [InstrStage<3, [ALU]>]>,
+ InstrItinData<IIFStore , [InstrStage<1, [ALU]>]>,
+ InstrItinData<IIFmoveC1 , [InstrStage<2, [ALU]>]>
]>;
diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp
index 259e68d..541e2ca 100644
--- a/lib/Target/Mips/MipsSubtarget.cpp
+++ b/lib/Target/Mips/MipsSubtarget.cpp
@@ -104,7 +104,7 @@ MipsSubtarget::enablePostRAScheduler(CodeGenOpt::Level OptLevel,
Mode = TargetSubtargetInfo::ANTIDEP_NONE;
CriticalPathRCs.clear();
CriticalPathRCs.push_back(hasMips64() ?
- &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass);
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass);
return OptLevel >= CodeGenOpt::Aggressive;
}
diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h
index ef7568a..bfb13bb 100644
--- a/lib/Target/Mips/MipsSubtarget.h
+++ b/lib/Target/Mips/MipsSubtarget.h
@@ -194,6 +194,7 @@ public:
bool hasBitCount() const { return HasBitCount; }
bool hasFPIdx() const { return HasFPIdx; }
+ const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
bool allowMixed16_32() const { return inMips16ModeDefault() |
AllowMixed16_32;}
diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp
index 9af2f1b..ced6a09 100644
--- a/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/lib/Target/Mips/MipsTargetMachine.cpp
@@ -70,8 +70,8 @@ MipsTargetMachine(const Target &T, StringRef TT,
"E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64")),
InstrInfo(MipsInstrInfo::create(*this)),
FrameLowering(MipsFrameLowering::create(*this, Subtarget)),
- TLInfo(MipsTargetLowering::create(*this)),
- TSInfo(*this), JITInfo() {
+ TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this),
+ InstrItins(Subtarget.getInstrItineraryData()), JITInfo() {
initAsmInfo();
}
diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h
index ee55708..5a9a11d 100644
--- a/lib/Target/Mips/MipsTargetMachine.h
+++ b/lib/Target/Mips/MipsTargetMachine.h
@@ -44,6 +44,7 @@ class MipsTargetMachine : public LLVMTargetMachine {
OwningPtr<const MipsFrameLowering> FrameLoweringSE;
OwningPtr<const MipsTargetLowering> TLInfoSE;
MipsSelectionDAGInfo TSInfo;
+ const InstrItineraryData &InstrItins;
MipsJITInfo JITInfo;
public:
@@ -65,6 +66,11 @@ public:
{ return &Subtarget; }
virtual const DataLayout *getDataLayout() const
{ return &DL;}
+
+ virtual const InstrItineraryData *getInstrItineraryData() const {
+ return Subtarget.inMips16Mode() ? 0 : &InstrItins;
+ }
+
virtual MipsJITInfo *getJITInfo()
{ return &JITInfo; }