blob: 1b1e31acd42f598f3c75a139469bb2dcb2087551 [file] [log] [blame]
Ulrich Weigand640192d2013-05-03 19:49:39 +00001//===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/PPCMCTargetDesc.h"
Ulrich Weigand96e65782013-06-20 16:23:52 +000011#include "MCTargetDesc/PPCMCExpr.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/SmallString.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringSwitch.h"
17#include "llvm/ADT/Twine.h"
Ulrich Weigandbb686102014-07-20 23:06:03 +000018#include "llvm/MC/MCContext.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000019#include "llvm/MC/MCExpr.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCParser/MCAsmLexer.h"
23#include "llvm/MC/MCParser/MCAsmParser.h"
24#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25#include "llvm/MC/MCRegisterInfo.h"
26#include "llvm/MC/MCStreamer.h"
27#include "llvm/MC/MCSubtargetInfo.h"
28#include "llvm/MC/MCTargetAsmParser.h"
Ulrich Weigand640192d2013-05-03 19:49:39 +000029#include "llvm/Support/SourceMgr.h"
30#include "llvm/Support/TargetRegistry.h"
31#include "llvm/Support/raw_ostream.h"
32
33using namespace llvm;
34
Craig Topperf7df7222014-12-18 05:02:14 +000035static const MCPhysReg RRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000036 PPC::R0, PPC::R1, PPC::R2, PPC::R3,
37 PPC::R4, PPC::R5, PPC::R6, PPC::R7,
38 PPC::R8, PPC::R9, PPC::R10, PPC::R11,
39 PPC::R12, PPC::R13, PPC::R14, PPC::R15,
40 PPC::R16, PPC::R17, PPC::R18, PPC::R19,
41 PPC::R20, PPC::R21, PPC::R22, PPC::R23,
42 PPC::R24, PPC::R25, PPC::R26, PPC::R27,
43 PPC::R28, PPC::R29, PPC::R30, PPC::R31
44};
Craig Topperf7df7222014-12-18 05:02:14 +000045static const MCPhysReg RRegsNoR0[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000046 PPC::ZERO,
47 PPC::R1, PPC::R2, PPC::R3,
48 PPC::R4, PPC::R5, PPC::R6, PPC::R7,
49 PPC::R8, PPC::R9, PPC::R10, PPC::R11,
50 PPC::R12, PPC::R13, PPC::R14, PPC::R15,
51 PPC::R16, PPC::R17, PPC::R18, PPC::R19,
52 PPC::R20, PPC::R21, PPC::R22, PPC::R23,
53 PPC::R24, PPC::R25, PPC::R26, PPC::R27,
54 PPC::R28, PPC::R29, PPC::R30, PPC::R31
55};
Craig Topperf7df7222014-12-18 05:02:14 +000056static const MCPhysReg XRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000057 PPC::X0, PPC::X1, PPC::X2, PPC::X3,
58 PPC::X4, PPC::X5, PPC::X6, PPC::X7,
59 PPC::X8, PPC::X9, PPC::X10, PPC::X11,
60 PPC::X12, PPC::X13, PPC::X14, PPC::X15,
61 PPC::X16, PPC::X17, PPC::X18, PPC::X19,
62 PPC::X20, PPC::X21, PPC::X22, PPC::X23,
63 PPC::X24, PPC::X25, PPC::X26, PPC::X27,
64 PPC::X28, PPC::X29, PPC::X30, PPC::X31
65};
Craig Topperf7df7222014-12-18 05:02:14 +000066static const MCPhysReg XRegsNoX0[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000067 PPC::ZERO8,
68 PPC::X1, PPC::X2, PPC::X3,
69 PPC::X4, PPC::X5, PPC::X6, PPC::X7,
70 PPC::X8, PPC::X9, PPC::X10, PPC::X11,
71 PPC::X12, PPC::X13, PPC::X14, PPC::X15,
72 PPC::X16, PPC::X17, PPC::X18, PPC::X19,
73 PPC::X20, PPC::X21, PPC::X22, PPC::X23,
74 PPC::X24, PPC::X25, PPC::X26, PPC::X27,
75 PPC::X28, PPC::X29, PPC::X30, PPC::X31
76};
Craig Topperf7df7222014-12-18 05:02:14 +000077static const MCPhysReg FRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000078 PPC::F0, PPC::F1, PPC::F2, PPC::F3,
79 PPC::F4, PPC::F5, PPC::F6, PPC::F7,
80 PPC::F8, PPC::F9, PPC::F10, PPC::F11,
81 PPC::F12, PPC::F13, PPC::F14, PPC::F15,
82 PPC::F16, PPC::F17, PPC::F18, PPC::F19,
83 PPC::F20, PPC::F21, PPC::F22, PPC::F23,
84 PPC::F24, PPC::F25, PPC::F26, PPC::F27,
85 PPC::F28, PPC::F29, PPC::F30, PPC::F31
86};
Craig Topperf7df7222014-12-18 05:02:14 +000087static const MCPhysReg VRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +000088 PPC::V0, PPC::V1, PPC::V2, PPC::V3,
89 PPC::V4, PPC::V5, PPC::V6, PPC::V7,
90 PPC::V8, PPC::V9, PPC::V10, PPC::V11,
91 PPC::V12, PPC::V13, PPC::V14, PPC::V15,
92 PPC::V16, PPC::V17, PPC::V18, PPC::V19,
93 PPC::V20, PPC::V21, PPC::V22, PPC::V23,
94 PPC::V24, PPC::V25, PPC::V26, PPC::V27,
95 PPC::V28, PPC::V29, PPC::V30, PPC::V31
96};
Craig Topperf7df7222014-12-18 05:02:14 +000097static const MCPhysReg VSRegs[64] = {
Hal Finkel27774d92014-03-13 07:58:58 +000098 PPC::VSL0, PPC::VSL1, PPC::VSL2, PPC::VSL3,
99 PPC::VSL4, PPC::VSL5, PPC::VSL6, PPC::VSL7,
100 PPC::VSL8, PPC::VSL9, PPC::VSL10, PPC::VSL11,
101 PPC::VSL12, PPC::VSL13, PPC::VSL14, PPC::VSL15,
102 PPC::VSL16, PPC::VSL17, PPC::VSL18, PPC::VSL19,
103 PPC::VSL20, PPC::VSL21, PPC::VSL22, PPC::VSL23,
104 PPC::VSL24, PPC::VSL25, PPC::VSL26, PPC::VSL27,
105 PPC::VSL28, PPC::VSL29, PPC::VSL30, PPC::VSL31,
106
107 PPC::VSH0, PPC::VSH1, PPC::VSH2, PPC::VSH3,
108 PPC::VSH4, PPC::VSH5, PPC::VSH6, PPC::VSH7,
109 PPC::VSH8, PPC::VSH9, PPC::VSH10, PPC::VSH11,
110 PPC::VSH12, PPC::VSH13, PPC::VSH14, PPC::VSH15,
111 PPC::VSH16, PPC::VSH17, PPC::VSH18, PPC::VSH19,
112 PPC::VSH20, PPC::VSH21, PPC::VSH22, PPC::VSH23,
113 PPC::VSH24, PPC::VSH25, PPC::VSH26, PPC::VSH27,
114 PPC::VSH28, PPC::VSH29, PPC::VSH30, PPC::VSH31
115};
Craig Topperf7df7222014-12-18 05:02:14 +0000116static const MCPhysReg VSFRegs[64] = {
Hal Finkel19be5062014-03-29 05:29:01 +0000117 PPC::F0, PPC::F1, PPC::F2, PPC::F3,
118 PPC::F4, PPC::F5, PPC::F6, PPC::F7,
119 PPC::F8, PPC::F9, PPC::F10, PPC::F11,
120 PPC::F12, PPC::F13, PPC::F14, PPC::F15,
121 PPC::F16, PPC::F17, PPC::F18, PPC::F19,
122 PPC::F20, PPC::F21, PPC::F22, PPC::F23,
123 PPC::F24, PPC::F25, PPC::F26, PPC::F27,
124 PPC::F28, PPC::F29, PPC::F30, PPC::F31,
125
126 PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
127 PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
128 PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
129 PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
130 PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
131 PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
132 PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
133 PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
134};
Craig Topperf7df7222014-12-18 05:02:14 +0000135static const MCPhysReg CRBITRegs[32] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000136 PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN,
137 PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN,
138 PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN,
139 PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN,
140 PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN,
141 PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN,
142 PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN,
143 PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN
144};
Craig Topperf7df7222014-12-18 05:02:14 +0000145static const MCPhysReg CRRegs[8] = {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000146 PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
147 PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
148};
149
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000150// Evaluate an expression containing condition register
151// or condition register field symbols. Returns positive
152// value on success, or -1 on error.
153static int64_t
154EvaluateCRExpr(const MCExpr *E) {
155 switch (E->getKind()) {
156 case MCExpr::Target:
157 return -1;
158
159 case MCExpr::Constant: {
160 int64_t Res = cast<MCConstantExpr>(E)->getValue();
161 return Res < 0 ? -1 : Res;
162 }
163
164 case MCExpr::SymbolRef: {
165 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
166 StringRef Name = SRE->getSymbol().getName();
167
168 if (Name == "lt") return 0;
169 if (Name == "gt") return 1;
170 if (Name == "eq") return 2;
171 if (Name == "so") return 3;
172 if (Name == "un") return 3;
173
174 if (Name == "cr0") return 0;
175 if (Name == "cr1") return 1;
176 if (Name == "cr2") return 2;
177 if (Name == "cr3") return 3;
178 if (Name == "cr4") return 4;
179 if (Name == "cr5") return 5;
180 if (Name == "cr6") return 6;
181 if (Name == "cr7") return 7;
182
183 return -1;
184 }
185
186 case MCExpr::Unary:
187 return -1;
188
189 case MCExpr::Binary: {
190 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
191 int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
192 int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
193 int64_t Res;
194
195 if (LHSVal < 0 || RHSVal < 0)
196 return -1;
197
198 switch (BE->getOpcode()) {
199 default: return -1;
200 case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
201 case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
202 }
203
204 return Res < 0 ? -1 : Res;
205 }
206 }
207
208 llvm_unreachable("Invalid expression kind!");
209}
210
Craig Topperf7df7222014-12-18 05:02:14 +0000211namespace {
212
Ulrich Weigand640192d2013-05-03 19:49:39 +0000213struct PPCOperand;
214
215class PPCAsmParser : public MCTargetAsmParser {
216 MCSubtargetInfo &STI;
Hal Finkel0096dbd2013-09-12 14:40:06 +0000217 const MCInstrInfo &MII;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000218 bool IsPPC64;
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000219 bool IsDarwin;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000220
Rafael Espindola961d4692014-11-11 05:18:41 +0000221 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
222 bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000223
224 bool isPPC64() const { return IsPPC64; }
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000225 bool isDarwin() const { return IsDarwin; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000226
227 bool MatchRegisterName(const AsmToken &Tok,
228 unsigned &RegNo, int64_t &IntVal);
229
Craig Topper0d3fa922014-04-29 07:57:37 +0000230 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000231
Ulrich Weigand96e65782013-06-20 16:23:52 +0000232 const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
233 PPCMCExpr::VariantKind &Variant);
Ulrich Weigand52cf8e42013-07-09 16:41:09 +0000234 const MCExpr *FixupVariantKind(const MCExpr *E);
Ulrich Weigand96e65782013-06-20 16:23:52 +0000235 bool ParseExpression(const MCExpr *&EVal);
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000236 bool ParseDarwinExpression(const MCExpr *&EVal);
Ulrich Weigand96e65782013-06-20 16:23:52 +0000237
David Blaikie960ea3f2014-06-08 16:18:35 +0000238 bool ParseOperand(OperandVector &Operands);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000239
240 bool ParseDirectiveWord(unsigned Size, SMLoc L);
241 bool ParseDirectiveTC(unsigned Size, SMLoc L);
Ulrich Weigand55daa772013-07-09 10:00:34 +0000242 bool ParseDirectiveMachine(SMLoc L);
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000243 bool ParseDarwinDirectiveMachine(SMLoc L);
Ulrich Weigand0daa5162014-07-20 22:56:57 +0000244 bool ParseDirectiveAbiVersion(SMLoc L);
Ulrich Weigandbb686102014-07-20 23:06:03 +0000245 bool ParseDirectiveLocalEntry(SMLoc L);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000246
247 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +0000248 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000249 uint64_t &ErrorInfo,
Craig Topper0d3fa922014-04-29 07:57:37 +0000250 bool MatchingInlineAsm) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000251
David Blaikie960ea3f2014-06-08 16:18:35 +0000252 void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
Ulrich Weigandd8394902013-05-03 19:50:27 +0000253
Ulrich Weigand640192d2013-05-03 19:49:39 +0000254 /// @name Auto-generated Match Functions
255 /// {
256
257#define GET_ASSEMBLER_HEADER
258#include "PPCGenAsmMatcher.inc"
259
260 /// }
261
262
263public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000264 PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
Rafael Espindola961d4692014-11-11 05:18:41 +0000265 const MCInstrInfo &_MII, const MCTargetOptions &Options)
266 : MCTargetAsmParser(), STI(_STI), MII(_MII) {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000267 // Check for 64-bit vs. 32-bit pointer mode.
268 Triple TheTriple(STI.getTargetTriple());
Bill Schmidt0a9170d2013-07-26 01:35:43 +0000269 IsPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
270 TheTriple.getArch() == Triple::ppc64le);
Iain Sandoee0b4cb62013-12-14 13:34:02 +0000271 IsDarwin = TheTriple.isMacOSX();
Ulrich Weigand640192d2013-05-03 19:49:39 +0000272 // Initialize the set of available features.
273 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
274 }
275
David Blaikie960ea3f2014-06-08 16:18:35 +0000276 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
277 SMLoc NameLoc, OperandVector &Operands) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000278
Craig Topper0d3fa922014-04-29 07:57:37 +0000279 bool ParseDirective(AsmToken DirectiveID) override;
Ulrich Weigandc0944b52013-07-08 14:49:37 +0000280
David Blaikie960ea3f2014-06-08 16:18:35 +0000281 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
Craig Topper0d3fa922014-04-29 07:57:37 +0000282 unsigned Kind) override;
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +0000283
Craig Topper0d3fa922014-04-29 07:57:37 +0000284 const MCExpr *applyModifierToExpr(const MCExpr *E,
285 MCSymbolRefExpr::VariantKind,
286 MCContext &Ctx) override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000287};
288
289/// PPCOperand - Instances of this class represent a parsed PowerPC machine
290/// instruction.
291struct PPCOperand : public MCParsedAsmOperand {
292 enum KindTy {
293 Token,
294 Immediate,
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000295 ContextImmediate,
Ulrich Weigand5b427592013-07-05 12:22:36 +0000296 Expression,
297 TLSRegister
Ulrich Weigand640192d2013-05-03 19:49:39 +0000298 } Kind;
299
300 SMLoc StartLoc, EndLoc;
301 bool IsPPC64;
302
303 struct TokOp {
304 const char *Data;
305 unsigned Length;
306 };
307
308 struct ImmOp {
309 int64_t Val;
310 };
311
312 struct ExprOp {
313 const MCExpr *Val;
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000314 int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
Ulrich Weigand640192d2013-05-03 19:49:39 +0000315 };
316
Ulrich Weigand5b427592013-07-05 12:22:36 +0000317 struct TLSRegOp {
318 const MCSymbolRefExpr *Sym;
319 };
320
Ulrich Weigand640192d2013-05-03 19:49:39 +0000321 union {
322 struct TokOp Tok;
323 struct ImmOp Imm;
324 struct ExprOp Expr;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000325 struct TLSRegOp TLSReg;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000326 };
327
328 PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
329public:
330 PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
331 Kind = o.Kind;
332 StartLoc = o.StartLoc;
333 EndLoc = o.EndLoc;
334 IsPPC64 = o.IsPPC64;
335 switch (Kind) {
336 case Token:
337 Tok = o.Tok;
338 break;
339 case Immediate:
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000340 case ContextImmediate:
Ulrich Weigand640192d2013-05-03 19:49:39 +0000341 Imm = o.Imm;
342 break;
343 case Expression:
344 Expr = o.Expr;
345 break;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000346 case TLSRegister:
347 TLSReg = o.TLSReg;
348 break;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000349 }
350 }
351
352 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper0d3fa922014-04-29 07:57:37 +0000353 SMLoc getStartLoc() const override { return StartLoc; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000354
355 /// getEndLoc - Get the location of the last token of this operand.
Craig Topper0d3fa922014-04-29 07:57:37 +0000356 SMLoc getEndLoc() const override { return EndLoc; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000357
358 /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
359 bool isPPC64() const { return IsPPC64; }
360
361 int64_t getImm() const {
362 assert(Kind == Immediate && "Invalid access!");
363 return Imm.Val;
364 }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000365 int64_t getImmS16Context() const {
366 assert((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!");
367 if (Kind == Immediate)
368 return Imm.Val;
369 return static_cast<int16_t>(Imm.Val);
370 }
371 int64_t getImmU16Context() const {
372 assert((Kind == Immediate || Kind == ContextImmediate) && "Invalid access!");
373 return Imm.Val;
374 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000375
376 const MCExpr *getExpr() const {
377 assert(Kind == Expression && "Invalid access!");
378 return Expr.Val;
379 }
380
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000381 int64_t getExprCRVal() const {
382 assert(Kind == Expression && "Invalid access!");
383 return Expr.CRVal;
384 }
385
Ulrich Weigand5b427592013-07-05 12:22:36 +0000386 const MCExpr *getTLSReg() const {
387 assert(Kind == TLSRegister && "Invalid access!");
388 return TLSReg.Sym;
389 }
390
Craig Topper0d3fa922014-04-29 07:57:37 +0000391 unsigned getReg() const override {
Ulrich Weigand640192d2013-05-03 19:49:39 +0000392 assert(isRegNumber() && "Invalid access!");
393 return (unsigned) Imm.Val;
394 }
395
Hal Finkel27774d92014-03-13 07:58:58 +0000396 unsigned getVSReg() const {
397 assert(isVSRegNumber() && "Invalid access!");
398 return (unsigned) Imm.Val;
399 }
400
Ulrich Weigand640192d2013-05-03 19:49:39 +0000401 unsigned getCCReg() const {
402 assert(isCCRegNumber() && "Invalid access!");
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000403 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
404 }
405
406 unsigned getCRBit() const {
407 assert(isCRBitNumber() && "Invalid access!");
408 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000409 }
410
411 unsigned getCRBitMask() const {
412 assert(isCRBitMask() && "Invalid access!");
Michael J. Spencerdf1ecbd72013-05-24 22:23:49 +0000413 return 7 - countTrailingZeros<uint64_t>(Imm.Val);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000414 }
415
Craig Topper0d3fa922014-04-29 07:57:37 +0000416 bool isToken() const override { return Kind == Token; }
417 bool isImm() const override { return Kind == Immediate || Kind == Expression; }
Hal Finkel27774d92014-03-13 07:58:58 +0000418 bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
Joerg Sonnenberger9e9623c2014-07-29 22:21:57 +0000419 bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000420 bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
421 bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
422 bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
Joerg Sonnenberger0013b922014-08-08 16:43:49 +0000423 bool isU6ImmX2() const { return Kind == Immediate &&
424 isUInt<6>(getImm()) &&
425 (getImm() & 1) == 0; }
426 bool isU7ImmX4() const { return Kind == Immediate &&
427 isUInt<7>(getImm()) &&
428 (getImm() & 3) == 0; }
429 bool isU8ImmX8() const { return Kind == Immediate &&
430 isUInt<8>(getImm()) &&
431 (getImm() & 7) == 0; }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000432 bool isU16Imm() const {
433 switch (Kind) {
434 case Expression:
435 return true;
436 case Immediate:
437 case ContextImmediate:
438 return isUInt<16>(getImmU16Context());
439 default:
440 return false;
441 }
442 }
443 bool isS16Imm() const {
444 switch (Kind) {
445 case Expression:
446 return true;
447 case Immediate:
448 case ContextImmediate:
449 return isInt<16>(getImmS16Context());
450 default:
451 return false;
452 }
453 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000454 bool isS16ImmX4() const { return Kind == Expression ||
455 (Kind == Immediate && isInt<16>(getImm()) &&
456 (getImm() & 3) == 0); }
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000457 bool isS17Imm() const {
458 switch (Kind) {
459 case Expression:
460 return true;
461 case Immediate:
462 case ContextImmediate:
463 return isInt<17>(getImmS16Context());
464 default:
465 return false;
466 }
467 }
Ulrich Weigand5b427592013-07-05 12:22:36 +0000468 bool isTLSReg() const { return Kind == TLSRegister; }
Joerg Sonnenbergereb9d13f2014-08-08 20:57:58 +0000469 bool isDirectBr() const {
470 if (Kind == Expression)
471 return true;
472 if (Kind != Immediate)
473 return false;
474 // Operand must be 64-bit aligned, signed 27-bit immediate.
475 if ((getImm() & 3) != 0)
476 return false;
477 if (isInt<26>(getImm()))
478 return true;
479 if (!IsPPC64) {
480 // In 32-bit mode, large 32-bit quantities wrap around.
481 if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
482 return true;
483 }
484 return false;
485 }
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000486 bool isCondBr() const { return Kind == Expression ||
487 (Kind == Immediate && isInt<16>(getImm()) &&
488 (getImm() & 3) == 0); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000489 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
Hal Finkel27774d92014-03-13 07:58:58 +0000490 bool isVSRegNumber() const { return Kind == Immediate && isUInt<6>(getImm()); }
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000491 bool isCCRegNumber() const { return (Kind == Expression
492 && isUInt<3>(getExprCRVal())) ||
493 (Kind == Immediate
494 && isUInt<3>(getImm())); }
495 bool isCRBitNumber() const { return (Kind == Expression
496 && isUInt<5>(getExprCRVal())) ||
497 (Kind == Immediate
498 && isUInt<5>(getImm())); }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000499 bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
500 isPowerOf2_32(getImm()); }
Craig Topper0d3fa922014-04-29 07:57:37 +0000501 bool isMem() const override { return false; }
502 bool isReg() const override { return false; }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000503
504 void addRegOperands(MCInst &Inst, unsigned N) const {
505 llvm_unreachable("addRegOperands");
506 }
507
508 void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
509 assert(N == 1 && "Invalid number of operands!");
510 Inst.addOperand(MCOperand::CreateReg(RRegs[getReg()]));
511 }
512
513 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
514 assert(N == 1 && "Invalid number of operands!");
515 Inst.addOperand(MCOperand::CreateReg(RRegsNoR0[getReg()]));
516 }
517
518 void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
519 assert(N == 1 && "Invalid number of operands!");
520 Inst.addOperand(MCOperand::CreateReg(XRegs[getReg()]));
521 }
522
523 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
524 assert(N == 1 && "Invalid number of operands!");
525 Inst.addOperand(MCOperand::CreateReg(XRegsNoX0[getReg()]));
526 }
527
528 void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
529 if (isPPC64())
530 addRegG8RCOperands(Inst, N);
531 else
532 addRegGPRCOperands(Inst, N);
533 }
534
535 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
536 if (isPPC64())
537 addRegG8RCNoX0Operands(Inst, N);
538 else
539 addRegGPRCNoR0Operands(Inst, N);
540 }
541
542 void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
543 assert(N == 1 && "Invalid number of operands!");
544 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()]));
545 }
546
547 void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
548 assert(N == 1 && "Invalid number of operands!");
549 Inst.addOperand(MCOperand::CreateReg(FRegs[getReg()]));
550 }
551
552 void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
553 assert(N == 1 && "Invalid number of operands!");
554 Inst.addOperand(MCOperand::CreateReg(VRegs[getReg()]));
555 }
556
Hal Finkel27774d92014-03-13 07:58:58 +0000557 void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
558 assert(N == 1 && "Invalid number of operands!");
559 Inst.addOperand(MCOperand::CreateReg(VSRegs[getVSReg()]));
560 }
561
Hal Finkel19be5062014-03-29 05:29:01 +0000562 void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
563 assert(N == 1 && "Invalid number of operands!");
564 Inst.addOperand(MCOperand::CreateReg(VSFRegs[getVSReg()]));
565 }
566
Ulrich Weigand640192d2013-05-03 19:49:39 +0000567 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
568 assert(N == 1 && "Invalid number of operands!");
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000569 Inst.addOperand(MCOperand::CreateReg(CRBITRegs[getCRBit()]));
Ulrich Weigand640192d2013-05-03 19:49:39 +0000570 }
571
572 void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
573 assert(N == 1 && "Invalid number of operands!");
574 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCCReg()]));
575 }
576
577 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
578 assert(N == 1 && "Invalid number of operands!");
579 Inst.addOperand(MCOperand::CreateReg(CRRegs[getCRBitMask()]));
580 }
581
582 void addImmOperands(MCInst &Inst, unsigned N) const {
583 assert(N == 1 && "Invalid number of operands!");
584 if (Kind == Immediate)
585 Inst.addOperand(MCOperand::CreateImm(getImm()));
586 else
587 Inst.addOperand(MCOperand::CreateExpr(getExpr()));
588 }
589
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000590 void addS16ImmOperands(MCInst &Inst, unsigned N) const {
591 assert(N == 1 && "Invalid number of operands!");
592 switch (Kind) {
593 case Immediate:
594 Inst.addOperand(MCOperand::CreateImm(getImm()));
595 break;
596 case ContextImmediate:
597 Inst.addOperand(MCOperand::CreateImm(getImmS16Context()));
598 break;
599 default:
600 Inst.addOperand(MCOperand::CreateExpr(getExpr()));
601 break;
602 }
603 }
604
605 void addU16ImmOperands(MCInst &Inst, unsigned N) const {
606 assert(N == 1 && "Invalid number of operands!");
607 switch (Kind) {
608 case Immediate:
609 Inst.addOperand(MCOperand::CreateImm(getImm()));
610 break;
611 case ContextImmediate:
612 Inst.addOperand(MCOperand::CreateImm(getImmU16Context()));
613 break;
614 default:
615 Inst.addOperand(MCOperand::CreateExpr(getExpr()));
616 break;
617 }
618 }
619
Ulrich Weigandb6a30d12013-06-24 11:03:33 +0000620 void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
621 assert(N == 1 && "Invalid number of operands!");
622 if (Kind == Immediate)
623 Inst.addOperand(MCOperand::CreateImm(getImm() / 4));
624 else
625 Inst.addOperand(MCOperand::CreateExpr(getExpr()));
626 }
627
Ulrich Weigand5b427592013-07-05 12:22:36 +0000628 void addTLSRegOperands(MCInst &Inst, unsigned N) const {
629 assert(N == 1 && "Invalid number of operands!");
630 Inst.addOperand(MCOperand::CreateExpr(getTLSReg()));
631 }
632
Ulrich Weigand640192d2013-05-03 19:49:39 +0000633 StringRef getToken() const {
634 assert(Kind == Token && "Invalid access!");
635 return StringRef(Tok.Data, Tok.Length);
636 }
637
Craig Topper0d3fa922014-04-29 07:57:37 +0000638 void print(raw_ostream &OS) const override;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000639
David Blaikie960ea3f2014-06-08 16:18:35 +0000640 static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
641 bool IsPPC64) {
642 auto Op = make_unique<PPCOperand>(Token);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000643 Op->Tok.Data = Str.data();
644 Op->Tok.Length = Str.size();
645 Op->StartLoc = S;
646 Op->EndLoc = S;
647 Op->IsPPC64 = IsPPC64;
648 return Op;
649 }
650
David Blaikie960ea3f2014-06-08 16:18:35 +0000651 static std::unique_ptr<PPCOperand>
652 CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000653 // Allocate extra memory for the string and copy it.
David Blaikie960ea3f2014-06-08 16:18:35 +0000654 // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
655 // deleter which will destroy them by simply using "delete", not correctly
656 // calling operator delete on this extra memory after calling the dtor
657 // explicitly.
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000658 void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000659 std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
Benjamin Kramer769989c2014-08-15 11:05:45 +0000660 Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000661 Op->Tok.Length = Str.size();
Benjamin Kramer769989c2014-08-15 11:05:45 +0000662 std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
Benjamin Kramer72d45cc2013-08-03 22:43:29 +0000663 Op->StartLoc = S;
664 Op->EndLoc = S;
665 Op->IsPPC64 = IsPPC64;
666 return Op;
667 }
668
David Blaikie960ea3f2014-06-08 16:18:35 +0000669 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
670 bool IsPPC64) {
671 auto Op = make_unique<PPCOperand>(Immediate);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000672 Op->Imm.Val = Val;
673 Op->StartLoc = S;
674 Op->EndLoc = E;
675 Op->IsPPC64 = IsPPC64;
676 return Op;
677 }
678
David Blaikie960ea3f2014-06-08 16:18:35 +0000679 static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
680 SMLoc E, bool IsPPC64) {
681 auto Op = make_unique<PPCOperand>(Expression);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000682 Op->Expr.Val = Val;
Ulrich Weigandb86cb7d2013-07-04 14:24:00 +0000683 Op->Expr.CRVal = EvaluateCRExpr(Val);
Ulrich Weigand640192d2013-05-03 19:49:39 +0000684 Op->StartLoc = S;
685 Op->EndLoc = E;
686 Op->IsPPC64 = IsPPC64;
687 return Op;
688 }
Ulrich Weigand5b427592013-07-05 12:22:36 +0000689
David Blaikie960ea3f2014-06-08 16:18:35 +0000690 static std::unique_ptr<PPCOperand>
691 CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
692 auto Op = make_unique<PPCOperand>(TLSRegister);
Ulrich Weigand5b427592013-07-05 12:22:36 +0000693 Op->TLSReg.Sym = Sym;
694 Op->StartLoc = S;
695 Op->EndLoc = E;
696 Op->IsPPC64 = IsPPC64;
697 return Op;
698 }
699
David Blaikie960ea3f2014-06-08 16:18:35 +0000700 static std::unique_ptr<PPCOperand>
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000701 CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
702 auto Op = make_unique<PPCOperand>(ContextImmediate);
703 Op->Imm.Val = Val;
704 Op->StartLoc = S;
705 Op->EndLoc = E;
706 Op->IsPPC64 = IsPPC64;
707 return Op;
708 }
709
710 static std::unique_ptr<PPCOperand>
David Blaikie960ea3f2014-06-08 16:18:35 +0000711 CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
Ulrich Weigand5b427592013-07-05 12:22:36 +0000712 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
713 return CreateImm(CE->getValue(), S, E, IsPPC64);
714
715 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
716 if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS)
717 return CreateTLSReg(SRE, S, E, IsPPC64);
718
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000719 if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
720 int64_t Res;
721 if (TE->EvaluateAsConstant(Res))
722 return CreateContextImm(Res, S, E, IsPPC64);
723 }
724
Ulrich Weigand5b427592013-07-05 12:22:36 +0000725 return CreateExpr(Val, S, E, IsPPC64);
726 }
Ulrich Weigand640192d2013-05-03 19:49:39 +0000727};
728
729} // end anonymous namespace.
730
731void PPCOperand::print(raw_ostream &OS) const {
732 switch (Kind) {
733 case Token:
734 OS << "'" << getToken() << "'";
735 break;
736 case Immediate:
Joerg Sonnenbergerbfef1dd2014-08-10 12:41:50 +0000737 case ContextImmediate:
Ulrich Weigand640192d2013-05-03 19:49:39 +0000738 OS << getImm();
739 break;
740 case Expression:
741 getExpr()->print(OS);
742 break;
Ulrich Weigand5b427592013-07-05 12:22:36 +0000743 case TLSRegister:
744 getTLSReg()->print(OS);
745 break;
Ulrich Weigand640192d2013-05-03 19:49:39 +0000746 }
747}
748
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000749static void
750addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
751 if (Op.isImm()) {
752 Inst.addOperand(MCOperand::CreateImm(-Op.getImm()));
753 return;
754 }
755 const MCExpr *Expr = Op.getExpr();
756 if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
757 if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
758 Inst.addOperand(MCOperand::CreateExpr(UnExpr->getSubExpr()));
759 return;
760 }
761 } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
762 if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
763 const MCExpr *NE = MCBinaryExpr::CreateSub(BinExpr->getRHS(),
764 BinExpr->getLHS(), Ctx);
765 Inst.addOperand(MCOperand::CreateExpr(NE));
766 return;
767 }
768 }
769 Inst.addOperand(MCOperand::CreateExpr(MCUnaryExpr::CreateMinus(Expr, Ctx)));
770}
771
David Blaikie960ea3f2014-06-08 16:18:35 +0000772void PPCAsmParser::ProcessInstruction(MCInst &Inst,
773 const OperandVector &Operands) {
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000774 int Opcode = Inst.getOpcode();
775 switch (Opcode) {
Ulrich Weigand6ca71572013-06-24 18:08:03 +0000776 case PPC::LAx: {
777 MCInst TmpInst;
778 TmpInst.setOpcode(PPC::LA);
779 TmpInst.addOperand(Inst.getOperand(0));
780 TmpInst.addOperand(Inst.getOperand(2));
781 TmpInst.addOperand(Inst.getOperand(1));
782 Inst = TmpInst;
783 break;
784 }
Ulrich Weigand4069e242013-06-25 13:16:48 +0000785 case PPC::SUBI: {
786 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000787 TmpInst.setOpcode(PPC::ADDI);
788 TmpInst.addOperand(Inst.getOperand(0));
789 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000790 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000791 Inst = TmpInst;
792 break;
793 }
794 case PPC::SUBIS: {
795 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000796 TmpInst.setOpcode(PPC::ADDIS);
797 TmpInst.addOperand(Inst.getOperand(0));
798 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000799 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000800 Inst = TmpInst;
801 break;
802 }
803 case PPC::SUBIC: {
804 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000805 TmpInst.setOpcode(PPC::ADDIC);
806 TmpInst.addOperand(Inst.getOperand(0));
807 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000808 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000809 Inst = TmpInst;
810 break;
811 }
812 case PPC::SUBICo: {
813 MCInst TmpInst;
Ulrich Weigand4069e242013-06-25 13:16:48 +0000814 TmpInst.setOpcode(PPC::ADDICo);
815 TmpInst.addOperand(Inst.getOperand(0));
816 TmpInst.addOperand(Inst.getOperand(1));
Joerg Sonnenberger5aab5af2014-08-09 17:10:26 +0000817 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
Ulrich Weigand4069e242013-06-25 13:16:48 +0000818 Inst = TmpInst;
819 break;
820 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000821 case PPC::EXTLWI:
822 case PPC::EXTLWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +0000823 MCInst TmpInst;
824 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000825 int64_t B = Inst.getOperand(3).getImm();
826 TmpInst.setOpcode(Opcode == PPC::EXTLWI? PPC::RLWINM : PPC::RLWINMo);
827 TmpInst.addOperand(Inst.getOperand(0));
828 TmpInst.addOperand(Inst.getOperand(1));
829 TmpInst.addOperand(MCOperand::CreateImm(B));
830 TmpInst.addOperand(MCOperand::CreateImm(0));
831 TmpInst.addOperand(MCOperand::CreateImm(N - 1));
832 Inst = TmpInst;
833 break;
834 }
835 case PPC::EXTRWI:
836 case PPC::EXTRWIo: {
837 MCInst TmpInst;
838 int64_t N = Inst.getOperand(2).getImm();
839 int64_t B = Inst.getOperand(3).getImm();
840 TmpInst.setOpcode(Opcode == PPC::EXTRWI? PPC::RLWINM : PPC::RLWINMo);
841 TmpInst.addOperand(Inst.getOperand(0));
842 TmpInst.addOperand(Inst.getOperand(1));
843 TmpInst.addOperand(MCOperand::CreateImm(B + N));
844 TmpInst.addOperand(MCOperand::CreateImm(32 - N));
845 TmpInst.addOperand(MCOperand::CreateImm(31));
846 Inst = TmpInst;
847 break;
848 }
849 case PPC::INSLWI:
850 case PPC::INSLWIo: {
851 MCInst TmpInst;
852 int64_t N = Inst.getOperand(2).getImm();
853 int64_t B = Inst.getOperand(3).getImm();
854 TmpInst.setOpcode(Opcode == PPC::INSLWI? PPC::RLWIMI : PPC::RLWIMIo);
855 TmpInst.addOperand(Inst.getOperand(0));
856 TmpInst.addOperand(Inst.getOperand(0));
857 TmpInst.addOperand(Inst.getOperand(1));
858 TmpInst.addOperand(MCOperand::CreateImm(32 - B));
859 TmpInst.addOperand(MCOperand::CreateImm(B));
860 TmpInst.addOperand(MCOperand::CreateImm((B + N) - 1));
861 Inst = TmpInst;
862 break;
863 }
864 case PPC::INSRWI:
865 case PPC::INSRWIo: {
866 MCInst TmpInst;
867 int64_t N = Inst.getOperand(2).getImm();
868 int64_t B = Inst.getOperand(3).getImm();
869 TmpInst.setOpcode(Opcode == PPC::INSRWI? PPC::RLWIMI : PPC::RLWIMIo);
870 TmpInst.addOperand(Inst.getOperand(0));
871 TmpInst.addOperand(Inst.getOperand(0));
872 TmpInst.addOperand(Inst.getOperand(1));
873 TmpInst.addOperand(MCOperand::CreateImm(32 - (B + N)));
874 TmpInst.addOperand(MCOperand::CreateImm(B));
875 TmpInst.addOperand(MCOperand::CreateImm((B + N) - 1));
876 Inst = TmpInst;
877 break;
878 }
879 case PPC::ROTRWI:
880 case PPC::ROTRWIo: {
881 MCInst TmpInst;
882 int64_t N = Inst.getOperand(2).getImm();
883 TmpInst.setOpcode(Opcode == PPC::ROTRWI? PPC::RLWINM : PPC::RLWINMo);
884 TmpInst.addOperand(Inst.getOperand(0));
885 TmpInst.addOperand(Inst.getOperand(1));
886 TmpInst.addOperand(MCOperand::CreateImm(32 - N));
887 TmpInst.addOperand(MCOperand::CreateImm(0));
888 TmpInst.addOperand(MCOperand::CreateImm(31));
889 Inst = TmpInst;
890 break;
891 }
892 case PPC::SLWI:
893 case PPC::SLWIo: {
894 MCInst TmpInst;
895 int64_t N = Inst.getOperand(2).getImm();
896 TmpInst.setOpcode(Opcode == PPC::SLWI? PPC::RLWINM : PPC::RLWINMo);
Ulrich Weigandd8394902013-05-03 19:50:27 +0000897 TmpInst.addOperand(Inst.getOperand(0));
898 TmpInst.addOperand(Inst.getOperand(1));
899 TmpInst.addOperand(MCOperand::CreateImm(N));
900 TmpInst.addOperand(MCOperand::CreateImm(0));
901 TmpInst.addOperand(MCOperand::CreateImm(31 - N));
902 Inst = TmpInst;
903 break;
904 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000905 case PPC::SRWI:
906 case PPC::SRWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +0000907 MCInst TmpInst;
908 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000909 TmpInst.setOpcode(Opcode == PPC::SRWI? PPC::RLWINM : PPC::RLWINMo);
Ulrich Weigandd8394902013-05-03 19:50:27 +0000910 TmpInst.addOperand(Inst.getOperand(0));
911 TmpInst.addOperand(Inst.getOperand(1));
912 TmpInst.addOperand(MCOperand::CreateImm(32 - N));
913 TmpInst.addOperand(MCOperand::CreateImm(N));
914 TmpInst.addOperand(MCOperand::CreateImm(31));
915 Inst = TmpInst;
916 break;
917 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000918 case PPC::CLRRWI:
919 case PPC::CLRRWIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +0000920 MCInst TmpInst;
921 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +0000922 TmpInst.setOpcode(Opcode == PPC::CLRRWI? PPC::RLWINM : PPC::RLWINMo);
923 TmpInst.addOperand(Inst.getOperand(0));
924 TmpInst.addOperand(Inst.getOperand(1));
925 TmpInst.addOperand(MCOperand::CreateImm(0));
926 TmpInst.addOperand(MCOperand::CreateImm(0));
927 TmpInst.addOperand(MCOperand::CreateImm(31 - N));
928 Inst = TmpInst;
929 break;
930 }
931 case PPC::CLRLSLWI:
932 case PPC::CLRLSLWIo: {
933 MCInst TmpInst;
934 int64_t B = Inst.getOperand(2).getImm();
935 int64_t N = Inst.getOperand(3).getImm();
936 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI? PPC::RLWINM : PPC::RLWINMo);
937 TmpInst.addOperand(Inst.getOperand(0));
938 TmpInst.addOperand(Inst.getOperand(1));
939 TmpInst.addOperand(MCOperand::CreateImm(N));
940 TmpInst.addOperand(MCOperand::CreateImm(B - N));
941 TmpInst.addOperand(MCOperand::CreateImm(31 - N));
942 Inst = TmpInst;
943 break;
944 }
945 case PPC::EXTLDI:
946 case PPC::EXTLDIo: {
947 MCInst TmpInst;
948 int64_t N = Inst.getOperand(2).getImm();
949 int64_t B = Inst.getOperand(3).getImm();
950 TmpInst.setOpcode(Opcode == PPC::EXTLDI? PPC::RLDICR : PPC::RLDICRo);
951 TmpInst.addOperand(Inst.getOperand(0));
952 TmpInst.addOperand(Inst.getOperand(1));
953 TmpInst.addOperand(MCOperand::CreateImm(B));
954 TmpInst.addOperand(MCOperand::CreateImm(N - 1));
955 Inst = TmpInst;
956 break;
957 }
958 case PPC::EXTRDI:
959 case PPC::EXTRDIo: {
960 MCInst TmpInst;
961 int64_t N = Inst.getOperand(2).getImm();
962 int64_t B = Inst.getOperand(3).getImm();
963 TmpInst.setOpcode(Opcode == PPC::EXTRDI? PPC::RLDICL : PPC::RLDICLo);
964 TmpInst.addOperand(Inst.getOperand(0));
965 TmpInst.addOperand(Inst.getOperand(1));
966 TmpInst.addOperand(MCOperand::CreateImm(B + N));
967 TmpInst.addOperand(MCOperand::CreateImm(64 - N));
968 Inst = TmpInst;
969 break;
970 }
971 case PPC::INSRDI:
972 case PPC::INSRDIo: {
973 MCInst TmpInst;
974 int64_t N = Inst.getOperand(2).getImm();
975 int64_t B = Inst.getOperand(3).getImm();
976 TmpInst.setOpcode(Opcode == PPC::INSRDI? PPC::RLDIMI : PPC::RLDIMIo);
977 TmpInst.addOperand(Inst.getOperand(0));
978 TmpInst.addOperand(Inst.getOperand(0));
979 TmpInst.addOperand(Inst.getOperand(1));
980 TmpInst.addOperand(MCOperand::CreateImm(64 - (B + N)));
981 TmpInst.addOperand(MCOperand::CreateImm(B));
982 Inst = TmpInst;
983 break;
984 }
985 case PPC::ROTRDI:
986 case PPC::ROTRDIo: {
987 MCInst TmpInst;
988 int64_t N = Inst.getOperand(2).getImm();
989 TmpInst.setOpcode(Opcode == PPC::ROTRDI? PPC::RLDICL : PPC::RLDICLo);
990 TmpInst.addOperand(Inst.getOperand(0));
991 TmpInst.addOperand(Inst.getOperand(1));
992 TmpInst.addOperand(MCOperand::CreateImm(64 - N));
993 TmpInst.addOperand(MCOperand::CreateImm(0));
994 Inst = TmpInst;
995 break;
996 }
997 case PPC::SLDI:
998 case PPC::SLDIo: {
999 MCInst TmpInst;
1000 int64_t N = Inst.getOperand(2).getImm();
1001 TmpInst.setOpcode(Opcode == PPC::SLDI? PPC::RLDICR : PPC::RLDICRo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001002 TmpInst.addOperand(Inst.getOperand(0));
1003 TmpInst.addOperand(Inst.getOperand(1));
1004 TmpInst.addOperand(MCOperand::CreateImm(N));
1005 TmpInst.addOperand(MCOperand::CreateImm(63 - N));
1006 Inst = TmpInst;
1007 break;
1008 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001009 case PPC::SRDI:
1010 case PPC::SRDIo: {
Ulrich Weigandd8394902013-05-03 19:50:27 +00001011 MCInst TmpInst;
1012 int64_t N = Inst.getOperand(2).getImm();
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001013 TmpInst.setOpcode(Opcode == PPC::SRDI? PPC::RLDICL : PPC::RLDICLo);
Ulrich Weigandd8394902013-05-03 19:50:27 +00001014 TmpInst.addOperand(Inst.getOperand(0));
1015 TmpInst.addOperand(Inst.getOperand(1));
1016 TmpInst.addOperand(MCOperand::CreateImm(64 - N));
1017 TmpInst.addOperand(MCOperand::CreateImm(N));
1018 Inst = TmpInst;
1019 break;
1020 }
Ulrich Weigandad873cd2013-06-25 13:17:41 +00001021 case PPC::CLRRDI:
1022 case PPC::CLRRDIo: {
1023 MCInst TmpInst;
1024 int64_t N = Inst.getOperand(2).getImm();
1025 TmpInst.setOpcode(Opcode == PPC::CLRRDI? PPC::RLDICR : PPC::RLDICRo);
1026 TmpInst.addOperand(Inst.getOperand(0));
1027 TmpInst.addOperand(Inst.getOperand(1));
1028 TmpInst.addOperand(MCOperand::CreateImm(0));
1029 TmpInst.addOperand(MCOperand::CreateImm(63 - N));
1030 Inst = TmpInst;
1031 break;
1032 }
1033 case PPC::CLRLSLDI:
1034 case PPC::CLRLSLDIo: {
1035 MCInst TmpInst;
1036 int64_t B = Inst.getOperand(2).getImm();
1037 int64_t N = Inst.getOperand(3).getImm();
1038 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI? PPC::RLDIC : PPC::RLDICo);
1039 TmpInst.addOperand(Inst.getOperand(0));
1040 TmpInst.addOperand(Inst.getOperand(1));
1041 TmpInst.addOperand(MCOperand::CreateImm(N));
1042 TmpInst.addOperand(MCOperand::CreateImm(B - N));
1043 Inst = TmpInst;
1044 break;
1045 }
Ulrich Weigandd8394902013-05-03 19:50:27 +00001046 }
1047}
1048
David Blaikie960ea3f2014-06-08 16:18:35 +00001049bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1050 OperandVector &Operands,
Tim Northover26bb14e2014-08-18 11:49:42 +00001051 MCStreamer &Out, uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +00001052 bool MatchingInlineAsm) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001053 MCInst Inst;
1054
1055 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1056 default: break;
1057 case Match_Success:
Ulrich Weigandd8394902013-05-03 19:50:27 +00001058 // Post-process instructions (typically extended mnemonics)
1059 ProcessInstruction(Inst, Operands);
Ulrich Weigand640192d2013-05-03 19:49:39 +00001060 Inst.setLoc(IDLoc);
David Woodhousee6c13e42014-01-28 23:12:42 +00001061 Out.EmitInstruction(Inst, STI);
Ulrich Weigand640192d2013-05-03 19:49:39 +00001062 return false;
1063 case Match_MissingFeature:
1064 return Error(IDLoc, "instruction use requires an option to be enabled");
1065 case Match_MnemonicFail:
1066 return Error(IDLoc, "unrecognized instruction mnemonic");
1067 case Match_InvalidOperand: {
1068 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +00001069 if (ErrorInfo != ~0ULL) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001070 if (ErrorInfo >= Operands.size())
1071 return Error(IDLoc, "too few operands for instruction");
1072
David Blaikie960ea3f2014-06-08 16:18:35 +00001073 ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001074 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1075 }
1076
1077 return Error(ErrorLoc, "invalid operand for instruction");
1078 }
1079 }
1080
1081 llvm_unreachable("Implement any new match types added!");
1082}
1083
1084bool PPCAsmParser::
1085MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) {
1086 if (Tok.is(AsmToken::Identifier)) {
Ulrich Weigand509c2402013-05-06 11:16:57 +00001087 StringRef Name = Tok.getString();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001088
Ulrich Weigand509c2402013-05-06 11:16:57 +00001089 if (Name.equals_lower("lr")) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001090 RegNo = isPPC64()? PPC::LR8 : PPC::LR;
1091 IntVal = 8;
1092 return false;
Ulrich Weigand509c2402013-05-06 11:16:57 +00001093 } else if (Name.equals_lower("ctr")) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001094 RegNo = isPPC64()? PPC::CTR8 : PPC::CTR;
1095 IntVal = 9;
1096 return false;
Hal Finkel52727c62013-07-02 03:39:34 +00001097 } else if (Name.equals_lower("vrsave")) {
1098 RegNo = PPC::VRSAVE;
1099 IntVal = 256;
1100 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001101 } else if (Name.startswith_lower("r") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001102 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1103 RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal];
1104 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001105 } else if (Name.startswith_lower("f") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001106 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1107 RegNo = FRegs[IntVal];
1108 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001109 } else if (Name.startswith_lower("v") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001110 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1111 RegNo = VRegs[IntVal];
1112 return false;
Rui Ueyama29d29102013-10-31 19:59:55 +00001113 } else if (Name.startswith_lower("cr") &&
Ulrich Weigand640192d2013-05-03 19:49:39 +00001114 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1115 RegNo = CRRegs[IntVal];
1116 return false;
1117 }
1118 }
1119
1120 return true;
1121}
1122
1123bool PPCAsmParser::
1124ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001125 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001126 const AsmToken &Tok = Parser.getTok();
1127 StartLoc = Tok.getLoc();
1128 EndLoc = Tok.getEndLoc();
1129 RegNo = 0;
1130 int64_t IntVal;
1131
1132 if (!MatchRegisterName(Tok, RegNo, IntVal)) {
1133 Parser.Lex(); // Eat identifier token.
1134 return false;
1135 }
1136
1137 return Error(StartLoc, "invalid register name");
1138}
1139
NAKAMURA Takumi36c17ee2013-06-25 01:14:20 +00001140/// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
Ulrich Weigande67c5652013-06-21 14:42:49 +00001141/// the expression and check for VK_PPC_LO/HI/HA
Ulrich Weigand96e65782013-06-20 16:23:52 +00001142/// symbol variants. If all symbols with modifier use the same
1143/// variant, return the corresponding PPCMCExpr::VariantKind,
1144/// and a modified expression using the default symbol variant.
1145/// Otherwise, return NULL.
1146const MCExpr *PPCAsmParser::
1147ExtractModifierFromExpr(const MCExpr *E,
1148 PPCMCExpr::VariantKind &Variant) {
1149 MCContext &Context = getParser().getContext();
1150 Variant = PPCMCExpr::VK_PPC_None;
1151
1152 switch (E->getKind()) {
1153 case MCExpr::Target:
1154 case MCExpr::Constant:
Craig Topper062a2ba2014-04-25 05:30:21 +00001155 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001156
1157 case MCExpr::SymbolRef: {
1158 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1159
1160 switch (SRE->getKind()) {
Ulrich Weigandd51c09f2013-06-21 14:42:20 +00001161 case MCSymbolRefExpr::VK_PPC_LO:
1162 Variant = PPCMCExpr::VK_PPC_LO;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001163 break;
Ulrich Weigande67c5652013-06-21 14:42:49 +00001164 case MCSymbolRefExpr::VK_PPC_HI:
1165 Variant = PPCMCExpr::VK_PPC_HI;
1166 break;
Ulrich Weigandd51c09f2013-06-21 14:42:20 +00001167 case MCSymbolRefExpr::VK_PPC_HA:
1168 Variant = PPCMCExpr::VK_PPC_HA;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001169 break;
Ulrich Weigande9126f52013-06-21 14:43:42 +00001170 case MCSymbolRefExpr::VK_PPC_HIGHER:
1171 Variant = PPCMCExpr::VK_PPC_HIGHER;
1172 break;
1173 case MCSymbolRefExpr::VK_PPC_HIGHERA:
1174 Variant = PPCMCExpr::VK_PPC_HIGHERA;
1175 break;
1176 case MCSymbolRefExpr::VK_PPC_HIGHEST:
1177 Variant = PPCMCExpr::VK_PPC_HIGHEST;
1178 break;
1179 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1180 Variant = PPCMCExpr::VK_PPC_HIGHESTA;
1181 break;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001182 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001183 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001184 }
1185
1186 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Context);
1187 }
1188
1189 case MCExpr::Unary: {
1190 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1191 const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
1192 if (!Sub)
Craig Topper062a2ba2014-04-25 05:30:21 +00001193 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001194 return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
1195 }
1196
1197 case MCExpr::Binary: {
1198 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1199 PPCMCExpr::VariantKind LHSVariant, RHSVariant;
1200 const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
1201 const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
1202
1203 if (!LHS && !RHS)
Craig Topper062a2ba2014-04-25 05:30:21 +00001204 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001205
1206 if (!LHS) LHS = BE->getLHS();
1207 if (!RHS) RHS = BE->getRHS();
1208
1209 if (LHSVariant == PPCMCExpr::VK_PPC_None)
1210 Variant = RHSVariant;
1211 else if (RHSVariant == PPCMCExpr::VK_PPC_None)
1212 Variant = LHSVariant;
1213 else if (LHSVariant == RHSVariant)
1214 Variant = LHSVariant;
1215 else
Craig Topper062a2ba2014-04-25 05:30:21 +00001216 return nullptr;
Ulrich Weigand96e65782013-06-20 16:23:52 +00001217
1218 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
1219 }
1220 }
1221
1222 llvm_unreachable("Invalid expression kind!");
1223}
1224
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001225/// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
1226/// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
1227/// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
1228/// FIXME: This is a hack.
1229const MCExpr *PPCAsmParser::
1230FixupVariantKind(const MCExpr *E) {
1231 MCContext &Context = getParser().getContext();
1232
1233 switch (E->getKind()) {
1234 case MCExpr::Target:
1235 case MCExpr::Constant:
1236 return E;
1237
1238 case MCExpr::SymbolRef: {
1239 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1240 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1241
1242 switch (SRE->getKind()) {
1243 case MCSymbolRefExpr::VK_TLSGD:
1244 Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
1245 break;
1246 case MCSymbolRefExpr::VK_TLSLD:
1247 Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
1248 break;
1249 default:
1250 return E;
1251 }
1252 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, Context);
1253 }
1254
1255 case MCExpr::Unary: {
1256 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1257 const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
1258 if (Sub == UE->getSubExpr())
1259 return E;
1260 return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
1261 }
1262
1263 case MCExpr::Binary: {
1264 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1265 const MCExpr *LHS = FixupVariantKind(BE->getLHS());
1266 const MCExpr *RHS = FixupVariantKind(BE->getRHS());
1267 if (LHS == BE->getLHS() && RHS == BE->getRHS())
1268 return E;
1269 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
1270 }
1271 }
1272
1273 llvm_unreachable("Invalid expression kind!");
1274}
1275
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001276/// ParseExpression. This differs from the default "parseExpression" in that
1277/// it handles modifiers.
Ulrich Weigand96e65782013-06-20 16:23:52 +00001278bool PPCAsmParser::
1279ParseExpression(const MCExpr *&EVal) {
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001280
1281 if (isDarwin())
1282 return ParseDarwinExpression(EVal);
1283
1284 // (ELF Platforms)
1285 // Handle \code @l/@ha \endcode
Ulrich Weigand96e65782013-06-20 16:23:52 +00001286 if (getParser().parseExpression(EVal))
1287 return true;
1288
Ulrich Weigand52cf8e42013-07-09 16:41:09 +00001289 EVal = FixupVariantKind(EVal);
1290
Ulrich Weigand96e65782013-06-20 16:23:52 +00001291 PPCMCExpr::VariantKind Variant;
1292 const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
1293 if (E)
Ulrich Weigand266db7f2013-07-08 20:20:51 +00001294 EVal = PPCMCExpr::Create(Variant, E, false, getParser().getContext());
Ulrich Weigand96e65782013-06-20 16:23:52 +00001295
1296 return false;
1297}
1298
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001299/// ParseDarwinExpression. (MachO Platforms)
1300/// This differs from the default "parseExpression" in that it handles detection
1301/// of the \code hi16(), ha16() and lo16() \endcode modifiers. At present,
1302/// parseExpression() doesn't recognise the modifiers when in the Darwin/MachO
1303/// syntax form so it is done here. TODO: Determine if there is merit in arranging
1304/// for this to be done at a higher level.
1305bool PPCAsmParser::
1306ParseDarwinExpression(const MCExpr *&EVal) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001307 MCAsmParser &Parser = getParser();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001308 PPCMCExpr::VariantKind Variant = PPCMCExpr::VK_PPC_None;
1309 switch (getLexer().getKind()) {
1310 default:
1311 break;
1312 case AsmToken::Identifier:
1313 // Compiler-generated Darwin identifiers begin with L,l,_ or "; thus
1314 // something starting with any other char should be part of the
1315 // asm syntax. If handwritten asm includes an identifier like lo16,
1316 // then all bets are off - but no-one would do that, right?
1317 StringRef poss = Parser.getTok().getString();
1318 if (poss.equals_lower("lo16")) {
1319 Variant = PPCMCExpr::VK_PPC_LO;
1320 } else if (poss.equals_lower("hi16")) {
1321 Variant = PPCMCExpr::VK_PPC_HI;
1322 } else if (poss.equals_lower("ha16")) {
1323 Variant = PPCMCExpr::VK_PPC_HA;
1324 }
1325 if (Variant != PPCMCExpr::VK_PPC_None) {
1326 Parser.Lex(); // Eat the xx16
1327 if (getLexer().isNot(AsmToken::LParen))
1328 return Error(Parser.getTok().getLoc(), "expected '('");
1329 Parser.Lex(); // Eat the '('
1330 }
1331 break;
1332 }
1333
1334 if (getParser().parseExpression(EVal))
1335 return true;
1336
1337 if (Variant != PPCMCExpr::VK_PPC_None) {
1338 if (getLexer().isNot(AsmToken::RParen))
1339 return Error(Parser.getTok().getLoc(), "expected ')'");
1340 Parser.Lex(); // Eat the ')'
1341 EVal = PPCMCExpr::Create(Variant, EVal, false, getParser().getContext());
1342 }
1343 return false;
1344}
1345
1346/// ParseOperand
1347/// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1348/// rNN for MachO.
David Blaikie960ea3f2014-06-08 16:18:35 +00001349bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001350 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001351 SMLoc S = Parser.getTok().getLoc();
1352 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1353 const MCExpr *EVal;
Ulrich Weigand640192d2013-05-03 19:49:39 +00001354
1355 // Attempt to parse the next token as an immediate
1356 switch (getLexer().getKind()) {
1357 // Special handling for register names. These are interpreted
1358 // as immediates corresponding to the register number.
1359 case AsmToken::Percent:
1360 Parser.Lex(); // Eat the '%'.
1361 unsigned RegNo;
1362 int64_t IntVal;
1363 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1364 Parser.Lex(); // Eat the identifier token.
David Blaikie960ea3f2014-06-08 16:18:35 +00001365 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001366 return false;
1367 }
1368 return Error(S, "invalid register name");
1369
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001370 case AsmToken::Identifier:
1371 // Note that non-register-name identifiers from the compiler will begin
1372 // with '_', 'L'/'l' or '"'. Of course, handwritten asm could include
1373 // identifiers like r31foo - so we fall through in the event that parsing
1374 // a register name fails.
1375 if (isDarwin()) {
1376 unsigned RegNo;
1377 int64_t IntVal;
1378 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1379 Parser.Lex(); // Eat the identifier token.
David Blaikie960ea3f2014-06-08 16:18:35 +00001380 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001381 return false;
1382 }
1383 }
1384 // Fall-through to process non-register-name identifiers as expression.
Ulrich Weigand640192d2013-05-03 19:49:39 +00001385 // All other expressions
1386 case AsmToken::LParen:
1387 case AsmToken::Plus:
1388 case AsmToken::Minus:
1389 case AsmToken::Integer:
Ulrich Weigand640192d2013-05-03 19:49:39 +00001390 case AsmToken::Dot:
1391 case AsmToken::Dollar:
Roman Divackya26f9a62014-03-12 19:25:57 +00001392 case AsmToken::Exclaim:
1393 case AsmToken::Tilde:
Ulrich Weigand96e65782013-06-20 16:23:52 +00001394 if (!ParseExpression(EVal))
Ulrich Weigand640192d2013-05-03 19:49:39 +00001395 break;
1396 /* fall through */
1397 default:
1398 return Error(S, "unknown operand");
1399 }
1400
Ulrich Weigand640192d2013-05-03 19:49:39 +00001401 // Push the parsed operand into the list of operands
David Blaikie960ea3f2014-06-08 16:18:35 +00001402 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001403
Ulrich Weigand42a09dc2013-07-02 21:31:59 +00001404 // Check whether this is a TLS call expression
1405 bool TLSCall = false;
1406 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
1407 TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
1408
1409 if (TLSCall && getLexer().is(AsmToken::LParen)) {
1410 const MCExpr *TLSSym;
1411
1412 Parser.Lex(); // Eat the '('.
1413 S = Parser.getTok().getLoc();
1414 if (ParseExpression(TLSSym))
1415 return Error(S, "invalid TLS call expression");
1416 if (getLexer().isNot(AsmToken::RParen))
1417 return Error(Parser.getTok().getLoc(), "missing ')'");
1418 E = Parser.getTok().getLoc();
1419 Parser.Lex(); // Eat the ')'.
1420
David Blaikie960ea3f2014-06-08 16:18:35 +00001421 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
Ulrich Weigand42a09dc2013-07-02 21:31:59 +00001422 }
1423
1424 // Otherwise, check for D-form memory operands
1425 if (!TLSCall && getLexer().is(AsmToken::LParen)) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001426 Parser.Lex(); // Eat the '('.
1427 S = Parser.getTok().getLoc();
1428
1429 int64_t IntVal;
1430 switch (getLexer().getKind()) {
1431 case AsmToken::Percent:
1432 Parser.Lex(); // Eat the '%'.
1433 unsigned RegNo;
1434 if (MatchRegisterName(Parser.getTok(), RegNo, IntVal))
1435 return Error(S, "invalid register name");
1436 Parser.Lex(); // Eat the identifier token.
1437 break;
1438
1439 case AsmToken::Integer:
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001440 if (!isDarwin()) {
1441 if (getParser().parseAbsoluteExpression(IntVal) ||
Ulrich Weigand640192d2013-05-03 19:49:39 +00001442 IntVal < 0 || IntVal > 31)
1443 return Error(S, "invalid register number");
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001444 } else {
1445 return Error(S, "unexpected integer value");
1446 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001447 break;
1448
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001449 case AsmToken::Identifier:
1450 if (isDarwin()) {
1451 unsigned RegNo;
1452 if (!MatchRegisterName(Parser.getTok(), RegNo, IntVal)) {
1453 Parser.Lex(); // Eat the identifier token.
1454 break;
1455 }
1456 }
1457 // Fall-through..
1458
Ulrich Weigand640192d2013-05-03 19:49:39 +00001459 default:
1460 return Error(S, "invalid memory operand");
1461 }
1462
1463 if (getLexer().isNot(AsmToken::RParen))
1464 return Error(Parser.getTok().getLoc(), "missing ')'");
1465 E = Parser.getTok().getLoc();
1466 Parser.Lex(); // Eat the ')'.
1467
David Blaikie960ea3f2014-06-08 16:18:35 +00001468 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001469 }
1470
1471 return false;
1472}
1473
1474/// Parse an instruction mnemonic followed by its operands.
David Blaikie960ea3f2014-06-08 16:18:35 +00001475bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1476 SMLoc NameLoc, OperandVector &Operands) {
Ulrich Weigand640192d2013-05-03 19:49:39 +00001477 // The first operand is the token for the instruction name.
Ulrich Weigand86247b62013-06-24 16:52:04 +00001478 // If the next character is a '+' or '-', we need to add it to the
1479 // instruction name, to match what TableGen is doing.
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001480 std::string NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001481 if (getLexer().is(AsmToken::Plus)) {
1482 getLexer().Lex();
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001483 NewOpcode = Name;
1484 NewOpcode += '+';
1485 Name = NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001486 }
1487 if (getLexer().is(AsmToken::Minus)) {
1488 getLexer().Lex();
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001489 NewOpcode = Name;
1490 NewOpcode += '-';
1491 Name = NewOpcode;
Ulrich Weigand86247b62013-06-24 16:52:04 +00001492 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001493 // If the instruction ends in a '.', we need to create a separate
1494 // token for it, to match what TableGen is doing.
1495 size_t Dot = Name.find('.');
1496 StringRef Mnemonic = Name.slice(0, Dot);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001497 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1498 Operands.push_back(
1499 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1500 else
1501 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001502 if (Dot != StringRef::npos) {
1503 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1504 StringRef DotStr = Name.slice(Dot, StringRef::npos);
Benjamin Kramer72d45cc2013-08-03 22:43:29 +00001505 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1506 Operands.push_back(
1507 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1508 else
1509 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
Ulrich Weigand640192d2013-05-03 19:49:39 +00001510 }
1511
1512 // If there are no more operands then finish
1513 if (getLexer().is(AsmToken::EndOfStatement))
1514 return false;
1515
1516 // Parse the first operand
1517 if (ParseOperand(Operands))
1518 return true;
1519
1520 while (getLexer().isNot(AsmToken::EndOfStatement) &&
1521 getLexer().is(AsmToken::Comma)) {
1522 // Consume the comma token
1523 getLexer().Lex();
1524
1525 // Parse the next operand
1526 if (ParseOperand(Operands))
1527 return true;
1528 }
1529
1530 return false;
1531}
1532
1533/// ParseDirective parses the PPC specific directives
1534bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1535 StringRef IDVal = DirectiveID.getIdentifier();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001536 if (!isDarwin()) {
1537 if (IDVal == ".word")
1538 return ParseDirectiveWord(2, DirectiveID.getLoc());
1539 if (IDVal == ".llong")
1540 return ParseDirectiveWord(8, DirectiveID.getLoc());
1541 if (IDVal == ".tc")
1542 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc());
1543 if (IDVal == ".machine")
1544 return ParseDirectiveMachine(DirectiveID.getLoc());
Ulrich Weigand0daa5162014-07-20 22:56:57 +00001545 if (IDVal == ".abiversion")
1546 return ParseDirectiveAbiVersion(DirectiveID.getLoc());
Ulrich Weigandbb686102014-07-20 23:06:03 +00001547 if (IDVal == ".localentry")
1548 return ParseDirectiveLocalEntry(DirectiveID.getLoc());
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001549 } else {
1550 if (IDVal == ".machine")
1551 return ParseDarwinDirectiveMachine(DirectiveID.getLoc());
1552 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001553 return true;
1554}
1555
1556/// ParseDirectiveWord
1557/// ::= .word [ expression (, expression)* ]
1558bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001559 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001560 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1561 for (;;) {
1562 const MCExpr *Value;
1563 if (getParser().parseExpression(Value))
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001564 return false;
Ulrich Weigand640192d2013-05-03 19:49:39 +00001565
1566 getParser().getStreamer().EmitValue(Value, Size);
1567
1568 if (getLexer().is(AsmToken::EndOfStatement))
1569 break;
1570
1571 if (getLexer().isNot(AsmToken::Comma))
1572 return Error(L, "unexpected token in directive");
1573 Parser.Lex();
1574 }
1575 }
1576
1577 Parser.Lex();
1578 return false;
1579}
1580
1581/// ParseDirectiveTC
1582/// ::= .tc [ symbol (, expression)* ]
1583bool PPCAsmParser::ParseDirectiveTC(unsigned Size, SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001584 MCAsmParser &Parser = getParser();
Ulrich Weigand640192d2013-05-03 19:49:39 +00001585 // Skip TC symbol, which is only used with XCOFF.
1586 while (getLexer().isNot(AsmToken::EndOfStatement)
1587 && getLexer().isNot(AsmToken::Comma))
1588 Parser.Lex();
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001589 if (getLexer().isNot(AsmToken::Comma)) {
1590 Error(L, "unexpected token in directive");
1591 return false;
1592 }
Ulrich Weigand640192d2013-05-03 19:49:39 +00001593 Parser.Lex();
1594
1595 // Align to word size.
1596 getParser().getStreamer().EmitValueToAlignment(Size);
1597
1598 // Emit expressions.
1599 return ParseDirectiveWord(Size, L);
1600}
1601
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001602/// ParseDirectiveMachine (ELF platforms)
Ulrich Weigand55daa772013-07-09 10:00:34 +00001603/// ::= .machine [ cpu | "push" | "pop" ]
1604bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001605 MCAsmParser &Parser = getParser();
Ulrich Weigand55daa772013-07-09 10:00:34 +00001606 if (getLexer().isNot(AsmToken::Identifier) &&
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001607 getLexer().isNot(AsmToken::String)) {
1608 Error(L, "unexpected token in directive");
1609 return false;
1610 }
Ulrich Weigand55daa772013-07-09 10:00:34 +00001611
1612 StringRef CPU = Parser.getTok().getIdentifier();
1613 Parser.Lex();
1614
1615 // FIXME: Right now, the parser always allows any available
1616 // instruction, so the .machine directive is not useful.
1617 // Implement ".machine any" (by doing nothing) for the benefit
1618 // of existing assembler code. Likewise, we can then implement
1619 // ".machine push" and ".machine pop" as no-op.
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001620 if (CPU != "any" && CPU != "push" && CPU != "pop") {
1621 Error(L, "unrecognized machine type");
1622 return false;
1623 }
Ulrich Weigand55daa772013-07-09 10:00:34 +00001624
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001625 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1626 Error(L, "unexpected token in directive");
1627 return false;
1628 }
Rafael Espindola6b9ee9b2014-01-25 02:35:56 +00001629 PPCTargetStreamer &TStreamer =
1630 *static_cast<PPCTargetStreamer *>(
1631 getParser().getStreamer().getTargetStreamer());
1632 TStreamer.emitMachine(CPU);
Ulrich Weigand55daa772013-07-09 10:00:34 +00001633
1634 return false;
1635}
1636
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001637/// ParseDarwinDirectiveMachine (Mach-o platforms)
1638/// ::= .machine cpu-identifier
1639bool PPCAsmParser::ParseDarwinDirectiveMachine(SMLoc L) {
Rafael Espindola961d4692014-11-11 05:18:41 +00001640 MCAsmParser &Parser = getParser();
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001641 if (getLexer().isNot(AsmToken::Identifier) &&
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001642 getLexer().isNot(AsmToken::String)) {
1643 Error(L, "unexpected token in directive");
1644 return false;
1645 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001646
1647 StringRef CPU = Parser.getTok().getIdentifier();
1648 Parser.Lex();
1649
1650 // FIXME: this is only the 'default' set of cpu variants.
1651 // However we don't act on this information at present, this is simply
1652 // allowing parsing to proceed with minimal sanity checking.
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001653 if (CPU != "ppc7400" && CPU != "ppc" && CPU != "ppc64") {
1654 Error(L, "unrecognized cpu type");
1655 return false;
1656 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001657
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001658 if (isPPC64() && (CPU == "ppc7400" || CPU == "ppc")) {
1659 Error(L, "wrong cpu type specified for 64bit");
1660 return false;
1661 }
1662 if (!isPPC64() && CPU == "ppc64") {
1663 Error(L, "wrong cpu type specified for 32bit");
1664 return false;
1665 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001666
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00001667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1668 Error(L, "unexpected token in directive");
1669 return false;
1670 }
Iain Sandoee0b4cb62013-12-14 13:34:02 +00001671
1672 return false;
1673}
1674
Ulrich Weigand0daa5162014-07-20 22:56:57 +00001675/// ParseDirectiveAbiVersion
1676/// ::= .abiversion constant-expression
1677bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
1678 int64_t AbiVersion;
1679 if (getParser().parseAbsoluteExpression(AbiVersion)){
1680 Error(L, "expected constant expression");
1681 return false;
1682 }
1683 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1684 Error(L, "unexpected token in directive");
1685 return false;
1686 }
1687
1688 PPCTargetStreamer &TStreamer =
1689 *static_cast<PPCTargetStreamer *>(
1690 getParser().getStreamer().getTargetStreamer());
1691 TStreamer.emitAbiVersion(AbiVersion);
1692
1693 return false;
1694}
1695
Ulrich Weigandbb686102014-07-20 23:06:03 +00001696/// ParseDirectiveLocalEntry
1697/// ::= .localentry symbol, expression
1698bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
1699 StringRef Name;
1700 if (getParser().parseIdentifier(Name)) {
1701 Error(L, "expected identifier in directive");
1702 return false;
1703 }
1704 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1705
1706 if (getLexer().isNot(AsmToken::Comma)) {
1707 Error(L, "unexpected token in directive");
1708 return false;
1709 }
1710 Lex();
1711
1712 const MCExpr *Expr;
1713 if (getParser().parseExpression(Expr)) {
1714 Error(L, "expected expression");
1715 return false;
1716 }
1717
1718 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1719 Error(L, "unexpected token in directive");
1720 return false;
1721 }
1722
1723 PPCTargetStreamer &TStreamer =
1724 *static_cast<PPCTargetStreamer *>(
1725 getParser().getStreamer().getTargetStreamer());
1726 TStreamer.emitLocalEntry(Sym, Expr);
1727
1728 return false;
1729}
1730
1731
1732
Ulrich Weigand640192d2013-05-03 19:49:39 +00001733/// Force static initialization.
1734extern "C" void LLVMInitializePowerPCAsmParser() {
1735 RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target);
1736 RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target);
Bill Schmidt0a9170d2013-07-26 01:35:43 +00001737 RegisterMCAsmParser<PPCAsmParser> C(ThePPC64LETarget);
Ulrich Weigand640192d2013-05-03 19:49:39 +00001738}
1739
1740#define GET_REGISTER_MATCHER
1741#define GET_MATCHER_IMPLEMENTATION
1742#include "PPCGenAsmMatcher.inc"
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001743
1744// Define this matcher function after the auto-generated include so we
1745// have the match class enum definitions.
David Blaikie960ea3f2014-06-08 16:18:35 +00001746unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001747 unsigned Kind) {
1748 // If the kind is a token for a literal immediate, check if our asm
1749 // operand matches. This is for InstAliases which have a fixed-value
1750 // immediate in the syntax.
1751 int64_t ImmVal;
1752 switch (Kind) {
1753 case MCK_0: ImmVal = 0; break;
1754 case MCK_1: ImmVal = 1; break;
Roman Divacky62cb6352013-09-12 17:50:54 +00001755 case MCK_2: ImmVal = 2; break;
1756 case MCK_3: ImmVal = 3; break;
Joerg Sonnenbergerdda8e782014-07-30 09:24:37 +00001757 case MCK_4: ImmVal = 4; break;
1758 case MCK_5: ImmVal = 5; break;
1759 case MCK_6: ImmVal = 6; break;
1760 case MCK_7: ImmVal = 7; break;
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001761 default: return Match_InvalidOperand;
1762 }
1763
David Blaikie960ea3f2014-06-08 16:18:35 +00001764 PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1765 if (Op.isImm() && Op.getImm() == ImmVal)
Ulrich Weigandc0944b52013-07-08 14:49:37 +00001766 return Match_Success;
1767
1768 return Match_InvalidOperand;
1769}
1770
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00001771const MCExpr *
1772PPCAsmParser::applyModifierToExpr(const MCExpr *E,
1773 MCSymbolRefExpr::VariantKind Variant,
1774 MCContext &Ctx) {
1775 switch (Variant) {
1776 case MCSymbolRefExpr::VK_PPC_LO:
1777 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_LO, E, false, Ctx);
1778 case MCSymbolRefExpr::VK_PPC_HI:
1779 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HI, E, false, Ctx);
1780 case MCSymbolRefExpr::VK_PPC_HA:
1781 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HA, E, false, Ctx);
1782 case MCSymbolRefExpr::VK_PPC_HIGHER:
1783 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HIGHER, E, false, Ctx);
1784 case MCSymbolRefExpr::VK_PPC_HIGHERA:
1785 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HIGHERA, E, false, Ctx);
1786 case MCSymbolRefExpr::VK_PPC_HIGHEST:
1787 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HIGHEST, E, false, Ctx);
1788 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1789 return PPCMCExpr::Create(PPCMCExpr::VK_PPC_HIGHESTA, E, false, Ctx);
1790 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001791 return nullptr;
Joerg Sonnenbergerb822af42013-08-27 20:23:19 +00001792 }
1793}