LLVM  7.0.0svn
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/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/SMLoc.h"
33 #include <algorithm>
34 #include <cassert>
35 #include <cstdint>
36 #include <memory>
37 
38 using namespace llvm;
39 
40 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
41 // namespace. But SPARC backend uses "SP" as its namespace.
42 namespace llvm {
43 namespace Sparc {
44 
45  using namespace SP;
46 
47 } // end namespace Sparc
48 } // end namespace llvm
49 
50 namespace {
51 
52 class SparcOperand;
53 
54 class SparcAsmParser : public MCTargetAsmParser {
55  MCAsmParser &Parser;
56 
57  /// @name Auto-generated Match Functions
58  /// {
59 
60 #define GET_ASSEMBLER_HEADER
61 #include "SparcGenAsmMatcher.inc"
62 
63  /// }
64 
65  // public interface of the MCTargetAsmParser.
66  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
67  OperandVector &Operands, MCStreamer &Out,
68  uint64_t &ErrorInfo,
69  bool MatchingInlineAsm) override;
70  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
71  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
72  SMLoc NameLoc, OperandVector &Operands) override;
73  bool ParseDirective(AsmToken DirectiveID) override;
74 
75  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
76  unsigned Kind) override;
77 
78  // Custom parse functions for Sparc specific operands.
79  OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
80 
81  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
82 
84  parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
85  bool isCall = false);
86 
87  OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
88 
89  // Helper function for dealing with %lo / %hi in PIC mode.
90  const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
91  const MCExpr *subExpr);
92 
93  // returns true if Tok is matched to a register and returns register in RegNo.
94  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
95  unsigned &RegKind);
96 
97  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
98 
99  bool is64Bit() const {
100  return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
101  }
102 
103  bool expandSET(MCInst &Inst, SMLoc IDLoc,
104  SmallVectorImpl<MCInst> &Instructions);
105 
106 public:
107  SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
108  const MCInstrInfo &MII,
109  const MCTargetOptions &Options)
110  : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
111  Parser.addAliasForDirective(".half", ".2byte");
112  Parser.addAliasForDirective(".uahalf", ".2byte");
113  Parser.addAliasForDirective(".word", ".4byte");
114  Parser.addAliasForDirective(".uaword", ".4byte");
115  Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
116  if (is64Bit())
117  Parser.addAliasForDirective(".xword", ".8byte");
118 
119  // Initialize the set of available features.
120  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
121  }
122 };
123 
124 } // end anonymous namespace
125 
126  static const MCPhysReg IntRegs[32] = {
127  Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
128  Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
129  Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
130  Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
131  Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
132  Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
133  Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
134  Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
135 
136  static const MCPhysReg FloatRegs[32] = {
137  Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
138  Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
139  Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
140  Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
141  Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
142  Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
143  Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
144  Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
145 
146  static const MCPhysReg DoubleRegs[32] = {
147  Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
148  Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
149  Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
150  Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
151  Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
152  Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
153  Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
154  Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
155 
156  static const MCPhysReg QuadFPRegs[32] = {
157  Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
158  Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
159  Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
160  Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
161 
162  static const MCPhysReg ASRRegs[32] = {
163  SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
164  SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
165  SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
166  SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
167  SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
168  SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
169  SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
170  SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
171 
172  static const MCPhysReg IntPairRegs[] = {
173  Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
174  Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
175  Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
176  Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
177 
178  static const MCPhysReg CoprocRegs[32] = {
179  Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
180  Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
181  Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
182  Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
183  Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
184  Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
185  Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
186  Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
187 
188  static const MCPhysReg CoprocPairRegs[] = {
189  Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
190  Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
191  Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
192  Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
193 
194 namespace {
195 
196 /// SparcOperand - Instances of this class represent a parsed Sparc machine
197 /// instruction.
198 class SparcOperand : public MCParsedAsmOperand {
199 public:
200  enum RegisterKind {
201  rk_None,
202  rk_IntReg,
203  rk_IntPairReg,
204  rk_FloatReg,
205  rk_DoubleReg,
206  rk_QuadReg,
207  rk_CoprocReg,
208  rk_CoprocPairReg,
209  rk_Special,
210  };
211 
212 private:
213  enum KindTy {
214  k_Token,
215  k_Register,
216  k_Immediate,
217  k_MemoryReg,
218  k_MemoryImm
219  } Kind;
220 
221  SMLoc StartLoc, EndLoc;
222 
223  struct Token {
224  const char *Data;
225  unsigned Length;
226  };
227 
228  struct RegOp {
229  unsigned RegNum;
231  };
232 
233  struct ImmOp {
234  const MCExpr *Val;
235  };
236 
237  struct MemOp {
238  unsigned Base;
239  unsigned OffsetReg;
240  const MCExpr *Off;
241  };
242 
243  union {
244  struct Token Tok;
245  struct RegOp Reg;
246  struct ImmOp Imm;
247  struct MemOp Mem;
248  };
249 
250 public:
251  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
252 
253  bool isToken() const override { return Kind == k_Token; }
254  bool isReg() const override { return Kind == k_Register; }
255  bool isImm() const override { return Kind == k_Immediate; }
256  bool isMem() const override { return isMEMrr() || isMEMri(); }
257  bool isMEMrr() const { return Kind == k_MemoryReg; }
258  bool isMEMri() const { return Kind == k_MemoryImm; }
259 
260  bool isIntReg() const {
261  return (Kind == k_Register && Reg.Kind == rk_IntReg);
262  }
263 
264  bool isFloatReg() const {
265  return (Kind == k_Register && Reg.Kind == rk_FloatReg);
266  }
267 
268  bool isFloatOrDoubleReg() const {
269  return (Kind == k_Register && (Reg.Kind == rk_FloatReg
270  || Reg.Kind == rk_DoubleReg));
271  }
272 
273  bool isCoprocReg() const {
274  return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
275  }
276 
277  StringRef getToken() const {
278  assert(Kind == k_Token && "Invalid access!");
279  return StringRef(Tok.Data, Tok.Length);
280  }
281 
282  unsigned getReg() const override {
283  assert((Kind == k_Register) && "Invalid access!");
284  return Reg.RegNum;
285  }
286 
287  const MCExpr *getImm() const {
288  assert((Kind == k_Immediate) && "Invalid access!");
289  return Imm.Val;
290  }
291 
292  unsigned getMemBase() const {
293  assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
294  return Mem.Base;
295  }
296 
297  unsigned getMemOffsetReg() const {
298  assert((Kind == k_MemoryReg) && "Invalid access!");
299  return Mem.OffsetReg;
300  }
301 
302  const MCExpr *getMemOff() const {
303  assert((Kind == k_MemoryImm) && "Invalid access!");
304  return Mem.Off;
305  }
306 
307  /// getStartLoc - Get the location of the first token of this operand.
308  SMLoc getStartLoc() const override {
309  return StartLoc;
310  }
311  /// getEndLoc - Get the location of the last token of this operand.
312  SMLoc getEndLoc() const override {
313  return EndLoc;
314  }
315 
316  void print(raw_ostream &OS) const override {
317  switch (Kind) {
318  case k_Token: OS << "Token: " << getToken() << "\n"; break;
319  case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
320  case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
321  case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
322  << getMemOffsetReg() << "\n"; break;
323  case k_MemoryImm: assert(getMemOff() != nullptr);
324  OS << "Mem: " << getMemBase()
325  << "+" << *getMemOff()
326  << "\n"; break;
327  }
328  }
329 
330  void addRegOperands(MCInst &Inst, unsigned N) const {
331  assert(N == 1 && "Invalid number of operands!");
333  }
334 
335  void addImmOperands(MCInst &Inst, unsigned N) const {
336  assert(N == 1 && "Invalid number of operands!");
337  const MCExpr *Expr = getImm();
338  addExpr(Inst, Expr);
339  }
340 
341  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
342  // Add as immediate when possible. Null MCExpr = 0.
343  if (!Expr)
345  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
346  Inst.addOperand(MCOperand::createImm(CE->getValue()));
347  else
348  Inst.addOperand(MCOperand::createExpr(Expr));
349  }
350 
351  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
352  assert(N == 2 && "Invalid number of operands!");
353 
354  Inst.addOperand(MCOperand::createReg(getMemBase()));
355 
356  assert(getMemOffsetReg() != 0 && "Invalid offset");
357  Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
358  }
359 
360  void addMEMriOperands(MCInst &Inst, unsigned N) const {
361  assert(N == 2 && "Invalid number of operands!");
362 
363  Inst.addOperand(MCOperand::createReg(getMemBase()));
364 
365  const MCExpr *Expr = getMemOff();
366  addExpr(Inst, Expr);
367  }
368 
369  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
370  auto Op = make_unique<SparcOperand>(k_Token);
371  Op->Tok.Data = Str.data();
372  Op->Tok.Length = Str.size();
373  Op->StartLoc = S;
374  Op->EndLoc = S;
375  return Op;
376  }
377 
378  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
379  SMLoc S, SMLoc E) {
380  auto Op = make_unique<SparcOperand>(k_Register);
381  Op->Reg.RegNum = RegNum;
382  Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
383  Op->StartLoc = S;
384  Op->EndLoc = E;
385  return Op;
386  }
387 
388  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
389  SMLoc E) {
390  auto Op = make_unique<SparcOperand>(k_Immediate);
391  Op->Imm.Val = Val;
392  Op->StartLoc = S;
393  Op->EndLoc = E;
394  return Op;
395  }
396 
397  static bool MorphToIntPairReg(SparcOperand &Op) {
398  unsigned Reg = Op.getReg();
399  assert(Op.Reg.Kind == rk_IntReg);
400  unsigned regIdx = 32;
401  if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
402  regIdx = Reg - Sparc::G0;
403  else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
404  regIdx = Reg - Sparc::O0 + 8;
405  else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
406  regIdx = Reg - Sparc::L0 + 16;
407  else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
408  regIdx = Reg - Sparc::I0 + 24;
409  if (regIdx % 2 || regIdx > 31)
410  return false;
411  Op.Reg.RegNum = IntPairRegs[regIdx / 2];
412  Op.Reg.Kind = rk_IntPairReg;
413  return true;
414  }
415 
416  static bool MorphToDoubleReg(SparcOperand &Op) {
417  unsigned Reg = Op.getReg();
418  assert(Op.Reg.Kind == rk_FloatReg);
419  unsigned regIdx = Reg - Sparc::F0;
420  if (regIdx % 2 || regIdx > 31)
421  return false;
422  Op.Reg.RegNum = DoubleRegs[regIdx / 2];
423  Op.Reg.Kind = rk_DoubleReg;
424  return true;
425  }
426 
427  static bool MorphToQuadReg(SparcOperand &Op) {
428  unsigned Reg = Op.getReg();
429  unsigned regIdx = 0;
430  switch (Op.Reg.Kind) {
431  default: llvm_unreachable("Unexpected register kind!");
432  case rk_FloatReg:
433  regIdx = Reg - Sparc::F0;
434  if (regIdx % 4 || regIdx > 31)
435  return false;
436  Reg = QuadFPRegs[regIdx / 4];
437  break;
438  case rk_DoubleReg:
439  regIdx = Reg - Sparc::D0;
440  if (regIdx % 2 || regIdx > 31)
441  return false;
442  Reg = QuadFPRegs[regIdx / 2];
443  break;
444  }
445  Op.Reg.RegNum = Reg;
446  Op.Reg.Kind = rk_QuadReg;
447  return true;
448  }
449 
450  static bool MorphToCoprocPairReg(SparcOperand &Op) {
451  unsigned Reg = Op.getReg();
452  assert(Op.Reg.Kind == rk_CoprocReg);
453  unsigned regIdx = 32;
454  if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
455  regIdx = Reg - Sparc::C0;
456  if (regIdx % 2 || regIdx > 31)
457  return false;
458  Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
459  Op.Reg.Kind = rk_CoprocPairReg;
460  return true;
461  }
462 
463  static std::unique_ptr<SparcOperand>
464  MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
465  unsigned offsetReg = Op->getReg();
466  Op->Kind = k_MemoryReg;
467  Op->Mem.Base = Base;
468  Op->Mem.OffsetReg = offsetReg;
469  Op->Mem.Off = nullptr;
470  return Op;
471  }
472 
473  static std::unique_ptr<SparcOperand>
474  CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
475  auto Op = make_unique<SparcOperand>(k_MemoryReg);
476  Op->Mem.Base = Base;
477  Op->Mem.OffsetReg = Sparc::G0; // always 0
478  Op->Mem.Off = nullptr;
479  Op->StartLoc = S;
480  Op->EndLoc = E;
481  return Op;
482  }
483 
484  static std::unique_ptr<SparcOperand>
485  MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
486  const MCExpr *Imm = Op->getImm();
487  Op->Kind = k_MemoryImm;
488  Op->Mem.Base = Base;
489  Op->Mem.OffsetReg = 0;
490  Op->Mem.Off = Imm;
491  return Op;
492  }
493 };
494 
495 } // end anonymous namespace
496 
497 bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
498  SmallVectorImpl<MCInst> &Instructions) {
499  MCOperand MCRegOp = Inst.getOperand(0);
500  MCOperand MCValOp = Inst.getOperand(1);
501  assert(MCRegOp.isReg());
502  assert(MCValOp.isImm() || MCValOp.isExpr());
503 
504  // the imm operand can be either an expression or an immediate.
505  bool IsImm = Inst.getOperand(1).isImm();
506  int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
507 
508  // Allow either a signed or unsigned 32-bit immediate.
509  if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
510  return Error(IDLoc,
511  "set: argument must be between -2147483648 and 4294967295");
512  }
513 
514  // If the value was expressed as a large unsigned number, that's ok.
515  // We want to see if it "looks like" a small signed number.
516  int32_t ImmValue = RawImmValue;
517  // For 'set' you can't use 'or' with a negative operand on V9 because
518  // that would splat the sign bit across the upper half of the destination
519  // register, whereas 'set' is defined to zero the high 32 bits.
520  bool IsEffectivelyImm13 =
521  IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
522  const MCExpr *ValExpr;
523  if (IsImm)
524  ValExpr = MCConstantExpr::create(ImmValue, getContext());
525  else
526  ValExpr = MCValOp.getExpr();
527 
528  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
529 
530  // If not just a signed imm13 value, then either we use a 'sethi' with a
531  // following 'or', or a 'sethi' by itself if there are no more 1 bits.
532  // In either case, start with the 'sethi'.
533  if (!IsEffectivelyImm13) {
534  MCInst TmpInst;
535  const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
536  TmpInst.setLoc(IDLoc);
537  TmpInst.setOpcode(SP::SETHIi);
538  TmpInst.addOperand(MCRegOp);
539  TmpInst.addOperand(MCOperand::createExpr(Expr));
540  Instructions.push_back(TmpInst);
541  PrevReg = MCRegOp;
542  }
543 
544  // The low bits require touching in 3 cases:
545  // * A non-immediate value will always require both instructions.
546  // * An effectively imm13 value needs only an 'or' instruction.
547  // * Otherwise, an immediate that is not effectively imm13 requires the
548  // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
549  // If the low bits are known zeros, there's nothing to do.
550  // In the second case, and only in that case, must we NOT clear
551  // bits of the immediate value via the %lo() assembler function.
552  // Note also, the 'or' instruction doesn't mind a large value in the case
553  // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
554  if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
555  MCInst TmpInst;
556  const MCExpr *Expr;
557  if (IsEffectivelyImm13)
558  Expr = ValExpr;
559  else
560  Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
561  TmpInst.setLoc(IDLoc);
562  TmpInst.setOpcode(SP::ORri);
563  TmpInst.addOperand(MCRegOp);
564  TmpInst.addOperand(PrevReg);
565  TmpInst.addOperand(MCOperand::createExpr(Expr));
566  Instructions.push_back(TmpInst);
567  }
568  return false;
569 }
570 
571 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
572  OperandVector &Operands,
573  MCStreamer &Out,
574  uint64_t &ErrorInfo,
575  bool MatchingInlineAsm) {
576  MCInst Inst;
577  SmallVector<MCInst, 8> Instructions;
578  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
579  MatchingInlineAsm);
580  switch (MatchResult) {
581  case Match_Success: {
582  switch (Inst.getOpcode()) {
583  default:
584  Inst.setLoc(IDLoc);
585  Instructions.push_back(Inst);
586  break;
587  case SP::SET:
588  if (expandSET(Inst, IDLoc, Instructions))
589  return true;
590  break;
591  }
592 
593  for (const MCInst &I : Instructions) {
594  Out.EmitInstruction(I, getSTI());
595  }
596  return false;
597  }
598 
599  case Match_MissingFeature:
600  return Error(IDLoc,
601  "instruction requires a CPU feature not currently enabled");
602 
603  case Match_InvalidOperand: {
604  SMLoc ErrorLoc = IDLoc;
605  if (ErrorInfo != ~0ULL) {
606  if (ErrorInfo >= Operands.size())
607  return Error(IDLoc, "too few operands for instruction");
608 
609  ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
610  if (ErrorLoc == SMLoc())
611  ErrorLoc = IDLoc;
612  }
613 
614  return Error(ErrorLoc, "invalid operand for instruction");
615  }
616  case Match_MnemonicFail:
617  return Error(IDLoc, "invalid instruction mnemonic");
618  }
619  llvm_unreachable("Implement any new match types added!");
620 }
621 
622 bool SparcAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
623  SMLoc &EndLoc) {
624  const AsmToken &Tok = Parser.getTok();
625  StartLoc = Tok.getLoc();
626  EndLoc = Tok.getEndLoc();
627  RegNo = 0;
628  if (getLexer().getKind() != AsmToken::Percent)
629  return false;
630  Parser.Lex();
631  unsigned regKind = SparcOperand::rk_None;
632  if (matchRegisterName(Tok, RegNo, regKind)) {
633  Parser.Lex();
634  return false;
635  }
636 
637  return Error(StartLoc, "invalid register name");
638 }
639 
640 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
641  unsigned VariantID);
642 
643 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
644  StringRef Name, SMLoc NameLoc,
645  OperandVector &Operands) {
646 
647  // First operand in MCInst is instruction mnemonic.
648  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
649 
650  // apply mnemonic aliases, if any, so that we can parse operands correctly.
651  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
652 
653  if (getLexer().isNot(AsmToken::EndOfStatement)) {
654  // Read the first operand.
655  if (getLexer().is(AsmToken::Comma)) {
656  if (parseBranchModifiers(Operands) != MatchOperand_Success) {
657  SMLoc Loc = getLexer().getLoc();
658  return Error(Loc, "unexpected token");
659  }
660  }
661  if (parseOperand(Operands, Name) != MatchOperand_Success) {
662  SMLoc Loc = getLexer().getLoc();
663  return Error(Loc, "unexpected token");
664  }
665 
666  while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
667  if (getLexer().is(AsmToken::Plus)) {
668  // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
669  Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
670  }
671  Parser.Lex(); // Eat the comma or plus.
672  // Parse and remember the operand.
673  if (parseOperand(Operands, Name) != MatchOperand_Success) {
674  SMLoc Loc = getLexer().getLoc();
675  return Error(Loc, "unexpected token");
676  }
677  }
678  }
679  if (getLexer().isNot(AsmToken::EndOfStatement)) {
680  SMLoc Loc = getLexer().getLoc();
681  return Error(Loc, "unexpected token");
682  }
683  Parser.Lex(); // Consume the EndOfStatement.
684  return false;
685 }
686 
687 bool SparcAsmParser::
688 ParseDirective(AsmToken DirectiveID)
689 {
690  StringRef IDVal = DirectiveID.getString();
691 
692  if (IDVal == ".register") {
693  // For now, ignore .register directive.
694  Parser.eatToEndOfStatement();
695  return false;
696  }
697  if (IDVal == ".proc") {
698  // For compatibility, ignore this directive.
699  // (It's supposed to be an "optimization" in the Sun assembler)
700  Parser.eatToEndOfStatement();
701  return false;
702  }
703 
704  // Let the MC layer to handle other directives.
705  return true;
706 }
707 
709 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
710  SMLoc S, E;
711  unsigned BaseReg = 0;
712 
713  if (ParseRegister(BaseReg, S, E)) {
714  return MatchOperand_NoMatch;
715  }
716 
717  switch (getLexer().getKind()) {
718  default: return MatchOperand_NoMatch;
719 
720  case AsmToken::Comma:
721  case AsmToken::RBrac:
723  Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
724  return MatchOperand_Success;
725 
726  case AsmToken:: Plus:
727  Parser.Lex(); // Eat the '+'
728  break;
729  case AsmToken::Minus:
730  break;
731  }
732 
733  std::unique_ptr<SparcOperand> Offset;
734  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
735  if (ResTy != MatchOperand_Success || !Offset)
736  return MatchOperand_NoMatch;
737 
738  Operands.push_back(
739  Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
740  : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
741 
742  return MatchOperand_Success;
743 }
744 
746 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
747 
748  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
749 
750  // If there wasn't a custom match, try the generic matcher below. Otherwise,
751  // there was a match, but an error occurred, in which case, just return that
752  // the operand parsing failed.
753  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
754  return ResTy;
755 
756  if (getLexer().is(AsmToken::LBrac)) {
757  // Memory operand
758  Operands.push_back(SparcOperand::CreateToken("[",
759  Parser.getTok().getLoc()));
760  Parser.Lex(); // Eat the [
761 
762  if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
763  SMLoc S = Parser.getTok().getLoc();
764  if (getLexer().getKind() != AsmToken::Percent)
765  return MatchOperand_NoMatch;
766  Parser.Lex(); // eat %
767 
768  unsigned RegNo, RegKind;
769  if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
770  return MatchOperand_NoMatch;
771 
772  Parser.Lex(); // Eat the identifier token.
774  Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
775  ResTy = MatchOperand_Success;
776  } else {
777  ResTy = parseMEMOperand(Operands);
778  }
779 
780  if (ResTy != MatchOperand_Success)
781  return ResTy;
782 
783  if (!getLexer().is(AsmToken::RBrac))
784  return MatchOperand_ParseFail;
785 
786  Operands.push_back(SparcOperand::CreateToken("]",
787  Parser.getTok().getLoc()));
788  Parser.Lex(); // Eat the ]
789 
790  // Parse an optional address-space identifier after the address.
791  if (getLexer().is(AsmToken::Integer)) {
792  std::unique_ptr<SparcOperand> Op;
793  ResTy = parseSparcAsmOperand(Op, false);
794  if (ResTy != MatchOperand_Success || !Op)
795  return MatchOperand_ParseFail;
796  Operands.push_back(std::move(Op));
797  }
798  return MatchOperand_Success;
799  }
800 
801  std::unique_ptr<SparcOperand> Op;
802 
803  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
804  if (ResTy != MatchOperand_Success || !Op)
805  return MatchOperand_ParseFail;
806 
807  // Push the parsed operand into the list of operands
808  Operands.push_back(std::move(Op));
809 
810  return MatchOperand_Success;
811 }
812 
814 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
815  bool isCall) {
816  SMLoc S = Parser.getTok().getLoc();
817  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
818  const MCExpr *EVal;
819 
820  Op = nullptr;
821  switch (getLexer().getKind()) {
822  default: break;
823 
824  case AsmToken::Percent:
825  Parser.Lex(); // Eat the '%'.
826  unsigned RegNo;
827  unsigned RegKind;
828  if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
829  StringRef name = Parser.getTok().getString();
830  Parser.Lex(); // Eat the identifier token.
831  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
832  switch (RegNo) {
833  default:
834  Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
835  break;
836  case Sparc::PSR:
837  Op = SparcOperand::CreateToken("%psr", S);
838  break;
839  case Sparc::FSR:
840  Op = SparcOperand::CreateToken("%fsr", S);
841  break;
842  case Sparc::FQ:
843  Op = SparcOperand::CreateToken("%fq", S);
844  break;
845  case Sparc::CPSR:
846  Op = SparcOperand::CreateToken("%csr", S);
847  break;
848  case Sparc::CPQ:
849  Op = SparcOperand::CreateToken("%cq", S);
850  break;
851  case Sparc::WIM:
852  Op = SparcOperand::CreateToken("%wim", S);
853  break;
854  case Sparc::TBR:
855  Op = SparcOperand::CreateToken("%tbr", S);
856  break;
857  case Sparc::ICC:
858  if (name == "xcc")
859  Op = SparcOperand::CreateToken("%xcc", S);
860  else
861  Op = SparcOperand::CreateToken("%icc", S);
862  break;
863  }
864  break;
865  }
866  if (matchSparcAsmModifiers(EVal, E)) {
867  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
868  Op = SparcOperand::CreateImm(EVal, S, E);
869  }
870  break;
871 
872  case AsmToken::Minus:
873  case AsmToken::Integer:
874  case AsmToken::LParen:
875  case AsmToken::Dot:
876  if (!getParser().parseExpression(EVal, E))
877  Op = SparcOperand::CreateImm(EVal, S, E);
878  break;
879 
880  case AsmToken::Identifier: {
882  if (!getParser().parseIdentifier(Identifier)) {
883  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
884  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
885 
887  getContext());
889 
890  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
891  if (isCall)
893  else
895  }
896 
897  Res = SparcMCExpr::create(Kind, Res, getContext());
898 
899  Op = SparcOperand::CreateImm(Res, S, E);
900  }
901  break;
902  }
903  }
905 }
906 
908 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
909  // parse (,a|,pn|,pt)+
910 
911  while (getLexer().is(AsmToken::Comma)) {
912  Parser.Lex(); // Eat the comma
913 
914  if (!getLexer().is(AsmToken::Identifier))
915  return MatchOperand_ParseFail;
916  StringRef modName = Parser.getTok().getString();
917  if (modName == "a" || modName == "pn" || modName == "pt") {
918  Operands.push_back(SparcOperand::CreateToken(modName,
919  Parser.getTok().getLoc()));
920  Parser.Lex(); // eat the identifier.
921  }
922  }
923  return MatchOperand_Success;
924 }
925 
926 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
927  unsigned &RegKind) {
928  int64_t intVal = 0;
929  RegNo = 0;
930  RegKind = SparcOperand::rk_None;
931  if (Tok.is(AsmToken::Identifier)) {
932  StringRef name = Tok.getString();
933 
934  // %fp
935  if (name.equals("fp")) {
936  RegNo = Sparc::I6;
937  RegKind = SparcOperand::rk_IntReg;
938  return true;
939  }
940  // %sp
941  if (name.equals("sp")) {
942  RegNo = Sparc::O6;
943  RegKind = SparcOperand::rk_IntReg;
944  return true;
945  }
946 
947  if (name.equals("y")) {
948  RegNo = Sparc::Y;
949  RegKind = SparcOperand::rk_Special;
950  return true;
951  }
952 
953  if (name.substr(0, 3).equals_lower("asr")
954  && !name.substr(3).getAsInteger(10, intVal)
955  && intVal > 0 && intVal < 32) {
956  RegNo = ASRRegs[intVal];
957  RegKind = SparcOperand::rk_Special;
958  return true;
959  }
960 
961  // %fprs is an alias of %asr6.
962  if (name.equals("fprs")) {
963  RegNo = ASRRegs[6];
964  RegKind = SparcOperand::rk_Special;
965  return true;
966  }
967 
968  if (name.equals("icc")) {
969  RegNo = Sparc::ICC;
970  RegKind = SparcOperand::rk_Special;
971  return true;
972  }
973 
974  if (name.equals("psr")) {
975  RegNo = Sparc::PSR;
976  RegKind = SparcOperand::rk_Special;
977  return true;
978  }
979 
980  if (name.equals("fsr")) {
981  RegNo = Sparc::FSR;
982  RegKind = SparcOperand::rk_Special;
983  return true;
984  }
985 
986  if (name.equals("fq")) {
987  RegNo = Sparc::FQ;
988  RegKind = SparcOperand::rk_Special;
989  return true;
990  }
991 
992  if (name.equals("csr")) {
993  RegNo = Sparc::CPSR;
994  RegKind = SparcOperand::rk_Special;
995  return true;
996  }
997 
998  if (name.equals("cq")) {
999  RegNo = Sparc::CPQ;
1000  RegKind = SparcOperand::rk_Special;
1001  return true;
1002  }
1003 
1004  if (name.equals("wim")) {
1005  RegNo = Sparc::WIM;
1006  RegKind = SparcOperand::rk_Special;
1007  return true;
1008  }
1009 
1010  if (name.equals("tbr")) {
1011  RegNo = Sparc::TBR;
1012  RegKind = SparcOperand::rk_Special;
1013  return true;
1014  }
1015 
1016  if (name.equals("xcc")) {
1017  // FIXME:: check 64bit.
1018  RegNo = Sparc::ICC;
1019  RegKind = SparcOperand::rk_Special;
1020  return true;
1021  }
1022 
1023  // %fcc0 - %fcc3
1024  if (name.substr(0, 3).equals_lower("fcc")
1025  && !name.substr(3).getAsInteger(10, intVal)
1026  && intVal < 4) {
1027  // FIXME: check 64bit and handle %fcc1 - %fcc3
1028  RegNo = Sparc::FCC0 + intVal;
1029  RegKind = SparcOperand::rk_Special;
1030  return true;
1031  }
1032 
1033  // %g0 - %g7
1034  if (name.substr(0, 1).equals_lower("g")
1035  && !name.substr(1).getAsInteger(10, intVal)
1036  && intVal < 8) {
1037  RegNo = IntRegs[intVal];
1038  RegKind = SparcOperand::rk_IntReg;
1039  return true;
1040  }
1041  // %o0 - %o7
1042  if (name.substr(0, 1).equals_lower("o")
1043  && !name.substr(1).getAsInteger(10, intVal)
1044  && intVal < 8) {
1045  RegNo = IntRegs[8 + intVal];
1046  RegKind = SparcOperand::rk_IntReg;
1047  return true;
1048  }
1049  if (name.substr(0, 1).equals_lower("l")
1050  && !name.substr(1).getAsInteger(10, intVal)
1051  && intVal < 8) {
1052  RegNo = IntRegs[16 + intVal];
1053  RegKind = SparcOperand::rk_IntReg;
1054  return true;
1055  }
1056  if (name.substr(0, 1).equals_lower("i")
1057  && !name.substr(1).getAsInteger(10, intVal)
1058  && intVal < 8) {
1059  RegNo = IntRegs[24 + intVal];
1060  RegKind = SparcOperand::rk_IntReg;
1061  return true;
1062  }
1063  // %f0 - %f31
1064  if (name.substr(0, 1).equals_lower("f")
1065  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1066  RegNo = FloatRegs[intVal];
1067  RegKind = SparcOperand::rk_FloatReg;
1068  return true;
1069  }
1070  // %f32 - %f62
1071  if (name.substr(0, 1).equals_lower("f")
1072  && !name.substr(1, 2).getAsInteger(10, intVal)
1073  && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1074  // FIXME: Check V9
1075  RegNo = DoubleRegs[intVal/2];
1076  RegKind = SparcOperand::rk_DoubleReg;
1077  return true;
1078  }
1079 
1080  // %r0 - %r31
1081  if (name.substr(0, 1).equals_lower("r")
1082  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1083  RegNo = IntRegs[intVal];
1084  RegKind = SparcOperand::rk_IntReg;
1085  return true;
1086  }
1087 
1088  // %c0 - %c31
1089  if (name.substr(0, 1).equals_lower("c")
1090  && !name.substr(1).getAsInteger(10, intVal)
1091  && intVal < 32) {
1092  RegNo = CoprocRegs[intVal];
1093  RegKind = SparcOperand::rk_CoprocReg;
1094  return true;
1095  }
1096 
1097  if (name.equals("tpc")) {
1098  RegNo = Sparc::TPC;
1099  RegKind = SparcOperand::rk_Special;
1100  return true;
1101  }
1102  if (name.equals("tnpc")) {
1103  RegNo = Sparc::TNPC;
1104  RegKind = SparcOperand::rk_Special;
1105  return true;
1106  }
1107  if (name.equals("tstate")) {
1108  RegNo = Sparc::TSTATE;
1109  RegKind = SparcOperand::rk_Special;
1110  return true;
1111  }
1112  if (name.equals("tt")) {
1113  RegNo = Sparc::TT;
1114  RegKind = SparcOperand::rk_Special;
1115  return true;
1116  }
1117  if (name.equals("tick")) {
1118  RegNo = Sparc::TICK;
1119  RegKind = SparcOperand::rk_Special;
1120  return true;
1121  }
1122  if (name.equals("tba")) {
1123  RegNo = Sparc::TBA;
1124  RegKind = SparcOperand::rk_Special;
1125  return true;
1126  }
1127  if (name.equals("pstate")) {
1128  RegNo = Sparc::PSTATE;
1129  RegKind = SparcOperand::rk_Special;
1130  return true;
1131  }
1132  if (name.equals("tl")) {
1133  RegNo = Sparc::TL;
1134  RegKind = SparcOperand::rk_Special;
1135  return true;
1136  }
1137  if (name.equals("pil")) {
1138  RegNo = Sparc::PIL;
1139  RegKind = SparcOperand::rk_Special;
1140  return true;
1141  }
1142  if (name.equals("cwp")) {
1143  RegNo = Sparc::CWP;
1144  RegKind = SparcOperand::rk_Special;
1145  return true;
1146  }
1147  if (name.equals("cansave")) {
1148  RegNo = Sparc::CANSAVE;
1149  RegKind = SparcOperand::rk_Special;
1150  return true;
1151  }
1152  if (name.equals("canrestore")) {
1153  RegNo = Sparc::CANRESTORE;
1154  RegKind = SparcOperand::rk_Special;
1155  return true;
1156  }
1157  if (name.equals("cleanwin")) {
1158  RegNo = Sparc::CLEANWIN;
1159  RegKind = SparcOperand::rk_Special;
1160  return true;
1161  }
1162  if (name.equals("otherwin")) {
1163  RegNo = Sparc::OTHERWIN;
1164  RegKind = SparcOperand::rk_Special;
1165  return true;
1166  }
1167  if (name.equals("wstate")) {
1168  RegNo = Sparc::WSTATE;
1169  RegKind = SparcOperand::rk_Special;
1170  return true;
1171  }
1172  }
1173  return false;
1174 }
1175 
1176 // Determine if an expression contains a reference to the symbol
1177 // "_GLOBAL_OFFSET_TABLE_".
1178 static bool hasGOTReference(const MCExpr *Expr) {
1179  switch (Expr->getKind()) {
1180  case MCExpr::Target:
1181  if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1182  return hasGOTReference(SE->getSubExpr());
1183  break;
1184 
1185  case MCExpr::Constant:
1186  break;
1187 
1188  case MCExpr::Binary: {
1189  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1190  return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1191  }
1192 
1193  case MCExpr::SymbolRef: {
1194  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1195  return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1196  }
1197 
1198  case MCExpr::Unary:
1199  return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1200  }
1201  return false;
1202 }
1203 
1204 const SparcMCExpr *
1205 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1206  const MCExpr *subExpr) {
1207  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1208  // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1209  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1210  // as %got10 or %got22 relocation.
1211 
1212  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1213  switch(VK) {
1214  default: break;
1218  break;
1222  break;
1223  }
1224  }
1225 
1226  return SparcMCExpr::create(VK, subExpr, getContext());
1227 }
1228 
1229 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1230  SMLoc &EndLoc) {
1231  AsmToken Tok = Parser.getTok();
1232  if (!Tok.is(AsmToken::Identifier))
1233  return false;
1234 
1235  StringRef name = Tok.getString();
1236 
1238 
1239  if (VK == SparcMCExpr::VK_Sparc_None)
1240  return false;
1241 
1242  Parser.Lex(); // Eat the identifier.
1243  if (Parser.getTok().getKind() != AsmToken::LParen)
1244  return false;
1245 
1246  Parser.Lex(); // Eat the LParen token.
1247  const MCExpr *subExpr;
1248  if (Parser.parseParenExpression(subExpr, EndLoc))
1249  return false;
1250 
1251  EVal = adjustPICRelocation(VK, subExpr);
1252  return true;
1253 }
1254 
1255 extern "C" void LLVMInitializeSparcAsmParser() {
1259 }
1260 
1261 #define GET_REGISTER_MATCHER
1262 #define GET_MATCHER_IMPLEMENTATION
1263 #include "SparcGenAsmMatcher.inc"
1264 
1265 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1266  unsigned Kind) {
1267  SparcOperand &Op = (SparcOperand &)GOp;
1268  if (Op.isFloatOrDoubleReg()) {
1269  switch (Kind) {
1270  default: break;
1271  case MCK_DFPRegs:
1272  if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1274  break;
1275  case MCK_QFPRegs:
1276  if (SparcOperand::MorphToQuadReg(Op))
1278  break;
1279  }
1280  }
1281  if (Op.isIntReg() && Kind == MCK_IntPair) {
1282  if (SparcOperand::MorphToIntPairReg(Op))
1284  }
1285  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1286  if (SparcOperand::MorphToCoprocPairReg(Op))
1288  }
1289  return Match_InvalidOperand;
1290 }
static bool isReg(const MCInst &MI, unsigned OpNo)
uint64_t CallInst * C
bool isImm() const
Definition: MCInst.h:59
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:111
static const MCPhysReg IntRegs[32]
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:176
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:137
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:137
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static const MCPhysReg CoprocPairRegs[]
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
unsigned Reg
bool isReg() const
Definition: MCInst.h:58
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:562
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:34
static const MCPhysReg ASRRegs[32]
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:907
static const MCPhysReg QuadFPRegs[32]
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, unsigned VariantID)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
RegisterKind
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:166
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:160
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:565
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
Target & getTheSparcTarget()
const MCExpr * getExpr() const
Definition: MCInst.h:96
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
Unary expressions.
Definition: MCExpr.h:42
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
void LLVMInitializeSparcAsmParser()
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
int64_t getImm() const
Definition: MCInst.h:76
const char * getPointer() const
Definition: SMLoc.h:35
Streaming machine code generation interface.
Definition: MCStreamer.h:183
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define SET(n)
Definition: MD5.cpp:68
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:32
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool is64Bit(const char *name)
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
Target & getTheSparcelTarget()
bool isExpr() const
Definition: MCInst.h:61
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:87
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static bool hasGOTReference(const MCExpr *Expr)
Binary assembler expressions.
Definition: MCExpr.h:415
void setLoc(SMLoc loc)
Definition: MCInst.h:179
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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:497
void setOpcode(unsigned Op)
Definition: MCInst.h:173
const MCSymbol & getSymbol() const
Definition: MCExpr.h:334
ExprKind getKind() const
Definition: MCExpr.h:73
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
static const MCPhysReg CoprocRegs[32]
bool is(TokenKind K) const
Definition: MCAsmMacro.h:83
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static const MCPhysReg IntPairRegs[]
Base class for user error types.
Definition: Error.h:339
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:169
Target & getTheSparcV9Target()
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:37
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Generic base class for all target subtargets.
References to labels and assigned expressions.
Definition: MCExpr.h:41
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:27
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Constant expressions.
Definition: MCExpr.h:40
static const MCPhysReg FloatRegs[32]
Binary expressions.
Definition: MCExpr.h:39
const FeatureBitset Features
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Target specific expression.
Definition: MCExpr.h:43
Represents a location in source code.
Definition: SMLoc.h:24
unsigned getOpcode() const
Definition: MCInst.h:174
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial &#39;(&#39; has already been consumed.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:164
TokenKind getKind() const
Definition: MCAsmMacro.h:82
static const MCPhysReg DoubleRegs[32]