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 "AsmParser/MipsAsmFlags.h"
11 #include "MCTargetDesc/MipsELFStreamer.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.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/TargetRegistry.h"
25 #include "llvm/ADT/APInt.h"
34 class MipsAssemblerOptions {
36 MipsAssemblerOptions():
37 aTReg(1), reorder(true), macro(true) {
40 unsigned getATRegNum() {return aTReg;}
41 bool setATReg(unsigned Reg);
43 bool isReorder() {return reorder;}
44 void setReorder() {reorder = true;}
45 void setNoreorder() {reorder = false;}
47 bool isMacro() {return macro;}
48 void setMacro() {macro = true;}
49 void setNomacro() {macro = false;}
59 class MipsAsmParser : public MCTargetAsmParser {
63 MipsAssemblerOptions Options;
65 bool hasConsumedDollar;
67 #define GET_ASSEMBLER_HEADER
68 #include "MipsGenAsmMatcher.inc"
70 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
72 MCStreamer &Out, unsigned &ErrorInfo,
73 bool MatchingInlineAsm);
75 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
77 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
79 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
81 bool ParseDirective(AsmToken DirectiveID);
83 MipsAsmParser::OperandMatchResultTy
84 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
87 MipsAsmParser::OperandMatchResultTy
88 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
91 MipsAsmParser::OperandMatchResultTy
92 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
94 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
96 MipsAsmParser::OperandMatchResultTy
97 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
99 MipsAsmParser::OperandMatchResultTy
100 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
102 MipsAsmParser::OperandMatchResultTy
103 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105 MipsAsmParser::OperandMatchResultTy
106 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108 MipsAsmParser::OperandMatchResultTy
109 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111 MipsAsmParser::OperandMatchResultTy
112 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114 MipsAsmParser::OperandMatchResultTy
115 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117 MipsAsmParser::OperandMatchResultTy
118 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120 MipsAsmParser::OperandMatchResultTy
121 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123 MipsAsmParser::OperandMatchResultTy
124 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
126 MipsAsmParser::OperandMatchResultTy
127 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
129 MipsAsmParser::OperandMatchResultTy
130 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
135 MipsAsmParser::OperandMatchResultTy
136 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
138 MipsAsmParser::OperandMatchResultTy
139 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
141 MipsAsmParser::OperandMatchResultTy
142 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144 MipsAsmParser::OperandMatchResultTy
145 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
147 MipsAsmParser::OperandMatchResultTy
148 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
150 MipsAsmParser::OperandMatchResultTy
151 parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
153 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
156 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
159 int tryParseRegister(bool is64BitReg);
161 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
164 bool needsExpansion(MCInst &Inst);
166 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
168 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
169 SmallVectorImpl<MCInst> &Instructions);
170 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
171 SmallVectorImpl<MCInst> &Instructions);
172 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
174 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions,
176 bool isLoad,bool isImmOpnd);
177 bool reportParseError(StringRef ErrorMsg);
179 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
180 bool parseRelocOperand(const MCExpr *&Res);
182 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
184 bool isEvaluated(const MCExpr *Expr);
185 bool parseDirectiveSet();
187 bool parseSetAtDirective();
188 bool parseSetNoAtDirective();
189 bool parseSetMacroDirective();
190 bool parseSetNoMacroDirective();
191 bool parseSetReorderDirective();
192 bool parseSetNoReorderDirective();
194 bool parseSetAssignment();
196 bool parseDirectiveWord(unsigned Size, SMLoc L);
198 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
200 bool isMips64() const {
201 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
204 bool isFP64() const {
205 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
209 return STI.getFeatureBits() & Mips::FeatureN64;
212 int matchRegisterName(StringRef Symbol, bool is64BitReg);
214 int matchCPURegisterName(StringRef Symbol);
216 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
218 int matchFPURegisterName(StringRef Name);
220 int matchFCCRegisterName(StringRef Name);
222 int matchACRegisterName(StringRef Name);
224 int matchMSA128RegisterName(StringRef Name);
226 int regKindToRegClass(int RegKind);
228 unsigned getReg(int RC, int RegNo);
232 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
233 SmallVectorImpl<MCInst> &Instructions);
234 void emitEndOfAsmFile(MCStreamer &Out);
237 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
238 const MCInstrInfo &MII)
239 : MCTargetAsmParser(), STI(sti), Parser(parser),
240 hasConsumedDollar(false) {
241 // Initialize the set of available features.
242 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
245 MCAsmParser &getParser() const { return Parser; }
246 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
253 /// MipsOperand - Instances of this class represent a parsed Mips machine
255 class MipsOperand : public MCParsedAsmOperand {
291 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
319 SMLoc StartLoc, EndLoc;
322 void addRegOperands(MCInst &Inst, unsigned N) const {
323 assert(N == 1 && "Invalid number of operands!");
324 Inst.addOperand(MCOperand::CreateReg(getReg()));
327 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
328 assert(N == 1 && "Invalid number of operands!");
329 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
332 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
333 // Add as immediate when possible. Null MCExpr = 0.
335 Inst.addOperand(MCOperand::CreateImm(0));
336 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
337 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
339 Inst.addOperand(MCOperand::CreateExpr(Expr));
342 void addImmOperands(MCInst &Inst, unsigned N) const {
343 assert(N == 1 && "Invalid number of operands!");
344 const MCExpr *Expr = getImm();
348 void addMemOperands(MCInst &Inst, unsigned N) const {
349 assert(N == 2 && "Invalid number of operands!");
351 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
353 const MCExpr *Expr = getMemOff();
357 bool isReg() const { return Kind == k_Register; }
358 bool isImm() const { return Kind == k_Immediate; }
359 bool isToken() const { return Kind == k_Token; }
360 bool isMem() const { return Kind == k_Memory; }
361 bool isPtrReg() const { return Kind == k_PtrReg; }
362 bool isInvNum() const { return Kind == k_Immediate; }
364 StringRef getToken() const {
365 assert(Kind == k_Token && "Invalid access!");
366 return StringRef(Tok.Data, Tok.Length);
369 unsigned getReg() const {
370 assert((Kind == k_Register) && "Invalid access!");
374 unsigned getPtrReg() const {
375 assert((Kind == k_PtrReg) && "Invalid access!");
379 void setRegKind(RegisterKind RegKind) {
380 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
384 const MCExpr *getImm() const {
385 assert((Kind == k_Immediate) && "Invalid access!");
389 unsigned getMemBase() const {
390 assert((Kind == k_Memory) && "Invalid access!");
394 const MCExpr *getMemOff() const {
395 assert((Kind == k_Memory) && "Invalid access!");
399 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
400 MipsOperand *Op = new MipsOperand(k_Token);
401 Op->Tok.Data = Str.data();
402 Op->Tok.Length = Str.size();
408 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
409 MipsOperand *Op = new MipsOperand(k_Register);
410 Op->Reg.RegNum = RegNum;
416 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
417 MipsOperand *Op = new MipsOperand(k_PtrReg);
418 Op->Reg.RegNum = RegNum;
424 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
425 MipsOperand *Op = new MipsOperand(k_Immediate);
432 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
434 MipsOperand *Op = new MipsOperand(k_Memory);
442 bool isGPR32Asm() const {
443 return Kind == k_Register && Reg.Kind == Kind_GPR32;
445 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
446 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
449 bool isGPR64Asm() const {
450 return Kind == k_Register && Reg.Kind == Kind_GPR64;
453 bool isHWRegsAsm() const {
454 assert((Kind == k_Register) && "Invalid access!");
455 return Reg.Kind == Kind_HWRegs;
458 bool isCCRAsm() const {
459 assert((Kind == k_Register) && "Invalid access!");
460 return Reg.Kind == Kind_CCRRegs;
463 bool isAFGR64Asm() const {
464 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
467 bool isFGR64Asm() const {
468 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
471 bool isFGR32Asm() const {
472 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
475 bool isFGRH32Asm() const {
476 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
479 bool isFCCRegsAsm() const {
480 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
483 bool isACC64DSPAsm() const {
484 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
487 bool isLO32DSPAsm() const {
488 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
491 bool isHI32DSPAsm() const {
492 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
495 bool isCOP2Asm() const {
496 return Kind == k_Register && Reg.Kind == Kind_COP2;
499 bool isMSA128BAsm() const {
500 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
503 bool isMSA128HAsm() const {
504 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
507 bool isMSA128WAsm() const {
508 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
511 bool isMSA128DAsm() const {
512 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
515 /// getStartLoc - Get the location of the first token of this operand.
516 SMLoc getStartLoc() const {
519 /// getEndLoc - Get the location of the last token of this operand.
520 SMLoc getEndLoc() const {
524 virtual void print(raw_ostream &OS) const {
525 llvm_unreachable("unimplemented!");
527 }; // class MipsOperand
531 extern const MCInstrDesc MipsInsts[];
533 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
534 return MipsInsts[Opcode];
537 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
538 SmallVectorImpl<MCInst> &Instructions) {
539 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
541 if (MCID.hasDelaySlot() && Options.isReorder()) {
542 // If this instruction has a delay slot and .set reorder is active,
543 // emit a NOP after it.
544 Instructions.push_back(Inst);
546 NopInst.setOpcode(Mips::SLL);
547 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
548 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
549 NopInst.addOperand(MCOperand::CreateImm(0));
550 Instructions.push_back(NopInst);
554 if (MCID.mayLoad() || MCID.mayStore()) {
555 // Check the offset of memory operand, if it is a symbol
556 // reference or immediate we may have to expand instructions.
557 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
558 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
559 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
560 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
561 MCOperand &Op = Inst.getOperand(i);
563 int MemOffset = Op.getImm();
564 if (MemOffset < -32768 || MemOffset > 32767) {
565 // Offset can't exceed 16bit value.
566 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
569 } else if (Op.isExpr()) {
570 const MCExpr *Expr = Op.getExpr();
571 if (Expr->getKind() == MCExpr::SymbolRef) {
572 const MCSymbolRefExpr *SR =
573 static_cast<const MCSymbolRefExpr*>(Expr);
574 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
576 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
579 } else if (!isEvaluated(Expr)) {
580 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
588 if (needsExpansion(Inst))
589 expandInstruction(Inst, IDLoc, Instructions);
591 Instructions.push_back(Inst);
596 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
598 switch (Inst.getOpcode()) {
599 case Mips::LoadImm32Reg:
600 case Mips::LoadAddr32Imm:
601 case Mips::LoadAddr32Reg:
608 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
609 SmallVectorImpl<MCInst> &Instructions) {
610 switch (Inst.getOpcode()) {
611 case Mips::LoadImm32Reg:
612 return expandLoadImm(Inst, IDLoc, Instructions);
613 case Mips::LoadAddr32Imm:
614 return expandLoadAddressImm(Inst, IDLoc, Instructions);
615 case Mips::LoadAddr32Reg:
616 return expandLoadAddressReg(Inst, IDLoc, Instructions);
620 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
621 SmallVectorImpl<MCInst> &Instructions) {
623 const MCOperand &ImmOp = Inst.getOperand(1);
624 assert(ImmOp.isImm() && "expected immediate operand kind");
625 const MCOperand &RegOp = Inst.getOperand(0);
626 assert(RegOp.isReg() && "expected register operand kind");
628 int ImmValue = ImmOp.getImm();
629 tmpInst.setLoc(IDLoc);
630 if (0 <= ImmValue && ImmValue <= 65535) {
631 // For 0 <= j <= 65535.
632 // li d,j => ori d,$zero,j
633 tmpInst.setOpcode(Mips::ORi);
634 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
635 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
636 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
637 Instructions.push_back(tmpInst);
638 } else if (ImmValue < 0 && ImmValue >= -32768) {
639 // For -32768 <= j < 0.
640 // li d,j => addiu d,$zero,j
641 tmpInst.setOpcode(Mips::ADDiu);
642 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
643 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
644 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
645 Instructions.push_back(tmpInst);
647 // For any other value of j that is representable as a 32-bit integer.
648 // li d,j => lui d,hi16(j)
650 tmpInst.setOpcode(Mips::LUi);
651 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
652 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
653 Instructions.push_back(tmpInst);
655 tmpInst.setOpcode(Mips::ORi);
656 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
657 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
658 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
659 tmpInst.setLoc(IDLoc);
660 Instructions.push_back(tmpInst);
664 void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
665 SmallVectorImpl<MCInst> &Instructions) {
667 const MCOperand &ImmOp = Inst.getOperand(2);
668 assert(ImmOp.isImm() && "expected immediate operand kind");
669 const MCOperand &SrcRegOp = Inst.getOperand(1);
670 assert(SrcRegOp.isReg() && "expected register operand kind");
671 const MCOperand &DstRegOp = Inst.getOperand(0);
672 assert(DstRegOp.isReg() && "expected register operand kind");
673 int ImmValue = ImmOp.getImm();
674 if (-32768 <= ImmValue && ImmValue <= 65535) {
675 // For -32768 <= j <= 65535.
676 // la d,j(s) => addiu d,s,j
677 tmpInst.setOpcode(Mips::ADDiu);
678 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
679 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
680 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
681 Instructions.push_back(tmpInst);
683 // For any other value of j that is representable as a 32-bit integer.
684 // la d,j(s) => lui d,hi16(j)
687 tmpInst.setOpcode(Mips::LUi);
688 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
689 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
690 Instructions.push_back(tmpInst);
692 tmpInst.setOpcode(Mips::ORi);
693 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
694 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
695 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
696 Instructions.push_back(tmpInst);
698 tmpInst.setOpcode(Mips::ADDu);
699 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
700 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
701 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
702 Instructions.push_back(tmpInst);
706 void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
707 SmallVectorImpl<MCInst> &Instructions) {
709 const MCOperand &ImmOp = Inst.getOperand(1);
710 assert(ImmOp.isImm() && "expected immediate operand kind");
711 const MCOperand &RegOp = Inst.getOperand(0);
712 assert(RegOp.isReg() && "expected register operand kind");
713 int ImmValue = ImmOp.getImm();
714 if (-32768 <= ImmValue && ImmValue <= 65535) {
715 // For -32768 <= j <= 65535.
716 // la d,j => addiu d,$zero,j
717 tmpInst.setOpcode(Mips::ADDiu);
718 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
719 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
720 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
721 Instructions.push_back(tmpInst);
723 // For any other value of j that is representable as a 32-bit integer.
724 // la d,j => lui d,hi16(j)
726 tmpInst.setOpcode(Mips::LUi);
727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
728 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
729 Instructions.push_back(tmpInst);
731 tmpInst.setOpcode(Mips::ORi);
732 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
733 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
734 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
735 Instructions.push_back(tmpInst);
739 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
740 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
741 const MCSymbolRefExpr *SR;
743 unsigned ImmOffset, HiOffset, LoOffset;
744 const MCExpr *ExprOffset;
746 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
747 : Mips::GPR32RegClassID, getATReg());
748 // 1st operand is either the source or destination register.
749 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
750 unsigned RegOpNum = Inst.getOperand(0).getReg();
751 // 2nd operand is the base register.
752 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
753 unsigned BaseRegNum = Inst.getOperand(1).getReg();
754 // 3rd operand is either an immediate or expression.
756 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
757 ImmOffset = Inst.getOperand(2).getImm();
758 LoOffset = ImmOffset & 0x0000ffff;
759 HiOffset = (ImmOffset & 0xffff0000) >> 16;
760 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
761 if (LoOffset & 0x8000)
764 ExprOffset = Inst.getOperand(2).getExpr();
765 // All instructions will have the same location.
766 TempInst.setLoc(IDLoc);
767 // 1st instruction in expansion is LUi. For load instruction we can use
768 // the dst register as a temporary if base and dst are different,
769 // but for stores we must use $at.
770 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
771 TempInst.setOpcode(Mips::LUi);
772 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
774 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
776 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
777 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
778 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
779 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
781 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
783 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
784 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
787 // Add the instruction to the list.
788 Instructions.push_back(TempInst);
789 // Prepare TempInst for next instruction.
791 // Add temp register to base.
792 TempInst.setOpcode(Mips::ADDu);
793 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
794 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
795 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
796 Instructions.push_back(TempInst);
798 // And finaly, create original instruction with low part
799 // of offset and new base.
800 TempInst.setOpcode(Inst.getOpcode());
801 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
802 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
804 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
806 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
807 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
808 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
810 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
812 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
813 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
816 Instructions.push_back(TempInst);
821 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
822 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
823 MCStreamer &Out, unsigned &ErrorInfo,
824 bool MatchingInlineAsm) {
826 SmallVector<MCInst, 8> Instructions;
827 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
830 switch (MatchResult) {
833 case Match_Success: {
834 if (processInstruction(Inst, IDLoc, Instructions))
836 for (unsigned i = 0; i < Instructions.size(); i++)
837 Out.EmitInstruction(Instructions[i]);
840 case Match_MissingFeature:
841 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
843 case Match_InvalidOperand: {
844 SMLoc ErrorLoc = IDLoc;
845 if (ErrorInfo != ~0U) {
846 if (ErrorInfo >= Operands.size())
847 return Error(IDLoc, "too few operands for instruction");
849 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
850 if (ErrorLoc == SMLoc())
854 return Error(ErrorLoc, "invalid operand for instruction");
856 case Match_MnemonicFail:
857 return Error(IDLoc, "invalid instruction");
862 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
868 CC = StringSwitch<unsigned>(Name)
902 // Although SGI documentation just cuts out t0-t3 for n32/n64,
903 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
904 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
905 if (isMips64() && 8 <= CC && CC <= 11)
908 if (CC == -1 && isMips64())
909 CC = StringSwitch<unsigned>(Name)
922 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
924 if (Name[0] == 'f') {
925 StringRef NumString = Name.substr(1);
927 if (NumString.getAsInteger(10, IntVal))
928 return -1; // This is not an integer.
929 if (IntVal > 31) // Maximum index for fpu register.
936 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
938 if (Name.startswith("fcc")) {
939 StringRef NumString = Name.substr(3);
941 if (NumString.getAsInteger(10, IntVal))
942 return -1; // This is not an integer.
943 if (IntVal > 7) // There are only 8 fcc registers.
950 int MipsAsmParser::matchACRegisterName(StringRef Name) {
952 if (Name.startswith("ac")) {
953 StringRef NumString = Name.substr(2);
955 if (NumString.getAsInteger(10, IntVal))
956 return -1; // This is not an integer.
957 if (IntVal > 3) // There are only 3 acc registers.
964 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
967 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
976 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
979 CC = matchCPURegisterName(Name);
981 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
982 : Mips::GPR32RegClassID);
983 CC = matchFPURegisterName(Name);
984 //TODO: decide about fpu register class
986 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
987 : Mips::FGR32RegClassID);
988 return matchMSA128RegisterName(Name);
991 int MipsAsmParser::regKindToRegClass(int RegKind) {
994 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
995 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
996 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
997 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
998 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
999 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
1000 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
1001 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
1002 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
1003 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
1004 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1005 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1006 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1007 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
1013 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1021 int MipsAsmParser::getATReg() {
1022 return Options.getATRegNum();
1025 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1026 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1029 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1031 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
1034 return getReg(RegClass, RegNum);
1037 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1038 const AsmToken &Tok = Parser.getTok();
1041 if (Tok.is(AsmToken::Identifier)) {
1042 std::string lowerCase = Tok.getString().lower();
1043 RegNum = matchRegisterName(lowerCase, is64BitReg);
1044 } else if (Tok.is(AsmToken::Integer))
1045 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1046 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
1050 bool MipsAsmParser::tryParseRegisterOperand(
1051 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
1053 SMLoc S = Parser.getTok().getLoc();
1056 RegNo = tryParseRegister(is64BitReg);
1060 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
1061 Parser.getTok().getLoc()));
1062 Parser.Lex(); // Eat register token.
1066 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1067 StringRef Mnemonic) {
1068 // Check if the current operand has a custom associated parser, if so, try to
1069 // custom parse the operand, or fallback to the general approach.
1070 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1071 if (ResTy == MatchOperand_Success)
1073 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1074 // there was a match, but an error occurred, in which case, just return that
1075 // the operand parsing failed.
1076 if (ResTy == MatchOperand_ParseFail)
1079 switch (getLexer().getKind()) {
1081 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1083 case AsmToken::Dollar: {
1084 // Parse the register.
1085 SMLoc S = Parser.getTok().getLoc();
1086 Parser.Lex(); // Eat dollar token.
1087 // Parse the register operand.
1088 if (!tryParseRegisterOperand(Operands, isMips64())) {
1089 if (getLexer().is(AsmToken::LParen)) {
1090 // Check if it is indexed addressing operand.
1091 Operands.push_back(MipsOperand::CreateToken("(", S));
1092 Parser.Lex(); // Eat the parenthesis.
1093 if (getLexer().isNot(AsmToken::Dollar))
1096 Parser.Lex(); // Eat the dollar
1097 if (tryParseRegisterOperand(Operands, isMips64()))
1100 if (!getLexer().is(AsmToken::RParen))
1103 S = Parser.getTok().getLoc();
1104 Operands.push_back(MipsOperand::CreateToken(")", S));
1109 // Maybe it is a symbol reference.
1110 StringRef Identifier;
1111 if (Parser.parseIdentifier(Identifier))
1114 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1116 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1118 // Otherwise create a symbol reference.
1119 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
1122 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1125 case AsmToken::Identifier:
1126 // Look for the existing symbol, we should check if
1127 // we need to assigne the propper RegisterKind.
1128 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1130 // Else drop to expression parsing.
1131 case AsmToken::LParen:
1132 case AsmToken::Minus:
1133 case AsmToken::Plus:
1134 case AsmToken::Integer:
1135 case AsmToken::String: {
1136 // Quoted label names.
1137 const MCExpr *IdVal;
1138 SMLoc S = Parser.getTok().getLoc();
1139 if (getParser().parseExpression(IdVal))
1141 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1142 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1145 case AsmToken::Percent: {
1146 // It is a symbol reference or constant expression.
1147 const MCExpr *IdVal;
1148 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1149 if (parseRelocOperand(IdVal))
1152 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1154 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1156 } // case AsmToken::Percent
1157 } // switch(getLexer().getKind())
1161 const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1162 StringRef RelocStr) {
1164 // Check the type of the expression.
1165 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1166 // It's a constant, evaluate lo or hi value.
1167 if (RelocStr == "lo") {
1168 short Val = MCE->getValue();
1169 Res = MCConstantExpr::Create(Val, getContext());
1170 } else if (RelocStr == "hi") {
1171 int Val = MCE->getValue();
1172 int LoSign = Val & 0x8000;
1173 Val = (Val & 0xffff0000) >> 16;
1174 // Lower part is treated as a signed int, so if it is negative
1175 // we must add 1 to the hi part to compensate.
1178 Res = MCConstantExpr::Create(Val, getContext());
1180 llvm_unreachable("Invalid RelocStr value");
1185 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1186 // It's a symbol, create a symbolic expression from the symbol.
1187 StringRef Symbol = MSRE->getSymbol().getName();
1188 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1189 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1193 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1194 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1195 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1196 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1200 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1201 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1202 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1205 // Just return the original expression.
1209 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1211 switch (Expr->getKind()) {
1212 case MCExpr::Constant:
1214 case MCExpr::SymbolRef:
1215 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1216 case MCExpr::Binary:
1217 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1218 if (!isEvaluated(BE->getLHS()))
1220 return isEvaluated(BE->getRHS());
1223 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1230 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1231 Parser.Lex(); // Eat the % token.
1232 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1233 if (Tok.isNot(AsmToken::Identifier))
1236 std::string Str = Tok.getIdentifier().str();
1238 Parser.Lex(); // Eat the identifier.
1239 // Now make an expression from the rest of the operand.
1240 const MCExpr *IdVal;
1243 if (getLexer().getKind() == AsmToken::LParen) {
1245 Parser.Lex(); // Eat the '(' token.
1246 if (getLexer().getKind() == AsmToken::Percent) {
1247 Parser.Lex(); // Eat the % token.
1248 const AsmToken &nextTok = Parser.getTok();
1249 if (nextTok.isNot(AsmToken::Identifier))
1252 Str += nextTok.getIdentifier();
1253 Parser.Lex(); // Eat the identifier.
1254 if (getLexer().getKind() != AsmToken::LParen)
1259 if (getParser().parseParenExpression(IdVal, EndLoc))
1262 while (getLexer().getKind() == AsmToken::RParen)
1263 Parser.Lex(); // Eat the ')' token.
1266 return true; // Parenthesis must follow the relocation operand.
1268 Res = evaluateRelocExpr(IdVal, Str);
1272 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1274 StartLoc = Parser.getTok().getLoc();
1275 RegNo = tryParseRegister(isMips64());
1276 EndLoc = Parser.getTok().getLoc();
1277 return (RegNo == (unsigned) -1);
1280 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1284 while (getLexer().getKind() == AsmToken::LParen)
1287 switch (getLexer().getKind()) {
1290 case AsmToken::Identifier:
1291 case AsmToken::LParen:
1292 case AsmToken::Integer:
1293 case AsmToken::Minus:
1294 case AsmToken::Plus:
1296 Result = getParser().parseParenExpression(Res, S);
1298 Result = (getParser().parseExpression(Res));
1299 while (getLexer().getKind() == AsmToken::RParen)
1302 case AsmToken::Percent:
1303 Result = parseRelocOperand(Res);
1308 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1309 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1311 const MCExpr *IdVal = 0;
1313 bool isParenExpr = false;
1314 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1315 // First operand is the offset.
1316 S = Parser.getTok().getLoc();
1318 if (getLexer().getKind() == AsmToken::LParen) {
1323 if (getLexer().getKind() != AsmToken::Dollar) {
1324 if (parseMemOffset(IdVal, isParenExpr))
1325 return MatchOperand_ParseFail;
1327 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1328 if (Tok.isNot(AsmToken::LParen)) {
1329 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1330 if (Mnemonic->getToken() == "la") {
1331 SMLoc E = SMLoc::getFromPointer(
1332 Parser.getTok().getLoc().getPointer() - 1);
1333 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1334 return MatchOperand_Success;
1336 if (Tok.is(AsmToken::EndOfStatement)) {
1337 SMLoc E = SMLoc::getFromPointer(
1338 Parser.getTok().getLoc().getPointer() - 1);
1340 // Zero register assumed, add a memory operand with ZERO as its base.
1341 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1344 return MatchOperand_Success;
1346 Error(Parser.getTok().getLoc(), "'(' expected");
1347 return MatchOperand_ParseFail;
1350 Parser.Lex(); // Eat the '(' token.
1353 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1354 (int) MipsOperand::Kind_GPR32);
1355 if (Res != MatchOperand_Success)
1358 if (Parser.getTok().isNot(AsmToken::RParen)) {
1359 Error(Parser.getTok().getLoc(), "')' expected");
1360 return MatchOperand_ParseFail;
1363 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1365 Parser.Lex(); // Eat the ')' token.
1368 IdVal = MCConstantExpr::Create(0, getContext());
1370 // Replace the register operand with the memory operand.
1371 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1372 int RegNo = op->getReg();
1373 // Remove the register from the operands.
1374 Operands.pop_back();
1375 // Add the memory operand.
1376 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1378 if (IdVal->EvaluateAsAbsolute(Imm))
1379 IdVal = MCConstantExpr::Create(Imm, getContext());
1380 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1381 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1385 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1387 return MatchOperand_Success;
1391 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1393 // If the first token is not '$' we have an error.
1394 if (Parser.getTok().isNot(AsmToken::Dollar))
1397 SMLoc S = Parser.getTok().getLoc();
1399 AsmToken::TokenKind TkKind = getLexer().getKind();
1402 if (TkKind == AsmToken::Integer) {
1403 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1404 regKindToRegClass(RegKind));
1407 } else if (TkKind == AsmToken::Identifier) {
1408 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1410 Reg = getReg(regKindToRegClass(RegKind), Reg);
1415 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1416 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1417 Operands.push_back(Op);
1422 MipsAsmParser::OperandMatchResultTy
1423 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1424 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1425 MipsOperand::Kind_GPR32;
1427 // Parse index register.
1428 if (!parsePtrReg(Operands, RegKind))
1429 return MatchOperand_NoMatch;
1432 if (Parser.getTok().isNot(AsmToken::LParen))
1433 return MatchOperand_NoMatch;
1435 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1438 // Parse base register.
1439 if (!parsePtrReg(Operands, RegKind))
1440 return MatchOperand_NoMatch;
1443 if (Parser.getTok().isNot(AsmToken::RParen))
1444 return MatchOperand_NoMatch;
1446 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1449 return MatchOperand_Success;
1452 MipsAsmParser::OperandMatchResultTy
1453 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1455 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1456 if (getLexer().getKind() == AsmToken::Identifier
1457 && !hasConsumedDollar) {
1458 if (searchSymbolAlias(Operands, Kind))
1459 return MatchOperand_Success;
1460 return MatchOperand_NoMatch;
1462 SMLoc S = Parser.getTok().getLoc();
1463 // If the first token is not '$', we have an error.
1464 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1465 return MatchOperand_NoMatch;
1466 if (!hasConsumedDollar) {
1467 Parser.Lex(); // Eat the '$'
1468 hasConsumedDollar = true;
1470 if (getLexer().getKind() == AsmToken::Identifier) {
1472 std::string RegName = Parser.getTok().getString().lower();
1473 // Match register by name
1475 case MipsOperand::Kind_GPR32:
1476 case MipsOperand::Kind_GPR64:
1477 RegNum = matchCPURegisterName(RegName);
1479 case MipsOperand::Kind_AFGR64Regs:
1480 case MipsOperand::Kind_FGR64Regs:
1481 case MipsOperand::Kind_FGR32Regs:
1482 case MipsOperand::Kind_FGRH32Regs:
1483 RegNum = matchFPURegisterName(RegName);
1484 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1486 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1488 if (RegNum != -1 && RegNum %2 != 0)
1489 Warning(S, "Float register should be even.");
1491 case MipsOperand::Kind_FCCRegs:
1492 RegNum = matchFCCRegisterName(RegName);
1494 case MipsOperand::Kind_ACC64DSP:
1495 RegNum = matchACRegisterName(RegName);
1497 default: break; // No match, value is set to -1.
1499 // No match found, return _NoMatch to give a chance to other round.
1501 return MatchOperand_NoMatch;
1503 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1505 return MatchOperand_NoMatch;
1507 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1508 Parser.getTok().getLoc());
1509 Op->setRegKind(Kind);
1510 Operands.push_back(Op);
1511 hasConsumedDollar = false;
1512 Parser.Lex(); // Eat the register name.
1513 return MatchOperand_Success;
1514 } else if (getLexer().getKind() == AsmToken::Integer) {
1515 unsigned RegNum = Parser.getTok().getIntVal();
1516 if (Kind == MipsOperand::Kind_HWRegs) {
1518 return MatchOperand_NoMatch;
1519 // Only hwreg 29 is supported, found at index 0.
1522 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1524 return MatchOperand_NoMatch;
1525 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1526 Op->setRegKind(Kind);
1527 Operands.push_back(Op);
1528 hasConsumedDollar = false;
1529 Parser.Lex(); // Eat the register number.
1530 if ((RegKind == MipsOperand::Kind_GPR32)
1531 && (getLexer().is(AsmToken::LParen))) {
1532 // Check if it is indexed addressing operand.
1533 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1534 Parser.Lex(); // Eat the parenthesis.
1535 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1536 return MatchOperand_NoMatch;
1537 if (getLexer().isNot(AsmToken::RParen))
1538 return MatchOperand_NoMatch;
1539 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1542 return MatchOperand_Success;
1544 return MatchOperand_NoMatch;
1547 MipsAsmParser::OperandMatchResultTy
1548 MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1550 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1551 SMLoc S = Parser.getTok().getLoc();
1552 std::string RegName;
1554 if (Parser.getTok().isNot(AsmToken::Dollar))
1555 return MatchOperand_NoMatch;
1559 return MatchOperand_ParseFail;
1560 case MipsOperand::Kind_MSA128BRegs:
1561 case MipsOperand::Kind_MSA128HRegs:
1562 case MipsOperand::Kind_MSA128WRegs:
1563 case MipsOperand::Kind_MSA128DRegs:
1567 Parser.Lex(); // Eat the '$'.
1568 if (getLexer().getKind() == AsmToken::Identifier)
1569 RegName = Parser.getTok().getString().lower();
1571 return MatchOperand_ParseFail;
1573 int RegNum = matchMSA128RegisterName(RegName);
1575 if (RegNum < 0 || RegNum > 31)
1576 return MatchOperand_ParseFail;
1578 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1580 return MatchOperand_ParseFail;
1582 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1583 Parser.getTok().getLoc());
1584 Op->setRegKind(Kind);
1585 Operands.push_back(Op);
1587 Parser.Lex(); // Eat the register identifier.
1589 return MatchOperand_Success;
1592 MipsAsmParser::OperandMatchResultTy
1593 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1596 return MatchOperand_NoMatch;
1597 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
1600 MipsAsmParser::OperandMatchResultTy
1601 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1602 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
1605 MipsAsmParser::OperandMatchResultTy
1606 MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1609 return MatchOperand_NoMatch;
1610 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1613 MipsAsmParser::OperandMatchResultTy
1614 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1616 return MatchOperand_NoMatch;
1617 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1620 MipsAsmParser::OperandMatchResultTy
1621 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1622 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1625 MipsAsmParser::OperandMatchResultTy
1626 MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1627 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1630 MipsAsmParser::OperandMatchResultTy
1631 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1632 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
1635 MipsAsmParser::OperandMatchResultTy
1636 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1637 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
1640 MipsAsmParser::OperandMatchResultTy
1641 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1642 // If the first token is not '$' we have an error.
1643 if (Parser.getTok().isNot(AsmToken::Dollar))
1644 return MatchOperand_NoMatch;
1646 SMLoc S = Parser.getTok().getLoc();
1647 Parser.Lex(); // Eat the '$'
1649 const AsmToken &Tok = Parser.getTok(); // Get next token.
1651 if (Tok.isNot(AsmToken::Identifier))
1652 return MatchOperand_NoMatch;
1654 if (!Tok.getIdentifier().startswith("ac"))
1655 return MatchOperand_NoMatch;
1657 StringRef NumString = Tok.getIdentifier().substr(2);
1660 if (NumString.getAsInteger(10, IntVal))
1661 return MatchOperand_NoMatch;
1663 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1665 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1666 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1667 Operands.push_back(Op);
1669 Parser.Lex(); // Eat the register number.
1670 return MatchOperand_Success;
1673 MipsAsmParser::OperandMatchResultTy
1674 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1675 // If the first token is not '$' we have an error.
1676 if (Parser.getTok().isNot(AsmToken::Dollar))
1677 return MatchOperand_NoMatch;
1679 SMLoc S = Parser.getTok().getLoc();
1680 Parser.Lex(); // Eat the '$'
1682 const AsmToken &Tok = Parser.getTok(); // Get next token.
1684 if (Tok.isNot(AsmToken::Identifier))
1685 return MatchOperand_NoMatch;
1687 if (!Tok.getIdentifier().startswith("ac"))
1688 return MatchOperand_NoMatch;
1690 StringRef NumString = Tok.getIdentifier().substr(2);
1693 if (NumString.getAsInteger(10, IntVal))
1694 return MatchOperand_NoMatch;
1696 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1698 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1699 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1700 Operands.push_back(Op);
1702 Parser.Lex(); // Eat the register number.
1703 return MatchOperand_Success;
1706 MipsAsmParser::OperandMatchResultTy
1707 MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1708 // If the first token is not '$' we have an error.
1709 if (Parser.getTok().isNot(AsmToken::Dollar))
1710 return MatchOperand_NoMatch;
1712 SMLoc S = Parser.getTok().getLoc();
1713 Parser.Lex(); // Eat the '$'
1715 const AsmToken &Tok = Parser.getTok(); // Get next token.
1717 if (Tok.isNot(AsmToken::Integer))
1718 return MatchOperand_NoMatch;
1720 unsigned IntVal = Tok.getIntVal();
1722 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1724 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1725 Op->setRegKind(MipsOperand::Kind_COP2);
1726 Operands.push_back(Op);
1728 Parser.Lex(); // Eat the register number.
1729 return MatchOperand_Success;
1732 MipsAsmParser::OperandMatchResultTy
1733 MipsAsmParser::parseMSA128BRegs(
1734 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1735 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1738 MipsAsmParser::OperandMatchResultTy
1739 MipsAsmParser::parseMSA128HRegs(
1740 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1741 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1744 MipsAsmParser::OperandMatchResultTy
1745 MipsAsmParser::parseMSA128WRegs(
1746 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1747 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1750 MipsAsmParser::OperandMatchResultTy
1751 MipsAsmParser::parseMSA128DRegs(
1752 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1753 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1756 bool MipsAsmParser::searchSymbolAlias(
1757 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1759 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1761 SMLoc S = Parser.getTok().getLoc();
1763 if (Sym->isVariable())
1764 Expr = Sym->getVariableValue();
1767 if (Expr->getKind() == MCExpr::SymbolRef) {
1768 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1769 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1770 const StringRef DefSymbol = Ref->getSymbol().getName();
1771 if (DefSymbol.startswith("$")) {
1773 APInt IntVal(32, -1);
1774 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1775 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1777 ? Mips::GPR64RegClassID
1778 : Mips::GPR32RegClassID);
1780 // Lookup for the register with the corresponding name.
1782 case MipsOperand::Kind_AFGR64Regs:
1783 case MipsOperand::Kind_FGR64Regs:
1784 RegNum = matchFPURegisterName(DefSymbol.substr(1));
1786 case MipsOperand::Kind_FGR32Regs:
1787 RegNum = matchFPURegisterName(DefSymbol.substr(1));
1789 case MipsOperand::Kind_GPR64:
1790 case MipsOperand::Kind_GPR32:
1792 RegNum = matchCPURegisterName(DefSymbol.substr(1));
1796 RegNum = getReg(regKindToRegClass(Kind), RegNum);
1800 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1801 Parser.getTok().getLoc());
1802 op->setRegKind(Kind);
1803 Operands.push_back(op);
1807 } else if (Expr->getKind() == MCExpr::Constant) {
1809 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1810 MipsOperand *op = MipsOperand::CreateImm(Const, S,
1811 Parser.getTok().getLoc());
1812 Operands.push_back(op);
1819 MipsAsmParser::OperandMatchResultTy
1820 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1821 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
1824 MipsAsmParser::OperandMatchResultTy
1825 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1826 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
1829 MipsAsmParser::OperandMatchResultTy
1830 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1831 const MCExpr *IdVal;
1832 // If the first token is '$' we may have register operand.
1833 if (Parser.getTok().is(AsmToken::Dollar))
1834 return MatchOperand_NoMatch;
1835 SMLoc S = Parser.getTok().getLoc();
1836 if (getParser().parseExpression(IdVal))
1837 return MatchOperand_ParseFail;
1838 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1839 assert( MCE && "Unexpected MCExpr type.");
1840 int64_t Val = MCE->getValue();
1841 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1842 Operands.push_back(MipsOperand::CreateImm(
1843 MCConstantExpr::Create(0 - Val, getContext()), S, E));
1844 return MatchOperand_Success;
1847 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1849 MCSymbolRefExpr::VariantKind VK
1850 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1851 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1852 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1853 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1854 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1855 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1856 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1857 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1858 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1859 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1860 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1861 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1862 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1863 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1864 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1865 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1866 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1867 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1868 .Default(MCSymbolRefExpr::VK_None);
1873 bool MipsAsmParser::
1874 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1875 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1876 // Check if we have valid mnemonic
1877 if (!mnemonicIsValid(Name, 0)) {
1878 Parser.eatToEndOfStatement();
1879 return Error(NameLoc, "Unknown instruction");
1881 // First operand in MCInst is instruction mnemonic.
1882 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1884 // Read the remaining operands.
1885 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1886 // Read the first operand.
1887 if (ParseOperand(Operands, Name)) {
1888 SMLoc Loc = getLexer().getLoc();
1889 Parser.eatToEndOfStatement();
1890 return Error(Loc, "unexpected token in argument list");
1893 while (getLexer().is(AsmToken::Comma)) {
1894 Parser.Lex(); // Eat the comma.
1895 // Parse and remember the operand.
1896 if (ParseOperand(Operands, Name)) {
1897 SMLoc Loc = getLexer().getLoc();
1898 Parser.eatToEndOfStatement();
1899 return Error(Loc, "unexpected token in argument list");
1903 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1904 SMLoc Loc = getLexer().getLoc();
1905 Parser.eatToEndOfStatement();
1906 return Error(Loc, "unexpected token in argument list");
1908 Parser.Lex(); // Consume the EndOfStatement.
1912 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1913 SMLoc Loc = getLexer().getLoc();
1914 Parser.eatToEndOfStatement();
1915 return Error(Loc, ErrorMsg);
1918 bool MipsAsmParser::parseSetNoAtDirective() {
1919 // Line should look like: ".set noat".
1921 Options.setATReg(0);
1924 // If this is not the end of the statement, report an error.
1925 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1926 reportParseError("unexpected token in statement");
1929 Parser.Lex(); // Consume the EndOfStatement.
1933 bool MipsAsmParser::parseSetAtDirective() {
1934 // Line can be .set at - defaults to $1
1938 if (getLexer().is(AsmToken::EndOfStatement)) {
1939 Options.setATReg(1);
1940 Parser.Lex(); // Consume the EndOfStatement.
1942 } else if (getLexer().is(AsmToken::Equal)) {
1943 getParser().Lex(); // Eat the '='.
1944 if (getLexer().isNot(AsmToken::Dollar)) {
1945 reportParseError("unexpected token in statement");
1948 Parser.Lex(); // Eat the '$'.
1949 const AsmToken &Reg = Parser.getTok();
1950 if (Reg.is(AsmToken::Identifier)) {
1951 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1952 } else if (Reg.is(AsmToken::Integer)) {
1953 AtRegNo = Reg.getIntVal();
1955 reportParseError("unexpected token in statement");
1959 if (AtRegNo < 1 || AtRegNo > 31) {
1960 reportParseError("unexpected token in statement");
1964 if (!Options.setATReg(AtRegNo)) {
1965 reportParseError("unexpected token in statement");
1968 getParser().Lex(); // Eat the register.
1970 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1971 reportParseError("unexpected token in statement");
1974 Parser.Lex(); // Consume the EndOfStatement.
1977 reportParseError("unexpected token in statement");
1982 bool MipsAsmParser::parseSetReorderDirective() {
1984 // If this is not the end of the statement, report an error.
1985 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1986 reportParseError("unexpected token in statement");
1989 Options.setReorder();
1990 Parser.Lex(); // Consume the EndOfStatement.
1994 bool MipsAsmParser::parseSetNoReorderDirective() {
1996 // If this is not the end of the statement, report an error.
1997 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1998 reportParseError("unexpected token in statement");
2001 Options.setNoreorder();
2002 Parser.Lex(); // Consume the EndOfStatement.
2006 bool MipsAsmParser::parseSetMacroDirective() {
2008 // If this is not the end of the statement, report an error.
2009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2010 reportParseError("unexpected token in statement");
2014 Parser.Lex(); // Consume the EndOfStatement.
2018 bool MipsAsmParser::parseSetNoMacroDirective() {
2020 // If this is not the end of the statement, report an error.
2021 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2022 reportParseError("`noreorder' must be set before `nomacro'");
2025 if (Options.isReorder()) {
2026 reportParseError("`noreorder' must be set before `nomacro'");
2029 Options.setNomacro();
2030 Parser.Lex(); // Consume the EndOfStatement.
2034 bool MipsAsmParser::parseSetAssignment() {
2036 const MCExpr *Value;
2038 if (Parser.parseIdentifier(Name))
2039 reportParseError("expected identifier after .set");
2041 if (getLexer().isNot(AsmToken::Comma))
2042 return reportParseError("unexpected token in .set directive");
2045 if (getLexer().is(AsmToken::Dollar)) {
2047 SMLoc DollarLoc = getLexer().getLoc();
2048 // Consume the dollar sign, and check for a following identifier.
2050 // We have a '$' followed by something, make sure they are adjacent.
2051 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2053 StringRef Res = StringRef(DollarLoc.getPointer(),
2054 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2055 Symbol = getContext().GetOrCreateSymbol(Res);
2057 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2059 } else if (Parser.parseExpression(Value))
2060 return reportParseError("expected valid expression after comma");
2062 // Check if the Name already exists as a symbol.
2063 MCSymbol *Sym = getContext().LookupSymbol(Name);
2065 return reportParseError("symbol already defined");
2066 Sym = getContext().GetOrCreateSymbol(Name);
2067 Sym->setVariableValue(Value);
2072 bool MipsAsmParser::parseDirectiveSet() {
2074 // Get the next token.
2075 const AsmToken &Tok = Parser.getTok();
2077 if (Tok.getString() == "noat") {
2078 return parseSetNoAtDirective();
2079 } else if (Tok.getString() == "at") {
2080 return parseSetAtDirective();
2081 } else if (Tok.getString() == "reorder") {
2082 return parseSetReorderDirective();
2083 } else if (Tok.getString() == "noreorder") {
2084 return parseSetNoReorderDirective();
2085 } else if (Tok.getString() == "macro") {
2086 return parseSetMacroDirective();
2087 } else if (Tok.getString() == "nomacro") {
2088 return parseSetNoMacroDirective();
2089 } else if (Tok.getString() == "nomips16") {
2090 // Ignore this directive for now.
2091 Parser.eatToEndOfStatement();
2093 } else if (Tok.getString() == "nomicromips") {
2094 // Ignore this directive for now.
2095 Parser.eatToEndOfStatement();
2098 // It is just an identifier, look for an assignment.
2099 parseSetAssignment();
2106 /// parseDirectiveWord
2107 /// ::= .word [ expression (, expression)* ]
2108 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2109 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2111 const MCExpr *Value;
2112 if (getParser().parseExpression(Value))
2115 getParser().getStreamer().EmitValue(Value, Size);
2117 if (getLexer().is(AsmToken::EndOfStatement))
2120 // FIXME: Improve diagnostic.
2121 if (getLexer().isNot(AsmToken::Comma))
2122 return Error(L, "unexpected token in directive");
2131 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2133 StringRef IDVal = DirectiveID.getString();
2135 if (IDVal == ".ent") {
2136 // Ignore this directive for now.
2141 if (IDVal == ".end") {
2142 // Ignore this directive for now.
2147 if (IDVal == ".frame") {
2148 // Ignore this directive for now.
2149 Parser.eatToEndOfStatement();
2153 if (IDVal == ".set") {
2154 return parseDirectiveSet();
2157 if (IDVal == ".fmask") {
2158 // Ignore this directive for now.
2159 Parser.eatToEndOfStatement();
2163 if (IDVal == ".mask") {
2164 // Ignore this directive for now.
2165 Parser.eatToEndOfStatement();
2169 if (IDVal == ".gpword") {
2170 // Ignore this directive for now.
2171 Parser.eatToEndOfStatement();
2175 if (IDVal == ".word") {
2176 parseDirectiveWord(4, DirectiveID.getLoc());
2180 if (IDVal == ".abicalls") {
2181 Flags.setRelocationModel(MipsMCAsmFlags::MAF_RM_CPIC);
2182 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
2183 return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2190 /// End of assembly processing such as updating ELF header flags.
2191 void MipsAsmParser::emitEndOfAsmFile(MCStreamer &OutStreamer) {
2192 if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer))
2193 MES->emitELFHeaderFlagsAsm(Flags);
2194 MCTargetAsmParser::emitEndOfAsmFile(OutStreamer);
2197 extern "C" void LLVMInitializeMipsAsmParser() {
2198 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2199 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2200 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2201 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2204 #define GET_REGISTER_MATCHER
2205 #define GET_MATCHER_IMPLEMENTATION
2206 #include "MipsGenAsmMatcher.inc"