1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsMCTargetDesc.h"
11 #include "MipsRegisterInfo.h"
12 #include "MipsTargetStreamer.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCParser/MCAsmLexer.h"
18 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCTargetAsmParser.h"
23 #include "llvm/Support/TargetRegistry.h"
24 #include "llvm/ADT/APInt.h"
33 class MipsAssemblerOptions {
35 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
37 unsigned getATRegNum() { return aTReg; }
38 bool setATReg(unsigned Reg);
40 bool isReorder() { return reorder; }
41 void setReorder() { reorder = true; }
42 void setNoreorder() { reorder = false; }
44 bool isMacro() { return macro; }
45 void setMacro() { macro = true; }
46 void setNomacro() { macro = false; }
56 class MipsAsmParser : public MCTargetAsmParser {
58 MipsTargetStreamer &getTargetStreamer() {
59 MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
60 return static_cast<MipsTargetStreamer &>(TS);
65 MipsAssemblerOptions Options;
66 bool hasConsumedDollar;
68 #define GET_ASSEMBLER_HEADER
69 #include "MipsGenAsmMatcher.inc"
71 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
72 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
73 MCStreamer &Out, unsigned &ErrorInfo,
74 bool MatchingInlineAsm);
76 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
78 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
80 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
82 bool ParseDirective(AsmToken DirectiveID);
84 MipsAsmParser::OperandMatchResultTy
85 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
87 MipsAsmParser::OperandMatchResultTy
88 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
90 MipsAsmParser::OperandMatchResultTy
91 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
94 MipsAsmParser::OperandMatchResultTy
95 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
97 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
100 MipsAsmParser::OperandMatchResultTy
101 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
103 MipsAsmParser::OperandMatchResultTy
104 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
106 MipsAsmParser::OperandMatchResultTy
107 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
109 MipsAsmParser::OperandMatchResultTy
110 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
112 MipsAsmParser::OperandMatchResultTy
113 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
115 MipsAsmParser::OperandMatchResultTy
116 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
118 MipsAsmParser::OperandMatchResultTy
119 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
121 MipsAsmParser::OperandMatchResultTy
122 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
124 MipsAsmParser::OperandMatchResultTy
125 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
127 MipsAsmParser::OperandMatchResultTy
128 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
130 MipsAsmParser::OperandMatchResultTy
131 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
133 MipsAsmParser::OperandMatchResultTy
134 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
136 MipsAsmParser::OperandMatchResultTy
137 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
139 MipsAsmParser::OperandMatchResultTy
140 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
148 MipsAsmParser::OperandMatchResultTy
149 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
151 MipsAsmParser::OperandMatchResultTy
152 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
154 MipsAsmParser::OperandMatchResultTy
155 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
157 MipsAsmParser::OperandMatchResultTy
158 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
160 MipsAsmParser::OperandMatchResultTy
161 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
163 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
166 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
169 int tryParseRegister(bool is64BitReg);
171 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
174 bool needsExpansion(MCInst &Inst);
176 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
178 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
180 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
182 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
184 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
187 bool reportParseError(StringRef ErrorMsg);
189 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
190 bool parseRelocOperand(const MCExpr *&Res);
192 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
194 bool isEvaluated(const MCExpr *Expr);
195 bool parseDirectiveSet();
196 bool parseDirectiveMipsHackStocg();
197 bool parseDirectiveMipsHackELFFlags();
199 bool parseSetAtDirective();
200 bool parseSetNoAtDirective();
201 bool parseSetMacroDirective();
202 bool parseSetNoMacroDirective();
203 bool parseSetReorderDirective();
204 bool parseSetNoReorderDirective();
206 bool parseSetAssignment();
208 bool parseDirectiveWord(unsigned Size, SMLoc L);
209 bool parseDirectiveGpWord();
211 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
213 bool isMips64() const {
214 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
217 bool isFP64() const {
218 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
221 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
223 int matchRegisterName(StringRef Symbol, bool is64BitReg);
225 int matchCPURegisterName(StringRef Symbol);
227 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
229 int matchFPURegisterName(StringRef Name);
231 int matchFCCRegisterName(StringRef Name);
233 int matchACRegisterName(StringRef Name);
235 int matchMSA128RegisterName(StringRef Name);
237 int matchMSA128CtrlRegisterName(StringRef Name);
239 int regKindToRegClass(int RegKind);
241 unsigned getReg(int RC, int RegNo);
245 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
246 SmallVectorImpl<MCInst> &Instructions);
248 // Helper function that checks if the value of a vector index is within the
249 // boundaries of accepted values for each RegisterKind
250 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
251 bool validateMSAIndex(int Val, int RegKind);
254 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
255 const MCInstrInfo &MII)
256 : MCTargetAsmParser(), STI(sti), Parser(parser),
257 hasConsumedDollar(false) {
258 // Initialize the set of available features.
259 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
262 MCAsmParser &getParser() const { return Parser; }
263 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
269 /// MipsOperand - Instances of this class represent a parsed Mips machine
271 class MipsOperand : public MCParsedAsmOperand {
309 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
337 SMLoc StartLoc, EndLoc;
340 void addRegOperands(MCInst &Inst, unsigned N) const {
341 assert(N == 1 && "Invalid number of operands!");
342 Inst.addOperand(MCOperand::CreateReg(getReg()));
345 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
346 assert(N == 1 && "Invalid number of operands!");
347 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
350 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
351 // Add as immediate when possible. Null MCExpr = 0.
353 Inst.addOperand(MCOperand::CreateImm(0));
354 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
355 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
357 Inst.addOperand(MCOperand::CreateExpr(Expr));
360 void addImmOperands(MCInst &Inst, unsigned N) const {
361 assert(N == 1 && "Invalid number of operands!");
362 const MCExpr *Expr = getImm();
366 void addMemOperands(MCInst &Inst, unsigned N) const {
367 assert(N == 2 && "Invalid number of operands!");
369 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
371 const MCExpr *Expr = getMemOff();
375 bool isReg() const { return Kind == k_Register; }
376 bool isImm() const { return Kind == k_Immediate; }
377 bool isToken() const { return Kind == k_Token; }
378 bool isMem() const { return Kind == k_Memory; }
379 bool isPtrReg() const { return Kind == k_PtrReg; }
380 bool isInvNum() const { return Kind == k_Immediate; }
381 bool isLSAImm() const { return Kind == k_LSAImm; }
383 StringRef getToken() const {
384 assert(Kind == k_Token && "Invalid access!");
385 return StringRef(Tok.Data, Tok.Length);
388 unsigned getReg() const {
389 assert((Kind == k_Register) && "Invalid access!");
393 unsigned getPtrReg() const {
394 assert((Kind == k_PtrReg) && "Invalid access!");
398 void setRegKind(RegisterKind RegKind) {
399 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
403 const MCExpr *getImm() const {
404 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
408 unsigned getMemBase() const {
409 assert((Kind == k_Memory) && "Invalid access!");
413 const MCExpr *getMemOff() const {
414 assert((Kind == k_Memory) && "Invalid access!");
418 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
419 MipsOperand *Op = new MipsOperand(k_Token);
420 Op->Tok.Data = Str.data();
421 Op->Tok.Length = Str.size();
427 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
428 MipsOperand *Op = new MipsOperand(k_Register);
429 Op->Reg.RegNum = RegNum;
435 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
436 MipsOperand *Op = new MipsOperand(k_PtrReg);
437 Op->Reg.RegNum = RegNum;
443 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
444 MipsOperand *Op = new MipsOperand(k_Immediate);
451 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
452 MipsOperand *Op = new MipsOperand(k_LSAImm);
459 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
461 MipsOperand *Op = new MipsOperand(k_Memory);
469 bool isGPR32Asm() const {
470 return Kind == k_Register && Reg.Kind == Kind_GPR32;
472 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
473 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
476 bool isGPR64Asm() const {
477 return Kind == k_Register && Reg.Kind == Kind_GPR64;
480 bool isHWRegsAsm() const {
481 assert((Kind == k_Register) && "Invalid access!");
482 return Reg.Kind == Kind_HWRegs;
485 bool isCCRAsm() const {
486 assert((Kind == k_Register) && "Invalid access!");
487 return Reg.Kind == Kind_CCRRegs;
490 bool isAFGR64Asm() const {
491 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
494 bool isFGR64Asm() const {
495 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
498 bool isFGR32Asm() const {
499 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
502 bool isFGRH32Asm() const {
503 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
506 bool isFCCRegsAsm() const {
507 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
510 bool isACC64DSPAsm() const {
511 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
514 bool isLO32DSPAsm() const {
515 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
518 bool isHI32DSPAsm() const {
519 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
522 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
524 bool isMSA128BAsm() const {
525 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
528 bool isMSA128HAsm() const {
529 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
532 bool isMSA128WAsm() const {
533 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
536 bool isMSA128DAsm() const {
537 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
540 bool isMSA128CRAsm() const {
541 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
544 /// getStartLoc - Get the location of the first token of this operand.
545 SMLoc getStartLoc() const { return StartLoc; }
546 /// getEndLoc - Get the location of the last token of this operand.
547 SMLoc getEndLoc() const { return EndLoc; }
549 virtual void print(raw_ostream &OS) const {
550 llvm_unreachable("unimplemented!");
552 }; // class MipsOperand
556 extern const MCInstrDesc MipsInsts[];
558 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
559 return MipsInsts[Opcode];
562 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
563 SmallVectorImpl<MCInst> &Instructions) {
564 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
566 if (MCID.hasDelaySlot() && Options.isReorder()) {
567 // If this instruction has a delay slot and .set reorder is active,
568 // emit a NOP after it.
569 Instructions.push_back(Inst);
571 NopInst.setOpcode(Mips::SLL);
572 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
573 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
574 NopInst.addOperand(MCOperand::CreateImm(0));
575 Instructions.push_back(NopInst);
579 if (MCID.mayLoad() || MCID.mayStore()) {
580 // Check the offset of memory operand, if it is a symbol
581 // reference or immediate we may have to expand instructions.
582 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
583 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
584 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
585 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
586 MCOperand &Op = Inst.getOperand(i);
588 int MemOffset = Op.getImm();
589 if (MemOffset < -32768 || MemOffset > 32767) {
590 // Offset can't exceed 16bit value.
591 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
594 } else if (Op.isExpr()) {
595 const MCExpr *Expr = Op.getExpr();
596 if (Expr->getKind() == MCExpr::SymbolRef) {
597 const MCSymbolRefExpr *SR =
598 static_cast<const MCSymbolRefExpr *>(Expr);
599 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
601 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
604 } else if (!isEvaluated(Expr)) {
605 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
613 if (needsExpansion(Inst))
614 expandInstruction(Inst, IDLoc, Instructions);
616 Instructions.push_back(Inst);
621 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
623 switch (Inst.getOpcode()) {
624 case Mips::LoadImm32Reg:
625 case Mips::LoadAddr32Imm:
626 case Mips::LoadAddr32Reg:
633 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
634 SmallVectorImpl<MCInst> &Instructions) {
635 switch (Inst.getOpcode()) {
636 case Mips::LoadImm32Reg:
637 return expandLoadImm(Inst, IDLoc, Instructions);
638 case Mips::LoadAddr32Imm:
639 return expandLoadAddressImm(Inst, IDLoc, Instructions);
640 case Mips::LoadAddr32Reg:
641 return expandLoadAddressReg(Inst, IDLoc, Instructions);
645 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
646 SmallVectorImpl<MCInst> &Instructions) {
648 const MCOperand &ImmOp = Inst.getOperand(1);
649 assert(ImmOp.isImm() && "expected immediate operand kind");
650 const MCOperand &RegOp = Inst.getOperand(0);
651 assert(RegOp.isReg() && "expected register operand kind");
653 int ImmValue = ImmOp.getImm();
654 tmpInst.setLoc(IDLoc);
655 if (0 <= ImmValue && ImmValue <= 65535) {
656 // For 0 <= j <= 65535.
657 // li d,j => ori d,$zero,j
658 tmpInst.setOpcode(Mips::ORi);
659 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
660 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
661 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
662 Instructions.push_back(tmpInst);
663 } else if (ImmValue < 0 && ImmValue >= -32768) {
664 // For -32768 <= j < 0.
665 // li d,j => addiu d,$zero,j
666 tmpInst.setOpcode(Mips::ADDiu);
667 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
668 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
669 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
670 Instructions.push_back(tmpInst);
672 // For any other value of j that is representable as a 32-bit integer.
673 // li d,j => lui d,hi16(j)
675 tmpInst.setOpcode(Mips::LUi);
676 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
677 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
678 Instructions.push_back(tmpInst);
680 tmpInst.setOpcode(Mips::ORi);
681 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
682 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
683 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
684 tmpInst.setLoc(IDLoc);
685 Instructions.push_back(tmpInst);
690 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
691 SmallVectorImpl<MCInst> &Instructions) {
693 const MCOperand &ImmOp = Inst.getOperand(2);
694 assert(ImmOp.isImm() && "expected immediate operand kind");
695 const MCOperand &SrcRegOp = Inst.getOperand(1);
696 assert(SrcRegOp.isReg() && "expected register operand kind");
697 const MCOperand &DstRegOp = Inst.getOperand(0);
698 assert(DstRegOp.isReg() && "expected register operand kind");
699 int ImmValue = ImmOp.getImm();
700 if (-32768 <= ImmValue && ImmValue <= 65535) {
701 // For -32768 <= j <= 65535.
702 // la d,j(s) => addiu d,s,j
703 tmpInst.setOpcode(Mips::ADDiu);
704 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
705 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
706 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
707 Instructions.push_back(tmpInst);
709 // For any other value of j that is representable as a 32-bit integer.
710 // la d,j(s) => lui d,hi16(j)
713 tmpInst.setOpcode(Mips::LUi);
714 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
715 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
716 Instructions.push_back(tmpInst);
718 tmpInst.setOpcode(Mips::ORi);
719 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
720 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
721 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
722 Instructions.push_back(tmpInst);
724 tmpInst.setOpcode(Mips::ADDu);
725 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
726 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
727 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
728 Instructions.push_back(tmpInst);
733 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
734 SmallVectorImpl<MCInst> &Instructions) {
736 const MCOperand &ImmOp = Inst.getOperand(1);
737 assert(ImmOp.isImm() && "expected immediate operand kind");
738 const MCOperand &RegOp = Inst.getOperand(0);
739 assert(RegOp.isReg() && "expected register operand kind");
740 int ImmValue = ImmOp.getImm();
741 if (-32768 <= ImmValue && ImmValue <= 65535) {
742 // For -32768 <= j <= 65535.
743 // la d,j => addiu d,$zero,j
744 tmpInst.setOpcode(Mips::ADDiu);
745 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
746 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
747 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
748 Instructions.push_back(tmpInst);
750 // For any other value of j that is representable as a 32-bit integer.
751 // la d,j => lui d,hi16(j)
753 tmpInst.setOpcode(Mips::LUi);
754 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
755 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
756 Instructions.push_back(tmpInst);
758 tmpInst.setOpcode(Mips::ORi);
759 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
760 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
761 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
762 Instructions.push_back(tmpInst);
766 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
767 SmallVectorImpl<MCInst> &Instructions,
768 bool isLoad, bool isImmOpnd) {
769 const MCSymbolRefExpr *SR;
771 unsigned ImmOffset, HiOffset, LoOffset;
772 const MCExpr *ExprOffset;
774 unsigned AtRegNum = getReg(
775 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
776 // 1st operand is either the source or destination register.
777 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
778 unsigned RegOpNum = Inst.getOperand(0).getReg();
779 // 2nd operand is the base register.
780 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
781 unsigned BaseRegNum = Inst.getOperand(1).getReg();
782 // 3rd operand is either an immediate or expression.
784 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
785 ImmOffset = Inst.getOperand(2).getImm();
786 LoOffset = ImmOffset & 0x0000ffff;
787 HiOffset = (ImmOffset & 0xffff0000) >> 16;
788 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
789 if (LoOffset & 0x8000)
792 ExprOffset = Inst.getOperand(2).getExpr();
793 // All instructions will have the same location.
794 TempInst.setLoc(IDLoc);
795 // 1st instruction in expansion is LUi. For load instruction we can use
796 // the dst register as a temporary if base and dst are different,
797 // but for stores we must use $at.
798 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
799 TempInst.setOpcode(Mips::LUi);
800 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
802 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
804 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
805 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
806 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
807 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
809 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
811 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
812 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
815 // Add the instruction to the list.
816 Instructions.push_back(TempInst);
817 // Prepare TempInst for next instruction.
819 // Add temp register to base.
820 TempInst.setOpcode(Mips::ADDu);
821 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
822 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
823 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
824 Instructions.push_back(TempInst);
826 // And finaly, create original instruction with low part
827 // of offset and new base.
828 TempInst.setOpcode(Inst.getOpcode());
829 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
830 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
832 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
834 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
835 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
836 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
838 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
840 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
841 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
844 Instructions.push_back(TempInst);
848 bool MipsAsmParser::MatchAndEmitInstruction(
849 SMLoc IDLoc, unsigned &Opcode,
850 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
851 unsigned &ErrorInfo, bool MatchingInlineAsm) {
853 SmallVector<MCInst, 8> Instructions;
854 unsigned MatchResult =
855 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
857 switch (MatchResult) {
860 case Match_Success: {
861 if (processInstruction(Inst, IDLoc, Instructions))
863 for (unsigned i = 0; i < Instructions.size(); i++)
864 Out.EmitInstruction(Instructions[i]);
867 case Match_MissingFeature:
868 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
870 case Match_InvalidOperand: {
871 SMLoc ErrorLoc = IDLoc;
872 if (ErrorInfo != ~0U) {
873 if (ErrorInfo >= Operands.size())
874 return Error(IDLoc, "too few operands for instruction");
876 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
877 if (ErrorLoc == SMLoc())
881 return Error(ErrorLoc, "invalid operand for instruction");
883 case Match_MnemonicFail:
884 return Error(IDLoc, "invalid instruction");
889 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
895 CC = StringSwitch<unsigned>(Name)
929 // Although SGI documentation just cuts out t0-t3 for n32/n64,
930 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
931 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
932 if (isMips64() && 8 <= CC && CC <= 11)
935 if (CC == -1 && isMips64())
936 CC = StringSwitch<unsigned>(Name)
949 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
951 if (Name[0] == 'f') {
952 StringRef NumString = Name.substr(1);
954 if (NumString.getAsInteger(10, IntVal))
955 return -1; // This is not an integer.
956 if (IntVal > 31) // Maximum index for fpu register.
963 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
965 if (Name.startswith("fcc")) {
966 StringRef NumString = Name.substr(3);
968 if (NumString.getAsInteger(10, IntVal))
969 return -1; // This is not an integer.
970 if (IntVal > 7) // There are only 8 fcc registers.
977 int MipsAsmParser::matchACRegisterName(StringRef Name) {
979 if (Name.startswith("ac")) {
980 StringRef NumString = Name.substr(2);
982 if (NumString.getAsInteger(10, IntVal))
983 return -1; // This is not an integer.
984 if (IntVal > 3) // There are only 3 acc registers.
991 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
994 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1003 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1006 CC = StringSwitch<unsigned>(Name)
1009 .Case("msaaccess", 2)
1011 .Case("msamodify", 4)
1012 .Case("msarequest", 5)
1014 .Case("msaunmap", 7)
1020 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1023 CC = matchCPURegisterName(Name);
1025 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1026 : Mips::GPR32RegClassID);
1027 CC = matchFPURegisterName(Name);
1028 // TODO: decide about fpu register class
1030 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1031 : Mips::FGR32RegClassID);
1032 return matchMSA128RegisterName(Name);
1035 int MipsAsmParser::regKindToRegClass(int RegKind) {
1038 case MipsOperand::Kind_GPR32:
1039 return Mips::GPR32RegClassID;
1040 case MipsOperand::Kind_GPR64:
1041 return Mips::GPR64RegClassID;
1042 case MipsOperand::Kind_HWRegs:
1043 return Mips::HWRegsRegClassID;
1044 case MipsOperand::Kind_FGR32Regs:
1045 return Mips::FGR32RegClassID;
1046 case MipsOperand::Kind_FGRH32Regs:
1047 return Mips::FGRH32RegClassID;
1048 case MipsOperand::Kind_FGR64Regs:
1049 return Mips::FGR64RegClassID;
1050 case MipsOperand::Kind_AFGR64Regs:
1051 return Mips::AFGR64RegClassID;
1052 case MipsOperand::Kind_CCRRegs:
1053 return Mips::CCRRegClassID;
1054 case MipsOperand::Kind_ACC64DSP:
1055 return Mips::ACC64DSPRegClassID;
1056 case MipsOperand::Kind_FCCRegs:
1057 return Mips::FCCRegClassID;
1058 case MipsOperand::Kind_MSA128BRegs:
1059 return Mips::MSA128BRegClassID;
1060 case MipsOperand::Kind_MSA128HRegs:
1061 return Mips::MSA128HRegClassID;
1062 case MipsOperand::Kind_MSA128WRegs:
1063 return Mips::MSA128WRegClassID;
1064 case MipsOperand::Kind_MSA128DRegs:
1065 return Mips::MSA128DRegClassID;
1066 case MipsOperand::Kind_MSA128CtrlRegs:
1067 return Mips::MSACtrlRegClassID;
1073 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1081 int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
1083 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1084 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1087 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1089 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
1092 return getReg(RegClass, RegNum);
1095 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1096 const AsmToken &Tok = Parser.getTok();
1099 if (Tok.is(AsmToken::Identifier)) {
1100 std::string lowerCase = Tok.getString().lower();
1101 RegNum = matchRegisterName(lowerCase, is64BitReg);
1102 } else if (Tok.is(AsmToken::Integer))
1103 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1104 is64BitReg ? Mips::GPR64RegClassID
1105 : Mips::GPR32RegClassID);
1109 bool MipsAsmParser::tryParseRegisterOperand(
1110 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
1112 SMLoc S = Parser.getTok().getLoc();
1115 RegNo = tryParseRegister(is64BitReg);
1120 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1121 Parser.Lex(); // Eat register token.
1126 MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1127 StringRef Mnemonic) {
1128 // Check if the current operand has a custom associated parser, if so, try to
1129 // custom parse the operand, or fallback to the general approach.
1130 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1131 if (ResTy == MatchOperand_Success)
1133 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1134 // there was a match, but an error occurred, in which case, just return that
1135 // the operand parsing failed.
1136 if (ResTy == MatchOperand_ParseFail)
1139 switch (getLexer().getKind()) {
1141 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1143 case AsmToken::Dollar: {
1144 // Parse the register.
1145 SMLoc S = Parser.getTok().getLoc();
1146 Parser.Lex(); // Eat dollar token.
1147 // Parse the register operand.
1148 if (!tryParseRegisterOperand(Operands, isMips64())) {
1149 if (getLexer().is(AsmToken::LParen)) {
1150 // Check if it is indexed addressing operand.
1151 Operands.push_back(MipsOperand::CreateToken("(", S));
1152 Parser.Lex(); // Eat the parenthesis.
1153 if (getLexer().isNot(AsmToken::Dollar))
1156 Parser.Lex(); // Eat the dollar
1157 if (tryParseRegisterOperand(Operands, isMips64()))
1160 if (!getLexer().is(AsmToken::RParen))
1163 S = Parser.getTok().getLoc();
1164 Operands.push_back(MipsOperand::CreateToken(")", S));
1169 // Maybe it is a symbol reference.
1170 StringRef Identifier;
1171 if (Parser.parseIdentifier(Identifier))
1174 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1175 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1176 // Otherwise create a symbol reference.
1178 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1180 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1183 case AsmToken::Identifier:
1184 // For instruction aliases like "bc1f $Label" dedicated parser will
1185 // eat the '$' sign before failing. So in order to look for appropriate
1186 // label we must check first if we have already consumed '$'.
1187 if (hasConsumedDollar) {
1188 hasConsumedDollar = false;
1189 SMLoc S = Parser.getTok().getLoc();
1190 StringRef Identifier;
1191 if (Parser.parseIdentifier(Identifier))
1194 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1195 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1196 // Create a symbol reference.
1198 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1200 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1203 // Look for the existing symbol, we should check if
1204 // we need to assigne the propper RegisterKind.
1205 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1207 // Else drop to expression parsing.
1208 case AsmToken::LParen:
1209 case AsmToken::Minus:
1210 case AsmToken::Plus:
1211 case AsmToken::Integer:
1212 case AsmToken::String: {
1213 // Quoted label names.
1214 const MCExpr *IdVal;
1215 SMLoc S = Parser.getTok().getLoc();
1216 if (getParser().parseExpression(IdVal))
1218 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1219 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1222 case AsmToken::Percent: {
1223 // It is a symbol reference or constant expression.
1224 const MCExpr *IdVal;
1225 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1226 if (parseRelocOperand(IdVal))
1229 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1231 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1233 } // case AsmToken::Percent
1234 } // switch(getLexer().getKind())
1238 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1239 StringRef RelocStr) {
1241 // Check the type of the expression.
1242 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1243 // It's a constant, evaluate lo or hi value.
1244 if (RelocStr == "lo") {
1245 short Val = MCE->getValue();
1246 Res = MCConstantExpr::Create(Val, getContext());
1247 } else if (RelocStr == "hi") {
1248 int Val = MCE->getValue();
1249 int LoSign = Val & 0x8000;
1250 Val = (Val & 0xffff0000) >> 16;
1251 // Lower part is treated as a signed int, so if it is negative
1252 // we must add 1 to the hi part to compensate.
1255 Res = MCConstantExpr::Create(Val, getContext());
1257 llvm_unreachable("Invalid RelocStr value");
1262 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1263 // It's a symbol, create a symbolic expression from the symbol.
1264 StringRef Symbol = MSRE->getSymbol().getName();
1265 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1266 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1270 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1271 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1272 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1273 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1277 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1278 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1279 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1282 // Just return the original expression.
1286 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1288 switch (Expr->getKind()) {
1289 case MCExpr::Constant:
1291 case MCExpr::SymbolRef:
1292 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1293 case MCExpr::Binary:
1294 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1295 if (!isEvaluated(BE->getLHS()))
1297 return isEvaluated(BE->getRHS());
1300 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1307 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1308 Parser.Lex(); // Eat the % token.
1309 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1310 if (Tok.isNot(AsmToken::Identifier))
1313 std::string Str = Tok.getIdentifier().str();
1315 Parser.Lex(); // Eat the identifier.
1316 // Now make an expression from the rest of the operand.
1317 const MCExpr *IdVal;
1320 if (getLexer().getKind() == AsmToken::LParen) {
1322 Parser.Lex(); // Eat the '(' token.
1323 if (getLexer().getKind() == AsmToken::Percent) {
1324 Parser.Lex(); // Eat the % token.
1325 const AsmToken &nextTok = Parser.getTok();
1326 if (nextTok.isNot(AsmToken::Identifier))
1329 Str += nextTok.getIdentifier();
1330 Parser.Lex(); // Eat the identifier.
1331 if (getLexer().getKind() != AsmToken::LParen)
1336 if (getParser().parseParenExpression(IdVal, EndLoc))
1339 while (getLexer().getKind() == AsmToken::RParen)
1340 Parser.Lex(); // Eat the ')' token.
1343 return true; // Parenthesis must follow the relocation operand.
1345 Res = evaluateRelocExpr(IdVal, Str);
1349 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1351 StartLoc = Parser.getTok().getLoc();
1352 RegNo = tryParseRegister(isMips64());
1353 EndLoc = Parser.getTok().getLoc();
1354 return (RegNo == (unsigned)-1);
1357 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1361 while (getLexer().getKind() == AsmToken::LParen)
1364 switch (getLexer().getKind()) {
1367 case AsmToken::Identifier:
1368 case AsmToken::LParen:
1369 case AsmToken::Integer:
1370 case AsmToken::Minus:
1371 case AsmToken::Plus:
1373 Result = getParser().parseParenExpression(Res, S);
1375 Result = (getParser().parseExpression(Res));
1376 while (getLexer().getKind() == AsmToken::RParen)
1379 case AsmToken::Percent:
1380 Result = parseRelocOperand(Res);
1385 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1386 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1388 const MCExpr *IdVal = 0;
1390 bool isParenExpr = false;
1391 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1392 // First operand is the offset.
1393 S = Parser.getTok().getLoc();
1395 if (getLexer().getKind() == AsmToken::LParen) {
1400 if (getLexer().getKind() != AsmToken::Dollar) {
1401 if (parseMemOffset(IdVal, isParenExpr))
1402 return MatchOperand_ParseFail;
1404 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1405 if (Tok.isNot(AsmToken::LParen)) {
1406 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1407 if (Mnemonic->getToken() == "la") {
1409 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1410 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1411 return MatchOperand_Success;
1413 if (Tok.is(AsmToken::EndOfStatement)) {
1415 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1417 // Zero register assumed, add a memory operand with ZERO as its base.
1418 Operands.push_back(MipsOperand::CreateMem(
1419 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
1420 return MatchOperand_Success;
1422 Error(Parser.getTok().getLoc(), "'(' expected");
1423 return MatchOperand_ParseFail;
1426 Parser.Lex(); // Eat the '(' token.
1429 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1430 : (int)MipsOperand::Kind_GPR32);
1431 if (Res != MatchOperand_Success)
1434 if (Parser.getTok().isNot(AsmToken::RParen)) {
1435 Error(Parser.getTok().getLoc(), "')' expected");
1436 return MatchOperand_ParseFail;
1439 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1441 Parser.Lex(); // Eat the ')' token.
1444 IdVal = MCConstantExpr::Create(0, getContext());
1446 // Replace the register operand with the memory operand.
1447 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1448 int RegNo = op->getReg();
1449 // Remove the register from the operands.
1450 Operands.pop_back();
1451 // Add the memory operand.
1452 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1454 if (IdVal->EvaluateAsAbsolute(Imm))
1455 IdVal = MCConstantExpr::Create(Imm, getContext());
1456 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1457 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1461 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1463 return MatchOperand_Success;
1466 bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1468 // If the first token is not '$' we have an error.
1469 if (Parser.getTok().isNot(AsmToken::Dollar))
1472 SMLoc S = Parser.getTok().getLoc();
1474 AsmToken::TokenKind TkKind = getLexer().getKind();
1477 if (TkKind == AsmToken::Integer) {
1478 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1479 regKindToRegClass(RegKind));
1482 } else if (TkKind == AsmToken::Identifier) {
1483 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1485 Reg = getReg(regKindToRegClass(RegKind), Reg);
1490 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1491 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1492 Operands.push_back(Op);
1497 MipsAsmParser::OperandMatchResultTy
1498 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1499 MipsOperand::RegisterKind RegKind =
1500 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1502 // Parse index register.
1503 if (!parsePtrReg(Operands, RegKind))
1504 return MatchOperand_NoMatch;
1507 if (Parser.getTok().isNot(AsmToken::LParen))
1508 return MatchOperand_NoMatch;
1510 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1513 // Parse base register.
1514 if (!parsePtrReg(Operands, RegKind))
1515 return MatchOperand_NoMatch;
1518 if (Parser.getTok().isNot(AsmToken::RParen))
1519 return MatchOperand_NoMatch;
1521 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1524 return MatchOperand_Success;
1527 MipsAsmParser::OperandMatchResultTy
1528 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1530 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1531 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1532 if (searchSymbolAlias(Operands, Kind))
1533 return MatchOperand_Success;
1534 return MatchOperand_NoMatch;
1536 SMLoc S = Parser.getTok().getLoc();
1537 // If the first token is not '$', we have an error.
1538 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1539 return MatchOperand_NoMatch;
1540 if (!hasConsumedDollar) {
1541 Parser.Lex(); // Eat the '$'
1542 hasConsumedDollar = true;
1544 if (getLexer().getKind() == AsmToken::Identifier) {
1546 std::string RegName = Parser.getTok().getString().lower();
1547 // Match register by name
1549 case MipsOperand::Kind_GPR32:
1550 case MipsOperand::Kind_GPR64:
1551 RegNum = matchCPURegisterName(RegName);
1553 case MipsOperand::Kind_AFGR64Regs:
1554 case MipsOperand::Kind_FGR64Regs:
1555 case MipsOperand::Kind_FGR32Regs:
1556 case MipsOperand::Kind_FGRH32Regs:
1557 RegNum = matchFPURegisterName(RegName);
1558 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1560 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1561 if (RegNum != -1 && RegNum % 2 != 0)
1562 Warning(S, "Float register should be even.");
1564 case MipsOperand::Kind_FCCRegs:
1565 RegNum = matchFCCRegisterName(RegName);
1567 case MipsOperand::Kind_ACC64DSP:
1568 RegNum = matchACRegisterName(RegName);
1571 break; // No match, value is set to -1.
1573 // No match found, return _NoMatch to give a chance to other round.
1575 return MatchOperand_NoMatch;
1577 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1579 return MatchOperand_NoMatch;
1582 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1583 Op->setRegKind(Kind);
1584 Operands.push_back(Op);
1585 hasConsumedDollar = false;
1586 Parser.Lex(); // Eat the register name.
1587 return MatchOperand_Success;
1588 } else if (getLexer().getKind() == AsmToken::Integer) {
1589 unsigned RegNum = Parser.getTok().getIntVal();
1590 if (Kind == MipsOperand::Kind_HWRegs) {
1592 return MatchOperand_NoMatch;
1593 // Only hwreg 29 is supported, found at index 0.
1596 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1598 return MatchOperand_NoMatch;
1599 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1600 Op->setRegKind(Kind);
1601 Operands.push_back(Op);
1602 hasConsumedDollar = false;
1603 Parser.Lex(); // Eat the register number.
1604 if ((RegKind == MipsOperand::Kind_GPR32) &&
1605 (getLexer().is(AsmToken::LParen))) {
1606 // Check if it is indexed addressing operand.
1607 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1608 Parser.Lex(); // Eat the parenthesis.
1609 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1610 return MatchOperand_NoMatch;
1611 if (getLexer().isNot(AsmToken::RParen))
1612 return MatchOperand_NoMatch;
1613 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1616 return MatchOperand_Success;
1618 return MatchOperand_NoMatch;
1621 bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1622 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1630 case MipsOperand::Kind_MSA128BRegs:
1632 case MipsOperand::Kind_MSA128HRegs:
1634 case MipsOperand::Kind_MSA128WRegs:
1636 case MipsOperand::Kind_MSA128DRegs:
1641 MipsAsmParser::OperandMatchResultTy
1642 MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1644 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1645 SMLoc S = Parser.getTok().getLoc();
1646 std::string RegName;
1648 if (Parser.getTok().isNot(AsmToken::Dollar))
1649 return MatchOperand_NoMatch;
1653 return MatchOperand_ParseFail;
1654 case MipsOperand::Kind_MSA128BRegs:
1655 case MipsOperand::Kind_MSA128HRegs:
1656 case MipsOperand::Kind_MSA128WRegs:
1657 case MipsOperand::Kind_MSA128DRegs:
1661 Parser.Lex(); // Eat the '$'.
1662 if (getLexer().getKind() == AsmToken::Identifier)
1663 RegName = Parser.getTok().getString().lower();
1665 return MatchOperand_ParseFail;
1667 int RegNum = matchMSA128RegisterName(RegName);
1669 if (RegNum < 0 || RegNum > 31)
1670 return MatchOperand_ParseFail;
1672 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1674 return MatchOperand_ParseFail;
1676 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1677 Op->setRegKind(Kind);
1678 Operands.push_back(Op);
1680 Parser.Lex(); // Eat the register identifier.
1682 // MSA registers may be suffixed with an index in the form of:
1683 // 1) Immediate expression.
1684 // 2) General Purpose Register.
1686 // 1) copy_s.b $29,$w0[0]
1687 // 2) sld.b $w0,$w1[$1]
1689 if (Parser.getTok().isNot(AsmToken::LBrac))
1690 return MatchOperand_Success;
1692 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1694 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1695 Parser.Lex(); // Parse the '[' token.
1697 if (Parser.getTok().is(AsmToken::Dollar)) {
1698 // This must be a GPR.
1700 SMLoc VIdx = Parser.getTok().getLoc();
1701 Parser.Lex(); // Parse the '$' token.
1703 // GPR have aliases and we must account for that. Example: $30 == $fp
1704 if (getLexer().getKind() == AsmToken::Integer) {
1705 unsigned RegNum = Parser.getTok().getIntVal();
1706 int Reg = matchRegisterByNumber(
1707 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1709 Error(VIdx, "invalid general purpose register");
1710 return MatchOperand_ParseFail;
1713 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1714 } else if (getLexer().getKind() == AsmToken::Identifier) {
1716 std::string RegName = Parser.getTok().getString().lower();
1718 RegNum = matchCPURegisterName(RegName);
1720 Error(VIdx, "general purpose register expected");
1721 return MatchOperand_ParseFail;
1723 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1724 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1726 return MatchOperand_ParseFail;
1728 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1729 Operands.push_back(RegOp);
1730 Parser.Lex(); // Eat the register identifier.
1732 if (Parser.getTok().isNot(AsmToken::RBrac))
1733 return MatchOperand_ParseFail;
1735 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1736 Parser.Lex(); // Parse the ']' token.
1738 return MatchOperand_Success;
1741 // The index must be a constant expression then.
1742 SMLoc VIdx = Parser.getTok().getLoc();
1743 const MCExpr *ImmVal;
1745 if (getParser().parseExpression(ImmVal))
1746 return MatchOperand_ParseFail;
1748 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1749 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1750 Error(VIdx, "invalid immediate value");
1751 return MatchOperand_ParseFail;
1754 SMLoc E = Parser.getTok().getEndLoc();
1756 if (Parser.getTok().isNot(AsmToken::RBrac))
1757 return MatchOperand_ParseFail;
1760 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1761 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1763 // The second vector index of insve instructions is always 0.
1764 if (insve && Operands.size() > 6) {
1765 if (expr->getValue() != 0) {
1766 Error(VIdx, "immediate value must be 0");
1767 return MatchOperand_ParseFail;
1769 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1771 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1773 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1775 Parser.Lex(); // Parse the ']' token.
1777 return MatchOperand_Success;
1780 MipsAsmParser::OperandMatchResultTy
1781 MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1783 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1785 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1786 return MatchOperand_NoMatch;
1788 if (Parser.getTok().isNot(AsmToken::Dollar))
1789 return MatchOperand_ParseFail;
1791 SMLoc S = Parser.getTok().getLoc();
1793 Parser.Lex(); // Eat the '$' symbol.
1796 if (getLexer().getKind() == AsmToken::Identifier)
1797 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1798 else if (getLexer().getKind() == AsmToken::Integer)
1799 RegNum = Parser.getTok().getIntVal();
1801 return MatchOperand_ParseFail;
1803 if (RegNum < 0 || RegNum > 7)
1804 return MatchOperand_ParseFail;
1806 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1808 return MatchOperand_ParseFail;
1810 MipsOperand *RegOp =
1811 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1812 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1813 Operands.push_back(RegOp);
1814 Parser.Lex(); // Eat the register identifier.
1816 return MatchOperand_Success;
1819 MipsAsmParser::OperandMatchResultTy
1820 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1823 return MatchOperand_NoMatch;
1824 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1827 MipsAsmParser::OperandMatchResultTy
1828 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1829 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1832 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1833 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1836 return MatchOperand_NoMatch;
1837 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1840 MipsAsmParser::OperandMatchResultTy
1841 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1843 return MatchOperand_NoMatch;
1844 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1847 MipsAsmParser::OperandMatchResultTy
1848 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1849 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1852 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1853 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1854 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
1857 MipsAsmParser::OperandMatchResultTy
1858 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1859 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
1862 MipsAsmParser::OperandMatchResultTy
1863 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1864 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
1867 MipsAsmParser::OperandMatchResultTy
1868 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1869 // If the first token is not '$' we have an error.
1870 if (Parser.getTok().isNot(AsmToken::Dollar))
1871 return MatchOperand_NoMatch;
1873 SMLoc S = Parser.getTok().getLoc();
1874 Parser.Lex(); // Eat the '$'
1876 const AsmToken &Tok = Parser.getTok(); // Get next token.
1878 if (Tok.isNot(AsmToken::Identifier))
1879 return MatchOperand_NoMatch;
1881 if (!Tok.getIdentifier().startswith("ac"))
1882 return MatchOperand_NoMatch;
1884 StringRef NumString = Tok.getIdentifier().substr(2);
1887 if (NumString.getAsInteger(10, IntVal))
1888 return MatchOperand_NoMatch;
1890 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1892 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1893 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1894 Operands.push_back(Op);
1896 Parser.Lex(); // Eat the register number.
1897 return MatchOperand_Success;
1900 MipsAsmParser::OperandMatchResultTy
1901 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1902 // If the first token is not '$' we have an error.
1903 if (Parser.getTok().isNot(AsmToken::Dollar))
1904 return MatchOperand_NoMatch;
1906 SMLoc S = Parser.getTok().getLoc();
1907 Parser.Lex(); // Eat the '$'
1909 const AsmToken &Tok = Parser.getTok(); // Get next token.
1911 if (Tok.isNot(AsmToken::Identifier))
1912 return MatchOperand_NoMatch;
1914 if (!Tok.getIdentifier().startswith("ac"))
1915 return MatchOperand_NoMatch;
1917 StringRef NumString = Tok.getIdentifier().substr(2);
1920 if (NumString.getAsInteger(10, IntVal))
1921 return MatchOperand_NoMatch;
1923 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1925 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1926 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1927 Operands.push_back(Op);
1929 Parser.Lex(); // Eat the register number.
1930 return MatchOperand_Success;
1933 MipsAsmParser::OperandMatchResultTy
1934 MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1935 // If the first token is not '$' we have an error.
1936 if (Parser.getTok().isNot(AsmToken::Dollar))
1937 return MatchOperand_NoMatch;
1939 SMLoc S = Parser.getTok().getLoc();
1940 Parser.Lex(); // Eat the '$'
1942 const AsmToken &Tok = Parser.getTok(); // Get next token.
1944 if (Tok.isNot(AsmToken::Integer))
1945 return MatchOperand_NoMatch;
1947 unsigned IntVal = Tok.getIntVal();
1949 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1951 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1952 Op->setRegKind(MipsOperand::Kind_COP2);
1953 Operands.push_back(Op);
1955 Parser.Lex(); // Eat the register number.
1956 return MatchOperand_Success;
1959 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
1960 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1961 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
1964 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
1965 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1966 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
1969 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
1970 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1971 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
1974 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
1975 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1976 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
1979 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
1980 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1981 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
1984 bool MipsAsmParser::searchSymbolAlias(
1985 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
1987 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1989 SMLoc S = Parser.getTok().getLoc();
1991 if (Sym->isVariable())
1992 Expr = Sym->getVariableValue();
1995 if (Expr->getKind() == MCExpr::SymbolRef) {
1996 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1997 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1998 const StringRef DefSymbol = Ref->getSymbol().getName();
1999 if (DefSymbol.startswith("$")) {
2001 APInt IntVal(32, -1);
2002 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2003 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
2004 isMips64() ? Mips::GPR64RegClassID
2005 : Mips::GPR32RegClassID);
2007 // Lookup for the register with the corresponding name.
2009 case MipsOperand::Kind_AFGR64Regs:
2010 case MipsOperand::Kind_FGR64Regs:
2011 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2013 case MipsOperand::Kind_FGR32Regs:
2014 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2016 case MipsOperand::Kind_GPR64:
2017 case MipsOperand::Kind_GPR32:
2019 RegNum = matchCPURegisterName(DefSymbol.substr(1));
2023 RegNum = getReg(regKindToRegClass(Kind), RegNum);
2028 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
2029 op->setRegKind(Kind);
2030 Operands.push_back(op);
2034 } else if (Expr->getKind() == MCExpr::Constant) {
2036 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2038 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
2039 Operands.push_back(op);
2046 MipsAsmParser::OperandMatchResultTy
2047 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2048 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
2051 MipsAsmParser::OperandMatchResultTy
2052 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2053 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
2056 MipsAsmParser::OperandMatchResultTy
2057 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2058 const MCExpr *IdVal;
2059 // If the first token is '$' we may have register operand.
2060 if (Parser.getTok().is(AsmToken::Dollar))
2061 return MatchOperand_NoMatch;
2062 SMLoc S = Parser.getTok().getLoc();
2063 if (getParser().parseExpression(IdVal))
2064 return MatchOperand_ParseFail;
2065 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2066 assert(MCE && "Unexpected MCExpr type.");
2067 int64_t Val = MCE->getValue();
2068 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2069 Operands.push_back(MipsOperand::CreateImm(
2070 MCConstantExpr::Create(0 - Val, getContext()), S, E));
2071 return MatchOperand_Success;
2074 MipsAsmParser::OperandMatchResultTy
2075 MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2076 switch (getLexer().getKind()) {
2078 return MatchOperand_NoMatch;
2079 case AsmToken::LParen:
2080 case AsmToken::Plus:
2081 case AsmToken::Minus:
2082 case AsmToken::Integer:
2087 SMLoc S = Parser.getTok().getLoc();
2089 if (getParser().parseExpression(Expr))
2090 return MatchOperand_ParseFail;
2093 if (!Expr->EvaluateAsAbsolute(Val)) {
2094 Error(S, "expected immediate value");
2095 return MatchOperand_ParseFail;
2098 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2099 // and because the CPU always adds one to the immediate field, the allowed
2100 // range becomes 1..4. We'll only check the range here and will deal
2101 // with the addition/subtraction when actually decoding/encoding
2103 if (Val < 1 || Val > 4) {
2104 Error(S, "immediate not in range (1..4)");
2105 return MatchOperand_ParseFail;
2108 Operands.push_back(MipsOperand::CreateLSAImm(Expr, S,
2109 Parser.getTok().getLoc()));
2110 return MatchOperand_Success;
2113 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2115 MCSymbolRefExpr::VariantKind VK =
2116 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2117 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2118 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2119 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2120 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2121 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2122 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2123 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2124 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2125 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2126 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2127 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2128 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2129 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2130 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2131 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2132 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2133 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2134 .Default(MCSymbolRefExpr::VK_None);
2139 bool MipsAsmParser::ParseInstruction(
2140 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2141 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2142 // Check if we have valid mnemonic
2143 if (!mnemonicIsValid(Name, 0)) {
2144 Parser.eatToEndOfStatement();
2145 return Error(NameLoc, "Unknown instruction");
2147 // First operand in MCInst is instruction mnemonic.
2148 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2150 // Read the remaining operands.
2151 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2152 // Read the first operand.
2153 if (ParseOperand(Operands, Name)) {
2154 SMLoc Loc = getLexer().getLoc();
2155 Parser.eatToEndOfStatement();
2156 return Error(Loc, "unexpected token in argument list");
2159 while (getLexer().is(AsmToken::Comma)) {
2160 Parser.Lex(); // Eat the comma.
2161 // Parse and remember the operand.
2162 if (ParseOperand(Operands, Name)) {
2163 SMLoc Loc = getLexer().getLoc();
2164 Parser.eatToEndOfStatement();
2165 return Error(Loc, "unexpected token in argument list");
2169 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2170 SMLoc Loc = getLexer().getLoc();
2171 Parser.eatToEndOfStatement();
2172 return Error(Loc, "unexpected token in argument list");
2174 Parser.Lex(); // Consume the EndOfStatement.
2178 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2179 SMLoc Loc = getLexer().getLoc();
2180 Parser.eatToEndOfStatement();
2181 return Error(Loc, ErrorMsg);
2184 bool MipsAsmParser::parseSetNoAtDirective() {
2185 // Line should look like: ".set noat".
2187 Options.setATReg(0);
2190 // If this is not the end of the statement, report an error.
2191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2192 reportParseError("unexpected token in statement");
2195 Parser.Lex(); // Consume the EndOfStatement.
2199 bool MipsAsmParser::parseSetAtDirective() {
2200 // Line can be .set at - defaults to $1
2204 if (getLexer().is(AsmToken::EndOfStatement)) {
2205 Options.setATReg(1);
2206 Parser.Lex(); // Consume the EndOfStatement.
2208 } else if (getLexer().is(AsmToken::Equal)) {
2209 getParser().Lex(); // Eat the '='.
2210 if (getLexer().isNot(AsmToken::Dollar)) {
2211 reportParseError("unexpected token in statement");
2214 Parser.Lex(); // Eat the '$'.
2215 const AsmToken &Reg = Parser.getTok();
2216 if (Reg.is(AsmToken::Identifier)) {
2217 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2218 } else if (Reg.is(AsmToken::Integer)) {
2219 AtRegNo = Reg.getIntVal();
2221 reportParseError("unexpected token in statement");
2225 if (AtRegNo < 1 || AtRegNo > 31) {
2226 reportParseError("unexpected token in statement");
2230 if (!Options.setATReg(AtRegNo)) {
2231 reportParseError("unexpected token in statement");
2234 getParser().Lex(); // Eat the register.
2236 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2237 reportParseError("unexpected token in statement");
2240 Parser.Lex(); // Consume the EndOfStatement.
2243 reportParseError("unexpected token in statement");
2248 bool MipsAsmParser::parseSetReorderDirective() {
2250 // If this is not the end of the statement, report an error.
2251 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2252 reportParseError("unexpected token in statement");
2255 Options.setReorder();
2256 Parser.Lex(); // Consume the EndOfStatement.
2260 bool MipsAsmParser::parseSetNoReorderDirective() {
2262 // If this is not the end of the statement, report an error.
2263 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2264 reportParseError("unexpected token in statement");
2267 Options.setNoreorder();
2268 Parser.Lex(); // Consume the EndOfStatement.
2272 bool MipsAsmParser::parseSetMacroDirective() {
2274 // If this is not the end of the statement, report an error.
2275 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2276 reportParseError("unexpected token in statement");
2280 Parser.Lex(); // Consume the EndOfStatement.
2284 bool MipsAsmParser::parseSetNoMacroDirective() {
2286 // If this is not the end of the statement, report an error.
2287 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2288 reportParseError("`noreorder' must be set before `nomacro'");
2291 if (Options.isReorder()) {
2292 reportParseError("`noreorder' must be set before `nomacro'");
2295 Options.setNomacro();
2296 Parser.Lex(); // Consume the EndOfStatement.
2300 bool MipsAsmParser::parseSetAssignment() {
2302 const MCExpr *Value;
2304 if (Parser.parseIdentifier(Name))
2305 reportParseError("expected identifier after .set");
2307 if (getLexer().isNot(AsmToken::Comma))
2308 return reportParseError("unexpected token in .set directive");
2311 if (Parser.parseExpression(Value))
2312 return reportParseError("expected valid expression after comma");
2314 // Check if the Name already exists as a symbol.
2315 MCSymbol *Sym = getContext().LookupSymbol(Name);
2317 return reportParseError("symbol already defined");
2318 Sym = getContext().GetOrCreateSymbol(Name);
2319 Sym->setVariableValue(Value);
2324 bool MipsAsmParser::parseDirectiveSet() {
2326 // Get the next token.
2327 const AsmToken &Tok = Parser.getTok();
2329 if (Tok.getString() == "noat") {
2330 return parseSetNoAtDirective();
2331 } else if (Tok.getString() == "at") {
2332 return parseSetAtDirective();
2333 } else if (Tok.getString() == "reorder") {
2334 return parseSetReorderDirective();
2335 } else if (Tok.getString() == "noreorder") {
2336 return parseSetNoReorderDirective();
2337 } else if (Tok.getString() == "macro") {
2338 return parseSetMacroDirective();
2339 } else if (Tok.getString() == "nomacro") {
2340 return parseSetNoMacroDirective();
2341 } else if (Tok.getString() == "nomips16") {
2342 // Ignore this directive for now.
2343 Parser.eatToEndOfStatement();
2345 } else if (Tok.getString() == "nomicromips") {
2346 // Ignore this directive for now.
2347 Parser.eatToEndOfStatement();
2350 // It is just an identifier, look for an assignment.
2351 parseSetAssignment();
2358 bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2359 MCAsmParser &Parser = getParser();
2361 if (Parser.parseIdentifier(Name))
2362 reportParseError("expected identifier");
2364 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2365 if (getLexer().isNot(AsmToken::Comma))
2366 return TokError("unexpected token");
2370 if (Parser.parseAbsoluteExpression(Flags))
2371 return TokError("unexpected token");
2373 getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
2377 bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2379 if (Parser.parseAbsoluteExpression(Flags))
2380 return TokError("unexpected token");
2382 getTargetStreamer().emitMipsHackELFFlags(Flags);
2386 /// parseDirectiveWord
2387 /// ::= .word [ expression (, expression)* ]
2388 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2391 const MCExpr *Value;
2392 if (getParser().parseExpression(Value))
2395 getParser().getStreamer().EmitValue(Value, Size);
2397 if (getLexer().is(AsmToken::EndOfStatement))
2400 // FIXME: Improve diagnostic.
2401 if (getLexer().isNot(AsmToken::Comma))
2402 return Error(L, "unexpected token in directive");
2411 /// parseDirectiveGpWord
2412 /// ::= .gpword local_sym
2413 bool MipsAsmParser::parseDirectiveGpWord() {
2414 const MCExpr *Value;
2415 // EmitGPRel32Value requires an expression, so we are using base class
2416 // method to evaluate the expression.
2417 if (getParser().parseExpression(Value))
2419 getParser().getStreamer().EmitGPRel32Value(Value);
2421 if (getLexer().isNot(AsmToken::EndOfStatement))
2422 return Error(getLexer().getLoc(), "unexpected token in directive");
2423 Parser.Lex(); // Eat EndOfStatement token.
2427 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2429 StringRef IDVal = DirectiveID.getString();
2431 if (IDVal == ".ent") {
2432 // Ignore this directive for now.
2437 if (IDVal == ".end") {
2438 // Ignore this directive for now.
2443 if (IDVal == ".frame") {
2444 // Ignore this directive for now.
2445 Parser.eatToEndOfStatement();
2449 if (IDVal == ".set") {
2450 return parseDirectiveSet();
2453 if (IDVal == ".fmask") {
2454 // Ignore this directive for now.
2455 Parser.eatToEndOfStatement();
2459 if (IDVal == ".mask") {
2460 // Ignore this directive for now.
2461 Parser.eatToEndOfStatement();
2465 if (IDVal == ".gpword") {
2466 // Ignore this directive for now.
2467 parseDirectiveGpWord();
2471 if (IDVal == ".word") {
2472 parseDirectiveWord(4, DirectiveID.getLoc());
2476 if (IDVal == ".mips_hack_stocg")
2477 return parseDirectiveMipsHackStocg();
2479 if (IDVal == ".mips_hack_elf_flags")
2480 return parseDirectiveMipsHackELFFlags();
2485 extern "C" void LLVMInitializeMipsAsmParser() {
2486 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2487 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2488 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2489 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2492 #define GET_REGISTER_MATCHER
2493 #define GET_MATCHER_IMPLEMENTATION
2494 #include "MipsGenAsmMatcher.inc"