File: | lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp |
Warning: | line 1490, column 22 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "MCTargetDesc/PPCMCExpr.h" | |||
10 | #include "MCTargetDesc/PPCMCTargetDesc.h" | |||
11 | #include "PPCTargetStreamer.h" | |||
12 | #include "TargetInfo/PowerPCTargetInfo.h" | |||
13 | #include "llvm/ADT/STLExtras.h" | |||
14 | #include "llvm/ADT/StringSwitch.h" | |||
15 | #include "llvm/ADT/Twine.h" | |||
16 | #include "llvm/MC/MCContext.h" | |||
17 | #include "llvm/MC/MCExpr.h" | |||
18 | #include "llvm/MC/MCInst.h" | |||
19 | #include "llvm/MC/MCInstrInfo.h" | |||
20 | #include "llvm/MC/MCParser/MCAsmLexer.h" | |||
21 | #include "llvm/MC/MCParser/MCAsmParser.h" | |||
22 | #include "llvm/MC/MCParser/MCParsedAsmOperand.h" | |||
23 | #include "llvm/MC/MCParser/MCTargetAsmParser.h" | |||
24 | #include "llvm/MC/MCStreamer.h" | |||
25 | #include "llvm/MC/MCSubtargetInfo.h" | |||
26 | #include "llvm/MC/MCSymbolELF.h" | |||
27 | #include "llvm/Support/SourceMgr.h" | |||
28 | #include "llvm/Support/TargetRegistry.h" | |||
29 | #include "llvm/Support/raw_ostream.h" | |||
30 | ||||
31 | using namespace llvm; | |||
32 | ||||
33 | DEFINE_PPC_REGCLASSESstatic const MCPhysReg RRegs[32] = { PPC::R0, PPC::R1, PPC::R2 , PPC::R3, PPC::R4, PPC::R5, PPC::R6, PPC::R7, PPC::R8, PPC:: R9, PPC::R10, PPC::R11, PPC::R12, PPC::R13, PPC::R14, PPC::R15 , PPC::R16, PPC::R17, PPC::R18, PPC::R19, PPC::R20, PPC::R21, PPC::R22, PPC::R23, PPC::R24, PPC::R25, PPC::R26, PPC::R27, PPC ::R28, PPC::R29, PPC::R30, PPC::R31 }; static const MCPhysReg XRegs[32] = { PPC::X0, PPC::X1, PPC::X2, PPC::X3, PPC::X4, PPC ::X5, PPC::X6, PPC::X7, PPC::X8, PPC::X9, PPC::X10, PPC::X11, PPC::X12, PPC::X13, PPC::X14, PPC::X15, PPC::X16, PPC::X17, PPC ::X18, PPC::X19, PPC::X20, PPC::X21, PPC::X22, PPC::X23, PPC:: X24, PPC::X25, PPC::X26, PPC::X27, PPC::X28, PPC::X29, PPC::X30 , PPC::X31 }; static const MCPhysReg FRegs[32] = { PPC::F0, PPC ::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, PPC ::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13, PPC::F14 , PPC::F15, PPC::F16, PPC::F17, PPC::F18, PPC::F19, PPC::F20, PPC::F21, PPC::F22, PPC::F23, PPC::F24, PPC::F25, PPC::F26, PPC ::F27, PPC::F28, PPC::F29, PPC::F30, PPC::F31 }; static const MCPhysReg SPERegs[32] = { PPC::S0, PPC::S1, PPC::S2, PPC::S3 , PPC::S4, PPC::S5, PPC::S6, PPC::S7, PPC::S8, PPC::S9, PPC:: S10, PPC::S11, PPC::S12, PPC::S13, PPC::S14, PPC::S15, PPC::S16 , PPC::S17, PPC::S18, PPC::S19, PPC::S20, PPC::S21, PPC::S22, PPC::S23, PPC::S24, PPC::S25, PPC::S26, PPC::S27, PPC::S28, PPC ::S29, PPC::S30, PPC::S31 }; static const MCPhysReg VFRegs[32 ] = { PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3, PPC::VF4, PPC:: VF5, PPC::VF6, PPC::VF7, PPC::VF8, PPC::VF9, PPC::VF10, PPC:: VF11, PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15, PPC::VF16, PPC ::VF17, PPC::VF18, PPC::VF19, PPC::VF20, PPC::VF21, PPC::VF22 , PPC::VF23, PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27, PPC:: VF28, PPC::VF29, PPC::VF30, PPC::VF31 }; static const MCPhysReg VRegs[32] = { PPC::V0, PPC::V1, PPC::V2, PPC::V3, PPC::V4, PPC ::V5, PPC::V6, PPC::V7, PPC::V8, PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15, PPC::V16, PPC::V17, PPC ::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23, PPC:: V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30 , PPC::V31 }; static const MCPhysReg QFRegs[32] = { PPC::QF0, PPC::QF1, PPC::QF2, PPC::QF3, PPC::QF4, PPC::QF5, PPC::QF6, PPC ::QF7, PPC::QF8, PPC::QF9, PPC::QF10, PPC::QF11, PPC::QF12, PPC ::QF13, PPC::QF14, PPC::QF15, PPC::QF16, PPC::QF17, PPC::QF18 , PPC::QF19, PPC::QF20, PPC::QF21, PPC::QF22, PPC::QF23, PPC:: QF24, PPC::QF25, PPC::QF26, PPC::QF27, PPC::QF28, PPC::QF29, PPC ::QF30, PPC::QF31 }; static const MCPhysReg RRegsNoR0[32] = { PPC::ZERO, PPC::R1, PPC::R2, PPC::R3, PPC::R4, PPC::R5, PPC:: R6, PPC::R7, PPC::R8, PPC::R9, PPC::R10, PPC::R11, PPC::R12, PPC ::R13, PPC::R14, PPC::R15, PPC::R16, PPC::R17, PPC::R18, PPC:: R19, PPC::R20, PPC::R21, PPC::R22, PPC::R23, PPC::R24, PPC::R25 , PPC::R26, PPC::R27, PPC::R28, PPC::R29, PPC::R30, PPC::R31 } ; static const MCPhysReg XRegsNoX0[32] = { PPC::ZERO8, PPC::X1 , PPC::X2, PPC::X3, PPC::X4, PPC::X5, PPC::X6, PPC::X7, PPC:: X8, PPC::X9, PPC::X10, PPC::X11, PPC::X12, PPC::X13, PPC::X14 , PPC::X15, PPC::X16, PPC::X17, PPC::X18, PPC::X19, PPC::X20, PPC::X21, PPC::X22, PPC::X23, PPC::X24, PPC::X25, PPC::X26, PPC ::X27, PPC::X28, PPC::X29, PPC::X30, PPC::X31 }; static const MCPhysReg VSRegs[64] = { PPC::VSL0, PPC::VSL1, PPC::VSL2, PPC ::VSL3, PPC::VSL4, PPC::VSL5, PPC::VSL6, PPC::VSL7, PPC::VSL8 , PPC::VSL9, PPC::VSL10, PPC::VSL11, PPC::VSL12, PPC::VSL13, PPC ::VSL14, PPC::VSL15, PPC::VSL16, PPC::VSL17, PPC::VSL18, PPC:: VSL19, PPC::VSL20, PPC::VSL21, PPC::VSL22, PPC::VSL23, PPC::VSL24 , PPC::VSL25, PPC::VSL26, PPC::VSL27, PPC::VSL28, PPC::VSL29, PPC::VSL30, PPC::VSL31, PPC::V0, PPC::V1, PPC::V2, PPC::V3, PPC ::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, PPC::V9, PPC::V10, PPC ::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15, PPC::V16, PPC:: V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23 , PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31 }; static const MCPhysReg VSFRegs[64] = { PPC::F0, PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6 , PPC::F7, PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC ::F13, PPC::F14, PPC::F15, PPC::F16, PPC::F17, PPC::F18, PPC:: F19, PPC::F20, PPC::F21, PPC::F22, PPC::F23, PPC::F24, PPC::F25 , PPC::F26, PPC::F27, PPC::F28, PPC::F29, PPC::F30, PPC::F31, PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3, PPC::VF4, PPC::VF5, PPC ::VF6, PPC::VF7, PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11, PPC ::VF12, PPC::VF13, PPC::VF14, PPC::VF15, PPC::VF16, PPC::VF17 , PPC::VF18, PPC::VF19, PPC::VF20, PPC::VF21, PPC::VF22, PPC:: VF23, PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27, PPC::VF28, PPC ::VF29, PPC::VF30, PPC::VF31 }; static const MCPhysReg VSSRegs [64] = { PPC::F0, PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5 , PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC ::F12, PPC::F13, PPC::F14, PPC::F15, PPC::F16, PPC::F17, PPC:: F18, PPC::F19, PPC::F20, PPC::F21, PPC::F22, PPC::F23, PPC::F24 , PPC::F25, PPC::F26, PPC::F27, PPC::F28, PPC::F29, PPC::F30, PPC::F31, PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3, PPC::VF4, PPC ::VF5, PPC::VF6, PPC::VF7, PPC::VF8, PPC::VF9, PPC::VF10, PPC ::VF11, PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15, PPC::VF16 , PPC::VF17, PPC::VF18, PPC::VF19, PPC::VF20, PPC::VF21, PPC:: VF22, PPC::VF23, PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27, PPC ::VF28, PPC::VF29, PPC::VF30, PPC::VF31 }; static const MCPhysReg CRBITRegs[32] = { PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN , PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN, PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, PPC::CR3LT, PPC::CR3GT, PPC ::CR3EQ, PPC::CR3UN, PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC:: CR4UN, PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, PPC::CR6LT , PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN}; static const MCPhysReg CRRegs[8] = { PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, PPC::CR4, PPC::CR5, PPC ::CR6, PPC::CR7}; | |||
34 | ||||
35 | // Evaluate an expression containing condition register | |||
36 | // or condition register field symbols. Returns positive | |||
37 | // value on success, or -1 on error. | |||
38 | static int64_t | |||
39 | EvaluateCRExpr(const MCExpr *E) { | |||
40 | switch (E->getKind()) { | |||
41 | case MCExpr::Target: | |||
42 | return -1; | |||
43 | ||||
44 | case MCExpr::Constant: { | |||
45 | int64_t Res = cast<MCConstantExpr>(E)->getValue(); | |||
46 | return Res < 0 ? -1 : Res; | |||
47 | } | |||
48 | ||||
49 | case MCExpr::SymbolRef: { | |||
50 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); | |||
51 | StringRef Name = SRE->getSymbol().getName(); | |||
52 | ||||
53 | if (Name == "lt") return 0; | |||
54 | if (Name == "gt") return 1; | |||
55 | if (Name == "eq") return 2; | |||
56 | if (Name == "so") return 3; | |||
57 | if (Name == "un") return 3; | |||
58 | ||||
59 | if (Name == "cr0") return 0; | |||
60 | if (Name == "cr1") return 1; | |||
61 | if (Name == "cr2") return 2; | |||
62 | if (Name == "cr3") return 3; | |||
63 | if (Name == "cr4") return 4; | |||
64 | if (Name == "cr5") return 5; | |||
65 | if (Name == "cr6") return 6; | |||
66 | if (Name == "cr7") return 7; | |||
67 | ||||
68 | return -1; | |||
69 | } | |||
70 | ||||
71 | case MCExpr::Unary: | |||
72 | return -1; | |||
73 | ||||
74 | case MCExpr::Binary: { | |||
75 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); | |||
76 | int64_t LHSVal = EvaluateCRExpr(BE->getLHS()); | |||
77 | int64_t RHSVal = EvaluateCRExpr(BE->getRHS()); | |||
78 | int64_t Res; | |||
79 | ||||
80 | if (LHSVal < 0 || RHSVal < 0) | |||
81 | return -1; | |||
82 | ||||
83 | switch (BE->getOpcode()) { | |||
84 | default: return -1; | |||
85 | case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break; | |||
86 | case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break; | |||
87 | } | |||
88 | ||||
89 | return Res < 0 ? -1 : Res; | |||
90 | } | |||
91 | } | |||
92 | ||||
93 | llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 93); | |||
94 | } | |||
95 | ||||
96 | namespace { | |||
97 | ||||
98 | struct PPCOperand; | |||
99 | ||||
100 | class PPCAsmParser : public MCTargetAsmParser { | |||
101 | bool IsPPC64; | |||
102 | bool IsDarwin; | |||
103 | ||||
104 | void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); } | |||
105 | ||||
106 | bool isPPC64() const { return IsPPC64; } | |||
107 | bool isDarwin() const { return IsDarwin; } | |||
108 | ||||
109 | bool MatchRegisterName(unsigned &RegNo, int64_t &IntVal); | |||
110 | ||||
111 | bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; | |||
112 | ||||
113 | const MCExpr *ExtractModifierFromExpr(const MCExpr *E, | |||
114 | PPCMCExpr::VariantKind &Variant); | |||
115 | const MCExpr *FixupVariantKind(const MCExpr *E); | |||
116 | bool ParseExpression(const MCExpr *&EVal); | |||
117 | bool ParseDarwinExpression(const MCExpr *&EVal); | |||
118 | ||||
119 | bool ParseOperand(OperandVector &Operands); | |||
120 | ||||
121 | bool ParseDirectiveWord(unsigned Size, AsmToken ID); | |||
122 | bool ParseDirectiveTC(unsigned Size, AsmToken ID); | |||
123 | bool ParseDirectiveMachine(SMLoc L); | |||
124 | bool ParseDarwinDirectiveMachine(SMLoc L); | |||
125 | bool ParseDirectiveAbiVersion(SMLoc L); | |||
126 | bool ParseDirectiveLocalEntry(SMLoc L); | |||
127 | ||||
128 | bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | |||
129 | OperandVector &Operands, MCStreamer &Out, | |||
130 | uint64_t &ErrorInfo, | |||
131 | bool MatchingInlineAsm) override; | |||
132 | ||||
133 | void ProcessInstruction(MCInst &Inst, const OperandVector &Ops); | |||
134 | ||||
135 | /// @name Auto-generated Match Functions | |||
136 | /// { | |||
137 | ||||
138 | #define GET_ASSEMBLER_HEADER | |||
139 | #include "PPCGenAsmMatcher.inc" | |||
140 | ||||
141 | /// } | |||
142 | ||||
143 | ||||
144 | public: | |||
145 | PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &, | |||
146 | const MCInstrInfo &MII, const MCTargetOptions &Options) | |||
147 | : MCTargetAsmParser(Options, STI, MII) { | |||
148 | // Check for 64-bit vs. 32-bit pointer mode. | |||
149 | const Triple &TheTriple = STI.getTargetTriple(); | |||
150 | IsPPC64 = TheTriple.isPPC64(); | |||
151 | IsDarwin = TheTriple.isMacOSX(); | |||
152 | // Initialize the set of available features. | |||
153 | setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); | |||
154 | } | |||
155 | ||||
156 | bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, | |||
157 | SMLoc NameLoc, OperandVector &Operands) override; | |||
158 | ||||
159 | bool ParseDirective(AsmToken DirectiveID) override; | |||
160 | ||||
161 | unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, | |||
162 | unsigned Kind) override; | |||
163 | ||||
164 | const MCExpr *applyModifierToExpr(const MCExpr *E, | |||
165 | MCSymbolRefExpr::VariantKind, | |||
166 | MCContext &Ctx) override; | |||
167 | }; | |||
168 | ||||
169 | /// PPCOperand - Instances of this class represent a parsed PowerPC machine | |||
170 | /// instruction. | |||
171 | struct PPCOperand : public MCParsedAsmOperand { | |||
172 | enum KindTy { | |||
173 | Token, | |||
174 | Immediate, | |||
175 | ContextImmediate, | |||
176 | Expression, | |||
177 | TLSRegister | |||
178 | } Kind; | |||
179 | ||||
180 | SMLoc StartLoc, EndLoc; | |||
181 | bool IsPPC64; | |||
182 | ||||
183 | struct TokOp { | |||
184 | const char *Data; | |||
185 | unsigned Length; | |||
186 | }; | |||
187 | ||||
188 | struct ImmOp { | |||
189 | int64_t Val; | |||
190 | }; | |||
191 | ||||
192 | struct ExprOp { | |||
193 | const MCExpr *Val; | |||
194 | int64_t CRVal; // Cached result of EvaluateCRExpr(Val) | |||
195 | }; | |||
196 | ||||
197 | struct TLSRegOp { | |||
198 | const MCSymbolRefExpr *Sym; | |||
199 | }; | |||
200 | ||||
201 | union { | |||
202 | struct TokOp Tok; | |||
203 | struct ImmOp Imm; | |||
204 | struct ExprOp Expr; | |||
205 | struct TLSRegOp TLSReg; | |||
206 | }; | |||
207 | ||||
208 | PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} | |||
209 | public: | |||
210 | PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() { | |||
211 | Kind = o.Kind; | |||
212 | StartLoc = o.StartLoc; | |||
213 | EndLoc = o.EndLoc; | |||
214 | IsPPC64 = o.IsPPC64; | |||
215 | switch (Kind) { | |||
216 | case Token: | |||
217 | Tok = o.Tok; | |||
218 | break; | |||
219 | case Immediate: | |||
220 | case ContextImmediate: | |||
221 | Imm = o.Imm; | |||
222 | break; | |||
223 | case Expression: | |||
224 | Expr = o.Expr; | |||
225 | break; | |||
226 | case TLSRegister: | |||
227 | TLSReg = o.TLSReg; | |||
228 | break; | |||
229 | } | |||
230 | } | |||
231 | ||||
232 | // Disable use of sized deallocation due to overallocation of PPCOperand | |||
233 | // objects in CreateTokenWithStringCopy. | |||
234 | void operator delete(void *p) { ::operator delete(p); } | |||
235 | ||||
236 | /// getStartLoc - Get the location of the first token of this operand. | |||
237 | SMLoc getStartLoc() const override { return StartLoc; } | |||
238 | ||||
239 | /// getEndLoc - Get the location of the last token of this operand. | |||
240 | SMLoc getEndLoc() const override { return EndLoc; } | |||
241 | ||||
242 | /// getLocRange - Get the range between the first and last token of this | |||
243 | /// operand. | |||
244 | SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } | |||
245 | ||||
246 | /// isPPC64 - True if this operand is for an instruction in 64-bit mode. | |||
247 | bool isPPC64() const { return IsPPC64; } | |||
248 | ||||
249 | int64_t getImm() const { | |||
250 | assert(Kind == Immediate && "Invalid access!")((Kind == Immediate && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("Kind == Immediate && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 250, __PRETTY_FUNCTION__)); | |||
251 | return Imm.Val; | |||
252 | } | |||
253 | int64_t getImmS16Context() const { | |||
254 | assert((Kind == Immediate || Kind == ContextImmediate) &&(((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == Immediate || Kind == ContextImmediate) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 255, __PRETTY_FUNCTION__)) | |||
255 | "Invalid access!")(((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == Immediate || Kind == ContextImmediate) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 255, __PRETTY_FUNCTION__)); | |||
256 | if (Kind == Immediate) | |||
257 | return Imm.Val; | |||
258 | return static_cast<int16_t>(Imm.Val); | |||
259 | } | |||
260 | int64_t getImmU16Context() const { | |||
261 | assert((Kind == Immediate || Kind == ContextImmediate) &&(((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == Immediate || Kind == ContextImmediate) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 262, __PRETTY_FUNCTION__)) | |||
262 | "Invalid access!")(((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!" ) ? static_cast<void> (0) : __assert_fail ("(Kind == Immediate || Kind == ContextImmediate) && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 262, __PRETTY_FUNCTION__)); | |||
263 | return Imm.Val; | |||
264 | } | |||
265 | ||||
266 | const MCExpr *getExpr() const { | |||
267 | assert(Kind == Expression && "Invalid access!")((Kind == Expression && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("Kind == Expression && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 267, __PRETTY_FUNCTION__)); | |||
268 | return Expr.Val; | |||
269 | } | |||
270 | ||||
271 | int64_t getExprCRVal() const { | |||
272 | assert(Kind == Expression && "Invalid access!")((Kind == Expression && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("Kind == Expression && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 272, __PRETTY_FUNCTION__)); | |||
273 | return Expr.CRVal; | |||
274 | } | |||
275 | ||||
276 | const MCExpr *getTLSReg() const { | |||
277 | assert(Kind == TLSRegister && "Invalid access!")((Kind == TLSRegister && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("Kind == TLSRegister && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 277, __PRETTY_FUNCTION__)); | |||
278 | return TLSReg.Sym; | |||
279 | } | |||
280 | ||||
281 | unsigned getReg() const override { | |||
282 | assert(isRegNumber() && "Invalid access!")((isRegNumber() && "Invalid access!") ? static_cast< void> (0) : __assert_fail ("isRegNumber() && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 282, __PRETTY_FUNCTION__)); | |||
283 | return (unsigned) Imm.Val; | |||
284 | } | |||
285 | ||||
286 | unsigned getVSReg() const { | |||
287 | assert(isVSRegNumber() && "Invalid access!")((isVSRegNumber() && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("isVSRegNumber() && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 287, __PRETTY_FUNCTION__)); | |||
288 | return (unsigned) Imm.Val; | |||
289 | } | |||
290 | ||||
291 | unsigned getCCReg() const { | |||
292 | assert(isCCRegNumber() && "Invalid access!")((isCCRegNumber() && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("isCCRegNumber() && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 292, __PRETTY_FUNCTION__)); | |||
293 | return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal); | |||
294 | } | |||
295 | ||||
296 | unsigned getCRBit() const { | |||
297 | assert(isCRBitNumber() && "Invalid access!")((isCRBitNumber() && "Invalid access!") ? static_cast <void> (0) : __assert_fail ("isCRBitNumber() && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 297, __PRETTY_FUNCTION__)); | |||
298 | return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal); | |||
299 | } | |||
300 | ||||
301 | unsigned getCRBitMask() const { | |||
302 | assert(isCRBitMask() && "Invalid access!")((isCRBitMask() && "Invalid access!") ? static_cast< void> (0) : __assert_fail ("isCRBitMask() && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 302, __PRETTY_FUNCTION__)); | |||
303 | return 7 - countTrailingZeros<uint64_t>(Imm.Val); | |||
304 | } | |||
305 | ||||
306 | bool isToken() const override { return Kind == Token; } | |||
307 | bool isImm() const override { | |||
308 | return Kind == Immediate || Kind == Expression; | |||
309 | } | |||
310 | bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); } | |||
311 | bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); } | |||
312 | bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); } | |||
313 | bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); } | |||
314 | bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); } | |||
315 | bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); } | |||
316 | bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); } | |||
317 | bool isU6ImmX2() const { return Kind == Immediate && | |||
318 | isUInt<6>(getImm()) && | |||
319 | (getImm() & 1) == 0; } | |||
320 | bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); } | |||
321 | bool isU7ImmX4() const { return Kind == Immediate && | |||
322 | isUInt<7>(getImm()) && | |||
323 | (getImm() & 3) == 0; } | |||
324 | bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); } | |||
325 | bool isU8ImmX8() const { return Kind == Immediate && | |||
326 | isUInt<8>(getImm()) && | |||
327 | (getImm() & 7) == 0; } | |||
328 | ||||
329 | bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); } | |||
330 | bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); } | |||
331 | bool isU16Imm() const { | |||
332 | switch (Kind) { | |||
333 | case Expression: | |||
334 | return true; | |||
335 | case Immediate: | |||
336 | case ContextImmediate: | |||
337 | return isUInt<16>(getImmU16Context()); | |||
338 | default: | |||
339 | return false; | |||
340 | } | |||
341 | } | |||
342 | bool isS16Imm() const { | |||
343 | switch (Kind) { | |||
344 | case Expression: | |||
345 | return true; | |||
346 | case Immediate: | |||
347 | case ContextImmediate: | |||
348 | return isInt<16>(getImmS16Context()); | |||
349 | default: | |||
350 | return false; | |||
351 | } | |||
352 | } | |||
353 | bool isS16ImmX4() const { return Kind == Expression || | |||
354 | (Kind == Immediate && isInt<16>(getImm()) && | |||
355 | (getImm() & 3) == 0); } | |||
356 | bool isS16ImmX16() const { return Kind == Expression || | |||
357 | (Kind == Immediate && isInt<16>(getImm()) && | |||
358 | (getImm() & 15) == 0); } | |||
359 | bool isS17Imm() const { | |||
360 | switch (Kind) { | |||
361 | case Expression: | |||
362 | return true; | |||
363 | case Immediate: | |||
364 | case ContextImmediate: | |||
365 | return isInt<17>(getImmS16Context()); | |||
366 | default: | |||
367 | return false; | |||
368 | } | |||
369 | } | |||
370 | bool isTLSReg() const { return Kind == TLSRegister; } | |||
371 | bool isDirectBr() const { | |||
372 | if (Kind == Expression) | |||
373 | return true; | |||
374 | if (Kind != Immediate) | |||
375 | return false; | |||
376 | // Operand must be 64-bit aligned, signed 27-bit immediate. | |||
377 | if ((getImm() & 3) != 0) | |||
378 | return false; | |||
379 | if (isInt<26>(getImm())) | |||
380 | return true; | |||
381 | if (!IsPPC64) { | |||
382 | // In 32-bit mode, large 32-bit quantities wrap around. | |||
383 | if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm()))) | |||
384 | return true; | |||
385 | } | |||
386 | return false; | |||
387 | } | |||
388 | bool isCondBr() const { return Kind == Expression || | |||
389 | (Kind == Immediate && isInt<16>(getImm()) && | |||
390 | (getImm() & 3) == 0); } | |||
391 | bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); } | |||
392 | bool isVSRegNumber() const { | |||
393 | return Kind == Immediate && isUInt<6>(getImm()); | |||
394 | } | |||
395 | bool isCCRegNumber() const { return (Kind == Expression | |||
396 | && isUInt<3>(getExprCRVal())) || | |||
397 | (Kind == Immediate | |||
398 | && isUInt<3>(getImm())); } | |||
399 | bool isCRBitNumber() const { return (Kind == Expression | |||
400 | && isUInt<5>(getExprCRVal())) || | |||
401 | (Kind == Immediate | |||
402 | && isUInt<5>(getImm())); } | |||
403 | bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) && | |||
404 | isPowerOf2_32(getImm()); } | |||
405 | bool isATBitsAsHint() const { return false; } | |||
406 | bool isMem() const override { return false; } | |||
407 | bool isReg() const override { return false; } | |||
408 | ||||
409 | void addRegOperands(MCInst &Inst, unsigned N) const { | |||
410 | llvm_unreachable("addRegOperands")::llvm::llvm_unreachable_internal("addRegOperands", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 410); | |||
411 | } | |||
412 | ||||
413 | void addRegGPRCOperands(MCInst &Inst, unsigned N) const { | |||
414 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 414, __PRETTY_FUNCTION__)); | |||
415 | Inst.addOperand(MCOperand::createReg(RRegs[getReg()])); | |||
416 | } | |||
417 | ||||
418 | void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const { | |||
419 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 419, __PRETTY_FUNCTION__)); | |||
420 | Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()])); | |||
421 | } | |||
422 | ||||
423 | void addRegG8RCOperands(MCInst &Inst, unsigned N) const { | |||
424 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 424, __PRETTY_FUNCTION__)); | |||
425 | Inst.addOperand(MCOperand::createReg(XRegs[getReg()])); | |||
426 | } | |||
427 | ||||
428 | void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const { | |||
429 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 429, __PRETTY_FUNCTION__)); | |||
430 | Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()])); | |||
431 | } | |||
432 | ||||
433 | void addRegGxRCOperands(MCInst &Inst, unsigned N) const { | |||
434 | if (isPPC64()) | |||
435 | addRegG8RCOperands(Inst, N); | |||
436 | else | |||
437 | addRegGPRCOperands(Inst, N); | |||
438 | } | |||
439 | ||||
440 | void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const { | |||
441 | if (isPPC64()) | |||
442 | addRegG8RCNoX0Operands(Inst, N); | |||
443 | else | |||
444 | addRegGPRCNoR0Operands(Inst, N); | |||
445 | } | |||
446 | ||||
447 | void addRegF4RCOperands(MCInst &Inst, unsigned N) const { | |||
448 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 448, __PRETTY_FUNCTION__)); | |||
449 | Inst.addOperand(MCOperand::createReg(FRegs[getReg()])); | |||
450 | } | |||
451 | ||||
452 | void addRegF8RCOperands(MCInst &Inst, unsigned N) const { | |||
453 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 453, __PRETTY_FUNCTION__)); | |||
454 | Inst.addOperand(MCOperand::createReg(FRegs[getReg()])); | |||
455 | } | |||
456 | ||||
457 | void addRegVFRCOperands(MCInst &Inst, unsigned N) const { | |||
458 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 458, __PRETTY_FUNCTION__)); | |||
459 | Inst.addOperand(MCOperand::createReg(VFRegs[getReg()])); | |||
460 | } | |||
461 | ||||
462 | void addRegVRRCOperands(MCInst &Inst, unsigned N) const { | |||
463 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 463, __PRETTY_FUNCTION__)); | |||
464 | Inst.addOperand(MCOperand::createReg(VRegs[getReg()])); | |||
465 | } | |||
466 | ||||
467 | void addRegVSRCOperands(MCInst &Inst, unsigned N) const { | |||
468 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 468, __PRETTY_FUNCTION__)); | |||
469 | Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()])); | |||
470 | } | |||
471 | ||||
472 | void addRegVSFRCOperands(MCInst &Inst, unsigned N) const { | |||
473 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 473, __PRETTY_FUNCTION__)); | |||
474 | Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()])); | |||
475 | } | |||
476 | ||||
477 | void addRegVSSRCOperands(MCInst &Inst, unsigned N) const { | |||
478 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 478, __PRETTY_FUNCTION__)); | |||
479 | Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()])); | |||
480 | } | |||
481 | ||||
482 | void addRegQFRCOperands(MCInst &Inst, unsigned N) const { | |||
483 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 483, __PRETTY_FUNCTION__)); | |||
484 | Inst.addOperand(MCOperand::createReg(QFRegs[getReg()])); | |||
485 | } | |||
486 | ||||
487 | void addRegQSRCOperands(MCInst &Inst, unsigned N) const { | |||
488 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 488, __PRETTY_FUNCTION__)); | |||
489 | Inst.addOperand(MCOperand::createReg(QFRegs[getReg()])); | |||
490 | } | |||
491 | ||||
492 | void addRegQBRCOperands(MCInst &Inst, unsigned N) const { | |||
493 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 493, __PRETTY_FUNCTION__)); | |||
494 | Inst.addOperand(MCOperand::createReg(QFRegs[getReg()])); | |||
495 | } | |||
496 | ||||
497 | void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const { | |||
498 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 498, __PRETTY_FUNCTION__)); | |||
499 | Inst.addOperand(MCOperand::createReg(RRegs[getReg()])); | |||
500 | } | |||
501 | ||||
502 | void addRegSPERCOperands(MCInst &Inst, unsigned N) const { | |||
503 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 503, __PRETTY_FUNCTION__)); | |||
504 | Inst.addOperand(MCOperand::createReg(SPERegs[getReg()])); | |||
505 | } | |||
506 | ||||
507 | void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const { | |||
508 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 508, __PRETTY_FUNCTION__)); | |||
509 | Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()])); | |||
510 | } | |||
511 | ||||
512 | void addRegCRRCOperands(MCInst &Inst, unsigned N) const { | |||
513 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 513, __PRETTY_FUNCTION__)); | |||
514 | Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()])); | |||
515 | } | |||
516 | ||||
517 | void addCRBitMaskOperands(MCInst &Inst, unsigned N) const { | |||
518 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 518, __PRETTY_FUNCTION__)); | |||
519 | Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()])); | |||
520 | } | |||
521 | ||||
522 | void addImmOperands(MCInst &Inst, unsigned N) const { | |||
523 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 523, __PRETTY_FUNCTION__)); | |||
524 | if (Kind == Immediate) | |||
525 | Inst.addOperand(MCOperand::createImm(getImm())); | |||
526 | else | |||
527 | Inst.addOperand(MCOperand::createExpr(getExpr())); | |||
528 | } | |||
529 | ||||
530 | void addS16ImmOperands(MCInst &Inst, unsigned N) const { | |||
531 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 531, __PRETTY_FUNCTION__)); | |||
532 | switch (Kind) { | |||
533 | case Immediate: | |||
534 | Inst.addOperand(MCOperand::createImm(getImm())); | |||
535 | break; | |||
536 | case ContextImmediate: | |||
537 | Inst.addOperand(MCOperand::createImm(getImmS16Context())); | |||
538 | break; | |||
539 | default: | |||
540 | Inst.addOperand(MCOperand::createExpr(getExpr())); | |||
541 | break; | |||
542 | } | |||
543 | } | |||
544 | ||||
545 | void addU16ImmOperands(MCInst &Inst, unsigned N) const { | |||
546 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 546, __PRETTY_FUNCTION__)); | |||
547 | switch (Kind) { | |||
548 | case Immediate: | |||
549 | Inst.addOperand(MCOperand::createImm(getImm())); | |||
550 | break; | |||
551 | case ContextImmediate: | |||
552 | Inst.addOperand(MCOperand::createImm(getImmU16Context())); | |||
553 | break; | |||
554 | default: | |||
555 | Inst.addOperand(MCOperand::createExpr(getExpr())); | |||
556 | break; | |||
557 | } | |||
558 | } | |||
559 | ||||
560 | void addBranchTargetOperands(MCInst &Inst, unsigned N) const { | |||
561 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 561, __PRETTY_FUNCTION__)); | |||
562 | if (Kind == Immediate) | |||
563 | Inst.addOperand(MCOperand::createImm(getImm() / 4)); | |||
564 | else | |||
565 | Inst.addOperand(MCOperand::createExpr(getExpr())); | |||
566 | } | |||
567 | ||||
568 | void addTLSRegOperands(MCInst &Inst, unsigned N) const { | |||
569 | assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast <void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 569, __PRETTY_FUNCTION__)); | |||
570 | Inst.addOperand(MCOperand::createExpr(getTLSReg())); | |||
571 | } | |||
572 | ||||
573 | StringRef getToken() const { | |||
574 | assert(Kind == Token && "Invalid access!")((Kind == Token && "Invalid access!") ? static_cast< void> (0) : __assert_fail ("Kind == Token && \"Invalid access!\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 574, __PRETTY_FUNCTION__)); | |||
575 | return StringRef(Tok.Data, Tok.Length); | |||
576 | } | |||
577 | ||||
578 | void print(raw_ostream &OS) const override; | |||
579 | ||||
580 | static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S, | |||
581 | bool IsPPC64) { | |||
582 | auto Op = make_unique<PPCOperand>(Token); | |||
583 | Op->Tok.Data = Str.data(); | |||
584 | Op->Tok.Length = Str.size(); | |||
585 | Op->StartLoc = S; | |||
586 | Op->EndLoc = S; | |||
587 | Op->IsPPC64 = IsPPC64; | |||
588 | return Op; | |||
589 | } | |||
590 | ||||
591 | static std::unique_ptr<PPCOperand> | |||
592 | CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) { | |||
593 | // Allocate extra memory for the string and copy it. | |||
594 | // FIXME: This is incorrect, Operands are owned by unique_ptr with a default | |||
595 | // deleter which will destroy them by simply using "delete", not correctly | |||
596 | // calling operator delete on this extra memory after calling the dtor | |||
597 | // explicitly. | |||
598 | void *Mem = ::operator new(sizeof(PPCOperand) + Str.size()); | |||
599 | std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token)); | |||
600 | Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1); | |||
601 | Op->Tok.Length = Str.size(); | |||
602 | std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size()); | |||
603 | Op->StartLoc = S; | |||
604 | Op->EndLoc = S; | |||
605 | Op->IsPPC64 = IsPPC64; | |||
606 | return Op; | |||
607 | } | |||
608 | ||||
609 | static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E, | |||
610 | bool IsPPC64) { | |||
611 | auto Op = make_unique<PPCOperand>(Immediate); | |||
612 | Op->Imm.Val = Val; | |||
613 | Op->StartLoc = S; | |||
614 | Op->EndLoc = E; | |||
615 | Op->IsPPC64 = IsPPC64; | |||
616 | return Op; | |||
617 | } | |||
618 | ||||
619 | static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S, | |||
620 | SMLoc E, bool IsPPC64) { | |||
621 | auto Op = make_unique<PPCOperand>(Expression); | |||
622 | Op->Expr.Val = Val; | |||
623 | Op->Expr.CRVal = EvaluateCRExpr(Val); | |||
624 | Op->StartLoc = S; | |||
625 | Op->EndLoc = E; | |||
626 | Op->IsPPC64 = IsPPC64; | |||
627 | return Op; | |||
628 | } | |||
629 | ||||
630 | static std::unique_ptr<PPCOperand> | |||
631 | CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) { | |||
632 | auto Op = make_unique<PPCOperand>(TLSRegister); | |||
633 | Op->TLSReg.Sym = Sym; | |||
634 | Op->StartLoc = S; | |||
635 | Op->EndLoc = E; | |||
636 | Op->IsPPC64 = IsPPC64; | |||
637 | return Op; | |||
638 | } | |||
639 | ||||
640 | static std::unique_ptr<PPCOperand> | |||
641 | CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { | |||
642 | auto Op = make_unique<PPCOperand>(ContextImmediate); | |||
643 | Op->Imm.Val = Val; | |||
644 | Op->StartLoc = S; | |||
645 | Op->EndLoc = E; | |||
646 | Op->IsPPC64 = IsPPC64; | |||
647 | return Op; | |||
648 | } | |||
649 | ||||
650 | static std::unique_ptr<PPCOperand> | |||
651 | CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) { | |||
652 | if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val)) | |||
653 | return CreateImm(CE->getValue(), S, E, IsPPC64); | |||
654 | ||||
655 | if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val)) | |||
656 | if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS) | |||
657 | return CreateTLSReg(SRE, S, E, IsPPC64); | |||
658 | ||||
659 | if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) { | |||
660 | int64_t Res; | |||
661 | if (TE->evaluateAsConstant(Res)) | |||
662 | return CreateContextImm(Res, S, E, IsPPC64); | |||
663 | } | |||
664 | ||||
665 | return CreateExpr(Val, S, E, IsPPC64); | |||
666 | } | |||
667 | }; | |||
668 | ||||
669 | } // end anonymous namespace. | |||
670 | ||||
671 | void PPCOperand::print(raw_ostream &OS) const { | |||
672 | switch (Kind) { | |||
673 | case Token: | |||
674 | OS << "'" << getToken() << "'"; | |||
675 | break; | |||
676 | case Immediate: | |||
677 | case ContextImmediate: | |||
678 | OS << getImm(); | |||
679 | break; | |||
680 | case Expression: | |||
681 | OS << *getExpr(); | |||
682 | break; | |||
683 | case TLSRegister: | |||
684 | OS << *getTLSReg(); | |||
685 | break; | |||
686 | } | |||
687 | } | |||
688 | ||||
689 | static void | |||
690 | addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) { | |||
691 | if (Op.isImm()) { | |||
692 | Inst.addOperand(MCOperand::createImm(-Op.getImm())); | |||
693 | return; | |||
694 | } | |||
695 | const MCExpr *Expr = Op.getExpr(); | |||
696 | if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) { | |||
697 | if (UnExpr->getOpcode() == MCUnaryExpr::Minus) { | |||
698 | Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr())); | |||
699 | return; | |||
700 | } | |||
701 | } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) { | |||
702 | if (BinExpr->getOpcode() == MCBinaryExpr::Sub) { | |||
703 | const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(), | |||
704 | BinExpr->getLHS(), Ctx); | |||
705 | Inst.addOperand(MCOperand::createExpr(NE)); | |||
706 | return; | |||
707 | } | |||
708 | } | |||
709 | Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx))); | |||
710 | } | |||
711 | ||||
712 | void PPCAsmParser::ProcessInstruction(MCInst &Inst, | |||
713 | const OperandVector &Operands) { | |||
714 | int Opcode = Inst.getOpcode(); | |||
715 | switch (Opcode) { | |||
716 | case PPC::DCBTx: | |||
717 | case PPC::DCBTT: | |||
718 | case PPC::DCBTSTx: | |||
719 | case PPC::DCBTSTT: { | |||
720 | MCInst TmpInst; | |||
721 | TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ? | |||
722 | PPC::DCBT : PPC::DCBTST); | |||
723 | TmpInst.addOperand(MCOperand::createImm( | |||
724 | (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16)); | |||
725 | TmpInst.addOperand(Inst.getOperand(0)); | |||
726 | TmpInst.addOperand(Inst.getOperand(1)); | |||
727 | Inst = TmpInst; | |||
728 | break; | |||
729 | } | |||
730 | case PPC::DCBTCT: | |||
731 | case PPC::DCBTDS: { | |||
732 | MCInst TmpInst; | |||
733 | TmpInst.setOpcode(PPC::DCBT); | |||
734 | TmpInst.addOperand(Inst.getOperand(2)); | |||
735 | TmpInst.addOperand(Inst.getOperand(0)); | |||
736 | TmpInst.addOperand(Inst.getOperand(1)); | |||
737 | Inst = TmpInst; | |||
738 | break; | |||
739 | } | |||
740 | case PPC::DCBTSTCT: | |||
741 | case PPC::DCBTSTDS: { | |||
742 | MCInst TmpInst; | |||
743 | TmpInst.setOpcode(PPC::DCBTST); | |||
744 | TmpInst.addOperand(Inst.getOperand(2)); | |||
745 | TmpInst.addOperand(Inst.getOperand(0)); | |||
746 | TmpInst.addOperand(Inst.getOperand(1)); | |||
747 | Inst = TmpInst; | |||
748 | break; | |||
749 | } | |||
750 | case PPC::DCBFx: | |||
751 | case PPC::DCBFL: | |||
752 | case PPC::DCBFLP: { | |||
753 | int L = 0; | |||
754 | if (Opcode == PPC::DCBFL) | |||
755 | L = 1; | |||
756 | else if (Opcode == PPC::DCBFLP) | |||
757 | L = 3; | |||
758 | ||||
759 | MCInst TmpInst; | |||
760 | TmpInst.setOpcode(PPC::DCBF); | |||
761 | TmpInst.addOperand(MCOperand::createImm(L)); | |||
762 | TmpInst.addOperand(Inst.getOperand(0)); | |||
763 | TmpInst.addOperand(Inst.getOperand(1)); | |||
764 | Inst = TmpInst; | |||
765 | break; | |||
766 | } | |||
767 | case PPC::LAx: { | |||
768 | MCInst TmpInst; | |||
769 | TmpInst.setOpcode(PPC::LA); | |||
770 | TmpInst.addOperand(Inst.getOperand(0)); | |||
771 | TmpInst.addOperand(Inst.getOperand(2)); | |||
772 | TmpInst.addOperand(Inst.getOperand(1)); | |||
773 | Inst = TmpInst; | |||
774 | break; | |||
775 | } | |||
776 | case PPC::SUBI: { | |||
777 | MCInst TmpInst; | |||
778 | TmpInst.setOpcode(PPC::ADDI); | |||
779 | TmpInst.addOperand(Inst.getOperand(0)); | |||
780 | TmpInst.addOperand(Inst.getOperand(1)); | |||
781 | addNegOperand(TmpInst, Inst.getOperand(2), getContext()); | |||
782 | Inst = TmpInst; | |||
783 | break; | |||
784 | } | |||
785 | case PPC::SUBIS: { | |||
786 | MCInst TmpInst; | |||
787 | TmpInst.setOpcode(PPC::ADDIS); | |||
788 | TmpInst.addOperand(Inst.getOperand(0)); | |||
789 | TmpInst.addOperand(Inst.getOperand(1)); | |||
790 | addNegOperand(TmpInst, Inst.getOperand(2), getContext()); | |||
791 | Inst = TmpInst; | |||
792 | break; | |||
793 | } | |||
794 | case PPC::SUBIC: { | |||
795 | MCInst TmpInst; | |||
796 | TmpInst.setOpcode(PPC::ADDIC); | |||
797 | TmpInst.addOperand(Inst.getOperand(0)); | |||
798 | TmpInst.addOperand(Inst.getOperand(1)); | |||
799 | addNegOperand(TmpInst, Inst.getOperand(2), getContext()); | |||
800 | Inst = TmpInst; | |||
801 | break; | |||
802 | } | |||
803 | case PPC::SUBICo: { | |||
804 | MCInst TmpInst; | |||
805 | TmpInst.setOpcode(PPC::ADDICo); | |||
806 | TmpInst.addOperand(Inst.getOperand(0)); | |||
807 | TmpInst.addOperand(Inst.getOperand(1)); | |||
808 | addNegOperand(TmpInst, Inst.getOperand(2), getContext()); | |||
809 | Inst = TmpInst; | |||
810 | break; | |||
811 | } | |||
812 | case PPC::EXTLWI: | |||
813 | case PPC::EXTLWIo: { | |||
814 | MCInst TmpInst; | |||
815 | int64_t N = Inst.getOperand(2).getImm(); | |||
816 | int64_t B = Inst.getOperand(3).getImm(); | |||
817 | TmpInst.setOpcode(Opcode == PPC::EXTLWI? PPC::RLWINM : PPC::RLWINMo); | |||
818 | TmpInst.addOperand(Inst.getOperand(0)); | |||
819 | TmpInst.addOperand(Inst.getOperand(1)); | |||
820 | TmpInst.addOperand(MCOperand::createImm(B)); | |||
821 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
822 | TmpInst.addOperand(MCOperand::createImm(N - 1)); | |||
823 | Inst = TmpInst; | |||
824 | break; | |||
825 | } | |||
826 | case PPC::EXTRWI: | |||
827 | case PPC::EXTRWIo: { | |||
828 | MCInst TmpInst; | |||
829 | int64_t N = Inst.getOperand(2).getImm(); | |||
830 | int64_t B = Inst.getOperand(3).getImm(); | |||
831 | TmpInst.setOpcode(Opcode == PPC::EXTRWI? PPC::RLWINM : PPC::RLWINMo); | |||
832 | TmpInst.addOperand(Inst.getOperand(0)); | |||
833 | TmpInst.addOperand(Inst.getOperand(1)); | |||
834 | TmpInst.addOperand(MCOperand::createImm(B + N)); | |||
835 | TmpInst.addOperand(MCOperand::createImm(32 - N)); | |||
836 | TmpInst.addOperand(MCOperand::createImm(31)); | |||
837 | Inst = TmpInst; | |||
838 | break; | |||
839 | } | |||
840 | case PPC::INSLWI: | |||
841 | case PPC::INSLWIo: { | |||
842 | MCInst TmpInst; | |||
843 | int64_t N = Inst.getOperand(2).getImm(); | |||
844 | int64_t B = Inst.getOperand(3).getImm(); | |||
845 | TmpInst.setOpcode(Opcode == PPC::INSLWI? PPC::RLWIMI : PPC::RLWIMIo); | |||
846 | TmpInst.addOperand(Inst.getOperand(0)); | |||
847 | TmpInst.addOperand(Inst.getOperand(0)); | |||
848 | TmpInst.addOperand(Inst.getOperand(1)); | |||
849 | TmpInst.addOperand(MCOperand::createImm(32 - B)); | |||
850 | TmpInst.addOperand(MCOperand::createImm(B)); | |||
851 | TmpInst.addOperand(MCOperand::createImm((B + N) - 1)); | |||
852 | Inst = TmpInst; | |||
853 | break; | |||
854 | } | |||
855 | case PPC::INSRWI: | |||
856 | case PPC::INSRWIo: { | |||
857 | MCInst TmpInst; | |||
858 | int64_t N = Inst.getOperand(2).getImm(); | |||
859 | int64_t B = Inst.getOperand(3).getImm(); | |||
860 | TmpInst.setOpcode(Opcode == PPC::INSRWI? PPC::RLWIMI : PPC::RLWIMIo); | |||
861 | TmpInst.addOperand(Inst.getOperand(0)); | |||
862 | TmpInst.addOperand(Inst.getOperand(0)); | |||
863 | TmpInst.addOperand(Inst.getOperand(1)); | |||
864 | TmpInst.addOperand(MCOperand::createImm(32 - (B + N))); | |||
865 | TmpInst.addOperand(MCOperand::createImm(B)); | |||
866 | TmpInst.addOperand(MCOperand::createImm((B + N) - 1)); | |||
867 | Inst = TmpInst; | |||
868 | break; | |||
869 | } | |||
870 | case PPC::ROTRWI: | |||
871 | case PPC::ROTRWIo: { | |||
872 | MCInst TmpInst; | |||
873 | int64_t N = Inst.getOperand(2).getImm(); | |||
874 | TmpInst.setOpcode(Opcode == PPC::ROTRWI? PPC::RLWINM : PPC::RLWINMo); | |||
875 | TmpInst.addOperand(Inst.getOperand(0)); | |||
876 | TmpInst.addOperand(Inst.getOperand(1)); | |||
877 | TmpInst.addOperand(MCOperand::createImm(32 - N)); | |||
878 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
879 | TmpInst.addOperand(MCOperand::createImm(31)); | |||
880 | Inst = TmpInst; | |||
881 | break; | |||
882 | } | |||
883 | case PPC::SLWI: | |||
884 | case PPC::SLWIo: { | |||
885 | MCInst TmpInst; | |||
886 | int64_t N = Inst.getOperand(2).getImm(); | |||
887 | TmpInst.setOpcode(Opcode == PPC::SLWI? PPC::RLWINM : PPC::RLWINMo); | |||
888 | TmpInst.addOperand(Inst.getOperand(0)); | |||
889 | TmpInst.addOperand(Inst.getOperand(1)); | |||
890 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
891 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
892 | TmpInst.addOperand(MCOperand::createImm(31 - N)); | |||
893 | Inst = TmpInst; | |||
894 | break; | |||
895 | } | |||
896 | case PPC::SRWI: | |||
897 | case PPC::SRWIo: { | |||
898 | MCInst TmpInst; | |||
899 | int64_t N = Inst.getOperand(2).getImm(); | |||
900 | TmpInst.setOpcode(Opcode == PPC::SRWI? PPC::RLWINM : PPC::RLWINMo); | |||
901 | TmpInst.addOperand(Inst.getOperand(0)); | |||
902 | TmpInst.addOperand(Inst.getOperand(1)); | |||
903 | TmpInst.addOperand(MCOperand::createImm(32 - N)); | |||
904 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
905 | TmpInst.addOperand(MCOperand::createImm(31)); | |||
906 | Inst = TmpInst; | |||
907 | break; | |||
908 | } | |||
909 | case PPC::CLRRWI: | |||
910 | case PPC::CLRRWIo: { | |||
911 | MCInst TmpInst; | |||
912 | int64_t N = Inst.getOperand(2).getImm(); | |||
913 | TmpInst.setOpcode(Opcode == PPC::CLRRWI? PPC::RLWINM : PPC::RLWINMo); | |||
914 | TmpInst.addOperand(Inst.getOperand(0)); | |||
915 | TmpInst.addOperand(Inst.getOperand(1)); | |||
916 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
917 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
918 | TmpInst.addOperand(MCOperand::createImm(31 - N)); | |||
919 | Inst = TmpInst; | |||
920 | break; | |||
921 | } | |||
922 | case PPC::CLRLSLWI: | |||
923 | case PPC::CLRLSLWIo: { | |||
924 | MCInst TmpInst; | |||
925 | int64_t B = Inst.getOperand(2).getImm(); | |||
926 | int64_t N = Inst.getOperand(3).getImm(); | |||
927 | TmpInst.setOpcode(Opcode == PPC::CLRLSLWI? PPC::RLWINM : PPC::RLWINMo); | |||
928 | TmpInst.addOperand(Inst.getOperand(0)); | |||
929 | TmpInst.addOperand(Inst.getOperand(1)); | |||
930 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
931 | TmpInst.addOperand(MCOperand::createImm(B - N)); | |||
932 | TmpInst.addOperand(MCOperand::createImm(31 - N)); | |||
933 | Inst = TmpInst; | |||
934 | break; | |||
935 | } | |||
936 | case PPC::EXTLDI: | |||
937 | case PPC::EXTLDIo: { | |||
938 | MCInst TmpInst; | |||
939 | int64_t N = Inst.getOperand(2).getImm(); | |||
940 | int64_t B = Inst.getOperand(3).getImm(); | |||
941 | TmpInst.setOpcode(Opcode == PPC::EXTLDI? PPC::RLDICR : PPC::RLDICRo); | |||
942 | TmpInst.addOperand(Inst.getOperand(0)); | |||
943 | TmpInst.addOperand(Inst.getOperand(1)); | |||
944 | TmpInst.addOperand(MCOperand::createImm(B)); | |||
945 | TmpInst.addOperand(MCOperand::createImm(N - 1)); | |||
946 | Inst = TmpInst; | |||
947 | break; | |||
948 | } | |||
949 | case PPC::EXTRDI: | |||
950 | case PPC::EXTRDIo: { | |||
951 | MCInst TmpInst; | |||
952 | int64_t N = Inst.getOperand(2).getImm(); | |||
953 | int64_t B = Inst.getOperand(3).getImm(); | |||
954 | TmpInst.setOpcode(Opcode == PPC::EXTRDI? PPC::RLDICL : PPC::RLDICLo); | |||
955 | TmpInst.addOperand(Inst.getOperand(0)); | |||
956 | TmpInst.addOperand(Inst.getOperand(1)); | |||
957 | TmpInst.addOperand(MCOperand::createImm(B + N)); | |||
958 | TmpInst.addOperand(MCOperand::createImm(64 - N)); | |||
959 | Inst = TmpInst; | |||
960 | break; | |||
961 | } | |||
962 | case PPC::INSRDI: | |||
963 | case PPC::INSRDIo: { | |||
964 | MCInst TmpInst; | |||
965 | int64_t N = Inst.getOperand(2).getImm(); | |||
966 | int64_t B = Inst.getOperand(3).getImm(); | |||
967 | TmpInst.setOpcode(Opcode == PPC::INSRDI? PPC::RLDIMI : PPC::RLDIMIo); | |||
968 | TmpInst.addOperand(Inst.getOperand(0)); | |||
969 | TmpInst.addOperand(Inst.getOperand(0)); | |||
970 | TmpInst.addOperand(Inst.getOperand(1)); | |||
971 | TmpInst.addOperand(MCOperand::createImm(64 - (B + N))); | |||
972 | TmpInst.addOperand(MCOperand::createImm(B)); | |||
973 | Inst = TmpInst; | |||
974 | break; | |||
975 | } | |||
976 | case PPC::ROTRDI: | |||
977 | case PPC::ROTRDIo: { | |||
978 | MCInst TmpInst; | |||
979 | int64_t N = Inst.getOperand(2).getImm(); | |||
980 | TmpInst.setOpcode(Opcode == PPC::ROTRDI? PPC::RLDICL : PPC::RLDICLo); | |||
981 | TmpInst.addOperand(Inst.getOperand(0)); | |||
982 | TmpInst.addOperand(Inst.getOperand(1)); | |||
983 | TmpInst.addOperand(MCOperand::createImm(64 - N)); | |||
984 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
985 | Inst = TmpInst; | |||
986 | break; | |||
987 | } | |||
988 | case PPC::SLDI: | |||
989 | case PPC::SLDIo: { | |||
990 | MCInst TmpInst; | |||
991 | int64_t N = Inst.getOperand(2).getImm(); | |||
992 | TmpInst.setOpcode(Opcode == PPC::SLDI? PPC::RLDICR : PPC::RLDICRo); | |||
993 | TmpInst.addOperand(Inst.getOperand(0)); | |||
994 | TmpInst.addOperand(Inst.getOperand(1)); | |||
995 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
996 | TmpInst.addOperand(MCOperand::createImm(63 - N)); | |||
997 | Inst = TmpInst; | |||
998 | break; | |||
999 | } | |||
1000 | case PPC::SUBPCIS: { | |||
1001 | MCInst TmpInst; | |||
1002 | int64_t N = Inst.getOperand(1).getImm(); | |||
1003 | TmpInst.setOpcode(PPC::ADDPCIS); | |||
1004 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1005 | TmpInst.addOperand(MCOperand::createImm(-N)); | |||
1006 | Inst = TmpInst; | |||
1007 | break; | |||
1008 | } | |||
1009 | case PPC::SRDI: | |||
1010 | case PPC::SRDIo: { | |||
1011 | MCInst TmpInst; | |||
1012 | int64_t N = Inst.getOperand(2).getImm(); | |||
1013 | TmpInst.setOpcode(Opcode == PPC::SRDI? PPC::RLDICL : PPC::RLDICLo); | |||
1014 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1015 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1016 | TmpInst.addOperand(MCOperand::createImm(64 - N)); | |||
1017 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
1018 | Inst = TmpInst; | |||
1019 | break; | |||
1020 | } | |||
1021 | case PPC::CLRRDI: | |||
1022 | case PPC::CLRRDIo: { | |||
1023 | MCInst TmpInst; | |||
1024 | int64_t N = Inst.getOperand(2).getImm(); | |||
1025 | TmpInst.setOpcode(Opcode == PPC::CLRRDI? PPC::RLDICR : PPC::RLDICRo); | |||
1026 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1027 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1028 | TmpInst.addOperand(MCOperand::createImm(0)); | |||
1029 | TmpInst.addOperand(MCOperand::createImm(63 - N)); | |||
1030 | Inst = TmpInst; | |||
1031 | break; | |||
1032 | } | |||
1033 | case PPC::CLRLSLDI: | |||
1034 | case PPC::CLRLSLDIo: { | |||
1035 | MCInst TmpInst; | |||
1036 | int64_t B = Inst.getOperand(2).getImm(); | |||
1037 | int64_t N = Inst.getOperand(3).getImm(); | |||
1038 | TmpInst.setOpcode(Opcode == PPC::CLRLSLDI? PPC::RLDIC : PPC::RLDICo); | |||
1039 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1040 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1041 | TmpInst.addOperand(MCOperand::createImm(N)); | |||
1042 | TmpInst.addOperand(MCOperand::createImm(B - N)); | |||
1043 | Inst = TmpInst; | |||
1044 | break; | |||
1045 | } | |||
1046 | case PPC::RLWINMbm: | |||
1047 | case PPC::RLWINMobm: { | |||
1048 | unsigned MB, ME; | |||
1049 | int64_t BM = Inst.getOperand(3).getImm(); | |||
1050 | if (!isRunOfOnes(BM, MB, ME)) | |||
1051 | break; | |||
1052 | ||||
1053 | MCInst TmpInst; | |||
1054 | TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINMo); | |||
1055 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1056 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1057 | TmpInst.addOperand(Inst.getOperand(2)); | |||
1058 | TmpInst.addOperand(MCOperand::createImm(MB)); | |||
1059 | TmpInst.addOperand(MCOperand::createImm(ME)); | |||
1060 | Inst = TmpInst; | |||
1061 | break; | |||
1062 | } | |||
1063 | case PPC::RLWIMIbm: | |||
1064 | case PPC::RLWIMIobm: { | |||
1065 | unsigned MB, ME; | |||
1066 | int64_t BM = Inst.getOperand(3).getImm(); | |||
1067 | if (!isRunOfOnes(BM, MB, ME)) | |||
1068 | break; | |||
1069 | ||||
1070 | MCInst TmpInst; | |||
1071 | TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMIo); | |||
1072 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1073 | TmpInst.addOperand(Inst.getOperand(0)); // The tied operand. | |||
1074 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1075 | TmpInst.addOperand(Inst.getOperand(2)); | |||
1076 | TmpInst.addOperand(MCOperand::createImm(MB)); | |||
1077 | TmpInst.addOperand(MCOperand::createImm(ME)); | |||
1078 | Inst = TmpInst; | |||
1079 | break; | |||
1080 | } | |||
1081 | case PPC::RLWNMbm: | |||
1082 | case PPC::RLWNMobm: { | |||
1083 | unsigned MB, ME; | |||
1084 | int64_t BM = Inst.getOperand(3).getImm(); | |||
1085 | if (!isRunOfOnes(BM, MB, ME)) | |||
1086 | break; | |||
1087 | ||||
1088 | MCInst TmpInst; | |||
1089 | TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNMo); | |||
1090 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1091 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1092 | TmpInst.addOperand(Inst.getOperand(2)); | |||
1093 | TmpInst.addOperand(MCOperand::createImm(MB)); | |||
1094 | TmpInst.addOperand(MCOperand::createImm(ME)); | |||
1095 | Inst = TmpInst; | |||
1096 | break; | |||
1097 | } | |||
1098 | case PPC::MFTB: { | |||
1099 | if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) { | |||
1100 | assert(Inst.getNumOperands() == 2 && "Expecting two operands")((Inst.getNumOperands() == 2 && "Expecting two operands" ) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Expecting two operands\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 1100, __PRETTY_FUNCTION__)); | |||
1101 | Inst.setOpcode(PPC::MFSPR); | |||
1102 | } | |||
1103 | break; | |||
1104 | } | |||
1105 | case PPC::CP_COPYx: | |||
1106 | case PPC::CP_COPY_FIRST: { | |||
1107 | MCInst TmpInst; | |||
1108 | TmpInst.setOpcode(PPC::CP_COPY); | |||
1109 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1110 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1111 | TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_COPYx ? 0 : 1)); | |||
1112 | ||||
1113 | Inst = TmpInst; | |||
1114 | break; | |||
1115 | } | |||
1116 | case PPC::CP_PASTEx : | |||
1117 | case PPC::CP_PASTE_LAST: { | |||
1118 | MCInst TmpInst; | |||
1119 | TmpInst.setOpcode(Opcode == PPC::CP_PASTEx ? | |||
1120 | PPC::CP_PASTE : PPC::CP_PASTEo); | |||
1121 | TmpInst.addOperand(Inst.getOperand(0)); | |||
1122 | TmpInst.addOperand(Inst.getOperand(1)); | |||
1123 | TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_PASTEx ? 0 : 1)); | |||
1124 | ||||
1125 | Inst = TmpInst; | |||
1126 | break; | |||
1127 | } | |||
1128 | } | |||
1129 | } | |||
1130 | ||||
1131 | static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, | |||
1132 | unsigned VariantID = 0); | |||
1133 | ||||
1134 | bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | |||
1135 | OperandVector &Operands, | |||
1136 | MCStreamer &Out, uint64_t &ErrorInfo, | |||
1137 | bool MatchingInlineAsm) { | |||
1138 | MCInst Inst; | |||
1139 | ||||
1140 | switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { | |||
1141 | case Match_Success: | |||
1142 | // Post-process instructions (typically extended mnemonics) | |||
1143 | ProcessInstruction(Inst, Operands); | |||
1144 | Inst.setLoc(IDLoc); | |||
1145 | Out.EmitInstruction(Inst, getSTI()); | |||
1146 | return false; | |||
1147 | case Match_MissingFeature: | |||
1148 | return Error(IDLoc, "instruction use requires an option to be enabled"); | |||
1149 | case Match_MnemonicFail: { | |||
1150 | FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); | |||
1151 | std::string Suggestion = PPCMnemonicSpellCheck( | |||
1152 | ((PPCOperand &)*Operands[0]).getToken(), FBS); | |||
1153 | return Error(IDLoc, "invalid instruction" + Suggestion, | |||
1154 | ((PPCOperand &)*Operands[0]).getLocRange()); | |||
1155 | } | |||
1156 | case Match_InvalidOperand: { | |||
1157 | SMLoc ErrorLoc = IDLoc; | |||
1158 | if (ErrorInfo != ~0ULL) { | |||
1159 | if (ErrorInfo >= Operands.size()) | |||
1160 | return Error(IDLoc, "too few operands for instruction"); | |||
1161 | ||||
1162 | ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc(); | |||
1163 | if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; | |||
1164 | } | |||
1165 | ||||
1166 | return Error(ErrorLoc, "invalid operand for instruction"); | |||
1167 | } | |||
1168 | } | |||
1169 | ||||
1170 | llvm_unreachable("Implement any new match types added!")::llvm::llvm_unreachable_internal("Implement any new match types added!" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 1170); | |||
1171 | } | |||
1172 | ||||
1173 | bool PPCAsmParser::MatchRegisterName(unsigned &RegNo, int64_t &IntVal) { | |||
1174 | if (getParser().getTok().is(AsmToken::Identifier)) { | |||
1175 | StringRef Name = getParser().getTok().getString(); | |||
1176 | if (Name.equals_lower("lr")) { | |||
1177 | RegNo = isPPC64()? PPC::LR8 : PPC::LR; | |||
1178 | IntVal = 8; | |||
1179 | } else if (Name.equals_lower("ctr")) { | |||
1180 | RegNo = isPPC64()? PPC::CTR8 : PPC::CTR; | |||
1181 | IntVal = 9; | |||
1182 | } else if (Name.equals_lower("vrsave")) { | |||
1183 | RegNo = PPC::VRSAVE; | |||
1184 | IntVal = 256; | |||
1185 | } else if (Name.startswith_lower("r") && | |||
1186 | !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { | |||
1187 | RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal]; | |||
1188 | } else if (Name.startswith_lower("f") && | |||
1189 | !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { | |||
1190 | RegNo = FRegs[IntVal]; | |||
1191 | } else if (Name.startswith_lower("vs") && | |||
1192 | !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) { | |||
1193 | RegNo = VSRegs[IntVal]; | |||
1194 | } else if (Name.startswith_lower("v") && | |||
1195 | !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { | |||
1196 | RegNo = VRegs[IntVal]; | |||
1197 | } else if (Name.startswith_lower("q") && | |||
1198 | !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) { | |||
1199 | RegNo = QFRegs[IntVal]; | |||
1200 | } else if (Name.startswith_lower("cr") && | |||
1201 | !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) { | |||
1202 | RegNo = CRRegs[IntVal]; | |||
1203 | } else | |||
1204 | return true; | |||
1205 | getParser().Lex(); | |||
1206 | return false; | |||
1207 | } | |||
1208 | return true; | |||
1209 | } | |||
1210 | ||||
1211 | bool PPCAsmParser:: | |||
1212 | ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { | |||
1213 | const AsmToken &Tok = getParser().getTok(); | |||
1214 | StartLoc = Tok.getLoc(); | |||
1215 | EndLoc = Tok.getEndLoc(); | |||
1216 | RegNo = 0; | |||
1217 | int64_t IntVal; | |||
1218 | if (MatchRegisterName(RegNo, IntVal)) | |||
1219 | return TokError("invalid register name"); | |||
1220 | return false; | |||
1221 | } | |||
1222 | ||||
1223 | /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan | |||
1224 | /// the expression and check for VK_PPC_LO/HI/HA | |||
1225 | /// symbol variants. If all symbols with modifier use the same | |||
1226 | /// variant, return the corresponding PPCMCExpr::VariantKind, | |||
1227 | /// and a modified expression using the default symbol variant. | |||
1228 | /// Otherwise, return NULL. | |||
1229 | const MCExpr *PPCAsmParser:: | |||
1230 | ExtractModifierFromExpr(const MCExpr *E, | |||
1231 | PPCMCExpr::VariantKind &Variant) { | |||
1232 | MCContext &Context = getParser().getContext(); | |||
1233 | Variant = PPCMCExpr::VK_PPC_None; | |||
1234 | ||||
1235 | switch (E->getKind()) { | |||
1236 | case MCExpr::Target: | |||
1237 | case MCExpr::Constant: | |||
1238 | return nullptr; | |||
1239 | ||||
1240 | case MCExpr::SymbolRef: { | |||
1241 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); | |||
1242 | ||||
1243 | switch (SRE->getKind()) { | |||
1244 | case MCSymbolRefExpr::VK_PPC_LO: | |||
1245 | Variant = PPCMCExpr::VK_PPC_LO; | |||
1246 | break; | |||
1247 | case MCSymbolRefExpr::VK_PPC_HI: | |||
1248 | Variant = PPCMCExpr::VK_PPC_HI; | |||
1249 | break; | |||
1250 | case MCSymbolRefExpr::VK_PPC_HA: | |||
1251 | Variant = PPCMCExpr::VK_PPC_HA; | |||
1252 | break; | |||
1253 | case MCSymbolRefExpr::VK_PPC_HIGH: | |||
1254 | Variant = PPCMCExpr::VK_PPC_HIGH; | |||
1255 | break; | |||
1256 | case MCSymbolRefExpr::VK_PPC_HIGHA: | |||
1257 | Variant = PPCMCExpr::VK_PPC_HIGHA; | |||
1258 | break; | |||
1259 | case MCSymbolRefExpr::VK_PPC_HIGHER: | |||
1260 | Variant = PPCMCExpr::VK_PPC_HIGHER; | |||
1261 | break; | |||
1262 | case MCSymbolRefExpr::VK_PPC_HIGHERA: | |||
1263 | Variant = PPCMCExpr::VK_PPC_HIGHERA; | |||
1264 | break; | |||
1265 | case MCSymbolRefExpr::VK_PPC_HIGHEST: | |||
1266 | Variant = PPCMCExpr::VK_PPC_HIGHEST; | |||
1267 | break; | |||
1268 | case MCSymbolRefExpr::VK_PPC_HIGHESTA: | |||
1269 | Variant = PPCMCExpr::VK_PPC_HIGHESTA; | |||
1270 | break; | |||
1271 | default: | |||
1272 | return nullptr; | |||
1273 | } | |||
1274 | ||||
1275 | return MCSymbolRefExpr::create(&SRE->getSymbol(), Context); | |||
1276 | } | |||
1277 | ||||
1278 | case MCExpr::Unary: { | |||
1279 | const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); | |||
1280 | const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant); | |||
1281 | if (!Sub) | |||
1282 | return nullptr; | |||
1283 | return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); | |||
1284 | } | |||
1285 | ||||
1286 | case MCExpr::Binary: { | |||
1287 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); | |||
1288 | PPCMCExpr::VariantKind LHSVariant, RHSVariant; | |||
1289 | const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant); | |||
1290 | const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant); | |||
1291 | ||||
1292 | if (!LHS && !RHS) | |||
1293 | return nullptr; | |||
1294 | ||||
1295 | if (!LHS) LHS = BE->getLHS(); | |||
1296 | if (!RHS) RHS = BE->getRHS(); | |||
1297 | ||||
1298 | if (LHSVariant == PPCMCExpr::VK_PPC_None) | |||
1299 | Variant = RHSVariant; | |||
1300 | else if (RHSVariant == PPCMCExpr::VK_PPC_None) | |||
1301 | Variant = LHSVariant; | |||
1302 | else if (LHSVariant == RHSVariant) | |||
1303 | Variant = LHSVariant; | |||
1304 | else | |||
1305 | return nullptr; | |||
1306 | ||||
1307 | return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); | |||
1308 | } | |||
1309 | } | |||
1310 | ||||
1311 | llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 1311); | |||
1312 | } | |||
1313 | ||||
1314 | /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace | |||
1315 | /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having | |||
1316 | /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT. | |||
1317 | /// FIXME: This is a hack. | |||
1318 | const MCExpr *PPCAsmParser:: | |||
1319 | FixupVariantKind(const MCExpr *E) { | |||
1320 | MCContext &Context = getParser().getContext(); | |||
1321 | ||||
1322 | switch (E->getKind()) { | |||
1323 | case MCExpr::Target: | |||
1324 | case MCExpr::Constant: | |||
1325 | return E; | |||
1326 | ||||
1327 | case MCExpr::SymbolRef: { | |||
1328 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); | |||
1329 | MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; | |||
1330 | ||||
1331 | switch (SRE->getKind()) { | |||
1332 | case MCSymbolRefExpr::VK_TLSGD: | |||
1333 | Variant = MCSymbolRefExpr::VK_PPC_TLSGD; | |||
1334 | break; | |||
1335 | case MCSymbolRefExpr::VK_TLSLD: | |||
1336 | Variant = MCSymbolRefExpr::VK_PPC_TLSLD; | |||
1337 | break; | |||
1338 | default: | |||
1339 | return E; | |||
1340 | } | |||
1341 | return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context); | |||
1342 | } | |||
1343 | ||||
1344 | case MCExpr::Unary: { | |||
1345 | const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); | |||
1346 | const MCExpr *Sub = FixupVariantKind(UE->getSubExpr()); | |||
1347 | if (Sub == UE->getSubExpr()) | |||
1348 | return E; | |||
1349 | return MCUnaryExpr::create(UE->getOpcode(), Sub, Context); | |||
1350 | } | |||
1351 | ||||
1352 | case MCExpr::Binary: { | |||
1353 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); | |||
1354 | const MCExpr *LHS = FixupVariantKind(BE->getLHS()); | |||
1355 | const MCExpr *RHS = FixupVariantKind(BE->getRHS()); | |||
1356 | if (LHS == BE->getLHS() && RHS == BE->getRHS()) | |||
1357 | return E; | |||
1358 | return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context); | |||
1359 | } | |||
1360 | } | |||
1361 | ||||
1362 | llvm_unreachable("Invalid expression kind!")::llvm::llvm_unreachable_internal("Invalid expression kind!", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 1362); | |||
1363 | } | |||
1364 | ||||
1365 | /// ParseExpression. This differs from the default "parseExpression" in that | |||
1366 | /// it handles modifiers. | |||
1367 | bool PPCAsmParser:: | |||
1368 | ParseExpression(const MCExpr *&EVal) { | |||
1369 | ||||
1370 | if (isDarwin()) | |||
1371 | return ParseDarwinExpression(EVal); | |||
1372 | ||||
1373 | // (ELF Platforms) | |||
1374 | // Handle \code @l/@ha \endcode | |||
1375 | if (getParser().parseExpression(EVal)) | |||
1376 | return true; | |||
1377 | ||||
1378 | EVal = FixupVariantKind(EVal); | |||
1379 | ||||
1380 | PPCMCExpr::VariantKind Variant; | |||
1381 | const MCExpr *E = ExtractModifierFromExpr(EVal, Variant); | |||
1382 | if (E) | |||
1383 | EVal = PPCMCExpr::create(Variant, E, false, getParser().getContext()); | |||
1384 | ||||
1385 | return false; | |||
1386 | } | |||
1387 | ||||
1388 | /// ParseDarwinExpression. (MachO Platforms) | |||
1389 | /// This differs from the default "parseExpression" in that it handles detection | |||
1390 | /// of the \code hi16(), ha16() and lo16() \endcode modifiers. At present, | |||
1391 | /// parseExpression() doesn't recognise the modifiers when in the Darwin/MachO | |||
1392 | /// syntax form so it is done here. TODO: Determine if there is merit in | |||
1393 | /// arranging for this to be done at a higher level. | |||
1394 | bool PPCAsmParser:: | |||
1395 | ParseDarwinExpression(const MCExpr *&EVal) { | |||
1396 | MCAsmParser &Parser = getParser(); | |||
1397 | PPCMCExpr::VariantKind Variant = PPCMCExpr::VK_PPC_None; | |||
1398 | switch (getLexer().getKind()) { | |||
1399 | default: | |||
1400 | break; | |||
1401 | case AsmToken::Identifier: | |||
1402 | // Compiler-generated Darwin identifiers begin with L,l,_ or "; thus | |||
1403 | // something starting with any other char should be part of the | |||
1404 | // asm syntax. If handwritten asm includes an identifier like lo16, | |||
1405 | // then all bets are off - but no-one would do that, right? | |||
1406 | StringRef poss = Parser.getTok().getString(); | |||
1407 | if (poss.equals_lower("lo16")) { | |||
1408 | Variant = PPCMCExpr::VK_PPC_LO; | |||
1409 | } else if (poss.equals_lower("hi16")) { | |||
1410 | Variant = PPCMCExpr::VK_PPC_HI; | |||
1411 | } else if (poss.equals_lower("ha16")) { | |||
1412 | Variant = PPCMCExpr::VK_PPC_HA; | |||
1413 | } | |||
1414 | if (Variant != PPCMCExpr::VK_PPC_None) { | |||
1415 | Parser.Lex(); // Eat the xx16 | |||
1416 | if (getLexer().isNot(AsmToken::LParen)) | |||
1417 | return Error(Parser.getTok().getLoc(), "expected '('"); | |||
1418 | Parser.Lex(); // Eat the '(' | |||
1419 | } | |||
1420 | break; | |||
1421 | } | |||
1422 | ||||
1423 | if (getParser().parseExpression(EVal)) | |||
1424 | return true; | |||
1425 | ||||
1426 | if (Variant != PPCMCExpr::VK_PPC_None) { | |||
1427 | if (getLexer().isNot(AsmToken::RParen)) | |||
1428 | return Error(Parser.getTok().getLoc(), "expected ')'"); | |||
1429 | Parser.Lex(); // Eat the ')' | |||
1430 | EVal = PPCMCExpr::create(Variant, EVal, false, getParser().getContext()); | |||
1431 | } | |||
1432 | return false; | |||
1433 | } | |||
1434 | ||||
1435 | /// ParseOperand | |||
1436 | /// This handles registers in the form 'NN', '%rNN' for ELF platforms and | |||
1437 | /// rNN for MachO. | |||
1438 | bool PPCAsmParser::ParseOperand(OperandVector &Operands) { | |||
1439 | MCAsmParser &Parser = getParser(); | |||
1440 | SMLoc S = Parser.getTok().getLoc(); | |||
1441 | SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); | |||
1442 | const MCExpr *EVal; | |||
1443 | ||||
1444 | // Attempt to parse the next token as an immediate | |||
1445 | switch (getLexer().getKind()) { | |||
1446 | // Special handling for register names. These are interpreted | |||
1447 | // as immediates corresponding to the register number. | |||
1448 | case AsmToken::Percent: | |||
1449 | Parser.Lex(); // Eat the '%'. | |||
1450 | unsigned RegNo; | |||
1451 | int64_t IntVal; | |||
1452 | if (MatchRegisterName(RegNo, IntVal)) | |||
1453 | return Error(S, "invalid register name"); | |||
1454 | ||||
1455 | Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64())); | |||
1456 | return false; | |||
1457 | ||||
1458 | case AsmToken::Identifier: | |||
1459 | case AsmToken::LParen: | |||
1460 | case AsmToken::Plus: | |||
1461 | case AsmToken::Minus: | |||
1462 | case AsmToken::Integer: | |||
1463 | case AsmToken::Dot: | |||
1464 | case AsmToken::Dollar: | |||
1465 | case AsmToken::Exclaim: | |||
1466 | case AsmToken::Tilde: | |||
1467 | // Note that non-register-name identifiers from the compiler will begin | |||
1468 | // with '_', 'L'/'l' or '"'. Of course, handwritten asm could include | |||
1469 | // identifiers like r31foo - so we fall through in the event that parsing | |||
1470 | // a register name fails. | |||
1471 | if (isDarwin()) { | |||
1472 | unsigned RegNo; | |||
1473 | int64_t IntVal; | |||
1474 | if (!MatchRegisterName(RegNo, IntVal)) { | |||
1475 | Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64())); | |||
1476 | return false; | |||
1477 | } | |||
1478 | } | |||
1479 | // All other expressions | |||
1480 | ||||
1481 | if (!ParseExpression(EVal)) | |||
1482 | break; | |||
1483 | // Fall-through | |||
1484 | LLVM_FALLTHROUGH[[clang::fallthrough]]; | |||
1485 | default: | |||
1486 | return Error(S, "unknown operand"); | |||
1487 | } | |||
1488 | ||||
1489 | // Push the parsed operand into the list of operands | |||
1490 | Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64())); | |||
| ||||
1491 | ||||
1492 | // Check whether this is a TLS call expression | |||
1493 | bool TLSCall = false; | |||
1494 | if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) | |||
1495 | TLSCall = Ref->getSymbol().getName() == "__tls_get_addr"; | |||
1496 | ||||
1497 | if (TLSCall && getLexer().is(AsmToken::LParen)) { | |||
1498 | const MCExpr *TLSSym; | |||
1499 | ||||
1500 | Parser.Lex(); // Eat the '('. | |||
1501 | S = Parser.getTok().getLoc(); | |||
1502 | if (ParseExpression(TLSSym)) | |||
1503 | return Error(S, "invalid TLS call expression"); | |||
1504 | if (getLexer().isNot(AsmToken::RParen)) | |||
1505 | return Error(Parser.getTok().getLoc(), "missing ')'"); | |||
1506 | E = Parser.getTok().getLoc(); | |||
1507 | Parser.Lex(); // Eat the ')'. | |||
1508 | ||||
1509 | Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64())); | |||
1510 | } | |||
1511 | ||||
1512 | // Otherwise, check for D-form memory operands | |||
1513 | if (!TLSCall && getLexer().is(AsmToken::LParen)) { | |||
1514 | Parser.Lex(); // Eat the '('. | |||
1515 | S = Parser.getTok().getLoc(); | |||
1516 | ||||
1517 | int64_t IntVal; | |||
1518 | switch (getLexer().getKind()) { | |||
1519 | case AsmToken::Percent: | |||
1520 | Parser.Lex(); // Eat the '%'. | |||
1521 | unsigned RegNo; | |||
1522 | if (MatchRegisterName(RegNo, IntVal)) | |||
1523 | return Error(S, "invalid register name"); | |||
1524 | break; | |||
1525 | ||||
1526 | case AsmToken::Integer: | |||
1527 | if (isDarwin()) | |||
1528 | return Error(S, "unexpected integer value"); | |||
1529 | else if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 || | |||
1530 | IntVal > 31) | |||
1531 | return Error(S, "invalid register number"); | |||
1532 | break; | |||
1533 | case AsmToken::Identifier: | |||
1534 | if (isDarwin()) { | |||
1535 | unsigned RegNo; | |||
1536 | if (!MatchRegisterName(RegNo, IntVal)) { | |||
1537 | break; | |||
1538 | } | |||
1539 | } | |||
1540 | LLVM_FALLTHROUGH[[clang::fallthrough]]; | |||
1541 | ||||
1542 | default: | |||
1543 | return Error(S, "invalid memory operand"); | |||
1544 | } | |||
1545 | ||||
1546 | E = Parser.getTok().getLoc(); | |||
1547 | if (parseToken(AsmToken::RParen, "missing ')'")) | |||
1548 | return true; | |||
1549 | Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64())); | |||
1550 | } | |||
1551 | ||||
1552 | return false; | |||
1553 | } | |||
1554 | ||||
1555 | /// Parse an instruction mnemonic followed by its operands. | |||
1556 | bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, | |||
1557 | SMLoc NameLoc, OperandVector &Operands) { | |||
1558 | // The first operand is the token for the instruction name. | |||
1559 | // If the next character is a '+' or '-', we need to add it to the | |||
1560 | // instruction name, to match what TableGen is doing. | |||
1561 | std::string NewOpcode; | |||
1562 | if (parseOptionalToken(AsmToken::Plus)) { | |||
| ||||
1563 | NewOpcode = Name; | |||
1564 | NewOpcode += '+'; | |||
1565 | Name = NewOpcode; | |||
1566 | } | |||
1567 | if (parseOptionalToken(AsmToken::Minus)) { | |||
1568 | NewOpcode = Name; | |||
1569 | NewOpcode += '-'; | |||
1570 | Name = NewOpcode; | |||
1571 | } | |||
1572 | // If the instruction ends in a '.', we need to create a separate | |||
1573 | // token for it, to match what TableGen is doing. | |||
1574 | size_t Dot = Name.find('.'); | |||
1575 | StringRef Mnemonic = Name.slice(0, Dot); | |||
1576 | if (!NewOpcode.empty()) // Underlying memory for Name is volatile. | |||
1577 | Operands.push_back( | |||
1578 | PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64())); | |||
1579 | else | |||
1580 | Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); | |||
1581 | if (Dot != StringRef::npos) { | |||
1582 | SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); | |||
1583 | StringRef DotStr = Name.slice(Dot, StringRef::npos); | |||
1584 | if (!NewOpcode.empty()) // Underlying memory for Name is volatile. | |||
1585 | Operands.push_back( | |||
1586 | PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64())); | |||
1587 | else | |||
1588 | Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); | |||
1589 | } | |||
1590 | ||||
1591 | // If there are no more operands then finish | |||
1592 | if (parseOptionalToken(AsmToken::EndOfStatement)) | |||
1593 | return false; | |||
1594 | ||||
1595 | // Parse the first operand | |||
1596 | if (ParseOperand(Operands)) | |||
1597 | return true; | |||
1598 | ||||
1599 | while (!parseOptionalToken(AsmToken::EndOfStatement)) { | |||
1600 | if (parseToken(AsmToken::Comma) || ParseOperand(Operands)) | |||
1601 | return true; | |||
1602 | } | |||
1603 | ||||
1604 | // We'll now deal with an unfortunate special case: the syntax for the dcbt | |||
1605 | // and dcbtst instructions differs for server vs. embedded cores. | |||
1606 | // The syntax for dcbt is: | |||
1607 | // dcbt ra, rb, th [server] | |||
1608 | // dcbt th, ra, rb [embedded] | |||
1609 | // where th can be omitted when it is 0. dcbtst is the same. We take the | |||
1610 | // server form to be the default, so swap the operands if we're parsing for | |||
1611 | // an embedded core (they'll be swapped again upon printing). | |||
1612 | if (getSTI().getFeatureBits()[PPC::FeatureBookE] && | |||
1613 | Operands.size() == 4 && | |||
1614 | (Name == "dcbt" || Name == "dcbtst")) { | |||
1615 | std::swap(Operands[1], Operands[3]); | |||
1616 | std::swap(Operands[2], Operands[1]); | |||
1617 | } | |||
1618 | ||||
1619 | return false; | |||
1620 | } | |||
1621 | ||||
1622 | /// ParseDirective parses the PPC specific directives | |||
1623 | bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) { | |||
1624 | StringRef IDVal = DirectiveID.getIdentifier(); | |||
1625 | if (isDarwin()) { | |||
1626 | if (IDVal == ".machine") | |||
1627 | ParseDarwinDirectiveMachine(DirectiveID.getLoc()); | |||
1628 | else | |||
1629 | return true; | |||
1630 | } else if (IDVal == ".word") | |||
1631 | ParseDirectiveWord(2, DirectiveID); | |||
1632 | else if (IDVal == ".llong") | |||
1633 | ParseDirectiveWord(8, DirectiveID); | |||
1634 | else if (IDVal == ".tc") | |||
1635 | ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID); | |||
1636 | else if (IDVal == ".machine") | |||
1637 | ParseDirectiveMachine(DirectiveID.getLoc()); | |||
1638 | else if (IDVal == ".abiversion") | |||
1639 | ParseDirectiveAbiVersion(DirectiveID.getLoc()); | |||
1640 | else if (IDVal == ".localentry") | |||
1641 | ParseDirectiveLocalEntry(DirectiveID.getLoc()); | |||
1642 | else | |||
1643 | return true; | |||
1644 | return false; | |||
1645 | } | |||
1646 | ||||
1647 | /// ParseDirectiveWord | |||
1648 | /// ::= .word [ expression (, expression)* ] | |||
1649 | bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) { | |||
1650 | auto parseOp = [&]() -> bool { | |||
1651 | const MCExpr *Value; | |||
1652 | SMLoc ExprLoc = getParser().getTok().getLoc(); | |||
1653 | if (getParser().parseExpression(Value)) | |||
1654 | return true; | |||
1655 | if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) { | |||
1656 | assert(Size <= 8 && "Invalid size")((Size <= 8 && "Invalid size") ? static_cast<void > (0) : __assert_fail ("Size <= 8 && \"Invalid size\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp" , 1656, __PRETTY_FUNCTION__)); | |||
1657 | uint64_t IntValue = MCE->getValue(); | |||
1658 | if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) | |||
1659 | return Error(ExprLoc, "literal value out of range for '" + | |||
1660 | ID.getIdentifier() + "' directive"); | |||
1661 | getStreamer().EmitIntValue(IntValue, Size); | |||
1662 | } else | |||
1663 | getStreamer().EmitValue(Value, Size, ExprLoc); | |||
1664 | return false; | |||
1665 | }; | |||
1666 | ||||
1667 | if (parseMany(parseOp)) | |||
1668 | return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive"); | |||
1669 | return false; | |||
1670 | } | |||
1671 | ||||
1672 | /// ParseDirectiveTC | |||
1673 | /// ::= .tc [ symbol (, expression)* ] | |||
1674 | bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) { | |||
1675 | MCAsmParser &Parser = getParser(); | |||
1676 | // Skip TC symbol, which is only used with XCOFF. | |||
1677 | while (getLexer().isNot(AsmToken::EndOfStatement) | |||
1678 | && getLexer().isNot(AsmToken::Comma)) | |||
1679 | Parser.Lex(); | |||
1680 | if (parseToken(AsmToken::Comma)) | |||
1681 | return addErrorSuffix(" in '.tc' directive"); | |||
1682 | ||||
1683 | // Align to word size. | |||
1684 | getParser().getStreamer().EmitValueToAlignment(Size); | |||
1685 | ||||
1686 | // Emit expressions. | |||
1687 | return ParseDirectiveWord(Size, ID); | |||
1688 | } | |||
1689 | ||||
1690 | /// ParseDirectiveMachine (ELF platforms) | |||
1691 | /// ::= .machine [ cpu | "push" | "pop" ] | |||
1692 | bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) { | |||
1693 | MCAsmParser &Parser = getParser(); | |||
1694 | if (Parser.getTok().isNot(AsmToken::Identifier) && | |||
1695 | Parser.getTok().isNot(AsmToken::String)) | |||
1696 | return Error(L, "unexpected token in '.machine' directive"); | |||
1697 | ||||
1698 | StringRef CPU = Parser.getTok().getIdentifier(); | |||
1699 | ||||
1700 | // FIXME: Right now, the parser always allows any available | |||
1701 | // instruction, so the .machine directive is not useful. | |||
1702 | // Implement ".machine any" (by doing nothing) for the benefit | |||
1703 | // of existing assembler code. Likewise, we can then implement | |||
1704 | // ".machine push" and ".machine pop" as no-op. | |||
1705 | if (CPU != "any" && CPU != "push" && CPU != "pop") | |||
1706 | return TokError("unrecognized machine type"); | |||
1707 | ||||
1708 | Parser.Lex(); | |||
1709 | ||||
1710 | if (parseToken(AsmToken::EndOfStatement)) | |||
1711 | return addErrorSuffix(" in '.machine' directive"); | |||
1712 | ||||
1713 | PPCTargetStreamer &TStreamer = | |||
1714 | *static_cast<PPCTargetStreamer *>( | |||
1715 | getParser().getStreamer().getTargetStreamer()); | |||
1716 | TStreamer.emitMachine(CPU); | |||
1717 | ||||
1718 | return false; | |||
1719 | } | |||
1720 | ||||
1721 | /// ParseDarwinDirectiveMachine (Mach-o platforms) | |||
1722 | /// ::= .machine cpu-identifier | |||
1723 | bool PPCAsmParser::ParseDarwinDirectiveMachine(SMLoc L) { | |||
1724 | MCAsmParser &Parser = getParser(); | |||
1725 | if (Parser.getTok().isNot(AsmToken::Identifier) && | |||
1726 | Parser.getTok().isNot(AsmToken::String)) | |||
1727 | return Error(L, "unexpected token in directive"); | |||
1728 | ||||
1729 | StringRef CPU = Parser.getTok().getIdentifier(); | |||
1730 | Parser.Lex(); | |||
1731 | ||||
1732 | // FIXME: this is only the 'default' set of cpu variants. | |||
1733 | // However we don't act on this information at present, this is simply | |||
1734 | // allowing parsing to proceed with minimal sanity checking. | |||
1735 | if (check(CPU != "ppc7400" && CPU != "ppc" && CPU != "ppc64", L, | |||
1736 | "unrecognized cpu type") || | |||
1737 | check(isPPC64() && (CPU == "ppc7400" || CPU == "ppc"), L, | |||
1738 | "wrong cpu type specified for 64bit") || | |||
1739 | check(!isPPC64() && CPU == "ppc64", L, | |||
1740 | "wrong cpu type specified for 32bit") || | |||
1741 | parseToken(AsmToken::EndOfStatement)) | |||
1742 | return addErrorSuffix(" in '.machine' directive"); | |||
1743 | return false; | |||
1744 | } | |||
1745 | ||||
1746 | /// ParseDirectiveAbiVersion | |||
1747 | /// ::= .abiversion constant-expression | |||
1748 | bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) { | |||
1749 | int64_t AbiVersion; | |||
1750 | if (check(getParser().parseAbsoluteExpression(AbiVersion), L, | |||
1751 | "expected constant expression") || | |||
1752 | parseToken(AsmToken::EndOfStatement)) | |||
1753 | return addErrorSuffix(" in '.abiversion' directive"); | |||
1754 | ||||
1755 | PPCTargetStreamer &TStreamer = | |||
1756 | *static_cast<PPCTargetStreamer *>( | |||
1757 | getParser().getStreamer().getTargetStreamer()); | |||
1758 | TStreamer.emitAbiVersion(AbiVersion); | |||
1759 | ||||
1760 | return false; | |||
1761 | } | |||
1762 | ||||
1763 | /// ParseDirectiveLocalEntry | |||
1764 | /// ::= .localentry symbol, expression | |||
1765 | bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) { | |||
1766 | StringRef Name; | |||
1767 | if (getParser().parseIdentifier(Name)) | |||
1768 | return Error(L, "expected identifier in '.localentry' directive"); | |||
1769 | ||||
1770 | MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name)); | |||
1771 | const MCExpr *Expr; | |||
1772 | ||||
1773 | if (parseToken(AsmToken::Comma) || | |||
1774 | check(getParser().parseExpression(Expr), L, "expected expression") || | |||
1775 | parseToken(AsmToken::EndOfStatement)) | |||
1776 | return addErrorSuffix(" in '.localentry' directive"); | |||
1777 | ||||
1778 | PPCTargetStreamer &TStreamer = | |||
1779 | *static_cast<PPCTargetStreamer *>( | |||
1780 | getParser().getStreamer().getTargetStreamer()); | |||
1781 | TStreamer.emitLocalEntry(Sym, Expr); | |||
1782 | ||||
1783 | return false; | |||
1784 | } | |||
1785 | ||||
1786 | ||||
1787 | ||||
1788 | /// Force static initialization. | |||
1789 | extern "C" void LLVMInitializePowerPCAsmParser() { | |||
1790 | RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target()); | |||
1791 | RegisterMCAsmParser<PPCAsmParser> B(getThePPC64Target()); | |||
1792 | RegisterMCAsmParser<PPCAsmParser> C(getThePPC64LETarget()); | |||
1793 | } | |||
1794 | ||||
1795 | #define GET_REGISTER_MATCHER | |||
1796 | #define GET_MATCHER_IMPLEMENTATION | |||
1797 | #define GET_MNEMONIC_SPELL_CHECKER | |||
1798 | #include "PPCGenAsmMatcher.inc" | |||
1799 | ||||
1800 | // Define this matcher function after the auto-generated include so we | |||
1801 | // have the match class enum definitions. | |||
1802 | unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, | |||
1803 | unsigned Kind) { | |||
1804 | // If the kind is a token for a literal immediate, check if our asm | |||
1805 | // operand matches. This is for InstAliases which have a fixed-value | |||
1806 | // immediate in the syntax. | |||
1807 | int64_t ImmVal; | |||
1808 | switch (Kind) { | |||
1809 | case MCK_0: ImmVal = 0; break; | |||
1810 | case MCK_1: ImmVal = 1; break; | |||
1811 | case MCK_2: ImmVal = 2; break; | |||
1812 | case MCK_3: ImmVal = 3; break; | |||
1813 | case MCK_4: ImmVal = 4; break; | |||
1814 | case MCK_5: ImmVal = 5; break; | |||
1815 | case MCK_6: ImmVal = 6; break; | |||
1816 | case MCK_7: ImmVal = 7; break; | |||
1817 | default: return Match_InvalidOperand; | |||
1818 | } | |||
1819 | ||||
1820 | PPCOperand &Op = static_cast<PPCOperand &>(AsmOp); | |||
1821 | if (Op.isImm() && Op.getImm() == ImmVal) | |||
1822 | return Match_Success; | |||
1823 | ||||
1824 | return Match_InvalidOperand; | |||
1825 | } | |||
1826 | ||||
1827 | const MCExpr * | |||
1828 | PPCAsmParser::applyModifierToExpr(const MCExpr *E, | |||
1829 | MCSymbolRefExpr::VariantKind Variant, | |||
1830 | MCContext &Ctx) { | |||
1831 | switch (Variant) { | |||
1832 | case MCSymbolRefExpr::VK_PPC_LO: | |||
1833 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, false, Ctx); | |||
1834 | case MCSymbolRefExpr::VK_PPC_HI: | |||
1835 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, false, Ctx); | |||
1836 | case MCSymbolRefExpr::VK_PPC_HA: | |||
1837 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, false, Ctx); | |||
1838 | case MCSymbolRefExpr::VK_PPC_HIGH: | |||
1839 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, false, Ctx); | |||
1840 | case MCSymbolRefExpr::VK_PPC_HIGHA: | |||
1841 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, false, Ctx); | |||
1842 | case MCSymbolRefExpr::VK_PPC_HIGHER: | |||
1843 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, false, Ctx); | |||
1844 | case MCSymbolRefExpr::VK_PPC_HIGHERA: | |||
1845 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, false, Ctx); | |||
1846 | case MCSymbolRefExpr::VK_PPC_HIGHEST: | |||
1847 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, false, Ctx); | |||
1848 | case MCSymbolRefExpr::VK_PPC_HIGHESTA: | |||
1849 | return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, false, Ctx); | |||
1850 | default: | |||
1851 | return nullptr; | |||
1852 | } | |||
1853 | } |