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