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