1*5f613dfdSUlrich Weigand //===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2*5f613dfdSUlrich Weigand //
3*5f613dfdSUlrich Weigand //                     The LLVM Compiler Infrastructure
4*5f613dfdSUlrich Weigand //
5*5f613dfdSUlrich Weigand // This file is distributed under the University of Illinois Open Source
6*5f613dfdSUlrich Weigand // License. See LICENSE.TXT for details.
7*5f613dfdSUlrich Weigand //
8*5f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
9*5f613dfdSUlrich Weigand 
10*5f613dfdSUlrich Weigand #include "MCTargetDesc/SystemZMCTargetDesc.h"
11*5f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h"
12*5f613dfdSUlrich Weigand #include "llvm/MC/MCInst.h"
13*5f613dfdSUlrich Weigand #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
14*5f613dfdSUlrich Weigand #include "llvm/MC/MCStreamer.h"
15*5f613dfdSUlrich Weigand #include "llvm/MC/MCSubtargetInfo.h"
16*5f613dfdSUlrich Weigand #include "llvm/MC/MCTargetAsmParser.h"
17*5f613dfdSUlrich Weigand #include "llvm/Support/TargetRegistry.h"
18*5f613dfdSUlrich Weigand 
19*5f613dfdSUlrich Weigand using namespace llvm;
20*5f613dfdSUlrich Weigand 
21*5f613dfdSUlrich Weigand // Return true if Expr is in the range [MinValue, MaxValue].
22*5f613dfdSUlrich Weigand static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
23*5f613dfdSUlrich Weigand   if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
24*5f613dfdSUlrich Weigand     int64_t Value = CE->getValue();
25*5f613dfdSUlrich Weigand     return Value >= MinValue && Value <= MaxValue;
26*5f613dfdSUlrich Weigand   }
27*5f613dfdSUlrich Weigand   return false;
28*5f613dfdSUlrich Weigand }
29*5f613dfdSUlrich Weigand 
30*5f613dfdSUlrich Weigand namespace {
31*5f613dfdSUlrich Weigand class SystemZOperand : public MCParsedAsmOperand {
32*5f613dfdSUlrich Weigand public:
33*5f613dfdSUlrich Weigand   enum RegisterKind {
34*5f613dfdSUlrich Weigand     GR32Reg,
35*5f613dfdSUlrich Weigand     GR64Reg,
36*5f613dfdSUlrich Weigand     GR128Reg,
37*5f613dfdSUlrich Weigand     ADDR32Reg,
38*5f613dfdSUlrich Weigand     ADDR64Reg,
39*5f613dfdSUlrich Weigand     FP32Reg,
40*5f613dfdSUlrich Weigand     FP64Reg,
41*5f613dfdSUlrich Weigand     FP128Reg
42*5f613dfdSUlrich Weigand   };
43*5f613dfdSUlrich Weigand 
44*5f613dfdSUlrich Weigand private:
45*5f613dfdSUlrich Weigand   enum OperandKind {
46*5f613dfdSUlrich Weigand     KindToken,
47*5f613dfdSUlrich Weigand     KindReg,
48*5f613dfdSUlrich Weigand     KindAccessReg,
49*5f613dfdSUlrich Weigand     KindImm,
50*5f613dfdSUlrich Weigand     KindMem
51*5f613dfdSUlrich Weigand   };
52*5f613dfdSUlrich Weigand 
53*5f613dfdSUlrich Weigand   OperandKind Kind;
54*5f613dfdSUlrich Weigand   SMLoc StartLoc, EndLoc;
55*5f613dfdSUlrich Weigand 
56*5f613dfdSUlrich Weigand   // A string of length Length, starting at Data.
57*5f613dfdSUlrich Weigand   struct TokenOp {
58*5f613dfdSUlrich Weigand     const char *Data;
59*5f613dfdSUlrich Weigand     unsigned Length;
60*5f613dfdSUlrich Weigand   };
61*5f613dfdSUlrich Weigand 
62*5f613dfdSUlrich Weigand   // LLVM register Num, which has kind Kind.
63*5f613dfdSUlrich Weigand   struct RegOp {
64*5f613dfdSUlrich Weigand     RegisterKind Kind;
65*5f613dfdSUlrich Weigand     unsigned Num;
66*5f613dfdSUlrich Weigand   };
67*5f613dfdSUlrich Weigand 
68*5f613dfdSUlrich Weigand   // Base + Disp + Index, where Base and Index are LLVM registers or 0.
69*5f613dfdSUlrich Weigand   // RegKind says what type the registers have (ADDR32Reg or ADDR64Reg).
70*5f613dfdSUlrich Weigand   struct MemOp {
71*5f613dfdSUlrich Weigand     unsigned Base : 8;
72*5f613dfdSUlrich Weigand     unsigned Index : 8;
73*5f613dfdSUlrich Weigand     unsigned RegKind : 8;
74*5f613dfdSUlrich Weigand     unsigned Unused : 8;
75*5f613dfdSUlrich Weigand     const MCExpr *Disp;
76*5f613dfdSUlrich Weigand   };
77*5f613dfdSUlrich Weigand 
78*5f613dfdSUlrich Weigand   union {
79*5f613dfdSUlrich Weigand     TokenOp Token;
80*5f613dfdSUlrich Weigand     RegOp Reg;
81*5f613dfdSUlrich Weigand     unsigned AccessReg;
82*5f613dfdSUlrich Weigand     const MCExpr *Imm;
83*5f613dfdSUlrich Weigand     MemOp Mem;
84*5f613dfdSUlrich Weigand   };
85*5f613dfdSUlrich Weigand 
86*5f613dfdSUlrich Weigand   SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
87*5f613dfdSUlrich Weigand     : Kind(kind), StartLoc(startLoc), EndLoc(endLoc)
88*5f613dfdSUlrich Weigand   {}
89*5f613dfdSUlrich Weigand 
90*5f613dfdSUlrich Weigand   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
91*5f613dfdSUlrich Weigand     // Add as immediates when possible.  Null MCExpr = 0.
92*5f613dfdSUlrich Weigand     if (Expr == 0)
93*5f613dfdSUlrich Weigand       Inst.addOperand(MCOperand::CreateImm(0));
94*5f613dfdSUlrich Weigand     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
95*5f613dfdSUlrich Weigand       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
96*5f613dfdSUlrich Weigand     else
97*5f613dfdSUlrich Weigand       Inst.addOperand(MCOperand::CreateExpr(Expr));
98*5f613dfdSUlrich Weigand   }
99*5f613dfdSUlrich Weigand 
100*5f613dfdSUlrich Weigand public:
101*5f613dfdSUlrich Weigand   // Create particular kinds of operand.
102*5f613dfdSUlrich Weigand   static SystemZOperand *createToken(StringRef Str, SMLoc Loc) {
103*5f613dfdSUlrich Weigand     SystemZOperand *Op = new SystemZOperand(KindToken, Loc, Loc);
104*5f613dfdSUlrich Weigand     Op->Token.Data = Str.data();
105*5f613dfdSUlrich Weigand     Op->Token.Length = Str.size();
106*5f613dfdSUlrich Weigand     return Op;
107*5f613dfdSUlrich Weigand   }
108*5f613dfdSUlrich Weigand   static SystemZOperand *createReg(RegisterKind Kind, unsigned Num,
109*5f613dfdSUlrich Weigand                                    SMLoc StartLoc, SMLoc EndLoc) {
110*5f613dfdSUlrich Weigand     SystemZOperand *Op = new SystemZOperand(KindReg, StartLoc, EndLoc);
111*5f613dfdSUlrich Weigand     Op->Reg.Kind = Kind;
112*5f613dfdSUlrich Weigand     Op->Reg.Num = Num;
113*5f613dfdSUlrich Weigand     return Op;
114*5f613dfdSUlrich Weigand   }
115*5f613dfdSUlrich Weigand   static SystemZOperand *createAccessReg(unsigned Num, SMLoc StartLoc,
116*5f613dfdSUlrich Weigand                                          SMLoc EndLoc) {
117*5f613dfdSUlrich Weigand     SystemZOperand *Op = new SystemZOperand(KindAccessReg, StartLoc, EndLoc);
118*5f613dfdSUlrich Weigand     Op->AccessReg = Num;
119*5f613dfdSUlrich Weigand     return Op;
120*5f613dfdSUlrich Weigand   }
121*5f613dfdSUlrich Weigand   static SystemZOperand *createImm(const MCExpr *Expr, SMLoc StartLoc,
122*5f613dfdSUlrich Weigand                                    SMLoc EndLoc) {
123*5f613dfdSUlrich Weigand     SystemZOperand *Op = new SystemZOperand(KindImm, StartLoc, EndLoc);
124*5f613dfdSUlrich Weigand     Op->Imm = Expr;
125*5f613dfdSUlrich Weigand     return Op;
126*5f613dfdSUlrich Weigand   }
127*5f613dfdSUlrich Weigand   static SystemZOperand *createMem(RegisterKind RegKind, unsigned Base,
128*5f613dfdSUlrich Weigand                                    const MCExpr *Disp, unsigned Index,
129*5f613dfdSUlrich Weigand                                    SMLoc StartLoc, SMLoc EndLoc) {
130*5f613dfdSUlrich Weigand     SystemZOperand *Op = new SystemZOperand(KindMem, StartLoc, EndLoc);
131*5f613dfdSUlrich Weigand     Op->Mem.RegKind = RegKind;
132*5f613dfdSUlrich Weigand     Op->Mem.Base = Base;
133*5f613dfdSUlrich Weigand     Op->Mem.Index = Index;
134*5f613dfdSUlrich Weigand     Op->Mem.Disp = Disp;
135*5f613dfdSUlrich Weigand     return Op;
136*5f613dfdSUlrich Weigand   }
137*5f613dfdSUlrich Weigand 
138*5f613dfdSUlrich Weigand   // Token operands
139*5f613dfdSUlrich Weigand   virtual bool isToken() const LLVM_OVERRIDE {
140*5f613dfdSUlrich Weigand     return Kind == KindToken;
141*5f613dfdSUlrich Weigand   }
142*5f613dfdSUlrich Weigand   StringRef getToken() const {
143*5f613dfdSUlrich Weigand     assert(Kind == KindToken && "Not a token");
144*5f613dfdSUlrich Weigand     return StringRef(Token.Data, Token.Length);
145*5f613dfdSUlrich Weigand   }
146*5f613dfdSUlrich Weigand 
147*5f613dfdSUlrich Weigand   // Register operands.
148*5f613dfdSUlrich Weigand   virtual bool isReg() const LLVM_OVERRIDE {
149*5f613dfdSUlrich Weigand     return Kind == KindReg;
150*5f613dfdSUlrich Weigand   }
151*5f613dfdSUlrich Weigand   bool isReg(RegisterKind RegKind) const {
152*5f613dfdSUlrich Weigand     return Kind == KindReg && Reg.Kind == RegKind;
153*5f613dfdSUlrich Weigand   }
154*5f613dfdSUlrich Weigand   virtual unsigned getReg() const LLVM_OVERRIDE {
155*5f613dfdSUlrich Weigand     assert(Kind == KindReg && "Not a register");
156*5f613dfdSUlrich Weigand     return Reg.Num;
157*5f613dfdSUlrich Weigand   }
158*5f613dfdSUlrich Weigand 
159*5f613dfdSUlrich Weigand   // Access register operands.  Access registers aren't exposed to LLVM
160*5f613dfdSUlrich Weigand   // as registers.
161*5f613dfdSUlrich Weigand   bool isAccessReg() const {
162*5f613dfdSUlrich Weigand     return Kind == KindAccessReg;
163*5f613dfdSUlrich Weigand   }
164*5f613dfdSUlrich Weigand 
165*5f613dfdSUlrich Weigand   // Immediate operands.
166*5f613dfdSUlrich Weigand   virtual bool isImm() const LLVM_OVERRIDE {
167*5f613dfdSUlrich Weigand     return Kind == KindImm;
168*5f613dfdSUlrich Weigand   }
169*5f613dfdSUlrich Weigand   bool isImm(int64_t MinValue, int64_t MaxValue) const {
170*5f613dfdSUlrich Weigand     return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
171*5f613dfdSUlrich Weigand   }
172*5f613dfdSUlrich Weigand   const MCExpr *getImm() const {
173*5f613dfdSUlrich Weigand     assert(Kind == KindImm && "Not an immediate");
174*5f613dfdSUlrich Weigand     return Imm;
175*5f613dfdSUlrich Weigand   }
176*5f613dfdSUlrich Weigand 
177*5f613dfdSUlrich Weigand   // Memory operands.
178*5f613dfdSUlrich Weigand   virtual bool isMem() const LLVM_OVERRIDE {
179*5f613dfdSUlrich Weigand     return Kind == KindMem;
180*5f613dfdSUlrich Weigand   }
181*5f613dfdSUlrich Weigand   bool isMem(RegisterKind RegKind, bool HasIndex) const {
182*5f613dfdSUlrich Weigand     return (Kind == KindMem &&
183*5f613dfdSUlrich Weigand             Mem.RegKind == RegKind &&
184*5f613dfdSUlrich Weigand             (HasIndex || !Mem.Index));
185*5f613dfdSUlrich Weigand   }
186*5f613dfdSUlrich Weigand   bool isMemDisp12(RegisterKind RegKind, bool HasIndex) const {
187*5f613dfdSUlrich Weigand     return isMem(RegKind, HasIndex) && inRange(Mem.Disp, 0, 0xfff);
188*5f613dfdSUlrich Weigand   }
189*5f613dfdSUlrich Weigand   bool isMemDisp20(RegisterKind RegKind, bool HasIndex) const {
190*5f613dfdSUlrich Weigand     return isMem(RegKind, HasIndex) && inRange(Mem.Disp, -524288, 524287);
191*5f613dfdSUlrich Weigand   }
192*5f613dfdSUlrich Weigand 
193*5f613dfdSUlrich Weigand   // Override MCParsedAsmOperand.
194*5f613dfdSUlrich Weigand   virtual SMLoc getStartLoc() const LLVM_OVERRIDE { return StartLoc; }
195*5f613dfdSUlrich Weigand   virtual SMLoc getEndLoc() const LLVM_OVERRIDE { return EndLoc; }
196*5f613dfdSUlrich Weigand   virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
197*5f613dfdSUlrich Weigand 
198*5f613dfdSUlrich Weigand   // Used by the TableGen code to add particular types of operand
199*5f613dfdSUlrich Weigand   // to an instruction.
200*5f613dfdSUlrich Weigand   void addRegOperands(MCInst &Inst, unsigned N) const {
201*5f613dfdSUlrich Weigand     assert(N == 1 && "Invalid number of operands");
202*5f613dfdSUlrich Weigand     Inst.addOperand(MCOperand::CreateReg(getReg()));
203*5f613dfdSUlrich Weigand   }
204*5f613dfdSUlrich Weigand   void addAccessRegOperands(MCInst &Inst, unsigned N) const {
205*5f613dfdSUlrich Weigand     assert(N == 1 && "Invalid number of operands");
206*5f613dfdSUlrich Weigand     assert(Kind == KindAccessReg && "Invalid operand type");
207*5f613dfdSUlrich Weigand     Inst.addOperand(MCOperand::CreateImm(AccessReg));
208*5f613dfdSUlrich Weigand   }
209*5f613dfdSUlrich Weigand   void addImmOperands(MCInst &Inst, unsigned N) const {
210*5f613dfdSUlrich Weigand     assert(N == 1 && "Invalid number of operands");
211*5f613dfdSUlrich Weigand     addExpr(Inst, getImm());
212*5f613dfdSUlrich Weigand   }
213*5f613dfdSUlrich Weigand   void addBDAddrOperands(MCInst &Inst, unsigned N) const {
214*5f613dfdSUlrich Weigand     assert(N == 2 && "Invalid number of operands");
215*5f613dfdSUlrich Weigand     assert(Kind == KindMem && Mem.Index == 0 && "Invalid operand type");
216*5f613dfdSUlrich Weigand     Inst.addOperand(MCOperand::CreateReg(Mem.Base));
217*5f613dfdSUlrich Weigand     addExpr(Inst, Mem.Disp);
218*5f613dfdSUlrich Weigand   }
219*5f613dfdSUlrich Weigand   void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
220*5f613dfdSUlrich Weigand     assert(N == 3 && "Invalid number of operands");
221*5f613dfdSUlrich Weigand     assert(Kind == KindMem && "Invalid operand type");
222*5f613dfdSUlrich Weigand     Inst.addOperand(MCOperand::CreateReg(Mem.Base));
223*5f613dfdSUlrich Weigand     addExpr(Inst, Mem.Disp);
224*5f613dfdSUlrich Weigand     Inst.addOperand(MCOperand::CreateReg(Mem.Index));
225*5f613dfdSUlrich Weigand   }
226*5f613dfdSUlrich Weigand 
227*5f613dfdSUlrich Weigand   // Used by the TableGen code to check for particular operand types.
228*5f613dfdSUlrich Weigand   bool isGR32() const { return isReg(GR32Reg); }
229*5f613dfdSUlrich Weigand   bool isGR64() const { return isReg(GR64Reg); }
230*5f613dfdSUlrich Weigand   bool isGR128() const { return isReg(GR128Reg); }
231*5f613dfdSUlrich Weigand   bool isADDR32() const { return isReg(ADDR32Reg); }
232*5f613dfdSUlrich Weigand   bool isADDR64() const { return isReg(ADDR64Reg); }
233*5f613dfdSUlrich Weigand   bool isADDR128() const { return false; }
234*5f613dfdSUlrich Weigand   bool isFP32() const { return isReg(FP32Reg); }
235*5f613dfdSUlrich Weigand   bool isFP64() const { return isReg(FP64Reg); }
236*5f613dfdSUlrich Weigand   bool isFP128() const { return isReg(FP128Reg); }
237*5f613dfdSUlrich Weigand   bool isBDAddr32Disp12() const { return isMemDisp12(ADDR32Reg, false); }
238*5f613dfdSUlrich Weigand   bool isBDAddr32Disp20() const { return isMemDisp20(ADDR32Reg, false); }
239*5f613dfdSUlrich Weigand   bool isBDAddr64Disp12() const { return isMemDisp12(ADDR64Reg, false); }
240*5f613dfdSUlrich Weigand   bool isBDAddr64Disp20() const { return isMemDisp20(ADDR64Reg, false); }
241*5f613dfdSUlrich Weigand   bool isBDXAddr64Disp12() const { return isMemDisp12(ADDR64Reg, true); }
242*5f613dfdSUlrich Weigand   bool isBDXAddr64Disp20() const { return isMemDisp20(ADDR64Reg, true); }
243*5f613dfdSUlrich Weigand   bool isU4Imm() const { return isImm(0, 15); }
244*5f613dfdSUlrich Weigand   bool isU6Imm() const { return isImm(0, 63); }
245*5f613dfdSUlrich Weigand   bool isU8Imm() const { return isImm(0, 255); }
246*5f613dfdSUlrich Weigand   bool isS8Imm() const { return isImm(-128, 127); }
247*5f613dfdSUlrich Weigand   bool isU16Imm() const { return isImm(0, 65535); }
248*5f613dfdSUlrich Weigand   bool isS16Imm() const { return isImm(-32768, 32767); }
249*5f613dfdSUlrich Weigand   bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
250*5f613dfdSUlrich Weigand   bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
251*5f613dfdSUlrich Weigand };
252*5f613dfdSUlrich Weigand 
253*5f613dfdSUlrich Weigand // Maps of asm register numbers to LLVM register numbers, with 0 indicating
254*5f613dfdSUlrich Weigand // an invalid register.  We don't use register class directly because that
255*5f613dfdSUlrich Weigand // specifies the allocation order.
256*5f613dfdSUlrich Weigand static const unsigned GR32Regs[] = {
257*5f613dfdSUlrich Weigand   SystemZ::R0W, SystemZ::R1W, SystemZ::R2W, SystemZ::R3W,
258*5f613dfdSUlrich Weigand   SystemZ::R4W, SystemZ::R5W, SystemZ::R6W, SystemZ::R7W,
259*5f613dfdSUlrich Weigand   SystemZ::R8W, SystemZ::R9W, SystemZ::R10W, SystemZ::R11W,
260*5f613dfdSUlrich Weigand   SystemZ::R12W, SystemZ::R13W, SystemZ::R14W, SystemZ::R15W
261*5f613dfdSUlrich Weigand };
262*5f613dfdSUlrich Weigand static const unsigned GR64Regs[] = {
263*5f613dfdSUlrich Weigand   SystemZ::R0D, SystemZ::R1D, SystemZ::R2D, SystemZ::R3D,
264*5f613dfdSUlrich Weigand   SystemZ::R4D, SystemZ::R5D, SystemZ::R6D, SystemZ::R7D,
265*5f613dfdSUlrich Weigand   SystemZ::R8D, SystemZ::R9D, SystemZ::R10D, SystemZ::R11D,
266*5f613dfdSUlrich Weigand   SystemZ::R12D, SystemZ::R13D, SystemZ::R14D, SystemZ::R15D
267*5f613dfdSUlrich Weigand };
268*5f613dfdSUlrich Weigand static const unsigned GR128Regs[] = {
269*5f613dfdSUlrich Weigand   SystemZ::R0Q, 0, SystemZ::R2Q, 0,
270*5f613dfdSUlrich Weigand   SystemZ::R4Q, 0, SystemZ::R6Q, 0,
271*5f613dfdSUlrich Weigand   SystemZ::R8Q, 0, SystemZ::R10Q, 0,
272*5f613dfdSUlrich Weigand   SystemZ::R12Q, 0, SystemZ::R14Q, 0
273*5f613dfdSUlrich Weigand };
274*5f613dfdSUlrich Weigand static const unsigned FP32Regs[] = {
275*5f613dfdSUlrich Weigand   SystemZ::F0S, SystemZ::F1S, SystemZ::F2S, SystemZ::F3S,
276*5f613dfdSUlrich Weigand   SystemZ::F4S, SystemZ::F5S, SystemZ::F6S, SystemZ::F7S,
277*5f613dfdSUlrich Weigand   SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S,
278*5f613dfdSUlrich Weigand   SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S
279*5f613dfdSUlrich Weigand };
280*5f613dfdSUlrich Weigand static const unsigned FP64Regs[] = {
281*5f613dfdSUlrich Weigand   SystemZ::F0D, SystemZ::F1D, SystemZ::F2D, SystemZ::F3D,
282*5f613dfdSUlrich Weigand   SystemZ::F4D, SystemZ::F5D, SystemZ::F6D, SystemZ::F7D,
283*5f613dfdSUlrich Weigand   SystemZ::F8D, SystemZ::F9D, SystemZ::F10D, SystemZ::F11D,
284*5f613dfdSUlrich Weigand   SystemZ::F12D, SystemZ::F13D, SystemZ::F14D, SystemZ::F15D
285*5f613dfdSUlrich Weigand };
286*5f613dfdSUlrich Weigand static const unsigned FP128Regs[] = {
287*5f613dfdSUlrich Weigand   SystemZ::F0Q, SystemZ::F1Q, 0, 0,
288*5f613dfdSUlrich Weigand   SystemZ::F4Q, SystemZ::F5Q, 0, 0,
289*5f613dfdSUlrich Weigand   SystemZ::F8Q, SystemZ::F9Q, 0, 0,
290*5f613dfdSUlrich Weigand   SystemZ::F12Q, SystemZ::F13Q, 0, 0
291*5f613dfdSUlrich Weigand };
292*5f613dfdSUlrich Weigand 
293*5f613dfdSUlrich Weigand class SystemZAsmParser : public MCTargetAsmParser {
294*5f613dfdSUlrich Weigand #define GET_ASSEMBLER_HEADER
295*5f613dfdSUlrich Weigand #include "SystemZGenAsmMatcher.inc"
296*5f613dfdSUlrich Weigand 
297*5f613dfdSUlrich Weigand private:
298*5f613dfdSUlrich Weigand   MCSubtargetInfo &STI;
299*5f613dfdSUlrich Weigand   MCAsmParser &Parser;
300*5f613dfdSUlrich Weigand   struct Register {
301*5f613dfdSUlrich Weigand     char Prefix;
302*5f613dfdSUlrich Weigand     unsigned Number;
303*5f613dfdSUlrich Weigand     SMLoc StartLoc, EndLoc;
304*5f613dfdSUlrich Weigand   };
305*5f613dfdSUlrich Weigand 
306*5f613dfdSUlrich Weigand   bool parseRegister(Register &Reg);
307*5f613dfdSUlrich Weigand 
308*5f613dfdSUlrich Weigand   OperandMatchResultTy
309*5f613dfdSUlrich Weigand   parseRegister(Register &Reg, char Prefix, const unsigned *Regs,
310*5f613dfdSUlrich Weigand                 bool IsAddress = false);
311*5f613dfdSUlrich Weigand 
312*5f613dfdSUlrich Weigand   OperandMatchResultTy
313*5f613dfdSUlrich Weigand   parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
314*5f613dfdSUlrich Weigand                 char Prefix, const unsigned *Regs,
315*5f613dfdSUlrich Weigand                 SystemZOperand::RegisterKind Kind,
316*5f613dfdSUlrich Weigand                 bool IsAddress = false);
317*5f613dfdSUlrich Weigand 
318*5f613dfdSUlrich Weigand   OperandMatchResultTy
319*5f613dfdSUlrich Weigand   parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
320*5f613dfdSUlrich Weigand                const unsigned *Regs, SystemZOperand::RegisterKind RegKind,
321*5f613dfdSUlrich Weigand                bool HasIndex);
322*5f613dfdSUlrich Weigand 
323*5f613dfdSUlrich Weigand   bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
324*5f613dfdSUlrich Weigand                     StringRef Mnemonic);
325*5f613dfdSUlrich Weigand 
326*5f613dfdSUlrich Weigand public:
327*5f613dfdSUlrich Weigand   SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
328*5f613dfdSUlrich Weigand     : MCTargetAsmParser(), STI(sti), Parser(parser) {
329*5f613dfdSUlrich Weigand     MCAsmParserExtension::Initialize(Parser);
330*5f613dfdSUlrich Weigand 
331*5f613dfdSUlrich Weigand     // Initialize the set of available features.
332*5f613dfdSUlrich Weigand     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
333*5f613dfdSUlrich Weigand   }
334*5f613dfdSUlrich Weigand 
335*5f613dfdSUlrich Weigand   // Override MCTargetAsmParser.
336*5f613dfdSUlrich Weigand   virtual bool ParseDirective(AsmToken DirectiveID) LLVM_OVERRIDE;
337*5f613dfdSUlrich Weigand   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
338*5f613dfdSUlrich Weigand                              SMLoc &EndLoc) LLVM_OVERRIDE;
339*5f613dfdSUlrich Weigand   virtual bool ParseInstruction(ParseInstructionInfo &Info,
340*5f613dfdSUlrich Weigand                                 StringRef Name, SMLoc NameLoc,
341*5f613dfdSUlrich Weigand                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
342*5f613dfdSUlrich Weigand     LLVM_OVERRIDE;
343*5f613dfdSUlrich Weigand   virtual bool
344*5f613dfdSUlrich Weigand     MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
345*5f613dfdSUlrich Weigand                             SmallVectorImpl<MCParsedAsmOperand*> &Operands,
346*5f613dfdSUlrich Weigand                             MCStreamer &Out, unsigned &ErrorInfo,
347*5f613dfdSUlrich Weigand                             bool MatchingInlineAsm) LLVM_OVERRIDE;
348*5f613dfdSUlrich Weigand 
349*5f613dfdSUlrich Weigand   // Used by the TableGen code to parse particular operand types.
350*5f613dfdSUlrich Weigand   OperandMatchResultTy
351*5f613dfdSUlrich Weigand   parseGR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
352*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'r', GR32Regs, SystemZOperand::GR32Reg);
353*5f613dfdSUlrich Weigand   }
354*5f613dfdSUlrich Weigand   OperandMatchResultTy
355*5f613dfdSUlrich Weigand   parseGR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
356*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'r', GR64Regs, SystemZOperand::GR64Reg);
357*5f613dfdSUlrich Weigand   }
358*5f613dfdSUlrich Weigand   OperandMatchResultTy
359*5f613dfdSUlrich Weigand   parseGR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
360*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'r', GR128Regs, SystemZOperand::GR128Reg);
361*5f613dfdSUlrich Weigand   }
362*5f613dfdSUlrich Weigand   OperandMatchResultTy
363*5f613dfdSUlrich Weigand   parseADDR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
364*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'r', GR32Regs, SystemZOperand::ADDR32Reg,
365*5f613dfdSUlrich Weigand                          true);
366*5f613dfdSUlrich Weigand   }
367*5f613dfdSUlrich Weigand   OperandMatchResultTy
368*5f613dfdSUlrich Weigand   parseADDR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
369*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'r', GR64Regs, SystemZOperand::ADDR64Reg,
370*5f613dfdSUlrich Weigand                          true);
371*5f613dfdSUlrich Weigand   }
372*5f613dfdSUlrich Weigand   OperandMatchResultTy
373*5f613dfdSUlrich Weigand   parseADDR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
374*5f613dfdSUlrich Weigand     llvm_unreachable("Shouldn't be used as an operand");
375*5f613dfdSUlrich Weigand   }
376*5f613dfdSUlrich Weigand   OperandMatchResultTy
377*5f613dfdSUlrich Weigand   parseFP32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
378*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'f', FP32Regs, SystemZOperand::FP32Reg);
379*5f613dfdSUlrich Weigand   }
380*5f613dfdSUlrich Weigand   OperandMatchResultTy
381*5f613dfdSUlrich Weigand   parseFP64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
382*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'f', FP64Regs, SystemZOperand::FP64Reg);
383*5f613dfdSUlrich Weigand   }
384*5f613dfdSUlrich Weigand   OperandMatchResultTy
385*5f613dfdSUlrich Weigand   parseFP128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
386*5f613dfdSUlrich Weigand     return parseRegister(Operands, 'f', FP128Regs, SystemZOperand::FP128Reg);
387*5f613dfdSUlrich Weigand   }
388*5f613dfdSUlrich Weigand   OperandMatchResultTy
389*5f613dfdSUlrich Weigand   parseBDAddr32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
390*5f613dfdSUlrich Weigand     return parseAddress(Operands, GR32Regs, SystemZOperand::ADDR32Reg, false);
391*5f613dfdSUlrich Weigand   }
392*5f613dfdSUlrich Weigand   OperandMatchResultTy
393*5f613dfdSUlrich Weigand   parseBDAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
394*5f613dfdSUlrich Weigand     return parseAddress(Operands, GR64Regs, SystemZOperand::ADDR64Reg, false);
395*5f613dfdSUlrich Weigand   }
396*5f613dfdSUlrich Weigand   OperandMatchResultTy
397*5f613dfdSUlrich Weigand   parseBDXAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
398*5f613dfdSUlrich Weigand     return parseAddress(Operands, GR64Regs, SystemZOperand::ADDR64Reg, true);
399*5f613dfdSUlrich Weigand   }
400*5f613dfdSUlrich Weigand   OperandMatchResultTy
401*5f613dfdSUlrich Weigand   parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
402*5f613dfdSUlrich Weigand };
403*5f613dfdSUlrich Weigand }
404*5f613dfdSUlrich Weigand 
405*5f613dfdSUlrich Weigand #define GET_REGISTER_MATCHER
406*5f613dfdSUlrich Weigand #define GET_SUBTARGET_FEATURE_NAME
407*5f613dfdSUlrich Weigand #define GET_MATCHER_IMPLEMENTATION
408*5f613dfdSUlrich Weigand #include "SystemZGenAsmMatcher.inc"
409*5f613dfdSUlrich Weigand 
410*5f613dfdSUlrich Weigand void SystemZOperand::print(raw_ostream &OS) const {
411*5f613dfdSUlrich Weigand   llvm_unreachable("Not implemented");
412*5f613dfdSUlrich Weigand }
413*5f613dfdSUlrich Weigand 
414*5f613dfdSUlrich Weigand // Parse one register of the form %<prefix><number>.
415*5f613dfdSUlrich Weigand bool SystemZAsmParser::parseRegister(Register &Reg) {
416*5f613dfdSUlrich Weigand   Reg.StartLoc = Parser.getTok().getLoc();
417*5f613dfdSUlrich Weigand 
418*5f613dfdSUlrich Weigand   // Eat the % prefix.
419*5f613dfdSUlrich Weigand   if (Parser.getTok().isNot(AsmToken::Percent))
420*5f613dfdSUlrich Weigand     return true;
421*5f613dfdSUlrich Weigand   Parser.Lex();
422*5f613dfdSUlrich Weigand 
423*5f613dfdSUlrich Weigand   // Expect a register name.
424*5f613dfdSUlrich Weigand   if (Parser.getTok().isNot(AsmToken::Identifier))
425*5f613dfdSUlrich Weigand     return true;
426*5f613dfdSUlrich Weigand 
427*5f613dfdSUlrich Weigand   // Check the prefix.
428*5f613dfdSUlrich Weigand   StringRef Name = Parser.getTok().getString();
429*5f613dfdSUlrich Weigand   if (Name.size() < 2)
430*5f613dfdSUlrich Weigand     return true;
431*5f613dfdSUlrich Weigand   Reg.Prefix = Name[0];
432*5f613dfdSUlrich Weigand 
433*5f613dfdSUlrich Weigand   // Treat the rest of the register name as a register number.
434*5f613dfdSUlrich Weigand   if (Name.substr(1).getAsInteger(10, Reg.Number))
435*5f613dfdSUlrich Weigand     return true;
436*5f613dfdSUlrich Weigand 
437*5f613dfdSUlrich Weigand   Reg.EndLoc = Parser.getTok().getLoc();
438*5f613dfdSUlrich Weigand   Parser.Lex();
439*5f613dfdSUlrich Weigand   return false;
440*5f613dfdSUlrich Weigand }
441*5f613dfdSUlrich Weigand 
442*5f613dfdSUlrich Weigand // Parse a register with prefix Prefix and convert it to LLVM numbering.
443*5f613dfdSUlrich Weigand // Regs maps asm register numbers to LLVM register numbers, with zero
444*5f613dfdSUlrich Weigand // entries indicating an invalid register.  IsAddress says whether the
445*5f613dfdSUlrich Weigand // register appears in an address context.
446*5f613dfdSUlrich Weigand SystemZAsmParser::OperandMatchResultTy
447*5f613dfdSUlrich Weigand SystemZAsmParser::parseRegister(Register &Reg, char Prefix,
448*5f613dfdSUlrich Weigand                                 const unsigned *Regs, bool IsAddress) {
449*5f613dfdSUlrich Weigand   if (parseRegister(Reg))
450*5f613dfdSUlrich Weigand     return MatchOperand_NoMatch;
451*5f613dfdSUlrich Weigand   if (Reg.Prefix != Prefix || Reg.Number > 15 || Regs[Reg.Number] == 0) {
452*5f613dfdSUlrich Weigand     Error(Reg.StartLoc, "invalid register");
453*5f613dfdSUlrich Weigand     return MatchOperand_ParseFail;
454*5f613dfdSUlrich Weigand   }
455*5f613dfdSUlrich Weigand   if (Reg.Number == 0 && IsAddress) {
456*5f613dfdSUlrich Weigand     Error(Reg.StartLoc, "%r0 used in an address");
457*5f613dfdSUlrich Weigand     return MatchOperand_ParseFail;
458*5f613dfdSUlrich Weigand   }
459*5f613dfdSUlrich Weigand   Reg.Number = Regs[Reg.Number];
460*5f613dfdSUlrich Weigand   return MatchOperand_Success;
461*5f613dfdSUlrich Weigand }
462*5f613dfdSUlrich Weigand 
463*5f613dfdSUlrich Weigand // Parse a register and add it to Operands.  Prefix is 'r' for GPRs,
464*5f613dfdSUlrich Weigand // 'f' for FPRs, etc.  Regs maps asm register numbers to LLVM register numbers,
465*5f613dfdSUlrich Weigand // with zero entries indicating an invalid register.  Kind is the type of
466*5f613dfdSUlrich Weigand // register represented by Regs and IsAddress says whether the register is
467*5f613dfdSUlrich Weigand // being parsed in an address context, meaning that %r0 evaluates as 0.
468*5f613dfdSUlrich Weigand SystemZAsmParser::OperandMatchResultTy
469*5f613dfdSUlrich Weigand SystemZAsmParser::parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
470*5f613dfdSUlrich Weigand                                 char Prefix, const unsigned *Regs,
471*5f613dfdSUlrich Weigand                                 SystemZOperand::RegisterKind Kind,
472*5f613dfdSUlrich Weigand                                 bool IsAddress) {
473*5f613dfdSUlrich Weigand   Register Reg;
474*5f613dfdSUlrich Weigand   OperandMatchResultTy Result = parseRegister(Reg, Prefix, Regs, IsAddress);
475*5f613dfdSUlrich Weigand   if (Result == MatchOperand_Success)
476*5f613dfdSUlrich Weigand     Operands.push_back(SystemZOperand::createReg(Kind, Reg.Number,
477*5f613dfdSUlrich Weigand                                                  Reg.StartLoc, Reg.EndLoc));
478*5f613dfdSUlrich Weigand   return Result;
479*5f613dfdSUlrich Weigand }
480*5f613dfdSUlrich Weigand 
481*5f613dfdSUlrich Weigand // Parse a memory operand and add it to Operands.  Regs maps asm register
482*5f613dfdSUlrich Weigand // numbers to LLVM address registers and RegKind says what kind of address
483*5f613dfdSUlrich Weigand // register we're using (ADDR32Reg or ADDR64Reg).  HasIndex says whether
484*5f613dfdSUlrich Weigand // the address allows index registers.
485*5f613dfdSUlrich Weigand SystemZAsmParser::OperandMatchResultTy
486*5f613dfdSUlrich Weigand SystemZAsmParser::parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
487*5f613dfdSUlrich Weigand                                const unsigned *Regs,
488*5f613dfdSUlrich Weigand                                SystemZOperand::RegisterKind RegKind,
489*5f613dfdSUlrich Weigand                                bool HasIndex) {
490*5f613dfdSUlrich Weigand   SMLoc StartLoc = Parser.getTok().getLoc();
491*5f613dfdSUlrich Weigand 
492*5f613dfdSUlrich Weigand   // Parse the displacement, which must always be present.
493*5f613dfdSUlrich Weigand   const MCExpr *Disp;
494*5f613dfdSUlrich Weigand   if (getParser().parseExpression(Disp))
495*5f613dfdSUlrich Weigand     return MatchOperand_NoMatch;
496*5f613dfdSUlrich Weigand 
497*5f613dfdSUlrich Weigand   // Parse the optional base and index.
498*5f613dfdSUlrich Weigand   unsigned Index = 0;
499*5f613dfdSUlrich Weigand   unsigned Base = 0;
500*5f613dfdSUlrich Weigand   if (getLexer().is(AsmToken::LParen)) {
501*5f613dfdSUlrich Weigand     Parser.Lex();
502*5f613dfdSUlrich Weigand 
503*5f613dfdSUlrich Weigand     // Parse the first register.
504*5f613dfdSUlrich Weigand     Register Reg;
505*5f613dfdSUlrich Weigand     OperandMatchResultTy Result = parseRegister(Reg, 'r', GR64Regs, true);
506*5f613dfdSUlrich Weigand     if (Result != MatchOperand_Success)
507*5f613dfdSUlrich Weigand       return Result;
508*5f613dfdSUlrich Weigand 
509*5f613dfdSUlrich Weigand     // Check whether there's a second register.  If so, the one that we
510*5f613dfdSUlrich Weigand     // just parsed was the index.
511*5f613dfdSUlrich Weigand     if (getLexer().is(AsmToken::Comma)) {
512*5f613dfdSUlrich Weigand       Parser.Lex();
513*5f613dfdSUlrich Weigand 
514*5f613dfdSUlrich Weigand       if (!HasIndex) {
515*5f613dfdSUlrich Weigand         Error(Reg.StartLoc, "invalid use of indexed addressing");
516*5f613dfdSUlrich Weigand         return MatchOperand_ParseFail;
517*5f613dfdSUlrich Weigand       }
518*5f613dfdSUlrich Weigand 
519*5f613dfdSUlrich Weigand       Index = Reg.Number;
520*5f613dfdSUlrich Weigand       Result = parseRegister(Reg, 'r', GR64Regs, true);
521*5f613dfdSUlrich Weigand       if (Result != MatchOperand_Success)
522*5f613dfdSUlrich Weigand         return Result;
523*5f613dfdSUlrich Weigand     }
524*5f613dfdSUlrich Weigand     Base = Reg.Number;
525*5f613dfdSUlrich Weigand 
526*5f613dfdSUlrich Weigand     // Consume the closing bracket.
527*5f613dfdSUlrich Weigand     if (getLexer().isNot(AsmToken::RParen))
528*5f613dfdSUlrich Weigand       return MatchOperand_NoMatch;
529*5f613dfdSUlrich Weigand     Parser.Lex();
530*5f613dfdSUlrich Weigand   }
531*5f613dfdSUlrich Weigand 
532*5f613dfdSUlrich Weigand   SMLoc EndLoc =
533*5f613dfdSUlrich Weigand     SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
534*5f613dfdSUlrich Weigand   Operands.push_back(SystemZOperand::createMem(RegKind, Base, Disp, Index,
535*5f613dfdSUlrich Weigand                                                StartLoc, EndLoc));
536*5f613dfdSUlrich Weigand   return MatchOperand_Success;
537*5f613dfdSUlrich Weigand }
538*5f613dfdSUlrich Weigand 
539*5f613dfdSUlrich Weigand bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
540*5f613dfdSUlrich Weigand   return true;
541*5f613dfdSUlrich Weigand }
542*5f613dfdSUlrich Weigand 
543*5f613dfdSUlrich Weigand bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
544*5f613dfdSUlrich Weigand                                      SMLoc &EndLoc) {
545*5f613dfdSUlrich Weigand   Register Reg;
546*5f613dfdSUlrich Weigand   if (parseRegister(Reg))
547*5f613dfdSUlrich Weigand     return Error(Reg.StartLoc, "register expected");
548*5f613dfdSUlrich Weigand   if (Reg.Prefix == 'r' && Reg.Number < 16)
549*5f613dfdSUlrich Weigand     RegNo = GR64Regs[Reg.Number];
550*5f613dfdSUlrich Weigand   else if (Reg.Prefix == 'f' && Reg.Number < 16)
551*5f613dfdSUlrich Weigand     RegNo = FP64Regs[Reg.Number];
552*5f613dfdSUlrich Weigand   else
553*5f613dfdSUlrich Weigand     return Error(Reg.StartLoc, "invalid register");
554*5f613dfdSUlrich Weigand   StartLoc = Reg.StartLoc;
555*5f613dfdSUlrich Weigand   EndLoc = Reg.EndLoc;
556*5f613dfdSUlrich Weigand   return false;
557*5f613dfdSUlrich Weigand }
558*5f613dfdSUlrich Weigand 
559*5f613dfdSUlrich Weigand bool SystemZAsmParser::
560*5f613dfdSUlrich Weigand ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
561*5f613dfdSUlrich Weigand                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
562*5f613dfdSUlrich Weigand   Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
563*5f613dfdSUlrich Weigand 
564*5f613dfdSUlrich Weigand   // Read the remaining operands.
565*5f613dfdSUlrich Weigand   if (getLexer().isNot(AsmToken::EndOfStatement)) {
566*5f613dfdSUlrich Weigand     // Read the first operand.
567*5f613dfdSUlrich Weigand     if (parseOperand(Operands, Name)) {
568*5f613dfdSUlrich Weigand       Parser.eatToEndOfStatement();
569*5f613dfdSUlrich Weigand       return true;
570*5f613dfdSUlrich Weigand     }
571*5f613dfdSUlrich Weigand 
572*5f613dfdSUlrich Weigand     // Read any subsequent operands.
573*5f613dfdSUlrich Weigand     while (getLexer().is(AsmToken::Comma)) {
574*5f613dfdSUlrich Weigand       Parser.Lex();
575*5f613dfdSUlrich Weigand       if (parseOperand(Operands, Name)) {
576*5f613dfdSUlrich Weigand         Parser.eatToEndOfStatement();
577*5f613dfdSUlrich Weigand         return true;
578*5f613dfdSUlrich Weigand       }
579*5f613dfdSUlrich Weigand     }
580*5f613dfdSUlrich Weigand     if (getLexer().isNot(AsmToken::EndOfStatement)) {
581*5f613dfdSUlrich Weigand       SMLoc Loc = getLexer().getLoc();
582*5f613dfdSUlrich Weigand       Parser.eatToEndOfStatement();
583*5f613dfdSUlrich Weigand       return Error(Loc, "unexpected token in argument list");
584*5f613dfdSUlrich Weigand     }
585*5f613dfdSUlrich Weigand   }
586*5f613dfdSUlrich Weigand 
587*5f613dfdSUlrich Weigand   // Consume the EndOfStatement.
588*5f613dfdSUlrich Weigand   Parser.Lex();
589*5f613dfdSUlrich Weigand   return false;
590*5f613dfdSUlrich Weigand }
591*5f613dfdSUlrich Weigand 
592*5f613dfdSUlrich Weigand bool SystemZAsmParser::
593*5f613dfdSUlrich Weigand parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
594*5f613dfdSUlrich Weigand              StringRef Mnemonic) {
595*5f613dfdSUlrich Weigand   // Check if the current operand has a custom associated parser, if so, try to
596*5f613dfdSUlrich Weigand   // custom parse the operand, or fallback to the general approach.
597*5f613dfdSUlrich Weigand   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
598*5f613dfdSUlrich Weigand   if (ResTy == MatchOperand_Success)
599*5f613dfdSUlrich Weigand     return false;
600*5f613dfdSUlrich Weigand 
601*5f613dfdSUlrich Weigand   // If there wasn't a custom match, try the generic matcher below. Otherwise,
602*5f613dfdSUlrich Weigand   // there was a match, but an error occurred, in which case, just return that
603*5f613dfdSUlrich Weigand   // the operand parsing failed.
604*5f613dfdSUlrich Weigand   if (ResTy == MatchOperand_ParseFail)
605*5f613dfdSUlrich Weigand     return true;
606*5f613dfdSUlrich Weigand 
607*5f613dfdSUlrich Weigand   // The only other type of operand is an immediate.
608*5f613dfdSUlrich Weigand   const MCExpr *Expr;
609*5f613dfdSUlrich Weigand   SMLoc StartLoc = Parser.getTok().getLoc();
610*5f613dfdSUlrich Weigand   if (getParser().parseExpression(Expr))
611*5f613dfdSUlrich Weigand     return true;
612*5f613dfdSUlrich Weigand 
613*5f613dfdSUlrich Weigand   SMLoc EndLoc =
614*5f613dfdSUlrich Weigand     SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
615*5f613dfdSUlrich Weigand   Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
616*5f613dfdSUlrich Weigand   return false;
617*5f613dfdSUlrich Weigand }
618*5f613dfdSUlrich Weigand 
619*5f613dfdSUlrich Weigand bool SystemZAsmParser::
620*5f613dfdSUlrich Weigand MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
621*5f613dfdSUlrich Weigand                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
622*5f613dfdSUlrich Weigand                         MCStreamer &Out, unsigned &ErrorInfo,
623*5f613dfdSUlrich Weigand                         bool MatchingInlineAsm) {
624*5f613dfdSUlrich Weigand   MCInst Inst;
625*5f613dfdSUlrich Weigand   unsigned MatchResult;
626*5f613dfdSUlrich Weigand 
627*5f613dfdSUlrich Weigand   MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
628*5f613dfdSUlrich Weigand                                      MatchingInlineAsm);
629*5f613dfdSUlrich Weigand   switch (MatchResult) {
630*5f613dfdSUlrich Weigand   default: break;
631*5f613dfdSUlrich Weigand   case Match_Success:
632*5f613dfdSUlrich Weigand     Inst.setLoc(IDLoc);
633*5f613dfdSUlrich Weigand     Out.EmitInstruction(Inst);
634*5f613dfdSUlrich Weigand     return false;
635*5f613dfdSUlrich Weigand 
636*5f613dfdSUlrich Weigand   case Match_MissingFeature: {
637*5f613dfdSUlrich Weigand     assert(ErrorInfo && "Unknown missing feature!");
638*5f613dfdSUlrich Weigand     // Special case the error message for the very common case where only
639*5f613dfdSUlrich Weigand     // a single subtarget feature is missing
640*5f613dfdSUlrich Weigand     std::string Msg = "instruction requires:";
641*5f613dfdSUlrich Weigand     unsigned Mask = 1;
642*5f613dfdSUlrich Weigand     for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
643*5f613dfdSUlrich Weigand       if (ErrorInfo & Mask) {
644*5f613dfdSUlrich Weigand         Msg += " ";
645*5f613dfdSUlrich Weigand         Msg += getSubtargetFeatureName(ErrorInfo & Mask);
646*5f613dfdSUlrich Weigand       }
647*5f613dfdSUlrich Weigand       Mask <<= 1;
648*5f613dfdSUlrich Weigand     }
649*5f613dfdSUlrich Weigand     return Error(IDLoc, Msg);
650*5f613dfdSUlrich Weigand   }
651*5f613dfdSUlrich Weigand 
652*5f613dfdSUlrich Weigand   case Match_InvalidOperand: {
653*5f613dfdSUlrich Weigand     SMLoc ErrorLoc = IDLoc;
654*5f613dfdSUlrich Weigand     if (ErrorInfo != ~0U) {
655*5f613dfdSUlrich Weigand       if (ErrorInfo >= Operands.size())
656*5f613dfdSUlrich Weigand         return Error(IDLoc, "too few operands for instruction");
657*5f613dfdSUlrich Weigand 
658*5f613dfdSUlrich Weigand       ErrorLoc = ((SystemZOperand*)Operands[ErrorInfo])->getStartLoc();
659*5f613dfdSUlrich Weigand       if (ErrorLoc == SMLoc())
660*5f613dfdSUlrich Weigand         ErrorLoc = IDLoc;
661*5f613dfdSUlrich Weigand     }
662*5f613dfdSUlrich Weigand     return Error(ErrorLoc, "invalid operand for instruction");
663*5f613dfdSUlrich Weigand   }
664*5f613dfdSUlrich Weigand 
665*5f613dfdSUlrich Weigand   case Match_MnemonicFail:
666*5f613dfdSUlrich Weigand     return Error(IDLoc, "invalid instruction");
667*5f613dfdSUlrich Weigand   }
668*5f613dfdSUlrich Weigand 
669*5f613dfdSUlrich Weigand   llvm_unreachable("Unexpected match type");
670*5f613dfdSUlrich Weigand }
671*5f613dfdSUlrich Weigand 
672*5f613dfdSUlrich Weigand SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
673*5f613dfdSUlrich Weigand parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
674*5f613dfdSUlrich Weigand   Register Reg;
675*5f613dfdSUlrich Weigand   if (parseRegister(Reg))
676*5f613dfdSUlrich Weigand     return MatchOperand_NoMatch;
677*5f613dfdSUlrich Weigand   if (Reg.Prefix != 'a' || Reg.Number > 15) {
678*5f613dfdSUlrich Weigand     Error(Reg.StartLoc, "invalid register");
679*5f613dfdSUlrich Weigand     return MatchOperand_ParseFail;
680*5f613dfdSUlrich Weigand   }
681*5f613dfdSUlrich Weigand   Operands.push_back(SystemZOperand::createAccessReg(Reg.Number,
682*5f613dfdSUlrich Weigand                                                      Reg.StartLoc, Reg.EndLoc));
683*5f613dfdSUlrich Weigand   return MatchOperand_Success;
684*5f613dfdSUlrich Weigand }
685*5f613dfdSUlrich Weigand 
686*5f613dfdSUlrich Weigand // Force static initialization.
687*5f613dfdSUlrich Weigand extern "C" void LLVMInitializeSystemZAsmParser() {
688*5f613dfdSUlrich Weigand   RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
689*5f613dfdSUlrich Weigand }
690