From ec3199f675b17b12fd779df557c6bff25aa4e862 Mon Sep 17 00:00:00 2001 From: Jack Carter Date: Sat, 12 Jan 2013 01:03:14 +0000 Subject: This patch tackles the problem of parsing Mips register names in the standalone assembler llvm-mc. Registers such as $A1 can represent either a 32 or 64 bit register based on the instruction using it. In addition, based on the abi, $T0 can represent different 32 bit registers. The problem is resolved by the Mips specific AsmParser td definitions changing to work together. Many cases of RegisterClass parameters are now RegisterOperand. Contributer: Vladimir Medic git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172284 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 330 ++++++++++++++++++------ lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp | 5 + lib/Target/Mips/InstPrinter/MipsInstPrinter.h | 1 + lib/Target/Mips/Mips64InstrInfo.td | 117 +++++---- lib/Target/Mips/MipsInstrFPU.td | 16 +- lib/Target/Mips/MipsInstrInfo.td | 219 ++++++++-------- lib/Target/Mips/MipsRegisterInfo.td | 45 ++++ test/MC/Mips/mips-alu-instructions.s | 2 +- test/MC/Mips/mips64-alu-instructions.s | 94 +++++++ 9 files changed, 591 insertions(+), 238 deletions(-) create mode 100644 test/MC/Mips/mips64-alu-instructions.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 085503eb0d..41df9d462d 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -84,15 +84,30 @@ class MipsAsmParser : public MCTargetAsmParser { bool ParseDirective(AsmToken DirectiveID); MipsAsmParser::OperandMatchResultTy - parseMemOperand(SmallVectorImpl&); + parseMemOperand(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseCPURegs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseCPU64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseHWRegs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseHW64Regs(SmallVectorImpl &Operands); + + MipsAsmParser::OperandMatchResultTy + parseCCRRegs(SmallVectorImpl &Operands); bool ParseOperand(SmallVectorImpl &, StringRef Mnemonic); - int tryParseRegister(StringRef Mnemonic); + int tryParseRegister(bool is64BitReg); bool tryParseRegisterOperand(SmallVectorImpl &Operands, - StringRef Mnemonic); + bool is64BitReg); bool needsExpansion(MCInst &Inst); @@ -107,7 +122,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool reportParseError(StringRef ErrorMsg); bool parseMemOffset(const MCExpr *&Res); - bool parseRelocOperand(const MCExpr *&Res, SMLoc &E); + bool parseRelocOperand(const MCExpr *&Res); bool parseDirectiveSet(); @@ -128,9 +143,9 @@ class MipsAsmParser : public MCTargetAsmParser { return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; } - int matchRegisterName(StringRef Symbol); + int matchRegisterName(StringRef Symbol, bool is64BitReg); - int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic); + int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); void setFpFormat(FpFormatTy Format) { FpFormat = Format; @@ -166,6 +181,20 @@ namespace { /// instruction. class MipsOperand : public MCParsedAsmOperand { +public: + enum RegisterKind { + Kind_None, + Kind_CPURegs, + Kind_CPU64Regs, + Kind_HWRegs, + Kind_HW64Regs, + Kind_FGR32Regs, + Kind_FGR64Regs, + Kind_AFGR32Regs, + Kind_CCRRegs + }; + +private: enum KindTy { k_CondCode, k_CoprocNum, @@ -186,6 +215,7 @@ class MipsOperand : public MCParsedAsmOperand { struct { unsigned RegNum; + RegisterKind Kind; } Reg; struct { @@ -246,6 +276,11 @@ public: return Reg.RegNum; } + void setRegKind(RegisterKind RegKind) { + assert((Kind == k_Register) && "Invalid access!"); + Reg.Kind = RegKind; + } + const MCExpr *getImm() const { assert((Kind == k_Immediate) && "Invalid access!"); return Imm.Val; @@ -296,6 +331,45 @@ public: return Op; } + bool isCPURegsAsm() const { + return Reg.Kind == Kind_CPURegs; + } + void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { + Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); + } + + bool isCPU64RegsAsm() const { + return Reg.Kind == Kind_CPU64Regs; + } + void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { + Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); + } + + 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; + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; } /// getEndLoc - Get the location of the last token of this operand. @@ -344,31 +418,31 @@ void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, if ( 0 <= ImmValue && ImmValue <= 65535) { // for 0 <= j <= 65535. // li d,j => ori d,$zero,j - tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); + tmpInst.setOpcode(Mips::ORi); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand( - MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); + MCOperand::CreateReg(Mips::ZERO)); tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); Instructions.push_back(tmpInst); } else if ( ImmValue < 0 && ImmValue >= -32768) { // for -32768 <= j < 0. // li d,j => addiu d,$zero,j - tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files? + tmpInst.setOpcode(Mips::ADDiu); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand( - MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); + MCOperand::CreateReg(Mips::ZERO)); tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); Instructions.push_back(tmpInst); } else { // for any other value of j that is representable as a 32-bit integer. // li d,j => lui d,hi16(j) // ori d,d,lo16(j) - tmpInst.setOpcode(isMips64() ? Mips::LUi64 : Mips::LUi); + tmpInst.setOpcode(Mips::LUi); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); Instructions.push_back(tmpInst); tmpInst.clear(); - tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); + tmpInst.setOpcode(Mips::ORi); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); @@ -390,7 +464,7 @@ void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, if ( -32768 <= ImmValue && ImmValue <= 65535) { //for -32768 <= j <= 65535. //la d,j(s) => addiu d,s,j - tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files? + tmpInst.setOpcode(Mips::ADDiu); tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); @@ -400,12 +474,12 @@ void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, //la d,j(s) => lui d,hi16(j) // ori d,d,lo16(j) // addu d,d,s - tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi); + tmpInst.setOpcode(Mips::LUi); tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); Instructions.push_back(tmpInst); tmpInst.clear(); - tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi); + tmpInst.setOpcode(Mips::ORi); tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); @@ -433,19 +507,19 @@ void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, tmpInst.setOpcode(Mips::ADDiu); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand( - MCOperand::CreateReg(isMips64()?Mips::ZERO_64:Mips::ZERO)); + MCOperand::CreateReg(Mips::ZERO)); tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); Instructions.push_back(tmpInst); } else { //for any other value of j that is representable as a 32-bit integer. //la d,j => lui d,hi16(j) // ori d,d,lo16(j) - tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi); + tmpInst.setOpcode(Mips::LUi); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); Instructions.push_back(tmpInst); tmpInst.clear(); - tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi); + tmpInst.setOpcode(Mips::ORi); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); @@ -498,10 +572,10 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return true; } -int MipsAsmParser::matchRegisterName(StringRef Name) { +int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { int CC; - if (!isMips64()) + if (!is64BitReg) CC = StringSwitch(Name) .Case("zero", Mips::ZERO) .Case("a0", Mips::A0) @@ -643,7 +717,7 @@ unsigned MipsAsmParser::getATReg() { unsigned Reg = Options.getATRegNum(); if (isMips64()) return getReg(Mips::CPU64RegsRegClassID,Reg); - + return getReg(Mips::CPURegsRegClassID,Reg); } @@ -651,63 +725,41 @@ unsigned MipsAsmParser::getReg(int RC,int RegNo) { return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); } -int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) { - - if (Mnemonic.lower() == "rdhwr") { - // at the moment only hwreg29 is supported - if (RegNum != 29) - return -1; - return Mips::HWR29; - } +int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { if (RegNum > 31) return -1; - // MIPS64 registers are numbered 1 after the 32-bit equivalents - return getReg(Mips::CPURegsRegClassID, RegNum) + isMips64(); + return getReg(RegClass, RegNum); } -int MipsAsmParser::tryParseRegister(StringRef Mnemonic) { +int MipsAsmParser::tryParseRegister(bool is64BitReg) { const AsmToken &Tok = Parser.getTok(); int RegNum = -1; if (Tok.is(AsmToken::Identifier)) { std::string lowerCase = Tok.getString().lower(); - RegNum = matchRegisterName(lowerCase); + RegNum = matchRegisterName(lowerCase, is64BitReg); } else if (Tok.is(AsmToken::Integer)) RegNum = matchRegisterByNumber(static_cast(Tok.getIntVal()), - Mnemonic.lower()); - else - return RegNum; //error - // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 - if (isMips64() && RegNum == Mips::ZERO_64) { - if (Mnemonic.find("ddiv") != StringRef::npos) - RegNum = Mips::ZERO; - } + is64BitReg ? Mips::CPU64RegsRegClassID + : Mips::CPURegsRegClassID); return RegNum; } bool MipsAsmParser:: tryParseRegisterOperand(SmallVectorImpl &Operands, - StringRef Mnemonic){ + bool is64BitReg){ SMLoc S = Parser.getTok().getLoc(); - SMLoc E = Parser.getTok().getEndLoc(); int RegNo = -1; - // FIXME: we should make a more generic method for CCR - if ((Mnemonic == "cfc1" || Mnemonic == "ctc1") - && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){ - RegNo = Parser.getTok().getIntVal(); // get the int value - // at the moment only fcc0 is supported - if (RegNo == 0) - RegNo = Mips::FCC0; - } else - RegNo = tryParseRegister(Mnemonic); + RegNo = tryParseRegister(is64BitReg); if (RegNo == -1) return true; - Operands.push_back(MipsOperand::CreateReg(RegNo, S, E)); + Operands.push_back(MipsOperand::CreateReg(RegNo, S, + Parser.getTok().getLoc())); Parser.Lex(); // Eat register token. return false; } @@ -734,7 +786,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, SMLoc S = Parser.getTok().getLoc(); Parser.Lex(); // Eat dollar token. // parse register operand - if (!tryParseRegisterOperand(Operands, Mnemonic)) { + if (!tryParseRegisterOperand(Operands, isMips64())) { if (getLexer().is(AsmToken::LParen)) { // check if it is indexed addressing operand Operands.push_back(MipsOperand::CreateToken("(", S)); @@ -743,7 +795,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, return true; Parser.Lex(); // eat dollar - if (tryParseRegisterOperand(Operands, Mnemonic)) + if (tryParseRegisterOperand(Operands, isMips64())) return true; if (!getLexer().is(AsmToken::RParen)) @@ -760,7 +812,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, if (Parser.ParseIdentifier(Identifier)) return true; - SMLoc E = SMLoc::getFromPointer(Identifier.end()); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); @@ -780,9 +832,9 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, // quoted label names const MCExpr *IdVal; SMLoc S = Parser.getTok().getLoc(); - SMLoc E; - if (getParser().ParseExpression(IdVal, E)) + if (getParser().ParseExpression(IdVal)) return true; + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); return false; } @@ -790,10 +842,11 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, // it is a symbol reference or constant expression const MCExpr *IdVal; SMLoc S = Parser.getTok().getLoc(); // start location of the operand - SMLoc E; - if (parseRelocOperand(IdVal, E)) + if (parseRelocOperand(IdVal)) return true; + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); return false; } // case AsmToken::Percent @@ -801,7 +854,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl&Operands, return true; } -bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res, SMLoc &EndLoc) { +bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { Parser.Lex(); // eat % token const AsmToken &Tok = Parser.getTok(); // get next token, operation @@ -813,6 +866,7 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res, SMLoc &EndLoc) { Parser.Lex(); // eat identifier // now make expression from the rest of the operand const MCExpr *IdVal; + SMLoc EndLoc; if (getLexer().getKind() == AsmToken::LParen) { while (1) { @@ -833,10 +887,8 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res, SMLoc &EndLoc) { if (getParser().ParseParenExpression(IdVal,EndLoc)) return true; - while (getLexer().getKind() == AsmToken::RParen) { - EndLoc = Parser.getTok().getEndLoc(); + while (getLexer().getKind() == AsmToken::RParen) Parser.Lex(); // eat ')' token - } } else return true; // parenthesis must follow reloc operand @@ -868,23 +920,24 @@ bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { StartLoc = Parser.getTok().getLoc(); - EndLoc = Parser.getTok().getEndLoc(); - RegNo = tryParseRegister(""); + RegNo = tryParseRegister(isMips64()); + EndLoc = Parser.getTok().getLoc(); return (RegNo == (unsigned)-1); } bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { + + SMLoc S; + switch(getLexer().getKind()) { default: return true; case AsmToken::Integer: case AsmToken::Minus: case AsmToken::Plus: - return getParser().ParseExpression(Res); - case AsmToken::Percent: { - SMLoc E; - return parseRelocOperand(Res, E); - } + return (getParser().ParseExpression(Res)); + case AsmToken::Percent: + return parseRelocOperand(Res); case AsmToken::LParen: return false; // it's probably assuming 0 } @@ -895,8 +948,9 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( SmallVectorImpl&Operands) { const MCExpr *IdVal = 0; - SMLoc S = Parser.getTok().getLoc(); - SMLoc E = Parser.getTok().getEndLoc(); + SMLoc S; + // first operand is the offset + S = Parser.getTok().getLoc(); if (parseMemOffset(IdVal)) return MatchOperand_ParseFail; @@ -905,6 +959,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( if (Tok.isNot(AsmToken::LParen)) { MipsOperand *Mnemonic = static_cast(Operands[0]); if (Mnemonic->getToken() == "la") { + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1); Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); return MatchOperand_Success; } @@ -917,7 +972,7 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( const AsmToken &Tok1 = Parser.getTok(); // get next token if (Tok1.is(AsmToken::Dollar)) { Parser.Lex(); // Eat '$' token. - if (tryParseRegisterOperand(Operands,"")) { + if (tryParseRegisterOperand(Operands, isMips64())) { Error(Parser.getTok().getLoc(), "unexpected token in operand"); return MatchOperand_ParseFail; } @@ -933,7 +988,8 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( return MatchOperand_ParseFail; } - E = Parser.getTok().getEndLoc(); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + Parser.Lex(); // Eat ')' token. if (IdVal == 0) @@ -950,6 +1006,126 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( return MatchOperand_Success; } +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseCPU64Regs(SmallVectorImpl &Operands) { + + if (!isMips64()) + 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, true)) { + // set the proper register kind + MipsOperand* op = static_cast(Operands.back()); + op->setRegKind(MipsOperand::Kind_CPU64Regs); + return MatchOperand_Success; + } + return MatchOperand_NoMatch; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseCPURegs(SmallVectorImpl &Operands) { + + // 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 propper register kind + MipsOperand* op = static_cast(Operands.back()); + op->setRegKind(MipsOperand::Kind_CPURegs); + return MatchOperand_Success; + } + return MatchOperand_NoMatch; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseHWRegs(SmallVectorImpl &Operands) { + + // if the first token is not '$' we have error + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat $ + + const AsmToken &Tok = Parser.getTok(); // get next token + if (Tok.isNot(AsmToken::Integer)) + return MatchOperand_NoMatch; + + unsigned RegNum = Tok.getIntVal(); + // at the moment only hwreg29 is supported + if (RegNum != 29) + return MatchOperand_ParseFail; + + MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, + Parser.getTok().getLoc()); + op->setRegKind(MipsOperand::Kind_HWRegs); + Operands.push_back(op); + + Parser.Lex(); // Eat reg number + return MatchOperand_Success; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseHW64Regs(SmallVectorImpl &Operands) { + //if the first token is not '$' we have error + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat $ + + const AsmToken &Tok = Parser.getTok(); // get next token + if (Tok.isNot(AsmToken::Integer)) + return MatchOperand_NoMatch; + + unsigned RegNum = Tok.getIntVal(); + // at the moment only hwreg29 is supported + if (RegNum != 29) + return MatchOperand_ParseFail; + + MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, + Parser.getTok().getLoc()); + op->setRegKind(MipsOperand::Kind_HWRegs); + Operands.push_back(op); + + Parser.Lex(); // Eat reg number + return MatchOperand_Success; +} + +MipsAsmParser::OperandMatchResultTy +MipsAsmParser::parseCCRRegs(SmallVectorImpl &Operands) { + unsigned RegNum; + //if the first token is not '$' we have error + if (Parser.getTok().isNot(AsmToken::Dollar)) + return MatchOperand_NoMatch; + SMLoc S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat $ + + 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 + return MatchOperand_NoMatch; + + MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, + Parser.getTok().getLoc()); + op->setRegKind(MipsOperand::Kind_CCRRegs); + Operands.push_back(op); + + Parser.Lex(); // Eat reg number + return MatchOperand_Success; +} + MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { MCSymbolRefExpr::VariantKind VK @@ -1083,8 +1259,8 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, if (Cc == -1) { return Error(NameLoc, "Invalid conditional code"); } - // FIXME: May include trailing whitespace... - SMLoc E = Parser.getTok().getLoc(); + SMLoc E = SMLoc::getFromPointer( + Parser.getTok().getLoc().getPointer() -1 ); Operands.push_back(MipsOperand::CreateImm( MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); } else { diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp index 68d3ac5f3b..97c367fbf1 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -149,6 +149,11 @@ 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); diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h index 3d8a6f918f..38cac68801 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h @@ -87,6 +87,7 @@ 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); private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index cdf12c8d2e..bbeb6498bc 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -71,52 +71,54 @@ let usesCustomInserter = 1, Predicates = [HasStdEnc], //===----------------------------------------------------------------------===// let DecoderNamespace = "Mips64" in { /// Arithmetic Instructions (ALU Immediate) -def DADDi : ArithLogicI<"daddi", simm16_64, CPU64Regs>, ADDI_FM<0x18>; -def DADDiu : ArithLogicI<"daddiu", simm16_64, CPU64Regs, immSExt16, add>, +def DADDi : ArithLogicI<"daddi", simm16_64, CPU64RegsOpnd>, ADDI_FM<0x18>; +def DADDiu : ArithLogicI<"daddiu", simm16_64, CPU64RegsOpnd, immSExt16, add>, ADDI_FM<0x19>, IsAsCheapAsAMove; -def DANDi : ArithLogicI<"andi", uimm16_64, CPU64Regs, immZExt16, and>, +def DANDi : ArithLogicI<"andi", uimm16_64, CPU64RegsOpnd, immZExt16, and>, ADDI_FM<0xc>; def SLTi64 : SetCC_I<"slti", setlt, simm16_64, immSExt16, CPU64Regs>, SLTI_FM<0xa>; def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, CPU64Regs>, SLTI_FM<0xb>; -def ORi64 : ArithLogicI<"ori", uimm16_64, CPU64Regs, immZExt16, or>, +def ORi64 : ArithLogicI<"ori", uimm16_64, CPU64RegsOpnd, immZExt16, or>, ADDI_FM<0xd>; -def XORi64 : ArithLogicI<"xori", uimm16_64, CPU64Regs, immZExt16, xor>, +def XORi64 : ArithLogicI<"xori", uimm16_64, CPU64RegsOpnd, immZExt16, xor>, ADDI_FM<0xe>; def LUi64 : LoadUpper<"lui", CPU64Regs, uimm16_64>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def DADD : ArithLogicR<"dadd", CPU64Regs>, ADD_FM<0, 0x2c>; -def DADDu : ArithLogicR<"daddu", CPU64Regs, 1, IIAlu, add>, ADD_FM<0, 0x2d>; -def DSUBu : ArithLogicR<"dsubu", CPU64Regs, 0, IIAlu, sub>, ADD_FM<0, 0x2f>; +def DADD : ArithLogicR<"dadd", CPU64RegsOpnd>, ADD_FM<0, 0x2c>; +def DADDu : ArithLogicR<"daddu", CPU64RegsOpnd, 1, IIAlu, add>, + ADD_FM<0, 0x2d>; +def DSUBu : ArithLogicR<"dsubu", CPU64RegsOpnd, 0, IIAlu, 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", CPU64Regs, 1, IIAlu, and>, ADD_FM<0, 0x24>; -def OR64 : ArithLogicR<"or", CPU64Regs, 1, IIAlu, or>, ADD_FM<0, 0x25>; -def XOR64 : ArithLogicR<"xor", CPU64Regs, 1, IIAlu, xor>, ADD_FM<0, 0x26>; -def NOR64 : LogicNOR<"nor", CPU64Regs>, ADD_FM<0, 0x27>; +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>; /// Shift Instructions -def DSLL : shift_rotate_imm<"dsll", shamt, CPU64Regs, shl, immZExt6>, +def DSLL : shift_rotate_imm<"dsll", shamt, CPU64RegsOpnd, shl, immZExt6>, SRA_FM<0x38, 0>; -def DSRL : shift_rotate_imm<"dsrl", shamt, CPU64Regs, srl, immZExt6>, +def DSRL : shift_rotate_imm<"dsrl", shamt, CPU64RegsOpnd, srl, immZExt6>, SRA_FM<0x3a, 0>; -def DSRA : shift_rotate_imm<"dsra", shamt, CPU64Regs, sra, immZExt6>, +def DSRA : shift_rotate_imm<"dsra", shamt, CPU64RegsOpnd, sra, immZExt6>, SRA_FM<0x3b, 0>; -def DSLLV : shift_rotate_reg<"dsllv", CPU64Regs, shl>, SRLV_FM<0x14, 0>; -def DSRLV : shift_rotate_reg<"dsrlv", CPU64Regs, srl>, SRLV_FM<0x16, 0>; -def DSRAV : shift_rotate_reg<"dsrav", CPU64Regs, sra>, SRLV_FM<0x17, 0>; -def DSLL32 : shift_rotate_imm<"dsll32", shamt, CPU64Regs>, SRA_FM<0x3c, 0>; -def DSRL32 : shift_rotate_imm<"dsrl32", shamt, CPU64Regs>, SRA_FM<0x3e, 0>; -def DSRA32 : shift_rotate_imm<"dsra32", shamt, CPU64Regs>, SRA_FM<0x3f, 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>; } // Rotate Instructions let Predicates = [HasMips64r2, HasStdEnc], DecoderNamespace = "Mips64" in { - def DROTR : shift_rotate_imm<"drotr", shamt, CPU64Regs, rotr, immZExt6>, + def DROTR : shift_rotate_imm<"drotr", shamt, CPU64RegsOpnd, rotr, immZExt6>, SRA_FM<0x3a, 1>; - def DROTRV : shift_rotate_reg<"drotrv", CPU64Regs, rotr>, SRLV_FM<0x16, 1>; + def DROTRV : shift_rotate_reg<"drotrv", CPU64RegsOpnd, rotr>, SRLV_FM<0x16, 1>; } let DecoderNamespace = "Mips64" in { @@ -135,12 +137,11 @@ defm LD : LoadM<"ld", CPU64Regs, load>, LW_FM<0x37>; defm SD : StoreM<"sd", CPU64Regs, store>, LW_FM<0x3f>; /// load/store left/right -let isCodeGenOnly = 1 in { - 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>; -} +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>; + 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>; @@ -148,13 +149,13 @@ defm SDR : StoreLeftRightM<"sdr", MipsSDR, CPU64Regs>, LW_FM<0x2d>; /// Load-linked, Store-conditional let Predicates = [NotN64, HasStdEnc] in { - def LLD : LLBase<"lld", CPU64Regs, mem>, LW_FM<0x34>; - def SCD : SCBase<"scd", CPU64Regs, mem>, LW_FM<0x3c>; + def LLD : LLBase<"lld", CPU64RegsOpnd, mem>, LW_FM<0x34>; + def SCD : SCBase<"scd", CPU64RegsOpnd, mem>, LW_FM<0x3c>; } let Predicates = [IsN64, HasStdEnc], isCodeGenOnly = 1 in { - def LLD_P8 : LLBase<"lld", CPU64Regs, mem64>, LW_FM<0x34>; - def SCD_P8 : SCBase<"scd", CPU64Regs, mem64>, LW_FM<0x3c>; + def LLD_P8 : LLBase<"lld", CPU64RegsOpnd, mem64>, LW_FM<0x34>; + def SCD_P8 : SCBase<"scd", CPU64RegsOpnd, mem64>, LW_FM<0x3c>; } /// Jump and Branch Instructions @@ -172,11 +173,11 @@ def TAILCALL64_R : JumpFR, MTLO_FM<8>, IsTailCall; let DecoderNamespace = "Mips64" in { /// Multiply and Divide Instructions. -def DMULT : Mult<"dmult", IIImul, CPU64Regs, [HI64, LO64]>, MULT_FM<0, 0x1c>; -def DMULTu : Mult<"dmultu", IIImul, CPU64Regs, [HI64, LO64]>, MULT_FM<0, 0x1d>; -def DSDIV : Div, +def DMULT : Mult<"dmult", IIImul, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1c>; +def DMULTu : Mult<"dmultu", IIImul, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1d>; +def DSDIV : Div, MULT_FM<0, 0x1e>; -def DUDIV : Div, +def DUDIV : Div, MULT_FM<0, 0x1f>; def MTHI64 : MoveToLOHI<"mthi", CPU64Regs, [HI64]>, MTLO_FM<0x11>; @@ -189,28 +190,28 @@ def SEB64 : SignExtInReg<"seb", i8, CPU64Regs>, SEB_FM<0x10, 0x20>; def SEH64 : SignExtInReg<"seh", i16, CPU64Regs>, SEB_FM<0x18, 0x20>; /// Count Leading -def DCLZ : CountLeading0<"dclz", CPU64Regs>, CLO_FM<0x24>; -def DCLO : CountLeading1<"dclo", CPU64Regs>, CLO_FM<0x25>; +def DCLZ : CountLeading0<"dclz", CPU64RegsOpnd>, CLO_FM<0x24>; +def DCLO : CountLeading1<"dclo", CPU64RegsOpnd>, CLO_FM<0x25>; /// Double Word Swap Bytes/HalfWords -def DSBH : SubwordSwap<"dsbh", CPU64Regs>, SEB_FM<2, 0x24>; -def DSHD : SubwordSwap<"dshd", CPU64Regs>, SEB_FM<5, 0x24>; +def DSBH : SubwordSwap<"dsbh", CPU64RegsOpnd>, SEB_FM<2, 0x24>; +def DSHD : SubwordSwap<"dshd", CPU64RegsOpnd>, SEB_FM<5, 0x24>; def LEA_ADDiu64 : EffectiveAddress<"daddiu", CPU64Regs, mem_ea_64>, LW_FM<0x19>; } let DecoderNamespace = "Mips64" in { -def RDHWR64 : ReadHardware, RDHWR_FM; +def RDHWR64 : ReadHardware, RDHWR_FM; -def DEXT : ExtBase<"dext", CPU64Regs>, EXT_FM<3>; +def DEXT : ExtBase<"dext", CPU64RegsOpnd>, EXT_FM<3>; let Pattern = [] in { - def DEXTU : ExtBase<"dextu", CPU64Regs>, EXT_FM<2>; - def DEXTM : ExtBase<"dextm", CPU64Regs>, EXT_FM<1>; + def DEXTU : ExtBase<"dextu", CPU64RegsOpnd>, EXT_FM<2>; + def DEXTM : ExtBase<"dextm", CPU64RegsOpnd>, EXT_FM<1>; } -def DINS : InsBase<"dins", CPU64Regs>, EXT_FM<7>; +def DINS : InsBase<"dins", CPU64RegsOpnd>, EXT_FM<7>; let Pattern = [] in { - def DINSU : InsBase<"dinsu", CPU64Regs>, EXT_FM<6>; - def DINSM : InsBase<"dinsm", CPU64Regs>, EXT_FM<5>; + def DINSU : InsBase<"dinsu", CPU64RegsOpnd>, EXT_FM<6>; + def DINSM : InsBase<"dinsm", CPU64RegsOpnd>, EXT_FM<5>; } let isCodeGenOnly = 1, rs = 0, shamt = 0 in { @@ -304,7 +305,25 @@ def : MipsPat<(bswap CPU64Regs:$rt), (DSHD (DSBH CPU64Regs:$rt))>; //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// -def : InstAlias<"move $dst,$src", (DADD CPU64Regs:$dst,CPU64Regs:$src,ZERO_64)>; +def : InstAlias<"move $dst,$src", (DADDu CPU64RegsOpnd:$dst, + CPU64RegsOpnd:$src,ZERO_64)>, + Requires<[HasMips64]>; +def : InstAlias<"and $rs, $rt, $imm", + (DANDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm)>, + Requires<[HasMips64]>; +def : InstAlias<"slt $rs, $rt, $imm", + (SLTi64 CPURegsOpnd:$rs, CPU64Regs:$rt, simm16_64:$imm)>, + Requires<[HasMips64]>; +def : InstAlias<"xor $rs, $rt, $imm", + (XORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm)>, + Requires<[HasMips64]>; +def : InstAlias<"not $rt, $rs", (NOR64 CPU64RegsOpnd:$rt, CPU64RegsOpnd:$rs, ZERO_64)>, + Requires<[HasMips64]>; +def : InstAlias<"j $rs", (JR64 CPU64Regs:$rs)>, Requires<[HasMips64]>; +def : InstAlias<"daddu $rs, $rt, $imm", + (DADDiu CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm)>; +def : InstAlias<"dadd $rs, $rt, $imm", + (DADDi CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, simm16_64:$imm)>; /// Move between CPU and coprocessor registers let DecoderNamespace = "Mips64" in { diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index ab6f8ab770..a38ed16ee7 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -138,6 +138,16 @@ class MTC1_FT; +class MFC1_FT_CCR : + InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR>; + +class MTC1_FT_CCR : + InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), + [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR>; + class LW_FT : InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), @@ -265,8 +275,8 @@ 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<"cfc1", CPURegs, CCR, IIFmove>, MFC1_FM<2>; -def CTC1 : MTC1_FT<"ctc1", CCR, CPURegs, IIFmove>, MFC1_FM<6>; +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>; @@ -437,7 +447,7 @@ def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions //===----------------------------------------------------------------------===// -def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCR:$src), []>; +def MOVCCRToCCR : PseudoSE<(outs CCR:$dst), (ins CCROpnd:$src), []>; // This pseudo instr gets expanded into 2 mtc1 instrs after register // allocation. diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 8f2ce6fa79..3ed8f93599 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -332,12 +332,12 @@ def addr : //===----------------------------------------------------------------------===// // Arithmetic and logical instructions with 3 register operands. -class ArithLogicR: - InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt), + InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RC:$rd, (OpNode RC:$rs, RC:$rt))], Itin, FrmR> { + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> { let isCommutable = isComm; let isReMaterializable = 1; string BaseOpcode; @@ -345,27 +345,27 @@ class ArithLogicR : - InstSE<(outs RC:$rt), (ins RC:$rs, Od:$imm16), + InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu, FrmI> { + [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], IIAlu, FrmI> { let isReMaterializable = 1; } // Arithmetic Multiply ADD/SUB class MArithR : - InstSE<(outs), (ins CPURegs:$rs, CPURegs:$rt), + InstSE<(outs), (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt), !strconcat(opstr, "\t$rs, $rt"), - [(op CPURegs:$rs, CPURegs:$rt, LO, HI)], IIImul, FrmR> { + [(op CPURegsOpnd:$rs, CPURegsOpnd:$rt, LO, HI)], IIImul, FrmR> { let Defs = [HI, LO]; let Uses = [HI, LO]; let isCommutable = isComm; } // Logical -class LogicNOR: +class LogicNOR: InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR> { @@ -374,17 +374,17 @@ class LogicNOR: // Shifts class shift_rotate_imm : InstSE<(outs RC:$rd), (ins RC:$rt, ImmOpnd:$shamt), !strconcat(opstr, "\t$rd, $rt, $shamt"), [(set RC:$rd, (OpNode RC:$rt, PF:$shamt))], IIAlu, FrmR>; -class shift_rotate_reg: - InstSE<(outs RC:$rd), (ins CPURegs:$rs, RC:$rt), + InstSE<(outs RC:$rd), (ins CPURegsOpnd:$rs, RC:$rt), !strconcat(opstr, "\t$rd, $rt, $rs"), - [(set RC:$rd, (OpNode RC:$rt, CPURegs:$rs))], IIAlu, FrmR>; + [(set RC:$rd, (OpNode RC:$rt, CPURegsOpnd:$rs))], IIAlu, FrmR>; // Load Upper Imediate class LoadUpper: @@ -498,15 +498,15 @@ class CBranchZero : // SetCC class SetCC_R : - InstSE<(outs CPURegs:$rd), (ins RC:$rs, RC:$rt), + InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set CPURegs:$rd, (cond_op RC:$rs, RC:$rt))], IIAlu, FrmR>; + [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], IIAlu, FrmR>; class SetCC_I: - InstSE<(outs CPURegs:$rt), (ins RC:$rs, Od:$imm16), + InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))], IIAlu, FrmI>; + [(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))], IIAlu, FrmI>; // Jump class JumpFJ; - class BGEZAL_FT : - InstSE<(outs), (ins RC:$rs, brtarget:$offset), + class BGEZAL_FT : + InstSE<(outs), (ins RO:$rs, brtarget:$offset), !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>; } @@ -585,19 +585,19 @@ class SYNC_FT : NoItinerary, FrmOther>; // Mul, Div -class Mult DefRegs> : - InstSE<(outs), (ins RC:$rs, RC:$rt), !strconcat(opstr, "\t$rs, $rt"), [], + InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR> { let isCommutable = 1; let Defs = DefRegs; let neverHasSideEffects = 1; } -class Div DefRegs> : - InstSE<(outs), (ins RC:$rs, RC:$rt), - !strconcat(opstr, "\t$$zero, $rs, $rt"), [(op RC:$rs, RC:$rt)], itin, + InstSE<(outs), (ins RO:$rs, RO:$rt), + !strconcat(opstr, "\t$$zero, $rs, $rt"), [(op RO:$rs, RO:$rt)], itin, FrmR> { let Defs = DefRegs; } @@ -623,14 +623,14 @@ class EffectiveAddress : } // Count Leading Ones/Zeros in Word -class CountLeading0: - InstSE<(outs RC:$rd), (ins RC:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RC:$rd, (ctlz RC:$rs))], IIAlu, FrmR>, +class CountLeading0: + InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), + [(set RO:$rd, (ctlz RO:$rs))], IIAlu, FrmR>, Requires<[HasBitCount, HasStdEnc]>; -class CountLeading1: - InstSE<(outs RC:$rd), (ins RC:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RC:$rd, (ctlz (not RC:$rs)))], IIAlu, FrmR>, +class CountLeading1: + InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), + [(set RO:$rd, (ctlz (not RO:$rs)))], IIAlu, FrmR>, Requires<[HasBitCount, HasStdEnc]>; @@ -642,31 +642,31 @@ class SignExtInReg : } // Subword Swap -class SubwordSwap: - InstSE<(outs RC:$rd), (ins RC:$rt), !strconcat(opstr, "\t$rd, $rt"), [], +class SubwordSwap: + InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], NoItinerary, FrmR> { let Predicates = [HasSwap, HasStdEnc]; let neverHasSideEffects = 1; } // Read Hardware -class ReadHardware : - InstSE<(outs CPURegClass:$rt), (ins HWRegClass:$rd), "rdhwr\t$rt, $rd", [], +class ReadHardware : + InstSE<(outs CPURegClass:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], IIAlu, FrmR>; // Ext and Ins -class ExtBase: - InstSE<(outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ext:$size), +class ExtBase: + InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ext:$size), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RC:$rt, (MipsExt RC:$rs, imm:$pos, imm:$size))], NoItinerary, + [(set RO:$rt, (MipsExt RO:$rs, imm:$pos, imm:$size))], NoItinerary, FrmR> { let Predicates = [HasMips32r2, HasStdEnc]; } -class InsBase: - InstSE<(outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ins:$size, RC:$src), +class InsBase: + InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ins:$size, RO:$src), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RC:$rt, (MipsIns RC:$rs, imm:$pos, imm:$size, RC:$src))], + [(set RO:$rt, (MipsIns RO:$rs, imm:$pos, imm:$size, RO:$src))], NoItinerary, FrmR> { let Predicates = [HasMips32r2, HasStdEnc]; let Constraints = "$src = $rt"; @@ -699,15 +699,15 @@ multiclass AtomicCmpSwap32 { } } -class LLBase : - InstSE<(outs RC:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), +class LLBase : + InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; let mayLoad = 1; } -class SCBase : - InstSE<(outs RC:$dst), (ins RC:$rt, Mem:$addr), +class SCBase : + InstSE<(outs RO:$dst), (ins RO:$rt, Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; let mayStore = 1; @@ -769,42 +769,42 @@ let usesCustomInserter = 1 in { //===----------------------------------------------------------------------===// /// Arithmetic Instructions (ALU Immediate) -def ADDiu : ArithLogicI<"addiu", simm16, CPURegs, immSExt16, add>, +def ADDiu : ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>, ADDI_FM<0x9>, IsAsCheapAsAMove; -def ADDi : ArithLogicI<"addi", simm16, CPURegs>, ADDI_FM<0x8>; +def ADDi : ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>; def SLTi : SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, SLTI_FM<0xa>; def SLTiu : SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, SLTI_FM<0xb>; -def ANDi : ArithLogicI<"andi", uimm16, CPURegs, immZExt16, and>, ADDI_FM<0xc>; -def ORi : ArithLogicI<"ori", uimm16, CPURegs, immZExt16, or>, ADDI_FM<0xd>; -def XORi : ArithLogicI<"xori", uimm16, CPURegs, immZExt16, xor>, ADDI_FM<0xe>; +def ANDi : ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, ADDI_FM<0xc>; +def ORi : ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, ADDI_FM<0xd>; +def XORi : ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, ADDI_FM<0xe>; def LUi : LoadUpper<"lui", CPURegs, uimm16>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : ArithLogicR<"addu", CPURegs, 1, IIAlu, add>, ADD_FM<0, 0x21>; -def SUBu : ArithLogicR<"subu", CPURegs, 0, IIAlu, sub>, ADD_FM<0, 0x23>; -def MUL : ArithLogicR<"mul", CPURegs, 1, IIImul, mul>, ADD_FM<0x1c, 2>; -def ADD : ArithLogicR<"add", CPURegs>, ADD_FM<0, 0x20>; -def SUB : ArithLogicR<"sub", CPURegs>, ADD_FM<0, 0x22>; +def ADDu : ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, ADD_FM<0, 0x21>; +def SUBu : ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, ADD_FM<0, 0x23>; +def MUL : ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, ADD_FM<0x1c, 2>; +def ADD : ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>; +def SUB : ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>; def SLT : SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>; def SLTu : SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>; -def AND : ArithLogicR<"and", CPURegs, 1, IIAlu, and>, ADD_FM<0, 0x24>; -def OR : ArithLogicR<"or", CPURegs, 1, IIAlu, or>, ADD_FM<0, 0x25>; -def XOR : ArithLogicR<"xor", CPURegs, 1, IIAlu, xor>, ADD_FM<0, 0x26>; -def NOR : LogicNOR<"nor", CPURegs>, ADD_FM<0, 0x27>; +def AND : ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, ADD_FM<0, 0x24>; +def OR : ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, ADD_FM<0, 0x25>; +def XOR : ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, ADD_FM<0, 0x26>; +def NOR : LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>; /// Shift Instructions -def SLL : shift_rotate_imm<"sll", shamt, CPURegs, shl, immZExt5>, SRA_FM<0, 0>; -def SRL : shift_rotate_imm<"srl", shamt, CPURegs, srl, immZExt5>, SRA_FM<2, 0>; -def SRA : shift_rotate_imm<"sra", shamt, CPURegs, sra, immZExt5>, SRA_FM<3, 0>; -def SLLV : shift_rotate_reg<"sllv", CPURegs, shl>, SRLV_FM<4, 0>; -def SRLV : shift_rotate_reg<"srlv", CPURegs, srl>, SRLV_FM<6, 0>; -def SRAV : shift_rotate_reg<"srav", CPURegs, sra>, SRLV_FM<7, 0>; +def SLL : shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>, SRA_FM<0, 0>; +def SRL : shift_rotate_imm<"srl", shamt, CPURegsOpnd, srl, immZExt5>, SRA_FM<2, 0>; +def SRA : shift_rotate_imm<"sra", shamt, CPURegsOpnd, sra, immZExt5>, SRA_FM<3, 0>; +def SLLV : shift_rotate_reg<"sllv", CPURegsOpnd, shl>, SRLV_FM<4, 0>; +def SRLV : shift_rotate_reg<"srlv", CPURegsOpnd, srl>, SRLV_FM<6, 0>; +def SRAV : shift_rotate_reg<"srav", CPURegsOpnd, sra>, SRLV_FM<7, 0>; // Rotate Instructions let Predicates = [HasMips32r2, HasStdEnc] in { - def ROTR : shift_rotate_imm<"rotr", shamt, CPURegs, rotr, immZExt5>, + def ROTR : shift_rotate_imm<"rotr", shamt, CPURegsOpnd, rotr, immZExt5>, SRA_FM<2, 1>; - def ROTRV : shift_rotate_reg<"rotrv", CPURegs, rotr>, SRLV_FM<6, 1>; + def ROTRV : shift_rotate_reg<"rotrv", CPURegsOpnd, rotr>, SRLV_FM<6, 1>; } /// Load and Store Instructions @@ -828,13 +828,13 @@ def SYNC : SYNC_FT, SYNC_FM; /// Load-linked, Store-conditional let Predicates = [NotN64, HasStdEnc] in { - def LL : LLBase<"ll", CPURegs, mem>, LW_FM<0x30>; - def SC : SCBase<"sc", CPURegs, mem>, LW_FM<0x38>; + def LL : LLBase<"ll", CPURegsOpnd, mem>, LW_FM<0x30>; + def SC : SCBase<"sc", CPURegsOpnd, mem>, LW_FM<0x38>; } let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LL_P8 : LLBase<"ll", CPURegs, mem64>, LW_FM<0x30>; - def SC_P8 : SCBase<"sc", CPURegs, mem64>, LW_FM<0x38>; + def LL_P8 : LLBase<"ll", CPURegsOpnd, mem64>, LW_FM<0x30>; + def SC_P8 : SCBase<"sc", CPURegsOpnd, mem64>, LW_FM<0x38>; } /// Jump and Branch Instructions @@ -853,18 +853,18 @@ def BAL_BR: BAL_FT, BAL_FM; def JAL : JumpLink<"jal">, FJ<3>; def JALR : JumpLinkReg<"jalr", CPURegs>, JALR_FM; -def BGEZAL : BGEZAL_FT<"bgezal", CPURegs>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", CPURegs>, BGEZAL_FM<0x10>; +def BGEZAL : BGEZAL_FT<"bgezal", CPURegsOpnd>, BGEZAL_FM<0x11>; +def BLTZAL : BGEZAL_FT<"bltzal", CPURegsOpnd>, BGEZAL_FM<0x10>; def TAILCALL : JumpFJ, FJ<2>, IsTailCall; def TAILCALL_R : JumpFR, MTLO_FM<8>, IsTailCall; def RET : RetBase, MTLO_FM<8>; /// Multiply and Divide Instructions. -def MULT : Mult<"mult", IIImul, CPURegs, [HI, LO]>, MULT_FM<0, 0x18>; -def MULTu : Mult<"multu", IIImul, CPURegs, [HI, LO]>, MULT_FM<0, 0x19>; -def SDIV : Div, MULT_FM<0, 0x1a>; -def UDIV : Div, +def MULT : Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x18>; +def MULTu : Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x19>; +def SDIV : Div, MULT_FM<0, 0x1a>; +def UDIV : Div, MULT_FM<0, 0x1b>; def MTHI : MoveToLOHI<"mthi", CPURegs, [HI]>, MTLO_FM<0x11>; @@ -877,11 +877,11 @@ def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10, 0x20>; def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18, 0x20>; /// Count Leading -def CLZ : CountLeading0<"clz", CPURegs>, CLO_FM<0x20>; -def CLO : CountLeading1<"clo", CPURegs>, CLO_FM<0x21>; +def CLZ : CountLeading0<"clz", CPURegsOpnd>, CLO_FM<0x20>; +def CLO : CountLeading1<"clo", CPURegsOpnd>, CLO_FM<0x21>; /// Word Swap Bytes Within Halfwords -def WSBH : SubwordSwap<"wsbh", CPURegs>, SEB_FM<2, 0x20>; +def WSBH : SubwordSwap<"wsbh", CPURegsOpnd>, SEB_FM<2, 0x20>; /// No operation. /// FIXME: NOP should be an alias of "sll $0, $0, 0". @@ -899,10 +899,10 @@ def MADDU : MArithR<"maddu", MipsMAddu, 1>, MULT_FM<0x1c, 1>; def MSUB : MArithR<"msub", MipsMSub>, MULT_FM<0x1c, 4>; def MSUBU : MArithR<"msubu", MipsMSubu>, MULT_FM<0x1c, 5>; -def RDHWR : ReadHardware, RDHWR_FM; +def RDHWR : ReadHardware, RDHWR_FM; -def EXT : ExtBase<"ext", CPURegs>, EXT_FM<0>; -def INS : InsBase<"ins", CPURegs>, EXT_FM<4>; +def EXT : ExtBase<"ext", CPURegsOpnd>, EXT_FM<0>; +def INS : InsBase<"ins", CPURegsOpnd>, EXT_FM<4>; /// Move Control Registers From/To CPU Registers def MFC0_3OP : MFC3OP<(outs CPURegs:$rt), (ins CPURegs:$rd, uimm16:$sel), @@ -920,22 +920,25 @@ def MTC2_3OP : MFC3OP<(outs CPURegs:$rd, uimm16:$sel), (ins CPURegs:$rt), //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// -def : InstAlias<"move $dst,$src", (ADD CPURegs:$dst,CPURegs:$src,ZERO)>; -def : InstAlias<"bal $offset", (BGEZAL RA,brtarget:$offset)>; -def : InstAlias<"addu $rs,$rt,$imm", - (ADDiu CPURegs:$rs,CPURegs:$rt,simm16:$imm)>; -def : InstAlias<"add $rs,$rt,$imm", - (ADDi CPURegs:$rs,CPURegs:$rt,simm16:$imm)>; -def : InstAlias<"and $rs,$rt,$imm", - (ANDi CPURegs:$rs,CPURegs:$rt,simm16:$imm)>; -def : InstAlias<"j $rs", (JR CPURegs:$rs)>; -def : InstAlias<"not $rt,$rs", (NOR CPURegs:$rt,CPURegs:$rs,ZERO)>; -def : InstAlias<"neg $rt,$rs", (SUB CPURegs:$rt,ZERO,CPURegs:$rs)>; -def : InstAlias<"negu $rt,$rs", (SUBu CPURegs:$rt,ZERO,CPURegs:$rs)>; -def : InstAlias<"slt $rs,$rt,$imm", - (SLTi CPURegs:$rs,CPURegs:$rt,simm16:$imm)>; -def : InstAlias<"xor $rs,$rt,$imm", - (XORi CPURegs:$rs,CPURegs:$rt,simm16:$imm)>; +def : InstAlias<"move $dst,$src", (ADDu CPURegsOpnd:$dst, + CPURegsOpnd:$src,ZERO)>, Requires<[NotMips64]>; +def : InstAlias<"bal $offset", (BGEZAL RA, brtarget:$offset)>; +def : InstAlias<"addu $rs, $rt, $imm", + (ADDiu CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm)>; +def : InstAlias<"add $rs, $rt, $imm", + (ADDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm)>; +def : InstAlias<"and $rs, $rt, $imm", + (ANDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm)>; +def : InstAlias<"j $rs", (JR CPURegs:$rs)>, Requires<[NotMips64]>; +def : InstAlias<"not $rt, $rs", (NOR CPURegsOpnd:$rt, CPURegsOpnd:$rs, ZERO)>; +def : InstAlias<"neg $rt, $rs", (SUB CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs)>; +def : InstAlias<"negu $rt, $rs", (SUBu CPURegsOpnd:$rt, ZERO, + CPURegsOpnd:$rs)>; +def : InstAlias<"slt $rs, $rt, $imm", + (SLTi CPURegsOpnd:$rs, CPURegs:$rt, simm16:$imm)>; +def : InstAlias<"xor $rs, $rt, $imm", + (XORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm)>, + Requires<[NotMips64]>; def : InstAlias<"mfc0 $rt, $rd", (MFC0_3OP CPURegs:$rt, CPURegs:$rd, 0)>; def : InstAlias<"mtc0 $rt, $rd", (MTC0_3OP CPURegs:$rd, 0, CPURegs:$rt)>; def : InstAlias<"mfc2 $rt, $rd", (MFC2_3OP CPURegs:$rt, CPURegs:$rd, 0)>; @@ -945,20 +948,20 @@ def : InstAlias<"mtc2 $rt, $rd", (MTC2_3OP CPURegs:$rd, 0, CPURegs:$rt)>; // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// -class LoadImm32< string instr_asm, Operand Od, RegisterClass RC> : - MipsAsmPseudoInst<(outs RC:$rt), (ins Od:$imm32), +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,CPURegs>; +def LoadImm32Reg : LoadImm32<"li", shamt,CPURegsOpnd>; -class LoadAddress : - MipsAsmPseudoInst<(outs RC:$rt), (ins MemOpnd:$addr), +class LoadAddress : + MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(instr_asm, "\t$rt, $addr")> ; -def LoadAddr32Reg : LoadAddress<"la", mem, CPURegs>; +def LoadAddr32Reg : LoadAddress<"la", mem, CPURegsOpnd>; -class LoadAddressImm : - MipsAsmPseudoInst<(outs RC:$rt), (ins Od:$imm32), +class LoadAddressImm : + MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddr32Imm : LoadAddressImm<"la", shamt,CPURegs>; +def LoadAddr32Imm : LoadAddressImm<"la", shamt,CPURegsOpnd>; @@ -1045,7 +1048,7 @@ def : WrapperPat; // Mips does not have "not", so we expand our way def : MipsPat<(not CPURegs:$in), - (NOR CPURegs:$in, ZERO)>; + (NOR CPURegsOpnd:$in, ZERO)>; // extended loads let Predicates = [NotN64, HasStdEnc] in { diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index f07a10c3dd..c6eb0e1e87 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -331,3 +331,48 @@ def HWRegs64 : RegisterClass<"Mips", [i64], 32, (add HWR29_64)>; // Accumulator Registers def ACRegs : RegisterClass<"Mips", [i64], 64, (sequence "AC%u", 0, 3)>; + +def CPURegsAsmOperand : AsmOperandClass { + let Name = "CPURegsAsm"; + let ParserMethod = "parseCPURegs"; +} + +def CPU64RegsAsmOperand : AsmOperandClass { + let Name = "CPU64RegsAsm"; + let ParserMethod = "parseCPU64Regs"; +} + +def CCRAsmOperand : AsmOperandClass { + let Name = "CCRAsm"; + let ParserMethod = "parseCCRRegs"; +} + +def CPURegsOpnd : RegisterOperand { + let ParserMatchClass = CPURegsAsmOperand; +} + +def CPU64RegsOpnd : RegisterOperand { + let ParserMatchClass = CPU64RegsAsmOperand; +} + +def CCROpnd : RegisterOperand { + let ParserMatchClass = CCRAsmOperand; +} + +def HWRegsAsmOperand : AsmOperandClass { + let Name = "HWRegsAsm"; + let ParserMethod = "parseHWRegs"; +} + +def HW64RegsAsmOperand : AsmOperandClass { + let Name = "HW64RegsAsm"; + let ParserMethod = "parseHW64Regs"; +} + +def HWRegsOpnd : RegisterOperand { + let ParserMatchClass = HWRegsAsmOperand; +} + +def HW64RegsOpnd : RegisterOperand { + let ParserMatchClass = HW64RegsAsmOperand; +} diff --git a/test/MC/Mips/mips-alu-instructions.s b/test/MC/Mips/mips-alu-instructions.s index 2997782cd0..ee2a9a0db4 100644 --- a/test/MC/Mips/mips-alu-instructions.s +++ b/test/MC/Mips/mips-alu-instructions.s @@ -80,7 +80,7 @@ # CHECK: subu $4, $3, $5 # encoding: [0x23,0x20,0x65,0x00] # CHECK: sub $6, $zero, $7 # encoding: [0x22,0x30,0x07,0x00] # CHECK: subu $6, $zero, $7 # encoding: [0x23,0x30,0x07,0x00] -# CHECK: add $7, $8, $zero # encoding: [0x20,0x38,0x00,0x01] +# CHECK: addu $7, $8, $zero # encoding: [0x21,0x38,0x00,0x01] add $9,$6,$7 add $9,$6,17767 addu $9,$6,-15001 diff --git a/test/MC/Mips/mips64-alu-instructions.s b/test/MC/Mips/mips64-alu-instructions.s new file mode 100644 index 0000000000..a77ed43ff1 --- /dev/null +++ b/test/MC/Mips/mips64-alu-instructions.s @@ -0,0 +1,94 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips64r2 | FileCheck %s +# Check that the assembler can handle the documented syntax +# for arithmetic and logical instructions. +# CHECK: .section __TEXT,__text,regular,pure_instructions +#------------------------------------------------------------------------------ +# Logical instructions +#------------------------------------------------------------------------------ +# CHECK: and $9, $6, $7 # encoding: [0x24,0x48,0xc7,0x00] +# CHECK: andi $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x30] +# CHECK: andi $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x30] +# CHECK: clo $6, $7 # encoding: [0x21,0x30,0xe6,0x70] +# CHECK: clz $6, $7 # encoding: [0x20,0x30,0xe6,0x70] +# CHECK: ins $19, $9, 6, 7 # encoding: [0x84,0x61,0x33,0x7d] +# CHECK: nor $9, $6, $7 # encoding: [0x27,0x48,0xc7,0x00] +# CHECK: or $3, $3, $5 # encoding: [0x25,0x18,0x65,0x00] +# CHECK: ori $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x34] +# CHECK: rotr $9, $6, 7 # encoding: [0xc2,0x49,0x26,0x00] +# CHECK: rotrv $9, $6, $7 # encoding: [0x46,0x48,0xe6,0x00] +# CHECK: sll $4, $3, 7 # encoding: [0xc0,0x21,0x03,0x00] +# CHECK: sllv $2, $3, $5 # encoding: [0x04,0x10,0xa3,0x00] +# CHECK: slt $3, $3, $5 # encoding: [0x2a,0x18,0x65,0x00] +# CHECK: slti $3, $3, 103 # encoding: [0x67,0x00,0x63,0x28] +# CHECK: slti $3, $3, 103 # encoding: [0x67,0x00,0x63,0x28] +# CHECK: sltiu $3, $3, 103 # encoding: [0x67,0x00,0x63,0x2c] +# CHECK: sltu $3, $3, $5 # encoding: [0x2b,0x18,0x65,0x00] +# CHECK: sra $4, $3, 7 # encoding: [0xc3,0x21,0x03,0x00] +# CHECK: srav $2, $3, $5 # encoding: [0x07,0x10,0xa3,0x00] +# CHECK: srl $4, $3, 7 # encoding: [0xc2,0x21,0x03,0x00] +# CHECK: srlv $2, $3, $5 # encoding: [0x06,0x10,0xa3,0x00] +# CHECK: xor $3, $3, $5 # encoding: [0x26,0x18,0x65,0x00] +# CHECK: xori $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x38] +# CHECK: xori $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x38] +# CHECK: wsbh $6, $7 # encoding: [0xa0,0x30,0x07,0x7c] +# CHECK: nor $7, $8, $zero # encoding: [0x27,0x38,0x00,0x01] + and $9, $6, $7 + and $9, $6, 17767 + andi $9, $6, 17767 + clo $6, $7 + clz $6, $7 + ins $19, $9, 6,7 + nor $9, $6, $7 + or $3, $3, $5 + ori $9, $6, 17767 + rotr $9, $6, 7 + rotrv $9, $6, $7 + sll $4, $3, 7 + sllv $2, $3, $5 + slt $3, $3, $5 + slt $3, $3, 103 + slti $3, $3, 103 + sltiu $3, $3, 103 + sltu $3, $3, $5 + sra $4, $3, 7 + srav $2, $3, $5 + srl $4, $3, 7 + srlv $2, $3, $5 + xor $3, $3, $5 + xor $9, $6, 17767 + xori $9, $6, 17767 + wsbh $6, $7 + not $7 ,$8 + +#------------------------------------------------------------------------------ +# Arithmetic instructions +#------------------------------------------------------------------------------ + +# CHECK: dadd $9, $6, $7 # encoding: [0x2c,0x48,0xc7,0x00] +# CHECK: daddi $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x60] +# CHECK: daddiu $9, $6, -15001 # encoding: [0x67,0xc5,0xc9,0x64] +# CHECK: daddi $9, $6, 17767 # encoding: [0x67,0x45,0xc9,0x60] +# CHECK: daddiu $9, $6, -15001 # encoding: [0x67,0xc5,0xc9,0x64] +# CHECK: daddu $9, $6, $7 # encoding: [0x2d,0x48,0xc7,0x00] +# CHECK: madd $6, $7 # encoding: [0x00,0x00,0xc7,0x70] +# CHECK: maddu $6, $7 # encoding: [0x01,0x00,0xc7,0x70] +# CHECK: msub $6, $7 # encoding: [0x04,0x00,0xc7,0x70] +# CHECK: msubu $6, $7 # encoding: [0x05,0x00,0xc7,0x70] +# CHECK: mult $3, $5 # encoding: [0x18,0x00,0x65,0x00] +# CHECK: multu $3, $5 # encoding: [0x19,0x00,0x65,0x00] +# CHECK: dsubu $4, $3, $5 # encoding: [0x2f,0x20,0x65,0x00] +# CHECK: daddu $7, $8, $zero # encoding: [0x2d,0x38,0x00,0x01] + dadd $9,$6,$7 + dadd $9,$6,17767 + daddu $9,$6,-15001 + daddi $9,$6,17767 + daddiu $9,$6,-15001 + daddu $9,$6,$7 + madd $6,$7 + maddu $6,$7 + msub $6,$7 + msubu $6,$7 + mult $3,$5 + multu $3,$5 + dsubu $4,$3,$5 + move $7,$8 -- cgit v1.2.3