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