1 //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
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
7 //===----------------------------------------------------------------------===//
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/MC/MCAsmMacro.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstBuilder.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCObjectFileInfo.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCAsmParser.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/TargetRegistry.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/SMLoc.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/TargetParser/Triple.h"
44 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
45 // namespace. But SPARC backend uses "SP" as its namespace.
51 } // end namespace Sparc
52 } // end namespace llvm
58 class SparcAsmParser
: public MCTargetAsmParser
{
61 enum class TailRelocKind
{ Load_GOT
, Add_TLS
, Load_TLS
, Call_TLS
};
63 /// @name Auto-generated Match Functions
66 #define GET_ASSEMBLER_HEADER
67 #include "SparcGenAsmMatcher.inc"
71 // public interface of the MCTargetAsmParser.
72 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
73 OperandVector
&Operands
, MCStreamer
&Out
,
75 bool MatchingInlineAsm
) override
;
76 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
77 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
78 SMLoc
&EndLoc
) override
;
79 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
80 SMLoc NameLoc
, OperandVector
&Operands
) override
;
81 ParseStatus
parseDirective(AsmToken DirectiveID
) override
;
83 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
84 unsigned Kind
) override
;
86 // Custom parse functions for Sparc specific operands.
87 ParseStatus
parseMEMOperand(OperandVector
&Operands
);
89 ParseStatus
parseMembarTag(OperandVector
&Operands
);
91 ParseStatus
parseASITag(OperandVector
&Operands
);
93 template <TailRelocKind Kind
>
94 ParseStatus
parseTailRelocSym(OperandVector
&Operands
);
96 template <unsigned N
> ParseStatus
parseShiftAmtImm(OperandVector
&Operands
);
98 ParseStatus
parseCallTarget(OperandVector
&Operands
);
100 ParseStatus
parseOperand(OperandVector
&Operands
, StringRef Name
);
102 ParseStatus
parseSparcAsmOperand(std::unique_ptr
<SparcOperand
> &Operand
,
103 bool isCall
= false);
105 ParseStatus
parseBranchModifiers(OperandVector
&Operands
);
107 // Helper function for dealing with %lo / %hi in PIC mode.
108 const SparcMCExpr
*adjustPICRelocation(SparcMCExpr::VariantKind VK
,
109 const MCExpr
*subExpr
);
111 // returns true if Tok is matched to a register and returns register in RegNo.
112 bool matchRegisterName(const AsmToken
&Tok
, MCRegister
&RegNo
,
115 bool matchSparcAsmModifiers(const MCExpr
*&EVal
, SMLoc
&EndLoc
);
117 bool is64Bit() const {
118 return getSTI().getTargetTriple().getArch() == Triple::sparcv9
;
121 bool expandSET(MCInst
&Inst
, SMLoc IDLoc
,
122 SmallVectorImpl
<MCInst
> &Instructions
);
124 bool expandSETX(MCInst
&Inst
, SMLoc IDLoc
,
125 SmallVectorImpl
<MCInst
> &Instructions
);
127 SMLoc
getLoc() const { return getParser().getTok().getLoc(); }
130 SparcAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
131 const MCInstrInfo
&MII
,
132 const MCTargetOptions
&Options
)
133 : MCTargetAsmParser(Options
, sti
, MII
), Parser(parser
) {
134 Parser
.addAliasForDirective(".half", ".2byte");
135 Parser
.addAliasForDirective(".uahalf", ".2byte");
136 Parser
.addAliasForDirective(".word", ".4byte");
137 Parser
.addAliasForDirective(".uaword", ".4byte");
138 Parser
.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
140 Parser
.addAliasForDirective(".xword", ".8byte");
142 // Initialize the set of available features.
143 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
147 } // end anonymous namespace
149 static const MCPhysReg IntRegs
[32] = {
150 Sparc::G0
, Sparc::G1
, Sparc::G2
, Sparc::G3
,
151 Sparc::G4
, Sparc::G5
, Sparc::G6
, Sparc::G7
,
152 Sparc::O0
, Sparc::O1
, Sparc::O2
, Sparc::O3
,
153 Sparc::O4
, Sparc::O5
, Sparc::O6
, Sparc::O7
,
154 Sparc::L0
, Sparc::L1
, Sparc::L2
, Sparc::L3
,
155 Sparc::L4
, Sparc::L5
, Sparc::L6
, Sparc::L7
,
156 Sparc::I0
, Sparc::I1
, Sparc::I2
, Sparc::I3
,
157 Sparc::I4
, Sparc::I5
, Sparc::I6
, Sparc::I7
};
159 static const MCPhysReg FloatRegs
[32] = {
160 Sparc::F0
, Sparc::F1
, Sparc::F2
, Sparc::F3
,
161 Sparc::F4
, Sparc::F5
, Sparc::F6
, Sparc::F7
,
162 Sparc::F8
, Sparc::F9
, Sparc::F10
, Sparc::F11
,
163 Sparc::F12
, Sparc::F13
, Sparc::F14
, Sparc::F15
,
164 Sparc::F16
, Sparc::F17
, Sparc::F18
, Sparc::F19
,
165 Sparc::F20
, Sparc::F21
, Sparc::F22
, Sparc::F23
,
166 Sparc::F24
, Sparc::F25
, Sparc::F26
, Sparc::F27
,
167 Sparc::F28
, Sparc::F29
, Sparc::F30
, Sparc::F31
};
169 static const MCPhysReg DoubleRegs
[32] = {
170 Sparc::D0
, Sparc::D1
, Sparc::D2
, Sparc::D3
,
171 Sparc::D4
, Sparc::D5
, Sparc::D6
, Sparc::D7
,
172 Sparc::D8
, Sparc::D9
, Sparc::D10
, Sparc::D11
,
173 Sparc::D12
, Sparc::D13
, Sparc::D14
, Sparc::D15
,
174 Sparc::D16
, Sparc::D17
, Sparc::D18
, Sparc::D19
,
175 Sparc::D20
, Sparc::D21
, Sparc::D22
, Sparc::D23
,
176 Sparc::D24
, Sparc::D25
, Sparc::D26
, Sparc::D27
,
177 Sparc::D28
, Sparc::D29
, Sparc::D30
, Sparc::D31
};
179 static const MCPhysReg QuadFPRegs
[32] = {
180 Sparc::Q0
, Sparc::Q1
, Sparc::Q2
, Sparc::Q3
,
181 Sparc::Q4
, Sparc::Q5
, Sparc::Q6
, Sparc::Q7
,
182 Sparc::Q8
, Sparc::Q9
, Sparc::Q10
, Sparc::Q11
,
183 Sparc::Q12
, Sparc::Q13
, Sparc::Q14
, Sparc::Q15
};
185 static const MCPhysReg ASRRegs
[32] = {
186 SP::Y
, SP::ASR1
, SP::ASR2
, SP::ASR3
,
187 SP::ASR4
, SP::ASR5
, SP::ASR6
, SP::ASR7
,
188 SP::ASR8
, SP::ASR9
, SP::ASR10
, SP::ASR11
,
189 SP::ASR12
, SP::ASR13
, SP::ASR14
, SP::ASR15
,
190 SP::ASR16
, SP::ASR17
, SP::ASR18
, SP::ASR19
,
191 SP::ASR20
, SP::ASR21
, SP::ASR22
, SP::ASR23
,
192 SP::ASR24
, SP::ASR25
, SP::ASR26
, SP::ASR27
,
193 SP::ASR28
, SP::ASR29
, SP::ASR30
, SP::ASR31
};
195 static const MCPhysReg IntPairRegs
[] = {
196 Sparc::G0_G1
, Sparc::G2_G3
, Sparc::G4_G5
, Sparc::G6_G7
,
197 Sparc::O0_O1
, Sparc::O2_O3
, Sparc::O4_O5
, Sparc::O6_O7
,
198 Sparc::L0_L1
, Sparc::L2_L3
, Sparc::L4_L5
, Sparc::L6_L7
,
199 Sparc::I0_I1
, Sparc::I2_I3
, Sparc::I4_I5
, Sparc::I6_I7
};
201 static const MCPhysReg CoprocRegs
[32] = {
202 Sparc::C0
, Sparc::C1
, Sparc::C2
, Sparc::C3
,
203 Sparc::C4
, Sparc::C5
, Sparc::C6
, Sparc::C7
,
204 Sparc::C8
, Sparc::C9
, Sparc::C10
, Sparc::C11
,
205 Sparc::C12
, Sparc::C13
, Sparc::C14
, Sparc::C15
,
206 Sparc::C16
, Sparc::C17
, Sparc::C18
, Sparc::C19
,
207 Sparc::C20
, Sparc::C21
, Sparc::C22
, Sparc::C23
,
208 Sparc::C24
, Sparc::C25
, Sparc::C26
, Sparc::C27
,
209 Sparc::C28
, Sparc::C29
, Sparc::C30
, Sparc::C31
};
211 static const MCPhysReg CoprocPairRegs
[] = {
212 Sparc::C0_C1
, Sparc::C2_C3
, Sparc::C4_C5
, Sparc::C6_C7
,
213 Sparc::C8_C9
, Sparc::C10_C11
, Sparc::C12_C13
, Sparc::C14_C15
,
214 Sparc::C16_C17
, Sparc::C18_C19
, Sparc::C20_C21
, Sparc::C22_C23
,
215 Sparc::C24_C25
, Sparc::C26_C27
, Sparc::C28_C29
, Sparc::C30_C31
};
219 /// SparcOperand - Instances of this class represent a parsed Sparc machine
221 class SparcOperand
: public MCParsedAsmOperand
{
245 SMLoc StartLoc
, EndLoc
;
276 SparcOperand(KindTy K
) : Kind(K
) {}
278 bool isToken() const override
{ return Kind
== k_Token
; }
279 bool isReg() const override
{ return Kind
== k_Register
; }
280 bool isImm() const override
{ return Kind
== k_Immediate
; }
281 bool isMem() const override
{ return isMEMrr() || isMEMri(); }
282 bool isMEMrr() const { return Kind
== k_MemoryReg
; }
283 bool isMEMri() const { return Kind
== k_MemoryImm
; }
284 bool isMembarTag() const { return Kind
== k_Immediate
; }
285 bool isASITag() const { return Kind
== k_ASITag
; }
286 bool isTailRelocSym() const { return Kind
== k_Immediate
; }
288 bool isCallTarget() const {
292 if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Imm
.Val
))
293 return CE
->getValue() % 4 == 0;
298 bool isShiftAmtImm5() const {
302 if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Imm
.Val
))
303 return isUInt
<5>(CE
->getValue());
308 bool isShiftAmtImm6() const {
312 if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Imm
.Val
))
313 return isUInt
<6>(CE
->getValue());
318 bool isIntReg() const {
319 return (Kind
== k_Register
&& Reg
.Kind
== rk_IntReg
);
322 bool isFloatReg() const {
323 return (Kind
== k_Register
&& Reg
.Kind
== rk_FloatReg
);
326 bool isFloatOrDoubleReg() const {
327 return (Kind
== k_Register
&& (Reg
.Kind
== rk_FloatReg
328 || Reg
.Kind
== rk_DoubleReg
));
331 bool isCoprocReg() const {
332 return (Kind
== k_Register
&& Reg
.Kind
== rk_CoprocReg
);
335 StringRef
getToken() const {
336 assert(Kind
== k_Token
&& "Invalid access!");
337 return StringRef(Tok
.Data
, Tok
.Length
);
340 unsigned getReg() const override
{
341 assert((Kind
== k_Register
) && "Invalid access!");
345 const MCExpr
*getImm() const {
346 assert((Kind
== k_Immediate
) && "Invalid access!");
350 unsigned getMemBase() const {
351 assert((Kind
== k_MemoryReg
|| Kind
== k_MemoryImm
) && "Invalid access!");
355 unsigned getMemOffsetReg() const {
356 assert((Kind
== k_MemoryReg
) && "Invalid access!");
357 return Mem
.OffsetReg
;
360 const MCExpr
*getMemOff() const {
361 assert((Kind
== k_MemoryImm
) && "Invalid access!");
365 unsigned getASITag() const {
366 assert((Kind
== k_ASITag
) && "Invalid access!");
370 /// getStartLoc - Get the location of the first token of this operand.
371 SMLoc
getStartLoc() const override
{
374 /// getEndLoc - Get the location of the last token of this operand.
375 SMLoc
getEndLoc() const override
{
379 void print(raw_ostream
&OS
) const override
{
381 case k_Token
: OS
<< "Token: " << getToken() << "\n"; break;
382 case k_Register
: OS
<< "Reg: #" << getReg() << "\n"; break;
383 case k_Immediate
: OS
<< "Imm: " << getImm() << "\n"; break;
384 case k_MemoryReg
: OS
<< "Mem: " << getMemBase() << "+"
385 << getMemOffsetReg() << "\n"; break;
386 case k_MemoryImm
: assert(getMemOff() != nullptr);
387 OS
<< "Mem: " << getMemBase()
388 << "+" << *getMemOff()
391 OS
<< "ASI tag: " << getASITag() << "\n";
396 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
397 assert(N
== 1 && "Invalid number of operands!");
398 Inst
.addOperand(MCOperand::createReg(getReg()));
401 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
402 assert(N
== 1 && "Invalid number of operands!");
403 const MCExpr
*Expr
= getImm();
407 void addShiftAmtImm5Operands(MCInst
&Inst
, unsigned N
) const {
408 assert(N
== 1 && "Invalid number of operands!");
409 addExpr(Inst
, getImm());
411 void addShiftAmtImm6Operands(MCInst
&Inst
, unsigned N
) const {
412 assert(N
== 1 && "Invalid number of operands!");
413 addExpr(Inst
, getImm());
416 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const{
417 // Add as immediate when possible. Null MCExpr = 0.
419 Inst
.addOperand(MCOperand::createImm(0));
420 else if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
))
421 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
423 Inst
.addOperand(MCOperand::createExpr(Expr
));
426 void addMEMrrOperands(MCInst
&Inst
, unsigned N
) const {
427 assert(N
== 2 && "Invalid number of operands!");
429 Inst
.addOperand(MCOperand::createReg(getMemBase()));
431 assert(getMemOffsetReg() != 0 && "Invalid offset");
432 Inst
.addOperand(MCOperand::createReg(getMemOffsetReg()));
435 void addMEMriOperands(MCInst
&Inst
, unsigned N
) const {
436 assert(N
== 2 && "Invalid number of operands!");
438 Inst
.addOperand(MCOperand::createReg(getMemBase()));
440 const MCExpr
*Expr
= getMemOff();
444 void addASITagOperands(MCInst
&Inst
, unsigned N
) const {
445 assert(N
== 1 && "Invalid number of operands!");
446 Inst
.addOperand(MCOperand::createImm(getASITag()));
449 void addMembarTagOperands(MCInst
&Inst
, unsigned N
) const {
450 assert(N
== 1 && "Invalid number of operands!");
451 const MCExpr
*Expr
= getImm();
455 void addCallTargetOperands(MCInst
&Inst
, unsigned N
) const {
456 assert(N
== 1 && "Invalid number of operands!");
457 addExpr(Inst
, getImm());
460 void addTailRelocSymOperands(MCInst
&Inst
, unsigned N
) const {
461 assert(N
== 1 && "Invalid number of operands!");
462 addExpr(Inst
, getImm());
465 static std::unique_ptr
<SparcOperand
> CreateToken(StringRef Str
, SMLoc S
) {
466 auto Op
= std::make_unique
<SparcOperand
>(k_Token
);
467 Op
->Tok
.Data
= Str
.data();
468 Op
->Tok
.Length
= Str
.size();
474 static std::unique_ptr
<SparcOperand
> CreateReg(unsigned RegNum
, unsigned Kind
,
476 auto Op
= std::make_unique
<SparcOperand
>(k_Register
);
477 Op
->Reg
.RegNum
= RegNum
;
478 Op
->Reg
.Kind
= (SparcOperand::RegisterKind
)Kind
;
484 static std::unique_ptr
<SparcOperand
> CreateImm(const MCExpr
*Val
, SMLoc S
,
486 auto Op
= std::make_unique
<SparcOperand
>(k_Immediate
);
493 static std::unique_ptr
<SparcOperand
> CreateASITag(unsigned Val
, SMLoc S
,
495 auto Op
= std::make_unique
<SparcOperand
>(k_ASITag
);
502 static bool MorphToIntPairReg(SparcOperand
&Op
) {
503 unsigned Reg
= Op
.getReg();
504 assert(Op
.Reg
.Kind
== rk_IntReg
);
505 unsigned regIdx
= 32;
506 if (Reg
>= Sparc::G0
&& Reg
<= Sparc::G7
)
507 regIdx
= Reg
- Sparc::G0
;
508 else if (Reg
>= Sparc::O0
&& Reg
<= Sparc::O7
)
509 regIdx
= Reg
- Sparc::O0
+ 8;
510 else if (Reg
>= Sparc::L0
&& Reg
<= Sparc::L7
)
511 regIdx
= Reg
- Sparc::L0
+ 16;
512 else if (Reg
>= Sparc::I0
&& Reg
<= Sparc::I7
)
513 regIdx
= Reg
- Sparc::I0
+ 24;
514 if (regIdx
% 2 || regIdx
> 31)
516 Op
.Reg
.RegNum
= IntPairRegs
[regIdx
/ 2];
517 Op
.Reg
.Kind
= rk_IntPairReg
;
521 static bool MorphToDoubleReg(SparcOperand
&Op
) {
522 unsigned Reg
= Op
.getReg();
523 assert(Op
.Reg
.Kind
== rk_FloatReg
);
524 unsigned regIdx
= Reg
- Sparc::F0
;
525 if (regIdx
% 2 || regIdx
> 31)
527 Op
.Reg
.RegNum
= DoubleRegs
[regIdx
/ 2];
528 Op
.Reg
.Kind
= rk_DoubleReg
;
532 static bool MorphToQuadReg(SparcOperand
&Op
) {
533 unsigned Reg
= Op
.getReg();
535 switch (Op
.Reg
.Kind
) {
536 default: llvm_unreachable("Unexpected register kind!");
538 regIdx
= Reg
- Sparc::F0
;
539 if (regIdx
% 4 || regIdx
> 31)
541 Reg
= QuadFPRegs
[regIdx
/ 4];
544 regIdx
= Reg
- Sparc::D0
;
545 if (regIdx
% 2 || regIdx
> 31)
547 Reg
= QuadFPRegs
[regIdx
/ 2];
551 Op
.Reg
.Kind
= rk_QuadReg
;
555 static bool MorphToCoprocPairReg(SparcOperand
&Op
) {
556 unsigned Reg
= Op
.getReg();
557 assert(Op
.Reg
.Kind
== rk_CoprocReg
);
558 unsigned regIdx
= 32;
559 if (Reg
>= Sparc::C0
&& Reg
<= Sparc::C31
)
560 regIdx
= Reg
- Sparc::C0
;
561 if (regIdx
% 2 || regIdx
> 31)
563 Op
.Reg
.RegNum
= CoprocPairRegs
[regIdx
/ 2];
564 Op
.Reg
.Kind
= rk_CoprocPairReg
;
568 static std::unique_ptr
<SparcOperand
>
569 MorphToMEMrr(unsigned Base
, std::unique_ptr
<SparcOperand
> Op
) {
570 unsigned offsetReg
= Op
->getReg();
571 Op
->Kind
= k_MemoryReg
;
573 Op
->Mem
.OffsetReg
= offsetReg
;
574 Op
->Mem
.Off
= nullptr;
578 static std::unique_ptr
<SparcOperand
>
579 CreateMEMr(unsigned Base
, SMLoc S
, SMLoc E
) {
580 auto Op
= std::make_unique
<SparcOperand
>(k_MemoryReg
);
582 Op
->Mem
.OffsetReg
= Sparc::G0
; // always 0
583 Op
->Mem
.Off
= nullptr;
589 static std::unique_ptr
<SparcOperand
>
590 MorphToMEMri(unsigned Base
, std::unique_ptr
<SparcOperand
> Op
) {
591 const MCExpr
*Imm
= Op
->getImm();
592 Op
->Kind
= k_MemoryImm
;
594 Op
->Mem
.OffsetReg
= 0;
600 } // end anonymous namespace
602 bool SparcAsmParser::expandSET(MCInst
&Inst
, SMLoc IDLoc
,
603 SmallVectorImpl
<MCInst
> &Instructions
) {
604 MCOperand MCRegOp
= Inst
.getOperand(0);
605 MCOperand MCValOp
= Inst
.getOperand(1);
606 assert(MCRegOp
.isReg());
607 assert(MCValOp
.isImm() || MCValOp
.isExpr());
609 // the imm operand can be either an expression or an immediate.
610 bool IsImm
= Inst
.getOperand(1).isImm();
611 int64_t RawImmValue
= IsImm
? MCValOp
.getImm() : 0;
613 // Allow either a signed or unsigned 32-bit immediate.
614 if (RawImmValue
< -2147483648LL || RawImmValue
> 4294967295LL) {
616 "set: argument must be between -2147483648 and 4294967295");
619 // If the value was expressed as a large unsigned number, that's ok.
620 // We want to see if it "looks like" a small signed number.
621 int32_t ImmValue
= RawImmValue
;
622 // For 'set' you can't use 'or' with a negative operand on V9 because
623 // that would splat the sign bit across the upper half of the destination
624 // register, whereas 'set' is defined to zero the high 32 bits.
625 bool IsEffectivelyImm13
=
626 IsImm
&& ((is64Bit() ? 0 : -4096) <= ImmValue
&& ImmValue
< 4096);
627 const MCExpr
*ValExpr
;
629 ValExpr
= MCConstantExpr::create(ImmValue
, getContext());
631 ValExpr
= MCValOp
.getExpr();
633 MCOperand PrevReg
= MCOperand::createReg(Sparc::G0
);
635 // If not just a signed imm13 value, then either we use a 'sethi' with a
636 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
637 // In either case, start with the 'sethi'.
638 if (!IsEffectivelyImm13
) {
640 const MCExpr
*Expr
= adjustPICRelocation(SparcMCExpr::VK_Sparc_HI
, ValExpr
);
641 TmpInst
.setLoc(IDLoc
);
642 TmpInst
.setOpcode(SP::SETHIi
);
643 TmpInst
.addOperand(MCRegOp
);
644 TmpInst
.addOperand(MCOperand::createExpr(Expr
));
645 Instructions
.push_back(TmpInst
);
649 // The low bits require touching in 3 cases:
650 // * A non-immediate value will always require both instructions.
651 // * An effectively imm13 value needs only an 'or' instruction.
652 // * Otherwise, an immediate that is not effectively imm13 requires the
653 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
654 // If the low bits are known zeros, there's nothing to do.
655 // In the second case, and only in that case, must we NOT clear
656 // bits of the immediate value via the %lo() assembler function.
657 // Note also, the 'or' instruction doesn't mind a large value in the case
658 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
659 if (!IsImm
|| IsEffectivelyImm13
|| (ImmValue
& 0x3ff)) {
662 if (IsEffectivelyImm13
)
665 Expr
= adjustPICRelocation(SparcMCExpr::VK_Sparc_LO
, ValExpr
);
666 TmpInst
.setLoc(IDLoc
);
667 TmpInst
.setOpcode(SP::ORri
);
668 TmpInst
.addOperand(MCRegOp
);
669 TmpInst
.addOperand(PrevReg
);
670 TmpInst
.addOperand(MCOperand::createExpr(Expr
));
671 Instructions
.push_back(TmpInst
);
676 bool SparcAsmParser::expandSETX(MCInst
&Inst
, SMLoc IDLoc
,
677 SmallVectorImpl
<MCInst
> &Instructions
) {
678 MCOperand MCRegOp
= Inst
.getOperand(0);
679 MCOperand MCValOp
= Inst
.getOperand(1);
680 MCOperand MCTmpOp
= Inst
.getOperand(2);
681 assert(MCRegOp
.isReg() && MCTmpOp
.isReg());
682 assert(MCValOp
.isImm() || MCValOp
.isExpr());
684 // the imm operand can be either an expression or an immediate.
685 bool IsImm
= MCValOp
.isImm();
686 int64_t ImmValue
= IsImm
? MCValOp
.getImm() : 0;
688 const MCExpr
*ValExpr
= IsImm
? MCConstantExpr::create(ImmValue
, getContext())
691 // Very small immediates can be expressed directly as a single `or`.
692 if (IsImm
&& isInt
<13>(ImmValue
)) {
694 Instructions
.push_back(MCInstBuilder(SP::ORri
)
695 .addReg(MCRegOp
.getReg())
701 // Otherwise, first we set the lower half of the register.
703 // sethi %hi(val), rd
704 Instructions
.push_back(
705 MCInstBuilder(SP::SETHIi
)
706 .addReg(MCRegOp
.getReg())
707 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI
, ValExpr
)));
708 // or rd, %lo(val), rd
709 Instructions
.push_back(
710 MCInstBuilder(SP::ORri
)
711 .addReg(MCRegOp
.getReg())
712 .addReg(MCRegOp
.getReg())
713 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_LO
, ValExpr
)));
715 // Small positive immediates can be expressed as a single `sethi`+`or`
716 // combination, so we can just return here.
717 if (IsImm
&& isUInt
<32>(ImmValue
))
720 // For bigger immediates, we need to generate the upper half, then shift and
721 // merge it with the lower half that has just been generated above.
723 // sethi %hh(val), tmp
724 Instructions
.push_back(
725 MCInstBuilder(SP::SETHIi
)
726 .addReg(MCTmpOp
.getReg())
727 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HH
, ValExpr
)));
728 // or tmp, %hm(val), tmp
729 Instructions
.push_back(
730 MCInstBuilder(SP::ORri
)
731 .addReg(MCTmpOp
.getReg())
732 .addReg(MCTmpOp
.getReg())
733 .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HM
, ValExpr
)));
735 Instructions
.push_back(MCInstBuilder(SP::SLLXri
)
736 .addReg(MCTmpOp
.getReg())
737 .addReg(MCTmpOp
.getReg())
740 Instructions
.push_back(MCInstBuilder(SP::ORrr
)
741 .addReg(MCRegOp
.getReg())
742 .addReg(MCTmpOp
.getReg())
743 .addReg(MCRegOp
.getReg()));
748 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
749 OperandVector
&Operands
,
752 bool MatchingInlineAsm
) {
754 SmallVector
<MCInst
, 8> Instructions
;
755 unsigned MatchResult
= MatchInstructionImpl(Operands
, Inst
, ErrorInfo
,
757 switch (MatchResult
) {
758 case Match_Success
: {
759 switch (Inst
.getOpcode()) {
762 Instructions
.push_back(Inst
);
765 if (expandSET(Inst
, IDLoc
, Instructions
))
769 if (expandSETX(Inst
, IDLoc
, Instructions
))
774 for (const MCInst
&I
: Instructions
) {
775 Out
.emitInstruction(I
, getSTI());
780 case Match_MissingFeature
:
782 "instruction requires a CPU feature not currently enabled");
784 case Match_InvalidOperand
: {
785 SMLoc ErrorLoc
= IDLoc
;
786 if (ErrorInfo
!= ~0ULL) {
787 if (ErrorInfo
>= Operands
.size())
788 return Error(IDLoc
, "too few operands for instruction");
790 ErrorLoc
= ((SparcOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
791 if (ErrorLoc
== SMLoc())
795 return Error(ErrorLoc
, "invalid operand for instruction");
797 case Match_MnemonicFail
:
798 return Error(IDLoc
, "invalid instruction mnemonic");
800 llvm_unreachable("Implement any new match types added!");
803 bool SparcAsmParser::parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
805 if (!tryParseRegister(Reg
, StartLoc
, EndLoc
).isSuccess())
806 return Error(StartLoc
, "invalid register name");
810 ParseStatus
SparcAsmParser::tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
812 const AsmToken
&Tok
= Parser
.getTok();
813 StartLoc
= Tok
.getLoc();
814 EndLoc
= Tok
.getEndLoc();
815 Reg
= Sparc::NoRegister
;
816 if (getLexer().getKind() != AsmToken::Percent
)
817 return ParseStatus::NoMatch
;
819 unsigned regKind
= SparcOperand::rk_None
;
820 if (matchRegisterName(Tok
, Reg
, regKind
)) {
822 return ParseStatus::Success
;
825 getLexer().UnLex(Tok
);
826 return ParseStatus::NoMatch
;
829 static void applyMnemonicAliases(StringRef
&Mnemonic
,
830 const FeatureBitset
&Features
,
833 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo
&Info
,
834 StringRef Name
, SMLoc NameLoc
,
835 OperandVector
&Operands
) {
837 // First operand in MCInst is instruction mnemonic.
838 Operands
.push_back(SparcOperand::CreateToken(Name
, NameLoc
));
840 // apply mnemonic aliases, if any, so that we can parse operands correctly.
841 applyMnemonicAliases(Name
, getAvailableFeatures(), 0);
843 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
844 // Read the first operand.
845 if (getLexer().is(AsmToken::Comma
)) {
846 if (!parseBranchModifiers(Operands
).isSuccess()) {
847 SMLoc Loc
= getLexer().getLoc();
848 return Error(Loc
, "unexpected token");
851 if (!parseOperand(Operands
, Name
).isSuccess()) {
852 SMLoc Loc
= getLexer().getLoc();
853 return Error(Loc
, "unexpected token");
856 while (getLexer().is(AsmToken::Comma
) || getLexer().is(AsmToken::Plus
)) {
857 if (getLexer().is(AsmToken::Plus
)) {
858 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
859 Operands
.push_back(SparcOperand::CreateToken("+", Parser
.getTok().getLoc()));
861 Parser
.Lex(); // Eat the comma or plus.
862 // Parse and remember the operand.
863 if (!parseOperand(Operands
, Name
).isSuccess()) {
864 SMLoc Loc
= getLexer().getLoc();
865 return Error(Loc
, "unexpected token");
869 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
870 SMLoc Loc
= getLexer().getLoc();
871 return Error(Loc
, "unexpected token");
873 Parser
.Lex(); // Consume the EndOfStatement.
877 ParseStatus
SparcAsmParser::parseDirective(AsmToken DirectiveID
) {
878 StringRef IDVal
= DirectiveID
.getString();
880 if (IDVal
== ".register") {
881 // For now, ignore .register directive.
882 Parser
.eatToEndOfStatement();
883 return ParseStatus::Success
;
885 if (IDVal
== ".proc") {
886 // For compatibility, ignore this directive.
887 // (It's supposed to be an "optimization" in the Sun assembler)
888 Parser
.eatToEndOfStatement();
889 return ParseStatus::Success
;
892 // Let the MC layer to handle other directives.
893 return ParseStatus::NoMatch
;
896 ParseStatus
SparcAsmParser::parseMEMOperand(OperandVector
&Operands
) {
899 std::unique_ptr
<SparcOperand
> LHS
;
900 if (!parseSparcAsmOperand(LHS
).isSuccess())
901 return ParseStatus::NoMatch
;
903 // Single immediate operand
905 Operands
.push_back(SparcOperand::MorphToMEMri(Sparc::G0
, std::move(LHS
)));
906 return ParseStatus::Success
;
909 if (!LHS
->isIntReg())
910 return Error(LHS
->getStartLoc(), "invalid register kind for this operand");
912 AsmToken Tok
= getLexer().getTok();
913 // The plus token may be followed by a register or an immediate value, the
914 // minus one is always interpreted as sign for the immediate value
915 if (Tok
.is(AsmToken::Plus
) || Tok
.is(AsmToken::Minus
)) {
916 (void)Parser
.parseOptionalToken(AsmToken::Plus
);
918 std::unique_ptr
<SparcOperand
> RHS
;
919 if (!parseSparcAsmOperand(RHS
).isSuccess())
920 return ParseStatus::NoMatch
;
922 if (RHS
->isReg() && !RHS
->isIntReg())
923 return Error(RHS
->getStartLoc(),
924 "invalid register kind for this operand");
928 ? SparcOperand::MorphToMEMri(LHS
->getReg(), std::move(RHS
))
929 : SparcOperand::MorphToMEMrr(LHS
->getReg(), std::move(RHS
)));
931 return ParseStatus::Success
;
934 Operands
.push_back(SparcOperand::CreateMEMr(LHS
->getReg(), S
, E
));
935 return ParseStatus::Success
;
938 template <unsigned N
>
939 ParseStatus
SparcAsmParser::parseShiftAmtImm(OperandVector
&Operands
) {
940 SMLoc S
= Parser
.getTok().getLoc();
941 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
943 // This is a register, not an immediate
944 if (getLexer().getKind() == AsmToken::Percent
)
945 return ParseStatus::NoMatch
;
948 if (getParser().parseExpression(Expr
))
949 return ParseStatus::Failure
;
951 const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
);
953 return Error(S
, "constant expression expected");
955 if (!isUInt
<N
>(CE
->getValue()))
956 return Error(S
, "immediate shift value out of range");
958 Operands
.push_back(SparcOperand::CreateImm(Expr
, S
, E
));
959 return ParseStatus::Success
;
962 template <SparcAsmParser::TailRelocKind Kind
>
963 ParseStatus
SparcAsmParser::parseTailRelocSym(OperandVector
&Operands
) {
965 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
967 auto MatchesKind
= [](SparcMCExpr::VariantKind VK
) -> bool {
969 case TailRelocKind::Load_GOT
:
970 // Non-TLS relocations on ld (or ldx).
971 // ld [%rr + %rr], %rr, %rel(sym)
972 return VK
== SparcMCExpr::VK_Sparc_GOTDATA_OP
;
973 case TailRelocKind::Add_TLS
:
974 // TLS relocations on add.
975 // add %rr, %rr, %rr, %rel(sym)
977 case SparcMCExpr::VK_Sparc_TLS_GD_ADD
:
978 case SparcMCExpr::VK_Sparc_TLS_IE_ADD
:
979 case SparcMCExpr::VK_Sparc_TLS_LDM_ADD
:
980 case SparcMCExpr::VK_Sparc_TLS_LDO_ADD
:
985 case TailRelocKind::Load_TLS
:
986 // TLS relocations on ld (or ldx).
987 // ld[x] %addr, %rr, %rel(sym)
989 case SparcMCExpr::VK_Sparc_TLS_IE_LD
:
990 case SparcMCExpr::VK_Sparc_TLS_IE_LDX
:
995 case TailRelocKind::Call_TLS
:
996 // TLS relocations on call.
997 // call sym, %rel(sym)
999 case SparcMCExpr::VK_Sparc_TLS_GD_CALL
:
1000 case SparcMCExpr::VK_Sparc_TLS_LDM_CALL
:
1006 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
1009 if (getLexer().getKind() != AsmToken::Percent
)
1010 return Error(getLoc(), "expected '%' for operand modifier");
1012 const AsmToken Tok
= Parser
.getTok();
1013 getParser().Lex(); // Eat '%'
1015 if (getLexer().getKind() != AsmToken::Identifier
)
1016 return Error(getLoc(), "expected valid identifier for operand modifier");
1018 StringRef Name
= getParser().getTok().getIdentifier();
1019 SparcMCExpr::VariantKind VK
= SparcMCExpr::parseVariantKind(Name
);
1020 if (VK
== SparcMCExpr::VK_Sparc_None
)
1021 return Error(getLoc(), "invalid operand modifier");
1023 if (!MatchesKind(VK
)) {
1024 // Did not match the specified set of relocation types, put '%' back.
1025 getLexer().UnLex(Tok
);
1026 return ParseStatus::NoMatch
;
1029 Parser
.Lex(); // Eat the identifier.
1030 if (getLexer().getKind() != AsmToken::LParen
)
1031 return Error(getLoc(), "expected '('");
1033 getParser().Lex(); // Eat '('
1034 const MCExpr
*SubExpr
;
1035 if (getParser().parseParenExpression(SubExpr
, E
))
1036 return ParseStatus::Failure
;
1038 const MCExpr
*Val
= adjustPICRelocation(VK
, SubExpr
);
1039 Operands
.push_back(SparcOperand::CreateImm(Val
, S
, E
));
1040 return ParseStatus::Success
;
1043 ParseStatus
SparcAsmParser::parseMembarTag(OperandVector
&Operands
) {
1044 SMLoc S
= Parser
.getTok().getLoc();
1048 std::unique_ptr
<SparcOperand
> Mask
;
1049 if (parseSparcAsmOperand(Mask
).isSuccess()) {
1050 if (!Mask
->isImm() || !Mask
->getImm()->evaluateAsAbsolute(ImmVal
) ||
1051 ImmVal
< 0 || ImmVal
> 127)
1052 return Error(S
, "invalid membar mask number");
1055 while (getLexer().getKind() == AsmToken::Hash
) {
1056 SMLoc TagStart
= getLexer().getLoc();
1057 Parser
.Lex(); // Eat the '#'.
1058 unsigned MaskVal
= StringSwitch
<unsigned>(Parser
.getTok().getString())
1059 .Case("LoadLoad", 0x1)
1060 .Case("StoreLoad", 0x2)
1061 .Case("LoadStore", 0x4)
1062 .Case("StoreStore", 0x8)
1063 .Case("Lookaside", 0x10)
1064 .Case("MemIssue", 0x20)
1068 Parser
.Lex(); // Eat the identifier token.
1071 return Error(TagStart
, "unknown membar tag");
1075 if (getLexer().getKind() == AsmToken::Pipe
)
1076 Parser
.Lex(); // Eat the '|'.
1079 EVal
= MCConstantExpr::create(ImmVal
, getContext());
1080 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1081 Operands
.push_back(SparcOperand::CreateImm(EVal
, S
, E
));
1082 return ParseStatus::Success
;
1085 ParseStatus
SparcAsmParser::parseASITag(OperandVector
&Operands
) {
1086 SMLoc S
= Parser
.getTok().getLoc();
1087 SMLoc E
= Parser
.getTok().getEndLoc();
1090 if (is64Bit() && (getLexer().getKind() == AsmToken::Hash
)) {
1091 // For now we only support named tags for 64-bit/V9 systems.
1092 // TODO: add support for 32-bit/V8 systems.
1093 SMLoc TagStart
= getLexer().peekTok(false).getLoc();
1094 Parser
.Lex(); // Eat the '#'.
1095 auto ASIName
= Parser
.getTok().getString();
1096 auto ASITag
= SparcASITag::lookupASITagByName(ASIName
);
1098 ASITag
= SparcASITag::lookupASITagByAltName(ASIName
);
1099 Parser
.Lex(); // Eat the identifier token.
1102 return Error(TagStart
, "unknown ASI tag");
1104 ASIVal
= ASITag
->Encoding
;
1105 } else if (!getParser().parseAbsoluteExpression(ASIVal
)) {
1106 if (!isUInt
<8>(ASIVal
))
1107 return Error(S
, "invalid ASI number, must be between 0 and 255");
1111 ? "malformed ASI tag, must be %asi, a constant integer "
1112 "expression, or a named tag"
1113 : "malformed ASI tag, must be a constant integer expression");
1116 Operands
.push_back(SparcOperand::CreateASITag(ASIVal
, S
, E
));
1117 return ParseStatus::Success
;
1120 ParseStatus
SparcAsmParser::parseCallTarget(OperandVector
&Operands
) {
1121 SMLoc S
= Parser
.getTok().getLoc();
1122 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1124 switch (getLexer().getKind()) {
1126 return ParseStatus::NoMatch
;
1127 case AsmToken::LParen
:
1128 case AsmToken::Integer
:
1129 case AsmToken::Identifier
:
1134 const MCExpr
*DestValue
;
1135 if (getParser().parseExpression(DestValue
))
1136 return ParseStatus::NoMatch
;
1138 bool IsPic
= getContext().getObjectFileInfo()->isPositionIndependent();
1139 SparcMCExpr::VariantKind Kind
=
1140 IsPic
? SparcMCExpr::VK_Sparc_WPLT30
: SparcMCExpr::VK_Sparc_WDISP30
;
1142 const MCExpr
*DestExpr
= SparcMCExpr::create(Kind
, DestValue
, getContext());
1143 Operands
.push_back(SparcOperand::CreateImm(DestExpr
, S
, E
));
1144 return ParseStatus::Success
;
1147 ParseStatus
SparcAsmParser::parseOperand(OperandVector
&Operands
,
1148 StringRef Mnemonic
) {
1150 ParseStatus Res
= MatchOperandParserImpl(Operands
, Mnemonic
);
1152 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1153 // there was a match, but an error occurred, in which case, just return that
1154 // the operand parsing failed.
1155 if (Res
.isSuccess() || Res
.isFailure())
1158 if (getLexer().is(AsmToken::LBrac
)) {
1160 Operands
.push_back(SparcOperand::CreateToken("[",
1161 Parser
.getTok().getLoc()));
1162 Parser
.Lex(); // Eat the [
1164 if (Mnemonic
== "cas" || Mnemonic
== "casl" || Mnemonic
== "casa" ||
1165 Mnemonic
== "casx" || Mnemonic
== "casxl" || Mnemonic
== "casxa") {
1166 SMLoc S
= Parser
.getTok().getLoc();
1167 if (getLexer().getKind() != AsmToken::Percent
)
1168 return ParseStatus::NoMatch
;
1169 Parser
.Lex(); // eat %
1173 if (!matchRegisterName(Parser
.getTok(), RegNo
, RegKind
))
1174 return ParseStatus::NoMatch
;
1176 Parser
.Lex(); // Eat the identifier token.
1177 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer()-1);
1178 Operands
.push_back(SparcOperand::CreateReg(RegNo
, RegKind
, S
, E
));
1179 Res
= ParseStatus::Success
;
1181 Res
= parseMEMOperand(Operands
);
1184 if (!Res
.isSuccess())
1187 if (!getLexer().is(AsmToken::RBrac
))
1188 return ParseStatus::Failure
;
1190 Operands
.push_back(SparcOperand::CreateToken("]",
1191 Parser
.getTok().getLoc()));
1192 Parser
.Lex(); // Eat the ]
1194 // Parse an optional address-space identifier after the address.
1195 // This will be either an immediate constant expression, or, on 64-bit
1196 // processors, the %asi register.
1197 if (is64Bit() && getLexer().is(AsmToken::Percent
)) {
1198 SMLoc S
= Parser
.getTok().getLoc();
1199 Parser
.Lex(); // Eat the %.
1200 const AsmToken Tok
= Parser
.getTok();
1201 if (Tok
.is(AsmToken::Identifier
) && Tok
.getString() == "asi") {
1202 // Here we patch the MEM operand from [base + %g0] into [base + 0]
1203 // as memory operations with ASI tag stored in %asi register needs
1204 // to use immediate offset. We need to do this because Reg addressing
1205 // will be parsed as Reg+G0 initially.
1206 // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.
1207 SparcOperand
&OldMemOp
= (SparcOperand
&)*Operands
[Operands
.size() - 2];
1208 if (OldMemOp
.isMEMrr()) {
1209 if (OldMemOp
.getMemOffsetReg() != Sparc::G0
) {
1210 return Error(S
, "invalid operand for instruction");
1212 Operands
[Operands
.size() - 2] = SparcOperand::MorphToMEMri(
1213 OldMemOp
.getMemBase(),
1214 SparcOperand::CreateImm(MCConstantExpr::create(0, getContext()),
1215 OldMemOp
.getStartLoc(),
1216 OldMemOp
.getEndLoc()));
1218 Parser
.Lex(); // Eat the identifier.
1219 // In this context, we convert the register operand into
1220 // a plain "%asi" token since the register access is already
1221 // implicit in the instruction definition and encoding.
1222 // See LoadASI/StoreASI in SparcInstrInfo.td.
1223 Operands
.push_back(SparcOperand::CreateToken("%asi", S
));
1224 return ParseStatus::Success
;
1227 return Error(S
, "malformed ASI tag, must be %asi, a constant integer "
1228 "expression, or a named tag");
1231 // If we're not at the end of statement and the next token is not a comma,
1232 // then it is an immediate ASI value.
1233 if (getLexer().isNot(AsmToken::EndOfStatement
) &&
1234 getLexer().isNot(AsmToken::Comma
))
1235 return parseASITag(Operands
);
1236 return ParseStatus::Success
;
1239 std::unique_ptr
<SparcOperand
> Op
;
1241 Res
= parseSparcAsmOperand(Op
, (Mnemonic
== "call"));
1242 if (!Res
.isSuccess() || !Op
)
1243 return ParseStatus::Failure
;
1245 // Push the parsed operand into the list of operands
1246 Operands
.push_back(std::move(Op
));
1248 return ParseStatus::Success
;
1252 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr
<SparcOperand
> &Op
,
1254 SMLoc S
= Parser
.getTok().getLoc();
1255 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1259 switch (getLexer().getKind()) {
1262 case AsmToken::Percent
: {
1263 Parser
.Lex(); // Eat the '%'.
1266 if (matchRegisterName(Parser
.getTok(), Reg
, RegKind
)) {
1267 StringRef Name
= Parser
.getTok().getString();
1268 Parser
.Lex(); // Eat the identifier token.
1269 E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1270 if (Reg
== Sparc::ICC
&& Name
== "xcc")
1271 Op
= SparcOperand::CreateToken("%xcc", S
);
1273 Op
= SparcOperand::CreateReg(Reg
, RegKind
, S
, E
);
1276 if (matchSparcAsmModifiers(EVal
, E
)) {
1277 E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
1278 Op
= SparcOperand::CreateImm(EVal
, S
, E
);
1283 case AsmToken::Plus
:
1284 case AsmToken::Minus
:
1285 case AsmToken::Integer
:
1286 case AsmToken::LParen
:
1288 case AsmToken::Identifier
:
1289 if (getParser().parseExpression(EVal
, E
))
1293 if (!EVal
->evaluateAsAbsolute(Res
)) {
1294 SparcMCExpr::VariantKind Kind
= SparcMCExpr::VK_Sparc_13
;
1296 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1298 Kind
= SparcMCExpr::VK_Sparc_WPLT30
;
1300 Kind
= SparcMCExpr::VK_Sparc_GOT13
;
1302 EVal
= SparcMCExpr::create(Kind
, EVal
, getContext());
1304 Op
= SparcOperand::CreateImm(EVal
, S
, E
);
1307 return Op
? ParseStatus::Success
: ParseStatus::Failure
;
1310 ParseStatus
SparcAsmParser::parseBranchModifiers(OperandVector
&Operands
) {
1311 // parse (,a|,pn|,pt)+
1313 while (getLexer().is(AsmToken::Comma
)) {
1314 Parser
.Lex(); // Eat the comma
1316 if (!getLexer().is(AsmToken::Identifier
))
1317 return ParseStatus::Failure
;
1318 StringRef modName
= Parser
.getTok().getString();
1319 if (modName
== "a" || modName
== "pn" || modName
== "pt") {
1320 Operands
.push_back(SparcOperand::CreateToken(modName
,
1321 Parser
.getTok().getLoc()));
1322 Parser
.Lex(); // eat the identifier.
1325 return ParseStatus::Success
;
1328 bool SparcAsmParser::matchRegisterName(const AsmToken
&Tok
, MCRegister
&RegNo
,
1329 unsigned &RegKind
) {
1332 RegKind
= SparcOperand::rk_None
;
1333 if (Tok
.is(AsmToken::Identifier
)) {
1334 StringRef name
= Tok
.getString();
1337 if (name
.equals("fp")) {
1339 RegKind
= SparcOperand::rk_IntReg
;
1343 if (name
.equals("sp")) {
1345 RegKind
= SparcOperand::rk_IntReg
;
1349 if (name
.equals("y")) {
1351 RegKind
= SparcOperand::rk_Special
;
1355 if (name
.substr(0, 3).equals_insensitive("asr") &&
1356 !name
.substr(3).getAsInteger(10, intVal
) && intVal
> 0 && intVal
< 32) {
1357 RegNo
= ASRRegs
[intVal
];
1358 RegKind
= SparcOperand::rk_Special
;
1362 if (name
.equals("fprs")) {
1363 RegNo
= Sparc::ASR6
;
1364 RegKind
= SparcOperand::rk_Special
;
1368 if (name
.equals("icc")) {
1370 RegKind
= SparcOperand::rk_Special
;
1374 if (name
.equals("psr")) {
1376 RegKind
= SparcOperand::rk_Special
;
1380 if (name
.equals("fsr")) {
1382 RegKind
= SparcOperand::rk_Special
;
1386 if (name
.equals("fq")) {
1388 RegKind
= SparcOperand::rk_Special
;
1392 if (name
.equals("csr")) {
1393 RegNo
= Sparc::CPSR
;
1394 RegKind
= SparcOperand::rk_Special
;
1398 if (name
.equals("cq")) {
1400 RegKind
= SparcOperand::rk_Special
;
1404 if (name
.equals("wim")) {
1406 RegKind
= SparcOperand::rk_Special
;
1410 if (name
.equals("tbr")) {
1412 RegKind
= SparcOperand::rk_Special
;
1416 if (name
.equals("xcc")) {
1417 // FIXME:: check 64bit.
1419 RegKind
= SparcOperand::rk_Special
;
1424 if (name
.substr(0, 3).equals_insensitive("fcc") &&
1425 !name
.substr(3).getAsInteger(10, intVal
) && intVal
< 4) {
1426 // FIXME: check 64bit and handle %fcc1 - %fcc3
1427 RegNo
= Sparc::FCC0
+ intVal
;
1428 RegKind
= SparcOperand::rk_Special
;
1433 if (name
.substr(0, 1).equals_insensitive("g") &&
1434 !name
.substr(1).getAsInteger(10, intVal
) && intVal
< 8) {
1435 RegNo
= IntRegs
[intVal
];
1436 RegKind
= SparcOperand::rk_IntReg
;
1440 if (name
.substr(0, 1).equals_insensitive("o") &&
1441 !name
.substr(1).getAsInteger(10, intVal
) && intVal
< 8) {
1442 RegNo
= IntRegs
[8 + intVal
];
1443 RegKind
= SparcOperand::rk_IntReg
;
1446 if (name
.substr(0, 1).equals_insensitive("l") &&
1447 !name
.substr(1).getAsInteger(10, intVal
) && intVal
< 8) {
1448 RegNo
= IntRegs
[16 + intVal
];
1449 RegKind
= SparcOperand::rk_IntReg
;
1452 if (name
.substr(0, 1).equals_insensitive("i") &&
1453 !name
.substr(1).getAsInteger(10, intVal
) && intVal
< 8) {
1454 RegNo
= IntRegs
[24 + intVal
];
1455 RegKind
= SparcOperand::rk_IntReg
;
1459 if (name
.substr(0, 1).equals_insensitive("f") &&
1460 !name
.substr(1, 2).getAsInteger(10, intVal
) && intVal
< 32) {
1461 RegNo
= FloatRegs
[intVal
];
1462 RegKind
= SparcOperand::rk_FloatReg
;
1466 if (name
.substr(0, 1).equals_insensitive("f") &&
1467 !name
.substr(1, 2).getAsInteger(10, intVal
) && intVal
>= 32 &&
1468 intVal
<= 62 && (intVal
% 2 == 0)) {
1470 RegNo
= DoubleRegs
[intVal
/2];
1471 RegKind
= SparcOperand::rk_DoubleReg
;
1476 if (name
.substr(0, 1).equals_insensitive("r") &&
1477 !name
.substr(1, 2).getAsInteger(10, intVal
) && intVal
< 31) {
1478 RegNo
= IntRegs
[intVal
];
1479 RegKind
= SparcOperand::rk_IntReg
;
1484 if (name
.substr(0, 1).equals_insensitive("c") &&
1485 !name
.substr(1).getAsInteger(10, intVal
) && intVal
< 32) {
1486 RegNo
= CoprocRegs
[intVal
];
1487 RegKind
= SparcOperand::rk_CoprocReg
;
1491 if (name
.equals("tpc")) {
1493 RegKind
= SparcOperand::rk_Special
;
1496 if (name
.equals("tnpc")) {
1497 RegNo
= Sparc::TNPC
;
1498 RegKind
= SparcOperand::rk_Special
;
1501 if (name
.equals("tstate")) {
1502 RegNo
= Sparc::TSTATE
;
1503 RegKind
= SparcOperand::rk_Special
;
1506 if (name
.equals("tt")) {
1508 RegKind
= SparcOperand::rk_Special
;
1511 if (name
.equals("tick")) {
1512 RegNo
= Sparc::TICK
;
1513 RegKind
= SparcOperand::rk_Special
;
1516 if (name
.equals("tba")) {
1518 RegKind
= SparcOperand::rk_Special
;
1521 if (name
.equals("pstate")) {
1522 RegNo
= Sparc::PSTATE
;
1523 RegKind
= SparcOperand::rk_Special
;
1526 if (name
.equals("tl")) {
1528 RegKind
= SparcOperand::rk_Special
;
1531 if (name
.equals("pil")) {
1533 RegKind
= SparcOperand::rk_Special
;
1536 if (name
.equals("cwp")) {
1538 RegKind
= SparcOperand::rk_Special
;
1541 if (name
.equals("cansave")) {
1542 RegNo
= Sparc::CANSAVE
;
1543 RegKind
= SparcOperand::rk_Special
;
1546 if (name
.equals("canrestore")) {
1547 RegNo
= Sparc::CANRESTORE
;
1548 RegKind
= SparcOperand::rk_Special
;
1551 if (name
.equals("cleanwin")) {
1552 RegNo
= Sparc::CLEANWIN
;
1553 RegKind
= SparcOperand::rk_Special
;
1556 if (name
.equals("otherwin")) {
1557 RegNo
= Sparc::OTHERWIN
;
1558 RegKind
= SparcOperand::rk_Special
;
1561 if (name
.equals("wstate")) {
1562 RegNo
= Sparc::WSTATE
;
1563 RegKind
= SparcOperand::rk_Special
;
1566 if (name
.equals("pc")) {
1567 RegNo
= Sparc::ASR5
;
1568 RegKind
= SparcOperand::rk_Special
;
1571 if (name
.equals("asi")) {
1572 RegNo
= Sparc::ASR3
;
1573 RegKind
= SparcOperand::rk_Special
;
1576 if (name
.equals("ccr")) {
1577 RegNo
= Sparc::ASR2
;
1578 RegKind
= SparcOperand::rk_Special
;
1581 if (name
.equals("gl")) {
1583 RegKind
= SparcOperand::rk_Special
;
1586 if (name
.equals("ver")) {
1588 RegKind
= SparcOperand::rk_Special
;
1592 // JPS1 extension - aliases for ASRs
1593 // Section A.51 - Read State Register
1594 if (name
.equals("pcr")) {
1595 RegNo
= Sparc::ASR16
;
1596 RegKind
= SparcOperand::rk_Special
;
1599 if (name
.equals("pic")) {
1600 RegNo
= Sparc::ASR17
;
1601 RegKind
= SparcOperand::rk_Special
;
1604 if (name
.equals("dcr")) {
1605 RegNo
= Sparc::ASR18
;
1606 RegKind
= SparcOperand::rk_Special
;
1609 if (name
.equals("gsr")) {
1610 RegNo
= Sparc::ASR19
;
1611 RegKind
= SparcOperand::rk_Special
;
1614 if (name
.equals("softint")) {
1615 RegNo
= Sparc::ASR22
;
1616 RegKind
= SparcOperand::rk_Special
;
1619 if (name
.equals("tick_cmpr")) {
1620 RegNo
= Sparc::ASR23
;
1621 RegKind
= SparcOperand::rk_Special
;
1624 if (name
.equals("stick") || name
.equals("sys_tick")) {
1625 RegNo
= Sparc::ASR24
;
1626 RegKind
= SparcOperand::rk_Special
;
1629 if (name
.equals("stick_cmpr") || name
.equals("sys_tick_cmpr")) {
1630 RegNo
= Sparc::ASR25
;
1631 RegKind
= SparcOperand::rk_Special
;
1638 // Determine if an expression contains a reference to the symbol
1639 // "_GLOBAL_OFFSET_TABLE_".
1640 static bool hasGOTReference(const MCExpr
*Expr
) {
1641 switch (Expr
->getKind()) {
1642 case MCExpr::Target
:
1643 if (const SparcMCExpr
*SE
= dyn_cast
<SparcMCExpr
>(Expr
))
1644 return hasGOTReference(SE
->getSubExpr());
1647 case MCExpr::Constant
:
1650 case MCExpr::Binary
: {
1651 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
1652 return hasGOTReference(BE
->getLHS()) || hasGOTReference(BE
->getRHS());
1655 case MCExpr::SymbolRef
: {
1656 const MCSymbolRefExpr
&SymRef
= *cast
<MCSymbolRefExpr
>(Expr
);
1657 return (SymRef
.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1661 return hasGOTReference(cast
<MCUnaryExpr
>(Expr
)->getSubExpr());
1667 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK
,
1668 const MCExpr
*subExpr
) {
1669 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1670 // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is
1671 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1672 // as %got10 or %got22 relocation.
1674 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1677 case SparcMCExpr::VK_Sparc_LO
:
1678 VK
= (hasGOTReference(subExpr
) ? SparcMCExpr::VK_Sparc_PC10
1679 : SparcMCExpr::VK_Sparc_GOT10
);
1681 case SparcMCExpr::VK_Sparc_HI
:
1682 VK
= (hasGOTReference(subExpr
) ? SparcMCExpr::VK_Sparc_PC22
1683 : SparcMCExpr::VK_Sparc_GOT22
);
1688 return SparcMCExpr::create(VK
, subExpr
, getContext());
1691 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr
*&EVal
,
1693 AsmToken Tok
= Parser
.getTok();
1694 if (!Tok
.is(AsmToken::Identifier
))
1697 StringRef name
= Tok
.getString();
1699 SparcMCExpr::VariantKind VK
= SparcMCExpr::parseVariantKind(name
);
1701 case SparcMCExpr::VK_Sparc_None
:
1702 Error(getLoc(), "invalid operand modifier");
1705 case SparcMCExpr::VK_Sparc_GOTDATA_OP
:
1706 case SparcMCExpr::VK_Sparc_TLS_GD_ADD
:
1707 case SparcMCExpr::VK_Sparc_TLS_GD_CALL
:
1708 case SparcMCExpr::VK_Sparc_TLS_IE_ADD
:
1709 case SparcMCExpr::VK_Sparc_TLS_IE_LD
:
1710 case SparcMCExpr::VK_Sparc_TLS_IE_LDX
:
1711 case SparcMCExpr::VK_Sparc_TLS_LDM_ADD
:
1712 case SparcMCExpr::VK_Sparc_TLS_LDM_CALL
:
1713 case SparcMCExpr::VK_Sparc_TLS_LDO_ADD
:
1714 // These are special-cased at tablegen level.
1721 Parser
.Lex(); // Eat the identifier.
1722 if (Parser
.getTok().getKind() != AsmToken::LParen
)
1725 Parser
.Lex(); // Eat the LParen token.
1726 const MCExpr
*subExpr
;
1727 if (Parser
.parseParenExpression(subExpr
, EndLoc
))
1730 EVal
= adjustPICRelocation(VK
, subExpr
);
1734 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeSparcAsmParser() {
1735 RegisterMCAsmParser
<SparcAsmParser
> A(getTheSparcTarget());
1736 RegisterMCAsmParser
<SparcAsmParser
> B(getTheSparcV9Target());
1737 RegisterMCAsmParser
<SparcAsmParser
> C(getTheSparcelTarget());
1740 #define GET_REGISTER_MATCHER
1741 #define GET_MATCHER_IMPLEMENTATION
1742 #include "SparcGenAsmMatcher.inc"
1744 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&GOp
,
1746 SparcOperand
&Op
= (SparcOperand
&)GOp
;
1747 if (Op
.isFloatOrDoubleReg()) {
1751 if (!Op
.isFloatReg() || SparcOperand::MorphToDoubleReg(Op
))
1752 return MCTargetAsmParser::Match_Success
;
1755 if (SparcOperand::MorphToQuadReg(Op
))
1756 return MCTargetAsmParser::Match_Success
;
1760 if (Op
.isIntReg() && Kind
== MCK_IntPair
) {
1761 if (SparcOperand::MorphToIntPairReg(Op
))
1762 return MCTargetAsmParser::Match_Success
;
1764 if (Op
.isCoprocReg() && Kind
== MCK_CoprocPair
) {
1765 if (SparcOperand::MorphToCoprocPairReg(Op
))
1766 return MCTargetAsmParser::Match_Success
;
1768 return Match_InvalidOperand
;