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