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