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