llvm.org GIT mirror llvm / bb017fb
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342571 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Atanasyan 1 year, 9 months ago
7 changed file(s) with 117 addition(s) and 134 deletion(s). Raw diff Collapse all Expand all
194194 OperandMatchResultTy parseImm(OperandVector &Operands);
195195 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
196196 OperandMatchResultTy parseInvNum(OperandVector &Operands);
197 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
198197 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
199198
200199 bool searchSymbolAlias(OperandVector &Operands);
759758 k_RegisterIndex, /// A register index in one or more RegKind.
760759 k_Token, /// A simple token
761760 k_RegList, /// A physical register list
762 k_RegPair /// A pair of physical register
763761 } Kind;
764762
765763 public:
777775 delete RegList.List;
778776 case k_RegisterIndex:
779777 case k_Token:
780 case k_RegPair:
781778 break;
782779 }
783780 }
10371034 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
10381035 }
10391036
1037 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1040 }
1041
1042 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1043 unsigned N) const {
1044 assert(N == 1 && "Invalid number of operands!");
1045 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1046 }
1047
10401048 /// Render the operand to an MCInst as a GPR64
10411049 /// Asserts if the wrong number of operands are requested, or the operand
10421050 /// is not a k_RegisterIndex compatible with RegKind_GPR
12161224 Inst.addOperand(MCOperand::createReg(RegNo));
12171225 }
12181226
1219 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1220 assert(N == 2 && "Invalid number of operands!");
1221 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1222 unsigned RegNo = getRegPair();
1223 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1224 Inst.addOperand(MCOperand::createReg(
1225 RegIdx.RegInfo->getRegClass(
1226 AsmParser.getABI().AreGprs64bit()
1227 ? Mips::GPR64RegClassID
1228 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1229 Inst.addOperand(MCOperand::createReg(
1230 RegIdx.RegInfo->getRegClass(
1231 AsmParser.getABI().AreGprs64bit()
1232 ? Mips::GPR64RegClassID
1233 : Mips::GPR32RegClassID).getRegister(RegNo)));
1234 }
1235
1236 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1237 assert(N == 2 && "Invalid number of operands!");
1238 for (auto RegNo : getRegList())
1239 Inst.addOperand(MCOperand::createReg(RegNo));
1240 }
1241
12421227 bool isReg() const override {
12431228 // As a special case until we sort out the definition of div/divu, accept
12441229 // $0/$zero here so that MCK_ZERO works correctly.
14051390
14061391 bool isRegList() const { return Kind == k_RegList; }
14071392
1408 bool isMovePRegPair() const {
1409 if (Kind != k_RegList || RegList.List->size() != 2)
1410 return false;
1411
1412 unsigned R0 = RegList.List->front();
1413 unsigned R1 = RegList.List->back();
1414
1415 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1416 (R0 == Mips::A1 && R1 == Mips::A3) ||
1417 (R0 == Mips::A2 && R1 == Mips::A3) ||
1418 (R0 == Mips::A0 && R1 == Mips::S5) ||
1419 (R0 == Mips::A0 && R1 == Mips::S6) ||
1420 (R0 == Mips::A0 && R1 == Mips::A1) ||
1421 (R0 == Mips::A0 && R1 == Mips::A2) ||
1422 (R0 == Mips::A0 && R1 == Mips::A3) ||
1423 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1424 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1425 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1426 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1427 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1428 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1429 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1430 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1431 return true;
1432
1433 return false;
1434 }
1435
14361393 StringRef getToken() const {
14371394 assert(Kind == k_Token && "Invalid access!");
14381395 return StringRef(Tok.Data, Tok.Length);
14781435 const SmallVectorImpl &getRegList() const {
14791436 assert((Kind == k_RegList) && "Invalid access!");
14801437 return *(RegList.List);
1481 }
1482
1483 unsigned getRegPair() const {
1484 assert((Kind == k_RegPair) && "Invalid access!");
1485 return RegIdx.Index;
14861438 }
14871439
14881440 static std::unique_ptr CreateToken(StringRef Str, SMLoc S,
15921544 return Op;
15931545 }
15941546
1595 static std::unique_ptr CreateRegPair(const MipsOperand &MOP,
1596 SMLoc S, SMLoc E,
1597 MipsAsmParser &Parser) {
1598 auto Op = llvm::make_unique(k_RegPair, Parser);
1599 Op->RegIdx.Index = MOP.RegIdx.Index;
1600 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1601 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1602 Op->StartLoc = S;
1603 Op->EndLoc = E;
1604 return Op;
1605 }
1606
16071547 bool isGPRZeroAsmReg() const {
16081548 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
16091549 }
16371577 return false;
16381578 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
16391579 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1580 }
1581
1582 bool isMM16AsmRegMovePPairFirst() const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1584 return false;
1585 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1586 }
1587
1588 bool isMM16AsmRegMovePPairSecond() const {
1589 if (!(isRegIdx() && RegIdx.Kind))
1590 return false;
1591 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1592 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
16401593 }
16411594
16421595 bool isFGRAsmReg() const {
17181671 for (auto Reg : (*RegList.List))
17191672 OS << Reg << " ";
17201673 OS << ">";
1721 break;
1722 case k_RegPair:
1723 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
17241674 break;
17251675 }
17261676 }
22872237 if (Inst.getOperand(0).getReg() == Mips::RA)
22882238 return Error(IDLoc, "invalid operand for instruction");
22892239 break;
2240 case Mips::MOVEP_MM:
2241 case Mips::MOVEP_MMR6: {
2242 unsigned R0 = Inst.getOperand(0).getReg();
2243 unsigned R1 = Inst.getOperand(1).getReg();
2244 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2245 (R0 == Mips::A1 && R1 == Mips::A3) ||
2246 (R0 == Mips::A2 && R1 == Mips::A3) ||
2247 (R0 == Mips::A0 && R1 == Mips::S5) ||
2248 (R0 == Mips::A0 && R1 == Mips::S6) ||
2249 (R0 == Mips::A0 && R1 == Mips::A1) ||
2250 (R0 == Mips::A0 && R1 == Mips::A2) ||
2251 (R0 == Mips::A0 && R1 == Mips::A3));
2252 if (!RegPair)
2253 return Error(IDLoc, "invalid operand for instruction");
2254 break;
2255 }
22902256 }
22912257 }
22922258
62776243 return MatchOperand_Success;
62786244 }
62796245
6280 OperandMatchResultTy
6281 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
6282 MCAsmParser &Parser = getParser();
6283 SmallVector, 8> TmpOperands;
6284 SmallVector Regs;
6285
6286 if (Parser.getTok().isNot(AsmToken::Dollar))
6287 return MatchOperand_ParseFail;
6288
6289 SMLoc S = Parser.getTok().getLoc();
6290
6291 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6292 return MatchOperand_ParseFail;
6293
6294 MipsOperand *Reg = &static_cast(*TmpOperands.back());
6295 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6296 Regs.push_back(RegNo);
6297
6298 SMLoc E = Parser.getTok().getLoc();
6299 if (Parser.getTok().isNot(AsmToken::Comma)) {
6300 Error(E, "',' expected");
6301 return MatchOperand_ParseFail;
6302 }
6303
6304 // Remove comma.
6305 Parser.Lex();
6306
6307 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6308 return MatchOperand_ParseFail;
6309
6310 Reg = &static_cast(*TmpOperands.back());
6311 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6312 Regs.push_back(RegNo);
6313
6314 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6315
6316 return MatchOperand_Success;
6317 }
6318
63196246 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
63206247 /// either this.
63216248 /// ::= '(', register, ')'
536536 static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
537537 uint64_t Address,
538538 const void *Decoder);
539
540 static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
541 uint64_t Address, const void *Decoder);
539542
540543 namespace llvm {
541544
24452448 Inst.addOperand(MCOperand::createReg(Regs[i]));
24462449
24472450 Inst.addOperand(MCOperand::createReg(Mips::RA));
2451
2452 return MCDisassembler::Success;
2453 }
2454
2455 static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
2456 uint64_t Address,
2457 const void *Decoder) {
2458 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2459 if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
2460 MCDisassembler::Fail)
2461 return MCDisassembler::Fail;
2462
2463 unsigned RegRs;
2464 if (static_cast(Decoder)->hasMips32r6())
2465 RegRs = fieldFromInstruction(Insn, 0, 2) |
2466 (fieldFromInstruction(Insn, 3, 1) << 2);
2467 else
2468 RegRs = fieldFromInstruction(Insn, 1, 3);
2469 if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
2470 MCDisassembler::Fail)
2471 return MCDisassembler::Fail;
2472
2473 unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
2474 if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
2475 MCDisassembler::Fail)
2476 return MCDisassembler::Fail;
24482477
24492478 return MCDisassembler::Success;
24502479 }
212212 TmpInst.setOpcode (NewOpcode);
213213 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
214214 }
215
216 if (((MI.getOpcode() == Mips::MOVEP_MM) ||
217 (MI.getOpcode() == Mips::MOVEP_MMR6))) {
218 unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI);
219 Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
220 }
215221 }
216222
217223 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
11001100 class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
11011101 MMR6Arch<"li16">, IsAsCheapAsAMove;
11021102 class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">;
1103 class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMoveP>, MMR6Arch<"movep">;
1103 class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
1104 GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
1105 MMR6Arch<"movep">;
11041106 class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">;
11051107 class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
11061108 MMR6Arch<"subu16"> {
230230 bit mayStore = 1;
231231 }
232232
233 /// A register pair used by movep instruction.
234 def MovePRegPairAsmOperand : AsmOperandClass {
235 let Name = "MovePRegPair";
236 let ParserMethod = "parseMovePRegPair";
237 let PredicateMethod = "isMovePRegPair";
238 }
239
240 def movep_regpair : Operand {
241 let EncoderMethod = "getMovePRegPairOpValue";
242 let ParserMatchClass = MovePRegPairAsmOperand;
243 let PrintMethod = "printRegisterList";
244 let DecoderMethod = "DecodeMovePRegPair";
245 let MIOperandInfo = (ops ptr_rc, ptr_rc);
246 }
247
248 class MovePMM16 :
249 MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt),
250 !strconcat(opstr, "\t$dst_regs, $rs, $rt"), [],
233 class MovePMM16,
234 RegisterOperand RO3> :
235 MicroMipsInst16<(outs RO1:$rd1, RO2:$rd2), (ins RO3:$rs, RO3:$rt),
236 !strconcat(opstr, "\t$rd1, $rd2, $rs, $rt"), [],
251237 NoItinerary, FrmR> {
252238 let isReMaterializable = 1;
253239 let isMoveReg = 1;
240 let DecoderMethod = "DecodeMovePOperands";
254241 }
255242
256243 class StorePairMM
681668 MFHILO_FM_MM16<0x12>, ISA_MICROMIPS32_NOT_MIPS32R6;
682669 def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>,
683670 ISA_MICROMIPS32_NOT_MIPS32R6;
684 def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16,
685 ISA_MICROMIPS32_NOT_MIPS32R6;
671 def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
672 GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
673 MOVEP_FM_MM16, ISA_MICROMIPS32_NOT_MIPS32R6;
686674 def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
687675 IsAsCheapAsAMove, ISA_MICROMIPS32_NOT_MIPS32R6;
688676 def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
5656 switch (RC.getID()) {
5757 case Mips::GPR32RegClassID:
5858 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
59 case Mips::GPRMM16MovePPairFirstRegClassID:
60 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
5961 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
62 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
6063 case Mips::SP32RegClassID:
6164 return getRegBank(Mips::GPRBRegBankID);
6265 default:
334334 // Callee save
335335 S0, S2, S3, S4)>;
336336
337 def GPRMM16MovePPairFirst : RegisterClass<"Mips", [i32], 32, (add
338 // Arguments
339 A0, A1, A2)>;
340
341 def GPRMM16MovePPairSecond : RegisterClass<"Mips", [i32], 32, (add
342 // Arguments
343 A1, A2, A3,
344 // Callee save
345 S5, S6)>;
346
337347 def GPR64 : RegisterClass<"Mips", [i64], 64, (add
338348 // Reserved
339349 ZERO_64, AT_64,
521531 let PredicateMethod = "isMM16AsmRegMoveP";
522532 }
523533
534 def GPRMM16AsmOperandMovePPairFirst : MipsAsmRegOperand {
535 let Name = "GPRMM16AsmRegMovePPairFirst";
536 let PredicateMethod = "isMM16AsmRegMovePPairFirst";
537 }
538
539 def GPRMM16AsmOperandMovePPairSecond : MipsAsmRegOperand {
540 let Name = "GPRMM16AsmRegMovePPairSecond";
541 let PredicateMethod = "isMM16AsmRegMovePPairSecond";
542 }
543
524544 def ACC64DSPAsmOperand : MipsAsmRegOperand {
525545 let Name = "ACC64DSPAsmReg";
526546 let PredicateMethod = "isACCAsmReg";
610630 def GPRMM16OpndMoveP : RegisterOperand {
611631 let ParserMatchClass = GPRMM16AsmOperandMoveP;
612632 let EncoderMethod = "getMovePRegSingleOpValue";
633 }
634
635 def GPRMM16OpndMovePPairFirst : RegisterOperand {
636 let ParserMatchClass = GPRMM16AsmOperandMovePPairFirst;
637 }
638
639 def GPRMM16OpndMovePPairSecond : RegisterOperand {
640 let ParserMatchClass = GPRMM16AsmOperandMovePPairSecond;
613641 }
614642
615643 def GPR64Opnd : RegisterOperand {