LLVM  17.0.0git
SystemZAsmParser.cpp
Go to the documentation of this file.
1 //===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "SystemZTargetStreamer.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCInstrInfo.h"
28 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/TargetRegistry.h"
31 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/SMLoc.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstddef>
37 #include <cstdint>
38 #include <iterator>
39 #include <memory>
40 #include <string>
41 
42 using namespace llvm;
43 
44 // Return true if Expr is in the range [MinValue, MaxValue]. If AllowSymbol
45 // is true any MCExpr is accepted (address displacement).
46 static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
47  bool AllowSymbol = false) {
48  if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
49  int64_t Value = CE->getValue();
50  return Value >= MinValue && Value <= MaxValue;
51  }
52  return AllowSymbol;
53 }
54 
55 namespace {
56 
57 enum RegisterKind {
58  GR32Reg,
59  GRH32Reg,
60  GR64Reg,
61  GR128Reg,
62  FP32Reg,
63  FP64Reg,
64  FP128Reg,
65  VR32Reg,
66  VR64Reg,
67  VR128Reg,
68  AR32Reg,
69  CR64Reg,
70 };
71 
72 enum MemoryKind {
73  BDMem,
74  BDXMem,
75  BDLMem,
76  BDRMem,
77  BDVMem
78 };
79 
80 class SystemZOperand : public MCParsedAsmOperand {
81 private:
82  enum OperandKind {
83  KindInvalid,
84  KindToken,
85  KindReg,
86  KindImm,
87  KindImmTLS,
88  KindMem
89  };
90 
91  OperandKind Kind;
92  SMLoc StartLoc, EndLoc;
93 
94  // A string of length Length, starting at Data.
95  struct TokenOp {
96  const char *Data;
97  unsigned Length;
98  };
99 
100  // LLVM register Num, which has kind Kind. In some ways it might be
101  // easier for this class to have a register bank (general, floating-point
102  // or access) and a raw register number (0-15). This would postpone the
103  // interpretation of the operand to the add*() methods and avoid the need
104  // for context-dependent parsing. However, we do things the current way
105  // because of the virtual getReg() method, which needs to distinguish
106  // between (say) %r0 used as a single register and %r0 used as a pair.
107  // Context-dependent parsing can also give us slightly better error
108  // messages when invalid pairs like %r1 are used.
109  struct RegOp {
110  RegisterKind Kind;
111  unsigned Num;
112  };
113 
114  // Base + Disp + Index, where Base and Index are LLVM registers or 0.
115  // MemKind says what type of memory this is and RegKind says what type
116  // the base register has (GR32Reg or GR64Reg). Length is the operand
117  // length for D(L,B)-style operands, otherwise it is null.
118  struct MemOp {
119  unsigned Base : 12;
120  unsigned Index : 12;
121  unsigned MemKind : 4;
122  unsigned RegKind : 4;
123  const MCExpr *Disp;
124  union {
125  const MCExpr *Imm;
126  unsigned Reg;
127  } Length;
128  };
129 
130  // Imm is an immediate operand, and Sym is an optional TLS symbol
131  // for use with a __tls_get_offset marker relocation.
132  struct ImmTLSOp {
133  const MCExpr *Imm;
134  const MCExpr *Sym;
135  };
136 
137  union {
138  TokenOp Token;
139  RegOp Reg;
140  const MCExpr *Imm;
141  ImmTLSOp ImmTLS;
142  MemOp Mem;
143  };
144 
145  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
146  // Add as immediates when possible. Null MCExpr = 0.
147  if (!Expr)
149  else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
150  Inst.addOperand(MCOperand::createImm(CE->getValue()));
151  else
152  Inst.addOperand(MCOperand::createExpr(Expr));
153  }
154 
155 public:
156  SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
157  : Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
158 
159  // Create particular kinds of operand.
160  static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
161  SMLoc EndLoc) {
162  return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
163  }
164 
165  static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
166  auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);
167  Op->Token.Data = Str.data();
168  Op->Token.Length = Str.size();
169  return Op;
170  }
171 
172  static std::unique_ptr<SystemZOperand>
173  createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
174  auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
175  Op->Reg.Kind = Kind;
176  Op->Reg.Num = Num;
177  return Op;
178  }
179 
180  static std::unique_ptr<SystemZOperand>
181  createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
182  auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
183  Op->Imm = Expr;
184  return Op;
185  }
186 
187  static std::unique_ptr<SystemZOperand>
188  createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,
189  const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,
190  unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
191  auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
192  Op->Mem.MemKind = MemKind;
193  Op->Mem.RegKind = RegKind;
194  Op->Mem.Base = Base;
195  Op->Mem.Index = Index;
196  Op->Mem.Disp = Disp;
197  if (MemKind == BDLMem)
198  Op->Mem.Length.Imm = LengthImm;
199  if (MemKind == BDRMem)
200  Op->Mem.Length.Reg = LengthReg;
201  return Op;
202  }
203 
204  static std::unique_ptr<SystemZOperand>
205  createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
206  SMLoc StartLoc, SMLoc EndLoc) {
207  auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
208  Op->ImmTLS.Imm = Imm;
209  Op->ImmTLS.Sym = Sym;
210  return Op;
211  }
212 
213  // Token operands
214  bool isToken() const override {
215  return Kind == KindToken;
216  }
217  StringRef getToken() const {
218  assert(Kind == KindToken && "Not a token");
219  return StringRef(Token.Data, Token.Length);
220  }
221 
222  // Register operands.
223  bool isReg() const override {
224  return Kind == KindReg;
225  }
226  bool isReg(RegisterKind RegKind) const {
227  return Kind == KindReg && Reg.Kind == RegKind;
228  }
229  unsigned getReg() const override {
230  assert(Kind == KindReg && "Not a register");
231  return Reg.Num;
232  }
233 
234  // Immediate operands.
235  bool isImm() const override {
236  return Kind == KindImm;
237  }
238  bool isImm(int64_t MinValue, int64_t MaxValue) const {
239  return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
240  }
241  const MCExpr *getImm() const {
242  assert(Kind == KindImm && "Not an immediate");
243  return Imm;
244  }
245 
246  // Immediate operands with optional TLS symbol.
247  bool isImmTLS() const {
248  return Kind == KindImmTLS;
249  }
250 
251  const ImmTLSOp getImmTLS() const {
252  assert(Kind == KindImmTLS && "Not a TLS immediate");
253  return ImmTLS;
254  }
255 
256  // Memory operands.
257  bool isMem() const override {
258  return Kind == KindMem;
259  }
260  bool isMem(MemoryKind MemKind) const {
261  return (Kind == KindMem &&
262  (Mem.MemKind == MemKind ||
263  // A BDMem can be treated as a BDXMem in which the index
264  // register field is 0.
265  (Mem.MemKind == BDMem && MemKind == BDXMem)));
266  }
267  bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {
268  return isMem(MemKind) && Mem.RegKind == RegKind;
269  }
270  bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {
271  return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff, true);
272  }
273  bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
274  return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287, true);
275  }
276  bool isMemDisp12Len4(RegisterKind RegKind) const {
277  return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);
278  }
279  bool isMemDisp12Len8(RegisterKind RegKind) const {
280  return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);
281  }
282 
283  const MemOp& getMem() const {
284  assert(Kind == KindMem && "Not a Mem operand");
285  return Mem;
286  }
287 
288  // Override MCParsedAsmOperand.
289  SMLoc getStartLoc() const override { return StartLoc; }
290  SMLoc getEndLoc() const override { return EndLoc; }
291  void print(raw_ostream &OS) const override;
292 
293  /// getLocRange - Get the range between the first and last token of this
294  /// operand.
295  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
296 
297  // Used by the TableGen code to add particular types of operand
298  // to an instruction.
299  void addRegOperands(MCInst &Inst, unsigned N) const {
300  assert(N == 1 && "Invalid number of operands");
302  }
303  void addImmOperands(MCInst &Inst, unsigned N) const {
304  assert(N == 1 && "Invalid number of operands");
305  addExpr(Inst, getImm());
306  }
307  void addBDAddrOperands(MCInst &Inst, unsigned N) const {
308  assert(N == 2 && "Invalid number of operands");
309  assert(isMem(BDMem) && "Invalid operand type");
310  Inst.addOperand(MCOperand::createReg(Mem.Base));
311  addExpr(Inst, Mem.Disp);
312  }
313  void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
314  assert(N == 3 && "Invalid number of operands");
315  assert(isMem(BDXMem) && "Invalid operand type");
316  Inst.addOperand(MCOperand::createReg(Mem.Base));
317  addExpr(Inst, Mem.Disp);
318  Inst.addOperand(MCOperand::createReg(Mem.Index));
319  }
320  void addBDLAddrOperands(MCInst &Inst, unsigned N) const {
321  assert(N == 3 && "Invalid number of operands");
322  assert(isMem(BDLMem) && "Invalid operand type");
323  Inst.addOperand(MCOperand::createReg(Mem.Base));
324  addExpr(Inst, Mem.Disp);
325  addExpr(Inst, Mem.Length.Imm);
326  }
327  void addBDRAddrOperands(MCInst &Inst, unsigned N) const {
328  assert(N == 3 && "Invalid number of operands");
329  assert(isMem(BDRMem) && "Invalid operand type");
330  Inst.addOperand(MCOperand::createReg(Mem.Base));
331  addExpr(Inst, Mem.Disp);
332  Inst.addOperand(MCOperand::createReg(Mem.Length.Reg));
333  }
334  void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
335  assert(N == 3 && "Invalid number of operands");
336  assert(isMem(BDVMem) && "Invalid operand type");
337  Inst.addOperand(MCOperand::createReg(Mem.Base));
338  addExpr(Inst, Mem.Disp);
339  Inst.addOperand(MCOperand::createReg(Mem.Index));
340  }
341  void addImmTLSOperands(MCInst &Inst, unsigned N) const {
342  assert(N == 2 && "Invalid number of operands");
343  assert(Kind == KindImmTLS && "Invalid operand type");
344  addExpr(Inst, ImmTLS.Imm);
345  if (ImmTLS.Sym)
346  addExpr(Inst, ImmTLS.Sym);
347  }
348 
349  // Used by the TableGen code to check for particular operand types.
350  bool isGR32() const { return isReg(GR32Reg); }
351  bool isGRH32() const { return isReg(GRH32Reg); }
352  bool isGRX32() const { return false; }
353  bool isGR64() const { return isReg(GR64Reg); }
354  bool isGR128() const { return isReg(GR128Reg); }
355  bool isADDR32() const { return isReg(GR32Reg); }
356  bool isADDR64() const { return isReg(GR64Reg); }
357  bool isADDR128() const { return false; }
358  bool isFP32() const { return isReg(FP32Reg); }
359  bool isFP64() const { return isReg(FP64Reg); }
360  bool isFP128() const { return isReg(FP128Reg); }
361  bool isVR32() const { return isReg(VR32Reg); }
362  bool isVR64() const { return isReg(VR64Reg); }
363  bool isVF128() const { return false; }
364  bool isVR128() const { return isReg(VR128Reg); }
365  bool isAR32() const { return isReg(AR32Reg); }
366  bool isCR64() const { return isReg(CR64Reg); }
367  bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
368  bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, GR32Reg); }
369  bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, GR32Reg); }
370  bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, GR64Reg); }
371  bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, GR64Reg); }
372  bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, GR64Reg); }
373  bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, GR64Reg); }
374  bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg); }
375  bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg); }
376  bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, GR64Reg); }
377  bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, GR64Reg); }
378  bool isU1Imm() const { return isImm(0, 1); }
379  bool isU2Imm() const { return isImm(0, 3); }
380  bool isU3Imm() const { return isImm(0, 7); }
381  bool isU4Imm() const { return isImm(0, 15); }
382  bool isU6Imm() const { return isImm(0, 63); }
383  bool isU8Imm() const { return isImm(0, 255); }
384  bool isS8Imm() const { return isImm(-128, 127); }
385  bool isU12Imm() const { return isImm(0, 4095); }
386  bool isU16Imm() const { return isImm(0, 65535); }
387  bool isS16Imm() const { return isImm(-32768, 32767); }
388  bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
389  bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
390  bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }
391 };
392 
393 class SystemZAsmParser : public MCTargetAsmParser {
394 #define GET_ASSEMBLER_HEADER
395 #include "SystemZGenAsmMatcher.inc"
396 
397 private:
398  MCAsmParser &Parser;
399  enum RegisterGroup {
400  RegGR,
401  RegFP,
402  RegV,
403  RegAR,
404  RegCR
405  };
406  struct Register {
407  RegisterGroup Group;
408  unsigned Num;
409  SMLoc StartLoc, EndLoc;
410  };
411 
412  SystemZTargetStreamer &getTargetStreamer() {
413  assert(getParser().getStreamer().getTargetStreamer() &&
414  "do not have a target streamer");
415  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
416  return static_cast<SystemZTargetStreamer &>(TS);
417  }
418 
419  bool parseRegister(Register &Reg, bool RestoreOnFailure = false);
420 
421  bool parseIntegerRegister(Register &Reg, RegisterGroup Group);
422 
424  RegisterKind Kind);
425 
426  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
427 
428  bool parseAddress(bool &HaveReg1, Register &Reg1, bool &HaveReg2,
429  Register &Reg2, const MCExpr *&Disp, const MCExpr *&Length,
430  bool HasLength = false, bool HasVectorIndex = false);
431  bool parseAddressRegister(Register &Reg);
432 
433  bool ParseDirectiveInsn(SMLoc L);
434  bool ParseDirectiveMachine(SMLoc L);
435  bool ParseGNUAttribute(SMLoc L);
436 
438  MemoryKind MemKind,
439  RegisterKind RegKind);
440 
441  OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
442  int64_t MaxVal, bool AllowTLS);
443 
444  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
445 
446  // Both the hlasm and att variants still rely on the basic gnu asm
447  // format with respect to inputs, clobbers, outputs etc.
448  //
449  // However, calling the overriden getAssemblerDialect() method in
450  // AsmParser is problematic. It either returns the AssemblerDialect field
451  // in the MCAsmInfo instance if the AssemblerDialect field in AsmParser is
452  // unset, otherwise it returns the private AssemblerDialect field in
453  // AsmParser.
454  //
455  // The problematic part is because, we forcibly set the inline asm dialect
456  // in the AsmParser instance in AsmPrinterInlineAsm.cpp. Soo any query
457  // to the overriden getAssemblerDialect function in AsmParser.cpp, will
458  // not return the assembler dialect set in the respective MCAsmInfo instance.
459  //
460  // For this purpose, we explicitly query the SystemZMCAsmInfo instance
461  // here, to get the "correct" assembler dialect, and use it in various
462  // functions.
463  unsigned getMAIAssemblerDialect() {
464  return Parser.getContext().getAsmInfo()->getAssemblerDialect();
465  }
466 
467  // An alphabetic character in HLASM is a letter from 'A' through 'Z',
468  // or from 'a' through 'z', or '$', '_','#', or '@'.
469  inline bool isHLASMAlpha(char C) {
470  return isAlpha(C) || llvm::is_contained("_@#$", C);
471  }
472 
473  // A digit in HLASM is a number from 0 to 9.
474  inline bool isHLASMAlnum(char C) { return isHLASMAlpha(C) || isDigit(C); }
475 
476  // Are we parsing using the AD_HLASM dialect?
477  inline bool isParsingHLASM() { return getMAIAssemblerDialect() == AD_HLASM; }
478 
479  // Are we parsing using the AD_ATT dialect?
480  inline bool isParsingATT() { return getMAIAssemblerDialect() == AD_ATT; }
481 
482 public:
483  SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
484  const MCInstrInfo &MII,
485  const MCTargetOptions &Options)
486  : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
488 
489  // Alias the .word directive to .short.
490  parser.addAliasForDirective(".word", ".short");
491 
492  // Initialize the set of available features.
493  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
494  }
495 
496  // Override MCTargetAsmParser.
497  bool ParseDirective(AsmToken DirectiveID) override;
498  bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
499  SMLoc &EndLoc) override;
500  bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
501  bool RestoreOnFailure);
502  OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
503  SMLoc &EndLoc) override;
504  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
505  SMLoc NameLoc, OperandVector &Operands) override;
506  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
509  bool MatchingInlineAsm) override;
510  bool isLabel(AsmToken &Token) override;
511 
512  // Used by the TableGen code to parse particular operand types.
514  return parseRegister(Operands, GR32Reg);
515  }
517  return parseRegister(Operands, GRH32Reg);
518  }
520  llvm_unreachable("GRX32 should only be used for pseudo instructions");
521  }
523  return parseRegister(Operands, GR64Reg);
524  }
526  return parseRegister(Operands, GR128Reg);
527  }
529  // For the AsmParser, we will accept %r0 for ADDR32 as well.
530  return parseRegister(Operands, GR32Reg);
531  }
533  // For the AsmParser, we will accept %r0 for ADDR64 as well.
534  return parseRegister(Operands, GR64Reg);
535  }
537  llvm_unreachable("Shouldn't be used as an operand");
538  }
540  return parseRegister(Operands, FP32Reg);
541  }
543  return parseRegister(Operands, FP64Reg);
544  }
546  return parseRegister(Operands, FP128Reg);
547  }
549  return parseRegister(Operands, VR32Reg);
550  }
552  return parseRegister(Operands, VR64Reg);
553  }
555  llvm_unreachable("Shouldn't be used as an operand");
556  }
558  return parseRegister(Operands, VR128Reg);
559  }
561  return parseRegister(Operands, AR32Reg);
562  }
564  return parseRegister(Operands, CR64Reg);
565  }
567  return parseAnyRegister(Operands);
568  }
570  return parseAddress(Operands, BDMem, GR32Reg);
571  }
573  return parseAddress(Operands, BDMem, GR64Reg);
574  }
575  OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
576  return parseAddress(Operands, BDXMem, GR64Reg);
577  }
578  OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
579  return parseAddress(Operands, BDLMem, GR64Reg);
580  }
581  OperandMatchResultTy parseBDRAddr64(OperandVector &Operands) {
582  return parseAddress(Operands, BDRMem, GR64Reg);
583  }
584  OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
585  return parseAddress(Operands, BDVMem, GR64Reg);
586  }
588  return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false);
589  }
591  return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
592  }
594  return parsePCRel(Operands, -(1LL << 24), (1LL << 24) - 1, false);
595  }
597  return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
598  }
599  OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
600  return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
601  }
602  OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
603  return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
604  }
605 };
606 
607 } // end anonymous namespace
608 
609 #define GET_REGISTER_MATCHER
610 #define GET_SUBTARGET_FEATURE_NAME
611 #define GET_MATCHER_IMPLEMENTATION
612 #define GET_MNEMONIC_SPELL_CHECKER
613 #include "SystemZGenAsmMatcher.inc"
614 
615 // Used for the .insn directives; contains information needed to parse the
616 // operands in the directive.
620  int32_t NumOperands;
621  MatchClassKind OperandKinds[7];
622 };
623 
624 // For equal_range comparison.
625 struct CompareInsn {
626  bool operator() (const InsnMatchEntry &LHS, StringRef RHS) {
627  return LHS.Format < RHS;
628  }
629  bool operator() (StringRef LHS, const InsnMatchEntry &RHS) {
630  return LHS < RHS.Format;
631  }
632  bool operator() (const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {
633  return LHS.Format < RHS.Format;
634  }
635 };
636 
637 // Table initializing information for parsing the .insn directive.
638 static struct InsnMatchEntry InsnMatchTable[] = {
639  /* Format, Opcode, NumOperands, OperandKinds */
640  { "e", SystemZ::InsnE, 1,
641  { MCK_U16Imm } },
642  { "ri", SystemZ::InsnRI, 3,
643  { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
644  { "rie", SystemZ::InsnRIE, 4,
645  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
646  { "ril", SystemZ::InsnRIL, 3,
647  { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
648  { "rilu", SystemZ::InsnRILU, 3,
649  { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
650  { "ris", SystemZ::InsnRIS, 5,
651  { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
652  { "rr", SystemZ::InsnRR, 3,
653  { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
654  { "rre", SystemZ::InsnRRE, 3,
655  { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
656  { "rrf", SystemZ::InsnRRF, 5,
657  { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
658  { "rrs", SystemZ::InsnRRS, 5,
659  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
660  { "rs", SystemZ::InsnRS, 4,
661  { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
662  { "rse", SystemZ::InsnRSE, 4,
663  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
664  { "rsi", SystemZ::InsnRSI, 4,
665  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
666  { "rsy", SystemZ::InsnRSY, 4,
667  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
668  { "rx", SystemZ::InsnRX, 3,
669  { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
670  { "rxe", SystemZ::InsnRXE, 3,
671  { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
672  { "rxf", SystemZ::InsnRXF, 4,
673  { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
674  { "rxy", SystemZ::InsnRXY, 3,
675  { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
676  { "s", SystemZ::InsnS, 2,
677  { MCK_U32Imm, MCK_BDAddr64Disp12 } },
678  { "si", SystemZ::InsnSI, 3,
679  { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
680  { "sil", SystemZ::InsnSIL, 3,
681  { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
682  { "siy", SystemZ::InsnSIY, 3,
683  { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
684  { "ss", SystemZ::InsnSS, 4,
685  { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
686  { "sse", SystemZ::InsnSSE, 3,
687  { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
688  { "ssf", SystemZ::InsnSSF, 4,
689  { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
690  { "vri", SystemZ::InsnVRI, 6,
691  { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
692  { "vrr", SystemZ::InsnVRR, 7,
693  { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
694  MCK_U4Imm } },
695  { "vrs", SystemZ::InsnVRS, 5,
696  { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
697  { "vrv", SystemZ::InsnVRV, 4,
698  { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
699  { "vrx", SystemZ::InsnVRX, 4,
700  { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
701  { "vsi", SystemZ::InsnVSI, 4,
702  { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
703 };
704 
705 static void printMCExpr(const MCExpr *E, raw_ostream &OS) {
706  if (!E)
707  return;
708  if (auto *CE = dyn_cast<MCConstantExpr>(E))
709  OS << *CE;
710  else if (auto *UE = dyn_cast<MCUnaryExpr>(E))
711  OS << *UE;
712  else if (auto *BE = dyn_cast<MCBinaryExpr>(E))
713  OS << *BE;
714  else if (auto *SRE = dyn_cast<MCSymbolRefExpr>(E))
715  OS << *SRE;
716  else
717  OS << *E;
718 }
719 
720 void SystemZOperand::print(raw_ostream &OS) const {
721  switch (Kind) {
722  case KindToken:
723  OS << "Token:" << getToken();
724  break;
725  case KindReg:
726  OS << "Reg:" << SystemZInstPrinter::getRegisterName(getReg());
727  break;
728  case KindImm:
729  OS << "Imm:";
730  printMCExpr(getImm(), OS);
731  break;
732  case KindImmTLS:
733  OS << "ImmTLS:";
734  printMCExpr(getImmTLS().Imm, OS);
735  if (getImmTLS().Sym) {
736  OS << ", ";
737  printMCExpr(getImmTLS().Sym, OS);
738  }
739  break;
740  case KindMem: {
741  const MemOp &Op = getMem();
742  OS << "Mem:" << *cast<MCConstantExpr>(Op.Disp);
743  if (Op.Base) {
744  OS << "(";
745  if (Op.MemKind == BDLMem)
746  OS << *cast<MCConstantExpr>(Op.Length.Imm) << ",";
747  else if (Op.MemKind == BDRMem)
748  OS << SystemZInstPrinter::getRegisterName(Op.Length.Reg) << ",";
749  if (Op.Index)
750  OS << SystemZInstPrinter::getRegisterName(Op.Index) << ",";
752  OS << ")";
753  }
754  break;
755  }
756  case KindInvalid:
757  break;
758  }
759 }
760 
761 // Parse one register of the form %<prefix><number>.
762 bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) {
763  Reg.StartLoc = Parser.getTok().getLoc();
764 
765  // Eat the % prefix.
766  if (Parser.getTok().isNot(AsmToken::Percent))
767  return Error(Parser.getTok().getLoc(), "register expected");
768  const AsmToken &PercentTok = Parser.getTok();
769  Parser.Lex();
770 
771  // Expect a register name.
772  if (Parser.getTok().isNot(AsmToken::Identifier)) {
773  if (RestoreOnFailure)
774  getLexer().UnLex(PercentTok);
775  return Error(Reg.StartLoc, "invalid register");
776  }
777 
778  // Check that there's a prefix.
779  StringRef Name = Parser.getTok().getString();
780  if (Name.size() < 2) {
781  if (RestoreOnFailure)
782  getLexer().UnLex(PercentTok);
783  return Error(Reg.StartLoc, "invalid register");
784  }
785  char Prefix = Name[0];
786 
787  // Treat the rest of the register name as a register number.
788  if (Name.substr(1).getAsInteger(10, Reg.Num)) {
789  if (RestoreOnFailure)
790  getLexer().UnLex(PercentTok);
791  return Error(Reg.StartLoc, "invalid register");
792  }
793 
794  // Look for valid combinations of prefix and number.
795  if (Prefix == 'r' && Reg.Num < 16)
796  Reg.Group = RegGR;
797  else if (Prefix == 'f' && Reg.Num < 16)
798  Reg.Group = RegFP;
799  else if (Prefix == 'v' && Reg.Num < 32)
800  Reg.Group = RegV;
801  else if (Prefix == 'a' && Reg.Num < 16)
802  Reg.Group = RegAR;
803  else if (Prefix == 'c' && Reg.Num < 16)
804  Reg.Group = RegCR;
805  else {
806  if (RestoreOnFailure)
807  getLexer().UnLex(PercentTok);
808  return Error(Reg.StartLoc, "invalid register");
809  }
810 
811  Reg.EndLoc = Parser.getTok().getLoc();
812  Parser.Lex();
813  return false;
814 }
815 
816 // Parse a register of kind Kind and add it to Operands.
818 SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterKind Kind) {
819  Register Reg;
820  RegisterGroup Group;
821  switch (Kind) {
822  case GR32Reg:
823  case GRH32Reg:
824  case GR64Reg:
825  case GR128Reg:
826  Group = RegGR;
827  break;
828  case FP32Reg:
829  case FP64Reg:
830  case FP128Reg:
831  Group = RegFP;
832  break;
833  case VR32Reg:
834  case VR64Reg:
835  case VR128Reg:
836  Group = RegV;
837  break;
838  case AR32Reg:
839  Group = RegAR;
840  break;
841  case CR64Reg:
842  Group = RegCR;
843  break;
844  }
845 
846  // Handle register names of the form %<prefix><number>
847  if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) {
848  if (parseRegister(Reg))
849  return MatchOperand_ParseFail;
850 
851  // Check the parsed register group "Reg.Group" with the expected "Group"
852  // Have to error out if user specified wrong prefix.
853  switch (Group) {
854  case RegGR:
855  case RegFP:
856  case RegAR:
857  case RegCR:
858  if (Group != Reg.Group) {
859  Error(Reg.StartLoc, "invalid operand for instruction");
860  return MatchOperand_ParseFail;
861  }
862  break;
863  case RegV:
864  if (Reg.Group != RegV && Reg.Group != RegFP) {
865  Error(Reg.StartLoc, "invalid operand for instruction");
866  return MatchOperand_ParseFail;
867  }
868  break;
869  }
870  } else if (Parser.getTok().is(AsmToken::Integer)) {
871  if (parseIntegerRegister(Reg, Group))
872  return MatchOperand_ParseFail;
873  }
874  // Otherwise we didn't match a register operand.
875  else
876  return MatchOperand_NoMatch;
877 
878  // Determine the LLVM register number according to Kind.
879  const unsigned *Regs;
880  switch (Kind) {
881  case GR32Reg: Regs = SystemZMC::GR32Regs; break;
882  case GRH32Reg: Regs = SystemZMC::GRH32Regs; break;
883  case GR64Reg: Regs = SystemZMC::GR64Regs; break;
884  case GR128Reg: Regs = SystemZMC::GR128Regs; break;
885  case FP32Reg: Regs = SystemZMC::FP32Regs; break;
886  case FP64Reg: Regs = SystemZMC::FP64Regs; break;
887  case FP128Reg: Regs = SystemZMC::FP128Regs; break;
888  case VR32Reg: Regs = SystemZMC::VR32Regs; break;
889  case VR64Reg: Regs = SystemZMC::VR64Regs; break;
890  case VR128Reg: Regs = SystemZMC::VR128Regs; break;
891  case AR32Reg: Regs = SystemZMC::AR32Regs; break;
892  case CR64Reg: Regs = SystemZMC::CR64Regs; break;
893  }
894  if (Regs[Reg.Num] == 0) {
895  Error(Reg.StartLoc, "invalid register pair");
896  return MatchOperand_ParseFail;
897  }
898 
899  Operands.push_back(
900  SystemZOperand::createReg(Kind, Regs[Reg.Num], Reg.StartLoc, Reg.EndLoc));
901  return MatchOperand_Success;
902 }
903 
904 // Parse any type of register (including integers) and add it to Operands.
906 SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
907  SMLoc StartLoc = Parser.getTok().getLoc();
908 
909  // Handle integer values.
910  if (Parser.getTok().is(AsmToken::Integer)) {
911  const MCExpr *Register;
912  if (Parser.parseExpression(Register))
913  return MatchOperand_ParseFail;
914 
915  if (auto *CE = dyn_cast<MCConstantExpr>(Register)) {
916  int64_t Value = CE->getValue();
917  if (Value < 0 || Value > 15) {
918  Error(StartLoc, "invalid register");
919  return MatchOperand_ParseFail;
920  }
921  }
922 
923  SMLoc EndLoc =
924  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
925 
926  Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));
927  }
928  else {
929  if (isParsingHLASM())
930  return MatchOperand_NoMatch;
931 
932  Register Reg;
933  if (parseRegister(Reg))
934  return MatchOperand_ParseFail;
935 
936  if (Reg.Num > 15) {
937  Error(StartLoc, "invalid register");
938  return MatchOperand_ParseFail;
939  }
940 
941  // Map to the correct register kind.
942  RegisterKind Kind;
943  unsigned RegNo;
944  if (Reg.Group == RegGR) {
945  Kind = GR64Reg;
946  RegNo = SystemZMC::GR64Regs[Reg.Num];
947  }
948  else if (Reg.Group == RegFP) {
949  Kind = FP64Reg;
950  RegNo = SystemZMC::FP64Regs[Reg.Num];
951  }
952  else if (Reg.Group == RegV) {
953  Kind = VR128Reg;
954  RegNo = SystemZMC::VR128Regs[Reg.Num];
955  }
956  else if (Reg.Group == RegAR) {
957  Kind = AR32Reg;
958  RegNo = SystemZMC::AR32Regs[Reg.Num];
959  }
960  else if (Reg.Group == RegCR) {
961  Kind = CR64Reg;
962  RegNo = SystemZMC::CR64Regs[Reg.Num];
963  }
964  else {
965  return MatchOperand_ParseFail;
966  }
967 
968  Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
969  Reg.StartLoc, Reg.EndLoc));
970  }
971  return MatchOperand_Success;
972 }
973 
974 bool SystemZAsmParser::parseIntegerRegister(Register &Reg,
975  RegisterGroup Group) {
976  Reg.StartLoc = Parser.getTok().getLoc();
977  // We have an integer token
978  const MCExpr *Register;
979  if (Parser.parseExpression(Register))
980  return true;
981 
982  const auto *CE = dyn_cast<MCConstantExpr>(Register);
983  if (!CE)
984  return true;
985 
986  int64_t MaxRegNum = (Group == RegV) ? 31 : 15;
987  int64_t Value = CE->getValue();
988  if (Value < 0 || Value > MaxRegNum) {
989  Error(Parser.getTok().getLoc(), "invalid register");
990  return true;
991  }
992 
993  // Assign the Register Number
994  Reg.Num = (unsigned)Value;
995  Reg.Group = Group;
996  Reg.EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
997 
998  // At this point, successfully parsed an integer register.
999  return false;
1000 }
1001 
1002 // Parse a memory operand into Reg1, Reg2, Disp, and Length.
1003 bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
1004  bool &HaveReg2, Register &Reg2,
1005  const MCExpr *&Disp, const MCExpr *&Length,
1006  bool HasLength, bool HasVectorIndex) {
1007  // Parse the displacement, which must always be present.
1008  if (getParser().parseExpression(Disp))
1009  return true;
1010 
1011  // Parse the optional base and index.
1012  HaveReg1 = false;
1013  HaveReg2 = false;
1014  Length = nullptr;
1015 
1016  // If we have a scenario as below:
1017  // vgef %v0, 0(0), 0
1018  // This is an example of a "BDVMem" instruction type.
1019  //
1020  // So when we parse this as an integer register, the register group
1021  // needs to be tied to "RegV". Usually when the prefix is passed in
1022  // as %<prefix><reg-number> its easy to check which group it should belong to
1023  // However, if we're passing in just the integer there's no real way to
1024  // "check" what register group it should belong to.
1025  //
1026  // When the user passes in the register as an integer, the user assumes that
1027  // the compiler is responsible for substituting it as the right kind of
1028  // register. Whereas, when the user specifies a "prefix", the onus is on
1029  // the user to make sure they pass in the right kind of register.
1030  //
1031  // The restriction only applies to the first Register (i.e. Reg1). Reg2 is
1032  // always a general register. Reg1 should be of group RegV if "HasVectorIndex"
1033  // (i.e. insn is of type BDVMem) is true.
1034  RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;
1035 
1036  if (getLexer().is(AsmToken::LParen)) {
1037  Parser.Lex();
1038 
1039  if (isParsingATT() && getLexer().is(AsmToken::Percent)) {
1040  // Parse the first register.
1041  HaveReg1 = true;
1042  if (parseRegister(Reg1))
1043  return true;
1044  }
1045  // So if we have an integer as the first token in ([tok1], ..), it could:
1046  // 1. Refer to a "Register" (i.e X,R,V fields in BD[X|R|V]Mem type of
1047  // instructions)
1048  // 2. Refer to a "Length" field (i.e L field in BDLMem type of instructions)
1049  else if (getLexer().is(AsmToken::Integer)) {
1050  if (HasLength) {
1051  // Instruction has a "Length" field, safe to parse the first token as
1052  // the "Length" field
1053  if (getParser().parseExpression(Length))
1054  return true;
1055  } else {
1056  // Otherwise, if the instruction has no "Length" field, parse the
1057  // token as a "Register". We don't have to worry about whether the
1058  // instruction is invalid here, because the caller will take care of
1059  // error reporting.
1060  HaveReg1 = true;
1061  if (parseIntegerRegister(Reg1, RegGroup))
1062  return true;
1063  }
1064  } else {
1065  // If its not an integer or a percent token, then if the instruction
1066  // is reported to have a "Length" then, parse it as "Length".
1067  if (HasLength) {
1068  if (getParser().parseExpression(Length))
1069  return true;
1070  }
1071  }
1072 
1073  // Check whether there's a second register.
1074  if (getLexer().is(AsmToken::Comma)) {
1075  Parser.Lex();
1076  HaveReg2 = true;
1077 
1078  if (getLexer().is(AsmToken::Integer)) {
1079  if (parseIntegerRegister(Reg2, RegGR))
1080  return true;
1081  } else {
1082  if (isParsingATT() && parseRegister(Reg2))
1083  return true;
1084  }
1085  }
1086 
1087  // Consume the closing bracket.
1088  if (getLexer().isNot(AsmToken::RParen))
1089  return Error(Parser.getTok().getLoc(), "unexpected token in address");
1090  Parser.Lex();
1091  }
1092  return false;
1093 }
1094 
1095 // Verify that Reg is a valid address register (base or index).
1096 bool
1097 SystemZAsmParser::parseAddressRegister(Register &Reg) {
1098  if (Reg.Group == RegV) {
1099  Error(Reg.StartLoc, "invalid use of vector addressing");
1100  return true;
1101  } else if (Reg.Group != RegGR) {
1102  Error(Reg.StartLoc, "invalid address register");
1103  return true;
1104  }
1105  return false;
1106 }
1107 
1108 // Parse a memory operand and add it to Operands. The other arguments
1109 // are as above.
1111 SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
1112  RegisterKind RegKind) {
1113  SMLoc StartLoc = Parser.getTok().getLoc();
1114  unsigned Base = 0, Index = 0, LengthReg = 0;
1115  Register Reg1, Reg2;
1116  bool HaveReg1, HaveReg2;
1117  const MCExpr *Disp;
1118  const MCExpr *Length;
1119 
1120  bool HasLength = (MemKind == BDLMem) ? true : false;
1121  bool HasVectorIndex = (MemKind == BDVMem) ? true : false;
1122  if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length, HasLength,
1123  HasVectorIndex))
1124  return MatchOperand_ParseFail;
1125 
1126  const unsigned *Regs;
1127  switch (RegKind) {
1128  case GR32Reg: Regs = SystemZMC::GR32Regs; break;
1129  case GR64Reg: Regs = SystemZMC::GR64Regs; break;
1130  default: llvm_unreachable("invalid RegKind");
1131  }
1132 
1133  switch (MemKind) {
1134  case BDMem:
1135  // If we have Reg1, it must be an address register.
1136  if (HaveReg1) {
1137  if (parseAddressRegister(Reg1))
1138  return MatchOperand_ParseFail;
1139  Base = Regs[Reg1.Num];
1140  }
1141  // There must be no Reg2.
1142  if (HaveReg2) {
1143  Error(StartLoc, "invalid use of indexed addressing");
1144  return MatchOperand_ParseFail;
1145  }
1146  break;
1147  case BDXMem:
1148  // If we have Reg1, it must be an address register.
1149  if (HaveReg1) {
1150  if (parseAddressRegister(Reg1))
1151  return MatchOperand_ParseFail;
1152  // If the are two registers, the first one is the index and the
1153  // second is the base.
1154  if (HaveReg2)
1155  Index = Regs[Reg1.Num];
1156  else
1157  Base = Regs[Reg1.Num];
1158  }
1159  // If we have Reg2, it must be an address register.
1160  if (HaveReg2) {
1161  if (parseAddressRegister(Reg2))
1162  return MatchOperand_ParseFail;
1163  Base = Regs[Reg2.Num];
1164  }
1165  break;
1166  case BDLMem:
1167  // If we have Reg2, it must be an address register.
1168  if (HaveReg2) {
1169  if (parseAddressRegister(Reg2))
1170  return MatchOperand_ParseFail;
1171  Base = Regs[Reg2.Num];
1172  }
1173  // We cannot support base+index addressing.
1174  if (HaveReg1 && HaveReg2) {
1175  Error(StartLoc, "invalid use of indexed addressing");
1176  return MatchOperand_ParseFail;
1177  }
1178  // We must have a length.
1179  if (!Length) {
1180  Error(StartLoc, "missing length in address");
1181  return MatchOperand_ParseFail;
1182  }
1183  break;
1184  case BDRMem:
1185  // We must have Reg1, and it must be a GPR.
1186  if (!HaveReg1 || Reg1.Group != RegGR) {
1187  Error(StartLoc, "invalid operand for instruction");
1188  return MatchOperand_ParseFail;
1189  }
1190  LengthReg = SystemZMC::GR64Regs[Reg1.Num];
1191  // If we have Reg2, it must be an address register.
1192  if (HaveReg2) {
1193  if (parseAddressRegister(Reg2))
1194  return MatchOperand_ParseFail;
1195  Base = Regs[Reg2.Num];
1196  }
1197  break;
1198  case BDVMem:
1199  // We must have Reg1, and it must be a vector register.
1200  if (!HaveReg1 || Reg1.Group != RegV) {
1201  Error(StartLoc, "vector index required in address");
1202  return MatchOperand_ParseFail;
1203  }
1204  Index = SystemZMC::VR128Regs[Reg1.Num];
1205  // If we have Reg2, it must be an address register.
1206  if (HaveReg2) {
1207  if (parseAddressRegister(Reg2))
1208  return MatchOperand_ParseFail;
1209  Base = Regs[Reg2.Num];
1210  }
1211  break;
1212  }
1213 
1214  SMLoc EndLoc =
1215  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1216  Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
1217  Index, Length, LengthReg,
1218  StartLoc, EndLoc));
1219  return MatchOperand_Success;
1220 }
1221 
1222 bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
1223  StringRef IDVal = DirectiveID.getIdentifier();
1224 
1225  if (IDVal == ".insn")
1226  return ParseDirectiveInsn(DirectiveID.getLoc());
1227  if (IDVal == ".machine")
1228  return ParseDirectiveMachine(DirectiveID.getLoc());
1229  if (IDVal.startswith(".gnu_attribute"))
1230  return ParseGNUAttribute(DirectiveID.getLoc());
1231 
1232  return true;
1233 }
1234 
1235 /// ParseDirectiveInsn
1236 /// ::= .insn [ format, encoding, (operands (, operands)*) ]
1237 bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) {
1238  MCAsmParser &Parser = getParser();
1239 
1240  // Expect instruction format as identifier.
1241  StringRef Format;
1242  SMLoc ErrorLoc = Parser.getTok().getLoc();
1243  if (Parser.parseIdentifier(Format))
1244  return Error(ErrorLoc, "expected instruction format");
1245 
1247 
1248  // Find entry for this format in InsnMatchTable.
1249  auto EntryRange =
1250  std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
1251  Format, CompareInsn());
1252 
1253  // If first == second, couldn't find a match in the table.
1254  if (EntryRange.first == EntryRange.second)
1255  return Error(ErrorLoc, "unrecognized format");
1256 
1257  struct InsnMatchEntry *Entry = EntryRange.first;
1258 
1259  // Format should match from equal_range.
1260  assert(Entry->Format == Format);
1261 
1262  // Parse the following operands using the table's information.
1263  for (int i = 0; i < Entry->NumOperands; i++) {
1264  MatchClassKind Kind = Entry->OperandKinds[i];
1265 
1266  SMLoc StartLoc = Parser.getTok().getLoc();
1267 
1268  // Always expect commas as separators for operands.
1269  if (getLexer().isNot(AsmToken::Comma))
1270  return Error(StartLoc, "unexpected token in directive");
1271  Lex();
1272 
1273  // Parse operands.
1274  OperandMatchResultTy ResTy;
1275  if (Kind == MCK_AnyReg)
1276  ResTy = parseAnyReg(Operands);
1277  else if (Kind == MCK_VR128)
1278  ResTy = parseVR128(Operands);
1279  else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1280  ResTy = parseBDXAddr64(Operands);
1281  else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1282  ResTy = parseBDAddr64(Operands);
1283  else if (Kind == MCK_BDVAddr64Disp12)
1284  ResTy = parseBDVAddr64(Operands);
1285  else if (Kind == MCK_PCRel32)
1286  ResTy = parsePCRel32(Operands);
1287  else if (Kind == MCK_PCRel16)
1288  ResTy = parsePCRel16(Operands);
1289  else {
1290  // Only remaining operand kind is an immediate.
1291  const MCExpr *Expr;
1292  SMLoc StartLoc = Parser.getTok().getLoc();
1293 
1294  // Expect immediate expression.
1295  if (Parser.parseExpression(Expr))
1296  return Error(StartLoc, "unexpected token in directive");
1297 
1298  SMLoc EndLoc =
1299  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1300 
1301  Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1302  ResTy = MatchOperand_Success;
1303  }
1304 
1305  if (ResTy != MatchOperand_Success)
1306  return true;
1307  }
1308 
1309  // Build the instruction with the parsed operands.
1310  MCInst Inst = MCInstBuilder(Entry->Opcode);
1311 
1312  for (size_t i = 0; i < Operands.size(); i++) {
1313  MCParsedAsmOperand &Operand = *Operands[i];
1314  MatchClassKind Kind = Entry->OperandKinds[i];
1315 
1316  // Verify operand.
1317  unsigned Res = validateOperandClass(Operand, Kind);
1318  if (Res != Match_Success)
1319  return Error(Operand.getStartLoc(), "unexpected operand type");
1320 
1321  // Add operands to instruction.
1322  SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);
1323  if (ZOperand.isReg())
1324  ZOperand.addRegOperands(Inst, 1);
1325  else if (ZOperand.isMem(BDMem))
1326  ZOperand.addBDAddrOperands(Inst, 2);
1327  else if (ZOperand.isMem(BDXMem))
1328  ZOperand.addBDXAddrOperands(Inst, 3);
1329  else if (ZOperand.isMem(BDVMem))
1330  ZOperand.addBDVAddrOperands(Inst, 3);
1331  else if (ZOperand.isImm())
1332  ZOperand.addImmOperands(Inst, 1);
1333  else
1334  llvm_unreachable("unexpected operand type");
1335  }
1336 
1337  // Emit as a regular instruction.
1338  Parser.getStreamer().emitInstruction(Inst, getSTI());
1339 
1340  return false;
1341 }
1342 
1343 /// ParseDirectiveMachine
1344 /// ::= .machine [ mcpu ]
1345 bool SystemZAsmParser::ParseDirectiveMachine(SMLoc L) {
1346  MCAsmParser &Parser = getParser();
1347  if (Parser.getTok().isNot(AsmToken::Identifier) &&
1348  Parser.getTok().isNot(AsmToken::String))
1349  return Error(L, "unexpected token in '.machine' directive");
1350 
1351  StringRef CPU = Parser.getTok().getIdentifier();
1352  Parser.Lex();
1353  if (parseToken(AsmToken::EndOfStatement))
1354  return addErrorSuffix(" in '.machine' directive");
1355 
1356  MCSubtargetInfo &STI = copySTI();
1357  STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
1358  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
1359 
1360  getTargetStreamer().emitMachine(CPU);
1361 
1362  return false;
1363 }
1364 
1365 bool SystemZAsmParser::ParseGNUAttribute(SMLoc L) {
1366  int64_t Tag;
1367  int64_t IntegerValue;
1368  if (!Parser.parseGNUAttribute(L, Tag, IntegerValue))
1369  return false;
1370 
1371  // Tag_GNU_S390_ABI_Vector tag is '8' and can be 0, 1, or 2.
1372  if (Tag != 8 || (IntegerValue < 0 || IntegerValue > 2)) {
1373  Error(Parser.getTok().getLoc(),
1374  "Unrecognized .gnu_attribute tag/value pair.");
1375  return false;
1376  }
1377 
1378  Parser.getStreamer().emitGNUAttribute(Tag, IntegerValue);
1379 
1380  return true;
1381 }
1382 
1383 bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1384  SMLoc &EndLoc, bool RestoreOnFailure) {
1385  Register Reg;
1386  if (parseRegister(Reg, RestoreOnFailure))
1387  return true;
1388  if (Reg.Group == RegGR)
1389  RegNo = SystemZMC::GR64Regs[Reg.Num];
1390  else if (Reg.Group == RegFP)
1391  RegNo = SystemZMC::FP64Regs[Reg.Num];
1392  else if (Reg.Group == RegV)
1393  RegNo = SystemZMC::VR128Regs[Reg.Num];
1394  else if (Reg.Group == RegAR)
1395  RegNo = SystemZMC::AR32Regs[Reg.Num];
1396  else if (Reg.Group == RegCR)
1397  RegNo = SystemZMC::CR64Regs[Reg.Num];
1398  StartLoc = Reg.StartLoc;
1399  EndLoc = Reg.EndLoc;
1400  return false;
1401 }
1402 
1403 bool SystemZAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1404  SMLoc &EndLoc) {
1405  return ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/false);
1406 }
1407 
1408 OperandMatchResultTy SystemZAsmParser::tryParseRegister(MCRegister &RegNo,
1409  SMLoc &StartLoc,
1410  SMLoc &EndLoc) {
1411  bool Result =
1412  ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/true);
1413  bool PendingErrors = getParser().hasPendingError();
1414  getParser().clearPendingErrors();
1415  if (PendingErrors)
1416  return MatchOperand_ParseFail;
1417  if (Result)
1418  return MatchOperand_NoMatch;
1419  return MatchOperand_Success;
1420 }
1421 
1422 bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1423  StringRef Name, SMLoc NameLoc,
1425 
1426  // Apply mnemonic aliases first, before doing anything else, in
1427  // case the target uses it.
1428  applyMnemonicAliases(Name, getAvailableFeatures(), getMAIAssemblerDialect());
1429 
1430  Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1431 
1432  // Read the remaining operands.
1433  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1434  // Read the first operand.
1435  if (parseOperand(Operands, Name)) {
1436  return true;
1437  }
1438 
1439  // Read any subsequent operands.
1440  while (getLexer().is(AsmToken::Comma)) {
1441  Parser.Lex();
1442 
1443  if (isParsingHLASM() && getLexer().is(AsmToken::Space))
1444  return Error(
1445  Parser.getTok().getLoc(),
1446  "No space allowed between comma that separates operand entries");
1447 
1448  if (parseOperand(Operands, Name)) {
1449  return true;
1450  }
1451  }
1452 
1453  // Under the HLASM variant, we could have the remark field
1454  // The remark field occurs after the operation entries
1455  // There is a space that separates the operation entries and the
1456  // remark field.
1457  if (isParsingHLASM() && getTok().is(AsmToken::Space)) {
1458  // We've confirmed that there is a Remark field.
1459  StringRef Remark(getLexer().LexUntilEndOfStatement());
1460  Parser.Lex();
1461 
1462  // If there is nothing after the space, then there is nothing to emit
1463  // We could have a situation as this:
1464  // " \n"
1465  // After lexing above, we will have
1466  // "\n"
1467  // This isn't an explicit remark field, so we don't have to output
1468  // this as a comment.
1469  if (Remark.size())
1470  // Output the entire Remarks Field as a comment
1471  getStreamer().AddComment(Remark);
1472  }
1473 
1474  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1475  SMLoc Loc = getLexer().getLoc();
1476  return Error(Loc, "unexpected token in argument list");
1477  }
1478  }
1479 
1480  // Consume the EndOfStatement.
1481  Parser.Lex();
1482  return false;
1483 }
1484 
1485 bool SystemZAsmParser::parseOperand(OperandVector &Operands,
1486  StringRef Mnemonic) {
1487  // Check if the current operand has a custom associated parser, if so, try to
1488  // custom parse the operand, or fallback to the general approach. Force all
1489  // features to be available during the operand check, or else we will fail to
1490  // find the custom parser, and then we will later get an InvalidOperand error
1491  // instead of a MissingFeature errror.
1492  FeatureBitset AvailableFeatures = getAvailableFeatures();
1494  All.set();
1495  setAvailableFeatures(All);
1496  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1497  setAvailableFeatures(AvailableFeatures);
1498  if (ResTy == MatchOperand_Success)
1499  return false;
1500 
1501  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1502  // there was a match, but an error occurred, in which case, just return that
1503  // the operand parsing failed.
1504  if (ResTy == MatchOperand_ParseFail)
1505  return true;
1506 
1507  // Check for a register. All real register operands should have used
1508  // a context-dependent parse routine, which gives the required register
1509  // class. The code is here to mop up other cases, like those where
1510  // the instruction isn't recognized.
1511  if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) {
1512  Register Reg;
1513  if (parseRegister(Reg))
1514  return true;
1515  Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
1516  return false;
1517  }
1518 
1519  // The only other type of operand is an immediate or address. As above,
1520  // real address operands should have used a context-dependent parse routine,
1521  // so we treat any plain expression as an immediate.
1522  SMLoc StartLoc = Parser.getTok().getLoc();
1523  Register Reg1, Reg2;
1524  bool HaveReg1, HaveReg2;
1525  const MCExpr *Expr;
1526  const MCExpr *Length;
1527  if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length,
1528  /*HasLength*/ true, /*HasVectorIndex*/ true))
1529  return true;
1530  // If the register combination is not valid for any instruction, reject it.
1531  // Otherwise, fall back to reporting an unrecognized instruction.
1532  if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1533  && parseAddressRegister(Reg1))
1534  return true;
1535  if (HaveReg2 && parseAddressRegister(Reg2))
1536  return true;
1537 
1538  SMLoc EndLoc =
1539  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1540  if (HaveReg1 || HaveReg2 || Length)
1541  Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1542  else
1543  Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1544  return false;
1545 }
1546 
1547 bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1549  MCStreamer &Out,
1551  bool MatchingInlineAsm) {
1552  MCInst Inst;
1553  unsigned MatchResult;
1554 
1555  unsigned Dialect = getMAIAssemblerDialect();
1556 
1557  FeatureBitset MissingFeatures;
1558  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1559  MatchingInlineAsm, Dialect);
1560  switch (MatchResult) {
1561  case Match_Success:
1562  Inst.setLoc(IDLoc);
1563  Out.emitInstruction(Inst, getSTI());
1564  return false;
1565 
1566  case Match_MissingFeature: {
1567  assert(MissingFeatures.any() && "Unknown missing feature!");
1568  // Special case the error message for the very common case where only
1569  // a single subtarget feature is missing
1570  std::string Msg = "instruction requires:";
1571  for (unsigned I = 0, E = MissingFeatures.size(); I != E; ++I) {
1572  if (MissingFeatures[I]) {
1573  Msg += " ";
1575  }
1576  }
1577  return Error(IDLoc, Msg);
1578  }
1579 
1580  case Match_InvalidOperand: {
1581  SMLoc ErrorLoc = IDLoc;
1582  if (ErrorInfo != ~0ULL) {
1583  if (ErrorInfo >= Operands.size())
1584  return Error(IDLoc, "too few operands for instruction");
1585 
1586  ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
1587  if (ErrorLoc == SMLoc())
1588  ErrorLoc = IDLoc;
1589  }
1590  return Error(ErrorLoc, "invalid operand for instruction");
1591  }
1592 
1593  case Match_MnemonicFail: {
1594  FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1595  std::string Suggestion = SystemZMnemonicSpellCheck(
1596  ((SystemZOperand &)*Operands[0]).getToken(), FBS, Dialect);
1597  return Error(IDLoc, "invalid instruction" + Suggestion,
1598  ((SystemZOperand &)*Operands[0]).getLocRange());
1599  }
1600  }
1601 
1602  llvm_unreachable("Unexpected match type");
1603 }
1604 
1606 SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
1607  int64_t MaxVal, bool AllowTLS) {
1608  MCContext &Ctx = getContext();
1609  MCStreamer &Out = getStreamer();
1610  const MCExpr *Expr;
1611  SMLoc StartLoc = Parser.getTok().getLoc();
1612  if (getParser().parseExpression(Expr))
1613  return MatchOperand_NoMatch;
1614 
1615  auto isOutOfRangeConstant = [&](const MCExpr *E, bool Negate) -> bool {
1616  if (auto *CE = dyn_cast<MCConstantExpr>(E)) {
1617  int64_t Value = CE->getValue();
1618  if (Negate)
1619  Value = -Value;
1620  if ((Value & 1) || Value < MinVal || Value > MaxVal)
1621  return true;
1622  }
1623  return false;
1624  };
1625 
1626  // For consistency with the GNU assembler, treat immediates as offsets
1627  // from ".".
1628  if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1629  if (isParsingHLASM()) {
1630  Error(StartLoc, "Expected PC-relative expression");
1631  return MatchOperand_ParseFail;
1632  }
1633  if (isOutOfRangeConstant(CE, false)) {
1634  Error(StartLoc, "offset out of range");
1635  return MatchOperand_ParseFail;
1636  }
1637  int64_t Value = CE->getValue();
1638  MCSymbol *Sym = Ctx.createTempSymbol();
1639  Out.emitLabel(Sym);
1641  Ctx);
1642  Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);
1643  }
1644 
1645  // For consistency with the GNU assembler, conservatively assume that a
1646  // constant offset must by itself be within the given size range.
1647  if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
1648  if (isOutOfRangeConstant(BE->getLHS(), false) ||
1649  isOutOfRangeConstant(BE->getRHS(),
1650  BE->getOpcode() == MCBinaryExpr::Sub)) {
1651  Error(StartLoc, "offset out of range");
1652  return MatchOperand_ParseFail;
1653  }
1654 
1655  // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
1656  const MCExpr *Sym = nullptr;
1657  if (AllowTLS && getLexer().is(AsmToken::Colon)) {
1658  Parser.Lex();
1659 
1660  if (Parser.getTok().isNot(AsmToken::Identifier)) {
1661  Error(Parser.getTok().getLoc(), "unexpected token");
1662  return MatchOperand_ParseFail;
1663  }
1664 
1666  StringRef Name = Parser.getTok().getString();
1667  if (Name == "tls_gdcall")
1669  else if (Name == "tls_ldcall")
1671  else {
1672  Error(Parser.getTok().getLoc(), "unknown TLS tag");
1673  return MatchOperand_ParseFail;
1674  }
1675  Parser.Lex();
1676 
1677  if (Parser.getTok().isNot(AsmToken::Colon)) {
1678  Error(Parser.getTok().getLoc(), "unexpected token");
1679  return MatchOperand_ParseFail;
1680  }
1681  Parser.Lex();
1682 
1683  if (Parser.getTok().isNot(AsmToken::Identifier)) {
1684  Error(Parser.getTok().getLoc(), "unexpected token");
1685  return MatchOperand_ParseFail;
1686  }
1687 
1688  StringRef Identifier = Parser.getTok().getString();
1690  Kind, Ctx);
1691  Parser.Lex();
1692  }
1693 
1694  SMLoc EndLoc =
1695  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1696 
1697  if (AllowTLS)
1698  Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1699  StartLoc, EndLoc));
1700  else
1701  Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1702 
1703  return MatchOperand_Success;
1704 }
1705 
1706 bool SystemZAsmParser::isLabel(AsmToken &Token) {
1707  if (isParsingATT())
1708  return true;
1709 
1710  // HLASM labels are ordinary symbols.
1711  // An HLASM label always starts at column 1.
1712  // An ordinary symbol syntax is laid out as follows:
1713  // Rules:
1714  // 1. Has to start with an "alphabetic character". Can be followed by up to
1715  // 62 alphanumeric characters. An "alphabetic character", in this scenario,
1716  // is a letter from 'A' through 'Z', or from 'a' through 'z',
1717  // or '$', '_', '#', or '@'
1718  // 2. Labels are case-insensitive. E.g. "lab123", "LAB123", "lAb123", etc.
1719  // are all treated as the same symbol. However, the processing for the case
1720  // folding will not be done in this function.
1721  StringRef RawLabel = Token.getString();
1722  SMLoc Loc = Token.getLoc();
1723 
1724  // An HLASM label cannot be empty.
1725  if (!RawLabel.size())
1726  return !Error(Loc, "HLASM Label cannot be empty");
1727 
1728  // An HLASM label cannot exceed greater than 63 characters.
1729  if (RawLabel.size() > 63)
1730  return !Error(Loc, "Maximum length for HLASM Label is 63 characters");
1731 
1732  // A label must start with an "alphabetic character".
1733  if (!isHLASMAlpha(RawLabel[0]))
1734  return !Error(Loc, "HLASM Label has to start with an alphabetic "
1735  "character or the underscore character");
1736 
1737  // Now, we've established that the length is valid
1738  // and the first character is alphabetic.
1739  // Check whether remaining string is alphanumeric.
1740  for (unsigned I = 1; I < RawLabel.size(); ++I)
1741  if (!isHLASMAlnum(RawLabel[I]))
1742  return !Error(Loc, "HLASM Label has to be alphanumeric");
1743 
1744  return true;
1745 }
1746 
1747 // Force static initialization.
1750 }
llvm::MCTargetStreamer::getStreamer
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
i
i
Definition: README.txt:29
llvm::MCAsmParser
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
UseBFI::All
@ All
llvm::SystemZMC::GR128Regs
const unsigned GR128Regs[16]
Definition: SystemZMCTargetDesc.cpp:56
is
should just be implemented with a CLZ instruction Since there are other e that share this it would be best to implement this in a target independent as zero is the default value for the binary encoder e add r0 add r5 Register operands should be distinct That is
Definition: README.txt:725
llvm::MCAsmParser::getStreamer
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::AsmToken::is
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition: MCParsedAsmOperand.h:24
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:159
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:76
StringRef.h
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition: MCAsmMacro.h:42
llvm::SystemZInstPrinter::getRegisterName
static const char * getRegisterName(MCRegister Reg)
llvm::SystemZMC::VR128Regs
const unsigned VR128Regs[32]
Definition: SystemZMCTargetDesc.cpp:106
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::SystemZMC::FP32Regs
const unsigned FP32Regs[16]
Definition: SystemZMCTargetDesc.cpp:63
MCParsedAsmOperand.h
llvm::MCAsmParser::parseIdentifier
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
ErrorHandling.h
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
MCInstBuilder.h
llvm::MemOp
Definition: TargetLowering.h:112
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::AsmToken::Integer
@ Integer
Definition: MCAsmMacro.h:32
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
llvm::SystemZMC::GR64Regs
const unsigned GR64Regs[16]
Definition: SystemZMCTargetDesc.cpp:49
llvm::SystemZTargetStreamer
Definition: SystemZTargetStreamer.h:18
InsnMatchEntry::NumOperands
int32_t NumOperands
Definition: SystemZAsmParser.cpp:620
SystemZMCTargetDesc.h
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:41
llvm::MCAsmInfo::getAssemblerDialect
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:686
llvm::SystemZMC::FP128Regs
const unsigned FP128Regs[16]
Definition: SystemZMCTargetDesc.cpp:77
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::SystemZMC::AR32Regs
const unsigned AR32Regs[16]
Definition: SystemZMCTargetDesc.cpp:117
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:103
MCAsmParser.h
MCTargetAsmParser.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
SystemZTargetInfo.h
SystemZInstPrinter.h
SystemZTargetStreamer.h
applyMnemonicAliases
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
llvm::AsmToken
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
isImm
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
Definition: SPIRVInstructionSelector.cpp:1218
llvm::MCParsedAsmOperand::getStartLoc
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
llvm::AsmToken::LParen
@ LParen
Definition: MCAsmMacro.h:48
llvm::MCAsmParser::Lex
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
InsnMatchEntry::Opcode
uint64_t Opcode
Definition: SystemZAsmParser.cpp:619
CompareInsn
Definition: SystemZAsmParser.cpp:625
printMCExpr
static void printMCExpr(const MCExpr *E, raw_ostream &OS)
Definition: SystemZAsmParser.cpp:705
llvm::MCAsmParser::parseExpression
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:201
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition: TargetRegistry.h:1398
llvm::SystemZMC::CR64Regs
const unsigned CR64Regs[16]
Definition: SystemZMCTargetDesc.cpp:124
llvm::MatchOperand_Success
@ MatchOperand_Success
Definition: MCTargetAsmParser.h:128
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
getReg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:521
InsnMatchEntry
Definition: SystemZAsmParser.cpp:617
llvm::getTheSystemZTarget
Target & getTheSystemZTarget()
Definition: SystemZTargetInfo.cpp:14
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
MCContext.h
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:423
MCInstrInfo.h
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCSymbolRefExpr::VK_TLSLDM
@ VK_TLSLDM
Definition: MCExpr.h:211
llvm::AD_ATT
@ AD_ATT
Definition: SystemZMCAsmInfo.h:18
MCInst.h
llvm::SystemZMC::GR32Regs
const unsigned GR32Regs[16]
Definition: SystemZMCTargetDesc.cpp:35
llvm::dwarf::Index
Index
Definition: Dwarf.h:550
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
llvm::MCAsmParser::getContext
virtual MCContext & getContext()=0
SMLoc.h
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::MCAsmParser::addAliasForDirective
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
getSubtargetFeatureName
static const char * getSubtargetFeatureName(uint64_t Val)
llvm::MCTargetStreamer
Target specific streamer interface.
Definition: MCStreamer.h:93
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
isNot
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Definition: AMDGPULegalizerInfo.cpp:3198
llvm::AsmToken::Percent
@ Percent
Definition: MCAsmMacro.h:52
Register
Promote Memory to Register
Definition: Mem2Reg.cpp:110
InsnMatchTable
static struct InsnMatchEntry InsnMatchTable[]
Definition: SystemZAsmParser.cpp:638
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:74
inRange
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue, bool AllowSymbol=false)
Definition: SystemZAsmParser.cpp:46
llvm::HighlightColor::Remark
@ Remark
MCAsmLexer.h
llvm::ParseInstructionInfo
Definition: MCTargetAsmParser.h:119
llvm::MCSymbolRefExpr::VariantKind
VariantKind
Definition: MCExpr.h:194
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
uint64_t
llvm::MCContext::getAsmInfo
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
llvm::MCAsmParserExtension::Initialize
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Definition: MCAsmParserExtension.cpp:21
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1096
llvm::AsmToken::Colon
@ Colon
Definition: MCAsmMacro.h:43
llvm::MatchOperand_ParseFail
@ MatchOperand_ParseFail
Definition: MCTargetAsmParser.h:130
I
#define I(x, y, z)
Definition: MD5.cpp:58
LLVMInitializeSystemZAsmParser
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser()
Definition: SystemZAsmParser.cpp:1748
llvm::MCInstBuilder
Definition: MCInstBuilder.h:21
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1869
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::FeatureBitset::size
constexpr size_t size() const
Definition: SubtargetFeature.h:90
llvm::WinEH::EncodingType::CE
@ CE
Windows NT (Windows on ARM)
llvm::Length
@ Length
Definition: DWP.cpp:406
llvm::SystemZMC::FP64Regs
const unsigned FP64Regs[16]
Definition: SystemZMCTargetDesc.cpp:70
llvm::ErrorInfo
Base class for user error types.
Definition: Error.h:348
llvm::MCTargetOptions
Definition: MCTargetOptions.h:37
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition: MipsInstPrinter.cpp:31
llvm::AsmToken::Comma
@ Comma
Definition: MCAsmMacro.h:49
llvm::print
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
Definition: GCNRegPressure.cpp:138
llvm::MCBinaryExpr::createAdd
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:525
llvm::SystemZMC::GRH32Regs
const unsigned GRH32Regs[16]
Definition: SystemZMCTargetDesc.cpp:42
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:173
MCAsmInfo.h
llvm::MatchOperand_NoMatch
@ MatchOperand_NoMatch
Definition: MCTargetAsmParser.h:129
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::MCAsmParser::getTok
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:40
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
llvm::AsmToken::Space
@ Space
Definition: MCAsmMacro.h:44
llvm::AsmToken::RParen
@ RParen
Definition: MCAsmMacro.h:48
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:318
llvm::AsmToken::getString
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::OperandMatchResultTy
OperandMatchResultTy
Definition: MCTargetAsmParser.h:127
llvm::AD_HLASM
@ AD_HLASM
Definition: SystemZMCAsmInfo.h:18
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition: MCInst.h:203
llvm::AsmToken::Identifier
@ Identifier
Definition: MCAsmMacro.h:28
llvm::AsmToken::isNot
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:83
MCAsmParserExtension.h
llvm::SMLoc::getPointer
const char * getPointer() const
Definition: SMLoc.h:34
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:354
llvm::MCBinaryExpr::Sub
@ Sub
Subtraction.
Definition: MCExpr.h:506
Casting.h
llvm::SystemZMC::VR64Regs
const unsigned VR64Regs[32]
Definition: SystemZMCTargetDesc.cpp:95
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::MCTargetAsmParser
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Definition: MCTargetAsmParser.h:315
llvm::object::Identifier
@ Identifier
Definition: COFFModuleDefinition.cpp:34
llvm::MCSymbolRefExpr::VK_TLSGD
@ VK_TLSGD
Definition: MCExpr.h:209
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
SmallVector.h
llvm::MCStreamer::getTargetStreamer
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:300
llvm::MCAsmParser::parseGNUAttribute
bool parseGNUAttribute(SMLoc L, int64_t &Tag, int64_t &IntegerValue)
Parse a .gnu_attribute.
Definition: MCAsmParser.cpp:145
llvm::SMRange
Represents a range in source code.
Definition: SMLoc.h:48
llvm::AsmToken::getIdentifier
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition: MCAsmMacro.h:99
N
#define N
MCStreamer.h
llvm::isMem
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:131
llvm::MCSubtargetInfo::setDefaultFeatures
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
Definition: MCSubtargetInfo.cpp:220
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::AsmToken::String
@ String
Definition: MCAsmMacro.h:29
InsnMatchEntry::Format
StringRef Format
Definition: SystemZAsmParser.cpp:618
llvm::AsmToken::getLoc
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
TargetRegistry.h
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::FeatureBitset::any
bool any() const
Definition: SubtargetFeature.h:92
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::SystemZMC::VR32Regs
const unsigned VR32Regs[32]
Definition: SystemZMCTargetDesc.cpp:84
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
llvm::MCStreamer::emitGNUAttribute
virtual void emitGNUAttribute(unsigned Tag, unsigned Value)
Emit a .gnu_attribute directive.
Definition: MCStreamer.h:664
SystemZMCAsmInfo.h