xref: /llvm-project/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp (revision 675f86996afcf245f1dfae588c21ec8dd58f81b1)
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/MC/MCContext.h"
12 #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 
20 using namespace llvm;
21 
22 // Return true if Expr is in the range [MinValue, MaxValue].
23 static 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 
31 namespace {
32 class SystemZOperand : public MCParsedAsmOperand {
33 public:
34   enum RegisterKind {
35     GR32Reg,
36     GR64Reg,
37     GR128Reg,
38     ADDR32Reg,
39     ADDR64Reg,
40     FP32Reg,
41     FP64Reg,
42     FP128Reg
43   };
44 
45 private:
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 
63   // 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.
72   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 
109 public:
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 
262 class SystemZAsmParser : public MCTargetAsmParser {
263 #define GET_ASSEMBLER_HEADER
264 #include "SystemZGenAsmMatcher.inc"
265 
266 private:
267   MCSubtargetInfo &STI;
268   MCAsmParser &Parser;
269   enum RegisterGroup {
270     RegGR,
271     RegFP,
272     RegAccess
273   };
274   struct Register {
275     RegisterGroup Group;
276     unsigned Num;
277     SMLoc StartLoc, EndLoc;
278   };
279 
280   bool parseRegister(Register &Reg);
281 
282   OperandMatchResultTy
283   parseRegister(Register &Reg, RegisterGroup Group, const unsigned *Regs,
284                 bool IsAddress = false);
285 
286   OperandMatchResultTy
287   parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
288                 RegisterGroup Group, const unsigned *Regs,
289                 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 
300 public:
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) {
326     return parseRegister(Operands, RegGR, SystemZMC::GR32Regs,
327                          SystemZOperand::GR32Reg);
328   }
329   OperandMatchResultTy
330   parseGR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
331     return parseRegister(Operands, RegGR, SystemZMC::GR64Regs,
332                          SystemZOperand::GR64Reg);
333   }
334   OperandMatchResultTy
335   parseGR128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
336     return parseRegister(Operands, RegGR, SystemZMC::GR128Regs,
337                          SystemZOperand::GR128Reg);
338   }
339   OperandMatchResultTy
340   parseADDR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
341     return parseRegister(Operands, RegGR, SystemZMC::GR32Regs,
342                          SystemZOperand::ADDR32Reg, true);
343   }
344   OperandMatchResultTy
345   parseADDR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
346     return parseRegister(Operands, RegGR, SystemZMC::GR64Regs,
347                          SystemZOperand::ADDR64Reg, true);
348   }
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) {
355     return parseRegister(Operands, RegFP, SystemZMC::FP32Regs,
356                          SystemZOperand::FP32Reg);
357   }
358   OperandMatchResultTy
359   parseFP64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
360     return parseRegister(Operands, RegFP, SystemZMC::FP64Regs,
361                          SystemZOperand::FP64Reg);
362   }
363   OperandMatchResultTy
364   parseFP128(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
365     return parseRegister(Operands, RegFP, SystemZMC::FP128Regs,
366                          SystemZOperand::FP128Reg);
367   }
368   OperandMatchResultTy
369   parseBDAddr32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
370     return parseAddress(Operands, SystemZMC::GR32Regs,
371                         SystemZOperand::ADDR32Reg, false);
372   }
373   OperandMatchResultTy
374   parseBDAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
375     return parseAddress(Operands, SystemZMC::GR64Regs,
376                         SystemZOperand::ADDR64Reg, false);
377   }
378   OperandMatchResultTy
379   parseBDXAddr64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
380     return parseAddress(Operands, SystemZMC::GR64Regs,
381                         SystemZOperand::ADDR64Reg, true);
382   }
383   OperandMatchResultTy
384   parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
385   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   }
396 };
397 }
398 
399 #define GET_REGISTER_MATCHER
400 #define GET_SUBTARGET_FEATURE_NAME
401 #define GET_MATCHER_IMPLEMENTATION
402 #include "SystemZGenAsmMatcher.inc"
403 
404 void SystemZOperand::print(raw_ostream &OS) const {
405   llvm_unreachable("Not implemented");
406 }
407 
408 // Parse one register of the form %<prefix><number>.
409 bool 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 
421   // Check that there's a prefix.
422   StringRef Name = Parser.getTok().getString();
423   if (Name.size() < 2)
424     return true;
425   char Prefix = Name[0];
426 
427   // Treat the rest of the register name as a register number.
428   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
439     return true;
440 
441   Reg.EndLoc = Parser.getTok().getLoc();
442   Parser.Lex();
443   return false;
444 }
445 
446 // 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.
450 SystemZAsmParser::OperandMatchResultTy
451 SystemZAsmParser::parseRegister(Register &Reg, RegisterGroup Group,
452                                 const unsigned *Regs, bool IsAddress) {
453   if (Parser.getTok().isNot(AsmToken::Percent))
454     return MatchOperand_NoMatch;
455   if (parseRegister(Reg)) {
456     Error(Reg.StartLoc, "invalid register");
457     return MatchOperand_ParseFail;
458   }
459   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) {
468     Error(Reg.StartLoc, "%r0 used in an address");
469     return MatchOperand_ParseFail;
470   }
471   if (Regs)
472     Reg.Num = Regs[Reg.Num];
473   return MatchOperand_Success;
474 }
475 
476 // Parse a register and add it to Operands.  The other arguments are as above.
477 SystemZAsmParser::OperandMatchResultTy
478 SystemZAsmParser::parseRegister(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
479                                 RegisterGroup Group, const unsigned *Regs,
480                                 SystemZOperand::RegisterKind Kind,
481                                 bool IsAddress) {
482   Register Reg;
483   OperandMatchResultTy Result = parseRegister(Reg, Group, Regs, IsAddress);
484   if (Result == MatchOperand_Success)
485     Operands.push_back(SystemZOperand::createReg(Kind, Reg.Num,
486                                                  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.
494 SystemZAsmParser::OperandMatchResultTy
495 SystemZAsmParser::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;
514     OperandMatchResultTy Result = parseRegister(Reg, RegGR, Regs, true);
515     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 
528       Index = Reg.Num;
529       Result = parseRegister(Reg, RegGR, Regs, true);
530       if (Result != MatchOperand_Success)
531         return Result;
532     }
533     Base = Reg.Num;
534 
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 
548 bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) {
549   return true;
550 }
551 
552 bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
553                                      SMLoc &EndLoc) {
554   if (Parser.getTok().isNot(AsmToken::Percent))
555     return Error(Parser.getTok().getLoc(), "register expected");
556   Register Reg;
557   if (parseRegister(Reg))
558     return Error(Reg.StartLoc, "invalid register");
559   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");
566   StartLoc = Reg.StartLoc;
567   EndLoc = Reg.EndLoc;
568   return false;
569 }
570 
571 bool SystemZAsmParser::
572 ParseInstruction(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 
604 bool SystemZAsmParser::
605 parseOperand(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 
631 bool SystemZAsmParser::
632 MatchAndEmitInstruction(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 
684 SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
685 parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
686   Register Reg;
687   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;
693 }
694 
695 SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
696 parsePCRel(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 
726 // Force static initialization.
727 extern "C" void LLVMInitializeSystemZAsmParser() {
728   RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
729 }
730