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