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