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