MipsAsmParser.cpp revision 006cff8d7b60ddf632f8642f01693dace7827d8b
1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/MipsMCTargetDesc.h"
11#include "MipsRegisterInfo.h"
12#include "MipsTargetStreamer.h"
13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
19#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/MC/MCSymbol.h"
22#include "llvm/MC/MCTargetAsmParser.h"
23#include "llvm/Support/TargetRegistry.h"
24#include "llvm/ADT/APInt.h"
25
26using namespace llvm;
27
28namespace llvm {
29class MCInstrInfo;
30}
31
32namespace {
33class MipsAssemblerOptions {
34public:
35  MipsAssemblerOptions():
36    aTReg(1), reorder(true), macro(true) {
37  }
38
39  unsigned getATRegNum() {return aTReg;}
40  bool setATReg(unsigned Reg);
41
42  bool isReorder() {return reorder;}
43  void setReorder() {reorder = true;}
44  void setNoreorder() {reorder = false;}
45
46  bool isMacro() {return macro;}
47  void setMacro() {macro = true;}
48  void setNomacro() {macro = false;}
49
50private:
51  unsigned aTReg;
52  bool reorder;
53  bool macro;
54};
55}
56
57namespace {
58class MipsAsmParser : public MCTargetAsmParser {
59
60  MipsTargetStreamer &getTargetStreamer() {
61    MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
62    return static_cast<MipsTargetStreamer &>(TS);
63  }
64
65  MCSubtargetInfo &STI;
66  MCAsmParser &Parser;
67  MipsAssemblerOptions Options;
68  bool hasConsumedDollar;
69
70#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
73  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
74                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
75                               MCStreamer &Out, unsigned &ErrorInfo,
76                               bool MatchingInlineAsm);
77
78  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
79
80  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
81                        SMLoc NameLoc,
82                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
83
84  bool ParseDirective(AsmToken DirectiveID);
85
86  MipsAsmParser::OperandMatchResultTy
87  parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
88                         int RegKind);
89
90  MipsAsmParser::OperandMatchResultTy
91  parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
92               int RegKind);
93
94  MipsAsmParser::OperandMatchResultTy
95  parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
96                   int RegKind);
97
98  MipsAsmParser::OperandMatchResultTy
99  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100
101  bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
102
103  MipsAsmParser::OperandMatchResultTy
104  parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
106  MipsAsmParser::OperandMatchResultTy
107  parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108
109  MipsAsmParser::OperandMatchResultTy
110  parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111
112  MipsAsmParser::OperandMatchResultTy
113  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
115  MipsAsmParser::OperandMatchResultTy
116  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117
118  MipsAsmParser::OperandMatchResultTy
119  parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120
121  MipsAsmParser::OperandMatchResultTy
122  parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123
124  MipsAsmParser::OperandMatchResultTy
125  parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
126
127  MipsAsmParser::OperandMatchResultTy
128  parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
129
130  MipsAsmParser::OperandMatchResultTy
131  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
132
133  MipsAsmParser::OperandMatchResultTy
134  parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
135
136  MipsAsmParser::OperandMatchResultTy
137  parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
138
139  MipsAsmParser::OperandMatchResultTy
140  parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
141
142  MipsAsmParser::OperandMatchResultTy
143  parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144
145  MipsAsmParser::OperandMatchResultTy
146  parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
147
148  MipsAsmParser::OperandMatchResultTy
149  parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
150
151  MipsAsmParser::OperandMatchResultTy
152  parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
153
154  MipsAsmParser::OperandMatchResultTy
155  parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
156
157  MipsAsmParser::OperandMatchResultTy
158  parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
159
160  MipsAsmParser::OperandMatchResultTy
161  parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
162
163  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
164                         unsigned RegKind);
165
166  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
167                    StringRef Mnemonic);
168
169  int tryParseRegister(bool is64BitReg);
170
171  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
172                               bool is64BitReg);
173
174  bool needsExpansion(MCInst &Inst);
175
176  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
177                         SmallVectorImpl<MCInst> &Instructions);
178  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
179                     SmallVectorImpl<MCInst> &Instructions);
180  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
181                            SmallVectorImpl<MCInst> &Instructions);
182  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
183                            SmallVectorImpl<MCInst> &Instructions);
184  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
185                     SmallVectorImpl<MCInst> &Instructions,
186                     bool isLoad,bool isImmOpnd);
187  bool reportParseError(StringRef ErrorMsg);
188
189  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
190  bool parseRelocOperand(const MCExpr *&Res);
191
192  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
193
194  bool isEvaluated(const MCExpr *Expr);
195  bool parseDirectiveSet();
196  bool parseDirectiveMipsHackStocg();
197  bool parseDirectiveMipsHackELFFlags();
198
199  bool parseSetAtDirective();
200  bool parseSetNoAtDirective();
201  bool parseSetMacroDirective();
202  bool parseSetNoMacroDirective();
203  bool parseSetReorderDirective();
204  bool parseSetNoReorderDirective();
205
206  bool parseSetAssignment();
207
208  bool parseDirectiveWord(unsigned Size, SMLoc L);
209
210  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
211
212  bool isMips64() const {
213    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
214  }
215
216  bool isFP64() const {
217    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
218  }
219
220  bool isN64() const {
221    return STI.getFeatureBits() & Mips::FeatureN64;
222  }
223
224  int matchRegisterName(StringRef Symbol, bool is64BitReg);
225
226  int matchCPURegisterName(StringRef Symbol);
227
228  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
229
230  int matchFPURegisterName(StringRef Name);
231
232  int matchFCCRegisterName(StringRef Name);
233
234  int matchACRegisterName(StringRef Name);
235
236  int matchMSA128RegisterName(StringRef Name);
237
238  int matchMSA128CtrlRegisterName(StringRef Name);
239
240  int regKindToRegClass(int RegKind);
241
242  unsigned getReg(int RC, int RegNo);
243
244  int getATReg();
245
246  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
247                        SmallVectorImpl<MCInst> &Instructions);
248
249  // Helper function that checks if the value of a vector index is within the
250  // boundaries of accepted values for each RegisterKind
251  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
252  bool validateMSAIndex(int Val, int RegKind);
253
254public:
255  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
256                const MCInstrInfo &MII)
257      : MCTargetAsmParser(), STI(sti), Parser(parser),
258        hasConsumedDollar(false) {
259    // Initialize the set of available features.
260    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
261  }
262
263  MCAsmParser &getParser() const { return Parser; }
264  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
265
266};
267}
268
269namespace {
270
271/// MipsOperand - Instances of this class represent a parsed Mips machine
272/// instruction.
273class MipsOperand : public MCParsedAsmOperand {
274
275public:
276  enum RegisterKind {
277    Kind_None,
278    Kind_GPR32,
279    Kind_GPR64,
280    Kind_HWRegs,
281    Kind_FGR32Regs,
282    Kind_FGRH32Regs,
283    Kind_FGR64Regs,
284    Kind_AFGR64Regs,
285    Kind_CCRRegs,
286    Kind_FCCRegs,
287    Kind_ACC64DSP,
288    Kind_LO32DSP,
289    Kind_HI32DSP,
290    Kind_COP2,
291    Kind_MSA128BRegs,
292    Kind_MSA128HRegs,
293    Kind_MSA128WRegs,
294    Kind_MSA128DRegs,
295    Kind_MSA128CtrlRegs
296  };
297
298private:
299  enum KindTy {
300    k_CondCode,
301    k_CoprocNum,
302    k_Immediate,
303    k_Memory,
304    k_PostIndexRegister,
305    k_Register,
306    k_PtrReg,
307    k_Token
308  } Kind;
309
310  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
311
312  struct Token {
313    const char *Data;
314    unsigned Length;
315  };
316
317  struct RegOp {
318    unsigned RegNum;
319    RegisterKind Kind;
320  };
321
322  struct ImmOp {
323    const MCExpr *Val;
324  };
325
326  struct MemOp {
327    unsigned Base;
328    const MCExpr *Off;
329  };
330
331  union {
332    struct Token Tok;
333    struct RegOp Reg;
334    struct ImmOp Imm;
335    struct MemOp Mem;
336  };
337
338  SMLoc StartLoc, EndLoc;
339
340public:
341  void addRegOperands(MCInst &Inst, unsigned N) const {
342    assert(N == 1 && "Invalid number of operands!");
343    Inst.addOperand(MCOperand::CreateReg(getReg()));
344  }
345
346  void addPtrRegOperands(MCInst &Inst, unsigned N) const {
347    assert(N == 1 && "Invalid number of operands!");
348    Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
349  }
350
351  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
352    // Add as immediate when possible.  Null MCExpr = 0.
353    if (Expr == 0)
354      Inst.addOperand(MCOperand::CreateImm(0));
355    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
356      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
357    else
358      Inst.addOperand(MCOperand::CreateExpr(Expr));
359  }
360
361  void addImmOperands(MCInst &Inst, unsigned N) const {
362    assert(N == 1 && "Invalid number of operands!");
363    const MCExpr *Expr = getImm();
364    addExpr(Inst, Expr);
365  }
366
367  void addMemOperands(MCInst &Inst, unsigned N) const {
368    assert(N == 2 && "Invalid number of operands!");
369
370    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
371
372    const MCExpr *Expr = getMemOff();
373    addExpr(Inst, Expr);
374  }
375
376  bool isReg() const { return Kind == k_Register; }
377  bool isImm() const { return Kind == k_Immediate; }
378  bool isToken() const { return Kind == k_Token; }
379  bool isMem() const { return Kind == k_Memory; }
380  bool isPtrReg() const { return Kind == k_PtrReg; }
381  bool isInvNum() const { return Kind == k_Immediate; }
382
383  StringRef getToken() const {
384    assert(Kind == k_Token && "Invalid access!");
385    return StringRef(Tok.Data, Tok.Length);
386  }
387
388  unsigned getReg() const {
389    assert((Kind == k_Register) && "Invalid access!");
390    return Reg.RegNum;
391  }
392
393  unsigned getPtrReg() const {
394    assert((Kind == k_PtrReg) && "Invalid access!");
395    return Reg.RegNum;
396  }
397
398  void setRegKind(RegisterKind RegKind) {
399    assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
400    Reg.Kind = RegKind;
401  }
402
403  const MCExpr *getImm() const {
404    assert((Kind == k_Immediate) && "Invalid access!");
405    return Imm.Val;
406  }
407
408  unsigned getMemBase() const {
409    assert((Kind == k_Memory) && "Invalid access!");
410    return Mem.Base;
411  }
412
413  const MCExpr *getMemOff() const {
414    assert((Kind == k_Memory) && "Invalid access!");
415    return Mem.Off;
416  }
417
418  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
419    MipsOperand *Op = new MipsOperand(k_Token);
420    Op->Tok.Data = Str.data();
421    Op->Tok.Length = Str.size();
422    Op->StartLoc = S;
423    Op->EndLoc = S;
424    return Op;
425  }
426
427  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
428    MipsOperand *Op = new MipsOperand(k_Register);
429    Op->Reg.RegNum = RegNum;
430    Op->StartLoc = S;
431    Op->EndLoc = E;
432    return Op;
433  }
434
435  static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
436    MipsOperand *Op = new MipsOperand(k_PtrReg);
437    Op->Reg.RegNum = RegNum;
438    Op->StartLoc = S;
439    Op->EndLoc = E;
440    return Op;
441  }
442
443  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
444    MipsOperand *Op = new MipsOperand(k_Immediate);
445    Op->Imm.Val = Val;
446    Op->StartLoc = S;
447    Op->EndLoc = E;
448    return Op;
449  }
450
451  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
452                                 SMLoc S, SMLoc E) {
453    MipsOperand *Op = new MipsOperand(k_Memory);
454    Op->Mem.Base = Base;
455    Op->Mem.Off = Off;
456    Op->StartLoc = S;
457    Op->EndLoc = E;
458    return Op;
459  }
460
461  bool isGPR32Asm() const {
462    return Kind == k_Register && Reg.Kind == Kind_GPR32;
463  }
464  void addRegAsmOperands(MCInst &Inst, unsigned N) const {
465    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
466  }
467
468  bool isGPR64Asm() const {
469    return Kind == k_Register && Reg.Kind == Kind_GPR64;
470  }
471
472  bool isHWRegsAsm() const {
473    assert((Kind == k_Register) && "Invalid access!");
474    return Reg.Kind == Kind_HWRegs;
475  }
476
477  bool isCCRAsm() const {
478    assert((Kind == k_Register) && "Invalid access!");
479    return Reg.Kind == Kind_CCRRegs;
480  }
481
482   bool isAFGR64Asm() const {
483    return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
484  }
485
486  bool isFGR64Asm() const {
487    return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
488  }
489
490  bool isFGR32Asm() const {
491    return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
492  }
493
494  bool isFGRH32Asm() const {
495    return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
496  }
497
498  bool isFCCRegsAsm() const {
499    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
500  }
501
502  bool isACC64DSPAsm() const {
503    return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
504  }
505
506  bool isLO32DSPAsm() const {
507    return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
508  }
509
510  bool isHI32DSPAsm() const {
511    return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
512  }
513
514  bool isCOP2Asm() const {
515    return Kind == k_Register && Reg.Kind == Kind_COP2;
516  }
517
518  bool isMSA128BAsm() const {
519    return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
520  }
521
522  bool isMSA128HAsm() const {
523    return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
524  }
525
526  bool isMSA128WAsm() const {
527    return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
528  }
529
530  bool isMSA128DAsm() const {
531    return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
532  }
533
534  bool isMSA128CRAsm() const {
535    return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
536  }
537
538  /// getStartLoc - Get the location of the first token of this operand.
539  SMLoc getStartLoc() const {
540    return StartLoc;
541  }
542  /// getEndLoc - Get the location of the last token of this operand.
543  SMLoc getEndLoc() const {
544    return EndLoc;
545  }
546
547  virtual void print(raw_ostream &OS) const {
548    llvm_unreachable("unimplemented!");
549  }
550}; // class MipsOperand
551}  // namespace
552
553namespace llvm {
554extern const MCInstrDesc MipsInsts[];
555}
556static const MCInstrDesc &getInstDesc(unsigned Opcode) {
557  return MipsInsts[Opcode];
558}
559
560bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
561                                       SmallVectorImpl<MCInst> &Instructions) {
562  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
563  Inst.setLoc(IDLoc);
564  if (MCID.hasDelaySlot() && Options.isReorder()) {
565    // If this instruction has a delay slot and .set reorder is active,
566    // emit a NOP after it.
567    Instructions.push_back(Inst);
568    MCInst NopInst;
569    NopInst.setOpcode(Mips::SLL);
570    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
571    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
572    NopInst.addOperand(MCOperand::CreateImm(0));
573    Instructions.push_back(NopInst);
574    return false;
575  }
576
577  if (MCID.mayLoad() || MCID.mayStore()) {
578    // Check the offset of memory operand, if it is a symbol
579    // reference or immediate we may have to expand instructions.
580    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
581      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
582      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
583          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
584        MCOperand &Op = Inst.getOperand(i);
585        if (Op.isImm()) {
586          int MemOffset = Op.getImm();
587          if (MemOffset < -32768 || MemOffset > 32767) {
588            // Offset can't exceed 16bit value.
589            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
590            return false;
591          }
592        } else if (Op.isExpr()) {
593          const MCExpr *Expr = Op.getExpr();
594          if (Expr->getKind() == MCExpr::SymbolRef) {
595            const MCSymbolRefExpr *SR =
596                static_cast<const MCSymbolRefExpr*>(Expr);
597            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
598              // Expand symbol.
599              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
600              return false;
601            }
602          } else if (!isEvaluated(Expr)) {
603            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
604            return false;
605          }
606        }
607      }
608    } // for
609  } // if load/store
610
611  if (needsExpansion(Inst))
612    expandInstruction(Inst, IDLoc, Instructions);
613  else
614    Instructions.push_back(Inst);
615
616  return false;
617}
618
619bool MipsAsmParser::needsExpansion(MCInst &Inst) {
620
621  switch (Inst.getOpcode()) {
622  case Mips::LoadImm32Reg:
623  case Mips::LoadAddr32Imm:
624  case Mips::LoadAddr32Reg:
625    return true;
626  default:
627    return false;
628  }
629}
630
631void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
632                                       SmallVectorImpl<MCInst> &Instructions) {
633  switch (Inst.getOpcode()) {
634  case Mips::LoadImm32Reg:
635    return expandLoadImm(Inst, IDLoc, Instructions);
636  case Mips::LoadAddr32Imm:
637    return expandLoadAddressImm(Inst, IDLoc, Instructions);
638  case Mips::LoadAddr32Reg:
639    return expandLoadAddressReg(Inst, IDLoc, Instructions);
640  }
641}
642
643void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
644                                  SmallVectorImpl<MCInst> &Instructions) {
645  MCInst tmpInst;
646  const MCOperand &ImmOp = Inst.getOperand(1);
647  assert(ImmOp.isImm() && "expected immediate operand kind");
648  const MCOperand &RegOp = Inst.getOperand(0);
649  assert(RegOp.isReg() && "expected register operand kind");
650
651  int ImmValue = ImmOp.getImm();
652  tmpInst.setLoc(IDLoc);
653  if (0 <= ImmValue && ImmValue <= 65535) {
654    // For 0 <= j <= 65535.
655    // li d,j => ori d,$zero,j
656    tmpInst.setOpcode(Mips::ORi);
657    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
658    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
659    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
660    Instructions.push_back(tmpInst);
661  } else if (ImmValue < 0 && ImmValue >= -32768) {
662    // For -32768 <= j < 0.
663    // li d,j => addiu d,$zero,j
664    tmpInst.setOpcode(Mips::ADDiu);
665    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
666    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
667    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
668    Instructions.push_back(tmpInst);
669  } else {
670    // For any other value of j that is representable as a 32-bit integer.
671    // li d,j => lui d,hi16(j)
672    //           ori d,d,lo16(j)
673    tmpInst.setOpcode(Mips::LUi);
674    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
675    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
676    Instructions.push_back(tmpInst);
677    tmpInst.clear();
678    tmpInst.setOpcode(Mips::ORi);
679    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
680    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
681    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
682    tmpInst.setLoc(IDLoc);
683    Instructions.push_back(tmpInst);
684  }
685}
686
687void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
688                                       SmallVectorImpl<MCInst> &Instructions) {
689  MCInst tmpInst;
690  const MCOperand &ImmOp = Inst.getOperand(2);
691  assert(ImmOp.isImm() && "expected immediate operand kind");
692  const MCOperand &SrcRegOp = Inst.getOperand(1);
693  assert(SrcRegOp.isReg() && "expected register operand kind");
694  const MCOperand &DstRegOp = Inst.getOperand(0);
695  assert(DstRegOp.isReg() && "expected register operand kind");
696  int ImmValue = ImmOp.getImm();
697  if (-32768 <= ImmValue && ImmValue <= 65535) {
698    // For -32768 <= j <= 65535.
699    // la d,j(s) => addiu d,s,j
700    tmpInst.setOpcode(Mips::ADDiu);
701    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
702    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
703    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
704    Instructions.push_back(tmpInst);
705  } else {
706    // For any other value of j that is representable as a 32-bit integer.
707    // la d,j(s) => lui d,hi16(j)
708    //              ori d,d,lo16(j)
709    //              addu d,d,s
710    tmpInst.setOpcode(Mips::LUi);
711    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
712    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
713    Instructions.push_back(tmpInst);
714    tmpInst.clear();
715    tmpInst.setOpcode(Mips::ORi);
716    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
717    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
718    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
719    Instructions.push_back(tmpInst);
720    tmpInst.clear();
721    tmpInst.setOpcode(Mips::ADDu);
722    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
723    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
724    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
725    Instructions.push_back(tmpInst);
726  }
727}
728
729void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
730                                       SmallVectorImpl<MCInst> &Instructions) {
731  MCInst tmpInst;
732  const MCOperand &ImmOp = Inst.getOperand(1);
733  assert(ImmOp.isImm() && "expected immediate operand kind");
734  const MCOperand &RegOp = Inst.getOperand(0);
735  assert(RegOp.isReg() && "expected register operand kind");
736  int ImmValue = ImmOp.getImm();
737  if (-32768 <= ImmValue && ImmValue <= 65535) {
738    // For -32768 <= j <= 65535.
739    // la d,j => addiu d,$zero,j
740    tmpInst.setOpcode(Mips::ADDiu);
741    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
742    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
743    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
744    Instructions.push_back(tmpInst);
745  } else {
746    // For any other value of j that is representable as a 32-bit integer.
747    // la d,j => lui d,hi16(j)
748    //           ori d,d,lo16(j)
749    tmpInst.setOpcode(Mips::LUi);
750    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
751    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
752    Instructions.push_back(tmpInst);
753    tmpInst.clear();
754    tmpInst.setOpcode(Mips::ORi);
755    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
756    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
757    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
758    Instructions.push_back(tmpInst);
759  }
760}
761
762void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
763          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
764  const MCSymbolRefExpr *SR;
765  MCInst TempInst;
766  unsigned ImmOffset, HiOffset, LoOffset;
767  const MCExpr *ExprOffset;
768  unsigned TmpRegNum;
769  unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
770                             : Mips::GPR32RegClassID, getATReg());
771  // 1st operand is either the source or destination register.
772  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
773  unsigned RegOpNum = Inst.getOperand(0).getReg();
774  // 2nd operand is the base register.
775  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
776  unsigned BaseRegNum = Inst.getOperand(1).getReg();
777  // 3rd operand is either an immediate or expression.
778  if (isImmOpnd) {
779    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
780    ImmOffset = Inst.getOperand(2).getImm();
781    LoOffset = ImmOffset & 0x0000ffff;
782    HiOffset = (ImmOffset & 0xffff0000) >> 16;
783    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
784    if (LoOffset & 0x8000)
785      HiOffset++;
786  } else
787    ExprOffset = Inst.getOperand(2).getExpr();
788  // All instructions will have the same location.
789  TempInst.setLoc(IDLoc);
790  // 1st instruction in expansion is LUi. For load instruction we can use
791  // the dst register as a temporary if base and dst are different,
792  // but for stores we must use $at.
793  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
794  TempInst.setOpcode(Mips::LUi);
795  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
796  if (isImmOpnd)
797    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
798  else {
799    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
800      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
801      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
802          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
803          getContext());
804      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
805    } else {
806      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
807      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
808    }
809  }
810  // Add the instruction to the list.
811  Instructions.push_back(TempInst);
812  // Prepare TempInst for next instruction.
813  TempInst.clear();
814  // Add temp register to base.
815  TempInst.setOpcode(Mips::ADDu);
816  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
817  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
818  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
819  Instructions.push_back(TempInst);
820  TempInst.clear();
821  // And finaly, create original instruction with low part
822  // of offset and new base.
823  TempInst.setOpcode(Inst.getOpcode());
824  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
825  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
826  if (isImmOpnd)
827    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
828  else {
829    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
830      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
831          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
832          getContext());
833      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
834    } else {
835      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
836      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
837    }
838  }
839  Instructions.push_back(TempInst);
840  TempInst.clear();
841}
842
843bool MipsAsmParser::
844MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
845                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
846                        MCStreamer &Out, unsigned &ErrorInfo,
847                        bool MatchingInlineAsm) {
848  MCInst Inst;
849  SmallVector<MCInst, 8> Instructions;
850  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
851                                              MatchingInlineAsm);
852
853  switch (MatchResult) {
854  default:
855    break;
856  case Match_Success: {
857    if (processInstruction(Inst, IDLoc, Instructions))
858      return true;
859    for (unsigned i = 0; i < Instructions.size(); i++)
860      Out.EmitInstruction(Instructions[i]);
861    return false;
862  }
863  case Match_MissingFeature:
864    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
865    return true;
866  case Match_InvalidOperand: {
867    SMLoc ErrorLoc = IDLoc;
868    if (ErrorInfo != ~0U) {
869      if (ErrorInfo >= Operands.size())
870        return Error(IDLoc, "too few operands for instruction");
871
872      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
873      if (ErrorLoc == SMLoc())
874        ErrorLoc = IDLoc;
875    }
876
877    return Error(ErrorLoc, "invalid operand for instruction");
878  }
879  case Match_MnemonicFail:
880    return Error(IDLoc, "invalid instruction");
881  }
882  return true;
883}
884
885int MipsAsmParser::matchCPURegisterName(StringRef Name) {
886   int CC;
887
888  if (Name == "at")
889    return getATReg();
890
891    CC = StringSwitch<unsigned>(Name)
892    .Case("zero", 0)
893    .Case("a0",   4)
894    .Case("a1",   5)
895    .Case("a2",   6)
896    .Case("a3",   7)
897    .Case("v0",   2)
898    .Case("v1",   3)
899    .Case("s0",  16)
900    .Case("s1",  17)
901    .Case("s2",  18)
902    .Case("s3",  19)
903    .Case("s4",  20)
904    .Case("s5",  21)
905    .Case("s6",  22)
906    .Case("s7",  23)
907    .Case("k0",  26)
908    .Case("k1",  27)
909    .Case("sp",  29)
910    .Case("fp",  30)
911    .Case("gp",  28)
912    .Case("ra",  31)
913    .Case("t0",   8)
914    .Case("t1",   9)
915    .Case("t2",  10)
916    .Case("t3",  11)
917    .Case("t4",  12)
918    .Case("t5",  13)
919    .Case("t6",  14)
920    .Case("t7",  15)
921    .Case("t8",  24)
922    .Case("t9",  25)
923    .Default(-1);
924
925  // Although SGI documentation just cuts out t0-t3 for n32/n64,
926  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
927  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
928  if (isMips64() && 8 <= CC && CC <= 11)
929    CC += 4;
930
931  if (CC == -1 && isMips64())
932    CC = StringSwitch<unsigned>(Name)
933      .Case("a4",   8)
934      .Case("a5",   9)
935      .Case("a6",  10)
936      .Case("a7",  11)
937      .Case("kt0", 26)
938      .Case("kt1", 27)
939      .Case("s8",  30)
940      .Default(-1);
941
942  return CC;
943}
944
945int MipsAsmParser::matchFPURegisterName(StringRef Name) {
946
947  if (Name[0] == 'f') {
948    StringRef NumString = Name.substr(1);
949    unsigned IntVal;
950    if (NumString.getAsInteger(10, IntVal))
951      return -1; // This is not an integer.
952    if (IntVal > 31) // Maximum index for fpu register.
953      return -1;
954    return IntVal;
955  }
956  return -1;
957}
958
959int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
960
961  if (Name.startswith("fcc")) {
962    StringRef NumString = Name.substr(3);
963    unsigned IntVal;
964    if (NumString.getAsInteger(10, IntVal))
965      return -1; // This is not an integer.
966    if (IntVal > 7) // There are only 8 fcc registers.
967      return -1;
968    return IntVal;
969  }
970  return -1;
971}
972
973int MipsAsmParser::matchACRegisterName(StringRef Name) {
974
975  if (Name.startswith("ac")) {
976    StringRef NumString = Name.substr(2);
977    unsigned IntVal;
978    if (NumString.getAsInteger(10, IntVal))
979      return -1; // This is not an integer.
980    if (IntVal > 3) // There are only 3 acc registers.
981      return -1;
982    return IntVal;
983  }
984  return -1;
985}
986
987int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
988  unsigned IntVal;
989
990  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
991    return -1;
992
993  if (IntVal > 31)
994    return -1;
995
996  return IntVal;
997}
998
999int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1000  int CC;
1001
1002  CC = StringSwitch<unsigned>(Name)
1003    .Case("msair",      0)
1004    .Case("msacsr",     1)
1005    .Case("msaaccess",  2)
1006    .Case("msasave",    3)
1007    .Case("msamodify",  4)
1008    .Case("msarequest", 5)
1009    .Case("msamap",     6)
1010    .Case("msaunmap",   7)
1011    .Default(-1);
1012
1013  return CC;
1014}
1015
1016int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1017
1018  int CC;
1019  CC = matchCPURegisterName(Name);
1020  if (CC != -1)
1021    return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1022                                                : Mips::GPR32RegClassID);
1023  CC = matchFPURegisterName(Name);
1024  //TODO: decide about fpu register class
1025  if (CC != -1)
1026    return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1027                                              : Mips::FGR32RegClassID);
1028  return matchMSA128RegisterName(Name);
1029}
1030
1031int MipsAsmParser::regKindToRegClass(int RegKind) {
1032
1033  switch (RegKind) {
1034  case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
1035  case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
1036  case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
1037  case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
1038  case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
1039  case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
1040  case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
1041  case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
1042  case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
1043  case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
1044  case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1045  case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1046  case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1047  case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
1048  case MipsOperand::Kind_MSA128CtrlRegs: return Mips::MSACtrlRegClassID;
1049  default :return -1;
1050  }
1051
1052}
1053
1054bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1055  if (Reg > 31)
1056    return false;
1057
1058  aTReg = Reg;
1059  return true;
1060}
1061
1062int MipsAsmParser::getATReg() {
1063  return Options.getATRegNum();
1064}
1065
1066unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1067  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1068}
1069
1070int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1071  if (RegNum >
1072       getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
1073    return -1;
1074
1075  return getReg(RegClass, RegNum);
1076}
1077
1078int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1079  const AsmToken &Tok = Parser.getTok();
1080  int RegNum = -1;
1081
1082  if (Tok.is(AsmToken::Identifier)) {
1083    std::string lowerCase = Tok.getString().lower();
1084    RegNum = matchRegisterName(lowerCase, is64BitReg);
1085  } else if (Tok.is(AsmToken::Integer))
1086    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1087        is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
1088  return RegNum;
1089}
1090
1091bool MipsAsmParser::tryParseRegisterOperand(
1092             SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
1093
1094  SMLoc S = Parser.getTok().getLoc();
1095  int RegNo = -1;
1096
1097  RegNo = tryParseRegister(is64BitReg);
1098  if (RegNo == -1)
1099    return true;
1100
1101  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
1102                                            Parser.getTok().getLoc()));
1103  Parser.Lex(); // Eat register token.
1104  return false;
1105}
1106
1107bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1108                                 StringRef Mnemonic) {
1109  // Check if the current operand has a custom associated parser, if so, try to
1110  // custom parse the operand, or fallback to the general approach.
1111  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1112  if (ResTy == MatchOperand_Success)
1113    return false;
1114  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1115  // there was a match, but an error occurred, in which case, just return that
1116  // the operand parsing failed.
1117  if (ResTy == MatchOperand_ParseFail)
1118    return true;
1119
1120  switch (getLexer().getKind()) {
1121  default:
1122    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1123    return true;
1124  case AsmToken::Dollar: {
1125    // Parse the register.
1126    SMLoc S = Parser.getTok().getLoc();
1127    Parser.Lex(); // Eat dollar token.
1128    // Parse the register operand.
1129    if (!tryParseRegisterOperand(Operands, isMips64())) {
1130      if (getLexer().is(AsmToken::LParen)) {
1131        // Check if it is indexed addressing operand.
1132        Operands.push_back(MipsOperand::CreateToken("(", S));
1133        Parser.Lex(); // Eat the parenthesis.
1134        if (getLexer().isNot(AsmToken::Dollar))
1135          return true;
1136
1137        Parser.Lex(); // Eat the dollar
1138        if (tryParseRegisterOperand(Operands, isMips64()))
1139          return true;
1140
1141        if (!getLexer().is(AsmToken::RParen))
1142          return true;
1143
1144        S = Parser.getTok().getLoc();
1145        Operands.push_back(MipsOperand::CreateToken(")", S));
1146        Parser.Lex();
1147      }
1148      return false;
1149    }
1150    // Maybe it is a symbol reference.
1151    StringRef Identifier;
1152    if (Parser.parseIdentifier(Identifier))
1153      return true;
1154
1155    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1156
1157    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1158
1159    // Otherwise create a symbol reference.
1160    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
1161                                                getContext());
1162
1163    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1164    return false;
1165  }
1166  case AsmToken::Identifier:
1167    // Look for the existing symbol, we should check if
1168    // we need to assigne the propper RegisterKind.
1169    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1170      return false;
1171    // Else drop to expression parsing.
1172  case AsmToken::LParen:
1173  case AsmToken::Minus:
1174  case AsmToken::Plus:
1175  case AsmToken::Integer:
1176  case AsmToken::String: {
1177    // Quoted label names.
1178    const MCExpr *IdVal;
1179    SMLoc S = Parser.getTok().getLoc();
1180    if (getParser().parseExpression(IdVal))
1181      return true;
1182    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1183    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1184    return false;
1185  }
1186  case AsmToken::Percent: {
1187    // It is a symbol reference or constant expression.
1188    const MCExpr *IdVal;
1189    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1190    if (parseRelocOperand(IdVal))
1191      return true;
1192
1193    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1194
1195    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1196    return false;
1197  } // case AsmToken::Percent
1198  } // switch(getLexer().getKind())
1199  return true;
1200}
1201
1202const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1203                                               StringRef RelocStr) {
1204  const MCExpr *Res;
1205  // Check the type of the expression.
1206  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1207    // It's a constant, evaluate lo or hi value.
1208    if (RelocStr == "lo") {
1209      short Val = MCE->getValue();
1210      Res = MCConstantExpr::Create(Val, getContext());
1211    } else if (RelocStr == "hi") {
1212      int Val = MCE->getValue();
1213      int LoSign = Val & 0x8000;
1214      Val = (Val & 0xffff0000) >> 16;
1215      // Lower part is treated as a signed int, so if it is negative
1216      // we must add 1 to the hi part to compensate.
1217      if (LoSign)
1218        Val++;
1219      Res = MCConstantExpr::Create(Val, getContext());
1220    } else {
1221      llvm_unreachable("Invalid RelocStr value");
1222    }
1223    return Res;
1224  }
1225
1226  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1227    // It's a symbol, create a symbolic expression from the symbol.
1228    StringRef Symbol = MSRE->getSymbol().getName();
1229    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1230    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1231    return Res;
1232  }
1233
1234  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1235    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1236    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1237    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1238    return Res;
1239  }
1240
1241  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1242    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1243    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1244    return Res;
1245  }
1246  // Just return the original expression.
1247  return Expr;
1248}
1249
1250bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1251
1252  switch (Expr->getKind()) {
1253  case MCExpr::Constant:
1254    return true;
1255  case MCExpr::SymbolRef:
1256    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1257  case MCExpr::Binary:
1258    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1259      if (!isEvaluated(BE->getLHS()))
1260        return false;
1261      return isEvaluated(BE->getRHS());
1262    }
1263  case MCExpr::Unary:
1264    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1265  default:
1266    return false;
1267  }
1268  return false;
1269}
1270
1271bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1272  Parser.Lex(); // Eat the % token.
1273  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1274  if (Tok.isNot(AsmToken::Identifier))
1275    return true;
1276
1277  std::string Str = Tok.getIdentifier().str();
1278
1279  Parser.Lex(); // Eat the identifier.
1280  // Now make an expression from the rest of the operand.
1281  const MCExpr *IdVal;
1282  SMLoc EndLoc;
1283
1284  if (getLexer().getKind() == AsmToken::LParen) {
1285    while (1) {
1286      Parser.Lex(); // Eat the '(' token.
1287      if (getLexer().getKind() == AsmToken::Percent) {
1288        Parser.Lex(); // Eat the % token.
1289        const AsmToken &nextTok = Parser.getTok();
1290        if (nextTok.isNot(AsmToken::Identifier))
1291          return true;
1292        Str += "(%";
1293        Str += nextTok.getIdentifier();
1294        Parser.Lex(); // Eat the identifier.
1295        if (getLexer().getKind() != AsmToken::LParen)
1296          return true;
1297      } else
1298        break;
1299    }
1300    if (getParser().parseParenExpression(IdVal, EndLoc))
1301      return true;
1302
1303    while (getLexer().getKind() == AsmToken::RParen)
1304      Parser.Lex(); // Eat the ')' token.
1305
1306  } else
1307    return true; // Parenthesis must follow the relocation operand.
1308
1309  Res = evaluateRelocExpr(IdVal, Str);
1310  return false;
1311}
1312
1313bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1314                                  SMLoc &EndLoc) {
1315  StartLoc = Parser.getTok().getLoc();
1316  RegNo = tryParseRegister(isMips64());
1317  EndLoc = Parser.getTok().getLoc();
1318  return (RegNo == (unsigned) -1);
1319}
1320
1321bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1322  SMLoc S;
1323  bool Result = true;
1324
1325  while (getLexer().getKind() == AsmToken::LParen)
1326    Parser.Lex();
1327
1328  switch (getLexer().getKind()) {
1329  default:
1330    return true;
1331  case AsmToken::Identifier:
1332  case AsmToken::LParen:
1333  case AsmToken::Integer:
1334  case AsmToken::Minus:
1335  case AsmToken::Plus:
1336    if (isParenExpr)
1337      Result = getParser().parseParenExpression(Res, S);
1338    else
1339      Result = (getParser().parseExpression(Res));
1340    while (getLexer().getKind() == AsmToken::RParen)
1341      Parser.Lex();
1342    break;
1343  case AsmToken::Percent:
1344    Result = parseRelocOperand(Res);
1345  }
1346  return Result;
1347}
1348
1349MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1350                               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1351
1352  const MCExpr *IdVal = 0;
1353  SMLoc S;
1354  bool isParenExpr = false;
1355  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1356  // First operand is the offset.
1357  S = Parser.getTok().getLoc();
1358
1359  if (getLexer().getKind() == AsmToken::LParen) {
1360    Parser.Lex();
1361    isParenExpr = true;
1362  }
1363
1364  if (getLexer().getKind() != AsmToken::Dollar) {
1365    if (parseMemOffset(IdVal, isParenExpr))
1366      return MatchOperand_ParseFail;
1367
1368    const AsmToken &Tok = Parser.getTok(); // Get the next token.
1369    if (Tok.isNot(AsmToken::LParen)) {
1370      MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1371      if (Mnemonic->getToken() == "la") {
1372        SMLoc E = SMLoc::getFromPointer(
1373            Parser.getTok().getLoc().getPointer() - 1);
1374        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1375        return MatchOperand_Success;
1376      }
1377      if (Tok.is(AsmToken::EndOfStatement)) {
1378        SMLoc E = SMLoc::getFromPointer(
1379            Parser.getTok().getLoc().getPointer() - 1);
1380
1381        // Zero register assumed, add a memory operand with ZERO as its base.
1382        Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1383                                                             : Mips::ZERO,
1384                           IdVal, S, E));
1385        return MatchOperand_Success;
1386      }
1387      Error(Parser.getTok().getLoc(), "'(' expected");
1388      return MatchOperand_ParseFail;
1389    }
1390
1391    Parser.Lex(); // Eat the '(' token.
1392  }
1393
1394  Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1395                                        (int) MipsOperand::Kind_GPR32);
1396  if (Res != MatchOperand_Success)
1397    return Res;
1398
1399  if (Parser.getTok().isNot(AsmToken::RParen)) {
1400    Error(Parser.getTok().getLoc(), "')' expected");
1401    return MatchOperand_ParseFail;
1402  }
1403
1404  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1405
1406  Parser.Lex(); // Eat the ')' token.
1407
1408  if (IdVal == 0)
1409    IdVal = MCConstantExpr::Create(0, getContext());
1410
1411  // Replace the register operand with the memory operand.
1412  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1413  int RegNo = op->getReg();
1414  // Remove the register from the operands.
1415  Operands.pop_back();
1416  // Add the memory operand.
1417  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1418    int64_t Imm;
1419    if (IdVal->EvaluateAsAbsolute(Imm))
1420      IdVal = MCConstantExpr::Create(Imm, getContext());
1421    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1422      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1423                                   getContext());
1424  }
1425
1426  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1427  delete op;
1428  return MatchOperand_Success;
1429}
1430
1431bool
1432MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1433                           int RegKind) {
1434  // If the first token is not '$' we have an error.
1435  if (Parser.getTok().isNot(AsmToken::Dollar))
1436    return false;
1437
1438  SMLoc S = Parser.getTok().getLoc();
1439  Parser.Lex();
1440  AsmToken::TokenKind TkKind = getLexer().getKind();
1441  int Reg;
1442
1443  if (TkKind == AsmToken::Integer) {
1444    Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1445                                regKindToRegClass(RegKind));
1446    if (Reg == -1)
1447      return false;
1448  } else if (TkKind == AsmToken::Identifier) {
1449    if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1450      return false;
1451    Reg = getReg(regKindToRegClass(RegKind), Reg);
1452  } else {
1453    return false;
1454  }
1455
1456  MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1457  Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1458  Operands.push_back(Op);
1459  Parser.Lex();
1460  return true;
1461}
1462
1463MipsAsmParser::OperandMatchResultTy
1464MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1465  MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1466                                                MipsOperand::Kind_GPR32;
1467
1468  // Parse index register.
1469  if (!parsePtrReg(Operands, RegKind))
1470    return MatchOperand_NoMatch;
1471
1472  // Parse '('.
1473  if (Parser.getTok().isNot(AsmToken::LParen))
1474    return MatchOperand_NoMatch;
1475
1476  Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1477  Parser.Lex();
1478
1479  // Parse base register.
1480  if (!parsePtrReg(Operands, RegKind))
1481    return MatchOperand_NoMatch;
1482
1483  // Parse ')'.
1484  if (Parser.getTok().isNot(AsmToken::RParen))
1485    return MatchOperand_NoMatch;
1486
1487  Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1488  Parser.Lex();
1489
1490  return MatchOperand_Success;
1491}
1492
1493MipsAsmParser::OperandMatchResultTy
1494MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1495                         int RegKind) {
1496  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1497  if (getLexer().getKind() == AsmToken::Identifier
1498       && !hasConsumedDollar) {
1499    if (searchSymbolAlias(Operands, Kind))
1500      return MatchOperand_Success;
1501    return MatchOperand_NoMatch;
1502  }
1503  SMLoc S = Parser.getTok().getLoc();
1504  // If the first token is not '$', we have an error.
1505  if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1506    return MatchOperand_NoMatch;
1507  if (!hasConsumedDollar) {
1508    Parser.Lex(); // Eat the '$'
1509    hasConsumedDollar = true;
1510  }
1511  if (getLexer().getKind() == AsmToken::Identifier) {
1512    int RegNum = -1;
1513    std::string RegName = Parser.getTok().getString().lower();
1514  // Match register by name
1515    switch (RegKind) {
1516    case MipsOperand::Kind_GPR32:
1517    case MipsOperand::Kind_GPR64:
1518      RegNum = matchCPURegisterName(RegName);
1519      break;
1520    case MipsOperand::Kind_AFGR64Regs:
1521    case MipsOperand::Kind_FGR64Regs:
1522    case MipsOperand::Kind_FGR32Regs:
1523    case MipsOperand::Kind_FGRH32Regs:
1524      RegNum = matchFPURegisterName(RegName);
1525      if (RegKind == MipsOperand::Kind_AFGR64Regs)
1526        RegNum /= 2;
1527      else if (RegKind == MipsOperand::Kind_FGRH32Regs
1528               && !isFP64())
1529        if (RegNum != -1 && RegNum %2 != 0)
1530          Warning(S, "Float register should be even.");
1531      break;
1532    case MipsOperand::Kind_FCCRegs:
1533      RegNum = matchFCCRegisterName(RegName);
1534      break;
1535    case MipsOperand::Kind_ACC64DSP:
1536      RegNum = matchACRegisterName(RegName);
1537      break;
1538    default: break; // No match, value is set to -1.
1539    }
1540    // No match found, return _NoMatch to give a chance to other round.
1541    if (RegNum < 0)
1542      return MatchOperand_NoMatch;
1543
1544    int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1545    if (RegVal == -1)
1546      return MatchOperand_NoMatch;
1547
1548    MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1549                                             Parser.getTok().getLoc());
1550    Op->setRegKind(Kind);
1551    Operands.push_back(Op);
1552    hasConsumedDollar = false;
1553    Parser.Lex(); // Eat the register name.
1554    return MatchOperand_Success;
1555  } else if (getLexer().getKind() == AsmToken::Integer) {
1556    unsigned RegNum = Parser.getTok().getIntVal();
1557    if (Kind == MipsOperand::Kind_HWRegs) {
1558      if (RegNum != 29)
1559        return MatchOperand_NoMatch;
1560      // Only hwreg 29 is supported, found at index 0.
1561      RegNum = 0;
1562    }
1563    int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1564    if (Reg == -1)
1565      return MatchOperand_NoMatch;
1566    MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1567    Op->setRegKind(Kind);
1568    Operands.push_back(Op);
1569    hasConsumedDollar = false;
1570    Parser.Lex(); // Eat the register number.
1571        if ((RegKind == MipsOperand::Kind_GPR32)
1572      && (getLexer().is(AsmToken::LParen))) {
1573      // Check if it is indexed addressing operand.
1574      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1575      Parser.Lex(); // Eat the parenthesis.
1576      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1577        return MatchOperand_NoMatch;
1578      if (getLexer().isNot(AsmToken::RParen))
1579        return MatchOperand_NoMatch;
1580      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1581      Parser.Lex();
1582    }
1583    return MatchOperand_Success;
1584  }
1585  return MatchOperand_NoMatch;
1586}
1587
1588bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1589  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1590
1591  if (Val < 0)
1592    return false;
1593
1594  switch (Kind) {
1595  default:
1596    return false;
1597  case MipsOperand::Kind_MSA128BRegs:
1598    return Val < 16;
1599  case MipsOperand::Kind_MSA128HRegs:
1600    return Val < 8;
1601  case MipsOperand::Kind_MSA128WRegs:
1602    return Val < 4;
1603  case MipsOperand::Kind_MSA128DRegs:
1604    return Val < 2;
1605  }
1606}
1607
1608MipsAsmParser::OperandMatchResultTy
1609MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1610                            int RegKind) {
1611  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1612  SMLoc S = Parser.getTok().getLoc();
1613  std::string RegName;
1614
1615  if (Parser.getTok().isNot(AsmToken::Dollar))
1616    return MatchOperand_NoMatch;
1617
1618  switch (RegKind) {
1619  default:
1620    return MatchOperand_ParseFail;
1621  case MipsOperand::Kind_MSA128BRegs:
1622  case MipsOperand::Kind_MSA128HRegs:
1623  case MipsOperand::Kind_MSA128WRegs:
1624  case MipsOperand::Kind_MSA128DRegs:
1625    break;
1626  }
1627
1628  Parser.Lex(); // Eat the '$'.
1629  if (getLexer().getKind() == AsmToken::Identifier)
1630    RegName = Parser.getTok().getString().lower();
1631  else
1632    return MatchOperand_ParseFail;
1633
1634  int RegNum = matchMSA128RegisterName(RegName);
1635
1636  if (RegNum < 0 || RegNum > 31)
1637    return MatchOperand_ParseFail;
1638
1639  int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1640  if (RegVal == -1)
1641    return MatchOperand_ParseFail;
1642
1643  MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1644                                           Parser.getTok().getLoc());
1645  Op->setRegKind(Kind);
1646  Operands.push_back(Op);
1647
1648  Parser.Lex(); // Eat the register identifier.
1649
1650  // MSA registers may be suffixed with an index in the form of:
1651  // 1) Immediate expression.
1652  // 2) General Purpose Register.
1653  // Examples:
1654  //   1) copy_s.b $29,$w0[0]
1655  //   2) sld.b $w0,$w1[$1]
1656
1657  if (Parser.getTok().isNot(AsmToken::LBrac))
1658    return MatchOperand_Success;
1659
1660  MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1661
1662  Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1663  Parser.Lex(); // Parse the '[' token.
1664
1665  if (Parser.getTok().is(AsmToken::Dollar)) {
1666    // This must be a GPR.
1667    MipsOperand *RegOp;
1668    SMLoc VIdx = Parser.getTok().getLoc();
1669    Parser.Lex(); // Parse the '$' token.
1670
1671    // GPR have aliases and we must account for that. Example: $30 == $fp
1672    if (getLexer().getKind() == AsmToken::Integer) {
1673      unsigned RegNum = Parser.getTok().getIntVal();
1674      int Reg = matchRegisterByNumber(
1675          RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1676      if (Reg == -1) {
1677        Error(VIdx, "invalid general purpose register");
1678        return MatchOperand_ParseFail;
1679      }
1680
1681      RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1682    } else if (getLexer().getKind() == AsmToken::Identifier) {
1683      int RegNum = -1;
1684      std::string RegName = Parser.getTok().getString().lower();
1685
1686      RegNum = matchCPURegisterName(RegName);
1687      if (RegNum == -1) {
1688        Error(VIdx, "general purpose register expected");
1689        return MatchOperand_ParseFail;
1690      }
1691      RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1692      RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1693    } else
1694      return MatchOperand_ParseFail;
1695
1696    RegOp->setRegKind(MipsOperand::Kind_GPR32);
1697    Operands.push_back(RegOp);
1698    Parser.Lex(); // Eat the register identifier.
1699
1700    if (Parser.getTok().isNot(AsmToken::RBrac))
1701      return MatchOperand_ParseFail;
1702
1703    Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1704    Parser.Lex(); // Parse the ']' token.
1705
1706    return MatchOperand_Success;
1707  }
1708
1709  // The index must be a constant expression then.
1710  SMLoc VIdx = Parser.getTok().getLoc();
1711  const MCExpr *ImmVal;
1712
1713  if (getParser().parseExpression(ImmVal))
1714    return MatchOperand_ParseFail;
1715
1716  const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1717  if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1718    Error(VIdx, "invalid immediate value");
1719    return MatchOperand_ParseFail;
1720  }
1721
1722  SMLoc E = Parser.getTok().getEndLoc();
1723
1724  if (Parser.getTok().isNot(AsmToken::RBrac))
1725    return MatchOperand_ParseFail;
1726
1727  bool insve = Mnemonic->getToken() == "insve.b" ||
1728               Mnemonic->getToken() == "insve.h" ||
1729               Mnemonic->getToken() == "insve.w" ||
1730               Mnemonic->getToken() == "insve.d";
1731
1732  // The second vector index of insve instructions is always 0.
1733  if (insve && Operands.size() > 6) {
1734    if (expr->getValue() != 0) {
1735      Error(VIdx, "immediate value must be 0");
1736      return MatchOperand_ParseFail;
1737    }
1738    Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1739  } else
1740    Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1741
1742  Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1743
1744  Parser.Lex(); // Parse the ']' token.
1745
1746  return MatchOperand_Success;
1747}
1748
1749MipsAsmParser::OperandMatchResultTy
1750MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1751                                int RegKind) {
1752  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1753
1754  if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1755    return MatchOperand_NoMatch;
1756
1757  if (Parser.getTok().isNot(AsmToken::Dollar))
1758    return MatchOperand_ParseFail;
1759
1760  SMLoc S = Parser.getTok().getLoc();
1761
1762  Parser.Lex(); // Eat the '$' symbol.
1763
1764  int RegNum = -1;
1765  if (getLexer().getKind() == AsmToken::Identifier)
1766    RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1767  else if (getLexer().getKind() == AsmToken::Integer)
1768    RegNum = Parser.getTok().getIntVal();
1769  else
1770    return MatchOperand_ParseFail;
1771
1772  if (RegNum < 0 || RegNum > 7)
1773    return MatchOperand_ParseFail;
1774
1775  int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1776  if (RegVal == -1)
1777    return MatchOperand_ParseFail;
1778
1779  MipsOperand *RegOp = MipsOperand::CreateReg(RegVal, S,
1780                                              Parser.getTok().getLoc());
1781  RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1782  Operands.push_back(RegOp);
1783  Parser.Lex(); // Eat the register identifier.
1784
1785  return MatchOperand_Success;
1786}
1787
1788MipsAsmParser::OperandMatchResultTy
1789MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1790
1791  if (!isMips64())
1792    return MatchOperand_NoMatch;
1793  return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
1794}
1795
1796MipsAsmParser::OperandMatchResultTy
1797MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1798 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
1799}
1800
1801MipsAsmParser::OperandMatchResultTy
1802MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1803
1804  if (isFP64())
1805    return MatchOperand_NoMatch;
1806  return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1807}
1808
1809MipsAsmParser::OperandMatchResultTy
1810MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1811  if (!isFP64())
1812    return MatchOperand_NoMatch;
1813 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1814}
1815
1816MipsAsmParser::OperandMatchResultTy
1817MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1818  return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1819}
1820
1821MipsAsmParser::OperandMatchResultTy
1822MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1823  return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1824}
1825
1826MipsAsmParser::OperandMatchResultTy
1827MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1828  return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
1829}
1830
1831MipsAsmParser::OperandMatchResultTy
1832MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1833  return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
1834}
1835
1836MipsAsmParser::OperandMatchResultTy
1837MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1838  // If the first token is not '$' we have an error.
1839  if (Parser.getTok().isNot(AsmToken::Dollar))
1840    return MatchOperand_NoMatch;
1841
1842  SMLoc S = Parser.getTok().getLoc();
1843  Parser.Lex(); // Eat the '$'
1844
1845  const AsmToken &Tok = Parser.getTok(); // Get next token.
1846
1847  if (Tok.isNot(AsmToken::Identifier))
1848    return MatchOperand_NoMatch;
1849
1850  if (!Tok.getIdentifier().startswith("ac"))
1851    return MatchOperand_NoMatch;
1852
1853  StringRef NumString = Tok.getIdentifier().substr(2);
1854
1855  unsigned IntVal;
1856  if (NumString.getAsInteger(10, IntVal))
1857    return MatchOperand_NoMatch;
1858
1859  unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1860
1861  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1862  Op->setRegKind(MipsOperand::Kind_LO32DSP);
1863  Operands.push_back(Op);
1864
1865  Parser.Lex(); // Eat the register number.
1866  return MatchOperand_Success;
1867}
1868
1869MipsAsmParser::OperandMatchResultTy
1870MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1871  // If the first token is not '$' we have an error.
1872  if (Parser.getTok().isNot(AsmToken::Dollar))
1873    return MatchOperand_NoMatch;
1874
1875  SMLoc S = Parser.getTok().getLoc();
1876  Parser.Lex(); // Eat the '$'
1877
1878  const AsmToken &Tok = Parser.getTok(); // Get next token.
1879
1880  if (Tok.isNot(AsmToken::Identifier))
1881    return MatchOperand_NoMatch;
1882
1883  if (!Tok.getIdentifier().startswith("ac"))
1884    return MatchOperand_NoMatch;
1885
1886  StringRef NumString = Tok.getIdentifier().substr(2);
1887
1888  unsigned IntVal;
1889  if (NumString.getAsInteger(10, IntVal))
1890    return MatchOperand_NoMatch;
1891
1892  unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1893
1894  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1895  Op->setRegKind(MipsOperand::Kind_HI32DSP);
1896  Operands.push_back(Op);
1897
1898  Parser.Lex(); // Eat the register number.
1899  return MatchOperand_Success;
1900}
1901
1902MipsAsmParser::OperandMatchResultTy
1903MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1904  // If the first token is not '$' we have an error.
1905  if (Parser.getTok().isNot(AsmToken::Dollar))
1906    return MatchOperand_NoMatch;
1907
1908  SMLoc S = Parser.getTok().getLoc();
1909  Parser.Lex(); // Eat the '$'
1910
1911  const AsmToken &Tok = Parser.getTok(); // Get next token.
1912
1913  if (Tok.isNot(AsmToken::Integer))
1914    return MatchOperand_NoMatch;
1915
1916  unsigned IntVal = Tok.getIntVal();
1917
1918  unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1919
1920  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1921  Op->setRegKind(MipsOperand::Kind_COP2);
1922  Operands.push_back(Op);
1923
1924  Parser.Lex(); // Eat the register number.
1925  return MatchOperand_Success;
1926}
1927
1928MipsAsmParser::OperandMatchResultTy
1929MipsAsmParser::parseMSA128BRegs(
1930                              SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1931  return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1932}
1933
1934MipsAsmParser::OperandMatchResultTy
1935MipsAsmParser::parseMSA128HRegs(
1936                              SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1937  return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1938}
1939
1940MipsAsmParser::OperandMatchResultTy
1941MipsAsmParser::parseMSA128WRegs(
1942                              SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1943  return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1944}
1945
1946MipsAsmParser::OperandMatchResultTy
1947MipsAsmParser::parseMSA128DRegs(
1948                              SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1949  return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1950}
1951
1952MipsAsmParser::OperandMatchResultTy
1953MipsAsmParser::parseMSA128CtrlRegs(
1954                             SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1955  return parseMSACtrlRegs(Operands, (int) MipsOperand::Kind_MSA128CtrlRegs);
1956}
1957
1958bool MipsAsmParser::searchSymbolAlias(
1959    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1960
1961  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1962  if (Sym) {
1963    SMLoc S = Parser.getTok().getLoc();
1964    const MCExpr *Expr;
1965    if (Sym->isVariable())
1966      Expr = Sym->getVariableValue();
1967    else
1968      return false;
1969    if (Expr->getKind() == MCExpr::SymbolRef) {
1970      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1971      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1972      const StringRef DefSymbol = Ref->getSymbol().getName();
1973      if (DefSymbol.startswith("$")) {
1974        int RegNum = -1;
1975        APInt IntVal(32, -1);
1976        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1977          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1978                                     isMips64()
1979                                       ? Mips::GPR64RegClassID
1980                                       : Mips::GPR32RegClassID);
1981        else {
1982          // Lookup for the register with the corresponding name.
1983          switch (Kind) {
1984          case MipsOperand::Kind_AFGR64Regs:
1985          case MipsOperand::Kind_FGR64Regs:
1986            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1987            break;
1988          case MipsOperand::Kind_FGR32Regs:
1989            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1990            break;
1991          case MipsOperand::Kind_GPR64:
1992          case MipsOperand::Kind_GPR32:
1993          default:
1994            RegNum = matchCPURegisterName(DefSymbol.substr(1));
1995            break;
1996          }
1997          if (RegNum > -1)
1998            RegNum = getReg(regKindToRegClass(Kind), RegNum);
1999        }
2000        if (RegNum > -1) {
2001          Parser.Lex();
2002          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
2003                                                   Parser.getTok().getLoc());
2004          op->setRegKind(Kind);
2005          Operands.push_back(op);
2006          return true;
2007        }
2008      }
2009    } else if (Expr->getKind() == MCExpr::Constant) {
2010      Parser.Lex();
2011      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
2012      MipsOperand *op = MipsOperand::CreateImm(Const, S,
2013          Parser.getTok().getLoc());
2014      Operands.push_back(op);
2015      return true;
2016    }
2017  }
2018  return false;
2019}
2020
2021MipsAsmParser::OperandMatchResultTy
2022MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2023  return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
2024}
2025
2026MipsAsmParser::OperandMatchResultTy
2027MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2028  return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
2029}
2030
2031MipsAsmParser::OperandMatchResultTy
2032MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2033  const MCExpr *IdVal;
2034  // If the first token is '$' we may have register operand.
2035  if (Parser.getTok().is(AsmToken::Dollar))
2036    return MatchOperand_NoMatch;
2037  SMLoc S = Parser.getTok().getLoc();
2038  if (getParser().parseExpression(IdVal))
2039    return MatchOperand_ParseFail;
2040  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2041    assert( MCE && "Unexpected MCExpr type.");
2042  int64_t Val = MCE->getValue();
2043  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2044  Operands.push_back(MipsOperand::CreateImm(
2045                     MCConstantExpr::Create(0 - Val, getContext()), S, E));
2046  return MatchOperand_Success;
2047}
2048
2049MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2050
2051  MCSymbolRefExpr::VariantKind VK
2052                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2053    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
2054    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
2055    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
2056    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
2057    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
2058    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
2059    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
2060    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2061    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2062    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
2063    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
2064    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
2065    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
2066    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2067    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
2068    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2069    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2070    .Default(MCSymbolRefExpr::VK_None);
2071
2072  return VK;
2073}
2074
2075bool MipsAsmParser::
2076ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2077                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2078  // Check if we have valid mnemonic
2079  if (!mnemonicIsValid(Name, 0)) {
2080    Parser.eatToEndOfStatement();
2081    return Error(NameLoc, "Unknown instruction");
2082  }
2083  // First operand in MCInst is instruction mnemonic.
2084  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2085
2086  // Read the remaining operands.
2087  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2088    // Read the first operand.
2089    if (ParseOperand(Operands, Name)) {
2090      SMLoc Loc = getLexer().getLoc();
2091      Parser.eatToEndOfStatement();
2092      return Error(Loc, "unexpected token in argument list");
2093    }
2094
2095    while (getLexer().is(AsmToken::Comma)) {
2096      Parser.Lex(); // Eat the comma.
2097      // Parse and remember the operand.
2098      if (ParseOperand(Operands, Name)) {
2099        SMLoc Loc = getLexer().getLoc();
2100        Parser.eatToEndOfStatement();
2101        return Error(Loc, "unexpected token in argument list");
2102      }
2103    }
2104  }
2105  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2106    SMLoc Loc = getLexer().getLoc();
2107    Parser.eatToEndOfStatement();
2108    return Error(Loc, "unexpected token in argument list");
2109  }
2110  Parser.Lex(); // Consume the EndOfStatement.
2111  return false;
2112}
2113
2114bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2115  SMLoc Loc = getLexer().getLoc();
2116  Parser.eatToEndOfStatement();
2117  return Error(Loc, ErrorMsg);
2118}
2119
2120bool MipsAsmParser::parseSetNoAtDirective() {
2121  // Line should look like: ".set noat".
2122  // set at reg to 0.
2123  Options.setATReg(0);
2124  // eat noat
2125  Parser.Lex();
2126  // If this is not the end of the statement, report an error.
2127  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2128    reportParseError("unexpected token in statement");
2129    return false;
2130  }
2131  Parser.Lex(); // Consume the EndOfStatement.
2132  return false;
2133}
2134
2135bool MipsAsmParser::parseSetAtDirective() {
2136  // Line can be .set at - defaults to $1
2137  // or .set at=$reg
2138  int AtRegNo;
2139  getParser().Lex();
2140  if (getLexer().is(AsmToken::EndOfStatement)) {
2141    Options.setATReg(1);
2142    Parser.Lex(); // Consume the EndOfStatement.
2143    return false;
2144  } else if (getLexer().is(AsmToken::Equal)) {
2145    getParser().Lex(); // Eat the '='.
2146    if (getLexer().isNot(AsmToken::Dollar)) {
2147      reportParseError("unexpected token in statement");
2148      return false;
2149    }
2150    Parser.Lex(); // Eat the '$'.
2151    const AsmToken &Reg = Parser.getTok();
2152    if (Reg.is(AsmToken::Identifier)) {
2153      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2154    } else if (Reg.is(AsmToken::Integer)) {
2155      AtRegNo = Reg.getIntVal();
2156    } else {
2157      reportParseError("unexpected token in statement");
2158      return false;
2159    }
2160
2161    if (AtRegNo < 1 || AtRegNo > 31) {
2162      reportParseError("unexpected token in statement");
2163      return false;
2164    }
2165
2166    if (!Options.setATReg(AtRegNo)) {
2167      reportParseError("unexpected token in statement");
2168      return false;
2169    }
2170    getParser().Lex(); // Eat the register.
2171
2172    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2173      reportParseError("unexpected token in statement");
2174      return false;
2175    }
2176    Parser.Lex(); // Consume the EndOfStatement.
2177    return false;
2178  } else {
2179    reportParseError("unexpected token in statement");
2180    return false;
2181  }
2182}
2183
2184bool MipsAsmParser::parseSetReorderDirective() {
2185  Parser.Lex();
2186  // If this is not the end of the statement, report an error.
2187  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2188    reportParseError("unexpected token in statement");
2189    return false;
2190  }
2191  Options.setReorder();
2192  Parser.Lex(); // Consume the EndOfStatement.
2193  return false;
2194}
2195
2196bool MipsAsmParser::parseSetNoReorderDirective() {
2197  Parser.Lex();
2198  // If this is not the end of the statement, report an error.
2199  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2200    reportParseError("unexpected token in statement");
2201    return false;
2202  }
2203  Options.setNoreorder();
2204  Parser.Lex(); // Consume the EndOfStatement.
2205  return false;
2206}
2207
2208bool MipsAsmParser::parseSetMacroDirective() {
2209  Parser.Lex();
2210  // If this is not the end of the statement, report an error.
2211  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2212    reportParseError("unexpected token in statement");
2213    return false;
2214  }
2215  Options.setMacro();
2216  Parser.Lex(); // Consume the EndOfStatement.
2217  return false;
2218}
2219
2220bool MipsAsmParser::parseSetNoMacroDirective() {
2221  Parser.Lex();
2222  // If this is not the end of the statement, report an error.
2223  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2224    reportParseError("`noreorder' must be set before `nomacro'");
2225    return false;
2226  }
2227  if (Options.isReorder()) {
2228    reportParseError("`noreorder' must be set before `nomacro'");
2229    return false;
2230  }
2231  Options.setNomacro();
2232  Parser.Lex(); // Consume the EndOfStatement.
2233  return false;
2234}
2235
2236bool MipsAsmParser::parseSetAssignment() {
2237  StringRef Name;
2238  const MCExpr *Value;
2239
2240  if (Parser.parseIdentifier(Name))
2241    reportParseError("expected identifier after .set");
2242
2243  if (getLexer().isNot(AsmToken::Comma))
2244    return reportParseError("unexpected token in .set directive");
2245  Lex(); // Eat comma
2246
2247  if (getLexer().is(AsmToken::Dollar)) {
2248    MCSymbol *Symbol;
2249    SMLoc DollarLoc = getLexer().getLoc();
2250    // Consume the dollar sign, and check for a following identifier.
2251    Parser.Lex();
2252    // We have a '$' followed by something, make sure they are adjacent.
2253    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2254      return true;
2255    StringRef Res = StringRef(DollarLoc.getPointer(),
2256        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2257    Symbol = getContext().GetOrCreateSymbol(Res);
2258    Parser.Lex();
2259    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2260                                    getContext());
2261  } else if (Parser.parseExpression(Value))
2262    return reportParseError("expected valid expression after comma");
2263
2264  // Check if the Name already exists as a symbol.
2265  MCSymbol *Sym = getContext().LookupSymbol(Name);
2266  if (Sym)
2267    return reportParseError("symbol already defined");
2268  Sym = getContext().GetOrCreateSymbol(Name);
2269  Sym->setVariableValue(Value);
2270
2271  return false;
2272}
2273
2274bool MipsAsmParser::parseDirectiveSet() {
2275
2276  // Get the next token.
2277  const AsmToken &Tok = Parser.getTok();
2278
2279  if (Tok.getString() == "noat") {
2280    return parseSetNoAtDirective();
2281  } else if (Tok.getString() == "at") {
2282    return parseSetAtDirective();
2283  } else if (Tok.getString() == "reorder") {
2284    return parseSetReorderDirective();
2285  } else if (Tok.getString() == "noreorder") {
2286    return parseSetNoReorderDirective();
2287  } else if (Tok.getString() == "macro") {
2288    return parseSetMacroDirective();
2289  } else if (Tok.getString() == "nomacro") {
2290    return parseSetNoMacroDirective();
2291  } else if (Tok.getString() == "nomips16") {
2292    // Ignore this directive for now.
2293    Parser.eatToEndOfStatement();
2294    return false;
2295  } else if (Tok.getString() == "nomicromips") {
2296    // Ignore this directive for now.
2297    Parser.eatToEndOfStatement();
2298    return false;
2299  } else {
2300    // It is just an identifier, look for an assignment.
2301    parseSetAssignment();
2302    return false;
2303  }
2304
2305  return true;
2306}
2307
2308bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2309  MCAsmParser &Parser = getParser();
2310  StringRef Name;
2311  if (Parser.parseIdentifier(Name))
2312    reportParseError("expected identifier");
2313
2314  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2315  if (getLexer().isNot(AsmToken::Comma))
2316    return TokError("unexpected token");
2317  Lex();
2318
2319  int64_t Flags = 0;
2320  if (Parser.parseAbsoluteExpression(Flags))
2321    return TokError("unexpected token");
2322
2323  getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
2324  return false;
2325}
2326
2327bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2328  int64_t Flags = 0;
2329  if (Parser.parseAbsoluteExpression(Flags))
2330    return TokError("unexpected token");
2331
2332  getTargetStreamer().emitMipsHackELFFlags(Flags);
2333  return false;
2334}
2335
2336/// parseDirectiveWord
2337///  ::= .word [ expression (, expression)* ]
2338bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2339  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2340    for (;;) {
2341      const MCExpr *Value;
2342      if (getParser().parseExpression(Value))
2343        return true;
2344
2345      getParser().getStreamer().EmitValue(Value, Size);
2346
2347      if (getLexer().is(AsmToken::EndOfStatement))
2348        break;
2349
2350      // FIXME: Improve diagnostic.
2351      if (getLexer().isNot(AsmToken::Comma))
2352        return Error(L, "unexpected token in directive");
2353      Parser.Lex();
2354    }
2355  }
2356
2357  Parser.Lex();
2358  return false;
2359}
2360
2361bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2362
2363  StringRef IDVal = DirectiveID.getString();
2364
2365  if (IDVal == ".ent") {
2366    // Ignore this directive for now.
2367    Parser.Lex();
2368    return false;
2369  }
2370
2371  if (IDVal == ".end") {
2372    // Ignore this directive for now.
2373    Parser.Lex();
2374    return false;
2375  }
2376
2377  if (IDVal == ".frame") {
2378    // Ignore this directive for now.
2379    Parser.eatToEndOfStatement();
2380    return false;
2381  }
2382
2383  if (IDVal == ".set") {
2384    return parseDirectiveSet();
2385  }
2386
2387  if (IDVal == ".fmask") {
2388    // Ignore this directive for now.
2389    Parser.eatToEndOfStatement();
2390    return false;
2391  }
2392
2393  if (IDVal == ".mask") {
2394    // Ignore this directive for now.
2395    Parser.eatToEndOfStatement();
2396    return false;
2397  }
2398
2399  if (IDVal == ".gpword") {
2400    // Ignore this directive for now.
2401    Parser.eatToEndOfStatement();
2402    return false;
2403  }
2404
2405  if (IDVal == ".word") {
2406    parseDirectiveWord(4, DirectiveID.getLoc());
2407    return false;
2408  }
2409
2410  if (IDVal == ".mips_hack_stocg")
2411    return parseDirectiveMipsHackStocg();
2412
2413  if (IDVal == ".mips_hack_elf_flags")
2414    return parseDirectiveMipsHackELFFlags();
2415
2416  return true;
2417}
2418
2419extern "C" void LLVMInitializeMipsAsmParser() {
2420  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2421  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2422  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2423  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2424}
2425
2426#define GET_REGISTER_MATCHER
2427#define GET_MATCHER_IMPLEMENTATION
2428#include "MipsGenAsmMatcher.inc"
2429