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