blob: 012b82f20e8b017488cb27ac85c0d291e0a861bf [file] [log] [blame]
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001//===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/SystemZMCTargetDesc.h"
Craig Topper690d8ea2013-07-24 07:33:14 +000011#include "llvm/ADT/STLExtras.h"
Richard Sandiford1fb58832013-05-14 09:47:26 +000012#include "llvm/MC/MCContext.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000013#include "llvm/MC/MCExpr.h"
14#include "llvm/MC/MCInst.h"
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +000015#include "llvm/MC/MCInstBuilder.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000016#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000017#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000018#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSubtargetInfo.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000020#include "llvm/Support/TargetRegistry.h"
21
22using namespace llvm;
23
24// Return true if Expr is in the range [MinValue, MaxValue].
25static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
Richard Sandiford21f5d682014-03-06 11:22:58 +000026 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000027 int64_t Value = CE->getValue();
28 return Value >= MinValue && Value <= MaxValue;
29 }
30 return false;
31}
32
33namespace {
Richard Sandiford1d959002013-07-02 14:56:45 +000034enum RegisterKind {
35 GR32Reg,
Richard Sandifordf9496062013-09-30 10:45:16 +000036 GRH32Reg,
Richard Sandiford1d959002013-07-02 14:56:45 +000037 GR64Reg,
38 GR128Reg,
39 ADDR32Reg,
40 ADDR64Reg,
41 FP32Reg,
42 FP64Reg,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000043 FP128Reg,
44 VR32Reg,
45 VR64Reg,
46 VR128Reg
Richard Sandiford1d959002013-07-02 14:56:45 +000047};
48
49enum MemoryKind {
50 BDMem,
51 BDXMem,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000052 BDLMem,
53 BDVMem
Richard Sandiford1d959002013-07-02 14:56:45 +000054};
55
Ulrich Weigand5f613df2013-05-06 16:15:19 +000056class SystemZOperand : public MCParsedAsmOperand {
57public:
Ulrich Weigand5f613df2013-05-06 16:15:19 +000058private:
59 enum OperandKind {
Richard Sandiforddc5ed712013-05-24 14:26:46 +000060 KindInvalid,
Ulrich Weigand5f613df2013-05-06 16:15:19 +000061 KindToken,
62 KindReg,
63 KindAccessReg,
64 KindImm,
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000065 KindImmTLS,
Ulrich Weigand5f613df2013-05-06 16:15:19 +000066 KindMem
67 };
68
69 OperandKind Kind;
70 SMLoc StartLoc, EndLoc;
71
72 // A string of length Length, starting at Data.
73 struct TokenOp {
74 const char *Data;
75 unsigned Length;
76 };
77
Richard Sandiford675f8692013-05-24 14:14:38 +000078 // LLVM register Num, which has kind Kind. In some ways it might be
79 // easier for this class to have a register bank (general, floating-point
80 // or access) and a raw register number (0-15). This would postpone the
81 // interpretation of the operand to the add*() methods and avoid the need
82 // for context-dependent parsing. However, we do things the current way
83 // because of the virtual getReg() method, which needs to distinguish
84 // between (say) %r0 used as a single register and %r0 used as a pair.
85 // Context-dependent parsing can also give us slightly better error
86 // messages when invalid pairs like %r1 are used.
Ulrich Weigand5f613df2013-05-06 16:15:19 +000087 struct RegOp {
88 RegisterKind Kind;
89 unsigned Num;
90 };
91
92 // Base + Disp + Index, where Base and Index are LLVM registers or 0.
Ulrich Weigand1f698b02015-05-04 17:40:53 +000093 // MemKind says what type of memory this is and RegKind says what type
94 // the base register has (ADDR32Reg or ADDR64Reg). Length is the operand
95 // length for D(L,B)-style operands, otherwise it is null.
Ulrich Weigand5f613df2013-05-06 16:15:19 +000096 struct MemOp {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000097 unsigned Base : 12;
98 unsigned Index : 12;
99 unsigned MemKind : 4;
100 unsigned RegKind : 4;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000101 const MCExpr *Disp;
Richard Sandiford1d959002013-07-02 14:56:45 +0000102 const MCExpr *Length;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000103 };
104
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000105 // Imm is an immediate operand, and Sym is an optional TLS symbol
106 // for use with a __tls_get_offset marker relocation.
107 struct ImmTLSOp {
108 const MCExpr *Imm;
109 const MCExpr *Sym;
110 };
111
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000112 union {
113 TokenOp Token;
114 RegOp Reg;
115 unsigned AccessReg;
116 const MCExpr *Imm;
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000117 ImmTLSOp ImmTLS;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000118 MemOp Mem;
119 };
120
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000121 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
122 // Add as immediates when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000123 if (!Expr)
Jim Grosbache9119e42015-05-13 18:37:00 +0000124 Inst.addOperand(MCOperand::createImm(0));
Richard Sandiford21f5d682014-03-06 11:22:58 +0000125 else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000126 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000127 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000128 Inst.addOperand(MCOperand::createExpr(Expr));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000129 }
130
131public:
David Blaikie960ea3f2014-06-08 16:18:35 +0000132 SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
133 : Kind(kind), StartLoc(startLoc), EndLoc(endLoc) {}
134
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000135 // Create particular kinds of operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000136 static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,
137 SMLoc EndLoc) {
138 return make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000139 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000140 static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {
141 auto Op = make_unique<SystemZOperand>(KindToken, Loc, Loc);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000142 Op->Token.Data = Str.data();
143 Op->Token.Length = Str.size();
144 return Op;
145 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000146 static std::unique_ptr<SystemZOperand>
147 createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
148 auto Op = make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000149 Op->Reg.Kind = Kind;
150 Op->Reg.Num = Num;
151 return Op;
152 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000153 static std::unique_ptr<SystemZOperand>
154 createAccessReg(unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
155 auto Op = make_unique<SystemZOperand>(KindAccessReg, StartLoc, EndLoc);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000156 Op->AccessReg = Num;
157 return Op;
158 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000159 static std::unique_ptr<SystemZOperand>
160 createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
161 auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000162 Op->Imm = Expr;
163 return Op;
164 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000165 static std::unique_ptr<SystemZOperand>
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000166 createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,
167 const MCExpr *Disp, unsigned Index, const MCExpr *Length,
168 SMLoc StartLoc, SMLoc EndLoc) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000169 auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000170 Op->Mem.MemKind = MemKind;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000171 Op->Mem.RegKind = RegKind;
172 Op->Mem.Base = Base;
173 Op->Mem.Index = Index;
174 Op->Mem.Disp = Disp;
Richard Sandiford1d959002013-07-02 14:56:45 +0000175 Op->Mem.Length = Length;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000176 return Op;
177 }
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000178 static std::unique_ptr<SystemZOperand>
179 createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
180 SMLoc StartLoc, SMLoc EndLoc) {
181 auto Op = make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
182 Op->ImmTLS.Imm = Imm;
183 Op->ImmTLS.Sym = Sym;
184 return Op;
185 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000186
187 // Token operands
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000188 bool isToken() const override {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000189 return Kind == KindToken;
190 }
191 StringRef getToken() const {
192 assert(Kind == KindToken && "Not a token");
193 return StringRef(Token.Data, Token.Length);
194 }
195
196 // Register operands.
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000197 bool isReg() const override {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000198 return Kind == KindReg;
199 }
200 bool isReg(RegisterKind RegKind) const {
201 return Kind == KindReg && Reg.Kind == RegKind;
202 }
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000203 unsigned getReg() const override {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000204 assert(Kind == KindReg && "Not a register");
205 return Reg.Num;
206 }
207
208 // Access register operands. Access registers aren't exposed to LLVM
209 // as registers.
210 bool isAccessReg() const {
211 return Kind == KindAccessReg;
212 }
213
214 // Immediate operands.
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000215 bool isImm() const override {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000216 return Kind == KindImm;
217 }
218 bool isImm(int64_t MinValue, int64_t MaxValue) const {
219 return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
220 }
221 const MCExpr *getImm() const {
222 assert(Kind == KindImm && "Not an immediate");
223 return Imm;
224 }
225
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000226 // Immediate operands with optional TLS symbol.
227 bool isImmTLS() const {
228 return Kind == KindImmTLS;
229 }
230
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000231 // Memory operands.
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000232 bool isMem() const override {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000233 return Kind == KindMem;
234 }
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000235 bool isMem(MemoryKind MemKind) const {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000236 return (Kind == KindMem &&
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000237 (Mem.MemKind == MemKind ||
238 // A BDMem can be treated as a BDXMem in which the index
239 // register field is 0.
240 (Mem.MemKind == BDMem && MemKind == BDXMem)));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000241 }
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000242 bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {
243 return isMem(MemKind) && Mem.RegKind == RegKind;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000244 }
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000245 bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {
246 return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff);
247 }
248 bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
249 return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287);
Richard Sandiford1d959002013-07-02 14:56:45 +0000250 }
251 bool isMemDisp12Len8(RegisterKind RegKind) const {
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000252 return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length, 1, 0x100);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000253 }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000254 void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
255 assert(N == 3 && "Invalid number of operands");
256 assert(isMem(BDVMem) && "Invalid operand type");
Jim Grosbache9119e42015-05-13 18:37:00 +0000257 Inst.addOperand(MCOperand::createReg(Mem.Base));
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000258 addExpr(Inst, Mem.Disp);
Jim Grosbache9119e42015-05-13 18:37:00 +0000259 Inst.addOperand(MCOperand::createReg(Mem.Index));
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000260 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000261
262 // Override MCParsedAsmOperand.
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000263 SMLoc getStartLoc() const override { return StartLoc; }
Peter Collingbournecc723cc2016-10-09 04:39:13 +0000264 SMLoc getEndLoc() const { return EndLoc; }
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000265 void print(raw_ostream &OS) const override;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000266
267 // Used by the TableGen code to add particular types of operand
268 // to an instruction.
269 void addRegOperands(MCInst &Inst, unsigned N) const {
270 assert(N == 1 && "Invalid number of operands");
Jim Grosbache9119e42015-05-13 18:37:00 +0000271 Inst.addOperand(MCOperand::createReg(getReg()));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000272 }
273 void addAccessRegOperands(MCInst &Inst, unsigned N) const {
274 assert(N == 1 && "Invalid number of operands");
275 assert(Kind == KindAccessReg && "Invalid operand type");
Jim Grosbache9119e42015-05-13 18:37:00 +0000276 Inst.addOperand(MCOperand::createImm(AccessReg));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000277 }
278 void addImmOperands(MCInst &Inst, unsigned N) const {
279 assert(N == 1 && "Invalid number of operands");
280 addExpr(Inst, getImm());
281 }
282 void addBDAddrOperands(MCInst &Inst, unsigned N) const {
283 assert(N == 2 && "Invalid number of operands");
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000284 assert(isMem(BDMem) && "Invalid operand type");
Jim Grosbache9119e42015-05-13 18:37:00 +0000285 Inst.addOperand(MCOperand::createReg(Mem.Base));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000286 addExpr(Inst, Mem.Disp);
287 }
288 void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
289 assert(N == 3 && "Invalid number of operands");
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000290 assert(isMem(BDXMem) && "Invalid operand type");
Jim Grosbache9119e42015-05-13 18:37:00 +0000291 Inst.addOperand(MCOperand::createReg(Mem.Base));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000292 addExpr(Inst, Mem.Disp);
Jim Grosbache9119e42015-05-13 18:37:00 +0000293 Inst.addOperand(MCOperand::createReg(Mem.Index));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000294 }
Richard Sandiford1d959002013-07-02 14:56:45 +0000295 void addBDLAddrOperands(MCInst &Inst, unsigned N) const {
296 assert(N == 3 && "Invalid number of operands");
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000297 assert(isMem(BDLMem) && "Invalid operand type");
Jim Grosbache9119e42015-05-13 18:37:00 +0000298 Inst.addOperand(MCOperand::createReg(Mem.Base));
Richard Sandiford1d959002013-07-02 14:56:45 +0000299 addExpr(Inst, Mem.Disp);
300 addExpr(Inst, Mem.Length);
301 }
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000302 void addImmTLSOperands(MCInst &Inst, unsigned N) const {
303 assert(N == 2 && "Invalid number of operands");
304 assert(Kind == KindImmTLS && "Invalid operand type");
305 addExpr(Inst, ImmTLS.Imm);
306 if (ImmTLS.Sym)
307 addExpr(Inst, ImmTLS.Sym);
308 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000309
310 // Used by the TableGen code to check for particular operand types.
311 bool isGR32() const { return isReg(GR32Reg); }
Richard Sandifordf9496062013-09-30 10:45:16 +0000312 bool isGRH32() const { return isReg(GRH32Reg); }
Richard Sandiford0755c932013-10-01 11:26:28 +0000313 bool isGRX32() const { return false; }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000314 bool isGR64() const { return isReg(GR64Reg); }
315 bool isGR128() const { return isReg(GR128Reg); }
316 bool isADDR32() const { return isReg(ADDR32Reg); }
317 bool isADDR64() const { return isReg(ADDR64Reg); }
318 bool isADDR128() const { return false; }
319 bool isFP32() const { return isReg(FP32Reg); }
320 bool isFP64() const { return isReg(FP64Reg); }
321 bool isFP128() const { return isReg(FP128Reg); }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000322 bool isVR32() const { return isReg(VR32Reg); }
323 bool isVR64() const { return isReg(VR64Reg); }
324 bool isVF128() const { return false; }
325 bool isVR128() const { return isReg(VR128Reg); }
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000326 bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000327 bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); }
328 bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); }
329 bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); }
330 bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, ADDR64Reg); }
331 bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); }
332 bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); }
Richard Sandiford1d959002013-07-02 14:56:45 +0000333 bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000334 bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); }
335 bool isU1Imm() const { return isImm(0, 1); }
336 bool isU2Imm() const { return isImm(0, 3); }
337 bool isU3Imm() const { return isImm(0, 7); }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000338 bool isU4Imm() const { return isImm(0, 15); }
339 bool isU6Imm() const { return isImm(0, 63); }
340 bool isU8Imm() const { return isImm(0, 255); }
341 bool isS8Imm() const { return isImm(-128, 127); }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000342 bool isU12Imm() const { return isImm(0, 4095); }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000343 bool isU16Imm() const { return isImm(0, 65535); }
344 bool isS16Imm() const { return isImm(-32768, 32767); }
345 bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
346 bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000347 bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000348};
349
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000350class SystemZAsmParser : public MCTargetAsmParser {
351#define GET_ASSEMBLER_HEADER
352#include "SystemZGenAsmMatcher.inc"
353
354private:
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000355 MCAsmParser &Parser;
Richard Sandiford675f8692013-05-24 14:14:38 +0000356 enum RegisterGroup {
357 RegGR,
358 RegFP,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000359 RegV,
Richard Sandiford675f8692013-05-24 14:14:38 +0000360 RegAccess
361 };
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000362 struct Register {
Richard Sandiford675f8692013-05-24 14:14:38 +0000363 RegisterGroup Group;
364 unsigned Num;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000365 SMLoc StartLoc, EndLoc;
366 };
367
368 bool parseRegister(Register &Reg);
369
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000370 bool parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
371 bool IsAddress = false);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000372
David Blaikie960ea3f2014-06-08 16:18:35 +0000373 OperandMatchResultTy parseRegister(OperandVector &Operands,
374 RegisterGroup Group, const unsigned *Regs,
375 RegisterKind Kind);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000376
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000377 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
378
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000379 bool parseAddress(unsigned &Base, const MCExpr *&Disp,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000380 unsigned &Index, bool &IsVector, const MCExpr *&Length,
Richard Sandiford1d959002013-07-02 14:56:45 +0000381 const unsigned *Regs, RegisterKind RegKind);
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000382
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000383 bool ParseDirectiveInsn(SMLoc L);
384
David Blaikie960ea3f2014-06-08 16:18:35 +0000385 OperandMatchResultTy parseAddress(OperandVector &Operands,
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000386 MemoryKind MemKind, const unsigned *Regs,
387 RegisterKind RegKind);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000388
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000389 OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
390 int64_t MaxVal, bool AllowTLS);
391
David Blaikie960ea3f2014-06-08 16:18:35 +0000392 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000393
394public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000395 SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000396 const MCInstrInfo &MII,
397 const MCTargetOptions &Options)
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000398 : MCTargetAsmParser(Options, sti), Parser(parser) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000399 MCAsmParserExtension::Initialize(Parser);
400
Zhan Jun Liau7d4d4362016-07-08 16:50:02 +0000401 // Alias the .word directive to .short.
402 parser.addAliasForDirective(".word", ".short");
403
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000404 // Initialize the set of available features.
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000405 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000406 }
407
408 // Override MCTargetAsmParser.
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000409 bool ParseDirective(AsmToken DirectiveID) override;
410 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
David Blaikie960ea3f2014-06-08 16:18:35 +0000411 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
412 SMLoc NameLoc, OperandVector &Operands) override;
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000413 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +0000414 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000415 uint64_t &ErrorInfo,
Richard Sandifordb4d67b52014-03-06 12:03:36 +0000416 bool MatchingInlineAsm) override;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000417
418 // Used by the TableGen code to parse particular operand types.
David Blaikie960ea3f2014-06-08 16:18:35 +0000419 OperandMatchResultTy parseGR32(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000420 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, GR32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000421 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000422 OperandMatchResultTy parseGRH32(OperandVector &Operands) {
Richard Sandifordf9496062013-09-30 10:45:16 +0000423 return parseRegister(Operands, RegGR, SystemZMC::GRH32Regs, GRH32Reg);
424 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000425 OperandMatchResultTy parseGRX32(OperandVector &Operands) {
Richard Sandiford0755c932013-10-01 11:26:28 +0000426 llvm_unreachable("GRX32 should only be used for pseudo instructions");
427 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000428 OperandMatchResultTy parseGR64(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000429 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, GR64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000430 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000431 OperandMatchResultTy parseGR128(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000432 return parseRegister(Operands, RegGR, SystemZMC::GR128Regs, GR128Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000433 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000434 OperandMatchResultTy parseADDR32(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000435 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs, ADDR32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000436 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000437 OperandMatchResultTy parseADDR64(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000438 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs, ADDR64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000439 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000440 OperandMatchResultTy parseADDR128(OperandVector &Operands) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000441 llvm_unreachable("Shouldn't be used as an operand");
442 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000443 OperandMatchResultTy parseFP32(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000444 return parseRegister(Operands, RegFP, SystemZMC::FP32Regs, FP32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000445 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000446 OperandMatchResultTy parseFP64(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000447 return parseRegister(Operands, RegFP, SystemZMC::FP64Regs, FP64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000448 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000449 OperandMatchResultTy parseFP128(OperandVector &Operands) {
Richard Sandiford1d959002013-07-02 14:56:45 +0000450 return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000451 }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000452 OperandMatchResultTy parseVR32(OperandVector &Operands) {
453 return parseRegister(Operands, RegV, SystemZMC::VR32Regs, VR32Reg);
454 }
455 OperandMatchResultTy parseVR64(OperandVector &Operands) {
456 return parseRegister(Operands, RegV, SystemZMC::VR64Regs, VR64Reg);
457 }
458 OperandMatchResultTy parseVF128(OperandVector &Operands) {
459 llvm_unreachable("Shouldn't be used as an operand");
460 }
461 OperandMatchResultTy parseVR128(OperandVector &Operands) {
462 return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg);
463 }
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000464 OperandMatchResultTy parseAnyReg(OperandVector &Operands) {
465 return parseAnyRegister(Operands);
466 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000467 OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000468 return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000469 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000470 OperandMatchResultTy parseBDAddr64(OperandVector &Operands) {
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000471 return parseAddress(Operands, BDMem, SystemZMC::GR64Regs, ADDR64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000472 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000473 OperandMatchResultTy parseBDXAddr64(OperandVector &Operands) {
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000474 return parseAddress(Operands, BDXMem, SystemZMC::GR64Regs, ADDR64Reg);
Richard Sandiford1d959002013-07-02 14:56:45 +0000475 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000476 OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000477 return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000478 }
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000479 OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
480 return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
481 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000482 OperandMatchResultTy parseAccessReg(OperandVector &Operands);
David Blaikie960ea3f2014-06-08 16:18:35 +0000483 OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000484 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000485 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000486 OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000487 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
488 }
489 OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
490 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
491 }
492 OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
493 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000494 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000495};
Richard Sandifordc2312692014-03-06 10:38:30 +0000496} // end anonymous namespace
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000497
498#define GET_REGISTER_MATCHER
499#define GET_SUBTARGET_FEATURE_NAME
500#define GET_MATCHER_IMPLEMENTATION
501#include "SystemZGenAsmMatcher.inc"
502
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000503// Used for the .insn directives; contains information needed to parse the
504// operands in the directive.
505struct InsnMatchEntry {
506 StringRef Format;
507 uint64_t Opcode;
508 int32_t NumOperands;
509 MatchClassKind OperandKinds[5];
510};
511
512// For equal_range comparison.
513struct CompareInsn {
514 bool operator() (const InsnMatchEntry &LHS, StringRef RHS) {
515 return LHS.Format < RHS;
516 }
517 bool operator() (StringRef LHS, const InsnMatchEntry &RHS) {
518 return LHS < RHS.Format;
519 }
Roger Ferrer Ibanez17586582016-08-10 16:39:58 +0000520 bool operator() (const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {
521 return LHS.Format < RHS.Format;
522 }
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000523};
524
525// Table initializing information for parsing the .insn directive.
526static struct InsnMatchEntry InsnMatchTable[] = {
527 /* Format, Opcode, NumOperands, OperandKinds */
528 { "e", SystemZ::InsnE, 1,
529 { MCK_U16Imm } },
530 { "ri", SystemZ::InsnRI, 3,
531 { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },
532 { "rie", SystemZ::InsnRIE, 4,
533 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
534 { "ril", SystemZ::InsnRIL, 3,
535 { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },
536 { "rilu", SystemZ::InsnRILU, 3,
537 { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
538 { "ris", SystemZ::InsnRIS, 5,
539 { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
540 { "rr", SystemZ::InsnRR, 3,
541 { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
542 { "rre", SystemZ::InsnRRE, 3,
543 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },
544 { "rrf", SystemZ::InsnRRF, 5,
545 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
546 { "rrs", SystemZ::InsnRRS, 5,
547 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
548 { "rs", SystemZ::InsnRS, 4,
549 { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
550 { "rse", SystemZ::InsnRSE, 4,
551 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
552 { "rsi", SystemZ::InsnRSI, 4,
553 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
554 { "rsy", SystemZ::InsnRSY, 4,
555 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
556 { "rx", SystemZ::InsnRX, 3,
557 { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
558 { "rxe", SystemZ::InsnRXE, 3,
559 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
560 { "rxf", SystemZ::InsnRXF, 4,
561 { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
562 { "rxy", SystemZ::InsnRXY, 3,
563 { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
564 { "s", SystemZ::InsnS, 2,
565 { MCK_U32Imm, MCK_BDAddr64Disp12 } },
566 { "si", SystemZ::InsnSI, 3,
567 { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
568 { "sil", SystemZ::InsnSIL, 3,
569 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
570 { "siy", SystemZ::InsnSIY, 3,
571 { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
572 { "ss", SystemZ::InsnSS, 4,
573 { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
574 { "sse", SystemZ::InsnSSE, 3,
575 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
576 { "ssf", SystemZ::InsnSSF, 4,
577 { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } }
578};
579
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000580void SystemZOperand::print(raw_ostream &OS) const {
581 llvm_unreachable("Not implemented");
582}
583
584// Parse one register of the form %<prefix><number>.
585bool SystemZAsmParser::parseRegister(Register &Reg) {
586 Reg.StartLoc = Parser.getTok().getLoc();
587
588 // Eat the % prefix.
589 if (Parser.getTok().isNot(AsmToken::Percent))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000590 return Error(Parser.getTok().getLoc(), "register expected");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000591 Parser.Lex();
592
593 // Expect a register name.
594 if (Parser.getTok().isNot(AsmToken::Identifier))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000595 return Error(Reg.StartLoc, "invalid register");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000596
Richard Sandiford675f8692013-05-24 14:14:38 +0000597 // Check that there's a prefix.
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000598 StringRef Name = Parser.getTok().getString();
599 if (Name.size() < 2)
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000600 return Error(Reg.StartLoc, "invalid register");
Richard Sandiford675f8692013-05-24 14:14:38 +0000601 char Prefix = Name[0];
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000602
603 // Treat the rest of the register name as a register number.
Richard Sandiford675f8692013-05-24 14:14:38 +0000604 if (Name.substr(1).getAsInteger(10, Reg.Num))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000605 return Error(Reg.StartLoc, "invalid register");
Richard Sandiford675f8692013-05-24 14:14:38 +0000606
607 // Look for valid combinations of prefix and number.
608 if (Prefix == 'r' && Reg.Num < 16)
609 Reg.Group = RegGR;
610 else if (Prefix == 'f' && Reg.Num < 16)
611 Reg.Group = RegFP;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000612 else if (Prefix == 'v' && Reg.Num < 32)
613 Reg.Group = RegV;
Richard Sandiford675f8692013-05-24 14:14:38 +0000614 else if (Prefix == 'a' && Reg.Num < 16)
615 Reg.Group = RegAccess;
616 else
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000617 return Error(Reg.StartLoc, "invalid register");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000618
619 Reg.EndLoc = Parser.getTok().getLoc();
620 Parser.Lex();
621 return false;
622}
623
Richard Sandiford675f8692013-05-24 14:14:38 +0000624// Parse a register of group Group. If Regs is nonnull, use it to map
Jonas Paulsson0a9049b2015-10-09 07:19:12 +0000625// the raw register number to LLVM numbering, with zero entries
626// indicating an invalid register. IsAddress says whether the
627// register appears in an address context. Allow FP Group if expecting
628// RegV Group, since the f-prefix yields the FP group even while used
629// with vector instructions.
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000630bool SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
631 const unsigned *Regs, bool IsAddress) {
632 if (parseRegister(Reg))
633 return true;
Jonas Paulsson0a9049b2015-10-09 07:19:12 +0000634 if (Reg.Group != Group && !(Reg.Group == RegFP && Group == RegV))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000635 return Error(Reg.StartLoc, "invalid operand for instruction");
636 if (Regs && Regs[Reg.Num] == 0)
637 return Error(Reg.StartLoc, "invalid register pair");
638 if (Reg.Num == 0 && IsAddress)
639 return Error(Reg.StartLoc, "%r0 used in an address");
Richard Sandiford675f8692013-05-24 14:14:38 +0000640 if (Regs)
641 Reg.Num = Regs[Reg.Num];
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000642 return false;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000643}
644
Richard Sandiford675f8692013-05-24 14:14:38 +0000645// Parse a register and add it to Operands. The other arguments are as above.
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000646SystemZAsmParser::OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000647SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
648 const unsigned *Regs, RegisterKind Kind) {
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000649 if (Parser.getTok().isNot(AsmToken::Percent))
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000650 return MatchOperand_NoMatch;
651
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000652 Register Reg;
Richard Sandiford1d959002013-07-02 14:56:45 +0000653 bool IsAddress = (Kind == ADDR32Reg || Kind == ADDR64Reg);
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000654 if (parseRegister(Reg, Group, Regs, IsAddress))
655 return MatchOperand_ParseFail;
656
657 Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
658 Reg.StartLoc, Reg.EndLoc));
659 return MatchOperand_Success;
660}
661
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000662// Parse any type of register (including integers) and add it to Operands.
663SystemZAsmParser::OperandMatchResultTy
664SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
665 // Handle integer values.
666 if (Parser.getTok().is(AsmToken::Integer)) {
667 const MCExpr *Register;
668 SMLoc StartLoc = Parser.getTok().getLoc();
669 if (Parser.parseExpression(Register))
670 return MatchOperand_ParseFail;
671
672 if (auto *CE = dyn_cast<MCConstantExpr>(Register)) {
673 int64_t Value = CE->getValue();
674 if (Value < 0 || Value > 15) {
675 Error(StartLoc, "invalid register");
676 return MatchOperand_ParseFail;
677 }
678 }
679
680 SMLoc EndLoc =
681 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
682
683 Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));
684 }
685 else {
686 Register Reg;
687 if (parseRegister(Reg))
688 return MatchOperand_ParseFail;
689
690 // Map to the correct register kind.
691 RegisterKind Kind;
692 unsigned RegNo;
693 if (Reg.Group == RegGR) {
694 Kind = GR64Reg;
695 RegNo = SystemZMC::GR64Regs[Reg.Num];
696 }
697 else if (Reg.Group == RegFP) {
698 Kind = FP64Reg;
699 RegNo = SystemZMC::FP64Regs[Reg.Num];
700 }
701 else if (Reg.Group == RegV) {
702 Kind = VR128Reg;
703 RegNo = SystemZMC::VR128Regs[Reg.Num];
704 }
705 else {
706 return MatchOperand_ParseFail;
707 }
708
709 Operands.push_back(SystemZOperand::createReg(Kind, RegNo,
710 Reg.StartLoc, Reg.EndLoc));
711 }
712 return MatchOperand_Success;
713}
714
Richard Sandiford1d959002013-07-02 14:56:45 +0000715// Parse a memory operand into Base, Disp, Index and Length.
716// Regs maps asm register numbers to LLVM register numbers and RegKind
717// says what kind of address register we're using (ADDR32Reg or ADDR64Reg).
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000718bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000719 unsigned &Index, bool &IsVector,
720 const MCExpr *&Length, const unsigned *Regs,
Richard Sandiford1d959002013-07-02 14:56:45 +0000721 RegisterKind RegKind) {
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000722 // Parse the displacement, which must always be present.
723 if (getParser().parseExpression(Disp))
724 return true;
725
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000726 // Parse the optional base and index.
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000727 Index = 0;
728 Base = 0;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000729 IsVector = false;
Craig Topper062a2ba2014-04-25 05:30:21 +0000730 Length = nullptr;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000731 if (getLexer().is(AsmToken::LParen)) {
732 Parser.Lex();
733
Richard Sandiford1d959002013-07-02 14:56:45 +0000734 if (getLexer().is(AsmToken::Percent)) {
735 // Parse the first register and decide whether it's a base or an index.
736 Register Reg;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000737 if (parseRegister(Reg))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000738 return true;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000739 if (Reg.Group == RegV) {
740 // A vector index register. The base register is optional.
741 IsVector = true;
742 Index = SystemZMC::VR128Regs[Reg.Num];
743 } else if (Reg.Group == RegGR) {
744 if (Reg.Num == 0)
745 return Error(Reg.StartLoc, "%r0 used in an address");
746 // If the are two registers, the first one is the index and the
747 // second is the base.
748 if (getLexer().is(AsmToken::Comma))
749 Index = Regs[Reg.Num];
750 else
751 Base = Regs[Reg.Num];
752 } else
753 return Error(Reg.StartLoc, "invalid address register");
Richard Sandiford1d959002013-07-02 14:56:45 +0000754 } else {
755 // Parse the length.
756 if (getParser().parseExpression(Length))
757 return true;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000758 }
Richard Sandiford1d959002013-07-02 14:56:45 +0000759
760 // Check whether there's a second register. It's the base if so.
761 if (getLexer().is(AsmToken::Comma)) {
762 Parser.Lex();
763 Register Reg;
764 if (parseRegister(Reg, RegGR, Regs, RegKind))
765 return true;
766 Base = Reg.Num;
767 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000768
769 // Consume the closing bracket.
770 if (getLexer().isNot(AsmToken::RParen))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000771 return Error(Parser.getTok().getLoc(), "unexpected token in address");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000772 Parser.Lex();
773 }
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000774 return false;
775}
776
777// Parse a memory operand and add it to Operands. The other arguments
778// are as above.
779SystemZAsmParser::OperandMatchResultTy
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000780SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
781 const unsigned *Regs, RegisterKind RegKind) {
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000782 SMLoc StartLoc = Parser.getTok().getLoc();
783 unsigned Base, Index;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000784 bool IsVector;
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000785 const MCExpr *Disp;
Richard Sandiford1d959002013-07-02 14:56:45 +0000786 const MCExpr *Length;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000787 if (parseAddress(Base, Disp, Index, IsVector, Length, Regs, RegKind))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000788 return MatchOperand_ParseFail;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000789
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000790 if (IsVector && MemKind != BDVMem) {
791 Error(StartLoc, "invalid use of vector addressing");
792 return MatchOperand_ParseFail;
793 }
Richard Sandiford1d959002013-07-02 14:56:45 +0000794
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000795 if (!IsVector && MemKind == BDVMem) {
796 Error(StartLoc, "vector index required in address");
797 return MatchOperand_ParseFail;
798 }
Richard Sandiford1d959002013-07-02 14:56:45 +0000799
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000800 if (Index && MemKind != BDXMem && MemKind != BDVMem) {
801 Error(StartLoc, "invalid use of indexed addressing");
802 return MatchOperand_ParseFail;
803 }
804
805 if (Length && MemKind != BDLMem) {
806 Error(StartLoc, "invalid use of length addressing");
807 return MatchOperand_ParseFail;
808 }
809
810 if (!Length && MemKind == BDLMem) {
811 Error(StartLoc, "missing length in address");
812 return MatchOperand_ParseFail;
813 }
Richard Sandiford1d959002013-07-02 14:56:45 +0000814
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000815 SMLoc EndLoc =
816 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Ulrich Weigand1f698b02015-05-04 17:40:53 +0000817 Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
818 Index, Length, StartLoc,
819 EndLoc));
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000820 return MatchOperand_Success;
821}
822
823bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000824 StringRef IDVal = DirectiveID.getIdentifier();
825
826 if (IDVal == ".insn")
827 return ParseDirectiveInsn(DirectiveID.getLoc());
828
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000829 return true;
830}
831
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000832/// ParseDirectiveInsn
833/// ::= .insn [ format, encoding, (operands (, operands)*) ]
834bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) {
835 MCAsmParser &Parser = getParser();
836
837 // Expect instruction format as identifier.
838 StringRef Format;
839 SMLoc ErrorLoc = Parser.getTok().getLoc();
840 if (Parser.parseIdentifier(Format))
841 return Error(ErrorLoc, "expected instruction format");
842
843 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
844
845 // Find entry for this format in InsnMatchTable.
846 auto EntryRange =
847 std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),
848 Format, CompareInsn());
849
850 // If first == second, couldn't find a match in the table.
851 if (EntryRange.first == EntryRange.second)
852 return Error(ErrorLoc, "unrecognized format");
853
854 struct InsnMatchEntry *Entry = EntryRange.first;
855
856 // Format should match from equal_range.
857 assert(Entry->Format == Format);
858
859 // Parse the following operands using the table's information.
860 for (int i = 0; i < Entry->NumOperands; i++) {
861 MatchClassKind Kind = Entry->OperandKinds[i];
862
863 SMLoc StartLoc = Parser.getTok().getLoc();
864
865 // Always expect commas as separators for operands.
866 if (getLexer().isNot(AsmToken::Comma))
867 return Error(StartLoc, "unexpected token in directive");
868 Lex();
869
870 // Parse operands.
871 OperandMatchResultTy ResTy;
872 if (Kind == MCK_AnyReg)
873 ResTy = parseAnyReg(Operands);
874 else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
875 ResTy = parseBDXAddr64(Operands);
876 else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
877 ResTy = parseBDAddr64(Operands);
878 else if (Kind == MCK_PCRel32)
879 ResTy = parsePCRel32(Operands);
880 else if (Kind == MCK_PCRel16)
881 ResTy = parsePCRel16(Operands);
882 else {
883 // Only remaining operand kind is an immediate.
884 const MCExpr *Expr;
885 SMLoc StartLoc = Parser.getTok().getLoc();
886
887 // Expect immediate expression.
888 if (Parser.parseExpression(Expr))
889 return Error(StartLoc, "unexpected token in directive");
890
891 SMLoc EndLoc =
892 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
893
894 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
895 ResTy = MatchOperand_Success;
896 }
897
898 if (ResTy != MatchOperand_Success)
899 return true;
900 }
901
902 // Build the instruction with the parsed operands.
903 MCInst Inst = MCInstBuilder(Entry->Opcode);
904
905 for (size_t i = 0; i < Operands.size(); i++) {
906 MCParsedAsmOperand &Operand = *Operands[i];
907 MatchClassKind Kind = Entry->OperandKinds[i];
908
909 // Verify operand.
910 unsigned Res = validateOperandClass(Operand, Kind);
911 if (Res != Match_Success)
912 return Error(Operand.getStartLoc(), "unexpected operand type");
913
914 // Add operands to instruction.
915 SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);
916 if (ZOperand.isReg())
917 ZOperand.addRegOperands(Inst, 1);
918 else if (ZOperand.isMem(BDMem))
919 ZOperand.addBDAddrOperands(Inst, 2);
920 else if (ZOperand.isMem(BDXMem))
921 ZOperand.addBDXAddrOperands(Inst, 3);
922 else if (ZOperand.isImm())
923 ZOperand.addImmOperands(Inst, 1);
924 else
925 llvm_unreachable("unexpected operand type");
926 }
927
928 // Emit as a regular instruction.
929 Parser.getStreamer().EmitInstruction(Inst, getSTI());
930
931 return false;
932}
933
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000934bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
935 SMLoc &EndLoc) {
936 Register Reg;
937 if (parseRegister(Reg))
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000938 return true;
Richard Sandiford675f8692013-05-24 14:14:38 +0000939 if (Reg.Group == RegGR)
940 RegNo = SystemZMC::GR64Regs[Reg.Num];
941 else if (Reg.Group == RegFP)
942 RegNo = SystemZMC::FP64Regs[Reg.Num];
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000943 else if (Reg.Group == RegV)
944 RegNo = SystemZMC::VR128Regs[Reg.Num];
Richard Sandiford675f8692013-05-24 14:14:38 +0000945 else
946 // FIXME: Access registers aren't modelled as LLVM registers yet.
947 return Error(Reg.StartLoc, "invalid operand for instruction");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000948 StartLoc = Reg.StartLoc;
949 EndLoc = Reg.EndLoc;
950 return false;
951}
952
David Blaikie960ea3f2014-06-08 16:18:35 +0000953bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
954 StringRef Name, SMLoc NameLoc,
955 OperandVector &Operands) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000956 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
957
958 // Read the remaining operands.
959 if (getLexer().isNot(AsmToken::EndOfStatement)) {
960 // Read the first operand.
961 if (parseOperand(Operands, Name)) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000962 return true;
963 }
964
965 // Read any subsequent operands.
966 while (getLexer().is(AsmToken::Comma)) {
967 Parser.Lex();
968 if (parseOperand(Operands, Name)) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000969 return true;
970 }
971 }
972 if (getLexer().isNot(AsmToken::EndOfStatement)) {
973 SMLoc Loc = getLexer().getLoc();
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000974 return Error(Loc, "unexpected token in argument list");
975 }
976 }
977
978 // Consume the EndOfStatement.
979 Parser.Lex();
980 return false;
981}
982
David Blaikie960ea3f2014-06-08 16:18:35 +0000983bool SystemZAsmParser::parseOperand(OperandVector &Operands,
984 StringRef Mnemonic) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000985 // Check if the current operand has a custom associated parser, if so, try to
986 // custom parse the operand, or fallback to the general approach.
987 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
988 if (ResTy == MatchOperand_Success)
989 return false;
990
991 // If there wasn't a custom match, try the generic matcher below. Otherwise,
992 // there was a match, but an error occurred, in which case, just return that
993 // the operand parsing failed.
994 if (ResTy == MatchOperand_ParseFail)
995 return true;
996
Richard Sandiforddc5ed712013-05-24 14:26:46 +0000997 // Check for a register. All real register operands should have used
998 // a context-dependent parse routine, which gives the required register
999 // class. The code is here to mop up other cases, like those where
1000 // the instruction isn't recognized.
1001 if (Parser.getTok().is(AsmToken::Percent)) {
1002 Register Reg;
1003 if (parseRegister(Reg))
1004 return true;
1005 Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));
1006 return false;
1007 }
1008
1009 // The only other type of operand is an immediate or address. As above,
1010 // real address operands should have used a context-dependent parse routine,
1011 // so we treat any plain expression as an immediate.
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001012 SMLoc StartLoc = Parser.getTok().getLoc();
Richard Sandiforddc5ed712013-05-24 14:26:46 +00001013 unsigned Base, Index;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +00001014 bool IsVector;
Richard Sandiford1d959002013-07-02 14:56:45 +00001015 const MCExpr *Expr, *Length;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +00001016 if (parseAddress(Base, Expr, Index, IsVector, Length, SystemZMC::GR64Regs,
1017 ADDR64Reg))
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001018 return true;
1019
1020 SMLoc EndLoc =
1021 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Richard Sandiford1d959002013-07-02 14:56:45 +00001022 if (Base || Index || Length)
Richard Sandiforddc5ed712013-05-24 14:26:46 +00001023 Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
1024 else
1025 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001026 return false;
1027}
1028
David Blaikie960ea3f2014-06-08 16:18:35 +00001029bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1030 OperandVector &Operands,
1031 MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +00001032 uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +00001033 bool MatchingInlineAsm) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001034 MCInst Inst;
1035 unsigned MatchResult;
1036
1037 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001038 MatchingInlineAsm);
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001039 switch (MatchResult) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001040 case Match_Success:
1041 Inst.setLoc(IDLoc);
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001042 Out.EmitInstruction(Inst, getSTI());
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001043 return false;
1044
1045 case Match_MissingFeature: {
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001046 assert(ErrorInfo && "Unknown missing feature!");
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001047 // Special case the error message for the very common case where only
1048 // a single subtarget feature is missing
1049 std::string Msg = "instruction requires:";
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001050 uint64_t Mask = 1;
1051 for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
1052 if (ErrorInfo & Mask) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001053 Msg += " ";
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001054 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001055 }
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001056 Mask <<= 1;
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001057 }
1058 return Error(IDLoc, Msg);
1059 }
1060
1061 case Match_InvalidOperand: {
1062 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +00001063 if (ErrorInfo != ~0ULL) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001064 if (ErrorInfo >= Operands.size())
1065 return Error(IDLoc, "too few operands for instruction");
1066
David Blaikie960ea3f2014-06-08 16:18:35 +00001067 ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001068 if (ErrorLoc == SMLoc())
1069 ErrorLoc = IDLoc;
1070 }
1071 return Error(ErrorLoc, "invalid operand for instruction");
1072 }
1073
1074 case Match_MnemonicFail:
1075 return Error(IDLoc, "invalid instruction");
1076 }
1077
1078 llvm_unreachable("Unexpected match type");
1079}
1080
David Blaikie960ea3f2014-06-08 16:18:35 +00001081SystemZAsmParser::OperandMatchResultTy
1082SystemZAsmParser::parseAccessReg(OperandVector &Operands) {
Richard Sandiforddc5ed712013-05-24 14:26:46 +00001083 if (Parser.getTok().isNot(AsmToken::Percent))
1084 return MatchOperand_NoMatch;
1085
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001086 Register Reg;
Craig Topper062a2ba2014-04-25 05:30:21 +00001087 if (parseRegister(Reg, RegAccess, nullptr))
Richard Sandiforddc5ed712013-05-24 14:26:46 +00001088 return MatchOperand_ParseFail;
1089
1090 Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
1091 Reg.StartLoc,
1092 Reg.EndLoc));
1093 return MatchOperand_Success;
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001094}
1095
David Blaikie960ea3f2014-06-08 16:18:35 +00001096SystemZAsmParser::OperandMatchResultTy
1097SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +00001098 int64_t MaxVal, bool AllowTLS) {
Richard Sandiford1fb58832013-05-14 09:47:26 +00001099 MCContext &Ctx = getContext();
1100 MCStreamer &Out = getStreamer();
1101 const MCExpr *Expr;
1102 SMLoc StartLoc = Parser.getTok().getLoc();
1103 if (getParser().parseExpression(Expr))
1104 return MatchOperand_NoMatch;
1105
1106 // For consistency with the GNU assembler, treat immediates as offsets
1107 // from ".".
Richard Sandiford21f5d682014-03-06 11:22:58 +00001108 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
Richard Sandiford1fb58832013-05-14 09:47:26 +00001109 int64_t Value = CE->getValue();
1110 if ((Value & 1) || Value < MinVal || Value > MaxVal) {
1111 Error(StartLoc, "offset out of range");
1112 return MatchOperand_ParseFail;
1113 }
Jim Grosbach6f482002015-05-18 18:43:14 +00001114 MCSymbol *Sym = Ctx.createTempSymbol();
Richard Sandiford1fb58832013-05-14 09:47:26 +00001115 Out.EmitLabel(Sym);
Jim Grosbach13760bd2015-05-30 01:25:56 +00001116 const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
Richard Sandiford1fb58832013-05-14 09:47:26 +00001117 Ctx);
Jim Grosbach13760bd2015-05-30 01:25:56 +00001118 Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);
Richard Sandiford1fb58832013-05-14 09:47:26 +00001119 }
1120
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +00001121 // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
1122 const MCExpr *Sym = nullptr;
1123 if (AllowTLS && getLexer().is(AsmToken::Colon)) {
1124 Parser.Lex();
1125
1126 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1127 Error(Parser.getTok().getLoc(), "unexpected token");
1128 return MatchOperand_ParseFail;
1129 }
1130
1131 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
1132 StringRef Name = Parser.getTok().getString();
1133 if (Name == "tls_gdcall")
1134 Kind = MCSymbolRefExpr::VK_TLSGD;
1135 else if (Name == "tls_ldcall")
1136 Kind = MCSymbolRefExpr::VK_TLSLDM;
1137 else {
1138 Error(Parser.getTok().getLoc(), "unknown TLS tag");
1139 return MatchOperand_ParseFail;
1140 }
1141 Parser.Lex();
1142
1143 if (Parser.getTok().isNot(AsmToken::Colon)) {
1144 Error(Parser.getTok().getLoc(), "unexpected token");
1145 return MatchOperand_ParseFail;
1146 }
1147 Parser.Lex();
1148
1149 if (Parser.getTok().isNot(AsmToken::Identifier)) {
1150 Error(Parser.getTok().getLoc(), "unexpected token");
1151 return MatchOperand_ParseFail;
1152 }
1153
1154 StringRef Identifier = Parser.getTok().getString();
Jim Grosbach13760bd2015-05-30 01:25:56 +00001155 Sym = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(Identifier),
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +00001156 Kind, Ctx);
1157 Parser.Lex();
1158 }
1159
Richard Sandiford1fb58832013-05-14 09:47:26 +00001160 SMLoc EndLoc =
1161 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +00001162
1163 if (AllowTLS)
1164 Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
1165 StartLoc, EndLoc));
1166 else
1167 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
1168
Richard Sandiford1fb58832013-05-14 09:47:26 +00001169 return MatchOperand_Success;
1170}
1171
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001172// Force static initialization.
1173extern "C" void LLVMInitializeSystemZAsmParser() {
1174 RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
1175}