Bug Summary

File:llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
Warning:line 564, column 21
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name PPCAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/PowerPC/AsmParser -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/PowerPC/AsmParser -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/PowerPC/AsmParser -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/PowerPC -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/PowerPC -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/PowerPC/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
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
30using namespace llvm;
31
32DEFINE_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.
37static int64_t
38EvaluateCRExpr(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
95namespace {
96
97struct PPCOperand;
98
99class 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
141public:
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.
167struct 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) {}
205public:
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);
2
Returning the value 4294967239
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()]));
1
Calling 'PPCOperand::getCRBitMask'
3
Returning from 'PPCOperand::getCRBitMask'
4
1st function call argument is an uninitialized value
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
717void 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
735static void
736addNegOperand(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
758void 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
1160static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
1161 unsigned VariantID = 0);
1162
1163bool 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
1202bool 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
1240bool PPCAsmParser::
1241ParseRegister(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
1247OperandMatchResultTy 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.
1266const MCExpr *PPCAsmParser::
1267ExtractModifierFromExpr(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.
1355const MCExpr *PPCAsmParser::
1356FixupVariantKind(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.
1404bool PPCAsmParser::
1405ParseExpression(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.
1424bool 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.
1516bool 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
1583bool 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)* ]
1604bool 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)* ]
1629bool 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" ]
1647bool 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
1674bool 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
1691bool 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.
1715extern "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.
1729unsigned 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
1754const MCExpr *
1755PPCAsmParser::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}