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