LLVM  15.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"
19 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/SMLoc.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <memory>
38 
39 using namespace llvm;
40 
41 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
42 // namespace. But SPARC backend uses "SP" as its namespace.
43 namespace llvm {
44 namespace Sparc {
45 
46  using namespace SP;
47 
48 } // end namespace Sparc
49 } // end namespace llvm
50 
51 namespace {
52 
53 class SparcOperand;
54 
55 class SparcAsmParser : public MCTargetAsmParser {
56  MCAsmParser &Parser;
57 
58  enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
59 
60  /// @name Auto-generated Match Functions
61  /// {
62 
63 #define GET_ASSEMBLER_HEADER
64 #include "SparcGenAsmMatcher.inc"
65 
66  /// }
67 
68  // public interface of the MCTargetAsmParser.
69  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
72  bool MatchingInlineAsm) override;
73  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
74  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
75  SMLoc &EndLoc) override;
76  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
77  SMLoc NameLoc, OperandVector &Operands) override;
78  bool ParseDirective(AsmToken DirectiveID) override;
79 
80  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
81  unsigned Kind) override;
82 
83  // Custom parse functions for Sparc specific operands.
85 
87 
88  template <TailRelocKind Kind>
89  OperandMatchResultTy parseTailRelocSym(OperandVector &Operands);
90 
91  template <unsigned N>
92  OperandMatchResultTy parseShiftAmtImm(OperandVector &Operands);
93 
95 
97 
99  parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
100  bool isCall = false);
101 
102  OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
103 
104  // Helper function for dealing with %lo / %hi in PIC mode.
105  const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
106  const MCExpr *subExpr);
107 
108  // returns true if Tok is matched to a register and returns register in RegNo.
109  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
110  unsigned &RegKind);
111 
112  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
113 
114  bool is64Bit() const {
115  return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
116  }
117 
118  bool expandSET(MCInst &Inst, SMLoc IDLoc,
120 
121  SMLoc getLoc() const { return getParser().getTok().getLoc(); }
122 
123 public:
124  SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
125  const MCInstrInfo &MII,
126  const MCTargetOptions &Options)
127  : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
128  Parser.addAliasForDirective(".half", ".2byte");
129  Parser.addAliasForDirective(".uahalf", ".2byte");
130  Parser.addAliasForDirective(".word", ".4byte");
131  Parser.addAliasForDirective(".uaword", ".4byte");
132  Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
133  if (is64Bit())
134  Parser.addAliasForDirective(".xword", ".8byte");
135 
136  // Initialize the set of available features.
137  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
138  }
139 };
140 
141 } // end anonymous namespace
142 
143  static const MCPhysReg IntRegs[32] = {
144  Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
145  Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
146  Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
147  Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
148  Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
150  Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
151  Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
152 
153  static const MCPhysReg FloatRegs[32] = {
154  Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
155  Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
156  Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
157  Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
158  Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
159  Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
160  Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
161  Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
162 
163  static const MCPhysReg DoubleRegs[32] = {
164  Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
165  Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
166  Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
167  Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
168  Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
169  Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
170  Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
171  Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
172 
173  static const MCPhysReg QuadFPRegs[32] = {
174  Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
175  Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
176  Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
177  Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
178 
179  static const MCPhysReg ASRRegs[32] = {
180  SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
181  SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
182  SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
183  SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
184  SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
185  SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
186  SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
187  SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
188 
189  static const MCPhysReg IntPairRegs[] = {
190  Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
191  Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
192  Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
193  Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
194 
195  static const MCPhysReg CoprocRegs[32] = {
196  Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
197  Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
198  Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
199  Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
200  Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
201  Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
202  Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
203  Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
204 
205  static const MCPhysReg CoprocPairRegs[] = {
206  Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
207  Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
208  Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
209  Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
210 
211 namespace {
212 
213 /// SparcOperand - Instances of this class represent a parsed Sparc machine
214 /// instruction.
215 class SparcOperand : public MCParsedAsmOperand {
216 public:
217  enum RegisterKind {
218  rk_None,
219  rk_IntReg,
220  rk_IntPairReg,
221  rk_FloatReg,
222  rk_DoubleReg,
223  rk_QuadReg,
224  rk_CoprocReg,
225  rk_CoprocPairReg,
226  rk_Special,
227  };
228 
229 private:
230  enum KindTy {
231  k_Token,
232  k_Register,
233  k_Immediate,
234  k_MemoryReg,
235  k_MemoryImm
236  } Kind;
237 
238  SMLoc StartLoc, EndLoc;
239 
240  struct Token {
241  const char *Data;
242  unsigned Length;
243  };
244 
245  struct RegOp {
246  unsigned RegNum;
247  RegisterKind Kind;
248  };
249 
250  struct ImmOp {
251  const MCExpr *Val;
252  };
253 
254  struct MemOp {
255  unsigned Base;
256  unsigned OffsetReg;
257  const MCExpr *Off;
258  };
259 
260  union {
261  struct Token Tok;
262  struct RegOp Reg;
263  struct ImmOp Imm;
264  struct MemOp Mem;
265  };
266 
267 public:
268  SparcOperand(KindTy K) : Kind(K) {}
269 
270  bool isToken() const override { return Kind == k_Token; }
271  bool isReg() const override { return Kind == k_Register; }
272  bool isImm() const override { return Kind == k_Immediate; }
273  bool isMem() const override { return isMEMrr() || isMEMri(); }
274  bool isMEMrr() const { return Kind == k_MemoryReg; }
275  bool isMEMri() const { return Kind == k_MemoryImm; }
276  bool isMembarTag() const { return Kind == k_Immediate; }
277  bool isTailRelocSym() const { return Kind == k_Immediate; }
278 
279  bool isCallTarget() const {
280  if (!isImm())
281  return false;
282 
283  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
284  return CE->getValue() % 4 == 0;
285 
286  return true;
287  }
288 
289  bool isShiftAmtImm5() const {
290  if (!isImm())
291  return false;
292 
293  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
294  return isUInt<5>(CE->getValue());
295 
296  return false;
297  }
298 
299  bool isShiftAmtImm6() const {
300  if (!isImm())
301  return false;
302 
303  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))
304  return isUInt<6>(CE->getValue());
305 
306  return false;
307  }
308 
309  bool isIntReg() const {
310  return (Kind == k_Register && Reg.Kind == rk_IntReg);
311  }
312 
313  bool isFloatReg() const {
314  return (Kind == k_Register && Reg.Kind == rk_FloatReg);
315  }
316 
317  bool isFloatOrDoubleReg() const {
318  return (Kind == k_Register && (Reg.Kind == rk_FloatReg
319  || Reg.Kind == rk_DoubleReg));
320  }
321 
322  bool isCoprocReg() const {
323  return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
324  }
325 
326  StringRef getToken() const {
327  assert(Kind == k_Token && "Invalid access!");
328  return StringRef(Tok.Data, Tok.Length);
329  }
330 
331  unsigned getReg() const override {
332  assert((Kind == k_Register) && "Invalid access!");
333  return Reg.RegNum;
334  }
335 
336  const MCExpr *getImm() const {
337  assert((Kind == k_Immediate) && "Invalid access!");
338  return Imm.Val;
339  }
340 
341  unsigned getMemBase() const {
342  assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
343  return Mem.Base;
344  }
345 
346  unsigned getMemOffsetReg() const {
347  assert((Kind == k_MemoryReg) && "Invalid access!");
348  return Mem.OffsetReg;
349  }
350 
351  const MCExpr *getMemOff() const {
352  assert((Kind == k_MemoryImm) && "Invalid access!");
353  return Mem.Off;
354  }
355 
356  /// getStartLoc - Get the location of the first token of this operand.
357  SMLoc getStartLoc() const override {
358  return StartLoc;
359  }
360  /// getEndLoc - Get the location of the last token of this operand.
361  SMLoc getEndLoc() const override {
362  return EndLoc;
363  }
364 
365  void print(raw_ostream &OS) const override {
366  switch (Kind) {
367  case k_Token: OS << "Token: " << getToken() << "\n"; break;
368  case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
369  case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
370  case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
371  << getMemOffsetReg() << "\n"; break;
372  case k_MemoryImm: assert(getMemOff() != nullptr);
373  OS << "Mem: " << getMemBase()
374  << "+" << *getMemOff()
375  << "\n"; break;
376  }
377  }
378 
379  void addRegOperands(MCInst &Inst, unsigned N) const {
380  assert(N == 1 && "Invalid number of operands!");
382  }
383 
384  void addImmOperands(MCInst &Inst, unsigned N) const {
385  assert(N == 1 && "Invalid number of operands!");
386  const MCExpr *Expr = getImm();
387  addExpr(Inst, Expr);
388  }
389 
390  void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {
391  assert(N == 1 && "Invalid number of operands!");
392  addExpr(Inst, getImm());
393  }
394  void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {
395  assert(N == 1 && "Invalid number of operands!");
396  addExpr(Inst, getImm());
397  }
398 
399  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
400  // Add as immediate when possible. Null MCExpr = 0.
401  if (!Expr)
403  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
404  Inst.addOperand(MCOperand::createImm(CE->getValue()));
405  else
406  Inst.addOperand(MCOperand::createExpr(Expr));
407  }
408 
409  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
410  assert(N == 2 && "Invalid number of operands!");
411 
412  Inst.addOperand(MCOperand::createReg(getMemBase()));
413 
414  assert(getMemOffsetReg() != 0 && "Invalid offset");
415  Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
416  }
417 
418  void addMEMriOperands(MCInst &Inst, unsigned N) const {
419  assert(N == 2 && "Invalid number of operands!");
420 
421  Inst.addOperand(MCOperand::createReg(getMemBase()));
422 
423  const MCExpr *Expr = getMemOff();
424  addExpr(Inst, Expr);
425  }
426 
427  void addMembarTagOperands(MCInst &Inst, unsigned N) const {
428  assert(N == 1 && "Invalid number of operands!");
429  const MCExpr *Expr = getImm();
430  addExpr(Inst, Expr);
431  }
432 
433  void addCallTargetOperands(MCInst &Inst, unsigned N) const {
434  assert(N == 1 && "Invalid number of operands!");
435  addExpr(Inst, getImm());
436  }
437 
438  void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
439  assert(N == 1 && "Invalid number of operands!");
440  addExpr(Inst, getImm());
441  }
442 
443  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
444  auto Op = std::make_unique<SparcOperand>(k_Token);
445  Op->Tok.Data = Str.data();
446  Op->Tok.Length = Str.size();
447  Op->StartLoc = S;
448  Op->EndLoc = S;
449  return Op;
450  }
451 
452  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
453  SMLoc S, SMLoc E) {
454  auto Op = std::make_unique<SparcOperand>(k_Register);
455  Op->Reg.RegNum = RegNum;
456  Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
457  Op->StartLoc = S;
458  Op->EndLoc = E;
459  return Op;
460  }
461 
462  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
463  SMLoc E) {
464  auto Op = std::make_unique<SparcOperand>(k_Immediate);
465  Op->Imm.Val = Val;
466  Op->StartLoc = S;
467  Op->EndLoc = E;
468  return Op;
469  }
470 
471  static bool MorphToIntPairReg(SparcOperand &Op) {
472  unsigned Reg = Op.getReg();
473  assert(Op.Reg.Kind == rk_IntReg);
474  unsigned regIdx = 32;
475  if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
476  regIdx = Reg - Sparc::G0;
477  else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
478  regIdx = Reg - Sparc::O0 + 8;
479  else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
480  regIdx = Reg - Sparc::L0 + 16;
481  else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
482  regIdx = Reg - Sparc::I0 + 24;
483  if (regIdx % 2 || regIdx > 31)
484  return false;
485  Op.Reg.RegNum = IntPairRegs[regIdx / 2];
486  Op.Reg.Kind = rk_IntPairReg;
487  return true;
488  }
489 
490  static bool MorphToDoubleReg(SparcOperand &Op) {
491  unsigned Reg = Op.getReg();
492  assert(Op.Reg.Kind == rk_FloatReg);
493  unsigned regIdx = Reg - Sparc::F0;
494  if (regIdx % 2 || regIdx > 31)
495  return false;
496  Op.Reg.RegNum = DoubleRegs[regIdx / 2];
497  Op.Reg.Kind = rk_DoubleReg;
498  return true;
499  }
500 
501  static bool MorphToQuadReg(SparcOperand &Op) {
502  unsigned Reg = Op.getReg();
503  unsigned regIdx = 0;
504  switch (Op.Reg.Kind) {
505  default: llvm_unreachable("Unexpected register kind!");
506  case rk_FloatReg:
507  regIdx = Reg - Sparc::F0;
508  if (regIdx % 4 || regIdx > 31)
509  return false;
510  Reg = QuadFPRegs[regIdx / 4];
511  break;
512  case rk_DoubleReg:
513  regIdx = Reg - Sparc::D0;
514  if (regIdx % 2 || regIdx > 31)
515  return false;
516  Reg = QuadFPRegs[regIdx / 2];
517  break;
518  }
519  Op.Reg.RegNum = Reg;
520  Op.Reg.Kind = rk_QuadReg;
521  return true;
522  }
523 
524  static bool MorphToCoprocPairReg(SparcOperand &Op) {
525  unsigned Reg = Op.getReg();
526  assert(Op.Reg.Kind == rk_CoprocReg);
527  unsigned regIdx = 32;
528  if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
529  regIdx = Reg - Sparc::C0;
530  if (regIdx % 2 || regIdx > 31)
531  return false;
532  Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
533  Op.Reg.Kind = rk_CoprocPairReg;
534  return true;
535  }
536 
537  static std::unique_ptr<SparcOperand>
538  MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
539  unsigned offsetReg = Op->getReg();
540  Op->Kind = k_MemoryReg;
541  Op->Mem.Base = Base;
542  Op->Mem.OffsetReg = offsetReg;
543  Op->Mem.Off = nullptr;
544  return Op;
545  }
546 
547  static std::unique_ptr<SparcOperand>
548  CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
549  auto Op = std::make_unique<SparcOperand>(k_MemoryReg);
550  Op->Mem.Base = Base;
551  Op->Mem.OffsetReg = Sparc::G0; // always 0
552  Op->Mem.Off = nullptr;
553  Op->StartLoc = S;
554  Op->EndLoc = E;
555  return Op;
556  }
557 
558  static std::unique_ptr<SparcOperand>
559  MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
560  const MCExpr *Imm = Op->getImm();
561  Op->Kind = k_MemoryImm;
562  Op->Mem.Base = Base;
563  Op->Mem.OffsetReg = 0;
564  Op->Mem.Off = Imm;
565  return Op;
566  }
567 };
568 
569 } // end anonymous namespace
570 
571 bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
573  MCOperand MCRegOp = Inst.getOperand(0);
574  MCOperand MCValOp = Inst.getOperand(1);
575  assert(MCRegOp.isReg());
576  assert(MCValOp.isImm() || MCValOp.isExpr());
577 
578  // the imm operand can be either an expression or an immediate.
579  bool IsImm = Inst.getOperand(1).isImm();
580  int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
581 
582  // Allow either a signed or unsigned 32-bit immediate.
583  if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
584  return Error(IDLoc,
585  "set: argument must be between -2147483648 and 4294967295");
586  }
587 
588  // If the value was expressed as a large unsigned number, that's ok.
589  // We want to see if it "looks like" a small signed number.
590  int32_t ImmValue = RawImmValue;
591  // For 'set' you can't use 'or' with a negative operand on V9 because
592  // that would splat the sign bit across the upper half of the destination
593  // register, whereas 'set' is defined to zero the high 32 bits.
594  bool IsEffectivelyImm13 =
595  IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
596  const MCExpr *ValExpr;
597  if (IsImm)
598  ValExpr = MCConstantExpr::create(ImmValue, getContext());
599  else
600  ValExpr = MCValOp.getExpr();
601 
602  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
603 
604  // If not just a signed imm13 value, then either we use a 'sethi' with a
605  // following 'or', or a 'sethi' by itself if there are no more 1 bits.
606  // In either case, start with the 'sethi'.
607  if (!IsEffectivelyImm13) {
608  MCInst TmpInst;
609  const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
610  TmpInst.setLoc(IDLoc);
611  TmpInst.setOpcode(SP::SETHIi);
612  TmpInst.addOperand(MCRegOp);
613  TmpInst.addOperand(MCOperand::createExpr(Expr));
614  Instructions.push_back(TmpInst);
615  PrevReg = MCRegOp;
616  }
617 
618  // The low bits require touching in 3 cases:
619  // * A non-immediate value will always require both instructions.
620  // * An effectively imm13 value needs only an 'or' instruction.
621  // * Otherwise, an immediate that is not effectively imm13 requires the
622  // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
623  // If the low bits are known zeros, there's nothing to do.
624  // In the second case, and only in that case, must we NOT clear
625  // bits of the immediate value via the %lo() assembler function.
626  // Note also, the 'or' instruction doesn't mind a large value in the case
627  // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
628  if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
629  MCInst TmpInst;
630  const MCExpr *Expr;
631  if (IsEffectivelyImm13)
632  Expr = ValExpr;
633  else
634  Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
635  TmpInst.setLoc(IDLoc);
636  TmpInst.setOpcode(SP::ORri);
637  TmpInst.addOperand(MCRegOp);
638  TmpInst.addOperand(PrevReg);
639  TmpInst.addOperand(MCOperand::createExpr(Expr));
640  Instructions.push_back(TmpInst);
641  }
642  return false;
643 }
644 
645 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
647  MCStreamer &Out,
649  bool MatchingInlineAsm) {
650  MCInst Inst;
652  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
653  MatchingInlineAsm);
654  switch (MatchResult) {
655  case Match_Success: {
656  switch (Inst.getOpcode()) {
657  default:
658  Inst.setLoc(IDLoc);
659  Instructions.push_back(Inst);
660  break;
661  case SP::SET:
662  if (expandSET(Inst, IDLoc, Instructions))
663  return true;
664  break;
665  }
666 
667  for (const MCInst &I : Instructions) {
668  Out.emitInstruction(I, getSTI());
669  }
670  return false;
671  }
672 
673  case Match_MissingFeature:
674  return Error(IDLoc,
675  "instruction requires a CPU feature not currently enabled");
676 
677  case Match_InvalidOperand: {
678  SMLoc ErrorLoc = IDLoc;
679  if (ErrorInfo != ~0ULL) {
680  if (ErrorInfo >= Operands.size())
681  return Error(IDLoc, "too few operands for instruction");
682 
683  ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
684  if (ErrorLoc == SMLoc())
685  ErrorLoc = IDLoc;
686  }
687 
688  return Error(ErrorLoc, "invalid operand for instruction");
689  }
690  case Match_MnemonicFail:
691  return Error(IDLoc, "invalid instruction mnemonic");
692  }
693  llvm_unreachable("Implement any new match types added!");
694 }
695 
696 bool SparcAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
697  SMLoc &EndLoc) {
698  if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
699  return Error(StartLoc, "invalid register name");
700  return false;
701 }
702 
703 OperandMatchResultTy SparcAsmParser::tryParseRegister(unsigned &RegNo,
704  SMLoc &StartLoc,
705  SMLoc &EndLoc) {
706  const AsmToken &Tok = Parser.getTok();
707  StartLoc = Tok.getLoc();
708  EndLoc = Tok.getEndLoc();
709  RegNo = 0;
710  if (getLexer().getKind() != AsmToken::Percent)
711  return MatchOperand_NoMatch;
712  Parser.Lex();
713  unsigned regKind = SparcOperand::rk_None;
714  if (matchRegisterName(Tok, RegNo, regKind)) {
715  Parser.Lex();
716  return MatchOperand_Success;
717  }
718 
719  getLexer().UnLex(Tok);
720  return MatchOperand_NoMatch;
721 }
722 
723 static void applyMnemonicAliases(StringRef &Mnemonic,
724  const FeatureBitset &Features,
725  unsigned VariantID);
726 
727 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
728  StringRef Name, SMLoc NameLoc,
730 
731  // First operand in MCInst is instruction mnemonic.
732  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
733 
734  // apply mnemonic aliases, if any, so that we can parse operands correctly.
735  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
736 
737  if (getLexer().isNot(AsmToken::EndOfStatement)) {
738  // Read the first operand.
739  if (getLexer().is(AsmToken::Comma)) {
740  if (parseBranchModifiers(Operands) != MatchOperand_Success) {
741  SMLoc Loc = getLexer().getLoc();
742  return Error(Loc, "unexpected token");
743  }
744  }
745  if (parseOperand(Operands, Name) != MatchOperand_Success) {
746  SMLoc Loc = getLexer().getLoc();
747  return Error(Loc, "unexpected token");
748  }
749 
750  while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
751  if (getLexer().is(AsmToken::Plus)) {
752  // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
753  Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
754  }
755  Parser.Lex(); // Eat the comma or plus.
756  // Parse and remember the operand.
757  if (parseOperand(Operands, Name) != MatchOperand_Success) {
758  SMLoc Loc = getLexer().getLoc();
759  return Error(Loc, "unexpected token");
760  }
761  }
762  }
763  if (getLexer().isNot(AsmToken::EndOfStatement)) {
764  SMLoc Loc = getLexer().getLoc();
765  return Error(Loc, "unexpected token");
766  }
767  Parser.Lex(); // Consume the EndOfStatement.
768  return false;
769 }
770 
771 bool SparcAsmParser::
772 ParseDirective(AsmToken DirectiveID)
773 {
774  StringRef IDVal = DirectiveID.getString();
775 
776  if (IDVal == ".register") {
777  // For now, ignore .register directive.
778  Parser.eatToEndOfStatement();
779  return false;
780  }
781  if (IDVal == ".proc") {
782  // For compatibility, ignore this directive.
783  // (It's supposed to be an "optimization" in the Sun assembler)
784  Parser.eatToEndOfStatement();
785  return false;
786  }
787 
788  // Let the MC layer to handle other directives.
789  return true;
790 }
791 
793 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
794  SMLoc S, E;
795 
796  std::unique_ptr<SparcOperand> LHS;
797  if (parseSparcAsmOperand(LHS) != MatchOperand_Success)
798  return MatchOperand_NoMatch;
799 
800  // Single immediate operand
801  if (LHS->isImm()) {
802  Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
803  return MatchOperand_Success;
804  }
805 
806  if (!LHS->isIntReg()) {
807  Error(LHS->getStartLoc(), "invalid register kind for this operand");
808  return MatchOperand_ParseFail;
809  }
810 
811  AsmToken Tok = getLexer().getTok();
812  // The plus token may be followed by a register or an immediate value, the
813  // minus one is always interpreted as sign for the immediate value
814  if (Tok.is(AsmToken::Plus) || Tok.is(AsmToken::Minus)) {
815  (void)Parser.parseOptionalToken(AsmToken::Plus);
816 
817  std::unique_ptr<SparcOperand> RHS;
818  if (parseSparcAsmOperand(RHS) != MatchOperand_Success)
819  return MatchOperand_NoMatch;
820 
821  if (RHS->isReg() && !RHS->isIntReg()) {
822  Error(RHS->getStartLoc(), "invalid register kind for this operand");
823  return MatchOperand_ParseFail;
824  }
825 
826  Operands.push_back(
827  RHS->isImm()
828  ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))
829  : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));
830 
831  return MatchOperand_Success;
832  }
833 
834  Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));
835  return MatchOperand_Success;
836 }
837 
838 template <unsigned N>
839 OperandMatchResultTy SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {
840  SMLoc S = Parser.getTok().getLoc();
841  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
842 
843  // This is a register, not an immediate
844  if (getLexer().getKind() == AsmToken::Percent)
845  return MatchOperand_NoMatch;
846 
847  const MCExpr *Expr;
848  if (getParser().parseExpression(Expr))
849  return MatchOperand_ParseFail;
850 
851  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
852  if (!CE) {
853  Error(S, "constant expression expected");
854  return MatchOperand_ParseFail;
855  }
856 
857  if (!isUInt<N>(CE->getValue())) {
858  Error(S, "immediate shift value out of range");
859  return MatchOperand_ParseFail;
860  }
861 
862  Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
863  return MatchOperand_Success;
864 }
865 
866 template <SparcAsmParser::TailRelocKind Kind>
868 SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
869  SMLoc S = getLoc();
870  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
871 
872  auto MatchesKind = [](SparcMCExpr::VariantKind VK) -> bool {
873  switch (Kind) {
874  case TailRelocKind::Load_GOT:
875  // Non-TLS relocations on ld (or ldx).
876  // ld [%rr + %rr], %rr, %rel(sym)
878  case TailRelocKind::Add_TLS:
879  // TLS relocations on add.
880  // add %rr, %rr, %rr, %rel(sym)
881  switch (VK) {
886  return true;
887  default:
888  return false;
889  }
890  case TailRelocKind::Load_TLS:
891  // TLS relocations on ld (or ldx).
892  // ld[x] %addr, %rr, %rel(sym)
893  switch (VK) {
896  return true;
897  default:
898  return false;
899  }
900  case TailRelocKind::Call_TLS:
901  // TLS relocations on call.
902  // call sym, %rel(sym)
903  switch (VK) {
906  return true;
907  default:
908  return false;
909  }
910  }
911  llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
912  };
913 
914  if (getLexer().getKind() != AsmToken::Percent) {
915  Error(getLoc(), "expected '%' for operand modifier");
916  return MatchOperand_ParseFail;
917  }
918 
919  const AsmToken Tok = Parser.getTok();
920  getParser().Lex(); // Eat '%'
921 
922  if (getLexer().getKind() != AsmToken::Identifier) {
923  Error(getLoc(), "expected valid identifier for operand modifier");
924  return MatchOperand_ParseFail;
925  }
926 
927  StringRef Name = getParser().getTok().getIdentifier();
929  if (VK == SparcMCExpr::VK_Sparc_None) {
930  Error(getLoc(), "invalid operand modifier");
931  return MatchOperand_ParseFail;
932  }
933 
934  if (!MatchesKind(VK)) {
935  // Did not match the specified set of relocation types, put '%' back.
936  getLexer().UnLex(Tok);
937  return MatchOperand_NoMatch;
938  }
939 
940  Parser.Lex(); // Eat the identifier.
941  if (getLexer().getKind() != AsmToken::LParen) {
942  Error(getLoc(), "expected '('");
943  return MatchOperand_ParseFail;
944  }
945 
946  getParser().Lex(); // Eat '('
947  const MCExpr *SubExpr;
948  if (getParser().parseParenExpression(SubExpr, E)) {
949  return MatchOperand_ParseFail;
950  }
951 
952  const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
953  Operands.push_back(SparcOperand::CreateImm(Val, S, E));
954  return MatchOperand_Success;
955 }
956 
957 OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
958  SMLoc S = Parser.getTok().getLoc();
959  const MCExpr *EVal;
960  int64_t ImmVal = 0;
961 
962  std::unique_ptr<SparcOperand> Mask;
963  if (parseSparcAsmOperand(Mask) == MatchOperand_Success) {
964  if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
965  ImmVal < 0 || ImmVal > 127) {
966  Error(S, "invalid membar mask number");
967  return MatchOperand_ParseFail;
968  }
969  }
970 
971  while (getLexer().getKind() == AsmToken::Hash) {
972  SMLoc TagStart = getLexer().getLoc();
973  Parser.Lex(); // Eat the '#'.
974  unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
975  .Case("LoadLoad", 0x1)
976  .Case("StoreLoad", 0x2)
977  .Case("LoadStore", 0x4)
978  .Case("StoreStore", 0x8)
979  .Case("Lookaside", 0x10)
980  .Case("MemIssue", 0x20)
981  .Case("Sync", 0x40)
982  .Default(0);
983 
984  Parser.Lex(); // Eat the identifier token.
985 
986  if (!MaskVal) {
987  Error(TagStart, "unknown membar tag");
988  return MatchOperand_ParseFail;
989  }
990 
991  ImmVal |= MaskVal;
992 
993  if (getLexer().getKind() == AsmToken::Pipe)
994  Parser.Lex(); // Eat the '|'.
995  }
996 
997  EVal = MCConstantExpr::create(ImmVal, getContext());
998  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
999  Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1000  return MatchOperand_Success;
1001 }
1002 
1003 OperandMatchResultTy SparcAsmParser::parseCallTarget(OperandVector &Operands) {
1004  SMLoc S = Parser.getTok().getLoc();
1005  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1006 
1007  switch (getLexer().getKind()) {
1008  default:
1009  return MatchOperand_NoMatch;
1010  case AsmToken::LParen:
1011  case AsmToken::Integer:
1012  case AsmToken::Identifier:
1013  case AsmToken::Dot:
1014  break;
1015  }
1016 
1017  const MCExpr *DestValue;
1018  if (getParser().parseExpression(DestValue))
1019  return MatchOperand_NoMatch;
1020 
1021  bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent();
1024 
1025  const MCExpr *DestExpr = SparcMCExpr::create(Kind, DestValue, getContext());
1026  Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E));
1027  return MatchOperand_Success;
1028 }
1029 
1031 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1032 
1033  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1034 
1035  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1036  // there was a match, but an error occurred, in which case, just return that
1037  // the operand parsing failed.
1038  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
1039  return ResTy;
1040 
1041  if (getLexer().is(AsmToken::LBrac)) {
1042  // Memory operand
1043  Operands.push_back(SparcOperand::CreateToken("[",
1044  Parser.getTok().getLoc()));
1045  Parser.Lex(); // Eat the [
1046 
1047  if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
1048  SMLoc S = Parser.getTok().getLoc();
1049  if (getLexer().getKind() != AsmToken::Percent)
1050  return MatchOperand_NoMatch;
1051  Parser.Lex(); // eat %
1052 
1053  unsigned RegNo, RegKind;
1054  if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
1055  return MatchOperand_NoMatch;
1056 
1057  Parser.Lex(); // Eat the identifier token.
1059  Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
1060  ResTy = MatchOperand_Success;
1061  } else {
1062  ResTy = parseMEMOperand(Operands);
1063  }
1064 
1065  if (ResTy != MatchOperand_Success)
1066  return ResTy;
1067 
1068  if (!getLexer().is(AsmToken::RBrac))
1069  return MatchOperand_ParseFail;
1070 
1071  Operands.push_back(SparcOperand::CreateToken("]",
1072  Parser.getTok().getLoc()));
1073  Parser.Lex(); // Eat the ]
1074 
1075  // Parse an optional address-space identifier after the address.
1076  if (getLexer().is(AsmToken::Integer)) {
1077  std::unique_ptr<SparcOperand> Op;
1078  ResTy = parseSparcAsmOperand(Op, false);
1079  if (ResTy != MatchOperand_Success || !Op)
1080  return MatchOperand_ParseFail;
1081  Operands.push_back(std::move(Op));
1082  }
1083  return MatchOperand_Success;
1084  }
1085 
1086  std::unique_ptr<SparcOperand> Op;
1087 
1088  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
1089  if (ResTy != MatchOperand_Success || !Op)
1090  return MatchOperand_ParseFail;
1091 
1092  // Push the parsed operand into the list of operands
1093  Operands.push_back(std::move(Op));
1094 
1095  return MatchOperand_Success;
1096 }
1097 
1099 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
1100  bool isCall) {
1101  SMLoc S = Parser.getTok().getLoc();
1102  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1103  const MCExpr *EVal;
1104 
1105  Op = nullptr;
1106  switch (getLexer().getKind()) {
1107  default: break;
1108 
1109  case AsmToken::Percent:
1110  Parser.Lex(); // Eat the '%'.
1111  unsigned RegNo;
1112  unsigned RegKind;
1113  if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
1114  StringRef name = Parser.getTok().getString();
1115  Parser.Lex(); // Eat the identifier token.
1116  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1117  switch (RegNo) {
1118  default:
1119  Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
1120  break;
1121  case Sparc::PSR:
1122  Op = SparcOperand::CreateToken("%psr", S);
1123  break;
1124  case Sparc::FSR:
1125  Op = SparcOperand::CreateToken("%fsr", S);
1126  break;
1127  case Sparc::FQ:
1128  Op = SparcOperand::CreateToken("%fq", S);
1129  break;
1130  case Sparc::CPSR:
1131  Op = SparcOperand::CreateToken("%csr", S);
1132  break;
1133  case Sparc::CPQ:
1134  Op = SparcOperand::CreateToken("%cq", S);
1135  break;
1136  case Sparc::WIM:
1137  Op = SparcOperand::CreateToken("%wim", S);
1138  break;
1139  case Sparc::TBR:
1140  Op = SparcOperand::CreateToken("%tbr", S);
1141  break;
1142  case Sparc::PC:
1143  Op = SparcOperand::CreateToken("%pc", S);
1144  break;
1145  case Sparc::ICC:
1146  if (name == "xcc")
1147  Op = SparcOperand::CreateToken("%xcc", S);
1148  else
1149  Op = SparcOperand::CreateToken("%icc", S);
1150  break;
1151  }
1152  break;
1153  }
1154  if (matchSparcAsmModifiers(EVal, E)) {
1155  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1156  Op = SparcOperand::CreateImm(EVal, S, E);
1157  }
1158  break;
1159 
1160  case AsmToken::Plus:
1161  case AsmToken::Minus:
1162  case AsmToken::Integer:
1163  case AsmToken::LParen:
1164  case AsmToken::Dot:
1165  case AsmToken::Identifier:
1166  if (getParser().parseExpression(EVal, E))
1167  break;
1168 
1169  int64_t Res;
1170  if (!EVal->evaluateAsAbsolute(Res)) {
1172 
1173  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1174  if (isCall)
1176  else
1178  }
1179  EVal = SparcMCExpr::create(Kind, EVal, getContext());
1180  }
1181  Op = SparcOperand::CreateImm(EVal, S, E);
1182  break;
1183  }
1185 }
1186 
1188 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
1189  // parse (,a|,pn|,pt)+
1190 
1191  while (getLexer().is(AsmToken::Comma)) {
1192  Parser.Lex(); // Eat the comma
1193 
1194  if (!getLexer().is(AsmToken::Identifier))
1195  return MatchOperand_ParseFail;
1196  StringRef modName = Parser.getTok().getString();
1197  if (modName == "a" || modName == "pn" || modName == "pt") {
1198  Operands.push_back(SparcOperand::CreateToken(modName,
1199  Parser.getTok().getLoc()));
1200  Parser.Lex(); // eat the identifier.
1201  }
1202  }
1203  return MatchOperand_Success;
1204 }
1205 
1206 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
1207  unsigned &RegKind) {
1208  int64_t intVal = 0;
1209  RegNo = 0;
1210  RegKind = SparcOperand::rk_None;
1211  if (Tok.is(AsmToken::Identifier)) {
1212  StringRef name = Tok.getString();
1213 
1214  // %fp
1215  if (name.equals("fp")) {
1216  RegNo = Sparc::I6;
1217  RegKind = SparcOperand::rk_IntReg;
1218  return true;
1219  }
1220  // %sp
1221  if (name.equals("sp")) {
1222  RegNo = Sparc::O6;
1223  RegKind = SparcOperand::rk_IntReg;
1224  return true;
1225  }
1226 
1227  if (name.equals("y")) {
1228  RegNo = Sparc::Y;
1229  RegKind = SparcOperand::rk_Special;
1230  return true;
1231  }
1232 
1233  if (name.substr(0, 3).equals_insensitive("asr") &&
1234  !name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) {
1235  RegNo = ASRRegs[intVal];
1236  RegKind = SparcOperand::rk_Special;
1237  return true;
1238  }
1239 
1240  // %fprs is an alias of %asr6.
1241  if (name.equals("fprs")) {
1242  RegNo = ASRRegs[6];
1243  RegKind = SparcOperand::rk_Special;
1244  return true;
1245  }
1246 
1247  if (name.equals("icc")) {
1248  RegNo = Sparc::ICC;
1249  RegKind = SparcOperand::rk_Special;
1250  return true;
1251  }
1252 
1253  if (name.equals("psr")) {
1254  RegNo = Sparc::PSR;
1255  RegKind = SparcOperand::rk_Special;
1256  return true;
1257  }
1258 
1259  if (name.equals("fsr")) {
1260  RegNo = Sparc::FSR;
1261  RegKind = SparcOperand::rk_Special;
1262  return true;
1263  }
1264 
1265  if (name.equals("fq")) {
1266  RegNo = Sparc::FQ;
1267  RegKind = SparcOperand::rk_Special;
1268  return true;
1269  }
1270 
1271  if (name.equals("csr")) {
1272  RegNo = Sparc::CPSR;
1273  RegKind = SparcOperand::rk_Special;
1274  return true;
1275  }
1276 
1277  if (name.equals("cq")) {
1278  RegNo = Sparc::CPQ;
1279  RegKind = SparcOperand::rk_Special;
1280  return true;
1281  }
1282 
1283  if (name.equals("wim")) {
1284  RegNo = Sparc::WIM;
1285  RegKind = SparcOperand::rk_Special;
1286  return true;
1287  }
1288 
1289  if (name.equals("tbr")) {
1290  RegNo = Sparc::TBR;
1291  RegKind = SparcOperand::rk_Special;
1292  return true;
1293  }
1294 
1295  if (name.equals("xcc")) {
1296  // FIXME:: check 64bit.
1297  RegNo = Sparc::ICC;
1298  RegKind = SparcOperand::rk_Special;
1299  return true;
1300  }
1301 
1302  // %fcc0 - %fcc3
1303  if (name.substr(0, 3).equals_insensitive("fcc") &&
1304  !name.substr(3).getAsInteger(10, intVal) && intVal < 4) {
1305  // FIXME: check 64bit and handle %fcc1 - %fcc3
1306  RegNo = Sparc::FCC0 + intVal;
1307  RegKind = SparcOperand::rk_Special;
1308  return true;
1309  }
1310 
1311  // %g0 - %g7
1312  if (name.substr(0, 1).equals_insensitive("g") &&
1313  !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1314  RegNo = IntRegs[intVal];
1315  RegKind = SparcOperand::rk_IntReg;
1316  return true;
1317  }
1318  // %o0 - %o7
1319  if (name.substr(0, 1).equals_insensitive("o") &&
1320  !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1321  RegNo = IntRegs[8 + intVal];
1322  RegKind = SparcOperand::rk_IntReg;
1323  return true;
1324  }
1325  if (name.substr(0, 1).equals_insensitive("l") &&
1326  !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1327  RegNo = IntRegs[16 + intVal];
1328  RegKind = SparcOperand::rk_IntReg;
1329  return true;
1330  }
1331  if (name.substr(0, 1).equals_insensitive("i") &&
1332  !name.substr(1).getAsInteger(10, intVal) && intVal < 8) {
1333  RegNo = IntRegs[24 + intVal];
1334  RegKind = SparcOperand::rk_IntReg;
1335  return true;
1336  }
1337  // %f0 - %f31
1338  if (name.substr(0, 1).equals_insensitive("f") &&
1339  !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1340  RegNo = FloatRegs[intVal];
1341  RegKind = SparcOperand::rk_FloatReg;
1342  return true;
1343  }
1344  // %f32 - %f62
1345  if (name.substr(0, 1).equals_insensitive("f") &&
1346  !name.substr(1, 2).getAsInteger(10, intVal) && intVal >= 32 &&
1347  intVal <= 62 && (intVal % 2 == 0)) {
1348  // FIXME: Check V9
1349  RegNo = DoubleRegs[intVal/2];
1350  RegKind = SparcOperand::rk_DoubleReg;
1351  return true;
1352  }
1353 
1354  // %r0 - %r31
1355  if (name.substr(0, 1).equals_insensitive("r") &&
1356  !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1357  RegNo = IntRegs[intVal];
1358  RegKind = SparcOperand::rk_IntReg;
1359  return true;
1360  }
1361 
1362  // %c0 - %c31
1363  if (name.substr(0, 1).equals_insensitive("c") &&
1364  !name.substr(1).getAsInteger(10, intVal) && intVal < 32) {
1365  RegNo = CoprocRegs[intVal];
1366  RegKind = SparcOperand::rk_CoprocReg;
1367  return true;
1368  }
1369 
1370  if (name.equals("tpc")) {
1371  RegNo = Sparc::TPC;
1372  RegKind = SparcOperand::rk_Special;
1373  return true;
1374  }
1375  if (name.equals("tnpc")) {
1376  RegNo = Sparc::TNPC;
1377  RegKind = SparcOperand::rk_Special;
1378  return true;
1379  }
1380  if (name.equals("tstate")) {
1381  RegNo = Sparc::TSTATE;
1382  RegKind = SparcOperand::rk_Special;
1383  return true;
1384  }
1385  if (name.equals("tt")) {
1386  RegNo = Sparc::TT;
1387  RegKind = SparcOperand::rk_Special;
1388  return true;
1389  }
1390  if (name.equals("tick")) {
1391  RegNo = Sparc::TICK;
1392  RegKind = SparcOperand::rk_Special;
1393  return true;
1394  }
1395  if (name.equals("tba")) {
1396  RegNo = Sparc::TBA;
1397  RegKind = SparcOperand::rk_Special;
1398  return true;
1399  }
1400  if (name.equals("pstate")) {
1401  RegNo = Sparc::PSTATE;
1402  RegKind = SparcOperand::rk_Special;
1403  return true;
1404  }
1405  if (name.equals("tl")) {
1406  RegNo = Sparc::TL;
1407  RegKind = SparcOperand::rk_Special;
1408  return true;
1409  }
1410  if (name.equals("pil")) {
1411  RegNo = Sparc::PIL;
1412  RegKind = SparcOperand::rk_Special;
1413  return true;
1414  }
1415  if (name.equals("cwp")) {
1416  RegNo = Sparc::CWP;
1417  RegKind = SparcOperand::rk_Special;
1418  return true;
1419  }
1420  if (name.equals("cansave")) {
1421  RegNo = Sparc::CANSAVE;
1422  RegKind = SparcOperand::rk_Special;
1423  return true;
1424  }
1425  if (name.equals("canrestore")) {
1426  RegNo = Sparc::CANRESTORE;
1427  RegKind = SparcOperand::rk_Special;
1428  return true;
1429  }
1430  if (name.equals("cleanwin")) {
1431  RegNo = Sparc::CLEANWIN;
1432  RegKind = SparcOperand::rk_Special;
1433  return true;
1434  }
1435  if (name.equals("otherwin")) {
1436  RegNo = Sparc::OTHERWIN;
1437  RegKind = SparcOperand::rk_Special;
1438  return true;
1439  }
1440  if (name.equals("wstate")) {
1441  RegNo = Sparc::WSTATE;
1442  RegKind = SparcOperand::rk_Special;
1443  return true;
1444  }
1445  if (name.equals("pc")) {
1446  RegNo = Sparc::PC;
1447  RegKind = SparcOperand::rk_Special;
1448  return true;
1449  }
1450  }
1451  return false;
1452 }
1453 
1454 // Determine if an expression contains a reference to the symbol
1455 // "_GLOBAL_OFFSET_TABLE_".
1456 static bool hasGOTReference(const MCExpr *Expr) {
1457  switch (Expr->getKind()) {
1458  case MCExpr::Target:
1459  if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1460  return hasGOTReference(SE->getSubExpr());
1461  break;
1462 
1463  case MCExpr::Constant:
1464  break;
1465 
1466  case MCExpr::Binary: {
1467  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1468  return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1469  }
1470 
1471  case MCExpr::SymbolRef: {
1472  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1473  return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1474  }
1475 
1476  case MCExpr::Unary:
1477  return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1478  }
1479  return false;
1480 }
1481 
1482 const SparcMCExpr *
1483 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1484  const MCExpr *subExpr) {
1485  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1486  // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is
1487  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1488  // as %got10 or %got22 relocation.
1489 
1490  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1491  switch(VK) {
1492  default: break;
1496  break;
1500  break;
1501  }
1502  }
1503 
1504  return SparcMCExpr::create(VK, subExpr, getContext());
1505 }
1506 
1507 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1508  SMLoc &EndLoc) {
1509  AsmToken Tok = Parser.getTok();
1510  if (!Tok.is(AsmToken::Identifier))
1511  return false;
1512 
1513  StringRef name = Tok.getString();
1514 
1516  switch (VK) {
1518  Error(getLoc(), "invalid operand modifier");
1519  return false;
1520 
1530  // These are special-cased at tablegen level.
1531  return false;
1532 
1533  default:
1534  break;
1535  }
1536 
1537  Parser.Lex(); // Eat the identifier.
1538  if (Parser.getTok().getKind() != AsmToken::LParen)
1539  return false;
1540 
1541  Parser.Lex(); // Eat the LParen token.
1542  const MCExpr *subExpr;
1543  if (Parser.parseParenExpression(subExpr, EndLoc))
1544  return false;
1545 
1546  EVal = adjustPICRelocation(VK, subExpr);
1547  return true;
1548 }
1549 
1554 }
1555 
1556 #define GET_REGISTER_MATCHER
1557 #define GET_MATCHER_IMPLEMENTATION
1558 #include "SparcGenAsmMatcher.inc"
1559 
1560 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1561  unsigned Kind) {
1562  SparcOperand &Op = (SparcOperand &)GOp;
1563  if (Op.isFloatOrDoubleReg()) {
1564  switch (Kind) {
1565  default: break;
1566  case MCK_DFPRegs:
1567  if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1569  break;
1570  case MCK_QFPRegs:
1571  if (SparcOperand::MorphToQuadReg(Op))
1573  break;
1574  }
1575  }
1576  if (Op.isIntReg() && Kind == MCK_IntPair) {
1577  if (SparcOperand::MorphToIntPairReg(Op))
1579  }
1580  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1581  if (SparcOperand::MorphToCoprocPairReg(Op))
1583  }
1584  return Match_InvalidOperand;
1585 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm::MCAsmParser
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:124
L5
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp which is much esp edx eax decl edx jle L7 L5
Definition: README.txt:656
is
should just be implemented with a CLZ instruction Since there are other e that share this it would be best to implement this in a target independent as zero is the default value for the binary encoder e add r0 add r5 Register operands should be distinct That is
Definition: README.txt:725
SparcTargetInfo.h
llvm::SparcMCExpr::VK_Sparc_TLS_IE_ADD
@ VK_Sparc_TLS_IE_ADD
Definition: SparcMCExpr.h:59
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::AsmToken::is
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
SET
#define SET(ID, TYPE, VAL)
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition: MCParsedAsmOperand.h:24
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::AsmToken::LBrac
@ LBrac
Definition: MCAsmMacro.h:48
StringRef.h
llvm::AsmToken::Dot
@ Dot
Definition: MCAsmMacro.h:49
SparcMCTargetDesc.h
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:183
is64Bit
static bool is64Bit(const char *name)
Definition: X86Disassembler.cpp:1018
llvm::SparcMCExpr::VK_Sparc_GOTDATA_OP
@ VK_Sparc_GOTDATA_OP
Definition: SparcMCExpr.h:66
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition: MCAsmMacro.h:42
C1
instcombine should handle this C2 when C1
Definition: README.txt:263
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::SparcMCExpr::VK_Sparc_None
@ VK_Sparc_None
Definition: SparcMCExpr.h:26
MCParsedAsmOperand.h
ErrorHandling.h
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::SparcMCExpr::VK_Sparc_TLS_LDO_ADD
@ VK_Sparc_TLS_LDO_ADD
Definition: SparcMCExpr.h:54
llvm::getTheSparcTarget
Target & getTheSparcTarget()
Definition: SparcTargetInfo.cpp:13
FloatRegs
static const MCPhysReg FloatRegs[32]
Definition: SparcAsmParser.cpp:153
llvm::MemOp
Definition: TargetLowering.h:111
MCObjectFileInfo.h
Instructions
Code Generation Notes for reduce the size of the ISel and reduce repetition in the implementation In a small number of this can cause even when no optimisation has taken place Instructions
Definition: MSA.txt:11
llvm::AsmToken::Integer
@ Integer
Definition: MCAsmMacro.h:32
llvm::MCAsmParser::parseOptionalToken
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
Definition: MCAsmParser.cpp:78
addCallTargetOperands
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info)
Definition: AMDGPUCallLowering.cpp:945
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
llvm::SparcMCExpr::VK_Sparc_TLS_LDM_ADD
@ VK_Sparc_TLS_LDM_ADD
Definition: SparcMCExpr.h:50
llvm::SparcMCExpr
Definition: SparcMCExpr.h:23
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::MCBinaryExpr
Binary assembler expressions.
Definition: MCExpr.h:481
MCAsmParser.h
MCTargetAsmParser.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::SparcMCExpr::parseVariantKind
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:93
llvm::AsmToken
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
I1
@ I1
Definition: DXILOpLowering.cpp:37
isImm
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
Definition: SPIRVInstructionSelector.cpp:982
llvm::SparcMCExpr::VK_Sparc_TLS_GD_CALL
@ VK_Sparc_TLS_GD_CALL
Definition: SparcMCExpr.h:47
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
llvm::AsmToken::Minus
@ Minus
Definition: MCAsmMacro.h:45
llvm::AsmToken::LParen
@ LParen
Definition: MCAsmMacro.h:48
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::MCAsmParser::Lex
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
hasGOTReference
static bool hasGOTReference(const MCExpr *Expr)
Definition: SparcAsmParser.cpp:1456
llvm::Triple::sparcv9
@ sparcv9
Definition: Triple.h:78
llvm::SparcMCExpr::VK_Sparc_TLS_LDM_CALL
@ VK_Sparc_TLS_LDM_CALL
Definition: SparcMCExpr.h:51
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition: TargetRegistry.h:1360
llvm::MatchOperand_Success
@ MatchOperand_Success
Definition: MCTargetAsmParser.h:127
L2
add sub stmia L5 ldr L2
Definition: README.txt:201
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
getReg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:517
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
L3
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx L3
Definition: README-X86-64.txt:22
llvm::MCExpr::Target
@ Target
Target specific expression.
Definition: MCExpr.h:42
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::SparcMCExpr::create
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:27
LLVMInitializeSparcAsmParser
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
Definition: SparcAsmParser.cpp:1550
MCContext.h
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCSymbol.h
SparcMCExpr.h
CoprocPairRegs
static const MCPhysReg CoprocPairRegs[]
Definition: SparcAsmParser.cpp:205
MCInst.h
llvm::MCBinaryExpr::getRHS
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:631
llvm::getTheSparcelTarget
Target & getTheSparcelTarget()
Definition: SparcTargetInfo.cpp:21
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MCSubtargetInfo.h
SMLoc.h
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::MCAsmParser::addAliasForDirective
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
llvm::MCSymbolRefExpr::getSymbol
const MCSymbol & getSymbol() const
Definition: MCExpr.h:399
llvm::AsmToken::getKind
TokenKind getKind() const
Definition: MCAsmMacro.h:81
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
llvm::MCExpr::getKind
ExprKind getKind() const
Definition: MCExpr.h:81
isNot
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Definition: AMDGPULegalizerInfo.cpp:3219
llvm::AsmToken::Percent
@ Percent
Definition: MCAsmMacro.h:52
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
L6
gets compiled into this on rsp movaps rsp movaps rsp movaps rsp movaps rsp movaps rsp movaps rsp movaps rsp movaps rsp movq rsp movq rsp movq rsp movq rsp movq rsp rax movq rsp rax movq rsp rsp rsp eax eax jbe LBB1_3 rcx rax movq rsp eax rsp ret ecx eax rcx movl rsp jmp LBB1_2 gcc rsp rax movq rsp rsp movq rsp rax movq rsp eax eax jb L6 rdx eax rsp ret p2align L6
Definition: README.txt:1168
llvm::MCExpr::Binary
@ Binary
Binary expressions.
Definition: MCExpr.h:38
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:74
llvm::MCConstantExpr
Definition: MCExpr.h:144
x2
gcc mainline compiles it x2(%rip)
llvm::SparcMCExpr::VK_Sparc_GOT13
@ VK_Sparc_GOT13
Definition: SparcMCExpr.h:39
MCAsmLexer.h
llvm::SparcMCExpr::VK_Sparc_TLS_IE_LDX
@ VK_Sparc_TLS_IE_LDX
Definition: SparcMCExpr.h:58
llvm::SparcMCExpr::VK_Sparc_PC22
@ VK_Sparc_PC22
Definition: SparcMCExpr.h:35
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::ParseInstructionInfo
Definition: MCTargetAsmParser.h:118
uint64_t
llvm::SparcMCExpr::VK_Sparc_GOT22
@ VK_Sparc_GOT22
Definition: SparcMCExpr.h:37
llvm::SparcMCExpr::VK_Sparc_TLS_IE_LD
@ VK_Sparc_TLS_IE_LD
Definition: SparcMCExpr.h:57
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:126
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1096
llvm::MatchOperand_ParseFail
@ MatchOperand_ParseFail
Definition: MCTargetAsmParser.h:129
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MCPhysReg
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:21
MCRegisterInfo.h
llvm::SparcMCExpr::VariantKind
VariantKind
Definition: SparcMCExpr.h:25
llvm::MCAsmParser::parseParenExpression
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
llvm::SparcMCExpr::VK_Sparc_PC10
@ VK_Sparc_PC10
Definition: SparcMCExpr.h:36
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::HexagonMCInstrInfo::isIntReg
bool isIntReg(unsigned Reg)
Definition: HexagonMCInstrInfo.cpp:652
DoubleRegs
static const MCPhysReg DoubleRegs[32]
Definition: SparcAsmParser.cpp:163
llvm::SparcMCExpr::VK_Sparc_13
@ VK_Sparc_13
Definition: SparcMCExpr.h:40
llvm::WinEH::EncodingType::CE
@ CE
Windows NT (Windows on ARM)
applyMnemonicAliases
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
llvm::SparcMCExpr::VK_Sparc_WDISP30
@ VK_Sparc_WDISP30
Definition: SparcMCExpr.h:42
llvm::ErrorInfo
Base class for user error types.
Definition: Error.h:347
llvm::SparcMCExpr::VK_Sparc_GOT10
@ VK_Sparc_GOT10
Definition: SparcMCExpr.h:38
llvm::MCTargetOptions
Definition: MCTargetOptions.h:42
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
llvm::AMDGPU::IsaInfo::TargetIDSetting::Off
@ Off
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition: MipsInstPrinter.cpp:31
llvm::AsmToken::Comma
@ Comma
Definition: MCAsmMacro.h:49
Triple.h
IntRegs
static const MCPhysReg IntRegs[32]
Definition: SparcAsmParser.cpp:143
llvm::MatchOperand_NoMatch
@ MatchOperand_NoMatch
Definition: MCTargetAsmParser.h:128
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MCAsmParser::getTok
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:38
llvm::AsmToken::Plus
@ Plus
Definition: MCAsmMacro.h:45
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
A
* A
Definition: README_ALTIVEC.txt:89
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::SparcMCExpr::VK_Sparc_WPLT30
@ VK_Sparc_WPLT30
Definition: SparcMCExpr.h:41
llvm::SparcMCExpr::VK_Sparc_HI
@ VK_Sparc_HI
Definition: SparcMCExpr.h:28
llvm::AsmToken::getString
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
llvm::MCTargetAsmParser::Match_Success
@ Match_Success
Definition: MCTargetAsmParser.h:321
llvm::OperandMatchResultTy
OperandMatchResultTy
Definition: MCTargetAsmParser.h:126
L4
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp which is much esp edx eax decl edx jle L7 esp ret eax ja L5 L4
Definition: README.txt:662
llvm::MCAsmParser::eatToEndOfStatement
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
llvm::SparcMCExpr::VK_Sparc_TLS_GD_ADD
@ VK_Sparc_TLS_GD_ADD
Definition: SparcMCExpr.h:46
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
llvm::AsmToken::Pipe
@ Pipe
Definition: MCAsmMacro.h:51
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition: MCInst.h:203
llvm::AsmToken::Identifier
@ Identifier
Definition: MCAsmMacro.h:28
llvm::SMLoc::getPointer
const char * getPointer() const
Definition: SMLoc.h:34
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:345
Casting.h
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
llvm::AsmToken::RBrac
@ RBrac
Definition: MCAsmMacro.h:48
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCTargetAsmParser
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Definition: MCTargetAsmParser.h:314
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
QuadFPRegs
static const MCPhysReg QuadFPRegs[32]
Definition: SparcAsmParser.cpp:173
llvm::RISCVISD::FSR
@ FSR
Definition: RISCVISelLowering.h:82
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
L7
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp which is much esp edx eax decl edx jle L7 esp ret L7
Definition: README.txt:658
SmallVector.h
llvm::MCExpr::SymbolRef
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
llvm::MCExpr::Unary
@ Unary
Unary expressions.
Definition: MCExpr.h:41
N
#define N
MCStreamer.h
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::MCExpr::Constant
@ Constant
Constant expressions.
Definition: MCExpr.h:39
llvm::isMem
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:131
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
ASRRegs
static const MCPhysReg ASRRegs[32]
Definition: SparcAsmParser.cpp:179
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::SparcMCExpr::VK_Sparc_LO
@ VK_Sparc_LO
Definition: SparcMCExpr.h:27
raw_ostream.h
llvm::AsmToken::Hash
@ Hash
Definition: MCAsmMacro.h:52
llvm::AsmToken::getLoc
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
llvm::AsmToken::getEndLoc
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
TargetRegistry.h
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
CoprocRegs
static const MCPhysReg CoprocRegs[32]
Definition: SparcAsmParser.cpp:195
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::getTheSparcV9Target
Target & getTheSparcV9Target()
Definition: SparcTargetInfo.cpp:17
IntPairRegs
static const MCPhysReg IntPairRegs[]
Definition: SparcAsmParser.cpp:189
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::MCBinaryExpr::getLHS
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:628