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