forked from OSchip/llvm-project
[mips][microMIPS] Fix the definition of MOVEP instruction
The patch fixes definition of MOVEP instruction. Two registers are used instead of register pairs. This is necessary as machine verifier cannot handle register pairs. Patch by Milena Vujosevic Janicic. Differential revision: https://reviews.llvm.org/D52035 llvm-svn: 342571
This commit is contained in:
parent
241c33bca7
commit
852dd83be8
|
@ -195,7 +195,6 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||||
OperandMatchResultTy parseImm(OperandVector &Operands);
|
OperandMatchResultTy parseImm(OperandVector &Operands);
|
||||||
OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
|
OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
|
||||||
OperandMatchResultTy parseInvNum(OperandVector &Operands);
|
OperandMatchResultTy parseInvNum(OperandVector &Operands);
|
||||||
OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
|
|
||||||
OperandMatchResultTy parseRegisterList(OperandVector &Operands);
|
OperandMatchResultTy parseRegisterList(OperandVector &Operands);
|
||||||
|
|
||||||
bool searchSymbolAlias(OperandVector &Operands);
|
bool searchSymbolAlias(OperandVector &Operands);
|
||||||
|
@ -760,7 +759,6 @@ private:
|
||||||
k_RegisterIndex, /// A register index in one or more RegKind.
|
k_RegisterIndex, /// A register index in one or more RegKind.
|
||||||
k_Token, /// A simple token
|
k_Token, /// A simple token
|
||||||
k_RegList, /// A physical register list
|
k_RegList, /// A physical register list
|
||||||
k_RegPair /// A pair of physical register
|
|
||||||
} Kind;
|
} Kind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -778,7 +776,6 @@ public:
|
||||||
delete RegList.List;
|
delete RegList.List;
|
||||||
case k_RegisterIndex:
|
case k_RegisterIndex:
|
||||||
case k_Token:
|
case k_Token:
|
||||||
case k_RegPair:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1038,6 +1035,17 @@ public:
|
||||||
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
|
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
|
||||||
|
unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
|
||||||
|
}
|
||||||
|
|
||||||
/// Render the operand to an MCInst as a GPR64
|
/// Render the operand to an MCInst as a GPR64
|
||||||
/// Asserts if the wrong number of operands are requested, or the operand
|
/// Asserts if the wrong number of operands are requested, or the operand
|
||||||
/// is not a k_RegisterIndex compatible with RegKind_GPR
|
/// is not a k_RegisterIndex compatible with RegKind_GPR
|
||||||
|
@ -1217,29 +1225,6 @@ public:
|
||||||
Inst.addOperand(MCOperand::createReg(RegNo));
|
Inst.addOperand(MCOperand::createReg(RegNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addRegPairOperands(MCInst &Inst, unsigned N) const {
|
|
||||||
assert(N == 2 && "Invalid number of operands!");
|
|
||||||
assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
|
|
||||||
unsigned RegNo = getRegPair();
|
|
||||||
AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
|
|
||||||
Inst.addOperand(MCOperand::createReg(
|
|
||||||
RegIdx.RegInfo->getRegClass(
|
|
||||||
AsmParser.getABI().AreGprs64bit()
|
|
||||||
? Mips::GPR64RegClassID
|
|
||||||
: Mips::GPR32RegClassID).getRegister(RegNo++)));
|
|
||||||
Inst.addOperand(MCOperand::createReg(
|
|
||||||
RegIdx.RegInfo->getRegClass(
|
|
||||||
AsmParser.getABI().AreGprs64bit()
|
|
||||||
? Mips::GPR64RegClassID
|
|
||||||
: Mips::GPR32RegClassID).getRegister(RegNo)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
|
|
||||||
assert(N == 2 && "Invalid number of operands!");
|
|
||||||
for (auto RegNo : getRegList())
|
|
||||||
Inst.addOperand(MCOperand::createReg(RegNo));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isReg() const override {
|
bool isReg() const override {
|
||||||
// As a special case until we sort out the definition of div/divu, accept
|
// As a special case until we sort out the definition of div/divu, accept
|
||||||
// $0/$zero here so that MCK_ZERO works correctly.
|
// $0/$zero here so that MCK_ZERO works correctly.
|
||||||
|
@ -1406,34 +1391,6 @@ public:
|
||||||
|
|
||||||
bool isRegList() const { return Kind == k_RegList; }
|
bool isRegList() const { return Kind == k_RegList; }
|
||||||
|
|
||||||
bool isMovePRegPair() const {
|
|
||||||
if (Kind != k_RegList || RegList.List->size() != 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned R0 = RegList.List->front();
|
|
||||||
unsigned R1 = RegList.List->back();
|
|
||||||
|
|
||||||
if ((R0 == Mips::A1 && R1 == Mips::A2) ||
|
|
||||||
(R0 == Mips::A1 && R1 == Mips::A3) ||
|
|
||||||
(R0 == Mips::A2 && R1 == Mips::A3) ||
|
|
||||||
(R0 == Mips::A0 && R1 == Mips::S5) ||
|
|
||||||
(R0 == Mips::A0 && R1 == Mips::S6) ||
|
|
||||||
(R0 == Mips::A0 && R1 == Mips::A1) ||
|
|
||||||
(R0 == Mips::A0 && R1 == Mips::A2) ||
|
|
||||||
(R0 == Mips::A0 && R1 == Mips::A3) ||
|
|
||||||
(R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
|
|
||||||
(R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
|
|
||||||
(R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
|
|
||||||
(R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
|
|
||||||
(R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
|
|
||||||
(R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
|
|
||||||
(R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
|
|
||||||
(R0 == Mips::A0_64 && R1 == Mips::A3_64))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef getToken() const {
|
StringRef getToken() const {
|
||||||
assert(Kind == k_Token && "Invalid access!");
|
assert(Kind == k_Token && "Invalid access!");
|
||||||
return StringRef(Tok.Data, Tok.Length);
|
return StringRef(Tok.Data, Tok.Length);
|
||||||
|
@ -1481,11 +1438,6 @@ public:
|
||||||
return *(RegList.List);
|
return *(RegList.List);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getRegPair() const {
|
|
||||||
assert((Kind == k_RegPair) && "Invalid access!");
|
|
||||||
return RegIdx.Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
|
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
|
||||||
MipsAsmParser &Parser) {
|
MipsAsmParser &Parser) {
|
||||||
auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
|
auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
|
||||||
|
@ -1593,18 +1545,6 @@ public:
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
|
|
||||||
SMLoc S, SMLoc E,
|
|
||||||
MipsAsmParser &Parser) {
|
|
||||||
auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
|
|
||||||
Op->RegIdx.Index = MOP.RegIdx.Index;
|
|
||||||
Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
|
|
||||||
Op->RegIdx.Kind = MOP.RegIdx.Kind;
|
|
||||||
Op->StartLoc = S;
|
|
||||||
Op->EndLoc = E;
|
|
||||||
return Op;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGPRZeroAsmReg() const {
|
bool isGPRZeroAsmReg() const {
|
||||||
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
|
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
|
||||||
}
|
}
|
||||||
|
@ -1640,6 +1580,19 @@ public:
|
||||||
(RegIdx.Index >= 16 && RegIdx.Index <= 20));
|
(RegIdx.Index >= 16 && RegIdx.Index <= 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isMM16AsmRegMovePPairFirst() const {
|
||||||
|
if (!(isRegIdx() && RegIdx.Kind))
|
||||||
|
return false;
|
||||||
|
return RegIdx.Index >= 4 && RegIdx.Index <= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMM16AsmRegMovePPairSecond() const {
|
||||||
|
if (!(isRegIdx() && RegIdx.Kind))
|
||||||
|
return false;
|
||||||
|
return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
|
||||||
|
(RegIdx.Index >= 5 && RegIdx.Index <= 7));
|
||||||
|
}
|
||||||
|
|
||||||
bool isFGRAsmReg() const {
|
bool isFGRAsmReg() const {
|
||||||
// AFGR64 is $0-$15 but we handle this in getAFGR64()
|
// AFGR64 is $0-$15 but we handle this in getAFGR64()
|
||||||
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
|
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
|
||||||
|
@ -1720,9 +1673,6 @@ public:
|
||||||
OS << Reg << " ";
|
OS << Reg << " ";
|
||||||
OS << ">";
|
OS << ">";
|
||||||
break;
|
break;
|
||||||
case k_RegPair:
|
|
||||||
OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2288,6 +2238,22 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
||||||
if (Inst.getOperand(0).getReg() == Mips::RA)
|
if (Inst.getOperand(0).getReg() == Mips::RA)
|
||||||
return Error(IDLoc, "invalid operand for instruction");
|
return Error(IDLoc, "invalid operand for instruction");
|
||||||
break;
|
break;
|
||||||
|
case Mips::MOVEP_MM:
|
||||||
|
case Mips::MOVEP_MMR6: {
|
||||||
|
unsigned R0 = Inst.getOperand(0).getReg();
|
||||||
|
unsigned R1 = Inst.getOperand(1).getReg();
|
||||||
|
bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
|
||||||
|
(R0 == Mips::A1 && R1 == Mips::A3) ||
|
||||||
|
(R0 == Mips::A2 && R1 == Mips::A3) ||
|
||||||
|
(R0 == Mips::A0 && R1 == Mips::S5) ||
|
||||||
|
(R0 == Mips::A0 && R1 == Mips::S6) ||
|
||||||
|
(R0 == Mips::A0 && R1 == Mips::A1) ||
|
||||||
|
(R0 == Mips::A0 && R1 == Mips::A2) ||
|
||||||
|
(R0 == Mips::A0 && R1 == Mips::A3));
|
||||||
|
if (!RegPair)
|
||||||
|
return Error(IDLoc, "invalid operand for instruction");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6278,45 +6244,6 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) {
|
||||||
return MatchOperand_Success;
|
return MatchOperand_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
OperandMatchResultTy
|
|
||||||
MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
|
|
||||||
MCAsmParser &Parser = getParser();
|
|
||||||
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
|
|
||||||
SmallVector<unsigned, 10> Regs;
|
|
||||||
|
|
||||||
if (Parser.getTok().isNot(AsmToken::Dollar))
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
|
|
||||||
SMLoc S = Parser.getTok().getLoc();
|
|
||||||
|
|
||||||
if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
|
|
||||||
MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
|
|
||||||
unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
|
|
||||||
Regs.push_back(RegNo);
|
|
||||||
|
|
||||||
SMLoc E = Parser.getTok().getLoc();
|
|
||||||
if (Parser.getTok().isNot(AsmToken::Comma)) {
|
|
||||||
Error(E, "',' expected");
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove comma.
|
|
||||||
Parser.Lex();
|
|
||||||
|
|
||||||
if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
|
|
||||||
return MatchOperand_ParseFail;
|
|
||||||
|
|
||||||
Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
|
|
||||||
RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
|
|
||||||
Regs.push_back(RegNo);
|
|
||||||
|
|
||||||
Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
|
|
||||||
|
|
||||||
return MatchOperand_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
|
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
|
||||||
/// either this.
|
/// either this.
|
||||||
/// ::= '(', register, ')'
|
/// ::= '(', register, ')'
|
||||||
|
|
|
@ -538,6 +538,9 @@ static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
|
||||||
uint64_t Address,
|
uint64_t Address,
|
||||||
const void *Decoder);
|
const void *Decoder);
|
||||||
|
|
||||||
|
static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
|
||||||
|
uint64_t Address, const void *Decoder);
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
Target &getTheMipselTarget();
|
Target &getTheMipselTarget();
|
||||||
|
@ -2450,6 +2453,32 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
|
||||||
return MCDisassembler::Success;
|
return MCDisassembler::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
|
||||||
|
uint64_t Address,
|
||||||
|
const void *Decoder) {
|
||||||
|
unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
|
||||||
|
if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
|
||||||
|
MCDisassembler::Fail)
|
||||||
|
return MCDisassembler::Fail;
|
||||||
|
|
||||||
|
unsigned RegRs;
|
||||||
|
if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
|
||||||
|
RegRs = fieldFromInstruction(Insn, 0, 2) |
|
||||||
|
(fieldFromInstruction(Insn, 3, 1) << 2);
|
||||||
|
else
|
||||||
|
RegRs = fieldFromInstruction(Insn, 1, 3);
|
||||||
|
if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
|
||||||
|
MCDisassembler::Fail)
|
||||||
|
return MCDisassembler::Fail;
|
||||||
|
|
||||||
|
unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
|
||||||
|
if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
|
||||||
|
MCDisassembler::Fail)
|
||||||
|
return MCDisassembler::Fail;
|
||||||
|
|
||||||
|
return MCDisassembler::Success;
|
||||||
|
}
|
||||||
|
|
||||||
static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
|
static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
|
||||||
uint64_t Address, const void *Decoder) {
|
uint64_t Address, const void *Decoder) {
|
||||||
switch (RegPair) {
|
switch (RegPair) {
|
||||||
|
|
|
@ -213,6 +213,12 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||||
TmpInst.setOpcode (NewOpcode);
|
TmpInst.setOpcode (NewOpcode);
|
||||||
Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
|
Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (((MI.getOpcode() == Mips::MOVEP_MM) ||
|
||||||
|
(MI.getOpcode() == Mips::MOVEP_MMR6))) {
|
||||||
|
unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI);
|
||||||
|
Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
|
const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
|
||||||
|
|
|
@ -1101,7 +1101,9 @@ class BREAK16_MMR6_DESC : BrkSdbbp16MM<"break16", II_BREAK>, MMR6Arch<"break16">
|
||||||
class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
|
class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
|
||||||
MMR6Arch<"li16">, IsAsCheapAsAMove;
|
MMR6Arch<"li16">, IsAsCheapAsAMove;
|
||||||
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">;
|
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">;
|
||||||
class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMoveP>, MMR6Arch<"movep">;
|
class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
|
||||||
|
GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
|
||||||
|
MMR6Arch<"movep">;
|
||||||
class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">;
|
class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">;
|
||||||
class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
|
class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
|
||||||
MMR6Arch<"subu16"> {
|
MMR6Arch<"subu16"> {
|
||||||
|
|
|
@ -231,27 +231,14 @@ class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
|
||||||
bit mayStore = 1;
|
bit mayStore = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A register pair used by movep instruction.
|
class MovePMM16<string opstr, RegisterOperand RO1, RegisterOperand RO2,
|
||||||
def MovePRegPairAsmOperand : AsmOperandClass {
|
RegisterOperand RO3> :
|
||||||
let Name = "MovePRegPair";
|
MicroMipsInst16<(outs RO1:$rd1, RO2:$rd2), (ins RO3:$rs, RO3:$rt),
|
||||||
let ParserMethod = "parseMovePRegPair";
|
!strconcat(opstr, "\t$rd1, $rd2, $rs, $rt"), [],
|
||||||
let PredicateMethod = "isMovePRegPair";
|
|
||||||
}
|
|
||||||
|
|
||||||
def movep_regpair : Operand<i32> {
|
|
||||||
let EncoderMethod = "getMovePRegPairOpValue";
|
|
||||||
let ParserMatchClass = MovePRegPairAsmOperand;
|
|
||||||
let PrintMethod = "printRegisterList";
|
|
||||||
let DecoderMethod = "DecodeMovePRegPair";
|
|
||||||
let MIOperandInfo = (ops ptr_rc, ptr_rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
class MovePMM16<string opstr, RegisterOperand RO> :
|
|
||||||
MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt),
|
|
||||||
!strconcat(opstr, "\t$dst_regs, $rs, $rt"), [],
|
|
||||||
NoItinerary, FrmR> {
|
NoItinerary, FrmR> {
|
||||||
let isReMaterializable = 1;
|
let isReMaterializable = 1;
|
||||||
let isMoveReg = 1;
|
let isMoveReg = 1;
|
||||||
|
let DecoderMethod = "DecodeMovePOperands";
|
||||||
}
|
}
|
||||||
|
|
||||||
class StorePairMM<string opstr, ComplexPattern Addr = addr>
|
class StorePairMM<string opstr, ComplexPattern Addr = addr>
|
||||||
|
@ -682,8 +669,9 @@ def MFLO16_MM : MoveFromHILOMM<"mflo16", GPR32Opnd, AC0>,
|
||||||
MFHILO_FM_MM16<0x12>, ISA_MICROMIPS32_NOT_MIPS32R6;
|
MFHILO_FM_MM16<0x12>, ISA_MICROMIPS32_NOT_MIPS32R6;
|
||||||
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>,
|
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>,
|
||||||
ISA_MICROMIPS32_NOT_MIPS32R6;
|
ISA_MICROMIPS32_NOT_MIPS32R6;
|
||||||
def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16,
|
def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
|
||||||
ISA_MICROMIPS32_NOT_MIPS32R6;
|
GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
|
||||||
|
MOVEP_FM_MM16, ISA_MICROMIPS32_NOT_MIPS32R6;
|
||||||
def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
|
def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
|
||||||
IsAsCheapAsAMove, ISA_MICROMIPS32_NOT_MIPS32R6;
|
IsAsCheapAsAMove, ISA_MICROMIPS32_NOT_MIPS32R6;
|
||||||
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
|
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
|
||||||
|
|
|
@ -57,7 +57,10 @@ const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
|
||||||
switch (RC.getID()) {
|
switch (RC.getID()) {
|
||||||
case Mips::GPR32RegClassID:
|
case Mips::GPR32RegClassID:
|
||||||
case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
|
case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
|
||||||
|
case Mips::GPRMM16MovePPairFirstRegClassID:
|
||||||
|
case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
|
||||||
case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
|
case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
|
||||||
|
case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
|
||||||
case Mips::SP32RegClassID:
|
case Mips::SP32RegClassID:
|
||||||
return getRegBank(Mips::GPRBRegBankID);
|
return getRegBank(Mips::GPRBRegBankID);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -335,6 +335,16 @@ def GPRMM16MoveP : RegisterClass<"Mips", [i32], 32, (add
|
||||||
// Callee save
|
// Callee save
|
||||||
S0, S2, S3, S4)>;
|
S0, S2, S3, S4)>;
|
||||||
|
|
||||||
|
def GPRMM16MovePPairFirst : RegisterClass<"Mips", [i32], 32, (add
|
||||||
|
// Arguments
|
||||||
|
A0, A1, A2)>;
|
||||||
|
|
||||||
|
def GPRMM16MovePPairSecond : RegisterClass<"Mips", [i32], 32, (add
|
||||||
|
// Arguments
|
||||||
|
A1, A2, A3,
|
||||||
|
// Callee save
|
||||||
|
S5, S6)>;
|
||||||
|
|
||||||
def GPR64 : RegisterClass<"Mips", [i64], 64, (add
|
def GPR64 : RegisterClass<"Mips", [i64], 64, (add
|
||||||
// Reserved
|
// Reserved
|
||||||
ZERO_64, AT_64,
|
ZERO_64, AT_64,
|
||||||
|
@ -522,6 +532,16 @@ def GPRMM16AsmOperandMoveP : MipsAsmRegOperand {
|
||||||
let PredicateMethod = "isMM16AsmRegMoveP";
|
let PredicateMethod = "isMM16AsmRegMoveP";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def GPRMM16AsmOperandMovePPairFirst : MipsAsmRegOperand {
|
||||||
|
let Name = "GPRMM16AsmRegMovePPairFirst";
|
||||||
|
let PredicateMethod = "isMM16AsmRegMovePPairFirst";
|
||||||
|
}
|
||||||
|
|
||||||
|
def GPRMM16AsmOperandMovePPairSecond : MipsAsmRegOperand {
|
||||||
|
let Name = "GPRMM16AsmRegMovePPairSecond";
|
||||||
|
let PredicateMethod = "isMM16AsmRegMovePPairSecond";
|
||||||
|
}
|
||||||
|
|
||||||
def ACC64DSPAsmOperand : MipsAsmRegOperand {
|
def ACC64DSPAsmOperand : MipsAsmRegOperand {
|
||||||
let Name = "ACC64DSPAsmReg";
|
let Name = "ACC64DSPAsmReg";
|
||||||
let PredicateMethod = "isACCAsmReg";
|
let PredicateMethod = "isACCAsmReg";
|
||||||
|
@ -613,6 +633,14 @@ def GPRMM16OpndMoveP : RegisterOperand<GPRMM16MoveP> {
|
||||||
let EncoderMethod = "getMovePRegSingleOpValue";
|
let EncoderMethod = "getMovePRegSingleOpValue";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def GPRMM16OpndMovePPairFirst : RegisterOperand<GPRMM16MovePPairFirst> {
|
||||||
|
let ParserMatchClass = GPRMM16AsmOperandMovePPairFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
def GPRMM16OpndMovePPairSecond : RegisterOperand<GPRMM16MovePPairSecond> {
|
||||||
|
let ParserMatchClass = GPRMM16AsmOperandMovePPairSecond;
|
||||||
|
}
|
||||||
|
|
||||||
def GPR64Opnd : RegisterOperand<GPR64> {
|
def GPR64Opnd : RegisterOperand<GPR64> {
|
||||||
let ParserMatchClass = GPR64AsmOperand;
|
let ParserMatchClass = GPR64AsmOperand;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue