1284c1978SDimitry Andric //===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2284c1978SDimitry Andric //
3284c1978SDimitry Andric // The LLVM Compiler Infrastructure
4284c1978SDimitry Andric //
5284c1978SDimitry Andric // This file is distributed under the University of Illinois Open Source
6284c1978SDimitry Andric // License. See LICENSE.TXT for details.
7284c1978SDimitry Andric //
8284c1978SDimitry Andric //===----------------------------------------------------------------------===//
9284c1978SDimitry Andric
10*b5893f02SDimitry Andric #include "InstPrinter/SystemZInstPrinter.h"
11284c1978SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h"
12f785676fSDimitry Andric #include "llvm/ADT/STLExtras.h"
13db17bf38SDimitry Andric #include "llvm/ADT/SmallVector.h"
147a7e6055SDimitry Andric #include "llvm/ADT/StringRef.h"
15f785676fSDimitry Andric #include "llvm/MC/MCContext.h"
16284c1978SDimitry Andric #include "llvm/MC/MCExpr.h"
17284c1978SDimitry Andric #include "llvm/MC/MCInst.h"
18d88c1a5aSDimitry Andric #include "llvm/MC/MCInstBuilder.h"
197a7e6055SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
207a7e6055SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
217a7e6055SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h"
22284c1978SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
233ca95b02SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h"
24284c1978SDimitry Andric #include "llvm/MC/MCStreamer.h"
25284c1978SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
267a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
277a7e6055SDimitry Andric #include "llvm/Support/ErrorHandling.h"
287a7e6055SDimitry Andric #include "llvm/Support/SMLoc.h"
29284c1978SDimitry Andric #include "llvm/Support/TargetRegistry.h"
307a7e6055SDimitry Andric #include <algorithm>
317a7e6055SDimitry Andric #include <cassert>
327a7e6055SDimitry Andric #include <cstddef>
337a7e6055SDimitry Andric #include <cstdint>
347a7e6055SDimitry Andric #include <iterator>
357a7e6055SDimitry Andric #include <memory>
367a7e6055SDimitry Andric #include <string>
37284c1978SDimitry Andric
38284c1978SDimitry Andric using namespace llvm;
39284c1978SDimitry Andric
40284c1978SDimitry Andric // Return true if Expr is in the range [MinValue, MaxValue].
inRange(const MCExpr * Expr,int64_t MinValue,int64_t MaxValue)41284c1978SDimitry Andric static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
4291bc56edSDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
43284c1978SDimitry Andric int64_t Value = CE->getValue();
44284c1978SDimitry Andric return Value >= MinValue && Value <= MaxValue;
45284c1978SDimitry Andric }
46284c1978SDimitry Andric return false;
47284c1978SDimitry Andric }
48284c1978SDimitry Andric
49284c1978SDimitry Andric namespace {
507a7e6055SDimitry Andric
51284c1978SDimitry Andric enum RegisterKind {
52284c1978SDimitry Andric GR32Reg,
53f785676fSDimitry Andric GRH32Reg,
54284c1978SDimitry Andric GR64Reg,
55284c1978SDimitry Andric GR128Reg,
56284c1978SDimitry Andric ADDR32Reg,
57284c1978SDimitry Andric ADDR64Reg,
58284c1978SDimitry Andric FP32Reg,
59284c1978SDimitry Andric FP64Reg,
60ff0cc061SDimitry Andric FP128Reg,
61ff0cc061SDimitry Andric VR32Reg,
62ff0cc061SDimitry Andric VR64Reg,
63d88c1a5aSDimitry Andric VR128Reg,
64d88c1a5aSDimitry Andric AR32Reg,
65a580b014SDimitry Andric CR64Reg,
66284c1978SDimitry Andric };
67284c1978SDimitry Andric
68f785676fSDimitry Andric enum MemoryKind {
69f785676fSDimitry Andric BDMem,
70f785676fSDimitry Andric BDXMem,
71ff0cc061SDimitry Andric BDLMem,
72d88c1a5aSDimitry Andric BDRMem,
73ff0cc061SDimitry Andric BDVMem
74f785676fSDimitry Andric };
75f785676fSDimitry Andric
76f785676fSDimitry Andric class SystemZOperand : public MCParsedAsmOperand {
77284c1978SDimitry Andric private:
78284c1978SDimitry Andric enum OperandKind {
79f785676fSDimitry Andric KindInvalid,
80284c1978SDimitry Andric KindToken,
81284c1978SDimitry Andric KindReg,
82284c1978SDimitry Andric KindImm,
83ff0cc061SDimitry Andric KindImmTLS,
84284c1978SDimitry Andric KindMem
85284c1978SDimitry Andric };
86284c1978SDimitry Andric
87284c1978SDimitry Andric OperandKind Kind;
88284c1978SDimitry Andric SMLoc StartLoc, EndLoc;
89284c1978SDimitry Andric
90284c1978SDimitry Andric // A string of length Length, starting at Data.
91284c1978SDimitry Andric struct TokenOp {
92284c1978SDimitry Andric const char *Data;
93284c1978SDimitry Andric unsigned Length;
94284c1978SDimitry Andric };
95284c1978SDimitry Andric
96f785676fSDimitry Andric // LLVM register Num, which has kind Kind. In some ways it might be
97f785676fSDimitry Andric // easier for this class to have a register bank (general, floating-point
98f785676fSDimitry Andric // or access) and a raw register number (0-15). This would postpone the
99f785676fSDimitry Andric // interpretation of the operand to the add*() methods and avoid the need
100f785676fSDimitry Andric // for context-dependent parsing. However, we do things the current way
101f785676fSDimitry Andric // because of the virtual getReg() method, which needs to distinguish
102f785676fSDimitry Andric // between (say) %r0 used as a single register and %r0 used as a pair.
103f785676fSDimitry Andric // Context-dependent parsing can also give us slightly better error
104f785676fSDimitry Andric // messages when invalid pairs like %r1 are used.
105284c1978SDimitry Andric struct RegOp {
106284c1978SDimitry Andric RegisterKind Kind;
107284c1978SDimitry Andric unsigned Num;
108284c1978SDimitry Andric };
109284c1978SDimitry Andric
110284c1978SDimitry Andric // Base + Disp + Index, where Base and Index are LLVM registers or 0.
111ff0cc061SDimitry Andric // MemKind says what type of memory this is and RegKind says what type
112ff0cc061SDimitry Andric // the base register has (ADDR32Reg or ADDR64Reg). Length is the operand
113ff0cc061SDimitry Andric // length for D(L,B)-style operands, otherwise it is null.
114284c1978SDimitry Andric struct MemOp {
115ff0cc061SDimitry Andric unsigned Base : 12;
116ff0cc061SDimitry Andric unsigned Index : 12;
117ff0cc061SDimitry Andric unsigned MemKind : 4;
118ff0cc061SDimitry Andric unsigned RegKind : 4;
119284c1978SDimitry Andric const MCExpr *Disp;
120d88c1a5aSDimitry Andric union {
121d88c1a5aSDimitry Andric const MCExpr *Imm;
122d88c1a5aSDimitry Andric unsigned Reg;
123d88c1a5aSDimitry Andric } Length;
124284c1978SDimitry Andric };
125284c1978SDimitry Andric
126ff0cc061SDimitry Andric // Imm is an immediate operand, and Sym is an optional TLS symbol
127ff0cc061SDimitry Andric // for use with a __tls_get_offset marker relocation.
128ff0cc061SDimitry Andric struct ImmTLSOp {
129ff0cc061SDimitry Andric const MCExpr *Imm;
130ff0cc061SDimitry Andric const MCExpr *Sym;
131ff0cc061SDimitry Andric };
132ff0cc061SDimitry Andric
133284c1978SDimitry Andric union {
134284c1978SDimitry Andric TokenOp Token;
135284c1978SDimitry Andric RegOp Reg;
136284c1978SDimitry Andric const MCExpr *Imm;
137ff0cc061SDimitry Andric ImmTLSOp ImmTLS;
138284c1978SDimitry Andric MemOp Mem;
139284c1978SDimitry Andric };
140284c1978SDimitry Andric
addExpr(MCInst & Inst,const MCExpr * Expr) const141284c1978SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const {
142284c1978SDimitry Andric // Add as immediates when possible. Null MCExpr = 0.
14391bc56edSDimitry Andric if (!Expr)
144ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
14591bc56edSDimitry Andric else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
146ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue()));
147284c1978SDimitry Andric else
148ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
149284c1978SDimitry Andric }
150284c1978SDimitry Andric
151284c1978SDimitry Andric public:
SystemZOperand(OperandKind kind,SMLoc startLoc,SMLoc endLoc)15291bc56edSDimitry Andric SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
15391bc56edSDimitry Andric : Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
15491bc56edSDimitry Andric
155284c1978SDimitry Andric // Create particular kinds of operand.
createInvalid(SMLoc StartLoc,SMLoc EndLoc)15691bc56edSDimitry Andric static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
15791bc56edSDimitry Andric SMLoc EndLoc) {
15891bc56edSDimitry Andric return make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
159f785676fSDimitry Andric }
1607a7e6055SDimitry Andric
createToken(StringRef Str,SMLoc Loc)16191bc56edSDimitry Andric static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
16291bc56edSDimitry Andric auto Op = make_unique<SystemZOperand>(KindToken, Loc, Loc);
163284c1978SDimitry Andric Op->Token.Data = Str.data();
164284c1978SDimitry Andric Op->Token.Length = Str.size();
165284c1978SDimitry Andric return Op;
166284c1978SDimitry Andric }
1677a7e6055SDimitry Andric
16891bc56edSDimitry Andric static std::unique_ptr<SystemZOperand>
createReg(RegisterKind Kind,unsigned Num,SMLoc StartLoc,SMLoc EndLoc)16991bc56edSDimitry Andric createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
17091bc56edSDimitry Andric auto Op = make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
171284c1978SDimitry Andric Op->Reg.Kind = Kind;
172284c1978SDimitry Andric Op->Reg.Num = Num;
173284c1978SDimitry Andric return Op;
174284c1978SDimitry Andric }
1757a7e6055SDimitry Andric
17691bc56edSDimitry Andric static std::unique_ptr<SystemZOperand>
createImm(const MCExpr * Expr,SMLoc StartLoc,SMLoc EndLoc)17791bc56edSDimitry Andric createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
17891bc56edSDimitry Andric auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
179284c1978SDimitry Andric Op->Imm = Expr;
180284c1978SDimitry Andric return Op;
181284c1978SDimitry Andric }
1827a7e6055SDimitry Andric
18391bc56edSDimitry Andric static std::unique_ptr<SystemZOperand>
createMem(MemoryKind MemKind,RegisterKind RegKind,unsigned Base,const MCExpr * Disp,unsigned Index,const MCExpr * LengthImm,unsigned LengthReg,SMLoc StartLoc,SMLoc EndLoc)184ff0cc061SDimitry Andric createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,
185d88c1a5aSDimitry Andric const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,
186d88c1a5aSDimitry Andric unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
18791bc56edSDimitry Andric auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
188ff0cc061SDimitry Andric Op->Mem.MemKind = MemKind;
189284c1978SDimitry Andric Op->Mem.RegKind = RegKind;
190284c1978SDimitry Andric Op->Mem.Base = Base;
191284c1978SDimitry Andric Op->Mem.Index = Index;
192284c1978SDimitry Andric Op->Mem.Disp = Disp;
193d88c1a5aSDimitry Andric if (MemKind == BDLMem)
194d88c1a5aSDimitry Andric Op->Mem.Length.Imm = LengthImm;
195d88c1a5aSDimitry Andric if (MemKind == BDRMem)
196d88c1a5aSDimitry Andric Op->Mem.Length.Reg = LengthReg;
197284c1978SDimitry Andric return Op;
198284c1978SDimitry Andric }
1997a7e6055SDimitry Andric
200ff0cc061SDimitry Andric static std::unique_ptr<SystemZOperand>
createImmTLS(const MCExpr * Imm,const MCExpr * Sym,SMLoc StartLoc,SMLoc EndLoc)201ff0cc061SDimitry Andric createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
202ff0cc061SDimitry Andric SMLoc StartLoc, SMLoc EndLoc) {
203ff0cc061SDimitry Andric auto Op = make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
204ff0cc061SDimitry Andric Op->ImmTLS.Imm = Imm;
205ff0cc061SDimitry Andric Op->ImmTLS.Sym = Sym;
206ff0cc061SDimitry Andric return Op;
207ff0cc061SDimitry Andric }
208284c1978SDimitry Andric
209284c1978SDimitry Andric // Token operands
isToken() const21091bc56edSDimitry Andric bool isToken() const override {
211284c1978SDimitry Andric return Kind == KindToken;
212284c1978SDimitry Andric }
getToken() const213284c1978SDimitry Andric StringRef getToken() const {
214284c1978SDimitry Andric assert(Kind == KindToken && "Not a token");
215284c1978SDimitry Andric return StringRef(Token.Data, Token.Length);
216284c1978SDimitry Andric }
217284c1978SDimitry Andric
218284c1978SDimitry Andric // Register operands.
isReg() const21991bc56edSDimitry Andric bool isReg() const override {
220284c1978SDimitry Andric return Kind == KindReg;
221284c1978SDimitry Andric }
isReg(RegisterKind RegKind) const222284c1978SDimitry Andric bool isReg(RegisterKind RegKind) const {
223284c1978SDimitry Andric return Kind == KindReg && Reg.Kind == RegKind;
224284c1978SDimitry Andric }
getReg() const22591bc56edSDimitry Andric unsigned getReg() const override {
226284c1978SDimitry Andric assert(Kind == KindReg && "Not a register");
227284c1978SDimitry Andric return Reg.Num;
228284c1978SDimitry Andric }
229284c1978SDimitry Andric
230284c1978SDimitry Andric // Immediate operands.
isImm() const23191bc56edSDimitry Andric bool isImm() const override {
232284c1978SDimitry Andric return Kind == KindImm;
233284c1978SDimitry Andric }
isImm(int64_t MinValue,int64_t MaxValue) const234284c1978SDimitry Andric bool isImm(int64_t MinValue, int64_t MaxValue) const {
235284c1978SDimitry Andric return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
236284c1978SDimitry Andric }
getImm() const237284c1978SDimitry Andric const MCExpr *getImm() const {
238284c1978SDimitry Andric assert(Kind == KindImm && "Not an immediate");
239284c1978SDimitry Andric return Imm;
240284c1978SDimitry Andric }
241284c1978SDimitry Andric
242ff0cc061SDimitry Andric // Immediate operands with optional TLS symbol.
isImmTLS() const243ff0cc061SDimitry Andric bool isImmTLS() const {
244ff0cc061SDimitry Andric return Kind == KindImmTLS;
245ff0cc061SDimitry Andric }
246ff0cc061SDimitry Andric
getImmTLS() const247*b5893f02SDimitry Andric const ImmTLSOp getImmTLS() const {
248*b5893f02SDimitry Andric assert(Kind == KindImmTLS && "Not a TLS immediate");
249*b5893f02SDimitry Andric return ImmTLS;
250*b5893f02SDimitry Andric }
251*b5893f02SDimitry Andric
252284c1978SDimitry Andric // Memory operands.
isMem() const25391bc56edSDimitry Andric bool isMem() const override {
254284c1978SDimitry Andric return Kind == KindMem;
255284c1978SDimitry Andric }
isMem(MemoryKind MemKind) const256ff0cc061SDimitry Andric bool isMem(MemoryKind MemKind) const {
257284c1978SDimitry Andric return (Kind == KindMem &&
258ff0cc061SDimitry Andric (Mem.MemKind == MemKind ||
259ff0cc061SDimitry Andric // A BDMem can be treated as a BDXMem in which the index
260ff0cc061SDimitry Andric // register field is 0.
261ff0cc061SDimitry Andric (Mem.MemKind == BDMem && MemKind == BDXMem)));
262284c1978SDimitry Andric }
isMem(MemoryKind MemKind,RegisterKind RegKind) const263ff0cc061SDimitry Andric bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {
264ff0cc061SDimitry Andric return isMem(MemKind) && Mem.RegKind == RegKind;
265284c1978SDimitry Andric }
isMemDisp12(MemoryKind MemKind,RegisterKind RegKind) const266ff0cc061SDimitry Andric bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {
267ff0cc061SDimitry Andric return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff);
268ff0cc061SDimitry Andric }
isMemDisp20(MemoryKind MemKind,RegisterKind RegKind) const269ff0cc061SDimitry Andric bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
270ff0cc061SDimitry Andric return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287);
271f785676fSDimitry Andric }
isMemDisp12Len4(RegisterKind RegKind) const2725517e702SDimitry Andric bool isMemDisp12Len4(RegisterKind RegKind) const {
2735517e702SDimitry Andric return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);
2745517e702SDimitry Andric }
isMemDisp12Len8(RegisterKind RegKind) const275f785676fSDimitry Andric bool isMemDisp12Len8(RegisterKind RegKind) const {
276d88c1a5aSDimitry Andric return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);
277284c1978SDimitry Andric }
278284c1978SDimitry Andric
getMem() const279*b5893f02SDimitry Andric const MemOp& getMem() const {
280*b5893f02SDimitry Andric assert(Kind == KindMem && "Not a Mem operand");
281*b5893f02SDimitry Andric return Mem;
282*b5893f02SDimitry Andric }
283*b5893f02SDimitry Andric
284284c1978SDimitry Andric // Override MCParsedAsmOperand.
getStartLoc() const28591bc56edSDimitry Andric SMLoc getStartLoc() const override { return StartLoc; }
getEndLoc() const28691bc56edSDimitry Andric SMLoc getEndLoc() const override { return EndLoc; }
28791bc56edSDimitry Andric void print(raw_ostream &OS) const override;
288284c1978SDimitry Andric
289b40b48b8SDimitry Andric /// getLocRange - Get the range between the first and last token of this
290b40b48b8SDimitry Andric /// operand.
getLocRange() const291b40b48b8SDimitry Andric SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
292b40b48b8SDimitry Andric
293284c1978SDimitry Andric // Used by the TableGen code to add particular types of operand
294284c1978SDimitry Andric // to an instruction.
addRegOperands(MCInst & Inst,unsigned N) const295284c1978SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const {
296284c1978SDimitry Andric assert(N == 1 && "Invalid number of operands");
297ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg()));
298284c1978SDimitry Andric }
addImmOperands(MCInst & Inst,unsigned N) const299284c1978SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const {
300284c1978SDimitry Andric assert(N == 1 && "Invalid number of operands");
301284c1978SDimitry Andric addExpr(Inst, getImm());
302284c1978SDimitry Andric }
addBDAddrOperands(MCInst & Inst,unsigned N) const303284c1978SDimitry Andric void addBDAddrOperands(MCInst &Inst, unsigned N) const {
304284c1978SDimitry Andric assert(N == 2 && "Invalid number of operands");
305ff0cc061SDimitry Andric assert(isMem(BDMem) && "Invalid operand type");
306ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Base));
307284c1978SDimitry Andric addExpr(Inst, Mem.Disp);
308284c1978SDimitry Andric }
addBDXAddrOperands(MCInst & Inst,unsigned N) const309284c1978SDimitry Andric void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
310284c1978SDimitry Andric assert(N == 3 && "Invalid number of operands");
311ff0cc061SDimitry Andric assert(isMem(BDXMem) && "Invalid operand type");
312ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Base));
313284c1978SDimitry Andric addExpr(Inst, Mem.Disp);
314ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Index));
315284c1978SDimitry Andric }
addBDLAddrOperands(MCInst & Inst,unsigned N) const316f785676fSDimitry Andric void addBDLAddrOperands(MCInst &Inst, unsigned N) const {
317f785676fSDimitry Andric assert(N == 3 && "Invalid number of operands");
318ff0cc061SDimitry Andric assert(isMem(BDLMem) && "Invalid operand type");
319ff0cc061SDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Base));
320f785676fSDimitry Andric addExpr(Inst, Mem.Disp);
321d88c1a5aSDimitry Andric addExpr(Inst, Mem.Length.Imm);
322d88c1a5aSDimitry Andric }
addBDRAddrOperands(MCInst & Inst,unsigned N) const323d88c1a5aSDimitry Andric void addBDRAddrOperands(MCInst &Inst, unsigned N) const {
324d88c1a5aSDimitry Andric assert(N == 3 && "Invalid number of operands");
325d88c1a5aSDimitry Andric assert(isMem(BDRMem) && "Invalid operand type");
326d88c1a5aSDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Base));
327d88c1a5aSDimitry Andric addExpr(Inst, Mem.Disp);
328d88c1a5aSDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Length.Reg));
329d88c1a5aSDimitry Andric }
addBDVAddrOperands(MCInst & Inst,unsigned N) const330d88c1a5aSDimitry Andric void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
331d88c1a5aSDimitry Andric assert(N == 3 && "Invalid number of operands");
332d88c1a5aSDimitry Andric assert(isMem(BDVMem) && "Invalid operand type");
333d88c1a5aSDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Base));
334d88c1a5aSDimitry Andric addExpr(Inst, Mem.Disp);
335d88c1a5aSDimitry Andric Inst.addOperand(MCOperand::createReg(Mem.Index));
336f785676fSDimitry Andric }
addImmTLSOperands(MCInst & Inst,unsigned N) const337ff0cc061SDimitry Andric void addImmTLSOperands(MCInst &Inst, unsigned N) const {
338ff0cc061SDimitry Andric assert(N == 2 && "Invalid number of operands");
339ff0cc061SDimitry Andric assert(Kind == KindImmTLS && "Invalid operand type");
340ff0cc061SDimitry Andric addExpr(Inst, ImmTLS.Imm);
341ff0cc061SDimitry Andric if (ImmTLS.Sym)
342ff0cc061SDimitry Andric addExpr(Inst, ImmTLS.Sym);
343ff0cc061SDimitry Andric }
344284c1978SDimitry Andric
345284c1978SDimitry Andric // Used by the TableGen code to check for particular operand types.
isGR32() const346284c1978SDimitry Andric bool isGR32() const { return isReg(GR32Reg); }
isGRH32() const347f785676fSDimitry Andric bool isGRH32() const { return isReg(GRH32Reg); }
isGRX32() const348f785676fSDimitry Andric bool isGRX32() const { return false; }
isGR64() const349284c1978SDimitry Andric bool isGR64() const { return isReg(GR64Reg); }
isGR128() const350284c1978SDimitry Andric bool isGR128() const { return isReg(GR128Reg); }
isADDR32() const351284c1978SDimitry Andric bool isADDR32() const { return isReg(ADDR32Reg); }
isADDR64() const352284c1978SDimitry Andric bool isADDR64() const { return isReg(ADDR64Reg); }
isADDR128() const353284c1978SDimitry Andric bool isADDR128() const { return false; }
isFP32() const354284c1978SDimitry Andric bool isFP32() const { return isReg(FP32Reg); }
isFP64() const355284c1978SDimitry Andric bool isFP64() const { return isReg(FP64Reg); }
isFP128() const356284c1978SDimitry Andric bool isFP128() const { return isReg(FP128Reg); }
isVR32() const357ff0cc061SDimitry Andric bool isVR32() const { return isReg(VR32Reg); }
isVR64() const358ff0cc061SDimitry Andric bool isVR64() const { return isReg(VR64Reg); }
isVF128() const359ff0cc061SDimitry Andric bool isVF128() const { return false; }
isVR128() const360ff0cc061SDimitry Andric bool isVR128() const { return isReg(VR128Reg); }
isAR32() const361d88c1a5aSDimitry Andric bool isAR32() const { return isReg(AR32Reg); }
isCR64() const362a580b014SDimitry Andric bool isCR64() const { return isReg(CR64Reg); }
isAnyReg() const363d88c1a5aSDimitry Andric bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
isBDAddr32Disp12() const364ff0cc061SDimitry Andric bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); }
isBDAddr32Disp20() const365ff0cc061SDimitry Andric bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); }
isBDAddr64Disp12() const366ff0cc061SDimitry Andric bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); }
isBDAddr64Disp20() const367ff0cc061SDimitry Andric bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, ADDR64Reg); }
isBDXAddr64Disp12() const368ff0cc061SDimitry Andric bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); }
isBDXAddr64Disp20() const369ff0cc061SDimitry Andric bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); }
isBDLAddr64Disp12Len4() const3705517e702SDimitry Andric bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(ADDR64Reg); }
isBDLAddr64Disp12Len8() const371f785676fSDimitry Andric bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
isBDRAddr64Disp12() const372d88c1a5aSDimitry Andric bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, ADDR64Reg); }
isBDVAddr64Disp12() const373ff0cc061SDimitry Andric bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); }
isU1Imm() const374ff0cc061SDimitry Andric bool isU1Imm() const { return isImm(0, 1); }
isU2Imm() const375ff0cc061SDimitry Andric bool isU2Imm() const { return isImm(0, 3); }
isU3Imm() const376ff0cc061SDimitry Andric bool isU3Imm() const { return isImm(0, 7); }
isU4Imm() const377284c1978SDimitry Andric bool isU4Imm() const { return isImm(0, 15); }
isU6Imm() const378284c1978SDimitry Andric bool isU6Imm() const { return isImm(0, 63); }
isU8Imm() const379284c1978SDimitry Andric bool isU8Imm() const { return isImm(0, 255); }
isS8Imm() const380284c1978SDimitry Andric bool isS8Imm() const { return isImm(-128, 127); }
isU12Imm() const381ff0cc061SDimitry Andric bool isU12Imm() const { return isImm(0, 4095); }
isU16Imm() const382284c1978SDimitry Andric bool isU16Imm() const { return isImm(0, 65535); }
isS16Imm() const383284c1978SDimitry Andric bool isS16Imm() const { return isImm(-32768, 32767); }
isU32Imm() const384284c1978SDimitry Andric bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
isS32Imm() const385284c1978SDimitry Andric bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
isU48Imm() const386d88c1a5aSDimitry Andric bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }
387284c1978SDimitry Andric };
388284c1978SDimitry Andric
389284c1978SDimitry Andric class SystemZAsmParser : public MCTargetAsmParser {
390284c1978SDimitry Andric #define GET_ASSEMBLER_HEADER
391284c1978SDimitry Andric #include "SystemZGenAsmMatcher.inc"
392284c1978SDimitry Andric
393284c1978SDimitry Andric private:
394284c1978SDimitry Andric MCAsmParser &Parser;
395f785676fSDimitry Andric enum RegisterGroup {
396f785676fSDimitry Andric RegGR,
397f785676fSDimitry Andric RegFP,
398ff0cc061SDimitry Andric RegV,
399a580b014SDimitry Andric RegAR,
400a580b014SDimitry Andric RegCR
401f785676fSDimitry Andric };
402284c1978SDimitry Andric struct Register {
403f785676fSDimitry Andric RegisterGroup Group;
404f785676fSDimitry Andric unsigned Num;
405284c1978SDimitry Andric SMLoc StartLoc, EndLoc;
406284c1978SDimitry Andric };
407284c1978SDimitry Andric
408284c1978SDimitry Andric bool parseRegister(Register &Reg);
409284c1978SDimitry Andric
410f785676fSDimitry Andric bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
411284c1978SDimitry Andric bool IsAddress = false);
412284c1978SDimitry Andric
41391bc56edSDimitry Andric OperandMatchResultTy parseRegister(OperandVector &Operands,
41491bc56edSDimitry Andric RegisterGroup Group, const unsigned *Regs,
41591bc56edSDimitry Andric RegisterKind Kind);
416f785676fSDimitry Andric
417d88c1a5aSDimitry Andric OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
418d88c1a5aSDimitry Andric
419d88c1a5aSDimitry Andric bool parseAddress(bool &HaveReg1, Register &Reg1,
420d88c1a5aSDimitry Andric bool &HaveReg2, Register &Reg2,
421d88c1a5aSDimitry Andric const MCExpr *&Disp, const MCExpr *&Length);
422d88c1a5aSDimitry Andric bool parseAddressRegister(Register &Reg);
423d88c1a5aSDimitry Andric
424d88c1a5aSDimitry Andric bool ParseDirectiveInsn(SMLoc L);
425284c1978SDimitry Andric
42691bc56edSDimitry Andric OperandMatchResultTy parseAddress(OperandVector &Operands,
427ff0cc061SDimitry Andric MemoryKind MemKind, const unsigned *Regs,
428ff0cc061SDimitry Andric RegisterKind RegKind);
429ff0cc061SDimitry Andric
430ff0cc061SDimitry Andric OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
431ff0cc061SDimitry Andric int64_t MaxVal, bool AllowTLS);
432284c1978SDimitry Andric
43391bc56edSDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
434284c1978SDimitry Andric
435284c1978SDimitry Andric public:
SystemZAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)4367d523365SDimitry Andric SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
43791bc56edSDimitry Andric const MCInstrInfo &MII,
43891bc56edSDimitry Andric const MCTargetOptions &Options)
4392cab237bSDimitry Andric : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
440284c1978SDimitry Andric MCAsmParserExtension::Initialize(Parser);
441284c1978SDimitry Andric
4423ca95b02SDimitry Andric // Alias the .word directive to .short.
4433ca95b02SDimitry Andric parser.addAliasForDirective(".word", ".short");
4443ca95b02SDimitry Andric
445284c1978SDimitry Andric // Initialize the set of available features.
4467d523365SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
447284c1978SDimitry Andric }
448284c1978SDimitry Andric
449284c1978SDimitry Andric // Override MCTargetAsmParser.
45091bc56edSDimitry Andric bool ParseDirective(AsmToken DirectiveID) override;
45191bc56edSDimitry Andric bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
45291bc56edSDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
45391bc56edSDimitry Andric SMLoc NameLoc, OperandVector &Operands) override;
45491bc56edSDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
45591bc56edSDimitry Andric OperandVector &Operands, MCStreamer &Out,
45639d628a0SDimitry Andric uint64_t &ErrorInfo,
45791bc56edSDimitry Andric bool MatchingInlineAsm) override;
458284c1978SDimitry Andric
459284c1978SDimitry Andric // Used by the TableGen code to parse particular operand types.
parseGR32(OperandVector & Operands)46091bc56edSDimitry Andric OperandMatchResultTy parseGR32(OperandVector &Operands) {
461f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg);
462f785676fSDimitry Andric }
parseGRH32(OperandVector & Operands)46391bc56edSDimitry Andric OperandMatchResultTy parseGRH32(OperandVector &Operands) {
464f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg);
465f785676fSDimitry Andric }
parseGRX32(OperandVector & Operands)46691bc56edSDimitry Andric OperandMatchResultTy parseGRX32(OperandVector &Operands) {
467f785676fSDimitry Andric llvm_unreachable("GRX32 should only be used for pseudo instructions");
468284c1978SDimitry Andric }
parseGR64(OperandVector & Operands)46991bc56edSDimitry Andric OperandMatchResultTy parseGR64(OperandVector &Operands) {
470f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg);
471284c1978SDimitry Andric }
parseGR128(OperandVector & Operands)47291bc56edSDimitry Andric OperandMatchResultTy parseGR128(OperandVector &Operands) {
473f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg);
474284c1978SDimitry Andric }
parseADDR32(OperandVector & Operands)47591bc56edSDimitry Andric OperandMatchResultTy parseADDR32(OperandVector &Operands) {
476f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg);
477284c1978SDimitry Andric }
parseADDR64(OperandVector & Operands)47891bc56edSDimitry Andric OperandMatchResultTy parseADDR64(OperandVector &Operands) {
479f785676fSDimitry Andric return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg);
480284c1978SDimitry Andric }
parseADDR128(OperandVector & Operands)48191bc56edSDimitry Andric OperandMatchResultTy parseADDR128(OperandVector &Operands) {
482284c1978SDimitry Andric llvm_unreachable("Shouldn't be used as an operand");
483284c1978SDimitry Andric }
parseFP32(OperandVector & Operands)48491bc56edSDimitry Andric OperandMatchResultTy parseFP32(OperandVector &Operands) {
485f785676fSDimitry Andric return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg);
486284c1978SDimitry Andric }
parseFP64(OperandVector & Operands)48791bc56edSDimitry Andric OperandMatchResultTy parseFP64(OperandVector &Operands) {
488f785676fSDimitry Andric return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg);
489284c1978SDimitry Andric }
parseFP128(OperandVector & Operands)49091bc56edSDimitry Andric OperandMatchResultTy parseFP128(OperandVector &Operands) {
491f785676fSDimitry Andric return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
492284c1978SDimitry Andric }
parseVR32(OperandVector & Operands)493ff0cc061SDimitry Andric OperandMatchResultTy parseVR32(OperandVector &Operands) {
494ff0cc061SDimitry Andric return parseRegister(Operands, RegV, SystemZMC::VR32Regs, VR32Reg);
495ff0cc061SDimitry Andric }
parseVR64(OperandVector & Operands)496ff0cc061SDimitry Andric OperandMatchResultTy parseVR64(OperandVector &Operands) {
497ff0cc061SDimitry Andric return parseRegister(Operands, RegV, SystemZMC::VR64Regs, VR64Reg);
498ff0cc061SDimitry Andric }
parseVF128(OperandVector & Operands)499ff0cc061SDimitry Andric OperandMatchResultTy parseVF128(OperandVector &Operands) {
500ff0cc061SDimitry Andric llvm_unreachable("Shouldn't be used as an operand");
501ff0cc061SDimitry Andric }
parseVR128(OperandVector & Operands)502ff0cc061SDimitry Andric OperandMatchResultTy parseVR128(OperandVector &Operands) {
503ff0cc061SDimitry Andric return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg);
504ff0cc061SDimitry Andric }
parseAR32(OperandVector & Operands)505d88c1a5aSDimitry Andric OperandMatchResultTy parseAR32(OperandVector &Operands) {
506d88c1a5aSDimitry Andric return parseRegister(Operands, RegAR, SystemZMC::AR32Regs, AR32Reg);
507d88c1a5aSDimitry Andric }
parseCR64(OperandVector & Operands)508a580b014SDimitry Andric OperandMatchResultTy parseCR64(OperandVector &Operands) {
509a580b014SDimitry Andric return parseRegister(Operands, RegCR, SystemZMC::CR64Regs, CR64Reg);
510a580b014SDimitry Andric }
parseAnyReg(OperandVector & Operands)511d88c1a5aSDimitry Andric OperandMatchResultTy parseAnyReg(OperandVector &Operands) {
512d88c1a5aSDimitry Andric return parseAnyRegister(Operands);
513d88c1a5aSDimitry Andric }
parseBDAddr32(OperandVector & Operands)51491bc56edSDimitry Andric OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
515ff0cc061SDimitry Andric return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg);
516284c1978SDimitry Andric }
parseBDAddr64(OperandVector & Operands)51791bc56edSDimitry Andric OperandMatchResultTy parseBDAddr64(OperandVector &Operands) {
518ff0cc061SDimitry Andric return parseAddress(Operands, BDMem, SystemZMC::GR64Regs, ADDR64Reg);
519284c1978SDimitry Andric }
parseBDXAddr64(OperandVector & Operands)52091bc56edSDimitry Andric OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
521ff0cc061SDimitry Andric return parseAddress(Operands, BDXMem, SystemZMC::GR64Regs, ADDR64Reg);
522f785676fSDimitry Andric }
parseBDLAddr64(OperandVector & Operands)52391bc56edSDimitry Andric OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
524ff0cc061SDimitry Andric return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg);
525ff0cc061SDimitry Andric }
parseBDRAddr64(OperandVector & Operands)526d88c1a5aSDimitry Andric OperandMatchResultTy parseBDRAddr64(OperandVector &Operands) {
527d88c1a5aSDimitry Andric return parseAddress(Operands, BDRMem, SystemZMC::GR64Regs, ADDR64Reg);
528d88c1a5aSDimitry Andric }
parseBDVAddr64(OperandVector & Operands)529ff0cc061SDimitry Andric OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
530ff0cc061SDimitry Andric return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
531284c1978SDimitry Andric }
parsePCRel12(OperandVector & Operands)532d88c1a5aSDimitry Andric OperandMatchResultTy parsePCRel12(OperandVector &Operands) {
533d88c1a5aSDimitry Andric return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false);
534d88c1a5aSDimitry Andric }
parsePCRel16(OperandVector & Operands)53591bc56edSDimitry Andric OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
536ff0cc061SDimitry Andric return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
537f785676fSDimitry Andric }
parsePCRel24(OperandVector & Operands)538d88c1a5aSDimitry Andric OperandMatchResultTy parsePCRel24(OperandVector &Operands) {
539d88c1a5aSDimitry Andric return parsePCRel(Operands, -(1LL << 24), (1LL << 24) - 1, false);
540d88c1a5aSDimitry Andric }
parsePCRel32(OperandVector & Operands)54191bc56edSDimitry Andric OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
542ff0cc061SDimitry Andric return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
543ff0cc061SDimitry Andric }
parsePCRelTLS16(OperandVector & Operands)544ff0cc061SDimitry Andric OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
545ff0cc061SDimitry Andric return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
546ff0cc061SDimitry Andric }
parsePCRelTLS32(OperandVector & Operands)547ff0cc061SDimitry Andric OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
548ff0cc061SDimitry Andric return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
549f785676fSDimitry Andric }
550284c1978SDimitry Andric };
5517a7e6055SDimitry Andric
55291bc56edSDimitry Andric } // end anonymous namespace
553284c1978SDimitry Andric
554284c1978SDimitry Andric #define GET_REGISTER_MATCHER
555284c1978SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME
556284c1978SDimitry Andric #define GET_MATCHER_IMPLEMENTATION
5572cab237bSDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER
558284c1978SDimitry Andric #include "SystemZGenAsmMatcher.inc"
559284c1978SDimitry Andric
560d88c1a5aSDimitry Andric // Used for the .insn directives; contains information needed to parse the
561d88c1a5aSDimitry Andric // operands in the directive.
562d88c1a5aSDimitry Andric struct InsnMatchEntry {
563d88c1a5aSDimitry Andric StringRef Format;
564d88c1a5aSDimitry Andric uint64_t Opcode;
565d88c1a5aSDimitry Andric int32_t NumOperands;
566d88c1a5aSDimitry Andric MatchClassKind OperandKinds[5];
567d88c1a5aSDimitry Andric };
568d88c1a5aSDimitry Andric
569d88c1a5aSDimitry Andric // For equal_range comparison.
570d88c1a5aSDimitry Andric struct CompareInsn {
operator ()CompareInsn571d88c1a5aSDimitry Andric bool operator() (const InsnMatchEntry &LHS, StringRef RHS) {
572d88c1a5aSDimitry Andric return LHS.Format < RHS;
573d88c1a5aSDimitry Andric }
operator ()CompareInsn574d88c1a5aSDimitry Andric bool operator() (StringRef LHS, const InsnMatchEntry &RHS) {
575d88c1a5aSDimitry Andric return LHS < RHS.Format;
576d88c1a5aSDimitry Andric }
operator ()CompareInsn577d88c1a5aSDimitry Andric bool operator() (const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {
578d88c1a5aSDimitry Andric return LHS.Format < RHS.Format;
579d88c1a5aSDimitry Andric }
580d88c1a5aSDimitry Andric };
581d88c1a5aSDimitry Andric
582d88c1a5aSDimitry Andric // Table initializing information for parsing the .insn directive.
583d88c1a5aSDimitry Andric static struct InsnMatchEntry InsnMatchTable[] = {
584d88c1a5aSDimitry Andric /* Format, Opcode, NumOperands, OperandKinds */
585d88c1a5aSDimitry Andric { "e", SystemZ::InsnE, 1,
586d88c1a5aSDimitry Andric { MCK_U16Imm } },
587d88c1a5aSDimitry Andric { "ri", SystemZ::InsnRI, 3,
588d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
589d88c1a5aSDimitry Andric { "rie", SystemZ::InsnRIE, 4,
590d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
591d88c1a5aSDimitry Andric { "ril", SystemZ::InsnRIL, 3,
592d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
593d88c1a5aSDimitry Andric { "rilu", SystemZ::InsnRILU, 3,
594d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
595d88c1a5aSDimitry Andric { "ris", SystemZ::InsnRIS, 5,
596d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
597d88c1a5aSDimitry Andric { "rr", SystemZ::InsnRR, 3,
598d88c1a5aSDimitry Andric { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
599d88c1a5aSDimitry Andric { "rre", SystemZ::InsnRRE, 3,
600d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
601d88c1a5aSDimitry Andric { "rrf", SystemZ::InsnRRF, 5,
602d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
603d88c1a5aSDimitry Andric { "rrs", SystemZ::InsnRRS, 5,
604d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
605d88c1a5aSDimitry Andric { "rs", SystemZ::InsnRS, 4,
606d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
607d88c1a5aSDimitry Andric { "rse", SystemZ::InsnRSE, 4,
608d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
609d88c1a5aSDimitry Andric { "rsi", SystemZ::InsnRSI, 4,
610d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
611d88c1a5aSDimitry Andric { "rsy", SystemZ::InsnRSY, 4,
612d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
613d88c1a5aSDimitry Andric { "rx", SystemZ::InsnRX, 3,
614d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
615d88c1a5aSDimitry Andric { "rxe", SystemZ::InsnRXE, 3,
616d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
617d88c1a5aSDimitry Andric { "rxf", SystemZ::InsnRXF, 4,
618d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
619d88c1a5aSDimitry Andric { "rxy", SystemZ::InsnRXY, 3,
620d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
621d88c1a5aSDimitry Andric { "s", SystemZ::InsnS, 2,
622d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_BDAddr64Disp12 } },
623d88c1a5aSDimitry Andric { "si", SystemZ::InsnSI, 3,
624d88c1a5aSDimitry Andric { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
625d88c1a5aSDimitry Andric { "sil", SystemZ::InsnSIL, 3,
626d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
627d88c1a5aSDimitry Andric { "siy", SystemZ::InsnSIY, 3,
628d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
629d88c1a5aSDimitry Andric { "ss", SystemZ::InsnSS, 4,
630d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
631d88c1a5aSDimitry Andric { "sse", SystemZ::InsnSSE, 3,
632d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
633d88c1a5aSDimitry Andric { "ssf", SystemZ::InsnSSF, 4,
634d88c1a5aSDimitry Andric { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } }
635d88c1a5aSDimitry Andric };
636d88c1a5aSDimitry Andric
printMCExpr(const MCExpr * E,raw_ostream & OS)637*b5893f02SDimitry Andric static void printMCExpr(const MCExpr *E, raw_ostream &OS) {
638*b5893f02SDimitry Andric if (!E)
639*b5893f02SDimitry Andric return;
640*b5893f02SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(E))
641*b5893f02SDimitry Andric OS << *CE;
642*b5893f02SDimitry Andric else if (auto *UE = dyn_cast<MCUnaryExpr>(E))
643*b5893f02SDimitry Andric OS << *UE;
644*b5893f02SDimitry Andric else if (auto *BE = dyn_cast<MCBinaryExpr>(E))
645*b5893f02SDimitry Andric OS << *BE;
646*b5893f02SDimitry Andric else if (auto *SRE = dyn_cast<MCSymbolRefExpr>(E))
647*b5893f02SDimitry Andric OS << *SRE;
648*b5893f02SDimitry Andric else
649*b5893f02SDimitry Andric OS << *E;
650*b5893f02SDimitry Andric }
651*b5893f02SDimitry Andric
print(raw_ostream & OS) const652284c1978SDimitry Andric void SystemZOperand::print(raw_ostream &OS) const {
653*b5893f02SDimitry Andric switch (Kind) {
654*b5893f02SDimitry Andric break;
655*b5893f02SDimitry Andric case KindToken:
656*b5893f02SDimitry Andric OS << "Token:" << getToken();
657*b5893f02SDimitry Andric break;
658*b5893f02SDimitry Andric case KindReg:
659*b5893f02SDimitry Andric OS << "Reg:" << SystemZInstPrinter::getRegisterName(getReg());
660*b5893f02SDimitry Andric break;
661*b5893f02SDimitry Andric case KindImm:
662*b5893f02SDimitry Andric OS << "Imm:";
663*b5893f02SDimitry Andric printMCExpr(getImm(), OS);
664*b5893f02SDimitry Andric break;
665*b5893f02SDimitry Andric case KindImmTLS:
666*b5893f02SDimitry Andric OS << "ImmTLS:";
667*b5893f02SDimitry Andric printMCExpr(getImmTLS().Imm, OS);
668*b5893f02SDimitry Andric if (getImmTLS().Sym) {
669*b5893f02SDimitry Andric OS << ", ";
670*b5893f02SDimitry Andric printMCExpr(getImmTLS().Sym, OS);
671*b5893f02SDimitry Andric }
672*b5893f02SDimitry Andric break;
673*b5893f02SDimitry Andric case KindMem: {
674*b5893f02SDimitry Andric const MemOp &Op = getMem();
675*b5893f02SDimitry Andric OS << "Mem:" << *cast<MCConstantExpr>(Op.Disp);
676*b5893f02SDimitry Andric if (Op.Base) {
677*b5893f02SDimitry Andric OS << "(";
678*b5893f02SDimitry Andric if (Op.MemKind == BDLMem)
679*b5893f02SDimitry Andric OS << *cast<MCConstantExpr>(Op.Length.Imm) << ",";
680*b5893f02SDimitry Andric else if (Op.MemKind == BDRMem)
681*b5893f02SDimitry Andric OS << SystemZInstPrinter::getRegisterName(Op.Length.Reg) << ",";
682*b5893f02SDimitry Andric if (Op.Index)
683*b5893f02SDimitry Andric OS << SystemZInstPrinter::getRegisterName(Op.Index) << ",";
684*b5893f02SDimitry Andric OS << SystemZInstPrinter::getRegisterName(Op.Base);
685*b5893f02SDimitry Andric OS << ")";
686*b5893f02SDimitry Andric }
687*b5893f02SDimitry Andric break;
688*b5893f02SDimitry Andric }
689*b5893f02SDimitry Andric case KindInvalid:
690*b5893f02SDimitry Andric break;
691*b5893f02SDimitry Andric }
692284c1978SDimitry Andric }
693284c1978SDimitry Andric
694284c1978SDimitry Andric // Parse one register of the form %<prefix><number>.
parseRegister(Register & Reg)695284c1978SDimitry Andric bool SystemZAsmParser::parseRegister(Register &Reg) {
696284c1978SDimitry Andric Reg.StartLoc = Parser.getTok().getLoc();
697284c1978SDimitry Andric
698284c1978SDimitry Andric // Eat the % prefix.
699284c1978SDimitry Andric if (Parser.getTok().isNot(AsmToken::Percent))
700f785676fSDimitry Andric return Error(Parser.getTok().getLoc(), "register expected");
701284c1978SDimitry Andric Parser.Lex();
702284c1978SDimitry Andric
703284c1978SDimitry Andric // Expect a register name.
704284c1978SDimitry Andric if (Parser.getTok().isNot(AsmToken::Identifier))
705f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid register");
706284c1978SDimitry Andric
707f785676fSDimitry Andric // Check that there's a prefix.
708284c1978SDimitry Andric StringRef Name = Parser.getTok().getString();
709284c1978SDimitry Andric if (Name.size() < 2)
710f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid register");
711f785676fSDimitry Andric char Prefix = Name[0];
712284c1978SDimitry Andric
713284c1978SDimitry Andric // Treat the rest of the register name as a register number.
714f785676fSDimitry Andric if (Name.substr(1).getAsInteger(10, Reg.Num))
715f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid register");
716f785676fSDimitry Andric
717f785676fSDimitry Andric // Look for valid combinations of prefix and number.
718f785676fSDimitry Andric if (Prefix == 'r' && Reg.Num < 16)
719f785676fSDimitry Andric Reg.Group = RegGR;
720f785676fSDimitry Andric else if (Prefix == 'f' && Reg.Num < 16)
721f785676fSDimitry Andric Reg.Group = RegFP;
722ff0cc061SDimitry Andric else if (Prefix == 'v' && Reg.Num < 32)
723ff0cc061SDimitry Andric Reg.Group = RegV;
724f785676fSDimitry Andric else if (Prefix == 'a' && Reg.Num < 16)
725d88c1a5aSDimitry Andric Reg.Group = RegAR;
726a580b014SDimitry Andric else if (Prefix == 'c' && Reg.Num < 16)
727a580b014SDimitry Andric Reg.Group = RegCR;
728f785676fSDimitry Andric else
729f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid register");
730284c1978SDimitry Andric
731284c1978SDimitry Andric Reg.EndLoc = Parser.getTok().getLoc();
732284c1978SDimitry Andric Parser.Lex();
733284c1978SDimitry Andric return false;
734284c1978SDimitry Andric }
735284c1978SDimitry Andric
736f785676fSDimitry Andric // Parse a register of group Group. If Regs is nonnull, use it to map
7377d523365SDimitry Andric // the raw register number to LLVM numbering, with zero entries
7387d523365SDimitry Andric // indicating an invalid register. IsAddress says whether the
7397d523365SDimitry Andric // register appears in an address context. Allow FP Group if expecting
7407d523365SDimitry Andric // RegV Group, since the f-prefix yields the FP group even while used
7417d523365SDimitry Andric // with vector instructions.
parseRegister(Register & Reg,RegisterGroup Group,const unsigned * Regs,bool IsAddress)742f785676fSDimitry Andric bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
743284c1978SDimitry Andric const unsigned *Regs, bool IsAddress) {
744284c1978SDimitry Andric if (parseRegister(Reg))
745f785676fSDimitry Andric return true;
7467d523365SDimitry Andric if (Reg.Group != Group && !(Reg.Group == RegFP && Group == RegV))
747f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid operand for instruction");
748f785676fSDimitry Andric if (Regs && Regs[Reg.Num] == 0)
749f785676fSDimitry Andric return Error(Reg.StartLoc, "invalid register pair");
750f785676fSDimitry Andric if (Reg.Num == 0 && IsAddress)
751f785676fSDimitry Andric return Error(Reg.StartLoc, "%r0 used in an address");
752f785676fSDimitry Andric if (Regs)
753f785676fSDimitry Andric Reg.Num = Regs[Reg.Num];
754f785676fSDimitry Andric return false;
755f785676fSDimitry Andric }
756f785676fSDimitry Andric
757f785676fSDimitry Andric // Parse a register and add it to Operands. The other arguments are as above.
758d88c1a5aSDimitry Andric OperandMatchResultTy
parseRegister(OperandVector & Operands,RegisterGroup Group,const unsigned * Regs,RegisterKind Kind)75991bc56edSDimitry Andric SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
76091bc56edSDimitry Andric const unsigned *Regs, RegisterKind Kind) {
761f785676fSDimitry Andric if (Parser.getTok().isNot(AsmToken::Percent))
762284c1978SDimitry Andric return MatchOperand_NoMatch;
763f785676fSDimitry Andric
764f785676fSDimitry Andric Register Reg;
765f785676fSDimitry Andric bool IsAddress = (Kind == ADDR32Reg || Kind == ADDR64Reg);
766f785676fSDimitry Andric if (parseRegister(Reg, Group, Regs, IsAddress))
767284c1978SDimitry Andric return MatchOperand_ParseFail;
768f785676fSDimitry Andric
769f785676fSDimitry Andric Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
770f785676fSDimitry Andric Reg.StartLoc, Reg.EndLoc));
771284c1978SDimitry Andric return MatchOperand_Success;
772284c1978SDimitry Andric }
773284c1978SDimitry Andric
774d88c1a5aSDimitry Andric // Parse any type of register (including integers) and add it to Operands.
775d88c1a5aSDimitry Andric OperandMatchResultTy
parseAnyRegister(OperandVector & Operands)776d88c1a5aSDimitry Andric SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
777d88c1a5aSDimitry Andric // Handle integer values.
778d88c1a5aSDimitry Andric if (Parser.getTok().is(AsmToken::Integer)) {
779d88c1a5aSDimitry Andric const MCExpr *Register;
780d88c1a5aSDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
781d88c1a5aSDimitry Andric if (Parser.parseExpression(Register))
782d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
783d88c1a5aSDimitry Andric
784d88c1a5aSDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Register)) {
785d88c1a5aSDimitry Andric int64_t Value = CE->getValue();
786d88c1a5aSDimitry Andric if (Value < 0 || Value > 15) {
787d88c1a5aSDimitry Andric Error(StartLoc, "invalid register");
788d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
789d88c1a5aSDimitry Andric }
790d88c1a5aSDimitry Andric }
791d88c1a5aSDimitry Andric
792d88c1a5aSDimitry Andric SMLoc EndLoc =
793d88c1a5aSDimitry Andric SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
794d88c1a5aSDimitry Andric
795d88c1a5aSDimitry Andric Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));
796d88c1a5aSDimitry Andric }
797d88c1a5aSDimitry Andric else {
798d88c1a5aSDimitry Andric Register Reg;
799d88c1a5aSDimitry Andric if (parseRegister(Reg))
800d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
801d88c1a5aSDimitry Andric
802d88c1a5aSDimitry Andric // Map to the correct register kind.
803d88c1a5aSDimitry Andric RegisterKind Kind;
804d88c1a5aSDimitry Andric unsigned RegNo;
805d88c1a5aSDimitry Andric if (Reg.Group == RegGR) {
806d88c1a5aSDimitry Andric Kind = GR64Reg;
807d88c1a5aSDimitry Andric RegNo = SystemZMC::GR64Regs[Reg.Num];
808d88c1a5aSDimitry Andric }
809d88c1a5aSDimitry Andric else if (Reg.Group == RegFP) {
810d88c1a5aSDimitry Andric Kind = FP64Reg;
811d88c1a5aSDimitry Andric RegNo = SystemZMC::FP64Regs[Reg.Num];
812d88c1a5aSDimitry Andric }
813d88c1a5aSDimitry Andric else if (Reg.Group == RegV) {
814d88c1a5aSDimitry Andric Kind = VR128Reg;
815d88c1a5aSDimitry Andric RegNo = SystemZMC::VR128Regs[Reg.Num];
816d88c1a5aSDimitry Andric }
817d88c1a5aSDimitry Andric else if (Reg.Group == RegAR) {
818d88c1a5aSDimitry Andric Kind = AR32Reg;
819d88c1a5aSDimitry Andric RegNo = SystemZMC::AR32Regs[Reg.Num];
820d88c1a5aSDimitry Andric }
821a580b014SDimitry Andric else if (Reg.Group == RegCR) {
822a580b014SDimitry Andric Kind = CR64Reg;
823a580b014SDimitry Andric RegNo = SystemZMC::CR64Regs[Reg.Num];
824a580b014SDimitry Andric }
825d88c1a5aSDimitry Andric else {
826d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
827d88c1a5aSDimitry Andric }
828d88c1a5aSDimitry Andric
829d88c1a5aSDimitry Andric Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
830d88c1a5aSDimitry Andric Reg.StartLoc, Reg.EndLoc));
831d88c1a5aSDimitry Andric }
832d88c1a5aSDimitry Andric return MatchOperand_Success;
833d88c1a5aSDimitry Andric }
834d88c1a5aSDimitry Andric
835d88c1a5aSDimitry Andric // Parse a memory operand into Reg1, Reg2, Disp, and Length.
parseAddress(bool & HaveReg1,Register & Reg1,bool & HaveReg2,Register & Reg2,const MCExpr * & Disp,const MCExpr * & Length)836d88c1a5aSDimitry Andric bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
837d88c1a5aSDimitry Andric bool &HaveReg2, Register &Reg2,
838d88c1a5aSDimitry Andric const MCExpr *&Disp,
839d88c1a5aSDimitry Andric const MCExpr *&Length) {
840284c1978SDimitry Andric // Parse the displacement, which must always be present.
841284c1978SDimitry Andric if (getParser().parseExpression(Disp))
842f785676fSDimitry Andric return true;
843284c1978SDimitry Andric
844284c1978SDimitry Andric // Parse the optional base and index.
845d88c1a5aSDimitry Andric HaveReg1 = false;
846d88c1a5aSDimitry Andric HaveReg2 = false;
84791bc56edSDimitry Andric Length = nullptr;
848284c1978SDimitry Andric if (getLexer().is(AsmToken::LParen)) {
849284c1978SDimitry Andric Parser.Lex();
850284c1978SDimitry Andric
851f785676fSDimitry Andric if (getLexer().is(AsmToken::Percent)) {
852d88c1a5aSDimitry Andric // Parse the first register.
853d88c1a5aSDimitry Andric HaveReg1 = true;
854d88c1a5aSDimitry Andric if (parseRegister(Reg1))
855f785676fSDimitry Andric return true;
856f785676fSDimitry Andric } else {
857f785676fSDimitry Andric // Parse the length.
858f785676fSDimitry Andric if (getParser().parseExpression(Length))
859f785676fSDimitry Andric return true;
860f785676fSDimitry Andric }
861284c1978SDimitry Andric
862d88c1a5aSDimitry Andric // Check whether there's a second register.
863284c1978SDimitry Andric if (getLexer().is(AsmToken::Comma)) {
864284c1978SDimitry Andric Parser.Lex();
865d88c1a5aSDimitry Andric HaveReg2 = true;
866d88c1a5aSDimitry Andric if (parseRegister(Reg2))
867f785676fSDimitry Andric return true;
868284c1978SDimitry Andric }
869284c1978SDimitry Andric
870284c1978SDimitry Andric // Consume the closing bracket.
871284c1978SDimitry Andric if (getLexer().isNot(AsmToken::RParen))
872f785676fSDimitry Andric return Error(Parser.getTok().getLoc(), "unexpected token in address");
873284c1978SDimitry Andric Parser.Lex();
874284c1978SDimitry Andric }
875f785676fSDimitry Andric return false;
876f785676fSDimitry Andric }
877f785676fSDimitry Andric
878d88c1a5aSDimitry Andric // Verify that Reg is a valid address register (base or index).
879d88c1a5aSDimitry Andric bool
parseAddressRegister(Register & Reg)880d88c1a5aSDimitry Andric SystemZAsmParser::parseAddressRegister(Register &Reg) {
881d88c1a5aSDimitry Andric if (Reg.Group == RegV) {
882d88c1a5aSDimitry Andric Error(Reg.StartLoc, "invalid use of vector addressing");
883d88c1a5aSDimitry Andric return true;
884d88c1a5aSDimitry Andric } else if (Reg.Group != RegGR) {
885d88c1a5aSDimitry Andric Error(Reg.StartLoc, "invalid address register");
886d88c1a5aSDimitry Andric return true;
887d88c1a5aSDimitry Andric } else if (Reg.Num == 0) {
888d88c1a5aSDimitry Andric Error(Reg.StartLoc, "%r0 used in an address");
889d88c1a5aSDimitry Andric return true;
890d88c1a5aSDimitry Andric }
891d88c1a5aSDimitry Andric return false;
892d88c1a5aSDimitry Andric }
893d88c1a5aSDimitry Andric
894f785676fSDimitry Andric // Parse a memory operand and add it to Operands. The other arguments
895f785676fSDimitry Andric // are as above.
896d88c1a5aSDimitry Andric OperandMatchResultTy
parseAddress(OperandVector & Operands,MemoryKind MemKind,const unsigned * Regs,RegisterKind RegKind)897ff0cc061SDimitry Andric SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
898ff0cc061SDimitry Andric const unsigned *Regs, RegisterKind RegKind) {
899f785676fSDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
900d88c1a5aSDimitry Andric unsigned Base = 0, Index = 0, LengthReg = 0;
901d88c1a5aSDimitry Andric Register Reg1, Reg2;
902d88c1a5aSDimitry Andric bool HaveReg1, HaveReg2;
903f785676fSDimitry Andric const MCExpr *Disp;
904f785676fSDimitry Andric const MCExpr *Length;
905d88c1a5aSDimitry Andric if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length))
906f785676fSDimitry Andric return MatchOperand_ParseFail;
907f785676fSDimitry Andric
908d88c1a5aSDimitry Andric switch (MemKind) {
909d88c1a5aSDimitry Andric case BDMem:
910d88c1a5aSDimitry Andric // If we have Reg1, it must be an address register.
911d88c1a5aSDimitry Andric if (HaveReg1) {
912d88c1a5aSDimitry Andric if (parseAddressRegister(Reg1))
913ff0cc061SDimitry Andric return MatchOperand_ParseFail;
914d88c1a5aSDimitry Andric Base = Regs[Reg1.Num];
915ff0cc061SDimitry Andric }
916d88c1a5aSDimitry Andric // There must be no Reg2 or length.
917d88c1a5aSDimitry Andric if (Length) {
918f785676fSDimitry Andric Error(StartLoc, "invalid use of length addressing");
919f785676fSDimitry Andric return MatchOperand_ParseFail;
920f785676fSDimitry Andric }
921d88c1a5aSDimitry Andric if (HaveReg2) {
922d88c1a5aSDimitry Andric Error(StartLoc, "invalid use of indexed addressing");
923d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
924d88c1a5aSDimitry Andric }
925d88c1a5aSDimitry Andric break;
926d88c1a5aSDimitry Andric case BDXMem:
927d88c1a5aSDimitry Andric // If we have Reg1, it must be an address register.
928d88c1a5aSDimitry Andric if (HaveReg1) {
929d88c1a5aSDimitry Andric if (parseAddressRegister(Reg1))
930d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
931d88c1a5aSDimitry Andric // If the are two registers, the first one is the index and the
932d88c1a5aSDimitry Andric // second is the base.
933d88c1a5aSDimitry Andric if (HaveReg2)
934d88c1a5aSDimitry Andric Index = Regs[Reg1.Num];
935d88c1a5aSDimitry Andric else
936d88c1a5aSDimitry Andric Base = Regs[Reg1.Num];
937d88c1a5aSDimitry Andric }
938d88c1a5aSDimitry Andric // If we have Reg2, it must be an address register.
939d88c1a5aSDimitry Andric if (HaveReg2) {
940d88c1a5aSDimitry Andric if (parseAddressRegister(Reg2))
941d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
942d88c1a5aSDimitry Andric Base = Regs[Reg2.Num];
943d88c1a5aSDimitry Andric }
944d88c1a5aSDimitry Andric // There must be no length.
945d88c1a5aSDimitry Andric if (Length) {
946d88c1a5aSDimitry Andric Error(StartLoc, "invalid use of length addressing");
947d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
948d88c1a5aSDimitry Andric }
949d88c1a5aSDimitry Andric break;
950d88c1a5aSDimitry Andric case BDLMem:
951d88c1a5aSDimitry Andric // If we have Reg2, it must be an address register.
952d88c1a5aSDimitry Andric if (HaveReg2) {
953d88c1a5aSDimitry Andric if (parseAddressRegister(Reg2))
954d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
955d88c1a5aSDimitry Andric Base = Regs[Reg2.Num];
956d88c1a5aSDimitry Andric }
957d88c1a5aSDimitry Andric // We cannot support base+index addressing.
958d88c1a5aSDimitry Andric if (HaveReg1 && HaveReg2) {
959d88c1a5aSDimitry Andric Error(StartLoc, "invalid use of indexed addressing");
960d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
961d88c1a5aSDimitry Andric }
962d88c1a5aSDimitry Andric // We must have a length.
963d88c1a5aSDimitry Andric if (!Length) {
964f785676fSDimitry Andric Error(StartLoc, "missing length in address");
965f785676fSDimitry Andric return MatchOperand_ParseFail;
966f785676fSDimitry Andric }
967d88c1a5aSDimitry Andric break;
968d88c1a5aSDimitry Andric case BDRMem:
969d88c1a5aSDimitry Andric // We must have Reg1, and it must be a GPR.
970d88c1a5aSDimitry Andric if (!HaveReg1 || Reg1.Group != RegGR) {
971d88c1a5aSDimitry Andric Error(StartLoc, "invalid operand for instruction");
972d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
973d88c1a5aSDimitry Andric }
974d88c1a5aSDimitry Andric LengthReg = SystemZMC::GR64Regs[Reg1.Num];
975d88c1a5aSDimitry Andric // If we have Reg2, it must be an address register.
976d88c1a5aSDimitry Andric if (HaveReg2) {
977d88c1a5aSDimitry Andric if (parseAddressRegister(Reg2))
978d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
979d88c1a5aSDimitry Andric Base = Regs[Reg2.Num];
980d88c1a5aSDimitry Andric }
981d88c1a5aSDimitry Andric // There must be no length.
982d88c1a5aSDimitry Andric if (Length) {
983d88c1a5aSDimitry Andric Error(StartLoc, "invalid use of length addressing");
984d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
985d88c1a5aSDimitry Andric }
986d88c1a5aSDimitry Andric break;
987d88c1a5aSDimitry Andric case BDVMem:
988d88c1a5aSDimitry Andric // We must have Reg1, and it must be a vector register.
989d88c1a5aSDimitry Andric if (!HaveReg1 || Reg1.Group != RegV) {
990d88c1a5aSDimitry Andric Error(StartLoc, "vector index required in address");
991d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
992d88c1a5aSDimitry Andric }
993d88c1a5aSDimitry Andric Index = SystemZMC::VR128Regs[Reg1.Num];
994d88c1a5aSDimitry Andric // If we have Reg2, it must be an address register.
995d88c1a5aSDimitry Andric if (HaveReg2) {
996d88c1a5aSDimitry Andric if (parseAddressRegister(Reg2))
997d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
998d88c1a5aSDimitry Andric Base = Regs[Reg2.Num];
999d88c1a5aSDimitry Andric }
1000d88c1a5aSDimitry Andric // There must be no length.
1001d88c1a5aSDimitry Andric if (Length) {
1002d88c1a5aSDimitry Andric Error(StartLoc, "invalid use of length addressing");
1003d88c1a5aSDimitry Andric return MatchOperand_ParseFail;
1004d88c1a5aSDimitry Andric }
1005d88c1a5aSDimitry Andric break;
1006d88c1a5aSDimitry Andric }
1007284c1978SDimitry Andric
1008284c1978SDimitry Andric SMLoc EndLoc =
1009284c1978SDimitry Andric SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1010ff0cc061SDimitry Andric Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
1011d88c1a5aSDimitry Andric Index, Length, LengthReg,
1012d88c1a5aSDimitry Andric StartLoc, EndLoc));
1013284c1978SDimitry Andric return MatchOperand_Success;
1014284c1978SDimitry Andric }
1015284c1978SDimitry Andric
ParseDirective(AsmToken DirectiveID)1016284c1978SDimitry Andric bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
1017d88c1a5aSDimitry Andric StringRef IDVal = DirectiveID.getIdentifier();
1018d88c1a5aSDimitry Andric
1019d88c1a5aSDimitry Andric if (IDVal == ".insn")
1020d88c1a5aSDimitry Andric return ParseDirectiveInsn(DirectiveID.getLoc());
1021d88c1a5aSDimitry Andric
1022284c1978SDimitry Andric return true;
1023284c1978SDimitry Andric }
1024284c1978SDimitry Andric
1025d88c1a5aSDimitry Andric /// ParseDirectiveInsn
1026d88c1a5aSDimitry Andric /// ::= .insn [ format, encoding, (operands (, operands)*) ]
ParseDirectiveInsn(SMLoc L)1027d88c1a5aSDimitry Andric bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) {
1028d88c1a5aSDimitry Andric MCAsmParser &Parser = getParser();
1029d88c1a5aSDimitry Andric
1030d88c1a5aSDimitry Andric // Expect instruction format as identifier.
1031d88c1a5aSDimitry Andric StringRef Format;
1032d88c1a5aSDimitry Andric SMLoc ErrorLoc = Parser.getTok().getLoc();
1033d88c1a5aSDimitry Andric if (Parser.parseIdentifier(Format))
1034d88c1a5aSDimitry Andric return Error(ErrorLoc, "expected instruction format");
1035d88c1a5aSDimitry Andric
1036d88c1a5aSDimitry Andric SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
1037d88c1a5aSDimitry Andric
1038d88c1a5aSDimitry Andric // Find entry for this format in InsnMatchTable.
1039d88c1a5aSDimitry Andric auto EntryRange =
1040d88c1a5aSDimitry Andric std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
1041d88c1a5aSDimitry Andric Format, CompareInsn());
1042d88c1a5aSDimitry Andric
1043d88c1a5aSDimitry Andric // If first == second, couldn't find a match in the table.
1044d88c1a5aSDimitry Andric if (EntryRange.first == EntryRange.second)
1045d88c1a5aSDimitry Andric return Error(ErrorLoc, "unrecognized format");
1046d88c1a5aSDimitry Andric
1047d88c1a5aSDimitry Andric struct InsnMatchEntry *Entry = EntryRange.first;
1048d88c1a5aSDimitry Andric
1049d88c1a5aSDimitry Andric // Format should match from equal_range.
1050d88c1a5aSDimitry Andric assert(Entry->Format == Format);
1051d88c1a5aSDimitry Andric
1052d88c1a5aSDimitry Andric // Parse the following operands using the table's information.
1053d88c1a5aSDimitry Andric for (int i = 0; i < Entry->NumOperands; i++) {
1054d88c1a5aSDimitry Andric MatchClassKind Kind = Entry->OperandKinds[i];
1055d88c1a5aSDimitry Andric
1056d88c1a5aSDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
1057d88c1a5aSDimitry Andric
1058d88c1a5aSDimitry Andric // Always expect commas as separators for operands.
1059d88c1a5aSDimitry Andric if (getLexer().isNot(AsmToken::Comma))
1060d88c1a5aSDimitry Andric return Error(StartLoc, "unexpected token in directive");
1061d88c1a5aSDimitry Andric Lex();
1062d88c1a5aSDimitry Andric
1063d88c1a5aSDimitry Andric // Parse operands.
1064d88c1a5aSDimitry Andric OperandMatchResultTy ResTy;
1065d88c1a5aSDimitry Andric if (Kind == MCK_AnyReg)
1066d88c1a5aSDimitry Andric ResTy = parseAnyReg(Operands);
1067d88c1a5aSDimitry Andric else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
1068d88c1a5aSDimitry Andric ResTy = parseBDXAddr64(Operands);
1069d88c1a5aSDimitry Andric else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
1070d88c1a5aSDimitry Andric ResTy = parseBDAddr64(Operands);
1071d88c1a5aSDimitry Andric else if (Kind == MCK_PCRel32)
1072d88c1a5aSDimitry Andric ResTy = parsePCRel32(Operands);
1073d88c1a5aSDimitry Andric else if (Kind == MCK_PCRel16)
1074d88c1a5aSDimitry Andric ResTy = parsePCRel16(Operands);
1075d88c1a5aSDimitry Andric else {
1076d88c1a5aSDimitry Andric // Only remaining operand kind is an immediate.
1077d88c1a5aSDimitry Andric const MCExpr *Expr;
1078d88c1a5aSDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
1079d88c1a5aSDimitry Andric
1080d88c1a5aSDimitry Andric // Expect immediate expression.
1081d88c1a5aSDimitry Andric if (Parser.parseExpression(Expr))
1082d88c1a5aSDimitry Andric return Error(StartLoc, "unexpected token in directive");
1083d88c1a5aSDimitry Andric
1084d88c1a5aSDimitry Andric SMLoc EndLoc =
1085d88c1a5aSDimitry Andric SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1086d88c1a5aSDimitry Andric
1087d88c1a5aSDimitry Andric Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1088d88c1a5aSDimitry Andric ResTy = MatchOperand_Success;
1089d88c1a5aSDimitry Andric }
1090d88c1a5aSDimitry Andric
1091d88c1a5aSDimitry Andric if (ResTy != MatchOperand_Success)
1092d88c1a5aSDimitry Andric return true;
1093d88c1a5aSDimitry Andric }
1094d88c1a5aSDimitry Andric
1095d88c1a5aSDimitry Andric // Build the instruction with the parsed operands.
1096d88c1a5aSDimitry Andric MCInst Inst = MCInstBuilder(Entry->Opcode);
1097d88c1a5aSDimitry Andric
1098d88c1a5aSDimitry Andric for (size_t i = 0; i < Operands.size(); i++) {
1099d88c1a5aSDimitry Andric MCParsedAsmOperand &Operand = *Operands[i];
1100d88c1a5aSDimitry Andric MatchClassKind Kind = Entry->OperandKinds[i];
1101d88c1a5aSDimitry Andric
1102d88c1a5aSDimitry Andric // Verify operand.
1103d88c1a5aSDimitry Andric unsigned Res = validateOperandClass(Operand, Kind);
1104d88c1a5aSDimitry Andric if (Res != Match_Success)
1105d88c1a5aSDimitry Andric return Error(Operand.getStartLoc(), "unexpected operand type");
1106d88c1a5aSDimitry Andric
1107d88c1a5aSDimitry Andric // Add operands to instruction.
1108d88c1a5aSDimitry Andric SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);
1109d88c1a5aSDimitry Andric if (ZOperand.isReg())
1110d88c1a5aSDimitry Andric ZOperand.addRegOperands(Inst, 1);
1111d88c1a5aSDimitry Andric else if (ZOperand.isMem(BDMem))
1112d88c1a5aSDimitry Andric ZOperand.addBDAddrOperands(Inst, 2);
1113d88c1a5aSDimitry Andric else if (ZOperand.isMem(BDXMem))
1114d88c1a5aSDimitry Andric ZOperand.addBDXAddrOperands(Inst, 3);
1115d88c1a5aSDimitry Andric else if (ZOperand.isImm())
1116d88c1a5aSDimitry Andric ZOperand.addImmOperands(Inst, 1);
1117d88c1a5aSDimitry Andric else
1118d88c1a5aSDimitry Andric llvm_unreachable("unexpected operand type");
1119d88c1a5aSDimitry Andric }
1120d88c1a5aSDimitry Andric
1121d88c1a5aSDimitry Andric // Emit as a regular instruction.
1122d88c1a5aSDimitry Andric Parser.getStreamer().EmitInstruction(Inst, getSTI());
1123d88c1a5aSDimitry Andric
1124d88c1a5aSDimitry Andric return false;
1125d88c1a5aSDimitry Andric }
1126d88c1a5aSDimitry Andric
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1127284c1978SDimitry Andric bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1128284c1978SDimitry Andric SMLoc &EndLoc) {
1129284c1978SDimitry Andric Register Reg;
1130284c1978SDimitry Andric if (parseRegister(Reg))
1131f785676fSDimitry Andric return true;
1132f785676fSDimitry Andric if (Reg.Group == RegGR)
1133f785676fSDimitry Andric RegNo = SystemZMC::GR64Regs[Reg.Num];
1134f785676fSDimitry Andric else if (Reg.Group == RegFP)
1135f785676fSDimitry Andric RegNo = SystemZMC::FP64Regs[Reg.Num];
1136ff0cc061SDimitry Andric else if (Reg.Group == RegV)
1137ff0cc061SDimitry Andric RegNo = SystemZMC::VR128Regs[Reg.Num];
1138d88c1a5aSDimitry Andric else if (Reg.Group == RegAR)
1139d88c1a5aSDimitry Andric RegNo = SystemZMC::AR32Regs[Reg.Num];
1140a580b014SDimitry Andric else if (Reg.Group == RegCR)
1141a580b014SDimitry Andric RegNo = SystemZMC::CR64Regs[Reg.Num];
1142284c1978SDimitry Andric StartLoc = Reg.StartLoc;
1143284c1978SDimitry Andric EndLoc = Reg.EndLoc;
1144284c1978SDimitry Andric return false;
1145284c1978SDimitry Andric }
1146284c1978SDimitry Andric
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)114791bc56edSDimitry Andric bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
114891bc56edSDimitry Andric StringRef Name, SMLoc NameLoc,
114991bc56edSDimitry Andric OperandVector &Operands) {
1150284c1978SDimitry Andric Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
1151284c1978SDimitry Andric
1152284c1978SDimitry Andric // Read the remaining operands.
1153284c1978SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) {
1154284c1978SDimitry Andric // Read the first operand.
1155284c1978SDimitry Andric if (parseOperand(Operands, Name)) {
1156284c1978SDimitry Andric return true;
1157284c1978SDimitry Andric }
1158284c1978SDimitry Andric
1159284c1978SDimitry Andric // Read any subsequent operands.
1160284c1978SDimitry Andric while (getLexer().is(AsmToken::Comma)) {
1161284c1978SDimitry Andric Parser.Lex();
1162284c1978SDimitry Andric if (parseOperand(Operands, Name)) {
1163284c1978SDimitry Andric return true;
1164284c1978SDimitry Andric }
1165284c1978SDimitry Andric }
1166284c1978SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) {
1167284c1978SDimitry Andric SMLoc Loc = getLexer().getLoc();
1168284c1978SDimitry Andric return Error(Loc, "unexpected token in argument list");
1169284c1978SDimitry Andric }
1170284c1978SDimitry Andric }
1171284c1978SDimitry Andric
1172284c1978SDimitry Andric // Consume the EndOfStatement.
1173284c1978SDimitry Andric Parser.Lex();
1174284c1978SDimitry Andric return false;
1175284c1978SDimitry Andric }
1176284c1978SDimitry Andric
parseOperand(OperandVector & Operands,StringRef Mnemonic)117791bc56edSDimitry Andric bool SystemZAsmParser::parseOperand(OperandVector &Operands,
1178284c1978SDimitry Andric StringRef Mnemonic) {
1179284c1978SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to
1180d88c1a5aSDimitry Andric // custom parse the operand, or fallback to the general approach. Force all
1181d88c1a5aSDimitry Andric // features to be available during the operand check, or else we will fail to
1182d88c1a5aSDimitry Andric // find the custom parser, and then we will later get an InvalidOperand error
1183d88c1a5aSDimitry Andric // instead of a MissingFeature errror.
1184d88c1a5aSDimitry Andric uint64_t AvailableFeatures = getAvailableFeatures();
1185d88c1a5aSDimitry Andric setAvailableFeatures(~(uint64_t)0);
1186284c1978SDimitry Andric OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1187d88c1a5aSDimitry Andric setAvailableFeatures(AvailableFeatures);
1188284c1978SDimitry Andric if (ResTy == MatchOperand_Success)
1189284c1978SDimitry Andric return false;
1190284c1978SDimitry Andric
1191284c1978SDimitry Andric // If there wasn't a custom match, try the generic matcher below. Otherwise,
1192284c1978SDimitry Andric // there was a match, but an error occurred, in which case, just return that
1193284c1978SDimitry Andric // the operand parsing failed.
1194284c1978SDimitry Andric if (ResTy == MatchOperand_ParseFail)
1195284c1978SDimitry Andric return true;
1196284c1978SDimitry Andric
1197f785676fSDimitry Andric // Check for a register. All real register operands should have used
1198f785676fSDimitry Andric // a context-dependent parse routine, which gives the required register
1199f785676fSDimitry Andric // class. The code is here to mop up other cases, like those where
1200f785676fSDimitry Andric // the instruction isn't recognized.
1201f785676fSDimitry Andric if (Parser.getTok().is(AsmToken::Percent)) {
1202f785676fSDimitry Andric Register Reg;
1203f785676fSDimitry Andric if (parseRegister(Reg))
1204f785676fSDimitry Andric return true;
1205f785676fSDimitry Andric Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
1206f785676fSDimitry Andric return false;
1207f785676fSDimitry Andric }
1208f785676fSDimitry Andric
1209f785676fSDimitry Andric // The only other type of operand is an immediate or address. As above,
1210f785676fSDimitry Andric // real address operands should have used a context-dependent parse routine,
1211f785676fSDimitry Andric // so we treat any plain expression as an immediate.
1212284c1978SDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
1213d88c1a5aSDimitry Andric Register Reg1, Reg2;
1214d88c1a5aSDimitry Andric bool HaveReg1, HaveReg2;
1215d88c1a5aSDimitry Andric const MCExpr *Expr;
1216d88c1a5aSDimitry Andric const MCExpr *Length;
1217d88c1a5aSDimitry Andric if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length))
1218d88c1a5aSDimitry Andric return true;
1219d88c1a5aSDimitry Andric // If the register combination is not valid for any instruction, reject it.
1220d88c1a5aSDimitry Andric // Otherwise, fall back to reporting an unrecognized instruction.
1221d88c1a5aSDimitry Andric if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
1222d88c1a5aSDimitry Andric && parseAddressRegister(Reg1))
1223d88c1a5aSDimitry Andric return true;
1224d88c1a5aSDimitry Andric if (HaveReg2 && parseAddressRegister(Reg2))
1225284c1978SDimitry Andric return true;
1226284c1978SDimitry Andric
1227284c1978SDimitry Andric SMLoc EndLoc =
1228284c1978SDimitry Andric SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1229d88c1a5aSDimitry Andric if (HaveReg1 || HaveReg2 || Length)
1230f785676fSDimitry Andric Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1231f785676fSDimitry Andric else
1232284c1978SDimitry Andric Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1233284c1978SDimitry Andric return false;
1234284c1978SDimitry Andric }
1235284c1978SDimitry Andric
12362cab237bSDimitry Andric static std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS,
12372cab237bSDimitry Andric unsigned VariantID = 0);
1238b40b48b8SDimitry Andric
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)123991bc56edSDimitry Andric bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124091bc56edSDimitry Andric OperandVector &Operands,
124191bc56edSDimitry Andric MCStreamer &Out,
124239d628a0SDimitry Andric uint64_t &ErrorInfo,
1243284c1978SDimitry Andric bool MatchingInlineAsm) {
1244284c1978SDimitry Andric MCInst Inst;
1245284c1978SDimitry Andric unsigned MatchResult;
1246284c1978SDimitry Andric
1247284c1978SDimitry Andric MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
1248284c1978SDimitry Andric MatchingInlineAsm);
1249284c1978SDimitry Andric switch (MatchResult) {
1250284c1978SDimitry Andric case Match_Success:
1251284c1978SDimitry Andric Inst.setLoc(IDLoc);
12527d523365SDimitry Andric Out.EmitInstruction(Inst, getSTI());
1253284c1978SDimitry Andric return false;
1254284c1978SDimitry Andric
1255284c1978SDimitry Andric case Match_MissingFeature: {
1256284c1978SDimitry Andric assert(ErrorInfo && "Unknown missing feature!");
1257284c1978SDimitry Andric // Special case the error message for the very common case where only
1258284c1978SDimitry Andric // a single subtarget feature is missing
1259284c1978SDimitry Andric std::string Msg = "instruction requires:";
126039d628a0SDimitry Andric uint64_t Mask = 1;
1261284c1978SDimitry Andric for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
1262284c1978SDimitry Andric if (ErrorInfo & Mask) {
1263284c1978SDimitry Andric Msg += " ";
1264284c1978SDimitry Andric Msg += getSubtargetFeatureName(ErrorInfo & Mask);
1265284c1978SDimitry Andric }
1266284c1978SDimitry Andric Mask <<= 1;
1267284c1978SDimitry Andric }
1268284c1978SDimitry Andric return Error(IDLoc, Msg);
1269284c1978SDimitry Andric }
1270284c1978SDimitry Andric
1271284c1978SDimitry Andric case Match_InvalidOperand: {
1272284c1978SDimitry Andric SMLoc ErrorLoc = IDLoc;
127339d628a0SDimitry Andric if (ErrorInfo != ~0ULL) {
1274284c1978SDimitry Andric if (ErrorInfo >= Operands.size())
1275284c1978SDimitry Andric return Error(IDLoc, "too few operands for instruction");
1276284c1978SDimitry Andric
127791bc56edSDimitry Andric ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
1278284c1978SDimitry Andric if (ErrorLoc == SMLoc())
1279284c1978SDimitry Andric ErrorLoc = IDLoc;
1280284c1978SDimitry Andric }
1281284c1978SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction");
1282284c1978SDimitry Andric }
1283284c1978SDimitry Andric
1284b40b48b8SDimitry Andric case Match_MnemonicFail: {
1285b40b48b8SDimitry Andric uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1286b40b48b8SDimitry Andric std::string Suggestion = SystemZMnemonicSpellCheck(
1287b40b48b8SDimitry Andric ((SystemZOperand &)*Operands[0]).getToken(), FBS);
1288b40b48b8SDimitry Andric return Error(IDLoc, "invalid instruction" + Suggestion,
1289b40b48b8SDimitry Andric ((SystemZOperand &)*Operands[0]).getLocRange());
1290b40b48b8SDimitry Andric }
1291284c1978SDimitry Andric }
1292284c1978SDimitry Andric
1293284c1978SDimitry Andric llvm_unreachable("Unexpected match type");
1294284c1978SDimitry Andric }
1295284c1978SDimitry Andric
1296d88c1a5aSDimitry Andric OperandMatchResultTy
parsePCRel(OperandVector & Operands,int64_t MinVal,int64_t MaxVal,bool AllowTLS)129791bc56edSDimitry Andric SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
1298ff0cc061SDimitry Andric int64_t MaxVal, bool AllowTLS) {
1299f785676fSDimitry Andric MCContext &Ctx = getContext();
1300f785676fSDimitry Andric MCStreamer &Out = getStreamer();
1301f785676fSDimitry Andric const MCExpr *Expr;
1302f785676fSDimitry Andric SMLoc StartLoc = Parser.getTok().getLoc();
1303f785676fSDimitry Andric if (getParser().parseExpression(Expr))
1304f785676fSDimitry Andric return MatchOperand_NoMatch;
1305f785676fSDimitry Andric
1306f785676fSDimitry Andric // For consistency with the GNU assembler, treat immediates as offsets
1307f785676fSDimitry Andric // from ".".
130891bc56edSDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
1309f785676fSDimitry Andric int64_t Value = CE->getValue();
1310f785676fSDimitry Andric if ((Value & 1) || Value < MinVal || Value > MaxVal) {
1311f785676fSDimitry Andric Error(StartLoc, "offset out of range");
1312284c1978SDimitry Andric return MatchOperand_ParseFail;
1313284c1978SDimitry Andric }
1314ff0cc061SDimitry Andric MCSymbol *Sym = Ctx.createTempSymbol();
1315f785676fSDimitry Andric Out.EmitLabel(Sym);
131697bc6c73SDimitry Andric const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1317f785676fSDimitry Andric Ctx);
131897bc6c73SDimitry Andric Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);
1319f785676fSDimitry Andric }
1320f785676fSDimitry Andric
1321ff0cc061SDimitry Andric // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
1322ff0cc061SDimitry Andric const MCExpr *Sym = nullptr;
1323ff0cc061SDimitry Andric if (AllowTLS && getLexer().is(AsmToken::Colon)) {
1324ff0cc061SDimitry Andric Parser.Lex();
1325ff0cc061SDimitry Andric
1326ff0cc061SDimitry Andric if (Parser.getTok().isNot(AsmToken::Identifier)) {
1327ff0cc061SDimitry Andric Error(Parser.getTok().getLoc(), "unexpected token");
1328ff0cc061SDimitry Andric return MatchOperand_ParseFail;
1329ff0cc061SDimitry Andric }
1330ff0cc061SDimitry Andric
1331ff0cc061SDimitry Andric MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
1332ff0cc061SDimitry Andric StringRef Name = Parser.getTok().getString();
1333ff0cc061SDimitry Andric if (Name == "tls_gdcall")
1334ff0cc061SDimitry Andric Kind = MCSymbolRefExpr::VK_TLSGD;
1335ff0cc061SDimitry Andric else if (Name == "tls_ldcall")
1336ff0cc061SDimitry Andric Kind = MCSymbolRefExpr::VK_TLSLDM;
1337ff0cc061SDimitry Andric else {
1338ff0cc061SDimitry Andric Error(Parser.getTok().getLoc(), "unknown TLS tag");
1339ff0cc061SDimitry Andric return MatchOperand_ParseFail;
1340ff0cc061SDimitry Andric }
1341ff0cc061SDimitry Andric Parser.Lex();
1342ff0cc061SDimitry Andric
1343ff0cc061SDimitry Andric if (Parser.getTok().isNot(AsmToken::Colon)) {
1344ff0cc061SDimitry Andric Error(Parser.getTok().getLoc(), "unexpected token");
1345ff0cc061SDimitry Andric return MatchOperand_ParseFail;
1346ff0cc061SDimitry Andric }
1347ff0cc061SDimitry Andric Parser.Lex();
1348ff0cc061SDimitry Andric
1349ff0cc061SDimitry Andric if (Parser.getTok().isNot(AsmToken::Identifier)) {
1350ff0cc061SDimitry Andric Error(Parser.getTok().getLoc(), "unexpected token");
1351ff0cc061SDimitry Andric return MatchOperand_ParseFail;
1352ff0cc061SDimitry Andric }
1353ff0cc061SDimitry Andric
1354ff0cc061SDimitry Andric StringRef Identifier = Parser.getTok().getString();
135597bc6c73SDimitry Andric Sym = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(Identifier),
1356ff0cc061SDimitry Andric Kind, Ctx);
1357ff0cc061SDimitry Andric Parser.Lex();
1358ff0cc061SDimitry Andric }
1359ff0cc061SDimitry Andric
1360f785676fSDimitry Andric SMLoc EndLoc =
1361f785676fSDimitry Andric SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1362ff0cc061SDimitry Andric
1363ff0cc061SDimitry Andric if (AllowTLS)
1364ff0cc061SDimitry Andric Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1365ff0cc061SDimitry Andric StartLoc, EndLoc));
1366ff0cc061SDimitry Andric else
1367f785676fSDimitry Andric Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1368ff0cc061SDimitry Andric
1369284c1978SDimitry Andric return MatchOperand_Success;
1370284c1978SDimitry Andric }
1371284c1978SDimitry Andric
1372284c1978SDimitry Andric // Force static initialization.
LLVMInitializeSystemZAsmParser()1373284c1978SDimitry Andric extern "C" void LLVMInitializeSystemZAsmParser() {
1374d88c1a5aSDimitry Andric RegisterMCAsmParser<SystemZAsmParser> X(getTheSystemZTarget());
1375284c1978SDimitry Andric }
1376