LLVM  3.7.0
SparcAsmParser.cpp
Go to the documentation of this file.
1 //===-- SparcAsmParser.cpp - Parse Sparc 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 
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSymbol.h"
22 
23 using namespace llvm;
24 
25 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
26 // namespace. But SPARC backend uses "SP" as its namespace.
27 namespace llvm {
28  namespace Sparc {
29  using namespace SP;
30  }
31 }
32 
33 namespace {
34 class SparcOperand;
35 class SparcAsmParser : public MCTargetAsmParser {
36 
37  MCSubtargetInfo &STI;
38  MCAsmParser &Parser;
39 
40  /// @name Auto-generated Match Functions
41  /// {
42 
43 #define GET_ASSEMBLER_HEADER
44 #include "SparcGenAsmMatcher.inc"
45 
46  /// }
47 
48  // public interface of the MCTargetAsmParser.
49  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
51  uint64_t &ErrorInfo,
52  bool MatchingInlineAsm) override;
53  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
54  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
55  SMLoc NameLoc, OperandVector &Operands) override;
56  bool ParseDirective(AsmToken DirectiveID) override;
57 
58  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
59  unsigned Kind) override;
60 
61  // Custom parse functions for Sparc specific operands.
62  OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
63 
64  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
65 
66  OperandMatchResultTy
67  parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
68  bool isCall = false);
69 
70  OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
71 
72  // returns true if Tok is matched to a register and returns register in RegNo.
73  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
74  unsigned &RegKind);
75 
76  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
77  bool parseDirectiveWord(unsigned Size, SMLoc L);
78 
79  bool is64Bit() const {
80  return STI.getTargetTriple().getArchName().startswith("sparcv9");
81  }
82 
83  void expandSET(MCInst &Inst, SMLoc IDLoc,
84  SmallVectorImpl<MCInst> &Instructions);
85 
86 public:
87  SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
88  const MCInstrInfo &MII,
89  const MCTargetOptions &Options)
90  : MCTargetAsmParser(), STI(sti), Parser(parser) {
91  // Initialize the set of available features.
92  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
93  }
94 
95 };
96 
97  static unsigned IntRegs[32] = {
98  Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
99  Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
100  Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
101  Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
102  Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
103  Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
104  Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
105  Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
106 
107  static unsigned FloatRegs[32] = {
108  Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
109  Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
110  Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
111  Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
112  Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
113  Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
114  Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
115  Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
116 
117  static unsigned DoubleRegs[32] = {
118  Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
119  Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
120  Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
121  Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
122  Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
123  Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
124  Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
125  Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
126 
127  static unsigned QuadFPRegs[32] = {
128  Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
129  Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
130  Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
131  Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
132 
133  static unsigned ASRRegs[32] = {
134  SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
135  SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
136  SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
137  SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
138  SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
139  SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
140  SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
141  SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
142 
143 /// SparcOperand - Instances of this class represent a parsed Sparc machine
144 /// instruction.
145 class SparcOperand : public MCParsedAsmOperand {
146 public:
147  enum RegisterKind {
148  rk_None,
149  rk_IntReg,
150  rk_FloatReg,
151  rk_DoubleReg,
152  rk_QuadReg,
153  rk_Special,
154  };
155 
156 private:
157  enum KindTy {
158  k_Token,
159  k_Register,
160  k_Immediate,
161  k_MemoryReg,
162  k_MemoryImm
163  } Kind;
164 
165  SMLoc StartLoc, EndLoc;
166 
167  struct Token {
168  const char *Data;
169  unsigned Length;
170  };
171 
172  struct RegOp {
173  unsigned RegNum;
175  };
176 
177  struct ImmOp {
178  const MCExpr *Val;
179  };
180 
181  struct MemOp {
182  unsigned Base;
183  unsigned OffsetReg;
184  const MCExpr *Off;
185  };
186 
187  union {
188  struct Token Tok;
189  struct RegOp Reg;
190  struct ImmOp Imm;
191  struct MemOp Mem;
192  };
193 public:
194  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
195 
196  bool isToken() const override { return Kind == k_Token; }
197  bool isReg() const override { return Kind == k_Register; }
198  bool isImm() const override { return Kind == k_Immediate; }
199  bool isMem() const override { return isMEMrr() || isMEMri(); }
200  bool isMEMrr() const { return Kind == k_MemoryReg; }
201  bool isMEMri() const { return Kind == k_MemoryImm; }
202 
203  bool isFloatReg() const {
204  return (Kind == k_Register && Reg.Kind == rk_FloatReg);
205  }
206 
207  bool isFloatOrDoubleReg() const {
208  return (Kind == k_Register && (Reg.Kind == rk_FloatReg
209  || Reg.Kind == rk_DoubleReg));
210  }
211 
212 
213  StringRef getToken() const {
214  assert(Kind == k_Token && "Invalid access!");
215  return StringRef(Tok.Data, Tok.Length);
216  }
217 
218  unsigned getReg() const override {
219  assert((Kind == k_Register) && "Invalid access!");
220  return Reg.RegNum;
221  }
222 
223  const MCExpr *getImm() const {
224  assert((Kind == k_Immediate) && "Invalid access!");
225  return Imm.Val;
226  }
227 
228  unsigned getMemBase() const {
229  assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
230  return Mem.Base;
231  }
232 
233  unsigned getMemOffsetReg() const {
234  assert((Kind == k_MemoryReg) && "Invalid access!");
235  return Mem.OffsetReg;
236  }
237 
238  const MCExpr *getMemOff() const {
239  assert((Kind == k_MemoryImm) && "Invalid access!");
240  return Mem.Off;
241  }
242 
243  /// getStartLoc - Get the location of the first token of this operand.
244  SMLoc getStartLoc() const override {
245  return StartLoc;
246  }
247  /// getEndLoc - Get the location of the last token of this operand.
248  SMLoc getEndLoc() const override {
249  return EndLoc;
250  }
251 
252  void print(raw_ostream &OS) const override {
253  switch (Kind) {
254  case k_Token: OS << "Token: " << getToken() << "\n"; break;
255  case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
256  case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
257  case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
258  << getMemOffsetReg() << "\n"; break;
259  case k_MemoryImm: assert(getMemOff() != nullptr);
260  OS << "Mem: " << getMemBase()
261  << "+" << *getMemOff()
262  << "\n"; break;
263  }
264  }
265 
266  void addRegOperands(MCInst &Inst, unsigned N) const {
267  assert(N == 1 && "Invalid number of operands!");
269  }
270 
271  void addImmOperands(MCInst &Inst, unsigned N) const {
272  assert(N == 1 && "Invalid number of operands!");
273  const MCExpr *Expr = getImm();
274  addExpr(Inst, Expr);
275  }
276 
277  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
278  // Add as immediate when possible. Null MCExpr = 0.
279  if (!Expr)
281  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
282  Inst.addOperand(MCOperand::createImm(CE->getValue()));
283  else
284  Inst.addOperand(MCOperand::createExpr(Expr));
285  }
286 
287  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
288  assert(N == 2 && "Invalid number of operands!");
289 
290  Inst.addOperand(MCOperand::createReg(getMemBase()));
291 
292  assert(getMemOffsetReg() != 0 && "Invalid offset");
293  Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
294  }
295 
296  void addMEMriOperands(MCInst &Inst, unsigned N) const {
297  assert(N == 2 && "Invalid number of operands!");
298 
299  Inst.addOperand(MCOperand::createReg(getMemBase()));
300 
301  const MCExpr *Expr = getMemOff();
302  addExpr(Inst, Expr);
303  }
304 
305  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
306  auto Op = make_unique<SparcOperand>(k_Token);
307  Op->Tok.Data = Str.data();
308  Op->Tok.Length = Str.size();
309  Op->StartLoc = S;
310  Op->EndLoc = S;
311  return Op;
312  }
313 
314  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
315  SMLoc S, SMLoc E) {
316  auto Op = make_unique<SparcOperand>(k_Register);
317  Op->Reg.RegNum = RegNum;
318  Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
319  Op->StartLoc = S;
320  Op->EndLoc = E;
321  return Op;
322  }
323 
324  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
325  SMLoc E) {
326  auto Op = make_unique<SparcOperand>(k_Immediate);
327  Op->Imm.Val = Val;
328  Op->StartLoc = S;
329  Op->EndLoc = E;
330  return Op;
331  }
332 
333  static bool MorphToDoubleReg(SparcOperand &Op) {
334  unsigned Reg = Op.getReg();
335  assert(Op.Reg.Kind == rk_FloatReg);
336  unsigned regIdx = Reg - Sparc::F0;
337  if (regIdx % 2 || regIdx > 31)
338  return false;
339  Op.Reg.RegNum = DoubleRegs[regIdx / 2];
340  Op.Reg.Kind = rk_DoubleReg;
341  return true;
342  }
343 
344  static bool MorphToQuadReg(SparcOperand &Op) {
345  unsigned Reg = Op.getReg();
346  unsigned regIdx = 0;
347  switch (Op.Reg.Kind) {
348  default: llvm_unreachable("Unexpected register kind!");
349  case rk_FloatReg:
350  regIdx = Reg - Sparc::F0;
351  if (regIdx % 4 || regIdx > 31)
352  return false;
353  Reg = QuadFPRegs[regIdx / 4];
354  break;
355  case rk_DoubleReg:
356  regIdx = Reg - Sparc::D0;
357  if (regIdx % 2 || regIdx > 31)
358  return false;
359  Reg = QuadFPRegs[regIdx / 2];
360  break;
361  }
362  Op.Reg.RegNum = Reg;
363  Op.Reg.Kind = rk_QuadReg;
364  return true;
365  }
366 
367  static std::unique_ptr<SparcOperand>
368  MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
369  unsigned offsetReg = Op->getReg();
370  Op->Kind = k_MemoryReg;
371  Op->Mem.Base = Base;
372  Op->Mem.OffsetReg = offsetReg;
373  Op->Mem.Off = nullptr;
374  return Op;
375  }
376 
377  static std::unique_ptr<SparcOperand>
378  CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
379  auto Op = make_unique<SparcOperand>(k_MemoryReg);
380  Op->Mem.Base = Base;
381  Op->Mem.OffsetReg = Sparc::G0; // always 0
382  Op->Mem.Off = nullptr;
383  Op->StartLoc = S;
384  Op->EndLoc = E;
385  return Op;
386  }
387 
388  static std::unique_ptr<SparcOperand>
389  MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
390  const MCExpr *Imm = Op->getImm();
391  Op->Kind = k_MemoryImm;
392  Op->Mem.Base = Base;
393  Op->Mem.OffsetReg = 0;
394  Op->Mem.Off = Imm;
395  return Op;
396  }
397 };
398 
399 } // end namespace
400 
401 void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
402  SmallVectorImpl<MCInst> &Instructions) {
403  MCOperand MCRegOp = Inst.getOperand(0);
404  MCOperand MCValOp = Inst.getOperand(1);
405  assert(MCRegOp.isReg());
406  assert(MCValOp.isImm() || MCValOp.isExpr());
407 
408  // the imm operand can be either an expression or an immediate.
409  bool IsImm = Inst.getOperand(1).isImm();
410  uint64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
411  const MCExpr *ValExpr;
412  if (IsImm)
413  ValExpr = MCConstantExpr::create(ImmValue, getContext());
414  else
415  ValExpr = MCValOp.getExpr();
416 
417  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
418 
419  if (!IsImm || (ImmValue & ~0x1fff)) {
420  MCInst TmpInst;
421  const MCExpr *Expr =
422  SparcMCExpr::create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext());
423  TmpInst.setLoc(IDLoc);
424  TmpInst.setOpcode(SP::SETHIi);
425  TmpInst.addOperand(MCRegOp);
426  TmpInst.addOperand(MCOperand::createExpr(Expr));
427  Instructions.push_back(TmpInst);
428  PrevReg = MCRegOp;
429  }
430 
431  if (!IsImm || ((ImmValue & 0x1fff) != 0 || ImmValue == 0)) {
432  MCInst TmpInst;
433  const MCExpr *Expr =
434  SparcMCExpr::create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext());
435  TmpInst.setLoc(IDLoc);
436  TmpInst.setOpcode(SP::ORri);
437  TmpInst.addOperand(MCRegOp);
438  TmpInst.addOperand(PrevReg);
439  TmpInst.addOperand(MCOperand::createExpr(Expr));
440  Instructions.push_back(TmpInst);
441  }
442 }
443 
444 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
446  MCStreamer &Out,
447  uint64_t &ErrorInfo,
448  bool MatchingInlineAsm) {
449  MCInst Inst;
450  SmallVector<MCInst, 8> Instructions;
451  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
452  MatchingInlineAsm);
453  switch (MatchResult) {
454  case Match_Success: {
455  switch (Inst.getOpcode()) {
456  default:
457  Inst.setLoc(IDLoc);
458  Instructions.push_back(Inst);
459  break;
460  case SP::SET:
461  expandSET(Inst, IDLoc, Instructions);
462  break;
463  }
464 
465  for (const MCInst &I : Instructions) {
466  Out.EmitInstruction(I, STI);
467  }
468  return false;
469  }
470 
471  case Match_MissingFeature:
472  return Error(IDLoc,
473  "instruction requires a CPU feature not currently enabled");
474 
475  case Match_InvalidOperand: {
476  SMLoc ErrorLoc = IDLoc;
477  if (ErrorInfo != ~0ULL) {
478  if (ErrorInfo >= Operands.size())
479  return Error(IDLoc, "too few operands for instruction");
480 
481  ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
482  if (ErrorLoc == SMLoc())
483  ErrorLoc = IDLoc;
484  }
485 
486  return Error(ErrorLoc, "invalid operand for instruction");
487  }
488  case Match_MnemonicFail:
489  return Error(IDLoc, "invalid instruction mnemonic");
490  }
491  llvm_unreachable("Implement any new match types added!");
492 }
493 
494 bool SparcAsmParser::
495 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
496 {
497  const AsmToken &Tok = Parser.getTok();
498  StartLoc = Tok.getLoc();
499  EndLoc = Tok.getEndLoc();
500  RegNo = 0;
501  if (getLexer().getKind() != AsmToken::Percent)
502  return false;
503  Parser.Lex();
504  unsigned regKind = SparcOperand::rk_None;
505  if (matchRegisterName(Tok, RegNo, regKind)) {
506  Parser.Lex();
507  return false;
508  }
509 
510  return Error(StartLoc, "invalid register name");
511 }
512 
513 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
514  unsigned VariantID);
515 
516 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
517  StringRef Name, SMLoc NameLoc,
518  OperandVector &Operands) {
519 
520  // First operand in MCInst is instruction mnemonic.
521  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
522 
523  // apply mnemonic aliases, if any, so that we can parse operands correctly.
524  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
525 
526  if (getLexer().isNot(AsmToken::EndOfStatement)) {
527  // Read the first operand.
528  if (getLexer().is(AsmToken::Comma)) {
529  if (parseBranchModifiers(Operands) != MatchOperand_Success) {
530  SMLoc Loc = getLexer().getLoc();
531  Parser.eatToEndOfStatement();
532  return Error(Loc, "unexpected token");
533  }
534  }
535  if (parseOperand(Operands, Name) != MatchOperand_Success) {
536  SMLoc Loc = getLexer().getLoc();
537  Parser.eatToEndOfStatement();
538  return Error(Loc, "unexpected token");
539  }
540 
541  while (getLexer().is(AsmToken::Comma)) {
542  Parser.Lex(); // Eat the comma.
543  // Parse and remember the operand.
544  if (parseOperand(Operands, Name) != MatchOperand_Success) {
545  SMLoc Loc = getLexer().getLoc();
546  Parser.eatToEndOfStatement();
547  return Error(Loc, "unexpected token");
548  }
549  }
550  }
551  if (getLexer().isNot(AsmToken::EndOfStatement)) {
552  SMLoc Loc = getLexer().getLoc();
553  Parser.eatToEndOfStatement();
554  return Error(Loc, "unexpected token");
555  }
556  Parser.Lex(); // Consume the EndOfStatement.
557  return false;
558 }
559 
560 bool SparcAsmParser::
561 ParseDirective(AsmToken DirectiveID)
562 {
563  StringRef IDVal = DirectiveID.getString();
564 
565  if (IDVal == ".byte")
566  return parseDirectiveWord(1, DirectiveID.getLoc());
567 
568  if (IDVal == ".half")
569  return parseDirectiveWord(2, DirectiveID.getLoc());
570 
571  if (IDVal == ".word")
572  return parseDirectiveWord(4, DirectiveID.getLoc());
573 
574  if (IDVal == ".nword")
575  return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
576 
577  if (is64Bit() && IDVal == ".xword")
578  return parseDirectiveWord(8, DirectiveID.getLoc());
579 
580  if (IDVal == ".register") {
581  // For now, ignore .register directive.
582  Parser.eatToEndOfStatement();
583  return false;
584  }
585 
586  // Let the MC layer to handle other directives.
587  return true;
588 }
589 
590 bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
591  if (getLexer().isNot(AsmToken::EndOfStatement)) {
592  for (;;) {
593  const MCExpr *Value;
594  if (getParser().parseExpression(Value))
595  return true;
596 
597  getParser().getStreamer().EmitValue(Value, Size);
598 
599  if (getLexer().is(AsmToken::EndOfStatement))
600  break;
601 
602  // FIXME: Improve diagnostic.
603  if (getLexer().isNot(AsmToken::Comma))
604  return Error(L, "unexpected token in directive");
605  Parser.Lex();
606  }
607  }
608  Parser.Lex();
609  return false;
610 }
611 
612 SparcAsmParser::OperandMatchResultTy
613 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
614 
615  SMLoc S, E;
616  unsigned BaseReg = 0;
617 
618  if (ParseRegister(BaseReg, S, E)) {
619  return MatchOperand_NoMatch;
620  }
621 
622  switch (getLexer().getKind()) {
623  default: return MatchOperand_NoMatch;
624 
625  case AsmToken::Comma:
626  case AsmToken::RBrac:
628  Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
629  return MatchOperand_Success;
630 
631  case AsmToken:: Plus:
632  Parser.Lex(); // Eat the '+'
633  break;
634  case AsmToken::Minus:
635  break;
636  }
637 
638  std::unique_ptr<SparcOperand> Offset;
639  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
640  if (ResTy != MatchOperand_Success || !Offset)
641  return MatchOperand_NoMatch;
642 
643  Operands.push_back(
644  Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
645  : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
646 
647  return MatchOperand_Success;
648 }
649 
650 SparcAsmParser::OperandMatchResultTy
651 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
652 
653  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
654 
655  // If there wasn't a custom match, try the generic matcher below. Otherwise,
656  // there was a match, but an error occurred, in which case, just return that
657  // the operand parsing failed.
658  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
659  return ResTy;
660 
661  if (getLexer().is(AsmToken::LBrac)) {
662  // Memory operand
663  Operands.push_back(SparcOperand::CreateToken("[",
664  Parser.getTok().getLoc()));
665  Parser.Lex(); // Eat the [
666 
667  if (Mnemonic == "cas" || Mnemonic == "casx") {
668  SMLoc S = Parser.getTok().getLoc();
669  if (getLexer().getKind() != AsmToken::Percent)
670  return MatchOperand_NoMatch;
671  Parser.Lex(); // eat %
672 
673  unsigned RegNo, RegKind;
674  if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
675  return MatchOperand_NoMatch;
676 
677  Parser.Lex(); // Eat the identifier token.
678  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
679  Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
680  ResTy = MatchOperand_Success;
681  } else {
682  ResTy = parseMEMOperand(Operands);
683  }
684 
685  if (ResTy != MatchOperand_Success)
686  return ResTy;
687 
688  if (!getLexer().is(AsmToken::RBrac))
689  return MatchOperand_ParseFail;
690 
691  Operands.push_back(SparcOperand::CreateToken("]",
692  Parser.getTok().getLoc()));
693  Parser.Lex(); // Eat the ]
694 
695  // Parse an optional address-space identifier after the address.
696  if (getLexer().is(AsmToken::Integer)) {
697  std::unique_ptr<SparcOperand> Op;
698  ResTy = parseSparcAsmOperand(Op, false);
699  if (ResTy != MatchOperand_Success || !Op)
700  return MatchOperand_ParseFail;
701  Operands.push_back(std::move(Op));
702  }
703  return MatchOperand_Success;
704  }
705 
706  std::unique_ptr<SparcOperand> Op;
707 
708  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
709  if (ResTy != MatchOperand_Success || !Op)
710  return MatchOperand_ParseFail;
711 
712  // Push the parsed operand into the list of operands
713  Operands.push_back(std::move(Op));
714 
715  return MatchOperand_Success;
716 }
717 
718 SparcAsmParser::OperandMatchResultTy
719 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
720  bool isCall) {
721 
722  SMLoc S = Parser.getTok().getLoc();
723  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
724  const MCExpr *EVal;
725 
726  Op = nullptr;
727  switch (getLexer().getKind()) {
728  default: break;
729 
730  case AsmToken::Percent:
731  Parser.Lex(); // Eat the '%'.
732  unsigned RegNo;
733  unsigned RegKind;
734  if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
735  StringRef name = Parser.getTok().getString();
736  Parser.Lex(); // Eat the identifier token.
737  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
738  switch (RegNo) {
739  default:
740  Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
741  break;
742  case Sparc::PSR:
743  Op = SparcOperand::CreateToken("%psr", S);
744  break;
745  case Sparc::WIM:
746  Op = SparcOperand::CreateToken("%wim", S);
747  break;
748  case Sparc::TBR:
749  Op = SparcOperand::CreateToken("%tbr", S);
750  break;
751  case Sparc::ICC:
752  if (name == "xcc")
753  Op = SparcOperand::CreateToken("%xcc", S);
754  else
755  Op = SparcOperand::CreateToken("%icc", S);
756  break;
757  }
758  break;
759  }
760  if (matchSparcAsmModifiers(EVal, E)) {
761  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
762  Op = SparcOperand::CreateImm(EVal, S, E);
763  }
764  break;
765 
766  case AsmToken::Minus:
767  case AsmToken::Integer:
768  case AsmToken::LParen:
769  if (!getParser().parseExpression(EVal, E))
770  Op = SparcOperand::CreateImm(EVal, S, E);
771  break;
772 
773  case AsmToken::Identifier: {
774  StringRef Identifier;
775  if (!getParser().parseIdentifier(Identifier)) {
776  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
777  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
778 
780  getContext());
781  if (isCall &&
782  getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
784  getContext());
785  Op = SparcOperand::CreateImm(Res, S, E);
786  }
787  break;
788  }
789  }
790  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
791 }
792 
793 SparcAsmParser::OperandMatchResultTy
794 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
795 
796  // parse (,a|,pn|,pt)+
797 
798  while (getLexer().is(AsmToken::Comma)) {
799 
800  Parser.Lex(); // Eat the comma
801 
802  if (!getLexer().is(AsmToken::Identifier))
803  return MatchOperand_ParseFail;
804  StringRef modName = Parser.getTok().getString();
805  if (modName == "a" || modName == "pn" || modName == "pt") {
806  Operands.push_back(SparcOperand::CreateToken(modName,
807  Parser.getTok().getLoc()));
808  Parser.Lex(); // eat the identifier.
809  }
810  }
811  return MatchOperand_Success;
812 }
813 
814 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
815  unsigned &RegNo,
816  unsigned &RegKind)
817 {
818  int64_t intVal = 0;
819  RegNo = 0;
820  RegKind = SparcOperand::rk_None;
821  if (Tok.is(AsmToken::Identifier)) {
822  StringRef name = Tok.getString();
823 
824  // %fp
825  if (name.equals("fp")) {
826  RegNo = Sparc::I6;
827  RegKind = SparcOperand::rk_IntReg;
828  return true;
829  }
830  // %sp
831  if (name.equals("sp")) {
832  RegNo = Sparc::O6;
833  RegKind = SparcOperand::rk_IntReg;
834  return true;
835  }
836 
837  if (name.equals("y")) {
838  RegNo = Sparc::Y;
839  RegKind = SparcOperand::rk_Special;
840  return true;
841  }
842 
843  if (name.substr(0, 3).equals_lower("asr")
844  && !name.substr(3).getAsInteger(10, intVal)
845  && intVal > 0 && intVal < 32) {
846  RegNo = ASRRegs[intVal];
847  RegKind = SparcOperand::rk_Special;
848  return true;
849  }
850 
851  if (name.equals("icc")) {
852  RegNo = Sparc::ICC;
853  RegKind = SparcOperand::rk_Special;
854  return true;
855  }
856 
857  if (name.equals("psr")) {
858  RegNo = Sparc::PSR;
859  RegKind = SparcOperand::rk_Special;
860  return true;
861  }
862 
863  if (name.equals("wim")) {
864  RegNo = Sparc::WIM;
865  RegKind = SparcOperand::rk_Special;
866  return true;
867  }
868 
869  if (name.equals("tbr")) {
870  RegNo = Sparc::TBR;
871  RegKind = SparcOperand::rk_Special;
872  return true;
873  }
874 
875  if (name.equals("xcc")) {
876  // FIXME:: check 64bit.
877  RegNo = Sparc::ICC;
878  RegKind = SparcOperand::rk_Special;
879  return true;
880  }
881 
882  // %fcc0 - %fcc3
883  if (name.substr(0, 3).equals_lower("fcc")
884  && !name.substr(3).getAsInteger(10, intVal)
885  && intVal < 4) {
886  // FIXME: check 64bit and handle %fcc1 - %fcc3
887  RegNo = Sparc::FCC0 + intVal;
888  RegKind = SparcOperand::rk_Special;
889  return true;
890  }
891 
892  // %g0 - %g7
893  if (name.substr(0, 1).equals_lower("g")
894  && !name.substr(1).getAsInteger(10, intVal)
895  && intVal < 8) {
896  RegNo = IntRegs[intVal];
897  RegKind = SparcOperand::rk_IntReg;
898  return true;
899  }
900  // %o0 - %o7
901  if (name.substr(0, 1).equals_lower("o")
902  && !name.substr(1).getAsInteger(10, intVal)
903  && intVal < 8) {
904  RegNo = IntRegs[8 + intVal];
905  RegKind = SparcOperand::rk_IntReg;
906  return true;
907  }
908  if (name.substr(0, 1).equals_lower("l")
909  && !name.substr(1).getAsInteger(10, intVal)
910  && intVal < 8) {
911  RegNo = IntRegs[16 + intVal];
912  RegKind = SparcOperand::rk_IntReg;
913  return true;
914  }
915  if (name.substr(0, 1).equals_lower("i")
916  && !name.substr(1).getAsInteger(10, intVal)
917  && intVal < 8) {
918  RegNo = IntRegs[24 + intVal];
919  RegKind = SparcOperand::rk_IntReg;
920  return true;
921  }
922  // %f0 - %f31
923  if (name.substr(0, 1).equals_lower("f")
924  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
925  RegNo = FloatRegs[intVal];
926  RegKind = SparcOperand::rk_FloatReg;
927  return true;
928  }
929  // %f32 - %f62
930  if (name.substr(0, 1).equals_lower("f")
931  && !name.substr(1, 2).getAsInteger(10, intVal)
932  && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
933  // FIXME: Check V9
934  RegNo = DoubleRegs[intVal/2];
935  RegKind = SparcOperand::rk_DoubleReg;
936  return true;
937  }
938 
939  // %r0 - %r31
940  if (name.substr(0, 1).equals_lower("r")
941  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
942  RegNo = IntRegs[intVal];
943  RegKind = SparcOperand::rk_IntReg;
944  return true;
945  }
946  }
947  return false;
948 }
949 
950 // Determine if an expression contains a reference to the symbol
951 // "_GLOBAL_OFFSET_TABLE_".
952 static bool hasGOTReference(const MCExpr *Expr) {
953  switch (Expr->getKind()) {
954  case MCExpr::Target:
955  if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
956  return hasGOTReference(SE->getSubExpr());
957  break;
958 
959  case MCExpr::Constant:
960  break;
961 
962  case MCExpr::Binary: {
963  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
964  return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
965  }
966 
967  case MCExpr::SymbolRef: {
968  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
969  return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
970  }
971 
972  case MCExpr::Unary:
973  return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
974  }
975  return false;
976 }
977 
978 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
979  SMLoc &EndLoc)
980 {
981  AsmToken Tok = Parser.getTok();
982  if (!Tok.is(AsmToken::Identifier))
983  return false;
984 
985  StringRef name = Tok.getString();
986 
988 
989  if (VK == SparcMCExpr::VK_Sparc_None)
990  return false;
991 
992  Parser.Lex(); // Eat the identifier.
993  if (Parser.getTok().getKind() != AsmToken::LParen)
994  return false;
995 
996  Parser.Lex(); // Eat the LParen token.
997  const MCExpr *subExpr;
998  if (Parser.parseParenExpression(subExpr, EndLoc))
999  return false;
1000 
1001  bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
1002 
1003  // Ugly: if a sparc assembly expression says "%hi(...)" but the
1004  // expression within contains _GLOBAL_OFFSET_TABLE_, it REALLY means
1005  // %pc22. Same with %lo -> %pc10. Worse, if it doesn't contain that,
1006  // the meaning depends on whether the assembler was invoked with
1007  // -KPIC or not: if so, it really means %got22/%got10; if not, it
1008  // actually means what it said! Sigh, historical mistakes...
1009 
1010  switch(VK) {
1011  default: break;
1013  VK = (hasGOTReference(subExpr)
1015  : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
1016  break;
1018  VK = (hasGOTReference(subExpr)
1020  : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
1021  break;
1022  }
1023 
1024  EVal = SparcMCExpr::create(VK, subExpr, getContext());
1025  return true;
1026 }
1027 
1028 extern "C" void LLVMInitializeSparcAsmParser() {
1032 }
1033 
1034 #define GET_REGISTER_MATCHER
1035 #define GET_MATCHER_IMPLEMENTATION
1036 #include "SparcGenAsmMatcher.inc"
1037 
1038 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1039  unsigned Kind) {
1040  SparcOperand &Op = (SparcOperand &)GOp;
1041  if (Op.isFloatOrDoubleReg()) {
1042  switch (Kind) {
1043  default: break;
1044  case MCK_DFPRegs:
1045  if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1047  break;
1048  case MCK_QFPRegs:
1049  if (SparcOperand::MorphToQuadReg(Op))
1051  break;
1052  }
1053  }
1054  return Match_InvalidOperand;
1055 }
static bool isReg(const MCInst &MI, unsigned OpNo)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:347
const MCSymbol & getSymbol() const
Definition: MCExpr.h:328
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
bool isReg() const
Definition: MCInst.h:56
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:64
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
MCTargetAsmParser - Generic interface to target specific assembly parsers.
ExprKind getKind() const
Definition: MCExpr.h:69
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmLexer.h:100
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:639
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, unsigned VariantID)
Target TheSparcTarget
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Definition: MCAsmLexer.h:22
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
Windows NT (Windows on ARM)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:107
Unary expressions.
Definition: MCExpr.h:39
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
void LLVMInitializeSparcAsmParser()
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:531
Streaming machine code generation interface.
Definition: MCStreamer.h:157
#define SET(n)
Definition: MD5.cpp:64
static bool is64Bit(const char *name)
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
bool isExpr() const
Definition: MCInst.h:59
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:86
SI Fold Operands
static bool hasGOTReference(const MCExpr *Expr)
Binary assembler expressions.
Definition: MCExpr.h:405
void setLoc(SMLoc loc)
Definition: MCInst.h:161
void setOpcode(unsigned Op)
Definition: MCInst.h:158
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
bool is(TokenKind K) const
Definition: MCAsmLexer.h:72
unsigned getOpcode() const
Definition: MCInst.h:159
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Target TheSparcV9Target
int64_t getImm() const
Definition: MCInst.h:74
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:136
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:35
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:534
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:142
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
MCSubtargetInfo - Generic base class for all target subtargets.
References to labels and assigned expressions.
Definition: MCExpr.h:38
static bool isMem(const MachineInstr *MI, unsigned Op)
Definition: X86InstrInfo.h:147
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:28
const ARM::ArchExtKind Kind
Target TheSparcelTarget
LLVM Value Representation.
Definition: Value.h:69
RegisterKind
static const char * name
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
Constant expressions.
Definition: MCExpr.h:37
Binary expressions.
Definition: MCExpr.h:36
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
C - The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Target specific expression.
Definition: MCExpr.h:40
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
Definition: SMLoc.h:23
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:150
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164