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