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