1839 lines · cpp
1//===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/PPCMCAsmInfo.h"10#include "MCTargetDesc/PPCMCTargetDesc.h"11#include "MCTargetDesc/PPCTargetStreamer.h"12#include "PPCInstrInfo.h"13#include "TargetInfo/PowerPCTargetInfo.h"14#include "llvm/ADT/Twine.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCInstrInfo.h"19#include "llvm/MC/MCParser/AsmLexer.h"20#include "llvm/MC/MCParser/MCAsmParser.h"21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"22#include "llvm/MC/MCParser/MCTargetAsmParser.h"23#include "llvm/MC/MCStreamer.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/MCSymbolELF.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Support/SourceMgr.h"29#include "llvm/Support/raw_ostream.h"30 31using namespace llvm;32 33DEFINE_PPC_REGCLASSES34 35// Evaluate an expression containing condition register36// or condition register field symbols. Returns positive37// value on success, or -1 on error.38static int64_t39EvaluateCRExpr(const MCExpr *E) {40 switch (E->getKind()) {41 case MCExpr::Constant: {42 int64_t Res = cast<MCConstantExpr>(E)->getValue();43 return Res < 0 ? -1 : Res;44 }45 46 case MCExpr::SymbolRef: {47 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);48 StringRef Name = SRE->getSymbol().getName();49 50 if (Name == "lt") return 0;51 if (Name == "gt") return 1;52 if (Name == "eq") return 2;53 if (Name == "so") return 3;54 if (Name == "un") return 3;55 56 if (Name == "cr0") return 0;57 if (Name == "cr1") return 1;58 if (Name == "cr2") return 2;59 if (Name == "cr3") return 3;60 if (Name == "cr4") return 4;61 if (Name == "cr5") return 5;62 if (Name == "cr6") return 6;63 if (Name == "cr7") return 7;64 65 return -1;66 }67 68 case MCExpr::Unary:69 return -1;70 71 case MCExpr::Binary: {72 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);73 int64_t LHSVal = EvaluateCRExpr(BE->getLHS());74 int64_t RHSVal = EvaluateCRExpr(BE->getRHS());75 int64_t Res;76 77 if (LHSVal < 0 || RHSVal < 0)78 return -1;79 80 switch (BE->getOpcode()) {81 default: return -1;82 case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;83 case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;84 }85 86 return Res < 0 ? -1 : Res;87 }88 case MCExpr::Specifier:89 return -1;90 case MCExpr::Target:91 llvm_unreachable("unused by this backend");92 }93 94 llvm_unreachable("Invalid expression kind!");95}96 97namespace {98 99struct PPCOperand;100 101class PPCAsmParser : public MCTargetAsmParser {102 const bool IsPPC64;103 104 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }105 106 bool isPPC64() const { return IsPPC64; }107 108 MCRegister matchRegisterName(int64_t &IntVal);109 110 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;111 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,112 SMLoc &EndLoc) override;113 114 const MCExpr *extractSpecifier(const MCExpr *E,115 PPCMCExpr::Specifier &Variant);116 bool parseExpression(const MCExpr *&EVal);117 118 bool parseOperand(OperandVector &Operands);119 120 bool parseDirectiveWord(unsigned Size, AsmToken ID);121 bool parseDirectiveTC(unsigned Size, AsmToken ID);122 bool parseDirectiveMachine(SMLoc L);123 bool parseDirectiveAbiVersion(SMLoc L);124 bool parseDirectiveLocalEntry(SMLoc L);125 bool parseGNUAttribute(SMLoc L);126 127 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,128 OperandVector &Operands, MCStreamer &Out,129 uint64_t &ErrorInfo,130 bool MatchingInlineAsm) override;131 132 void processInstruction(MCInst &Inst, const OperandVector &Ops);133 134 /// @name Auto-generated Match Functions135 /// {136 137#define GET_ASSEMBLER_HEADER138#include "PPCGenAsmMatcher.inc"139 140 /// }141 142 143public:144 PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,145 const MCInstrInfo &MII, const MCTargetOptions &Options)146 : MCTargetAsmParser(Options, STI, MII),147 IsPPC64(STI.getTargetTriple().isPPC64()) {148 // Initialize the set of available features.149 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));150 }151 152 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,153 SMLoc NameLoc, OperandVector &Operands) override;154 155 bool ParseDirective(AsmToken DirectiveID) override;156 157 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,158 unsigned Kind) override;159 160 const MCExpr *applySpecifier(const MCExpr *E, uint32_t,161 MCContext &Ctx) override;162};163 164/// PPCOperand - Instances of this class represent a parsed PowerPC machine165/// instruction.166struct PPCOperand : public MCParsedAsmOperand {167 enum KindTy {168 Token,169 Immediate,170 ContextImmediate,171 Expression,172 TLSRegister173 } Kind;174 175 SMLoc StartLoc, EndLoc;176 bool IsPPC64;177 178 struct TokOp {179 const char *Data;180 unsigned Length;181 };182 183 struct ImmOp {184 int64_t Val;185 bool IsMemOpBase;186 };187 188 struct ExprOp {189 const MCExpr *Val;190 int64_t CRVal; // Cached result of EvaluateCRExpr(Val)191 };192 193 struct TLSRegOp {194 const MCSymbolRefExpr *Sym;195 };196 197 union {198 struct TokOp Tok;199 struct ImmOp Imm;200 struct ExprOp Expr;201 struct TLSRegOp TLSReg;202 };203 204 PPCOperand(KindTy K) : Kind(K) {}205 206public:207 PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {208 Kind = o.Kind;209 StartLoc = o.StartLoc;210 EndLoc = o.EndLoc;211 IsPPC64 = o.IsPPC64;212 switch (Kind) {213 case Token:214 Tok = o.Tok;215 break;216 case Immediate:217 case ContextImmediate:218 Imm = o.Imm;219 break;220 case Expression:221 Expr = o.Expr;222 break;223 case TLSRegister:224 TLSReg = o.TLSReg;225 break;226 }227 }228 229 // Disable use of sized deallocation due to overallocation of PPCOperand230 // objects in CreateTokenWithStringCopy.231 void operator delete(void *p) { ::operator delete(p); }232 233 /// getStartLoc - Get the location of the first token of this operand.234 SMLoc getStartLoc() const override { return StartLoc; }235 236 /// getEndLoc - Get the location of the last token of this operand.237 SMLoc getEndLoc() const override { return EndLoc; }238 239 /// getLocRange - Get the range between the first and last token of this240 /// operand.241 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }242 243 /// isPPC64 - True if this operand is for an instruction in 64-bit mode.244 bool isPPC64() const { return IsPPC64; }245 246 /// isMemOpBase - True if this operand is the base of a memory operand.247 bool isMemOpBase() const { return Kind == Immediate && Imm.IsMemOpBase; }248 249 int64_t getImm() const {250 assert(Kind == Immediate && "Invalid access!");251 return Imm.Val;252 }253 int64_t getImmS16Context() const {254 assert((Kind == Immediate || Kind == ContextImmediate) &&255 "Invalid access!");256 if (Kind == Immediate)257 return Imm.Val;258 return static_cast<int16_t>(Imm.Val);259 }260 int64_t getImmU16Context() const {261 assert((Kind == Immediate || Kind == ContextImmediate) &&262 "Invalid access!");263 return Imm.Val;264 }265 266 const MCExpr *getExpr() const {267 assert(Kind == Expression && "Invalid access!");268 return Expr.Val;269 }270 271 int64_t getExprCRVal() const {272 assert(Kind == Expression && "Invalid access!");273 return Expr.CRVal;274 }275 276 const MCExpr *getTLSReg() const {277 assert(Kind == TLSRegister && "Invalid access!");278 return TLSReg.Sym;279 }280 281 MCRegister getReg() const override { llvm_unreachable("Not implemented"); }282 283 unsigned getRegNum() const {284 assert(isRegNumber() && "Invalid access!");285 return (unsigned)Imm.Val;286 }287 288 unsigned getFpReg() const {289 assert(isEvenRegNumber() && "Invalid access!");290 return (unsigned)(Imm.Val >> 1);291 }292 293 unsigned getVSReg() const {294 assert(isVSRegNumber() && "Invalid access!");295 return (unsigned) Imm.Val;296 }297 298 unsigned getACCReg() const {299 assert(isACCRegNumber() && "Invalid access!");300 return (unsigned) Imm.Val;301 }302 303 unsigned getDMRROWReg() const {304 assert(isDMRROWRegNumber() && "Invalid access!");305 return (unsigned)Imm.Val;306 }307 308 unsigned getDMRROWpReg() const {309 assert(isDMRROWpRegNumber() && "Invalid access!");310 return (unsigned)Imm.Val;311 }312 313 unsigned getDMRReg() const {314 assert(isDMRRegNumber() && "Invalid access!");315 return (unsigned)Imm.Val;316 }317 318 unsigned getDMRpReg() const {319 assert(isDMRpRegNumber() && "Invalid access!");320 return (unsigned)Imm.Val;321 }322 323 unsigned getVSRpEvenReg() const {324 assert(isVSRpEvenRegNumber() && "Invalid access!");325 return (unsigned) Imm.Val >> 1;326 }327 328 unsigned getG8pReg() const {329 assert(isEvenRegNumber() && "Invalid access!");330 return (unsigned)Imm.Val;331 }332 333 unsigned getCCReg() const {334 assert(isCCRegNumber() && "Invalid access!");335 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);336 }337 338 unsigned getCRBit() const {339 assert(isCRBitNumber() && "Invalid access!");340 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);341 }342 343 unsigned getCRBitMask() const {344 assert(isCRBitMask() && "Invalid access!");345 return 7 - llvm::countr_zero<uint64_t>(Imm.Val);346 }347 348 bool isToken() const override { return Kind == Token; }349 bool isImm() const override {350 return Kind == Immediate || Kind == Expression;351 }352 353 template <uint64_t N> bool isUImm() const {354 return Kind == Immediate && isUInt<N>(getImm());355 }356 template <uint64_t N> bool isSImm() const {357 return Kind == Immediate && isInt<N>(getImm());358 }359 bool isU6ImmX2() const { return isUImm<6>() && (getImm() & 1) == 0; }360 bool isU7ImmX4() const { return isUImm<7>() && (getImm() & 3) == 0; }361 bool isU8ImmX8() const { return isUImm<8>() && (getImm() & 7) == 0; }362 363 bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }364 bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }365 bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }366 bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }367 bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }368 bool isS32Imm() const {369 // TODO: Is ContextImmediate needed?370 return Kind == Expression || isSImm<32>();371 }372 bool isS34Imm() const {373 // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit374 // ContextImmediate is needed.375 return Kind == Expression || isSImm<34>();376 }377 bool isS34ImmX16() const {378 return Kind == Expression || (isSImm<34>() && (getImm() & 15) == 0);379 }380 381 bool isHashImmX8() const {382 // The Hash Imm form is used for instructions that check or store a hash.383 // These instructions have a small immediate range that spans between384 // -8 and -512.385 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&386 (getImm() & 7) == 0);387 }388 389 bool isTLSReg() const { return Kind == TLSRegister; }390 bool isDirectBr() const {391 if (Kind == Expression)392 return true;393 if (Kind != Immediate)394 return false;395 // Operand must be 64-bit aligned, signed 27-bit immediate.396 if ((getImm() & 3) != 0)397 return false;398 if (isInt<26>(getImm()))399 return true;400 if (!IsPPC64) {401 // In 32-bit mode, large 32-bit quantities wrap around.402 if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))403 return true;404 }405 return false;406 }407 bool isCondBr() const { return Kind == Expression ||408 (Kind == Immediate && isInt<16>(getImm()) &&409 (getImm() & 3) == 0); }410 bool isImmZero() const { return Kind == Immediate && getImm() == 0; }411 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }412 bool isACCRegNumber() const {413 return Kind == Immediate && isUInt<3>(getImm());414 }415 bool isDMRROWRegNumber() const {416 return Kind == Immediate && isUInt<6>(getImm());417 }418 bool isDMRROWpRegNumber() const {419 return Kind == Immediate && isUInt<5>(getImm());420 }421 bool isDMRRegNumber() const {422 return Kind == Immediate && isUInt<3>(getImm());423 }424 bool isDMRpRegNumber() const {425 return Kind == Immediate && isUInt<2>(getImm());426 }427 bool isVSRpEvenRegNumber() const {428 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);429 }430 bool isVSRegNumber() const {431 return Kind == Immediate && isUInt<6>(getImm());432 }433 bool isCCRegNumber() const { return (Kind == Expression434 && isUInt<3>(getExprCRVal())) ||435 (Kind == Immediate436 && isUInt<3>(getImm())); }437 bool isCRBitNumber() const { return (Kind == Expression438 && isUInt<5>(getExprCRVal())) ||439 (Kind == Immediate440 && isUInt<5>(getImm())); }441 442 bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }443 444 bool isCRBitMask() const {445 return Kind == Immediate && isUInt<8>(getImm()) &&446 llvm::has_single_bit<uint32_t>(getImm());447 }448 bool isATBitsAsHint() const { return false; }449 bool isMem() const override { return false; }450 bool isReg() const override { return false; }451 452 void addRegOperands(MCInst &Inst, unsigned N) const {453 llvm_unreachable("addRegOperands");454 }455 456 void addRegGPRCOperands(MCInst &Inst, unsigned N) const {457 assert(N == 1 && "Invalid number of operands!");458 Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));459 }460 461 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {462 assert(N == 1 && "Invalid number of operands!");463 Inst.addOperand(MCOperand::createReg(RRegsNoR0[getRegNum()]));464 }465 466 void addRegG8RCOperands(MCInst &Inst, unsigned N) const {467 assert(N == 1 && "Invalid number of operands!");468 Inst.addOperand(MCOperand::createReg(XRegs[getRegNum()]));469 }470 471 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {472 assert(N == 1 && "Invalid number of operands!");473 Inst.addOperand(MCOperand::createReg(XRegsNoX0[getRegNum()]));474 }475 476 void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {477 assert(N == 1 && "Invalid number of operands!");478 Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));479 }480 481 void addRegGxRCOperands(MCInst &Inst, unsigned N) const {482 if (isPPC64())483 addRegG8RCOperands(Inst, N);484 else485 addRegGPRCOperands(Inst, N);486 }487 488 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {489 if (isPPC64())490 addRegG8RCNoX0Operands(Inst, N);491 else492 addRegGPRCNoR0Operands(Inst, N);493 }494 495 void addRegF4RCOperands(MCInst &Inst, unsigned N) const {496 assert(N == 1 && "Invalid number of operands!");497 Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));498 }499 500 void addRegF8RCOperands(MCInst &Inst, unsigned N) const {501 assert(N == 1 && "Invalid number of operands!");502 Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));503 }504 505 void addRegFpRCOperands(MCInst &Inst, unsigned N) const {506 assert(N == 1 && "Invalid number of operands!");507 Inst.addOperand(MCOperand::createReg(FpRegs[getFpReg()]));508 }509 510 void addRegVFRCOperands(MCInst &Inst, unsigned N) const {511 assert(N == 1 && "Invalid number of operands!");512 Inst.addOperand(MCOperand::createReg(VFRegs[getRegNum()]));513 }514 515 void addRegVRRCOperands(MCInst &Inst, unsigned N) const {516 assert(N == 1 && "Invalid number of operands!");517 Inst.addOperand(MCOperand::createReg(VRegs[getRegNum()]));518 }519 520 void addRegVSRCOperands(MCInst &Inst, unsigned N) const {521 assert(N == 1 && "Invalid number of operands!");522 Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));523 }524 525 void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {526 assert(N == 1 && "Invalid number of operands!");527 Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));528 }529 530 void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {531 assert(N == 1 && "Invalid number of operands!");532 Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));533 }534 535 void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {536 assert(N == 1 && "Invalid number of operands!");537 Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));538 }539 540 void addRegSPERCOperands(MCInst &Inst, unsigned N) const {541 assert(N == 1 && "Invalid number of operands!");542 Inst.addOperand(MCOperand::createReg(SPERegs[getRegNum()]));543 }544 545 void addRegACCRCOperands(MCInst &Inst, unsigned N) const {546 assert(N == 1 && "Invalid number of operands!");547 Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));548 }549 550 void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const {551 assert(N == 1 && "Invalid number of operands!");552 Inst.addOperand(MCOperand::createReg(DMRROWRegs[getDMRROWReg()]));553 }554 555 void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const {556 assert(N == 1 && "Invalid number of operands!");557 Inst.addOperand(MCOperand::createReg(DMRROWpRegs[getDMRROWpReg()]));558 }559 560 void addRegDMRRCOperands(MCInst &Inst, unsigned N) const {561 assert(N == 1 && "Invalid number of operands!");562 Inst.addOperand(MCOperand::createReg(DMRRegs[getDMRReg()]));563 }564 565 void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const {566 assert(N == 1 && "Invalid number of operands!");567 Inst.addOperand(MCOperand::createReg(DMRpRegs[getDMRpReg()]));568 }569 570 void addRegWACCRCOperands(MCInst &Inst, unsigned N) const {571 assert(N == 1 && "Invalid number of operands!");572 Inst.addOperand(MCOperand::createReg(WACCRegs[getACCReg()]));573 }574 575 void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const {576 assert(N == 1 && "Invalid number of operands!");577 Inst.addOperand(MCOperand::createReg(WACC_HIRegs[getACCReg()]));578 }579 580 void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {581 assert(N == 1 && "Invalid number of operands!");582 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));583 }584 585 void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {586 assert(N == 1 && "Invalid number of operands!");587 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));588 }589 590 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {591 assert(N == 1 && "Invalid number of operands!");592 Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));593 }594 595 void addRegCRRCOperands(MCInst &Inst, unsigned N) const {596 assert(N == 1 && "Invalid number of operands!");597 Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));598 }599 600 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {601 assert(N == 1 && "Invalid number of operands!");602 Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));603 }604 605 void addImmOperands(MCInst &Inst, unsigned N) const {606 assert(N == 1 && "Invalid number of operands!");607 if (Kind == Immediate)608 Inst.addOperand(MCOperand::createImm(getImm()));609 else610 Inst.addOperand(MCOperand::createExpr(getExpr()));611 }612 613 void addS16ImmOperands(MCInst &Inst, unsigned N) const {614 assert(N == 1 && "Invalid number of operands!");615 switch (Kind) {616 case Immediate:617 Inst.addOperand(MCOperand::createImm(getImm()));618 break;619 case ContextImmediate:620 Inst.addOperand(MCOperand::createImm(getImmS16Context()));621 break;622 default:623 Inst.addOperand(MCOperand::createExpr(getExpr()));624 break;625 }626 }627 628 void addU16ImmOperands(MCInst &Inst, unsigned N) const {629 assert(N == 1 && "Invalid number of operands!");630 switch (Kind) {631 case Immediate:632 Inst.addOperand(MCOperand::createImm(getImm()));633 break;634 case ContextImmediate:635 Inst.addOperand(MCOperand::createImm(getImmU16Context()));636 break;637 default:638 Inst.addOperand(MCOperand::createExpr(getExpr()));639 break;640 }641 }642 643 void addBranchTargetOperands(MCInst &Inst, unsigned N) const {644 assert(N == 1 && "Invalid number of operands!");645 if (Kind == Immediate)646 Inst.addOperand(MCOperand::createImm(getImm() / 4));647 else648 Inst.addOperand(MCOperand::createExpr(getExpr()));649 }650 651 void addTLSRegOperands(MCInst &Inst, unsigned N) const {652 assert(N == 1 && "Invalid number of operands!");653 Inst.addOperand(MCOperand::createExpr(getTLSReg()));654 }655 656 StringRef getToken() const {657 assert(Kind == Token && "Invalid access!");658 return StringRef(Tok.Data, Tok.Length);659 }660 661 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;662 663 static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,664 bool IsPPC64) {665 auto Op = std::make_unique<PPCOperand>(Token);666 Op->Tok.Data = Str.data();667 Op->Tok.Length = Str.size();668 Op->StartLoc = S;669 Op->EndLoc = S;670 Op->IsPPC64 = IsPPC64;671 return Op;672 }673 674 static std::unique_ptr<PPCOperand>675 CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {676 // Allocate extra memory for the string and copy it.677 // FIXME: This is incorrect, Operands are owned by unique_ptr with a default678 // deleter which will destroy them by simply using "delete", not correctly679 // calling operator delete on this extra memory after calling the dtor680 // explicitly.681 void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());682 std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));683 Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);684 Op->Tok.Length = Str.size();685 std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());686 Op->StartLoc = S;687 Op->EndLoc = S;688 Op->IsPPC64 = IsPPC64;689 return Op;690 }691 692 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,693 bool IsPPC64,694 bool IsMemOpBase = false) {695 auto Op = std::make_unique<PPCOperand>(Immediate);696 Op->Imm.Val = Val;697 Op->Imm.IsMemOpBase = IsMemOpBase;698 Op->StartLoc = S;699 Op->EndLoc = E;700 Op->IsPPC64 = IsPPC64;701 return Op;702 }703 704 static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,705 SMLoc E, bool IsPPC64) {706 auto Op = std::make_unique<PPCOperand>(Expression);707 Op->Expr.Val = Val;708 Op->Expr.CRVal = EvaluateCRExpr(Val);709 Op->StartLoc = S;710 Op->EndLoc = E;711 Op->IsPPC64 = IsPPC64;712 return Op;713 }714 715 static std::unique_ptr<PPCOperand>716 CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {717 auto Op = std::make_unique<PPCOperand>(TLSRegister);718 Op->TLSReg.Sym = Sym;719 Op->StartLoc = S;720 Op->EndLoc = E;721 Op->IsPPC64 = IsPPC64;722 return Op;723 }724 725 static std::unique_ptr<PPCOperand>726 CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {727 auto Op = std::make_unique<PPCOperand>(ContextImmediate);728 Op->Imm.Val = Val;729 Op->StartLoc = S;730 Op->EndLoc = E;731 Op->IsPPC64 = IsPPC64;732 return Op;733 }734 735 static std::unique_ptr<PPCOperand>736 CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {737 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))738 return CreateImm(CE->getValue(), S, E, IsPPC64);739 740 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))741 if (getSpecifier(SRE) == PPC::S_TLS ||742 getSpecifier(SRE) == PPC::S_TLS_PCREL)743 return CreateTLSReg(SRE, S, E, IsPPC64);744 745 if (const auto *SE = dyn_cast<MCSpecifierExpr>(Val)) {746 int64_t Res;747 if (PPC::evaluateAsConstant(*SE, Res))748 return CreateContextImm(Res, S, E, IsPPC64);749 }750 751 return CreateExpr(Val, S, E, IsPPC64);752 }753 754private:755 template <unsigned Width>756 bool isExtImm(bool Signed, unsigned Multiple) const {757 switch (Kind) {758 default:759 return false;760 case Expression:761 return true;762 case Immediate:763 case ContextImmediate:764 if (Signed)765 return isInt<Width>(getImmS16Context()) &&766 (getImmS16Context() & (Multiple - 1)) == 0;767 else768 return isUInt<Width>(getImmU16Context()) &&769 (getImmU16Context() & (Multiple - 1)) == 0;770 }771 }772};773 774} // end anonymous namespace.775 776void PPCOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {777 switch (Kind) {778 case Token:779 OS << "'" << getToken() << "'";780 break;781 case Immediate:782 case ContextImmediate:783 OS << getImm();784 break;785 case Expression:786 MAI.printExpr(OS, *getExpr());787 break;788 case TLSRegister:789 MAI.printExpr(OS, *getTLSReg());790 break;791 }792}793 794static void795addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {796 if (Op.isImm()) {797 Inst.addOperand(MCOperand::createImm(-Op.getImm()));798 return;799 }800 const MCExpr *Expr = Op.getExpr();801 if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {802 if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {803 Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));804 return;805 }806 } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {807 if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {808 const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),809 BinExpr->getLHS(), Ctx);810 Inst.addOperand(MCOperand::createExpr(NE));811 return;812 }813 }814 Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));815}816 817void PPCAsmParser::processInstruction(MCInst &Inst,818 const OperandVector &Operands) {819 int Opcode = Inst.getOpcode();820 switch (Opcode) {821 case PPC::DCBTx:822 case PPC::DCBTT:823 case PPC::DCBTSTx:824 case PPC::DCBTSTT: {825 MCInst TmpInst;826 TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?827 PPC::DCBT : PPC::DCBTST);828 TmpInst.addOperand(MCOperand::createImm(829 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));830 TmpInst.addOperand(Inst.getOperand(0));831 TmpInst.addOperand(Inst.getOperand(1));832 Inst = TmpInst;833 break;834 }835 case PPC::DCBTCT:836 case PPC::DCBTDS: {837 MCInst TmpInst;838 TmpInst.setOpcode(PPC::DCBT);839 TmpInst.addOperand(Inst.getOperand(2));840 TmpInst.addOperand(Inst.getOperand(0));841 TmpInst.addOperand(Inst.getOperand(1));842 Inst = TmpInst;843 break;844 }845 case PPC::DCBTSTCT:846 case PPC::DCBTSTDS: {847 MCInst TmpInst;848 TmpInst.setOpcode(PPC::DCBTST);849 TmpInst.addOperand(Inst.getOperand(2));850 TmpInst.addOperand(Inst.getOperand(0));851 TmpInst.addOperand(Inst.getOperand(1));852 Inst = TmpInst;853 break;854 }855 case PPC::DCBFx:856 case PPC::DCBFL:857 case PPC::DCBFLP:858 case PPC::DCBFPS:859 case PPC::DCBSTPS: {860 int L = 0;861 if (Opcode == PPC::DCBFL)862 L = 1;863 else if (Opcode == PPC::DCBFLP)864 L = 3;865 else if (Opcode == PPC::DCBFPS)866 L = 4;867 else if (Opcode == PPC::DCBSTPS)868 L = 6;869 870 MCInst TmpInst;871 TmpInst.setOpcode(PPC::DCBF);872 TmpInst.addOperand(MCOperand::createImm(L));873 TmpInst.addOperand(Inst.getOperand(0));874 TmpInst.addOperand(Inst.getOperand(1));875 Inst = TmpInst;876 break;877 }878 case PPC::LAx: {879 MCInst TmpInst;880 TmpInst.setOpcode(PPC::LA);881 TmpInst.addOperand(Inst.getOperand(0));882 TmpInst.addOperand(Inst.getOperand(2));883 TmpInst.addOperand(Inst.getOperand(1));884 Inst = TmpInst;885 break;886 }887 case PPC::PLA8:888 case PPC::PLA: {889 MCInst TmpInst;890 TmpInst.setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);891 TmpInst.addOperand(Inst.getOperand(0));892 TmpInst.addOperand(Inst.getOperand(1));893 TmpInst.addOperand(Inst.getOperand(2));894 Inst = TmpInst;895 break;896 }897 case PPC::PLA8pc:898 case PPC::PLApc: {899 MCInst TmpInst;900 TmpInst.setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);901 TmpInst.addOperand(Inst.getOperand(0));902 TmpInst.addOperand(MCOperand::createImm(0));903 TmpInst.addOperand(Inst.getOperand(1));904 Inst = TmpInst;905 break;906 }907 case PPC::SUBI: {908 MCInst TmpInst;909 TmpInst.setOpcode(PPC::ADDI);910 TmpInst.addOperand(Inst.getOperand(0));911 TmpInst.addOperand(Inst.getOperand(1));912 addNegOperand(TmpInst, Inst.getOperand(2), getContext());913 Inst = TmpInst;914 break;915 }916 case PPC::PSUBI: {917 MCInst TmpInst;918 TmpInst.setOpcode(PPC::PADDI);919 TmpInst.addOperand(Inst.getOperand(0));920 TmpInst.addOperand(Inst.getOperand(1));921 addNegOperand(TmpInst, Inst.getOperand(2), getContext());922 Inst = TmpInst;923 break;924 }925 case PPC::SUBIS: {926 MCInst TmpInst;927 TmpInst.setOpcode(PPC::ADDIS);928 TmpInst.addOperand(Inst.getOperand(0));929 TmpInst.addOperand(Inst.getOperand(1));930 addNegOperand(TmpInst, Inst.getOperand(2), getContext());931 Inst = TmpInst;932 break;933 }934 case PPC::SUBIC: {935 MCInst TmpInst;936 TmpInst.setOpcode(PPC::ADDIC);937 TmpInst.addOperand(Inst.getOperand(0));938 TmpInst.addOperand(Inst.getOperand(1));939 addNegOperand(TmpInst, Inst.getOperand(2), getContext());940 Inst = TmpInst;941 break;942 }943 case PPC::SUBIC_rec: {944 MCInst TmpInst;945 TmpInst.setOpcode(PPC::ADDIC_rec);946 TmpInst.addOperand(Inst.getOperand(0));947 TmpInst.addOperand(Inst.getOperand(1));948 addNegOperand(TmpInst, Inst.getOperand(2), getContext());949 Inst = TmpInst;950 break;951 }952 case PPC::EXTLWI:953 case PPC::EXTLWI_rec: {954 MCInst TmpInst;955 int64_t N = Inst.getOperand(2).getImm();956 int64_t B = Inst.getOperand(3).getImm();957 TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);958 TmpInst.addOperand(Inst.getOperand(0));959 TmpInst.addOperand(Inst.getOperand(1));960 TmpInst.addOperand(MCOperand::createImm(B));961 TmpInst.addOperand(MCOperand::createImm(0));962 TmpInst.addOperand(MCOperand::createImm(N - 1));963 Inst = TmpInst;964 break;965 }966 case PPC::EXTRWI:967 case PPC::EXTRWI_rec: {968 MCInst TmpInst;969 int64_t N = Inst.getOperand(2).getImm();970 int64_t B = Inst.getOperand(3).getImm();971 TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);972 TmpInst.addOperand(Inst.getOperand(0));973 TmpInst.addOperand(Inst.getOperand(1));974 TmpInst.addOperand(MCOperand::createImm(B + N));975 TmpInst.addOperand(MCOperand::createImm(32 - N));976 TmpInst.addOperand(MCOperand::createImm(31));977 Inst = TmpInst;978 break;979 }980 case PPC::INSLWI:981 case PPC::INSLWI_rec: {982 MCInst TmpInst;983 int64_t N = Inst.getOperand(2).getImm();984 int64_t B = Inst.getOperand(3).getImm();985 TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);986 TmpInst.addOperand(Inst.getOperand(0));987 TmpInst.addOperand(Inst.getOperand(0));988 TmpInst.addOperand(Inst.getOperand(1));989 TmpInst.addOperand(MCOperand::createImm(32 - B));990 TmpInst.addOperand(MCOperand::createImm(B));991 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));992 Inst = TmpInst;993 break;994 }995 case PPC::INSRWI:996 case PPC::INSRWI_rec: {997 MCInst TmpInst;998 int64_t N = Inst.getOperand(2).getImm();999 int64_t B = Inst.getOperand(3).getImm();1000 TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);1001 TmpInst.addOperand(Inst.getOperand(0));1002 TmpInst.addOperand(Inst.getOperand(0));1003 TmpInst.addOperand(Inst.getOperand(1));1004 TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));1005 TmpInst.addOperand(MCOperand::createImm(B));1006 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));1007 Inst = TmpInst;1008 break;1009 }1010 case PPC::ROTRWI:1011 case PPC::ROTRWI_rec: {1012 MCInst TmpInst;1013 int64_t N = Inst.getOperand(2).getImm();1014 TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);1015 TmpInst.addOperand(Inst.getOperand(0));1016 TmpInst.addOperand(Inst.getOperand(1));1017 TmpInst.addOperand(MCOperand::createImm(32 - N));1018 TmpInst.addOperand(MCOperand::createImm(0));1019 TmpInst.addOperand(MCOperand::createImm(31));1020 Inst = TmpInst;1021 break;1022 }1023 case PPC::SLWI:1024 case PPC::SLWI_rec: {1025 MCInst TmpInst;1026 int64_t N = Inst.getOperand(2).getImm();1027 TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);1028 TmpInst.addOperand(Inst.getOperand(0));1029 TmpInst.addOperand(Inst.getOperand(1));1030 TmpInst.addOperand(MCOperand::createImm(N));1031 TmpInst.addOperand(MCOperand::createImm(0));1032 TmpInst.addOperand(MCOperand::createImm(31 - N));1033 Inst = TmpInst;1034 break;1035 }1036 case PPC::SRWI:1037 case PPC::SRWI_rec: {1038 MCInst TmpInst;1039 int64_t N = Inst.getOperand(2).getImm();1040 TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);1041 TmpInst.addOperand(Inst.getOperand(0));1042 TmpInst.addOperand(Inst.getOperand(1));1043 TmpInst.addOperand(MCOperand::createImm(32 - N));1044 TmpInst.addOperand(MCOperand::createImm(N));1045 TmpInst.addOperand(MCOperand::createImm(31));1046 Inst = TmpInst;1047 break;1048 }1049 case PPC::CLRRWI:1050 case PPC::CLRRWI_rec: {1051 MCInst TmpInst;1052 int64_t N = Inst.getOperand(2).getImm();1053 TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);1054 TmpInst.addOperand(Inst.getOperand(0));1055 TmpInst.addOperand(Inst.getOperand(1));1056 TmpInst.addOperand(MCOperand::createImm(0));1057 TmpInst.addOperand(MCOperand::createImm(0));1058 TmpInst.addOperand(MCOperand::createImm(31 - N));1059 Inst = TmpInst;1060 break;1061 }1062 case PPC::CLRLSLWI:1063 case PPC::CLRLSLWI_rec: {1064 MCInst TmpInst;1065 int64_t B = Inst.getOperand(2).getImm();1066 int64_t N = Inst.getOperand(3).getImm();1067 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);1068 TmpInst.addOperand(Inst.getOperand(0));1069 TmpInst.addOperand(Inst.getOperand(1));1070 TmpInst.addOperand(MCOperand::createImm(N));1071 TmpInst.addOperand(MCOperand::createImm(B - N));1072 TmpInst.addOperand(MCOperand::createImm(31 - N));1073 Inst = TmpInst;1074 break;1075 }1076 case PPC::EXTLDI:1077 case PPC::EXTLDI_rec: {1078 MCInst TmpInst;1079 int64_t N = Inst.getOperand(2).getImm();1080 int64_t B = Inst.getOperand(3).getImm();1081 TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);1082 TmpInst.addOperand(Inst.getOperand(0));1083 TmpInst.addOperand(Inst.getOperand(1));1084 TmpInst.addOperand(MCOperand::createImm(B));1085 TmpInst.addOperand(MCOperand::createImm(N - 1));1086 Inst = TmpInst;1087 break;1088 }1089 case PPC::EXTRDI:1090 case PPC::EXTRDI_rec: {1091 MCInst TmpInst;1092 int64_t N = Inst.getOperand(2).getImm();1093 int64_t B = Inst.getOperand(3).getImm();1094 TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);1095 TmpInst.addOperand(Inst.getOperand(0));1096 TmpInst.addOperand(Inst.getOperand(1));1097 TmpInst.addOperand(MCOperand::createImm(B + N));1098 TmpInst.addOperand(MCOperand::createImm(64 - N));1099 Inst = TmpInst;1100 break;1101 }1102 case PPC::INSRDI:1103 case PPC::INSRDI_rec: {1104 MCInst TmpInst;1105 int64_t N = Inst.getOperand(2).getImm();1106 int64_t B = Inst.getOperand(3).getImm();1107 TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);1108 TmpInst.addOperand(Inst.getOperand(0));1109 TmpInst.addOperand(Inst.getOperand(0));1110 TmpInst.addOperand(Inst.getOperand(1));1111 TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));1112 TmpInst.addOperand(MCOperand::createImm(B));1113 Inst = TmpInst;1114 break;1115 }1116 case PPC::ROTRDI:1117 case PPC::ROTRDI_rec: {1118 MCInst TmpInst;1119 int64_t N = Inst.getOperand(2).getImm();1120 TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);1121 TmpInst.addOperand(Inst.getOperand(0));1122 TmpInst.addOperand(Inst.getOperand(1));1123 TmpInst.addOperand(MCOperand::createImm(64 - N));1124 TmpInst.addOperand(MCOperand::createImm(0));1125 Inst = TmpInst;1126 break;1127 }1128 case PPC::SLDI:1129 case PPC::SLDI_rec: {1130 MCInst TmpInst;1131 int64_t N = Inst.getOperand(2).getImm();1132 TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);1133 TmpInst.addOperand(Inst.getOperand(0));1134 TmpInst.addOperand(Inst.getOperand(1));1135 TmpInst.addOperand(MCOperand::createImm(N));1136 TmpInst.addOperand(MCOperand::createImm(63 - N));1137 Inst = TmpInst;1138 break;1139 }1140 case PPC::SUBPCIS: {1141 MCInst TmpInst;1142 int64_t N = Inst.getOperand(1).getImm();1143 TmpInst.setOpcode(PPC::ADDPCIS);1144 TmpInst.addOperand(Inst.getOperand(0));1145 TmpInst.addOperand(MCOperand::createImm(-N));1146 Inst = TmpInst;1147 break;1148 }1149 case PPC::SRDI:1150 case PPC::SRDI_rec: {1151 MCInst TmpInst;1152 int64_t N = Inst.getOperand(2).getImm();1153 TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);1154 TmpInst.addOperand(Inst.getOperand(0));1155 TmpInst.addOperand(Inst.getOperand(1));1156 TmpInst.addOperand(MCOperand::createImm(64 - N));1157 TmpInst.addOperand(MCOperand::createImm(N));1158 Inst = TmpInst;1159 break;1160 }1161 case PPC::CLRRDI:1162 case PPC::CLRRDI_rec: {1163 MCInst TmpInst;1164 int64_t N = Inst.getOperand(2).getImm();1165 TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);1166 TmpInst.addOperand(Inst.getOperand(0));1167 TmpInst.addOperand(Inst.getOperand(1));1168 TmpInst.addOperand(MCOperand::createImm(0));1169 TmpInst.addOperand(MCOperand::createImm(63 - N));1170 Inst = TmpInst;1171 break;1172 }1173 case PPC::CLRLSLDI:1174 case PPC::CLRLSLDI_rec: {1175 MCInst TmpInst;1176 int64_t B = Inst.getOperand(2).getImm();1177 int64_t N = Inst.getOperand(3).getImm();1178 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);1179 TmpInst.addOperand(Inst.getOperand(0));1180 TmpInst.addOperand(Inst.getOperand(1));1181 TmpInst.addOperand(MCOperand::createImm(N));1182 TmpInst.addOperand(MCOperand::createImm(B - N));1183 Inst = TmpInst;1184 break;1185 }1186 case PPC::RLWINMbm:1187 case PPC::RLWINMbm_rec: {1188 unsigned MB, ME;1189 int64_t BM = Inst.getOperand(3).getImm();1190 if (!isRunOfOnes(BM, MB, ME))1191 break;1192 1193 MCInst TmpInst;1194 TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);1195 TmpInst.addOperand(Inst.getOperand(0));1196 TmpInst.addOperand(Inst.getOperand(1));1197 TmpInst.addOperand(Inst.getOperand(2));1198 TmpInst.addOperand(MCOperand::createImm(MB));1199 TmpInst.addOperand(MCOperand::createImm(ME));1200 Inst = TmpInst;1201 break;1202 }1203 case PPC::RLWIMIbm:1204 case PPC::RLWIMIbm_rec: {1205 unsigned MB, ME;1206 int64_t BM = Inst.getOperand(3).getImm();1207 if (!isRunOfOnes(BM, MB, ME))1208 break;1209 1210 MCInst TmpInst;1211 TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);1212 TmpInst.addOperand(Inst.getOperand(0));1213 TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.1214 TmpInst.addOperand(Inst.getOperand(1));1215 TmpInst.addOperand(Inst.getOperand(2));1216 TmpInst.addOperand(MCOperand::createImm(MB));1217 TmpInst.addOperand(MCOperand::createImm(ME));1218 Inst = TmpInst;1219 break;1220 }1221 case PPC::RLWNMbm:1222 case PPC::RLWNMbm_rec: {1223 unsigned MB, ME;1224 int64_t BM = Inst.getOperand(3).getImm();1225 if (!isRunOfOnes(BM, MB, ME))1226 break;1227 1228 MCInst TmpInst;1229 TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);1230 TmpInst.addOperand(Inst.getOperand(0));1231 TmpInst.addOperand(Inst.getOperand(1));1232 TmpInst.addOperand(Inst.getOperand(2));1233 TmpInst.addOperand(MCOperand::createImm(MB));1234 TmpInst.addOperand(MCOperand::createImm(ME));1235 Inst = TmpInst;1236 break;1237 }1238 case PPC::MFTB: {1239 if (getSTI().hasFeature(PPC::FeatureMFTB)) {1240 assert(Inst.getNumOperands() == 2 && "Expecting two operands");1241 Inst.setOpcode(PPC::MFSPR);1242 }1243 break;1244 }1245 }1246}1247 1248static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,1249 unsigned VariantID = 0);1250 1251// Check that the register+immediate memory operand is in the right position and1252// is expected by the instruction. Returns true if the memory operand syntax is1253// valid; otherwise, returns false.1254static bool validateMemOp(const OperandVector &Operands, bool isMemriOp) {1255 for (size_t idx = 0; idx < Operands.size(); ++idx) {1256 const PPCOperand &Op = static_cast<const PPCOperand &>(*Operands[idx]);1257 if (Op.isMemOpBase() != (idx == 3 && isMemriOp))1258 return false;1259 }1260 return true;1261}1262 1263bool PPCAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,1264 OperandVector &Operands,1265 MCStreamer &Out, uint64_t &ErrorInfo,1266 bool MatchingInlineAsm) {1267 MCInst Inst;1268 const PPCInstrInfo *TII = static_cast<const PPCInstrInfo *>(&MII);1269 1270 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {1271 case Match_Success:1272 if (!validateMemOp(Operands, TII->isMemriOp(Inst.getOpcode())))1273 return Error(IDLoc, "invalid operand for instruction");1274 // Post-process instructions (typically extended mnemonics)1275 processInstruction(Inst, Operands);1276 Inst.setLoc(IDLoc);1277 Out.emitInstruction(Inst, getSTI());1278 return false;1279 case Match_MissingFeature:1280 return Error(IDLoc, "instruction use requires an option to be enabled");1281 case Match_MnemonicFail: {1282 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());1283 std::string Suggestion = PPCMnemonicSpellCheck(1284 ((PPCOperand &)*Operands[0]).getToken(), FBS);1285 return Error(IDLoc, "invalid instruction" + Suggestion,1286 ((PPCOperand &)*Operands[0]).getLocRange());1287 }1288 case Match_InvalidOperand: {1289 SMLoc ErrorLoc = IDLoc;1290 if (ErrorInfo != ~0ULL) {1291 if (ErrorInfo >= Operands.size())1292 return Error(IDLoc, "too few operands for instruction");1293 1294 ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();1295 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;1296 }1297 1298 return Error(ErrorLoc, "invalid operand for instruction");1299 }1300 }1301 1302 llvm_unreachable("Implement any new match types added!");1303}1304 1305#define GET_REGISTER_MATCHER1306#include "PPCGenAsmMatcher.inc"1307 1308MCRegister PPCAsmParser::matchRegisterName(int64_t &IntVal) {1309 if (getParser().getTok().is(AsmToken::Percent))1310 getParser().Lex(); // Eat the '%'.1311 1312 if (!getParser().getTok().is(AsmToken::Identifier))1313 return MCRegister();1314 1315 // MatchRegisterName() expects lower-case registers, but we want to support1316 // case-insensitive spelling.1317 std::string NameBuf = getParser().getTok().getString().lower();1318 StringRef Name(NameBuf);1319 MCRegister RegNo = MatchRegisterName(Name);1320 if (!RegNo)1321 return RegNo;1322 1323 Name.substr(Name.find_first_of("1234567890")).getAsInteger(10, IntVal);1324 1325 // MatchRegisterName doesn't seem to have special handling for 64bit vs 32bit1326 // register types.1327 if (Name == "lr") {1328 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;1329 IntVal = 8;1330 } else if (Name == "ctr") {1331 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;1332 IntVal = 9;1333 } else if (Name == "vrsave")1334 IntVal = 256;1335 else if (Name.starts_with("r"))1336 RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];1337 1338 getParser().Lex();1339 return RegNo;1340}1341 1342bool PPCAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1343 SMLoc &EndLoc) {1344 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())1345 return TokError("invalid register name");1346 return false;1347}1348 1349ParseStatus PPCAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1350 SMLoc &EndLoc) {1351 const AsmToken &Tok = getParser().getTok();1352 StartLoc = Tok.getLoc();1353 EndLoc = Tok.getEndLoc();1354 int64_t IntVal;1355 if (!(Reg = matchRegisterName(IntVal)))1356 return ParseStatus::NoMatch;1357 return ParseStatus::Success;1358}1359 1360// Extract the @l or @ha specifier from the expression, returning a modified1361// expression with the specifier removed. Stores the extracted specifier in1362// `Spec`. Reports an error if multiple specifiers are detected.1363const MCExpr *PPCAsmParser::extractSpecifier(const MCExpr *E,1364 PPCMCExpr::Specifier &Spec) {1365 MCContext &Context = getParser().getContext();1366 switch (E->getKind()) {1367 case MCExpr::Constant:1368 break;1369 case MCExpr::Specifier: {1370 // Detect error but do not return a modified expression.1371 auto *TE = cast<MCSpecifierExpr>(E);1372 Spec = TE->getSpecifier();1373 (void)extractSpecifier(TE->getSubExpr(), Spec);1374 Spec = PPC::S_None;1375 } break;1376 1377 case MCExpr::SymbolRef: {1378 const auto *SRE = cast<MCSymbolRefExpr>(E);1379 switch (getSpecifier(SRE)) {1380 case PPC::S_None:1381 default:1382 break;1383 case PPC::S_LO:1384 case PPC::S_HI:1385 case PPC::S_HA:1386 case PPC::S_HIGH:1387 case PPC::S_HIGHA:1388 case PPC::S_HIGHER:1389 case PPC::S_HIGHERA:1390 case PPC::S_HIGHEST:1391 case PPC::S_HIGHESTA:1392 if (Spec == PPC::S_None)1393 Spec = getSpecifier(SRE);1394 else1395 Error(E->getLoc(), "cannot contain more than one relocation specifier");1396 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);1397 }1398 break;1399 }1400 1401 case MCExpr::Unary: {1402 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);1403 const MCExpr *Sub = extractSpecifier(UE->getSubExpr(), Spec);1404 if (Spec != PPC::S_None)1405 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);1406 break;1407 }1408 1409 case MCExpr::Binary: {1410 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);1411 const MCExpr *LHS = extractSpecifier(BE->getLHS(), Spec);1412 const MCExpr *RHS = extractSpecifier(BE->getRHS(), Spec);1413 if (Spec != PPC::S_None)1414 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);1415 break;1416 }1417 case MCExpr::Target:1418 llvm_unreachable("unused by this backend");1419 }1420 1421 return E;1422}1423 1424/// This differs from the default "parseExpression" in that it handles1425/// specifiers.1426bool PPCAsmParser::parseExpression(const MCExpr *&EVal) {1427 // (ELF Platforms)1428 // Handle \code @l/@ha \endcode1429 if (getParser().parseExpression(EVal))1430 return true;1431 1432 uint16_t Spec = PPC::S_None;1433 const MCExpr *E = extractSpecifier(EVal, Spec);1434 if (Spec != PPC::S_None)1435 EVal = MCSpecifierExpr::create(E, Spec, getParser().getContext());1436 1437 return false;1438}1439 1440/// This handles registers in the form 'NN', '%rNN' for ELF platforms and1441/// rNN for MachO.1442bool PPCAsmParser::parseOperand(OperandVector &Operands) {1443 MCAsmParser &Parser = getParser();1444 SMLoc S = Parser.getTok().getLoc();1445 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1446 const MCExpr *EVal;1447 1448 // Attempt to parse the next token as an immediate1449 switch (getLexer().getKind()) {1450 // Special handling for register names. These are interpreted1451 // as immediates corresponding to the register number.1452 case AsmToken::Percent: {1453 int64_t IntVal;1454 if (!matchRegisterName(IntVal))1455 return Error(S, "invalid register name");1456 1457 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));1458 return false;1459 }1460 case AsmToken::Identifier:1461 case AsmToken::LParen:1462 case AsmToken::Plus:1463 case AsmToken::Minus:1464 case AsmToken::Integer:1465 case AsmToken::Dot:1466 case AsmToken::Dollar:1467 case AsmToken::Exclaim:1468 case AsmToken::Tilde:1469 if (!parseExpression(EVal))1470 break;1471 // Fall-through1472 [[fallthrough]];1473 default:1474 return Error(S, "unknown operand");1475 }1476 1477 // Push the parsed operand into the list of operands1478 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));1479 1480 // Check whether this is a TLS call expression1481 const char TlsGetAddr[] = "__tls_get_addr";1482 bool TlsCall = false;1483 const MCExpr *TlsCallAddend = nullptr;1484 if (auto *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {1485 TlsCall = Ref->getSymbol().getName() == TlsGetAddr;1486 } else if (auto *Bin = dyn_cast<MCBinaryExpr>(EVal);1487 Bin && Bin->getOpcode() == MCBinaryExpr::Add) {1488 if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Bin->getLHS())) {1489 TlsCall = Ref->getSymbol().getName() == TlsGetAddr;1490 TlsCallAddend = Bin->getRHS();1491 }1492 }1493 1494 if (TlsCall && parseOptionalToken(AsmToken::LParen)) {1495 const MCExpr *TLSSym;1496 const SMLoc S2 = Parser.getTok().getLoc();1497 if (parseExpression(TLSSym))1498 return Error(S2, "invalid TLS call expression");1499 E = Parser.getTok().getLoc();1500 if (parseToken(AsmToken::RParen, "expected ')'"))1501 return true;1502 // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]".1503 if (!isPPC64() && parseOptionalToken(AsmToken::At)) {1504 AsmToken Tok = getTok();1505 if (!(parseOptionalToken(AsmToken::Identifier) &&1506 Tok.getString().compare_insensitive("plt") == 0))1507 return Error(Tok.getLoc(), "expected 'plt'");1508 EVal = MCSymbolRefExpr::create(getContext().getOrCreateSymbol(TlsGetAddr),1509 PPC::S_PLT, getContext());1510 if (parseOptionalToken(AsmToken::Plus)) {1511 const MCExpr *Addend = nullptr;1512 SMLoc EndLoc;1513 if (parsePrimaryExpr(Addend, EndLoc))1514 return true;1515 if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b1516 TlsCallAddend =1517 MCBinaryExpr::createAdd(TlsCallAddend, Addend, getContext());1518 else // __tls_get_addr(x@tlsgd)@plt+b1519 TlsCallAddend = Addend;1520 }1521 if (TlsCallAddend)1522 EVal = MCBinaryExpr::createAdd(EVal, TlsCallAddend, getContext());1523 // Add a __tls_get_addr operand with addend a, b, or a+b.1524 Operands.back() = PPCOperand::CreateFromMCExpr(1525 EVal, S, Parser.getTok().getLoc(), false);1526 }1527 1528 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));1529 }1530 1531 // Otherwise, check for D-form memory operands1532 if (!TlsCall && parseOptionalToken(AsmToken::LParen)) {1533 S = Parser.getTok().getLoc();1534 1535 int64_t IntVal;1536 switch (getLexer().getKind()) {1537 case AsmToken::Percent: {1538 if (!matchRegisterName(IntVal))1539 return Error(S, "invalid register name");1540 break;1541 }1542 case AsmToken::Integer:1543 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||1544 IntVal > 31)1545 return Error(S, "invalid register number");1546 break;1547 case AsmToken::Identifier:1548 default:1549 return Error(S, "invalid memory operand");1550 }1551 1552 E = Parser.getTok().getLoc();1553 if (parseToken(AsmToken::RParen, "missing ')'"))1554 return true;1555 Operands.push_back(1556 PPCOperand::CreateImm(IntVal, S, E, isPPC64(), /*IsMemOpBase=*/true));1557 }1558 1559 return false;1560}1561 1562/// Parse an instruction mnemonic followed by its operands.1563bool PPCAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,1564 SMLoc NameLoc, OperandVector &Operands) {1565 // The first operand is the token for the instruction name.1566 // If the next character is a '+' or '-', we need to add it to the1567 // instruction name, to match what TableGen is doing.1568 std::string NewOpcode;1569 if (parseOptionalToken(AsmToken::Plus)) {1570 NewOpcode = std::string(Name);1571 NewOpcode += '+';1572 Name = NewOpcode;1573 }1574 if (parseOptionalToken(AsmToken::Minus)) {1575 NewOpcode = std::string(Name);1576 NewOpcode += '-';1577 Name = NewOpcode;1578 }1579 // If the instruction ends in a '.', we need to create a separate1580 // token for it, to match what TableGen is doing.1581 size_t Dot = Name.find('.');1582 StringRef Mnemonic = Name.slice(0, Dot);1583 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.1584 Operands.push_back(1585 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));1586 else1587 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));1588 if (Dot != StringRef::npos) {1589 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);1590 StringRef DotStr = Name.substr(Dot);1591 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.1592 Operands.push_back(1593 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));1594 else1595 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));1596 }1597 1598 // If there are no more operands then finish1599 if (parseOptionalToken(AsmToken::EndOfStatement))1600 return false;1601 1602 // Parse the first operand1603 if (parseOperand(Operands))1604 return true;1605 1606 while (!parseOptionalToken(AsmToken::EndOfStatement)) {1607 if (parseToken(AsmToken::Comma) || parseOperand(Operands))1608 return true;1609 }1610 1611 // We'll now deal with an unfortunate special case: the syntax for the dcbt1612 // and dcbtst instructions differs for server vs. embedded cores.1613 // The syntax for dcbt is:1614 // dcbt ra, rb, th [server]1615 // dcbt th, ra, rb [embedded]1616 // where th can be omitted when it is 0. dcbtst is the same. We take the1617 // server form to be the default, so swap the operands if we're parsing for1618 // an embedded core (they'll be swapped again upon printing).1619 if (getSTI().hasFeature(PPC::FeatureBookE) &&1620 Operands.size() == 4 &&1621 (Name == "dcbt" || Name == "dcbtst")) {1622 std::swap(Operands[1], Operands[3]);1623 std::swap(Operands[2], Operands[1]);1624 }1625 1626 // Handle base mnemonic for atomic loads where the EH bit is zero.1627 if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||1628 Name == "lharx" || Name == "lbarx") {1629 if (Operands.size() != 5)1630 return false;1631 PPCOperand &EHOp = (PPCOperand &)*Operands[4];1632 if (EHOp.isUImm<1>() && EHOp.getImm() == 0)1633 Operands.pop_back();1634 }1635 1636 return false;1637}1638 1639/// Parses the PPC specific directives1640bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {1641 StringRef IDVal = DirectiveID.getIdentifier();1642 if (IDVal == ".word")1643 parseDirectiveWord(2, DirectiveID);1644 else if (IDVal == ".llong")1645 parseDirectiveWord(8, DirectiveID);1646 else if (IDVal == ".tc")1647 parseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);1648 else if (IDVal == ".machine")1649 parseDirectiveMachine(DirectiveID.getLoc());1650 else if (IDVal == ".abiversion")1651 parseDirectiveAbiVersion(DirectiveID.getLoc());1652 else if (IDVal == ".localentry")1653 parseDirectiveLocalEntry(DirectiveID.getLoc());1654 else if (IDVal.starts_with(".gnu_attribute"))1655 parseGNUAttribute(DirectiveID.getLoc());1656 else1657 return true;1658 return false;1659}1660 1661/// ::= .word [ expression (, expression)* ]1662bool PPCAsmParser::parseDirectiveWord(unsigned Size, AsmToken ID) {1663 auto parseOp = [&]() -> bool {1664 const MCExpr *Value;1665 SMLoc ExprLoc = getParser().getTok().getLoc();1666 if (getParser().parseExpression(Value))1667 return true;1668 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {1669 assert(Size <= 8 && "Invalid size");1670 uint64_t IntValue = MCE->getValue();1671 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))1672 return Error(ExprLoc, "literal value out of range for '" +1673 ID.getIdentifier() + "' directive");1674 getStreamer().emitIntValue(IntValue, Size);1675 } else1676 getStreamer().emitValue(Value, Size, ExprLoc);1677 return false;1678 };1679 1680 if (parseMany(parseOp))1681 return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");1682 return false;1683}1684 1685/// ::= .tc [ symbol (, expression)* ]1686bool PPCAsmParser::parseDirectiveTC(unsigned Size, AsmToken ID) {1687 MCAsmParser &Parser = getParser();1688 // Skip TC symbol, which is only used with XCOFF.1689 while (getLexer().isNot(AsmToken::EndOfStatement)1690 && getLexer().isNot(AsmToken::Comma))1691 Parser.Lex();1692 if (parseToken(AsmToken::Comma))1693 return addErrorSuffix(" in '.tc' directive");1694 1695 // Align to word size.1696 getParser().getStreamer().emitValueToAlignment(Align(Size));1697 1698 // Emit expressions.1699 return parseDirectiveWord(Size, ID);1700}1701 1702/// ELF platforms.1703/// ::= .machine [ cpu | "push" | "pop" ]1704bool PPCAsmParser::parseDirectiveMachine(SMLoc L) {1705 MCAsmParser &Parser = getParser();1706 if (Parser.getTok().isNot(AsmToken::Identifier) &&1707 Parser.getTok().isNot(AsmToken::String))1708 return Error(L, "unexpected token in '.machine' directive");1709 1710 StringRef CPU = Parser.getTok().getIdentifier();1711 1712 // FIXME: Right now, the parser always allows any available1713 // instruction, so the .machine directive is not useful.1714 // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.1715 1716 Parser.Lex();1717 1718 if (parseToken(AsmToken::EndOfStatement))1719 return addErrorSuffix(" in '.machine' directive");1720 1721 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1722 getParser().getStreamer().getTargetStreamer());1723 if (TStreamer != nullptr)1724 TStreamer->emitMachine(CPU);1725 1726 return false;1727}1728 1729/// ::= .abiversion constant-expression1730bool PPCAsmParser::parseDirectiveAbiVersion(SMLoc L) {1731 int64_t AbiVersion;1732 if (check(getParser().parseAbsoluteExpression(AbiVersion), L,1733 "expected constant expression") ||1734 parseToken(AsmToken::EndOfStatement))1735 return addErrorSuffix(" in '.abiversion' directive");1736 1737 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1738 getParser().getStreamer().getTargetStreamer());1739 if (TStreamer != nullptr)1740 TStreamer->emitAbiVersion(AbiVersion);1741 1742 return false;1743}1744 1745/// ::= .localentry symbol, expression1746bool PPCAsmParser::parseDirectiveLocalEntry(SMLoc L) {1747 StringRef Name;1748 if (getParser().parseIdentifier(Name))1749 return Error(L, "expected identifier in '.localentry' directive");1750 1751 auto *Sym = static_cast<MCSymbolELF *>(getContext().getOrCreateSymbol(Name));1752 const MCExpr *Expr;1753 1754 if (parseToken(AsmToken::Comma) ||1755 check(getParser().parseExpression(Expr), L, "expected expression") ||1756 parseToken(AsmToken::EndOfStatement))1757 return addErrorSuffix(" in '.localentry' directive");1758 1759 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1760 getParser().getStreamer().getTargetStreamer());1761 if (TStreamer != nullptr)1762 TStreamer->emitLocalEntry(Sym, Expr);1763 1764 return false;1765}1766 1767bool PPCAsmParser::parseGNUAttribute(SMLoc L) {1768 int64_t Tag;1769 int64_t IntegerValue;1770 if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))1771 return false;1772 1773 getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);1774 1775 return true;1776}1777 1778/// Force static initialization.1779extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void1780LLVMInitializePowerPCAsmParser() {1781 RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());1782 RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());1783 RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());1784 RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());1785}1786 1787#define GET_MATCHER_IMPLEMENTATION1788#define GET_MNEMONIC_SPELL_CHECKER1789#include "PPCGenAsmMatcher.inc"1790 1791// Define this matcher function after the auto-generated include so we1792// have the match class enum definitions.1793unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,1794 unsigned Kind) {1795 // If the kind is a token for a literal immediate, check if our asm1796 // operand matches. This is for InstAliases which have a fixed-value1797 // immediate in the syntax.1798 int64_t ImmVal;1799 switch (Kind) {1800 case MCK_0: ImmVal = 0; break;1801 case MCK_1: ImmVal = 1; break;1802 case MCK_2: ImmVal = 2; break;1803 case MCK_3: ImmVal = 3; break;1804 case MCK_4: ImmVal = 4; break;1805 case MCK_5: ImmVal = 5; break;1806 case MCK_6: ImmVal = 6; break;1807 case MCK_7: ImmVal = 7; break;1808 default: return Match_InvalidOperand;1809 }1810 1811 PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);1812 if (Op.isUImm<3>() && Op.getImm() == ImmVal)1813 return Match_Success;1814 1815 return Match_InvalidOperand;1816}1817 1818const MCExpr *PPCAsmParser::applySpecifier(const MCExpr *E, uint32_t Spec,1819 MCContext &Ctx) {1820 if (isa<MCConstantExpr>(E)) {1821 switch (PPCMCExpr::Specifier(Spec)) {1822 case PPC::S_LO:1823 case PPC::S_HI:1824 case PPC::S_HA:1825 case PPC::S_HIGH:1826 case PPC::S_HIGHA:1827 case PPC::S_HIGHER:1828 case PPC::S_HIGHERA:1829 case PPC::S_HIGHEST:1830 case PPC::S_HIGHESTA:1831 break;1832 default:1833 return nullptr;1834 }1835 }1836 1837 return MCSpecifierExpr::create(E, Spec, Ctx);1838}1839