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/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21 #include "llvm/MC/MCStreamer.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/MC/MCTargetAsmParser.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/TargetRegistry.h"
35 class MipsAssemblerOptions {
37 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
39 unsigned getATRegNum() { return aTReg; }
40 bool setATReg(unsigned Reg);
42 bool isReorder() { return reorder; }
43 void setReorder() { reorder = true; }
44 void setNoreorder() { reorder = false; }
46 bool isMacro() { return macro; }
47 void setMacro() { macro = true; }
48 void setNomacro() { macro = false; }
58 class MipsAsmParser : public MCTargetAsmParser {
60 MipsTargetStreamer &getTargetStreamer() {
61 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
62 return static_cast<MipsTargetStreamer &>(TS);
67 MipsAssemblerOptions Options;
68 bool hasConsumedDollar;
70 #define GET_ASSEMBLER_HEADER
71 #include "MipsGenAsmMatcher.inc"
73 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
74 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
75 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
78 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
80 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
82 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
84 bool ParseDirective(AsmToken DirectiveID);
86 MipsAsmParser::OperandMatchResultTy
87 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
89 MipsAsmParser::OperandMatchResultTy
90 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
92 MipsAsmParser::OperandMatchResultTy
93 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
96 MipsAsmParser::OperandMatchResultTy
97 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
99 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
102 MipsAsmParser::OperandMatchResultTy
103 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
105 MipsAsmParser::OperandMatchResultTy
106 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
108 MipsAsmParser::OperandMatchResultTy
109 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
111 MipsAsmParser::OperandMatchResultTy
112 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
114 MipsAsmParser::OperandMatchResultTy
115 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
117 MipsAsmParser::OperandMatchResultTy
118 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
120 MipsAsmParser::OperandMatchResultTy
121 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
123 MipsAsmParser::OperandMatchResultTy
124 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
126 MipsAsmParser::OperandMatchResultTy
127 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
129 MipsAsmParser::OperandMatchResultTy
130 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
135 MipsAsmParser::OperandMatchResultTy
136 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
138 MipsAsmParser::OperandMatchResultTy
139 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
141 MipsAsmParser::OperandMatchResultTy
142 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
144 MipsAsmParser::OperandMatchResultTy
145 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
147 MipsAsmParser::OperandMatchResultTy
148 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
150 MipsAsmParser::OperandMatchResultTy
151 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
153 MipsAsmParser::OperandMatchResultTy
154 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
156 MipsAsmParser::OperandMatchResultTy
157 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
165 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
168 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
171 int tryParseRegister(bool is64BitReg);
173 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
176 bool needsExpansion(MCInst &Inst);
178 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
180 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
182 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
184 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
186 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
189 bool reportParseError(StringRef ErrorMsg);
191 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
192 bool parseRelocOperand(const MCExpr *&Res);
194 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
196 bool isEvaluated(const MCExpr *Expr);
197 bool parseDirectiveSet();
198 bool parseDirectiveOption();
200 bool parseSetAtDirective();
201 bool parseSetNoAtDirective();
202 bool parseSetMacroDirective();
203 bool parseSetNoMacroDirective();
204 bool parseSetReorderDirective();
205 bool parseSetNoReorderDirective();
206 bool parseSetMips16Directive();
207 bool parseSetNoMips16Directive();
209 bool parseSetAssignment();
211 bool parseDirectiveWord(unsigned Size, SMLoc L);
212 bool parseDirectiveGpWord();
214 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
216 bool isMips64() const {
217 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
220 bool isFP64() const {
221 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
224 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
226 bool isMicroMips() const {
227 return STI.getFeatureBits() & Mips::FeatureMicroMips;
230 int matchRegisterName(StringRef Symbol, bool is64BitReg);
232 int matchCPURegisterName(StringRef Symbol);
234 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
236 int matchFPURegisterName(StringRef Name);
238 int matchFCCRegisterName(StringRef Name);
240 int matchACRegisterName(StringRef Name);
242 int matchMSA128RegisterName(StringRef Name);
244 int matchMSA128CtrlRegisterName(StringRef Name);
246 int regKindToRegClass(int RegKind);
248 unsigned getReg(int RC, int RegNo);
252 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
253 SmallVectorImpl<MCInst> &Instructions);
255 // Helper function that checks if the value of a vector index is within the
256 // boundaries of accepted values for each RegisterKind
257 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
258 bool validateMSAIndex(int Val, int RegKind);
261 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
262 const MCInstrInfo &MII)
263 : MCTargetAsmParser(), STI(sti), Parser(parser),
264 hasConsumedDollar(false) {
265 // Initialize the set of available features.
266 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
268 // Assert exactly one ABI was chosen.
269 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
270 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
271 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
272 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
275 MCAsmParser &getParser() const { return Parser; }
276 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
282 /// MipsOperand - Instances of this class represent a parsed Mips machine
284 class MipsOperand : public MCParsedAsmOperand {
322 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
350 SMLoc StartLoc, EndLoc;
353 void addRegOperands(MCInst &Inst, unsigned N) const {
354 assert(N == 1 && "Invalid number of operands!");
355 Inst.addOperand(MCOperand::CreateReg(getReg()));
358 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
359 assert(N == 1 && "Invalid number of operands!");
360 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
363 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
364 // Add as immediate when possible. Null MCExpr = 0.
366 Inst.addOperand(MCOperand::CreateImm(0));
367 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
368 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
370 Inst.addOperand(MCOperand::CreateExpr(Expr));
373 void addImmOperands(MCInst &Inst, unsigned N) const {
374 assert(N == 1 && "Invalid number of operands!");
375 const MCExpr *Expr = getImm();
379 void addMemOperands(MCInst &Inst, unsigned N) const {
380 assert(N == 2 && "Invalid number of operands!");
382 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
384 const MCExpr *Expr = getMemOff();
388 bool isReg() const { return Kind == k_Register; }
389 bool isImm() const { return Kind == k_Immediate; }
390 bool isToken() const { return Kind == k_Token; }
391 bool isMem() const { return Kind == k_Memory; }
392 bool isPtrReg() const { return Kind == k_PtrReg; }
393 bool isInvNum() const { return Kind == k_Immediate; }
394 bool isLSAImm() const { return Kind == k_LSAImm; }
396 StringRef getToken() const {
397 assert(Kind == k_Token && "Invalid access!");
398 return StringRef(Tok.Data, Tok.Length);
401 unsigned getReg() const {
402 assert((Kind == k_Register) && "Invalid access!");
406 unsigned getPtrReg() const {
407 assert((Kind == k_PtrReg) && "Invalid access!");
411 void setRegKind(RegisterKind RegKind) {
412 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
416 const MCExpr *getImm() const {
417 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
421 unsigned getMemBase() const {
422 assert((Kind == k_Memory) && "Invalid access!");
426 const MCExpr *getMemOff() const {
427 assert((Kind == k_Memory) && "Invalid access!");
431 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
432 MipsOperand *Op = new MipsOperand(k_Token);
433 Op->Tok.Data = Str.data();
434 Op->Tok.Length = Str.size();
440 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
441 MipsOperand *Op = new MipsOperand(k_Register);
442 Op->Reg.RegNum = RegNum;
448 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
449 MipsOperand *Op = new MipsOperand(k_PtrReg);
450 Op->Reg.RegNum = RegNum;
456 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
457 MipsOperand *Op = new MipsOperand(k_Immediate);
464 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
465 MipsOperand *Op = new MipsOperand(k_LSAImm);
472 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
474 MipsOperand *Op = new MipsOperand(k_Memory);
482 bool isGPR32Asm() const {
483 return Kind == k_Register && Reg.Kind == Kind_GPR32;
485 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
486 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
489 bool isGPR64Asm() const {
490 return Kind == k_Register && Reg.Kind == Kind_GPR64;
493 bool isHWRegsAsm() const {
494 assert((Kind == k_Register) && "Invalid access!");
495 return Reg.Kind == Kind_HWRegs;
498 bool isCCRAsm() const {
499 assert((Kind == k_Register) && "Invalid access!");
500 return Reg.Kind == Kind_CCRRegs;
503 bool isAFGR64Asm() const {
504 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
507 bool isFGR64Asm() const {
508 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
511 bool isFGR32Asm() const {
512 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
515 bool isFGRH32Asm() const {
516 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
519 bool isFCCRegsAsm() const {
520 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
523 bool isACC64DSPAsm() const {
524 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
527 bool isLO32DSPAsm() const {
528 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
531 bool isHI32DSPAsm() const {
532 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
535 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
537 bool isMSA128BAsm() const {
538 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
541 bool isMSA128HAsm() const {
542 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
545 bool isMSA128WAsm() const {
546 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
549 bool isMSA128DAsm() const {
550 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
553 bool isMSA128CRAsm() const {
554 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
557 /// getStartLoc - Get the location of the first token of this operand.
558 SMLoc getStartLoc() const { return StartLoc; }
559 /// getEndLoc - Get the location of the last token of this operand.
560 SMLoc getEndLoc() const { return EndLoc; }
562 virtual void print(raw_ostream &OS) const {
563 llvm_unreachable("unimplemented!");
565 }; // class MipsOperand
569 extern const MCInstrDesc MipsInsts[];
571 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
572 return MipsInsts[Opcode];
575 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
576 SmallVectorImpl<MCInst> &Instructions) {
577 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
580 if (MCID.isBranch() || MCID.isCall()) {
581 const unsigned Opcode = Inst.getOpcode();
589 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
590 Offset = Inst.getOperand(2);
592 break; // We'll deal with this situation later on when applying fixups.
593 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
594 return Error(IDLoc, "branch target out of range");
595 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
596 return Error(IDLoc, "branch to misaligned address");
606 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
607 Offset = Inst.getOperand(1);
609 break; // We'll deal with this situation later on when applying fixups.
610 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
611 return Error(IDLoc, "branch target out of range");
612 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
613 return Error(IDLoc, "branch to misaligned address");
618 if (MCID.hasDelaySlot() && Options.isReorder()) {
619 // If this instruction has a delay slot and .set reorder is active,
620 // emit a NOP after it.
621 Instructions.push_back(Inst);
623 NopInst.setOpcode(Mips::SLL);
624 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
625 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
626 NopInst.addOperand(MCOperand::CreateImm(0));
627 Instructions.push_back(NopInst);
631 if (MCID.mayLoad() || MCID.mayStore()) {
632 // Check the offset of memory operand, if it is a symbol
633 // reference or immediate we may have to expand instructions.
634 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
635 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
636 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
637 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
638 MCOperand &Op = Inst.getOperand(i);
640 int MemOffset = Op.getImm();
641 if (MemOffset < -32768 || MemOffset > 32767) {
642 // Offset can't exceed 16bit value.
643 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
646 } else if (Op.isExpr()) {
647 const MCExpr *Expr = Op.getExpr();
648 if (Expr->getKind() == MCExpr::SymbolRef) {
649 const MCSymbolRefExpr *SR =
650 static_cast<const MCSymbolRefExpr *>(Expr);
651 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
653 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
656 } else if (!isEvaluated(Expr)) {
657 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
665 if (needsExpansion(Inst))
666 expandInstruction(Inst, IDLoc, Instructions);
668 Instructions.push_back(Inst);
673 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
675 switch (Inst.getOpcode()) {
676 case Mips::LoadImm32Reg:
677 case Mips::LoadAddr32Imm:
678 case Mips::LoadAddr32Reg:
685 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
686 SmallVectorImpl<MCInst> &Instructions) {
687 switch (Inst.getOpcode()) {
688 case Mips::LoadImm32Reg:
689 return expandLoadImm(Inst, IDLoc, Instructions);
690 case Mips::LoadAddr32Imm:
691 return expandLoadAddressImm(Inst, IDLoc, Instructions);
692 case Mips::LoadAddr32Reg:
693 return expandLoadAddressReg(Inst, IDLoc, Instructions);
697 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
698 SmallVectorImpl<MCInst> &Instructions) {
700 const MCOperand &ImmOp = Inst.getOperand(1);
701 assert(ImmOp.isImm() && "expected immediate operand kind");
702 const MCOperand &RegOp = Inst.getOperand(0);
703 assert(RegOp.isReg() && "expected register operand kind");
705 int ImmValue = ImmOp.getImm();
706 tmpInst.setLoc(IDLoc);
707 if (0 <= ImmValue && ImmValue <= 65535) {
708 // For 0 <= j <= 65535.
709 // li d,j => ori d,$zero,j
710 tmpInst.setOpcode(Mips::ORi);
711 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
712 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
713 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
714 Instructions.push_back(tmpInst);
715 } else if (ImmValue < 0 && ImmValue >= -32768) {
716 // For -32768 <= j < 0.
717 // li d,j => addiu d,$zero,j
718 tmpInst.setOpcode(Mips::ADDiu);
719 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
720 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
721 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
722 Instructions.push_back(tmpInst);
724 // For any other value of j that is representable as a 32-bit integer.
725 // li d,j => lui d,hi16(j)
727 tmpInst.setOpcode(Mips::LUi);
728 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
729 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
730 Instructions.push_back(tmpInst);
732 tmpInst.setOpcode(Mips::ORi);
733 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
734 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
735 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
736 tmpInst.setLoc(IDLoc);
737 Instructions.push_back(tmpInst);
742 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
743 SmallVectorImpl<MCInst> &Instructions) {
745 const MCOperand &ImmOp = Inst.getOperand(2);
746 assert(ImmOp.isImm() && "expected immediate operand kind");
747 const MCOperand &SrcRegOp = Inst.getOperand(1);
748 assert(SrcRegOp.isReg() && "expected register operand kind");
749 const MCOperand &DstRegOp = Inst.getOperand(0);
750 assert(DstRegOp.isReg() && "expected register operand kind");
751 int ImmValue = ImmOp.getImm();
752 if (-32768 <= ImmValue && ImmValue <= 65535) {
753 // For -32768 <= j <= 65535.
754 // la d,j(s) => addiu d,s,j
755 tmpInst.setOpcode(Mips::ADDiu);
756 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
757 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
758 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
759 Instructions.push_back(tmpInst);
761 // For any other value of j that is representable as a 32-bit integer.
762 // la d,j(s) => lui d,hi16(j)
765 tmpInst.setOpcode(Mips::LUi);
766 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
767 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
768 Instructions.push_back(tmpInst);
770 tmpInst.setOpcode(Mips::ORi);
771 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
772 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
774 Instructions.push_back(tmpInst);
776 tmpInst.setOpcode(Mips::ADDu);
777 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
778 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
779 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
780 Instructions.push_back(tmpInst);
785 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
786 SmallVectorImpl<MCInst> &Instructions) {
788 const MCOperand &ImmOp = Inst.getOperand(1);
789 assert(ImmOp.isImm() && "expected immediate operand kind");
790 const MCOperand &RegOp = Inst.getOperand(0);
791 assert(RegOp.isReg() && "expected register operand kind");
792 int ImmValue = ImmOp.getImm();
793 if (-32768 <= ImmValue && ImmValue <= 65535) {
794 // For -32768 <= j <= 65535.
795 // la d,j => addiu d,$zero,j
796 tmpInst.setOpcode(Mips::ADDiu);
797 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
798 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
799 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
800 Instructions.push_back(tmpInst);
802 // For any other value of j that is representable as a 32-bit integer.
803 // la d,j => lui d,hi16(j)
805 tmpInst.setOpcode(Mips::LUi);
806 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
807 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
808 Instructions.push_back(tmpInst);
810 tmpInst.setOpcode(Mips::ORi);
811 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
812 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
813 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
814 Instructions.push_back(tmpInst);
818 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
819 SmallVectorImpl<MCInst> &Instructions,
820 bool isLoad, bool isImmOpnd) {
821 const MCSymbolRefExpr *SR;
823 unsigned ImmOffset, HiOffset, LoOffset;
824 const MCExpr *ExprOffset;
826 unsigned AtRegNum = getReg(
827 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
828 // 1st operand is either the source or destination register.
829 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
830 unsigned RegOpNum = Inst.getOperand(0).getReg();
831 // 2nd operand is the base register.
832 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
833 unsigned BaseRegNum = Inst.getOperand(1).getReg();
834 // 3rd operand is either an immediate or expression.
836 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
837 ImmOffset = Inst.getOperand(2).getImm();
838 LoOffset = ImmOffset & 0x0000ffff;
839 HiOffset = (ImmOffset & 0xffff0000) >> 16;
840 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
841 if (LoOffset & 0x8000)
844 ExprOffset = Inst.getOperand(2).getExpr();
845 // All instructions will have the same location.
846 TempInst.setLoc(IDLoc);
847 // 1st instruction in expansion is LUi. For load instruction we can use
848 // the dst register as a temporary if base and dst are different,
849 // but for stores we must use $at.
850 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
851 TempInst.setOpcode(Mips::LUi);
852 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
854 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
856 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
857 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
858 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
859 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
861 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
863 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
864 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
867 // Add the instruction to the list.
868 Instructions.push_back(TempInst);
869 // Prepare TempInst for next instruction.
871 // Add temp register to base.
872 TempInst.setOpcode(Mips::ADDu);
873 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
874 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
875 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
876 Instructions.push_back(TempInst);
878 // And finally, create original instruction with low part
879 // of offset and new base.
880 TempInst.setOpcode(Inst.getOpcode());
881 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
882 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
884 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
886 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
887 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
888 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
890 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
892 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
893 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
896 Instructions.push_back(TempInst);
900 bool MipsAsmParser::MatchAndEmitInstruction(
901 SMLoc IDLoc, unsigned &Opcode,
902 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
903 unsigned &ErrorInfo, bool MatchingInlineAsm) {
905 SmallVector<MCInst, 8> Instructions;
906 unsigned MatchResult =
907 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
909 switch (MatchResult) {
912 case Match_Success: {
913 if (processInstruction(Inst, IDLoc, Instructions))
915 for (unsigned i = 0; i < Instructions.size(); i++)
916 Out.EmitInstruction(Instructions[i], STI);
919 case Match_MissingFeature:
920 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
922 case Match_InvalidOperand: {
923 SMLoc ErrorLoc = IDLoc;
924 if (ErrorInfo != ~0U) {
925 if (ErrorInfo >= Operands.size())
926 return Error(IDLoc, "too few operands for instruction");
928 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
929 if (ErrorLoc == SMLoc())
933 return Error(ErrorLoc, "invalid operand for instruction");
935 case Match_MnemonicFail:
936 return Error(IDLoc, "invalid instruction");
941 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
947 CC = StringSwitch<unsigned>(Name)
981 // Although SGI documentation just cuts out t0-t3 for n32/n64,
982 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
983 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
984 if (isMips64() && 8 <= CC && CC <= 11)
987 if (CC == -1 && isMips64())
988 CC = StringSwitch<unsigned>(Name)
1001 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1003 if (Name[0] == 'f') {
1004 StringRef NumString = Name.substr(1);
1006 if (NumString.getAsInteger(10, IntVal))
1007 return -1; // This is not an integer.
1008 if (IntVal > 31) // Maximum index for fpu register.
1015 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1017 if (Name.startswith("fcc")) {
1018 StringRef NumString = Name.substr(3);
1020 if (NumString.getAsInteger(10, IntVal))
1021 return -1; // This is not an integer.
1022 if (IntVal > 7) // There are only 8 fcc registers.
1029 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1031 if (Name.startswith("ac")) {
1032 StringRef NumString = Name.substr(2);
1034 if (NumString.getAsInteger(10, IntVal))
1035 return -1; // This is not an integer.
1036 if (IntVal > 3) // There are only 3 acc registers.
1043 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1046 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1055 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1058 CC = StringSwitch<unsigned>(Name)
1061 .Case("msaaccess", 2)
1063 .Case("msamodify", 4)
1064 .Case("msarequest", 5)
1066 .Case("msaunmap", 7)
1072 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1075 CC = matchCPURegisterName(Name);
1077 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1078 : Mips::GPR32RegClassID);
1079 CC = matchFPURegisterName(Name);
1080 // TODO: decide about fpu register class
1082 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1083 : Mips::FGR32RegClassID);
1084 return matchMSA128RegisterName(Name);
1087 int MipsAsmParser::regKindToRegClass(int RegKind) {
1090 case MipsOperand::Kind_GPR32:
1091 return Mips::GPR32RegClassID;
1092 case MipsOperand::Kind_GPR64:
1093 return Mips::GPR64RegClassID;
1094 case MipsOperand::Kind_HWRegs:
1095 return Mips::HWRegsRegClassID;
1096 case MipsOperand::Kind_FGR32Regs:
1097 return Mips::FGR32RegClassID;
1098 case MipsOperand::Kind_FGRH32Regs:
1099 return Mips::FGRH32RegClassID;
1100 case MipsOperand::Kind_FGR64Regs:
1101 return Mips::FGR64RegClassID;
1102 case MipsOperand::Kind_AFGR64Regs:
1103 return Mips::AFGR64RegClassID;
1104 case MipsOperand::Kind_CCRRegs:
1105 return Mips::CCRRegClassID;
1106 case MipsOperand::Kind_ACC64DSP:
1107 return Mips::ACC64DSPRegClassID;
1108 case MipsOperand::Kind_FCCRegs:
1109 return Mips::FCCRegClassID;
1110 case MipsOperand::Kind_MSA128BRegs:
1111 return Mips::MSA128BRegClassID;
1112 case MipsOperand::Kind_MSA128HRegs:
1113 return Mips::MSA128HRegClassID;
1114 case MipsOperand::Kind_MSA128WRegs:
1115 return Mips::MSA128WRegClassID;
1116 case MipsOperand::Kind_MSA128DRegs:
1117 return Mips::MSA128DRegClassID;
1118 case MipsOperand::Kind_MSA128CtrlRegs:
1119 return Mips::MSACtrlRegClassID;
1125 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1133 int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
1135 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1136 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1139 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1141 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
1144 return getReg(RegClass, RegNum);
1147 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1148 const AsmToken &Tok = Parser.getTok();
1151 if (Tok.is(AsmToken::Identifier)) {
1152 std::string lowerCase = Tok.getString().lower();
1153 RegNum = matchRegisterName(lowerCase, is64BitReg);
1154 } else if (Tok.is(AsmToken::Integer))
1155 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1156 is64BitReg ? Mips::GPR64RegClassID
1157 : Mips::GPR32RegClassID);
1161 bool MipsAsmParser::tryParseRegisterOperand(
1162 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
1164 SMLoc S = Parser.getTok().getLoc();
1167 RegNo = tryParseRegister(is64BitReg);
1172 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1173 Parser.Lex(); // Eat register token.
1178 MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1179 StringRef Mnemonic) {
1180 // Check if the current operand has a custom associated parser, if so, try to
1181 // custom parse the operand, or fallback to the general approach.
1182 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1183 if (ResTy == MatchOperand_Success)
1185 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1186 // there was a match, but an error occurred, in which case, just return that
1187 // the operand parsing failed.
1188 if (ResTy == MatchOperand_ParseFail)
1191 switch (getLexer().getKind()) {
1193 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1195 case AsmToken::Dollar: {
1196 // Parse the register.
1197 SMLoc S = Parser.getTok().getLoc();
1198 Parser.Lex(); // Eat dollar token.
1199 // Parse the register operand.
1200 if (!tryParseRegisterOperand(Operands, isMips64())) {
1201 if (getLexer().is(AsmToken::LParen)) {
1202 // Check if it is indexed addressing operand.
1203 Operands.push_back(MipsOperand::CreateToken("(", S));
1204 Parser.Lex(); // Eat the parenthesis.
1205 if (getLexer().isNot(AsmToken::Dollar))
1208 Parser.Lex(); // Eat the dollar
1209 if (tryParseRegisterOperand(Operands, isMips64()))
1212 if (!getLexer().is(AsmToken::RParen))
1215 S = Parser.getTok().getLoc();
1216 Operands.push_back(MipsOperand::CreateToken(")", S));
1221 // Maybe it is a symbol reference.
1222 StringRef Identifier;
1223 if (Parser.parseIdentifier(Identifier))
1226 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1227 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1228 // Otherwise create a symbol reference.
1230 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1232 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1235 case AsmToken::Identifier:
1236 // For instruction aliases like "bc1f $Label" dedicated parser will
1237 // eat the '$' sign before failing. So in order to look for appropriate
1238 // label we must check first if we have already consumed '$'.
1239 if (hasConsumedDollar) {
1240 hasConsumedDollar = false;
1241 SMLoc S = Parser.getTok().getLoc();
1242 StringRef Identifier;
1243 if (Parser.parseIdentifier(Identifier))
1246 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1247 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1248 // Create a symbol reference.
1250 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1252 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1255 // Look for the existing symbol, we should check if
1256 // we need to assign the proper RegisterKind.
1257 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1259 // Else drop to expression parsing.
1260 case AsmToken::LParen:
1261 case AsmToken::Minus:
1262 case AsmToken::Plus:
1263 case AsmToken::Integer:
1264 case AsmToken::String: {
1265 // Quoted label names.
1266 const MCExpr *IdVal;
1267 SMLoc S = Parser.getTok().getLoc();
1268 if (getParser().parseExpression(IdVal))
1270 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1271 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1274 case AsmToken::Percent: {
1275 // It is a symbol reference or constant expression.
1276 const MCExpr *IdVal;
1277 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1278 if (parseRelocOperand(IdVal))
1281 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1283 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1285 } // case AsmToken::Percent
1286 } // switch(getLexer().getKind())
1290 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1291 StringRef RelocStr) {
1293 // Check the type of the expression.
1294 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1295 // It's a constant, evaluate lo or hi value.
1296 if (RelocStr == "lo") {
1297 short Val = MCE->getValue();
1298 Res = MCConstantExpr::Create(Val, getContext());
1299 } else if (RelocStr == "hi") {
1300 int Val = MCE->getValue();
1301 int LoSign = Val & 0x8000;
1302 Val = (Val & 0xffff0000) >> 16;
1303 // Lower part is treated as a signed int, so if it is negative
1304 // we must add 1 to the hi part to compensate.
1307 Res = MCConstantExpr::Create(Val, getContext());
1309 llvm_unreachable("Invalid RelocStr value");
1314 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1315 // It's a symbol, create a symbolic expression from the symbol.
1316 StringRef Symbol = MSRE->getSymbol().getName();
1317 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1318 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1322 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1323 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1325 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1326 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1327 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1328 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1329 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1330 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1331 return MipsMCExpr::CreateHi(Expr, getContext());
1332 return MipsMCExpr::CreateLo(Expr, getContext());
1335 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1336 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1337 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1341 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1342 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1343 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1346 // Just return the original expression.
1350 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1352 switch (Expr->getKind()) {
1353 case MCExpr::Constant:
1355 case MCExpr::SymbolRef:
1356 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1357 case MCExpr::Binary:
1358 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1359 if (!isEvaluated(BE->getLHS()))
1361 return isEvaluated(BE->getRHS());
1364 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1365 case MCExpr::Target:
1371 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1372 Parser.Lex(); // Eat the % token.
1373 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1374 if (Tok.isNot(AsmToken::Identifier))
1377 std::string Str = Tok.getIdentifier().str();
1379 Parser.Lex(); // Eat the identifier.
1380 // Now make an expression from the rest of the operand.
1381 const MCExpr *IdVal;
1384 if (getLexer().getKind() == AsmToken::LParen) {
1386 Parser.Lex(); // Eat the '(' token.
1387 if (getLexer().getKind() == AsmToken::Percent) {
1388 Parser.Lex(); // Eat the % token.
1389 const AsmToken &nextTok = Parser.getTok();
1390 if (nextTok.isNot(AsmToken::Identifier))
1393 Str += nextTok.getIdentifier();
1394 Parser.Lex(); // Eat the identifier.
1395 if (getLexer().getKind() != AsmToken::LParen)
1400 if (getParser().parseParenExpression(IdVal, EndLoc))
1403 while (getLexer().getKind() == AsmToken::RParen)
1404 Parser.Lex(); // Eat the ')' token.
1407 return true; // Parenthesis must follow the relocation operand.
1409 Res = evaluateRelocExpr(IdVal, Str);
1413 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1415 StartLoc = Parser.getTok().getLoc();
1416 RegNo = tryParseRegister(isMips64());
1417 EndLoc = Parser.getTok().getLoc();
1418 return (RegNo == (unsigned)-1);
1421 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1425 while (getLexer().getKind() == AsmToken::LParen)
1428 switch (getLexer().getKind()) {
1431 case AsmToken::Identifier:
1432 case AsmToken::LParen:
1433 case AsmToken::Integer:
1434 case AsmToken::Minus:
1435 case AsmToken::Plus:
1437 Result = getParser().parseParenExpression(Res, S);
1439 Result = (getParser().parseExpression(Res));
1440 while (getLexer().getKind() == AsmToken::RParen)
1443 case AsmToken::Percent:
1444 Result = parseRelocOperand(Res);
1449 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1450 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1452 const MCExpr *IdVal = 0;
1454 bool isParenExpr = false;
1455 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1456 // First operand is the offset.
1457 S = Parser.getTok().getLoc();
1459 if (getLexer().getKind() == AsmToken::LParen) {
1464 if (getLexer().getKind() != AsmToken::Dollar) {
1465 if (parseMemOffset(IdVal, isParenExpr))
1466 return MatchOperand_ParseFail;
1468 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1469 if (Tok.isNot(AsmToken::LParen)) {
1470 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1471 if (Mnemonic->getToken() == "la") {
1473 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1474 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1475 return MatchOperand_Success;
1477 if (Tok.is(AsmToken::EndOfStatement)) {
1479 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1481 // Zero register assumed, add a memory operand with ZERO as its base.
1482 Operands.push_back(MipsOperand::CreateMem(
1483 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
1484 return MatchOperand_Success;
1486 Error(Parser.getTok().getLoc(), "'(' expected");
1487 return MatchOperand_ParseFail;
1490 Parser.Lex(); // Eat the '(' token.
1493 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1494 : (int)MipsOperand::Kind_GPR32);
1495 if (Res != MatchOperand_Success)
1498 if (Parser.getTok().isNot(AsmToken::RParen)) {
1499 Error(Parser.getTok().getLoc(), "')' expected");
1500 return MatchOperand_ParseFail;
1503 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1505 Parser.Lex(); // Eat the ')' token.
1508 IdVal = MCConstantExpr::Create(0, getContext());
1510 // Replace the register operand with the memory operand.
1511 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1512 int RegNo = op->getReg();
1513 // Remove the register from the operands.
1514 Operands.pop_back();
1515 // Add the memory operand.
1516 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1518 if (IdVal->EvaluateAsAbsolute(Imm))
1519 IdVal = MCConstantExpr::Create(Imm, getContext());
1520 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1521 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1525 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1527 return MatchOperand_Success;
1530 bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1532 // If the first token is not '$' we have an error.
1533 if (Parser.getTok().isNot(AsmToken::Dollar))
1536 SMLoc S = Parser.getTok().getLoc();
1538 AsmToken::TokenKind TkKind = getLexer().getKind();
1541 if (TkKind == AsmToken::Integer) {
1542 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1543 regKindToRegClass(RegKind));
1546 } else if (TkKind == AsmToken::Identifier) {
1547 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1549 Reg = getReg(regKindToRegClass(RegKind), Reg);
1554 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1555 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1556 Operands.push_back(Op);
1561 MipsAsmParser::OperandMatchResultTy
1562 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1563 MipsOperand::RegisterKind RegKind =
1564 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1566 // Parse index register.
1567 if (!parsePtrReg(Operands, RegKind))
1568 return MatchOperand_NoMatch;
1571 if (Parser.getTok().isNot(AsmToken::LParen))
1572 return MatchOperand_NoMatch;
1574 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1577 // Parse base register.
1578 if (!parsePtrReg(Operands, RegKind))
1579 return MatchOperand_NoMatch;
1582 if (Parser.getTok().isNot(AsmToken::RParen))
1583 return MatchOperand_NoMatch;
1585 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1588 return MatchOperand_Success;
1591 MipsAsmParser::OperandMatchResultTy
1592 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1594 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1595 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1596 if (searchSymbolAlias(Operands, Kind))
1597 return MatchOperand_Success;
1598 return MatchOperand_NoMatch;
1600 SMLoc S = Parser.getTok().getLoc();
1601 // If the first token is not '$', we have an error.
1602 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1603 return MatchOperand_NoMatch;
1604 if (!hasConsumedDollar) {
1605 Parser.Lex(); // Eat the '$'
1606 hasConsumedDollar = true;
1608 if (getLexer().getKind() == AsmToken::Identifier) {
1610 std::string RegName = Parser.getTok().getString().lower();
1611 // Match register by name
1613 case MipsOperand::Kind_GPR32:
1614 case MipsOperand::Kind_GPR64:
1615 RegNum = matchCPURegisterName(RegName);
1617 case MipsOperand::Kind_AFGR64Regs:
1618 case MipsOperand::Kind_FGR64Regs:
1619 case MipsOperand::Kind_FGR32Regs:
1620 case MipsOperand::Kind_FGRH32Regs:
1621 RegNum = matchFPURegisterName(RegName);
1622 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1624 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1625 if (RegNum != -1 && RegNum % 2 != 0)
1626 Warning(S, "Float register should be even.");
1628 case MipsOperand::Kind_FCCRegs:
1629 RegNum = matchFCCRegisterName(RegName);
1631 case MipsOperand::Kind_ACC64DSP:
1632 RegNum = matchACRegisterName(RegName);
1635 break; // No match, value is set to -1.
1637 // No match found, return _NoMatch to give a chance to other round.
1639 return MatchOperand_NoMatch;
1641 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1643 return MatchOperand_NoMatch;
1646 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1647 Op->setRegKind(Kind);
1648 Operands.push_back(Op);
1649 hasConsumedDollar = false;
1650 Parser.Lex(); // Eat the register name.
1651 return MatchOperand_Success;
1652 } else if (getLexer().getKind() == AsmToken::Integer) {
1653 unsigned RegNum = Parser.getTok().getIntVal();
1654 if (Kind == MipsOperand::Kind_HWRegs) {
1656 return MatchOperand_NoMatch;
1657 // Only hwreg 29 is supported, found at index 0.
1660 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1662 return MatchOperand_NoMatch;
1663 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1664 Op->setRegKind(Kind);
1665 Operands.push_back(Op);
1666 hasConsumedDollar = false;
1667 Parser.Lex(); // Eat the register number.
1668 if ((RegKind == MipsOperand::Kind_GPR32) &&
1669 (getLexer().is(AsmToken::LParen))) {
1670 // Check if it is indexed addressing operand.
1671 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1672 Parser.Lex(); // Eat the parenthesis.
1673 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1674 return MatchOperand_NoMatch;
1675 if (getLexer().isNot(AsmToken::RParen))
1676 return MatchOperand_NoMatch;
1677 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1680 return MatchOperand_Success;
1682 return MatchOperand_NoMatch;
1685 bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1686 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1694 case MipsOperand::Kind_MSA128BRegs:
1696 case MipsOperand::Kind_MSA128HRegs:
1698 case MipsOperand::Kind_MSA128WRegs:
1700 case MipsOperand::Kind_MSA128DRegs:
1705 MipsAsmParser::OperandMatchResultTy
1706 MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1708 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1709 SMLoc S = Parser.getTok().getLoc();
1710 std::string RegName;
1712 if (Parser.getTok().isNot(AsmToken::Dollar))
1713 return MatchOperand_NoMatch;
1717 return MatchOperand_ParseFail;
1718 case MipsOperand::Kind_MSA128BRegs:
1719 case MipsOperand::Kind_MSA128HRegs:
1720 case MipsOperand::Kind_MSA128WRegs:
1721 case MipsOperand::Kind_MSA128DRegs:
1725 Parser.Lex(); // Eat the '$'.
1726 if (getLexer().getKind() == AsmToken::Identifier)
1727 RegName = Parser.getTok().getString().lower();
1729 return MatchOperand_ParseFail;
1731 int RegNum = matchMSA128RegisterName(RegName);
1733 if (RegNum < 0 || RegNum > 31)
1734 return MatchOperand_ParseFail;
1736 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1738 return MatchOperand_ParseFail;
1740 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1741 Op->setRegKind(Kind);
1742 Operands.push_back(Op);
1744 Parser.Lex(); // Eat the register identifier.
1746 // MSA registers may be suffixed with an index in the form of:
1747 // 1) Immediate expression.
1748 // 2) General Purpose Register.
1750 // 1) copy_s.b $29,$w0[0]
1751 // 2) sld.b $w0,$w1[$1]
1753 if (Parser.getTok().isNot(AsmToken::LBrac))
1754 return MatchOperand_Success;
1756 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1758 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1759 Parser.Lex(); // Parse the '[' token.
1761 if (Parser.getTok().is(AsmToken::Dollar)) {
1762 // This must be a GPR.
1764 SMLoc VIdx = Parser.getTok().getLoc();
1765 Parser.Lex(); // Parse the '$' token.
1767 // GPR have aliases and we must account for that. Example: $30 == $fp
1768 if (getLexer().getKind() == AsmToken::Integer) {
1769 unsigned RegNum = Parser.getTok().getIntVal();
1770 int Reg = matchRegisterByNumber(
1771 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1773 Error(VIdx, "invalid general purpose register");
1774 return MatchOperand_ParseFail;
1777 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1778 } else if (getLexer().getKind() == AsmToken::Identifier) {
1780 std::string RegName = Parser.getTok().getString().lower();
1782 RegNum = matchCPURegisterName(RegName);
1784 Error(VIdx, "general purpose register expected");
1785 return MatchOperand_ParseFail;
1787 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1788 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1790 return MatchOperand_ParseFail;
1792 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1793 Operands.push_back(RegOp);
1794 Parser.Lex(); // Eat the register identifier.
1796 if (Parser.getTok().isNot(AsmToken::RBrac))
1797 return MatchOperand_ParseFail;
1799 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1800 Parser.Lex(); // Parse the ']' token.
1802 return MatchOperand_Success;
1805 // The index must be a constant expression then.
1806 SMLoc VIdx = Parser.getTok().getLoc();
1807 const MCExpr *ImmVal;
1809 if (getParser().parseExpression(ImmVal))
1810 return MatchOperand_ParseFail;
1812 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1813 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1814 Error(VIdx, "invalid immediate value");
1815 return MatchOperand_ParseFail;
1818 SMLoc E = Parser.getTok().getEndLoc();
1820 if (Parser.getTok().isNot(AsmToken::RBrac))
1821 return MatchOperand_ParseFail;
1824 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1825 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1827 // The second vector index of insve instructions is always 0.
1828 if (insve && Operands.size() > 6) {
1829 if (expr->getValue() != 0) {
1830 Error(VIdx, "immediate value must be 0");
1831 return MatchOperand_ParseFail;
1833 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1835 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1837 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1839 Parser.Lex(); // Parse the ']' token.
1841 return MatchOperand_Success;
1844 MipsAsmParser::OperandMatchResultTy
1845 MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1847 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1849 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1850 return MatchOperand_NoMatch;
1852 if (Parser.getTok().isNot(AsmToken::Dollar))
1853 return MatchOperand_ParseFail;
1855 SMLoc S = Parser.getTok().getLoc();
1857 Parser.Lex(); // Eat the '$' symbol.
1860 if (getLexer().getKind() == AsmToken::Identifier)
1861 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1862 else if (getLexer().getKind() == AsmToken::Integer)
1863 RegNum = Parser.getTok().getIntVal();
1865 return MatchOperand_ParseFail;
1867 if (RegNum < 0 || RegNum > 7)
1868 return MatchOperand_ParseFail;
1870 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1872 return MatchOperand_ParseFail;
1874 MipsOperand *RegOp =
1875 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1876 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1877 Operands.push_back(RegOp);
1878 Parser.Lex(); // Eat the register identifier.
1880 return MatchOperand_Success;
1883 MipsAsmParser::OperandMatchResultTy
1884 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1887 return MatchOperand_NoMatch;
1888 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1891 MipsAsmParser::OperandMatchResultTy
1892 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1893 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1896 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1897 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1900 return MatchOperand_NoMatch;
1901 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1904 MipsAsmParser::OperandMatchResultTy
1905 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1907 return MatchOperand_NoMatch;
1908 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1911 MipsAsmParser::OperandMatchResultTy
1912 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1913 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1916 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1917 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1918 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
1921 MipsAsmParser::OperandMatchResultTy
1922 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1923 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
1926 MipsAsmParser::OperandMatchResultTy
1927 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1928 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
1931 MipsAsmParser::OperandMatchResultTy
1932 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1933 // If the first token is not '$' we have an error.
1934 if (Parser.getTok().isNot(AsmToken::Dollar))
1935 return MatchOperand_NoMatch;
1937 SMLoc S = Parser.getTok().getLoc();
1938 Parser.Lex(); // Eat the '$'
1940 const AsmToken &Tok = Parser.getTok(); // Get next token.
1942 if (Tok.isNot(AsmToken::Identifier))
1943 return MatchOperand_NoMatch;
1945 if (!Tok.getIdentifier().startswith("ac"))
1946 return MatchOperand_NoMatch;
1948 StringRef NumString = Tok.getIdentifier().substr(2);
1951 if (NumString.getAsInteger(10, IntVal))
1952 return MatchOperand_NoMatch;
1954 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1956 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1957 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1958 Operands.push_back(Op);
1960 Parser.Lex(); // Eat the register number.
1961 return MatchOperand_Success;
1964 MipsAsmParser::OperandMatchResultTy
1965 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1966 // If the first token is not '$' we have an error.
1967 if (Parser.getTok().isNot(AsmToken::Dollar))
1968 return MatchOperand_NoMatch;
1970 SMLoc S = Parser.getTok().getLoc();
1971 Parser.Lex(); // Eat the '$'
1973 const AsmToken &Tok = Parser.getTok(); // Get next token.
1975 if (Tok.isNot(AsmToken::Identifier))
1976 return MatchOperand_NoMatch;
1978 if (!Tok.getIdentifier().startswith("ac"))
1979 return MatchOperand_NoMatch;
1981 StringRef NumString = Tok.getIdentifier().substr(2);
1984 if (NumString.getAsInteger(10, IntVal))
1985 return MatchOperand_NoMatch;
1987 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1989 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1990 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1991 Operands.push_back(Op);
1993 Parser.Lex(); // Eat the register number.
1994 return MatchOperand_Success;
1997 MipsAsmParser::OperandMatchResultTy
1998 MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1999 // If the first token is not '$' we have an error.
2000 if (Parser.getTok().isNot(AsmToken::Dollar))
2001 return MatchOperand_NoMatch;
2003 SMLoc S = Parser.getTok().getLoc();
2004 Parser.Lex(); // Eat the '$'
2006 const AsmToken &Tok = Parser.getTok(); // Get next token.
2008 if (Tok.isNot(AsmToken::Integer))
2009 return MatchOperand_NoMatch;
2011 unsigned IntVal = Tok.getIntVal();
2013 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2015 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2016 Op->setRegKind(MipsOperand::Kind_COP2);
2017 Operands.push_back(Op);
2019 Parser.Lex(); // Eat the register number.
2020 return MatchOperand_Success;
2023 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2024 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2025 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
2028 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2029 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2030 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
2033 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2034 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2035 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
2038 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2039 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2040 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
2043 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2044 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2045 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
2048 bool MipsAsmParser::searchSymbolAlias(
2049 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
2051 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2053 SMLoc S = Parser.getTok().getLoc();
2055 if (Sym->isVariable())
2056 Expr = Sym->getVariableValue();
2059 if (Expr->getKind() == MCExpr::SymbolRef) {
2060 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2061 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2062 const StringRef DefSymbol = Ref->getSymbol().getName();
2063 if (DefSymbol.startswith("$")) {
2065 APInt IntVal(32, -1);
2066 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2067 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
2068 isMips64() ? Mips::GPR64RegClassID
2069 : Mips::GPR32RegClassID);
2071 // Lookup for the register with the corresponding name.
2073 case MipsOperand::Kind_AFGR64Regs:
2074 case MipsOperand::Kind_FGR64Regs:
2075 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2077 case MipsOperand::Kind_FGR32Regs:
2078 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2080 case MipsOperand::Kind_GPR64:
2081 case MipsOperand::Kind_GPR32:
2083 RegNum = matchCPURegisterName(DefSymbol.substr(1));
2087 RegNum = getReg(regKindToRegClass(Kind), RegNum);
2092 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
2093 op->setRegKind(Kind);
2094 Operands.push_back(op);
2098 } else if (Expr->getKind() == MCExpr::Constant) {
2100 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2102 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
2103 Operands.push_back(op);
2110 MipsAsmParser::OperandMatchResultTy
2111 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2112 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
2115 MipsAsmParser::OperandMatchResultTy
2116 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2117 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
2120 MipsAsmParser::OperandMatchResultTy
2121 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2122 const MCExpr *IdVal;
2123 // If the first token is '$' we may have register operand.
2124 if (Parser.getTok().is(AsmToken::Dollar))
2125 return MatchOperand_NoMatch;
2126 SMLoc S = Parser.getTok().getLoc();
2127 if (getParser().parseExpression(IdVal))
2128 return MatchOperand_ParseFail;
2129 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2130 assert(MCE && "Unexpected MCExpr type.");
2131 int64_t Val = MCE->getValue();
2132 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2133 Operands.push_back(MipsOperand::CreateImm(
2134 MCConstantExpr::Create(0 - Val, getContext()), S, E));
2135 return MatchOperand_Success;
2138 MipsAsmParser::OperandMatchResultTy
2139 MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2140 switch (getLexer().getKind()) {
2142 return MatchOperand_NoMatch;
2143 case AsmToken::LParen:
2144 case AsmToken::Plus:
2145 case AsmToken::Minus:
2146 case AsmToken::Integer:
2151 SMLoc S = Parser.getTok().getLoc();
2153 if (getParser().parseExpression(Expr))
2154 return MatchOperand_ParseFail;
2157 if (!Expr->EvaluateAsAbsolute(Val)) {
2158 Error(S, "expected immediate value");
2159 return MatchOperand_ParseFail;
2162 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2163 // and because the CPU always adds one to the immediate field, the allowed
2164 // range becomes 1..4. We'll only check the range here and will deal
2165 // with the addition/subtraction when actually decoding/encoding
2167 if (Val < 1 || Val > 4) {
2168 Error(S, "immediate not in range (1..4)");
2169 return MatchOperand_ParseFail;
2173 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
2174 return MatchOperand_Success;
2177 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2179 MCSymbolRefExpr::VariantKind VK =
2180 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2181 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2182 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2183 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2184 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2185 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2186 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2187 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2188 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2189 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2190 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2191 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2192 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2193 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2194 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2195 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2196 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2197 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2198 .Default(MCSymbolRefExpr::VK_None);
2203 bool MipsAsmParser::ParseInstruction(
2204 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2205 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2206 // Check if we have valid mnemonic
2207 if (!mnemonicIsValid(Name, 0)) {
2208 Parser.eatToEndOfStatement();
2209 return Error(NameLoc, "Unknown instruction");
2211 // First operand in MCInst is instruction mnemonic.
2212 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2214 // Read the remaining operands.
2215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2216 // Read the first operand.
2217 if (ParseOperand(Operands, Name)) {
2218 SMLoc Loc = getLexer().getLoc();
2219 Parser.eatToEndOfStatement();
2220 return Error(Loc, "unexpected token in argument list");
2223 while (getLexer().is(AsmToken::Comma)) {
2224 Parser.Lex(); // Eat the comma.
2225 // Parse and remember the operand.
2226 if (ParseOperand(Operands, Name)) {
2227 SMLoc Loc = getLexer().getLoc();
2228 Parser.eatToEndOfStatement();
2229 return Error(Loc, "unexpected token in argument list");
2233 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2234 SMLoc Loc = getLexer().getLoc();
2235 Parser.eatToEndOfStatement();
2236 return Error(Loc, "unexpected token in argument list");
2238 Parser.Lex(); // Consume the EndOfStatement.
2242 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2243 SMLoc Loc = getLexer().getLoc();
2244 Parser.eatToEndOfStatement();
2245 return Error(Loc, ErrorMsg);
2248 bool MipsAsmParser::parseSetNoAtDirective() {
2249 // Line should look like: ".set noat".
2251 Options.setATReg(0);
2254 // If this is not the end of the statement, report an error.
2255 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2256 reportParseError("unexpected token in statement");
2259 Parser.Lex(); // Consume the EndOfStatement.
2263 bool MipsAsmParser::parseSetAtDirective() {
2264 // Line can be .set at - defaults to $1
2268 if (getLexer().is(AsmToken::EndOfStatement)) {
2269 Options.setATReg(1);
2270 Parser.Lex(); // Consume the EndOfStatement.
2272 } else if (getLexer().is(AsmToken::Equal)) {
2273 getParser().Lex(); // Eat the '='.
2274 if (getLexer().isNot(AsmToken::Dollar)) {
2275 reportParseError("unexpected token in statement");
2278 Parser.Lex(); // Eat the '$'.
2279 const AsmToken &Reg = Parser.getTok();
2280 if (Reg.is(AsmToken::Identifier)) {
2281 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2282 } else if (Reg.is(AsmToken::Integer)) {
2283 AtRegNo = Reg.getIntVal();
2285 reportParseError("unexpected token in statement");
2289 if (AtRegNo < 1 || AtRegNo > 31) {
2290 reportParseError("unexpected token in statement");
2294 if (!Options.setATReg(AtRegNo)) {
2295 reportParseError("unexpected token in statement");
2298 getParser().Lex(); // Eat the register.
2300 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2301 reportParseError("unexpected token in statement");
2304 Parser.Lex(); // Consume the EndOfStatement.
2307 reportParseError("unexpected token in statement");
2312 bool MipsAsmParser::parseSetReorderDirective() {
2314 // If this is not the end of the statement, report an error.
2315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2316 reportParseError("unexpected token in statement");
2319 Options.setReorder();
2320 Parser.Lex(); // Consume the EndOfStatement.
2324 bool MipsAsmParser::parseSetNoReorderDirective() {
2326 // If this is not the end of the statement, report an error.
2327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2328 reportParseError("unexpected token in statement");
2331 Options.setNoreorder();
2332 getTargetStreamer().emitDirectiveSetNoReorder();
2333 Parser.Lex(); // Consume the EndOfStatement.
2337 bool MipsAsmParser::parseSetMacroDirective() {
2339 // If this is not the end of the statement, report an error.
2340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2341 reportParseError("unexpected token in statement");
2345 Parser.Lex(); // Consume the EndOfStatement.
2349 bool MipsAsmParser::parseSetNoMacroDirective() {
2351 // If this is not the end of the statement, report an error.
2352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2353 reportParseError("`noreorder' must be set before `nomacro'");
2356 if (Options.isReorder()) {
2357 reportParseError("`noreorder' must be set before `nomacro'");
2360 Options.setNomacro();
2361 Parser.Lex(); // Consume the EndOfStatement.
2365 bool MipsAsmParser::parseSetMips16Directive() {
2367 // If this is not the end of the statement, report an error.
2368 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2369 reportParseError("unexpected token in statement");
2372 getTargetStreamer().emitDirectiveSetMips16();
2373 Parser.Lex(); // Consume the EndOfStatement.
2377 bool MipsAsmParser::parseSetNoMips16Directive() {
2379 // If this is not the end of the statement, report an error.
2380 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2381 reportParseError("unexpected token in statement");
2384 // For now do nothing.
2385 Parser.Lex(); // Consume the EndOfStatement.
2389 bool MipsAsmParser::parseSetAssignment() {
2391 const MCExpr *Value;
2393 if (Parser.parseIdentifier(Name))
2394 reportParseError("expected identifier after .set");
2396 if (getLexer().isNot(AsmToken::Comma))
2397 return reportParseError("unexpected token in .set directive");
2400 if (Parser.parseExpression(Value))
2401 return reportParseError("expected valid expression after comma");
2403 // Check if the Name already exists as a symbol.
2404 MCSymbol *Sym = getContext().LookupSymbol(Name);
2406 return reportParseError("symbol already defined");
2407 Sym = getContext().GetOrCreateSymbol(Name);
2408 Sym->setVariableValue(Value);
2413 bool MipsAsmParser::parseDirectiveSet() {
2415 // Get the next token.
2416 const AsmToken &Tok = Parser.getTok();
2418 if (Tok.getString() == "noat") {
2419 return parseSetNoAtDirective();
2420 } else if (Tok.getString() == "at") {
2421 return parseSetAtDirective();
2422 } else if (Tok.getString() == "reorder") {
2423 return parseSetReorderDirective();
2424 } else if (Tok.getString() == "noreorder") {
2425 return parseSetNoReorderDirective();
2426 } else if (Tok.getString() == "macro") {
2427 return parseSetMacroDirective();
2428 } else if (Tok.getString() == "nomacro") {
2429 return parseSetNoMacroDirective();
2430 } else if (Tok.getString() == "mips16") {
2431 return parseSetMips16Directive();
2432 } else if (Tok.getString() == "nomips16") {
2433 return parseSetNoMips16Directive();
2434 } else if (Tok.getString() == "nomicromips") {
2435 getTargetStreamer().emitDirectiveSetNoMicroMips();
2436 Parser.eatToEndOfStatement();
2438 } else if (Tok.getString() == "micromips") {
2439 getTargetStreamer().emitDirectiveSetMicroMips();
2440 Parser.eatToEndOfStatement();
2443 // It is just an identifier, look for an assignment.
2444 parseSetAssignment();
2451 /// parseDirectiveWord
2452 /// ::= .word [ expression (, expression)* ]
2453 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2454 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2456 const MCExpr *Value;
2457 if (getParser().parseExpression(Value))
2460 getParser().getStreamer().EmitValue(Value, Size);
2462 if (getLexer().is(AsmToken::EndOfStatement))
2465 // FIXME: Improve diagnostic.
2466 if (getLexer().isNot(AsmToken::Comma))
2467 return Error(L, "unexpected token in directive");
2476 /// parseDirectiveGpWord
2477 /// ::= .gpword local_sym
2478 bool MipsAsmParser::parseDirectiveGpWord() {
2479 const MCExpr *Value;
2480 // EmitGPRel32Value requires an expression, so we are using base class
2481 // method to evaluate the expression.
2482 if (getParser().parseExpression(Value))
2484 getParser().getStreamer().EmitGPRel32Value(Value);
2486 if (getLexer().isNot(AsmToken::EndOfStatement))
2487 return Error(getLexer().getLoc(), "unexpected token in directive");
2488 Parser.Lex(); // Eat EndOfStatement token.
2492 bool MipsAsmParser::parseDirectiveOption() {
2493 // Get the option token.
2494 AsmToken Tok = Parser.getTok();
2495 // At the moment only identifiers are supported.
2496 if (Tok.isNot(AsmToken::Identifier)) {
2497 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2498 Parser.eatToEndOfStatement();
2502 StringRef Option = Tok.getIdentifier();
2504 if (Option == "pic0") {
2505 getTargetStreamer().emitDirectiveOptionPic0();
2507 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2508 Error(Parser.getTok().getLoc(),
2509 "unexpected token in .option pic0 directive");
2510 Parser.eatToEndOfStatement();
2516 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2517 Parser.eatToEndOfStatement();
2521 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2522 StringRef IDVal = DirectiveID.getString();
2524 if (IDVal == ".ent") {
2525 // Ignore this directive for now.
2530 if (IDVal == ".end") {
2531 // Ignore this directive for now.
2536 if (IDVal == ".frame") {
2537 // Ignore this directive for now.
2538 Parser.eatToEndOfStatement();
2542 if (IDVal == ".set") {
2543 return parseDirectiveSet();
2546 if (IDVal == ".fmask") {
2547 // Ignore this directive for now.
2548 Parser.eatToEndOfStatement();
2552 if (IDVal == ".mask") {
2553 // Ignore this directive for now.
2554 Parser.eatToEndOfStatement();
2558 if (IDVal == ".gpword") {
2559 // Ignore this directive for now.
2560 parseDirectiveGpWord();
2564 if (IDVal == ".word") {
2565 parseDirectiveWord(4, DirectiveID.getLoc());
2569 if (IDVal == ".option")
2570 return parseDirectiveOption();
2572 if (IDVal == ".abicalls") {
2573 getTargetStreamer().emitDirectiveAbiCalls();
2574 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2575 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2577 Parser.eatToEndOfStatement();
2585 extern "C" void LLVMInitializeMipsAsmParser() {
2586 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2587 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2588 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2589 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2592 #define GET_REGISTER_MATCHER
2593 #define GET_MATCHER_IMPLEMENTATION
2594 #include "MipsGenAsmMatcher.inc"