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