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