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