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 "llvm/ADT/StringSwitch.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCParser/MCAsmLexer.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSubtargetInfo.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/MC/MCTargetAsmParser.h"
22 #include "llvm/Support/TargetRegistry.h"
27 class MipsAssemblerOptions {
29 MipsAssemblerOptions():
30 aTReg(1), reorder(true), macro(true) {
33 unsigned getATRegNum() {return aTReg;}
34 bool setATReg(unsigned Reg);
36 bool isReorder() {return reorder;}
37 void setReorder() {reorder = true;}
38 void setNoreorder() {reorder = false;}
40 bool isMacro() {return macro;}
41 void setMacro() {macro = true;}
42 void setNomacro() {macro = false;}
52 class MipsAsmParser : public MCTargetAsmParser {
64 MipsAssemblerOptions Options;
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 parseMathOperation(StringRef Name, SMLoc NameLoc,
82 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
84 bool ParseDirective(AsmToken DirectiveID);
86 MipsAsmParser::OperandMatchResultTy
87 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
89 MipsAsmParser::OperandMatchResultTy
90 parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
92 MipsAsmParser::OperandMatchResultTy
93 parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95 MipsAsmParser::OperandMatchResultTy
96 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
98 MipsAsmParser::OperandMatchResultTy
99 parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
101 MipsAsmParser::OperandMatchResultTy
102 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
104 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
105 unsigned RegisterClass);
107 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
110 int tryParseRegister(bool is64BitReg);
112 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
115 bool needsExpansion(MCInst &Inst);
117 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
118 SmallVectorImpl<MCInst> &Instructions);
119 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
120 SmallVectorImpl<MCInst> &Instructions);
121 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
122 SmallVectorImpl<MCInst> &Instructions);
123 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
124 SmallVectorImpl<MCInst> &Instructions);
125 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
126 SmallVectorImpl<MCInst> &Instructions,
127 bool isLoad,bool isImmOpnd);
128 bool reportParseError(StringRef ErrorMsg);
130 bool parseMemOffset(const MCExpr *&Res);
131 bool parseRelocOperand(const MCExpr *&Res);
133 bool parseDirectiveSet();
135 bool parseSetAtDirective();
136 bool parseSetNoAtDirective();
137 bool parseSetMacroDirective();
138 bool parseSetNoMacroDirective();
139 bool parseSetReorderDirective();
140 bool parseSetNoReorderDirective();
142 bool parseSetAssignment();
144 bool parseDirectiveWord(unsigned Size, SMLoc L);
146 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
148 bool isMips64() const {
149 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
152 bool isFP64() const {
153 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
156 int matchRegisterName(StringRef Symbol, bool is64BitReg);
158 int matchCPURegisterName(StringRef Symbol);
160 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
162 void setFpFormat(FpFormatTy Format) {
166 void setDefaultFpFormat();
168 void setFpFormat(StringRef Format);
170 FpFormatTy getFpFormat() {return FpFormat;}
172 bool requestsDoubleOperand(StringRef Mnemonic);
174 unsigned getReg(int RC,int RegNo);
178 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions);
181 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
182 : MCTargetAsmParser(), STI(sti), Parser(parser) {
183 // Initialize the set of available features.
184 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
187 MCAsmParser &getParser() const { return Parser; }
188 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
195 /// MipsOperand - Instances of this class represent a parsed Mips machine
197 class MipsOperand : public MCParsedAsmOperand {
223 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
251 SMLoc StartLoc, EndLoc;
254 void addRegOperands(MCInst &Inst, unsigned N) const {
255 assert(N == 1 && "Invalid number of operands!");
256 Inst.addOperand(MCOperand::CreateReg(getReg()));
259 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
260 // Add as immediate when possible. Null MCExpr = 0.
262 Inst.addOperand(MCOperand::CreateImm(0));
263 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
264 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
266 Inst.addOperand(MCOperand::CreateExpr(Expr));
269 void addImmOperands(MCInst &Inst, unsigned N) const {
270 assert(N == 1 && "Invalid number of operands!");
271 const MCExpr *Expr = getImm();
275 void addMemOperands(MCInst &Inst, unsigned N) const {
276 assert(N == 2 && "Invalid number of operands!");
278 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
280 const MCExpr *Expr = getMemOff();
284 bool isReg() const { return Kind == k_Register; }
285 bool isImm() const { return Kind == k_Immediate; }
286 bool isToken() const { return Kind == k_Token; }
287 bool isMem() const { return Kind == k_Memory; }
289 StringRef getToken() const {
290 assert(Kind == k_Token && "Invalid access!");
291 return StringRef(Tok.Data, Tok.Length);
294 unsigned getReg() const {
295 assert((Kind == k_Register) && "Invalid access!");
299 void setRegKind(RegisterKind RegKind) {
300 assert((Kind == k_Register) && "Invalid access!");
304 const MCExpr *getImm() const {
305 assert((Kind == k_Immediate) && "Invalid access!");
309 unsigned getMemBase() const {
310 assert((Kind == k_Memory) && "Invalid access!");
314 const MCExpr *getMemOff() const {
315 assert((Kind == k_Memory) && "Invalid access!");
319 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
320 MipsOperand *Op = new MipsOperand(k_Token);
321 Op->Tok.Data = Str.data();
322 Op->Tok.Length = Str.size();
328 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
329 MipsOperand *Op = new MipsOperand(k_Register);
330 Op->Reg.RegNum = RegNum;
336 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
337 MipsOperand *Op = new MipsOperand(k_Immediate);
344 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
346 MipsOperand *Op = new MipsOperand(k_Memory);
354 bool isCPURegsAsm() const {
355 return Kind == k_Register && Reg.Kind == Kind_CPURegs;
357 void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const {
358 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
361 bool isCPU64RegsAsm() const {
362 return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
364 void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const {
365 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
368 bool isHWRegsAsm() const {
369 assert((Kind == k_Register) && "Invalid access!");
370 return Reg.Kind == Kind_HWRegs;
372 void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const {
373 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
376 bool isHW64RegsAsm() const {
377 assert((Kind == k_Register) && "Invalid access!");
378 return Reg.Kind == Kind_HW64Regs;
380 void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const {
381 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
384 void addCCRAsmOperands(MCInst &Inst, unsigned N) const {
385 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
388 bool isCCRAsm() const {
389 assert((Kind == k_Register) && "Invalid access!");
390 return Reg.Kind == Kind_CCRRegs;
393 /// getStartLoc - Get the location of the first token of this operand.
394 SMLoc getStartLoc() const { return StartLoc; }
395 /// getEndLoc - Get the location of the last token of this operand.
396 SMLoc getEndLoc() const { return EndLoc; }
398 virtual void print(raw_ostream &OS) const {
399 llvm_unreachable("unimplemented!");
405 extern const MCInstrDesc MipsInsts[];
407 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
408 return MipsInsts[Opcode];
411 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
412 SmallVectorImpl<MCInst> &Instructions) {
413 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
415 if (MCID.mayLoad() || MCID.mayStore()) {
416 // Check the offset of memory operand, if it is a symbol
417 // reference or immediate we may have to expand instructions
418 for (unsigned i=0;i<MCID.getNumOperands();i++) {
419 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
420 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
421 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
422 MCOperand &Op = Inst.getOperand(i);
424 int MemOffset = Op.getImm();
425 if (MemOffset < -32768 || MemOffset > 32767) {
426 // Offset can't exceed 16bit value
427 expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),true);
430 } else if (Op.isExpr()) {
431 const MCExpr *Expr = Op.getExpr();
432 if (Expr->getKind() == MCExpr::SymbolRef){
433 const MCSymbolRefExpr *SR =
434 static_cast<const MCSymbolRefExpr*>(Expr);
435 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
437 expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),false);
446 if (needsExpansion(Inst))
447 expandInstruction(Inst, IDLoc, Instructions);
449 Instructions.push_back(Inst);
454 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
456 switch(Inst.getOpcode()) {
457 case Mips::LoadImm32Reg:
458 case Mips::LoadAddr32Imm:
459 case Mips::LoadAddr32Reg:
466 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
467 SmallVectorImpl<MCInst> &Instructions){
468 switch(Inst.getOpcode()) {
469 case Mips::LoadImm32Reg:
470 return expandLoadImm(Inst, IDLoc, Instructions);
471 case Mips::LoadAddr32Imm:
472 return expandLoadAddressImm(Inst,IDLoc,Instructions);
473 case Mips::LoadAddr32Reg:
474 return expandLoadAddressReg(Inst,IDLoc,Instructions);
478 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
479 SmallVectorImpl<MCInst> &Instructions){
481 const MCOperand &ImmOp = Inst.getOperand(1);
482 assert(ImmOp.isImm() && "expected immediate operand kind");
483 const MCOperand &RegOp = Inst.getOperand(0);
484 assert(RegOp.isReg() && "expected register operand kind");
486 int ImmValue = ImmOp.getImm();
487 tmpInst.setLoc(IDLoc);
488 if ( 0 <= ImmValue && ImmValue <= 65535) {
489 // for 0 <= j <= 65535.
490 // li d,j => ori d,$zero,j
491 tmpInst.setOpcode(Mips::ORi);
492 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
494 MCOperand::CreateReg(Mips::ZERO));
495 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
496 Instructions.push_back(tmpInst);
497 } else if ( ImmValue < 0 && ImmValue >= -32768) {
498 // for -32768 <= j < 0.
499 // li d,j => addiu d,$zero,j
500 tmpInst.setOpcode(Mips::ADDiu);
501 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
503 MCOperand::CreateReg(Mips::ZERO));
504 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
505 Instructions.push_back(tmpInst);
507 // for any other value of j that is representable as a 32-bit integer.
508 // li d,j => lui d,hi16(j)
510 tmpInst.setOpcode(Mips::LUi);
511 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
512 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
513 Instructions.push_back(tmpInst);
515 tmpInst.setOpcode(Mips::ORi);
516 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
517 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
518 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
519 tmpInst.setLoc(IDLoc);
520 Instructions.push_back(tmpInst);
524 void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
525 SmallVectorImpl<MCInst> &Instructions){
527 const MCOperand &ImmOp = Inst.getOperand(2);
528 assert(ImmOp.isImm() && "expected immediate operand kind");
529 const MCOperand &SrcRegOp = Inst.getOperand(1);
530 assert(SrcRegOp.isReg() && "expected register operand kind");
531 const MCOperand &DstRegOp = Inst.getOperand(0);
532 assert(DstRegOp.isReg() && "expected register operand kind");
533 int ImmValue = ImmOp.getImm();
534 if ( -32768 <= ImmValue && ImmValue <= 65535) {
535 //for -32768 <= j <= 65535.
536 //la d,j(s) => addiu d,s,j
537 tmpInst.setOpcode(Mips::ADDiu);
538 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
539 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
540 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
541 Instructions.push_back(tmpInst);
543 //for any other value of j that is representable as a 32-bit integer.
544 //la d,j(s) => lui d,hi16(j)
547 tmpInst.setOpcode(Mips::LUi);
548 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
549 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
550 Instructions.push_back(tmpInst);
552 tmpInst.setOpcode(Mips::ORi);
553 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
554 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
555 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
556 Instructions.push_back(tmpInst);
558 tmpInst.setOpcode(Mips::ADDu);
559 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
560 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
561 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
562 Instructions.push_back(tmpInst);
566 void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
567 SmallVectorImpl<MCInst> &Instructions){
569 const MCOperand &ImmOp = Inst.getOperand(1);
570 assert(ImmOp.isImm() && "expected immediate operand kind");
571 const MCOperand &RegOp = Inst.getOperand(0);
572 assert(RegOp.isReg() && "expected register operand kind");
573 int ImmValue = ImmOp.getImm();
574 if ( -32768 <= ImmValue && ImmValue <= 65535) {
575 //for -32768 <= j <= 65535.
576 //la d,j => addiu d,$zero,j
577 tmpInst.setOpcode(Mips::ADDiu);
578 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
580 MCOperand::CreateReg(Mips::ZERO));
581 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
582 Instructions.push_back(tmpInst);
584 //for any other value of j that is representable as a 32-bit integer.
585 //la d,j => lui d,hi16(j)
587 tmpInst.setOpcode(Mips::LUi);
588 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
589 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
590 Instructions.push_back(tmpInst);
592 tmpInst.setOpcode(Mips::ORi);
593 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
594 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
595 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
596 Instructions.push_back(tmpInst);
600 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
601 SmallVectorImpl<MCInst> &Instructions,
602 bool isLoad,bool isImmOpnd) {
603 const MCSymbolRefExpr *SR;
605 unsigned ImmOffset,HiOffset,LoOffset;
606 const MCExpr *ExprOffset;
608 unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID:
609 Mips::CPURegsRegClassID,
611 // 1st operand is either source or dst register
612 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
613 unsigned RegOpNum = Inst.getOperand(0).getReg();
614 // 2nd operand is base register
615 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
616 unsigned BaseRegNum = Inst.getOperand(1).getReg();
617 // 3rd operand is either immediate or expression
619 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
620 ImmOffset = Inst.getOperand(2).getImm();
621 LoOffset = ImmOffset & 0x0000ffff;
622 HiOffset = (ImmOffset & 0xffff0000) >> 16;
623 // If msb of LoOffset is 1(negative number) we must increment HiOffset
624 if (LoOffset & 0x8000)
628 ExprOffset = Inst.getOperand(2).getExpr();
629 // All instructions will have the same location
630 TempInst.setLoc(IDLoc);
631 // 1st instruction in expansion is LUi. For load instruction we can use
632 // the dst register as a temporary if base and dst are different,
633 // but for stores we must use $at
634 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum))?RegOpNum:AtRegNum;
635 TempInst.setOpcode(Mips::LUi);
636 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
638 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
640 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
641 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
642 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::
643 Create(SR->getSymbol().getName(),
644 MCSymbolRefExpr::VK_Mips_ABS_HI,
646 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
649 // Add the instruction to the list
650 Instructions.push_back(TempInst);
651 // and prepare TempInst for next instruction
653 // which is add temp register to base
654 TempInst.setOpcode(Mips::ADDu);
655 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
656 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
657 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
658 Instructions.push_back(TempInst);
660 // and finaly, create original instruction with low part
661 // of offset and new base
662 TempInst.setOpcode(Inst.getOpcode());
663 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
664 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
666 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
668 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
669 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::
670 Create(SR->getSymbol().getName(),
671 MCSymbolRefExpr::VK_Mips_ABS_LO,
673 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
676 Instructions.push_back(TempInst);
681 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
682 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
683 MCStreamer &Out, unsigned &ErrorInfo,
684 bool MatchingInlineAsm) {
686 SmallVector<MCInst, 8> Instructions;
687 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
690 switch (MatchResult) {
692 case Match_Success: {
693 if (processInstruction(Inst,IDLoc,Instructions))
695 for(unsigned i =0; i < Instructions.size(); i++)
696 Out.EmitInstruction(Instructions[i]);
699 case Match_MissingFeature:
700 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
702 case Match_InvalidOperand: {
703 SMLoc ErrorLoc = IDLoc;
704 if (ErrorInfo != ~0U) {
705 if (ErrorInfo >= Operands.size())
706 return Error(IDLoc, "too few operands for instruction");
708 ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc();
709 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
712 return Error(ErrorLoc, "invalid operand for instruction");
714 case Match_MnemonicFail:
715 return Error(IDLoc, "invalid instruction");
720 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
726 CC = StringSwitch<unsigned>(Name)
760 // Although SGI documentation just cut out t0-t3 for n32/n64,
761 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
762 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
763 if (isMips64() && 8 <= CC && CC <= 11)
766 if (CC == -1 && isMips64())
767 CC = StringSwitch<unsigned>(Name)
779 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
781 if (Name.equals("fcc0"))
785 CC = matchCPURegisterName(Name);
787 return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID:
788 Mips::CPURegsRegClassID);
790 if (Name[0] == 'f') {
791 StringRef NumString = Name.substr(1);
793 if( NumString.getAsInteger(10, IntVal))
794 return -1; // not integer
798 FpFormatTy Format = getFpFormat();
800 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
801 return getReg(Mips::FGR32RegClassID, IntVal);
802 if (Format == FP_FORMAT_D) {
804 return getReg(Mips::FGR64RegClassID, IntVal);
806 // only even numbers available as register pairs
807 if (( IntVal > 31) || (IntVal%2 != 0))
809 return getReg(Mips::AFGR64RegClassID, IntVal/2);
815 void MipsAsmParser::setDefaultFpFormat() {
817 if (isMips64() || isFP64())
818 FpFormat = FP_FORMAT_D;
820 FpFormat = FP_FORMAT_S;
823 bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
825 bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
834 void MipsAsmParser::setFpFormat(StringRef Format) {
836 FpFormat = StringSwitch<FpFormatTy>(Format.lower())
837 .Case(".s", FP_FORMAT_S)
838 .Case(".d", FP_FORMAT_D)
839 .Case(".l", FP_FORMAT_L)
840 .Case(".w", FP_FORMAT_W)
841 .Default(FP_FORMAT_NONE);
844 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
852 int MipsAsmParser::getATReg() {
853 return Options.getATRegNum();
856 unsigned MipsAsmParser::getReg(int RC,int RegNo) {
857 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
860 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
865 return getReg(RegClass, RegNum);
868 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
869 const AsmToken &Tok = Parser.getTok();
872 if (Tok.is(AsmToken::Identifier)) {
873 std::string lowerCase = Tok.getString().lower();
874 RegNum = matchRegisterName(lowerCase, is64BitReg);
875 } else if (Tok.is(AsmToken::Integer))
876 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
877 is64BitReg ? Mips::CPU64RegsRegClassID
878 : Mips::CPURegsRegClassID);
883 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
886 SMLoc S = Parser.getTok().getLoc();
889 RegNo = tryParseRegister(is64BitReg);
893 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
894 Parser.getTok().getLoc()));
895 Parser.Lex(); // Eat register token.
899 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
900 StringRef Mnemonic) {
901 // Check if the current operand has a custom associated parser, if so, try to
902 // custom parse the operand, or fallback to the general approach.
903 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
904 if (ResTy == MatchOperand_Success)
906 // If there wasn't a custom match, try the generic matcher below. Otherwise,
907 // there was a match, but an error occurred, in which case, just return that
908 // the operand parsing failed.
909 if (ResTy == MatchOperand_ParseFail)
912 switch (getLexer().getKind()) {
914 Error(Parser.getTok().getLoc(), "unexpected token in operand");
916 case AsmToken::Dollar: {
918 SMLoc S = Parser.getTok().getLoc();
919 Parser.Lex(); // Eat dollar token.
920 // parse register operand
921 if (!tryParseRegisterOperand(Operands, isMips64())) {
922 if (getLexer().is(AsmToken::LParen)) {
923 // check if it is indexed addressing operand
924 Operands.push_back(MipsOperand::CreateToken("(", S));
925 Parser.Lex(); // eat parenthesis
926 if (getLexer().isNot(AsmToken::Dollar))
929 Parser.Lex(); // eat dollar
930 if (tryParseRegisterOperand(Operands, isMips64()))
933 if (!getLexer().is(AsmToken::RParen))
936 S = Parser.getTok().getLoc();
937 Operands.push_back(MipsOperand::CreateToken(")", S));
942 // maybe it is a symbol reference
943 StringRef Identifier;
944 if (Parser.parseIdentifier(Identifier))
947 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
949 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
951 // Otherwise create a symbol ref.
952 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
955 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
958 case AsmToken::Identifier:
959 // Look for the existing symbol, we should check if
960 // we need to assigne the propper RegisterKind
961 if (searchSymbolAlias(Operands,MipsOperand::Kind_None))
963 //else drop to expression parsing
964 case AsmToken::LParen:
965 case AsmToken::Minus:
967 case AsmToken::Integer:
968 case AsmToken::String: {
969 // quoted label names
971 SMLoc S = Parser.getTok().getLoc();
972 if (getParser().parseExpression(IdVal))
974 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
975 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
978 case AsmToken::Percent: {
979 // it is a symbol reference or constant expression
981 SMLoc S = Parser.getTok().getLoc(); // start location of the operand
982 if (parseRelocOperand(IdVal))
985 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
987 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
989 } // case AsmToken::Percent
990 } // switch(getLexer().getKind())
994 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
996 Parser.Lex(); // eat % token
997 const AsmToken &Tok = Parser.getTok(); // get next token, operation
998 if (Tok.isNot(AsmToken::Identifier))
1001 std::string Str = Tok.getIdentifier().str();
1003 Parser.Lex(); // eat identifier
1004 // now make expression from the rest of the operand
1005 const MCExpr *IdVal;
1008 if (getLexer().getKind() == AsmToken::LParen) {
1010 Parser.Lex(); // eat '(' token
1011 if (getLexer().getKind() == AsmToken::Percent) {
1012 Parser.Lex(); // eat % token
1013 const AsmToken &nextTok = Parser.getTok();
1014 if (nextTok.isNot(AsmToken::Identifier))
1017 Str += nextTok.getIdentifier();
1018 Parser.Lex(); // eat identifier
1019 if (getLexer().getKind() != AsmToken::LParen)
1024 if (getParser().parseParenExpression(IdVal,EndLoc))
1027 while (getLexer().getKind() == AsmToken::RParen)
1028 Parser.Lex(); // eat ')' token
1031 return true; // parenthesis must follow reloc operand
1033 // Check the type of the expression
1034 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
1035 // It's a constant, evaluate lo or hi value
1037 short Val = MCE->getValue();
1038 Res = MCConstantExpr::Create(Val, getContext());
1039 } else if (Str == "hi") {
1040 int Val = MCE->getValue();
1041 int LoSign = Val & 0x8000;
1042 Val = (Val & 0xffff0000) >> 16;
1043 // Lower part is treated as a signed int, so if it is negative
1044 // we must add 1 to the hi part to compensate
1047 Res = MCConstantExpr::Create(Val, getContext());
1052 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
1053 // It's a symbol, create symbolic expression from symbol
1054 StringRef Symbol = MSRE->getSymbol().getName();
1055 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
1056 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
1062 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1065 StartLoc = Parser.getTok().getLoc();
1066 RegNo = tryParseRegister(isMips64());
1067 EndLoc = Parser.getTok().getLoc();
1068 return (RegNo == (unsigned)-1);
1071 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
1075 switch(getLexer().getKind()) {
1078 case AsmToken::Identifier:
1079 case AsmToken::Integer:
1080 case AsmToken::Minus:
1081 case AsmToken::Plus:
1082 return (getParser().parseExpression(Res));
1083 case AsmToken::Percent:
1084 return parseRelocOperand(Res);
1085 case AsmToken::LParen:
1086 return false; // it's probably assuming 0
1091 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1092 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1094 const MCExpr *IdVal = 0;
1096 // first operand is the offset
1097 S = Parser.getTok().getLoc();
1099 if (parseMemOffset(IdVal))
1100 return MatchOperand_ParseFail;
1102 const AsmToken &Tok = Parser.getTok(); // get next token
1103 if (Tok.isNot(AsmToken::LParen)) {
1104 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1105 if (Mnemonic->getToken() == "la") {
1106 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1);
1107 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1108 return MatchOperand_Success;
1110 Error(Parser.getTok().getLoc(), "'(' expected");
1111 return MatchOperand_ParseFail;
1114 Parser.Lex(); // Eat '(' token.
1116 const AsmToken &Tok1 = Parser.getTok(); // get next token
1117 if (Tok1.is(AsmToken::Dollar)) {
1118 Parser.Lex(); // Eat '$' token.
1119 if (tryParseRegisterOperand(Operands, isMips64())) {
1120 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1121 return MatchOperand_ParseFail;
1125 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1126 return MatchOperand_ParseFail;
1129 const AsmToken &Tok2 = Parser.getTok(); // get next token
1130 if (Tok2.isNot(AsmToken::RParen)) {
1131 Error(Parser.getTok().getLoc(), "')' expected");
1132 return MatchOperand_ParseFail;
1135 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1137 Parser.Lex(); // Eat ')' token.
1140 IdVal = MCConstantExpr::Create(0, getContext());
1142 // now replace register operand with the mem operand
1143 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1144 int RegNo = op->getReg();
1145 // remove register from operands
1146 Operands.pop_back();
1147 // and add memory operand
1148 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1150 return MatchOperand_Success;
1153 MipsAsmParser::OperandMatchResultTy
1154 MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1157 return MatchOperand_NoMatch;
1158 if (getLexer().getKind() == AsmToken::Identifier) {
1159 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs))
1160 return MatchOperand_Success;
1161 return MatchOperand_NoMatch;
1163 // if the first token is not '$' we have an error
1164 if (Parser.getTok().isNot(AsmToken::Dollar))
1165 return MatchOperand_NoMatch;
1167 Parser.Lex(); // Eat $
1168 if(!tryParseRegisterOperand(Operands, true)) {
1169 // set the proper register kind
1170 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1171 op->setRegKind(MipsOperand::Kind_CPU64Regs);
1172 return MatchOperand_Success;
1174 return MatchOperand_NoMatch;
1177 bool MipsAsmParser::
1178 searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1179 unsigned RegisterKind) {
1181 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1183 SMLoc S = Parser.getTok().getLoc();
1185 if (Sym->isVariable())
1186 Expr = Sym->getVariableValue();
1189 if (Expr->getKind() == MCExpr::SymbolRef) {
1190 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1191 const StringRef DefSymbol = Ref->getSymbol().getName();
1192 if (DefSymbol.startswith("$")) {
1193 // Lookup for the register with corresponding name
1194 int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64());
1197 MipsOperand *op = MipsOperand::CreateReg(RegNum,S,
1198 Parser.getTok().getLoc());
1199 op->setRegKind((MipsOperand::RegisterKind)RegisterKind);
1200 Operands.push_back(op);
1204 } else if (Expr->getKind() == MCExpr::Constant) {
1206 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1207 MipsOperand *op = MipsOperand::CreateImm(Const,S,
1208 Parser.getTok().getLoc());
1209 Operands.push_back(op);
1215 MipsAsmParser::OperandMatchResultTy
1216 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1218 if (getLexer().getKind() == AsmToken::Identifier) {
1219 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs))
1220 return MatchOperand_Success;
1221 return MatchOperand_NoMatch;
1223 // if the first token is not '$' we have an error
1224 if (Parser.getTok().isNot(AsmToken::Dollar))
1225 return MatchOperand_NoMatch;
1227 Parser.Lex(); // Eat $
1228 if(!tryParseRegisterOperand(Operands, false)) {
1229 // set the propper register kind
1230 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1231 op->setRegKind(MipsOperand::Kind_CPURegs);
1232 return MatchOperand_Success;
1234 return MatchOperand_NoMatch;
1237 MipsAsmParser::OperandMatchResultTy
1238 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1241 return MatchOperand_NoMatch;
1243 // if the first token is not '$' we have error
1244 if (Parser.getTok().isNot(AsmToken::Dollar))
1245 return MatchOperand_NoMatch;
1246 SMLoc S = Parser.getTok().getLoc();
1247 Parser.Lex(); // Eat $
1249 const AsmToken &Tok = Parser.getTok(); // get next token
1250 if (Tok.isNot(AsmToken::Integer))
1251 return MatchOperand_NoMatch;
1253 unsigned RegNum = Tok.getIntVal();
1254 // at the moment only hwreg29 is supported
1256 return MatchOperand_ParseFail;
1258 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1259 Parser.getTok().getLoc());
1260 op->setRegKind(MipsOperand::Kind_HWRegs);
1261 Operands.push_back(op);
1263 Parser.Lex(); // Eat reg number
1264 return MatchOperand_Success;
1267 MipsAsmParser::OperandMatchResultTy
1268 MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1271 return MatchOperand_NoMatch;
1272 //if the first token is not '$' we have error
1273 if (Parser.getTok().isNot(AsmToken::Dollar))
1274 return MatchOperand_NoMatch;
1275 SMLoc S = Parser.getTok().getLoc();
1276 Parser.Lex(); // Eat $
1278 const AsmToken &Tok = Parser.getTok(); // get next token
1279 if (Tok.isNot(AsmToken::Integer))
1280 return MatchOperand_NoMatch;
1282 unsigned RegNum = Tok.getIntVal();
1283 // at the moment only hwreg29 is supported
1285 return MatchOperand_ParseFail;
1287 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1288 Parser.getTok().getLoc());
1289 op->setRegKind(MipsOperand::Kind_HW64Regs);
1290 Operands.push_back(op);
1292 Parser.Lex(); // Eat reg number
1293 return MatchOperand_Success;
1296 MipsAsmParser::OperandMatchResultTy
1297 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1299 //if the first token is not '$' we have error
1300 if (Parser.getTok().isNot(AsmToken::Dollar))
1301 return MatchOperand_NoMatch;
1302 SMLoc S = Parser.getTok().getLoc();
1303 Parser.Lex(); // Eat $
1305 const AsmToken &Tok = Parser.getTok(); // get next token
1306 if (Tok.is(AsmToken::Integer)) {
1307 RegNum = Tok.getIntVal();
1308 // at the moment only fcc0 is supported
1310 return MatchOperand_ParseFail;
1311 } else if (Tok.is(AsmToken::Identifier)) {
1312 // at the moment only fcc0 is supported
1313 if (Tok.getIdentifier() != "fcc0")
1314 return MatchOperand_ParseFail;
1316 return MatchOperand_NoMatch;
1318 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1319 Parser.getTok().getLoc());
1320 op->setRegKind(MipsOperand::Kind_CCRRegs);
1321 Operands.push_back(op);
1323 Parser.Lex(); // Eat reg number
1324 return MatchOperand_Success;
1327 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1329 MCSymbolRefExpr::VariantKind VK
1330 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1331 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1332 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1333 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1334 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1335 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1336 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1337 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1338 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1339 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1340 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1341 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1342 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1343 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1344 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1345 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1346 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1347 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1348 .Default(MCSymbolRefExpr::VK_None);
1353 static int ConvertCcString(StringRef CondString) {
1354 int CC = StringSwitch<unsigned>(CondString)
1376 bool MipsAsmParser::
1377 parseMathOperation(StringRef Name, SMLoc NameLoc,
1378 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1380 size_t Start = Name.find('.'), Next = Name.rfind('.');
1381 StringRef Format1 = Name.slice(Start, Next);
1382 // and add the first format to the operands
1383 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
1384 // now for the second format
1385 StringRef Format2 = Name.slice(Next, StringRef::npos);
1386 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1388 // set the format for the first register
1389 setFpFormat(Format1);
1391 // Read the remaining operands.
1392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1393 // Read the first operand.
1394 if (ParseOperand(Operands, Name)) {
1395 SMLoc Loc = getLexer().getLoc();
1396 Parser.eatToEndOfStatement();
1397 return Error(Loc, "unexpected token in argument list");
1400 if (getLexer().isNot(AsmToken::Comma)) {
1401 SMLoc Loc = getLexer().getLoc();
1402 Parser.eatToEndOfStatement();
1403 return Error(Loc, "unexpected token in argument list");
1406 Parser.Lex(); // Eat the comma.
1408 //set the format for the first register
1409 setFpFormat(Format2);
1411 // Parse and remember the operand.
1412 if (ParseOperand(Operands, Name)) {
1413 SMLoc Loc = getLexer().getLoc();
1414 Parser.eatToEndOfStatement();
1415 return Error(Loc, "unexpected token in argument list");
1419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1420 SMLoc Loc = getLexer().getLoc();
1421 Parser.eatToEndOfStatement();
1422 return Error(Loc, "unexpected token in argument list");
1425 Parser.Lex(); // Consume the EndOfStatement
1429 bool MipsAsmParser::
1430 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1431 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1433 // floating point instructions: should register be treated as double?
1434 if (requestsDoubleOperand(Name)) {
1435 setFpFormat(FP_FORMAT_D);
1436 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1440 setDefaultFpFormat();
1441 // Create the leading tokens for the mnemonic, split by '.' characters.
1442 size_t Start = 0, Next = Name.find('.');
1443 Mnemonic = Name.slice(Start, Next);
1445 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1447 if (Next != StringRef::npos) {
1448 // there is a format token in mnemonic
1449 // StringRef Rest = Name.slice(Next, StringRef::npos);
1450 size_t Dot = Name.find('.', Next+1);
1451 StringRef Format = Name.slice(Next, Dot);
1452 if (Dot == StringRef::npos) //only one '.' in a string, it's a format
1453 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1455 if (Name.startswith("c.")){
1456 // floating point compare, add '.' and immediate represent for cc
1457 Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1458 int Cc = ConvertCcString(Format);
1460 return Error(NameLoc, "Invalid conditional code");
1462 SMLoc E = SMLoc::getFromPointer(
1463 Parser.getTok().getLoc().getPointer() -1 );
1464 Operands.push_back(MipsOperand::CreateImm(
1465 MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
1467 // trunc, ceil, floor ...
1468 return parseMathOperation(Name, NameLoc, Operands);
1471 // the rest is a format
1472 Format = Name.slice(Dot, StringRef::npos);
1473 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1476 setFpFormat(Format);
1480 // Read the remaining operands.
1481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1482 // Read the first operand.
1483 if (ParseOperand(Operands, Mnemonic)) {
1484 SMLoc Loc = getLexer().getLoc();
1485 Parser.eatToEndOfStatement();
1486 return Error(Loc, "unexpected token in argument list");
1489 while (getLexer().is(AsmToken::Comma) ) {
1490 Parser.Lex(); // Eat the comma.
1492 // Parse and remember the operand.
1493 if (ParseOperand(Operands, Name)) {
1494 SMLoc Loc = getLexer().getLoc();
1495 Parser.eatToEndOfStatement();
1496 return Error(Loc, "unexpected token in argument list");
1501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1502 SMLoc Loc = getLexer().getLoc();
1503 Parser.eatToEndOfStatement();
1504 return Error(Loc, "unexpected token in argument list");
1507 Parser.Lex(); // Consume the EndOfStatement
1511 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1512 SMLoc Loc = getLexer().getLoc();
1513 Parser.eatToEndOfStatement();
1514 return Error(Loc, ErrorMsg);
1517 bool MipsAsmParser::parseSetNoAtDirective() {
1518 // Line should look like:
1521 Options.setATReg(0);
1524 // If this is not the end of the statement, report error
1525 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1526 reportParseError("unexpected token in statement");
1529 Parser.Lex(); // Consume the EndOfStatement
1532 bool MipsAsmParser::parseSetAtDirective() {
1534 // .set at - defaults to $1
1538 if (getLexer().is(AsmToken::EndOfStatement)) {
1539 Options.setATReg(1);
1540 Parser.Lex(); // Consume the EndOfStatement
1542 } else if (getLexer().is(AsmToken::Equal)) {
1543 getParser().Lex(); // eat '='
1544 if (getLexer().isNot(AsmToken::Dollar)) {
1545 reportParseError("unexpected token in statement");
1548 Parser.Lex(); // Eat '$'
1549 const AsmToken &Reg = Parser.getTok();
1550 if (Reg.is(AsmToken::Identifier)) {
1551 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1552 } else if (Reg.is(AsmToken::Integer)) {
1553 AtRegNo = Reg.getIntVal();
1555 reportParseError("unexpected token in statement");
1559 if ( AtRegNo < 1 || AtRegNo > 31) {
1560 reportParseError("unexpected token in statement");
1564 if (!Options.setATReg(AtRegNo)) {
1565 reportParseError("unexpected token in statement");
1568 getParser().Lex(); // Eat reg
1570 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1571 reportParseError("unexpected token in statement");
1574 Parser.Lex(); // Consume the EndOfStatement
1577 reportParseError("unexpected token in statement");
1582 bool MipsAsmParser::parseSetReorderDirective() {
1584 // If this is not the end of the statement, report error
1585 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1586 reportParseError("unexpected token in statement");
1589 Options.setReorder();
1590 Parser.Lex(); // Consume the EndOfStatement
1594 bool MipsAsmParser::parseSetNoReorderDirective() {
1596 // if this is not the end of the statement, report error
1597 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1598 reportParseError("unexpected token in statement");
1601 Options.setNoreorder();
1602 Parser.Lex(); // Consume the EndOfStatement
1606 bool MipsAsmParser::parseSetMacroDirective() {
1608 // if this is not the end of the statement, report error
1609 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1610 reportParseError("unexpected token in statement");
1614 Parser.Lex(); // Consume the EndOfStatement
1618 bool MipsAsmParser::parseSetNoMacroDirective() {
1620 // if this is not the end of the statement, report error
1621 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1622 reportParseError("`noreorder' must be set before `nomacro'");
1625 if (Options.isReorder()) {
1626 reportParseError("`noreorder' must be set before `nomacro'");
1629 Options.setNomacro();
1630 Parser.Lex(); // Consume the EndOfStatement
1634 bool MipsAsmParser::parseSetAssignment() {
1636 const MCExpr *Value;
1638 if (Parser.parseIdentifier(Name))
1639 reportParseError("expected identifier after .set");
1641 if (getLexer().isNot(AsmToken::Comma))
1642 return reportParseError("unexpected token in .set directive");
1645 if (Parser.parseExpression(Value))
1646 reportParseError("expected valid expression after comma");
1648 // check if the Name already exists as a symbol
1649 MCSymbol *Sym = getContext().LookupSymbol(Name);
1651 return reportParseError("symbol already defined");
1653 Sym = getContext().GetOrCreateSymbol(Name);
1654 Sym->setVariableValue(Value);
1658 bool MipsAsmParser::parseDirectiveSet() {
1661 const AsmToken &Tok = Parser.getTok();
1663 if (Tok.getString() == "noat") {
1664 return parseSetNoAtDirective();
1665 } else if (Tok.getString() == "at") {
1666 return parseSetAtDirective();
1667 } else if (Tok.getString() == "reorder") {
1668 return parseSetReorderDirective();
1669 } else if (Tok.getString() == "noreorder") {
1670 return parseSetNoReorderDirective();
1671 } else if (Tok.getString() == "macro") {
1672 return parseSetMacroDirective();
1673 } else if (Tok.getString() == "nomacro") {
1674 return parseSetNoMacroDirective();
1675 } else if (Tok.getString() == "nomips16") {
1676 // ignore this directive for now
1677 Parser.eatToEndOfStatement();
1679 } else if (Tok.getString() == "nomicromips") {
1680 // ignore this directive for now
1681 Parser.eatToEndOfStatement();
1684 // it is just an identifier, look for assignment
1685 parseSetAssignment();
1692 /// parseDirectiveWord
1693 /// ::= .word [ expression (, expression)* ]
1694 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1695 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1697 const MCExpr *Value;
1698 if (getParser().parseExpression(Value))
1701 getParser().getStreamer().EmitValue(Value, Size);
1703 if (getLexer().is(AsmToken::EndOfStatement))
1706 // FIXME: Improve diagnostic.
1707 if (getLexer().isNot(AsmToken::Comma))
1708 return Error(L, "unexpected token in directive");
1717 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1719 StringRef IDVal = DirectiveID.getString();
1721 if ( IDVal == ".ent") {
1722 // ignore this directive for now
1727 if (IDVal == ".end") {
1728 // ignore this directive for now
1733 if (IDVal == ".frame") {
1734 // ignore this directive for now
1735 Parser.eatToEndOfStatement();
1739 if (IDVal == ".set") {
1740 return parseDirectiveSet();
1743 if (IDVal == ".fmask") {
1744 // ignore this directive for now
1745 Parser.eatToEndOfStatement();
1749 if (IDVal == ".mask") {
1750 // ignore this directive for now
1751 Parser.eatToEndOfStatement();
1755 if (IDVal == ".gpword") {
1756 // ignore this directive for now
1757 Parser.eatToEndOfStatement();
1761 if (IDVal == ".word") {
1762 parseDirectiveWord(4, DirectiveID.getLoc());
1769 extern "C" void LLVMInitializeMipsAsmParser() {
1770 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1771 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1772 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1773 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1776 #define GET_REGISTER_MATCHER
1777 #define GET_MATCHER_IMPLEMENTATION
1778 #include "MipsGenAsmMatcher.inc"