1 //===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/SystemZGNUInstPrinter.h"
10 #include "MCTargetDesc/SystemZMCAsmInfo.h"
11 #include "MCTargetDesc/SystemZMCTargetDesc.h"
12 #include "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/MCAsmLexer.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/MCStreamer.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/MC/TargetRegistry.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/SMLoc.h"
45 // Return true if Expr is in the range [MinValue, MaxValue]. If AllowSymbol
46 // is true any MCExpr is accepted (address displacement).
47 static bool inRange(const MCExpr
*Expr
, int64_t MinValue
, int64_t MaxValue
,
48 bool AllowSymbol
= false) {
49 if (auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
)) {
50 int64_t Value
= CE
->getValue();
51 return Value
>= MinValue
&& Value
<= MaxValue
;
82 class SystemZOperand
: public MCParsedAsmOperand
{
94 SMLoc StartLoc
, EndLoc
;
96 // A string of length Length, starting at Data.
102 // LLVM register Num, which has kind Kind. In some ways it might be
103 // easier for this class to have a register bank (general, floating-point
104 // or access) and a raw register number (0-15). This would postpone the
105 // interpretation of the operand to the add*() methods and avoid the need
106 // for context-dependent parsing. However, we do things the current way
107 // because of the virtual getReg() method, which needs to distinguish
108 // between (say) %r0 used as a single register and %r0 used as a pair.
109 // Context-dependent parsing can also give us slightly better error
110 // messages when invalid pairs like %r1 are used.
116 // Base + Disp + Index, where Base and Index are LLVM registers or 0.
117 // MemKind says what type of memory this is and RegKind says what type
118 // the base register has (GR32Reg or GR64Reg). Length is the operand
119 // length for D(L,B)-style operands, otherwise it is null.
123 unsigned MemKind
: 4;
124 unsigned RegKind
: 4;
132 // Imm is an immediate operand, and Sym is an optional TLS symbol
133 // for use with a __tls_get_offset marker relocation.
147 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
148 // Add as immediates when possible. Null MCExpr = 0.
150 Inst
.addOperand(MCOperand::createImm(0));
151 else if (auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
))
152 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
154 Inst
.addOperand(MCOperand::createExpr(Expr
));
158 SystemZOperand(OperandKind Kind
, SMLoc StartLoc
, SMLoc EndLoc
)
159 : Kind(Kind
), StartLoc(StartLoc
), EndLoc(EndLoc
) {}
161 // Create particular kinds of operand.
162 static std::unique_ptr
<SystemZOperand
> createInvalid(SMLoc StartLoc
,
164 return std::make_unique
<SystemZOperand
>(KindInvalid
, StartLoc
, EndLoc
);
167 static std::unique_ptr
<SystemZOperand
> createToken(StringRef Str
, SMLoc Loc
) {
168 auto Op
= std::make_unique
<SystemZOperand
>(KindToken
, Loc
, Loc
);
169 Op
->Token
.Data
= Str
.data();
170 Op
->Token
.Length
= Str
.size();
174 static std::unique_ptr
<SystemZOperand
>
175 createReg(RegisterKind Kind
, unsigned Num
, SMLoc StartLoc
, SMLoc EndLoc
) {
176 auto Op
= std::make_unique
<SystemZOperand
>(KindReg
, StartLoc
, EndLoc
);
182 static std::unique_ptr
<SystemZOperand
>
183 createImm(const MCExpr
*Expr
, SMLoc StartLoc
, SMLoc EndLoc
) {
184 auto Op
= std::make_unique
<SystemZOperand
>(KindImm
, StartLoc
, EndLoc
);
189 static std::unique_ptr
<SystemZOperand
>
190 createMem(MemoryKind MemKind
, RegisterKind RegKind
, unsigned Base
,
191 const MCExpr
*Disp
, unsigned Index
, const MCExpr
*LengthImm
,
192 unsigned LengthReg
, SMLoc StartLoc
, SMLoc EndLoc
) {
193 auto Op
= std::make_unique
<SystemZOperand
>(KindMem
, StartLoc
, EndLoc
);
194 Op
->Mem
.MemKind
= MemKind
;
195 Op
->Mem
.RegKind
= RegKind
;
197 Op
->Mem
.Index
= Index
;
199 if (MemKind
== BDLMem
)
200 Op
->Mem
.Length
.Imm
= LengthImm
;
201 if (MemKind
== BDRMem
)
202 Op
->Mem
.Length
.Reg
= LengthReg
;
206 static std::unique_ptr
<SystemZOperand
>
207 createImmTLS(const MCExpr
*Imm
, const MCExpr
*Sym
,
208 SMLoc StartLoc
, SMLoc EndLoc
) {
209 auto Op
= std::make_unique
<SystemZOperand
>(KindImmTLS
, StartLoc
, EndLoc
);
210 Op
->ImmTLS
.Imm
= Imm
;
211 Op
->ImmTLS
.Sym
= Sym
;
216 bool isToken() const override
{
217 return Kind
== KindToken
;
219 StringRef
getToken() const {
220 assert(Kind
== KindToken
&& "Not a token");
221 return StringRef(Token
.Data
, Token
.Length
);
224 // Register operands.
225 bool isReg() const override
{
226 return Kind
== KindReg
;
228 bool isReg(RegisterKind RegKind
) const {
229 return Kind
== KindReg
&& Reg
.Kind
== RegKind
;
231 MCRegister
getReg() const override
{
232 assert(Kind
== KindReg
&& "Not a register");
236 // Immediate operands.
237 bool isImm() const override
{
238 return Kind
== KindImm
;
240 bool isImm(int64_t MinValue
, int64_t MaxValue
) const {
241 return Kind
== KindImm
&& inRange(Imm
, MinValue
, MaxValue
, true);
243 const MCExpr
*getImm() const {
244 assert(Kind
== KindImm
&& "Not an immediate");
248 // Immediate operands with optional TLS symbol.
249 bool isImmTLS() const {
250 return Kind
== KindImmTLS
;
253 const ImmTLSOp
getImmTLS() const {
254 assert(Kind
== KindImmTLS
&& "Not a TLS immediate");
259 bool isMem() const override
{
260 return Kind
== KindMem
;
262 bool isMem(MemoryKind MemKind
) const {
263 return (Kind
== KindMem
&&
264 (Mem
.MemKind
== MemKind
||
265 // A BDMem can be treated as a BDXMem in which the index
266 // register field is 0.
267 (Mem
.MemKind
== BDMem
&& MemKind
== BDXMem
)));
269 bool isMem(MemoryKind MemKind
, RegisterKind RegKind
) const {
270 return isMem(MemKind
) && Mem
.RegKind
== RegKind
;
272 bool isMemDisp12(MemoryKind MemKind
, RegisterKind RegKind
) const {
273 return isMem(MemKind
, RegKind
) && inRange(Mem
.Disp
, 0, 0xfff, true);
275 bool isMemDisp20(MemoryKind MemKind
, RegisterKind RegKind
) const {
276 return isMem(MemKind
, RegKind
) && inRange(Mem
.Disp
, -524288, 524287, true);
278 bool isMemDisp12Len4(RegisterKind RegKind
) const {
279 return isMemDisp12(BDLMem
, RegKind
) && inRange(Mem
.Length
.Imm
, 1, 0x10);
281 bool isMemDisp12Len8(RegisterKind RegKind
) const {
282 return isMemDisp12(BDLMem
, RegKind
) && inRange(Mem
.Length
.Imm
, 1, 0x100);
285 const MemOp
& getMem() const {
286 assert(Kind
== KindMem
&& "Not a Mem operand");
290 // Override MCParsedAsmOperand.
291 SMLoc
getStartLoc() const override
{ return StartLoc
; }
292 SMLoc
getEndLoc() const override
{ return EndLoc
; }
293 void print(raw_ostream
&OS
) const override
;
295 /// getLocRange - Get the range between the first and last token of this
297 SMRange
getLocRange() const { return SMRange(StartLoc
, EndLoc
); }
299 // Used by the TableGen code to add particular types of operand
300 // to an instruction.
301 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
302 assert(N
== 1 && "Invalid number of operands");
303 Inst
.addOperand(MCOperand::createReg(getReg()));
305 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
306 assert(N
== 1 && "Invalid number of operands");
307 addExpr(Inst
, getImm());
309 void addBDAddrOperands(MCInst
&Inst
, unsigned N
) const {
310 assert(N
== 2 && "Invalid number of operands");
311 assert(isMem(BDMem
) && "Invalid operand type");
312 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
313 addExpr(Inst
, Mem
.Disp
);
315 void addBDXAddrOperands(MCInst
&Inst
, unsigned N
) const {
316 assert(N
== 3 && "Invalid number of operands");
317 assert(isMem(BDXMem
) && "Invalid operand type");
318 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
319 addExpr(Inst
, Mem
.Disp
);
320 Inst
.addOperand(MCOperand::createReg(Mem
.Index
));
322 void addBDLAddrOperands(MCInst
&Inst
, unsigned N
) const {
323 assert(N
== 3 && "Invalid number of operands");
324 assert(isMem(BDLMem
) && "Invalid operand type");
325 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
326 addExpr(Inst
, Mem
.Disp
);
327 addExpr(Inst
, Mem
.Length
.Imm
);
329 void addBDRAddrOperands(MCInst
&Inst
, unsigned N
) const {
330 assert(N
== 3 && "Invalid number of operands");
331 assert(isMem(BDRMem
) && "Invalid operand type");
332 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
333 addExpr(Inst
, Mem
.Disp
);
334 Inst
.addOperand(MCOperand::createReg(Mem
.Length
.Reg
));
336 void addBDVAddrOperands(MCInst
&Inst
, unsigned N
) const {
337 assert(N
== 3 && "Invalid number of operands");
338 assert(isMem(BDVMem
) && "Invalid operand type");
339 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
340 addExpr(Inst
, Mem
.Disp
);
341 Inst
.addOperand(MCOperand::createReg(Mem
.Index
));
343 void addLXAAddrOperands(MCInst
&Inst
, unsigned N
) const {
344 assert(N
== 3 && "Invalid number of operands");
345 assert(isMem(LXAMem
) && "Invalid operand type");
346 Inst
.addOperand(MCOperand::createReg(Mem
.Base
));
347 addExpr(Inst
, Mem
.Disp
);
348 Inst
.addOperand(MCOperand::createReg(Mem
.Index
));
350 void addImmTLSOperands(MCInst
&Inst
, unsigned N
) const {
351 assert(N
== 2 && "Invalid number of operands");
352 assert(Kind
== KindImmTLS
&& "Invalid operand type");
353 addExpr(Inst
, ImmTLS
.Imm
);
355 addExpr(Inst
, ImmTLS
.Sym
);
358 // Used by the TableGen code to check for particular operand types.
359 bool isGR32() const { return isReg(GR32Reg
); }
360 bool isGRH32() const { return isReg(GRH32Reg
); }
361 bool isGRX32() const { return false; }
362 bool isGR64() const { return isReg(GR64Reg
); }
363 bool isGR128() const { return isReg(GR128Reg
); }
364 bool isADDR32() const { return isReg(GR32Reg
); }
365 bool isADDR64() const { return isReg(GR64Reg
); }
366 bool isADDR128() const { return false; }
367 bool isFP32() const { return isReg(FP32Reg
); }
368 bool isFP64() const { return isReg(FP64Reg
); }
369 bool isFP128() const { return isReg(FP128Reg
); }
370 bool isVR32() const { return isReg(VR32Reg
); }
371 bool isVR64() const { return isReg(VR64Reg
); }
372 bool isVF128() const { return false; }
373 bool isVR128() const { return isReg(VR128Reg
); }
374 bool isAR32() const { return isReg(AR32Reg
); }
375 bool isCR64() const { return isReg(CR64Reg
); }
376 bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
377 bool isBDAddr32Disp12() const { return isMemDisp12(BDMem
, GR32Reg
); }
378 bool isBDAddr32Disp20() const { return isMemDisp20(BDMem
, GR32Reg
); }
379 bool isBDAddr64Disp12() const { return isMemDisp12(BDMem
, GR64Reg
); }
380 bool isBDAddr64Disp20() const { return isMemDisp20(BDMem
, GR64Reg
); }
381 bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem
, GR64Reg
); }
382 bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem
, GR64Reg
); }
383 bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg
); }
384 bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg
); }
385 bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem
, GR64Reg
); }
386 bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem
, GR64Reg
); }
387 bool isLXAAddr64Disp20() const { return isMemDisp20(LXAMem
, GR64Reg
); }
388 bool isU1Imm() const { return isImm(0, 1); }
389 bool isU2Imm() const { return isImm(0, 3); }
390 bool isU3Imm() const { return isImm(0, 7); }
391 bool isU4Imm() const { return isImm(0, 15); }
392 bool isU8Imm() const { return isImm(0, 255); }
393 bool isS8Imm() const { return isImm(-128, 127); }
394 bool isU12Imm() const { return isImm(0, 4095); }
395 bool isU16Imm() const { return isImm(0, 65535); }
396 bool isS16Imm() const { return isImm(-32768, 32767); }
397 bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
398 bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
399 bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }
402 class SystemZAsmParser
: public MCTargetAsmParser
{
403 #define GET_ASSEMBLER_HEADER
404 #include "SystemZGenAsmMatcher.inc"
418 SMLoc StartLoc
, EndLoc
;
421 SystemZTargetStreamer
&getTargetStreamer() {
422 assert(getParser().getStreamer().getTargetStreamer() &&
423 "do not have a target streamer");
424 MCTargetStreamer
&TS
= *getParser().getStreamer().getTargetStreamer();
425 return static_cast<SystemZTargetStreamer
&>(TS
);
428 bool parseRegister(Register
&Reg
, bool RequirePercent
,
429 bool RestoreOnFailure
= false);
431 bool parseIntegerRegister(Register
&Reg
, RegisterGroup Group
);
433 ParseStatus
parseRegister(OperandVector
&Operands
, RegisterKind Kind
);
435 ParseStatus
parseAnyRegister(OperandVector
&Operands
);
437 bool parseAddress(bool &HaveReg1
, Register
&Reg1
, bool &HaveReg2
,
438 Register
&Reg2
, const MCExpr
*&Disp
, const MCExpr
*&Length
,
439 bool HasLength
= false, bool HasVectorIndex
= false);
440 bool parseAddressRegister(Register
&Reg
);
442 bool ParseDirectiveInsn(SMLoc L
);
443 bool ParseDirectiveMachine(SMLoc L
);
444 bool ParseGNUAttribute(SMLoc L
);
446 ParseStatus
parseAddress(OperandVector
&Operands
, MemoryKind MemKind
,
447 RegisterKind RegKind
);
449 ParseStatus
parsePCRel(OperandVector
&Operands
, int64_t MinVal
,
450 int64_t MaxVal
, bool AllowTLS
);
452 bool parseOperand(OperandVector
&Operands
, StringRef Mnemonic
);
454 // Both the hlasm and gnu variants still rely on the basic gnu asm
455 // format with respect to inputs, clobbers, outputs etc.
457 // However, calling the overriden getAssemblerDialect() method in
458 // AsmParser is problematic. It either returns the AssemblerDialect field
459 // in the MCAsmInfo instance if the AssemblerDialect field in AsmParser is
460 // unset, otherwise it returns the private AssemblerDialect field in
463 // The problematic part is because, we forcibly set the inline asm dialect
464 // in the AsmParser instance in AsmPrinterInlineAsm.cpp. Soo any query
465 // to the overriden getAssemblerDialect function in AsmParser.cpp, will
466 // not return the assembler dialect set in the respective MCAsmInfo instance.
468 // For this purpose, we explicitly query the SystemZMCAsmInfo instance
469 // here, to get the "correct" assembler dialect, and use it in various
471 unsigned getMAIAssemblerDialect() {
472 return Parser
.getContext().getAsmInfo()->getAssemblerDialect();
475 // An alphabetic character in HLASM is a letter from 'A' through 'Z',
476 // or from 'a' through 'z', or '$', '_','#', or '@'.
477 inline bool isHLASMAlpha(char C
) {
478 return isAlpha(C
) || llvm::is_contained("_@#$", C
);
481 // A digit in HLASM is a number from 0 to 9.
482 inline bool isHLASMAlnum(char C
) { return isHLASMAlpha(C
) || isDigit(C
); }
484 // Are we parsing using the AD_HLASM dialect?
485 inline bool isParsingHLASM() { return getMAIAssemblerDialect() == AD_HLASM
; }
487 // Are we parsing using the AD_GNU dialect?
488 inline bool isParsingGNU() { return getMAIAssemblerDialect() == AD_GNU
; }
491 SystemZAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
492 const MCInstrInfo
&MII
,
493 const MCTargetOptions
&Options
)
494 : MCTargetAsmParser(Options
, sti
, MII
), Parser(parser
) {
495 MCAsmParserExtension::Initialize(Parser
);
497 // Alias the .word directive to .short.
498 parser
.addAliasForDirective(".word", ".short");
500 // Initialize the set of available features.
501 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
504 // Override MCTargetAsmParser.
505 ParseStatus
parseDirective(AsmToken DirectiveID
) override
;
506 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
507 bool ParseRegister(MCRegister
&RegNo
, SMLoc
&StartLoc
, SMLoc
&EndLoc
,
508 bool RequirePercent
, bool RestoreOnFailure
);
509 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
510 SMLoc
&EndLoc
) override
;
511 bool parseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
512 SMLoc NameLoc
, OperandVector
&Operands
) override
;
513 bool matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
514 OperandVector
&Operands
, MCStreamer
&Out
,
516 bool MatchingInlineAsm
) override
;
517 bool isLabel(AsmToken
&Token
) override
;
519 // Used by the TableGen code to parse particular operand types.
520 ParseStatus
parseGR32(OperandVector
&Operands
) {
521 return parseRegister(Operands
, GR32Reg
);
523 ParseStatus
parseGRH32(OperandVector
&Operands
) {
524 return parseRegister(Operands
, GRH32Reg
);
526 ParseStatus
parseGRX32(OperandVector
&Operands
) {
527 llvm_unreachable("GRX32 should only be used for pseudo instructions");
529 ParseStatus
parseGR64(OperandVector
&Operands
) {
530 return parseRegister(Operands
, GR64Reg
);
532 ParseStatus
parseGR128(OperandVector
&Operands
) {
533 return parseRegister(Operands
, GR128Reg
);
535 ParseStatus
parseADDR32(OperandVector
&Operands
) {
536 // For the AsmParser, we will accept %r0 for ADDR32 as well.
537 return parseRegister(Operands
, GR32Reg
);
539 ParseStatus
parseADDR64(OperandVector
&Operands
) {
540 // For the AsmParser, we will accept %r0 for ADDR64 as well.
541 return parseRegister(Operands
, GR64Reg
);
543 ParseStatus
parseADDR128(OperandVector
&Operands
) {
544 llvm_unreachable("Shouldn't be used as an operand");
546 ParseStatus
parseFP32(OperandVector
&Operands
) {
547 return parseRegister(Operands
, FP32Reg
);
549 ParseStatus
parseFP64(OperandVector
&Operands
) {
550 return parseRegister(Operands
, FP64Reg
);
552 ParseStatus
parseFP128(OperandVector
&Operands
) {
553 return parseRegister(Operands
, FP128Reg
);
555 ParseStatus
parseVR32(OperandVector
&Operands
) {
556 return parseRegister(Operands
, VR32Reg
);
558 ParseStatus
parseVR64(OperandVector
&Operands
) {
559 return parseRegister(Operands
, VR64Reg
);
561 ParseStatus
parseVF128(OperandVector
&Operands
) {
562 llvm_unreachable("Shouldn't be used as an operand");
564 ParseStatus
parseVR128(OperandVector
&Operands
) {
565 return parseRegister(Operands
, VR128Reg
);
567 ParseStatus
parseAR32(OperandVector
&Operands
) {
568 return parseRegister(Operands
, AR32Reg
);
570 ParseStatus
parseCR64(OperandVector
&Operands
) {
571 return parseRegister(Operands
, CR64Reg
);
573 ParseStatus
parseAnyReg(OperandVector
&Operands
) {
574 return parseAnyRegister(Operands
);
576 ParseStatus
parseBDAddr32(OperandVector
&Operands
) {
577 return parseAddress(Operands
, BDMem
, GR32Reg
);
579 ParseStatus
parseBDAddr64(OperandVector
&Operands
) {
580 return parseAddress(Operands
, BDMem
, GR64Reg
);
582 ParseStatus
parseBDXAddr64(OperandVector
&Operands
) {
583 return parseAddress(Operands
, BDXMem
, GR64Reg
);
585 ParseStatus
parseBDLAddr64(OperandVector
&Operands
) {
586 return parseAddress(Operands
, BDLMem
, GR64Reg
);
588 ParseStatus
parseBDRAddr64(OperandVector
&Operands
) {
589 return parseAddress(Operands
, BDRMem
, GR64Reg
);
591 ParseStatus
parseBDVAddr64(OperandVector
&Operands
) {
592 return parseAddress(Operands
, BDVMem
, GR64Reg
);
594 ParseStatus
parseLXAAddr64(OperandVector
&Operands
) {
595 return parseAddress(Operands
, LXAMem
, GR64Reg
);
597 ParseStatus
parsePCRel12(OperandVector
&Operands
) {
598 return parsePCRel(Operands
, -(1LL << 12), (1LL << 12) - 1, false);
600 ParseStatus
parsePCRel16(OperandVector
&Operands
) {
601 return parsePCRel(Operands
, -(1LL << 16), (1LL << 16) - 1, false);
603 ParseStatus
parsePCRel24(OperandVector
&Operands
) {
604 return parsePCRel(Operands
, -(1LL << 24), (1LL << 24) - 1, false);
606 ParseStatus
parsePCRel32(OperandVector
&Operands
) {
607 return parsePCRel(Operands
, -(1LL << 32), (1LL << 32) - 1, false);
609 ParseStatus
parsePCRelTLS16(OperandVector
&Operands
) {
610 return parsePCRel(Operands
, -(1LL << 16), (1LL << 16) - 1, true);
612 ParseStatus
parsePCRelTLS32(OperandVector
&Operands
) {
613 return parsePCRel(Operands
, -(1LL << 32), (1LL << 32) - 1, true);
617 } // end anonymous namespace
619 #define GET_REGISTER_MATCHER
620 #define GET_SUBTARGET_FEATURE_NAME
621 #define GET_MATCHER_IMPLEMENTATION
622 #define GET_MNEMONIC_SPELL_CHECKER
623 #include "SystemZGenAsmMatcher.inc"
625 // Used for the .insn directives; contains information needed to parse the
626 // operands in the directive.
627 struct InsnMatchEntry
{
631 MatchClassKind OperandKinds
[7];
634 // For equal_range comparison.
636 bool operator() (const InsnMatchEntry
&LHS
, StringRef RHS
) {
637 return LHS
.Format
< RHS
;
639 bool operator() (StringRef LHS
, const InsnMatchEntry
&RHS
) {
640 return LHS
< RHS
.Format
;
642 bool operator() (const InsnMatchEntry
&LHS
, const InsnMatchEntry
&RHS
) {
643 return LHS
.Format
< RHS
.Format
;
647 // Table initializing information for parsing the .insn directive.
648 static struct InsnMatchEntry InsnMatchTable
[] = {
649 /* Format, Opcode, NumOperands, OperandKinds */
650 { "e", SystemZ::InsnE
, 1,
652 { "ri", SystemZ::InsnRI
, 3,
653 { MCK_U32Imm
, MCK_AnyReg
, MCK_S16Imm
} },
654 { "rie", SystemZ::InsnRIE
, 4,
655 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_PCRel16
} },
656 { "ril", SystemZ::InsnRIL
, 3,
657 { MCK_U48Imm
, MCK_AnyReg
, MCK_PCRel32
} },
658 { "rilu", SystemZ::InsnRILU
, 3,
659 { MCK_U48Imm
, MCK_AnyReg
, MCK_U32Imm
} },
660 { "ris", SystemZ::InsnRIS
, 5,
661 { MCK_U48Imm
, MCK_AnyReg
, MCK_S8Imm
, MCK_U4Imm
, MCK_BDAddr64Disp12
} },
662 { "rr", SystemZ::InsnRR
, 3,
663 { MCK_U16Imm
, MCK_AnyReg
, MCK_AnyReg
} },
664 { "rre", SystemZ::InsnRRE
, 3,
665 { MCK_U32Imm
, MCK_AnyReg
, MCK_AnyReg
} },
666 { "rrf", SystemZ::InsnRRF
, 5,
667 { MCK_U32Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_AnyReg
, MCK_U4Imm
} },
668 { "rrs", SystemZ::InsnRRS
, 5,
669 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_U4Imm
, MCK_BDAddr64Disp12
} },
670 { "rs", SystemZ::InsnRS
, 4,
671 { MCK_U32Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_BDAddr64Disp12
} },
672 { "rse", SystemZ::InsnRSE
, 4,
673 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_BDAddr64Disp12
} },
674 { "rsi", SystemZ::InsnRSI
, 4,
675 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_PCRel16
} },
676 { "rsy", SystemZ::InsnRSY
, 4,
677 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_BDAddr64Disp20
} },
678 { "rx", SystemZ::InsnRX
, 3,
679 { MCK_U32Imm
, MCK_AnyReg
, MCK_BDXAddr64Disp12
} },
680 { "rxe", SystemZ::InsnRXE
, 3,
681 { MCK_U48Imm
, MCK_AnyReg
, MCK_BDXAddr64Disp12
} },
682 { "rxf", SystemZ::InsnRXF
, 4,
683 { MCK_U48Imm
, MCK_AnyReg
, MCK_AnyReg
, MCK_BDXAddr64Disp12
} },
684 { "rxy", SystemZ::InsnRXY
, 3,
685 { MCK_U48Imm
, MCK_AnyReg
, MCK_BDXAddr64Disp20
} },
686 { "s", SystemZ::InsnS
, 2,
687 { MCK_U32Imm
, MCK_BDAddr64Disp12
} },
688 { "si", SystemZ::InsnSI
, 3,
689 { MCK_U32Imm
, MCK_BDAddr64Disp12
, MCK_S8Imm
} },
690 { "sil", SystemZ::InsnSIL
, 3,
691 { MCK_U48Imm
, MCK_BDAddr64Disp12
, MCK_U16Imm
} },
692 { "siy", SystemZ::InsnSIY
, 3,
693 { MCK_U48Imm
, MCK_BDAddr64Disp20
, MCK_U8Imm
} },
694 { "ss", SystemZ::InsnSS
, 4,
695 { MCK_U48Imm
, MCK_BDXAddr64Disp12
, MCK_BDAddr64Disp12
, MCK_AnyReg
} },
696 { "sse", SystemZ::InsnSSE
, 3,
697 { MCK_U48Imm
, MCK_BDAddr64Disp12
, MCK_BDAddr64Disp12
} },
698 { "ssf", SystemZ::InsnSSF
, 4,
699 { MCK_U48Imm
, MCK_BDAddr64Disp12
, MCK_BDAddr64Disp12
, MCK_AnyReg
} },
700 { "vri", SystemZ::InsnVRI
, 6,
701 { MCK_U48Imm
, MCK_VR128
, MCK_VR128
, MCK_U12Imm
, MCK_U4Imm
, MCK_U4Imm
} },
702 { "vrr", SystemZ::InsnVRR
, 7,
703 { MCK_U48Imm
, MCK_VR128
, MCK_VR128
, MCK_VR128
, MCK_U4Imm
, MCK_U4Imm
,
705 { "vrs", SystemZ::InsnVRS
, 5,
706 { MCK_U48Imm
, MCK_AnyReg
, MCK_VR128
, MCK_BDAddr64Disp12
, MCK_U4Imm
} },
707 { "vrv", SystemZ::InsnVRV
, 4,
708 { MCK_U48Imm
, MCK_VR128
, MCK_BDVAddr64Disp12
, MCK_U4Imm
} },
709 { "vrx", SystemZ::InsnVRX
, 4,
710 { MCK_U48Imm
, MCK_VR128
, MCK_BDXAddr64Disp12
, MCK_U4Imm
} },
711 { "vsi", SystemZ::InsnVSI
, 4,
712 { MCK_U48Imm
, MCK_VR128
, MCK_BDAddr64Disp12
, MCK_U8Imm
} }
715 static void printMCExpr(const MCExpr
*E
, raw_ostream
&OS
) {
718 if (auto *CE
= dyn_cast
<MCConstantExpr
>(E
))
720 else if (auto *UE
= dyn_cast
<MCUnaryExpr
>(E
))
722 else if (auto *BE
= dyn_cast
<MCBinaryExpr
>(E
))
724 else if (auto *SRE
= dyn_cast
<MCSymbolRefExpr
>(E
))
730 void SystemZOperand::print(raw_ostream
&OS
) const {
733 OS
<< "Token:" << getToken();
736 OS
<< "Reg:" << SystemZGNUInstPrinter::getRegisterName(getReg());
740 printMCExpr(getImm(), OS
);
744 printMCExpr(getImmTLS().Imm
, OS
);
745 if (getImmTLS().Sym
) {
747 printMCExpr(getImmTLS().Sym
, OS
);
751 const MemOp
&Op
= getMem();
752 OS
<< "Mem:" << *cast
<MCConstantExpr
>(Op
.Disp
);
755 if (Op
.MemKind
== BDLMem
)
756 OS
<< *cast
<MCConstantExpr
>(Op
.Length
.Imm
) << ",";
757 else if (Op
.MemKind
== BDRMem
)
758 OS
<< SystemZGNUInstPrinter::getRegisterName(Op
.Length
.Reg
) << ",";
760 OS
<< SystemZGNUInstPrinter::getRegisterName(Op
.Index
) << ",";
761 OS
<< SystemZGNUInstPrinter::getRegisterName(Op
.Base
);
771 // Parse one register of the form %<prefix><number>.
772 bool SystemZAsmParser::parseRegister(Register
&Reg
, bool RequirePercent
,
773 bool RestoreOnFailure
) {
774 const AsmToken
&PercentTok
= Parser
.getTok();
775 bool HasPercent
= PercentTok
.is(AsmToken::Percent
);
777 Reg
.StartLoc
= PercentTok
.getLoc();
779 if (RequirePercent
&& PercentTok
.isNot(AsmToken::Percent
))
780 return Error(PercentTok
.getLoc(), "register expected");
783 Parser
.Lex(); // Eat percent token.
786 // Expect a register name.
787 if (Parser
.getTok().isNot(AsmToken::Identifier
)) {
788 if (RestoreOnFailure
&& HasPercent
)
789 getLexer().UnLex(PercentTok
);
790 return Error(Reg
.StartLoc
,
791 HasPercent
? "invalid register" : "register expected");
794 // Check that there's a prefix.
795 StringRef Name
= Parser
.getTok().getString();
796 if (Name
.size() < 2) {
797 if (RestoreOnFailure
&& HasPercent
)
798 getLexer().UnLex(PercentTok
);
799 return Error(Reg
.StartLoc
, "invalid register");
801 char Prefix
= Name
[0];
803 // Treat the rest of the register name as a register number.
804 if (Name
.substr(1).getAsInteger(10, Reg
.Num
)) {
805 if (RestoreOnFailure
&& HasPercent
)
806 getLexer().UnLex(PercentTok
);
807 return Error(Reg
.StartLoc
, "invalid register");
810 // Look for valid combinations of prefix and number.
811 if (Prefix
== 'r' && Reg
.Num
< 16)
813 else if (Prefix
== 'f' && Reg
.Num
< 16)
815 else if (Prefix
== 'v' && Reg
.Num
< 32)
817 else if (Prefix
== 'a' && Reg
.Num
< 16)
819 else if (Prefix
== 'c' && Reg
.Num
< 16)
822 if (RestoreOnFailure
&& HasPercent
)
823 getLexer().UnLex(PercentTok
);
824 return Error(Reg
.StartLoc
, "invalid register");
827 Reg
.EndLoc
= Parser
.getTok().getLoc();
832 // Parse a register of kind Kind and add it to Operands.
833 ParseStatus
SystemZAsmParser::parseRegister(OperandVector
&Operands
,
862 // Handle register names of the form %<prefix><number>
863 if (isParsingGNU() && Parser
.getTok().is(AsmToken::Percent
)) {
864 if (parseRegister(Reg
, /*RequirePercent=*/true))
865 return ParseStatus::Failure
;
867 // Check the parsed register group "Reg.Group" with the expected "Group"
868 // Have to error out if user specified wrong prefix.
874 if (Group
!= Reg
.Group
)
875 return Error(Reg
.StartLoc
, "invalid operand for instruction");
878 if (Reg
.Group
!= RegV
&& Reg
.Group
!= RegFP
)
879 return Error(Reg
.StartLoc
, "invalid operand for instruction");
882 } else if (Parser
.getTok().is(AsmToken::Integer
)) {
883 if (parseIntegerRegister(Reg
, Group
))
884 return ParseStatus::Failure
;
886 // Otherwise we didn't match a register operand.
888 return ParseStatus::NoMatch
;
890 // Determine the LLVM register number according to Kind.
891 const unsigned *Regs
;
893 case GR32Reg
: Regs
= SystemZMC::GR32Regs
; break;
894 case GRH32Reg
: Regs
= SystemZMC::GRH32Regs
; break;
895 case GR64Reg
: Regs
= SystemZMC::GR64Regs
; break;
896 case GR128Reg
: Regs
= SystemZMC::GR128Regs
; break;
897 case FP32Reg
: Regs
= SystemZMC::FP32Regs
; break;
898 case FP64Reg
: Regs
= SystemZMC::FP64Regs
; break;
899 case FP128Reg
: Regs
= SystemZMC::FP128Regs
; break;
900 case VR32Reg
: Regs
= SystemZMC::VR32Regs
; break;
901 case VR64Reg
: Regs
= SystemZMC::VR64Regs
; break;
902 case VR128Reg
: Regs
= SystemZMC::VR128Regs
; break;
903 case AR32Reg
: Regs
= SystemZMC::AR32Regs
; break;
904 case CR64Reg
: Regs
= SystemZMC::CR64Regs
; break;
906 if (Regs
[Reg
.Num
] == 0)
907 return Error(Reg
.StartLoc
, "invalid register pair");
910 SystemZOperand::createReg(Kind
, Regs
[Reg
.Num
], Reg
.StartLoc
, Reg
.EndLoc
));
911 return ParseStatus::Success
;
914 // Parse any type of register (including integers) and add it to Operands.
915 ParseStatus
SystemZAsmParser::parseAnyRegister(OperandVector
&Operands
) {
916 SMLoc StartLoc
= Parser
.getTok().getLoc();
918 // Handle integer values.
919 if (Parser
.getTok().is(AsmToken::Integer
)) {
920 const MCExpr
*Register
;
921 if (Parser
.parseExpression(Register
))
922 return ParseStatus::Failure
;
924 if (auto *CE
= dyn_cast
<MCConstantExpr
>(Register
)) {
925 int64_t Value
= CE
->getValue();
926 if (Value
< 0 || Value
> 15)
927 return Error(StartLoc
, "invalid register");
931 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
933 Operands
.push_back(SystemZOperand::createImm(Register
, StartLoc
, EndLoc
));
936 if (isParsingHLASM())
937 return ParseStatus::NoMatch
;
940 if (parseRegister(Reg
, /*RequirePercent=*/true))
941 return ParseStatus::Failure
;
944 return Error(StartLoc
, "invalid register");
946 // Map to the correct register kind.
949 if (Reg
.Group
== RegGR
) {
951 RegNo
= SystemZMC::GR64Regs
[Reg
.Num
];
953 else if (Reg
.Group
== RegFP
) {
955 RegNo
= SystemZMC::FP64Regs
[Reg
.Num
];
957 else if (Reg
.Group
== RegV
) {
959 RegNo
= SystemZMC::VR128Regs
[Reg
.Num
];
961 else if (Reg
.Group
== RegAR
) {
963 RegNo
= SystemZMC::AR32Regs
[Reg
.Num
];
965 else if (Reg
.Group
== RegCR
) {
967 RegNo
= SystemZMC::CR64Regs
[Reg
.Num
];
970 return ParseStatus::Failure
;
973 Operands
.push_back(SystemZOperand::createReg(Kind
, RegNo
,
974 Reg
.StartLoc
, Reg
.EndLoc
));
976 return ParseStatus::Success
;
979 bool SystemZAsmParser::parseIntegerRegister(Register
&Reg
,
980 RegisterGroup Group
) {
981 Reg
.StartLoc
= Parser
.getTok().getLoc();
982 // We have an integer token
983 const MCExpr
*Register
;
984 if (Parser
.parseExpression(Register
))
987 const auto *CE
= dyn_cast
<MCConstantExpr
>(Register
);
991 int64_t MaxRegNum
= (Group
== RegV
) ? 31 : 15;
992 int64_t Value
= CE
->getValue();
993 if (Value
< 0 || Value
> MaxRegNum
) {
994 Error(Parser
.getTok().getLoc(), "invalid register");
998 // Assign the Register Number
999 Reg
.Num
= (unsigned)Value
;
1001 Reg
.EndLoc
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1003 // At this point, successfully parsed an integer register.
1007 // Parse a memory operand into Reg1, Reg2, Disp, and Length.
1008 bool SystemZAsmParser::parseAddress(bool &HaveReg1
, Register
&Reg1
,
1009 bool &HaveReg2
, Register
&Reg2
,
1010 const MCExpr
*&Disp
, const MCExpr
*&Length
,
1011 bool HasLength
, bool HasVectorIndex
) {
1012 // Parse the displacement, which must always be present.
1013 if (getParser().parseExpression(Disp
))
1016 // Parse the optional base and index.
1021 // If we have a scenario as below:
1022 // vgef %v0, 0(0), 0
1023 // This is an example of a "BDVMem" instruction type.
1025 // So when we parse this as an integer register, the register group
1026 // needs to be tied to "RegV". Usually when the prefix is passed in
1027 // as %<prefix><reg-number> its easy to check which group it should belong to
1028 // However, if we're passing in just the integer there's no real way to
1029 // "check" what register group it should belong to.
1031 // When the user passes in the register as an integer, the user assumes that
1032 // the compiler is responsible for substituting it as the right kind of
1033 // register. Whereas, when the user specifies a "prefix", the onus is on
1034 // the user to make sure they pass in the right kind of register.
1036 // The restriction only applies to the first Register (i.e. Reg1). Reg2 is
1037 // always a general register. Reg1 should be of group RegV if "HasVectorIndex"
1038 // (i.e. insn is of type BDVMem) is true.
1039 RegisterGroup RegGroup
= HasVectorIndex
? RegV
: RegGR
;
1041 if (getLexer().is(AsmToken::LParen
)) {
1044 if (isParsingGNU() && getLexer().is(AsmToken::Percent
)) {
1045 // Parse the first register.
1047 if (parseRegister(Reg1
, /*RequirePercent=*/true))
1050 // So if we have an integer as the first token in ([tok1], ..), it could:
1051 // 1. Refer to a "Register" (i.e X,R,V fields in BD[X|R|V]Mem type of
1053 // 2. Refer to a "Length" field (i.e L field in BDLMem type of instructions)
1054 else if (getLexer().is(AsmToken::Integer
)) {
1056 // Instruction has a "Length" field, safe to parse the first token as
1057 // the "Length" field
1058 if (getParser().parseExpression(Length
))
1061 // Otherwise, if the instruction has no "Length" field, parse the
1062 // token as a "Register". We don't have to worry about whether the
1063 // instruction is invalid here, because the caller will take care of
1066 if (parseIntegerRegister(Reg1
, RegGroup
))
1070 // If its not an integer or a percent token, then if the instruction
1071 // is reported to have a "Length" then, parse it as "Length".
1073 if (getParser().parseExpression(Length
))
1078 // Check whether there's a second register.
1079 if (getLexer().is(AsmToken::Comma
)) {
1083 if (getLexer().is(AsmToken::Integer
)) {
1084 if (parseIntegerRegister(Reg2
, RegGR
))
1086 } else if (isParsingGNU()) {
1087 if (Parser
.getTok().is(AsmToken::Percent
)) {
1088 if (parseRegister(Reg2
, /*RequirePercent=*/true))
1091 // GAS allows ",)" to indicate a missing base register.
1094 Reg2
.StartLoc
= Reg2
.EndLoc
= Parser
.getTok().getLoc();
1099 // Consume the closing bracket.
1100 if (getLexer().isNot(AsmToken::RParen
))
1101 return Error(Parser
.getTok().getLoc(), "unexpected token in address");
1107 // Verify that Reg is a valid address register (base or index).
1109 SystemZAsmParser::parseAddressRegister(Register
&Reg
) {
1110 if (Reg
.Group
== RegV
) {
1111 Error(Reg
.StartLoc
, "invalid use of vector addressing");
1114 if (Reg
.Group
!= RegGR
) {
1115 Error(Reg
.StartLoc
, "invalid address register");
1121 // Parse a memory operand and add it to Operands. The other arguments
1123 ParseStatus
SystemZAsmParser::parseAddress(OperandVector
&Operands
,
1125 RegisterKind RegKind
) {
1126 SMLoc StartLoc
= Parser
.getTok().getLoc();
1127 unsigned Base
= 0, Index
= 0, LengthReg
= 0;
1128 Register Reg1
, Reg2
;
1129 bool HaveReg1
, HaveReg2
;
1131 const MCExpr
*Length
;
1133 bool HasLength
= (MemKind
== BDLMem
) ? true : false;
1134 bool HasVectorIndex
= (MemKind
== BDVMem
) ? true : false;
1135 if (parseAddress(HaveReg1
, Reg1
, HaveReg2
, Reg2
, Disp
, Length
, HasLength
,
1137 return ParseStatus::Failure
;
1139 const unsigned *Regs
;
1141 case GR32Reg
: Regs
= SystemZMC::GR32Regs
; break;
1142 case GR64Reg
: Regs
= SystemZMC::GR64Regs
; break;
1143 default: llvm_unreachable("invalid RegKind");
1148 // If we have Reg1, it must be an address register.
1150 if (parseAddressRegister(Reg1
))
1151 return ParseStatus::Failure
;
1152 Base
= Reg1
.Num
== 0 ? 0 : Regs
[Reg1
.Num
];
1154 // There must be no Reg2.
1156 return Error(StartLoc
, "invalid use of indexed addressing");
1160 // If we have Reg1, it must be an address register.
1162 const unsigned *IndexRegs
= Regs
;
1163 if (MemKind
== LXAMem
)
1164 IndexRegs
= SystemZMC::GR32Regs
;
1166 if (parseAddressRegister(Reg1
))
1167 return ParseStatus::Failure
;
1168 // If there are two registers, the first one is the index and the
1169 // second is the base. If there is only a single register, it is
1170 // used as base with GAS and as index with HLASM.
1171 if (HaveReg2
|| isParsingHLASM())
1172 Index
= Reg1
.Num
== 0 ? 0 : IndexRegs
[Reg1
.Num
];
1174 Base
= Reg1
.Num
== 0 ? 0 : Regs
[Reg1
.Num
];
1176 // If we have Reg2, it must be an address register.
1178 if (parseAddressRegister(Reg2
))
1179 return ParseStatus::Failure
;
1180 Base
= Reg2
.Num
== 0 ? 0 : Regs
[Reg2
.Num
];
1184 // If we have Reg2, it must be an address register.
1186 if (parseAddressRegister(Reg2
))
1187 return ParseStatus::Failure
;
1188 Base
= Reg2
.Num
== 0 ? 0 : Regs
[Reg2
.Num
];
1190 // We cannot support base+index addressing.
1191 if (HaveReg1
&& HaveReg2
)
1192 return Error(StartLoc
, "invalid use of indexed addressing");
1193 // We must have a length.
1195 return Error(StartLoc
, "missing length in address");
1198 // We must have Reg1, and it must be a GPR.
1199 if (!HaveReg1
|| Reg1
.Group
!= RegGR
)
1200 return Error(StartLoc
, "invalid operand for instruction");
1201 LengthReg
= SystemZMC::GR64Regs
[Reg1
.Num
];
1202 // If we have Reg2, it must be an address register.
1204 if (parseAddressRegister(Reg2
))
1205 return ParseStatus::Failure
;
1206 Base
= Reg2
.Num
== 0 ? 0 : Regs
[Reg2
.Num
];
1210 // We must have Reg1, and it must be a vector register.
1211 if (!HaveReg1
|| Reg1
.Group
!= RegV
)
1212 return Error(StartLoc
, "vector index required in address");
1213 Index
= SystemZMC::VR128Regs
[Reg1
.Num
];
1214 // In GAS mode, we must have Reg2, since a single register would be
1215 // interpreted as base register, which cannot be a vector register.
1216 if (isParsingGNU() && !HaveReg2
)
1217 return Error(Reg1
.StartLoc
, "invalid use of vector addressing");
1218 // If we have Reg2, it must be an address register.
1220 if (parseAddressRegister(Reg2
))
1221 return ParseStatus::Failure
;
1222 Base
= Reg2
.Num
== 0 ? 0 : Regs
[Reg2
.Num
];
1228 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1229 Operands
.push_back(SystemZOperand::createMem(MemKind
, RegKind
, Base
, Disp
,
1230 Index
, Length
, LengthReg
,
1232 return ParseStatus::Success
;
1235 ParseStatus
SystemZAsmParser::parseDirective(AsmToken DirectiveID
) {
1236 StringRef IDVal
= DirectiveID
.getIdentifier();
1238 if (IDVal
== ".insn")
1239 return ParseDirectiveInsn(DirectiveID
.getLoc());
1240 if (IDVal
== ".machine")
1241 return ParseDirectiveMachine(DirectiveID
.getLoc());
1242 if (IDVal
.starts_with(".gnu_attribute"))
1243 return ParseGNUAttribute(DirectiveID
.getLoc());
1245 return ParseStatus::NoMatch
;
1248 /// ParseDirectiveInsn
1249 /// ::= .insn [ format, encoding, (operands (, operands)*) ]
1250 bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L
) {
1251 MCAsmParser
&Parser
= getParser();
1253 // Expect instruction format as identifier.
1255 SMLoc ErrorLoc
= Parser
.getTok().getLoc();
1256 if (Parser
.parseIdentifier(Format
))
1257 return Error(ErrorLoc
, "expected instruction format");
1259 SmallVector
<std::unique_ptr
<MCParsedAsmOperand
>, 8> Operands
;
1261 // Find entry for this format in InsnMatchTable.
1263 std::equal_range(std::begin(InsnMatchTable
), std::end(InsnMatchTable
),
1264 Format
, CompareInsn());
1266 // If first == second, couldn't find a match in the table.
1267 if (EntryRange
.first
== EntryRange
.second
)
1268 return Error(ErrorLoc
, "unrecognized format");
1270 struct InsnMatchEntry
*Entry
= EntryRange
.first
;
1272 // Format should match from equal_range.
1273 assert(Entry
->Format
== Format
);
1275 // Parse the following operands using the table's information.
1276 for (int I
= 0; I
< Entry
->NumOperands
; I
++) {
1277 MatchClassKind Kind
= Entry
->OperandKinds
[I
];
1279 SMLoc StartLoc
= Parser
.getTok().getLoc();
1281 // Always expect commas as separators for operands.
1282 if (getLexer().isNot(AsmToken::Comma
))
1283 return Error(StartLoc
, "unexpected token in directive");
1288 if (Kind
== MCK_AnyReg
)
1289 ResTy
= parseAnyReg(Operands
);
1290 else if (Kind
== MCK_VR128
)
1291 ResTy
= parseVR128(Operands
);
1292 else if (Kind
== MCK_BDXAddr64Disp12
|| Kind
== MCK_BDXAddr64Disp20
)
1293 ResTy
= parseBDXAddr64(Operands
);
1294 else if (Kind
== MCK_BDAddr64Disp12
|| Kind
== MCK_BDAddr64Disp20
)
1295 ResTy
= parseBDAddr64(Operands
);
1296 else if (Kind
== MCK_BDVAddr64Disp12
)
1297 ResTy
= parseBDVAddr64(Operands
);
1298 else if (Kind
== MCK_LXAAddr64Disp20
)
1299 ResTy
= parseLXAAddr64(Operands
);
1300 else if (Kind
== MCK_PCRel32
)
1301 ResTy
= parsePCRel32(Operands
);
1302 else if (Kind
== MCK_PCRel16
)
1303 ResTy
= parsePCRel16(Operands
);
1305 // Only remaining operand kind is an immediate.
1307 SMLoc StartLoc
= Parser
.getTok().getLoc();
1309 // Expect immediate expression.
1310 if (Parser
.parseExpression(Expr
))
1311 return Error(StartLoc
, "unexpected token in directive");
1314 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1316 Operands
.push_back(SystemZOperand::createImm(Expr
, StartLoc
, EndLoc
));
1317 ResTy
= ParseStatus::Success
;
1320 if (!ResTy
.isSuccess())
1324 // Build the instruction with the parsed operands.
1325 MCInst Inst
= MCInstBuilder(Entry
->Opcode
);
1327 for (size_t I
= 0; I
< Operands
.size(); I
++) {
1328 MCParsedAsmOperand
&Operand
= *Operands
[I
];
1329 MatchClassKind Kind
= Entry
->OperandKinds
[I
];
1332 unsigned Res
= validateOperandClass(Operand
, Kind
);
1333 if (Res
!= Match_Success
)
1334 return Error(Operand
.getStartLoc(), "unexpected operand type");
1336 // Add operands to instruction.
1337 SystemZOperand
&ZOperand
= static_cast<SystemZOperand
&>(Operand
);
1338 if (ZOperand
.isReg())
1339 ZOperand
.addRegOperands(Inst
, 1);
1340 else if (ZOperand
.isMem(BDMem
))
1341 ZOperand
.addBDAddrOperands(Inst
, 2);
1342 else if (ZOperand
.isMem(BDXMem
))
1343 ZOperand
.addBDXAddrOperands(Inst
, 3);
1344 else if (ZOperand
.isMem(BDVMem
))
1345 ZOperand
.addBDVAddrOperands(Inst
, 3);
1346 else if (ZOperand
.isMem(LXAMem
))
1347 ZOperand
.addLXAAddrOperands(Inst
, 3);
1348 else if (ZOperand
.isImm())
1349 ZOperand
.addImmOperands(Inst
, 1);
1351 llvm_unreachable("unexpected operand type");
1354 // Emit as a regular instruction.
1355 Parser
.getStreamer().emitInstruction(Inst
, getSTI());
1360 /// ParseDirectiveMachine
1361 /// ::= .machine [ mcpu ]
1362 bool SystemZAsmParser::ParseDirectiveMachine(SMLoc L
) {
1363 MCAsmParser
&Parser
= getParser();
1364 if (Parser
.getTok().isNot(AsmToken::Identifier
) &&
1365 Parser
.getTok().isNot(AsmToken::String
))
1366 return TokError("unexpected token in '.machine' directive");
1368 StringRef CPU
= Parser
.getTok().getIdentifier();
1373 MCSubtargetInfo
&STI
= copySTI();
1374 STI
.setDefaultFeatures(CPU
, /*TuneCPU*/ CPU
, "");
1375 setAvailableFeatures(ComputeAvailableFeatures(STI
.getFeatureBits()));
1377 getTargetStreamer().emitMachine(CPU
);
1382 bool SystemZAsmParser::ParseGNUAttribute(SMLoc L
) {
1384 int64_t IntegerValue
;
1385 if (!Parser
.parseGNUAttribute(L
, Tag
, IntegerValue
))
1386 return Error(L
, "malformed .gnu_attribute directive");
1388 // Tag_GNU_S390_ABI_Vector tag is '8' and can be 0, 1, or 2.
1389 if (Tag
!= 8 || (IntegerValue
< 0 || IntegerValue
> 2))
1390 return Error(L
, "unrecognized .gnu_attribute tag/value pair.");
1392 Parser
.getStreamer().emitGNUAttribute(Tag
, IntegerValue
);
1397 bool SystemZAsmParser::ParseRegister(MCRegister
&RegNo
, SMLoc
&StartLoc
,
1398 SMLoc
&EndLoc
, bool RequirePercent
,
1399 bool RestoreOnFailure
) {
1401 if (parseRegister(Reg
, RequirePercent
, RestoreOnFailure
))
1403 if (Reg
.Group
== RegGR
)
1404 RegNo
= SystemZMC::GR64Regs
[Reg
.Num
];
1405 else if (Reg
.Group
== RegFP
)
1406 RegNo
= SystemZMC::FP64Regs
[Reg
.Num
];
1407 else if (Reg
.Group
== RegV
)
1408 RegNo
= SystemZMC::VR128Regs
[Reg
.Num
];
1409 else if (Reg
.Group
== RegAR
)
1410 RegNo
= SystemZMC::AR32Regs
[Reg
.Num
];
1411 else if (Reg
.Group
== RegCR
)
1412 RegNo
= SystemZMC::CR64Regs
[Reg
.Num
];
1413 StartLoc
= Reg
.StartLoc
;
1414 EndLoc
= Reg
.EndLoc
;
1418 bool SystemZAsmParser::parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
1420 return ParseRegister(Reg
, StartLoc
, EndLoc
, /*RequirePercent=*/false,
1421 /*RestoreOnFailure=*/false);
1424 ParseStatus
SystemZAsmParser::tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
1426 bool Result
= ParseRegister(Reg
, StartLoc
, EndLoc
, /*RequirePercent=*/false,
1427 /*RestoreOnFailure=*/true);
1428 bool PendingErrors
= getParser().hasPendingError();
1429 getParser().clearPendingErrors();
1431 return ParseStatus::Failure
;
1433 return ParseStatus::NoMatch
;
1434 return ParseStatus::Success
;
1437 bool SystemZAsmParser::parseInstruction(ParseInstructionInfo
&Info
,
1438 StringRef Name
, SMLoc NameLoc
,
1439 OperandVector
&Operands
) {
1441 // Apply mnemonic aliases first, before doing anything else, in
1442 // case the target uses it.
1443 applyMnemonicAliases(Name
, getAvailableFeatures(), getMAIAssemblerDialect());
1445 Operands
.push_back(SystemZOperand::createToken(Name
, NameLoc
));
1447 // Read the remaining operands.
1448 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1449 // Read the first operand.
1450 if (parseOperand(Operands
, Name
)) {
1454 // Read any subsequent operands.
1455 while (getLexer().is(AsmToken::Comma
)) {
1458 if (isParsingHLASM() && getLexer().is(AsmToken::Space
))
1460 Parser
.getTok().getLoc(),
1461 "No space allowed between comma that separates operand entries");
1463 if (parseOperand(Operands
, Name
)) {
1468 // Under the HLASM variant, we could have the remark field
1469 // The remark field occurs after the operation entries
1470 // There is a space that separates the operation entries and the
1472 if (isParsingHLASM() && getTok().is(AsmToken::Space
)) {
1473 // We've confirmed that there is a Remark field.
1474 StringRef
Remark(getLexer().LexUntilEndOfStatement());
1477 // If there is nothing after the space, then there is nothing to emit
1478 // We could have a situation as this:
1480 // After lexing above, we will have
1482 // This isn't an explicit remark field, so we don't have to output
1483 // this as a comment.
1485 // Output the entire Remarks Field as a comment
1486 getStreamer().AddComment(Remark
);
1489 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1490 SMLoc Loc
= getLexer().getLoc();
1491 return Error(Loc
, "unexpected token in argument list");
1495 // Consume the EndOfStatement.
1500 bool SystemZAsmParser::parseOperand(OperandVector
&Operands
,
1501 StringRef Mnemonic
) {
1502 // Check if the current operand has a custom associated parser, if so, try to
1503 // custom parse the operand, or fallback to the general approach. Force all
1504 // features to be available during the operand check, or else we will fail to
1505 // find the custom parser, and then we will later get an InvalidOperand error
1506 // instead of a MissingFeature errror.
1507 FeatureBitset AvailableFeatures
= getAvailableFeatures();
1510 setAvailableFeatures(All
);
1511 ParseStatus Res
= MatchOperandParserImpl(Operands
, Mnemonic
);
1512 setAvailableFeatures(AvailableFeatures
);
1513 if (Res
.isSuccess())
1516 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1517 // there was a match, but an error occurred, in which case, just return that
1518 // the operand parsing failed.
1519 if (Res
.isFailure())
1522 // Check for a register. All real register operands should have used
1523 // a context-dependent parse routine, which gives the required register
1524 // class. The code is here to mop up other cases, like those where
1525 // the instruction isn't recognized.
1526 if (isParsingGNU() && Parser
.getTok().is(AsmToken::Percent
)) {
1528 if (parseRegister(Reg
, /*RequirePercent=*/true))
1530 Operands
.push_back(SystemZOperand::createInvalid(Reg
.StartLoc
, Reg
.EndLoc
));
1534 // The only other type of operand is an immediate or address. As above,
1535 // real address operands should have used a context-dependent parse routine,
1536 // so we treat any plain expression as an immediate.
1537 SMLoc StartLoc
= Parser
.getTok().getLoc();
1538 Register Reg1
, Reg2
;
1539 bool HaveReg1
, HaveReg2
;
1541 const MCExpr
*Length
;
1542 if (parseAddress(HaveReg1
, Reg1
, HaveReg2
, Reg2
, Expr
, Length
,
1543 /*HasLength*/ true, /*HasVectorIndex*/ true))
1545 // If the register combination is not valid for any instruction, reject it.
1546 // Otherwise, fall back to reporting an unrecognized instruction.
1547 if (HaveReg1
&& Reg1
.Group
!= RegGR
&& Reg1
.Group
!= RegV
1548 && parseAddressRegister(Reg1
))
1550 if (HaveReg2
&& parseAddressRegister(Reg2
))
1554 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1555 if (HaveReg1
|| HaveReg2
|| Length
)
1556 Operands
.push_back(SystemZOperand::createInvalid(StartLoc
, EndLoc
));
1558 Operands
.push_back(SystemZOperand::createImm(Expr
, StartLoc
, EndLoc
));
1562 bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
1563 OperandVector
&Operands
,
1565 uint64_t &ErrorInfo
,
1566 bool MatchingInlineAsm
) {
1568 unsigned MatchResult
;
1570 unsigned Dialect
= getMAIAssemblerDialect();
1572 FeatureBitset MissingFeatures
;
1573 MatchResult
= MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MissingFeatures
,
1574 MatchingInlineAsm
, Dialect
);
1575 switch (MatchResult
) {
1578 Out
.emitInstruction(Inst
, getSTI());
1581 case Match_MissingFeature
: {
1582 assert(MissingFeatures
.any() && "Unknown missing feature!");
1583 // Special case the error message for the very common case where only
1584 // a single subtarget feature is missing
1585 std::string Msg
= "instruction requires:";
1586 for (unsigned I
= 0, E
= MissingFeatures
.size(); I
!= E
; ++I
) {
1587 if (MissingFeatures
[I
]) {
1589 Msg
+= getSubtargetFeatureName(I
);
1592 return Error(IDLoc
, Msg
);
1595 case Match_InvalidOperand
: {
1596 SMLoc ErrorLoc
= IDLoc
;
1597 if (ErrorInfo
!= ~0ULL) {
1598 if (ErrorInfo
>= Operands
.size())
1599 return Error(IDLoc
, "too few operands for instruction");
1601 ErrorLoc
= ((SystemZOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1602 if (ErrorLoc
== SMLoc())
1605 return Error(ErrorLoc
, "invalid operand for instruction");
1608 case Match_MnemonicFail
: {
1609 FeatureBitset FBS
= ComputeAvailableFeatures(getSTI().getFeatureBits());
1610 std::string Suggestion
= SystemZMnemonicSpellCheck(
1611 ((SystemZOperand
&)*Operands
[0]).getToken(), FBS
, Dialect
);
1612 return Error(IDLoc
, "invalid instruction" + Suggestion
,
1613 ((SystemZOperand
&)*Operands
[0]).getLocRange());
1617 llvm_unreachable("Unexpected match type");
1620 ParseStatus
SystemZAsmParser::parsePCRel(OperandVector
&Operands
,
1621 int64_t MinVal
, int64_t MaxVal
,
1623 MCContext
&Ctx
= getContext();
1624 MCStreamer
&Out
= getStreamer();
1626 SMLoc StartLoc
= Parser
.getTok().getLoc();
1627 if (getParser().parseExpression(Expr
))
1628 return ParseStatus::NoMatch
;
1630 auto IsOutOfRangeConstant
= [&](const MCExpr
*E
, bool Negate
) -> bool {
1631 if (auto *CE
= dyn_cast
<MCConstantExpr
>(E
)) {
1632 int64_t Value
= CE
->getValue();
1635 if ((Value
& 1) || Value
< MinVal
|| Value
> MaxVal
)
1641 // For consistency with the GNU assembler, treat immediates as offsets
1643 if (auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
)) {
1644 if (isParsingHLASM())
1645 return Error(StartLoc
, "Expected PC-relative expression");
1646 if (IsOutOfRangeConstant(CE
, false))
1647 return Error(StartLoc
, "offset out of range");
1648 int64_t Value
= CE
->getValue();
1649 MCSymbol
*Sym
= Ctx
.createTempSymbol();
1651 const MCExpr
*Base
= MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
,
1653 Expr
= Value
== 0 ? Base
: MCBinaryExpr::createAdd(Base
, Expr
, Ctx
);
1656 // For consistency with the GNU assembler, conservatively assume that a
1657 // constant offset must by itself be within the given size range.
1658 if (const auto *BE
= dyn_cast
<MCBinaryExpr
>(Expr
))
1659 if (IsOutOfRangeConstant(BE
->getLHS(), false) ||
1660 IsOutOfRangeConstant(BE
->getRHS(),
1661 BE
->getOpcode() == MCBinaryExpr::Sub
))
1662 return Error(StartLoc
, "offset out of range");
1664 // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
1665 const MCExpr
*Sym
= nullptr;
1666 if (AllowTLS
&& getLexer().is(AsmToken::Colon
)) {
1669 if (Parser
.getTok().isNot(AsmToken::Identifier
))
1670 return Error(Parser
.getTok().getLoc(), "unexpected token");
1672 MCSymbolRefExpr::VariantKind Kind
= MCSymbolRefExpr::VK_None
;
1673 StringRef Name
= Parser
.getTok().getString();
1674 if (Name
== "tls_gdcall")
1675 Kind
= MCSymbolRefExpr::VK_TLSGD
;
1676 else if (Name
== "tls_ldcall")
1677 Kind
= MCSymbolRefExpr::VK_TLSLDM
;
1679 return Error(Parser
.getTok().getLoc(), "unknown TLS tag");
1682 if (Parser
.getTok().isNot(AsmToken::Colon
))
1683 return Error(Parser
.getTok().getLoc(), "unexpected token");
1686 if (Parser
.getTok().isNot(AsmToken::Identifier
))
1687 return Error(Parser
.getTok().getLoc(), "unexpected token");
1689 StringRef Identifier
= Parser
.getTok().getString();
1690 Sym
= MCSymbolRefExpr::create(Ctx
.getOrCreateSymbol(Identifier
),
1696 SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1699 Operands
.push_back(SystemZOperand::createImmTLS(Expr
, Sym
,
1702 Operands
.push_back(SystemZOperand::createImm(Expr
, StartLoc
, EndLoc
));
1704 return ParseStatus::Success
;
1707 bool SystemZAsmParser::isLabel(AsmToken
&Token
) {
1711 // HLASM labels are ordinary symbols.
1712 // An HLASM label always starts at column 1.
1713 // An ordinary symbol syntax is laid out as follows:
1715 // 1. Has to start with an "alphabetic character". Can be followed by up to
1716 // 62 alphanumeric characters. An "alphabetic character", in this scenario,
1717 // is a letter from 'A' through 'Z', or from 'a' through 'z',
1718 // or '$', '_', '#', or '@'
1719 // 2. Labels are case-insensitive. E.g. "lab123", "LAB123", "lAb123", etc.
1720 // are all treated as the same symbol. However, the processing for the case
1721 // folding will not be done in this function.
1722 StringRef RawLabel
= Token
.getString();
1723 SMLoc Loc
= Token
.getLoc();
1725 // An HLASM label cannot be empty.
1726 if (!RawLabel
.size())
1727 return !Error(Loc
, "HLASM Label cannot be empty");
1729 // An HLASM label cannot exceed greater than 63 characters.
1730 if (RawLabel
.size() > 63)
1731 return !Error(Loc
, "Maximum length for HLASM Label is 63 characters");
1733 // A label must start with an "alphabetic character".
1734 if (!isHLASMAlpha(RawLabel
[0]))
1735 return !Error(Loc
, "HLASM Label has to start with an alphabetic "
1736 "character or the underscore character");
1738 // Now, we've established that the length is valid
1739 // and the first character is alphabetic.
1740 // Check whether remaining string is alphanumeric.
1741 for (unsigned I
= 1; I
< RawLabel
.size(); ++I
)
1742 if (!isHLASMAlnum(RawLabel
[I
]))
1743 return !Error(Loc
, "HLASM Label has to be alphanumeric");
1748 // Force static initialization.
1749 // NOLINTNEXTLINE(readability-identifier-naming)
1750 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeSystemZAsmParser() {
1751 RegisterMCAsmParser
<SystemZAsmParser
> X(getTheSystemZTarget());