mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-18 11:05:48 -04:00
Added support for bkrep in assembler, replace addv by modr if possible by extra pass
This commit is contained in:
parent
3da44a85b7
commit
4bd5cbf0f7
@ -69,6 +69,16 @@ void Teak::relocateOne(uint8_t *loc, RelType type, uint64_t val) const
|
||||
case R_TEAK_PTR_IMM16:
|
||||
write16le(loc + 2, (val >> 1) & 0xFFFF);
|
||||
break;
|
||||
case R_TEAK_BKREP_REG:
|
||||
val -= 2;
|
||||
write16le(loc, (read16le(loc) & ~0x60) | (((val >> 17) & 3) << 5));
|
||||
write16le(loc + 2, (val >> 1) & 0xFFFF);
|
||||
break;
|
||||
case R_TEAK_BKREP_R6:
|
||||
val -= 2;
|
||||
write16le(loc, (read16le(loc) & ~3) | ((val >> 17) & 3));
|
||||
write16le(loc + 2, (val >> 1) & 0xFFFF);
|
||||
break;
|
||||
default:
|
||||
error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
|
||||
}
|
||||
@ -82,6 +92,10 @@ int64_t Teak::getImplicitAddend(const uint8_t* buf, RelType type) const
|
||||
return (((read16le(buf) >> 4) & 3) << 17) | (read16le(buf + 2) << 1);
|
||||
case R_TEAK_PTR_IMM16:
|
||||
return read16le(buf + 2) << 1;
|
||||
case R_TEAK_BKREP_REG:
|
||||
return (((read16le(buf) >> 5) & 3) << 17) | (read16le(buf + 2) << 1) + 2;
|
||||
case R_TEAK_BKREP_R6:
|
||||
return ((read16le(buf) & 3) << 17) | (read16le(buf + 2) << 1) + 2;
|
||||
default:
|
||||
error("unrecognized relocation " + toString(type));
|
||||
}
|
||||
|
@ -7,3 +7,5 @@ ELF_RELOC(R_TEAK_16, 1)
|
||||
ELF_RELOC(R_TEAK_CALL_IMM18, 2)
|
||||
ELF_RELOC(R_TEAK_PTR_IMM16, 3)
|
||||
ELF_RELOC(R_TEAK_REL7, 4)
|
||||
ELF_RELOC(R_TEAK_BKREP_REG, 5)
|
||||
ELF_RELOC(R_TEAK_BKREP_R6, 6)
|
@ -314,6 +314,18 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
return false;
|
||||
}
|
||||
else if(((TeakOperand&)*Operands[0]).getToken() == "callr")
|
||||
{
|
||||
std::string cc = ((TeakOperand&)*Operands[2]).getToken();
|
||||
TeakCC::CondCodes condition;
|
||||
if(!ParseConditionOp(cc, condition))
|
||||
return Error(IDLoc, "Invalid condition code!");
|
||||
Inst.setOpcode(Teak::CALLR_rel7);
|
||||
Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
|
||||
Inst.addOperand(MCOperand::createImm((int)condition));
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
return false;
|
||||
}
|
||||
else if(((TeakOperand&)*Operands[0]).getToken() == "br")
|
||||
{
|
||||
std::string cc = ((TeakOperand&)*Operands[2]).getToken();
|
||||
@ -326,6 +338,72 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
return false;
|
||||
}
|
||||
else if(((TeakOperand&)*Operands[0]).getToken() == "brr")
|
||||
{
|
||||
std::string cc = ((TeakOperand&)*Operands[2]).getToken();
|
||||
TeakCC::CondCodes condition;
|
||||
if(!ParseConditionOp(cc, condition))
|
||||
return Error(IDLoc, "Invalid condition code!");
|
||||
Inst.setOpcode(Teak::BRRCond_rel7);
|
||||
Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
|
||||
Inst.addOperand(MCOperand::createImm((int)condition));
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
return false;
|
||||
}
|
||||
else if(((TeakOperand&)*Operands[0]).getToken() == "bkrep")
|
||||
{
|
||||
std::string regString = ((TeakOperand&)*Operands[1]).getToken();
|
||||
|
||||
Inst.setOpcode(Teak::BKREP_reg16);
|
||||
|
||||
int reg = -1;
|
||||
if (regString == "a0l")
|
||||
reg = Teak::A0L;
|
||||
else if (regString == "a1l")
|
||||
reg = Teak::A1L;
|
||||
else if (regString == "b0l")
|
||||
reg = Teak::B0L;
|
||||
else if (regString == "b1l")
|
||||
reg = Teak::B1L;
|
||||
else if (regString == "a0h")
|
||||
reg = Teak::A0H;
|
||||
else if (regString == "a1h")
|
||||
reg = Teak::A1H;
|
||||
else if (regString == "b0h")
|
||||
reg = Teak::B0H;
|
||||
else if (regString == "b1h")
|
||||
reg = Teak::B1H;
|
||||
else if (regString == "r0")
|
||||
reg = Teak::R0;
|
||||
else if (regString == "r1")
|
||||
reg = Teak::R1;
|
||||
else if (regString == "r2")
|
||||
reg = Teak::R2;
|
||||
else if (regString == "r3")
|
||||
reg = Teak::R3;
|
||||
else if (regString == "r4")
|
||||
reg = Teak::R4;
|
||||
else if (regString == "r5")
|
||||
reg = Teak::R5;
|
||||
else if (regString == "r6")
|
||||
reg = Teak::R6;
|
||||
else if (regString == "r7")
|
||||
reg = Teak::R7;
|
||||
else if (regString == "y0")
|
||||
reg = Teak::Y0;
|
||||
else if (regString == "sv")
|
||||
reg = Teak::SV;
|
||||
else if (regString == "lc")
|
||||
reg = Teak::LC;
|
||||
|
||||
if (reg == -1)
|
||||
return Error(IDLoc, "Invalid register for bkrep");
|
||||
|
||||
Inst.addOperand(MCOperand::createReg(reg));
|
||||
Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[2]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
return false;
|
||||
}
|
||||
for (auto &op : Operands)
|
||||
{
|
||||
TeakOperand& teakOp = static_cast<TeakOperand&>(*op);
|
||||
@ -510,6 +588,19 @@ bool TeakAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
else
|
||||
Operands.push_back(TeakOperand::createToken(op + formatString("0x%04x", val), loc, true, hasSign, false, val * mul));
|
||||
}
|
||||
else if (Tok.is(AsmToken::Identifier))
|
||||
{
|
||||
std::string reg = Tok.getString();
|
||||
getParser().Lex();
|
||||
const AsmToken &Tok2 = getParser().getTok();
|
||||
if (reg == "p" && Tok2.is(AsmToken::Star))
|
||||
{
|
||||
Operands.push_back(TeakOperand::createToken("p*", loc));
|
||||
getParser().Lex();
|
||||
}
|
||||
else
|
||||
Operands.push_back(TeakOperand::createToken(reg, loc));
|
||||
}
|
||||
else
|
||||
{
|
||||
Operands.push_back(TeakOperand::createToken(Name2, Tok.getLoc()));
|
||||
|
@ -59,6 +59,8 @@ public:
|
||||
{ "fixup_teak_call_imm18", 0, 18, 0 },
|
||||
{ "fixup_teak_rel7", 0, 7, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_teak_ptr_imm16", 0, 16, 0 },
|
||||
{ "fixup_teak_bkrep_reg", 0, 18, 0 },
|
||||
{ "fixup_teak_bkrep_r6", 0, 18, 0 },
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
@ -132,6 +134,16 @@ void TeakAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
case Teak::fixup_teak_ptr_imm16:
|
||||
write16le(&Data[Offset + 2], Value);
|
||||
break;
|
||||
case Teak::fixup_teak_bkrep_reg:
|
||||
Value--; //bkrep wants as address the last instruction word
|
||||
write16le(&Data[Offset], (read16le(&Data[Offset]) & ~0x60) | (((Value >> 16) & 3) << 5));
|
||||
write16le(&Data[Offset + 2], Value & 0xFFFF);
|
||||
break;
|
||||
case Teak::fixup_teak_bkrep_r6:
|
||||
Value--; //bkrep wants as address the last instruction word
|
||||
write16le(&Data[Offset], (read16le(&Data[Offset]) & ~3) | ((Value >> 16) & 3));
|
||||
write16le(&Data[Offset + 2], Value & 0xFFFF);
|
||||
break;
|
||||
}
|
||||
// unsigned NumBytes = 4;
|
||||
// Value = adjustFixupValue(Fixup, Value);
|
||||
|
@ -56,6 +56,12 @@ unsigned TeakELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
case Teak::fixup_teak_ptr_imm16:
|
||||
Type = ELF::R_TEAK_PTR_IMM16;
|
||||
break;
|
||||
case Teak::fixup_teak_bkrep_reg:
|
||||
Type = ELF::R_TEAK_BKREP_REG;
|
||||
break;
|
||||
case Teak::fixup_teak_bkrep_r6:
|
||||
Type = ELF::R_TEAK_BKREP_R6;
|
||||
break;
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ enum Fixups {
|
||||
fixup_teak_call_imm18 = FirstTargetFixupKind,
|
||||
fixup_teak_rel7,
|
||||
fixup_teak_ptr_imm16,
|
||||
fixup_teak_bkrep_reg,
|
||||
fixup_teak_bkrep_r6,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
|
@ -495,6 +495,23 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
case Teak::AND_memrn_a:
|
||||
EmitConstant(0x8280 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
|
||||
break;
|
||||
case Teak::BKREP_reg16:
|
||||
{
|
||||
unsigned lcReg = MI.getOperand(0).getReg();
|
||||
if (lcReg == Teak::R6)
|
||||
{
|
||||
EmitConstant(0x8FDC, 2, OS);
|
||||
EmitConstant(0, 2, OS);
|
||||
Fixups.push_back(MCFixup::create(0, MI.getOperand(1).getExpr(), MCFixupKind(Teak::fixup_teak_bkrep_r6)));
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitConstant(0x5D00 | encodeRegisterOp(lcReg), 2, OS);
|
||||
EmitConstant(0, 2, OS);
|
||||
Fixups.push_back(MCFixup::create(0, MI.getOperand(1).getExpr(), MCFixupKind(Teak::fixup_teak_bkrep_reg)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Teak::BRR_rel7:
|
||||
case Teak::BRRCond_rel7:
|
||||
EmitConstant(0x5000 | (MI.getOpcode() == Teak::BRR_rel7 ? 0 : MI.getOperand(1).getImm()), 2, OS);
|
||||
|
@ -237,10 +237,10 @@ let Defs = [ICC] in
|
||||
|
||||
let Constraints = "$dst = $a" in
|
||||
{
|
||||
def MODR_inc1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}++]", [(set GRRegs:$dst, (add GRRegs:$a, 1))]>;
|
||||
def MODR_dec1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}--]", [(set GRRegs:$dst, (add GRRegs:$a, -1))]>;
|
||||
def MODR_inc2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, +2", [(set GRRegs:$dst, (add GRRegs:$a, 2))]>;
|
||||
def MODR_dec2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, -2", [(set GRRegs:$dst, (add GRRegs:$a, -2))]>;
|
||||
def MODR_inc1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}++]", []>;//(set GRRegs:$dst, (add GRRegs:$a, 1))]>;
|
||||
def MODR_dec1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}--]", []>;//(set GRRegs:$dst, (add GRRegs:$a, -1))]>;
|
||||
def MODR_inc2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, +2", []>;//(set GRRegs:$dst, (add GRRegs:$a, 2))]>;
|
||||
def MODR_dec2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, -2", []>;//(set GRRegs:$dst, (add GRRegs:$a, -2))]>;
|
||||
}
|
||||
|
||||
let Constraints = "$dst = $a" in
|
||||
@ -624,6 +624,9 @@ def BRR_rel7 : InstTeak<(outs), (ins Operand<OtherVT>:$addr), "brr $addr, always
|
||||
let isBranch = 1, isTerminator = 1 in
|
||||
def BR_imm18 : InstTeakImm16<(outs), (ins Operand<OtherVT>:$addr, pred:$p), "br $addr, $p", []>;
|
||||
|
||||
let Defs = [LC] in
|
||||
def BKREP_reg16 : InstTeakImm16<(outs), (ins RegNoBRegs16:$it, Operand<OtherVT>:$addr), "bkre $it, $addr", []>;
|
||||
|
||||
let isCall = 1, Uses = [SP] in
|
||||
def CALLR_rel7 : InstTeak<(outs), (ins Operand<i40>:$addr, pred:$p), "callr $addr, $p", []>;
|
||||
|
||||
|
@ -35,6 +35,7 @@ bool TeakOptimizeMovImmPass::runOnMachineFunction(MachineFunction& mf)
|
||||
const TargetInstrInfo* tii = mf.getSubtarget().getInstrInfo();
|
||||
|
||||
std::vector<MachineInstr*> movImms;
|
||||
std::vector<MachineInstr*> addvSubvReg;
|
||||
|
||||
for (auto& mbb : mf)
|
||||
{
|
||||
@ -46,6 +47,8 @@ bool TeakOptimizeMovImmPass::runOnMachineFunction(MachineFunction& mf)
|
||||
{
|
||||
movImms.push_back(&mi);
|
||||
}
|
||||
else if (mi.getOpcode() == Teak::ADDV_imm16_RegNoBRegs16 || mi.getOpcode() == Teak::SUBV_imm16_RegNoBRegs16)
|
||||
addvSubvReg.push_back(&mi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +87,48 @@ bool TeakOptimizeMovImmPass::runOnMachineFunction(MachineFunction& mf)
|
||||
}
|
||||
}
|
||||
|
||||
for (auto mi : addvSubvReg)
|
||||
{
|
||||
if (!mi->getOperand(1).isImm())
|
||||
continue;
|
||||
unsigned dstReg = mi->getOperand(0).getReg();
|
||||
if (!TeakMCRegisterClasses[Teak::GRRegsRegClassID].contains(dstReg))
|
||||
continue;
|
||||
|
||||
int16_t imm = (int16_t)mi->getOperand(1).getImm();
|
||||
if (mi->getOpcode() == Teak::SUBV_imm16_RegNoBRegs16)
|
||||
imm = -imm;
|
||||
|
||||
if (imm == 1)
|
||||
{
|
||||
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MODR_inc1), dstReg)
|
||||
.addReg(dstReg);
|
||||
mi->eraseFromParent();
|
||||
changed = true;
|
||||
}
|
||||
else if (imm == -1)
|
||||
{
|
||||
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MODR_dec1), dstReg)
|
||||
.addReg(dstReg);
|
||||
mi->eraseFromParent();
|
||||
changed = true;
|
||||
}
|
||||
else if (imm == 2)
|
||||
{
|
||||
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MODR_inc2), dstReg)
|
||||
.addReg(dstReg);
|
||||
mi->eraseFromParent();
|
||||
changed = true;
|
||||
}
|
||||
else if (imm == -2)
|
||||
{
|
||||
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MODR_dec2), dstReg)
|
||||
.addReg(dstReg);
|
||||
mi->eraseFromParent();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user