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 29 using namespace llvm; 30 31 namespace { 32 33 static 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 }; 43 static 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 }; 54 static 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 }; 64 static 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 }; 75 static 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 }; 85 static 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 }; 95 static 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 }; 105 static unsigned CRRegs[8] = { 106 PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, 107 PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7 108 }; 109 110 struct PPCOperand; 111 112 class 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 156 public: 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. 175 struct 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) {} 205 public: 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 isS17Imm() const { return Kind == Expression || 271 (Kind == Immediate && isInt<17>(getImm())); } 272 bool isDirectBr() const { return Kind == Expression || 273 (Kind == Immediate && isInt<26>(getImm()) && 274 (getImm() & 3) == 0); } 275 bool isCondBr() const { return Kind == Expression || 276 (Kind == Immediate && isInt<16>(getImm()) && 277 (getImm() & 3) == 0); } 278 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); } 279 bool isCCRegNumber() const { return Kind == Immediate && 280 isUInt<3>(getImm()); } 281 bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) && 282 isPowerOf2_32(getImm()); } 283 bool isMem() const { return false; } 284 bool isReg() const { return false; } 285 286 void addRegOperands(MCInst &Inst, unsigned N) const { 287 llvm_unreachable("addRegOperands"); 288 } 289 290 void addRegGPRCOperands(MCInst &Inst, unsigned N) const { 291 assert(N == 1 && "Invalid number of operands!"); 292 Inst.addOperand(MCOperand::CreateReg(RRegs[getReg()])); 293 } 294 295 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const { 296 assert(N == 1 && "Invalid number of operands!"); 297 Inst.addOperand(MCOperand::CreateReg(RRegsNoR0[getReg()])); 298 } 299 300 void addRegG8RCOperands(MCInst &Inst, unsigned N) const { 301 assert(N == 1 && "Invalid number of operands!"); 302 Inst.addOperand(MCOperand::CreateReg(XRegs[getReg()])); 303 } 304 305 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const { 306 assert(N == 1 && "Invalid number of operands!"); 307 Inst.addOperand(MCOperand::CreateReg(XRegsNoX0[getReg()])); 308 } 309 310 void addRegGxRCOperands(MCInst &Inst, unsigned N) const { 311 if (isPPC64()) 312 addRegG8RCOperands(Inst, N); 313 else 314 addRegGPRCOperands(Inst, N); 315 } 316 317 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const { 318 if (isPPC64()) 319 addRegG8RCNoX0Operands(Inst, N); 320 else 321 addRegGPRCNoR0Operands(Inst, N); 322 } 323 324 void addRegF4RCOperands(MCInst &Inst, unsigned N) const { 325 assert(N == 1 && "Invalid number of operands!"); 326 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()])); 327 } 328 329 void addRegF8RCOperands(MCInst &Inst, unsigned N) const { 330 assert(N == 1 && "Invalid number of operands!"); 331 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()])); 332 } 333 334 void addRegVRRCOperands(MCInst &Inst, unsigned N) const { 335 assert(N == 1 && "Invalid number of operands!"); 336 Inst.addOperand(MCOperand::CreateReg(VRegs[getReg()])); 337 } 338 339 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const { 340 assert(N == 1 && "Invalid number of operands!"); 341 Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getReg()])); 342 } 343 344 void addRegCRRCOperands(MCInst &Inst, unsigned N) const { 345 assert(N == 1 && "Invalid number of operands!"); 346 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCCReg()])); 347 } 348 349 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const { 350 assert(N == 1 && "Invalid number of operands!"); 351 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCRBitMask()])); 352 } 353 354 void addImmOperands(MCInst &Inst, unsigned N) const { 355 assert(N == 1 && "Invalid number of operands!"); 356 if (Kind == Immediate) 357 Inst.addOperand(MCOperand::CreateImm(getImm())); 358 else 359 Inst.addOperand(MCOperand::CreateExpr(getExpr())); 360 } 361 362 void addBranchTargetOperands(MCInst &Inst, unsigned N) const { 363 assert(N == 1 && "Invalid number of operands!"); 364 if (Kind == Immediate) 365 Inst.addOperand(MCOperand::CreateImm(getImm() / 4)); 366 else 367 Inst.addOperand(MCOperand::CreateExpr(getExpr())); 368 } 369 370 StringRef getToken() const { 371 assert(Kind == Token && "Invalid access!"); 372 return StringRef(Tok.Data, Tok.Length); 373 } 374 375 virtual void print(raw_ostream &OS) const; 376 377 static PPCOperand *CreateToken(StringRef Str, SMLoc S, bool IsPPC64) { 378 PPCOperand *Op = new PPCOperand(Token); 379 Op->Tok.Data = Str.data(); 380 Op->Tok.Length = Str.size(); 381 Op->StartLoc = S; 382 Op->EndLoc = S; 383 Op->IsPPC64 = IsPPC64; 384 return Op; 385 } 386 387 static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { 388 PPCOperand *Op = new PPCOperand(Immediate); 389 Op->Imm.Val = Val; 390 Op->StartLoc = S; 391 Op->EndLoc = E; 392 Op->IsPPC64 = IsPPC64; 393 return Op; 394 } 395 396 static PPCOperand *CreateExpr(const MCExpr *Val, 397 SMLoc S, SMLoc E, bool IsPPC64) { 398 PPCOperand *Op = new PPCOperand(Expression); 399 Op->Expr.Val = Val; 400 Op->StartLoc = S; 401 Op->EndLoc = E; 402 Op->IsPPC64 = IsPPC64; 403 return Op; 404 } 405 }; 406 407 } // end anonymous namespace. 408 409 void PPCOperand::print(raw_ostream &OS) const { 410 switch (Kind) { 411 case Token: 412 OS << "'" << getToken() << "'"; 413 break; 414 case Immediate: 415 OS << getImm(); 416 break; 417 case Expression: 418 getExpr()->print(OS); 419 break; 420 } 421 } 422 423 424 void PPCAsmParser:: 425 ProcessInstruction(MCInst &Inst, 426 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 427 int Opcode = Inst.getOpcode(); 428 switch (Opcode) { 429 case PPC::LAx: { 430 MCInst TmpInst; 431 TmpInst.setOpcode(PPC::LA); 432 TmpInst.addOperand(Inst.getOperand(0)); 433 TmpInst.addOperand(Inst.getOperand(2)); 434 TmpInst.addOperand(Inst.getOperand(1)); 435 Inst = TmpInst; 436 break; 437 } 438 case PPC::SUBI: { 439 MCInst TmpInst; 440 int64_t N = Inst.getOperand(2).getImm(); 441 TmpInst.setOpcode(PPC::ADDI); 442 TmpInst.addOperand(Inst.getOperand(0)); 443 TmpInst.addOperand(Inst.getOperand(1)); 444 TmpInst.addOperand(MCOperand::CreateImm(-N)); 445 Inst = TmpInst; 446 break; 447 } 448 case PPC::SUBIS: { 449 MCInst TmpInst; 450 int64_t N = Inst.getOperand(2).getImm(); 451 TmpInst.setOpcode(PPC::ADDIS); 452 TmpInst.addOperand(Inst.getOperand(0)); 453 TmpInst.addOperand(Inst.getOperand(1)); 454 TmpInst.addOperand(MCOperand::CreateImm(-N)); 455 Inst = TmpInst; 456 break; 457 } 458 case PPC::SUBIC: { 459 MCInst TmpInst; 460 int64_t N = Inst.getOperand(2).getImm(); 461 TmpInst.setOpcode(PPC::ADDIC); 462 TmpInst.addOperand(Inst.getOperand(0)); 463 TmpInst.addOperand(Inst.getOperand(1)); 464 TmpInst.addOperand(MCOperand::CreateImm(-N)); 465 Inst = TmpInst; 466 break; 467 } 468 case PPC::SUBICo: { 469 MCInst TmpInst; 470 int64_t N = Inst.getOperand(2).getImm(); 471 TmpInst.setOpcode(PPC::ADDICo); 472 TmpInst.addOperand(Inst.getOperand(0)); 473 TmpInst.addOperand(Inst.getOperand(1)); 474 TmpInst.addOperand(MCOperand::CreateImm(-N)); 475 Inst = TmpInst; 476 break; 477 } 478 case PPC::EXTLWI: 479 case PPC::EXTLWIo: { 480 MCInst TmpInst; 481 int64_t N = Inst.getOperand(2).getImm(); 482 int64_t B = Inst.getOperand(3).getImm(); 483 TmpInst.setOpcode(Opcode == PPC::EXTLWI? PPC::RLWINM : PPC::RLWINMo); 484 TmpInst.addOperand(Inst.getOperand(0)); 485 TmpInst.addOperand(Inst.getOperand(1)); 486 TmpInst.addOperand(MCOperand::CreateImm(B)); 487 TmpInst.addOperand(MCOperand::CreateImm(0)); 488 TmpInst.addOperand(MCOperand::CreateImm(N - 1)); 489 Inst = TmpInst; 490 break; 491 } 492 case PPC::EXTRWI: 493 case PPC::EXTRWIo: { 494 MCInst TmpInst; 495 int64_t N = Inst.getOperand(2).getImm(); 496 int64_t B = Inst.getOperand(3).getImm(); 497 TmpInst.setOpcode(Opcode == PPC::EXTRWI? PPC::RLWINM : PPC::RLWINMo); 498 TmpInst.addOperand(Inst.getOperand(0)); 499 TmpInst.addOperand(Inst.getOperand(1)); 500 TmpInst.addOperand(MCOperand::CreateImm(B + N)); 501 TmpInst.addOperand(MCOperand::CreateImm(32 - N)); 502 TmpInst.addOperand(MCOperand::CreateImm(31)); 503 Inst = TmpInst; 504 break; 505 } 506 case PPC::INSLWI: 507 case PPC::INSLWIo: { 508 MCInst TmpInst; 509 int64_t N = Inst.getOperand(2).getImm(); 510 int64_t B = Inst.getOperand(3).getImm(); 511 TmpInst.setOpcode(Opcode == PPC::INSLWI? PPC::RLWIMI : PPC::RLWIMIo); 512 TmpInst.addOperand(Inst.getOperand(0)); 513 TmpInst.addOperand(Inst.getOperand(0)); 514 TmpInst.addOperand(Inst.getOperand(1)); 515 TmpInst.addOperand(MCOperand::CreateImm(32 - B)); 516 TmpInst.addOperand(MCOperand::CreateImm(B)); 517 TmpInst.addOperand(MCOperand::CreateImm((B + N) - 1)); 518 Inst = TmpInst; 519 break; 520 } 521 case PPC::INSRWI: 522 case PPC::INSRWIo: { 523 MCInst TmpInst; 524 int64_t N = Inst.getOperand(2).getImm(); 525 int64_t B = Inst.getOperand(3).getImm(); 526 TmpInst.setOpcode(Opcode == PPC::INSRWI? PPC::RLWIMI : PPC::RLWIMIo); 527 TmpInst.addOperand(Inst.getOperand(0)); 528 TmpInst.addOperand(Inst.getOperand(0)); 529 TmpInst.addOperand(Inst.getOperand(1)); 530 TmpInst.addOperand(MCOperand::CreateImm(32 - (B + N))); 531 TmpInst.addOperand(MCOperand::CreateImm(B)); 532 TmpInst.addOperand(MCOperand::CreateImm((B + N) - 1)); 533 Inst = TmpInst; 534 break; 535 } 536 case PPC::ROTRWI: 537 case PPC::ROTRWIo: { 538 MCInst TmpInst; 539 int64_t N = Inst.getOperand(2).getImm(); 540 TmpInst.setOpcode(Opcode == PPC::ROTRWI? PPC::RLWINM : PPC::RLWINMo); 541 TmpInst.addOperand(Inst.getOperand(0)); 542 TmpInst.addOperand(Inst.getOperand(1)); 543 TmpInst.addOperand(MCOperand::CreateImm(32 - N)); 544 TmpInst.addOperand(MCOperand::CreateImm(0)); 545 TmpInst.addOperand(MCOperand::CreateImm(31)); 546 Inst = TmpInst; 547 break; 548 } 549 case PPC::SLWI: 550 case PPC::SLWIo: { 551 MCInst TmpInst; 552 int64_t N = Inst.getOperand(2).getImm(); 553 TmpInst.setOpcode(Opcode == PPC::SLWI? PPC::RLWINM : PPC::RLWINMo); 554 TmpInst.addOperand(Inst.getOperand(0)); 555 TmpInst.addOperand(Inst.getOperand(1)); 556 TmpInst.addOperand(MCOperand::CreateImm(N)); 557 TmpInst.addOperand(MCOperand::CreateImm(0)); 558 TmpInst.addOperand(MCOperand::CreateImm(31 - N)); 559 Inst = TmpInst; 560 break; 561 } 562 case PPC::SRWI: 563 case PPC::SRWIo: { 564 MCInst TmpInst; 565 int64_t N = Inst.getOperand(2).getImm(); 566 TmpInst.setOpcode(Opcode == PPC::SRWI? PPC::RLWINM : PPC::RLWINMo); 567 TmpInst.addOperand(Inst.getOperand(0)); 568 TmpInst.addOperand(Inst.getOperand(1)); 569 TmpInst.addOperand(MCOperand::CreateImm(32 - N)); 570 TmpInst.addOperand(MCOperand::CreateImm(N)); 571 TmpInst.addOperand(MCOperand::CreateImm(31)); 572 Inst = TmpInst; 573 break; 574 } 575 case PPC::CLRRWI: 576 case PPC::CLRRWIo: { 577 MCInst TmpInst; 578 int64_t N = Inst.getOperand(2).getImm(); 579 TmpInst.setOpcode(Opcode == PPC::CLRRWI? PPC::RLWINM : PPC::RLWINMo); 580 TmpInst.addOperand(Inst.getOperand(0)); 581 TmpInst.addOperand(Inst.getOperand(1)); 582 TmpInst.addOperand(MCOperand::CreateImm(0)); 583 TmpInst.addOperand(MCOperand::CreateImm(0)); 584 TmpInst.addOperand(MCOperand::CreateImm(31 - N)); 585 Inst = TmpInst; 586 break; 587 } 588 case PPC::CLRLSLWI: 589 case PPC::CLRLSLWIo: { 590 MCInst TmpInst; 591 int64_t B = Inst.getOperand(2).getImm(); 592 int64_t N = Inst.getOperand(3).getImm(); 593 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI? PPC::RLWINM : PPC::RLWINMo); 594 TmpInst.addOperand(Inst.getOperand(0)); 595 TmpInst.addOperand(Inst.getOperand(1)); 596 TmpInst.addOperand(MCOperand::CreateImm(N)); 597 TmpInst.addOperand(MCOperand::CreateImm(B - N)); 598 TmpInst.addOperand(MCOperand::CreateImm(31 - N)); 599 Inst = TmpInst; 600 break; 601 } 602 case PPC::EXTLDI: 603 case PPC::EXTLDIo: { 604 MCInst TmpInst; 605 int64_t N = Inst.getOperand(2).getImm(); 606 int64_t B = Inst.getOperand(3).getImm(); 607 TmpInst.setOpcode(Opcode == PPC::EXTLDI? PPC::RLDICR : PPC::RLDICRo); 608 TmpInst.addOperand(Inst.getOperand(0)); 609 TmpInst.addOperand(Inst.getOperand(1)); 610 TmpInst.addOperand(MCOperand::CreateImm(B)); 611 TmpInst.addOperand(MCOperand::CreateImm(N - 1)); 612 Inst = TmpInst; 613 break; 614 } 615 case PPC::EXTRDI: 616 case PPC::EXTRDIo: { 617 MCInst TmpInst; 618 int64_t N = Inst.getOperand(2).getImm(); 619 int64_t B = Inst.getOperand(3).getImm(); 620 TmpInst.setOpcode(Opcode == PPC::EXTRDI? PPC::RLDICL : PPC::RLDICLo); 621 TmpInst.addOperand(Inst.getOperand(0)); 622 TmpInst.addOperand(Inst.getOperand(1)); 623 TmpInst.addOperand(MCOperand::CreateImm(B + N)); 624 TmpInst.addOperand(MCOperand::CreateImm(64 - N)); 625 Inst = TmpInst; 626 break; 627 } 628 case PPC::INSRDI: 629 case PPC::INSRDIo: { 630 MCInst TmpInst; 631 int64_t N = Inst.getOperand(2).getImm(); 632 int64_t B = Inst.getOperand(3).getImm(); 633 TmpInst.setOpcode(Opcode == PPC::INSRDI? PPC::RLDIMI : PPC::RLDIMIo); 634 TmpInst.addOperand(Inst.getOperand(0)); 635 TmpInst.addOperand(Inst.getOperand(0)); 636 TmpInst.addOperand(Inst.getOperand(1)); 637 TmpInst.addOperand(MCOperand::CreateImm(64 - (B + N))); 638 TmpInst.addOperand(MCOperand::CreateImm(B)); 639 Inst = TmpInst; 640 break; 641 } 642 case PPC::ROTRDI: 643 case PPC::ROTRDIo: { 644 MCInst TmpInst; 645 int64_t N = Inst.getOperand(2).getImm(); 646 TmpInst.setOpcode(Opcode == PPC::ROTRDI? PPC::RLDICL : PPC::RLDICLo); 647 TmpInst.addOperand(Inst.getOperand(0)); 648 TmpInst.addOperand(Inst.getOperand(1)); 649 TmpInst.addOperand(MCOperand::CreateImm(64 - N)); 650 TmpInst.addOperand(MCOperand::CreateImm(0)); 651 Inst = TmpInst; 652 break; 653 } 654 case PPC::SLDI: 655 case PPC::SLDIo: { 656 MCInst TmpInst; 657 int64_t N = Inst.getOperand(2).getImm(); 658 TmpInst.setOpcode(Opcode == PPC::SLDI? PPC::RLDICR : PPC::RLDICRo); 659 TmpInst.addOperand(Inst.getOperand(0)); 660 TmpInst.addOperand(Inst.getOperand(1)); 661 TmpInst.addOperand(MCOperand::CreateImm(N)); 662 TmpInst.addOperand(MCOperand::CreateImm(63 - N)); 663 Inst = TmpInst; 664 break; 665 } 666 case PPC::SRDI: 667 case PPC::SRDIo: { 668 MCInst TmpInst; 669 int64_t N = Inst.getOperand(2).getImm(); 670 TmpInst.setOpcode(Opcode == PPC::SRDI? PPC::RLDICL : PPC::RLDICLo); 671 TmpInst.addOperand(Inst.getOperand(0)); 672 TmpInst.addOperand(Inst.getOperand(1)); 673 TmpInst.addOperand(MCOperand::CreateImm(64 - N)); 674 TmpInst.addOperand(MCOperand::CreateImm(N)); 675 Inst = TmpInst; 676 break; 677 } 678 case PPC::CLRRDI: 679 case PPC::CLRRDIo: { 680 MCInst TmpInst; 681 int64_t N = Inst.getOperand(2).getImm(); 682 TmpInst.setOpcode(Opcode == PPC::CLRRDI? PPC::RLDICR : PPC::RLDICRo); 683 TmpInst.addOperand(Inst.getOperand(0)); 684 TmpInst.addOperand(Inst.getOperand(1)); 685 TmpInst.addOperand(MCOperand::CreateImm(0)); 686 TmpInst.addOperand(MCOperand::CreateImm(63 - N)); 687 Inst = TmpInst; 688 break; 689 } 690 case PPC::CLRLSLDI: 691 case PPC::CLRLSLDIo: { 692 MCInst TmpInst; 693 int64_t B = Inst.getOperand(2).getImm(); 694 int64_t N = Inst.getOperand(3).getImm(); 695 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI? PPC::RLDIC : PPC::RLDICo); 696 TmpInst.addOperand(Inst.getOperand(0)); 697 TmpInst.addOperand(Inst.getOperand(1)); 698 TmpInst.addOperand(MCOperand::CreateImm(N)); 699 TmpInst.addOperand(MCOperand::CreateImm(B - N)); 700 Inst = TmpInst; 701 break; 702 } 703 } 704 } 705 706 bool PPCAsmParser:: 707 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 708 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 709 MCStreamer &Out, unsigned &ErrorInfo, 710 bool MatchingInlineAsm) { 711 MCInst Inst; 712 713 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 714 default: break; 715 case Match_Success: 716 // Post-process instructions (typically extended mnemonics) 717 ProcessInstruction(Inst, Operands); 718 Inst.setLoc(IDLoc); 719 Out.EmitInstruction(Inst); 720 return false; 721 case Match_MissingFeature: 722 return Error(IDLoc, "instruction use requires an option to be enabled"); 723 case Match_MnemonicFail: 724 return Error(IDLoc, "unrecognized instruction mnemonic"); 725 case Match_InvalidOperand: { 726 SMLoc ErrorLoc = IDLoc; 727 if (ErrorInfo != ~0U) { 728 if (ErrorInfo >= Operands.size()) 729 return Error(IDLoc, "too few operands for instruction"); 730 731 ErrorLoc = ((PPCOperand*)Operands[ErrorInfo])->getStartLoc(); 732 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 733 } 734 735 return Error(ErrorLoc, "invalid operand for instruction"); 736 } 737 } 738 739 llvm_unreachable("Implement any new match types added!"); 740 } 741 742 bool PPCAsmParser:: 743 MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) { 744 if (Tok.is(AsmToken::Identifier)) { 745 StringRef Name = Tok.getString(); 746 747 if (Name.equals_lower("lr")) { 748 RegNo = isPPC64()? PPC::LR8 : PPC::LR; 749 IntVal = 8; 750 return false; 751 } else if (Name.equals_lower("ctr")) { 752 RegNo = isPPC64()? PPC::CTR8 : PPC::CTR; 753 IntVal = 9; 754 return false; 755 } else if (Name.equals_lower("vrsave")) { 756 RegNo = PPC::VRSAVE; 757 IntVal = 256; 758 return false; 759 } else if (Name.substr(0, 1).equals_lower("r") && 760 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 761 RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal]; 762 return false; 763 } else if (Name.substr(0, 1).equals_lower("f") && 764 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 765 RegNo = FRegs[IntVal]; 766 return false; 767 } else if (Name.substr(0, 1).equals_lower("v") && 768 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { 769 RegNo = VRegs[IntVal]; 770 return false; 771 } else if (Name.substr(0, 2).equals_lower("cr") && 772 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) { 773 RegNo = CRRegs[IntVal]; 774 return false; 775 } 776 } 777 778 return true; 779 } 780 781 bool PPCAsmParser:: 782 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { 783 const AsmToken &Tok = Parser.getTok(); 784 StartLoc = Tok.getLoc(); 785 EndLoc = Tok.getEndLoc(); 786 RegNo = 0; 787 int64_t IntVal; 788 789 if (!MatchRegisterName(Tok, RegNo, IntVal)) { 790 Parser.Lex(); // Eat identifier token. 791 return false; 792 } 793 794 return Error(StartLoc, "invalid register name"); 795 } 796 797 /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan 798 /// the expression and check for VK_PPC_LO/HI/HA 799 /// symbol variants. If all symbols with modifier use the same 800 /// variant, return the corresponding PPCMCExpr::VariantKind, 801 /// and a modified expression using the default symbol variant. 802 /// Otherwise, return NULL. 803 const MCExpr *PPCAsmParser:: 804 ExtractModifierFromExpr(const MCExpr *E, 805 PPCMCExpr::VariantKind &Variant) { 806 MCContext &Context = getParser().getContext(); 807 Variant = PPCMCExpr::VK_PPC_None; 808 809 switch (E->getKind()) { 810 case MCExpr::Target: 811 case MCExpr::Constant: 812 return 0; 813 814 case MCExpr::SymbolRef: { 815 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 816 817 switch (SRE->getKind()) { 818 case MCSymbolRefExpr::VK_PPC_LO: 819 Variant = PPCMCExpr::VK_PPC_LO; 820 break; 821 case MCSymbolRefExpr::VK_PPC_HI: 822 Variant = PPCMCExpr::VK_PPC_HI; 823 break; 824 case MCSymbolRefExpr::VK_PPC_HA: 825 Variant = PPCMCExpr::VK_PPC_HA; 826 break; 827 case MCSymbolRefExpr::VK_PPC_HIGHER: 828 Variant = PPCMCExpr::VK_PPC_HIGHER; 829 break; 830 case MCSymbolRefExpr::VK_PPC_HIGHERA: 831 Variant = PPCMCExpr::VK_PPC_HIGHERA; 832 break; 833 case MCSymbolRefExpr::VK_PPC_HIGHEST: 834 Variant = PPCMCExpr::VK_PPC_HIGHEST; 835 break; 836 case MCSymbolRefExpr::VK_PPC_HIGHESTA: 837 Variant = PPCMCExpr::VK_PPC_HIGHESTA; 838 break; 839 default: 840 return 0; 841 } 842 843 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Context); 844 } 845 846 case MCExpr::Unary: { 847 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 848 const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant); 849 if (!Sub) 850 return 0; 851 return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context); 852 } 853 854 case MCExpr::Binary: { 855 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 856 PPCMCExpr::VariantKind LHSVariant, RHSVariant; 857 const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant); 858 const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant); 859 860 if (!LHS && !RHS) 861 return 0; 862 863 if (!LHS) LHS = BE->getLHS(); 864 if (!RHS) RHS = BE->getRHS(); 865 866 if (LHSVariant == PPCMCExpr::VK_PPC_None) 867 Variant = RHSVariant; 868 else if (RHSVariant == PPCMCExpr::VK_PPC_None) 869 Variant = LHSVariant; 870 else if (LHSVariant == RHSVariant) 871 Variant = LHSVariant; 872 else 873 return 0; 874 875 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context); 876 } 877 } 878 879 llvm_unreachable("Invalid expression kind!"); 880 } 881 882 /// Parse an expression. This differs from the default "parseExpression" 883 /// in that it handles complex \code @l/@ha \endcode modifiers. 884 bool PPCAsmParser:: 885 ParseExpression(const MCExpr *&EVal) { 886 if (getParser().parseExpression(EVal)) 887 return true; 888 889 PPCMCExpr::VariantKind Variant; 890 const MCExpr *E = ExtractModifierFromExpr(EVal, Variant); 891 if (E) 892 EVal = PPCMCExpr::Create(Variant, E, getParser().getContext()); 893 894 return false; 895 } 896 897 bool PPCAsmParser:: 898 ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 899 SMLoc S = Parser.getTok().getLoc(); 900 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 901 const MCExpr *EVal; 902 PPCOperand *Op; 903 904 // Attempt to parse the next token as an immediate 905 switch (getLexer().getKind()) { 906 // Special handling for register names. These are interpreted 907 // as immediates corresponding to the register number. 908 case AsmToken::Percent: 909 Parser.Lex(); // Eat the '%'. 910 unsigned RegNo; 911 int64_t IntVal; 912 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) { 913 Parser.Lex(); // Eat the identifier token. 914 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 915 Operands.push_back(Op); 916 return false; 917 } 918 return Error(S, "invalid register name"); 919 920 // All other expressions 921 case AsmToken::LParen: 922 case AsmToken::Plus: 923 case AsmToken::Minus: 924 case AsmToken::Integer: 925 case AsmToken::Identifier: 926 case AsmToken::Dot: 927 case AsmToken::Dollar: 928 if (!ParseExpression(EVal)) 929 break; 930 /* fall through */ 931 default: 932 return Error(S, "unknown operand"); 933 } 934 935 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(EVal)) 936 Op = PPCOperand::CreateImm(CE->getValue(), S, E, isPPC64()); 937 else 938 Op = PPCOperand::CreateExpr(EVal, S, E, isPPC64()); 939 940 // Push the parsed operand into the list of operands 941 Operands.push_back(Op); 942 943 // Check whether this is a TLS call expression 944 bool TLSCall = false; 945 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) 946 TLSCall = Ref->getSymbol().getName() == "__tls_get_addr"; 947 948 if (TLSCall && getLexer().is(AsmToken::LParen)) { 949 const MCExpr *TLSSym; 950 951 Parser.Lex(); // Eat the '('. 952 S = Parser.getTok().getLoc(); 953 if (ParseExpression(TLSSym)) 954 return Error(S, "invalid TLS call expression"); 955 if (getLexer().isNot(AsmToken::RParen)) 956 return Error(Parser.getTok().getLoc(), "missing ')'"); 957 E = Parser.getTok().getLoc(); 958 Parser.Lex(); // Eat the ')'. 959 960 Op = PPCOperand::CreateExpr(TLSSym, S, E, isPPC64()); 961 Operands.push_back(Op); 962 } 963 964 // Otherwise, check for D-form memory operands 965 if (!TLSCall && getLexer().is(AsmToken::LParen)) { 966 Parser.Lex(); // Eat the '('. 967 S = Parser.getTok().getLoc(); 968 969 int64_t IntVal; 970 switch (getLexer().getKind()) { 971 case AsmToken::Percent: 972 Parser.Lex(); // Eat the '%'. 973 unsigned RegNo; 974 if (MatchRegisterName(Parser.getTok(), RegNo, IntVal)) 975 return Error(S, "invalid register name"); 976 Parser.Lex(); // Eat the identifier token. 977 break; 978 979 case AsmToken::Integer: 980 if (getParser().parseAbsoluteExpression(IntVal) || 981 IntVal < 0 || IntVal > 31) 982 return Error(S, "invalid register number"); 983 break; 984 985 default: 986 return Error(S, "invalid memory operand"); 987 } 988 989 if (getLexer().isNot(AsmToken::RParen)) 990 return Error(Parser.getTok().getLoc(), "missing ')'"); 991 E = Parser.getTok().getLoc(); 992 Parser.Lex(); // Eat the ')'. 993 994 Op = PPCOperand::CreateImm(IntVal, S, E, isPPC64()); 995 Operands.push_back(Op); 996 } 997 998 return false; 999 } 1000 1001 /// Parse an instruction mnemonic followed by its operands. 1002 bool PPCAsmParser:: 1003 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1004 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1005 // The first operand is the token for the instruction name. 1006 // If the next character is a '+' or '-', we need to add it to the 1007 // instruction name, to match what TableGen is doing. 1008 if (getLexer().is(AsmToken::Plus)) { 1009 getLexer().Lex(); 1010 char *NewOpcode = new char[Name.size() + 1]; 1011 memcpy(NewOpcode, Name.data(), Name.size()); 1012 NewOpcode[Name.size()] = '+'; 1013 Name = StringRef(NewOpcode, Name.size() + 1); 1014 } 1015 if (getLexer().is(AsmToken::Minus)) { 1016 getLexer().Lex(); 1017 char *NewOpcode = new char[Name.size() + 1]; 1018 memcpy(NewOpcode, Name.data(), Name.size()); 1019 NewOpcode[Name.size()] = '-'; 1020 Name = StringRef(NewOpcode, Name.size() + 1); 1021 } 1022 // If the instruction ends in a '.', we need to create a separate 1023 // token for it, to match what TableGen is doing. 1024 size_t Dot = Name.find('.'); 1025 StringRef Mnemonic = Name.slice(0, Dot); 1026 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); 1027 if (Dot != StringRef::npos) { 1028 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); 1029 StringRef DotStr = Name.slice(Dot, StringRef::npos); 1030 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); 1031 } 1032 1033 // If there are no more operands then finish 1034 if (getLexer().is(AsmToken::EndOfStatement)) 1035 return false; 1036 1037 // Parse the first operand 1038 if (ParseOperand(Operands)) 1039 return true; 1040 1041 while (getLexer().isNot(AsmToken::EndOfStatement) && 1042 getLexer().is(AsmToken::Comma)) { 1043 // Consume the comma token 1044 getLexer().Lex(); 1045 1046 // Parse the next operand 1047 if (ParseOperand(Operands)) 1048 return true; 1049 } 1050 1051 return false; 1052 } 1053 1054 /// ParseDirective parses the PPC specific directives 1055 bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) { 1056 StringRef IDVal = DirectiveID.getIdentifier(); 1057 if (IDVal == ".word") 1058 return ParseDirectiveWord(4, DirectiveID.getLoc()); 1059 if (IDVal == ".tc") 1060 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc()); 1061 return true; 1062 } 1063 1064 /// ParseDirectiveWord 1065 /// ::= .word [ expression (, expression)* ] 1066 bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1067 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1068 for (;;) { 1069 const MCExpr *Value; 1070 if (getParser().parseExpression(Value)) 1071 return true; 1072 1073 getParser().getStreamer().EmitValue(Value, Size); 1074 1075 if (getLexer().is(AsmToken::EndOfStatement)) 1076 break; 1077 1078 if (getLexer().isNot(AsmToken::Comma)) 1079 return Error(L, "unexpected token in directive"); 1080 Parser.Lex(); 1081 } 1082 } 1083 1084 Parser.Lex(); 1085 return false; 1086 } 1087 1088 /// ParseDirectiveTC 1089 /// ::= .tc [ symbol (, expression)* ] 1090 bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) { 1091 // Skip TC symbol, which is only used with XCOFF. 1092 while (getLexer().isNot(AsmToken::EndOfStatement) 1093 && getLexer().isNot(AsmToken::Comma)) 1094 Parser.Lex(); 1095 if (getLexer().isNot(AsmToken::Comma)) 1096 return Error(L, "unexpected token in directive"); 1097 Parser.Lex(); 1098 1099 // Align to word size. 1100 getParser().getStreamer().EmitValueToAlignment(Size); 1101 1102 // Emit expressions. 1103 return ParseDirectiveWord(Size, L); 1104 } 1105 1106 /// Force static initialization. 1107 extern "C" void LLVMInitializePowerPCAsmParser() { 1108 RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target); 1109 RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target); 1110 } 1111 1112 #define GET_REGISTER_MATCHER 1113 #define GET_MATCHER_IMPLEMENTATION 1114 #include "PPCGenAsmMatcher.inc" 1115