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