PPCAsmParser.cpp revision c6af2432c802d241c8fffbe0371c023e6c58844e
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 28using namespace llvm; 29 30namespace { 31 32static 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}; 42static 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}; 53static 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}; 63static 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}; 74static 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}; 84static 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}; 94static 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}; 104static unsigned CRRegs[8] = { 105 PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, 106 PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7 107}; 108 109struct PPCOperand; 110 111class 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 151public: 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. 170struct 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) {} 200public: 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<uint64_t>(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 StringRef getToken() const { 350 assert(Kind == Token && "Invalid access!"); 351 return StringRef(Tok.Data, Tok.Length); 352 } 353 354 virtual void print(raw_ostream &OS) const; 355 356 static PPCOperand *CreateToken(StringRef Str, SMLoc S, bool IsPPC64) { 357 PPCOperand *Op = new PPCOperand(Token); 358 Op->Tok.Data = Str.data(); 359 Op->Tok.Length = Str.size(); 360 Op->StartLoc = S; 361 Op->EndLoc = S; 362 Op->IsPPC64 = IsPPC64; 363 return Op; 364 } 365 366 static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { 367 PPCOperand *Op = new PPCOperand(Immediate); 368 Op->Imm.Val = Val; 369 Op->StartLoc = S; 370 Op->EndLoc = E; 371 Op->IsPPC64 = IsPPC64; 372 return Op; 373 } 374 375 static PPCOperand *CreateExpr(const MCExpr *Val, 376 SMLoc S, SMLoc E, bool IsPPC64) { 377 PPCOperand *Op = new PPCOperand(Expression); 378 Op->Expr.Val = Val; 379 Op->StartLoc = S; 380 Op->EndLoc = E; 381 Op->IsPPC64 = IsPPC64; 382 return Op; 383 } 384}; 385 386} // end anonymous namespace. 387 388void PPCOperand::print(raw_ostream &OS) const { 389 switch (Kind) { 390 case Token: 391 OS << "'" << getToken() << "'"; 392 break; 393 case Immediate: 394 OS << getImm(); 395 break; 396 case Expression: 397 getExpr()->print(OS); 398 break; 399 } 400} 401 402 403void PPCAsmParser:: 404ProcessInstruction(MCInst &Inst, 405 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 406 switch (Inst.getOpcode()) { 407 case PPC::SLWI: { 408 MCInst TmpInst; 409 int64_t N = Inst.getOperand(2).getImm(); 410 TmpInst.setOpcode(PPC::RLWINM); 411 TmpInst.addOperand(Inst.getOperand(0)); 412 TmpInst.addOperand(Inst.getOperand(1)); 413 TmpInst.addOperand(MCOperand::CreateImm(N)); 414 TmpInst.addOperand(MCOperand::CreateImm(0)); 415 TmpInst.addOperand(MCOperand::CreateImm(31 - N)); 416 Inst = TmpInst; 417 break; 418 } 419 case PPC::SRWI: { 420 MCInst TmpInst; 421 int64_t N = Inst.getOperand(2).getImm(); 422 TmpInst.setOpcode(PPC::RLWINM); 423 TmpInst.addOperand(Inst.getOperand(0)); 424 TmpInst.addOperand(Inst.getOperand(1)); 425 TmpInst.addOperand(MCOperand::CreateImm(32 - N)); 426 TmpInst.addOperand(MCOperand::CreateImm(N)); 427 TmpInst.addOperand(MCOperand::CreateImm(31)); 428 Inst = TmpInst; 429 break; 430 } 431 case PPC::SLDI: { 432 MCInst TmpInst; 433 int64_t N = Inst.getOperand(2).getImm(); 434 TmpInst.setOpcode(PPC::RLDICR); 435 TmpInst.addOperand(Inst.getOperand(0)); 436 TmpInst.addOperand(Inst.getOperand(1)); 437 TmpInst.addOperand(MCOperand::CreateImm(N)); 438 TmpInst.addOperand(MCOperand::CreateImm(63 - N)); 439 Inst = TmpInst; 440 break; 441 } 442 case PPC::SRDI: { 443 MCInst TmpInst; 444 int64_t N = Inst.getOperand(2).getImm(); 445 TmpInst.setOpcode(PPC::RLDICL); 446 TmpInst.addOperand(Inst.getOperand(0)); 447 TmpInst.addOperand(Inst.getOperand(1)); 448 TmpInst.addOperand(MCOperand::CreateImm(64 - N)); 449 TmpInst.addOperand(MCOperand::CreateImm(N)); 450 Inst = TmpInst; 451 break; 452 } 453 } 454} 455 456bool PPCAsmParser:: 457MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 458 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 459 MCStreamer &Out, unsigned &ErrorInfo, 460 bool MatchingInlineAsm) { 461 MCInst Inst; 462 463 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 464 default: break; 465 case Match_Success: 466 // Post-process instructions (typically extended mnemonics) 467 ProcessInstruction(Inst, Operands); 468 Inst.setLoc(IDLoc); 469 Out.EmitInstruction(Inst); 470 return false; 471 case Match_MissingFeature: 472 return Error(IDLoc, "instruction use requires an option to be enabled"); 473 case Match_MnemonicFail: 474 return Error(IDLoc, "unrecognized instruction mnemonic"); 475 case Match_InvalidOperand: { 476 SMLoc ErrorLoc = IDLoc; 477 if (ErrorInfo != ~0U) { 478 if (ErrorInfo >= Operands.size()) 479 return Error(IDLoc, "too few operands for instruction"); 480 481 ErrorLoc = ((PPCOperand*)Operands[ErrorInfo])->getStartLoc(); 482 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 483 } 484 485 return Error(ErrorLoc, "invalid operand for instruction"); 486 } 487 } 488 489 llvm_unreachable("Implement any new match types added!"); 490} 491 492bool PPCAsmParser:: 493MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) { 494 if (Tok.is(AsmToken::Identifier)) { 495 StringRef Name = Tok.getString(); 496 497 if (Name.equals_lower("lr")) { 498 RegNo = isPPC64()? PPC::LR8 : PPC::LR; 499 IntVal = 8; 500 return false; 501 } else if (Name.equals_lower("ctr")) { 502 RegNo = isPPC64()? PPC::CTR8 : PPC::CTR; 503 IntVal = 9; 504 return false; 505 } else if (Name.substr(0, 1).equals_lower("r") && 506 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 507 RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal]; 508 return false; 509 } else if (Name.substr(0, 1).equals_lower("f") && 510 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 511 RegNo = FRegs[IntVal]; 512 return false; 513 } else if (Name.substr(0, 1).equals_lower("v") && 514 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 515 RegNo = VRegs[IntVal]; 516 return false; 517 } else if (Name.substr(0, 2).equals_lower("cr") && 518 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) { 519 RegNo = CRRegs[IntVal]; 520 return false; 521 } 522 } 523 524 return true; 525} 526 527bool PPCAsmParser:: 528ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 529 const AsmToken &Tok = Parser.getTok(); 530 StartLoc = Tok.getLoc(); 531 EndLoc = Tok.getEndLoc(); 532 RegNo = 0; 533 int64_t IntVal; 534 535 if (!MatchRegisterName(Tok, RegNo, IntVal)) { 536 Parser.Lex(); // Eat identifier token. 537 return false; 538 } 539 540 return Error(StartLoc, "invalid register name"); 541} 542 543bool PPCAsmParser:: 544ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 545 SMLoc S = Parser.getTok().getLoc(); 546 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 547 const MCExpr *EVal; 548 PPCOperand *Op; 549 550 // Attempt to parse the next token as an immediate 551 switch (getLexer().getKind()) { 552 // Special handling for register names. These are interpreted 553 // as immediates corresponding to the register number. 554 case AsmToken::Percent: 555 Parser.Lex(); // Eat the '%'. 556 unsigned RegNo; 557 int64_t IntVal; 558 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) { 559 Parser.Lex(); // Eat the identifier token. 560 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 561 Operands.push_back(Op); 562 return false; 563 } 564 return Error(S, "invalid register name"); 565 566 // All other expressions 567 case AsmToken::LParen: 568 case AsmToken::Plus: 569 case AsmToken::Minus: 570 case AsmToken::Integer: 571 case AsmToken::Identifier: 572 case AsmToken::Dot: 573 case AsmToken::Dollar: 574 if (!getParser().parseExpression(EVal)) 575 break; 576 /* fall through */ 577 default: 578 return Error(S, "unknown operand"); 579 } 580 581 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(EVal)) 582 Op = PPCOperand::CreateImm(CE->getValue(), S, E, isPPC64()); 583 else 584 Op = PPCOperand::CreateExpr(EVal, S, E, isPPC64()); 585 586 // Push the parsed operand into the list of operands 587 Operands.push_back(Op); 588 589 // Check for D-form memory operands 590 if (getLexer().is(AsmToken::LParen)) { 591 Parser.Lex(); // Eat the '('. 592 S = Parser.getTok().getLoc(); 593 594 int64_t IntVal; 595 switch (getLexer().getKind()) { 596 case AsmToken::Percent: 597 Parser.Lex(); // Eat the '%'. 598 unsigned RegNo; 599 if (MatchRegisterName(Parser.getTok(), RegNo, IntVal)) 600 return Error(S, "invalid register name"); 601 Parser.Lex(); // Eat the identifier token. 602 break; 603 604 case AsmToken::Integer: 605 if (getParser().parseAbsoluteExpression(IntVal) || 606 IntVal < 0 || IntVal > 31) 607 return Error(S, "invalid register number"); 608 break; 609 610 default: 611 return Error(S, "invalid memory operand"); 612 } 613 614 if (getLexer().isNot(AsmToken::RParen)) 615 return Error(Parser.getTok().getLoc(), "missing ')'"); 616 E = Parser.getTok().getLoc(); 617 Parser.Lex(); // Eat the ')'. 618 619 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 620 Operands.push_back(Op); 621 } 622 623 return false; 624} 625 626/// Parse an instruction mnemonic followed by its operands. 627bool PPCAsmParser:: 628ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 629 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 630 // The first operand is the token for the instruction name. 631 // If the instruction ends in a '.', we need to create a separate 632 // token for it, to match what TableGen is doing. 633 size_t Dot = Name.find('.'); 634 StringRef Mnemonic = Name.slice(0, Dot); 635 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); 636 if (Dot != StringRef::npos) { 637 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); 638 StringRef DotStr = Name.slice(Dot, StringRef::npos); 639 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); 640 } 641 642 // If there are no more operands then finish 643 if (getLexer().is(AsmToken::EndOfStatement)) 644 return false; 645 646 // Parse the first operand 647 if (ParseOperand(Operands)) 648 return true; 649 650 while (getLexer().isNot(AsmToken::EndOfStatement) && 651 getLexer().is(AsmToken::Comma)) { 652 // Consume the comma token 653 getLexer().Lex(); 654 655 // Parse the next operand 656 if (ParseOperand(Operands)) 657 return true; 658 } 659 660 return false; 661} 662 663/// ParseDirective parses the PPC specific directives 664bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) { 665 StringRef IDVal = DirectiveID.getIdentifier(); 666 if (IDVal == ".word") 667 return ParseDirectiveWord(4, DirectiveID.getLoc()); 668 if (IDVal == ".tc") 669 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc()); 670 return true; 671} 672 673/// ParseDirectiveWord 674/// ::= .word [ expression (, expression)* ] 675bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 676 if (getLexer().isNot(AsmToken::EndOfStatement)) { 677 for (;;) { 678 const MCExpr *Value; 679 if (getParser().parseExpression(Value)) 680 return true; 681 682 getParser().getStreamer().EmitValue(Value, Size); 683 684 if (getLexer().is(AsmToken::EndOfStatement)) 685 break; 686 687 if (getLexer().isNot(AsmToken::Comma)) 688 return Error(L, "unexpected token in directive"); 689 Parser.Lex(); 690 } 691 } 692 693 Parser.Lex(); 694 return false; 695} 696 697/// ParseDirectiveTC 698/// ::= .tc [ symbol (, expression)* ] 699bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) { 700 // Skip TC symbol, which is only used with XCOFF. 701 while (getLexer().isNot(AsmToken::EndOfStatement) 702 && getLexer().isNot(AsmToken::Comma)) 703 Parser.Lex(); 704 if (getLexer().isNot(AsmToken::Comma)) 705 return Error(L, "unexpected token in directive"); 706 Parser.Lex(); 707 708 // Align to word size. 709 getParser().getStreamer().EmitValueToAlignment(Size); 710 711 // Emit expressions. 712 return ParseDirectiveWord(Size, L); 713} 714 715/// Force static initialization. 716extern "C" void LLVMInitializePowerPCAsmParser() { 717 RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target); 718 RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target); 719} 720 721#define GET_REGISTER_MATCHER 722#define GET_MATCHER_IMPLEMENTATION 723#include "PPCGenAsmMatcher.inc" 724