LLVM API Documentation

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