12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781 |
- //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "MCTargetDesc/PPCMCExpr.h"
- #include "MCTargetDesc/PPCMCTargetDesc.h"
- #include "PPCTargetStreamer.h"
- #include "TargetInfo/PowerPCTargetInfo.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/Twine.h"
- #include "llvm/MC/MCContext.h"
- #include "llvm/MC/MCExpr.h"
- #include "llvm/MC/MCInst.h"
- #include "llvm/MC/MCInstrInfo.h"
- #include "llvm/MC/MCParser/MCAsmLexer.h"
- #include "llvm/MC/MCParser/MCAsmParser.h"
- #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
- #include "llvm/MC/MCParser/MCTargetAsmParser.h"
- #include "llvm/MC/MCStreamer.h"
- #include "llvm/MC/MCSubtargetInfo.h"
- #include "llvm/MC/MCSymbolELF.h"
- #include "llvm/Support/SourceMgr.h"
- #include "llvm/Support/TargetRegistry.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace llvm;
- DEFINE_PPC_REGCLASSES;
- // Evaluate an expression containing condition register
- // or condition register field symbols. Returns positive
- // value on success, or -1 on error.
- static int64_t
- EvaluateCRExpr(const MCExpr *E) {
- switch (E->getKind()) {
- case MCExpr::Target:
- return -1;
- case MCExpr::Constant: {
- int64_t Res = cast<MCConstantExpr>(E)->getValue();
- return Res < 0 ? -1 : Res;
- }
- case MCExpr::SymbolRef: {
- const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
- StringRef Name = SRE->getSymbol().getName();
- if (Name == "lt") return 0;
- if (Name == "gt") return 1;
- if (Name == "eq") return 2;
- if (Name == "so") return 3;
- if (Name == "un") return 3;
- if (Name == "cr0") return 0;
- if (Name == "cr1") return 1;
- if (Name == "cr2") return 2;
- if (Name == "cr3") return 3;
- if (Name == "cr4") return 4;
- if (Name == "cr5") return 5;
- if (Name == "cr6") return 6;
- if (Name == "cr7") return 7;
- return -1;
- }
- case MCExpr::Unary:
- return -1;
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
- int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
- int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
- int64_t Res;
- if (LHSVal < 0 || RHSVal < 0)
- return -1;
- switch (BE->getOpcode()) {
- default: return -1;
- case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
- case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
- }
- return Res < 0 ? -1 : Res;
- }
- }
- llvm_unreachable("Invalid expression kind!");
- }
- namespace {
- struct PPCOperand;
- class PPCAsmParser : public MCTargetAsmParser {
- bool IsPPC64;
- void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
- bool isPPC64() const { return IsPPC64; }
- bool MatchRegisterName(unsigned &RegNo, int64_t &IntVal);
- bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
- OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
- SMLoc &EndLoc) override;
- const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
- PPCMCExpr::VariantKind &Variant);
- const MCExpr *FixupVariantKind(const MCExpr *E);
- bool ParseExpression(const MCExpr *&EVal);
- bool ParseOperand(OperandVector &Operands);
- bool ParseDirectiveWord(unsigned Size, AsmToken ID);
- bool ParseDirectiveTC(unsigned Size, AsmToken ID);
- bool ParseDirectiveMachine(SMLoc L);
- bool ParseDirectiveAbiVersion(SMLoc L);
- bool ParseDirectiveLocalEntry(SMLoc L);
- bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
- OperandVector &Operands, MCStreamer &Out,
- uint64_t &ErrorInfo,
- bool MatchingInlineAsm) override;
- void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
- /// @name Auto-generated Match Functions
- /// {
- #define GET_ASSEMBLER_HEADER
- #include "PPCGenAsmMatcher.inc"
- /// }
- public:
- PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
- const MCInstrInfo &MII, const MCTargetOptions &Options)
- : MCTargetAsmParser(Options, STI, MII) {
- // Check for 64-bit vs. 32-bit pointer mode.
- const Triple &TheTriple = STI.getTargetTriple();
- IsPPC64 = TheTriple.isPPC64();
- // Initialize the set of available features.
- setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
- }
- bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
- SMLoc NameLoc, OperandVector &Operands) override;
- bool ParseDirective(AsmToken DirectiveID) override;
- unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
- unsigned Kind) override;
- const MCExpr *applyModifierToExpr(const MCExpr *E,
- MCSymbolRefExpr::VariantKind,
- MCContext &Ctx) override;
- };
- /// PPCOperand - Instances of this class represent a parsed PowerPC machine
- /// instruction.
- struct PPCOperand : public MCParsedAsmOperand {
- enum KindTy {
- Token,
- Immediate,
- ContextImmediate,
- Expression,
- TLSRegister
- } Kind;
- SMLoc StartLoc, EndLoc;
- bool IsPPC64;
- struct TokOp {
- const char *Data;
- unsigned Length;
- };
- struct ImmOp {
- int64_t Val;
- };
- struct ExprOp {
- const MCExpr *Val;
- int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
- };
- struct TLSRegOp {
- const MCSymbolRefExpr *Sym;
- };
- union {
- struct TokOp Tok;
- struct ImmOp Imm;
- struct ExprOp Expr;
- struct TLSRegOp TLSReg;
- };
- PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
- public:
- PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
- Kind = o.Kind;
- StartLoc = o.StartLoc;
- EndLoc = o.EndLoc;
- IsPPC64 = o.IsPPC64;
- switch (Kind) {
- case Token:
- Tok = o.Tok;
- break;
- case Immediate:
- case ContextImmediate:
- Imm = o.Imm;
- break;
- case Expression:
- Expr = o.Expr;
- break;
- case TLSRegister:
- TLSReg = o.TLSReg;
- break;
- }
- }
- // Disable use of sized deallocation due to overallocation of PPCOperand
- // objects in CreateTokenWithStringCopy.
- void operator delete(void *p) { ::operator delete(p); }
- /// getStartLoc - Get the location of the first token of this operand.
- SMLoc getStartLoc() const override { return StartLoc; }
- /// getEndLoc - Get the location of the last token of this operand.
- SMLoc getEndLoc() const override { return EndLoc; }
- /// getLocRange - Get the range between the first and last token of this
- /// operand.
- SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
- /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
- bool isPPC64() const { return IsPPC64; }
- int64_t getImm() const {
- assert(Kind == Immediate && "Invalid access!");
- return Imm.Val;
- }
- int64_t getImmS16Context() const {
- assert((Kind == Immediate || Kind == ContextImmediate) &&
- "Invalid access!");
- if (Kind == Immediate)
- return Imm.Val;
- return static_cast<int16_t>(Imm.Val);
- }
- int64_t getImmU16Context() const {
- assert((Kind == Immediate || Kind == ContextImmediate) &&
- "Invalid access!");
- return Imm.Val;
- }
- const MCExpr *getExpr() const {
- assert(Kind == Expression && "Invalid access!");
- return Expr.Val;
- }
- int64_t getExprCRVal() const {
- assert(Kind == Expression && "Invalid access!");
- return Expr.CRVal;
- }
- const MCExpr *getTLSReg() const {
- assert(Kind == TLSRegister && "Invalid access!");
- return TLSReg.Sym;
- }
- unsigned getReg() const override {
- assert(isRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val;
- }
- unsigned getVSReg() const {
- assert(isVSRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val;
- }
- unsigned getACCReg() const {
- assert(isACCRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val;
- }
- unsigned getVSRpEvenReg() const {
- assert(isVSRpEvenRegNumber() && "Invalid access!");
- return (unsigned) Imm.Val >> 1;
- }
- unsigned getCCReg() const {
- assert(isCCRegNumber() && "Invalid access!");
- return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
- }
- unsigned getCRBit() const {
- assert(isCRBitNumber() && "Invalid access!");
- return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
- }
- unsigned getCRBitMask() const {
- assert(isCRBitMask() && "Invalid access!");
- return 7 - countTrailingZeros<uint64_t>(Imm.Val);
- }
- bool isToken() const override { return Kind == Token; }
- bool isImm() const override {
- return Kind == Immediate || Kind == Expression;
- }
- bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
- bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
- bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
- bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
- bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
- bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
- bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
- bool isU6ImmX2() const { return Kind == Immediate &&
- isUInt<6>(getImm()) &&
- (getImm() & 1) == 0; }
- bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
- bool isU7ImmX4() const { return Kind == Immediate &&
- isUInt<7>(getImm()) &&
- (getImm() & 3) == 0; }
- bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
- bool isU8ImmX8() const { return Kind == Immediate &&
- isUInt<8>(getImm()) &&
- (getImm() & 7) == 0; }
- bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
- bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
- bool isU16Imm() const {
- switch (Kind) {
- case Expression:
- return true;
- case Immediate:
- case ContextImmediate:
- return isUInt<16>(getImmU16Context());
- default:
- return false;
- }
- }
- bool isS16Imm() const {
- switch (Kind) {
- case Expression:
- return true;
- case Immediate:
- case ContextImmediate:
- return isInt<16>(getImmS16Context());
- default:
- return false;
- }
- }
- bool isS16ImmX4() const { return Kind == Expression ||
- (Kind == Immediate && isInt<16>(getImm()) &&
- (getImm() & 3) == 0); }
- bool isS16ImmX16() const { return Kind == Expression ||
- (Kind == Immediate && isInt<16>(getImm()) &&
- (getImm() & 15) == 0); }
- bool isS34ImmX16() const {
- return Kind == Expression ||
- (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
- }
- bool isS34Imm() const {
- // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
- // ContextImmediate is needed.
- return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
- }
- bool isS17Imm() const {
- switch (Kind) {
- case Expression:
- return true;
- case Immediate:
- case ContextImmediate:
- return isInt<17>(getImmS16Context());
- default:
- return false;
- }
- }
- bool isTLSReg() const { return Kind == TLSRegister; }
- bool isDirectBr() const {
- if (Kind == Expression)
- return true;
- if (Kind != Immediate)
- return false;
- // Operand must be 64-bit aligned, signed 27-bit immediate.
- if ((getImm() & 3) != 0)
- return false;
- if (isInt<26>(getImm()))
- return true;
- if (!IsPPC64) {
- // In 32-bit mode, large 32-bit quantities wrap around.
- if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
- return true;
- }
- return false;
- }
- bool isCondBr() const { return Kind == Expression ||
- (Kind == Immediate && isInt<16>(getImm()) &&
- (getImm() & 3) == 0); }
- bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
- bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
- bool isACCRegNumber() const {
- return Kind == Immediate && isUInt<3>(getImm());
- }
- bool isVSRpEvenRegNumber() const {
- return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
- }
- bool isVSRegNumber() const {
- return Kind == Immediate && isUInt<6>(getImm());
- }
- bool isCCRegNumber() const { return (Kind == Expression
- && isUInt<3>(getExprCRVal())) ||
- (Kind == Immediate
- && isUInt<3>(getImm())); }
- bool isCRBitNumber() const { return (Kind == Expression
- && isUInt<5>(getExprCRVal())) ||
- (Kind == Immediate
- && isUInt<5>(getImm())); }
- bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
- isPowerOf2_32(getImm()); }
- bool isATBitsAsHint() const { return false; }
- bool isMem() const override { return false; }
- bool isReg() const override { return false; }
- void addRegOperands(MCInst &Inst, unsigned N) const {
- llvm_unreachable("addRegOperands");
- }
- void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
- }
- void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()]));
- }
- void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(XRegs[getReg()]));
- }
- void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()]));
- }
- void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
- if (isPPC64())
- addRegG8RCOperands(Inst, N);
- else
- addRegGPRCOperands(Inst, N);
- }
- void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
- if (isPPC64())
- addRegG8RCNoX0Operands(Inst, N);
- else
- addRegGPRCNoR0Operands(Inst, N);
- }
- void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
- }
- void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
- }
- void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VFRegs[getReg()]));
- }
- void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VRegs[getReg()]));
- }
- void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
- }
- void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
- }
- void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
- }
- void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
- }
- void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
- }
- void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
- }
- void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
- }
- void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
- }
- void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
- }
- void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
- }
- void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
- }
- void addImmOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- if (Kind == Immediate)
- Inst.addOperand(MCOperand::createImm(getImm()));
- else
- Inst.addOperand(MCOperand::createExpr(getExpr()));
- }
- void addS16ImmOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- switch (Kind) {
- case Immediate:
- Inst.addOperand(MCOperand::createImm(getImm()));
- break;
- case ContextImmediate:
- Inst.addOperand(MCOperand::createImm(getImmS16Context()));
- break;
- default:
- Inst.addOperand(MCOperand::createExpr(getExpr()));
- break;
- }
- }
- void addU16ImmOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- switch (Kind) {
- case Immediate:
- Inst.addOperand(MCOperand::createImm(getImm()));
- break;
- case ContextImmediate:
- Inst.addOperand(MCOperand::createImm(getImmU16Context()));
- break;
- default:
- Inst.addOperand(MCOperand::createExpr(getExpr()));
- break;
- }
- }
- void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- if (Kind == Immediate)
- Inst.addOperand(MCOperand::createImm(getImm() / 4));
- else
- Inst.addOperand(MCOperand::createExpr(getExpr()));
- }
- void addTLSRegOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createExpr(getTLSReg()));
- }
- StringRef getToken() const {
- assert(Kind == Token && "Invalid access!");
- return StringRef(Tok.Data, Tok.Length);
- }
- void print(raw_ostream &OS) const override;
- static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
- bool IsPPC64) {
- auto Op = std::make_unique<PPCOperand>(Token);
- Op->Tok.Data = Str.data();
- Op->Tok.Length = Str.size();
- Op->StartLoc = S;
- Op->EndLoc = S;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand>
- CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
- // Allocate extra memory for the string and copy it.
- // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
- // deleter which will destroy them by simply using "delete", not correctly
- // calling operator delete on this extra memory after calling the dtor
- // explicitly.
- void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
- std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
- Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
- Op->Tok.Length = Str.size();
- std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
- Op->StartLoc = S;
- Op->EndLoc = S;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
- bool IsPPC64) {
- auto Op = std::make_unique<PPCOperand>(Immediate);
- Op->Imm.Val = Val;
- Op->StartLoc = S;
- Op->EndLoc = E;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
- SMLoc E, bool IsPPC64) {
- auto Op = std::make_unique<PPCOperand>(Expression);
- Op->Expr.Val = Val;
- Op->Expr.CRVal = EvaluateCRExpr(Val);
- Op->StartLoc = S;
- Op->EndLoc = E;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand>
- CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
- auto Op = std::make_unique<PPCOperand>(TLSRegister);
- Op->TLSReg.Sym = Sym;
- Op->StartLoc = S;
- Op->EndLoc = E;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand>
- CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
- auto Op = std::make_unique<PPCOperand>(ContextImmediate);
- Op->Imm.Val = Val;
- Op->StartLoc = S;
- Op->EndLoc = E;
- Op->IsPPC64 = IsPPC64;
- return Op;
- }
- static std::unique_ptr<PPCOperand>
- CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
- return CreateImm(CE->getValue(), S, E, IsPPC64);
- if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
- if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
- SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
- return CreateTLSReg(SRE, S, E, IsPPC64);
- if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
- int64_t Res;
- if (TE->evaluateAsConstant(Res))
- return CreateContextImm(Res, S, E, IsPPC64);
- }
- return CreateExpr(Val, S, E, IsPPC64);
- }
- };
- } // end anonymous namespace.
- void PPCOperand::print(raw_ostream &OS) const {
- switch (Kind) {
- case Token:
- OS << "'" << getToken() << "'";
- break;
- case Immediate:
- case ContextImmediate:
- OS << getImm();
- break;
- case Expression:
- OS << *getExpr();
- break;
- case TLSRegister:
- OS << *getTLSReg();
- break;
- }
- }
- static void
- addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
- if (Op.isImm()) {
- Inst.addOperand(MCOperand::createImm(-Op.getImm()));
- return;
- }
- const MCExpr *Expr = Op.getExpr();
- if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
- if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
- Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
- return;
- }
- } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
- if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
- const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
- BinExpr->getLHS(), Ctx);
- Inst.addOperand(MCOperand::createExpr(NE));
- return;
- }
- }
- Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));
- }
- void PPCAsmParser::ProcessInstruction(MCInst &Inst,
- const OperandVector &Operands) {
- int Opcode = Inst.getOpcode();
- switch (Opcode) {
- case PPC::DCBTx:
- case PPC::DCBTT:
- case PPC::DCBTSTx:
- case PPC::DCBTSTT: {
- MCInst TmpInst;
- TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
- PPC::DCBT : PPC::DCBTST);
- TmpInst.addOperand(MCOperand::createImm(
- (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- break;
- }
- case PPC::DCBTCT:
- case PPC::DCBTDS: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::DCBT);
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- break;
- }
- case PPC::DCBTSTCT:
- case PPC::DCBTSTDS: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::DCBTST);
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- break;
- }
- case PPC::DCBFx:
- case PPC::DCBFL:
- case PPC::DCBFLP:
- case PPC::DCBFPS:
- case PPC::DCBSTPS: {
- int L = 0;
- if (Opcode == PPC::DCBFL)
- L = 1;
- else if (Opcode == PPC::DCBFLP)
- L = 3;
- else if (Opcode == PPC::DCBFPS)
- L = 4;
- else if (Opcode == PPC::DCBSTPS)
- L = 6;
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::DCBF);
- TmpInst.addOperand(MCOperand::createImm(L));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- break;
- }
- case PPC::LAx: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::LA);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(Inst.getOperand(1));
- Inst = TmpInst;
- break;
- }
- case PPC::SUBI: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::ADDI);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- addNegOperand(TmpInst, Inst.getOperand(2), getContext());
- Inst = TmpInst;
- break;
- }
- case PPC::SUBIS: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::ADDIS);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- addNegOperand(TmpInst, Inst.getOperand(2), getContext());
- Inst = TmpInst;
- break;
- }
- case PPC::SUBIC: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::ADDIC);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- addNegOperand(TmpInst, Inst.getOperand(2), getContext());
- Inst = TmpInst;
- break;
- }
- case PPC::SUBIC_rec: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::ADDIC_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- addNegOperand(TmpInst, Inst.getOperand(2), getContext());
- Inst = TmpInst;
- break;
- }
- case PPC::EXTLWI:
- case PPC::EXTLWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(B));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(N - 1));
- Inst = TmpInst;
- break;
- }
- case PPC::EXTRWI:
- case PPC::EXTRWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(B + N));
- TmpInst.addOperand(MCOperand::createImm(32 - N));
- TmpInst.addOperand(MCOperand::createImm(31));
- Inst = TmpInst;
- break;
- }
- case PPC::INSLWI:
- case PPC::INSLWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(32 - B));
- TmpInst.addOperand(MCOperand::createImm(B));
- TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
- Inst = TmpInst;
- break;
- }
- case PPC::INSRWI:
- case PPC::INSRWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
- TmpInst.addOperand(MCOperand::createImm(B));
- TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
- Inst = TmpInst;
- break;
- }
- case PPC::ROTRWI:
- case PPC::ROTRWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(32 - N));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(31));
- Inst = TmpInst;
- break;
- }
- case PPC::SLWI:
- case PPC::SLWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(N));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(31 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::SRWI:
- case PPC::SRWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(32 - N));
- TmpInst.addOperand(MCOperand::createImm(N));
- TmpInst.addOperand(MCOperand::createImm(31));
- Inst = TmpInst;
- break;
- }
- case PPC::CLRRWI:
- case PPC::CLRRWI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(31 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::CLRLSLWI:
- case PPC::CLRLSLWI_rec: {
- MCInst TmpInst;
- int64_t B = Inst.getOperand(2).getImm();
- int64_t N = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(N));
- TmpInst.addOperand(MCOperand::createImm(B - N));
- TmpInst.addOperand(MCOperand::createImm(31 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::EXTLDI:
- case PPC::EXTLDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(B));
- TmpInst.addOperand(MCOperand::createImm(N - 1));
- Inst = TmpInst;
- break;
- }
- case PPC::EXTRDI:
- case PPC::EXTRDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(B + N));
- TmpInst.addOperand(MCOperand::createImm(64 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::INSRDI:
- case PPC::INSRDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- int64_t B = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
- TmpInst.addOperand(MCOperand::createImm(B));
- Inst = TmpInst;
- break;
- }
- case PPC::ROTRDI:
- case PPC::ROTRDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(64 - N));
- TmpInst.addOperand(MCOperand::createImm(0));
- Inst = TmpInst;
- break;
- }
- case PPC::SLDI:
- case PPC::SLDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(N));
- TmpInst.addOperand(MCOperand::createImm(63 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::SUBPCIS: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(1).getImm();
- TmpInst.setOpcode(PPC::ADDPCIS);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(MCOperand::createImm(-N));
- Inst = TmpInst;
- break;
- }
- case PPC::SRDI:
- case PPC::SRDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(64 - N));
- TmpInst.addOperand(MCOperand::createImm(N));
- Inst = TmpInst;
- break;
- }
- case PPC::CLRRDI:
- case PPC::CLRRDI_rec: {
- MCInst TmpInst;
- int64_t N = Inst.getOperand(2).getImm();
- TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(0));
- TmpInst.addOperand(MCOperand::createImm(63 - N));
- Inst = TmpInst;
- break;
- }
- case PPC::CLRLSLDI:
- case PPC::CLRLSLDI_rec: {
- MCInst TmpInst;
- int64_t B = Inst.getOperand(2).getImm();
- int64_t N = Inst.getOperand(3).getImm();
- TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(N));
- TmpInst.addOperand(MCOperand::createImm(B - N));
- Inst = TmpInst;
- break;
- }
- case PPC::RLWINMbm:
- case PPC::RLWINMbm_rec: {
- unsigned MB, ME;
- int64_t BM = Inst.getOperand(3).getImm();
- if (!isRunOfOnes(BM, MB, ME))
- break;
- MCInst TmpInst;
- TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(MCOperand::createImm(MB));
- TmpInst.addOperand(MCOperand::createImm(ME));
- Inst = TmpInst;
- break;
- }
- case PPC::RLWIMIbm:
- case PPC::RLWIMIbm_rec: {
- unsigned MB, ME;
- int64_t BM = Inst.getOperand(3).getImm();
- if (!isRunOfOnes(BM, MB, ME))
- break;
- MCInst TmpInst;
- TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(MCOperand::createImm(MB));
- TmpInst.addOperand(MCOperand::createImm(ME));
- Inst = TmpInst;
- break;
- }
- case PPC::RLWNMbm:
- case PPC::RLWNMbm_rec: {
- unsigned MB, ME;
- int64_t BM = Inst.getOperand(3).getImm();
- if (!isRunOfOnes(BM, MB, ME))
- break;
- MCInst TmpInst;
- TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(Inst.getOperand(2));
- TmpInst.addOperand(MCOperand::createImm(MB));
- TmpInst.addOperand(MCOperand::createImm(ME));
- Inst = TmpInst;
- break;
- }
- case PPC::MFTB: {
- if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) {
- assert(Inst.getNumOperands() == 2 && "Expecting two operands");
- Inst.setOpcode(PPC::MFSPR);
- }
- break;
- }
- case PPC::CP_COPYx:
- case PPC::CP_COPY_FIRST: {
- MCInst TmpInst;
- TmpInst.setOpcode(PPC::CP_COPY);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_COPYx ? 0 : 1));
- Inst = TmpInst;
- break;
- }
- case PPC::CP_PASTEx :
- case PPC::CP_PASTE_LAST: {
- MCInst TmpInst;
- TmpInst.setOpcode(Opcode == PPC::CP_PASTEx ? PPC::CP_PASTE
- : PPC::CP_PASTE_rec);
- TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_PASTEx ? 0 : 1));
- Inst = TmpInst;
- break;
- }
- }
- }
- static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
- unsigned VariantID = 0);
- bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
- OperandVector &Operands,
- MCStreamer &Out, uint64_t &ErrorInfo,
- bool MatchingInlineAsm) {
- MCInst Inst;
- switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
- case Match_Success:
- // Post-process instructions (typically extended mnemonics)
- ProcessInstruction(Inst, Operands);
- Inst.setLoc(IDLoc);
- Out.emitInstruction(Inst, getSTI());
- return false;
- case Match_MissingFeature:
- return Error(IDLoc, "instruction use requires an option to be enabled");
- case Match_MnemonicFail: {
- FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
- std::string Suggestion = PPCMnemonicSpellCheck(
- ((PPCOperand &)*Operands[0]).getToken(), FBS);
- return Error(IDLoc, "invalid instruction" + Suggestion,
- ((PPCOperand &)*Operands[0]).getLocRange());
- }
- case Match_InvalidOperand: {
- SMLoc ErrorLoc = IDLoc;
- if (ErrorInfo != ~0ULL) {
- if (ErrorInfo >= Operands.size())
- return Error(IDLoc, "too few operands for instruction");
- ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
- if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
- }
- return Error(ErrorLoc, "invalid operand for instruction");
- }
- }
- llvm_unreachable("Implement any new match types added!");
- }
- bool PPCAsmParser::MatchRegisterName(unsigned &RegNo, int64_t &IntVal) {
- if (getParser().getTok().is(AsmToken::Percent))
- getParser().Lex(); // Eat the '%'.
- if (!getParser().getTok().is(AsmToken::Identifier))
- return true;
- StringRef Name = getParser().getTok().getString();
- if (Name.equals_lower("lr")) {
- RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
- IntVal = 8;
- } else if (Name.equals_lower("ctr")) {
- RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
- IntVal = 9;
- } else if (Name.equals_lower("vrsave")) {
- RegNo = PPC::VRSAVE;
- IntVal = 256;
- } else if (Name.startswith_lower("r") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
- } else if (Name.startswith_lower("f") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = FRegs[IntVal];
- } else if (Name.startswith_lower("vs") &&
- !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
- RegNo = VSRegs[IntVal];
- } else if (Name.startswith_lower("v") &&
- !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
- RegNo = VRegs[IntVal];
- } else if (Name.startswith_lower("cr") &&
- !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
- RegNo = CRRegs[IntVal];
- } else
- return true;
- getParser().Lex();
- return false;
- }
- bool PPCAsmParser::
- ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
- if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
- return TokError("invalid register name");
- return false;
- }
- OperandMatchResultTy PPCAsmParser::tryParseRegister(unsigned &RegNo,
- SMLoc &StartLoc,
- SMLoc &EndLoc) {
- const AsmToken &Tok = getParser().getTok();
- StartLoc = Tok.getLoc();
- EndLoc = Tok.getEndLoc();
- RegNo = 0;
- int64_t IntVal;
- if (MatchRegisterName(RegNo, IntVal))
- return MatchOperand_NoMatch;
- return MatchOperand_Success;
- }
- /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
- /// the expression and check for VK_PPC_LO/HI/HA
- /// symbol variants. If all symbols with modifier use the same
- /// variant, return the corresponding PPCMCExpr::VariantKind,
- /// and a modified expression using the default symbol variant.
- /// Otherwise, return NULL.
- const MCExpr *PPCAsmParser::
- ExtractModifierFromExpr(const MCExpr *E,
- PPCMCExpr::VariantKind &Variant) {
- MCContext &Context = getParser().getContext();
- Variant = PPCMCExpr::VK_PPC_None;
- switch (E->getKind()) {
- case MCExpr::Target:
- case MCExpr::Constant:
- return nullptr;
- case MCExpr::SymbolRef: {
- const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
- switch (SRE->getKind()) {
- case MCSymbolRefExpr::VK_PPC_LO:
- Variant = PPCMCExpr::VK_PPC_LO;
- break;
- case MCSymbolRefExpr::VK_PPC_HI:
- Variant = PPCMCExpr::VK_PPC_HI;
- break;
- case MCSymbolRefExpr::VK_PPC_HA:
- Variant = PPCMCExpr::VK_PPC_HA;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGH:
- Variant = PPCMCExpr::VK_PPC_HIGH;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGHA:
- Variant = PPCMCExpr::VK_PPC_HIGHA;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGHER:
- Variant = PPCMCExpr::VK_PPC_HIGHER;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGHERA:
- Variant = PPCMCExpr::VK_PPC_HIGHERA;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGHEST:
- Variant = PPCMCExpr::VK_PPC_HIGHEST;
- break;
- case MCSymbolRefExpr::VK_PPC_HIGHESTA:
- Variant = PPCMCExpr::VK_PPC_HIGHESTA;
- break;
- default:
- return nullptr;
- }
- return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
- }
- case MCExpr::Unary: {
- const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
- const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
- if (!Sub)
- return nullptr;
- return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
- }
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
- PPCMCExpr::VariantKind LHSVariant, RHSVariant;
- const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
- const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
- if (!LHS && !RHS)
- return nullptr;
- if (!LHS) LHS = BE->getLHS();
- if (!RHS) RHS = BE->getRHS();
- if (LHSVariant == PPCMCExpr::VK_PPC_None)
- Variant = RHSVariant;
- else if (RHSVariant == PPCMCExpr::VK_PPC_None)
- Variant = LHSVariant;
- else if (LHSVariant == RHSVariant)
- Variant = LHSVariant;
- else
- return nullptr;
- return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
- }
- }
- llvm_unreachable("Invalid expression kind!");
- }
- /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
- /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
- /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
- /// FIXME: This is a hack.
- const MCExpr *PPCAsmParser::
- FixupVariantKind(const MCExpr *E) {
- MCContext &Context = getParser().getContext();
- switch (E->getKind()) {
- case MCExpr::Target:
- case MCExpr::Constant:
- return E;
- case MCExpr::SymbolRef: {
- const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- switch (SRE->getKind()) {
- case MCSymbolRefExpr::VK_TLSGD:
- Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
- break;
- case MCSymbolRefExpr::VK_TLSLD:
- Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
- break;
- default:
- return E;
- }
- return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
- }
- case MCExpr::Unary: {
- const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
- const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
- if (Sub == UE->getSubExpr())
- return E;
- return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
- }
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
- const MCExpr *LHS = FixupVariantKind(BE->getLHS());
- const MCExpr *RHS = FixupVariantKind(BE->getRHS());
- if (LHS == BE->getLHS() && RHS == BE->getRHS())
- return E;
- return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
- }
- }
- llvm_unreachable("Invalid expression kind!");
- }
- /// ParseExpression. This differs from the default "parseExpression" in that
- /// it handles modifiers.
- bool PPCAsmParser::
- ParseExpression(const MCExpr *&EVal) {
- // (ELF Platforms)
- // Handle \code @l/@ha \endcode
- if (getParser().parseExpression(EVal))
- return true;
- EVal = FixupVariantKind(EVal);
- PPCMCExpr::VariantKind Variant;
- const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
- if (E)
- EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
- return false;
- }
- /// ParseOperand
- /// This handles registers in the form 'NN', '%rNN' for ELF platforms and
- /// rNN for MachO.
- bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
- MCAsmParser &Parser = getParser();
- SMLoc S = Parser.getTok().getLoc();
- SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- const MCExpr *EVal;
- // Attempt to parse the next token as an immediate
- switch (getLexer().getKind()) {
- // Special handling for register names. These are interpreted
- // as immediates corresponding to the register number.
- case AsmToken::Percent: {
- unsigned RegNo;
- int64_t IntVal;
- if (MatchRegisterName(RegNo, IntVal))
- return Error(S, "invalid register name");
- Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
- return false;
- }
- case AsmToken::Identifier:
- case AsmToken::LParen:
- case AsmToken::Plus:
- case AsmToken::Minus:
- case AsmToken::Integer:
- case AsmToken::Dot:
- case AsmToken::Dollar:
- case AsmToken::Exclaim:
- case AsmToken::Tilde:
- if (!ParseExpression(EVal))
- break;
- // Fall-through
- LLVM_FALLTHROUGH;
- default:
- return Error(S, "unknown operand");
- }
- // Push the parsed operand into the list of operands
- Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
- // Check whether this is a TLS call expression
- bool TLSCall = false;
- if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
- TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
- if (TLSCall && getLexer().is(AsmToken::LParen)) {
- const MCExpr *TLSSym;
- Parser.Lex(); // Eat the '('.
- S = Parser.getTok().getLoc();
- if (ParseExpression(TLSSym))
- return Error(S, "invalid TLS call expression");
- if (getLexer().isNot(AsmToken::RParen))
- return Error(Parser.getTok().getLoc(), "missing ')'");
- E = Parser.getTok().getLoc();
- Parser.Lex(); // Eat the ')'.
- Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
- }
- // Otherwise, check for D-form memory operands
- if (!TLSCall && getLexer().is(AsmToken::LParen)) {
- Parser.Lex(); // Eat the '('.
- S = Parser.getTok().getLoc();
- int64_t IntVal;
- switch (getLexer().getKind()) {
- case AsmToken::Percent: {
- unsigned RegNo;
- if (MatchRegisterName(RegNo, IntVal))
- return Error(S, "invalid register name");
- break;
- }
- case AsmToken::Integer:
- if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
- IntVal > 31)
- return Error(S, "invalid register number");
- break;
- case AsmToken::Identifier:
- default:
- return Error(S, "invalid memory operand");
- }
- E = Parser.getTok().getLoc();
- if (parseToken(AsmToken::RParen, "missing ')'"))
- return true;
- Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
- }
- return false;
- }
- /// Parse an instruction mnemonic followed by its operands.
- bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
- SMLoc NameLoc, OperandVector &Operands) {
- // The first operand is the token for the instruction name.
- // If the next character is a '+' or '-', we need to add it to the
- // instruction name, to match what TableGen is doing.
- std::string NewOpcode;
- if (parseOptionalToken(AsmToken::Plus)) {
- NewOpcode = std::string(Name);
- NewOpcode += '+';
- Name = NewOpcode;
- }
- if (parseOptionalToken(AsmToken::Minus)) {
- NewOpcode = std::string(Name);
- NewOpcode += '-';
- Name = NewOpcode;
- }
- // If the instruction ends in a '.', we need to create a separate
- // token for it, to match what TableGen is doing.
- size_t Dot = Name.find('.');
- StringRef Mnemonic = Name.slice(0, Dot);
- if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
- Operands.push_back(
- PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
- else
- Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
- if (Dot != StringRef::npos) {
- SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
- StringRef DotStr = Name.slice(Dot, StringRef::npos);
- if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
- Operands.push_back(
- PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
- else
- Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
- }
- // If there are no more operands then finish
- if (parseOptionalToken(AsmToken::EndOfStatement))
- return false;
- // Parse the first operand
- if (ParseOperand(Operands))
- return true;
- while (!parseOptionalToken(AsmToken::EndOfStatement)) {
- if (parseToken(AsmToken::Comma) || ParseOperand(Operands))
- return true;
- }
- // We'll now deal with an unfortunate special case: the syntax for the dcbt
- // and dcbtst instructions differs for server vs. embedded cores.
- // The syntax for dcbt is:
- // dcbt ra, rb, th [server]
- // dcbt th, ra, rb [embedded]
- // where th can be omitted when it is 0. dcbtst is the same. We take the
- // server form to be the default, so swap the operands if we're parsing for
- // an embedded core (they'll be swapped again upon printing).
- if (getSTI().getFeatureBits()[PPC::FeatureBookE] &&
- Operands.size() == 4 &&
- (Name == "dcbt" || Name == "dcbtst")) {
- std::swap(Operands[1], Operands[3]);
- std::swap(Operands[2], Operands[1]);
- }
- return false;
- }
- /// ParseDirective parses the PPC specific directives
- bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
- StringRef IDVal = DirectiveID.getIdentifier();
- if (IDVal == ".word")
- ParseDirectiveWord(2, DirectiveID);
- else if (IDVal == ".llong")
- ParseDirectiveWord(8, DirectiveID);
- else if (IDVal == ".tc")
- ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
- else if (IDVal == ".machine")
- ParseDirectiveMachine(DirectiveID.getLoc());
- else if (IDVal == ".abiversion")
- ParseDirectiveAbiVersion(DirectiveID.getLoc());
- else if (IDVal == ".localentry")
- ParseDirectiveLocalEntry(DirectiveID.getLoc());
- else
- return true;
- return false;
- }
- /// ParseDirectiveWord
- /// ::= .word [ expression (, expression)* ]
- bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) {
- auto parseOp = [&]() -> bool {
- const MCExpr *Value;
- SMLoc ExprLoc = getParser().getTok().getLoc();
- if (getParser().parseExpression(Value))
- return true;
- if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
- assert(Size <= 8 && "Invalid size");
- uint64_t IntValue = MCE->getValue();
- if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
- return Error(ExprLoc, "literal value out of range for '" +
- ID.getIdentifier() + "' directive");
- getStreamer().emitIntValue(IntValue, Size);
- } else
- getStreamer().emitValue(Value, Size, ExprLoc);
- return false;
- };
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
- return false;
- }
- /// ParseDirectiveTC
- /// ::= .tc [ symbol (, expression)* ]
- bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) {
- MCAsmParser &Parser = getParser();
- // Skip TC symbol, which is only used with XCOFF.
- while (getLexer().isNot(AsmToken::EndOfStatement)
- && getLexer().isNot(AsmToken::Comma))
- Parser.Lex();
- if (parseToken(AsmToken::Comma))
- return addErrorSuffix(" in '.tc' directive");
- // Align to word size.
- getParser().getStreamer().emitValueToAlignment(Size);
- // Emit expressions.
- return ParseDirectiveWord(Size, ID);
- }
- /// ParseDirectiveMachine (ELF platforms)
- /// ::= .machine [ cpu | "push" | "pop" ]
- bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
- MCAsmParser &Parser = getParser();
- if (Parser.getTok().isNot(AsmToken::Identifier) &&
- Parser.getTok().isNot(AsmToken::String))
- return Error(L, "unexpected token in '.machine' directive");
- StringRef CPU = Parser.getTok().getIdentifier();
- // FIXME: Right now, the parser always allows any available
- // instruction, so the .machine directive is not useful.
- // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
- Parser.Lex();
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.machine' directive");
- PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
- getParser().getStreamer().getTargetStreamer());
- if (TStreamer != nullptr)
- TStreamer->emitMachine(CPU);
- return false;
- }
- /// ParseDirectiveAbiVersion
- /// ::= .abiversion constant-expression
- bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
- int64_t AbiVersion;
- if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
- "expected constant expression") ||
- parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.abiversion' directive");
- PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
- getParser().getStreamer().getTargetStreamer());
- if (TStreamer != nullptr)
- TStreamer->emitAbiVersion(AbiVersion);
- return false;
- }
- /// ParseDirectiveLocalEntry
- /// ::= .localentry symbol, expression
- bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
- StringRef Name;
- if (getParser().parseIdentifier(Name))
- return Error(L, "expected identifier in '.localentry' directive");
- MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
- const MCExpr *Expr;
- if (parseToken(AsmToken::Comma) ||
- check(getParser().parseExpression(Expr), L, "expected expression") ||
- parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.localentry' directive");
- PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
- getParser().getStreamer().getTargetStreamer());
- if (TStreamer != nullptr)
- TStreamer->emitLocalEntry(Sym, Expr);
- return false;
- }
- /// Force static initialization.
- extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
- RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
- RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
- RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
- RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
- }
- #define GET_REGISTER_MATCHER
- #define GET_MATCHER_IMPLEMENTATION
- #define GET_MNEMONIC_SPELL_CHECKER
- #include "PPCGenAsmMatcher.inc"
- // Define this matcher function after the auto-generated include so we
- // have the match class enum definitions.
- unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
- unsigned Kind) {
- // If the kind is a token for a literal immediate, check if our asm
- // operand matches. This is for InstAliases which have a fixed-value
- // immediate in the syntax.
- int64_t ImmVal;
- switch (Kind) {
- case MCK_0: ImmVal = 0; break;
- case MCK_1: ImmVal = 1; break;
- case MCK_2: ImmVal = 2; break;
- case MCK_3: ImmVal = 3; break;
- case MCK_4: ImmVal = 4; break;
- case MCK_5: ImmVal = 5; break;
- case MCK_6: ImmVal = 6; break;
- case MCK_7: ImmVal = 7; break;
- default: return Match_InvalidOperand;
- }
- PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
- if (Op.isImm() && Op.getImm() == ImmVal)
- return Match_Success;
- return Match_InvalidOperand;
- }
- const MCExpr *
- PPCAsmParser::applyModifierToExpr(const MCExpr *E,
- MCSymbolRefExpr::VariantKind Variant,
- MCContext &Ctx) {
- switch (Variant) {
- case MCSymbolRefExpr::VK_PPC_LO:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HI:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HA:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGH:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGHA:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGHER:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGHERA:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGHEST:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, Ctx);
- case MCSymbolRefExpr::VK_PPC_HIGHESTA:
- return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, Ctx);
- default:
- return nullptr;
- }
- }
|