blob: 9e23d2498bf7ccc45374b297b87bc9da37b68a81 [file] [log] [blame]
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001//===-- SparcAsmParser.cpp - Parse Sparc assembly 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
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000010#include "MCTargetDesc/SparcMCExpr.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000011#include "MCTargetDesc/SparcMCTargetDesc.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000012#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000013#include "llvm/ADT/SmallVector.h"
Eugene Zelenko3f37f072017-02-04 00:36:49 +000014#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/Triple.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000016#include "llvm/MC/MCContext.h"
Eugene Zelenko3f37f072017-02-04 00:36:49 +000017#include "llvm/MC/MCExpr.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000018#include "llvm/MC/MCInst.h"
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +000019#include "llvm/MC/MCObjectFileInfo.h"
Eugene Zelenko3f37f072017-02-04 00:36:49 +000020#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCAsmParser.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000022#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000023#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Craig Topper92cfdd72015-10-18 05:29:05 +000024#include "llvm/MC/MCRegisterInfo.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000025#include "llvm/MC/MCStreamer.h"
26#include "llvm/MC/MCSubtargetInfo.h"
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +000027#include "llvm/MC/MCSymbol.h"
Eugene Zelenko3f37f072017-02-04 00:36:49 +000028#include "llvm/Support/Casting.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/SMLoc.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000031#include "llvm/Support/TargetRegistry.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000032#include "llvm/Support/raw_ostream.h"
Eugene Zelenko3f37f072017-02-04 00:36:49 +000033#include <algorithm>
34#include <cassert>
35#include <cstdint>
36#include <memory>
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000037
38using namespace llvm;
39
40// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
41// namespace. But SPARC backend uses "SP" as its namespace.
42namespace llvm {
Eugene Zelenko3f37f072017-02-04 00:36:49 +000043namespace Sparc {
44
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000045 using namespace SP;
Eugene Zelenko3f37f072017-02-04 00:36:49 +000046
47} // end namespace Sparc
48} // end namespace llvm
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000049
50namespace {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000051
Eugene Zelenko3f37f072017-02-04 00:36:49 +000052class SparcOperand;
53
54class SparcAsmParser : public MCTargetAsmParser {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000055 MCAsmParser &Parser;
56
57 /// @name Auto-generated Match Functions
58 /// {
59
60#define GET_ASSEMBLER_HEADER
61#include "SparcGenAsmMatcher.inc"
62
63 /// }
64
65 // public interface of the MCTargetAsmParser.
66 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +000067 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +000068 uint64_t &ErrorInfo,
Craig Topperb0c941b2014-04-29 07:57:13 +000069 bool MatchingInlineAsm) override;
70 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000071 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
David Blaikie960ea3f2014-06-08 16:18:35 +000072 SMLoc NameLoc, OperandVector &Operands) override;
Craig Topperb0c941b2014-04-29 07:57:13 +000073 bool ParseDirective(AsmToken DirectiveID) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000074
David Blaikie960ea3f2014-06-08 16:18:35 +000075 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
Craig Topperb0c941b2014-04-29 07:57:13 +000076 unsigned Kind) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000077
78 // Custom parse functions for Sparc specific operands.
David Blaikie960ea3f2014-06-08 16:18:35 +000079 OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
80
81 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000082
83 OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +000084 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
85 bool isCall = false);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000086
David Blaikie960ea3f2014-06-08 16:18:35 +000087 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
Venkatraman Govindaraju22868742014-03-01 20:08:48 +000088
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +000089 // Helper function for dealing with %lo / %hi in PIC mode.
90 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
91 const MCExpr *subExpr);
92
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000093 // returns true if Tok is matched to a register and returns register in RegNo.
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +000094 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
95 unsigned &RegKind);
96
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000097 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000098
Daniel Sandersa73f1fd2015-06-10 12:11:26 +000099 bool is64Bit() const {
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000100 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
Daniel Sandersa73f1fd2015-06-10 12:11:26 +0000101 }
James Y Knightc49e7882015-05-18 16:43:33 +0000102
Nirav Dave2364748a2016-09-16 18:30:20 +0000103 bool expandSET(MCInst &Inst, SMLoc IDLoc,
James Y Knightc49e7882015-05-18 16:43:33 +0000104 SmallVectorImpl<MCInst> &Instructions);
105
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000106public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000107 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000108 const MCInstrInfo &MII,
109 const MCTargetOptions &Options)
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000110 : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
Alex Bradbury3fa69dd2018-05-23 11:20:28 +0000111 Parser.addAliasForDirective(".half", ".2byte");
112 Parser.addAliasForDirective(".word", ".4byte");
113 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
114 if (is64Bit())
115 Parser.addAliasForDirective(".xword", ".8byte");
116
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000117 // Initialize the set of available features.
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000118 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000119 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000120};
121
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000122} // end anonymous namespace
123
Craig Topper92cfdd72015-10-18 05:29:05 +0000124 static const MCPhysReg IntRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000125 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
126 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
127 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
128 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
129 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
130 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
131 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
132 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
133
Craig Topper92cfdd72015-10-18 05:29:05 +0000134 static const MCPhysReg FloatRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000135 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
136 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
137 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
138 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
139 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
140 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
141 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
142 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
143
Craig Topper92cfdd72015-10-18 05:29:05 +0000144 static const MCPhysReg DoubleRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000145 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
146 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
Daniel Cedermanef62c592016-12-02 15:05:26 +0000147 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000148 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
149 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
150 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
151 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
152 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
153
Craig Topper92cfdd72015-10-18 05:29:05 +0000154 static const MCPhysReg QuadFPRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000155 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
156 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
Venkatraman Govindaraju98aa7fa2014-01-24 05:24:01 +0000157 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000158 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
159
Craig Topper92cfdd72015-10-18 05:29:05 +0000160 static const MCPhysReg ASRRegs[32] = {
James Y Knight807563d2015-05-18 16:29:48 +0000161 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
162 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
163 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
164 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
165 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
166 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
167 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
168 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000169
Craig Topper92cfdd72015-10-18 05:29:05 +0000170 static const MCPhysReg IntPairRegs[] = {
James Y Knight3994be82015-08-10 19:11:39 +0000171 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
172 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
173 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
174 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
175
Chris Dewhurst053826a2016-02-27 12:49:59 +0000176 static const MCPhysReg CoprocRegs[32] = {
177 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
178 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
179 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
180 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
181 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
182 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
183 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
184 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
185
186 static const MCPhysReg CoprocPairRegs[] = {
187 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
188 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
189 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
190 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
191
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000192namespace {
193
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000194/// SparcOperand - Instances of this class represent a parsed Sparc machine
195/// instruction.
196class SparcOperand : public MCParsedAsmOperand {
197public:
198 enum RegisterKind {
199 rk_None,
200 rk_IntReg,
James Y Knight3994be82015-08-10 19:11:39 +0000201 rk_IntPairReg,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000202 rk_FloatReg,
203 rk_DoubleReg,
204 rk_QuadReg,
Chris Dewhurst053826a2016-02-27 12:49:59 +0000205 rk_CoprocReg,
206 rk_CoprocPairReg,
James Y Knightf7e70172015-05-18 16:38:47 +0000207 rk_Special,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000208 };
James Y Knightf7e70172015-05-18 16:38:47 +0000209
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000210private:
211 enum KindTy {
212 k_Token,
213 k_Register,
214 k_Immediate,
215 k_MemoryReg,
216 k_MemoryImm
217 } Kind;
218
219 SMLoc StartLoc, EndLoc;
220
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000221 struct Token {
222 const char *Data;
223 unsigned Length;
224 };
225
226 struct RegOp {
227 unsigned RegNum;
228 RegisterKind Kind;
229 };
230
231 struct ImmOp {
232 const MCExpr *Val;
233 };
234
235 struct MemOp {
236 unsigned Base;
237 unsigned OffsetReg;
238 const MCExpr *Off;
239 };
240
241 union {
242 struct Token Tok;
243 struct RegOp Reg;
244 struct ImmOp Imm;
245 struct MemOp Mem;
246 };
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000247
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000248public:
David Blaikie960ea3f2014-06-08 16:18:35 +0000249 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
250
Craig Topperb0c941b2014-04-29 07:57:13 +0000251 bool isToken() const override { return Kind == k_Token; }
252 bool isReg() const override { return Kind == k_Register; }
253 bool isImm() const override { return Kind == k_Immediate; }
254 bool isMem() const override { return isMEMrr() || isMEMri(); }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000255 bool isMEMrr() const { return Kind == k_MemoryReg; }
256 bool isMEMri() const { return Kind == k_MemoryImm; }
257
James Y Knight3994be82015-08-10 19:11:39 +0000258 bool isIntReg() const {
259 return (Kind == k_Register && Reg.Kind == rk_IntReg);
260 }
261
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000262 bool isFloatReg() const {
263 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
264 }
265
266 bool isFloatOrDoubleReg() const {
267 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
268 || Reg.Kind == rk_DoubleReg));
269 }
270
Chris Dewhurst053826a2016-02-27 12:49:59 +0000271 bool isCoprocReg() const {
272 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
273 }
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000274
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000275 StringRef getToken() const {
276 assert(Kind == k_Token && "Invalid access!");
277 return StringRef(Tok.Data, Tok.Length);
278 }
279
Craig Topperb0c941b2014-04-29 07:57:13 +0000280 unsigned getReg() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000281 assert((Kind == k_Register) && "Invalid access!");
282 return Reg.RegNum;
283 }
284
285 const MCExpr *getImm() const {
286 assert((Kind == k_Immediate) && "Invalid access!");
287 return Imm.Val;
288 }
289
290 unsigned getMemBase() const {
291 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
292 return Mem.Base;
293 }
294
295 unsigned getMemOffsetReg() const {
296 assert((Kind == k_MemoryReg) && "Invalid access!");
297 return Mem.OffsetReg;
298 }
299
300 const MCExpr *getMemOff() const {
301 assert((Kind == k_MemoryImm) && "Invalid access!");
302 return Mem.Off;
303 }
304
305 /// getStartLoc - Get the location of the first token of this operand.
Craig Topperb0c941b2014-04-29 07:57:13 +0000306 SMLoc getStartLoc() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000307 return StartLoc;
308 }
309 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +0000310 SMLoc getEndLoc() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000311 return EndLoc;
312 }
313
Craig Topperb0c941b2014-04-29 07:57:13 +0000314 void print(raw_ostream &OS) const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000315 switch (Kind) {
316 case k_Token: OS << "Token: " << getToken() << "\n"; break;
317 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
318 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
319 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
320 << getMemOffsetReg() << "\n"; break;
Craig Toppere73658d2014-04-28 04:05:08 +0000321 case k_MemoryImm: assert(getMemOff() != nullptr);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000322 OS << "Mem: " << getMemBase()
323 << "+" << *getMemOff()
324 << "\n"; break;
325 }
326 }
327
328 void addRegOperands(MCInst &Inst, unsigned N) const {
329 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000330 Inst.addOperand(MCOperand::createReg(getReg()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000331 }
332
333 void addImmOperands(MCInst &Inst, unsigned N) const {
334 assert(N == 1 && "Invalid number of operands!");
335 const MCExpr *Expr = getImm();
336 addExpr(Inst, Expr);
337 }
338
339 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
340 // Add as immediate when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000341 if (!Expr)
Jim Grosbache9119e42015-05-13 18:37:00 +0000342 Inst.addOperand(MCOperand::createImm(0));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000343 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000344 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000345 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000346 Inst.addOperand(MCOperand::createExpr(Expr));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000347 }
348
349 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
350 assert(N == 2 && "Invalid number of operands!");
351
Jim Grosbache9119e42015-05-13 18:37:00 +0000352 Inst.addOperand(MCOperand::createReg(getMemBase()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000353
354 assert(getMemOffsetReg() != 0 && "Invalid offset");
Jim Grosbache9119e42015-05-13 18:37:00 +0000355 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000356 }
357
358 void addMEMriOperands(MCInst &Inst, unsigned N) const {
359 assert(N == 2 && "Invalid number of operands!");
360
Jim Grosbache9119e42015-05-13 18:37:00 +0000361 Inst.addOperand(MCOperand::createReg(getMemBase()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000362
363 const MCExpr *Expr = getMemOff();
364 addExpr(Inst, Expr);
365 }
366
David Blaikie960ea3f2014-06-08 16:18:35 +0000367 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
368 auto Op = make_unique<SparcOperand>(k_Token);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000369 Op->Tok.Data = Str.data();
370 Op->Tok.Length = Str.size();
371 Op->StartLoc = S;
372 Op->EndLoc = S;
373 return Op;
374 }
375
David Blaikie960ea3f2014-06-08 16:18:35 +0000376 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
377 SMLoc S, SMLoc E) {
378 auto Op = make_unique<SparcOperand>(k_Register);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000379 Op->Reg.RegNum = RegNum;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000380 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000381 Op->StartLoc = S;
382 Op->EndLoc = E;
383 return Op;
384 }
385
David Blaikie960ea3f2014-06-08 16:18:35 +0000386 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
387 SMLoc E) {
388 auto Op = make_unique<SparcOperand>(k_Immediate);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000389 Op->Imm.Val = Val;
390 Op->StartLoc = S;
391 Op->EndLoc = E;
392 return Op;
393 }
394
James Y Knight3994be82015-08-10 19:11:39 +0000395 static bool MorphToIntPairReg(SparcOperand &Op) {
396 unsigned Reg = Op.getReg();
397 assert(Op.Reg.Kind == rk_IntReg);
398 unsigned regIdx = 32;
399 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
400 regIdx = Reg - Sparc::G0;
401 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
402 regIdx = Reg - Sparc::O0 + 8;
403 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
404 regIdx = Reg - Sparc::L0 + 16;
405 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
406 regIdx = Reg - Sparc::I0 + 24;
407 if (regIdx % 2 || regIdx > 31)
408 return false;
409 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
410 Op.Reg.Kind = rk_IntPairReg;
411 return true;
412 }
413
David Blaikie960ea3f2014-06-08 16:18:35 +0000414 static bool MorphToDoubleReg(SparcOperand &Op) {
415 unsigned Reg = Op.getReg();
416 assert(Op.Reg.Kind == rk_FloatReg);
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000417 unsigned regIdx = Reg - Sparc::F0;
418 if (regIdx % 2 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000419 return false;
420 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
421 Op.Reg.Kind = rk_DoubleReg;
422 return true;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000423 }
424
David Blaikie960ea3f2014-06-08 16:18:35 +0000425 static bool MorphToQuadReg(SparcOperand &Op) {
426 unsigned Reg = Op.getReg();
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000427 unsigned regIdx = 0;
David Blaikie960ea3f2014-06-08 16:18:35 +0000428 switch (Op.Reg.Kind) {
Craig Topper2a30d782014-06-18 05:05:13 +0000429 default: llvm_unreachable("Unexpected register kind!");
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000430 case rk_FloatReg:
431 regIdx = Reg - Sparc::F0;
432 if (regIdx % 4 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000433 return false;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000434 Reg = QuadFPRegs[regIdx / 4];
435 break;
436 case rk_DoubleReg:
437 regIdx = Reg - Sparc::D0;
438 if (regIdx % 2 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000439 return false;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000440 Reg = QuadFPRegs[regIdx / 2];
441 break;
442 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000443 Op.Reg.RegNum = Reg;
444 Op.Reg.Kind = rk_QuadReg;
445 return true;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000446 }
447
Chris Dewhurst053826a2016-02-27 12:49:59 +0000448 static bool MorphToCoprocPairReg(SparcOperand &Op) {
449 unsigned Reg = Op.getReg();
450 assert(Op.Reg.Kind == rk_CoprocReg);
451 unsigned regIdx = 32;
452 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
453 regIdx = Reg - Sparc::C0;
454 if (regIdx % 2 || regIdx > 31)
455 return false;
456 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
457 Op.Reg.Kind = rk_CoprocPairReg;
458 return true;
459 }
460
David Blaikie960ea3f2014-06-08 16:18:35 +0000461 static std::unique_ptr<SparcOperand>
462 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000463 unsigned offsetReg = Op->getReg();
464 Op->Kind = k_MemoryReg;
465 Op->Mem.Base = Base;
466 Op->Mem.OffsetReg = offsetReg;
Craig Topper062a2ba2014-04-25 05:30:21 +0000467 Op->Mem.Off = nullptr;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000468 return Op;
469 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000470
David Blaikie960ea3f2014-06-08 16:18:35 +0000471 static std::unique_ptr<SparcOperand>
James Y Knightc09bdfa2015-04-29 14:54:44 +0000472 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
473 auto Op = make_unique<SparcOperand>(k_MemoryReg);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000474 Op->Mem.Base = Base;
James Y Knightc09bdfa2015-04-29 14:54:44 +0000475 Op->Mem.OffsetReg = Sparc::G0; // always 0
476 Op->Mem.Off = nullptr;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000477 Op->StartLoc = S;
478 Op->EndLoc = E;
479 return Op;
480 }
481
David Blaikie960ea3f2014-06-08 16:18:35 +0000482 static std::unique_ptr<SparcOperand>
483 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000484 const MCExpr *Imm = Op->getImm();
485 Op->Kind = k_MemoryImm;
486 Op->Mem.Base = Base;
487 Op->Mem.OffsetReg = 0;
488 Op->Mem.Off = Imm;
489 return Op;
490 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000491};
492
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000493} // end anonymous namespace
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000494
Nirav Dave2364748a2016-09-16 18:30:20 +0000495bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
James Y Knightc49e7882015-05-18 16:43:33 +0000496 SmallVectorImpl<MCInst> &Instructions) {
497 MCOperand MCRegOp = Inst.getOperand(0);
498 MCOperand MCValOp = Inst.getOperand(1);
499 assert(MCRegOp.isReg());
500 assert(MCValOp.isImm() || MCValOp.isExpr());
501
502 // the imm operand can be either an expression or an immediate.
503 bool IsImm = Inst.getOperand(1).isImm();
Douglas Katzman58195a22015-08-20 16:16:16 +0000504 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
505
506 // Allow either a signed or unsigned 32-bit immediate.
NAKAMURA Takumicf61aae2015-08-21 01:12:19 +0000507 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
Nirav Dave2364748a2016-09-16 18:30:20 +0000508 return Error(IDLoc,
509 "set: argument must be between -2147483648 and 4294967295");
Douglas Katzman58195a22015-08-20 16:16:16 +0000510 }
511
512 // If the value was expressed as a large unsigned number, that's ok.
513 // We want to see if it "looks like" a small signed number.
514 int32_t ImmValue = RawImmValue;
515 // For 'set' you can't use 'or' with a negative operand on V9 because
516 // that would splat the sign bit across the upper half of the destination
517 // register, whereas 'set' is defined to zero the high 32 bits.
518 bool IsEffectivelyImm13 =
519 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
James Y Knightc49e7882015-05-18 16:43:33 +0000520 const MCExpr *ValExpr;
521 if (IsImm)
Jim Grosbach13760bd2015-05-30 01:25:56 +0000522 ValExpr = MCConstantExpr::create(ImmValue, getContext());
James Y Knightc49e7882015-05-18 16:43:33 +0000523 else
524 ValExpr = MCValOp.getExpr();
525
526 MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
527
Douglas Katzman58195a22015-08-20 16:16:16 +0000528 // If not just a signed imm13 value, then either we use a 'sethi' with a
529 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
530 // In either case, start with the 'sethi'.
531 if (!IsEffectivelyImm13) {
James Y Knightc49e7882015-05-18 16:43:33 +0000532 MCInst TmpInst;
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +0000533 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
James Y Knightc49e7882015-05-18 16:43:33 +0000534 TmpInst.setLoc(IDLoc);
535 TmpInst.setOpcode(SP::SETHIi);
536 TmpInst.addOperand(MCRegOp);
537 TmpInst.addOperand(MCOperand::createExpr(Expr));
538 Instructions.push_back(TmpInst);
539 PrevReg = MCRegOp;
540 }
541
Douglas Katzman58195a22015-08-20 16:16:16 +0000542 // The low bits require touching in 3 cases:
543 // * A non-immediate value will always require both instructions.
544 // * An effectively imm13 value needs only an 'or' instruction.
545 // * Otherwise, an immediate that is not effectively imm13 requires the
546 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
547 // If the low bits are known zeros, there's nothing to do.
548 // In the second case, and only in that case, must we NOT clear
549 // bits of the immediate value via the %lo() assembler function.
550 // Note also, the 'or' instruction doesn't mind a large value in the case
551 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
552 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
James Y Knightc49e7882015-05-18 16:43:33 +0000553 MCInst TmpInst;
Douglas Katzman58195a22015-08-20 16:16:16 +0000554 const MCExpr *Expr;
555 if (IsEffectivelyImm13)
556 Expr = ValExpr;
557 else
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +0000558 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
James Y Knightc49e7882015-05-18 16:43:33 +0000559 TmpInst.setLoc(IDLoc);
560 TmpInst.setOpcode(SP::ORri);
561 TmpInst.addOperand(MCRegOp);
562 TmpInst.addOperand(PrevReg);
563 TmpInst.addOperand(MCOperand::createExpr(Expr));
564 Instructions.push_back(TmpInst);
565 }
Nirav Dave2364748a2016-09-16 18:30:20 +0000566 return false;
James Y Knightc49e7882015-05-18 16:43:33 +0000567}
568
David Blaikie960ea3f2014-06-08 16:18:35 +0000569bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
570 OperandVector &Operands,
571 MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000572 uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +0000573 bool MatchingInlineAsm) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000574 MCInst Inst;
575 SmallVector<MCInst, 8> Instructions;
576 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
577 MatchingInlineAsm);
578 switch (MatchResult) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000579 case Match_Success: {
James Y Knightc49e7882015-05-18 16:43:33 +0000580 switch (Inst.getOpcode()) {
581 default:
582 Inst.setLoc(IDLoc);
583 Instructions.push_back(Inst);
584 break;
585 case SP::SET:
Nirav Dave2364748a2016-09-16 18:30:20 +0000586 if (expandSET(Inst, IDLoc, Instructions))
587 return true;
James Y Knightc49e7882015-05-18 16:43:33 +0000588 break;
589 }
590
591 for (const MCInst &I : Instructions) {
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000592 Out.EmitInstruction(I, getSTI());
James Y Knightc49e7882015-05-18 16:43:33 +0000593 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000594 return false;
595 }
596
597 case Match_MissingFeature:
598 return Error(IDLoc,
599 "instruction requires a CPU feature not currently enabled");
600
601 case Match_InvalidOperand: {
602 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +0000603 if (ErrorInfo != ~0ULL) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000604 if (ErrorInfo >= Operands.size())
605 return Error(IDLoc, "too few operands for instruction");
606
David Blaikie960ea3f2014-06-08 16:18:35 +0000607 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000608 if (ErrorLoc == SMLoc())
609 ErrorLoc = IDLoc;
610 }
611
612 return Error(ErrorLoc, "invalid operand for instruction");
613 }
614 case Match_MnemonicFail:
Venkatraman Govindarajue0c5bff2014-03-01 18:54:52 +0000615 return Error(IDLoc, "invalid instruction mnemonic");
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000616 }
Craig Topper589ceee2015-01-03 08:16:34 +0000617 llvm_unreachable("Implement any new match types added!");
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000618}
619
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000620bool SparcAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
621 SMLoc &EndLoc) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000622 const AsmToken &Tok = Parser.getTok();
623 StartLoc = Tok.getLoc();
624 EndLoc = Tok.getEndLoc();
625 RegNo = 0;
626 if (getLexer().getKind() != AsmToken::Percent)
627 return false;
628 Parser.Lex();
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000629 unsigned regKind = SparcOperand::rk_None;
630 if (matchRegisterName(Tok, RegNo, regKind)) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000631 Parser.Lex();
632 return false;
633 }
634
635 return Error(StartLoc, "invalid register name");
636}
637
Ranjeet Singh86ecbb72015-06-30 12:32:53 +0000638static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000639 unsigned VariantID);
640
David Blaikie960ea3f2014-06-08 16:18:35 +0000641bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
642 StringRef Name, SMLoc NameLoc,
643 OperandVector &Operands) {
Venkatraman Govindarajue0c5bff2014-03-01 18:54:52 +0000644
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000645 // First operand in MCInst is instruction mnemonic.
646 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
647
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000648 // apply mnemonic aliases, if any, so that we can parse operands correctly.
649 applyMnemonicAliases(Name, getAvailableFeatures(), 0);
650
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000651 if (getLexer().isNot(AsmToken::EndOfStatement)) {
652 // Read the first operand.
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000653 if (getLexer().is(AsmToken::Comma)) {
654 if (parseBranchModifiers(Operands) != MatchOperand_Success) {
655 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000656 return Error(Loc, "unexpected token");
657 }
658 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000659 if (parseOperand(Operands, Name) != MatchOperand_Success) {
660 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000661 return Error(Loc, "unexpected token");
662 }
663
Chris Dewhurst52adb572016-03-09 18:20:21 +0000664 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
665 if (getLexer().is(AsmToken::Plus)) {
666 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
667 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
668 }
669 Parser.Lex(); // Eat the comma or plus.
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000670 // Parse and remember the operand.
671 if (parseOperand(Operands, Name) != MatchOperand_Success) {
672 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000673 return Error(Loc, "unexpected token");
674 }
675 }
676 }
677 if (getLexer().isNot(AsmToken::EndOfStatement)) {
678 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000679 return Error(Loc, "unexpected token");
680 }
681 Parser.Lex(); // Consume the EndOfStatement.
682 return false;
683}
684
685bool SparcAsmParser::
686ParseDirective(AsmToken DirectiveID)
687{
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +0000688 StringRef IDVal = DirectiveID.getString();
689
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +0000690 if (IDVal == ".register") {
691 // For now, ignore .register directive.
692 Parser.eatToEndOfStatement();
693 return false;
694 }
Douglas Katzmand0c11cf2016-03-28 14:00:11 +0000695 if (IDVal == ".proc") {
696 // For compatibility, ignore this directive.
697 // (It's supposed to be an "optimization" in the Sun assembler)
698 Parser.eatToEndOfStatement();
699 return false;
700 }
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +0000701
702 // Let the MC layer to handle other directives.
703 return true;
704}
705
Alex Bradbury58eba092016-11-01 16:32:05 +0000706OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000707SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000708 SMLoc S, E;
709 unsigned BaseReg = 0;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000710
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000711 if (ParseRegister(BaseReg, S, E)) {
712 return MatchOperand_NoMatch;
713 }
714
715 switch (getLexer().getKind()) {
716 default: return MatchOperand_NoMatch;
717
Venkatraman Govindaraju0d288d32014-01-10 01:48:17 +0000718 case AsmToken::Comma:
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000719 case AsmToken::RBrac:
720 case AsmToken::EndOfStatement:
James Y Knightc09bdfa2015-04-29 14:54:44 +0000721 Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000722 return MatchOperand_Success;
723
724 case AsmToken:: Plus:
725 Parser.Lex(); // Eat the '+'
726 break;
727 case AsmToken::Minus:
728 break;
729 }
730
David Blaikie960ea3f2014-06-08 16:18:35 +0000731 std::unique_ptr<SparcOperand> Offset;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000732 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
733 if (ResTy != MatchOperand_Success || !Offset)
734 return MatchOperand_NoMatch;
735
David Blaikie960ea3f2014-06-08 16:18:35 +0000736 Operands.push_back(
737 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
738 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000739
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000740 return MatchOperand_Success;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000741}
742
Alex Bradbury58eba092016-11-01 16:32:05 +0000743OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000744SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000745
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000746 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000747
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000748 // If there wasn't a custom match, try the generic matcher below. Otherwise,
749 // there was a match, but an error occurred, in which case, just return that
750 // the operand parsing failed.
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000751 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000752 return ResTy;
753
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000754 if (getLexer().is(AsmToken::LBrac)) {
755 // Memory operand
756 Operands.push_back(SparcOperand::CreateToken("[",
757 Parser.getTok().getLoc()));
758 Parser.Lex(); // Eat the [
759
Chris Dewhurst7d8412f2016-05-16 11:02:00 +0000760 if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
Venkatraman Govindarajuced92262014-02-07 07:34:49 +0000761 SMLoc S = Parser.getTok().getLoc();
762 if (getLexer().getKind() != AsmToken::Percent)
763 return MatchOperand_NoMatch;
764 Parser.Lex(); // eat %
765
766 unsigned RegNo, RegKind;
767 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
768 return MatchOperand_NoMatch;
769
770 Parser.Lex(); // Eat the identifier token.
771 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
772 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
773 ResTy = MatchOperand_Success;
774 } else {
775 ResTy = parseMEMOperand(Operands);
776 }
777
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000778 if (ResTy != MatchOperand_Success)
779 return ResTy;
780
781 if (!getLexer().is(AsmToken::RBrac))
782 return MatchOperand_ParseFail;
783
784 Operands.push_back(SparcOperand::CreateToken("]",
785 Parser.getTok().getLoc()));
786 Parser.Lex(); // Eat the ]
James Y Knight24060be2015-05-18 16:35:04 +0000787
788 // Parse an optional address-space identifier after the address.
789 if (getLexer().is(AsmToken::Integer)) {
790 std::unique_ptr<SparcOperand> Op;
791 ResTy = parseSparcAsmOperand(Op, false);
792 if (ResTy != MatchOperand_Success || !Op)
793 return MatchOperand_ParseFail;
794 Operands.push_back(std::move(Op));
795 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000796 return MatchOperand_Success;
797 }
798
David Blaikie960ea3f2014-06-08 16:18:35 +0000799 std::unique_ptr<SparcOperand> Op;
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000800
Venkatraman Govindaraju600f3902014-03-02 06:28:15 +0000801 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000802 if (ResTy != MatchOperand_Success || !Op)
803 return MatchOperand_ParseFail;
804
805 // Push the parsed operand into the list of operands
David Blaikie960ea3f2014-06-08 16:18:35 +0000806 Operands.push_back(std::move(Op));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000807
808 return MatchOperand_Success;
809}
810
Alex Bradbury58eba092016-11-01 16:32:05 +0000811OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000812SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
813 bool isCall) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000814 SMLoc S = Parser.getTok().getLoc();
815 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
816 const MCExpr *EVal;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000817
Craig Topper062a2ba2014-04-25 05:30:21 +0000818 Op = nullptr;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000819 switch (getLexer().getKind()) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000820 default: break;
821
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000822 case AsmToken::Percent:
823 Parser.Lex(); // Eat the '%'.
824 unsigned RegNo;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000825 unsigned RegKind;
826 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000827 StringRef name = Parser.getTok().getString();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000828 Parser.Lex(); // Eat the identifier token.
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000829 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000830 switch (RegNo) {
831 default:
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000832 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000833 break;
James Y Knightf7e70172015-05-18 16:38:47 +0000834 case Sparc::PSR:
835 Op = SparcOperand::CreateToken("%psr", S);
836 break;
Douglas Katzmane5485c62015-08-19 18:34:48 +0000837 case Sparc::FSR:
838 Op = SparcOperand::CreateToken("%fsr", S);
839 break;
Chris Dewhurst053826a2016-02-27 12:49:59 +0000840 case Sparc::FQ:
841 Op = SparcOperand::CreateToken("%fq", S);
842 break;
843 case Sparc::CPSR:
844 Op = SparcOperand::CreateToken("%csr", S);
845 break;
846 case Sparc::CPQ:
847 Op = SparcOperand::CreateToken("%cq", S);
848 break;
James Y Knightf7e70172015-05-18 16:38:47 +0000849 case Sparc::WIM:
850 Op = SparcOperand::CreateToken("%wim", S);
851 break;
852 case Sparc::TBR:
853 Op = SparcOperand::CreateToken("%tbr", S);
854 break;
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000855 case Sparc::ICC:
856 if (name == "xcc")
857 Op = SparcOperand::CreateToken("%xcc", S);
858 else
859 Op = SparcOperand::CreateToken("%icc", S);
860 break;
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000861 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000862 break;
863 }
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000864 if (matchSparcAsmModifiers(EVal, E)) {
865 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
866 Op = SparcOperand::CreateImm(EVal, S, E);
867 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000868 break;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000869
870 case AsmToken::Minus:
871 case AsmToken::Integer:
Douglas Katzman9cb88b72015-04-29 18:48:29 +0000872 case AsmToken::LParen:
Douglas Katzman685a7d12015-08-17 19:55:01 +0000873 case AsmToken::Dot:
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000874 if (!getParser().parseExpression(EVal, E))
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000875 Op = SparcOperand::CreateImm(EVal, S, E);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000876 break;
877
878 case AsmToken::Identifier: {
879 StringRef Identifier;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000880 if (!getParser().parseIdentifier(Identifier)) {
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000881 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jim Grosbach6f482002015-05-18 18:43:14 +0000882 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000883
Jim Grosbach13760bd2015-05-30 01:25:56 +0000884 const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000885 getContext());
Rafael Espindola699281c2016-05-18 11:58:50 +0000886 if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())
Jim Grosbach13760bd2015-05-30 01:25:56 +0000887 Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +0000888 getContext());
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000889 Op = SparcOperand::CreateImm(Res, S, E);
890 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000891 break;
892 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000893 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000894 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000895}
896
Alex Bradbury58eba092016-11-01 16:32:05 +0000897OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000898SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000899 // parse (,a|,pn|,pt)+
900
901 while (getLexer().is(AsmToken::Comma)) {
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000902 Parser.Lex(); // Eat the comma
903
904 if (!getLexer().is(AsmToken::Identifier))
905 return MatchOperand_ParseFail;
906 StringRef modName = Parser.getTok().getString();
907 if (modName == "a" || modName == "pn" || modName == "pt") {
908 Operands.push_back(SparcOperand::CreateToken(modName,
909 Parser.getTok().getLoc()));
910 Parser.Lex(); // eat the identifier.
911 }
912 }
913 return MatchOperand_Success;
914}
915
Eugene Zelenko3f37f072017-02-04 00:36:49 +0000916bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
917 unsigned &RegKind) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000918 int64_t intVal = 0;
919 RegNo = 0;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000920 RegKind = SparcOperand::rk_None;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000921 if (Tok.is(AsmToken::Identifier)) {
922 StringRef name = Tok.getString();
923
924 // %fp
925 if (name.equals("fp")) {
926 RegNo = Sparc::I6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000927 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000928 return true;
929 }
930 // %sp
931 if (name.equals("sp")) {
932 RegNo = Sparc::O6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000933 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000934 return true;
935 }
936
937 if (name.equals("y")) {
938 RegNo = Sparc::Y;
James Y Knightf7e70172015-05-18 16:38:47 +0000939 RegKind = SparcOperand::rk_Special;
James Y Knight807563d2015-05-18 16:29:48 +0000940 return true;
941 }
942
943 if (name.substr(0, 3).equals_lower("asr")
944 && !name.substr(3).getAsInteger(10, intVal)
945 && intVal > 0 && intVal < 32) {
946 RegNo = ASRRegs[intVal];
James Y Knightf7e70172015-05-18 16:38:47 +0000947 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000948 return true;
949 }
950
Joerg Sonnenberger7d180c52015-08-19 13:55:14 +0000951 // %fprs is an alias of %asr6.
952 if (name.equals("fprs")) {
953 RegNo = ASRRegs[6];
954 RegKind = SparcOperand::rk_Special;
955 return true;
956 }
957
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000958 if (name.equals("icc")) {
959 RegNo = Sparc::ICC;
James Y Knightf7e70172015-05-18 16:38:47 +0000960 RegKind = SparcOperand::rk_Special;
961 return true;
962 }
963
964 if (name.equals("psr")) {
965 RegNo = Sparc::PSR;
966 RegKind = SparcOperand::rk_Special;
967 return true;
968 }
969
Douglas Katzmane5485c62015-08-19 18:34:48 +0000970 if (name.equals("fsr")) {
971 RegNo = Sparc::FSR;
972 RegKind = SparcOperand::rk_Special;
973 return true;
974 }
975
Chris Dewhurst053826a2016-02-27 12:49:59 +0000976 if (name.equals("fq")) {
977 RegNo = Sparc::FQ;
978 RegKind = SparcOperand::rk_Special;
979 return true;
980 }
981
982 if (name.equals("csr")) {
983 RegNo = Sparc::CPSR;
984 RegKind = SparcOperand::rk_Special;
985 return true;
986 }
987
988 if (name.equals("cq")) {
989 RegNo = Sparc::CPQ;
990 RegKind = SparcOperand::rk_Special;
991 return true;
992 }
993
James Y Knightf7e70172015-05-18 16:38:47 +0000994 if (name.equals("wim")) {
995 RegNo = Sparc::WIM;
996 RegKind = SparcOperand::rk_Special;
997 return true;
998 }
999
1000 if (name.equals("tbr")) {
1001 RegNo = Sparc::TBR;
1002 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001003 return true;
1004 }
1005
1006 if (name.equals("xcc")) {
1007 // FIXME:: check 64bit.
1008 RegNo = Sparc::ICC;
James Y Knightf7e70172015-05-18 16:38:47 +00001009 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001010 return true;
1011 }
1012
1013 // %fcc0 - %fcc3
1014 if (name.substr(0, 3).equals_lower("fcc")
1015 && !name.substr(3).getAsInteger(10, intVal)
1016 && intVal < 4) {
1017 // FIXME: check 64bit and handle %fcc1 - %fcc3
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +00001018 RegNo = Sparc::FCC0 + intVal;
James Y Knightf7e70172015-05-18 16:38:47 +00001019 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001020 return true;
1021 }
1022
1023 // %g0 - %g7
1024 if (name.substr(0, 1).equals_lower("g")
1025 && !name.substr(1).getAsInteger(10, intVal)
1026 && intVal < 8) {
1027 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001028 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001029 return true;
1030 }
1031 // %o0 - %o7
1032 if (name.substr(0, 1).equals_lower("o")
1033 && !name.substr(1).getAsInteger(10, intVal)
1034 && intVal < 8) {
1035 RegNo = IntRegs[8 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001036 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001037 return true;
1038 }
1039 if (name.substr(0, 1).equals_lower("l")
1040 && !name.substr(1).getAsInteger(10, intVal)
1041 && intVal < 8) {
1042 RegNo = IntRegs[16 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001043 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001044 return true;
1045 }
1046 if (name.substr(0, 1).equals_lower("i")
1047 && !name.substr(1).getAsInteger(10, intVal)
1048 && intVal < 8) {
1049 RegNo = IntRegs[24 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001050 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001051 return true;
1052 }
1053 // %f0 - %f31
1054 if (name.substr(0, 1).equals_lower("f")
1055 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001056 RegNo = FloatRegs[intVal];
1057 RegKind = SparcOperand::rk_FloatReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001058 return true;
1059 }
1060 // %f32 - %f62
1061 if (name.substr(0, 1).equals_lower("f")
1062 && !name.substr(1, 2).getAsInteger(10, intVal)
1063 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001064 // FIXME: Check V9
Eric Christopher7383d4a2014-01-23 21:41:10 +00001065 RegNo = DoubleRegs[intVal/2];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001066 RegKind = SparcOperand::rk_DoubleReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001067 return true;
1068 }
1069
1070 // %r0 - %r31
1071 if (name.substr(0, 1).equals_lower("r")
1072 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1073 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001074 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001075 return true;
1076 }
Joerg Sonnenberger726e6242015-10-04 09:11:22 +00001077
Chris Dewhurst053826a2016-02-27 12:49:59 +00001078 // %c0 - %c31
1079 if (name.substr(0, 1).equals_lower("c")
1080 && !name.substr(1).getAsInteger(10, intVal)
1081 && intVal < 32) {
1082 RegNo = CoprocRegs[intVal];
1083 RegKind = SparcOperand::rk_CoprocReg;
1084 return true;
1085 }
1086
Joerg Sonnenberger726e6242015-10-04 09:11:22 +00001087 if (name.equals("tpc")) {
1088 RegNo = Sparc::TPC;
1089 RegKind = SparcOperand::rk_Special;
1090 return true;
1091 }
1092 if (name.equals("tnpc")) {
1093 RegNo = Sparc::TNPC;
1094 RegKind = SparcOperand::rk_Special;
1095 return true;
1096 }
1097 if (name.equals("tstate")) {
1098 RegNo = Sparc::TSTATE;
1099 RegKind = SparcOperand::rk_Special;
1100 return true;
1101 }
1102 if (name.equals("tt")) {
1103 RegNo = Sparc::TT;
1104 RegKind = SparcOperand::rk_Special;
1105 return true;
1106 }
1107 if (name.equals("tick")) {
1108 RegNo = Sparc::TICK;
1109 RegKind = SparcOperand::rk_Special;
1110 return true;
1111 }
1112 if (name.equals("tba")) {
1113 RegNo = Sparc::TBA;
1114 RegKind = SparcOperand::rk_Special;
1115 return true;
1116 }
1117 if (name.equals("pstate")) {
1118 RegNo = Sparc::PSTATE;
1119 RegKind = SparcOperand::rk_Special;
1120 return true;
1121 }
1122 if (name.equals("tl")) {
1123 RegNo = Sparc::TL;
1124 RegKind = SparcOperand::rk_Special;
1125 return true;
1126 }
1127 if (name.equals("pil")) {
1128 RegNo = Sparc::PIL;
1129 RegKind = SparcOperand::rk_Special;
1130 return true;
1131 }
1132 if (name.equals("cwp")) {
1133 RegNo = Sparc::CWP;
1134 RegKind = SparcOperand::rk_Special;
1135 return true;
1136 }
1137 if (name.equals("cansave")) {
1138 RegNo = Sparc::CANSAVE;
1139 RegKind = SparcOperand::rk_Special;
1140 return true;
1141 }
1142 if (name.equals("canrestore")) {
1143 RegNo = Sparc::CANRESTORE;
1144 RegKind = SparcOperand::rk_Special;
1145 return true;
1146 }
1147 if (name.equals("cleanwin")) {
1148 RegNo = Sparc::CLEANWIN;
1149 RegKind = SparcOperand::rk_Special;
1150 return true;
1151 }
1152 if (name.equals("otherwin")) {
1153 RegNo = Sparc::OTHERWIN;
1154 RegKind = SparcOperand::rk_Special;
1155 return true;
1156 }
1157 if (name.equals("wstate")) {
1158 RegNo = Sparc::WSTATE;
1159 RegKind = SparcOperand::rk_Special;
1160 return true;
1161 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001162 }
1163 return false;
1164}
1165
James Y Knightf90346f2015-06-18 15:05:15 +00001166// Determine if an expression contains a reference to the symbol
1167// "_GLOBAL_OFFSET_TABLE_".
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +00001168static bool hasGOTReference(const MCExpr *Expr) {
1169 switch (Expr->getKind()) {
1170 case MCExpr::Target:
1171 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1172 return hasGOTReference(SE->getSubExpr());
1173 break;
1174
1175 case MCExpr::Constant:
1176 break;
1177
1178 case MCExpr::Binary: {
1179 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1180 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1181 }
1182
1183 case MCExpr::SymbolRef: {
1184 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1185 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1186 }
1187
1188 case MCExpr::Unary:
1189 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1190 }
1191 return false;
1192}
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001193
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001194const SparcMCExpr *
1195SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
Eugene Zelenko3f37f072017-02-04 00:36:49 +00001196 const MCExpr *subExpr) {
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001197 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1198 // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1199 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1200 // as %got10 or %got22 relocation.
1201
Rafael Espindola699281c2016-05-18 11:58:50 +00001202 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001203 switch(VK) {
1204 default: break;
1205 case SparcMCExpr::VK_Sparc_LO:
1206 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1207 : SparcMCExpr::VK_Sparc_GOT10);
1208 break;
1209 case SparcMCExpr::VK_Sparc_HI:
1210 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1211 : SparcMCExpr::VK_Sparc_GOT22);
1212 break;
1213 }
1214 }
1215
1216 return SparcMCExpr::create(VK, subExpr, getContext());
1217}
1218
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +00001219bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
Eugene Zelenko3f37f072017-02-04 00:36:49 +00001220 SMLoc &EndLoc) {
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +00001221 AsmToken Tok = Parser.getTok();
1222 if (!Tok.is(AsmToken::Identifier))
1223 return false;
1224
1225 StringRef name = Tok.getString();
1226
1227 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1228
1229 if (VK == SparcMCExpr::VK_Sparc_None)
1230 return false;
1231
1232 Parser.Lex(); // Eat the identifier.
1233 if (Parser.getTok().getKind() != AsmToken::LParen)
1234 return false;
1235
1236 Parser.Lex(); // Eat the LParen token.
1237 const MCExpr *subExpr;
1238 if (Parser.parseParenExpression(subExpr, EndLoc))
1239 return false;
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +00001240
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001241 EVal = adjustPICRelocation(VK, subExpr);
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +00001242 return true;
1243}
1244
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001245extern "C" void LLVMInitializeSparcAsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +00001246 RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());
1247 RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());
1248 RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget());
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001249}
1250
1251#define GET_REGISTER_MATCHER
1252#define GET_MATCHER_IMPLEMENTATION
1253#include "SparcGenAsmMatcher.inc"
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001254
David Blaikie960ea3f2014-06-08 16:18:35 +00001255unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1256 unsigned Kind) {
1257 SparcOperand &Op = (SparcOperand &)GOp;
1258 if (Op.isFloatOrDoubleReg()) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001259 switch (Kind) {
1260 default: break;
1261 case MCK_DFPRegs:
David Blaikie960ea3f2014-06-08 16:18:35 +00001262 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001263 return MCTargetAsmParser::Match_Success;
1264 break;
1265 case MCK_QFPRegs:
1266 if (SparcOperand::MorphToQuadReg(Op))
1267 return MCTargetAsmParser::Match_Success;
1268 break;
1269 }
1270 }
James Y Knight3994be82015-08-10 19:11:39 +00001271 if (Op.isIntReg() && Kind == MCK_IntPair) {
1272 if (SparcOperand::MorphToIntPairReg(Op))
1273 return MCTargetAsmParser::Match_Success;
1274 }
Chris Dewhurst053826a2016-02-27 12:49:59 +00001275 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1276 if (SparcOperand::MorphToCoprocPairReg(Op))
1277 return MCTargetAsmParser::Match_Success;
1278 }
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001279 return Match_InvalidOperand;
1280}