1 //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst 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/PPCMCTargetDesc.h" 11 #include "llvm/MC/MCTargetAsmParser.h" 12 #include "llvm/MC/MCStreamer.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCInst.h" 15 #include "llvm/MC/MCRegisterInfo.h" 16 #include "llvm/MC/MCSubtargetInfo.h" 17 #include "llvm/MC/MCParser/MCAsmLexer.h" 18 #include "llvm/MC/MCParser/MCAsmParser.h" 19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/StringSwitch.h" 23 #include "llvm/ADT/Twine.h" 24 #include "llvm/Support/SourceMgr.h" 25 #include "llvm/Support/TargetRegistry.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 using namespace llvm; 29 30 namespace { 31 32 static unsigned RRegs[32] = { 33 PPC::R0, PPC::R1, PPC::R2, PPC::R3, 34 PPC::R4, PPC::R5, PPC::R6, PPC::R7, 35 PPC::R8, PPC::R9, PPC::R10, PPC::R11, 36 PPC::R12, PPC::R13, PPC::R14, PPC::R15, 37 PPC::R16, PPC::R17, PPC::R18, PPC::R19, 38 PPC::R20, PPC::R21, PPC::R22, PPC::R23, 39 PPC::R24, PPC::R25, PPC::R26, PPC::R27, 40 PPC::R28, PPC::R29, PPC::R30, PPC::R31 41 }; 42 static unsigned RRegsNoR0[32] = { 43 PPC::ZERO, 44 PPC::R1, PPC::R2, PPC::R3, 45 PPC::R4, PPC::R5, PPC::R6, PPC::R7, 46 PPC::R8, PPC::R9, PPC::R10, PPC::R11, 47 PPC::R12, PPC::R13, PPC::R14, PPC::R15, 48 PPC::R16, PPC::R17, PPC::R18, PPC::R19, 49 PPC::R20, PPC::R21, PPC::R22, PPC::R23, 50 PPC::R24, PPC::R25, PPC::R26, PPC::R27, 51 PPC::R28, PPC::R29, PPC::R30, PPC::R31 52 }; 53 static unsigned XRegs[32] = { 54 PPC::X0, PPC::X1, PPC::X2, PPC::X3, 55 PPC::X4, PPC::X5, PPC::X6, PPC::X7, 56 PPC::X8, PPC::X9, PPC::X10, PPC::X11, 57 PPC::X12, PPC::X13, PPC::X14, PPC::X15, 58 PPC::X16, PPC::X17, PPC::X18, PPC::X19, 59 PPC::X20, PPC::X21, PPC::X22, PPC::X23, 60 PPC::X24, PPC::X25, PPC::X26, PPC::X27, 61 PPC::X28, PPC::X29, PPC::X30, PPC::X31 62 }; 63 static unsigned XRegsNoX0[32] = { 64 PPC::ZERO8, 65 PPC::X1, PPC::X2, PPC::X3, 66 PPC::X4, PPC::X5, PPC::X6, PPC::X7, 67 PPC::X8, PPC::X9, PPC::X10, PPC::X11, 68 PPC::X12, PPC::X13, PPC::X14, PPC::X15, 69 PPC::X16, PPC::X17, PPC::X18, PPC::X19, 70 PPC::X20, PPC::X21, PPC::X22, PPC::X23, 71 PPC::X24, PPC::X25, PPC::X26, PPC::X27, 72 PPC::X28, PPC::X29, PPC::X30, PPC::X31 73 }; 74 static unsigned FRegs[32] = { 75 PPC::F0, PPC::F1, PPC::F2, PPC::F3, 76 PPC::F4, PPC::F5, PPC::F6, PPC::F7, 77 PPC::F8, PPC::F9, PPC::F10, PPC::F11, 78 PPC::F12, PPC::F13, PPC::F14, PPC::F15, 79 PPC::F16, PPC::F17, PPC::F18, PPC::F19, 80 PPC::F20, PPC::F21, PPC::F22, PPC::F23, 81 PPC::F24, PPC::F25, PPC::F26, PPC::F27, 82 PPC::F28, PPC::F29, PPC::F30, PPC::F31 83 }; 84 static unsigned VRegs[32] = { 85 PPC::V0, PPC::V1, PPC::V2, PPC::V3, 86 PPC::V4, PPC::V5, PPC::V6, PPC::V7, 87 PPC::V8, PPC::V9, PPC::V10, PPC::V11, 88 PPC::V12, PPC::V13, PPC::V14, PPC::V15, 89 PPC::V16, PPC::V17, PPC::V18, PPC::V19, 90 PPC::V20, PPC::V21, PPC::V22, PPC::V23, 91 PPC::V24, PPC::V25, PPC::V26, PPC::V27, 92 PPC::V28, PPC::V29, PPC::V30, PPC::V31 93 }; 94 static unsigned CRBITRegs[32] = { 95 PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN, 96 PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN, 97 PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, 98 PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, 99 PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, 100 PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, 101 PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, 102 PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN 103 }; 104 static unsigned CRRegs[8] = { 105 PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, 106 PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7 107 }; 108 109 struct PPCOperand; 110 111 class PPCAsmParser : public MCTargetAsmParser { 112 MCSubtargetInfo &STI; 113 MCAsmParser &Parser; 114 bool IsPPC64; 115 116 MCAsmParser &getParser() const { return Parser; } 117 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 118 119 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 120 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 121 122 bool isPPC64() const { return IsPPC64; } 123 124 bool MatchRegisterName(const AsmToken &Tok, 125 unsigned &RegNo, int64_t &IntVal); 126 127 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 128 129 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 130 131 bool ParseDirectiveWord(unsigned Size, SMLoc L); 132 bool ParseDirectiveTC(unsigned Size, SMLoc L); 133 134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 135 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 136 MCStreamer &Out, unsigned &ErrorInfo, 137 bool MatchingInlineAsm); 138 139 void ProcessInstruction(MCInst &Inst, 140 const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 141 142 /// @name Auto-generated Match Functions 143 /// { 144 145 #define GET_ASSEMBLER_HEADER 146 #include "PPCGenAsmMatcher.inc" 147 148 /// } 149 150 151 public: 152 PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 153 : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 154 // Check for 64-bit vs. 32-bit pointer mode. 155 Triple TheTriple(STI.getTargetTriple()); 156 IsPPC64 = TheTriple.getArch() == Triple::ppc64; 157 // Initialize the set of available features. 158 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 159 } 160 161 virtual bool ParseInstruction(ParseInstructionInfo &Info, 162 StringRef Name, SMLoc NameLoc, 163 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 164 165 virtual bool ParseDirective(AsmToken DirectiveID); 166 }; 167 168 /// PPCOperand - Instances of this class represent a parsed PowerPC machine 169 /// instruction. 170 struct PPCOperand : public MCParsedAsmOperand { 171 enum KindTy { 172 Token, 173 Immediate, 174 Expression 175 } Kind; 176 177 SMLoc StartLoc, EndLoc; 178 bool IsPPC64; 179 180 struct TokOp { 181 const char *Data; 182 unsigned Length; 183 }; 184 185 struct ImmOp { 186 int64_t Val; 187 }; 188 189 struct ExprOp { 190 const MCExpr *Val; 191 }; 192 193 union { 194 struct TokOp Tok; 195 struct ImmOp Imm; 196 struct ExprOp Expr; 197 }; 198 199 PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 200 public: 201 PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() { 202 Kind = o.Kind; 203 StartLoc = o.StartLoc; 204 EndLoc = o.EndLoc; 205 IsPPC64 = o.IsPPC64; 206 switch (Kind) { 207 case Token: 208 Tok = o.Tok; 209 break; 210 case Immediate: 211 Imm = o.Imm; 212 break; 213 case Expression: 214 Expr = o.Expr; 215 break; 216 } 217 } 218 219 /// getStartLoc - Get the location of the first token of this operand. 220 SMLoc getStartLoc() const { return StartLoc; } 221 222 /// getEndLoc - Get the location of the last token of this operand. 223 SMLoc getEndLoc() const { return EndLoc; } 224 225 /// isPPC64 - True if this operand is for an instruction in 64-bit mode. 226 bool isPPC64() const { return IsPPC64; } 227 228 int64_t getImm() const { 229 assert(Kind == Immediate && "Invalid access!"); 230 return Imm.Val; 231 } 232 233 const MCExpr *getExpr() const { 234 assert(Kind == Expression && "Invalid access!"); 235 return Expr.Val; 236 } 237 238 unsigned getReg() const { 239 assert(isRegNumber() && "Invalid access!"); 240 return (unsigned) Imm.Val; 241 } 242 243 unsigned getCCReg() const { 244 assert(isCCRegNumber() && "Invalid access!"); 245 return (unsigned) Imm.Val; 246 } 247 248 unsigned getCRBitMask() const { 249 assert(isCRBitMask() && "Invalid access!"); 250 return 7 - CountTrailingZeros_32(Imm.Val); 251 } 252 253 bool isToken() const { return Kind == Token; } 254 bool isImm() const { return Kind == Immediate || Kind == Expression; } 255 bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); } 256 bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); } 257 bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); } 258 bool isU16Imm() const { return Kind == Expression || 259 (Kind == Immediate && isUInt<16>(getImm())); } 260 bool isS16Imm() const { return Kind == Expression || 261 (Kind == Immediate && isInt<16>(getImm())); } 262 bool isS16ImmX4() const { return Kind == Expression || 263 (Kind == Immediate && isInt<16>(getImm()) && 264 (getImm() & 3) == 0); } 265 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); } 266 bool isCCRegNumber() const { return Kind == Immediate && 267 isUInt<3>(getImm()); } 268 bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) && 269 isPowerOf2_32(getImm()); } 270 bool isMem() const { return false; } 271 bool isReg() const { return false; } 272 273 void addRegOperands(MCInst &Inst, unsigned N) const { 274 llvm_unreachable("addRegOperands"); 275 } 276 277 void addRegGPRCOperands(MCInst &Inst, unsigned N) const { 278 assert(N == 1 && "Invalid number of operands!"); 279 Inst.addOperand(MCOperand::CreateReg(RRegs[getReg()])); 280 } 281 282 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const { 283 assert(N == 1 && "Invalid number of operands!"); 284 Inst.addOperand(MCOperand::CreateReg(RRegsNoR0[getReg()])); 285 } 286 287 void addRegG8RCOperands(MCInst &Inst, unsigned N) const { 288 assert(N == 1 && "Invalid number of operands!"); 289 Inst.addOperand(MCOperand::CreateReg(XRegs[getReg()])); 290 } 291 292 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const { 293 assert(N == 1 && "Invalid number of operands!"); 294 Inst.addOperand(MCOperand::CreateReg(XRegsNoX0[getReg()])); 295 } 296 297 void addRegGxRCOperands(MCInst &Inst, unsigned N) const { 298 if (isPPC64()) 299 addRegG8RCOperands(Inst, N); 300 else 301 addRegGPRCOperands(Inst, N); 302 } 303 304 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const { 305 if (isPPC64()) 306 addRegG8RCNoX0Operands(Inst, N); 307 else 308 addRegGPRCNoR0Operands(Inst, N); 309 } 310 311 void addRegF4RCOperands(MCInst &Inst, unsigned N) const { 312 assert(N == 1 && "Invalid number of operands!"); 313 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()])); 314 } 315 316 void addRegF8RCOperands(MCInst &Inst, unsigned N) const { 317 assert(N == 1 && "Invalid number of operands!"); 318 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()])); 319 } 320 321 void addRegVRRCOperands(MCInst &Inst, unsigned N) const { 322 assert(N == 1 && "Invalid number of operands!"); 323 Inst.addOperand(MCOperand::CreateReg(VRegs[getReg()])); 324 } 325 326 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const { 327 assert(N == 1 && "Invalid number of operands!"); 328 Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getReg()])); 329 } 330 331 void addRegCRRCOperands(MCInst &Inst, unsigned N) const { 332 assert(N == 1 && "Invalid number of operands!"); 333 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCCReg()])); 334 } 335 336 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const { 337 assert(N == 1 && "Invalid number of operands!"); 338 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCRBitMask()])); 339 } 340 341 void addImmOperands(MCInst &Inst, unsigned N) const { 342 assert(N == 1 && "Invalid number of operands!"); 343 if (Kind == Immediate) 344 Inst.addOperand(MCOperand::CreateImm(getImm())); 345 else 346 Inst.addOperand(MCOperand::CreateExpr(getExpr())); 347 } 348 349 void addDispRIOperands(MCInst &Inst, unsigned N) const { 350 assert(N == 1 && "Invalid number of operands!"); 351 if (Kind == Immediate) 352 Inst.addOperand(MCOperand::CreateImm(getImm())); 353 else 354 Inst.addOperand(MCOperand::CreateExpr(getExpr())); 355 } 356 357 void addDispRIXOperands(MCInst &Inst, unsigned N) const { 358 assert(N == 1 && "Invalid number of operands!"); 359 if (Kind == Immediate) 360 Inst.addOperand(MCOperand::CreateImm(getImm() / 4)); 361 else 362 Inst.addOperand(MCOperand::CreateExpr(getExpr())); 363 } 364 365 StringRef getToken() const { 366 assert(Kind == Token && "Invalid access!"); 367 return StringRef(Tok.Data, Tok.Length); 368 } 369 370 virtual void print(raw_ostream &OS) const; 371 372 static PPCOperand *CreateToken(StringRef Str, SMLoc S, bool IsPPC64) { 373 PPCOperand *Op = new PPCOperand(Token); 374 Op->Tok.Data = Str.data(); 375 Op->Tok.Length = Str.size(); 376 Op->StartLoc = S; 377 Op->EndLoc = S; 378 Op->IsPPC64 = IsPPC64; 379 return Op; 380 } 381 382 static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { 383 PPCOperand *Op = new PPCOperand(Immediate); 384 Op->Imm.Val = Val; 385 Op->StartLoc = S; 386 Op->EndLoc = E; 387 Op->IsPPC64 = IsPPC64; 388 return Op; 389 } 390 391 static PPCOperand *CreateExpr(const MCExpr *Val, 392 SMLoc S, SMLoc E, bool IsPPC64) { 393 PPCOperand *Op = new PPCOperand(Expression); 394 Op->Expr.Val = Val; 395 Op->StartLoc = S; 396 Op->EndLoc = E; 397 Op->IsPPC64 = IsPPC64; 398 return Op; 399 } 400 }; 401 402 } // end anonymous namespace. 403 404 void PPCOperand::print(raw_ostream &OS) const { 405 switch (Kind) { 406 case Token: 407 OS << "'" << getToken() << "'"; 408 break; 409 case Immediate: 410 OS << getImm(); 411 break; 412 case Expression: 413 getExpr()->print(OS); 414 break; 415 } 416 } 417 418 419 void PPCAsmParser:: 420 ProcessInstruction(MCInst &Inst, 421 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 422 switch (Inst.getOpcode()) { 423 case PPC::SLWI: { 424 MCInst TmpInst; 425 int64_t N = Inst.getOperand(2).getImm(); 426 TmpInst.setOpcode(PPC::RLWINM); 427 TmpInst.addOperand(Inst.getOperand(0)); 428 TmpInst.addOperand(Inst.getOperand(1)); 429 TmpInst.addOperand(MCOperand::CreateImm(N)); 430 TmpInst.addOperand(MCOperand::CreateImm(0)); 431 TmpInst.addOperand(MCOperand::CreateImm(31 - N)); 432 Inst = TmpInst; 433 break; 434 } 435 case PPC::SRWI: { 436 MCInst TmpInst; 437 int64_t N = Inst.getOperand(2).getImm(); 438 TmpInst.setOpcode(PPC::RLWINM); 439 TmpInst.addOperand(Inst.getOperand(0)); 440 TmpInst.addOperand(Inst.getOperand(1)); 441 TmpInst.addOperand(MCOperand::CreateImm(32 - N)); 442 TmpInst.addOperand(MCOperand::CreateImm(N)); 443 TmpInst.addOperand(MCOperand::CreateImm(31)); 444 Inst = TmpInst; 445 break; 446 } 447 case PPC::SLDI: { 448 MCInst TmpInst; 449 int64_t N = Inst.getOperand(2).getImm(); 450 TmpInst.setOpcode(PPC::RLDICR); 451 TmpInst.addOperand(Inst.getOperand(0)); 452 TmpInst.addOperand(Inst.getOperand(1)); 453 TmpInst.addOperand(MCOperand::CreateImm(N)); 454 TmpInst.addOperand(MCOperand::CreateImm(63 - N)); 455 Inst = TmpInst; 456 break; 457 } 458 case PPC::SRDI: { 459 MCInst TmpInst; 460 int64_t N = Inst.getOperand(2).getImm(); 461 TmpInst.setOpcode(PPC::RLDICL); 462 TmpInst.addOperand(Inst.getOperand(0)); 463 TmpInst.addOperand(Inst.getOperand(1)); 464 TmpInst.addOperand(MCOperand::CreateImm(64 - N)); 465 TmpInst.addOperand(MCOperand::CreateImm(N)); 466 Inst = TmpInst; 467 break; 468 } 469 } 470 } 471 472 bool PPCAsmParser:: 473 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 474 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 475 MCStreamer &Out, unsigned &ErrorInfo, 476 bool MatchingInlineAsm) { 477 MCInst Inst; 478 479 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 480 default: break; 481 case Match_Success: 482 // Post-process instructions (typically extended mnemonics) 483 ProcessInstruction(Inst, Operands); 484 Inst.setLoc(IDLoc); 485 Out.EmitInstruction(Inst); 486 return false; 487 case Match_MissingFeature: 488 return Error(IDLoc, "instruction use requires an option to be enabled"); 489 case Match_MnemonicFail: 490 return Error(IDLoc, "unrecognized instruction mnemonic"); 491 case Match_InvalidOperand: { 492 SMLoc ErrorLoc = IDLoc; 493 if (ErrorInfo != ~0U) { 494 if (ErrorInfo >= Operands.size()) 495 return Error(IDLoc, "too few operands for instruction"); 496 497 ErrorLoc = ((PPCOperand*)Operands[ErrorInfo])->getStartLoc(); 498 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 499 } 500 501 return Error(ErrorLoc, "invalid operand for instruction"); 502 } 503 } 504 505 llvm_unreachable("Implement any new match types added!"); 506 } 507 508 bool PPCAsmParser:: 509 MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) { 510 if (Tok.is(AsmToken::Identifier)) { 511 StringRef Name = Tok.getString(); 512 513 if (Name.equals_lower("lr")) { 514 RegNo = isPPC64()? PPC::LR8 : PPC::LR; 515 IntVal = 8; 516 return false; 517 } else if (Name.equals_lower("ctr")) { 518 RegNo = isPPC64()? PPC::CTR8 : PPC::CTR; 519 IntVal = 9; 520 return false; 521 } else if (Name.substr(0, 1).equals_lower("r") && 522 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 523 RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal]; 524 return false; 525 } else if (Name.substr(0, 1).equals_lower("f") && 526 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 527 RegNo = FRegs[IntVal]; 528 return false; 529 } else if (Name.substr(0, 1).equals_lower("v") && 530 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 531 RegNo = VRegs[IntVal]; 532 return false; 533 } else if (Name.substr(0, 2).equals_lower("cr") && 534 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) { 535 RegNo = CRRegs[IntVal]; 536 return false; 537 } 538 } 539 540 return true; 541 } 542 543 bool PPCAsmParser:: 544 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 545 const AsmToken &Tok = Parser.getTok(); 546 StartLoc = Tok.getLoc(); 547 EndLoc = Tok.getEndLoc(); 548 RegNo = 0; 549 int64_t IntVal; 550 551 if (!MatchRegisterName(Tok, RegNo, IntVal)) { 552 Parser.Lex(); // Eat identifier token. 553 return false; 554 } 555 556 return Error(StartLoc, "invalid register name"); 557 } 558 559 bool PPCAsmParser:: 560 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 561 SMLoc S = Parser.getTok().getLoc(); 562 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 563 const MCExpr *EVal; 564 PPCOperand *Op; 565 566 // Attempt to parse the next token as an immediate 567 switch (getLexer().getKind()) { 568 // Special handling for register names. These are interpreted 569 // as immediates corresponding to the register number. 570 case AsmToken::Percent: 571 Parser.Lex(); // Eat the '%'. 572 unsigned RegNo; 573 int64_t IntVal; 574 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) { 575 Parser.Lex(); // Eat the identifier token. 576 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 577 Operands.push_back(Op); 578 return false; 579 } 580 return Error(S, "invalid register name"); 581 582 // All other expressions 583 case AsmToken::LParen: 584 case AsmToken::Plus: 585 case AsmToken::Minus: 586 case AsmToken::Integer: 587 case AsmToken::Identifier: 588 case AsmToken::Dot: 589 case AsmToken::Dollar: 590 if (!getParser().parseExpression(EVal)) 591 break; 592 /* fall through */ 593 default: 594 return Error(S, "unknown operand"); 595 } 596 597 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(EVal)) 598 Op = PPCOperand::CreateImm(CE->getValue(), S, E, isPPC64()); 599 else 600 Op = PPCOperand::CreateExpr(EVal, S, E, isPPC64()); 601 602 // Push the parsed operand into the list of operands 603 Operands.push_back(Op); 604 605 // Check for D-form memory operands 606 if (getLexer().is(AsmToken::LParen)) { 607 Parser.Lex(); // Eat the '('. 608 S = Parser.getTok().getLoc(); 609 610 int64_t IntVal; 611 switch (getLexer().getKind()) { 612 case AsmToken::Percent: 613 Parser.Lex(); // Eat the '%'. 614 unsigned RegNo; 615 if (MatchRegisterName(Parser.getTok(), RegNo, IntVal)) 616 return Error(S, "invalid register name"); 617 Parser.Lex(); // Eat the identifier token. 618 break; 619 620 case AsmToken::Integer: 621 if (getParser().parseAbsoluteExpression(IntVal) || 622 IntVal < 0 || IntVal > 31) 623 return Error(S, "invalid register number"); 624 break; 625 626 default: 627 return Error(S, "invalid memory operand"); 628 } 629 630 if (getLexer().isNot(AsmToken::RParen)) 631 return Error(Parser.getTok().getLoc(), "missing ')'"); 632 E = Parser.getTok().getLoc(); 633 Parser.Lex(); // Eat the ')'. 634 635 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 636 Operands.push_back(Op); 637 } 638 639 return false; 640 } 641 642 /// Parse an instruction mnemonic followed by its operands. 643 bool PPCAsmParser:: 644 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 645 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 646 // The first operand is the token for the instruction name. 647 // If the instruction ends in a '.', we need to create a separate 648 // token for it, to match what TableGen is doing. 649 size_t Dot = Name.find('.'); 650 StringRef Mnemonic = Name.slice(0, Dot); 651 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); 652 if (Dot != StringRef::npos) { 653 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); 654 StringRef DotStr = Name.slice(Dot, StringRef::npos); 655 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); 656 } 657 658 // If there are no more operands then finish 659 if (getLexer().is(AsmToken::EndOfStatement)) 660 return false; 661 662 // Parse the first operand 663 if (ParseOperand(Operands)) 664 return true; 665 666 while (getLexer().isNot(AsmToken::EndOfStatement) && 667 getLexer().is(AsmToken::Comma)) { 668 // Consume the comma token 669 getLexer().Lex(); 670 671 // Parse the next operand 672 if (ParseOperand(Operands)) 673 return true; 674 } 675 676 return false; 677 } 678 679 /// ParseDirective parses the PPC specific directives 680 bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) { 681 StringRef IDVal = DirectiveID.getIdentifier(); 682 if (IDVal == ".word") 683 return ParseDirectiveWord(4, DirectiveID.getLoc()); 684 if (IDVal == ".tc") 685 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc()); 686 return true; 687 } 688 689 /// ParseDirectiveWord 690 /// ::= .word [ expression (, expression)* ] 691 bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 692 if (getLexer().isNot(AsmToken::EndOfStatement)) { 693 for (;;) { 694 const MCExpr *Value; 695 if (getParser().parseExpression(Value)) 696 return true; 697 698 getParser().getStreamer().EmitValue(Value, Size); 699 700 if (getLexer().is(AsmToken::EndOfStatement)) 701 break; 702 703 if (getLexer().isNot(AsmToken::Comma)) 704 return Error(L, "unexpected token in directive"); 705 Parser.Lex(); 706 } 707 } 708 709 Parser.Lex(); 710 return false; 711 } 712 713 /// ParseDirectiveTC 714 /// ::= .tc [ symbol (, expression)* ] 715 bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) { 716 // Skip TC symbol, which is only used with XCOFF. 717 while (getLexer().isNot(AsmToken::EndOfStatement) 718 && getLexer().isNot(AsmToken::Comma)) 719 Parser.Lex(); 720 if (getLexer().isNot(AsmToken::Comma)) 721 return Error(L, "unexpected token in directive"); 722 Parser.Lex(); 723 724 // Align to word size. 725 getParser().getStreamer().EmitValueToAlignment(Size); 726 727 // Emit expressions. 728 return ParseDirectiveWord(Size, L); 729 } 730 731 /// Force static initialization. 732 extern "C" void LLVMInitializePowerPCAsmParser() { 733 RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target); 734 RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target); 735 } 736 737 #define GET_REGISTER_MATCHER 738 #define GET_MATCHER_IMPLEMENTATION 739 #include "PPCGenAsmMatcher.inc" 740