blob: 8b3eac2e691eaf7a5dcf0c441c85d11c90b58a9e [file] [log] [blame]
Eric Christopher87590fa2016-06-16 01:00:53 +00001//===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//
Ulrich Weigand640192d2013-05-03 19:49:39 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Ulrich Weigand96e65782013-06-20 16:23:52 +000010#include "MCTargetDesc/PPCMCExpr.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000011#include "MCTargetDesc/PPCMCTargetDesc.h"
Rafael Espindola6b9ee9b2014-01-25 02:35:56 +000012#include "PPCTargetStreamer.h"
Craig Topper690d8ea2013-07-24 07:33:14 +000013#include "llvm/ADT/STLExtras.h"
Ulrich Weigand640192d2013-05-03 19:49:39 +000014#include "llvm/ADT/StringSwitch.h"
15#include "llvm/ADT/Twine.h"
Ulrich Weigandbb686102014-07-20 23:06:03 +000016#include "llvm/MC/MCContext.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000017#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCInstrInfo.h"
20#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCAsmParser.h"
22#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000023#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000024#include "llvm/MC/MCRegisterInfo.h"
25#include "llvm/MC/MCStreamer.h"
26#include "llvm/MC/MCSubtargetInfo.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000027#include "llvm/MC/MCSymbolELF.h"
Ulrich Weigand640192d2013-05-03 19:49:39 +000028#include "llvm/Support/SourceMgr.h"
29#include "llvm/Support/TargetRegistry.h"
30#include "llvm/Support/raw_ostream.h"
31
32using namespace llvm;
33
Craig Topperf7df7222014-12-18 05:02:14 +000034static const MCPhysReg RRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000035 PPC::R0, PPC::R1, PPC::R2, PPC::R3,
36 PPC::R4, PPC::R5, PPC::R6, PPC::R7,
37 PPC::R8, PPC::R9, PPC::R10, PPC::R11,
38 PPC::R12, PPC::R13, PPC::R14, PPC::R15,
39 PPC::R16, PPC::R17, PPC::R18, PPC::R19,
40 PPC::R20, PPC::R21, PPC::R22, PPC::R23,
41 PPC::R24, PPC::R25, PPC::R26, PPC::R27,
42 PPC::R28, PPC::R29, PPC::R30, PPC::R31
43};
Craig Topperf7df7222014-12-18 05:02:14 +000044static const MCPhysReg RRegsNoR0[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000045 PPC::ZERO,
46 PPC::R1, PPC::R2, PPC::R3,
47 PPC::R4, PPC::R5, PPC::R6, PPC::R7,
48 PPC::R8, PPC::R9, PPC::R10, PPC::R11,
49 PPC::R12, PPC::R13, PPC::R14, PPC::R15,
50 PPC::R16, PPC::R17, PPC::R18, PPC::R19,
51 PPC::R20, PPC::R21, PPC::R22, PPC::R23,
52 PPC::R24, PPC::R25, PPC::R26, PPC::R27,
53 PPC::R28, PPC::R29, PPC::R30, PPC::R31
54};
Craig Topperf7df7222014-12-18 05:02:14 +000055static const MCPhysReg XRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000056 PPC::X0, PPC::X1, PPC::X2, PPC::X3,
57 PPC::X4, PPC::X5, PPC::X6, PPC::X7,
58 PPC::X8, PPC::X9, PPC::X10, PPC::X11,
59 PPC::X12, PPC::X13, PPC::X14, PPC::X15,
60 PPC::X16, PPC::X17, PPC::X18, PPC::X19,
61 PPC::X20, PPC::X21, PPC::X22, PPC::X23,
62 PPC::X24, PPC::X25, PPC::X26, PPC::X27,
63 PPC::X28, PPC::X29, PPC::X30, PPC::X31
64};
Craig Topperf7df7222014-12-18 05:02:14 +000065static const MCPhysReg XRegsNoX0[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000066 PPC::ZERO8,
67 PPC::X1, PPC::X2, PPC::X3,
68 PPC::X4, PPC::X5, PPC::X6, PPC::X7,
69 PPC::X8, PPC::X9, PPC::X10, PPC::X11,
70 PPC::X12, PPC::X13, PPC::X14, PPC::X15,
71 PPC::X16, PPC::X17, PPC::X18, PPC::X19,
72 PPC::X20, PPC::X21, PPC::X22, PPC::X23,
73 PPC::X24, PPC::X25, PPC::X26, PPC::X27,
74 PPC::X28, PPC::X29, PPC::X30, PPC::X31
75};
Craig Topperf7df7222014-12-18 05:02:14 +000076static const MCPhysReg FRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000077 PPC::F0, PPC::F1, PPC::F2, PPC::F3,
78 PPC::F4, PPC::F5, PPC::F6, PPC::F7,
79 PPC::F8, PPC::F9, PPC::F10, PPC::F11,
80 PPC::F12, PPC::F13, PPC::F14, PPC::F15,
81 PPC::F16, PPC::F17, PPC::F18, PPC::F19,
82 PPC::F20, PPC::F21, PPC::F22, PPC::F23,
83 PPC::F24, PPC::F25, PPC::F26, PPC::F27,
84 PPC::F28, PPC::F29, PPC::F30, PPC::F31
85};
Nemanja Ivanovic11049f82016-10-04 06:59:23 +000086static const MCPhysReg VFRegs[32] = {
87 PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
88 PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
89 PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
90 PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
91 PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
92 PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
93 PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
94 PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
95};
Craig Topperf7df7222014-12-18 05:02:14 +000096static const MCPhysReg VRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000097 PPC::V0, PPC::V1, PPC::V2, PPC::V3,
98 PPC::V4, PPC::V5, PPC::V6, PPC::V7,
99 PPC::V8, PPC::V9, PPC::V10, PPC::V11,
100 PPC::V12, PPC::V13, PPC::V14, PPC::V15,
101 PPC::V16, PPC::V17, PPC::V18, PPC::V19,
102 PPC::V20, PPC::V21, PPC::V22, PPC::V23,
103 PPC::V24, PPC::V25, PPC::V26, PPC::V27,
104 PPC::V28, PPC::V29, PPC::V30, PPC::V31
105};
Craig Topperf7df7222014-12-18 05:02:14 +0000106static const MCPhysReg VSRegs[64] = {
Hal Finkel27774d92014-03-13 07:58:58 +0000107 PPC::VSL0, PPC::VSL1, PPC::VSL2, PPC::VSL3,
108 PPC::VSL4, PPC::VSL5, PPC::VSL6, PPC::VSL7,
109 PPC::VSL8, PPC::VSL9, PPC::VSL10, PPC::VSL11,
110 PPC::VSL12, PPC::VSL13, PPC::VSL14, PPC::VSL15,
111 PPC::VSL16, PPC::VSL17, PPC::VSL18, PPC::VSL19,
112 PPC::VSL20, PPC::VSL21, PPC::VSL22, PPC::VSL23,
113 PPC::VSL24, PPC::VSL25, PPC::VSL26, PPC::VSL27,
114 PPC::VSL28, PPC::VSL29, PPC::VSL30, PPC::VSL31,
115
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000116 PPC::V0, PPC::V1, PPC::V2, PPC::V3,
117 PPC::V4, PPC::V5, PPC::V6, PPC::V7,
118 PPC::V8, PPC::V9, PPC::V10, PPC::V11,
119 PPC::V12, PPC::V13, PPC::V14, PPC::V15,
120 PPC::V16, PPC::V17, PPC::V18, PPC::V19,
121 PPC::V20, PPC::V21, PPC::V22, PPC::V23,
122 PPC::V24, PPC::V25, PPC::V26, PPC::V27,
123 PPC::V28, PPC::V29, PPC::V30, PPC::V31
Hal Finkel27774d92014-03-13 07:58:58 +0000124};
Craig Topperf7df7222014-12-18 05:02:14 +0000125static const MCPhysReg VSFRegs[64] = {
Hal Finkel19be5062014-03-29 05:29:01 +0000126 PPC::F0, PPC::F1, PPC::F2, PPC::F3,
127 PPC::F4, PPC::F5, PPC::F6, PPC::F7,
128 PPC::F8, PPC::F9, PPC::F10, PPC::F11,
129 PPC::F12, PPC::F13, PPC::F14, PPC::F15,
130 PPC::F16, PPC::F17, PPC::F18, PPC::F19,
131 PPC::F20, PPC::F21, PPC::F22, PPC::F23,
132 PPC::F24, PPC::F25, PPC::F26, PPC::F27,
133 PPC::F28, PPC::F29, PPC::F30, PPC::F31,
134
135 PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
136 PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
137 PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
138 PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
139 PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
140 PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
141 PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
142 PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
143};
Nemanja Ivanovicf3c94b12015-05-07 18:24:05 +0000144static const MCPhysReg VSSRegs[64] = {
145 PPC::F0, PPC::F1, PPC::F2, PPC::F3,
146 PPC::F4, PPC::F5, PPC::F6, PPC::F7,
147 PPC::F8, PPC::F9, PPC::F10, PPC::F11,
148 PPC::F12, PPC::F13, PPC::F14, PPC::F15,
149 PPC::F16, PPC::F17, PPC::F18, PPC::F19,
150 PPC::F20, PPC::F21, PPC::F22, PPC::F23,
151 PPC::F24, PPC::F25, PPC::F26, PPC::F27,
152 PPC::F28, PPC::F29, PPC::F30, PPC::F31,
153
154 PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
155 PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
156 PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
157 PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
158 PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
159 PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
160 PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
161 PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
162};
Hal Finkelc93a9a22015-02-25 01:06:45 +0000163static unsigned QFRegs[32] = {
164 PPC::QF0, PPC::QF1, PPC::QF2, PPC::QF3,
165 PPC::QF4, PPC::QF5, PPC::QF6, PPC::QF7,
166 PPC::QF8, PPC::QF9, PPC::QF10, PPC::QF11,
167 PPC::QF12, PPC::QF13, PPC::QF14, PPC::QF15,
168 PPC::QF16, PPC::QF17, PPC::QF18, PPC::QF19,
169 PPC::QF20, PPC::QF21, PPC::QF22, PPC::QF23,
170 PPC::QF24, PPC::QF25, PPC::QF26, PPC::QF27,
171 PPC::QF28, PPC::QF29, PPC::QF30, PPC::QF31
172};
Craig Topperf7df7222014-12-18 05:02:14 +0000173static const MCPhysReg CRBITRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000174 PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN,
175 PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN,
176 PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN,
177 PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN,
178 PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN,
179 PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN,
180 PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN,
181 PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN
182};
Craig Topperf7df7222014-12-18 05:02:14 +0000183static const MCPhysReg CRRegs[8] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000184 PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
185 PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
186};
187
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000188// Evaluate an expression containing condition register
189// or condition register field symbols. Returns positive
190// value on success, or -1 on error.
191static int64_t
192EvaluateCRExpr(const MCExpr *E) {
193 switch (E->getKind()) {
194 case MCExpr::Target:
195 return -1;
196
197 case MCExpr::Constant: {
198 int64_t Res = cast<MCConstantExpr>(E)->getValue();
199 return Res < 0 ? -1 : Res;
200 }
201
202 case MCExpr::SymbolRef: {
203 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
204 StringRef Name = SRE->getSymbol().getName();
205
206 if (Name == "lt") return 0;
207 if (Name == "gt") return 1;
208 if (Name == "eq") return 2;
209 if (Name == "so") return 3;
210 if (Name == "un") return 3;
211
212 if (Name == "cr0") return 0;
213 if (Name == "cr1") return 1;
214 if (Name == "cr2") return 2;
215 if (Name == "cr3") return 3;
216 if (Name == "cr4") return 4;
217 if (Name == "cr5") return 5;
218 if (Name == "cr6") return 6;
219 if (Name == "cr7") return 7;
220
221 return -1;
222 }
223
224 case MCExpr::Unary:
225 return -1;
226
227 case MCExpr::Binary: {
228 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
229 int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
230 int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
231 int64_t Res;
232
233 if (LHSVal < 0 || RHSVal < 0)
234 return -1;
235
236 switch (BE->getOpcode()) {
237 default: return -1;
238 case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
239 case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
240 }
241
242 return Res < 0 ? -1 : Res;
243 }
244 }
245
246 llvm_unreachable("Invalid expression kind!");
247}
248
Craig Topperf7df7222014-12-18 05:02:14 +0000249namespace {
250
Ulrich Weigand640192d2013-05-03 19:49:39 +0000251struct PPCOperand;
252
253class PPCAsmParser : public MCTargetAsmParser {
Hal Finkel0096dbd2013-09-12 14:40:06 +0000254 const MCInstrInfo &MII;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000255 bool IsPPC64;
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000256 bool IsDarwin;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000257
Rafael Espindola961d4692014-11-11 05:18:41 +0000258 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
259 bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000260
261 bool isPPC64() const { return IsPPC64; }
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000262 bool isDarwin() const { return IsDarwin; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000263
264 bool MatchRegisterName(const AsmToken &Tok,
265 unsigned &RegNo, int64_t &IntVal);
266
Craig Topper0d3fa922014-04-29 07:57:37 +0000267 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000268
Ulrich Weigand96e65782013-06-20 16:23:52 +0000269 const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
270 PPCMCExpr::VariantKind &Variant);
Ulrich Weigand52cf8e42013-07-09 16:41:09 +0000271 const MCExpr *FixupVariantKind(const MCExpr *E);
Ulrich Weigand96e65782013-06-20 16:23:52 +0000272 bool ParseExpression(const MCExpr *&EVal);
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000273 bool ParseDarwinExpression(const MCExpr *&EVal);
Ulrich Weigand96e65782013-06-20 16:23:52 +0000274
David Blaikie960ea3f2014-06-08 16:18:35 +0000275 bool ParseOperand(OperandVector &Operands);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000276
277 bool ParseDirectiveWord(unsigned Size, SMLoc L);
278 bool ParseDirectiveTC(unsigned Size, SMLoc L);
Ulrich Weigand55daa772013-07-09 10:00:34 +0000279 bool ParseDirectiveMachine(SMLoc L);
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000280 bool ParseDarwinDirectiveMachine(SMLoc L);
Ulrich Weigand0daa5162014-07-20 22:56:57 +0000281 bool ParseDirectiveAbiVersion(SMLoc L);
Ulrich Weigandbb686102014-07-20 23:06:03 +0000282 bool ParseDirectiveLocalEntry(SMLoc L);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000283
284 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +0000285 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000286 uint64_t &ErrorInfo,
Craig Topper0d3fa922014-04-29 07:57:37 +0000287 bool MatchingInlineAsm) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000288
David Blaikie960ea3f2014-06-08 16:18:35 +0000289 void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
Ulrich Weigandd8394902013-05-03 19:50:27 +0000290
Ulrich Weigand640192d2013-05-03 19:49:39 +0000291 /// @name Auto-generated Match Functions
292 /// {
293
294#define GET_ASSEMBLER_HEADER
295#include "PPCGenAsmMatcher.inc"
296
297 /// }
298
299
300public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000301 PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000302 const MCInstrInfo &MII, const MCTargetOptions &Options)
303 : MCTargetAsmParser(Options, STI), MII(MII) {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000304 // Check for 64-bit vs. 32-bit pointer mode.
Benjamin Kramer4fed9282016-05-27 12:30:51 +0000305 const Triple &TheTriple = STI.getTargetTriple();
Daniel Sanders50f17232015-09-15 16:17:27 +0000306 IsPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
307 TheTriple.getArch() == Triple::ppc64le);
308 IsDarwin = TheTriple.isMacOSX();
Ulrich Weigand640192d2013-05-03 19:49:39 +0000309 // Initialize the set of available features.
310 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
311 }
312
David Blaikie960ea3f2014-06-08 16:18:35 +0000313 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
314 SMLoc NameLoc, OperandVector &Operands) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000315
Craig Topper0d3fa922014-04-29 07:57:37 +0000316 bool ParseDirective(AsmToken DirectiveID) override;
Ulrich Weigandc0944b52013-07-08 14:49:37 +0000317
David Blaikie960ea3f2014-06-08 16:18:35 +0000318 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
Craig Topper0d3fa922014-04-29 07:57:37 +0000319 unsigned Kind) override;
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +0000320
Craig Topper0d3fa922014-04-29 07:57:37 +0000321 const MCExpr *applyModifierToExpr(const MCExpr *E,
322 MCSymbolRefExpr::VariantKind,
323 MCContext &Ctx) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000324};
325
326/// PPCOperand - Instances of this class represent a parsed PowerPC machine
327/// instruction.
328struct PPCOperand : public MCParsedAsmOperand {
329 enum KindTy {
330 Token,
331 Immediate,
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000332 ContextImmediate,
Ulrich Weigand5b427592013-07-05 12:22:36 +0000333 Expression,
334 TLSRegister
Ulrich Weigand640192d2013-05-03 19:49:39 +0000335 } Kind;
336
337 SMLoc StartLoc, EndLoc;
338 bool IsPPC64;
339
340 struct TokOp {
341 const char *Data;
342 unsigned Length;
343 };
344
345 struct ImmOp {
346 int64_t Val;
347 };
348
349 struct ExprOp {
350 const MCExpr *Val;
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000351 int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
Ulrich Weigand640192d2013-05-03 19:49:39 +0000352 };
353
Ulrich Weigand5b427592013-07-05 12:22:36 +0000354 struct TLSRegOp {
355 const MCSymbolRefExpr *Sym;
356 };
357
Ulrich Weigand640192d2013-05-03 19:49:39 +0000358 union {
359 struct TokOp Tok;
360 struct ImmOp Imm;
361 struct ExprOp Expr;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000362 struct TLSRegOp TLSReg;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000363 };
364
365 PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
366public:
367 PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
368 Kind = o.Kind;
369 StartLoc = o.StartLoc;
370 EndLoc = o.EndLoc;
371 IsPPC64 = o.IsPPC64;
372 switch (Kind) {
373 case Token:
374 Tok = o.Tok;
375 break;
376 case Immediate:
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000377 case ContextImmediate:
Ulrich Weigand640192d2013-05-03 19:49:39 +0000378 Imm = o.Imm;
379 break;
380 case Expression:
381 Expr = o.Expr;
382 break;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000383 case TLSRegister:
384 TLSReg = o.TLSReg;
385 break;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000386 }
387 }
388
Richard Smithc2a28302016-03-08 00:59:44 +0000389 // Disable use of sized deallocation due to overallocation of PPCOperand
390 // objects in CreateTokenWithStringCopy.
391 void operator delete(void *p) { ::operator delete(p); }
392
Ulrich Weigand640192d2013-05-03 19:49:39 +0000393 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper0d3fa922014-04-29 07:57:37 +0000394 SMLoc getStartLoc() const override { return StartLoc; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000395
396 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbournecc723cc2016-10-09 04:39:13 +0000397 SMLoc getEndLoc() const { return EndLoc; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000398
399 /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
400 bool isPPC64() const { return IsPPC64; }
401
402 int64_t getImm() const {
403 assert(Kind == Immediate && "Invalid access!");
404 return Imm.Val;
405 }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000406 int64_t getImmS16Context() const {
Eric Christopher87590fa2016-06-16 01:00:53 +0000407 assert((Kind == Immediate || Kind == ContextImmediate) &&
408 "Invalid access!");
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000409 if (Kind == Immediate)
410 return Imm.Val;
411 return static_cast<int16_t>(Imm.Val);
412 }
413 int64_t getImmU16Context() const {
Eric Christopher87590fa2016-06-16 01:00:53 +0000414 assert((Kind == Immediate || Kind == ContextImmediate) &&
415 "Invalid access!");
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000416 return Imm.Val;
417 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000418
419 const MCExpr *getExpr() const {
420 assert(Kind == Expression && "Invalid access!");
421 return Expr.Val;
422 }
423
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000424 int64_t getExprCRVal() const {
425 assert(Kind == Expression && "Invalid access!");
426 return Expr.CRVal;
427 }
428
Ulrich Weigand5b427592013-07-05 12:22:36 +0000429 const MCExpr *getTLSReg() const {
430 assert(Kind == TLSRegister && "Invalid access!");
431 return TLSReg.Sym;
432 }
433
Craig Topper0d3fa922014-04-29 07:57:37 +0000434 unsigned getReg() const override {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000435 assert(isRegNumber() && "Invalid access!");
436 return (unsigned) Imm.Val;
437 }
438
Hal Finkel27774d92014-03-13 07:58:58 +0000439 unsigned getVSReg() const {
440 assert(isVSRegNumber() && "Invalid access!");
441 return (unsigned) Imm.Val;
442 }
443
Ulrich Weigand640192d2013-05-03 19:49:39 +0000444 unsigned getCCReg() const {
445 assert(isCCRegNumber() && "Invalid access!");
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000446 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
447 }
448
449 unsigned getCRBit() const {
450 assert(isCRBitNumber() && "Invalid access!");
451 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000452 }
453
454 unsigned getCRBitMask() const {
455 assert(isCRBitMask() && "Invalid access!");
Michael J. Spencerdf1ecbd72013-05-24 22:23:49 +0000456 return 7 - countTrailingZeros<uint64_t>(Imm.Val);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000457 }
458
Craig Topper0d3fa922014-04-29 07:57:37 +0000459 bool isToken() const override { return Kind == Token; }
Eric Christopher87590fa2016-06-16 01:00:53 +0000460 bool isImm() const override {
461 return Kind == Immediate || Kind == Expression;
462 }
Nemanja Ivanovice8effe12015-03-04 20:44:33 +0000463 bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
Hal Finkel27774d92014-03-13 07:58:58 +0000464 bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
Kit Barton535e69d2015-03-25 19:36:23 +0000465 bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
Joerg Sonnenberger9e9623c2014-07-29 22:21:57 +0000466 bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000467 bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
468 bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
469 bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
Joerg Sonnenberger0013b922014-08-08 16:43:49 +0000470 bool isU6ImmX2() const { return Kind == Immediate &&
471 isUInt<6>(getImm()) &&
472 (getImm() & 1) == 0; }
Chuang-Yu Cheng80722712016-03-28 08:34:28 +0000473 bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
Joerg Sonnenberger0013b922014-08-08 16:43:49 +0000474 bool isU7ImmX4() const { return Kind == Immediate &&
475 isUInt<7>(getImm()) &&
476 (getImm() & 3) == 0; }
Chuang-Yu Cheng80722712016-03-28 08:34:28 +0000477 bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
Joerg Sonnenberger0013b922014-08-08 16:43:49 +0000478 bool isU8ImmX8() const { return Kind == Immediate &&
479 isUInt<8>(getImm()) &&
480 (getImm() & 7) == 0; }
Eric Christopher87590fa2016-06-16 01:00:53 +0000481
Bill Schmidte26236e2015-05-22 16:44:10 +0000482 bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
Hal Finkelc93a9a22015-02-25 01:06:45 +0000483 bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000484 bool isU16Imm() const {
485 switch (Kind) {
486 case Expression:
487 return true;
488 case Immediate:
489 case ContextImmediate:
490 return isUInt<16>(getImmU16Context());
491 default:
492 return false;
493 }
494 }
495 bool isS16Imm() const {
496 switch (Kind) {
497 case Expression:
498 return true;
499 case Immediate:
500 case ContextImmediate:
501 return isInt<16>(getImmS16Context());
502 default:
503 return false;
504 }
505 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000506 bool isS16ImmX4() const { return Kind == Expression ||
507 (Kind == Immediate && isInt<16>(getImm()) &&
508 (getImm() & 3) == 0); }
Kit Bartonba532dc2016-03-08 03:49:13 +0000509 bool isS16ImmX16() const { return Kind == Expression ||
510 (Kind == Immediate && isInt<16>(getImm()) &&
511 (getImm() & 15) == 0); }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000512 bool isS17Imm() const {
513 switch (Kind) {
514 case Expression:
515 return true;
516 case Immediate:
517 case ContextImmediate:
518 return isInt<17>(getImmS16Context());
519 default:
520 return false;
521 }
522 }
Ulrich Weigand5b427592013-07-05 12:22:36 +0000523 bool isTLSReg() const { return Kind == TLSRegister; }
Joerg Sonnenbergereb9d13f2014-08-08 20:57:58 +0000524 bool isDirectBr() const {
525 if (Kind == Expression)
526 return true;
527 if (Kind != Immediate)
528 return false;
529 // Operand must be 64-bit aligned, signed 27-bit immediate.
530 if ((getImm() & 3) != 0)
531 return false;
532 if (isInt<26>(getImm()))
533 return true;
534 if (!IsPPC64) {
535 // In 32-bit mode, large 32-bit quantities wrap around.
536 if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
537 return true;
538 }
539 return false;
540 }
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000541 bool isCondBr() const { return Kind == Expression ||
542 (Kind == Immediate && isInt<16>(getImm()) &&
543 (getImm() & 3) == 0); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000544 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
Eric Christopher87590fa2016-06-16 01:00:53 +0000545 bool isVSRegNumber() const {
546 return Kind == Immediate && isUInt<6>(getImm());
547 }
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000548 bool isCCRegNumber() const { return (Kind == Expression
549 && isUInt<3>(getExprCRVal())) ||
550 (Kind == Immediate
551 && isUInt<3>(getImm())); }
552 bool isCRBitNumber() const { return (Kind == Expression
553 && isUInt<5>(getExprCRVal())) ||
554 (Kind == Immediate
555 && isUInt<5>(getImm())); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000556 bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
557 isPowerOf2_32(getImm()); }
Hal Finkel522e4d92016-09-03 02:31:44 +0000558 bool isATBitsAsHint() const { return false; }
Craig Topper0d3fa922014-04-29 07:57:37 +0000559 bool isMem() const override { return false; }
560 bool isReg() const override { return false; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000561
562 void addRegOperands(MCInst &Inst, unsigned N) const {
563 llvm_unreachable("addRegOperands");
564 }
565
566 void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
567 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000568 Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000569 }
570
571 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
572 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000573 Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000574 }
575
576 void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
577 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000578 Inst.addOperand(MCOperand::createReg(XRegs[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000579 }
580
581 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
582 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000583 Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000584 }
585
586 void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
587 if (isPPC64())
588 addRegG8RCOperands(Inst, N);
589 else
590 addRegGPRCOperands(Inst, N);
591 }
592
593 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
594 if (isPPC64())
595 addRegG8RCNoX0Operands(Inst, N);
596 else
597 addRegGPRCNoR0Operands(Inst, N);
598 }
599
600 void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
601 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000602 Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000603 }
604
605 void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
606 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000607 Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000608 }
609
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000610 void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
611 assert(N == 1 && "Invalid number of operands!");
612 Inst.addOperand(MCOperand::createReg(VFRegs[getReg()]));
613 }
614
Ulrich Weigand640192d2013-05-03 19:49:39 +0000615 void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
616 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000617 Inst.addOperand(MCOperand::createReg(VRegs[getReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000618 }
619
Hal Finkel27774d92014-03-13 07:58:58 +0000620 void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
621 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000622 Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
Hal Finkel27774d92014-03-13 07:58:58 +0000623 }
624
Hal Finkel19be5062014-03-29 05:29:01 +0000625 void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
626 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000627 Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
Hal Finkel19be5062014-03-29 05:29:01 +0000628 }
629
Nemanja Ivanovicf3c94b12015-05-07 18:24:05 +0000630 void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
631 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000632 Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
Nemanja Ivanovicf3c94b12015-05-07 18:24:05 +0000633 }
634
Hal Finkelc93a9a22015-02-25 01:06:45 +0000635 void addRegQFRCOperands(MCInst &Inst, unsigned N) const {
636 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000637 Inst.addOperand(MCOperand::createReg(QFRegs[getReg()]));
Hal Finkelc93a9a22015-02-25 01:06:45 +0000638 }
639
640 void addRegQSRCOperands(MCInst &Inst, unsigned N) const {
641 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000642 Inst.addOperand(MCOperand::createReg(QFRegs[getReg()]));
Hal Finkelc93a9a22015-02-25 01:06:45 +0000643 }
644
645 void addRegQBRCOperands(MCInst &Inst, unsigned N) const {
646 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000647 Inst.addOperand(MCOperand::createReg(QFRegs[getReg()]));
Hal Finkelc93a9a22015-02-25 01:06:45 +0000648 }
649
Ulrich Weigand640192d2013-05-03 19:49:39 +0000650 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
651 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000652 Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000653 }
654
655 void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
656 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000657 Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000658 }
659
660 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
661 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000662 Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000663 }
664
665 void addImmOperands(MCInst &Inst, unsigned N) const {
666 assert(N == 1 && "Invalid number of operands!");
667 if (Kind == Immediate)
Jim Grosbache9119e42015-05-13 18:37:00 +0000668 Inst.addOperand(MCOperand::createImm(getImm()));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000669 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000670 Inst.addOperand(MCOperand::createExpr(getExpr()));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000671 }
672
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000673 void addS16ImmOperands(MCInst &Inst, unsigned N) const {
674 assert(N == 1 && "Invalid number of operands!");
675 switch (Kind) {
676 case Immediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000677 Inst.addOperand(MCOperand::createImm(getImm()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000678 break;
679 case ContextImmediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000680 Inst.addOperand(MCOperand::createImm(getImmS16Context()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000681 break;
682 default:
Jim Grosbache9119e42015-05-13 18:37:00 +0000683 Inst.addOperand(MCOperand::createExpr(getExpr()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000684 break;
685 }
686 }
687
688 void addU16ImmOperands(MCInst &Inst, unsigned N) const {
689 assert(N == 1 && "Invalid number of operands!");
690 switch (Kind) {
691 case Immediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000692 Inst.addOperand(MCOperand::createImm(getImm()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000693 break;
694 case ContextImmediate:
Jim Grosbache9119e42015-05-13 18:37:00 +0000695 Inst.addOperand(MCOperand::createImm(getImmU16Context()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000696 break;
697 default:
Jim Grosbache9119e42015-05-13 18:37:00 +0000698 Inst.addOperand(MCOperand::createExpr(getExpr()));
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000699 break;
700 }
701 }
702
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000703 void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 if (Kind == Immediate)
Jim Grosbache9119e42015-05-13 18:37:00 +0000706 Inst.addOperand(MCOperand::createImm(getImm() / 4));
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000707 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000708 Inst.addOperand(MCOperand::createExpr(getExpr()));
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000709 }
710
Ulrich Weigand5b427592013-07-05 12:22:36 +0000711 void addTLSRegOperands(MCInst &Inst, unsigned N) const {
712 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000713 Inst.addOperand(MCOperand::createExpr(getTLSReg()));
Ulrich Weigand5b427592013-07-05 12:22:36 +0000714 }
715
Ulrich Weigand640192d2013-05-03 19:49:39 +0000716 StringRef getToken() const {
717 assert(Kind == Token && "Invalid access!");
718 return StringRef(Tok.Data, Tok.Length);
719 }
720
Craig Topper0d3fa922014-04-29 07:57:37 +0000721 void print(raw_ostream &OS) const override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000722
David Blaikie960ea3f2014-06-08 16:18:35 +0000723 static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
724 bool IsPPC64) {
725 auto Op = make_unique<PPCOperand>(Token);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000726 Op->Tok.Data = Str.data();
727 Op->Tok.Length = Str.size();
728 Op->StartLoc = S;
729 Op->EndLoc = S;
730 Op->IsPPC64 = IsPPC64;
731 return Op;
732 }
733
David Blaikie960ea3f2014-06-08 16:18:35 +0000734 static std::unique_ptr<PPCOperand>
735 CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000736 // Allocate extra memory for the string and copy it.
David Blaikie960ea3f2014-06-08 16:18:35 +0000737 // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
738 // deleter which will destroy them by simply using "delete", not correctly
739 // calling operator delete on this extra memory after calling the dtor
740 // explicitly.
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000741 void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000742 std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
Benjamin Kramer769989c2014-08-15 11:05:45 +0000743 Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000744 Op->Tok.Length = Str.size();
Benjamin Kramer769989c2014-08-15 11:05:45 +0000745 std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000746 Op->StartLoc = S;
747 Op->EndLoc = S;
748 Op->IsPPC64 = IsPPC64;
749 return Op;
750 }
751
David Blaikie960ea3f2014-06-08 16:18:35 +0000752 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
753 bool IsPPC64) {
754 auto Op = make_unique<PPCOperand>(Immediate);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000755 Op->Imm.Val = Val;
756 Op->StartLoc = S;
757 Op->EndLoc = E;
758 Op->IsPPC64 = IsPPC64;
759 return Op;
760 }
761
David Blaikie960ea3f2014-06-08 16:18:35 +0000762 static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
763 SMLoc E, bool IsPPC64) {
764 auto Op = make_unique<PPCOperand>(Expression);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000765 Op->Expr.Val = Val;
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000766 Op->Expr.CRVal = EvaluateCRExpr(Val);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000767 Op->StartLoc = S;
768 Op->EndLoc = E;
769 Op->IsPPC64 = IsPPC64;
770 return Op;
771 }
Ulrich Weigand5b427592013-07-05 12:22:36 +0000772
David Blaikie960ea3f2014-06-08 16:18:35 +0000773 static std::unique_ptr<PPCOperand>
774 CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
775 auto Op = make_unique<PPCOperand>(TLSRegister);
Ulrich Weigand5b427592013-07-05 12:22:36 +0000776 Op->TLSReg.Sym = Sym;
777 Op->StartLoc = S;
778 Op->EndLoc = E;
779 Op->IsPPC64 = IsPPC64;
780 return Op;
781 }
782
David Blaikie960ea3f2014-06-08 16:18:35 +0000783 static std::unique_ptr<PPCOperand>
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000784 CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
785 auto Op = make_unique<PPCOperand>(ContextImmediate);
786 Op->Imm.Val = Val;
787 Op->StartLoc = S;
788 Op->EndLoc = E;
789 Op->IsPPC64 = IsPPC64;
790 return Op;
791 }
792
793 static std::unique_ptr<PPCOperand>
David Blaikie960ea3f2014-06-08 16:18:35 +0000794 CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
Ulrich Weigand5b427592013-07-05 12:22:36 +0000795 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
796 return CreateImm(CE->getValue(), S, E, IsPPC64);
797
798 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
799 if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS)
800 return CreateTLSReg(SRE, S, E, IsPPC64);
801
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000802 if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
803 int64_t Res;
Jim Grosbach13760bd2015-05-30 01:25:56 +0000804 if (TE->evaluateAsConstant(Res))
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000805 return CreateContextImm(Res, S, E, IsPPC64);
806 }
807
Ulrich Weigand5b427592013-07-05 12:22:36 +0000808 return CreateExpr(Val, S, E, IsPPC64);
809 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000810};
811
812} // end anonymous namespace.
813
814void PPCOperand::print(raw_ostream &OS) const {
815 switch (Kind) {
816 case Token:
817 OS << "'" << getToken() << "'";
818 break;
819 case Immediate:
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000820 case ContextImmediate:
Ulrich Weigand640192d2013-05-03 19:49:39 +0000821 OS << getImm();
822 break;
823 case Expression:
Rafael Espindolaf4a13652015-05-27 13:05:42 +0000824 OS << *getExpr();
Ulrich Weigand640192d2013-05-03 19:49:39 +0000825 break;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000826 case TLSRegister:
Rafael Espindolaf4a13652015-05-27 13:05:42 +0000827 OS << *getTLSReg();
Ulrich Weigand5b427592013-07-05 12:22:36 +0000828 break;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000829 }
830}
831
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000832static void
833addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
834 if (Op.isImm()) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000835 Inst.addOperand(MCOperand::createImm(-Op.getImm()));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000836 return;
837 }
838 const MCExpr *Expr = Op.getExpr();
839 if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
840 if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000841 Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000842 return;
843 }
844 } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
845 if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
Jim Grosbach13760bd2015-05-30 01:25:56 +0000846 const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000847 BinExpr->getLHS(), Ctx);
Jim Grosbache9119e42015-05-13 18:37:00 +0000848 Inst.addOperand(MCOperand::createExpr(NE));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000849 return;
850 }
851 }
Jim Grosbach13760bd2015-05-30 01:25:56 +0000852 Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000853}
854
David Blaikie960ea3f2014-06-08 16:18:35 +0000855void PPCAsmParser::ProcessInstruction(MCInst &Inst,
856 const OperandVector &Operands) {
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000857 int Opcode = Inst.getOpcode();
858 switch (Opcode) {
Hal Finkelfefcfff2015-04-23 22:47:57 +0000859 case PPC::DCBTx:
860 case PPC::DCBTT:
861 case PPC::DCBTSTx:
862 case PPC::DCBTSTT: {
863 MCInst TmpInst;
864 TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
865 PPC::DCBT : PPC::DCBTST);
Jim Grosbache9119e42015-05-13 18:37:00 +0000866 TmpInst.addOperand(MCOperand::createImm(
Hal Finkelfefcfff2015-04-23 22:47:57 +0000867 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
868 TmpInst.addOperand(Inst.getOperand(0));
869 TmpInst.addOperand(Inst.getOperand(1));
870 Inst = TmpInst;
871 break;
872 }
873 case PPC::DCBTCT:
874 case PPC::DCBTDS: {
875 MCInst TmpInst;
876 TmpInst.setOpcode(PPC::DCBT);
877 TmpInst.addOperand(Inst.getOperand(2));
878 TmpInst.addOperand(Inst.getOperand(0));
879 TmpInst.addOperand(Inst.getOperand(1));
880 Inst = TmpInst;
881 break;
882 }
883 case PPC::DCBTSTCT:
884 case PPC::DCBTSTDS: {
885 MCInst TmpInst;
886 TmpInst.setOpcode(PPC::DCBTST);
887 TmpInst.addOperand(Inst.getOperand(2));
888 TmpInst.addOperand(Inst.getOperand(0));
889 TmpInst.addOperand(Inst.getOperand(1));
890 Inst = TmpInst;
891 break;
892 }
Hal Finkel277736e2016-09-02 23:41:54 +0000893 case PPC::DCBFx:
894 case PPC::DCBFL:
895 case PPC::DCBFLP: {
896 int L = 0;
897 if (Opcode == PPC::DCBFL)
898 L = 1;
899 else if (Opcode == PPC::DCBFLP)
900 L = 3;
901
902 MCInst TmpInst;
903 TmpInst.setOpcode(PPC::DCBF);
904 TmpInst.addOperand(MCOperand::createImm(L));
905 TmpInst.addOperand(Inst.getOperand(0));
906 TmpInst.addOperand(Inst.getOperand(1));
907 Inst = TmpInst;
908 break;
909 }
Ulrich Weigand6ca71572013-06-24 18:08:03 +0000910 case PPC::LAx: {
911 MCInst TmpInst;
912 TmpInst.setOpcode(PPC::LA);
913 TmpInst.addOperand(Inst.getOperand(0));
914 TmpInst.addOperand(Inst.getOperand(2));
915 TmpInst.addOperand(Inst.getOperand(1));
916 Inst = TmpInst;
917 break;
918 }
Ulrich Weigand4069e242013-06-25 13:16:48 +0000919 case PPC::SUBI: {
920 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000921 TmpInst.setOpcode(PPC::ADDI);
922 TmpInst.addOperand(Inst.getOperand(0));
923 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000924 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000925 Inst = TmpInst;
926 break;
927 }
928 case PPC::SUBIS: {
929 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000930 TmpInst.setOpcode(PPC::ADDIS);
931 TmpInst.addOperand(Inst.getOperand(0));
932 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000933 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000934 Inst = TmpInst;
935 break;
936 }
937 case PPC::SUBIC: {
938 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000939 TmpInst.setOpcode(PPC::ADDIC);
940 TmpInst.addOperand(Inst.getOperand(0));
941 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000942 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000943 Inst = TmpInst;
944 break;
945 }
946 case PPC::SUBICo: {
947 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000948 TmpInst.setOpcode(PPC::ADDICo);
949 TmpInst.addOperand(Inst.getOperand(0));
950 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000951 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000952 Inst = TmpInst;
953 break;
954 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000955 case PPC::EXTLWI:
956 case PPC::EXTLWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +0000957 MCInst TmpInst;
958 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000959 int64_t B = Inst.getOperand(3).getImm();
960 TmpInst.setOpcode(Opcode == PPC::EXTLWI? PPC::RLWINM : PPC::RLWINMo);
961 TmpInst.addOperand(Inst.getOperand(0));
962 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +0000963 TmpInst.addOperand(MCOperand::createImm(B));
964 TmpInst.addOperand(MCOperand::createImm(0));
965 TmpInst.addOperand(MCOperand::createImm(N - 1));
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000966 Inst = TmpInst;
967 break;
968 }
969 case PPC::EXTRWI:
970 case PPC::EXTRWIo: {
971 MCInst TmpInst;
972 int64_t N = Inst.getOperand(2).getImm();
973 int64_t B = Inst.getOperand(3).getImm();
974 TmpInst.setOpcode(Opcode == PPC::EXTRWI? PPC::RLWINM : PPC::RLWINMo);
975 TmpInst.addOperand(Inst.getOperand(0));
976 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +0000977 TmpInst.addOperand(MCOperand::createImm(B + N));
978 TmpInst.addOperand(MCOperand::createImm(32 - N));
979 TmpInst.addOperand(MCOperand::createImm(31));
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000980 Inst = TmpInst;
981 break;
982 }
983 case PPC::INSLWI:
984 case PPC::INSLWIo: {
985 MCInst TmpInst;
986 int64_t N = Inst.getOperand(2).getImm();
987 int64_t B = Inst.getOperand(3).getImm();
988 TmpInst.setOpcode(Opcode == PPC::INSLWI? PPC::RLWIMI : PPC::RLWIMIo);
989 TmpInst.addOperand(Inst.getOperand(0));
990 TmpInst.addOperand(Inst.getOperand(0));
991 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +0000992 TmpInst.addOperand(MCOperand::createImm(32 - B));
993 TmpInst.addOperand(MCOperand::createImm(B));
994 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000995 Inst = TmpInst;
996 break;
997 }
998 case PPC::INSRWI:
999 case PPC::INSRWIo: {
1000 MCInst TmpInst;
1001 int64_t N = Inst.getOperand(2).getImm();
1002 int64_t B = Inst.getOperand(3).getImm();
1003 TmpInst.setOpcode(Opcode == PPC::INSRWI? PPC::RLWIMI : PPC::RLWIMIo);
1004 TmpInst.addOperand(Inst.getOperand(0));
1005 TmpInst.addOperand(Inst.getOperand(0));
1006 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001007 TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
1008 TmpInst.addOperand(MCOperand::createImm(B));
1009 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001010 Inst = TmpInst;
1011 break;
1012 }
1013 case PPC::ROTRWI:
1014 case PPC::ROTRWIo: {
1015 MCInst TmpInst;
1016 int64_t N = Inst.getOperand(2).getImm();
1017 TmpInst.setOpcode(Opcode == PPC::ROTRWI? PPC::RLWINM : PPC::RLWINMo);
1018 TmpInst.addOperand(Inst.getOperand(0));
1019 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001020 TmpInst.addOperand(MCOperand::createImm(32 - N));
1021 TmpInst.addOperand(MCOperand::createImm(0));
1022 TmpInst.addOperand(MCOperand::createImm(31));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001023 Inst = TmpInst;
1024 break;
1025 }
1026 case PPC::SLWI:
1027 case PPC::SLWIo: {
1028 MCInst TmpInst;
1029 int64_t N = Inst.getOperand(2).getImm();
1030 TmpInst.setOpcode(Opcode == PPC::SLWI? PPC::RLWINM : PPC::RLWINMo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001031 TmpInst.addOperand(Inst.getOperand(0));
1032 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001033 TmpInst.addOperand(MCOperand::createImm(N));
1034 TmpInst.addOperand(MCOperand::createImm(0));
1035 TmpInst.addOperand(MCOperand::createImm(31 - N));
Ulrich Weigandd8394902013-05-03 19:50:27 +00001036 Inst = TmpInst;
1037 break;
1038 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001039 case PPC::SRWI:
1040 case PPC::SRWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +00001041 MCInst TmpInst;
1042 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001043 TmpInst.setOpcode(Opcode == PPC::SRWI? PPC::RLWINM : PPC::RLWINMo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001044 TmpInst.addOperand(Inst.getOperand(0));
1045 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001046 TmpInst.addOperand(MCOperand::createImm(32 - N));
1047 TmpInst.addOperand(MCOperand::createImm(N));
1048 TmpInst.addOperand(MCOperand::createImm(31));
Ulrich Weigandd8394902013-05-03 19:50:27 +00001049 Inst = TmpInst;
1050 break;
1051 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001052 case PPC::CLRRWI:
1053 case PPC::CLRRWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +00001054 MCInst TmpInst;
1055 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001056 TmpInst.setOpcode(Opcode == PPC::CLRRWI? PPC::RLWINM : PPC::RLWINMo);
1057 TmpInst.addOperand(Inst.getOperand(0));
1058 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001059 TmpInst.addOperand(MCOperand::createImm(0));
1060 TmpInst.addOperand(MCOperand::createImm(0));
1061 TmpInst.addOperand(MCOperand::createImm(31 - N));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001062 Inst = TmpInst;
1063 break;
1064 }
1065 case PPC::CLRLSLWI:
1066 case PPC::CLRLSLWIo: {
1067 MCInst TmpInst;
1068 int64_t B = Inst.getOperand(2).getImm();
1069 int64_t N = Inst.getOperand(3).getImm();
1070 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI? PPC::RLWINM : PPC::RLWINMo);
1071 TmpInst.addOperand(Inst.getOperand(0));
1072 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001073 TmpInst.addOperand(MCOperand::createImm(N));
1074 TmpInst.addOperand(MCOperand::createImm(B - N));
1075 TmpInst.addOperand(MCOperand::createImm(31 - N));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001076 Inst = TmpInst;
1077 break;
1078 }
1079 case PPC::EXTLDI:
1080 case PPC::EXTLDIo: {
1081 MCInst TmpInst;
1082 int64_t N = Inst.getOperand(2).getImm();
1083 int64_t B = Inst.getOperand(3).getImm();
1084 TmpInst.setOpcode(Opcode == PPC::EXTLDI? PPC::RLDICR : PPC::RLDICRo);
1085 TmpInst.addOperand(Inst.getOperand(0));
1086 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001087 TmpInst.addOperand(MCOperand::createImm(B));
1088 TmpInst.addOperand(MCOperand::createImm(N - 1));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001089 Inst = TmpInst;
1090 break;
1091 }
1092 case PPC::EXTRDI:
1093 case PPC::EXTRDIo: {
1094 MCInst TmpInst;
1095 int64_t N = Inst.getOperand(2).getImm();
1096 int64_t B = Inst.getOperand(3).getImm();
1097 TmpInst.setOpcode(Opcode == PPC::EXTRDI? PPC::RLDICL : PPC::RLDICLo);
1098 TmpInst.addOperand(Inst.getOperand(0));
1099 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001100 TmpInst.addOperand(MCOperand::createImm(B + N));
1101 TmpInst.addOperand(MCOperand::createImm(64 - N));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001102 Inst = TmpInst;
1103 break;
1104 }
1105 case PPC::INSRDI:
1106 case PPC::INSRDIo: {
1107 MCInst TmpInst;
1108 int64_t N = Inst.getOperand(2).getImm();
1109 int64_t B = Inst.getOperand(3).getImm();
1110 TmpInst.setOpcode(Opcode == PPC::INSRDI? PPC::RLDIMI : PPC::RLDIMIo);
1111 TmpInst.addOperand(Inst.getOperand(0));
1112 TmpInst.addOperand(Inst.getOperand(0));
1113 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001114 TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
1115 TmpInst.addOperand(MCOperand::createImm(B));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001116 Inst = TmpInst;
1117 break;
1118 }
1119 case PPC::ROTRDI:
1120 case PPC::ROTRDIo: {
1121 MCInst TmpInst;
1122 int64_t N = Inst.getOperand(2).getImm();
1123 TmpInst.setOpcode(Opcode == PPC::ROTRDI? PPC::RLDICL : PPC::RLDICLo);
1124 TmpInst.addOperand(Inst.getOperand(0));
1125 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001126 TmpInst.addOperand(MCOperand::createImm(64 - N));
1127 TmpInst.addOperand(MCOperand::createImm(0));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001128 Inst = TmpInst;
1129 break;
1130 }
1131 case PPC::SLDI:
1132 case PPC::SLDIo: {
1133 MCInst TmpInst;
1134 int64_t N = Inst.getOperand(2).getImm();
1135 TmpInst.setOpcode(Opcode == PPC::SLDI? PPC::RLDICR : PPC::RLDICRo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001136 TmpInst.addOperand(Inst.getOperand(0));
1137 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001138 TmpInst.addOperand(MCOperand::createImm(N));
1139 TmpInst.addOperand(MCOperand::createImm(63 - N));
Ulrich Weigandd8394902013-05-03 19:50:27 +00001140 Inst = TmpInst;
1141 break;
1142 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001143 case PPC::SRDI:
1144 case PPC::SRDIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +00001145 MCInst TmpInst;
1146 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001147 TmpInst.setOpcode(Opcode == PPC::SRDI? PPC::RLDICL : PPC::RLDICLo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001148 TmpInst.addOperand(Inst.getOperand(0));
1149 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001150 TmpInst.addOperand(MCOperand::createImm(64 - N));
1151 TmpInst.addOperand(MCOperand::createImm(N));
Ulrich Weigandd8394902013-05-03 19:50:27 +00001152 Inst = TmpInst;
1153 break;
1154 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001155 case PPC::CLRRDI:
1156 case PPC::CLRRDIo: {
1157 MCInst TmpInst;
1158 int64_t N = Inst.getOperand(2).getImm();
1159 TmpInst.setOpcode(Opcode == PPC::CLRRDI? PPC::RLDICR : PPC::RLDICRo);
1160 TmpInst.addOperand(Inst.getOperand(0));
1161 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001162 TmpInst.addOperand(MCOperand::createImm(0));
1163 TmpInst.addOperand(MCOperand::createImm(63 - N));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001164 Inst = TmpInst;
1165 break;
1166 }
1167 case PPC::CLRLSLDI:
1168 case PPC::CLRLSLDIo: {
1169 MCInst TmpInst;
1170 int64_t B = Inst.getOperand(2).getImm();
1171 int64_t N = Inst.getOperand(3).getImm();
1172 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI? PPC::RLDIC : PPC::RLDICo);
1173 TmpInst.addOperand(Inst.getOperand(0));
1174 TmpInst.addOperand(Inst.getOperand(1));
Jim Grosbache9119e42015-05-13 18:37:00 +00001175 TmpInst.addOperand(MCOperand::createImm(N));
1176 TmpInst.addOperand(MCOperand::createImm(B - N));
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001177 Inst = TmpInst;
1178 break;
1179 }
Hal Finkel6e9110a2015-03-28 19:42:41 +00001180 case PPC::RLWINMbm:
1181 case PPC::RLWINMobm: {
1182 unsigned MB, ME;
1183 int64_t BM = Inst.getOperand(3).getImm();
1184 if (!isRunOfOnes(BM, MB, ME))
1185 break;
1186
1187 MCInst TmpInst;
1188 TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINMo);
1189 TmpInst.addOperand(Inst.getOperand(0));
1190 TmpInst.addOperand(Inst.getOperand(1));
1191 TmpInst.addOperand(Inst.getOperand(2));
Jim Grosbache9119e42015-05-13 18:37:00 +00001192 TmpInst.addOperand(MCOperand::createImm(MB));
1193 TmpInst.addOperand(MCOperand::createImm(ME));
Hal Finkel6e9110a2015-03-28 19:42:41 +00001194 Inst = TmpInst;
1195 break;
1196 }
1197 case PPC::RLWIMIbm:
1198 case PPC::RLWIMIobm: {
1199 unsigned MB, ME;
1200 int64_t BM = Inst.getOperand(3).getImm();
1201 if (!isRunOfOnes(BM, MB, ME))
1202 break;
1203
1204 MCInst TmpInst;
1205 TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMIo);
1206 TmpInst.addOperand(Inst.getOperand(0));
1207 TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
1208 TmpInst.addOperand(Inst.getOperand(1));
1209 TmpInst.addOperand(Inst.getOperand(2));
Jim Grosbache9119e42015-05-13 18:37:00 +00001210 TmpInst.addOperand(MCOperand::createImm(MB));
1211 TmpInst.addOperand(MCOperand::createImm(ME));
Hal Finkel6e9110a2015-03-28 19:42:41 +00001212 Inst = TmpInst;
1213 break;
1214 }
1215 case PPC::RLWNMbm:
1216 case PPC::RLWNMobm: {
1217 unsigned MB, ME;
1218 int64_t BM = Inst.getOperand(3).getImm();
1219 if (!isRunOfOnes(BM, MB, ME))
1220 break;
1221
1222 MCInst TmpInst;
1223 TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNMo);
1224 TmpInst.addOperand(Inst.getOperand(0));
1225 TmpInst.addOperand(Inst.getOperand(1));
1226 TmpInst.addOperand(Inst.getOperand(2));
Jim Grosbache9119e42015-05-13 18:37:00 +00001227 TmpInst.addOperand(MCOperand::createImm(MB));
1228 TmpInst.addOperand(MCOperand::createImm(ME));
Hal Finkel6e9110a2015-03-28 19:42:41 +00001229 Inst = TmpInst;
1230 break;
1231 }
Kit Barton4f79f962015-06-16 16:01:15 +00001232 case PPC::MFTB: {
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001233 if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) {
Kit Barton4f79f962015-06-16 16:01:15 +00001234 assert(Inst.getNumOperands() == 2 && "Expecting two operands");
1235 Inst.setOpcode(PPC::MFSPR);
1236 }
1237 break;
1238 }
Chuang-Yu Chengeaf4b3d2016-04-06 01:46:45 +00001239 case PPC::CP_COPYx:
1240 case PPC::CP_COPY_FIRST: {
1241 MCInst TmpInst;
1242 TmpInst.setOpcode(PPC::CP_COPY);
1243 TmpInst.addOperand(Inst.getOperand(0));
1244 TmpInst.addOperand(Inst.getOperand(1));
1245 TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_COPYx ? 0 : 1));
1246
1247 Inst = TmpInst;
1248 break;
1249 }
1250 case PPC::CP_PASTEx :
1251 case PPC::CP_PASTE_LAST: {
1252 MCInst TmpInst;
1253 TmpInst.setOpcode(Opcode == PPC::CP_PASTEx ?
1254 PPC::CP_PASTE : PPC::CP_PASTEo);
1255 TmpInst.addOperand(Inst.getOperand(0));
1256 TmpInst.addOperand(Inst.getOperand(1));
1257 TmpInst.addOperand(MCOperand::createImm(Opcode == PPC::CP_PASTEx ? 0 : 1));
1258
1259 Inst = TmpInst;
1260 break;
1261 }
Ulrich Weigandd8394902013-05-03 19:50:27 +00001262 }
1263}
1264
David Blaikie960ea3f2014-06-08 16:18:35 +00001265bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1266 OperandVector &Operands,
Tim Northover26bb14e2014-08-18 11:49:42 +00001267 MCStreamer &Out, uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +00001268 bool MatchingInlineAsm) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001269 MCInst Inst;
1270
Ranjeet Singh86ecbb72015-06-30 12:32:53 +00001271 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001272 case Match_Success:
Ulrich Weigandd8394902013-05-03 19:50:27 +00001273 // Post-process instructions (typically extended mnemonics)
1274 ProcessInstruction(Inst, Operands);
Ulrich Weigand640192d2013-05-03 19:49:39 +00001275 Inst.setLoc(IDLoc);
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001276 Out.EmitInstruction(Inst, getSTI());
Ulrich Weigand640192d2013-05-03 19:49:39 +00001277 return false;
1278 case Match_MissingFeature:
1279 return Error(IDLoc, "instruction use requires an option to be enabled");
1280 case Match_MnemonicFail:
Craig Topper589ceee2015-01-03 08:16:34 +00001281 return Error(IDLoc, "unrecognized instruction mnemonic");
Ulrich Weigand640192d2013-05-03 19:49:39 +00001282 case Match_InvalidOperand: {
1283 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +00001284 if (ErrorInfo != ~0ULL) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001285 if (ErrorInfo >= Operands.size())
1286 return Error(IDLoc, "too few operands for instruction");
1287
David Blaikie960ea3f2014-06-08 16:18:35 +00001288 ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001289 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1290 }
1291
1292 return Error(ErrorLoc, "invalid operand for instruction");
1293 }
1294 }
1295
1296 llvm_unreachable("Implement any new match types added!");
1297}
1298
1299bool PPCAsmParser::
1300MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) {
1301 if (Tok.is(AsmToken::Identifier)) {
Ulrich Weigand509c2402013-05-06 11:16:57 +00001302 StringRef Name = Tok.getString();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001303
Ulrich Weigand509c2402013-05-06 11:16:57 +00001304 if (Name.equals_lower("lr")) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001305 RegNo = isPPC64()? PPC::LR8 : PPC::LR;
1306 IntVal = 8;
1307 return false;
Ulrich Weigand509c2402013-05-06 11:16:57 +00001308 } else if (Name.equals_lower("ctr")) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001309 RegNo = isPPC64()? PPC::CTR8 : PPC::CTR;
1310 IntVal = 9;
1311 return false;
Hal Finkel52727c62013-07-02 03:39:34 +00001312 } else if (Name.equals_lower("vrsave")) {
1313 RegNo = PPC::VRSAVE;
1314 IntVal = 256;
1315 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001316 } else if (Name.startswith_lower("r") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001317 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1318 RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal];
1319 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001320 } else if (Name.startswith_lower("f") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001321 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1322 RegNo = FRegs[IntVal];
1323 return false;
Hal Finkel4dc8fcc2015-04-23 23:16:22 +00001324 } else if (Name.startswith_lower("vs") &&
1325 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1326 RegNo = VSRegs[IntVal];
1327 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001328 } else if (Name.startswith_lower("v") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001329 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1330 RegNo = VRegs[IntVal];
1331 return false;
Hal Finkel4dc8fcc2015-04-23 23:16:22 +00001332 } else if (Name.startswith_lower("q") &&
1333 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1334 RegNo = QFRegs[IntVal];
1335 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001336 } else if (Name.startswith_lower("cr") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001337 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1338 RegNo = CRRegs[IntVal];
1339 return false;
1340 }
1341 }
1342
1343 return true;
1344}
1345
1346bool PPCAsmParser::
1347ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001348 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001349 const AsmToken &Tok = Parser.getTok();
1350 StartLoc = Tok.getLoc();
1351 EndLoc = Tok.getEndLoc();
1352 RegNo = 0;
1353 int64_t IntVal;
1354
1355 if (!MatchRegisterName(Tok, RegNo, IntVal)) {
1356 Parser.Lex(); // Eat identifier token.
1357 return false;
1358 }
1359
1360 return Error(StartLoc, "invalid register name");
1361}
1362
NAKAMURA Takumi36c17ee2013-06-25 01:14:20 +00001363/// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
Ulrich Weigande67c5652013-06-21 14:42:49 +00001364/// the expression and check for VK_PPC_LO/HI/HA
Ulrich Weigand96e65782013-06-20 16:23:52 +00001365/// symbol variants. If all symbols with modifier use the same
1366/// variant, return the corresponding PPCMCExpr::VariantKind,
1367/// and a modified expression using the default symbol variant.
1368/// Otherwise, return NULL.
1369const MCExpr *PPCAsmParser::
1370ExtractModifierFromExpr(const MCExpr *E,
1371 PPCMCExpr::VariantKind &Variant) {
1372 MCContext &Context = getParser().getContext();
1373 Variant = PPCMCExpr::VK_PPC_None;
1374
1375 switch (E->getKind()) {
1376 case MCExpr::Target:
1377 case MCExpr::Constant:
Craig Topper062a2ba2014-04-25 05:30:21 +00001378 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001379
1380 case MCExpr::SymbolRef: {
1381 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1382
1383 switch (SRE->getKind()) {
Ulrich Weigandd51c09f2013-06-21 14:42:20 +00001384 case MCSymbolRefExpr::VK_PPC_LO:
1385 Variant = PPCMCExpr::VK_PPC_LO;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001386 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +00001387 case MCSymbolRefExpr::VK_PPC_HI:
1388 Variant = PPCMCExpr::VK_PPC_HI;
1389 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +00001390 case MCSymbolRefExpr::VK_PPC_HA:
1391 Variant = PPCMCExpr::VK_PPC_HA;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001392 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +00001393 case MCSymbolRefExpr::VK_PPC_HIGHER:
1394 Variant = PPCMCExpr::VK_PPC_HIGHER;
1395 break;
1396 case MCSymbolRefExpr::VK_PPC_HIGHERA:
1397 Variant = PPCMCExpr::VK_PPC_HIGHERA;
1398 break;
1399 case MCSymbolRefExpr::VK_PPC_HIGHEST:
1400 Variant = PPCMCExpr::VK_PPC_HIGHEST;
1401 break;
1402 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1403 Variant = PPCMCExpr::VK_PPC_HIGHESTA;
1404 break;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001405 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001406 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001407 }
1408
Jim Grosbach13760bd2015-05-30 01:25:56 +00001409 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
Ulrich Weigand96e65782013-06-20 16:23:52 +00001410 }
1411
1412 case MCExpr::Unary: {
1413 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1414 const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
1415 if (!Sub)
Craig Topper062a2ba2014-04-25 05:30:21 +00001416 return nullptr;
Jim Grosbach13760bd2015-05-30 01:25:56 +00001417 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
Ulrich Weigand96e65782013-06-20 16:23:52 +00001418 }
1419
1420 case MCExpr::Binary: {
1421 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1422 PPCMCExpr::VariantKind LHSVariant, RHSVariant;
1423 const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
1424 const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
1425
1426 if (!LHS && !RHS)
Craig Topper062a2ba2014-04-25 05:30:21 +00001427 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001428
1429 if (!LHS) LHS = BE->getLHS();
1430 if (!RHS) RHS = BE->getRHS();
1431
1432 if (LHSVariant == PPCMCExpr::VK_PPC_None)
1433 Variant = RHSVariant;
1434 else if (RHSVariant == PPCMCExpr::VK_PPC_None)
1435 Variant = LHSVariant;
1436 else if (LHSVariant == RHSVariant)
1437 Variant = LHSVariant;
1438 else
Craig Topper062a2ba2014-04-25 05:30:21 +00001439 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001440
Jim Grosbach13760bd2015-05-30 01:25:56 +00001441 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
Ulrich Weigand96e65782013-06-20 16:23:52 +00001442 }
1443 }
1444
1445 llvm_unreachable("Invalid expression kind!");
1446}
1447
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001448/// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
1449/// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
1450/// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
1451/// FIXME: This is a hack.
1452const MCExpr *PPCAsmParser::
1453FixupVariantKind(const MCExpr *E) {
1454 MCContext &Context = getParser().getContext();
1455
1456 switch (E->getKind()) {
1457 case MCExpr::Target:
1458 case MCExpr::Constant:
1459 return E;
1460
1461 case MCExpr::SymbolRef: {
1462 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1463 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1464
1465 switch (SRE->getKind()) {
1466 case MCSymbolRefExpr::VK_TLSGD:
1467 Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
1468 break;
1469 case MCSymbolRefExpr::VK_TLSLD:
1470 Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
1471 break;
1472 default:
1473 return E;
1474 }
Jim Grosbach13760bd2015-05-30 01:25:56 +00001475 return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001476 }
1477
1478 case MCExpr::Unary: {
1479 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1480 const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
1481 if (Sub == UE->getSubExpr())
1482 return E;
Jim Grosbach13760bd2015-05-30 01:25:56 +00001483 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001484 }
1485
1486 case MCExpr::Binary: {
1487 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1488 const MCExpr *LHS = FixupVariantKind(BE->getLHS());
1489 const MCExpr *RHS = FixupVariantKind(BE->getRHS());
1490 if (LHS == BE->getLHS() && RHS == BE->getRHS())
1491 return E;
Jim Grosbach13760bd2015-05-30 01:25:56 +00001492 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001493 }
1494 }
1495
1496 llvm_unreachable("Invalid expression kind!");
1497}
1498
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001499/// ParseExpression. This differs from the default "parseExpression" in that
1500/// it handles modifiers.
Ulrich Weigand96e65782013-06-20 16:23:52 +00001501bool PPCAsmParser::
1502ParseExpression(const MCExpr *&EVal) {
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001503
1504 if (isDarwin())
1505 return ParseDarwinExpression(EVal);
1506
1507 // (ELF Platforms)
1508 // Handle \code @l/@ha \endcode
Ulrich Weigand96e65782013-06-20 16:23:52 +00001509 if (getParser().parseExpression(EVal))
1510 return true;
1511
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001512 EVal = FixupVariantKind(EVal);
1513
Ulrich Weigand96e65782013-06-20 16:23:52 +00001514 PPCMCExpr::VariantKind Variant;
1515 const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
1516 if (E)
Jim Grosbach13760bd2015-05-30 01:25:56 +00001517 EVal = PPCMCExpr::create(Variant, E, false, getParser().getContext());
Ulrich Weigand96e65782013-06-20 16:23:52 +00001518
1519 return false;
1520}
1521
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001522/// ParseDarwinExpression. (MachO Platforms)
1523/// This differs from the default "parseExpression" in that it handles detection
1524/// of the \code hi16(), ha16() and lo16() \endcode modifiers. At present,
1525/// parseExpression() doesn't recognise the modifiers when in the Darwin/MachO
Eric Christopher87590fa2016-06-16 01:00:53 +00001526/// syntax form so it is done here. TODO: Determine if there is merit in
1527/// arranging for this to be done at a higher level.
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001528bool PPCAsmParser::
1529ParseDarwinExpression(const MCExpr *&EVal) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001530 MCAsmParser &Parser = getParser();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001531 PPCMCExpr::VariantKind Variant = PPCMCExpr::VK_PPC_None;
1532 switch (getLexer().getKind()) {
1533 default:
1534 break;
1535 case AsmToken::Identifier:
1536 // Compiler-generated Darwin identifiers begin with L,l,_ or "; thus
1537 // something starting with any other char should be part of the
1538 // asm syntax. If handwritten asm includes an identifier like lo16,
1539 // then all bets are off - but no-one would do that, right?
1540 StringRef poss = Parser.getTok().getString();
1541 if (poss.equals_lower("lo16")) {
1542 Variant = PPCMCExpr::VK_PPC_LO;
1543 } else if (poss.equals_lower("hi16")) {
1544 Variant = PPCMCExpr::VK_PPC_HI;
1545 } else if (poss.equals_lower("ha16")) {
1546 Variant = PPCMCExpr::VK_PPC_HA;
1547 }
1548 if (Variant != PPCMCExpr::VK_PPC_None) {
1549 Parser.Lex(); // Eat the xx16
1550 if (getLexer().isNot(AsmToken::LParen))
1551 return Error(Parser.getTok().getLoc(), "expected '('");
1552 Parser.Lex(); // Eat the '('
1553 }
1554 break;
1555 }
1556
1557 if (getParser().parseExpression(EVal))
1558 return true;
1559
1560 if (Variant != PPCMCExpr::VK_PPC_None) {
1561 if (getLexer().isNot(AsmToken::RParen))
1562 return Error(Parser.getTok().getLoc(), "expected ')'");
1563 Parser.Lex(); // Eat the ')'
Jim Grosbach13760bd2015-05-30 01:25:56 +00001564 EVal = PPCMCExpr::create(Variant, EVal, false, getParser().getContext());
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001565 }
1566 return false;
1567}
1568
1569/// ParseOperand
1570/// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1571/// rNN for MachO.
David Blaikie960ea3f2014-06-08 16:18:35 +00001572bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001573 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001574 SMLoc S = Parser.getTok().getLoc();
1575 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1576 const MCExpr *EVal;
Ulrich Weigand640192d2013-05-03 19:49:39 +00001577
1578 // Attempt to parse the next token as an immediate
1579 switch (getLexer().getKind()) {
1580 // Special handling for register names. These are interpreted
1581 // as immediates corresponding to the register number.
1582 case AsmToken::Percent:
1583 Parser.Lex(); // Eat the '%'.
1584 unsigned RegNo;
1585 int64_t IntVal;
1586 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1587 Parser.Lex(); // Eat the identifier token.
David Blaikie960ea3f2014-06-08 16:18:35 +00001588 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001589 return false;
1590 }
1591 return Error(S, "invalid register name");
1592
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001593 case AsmToken::Identifier:
1594 // Note that non-register-name identifiers from the compiler will begin
1595 // with '_', 'L'/'l' or '"'. Of course, handwritten asm could include
1596 // identifiers like r31foo - so we fall through in the event that parsing
1597 // a register name fails.
1598 if (isDarwin()) {
1599 unsigned RegNo;
1600 int64_t IntVal;
1601 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1602 Parser.Lex(); // Eat the identifier token.
David Blaikie960ea3f2014-06-08 16:18:35 +00001603 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001604 return false;
1605 }
1606 }
Justin Bognerb03fd122016-08-17 05:10:15 +00001607 // Fall-through to process non-register-name identifiers as expression.
1608 LLVM_FALLTHROUGH;
Ulrich Weigand640192d2013-05-03 19:49:39 +00001609 // All other expressions
1610 case AsmToken::LParen:
1611 case AsmToken::Plus:
1612 case AsmToken::Minus:
1613 case AsmToken::Integer:
Ulrich Weigand640192d2013-05-03 19:49:39 +00001614 case AsmToken::Dot:
1615 case AsmToken::Dollar:
Roman Divackya26f9a62014-03-12 19:25:57 +00001616 case AsmToken::Exclaim:
1617 case AsmToken::Tilde:
Ulrich Weigand96e65782013-06-20 16:23:52 +00001618 if (!ParseExpression(EVal))
Ulrich Weigand640192d2013-05-03 19:49:39 +00001619 break;
1620 /* fall through */
1621 default:
1622 return Error(S, "unknown operand");
1623 }
1624
Ulrich Weigand640192d2013-05-03 19:49:39 +00001625 // Push the parsed operand into the list of operands
David Blaikie960ea3f2014-06-08 16:18:35 +00001626 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001627
Ulrich Weigand42a09dc2013-07-02 21:31:59 +00001628 // Check whether this is a TLS call expression
1629 bool TLSCall = false;
1630 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
1631 TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
1632
1633 if (TLSCall && getLexer().is(AsmToken::LParen)) {
1634 const MCExpr *TLSSym;
1635
1636 Parser.Lex(); // Eat the '('.
1637 S = Parser.getTok().getLoc();
1638 if (ParseExpression(TLSSym))
1639 return Error(S, "invalid TLS call expression");
1640 if (getLexer().isNot(AsmToken::RParen))
1641 return Error(Parser.getTok().getLoc(), "missing ')'");
1642 E = Parser.getTok().getLoc();
1643 Parser.Lex(); // Eat the ')'.
1644
David Blaikie960ea3f2014-06-08 16:18:35 +00001645 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
Ulrich Weigand42a09dc2013-07-02 21:31:59 +00001646 }
1647
1648 // Otherwise, check for D-form memory operands
1649 if (!TLSCall && getLexer().is(AsmToken::LParen)) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001650 Parser.Lex(); // Eat the '('.
1651 S = Parser.getTok().getLoc();
1652
1653 int64_t IntVal;
1654 switch (getLexer().getKind()) {
1655 case AsmToken::Percent:
1656 Parser.Lex(); // Eat the '%'.
1657 unsigned RegNo;
1658 if (MatchRegisterName(Parser.getTok(), RegNo, IntVal))
1659 return Error(S, "invalid register name");
1660 Parser.Lex(); // Eat the identifier token.
1661 break;
1662
1663 case AsmToken::Integer:
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001664 if (!isDarwin()) {
1665 if (getParser().parseAbsoluteExpression(IntVal) ||
Ulrich Weigand640192d2013-05-03 19:49:39 +00001666 IntVal < 0 || IntVal > 31)
1667 return Error(S, "invalid register number");
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001668 } else {
1669 return Error(S, "unexpected integer value");
1670 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001671 break;
1672
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001673 case AsmToken::Identifier:
1674 if (isDarwin()) {
1675 unsigned RegNo;
1676 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1677 Parser.Lex(); // Eat the identifier token.
1678 break;
1679 }
1680 }
Justin Bognerb03fd122016-08-17 05:10:15 +00001681 LLVM_FALLTHROUGH;
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001682
Ulrich Weigand640192d2013-05-03 19:49:39 +00001683 default:
1684 return Error(S, "invalid memory operand");
1685 }
1686
1687 if (getLexer().isNot(AsmToken::RParen))
1688 return Error(Parser.getTok().getLoc(), "missing ')'");
1689 E = Parser.getTok().getLoc();
1690 Parser.Lex(); // Eat the ')'.
1691
David Blaikie960ea3f2014-06-08 16:18:35 +00001692 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001693 }
1694
1695 return false;
1696}
1697
1698/// Parse an instruction mnemonic followed by its operands.
David Blaikie960ea3f2014-06-08 16:18:35 +00001699bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1700 SMLoc NameLoc, OperandVector &Operands) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001701 // The first operand is the token for the instruction name.
Ulrich Weigand86247b62013-06-24 16:52:04 +00001702 // If the next character is a '+' or '-', we need to add it to the
1703 // instruction name, to match what TableGen is doing.
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001704 std::string NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001705 if (getLexer().is(AsmToken::Plus)) {
1706 getLexer().Lex();
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001707 NewOpcode = Name;
1708 NewOpcode += '+';
1709 Name = NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001710 }
1711 if (getLexer().is(AsmToken::Minus)) {
1712 getLexer().Lex();
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001713 NewOpcode = Name;
1714 NewOpcode += '-';
1715 Name = NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001716 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001717 // If the instruction ends in a '.', we need to create a separate
1718 // token for it, to match what TableGen is doing.
1719 size_t Dot = Name.find('.');
1720 StringRef Mnemonic = Name.slice(0, Dot);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001721 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1722 Operands.push_back(
1723 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1724 else
1725 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001726 if (Dot != StringRef::npos) {
1727 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1728 StringRef DotStr = Name.slice(Dot, StringRef::npos);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001729 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1730 Operands.push_back(
1731 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1732 else
1733 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001734 }
1735
1736 // If there are no more operands then finish
1737 if (getLexer().is(AsmToken::EndOfStatement))
1738 return false;
1739
1740 // Parse the first operand
1741 if (ParseOperand(Operands))
1742 return true;
1743
1744 while (getLexer().isNot(AsmToken::EndOfStatement) &&
1745 getLexer().is(AsmToken::Comma)) {
1746 // Consume the comma token
Nirav Davefd910412016-06-17 16:06:17 +00001747 Lex();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001748
1749 // Parse the next operand
1750 if (ParseOperand(Operands))
1751 return true;
1752 }
1753
Hal Finkelfefcfff2015-04-23 22:47:57 +00001754 // We'll now deal with an unfortunate special case: the syntax for the dcbt
1755 // and dcbtst instructions differs for server vs. embedded cores.
1756 // The syntax for dcbt is:
1757 // dcbt ra, rb, th [server]
1758 // dcbt th, ra, rb [embedded]
1759 // where th can be omitted when it is 0. dcbtst is the same. We take the
1760 // server form to be the default, so swap the operands if we're parsing for
1761 // an embedded core (they'll be swapped again upon printing).
Akira Hatanakabd9fc282015-11-14 05:20:05 +00001762 if (getSTI().getFeatureBits()[PPC::FeatureBookE] &&
Hal Finkelfefcfff2015-04-23 22:47:57 +00001763 Operands.size() == 4 &&
1764 (Name == "dcbt" || Name == "dcbtst")) {
1765 std::swap(Operands[1], Operands[3]);
1766 std::swap(Operands[2], Operands[1]);
1767 }
1768
Ulrich Weigand640192d2013-05-03 19:49:39 +00001769 return false;
1770}
1771
1772/// ParseDirective parses the PPC specific directives
1773bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1774 StringRef IDVal = DirectiveID.getIdentifier();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001775 if (!isDarwin()) {
1776 if (IDVal == ".word")
1777 return ParseDirectiveWord(2, DirectiveID.getLoc());
1778 if (IDVal == ".llong")
1779 return ParseDirectiveWord(8, DirectiveID.getLoc());
1780 if (IDVal == ".tc")
1781 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc());
1782 if (IDVal == ".machine")
1783 return ParseDirectiveMachine(DirectiveID.getLoc());
Ulrich Weigand0daa5162014-07-20 22:56:57 +00001784 if (IDVal == ".abiversion")
1785 return ParseDirectiveAbiVersion(DirectiveID.getLoc());
Ulrich Weigandbb686102014-07-20 23:06:03 +00001786 if (IDVal == ".localentry")
1787 return ParseDirectiveLocalEntry(DirectiveID.getLoc());
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001788 } else {
1789 if (IDVal == ".machine")
1790 return ParseDarwinDirectiveMachine(DirectiveID.getLoc());
1791 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001792 return true;
1793}
1794
1795/// ParseDirectiveWord
1796/// ::= .word [ expression (, expression)* ]
1797bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001798 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001799 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1800 for (;;) {
1801 const MCExpr *Value;
David Majnemera375b262015-10-26 02:45:50 +00001802 SMLoc ExprLoc = getLexer().getLoc();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001803 if (getParser().parseExpression(Value))
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001804 return false;
Ulrich Weigand640192d2013-05-03 19:49:39 +00001805
David Majnemera375b262015-10-26 02:45:50 +00001806 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
1807 assert(Size <= 8 && "Invalid size");
1808 uint64_t IntValue = MCE->getValue();
1809 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1810 return Error(ExprLoc, "literal value out of range for directive");
1811 getStreamer().EmitIntValue(IntValue, Size);
1812 } else {
1813 getStreamer().EmitValue(Value, Size, ExprLoc);
1814 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001815
1816 if (getLexer().is(AsmToken::EndOfStatement))
1817 break;
1818
1819 if (getLexer().isNot(AsmToken::Comma))
1820 return Error(L, "unexpected token in directive");
1821 Parser.Lex();
1822 }
1823 }
1824
1825 Parser.Lex();
1826 return false;
1827}
1828
1829/// ParseDirectiveTC
1830/// ::= .tc [ symbol (, expression)* ]
1831bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001832 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001833 // Skip TC symbol, which is only used with XCOFF.
1834 while (getLexer().isNot(AsmToken::EndOfStatement)
1835 && getLexer().isNot(AsmToken::Comma))
1836 Parser.Lex();
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001837 if (getLexer().isNot(AsmToken::Comma)) {
1838 Error(L, "unexpected token in directive");
1839 return false;
1840 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001841 Parser.Lex();
1842
1843 // Align to word size.
1844 getParser().getStreamer().EmitValueToAlignment(Size);
1845
1846 // Emit expressions.
1847 return ParseDirectiveWord(Size, L);
1848}
1849
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001850/// ParseDirectiveMachine (ELF platforms)
Ulrich Weigand55daa772013-07-09 10:00:34 +00001851/// ::= .machine [ cpu | "push" | "pop" ]
1852bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001853 MCAsmParser &Parser = getParser();
Ulrich Weigand55daa772013-07-09 10:00:34 +00001854 if (getLexer().isNot(AsmToken::Identifier) &&
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001855 getLexer().isNot(AsmToken::String)) {
1856 Error(L, "unexpected token in directive");
1857 return false;
1858 }
Ulrich Weigand55daa772013-07-09 10:00:34 +00001859
1860 StringRef CPU = Parser.getTok().getIdentifier();
1861 Parser.Lex();
1862
1863 // FIXME: Right now, the parser always allows any available
1864 // instruction, so the .machine directive is not useful.
1865 // Implement ".machine any" (by doing nothing) for the benefit
1866 // of existing assembler code. Likewise, we can then implement
1867 // ".machine push" and ".machine pop" as no-op.
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001868 if (CPU != "any" && CPU != "push" && CPU != "pop") {
1869 Error(L, "unrecognized machine type");
1870 return false;
1871 }
Ulrich Weigand55daa772013-07-09 10:00:34 +00001872
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001873 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1874 Error(L, "unexpected token in directive");
1875 return false;
1876 }
Rafael Espindola6b9ee9b2014-01-25 02:35:56 +00001877 PPCTargetStreamer &TStreamer =
1878 *static_cast<PPCTargetStreamer *>(
1879 getParser().getStreamer().getTargetStreamer());
1880 TStreamer.emitMachine(CPU);
Ulrich Weigand55daa772013-07-09 10:00:34 +00001881
1882 return false;
1883}
1884
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001885/// ParseDarwinDirectiveMachine (Mach-o platforms)
1886/// ::= .machine cpu-identifier
1887bool PPCAsmParser::ParseDarwinDirectiveMachine(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001888 MCAsmParser &Parser = getParser();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001889 if (getLexer().isNot(AsmToken::Identifier) &&
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001890 getLexer().isNot(AsmToken::String)) {
1891 Error(L, "unexpected token in directive");
1892 return false;
1893 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001894
1895 StringRef CPU = Parser.getTok().getIdentifier();
1896 Parser.Lex();
1897
1898 // FIXME: this is only the 'default' set of cpu variants.
1899 // However we don't act on this information at present, this is simply
1900 // allowing parsing to proceed with minimal sanity checking.
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001901 if (CPU != "ppc7400" && CPU != "ppc" && CPU != "ppc64") {
1902 Error(L, "unrecognized cpu type");
1903 return false;
1904 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001905
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001906 if (isPPC64() && (CPU == "ppc7400" || CPU == "ppc")) {
1907 Error(L, "wrong cpu type specified for 64bit");
1908 return false;
1909 }
1910 if (!isPPC64() && CPU == "ppc64") {
1911 Error(L, "wrong cpu type specified for 32bit");
1912 return false;
1913 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001914
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001915 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1916 Error(L, "unexpected token in directive");
1917 return false;
1918 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001919
1920 return false;
1921}
1922
Ulrich Weigand0daa5162014-07-20 22:56:57 +00001923/// ParseDirectiveAbiVersion
1924/// ::= .abiversion constant-expression
1925bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
1926 int64_t AbiVersion;
1927 if (getParser().parseAbsoluteExpression(AbiVersion)){
1928 Error(L, "expected constant expression");
1929 return false;
1930 }
1931 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1932 Error(L, "unexpected token in directive");
1933 return false;
1934 }
1935
1936 PPCTargetStreamer &TStreamer =
1937 *static_cast<PPCTargetStreamer *>(
1938 getParser().getStreamer().getTargetStreamer());
1939 TStreamer.emitAbiVersion(AbiVersion);
1940
1941 return false;
1942}
1943
Ulrich Weigandbb686102014-07-20 23:06:03 +00001944/// ParseDirectiveLocalEntry
1945/// ::= .localentry symbol, expression
1946bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
1947 StringRef Name;
1948 if (getParser().parseIdentifier(Name)) {
1949 Error(L, "expected identifier in directive");
1950 return false;
1951 }
Rafael Espindola95fb9b92015-06-02 20:38:46 +00001952 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
Ulrich Weigandbb686102014-07-20 23:06:03 +00001953
1954 if (getLexer().isNot(AsmToken::Comma)) {
1955 Error(L, "unexpected token in directive");
1956 return false;
1957 }
1958 Lex();
1959
1960 const MCExpr *Expr;
1961 if (getParser().parseExpression(Expr)) {
1962 Error(L, "expected expression");
1963 return false;
1964 }
1965
1966 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1967 Error(L, "unexpected token in directive");
1968 return false;
1969 }
1970
1971 PPCTargetStreamer &TStreamer =
1972 *static_cast<PPCTargetStreamer *>(
1973 getParser().getStreamer().getTargetStreamer());
1974 TStreamer.emitLocalEntry(Sym, Expr);
1975
1976 return false;
1977}
1978
1979
1980
Ulrich Weigand640192d2013-05-03 19:49:39 +00001981/// Force static initialization.
1982extern "C" void LLVMInitializePowerPCAsmParser() {
1983 RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target);
1984 RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target);
Bill Schmidt0a9170d2013-07-26 01:35:43 +00001985 RegisterMCAsmParser<PPCAsmParser> C(ThePPC64LETarget);
Ulrich Weigand640192d2013-05-03 19:49:39 +00001986}
1987
1988#define GET_REGISTER_MATCHER
1989#define GET_MATCHER_IMPLEMENTATION
1990#include "PPCGenAsmMatcher.inc"
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001991
1992// Define this matcher function after the auto-generated include so we
1993// have the match class enum definitions.
David Blaikie960ea3f2014-06-08 16:18:35 +00001994unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001995 unsigned Kind) {
1996 // If the kind is a token for a literal immediate, check if our asm
1997 // operand matches. This is for InstAliases which have a fixed-value
1998 // immediate in the syntax.
1999 int64_t ImmVal;
2000 switch (Kind) {
2001 case MCK_0: ImmVal = 0; break;
2002 case MCK_1: ImmVal = 1; break;
Roman Divacky62cb6352013-09-12 17:50:54 +00002003 case MCK_2: ImmVal = 2; break;
2004 case MCK_3: ImmVal = 3; break;
Joerg Sonnenbergerdda8e782014-07-30 09:24:37 +00002005 case MCK_4: ImmVal = 4; break;
2006 case MCK_5: ImmVal = 5; break;
2007 case MCK_6: ImmVal = 6; break;
2008 case MCK_7: ImmVal = 7; break;
Ulrich Weigandc0944b52013-07-08 14:49:37 +00002009 default: return Match_InvalidOperand;
2010 }
2011
David Blaikie960ea3f2014-06-08 16:18:35 +00002012 PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
2013 if (Op.isImm() && Op.getImm() == ImmVal)
Ulrich Weigandc0944b52013-07-08 14:49:37 +00002014 return Match_Success;
2015
2016 return Match_InvalidOperand;
2017}
2018
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002019const MCExpr *
2020PPCAsmParser::applyModifierToExpr(const MCExpr *E,
2021 MCSymbolRefExpr::VariantKind Variant,
2022 MCContext &Ctx) {
2023 switch (Variant) {
2024 case MCSymbolRefExpr::VK_PPC_LO:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002025 return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002026 case MCSymbolRefExpr::VK_PPC_HI:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002027 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002028 case MCSymbolRefExpr::VK_PPC_HA:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002029 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002030 case MCSymbolRefExpr::VK_PPC_HIGHER:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002031 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002032 case MCSymbolRefExpr::VK_PPC_HIGHERA:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002033 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002034 case MCSymbolRefExpr::VK_PPC_HIGHEST:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002035 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002036 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
Jim Grosbach13760bd2015-05-30 01:25:56 +00002037 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, false, Ctx);
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002038 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002039 return nullptr;
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00002040 }
2041}