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