43 #define GET_ASSEMBLER_HEADER
44 #include "SparcGenAsmMatcher.inc"
49 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
52 bool MatchingInlineAsm)
override;
53 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
56 bool ParseDirective(
AsmToken DirectiveID)
override;
59 unsigned Kind)
override;
67 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
73 bool matchRegisterName(
const AsmToken &Tok,
unsigned &RegNo,
76 bool matchSparcAsmModifiers(
const MCExpr *&EVal,
SMLoc &EndLoc);
77 bool parseDirectiveWord(
unsigned Size,
SMLoc L);
80 return STI.getTargetTriple().getArchName().startswith(
"sparcv9");
92 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
97 static unsigned IntRegs[32] = {
98 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
99 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
100 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
101 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
102 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
103 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
104 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
105 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
107 static unsigned FloatRegs[32] = {
108 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
109 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
110 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
111 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
112 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
113 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
114 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
115 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
117 static unsigned DoubleRegs[32] = {
118 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
119 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
120 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
121 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
122 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
123 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
124 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
125 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
127 static unsigned QuadFPRegs[32] = {
128 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
129 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
130 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
131 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
133 static unsigned ASRRegs[32] = {
134 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
135 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
136 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
137 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
138 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
139 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
140 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
141 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
165 SMLoc StartLoc, EndLoc;
196 bool isToken()
const override {
return Kind == k_Token; }
197 bool isReg()
const override {
return Kind == k_Register; }
198 bool isImm()
const override {
return Kind == k_Immediate; }
199 bool isMem()
const override {
return isMEMrr() || isMEMri(); }
200 bool isMEMrr()
const {
return Kind == k_MemoryReg; }
201 bool isMEMri()
const {
return Kind == k_MemoryImm; }
203 bool isFloatReg()
const {
204 return (
Kind == k_Register &&
Reg.Kind == rk_FloatReg);
207 bool isFloatOrDoubleReg()
const {
208 return (
Kind == k_Register && (
Reg.Kind == rk_FloatReg
209 ||
Reg.Kind == rk_DoubleReg));
214 assert(
Kind == k_Token &&
"Invalid access!");
218 unsigned getReg()
const override {
219 assert((
Kind == k_Register) &&
"Invalid access!");
223 const MCExpr *getImm()
const {
224 assert((
Kind == k_Immediate) &&
"Invalid access!");
228 unsigned getMemBase()
const {
229 assert((
Kind == k_MemoryReg ||
Kind == k_MemoryImm) &&
"Invalid access!");
233 unsigned getMemOffsetReg()
const {
234 assert((
Kind == k_MemoryReg) &&
"Invalid access!");
235 return Mem.OffsetReg;
238 const MCExpr *getMemOff()
const {
239 assert((
Kind == k_MemoryImm) &&
"Invalid access!");
244 SMLoc getStartLoc()
const override {
248 SMLoc getEndLoc()
const override {
254 case k_Token: OS <<
"Token: " <<
getToken() <<
"\n";
break;
255 case k_Register: OS <<
"Reg: #" <<
getReg() <<
"\n";
break;
256 case k_Immediate: OS <<
"Imm: " << getImm() <<
"\n";
break;
257 case k_MemoryReg: OS <<
"Mem: " << getMemBase() <<
"+"
258 << getMemOffsetReg() <<
"\n";
break;
259 case k_MemoryImm: assert(getMemOff() !=
nullptr);
260 OS <<
"Mem: " << getMemBase()
261 <<
"+" << *getMemOff()
266 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
267 assert(N == 1 &&
"Invalid number of operands!");
271 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
272 assert(N == 1 &&
"Invalid number of operands!");
273 const MCExpr *Expr = getImm();
281 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
287 void addMEMrrOperands(
MCInst &Inst,
unsigned N)
const {
288 assert(N == 2 &&
"Invalid number of operands!");
292 assert(getMemOffsetReg() != 0 &&
"Invalid offset");
296 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
297 assert(N == 2 &&
"Invalid number of operands!");
301 const MCExpr *Expr = getMemOff();
305 static std::unique_ptr<SparcOperand> CreateToken(
StringRef Str,
SMLoc S) {
306 auto Op = make_unique<SparcOperand>(k_Token);
307 Op->Tok.Data = Str.
data();
308 Op->Tok.Length = Str.
size();
314 static std::unique_ptr<SparcOperand> CreateReg(
unsigned RegNum,
unsigned Kind,
316 auto Op = make_unique<SparcOperand>(k_Register);
317 Op->Reg.RegNum = RegNum;
324 static std::unique_ptr<SparcOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
326 auto Op = make_unique<SparcOperand>(k_Immediate);
333 static bool MorphToDoubleReg(SparcOperand &Op) {
334 unsigned Reg = Op.getReg();
335 assert(Op.Reg.Kind == rk_FloatReg);
336 unsigned regIdx = Reg - Sparc::F0;
337 if (regIdx % 2 || regIdx > 31)
339 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
340 Op.Reg.Kind = rk_DoubleReg;
344 static bool MorphToQuadReg(SparcOperand &Op) {
345 unsigned Reg = Op.getReg();
347 switch (Op.Reg.Kind) {
350 regIdx = Reg - Sparc::F0;
351 if (regIdx % 4 || regIdx > 31)
353 Reg = QuadFPRegs[regIdx / 4];
356 regIdx = Reg - Sparc::D0;
357 if (regIdx % 2 || regIdx > 31)
359 Reg = QuadFPRegs[regIdx / 2];
363 Op.Reg.Kind = rk_QuadReg;
367 static std::unique_ptr<SparcOperand>
368 MorphToMEMrr(
unsigned Base, std::unique_ptr<SparcOperand> Op) {
369 unsigned offsetReg = Op->getReg();
370 Op->Kind = k_MemoryReg;
372 Op->Mem.OffsetReg = offsetReg;
373 Op->Mem.Off =
nullptr;
377 static std::unique_ptr<SparcOperand>
379 auto Op = make_unique<SparcOperand>(k_MemoryReg);
381 Op->Mem.OffsetReg = Sparc::G0;
382 Op->Mem.Off =
nullptr;
388 static std::unique_ptr<SparcOperand>
389 MorphToMEMri(
unsigned Base, std::unique_ptr<SparcOperand> Op) {
390 const MCExpr *Imm = Op->getImm();
391 Op->Kind = k_MemoryImm;
393 Op->Mem.OffsetReg = 0;
401 void SparcAsmParser::expandSET(
MCInst &Inst,
SMLoc IDLoc,
405 assert(MCRegOp.
isReg());
410 uint64_t ImmValue = IsImm ? MCValOp.
getImm() : 0;
419 if (!IsImm || (ImmValue & ~0x1fff)) {
431 if (!IsImm || ((ImmValue & 0x1fff) != 0 || ImmValue == 0)) {
444 bool SparcAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
448 bool MatchingInlineAsm) {
451 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
453 switch (MatchResult) {
454 case Match_Success: {
461 expandSET(Inst, IDLoc, Instructions);
465 for (
const MCInst &
I : Instructions) {
471 case Match_MissingFeature:
473 "instruction requires a CPU feature not currently enabled");
475 case Match_InvalidOperand: {
476 SMLoc ErrorLoc = IDLoc;
477 if (ErrorInfo != ~0ULL) {
478 if (ErrorInfo >= Operands.
size())
479 return Error(IDLoc,
"too few operands for instruction");
481 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
482 if (ErrorLoc ==
SMLoc())
486 return Error(ErrorLoc,
"invalid operand for instruction");
488 case Match_MnemonicFail:
489 return Error(IDLoc,
"invalid instruction mnemonic");
494 bool SparcAsmParser::
495 ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
497 const AsmToken &Tok = Parser.getTok();
504 unsigned regKind = SparcOperand::rk_None;
505 if (matchRegisterName(Tok, RegNo, regKind)) {
510 return Error(StartLoc,
"invalid register name");
521 Operands.
push_back(SparcOperand::CreateToken(Name, NameLoc));
529 if (parseBranchModifiers(Operands) != MatchOperand_Success) {
530 SMLoc Loc = getLexer().getLoc();
531 Parser.eatToEndOfStatement();
532 return Error(Loc,
"unexpected token");
535 if (parseOperand(Operands, Name) != MatchOperand_Success) {
536 SMLoc Loc = getLexer().getLoc();
537 Parser.eatToEndOfStatement();
538 return Error(Loc,
"unexpected token");
544 if (parseOperand(Operands, Name) != MatchOperand_Success) {
545 SMLoc Loc = getLexer().getLoc();
546 Parser.eatToEndOfStatement();
547 return Error(Loc,
"unexpected token");
552 SMLoc Loc = getLexer().getLoc();
553 Parser.eatToEndOfStatement();
554 return Error(Loc,
"unexpected token");
560 bool SparcAsmParser::
561 ParseDirective(
AsmToken DirectiveID)
565 if (IDVal ==
".byte")
566 return parseDirectiveWord(1, DirectiveID.
getLoc());
568 if (IDVal ==
".half")
569 return parseDirectiveWord(2, DirectiveID.
getLoc());
571 if (IDVal ==
".word")
572 return parseDirectiveWord(4, DirectiveID.
getLoc());
574 if (IDVal ==
".nword")
575 return parseDirectiveWord(
is64Bit() ? 8 : 4, DirectiveID.
getLoc());
577 if (
is64Bit() && IDVal ==
".xword")
578 return parseDirectiveWord(8, DirectiveID.
getLoc());
580 if (IDVal ==
".register") {
582 Parser.eatToEndOfStatement();
590 bool SparcAsmParser:: parseDirectiveWord(
unsigned Size,
SMLoc L) {
594 if (getParser().parseExpression(Value))
597 getParser().getStreamer().EmitValue(Value, Size);
604 return Error(L,
"unexpected token in directive");
612 SparcAsmParser::OperandMatchResultTy
616 unsigned BaseReg = 0;
618 if (ParseRegister(BaseReg, S, E)) {
619 return MatchOperand_NoMatch;
622 switch (getLexer().getKind()) {
623 default:
return MatchOperand_NoMatch;
628 Operands.
push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
629 return MatchOperand_Success;
638 std::unique_ptr<SparcOperand> Offset;
639 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
640 if (ResTy != MatchOperand_Success || !Offset)
641 return MatchOperand_NoMatch;
644 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
645 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
647 return MatchOperand_Success;
650 SparcAsmParser::OperandMatchResultTy
653 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
658 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
663 Operands.
push_back(SparcOperand::CreateToken(
"[",
664 Parser.getTok().getLoc()));
667 if (Mnemonic ==
"cas" || Mnemonic ==
"casx") {
668 SMLoc S = Parser.getTok().getLoc();
670 return MatchOperand_NoMatch;
673 unsigned RegNo, RegKind;
674 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
675 return MatchOperand_NoMatch;
679 Operands.
push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
680 ResTy = MatchOperand_Success;
682 ResTy = parseMEMOperand(Operands);
685 if (ResTy != MatchOperand_Success)
689 return MatchOperand_ParseFail;
691 Operands.
push_back(SparcOperand::CreateToken(
"]",
692 Parser.getTok().getLoc()));
697 std::unique_ptr<SparcOperand> Op;
698 ResTy = parseSparcAsmOperand(Op,
false);
699 if (ResTy != MatchOperand_Success || !Op)
700 return MatchOperand_ParseFail;
703 return MatchOperand_Success;
706 std::unique_ptr<SparcOperand> Op;
708 ResTy = parseSparcAsmOperand(Op, (Mnemonic ==
"call"));
709 if (ResTy != MatchOperand_Success || !Op)
710 return MatchOperand_ParseFail;
715 return MatchOperand_Success;
718 SparcAsmParser::OperandMatchResultTy
719 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
722 SMLoc S = Parser.getTok().getLoc();
727 switch (getLexer().getKind()) {
734 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
740 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
743 Op = SparcOperand::CreateToken(
"%psr", S);
746 Op = SparcOperand::CreateToken(
"%wim", S);
749 Op = SparcOperand::CreateToken(
"%tbr", S);
753 Op = SparcOperand::CreateToken(
"%xcc", S);
755 Op = SparcOperand::CreateToken(
"%icc", S);
760 if (matchSparcAsmModifiers(EVal, E)) {
762 Op = SparcOperand::CreateImm(EVal, S, E);
769 if (!getParser().parseExpression(EVal, E))
770 Op = SparcOperand::CreateImm(EVal, S, E);
775 if (!getParser().parseIdentifier(Identifier)) {
777 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
782 getContext().getObjectFileInfo()->getRelocM() ==
Reloc::PIC_)
785 Op = SparcOperand::CreateImm(Res, S, E);
790 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
793 SparcAsmParser::OperandMatchResultTy
794 SparcAsmParser::parseBranchModifiers(
OperandVector &Operands) {
803 return MatchOperand_ParseFail;
804 StringRef modName = Parser.getTok().getString();
805 if (modName ==
"a" || modName ==
"pn" || modName ==
"pt") {
806 Operands.
push_back(SparcOperand::CreateToken(modName,
807 Parser.getTok().getLoc()));
811 return MatchOperand_Success;
814 bool SparcAsmParser::matchRegisterName(
const AsmToken &Tok,
820 RegKind = SparcOperand::rk_None;
827 RegKind = SparcOperand::rk_IntReg;
833 RegKind = SparcOperand::rk_IntReg;
839 RegKind = SparcOperand::rk_Special;
845 && intVal > 0 && intVal < 32) {
846 RegNo = ASRRegs[intVal];
847 RegKind = SparcOperand::rk_Special;
853 RegKind = SparcOperand::rk_Special;
859 RegKind = SparcOperand::rk_Special;
865 RegKind = SparcOperand::rk_Special;
871 RegKind = SparcOperand::rk_Special;
878 RegKind = SparcOperand::rk_Special;
887 RegNo = Sparc::FCC0 + intVal;
888 RegKind = SparcOperand::rk_Special;
896 RegNo = IntRegs[intVal];
897 RegKind = SparcOperand::rk_IntReg;
904 RegNo = IntRegs[8 + intVal];
905 RegKind = SparcOperand::rk_IntReg;
911 RegNo = IntRegs[16 + intVal];
912 RegKind = SparcOperand::rk_IntReg;
918 RegNo = IntRegs[24 + intVal];
919 RegKind = SparcOperand::rk_IntReg;
925 RegNo = FloatRegs[intVal];
926 RegKind = SparcOperand::rk_FloatReg;
932 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
934 RegNo = DoubleRegs[intVal/2];
935 RegKind = SparcOperand::rk_DoubleReg;
942 RegNo = IntRegs[intVal];
943 RegKind = SparcOperand::rk_IntReg;
955 if (
const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
978 bool SparcAsmParser::matchSparcAsmModifiers(
const MCExpr *&EVal,
998 if (Parser.parseParenExpression(subExpr, EndLoc))
1001 bool isPIC = getContext().getObjectFileInfo()->getRelocM() ==
Reloc::PIC_;
1034 #define GET_REGISTER_MATCHER
1035 #define GET_MATCHER_IMPLEMENTATION
1036 #include "SparcGenAsmMatcher.inc"
1040 SparcOperand &Op = (SparcOperand &)GOp;
1041 if (Op.isFloatOrDoubleReg()) {
1045 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1049 if (SparcOperand::MorphToQuadReg(Op))
1054 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
void push_back(const T &Elt)
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
size_t size() const
size - Get the string size.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, unsigned VariantID)
static MCOperand createReg(unsigned Reg)
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
Windows NT (Windows on ARM)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Instances of this class represent a single low-level machine instruction.
void LLVMInitializeSparcAsmParser()
const MCExpr * getExpr() const
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Streaming machine code generation interface.
static bool is64Bit(const char *name)
Interface to description of machine instruction set.
static VariantKind parseVariantKind(StringRef name)
static bool hasGOTReference(const MCExpr *Expr)
Binary assembler expressions.
void setOpcode(unsigned Op)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool is(TokenKind K) const
unsigned getOpcode() const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
static SMLoc getFromPointer(const char *Ptr)
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
MCSubtargetInfo - Generic base class for all target subtargets.
References to labels and assigned expressions.
static bool isMem(const MachineInstr *MI, unsigned Op)
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
const ARM::ArchExtKind Kind
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
C - The default llvm calling convention, compatible with C.
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
Target specific expression.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const