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