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, uint64_t Features,
649  unsigned VariantID);
650 
651 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
652  StringRef Name, SMLoc NameLoc,
653  OperandVector &Operands) {
654 
655  // First operand in MCInst is instruction mnemonic.
656  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
657 
658  // apply mnemonic aliases, if any, so that we can parse operands correctly.
659  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
660 
661  if (getLexer().isNot(AsmToken::EndOfStatement)) {
662  // Read the first operand.
663  if (getLexer().is(AsmToken::Comma)) {
664  if (parseBranchModifiers(Operands) != MatchOperand_Success) {
665  SMLoc Loc = getLexer().getLoc();
666  return Error(Loc, "unexpected token");
667  }
668  }
669  if (parseOperand(Operands, Name) != MatchOperand_Success) {
670  SMLoc Loc = getLexer().getLoc();
671  return Error(Loc, "unexpected token");
672  }
673 
674  while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
675  if (getLexer().is(AsmToken::Plus)) {
676  // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
677  Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
678  }
679  Parser.Lex(); // Eat the comma or plus.
680  // Parse and remember the operand.
681  if (parseOperand(Operands, Name) != MatchOperand_Success) {
682  SMLoc Loc = getLexer().getLoc();
683  return Error(Loc, "unexpected token");
684  }
685  }
686  }
687  if (getLexer().isNot(AsmToken::EndOfStatement)) {
688  SMLoc Loc = getLexer().getLoc();
689  return Error(Loc, "unexpected token");
690  }
691  Parser.Lex(); // Consume the EndOfStatement.
692  return false;
693 }
694 
695 bool SparcAsmParser::
696 ParseDirective(AsmToken DirectiveID)
697 {
698  StringRef IDVal = DirectiveID.getString();
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 
717 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
718  SMLoc S, E;
719  unsigned BaseReg = 0;
720 
721  if (ParseRegister(BaseReg, S, E)) {
722  return MatchOperand_NoMatch;
723  }
724 
725  switch (getLexer().getKind()) {
726  default: return MatchOperand_NoMatch;
727 
728  case AsmToken::Comma:
729  case AsmToken::RBrac:
731  Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
732  return MatchOperand_Success;
733 
734  case AsmToken:: Plus:
735  Parser.Lex(); // Eat the '+'
736  break;
737  case AsmToken::Minus:
738  break;
739  }
740 
741  std::unique_ptr<SparcOperand> Offset;
742  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
743  if (ResTy != MatchOperand_Success || !Offset)
744  return MatchOperand_NoMatch;
745 
746  Operands.push_back(
747  Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
748  : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
749 
750  return MatchOperand_Success;
751 }
752 
753 OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
754  SMLoc S = Parser.getTok().getLoc();
755  const MCExpr *EVal;
756  int64_t ImmVal = 0;
757 
758  std::unique_ptr<SparcOperand> Mask;
759  if (parseSparcAsmOperand(Mask) == MatchOperand_Success) {
760  if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
761  ImmVal < 0 || ImmVal > 127) {
762  Error(S, "invalid membar mask number");
763  return MatchOperand_ParseFail;
764  }
765  }
766 
767  while (getLexer().getKind() == AsmToken::Hash) {
768  SMLoc TagStart = getLexer().getLoc();
769  Parser.Lex(); // Eat the '#'.
770  unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
771  .Case("LoadLoad", 0x1)
772  .Case("StoreLoad", 0x2)
773  .Case("LoadStore", 0x4)
774  .Case("StoreStore", 0x8)
775  .Case("Lookaside", 0x10)
776  .Case("MemIssue", 0x20)
777  .Case("Sync", 0x40)
778  .Default(0);
779 
780  Parser.Lex(); // Eat the identifier token.
781 
782  if (!MaskVal) {
783  Error(TagStart, "unknown membar tag");
784  return MatchOperand_ParseFail;
785  }
786 
787  ImmVal |= MaskVal;
788 
789  if (getLexer().getKind() == AsmToken::Pipe)
790  Parser.Lex(); // Eat the '|'.
791  }
792 
793  EVal = MCConstantExpr::create(ImmVal, getContext());
794  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
795  Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
796  return MatchOperand_Success;
797 }
798 
800 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
801 
802  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
803 
804  // If there wasn't a custom match, try the generic matcher below. Otherwise,
805  // there was a match, but an error occurred, in which case, just return that
806  // the operand parsing failed.
807  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
808  return ResTy;
809 
810  if (getLexer().is(AsmToken::LBrac)) {
811  // Memory operand
812  Operands.push_back(SparcOperand::CreateToken("[",
813  Parser.getTok().getLoc()));
814  Parser.Lex(); // Eat the [
815 
816  if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
817  SMLoc S = Parser.getTok().getLoc();
818  if (getLexer().getKind() != AsmToken::Percent)
819  return MatchOperand_NoMatch;
820  Parser.Lex(); // eat %
821 
822  unsigned RegNo, RegKind;
823  if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
824  return MatchOperand_NoMatch;
825 
826  Parser.Lex(); // Eat the identifier token.
828  Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
829  ResTy = MatchOperand_Success;
830  } else {
831  ResTy = parseMEMOperand(Operands);
832  }
833 
834  if (ResTy != MatchOperand_Success)
835  return ResTy;
836 
837  if (!getLexer().is(AsmToken::RBrac))
838  return MatchOperand_ParseFail;
839 
840  Operands.push_back(SparcOperand::CreateToken("]",
841  Parser.getTok().getLoc()));
842  Parser.Lex(); // Eat the ]
843 
844  // Parse an optional address-space identifier after the address.
845  if (getLexer().is(AsmToken::Integer)) {
846  std::unique_ptr<SparcOperand> Op;
847  ResTy = parseSparcAsmOperand(Op, false);
848  if (ResTy != MatchOperand_Success || !Op)
849  return MatchOperand_ParseFail;
850  Operands.push_back(std::move(Op));
851  }
852  return MatchOperand_Success;
853  }
854 
855  std::unique_ptr<SparcOperand> Op;
856 
857  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
858  if (ResTy != MatchOperand_Success || !Op)
859  return MatchOperand_ParseFail;
860 
861  // Push the parsed operand into the list of operands
862  Operands.push_back(std::move(Op));
863 
864  return MatchOperand_Success;
865 }
866 
868 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
869  bool isCall) {
870  SMLoc S = Parser.getTok().getLoc();
871  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
872  const MCExpr *EVal;
873 
874  Op = nullptr;
875  switch (getLexer().getKind()) {
876  default: break;
877 
878  case AsmToken::Percent:
879  Parser.Lex(); // Eat the '%'.
880  unsigned RegNo;
881  unsigned RegKind;
882  if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
883  StringRef name = Parser.getTok().getString();
884  Parser.Lex(); // Eat the identifier token.
885  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
886  switch (RegNo) {
887  default:
888  Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
889  break;
890  case Sparc::PSR:
891  Op = SparcOperand::CreateToken("%psr", S);
892  break;
893  case Sparc::FSR:
894  Op = SparcOperand::CreateToken("%fsr", S);
895  break;
896  case Sparc::FQ:
897  Op = SparcOperand::CreateToken("%fq", S);
898  break;
899  case Sparc::CPSR:
900  Op = SparcOperand::CreateToken("%csr", S);
901  break;
902  case Sparc::CPQ:
903  Op = SparcOperand::CreateToken("%cq", S);
904  break;
905  case Sparc::WIM:
906  Op = SparcOperand::CreateToken("%wim", S);
907  break;
908  case Sparc::TBR:
909  Op = SparcOperand::CreateToken("%tbr", S);
910  break;
911  case Sparc::ICC:
912  if (name == "xcc")
913  Op = SparcOperand::CreateToken("%xcc", S);
914  else
915  Op = SparcOperand::CreateToken("%icc", S);
916  break;
917  }
918  break;
919  }
920  if (matchSparcAsmModifiers(EVal, E)) {
921  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
922  Op = SparcOperand::CreateImm(EVal, S, E);
923  }
924  break;
925 
926  case AsmToken::Minus:
927  case AsmToken::Integer:
928  case AsmToken::LParen:
929  case AsmToken::Dot:
930  if (!getParser().parseExpression(EVal, E))
931  Op = SparcOperand::CreateImm(EVal, S, E);
932  break;
933 
934  case AsmToken::Identifier: {
936  if (!getParser().parseIdentifier(Identifier)) {
937  E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
938  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
939 
941  getContext());
943 
944  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
945  if (isCall)
947  else
949  }
950 
951  Res = SparcMCExpr::create(Kind, Res, getContext());
952 
953  Op = SparcOperand::CreateImm(Res, S, E);
954  }
955  break;
956  }
957  }
959 }
960 
962 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
963  // parse (,a|,pn|,pt)+
964 
965  while (getLexer().is(AsmToken::Comma)) {
966  Parser.Lex(); // Eat the comma
967 
968  if (!getLexer().is(AsmToken::Identifier))
969  return MatchOperand_ParseFail;
970  StringRef modName = Parser.getTok().getString();
971  if (modName == "a" || modName == "pn" || modName == "pt") {
972  Operands.push_back(SparcOperand::CreateToken(modName,
973  Parser.getTok().getLoc()));
974  Parser.Lex(); // eat the identifier.
975  }
976  }
977  return MatchOperand_Success;
978 }
979 
980 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
981  unsigned &RegKind) {
982  int64_t intVal = 0;
983  RegNo = 0;
984  RegKind = SparcOperand::rk_None;
985  if (Tok.is(AsmToken::Identifier)) {
986  StringRef name = Tok.getString();
987 
988  // %fp
989  if (name.equals("fp")) {
990  RegNo = Sparc::I6;
991  RegKind = SparcOperand::rk_IntReg;
992  return true;
993  }
994  // %sp
995  if (name.equals("sp")) {
996  RegNo = Sparc::O6;
997  RegKind = SparcOperand::rk_IntReg;
998  return true;
999  }
1000 
1001  if (name.equals("y")) {
1002  RegNo = Sparc::Y;
1003  RegKind = SparcOperand::rk_Special;
1004  return true;
1005  }
1006 
1007  if (name.substr(0, 3).equals_lower("asr")
1008  && !name.substr(3).getAsInteger(10, intVal)
1009  && intVal > 0 && intVal < 32) {
1010  RegNo = ASRRegs[intVal];
1011  RegKind = SparcOperand::rk_Special;
1012  return true;
1013  }
1014 
1015  // %fprs is an alias of %asr6.
1016  if (name.equals("fprs")) {
1017  RegNo = ASRRegs[6];
1018  RegKind = SparcOperand::rk_Special;
1019  return true;
1020  }
1021 
1022  if (name.equals("icc")) {
1023  RegNo = Sparc::ICC;
1024  RegKind = SparcOperand::rk_Special;
1025  return true;
1026  }
1027 
1028  if (name.equals("psr")) {
1029  RegNo = Sparc::PSR;
1030  RegKind = SparcOperand::rk_Special;
1031  return true;
1032  }
1033 
1034  if (name.equals("fsr")) {
1035  RegNo = Sparc::FSR;
1036  RegKind = SparcOperand::rk_Special;
1037  return true;
1038  }
1039 
1040  if (name.equals("fq")) {
1041  RegNo = Sparc::FQ;
1042  RegKind = SparcOperand::rk_Special;
1043  return true;
1044  }
1045 
1046  if (name.equals("csr")) {
1047  RegNo = Sparc::CPSR;
1048  RegKind = SparcOperand::rk_Special;
1049  return true;
1050  }
1051 
1052  if (name.equals("cq")) {
1053  RegNo = Sparc::CPQ;
1054  RegKind = SparcOperand::rk_Special;
1055  return true;
1056  }
1057 
1058  if (name.equals("wim")) {
1059  RegNo = Sparc::WIM;
1060  RegKind = SparcOperand::rk_Special;
1061  return true;
1062  }
1063 
1064  if (name.equals("tbr")) {
1065  RegNo = Sparc::TBR;
1066  RegKind = SparcOperand::rk_Special;
1067  return true;
1068  }
1069 
1070  if (name.equals("xcc")) {
1071  // FIXME:: check 64bit.
1072  RegNo = Sparc::ICC;
1073  RegKind = SparcOperand::rk_Special;
1074  return true;
1075  }
1076 
1077  // %fcc0 - %fcc3
1078  if (name.substr(0, 3).equals_lower("fcc")
1079  && !name.substr(3).getAsInteger(10, intVal)
1080  && intVal < 4) {
1081  // FIXME: check 64bit and handle %fcc1 - %fcc3
1082  RegNo = Sparc::FCC0 + intVal;
1083  RegKind = SparcOperand::rk_Special;
1084  return true;
1085  }
1086 
1087  // %g0 - %g7
1088  if (name.substr(0, 1).equals_lower("g")
1089  && !name.substr(1).getAsInteger(10, intVal)
1090  && intVal < 8) {
1091  RegNo = IntRegs[intVal];
1092  RegKind = SparcOperand::rk_IntReg;
1093  return true;
1094  }
1095  // %o0 - %o7
1096  if (name.substr(0, 1).equals_lower("o")
1097  && !name.substr(1).getAsInteger(10, intVal)
1098  && intVal < 8) {
1099  RegNo = IntRegs[8 + intVal];
1100  RegKind = SparcOperand::rk_IntReg;
1101  return true;
1102  }
1103  if (name.substr(0, 1).equals_lower("l")
1104  && !name.substr(1).getAsInteger(10, intVal)
1105  && intVal < 8) {
1106  RegNo = IntRegs[16 + intVal];
1107  RegKind = SparcOperand::rk_IntReg;
1108  return true;
1109  }
1110  if (name.substr(0, 1).equals_lower("i")
1111  && !name.substr(1).getAsInteger(10, intVal)
1112  && intVal < 8) {
1113  RegNo = IntRegs[24 + intVal];
1114  RegKind = SparcOperand::rk_IntReg;
1115  return true;
1116  }
1117  // %f0 - %f31
1118  if (name.substr(0, 1).equals_lower("f")
1119  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1120  RegNo = FloatRegs[intVal];
1121  RegKind = SparcOperand::rk_FloatReg;
1122  return true;
1123  }
1124  // %f32 - %f62
1125  if (name.substr(0, 1).equals_lower("f")
1126  && !name.substr(1, 2).getAsInteger(10, intVal)
1127  && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1128  // FIXME: Check V9
1129  RegNo = DoubleRegs[intVal/2];
1130  RegKind = SparcOperand::rk_DoubleReg;
1131  return true;
1132  }
1133 
1134  // %r0 - %r31
1135  if (name.substr(0, 1).equals_lower("r")
1136  && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1137  RegNo = IntRegs[intVal];
1138  RegKind = SparcOperand::rk_IntReg;
1139  return true;
1140  }
1141 
1142  // %c0 - %c31
1143  if (name.substr(0, 1).equals_lower("c")
1144  && !name.substr(1).getAsInteger(10, intVal)
1145  && intVal < 32) {
1146  RegNo = CoprocRegs[intVal];
1147  RegKind = SparcOperand::rk_CoprocReg;
1148  return true;
1149  }
1150 
1151  if (name.equals("tpc")) {
1152  RegNo = Sparc::TPC;
1153  RegKind = SparcOperand::rk_Special;
1154  return true;
1155  }
1156  if (name.equals("tnpc")) {
1157  RegNo = Sparc::TNPC;
1158  RegKind = SparcOperand::rk_Special;
1159  return true;
1160  }
1161  if (name.equals("tstate")) {
1162  RegNo = Sparc::TSTATE;
1163  RegKind = SparcOperand::rk_Special;
1164  return true;
1165  }
1166  if (name.equals("tt")) {
1167  RegNo = Sparc::TT;
1168  RegKind = SparcOperand::rk_Special;
1169  return true;
1170  }
1171  if (name.equals("tick")) {
1172  RegNo = Sparc::TICK;
1173  RegKind = SparcOperand::rk_Special;
1174  return true;
1175  }
1176  if (name.equals("tba")) {
1177  RegNo = Sparc::TBA;
1178  RegKind = SparcOperand::rk_Special;
1179  return true;
1180  }
1181  if (name.equals("pstate")) {
1182  RegNo = Sparc::PSTATE;
1183  RegKind = SparcOperand::rk_Special;
1184  return true;
1185  }
1186  if (name.equals("tl")) {
1187  RegNo = Sparc::TL;
1188  RegKind = SparcOperand::rk_Special;
1189  return true;
1190  }
1191  if (name.equals("pil")) {
1192  RegNo = Sparc::PIL;
1193  RegKind = SparcOperand::rk_Special;
1194  return true;
1195  }
1196  if (name.equals("cwp")) {
1197  RegNo = Sparc::CWP;
1198  RegKind = SparcOperand::rk_Special;
1199  return true;
1200  }
1201  if (name.equals("cansave")) {
1202  RegNo = Sparc::CANSAVE;
1203  RegKind = SparcOperand::rk_Special;
1204  return true;
1205  }
1206  if (name.equals("canrestore")) {
1207  RegNo = Sparc::CANRESTORE;
1208  RegKind = SparcOperand::rk_Special;
1209  return true;
1210  }
1211  if (name.equals("cleanwin")) {
1212  RegNo = Sparc::CLEANWIN;
1213  RegKind = SparcOperand::rk_Special;
1214  return true;
1215  }
1216  if (name.equals("otherwin")) {
1217  RegNo = Sparc::OTHERWIN;
1218  RegKind = SparcOperand::rk_Special;
1219  return true;
1220  }
1221  if (name.equals("wstate")) {
1222  RegNo = Sparc::WSTATE;
1223  RegKind = SparcOperand::rk_Special;
1224  return true;
1225  }
1226  }
1227  return false;
1228 }
1229 
1230 // Determine if an expression contains a reference to the symbol
1231 // "_GLOBAL_OFFSET_TABLE_".
1232 static bool hasGOTReference(const MCExpr *Expr) {
1233  switch (Expr->getKind()) {
1234  case MCExpr::Target:
1235  if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1236  return hasGOTReference(SE->getSubExpr());
1237  break;
1238 
1239  case MCExpr::Constant:
1240  break;
1241 
1242  case MCExpr::Binary: {
1243  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1244  return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1245  }
1246 
1247  case MCExpr::SymbolRef: {
1248  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1249  return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1250  }
1251 
1252  case MCExpr::Unary:
1253  return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1254  }
1255  return false;
1256 }
1257 
1258 const SparcMCExpr *
1259 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1260  const MCExpr *subExpr) {
1261  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1262  // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1263  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1264  // as %got10 or %got22 relocation.
1265 
1266  if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1267  switch(VK) {
1268  default: break;
1272  break;
1276  break;
1277  }
1278  }
1279 
1280  return SparcMCExpr::create(VK, subExpr, getContext());
1281 }
1282 
1283 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1284  SMLoc &EndLoc) {
1285  AsmToken Tok = Parser.getTok();
1286  if (!Tok.is(AsmToken::Identifier))
1287  return false;
1288 
1289  StringRef name = Tok.getString();
1290 
1292 
1293  if (VK == SparcMCExpr::VK_Sparc_None)
1294  return false;
1295 
1296  Parser.Lex(); // Eat the identifier.
1297  if (Parser.getTok().getKind() != AsmToken::LParen)
1298  return false;
1299 
1300  Parser.Lex(); // Eat the LParen token.
1301  const MCExpr *subExpr;
1302  if (Parser.parseParenExpression(subExpr, EndLoc))
1303  return false;
1304 
1305  EVal = adjustPICRelocation(VK, subExpr);
1306  return true;
1307 }
1308 
1309 extern "C" void LLVMInitializeSparcAsmParser() {
1313 }
1314 
1315 #define GET_REGISTER_MATCHER
1316 #define GET_MATCHER_IMPLEMENTATION
1317 #include "SparcGenAsmMatcher.inc"
1318 
1319 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1320  unsigned Kind) {
1321  SparcOperand &Op = (SparcOperand &)GOp;
1322  if (Op.isFloatOrDoubleReg()) {
1323  switch (Kind) {
1324  default: break;
1325  case MCK_DFPRegs:
1326  if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1328  break;
1329  case MCK_QFPRegs:
1330  if (SparcOperand::MorphToQuadReg(Op))
1332  break;
1333  }
1334  }
1335  if (Op.isIntReg() && Kind == MCK_IntPair) {
1336  if (SparcOperand::MorphToIntPairReg(Op))
1338  }
1339  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1340  if (SparcOperand::MorphToCoprocPairReg(Op))
1342  }
1343  return Match_InvalidOperand;
1344 }
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:322
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
const FeatureBitset Features
bool isReg() const
Definition: MCInst.h:57
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:563
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:955
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
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: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:160
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:566
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")
#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:416
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:335
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:839
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
const unsigned Kind
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
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]