LLVM  10.0.0svn
SparcAsmParser.cpp
Go to the documentation of this file.
1 //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
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,
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.
80 
82 
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 = std::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 = std::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 = std::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 = std::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,
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,
650  const FeatureBitset &Features,
651  unsigned VariantID);
652 
653 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
654  StringRef Name, SMLoc NameLoc,
655  OperandVector &Operands) {
656 
657  // First operand in MCInst is instruction mnemonic.
658  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
659 
660  // apply mnemonic aliases, if any, so that we can parse operands correctly.
661  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
662 
663  if (getLexer().isNot(AsmToken::EndOfStatement)) {
664  // Read the first operand.
665  if (getLexer().is(AsmToken::Comma)) {
666  if (parseBranchModifiers(Operands) != MatchOperand_Success) {
667  SMLoc Loc = getLexer().getLoc();
668  return Error(Loc, "unexpected token");
669  }
670  }
671  if (parseOperand(Operands, Name) != MatchOperand_Success) {
672  SMLoc Loc = getLexer().getLoc();
673  return Error(Loc, "unexpected token");
674  }
675 
676  while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
677  if (getLexer().is(AsmToken::Plus)) {
678  // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
679  Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
680  }
681  Parser.Lex(); // Eat the comma or plus.
682  // Parse and remember the operand.
683  if (parseOperand(Operands, Name) != MatchOperand_Success) {
684  SMLoc Loc = getLexer().getLoc();
685  return Error(Loc, "unexpected token");
686  }
687  }
688  }
689  if (getLexer().isNot(AsmToken::EndOfStatement)) {
690  SMLoc Loc = getLexer().getLoc();
691  return Error(Loc, "unexpected token");
692  }
693  Parser.Lex(); // Consume the EndOfStatement.
694  return false;
695 }
696 
697 bool SparcAsmParser::
698 ParseDirective(AsmToken DirectiveID)
699 {
700  StringRef IDVal = DirectiveID.getString();
701 
702  if (IDVal == ".register") {
703  // For now, ignore .register directive.
704  Parser.eatToEndOfStatement();
705  return false;
706  }
707  if (IDVal == ".proc") {
708  // For compatibility, ignore this directive.
709  // (It's supposed to be an "optimization" in the Sun assembler)
710  Parser.eatToEndOfStatement();
711  return false;
712  }
713 
714  // Let the MC layer to handle other directives.
715  return true;
716 }
717 
719 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
720  SMLoc S, E;
721  unsigned BaseReg = 0;
722 
723  if (ParseRegister(BaseReg, S, E)) {
724  return MatchOperand_NoMatch;
725  }
726 
727  switch (getLexer().getKind()) {
728  default: return MatchOperand_NoMatch;
729 
730  case AsmToken::Comma:
731  case AsmToken::RBrac:
733  Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
734  return MatchOperand_Success;
735 
736  case AsmToken:: Plus:
737  Parser.Lex(); // Eat the '+'
738  break;
739  case AsmToken::Minus:
740  break;
741  }
742 
743  std::unique_ptr<SparcOperand> Offset;
744  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
745  if (ResTy != MatchOperand_Success || !Offset)
746  return MatchOperand_NoMatch;
747 
748  Operands.push_back(
749  Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
750  : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
751 
752  return MatchOperand_Success;
753 }
754 
755 OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
756  SMLoc S = Parser.getTok().getLoc();
757  const MCExpr *EVal;
758  int64_t ImmVal = 0;
759 
760  std::unique_ptr<SparcOperand> Mask;
761  if (parseSparcAsmOperand(Mask) == MatchOperand_Success) {
762  if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
763  ImmVal < 0 || ImmVal > 127) {
764  Error(S, "invalid membar mask number");
765  return MatchOperand_ParseFail;
766  }
767  }
768 
769  while (getLexer().getKind() == AsmToken::Hash) {
770  SMLoc TagStart = getLexer().getLoc();
771  Parser.Lex(); // Eat the '#'.
772  unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
773  .Case("LoadLoad", 0x1)
774  .Case("StoreLoad", 0x2)
775  .Case("LoadStore", 0x4)
776  .Case("StoreStore", 0x8)
777  .Case("Lookaside", 0x10)
778  .Case("MemIssue", 0x20)
779  .Case("Sync", 0x40)
780  .Default(0);
781 
782  Parser.Lex(); // Eat the identifier token.
783 
784  if (!MaskVal) {
785  Error(TagStart, "unknown membar tag");
786  return MatchOperand_ParseFail;
787  }
788 
789  ImmVal |= MaskVal;
790 
791  if (getLexer().getKind() == AsmToken::Pipe)
792  Parser.Lex(); // Eat the '|'.
793  }
794 
795  EVal = MCConstantExpr::create(ImmVal, getContext());
796  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
797  Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
798  return MatchOperand_Success;
799 }
800 
802 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
803 
804  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
805 
806  // If there wasn't a custom match, try the generic matcher below. Otherwise,
807  // there was a match, but an error occurred, in which case, just return that
808  // the operand parsing failed.
809  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
810  return ResTy;
811 
812  if (getLexer().is(AsmToken::LBrac)) {
813  // Memory operand
814  Operands.push_back(SparcOperand::CreateToken("[",
815  Parser.getTok().getLoc()));
816  Parser.Lex(); // Eat the [
817 
818  if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
819  SMLoc S = Parser.getTok().getLoc();
820  if (getLexer().getKind() != AsmToken::Percent)
821  return MatchOperand_NoMatch;
822  Parser.Lex(); // eat %
823 
824  unsigned RegNo, RegKind;
825  if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
826  return MatchOperand_NoMatch;
827 
828  Parser.Lex(); // Eat the identifier token.
830  Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
831  ResTy = MatchOperand_Success;
832  } else {
833  ResTy = parseMEMOperand(Operands);
834  }
835 
836  if (ResTy != MatchOperand_Success)
837  return ResTy;
838 
839  if (!getLexer().is(AsmToken::RBrac))
840  return MatchOperand_ParseFail;
841 
842  Operands.push_back(SparcOperand::CreateToken("]",
843  Parser.getTok().getLoc()));
844  Parser.Lex(); // Eat the ]
845 
846  // Parse an optional address-space identifier after the address.
847  if (getLexer().is(AsmToken::Integer)) {
848  std::unique_ptr<SparcOperand> Op;
849  ResTy = parseSparcAsmOperand(Op, false);
850  if (ResTy != MatchOperand_Success || !Op)
851  return MatchOperand_ParseFail;
852  Operands.push_back(std::move(Op));
853  }
854  return MatchOperand_Success;
855  }
856 
857  std::unique_ptr<SparcOperand> Op;
858 
859  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
860  if (ResTy != MatchOperand_Success || !Op)
861  return MatchOperand_ParseFail;
862 
863  // Push the parsed operand into the list of operands
864  Operands.push_back(std::move(Op));
865 
866  return MatchOperand_Success;
867 }
868 
870 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
871  bool isCall) {
872  SMLoc S = Parser.getTok().getLoc();
873  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
874  const MCExpr *EVal;
875 
876  Op = nullptr;
877  switch (getLexer().getKind()) {
878  default: break;
879 
880  case AsmToken::Percent:
881  Parser.Lex(); // Eat the '%'.
882  unsigned RegNo;
883  unsigned RegKind;
884  if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
885  StringRef name = Parser.getTok().getString();
886  Parser.Lex(); // Eat the identifier token.
887  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
888  switch (RegNo) {
889  default:
890  Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
891  break;
892  case Sparc::PSR:
893  Op = SparcOperand::CreateToken("%psr", S);
894  break;
895  case Sparc::FSR:
896  Op = SparcOperand::CreateToken("%fsr", S);
897  break;
898  case Sparc::FQ:
899  Op = SparcOperand::CreateToken("%fq", S);
900  break;
901  case Sparc::CPSR:
902  Op = SparcOperand::CreateToken("%csr", S);
903  break;
904  case Sparc::CPQ:
905  Op = SparcOperand::CreateToken("%cq", S);
906  break;
907  case Sparc::WIM:
908  Op = SparcOperand::CreateToken("%wim", S);
909  break;
910  case Sparc::TBR:
911  Op = SparcOperand::CreateToken("%tbr", S);
912  break;
913  case Sparc::ICC:
914  if (name == "xcc")
915  Op = SparcOperand::CreateToken("%xcc", S);
916  else
917  Op = SparcOperand::CreateToken("%icc", S);
918  break;
919  }
920  break;
921  }
922  if (matchSparcAsmModifiers(EVal, E)) {
923  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
924  Op = SparcOperand::CreateImm(EVal, S, E);
925  }
926  break;
927 
928  case AsmToken::Minus:
929  case AsmToken::Integer:
930  case AsmToken::LParen:
931  case AsmToken::Dot:
932  if (!getParser().parseExpression(EVal, E))
933  Op = SparcOperand::CreateImm(EVal, S, E);
934  break;
935 
936  case AsmToken::Identifier: {
938  if (!getParser().parseIdentifier(Identifier)) {
939  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
940  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
941 
943  getContext());
945 
946  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
947  if (isCall)
949  else
951  }
952 
953  Res = SparcMCExpr::create(Kind, Res, getContext());
954 
955  Op = SparcOperand::CreateImm(Res, S, E);
956  }
957  break;
958  }
959  }
961 }
962 
964 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
965  // parse (,a|,pn|,pt)+
966 
967  while (getLexer().is(AsmToken::Comma)) {
968  Parser.Lex(); // Eat the comma
969 
970  if (!getLexer().is(AsmToken::Identifier))
971  return MatchOperand_ParseFail;
972  StringRef modName = Parser.getTok().getString();
973  if (modName == "a" || modName == "pn" || modName == "pt") {
974  Operands.push_back(SparcOperand::CreateToken(modName,
975  Parser.getTok().getLoc()));
976  Parser.Lex(); // eat the identifier.
977  }
978  }
979  return MatchOperand_Success;
980 }
981 
982 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
983  unsigned &RegKind) {
984  int64_t intVal = 0;
985  RegNo = 0;
986  RegKind = SparcOperand::rk_None;
987  if (Tok.is(AsmToken::Identifier)) {
988  StringRef name = Tok.getString();
989 
990  // %fp
991  if (name.equals("fp")) {
992  RegNo = Sparc::I6;
993  RegKind = SparcOperand::rk_IntReg;
994  return true;
995  }
996  // %sp
997  if (name.equals("sp")) {
998  RegNo = Sparc::O6;
999  RegKind = SparcOperand::rk_IntReg;
1000  return true;
1001  }
1002 
1003  if (name.equals("y")) {
1004  RegNo = Sparc::Y;
1005  RegKind = SparcOperand::rk_Special;
1006  return true;
1007  }
1008 
1009  if (name.substr(0, 3).equals_lower("asr")
1010  && !name.substr(3).getAsInteger(10, intVal)
1011  && intVal > 0 && intVal < 32) {
1012  RegNo = ASRRegs[intVal];
1013  RegKind = SparcOperand::rk_Special;
1014  return true;
1015  }
1016 
1017  // %fprs is an alias of %asr6.
1018  if (name.equals("fprs")) {
1019  RegNo = ASRRegs[6];
1020  RegKind = SparcOperand::rk_Special;
1021  return true;
1022  }
1023 
1024  if (name.equals("icc")) {
1025  RegNo = Sparc::ICC;
1026  RegKind = SparcOperand::rk_Special;
1027  return true;
1028  }
1029 
1030  if (name.equals("psr")) {
1031  RegNo = Sparc::PSR;
1032  RegKind = SparcOperand::rk_Special;
1033  return true;
1034  }
1035 
1036  if (name.equals("fsr")) {
1037  RegNo = Sparc::FSR;
1038  RegKind = SparcOperand::rk_Special;
1039  return true;
1040  }
1041 
1042  if (name.equals("fq")) {
1043  RegNo = Sparc::FQ;
1044  RegKind = SparcOperand::rk_Special;
1045  return true;
1046  }
1047 
1048  if (name.equals("csr")) {
1049  RegNo = Sparc::CPSR;
1050  RegKind = SparcOperand::rk_Special;
1051  return true;
1052  }
1053 
1054  if (name.equals("cq")) {
1055  RegNo = Sparc::CPQ;
1056  RegKind = SparcOperand::rk_Special;
1057  return true;
1058  }
1059 
1060  if (name.equals("wim")) {
1061  RegNo = Sparc::WIM;
1062  RegKind = SparcOperand::rk_Special;
1063  return true;
1064  }
1065 
1066  if (name.equals("tbr")) {
1067  RegNo = Sparc::TBR;
1068  RegKind = SparcOperand::rk_Special;
1069  return true;
1070  }
1071 
1072  if (name.equals("xcc")) {
1073  // FIXME:: check 64bit.
1074  RegNo = Sparc::ICC;
1075  RegKind = SparcOperand::rk_Special;
1076  return true;
1077  }
1078 
1079  // %fcc0 - %fcc3
1080  if (name.substr(0, 3).equals_lower("fcc")
1081  && !name.substr(3).getAsInteger(10, intVal)
1082  && intVal < 4) {
1083  // FIXME: check 64bit and handle %fcc1 - %fcc3
1084  RegNo = Sparc::FCC0 + intVal;
1085  RegKind = SparcOperand::rk_Special;
1086  return true;
1087  }
1088 
1089  // %g0 - %g7
1090  if (name.substr(0, 1).equals_lower("g")
1091  && !name.substr(1).getAsInteger(10, intVal)
1092  && intVal < 8) {
1093  RegNo = IntRegs[intVal];
1094  RegKind = SparcOperand::rk_IntReg;
1095  return true;
1096  }
1097  // %o0 - %o7
1098  if (name.substr(0, 1).equals_lower("o")
1099  && !name.substr(1).getAsInteger(10, intVal)
1100  && intVal < 8) {
1101  RegNo = IntRegs[8 + intVal];
1102  RegKind = SparcOperand::rk_IntReg;
1103  return true;
1104  }
1105  if (name.substr(0, 1).equals_lower("l")
1106  && !name.substr(1).getAsInteger(10, intVal)
1107  && intVal < 8) {
1108  RegNo = IntRegs[16 + intVal];
1109  RegKind = SparcOperand::rk_IntReg;
1110  return true;
1111  }
1112  if (name.substr(0, 1).equals_lower("i")
1113  && !name.substr(1).getAsInteger(10, intVal)
1114  && intVal < 8) {
1115  RegNo = IntRegs[24 + intVal];
1116  RegKind = SparcOperand::rk_IntReg;
1117  return true;
1118  }
1119  // %f0 - %f31
1120  if (name.substr(0, 1).equals_lower("f")
1121  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1122  RegNo = FloatRegs[intVal];
1123  RegKind = SparcOperand::rk_FloatReg;
1124  return true;
1125  }
1126  // %f32 - %f62
1127  if (name.substr(0, 1).equals_lower("f")
1128  && !name.substr(1, 2).getAsInteger(10, intVal)
1129  && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1130  // FIXME: Check V9
1131  RegNo = DoubleRegs[intVal/2];
1132  RegKind = SparcOperand::rk_DoubleReg;
1133  return true;
1134  }
1135 
1136  // %r0 - %r31
1137  if (name.substr(0, 1).equals_lower("r")
1138  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1139  RegNo = IntRegs[intVal];
1140  RegKind = SparcOperand::rk_IntReg;
1141  return true;
1142  }
1143 
1144  // %c0 - %c31
1145  if (name.substr(0, 1).equals_lower("c")
1146  && !name.substr(1).getAsInteger(10, intVal)
1147  && intVal < 32) {
1148  RegNo = CoprocRegs[intVal];
1149  RegKind = SparcOperand::rk_CoprocReg;
1150  return true;
1151  }
1152 
1153  if (name.equals("tpc")) {
1154  RegNo = Sparc::TPC;
1155  RegKind = SparcOperand::rk_Special;
1156  return true;
1157  }
1158  if (name.equals("tnpc")) {
1159  RegNo = Sparc::TNPC;
1160  RegKind = SparcOperand::rk_Special;
1161  return true;
1162  }
1163  if (name.equals("tstate")) {
1164  RegNo = Sparc::TSTATE;
1165  RegKind = SparcOperand::rk_Special;
1166  return true;
1167  }
1168  if (name.equals("tt")) {
1169  RegNo = Sparc::TT;
1170  RegKind = SparcOperand::rk_Special;
1171  return true;
1172  }
1173  if (name.equals("tick")) {
1174  RegNo = Sparc::TICK;
1175  RegKind = SparcOperand::rk_Special;
1176  return true;
1177  }
1178  if (name.equals("tba")) {
1179  RegNo = Sparc::TBA;
1180  RegKind = SparcOperand::rk_Special;
1181  return true;
1182  }
1183  if (name.equals("pstate")) {
1184  RegNo = Sparc::PSTATE;
1185  RegKind = SparcOperand::rk_Special;
1186  return true;
1187  }
1188  if (name.equals("tl")) {
1189  RegNo = Sparc::TL;
1190  RegKind = SparcOperand::rk_Special;
1191  return true;
1192  }
1193  if (name.equals("pil")) {
1194  RegNo = Sparc::PIL;
1195  RegKind = SparcOperand::rk_Special;
1196  return true;
1197  }
1198  if (name.equals("cwp")) {
1199  RegNo = Sparc::CWP;
1200  RegKind = SparcOperand::rk_Special;
1201  return true;
1202  }
1203  if (name.equals("cansave")) {
1204  RegNo = Sparc::CANSAVE;
1205  RegKind = SparcOperand::rk_Special;
1206  return true;
1207  }
1208  if (name.equals("canrestore")) {
1209  RegNo = Sparc::CANRESTORE;
1210  RegKind = SparcOperand::rk_Special;
1211  return true;
1212  }
1213  if (name.equals("cleanwin")) {
1214  RegNo = Sparc::CLEANWIN;
1215  RegKind = SparcOperand::rk_Special;
1216  return true;
1217  }
1218  if (name.equals("otherwin")) {
1219  RegNo = Sparc::OTHERWIN;
1220  RegKind = SparcOperand::rk_Special;
1221  return true;
1222  }
1223  if (name.equals("wstate")) {
1224  RegNo = Sparc::WSTATE;
1225  RegKind = SparcOperand::rk_Special;
1226  return true;
1227  }
1228  }
1229  return false;
1230 }
1231 
1232 // Determine if an expression contains a reference to the symbol
1233 // "_GLOBAL_OFFSET_TABLE_".
1234 static bool hasGOTReference(const MCExpr *Expr) {
1235  switch (Expr->getKind()) {
1236  case MCExpr::Target:
1237  if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1238  return hasGOTReference(SE->getSubExpr());
1239  break;
1240 
1241  case MCExpr::Constant:
1242  break;
1243 
1244  case MCExpr::Binary: {
1245  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1246  return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1247  }
1248 
1249  case MCExpr::SymbolRef: {
1250  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1251  return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1252  }
1253 
1254  case MCExpr::Unary:
1255  return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1256  }
1257  return false;
1258 }
1259 
1260 const SparcMCExpr *
1261 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1262  const MCExpr *subExpr) {
1263  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1264  // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1265  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1266  // as %got10 or %got22 relocation.
1267 
1268  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1269  switch(VK) {
1270  default: break;
1274  break;
1278  break;
1279  }
1280  }
1281 
1282  return SparcMCExpr::create(VK, subExpr, getContext());
1283 }
1284 
1285 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1286  SMLoc &EndLoc) {
1287  AsmToken Tok = Parser.getTok();
1288  if (!Tok.is(AsmToken::Identifier))
1289  return false;
1290 
1291  StringRef name = Tok.getString();
1292 
1294 
1295  if (VK == SparcMCExpr::VK_Sparc_None)
1296  return false;
1297 
1298  Parser.Lex(); // Eat the identifier.
1299  if (Parser.getTok().getKind() != AsmToken::LParen)
1300  return false;
1301 
1302  Parser.Lex(); // Eat the LParen token.
1303  const MCExpr *subExpr;
1304  if (Parser.parseParenExpression(subExpr, EndLoc))
1305  return false;
1306 
1307  EVal = adjustPICRelocation(VK, subExpr);
1308  return true;
1309 }
1310 
1311 extern "C" void LLVMInitializeSparcAsmParser() {
1315 }
1316 
1317 #define GET_REGISTER_MATCHER
1318 #define GET_MATCHER_IMPLEMENTATION
1319 #include "SparcGenAsmMatcher.inc"
1320 
1321 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1322  unsigned Kind) {
1323  SparcOperand &Op = (SparcOperand &)GOp;
1324  if (Op.isFloatOrDoubleReg()) {
1325  switch (Kind) {
1326  default: break;
1327  case MCK_DFPRegs:
1328  if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1330  break;
1331  case MCK_QFPRegs:
1332  if (SparcOperand::MorphToQuadReg(Op))
1334  break;
1335  }
1336  }
1337  if (Op.isIntReg() && Kind == MCK_IntPair) {
1338  if (SparcOperand::MorphToIntPairReg(Op))
1340  }
1341  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1342  if (SparcOperand::MorphToCoprocPairReg(Op))
1344  }
1345  return Match_InvalidOperand;
1346 }
static bool isReg(const MCInst &MI, unsigned OpNo)
uint64_t CallInst * C
bool isImm() const
Definition: MCInst.h:58
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
static const MCPhysReg IntRegs[32]
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:329
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:181
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:109
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:136
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static const MCPhysReg CoprocPairRegs[]
unsigned Reg
bool isReg() const
Definition: MCInst.h:57
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:570
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:33
static const MCPhysReg ASRRegs[32]
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
static const MCPhysReg QuadFPRegs[32]
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
RegisterKind
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
mir Rename Register Operands
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:592
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:125
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:573
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:27
Target & getTheSparcTarget()
const MCExpr * getExpr() const
Definition: MCInst.h:95
Unary expressions.
Definition: MCExpr.h:41
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
void LLVMInitializeSparcAsmParser()
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
int64_t getImm() const
Definition: MCInst.h:75
const char * getPointer() const
Definition: SMLoc.h:34
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
Streaming machine code generation interface.
Definition: MCStreamer.h:196
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Container class for subtarget features.
#define SET(n)
Definition: MD5.cpp:68
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:31
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:23
Target & getTheSparcelTarget()
bool isExpr() const
Definition: MCInst.h:60
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:86
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static bool hasGOTReference(const MCExpr *Expr)
Binary assembler expressions.
Definition: MCExpr.h:423
size_t size() const
Definition: SmallVector.h:52
void setLoc(SMLoc loc)
Definition: MCInst.h:176
#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:492
void setOpcode(unsigned Op)
Definition: MCInst.h:170
const MCSymbol & getSymbol() const
Definition: MCExpr.h:342
ExprKind getKind() const
Definition: MCExpr.h:68
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
static const MCPhysReg CoprocRegs[32]
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static const MCPhysReg IntPairRegs[]
Base class for user error types.
Definition: Error.h:344
Target & getTheSparcV9Target()
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:174
#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:40
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:26
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:204
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Constant expressions.
Definition: MCExpr.h:39
static const MCPhysReg FloatRegs[32]
Binary expressions.
Definition: MCExpr.h:38
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:80
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Target specific expression.
Definition: MCExpr.h:42
Represents a location in source code.
Definition: SMLoc.h:23
unsigned getOpcode() const
Definition: MCInst.h:171
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
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:122
TokenKind getKind() const
Definition: MCAsmMacro.h:81
static const MCPhysReg DoubleRegs[32]