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) {
782 CC = matchCPURegisterName(Name);
784 return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID:
785 Mips::CPURegsRegClassID);
787 if (Name[0] == 'f') {
788 StringRef NumString = Name.substr(1);
790 if( NumString.getAsInteger(10, IntVal))
791 return -1; // not integer
795 FpFormatTy Format = getFpFormat();
797 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
798 return getReg(Mips::FGR32RegClassID, IntVal);
799 if (Format == FP_FORMAT_D) {
801 return getReg(Mips::FGR64RegClassID, IntVal);
803 // only even numbers available as register pairs
804 if (( IntVal > 31) || (IntVal%2 != 0))
806 return getReg(Mips::AFGR64RegClassID, IntVal/2);
812 void MipsAsmParser::setDefaultFpFormat() {
814 if (isMips64() || isFP64())
815 FpFormat = FP_FORMAT_D;
817 FpFormat = FP_FORMAT_S;
820 bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
822 bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
831 void MipsAsmParser::setFpFormat(StringRef Format) {
833 FpFormat = StringSwitch<FpFormatTy>(Format.lower())
834 .Case(".s", FP_FORMAT_S)
835 .Case(".d", FP_FORMAT_D)
836 .Case(".l", FP_FORMAT_L)
837 .Case(".w", FP_FORMAT_W)
838 .Default(FP_FORMAT_NONE);
841 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
849 int MipsAsmParser::getATReg() {
850 return Options.getATRegNum();
853 unsigned MipsAsmParser::getReg(int RC,int RegNo) {
854 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
857 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
862 return getReg(RegClass, RegNum);
865 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
866 const AsmToken &Tok = Parser.getTok();
869 if (Tok.is(AsmToken::Identifier)) {
870 std::string lowerCase = Tok.getString().lower();
871 RegNum = matchRegisterName(lowerCase, is64BitReg);
872 } else if (Tok.is(AsmToken::Integer))
873 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
874 is64BitReg ? Mips::CPU64RegsRegClassID
875 : Mips::CPURegsRegClassID);
880 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
883 SMLoc S = Parser.getTok().getLoc();
886 RegNo = tryParseRegister(is64BitReg);
890 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
891 Parser.getTok().getLoc()));
892 Parser.Lex(); // Eat register token.
896 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
897 StringRef Mnemonic) {
898 // Check if the current operand has a custom associated parser, if so, try to
899 // custom parse the operand, or fallback to the general approach.
900 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
901 if (ResTy == MatchOperand_Success)
903 // If there wasn't a custom match, try the generic matcher below. Otherwise,
904 // there was a match, but an error occurred, in which case, just return that
905 // the operand parsing failed.
906 if (ResTy == MatchOperand_ParseFail)
909 switch (getLexer().getKind()) {
911 Error(Parser.getTok().getLoc(), "unexpected token in operand");
913 case AsmToken::Dollar: {
915 SMLoc S = Parser.getTok().getLoc();
916 Parser.Lex(); // Eat dollar token.
917 // parse register operand
918 if (!tryParseRegisterOperand(Operands, isMips64())) {
919 if (getLexer().is(AsmToken::LParen)) {
920 // check if it is indexed addressing operand
921 Operands.push_back(MipsOperand::CreateToken("(", S));
922 Parser.Lex(); // eat parenthesis
923 if (getLexer().isNot(AsmToken::Dollar))
926 Parser.Lex(); // eat dollar
927 if (tryParseRegisterOperand(Operands, isMips64()))
930 if (!getLexer().is(AsmToken::RParen))
933 S = Parser.getTok().getLoc();
934 Operands.push_back(MipsOperand::CreateToken(")", S));
939 // maybe it is a symbol reference
940 StringRef Identifier;
941 if (Parser.parseIdentifier(Identifier))
944 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
946 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
948 // Otherwise create a symbol ref.
949 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
952 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
955 case AsmToken::Identifier:
956 // Look for the existing symbol, we should check if
957 // we need to assigne the propper RegisterKind
958 if (searchSymbolAlias(Operands,MipsOperand::Kind_None))
960 //else drop to expression parsing
961 case AsmToken::LParen:
962 case AsmToken::Minus:
964 case AsmToken::Integer:
965 case AsmToken::String: {
966 // quoted label names
968 SMLoc S = Parser.getTok().getLoc();
969 if (getParser().parseExpression(IdVal))
971 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
972 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
975 case AsmToken::Percent: {
976 // it is a symbol reference or constant expression
978 SMLoc S = Parser.getTok().getLoc(); // start location of the operand
979 if (parseRelocOperand(IdVal))
982 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
984 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
986 } // case AsmToken::Percent
987 } // switch(getLexer().getKind())
991 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
993 Parser.Lex(); // eat % token
994 const AsmToken &Tok = Parser.getTok(); // get next token, operation
995 if (Tok.isNot(AsmToken::Identifier))
998 std::string Str = Tok.getIdentifier().str();
1000 Parser.Lex(); // eat identifier
1001 // now make expression from the rest of the operand
1002 const MCExpr *IdVal;
1005 if (getLexer().getKind() == AsmToken::LParen) {
1007 Parser.Lex(); // eat '(' token
1008 if (getLexer().getKind() == AsmToken::Percent) {
1009 Parser.Lex(); // eat % token
1010 const AsmToken &nextTok = Parser.getTok();
1011 if (nextTok.isNot(AsmToken::Identifier))
1014 Str += nextTok.getIdentifier();
1015 Parser.Lex(); // eat identifier
1016 if (getLexer().getKind() != AsmToken::LParen)
1021 if (getParser().parseParenExpression(IdVal,EndLoc))
1024 while (getLexer().getKind() == AsmToken::RParen)
1025 Parser.Lex(); // eat ')' token
1028 return true; // parenthesis must follow reloc operand
1030 // Check the type of the expression
1031 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
1032 // It's a constant, evaluate lo or hi value
1034 short Val = MCE->getValue();
1035 Res = MCConstantExpr::Create(Val, getContext());
1036 } else if (Str == "hi") {
1037 int Val = MCE->getValue();
1038 int LoSign = Val & 0x8000;
1039 Val = (Val & 0xffff0000) >> 16;
1040 // Lower part is treated as a signed int, so if it is negative
1041 // we must add 1 to the hi part to compensate
1044 Res = MCConstantExpr::Create(Val, getContext());
1049 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
1050 // It's a symbol, create symbolic expression from symbol
1051 StringRef Symbol = MSRE->getSymbol().getName();
1052 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
1053 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
1059 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1062 StartLoc = Parser.getTok().getLoc();
1063 RegNo = tryParseRegister(isMips64());
1064 EndLoc = Parser.getTok().getLoc();
1065 return (RegNo == (unsigned)-1);
1068 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
1072 switch(getLexer().getKind()) {
1075 case AsmToken::Identifier:
1076 case AsmToken::Integer:
1077 case AsmToken::Minus:
1078 case AsmToken::Plus:
1079 return (getParser().parseExpression(Res));
1080 case AsmToken::Percent:
1081 return parseRelocOperand(Res);
1082 case AsmToken::LParen:
1083 return false; // it's probably assuming 0
1088 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1089 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1091 const MCExpr *IdVal = 0;
1093 // first operand is the offset
1094 S = Parser.getTok().getLoc();
1096 if (parseMemOffset(IdVal))
1097 return MatchOperand_ParseFail;
1099 const AsmToken &Tok = Parser.getTok(); // get next token
1100 if (Tok.isNot(AsmToken::LParen)) {
1101 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1102 if (Mnemonic->getToken() == "la") {
1103 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1);
1104 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1105 return MatchOperand_Success;
1107 Error(Parser.getTok().getLoc(), "'(' expected");
1108 return MatchOperand_ParseFail;
1111 Parser.Lex(); // Eat '(' token.
1113 const AsmToken &Tok1 = Parser.getTok(); // get next token
1114 if (Tok1.is(AsmToken::Dollar)) {
1115 Parser.Lex(); // Eat '$' token.
1116 if (tryParseRegisterOperand(Operands, isMips64())) {
1117 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1118 return MatchOperand_ParseFail;
1122 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1123 return MatchOperand_ParseFail;
1126 const AsmToken &Tok2 = Parser.getTok(); // get next token
1127 if (Tok2.isNot(AsmToken::RParen)) {
1128 Error(Parser.getTok().getLoc(), "')' expected");
1129 return MatchOperand_ParseFail;
1132 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1134 Parser.Lex(); // Eat ')' token.
1137 IdVal = MCConstantExpr::Create(0, getContext());
1139 // now replace register operand with the mem operand
1140 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1141 int RegNo = op->getReg();
1142 // remove register from operands
1143 Operands.pop_back();
1144 // and add memory operand
1145 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1147 return MatchOperand_Success;
1150 MipsAsmParser::OperandMatchResultTy
1151 MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1154 return MatchOperand_NoMatch;
1155 if (getLexer().getKind() == AsmToken::Identifier) {
1156 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs))
1157 return MatchOperand_Success;
1158 return MatchOperand_NoMatch;
1160 // if the first token is not '$' we have an error
1161 if (Parser.getTok().isNot(AsmToken::Dollar))
1162 return MatchOperand_NoMatch;
1164 Parser.Lex(); // Eat $
1165 if(!tryParseRegisterOperand(Operands, true)) {
1166 // set the proper register kind
1167 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1168 op->setRegKind(MipsOperand::Kind_CPU64Regs);
1169 return MatchOperand_Success;
1171 return MatchOperand_NoMatch;
1174 bool MipsAsmParser::
1175 searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1176 unsigned RegisterKind) {
1178 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1180 SMLoc S = Parser.getTok().getLoc();
1182 if (Sym->isVariable())
1183 Expr = Sym->getVariableValue();
1186 if (Expr->getKind() == MCExpr::SymbolRef) {
1187 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1188 const StringRef DefSymbol = Ref->getSymbol().getName();
1189 if (DefSymbol.startswith("$")) {
1190 // Lookup for the register with corresponding name
1191 int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64());
1194 MipsOperand *op = MipsOperand::CreateReg(RegNum,S,
1195 Parser.getTok().getLoc());
1196 op->setRegKind((MipsOperand::RegisterKind)RegisterKind);
1197 Operands.push_back(op);
1201 } else if (Expr->getKind() == MCExpr::Constant) {
1203 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1204 MipsOperand *op = MipsOperand::CreateImm(Const,S,
1205 Parser.getTok().getLoc());
1206 Operands.push_back(op);
1212 MipsAsmParser::OperandMatchResultTy
1213 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1215 if (getLexer().getKind() == AsmToken::Identifier) {
1216 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs))
1217 return MatchOperand_Success;
1218 return MatchOperand_NoMatch;
1220 // if the first token is not '$' we have an error
1221 if (Parser.getTok().isNot(AsmToken::Dollar))
1222 return MatchOperand_NoMatch;
1224 Parser.Lex(); // Eat $
1225 if(!tryParseRegisterOperand(Operands, false)) {
1226 // set the propper register kind
1227 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1228 op->setRegKind(MipsOperand::Kind_CPURegs);
1229 return MatchOperand_Success;
1231 return MatchOperand_NoMatch;
1234 MipsAsmParser::OperandMatchResultTy
1235 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1238 return MatchOperand_NoMatch;
1240 // if the first token is not '$' we have error
1241 if (Parser.getTok().isNot(AsmToken::Dollar))
1242 return MatchOperand_NoMatch;
1243 SMLoc S = Parser.getTok().getLoc();
1244 Parser.Lex(); // Eat $
1246 const AsmToken &Tok = Parser.getTok(); // get next token
1247 if (Tok.isNot(AsmToken::Integer))
1248 return MatchOperand_NoMatch;
1250 unsigned RegNum = Tok.getIntVal();
1251 // at the moment only hwreg29 is supported
1253 return MatchOperand_ParseFail;
1255 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1256 Parser.getTok().getLoc());
1257 op->setRegKind(MipsOperand::Kind_HWRegs);
1258 Operands.push_back(op);
1260 Parser.Lex(); // Eat reg number
1261 return MatchOperand_Success;
1264 MipsAsmParser::OperandMatchResultTy
1265 MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1268 return MatchOperand_NoMatch;
1269 //if the first token is not '$' we have error
1270 if (Parser.getTok().isNot(AsmToken::Dollar))
1271 return MatchOperand_NoMatch;
1272 SMLoc S = Parser.getTok().getLoc();
1273 Parser.Lex(); // Eat $
1275 const AsmToken &Tok = Parser.getTok(); // get next token
1276 if (Tok.isNot(AsmToken::Integer))
1277 return MatchOperand_NoMatch;
1279 unsigned RegNum = Tok.getIntVal();
1280 // at the moment only hwreg29 is supported
1282 return MatchOperand_ParseFail;
1284 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1285 Parser.getTok().getLoc());
1286 op->setRegKind(MipsOperand::Kind_HW64Regs);
1287 Operands.push_back(op);
1289 Parser.Lex(); // Eat reg number
1290 return MatchOperand_Success;
1293 MipsAsmParser::OperandMatchResultTy
1294 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1296 //if the first token is not '$' we have error
1297 if (Parser.getTok().isNot(AsmToken::Dollar))
1298 return MatchOperand_NoMatch;
1299 SMLoc S = Parser.getTok().getLoc();
1300 Parser.Lex(); // Eat $
1302 const AsmToken &Tok = Parser.getTok(); // get next token
1303 if (Tok.is(AsmToken::Integer)) {
1304 RegNum = Tok.getIntVal();
1305 // at the moment only fcc0 is supported
1307 return MatchOperand_ParseFail;
1308 } else if (Tok.is(AsmToken::Identifier)) {
1309 // at the moment only fcc0 is supported
1310 if (Tok.getIdentifier() != "fcc0")
1311 return MatchOperand_ParseFail;
1313 return MatchOperand_NoMatch;
1315 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1316 Parser.getTok().getLoc());
1317 op->setRegKind(MipsOperand::Kind_CCRRegs);
1318 Operands.push_back(op);
1320 Parser.Lex(); // Eat reg number
1321 return MatchOperand_Success;
1324 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1326 MCSymbolRefExpr::VariantKind VK
1327 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1328 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1329 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1330 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1331 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1332 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1333 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1334 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1335 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1336 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1337 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1338 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1339 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1340 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1341 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1342 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1343 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1344 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1345 .Default(MCSymbolRefExpr::VK_None);
1350 static int ConvertCcString(StringRef CondString) {
1351 int CC = StringSwitch<unsigned>(CondString)
1373 bool MipsAsmParser::
1374 parseMathOperation(StringRef Name, SMLoc NameLoc,
1375 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1377 size_t Start = Name.find('.'), Next = Name.rfind('.');
1378 StringRef Format1 = Name.slice(Start, Next);
1379 // and add the first format to the operands
1380 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
1381 // now for the second format
1382 StringRef Format2 = Name.slice(Next, StringRef::npos);
1383 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1385 // set the format for the first register
1386 setFpFormat(Format1);
1388 // Read the remaining operands.
1389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1390 // Read the first operand.
1391 if (ParseOperand(Operands, Name)) {
1392 SMLoc Loc = getLexer().getLoc();
1393 Parser.eatToEndOfStatement();
1394 return Error(Loc, "unexpected token in argument list");
1397 if (getLexer().isNot(AsmToken::Comma)) {
1398 SMLoc Loc = getLexer().getLoc();
1399 Parser.eatToEndOfStatement();
1400 return Error(Loc, "unexpected token in argument list");
1403 Parser.Lex(); // Eat the comma.
1405 //set the format for the first register
1406 setFpFormat(Format2);
1408 // Parse and remember the operand.
1409 if (ParseOperand(Operands, Name)) {
1410 SMLoc Loc = getLexer().getLoc();
1411 Parser.eatToEndOfStatement();
1412 return Error(Loc, "unexpected token in argument list");
1416 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1417 SMLoc Loc = getLexer().getLoc();
1418 Parser.eatToEndOfStatement();
1419 return Error(Loc, "unexpected token in argument list");
1422 Parser.Lex(); // Consume the EndOfStatement
1426 bool MipsAsmParser::
1427 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1428 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1430 // floating point instructions: should register be treated as double?
1431 if (requestsDoubleOperand(Name)) {
1432 setFpFormat(FP_FORMAT_D);
1433 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1437 setDefaultFpFormat();
1438 // Create the leading tokens for the mnemonic, split by '.' characters.
1439 size_t Start = 0, Next = Name.find('.');
1440 Mnemonic = Name.slice(Start, Next);
1442 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1444 if (Next != StringRef::npos) {
1445 // there is a format token in mnemonic
1446 // StringRef Rest = Name.slice(Next, StringRef::npos);
1447 size_t Dot = Name.find('.', Next+1);
1448 StringRef Format = Name.slice(Next, Dot);
1449 if (Dot == StringRef::npos) //only one '.' in a string, it's a format
1450 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1452 if (Name.startswith("c.")){
1453 // floating point compare, add '.' and immediate represent for cc
1454 Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1455 int Cc = ConvertCcString(Format);
1457 return Error(NameLoc, "Invalid conditional code");
1459 SMLoc E = SMLoc::getFromPointer(
1460 Parser.getTok().getLoc().getPointer() -1 );
1461 Operands.push_back(MipsOperand::CreateImm(
1462 MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
1464 // trunc, ceil, floor ...
1465 return parseMathOperation(Name, NameLoc, Operands);
1468 // the rest is a format
1469 Format = Name.slice(Dot, StringRef::npos);
1470 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1473 setFpFormat(Format);
1477 // Read the remaining operands.
1478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1479 // Read the first operand.
1480 if (ParseOperand(Operands, Mnemonic)) {
1481 SMLoc Loc = getLexer().getLoc();
1482 Parser.eatToEndOfStatement();
1483 return Error(Loc, "unexpected token in argument list");
1486 while (getLexer().is(AsmToken::Comma) ) {
1487 Parser.Lex(); // Eat the comma.
1489 // Parse and remember the operand.
1490 if (ParseOperand(Operands, Name)) {
1491 SMLoc Loc = getLexer().getLoc();
1492 Parser.eatToEndOfStatement();
1493 return Error(Loc, "unexpected token in argument list");
1498 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1499 SMLoc Loc = getLexer().getLoc();
1500 Parser.eatToEndOfStatement();
1501 return Error(Loc, "unexpected token in argument list");
1504 Parser.Lex(); // Consume the EndOfStatement
1508 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1509 SMLoc Loc = getLexer().getLoc();
1510 Parser.eatToEndOfStatement();
1511 return Error(Loc, ErrorMsg);
1514 bool MipsAsmParser::parseSetNoAtDirective() {
1515 // Line should look like:
1518 Options.setATReg(0);
1521 // If this is not the end of the statement, report error
1522 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1523 reportParseError("unexpected token in statement");
1526 Parser.Lex(); // Consume the EndOfStatement
1529 bool MipsAsmParser::parseSetAtDirective() {
1531 // .set at - defaults to $1
1535 if (getLexer().is(AsmToken::EndOfStatement)) {
1536 Options.setATReg(1);
1537 Parser.Lex(); // Consume the EndOfStatement
1539 } else if (getLexer().is(AsmToken::Equal)) {
1540 getParser().Lex(); // eat '='
1541 if (getLexer().isNot(AsmToken::Dollar)) {
1542 reportParseError("unexpected token in statement");
1545 Parser.Lex(); // Eat '$'
1546 const AsmToken &Reg = Parser.getTok();
1547 if (Reg.is(AsmToken::Identifier)) {
1548 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1549 } else if (Reg.is(AsmToken::Integer)) {
1550 AtRegNo = Reg.getIntVal();
1552 reportParseError("unexpected token in statement");
1556 if ( AtRegNo < 1 || AtRegNo > 31) {
1557 reportParseError("unexpected token in statement");
1561 if (!Options.setATReg(AtRegNo)) {
1562 reportParseError("unexpected token in statement");
1565 getParser().Lex(); // Eat reg
1567 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1568 reportParseError("unexpected token in statement");
1571 Parser.Lex(); // Consume the EndOfStatement
1574 reportParseError("unexpected token in statement");
1579 bool MipsAsmParser::parseSetReorderDirective() {
1581 // If this is not the end of the statement, report error
1582 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1583 reportParseError("unexpected token in statement");
1586 Options.setReorder();
1587 Parser.Lex(); // Consume the EndOfStatement
1591 bool MipsAsmParser::parseSetNoReorderDirective() {
1593 // if this is not the end of the statement, report error
1594 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1595 reportParseError("unexpected token in statement");
1598 Options.setNoreorder();
1599 Parser.Lex(); // Consume the EndOfStatement
1603 bool MipsAsmParser::parseSetMacroDirective() {
1605 // if this is not the end of the statement, report error
1606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1607 reportParseError("unexpected token in statement");
1611 Parser.Lex(); // Consume the EndOfStatement
1615 bool MipsAsmParser::parseSetNoMacroDirective() {
1617 // if this is not the end of the statement, report error
1618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1619 reportParseError("`noreorder' must be set before `nomacro'");
1622 if (Options.isReorder()) {
1623 reportParseError("`noreorder' must be set before `nomacro'");
1626 Options.setNomacro();
1627 Parser.Lex(); // Consume the EndOfStatement
1631 bool MipsAsmParser::parseSetAssignment() {
1633 const MCExpr *Value;
1635 if (Parser.parseIdentifier(Name))
1636 reportParseError("expected identifier after .set");
1638 if (getLexer().isNot(AsmToken::Comma))
1639 return reportParseError("unexpected token in .set directive");
1642 if (Parser.parseExpression(Value))
1643 reportParseError("expected valid expression after comma");
1645 // check if the Name already exists as a symbol
1646 MCSymbol *Sym = getContext().LookupSymbol(Name);
1648 return reportParseError("symbol already defined");
1650 Sym = getContext().GetOrCreateSymbol(Name);
1651 Sym->setVariableValue(Value);
1655 bool MipsAsmParser::parseDirectiveSet() {
1658 const AsmToken &Tok = Parser.getTok();
1660 if (Tok.getString() == "noat") {
1661 return parseSetNoAtDirective();
1662 } else if (Tok.getString() == "at") {
1663 return parseSetAtDirective();
1664 } else if (Tok.getString() == "reorder") {
1665 return parseSetReorderDirective();
1666 } else if (Tok.getString() == "noreorder") {
1667 return parseSetNoReorderDirective();
1668 } else if (Tok.getString() == "macro") {
1669 return parseSetMacroDirective();
1670 } else if (Tok.getString() == "nomacro") {
1671 return parseSetNoMacroDirective();
1672 } else if (Tok.getString() == "nomips16") {
1673 // ignore this directive for now
1674 Parser.eatToEndOfStatement();
1676 } else if (Tok.getString() == "nomicromips") {
1677 // ignore this directive for now
1678 Parser.eatToEndOfStatement();
1681 // it is just an identifier, look for assignment
1682 parseSetAssignment();
1689 /// parseDirectiveWord
1690 /// ::= .word [ expression (, expression)* ]
1691 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1692 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1694 const MCExpr *Value;
1695 if (getParser().parseExpression(Value))
1698 getParser().getStreamer().EmitValue(Value, Size);
1700 if (getLexer().is(AsmToken::EndOfStatement))
1703 // FIXME: Improve diagnostic.
1704 if (getLexer().isNot(AsmToken::Comma))
1705 return Error(L, "unexpected token in directive");
1714 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1716 StringRef IDVal = DirectiveID.getString();
1718 if ( IDVal == ".ent") {
1719 // ignore this directive for now
1724 if (IDVal == ".end") {
1725 // ignore this directive for now
1730 if (IDVal == ".frame") {
1731 // ignore this directive for now
1732 Parser.eatToEndOfStatement();
1736 if (IDVal == ".set") {
1737 return parseDirectiveSet();
1740 if (IDVal == ".fmask") {
1741 // ignore this directive for now
1742 Parser.eatToEndOfStatement();
1746 if (IDVal == ".mask") {
1747 // ignore this directive for now
1748 Parser.eatToEndOfStatement();
1752 if (IDVal == ".gpword") {
1753 // ignore this directive for now
1754 Parser.eatToEndOfStatement();
1758 if (IDVal == ".word") {
1759 parseDirectiveWord(4, DirectiveID.getLoc());
1766 extern "C" void LLVMInitializeMipsAsmParser() {
1767 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1768 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1769 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1770 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1773 #define GET_REGISTER_MATCHER
1774 #define GET_MATCHER_IMPLEMENTATION
1775 #include "MipsGenAsmMatcher.inc"