10b57cec5SDimitry Andric //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCExpr.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
110b57cec5SDimitry Andric #include "PPCTargetStreamer.h"
120b57cec5SDimitry Andric #include "TargetInfo/PowerPCTargetInfo.h"
130b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
140b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
26349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
270b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
280b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric
32bdd1243dSDimitry Andric DEFINE_PPC_REGCLASSES
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric // Evaluate an expression containing condition register
350b57cec5SDimitry Andric // or condition register field symbols. Returns positive
360b57cec5SDimitry Andric // value on success, or -1 on error.
370b57cec5SDimitry Andric static int64_t
EvaluateCRExpr(const MCExpr * E)380b57cec5SDimitry Andric EvaluateCRExpr(const MCExpr *E) {
390b57cec5SDimitry Andric switch (E->getKind()) {
400b57cec5SDimitry Andric case MCExpr::Target:
410b57cec5SDimitry Andric return -1;
420b57cec5SDimitry Andric
430b57cec5SDimitry Andric case MCExpr::Constant: {
440b57cec5SDimitry Andric int64_t Res = cast<MCConstantExpr>(E)->getValue();
450b57cec5SDimitry Andric return Res < 0 ? -1 : Res;
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric case MCExpr::SymbolRef: {
490b57cec5SDimitry Andric const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
500b57cec5SDimitry Andric StringRef Name = SRE->getSymbol().getName();
510b57cec5SDimitry Andric
520b57cec5SDimitry Andric if (Name == "lt") return 0;
530b57cec5SDimitry Andric if (Name == "gt") return 1;
540b57cec5SDimitry Andric if (Name == "eq") return 2;
550b57cec5SDimitry Andric if (Name == "so") return 3;
560b57cec5SDimitry Andric if (Name == "un") return 3;
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric if (Name == "cr0") return 0;
590b57cec5SDimitry Andric if (Name == "cr1") return 1;
600b57cec5SDimitry Andric if (Name == "cr2") return 2;
610b57cec5SDimitry Andric if (Name == "cr3") return 3;
620b57cec5SDimitry Andric if (Name == "cr4") return 4;
630b57cec5SDimitry Andric if (Name == "cr5") return 5;
640b57cec5SDimitry Andric if (Name == "cr6") return 6;
650b57cec5SDimitry Andric if (Name == "cr7") return 7;
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric return -1;
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric case MCExpr::Unary:
710b57cec5SDimitry Andric return -1;
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric case MCExpr::Binary: {
740b57cec5SDimitry Andric const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
750b57cec5SDimitry Andric int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
760b57cec5SDimitry Andric int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
770b57cec5SDimitry Andric int64_t Res;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric if (LHSVal < 0 || RHSVal < 0)
800b57cec5SDimitry Andric return -1;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric switch (BE->getOpcode()) {
830b57cec5SDimitry Andric default: return -1;
840b57cec5SDimitry Andric case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
850b57cec5SDimitry Andric case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric return Res < 0 ? -1 : Res;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric llvm_unreachable("Invalid expression kind!");
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric namespace {
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric struct PPCOperand;
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric class PPCAsmParser : public MCTargetAsmParser {
1000b57cec5SDimitry Andric bool IsPPC64;
1010b57cec5SDimitry Andric
Warning(SMLoc L,const Twine & Msg)1020b57cec5SDimitry Andric void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
1030b57cec5SDimitry Andric
isPPC64() const1040b57cec5SDimitry Andric bool isPPC64() const { return IsPPC64; }
1050b57cec5SDimitry Andric
106bdd1243dSDimitry Andric bool MatchRegisterName(MCRegister &RegNo, int64_t &IntVal);
1070b57cec5SDimitry Andric
1085f757f3fSDimitry Andric bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
1095f757f3fSDimitry Andric ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1105ffd83dbSDimitry Andric SMLoc &EndLoc) override;
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
1130b57cec5SDimitry Andric PPCMCExpr::VariantKind &Variant);
1140b57cec5SDimitry Andric const MCExpr *FixupVariantKind(const MCExpr *E);
1150b57cec5SDimitry Andric bool ParseExpression(const MCExpr *&EVal);
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric bool ParseOperand(OperandVector &Operands);
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric bool ParseDirectiveWord(unsigned Size, AsmToken ID);
1200b57cec5SDimitry Andric bool ParseDirectiveTC(unsigned Size, AsmToken ID);
1210b57cec5SDimitry Andric bool ParseDirectiveMachine(SMLoc L);
1220b57cec5SDimitry Andric bool ParseDirectiveAbiVersion(SMLoc L);
1230b57cec5SDimitry Andric bool ParseDirectiveLocalEntry(SMLoc L);
12404eeddc0SDimitry Andric bool ParseGNUAttribute(SMLoc L);
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1270b57cec5SDimitry Andric OperandVector &Operands, MCStreamer &Out,
1280b57cec5SDimitry Andric uint64_t &ErrorInfo,
1290b57cec5SDimitry Andric bool MatchingInlineAsm) override;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric /// @name Auto-generated Match Functions
1340b57cec5SDimitry Andric /// {
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric #define GET_ASSEMBLER_HEADER
1370b57cec5SDimitry Andric #include "PPCGenAsmMatcher.inc"
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric /// }
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andric public:
PPCAsmParser(const MCSubtargetInfo & STI,MCAsmParser &,const MCInstrInfo & MII,const MCTargetOptions & Options)1430b57cec5SDimitry Andric PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
1440b57cec5SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options)
1450b57cec5SDimitry Andric : MCTargetAsmParser(Options, STI, MII) {
1460b57cec5SDimitry Andric // Check for 64-bit vs. 32-bit pointer mode.
1470b57cec5SDimitry Andric const Triple &TheTriple = STI.getTargetTriple();
1480b57cec5SDimitry Andric IsPPC64 = TheTriple.isPPC64();
1490b57cec5SDimitry Andric // Initialize the set of available features.
1500b57cec5SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1540b57cec5SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override;
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric bool ParseDirective(AsmToken DirectiveID) override;
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
1590b57cec5SDimitry Andric unsigned Kind) override;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric const MCExpr *applyModifierToExpr(const MCExpr *E,
1620b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind,
1630b57cec5SDimitry Andric MCContext &Ctx) override;
1640b57cec5SDimitry Andric };
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric /// PPCOperand - Instances of this class represent a parsed PowerPC machine
1670b57cec5SDimitry Andric /// instruction.
1680b57cec5SDimitry Andric struct PPCOperand : public MCParsedAsmOperand {
1690b57cec5SDimitry Andric enum KindTy {
1700b57cec5SDimitry Andric Token,
1710b57cec5SDimitry Andric Immediate,
1720b57cec5SDimitry Andric ContextImmediate,
1730b57cec5SDimitry Andric Expression,
1740b57cec5SDimitry Andric TLSRegister
1750b57cec5SDimitry Andric } Kind;
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric SMLoc StartLoc, EndLoc;
1780b57cec5SDimitry Andric bool IsPPC64;
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric struct TokOp {
1810b57cec5SDimitry Andric const char *Data;
1820b57cec5SDimitry Andric unsigned Length;
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric struct ImmOp {
1860b57cec5SDimitry Andric int64_t Val;
1870b57cec5SDimitry Andric };
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric struct ExprOp {
1900b57cec5SDimitry Andric const MCExpr *Val;
1910b57cec5SDimitry Andric int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
1920b57cec5SDimitry Andric };
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric struct TLSRegOp {
1950b57cec5SDimitry Andric const MCSymbolRefExpr *Sym;
1960b57cec5SDimitry Andric };
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric union {
1990b57cec5SDimitry Andric struct TokOp Tok;
2000b57cec5SDimitry Andric struct ImmOp Imm;
2010b57cec5SDimitry Andric struct ExprOp Expr;
2020b57cec5SDimitry Andric struct TLSRegOp TLSReg;
2030b57cec5SDimitry Andric };
2040b57cec5SDimitry Andric
PPCOperand__anon49f2f9030111::PPCOperand20504eeddc0SDimitry Andric PPCOperand(KindTy K) : Kind(K) {}
20604eeddc0SDimitry Andric
2070b57cec5SDimitry Andric public:
PPCOperand__anon49f2f9030111::PPCOperand2080b57cec5SDimitry Andric PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
2090b57cec5SDimitry Andric Kind = o.Kind;
2100b57cec5SDimitry Andric StartLoc = o.StartLoc;
2110b57cec5SDimitry Andric EndLoc = o.EndLoc;
2120b57cec5SDimitry Andric IsPPC64 = o.IsPPC64;
2130b57cec5SDimitry Andric switch (Kind) {
2140b57cec5SDimitry Andric case Token:
2150b57cec5SDimitry Andric Tok = o.Tok;
2160b57cec5SDimitry Andric break;
2170b57cec5SDimitry Andric case Immediate:
2180b57cec5SDimitry Andric case ContextImmediate:
2190b57cec5SDimitry Andric Imm = o.Imm;
2200b57cec5SDimitry Andric break;
2210b57cec5SDimitry Andric case Expression:
2220b57cec5SDimitry Andric Expr = o.Expr;
2230b57cec5SDimitry Andric break;
2240b57cec5SDimitry Andric case TLSRegister:
2250b57cec5SDimitry Andric TLSReg = o.TLSReg;
2260b57cec5SDimitry Andric break;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric // Disable use of sized deallocation due to overallocation of PPCOperand
2310b57cec5SDimitry Andric // objects in CreateTokenWithStringCopy.
operator delete__anon49f2f9030111::PPCOperand2320b57cec5SDimitry Andric void operator delete(void *p) { ::operator delete(p); }
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric /// getStartLoc - Get the location of the first token of this operand.
getStartLoc__anon49f2f9030111::PPCOperand2350b57cec5SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; }
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric /// getEndLoc - Get the location of the last token of this operand.
getEndLoc__anon49f2f9030111::PPCOperand2380b57cec5SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; }
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric /// getLocRange - Get the range between the first and last token of this
2410b57cec5SDimitry Andric /// operand.
getLocRange__anon49f2f9030111::PPCOperand2420b57cec5SDimitry Andric SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
isPPC64__anon49f2f9030111::PPCOperand2450b57cec5SDimitry Andric bool isPPC64() const { return IsPPC64; }
2460b57cec5SDimitry Andric
getImm__anon49f2f9030111::PPCOperand2470b57cec5SDimitry Andric int64_t getImm() const {
2480b57cec5SDimitry Andric assert(Kind == Immediate && "Invalid access!");
2490b57cec5SDimitry Andric return Imm.Val;
2500b57cec5SDimitry Andric }
getImmS16Context__anon49f2f9030111::PPCOperand2510b57cec5SDimitry Andric int64_t getImmS16Context() const {
2520b57cec5SDimitry Andric assert((Kind == Immediate || Kind == ContextImmediate) &&
2530b57cec5SDimitry Andric "Invalid access!");
2540b57cec5SDimitry Andric if (Kind == Immediate)
2550b57cec5SDimitry Andric return Imm.Val;
2560b57cec5SDimitry Andric return static_cast<int16_t>(Imm.Val);
2570b57cec5SDimitry Andric }
getImmU16Context__anon49f2f9030111::PPCOperand2580b57cec5SDimitry Andric int64_t getImmU16Context() const {
2590b57cec5SDimitry Andric assert((Kind == Immediate || Kind == ContextImmediate) &&
2600b57cec5SDimitry Andric "Invalid access!");
2610b57cec5SDimitry Andric return Imm.Val;
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric
getExpr__anon49f2f9030111::PPCOperand2640b57cec5SDimitry Andric const MCExpr *getExpr() const {
2650b57cec5SDimitry Andric assert(Kind == Expression && "Invalid access!");
2660b57cec5SDimitry Andric return Expr.Val;
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric
getExprCRVal__anon49f2f9030111::PPCOperand2690b57cec5SDimitry Andric int64_t getExprCRVal() const {
2700b57cec5SDimitry Andric assert(Kind == Expression && "Invalid access!");
2710b57cec5SDimitry Andric return Expr.CRVal;
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
getTLSReg__anon49f2f9030111::PPCOperand2740b57cec5SDimitry Andric const MCExpr *getTLSReg() const {
2750b57cec5SDimitry Andric assert(Kind == TLSRegister && "Invalid access!");
2760b57cec5SDimitry Andric return TLSReg.Sym;
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
getReg__anon49f2f9030111::PPCOperand279*0fca6ea1SDimitry Andric MCRegister getReg() const override { llvm_unreachable("Not implemented"); }
280*0fca6ea1SDimitry Andric
getRegNum__anon49f2f9030111::PPCOperand281*0fca6ea1SDimitry Andric unsigned getRegNum() const {
2820b57cec5SDimitry Andric assert(isRegNumber() && "Invalid access!");
2830b57cec5SDimitry Andric return (unsigned)Imm.Val;
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric
getFpReg__anon49f2f9030111::PPCOperand28606c3fb27SDimitry Andric unsigned getFpReg() const {
28706c3fb27SDimitry Andric assert(isEvenRegNumber() && "Invalid access!");
28806c3fb27SDimitry Andric return (unsigned)(Imm.Val >> 1);
28906c3fb27SDimitry Andric }
29006c3fb27SDimitry Andric
getVSReg__anon49f2f9030111::PPCOperand2910b57cec5SDimitry Andric unsigned getVSReg() const {
2920b57cec5SDimitry Andric assert(isVSRegNumber() && "Invalid access!");
2930b57cec5SDimitry Andric return (unsigned) Imm.Val;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric
getACCReg__anon49f2f9030111::PPCOperand296e8d8bef9SDimitry Andric unsigned getACCReg() const {
297e8d8bef9SDimitry Andric assert(isACCRegNumber() && "Invalid access!");
298e8d8bef9SDimitry Andric return (unsigned) Imm.Val;
299e8d8bef9SDimitry Andric }
300e8d8bef9SDimitry Andric
getDMRROWReg__anon49f2f9030111::PPCOperand301bdd1243dSDimitry Andric unsigned getDMRROWReg() const {
302bdd1243dSDimitry Andric assert(isDMRROWRegNumber() && "Invalid access!");
303bdd1243dSDimitry Andric return (unsigned)Imm.Val;
304bdd1243dSDimitry Andric }
305bdd1243dSDimitry Andric
getDMRROWpReg__anon49f2f9030111::PPCOperand306bdd1243dSDimitry Andric unsigned getDMRROWpReg() const {
307bdd1243dSDimitry Andric assert(isDMRROWpRegNumber() && "Invalid access!");
308bdd1243dSDimitry Andric return (unsigned)Imm.Val;
309bdd1243dSDimitry Andric }
310bdd1243dSDimitry Andric
getDMRReg__anon49f2f9030111::PPCOperand311bdd1243dSDimitry Andric unsigned getDMRReg() const {
312bdd1243dSDimitry Andric assert(isDMRRegNumber() && "Invalid access!");
313bdd1243dSDimitry Andric return (unsigned)Imm.Val;
314bdd1243dSDimitry Andric }
315bdd1243dSDimitry Andric
getDMRpReg__anon49f2f9030111::PPCOperand316bdd1243dSDimitry Andric unsigned getDMRpReg() const {
317bdd1243dSDimitry Andric assert(isDMRpRegNumber() && "Invalid access!");
318bdd1243dSDimitry Andric return (unsigned)Imm.Val;
319bdd1243dSDimitry Andric }
320bdd1243dSDimitry Andric
getVSRpEvenReg__anon49f2f9030111::PPCOperand321e8d8bef9SDimitry Andric unsigned getVSRpEvenReg() const {
322e8d8bef9SDimitry Andric assert(isVSRpEvenRegNumber() && "Invalid access!");
323e8d8bef9SDimitry Andric return (unsigned) Imm.Val >> 1;
324e8d8bef9SDimitry Andric }
325e8d8bef9SDimitry Andric
getG8pReg__anon49f2f9030111::PPCOperand326fe6060f1SDimitry Andric unsigned getG8pReg() const {
327fe6060f1SDimitry Andric assert(isEvenRegNumber() && "Invalid access!");
328fe6060f1SDimitry Andric return (unsigned)Imm.Val;
329fe6060f1SDimitry Andric }
330fe6060f1SDimitry Andric
getCCReg__anon49f2f9030111::PPCOperand3310b57cec5SDimitry Andric unsigned getCCReg() const {
3320b57cec5SDimitry Andric assert(isCCRegNumber() && "Invalid access!");
3330b57cec5SDimitry Andric return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric
getCRBit__anon49f2f9030111::PPCOperand3360b57cec5SDimitry Andric unsigned getCRBit() const {
3370b57cec5SDimitry Andric assert(isCRBitNumber() && "Invalid access!");
3380b57cec5SDimitry Andric return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric
getCRBitMask__anon49f2f9030111::PPCOperand3410b57cec5SDimitry Andric unsigned getCRBitMask() const {
3420b57cec5SDimitry Andric assert(isCRBitMask() && "Invalid access!");
34306c3fb27SDimitry Andric return 7 - llvm::countr_zero<uint64_t>(Imm.Val);
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric
isToken__anon49f2f9030111::PPCOperand3460b57cec5SDimitry Andric bool isToken() const override { return Kind == Token; }
isImm__anon49f2f9030111::PPCOperand3470b57cec5SDimitry Andric bool isImm() const override {
3480b57cec5SDimitry Andric return Kind == Immediate || Kind == Expression;
3490b57cec5SDimitry Andric }
isU1Imm__anon49f2f9030111::PPCOperand3500b57cec5SDimitry Andric bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
isU2Imm__anon49f2f9030111::PPCOperand3510b57cec5SDimitry Andric bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
isU3Imm__anon49f2f9030111::PPCOperand3520b57cec5SDimitry Andric bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
isU4Imm__anon49f2f9030111::PPCOperand3530b57cec5SDimitry Andric bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
isU5Imm__anon49f2f9030111::PPCOperand3540b57cec5SDimitry Andric bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
isS5Imm__anon49f2f9030111::PPCOperand3550b57cec5SDimitry Andric bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
isU6Imm__anon49f2f9030111::PPCOperand3560b57cec5SDimitry Andric bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
isU6ImmX2__anon49f2f9030111::PPCOperand3570b57cec5SDimitry Andric bool isU6ImmX2() const { return Kind == Immediate &&
3580b57cec5SDimitry Andric isUInt<6>(getImm()) &&
3590b57cec5SDimitry Andric (getImm() & 1) == 0; }
isU7Imm__anon49f2f9030111::PPCOperand3600b57cec5SDimitry Andric bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
isU7ImmX4__anon49f2f9030111::PPCOperand3610b57cec5SDimitry Andric bool isU7ImmX4() const { return Kind == Immediate &&
3620b57cec5SDimitry Andric isUInt<7>(getImm()) &&
3630b57cec5SDimitry Andric (getImm() & 3) == 0; }
isU8Imm__anon49f2f9030111::PPCOperand3640b57cec5SDimitry Andric bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
isU8ImmX8__anon49f2f9030111::PPCOperand3650b57cec5SDimitry Andric bool isU8ImmX8() const { return Kind == Immediate &&
3660b57cec5SDimitry Andric isUInt<8>(getImm()) &&
3670b57cec5SDimitry Andric (getImm() & 7) == 0; }
3680b57cec5SDimitry Andric
isU10Imm__anon49f2f9030111::PPCOperand3690b57cec5SDimitry Andric bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
isU12Imm__anon49f2f9030111::PPCOperand3700b57cec5SDimitry Andric bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
isU16Imm__anon49f2f9030111::PPCOperand3713a9a9c0cSDimitry Andric bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }
isS16Imm__anon49f2f9030111::PPCOperand3723a9a9c0cSDimitry Andric bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }
isS16ImmX4__anon49f2f9030111::PPCOperand3733a9a9c0cSDimitry Andric bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }
isS16ImmX16__anon49f2f9030111::PPCOperand3743a9a9c0cSDimitry Andric bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }
isS17Imm__anon49f2f9030111::PPCOperand3753a9a9c0cSDimitry Andric bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }
376fe6060f1SDimitry Andric
isHashImmX8__anon49f2f9030111::PPCOperand377fe6060f1SDimitry Andric bool isHashImmX8() const {
378fe6060f1SDimitry Andric // The Hash Imm form is used for instructions that check or store a hash.
379fe6060f1SDimitry Andric // These instructions have a small immediate range that spans between
380fe6060f1SDimitry Andric // -8 and -512.
381fe6060f1SDimitry Andric return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
382fe6060f1SDimitry Andric (getImm() & 7) == 0);
383fe6060f1SDimitry Andric }
384fe6060f1SDimitry Andric
isS34ImmX16__anon49f2f9030111::PPCOperand3855ffd83dbSDimitry Andric bool isS34ImmX16() const {
3865ffd83dbSDimitry Andric return Kind == Expression ||
3875ffd83dbSDimitry Andric (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
3885ffd83dbSDimitry Andric }
isS34Imm__anon49f2f9030111::PPCOperand3895ffd83dbSDimitry Andric bool isS34Imm() const {
3905ffd83dbSDimitry Andric // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
3915ffd83dbSDimitry Andric // ContextImmediate is needed.
3925ffd83dbSDimitry Andric return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
3935ffd83dbSDimitry Andric }
3945ffd83dbSDimitry Andric
isTLSReg__anon49f2f9030111::PPCOperand3950b57cec5SDimitry Andric bool isTLSReg() const { return Kind == TLSRegister; }
isDirectBr__anon49f2f9030111::PPCOperand3960b57cec5SDimitry Andric bool isDirectBr() const {
3970b57cec5SDimitry Andric if (Kind == Expression)
3980b57cec5SDimitry Andric return true;
3990b57cec5SDimitry Andric if (Kind != Immediate)
4000b57cec5SDimitry Andric return false;
4010b57cec5SDimitry Andric // Operand must be 64-bit aligned, signed 27-bit immediate.
4020b57cec5SDimitry Andric if ((getImm() & 3) != 0)
4030b57cec5SDimitry Andric return false;
4040b57cec5SDimitry Andric if (isInt<26>(getImm()))
4050b57cec5SDimitry Andric return true;
4060b57cec5SDimitry Andric if (!IsPPC64) {
4070b57cec5SDimitry Andric // In 32-bit mode, large 32-bit quantities wrap around.
4080b57cec5SDimitry Andric if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
4090b57cec5SDimitry Andric return true;
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric return false;
4120b57cec5SDimitry Andric }
isCondBr__anon49f2f9030111::PPCOperand4130b57cec5SDimitry Andric bool isCondBr() const { return Kind == Expression ||
4140b57cec5SDimitry Andric (Kind == Immediate && isInt<16>(getImm()) &&
4150b57cec5SDimitry Andric (getImm() & 3) == 0); }
isImmZero__anon49f2f9030111::PPCOperand4165ffd83dbSDimitry Andric bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
isRegNumber__anon49f2f9030111::PPCOperand4170b57cec5SDimitry Andric bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
isACCRegNumber__anon49f2f9030111::PPCOperand418e8d8bef9SDimitry Andric bool isACCRegNumber() const {
419e8d8bef9SDimitry Andric return Kind == Immediate && isUInt<3>(getImm());
420e8d8bef9SDimitry Andric }
isDMRROWRegNumber__anon49f2f9030111::PPCOperand421bdd1243dSDimitry Andric bool isDMRROWRegNumber() const {
422bdd1243dSDimitry Andric return Kind == Immediate && isUInt<6>(getImm());
423bdd1243dSDimitry Andric }
isDMRROWpRegNumber__anon49f2f9030111::PPCOperand424bdd1243dSDimitry Andric bool isDMRROWpRegNumber() const {
425bdd1243dSDimitry Andric return Kind == Immediate && isUInt<5>(getImm());
426bdd1243dSDimitry Andric }
isDMRRegNumber__anon49f2f9030111::PPCOperand427bdd1243dSDimitry Andric bool isDMRRegNumber() const {
428bdd1243dSDimitry Andric return Kind == Immediate && isUInt<3>(getImm());
429bdd1243dSDimitry Andric }
isDMRpRegNumber__anon49f2f9030111::PPCOperand430bdd1243dSDimitry Andric bool isDMRpRegNumber() const {
431bdd1243dSDimitry Andric return Kind == Immediate && isUInt<2>(getImm());
432bdd1243dSDimitry Andric }
isVSRpEvenRegNumber__anon49f2f9030111::PPCOperand433e8d8bef9SDimitry Andric bool isVSRpEvenRegNumber() const {
434e8d8bef9SDimitry Andric return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
435e8d8bef9SDimitry Andric }
isVSRegNumber__anon49f2f9030111::PPCOperand4360b57cec5SDimitry Andric bool isVSRegNumber() const {
4370b57cec5SDimitry Andric return Kind == Immediate && isUInt<6>(getImm());
4380b57cec5SDimitry Andric }
isCCRegNumber__anon49f2f9030111::PPCOperand4390b57cec5SDimitry Andric bool isCCRegNumber() const { return (Kind == Expression
4400b57cec5SDimitry Andric && isUInt<3>(getExprCRVal())) ||
4410b57cec5SDimitry Andric (Kind == Immediate
4420b57cec5SDimitry Andric && isUInt<3>(getImm())); }
isCRBitNumber__anon49f2f9030111::PPCOperand4430b57cec5SDimitry Andric bool isCRBitNumber() const { return (Kind == Expression
4440b57cec5SDimitry Andric && isUInt<5>(getExprCRVal())) ||
4450b57cec5SDimitry Andric (Kind == Immediate
4460b57cec5SDimitry Andric && isUInt<5>(getImm())); }
447fe6060f1SDimitry Andric
isEvenRegNumber__anon49f2f9030111::PPCOperand448fe6060f1SDimitry Andric bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }
449fe6060f1SDimitry Andric
isCRBitMask__anon49f2f9030111::PPCOperand45006c3fb27SDimitry Andric bool isCRBitMask() const {
45106c3fb27SDimitry Andric return Kind == Immediate && isUInt<8>(getImm()) &&
45206c3fb27SDimitry Andric llvm::has_single_bit<uint32_t>(getImm());
45306c3fb27SDimitry Andric }
isATBitsAsHint__anon49f2f9030111::PPCOperand4540b57cec5SDimitry Andric bool isATBitsAsHint() const { return false; }
isMem__anon49f2f9030111::PPCOperand4550b57cec5SDimitry Andric bool isMem() const override { return false; }
isReg__anon49f2f9030111::PPCOperand4560b57cec5SDimitry Andric bool isReg() const override { return false; }
4570b57cec5SDimitry Andric
addRegOperands__anon49f2f9030111::PPCOperand4580b57cec5SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const {
4590b57cec5SDimitry Andric llvm_unreachable("addRegOperands");
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric
addRegGPRCOperands__anon49f2f9030111::PPCOperand4620b57cec5SDimitry Andric void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
4630b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
464*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));
4650b57cec5SDimitry Andric }
4660b57cec5SDimitry Andric
addRegGPRCNoR0Operands__anon49f2f9030111::PPCOperand4670b57cec5SDimitry Andric void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
4680b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
469*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(RRegsNoR0[getRegNum()]));
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric
addRegG8RCOperands__anon49f2f9030111::PPCOperand4720b57cec5SDimitry Andric void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
4730b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
474*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(XRegs[getRegNum()]));
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric
addRegG8RCNoX0Operands__anon49f2f9030111::PPCOperand4770b57cec5SDimitry Andric void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
4780b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
479*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(XRegsNoX0[getRegNum()]));
4800b57cec5SDimitry Andric }
4810b57cec5SDimitry Andric
addRegG8pRCOperands__anon49f2f9030111::PPCOperand482fe6060f1SDimitry Andric void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {
483fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!");
484fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));
485fe6060f1SDimitry Andric }
486fe6060f1SDimitry Andric
addRegGxRCOperands__anon49f2f9030111::PPCOperand4870b57cec5SDimitry Andric void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
4880b57cec5SDimitry Andric if (isPPC64())
4890b57cec5SDimitry Andric addRegG8RCOperands(Inst, N);
4900b57cec5SDimitry Andric else
4910b57cec5SDimitry Andric addRegGPRCOperands(Inst, N);
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric
addRegGxRCNoR0Operands__anon49f2f9030111::PPCOperand4940b57cec5SDimitry Andric void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
4950b57cec5SDimitry Andric if (isPPC64())
4960b57cec5SDimitry Andric addRegG8RCNoX0Operands(Inst, N);
4970b57cec5SDimitry Andric else
4980b57cec5SDimitry Andric addRegGPRCNoR0Operands(Inst, N);
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric
addRegF4RCOperands__anon49f2f9030111::PPCOperand5010b57cec5SDimitry Andric void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
5020b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
503*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric
addRegF8RCOperands__anon49f2f9030111::PPCOperand5060b57cec5SDimitry Andric void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
5070b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
508*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric
addRegFpRCOperands__anon49f2f9030111::PPCOperand51106c3fb27SDimitry Andric void addRegFpRCOperands(MCInst &Inst, unsigned N) const {
51206c3fb27SDimitry Andric assert(N == 1 && "Invalid number of operands!");
51306c3fb27SDimitry Andric Inst.addOperand(MCOperand::createReg(FpRegs[getFpReg()]));
51406c3fb27SDimitry Andric }
51506c3fb27SDimitry Andric
addRegVFRCOperands__anon49f2f9030111::PPCOperand5160b57cec5SDimitry Andric void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
5170b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
518*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(VFRegs[getRegNum()]));
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric
addRegVRRCOperands__anon49f2f9030111::PPCOperand5210b57cec5SDimitry Andric void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
5220b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
523*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(VRegs[getRegNum()]));
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric
addRegVSRCOperands__anon49f2f9030111::PPCOperand5260b57cec5SDimitry Andric void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
5270b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
5280b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
addRegVSFRCOperands__anon49f2f9030111::PPCOperand5310b57cec5SDimitry Andric void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
5320b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
5330b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric
addRegVSSRCOperands__anon49f2f9030111::PPCOperand5360b57cec5SDimitry Andric void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
5370b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
5380b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric
addRegSPE4RCOperands__anon49f2f9030111::PPCOperand5410b57cec5SDimitry Andric void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
5420b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
543*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric
addRegSPERCOperands__anon49f2f9030111::PPCOperand5460b57cec5SDimitry Andric void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
5470b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
548*0fca6ea1SDimitry Andric Inst.addOperand(MCOperand::createReg(SPERegs[getRegNum()]));
5490b57cec5SDimitry Andric }
5500b57cec5SDimitry Andric
addRegACCRCOperands__anon49f2f9030111::PPCOperand551e8d8bef9SDimitry Andric void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
552e8d8bef9SDimitry Andric assert(N == 1 && "Invalid number of operands!");
553e8d8bef9SDimitry Andric Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
554e8d8bef9SDimitry Andric }
555e8d8bef9SDimitry Andric
addRegDMRROWRCOperands__anon49f2f9030111::PPCOperand556bdd1243dSDimitry Andric void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const {
557bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
558bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(DMRROWRegs[getDMRROWReg()]));
559bdd1243dSDimitry Andric }
560bdd1243dSDimitry Andric
addRegDMRROWpRCOperands__anon49f2f9030111::PPCOperand561bdd1243dSDimitry Andric void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const {
562bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
563bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(DMRROWpRegs[getDMRROWpReg()]));
564bdd1243dSDimitry Andric }
565bdd1243dSDimitry Andric
addRegDMRRCOperands__anon49f2f9030111::PPCOperand566bdd1243dSDimitry Andric void addRegDMRRCOperands(MCInst &Inst, unsigned N) const {
567bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
568bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(DMRRegs[getDMRReg()]));
569bdd1243dSDimitry Andric }
570bdd1243dSDimitry Andric
addRegDMRpRCOperands__anon49f2f9030111::PPCOperand571bdd1243dSDimitry Andric void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const {
572bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
573bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(DMRpRegs[getDMRpReg()]));
574bdd1243dSDimitry Andric }
575bdd1243dSDimitry Andric
addRegWACCRCOperands__anon49f2f9030111::PPCOperand576bdd1243dSDimitry Andric void addRegWACCRCOperands(MCInst &Inst, unsigned N) const {
577bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
578bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(WACCRegs[getACCReg()]));
579bdd1243dSDimitry Andric }
580bdd1243dSDimitry Andric
addRegWACC_HIRCOperands__anon49f2f9030111::PPCOperand581bdd1243dSDimitry Andric void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const {
582bdd1243dSDimitry Andric assert(N == 1 && "Invalid number of operands!");
583bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createReg(WACC_HIRegs[getACCReg()]));
584bdd1243dSDimitry Andric }
585bdd1243dSDimitry Andric
addRegVSRpRCOperands__anon49f2f9030111::PPCOperand586e8d8bef9SDimitry Andric void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
587e8d8bef9SDimitry Andric assert(N == 1 && "Invalid number of operands!");
588e8d8bef9SDimitry Andric Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
589e8d8bef9SDimitry Andric }
590e8d8bef9SDimitry Andric
addRegVSRpEvenRCOperands__anon49f2f9030111::PPCOperand591e8d8bef9SDimitry Andric void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
592e8d8bef9SDimitry Andric assert(N == 1 && "Invalid number of operands!");
593e8d8bef9SDimitry Andric Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
594e8d8bef9SDimitry Andric }
595e8d8bef9SDimitry Andric
addRegCRBITRCOperands__anon49f2f9030111::PPCOperand5960b57cec5SDimitry Andric void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
5970b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
5980b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric
addRegCRRCOperands__anon49f2f9030111::PPCOperand6010b57cec5SDimitry Andric void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
6020b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6030b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric
addCRBitMaskOperands__anon49f2f9030111::PPCOperand6060b57cec5SDimitry Andric void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
6070b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6080b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
6090b57cec5SDimitry Andric }
6100b57cec5SDimitry Andric
addImmOperands__anon49f2f9030111::PPCOperand6110b57cec5SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const {
6120b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6130b57cec5SDimitry Andric if (Kind == Immediate)
6140b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImm()));
6150b57cec5SDimitry Andric else
6160b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getExpr()));
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric
addS16ImmOperands__anon49f2f9030111::PPCOperand6190b57cec5SDimitry Andric void addS16ImmOperands(MCInst &Inst, unsigned N) const {
6200b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6210b57cec5SDimitry Andric switch (Kind) {
6220b57cec5SDimitry Andric case Immediate:
6230b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImm()));
6240b57cec5SDimitry Andric break;
6250b57cec5SDimitry Andric case ContextImmediate:
6260b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImmS16Context()));
6270b57cec5SDimitry Andric break;
6280b57cec5SDimitry Andric default:
6290b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getExpr()));
6300b57cec5SDimitry Andric break;
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric
addU16ImmOperands__anon49f2f9030111::PPCOperand6340b57cec5SDimitry Andric void addU16ImmOperands(MCInst &Inst, unsigned N) const {
6350b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6360b57cec5SDimitry Andric switch (Kind) {
6370b57cec5SDimitry Andric case Immediate:
6380b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImm()));
6390b57cec5SDimitry Andric break;
6400b57cec5SDimitry Andric case ContextImmediate:
6410b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImmU16Context()));
6420b57cec5SDimitry Andric break;
6430b57cec5SDimitry Andric default:
6440b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getExpr()));
6450b57cec5SDimitry Andric break;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric }
6480b57cec5SDimitry Andric
addBranchTargetOperands__anon49f2f9030111::PPCOperand6490b57cec5SDimitry Andric void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
6500b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6510b57cec5SDimitry Andric if (Kind == Immediate)
6520b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getImm() / 4));
6530b57cec5SDimitry Andric else
6540b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getExpr()));
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric
addTLSRegOperands__anon49f2f9030111::PPCOperand6570b57cec5SDimitry Andric void addTLSRegOperands(MCInst &Inst, unsigned N) const {
6580b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!");
6590b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getTLSReg()));
6600b57cec5SDimitry Andric }
6610b57cec5SDimitry Andric
getToken__anon49f2f9030111::PPCOperand6620b57cec5SDimitry Andric StringRef getToken() const {
6630b57cec5SDimitry Andric assert(Kind == Token && "Invalid access!");
6640b57cec5SDimitry Andric return StringRef(Tok.Data, Tok.Length);
6650b57cec5SDimitry Andric }
6660b57cec5SDimitry Andric
6670b57cec5SDimitry Andric void print(raw_ostream &OS) const override;
6680b57cec5SDimitry Andric
CreateToken__anon49f2f9030111::PPCOperand6690b57cec5SDimitry Andric static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
6700b57cec5SDimitry Andric bool IsPPC64) {
6718bcb0991SDimitry Andric auto Op = std::make_unique<PPCOperand>(Token);
6720b57cec5SDimitry Andric Op->Tok.Data = Str.data();
6730b57cec5SDimitry Andric Op->Tok.Length = Str.size();
6740b57cec5SDimitry Andric Op->StartLoc = S;
6750b57cec5SDimitry Andric Op->EndLoc = S;
6760b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
6770b57cec5SDimitry Andric return Op;
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric
6800b57cec5SDimitry Andric static std::unique_ptr<PPCOperand>
CreateTokenWithStringCopy__anon49f2f9030111::PPCOperand6810b57cec5SDimitry Andric CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
6820b57cec5SDimitry Andric // Allocate extra memory for the string and copy it.
6830b57cec5SDimitry Andric // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
6840b57cec5SDimitry Andric // deleter which will destroy them by simply using "delete", not correctly
6850b57cec5SDimitry Andric // calling operator delete on this extra memory after calling the dtor
6860b57cec5SDimitry Andric // explicitly.
6870b57cec5SDimitry Andric void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
6880b57cec5SDimitry Andric std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
6890b57cec5SDimitry Andric Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
6900b57cec5SDimitry Andric Op->Tok.Length = Str.size();
6910b57cec5SDimitry Andric std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
6920b57cec5SDimitry Andric Op->StartLoc = S;
6930b57cec5SDimitry Andric Op->EndLoc = S;
6940b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
6950b57cec5SDimitry Andric return Op;
6960b57cec5SDimitry Andric }
6970b57cec5SDimitry Andric
CreateImm__anon49f2f9030111::PPCOperand6980b57cec5SDimitry Andric static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
6990b57cec5SDimitry Andric bool IsPPC64) {
7008bcb0991SDimitry Andric auto Op = std::make_unique<PPCOperand>(Immediate);
7010b57cec5SDimitry Andric Op->Imm.Val = Val;
7020b57cec5SDimitry Andric Op->StartLoc = S;
7030b57cec5SDimitry Andric Op->EndLoc = E;
7040b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
7050b57cec5SDimitry Andric return Op;
7060b57cec5SDimitry Andric }
7070b57cec5SDimitry Andric
CreateExpr__anon49f2f9030111::PPCOperand7080b57cec5SDimitry Andric static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
7090b57cec5SDimitry Andric SMLoc E, bool IsPPC64) {
7108bcb0991SDimitry Andric auto Op = std::make_unique<PPCOperand>(Expression);
7110b57cec5SDimitry Andric Op->Expr.Val = Val;
7120b57cec5SDimitry Andric Op->Expr.CRVal = EvaluateCRExpr(Val);
7130b57cec5SDimitry Andric Op->StartLoc = S;
7140b57cec5SDimitry Andric Op->EndLoc = E;
7150b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
7160b57cec5SDimitry Andric return Op;
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric static std::unique_ptr<PPCOperand>
CreateTLSReg__anon49f2f9030111::PPCOperand7200b57cec5SDimitry Andric CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
7218bcb0991SDimitry Andric auto Op = std::make_unique<PPCOperand>(TLSRegister);
7220b57cec5SDimitry Andric Op->TLSReg.Sym = Sym;
7230b57cec5SDimitry Andric Op->StartLoc = S;
7240b57cec5SDimitry Andric Op->EndLoc = E;
7250b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
7260b57cec5SDimitry Andric return Op;
7270b57cec5SDimitry Andric }
7280b57cec5SDimitry Andric
7290b57cec5SDimitry Andric static std::unique_ptr<PPCOperand>
CreateContextImm__anon49f2f9030111::PPCOperand7300b57cec5SDimitry Andric CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
7318bcb0991SDimitry Andric auto Op = std::make_unique<PPCOperand>(ContextImmediate);
7320b57cec5SDimitry Andric Op->Imm.Val = Val;
7330b57cec5SDimitry Andric Op->StartLoc = S;
7340b57cec5SDimitry Andric Op->EndLoc = E;
7350b57cec5SDimitry Andric Op->IsPPC64 = IsPPC64;
7360b57cec5SDimitry Andric return Op;
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric static std::unique_ptr<PPCOperand>
CreateFromMCExpr__anon49f2f9030111::PPCOperand7400b57cec5SDimitry Andric CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
7410b57cec5SDimitry Andric if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
7420b57cec5SDimitry Andric return CreateImm(CE->getValue(), S, E, IsPPC64);
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andric if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
745e8d8bef9SDimitry Andric if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
746e8d8bef9SDimitry Andric SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
7470b57cec5SDimitry Andric return CreateTLSReg(SRE, S, E, IsPPC64);
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
7500b57cec5SDimitry Andric int64_t Res;
7510b57cec5SDimitry Andric if (TE->evaluateAsConstant(Res))
7520b57cec5SDimitry Andric return CreateContextImm(Res, S, E, IsPPC64);
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andric return CreateExpr(Val, S, E, IsPPC64);
7560b57cec5SDimitry Andric }
7573a9a9c0cSDimitry Andric
7583a9a9c0cSDimitry Andric private:
7593a9a9c0cSDimitry Andric template <unsigned Width>
isExtImm__anon49f2f9030111::PPCOperand7603a9a9c0cSDimitry Andric bool isExtImm(bool Signed, unsigned Multiple) const {
7613a9a9c0cSDimitry Andric switch (Kind) {
7623a9a9c0cSDimitry Andric default:
7633a9a9c0cSDimitry Andric return false;
7643a9a9c0cSDimitry Andric case Expression:
7653a9a9c0cSDimitry Andric return true;
7663a9a9c0cSDimitry Andric case Immediate:
7673a9a9c0cSDimitry Andric case ContextImmediate:
7683a9a9c0cSDimitry Andric if (Signed)
7693a9a9c0cSDimitry Andric return isInt<Width>(getImmS16Context()) &&
7703a9a9c0cSDimitry Andric (getImmS16Context() & (Multiple - 1)) == 0;
7713a9a9c0cSDimitry Andric else
7723a9a9c0cSDimitry Andric return isUInt<Width>(getImmU16Context()) &&
7733a9a9c0cSDimitry Andric (getImmU16Context() & (Multiple - 1)) == 0;
7743a9a9c0cSDimitry Andric }
7753a9a9c0cSDimitry Andric }
7760b57cec5SDimitry Andric };
7770b57cec5SDimitry Andric
7780b57cec5SDimitry Andric } // end anonymous namespace.
7790b57cec5SDimitry Andric
print(raw_ostream & OS) const7800b57cec5SDimitry Andric void PPCOperand::print(raw_ostream &OS) const {
7810b57cec5SDimitry Andric switch (Kind) {
7820b57cec5SDimitry Andric case Token:
7830b57cec5SDimitry Andric OS << "'" << getToken() << "'";
7840b57cec5SDimitry Andric break;
7850b57cec5SDimitry Andric case Immediate:
7860b57cec5SDimitry Andric case ContextImmediate:
7870b57cec5SDimitry Andric OS << getImm();
7880b57cec5SDimitry Andric break;
7890b57cec5SDimitry Andric case Expression:
7900b57cec5SDimitry Andric OS << *getExpr();
7910b57cec5SDimitry Andric break;
7920b57cec5SDimitry Andric case TLSRegister:
7930b57cec5SDimitry Andric OS << *getTLSReg();
7940b57cec5SDimitry Andric break;
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric static void
addNegOperand(MCInst & Inst,MCOperand & Op,MCContext & Ctx)7990b57cec5SDimitry Andric addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
8000b57cec5SDimitry Andric if (Op.isImm()) {
8010b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(-Op.getImm()));
8020b57cec5SDimitry Andric return;
8030b57cec5SDimitry Andric }
8040b57cec5SDimitry Andric const MCExpr *Expr = Op.getExpr();
8050b57cec5SDimitry Andric if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
8060b57cec5SDimitry Andric if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
8070b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
8080b57cec5SDimitry Andric return;
8090b57cec5SDimitry Andric }
8100b57cec5SDimitry Andric } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
8110b57cec5SDimitry Andric if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
8120b57cec5SDimitry Andric const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
8130b57cec5SDimitry Andric BinExpr->getLHS(), Ctx);
8140b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(NE));
8150b57cec5SDimitry Andric return;
8160b57cec5SDimitry Andric }
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));
8190b57cec5SDimitry Andric }
8200b57cec5SDimitry Andric
ProcessInstruction(MCInst & Inst,const OperandVector & Operands)8210b57cec5SDimitry Andric void PPCAsmParser::ProcessInstruction(MCInst &Inst,
8220b57cec5SDimitry Andric const OperandVector &Operands) {
8230b57cec5SDimitry Andric int Opcode = Inst.getOpcode();
8240b57cec5SDimitry Andric switch (Opcode) {
8250b57cec5SDimitry Andric case PPC::DCBTx:
8260b57cec5SDimitry Andric case PPC::DCBTT:
8270b57cec5SDimitry Andric case PPC::DCBTSTx:
8280b57cec5SDimitry Andric case PPC::DCBTSTT: {
8290b57cec5SDimitry Andric MCInst TmpInst;
8300b57cec5SDimitry Andric TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
8310b57cec5SDimitry Andric PPC::DCBT : PPC::DCBTST);
8320b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(
8330b57cec5SDimitry Andric (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
8340b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8350b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8360b57cec5SDimitry Andric Inst = TmpInst;
8370b57cec5SDimitry Andric break;
8380b57cec5SDimitry Andric }
8390b57cec5SDimitry Andric case PPC::DCBTCT:
8400b57cec5SDimitry Andric case PPC::DCBTDS: {
8410b57cec5SDimitry Andric MCInst TmpInst;
8420b57cec5SDimitry Andric TmpInst.setOpcode(PPC::DCBT);
8430b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
8440b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8450b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8460b57cec5SDimitry Andric Inst = TmpInst;
8470b57cec5SDimitry Andric break;
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric case PPC::DCBTSTCT:
8500b57cec5SDimitry Andric case PPC::DCBTSTDS: {
8510b57cec5SDimitry Andric MCInst TmpInst;
8520b57cec5SDimitry Andric TmpInst.setOpcode(PPC::DCBTST);
8530b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
8540b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8550b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8560b57cec5SDimitry Andric Inst = TmpInst;
8570b57cec5SDimitry Andric break;
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric case PPC::DCBFx:
8600b57cec5SDimitry Andric case PPC::DCBFL:
861e8d8bef9SDimitry Andric case PPC::DCBFLP:
862e8d8bef9SDimitry Andric case PPC::DCBFPS:
863e8d8bef9SDimitry Andric case PPC::DCBSTPS: {
8640b57cec5SDimitry Andric int L = 0;
8650b57cec5SDimitry Andric if (Opcode == PPC::DCBFL)
8660b57cec5SDimitry Andric L = 1;
8670b57cec5SDimitry Andric else if (Opcode == PPC::DCBFLP)
8680b57cec5SDimitry Andric L = 3;
869e8d8bef9SDimitry Andric else if (Opcode == PPC::DCBFPS)
870e8d8bef9SDimitry Andric L = 4;
871e8d8bef9SDimitry Andric else if (Opcode == PPC::DCBSTPS)
872e8d8bef9SDimitry Andric L = 6;
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric MCInst TmpInst;
8750b57cec5SDimitry Andric TmpInst.setOpcode(PPC::DCBF);
8760b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(L));
8770b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8780b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8790b57cec5SDimitry Andric Inst = TmpInst;
8800b57cec5SDimitry Andric break;
8810b57cec5SDimitry Andric }
8820b57cec5SDimitry Andric case PPC::LAx: {
8830b57cec5SDimitry Andric MCInst TmpInst;
8840b57cec5SDimitry Andric TmpInst.setOpcode(PPC::LA);
8850b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8860b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
8870b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8880b57cec5SDimitry Andric Inst = TmpInst;
8890b57cec5SDimitry Andric break;
8900b57cec5SDimitry Andric }
8915f757f3fSDimitry Andric case PPC::PLA8:
8925f757f3fSDimitry Andric case PPC::PLA: {
8935f757f3fSDimitry Andric MCInst TmpInst;
8945f757f3fSDimitry Andric TmpInst.setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);
8955f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
8965f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
8975f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
8985f757f3fSDimitry Andric Inst = TmpInst;
8995f757f3fSDimitry Andric break;
9005f757f3fSDimitry Andric }
9015f757f3fSDimitry Andric case PPC::PLA8pc:
9025f757f3fSDimitry Andric case PPC::PLApc: {
9035f757f3fSDimitry Andric MCInst TmpInst;
9045f757f3fSDimitry Andric TmpInst.setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);
9055f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9065f757f3fSDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
9075f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9085f757f3fSDimitry Andric Inst = TmpInst;
9095f757f3fSDimitry Andric break;
9105f757f3fSDimitry Andric }
9110b57cec5SDimitry Andric case PPC::SUBI: {
9120b57cec5SDimitry Andric MCInst TmpInst;
9130b57cec5SDimitry Andric TmpInst.setOpcode(PPC::ADDI);
9140b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9150b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9160b57cec5SDimitry Andric addNegOperand(TmpInst, Inst.getOperand(2), getContext());
9170b57cec5SDimitry Andric Inst = TmpInst;
9180b57cec5SDimitry Andric break;
9190b57cec5SDimitry Andric }
9205f757f3fSDimitry Andric case PPC::PSUBI: {
9215f757f3fSDimitry Andric MCInst TmpInst;
9225f757f3fSDimitry Andric TmpInst.setOpcode(PPC::PADDI);
9235f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9245f757f3fSDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9255f757f3fSDimitry Andric addNegOperand(TmpInst, Inst.getOperand(2), getContext());
9265f757f3fSDimitry Andric Inst = TmpInst;
9275f757f3fSDimitry Andric break;
9285f757f3fSDimitry Andric }
9290b57cec5SDimitry Andric case PPC::SUBIS: {
9300b57cec5SDimitry Andric MCInst TmpInst;
9310b57cec5SDimitry Andric TmpInst.setOpcode(PPC::ADDIS);
9320b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9330b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9340b57cec5SDimitry Andric addNegOperand(TmpInst, Inst.getOperand(2), getContext());
9350b57cec5SDimitry Andric Inst = TmpInst;
9360b57cec5SDimitry Andric break;
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric case PPC::SUBIC: {
9390b57cec5SDimitry Andric MCInst TmpInst;
9400b57cec5SDimitry Andric TmpInst.setOpcode(PPC::ADDIC);
9410b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9420b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9430b57cec5SDimitry Andric addNegOperand(TmpInst, Inst.getOperand(2), getContext());
9440b57cec5SDimitry Andric Inst = TmpInst;
9450b57cec5SDimitry Andric break;
9460b57cec5SDimitry Andric }
947480093f4SDimitry Andric case PPC::SUBIC_rec: {
9480b57cec5SDimitry Andric MCInst TmpInst;
949480093f4SDimitry Andric TmpInst.setOpcode(PPC::ADDIC_rec);
9500b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9510b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9520b57cec5SDimitry Andric addNegOperand(TmpInst, Inst.getOperand(2), getContext());
9530b57cec5SDimitry Andric Inst = TmpInst;
9540b57cec5SDimitry Andric break;
9550b57cec5SDimitry Andric }
9560b57cec5SDimitry Andric case PPC::EXTLWI:
957480093f4SDimitry Andric case PPC::EXTLWI_rec: {
9580b57cec5SDimitry Andric MCInst TmpInst;
9590b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
9600b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
961480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
9620b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9630b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9640b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B));
9650b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
9660b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N - 1));
9670b57cec5SDimitry Andric Inst = TmpInst;
9680b57cec5SDimitry Andric break;
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric case PPC::EXTRWI:
971480093f4SDimitry Andric case PPC::EXTRWI_rec: {
9720b57cec5SDimitry Andric MCInst TmpInst;
9730b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
9740b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
975480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
9760b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9770b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9780b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B + N));
9790b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(32 - N));
9800b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31));
9810b57cec5SDimitry Andric Inst = TmpInst;
9820b57cec5SDimitry Andric break;
9830b57cec5SDimitry Andric }
9840b57cec5SDimitry Andric case PPC::INSLWI:
985480093f4SDimitry Andric case PPC::INSLWI_rec: {
9860b57cec5SDimitry Andric MCInst TmpInst;
9870b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
9880b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
989480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
9900b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9910b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
9920b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
9930b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(32 - B));
9940b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B));
9950b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
9960b57cec5SDimitry Andric Inst = TmpInst;
9970b57cec5SDimitry Andric break;
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric case PPC::INSRWI:
1000480093f4SDimitry Andric case PPC::INSRWI_rec: {
10010b57cec5SDimitry Andric MCInst TmpInst;
10020b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
10030b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
1004480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
10050b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10060b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10070b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10080b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
10090b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B));
10100b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
10110b57cec5SDimitry Andric Inst = TmpInst;
10120b57cec5SDimitry Andric break;
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric case PPC::ROTRWI:
1015480093f4SDimitry Andric case PPC::ROTRWI_rec: {
10160b57cec5SDimitry Andric MCInst TmpInst;
10170b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1018480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
10190b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10200b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10210b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(32 - N));
10220b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
10230b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31));
10240b57cec5SDimitry Andric Inst = TmpInst;
10250b57cec5SDimitry Andric break;
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric case PPC::SLWI:
1028480093f4SDimitry Andric case PPC::SLWI_rec: {
10290b57cec5SDimitry Andric MCInst TmpInst;
10300b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1031480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
10320b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10330b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10340b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
10350b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
10360b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31 - N));
10370b57cec5SDimitry Andric Inst = TmpInst;
10380b57cec5SDimitry Andric break;
10390b57cec5SDimitry Andric }
10400b57cec5SDimitry Andric case PPC::SRWI:
1041480093f4SDimitry Andric case PPC::SRWI_rec: {
10420b57cec5SDimitry Andric MCInst TmpInst;
10430b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1044480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
10450b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10460b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10470b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(32 - N));
10480b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
10490b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31));
10500b57cec5SDimitry Andric Inst = TmpInst;
10510b57cec5SDimitry Andric break;
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric case PPC::CLRRWI:
1054480093f4SDimitry Andric case PPC::CLRRWI_rec: {
10550b57cec5SDimitry Andric MCInst TmpInst;
10560b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1057480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
10580b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10590b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10600b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
10610b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
10620b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31 - N));
10630b57cec5SDimitry Andric Inst = TmpInst;
10640b57cec5SDimitry Andric break;
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric case PPC::CLRLSLWI:
1067480093f4SDimitry Andric case PPC::CLRLSLWI_rec: {
10680b57cec5SDimitry Andric MCInst TmpInst;
10690b57cec5SDimitry Andric int64_t B = Inst.getOperand(2).getImm();
10700b57cec5SDimitry Andric int64_t N = Inst.getOperand(3).getImm();
1071480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
10720b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10730b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10740b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
10750b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B - N));
10760b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(31 - N));
10770b57cec5SDimitry Andric Inst = TmpInst;
10780b57cec5SDimitry Andric break;
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric case PPC::EXTLDI:
1081480093f4SDimitry Andric case PPC::EXTLDI_rec: {
10820b57cec5SDimitry Andric MCInst TmpInst;
10830b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
10840b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
1085480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
10860b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
10870b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
10880b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B));
10890b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N - 1));
10900b57cec5SDimitry Andric Inst = TmpInst;
10910b57cec5SDimitry Andric break;
10920b57cec5SDimitry Andric }
10930b57cec5SDimitry Andric case PPC::EXTRDI:
1094480093f4SDimitry Andric case PPC::EXTRDI_rec: {
10950b57cec5SDimitry Andric MCInst TmpInst;
10960b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
10970b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
1098480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
10990b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11000b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11010b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B + N));
11020b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(64 - N));
11030b57cec5SDimitry Andric Inst = TmpInst;
11040b57cec5SDimitry Andric break;
11050b57cec5SDimitry Andric }
11060b57cec5SDimitry Andric case PPC::INSRDI:
1107480093f4SDimitry Andric case PPC::INSRDI_rec: {
11080b57cec5SDimitry Andric MCInst TmpInst;
11090b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
11100b57cec5SDimitry Andric int64_t B = Inst.getOperand(3).getImm();
1111480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
11120b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11130b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11140b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11150b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
11160b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B));
11170b57cec5SDimitry Andric Inst = TmpInst;
11180b57cec5SDimitry Andric break;
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric case PPC::ROTRDI:
1121480093f4SDimitry Andric case PPC::ROTRDI_rec: {
11220b57cec5SDimitry Andric MCInst TmpInst;
11230b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1124480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
11250b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11260b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11270b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(64 - N));
11280b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
11290b57cec5SDimitry Andric Inst = TmpInst;
11300b57cec5SDimitry Andric break;
11310b57cec5SDimitry Andric }
11320b57cec5SDimitry Andric case PPC::SLDI:
1133480093f4SDimitry Andric case PPC::SLDI_rec: {
11340b57cec5SDimitry Andric MCInst TmpInst;
11350b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1136480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
11370b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11380b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11390b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
11400b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(63 - N));
11410b57cec5SDimitry Andric Inst = TmpInst;
11420b57cec5SDimitry Andric break;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric case PPC::SUBPCIS: {
11450b57cec5SDimitry Andric MCInst TmpInst;
11460b57cec5SDimitry Andric int64_t N = Inst.getOperand(1).getImm();
11470b57cec5SDimitry Andric TmpInst.setOpcode(PPC::ADDPCIS);
11480b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11490b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(-N));
11500b57cec5SDimitry Andric Inst = TmpInst;
11510b57cec5SDimitry Andric break;
11520b57cec5SDimitry Andric }
11530b57cec5SDimitry Andric case PPC::SRDI:
1154480093f4SDimitry Andric case PPC::SRDI_rec: {
11550b57cec5SDimitry Andric MCInst TmpInst;
11560b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1157480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
11580b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11590b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11600b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(64 - N));
11610b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
11620b57cec5SDimitry Andric Inst = TmpInst;
11630b57cec5SDimitry Andric break;
11640b57cec5SDimitry Andric }
11650b57cec5SDimitry Andric case PPC::CLRRDI:
1166480093f4SDimitry Andric case PPC::CLRRDI_rec: {
11670b57cec5SDimitry Andric MCInst TmpInst;
11680b57cec5SDimitry Andric int64_t N = Inst.getOperand(2).getImm();
1169480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
11700b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11710b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11720b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(0));
11730b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(63 - N));
11740b57cec5SDimitry Andric Inst = TmpInst;
11750b57cec5SDimitry Andric break;
11760b57cec5SDimitry Andric }
11770b57cec5SDimitry Andric case PPC::CLRLSLDI:
1178480093f4SDimitry Andric case PPC::CLRLSLDI_rec: {
11790b57cec5SDimitry Andric MCInst TmpInst;
11800b57cec5SDimitry Andric int64_t B = Inst.getOperand(2).getImm();
11810b57cec5SDimitry Andric int64_t N = Inst.getOperand(3).getImm();
1182480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
11830b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
11840b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
11850b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(N));
11860b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(B - N));
11870b57cec5SDimitry Andric Inst = TmpInst;
11880b57cec5SDimitry Andric break;
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric case PPC::RLWINMbm:
1191480093f4SDimitry Andric case PPC::RLWINMbm_rec: {
11920b57cec5SDimitry Andric unsigned MB, ME;
11930b57cec5SDimitry Andric int64_t BM = Inst.getOperand(3).getImm();
11940b57cec5SDimitry Andric if (!isRunOfOnes(BM, MB, ME))
11950b57cec5SDimitry Andric break;
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andric MCInst TmpInst;
1198480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
11990b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
12000b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
12010b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
12020b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(MB));
12030b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(ME));
12040b57cec5SDimitry Andric Inst = TmpInst;
12050b57cec5SDimitry Andric break;
12060b57cec5SDimitry Andric }
12070b57cec5SDimitry Andric case PPC::RLWIMIbm:
1208480093f4SDimitry Andric case PPC::RLWIMIbm_rec: {
12090b57cec5SDimitry Andric unsigned MB, ME;
12100b57cec5SDimitry Andric int64_t BM = Inst.getOperand(3).getImm();
12110b57cec5SDimitry Andric if (!isRunOfOnes(BM, MB, ME))
12120b57cec5SDimitry Andric break;
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric MCInst TmpInst;
1215480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
12160b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
12170b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
12180b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
12190b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
12200b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(MB));
12210b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(ME));
12220b57cec5SDimitry Andric Inst = TmpInst;
12230b57cec5SDimitry Andric break;
12240b57cec5SDimitry Andric }
12250b57cec5SDimitry Andric case PPC::RLWNMbm:
1226480093f4SDimitry Andric case PPC::RLWNMbm_rec: {
12270b57cec5SDimitry Andric unsigned MB, ME;
12280b57cec5SDimitry Andric int64_t BM = Inst.getOperand(3).getImm();
12290b57cec5SDimitry Andric if (!isRunOfOnes(BM, MB, ME))
12300b57cec5SDimitry Andric break;
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andric MCInst TmpInst;
1233480093f4SDimitry Andric TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
12340b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(0));
12350b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(1));
12360b57cec5SDimitry Andric TmpInst.addOperand(Inst.getOperand(2));
12370b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(MB));
12380b57cec5SDimitry Andric TmpInst.addOperand(MCOperand::createImm(ME));
12390b57cec5SDimitry Andric Inst = TmpInst;
12400b57cec5SDimitry Andric break;
12410b57cec5SDimitry Andric }
12420b57cec5SDimitry Andric case PPC::MFTB: {
124306c3fb27SDimitry Andric if (getSTI().hasFeature(PPC::FeatureMFTB)) {
12440b57cec5SDimitry Andric assert(Inst.getNumOperands() == 2 && "Expecting two operands");
12450b57cec5SDimitry Andric Inst.setOpcode(PPC::MFSPR);
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric break;
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
12530b57cec5SDimitry Andric unsigned VariantID = 0);
12540b57cec5SDimitry Andric
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)12550b57cec5SDimitry Andric bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
12560b57cec5SDimitry Andric OperandVector &Operands,
12570b57cec5SDimitry Andric MCStreamer &Out, uint64_t &ErrorInfo,
12580b57cec5SDimitry Andric bool MatchingInlineAsm) {
12590b57cec5SDimitry Andric MCInst Inst;
12600b57cec5SDimitry Andric
12610b57cec5SDimitry Andric switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
12620b57cec5SDimitry Andric case Match_Success:
12630b57cec5SDimitry Andric // Post-process instructions (typically extended mnemonics)
12640b57cec5SDimitry Andric ProcessInstruction(Inst, Operands);
12650b57cec5SDimitry Andric Inst.setLoc(IDLoc);
12665ffd83dbSDimitry Andric Out.emitInstruction(Inst, getSTI());
12670b57cec5SDimitry Andric return false;
12680b57cec5SDimitry Andric case Match_MissingFeature:
12690b57cec5SDimitry Andric return Error(IDLoc, "instruction use requires an option to be enabled");
12700b57cec5SDimitry Andric case Match_MnemonicFail: {
12710b57cec5SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
12720b57cec5SDimitry Andric std::string Suggestion = PPCMnemonicSpellCheck(
12730b57cec5SDimitry Andric ((PPCOperand &)*Operands[0]).getToken(), FBS);
12740b57cec5SDimitry Andric return Error(IDLoc, "invalid instruction" + Suggestion,
12750b57cec5SDimitry Andric ((PPCOperand &)*Operands[0]).getLocRange());
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric case Match_InvalidOperand: {
12780b57cec5SDimitry Andric SMLoc ErrorLoc = IDLoc;
12790b57cec5SDimitry Andric if (ErrorInfo != ~0ULL) {
12800b57cec5SDimitry Andric if (ErrorInfo >= Operands.size())
12810b57cec5SDimitry Andric return Error(IDLoc, "too few operands for instruction");
12820b57cec5SDimitry Andric
12830b57cec5SDimitry Andric ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
12840b57cec5SDimitry Andric if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric
12870b57cec5SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction");
12880b57cec5SDimitry Andric }
12890b57cec5SDimitry Andric }
12900b57cec5SDimitry Andric
12910b57cec5SDimitry Andric llvm_unreachable("Implement any new match types added!");
12920b57cec5SDimitry Andric }
12930b57cec5SDimitry Andric
MatchRegisterName(MCRegister & RegNo,int64_t & IntVal)1294bdd1243dSDimitry Andric bool PPCAsmParser::MatchRegisterName(MCRegister &RegNo, int64_t &IntVal) {
1295e8d8bef9SDimitry Andric if (getParser().getTok().is(AsmToken::Percent))
1296e8d8bef9SDimitry Andric getParser().Lex(); // Eat the '%'.
1297e8d8bef9SDimitry Andric
1298e8d8bef9SDimitry Andric if (!getParser().getTok().is(AsmToken::Identifier))
1299e8d8bef9SDimitry Andric return true;
1300e8d8bef9SDimitry Andric
13010b57cec5SDimitry Andric StringRef Name = getParser().getTok().getString();
1302fe6060f1SDimitry Andric if (Name.equals_insensitive("lr")) {
13030b57cec5SDimitry Andric RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
13040b57cec5SDimitry Andric IntVal = 8;
1305fe6060f1SDimitry Andric } else if (Name.equals_insensitive("ctr")) {
13060b57cec5SDimitry Andric RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
13070b57cec5SDimitry Andric IntVal = 9;
1308fe6060f1SDimitry Andric } else if (Name.equals_insensitive("vrsave")) {
13090b57cec5SDimitry Andric RegNo = PPC::VRSAVE;
13100b57cec5SDimitry Andric IntVal = 256;
131106c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("r") &&
13120b57cec5SDimitry Andric !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
13130b57cec5SDimitry Andric RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
131406c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("f") &&
13150b57cec5SDimitry Andric !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
13160b57cec5SDimitry Andric RegNo = FRegs[IntVal];
131706c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("vs") &&
13180b57cec5SDimitry Andric !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
13190b57cec5SDimitry Andric RegNo = VSRegs[IntVal];
132006c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("v") &&
13210b57cec5SDimitry Andric !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
13220b57cec5SDimitry Andric RegNo = VRegs[IntVal];
132306c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("cr") &&
13240b57cec5SDimitry Andric !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
13250b57cec5SDimitry Andric RegNo = CRRegs[IntVal];
132606c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("acc") &&
1327bdd1243dSDimitry Andric !Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1328bdd1243dSDimitry Andric RegNo = ACCRegs[IntVal];
132906c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("wacc_hi") &&
1330bdd1243dSDimitry Andric !Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
1331bdd1243dSDimitry Andric RegNo = ACCRegs[IntVal];
133206c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("wacc") &&
1333bdd1243dSDimitry Andric !Name.substr(4).getAsInteger(10, IntVal) && IntVal < 8) {
1334bdd1243dSDimitry Andric RegNo = WACCRegs[IntVal];
133506c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("dmrrowp") &&
1336bdd1243dSDimitry Andric !Name.substr(7).getAsInteger(10, IntVal) && IntVal < 32) {
1337bdd1243dSDimitry Andric RegNo = DMRROWpRegs[IntVal];
133806c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("dmrrow") &&
1339bdd1243dSDimitry Andric !Name.substr(6).getAsInteger(10, IntVal) && IntVal < 64) {
1340bdd1243dSDimitry Andric RegNo = DMRROWRegs[IntVal];
134106c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("dmrp") &&
1342bdd1243dSDimitry Andric !Name.substr(4).getAsInteger(10, IntVal) && IntVal < 4) {
1343bdd1243dSDimitry Andric RegNo = DMRROWpRegs[IntVal];
134406c3fb27SDimitry Andric } else if (Name.starts_with_insensitive("dmr") &&
1345bdd1243dSDimitry Andric !Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1346bdd1243dSDimitry Andric RegNo = DMRRegs[IntVal];
13470b57cec5SDimitry Andric } else
13480b57cec5SDimitry Andric return true;
13490b57cec5SDimitry Andric getParser().Lex();
13500b57cec5SDimitry Andric return false;
13510b57cec5SDimitry Andric }
13520b57cec5SDimitry Andric
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)13535f757f3fSDimitry Andric bool PPCAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1354bdd1243dSDimitry Andric SMLoc &EndLoc) {
13555f757f3fSDimitry Andric if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
13565ffd83dbSDimitry Andric return TokError("invalid register name");
13575ffd83dbSDimitry Andric return false;
13585ffd83dbSDimitry Andric }
13595ffd83dbSDimitry Andric
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)13605f757f3fSDimitry Andric ParseStatus PPCAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
13615ffd83dbSDimitry Andric SMLoc &EndLoc) {
13620b57cec5SDimitry Andric const AsmToken &Tok = getParser().getTok();
13630b57cec5SDimitry Andric StartLoc = Tok.getLoc();
13640b57cec5SDimitry Andric EndLoc = Tok.getEndLoc();
13655f757f3fSDimitry Andric Reg = PPC::NoRegister;
13660b57cec5SDimitry Andric int64_t IntVal;
13675f757f3fSDimitry Andric if (MatchRegisterName(Reg, IntVal))
13685f757f3fSDimitry Andric return ParseStatus::NoMatch;
13695f757f3fSDimitry Andric return ParseStatus::Success;
13700b57cec5SDimitry Andric }
13710b57cec5SDimitry Andric
13720b57cec5SDimitry Andric /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
13730b57cec5SDimitry Andric /// the expression and check for VK_PPC_LO/HI/HA
13740b57cec5SDimitry Andric /// symbol variants. If all symbols with modifier use the same
13750b57cec5SDimitry Andric /// variant, return the corresponding PPCMCExpr::VariantKind,
13760b57cec5SDimitry Andric /// and a modified expression using the default symbol variant.
13770b57cec5SDimitry Andric /// Otherwise, return NULL.
13780b57cec5SDimitry Andric const MCExpr *PPCAsmParser::
ExtractModifierFromExpr(const MCExpr * E,PPCMCExpr::VariantKind & Variant)13790b57cec5SDimitry Andric ExtractModifierFromExpr(const MCExpr *E,
13800b57cec5SDimitry Andric PPCMCExpr::VariantKind &Variant) {
13810b57cec5SDimitry Andric MCContext &Context = getParser().getContext();
13820b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_None;
13830b57cec5SDimitry Andric
13840b57cec5SDimitry Andric switch (E->getKind()) {
13850b57cec5SDimitry Andric case MCExpr::Target:
13860b57cec5SDimitry Andric case MCExpr::Constant:
13870b57cec5SDimitry Andric return nullptr;
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andric case MCExpr::SymbolRef: {
13900b57cec5SDimitry Andric const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andric switch (SRE->getKind()) {
13930b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO:
13940b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_LO;
13950b57cec5SDimitry Andric break;
13960b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI:
13970b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HI;
13980b57cec5SDimitry Andric break;
13990b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA:
14000b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HA;
14010b57cec5SDimitry Andric break;
14020b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGH:
14030b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGH;
14040b57cec5SDimitry Andric break;
14050b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHA:
14060b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGHA;
14070b57cec5SDimitry Andric break;
14080b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHER:
14090b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGHER;
14100b57cec5SDimitry Andric break;
14110b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHERA:
14120b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGHERA;
14130b57cec5SDimitry Andric break;
14140b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHEST:
14150b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGHEST;
14160b57cec5SDimitry Andric break;
14170b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHESTA:
14180b57cec5SDimitry Andric Variant = PPCMCExpr::VK_PPC_HIGHESTA;
14190b57cec5SDimitry Andric break;
14200b57cec5SDimitry Andric default:
14210b57cec5SDimitry Andric return nullptr;
14220b57cec5SDimitry Andric }
14230b57cec5SDimitry Andric
14240b57cec5SDimitry Andric return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
14250b57cec5SDimitry Andric }
14260b57cec5SDimitry Andric
14270b57cec5SDimitry Andric case MCExpr::Unary: {
14280b57cec5SDimitry Andric const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
14290b57cec5SDimitry Andric const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
14300b57cec5SDimitry Andric if (!Sub)
14310b57cec5SDimitry Andric return nullptr;
14320b57cec5SDimitry Andric return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric
14350b57cec5SDimitry Andric case MCExpr::Binary: {
14360b57cec5SDimitry Andric const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
14370b57cec5SDimitry Andric PPCMCExpr::VariantKind LHSVariant, RHSVariant;
14380b57cec5SDimitry Andric const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
14390b57cec5SDimitry Andric const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
14400b57cec5SDimitry Andric
14410b57cec5SDimitry Andric if (!LHS && !RHS)
14420b57cec5SDimitry Andric return nullptr;
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andric if (!LHS) LHS = BE->getLHS();
14450b57cec5SDimitry Andric if (!RHS) RHS = BE->getRHS();
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andric if (LHSVariant == PPCMCExpr::VK_PPC_None)
14480b57cec5SDimitry Andric Variant = RHSVariant;
14490b57cec5SDimitry Andric else if (RHSVariant == PPCMCExpr::VK_PPC_None)
14500b57cec5SDimitry Andric Variant = LHSVariant;
14510b57cec5SDimitry Andric else if (LHSVariant == RHSVariant)
14520b57cec5SDimitry Andric Variant = LHSVariant;
14530b57cec5SDimitry Andric else
14540b57cec5SDimitry Andric return nullptr;
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andric return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
14570b57cec5SDimitry Andric }
14580b57cec5SDimitry Andric }
14590b57cec5SDimitry Andric
14600b57cec5SDimitry Andric llvm_unreachable("Invalid expression kind!");
14610b57cec5SDimitry Andric }
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andric /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
14640b57cec5SDimitry Andric /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
14650b57cec5SDimitry Andric /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
14660b57cec5SDimitry Andric /// FIXME: This is a hack.
14670b57cec5SDimitry Andric const MCExpr *PPCAsmParser::
FixupVariantKind(const MCExpr * E)14680b57cec5SDimitry Andric FixupVariantKind(const MCExpr *E) {
14690b57cec5SDimitry Andric MCContext &Context = getParser().getContext();
14700b57cec5SDimitry Andric
14710b57cec5SDimitry Andric switch (E->getKind()) {
14720b57cec5SDimitry Andric case MCExpr::Target:
14730b57cec5SDimitry Andric case MCExpr::Constant:
14740b57cec5SDimitry Andric return E;
14750b57cec5SDimitry Andric
14760b57cec5SDimitry Andric case MCExpr::SymbolRef: {
14770b57cec5SDimitry Andric const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
14780b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andric switch (SRE->getKind()) {
14810b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSGD:
14820b57cec5SDimitry Andric Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
14830b57cec5SDimitry Andric break;
14840b57cec5SDimitry Andric case MCSymbolRefExpr::VK_TLSLD:
14850b57cec5SDimitry Andric Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
14860b57cec5SDimitry Andric break;
14870b57cec5SDimitry Andric default:
14880b57cec5SDimitry Andric return E;
14890b57cec5SDimitry Andric }
14900b57cec5SDimitry Andric return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
14910b57cec5SDimitry Andric }
14920b57cec5SDimitry Andric
14930b57cec5SDimitry Andric case MCExpr::Unary: {
14940b57cec5SDimitry Andric const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
14950b57cec5SDimitry Andric const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
14960b57cec5SDimitry Andric if (Sub == UE->getSubExpr())
14970b57cec5SDimitry Andric return E;
14980b57cec5SDimitry Andric return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric
15010b57cec5SDimitry Andric case MCExpr::Binary: {
15020b57cec5SDimitry Andric const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
15030b57cec5SDimitry Andric const MCExpr *LHS = FixupVariantKind(BE->getLHS());
15040b57cec5SDimitry Andric const MCExpr *RHS = FixupVariantKind(BE->getRHS());
15050b57cec5SDimitry Andric if (LHS == BE->getLHS() && RHS == BE->getRHS())
15060b57cec5SDimitry Andric return E;
15070b57cec5SDimitry Andric return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
15080b57cec5SDimitry Andric }
15090b57cec5SDimitry Andric }
15100b57cec5SDimitry Andric
15110b57cec5SDimitry Andric llvm_unreachable("Invalid expression kind!");
15120b57cec5SDimitry Andric }
15130b57cec5SDimitry Andric
15140b57cec5SDimitry Andric /// ParseExpression. This differs from the default "parseExpression" in that
15150b57cec5SDimitry Andric /// it handles modifiers.
15160b57cec5SDimitry Andric bool PPCAsmParser::
ParseExpression(const MCExpr * & EVal)15170b57cec5SDimitry Andric ParseExpression(const MCExpr *&EVal) {
15180b57cec5SDimitry Andric // (ELF Platforms)
15190b57cec5SDimitry Andric // Handle \code @l/@ha \endcode
15200b57cec5SDimitry Andric if (getParser().parseExpression(EVal))
15210b57cec5SDimitry Andric return true;
15220b57cec5SDimitry Andric
15230b57cec5SDimitry Andric EVal = FixupVariantKind(EVal);
15240b57cec5SDimitry Andric
15250b57cec5SDimitry Andric PPCMCExpr::VariantKind Variant;
15260b57cec5SDimitry Andric const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
15270b57cec5SDimitry Andric if (E)
15285ffd83dbSDimitry Andric EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
15290b57cec5SDimitry Andric
15300b57cec5SDimitry Andric return false;
15310b57cec5SDimitry Andric }
15320b57cec5SDimitry Andric
15330b57cec5SDimitry Andric /// ParseOperand
15340b57cec5SDimitry Andric /// This handles registers in the form 'NN', '%rNN' for ELF platforms and
15350b57cec5SDimitry Andric /// rNN for MachO.
ParseOperand(OperandVector & Operands)15360b57cec5SDimitry Andric bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
15370b57cec5SDimitry Andric MCAsmParser &Parser = getParser();
15380b57cec5SDimitry Andric SMLoc S = Parser.getTok().getLoc();
15390b57cec5SDimitry Andric SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
15400b57cec5SDimitry Andric const MCExpr *EVal;
15410b57cec5SDimitry Andric
15420b57cec5SDimitry Andric // Attempt to parse the next token as an immediate
15430b57cec5SDimitry Andric switch (getLexer().getKind()) {
15440b57cec5SDimitry Andric // Special handling for register names. These are interpreted
15450b57cec5SDimitry Andric // as immediates corresponding to the register number.
1546e8d8bef9SDimitry Andric case AsmToken::Percent: {
1547bdd1243dSDimitry Andric MCRegister RegNo;
15480b57cec5SDimitry Andric int64_t IntVal;
15490b57cec5SDimitry Andric if (MatchRegisterName(RegNo, IntVal))
15500b57cec5SDimitry Andric return Error(S, "invalid register name");
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
15530b57cec5SDimitry Andric return false;
1554e8d8bef9SDimitry Andric }
15550b57cec5SDimitry Andric case AsmToken::Identifier:
15560b57cec5SDimitry Andric case AsmToken::LParen:
15570b57cec5SDimitry Andric case AsmToken::Plus:
15580b57cec5SDimitry Andric case AsmToken::Minus:
15590b57cec5SDimitry Andric case AsmToken::Integer:
15600b57cec5SDimitry Andric case AsmToken::Dot:
15610b57cec5SDimitry Andric case AsmToken::Dollar:
15620b57cec5SDimitry Andric case AsmToken::Exclaim:
15630b57cec5SDimitry Andric case AsmToken::Tilde:
15640b57cec5SDimitry Andric if (!ParseExpression(EVal))
15650b57cec5SDimitry Andric break;
15660b57cec5SDimitry Andric // Fall-through
1567bdd1243dSDimitry Andric [[fallthrough]];
15680b57cec5SDimitry Andric default:
15690b57cec5SDimitry Andric return Error(S, "unknown operand");
15700b57cec5SDimitry Andric }
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andric // Push the parsed operand into the list of operands
15730b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric // Check whether this is a TLS call expression
15768a4dda33SDimitry Andric const char TlsGetAddr[] = "__tls_get_addr";
15778a4dda33SDimitry Andric bool TlsCall = false;
15788a4dda33SDimitry Andric const MCExpr *TlsCallAddend = nullptr;
15798a4dda33SDimitry Andric if (auto *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
15808a4dda33SDimitry Andric TlsCall = Ref->getSymbol().getName() == TlsGetAddr;
15818a4dda33SDimitry Andric } else if (auto *Bin = dyn_cast<MCBinaryExpr>(EVal);
15828a4dda33SDimitry Andric Bin && Bin->getOpcode() == MCBinaryExpr::Add) {
15838a4dda33SDimitry Andric if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Bin->getLHS())) {
15848a4dda33SDimitry Andric TlsCall = Ref->getSymbol().getName() == TlsGetAddr;
15858a4dda33SDimitry Andric TlsCallAddend = Bin->getRHS();
15868a4dda33SDimitry Andric }
15878a4dda33SDimitry Andric }
15880b57cec5SDimitry Andric
15898a4dda33SDimitry Andric if (TlsCall && parseOptionalToken(AsmToken::LParen)) {
15900b57cec5SDimitry Andric const MCExpr *TLSSym;
15918a4dda33SDimitry Andric const SMLoc S2 = Parser.getTok().getLoc();
15920b57cec5SDimitry Andric if (ParseExpression(TLSSym))
15938a4dda33SDimitry Andric return Error(S2, "invalid TLS call expression");
15948a4dda33SDimitry Andric E = Parser.getTok().getLoc();
159506c3fb27SDimitry Andric if (parseToken(AsmToken::RParen, "expected ')'"))
159606c3fb27SDimitry Andric return true;
15978a4dda33SDimitry Andric // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]".
15988a4dda33SDimitry Andric if (!isPPC64() && parseOptionalToken(AsmToken::At)) {
15998a4dda33SDimitry Andric AsmToken Tok = getTok();
16008a4dda33SDimitry Andric if (!(parseOptionalToken(AsmToken::Identifier) &&
16018a4dda33SDimitry Andric Tok.getString().compare_insensitive("plt") == 0))
16028a4dda33SDimitry Andric return Error(Tok.getLoc(), "expected 'plt'");
16038a4dda33SDimitry Andric EVal = MCSymbolRefExpr::create(TlsGetAddr, MCSymbolRefExpr::VK_PLT,
16048a4dda33SDimitry Andric getContext());
16058a4dda33SDimitry Andric if (parseOptionalToken(AsmToken::Plus)) {
16068a4dda33SDimitry Andric const MCExpr *Addend = nullptr;
16078a4dda33SDimitry Andric SMLoc EndLoc;
16088a4dda33SDimitry Andric if (parsePrimaryExpr(Addend, EndLoc))
16098a4dda33SDimitry Andric return true;
16108a4dda33SDimitry Andric if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b
16118a4dda33SDimitry Andric TlsCallAddend =
16128a4dda33SDimitry Andric MCBinaryExpr::createAdd(TlsCallAddend, Addend, getContext());
16138a4dda33SDimitry Andric else // __tls_get_addr(x@tlsgd)@plt+b
16148a4dda33SDimitry Andric TlsCallAddend = Addend;
16158a4dda33SDimitry Andric }
16168a4dda33SDimitry Andric if (TlsCallAddend)
16178a4dda33SDimitry Andric EVal = MCBinaryExpr::createAdd(EVal, TlsCallAddend, getContext());
16188a4dda33SDimitry Andric // Add a __tls_get_addr operand with addend a, b, or a+b.
16198a4dda33SDimitry Andric Operands.back() = PPCOperand::CreateFromMCExpr(
16208a4dda33SDimitry Andric EVal, S, Parser.getTok().getLoc(), false);
16218a4dda33SDimitry Andric }
16220b57cec5SDimitry Andric
16230b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
16240b57cec5SDimitry Andric }
16250b57cec5SDimitry Andric
16260b57cec5SDimitry Andric // Otherwise, check for D-form memory operands
16278a4dda33SDimitry Andric if (!TlsCall && parseOptionalToken(AsmToken::LParen)) {
16280b57cec5SDimitry Andric S = Parser.getTok().getLoc();
16290b57cec5SDimitry Andric
16300b57cec5SDimitry Andric int64_t IntVal;
16310b57cec5SDimitry Andric switch (getLexer().getKind()) {
1632e8d8bef9SDimitry Andric case AsmToken::Percent: {
1633bdd1243dSDimitry Andric MCRegister RegNo;
16340b57cec5SDimitry Andric if (MatchRegisterName(RegNo, IntVal))
16350b57cec5SDimitry Andric return Error(S, "invalid register name");
16360b57cec5SDimitry Andric break;
1637e8d8bef9SDimitry Andric }
16380b57cec5SDimitry Andric case AsmToken::Integer:
1639e8d8bef9SDimitry Andric if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
16400b57cec5SDimitry Andric IntVal > 31)
16410b57cec5SDimitry Andric return Error(S, "invalid register number");
16420b57cec5SDimitry Andric break;
16430b57cec5SDimitry Andric case AsmToken::Identifier:
16440b57cec5SDimitry Andric default:
16450b57cec5SDimitry Andric return Error(S, "invalid memory operand");
16460b57cec5SDimitry Andric }
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andric E = Parser.getTok().getLoc();
16490b57cec5SDimitry Andric if (parseToken(AsmToken::RParen, "missing ')'"))
16500b57cec5SDimitry Andric return true;
16510b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
16520b57cec5SDimitry Andric }
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andric return false;
16550b57cec5SDimitry Andric }
16560b57cec5SDimitry Andric
16570b57cec5SDimitry Andric /// Parse an instruction mnemonic followed by its operands.
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)16580b57cec5SDimitry Andric bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
16590b57cec5SDimitry Andric SMLoc NameLoc, OperandVector &Operands) {
16600b57cec5SDimitry Andric // The first operand is the token for the instruction name.
16610b57cec5SDimitry Andric // If the next character is a '+' or '-', we need to add it to the
16620b57cec5SDimitry Andric // instruction name, to match what TableGen is doing.
16630b57cec5SDimitry Andric std::string NewOpcode;
16640b57cec5SDimitry Andric if (parseOptionalToken(AsmToken::Plus)) {
16655ffd83dbSDimitry Andric NewOpcode = std::string(Name);
16660b57cec5SDimitry Andric NewOpcode += '+';
16670b57cec5SDimitry Andric Name = NewOpcode;
16680b57cec5SDimitry Andric }
16690b57cec5SDimitry Andric if (parseOptionalToken(AsmToken::Minus)) {
16705ffd83dbSDimitry Andric NewOpcode = std::string(Name);
16710b57cec5SDimitry Andric NewOpcode += '-';
16720b57cec5SDimitry Andric Name = NewOpcode;
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric // If the instruction ends in a '.', we need to create a separate
16750b57cec5SDimitry Andric // token for it, to match what TableGen is doing.
16760b57cec5SDimitry Andric size_t Dot = Name.find('.');
16770b57cec5SDimitry Andric StringRef Mnemonic = Name.slice(0, Dot);
16780b57cec5SDimitry Andric if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
16790b57cec5SDimitry Andric Operands.push_back(
16800b57cec5SDimitry Andric PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
16810b57cec5SDimitry Andric else
16820b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
16830b57cec5SDimitry Andric if (Dot != StringRef::npos) {
16840b57cec5SDimitry Andric SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
16850b57cec5SDimitry Andric StringRef DotStr = Name.slice(Dot, StringRef::npos);
16860b57cec5SDimitry Andric if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
16870b57cec5SDimitry Andric Operands.push_back(
16880b57cec5SDimitry Andric PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
16890b57cec5SDimitry Andric else
16900b57cec5SDimitry Andric Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric
16930b57cec5SDimitry Andric // If there are no more operands then finish
16940b57cec5SDimitry Andric if (parseOptionalToken(AsmToken::EndOfStatement))
16950b57cec5SDimitry Andric return false;
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric // Parse the first operand
16980b57cec5SDimitry Andric if (ParseOperand(Operands))
16990b57cec5SDimitry Andric return true;
17000b57cec5SDimitry Andric
17010b57cec5SDimitry Andric while (!parseOptionalToken(AsmToken::EndOfStatement)) {
17020b57cec5SDimitry Andric if (parseToken(AsmToken::Comma) || ParseOperand(Operands))
17030b57cec5SDimitry Andric return true;
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric
17060b57cec5SDimitry Andric // We'll now deal with an unfortunate special case: the syntax for the dcbt
17070b57cec5SDimitry Andric // and dcbtst instructions differs for server vs. embedded cores.
17080b57cec5SDimitry Andric // The syntax for dcbt is:
17090b57cec5SDimitry Andric // dcbt ra, rb, th [server]
17100b57cec5SDimitry Andric // dcbt th, ra, rb [embedded]
17110b57cec5SDimitry Andric // where th can be omitted when it is 0. dcbtst is the same. We take the
17120b57cec5SDimitry Andric // server form to be the default, so swap the operands if we're parsing for
17130b57cec5SDimitry Andric // an embedded core (they'll be swapped again upon printing).
171406c3fb27SDimitry Andric if (getSTI().hasFeature(PPC::FeatureBookE) &&
17150b57cec5SDimitry Andric Operands.size() == 4 &&
17160b57cec5SDimitry Andric (Name == "dcbt" || Name == "dcbtst")) {
17170b57cec5SDimitry Andric std::swap(Operands[1], Operands[3]);
17180b57cec5SDimitry Andric std::swap(Operands[2], Operands[1]);
17190b57cec5SDimitry Andric }
17200b57cec5SDimitry Andric
17210eae32dcSDimitry Andric // Handle base mnemonic for atomic loads where the EH bit is zero.
17220eae32dcSDimitry Andric if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
17230eae32dcSDimitry Andric Name == "lharx" || Name == "lbarx") {
17240eae32dcSDimitry Andric if (Operands.size() != 5)
17250eae32dcSDimitry Andric return false;
17260eae32dcSDimitry Andric PPCOperand &EHOp = (PPCOperand &)*Operands[4];
17270eae32dcSDimitry Andric if (EHOp.isU1Imm() && EHOp.getImm() == 0)
17280eae32dcSDimitry Andric Operands.pop_back();
17290eae32dcSDimitry Andric }
17300eae32dcSDimitry Andric
17310b57cec5SDimitry Andric return false;
17320b57cec5SDimitry Andric }
17330b57cec5SDimitry Andric
17340b57cec5SDimitry Andric /// ParseDirective parses the PPC specific directives
ParseDirective(AsmToken DirectiveID)17350b57cec5SDimitry Andric bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
17360b57cec5SDimitry Andric StringRef IDVal = DirectiveID.getIdentifier();
1737e8d8bef9SDimitry Andric if (IDVal == ".word")
17380b57cec5SDimitry Andric ParseDirectiveWord(2, DirectiveID);
17390b57cec5SDimitry Andric else if (IDVal == ".llong")
17400b57cec5SDimitry Andric ParseDirectiveWord(8, DirectiveID);
17410b57cec5SDimitry Andric else if (IDVal == ".tc")
17420b57cec5SDimitry Andric ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
17430b57cec5SDimitry Andric else if (IDVal == ".machine")
17440b57cec5SDimitry Andric ParseDirectiveMachine(DirectiveID.getLoc());
17450b57cec5SDimitry Andric else if (IDVal == ".abiversion")
17460b57cec5SDimitry Andric ParseDirectiveAbiVersion(DirectiveID.getLoc());
17470b57cec5SDimitry Andric else if (IDVal == ".localentry")
17480b57cec5SDimitry Andric ParseDirectiveLocalEntry(DirectiveID.getLoc());
17495f757f3fSDimitry Andric else if (IDVal.starts_with(".gnu_attribute"))
175004eeddc0SDimitry Andric ParseGNUAttribute(DirectiveID.getLoc());
17510b57cec5SDimitry Andric else
17520b57cec5SDimitry Andric return true;
17530b57cec5SDimitry Andric return false;
17540b57cec5SDimitry Andric }
17550b57cec5SDimitry Andric
17560b57cec5SDimitry Andric /// ParseDirectiveWord
17570b57cec5SDimitry Andric /// ::= .word [ expression (, expression)* ]
ParseDirectiveWord(unsigned Size,AsmToken ID)17580b57cec5SDimitry Andric bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) {
17590b57cec5SDimitry Andric auto parseOp = [&]() -> bool {
17600b57cec5SDimitry Andric const MCExpr *Value;
17610b57cec5SDimitry Andric SMLoc ExprLoc = getParser().getTok().getLoc();
17620b57cec5SDimitry Andric if (getParser().parseExpression(Value))
17630b57cec5SDimitry Andric return true;
17640b57cec5SDimitry Andric if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
17650b57cec5SDimitry Andric assert(Size <= 8 && "Invalid size");
17660b57cec5SDimitry Andric uint64_t IntValue = MCE->getValue();
17670b57cec5SDimitry Andric if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
17680b57cec5SDimitry Andric return Error(ExprLoc, "literal value out of range for '" +
17690b57cec5SDimitry Andric ID.getIdentifier() + "' directive");
17705ffd83dbSDimitry Andric getStreamer().emitIntValue(IntValue, Size);
17710b57cec5SDimitry Andric } else
17725ffd83dbSDimitry Andric getStreamer().emitValue(Value, Size, ExprLoc);
17730b57cec5SDimitry Andric return false;
17740b57cec5SDimitry Andric };
17750b57cec5SDimitry Andric
17760b57cec5SDimitry Andric if (parseMany(parseOp))
17770b57cec5SDimitry Andric return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
17780b57cec5SDimitry Andric return false;
17790b57cec5SDimitry Andric }
17800b57cec5SDimitry Andric
17810b57cec5SDimitry Andric /// ParseDirectiveTC
17820b57cec5SDimitry Andric /// ::= .tc [ symbol (, expression)* ]
ParseDirectiveTC(unsigned Size,AsmToken ID)17830b57cec5SDimitry Andric bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) {
17840b57cec5SDimitry Andric MCAsmParser &Parser = getParser();
17850b57cec5SDimitry Andric // Skip TC symbol, which is only used with XCOFF.
17860b57cec5SDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)
17870b57cec5SDimitry Andric && getLexer().isNot(AsmToken::Comma))
17880b57cec5SDimitry Andric Parser.Lex();
17890b57cec5SDimitry Andric if (parseToken(AsmToken::Comma))
17900b57cec5SDimitry Andric return addErrorSuffix(" in '.tc' directive");
17910b57cec5SDimitry Andric
17920b57cec5SDimitry Andric // Align to word size.
1793bdd1243dSDimitry Andric getParser().getStreamer().emitValueToAlignment(Align(Size));
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andric // Emit expressions.
17960b57cec5SDimitry Andric return ParseDirectiveWord(Size, ID);
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric
17990b57cec5SDimitry Andric /// ParseDirectiveMachine (ELF platforms)
18000b57cec5SDimitry Andric /// ::= .machine [ cpu | "push" | "pop" ]
ParseDirectiveMachine(SMLoc L)18010b57cec5SDimitry Andric bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
18020b57cec5SDimitry Andric MCAsmParser &Parser = getParser();
18030b57cec5SDimitry Andric if (Parser.getTok().isNot(AsmToken::Identifier) &&
18040b57cec5SDimitry Andric Parser.getTok().isNot(AsmToken::String))
18050b57cec5SDimitry Andric return Error(L, "unexpected token in '.machine' directive");
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric StringRef CPU = Parser.getTok().getIdentifier();
18080b57cec5SDimitry Andric
18090b57cec5SDimitry Andric // FIXME: Right now, the parser always allows any available
18100b57cec5SDimitry Andric // instruction, so the .machine directive is not useful.
1811e8d8bef9SDimitry Andric // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
18120b57cec5SDimitry Andric
18130b57cec5SDimitry Andric Parser.Lex();
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andric if (parseToken(AsmToken::EndOfStatement))
18160b57cec5SDimitry Andric return addErrorSuffix(" in '.machine' directive");
18170b57cec5SDimitry Andric
18185ffd83dbSDimitry Andric PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
18190b57cec5SDimitry Andric getParser().getStreamer().getTargetStreamer());
18205ffd83dbSDimitry Andric if (TStreamer != nullptr)
18215ffd83dbSDimitry Andric TStreamer->emitMachine(CPU);
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andric return false;
18240b57cec5SDimitry Andric }
18250b57cec5SDimitry Andric
18260b57cec5SDimitry Andric /// ParseDirectiveAbiVersion
18270b57cec5SDimitry Andric /// ::= .abiversion constant-expression
ParseDirectiveAbiVersion(SMLoc L)18280b57cec5SDimitry Andric bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
18290b57cec5SDimitry Andric int64_t AbiVersion;
18300b57cec5SDimitry Andric if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
18310b57cec5SDimitry Andric "expected constant expression") ||
18320b57cec5SDimitry Andric parseToken(AsmToken::EndOfStatement))
18330b57cec5SDimitry Andric return addErrorSuffix(" in '.abiversion' directive");
18340b57cec5SDimitry Andric
18355ffd83dbSDimitry Andric PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
18360b57cec5SDimitry Andric getParser().getStreamer().getTargetStreamer());
18375ffd83dbSDimitry Andric if (TStreamer != nullptr)
18385ffd83dbSDimitry Andric TStreamer->emitAbiVersion(AbiVersion);
18390b57cec5SDimitry Andric
18400b57cec5SDimitry Andric return false;
18410b57cec5SDimitry Andric }
18420b57cec5SDimitry Andric
18430b57cec5SDimitry Andric /// ParseDirectiveLocalEntry
18440b57cec5SDimitry Andric /// ::= .localentry symbol, expression
ParseDirectiveLocalEntry(SMLoc L)18450b57cec5SDimitry Andric bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
18460b57cec5SDimitry Andric StringRef Name;
18470b57cec5SDimitry Andric if (getParser().parseIdentifier(Name))
18480b57cec5SDimitry Andric return Error(L, "expected identifier in '.localentry' directive");
18490b57cec5SDimitry Andric
18500b57cec5SDimitry Andric MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
18510b57cec5SDimitry Andric const MCExpr *Expr;
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric if (parseToken(AsmToken::Comma) ||
18540b57cec5SDimitry Andric check(getParser().parseExpression(Expr), L, "expected expression") ||
18550b57cec5SDimitry Andric parseToken(AsmToken::EndOfStatement))
18560b57cec5SDimitry Andric return addErrorSuffix(" in '.localentry' directive");
18570b57cec5SDimitry Andric
18585ffd83dbSDimitry Andric PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
18590b57cec5SDimitry Andric getParser().getStreamer().getTargetStreamer());
18605ffd83dbSDimitry Andric if (TStreamer != nullptr)
18615ffd83dbSDimitry Andric TStreamer->emitLocalEntry(Sym, Expr);
18620b57cec5SDimitry Andric
18630b57cec5SDimitry Andric return false;
18640b57cec5SDimitry Andric }
18650b57cec5SDimitry Andric
ParseGNUAttribute(SMLoc L)186604eeddc0SDimitry Andric bool PPCAsmParser::ParseGNUAttribute(SMLoc L) {
186704eeddc0SDimitry Andric int64_t Tag;
186804eeddc0SDimitry Andric int64_t IntegerValue;
186904eeddc0SDimitry Andric if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))
187004eeddc0SDimitry Andric return false;
18710b57cec5SDimitry Andric
187204eeddc0SDimitry Andric getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);
187304eeddc0SDimitry Andric
187404eeddc0SDimitry Andric return true;
187504eeddc0SDimitry Andric }
18760b57cec5SDimitry Andric
18770b57cec5SDimitry Andric /// Force static initialization.
LLVMInitializePowerPCAsmParser()1878480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
18790b57cec5SDimitry Andric RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
1880e8d8bef9SDimitry Andric RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
1881e8d8bef9SDimitry Andric RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
1882e8d8bef9SDimitry Andric RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
18830b57cec5SDimitry Andric }
18840b57cec5SDimitry Andric
18850b57cec5SDimitry Andric #define GET_REGISTER_MATCHER
18860b57cec5SDimitry Andric #define GET_MATCHER_IMPLEMENTATION
18870b57cec5SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER
18880b57cec5SDimitry Andric #include "PPCGenAsmMatcher.inc"
18890b57cec5SDimitry Andric
18900b57cec5SDimitry Andric // Define this matcher function after the auto-generated include so we
18910b57cec5SDimitry Andric // have the match class enum definitions.
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)18920b57cec5SDimitry Andric unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
18930b57cec5SDimitry Andric unsigned Kind) {
18940b57cec5SDimitry Andric // If the kind is a token for a literal immediate, check if our asm
18950b57cec5SDimitry Andric // operand matches. This is for InstAliases which have a fixed-value
18960b57cec5SDimitry Andric // immediate in the syntax.
18970b57cec5SDimitry Andric int64_t ImmVal;
18980b57cec5SDimitry Andric switch (Kind) {
18990b57cec5SDimitry Andric case MCK_0: ImmVal = 0; break;
19000b57cec5SDimitry Andric case MCK_1: ImmVal = 1; break;
19010b57cec5SDimitry Andric case MCK_2: ImmVal = 2; break;
19020b57cec5SDimitry Andric case MCK_3: ImmVal = 3; break;
19030b57cec5SDimitry Andric case MCK_4: ImmVal = 4; break;
19040b57cec5SDimitry Andric case MCK_5: ImmVal = 5; break;
19050b57cec5SDimitry Andric case MCK_6: ImmVal = 6; break;
19060b57cec5SDimitry Andric case MCK_7: ImmVal = 7; break;
19070b57cec5SDimitry Andric default: return Match_InvalidOperand;
19080b57cec5SDimitry Andric }
19090b57cec5SDimitry Andric
19100b57cec5SDimitry Andric PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
19110eae32dcSDimitry Andric if (Op.isU3Imm() && Op.getImm() == ImmVal)
19120b57cec5SDimitry Andric return Match_Success;
19130b57cec5SDimitry Andric
19140b57cec5SDimitry Andric return Match_InvalidOperand;
19150b57cec5SDimitry Andric }
19160b57cec5SDimitry Andric
19170b57cec5SDimitry Andric const MCExpr *
applyModifierToExpr(const MCExpr * E,MCSymbolRefExpr::VariantKind Variant,MCContext & Ctx)19180b57cec5SDimitry Andric PPCAsmParser::applyModifierToExpr(const MCExpr *E,
19190b57cec5SDimitry Andric MCSymbolRefExpr::VariantKind Variant,
19200b57cec5SDimitry Andric MCContext &Ctx) {
19210b57cec5SDimitry Andric switch (Variant) {
19220b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_LO:
19235ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, Ctx);
19240b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HI:
19255ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, Ctx);
19260b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HA:
19275ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, Ctx);
19280b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGH:
19295ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, Ctx);
19300b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHA:
19315ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, Ctx);
19320b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHER:
19335ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, Ctx);
19340b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHERA:
19355ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, Ctx);
19360b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHEST:
19375ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, Ctx);
19380b57cec5SDimitry Andric case MCSymbolRefExpr::VK_PPC_HIGHESTA:
19395ffd83dbSDimitry Andric return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, Ctx);
19400b57cec5SDimitry Andric default:
19410b57cec5SDimitry Andric return nullptr;
19420b57cec5SDimitry Andric }
19430b57cec5SDimitry Andric }
1944