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