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/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"
40 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
41 // namespace. But SPARC backend uses "SP" as its namespace.
47 } // end namespace Sparc
48 } // end namespace llvm
54 class SparcAsmParser
: public MCTargetAsmParser
{
57 /// @name Auto-generated Match Functions
60 #define GET_ASSEMBLER_HEADER
61 #include "SparcGenAsmMatcher.inc"
65 // public interface of the MCTargetAsmParser.
66 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
67 OperandVector
&Operands
, MCStreamer
&Out
,
69 bool MatchingInlineAsm
) override
;
70 bool ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
71 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
72 SMLoc NameLoc
, OperandVector
&Operands
) override
;
73 bool ParseDirective(AsmToken DirectiveID
) override
;
75 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
76 unsigned Kind
) override
;
78 // Custom parse functions for Sparc specific operands.
79 OperandMatchResultTy
parseMEMOperand(OperandVector
&Operands
);
81 OperandMatchResultTy
parseMembarTag(OperandVector
&Operands
);
83 OperandMatchResultTy
parseOperand(OperandVector
&Operands
, StringRef Name
);
86 parseSparcAsmOperand(std::unique_ptr
<SparcOperand
> &Operand
,
89 OperandMatchResultTy
parseBranchModifiers(OperandVector
&Operands
);
91 // Helper function for dealing with %lo / %hi in PIC mode.
92 const SparcMCExpr
*adjustPICRelocation(SparcMCExpr::VariantKind VK
,
93 const MCExpr
*subExpr
);
95 // returns true if Tok is matched to a register and returns register in RegNo.
96 bool matchRegisterName(const AsmToken
&Tok
, unsigned &RegNo
,
99 bool matchSparcAsmModifiers(const MCExpr
*&EVal
, SMLoc
&EndLoc
);
101 bool is64Bit() const {
102 return getSTI().getTargetTriple().getArch() == Triple::sparcv9
;
105 bool expandSET(MCInst
&Inst
, SMLoc IDLoc
,
106 SmallVectorImpl
<MCInst
> &Instructions
);
109 SparcAsmParser(const MCSubtargetInfo
&sti
, MCAsmParser
&parser
,
110 const MCInstrInfo
&MII
,
111 const MCTargetOptions
&Options
)
112 : MCTargetAsmParser(Options
, sti
, MII
), Parser(parser
) {
113 Parser
.addAliasForDirective(".half", ".2byte");
114 Parser
.addAliasForDirective(".uahalf", ".2byte");
115 Parser
.addAliasForDirective(".word", ".4byte");
116 Parser
.addAliasForDirective(".uaword", ".4byte");
117 Parser
.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
119 Parser
.addAliasForDirective(".xword", ".8byte");
121 // Initialize the set of available features.
122 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
126 } // end anonymous namespace
128 static const MCPhysReg IntRegs
[32] = {
129 Sparc::G0
, Sparc::G1
, Sparc::G2
, Sparc::G3
,
130 Sparc::G4
, Sparc::G5
, Sparc::G6
, Sparc::G7
,
131 Sparc::O0
, Sparc::O1
, Sparc::O2
, Sparc::O3
,
132 Sparc::O4
, Sparc::O5
, Sparc::O6
, Sparc::O7
,
133 Sparc::L0
, Sparc::L1
, Sparc::L2
, Sparc::L3
,
134 Sparc::L4
, Sparc::L5
, Sparc::L6
, Sparc::L7
,
135 Sparc::I0
, Sparc::I1
, Sparc::I2
, Sparc::I3
,
136 Sparc::I4
, Sparc::I5
, Sparc::I6
, Sparc::I7
};
138 static const MCPhysReg FloatRegs
[32] = {
139 Sparc::F0
, Sparc::F1
, Sparc::F2
, Sparc::F3
,
140 Sparc::F4
, Sparc::F5
, Sparc::F6
, Sparc::F7
,
141 Sparc::F8
, Sparc::F9
, Sparc::F10
, Sparc::F11
,
142 Sparc::F12
, Sparc::F13
, Sparc::F14
, Sparc::F15
,
143 Sparc::F16
, Sparc::F17
, Sparc::F18
, Sparc::F19
,
144 Sparc::F20
, Sparc::F21
, Sparc::F22
, Sparc::F23
,
145 Sparc::F24
, Sparc::F25
, Sparc::F26
, Sparc::F27
,
146 Sparc::F28
, Sparc::F29
, Sparc::F30
, Sparc::F31
};
148 static const MCPhysReg DoubleRegs
[32] = {
149 Sparc::D0
, Sparc::D1
, Sparc::D2
, Sparc::D3
,
150 Sparc::D4
, Sparc::D5
, Sparc::D6
, Sparc::D7
,
151 Sparc::D8
, Sparc::D9
, Sparc::D10
, Sparc::D11
,
152 Sparc::D12
, Sparc::D13
, Sparc::D14
, Sparc::D15
,
153 Sparc::D16
, Sparc::D17
, Sparc::D18
, Sparc::D19
,
154 Sparc::D20
, Sparc::D21
, Sparc::D22
, Sparc::D23
,
155 Sparc::D24
, Sparc::D25
, Sparc::D26
, Sparc::D27
,
156 Sparc::D28
, Sparc::D29
, Sparc::D30
, Sparc::D31
};
158 static const MCPhysReg QuadFPRegs
[32] = {
159 Sparc::Q0
, Sparc::Q1
, Sparc::Q2
, Sparc::Q3
,
160 Sparc::Q4
, Sparc::Q5
, Sparc::Q6
, Sparc::Q7
,
161 Sparc::Q8
, Sparc::Q9
, Sparc::Q10
, Sparc::Q11
,
162 Sparc::Q12
, Sparc::Q13
, Sparc::Q14
, Sparc::Q15
};
164 static const MCPhysReg ASRRegs
[32] = {
165 SP::Y
, SP::ASR1
, SP::ASR2
, SP::ASR3
,
166 SP::ASR4
, SP::ASR5
, SP::ASR6
, SP::ASR7
,
167 SP::ASR8
, SP::ASR9
, SP::ASR10
, SP::ASR11
,
168 SP::ASR12
, SP::ASR13
, SP::ASR14
, SP::ASR15
,
169 SP::ASR16
, SP::ASR17
, SP::ASR18
, SP::ASR19
,
170 SP::ASR20
, SP::ASR21
, SP::ASR22
, SP::ASR23
,
171 SP::ASR24
, SP::ASR25
, SP::ASR26
, SP::ASR27
,
172 SP::ASR28
, SP::ASR29
, SP::ASR30
, SP::ASR31
};
174 static const MCPhysReg IntPairRegs
[] = {
175 Sparc::G0_G1
, Sparc::G2_G3
, Sparc::G4_G5
, Sparc::G6_G7
,
176 Sparc::O0_O1
, Sparc::O2_O3
, Sparc::O4_O5
, Sparc::O6_O7
,
177 Sparc::L0_L1
, Sparc::L2_L3
, Sparc::L4_L5
, Sparc::L6_L7
,
178 Sparc::I0_I1
, Sparc::I2_I3
, Sparc::I4_I5
, Sparc::I6_I7
};
180 static const MCPhysReg CoprocRegs
[32] = {
181 Sparc::C0
, Sparc::C1
, Sparc::C2
, Sparc::C3
,
182 Sparc::C4
, Sparc::C5
, Sparc::C6
, Sparc::C7
,
183 Sparc::C8
, Sparc::C9
, Sparc::C10
, Sparc::C11
,
184 Sparc::C12
, Sparc::C13
, Sparc::C14
, Sparc::C15
,
185 Sparc::C16
, Sparc::C17
, Sparc::C18
, Sparc::C19
,
186 Sparc::C20
, Sparc::C21
, Sparc::C22
, Sparc::C23
,
187 Sparc::C24
, Sparc::C25
, Sparc::C26
, Sparc::C27
,
188 Sparc::C28
, Sparc::C29
, Sparc::C30
, Sparc::C31
};
190 static const MCPhysReg CoprocPairRegs
[] = {
191 Sparc::C0_C1
, Sparc::C2_C3
, Sparc::C4_C5
, Sparc::C6_C7
,
192 Sparc::C8_C9
, Sparc::C10_C11
, Sparc::C12_C13
, Sparc::C14_C15
,
193 Sparc::C16_C17
, Sparc::C18_C19
, Sparc::C20_C21
, Sparc::C22_C23
,
194 Sparc::C24_C25
, Sparc::C26_C27
, Sparc::C28_C29
, Sparc::C30_C31
};
198 /// SparcOperand - Instances of this class represent a parsed Sparc machine
200 class SparcOperand
: public MCParsedAsmOperand
{
223 SMLoc StartLoc
, EndLoc
;
253 SparcOperand(KindTy K
) : MCParsedAsmOperand(), Kind(K
) {}
255 bool isToken() const override
{ return Kind
== k_Token
; }
256 bool isReg() const override
{ return Kind
== k_Register
; }
257 bool isImm() const override
{ return Kind
== k_Immediate
; }
258 bool isMem() const override
{ return isMEMrr() || isMEMri(); }
259 bool isMEMrr() const { return Kind
== k_MemoryReg
; }
260 bool isMEMri() const { return Kind
== k_MemoryImm
; }
261 bool isMembarTag() const { return Kind
== k_Immediate
; }
263 bool isIntReg() const {
264 return (Kind
== k_Register
&& Reg
.Kind
== rk_IntReg
);
267 bool isFloatReg() const {
268 return (Kind
== k_Register
&& Reg
.Kind
== rk_FloatReg
);
271 bool isFloatOrDoubleReg() const {
272 return (Kind
== k_Register
&& (Reg
.Kind
== rk_FloatReg
273 || Reg
.Kind
== rk_DoubleReg
));
276 bool isCoprocReg() const {
277 return (Kind
== k_Register
&& Reg
.Kind
== rk_CoprocReg
);
280 StringRef
getToken() const {
281 assert(Kind
== k_Token
&& "Invalid access!");
282 return StringRef(Tok
.Data
, Tok
.Length
);
285 unsigned getReg() const override
{
286 assert((Kind
== k_Register
) && "Invalid access!");
290 const MCExpr
*getImm() const {
291 assert((Kind
== k_Immediate
) && "Invalid access!");
295 unsigned getMemBase() const {
296 assert((Kind
== k_MemoryReg
|| Kind
== k_MemoryImm
) && "Invalid access!");
300 unsigned getMemOffsetReg() const {
301 assert((Kind
== k_MemoryReg
) && "Invalid access!");
302 return Mem
.OffsetReg
;
305 const MCExpr
*getMemOff() const {
306 assert((Kind
== k_MemoryImm
) && "Invalid access!");
310 /// getStartLoc - Get the location of the first token of this operand.
311 SMLoc
getStartLoc() const override
{
314 /// getEndLoc - Get the location of the last token of this operand.
315 SMLoc
getEndLoc() const override
{
319 void print(raw_ostream
&OS
) const override
{
321 case k_Token
: OS
<< "Token: " << getToken() << "\n"; break;
322 case k_Register
: OS
<< "Reg: #" << getReg() << "\n"; break;
323 case k_Immediate
: OS
<< "Imm: " << getImm() << "\n"; break;
324 case k_MemoryReg
: OS
<< "Mem: " << getMemBase() << "+"
325 << getMemOffsetReg() << "\n"; break;
326 case k_MemoryImm
: assert(getMemOff() != nullptr);
327 OS
<< "Mem: " << getMemBase()
328 << "+" << *getMemOff()
333 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
334 assert(N
== 1 && "Invalid number of operands!");
335 Inst
.addOperand(MCOperand::createReg(getReg()));
338 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
339 assert(N
== 1 && "Invalid number of operands!");
340 const MCExpr
*Expr
= getImm();
344 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const{
345 // Add as immediate when possible. Null MCExpr = 0.
347 Inst
.addOperand(MCOperand::createImm(0));
348 else if (const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(Expr
))
349 Inst
.addOperand(MCOperand::createImm(CE
->getValue()));
351 Inst
.addOperand(MCOperand::createExpr(Expr
));
354 void addMEMrrOperands(MCInst
&Inst
, unsigned N
) const {
355 assert(N
== 2 && "Invalid number of operands!");
357 Inst
.addOperand(MCOperand::createReg(getMemBase()));
359 assert(getMemOffsetReg() != 0 && "Invalid offset");
360 Inst
.addOperand(MCOperand::createReg(getMemOffsetReg()));
363 void addMEMriOperands(MCInst
&Inst
, unsigned N
) const {
364 assert(N
== 2 && "Invalid number of operands!");
366 Inst
.addOperand(MCOperand::createReg(getMemBase()));
368 const MCExpr
*Expr
= getMemOff();
372 void addMembarTagOperands(MCInst
&Inst
, unsigned N
) const {
373 assert(N
== 1 && "Invalid number of operands!");
374 const MCExpr
*Expr
= getImm();
378 static std::unique_ptr
<SparcOperand
> CreateToken(StringRef Str
, SMLoc S
) {
379 auto Op
= std::make_unique
<SparcOperand
>(k_Token
);
380 Op
->Tok
.Data
= Str
.data();
381 Op
->Tok
.Length
= Str
.size();
387 static std::unique_ptr
<SparcOperand
> CreateReg(unsigned RegNum
, unsigned Kind
,
389 auto Op
= std::make_unique
<SparcOperand
>(k_Register
);
390 Op
->Reg
.RegNum
= RegNum
;
391 Op
->Reg
.Kind
= (SparcOperand::RegisterKind
)Kind
;
397 static std::unique_ptr
<SparcOperand
> CreateImm(const MCExpr
*Val
, SMLoc S
,
399 auto Op
= std::make_unique
<SparcOperand
>(k_Immediate
);
406 static bool MorphToIntPairReg(SparcOperand
&Op
) {
407 unsigned Reg
= Op
.getReg();
408 assert(Op
.Reg
.Kind
== rk_IntReg
);
409 unsigned regIdx
= 32;
410 if (Reg
>= Sparc::G0
&& Reg
<= Sparc::G7
)
411 regIdx
= Reg
- Sparc::G0
;
412 else if (Reg
>= Sparc::O0
&& Reg
<= Sparc::O7
)
413 regIdx
= Reg
- Sparc::O0
+ 8;
414 else if (Reg
>= Sparc::L0
&& Reg
<= Sparc::L7
)
415 regIdx
= Reg
- Sparc::L0
+ 16;
416 else if (Reg
>= Sparc::I0
&& Reg
<= Sparc::I7
)
417 regIdx
= Reg
- Sparc::I0
+ 24;
418 if (regIdx
% 2 || regIdx
> 31)
420 Op
.Reg
.RegNum
= IntPairRegs
[regIdx
/ 2];
421 Op
.Reg
.Kind
= rk_IntPairReg
;
425 static bool MorphToDoubleReg(SparcOperand
&Op
) {
426 unsigned Reg
= Op
.getReg();
427 assert(Op
.Reg
.Kind
== rk_FloatReg
);
428 unsigned regIdx
= Reg
- Sparc::F0
;
429 if (regIdx
% 2 || regIdx
> 31)
431 Op
.Reg
.RegNum
= DoubleRegs
[regIdx
/ 2];
432 Op
.Reg
.Kind
= rk_DoubleReg
;
436 static bool MorphToQuadReg(SparcOperand
&Op
) {
437 unsigned Reg
= Op
.getReg();
439 switch (Op
.Reg
.Kind
) {
440 default: llvm_unreachable("Unexpected register kind!");
442 regIdx
= Reg
- Sparc::F0
;
443 if (regIdx
% 4 || regIdx
> 31)
445 Reg
= QuadFPRegs
[regIdx
/ 4];
448 regIdx
= Reg
- Sparc::D0
;
449 if (regIdx
% 2 || regIdx
> 31)
451 Reg
= QuadFPRegs
[regIdx
/ 2];
455 Op
.Reg
.Kind
= rk_QuadReg
;
459 static bool MorphToCoprocPairReg(SparcOperand
&Op
) {
460 unsigned Reg
= Op
.getReg();
461 assert(Op
.Reg
.Kind
== rk_CoprocReg
);
462 unsigned regIdx
= 32;
463 if (Reg
>= Sparc::C0
&& Reg
<= Sparc::C31
)
464 regIdx
= Reg
- Sparc::C0
;
465 if (regIdx
% 2 || regIdx
> 31)
467 Op
.Reg
.RegNum
= CoprocPairRegs
[regIdx
/ 2];
468 Op
.Reg
.Kind
= rk_CoprocPairReg
;
472 static std::unique_ptr
<SparcOperand
>
473 MorphToMEMrr(unsigned Base
, std::unique_ptr
<SparcOperand
> Op
) {
474 unsigned offsetReg
= Op
->getReg();
475 Op
->Kind
= k_MemoryReg
;
477 Op
->Mem
.OffsetReg
= offsetReg
;
478 Op
->Mem
.Off
= nullptr;
482 static std::unique_ptr
<SparcOperand
>
483 CreateMEMr(unsigned Base
, SMLoc S
, SMLoc E
) {
484 auto Op
= std::make_unique
<SparcOperand
>(k_MemoryReg
);
486 Op
->Mem
.OffsetReg
= Sparc::G0
; // always 0
487 Op
->Mem
.Off
= nullptr;
493 static std::unique_ptr
<SparcOperand
>
494 MorphToMEMri(unsigned Base
, std::unique_ptr
<SparcOperand
> Op
) {
495 const MCExpr
*Imm
= Op
->getImm();
496 Op
->Kind
= k_MemoryImm
;
498 Op
->Mem
.OffsetReg
= 0;
504 } // end anonymous namespace
506 bool SparcAsmParser::expandSET(MCInst
&Inst
, SMLoc IDLoc
,
507 SmallVectorImpl
<MCInst
> &Instructions
) {
508 MCOperand MCRegOp
= Inst
.getOperand(0);
509 MCOperand MCValOp
= Inst
.getOperand(1);
510 assert(MCRegOp
.isReg());
511 assert(MCValOp
.isImm() || MCValOp
.isExpr());
513 // the imm operand can be either an expression or an immediate.
514 bool IsImm
= Inst
.getOperand(1).isImm();
515 int64_t RawImmValue
= IsImm
? MCValOp
.getImm() : 0;
517 // Allow either a signed or unsigned 32-bit immediate.
518 if (RawImmValue
< -2147483648LL || RawImmValue
> 4294967295LL) {
520 "set: argument must be between -2147483648 and 4294967295");
523 // If the value was expressed as a large unsigned number, that's ok.
524 // We want to see if it "looks like" a small signed number.
525 int32_t ImmValue
= RawImmValue
;
526 // For 'set' you can't use 'or' with a negative operand on V9 because
527 // that would splat the sign bit across the upper half of the destination
528 // register, whereas 'set' is defined to zero the high 32 bits.
529 bool IsEffectivelyImm13
=
530 IsImm
&& ((is64Bit() ? 0 : -4096) <= ImmValue
&& ImmValue
< 4096);
531 const MCExpr
*ValExpr
;
533 ValExpr
= MCConstantExpr::create(ImmValue
, getContext());
535 ValExpr
= MCValOp
.getExpr();
537 MCOperand PrevReg
= MCOperand::createReg(Sparc::G0
);
539 // If not just a signed imm13 value, then either we use a 'sethi' with a
540 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
541 // In either case, start with the 'sethi'.
542 if (!IsEffectivelyImm13
) {
544 const MCExpr
*Expr
= adjustPICRelocation(SparcMCExpr::VK_Sparc_HI
, ValExpr
);
545 TmpInst
.setLoc(IDLoc
);
546 TmpInst
.setOpcode(SP::SETHIi
);
547 TmpInst
.addOperand(MCRegOp
);
548 TmpInst
.addOperand(MCOperand::createExpr(Expr
));
549 Instructions
.push_back(TmpInst
);
553 // The low bits require touching in 3 cases:
554 // * A non-immediate value will always require both instructions.
555 // * An effectively imm13 value needs only an 'or' instruction.
556 // * Otherwise, an immediate that is not effectively imm13 requires the
557 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
558 // If the low bits are known zeros, there's nothing to do.
559 // In the second case, and only in that case, must we NOT clear
560 // bits of the immediate value via the %lo() assembler function.
561 // Note also, the 'or' instruction doesn't mind a large value in the case
562 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
563 if (!IsImm
|| IsEffectivelyImm13
|| (ImmValue
& 0x3ff)) {
566 if (IsEffectivelyImm13
)
569 Expr
= adjustPICRelocation(SparcMCExpr::VK_Sparc_LO
, ValExpr
);
570 TmpInst
.setLoc(IDLoc
);
571 TmpInst
.setOpcode(SP::ORri
);
572 TmpInst
.addOperand(MCRegOp
);
573 TmpInst
.addOperand(PrevReg
);
574 TmpInst
.addOperand(MCOperand::createExpr(Expr
));
575 Instructions
.push_back(TmpInst
);
580 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
581 OperandVector
&Operands
,
584 bool MatchingInlineAsm
) {
586 SmallVector
<MCInst
, 8> Instructions
;
587 unsigned MatchResult
= MatchInstructionImpl(Operands
, Inst
, ErrorInfo
,
589 switch (MatchResult
) {
590 case Match_Success
: {
591 switch (Inst
.getOpcode()) {
594 Instructions
.push_back(Inst
);
597 if (expandSET(Inst
, IDLoc
, Instructions
))
602 for (const MCInst
&I
: Instructions
) {
603 Out
.EmitInstruction(I
, getSTI());
608 case Match_MissingFeature
:
610 "instruction requires a CPU feature not currently enabled");
612 case Match_InvalidOperand
: {
613 SMLoc ErrorLoc
= IDLoc
;
614 if (ErrorInfo
!= ~0ULL) {
615 if (ErrorInfo
>= Operands
.size())
616 return Error(IDLoc
, "too few operands for instruction");
618 ErrorLoc
= ((SparcOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
619 if (ErrorLoc
== SMLoc())
623 return Error(ErrorLoc
, "invalid operand for instruction");
625 case Match_MnemonicFail
:
626 return Error(IDLoc
, "invalid instruction mnemonic");
628 llvm_unreachable("Implement any new match types added!");
631 bool SparcAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
633 const AsmToken
&Tok
= Parser
.getTok();
634 StartLoc
= Tok
.getLoc();
635 EndLoc
= Tok
.getEndLoc();
637 if (getLexer().getKind() != AsmToken::Percent
)
640 unsigned regKind
= SparcOperand::rk_None
;
641 if (matchRegisterName(Tok
, RegNo
, regKind
)) {
646 return Error(StartLoc
, "invalid register name");
649 static void applyMnemonicAliases(StringRef
&Mnemonic
,
650 const FeatureBitset
&Features
,
653 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo
&Info
,
654 StringRef Name
, SMLoc NameLoc
,
655 OperandVector
&Operands
) {
657 // First operand in MCInst is instruction mnemonic.
658 Operands
.push_back(SparcOperand::CreateToken(Name
, NameLoc
));
660 // apply mnemonic aliases, if any, so that we can parse operands correctly.
661 applyMnemonicAliases(Name
, getAvailableFeatures(), 0);
663 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
664 // Read the first operand.
665 if (getLexer().is(AsmToken::Comma
)) {
666 if (parseBranchModifiers(Operands
) != MatchOperand_Success
) {
667 SMLoc Loc
= getLexer().getLoc();
668 return Error(Loc
, "unexpected token");
671 if (parseOperand(Operands
, Name
) != MatchOperand_Success
) {
672 SMLoc Loc
= getLexer().getLoc();
673 return Error(Loc
, "unexpected token");
676 while (getLexer().is(AsmToken::Comma
) || getLexer().is(AsmToken::Plus
)) {
677 if (getLexer().is(AsmToken::Plus
)) {
678 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
679 Operands
.push_back(SparcOperand::CreateToken("+", Parser
.getTok().getLoc()));
681 Parser
.Lex(); // Eat the comma or plus.
682 // Parse and remember the operand.
683 if (parseOperand(Operands
, Name
) != MatchOperand_Success
) {
684 SMLoc Loc
= getLexer().getLoc();
685 return Error(Loc
, "unexpected token");
689 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
690 SMLoc Loc
= getLexer().getLoc();
691 return Error(Loc
, "unexpected token");
693 Parser
.Lex(); // Consume the EndOfStatement.
697 bool SparcAsmParser::
698 ParseDirective(AsmToken DirectiveID
)
700 StringRef IDVal
= DirectiveID
.getString();
702 if (IDVal
== ".register") {
703 // For now, ignore .register directive.
704 Parser
.eatToEndOfStatement();
707 if (IDVal
== ".proc") {
708 // For compatibility, ignore this directive.
709 // (It's supposed to be an "optimization" in the Sun assembler)
710 Parser
.eatToEndOfStatement();
714 // Let the MC layer to handle other directives.
719 SparcAsmParser::parseMEMOperand(OperandVector
&Operands
) {
721 unsigned BaseReg
= 0;
723 if (ParseRegister(BaseReg
, S
, E
)) {
724 return MatchOperand_NoMatch
;
727 switch (getLexer().getKind()) {
728 default: return MatchOperand_NoMatch
;
730 case AsmToken::Comma
:
731 case AsmToken::RBrac
:
732 case AsmToken::EndOfStatement
:
733 Operands
.push_back(SparcOperand::CreateMEMr(BaseReg
, S
, E
));
734 return MatchOperand_Success
;
736 case AsmToken:: Plus
:
737 Parser
.Lex(); // Eat the '+'
739 case AsmToken::Minus
:
743 std::unique_ptr
<SparcOperand
> Offset
;
744 OperandMatchResultTy ResTy
= parseSparcAsmOperand(Offset
);
745 if (ResTy
!= MatchOperand_Success
|| !Offset
)
746 return MatchOperand_NoMatch
;
749 Offset
->isImm() ? SparcOperand::MorphToMEMri(BaseReg
, std::move(Offset
))
750 : SparcOperand::MorphToMEMrr(BaseReg
, std::move(Offset
)));
752 return MatchOperand_Success
;
755 OperandMatchResultTy
SparcAsmParser::parseMembarTag(OperandVector
&Operands
) {
756 SMLoc S
= Parser
.getTok().getLoc();
760 std::unique_ptr
<SparcOperand
> Mask
;
761 if (parseSparcAsmOperand(Mask
) == MatchOperand_Success
) {
762 if (!Mask
->isImm() || !Mask
->getImm()->evaluateAsAbsolute(ImmVal
) ||
763 ImmVal
< 0 || ImmVal
> 127) {
764 Error(S
, "invalid membar mask number");
765 return MatchOperand_ParseFail
;
769 while (getLexer().getKind() == AsmToken::Hash
) {
770 SMLoc TagStart
= getLexer().getLoc();
771 Parser
.Lex(); // Eat the '#'.
772 unsigned MaskVal
= StringSwitch
<unsigned>(Parser
.getTok().getString())
773 .Case("LoadLoad", 0x1)
774 .Case("StoreLoad", 0x2)
775 .Case("LoadStore", 0x4)
776 .Case("StoreStore", 0x8)
777 .Case("Lookaside", 0x10)
778 .Case("MemIssue", 0x20)
782 Parser
.Lex(); // Eat the identifier token.
785 Error(TagStart
, "unknown membar tag");
786 return MatchOperand_ParseFail
;
791 if (getLexer().getKind() == AsmToken::Pipe
)
792 Parser
.Lex(); // Eat the '|'.
795 EVal
= MCConstantExpr::create(ImmVal
, getContext());
796 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
797 Operands
.push_back(SparcOperand::CreateImm(EVal
, S
, E
));
798 return MatchOperand_Success
;
802 SparcAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
) {
804 OperandMatchResultTy ResTy
= MatchOperandParserImpl(Operands
, Mnemonic
);
806 // If there wasn't a custom match, try the generic matcher below. Otherwise,
807 // there was a match, but an error occurred, in which case, just return that
808 // the operand parsing failed.
809 if (ResTy
== MatchOperand_Success
|| ResTy
== MatchOperand_ParseFail
)
812 if (getLexer().is(AsmToken::LBrac
)) {
814 Operands
.push_back(SparcOperand::CreateToken("[",
815 Parser
.getTok().getLoc()));
816 Parser
.Lex(); // Eat the [
818 if (Mnemonic
== "cas" || Mnemonic
== "casx" || Mnemonic
== "casa") {
819 SMLoc S
= Parser
.getTok().getLoc();
820 if (getLexer().getKind() != AsmToken::Percent
)
821 return MatchOperand_NoMatch
;
822 Parser
.Lex(); // eat %
824 unsigned RegNo
, RegKind
;
825 if (!matchRegisterName(Parser
.getTok(), RegNo
, RegKind
))
826 return MatchOperand_NoMatch
;
828 Parser
.Lex(); // Eat the identifier token.
829 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer()-1);
830 Operands
.push_back(SparcOperand::CreateReg(RegNo
, RegKind
, S
, E
));
831 ResTy
= MatchOperand_Success
;
833 ResTy
= parseMEMOperand(Operands
);
836 if (ResTy
!= MatchOperand_Success
)
839 if (!getLexer().is(AsmToken::RBrac
))
840 return MatchOperand_ParseFail
;
842 Operands
.push_back(SparcOperand::CreateToken("]",
843 Parser
.getTok().getLoc()));
844 Parser
.Lex(); // Eat the ]
846 // Parse an optional address-space identifier after the address.
847 if (getLexer().is(AsmToken::Integer
)) {
848 std::unique_ptr
<SparcOperand
> Op
;
849 ResTy
= parseSparcAsmOperand(Op
, false);
850 if (ResTy
!= MatchOperand_Success
|| !Op
)
851 return MatchOperand_ParseFail
;
852 Operands
.push_back(std::move(Op
));
854 return MatchOperand_Success
;
857 std::unique_ptr
<SparcOperand
> Op
;
859 ResTy
= parseSparcAsmOperand(Op
, (Mnemonic
== "call"));
860 if (ResTy
!= MatchOperand_Success
|| !Op
)
861 return MatchOperand_ParseFail
;
863 // Push the parsed operand into the list of operands
864 Operands
.push_back(std::move(Op
));
866 return MatchOperand_Success
;
870 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr
<SparcOperand
> &Op
,
872 SMLoc S
= Parser
.getTok().getLoc();
873 SMLoc E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
877 switch (getLexer().getKind()) {
880 case AsmToken::Percent
:
881 Parser
.Lex(); // Eat the '%'.
884 if (matchRegisterName(Parser
.getTok(), RegNo
, RegKind
)) {
885 StringRef name
= Parser
.getTok().getString();
886 Parser
.Lex(); // Eat the identifier token.
887 E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
890 Op
= SparcOperand::CreateReg(RegNo
, RegKind
, S
, E
);
893 Op
= SparcOperand::CreateToken("%psr", S
);
896 Op
= SparcOperand::CreateToken("%fsr", S
);
899 Op
= SparcOperand::CreateToken("%fq", S
);
902 Op
= SparcOperand::CreateToken("%csr", S
);
905 Op
= SparcOperand::CreateToken("%cq", S
);
908 Op
= SparcOperand::CreateToken("%wim", S
);
911 Op
= SparcOperand::CreateToken("%tbr", S
);
915 Op
= SparcOperand::CreateToken("%xcc", S
);
917 Op
= SparcOperand::CreateToken("%icc", S
);
922 if (matchSparcAsmModifiers(EVal
, E
)) {
923 E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
924 Op
= SparcOperand::CreateImm(EVal
, S
, E
);
928 case AsmToken::Minus
:
929 case AsmToken::Integer
:
930 case AsmToken::LParen
:
932 if (!getParser().parseExpression(EVal
, E
))
933 Op
= SparcOperand::CreateImm(EVal
, S
, E
);
936 case AsmToken::Identifier
: {
937 StringRef Identifier
;
938 if (!getParser().parseIdentifier(Identifier
)) {
939 E
= SMLoc::getFromPointer(Parser
.getTok().getLoc().getPointer() - 1);
940 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
942 const MCExpr
*Res
= MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
,
944 SparcMCExpr::VariantKind Kind
= SparcMCExpr::VK_Sparc_13
;
946 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
948 Kind
= SparcMCExpr::VK_Sparc_WPLT30
;
950 Kind
= SparcMCExpr::VK_Sparc_GOT13
;
953 Res
= SparcMCExpr::create(Kind
, Res
, getContext());
955 Op
= SparcOperand::CreateImm(Res
, S
, E
);
960 return (Op
) ? MatchOperand_Success
: MatchOperand_ParseFail
;
964 SparcAsmParser::parseBranchModifiers(OperandVector
&Operands
) {
965 // parse (,a|,pn|,pt)+
967 while (getLexer().is(AsmToken::Comma
)) {
968 Parser
.Lex(); // Eat the comma
970 if (!getLexer().is(AsmToken::Identifier
))
971 return MatchOperand_ParseFail
;
972 StringRef modName
= Parser
.getTok().getString();
973 if (modName
== "a" || modName
== "pn" || modName
== "pt") {
974 Operands
.push_back(SparcOperand::CreateToken(modName
,
975 Parser
.getTok().getLoc()));
976 Parser
.Lex(); // eat the identifier.
979 return MatchOperand_Success
;
982 bool SparcAsmParser::matchRegisterName(const AsmToken
&Tok
, unsigned &RegNo
,
986 RegKind
= SparcOperand::rk_None
;
987 if (Tok
.is(AsmToken::Identifier
)) {
988 StringRef name
= Tok
.getString();
991 if (name
.equals("fp")) {
993 RegKind
= SparcOperand::rk_IntReg
;
997 if (name
.equals("sp")) {
999 RegKind
= SparcOperand::rk_IntReg
;
1003 if (name
.equals("y")) {
1005 RegKind
= SparcOperand::rk_Special
;
1009 if (name
.substr(0, 3).equals_lower("asr")
1010 && !name
.substr(3).getAsInteger(10, intVal
)
1011 && intVal
> 0 && intVal
< 32) {
1012 RegNo
= ASRRegs
[intVal
];
1013 RegKind
= SparcOperand::rk_Special
;
1017 // %fprs is an alias of %asr6.
1018 if (name
.equals("fprs")) {
1020 RegKind
= SparcOperand::rk_Special
;
1024 if (name
.equals("icc")) {
1026 RegKind
= SparcOperand::rk_Special
;
1030 if (name
.equals("psr")) {
1032 RegKind
= SparcOperand::rk_Special
;
1036 if (name
.equals("fsr")) {
1038 RegKind
= SparcOperand::rk_Special
;
1042 if (name
.equals("fq")) {
1044 RegKind
= SparcOperand::rk_Special
;
1048 if (name
.equals("csr")) {
1049 RegNo
= Sparc::CPSR
;
1050 RegKind
= SparcOperand::rk_Special
;
1054 if (name
.equals("cq")) {
1056 RegKind
= SparcOperand::rk_Special
;
1060 if (name
.equals("wim")) {
1062 RegKind
= SparcOperand::rk_Special
;
1066 if (name
.equals("tbr")) {
1068 RegKind
= SparcOperand::rk_Special
;
1072 if (name
.equals("xcc")) {
1073 // FIXME:: check 64bit.
1075 RegKind
= SparcOperand::rk_Special
;
1080 if (name
.substr(0, 3).equals_lower("fcc")
1081 && !name
.substr(3).getAsInteger(10, intVal
)
1083 // FIXME: check 64bit and handle %fcc1 - %fcc3
1084 RegNo
= Sparc::FCC0
+ intVal
;
1085 RegKind
= SparcOperand::rk_Special
;
1090 if (name
.substr(0, 1).equals_lower("g")
1091 && !name
.substr(1).getAsInteger(10, intVal
)
1093 RegNo
= IntRegs
[intVal
];
1094 RegKind
= SparcOperand::rk_IntReg
;
1098 if (name
.substr(0, 1).equals_lower("o")
1099 && !name
.substr(1).getAsInteger(10, intVal
)
1101 RegNo
= IntRegs
[8 + intVal
];
1102 RegKind
= SparcOperand::rk_IntReg
;
1105 if (name
.substr(0, 1).equals_lower("l")
1106 && !name
.substr(1).getAsInteger(10, intVal
)
1108 RegNo
= IntRegs
[16 + intVal
];
1109 RegKind
= SparcOperand::rk_IntReg
;
1112 if (name
.substr(0, 1).equals_lower("i")
1113 && !name
.substr(1).getAsInteger(10, intVal
)
1115 RegNo
= IntRegs
[24 + intVal
];
1116 RegKind
= SparcOperand::rk_IntReg
;
1120 if (name
.substr(0, 1).equals_lower("f")
1121 && !name
.substr(1, 2).getAsInteger(10, intVal
) && intVal
< 32) {
1122 RegNo
= FloatRegs
[intVal
];
1123 RegKind
= SparcOperand::rk_FloatReg
;
1127 if (name
.substr(0, 1).equals_lower("f")
1128 && !name
.substr(1, 2).getAsInteger(10, intVal
)
1129 && intVal
>= 32 && intVal
<= 62 && (intVal
% 2 == 0)) {
1131 RegNo
= DoubleRegs
[intVal
/2];
1132 RegKind
= SparcOperand::rk_DoubleReg
;
1137 if (name
.substr(0, 1).equals_lower("r")
1138 && !name
.substr(1, 2).getAsInteger(10, intVal
) && intVal
< 31) {
1139 RegNo
= IntRegs
[intVal
];
1140 RegKind
= SparcOperand::rk_IntReg
;
1145 if (name
.substr(0, 1).equals_lower("c")
1146 && !name
.substr(1).getAsInteger(10, intVal
)
1148 RegNo
= CoprocRegs
[intVal
];
1149 RegKind
= SparcOperand::rk_CoprocReg
;
1153 if (name
.equals("tpc")) {
1155 RegKind
= SparcOperand::rk_Special
;
1158 if (name
.equals("tnpc")) {
1159 RegNo
= Sparc::TNPC
;
1160 RegKind
= SparcOperand::rk_Special
;
1163 if (name
.equals("tstate")) {
1164 RegNo
= Sparc::TSTATE
;
1165 RegKind
= SparcOperand::rk_Special
;
1168 if (name
.equals("tt")) {
1170 RegKind
= SparcOperand::rk_Special
;
1173 if (name
.equals("tick")) {
1174 RegNo
= Sparc::TICK
;
1175 RegKind
= SparcOperand::rk_Special
;
1178 if (name
.equals("tba")) {
1180 RegKind
= SparcOperand::rk_Special
;
1183 if (name
.equals("pstate")) {
1184 RegNo
= Sparc::PSTATE
;
1185 RegKind
= SparcOperand::rk_Special
;
1188 if (name
.equals("tl")) {
1190 RegKind
= SparcOperand::rk_Special
;
1193 if (name
.equals("pil")) {
1195 RegKind
= SparcOperand::rk_Special
;
1198 if (name
.equals("cwp")) {
1200 RegKind
= SparcOperand::rk_Special
;
1203 if (name
.equals("cansave")) {
1204 RegNo
= Sparc::CANSAVE
;
1205 RegKind
= SparcOperand::rk_Special
;
1208 if (name
.equals("canrestore")) {
1209 RegNo
= Sparc::CANRESTORE
;
1210 RegKind
= SparcOperand::rk_Special
;
1213 if (name
.equals("cleanwin")) {
1214 RegNo
= Sparc::CLEANWIN
;
1215 RegKind
= SparcOperand::rk_Special
;
1218 if (name
.equals("otherwin")) {
1219 RegNo
= Sparc::OTHERWIN
;
1220 RegKind
= SparcOperand::rk_Special
;
1223 if (name
.equals("wstate")) {
1224 RegNo
= Sparc::WSTATE
;
1225 RegKind
= SparcOperand::rk_Special
;
1232 // Determine if an expression contains a reference to the symbol
1233 // "_GLOBAL_OFFSET_TABLE_".
1234 static bool hasGOTReference(const MCExpr
*Expr
) {
1235 switch (Expr
->getKind()) {
1236 case MCExpr::Target
:
1237 if (const SparcMCExpr
*SE
= dyn_cast
<SparcMCExpr
>(Expr
))
1238 return hasGOTReference(SE
->getSubExpr());
1241 case MCExpr::Constant
:
1244 case MCExpr::Binary
: {
1245 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
1246 return hasGOTReference(BE
->getLHS()) || hasGOTReference(BE
->getRHS());
1249 case MCExpr::SymbolRef
: {
1250 const MCSymbolRefExpr
&SymRef
= *cast
<MCSymbolRefExpr
>(Expr
);
1251 return (SymRef
.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1255 return hasGOTReference(cast
<MCUnaryExpr
>(Expr
)->getSubExpr());
1261 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK
,
1262 const MCExpr
*subExpr
) {
1263 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1264 // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1265 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1266 // as %got10 or %got22 relocation.
1268 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1271 case SparcMCExpr::VK_Sparc_LO
:
1272 VK
= (hasGOTReference(subExpr
) ? SparcMCExpr::VK_Sparc_PC10
1273 : SparcMCExpr::VK_Sparc_GOT10
);
1275 case SparcMCExpr::VK_Sparc_HI
:
1276 VK
= (hasGOTReference(subExpr
) ? SparcMCExpr::VK_Sparc_PC22
1277 : SparcMCExpr::VK_Sparc_GOT22
);
1282 return SparcMCExpr::create(VK
, subExpr
, getContext());
1285 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr
*&EVal
,
1287 AsmToken Tok
= Parser
.getTok();
1288 if (!Tok
.is(AsmToken::Identifier
))
1291 StringRef name
= Tok
.getString();
1293 SparcMCExpr::VariantKind VK
= SparcMCExpr::parseVariantKind(name
);
1295 if (VK
== SparcMCExpr::VK_Sparc_None
)
1298 Parser
.Lex(); // Eat the identifier.
1299 if (Parser
.getTok().getKind() != AsmToken::LParen
)
1302 Parser
.Lex(); // Eat the LParen token.
1303 const MCExpr
*subExpr
;
1304 if (Parser
.parseParenExpression(subExpr
, EndLoc
))
1307 EVal
= adjustPICRelocation(VK
, subExpr
);
1311 extern "C" void LLVMInitializeSparcAsmParser() {
1312 RegisterMCAsmParser
<SparcAsmParser
> A(getTheSparcTarget());
1313 RegisterMCAsmParser
<SparcAsmParser
> B(getTheSparcV9Target());
1314 RegisterMCAsmParser
<SparcAsmParser
> C(getTheSparcelTarget());
1317 #define GET_REGISTER_MATCHER
1318 #define GET_MATCHER_IMPLEMENTATION
1319 #include "SparcGenAsmMatcher.inc"
1321 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&GOp
,
1323 SparcOperand
&Op
= (SparcOperand
&)GOp
;
1324 if (Op
.isFloatOrDoubleReg()) {
1328 if (!Op
.isFloatReg() || SparcOperand::MorphToDoubleReg(Op
))
1329 return MCTargetAsmParser::Match_Success
;
1332 if (SparcOperand::MorphToQuadReg(Op
))
1333 return MCTargetAsmParser::Match_Success
;
1337 if (Op
.isIntReg() && Kind
== MCK_IntPair
) {
1338 if (SparcOperand::MorphToIntPairReg(Op
))
1339 return MCTargetAsmParser::Match_Success
;
1341 if (Op
.isCoprocReg() && Kind
== MCK_CoprocPair
) {
1342 if (SparcOperand::MorphToCoprocPairReg(Op
))
1343 return MCTargetAsmParser::Match_Success
;
1345 return Match_InvalidOperand
;