1 //===-- 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
10 #include "MCTargetDesc/SparcMCExpr.h"
11 #include "MCTargetDesc/SparcMCTargetDesc.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCObjectFileInfo.h"
16 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
18 #include "llvm/MC/MCRegisterInfo.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/TargetRegistry.h"
23
24 using namespace llvm;
25
26 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
27 // namespace. But SPARC backend uses "SP" as its namespace.
28 namespace llvm {
29 namespace Sparc {
30 using namespace SP;
31 }
32 }
33
34 namespace {
35 class SparcOperand;
36 class SparcAsmParser : public MCTargetAsmParser {
37
38 MCAsmParser &Parser;
39
40 /// @name Auto-generated Match Functions
41 /// {
42
43 #define GET_ASSEMBLER_HEADER
44 #include "SparcGenAsmMatcher.inc"
45
46 /// }
47
48 // public interface of the MCTargetAsmParser.
49 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
50 OperandVector &Operands, MCStreamer &Out,
51 uint64_t &ErrorInfo,
52 bool MatchingInlineAsm) override;
53 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
54 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
55 SMLoc NameLoc, OperandVector &Operands) override;
56 bool ParseDirective(AsmToken DirectiveID) override;
57
58 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
59 unsigned Kind) override;
60
61 // Custom parse functions for Sparc specific operands.
62 OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
63
64 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
65
66 OperandMatchResultTy
67 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
68 bool isCall = false);
69
70 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
71
72 // Helper function for dealing with %lo / %hi in PIC mode.
73 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
74 const MCExpr *subExpr);
75
76 // returns true if Tok is matched to a register and returns register in RegNo.
77 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
78 unsigned &RegKind);
79
80 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
81 bool parseDirectiveWord(unsigned Size, SMLoc L);
82
is64Bit() const83 bool is64Bit() const {
84 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
85 }
86
87 void expandSET(MCInst &Inst, SMLoc IDLoc,
88 SmallVectorImpl<MCInst> &Instructions);
89
90 public:
SparcAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)91 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
92 const MCInstrInfo &MII,
93 const MCTargetOptions &Options)
94 : MCTargetAsmParser(Options, sti), Parser(parser) {
95 // Initialize the set of available features.
96 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
97 }
98
99 };
100
101 static const MCPhysReg IntRegs[32] = {
102 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
103 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
104 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
105 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
106 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
107 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
108 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
109 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
110
111 static const MCPhysReg FloatRegs[32] = {
112 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
113 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
114 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
115 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
116 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
117 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
118 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
119 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
120
121 static const MCPhysReg DoubleRegs[32] = {
122 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
123 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
124 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
125 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
126 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
127 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
128 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
129 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
130
131 static const MCPhysReg QuadFPRegs[32] = {
132 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
133 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
134 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
135 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
136
137 static const MCPhysReg ASRRegs[32] = {
138 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
139 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
140 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
141 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
142 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
143 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
144 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
145 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
146
147 static const MCPhysReg IntPairRegs[] = {
148 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
149 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
150 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
151 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
152
153 static const MCPhysReg CoprocRegs[32] = {
154 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
155 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
156 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
157 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
158 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
159 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
160 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
161 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
162
163 static const MCPhysReg CoprocPairRegs[] = {
164 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
165 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
166 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
167 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
168
169 /// SparcOperand - Instances of this class represent a parsed Sparc machine
170 /// instruction.
171 class SparcOperand : public MCParsedAsmOperand {
172 public:
173 enum RegisterKind {
174 rk_None,
175 rk_IntReg,
176 rk_IntPairReg,
177 rk_FloatReg,
178 rk_DoubleReg,
179 rk_QuadReg,
180 rk_CoprocReg,
181 rk_CoprocPairReg,
182 rk_Special,
183 };
184
185 private:
186 enum KindTy {
187 k_Token,
188 k_Register,
189 k_Immediate,
190 k_MemoryReg,
191 k_MemoryImm
192 } Kind;
193
194 SMLoc StartLoc, EndLoc;
195
196 struct Token {
197 const char *Data;
198 unsigned Length;
199 };
200
201 struct RegOp {
202 unsigned RegNum;
203 RegisterKind Kind;
204 };
205
206 struct ImmOp {
207 const MCExpr *Val;
208 };
209
210 struct MemOp {
211 unsigned Base;
212 unsigned OffsetReg;
213 const MCExpr *Off;
214 };
215
216 union {
217 struct Token Tok;
218 struct RegOp Reg;
219 struct ImmOp Imm;
220 struct MemOp Mem;
221 };
222 public:
SparcOperand(KindTy K)223 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
224
isToken() const225 bool isToken() const override { return Kind == k_Token; }
isReg() const226 bool isReg() const override { return Kind == k_Register; }
isImm() const227 bool isImm() const override { return Kind == k_Immediate; }
isMem() const228 bool isMem() const override { return isMEMrr() || isMEMri(); }
isMEMrr() const229 bool isMEMrr() const { return Kind == k_MemoryReg; }
isMEMri() const230 bool isMEMri() const { return Kind == k_MemoryImm; }
231
isIntReg() const232 bool isIntReg() const {
233 return (Kind == k_Register && Reg.Kind == rk_IntReg);
234 }
235
isFloatReg() const236 bool isFloatReg() const {
237 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
238 }
239
isFloatOrDoubleReg() const240 bool isFloatOrDoubleReg() const {
241 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
242 || Reg.Kind == rk_DoubleReg));
243 }
244
isCoprocReg() const245 bool isCoprocReg() const {
246 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
247 }
248
getToken() const249 StringRef getToken() const {
250 assert(Kind == k_Token && "Invalid access!");
251 return StringRef(Tok.Data, Tok.Length);
252 }
253
getReg() const254 unsigned getReg() const override {
255 assert((Kind == k_Register) && "Invalid access!");
256 return Reg.RegNum;
257 }
258
getImm() const259 const MCExpr *getImm() const {
260 assert((Kind == k_Immediate) && "Invalid access!");
261 return Imm.Val;
262 }
263
getMemBase() const264 unsigned getMemBase() const {
265 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
266 return Mem.Base;
267 }
268
getMemOffsetReg() const269 unsigned getMemOffsetReg() const {
270 assert((Kind == k_MemoryReg) && "Invalid access!");
271 return Mem.OffsetReg;
272 }
273
getMemOff() const274 const MCExpr *getMemOff() const {
275 assert((Kind == k_MemoryImm) && "Invalid access!");
276 return Mem.Off;
277 }
278
279 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const280 SMLoc getStartLoc() const override {
281 return StartLoc;
282 }
283 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const284 SMLoc getEndLoc() const override {
285 return EndLoc;
286 }
287
print(raw_ostream & OS) const288 void print(raw_ostream &OS) const override {
289 switch (Kind) {
290 case k_Token: OS << "Token: " << getToken() << "\n"; break;
291 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
292 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
293 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
294 << getMemOffsetReg() << "\n"; break;
295 case k_MemoryImm: assert(getMemOff() != nullptr);
296 OS << "Mem: " << getMemBase()
297 << "+" << *getMemOff()
298 << "\n"; break;
299 }
300 }
301
addRegOperands(MCInst & Inst,unsigned N) const302 void addRegOperands(MCInst &Inst, unsigned N) const {
303 assert(N == 1 && "Invalid number of operands!");
304 Inst.addOperand(MCOperand::createReg(getReg()));
305 }
306
addImmOperands(MCInst & Inst,unsigned N) const307 void addImmOperands(MCInst &Inst, unsigned N) const {
308 assert(N == 1 && "Invalid number of operands!");
309 const MCExpr *Expr = getImm();
310 addExpr(Inst, Expr);
311 }
312
addExpr(MCInst & Inst,const MCExpr * Expr) const313 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
314 // Add as immediate when possible. Null MCExpr = 0.
315 if (!Expr)
316 Inst.addOperand(MCOperand::createImm(0));
317 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
318 Inst.addOperand(MCOperand::createImm(CE->getValue()));
319 else
320 Inst.addOperand(MCOperand::createExpr(Expr));
321 }
322
addMEMrrOperands(MCInst & Inst,unsigned N) const323 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
324 assert(N == 2 && "Invalid number of operands!");
325
326 Inst.addOperand(MCOperand::createReg(getMemBase()));
327
328 assert(getMemOffsetReg() != 0 && "Invalid offset");
329 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
330 }
331
addMEMriOperands(MCInst & Inst,unsigned N) const332 void addMEMriOperands(MCInst &Inst, unsigned N) const {
333 assert(N == 2 && "Invalid number of operands!");
334
335 Inst.addOperand(MCOperand::createReg(getMemBase()));
336
337 const MCExpr *Expr = getMemOff();
338 addExpr(Inst, Expr);
339 }
340
CreateToken(StringRef Str,SMLoc S)341 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
342 auto Op = make_unique<SparcOperand>(k_Token);
343 Op->Tok.Data = Str.data();
344 Op->Tok.Length = Str.size();
345 Op->StartLoc = S;
346 Op->EndLoc = S;
347 return Op;
348 }
349
CreateReg(unsigned RegNum,unsigned Kind,SMLoc S,SMLoc E)350 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
351 SMLoc S, SMLoc E) {
352 auto Op = make_unique<SparcOperand>(k_Register);
353 Op->Reg.RegNum = RegNum;
354 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
355 Op->StartLoc = S;
356 Op->EndLoc = E;
357 return Op;
358 }
359
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E)360 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
361 SMLoc E) {
362 auto Op = make_unique<SparcOperand>(k_Immediate);
363 Op->Imm.Val = Val;
364 Op->StartLoc = S;
365 Op->EndLoc = E;
366 return Op;
367 }
368
MorphToIntPairReg(SparcOperand & Op)369 static bool MorphToIntPairReg(SparcOperand &Op) {
370 unsigned Reg = Op.getReg();
371 assert(Op.Reg.Kind == rk_IntReg);
372 unsigned regIdx = 32;
373 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
374 regIdx = Reg - Sparc::G0;
375 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
376 regIdx = Reg - Sparc::O0 + 8;
377 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
378 regIdx = Reg - Sparc::L0 + 16;
379 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
380 regIdx = Reg - Sparc::I0 + 24;
381 if (regIdx % 2 || regIdx > 31)
382 return false;
383 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
384 Op.Reg.Kind = rk_IntPairReg;
385 return true;
386 }
387
MorphToDoubleReg(SparcOperand & Op)388 static bool MorphToDoubleReg(SparcOperand &Op) {
389 unsigned Reg = Op.getReg();
390 assert(Op.Reg.Kind == rk_FloatReg);
391 unsigned regIdx = Reg - Sparc::F0;
392 if (regIdx % 2 || regIdx > 31)
393 return false;
394 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
395 Op.Reg.Kind = rk_DoubleReg;
396 return true;
397 }
398
MorphToQuadReg(SparcOperand & Op)399 static bool MorphToQuadReg(SparcOperand &Op) {
400 unsigned Reg = Op.getReg();
401 unsigned regIdx = 0;
402 switch (Op.Reg.Kind) {
403 default: llvm_unreachable("Unexpected register kind!");
404 case rk_FloatReg:
405 regIdx = Reg - Sparc::F0;
406 if (regIdx % 4 || regIdx > 31)
407 return false;
408 Reg = QuadFPRegs[regIdx / 4];
409 break;
410 case rk_DoubleReg:
411 regIdx = Reg - Sparc::D0;
412 if (regIdx % 2 || regIdx > 31)
413 return false;
414 Reg = QuadFPRegs[regIdx / 2];
415 break;
416 }
417 Op.Reg.RegNum = Reg;
418 Op.Reg.Kind = rk_QuadReg;
419 return true;
420 }
421
MorphToCoprocPairReg(SparcOperand & Op)422 static bool MorphToCoprocPairReg(SparcOperand &Op) {
423 unsigned Reg = Op.getReg();
424 assert(Op.Reg.Kind == rk_CoprocReg);
425 unsigned regIdx = 32;
426 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
427 regIdx = Reg - Sparc::C0;
428 if (regIdx % 2 || regIdx > 31)
429 return false;
430 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
431 Op.Reg.Kind = rk_CoprocPairReg;
432 return true;
433 }
434
435 static std::unique_ptr<SparcOperand>
MorphToMEMrr(unsigned Base,std::unique_ptr<SparcOperand> Op)436 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
437 unsigned offsetReg = Op->getReg();
438 Op->Kind = k_MemoryReg;
439 Op->Mem.Base = Base;
440 Op->Mem.OffsetReg = offsetReg;
441 Op->Mem.Off = nullptr;
442 return Op;
443 }
444
445 static std::unique_ptr<SparcOperand>
CreateMEMr(unsigned Base,SMLoc S,SMLoc E)446 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
447 auto Op = make_unique<SparcOperand>(k_MemoryReg);
448 Op->Mem.Base = Base;
449 Op->Mem.OffsetReg = Sparc::G0; // always 0
450 Op->Mem.Off = nullptr;
451 Op->StartLoc = S;
452 Op->EndLoc = E;
453 return Op;
454 }
455
456 static std::unique_ptr<SparcOperand>
MorphToMEMri(unsigned Base,std::unique_ptr<SparcOperand> Op)457 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
458 const MCExpr *Imm = Op->getImm();
459 Op->Kind = k_MemoryImm;
460 Op->Mem.Base = Base;
461 Op->Mem.OffsetReg = 0;
462 Op->Mem.Off = Imm;
463 return Op;
464 }
465 };
466
467 } // end namespace
468
expandSET(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)469 void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
470 SmallVectorImpl<MCInst> &Instructions) {
471 MCOperand MCRegOp = Inst.getOperand(0);
472 MCOperand MCValOp = Inst.getOperand(1);
473 assert(MCRegOp.isReg());
474 assert(MCValOp.isImm() || MCValOp.isExpr());
475
476 // the imm operand can be either an expression or an immediate.
477 bool IsImm = Inst.getOperand(1).isImm();
478 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
479
480 // Allow either a signed or unsigned 32-bit immediate.
481 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
482 Error(IDLoc, "set: argument must be between -2147483648 and 4294967295");
483 return;
484 }
485
486 // If the value was expressed as a large unsigned number, that's ok.
487 // We want to see if it "looks like" a small signed number.
488 int32_t ImmValue = RawImmValue;
489 // For 'set' you can't use 'or' with a negative operand on V9 because
490 // that would splat the sign bit across the upper half of the destination
491 // register, whereas 'set' is defined to zero the high 32 bits.
492 bool IsEffectivelyImm13 =
493 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
494 const MCExpr *ValExpr;
495 if (IsImm)
496 ValExpr = MCConstantExpr::create(ImmValue, getContext());
497 else
498 ValExpr = MCValOp.getExpr();
499
500 MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
501
502 // If not just a signed imm13 value, then either we use a 'sethi' with a
503 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
504 // In either case, start with the 'sethi'.
505 if (!IsEffectivelyImm13) {
506 MCInst TmpInst;
507 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
508 TmpInst.setLoc(IDLoc);
509 TmpInst.setOpcode(SP::SETHIi);
510 TmpInst.addOperand(MCRegOp);
511 TmpInst.addOperand(MCOperand::createExpr(Expr));
512 Instructions.push_back(TmpInst);
513 PrevReg = MCRegOp;
514 }
515
516 // The low bits require touching in 3 cases:
517 // * A non-immediate value will always require both instructions.
518 // * An effectively imm13 value needs only an 'or' instruction.
519 // * Otherwise, an immediate that is not effectively imm13 requires the
520 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
521 // If the low bits are known zeros, there's nothing to do.
522 // In the second case, and only in that case, must we NOT clear
523 // bits of the immediate value via the %lo() assembler function.
524 // Note also, the 'or' instruction doesn't mind a large value in the case
525 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
526 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
527 MCInst TmpInst;
528 const MCExpr *Expr;
529 if (IsEffectivelyImm13)
530 Expr = ValExpr;
531 else
532 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
533 TmpInst.setLoc(IDLoc);
534 TmpInst.setOpcode(SP::ORri);
535 TmpInst.addOperand(MCRegOp);
536 TmpInst.addOperand(PrevReg);
537 TmpInst.addOperand(MCOperand::createExpr(Expr));
538 Instructions.push_back(TmpInst);
539 }
540 }
541
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)542 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
543 OperandVector &Operands,
544 MCStreamer &Out,
545 uint64_t &ErrorInfo,
546 bool MatchingInlineAsm) {
547 MCInst Inst;
548 SmallVector<MCInst, 8> Instructions;
549 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
550 MatchingInlineAsm);
551 switch (MatchResult) {
552 case Match_Success: {
553 switch (Inst.getOpcode()) {
554 default:
555 Inst.setLoc(IDLoc);
556 Instructions.push_back(Inst);
557 break;
558 case SP::SET:
559 expandSET(Inst, IDLoc, Instructions);
560 break;
561 }
562
563 for (const MCInst &I : Instructions) {
564 Out.EmitInstruction(I, getSTI());
565 }
566 return false;
567 }
568
569 case Match_MissingFeature:
570 return Error(IDLoc,
571 "instruction requires a CPU feature not currently enabled");
572
573 case Match_InvalidOperand: {
574 SMLoc ErrorLoc = IDLoc;
575 if (ErrorInfo != ~0ULL) {
576 if (ErrorInfo >= Operands.size())
577 return Error(IDLoc, "too few operands for instruction");
578
579 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
580 if (ErrorLoc == SMLoc())
581 ErrorLoc = IDLoc;
582 }
583
584 return Error(ErrorLoc, "invalid operand for instruction");
585 }
586 case Match_MnemonicFail:
587 return Error(IDLoc, "invalid instruction mnemonic");
588 }
589 llvm_unreachable("Implement any new match types added!");
590 }
591
592 bool SparcAsmParser::
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)593 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
594 {
595 const AsmToken &Tok = Parser.getTok();
596 StartLoc = Tok.getLoc();
597 EndLoc = Tok.getEndLoc();
598 RegNo = 0;
599 if (getLexer().getKind() != AsmToken::Percent)
600 return false;
601 Parser.Lex();
602 unsigned regKind = SparcOperand::rk_None;
603 if (matchRegisterName(Tok, RegNo, regKind)) {
604 Parser.Lex();
605 return false;
606 }
607
608 return Error(StartLoc, "invalid register name");
609 }
610
611 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
612 unsigned VariantID);
613
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)614 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
615 StringRef Name, SMLoc NameLoc,
616 OperandVector &Operands) {
617
618 // First operand in MCInst is instruction mnemonic.
619 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
620
621 // apply mnemonic aliases, if any, so that we can parse operands correctly.
622 applyMnemonicAliases(Name, getAvailableFeatures(), 0);
623
624 if (getLexer().isNot(AsmToken::EndOfStatement)) {
625 // Read the first operand.
626 if (getLexer().is(AsmToken::Comma)) {
627 if (parseBranchModifiers(Operands) != MatchOperand_Success) {
628 SMLoc Loc = getLexer().getLoc();
629 Parser.eatToEndOfStatement();
630 return Error(Loc, "unexpected token");
631 }
632 }
633 if (parseOperand(Operands, Name) != MatchOperand_Success) {
634 SMLoc Loc = getLexer().getLoc();
635 Parser.eatToEndOfStatement();
636 return Error(Loc, "unexpected token");
637 }
638
639 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
640 if (getLexer().is(AsmToken::Plus)) {
641 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
642 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
643 }
644 Parser.Lex(); // Eat the comma or plus.
645 // Parse and remember the operand.
646 if (parseOperand(Operands, Name) != MatchOperand_Success) {
647 SMLoc Loc = getLexer().getLoc();
648 Parser.eatToEndOfStatement();
649 return Error(Loc, "unexpected token");
650 }
651 }
652 }
653 if (getLexer().isNot(AsmToken::EndOfStatement)) {
654 SMLoc Loc = getLexer().getLoc();
655 Parser.eatToEndOfStatement();
656 return Error(Loc, "unexpected token");
657 }
658 Parser.Lex(); // Consume the EndOfStatement.
659 return false;
660 }
661
662 bool SparcAsmParser::
ParseDirective(AsmToken DirectiveID)663 ParseDirective(AsmToken DirectiveID)
664 {
665 StringRef IDVal = DirectiveID.getString();
666
667 if (IDVal == ".byte")
668 return parseDirectiveWord(1, DirectiveID.getLoc());
669
670 if (IDVal == ".half")
671 return parseDirectiveWord(2, DirectiveID.getLoc());
672
673 if (IDVal == ".word")
674 return parseDirectiveWord(4, DirectiveID.getLoc());
675
676 if (IDVal == ".nword")
677 return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
678
679 if (is64Bit() && IDVal == ".xword")
680 return parseDirectiveWord(8, DirectiveID.getLoc());
681
682 if (IDVal == ".register") {
683 // For now, ignore .register directive.
684 Parser.eatToEndOfStatement();
685 return false;
686 }
687 if (IDVal == ".proc") {
688 // For compatibility, ignore this directive.
689 // (It's supposed to be an "optimization" in the Sun assembler)
690 Parser.eatToEndOfStatement();
691 return false;
692 }
693
694 // Let the MC layer to handle other directives.
695 return true;
696 }
697
parseDirectiveWord(unsigned Size,SMLoc L)698 bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
699 if (getLexer().isNot(AsmToken::EndOfStatement)) {
700 for (;;) {
701 const MCExpr *Value;
702 if (getParser().parseExpression(Value))
703 return true;
704
705 getParser().getStreamer().EmitValue(Value, Size);
706
707 if (getLexer().is(AsmToken::EndOfStatement))
708 break;
709
710 // FIXME: Improve diagnostic.
711 if (getLexer().isNot(AsmToken::Comma))
712 return Error(L, "unexpected token in directive");
713 Parser.Lex();
714 }
715 }
716 Parser.Lex();
717 return false;
718 }
719
720 SparcAsmParser::OperandMatchResultTy
parseMEMOperand(OperandVector & Operands)721 SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
722
723 SMLoc S, E;
724 unsigned BaseReg = 0;
725
726 if (ParseRegister(BaseReg, S, E)) {
727 return MatchOperand_NoMatch;
728 }
729
730 switch (getLexer().getKind()) {
731 default: return MatchOperand_NoMatch;
732
733 case AsmToken::Comma:
734 case AsmToken::RBrac:
735 case AsmToken::EndOfStatement:
736 Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
737 return MatchOperand_Success;
738
739 case AsmToken:: Plus:
740 Parser.Lex(); // Eat the '+'
741 break;
742 case AsmToken::Minus:
743 break;
744 }
745
746 std::unique_ptr<SparcOperand> Offset;
747 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
748 if (ResTy != MatchOperand_Success || !Offset)
749 return MatchOperand_NoMatch;
750
751 Operands.push_back(
752 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
753 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
754
755 return MatchOperand_Success;
756 }
757
758 SparcAsmParser::OperandMatchResultTy
parseOperand(OperandVector & Operands,StringRef Mnemonic)759 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
760
761 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
762
763 // If there wasn't a custom match, try the generic matcher below. Otherwise,
764 // there was a match, but an error occurred, in which case, just return that
765 // the operand parsing failed.
766 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
767 return ResTy;
768
769 if (getLexer().is(AsmToken::LBrac)) {
770 // Memory operand
771 Operands.push_back(SparcOperand::CreateToken("[",
772 Parser.getTok().getLoc()));
773 Parser.Lex(); // Eat the [
774
775 if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
776 SMLoc S = Parser.getTok().getLoc();
777 if (getLexer().getKind() != AsmToken::Percent)
778 return MatchOperand_NoMatch;
779 Parser.Lex(); // eat %
780
781 unsigned RegNo, RegKind;
782 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
783 return MatchOperand_NoMatch;
784
785 Parser.Lex(); // Eat the identifier token.
786 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
787 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
788 ResTy = MatchOperand_Success;
789 } else {
790 ResTy = parseMEMOperand(Operands);
791 }
792
793 if (ResTy != MatchOperand_Success)
794 return ResTy;
795
796 if (!getLexer().is(AsmToken::RBrac))
797 return MatchOperand_ParseFail;
798
799 Operands.push_back(SparcOperand::CreateToken("]",
800 Parser.getTok().getLoc()));
801 Parser.Lex(); // Eat the ]
802
803 // Parse an optional address-space identifier after the address.
804 if (getLexer().is(AsmToken::Integer)) {
805 std::unique_ptr<SparcOperand> Op;
806 ResTy = parseSparcAsmOperand(Op, false);
807 if (ResTy != MatchOperand_Success || !Op)
808 return MatchOperand_ParseFail;
809 Operands.push_back(std::move(Op));
810 }
811 return MatchOperand_Success;
812 }
813
814 std::unique_ptr<SparcOperand> Op;
815
816 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
817 if (ResTy != MatchOperand_Success || !Op)
818 return MatchOperand_ParseFail;
819
820 // Push the parsed operand into the list of operands
821 Operands.push_back(std::move(Op));
822
823 return MatchOperand_Success;
824 }
825
826 SparcAsmParser::OperandMatchResultTy
parseSparcAsmOperand(std::unique_ptr<SparcOperand> & Op,bool isCall)827 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
828 bool isCall) {
829
830 SMLoc S = Parser.getTok().getLoc();
831 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
832 const MCExpr *EVal;
833
834 Op = nullptr;
835 switch (getLexer().getKind()) {
836 default: break;
837
838 case AsmToken::Percent:
839 Parser.Lex(); // Eat the '%'.
840 unsigned RegNo;
841 unsigned RegKind;
842 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
843 StringRef name = Parser.getTok().getString();
844 Parser.Lex(); // Eat the identifier token.
845 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
846 switch (RegNo) {
847 default:
848 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
849 break;
850 case Sparc::PSR:
851 Op = SparcOperand::CreateToken("%psr", S);
852 break;
853 case Sparc::FSR:
854 Op = SparcOperand::CreateToken("%fsr", S);
855 break;
856 case Sparc::FQ:
857 Op = SparcOperand::CreateToken("%fq", S);
858 break;
859 case Sparc::CPSR:
860 Op = SparcOperand::CreateToken("%csr", S);
861 break;
862 case Sparc::CPQ:
863 Op = SparcOperand::CreateToken("%cq", S);
864 break;
865 case Sparc::WIM:
866 Op = SparcOperand::CreateToken("%wim", S);
867 break;
868 case Sparc::TBR:
869 Op = SparcOperand::CreateToken("%tbr", S);
870 break;
871 case Sparc::ICC:
872 if (name == "xcc")
873 Op = SparcOperand::CreateToken("%xcc", S);
874 else
875 Op = SparcOperand::CreateToken("%icc", S);
876 break;
877 }
878 break;
879 }
880 if (matchSparcAsmModifiers(EVal, E)) {
881 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
882 Op = SparcOperand::CreateImm(EVal, S, E);
883 }
884 break;
885
886 case AsmToken::Minus:
887 case AsmToken::Integer:
888 case AsmToken::LParen:
889 case AsmToken::Dot:
890 if (!getParser().parseExpression(EVal, E))
891 Op = SparcOperand::CreateImm(EVal, S, E);
892 break;
893
894 case AsmToken::Identifier: {
895 StringRef Identifier;
896 if (!getParser().parseIdentifier(Identifier)) {
897 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
898 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
899
900 const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
901 getContext());
902 if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())
903 Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
904 getContext());
905 Op = SparcOperand::CreateImm(Res, S, E);
906 }
907 break;
908 }
909 }
910 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
911 }
912
913 SparcAsmParser::OperandMatchResultTy
parseBranchModifiers(OperandVector & Operands)914 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
915
916 // parse (,a|,pn|,pt)+
917
918 while (getLexer().is(AsmToken::Comma)) {
919
920 Parser.Lex(); // Eat the comma
921
922 if (!getLexer().is(AsmToken::Identifier))
923 return MatchOperand_ParseFail;
924 StringRef modName = Parser.getTok().getString();
925 if (modName == "a" || modName == "pn" || modName == "pt") {
926 Operands.push_back(SparcOperand::CreateToken(modName,
927 Parser.getTok().getLoc()));
928 Parser.Lex(); // eat the identifier.
929 }
930 }
931 return MatchOperand_Success;
932 }
933
matchRegisterName(const AsmToken & Tok,unsigned & RegNo,unsigned & RegKind)934 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
935 unsigned &RegNo,
936 unsigned &RegKind)
937 {
938 int64_t intVal = 0;
939 RegNo = 0;
940 RegKind = SparcOperand::rk_None;
941 if (Tok.is(AsmToken::Identifier)) {
942 StringRef name = Tok.getString();
943
944 // %fp
945 if (name.equals("fp")) {
946 RegNo = Sparc::I6;
947 RegKind = SparcOperand::rk_IntReg;
948 return true;
949 }
950 // %sp
951 if (name.equals("sp")) {
952 RegNo = Sparc::O6;
953 RegKind = SparcOperand::rk_IntReg;
954 return true;
955 }
956
957 if (name.equals("y")) {
958 RegNo = Sparc::Y;
959 RegKind = SparcOperand::rk_Special;
960 return true;
961 }
962
963 if (name.substr(0, 3).equals_lower("asr")
964 && !name.substr(3).getAsInteger(10, intVal)
965 && intVal > 0 && intVal < 32) {
966 RegNo = ASRRegs[intVal];
967 RegKind = SparcOperand::rk_Special;
968 return true;
969 }
970
971 // %fprs is an alias of %asr6.
972 if (name.equals("fprs")) {
973 RegNo = ASRRegs[6];
974 RegKind = SparcOperand::rk_Special;
975 return true;
976 }
977
978 if (name.equals("icc")) {
979 RegNo = Sparc::ICC;
980 RegKind = SparcOperand::rk_Special;
981 return true;
982 }
983
984 if (name.equals("psr")) {
985 RegNo = Sparc::PSR;
986 RegKind = SparcOperand::rk_Special;
987 return true;
988 }
989
990 if (name.equals("fsr")) {
991 RegNo = Sparc::FSR;
992 RegKind = SparcOperand::rk_Special;
993 return true;
994 }
995
996 if (name.equals("fq")) {
997 RegNo = Sparc::FQ;
998 RegKind = SparcOperand::rk_Special;
999 return true;
1000 }
1001
1002 if (name.equals("csr")) {
1003 RegNo = Sparc::CPSR;
1004 RegKind = SparcOperand::rk_Special;
1005 return true;
1006 }
1007
1008 if (name.equals("cq")) {
1009 RegNo = Sparc::CPQ;
1010 RegKind = SparcOperand::rk_Special;
1011 return true;
1012 }
1013
1014 if (name.equals("wim")) {
1015 RegNo = Sparc::WIM;
1016 RegKind = SparcOperand::rk_Special;
1017 return true;
1018 }
1019
1020 if (name.equals("tbr")) {
1021 RegNo = Sparc::TBR;
1022 RegKind = SparcOperand::rk_Special;
1023 return true;
1024 }
1025
1026 if (name.equals("xcc")) {
1027 // FIXME:: check 64bit.
1028 RegNo = Sparc::ICC;
1029 RegKind = SparcOperand::rk_Special;
1030 return true;
1031 }
1032
1033 // %fcc0 - %fcc3
1034 if (name.substr(0, 3).equals_lower("fcc")
1035 && !name.substr(3).getAsInteger(10, intVal)
1036 && intVal < 4) {
1037 // FIXME: check 64bit and handle %fcc1 - %fcc3
1038 RegNo = Sparc::FCC0 + intVal;
1039 RegKind = SparcOperand::rk_Special;
1040 return true;
1041 }
1042
1043 // %g0 - %g7
1044 if (name.substr(0, 1).equals_lower("g")
1045 && !name.substr(1).getAsInteger(10, intVal)
1046 && intVal < 8) {
1047 RegNo = IntRegs[intVal];
1048 RegKind = SparcOperand::rk_IntReg;
1049 return true;
1050 }
1051 // %o0 - %o7
1052 if (name.substr(0, 1).equals_lower("o")
1053 && !name.substr(1).getAsInteger(10, intVal)
1054 && intVal < 8) {
1055 RegNo = IntRegs[8 + intVal];
1056 RegKind = SparcOperand::rk_IntReg;
1057 return true;
1058 }
1059 if (name.substr(0, 1).equals_lower("l")
1060 && !name.substr(1).getAsInteger(10, intVal)
1061 && intVal < 8) {
1062 RegNo = IntRegs[16 + intVal];
1063 RegKind = SparcOperand::rk_IntReg;
1064 return true;
1065 }
1066 if (name.substr(0, 1).equals_lower("i")
1067 && !name.substr(1).getAsInteger(10, intVal)
1068 && intVal < 8) {
1069 RegNo = IntRegs[24 + intVal];
1070 RegKind = SparcOperand::rk_IntReg;
1071 return true;
1072 }
1073 // %f0 - %f31
1074 if (name.substr(0, 1).equals_lower("f")
1075 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1076 RegNo = FloatRegs[intVal];
1077 RegKind = SparcOperand::rk_FloatReg;
1078 return true;
1079 }
1080 // %f32 - %f62
1081 if (name.substr(0, 1).equals_lower("f")
1082 && !name.substr(1, 2).getAsInteger(10, intVal)
1083 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1084 // FIXME: Check V9
1085 RegNo = DoubleRegs[intVal/2];
1086 RegKind = SparcOperand::rk_DoubleReg;
1087 return true;
1088 }
1089
1090 // %r0 - %r31
1091 if (name.substr(0, 1).equals_lower("r")
1092 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1093 RegNo = IntRegs[intVal];
1094 RegKind = SparcOperand::rk_IntReg;
1095 return true;
1096 }
1097
1098 // %c0 - %c31
1099 if (name.substr(0, 1).equals_lower("c")
1100 && !name.substr(1).getAsInteger(10, intVal)
1101 && intVal < 32) {
1102 RegNo = CoprocRegs[intVal];
1103 RegKind = SparcOperand::rk_CoprocReg;
1104 return true;
1105 }
1106
1107 if (name.equals("tpc")) {
1108 RegNo = Sparc::TPC;
1109 RegKind = SparcOperand::rk_Special;
1110 return true;
1111 }
1112 if (name.equals("tnpc")) {
1113 RegNo = Sparc::TNPC;
1114 RegKind = SparcOperand::rk_Special;
1115 return true;
1116 }
1117 if (name.equals("tstate")) {
1118 RegNo = Sparc::TSTATE;
1119 RegKind = SparcOperand::rk_Special;
1120 return true;
1121 }
1122 if (name.equals("tt")) {
1123 RegNo = Sparc::TT;
1124 RegKind = SparcOperand::rk_Special;
1125 return true;
1126 }
1127 if (name.equals("tick")) {
1128 RegNo = Sparc::TICK;
1129 RegKind = SparcOperand::rk_Special;
1130 return true;
1131 }
1132 if (name.equals("tba")) {
1133 RegNo = Sparc::TBA;
1134 RegKind = SparcOperand::rk_Special;
1135 return true;
1136 }
1137 if (name.equals("pstate")) {
1138 RegNo = Sparc::PSTATE;
1139 RegKind = SparcOperand::rk_Special;
1140 return true;
1141 }
1142 if (name.equals("tl")) {
1143 RegNo = Sparc::TL;
1144 RegKind = SparcOperand::rk_Special;
1145 return true;
1146 }
1147 if (name.equals("pil")) {
1148 RegNo = Sparc::PIL;
1149 RegKind = SparcOperand::rk_Special;
1150 return true;
1151 }
1152 if (name.equals("cwp")) {
1153 RegNo = Sparc::CWP;
1154 RegKind = SparcOperand::rk_Special;
1155 return true;
1156 }
1157 if (name.equals("cansave")) {
1158 RegNo = Sparc::CANSAVE;
1159 RegKind = SparcOperand::rk_Special;
1160 return true;
1161 }
1162 if (name.equals("canrestore")) {
1163 RegNo = Sparc::CANRESTORE;
1164 RegKind = SparcOperand::rk_Special;
1165 return true;
1166 }
1167 if (name.equals("cleanwin")) {
1168 RegNo = Sparc::CLEANWIN;
1169 RegKind = SparcOperand::rk_Special;
1170 return true;
1171 }
1172 if (name.equals("otherwin")) {
1173 RegNo = Sparc::OTHERWIN;
1174 RegKind = SparcOperand::rk_Special;
1175 return true;
1176 }
1177 if (name.equals("wstate")) {
1178 RegNo = Sparc::WSTATE;
1179 RegKind = SparcOperand::rk_Special;
1180 return true;
1181 }
1182 }
1183 return false;
1184 }
1185
1186 // Determine if an expression contains a reference to the symbol
1187 // "_GLOBAL_OFFSET_TABLE_".
hasGOTReference(const MCExpr * Expr)1188 static bool hasGOTReference(const MCExpr *Expr) {
1189 switch (Expr->getKind()) {
1190 case MCExpr::Target:
1191 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1192 return hasGOTReference(SE->getSubExpr());
1193 break;
1194
1195 case MCExpr::Constant:
1196 break;
1197
1198 case MCExpr::Binary: {
1199 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1200 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1201 }
1202
1203 case MCExpr::SymbolRef: {
1204 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1205 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1206 }
1207
1208 case MCExpr::Unary:
1209 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1210 }
1211 return false;
1212 }
1213
1214 const SparcMCExpr *
adjustPICRelocation(SparcMCExpr::VariantKind VK,const MCExpr * subExpr)1215 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1216 const MCExpr *subExpr)
1217 {
1218 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1219 // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1220 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1221 // as %got10 or %got22 relocation.
1222
1223 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1224 switch(VK) {
1225 default: break;
1226 case SparcMCExpr::VK_Sparc_LO:
1227 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1228 : SparcMCExpr::VK_Sparc_GOT10);
1229 break;
1230 case SparcMCExpr::VK_Sparc_HI:
1231 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1232 : SparcMCExpr::VK_Sparc_GOT22);
1233 break;
1234 }
1235 }
1236
1237 return SparcMCExpr::create(VK, subExpr, getContext());
1238 }
1239
matchSparcAsmModifiers(const MCExpr * & EVal,SMLoc & EndLoc)1240 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1241 SMLoc &EndLoc)
1242 {
1243 AsmToken Tok = Parser.getTok();
1244 if (!Tok.is(AsmToken::Identifier))
1245 return false;
1246
1247 StringRef name = Tok.getString();
1248
1249 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1250
1251 if (VK == SparcMCExpr::VK_Sparc_None)
1252 return false;
1253
1254 Parser.Lex(); // Eat the identifier.
1255 if (Parser.getTok().getKind() != AsmToken::LParen)
1256 return false;
1257
1258 Parser.Lex(); // Eat the LParen token.
1259 const MCExpr *subExpr;
1260 if (Parser.parseParenExpression(subExpr, EndLoc))
1261 return false;
1262
1263 EVal = adjustPICRelocation(VK, subExpr);
1264 return true;
1265 }
1266
LLVMInitializeSparcAsmParser()1267 extern "C" void LLVMInitializeSparcAsmParser() {
1268 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
1269 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
1270 RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
1271 }
1272
1273 #define GET_REGISTER_MATCHER
1274 #define GET_MATCHER_IMPLEMENTATION
1275 #include "SparcGenAsmMatcher.inc"
1276
validateTargetOperandClass(MCParsedAsmOperand & GOp,unsigned Kind)1277 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1278 unsigned Kind) {
1279 SparcOperand &Op = (SparcOperand &)GOp;
1280 if (Op.isFloatOrDoubleReg()) {
1281 switch (Kind) {
1282 default: break;
1283 case MCK_DFPRegs:
1284 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1285 return MCTargetAsmParser::Match_Success;
1286 break;
1287 case MCK_QFPRegs:
1288 if (SparcOperand::MorphToQuadReg(Op))
1289 return MCTargetAsmParser::Match_Success;
1290 break;
1291 }
1292 }
1293 if (Op.isIntReg() && Kind == MCK_IntPair) {
1294 if (SparcOperand::MorphToIntPairReg(Op))
1295 return MCTargetAsmParser::Match_Success;
1296 }
1297 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1298 if (SparcOperand::MorphToCoprocPairReg(Op))
1299 return MCTargetAsmParser::Match_Success;
1300 }
1301 return Match_InvalidOperand;
1302 }
1303