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
9#include "MCTargetDesc/SystemZGNUInstPrinter.h"
10#include "MCTargetDesc/SystemZMCAsmInfo.h"
11#include "MCTargetDesc/SystemZMCTargetDesc.h"
12#include "MCTargetDesc/SystemZTargetStreamer.h"
13#include "TargetInfo/SystemZTargetInfo.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringExtras.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"
22#include "llvm/MC/MCInstBuilder.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCParser/AsmLexer.h"
25#include "llvm/MC/MCParser/MCAsmParser.h"
26#include "llvm/MC/MCParser/MCAsmParserExtension.h"
27#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
28#include "llvm/MC/MCParser/MCTargetAsmParser.h"
29#include "llvm/MC/MCRegisterInfo.h"
30#include "llvm/MC/MCStreamer.h"
31#include "llvm/MC/MCSubtargetInfo.h"
32#include "llvm/MC/TargetRegistry.h"
33#include "llvm/Support/Casting.h"
34#include "llvm/Support/Compiler.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/SMLoc.h"
37#include "llvm/TargetParser/SubtargetFeature.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>(Val: 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)
155 Inst.addOperand(Op: MCOperand::createImm(Val: 0));
156 else if (auto *CE = dyn_cast<MCConstantExpr>(Val: Expr))
157 Inst.addOperand(Op: MCOperand::createImm(Val: CE->getValue()));
158 else
159 Inst.addOperand(Op: MCOperand::createExpr(Val: Expr));
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>(args: KindInvalid, args&: StartLoc, args&: EndLoc);
170 }
171
172 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
173 auto Op = std::make_unique<SystemZOperand>(args: KindToken, args&: Loc, args&: 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>(args: KindReg, args&: StartLoc, args&: 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>(args: KindImm, args&: StartLoc, args&: 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>(args: KindMem, args&: StartLoc, args&: 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>(args: KindImmTLS, args&: StartLoc, args&: 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(Expr: Imm, MinValue, MaxValue, AllowSymbol: 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(Expr: Mem.Disp, MinValue: 0, MaxValue: 0xfff, AllowSymbol: true);
279 }
280 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
281 return isMem(MemKind, RegKind) && inRange(Expr: Mem.Disp, MinValue: -524288, MaxValue: 524287, AllowSymbol: true);
282 }
283 bool isMemDisp12Len4(RegisterKind RegKind) const {
284 return isMemDisp12(MemKind: BDLMem, RegKind) && inRange(Expr: Mem.Length.Imm, MinValue: 1, MaxValue: 0x10);
285 }
286 bool isMemDisp12Len8(RegisterKind RegKind) const {
287 return isMemDisp12(MemKind: BDLMem, RegKind) && inRange(Expr: Mem.Length.Imm, MinValue: 1, MaxValue: 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");
308 Inst.addOperand(Op: MCOperand::createReg(Reg: getReg()));
309 }
310 void addImmOperands(MCInst &Inst, unsigned N) const {
311 assert(N == 1 && "Invalid number of operands");
312 addExpr(Inst, Expr: 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(Op: MCOperand::createReg(Reg: Mem.Base));
318 addExpr(Inst, Expr: 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(Op: MCOperand::createReg(Reg: Mem.Base));
324 addExpr(Inst, Expr: Mem.Disp);
325 Inst.addOperand(Op: MCOperand::createReg(Reg: 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(Op: MCOperand::createReg(Reg: Mem.Base));
331 addExpr(Inst, Expr: Mem.Disp);
332 addExpr(Inst, Expr: 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(Op: MCOperand::createReg(Reg: Mem.Base));
338 addExpr(Inst, Expr: Mem.Disp);
339 Inst.addOperand(Op: MCOperand::createReg(Reg: 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(Op: MCOperand::createReg(Reg: Mem.Base));
345 addExpr(Inst, Expr: Mem.Disp);
346 Inst.addOperand(Op: MCOperand::createReg(Reg: 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(Op: MCOperand::createReg(Reg: Mem.Base));
352 addExpr(Inst, Expr: Mem.Disp);
353 Inst.addOperand(Op: MCOperand::createReg(Reg: 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, Expr: ImmTLS.Imm);
359 if (ImmTLS.Sym)
360 addExpr(Inst, Expr: ImmTLS.Sym);
361 }
362
363 // Used by the TableGen code to check for particular operand types.
364 bool isGR32() const { return isReg(RegKind: GR32Reg); }
365 bool isGRH32() const { return isReg(RegKind: GRH32Reg); }
366 bool isGRX32() const { return false; }
367 bool isGR64() const { return isReg(RegKind: GR64Reg); }
368 bool isGR128() const { return isReg(RegKind: GR128Reg); }
369 bool isADDR32() const { return isReg(RegKind: GR32Reg); }
370 bool isADDR64() const { return isReg(RegKind: GR64Reg); }
371 bool isADDR128() const { return false; }
372 bool isFP16() const { return isReg(RegKind: FP16Reg); }
373 bool isFP32() const { return isReg(RegKind: FP32Reg); }
374 bool isFP64() const { return isReg(RegKind: FP64Reg); }
375 bool isFP128() const { return isReg(RegKind: FP128Reg); }
376 bool isVR16() const { return isReg(RegKind: VR16Reg); }
377 bool isVR32() const { return isReg(RegKind: VR32Reg); }
378 bool isVR64() const { return isReg(RegKind: VR64Reg); }
379 bool isVF128() const { return false; }
380 bool isVR128() const { return isReg(RegKind: VR128Reg); }
381 bool isAR32() const { return isReg(RegKind: AR32Reg); }
382 bool isCR64() const { return isReg(RegKind: CR64Reg); }
383 bool isAnyReg() const { return (isReg() || isImm(MinValue: 0, MaxValue: 15)); }
384 bool isBDAddr32Disp12() const { return isMemDisp12(MemKind: BDMem, RegKind: GR32Reg); }
385 bool isBDAddr32Disp20() const { return isMemDisp20(MemKind: BDMem, RegKind: GR32Reg); }
386 bool isBDAddr64Disp12() const { return isMemDisp12(MemKind: BDMem, RegKind: GR64Reg); }
387 bool isBDAddr64Disp20() const { return isMemDisp20(MemKind: BDMem, RegKind: GR64Reg); }
388 bool isBDXAddr64Disp12() const { return isMemDisp12(MemKind: BDXMem, RegKind: GR64Reg); }
389 bool isBDXAddr64Disp20() const { return isMemDisp20(MemKind: BDXMem, RegKind: GR64Reg); }
390 bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(RegKind: GR64Reg); }
391 bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(RegKind: GR64Reg); }
392 bool isBDRAddr64Disp12() const { return isMemDisp12(MemKind: BDRMem, RegKind: GR64Reg); }
393 bool isBDVAddr64Disp12() const { return isMemDisp12(MemKind: BDVMem, RegKind: GR64Reg); }
394 bool isLXAAddr64Disp20() const { return isMemDisp20(MemKind: LXAMem, RegKind: GR64Reg); }
395 bool isU1Imm() const { return isImm(MinValue: 0, MaxValue: 1); }
396 bool isU2Imm() const { return isImm(MinValue: 0, MaxValue: 3); }
397 bool isU3Imm() const { return isImm(MinValue: 0, MaxValue: 7); }
398 bool isU4Imm() const { return isImm(MinValue: 0, MaxValue: 15); }
399 bool isU8Imm() const { return isImm(MinValue: 0, MaxValue: 255); }
400 bool isS8Imm() const { return isImm(MinValue: -128, MaxValue: 127); }
401 bool isU12Imm() const { return isImm(MinValue: 0, MaxValue: 4095); }
402 bool isU16Imm() const { return isImm(MinValue: 0, MaxValue: 65535); }
403 bool isS16Imm() const { return isImm(MinValue: -32768, MaxValue: 32767); }
404 bool isU32Imm() const { return isImm(MinValue: 0, MaxValue: (1LL << 32) - 1); }
405 bool isS32Imm() const { return isImm(MinValue: -(1LL << 31), MaxValue: (1LL << 31) - 1); }
406 bool isU48Imm() const { return isImm(MinValue: 0, MaxValue: (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(Range: "_@#$", Element: 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) {
507 MCAsmParserExtension::Initialize(Parser);
508
509 // Alias the .word directive to .short.
510 parser.addAliasForDirective(Directive: ".word", Alias: ".short");
511
512 // Initialize the set of available features.
513 setAvailableFeatures(ComputeAvailableFeatures(FB: 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, Kind: GR32Reg);
534 }
535 ParseStatus parseGRH32(OperandVector &Operands) {
536 return parseRegister(Operands, Kind: 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, Kind: GR64Reg);
543 }
544 ParseStatus parseGR128(OperandVector &Operands) {
545 return parseRegister(Operands, Kind: GR128Reg);
546 }
547 ParseStatus parseADDR32(OperandVector &Operands) {
548 // For the AsmParser, we will accept %r0 for ADDR32 as well.
549 return parseRegister(Operands, Kind: GR32Reg);
550 }
551 ParseStatus parseADDR64(OperandVector &Operands) {
552 // For the AsmParser, we will accept %r0 for ADDR64 as well.
553 return parseRegister(Operands, Kind: 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, Kind: FP16Reg);
560 }
561 ParseStatus parseFP32(OperandVector &Operands) {
562 return parseRegister(Operands, Kind: FP32Reg);
563 }
564 ParseStatus parseFP64(OperandVector &Operands) {
565 return parseRegister(Operands, Kind: FP64Reg);
566 }
567 ParseStatus parseFP128(OperandVector &Operands) {
568 return parseRegister(Operands, Kind: FP128Reg);
569 }
570 ParseStatus parseVR16(OperandVector &Operands) {
571 return parseRegister(Operands, Kind: VR16Reg);
572 }
573 ParseStatus parseVR32(OperandVector &Operands) {
574 return parseRegister(Operands, Kind: VR32Reg);
575 }
576 ParseStatus parseVR64(OperandVector &Operands) {
577 return parseRegister(Operands, Kind: 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, Kind: VR128Reg);
584 }
585 ParseStatus parseAR32(OperandVector &Operands) {
586 return parseRegister(Operands, Kind: AR32Reg);
587 }
588 ParseStatus parseCR64(OperandVector &Operands) {
589 return parseRegister(Operands, Kind: CR64Reg);
590 }
591 ParseStatus parseAnyReg(OperandVector &Operands) {
592 return parseAnyRegister(Operands);
593 }
594 ParseStatus parseBDAddr32(OperandVector &Operands) {
595 return parseAddress(Operands, MemKind: BDMem, RegKind: GR32Reg);
596 }
597 ParseStatus parseBDAddr64(OperandVector &Operands) {
598 return parseAddress(Operands, MemKind: BDMem, RegKind: GR64Reg);
599 }
600 ParseStatus parseBDXAddr64(OperandVector &Operands) {
601 return parseAddress(Operands, MemKind: BDXMem, RegKind: GR64Reg);
602 }
603 ParseStatus parseBDLAddr64(OperandVector &Operands) {
604 return parseAddress(Operands, MemKind: BDLMem, RegKind: GR64Reg);
605 }
606 ParseStatus parseBDRAddr64(OperandVector &Operands) {
607 return parseAddress(Operands, MemKind: BDRMem, RegKind: GR64Reg);
608 }
609 ParseStatus parseBDVAddr64(OperandVector &Operands) {
610 return parseAddress(Operands, MemKind: BDVMem, RegKind: GR64Reg);
611 }
612 ParseStatus parseLXAAddr64(OperandVector &Operands) {
613 return parseAddress(Operands, MemKind: LXAMem, RegKind: GR64Reg);
614 }
615 ParseStatus parsePCRel12(OperandVector &Operands) {
616 return parsePCRel(Operands, MinVal: -(1LL << 12), MaxVal: (1LL << 12) - 1, AllowTLS: false);
617 }
618 ParseStatus parsePCRel16(OperandVector &Operands) {
619 return parsePCRel(Operands, MinVal: -(1LL << 16), MaxVal: (1LL << 16) - 1, AllowTLS: false);
620 }
621 ParseStatus parsePCRel24(OperandVector &Operands) {
622 return parsePCRel(Operands, MinVal: -(1LL << 24), MaxVal: (1LL << 24) - 1, AllowTLS: false);
623 }
624 ParseStatus parsePCRel32(OperandVector &Operands) {
625 return parsePCRel(Operands, MinVal: -(1LL << 32), MaxVal: (1LL << 32) - 1, AllowTLS: false);
626 }
627 ParseStatus parsePCRelTLS16(OperandVector &Operands) {
628 return parsePCRel(Operands, MinVal: -(1LL << 16), MaxVal: (1LL << 16) - 1, AllowTLS: true);
629 }
630 ParseStatus parsePCRelTLS32(OperandVector &Operands) {
631 return parsePCRel(Operands, MinVal: -(1LL << 32), MaxVal: (1LL << 32) - 1, AllowTLS: 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.
645struct InsnMatchEntry {
646 StringRef Format;
647 uint64_t Opcode;
648 int32_t NumOperands;
649 MatchClassKind OperandKinds[7];
650};
651
652// For equal_range comparison.
653struct CompareInsn {
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.
666static struct InsnMatchEntry InsnMatchTable[] = {
667 /* Format, Opcode, NumOperands, OperandKinds */
668 { .Format: "e", .Opcode: SystemZ::InsnE, .NumOperands: 1,
669 .OperandKinds: { MCK_U16Imm } },
670 { .Format: "ri", .Opcode: SystemZ::InsnRI, .NumOperands: 3,
671 .OperandKinds: { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
672 { .Format: "rie", .Opcode: SystemZ::InsnRIE, .NumOperands: 4,
673 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
674 { .Format: "ril", .Opcode: SystemZ::InsnRIL, .NumOperands: 3,
675 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
676 { .Format: "rilu", .Opcode: SystemZ::InsnRILU, .NumOperands: 3,
677 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
678 { .Format: "ris", .Opcode: SystemZ::InsnRIS, .NumOperands: 5,
679 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
680 { .Format: "rr", .Opcode: SystemZ::InsnRR, .NumOperands: 3,
681 .OperandKinds: { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
682 { .Format: "rre", .Opcode: SystemZ::InsnRRE, .NumOperands: 3,
683 .OperandKinds: { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
684 { .Format: "rrf", .Opcode: SystemZ::InsnRRF, .NumOperands: 5,
685 .OperandKinds: { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
686 { .Format: "rrs", .Opcode: SystemZ::InsnRRS, .NumOperands: 5,
687 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
688 { .Format: "rs", .Opcode: SystemZ::InsnRS, .NumOperands: 4,
689 .OperandKinds: { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
690 { .Format: "rse", .Opcode: SystemZ::InsnRSE, .NumOperands: 4,
691 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
692 { .Format: "rsi", .Opcode: SystemZ::InsnRSI, .NumOperands: 4,
693 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
694 { .Format: "rsy", .Opcode: SystemZ::InsnRSY, .NumOperands: 4,
695 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
696 { .Format: "rx", .Opcode: SystemZ::InsnRX, .NumOperands: 3,
697 .OperandKinds: { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
698 { .Format: "rxe", .Opcode: SystemZ::InsnRXE, .NumOperands: 3,
699 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
700 { .Format: "rxf", .Opcode: SystemZ::InsnRXF, .NumOperands: 4,
701 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
702 { .Format: "rxy", .Opcode: SystemZ::InsnRXY, .NumOperands: 3,
703 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
704 { .Format: "s", .Opcode: SystemZ::InsnS, .NumOperands: 2,
705 .OperandKinds: { MCK_U32Imm, MCK_BDAddr64Disp12 } },
706 { .Format: "si", .Opcode: SystemZ::InsnSI, .NumOperands: 3,
707 .OperandKinds: { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
708 { .Format: "sil", .Opcode: SystemZ::InsnSIL, .NumOperands: 3,
709 .OperandKinds: { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
710 { .Format: "siy", .Opcode: SystemZ::InsnSIY, .NumOperands: 3,
711 .OperandKinds: { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
712 { .Format: "ss", .Opcode: SystemZ::InsnSS, .NumOperands: 4,
713 .OperandKinds: { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
714 { .Format: "sse", .Opcode: SystemZ::InsnSSE, .NumOperands: 3,
715 .OperandKinds: { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
716 { .Format: "ssf", .Opcode: SystemZ::InsnSSF, .NumOperands: 4,
717 .OperandKinds: { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
718 { .Format: "vri", .Opcode: SystemZ::InsnVRI, .NumOperands: 6,
719 .OperandKinds: { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
720 { .Format: "vrr", .Opcode: SystemZ::InsnVRR, .NumOperands: 7,
721 .OperandKinds: { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
722 MCK_U4Imm } },
723 { .Format: "vrs", .Opcode: SystemZ::InsnVRS, .NumOperands: 5,
724 .OperandKinds: { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
725 { .Format: "vrv", .Opcode: SystemZ::InsnVRV, .NumOperands: 4,
726 .OperandKinds: { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
727 { .Format: "vrx", .Opcode: SystemZ::InsnVRX, .NumOperands: 4,
728 .OperandKinds: { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
729 { .Format: "vsi", .Opcode: SystemZ::InsnVSI, .NumOperands: 4,
730 .OperandKinds: { 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:
739 OS << "Reg:" << SystemZGNUInstPrinter::getRegisterName(Reg: getReg());
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>(Val: Op.Disp));
757 if (Op.Base) {
758 OS << "(";
759 if (Op.MemKind == BDLMem) {
760 MAI.printExpr(OS, *cast<MCConstantExpr>(Val: Op.Length.Imm));
761 OS << ',';
762 } else if (Op.MemKind == BDRMem)
763 OS << SystemZGNUInstPrinter::getRegisterName(Reg: Op.Length.Reg) << ",";
764 if (Op.Index)
765 OS << SystemZGNUInstPrinter::getRegisterName(Reg: Op.Index) << ",";
766 OS << SystemZGNUInstPrinter::getRegisterName(Reg: Op.Base);
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(K: AsmToken::Percent);
781
782 Reg.StartLoc = PercentTok.getLoc();
783
784 if (RequirePercent && PercentTok.isNot(K: AsmToken::Percent))
785 return Error(L: PercentTok.getLoc(), Msg: "register expected");
786
787 if (HasPercent) {
788 Parser.Lex(); // Eat percent token.
789 }
790
791 // Expect a register name.
792 if (Parser.getTok().isNot(K: AsmToken::Identifier)) {
793 if (RestoreOnFailure && HasPercent)
794 getLexer().UnLex(Token: PercentTok);
795 return Error(L: Reg.StartLoc,
796 Msg: 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(Token: PercentTok);
804 return Error(L: Reg.StartLoc, Msg: "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(Start: 1).getAsInteger(Radix: 10, Result&: Reg.Num)) {
810 if (RestoreOnFailure && HasPercent)
811 getLexer().UnLex(Token: PercentTok);
812 return Error(L: Reg.StartLoc, Msg: "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(Token: PercentTok);
829 return Error(L: Reg.StartLoc, Msg: "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) {
840 Register Reg;
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(K: AsmToken::Percent)) {
871 if (parseRegister(Reg, /*RequirePercent=*/true))
872 return ParseStatus::Failure;
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(L: Reg.StartLoc, Msg: "invalid operand for instruction");
883 break;
884 case RegV:
885 if (Reg.Group != RegV && Reg.Group != RegFP)
886 return Error(L: Reg.StartLoc, Msg: "invalid operand for instruction");
887 break;
888 }
889 } else if (Parser.getTok().is(K: AsmToken::Integer)) {
890 if (parseIntegerRegister(Reg, Group))
891 return ParseStatus::Failure;
892 }
893 // Otherwise we didn't match a register operand.
894 else
895 return ParseStatus::NoMatch;
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(L: Reg.StartLoc, Msg: "invalid register pair");
919
920 Operands.push_back(
921 Elt: SystemZOperand::createReg(Kind, Num: Regs[Reg.Num], StartLoc: Reg.StartLoc, EndLoc: Reg.EndLoc));
922 return ParseStatus::Success;
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(K: AsmToken::Integer)) {
931 const MCExpr *Register;
932 if (Parser.parseExpression(Res&: Register))
933 return ParseStatus::Failure;
934
935 if (auto *CE = dyn_cast<MCConstantExpr>(Val: Register)) {
936 int64_t Value = CE->getValue();
937 if (Value < 0 || Value > 15)
938 return Error(L: StartLoc, Msg: "invalid register");
939 }
940
941 SMLoc EndLoc =
942 SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
943
944 Operands.push_back(Elt: SystemZOperand::createImm(Expr: Register, StartLoc, EndLoc));
945 }
946 else {
947 if (isParsingHLASM())
948 return ParseStatus::NoMatch;
949
950 Register Reg;
951 if (parseRegister(Reg, /*RequirePercent=*/true))
952 return ParseStatus::Failure;
953
954 if (Reg.Num > 15)
955 return Error(L: StartLoc, Msg: "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 {
981 return ParseStatus::Failure;
982 }
983
984 Operands.push_back(Elt: SystemZOperand::createReg(Kind, Num: RegNo,
985 StartLoc: Reg.StartLoc, EndLoc: Reg.EndLoc));
986 }
987 return ParseStatus::Success;
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(Res&: Register))
996 return true;
997
998 const auto *CE = dyn_cast<MCConstantExpr>(Val: 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(L: Parser.getTok().getLoc(), Msg: "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(Ptr: 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(Res&: 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(K: AsmToken::LParen)) {
1053 Parser.Lex();
1054
1055 if (isParsingGNU() && getLexer().is(K: AsmToken::Percent)) {
1056 // Parse the first register.
1057 HaveReg1 = true;
1058 if (parseRegister(Reg&: 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(K: 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(Res&: 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(Reg&: Reg1, Group: 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(Res&: Length))
1085 return true;
1086 }
1087 }
1088
1089 // Check whether there's a second register.
1090 if (getLexer().is(K: AsmToken::Comma)) {
1091 Parser.Lex();
1092 HaveReg2 = true;
1093
1094 if (getLexer().is(K: AsmToken::Integer)) {
1095 if (parseIntegerRegister(Reg&: Reg2, Group: RegGR))
1096 return true;
1097 } else if (isParsingGNU()) {
1098 if (Parser.getTok().is(K: AsmToken::Percent)) {
1099 if (parseRegister(Reg&: 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(K: AsmToken::RParen))
1112 return Error(L: Parser.getTok().getLoc(), Msg: "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(L: Reg.StartLoc, Msg: "invalid use of vector addressing");
1123 return true;
1124 }
1125 if (Reg.Group != RegGR) {
1126 Error(L: Reg.StartLoc, Msg: "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(Reg&: 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(L: StartLoc, Msg: "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(Reg&: 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(Reg&: 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(Reg&: 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(L: StartLoc, Msg: "invalid use of indexed addressing");
1204 // We must have a length.
1205 if (!Length)
1206 return Error(L: StartLoc, Msg: "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(L: StartLoc, Msg: "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(Reg&: 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(L: StartLoc, Msg: "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(L: Reg1.StartLoc, Msg: "invalid use of vector addressing");
1229 // If we have Reg2, it must be an address register.
1230 if (HaveReg2) {
1231 if (parseAddressRegister(Reg&: Reg2))
1232 return ParseStatus::Failure;
1233 Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];
1234 }
1235 break;
1236 }
1237
1238 SMLoc EndLoc =
1239 SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1240 Operands.push_back(Elt: SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
1241 Index, LengthImm: 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(L: DirectiveID.getLoc());
1251 if (IDVal == ".machine")
1252 return parseDirectiveMachine(L: DirectiveID.getLoc());
1253 if (IDVal.starts_with(Prefix: ".gnu_attribute"))
1254 return parseGNUAttribute(L: 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(Res&: Format))
1268 return Error(L: ErrorLoc, Msg: "expected instruction format");
1269
1270 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
1271
1272 // Find entry for this format in InsnMatchTable.
1273 auto EntryRange =
1274 std::equal_range(first: std::begin(arr&: InsnMatchTable), last: std::end(arr&: InsnMatchTable),
1275 val: Format, comp: CompareInsn());
1276
1277 // If first == second, couldn't find a match in the table.
1278 if (EntryRange.first == EntryRange.second)
1279 return Error(L: ErrorLoc, Msg: "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(K: AsmToken::Comma))
1294 return Error(L: StartLoc, Msg: "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(Res&: Expr))
1322 return Error(L: StartLoc, Msg: "unexpected token in directive");
1323
1324 SMLoc EndLoc =
1325 SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1326
1327 Operands.push_back(Elt: 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(GOp&: Operand, Kind, STI: *STI);
1344 if (Res != Match_Success)
1345 return Error(L: Operand.getStartLoc(), Msg: "unexpected operand type");
1346
1347 // Add operands to instruction.
1348 SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);
1349 if (ZOperand.isReg())
1350 ZOperand.addRegOperands(Inst, N: 1);
1351 else if (ZOperand.isMem(MemKind: BDMem))
1352 ZOperand.addBDAddrOperands(Inst, N: 2);
1353 else if (ZOperand.isMem(MemKind: BDXMem))
1354 ZOperand.addBDXAddrOperands(Inst, N: 3);
1355 else if (ZOperand.isMem(MemKind: BDVMem))
1356 ZOperand.addBDVAddrOperands(Inst, N: 3);
1357 else if (ZOperand.isMem(MemKind: LXAMem))
1358 ZOperand.addLXAAddrOperands(Inst, N: 3);
1359 else if (ZOperand.isImm())
1360 ZOperand.addImmOperands(Inst, N: 1);
1361 else
1362 llvm_unreachable("unexpected operand type");
1363 }
1364
1365 // Emit as a regular instruction.
1366 Parser.getStreamer().emitInstruction(Inst, STI: 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(K: AsmToken::Identifier) &&
1376 Parser.getTok().isNot(K: AsmToken::String))
1377 return TokError(Msg: "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(Elt: 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(L: IdLoc,
1394 Msg: "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(CPU: Id, /*TuneCPU*/ Id, FS: "");
1402 setAvailableFeatures(ComputeAvailableFeatures(FB: STI.getFeatureBits()));
1403 }
1404 getTargetStreamer().emitMachine(CPUOrCommand: 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, Msg: "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, Msg: "unrecognized .gnu_attribute tag/value pair.");
1418
1419 Parser.getStreamer().emitGNUAttribute(Tag, Value: 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(RegNo&: Reg, StartLoc, EndLoc, /*RequirePercent=*/false,
1448 /*RestoreOnFailure=*/false);
1449}
1450
1451ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1452 SMLoc &EndLoc) {
1453 bool Result = ParseRegister(RegNo&: 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,
1466 OperandVector &Operands) {
1467
1468 // Apply mnemonic aliases first, before doing anything else, in
1469 // case the target uses it.
1470 applyMnemonicAliases(Mnemonic&: Name, Features: getAvailableFeatures(), VariantID: getMAIAssemblerDialect());
1471
1472 Operands.push_back(Elt: SystemZOperand::createToken(Str: Name, Loc: NameLoc));
1473
1474 // Read the remaining operands.
1475 if (getLexer().isNot(K: AsmToken::EndOfStatement)) {
1476 // Read the first operand.
1477 if (parseOperand(Operands, Mnemonic: Name)) {
1478 return true;
1479 }
1480
1481 // Read any subsequent operands.
1482 while (getLexer().is(K: AsmToken::Comma)) {
1483 Parser.Lex();
1484
1485 if (isParsingHLASM() && getLexer().is(K: AsmToken::Space))
1486 return Error(
1487 L: Parser.getTok().getLoc(),
1488 Msg: "No space allowed between comma that separates operand entries");
1489
1490 if (parseOperand(Operands, Mnemonic: 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(K: 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(T: Remark);
1514 }
1515
1516 if (getLexer().isNot(K: AsmToken::EndOfStatement)) {
1517 SMLoc Loc = getLexer().getLoc();
1518 return Error(L: Loc, Msg: "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(K: AsmToken::Percent)) {
1554 Register Reg;
1555 if (parseRegister(Reg, /*RequirePercent=*/true))
1556 return true;
1557 Operands.push_back(Elt: SystemZOperand::createInvalid(StartLoc: Reg.StartLoc, EndLoc: 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, Disp&: 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(Reg&: Reg1))
1576 return true;
1577 if (HaveReg2 && parseAddressRegister(Reg&: Reg2))
1578 return true;
1579
1580 SMLoc EndLoc =
1581 SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1582 if (HaveReg1 || HaveReg2 || Length)
1583 Operands.push_back(Elt: SystemZOperand::createInvalid(StartLoc, EndLoc));
1584 else
1585 Operands.push_back(Elt: SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1586 return false;
1587}
1588
1589bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1590 OperandVector &Operands,
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: MatchingInlineAsm, VariantID: Dialect);
1602 switch (MatchResult) {
1603 case Match_Success:
1604 Inst.setLoc(IDLoc);
1605 Out.emitInstruction(Inst, STI: 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 += " ";
1616 Msg += getSubtargetFeatureName(Val: I);
1617 }
1618 }
1619 return Error(L: IDLoc, Msg);
1620 }
1621
1622 case Match_InvalidOperand: {
1623 SMLoc ErrorLoc = IDLoc;
1624 if (ErrorInfo != ~0ULL) {
1625 if (ErrorInfo >= Operands.size())
1626 return Error(L: IDLoc, Msg: "too few operands for instruction");
1627
1628 ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
1629 if (ErrorLoc == SMLoc())
1630 ErrorLoc = IDLoc;
1631 }
1632 return Error(L: ErrorLoc, Msg: "invalid operand for instruction");
1633 }
1634
1635 case Match_MnemonicFail: {
1636 FeatureBitset FBS = ComputeAvailableFeatures(FB: getSTI().getFeatureBits());
1637 std::string Suggestion = SystemZMnemonicSpellCheck(
1638 S: ((SystemZOperand &)*Operands[0]).getToken(), FBS, VariantID: Dialect);
1639 return Error(L: IDLoc, Msg: "invalid instruction" + Suggestion,
1640 Range: ((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(Res&: Expr))
1655 return ParseStatus::NoMatch;
1656
1657 auto IsOutOfRangeConstant = [&](const MCExpr *E, bool Negate) -> bool {
1658 if (auto *CE = dyn_cast<MCConstantExpr>(Val: 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>(Val: Expr)) {
1671 if (isParsingHLASM())
1672 return Error(L: StartLoc, Msg: "Expected PC-relative expression");
1673 if (IsOutOfRangeConstant(CE, false))
1674 return Error(L: StartLoc, Msg: "offset out of range");
1675 int64_t Value = CE->getValue();
1676 MCSymbol *Sym = Ctx.createTempSymbol();
1677 Out.emitLabel(Symbol: Sym);
1678 const MCExpr *Base = MCSymbolRefExpr::create(Symbol: Sym, Ctx);
1679 Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(LHS: Base, RHS: 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>(Val: Expr))
1685 if (IsOutOfRangeConstant(BE->getLHS(), false) ||
1686 IsOutOfRangeConstant(BE->getRHS(),
1687 BE->getOpcode() == MCBinaryExpr::Sub))
1688 return Error(L: StartLoc, Msg: "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(K: AsmToken::Colon)) {
1693 Parser.Lex();
1694
1695 if (Parser.getTok().isNot(K: AsmToken::Identifier))
1696 return Error(L: Parser.getTok().getLoc(), Msg: "unexpected token");
1697
1698 auto Kind = SystemZ::S_None;
1699 StringRef Name = Parser.getTok().getString();
1700 if (Name == "tls_gdcall")
1701 Kind = SystemZ::S_TLSGD;
1702 else if (Name == "tls_ldcall")
1703 Kind = SystemZ::S_TLSLDM;
1704 else
1705 return Error(L: Parser.getTok().getLoc(), Msg: "unknown TLS tag");
1706 Parser.Lex();
1707
1708 if (Parser.getTok().isNot(K: AsmToken::Colon))
1709 return Error(L: Parser.getTok().getLoc(), Msg: "unexpected token");
1710 Parser.Lex();
1711
1712 if (Parser.getTok().isNot(K: AsmToken::Identifier))
1713 return Error(L: Parser.getTok().getLoc(), Msg: "unexpected token");
1714
1715 StringRef Identifier = Parser.getTok().getString();
1716 Sym = MCSymbolRefExpr::create(Symbol: Ctx.getOrCreateSymbol(Name: Identifier),
1717 specifier: Kind, Ctx);
1718 Parser.Lex();
1719 }
1720
1721 SMLoc EndLoc =
1722 SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1);
1723
1724 if (AllowTLS)
1725 Operands.push_back(Elt: SystemZOperand::createImmTLS(Imm: Expr, Sym,
1726 StartLoc, EndLoc));
1727 else
1728 Operands.push_back(Elt: 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(L: Loc, Msg: "HLASM Label cannot be empty");
1754
1755 // An HLASM label cannot exceed greater than 63 characters.
1756 if (RawLabel.size() > 63)
1757 return !Error(L: Loc, Msg: "Maximum length for HLASM Label is 63 characters");
1758
1759 // A label must start with an "alphabetic character".
1760 if (!isHLASMAlpha(C: RawLabel[0]))
1761 return !Error(L: Loc, Msg: "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(C: RawLabel[I]))
1769 return !Error(L: Loc, Msg: "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
1777LLVMInitializeSystemZAsmParser() {
1778 RegisterMCAsmParser<SystemZAsmParser> X(getTheSystemZTarget());
1779}
1780