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