summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp')
-rw-r--r--contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp164
1 files changed, 136 insertions, 28 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 551189c..6b3b51a 100644
--- a/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -77,6 +77,10 @@ class SparcAsmParser : public MCTargetAsmParser {
bool parseDirectiveWord(unsigned Size, SMLoc L);
bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); }
+
+ void expandSET(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
public:
SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
const MCInstrInfo &MII,
@@ -124,6 +128,15 @@ public:
Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
+ static unsigned ASRRegs[32] = {
+ SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
+ SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
+ SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
+ SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
+ SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
+ SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
+ SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
+ SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
/// SparcOperand - Instances of this class represent a parsed Sparc machine
/// instruction.
@@ -135,9 +148,9 @@ public:
rk_FloatReg,
rk_DoubleReg,
rk_QuadReg,
- rk_CCReg,
- rk_Y
+ rk_Special,
};
+
private:
enum KindTy {
k_Token,
@@ -250,7 +263,7 @@ public:
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(getReg()));
+ Inst.addOperand(MCOperand::createReg(getReg()));
}
void addImmOperands(MCInst &Inst, unsigned N) const {
@@ -262,26 +275,26 @@ public:
void addExpr(MCInst &Inst, const MCExpr *Expr) const{
// Add as immediate when possible. Null MCExpr = 0.
if (!Expr)
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createImm(0));
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
- Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(CE->getValue()));
else
- Inst.addOperand(MCOperand::CreateExpr(Expr));
+ Inst.addOperand(MCOperand::createExpr(Expr));
}
void addMEMrrOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(getMemBase()));
+ Inst.addOperand(MCOperand::createReg(getMemBase()));
assert(getMemOffsetReg() != 0 && "Invalid offset");
- Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
+ Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
}
void addMEMriOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(getMemBase()));
+ Inst.addOperand(MCOperand::createReg(getMemBase()));
const MCExpr *Expr = getMemOff();
addExpr(Inst, Expr);
@@ -360,11 +373,11 @@ public:
}
static std::unique_ptr<SparcOperand>
- CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) {
- auto Op = make_unique<SparcOperand>(k_MemoryImm);
+ CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
+ auto Op = make_unique<SparcOperand>(k_MemoryReg);
Op->Mem.Base = Base;
- Op->Mem.OffsetReg = 0;
- Op->Mem.Off = Off;
+ Op->Mem.OffsetReg = Sparc::G0; // always 0
+ Op->Mem.Off = nullptr;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
@@ -383,6 +396,49 @@ public:
} // end namespace
+void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+ MCOperand MCRegOp = Inst.getOperand(0);
+ MCOperand MCValOp = Inst.getOperand(1);
+ assert(MCRegOp.isReg());
+ assert(MCValOp.isImm() || MCValOp.isExpr());
+
+ // the imm operand can be either an expression or an immediate.
+ bool IsImm = Inst.getOperand(1).isImm();
+ uint64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
+ const MCExpr *ValExpr;
+ if (IsImm)
+ ValExpr = MCConstantExpr::create(ImmValue, getContext());
+ else
+ ValExpr = MCValOp.getExpr();
+
+ MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
+
+ if (!IsImm || (ImmValue & ~0x1fff)) {
+ MCInst TmpInst;
+ const MCExpr *Expr =
+ SparcMCExpr::create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext());
+ TmpInst.setLoc(IDLoc);
+ TmpInst.setOpcode(SP::SETHIi);
+ TmpInst.addOperand(MCRegOp);
+ TmpInst.addOperand(MCOperand::createExpr(Expr));
+ Instructions.push_back(TmpInst);
+ PrevReg = MCRegOp;
+ }
+
+ if (!IsImm || ((ImmValue & 0x1fff) != 0 || ImmValue == 0)) {
+ MCInst TmpInst;
+ const MCExpr *Expr =
+ SparcMCExpr::create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext());
+ TmpInst.setLoc(IDLoc);
+ TmpInst.setOpcode(SP::ORri);
+ TmpInst.addOperand(MCRegOp);
+ TmpInst.addOperand(PrevReg);
+ TmpInst.addOperand(MCOperand::createExpr(Expr));
+ Instructions.push_back(TmpInst);
+ }
+}
+
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out,
@@ -394,8 +450,19 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
MatchingInlineAsm);
switch (MatchResult) {
case Match_Success: {
- Inst.setLoc(IDLoc);
- Out.EmitInstruction(Inst, STI);
+ switch (Inst.getOpcode()) {
+ default:
+ Inst.setLoc(IDLoc);
+ Instructions.push_back(Inst);
+ break;
+ case SP::SET:
+ expandSET(Inst, IDLoc, Instructions);
+ break;
+ }
+
+ for (const MCInst &I : Instructions) {
+ Out.EmitInstruction(I, STI);
+ }
return false;
}
@@ -556,7 +623,7 @@ SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
case AsmToken::Comma:
case AsmToken::RBrac:
case AsmToken::EndOfStatement:
- Operands.push_back(SparcOperand::CreateMEMri(BaseReg, nullptr, S, E));
+ Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
return MatchOperand_Success;
case AsmToken:: Plus:
@@ -622,6 +689,15 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
Operands.push_back(SparcOperand::CreateToken("]",
Parser.getTok().getLoc()));
Parser.Lex(); // Eat the ]
+
+ // Parse an optional address-space identifier after the address.
+ if (getLexer().is(AsmToken::Integer)) {
+ std::unique_ptr<SparcOperand> Op;
+ ResTy = parseSparcAsmOperand(Op, false);
+ if (ResTy != MatchOperand_Success || !Op)
+ return MatchOperand_ParseFail;
+ Operands.push_back(std::move(Op));
+ }
return MatchOperand_Success;
}
@@ -661,10 +737,15 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
default:
Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
break;
- case Sparc::Y:
- Op = SparcOperand::CreateToken("%y", S);
+ case Sparc::PSR:
+ Op = SparcOperand::CreateToken("%psr", S);
+ break;
+ case Sparc::WIM:
+ Op = SparcOperand::CreateToken("%wim", S);
+ break;
+ case Sparc::TBR:
+ Op = SparcOperand::CreateToken("%tbr", S);
break;
-
case Sparc::ICC:
if (name == "xcc")
Op = SparcOperand::CreateToken("%xcc", S);
@@ -682,6 +763,7 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
case AsmToken::Minus:
case AsmToken::Integer:
+ case AsmToken::LParen:
if (!getParser().parseExpression(EVal, E))
Op = SparcOperand::CreateImm(EVal, S, E);
break;
@@ -690,13 +772,13 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
StringRef Identifier;
if (!getParser().parseIdentifier(Identifier)) {
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
- const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+ const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
getContext());
if (isCall &&
getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
- Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
+ Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
getContext());
Op = SparcOperand::CreateImm(Res, S, E);
}
@@ -752,20 +834,46 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
if (name.equals("y")) {
RegNo = Sparc::Y;
- RegKind = SparcOperand::rk_Y;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.substr(0, 3).equals_lower("asr")
+ && !name.substr(3).getAsInteger(10, intVal)
+ && intVal > 0 && intVal < 32) {
+ RegNo = ASRRegs[intVal];
+ RegKind = SparcOperand::rk_Special;
return true;
}
if (name.equals("icc")) {
RegNo = Sparc::ICC;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("psr")) {
+ RegNo = Sparc::PSR;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("wim")) {
+ RegNo = Sparc::WIM;
+ RegKind = SparcOperand::rk_Special;
+ return true;
+ }
+
+ if (name.equals("tbr")) {
+ RegNo = Sparc::TBR;
+ RegKind = SparcOperand::rk_Special;
return true;
}
if (name.equals("xcc")) {
// FIXME:: check 64bit.
RegNo = Sparc::ICC;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
@@ -775,7 +883,7 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
&& intVal < 4) {
// FIXME: check 64bit and handle %fcc1 - %fcc3
RegNo = Sparc::FCC0 + intVal;
- RegKind = SparcOperand::rk_CCReg;
+ RegKind = SparcOperand::rk_Special;
return true;
}
@@ -902,14 +1010,14 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
break;
}
- EVal = SparcMCExpr::Create(VK, subExpr, getContext());
+ EVal = SparcMCExpr::create(VK, subExpr, getContext());
return true;
}
-
extern "C" void LLVMInitializeSparcAsmParser() {
RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
+ RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
}
#define GET_REGISTER_MATCHER
OpenPOWER on IntegriCloud