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/MC/TargetRegistry.h" |
27 | #include "llvm/Support/SourceMgr.h" |
28 | #include "llvm/Support/raw_ostream.h" |
29 | |
30 | using namespace llvm; |
31 | |
32 | DEFINE_PPC_REGCLASSES |
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>(Val: E)->getValue(); |
45 | return Res < 0 ? -1 : Res; |
46 | } |
47 | |
48 | case MCExpr::SymbolRef: { |
49 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Val: 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>(Val: E); |
75 | int64_t LHSVal = EvaluateCRExpr(E: BE->getLHS()); |
76 | int64_t RHSVal = EvaluateCRExpr(E: 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!" ); |
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(MCRegister &RegNo, int64_t &IntVal); |
107 | |
108 | bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; |
109 | ParseStatus tryParseRegister(MCRegister &Reg, 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 | bool ParseGNUAttribute(SMLoc L); |
125 | |
126 | bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, |
127 | OperandVector &Operands, MCStreamer &Out, |
128 | uint64_t &ErrorInfo, |
129 | bool MatchingInlineAsm) override; |
130 | |
131 | void ProcessInstruction(MCInst &Inst, const OperandVector &Ops); |
132 | |
133 | /// @name Auto-generated Match Functions |
134 | /// { |
135 | |
136 | #define |
137 | #include "PPCGenAsmMatcher.inc" |
138 | |
139 | /// } |
140 | |
141 | |
142 | public: |
143 | PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &, |
144 | const MCInstrInfo &MII, const MCTargetOptions &Options) |
145 | : MCTargetAsmParser(Options, STI, MII) { |
146 | // Check for 64-bit vs. 32-bit pointer mode. |
147 | const Triple &TheTriple = STI.getTargetTriple(); |
148 | IsPPC64 = TheTriple.isPPC64(); |
149 | // Initialize the set of available features. |
150 | setAvailableFeatures(ComputeAvailableFeatures(FB: STI.getFeatureBits())); |
151 | } |
152 | |
153 | bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, |
154 | SMLoc NameLoc, OperandVector &Operands) override; |
155 | |
156 | bool ParseDirective(AsmToken DirectiveID) override; |
157 | |
158 | unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, |
159 | unsigned Kind) override; |
160 | |
161 | const MCExpr *applyModifierToExpr(const MCExpr *E, |
162 | MCSymbolRefExpr::VariantKind, |
163 | MCContext &Ctx) override; |
164 | }; |
165 | |
166 | /// PPCOperand - Instances of this class represent a parsed PowerPC machine |
167 | /// instruction. |
168 | struct PPCOperand : public MCParsedAsmOperand { |
169 | enum KindTy { |
170 | Token, |
171 | Immediate, |
172 | ContextImmediate, |
173 | Expression, |
174 | TLSRegister |
175 | } Kind; |
176 | |
177 | SMLoc StartLoc, EndLoc; |
178 | bool IsPPC64; |
179 | |
180 | struct TokOp { |
181 | const char *Data; |
182 | unsigned Length; |
183 | }; |
184 | |
185 | struct ImmOp { |
186 | int64_t Val; |
187 | }; |
188 | |
189 | struct ExprOp { |
190 | const MCExpr *Val; |
191 | int64_t CRVal; // Cached result of EvaluateCRExpr(Val) |
192 | }; |
193 | |
194 | struct TLSRegOp { |
195 | const MCSymbolRefExpr *Sym; |
196 | }; |
197 | |
198 | union { |
199 | struct TokOp Tok; |
200 | struct ImmOp Imm; |
201 | struct ExprOp Expr; |
202 | struct TLSRegOp TLSReg; |
203 | }; |
204 | |
205 | PPCOperand(KindTy K) : Kind(K) {} |
206 | |
207 | public: |
208 | PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() { |
209 | Kind = o.Kind; |
210 | StartLoc = o.StartLoc; |
211 | EndLoc = o.EndLoc; |
212 | IsPPC64 = o.IsPPC64; |
213 | switch (Kind) { |
214 | case Token: |
215 | Tok = o.Tok; |
216 | break; |
217 | case Immediate: |
218 | case ContextImmediate: |
219 | Imm = o.Imm; |
220 | break; |
221 | case Expression: |
222 | Expr = o.Expr; |
223 | break; |
224 | case TLSRegister: |
225 | TLSReg = o.TLSReg; |
226 | break; |
227 | } |
228 | } |
229 | |
230 | // Disable use of sized deallocation due to overallocation of PPCOperand |
231 | // objects in CreateTokenWithStringCopy. |
232 | void operator delete(void *p) { ::operator delete(p); } |
233 | |
234 | /// getStartLoc - Get the location of the first token of this operand. |
235 | SMLoc getStartLoc() const override { return StartLoc; } |
236 | |
237 | /// getEndLoc - Get the location of the last token of this operand. |
238 | SMLoc getEndLoc() const override { return EndLoc; } |
239 | |
240 | /// getLocRange - Get the range between the first and last token of this |
241 | /// operand. |
242 | SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } |
243 | |
244 | /// isPPC64 - True if this operand is for an instruction in 64-bit mode. |
245 | bool isPPC64() const { return IsPPC64; } |
246 | |
247 | int64_t getImm() const { |
248 | assert(Kind == Immediate && "Invalid access!" ); |
249 | return Imm.Val; |
250 | } |
251 | int64_t getImmS16Context() const { |
252 | assert((Kind == Immediate || Kind == ContextImmediate) && |
253 | "Invalid access!" ); |
254 | if (Kind == Immediate) |
255 | return Imm.Val; |
256 | return static_cast<int16_t>(Imm.Val); |
257 | } |
258 | int64_t getImmU16Context() const { |
259 | assert((Kind == Immediate || Kind == ContextImmediate) && |
260 | "Invalid access!" ); |
261 | return Imm.Val; |
262 | } |
263 | |
264 | const MCExpr *getExpr() const { |
265 | assert(Kind == Expression && "Invalid access!" ); |
266 | return Expr.Val; |
267 | } |
268 | |
269 | int64_t getExprCRVal() const { |
270 | assert(Kind == Expression && "Invalid access!" ); |
271 | return Expr.CRVal; |
272 | } |
273 | |
274 | const MCExpr *getTLSReg() const { |
275 | assert(Kind == TLSRegister && "Invalid access!" ); |
276 | return TLSReg.Sym; |
277 | } |
278 | |
279 | MCRegister getReg() const override { llvm_unreachable("Not implemented" ); } |
280 | |
281 | unsigned getRegNum() const { |
282 | assert(isRegNumber() && "Invalid access!" ); |
283 | return (unsigned)Imm.Val; |
284 | } |
285 | |
286 | unsigned getFpReg() const { |
287 | assert(isEvenRegNumber() && "Invalid access!" ); |
288 | return (unsigned)(Imm.Val >> 1); |
289 | } |
290 | |
291 | unsigned getVSReg() const { |
292 | assert(isVSRegNumber() && "Invalid access!" ); |
293 | return (unsigned) Imm.Val; |
294 | } |
295 | |
296 | unsigned getACCReg() const { |
297 | assert(isACCRegNumber() && "Invalid access!" ); |
298 | return (unsigned) Imm.Val; |
299 | } |
300 | |
301 | unsigned getDMRROWReg() const { |
302 | assert(isDMRROWRegNumber() && "Invalid access!" ); |
303 | return (unsigned)Imm.Val; |
304 | } |
305 | |
306 | unsigned getDMRROWpReg() const { |
307 | assert(isDMRROWpRegNumber() && "Invalid access!" ); |
308 | return (unsigned)Imm.Val; |
309 | } |
310 | |
311 | unsigned getDMRReg() const { |
312 | assert(isDMRRegNumber() && "Invalid access!" ); |
313 | return (unsigned)Imm.Val; |
314 | } |
315 | |
316 | unsigned getDMRpReg() const { |
317 | assert(isDMRpRegNumber() && "Invalid access!" ); |
318 | return (unsigned)Imm.Val; |
319 | } |
320 | |
321 | unsigned getVSRpEvenReg() const { |
322 | assert(isVSRpEvenRegNumber() && "Invalid access!" ); |
323 | return (unsigned) Imm.Val >> 1; |
324 | } |
325 | |
326 | unsigned getG8pReg() const { |
327 | assert(isEvenRegNumber() && "Invalid access!" ); |
328 | return (unsigned)Imm.Val; |
329 | } |
330 | |
331 | unsigned getCCReg() const { |
332 | assert(isCCRegNumber() && "Invalid access!" ); |
333 | return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal); |
334 | } |
335 | |
336 | unsigned getCRBit() const { |
337 | assert(isCRBitNumber() && "Invalid access!" ); |
338 | return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal); |
339 | } |
340 | |
341 | unsigned getCRBitMask() const { |
342 | assert(isCRBitMask() && "Invalid access!" ); |
343 | return 7 - llvm::countr_zero<uint64_t>(Val: Imm.Val); |
344 | } |
345 | |
346 | bool isToken() const override { return Kind == Token; } |
347 | bool isImm() const override { |
348 | return Kind == Immediate || Kind == Expression; |
349 | } |
350 | bool isU1Imm() const { return Kind == Immediate && isUInt<1>(x: getImm()); } |
351 | bool isU2Imm() const { return Kind == Immediate && isUInt<2>(x: getImm()); } |
352 | bool isU3Imm() const { return Kind == Immediate && isUInt<3>(x: getImm()); } |
353 | bool isU4Imm() const { return Kind == Immediate && isUInt<4>(x: getImm()); } |
354 | bool isU5Imm() const { return Kind == Immediate && isUInt<5>(x: getImm()); } |
355 | bool isS5Imm() const { return Kind == Immediate && isInt<5>(x: getImm()); } |
356 | bool isU6Imm() const { return Kind == Immediate && isUInt<6>(x: getImm()); } |
357 | bool isU6ImmX2() const { return Kind == Immediate && |
358 | isUInt<6>(x: getImm()) && |
359 | (getImm() & 1) == 0; } |
360 | bool isU7Imm() const { return Kind == Immediate && isUInt<7>(x: getImm()); } |
361 | bool isU7ImmX4() const { return Kind == Immediate && |
362 | isUInt<7>(x: getImm()) && |
363 | (getImm() & 3) == 0; } |
364 | bool isU8Imm() const { return Kind == Immediate && isUInt<8>(x: getImm()); } |
365 | bool isU8ImmX8() const { return Kind == Immediate && |
366 | isUInt<8>(x: getImm()) && |
367 | (getImm() & 7) == 0; } |
368 | |
369 | bool isU10Imm() const { return Kind == Immediate && isUInt<10>(x: getImm()); } |
370 | bool isU12Imm() const { return Kind == Immediate && isUInt<12>(x: getImm()); } |
371 | bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, Multiple: 1); } |
372 | bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, Multiple: 1); } |
373 | bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, Multiple: 4); } |
374 | bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, Multiple: 16); } |
375 | bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, Multiple: 1); } |
376 | |
377 | bool isHashImmX8() const { |
378 | // The Hash Imm form is used for instructions that check or store a hash. |
379 | // These instructions have a small immediate range that spans between |
380 | // -8 and -512. |
381 | return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 && |
382 | (getImm() & 7) == 0); |
383 | } |
384 | |
385 | bool isS34ImmX16() const { |
386 | return Kind == Expression || |
387 | (Kind == Immediate && isInt<34>(x: getImm()) && (getImm() & 15) == 0); |
388 | } |
389 | bool isS34Imm() const { |
390 | // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit |
391 | // ContextImmediate is needed. |
392 | return Kind == Expression || (Kind == Immediate && isInt<34>(x: getImm())); |
393 | } |
394 | |
395 | bool isTLSReg() const { return Kind == TLSRegister; } |
396 | bool isDirectBr() const { |
397 | if (Kind == Expression) |
398 | return true; |
399 | if (Kind != Immediate) |
400 | return false; |
401 | // Operand must be 64-bit aligned, signed 27-bit immediate. |
402 | if ((getImm() & 3) != 0) |
403 | return false; |
404 | if (isInt<26>(x: getImm())) |
405 | return true; |
406 | if (!IsPPC64) { |
407 | // In 32-bit mode, large 32-bit quantities wrap around. |
408 | if (isUInt<32>(x: getImm()) && isInt<26>(x: static_cast<int32_t>(getImm()))) |
409 | return true; |
410 | } |
411 | return false; |
412 | } |
413 | bool isCondBr() const { return Kind == Expression || |
414 | (Kind == Immediate && isInt<16>(x: getImm()) && |
415 | (getImm() & 3) == 0); } |
416 | bool isImmZero() const { return Kind == Immediate && getImm() == 0; } |
417 | bool isRegNumber() const { return Kind == Immediate && isUInt<5>(x: getImm()); } |
418 | bool isACCRegNumber() const { |
419 | return Kind == Immediate && isUInt<3>(x: getImm()); |
420 | } |
421 | bool isDMRROWRegNumber() const { |
422 | return Kind == Immediate && isUInt<6>(x: getImm()); |
423 | } |
424 | bool isDMRROWpRegNumber() const { |
425 | return Kind == Immediate && isUInt<5>(x: getImm()); |
426 | } |
427 | bool isDMRRegNumber() const { |
428 | return Kind == Immediate && isUInt<3>(x: getImm()); |
429 | } |
430 | bool isDMRpRegNumber() const { |
431 | return Kind == Immediate && isUInt<2>(x: getImm()); |
432 | } |
433 | bool isVSRpEvenRegNumber() const { |
434 | return Kind == Immediate && isUInt<6>(x: getImm()) && ((getImm() & 1) == 0); |
435 | } |
436 | bool isVSRegNumber() const { |
437 | return Kind == Immediate && isUInt<6>(x: getImm()); |
438 | } |
439 | bool isCCRegNumber() const { return (Kind == Expression |
440 | && isUInt<3>(x: getExprCRVal())) || |
441 | (Kind == Immediate |
442 | && isUInt<3>(x: getImm())); } |
443 | bool isCRBitNumber() const { return (Kind == Expression |
444 | && isUInt<5>(x: getExprCRVal())) || |
445 | (Kind == Immediate |
446 | && isUInt<5>(x: getImm())); } |
447 | |
448 | bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; } |
449 | |
450 | bool isCRBitMask() const { |
451 | return Kind == Immediate && isUInt<8>(x: getImm()) && |
452 | llvm::has_single_bit<uint32_t>(Value: getImm()); |
453 | } |
454 | bool isATBitsAsHint() const { return false; } |
455 | bool isMem() const override { return false; } |
456 | bool isReg() const override { return false; } |
457 | |
458 | void addRegOperands(MCInst &Inst, unsigned N) const { |
459 | llvm_unreachable("addRegOperands" ); |
460 | } |
461 | |
462 | void addRegGPRCOperands(MCInst &Inst, unsigned N) const { |
463 | assert(N == 1 && "Invalid number of operands!" ); |
464 | Inst.addOperand(Op: MCOperand::createReg(Reg: RRegs[getRegNum()])); |
465 | } |
466 | |
467 | void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const { |
468 | assert(N == 1 && "Invalid number of operands!" ); |
469 | Inst.addOperand(Op: MCOperand::createReg(Reg: RRegsNoR0[getRegNum()])); |
470 | } |
471 | |
472 | void addRegG8RCOperands(MCInst &Inst, unsigned N) const { |
473 | assert(N == 1 && "Invalid number of operands!" ); |
474 | Inst.addOperand(Op: MCOperand::createReg(Reg: XRegs[getRegNum()])); |
475 | } |
476 | |
477 | void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const { |
478 | assert(N == 1 && "Invalid number of operands!" ); |
479 | Inst.addOperand(Op: MCOperand::createReg(Reg: XRegsNoX0[getRegNum()])); |
480 | } |
481 | |
482 | void addRegG8pRCOperands(MCInst &Inst, unsigned N) const { |
483 | assert(N == 1 && "Invalid number of operands!" ); |
484 | Inst.addOperand(Op: MCOperand::createReg(Reg: XRegs[getG8pReg()])); |
485 | } |
486 | |
487 | void addRegGxRCOperands(MCInst &Inst, unsigned N) const { |
488 | if (isPPC64()) |
489 | addRegG8RCOperands(Inst, N); |
490 | else |
491 | addRegGPRCOperands(Inst, N); |
492 | } |
493 | |
494 | void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const { |
495 | if (isPPC64()) |
496 | addRegG8RCNoX0Operands(Inst, N); |
497 | else |
498 | addRegGPRCNoR0Operands(Inst, N); |
499 | } |
500 | |
501 | void addRegF4RCOperands(MCInst &Inst, unsigned N) const { |
502 | assert(N == 1 && "Invalid number of operands!" ); |
503 | Inst.addOperand(Op: MCOperand::createReg(Reg: FRegs[getRegNum()])); |
504 | } |
505 | |
506 | void addRegF8RCOperands(MCInst &Inst, unsigned N) const { |
507 | assert(N == 1 && "Invalid number of operands!" ); |
508 | Inst.addOperand(Op: MCOperand::createReg(Reg: FRegs[getRegNum()])); |
509 | } |
510 | |
511 | void addRegFpRCOperands(MCInst &Inst, unsigned N) const { |
512 | assert(N == 1 && "Invalid number of operands!" ); |
513 | Inst.addOperand(Op: MCOperand::createReg(Reg: FpRegs[getFpReg()])); |
514 | } |
515 | |
516 | void addRegVFRCOperands(MCInst &Inst, unsigned N) const { |
517 | assert(N == 1 && "Invalid number of operands!" ); |
518 | Inst.addOperand(Op: MCOperand::createReg(Reg: VFRegs[getRegNum()])); |
519 | } |
520 | |
521 | void addRegVRRCOperands(MCInst &Inst, unsigned N) const { |
522 | assert(N == 1 && "Invalid number of operands!" ); |
523 | Inst.addOperand(Op: MCOperand::createReg(Reg: VRegs[getRegNum()])); |
524 | } |
525 | |
526 | void addRegVSRCOperands(MCInst &Inst, unsigned N) const { |
527 | assert(N == 1 && "Invalid number of operands!" ); |
528 | Inst.addOperand(Op: MCOperand::createReg(Reg: VSRegs[getVSReg()])); |
529 | } |
530 | |
531 | void addRegVSFRCOperands(MCInst &Inst, unsigned N) const { |
532 | assert(N == 1 && "Invalid number of operands!" ); |
533 | Inst.addOperand(Op: MCOperand::createReg(Reg: VSFRegs[getVSReg()])); |
534 | } |
535 | |
536 | void addRegVSSRCOperands(MCInst &Inst, unsigned N) const { |
537 | assert(N == 1 && "Invalid number of operands!" ); |
538 | Inst.addOperand(Op: MCOperand::createReg(Reg: VSSRegs[getVSReg()])); |
539 | } |
540 | |
541 | void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const { |
542 | assert(N == 1 && "Invalid number of operands!" ); |
543 | Inst.addOperand(Op: MCOperand::createReg(Reg: RRegs[getRegNum()])); |
544 | } |
545 | |
546 | void addRegSPERCOperands(MCInst &Inst, unsigned N) const { |
547 | assert(N == 1 && "Invalid number of operands!" ); |
548 | Inst.addOperand(Op: MCOperand::createReg(Reg: SPERegs[getRegNum()])); |
549 | } |
550 | |
551 | void addRegACCRCOperands(MCInst &Inst, unsigned N) const { |
552 | assert(N == 1 && "Invalid number of operands!" ); |
553 | Inst.addOperand(Op: MCOperand::createReg(Reg: ACCRegs[getACCReg()])); |
554 | } |
555 | |
556 | void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const { |
557 | assert(N == 1 && "Invalid number of operands!" ); |
558 | Inst.addOperand(Op: MCOperand::createReg(Reg: DMRROWRegs[getDMRROWReg()])); |
559 | } |
560 | |
561 | void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const { |
562 | assert(N == 1 && "Invalid number of operands!" ); |
563 | Inst.addOperand(Op: MCOperand::createReg(Reg: DMRROWpRegs[getDMRROWpReg()])); |
564 | } |
565 | |
566 | void addRegDMRRCOperands(MCInst &Inst, unsigned N) const { |
567 | assert(N == 1 && "Invalid number of operands!" ); |
568 | Inst.addOperand(Op: MCOperand::createReg(Reg: DMRRegs[getDMRReg()])); |
569 | } |
570 | |
571 | void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const { |
572 | assert(N == 1 && "Invalid number of operands!" ); |
573 | Inst.addOperand(Op: MCOperand::createReg(Reg: DMRpRegs[getDMRpReg()])); |
574 | } |
575 | |
576 | void addRegWACCRCOperands(MCInst &Inst, unsigned N) const { |
577 | assert(N == 1 && "Invalid number of operands!" ); |
578 | Inst.addOperand(Op: MCOperand::createReg(Reg: WACCRegs[getACCReg()])); |
579 | } |
580 | |
581 | void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const { |
582 | assert(N == 1 && "Invalid number of operands!" ); |
583 | Inst.addOperand(Op: MCOperand::createReg(Reg: WACC_HIRegs[getACCReg()])); |
584 | } |
585 | |
586 | void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const { |
587 | assert(N == 1 && "Invalid number of operands!" ); |
588 | Inst.addOperand(Op: MCOperand::createReg(Reg: VSRpRegs[getVSRpEvenReg()])); |
589 | } |
590 | |
591 | void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const { |
592 | assert(N == 1 && "Invalid number of operands!" ); |
593 | Inst.addOperand(Op: MCOperand::createReg(Reg: VSRpRegs[getVSRpEvenReg()])); |
594 | } |
595 | |
596 | void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const { |
597 | assert(N == 1 && "Invalid number of operands!" ); |
598 | Inst.addOperand(Op: MCOperand::createReg(Reg: CRBITRegs[getCRBit()])); |
599 | } |
600 | |
601 | void addRegCRRCOperands(MCInst &Inst, unsigned N) const { |
602 | assert(N == 1 && "Invalid number of operands!" ); |
603 | Inst.addOperand(Op: MCOperand::createReg(Reg: CRRegs[getCCReg()])); |
604 | } |
605 | |
606 | void addCRBitMaskOperands(MCInst &Inst, unsigned N) const { |
607 | assert(N == 1 && "Invalid number of operands!" ); |
608 | Inst.addOperand(Op: MCOperand::createReg(Reg: CRRegs[getCRBitMask()])); |
609 | } |
610 | |
611 | void addImmOperands(MCInst &Inst, unsigned N) const { |
612 | assert(N == 1 && "Invalid number of operands!" ); |
613 | if (Kind == Immediate) |
614 | Inst.addOperand(Op: MCOperand::createImm(Val: getImm())); |
615 | else |
616 | Inst.addOperand(Op: MCOperand::createExpr(Val: getExpr())); |
617 | } |
618 | |
619 | void addS16ImmOperands(MCInst &Inst, unsigned N) const { |
620 | assert(N == 1 && "Invalid number of operands!" ); |
621 | switch (Kind) { |
622 | case Immediate: |
623 | Inst.addOperand(Op: MCOperand::createImm(Val: getImm())); |
624 | break; |
625 | case ContextImmediate: |
626 | Inst.addOperand(Op: MCOperand::createImm(Val: getImmS16Context())); |
627 | break; |
628 | default: |
629 | Inst.addOperand(Op: MCOperand::createExpr(Val: getExpr())); |
630 | break; |
631 | } |
632 | } |
633 | |
634 | void addU16ImmOperands(MCInst &Inst, unsigned N) const { |
635 | assert(N == 1 && "Invalid number of operands!" ); |
636 | switch (Kind) { |
637 | case Immediate: |
638 | Inst.addOperand(Op: MCOperand::createImm(Val: getImm())); |
639 | break; |
640 | case ContextImmediate: |
641 | Inst.addOperand(Op: MCOperand::createImm(Val: getImmU16Context())); |
642 | break; |
643 | default: |
644 | Inst.addOperand(Op: MCOperand::createExpr(Val: getExpr())); |
645 | break; |
646 | } |
647 | } |
648 | |
649 | void addBranchTargetOperands(MCInst &Inst, unsigned N) const { |
650 | assert(N == 1 && "Invalid number of operands!" ); |
651 | if (Kind == Immediate) |
652 | Inst.addOperand(Op: MCOperand::createImm(Val: getImm() / 4)); |
653 | else |
654 | Inst.addOperand(Op: MCOperand::createExpr(Val: getExpr())); |
655 | } |
656 | |
657 | void addTLSRegOperands(MCInst &Inst, unsigned N) const { |
658 | assert(N == 1 && "Invalid number of operands!" ); |
659 | Inst.addOperand(Op: MCOperand::createExpr(Val: getTLSReg())); |
660 | } |
661 | |
662 | StringRef getToken() const { |
663 | assert(Kind == Token && "Invalid access!" ); |
664 | return StringRef(Tok.Data, Tok.Length); |
665 | } |
666 | |
667 | void print(raw_ostream &OS) const override; |
668 | |
669 | static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S, |
670 | bool IsPPC64) { |
671 | auto Op = std::make_unique<PPCOperand>(args: Token); |
672 | Op->Tok.Data = Str.data(); |
673 | Op->Tok.Length = Str.size(); |
674 | Op->StartLoc = S; |
675 | Op->EndLoc = S; |
676 | Op->IsPPC64 = IsPPC64; |
677 | return Op; |
678 | } |
679 | |
680 | static std::unique_ptr<PPCOperand> |
681 | CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) { |
682 | // Allocate extra memory for the string and copy it. |
683 | // FIXME: This is incorrect, Operands are owned by unique_ptr with a default |
684 | // deleter which will destroy them by simply using "delete", not correctly |
685 | // calling operator delete on this extra memory after calling the dtor |
686 | // explicitly. |
687 | void *Mem = ::operator new(sizeof(PPCOperand) + Str.size()); |
688 | std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token)); |
689 | Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1); |
690 | Op->Tok.Length = Str.size(); |
691 | std::memcpy(dest: const_cast<char *>(Op->Tok.Data), src: Str.data(), n: Str.size()); |
692 | Op->StartLoc = S; |
693 | Op->EndLoc = S; |
694 | Op->IsPPC64 = IsPPC64; |
695 | return Op; |
696 | } |
697 | |
698 | static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E, |
699 | bool IsPPC64) { |
700 | auto Op = std::make_unique<PPCOperand>(args: Immediate); |
701 | Op->Imm.Val = Val; |
702 | Op->StartLoc = S; |
703 | Op->EndLoc = E; |
704 | Op->IsPPC64 = IsPPC64; |
705 | return Op; |
706 | } |
707 | |
708 | static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S, |
709 | SMLoc E, bool IsPPC64) { |
710 | auto Op = std::make_unique<PPCOperand>(args: Expression); |
711 | Op->Expr.Val = Val; |
712 | Op->Expr.CRVal = EvaluateCRExpr(E: Val); |
713 | Op->StartLoc = S; |
714 | Op->EndLoc = E; |
715 | Op->IsPPC64 = IsPPC64; |
716 | return Op; |
717 | } |
718 | |
719 | static std::unique_ptr<PPCOperand> |
720 | CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) { |
721 | auto Op = std::make_unique<PPCOperand>(args: TLSRegister); |
722 | Op->TLSReg.Sym = Sym; |
723 | Op->StartLoc = S; |
724 | Op->EndLoc = E; |
725 | Op->IsPPC64 = IsPPC64; |
726 | return Op; |
727 | } |
728 | |
729 | static std::unique_ptr<PPCOperand> |
730 | CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) { |
731 | auto Op = std::make_unique<PPCOperand>(args: ContextImmediate); |
732 | Op->Imm.Val = Val; |
733 | Op->StartLoc = S; |
734 | Op->EndLoc = E; |
735 | Op->IsPPC64 = IsPPC64; |
736 | return Op; |
737 | } |
738 | |
739 | static std::unique_ptr<PPCOperand> |
740 | CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) { |
741 | if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val)) |
742 | return CreateImm(Val: CE->getValue(), S, E, IsPPC64); |
743 | |
744 | if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val)) |
745 | if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS || |
746 | SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL) |
747 | return CreateTLSReg(Sym: SRE, S, E, IsPPC64); |
748 | |
749 | if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) { |
750 | int64_t Res; |
751 | if (TE->evaluateAsConstant(Res)) |
752 | return CreateContextImm(Val: Res, S, E, IsPPC64); |
753 | } |
754 | |
755 | return CreateExpr(Val, S, E, IsPPC64); |
756 | } |
757 | |
758 | private: |
759 | template <unsigned Width> |
760 | bool isExtImm(bool Signed, unsigned Multiple) const { |
761 | switch (Kind) { |
762 | default: |
763 | return false; |
764 | case Expression: |
765 | return true; |
766 | case Immediate: |
767 | case ContextImmediate: |
768 | if (Signed) |
769 | return isInt<Width>(getImmS16Context()) && |
770 | (getImmS16Context() & (Multiple - 1)) == 0; |
771 | else |
772 | return isUInt<Width>(getImmU16Context()) && |
773 | (getImmU16Context() & (Multiple - 1)) == 0; |
774 | } |
775 | } |
776 | }; |
777 | |
778 | } // end anonymous namespace. |
779 | |
780 | void PPCOperand::print(raw_ostream &OS) const { |
781 | switch (Kind) { |
782 | case Token: |
783 | OS << "'" << getToken() << "'" ; |
784 | break; |
785 | case Immediate: |
786 | case ContextImmediate: |
787 | OS << getImm(); |
788 | break; |
789 | case Expression: |
790 | OS << *getExpr(); |
791 | break; |
792 | case TLSRegister: |
793 | OS << *getTLSReg(); |
794 | break; |
795 | } |
796 | } |
797 | |
798 | static void |
799 | addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) { |
800 | if (Op.isImm()) { |
801 | Inst.addOperand(Op: MCOperand::createImm(Val: -Op.getImm())); |
802 | return; |
803 | } |
804 | const MCExpr *Expr = Op.getExpr(); |
805 | if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Val: Expr)) { |
806 | if (UnExpr->getOpcode() == MCUnaryExpr::Minus) { |
807 | Inst.addOperand(Op: MCOperand::createExpr(Val: UnExpr->getSubExpr())); |
808 | return; |
809 | } |
810 | } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Val: Expr)) { |
811 | if (BinExpr->getOpcode() == MCBinaryExpr::Sub) { |
812 | const MCExpr *NE = MCBinaryExpr::createSub(LHS: BinExpr->getRHS(), |
813 | RHS: BinExpr->getLHS(), Ctx); |
814 | Inst.addOperand(Op: MCOperand::createExpr(Val: NE)); |
815 | return; |
816 | } |
817 | } |
818 | Inst.addOperand(Op: MCOperand::createExpr(Val: MCUnaryExpr::createMinus(Expr, Ctx))); |
819 | } |
820 | |
821 | void PPCAsmParser::ProcessInstruction(MCInst &Inst, |
822 | const OperandVector &Operands) { |
823 | int Opcode = Inst.getOpcode(); |
824 | switch (Opcode) { |
825 | case PPC::DCBTx: |
826 | case PPC::DCBTT: |
827 | case PPC::DCBTSTx: |
828 | case PPC::DCBTSTT: { |
829 | MCInst TmpInst; |
830 | TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ? |
831 | PPC::DCBT : PPC::DCBTST); |
832 | TmpInst.addOperand(Op: MCOperand::createImm( |
833 | Val: (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16)); |
834 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
835 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
836 | Inst = TmpInst; |
837 | break; |
838 | } |
839 | case PPC::DCBTCT: |
840 | case PPC::DCBTDS: { |
841 | MCInst TmpInst; |
842 | TmpInst.setOpcode(PPC::DCBT); |
843 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
844 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
845 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
846 | Inst = TmpInst; |
847 | break; |
848 | } |
849 | case PPC::DCBTSTCT: |
850 | case PPC::DCBTSTDS: { |
851 | MCInst TmpInst; |
852 | TmpInst.setOpcode(PPC::DCBTST); |
853 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
854 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
855 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
856 | Inst = TmpInst; |
857 | break; |
858 | } |
859 | case PPC::DCBFx: |
860 | case PPC::DCBFL: |
861 | case PPC::DCBFLP: |
862 | case PPC::DCBFPS: |
863 | case PPC::DCBSTPS: { |
864 | int L = 0; |
865 | if (Opcode == PPC::DCBFL) |
866 | L = 1; |
867 | else if (Opcode == PPC::DCBFLP) |
868 | L = 3; |
869 | else if (Opcode == PPC::DCBFPS) |
870 | L = 4; |
871 | else if (Opcode == PPC::DCBSTPS) |
872 | L = 6; |
873 | |
874 | MCInst TmpInst; |
875 | TmpInst.setOpcode(PPC::DCBF); |
876 | TmpInst.addOperand(Op: MCOperand::createImm(Val: L)); |
877 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
878 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
879 | Inst = TmpInst; |
880 | break; |
881 | } |
882 | case PPC::LAx: { |
883 | MCInst TmpInst; |
884 | TmpInst.setOpcode(PPC::LA); |
885 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
886 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
887 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
888 | Inst = TmpInst; |
889 | break; |
890 | } |
891 | case PPC::PLA8: |
892 | case PPC::PLA: { |
893 | MCInst TmpInst; |
894 | TmpInst.setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8); |
895 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
896 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
897 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
898 | Inst = TmpInst; |
899 | break; |
900 | } |
901 | case PPC::PLA8pc: |
902 | case PPC::PLApc: { |
903 | MCInst TmpInst; |
904 | TmpInst.setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc); |
905 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
906 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
907 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
908 | Inst = TmpInst; |
909 | break; |
910 | } |
911 | case PPC::SUBI: { |
912 | MCInst TmpInst; |
913 | TmpInst.setOpcode(PPC::ADDI); |
914 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
915 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
916 | addNegOperand(Inst&: TmpInst, Op&: Inst.getOperand(i: 2), Ctx&: getContext()); |
917 | Inst = TmpInst; |
918 | break; |
919 | } |
920 | case PPC::PSUBI: { |
921 | MCInst TmpInst; |
922 | TmpInst.setOpcode(PPC::PADDI); |
923 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
924 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
925 | addNegOperand(Inst&: TmpInst, Op&: Inst.getOperand(i: 2), Ctx&: getContext()); |
926 | Inst = TmpInst; |
927 | break; |
928 | } |
929 | case PPC::SUBIS: { |
930 | MCInst TmpInst; |
931 | TmpInst.setOpcode(PPC::ADDIS); |
932 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
933 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
934 | addNegOperand(Inst&: TmpInst, Op&: Inst.getOperand(i: 2), Ctx&: getContext()); |
935 | Inst = TmpInst; |
936 | break; |
937 | } |
938 | case PPC::SUBIC: { |
939 | MCInst TmpInst; |
940 | TmpInst.setOpcode(PPC::ADDIC); |
941 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
942 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
943 | addNegOperand(Inst&: TmpInst, Op&: Inst.getOperand(i: 2), Ctx&: getContext()); |
944 | Inst = TmpInst; |
945 | break; |
946 | } |
947 | case PPC::SUBIC_rec: { |
948 | MCInst TmpInst; |
949 | TmpInst.setOpcode(PPC::ADDIC_rec); |
950 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
951 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
952 | addNegOperand(Inst&: TmpInst, Op&: Inst.getOperand(i: 2), Ctx&: getContext()); |
953 | Inst = TmpInst; |
954 | break; |
955 | } |
956 | case PPC::EXTLWI: |
957 | case PPC::EXTLWI_rec: { |
958 | MCInst TmpInst; |
959 | int64_t N = Inst.getOperand(i: 2).getImm(); |
960 | int64_t B = Inst.getOperand(i: 3).getImm(); |
961 | TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec); |
962 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
963 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
964 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B)); |
965 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
966 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N - 1)); |
967 | Inst = TmpInst; |
968 | break; |
969 | } |
970 | case PPC::EXTRWI: |
971 | case PPC::EXTRWI_rec: { |
972 | MCInst TmpInst; |
973 | int64_t N = Inst.getOperand(i: 2).getImm(); |
974 | int64_t B = Inst.getOperand(i: 3).getImm(); |
975 | TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec); |
976 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
977 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
978 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B + N)); |
979 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 32 - N)); |
980 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31)); |
981 | Inst = TmpInst; |
982 | break; |
983 | } |
984 | case PPC::INSLWI: |
985 | case PPC::INSLWI_rec: { |
986 | MCInst TmpInst; |
987 | int64_t N = Inst.getOperand(i: 2).getImm(); |
988 | int64_t B = Inst.getOperand(i: 3).getImm(); |
989 | TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec); |
990 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
991 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
992 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
993 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 32 - B)); |
994 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B)); |
995 | TmpInst.addOperand(Op: MCOperand::createImm(Val: (B + N) - 1)); |
996 | Inst = TmpInst; |
997 | break; |
998 | } |
999 | case PPC::INSRWI: |
1000 | case PPC::INSRWI_rec: { |
1001 | MCInst TmpInst; |
1002 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1003 | int64_t B = Inst.getOperand(i: 3).getImm(); |
1004 | TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec); |
1005 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1006 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1007 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1008 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 32 - (B + N))); |
1009 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B)); |
1010 | TmpInst.addOperand(Op: MCOperand::createImm(Val: (B + N) - 1)); |
1011 | Inst = TmpInst; |
1012 | break; |
1013 | } |
1014 | case PPC::ROTRWI: |
1015 | case PPC::ROTRWI_rec: { |
1016 | MCInst TmpInst; |
1017 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1018 | TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec); |
1019 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1020 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1021 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 32 - N)); |
1022 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1023 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31)); |
1024 | Inst = TmpInst; |
1025 | break; |
1026 | } |
1027 | case PPC::SLWI: |
1028 | case PPC::SLWI_rec: { |
1029 | MCInst TmpInst; |
1030 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1031 | TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec); |
1032 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1033 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1034 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1035 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1036 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31 - N)); |
1037 | Inst = TmpInst; |
1038 | break; |
1039 | } |
1040 | case PPC::SRWI: |
1041 | case PPC::SRWI_rec: { |
1042 | MCInst TmpInst; |
1043 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1044 | TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec); |
1045 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1046 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1047 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 32 - N)); |
1048 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1049 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31)); |
1050 | Inst = TmpInst; |
1051 | break; |
1052 | } |
1053 | case PPC::CLRRWI: |
1054 | case PPC::CLRRWI_rec: { |
1055 | MCInst TmpInst; |
1056 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1057 | TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec); |
1058 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1059 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1060 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1061 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1062 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31 - N)); |
1063 | Inst = TmpInst; |
1064 | break; |
1065 | } |
1066 | case PPC::CLRLSLWI: |
1067 | case PPC::CLRLSLWI_rec: { |
1068 | MCInst TmpInst; |
1069 | int64_t B = Inst.getOperand(i: 2).getImm(); |
1070 | int64_t N = Inst.getOperand(i: 3).getImm(); |
1071 | TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec); |
1072 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1073 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1074 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1075 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B - N)); |
1076 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 31 - N)); |
1077 | Inst = TmpInst; |
1078 | break; |
1079 | } |
1080 | case PPC::EXTLDI: |
1081 | case PPC::EXTLDI_rec: { |
1082 | MCInst TmpInst; |
1083 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1084 | int64_t B = Inst.getOperand(i: 3).getImm(); |
1085 | TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec); |
1086 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1087 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1088 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B)); |
1089 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N - 1)); |
1090 | Inst = TmpInst; |
1091 | break; |
1092 | } |
1093 | case PPC::EXTRDI: |
1094 | case PPC::EXTRDI_rec: { |
1095 | MCInst TmpInst; |
1096 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1097 | int64_t B = Inst.getOperand(i: 3).getImm(); |
1098 | TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec); |
1099 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1100 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1101 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B + N)); |
1102 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 64 - N)); |
1103 | Inst = TmpInst; |
1104 | break; |
1105 | } |
1106 | case PPC::INSRDI: |
1107 | case PPC::INSRDI_rec: { |
1108 | MCInst TmpInst; |
1109 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1110 | int64_t B = Inst.getOperand(i: 3).getImm(); |
1111 | TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec); |
1112 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1113 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1114 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1115 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 64 - (B + N))); |
1116 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B)); |
1117 | Inst = TmpInst; |
1118 | break; |
1119 | } |
1120 | case PPC::ROTRDI: |
1121 | case PPC::ROTRDI_rec: { |
1122 | MCInst TmpInst; |
1123 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1124 | TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec); |
1125 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1126 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1127 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 64 - N)); |
1128 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1129 | Inst = TmpInst; |
1130 | break; |
1131 | } |
1132 | case PPC::SLDI: |
1133 | case PPC::SLDI_rec: { |
1134 | MCInst TmpInst; |
1135 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1136 | TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec); |
1137 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1138 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1139 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1140 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 63 - N)); |
1141 | Inst = TmpInst; |
1142 | break; |
1143 | } |
1144 | case PPC::SUBPCIS: { |
1145 | MCInst TmpInst; |
1146 | int64_t N = Inst.getOperand(i: 1).getImm(); |
1147 | TmpInst.setOpcode(PPC::ADDPCIS); |
1148 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1149 | TmpInst.addOperand(Op: MCOperand::createImm(Val: -N)); |
1150 | Inst = TmpInst; |
1151 | break; |
1152 | } |
1153 | case PPC::SRDI: |
1154 | case PPC::SRDI_rec: { |
1155 | MCInst TmpInst; |
1156 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1157 | TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec); |
1158 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1159 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1160 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 64 - N)); |
1161 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1162 | Inst = TmpInst; |
1163 | break; |
1164 | } |
1165 | case PPC::CLRRDI: |
1166 | case PPC::CLRRDI_rec: { |
1167 | MCInst TmpInst; |
1168 | int64_t N = Inst.getOperand(i: 2).getImm(); |
1169 | TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec); |
1170 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1171 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1172 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 0)); |
1173 | TmpInst.addOperand(Op: MCOperand::createImm(Val: 63 - N)); |
1174 | Inst = TmpInst; |
1175 | break; |
1176 | } |
1177 | case PPC::CLRLSLDI: |
1178 | case PPC::CLRLSLDI_rec: { |
1179 | MCInst TmpInst; |
1180 | int64_t B = Inst.getOperand(i: 2).getImm(); |
1181 | int64_t N = Inst.getOperand(i: 3).getImm(); |
1182 | TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec); |
1183 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1184 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1185 | TmpInst.addOperand(Op: MCOperand::createImm(Val: N)); |
1186 | TmpInst.addOperand(Op: MCOperand::createImm(Val: B - N)); |
1187 | Inst = TmpInst; |
1188 | break; |
1189 | } |
1190 | case PPC::RLWINMbm: |
1191 | case PPC::RLWINMbm_rec: { |
1192 | unsigned MB, ME; |
1193 | int64_t BM = Inst.getOperand(i: 3).getImm(); |
1194 | if (!isRunOfOnes(Val: BM, MB, ME)) |
1195 | break; |
1196 | |
1197 | MCInst TmpInst; |
1198 | TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec); |
1199 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1200 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1201 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
1202 | TmpInst.addOperand(Op: MCOperand::createImm(Val: MB)); |
1203 | TmpInst.addOperand(Op: MCOperand::createImm(Val: ME)); |
1204 | Inst = TmpInst; |
1205 | break; |
1206 | } |
1207 | case PPC::RLWIMIbm: |
1208 | case PPC::RLWIMIbm_rec: { |
1209 | unsigned MB, ME; |
1210 | int64_t BM = Inst.getOperand(i: 3).getImm(); |
1211 | if (!isRunOfOnes(Val: BM, MB, ME)) |
1212 | break; |
1213 | |
1214 | MCInst TmpInst; |
1215 | TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec); |
1216 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1217 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); // The tied operand. |
1218 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1219 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
1220 | TmpInst.addOperand(Op: MCOperand::createImm(Val: MB)); |
1221 | TmpInst.addOperand(Op: MCOperand::createImm(Val: ME)); |
1222 | Inst = TmpInst; |
1223 | break; |
1224 | } |
1225 | case PPC::RLWNMbm: |
1226 | case PPC::RLWNMbm_rec: { |
1227 | unsigned MB, ME; |
1228 | int64_t BM = Inst.getOperand(i: 3).getImm(); |
1229 | if (!isRunOfOnes(Val: BM, MB, ME)) |
1230 | break; |
1231 | |
1232 | MCInst TmpInst; |
1233 | TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec); |
1234 | TmpInst.addOperand(Op: Inst.getOperand(i: 0)); |
1235 | TmpInst.addOperand(Op: Inst.getOperand(i: 1)); |
1236 | TmpInst.addOperand(Op: Inst.getOperand(i: 2)); |
1237 | TmpInst.addOperand(Op: MCOperand::createImm(Val: MB)); |
1238 | TmpInst.addOperand(Op: MCOperand::createImm(Val: ME)); |
1239 | Inst = TmpInst; |
1240 | break; |
1241 | } |
1242 | case PPC::MFTB: { |
1243 | if (getSTI().hasFeature(Feature: PPC::FeatureMFTB)) { |
1244 | assert(Inst.getNumOperands() == 2 && "Expecting two operands" ); |
1245 | Inst.setOpcode(PPC::MFSPR); |
1246 | } |
1247 | break; |
1248 | } |
1249 | } |
1250 | } |
1251 | |
1252 | static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, |
1253 | unsigned VariantID = 0); |
1254 | |
1255 | bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, |
1256 | OperandVector &Operands, |
1257 | MCStreamer &Out, uint64_t &ErrorInfo, |
1258 | bool MatchingInlineAsm) { |
1259 | MCInst Inst; |
1260 | |
1261 | switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, matchingInlineAsm: MatchingInlineAsm)) { |
1262 | case Match_Success: |
1263 | // Post-process instructions (typically extended mnemonics) |
1264 | ProcessInstruction(Inst, Operands); |
1265 | Inst.setLoc(IDLoc); |
1266 | Out.emitInstruction(Inst, STI: getSTI()); |
1267 | return false; |
1268 | case Match_MissingFeature: |
1269 | return Error(L: IDLoc, Msg: "instruction use requires an option to be enabled" ); |
1270 | case Match_MnemonicFail: { |
1271 | FeatureBitset FBS = ComputeAvailableFeatures(FB: getSTI().getFeatureBits()); |
1272 | std::string Suggestion = PPCMnemonicSpellCheck( |
1273 | S: ((PPCOperand &)*Operands[0]).getToken(), FBS); |
1274 | return Error(L: IDLoc, Msg: "invalid instruction" + Suggestion, |
1275 | Range: ((PPCOperand &)*Operands[0]).getLocRange()); |
1276 | } |
1277 | case Match_InvalidOperand: { |
1278 | SMLoc ErrorLoc = IDLoc; |
1279 | if (ErrorInfo != ~0ULL) { |
1280 | if (ErrorInfo >= Operands.size()) |
1281 | return Error(L: IDLoc, Msg: "too few operands for instruction" ); |
1282 | |
1283 | ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc(); |
1284 | if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; |
1285 | } |
1286 | |
1287 | return Error(L: ErrorLoc, Msg: "invalid operand for instruction" ); |
1288 | } |
1289 | } |
1290 | |
1291 | llvm_unreachable("Implement any new match types added!" ); |
1292 | } |
1293 | |
1294 | bool PPCAsmParser::MatchRegisterName(MCRegister &RegNo, int64_t &IntVal) { |
1295 | if (getParser().getTok().is(K: AsmToken::Percent)) |
1296 | getParser().Lex(); // Eat the '%'. |
1297 | |
1298 | if (!getParser().getTok().is(K: AsmToken::Identifier)) |
1299 | return true; |
1300 | |
1301 | StringRef Name = getParser().getTok().getString(); |
1302 | if (Name.equals_insensitive(RHS: "lr" )) { |
1303 | RegNo = isPPC64() ? PPC::LR8 : PPC::LR; |
1304 | IntVal = 8; |
1305 | } else if (Name.equals_insensitive(RHS: "ctr" )) { |
1306 | RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR; |
1307 | IntVal = 9; |
1308 | } else if (Name.equals_insensitive(RHS: "vrsave" )) { |
1309 | RegNo = PPC::VRSAVE; |
1310 | IntVal = 256; |
1311 | } else if (Name.starts_with_insensitive(Prefix: "r" ) && |
1312 | !Name.substr(Start: 1).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 32) { |
1313 | RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal]; |
1314 | } else if (Name.starts_with_insensitive(Prefix: "f" ) && |
1315 | !Name.substr(Start: 1).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 32) { |
1316 | RegNo = FRegs[IntVal]; |
1317 | } else if (Name.starts_with_insensitive(Prefix: "vs" ) && |
1318 | !Name.substr(Start: 2).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 64) { |
1319 | RegNo = VSRegs[IntVal]; |
1320 | } else if (Name.starts_with_insensitive(Prefix: "v" ) && |
1321 | !Name.substr(Start: 1).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 32) { |
1322 | RegNo = VRegs[IntVal]; |
1323 | } else if (Name.starts_with_insensitive(Prefix: "cr" ) && |
1324 | !Name.substr(Start: 2).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 8) { |
1325 | RegNo = CRRegs[IntVal]; |
1326 | } else if (Name.starts_with_insensitive(Prefix: "acc" ) && |
1327 | !Name.substr(Start: 3).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 8) { |
1328 | RegNo = ACCRegs[IntVal]; |
1329 | } else if (Name.starts_with_insensitive(Prefix: "wacc_hi" ) && |
1330 | !Name.substr(Start: 7).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 8) { |
1331 | RegNo = ACCRegs[IntVal]; |
1332 | } else if (Name.starts_with_insensitive(Prefix: "wacc" ) && |
1333 | !Name.substr(Start: 4).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 8) { |
1334 | RegNo = WACCRegs[IntVal]; |
1335 | } else if (Name.starts_with_insensitive(Prefix: "dmrrowp" ) && |
1336 | !Name.substr(Start: 7).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 32) { |
1337 | RegNo = DMRROWpRegs[IntVal]; |
1338 | } else if (Name.starts_with_insensitive(Prefix: "dmrrow" ) && |
1339 | !Name.substr(Start: 6).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 64) { |
1340 | RegNo = DMRROWRegs[IntVal]; |
1341 | } else if (Name.starts_with_insensitive(Prefix: "dmrp" ) && |
1342 | !Name.substr(Start: 4).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 4) { |
1343 | RegNo = DMRROWpRegs[IntVal]; |
1344 | } else if (Name.starts_with_insensitive(Prefix: "dmr" ) && |
1345 | !Name.substr(Start: 3).getAsInteger(Radix: 10, Result&: IntVal) && IntVal < 8) { |
1346 | RegNo = DMRRegs[IntVal]; |
1347 | } else |
1348 | return true; |
1349 | getParser().Lex(); |
1350 | return false; |
1351 | } |
1352 | |
1353 | bool PPCAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, |
1354 | SMLoc &EndLoc) { |
1355 | if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess()) |
1356 | return TokError(Msg: "invalid register name" ); |
1357 | return false; |
1358 | } |
1359 | |
1360 | ParseStatus PPCAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, |
1361 | SMLoc &EndLoc) { |
1362 | const AsmToken &Tok = getParser().getTok(); |
1363 | StartLoc = Tok.getLoc(); |
1364 | EndLoc = Tok.getEndLoc(); |
1365 | Reg = PPC::NoRegister; |
1366 | int64_t IntVal; |
1367 | if (MatchRegisterName(RegNo&: Reg, IntVal)) |
1368 | return ParseStatus::NoMatch; |
1369 | return ParseStatus::Success; |
1370 | } |
1371 | |
1372 | /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan |
1373 | /// the expression and check for VK_PPC_LO/HI/HA |
1374 | /// symbol variants. If all symbols with modifier use the same |
1375 | /// variant, return the corresponding PPCMCExpr::VariantKind, |
1376 | /// and a modified expression using the default symbol variant. |
1377 | /// Otherwise, return NULL. |
1378 | const MCExpr *PPCAsmParser:: |
1379 | (const MCExpr *E, |
1380 | PPCMCExpr::VariantKind &Variant) { |
1381 | MCContext &Context = getParser().getContext(); |
1382 | Variant = PPCMCExpr::VK_PPC_None; |
1383 | |
1384 | switch (E->getKind()) { |
1385 | case MCExpr::Target: |
1386 | case MCExpr::Constant: |
1387 | return nullptr; |
1388 | |
1389 | case MCExpr::SymbolRef: { |
1390 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Val: E); |
1391 | |
1392 | switch (SRE->getKind()) { |
1393 | case MCSymbolRefExpr::VK_PPC_LO: |
1394 | Variant = PPCMCExpr::VK_PPC_LO; |
1395 | break; |
1396 | case MCSymbolRefExpr::VK_PPC_HI: |
1397 | Variant = PPCMCExpr::VK_PPC_HI; |
1398 | break; |
1399 | case MCSymbolRefExpr::VK_PPC_HA: |
1400 | Variant = PPCMCExpr::VK_PPC_HA; |
1401 | break; |
1402 | case MCSymbolRefExpr::VK_PPC_HIGH: |
1403 | Variant = PPCMCExpr::VK_PPC_HIGH; |
1404 | break; |
1405 | case MCSymbolRefExpr::VK_PPC_HIGHA: |
1406 | Variant = PPCMCExpr::VK_PPC_HIGHA; |
1407 | break; |
1408 | case MCSymbolRefExpr::VK_PPC_HIGHER: |
1409 | Variant = PPCMCExpr::VK_PPC_HIGHER; |
1410 | break; |
1411 | case MCSymbolRefExpr::VK_PPC_HIGHERA: |
1412 | Variant = PPCMCExpr::VK_PPC_HIGHERA; |
1413 | break; |
1414 | case MCSymbolRefExpr::VK_PPC_HIGHEST: |
1415 | Variant = PPCMCExpr::VK_PPC_HIGHEST; |
1416 | break; |
1417 | case MCSymbolRefExpr::VK_PPC_HIGHESTA: |
1418 | Variant = PPCMCExpr::VK_PPC_HIGHESTA; |
1419 | break; |
1420 | default: |
1421 | return nullptr; |
1422 | } |
1423 | |
1424 | return MCSymbolRefExpr::create(Symbol: &SRE->getSymbol(), Ctx&: Context); |
1425 | } |
1426 | |
1427 | case MCExpr::Unary: { |
1428 | const MCUnaryExpr *UE = cast<MCUnaryExpr>(Val: E); |
1429 | const MCExpr *Sub = ExtractModifierFromExpr(E: UE->getSubExpr(), Variant); |
1430 | if (!Sub) |
1431 | return nullptr; |
1432 | return MCUnaryExpr::create(Op: UE->getOpcode(), Expr: Sub, Ctx&: Context); |
1433 | } |
1434 | |
1435 | case MCExpr::Binary: { |
1436 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(Val: E); |
1437 | PPCMCExpr::VariantKind LHSVariant, RHSVariant; |
1438 | const MCExpr *LHS = ExtractModifierFromExpr(E: BE->getLHS(), Variant&: LHSVariant); |
1439 | const MCExpr *RHS = ExtractModifierFromExpr(E: BE->getRHS(), Variant&: RHSVariant); |
1440 | |
1441 | if (!LHS && !RHS) |
1442 | return nullptr; |
1443 | |
1444 | if (!LHS) LHS = BE->getLHS(); |
1445 | if (!RHS) RHS = BE->getRHS(); |
1446 | |
1447 | if (LHSVariant == PPCMCExpr::VK_PPC_None) |
1448 | Variant = RHSVariant; |
1449 | else if (RHSVariant == PPCMCExpr::VK_PPC_None) |
1450 | Variant = LHSVariant; |
1451 | else if (LHSVariant == RHSVariant) |
1452 | Variant = LHSVariant; |
1453 | else |
1454 | return nullptr; |
1455 | |
1456 | return MCBinaryExpr::create(Op: BE->getOpcode(), LHS, RHS, Ctx&: Context); |
1457 | } |
1458 | } |
1459 | |
1460 | llvm_unreachable("Invalid expression kind!" ); |
1461 | } |
1462 | |
1463 | /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace |
1464 | /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having |
1465 | /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT. |
1466 | /// FIXME: This is a hack. |
1467 | const MCExpr *PPCAsmParser:: |
1468 | FixupVariantKind(const MCExpr *E) { |
1469 | MCContext &Context = getParser().getContext(); |
1470 | |
1471 | switch (E->getKind()) { |
1472 | case MCExpr::Target: |
1473 | case MCExpr::Constant: |
1474 | return E; |
1475 | |
1476 | case MCExpr::SymbolRef: { |
1477 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Val: E); |
1478 | MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; |
1479 | |
1480 | switch (SRE->getKind()) { |
1481 | case MCSymbolRefExpr::VK_TLSGD: |
1482 | Variant = MCSymbolRefExpr::VK_PPC_TLSGD; |
1483 | break; |
1484 | case MCSymbolRefExpr::VK_TLSLD: |
1485 | Variant = MCSymbolRefExpr::VK_PPC_TLSLD; |
1486 | break; |
1487 | default: |
1488 | return E; |
1489 | } |
1490 | return MCSymbolRefExpr::create(Symbol: &SRE->getSymbol(), Kind: Variant, Ctx&: Context); |
1491 | } |
1492 | |
1493 | case MCExpr::Unary: { |
1494 | const MCUnaryExpr *UE = cast<MCUnaryExpr>(Val: E); |
1495 | const MCExpr *Sub = FixupVariantKind(E: UE->getSubExpr()); |
1496 | if (Sub == UE->getSubExpr()) |
1497 | return E; |
1498 | return MCUnaryExpr::create(Op: UE->getOpcode(), Expr: Sub, Ctx&: Context); |
1499 | } |
1500 | |
1501 | case MCExpr::Binary: { |
1502 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(Val: E); |
1503 | const MCExpr *LHS = FixupVariantKind(E: BE->getLHS()); |
1504 | const MCExpr *RHS = FixupVariantKind(E: BE->getRHS()); |
1505 | if (LHS == BE->getLHS() && RHS == BE->getRHS()) |
1506 | return E; |
1507 | return MCBinaryExpr::create(Op: BE->getOpcode(), LHS, RHS, Ctx&: Context); |
1508 | } |
1509 | } |
1510 | |
1511 | llvm_unreachable("Invalid expression kind!" ); |
1512 | } |
1513 | |
1514 | /// ParseExpression. This differs from the default "parseExpression" in that |
1515 | /// it handles modifiers. |
1516 | bool PPCAsmParser:: |
1517 | ParseExpression(const MCExpr *&EVal) { |
1518 | // (ELF Platforms) |
1519 | // Handle \code @l/@ha \endcode |
1520 | if (getParser().parseExpression(Res&: EVal)) |
1521 | return true; |
1522 | |
1523 | EVal = FixupVariantKind(E: EVal); |
1524 | |
1525 | PPCMCExpr::VariantKind Variant; |
1526 | const MCExpr *E = ExtractModifierFromExpr(E: EVal, Variant); |
1527 | if (E) |
1528 | EVal = PPCMCExpr::create(Kind: Variant, Expr: E, Ctx&: getParser().getContext()); |
1529 | |
1530 | return false; |
1531 | } |
1532 | |
1533 | /// ParseOperand |
1534 | /// This handles registers in the form 'NN', '%rNN' for ELF platforms and |
1535 | /// rNN for MachO. |
1536 | bool PPCAsmParser::ParseOperand(OperandVector &Operands) { |
1537 | MCAsmParser &Parser = getParser(); |
1538 | SMLoc S = Parser.getTok().getLoc(); |
1539 | SMLoc E = SMLoc::getFromPointer(Ptr: Parser.getTok().getLoc().getPointer() - 1); |
1540 | const MCExpr *EVal; |
1541 | |
1542 | // Attempt to parse the next token as an immediate |
1543 | switch (getLexer().getKind()) { |
1544 | // Special handling for register names. These are interpreted |
1545 | // as immediates corresponding to the register number. |
1546 | case AsmToken::Percent: { |
1547 | MCRegister RegNo; |
1548 | int64_t IntVal; |
1549 | if (MatchRegisterName(RegNo, IntVal)) |
1550 | return Error(L: S, Msg: "invalid register name" ); |
1551 | |
1552 | Operands.push_back(Elt: PPCOperand::CreateImm(Val: IntVal, S, E, IsPPC64: isPPC64())); |
1553 | return false; |
1554 | } |
1555 | case AsmToken::Identifier: |
1556 | case AsmToken::LParen: |
1557 | case AsmToken::Plus: |
1558 | case AsmToken::Minus: |
1559 | case AsmToken::Integer: |
1560 | case AsmToken::Dot: |
1561 | case AsmToken::Dollar: |
1562 | case AsmToken::Exclaim: |
1563 | case AsmToken::Tilde: |
1564 | if (!ParseExpression(EVal)) |
1565 | break; |
1566 | // Fall-through |
1567 | [[fallthrough]]; |
1568 | default: |
1569 | return Error(L: S, Msg: "unknown operand" ); |
1570 | } |
1571 | |
1572 | // Push the parsed operand into the list of operands |
1573 | Operands.push_back(Elt: PPCOperand::CreateFromMCExpr(Val: EVal, S, E, IsPPC64: isPPC64())); |
1574 | |
1575 | // Check whether this is a TLS call expression |
1576 | const char TlsGetAddr[] = "__tls_get_addr" ; |
1577 | bool TlsCall = false; |
1578 | const MCExpr *TlsCallAddend = nullptr; |
1579 | if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Val: EVal)) { |
1580 | TlsCall = Ref->getSymbol().getName() == TlsGetAddr; |
1581 | } else if (auto *Bin = dyn_cast<MCBinaryExpr>(Val: EVal); |
1582 | Bin && Bin->getOpcode() == MCBinaryExpr::Add) { |
1583 | if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Val: Bin->getLHS())) { |
1584 | TlsCall = Ref->getSymbol().getName() == TlsGetAddr; |
1585 | TlsCallAddend = Bin->getRHS(); |
1586 | } |
1587 | } |
1588 | |
1589 | if (TlsCall && parseOptionalToken(T: AsmToken::LParen)) { |
1590 | const MCExpr *TLSSym; |
1591 | const SMLoc S2 = Parser.getTok().getLoc(); |
1592 | if (ParseExpression(EVal&: TLSSym)) |
1593 | return Error(L: S2, Msg: "invalid TLS call expression" ); |
1594 | E = Parser.getTok().getLoc(); |
1595 | if (parseToken(T: AsmToken::RParen, Msg: "expected ')'" )) |
1596 | return true; |
1597 | // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]". |
1598 | if (!isPPC64() && parseOptionalToken(T: AsmToken::At)) { |
1599 | AsmToken Tok = getTok(); |
1600 | if (!(parseOptionalToken(T: AsmToken::Identifier) && |
1601 | Tok.getString().compare_insensitive(RHS: "plt" ) == 0)) |
1602 | return Error(L: Tok.getLoc(), Msg: "expected 'plt'" ); |
1603 | EVal = MCSymbolRefExpr::create(Name: TlsGetAddr, Kind: MCSymbolRefExpr::VK_PLT, |
1604 | Ctx&: getContext()); |
1605 | if (parseOptionalToken(T: AsmToken::Plus)) { |
1606 | const MCExpr *Addend = nullptr; |
1607 | SMLoc EndLoc; |
1608 | if (parsePrimaryExpr(Res&: Addend, EndLoc)) |
1609 | return true; |
1610 | if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b |
1611 | TlsCallAddend = |
1612 | MCBinaryExpr::createAdd(LHS: TlsCallAddend, RHS: Addend, Ctx&: getContext()); |
1613 | else // __tls_get_addr(x@tlsgd)@plt+b |
1614 | TlsCallAddend = Addend; |
1615 | } |
1616 | if (TlsCallAddend) |
1617 | EVal = MCBinaryExpr::createAdd(LHS: EVal, RHS: TlsCallAddend, Ctx&: getContext()); |
1618 | // Add a __tls_get_addr operand with addend a, b, or a+b. |
1619 | Operands.back() = PPCOperand::CreateFromMCExpr( |
1620 | Val: EVal, S, E: Parser.getTok().getLoc(), IsPPC64: false); |
1621 | } |
1622 | |
1623 | Operands.push_back(Elt: PPCOperand::CreateFromMCExpr(Val: TLSSym, S, E, IsPPC64: isPPC64())); |
1624 | } |
1625 | |
1626 | // Otherwise, check for D-form memory operands |
1627 | if (!TlsCall && parseOptionalToken(T: AsmToken::LParen)) { |
1628 | S = Parser.getTok().getLoc(); |
1629 | |
1630 | int64_t IntVal; |
1631 | switch (getLexer().getKind()) { |
1632 | case AsmToken::Percent: { |
1633 | MCRegister RegNo; |
1634 | if (MatchRegisterName(RegNo, IntVal)) |
1635 | return Error(L: S, Msg: "invalid register name" ); |
1636 | break; |
1637 | } |
1638 | case AsmToken::Integer: |
1639 | if (getParser().parseAbsoluteExpression(Res&: IntVal) || IntVal < 0 || |
1640 | IntVal > 31) |
1641 | return Error(L: S, Msg: "invalid register number" ); |
1642 | break; |
1643 | case AsmToken::Identifier: |
1644 | default: |
1645 | return Error(L: S, Msg: "invalid memory operand" ); |
1646 | } |
1647 | |
1648 | E = Parser.getTok().getLoc(); |
1649 | if (parseToken(T: AsmToken::RParen, Msg: "missing ')'" )) |
1650 | return true; |
1651 | Operands.push_back(Elt: PPCOperand::CreateImm(Val: IntVal, S, E, IsPPC64: isPPC64())); |
1652 | } |
1653 | |
1654 | return false; |
1655 | } |
1656 | |
1657 | /// Parse an instruction mnemonic followed by its operands. |
1658 | bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, |
1659 | SMLoc NameLoc, OperandVector &Operands) { |
1660 | // The first operand is the token for the instruction name. |
1661 | // If the next character is a '+' or '-', we need to add it to the |
1662 | // instruction name, to match what TableGen is doing. |
1663 | std::string NewOpcode; |
1664 | if (parseOptionalToken(T: AsmToken::Plus)) { |
1665 | NewOpcode = std::string(Name); |
1666 | NewOpcode += '+'; |
1667 | Name = NewOpcode; |
1668 | } |
1669 | if (parseOptionalToken(T: AsmToken::Minus)) { |
1670 | NewOpcode = std::string(Name); |
1671 | NewOpcode += '-'; |
1672 | Name = NewOpcode; |
1673 | } |
1674 | // If the instruction ends in a '.', we need to create a separate |
1675 | // token for it, to match what TableGen is doing. |
1676 | size_t Dot = Name.find(C: '.'); |
1677 | StringRef Mnemonic = Name.slice(Start: 0, End: Dot); |
1678 | if (!NewOpcode.empty()) // Underlying memory for Name is volatile. |
1679 | Operands.push_back( |
1680 | Elt: PPCOperand::CreateTokenWithStringCopy(Str: Mnemonic, S: NameLoc, IsPPC64: isPPC64())); |
1681 | else |
1682 | Operands.push_back(Elt: PPCOperand::CreateToken(Str: Mnemonic, S: NameLoc, IsPPC64: isPPC64())); |
1683 | if (Dot != StringRef::npos) { |
1684 | SMLoc DotLoc = SMLoc::getFromPointer(Ptr: NameLoc.getPointer() + Dot); |
1685 | StringRef DotStr = Name.slice(Start: Dot, End: StringRef::npos); |
1686 | if (!NewOpcode.empty()) // Underlying memory for Name is volatile. |
1687 | Operands.push_back( |
1688 | Elt: PPCOperand::CreateTokenWithStringCopy(Str: DotStr, S: DotLoc, IsPPC64: isPPC64())); |
1689 | else |
1690 | Operands.push_back(Elt: PPCOperand::CreateToken(Str: DotStr, S: DotLoc, IsPPC64: isPPC64())); |
1691 | } |
1692 | |
1693 | // If there are no more operands then finish |
1694 | if (parseOptionalToken(T: AsmToken::EndOfStatement)) |
1695 | return false; |
1696 | |
1697 | // Parse the first operand |
1698 | if (ParseOperand(Operands)) |
1699 | return true; |
1700 | |
1701 | while (!parseOptionalToken(T: AsmToken::EndOfStatement)) { |
1702 | if (parseToken(T: AsmToken::Comma) || ParseOperand(Operands)) |
1703 | return true; |
1704 | } |
1705 | |
1706 | // We'll now deal with an unfortunate special case: the syntax for the dcbt |
1707 | // and dcbtst instructions differs for server vs. embedded cores. |
1708 | // The syntax for dcbt is: |
1709 | // dcbt ra, rb, th [server] |
1710 | // dcbt th, ra, rb [embedded] |
1711 | // where th can be omitted when it is 0. dcbtst is the same. We take the |
1712 | // server form to be the default, so swap the operands if we're parsing for |
1713 | // an embedded core (they'll be swapped again upon printing). |
1714 | if (getSTI().hasFeature(Feature: PPC::FeatureBookE) && |
1715 | Operands.size() == 4 && |
1716 | (Name == "dcbt" || Name == "dcbtst" )) { |
1717 | std::swap(x&: Operands[1], y&: Operands[3]); |
1718 | std::swap(x&: Operands[2], y&: Operands[1]); |
1719 | } |
1720 | |
1721 | // Handle base mnemonic for atomic loads where the EH bit is zero. |
1722 | if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" || |
1723 | Name == "lharx" || Name == "lbarx" ) { |
1724 | if (Operands.size() != 5) |
1725 | return false; |
1726 | PPCOperand &EHOp = (PPCOperand &)*Operands[4]; |
1727 | if (EHOp.isU1Imm() && EHOp.getImm() == 0) |
1728 | Operands.pop_back(); |
1729 | } |
1730 | |
1731 | return false; |
1732 | } |
1733 | |
1734 | /// ParseDirective parses the PPC specific directives |
1735 | bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) { |
1736 | StringRef IDVal = DirectiveID.getIdentifier(); |
1737 | if (IDVal == ".word" ) |
1738 | ParseDirectiveWord(Size: 2, ID: DirectiveID); |
1739 | else if (IDVal == ".llong" ) |
1740 | ParseDirectiveWord(Size: 8, ID: DirectiveID); |
1741 | else if (IDVal == ".tc" ) |
1742 | ParseDirectiveTC(Size: isPPC64() ? 8 : 4, ID: DirectiveID); |
1743 | else if (IDVal == ".machine" ) |
1744 | ParseDirectiveMachine(L: DirectiveID.getLoc()); |
1745 | else if (IDVal == ".abiversion" ) |
1746 | ParseDirectiveAbiVersion(L: DirectiveID.getLoc()); |
1747 | else if (IDVal == ".localentry" ) |
1748 | ParseDirectiveLocalEntry(L: DirectiveID.getLoc()); |
1749 | else if (IDVal.starts_with(Prefix: ".gnu_attribute" )) |
1750 | ParseGNUAttribute(L: DirectiveID.getLoc()); |
1751 | else |
1752 | return true; |
1753 | return false; |
1754 | } |
1755 | |
1756 | /// ParseDirectiveWord |
1757 | /// ::= .word [ expression (, expression)* ] |
1758 | bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) { |
1759 | auto parseOp = [&]() -> bool { |
1760 | const MCExpr *Value; |
1761 | SMLoc ExprLoc = getParser().getTok().getLoc(); |
1762 | if (getParser().parseExpression(Res&: Value)) |
1763 | return true; |
1764 | if (const auto *MCE = dyn_cast<MCConstantExpr>(Val: Value)) { |
1765 | assert(Size <= 8 && "Invalid size" ); |
1766 | uint64_t IntValue = MCE->getValue(); |
1767 | if (!isUIntN(N: 8 * Size, x: IntValue) && !isIntN(N: 8 * Size, x: IntValue)) |
1768 | return Error(L: ExprLoc, Msg: "literal value out of range for '" + |
1769 | ID.getIdentifier() + "' directive" ); |
1770 | getStreamer().emitIntValue(Value: IntValue, Size); |
1771 | } else |
1772 | getStreamer().emitValue(Value, Size, Loc: ExprLoc); |
1773 | return false; |
1774 | }; |
1775 | |
1776 | if (parseMany(parseOne: parseOp)) |
1777 | return addErrorSuffix(Suffix: " in '" + ID.getIdentifier() + "' directive" ); |
1778 | return false; |
1779 | } |
1780 | |
1781 | /// ParseDirectiveTC |
1782 | /// ::= .tc [ symbol (, expression)* ] |
1783 | bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) { |
1784 | MCAsmParser &Parser = getParser(); |
1785 | // Skip TC symbol, which is only used with XCOFF. |
1786 | while (getLexer().isNot(K: AsmToken::EndOfStatement) |
1787 | && getLexer().isNot(K: AsmToken::Comma)) |
1788 | Parser.Lex(); |
1789 | if (parseToken(T: AsmToken::Comma)) |
1790 | return addErrorSuffix(Suffix: " in '.tc' directive" ); |
1791 | |
1792 | // Align to word size. |
1793 | getParser().getStreamer().emitValueToAlignment(Alignment: Align(Size)); |
1794 | |
1795 | // Emit expressions. |
1796 | return ParseDirectiveWord(Size, ID); |
1797 | } |
1798 | |
1799 | /// ParseDirectiveMachine (ELF platforms) |
1800 | /// ::= .machine [ cpu | "push" | "pop" ] |
1801 | bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) { |
1802 | MCAsmParser &Parser = getParser(); |
1803 | if (Parser.getTok().isNot(K: AsmToken::Identifier) && |
1804 | Parser.getTok().isNot(K: AsmToken::String)) |
1805 | return Error(L, Msg: "unexpected token in '.machine' directive" ); |
1806 | |
1807 | StringRef CPU = Parser.getTok().getIdentifier(); |
1808 | |
1809 | // FIXME: Right now, the parser always allows any available |
1810 | // instruction, so the .machine directive is not useful. |
1811 | // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen. |
1812 | |
1813 | Parser.Lex(); |
1814 | |
1815 | if (parseToken(T: AsmToken::EndOfStatement)) |
1816 | return addErrorSuffix(Suffix: " in '.machine' directive" ); |
1817 | |
1818 | PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>( |
1819 | getParser().getStreamer().getTargetStreamer()); |
1820 | if (TStreamer != nullptr) |
1821 | TStreamer->emitMachine(CPU); |
1822 | |
1823 | return false; |
1824 | } |
1825 | |
1826 | /// ParseDirectiveAbiVersion |
1827 | /// ::= .abiversion constant-expression |
1828 | bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) { |
1829 | int64_t AbiVersion; |
1830 | if (check(P: getParser().parseAbsoluteExpression(Res&: AbiVersion), Loc: L, |
1831 | Msg: "expected constant expression" ) || |
1832 | parseToken(T: AsmToken::EndOfStatement)) |
1833 | return addErrorSuffix(Suffix: " in '.abiversion' directive" ); |
1834 | |
1835 | PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>( |
1836 | getParser().getStreamer().getTargetStreamer()); |
1837 | if (TStreamer != nullptr) |
1838 | TStreamer->emitAbiVersion(AbiVersion); |
1839 | |
1840 | return false; |
1841 | } |
1842 | |
1843 | /// ParseDirectiveLocalEntry |
1844 | /// ::= .localentry symbol, expression |
1845 | bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) { |
1846 | StringRef Name; |
1847 | if (getParser().parseIdentifier(Res&: Name)) |
1848 | return Error(L, Msg: "expected identifier in '.localentry' directive" ); |
1849 | |
1850 | MCSymbolELF *Sym = cast<MCSymbolELF>(Val: getContext().getOrCreateSymbol(Name)); |
1851 | const MCExpr *Expr; |
1852 | |
1853 | if (parseToken(T: AsmToken::Comma) || |
1854 | check(P: getParser().parseExpression(Res&: Expr), Loc: L, Msg: "expected expression" ) || |
1855 | parseToken(T: AsmToken::EndOfStatement)) |
1856 | return addErrorSuffix(Suffix: " in '.localentry' directive" ); |
1857 | |
1858 | PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>( |
1859 | getParser().getStreamer().getTargetStreamer()); |
1860 | if (TStreamer != nullptr) |
1861 | TStreamer->emitLocalEntry(S: Sym, LocalOffset: Expr); |
1862 | |
1863 | return false; |
1864 | } |
1865 | |
1866 | bool PPCAsmParser::ParseGNUAttribute(SMLoc L) { |
1867 | int64_t Tag; |
1868 | int64_t IntegerValue; |
1869 | if (!getParser().parseGNUAttribute(L, Tag, IntegerValue)) |
1870 | return false; |
1871 | |
1872 | getParser().getStreamer().emitGNUAttribute(Tag, Value: IntegerValue); |
1873 | |
1874 | return true; |
1875 | } |
1876 | |
1877 | /// Force static initialization. |
1878 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() { |
1879 | RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target()); |
1880 | RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget()); |
1881 | RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target()); |
1882 | RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget()); |
1883 | } |
1884 | |
1885 | #define GET_REGISTER_MATCHER |
1886 | #define GET_MATCHER_IMPLEMENTATION |
1887 | #define GET_MNEMONIC_SPELL_CHECKER |
1888 | #include "PPCGenAsmMatcher.inc" |
1889 | |
1890 | // Define this matcher function after the auto-generated include so we |
1891 | // have the match class enum definitions. |
1892 | unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, |
1893 | unsigned Kind) { |
1894 | // If the kind is a token for a literal immediate, check if our asm |
1895 | // operand matches. This is for InstAliases which have a fixed-value |
1896 | // immediate in the syntax. |
1897 | int64_t ImmVal; |
1898 | switch (Kind) { |
1899 | case MCK_0: ImmVal = 0; break; |
1900 | case MCK_1: ImmVal = 1; break; |
1901 | case MCK_2: ImmVal = 2; break; |
1902 | case MCK_3: ImmVal = 3; break; |
1903 | case MCK_4: ImmVal = 4; break; |
1904 | case MCK_5: ImmVal = 5; break; |
1905 | case MCK_6: ImmVal = 6; break; |
1906 | case MCK_7: ImmVal = 7; break; |
1907 | default: return Match_InvalidOperand; |
1908 | } |
1909 | |
1910 | PPCOperand &Op = static_cast<PPCOperand &>(AsmOp); |
1911 | if (Op.isU3Imm() && Op.getImm() == ImmVal) |
1912 | return Match_Success; |
1913 | |
1914 | return Match_InvalidOperand; |
1915 | } |
1916 | |
1917 | const MCExpr * |
1918 | PPCAsmParser::applyModifierToExpr(const MCExpr *E, |
1919 | MCSymbolRefExpr::VariantKind Variant, |
1920 | MCContext &Ctx) { |
1921 | switch (Variant) { |
1922 | case MCSymbolRefExpr::VK_PPC_LO: |
1923 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_LO, Expr: E, Ctx); |
1924 | case MCSymbolRefExpr::VK_PPC_HI: |
1925 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HI, Expr: E, Ctx); |
1926 | case MCSymbolRefExpr::VK_PPC_HA: |
1927 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HA, Expr: E, Ctx); |
1928 | case MCSymbolRefExpr::VK_PPC_HIGH: |
1929 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGH, Expr: E, Ctx); |
1930 | case MCSymbolRefExpr::VK_PPC_HIGHA: |
1931 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGHA, Expr: E, Ctx); |
1932 | case MCSymbolRefExpr::VK_PPC_HIGHER: |
1933 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGHER, Expr: E, Ctx); |
1934 | case MCSymbolRefExpr::VK_PPC_HIGHERA: |
1935 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGHERA, Expr: E, Ctx); |
1936 | case MCSymbolRefExpr::VK_PPC_HIGHEST: |
1937 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGHEST, Expr: E, Ctx); |
1938 | case MCSymbolRefExpr::VK_PPC_HIGHESTA: |
1939 | return PPCMCExpr::create(Kind: PPCMCExpr::VK_PPC_HIGHESTA, Expr: E, Ctx); |
1940 | default: |
1941 | return nullptr; |
1942 | } |
1943 | } |
1944 | |