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