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