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/APInt.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/MC/MCTargetAsmParser.h"
24 #include "llvm/Support/ELF.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/ADT/APInt.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/TargetRegistry.h"
37 class MipsAssemblerOptions {
39 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
41 unsigned getATRegNum() { return aTReg; }
42 bool setATReg(unsigned Reg);
44 bool isReorder() { return reorder; }
45 void setReorder() { reorder = true; }
46 void setNoreorder() { reorder = false; }
48 bool isMacro() { return macro; }
49 void setMacro() { macro = true; }
50 void setNomacro() { macro = false; }
60 class MipsAsmParser : public MCTargetAsmParser {
62 MipsTargetStreamer &getTargetStreamer() {
63 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
64 return static_cast<MipsTargetStreamer &>(TS);
69 MipsAssemblerOptions Options;
70 bool hasConsumedDollar;
72 #define GET_ASSEMBLER_HEADER
73 #include "MipsGenAsmMatcher.inc"
75 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
76 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
77 MCStreamer &Out, unsigned &ErrorInfo,
78 bool MatchingInlineAsm);
80 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
82 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
84 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
86 bool ParseDirective(AsmToken DirectiveID);
88 MipsAsmParser::OperandMatchResultTy
89 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
91 MipsAsmParser::OperandMatchResultTy
92 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
94 MipsAsmParser::OperandMatchResultTy
95 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
98 MipsAsmParser::OperandMatchResultTy
99 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
101 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
104 MipsAsmParser::OperandMatchResultTy
105 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
107 MipsAsmParser::OperandMatchResultTy
108 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
110 MipsAsmParser::OperandMatchResultTy
111 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
113 MipsAsmParser::OperandMatchResultTy
114 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
116 MipsAsmParser::OperandMatchResultTy
117 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
119 MipsAsmParser::OperandMatchResultTy
120 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
122 MipsAsmParser::OperandMatchResultTy
123 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
125 MipsAsmParser::OperandMatchResultTy
126 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
128 MipsAsmParser::OperandMatchResultTy
129 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
131 MipsAsmParser::OperandMatchResultTy
132 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
134 MipsAsmParser::OperandMatchResultTy
135 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
137 MipsAsmParser::OperandMatchResultTy
138 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
140 MipsAsmParser::OperandMatchResultTy
141 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
143 MipsAsmParser::OperandMatchResultTy
144 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
146 MipsAsmParser::OperandMatchResultTy
147 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
152 MipsAsmParser::OperandMatchResultTy
153 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
155 MipsAsmParser::OperandMatchResultTy
156 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
158 MipsAsmParser::OperandMatchResultTy
159 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
161 MipsAsmParser::OperandMatchResultTy
162 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
164 MipsAsmParser::OperandMatchResultTy
165 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
167 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
170 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
173 int tryParseRegister(bool is64BitReg);
175 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
178 bool needsExpansion(MCInst &Inst);
180 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
182 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
184 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
186 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
188 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
191 bool reportParseError(StringRef ErrorMsg);
193 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
194 bool parseRelocOperand(const MCExpr *&Res);
196 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
198 bool isEvaluated(const MCExpr *Expr);
199 bool parseDirectiveSet();
200 bool parseDirectiveOption();
202 bool parseSetAtDirective();
203 bool parseSetNoAtDirective();
204 bool parseSetMacroDirective();
205 bool parseSetNoMacroDirective();
206 bool parseSetReorderDirective();
207 bool parseSetNoReorderDirective();
208 bool parseSetMips16Directive();
209 bool parseSetNoMips16Directive();
211 bool parseSetAssignment();
213 bool parseDirectiveWord(unsigned Size, SMLoc L);
214 bool parseDirectiveGpWord();
216 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
218 bool isMips64() const {
219 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
222 bool isFP64() const {
223 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
226 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
228 bool isMicroMips() const {
229 return STI.getFeatureBits() & Mips::FeatureMicroMips;
232 int matchRegisterName(StringRef Symbol, bool is64BitReg);
234 int matchCPURegisterName(StringRef Symbol);
236 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
238 int matchFPURegisterName(StringRef Name);
240 int matchFCCRegisterName(StringRef Name);
242 int matchACRegisterName(StringRef Name);
244 int matchMSA128RegisterName(StringRef Name);
246 int matchMSA128CtrlRegisterName(StringRef Name);
248 int regKindToRegClass(int RegKind);
250 unsigned getReg(int RC, int RegNo);
254 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
255 SmallVectorImpl<MCInst> &Instructions);
257 // Helper function that checks if the value of a vector index is within the
258 // boundaries of accepted values for each RegisterKind
259 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
260 bool validateMSAIndex(int Val, int RegKind);
262 // Set ELF flags based on defaults and commandline arguments.
263 void processInitialEFlags();
266 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
267 const MCInstrInfo &MII)
268 : MCTargetAsmParser(), STI(sti), Parser(parser),
269 hasConsumedDollar(false) {
270 // Initialize the set of available features.
271 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
272 processInitialEFlags();
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]);
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 assigne 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 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1324 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1325 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1329 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1330 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1331 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1334 // Just return the original expression.
1338 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1340 switch (Expr->getKind()) {
1341 case MCExpr::Constant:
1343 case MCExpr::SymbolRef:
1344 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1345 case MCExpr::Binary:
1346 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1347 if (!isEvaluated(BE->getLHS()))
1349 return isEvaluated(BE->getRHS());
1352 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1359 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1360 Parser.Lex(); // Eat the % token.
1361 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1362 if (Tok.isNot(AsmToken::Identifier))
1365 std::string Str = Tok.getIdentifier().str();
1367 Parser.Lex(); // Eat the identifier.
1368 // Now make an expression from the rest of the operand.
1369 const MCExpr *IdVal;
1372 if (getLexer().getKind() == AsmToken::LParen) {
1374 Parser.Lex(); // Eat the '(' token.
1375 if (getLexer().getKind() == AsmToken::Percent) {
1376 Parser.Lex(); // Eat the % token.
1377 const AsmToken &nextTok = Parser.getTok();
1378 if (nextTok.isNot(AsmToken::Identifier))
1381 Str += nextTok.getIdentifier();
1382 Parser.Lex(); // Eat the identifier.
1383 if (getLexer().getKind() != AsmToken::LParen)
1388 if (getParser().parseParenExpression(IdVal, EndLoc))
1391 while (getLexer().getKind() == AsmToken::RParen)
1392 Parser.Lex(); // Eat the ')' token.
1395 return true; // Parenthesis must follow the relocation operand.
1397 Res = evaluateRelocExpr(IdVal, Str);
1401 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1403 StartLoc = Parser.getTok().getLoc();
1404 RegNo = tryParseRegister(isMips64());
1405 EndLoc = Parser.getTok().getLoc();
1406 return (RegNo == (unsigned)-1);
1409 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1413 while (getLexer().getKind() == AsmToken::LParen)
1416 switch (getLexer().getKind()) {
1419 case AsmToken::Identifier:
1420 case AsmToken::LParen:
1421 case AsmToken::Integer:
1422 case AsmToken::Minus:
1423 case AsmToken::Plus:
1425 Result = getParser().parseParenExpression(Res, S);
1427 Result = (getParser().parseExpression(Res));
1428 while (getLexer().getKind() == AsmToken::RParen)
1431 case AsmToken::Percent:
1432 Result = parseRelocOperand(Res);
1437 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1438 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1440 const MCExpr *IdVal = 0;
1442 bool isParenExpr = false;
1443 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1444 // First operand is the offset.
1445 S = Parser.getTok().getLoc();
1447 if (getLexer().getKind() == AsmToken::LParen) {
1452 if (getLexer().getKind() != AsmToken::Dollar) {
1453 if (parseMemOffset(IdVal, isParenExpr))
1454 return MatchOperand_ParseFail;
1456 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1457 if (Tok.isNot(AsmToken::LParen)) {
1458 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1459 if (Mnemonic->getToken() == "la") {
1461 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1462 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1463 return MatchOperand_Success;
1465 if (Tok.is(AsmToken::EndOfStatement)) {
1467 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1469 // Zero register assumed, add a memory operand with ZERO as its base.
1470 Operands.push_back(MipsOperand::CreateMem(
1471 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
1472 return MatchOperand_Success;
1474 Error(Parser.getTok().getLoc(), "'(' expected");
1475 return MatchOperand_ParseFail;
1478 Parser.Lex(); // Eat the '(' token.
1481 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1482 : (int)MipsOperand::Kind_GPR32);
1483 if (Res != MatchOperand_Success)
1486 if (Parser.getTok().isNot(AsmToken::RParen)) {
1487 Error(Parser.getTok().getLoc(), "')' expected");
1488 return MatchOperand_ParseFail;
1491 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1493 Parser.Lex(); // Eat the ')' token.
1496 IdVal = MCConstantExpr::Create(0, getContext());
1498 // Replace the register operand with the memory operand.
1499 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1500 int RegNo = op->getReg();
1501 // Remove the register from the operands.
1502 Operands.pop_back();
1503 // Add the memory operand.
1504 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1506 if (IdVal->EvaluateAsAbsolute(Imm))
1507 IdVal = MCConstantExpr::Create(Imm, getContext());
1508 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1509 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1513 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1515 return MatchOperand_Success;
1518 bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1520 // If the first token is not '$' we have an error.
1521 if (Parser.getTok().isNot(AsmToken::Dollar))
1524 SMLoc S = Parser.getTok().getLoc();
1526 AsmToken::TokenKind TkKind = getLexer().getKind();
1529 if (TkKind == AsmToken::Integer) {
1530 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1531 regKindToRegClass(RegKind));
1534 } else if (TkKind == AsmToken::Identifier) {
1535 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1537 Reg = getReg(regKindToRegClass(RegKind), Reg);
1542 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1543 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1544 Operands.push_back(Op);
1549 MipsAsmParser::OperandMatchResultTy
1550 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1551 MipsOperand::RegisterKind RegKind =
1552 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1554 // Parse index register.
1555 if (!parsePtrReg(Operands, RegKind))
1556 return MatchOperand_NoMatch;
1559 if (Parser.getTok().isNot(AsmToken::LParen))
1560 return MatchOperand_NoMatch;
1562 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1565 // Parse base register.
1566 if (!parsePtrReg(Operands, RegKind))
1567 return MatchOperand_NoMatch;
1570 if (Parser.getTok().isNot(AsmToken::RParen))
1571 return MatchOperand_NoMatch;
1573 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1576 return MatchOperand_Success;
1579 MipsAsmParser::OperandMatchResultTy
1580 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1582 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1583 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1584 if (searchSymbolAlias(Operands, Kind))
1585 return MatchOperand_Success;
1586 return MatchOperand_NoMatch;
1588 SMLoc S = Parser.getTok().getLoc();
1589 // If the first token is not '$', we have an error.
1590 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1591 return MatchOperand_NoMatch;
1592 if (!hasConsumedDollar) {
1593 Parser.Lex(); // Eat the '$'
1594 hasConsumedDollar = true;
1596 if (getLexer().getKind() == AsmToken::Identifier) {
1598 std::string RegName = Parser.getTok().getString().lower();
1599 // Match register by name
1601 case MipsOperand::Kind_GPR32:
1602 case MipsOperand::Kind_GPR64:
1603 RegNum = matchCPURegisterName(RegName);
1605 case MipsOperand::Kind_AFGR64Regs:
1606 case MipsOperand::Kind_FGR64Regs:
1607 case MipsOperand::Kind_FGR32Regs:
1608 case MipsOperand::Kind_FGRH32Regs:
1609 RegNum = matchFPURegisterName(RegName);
1610 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1612 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1613 if (RegNum != -1 && RegNum % 2 != 0)
1614 Warning(S, "Float register should be even.");
1616 case MipsOperand::Kind_FCCRegs:
1617 RegNum = matchFCCRegisterName(RegName);
1619 case MipsOperand::Kind_ACC64DSP:
1620 RegNum = matchACRegisterName(RegName);
1623 break; // No match, value is set to -1.
1625 // No match found, return _NoMatch to give a chance to other round.
1627 return MatchOperand_NoMatch;
1629 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1631 return MatchOperand_NoMatch;
1634 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1635 Op->setRegKind(Kind);
1636 Operands.push_back(Op);
1637 hasConsumedDollar = false;
1638 Parser.Lex(); // Eat the register name.
1639 return MatchOperand_Success;
1640 } else if (getLexer().getKind() == AsmToken::Integer) {
1641 unsigned RegNum = Parser.getTok().getIntVal();
1642 if (Kind == MipsOperand::Kind_HWRegs) {
1644 return MatchOperand_NoMatch;
1645 // Only hwreg 29 is supported, found at index 0.
1648 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1650 return MatchOperand_NoMatch;
1651 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1652 Op->setRegKind(Kind);
1653 Operands.push_back(Op);
1654 hasConsumedDollar = false;
1655 Parser.Lex(); // Eat the register number.
1656 if ((RegKind == MipsOperand::Kind_GPR32) &&
1657 (getLexer().is(AsmToken::LParen))) {
1658 // Check if it is indexed addressing operand.
1659 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1660 Parser.Lex(); // Eat the parenthesis.
1661 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1662 return MatchOperand_NoMatch;
1663 if (getLexer().isNot(AsmToken::RParen))
1664 return MatchOperand_NoMatch;
1665 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1668 return MatchOperand_Success;
1670 return MatchOperand_NoMatch;
1673 bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1674 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1682 case MipsOperand::Kind_MSA128BRegs:
1684 case MipsOperand::Kind_MSA128HRegs:
1686 case MipsOperand::Kind_MSA128WRegs:
1688 case MipsOperand::Kind_MSA128DRegs:
1693 MipsAsmParser::OperandMatchResultTy
1694 MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1696 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1697 SMLoc S = Parser.getTok().getLoc();
1698 std::string RegName;
1700 if (Parser.getTok().isNot(AsmToken::Dollar))
1701 return MatchOperand_NoMatch;
1705 return MatchOperand_ParseFail;
1706 case MipsOperand::Kind_MSA128BRegs:
1707 case MipsOperand::Kind_MSA128HRegs:
1708 case MipsOperand::Kind_MSA128WRegs:
1709 case MipsOperand::Kind_MSA128DRegs:
1713 Parser.Lex(); // Eat the '$'.
1714 if (getLexer().getKind() == AsmToken::Identifier)
1715 RegName = Parser.getTok().getString().lower();
1717 return MatchOperand_ParseFail;
1719 int RegNum = matchMSA128RegisterName(RegName);
1721 if (RegNum < 0 || RegNum > 31)
1722 return MatchOperand_ParseFail;
1724 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1726 return MatchOperand_ParseFail;
1728 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1729 Op->setRegKind(Kind);
1730 Operands.push_back(Op);
1732 Parser.Lex(); // Eat the register identifier.
1734 // MSA registers may be suffixed with an index in the form of:
1735 // 1) Immediate expression.
1736 // 2) General Purpose Register.
1738 // 1) copy_s.b $29,$w0[0]
1739 // 2) sld.b $w0,$w1[$1]
1741 if (Parser.getTok().isNot(AsmToken::LBrac))
1742 return MatchOperand_Success;
1744 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1746 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1747 Parser.Lex(); // Parse the '[' token.
1749 if (Parser.getTok().is(AsmToken::Dollar)) {
1750 // This must be a GPR.
1752 SMLoc VIdx = Parser.getTok().getLoc();
1753 Parser.Lex(); // Parse the '$' token.
1755 // GPR have aliases and we must account for that. Example: $30 == $fp
1756 if (getLexer().getKind() == AsmToken::Integer) {
1757 unsigned RegNum = Parser.getTok().getIntVal();
1758 int Reg = matchRegisterByNumber(
1759 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1761 Error(VIdx, "invalid general purpose register");
1762 return MatchOperand_ParseFail;
1765 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1766 } else if (getLexer().getKind() == AsmToken::Identifier) {
1768 std::string RegName = Parser.getTok().getString().lower();
1770 RegNum = matchCPURegisterName(RegName);
1772 Error(VIdx, "general purpose register expected");
1773 return MatchOperand_ParseFail;
1775 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1776 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1778 return MatchOperand_ParseFail;
1780 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1781 Operands.push_back(RegOp);
1782 Parser.Lex(); // Eat the register identifier.
1784 if (Parser.getTok().isNot(AsmToken::RBrac))
1785 return MatchOperand_ParseFail;
1787 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1788 Parser.Lex(); // Parse the ']' token.
1790 return MatchOperand_Success;
1793 // The index must be a constant expression then.
1794 SMLoc VIdx = Parser.getTok().getLoc();
1795 const MCExpr *ImmVal;
1797 if (getParser().parseExpression(ImmVal))
1798 return MatchOperand_ParseFail;
1800 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1801 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1802 Error(VIdx, "invalid immediate value");
1803 return MatchOperand_ParseFail;
1806 SMLoc E = Parser.getTok().getEndLoc();
1808 if (Parser.getTok().isNot(AsmToken::RBrac))
1809 return MatchOperand_ParseFail;
1812 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1813 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1815 // The second vector index of insve instructions is always 0.
1816 if (insve && Operands.size() > 6) {
1817 if (expr->getValue() != 0) {
1818 Error(VIdx, "immediate value must be 0");
1819 return MatchOperand_ParseFail;
1821 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1823 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1825 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1827 Parser.Lex(); // Parse the ']' token.
1829 return MatchOperand_Success;
1832 MipsAsmParser::OperandMatchResultTy
1833 MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1835 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1837 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1838 return MatchOperand_NoMatch;
1840 if (Parser.getTok().isNot(AsmToken::Dollar))
1841 return MatchOperand_ParseFail;
1843 SMLoc S = Parser.getTok().getLoc();
1845 Parser.Lex(); // Eat the '$' symbol.
1848 if (getLexer().getKind() == AsmToken::Identifier)
1849 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1850 else if (getLexer().getKind() == AsmToken::Integer)
1851 RegNum = Parser.getTok().getIntVal();
1853 return MatchOperand_ParseFail;
1855 if (RegNum < 0 || RegNum > 7)
1856 return MatchOperand_ParseFail;
1858 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1860 return MatchOperand_ParseFail;
1862 MipsOperand *RegOp =
1863 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1864 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1865 Operands.push_back(RegOp);
1866 Parser.Lex(); // Eat the register identifier.
1868 return MatchOperand_Success;
1871 MipsAsmParser::OperandMatchResultTy
1872 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1875 return MatchOperand_NoMatch;
1876 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1879 MipsAsmParser::OperandMatchResultTy
1880 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1881 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1884 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1885 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1888 return MatchOperand_NoMatch;
1889 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1892 MipsAsmParser::OperandMatchResultTy
1893 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1895 return MatchOperand_NoMatch;
1896 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1899 MipsAsmParser::OperandMatchResultTy
1900 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1901 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1904 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1905 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1906 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
1909 MipsAsmParser::OperandMatchResultTy
1910 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1911 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
1914 MipsAsmParser::OperandMatchResultTy
1915 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1916 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
1919 MipsAsmParser::OperandMatchResultTy
1920 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1921 // If the first token is not '$' we have an error.
1922 if (Parser.getTok().isNot(AsmToken::Dollar))
1923 return MatchOperand_NoMatch;
1925 SMLoc S = Parser.getTok().getLoc();
1926 Parser.Lex(); // Eat the '$'
1928 const AsmToken &Tok = Parser.getTok(); // Get next token.
1930 if (Tok.isNot(AsmToken::Identifier))
1931 return MatchOperand_NoMatch;
1933 if (!Tok.getIdentifier().startswith("ac"))
1934 return MatchOperand_NoMatch;
1936 StringRef NumString = Tok.getIdentifier().substr(2);
1939 if (NumString.getAsInteger(10, IntVal))
1940 return MatchOperand_NoMatch;
1942 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1944 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1945 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1946 Operands.push_back(Op);
1948 Parser.Lex(); // Eat the register number.
1949 return MatchOperand_Success;
1952 MipsAsmParser::OperandMatchResultTy
1953 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1954 // If the first token is not '$' we have an error.
1955 if (Parser.getTok().isNot(AsmToken::Dollar))
1956 return MatchOperand_NoMatch;
1958 SMLoc S = Parser.getTok().getLoc();
1959 Parser.Lex(); // Eat the '$'
1961 const AsmToken &Tok = Parser.getTok(); // Get next token.
1963 if (Tok.isNot(AsmToken::Identifier))
1964 return MatchOperand_NoMatch;
1966 if (!Tok.getIdentifier().startswith("ac"))
1967 return MatchOperand_NoMatch;
1969 StringRef NumString = Tok.getIdentifier().substr(2);
1972 if (NumString.getAsInteger(10, IntVal))
1973 return MatchOperand_NoMatch;
1975 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1977 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1978 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1979 Operands.push_back(Op);
1981 Parser.Lex(); // Eat the register number.
1982 return MatchOperand_Success;
1985 MipsAsmParser::OperandMatchResultTy
1986 MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1987 // If the first token is not '$' we have an error.
1988 if (Parser.getTok().isNot(AsmToken::Dollar))
1989 return MatchOperand_NoMatch;
1991 SMLoc S = Parser.getTok().getLoc();
1992 Parser.Lex(); // Eat the '$'
1994 const AsmToken &Tok = Parser.getTok(); // Get next token.
1996 if (Tok.isNot(AsmToken::Integer))
1997 return MatchOperand_NoMatch;
1999 unsigned IntVal = Tok.getIntVal();
2001 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2003 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2004 Op->setRegKind(MipsOperand::Kind_COP2);
2005 Operands.push_back(Op);
2007 Parser.Lex(); // Eat the register number.
2008 return MatchOperand_Success;
2011 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2012 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2013 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
2016 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2017 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2018 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
2021 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2022 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2023 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
2026 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2027 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2028 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
2031 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2032 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2033 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
2036 bool MipsAsmParser::searchSymbolAlias(
2037 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
2039 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2041 SMLoc S = Parser.getTok().getLoc();
2043 if (Sym->isVariable())
2044 Expr = Sym->getVariableValue();
2047 if (Expr->getKind() == MCExpr::SymbolRef) {
2048 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2049 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2050 const StringRef DefSymbol = Ref->getSymbol().getName();
2051 if (DefSymbol.startswith("$")) {
2053 APInt IntVal(32, -1);
2054 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2055 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
2056 isMips64() ? Mips::GPR64RegClassID
2057 : Mips::GPR32RegClassID);
2059 // Lookup for the register with the corresponding name.
2061 case MipsOperand::Kind_AFGR64Regs:
2062 case MipsOperand::Kind_FGR64Regs:
2063 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2065 case MipsOperand::Kind_FGR32Regs:
2066 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2068 case MipsOperand::Kind_GPR64:
2069 case MipsOperand::Kind_GPR32:
2071 RegNum = matchCPURegisterName(DefSymbol.substr(1));
2075 RegNum = getReg(regKindToRegClass(Kind), RegNum);
2080 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
2081 op->setRegKind(Kind);
2082 Operands.push_back(op);
2086 } else if (Expr->getKind() == MCExpr::Constant) {
2088 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2090 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
2091 Operands.push_back(op);
2098 MipsAsmParser::OperandMatchResultTy
2099 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2100 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
2103 MipsAsmParser::OperandMatchResultTy
2104 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2105 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
2108 MipsAsmParser::OperandMatchResultTy
2109 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2110 const MCExpr *IdVal;
2111 // If the first token is '$' we may have register operand.
2112 if (Parser.getTok().is(AsmToken::Dollar))
2113 return MatchOperand_NoMatch;
2114 SMLoc S = Parser.getTok().getLoc();
2115 if (getParser().parseExpression(IdVal))
2116 return MatchOperand_ParseFail;
2117 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2118 assert(MCE && "Unexpected MCExpr type.");
2119 int64_t Val = MCE->getValue();
2120 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2121 Operands.push_back(MipsOperand::CreateImm(
2122 MCConstantExpr::Create(0 - Val, getContext()), S, E));
2123 return MatchOperand_Success;
2126 MipsAsmParser::OperandMatchResultTy
2127 MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2128 switch (getLexer().getKind()) {
2130 return MatchOperand_NoMatch;
2131 case AsmToken::LParen:
2132 case AsmToken::Plus:
2133 case AsmToken::Minus:
2134 case AsmToken::Integer:
2139 SMLoc S = Parser.getTok().getLoc();
2141 if (getParser().parseExpression(Expr))
2142 return MatchOperand_ParseFail;
2145 if (!Expr->EvaluateAsAbsolute(Val)) {
2146 Error(S, "expected immediate value");
2147 return MatchOperand_ParseFail;
2150 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2151 // and because the CPU always adds one to the immediate field, the allowed
2152 // range becomes 1..4. We'll only check the range here and will deal
2153 // with the addition/subtraction when actually decoding/encoding
2155 if (Val < 1 || Val > 4) {
2156 Error(S, "immediate not in range (1..4)");
2157 return MatchOperand_ParseFail;
2161 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
2162 return MatchOperand_Success;
2165 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2167 MCSymbolRefExpr::VariantKind VK =
2168 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2169 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2170 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2171 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2172 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2173 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2174 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2175 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2176 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2177 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2178 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2179 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2180 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2181 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2182 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2183 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2184 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2185 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2186 .Default(MCSymbolRefExpr::VK_None);
2191 bool MipsAsmParser::ParseInstruction(
2192 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2193 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2194 // Check if we have valid mnemonic
2195 if (!mnemonicIsValid(Name, 0)) {
2196 Parser.eatToEndOfStatement();
2197 return Error(NameLoc, "Unknown instruction");
2199 // First operand in MCInst is instruction mnemonic.
2200 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2202 // Read the remaining operands.
2203 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2204 // Read the first operand.
2205 if (ParseOperand(Operands, Name)) {
2206 SMLoc Loc = getLexer().getLoc();
2207 Parser.eatToEndOfStatement();
2208 return Error(Loc, "unexpected token in argument list");
2211 while (getLexer().is(AsmToken::Comma)) {
2212 Parser.Lex(); // Eat the comma.
2213 // Parse and remember the operand.
2214 if (ParseOperand(Operands, Name)) {
2215 SMLoc Loc = getLexer().getLoc();
2216 Parser.eatToEndOfStatement();
2217 return Error(Loc, "unexpected token in argument list");
2221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2222 SMLoc Loc = getLexer().getLoc();
2223 Parser.eatToEndOfStatement();
2224 return Error(Loc, "unexpected token in argument list");
2226 Parser.Lex(); // Consume the EndOfStatement.
2230 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2231 SMLoc Loc = getLexer().getLoc();
2232 Parser.eatToEndOfStatement();
2233 return Error(Loc, ErrorMsg);
2236 bool MipsAsmParser::parseSetNoAtDirective() {
2237 // Line should look like: ".set noat".
2239 Options.setATReg(0);
2242 // If this is not the end of the statement, report an error.
2243 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2244 reportParseError("unexpected token in statement");
2247 Parser.Lex(); // Consume the EndOfStatement.
2251 bool MipsAsmParser::parseSetAtDirective() {
2252 // Line can be .set at - defaults to $1
2256 if (getLexer().is(AsmToken::EndOfStatement)) {
2257 Options.setATReg(1);
2258 Parser.Lex(); // Consume the EndOfStatement.
2260 } else if (getLexer().is(AsmToken::Equal)) {
2261 getParser().Lex(); // Eat the '='.
2262 if (getLexer().isNot(AsmToken::Dollar)) {
2263 reportParseError("unexpected token in statement");
2266 Parser.Lex(); // Eat the '$'.
2267 const AsmToken &Reg = Parser.getTok();
2268 if (Reg.is(AsmToken::Identifier)) {
2269 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2270 } else if (Reg.is(AsmToken::Integer)) {
2271 AtRegNo = Reg.getIntVal();
2273 reportParseError("unexpected token in statement");
2277 if (AtRegNo < 1 || AtRegNo > 31) {
2278 reportParseError("unexpected token in statement");
2282 if (!Options.setATReg(AtRegNo)) {
2283 reportParseError("unexpected token in statement");
2286 getParser().Lex(); // Eat the register.
2288 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2289 reportParseError("unexpected token in statement");
2292 Parser.Lex(); // Consume the EndOfStatement.
2295 reportParseError("unexpected token in statement");
2300 bool MipsAsmParser::parseSetReorderDirective() {
2302 // If this is not the end of the statement, report an error.
2303 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2304 reportParseError("unexpected token in statement");
2307 Options.setReorder();
2308 Parser.Lex(); // Consume the EndOfStatement.
2312 bool MipsAsmParser::parseSetNoReorderDirective() {
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.setNoreorder();
2320 Parser.Lex(); // Consume the EndOfStatement.
2324 bool MipsAsmParser::parseSetMacroDirective() {
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");
2332 Parser.Lex(); // Consume the EndOfStatement.
2336 bool MipsAsmParser::parseSetNoMacroDirective() {
2338 // If this is not the end of the statement, report an error.
2339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2340 reportParseError("`noreorder' must be set before `nomacro'");
2343 if (Options.isReorder()) {
2344 reportParseError("`noreorder' must be set before `nomacro'");
2347 Options.setNomacro();
2348 Parser.Lex(); // Consume the EndOfStatement.
2352 bool MipsAsmParser::parseSetMips16Directive() {
2354 // If this is not the end of the statement, report an error.
2355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2356 reportParseError("unexpected token in statement");
2359 getTargetStreamer().emitDirectiveSetMips16();
2360 Parser.Lex(); // Consume the EndOfStatement.
2364 bool MipsAsmParser::parseSetNoMips16Directive() {
2366 // If this is not the end of the statement, report an error.
2367 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2368 reportParseError("unexpected token in statement");
2371 // For now do nothing.
2372 Parser.Lex(); // Consume the EndOfStatement.
2376 bool MipsAsmParser::parseSetAssignment() {
2378 const MCExpr *Value;
2380 if (Parser.parseIdentifier(Name))
2381 reportParseError("expected identifier after .set");
2383 if (getLexer().isNot(AsmToken::Comma))
2384 return reportParseError("unexpected token in .set directive");
2387 if (Parser.parseExpression(Value))
2388 return reportParseError("expected valid expression after comma");
2390 // Check if the Name already exists as a symbol.
2391 MCSymbol *Sym = getContext().LookupSymbol(Name);
2393 return reportParseError("symbol already defined");
2394 Sym = getContext().GetOrCreateSymbol(Name);
2395 Sym->setVariableValue(Value);
2400 bool MipsAsmParser::parseDirectiveSet() {
2402 // Get the next token.
2403 const AsmToken &Tok = Parser.getTok();
2405 if (Tok.getString() == "noat") {
2406 return parseSetNoAtDirective();
2407 } else if (Tok.getString() == "at") {
2408 return parseSetAtDirective();
2409 } else if (Tok.getString() == "reorder") {
2410 return parseSetReorderDirective();
2411 } else if (Tok.getString() == "noreorder") {
2412 return parseSetNoReorderDirective();
2413 } else if (Tok.getString() == "macro") {
2414 return parseSetMacroDirective();
2415 } else if (Tok.getString() == "nomacro") {
2416 return parseSetNoMacroDirective();
2417 } else if (Tok.getString() == "mips16") {
2418 return parseSetMips16Directive();
2419 } else if (Tok.getString() == "nomips16") {
2420 return parseSetNoMips16Directive();
2421 } else if (Tok.getString() == "nomicromips") {
2422 getTargetStreamer().emitDirectiveSetNoMicroMips();
2423 Parser.eatToEndOfStatement();
2425 } else if (Tok.getString() == "micromips") {
2426 getTargetStreamer().emitDirectiveSetMicroMips();
2427 Parser.eatToEndOfStatement();
2430 // It is just an identifier, look for an assignment.
2431 parseSetAssignment();
2438 /// parseDirectiveWord
2439 /// ::= .word [ expression (, expression)* ]
2440 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2443 const MCExpr *Value;
2444 if (getParser().parseExpression(Value))
2447 getParser().getStreamer().EmitValue(Value, Size);
2449 if (getLexer().is(AsmToken::EndOfStatement))
2452 // FIXME: Improve diagnostic.
2453 if (getLexer().isNot(AsmToken::Comma))
2454 return Error(L, "unexpected token in directive");
2463 /// parseDirectiveGpWord
2464 /// ::= .gpword local_sym
2465 bool MipsAsmParser::parseDirectiveGpWord() {
2466 const MCExpr *Value;
2467 // EmitGPRel32Value requires an expression, so we are using base class
2468 // method to evaluate the expression.
2469 if (getParser().parseExpression(Value))
2471 getParser().getStreamer().EmitGPRel32Value(Value);
2473 if (getLexer().isNot(AsmToken::EndOfStatement))
2474 return Error(getLexer().getLoc(), "unexpected token in directive");
2475 Parser.Lex(); // Eat EndOfStatement token.
2479 bool MipsAsmParser::parseDirectiveOption() {
2480 // Get the option token.
2481 AsmToken Tok = Parser.getTok();
2482 // At the moment only identifiers are supported.
2483 if (Tok.isNot(AsmToken::Identifier)) {
2484 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2485 Parser.eatToEndOfStatement();
2489 StringRef Option = Tok.getIdentifier();
2491 if (Option == "pic0") {
2492 getTargetStreamer().emitDirectiveOptionPic0();
2494 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2495 Error(Parser.getTok().getLoc(),
2496 "unexpected token in .option pic0 directive");
2497 Parser.eatToEndOfStatement();
2503 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2504 Parser.eatToEndOfStatement();
2508 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2509 StringRef IDVal = DirectiveID.getString();
2511 if (IDVal == ".ent") {
2512 // Ignore this directive for now.
2517 if (IDVal == ".end") {
2518 // Ignore this directive for now.
2523 if (IDVal == ".frame") {
2524 // Ignore this directive for now.
2525 Parser.eatToEndOfStatement();
2529 if (IDVal == ".set") {
2530 return parseDirectiveSet();
2533 if (IDVal == ".fmask") {
2534 // Ignore this directive for now.
2535 Parser.eatToEndOfStatement();
2539 if (IDVal == ".mask") {
2540 // Ignore this directive for now.
2541 Parser.eatToEndOfStatement();
2545 if (IDVal == ".gpword") {
2546 // Ignore this directive for now.
2547 parseDirectiveGpWord();
2551 if (IDVal == ".word") {
2552 parseDirectiveWord(4, DirectiveID.getLoc());
2556 if (IDVal == ".option")
2557 return parseDirectiveOption();
2559 if (IDVal == ".abicalls") {
2560 getTargetStreamer().emitDirectiveAbiCalls();
2561 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2562 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2564 Parser.eatToEndOfStatement();
2572 void MipsAsmParser::processInitialEFlags() {
2573 // Start will a clean slate.
2574 unsigned EFlags = 0;
2575 unsigned FeatureBits = STI.getFeatureBits();
2578 EFlags |= ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_PIC | ELF::EF_MIPS_ABI_O32;
2581 if (FeatureBits & Mips::FeatureMips64r2) {
2582 EFlags |= ELF::EF_MIPS_ARCH_64R2;
2583 EFlags &= ~ELF::EF_MIPS_ABI_O32;
2584 } else if (FeatureBits & Mips::FeatureMips64) {
2585 EFlags |= ELF::EF_MIPS_ARCH_64;
2586 EFlags &= ~ELF::EF_MIPS_ABI_O32;
2587 } else if (FeatureBits & Mips::FeatureMips32r2)
2588 EFlags |= ELF::EF_MIPS_ARCH_32R2;
2589 else if (FeatureBits & Mips::FeatureMips32)
2590 EFlags |= ELF::EF_MIPS_ARCH_32;
2591 else if (FeatureBits & Mips::FeatureO32)
2592 EFlags |= ELF::EF_MIPS_ABI_O32; // This is really a zero
2595 if (FeatureBits & Mips::FeatureMicroMips)
2596 EFlags |= ELF::EF_MIPS_MICROMIPS;
2597 else if (FeatureBits & Mips::FeatureMips16)
2598 EFlags |= ELF::EF_MIPS_ARCH_ASE_M16;
2604 // TODO: pic/cpic/static
2606 getTargetStreamer().emitMipsELFFlags(EFlags);
2609 extern "C" void LLVMInitializeMipsAsmParser() {
2610 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2611 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2612 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2613 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2616 #define GET_REGISTER_MATCHER
2617 #define GET_MATCHER_IMPLEMENTATION
2618 #include "MipsGenAsmMatcher.inc"