MipsAsmParser.cpp revision 899ee589f5182a35495f068ae15b5f2b5ff4ef8a
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 "llvm/ADT/StringSwitch.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCInst.h"
16#include "llvm/MC/MCParser/MCAsmLexer.h"
17#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSubtargetInfo.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/MC/MCTargetAsmParser.h"
22#include "llvm/Support/TargetRegistry.h"
23#include "llvm/ADT/APInt.h"
24
25using namespace llvm;
26
27namespace {
28class MipsAssemblerOptions {
29public:
30  MipsAssemblerOptions():
31    aTReg(1), reorder(true), macro(true) {
32  }
33
34  unsigned getATRegNum() {return aTReg;}
35  bool setATReg(unsigned Reg);
36
37  bool isReorder() {return reorder;}
38  void setReorder() {reorder = true;}
39  void setNoreorder() {reorder = false;}
40
41  bool isMacro() {return macro;}
42  void setMacro() {macro = true;}
43  void setNomacro() {macro = false;}
44
45private:
46  unsigned aTReg;
47  bool reorder;
48  bool macro;
49};
50}
51
52namespace {
53class MipsAsmParser : public MCTargetAsmParser {
54
55  enum FpFormatTy {
56    FP_FORMAT_NONE = -1,
57    FP_FORMAT_S,
58    FP_FORMAT_D,
59    FP_FORMAT_L,
60    FP_FORMAT_W
61  } FpFormat;
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,
86                         int RegKind);
87
88  MipsAsmParser::OperandMatchResultTy
89  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90
91  MipsAsmParser::OperandMatchResultTy
92  parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
93
94  MipsAsmParser::OperandMatchResultTy
95  parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
96
97  MipsAsmParser::OperandMatchResultTy
98  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
99
100  MipsAsmParser::OperandMatchResultTy
101  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
102
103  MipsAsmParser::OperandMatchResultTy
104  parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
106  MipsAsmParser::OperandMatchResultTy
107  parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108
109  MipsAsmParser::OperandMatchResultTy
110  parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111
112  MipsAsmParser::OperandMatchResultTy
113  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
115  MipsAsmParser::OperandMatchResultTy
116  parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117
118  MipsAsmParser::OperandMatchResultTy
119  parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120
121  MipsAsmParser::OperandMatchResultTy
122  parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123
124  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
125                         unsigned RegKind);
126
127  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
128                    StringRef Mnemonic);
129
130  int tryParseRegister(bool is64BitReg);
131
132  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
133                               bool is64BitReg);
134
135  bool needsExpansion(MCInst &Inst);
136
137  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
138                         SmallVectorImpl<MCInst> &Instructions);
139  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
140                     SmallVectorImpl<MCInst> &Instructions);
141  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
142                            SmallVectorImpl<MCInst> &Instructions);
143  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
144                            SmallVectorImpl<MCInst> &Instructions);
145  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
146                     SmallVectorImpl<MCInst> &Instructions,
147                     bool isLoad,bool isImmOpnd);
148  bool reportParseError(StringRef ErrorMsg);
149
150  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
151  bool parseRelocOperand(const MCExpr *&Res);
152
153  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
154
155  bool isEvaluated(const MCExpr *Expr);
156  bool parseDirectiveSet();
157
158  bool parseSetAtDirective();
159  bool parseSetNoAtDirective();
160  bool parseSetMacroDirective();
161  bool parseSetNoMacroDirective();
162  bool parseSetReorderDirective();
163  bool parseSetNoReorderDirective();
164
165  bool parseSetAssignment();
166
167  bool parseDirectiveWord(unsigned Size, SMLoc L);
168
169  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
170
171  bool isMips64() const {
172    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
173  }
174
175  bool isFP64() const {
176    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
177  }
178
179  int matchRegisterName(StringRef Symbol, bool is64BitReg);
180
181  int matchCPURegisterName(StringRef Symbol);
182
183  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
184
185  int matchFPURegisterName(StringRef Name);
186
187  int matchFCCRegisterName(StringRef Name);
188
189  int matchACRegisterName(StringRef Name);
190
191  int regKindToRegClass(int RegKind);
192
193  FpFormatTy getFpFormat() {return FpFormat;}
194
195  unsigned getReg(int RC, int RegNo);
196
197  int getATReg();
198
199  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
200                        SmallVectorImpl<MCInst> &Instructions);
201public:
202  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
203    : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) {
204    // Initialize the set of available features.
205    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
206  }
207
208  MCAsmParser &getParser() const { return Parser; }
209  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
210
211};
212}
213
214namespace {
215
216/// MipsOperand - Instances of this class represent a parsed Mips machine
217/// instruction.
218class MipsOperand : public MCParsedAsmOperand {
219
220public:
221  enum RegisterKind {
222    Kind_None,
223    Kind_GPR32,
224    Kind_GPR64,
225    Kind_HWRegs,
226    Kind_FGR32Regs,
227    Kind_FGR64Regs,
228    Kind_AFGR64Regs,
229    Kind_CCRRegs,
230    Kind_FCCRegs,
231    Kind_ACC64DSP,
232    Kind_LO32DSP,
233    Kind_HI32DSP
234  };
235
236private:
237  enum KindTy {
238    k_CondCode,
239    k_CoprocNum,
240    k_Immediate,
241    k_Memory,
242    k_PostIndexRegister,
243    k_Register,
244    k_Token
245  } Kind;
246
247  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
248
249  struct Token {
250    const char *Data;
251    unsigned Length;
252  };
253
254  struct RegOp {
255    unsigned RegNum;
256    RegisterKind Kind;
257  };
258
259  struct ImmOp {
260    const MCExpr *Val;
261  };
262
263  struct MemOp {
264    unsigned Base;
265    const MCExpr *Off;
266  };
267
268  union {
269    struct Token Tok;
270    struct RegOp Reg;
271    struct ImmOp Imm;
272    struct MemOp Mem;
273  };
274
275  SMLoc StartLoc, EndLoc;
276
277public:
278  void addRegOperands(MCInst &Inst, unsigned N) const {
279    assert(N == 1 && "Invalid number of operands!");
280    Inst.addOperand(MCOperand::CreateReg(getReg()));
281  }
282
283  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
284    // Add as immediate when possible.  Null MCExpr = 0.
285    if (Expr == 0)
286      Inst.addOperand(MCOperand::CreateImm(0));
287    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
288      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
289    else
290      Inst.addOperand(MCOperand::CreateExpr(Expr));
291  }
292
293  void addImmOperands(MCInst &Inst, unsigned N) const {
294    assert(N == 1 && "Invalid number of operands!");
295    const MCExpr *Expr = getImm();
296    addExpr(Inst, Expr);
297  }
298
299  void addMemOperands(MCInst &Inst, unsigned N) const {
300    assert(N == 2 && "Invalid number of operands!");
301
302    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
303
304    const MCExpr *Expr = getMemOff();
305    addExpr(Inst, Expr);
306  }
307
308  bool isReg() const { return Kind == k_Register; }
309  bool isImm() const { return Kind == k_Immediate; }
310  bool isToken() const { return Kind == k_Token; }
311  bool isMem() const { return Kind == k_Memory; }
312
313  StringRef getToken() const {
314    assert(Kind == k_Token && "Invalid access!");
315    return StringRef(Tok.Data, Tok.Length);
316  }
317
318  unsigned getReg() const {
319    assert((Kind == k_Register) && "Invalid access!");
320    return Reg.RegNum;
321  }
322
323  void setRegKind(RegisterKind RegKind) {
324    assert((Kind == k_Register) && "Invalid access!");
325    Reg.Kind = RegKind;
326  }
327
328  const MCExpr *getImm() const {
329    assert((Kind == k_Immediate) && "Invalid access!");
330    return Imm.Val;
331  }
332
333  unsigned getMemBase() const {
334    assert((Kind == k_Memory) && "Invalid access!");
335    return Mem.Base;
336  }
337
338  const MCExpr *getMemOff() const {
339    assert((Kind == k_Memory) && "Invalid access!");
340    return Mem.Off;
341  }
342
343  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
344    MipsOperand *Op = new MipsOperand(k_Token);
345    Op->Tok.Data = Str.data();
346    Op->Tok.Length = Str.size();
347    Op->StartLoc = S;
348    Op->EndLoc = S;
349    return Op;
350  }
351
352  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
353    MipsOperand *Op = new MipsOperand(k_Register);
354    Op->Reg.RegNum = RegNum;
355    Op->StartLoc = S;
356    Op->EndLoc = E;
357    return Op;
358  }
359
360  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
361    MipsOperand *Op = new MipsOperand(k_Immediate);
362    Op->Imm.Val = Val;
363    Op->StartLoc = S;
364    Op->EndLoc = E;
365    return Op;
366  }
367
368  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
369                                 SMLoc S, SMLoc E) {
370    MipsOperand *Op = new MipsOperand(k_Memory);
371    Op->Mem.Base = Base;
372    Op->Mem.Off = Off;
373    Op->StartLoc = S;
374    Op->EndLoc = E;
375    return Op;
376  }
377
378  bool isGPR32Asm() const {
379    return Kind == k_Register && Reg.Kind == Kind_GPR32;
380  }
381  void addRegAsmOperands(MCInst &Inst, unsigned N) const {
382    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
383  }
384
385  bool isGPR64Asm() const {
386    return Kind == k_Register && Reg.Kind == Kind_GPR64;
387  }
388
389  bool isHWRegsAsm() const {
390    assert((Kind == k_Register) && "Invalid access!");
391    return Reg.Kind == Kind_HWRegs;
392  }
393
394  bool isCCRAsm() const {
395    assert((Kind == k_Register) && "Invalid access!");
396    return Reg.Kind == Kind_CCRRegs;
397  }
398
399   bool isAFGR64Asm() const {
400    return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
401  }
402
403  bool isFGR64Asm() const {
404    return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
405  }
406
407  bool isFGR32Asm() const {
408    return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
409  }
410
411  bool isFCCRegsAsm() const {
412    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
413  }
414
415  bool isACC64DSPAsm() const {
416    return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
417  }
418
419  bool isLO32DSPAsm() const {
420    return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
421  }
422
423  bool isHI32DSPAsm() const {
424    return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
425  }
426
427  /// getStartLoc - Get the location of the first token of this operand.
428  SMLoc getStartLoc() const {
429    return StartLoc;
430  }
431  /// getEndLoc - Get the location of the last token of this operand.
432  SMLoc getEndLoc() const {
433    return EndLoc;
434  }
435
436  virtual void print(raw_ostream &OS) const {
437    llvm_unreachable("unimplemented!");
438  }
439}; // class MipsOperand
440}  // namespace
441
442namespace llvm {
443extern const MCInstrDesc MipsInsts[];
444}
445static const MCInstrDesc &getInstDesc(unsigned Opcode) {
446  return MipsInsts[Opcode];
447}
448
449bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
450                                       SmallVectorImpl<MCInst> &Instructions) {
451  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
452  Inst.setLoc(IDLoc);
453  if (MCID.hasDelaySlot() && Options.isReorder()) {
454    // If this instruction has a delay slot and .set reorder is active,
455    // emit a NOP after it.
456    Instructions.push_back(Inst);
457    MCInst NopInst;
458    NopInst.setOpcode(Mips::SLL);
459    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
460    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
461    NopInst.addOperand(MCOperand::CreateImm(0));
462    Instructions.push_back(NopInst);
463    return false;
464  }
465
466  if (MCID.mayLoad() || MCID.mayStore()) {
467    // Check the offset of memory operand, if it is a symbol
468    // reference or immediate we may have to expand instructions.
469    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
470      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
471      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
472          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
473        MCOperand &Op = Inst.getOperand(i);
474        if (Op.isImm()) {
475          int MemOffset = Op.getImm();
476          if (MemOffset < -32768 || MemOffset > 32767) {
477            // Offset can't exceed 16bit value.
478            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
479            return false;
480          }
481        } else if (Op.isExpr()) {
482          const MCExpr *Expr = Op.getExpr();
483          if (Expr->getKind() == MCExpr::SymbolRef) {
484            const MCSymbolRefExpr *SR =
485                static_cast<const MCSymbolRefExpr*>(Expr);
486            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
487              // Expand symbol.
488              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
489              return false;
490            }
491          } else if (!isEvaluated(Expr)) {
492            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
493            return false;
494          }
495        }
496      }
497    } // for
498  } // if load/store
499
500  if (needsExpansion(Inst))
501    expandInstruction(Inst, IDLoc, Instructions);
502  else
503    Instructions.push_back(Inst);
504
505  return false;
506}
507
508bool MipsAsmParser::needsExpansion(MCInst &Inst) {
509
510  switch (Inst.getOpcode()) {
511  case Mips::LoadImm32Reg:
512  case Mips::LoadAddr32Imm:
513  case Mips::LoadAddr32Reg:
514    return true;
515  default:
516    return false;
517  }
518}
519
520void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
521                                       SmallVectorImpl<MCInst> &Instructions) {
522  switch (Inst.getOpcode()) {
523  case Mips::LoadImm32Reg:
524    return expandLoadImm(Inst, IDLoc, Instructions);
525  case Mips::LoadAddr32Imm:
526    return expandLoadAddressImm(Inst, IDLoc, Instructions);
527  case Mips::LoadAddr32Reg:
528    return expandLoadAddressReg(Inst, IDLoc, Instructions);
529  }
530}
531
532void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
533                                  SmallVectorImpl<MCInst> &Instructions) {
534  MCInst tmpInst;
535  const MCOperand &ImmOp = Inst.getOperand(1);
536  assert(ImmOp.isImm() && "expected immediate operand kind");
537  const MCOperand &RegOp = Inst.getOperand(0);
538  assert(RegOp.isReg() && "expected register operand kind");
539
540  int ImmValue = ImmOp.getImm();
541  tmpInst.setLoc(IDLoc);
542  if (0 <= ImmValue && ImmValue <= 65535) {
543    // For 0 <= j <= 65535.
544    // li d,j => ori d,$zero,j
545    tmpInst.setOpcode(Mips::ORi);
546    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
547    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
548    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
549    Instructions.push_back(tmpInst);
550  } else if (ImmValue < 0 && ImmValue >= -32768) {
551    // For -32768 <= j < 0.
552    // li d,j => addiu d,$zero,j
553    tmpInst.setOpcode(Mips::ADDiu);
554    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
555    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
556    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
557    Instructions.push_back(tmpInst);
558  } else {
559    // For any other value of j that is representable as a 32-bit integer.
560    // li d,j => lui d,hi16(j)
561    //           ori d,d,lo16(j)
562    tmpInst.setOpcode(Mips::LUi);
563    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
564    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
565    Instructions.push_back(tmpInst);
566    tmpInst.clear();
567    tmpInst.setOpcode(Mips::ORi);
568    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
569    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
570    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
571    tmpInst.setLoc(IDLoc);
572    Instructions.push_back(tmpInst);
573  }
574}
575
576void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
577                                       SmallVectorImpl<MCInst> &Instructions) {
578  MCInst tmpInst;
579  const MCOperand &ImmOp = Inst.getOperand(2);
580  assert(ImmOp.isImm() && "expected immediate operand kind");
581  const MCOperand &SrcRegOp = Inst.getOperand(1);
582  assert(SrcRegOp.isReg() && "expected register operand kind");
583  const MCOperand &DstRegOp = Inst.getOperand(0);
584  assert(DstRegOp.isReg() && "expected register operand kind");
585  int ImmValue = ImmOp.getImm();
586  if (-32768 <= ImmValue && ImmValue <= 65535) {
587    // For -32768 <= j <= 65535.
588    // la d,j(s) => addiu d,s,j
589    tmpInst.setOpcode(Mips::ADDiu);
590    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
591    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
592    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
593    Instructions.push_back(tmpInst);
594  } else {
595    // For any other value of j that is representable as a 32-bit integer.
596    // la d,j(s) => lui d,hi16(j)
597    //              ori d,d,lo16(j)
598    //              addu d,d,s
599    tmpInst.setOpcode(Mips::LUi);
600    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
601    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
602    Instructions.push_back(tmpInst);
603    tmpInst.clear();
604    tmpInst.setOpcode(Mips::ORi);
605    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
606    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
607    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
608    Instructions.push_back(tmpInst);
609    tmpInst.clear();
610    tmpInst.setOpcode(Mips::ADDu);
611    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
612    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
613    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
614    Instructions.push_back(tmpInst);
615  }
616}
617
618void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
619                                       SmallVectorImpl<MCInst> &Instructions) {
620  MCInst tmpInst;
621  const MCOperand &ImmOp = Inst.getOperand(1);
622  assert(ImmOp.isImm() && "expected immediate operand kind");
623  const MCOperand &RegOp = Inst.getOperand(0);
624  assert(RegOp.isReg() && "expected register operand kind");
625  int ImmValue = ImmOp.getImm();
626  if (-32768 <= ImmValue && ImmValue <= 65535) {
627    // For -32768 <= j <= 65535.
628    // la d,j => addiu d,$zero,j
629    tmpInst.setOpcode(Mips::ADDiu);
630    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
631    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
632    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
633    Instructions.push_back(tmpInst);
634  } else {
635    // For any other value of j that is representable as a 32-bit integer.
636    // la d,j => lui d,hi16(j)
637    //           ori d,d,lo16(j)
638    tmpInst.setOpcode(Mips::LUi);
639    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
640    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
641    Instructions.push_back(tmpInst);
642    tmpInst.clear();
643    tmpInst.setOpcode(Mips::ORi);
644    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
645    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
646    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
647    Instructions.push_back(tmpInst);
648  }
649}
650
651void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
652          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
653  const MCSymbolRefExpr *SR;
654  MCInst TempInst;
655  unsigned ImmOffset, HiOffset, LoOffset;
656  const MCExpr *ExprOffset;
657  unsigned TmpRegNum;
658  unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
659                             : Mips::GPR32RegClassID, getATReg());
660  // 1st operand is either the source or destination register.
661  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
662  unsigned RegOpNum = Inst.getOperand(0).getReg();
663  // 2nd operand is the base register.
664  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
665  unsigned BaseRegNum = Inst.getOperand(1).getReg();
666  // 3rd operand is either an immediate or expression.
667  if (isImmOpnd) {
668    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
669    ImmOffset = Inst.getOperand(2).getImm();
670    LoOffset = ImmOffset & 0x0000ffff;
671    HiOffset = (ImmOffset & 0xffff0000) >> 16;
672    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
673    if (LoOffset & 0x8000)
674      HiOffset++;
675  } else
676    ExprOffset = Inst.getOperand(2).getExpr();
677  // All instructions will have the same location.
678  TempInst.setLoc(IDLoc);
679  // 1st instruction in expansion is LUi. For load instruction we can use
680  // the dst register as a temporary if base and dst are different,
681  // but for stores we must use $at.
682  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
683  TempInst.setOpcode(Mips::LUi);
684  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
685  if (isImmOpnd)
686    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
687  else {
688    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
689      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
690      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
691          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
692          getContext());
693      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
694    } else {
695      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
696      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
697    }
698  }
699  // Add the instruction to the list.
700  Instructions.push_back(TempInst);
701  // Prepare TempInst for next instruction.
702  TempInst.clear();
703  // Add temp register to base.
704  TempInst.setOpcode(Mips::ADDu);
705  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
706  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
707  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
708  Instructions.push_back(TempInst);
709  TempInst.clear();
710  // And finaly, create original instruction with low part
711  // of offset and new base.
712  TempInst.setOpcode(Inst.getOpcode());
713  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
714  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
715  if (isImmOpnd)
716    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
717  else {
718    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
719      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
720          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
721          getContext());
722      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
723    } else {
724      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
725      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
726    }
727  }
728  Instructions.push_back(TempInst);
729  TempInst.clear();
730}
731
732bool MipsAsmParser::
733MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
734                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
735                        MCStreamer &Out, unsigned &ErrorInfo,
736                        bool MatchingInlineAsm) {
737  MCInst Inst;
738  SmallVector<MCInst, 8> Instructions;
739  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
740                                              MatchingInlineAsm);
741
742  switch (MatchResult) {
743  default:
744    break;
745  case Match_Success: {
746    if (processInstruction(Inst, IDLoc, Instructions))
747      return true;
748    for (unsigned i = 0; i < Instructions.size(); i++)
749      Out.EmitInstruction(Instructions[i]);
750    return false;
751  }
752  case Match_MissingFeature:
753    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
754    return true;
755  case Match_InvalidOperand: {
756    SMLoc ErrorLoc = IDLoc;
757    if (ErrorInfo != ~0U) {
758      if (ErrorInfo >= Operands.size())
759        return Error(IDLoc, "too few operands for instruction");
760
761      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
762      if (ErrorLoc == SMLoc())
763        ErrorLoc = IDLoc;
764    }
765
766    return Error(ErrorLoc, "invalid operand for instruction");
767  }
768  case Match_MnemonicFail:
769    return Error(IDLoc, "invalid instruction");
770  }
771  return true;
772}
773
774int MipsAsmParser::matchCPURegisterName(StringRef Name) {
775   int CC;
776
777  if (Name == "at")
778    return getATReg();
779
780    CC = StringSwitch<unsigned>(Name)
781    .Case("zero", 0)
782    .Case("a0",   4)
783    .Case("a1",   5)
784    .Case("a2",   6)
785    .Case("a3",   7)
786    .Case("v0",   2)
787    .Case("v1",   3)
788    .Case("s0",  16)
789    .Case("s1",  17)
790    .Case("s2",  18)
791    .Case("s3",  19)
792    .Case("s4",  20)
793    .Case("s5",  21)
794    .Case("s6",  22)
795    .Case("s7",  23)
796    .Case("k0",  26)
797    .Case("k1",  27)
798    .Case("sp",  29)
799    .Case("fp",  30)
800    .Case("gp",  28)
801    .Case("ra",  31)
802    .Case("t0",   8)
803    .Case("t1",   9)
804    .Case("t2",  10)
805    .Case("t3",  11)
806    .Case("t4",  12)
807    .Case("t5",  13)
808    .Case("t6",  14)
809    .Case("t7",  15)
810    .Case("t8",  24)
811    .Case("t9",  25)
812    .Default(-1);
813
814  // Although SGI documentation just cuts out t0-t3 for n32/n64,
815  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
816  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
817  if (isMips64() && 8 <= CC && CC <= 11)
818    CC += 4;
819
820  if (CC == -1 && isMips64())
821    CC = StringSwitch<unsigned>(Name)
822      .Case("a4",   8)
823      .Case("a5",   9)
824      .Case("a6",  10)
825      .Case("a7",  11)
826      .Case("kt0", 26)
827      .Case("kt1", 27)
828      .Case("s8",  30)
829      .Default(-1);
830
831  return CC;
832}
833
834int MipsAsmParser::matchFPURegisterName(StringRef Name) {
835
836  if (Name[0] == 'f') {
837    StringRef NumString = Name.substr(1);
838    unsigned IntVal;
839    if (NumString.getAsInteger(10, IntVal))
840      return -1; // This is not an integer.
841    if (IntVal > 31) // Maximum index for fpu register.
842      return -1;
843    return IntVal;
844  }
845  return -1;
846}
847
848int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
849
850  if (Name.startswith("fcc")) {
851    StringRef NumString = Name.substr(3);
852    unsigned IntVal;
853    if (NumString.getAsInteger(10, IntVal))
854      return -1; // This is not an integer.
855    if (IntVal > 7) // There are only 8 fcc registers.
856      return -1;
857    return IntVal;
858  }
859  return -1;
860}
861
862int MipsAsmParser::matchACRegisterName(StringRef Name) {
863
864  if (Name.startswith("ac")) {
865    StringRef NumString = Name.substr(2);
866    unsigned IntVal;
867    if (NumString.getAsInteger(10, IntVal))
868      return -1; // This is not an integer.
869    if (IntVal > 3) // There are only 3 acc registers.
870      return -1;
871    return IntVal;
872  }
873  return -1;
874}
875
876int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
877
878  int CC;
879  CC = matchCPURegisterName(Name);
880  if (CC != -1)
881    return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
882                                                : Mips::GPR32RegClassID);
883  CC= matchFPURegisterName(Name);
884  //TODO: decide about fpu register class
885  return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
886                                                : Mips::FGR32RegClassID);
887}
888
889int MipsAsmParser::regKindToRegClass(int RegKind) {
890
891  switch (RegKind) {
892  case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
893  case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
894  case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
895  case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
896  case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
897  case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
898  case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
899  case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
900  case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
901  default :return -1;
902  }
903
904}
905
906bool MipsAssemblerOptions::setATReg(unsigned Reg) {
907  if (Reg > 31)
908    return false;
909
910  aTReg = Reg;
911  return true;
912}
913
914int MipsAsmParser::getATReg() {
915  return Options.getATRegNum();
916}
917
918unsigned MipsAsmParser::getReg(int RC, int RegNo) {
919  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
920}
921
922int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
923  if (RegNum >
924       getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
925    return -1;
926
927  return getReg(RegClass, RegNum);
928}
929
930int MipsAsmParser::tryParseRegister(bool is64BitReg) {
931  const AsmToken &Tok = Parser.getTok();
932  int RegNum = -1;
933
934  if (Tok.is(AsmToken::Identifier)) {
935    std::string lowerCase = Tok.getString().lower();
936    RegNum = matchRegisterName(lowerCase, is64BitReg);
937  } else if (Tok.is(AsmToken::Integer))
938    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
939        is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
940  return RegNum;
941}
942
943bool MipsAsmParser::tryParseRegisterOperand(
944             SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
945
946  SMLoc S = Parser.getTok().getLoc();
947  int RegNo = -1;
948
949  RegNo = tryParseRegister(is64BitReg);
950  if (RegNo == -1)
951    return true;
952
953  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
954                                            Parser.getTok().getLoc()));
955  Parser.Lex(); // Eat register token.
956  return false;
957}
958
959bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
960                                 StringRef Mnemonic) {
961  // Check if the current operand has a custom associated parser, if so, try to
962  // custom parse the operand, or fallback to the general approach.
963  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
964  if (ResTy == MatchOperand_Success)
965    return false;
966  // If there wasn't a custom match, try the generic matcher below. Otherwise,
967  // there was a match, but an error occurred, in which case, just return that
968  // the operand parsing failed.
969  if (ResTy == MatchOperand_ParseFail)
970    return true;
971
972  switch (getLexer().getKind()) {
973  default:
974    Error(Parser.getTok().getLoc(), "unexpected token in operand");
975    return true;
976  case AsmToken::Dollar: {
977    // Parse the register.
978    SMLoc S = Parser.getTok().getLoc();
979    Parser.Lex(); // Eat dollar token.
980    // Parse the register operand.
981    if (!tryParseRegisterOperand(Operands, isMips64())) {
982      if (getLexer().is(AsmToken::LParen)) {
983        // Check if it is indexed addressing operand.
984        Operands.push_back(MipsOperand::CreateToken("(", S));
985        Parser.Lex(); // Eat the parenthesis.
986        if (getLexer().isNot(AsmToken::Dollar))
987          return true;
988
989        Parser.Lex(); // Eat the dollar
990        if (tryParseRegisterOperand(Operands, isMips64()))
991          return true;
992
993        if (!getLexer().is(AsmToken::RParen))
994          return true;
995
996        S = Parser.getTok().getLoc();
997        Operands.push_back(MipsOperand::CreateToken(")", S));
998        Parser.Lex();
999      }
1000      return false;
1001    }
1002    // Maybe it is a symbol reference.
1003    StringRef Identifier;
1004    if (Parser.parseIdentifier(Identifier))
1005      return true;
1006
1007    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1008
1009    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1010
1011    // Otherwise create a symbol reference.
1012    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
1013                                                getContext());
1014
1015    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1016    return false;
1017  }
1018  case AsmToken::Identifier:
1019    // Look for the existing symbol, we should check if
1020    // we need to assigne the propper RegisterKind.
1021    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1022      return false;
1023    // Else drop to expression parsing.
1024  case AsmToken::LParen:
1025  case AsmToken::Minus:
1026  case AsmToken::Plus:
1027  case AsmToken::Integer:
1028  case AsmToken::String: {
1029    // Quoted label names.
1030    const MCExpr *IdVal;
1031    SMLoc S = Parser.getTok().getLoc();
1032    if (getParser().parseExpression(IdVal))
1033      return true;
1034    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1035    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1036    return false;
1037  }
1038  case AsmToken::Percent: {
1039    // It is a symbol reference or constant expression.
1040    const MCExpr *IdVal;
1041    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1042    if (parseRelocOperand(IdVal))
1043      return true;
1044
1045    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1046
1047    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1048    return false;
1049  } // case AsmToken::Percent
1050  } // switch(getLexer().getKind())
1051  return true;
1052}
1053
1054const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1055                                               StringRef RelocStr) {
1056  const MCExpr *Res;
1057  // Check the type of the expression.
1058  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1059    // It's a constant, evaluate lo or hi value.
1060    if (RelocStr == "lo") {
1061      short Val = MCE->getValue();
1062      Res = MCConstantExpr::Create(Val, getContext());
1063    } else if (RelocStr == "hi") {
1064      int Val = MCE->getValue();
1065      int LoSign = Val & 0x8000;
1066      Val = (Val & 0xffff0000) >> 16;
1067      // Lower part is treated as a signed int, so if it is negative
1068      // we must add 1 to the hi part to compensate.
1069      if (LoSign)
1070        Val++;
1071      Res = MCConstantExpr::Create(Val, getContext());
1072    } else {
1073      llvm_unreachable("Invalid RelocStr value");
1074    }
1075    return Res;
1076  }
1077
1078  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1079    // It's a symbol, create a symbolic expression from the symbol.
1080    StringRef Symbol = MSRE->getSymbol().getName();
1081    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1082    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1083    return Res;
1084  }
1085
1086  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1087    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1088    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1089    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1090    return Res;
1091  }
1092
1093  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1094    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1095    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1096    return Res;
1097  }
1098  // Just return the original expression.
1099  return Expr;
1100}
1101
1102bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1103
1104  switch (Expr->getKind()) {
1105  case MCExpr::Constant:
1106    return true;
1107  case MCExpr::SymbolRef:
1108    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1109  case MCExpr::Binary:
1110    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1111      if (!isEvaluated(BE->getLHS()))
1112        return false;
1113      return isEvaluated(BE->getRHS());
1114    }
1115  case MCExpr::Unary:
1116    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1117  default:
1118    return false;
1119  }
1120  return false;
1121}
1122
1123bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1124  Parser.Lex(); // Eat the % token.
1125  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1126  if (Tok.isNot(AsmToken::Identifier))
1127    return true;
1128
1129  std::string Str = Tok.getIdentifier().str();
1130
1131  Parser.Lex(); // Eat the identifier.
1132  // Now make an expression from the rest of the operand.
1133  const MCExpr *IdVal;
1134  SMLoc EndLoc;
1135
1136  if (getLexer().getKind() == AsmToken::LParen) {
1137    while (1) {
1138      Parser.Lex(); // Eat the '(' token.
1139      if (getLexer().getKind() == AsmToken::Percent) {
1140        Parser.Lex(); // Eat the % token.
1141        const AsmToken &nextTok = Parser.getTok();
1142        if (nextTok.isNot(AsmToken::Identifier))
1143          return true;
1144        Str += "(%";
1145        Str += nextTok.getIdentifier();
1146        Parser.Lex(); // Eat the identifier.
1147        if (getLexer().getKind() != AsmToken::LParen)
1148          return true;
1149      } else
1150        break;
1151    }
1152    if (getParser().parseParenExpression(IdVal, EndLoc))
1153      return true;
1154
1155    while (getLexer().getKind() == AsmToken::RParen)
1156      Parser.Lex(); // Eat the ')' token.
1157
1158  } else
1159    return true; // Parenthesis must follow the relocation operand.
1160
1161  Res = evaluateRelocExpr(IdVal, Str);
1162  return false;
1163}
1164
1165bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1166                                  SMLoc &EndLoc) {
1167  StartLoc = Parser.getTok().getLoc();
1168  RegNo = tryParseRegister(isMips64());
1169  EndLoc = Parser.getTok().getLoc();
1170  return (RegNo == (unsigned) -1);
1171}
1172
1173bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1174  SMLoc S;
1175  bool Result = true;
1176
1177  while (getLexer().getKind() == AsmToken::LParen)
1178    Parser.Lex();
1179
1180  switch (getLexer().getKind()) {
1181  default:
1182    return true;
1183  case AsmToken::Identifier:
1184  case AsmToken::LParen:
1185  case AsmToken::Integer:
1186  case AsmToken::Minus:
1187  case AsmToken::Plus:
1188    if (isParenExpr)
1189      Result = getParser().parseParenExpression(Res, S);
1190    else
1191      Result = (getParser().parseExpression(Res));
1192    while (getLexer().getKind() == AsmToken::RParen)
1193      Parser.Lex();
1194    break;
1195  case AsmToken::Percent:
1196    Result = parseRelocOperand(Res);
1197  }
1198  return Result;
1199}
1200
1201MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1202                               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1203
1204  const MCExpr *IdVal = 0;
1205  SMLoc S;
1206  bool isParenExpr = false;
1207  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1208  // First operand is the offset.
1209  S = Parser.getTok().getLoc();
1210
1211  if (getLexer().getKind() == AsmToken::LParen) {
1212    Parser.Lex();
1213    isParenExpr = true;
1214  }
1215
1216  if (getLexer().getKind() != AsmToken::Dollar) {
1217    if (parseMemOffset(IdVal, isParenExpr))
1218      return MatchOperand_ParseFail;
1219
1220    const AsmToken &Tok = Parser.getTok(); // Get the next token.
1221    if (Tok.isNot(AsmToken::LParen)) {
1222      MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1223      if (Mnemonic->getToken() == "la") {
1224        SMLoc E = SMLoc::getFromPointer(
1225            Parser.getTok().getLoc().getPointer() - 1);
1226        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1227        return MatchOperand_Success;
1228      }
1229      if (Tok.is(AsmToken::EndOfStatement)) {
1230        SMLoc E = SMLoc::getFromPointer(
1231            Parser.getTok().getLoc().getPointer() - 1);
1232
1233        // Zero register assumed, add a memory operand with ZERO as its base.
1234        Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1235                                                             : Mips::ZERO,
1236                           IdVal, S, E));
1237        return MatchOperand_Success;
1238      }
1239      Error(Parser.getTok().getLoc(), "'(' expected");
1240      return MatchOperand_ParseFail;
1241    }
1242
1243    Parser.Lex(); // Eat the '(' token.
1244  }
1245
1246  Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1247                                        (int) MipsOperand::Kind_GPR32);
1248  if (Res != MatchOperand_Success)
1249    return Res;
1250
1251  if (Parser.getTok().isNot(AsmToken::RParen)) {
1252    Error(Parser.getTok().getLoc(), "')' expected");
1253    return MatchOperand_ParseFail;
1254  }
1255
1256  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1257
1258  Parser.Lex(); // Eat the ')' token.
1259
1260  if (IdVal == 0)
1261    IdVal = MCConstantExpr::Create(0, getContext());
1262
1263  // Replace the register operand with the memory operand.
1264  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1265  int RegNo = op->getReg();
1266  // Remove the register from the operands.
1267  Operands.pop_back();
1268  // Add the memory operand.
1269  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1270    int64_t Imm;
1271    if (IdVal->EvaluateAsAbsolute(Imm))
1272      IdVal = MCConstantExpr::Create(Imm, getContext());
1273    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1274      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1275                                   getContext());
1276  }
1277
1278  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1279  delete op;
1280  return MatchOperand_Success;
1281}
1282
1283MipsAsmParser::OperandMatchResultTy
1284MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1285                         int RegKind) {
1286  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1287  if (getLexer().getKind() == AsmToken::Identifier
1288       && !hasConsumedDollar) {
1289    if (searchSymbolAlias(Operands, Kind))
1290      return MatchOperand_Success;
1291    return MatchOperand_NoMatch;
1292  }
1293  SMLoc S = Parser.getTok().getLoc();
1294  // If the first token is not '$', we have an error.
1295  if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1296    return MatchOperand_NoMatch;
1297  if (!hasConsumedDollar) {
1298    Parser.Lex(); // Eat the '$'
1299    hasConsumedDollar = true;
1300  }
1301  if (getLexer().getKind() == AsmToken::Identifier) {
1302    int RegNum = -1;
1303    std::string RegName = Parser.getTok().getString().lower();
1304  // Match register by name
1305    switch (RegKind) {
1306    case MipsOperand::Kind_GPR32:
1307    case MipsOperand::Kind_GPR64:
1308      RegNum = matchCPURegisterName(RegName);
1309      break;
1310    case MipsOperand::Kind_AFGR64Regs:
1311    case MipsOperand::Kind_FGR64Regs:
1312    case MipsOperand::Kind_FGR32Regs:
1313      RegNum = matchFPURegisterName(RegName);
1314      if (RegKind == MipsOperand::Kind_AFGR64Regs)
1315        RegNum /= 2;
1316      break;
1317    case MipsOperand::Kind_FCCRegs:
1318      RegNum = matchFCCRegisterName(RegName);
1319      break;
1320    case MipsOperand::Kind_ACC64DSP:
1321      RegNum = matchACRegisterName(RegName);
1322      break;
1323    default: break; // No match, value is set to -1.
1324    }
1325    // No match found, return _NoMatch to give a chance to other round.
1326    if (RegNum < 0)
1327      return MatchOperand_NoMatch;
1328
1329    int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1330    if (RegVal == -1)
1331      return MatchOperand_NoMatch;
1332
1333    MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1334                                             Parser.getTok().getLoc());
1335    Op->setRegKind(Kind);
1336    Operands.push_back(Op);
1337    hasConsumedDollar = false;
1338    Parser.Lex(); // Eat the register name.
1339    if ((RegKind == MipsOperand::Kind_GPR32)
1340      && (getLexer().is(AsmToken::LParen))) {
1341      // Check if it is indexed addressing operand.
1342      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1343      Parser.Lex(); // Eat the parenthesis.
1344      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1345        return MatchOperand_NoMatch;
1346      if (getLexer().isNot(AsmToken::RParen))
1347        return MatchOperand_NoMatch;
1348      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1349      Parser.Lex();
1350    }
1351    return MatchOperand_Success;
1352  } else if (getLexer().getKind() == AsmToken::Integer) {
1353    unsigned RegNum = Parser.getTok().getIntVal();
1354    if (Kind == MipsOperand::Kind_HWRegs) {
1355      if (RegNum != 29)
1356        return MatchOperand_NoMatch;
1357      // Only hwreg 29 is supported, found at index 0.
1358      RegNum = 0;
1359    }
1360    int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1361    if (Reg == -1)
1362      return MatchOperand_NoMatch;
1363    MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1364    Op->setRegKind(Kind);
1365    Operands.push_back(Op);
1366    hasConsumedDollar = false;
1367    Parser.Lex(); // Eat the register number.
1368        if ((RegKind == MipsOperand::Kind_GPR32)
1369      && (getLexer().is(AsmToken::LParen))) {
1370      // Check if it is indexed addressing operand.
1371      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1372      Parser.Lex(); // Eat the parenthesis.
1373      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1374        return MatchOperand_NoMatch;
1375      if (getLexer().isNot(AsmToken::RParen))
1376        return MatchOperand_NoMatch;
1377      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1378      Parser.Lex();
1379    }
1380    return MatchOperand_Success;
1381  }
1382  return MatchOperand_NoMatch;
1383}
1384
1385MipsAsmParser::OperandMatchResultTy
1386MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1387
1388  if (!isMips64())
1389    return MatchOperand_NoMatch;
1390  return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
1391}
1392
1393MipsAsmParser::OperandMatchResultTy
1394MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1395 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
1396}
1397
1398MipsAsmParser::OperandMatchResultTy
1399MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1400
1401  if (isFP64())
1402    return MatchOperand_NoMatch;
1403  return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1404}
1405
1406MipsAsmParser::OperandMatchResultTy
1407MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1408  if (!isFP64())
1409    return MatchOperand_NoMatch;
1410 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1411}
1412
1413MipsAsmParser::OperandMatchResultTy
1414MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1415  return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1416}
1417
1418MipsAsmParser::OperandMatchResultTy
1419MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1420  return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
1421}
1422
1423MipsAsmParser::OperandMatchResultTy
1424MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1425  return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
1426}
1427
1428MipsAsmParser::OperandMatchResultTy
1429MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1430  // If the first token is not '$' we have an error.
1431  if (Parser.getTok().isNot(AsmToken::Dollar))
1432    return MatchOperand_NoMatch;
1433
1434  SMLoc S = Parser.getTok().getLoc();
1435  Parser.Lex(); // Eat the '$'
1436
1437  const AsmToken &Tok = Parser.getTok(); // Get next token.
1438
1439  if (Tok.isNot(AsmToken::Identifier))
1440    return MatchOperand_NoMatch;
1441
1442  if (!Tok.getIdentifier().startswith("ac"))
1443    return MatchOperand_NoMatch;
1444
1445  StringRef NumString = Tok.getIdentifier().substr(2);
1446
1447  unsigned IntVal;
1448  if (NumString.getAsInteger(10, IntVal))
1449    return MatchOperand_NoMatch;
1450
1451  unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1452
1453  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1454  Op->setRegKind(MipsOperand::Kind_LO32DSP);
1455  Operands.push_back(Op);
1456
1457  Parser.Lex(); // Eat the register number.
1458  return MatchOperand_Success;
1459}
1460
1461MipsAsmParser::OperandMatchResultTy
1462MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1463  // If the first token is not '$' we have an error.
1464  if (Parser.getTok().isNot(AsmToken::Dollar))
1465    return MatchOperand_NoMatch;
1466
1467  SMLoc S = Parser.getTok().getLoc();
1468  Parser.Lex(); // Eat the '$'
1469
1470  const AsmToken &Tok = Parser.getTok(); // Get next token.
1471
1472  if (Tok.isNot(AsmToken::Identifier))
1473    return MatchOperand_NoMatch;
1474
1475  if (!Tok.getIdentifier().startswith("ac"))
1476    return MatchOperand_NoMatch;
1477
1478  StringRef NumString = Tok.getIdentifier().substr(2);
1479
1480  unsigned IntVal;
1481  if (NumString.getAsInteger(10, IntVal))
1482    return MatchOperand_NoMatch;
1483
1484  unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1485
1486  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1487  Op->setRegKind(MipsOperand::Kind_HI32DSP);
1488  Operands.push_back(Op);
1489
1490  Parser.Lex(); // Eat the register number.
1491  return MatchOperand_Success;
1492}
1493
1494bool MipsAsmParser::searchSymbolAlias(
1495    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1496
1497  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1498  if (Sym) {
1499    SMLoc S = Parser.getTok().getLoc();
1500    const MCExpr *Expr;
1501    if (Sym->isVariable())
1502      Expr = Sym->getVariableValue();
1503    else
1504      return false;
1505    if (Expr->getKind() == MCExpr::SymbolRef) {
1506      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1507      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1508      const StringRef DefSymbol = Ref->getSymbol().getName();
1509      if (DefSymbol.startswith("$")) {
1510        int RegNum = -1;
1511        APInt IntVal(32, -1);
1512        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1513          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1514                                     isMips64()
1515                                       ? Mips::GPR64RegClassID
1516                                       : Mips::GPR32RegClassID);
1517        else {
1518          // Lookup for the register with the corresponding name.
1519          switch (Kind) {
1520          case MipsOperand::Kind_AFGR64Regs:
1521          case MipsOperand::Kind_FGR64Regs:
1522            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1523            break;
1524          case MipsOperand::Kind_FGR32Regs:
1525            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1526            break;
1527          case MipsOperand::Kind_GPR64:
1528          case MipsOperand::Kind_GPR32:
1529          default:
1530            RegNum = matchCPURegisterName(DefSymbol.substr(1));
1531            break;
1532          }
1533          if (RegNum > -1)
1534            RegNum = getReg(regKindToRegClass(Kind), RegNum);
1535        }
1536        if (RegNum > -1) {
1537          Parser.Lex();
1538          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1539                                                   Parser.getTok().getLoc());
1540          op->setRegKind(Kind);
1541          Operands.push_back(op);
1542          return true;
1543        }
1544      }
1545    } else if (Expr->getKind() == MCExpr::Constant) {
1546      Parser.Lex();
1547      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1548      MipsOperand *op = MipsOperand::CreateImm(Const, S,
1549          Parser.getTok().getLoc());
1550      Operands.push_back(op);
1551      return true;
1552    }
1553  }
1554  return false;
1555}
1556
1557MipsAsmParser::OperandMatchResultTy
1558MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1559  return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
1560}
1561
1562MipsAsmParser::OperandMatchResultTy
1563MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1564  return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
1565}
1566
1567MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1568
1569  MCSymbolRefExpr::VariantKind VK
1570                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1571    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1572    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1573    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1574    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1575    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1576    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1577    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1578    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1579    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1580    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1581    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1582    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1583    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1584    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1585    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1586    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1587    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1588    .Default(MCSymbolRefExpr::VK_None);
1589
1590  return VK;
1591}
1592
1593bool MipsAsmParser::
1594ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1595                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1596  // Check if we have valid mnemonic
1597  if (!mnemonicIsValid(Name, 0)) {
1598    Parser.eatToEndOfStatement();
1599    return Error(NameLoc, "Unknown instruction");
1600  }
1601  // First operand in MCInst is instruction mnemonic.
1602  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1603
1604  // Read the remaining operands.
1605  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1606    // Read the first operand.
1607    if (ParseOperand(Operands, Name)) {
1608      SMLoc Loc = getLexer().getLoc();
1609      Parser.eatToEndOfStatement();
1610      return Error(Loc, "unexpected token in argument list");
1611    }
1612
1613    while (getLexer().is(AsmToken::Comma)) {
1614      Parser.Lex(); // Eat the comma.
1615      // Parse and remember the operand.
1616      if (ParseOperand(Operands, Name)) {
1617        SMLoc Loc = getLexer().getLoc();
1618        Parser.eatToEndOfStatement();
1619        return Error(Loc, "unexpected token in argument list");
1620      }
1621    }
1622  }
1623  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1624    SMLoc Loc = getLexer().getLoc();
1625    Parser.eatToEndOfStatement();
1626    return Error(Loc, "unexpected token in argument list");
1627  }
1628  Parser.Lex(); // Consume the EndOfStatement.
1629  return false;
1630}
1631
1632bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1633  SMLoc Loc = getLexer().getLoc();
1634  Parser.eatToEndOfStatement();
1635  return Error(Loc, ErrorMsg);
1636}
1637
1638bool MipsAsmParser::parseSetNoAtDirective() {
1639  // Line should look like: ".set noat".
1640  // set at reg to 0.
1641  Options.setATReg(0);
1642  // eat noat
1643  Parser.Lex();
1644  // If this is not the end of the statement, report an error.
1645  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1646    reportParseError("unexpected token in statement");
1647    return false;
1648  }
1649  Parser.Lex(); // Consume the EndOfStatement.
1650  return false;
1651}
1652
1653bool MipsAsmParser::parseSetAtDirective() {
1654  // Line can be .set at - defaults to $1
1655  // or .set at=$reg
1656  int AtRegNo;
1657  getParser().Lex();
1658  if (getLexer().is(AsmToken::EndOfStatement)) {
1659    Options.setATReg(1);
1660    Parser.Lex(); // Consume the EndOfStatement.
1661    return false;
1662  } else if (getLexer().is(AsmToken::Equal)) {
1663    getParser().Lex(); // Eat the '='.
1664    if (getLexer().isNot(AsmToken::Dollar)) {
1665      reportParseError("unexpected token in statement");
1666      return false;
1667    }
1668    Parser.Lex(); // Eat the '$'.
1669    const AsmToken &Reg = Parser.getTok();
1670    if (Reg.is(AsmToken::Identifier)) {
1671      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1672    } else if (Reg.is(AsmToken::Integer)) {
1673      AtRegNo = Reg.getIntVal();
1674    } else {
1675      reportParseError("unexpected token in statement");
1676      return false;
1677    }
1678
1679    if (AtRegNo < 1 || AtRegNo > 31) {
1680      reportParseError("unexpected token in statement");
1681      return false;
1682    }
1683
1684    if (!Options.setATReg(AtRegNo)) {
1685      reportParseError("unexpected token in statement");
1686      return false;
1687    }
1688    getParser().Lex(); // Eat the register.
1689
1690    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1691      reportParseError("unexpected token in statement");
1692      return false;
1693    }
1694    Parser.Lex(); // Consume the EndOfStatement.
1695    return false;
1696  } else {
1697    reportParseError("unexpected token in statement");
1698    return false;
1699  }
1700}
1701
1702bool MipsAsmParser::parseSetReorderDirective() {
1703  Parser.Lex();
1704  // If this is not the end of the statement, report an error.
1705  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1706    reportParseError("unexpected token in statement");
1707    return false;
1708  }
1709  Options.setReorder();
1710  Parser.Lex(); // Consume the EndOfStatement.
1711  return false;
1712}
1713
1714bool MipsAsmParser::parseSetNoReorderDirective() {
1715  Parser.Lex();
1716  // If this is not the end of the statement, report an error.
1717  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1718    reportParseError("unexpected token in statement");
1719    return false;
1720  }
1721  Options.setNoreorder();
1722  Parser.Lex(); // Consume the EndOfStatement.
1723  return false;
1724}
1725
1726bool MipsAsmParser::parseSetMacroDirective() {
1727  Parser.Lex();
1728  // If this is not the end of the statement, report an error.
1729  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1730    reportParseError("unexpected token in statement");
1731    return false;
1732  }
1733  Options.setMacro();
1734  Parser.Lex(); // Consume the EndOfStatement.
1735  return false;
1736}
1737
1738bool MipsAsmParser::parseSetNoMacroDirective() {
1739  Parser.Lex();
1740  // If this is not the end of the statement, report an error.
1741  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1742    reportParseError("`noreorder' must be set before `nomacro'");
1743    return false;
1744  }
1745  if (Options.isReorder()) {
1746    reportParseError("`noreorder' must be set before `nomacro'");
1747    return false;
1748  }
1749  Options.setNomacro();
1750  Parser.Lex(); // Consume the EndOfStatement.
1751  return false;
1752}
1753
1754bool MipsAsmParser::parseSetAssignment() {
1755  StringRef Name;
1756  const MCExpr *Value;
1757
1758  if (Parser.parseIdentifier(Name))
1759    reportParseError("expected identifier after .set");
1760
1761  if (getLexer().isNot(AsmToken::Comma))
1762    return reportParseError("unexpected token in .set directive");
1763  Lex(); // Eat comma
1764
1765  if (getLexer().is(AsmToken::Dollar)) {
1766    MCSymbol *Symbol;
1767    SMLoc DollarLoc = getLexer().getLoc();
1768    // Consume the dollar sign, and check for a following identifier.
1769    Parser.Lex();
1770    // We have a '$' followed by something, make sure they are adjacent.
1771    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1772      return true;
1773    StringRef Res = StringRef(DollarLoc.getPointer(),
1774        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1775    Symbol = getContext().GetOrCreateSymbol(Res);
1776    Parser.Lex();
1777    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1778                                    getContext());
1779  } else if (Parser.parseExpression(Value))
1780    return reportParseError("expected valid expression after comma");
1781
1782  // Check if the Name already exists as a symbol.
1783  MCSymbol *Sym = getContext().LookupSymbol(Name);
1784  if (Sym)
1785    return reportParseError("symbol already defined");
1786  Sym = getContext().GetOrCreateSymbol(Name);
1787  Sym->setVariableValue(Value);
1788
1789  return false;
1790}
1791
1792bool MipsAsmParser::parseDirectiveSet() {
1793
1794  // Get the next token.
1795  const AsmToken &Tok = Parser.getTok();
1796
1797  if (Tok.getString() == "noat") {
1798    return parseSetNoAtDirective();
1799  } else if (Tok.getString() == "at") {
1800    return parseSetAtDirective();
1801  } else if (Tok.getString() == "reorder") {
1802    return parseSetReorderDirective();
1803  } else if (Tok.getString() == "noreorder") {
1804    return parseSetNoReorderDirective();
1805  } else if (Tok.getString() == "macro") {
1806    return parseSetMacroDirective();
1807  } else if (Tok.getString() == "nomacro") {
1808    return parseSetNoMacroDirective();
1809  } else if (Tok.getString() == "nomips16") {
1810    // Ignore this directive for now.
1811    Parser.eatToEndOfStatement();
1812    return false;
1813  } else if (Tok.getString() == "nomicromips") {
1814    // Ignore this directive for now.
1815    Parser.eatToEndOfStatement();
1816    return false;
1817  } else {
1818    // It is just an identifier, look for an assignment.
1819    parseSetAssignment();
1820    return false;
1821  }
1822
1823  return true;
1824}
1825
1826/// parseDirectiveWord
1827///  ::= .word [ expression (, expression)* ]
1828bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1829  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1830    for (;;) {
1831      const MCExpr *Value;
1832      if (getParser().parseExpression(Value))
1833        return true;
1834
1835      getParser().getStreamer().EmitValue(Value, Size);
1836
1837      if (getLexer().is(AsmToken::EndOfStatement))
1838        break;
1839
1840      // FIXME: Improve diagnostic.
1841      if (getLexer().isNot(AsmToken::Comma))
1842        return Error(L, "unexpected token in directive");
1843      Parser.Lex();
1844    }
1845  }
1846
1847  Parser.Lex();
1848  return false;
1849}
1850
1851bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1852
1853  StringRef IDVal = DirectiveID.getString();
1854
1855  if (IDVal == ".ent") {
1856    // Ignore this directive for now.
1857    Parser.Lex();
1858    return false;
1859  }
1860
1861  if (IDVal == ".end") {
1862    // Ignore this directive for now.
1863    Parser.Lex();
1864    return false;
1865  }
1866
1867  if (IDVal == ".frame") {
1868    // Ignore this directive for now.
1869    Parser.eatToEndOfStatement();
1870    return false;
1871  }
1872
1873  if (IDVal == ".set") {
1874    return parseDirectiveSet();
1875  }
1876
1877  if (IDVal == ".fmask") {
1878    // Ignore this directive for now.
1879    Parser.eatToEndOfStatement();
1880    return false;
1881  }
1882
1883  if (IDVal == ".mask") {
1884    // Ignore this directive for now.
1885    Parser.eatToEndOfStatement();
1886    return false;
1887  }
1888
1889  if (IDVal == ".gpword") {
1890    // Ignore this directive for now.
1891    Parser.eatToEndOfStatement();
1892    return false;
1893  }
1894
1895  if (IDVal == ".word") {
1896    parseDirectiveWord(4, DirectiveID.getLoc());
1897    return false;
1898  }
1899
1900  return true;
1901}
1902
1903extern "C" void LLVMInitializeMipsAsmParser() {
1904  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1905  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1906  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1907  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1908}
1909
1910#define GET_REGISTER_MATCHER
1911#define GET_MATCHER_IMPLEMENTATION
1912#include "MipsGenAsmMatcher.inc"
1913