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 ParseOperand(SmallVectorImpl
<MCParsedAsmOperand
*> &,
107 int tryParseRegister(bool is64BitReg
);
109 bool tryParseRegisterOperand(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
,
112 bool needsExpansion(MCInst
&Inst
);
114 void expandInstruction(MCInst
&Inst
, SMLoc IDLoc
,
115 SmallVectorImpl
<MCInst
> &Instructions
);
116 void expandLoadImm(MCInst
&Inst
, SMLoc IDLoc
,
117 SmallVectorImpl
<MCInst
> &Instructions
);
118 void expandLoadAddressImm(MCInst
&Inst
, SMLoc IDLoc
,
119 SmallVectorImpl
<MCInst
> &Instructions
);
120 void expandLoadAddressReg(MCInst
&Inst
, SMLoc IDLoc
,
121 SmallVectorImpl
<MCInst
> &Instructions
);
122 bool reportParseError(StringRef ErrorMsg
);
124 bool parseMemOffset(const MCExpr
*&Res
);
125 bool parseRelocOperand(const MCExpr
*&Res
);
127 bool parseDirectiveSet();
129 bool parseSetAtDirective();
130 bool parseSetNoAtDirective();
131 bool parseSetMacroDirective();
132 bool parseSetNoMacroDirective();
133 bool parseSetReorderDirective();
134 bool parseSetNoReorderDirective();
136 bool parseDirectiveWord(unsigned Size
, SMLoc L
);
138 MCSymbolRefExpr::VariantKind
getVariantKind(StringRef Symbol
);
140 bool isMips64() const {
141 return (STI
.getFeatureBits() & Mips::FeatureMips64
) != 0;
144 bool isFP64() const {
145 return (STI
.getFeatureBits() & Mips::FeatureFP64Bit
) != 0;
148 int matchRegisterName(StringRef Symbol
, bool is64BitReg
);
150 int matchCPURegisterName(StringRef Symbol
);
152 int matchRegisterByNumber(unsigned RegNum
, unsigned RegClass
);
154 void setFpFormat(FpFormatTy Format
) {
158 void setDefaultFpFormat();
160 void setFpFormat(StringRef Format
);
162 FpFormatTy
getFpFormat() {return FpFormat
;}
164 bool requestsDoubleOperand(StringRef Mnemonic
);
166 unsigned getReg(int RC
,int RegNo
);
170 MipsAsmParser(MCSubtargetInfo
&sti
, MCAsmParser
&parser
)
171 : MCTargetAsmParser(), STI(sti
), Parser(parser
) {
172 // Initialize the set of available features.
173 setAvailableFeatures(ComputeAvailableFeatures(STI
.getFeatureBits()));
176 MCAsmParser
&getParser() const { return Parser
; }
177 MCAsmLexer
&getLexer() const { return Parser
.getLexer(); }
184 /// MipsOperand - Instances of this class represent a parsed Mips machine
186 class MipsOperand
: public MCParsedAsmOperand
{
212 MipsOperand(KindTy K
) : MCParsedAsmOperand(), Kind(K
) {}
240 SMLoc StartLoc
, EndLoc
;
243 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
244 assert(N
== 1 && "Invalid number of operands!");
245 Inst
.addOperand(MCOperand::CreateReg(getReg()));
248 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const{
249 // Add as immediate when possible. Null MCExpr = 0.
251 Inst
.addOperand(MCOperand::CreateImm(0));
252 else if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
))
253 Inst
.addOperand(MCOperand::CreateImm(CE
->getValue()));
255 Inst
.addOperand(MCOperand::CreateExpr(Expr
));
258 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
259 assert(N
== 1 && "Invalid number of operands!");
260 const MCExpr
*Expr
= getImm();
264 void addMemOperands(MCInst
&Inst
, unsigned N
) const {
265 assert(N
== 2 && "Invalid number of operands!");
267 Inst
.addOperand(MCOperand::CreateReg(getMemBase()));
269 const MCExpr
*Expr
= getMemOff();
273 bool isReg() const { return Kind
== k_Register
; }
274 bool isImm() const { return Kind
== k_Immediate
; }
275 bool isToken() const { return Kind
== k_Token
; }
276 bool isMem() const { return Kind
== k_Memory
; }
278 StringRef
getToken() const {
279 assert(Kind
== k_Token
&& "Invalid access!");
280 return StringRef(Tok
.Data
, Tok
.Length
);
283 unsigned getReg() const {
284 assert((Kind
== k_Register
) && "Invalid access!");
288 void setRegKind(RegisterKind RegKind
) {
289 assert((Kind
== k_Register
) && "Invalid access!");
293 const MCExpr
*getImm() const {
294 assert((Kind
== k_Immediate
) && "Invalid access!");
298 unsigned getMemBase() const {
299 assert((Kind
== k_Memory
) && "Invalid access!");
303 const MCExpr
*getMemOff() const {
304 assert((Kind
== k_Memory
) && "Invalid access!");
308 static MipsOperand
*CreateToken(StringRef Str
, SMLoc S
) {
309 MipsOperand
*Op
= new MipsOperand(k_Token
);
310 Op
->Tok
.Data
= Str
.data();
311 Op
->Tok
.Length
= Str
.size();
317 static MipsOperand
*CreateReg(unsigned RegNum
, SMLoc S
, SMLoc E
) {
318 MipsOperand
*Op
= new MipsOperand(k_Register
);
319 Op
->Reg
.RegNum
= RegNum
;
325 static MipsOperand
*CreateImm(const MCExpr
*Val
, SMLoc S
, SMLoc E
) {
326 MipsOperand
*Op
= new MipsOperand(k_Immediate
);
333 static MipsOperand
*CreateMem(unsigned Base
, const MCExpr
*Off
,
335 MipsOperand
*Op
= new MipsOperand(k_Memory
);
343 bool isCPURegsAsm() const {
344 return Kind
== k_Register
&& Reg
.Kind
== Kind_CPURegs
;
346 void addCPURegsAsmOperands(MCInst
&Inst
, unsigned N
) const {
347 Inst
.addOperand(MCOperand::CreateReg(Reg
.RegNum
));
350 bool isCPU64RegsAsm() const {
351 return Kind
== k_Register
&& Reg
.Kind
== Kind_CPU64Regs
;
353 void addCPU64RegsAsmOperands(MCInst
&Inst
, unsigned N
) const {
354 Inst
.addOperand(MCOperand::CreateReg(Reg
.RegNum
));
357 bool isHWRegsAsm() const {
358 assert((Kind
== k_Register
) && "Invalid access!");
359 return Reg
.Kind
== Kind_HWRegs
;
361 void addHWRegsAsmOperands(MCInst
&Inst
, unsigned N
) const {
362 Inst
.addOperand(MCOperand::CreateReg(Reg
.RegNum
));
365 bool isHW64RegsAsm() const {
366 assert((Kind
== k_Register
) && "Invalid access!");
367 return Reg
.Kind
== Kind_HW64Regs
;
369 void addHW64RegsAsmOperands(MCInst
&Inst
, unsigned N
) const {
370 Inst
.addOperand(MCOperand::CreateReg(Reg
.RegNum
));
373 void addCCRAsmOperands(MCInst
&Inst
, unsigned N
) const {
374 Inst
.addOperand(MCOperand::CreateReg(Reg
.RegNum
));
377 bool isCCRAsm() const {
378 assert((Kind
== k_Register
) && "Invalid access!");
379 return Reg
.Kind
== Kind_CCRRegs
;
382 /// getStartLoc - Get the location of the first token of this operand.
383 SMLoc
getStartLoc() const { return StartLoc
; }
384 /// getEndLoc - Get the location of the last token of this operand.
385 SMLoc
getEndLoc() const { return EndLoc
; }
387 virtual void print(raw_ostream
&OS
) const {
388 llvm_unreachable("unimplemented!");
393 bool MipsAsmParser::needsExpansion(MCInst
&Inst
) {
395 switch(Inst
.getOpcode()) {
396 case Mips::LoadImm32Reg
:
397 case Mips::LoadAddr32Imm
:
398 case Mips::LoadAddr32Reg
:
405 void MipsAsmParser::expandInstruction(MCInst
&Inst
, SMLoc IDLoc
,
406 SmallVectorImpl
<MCInst
> &Instructions
){
407 switch(Inst
.getOpcode()) {
408 case Mips::LoadImm32Reg
:
409 return expandLoadImm(Inst
, IDLoc
, Instructions
);
410 case Mips::LoadAddr32Imm
:
411 return expandLoadAddressImm(Inst
,IDLoc
,Instructions
);
412 case Mips::LoadAddr32Reg
:
413 return expandLoadAddressReg(Inst
,IDLoc
,Instructions
);
417 void MipsAsmParser::expandLoadImm(MCInst
&Inst
, SMLoc IDLoc
,
418 SmallVectorImpl
<MCInst
> &Instructions
){
420 const MCOperand
&ImmOp
= Inst
.getOperand(1);
421 assert(ImmOp
.isImm() && "expected immediate operand kind");
422 const MCOperand
&RegOp
= Inst
.getOperand(0);
423 assert(RegOp
.isReg() && "expected register operand kind");
425 int ImmValue
= ImmOp
.getImm();
426 tmpInst
.setLoc(IDLoc
);
427 if ( 0 <= ImmValue
&& ImmValue
<= 65535) {
428 // for 0 <= j <= 65535.
429 // li d,j => ori d,$zero,j
430 tmpInst
.setOpcode(Mips::ORi
);
431 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
433 MCOperand::CreateReg(Mips::ZERO
));
434 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
));
435 Instructions
.push_back(tmpInst
);
436 } else if ( ImmValue
< 0 && ImmValue
>= -32768) {
437 // for -32768 <= j < 0.
438 // li d,j => addiu d,$zero,j
439 tmpInst
.setOpcode(Mips::ADDiu
);
440 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
442 MCOperand::CreateReg(Mips::ZERO
));
443 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
));
444 Instructions
.push_back(tmpInst
);
446 // for any other value of j that is representable as a 32-bit integer.
447 // li d,j => lui d,hi16(j)
449 tmpInst
.setOpcode(Mips::LUi
);
450 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
451 tmpInst
.addOperand(MCOperand::CreateImm((ImmValue
& 0xffff0000) >> 16));
452 Instructions
.push_back(tmpInst
);
454 tmpInst
.setOpcode(Mips::ORi
);
455 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
456 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
457 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
& 0xffff));
458 tmpInst
.setLoc(IDLoc
);
459 Instructions
.push_back(tmpInst
);
463 void MipsAsmParser::expandLoadAddressReg(MCInst
&Inst
, SMLoc IDLoc
,
464 SmallVectorImpl
<MCInst
> &Instructions
){
466 const MCOperand
&ImmOp
= Inst
.getOperand(2);
467 assert(ImmOp
.isImm() && "expected immediate operand kind");
468 const MCOperand
&SrcRegOp
= Inst
.getOperand(1);
469 assert(SrcRegOp
.isReg() && "expected register operand kind");
470 const MCOperand
&DstRegOp
= Inst
.getOperand(0);
471 assert(DstRegOp
.isReg() && "expected register operand kind");
472 int ImmValue
= ImmOp
.getImm();
473 if ( -32768 <= ImmValue
&& ImmValue
<= 65535) {
474 //for -32768 <= j <= 65535.
475 //la d,j(s) => addiu d,s,j
476 tmpInst
.setOpcode(Mips::ADDiu
);
477 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
478 tmpInst
.addOperand(MCOperand::CreateReg(SrcRegOp
.getReg()));
479 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
));
480 Instructions
.push_back(tmpInst
);
482 //for any other value of j that is representable as a 32-bit integer.
483 //la d,j(s) => lui d,hi16(j)
486 tmpInst
.setOpcode(Mips::LUi
);
487 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
488 tmpInst
.addOperand(MCOperand::CreateImm((ImmValue
& 0xffff0000) >> 16));
489 Instructions
.push_back(tmpInst
);
491 tmpInst
.setOpcode(Mips::ORi
);
492 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
493 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
494 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
& 0xffff));
495 Instructions
.push_back(tmpInst
);
497 tmpInst
.setOpcode(Mips::ADDu
);
498 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
499 tmpInst
.addOperand(MCOperand::CreateReg(DstRegOp
.getReg()));
500 tmpInst
.addOperand(MCOperand::CreateReg(SrcRegOp
.getReg()));
501 Instructions
.push_back(tmpInst
);
505 void MipsAsmParser::expandLoadAddressImm(MCInst
&Inst
, SMLoc IDLoc
,
506 SmallVectorImpl
<MCInst
> &Instructions
){
508 const MCOperand
&ImmOp
= Inst
.getOperand(1);
509 assert(ImmOp
.isImm() && "expected immediate operand kind");
510 const MCOperand
&RegOp
= Inst
.getOperand(0);
511 assert(RegOp
.isReg() && "expected register operand kind");
512 int ImmValue
= ImmOp
.getImm();
513 if ( -32768 <= ImmValue
&& ImmValue
<= 65535) {
514 //for -32768 <= j <= 65535.
515 //la d,j => addiu d,$zero,j
516 tmpInst
.setOpcode(Mips::ADDiu
);
517 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
519 MCOperand::CreateReg(Mips::ZERO
));
520 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
));
521 Instructions
.push_back(tmpInst
);
523 //for any other value of j that is representable as a 32-bit integer.
524 //la d,j => lui d,hi16(j)
526 tmpInst
.setOpcode(Mips::LUi
);
527 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
528 tmpInst
.addOperand(MCOperand::CreateImm((ImmValue
& 0xffff0000) >> 16));
529 Instructions
.push_back(tmpInst
);
531 tmpInst
.setOpcode(Mips::ORi
);
532 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
533 tmpInst
.addOperand(MCOperand::CreateReg(RegOp
.getReg()));
534 tmpInst
.addOperand(MCOperand::CreateImm(ImmValue
& 0xffff));
535 Instructions
.push_back(tmpInst
);
540 MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
541 SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
,
542 MCStreamer
&Out
, unsigned &ErrorInfo
,
543 bool MatchingInlineAsm
) {
545 unsigned MatchResult
= MatchInstructionImpl(Operands
, Inst
, ErrorInfo
,
548 switch (MatchResult
) {
550 case Match_Success
: {
551 if (needsExpansion(Inst
)) {
552 SmallVector
<MCInst
, 4> Instructions
;
553 expandInstruction(Inst
, IDLoc
, Instructions
);
554 for(unsigned i
=0; i
< Instructions
.size(); i
++){
555 Out
.EmitInstruction(Instructions
[i
]);
559 Out
.EmitInstruction(Inst
);
563 case Match_MissingFeature
:
564 Error(IDLoc
, "instruction requires a CPU feature not currently enabled");
566 case Match_InvalidOperand
: {
567 SMLoc ErrorLoc
= IDLoc
;
568 if (ErrorInfo
!= ~0U) {
569 if (ErrorInfo
>= Operands
.size())
570 return Error(IDLoc
, "too few operands for instruction");
572 ErrorLoc
= ((MipsOperand
*)Operands
[ErrorInfo
])->getStartLoc();
573 if (ErrorLoc
== SMLoc()) ErrorLoc
= IDLoc
;
576 return Error(ErrorLoc
, "invalid operand for instruction");
578 case Match_MnemonicFail
:
579 return Error(IDLoc
, "invalid instruction");
584 int MipsAsmParser::matchCPURegisterName(StringRef Name
) {
590 CC
= StringSwitch
<unsigned>(Name
)
624 // Although SGI documentation just cut out t0-t3 for n32/n64,
625 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
626 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
627 if (isMips64() && 8 <= CC
&& CC
<= 11)
630 if (CC
== -1 && isMips64())
631 CC
= StringSwitch
<unsigned>(Name
)
643 int MipsAsmParser::matchRegisterName(StringRef Name
, bool is64BitReg
) {
646 CC
= matchCPURegisterName(Name
);
648 return matchRegisterByNumber(CC
,is64BitReg
?Mips::CPU64RegsRegClassID
:
649 Mips::CPURegsRegClassID
);
651 if (Name
[0] == 'f') {
652 StringRef NumString
= Name
.substr(1);
654 if( NumString
.getAsInteger(10, IntVal
))
655 return -1; // not integer
659 FpFormatTy Format
= getFpFormat();
661 if (Format
== FP_FORMAT_S
|| Format
== FP_FORMAT_W
)
662 return getReg(Mips::FGR32RegClassID
, IntVal
);
663 if (Format
== FP_FORMAT_D
) {
665 return getReg(Mips::FGR64RegClassID
, IntVal
);
667 // only even numbers available as register pairs
668 if (( IntVal
> 31) || (IntVal
%2 != 0))
670 return getReg(Mips::AFGR64RegClassID
, IntVal
/2);
676 void MipsAsmParser::setDefaultFpFormat() {
678 if (isMips64() || isFP64())
679 FpFormat
= FP_FORMAT_D
;
681 FpFormat
= FP_FORMAT_S
;
684 bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic
){
686 bool IsDouble
= StringSwitch
<bool>(Mnemonic
.lower())
695 void MipsAsmParser::setFpFormat(StringRef Format
) {
697 FpFormat
= StringSwitch
<FpFormatTy
>(Format
.lower())
698 .Case(".s", FP_FORMAT_S
)
699 .Case(".d", FP_FORMAT_D
)
700 .Case(".l", FP_FORMAT_L
)
701 .Case(".w", FP_FORMAT_W
)
702 .Default(FP_FORMAT_NONE
);
705 bool MipsAssemblerOptions::setATReg(unsigned Reg
) {
713 int MipsAsmParser::getATReg() {
714 return Options
.getATRegNum();
717 unsigned MipsAsmParser::getReg(int RC
,int RegNo
) {
718 return *(getContext().getRegisterInfo().getRegClass(RC
).begin() + RegNo
);
721 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum
, unsigned RegClass
) {
726 return getReg(RegClass
, RegNum
);
729 int MipsAsmParser::tryParseRegister(bool is64BitReg
) {
730 const AsmToken
&Tok
= Parser
.getTok();
733 if (Tok
.is(AsmToken::Identifier
)) {
734 std::string lowerCase
= Tok
.getString().lower();
735 RegNum
= matchRegisterName(lowerCase
, is64BitReg
);
736 } else if (Tok
.is(AsmToken::Integer
))
737 RegNum
= matchRegisterByNumber(static_cast<unsigned>(Tok
.getIntVal()),
738 is64BitReg
? Mips::CPU64RegsRegClassID
739 : Mips::CPURegsRegClassID
);
744 tryParseRegisterOperand(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
,
747 SMLoc S
= Parser
.getTok().getLoc();
750 RegNo
= tryParseRegister(is64BitReg
);
754 Operands
.push_back(MipsOperand::CreateReg(RegNo
, S
,
755 Parser
.getTok().getLoc()));
756 Parser
.Lex(); // Eat register token.
760 bool MipsAsmParser::ParseOperand(SmallVectorImpl
<MCParsedAsmOperand
*>&Operands
,
761 StringRef Mnemonic
) {
762 // Check if the current operand has a custom associated parser, if so, try to
763 // custom parse the operand, or fallback to the general approach.
764 OperandMatchResultTy ResTy
= MatchOperandParserImpl(Operands
, Mnemonic
);
765 if (ResTy
== MatchOperand_Success
)
767 // If there wasn't a custom match, try the generic matcher below. Otherwise,
768 // there was a match, but an error occurred, in which case, just return that
769 // the operand parsing failed.
770 if (ResTy
== MatchOperand_ParseFail
)
773 switch (getLexer().getKind()) {
775 Error(Parser
.getTok().getLoc(), "unexpected token in operand");
777 case AsmToken::Dollar
: {
779 SMLoc S
= Parser
.getTok().getLoc();
780 Parser
.Lex(); // Eat dollar token.
781 // parse register operand
782 if (!tryParseRegisterOperand(Operands
, isMips64())) {
783 if (getLexer().is(AsmToken::LParen
)) {
784 // check if it is indexed addressing operand
785 Operands
.push_back(MipsOperand::CreateToken("(", S
));
786 Parser
.Lex(); // eat parenthesis
787 if (getLexer().isNot(AsmToken::Dollar
))
790 Parser
.Lex(); // eat dollar
791 if (tryParseRegisterOperand(Operands
, isMips64()))
794 if (!getLexer().is(AsmToken::RParen
))
797 S
= Parser
.getTok().getLoc();
798 Operands
.push_back(MipsOperand::CreateToken(")", S
));
803 // maybe it is a symbol reference
804 StringRef Identifier
;
805 if (Parser
.parseIdentifier(Identifier
))
808 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
810 MCSymbol
*Sym
= getContext().GetOrCreateSymbol("$" + Identifier
);
812 // Otherwise create a symbol ref.
813 const MCExpr
*Res
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_None
,
816 Operands
.push_back(MipsOperand::CreateImm(Res
, S
, E
));
819 case AsmToken::Identifier
:
820 case AsmToken::LParen
:
821 case AsmToken::Minus
:
823 case AsmToken::Integer
:
824 case AsmToken::String
: {
825 // quoted label names
827 SMLoc S
= Parser
.getTok().getLoc();
828 if (getParser().parseExpression(IdVal
))
830 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
831 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
));
834 case AsmToken::Percent
: {
835 // it is a symbol reference or constant expression
837 SMLoc S
= Parser
.getTok().getLoc(); // start location of the operand
838 if (parseRelocOperand(IdVal
))
841 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
843 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
));
845 } // case AsmToken::Percent
846 } // switch(getLexer().getKind())
850 bool MipsAsmParser::parseRelocOperand(const MCExpr
*&Res
) {
852 Parser
.Lex(); // eat % token
853 const AsmToken
&Tok
= Parser
.getTok(); // get next token, operation
854 if (Tok
.isNot(AsmToken::Identifier
))
857 std::string Str
= Tok
.getIdentifier().str();
859 Parser
.Lex(); // eat identifier
860 // now make expression from the rest of the operand
864 if (getLexer().getKind() == AsmToken::LParen
) {
866 Parser
.Lex(); // eat '(' token
867 if (getLexer().getKind() == AsmToken::Percent
) {
868 Parser
.Lex(); // eat % token
869 const AsmToken
&nextTok
= Parser
.getTok();
870 if (nextTok
.isNot(AsmToken::Identifier
))
873 Str
+= nextTok
.getIdentifier();
874 Parser
.Lex(); // eat identifier
875 if (getLexer().getKind() != AsmToken::LParen
)
880 if (getParser().parseParenExpression(IdVal
,EndLoc
))
883 while (getLexer().getKind() == AsmToken::RParen
)
884 Parser
.Lex(); // eat ')' token
887 return true; // parenthesis must follow reloc operand
889 // Check the type of the expression
890 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(IdVal
)) {
891 // it's a constant, evaluate lo or hi value
892 int Val
= MCE
->getValue();
895 } else if (Str
== "hi") {
896 int LoSign
= Val
& 0x8000;
897 Val
= (Val
& 0xffff0000) >> 16;
898 //lower part is treated as signed int, so if it is negative
899 //we must add 1 to hi part to compensate
903 Res
= MCConstantExpr::Create(Val
, getContext());
907 if (const MCSymbolRefExpr
*MSRE
= dyn_cast
<MCSymbolRefExpr
>(IdVal
)) {
908 // it's a symbol, create symbolic expression from symbol
909 StringRef Symbol
= MSRE
->getSymbol().getName();
910 MCSymbolRefExpr::VariantKind VK
= getVariantKind(Str
);
911 Res
= MCSymbolRefExpr::Create(Symbol
,VK
,getContext());
917 bool MipsAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
920 StartLoc
= Parser
.getTok().getLoc();
921 RegNo
= tryParseRegister(isMips64());
922 EndLoc
= Parser
.getTok().getLoc();
923 return (RegNo
== (unsigned)-1);
926 bool MipsAsmParser::parseMemOffset(const MCExpr
*&Res
) {
930 switch(getLexer().getKind()) {
933 case AsmToken::Integer
:
934 case AsmToken::Minus
:
936 return (getParser().parseExpression(Res
));
937 case AsmToken::Percent
:
938 return parseRelocOperand(Res
);
939 case AsmToken::LParen
:
940 return false; // it's probably assuming 0
945 MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseMemOperand(
946 SmallVectorImpl
<MCParsedAsmOperand
*>&Operands
) {
948 const MCExpr
*IdVal
= 0;
950 // first operand is the offset
951 S
= Parser
.getTok().getLoc();
953 if (parseMemOffset(IdVal
))
954 return MatchOperand_ParseFail
;
956 const AsmToken
&Tok
= Parser
.getTok(); // get next token
957 if (Tok
.isNot(AsmToken::LParen
)) {
958 MipsOperand
*Mnemonic
= static_cast<MipsOperand
*>(Operands
[0]);
959 if (Mnemonic
->getToken() == "la") {
960 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() -1);
961 Operands
.push_back(MipsOperand::CreateImm(IdVal
, S
, E
));
962 return MatchOperand_Success
;
964 Error(Parser
.getTok().getLoc(), "'(' expected");
965 return MatchOperand_ParseFail
;
968 Parser
.Lex(); // Eat '(' token.
970 const AsmToken
&Tok1
= Parser
.getTok(); // get next token
971 if (Tok1
.is(AsmToken::Dollar
)) {
972 Parser
.Lex(); // Eat '$' token.
973 if (tryParseRegisterOperand(Operands
, isMips64())) {
974 Error(Parser
.getTok().getLoc(), "unexpected token in operand");
975 return MatchOperand_ParseFail
;
979 Error(Parser
.getTok().getLoc(), "unexpected token in operand");
980 return MatchOperand_ParseFail
;
983 const AsmToken
&Tok2
= Parser
.getTok(); // get next token
984 if (Tok2
.isNot(AsmToken::RParen
)) {
985 Error(Parser
.getTok().getLoc(), "')' expected");
986 return MatchOperand_ParseFail
;
989 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
991 Parser
.Lex(); // Eat ')' token.
994 IdVal
= MCConstantExpr::Create(0, getContext());
996 // now replace register operand with the mem operand
997 MipsOperand
* op
= static_cast<MipsOperand
*>(Operands
.back());
998 int RegNo
= op
->getReg();
999 // remove register from operands
1000 Operands
.pop_back();
1001 // and add memory operand
1002 Operands
.push_back(MipsOperand::CreateMem(RegNo
, IdVal
, S
, E
));
1004 return MatchOperand_Success
;
1007 MipsAsmParser::OperandMatchResultTy
1008 MipsAsmParser::parseCPU64Regs(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1011 return MatchOperand_NoMatch
;
1012 // if the first token is not '$' we have an error
1013 if (Parser
.getTok().isNot(AsmToken::Dollar
))
1014 return MatchOperand_NoMatch
;
1016 Parser
.Lex(); // Eat $
1017 if(!tryParseRegisterOperand(Operands
, true)) {
1018 // set the proper register kind
1019 MipsOperand
* op
= static_cast<MipsOperand
*>(Operands
.back());
1020 op
->setRegKind(MipsOperand::Kind_CPU64Regs
);
1021 return MatchOperand_Success
;
1023 return MatchOperand_NoMatch
;
1026 MipsAsmParser::OperandMatchResultTy
1027 MipsAsmParser::parseCPURegs(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1029 // if the first token is not '$' we have an error
1030 if (Parser
.getTok().isNot(AsmToken::Dollar
))
1031 return MatchOperand_NoMatch
;
1033 Parser
.Lex(); // Eat $
1034 if(!tryParseRegisterOperand(Operands
, false)) {
1035 // set the propper register kind
1036 MipsOperand
* op
= static_cast<MipsOperand
*>(Operands
.back());
1037 op
->setRegKind(MipsOperand::Kind_CPURegs
);
1038 return MatchOperand_Success
;
1040 return MatchOperand_NoMatch
;
1043 MipsAsmParser::OperandMatchResultTy
1044 MipsAsmParser::parseHWRegs(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1047 return MatchOperand_NoMatch
;
1049 // if the first token is not '$' we have error
1050 if (Parser
.getTok().isNot(AsmToken::Dollar
))
1051 return MatchOperand_NoMatch
;
1052 SMLoc S
= Parser
.getTok().getLoc();
1053 Parser
.Lex(); // Eat $
1055 const AsmToken
&Tok
= Parser
.getTok(); // get next token
1056 if (Tok
.isNot(AsmToken::Integer
))
1057 return MatchOperand_NoMatch
;
1059 unsigned RegNum
= Tok
.getIntVal();
1060 // at the moment only hwreg29 is supported
1062 return MatchOperand_ParseFail
;
1064 MipsOperand
*op
= MipsOperand::CreateReg(Mips::HWR29
, S
,
1065 Parser
.getTok().getLoc());
1066 op
->setRegKind(MipsOperand::Kind_HWRegs
);
1067 Operands
.push_back(op
);
1069 Parser
.Lex(); // Eat reg number
1070 return MatchOperand_Success
;
1073 MipsAsmParser::OperandMatchResultTy
1074 MipsAsmParser::parseHW64Regs(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1077 return MatchOperand_NoMatch
;
1078 //if the first token is not '$' we have error
1079 if (Parser
.getTok().isNot(AsmToken::Dollar
))
1080 return MatchOperand_NoMatch
;
1081 SMLoc S
= Parser
.getTok().getLoc();
1082 Parser
.Lex(); // Eat $
1084 const AsmToken
&Tok
= Parser
.getTok(); // get next token
1085 if (Tok
.isNot(AsmToken::Integer
))
1086 return MatchOperand_NoMatch
;
1088 unsigned RegNum
= Tok
.getIntVal();
1089 // at the moment only hwreg29 is supported
1091 return MatchOperand_ParseFail
;
1093 MipsOperand
*op
= MipsOperand::CreateReg(Mips::HWR29_64
, S
,
1094 Parser
.getTok().getLoc());
1095 op
->setRegKind(MipsOperand::Kind_HW64Regs
);
1096 Operands
.push_back(op
);
1098 Parser
.Lex(); // Eat reg number
1099 return MatchOperand_Success
;
1102 MipsAsmParser::OperandMatchResultTy
1103 MipsAsmParser::parseCCRRegs(SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1105 //if the first token is not '$' we have error
1106 if (Parser
.getTok().isNot(AsmToken::Dollar
))
1107 return MatchOperand_NoMatch
;
1108 SMLoc S
= Parser
.getTok().getLoc();
1109 Parser
.Lex(); // Eat $
1111 const AsmToken
&Tok
= Parser
.getTok(); // get next token
1112 if (Tok
.is(AsmToken::Integer
)) {
1113 RegNum
= Tok
.getIntVal();
1114 // at the moment only fcc0 is supported
1116 return MatchOperand_ParseFail
;
1117 } else if (Tok
.is(AsmToken::Identifier
)) {
1118 // at the moment only fcc0 is supported
1119 if (Tok
.getIdentifier() != "fcc0")
1120 return MatchOperand_ParseFail
;
1122 return MatchOperand_NoMatch
;
1124 MipsOperand
*op
= MipsOperand::CreateReg(Mips::FCC0
, S
,
1125 Parser
.getTok().getLoc());
1126 op
->setRegKind(MipsOperand::Kind_CCRRegs
);
1127 Operands
.push_back(op
);
1129 Parser
.Lex(); // Eat reg number
1130 return MatchOperand_Success
;
1133 MCSymbolRefExpr::VariantKind
MipsAsmParser::getVariantKind(StringRef Symbol
) {
1135 MCSymbolRefExpr::VariantKind VK
1136 = StringSwitch
<MCSymbolRefExpr::VariantKind
>(Symbol
)
1137 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI
)
1138 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO
)
1139 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL
)
1140 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL
)
1141 .Case("got", MCSymbolRefExpr::VK_Mips_GOT
)
1142 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD
)
1143 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM
)
1144 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI
)
1145 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO
)
1146 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL
)
1147 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI
)
1148 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO
)
1149 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP
)
1150 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE
)
1151 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST
)
1152 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI
)
1153 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO
)
1154 .Default(MCSymbolRefExpr::VK_None
);
1159 static int ConvertCcString(StringRef CondString
) {
1160 int CC
= StringSwitch
<unsigned>(CondString
)
1182 bool MipsAsmParser::
1183 parseMathOperation(StringRef Name
, SMLoc NameLoc
,
1184 SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1186 size_t Start
= Name
.find('.'), Next
= Name
.rfind('.');
1187 StringRef Format1
= Name
.slice(Start
, Next
);
1188 // and add the first format to the operands
1189 Operands
.push_back(MipsOperand::CreateToken(Format1
, NameLoc
));
1190 // now for the second format
1191 StringRef Format2
= Name
.slice(Next
, StringRef::npos
);
1192 Operands
.push_back(MipsOperand::CreateToken(Format2
, NameLoc
));
1194 // set the format for the first register
1195 setFpFormat(Format1
);
1197 // Read the remaining operands.
1198 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1199 // Read the first operand.
1200 if (ParseOperand(Operands
, Name
)) {
1201 SMLoc Loc
= getLexer().getLoc();
1202 Parser
.eatToEndOfStatement();
1203 return Error(Loc
, "unexpected token in argument list");
1206 if (getLexer().isNot(AsmToken::Comma
)) {
1207 SMLoc Loc
= getLexer().getLoc();
1208 Parser
.eatToEndOfStatement();
1209 return Error(Loc
, "unexpected token in argument list");
1212 Parser
.Lex(); // Eat the comma.
1214 //set the format for the first register
1215 setFpFormat(Format2
);
1217 // Parse and remember the operand.
1218 if (ParseOperand(Operands
, Name
)) {
1219 SMLoc Loc
= getLexer().getLoc();
1220 Parser
.eatToEndOfStatement();
1221 return Error(Loc
, "unexpected token in argument list");
1225 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1226 SMLoc Loc
= getLexer().getLoc();
1227 Parser
.eatToEndOfStatement();
1228 return Error(Loc
, "unexpected token in argument list");
1231 Parser
.Lex(); // Consume the EndOfStatement
1235 bool MipsAsmParser::
1236 ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
, SMLoc NameLoc
,
1237 SmallVectorImpl
<MCParsedAsmOperand
*> &Operands
) {
1239 // floating point instructions: should register be treated as double?
1240 if (requestsDoubleOperand(Name
)) {
1241 setFpFormat(FP_FORMAT_D
);
1242 Operands
.push_back(MipsOperand::CreateToken(Name
, NameLoc
));
1246 setDefaultFpFormat();
1247 // Create the leading tokens for the mnemonic, split by '.' characters.
1248 size_t Start
= 0, Next
= Name
.find('.');
1249 Mnemonic
= Name
.slice(Start
, Next
);
1251 Operands
.push_back(MipsOperand::CreateToken(Mnemonic
, NameLoc
));
1253 if (Next
!= StringRef::npos
) {
1254 // there is a format token in mnemonic
1255 // StringRef Rest = Name.slice(Next, StringRef::npos);
1256 size_t Dot
= Name
.find('.', Next
+1);
1257 StringRef Format
= Name
.slice(Next
, Dot
);
1258 if (Dot
== StringRef::npos
) //only one '.' in a string, it's a format
1259 Operands
.push_back(MipsOperand::CreateToken(Format
, NameLoc
));
1261 if (Name
.startswith("c.")){
1262 // floating point compare, add '.' and immediate represent for cc
1263 Operands
.push_back(MipsOperand::CreateToken(".", NameLoc
));
1264 int Cc
= ConvertCcString(Format
);
1266 return Error(NameLoc
, "Invalid conditional code");
1268 SMLoc E
= SMLoc::getFromPointer(
1269 Parser
.getTok().getLoc().getPointer() -1 );
1270 Operands
.push_back(MipsOperand::CreateImm(
1271 MCConstantExpr::Create(Cc
, getContext()), NameLoc
, E
));
1273 // trunc, ceil, floor ...
1274 return parseMathOperation(Name
, NameLoc
, Operands
);
1277 // the rest is a format
1278 Format
= Name
.slice(Dot
, StringRef::npos
);
1279 Operands
.push_back(MipsOperand::CreateToken(Format
, NameLoc
));
1282 setFpFormat(Format
);
1286 // Read the remaining operands.
1287 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1288 // Read the first operand.
1289 if (ParseOperand(Operands
, Mnemonic
)) {
1290 SMLoc Loc
= getLexer().getLoc();
1291 Parser
.eatToEndOfStatement();
1292 return Error(Loc
, "unexpected token in argument list");
1295 while (getLexer().is(AsmToken::Comma
) ) {
1296 Parser
.Lex(); // Eat the comma.
1298 // Parse and remember the operand.
1299 if (ParseOperand(Operands
, Name
)) {
1300 SMLoc Loc
= getLexer().getLoc();
1301 Parser
.eatToEndOfStatement();
1302 return Error(Loc
, "unexpected token in argument list");
1307 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1308 SMLoc Loc
= getLexer().getLoc();
1309 Parser
.eatToEndOfStatement();
1310 return Error(Loc
, "unexpected token in argument list");
1313 Parser
.Lex(); // Consume the EndOfStatement
1317 bool MipsAsmParser::reportParseError(StringRef ErrorMsg
) {
1318 SMLoc Loc
= getLexer().getLoc();
1319 Parser
.eatToEndOfStatement();
1320 return Error(Loc
, ErrorMsg
);
1323 bool MipsAsmParser::parseSetNoAtDirective() {
1324 // line should look like:
1327 Options
.setATReg(0);
1330 // if this is not the end of the statement, report error
1331 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1332 reportParseError("unexpected token in statement");
1335 Parser
.Lex(); // Consume the EndOfStatement
1338 bool MipsAsmParser::parseSetAtDirective() {
1340 // .set at - defaults to $1
1344 if (getLexer().is(AsmToken::EndOfStatement
)) {
1345 Options
.setATReg(1);
1346 Parser
.Lex(); // Consume the EndOfStatement
1348 } else if (getLexer().is(AsmToken::Equal
)) {
1349 getParser().Lex(); //eat '='
1350 if (getLexer().isNot(AsmToken::Dollar
)) {
1351 reportParseError("unexpected token in statement");
1354 Parser
.Lex(); // eat '$'
1355 const AsmToken
&Reg
= Parser
.getTok();
1356 if (Reg
.is(AsmToken::Identifier
)) {
1357 AtRegNo
= matchCPURegisterName(Reg
.getIdentifier());
1358 } else if (Reg
.is(AsmToken::Integer
)) {
1359 AtRegNo
= Reg
.getIntVal();
1361 reportParseError("unexpected token in statement");
1365 if ( AtRegNo
< 1 || AtRegNo
> 31) {
1366 reportParseError("unexpected token in statement");
1370 if (!Options
.setATReg(AtRegNo
)) {
1371 reportParseError("unexpected token in statement");
1374 getParser().Lex(); //eat reg
1376 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1377 reportParseError("unexpected token in statement");
1380 Parser
.Lex(); // Consume the EndOfStatement
1383 reportParseError("unexpected token in statement");
1388 bool MipsAsmParser::parseSetReorderDirective() {
1390 // if this is not the end of the statement, report error
1391 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1392 reportParseError("unexpected token in statement");
1395 Options
.setReorder();
1396 Parser
.Lex(); // Consume the EndOfStatement
1400 bool MipsAsmParser::parseSetNoReorderDirective() {
1402 // if this is not the end of the statement, report error
1403 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1404 reportParseError("unexpected token in statement");
1407 Options
.setNoreorder();
1408 Parser
.Lex(); // Consume the EndOfStatement
1412 bool MipsAsmParser::parseSetMacroDirective() {
1414 // if this is not the end of the statement, report error
1415 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1416 reportParseError("unexpected token in statement");
1420 Parser
.Lex(); // Consume the EndOfStatement
1424 bool MipsAsmParser::parseSetNoMacroDirective() {
1426 // if this is not the end of the statement, report error
1427 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1428 reportParseError("`noreorder' must be set before `nomacro'");
1431 if (Options
.isReorder()) {
1432 reportParseError("`noreorder' must be set before `nomacro'");
1435 Options
.setNomacro();
1436 Parser
.Lex(); // Consume the EndOfStatement
1439 bool MipsAsmParser::parseDirectiveSet() {
1442 const AsmToken
&Tok
= Parser
.getTok();
1444 if (Tok
.getString() == "noat") {
1445 return parseSetNoAtDirective();
1446 } else if (Tok
.getString() == "at") {
1447 return parseSetAtDirective();
1448 } else if (Tok
.getString() == "reorder") {
1449 return parseSetReorderDirective();
1450 } else if (Tok
.getString() == "noreorder") {
1451 return parseSetNoReorderDirective();
1452 } else if (Tok
.getString() == "macro") {
1453 return parseSetMacroDirective();
1454 } else if (Tok
.getString() == "nomacro") {
1455 return parseSetNoMacroDirective();
1456 } else if (Tok
.getString() == "nomips16") {
1457 // ignore this directive for now
1458 Parser
.eatToEndOfStatement();
1460 } else if (Tok
.getString() == "nomicromips") {
1461 // ignore this directive for now
1462 Parser
.eatToEndOfStatement();
1469 /// parseDirectiveWord
1470 /// ::= .word [ expression (, expression)* ]
1471 bool MipsAsmParser::parseDirectiveWord(unsigned Size
, SMLoc L
) {
1472 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1474 const MCExpr
*Value
;
1475 if (getParser().parseExpression(Value
))
1478 getParser().getStreamer().EmitValue(Value
, Size
);
1480 if (getLexer().is(AsmToken::EndOfStatement
))
1483 // FIXME: Improve diagnostic.
1484 if (getLexer().isNot(AsmToken::Comma
))
1485 return Error(L
, "unexpected token in directive");
1494 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID
) {
1496 StringRef IDVal
= DirectiveID
.getString();
1498 if ( IDVal
== ".ent") {
1499 // ignore this directive for now
1504 if (IDVal
== ".end") {
1505 // ignore this directive for now
1510 if (IDVal
== ".frame") {
1511 // ignore this directive for now
1512 Parser
.eatToEndOfStatement();
1516 if (IDVal
== ".set") {
1517 return parseDirectiveSet();
1520 if (IDVal
== ".fmask") {
1521 // ignore this directive for now
1522 Parser
.eatToEndOfStatement();
1526 if (IDVal
== ".mask") {
1527 // ignore this directive for now
1528 Parser
.eatToEndOfStatement();
1532 if (IDVal
== ".gpword") {
1533 // ignore this directive for now
1534 Parser
.eatToEndOfStatement();
1538 if (IDVal
== ".word") {
1539 parseDirectiveWord(4, DirectiveID
.getLoc());
1546 extern "C" void LLVMInitializeMipsAsmParser() {
1547 RegisterMCAsmParser
<MipsAsmParser
> X(TheMipsTarget
);
1548 RegisterMCAsmParser
<MipsAsmParser
> Y(TheMipselTarget
);
1549 RegisterMCAsmParser
<MipsAsmParser
> A(TheMips64Target
);
1550 RegisterMCAsmParser
<MipsAsmParser
> B(TheMips64elTarget
);
1553 #define GET_REGISTER_MATCHER
1554 #define GET_MATCHER_IMPLEMENTATION
1555 #include "MipsGenAsmMatcher.inc"