blob: 600834e74494a2cb0d6ebc6b56e817bc2d12bb85 [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"
Richard Sandiford1fb58832013-05-14 09:47:26 +000011#include "llvm/MC/MCContext.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000012#include "llvm/MC/MCExpr.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
15#include "llvm/MC/MCStreamer.h"
16#include "llvm/MC/MCSubtargetInfo.h"
17#include "llvm/MC/MCTargetAsmParser.h"
18#include "llvm/Support/TargetRegistry.h"
19
20using namespace llvm;
21
22// Return true if Expr is in the range [MinValue, MaxValue].
23static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
24 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
25 int64_t Value = CE->getValue();
26 return Value >= MinValue && Value <= MaxValue;
27 }
28 return false;
29}
30
31namespace {
32class SystemZOperand : public MCParsedAsmOperand {
33public:
34 enum RegisterKind {
35 GR32Reg,
36 GR64Reg,
37 GR128Reg,
38 ADDR32Reg,
39 ADDR64Reg,
40 FP32Reg,
41 FP64Reg,
42 FP128Reg
43 };
44
45private:
46 enum OperandKind {
47 KindToken,
48 KindReg,
49 KindAccessReg,
50 KindImm,
51 KindMem
52 };
53
54 OperandKind Kind;
55 SMLoc StartLoc, EndLoc;
56
57 // A string of length Length, starting at Data.
58 struct TokenOp {
59 const char *Data;
60 unsigned Length;
61 };
62
Richard Sandiford675f8692013-05-24 14:14:38 +000063 // LLVM register Num, which has kind Kind. In some ways it might be
64 // easier for this class to have a register bank (general, floating-point
65 // or access) and a raw register number (0-15). This would postpone the
66 // interpretation of the operand to the add*() methods and avoid the need
67 // for context-dependent parsing. However, we do things the current way
68 // because of the virtual getReg() method, which needs to distinguish
69 // between (say) %r0 used as a single register and %r0 used as a pair.
70 // Context-dependent parsing can also give us slightly better error
71 // messages when invalid pairs like %r1 are used.
Ulrich Weigand5f613df2013-05-06 16:15:19 +000072 struct RegOp {
73 RegisterKind Kind;
74 unsigned Num;
75 };
76
77 // Base + Disp + Index, where Base and Index are LLVM registers or 0.
78 // RegKind says what type the registers have (ADDR32Reg or ADDR64Reg).
79 struct MemOp {
80 unsigned Base : 8;
81 unsigned Index : 8;
82 unsigned RegKind : 8;
83 unsigned Unused : 8;
84 const MCExpr *Disp;
85 };
86
87 union {
88 TokenOp Token;
89 RegOp Reg;
90 unsigned AccessReg;
91 const MCExpr *Imm;
92 MemOp Mem;
93 };
94
95 SystemZOperand(OperandKind kind, SMLoc startLoc, SMLoc endLoc)
96 : Kind(kind), StartLoc(startLoc), EndLoc(endLoc)
97 {}
98
99 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
100 // Add as immediates when possible. Null MCExpr = 0.
101 if (Expr == 0)
102 Inst.addOperand(MCOperand::CreateImm(0));
103 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
104 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
105 else
106 Inst.addOperand(MCOperand::CreateExpr(Expr));
107 }
108
109public:
110 // Create particular kinds of operand.
111 static SystemZOperand *createToken(StringRef Str, SMLoc Loc) {
112 SystemZOperand *Op = new SystemZOperand(KindToken, Loc, Loc);
113 Op->Token.Data = Str.data();
114 Op->Token.Length = Str.size();
115 return Op;
116 }
117 static SystemZOperand *createReg(RegisterKind Kind, unsigned Num,
118 SMLoc StartLoc, SMLoc EndLoc) {
119 SystemZOperand *Op = new SystemZOperand(KindReg, StartLoc, EndLoc);
120 Op->Reg.Kind = Kind;
121 Op->Reg.Num = Num;
122 return Op;
123 }
124 static SystemZOperand *createAccessReg(unsigned Num, SMLoc StartLoc,
125 SMLoc EndLoc) {
126 SystemZOperand *Op = new SystemZOperand(KindAccessReg, StartLoc, EndLoc);
127 Op->AccessReg = Num;
128 return Op;
129 }
130 static SystemZOperand *createImm(const MCExpr *Expr, SMLoc StartLoc,
131 SMLoc EndLoc) {
132 SystemZOperand *Op = new SystemZOperand(KindImm, StartLoc, EndLoc);
133 Op->Imm = Expr;
134 return Op;
135 }
136 static SystemZOperand *createMem(RegisterKind RegKind, unsigned Base,
137 const MCExpr *Disp, unsigned Index,
138 SMLoc StartLoc, SMLoc EndLoc) {
139 SystemZOperand *Op = new SystemZOperand(KindMem, StartLoc, EndLoc);
140 Op->Mem.RegKind = RegKind;
141 Op->Mem.Base = Base;
142 Op->Mem.Index = Index;
143 Op->Mem.Disp = Disp;
144 return Op;
145 }
146
147 // Token operands
148 virtual bool isToken() const LLVM_OVERRIDE {
149 return Kind == KindToken;
150 }
151 StringRef getToken() const {
152 assert(Kind == KindToken && "Not a token");
153 return StringRef(Token.Data, Token.Length);
154 }
155
156 // Register operands.
157 virtual bool isReg() const LLVM_OVERRIDE {
158 return Kind == KindReg;
159 }
160 bool isReg(RegisterKind RegKind) const {
161 return Kind == KindReg && Reg.Kind == RegKind;
162 }
163 virtual unsigned getReg() const LLVM_OVERRIDE {
164 assert(Kind == KindReg && "Not a register");
165 return Reg.Num;
166 }
167
168 // Access register operands. Access registers aren't exposed to LLVM
169 // as registers.
170 bool isAccessReg() const {
171 return Kind == KindAccessReg;
172 }
173
174 // Immediate operands.
175 virtual bool isImm() const LLVM_OVERRIDE {
176 return Kind == KindImm;
177 }
178 bool isImm(int64_t MinValue, int64_t MaxValue) const {
179 return Kind == KindImm && inRange(Imm, MinValue, MaxValue);
180 }
181 const MCExpr *getImm() const {
182 assert(Kind == KindImm && "Not an immediate");
183 return Imm;
184 }
185
186 // Memory operands.
187 virtual bool isMem() const LLVM_OVERRIDE {
188 return Kind == KindMem;
189 }
190 bool isMem(RegisterKind RegKind, bool HasIndex) const {
191 return (Kind == KindMem &&
192 Mem.RegKind == RegKind &&
193 (HasIndex || !Mem.Index));
194 }
195 bool isMemDisp12(RegisterKind RegKind, bool HasIndex) const {
196 return isMem(RegKind, HasIndex) && inRange(Mem.Disp, 0, 0xfff);
197 }
198 bool isMemDisp20(RegisterKind RegKind, bool HasIndex) const {
199 return isMem(RegKind, HasIndex) && inRange(Mem.Disp, -524288, 524287);
200 }
201
202 // Override MCParsedAsmOperand.
203 virtual SMLoc getStartLoc() const LLVM_OVERRIDE { return StartLoc; }
204 virtual SMLoc getEndLoc() const LLVM_OVERRIDE { return EndLoc; }
205 virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
206
207 // Used by the TableGen code to add particular types of operand
208 // to an instruction.
209 void addRegOperands(MCInst &Inst, unsigned N) const {
210 assert(N == 1 && "Invalid number of operands");
211 Inst.addOperand(MCOperand::CreateReg(getReg()));
212 }
213 void addAccessRegOperands(MCInst &Inst, unsigned N) const {
214 assert(N == 1 && "Invalid number of operands");
215 assert(Kind == KindAccessReg && "Invalid operand type");
216 Inst.addOperand(MCOperand::CreateImm(AccessReg));
217 }
218 void addImmOperands(MCInst &Inst, unsigned N) const {
219 assert(N == 1 && "Invalid number of operands");
220 addExpr(Inst, getImm());
221 }
222 void addBDAddrOperands(MCInst &Inst, unsigned N) const {
223 assert(N == 2 && "Invalid number of operands");
224 assert(Kind == KindMem && Mem.Index == 0 && "Invalid operand type");
225 Inst.addOperand(MCOperand::CreateReg(Mem.Base));
226 addExpr(Inst, Mem.Disp);
227 }
228 void addBDXAddrOperands(MCInst &Inst, unsigned N) const {
229 assert(N == 3 && "Invalid number of operands");
230 assert(Kind == KindMem && "Invalid operand type");
231 Inst.addOperand(MCOperand::CreateReg(Mem.Base));
232 addExpr(Inst, Mem.Disp);
233 Inst.addOperand(MCOperand::CreateReg(Mem.Index));
234 }
235
236 // Used by the TableGen code to check for particular operand types.
237 bool isGR32() const { return isReg(GR32Reg); }
238 bool isGR64() const { return isReg(GR64Reg); }
239 bool isGR128() const { return isReg(GR128Reg); }
240 bool isADDR32() const { return isReg(ADDR32Reg); }
241 bool isADDR64() const { return isReg(ADDR64Reg); }
242 bool isADDR128() const { return false; }
243 bool isFP32() const { return isReg(FP32Reg); }
244 bool isFP64() const { return isReg(FP64Reg); }
245 bool isFP128() const { return isReg(FP128Reg); }
246 bool isBDAddr32Disp12() const { return isMemDisp12(ADDR32Reg, false); }
247 bool isBDAddr32Disp20() const { return isMemDisp20(ADDR32Reg, false); }
248 bool isBDAddr64Disp12() const { return isMemDisp12(ADDR64Reg, false); }
249 bool isBDAddr64Disp20() const { return isMemDisp20(ADDR64Reg, false); }
250 bool isBDXAddr64Disp12() const { return isMemDisp12(ADDR64Reg, true); }
251 bool isBDXAddr64Disp20() const { return isMemDisp20(ADDR64Reg, true); }
252 bool isU4Imm() const { return isImm(0, 15); }
253 bool isU6Imm() const { return isImm(0, 63); }
254 bool isU8Imm() const { return isImm(0, 255); }
255 bool isS8Imm() const { return isImm(-128, 127); }
256 bool isU16Imm() const { return isImm(0, 65535); }
257 bool isS16Imm() const { return isImm(-32768, 32767); }
258 bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
259 bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }
260};
261
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000262class SystemZAsmParser : public MCTargetAsmParser {
263#define GET_ASSEMBLER_HEADER
264#include "SystemZGenAsmMatcher.inc"
265
266private:
267 MCSubtargetInfo &STI;
268 MCAsmParser &Parser;
Richard Sandiford675f8692013-05-24 14:14:38 +0000269 enum RegisterGroup {
270 RegGR,
271 RegFP,
272 RegAccess
273 };
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000274 struct Register {
Richard Sandiford675f8692013-05-24 14:14:38 +0000275 RegisterGroup Group;
276 unsigned Num;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000277 SMLoc StartLoc, EndLoc;
278 };
279
280 bool parseRegister(Register &Reg);
281
282 OperandMatchResultTy
Richard Sandiford675f8692013-05-24 14:14:38 +0000283 parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000284 bool IsAddress = false);
285
286 OperandMatchResultTy
287 parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Richard Sandiford675f8692013-05-24 14:14:38 +0000288 RegisterGroup Group, const unsigned *Regs,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000289 SystemZOperand::RegisterKind Kind,
290 bool IsAddress = false);
291
292 OperandMatchResultTy
293 parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
294 const unsigned *Regs, SystemZOperand::RegisterKind RegKind,
295 bool HasIndex);
296
297 bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
298 StringRef Mnemonic);
299
300public:
301 SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
302 : MCTargetAsmParser(), STI(sti), Parser(parser) {
303 MCAsmParserExtension::Initialize(Parser);
304
305 // Initialize the set of available features.
306 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
307 }
308
309 // Override MCTargetAsmParser.
310 virtual bool ParseDirective(AsmToken DirectiveID) LLVM_OVERRIDE;
311 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
312 SMLoc &EndLoc) LLVM_OVERRIDE;
313 virtual bool ParseInstruction(ParseInstructionInfo &Info,
314 StringRef Name, SMLoc NameLoc,
315 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
316 LLVM_OVERRIDE;
317 virtual bool
318 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
319 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
320 MCStreamer &Out, unsigned &ErrorInfo,
321 bool MatchingInlineAsm) LLVM_OVERRIDE;
322
323 // Used by the TableGen code to parse particular operand types.
324 OperandMatchResultTy
325 parseGR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000326 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000327 SystemZOperand::GR32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000328 }
329 OperandMatchResultTy
330 parseGR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000331 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000332 SystemZOperand::GR64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000333 }
334 OperandMatchResultTy
335 parseGR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000336 return parseRegister(Operands, RegGR, SystemZMC::GR128Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000337 SystemZOperand::GR128Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000338 }
339 OperandMatchResultTy
340 parseADDR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000341 return parseRegister(Operands, RegGR, SystemZMC::GR32Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000342 SystemZOperand::ADDR32Reg, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000343 }
344 OperandMatchResultTy
345 parseADDR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000346 return parseRegister(Operands, RegGR, SystemZMC::GR64Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000347 SystemZOperand::ADDR64Reg, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000348 }
349 OperandMatchResultTy
350 parseADDR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
351 llvm_unreachable("Shouldn't be used as an operand");
352 }
353 OperandMatchResultTy
354 parseFP32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000355 return parseRegister(Operands, RegFP, SystemZMC::FP32Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000356 SystemZOperand::FP32Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000357 }
358 OperandMatchResultTy
359 parseFP64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000360 return parseRegister(Operands, RegFP, SystemZMC::FP64Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000361 SystemZOperand::FP64Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000362 }
363 OperandMatchResultTy
364 parseFP128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000365 return parseRegister(Operands, RegFP, SystemZMC::FP128Regs,
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000366 SystemZOperand::FP128Reg);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000367 }
368 OperandMatchResultTy
369 parseBDAddr32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000370 return parseAddress(Operands, SystemZMC::GR32Regs,
371 SystemZOperand::ADDR32Reg, false);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000372 }
373 OperandMatchResultTy
374 parseBDAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000375 return parseAddress(Operands, SystemZMC::GR64Regs,
376 SystemZOperand::ADDR64Reg, false);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000377 }
378 OperandMatchResultTy
379 parseBDXAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Richard Sandiford7d37cd22013-05-14 09:36:44 +0000380 return parseAddress(Operands, SystemZMC::GR64Regs,
381 SystemZOperand::ADDR64Reg, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000382 }
383 OperandMatchResultTy
384 parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000385 OperandMatchResultTy
386 parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
387 int64_t MinVal, int64_t MaxVal);
388 OperandMatchResultTy
389 parsePCRel16(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
390 return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1);
391 }
392 OperandMatchResultTy
393 parsePCRel32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
394 return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1);
395 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000396};
397}
398
399#define GET_REGISTER_MATCHER
400#define GET_SUBTARGET_FEATURE_NAME
401#define GET_MATCHER_IMPLEMENTATION
402#include "SystemZGenAsmMatcher.inc"
403
404void SystemZOperand::print(raw_ostream &OS) const {
405 llvm_unreachable("Not implemented");
406}
407
408// Parse one register of the form %<prefix><number>.
409bool SystemZAsmParser::parseRegister(Register &Reg) {
410 Reg.StartLoc = Parser.getTok().getLoc();
411
412 // Eat the % prefix.
413 if (Parser.getTok().isNot(AsmToken::Percent))
414 return true;
415 Parser.Lex();
416
417 // Expect a register name.
418 if (Parser.getTok().isNot(AsmToken::Identifier))
419 return true;
420
Richard Sandiford675f8692013-05-24 14:14:38 +0000421 // Check that there's a prefix.
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000422 StringRef Name = Parser.getTok().getString();
423 if (Name.size() < 2)
424 return true;
Richard Sandiford675f8692013-05-24 14:14:38 +0000425 char Prefix = Name[0];
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000426
427 // Treat the rest of the register name as a register number.
Richard Sandiford675f8692013-05-24 14:14:38 +0000428 if (Name.substr(1).getAsInteger(10, Reg.Num))
429 return true;
430
431 // Look for valid combinations of prefix and number.
432 if (Prefix == 'r' && Reg.Num < 16)
433 Reg.Group = RegGR;
434 else if (Prefix == 'f' && Reg.Num < 16)
435 Reg.Group = RegFP;
436 else if (Prefix == 'a' && Reg.Num < 16)
437 Reg.Group = RegAccess;
438 else
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000439 return true;
440
441 Reg.EndLoc = Parser.getTok().getLoc();
442 Parser.Lex();
443 return false;
444}
445
Richard Sandiford675f8692013-05-24 14:14:38 +0000446// Parse a register of group Group. If Regs is nonnull, use it to map
447// the raw register number to LLVM numbering, with zero entries indicating
448// an invalid register. IsAddress says whether the register appears in an
449// address context.
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000450SystemZAsmParser::OperandMatchResultTy
Richard Sandiford675f8692013-05-24 14:14:38 +0000451SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000452 const unsigned *Regs, bool IsAddress) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000453 if (Parser.getTok().isNot(AsmToken::Percent))
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000454 return MatchOperand_NoMatch;
Richard Sandiford675f8692013-05-24 14:14:38 +0000455 if (parseRegister(Reg)) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000456 Error(Reg.StartLoc, "invalid register");
457 return MatchOperand_ParseFail;
458 }
Richard Sandiford675f8692013-05-24 14:14:38 +0000459 if (Reg.Group != Group) {
460 Error(Reg.StartLoc, "invalid operand for instruction");
461 return MatchOperand_ParseFail;
462 }
463 if (Regs && Regs[Reg.Num] == 0) {
464 Error(Reg.StartLoc, "invalid register pair");
465 return MatchOperand_ParseFail;
466 }
467 if (Reg.Num == 0 && IsAddress) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000468 Error(Reg.StartLoc, "%r0 used in an address");
469 return MatchOperand_ParseFail;
470 }
Richard Sandiford675f8692013-05-24 14:14:38 +0000471 if (Regs)
472 Reg.Num = Regs[Reg.Num];
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000473 return MatchOperand_Success;
474}
475
Richard Sandiford675f8692013-05-24 14:14:38 +0000476// Parse a register and add it to Operands. The other arguments are as above.
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000477SystemZAsmParser::OperandMatchResultTy
478SystemZAsmParser::parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Richard Sandiford675f8692013-05-24 14:14:38 +0000479 RegisterGroup Group, const unsigned *Regs,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000480 SystemZOperand::RegisterKind Kind,
481 bool IsAddress) {
482 Register Reg;
Richard Sandiford675f8692013-05-24 14:14:38 +0000483 OperandMatchResultTy Result = parseRegister(Reg, Group, Regs, IsAddress);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000484 if (Result == MatchOperand_Success)
Richard Sandiford675f8692013-05-24 14:14:38 +0000485 Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000486 Reg.StartLoc, Reg.EndLoc));
487 return Result;
488}
489
490// Parse a memory operand and add it to Operands. Regs maps asm register
491// numbers to LLVM address registers and RegKind says what kind of address
492// register we're using (ADDR32Reg or ADDR64Reg). HasIndex says whether
493// the address allows index registers.
494SystemZAsmParser::OperandMatchResultTy
495SystemZAsmParser::parseAddress(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
496 const unsigned *Regs,
497 SystemZOperand::RegisterKind RegKind,
498 bool HasIndex) {
499 SMLoc StartLoc = Parser.getTok().getLoc();
500
501 // Parse the displacement, which must always be present.
502 const MCExpr *Disp;
503 if (getParser().parseExpression(Disp))
504 return MatchOperand_NoMatch;
505
506 // Parse the optional base and index.
507 unsigned Index = 0;
508 unsigned Base = 0;
509 if (getLexer().is(AsmToken::LParen)) {
510 Parser.Lex();
511
512 // Parse the first register.
513 Register Reg;
Richard Sandiford675f8692013-05-24 14:14:38 +0000514 OperandMatchResultTy Result = parseRegister(Reg, RegGR, Regs, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000515 if (Result != MatchOperand_Success)
516 return Result;
517
518 // Check whether there's a second register. If so, the one that we
519 // just parsed was the index.
520 if (getLexer().is(AsmToken::Comma)) {
521 Parser.Lex();
522
523 if (!HasIndex) {
524 Error(Reg.StartLoc, "invalid use of indexed addressing");
525 return MatchOperand_ParseFail;
526 }
527
Richard Sandiford675f8692013-05-24 14:14:38 +0000528 Index = Reg.Num;
529 Result = parseRegister(Reg, RegGR, Regs, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000530 if (Result != MatchOperand_Success)
531 return Result;
532 }
Richard Sandiford675f8692013-05-24 14:14:38 +0000533 Base = Reg.Num;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000534
535 // Consume the closing bracket.
536 if (getLexer().isNot(AsmToken::RParen))
537 return MatchOperand_NoMatch;
538 Parser.Lex();
539 }
540
541 SMLoc EndLoc =
542 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
543 Operands.push_back(SystemZOperand::createMem(RegKind, Base, Disp, Index,
544 StartLoc, EndLoc));
545 return MatchOperand_Success;
546}
547
548bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
549 return true;
550}
551
552bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
553 SMLoc &EndLoc) {
Richard Sandiford675f8692013-05-24 14:14:38 +0000554 if (Parser.getTok().isNot(AsmToken::Percent))
555 return Error(Parser.getTok().getLoc(), "register expected");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000556 Register Reg;
557 if (parseRegister(Reg))
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000558 return Error(Reg.StartLoc, "invalid register");
Richard Sandiford675f8692013-05-24 14:14:38 +0000559 if (Reg.Group == RegGR)
560 RegNo = SystemZMC::GR64Regs[Reg.Num];
561 else if (Reg.Group == RegFP)
562 RegNo = SystemZMC::FP64Regs[Reg.Num];
563 else
564 // FIXME: Access registers aren't modelled as LLVM registers yet.
565 return Error(Reg.StartLoc, "invalid operand for instruction");
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000566 StartLoc = Reg.StartLoc;
567 EndLoc = Reg.EndLoc;
568 return false;
569}
570
571bool SystemZAsmParser::
572ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
573 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
574 Operands.push_back(SystemZOperand::createToken(Name, NameLoc));
575
576 // Read the remaining operands.
577 if (getLexer().isNot(AsmToken::EndOfStatement)) {
578 // Read the first operand.
579 if (parseOperand(Operands, Name)) {
580 Parser.eatToEndOfStatement();
581 return true;
582 }
583
584 // Read any subsequent operands.
585 while (getLexer().is(AsmToken::Comma)) {
586 Parser.Lex();
587 if (parseOperand(Operands, Name)) {
588 Parser.eatToEndOfStatement();
589 return true;
590 }
591 }
592 if (getLexer().isNot(AsmToken::EndOfStatement)) {
593 SMLoc Loc = getLexer().getLoc();
594 Parser.eatToEndOfStatement();
595 return Error(Loc, "unexpected token in argument list");
596 }
597 }
598
599 // Consume the EndOfStatement.
600 Parser.Lex();
601 return false;
602}
603
604bool SystemZAsmParser::
605parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
606 StringRef Mnemonic) {
607 // Check if the current operand has a custom associated parser, if so, try to
608 // custom parse the operand, or fallback to the general approach.
609 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
610 if (ResTy == MatchOperand_Success)
611 return false;
612
613 // If there wasn't a custom match, try the generic matcher below. Otherwise,
614 // there was a match, but an error occurred, in which case, just return that
615 // the operand parsing failed.
616 if (ResTy == MatchOperand_ParseFail)
617 return true;
618
619 // The only other type of operand is an immediate.
620 const MCExpr *Expr;
621 SMLoc StartLoc = Parser.getTok().getLoc();
622 if (getParser().parseExpression(Expr))
623 return true;
624
625 SMLoc EndLoc =
626 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
627 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
628 return false;
629}
630
631bool SystemZAsmParser::
632MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
633 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
634 MCStreamer &Out, unsigned &ErrorInfo,
635 bool MatchingInlineAsm) {
636 MCInst Inst;
637 unsigned MatchResult;
638
639 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
640 MatchingInlineAsm);
641 switch (MatchResult) {
642 default: break;
643 case Match_Success:
644 Inst.setLoc(IDLoc);
645 Out.EmitInstruction(Inst);
646 return false;
647
648 case Match_MissingFeature: {
649 assert(ErrorInfo && "Unknown missing feature!");
650 // Special case the error message for the very common case where only
651 // a single subtarget feature is missing
652 std::string Msg = "instruction requires:";
653 unsigned Mask = 1;
654 for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
655 if (ErrorInfo & Mask) {
656 Msg += " ";
657 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
658 }
659 Mask <<= 1;
660 }
661 return Error(IDLoc, Msg);
662 }
663
664 case Match_InvalidOperand: {
665 SMLoc ErrorLoc = IDLoc;
666 if (ErrorInfo != ~0U) {
667 if (ErrorInfo >= Operands.size())
668 return Error(IDLoc, "too few operands for instruction");
669
670 ErrorLoc = ((SystemZOperand*)Operands[ErrorInfo])->getStartLoc();
671 if (ErrorLoc == SMLoc())
672 ErrorLoc = IDLoc;
673 }
674 return Error(ErrorLoc, "invalid operand for instruction");
675 }
676
677 case Match_MnemonicFail:
678 return Error(IDLoc, "invalid instruction");
679 }
680
681 llvm_unreachable("Unexpected match type");
682}
683
684SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
685parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
686 Register Reg;
Richard Sandiford675f8692013-05-24 14:14:38 +0000687 OperandMatchResultTy Result = parseRegister(Reg, RegAccess, 0);
688 if (Result == MatchOperand_Success)
689 Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
690 Reg.StartLoc,
691 Reg.EndLoc));
692 return Result;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000693}
694
Richard Sandiford1fb58832013-05-14 09:47:26 +0000695SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
696parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
697 int64_t MinVal, int64_t MaxVal) {
698 MCContext &Ctx = getContext();
699 MCStreamer &Out = getStreamer();
700 const MCExpr *Expr;
701 SMLoc StartLoc = Parser.getTok().getLoc();
702 if (getParser().parseExpression(Expr))
703 return MatchOperand_NoMatch;
704
705 // For consistency with the GNU assembler, treat immediates as offsets
706 // from ".".
707 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
708 int64_t Value = CE->getValue();
709 if ((Value & 1) || Value < MinVal || Value > MaxVal) {
710 Error(StartLoc, "offset out of range");
711 return MatchOperand_ParseFail;
712 }
713 MCSymbol *Sym = Ctx.CreateTempSymbol();
714 Out.EmitLabel(Sym);
715 const MCExpr *Base = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
716 Ctx);
717 Expr = Value == 0 ? Base : MCBinaryExpr::CreateAdd(Base, Expr, Ctx);
718 }
719
720 SMLoc EndLoc =
721 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
722 Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
723 return MatchOperand_Success;
724}
725
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000726// Force static initialization.
727extern "C" void LLVMInitializeSystemZAsmParser() {
728 RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
729}