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