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