mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 03:25:54 -04:00
Fixed signedness issue with 32 bit immediates, added support for relative branches
This commit is contained in:
parent
43b2f058d5
commit
0ebd722eea
@ -6,3 +6,4 @@ ELF_RELOC(R_TEAK_NONE, 0)
|
||||
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)
|
||||
|
@ -308,7 +308,7 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
|
||||
TeakCC::CondCodes condition;
|
||||
if(!ParseConditionOp(cc, condition))
|
||||
return Error(IDLoc, "Invalid condition code!");
|
||||
Inst.setOpcode(Teak::CALL_imm);
|
||||
Inst.setOpcode(Teak::CALL_imm18);
|
||||
Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
|
||||
Inst.addOperand(MCOperand::createImm((int)condition));
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
@ -320,7 +320,7 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
|
||||
TeakCC::CondCodes condition;
|
||||
if(!ParseConditionOp(cc, condition))
|
||||
return Error(IDLoc, "Invalid condition code!");
|
||||
Inst.setOpcode(Teak::BRCond_imm18);
|
||||
Inst.setOpcode(Teak::BR_imm18);
|
||||
Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
|
||||
Inst.addOperand(MCOperand::createImm((int)condition));
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
|
@ -50,21 +50,21 @@ public:
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
|
||||
const static MCFixupKindInfo Infos[Teak::NumTargetFixupKinds] = {
|
||||
// This table *must* be in the order that the fixup_* kinds are defined in
|
||||
// TeakFixupKinds.h.
|
||||
//
|
||||
// Name Offset (bits) Size (bits) Flags
|
||||
{ "fixup_teak_call_imm18", 0, 18, 0 },
|
||||
{ "fixup_teak_ptr_imm16", 0, 16, 0 },
|
||||
const static MCFixupKindInfo Infos[Teak::NumTargetFixupKinds] =
|
||||
{
|
||||
// This table *must* be in the order that the fixup_* kinds are defined in
|
||||
// TeakFixupKinds.h.
|
||||
//
|
||||
// Name Offset (bits) Size (bits) Flags
|
||||
{ "fixup_teak_call_imm18", 0, 18, 0 },
|
||||
{ "fixup_teak_rel7", 0, 7, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_teak_ptr_imm16", 0, 16, 0 },
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind) {
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
}
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!");
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
@ -126,6 +126,9 @@ void TeakAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
write16le(&Data[Offset], (read16le(&Data[Offset]) & ~0x30) | (((Value >> 16) & 3) << 4));
|
||||
write16le(&Data[Offset + 2], Value & 0xFFFF);
|
||||
break;
|
||||
case Teak::fixup_teak_rel7:
|
||||
write16le(&Data[Offset], (read16le(&Data[Offset]) & ~0x7F0) | ((((Value >> 1) - 1) & 0x7F) << 4));
|
||||
break;
|
||||
case Teak::fixup_teak_ptr_imm16:
|
||||
write16le(&Data[Offset + 2], Value);
|
||||
break;
|
||||
|
@ -50,6 +50,9 @@ unsigned TeakELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
case Teak::fixup_teak_call_imm18:
|
||||
Type = ELF::R_TEAK_CALL_IMM18;
|
||||
break;
|
||||
case Teak::fixup_teak_rel7:
|
||||
Type = ELF::R_TEAK_REL7;
|
||||
break;
|
||||
case Teak::fixup_teak_ptr_imm16:
|
||||
Type = ELF::R_TEAK_PTR_IMM16;
|
||||
break;
|
||||
|
@ -16,6 +16,7 @@ namespace llvm {
|
||||
namespace Teak {
|
||||
enum Fixups {
|
||||
fixup_teak_call_imm18 = FirstTargetFixupKind,
|
||||
fixup_teak_rel7,
|
||||
fixup_teak_ptr_imm16,
|
||||
|
||||
// Marker
|
||||
|
@ -408,16 +408,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::BRR_rel7:
|
||||
case Teak::BRRCond_rel7:
|
||||
EmitConstant(0x5000 | (MI.getOpcode() == Teak::BRR_rel7 ? 0 : MI.getOperand(1).getImm()), 2, OS);
|
||||
Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), MCFixupKind(Teak::fixup_teak_rel7)));
|
||||
break;
|
||||
case Teak::BR_imm18:
|
||||
case Teak::BRCond_imm18:
|
||||
{
|
||||
unsigned cond = MI.getOpcode() == Teak::BR_imm18 ? TeakCC::True : MI.getOperand(1).getImm();
|
||||
EmitConstant(0x4180 | cond, 2, OS);
|
||||
EmitConstant(0x4180 | MI.getOperand(1).getImm(), 2, OS);
|
||||
EmitConstant(0, 2, OS);
|
||||
Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), MCFixupKind(Teak::fixup_teak_call_imm18)));
|
||||
break;
|
||||
}
|
||||
case Teak::CALL_imm:
|
||||
case Teak::CALLR_rel7:
|
||||
EmitConstant(0x1000 | MI.getOperand(1).getImm(), 2, OS);
|
||||
Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), MCFixupKind(Teak::fixup_teak_rel7)));
|
||||
break;
|
||||
case Teak::CALL_imm18:
|
||||
{
|
||||
EmitConstant(0x41C0 | MI.getOperand(1).getImm(), 2, OS);
|
||||
EmitConstant(0, 2, OS);
|
||||
@ -427,10 +434,13 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
|
||||
case Teak::CHNG_imm16_regnob16:
|
||||
case Teak::CHNG_imm16_abl:
|
||||
case Teak::CHNG_imm16_abh:
|
||||
{
|
||||
unsigned aReg = MI.getOperand(0).getReg();
|
||||
if(MI.getOpcode() == Teak::CHNG_imm16_abl)
|
||||
aReg = teakGetAbLReg(aReg);
|
||||
else if(MI.getOpcode() == Teak::CHNG_imm16_abh)
|
||||
aReg = teakGetAbHReg(aReg);
|
||||
if(aReg == Teak::R6)
|
||||
EmitConstant(0x47BA, 2, OS);
|
||||
else
|
||||
@ -536,12 +546,12 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
case Teak::MOV_imm16_regnob16:
|
||||
case Teak::MOV_imm16neg_ab:
|
||||
case Teak::MOV_imm16_ab:
|
||||
case Teak::MOV_imm16hi_ab:
|
||||
case Teak::MOV_imm16_abh:
|
||||
{
|
||||
unsigned reg = MI.getOperand(0).getReg();
|
||||
if(MI.getOpcode() == Teak::MOV_imm16_ab)
|
||||
reg = teakGetAbLReg(reg);
|
||||
else if(MI.getOpcode() == Teak::MOV_imm16hi_ab)
|
||||
else if(MI.getOpcode() == Teak::MOV_imm16_abh)
|
||||
reg = teakGetAbHReg(reg);
|
||||
if(reg == Teak::R6)
|
||||
EmitConstant(0x0023, 2, OS);
|
||||
@ -549,7 +559,7 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
EmitConstant(0x5E00 | encodeRegisterOp(reg), 2, OS);
|
||||
else
|
||||
EmitConstant(0x5E20 | (encodeBxOp(reg) << 8), 2, OS);
|
||||
if(MI.getOperand(1).isImm() || MI.getOpcode() == Teak::MOV_imm16hi_ab)
|
||||
if(MI.getOperand(1).isImm() || MI.getOpcode() == Teak::MOV_imm16_abh)
|
||||
EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
|
||||
else
|
||||
{
|
||||
@ -760,10 +770,13 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
|
||||
case Teak::SET_imm16_regnob16:
|
||||
case Teak::SET_imm16_abl:
|
||||
case Teak::SET_imm16_abh:
|
||||
{
|
||||
unsigned aReg = MI.getOperand(0).getReg();
|
||||
if(MI.getOpcode() == Teak::SET_imm16_abl)
|
||||
aReg = teakGetAbLReg(aReg);
|
||||
else if(MI.getOpcode() == Teak::SET_imm16_abh)
|
||||
aReg = teakGetAbHReg(aReg);
|
||||
if(aReg == Teak::R6)
|
||||
EmitConstant(0x47B8, 2, OS);
|
||||
else
|
||||
|
@ -49,6 +49,7 @@ namespace
|
||||
// SDNode *SelectMoveImmediate(SDNode *N);
|
||||
// SDNode *SelectConditionalBranch(SDNode *N);
|
||||
bool SelectLoad(SDNode* N);
|
||||
//bool SelectBRICC(SDNode* node);
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "TeakGenDAGISel.inc"
|
||||
@ -144,6 +145,18 @@ bool TeakDAGToDAGISel::SelectLoad(SDNode* node)
|
||||
return false;
|
||||
}
|
||||
|
||||
// bool TeakDAGToDAGISel::SelectBRICC(SDNode* node)
|
||||
// {
|
||||
// SDValue dst = node->getOperand(0);
|
||||
// SDValue cond = node->getOperand(1);
|
||||
// SDValue shit = node->getOperand(2);
|
||||
// SDValue branchOps[] = { dst, cond, CurDAG->getRegister(Teak::ICC, MVT::i32), shit };
|
||||
// SDNode* resNode = CurDAG->getMachineNode(Teak::BRR_rel7, node, MVT::Other, branchOps);
|
||||
// ReplaceUses(SDValue(node, 0), SDValue(resNode, 0));
|
||||
// CurDAG->RemoveDeadNode(node);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
void TeakDAGToDAGISel::Select(SDNode* N)
|
||||
{
|
||||
switch (N->getOpcode())
|
||||
@ -152,6 +165,10 @@ void TeakDAGToDAGISel::Select(SDNode* N)
|
||||
if(SelectLoad(N))
|
||||
return;
|
||||
break;
|
||||
// case TeakISD::BRICC:
|
||||
// if(SelectBRICC(N))
|
||||
// return;
|
||||
// break;
|
||||
}
|
||||
|
||||
// if (N->isMachineOpcode()) {
|
||||
|
@ -976,7 +976,7 @@ MachineBasicBlock* TeakTargetLowering::EmitInstrWithCustomInserter(MachineInstr
|
||||
llvm_unreachable("Unknown SELECT_CC!");
|
||||
case Teak::SELECT_CC_Int_ICC:
|
||||
case Teak::SELECT_CC_Int_ICC_i16:
|
||||
return ExpandSelectCC(MI, BB, Teak::BRCond_imm18);
|
||||
return ExpandSelectCC(MI, BB, Teak::BRRCond_rel7);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1008,8 +1008,7 @@ MachineBasicBlock* TeakTargetLowering::ExpandSelectCC(MachineInstr &MI, MachineB
|
||||
F->insert(It, SinkMBB);
|
||||
|
||||
// Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
|
||||
SinkMBB->splice(SinkMBB->begin(), ThisMBB,
|
||||
std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
|
||||
SinkMBB->splice(SinkMBB->begin(), ThisMBB, std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
|
||||
SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);
|
||||
|
||||
// Set the new successors for ThisMBB.
|
||||
@ -1019,13 +1018,14 @@ MachineBasicBlock* TeakTargetLowering::ExpandSelectCC(MachineInstr &MI, MachineB
|
||||
BuildMI(ThisMBB, dl, TII.get(BROpcode))
|
||||
.addMBB(SinkMBB)
|
||||
.addImm(CC);
|
||||
//.addReg(Teak::ICC, RegState::Implicit);
|
||||
//.addReg(Teak::ICC, RegState::Implicit);
|
||||
|
||||
// IfFalseMBB just falls through to SinkMBB.
|
||||
IfFalseMBB->addSuccessor(SinkMBB);
|
||||
|
||||
// %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ]
|
||||
BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(Teak::PHI),
|
||||
MI.getOperand(0).getReg())
|
||||
BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(Teak::PHI), MI.getOperand(0).getReg())
|
||||
.addReg(MI.getOperand(1).getReg())
|
||||
.addMBB(ThisMBB)
|
||||
.addReg(MI.getOperand(2).getReg())
|
||||
|
@ -94,80 +94,112 @@ TeakInstrInfo::TeakInstrInfo()
|
||||
bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const {
|
||||
bool HasCondBranch = false;
|
||||
TBB = nullptr;
|
||||
FBB = nullptr;
|
||||
for (MachineInstr &MI : MBB) {
|
||||
if (MI.getOpcode() == Teak::BR_imm18) {
|
||||
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
|
||||
if (HasCondBranch) {
|
||||
FBB = TargetBB;
|
||||
} else {
|
||||
TBB = TargetBB;
|
||||
}
|
||||
} else if (MI.getOpcode() == Teak::BRCond_imm18) {
|
||||
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
|
||||
TBB = TargetBB;
|
||||
Cond.push_back(MI.getOperand(1));
|
||||
HasCondBranch = true;
|
||||
bool AllowModify) const
|
||||
{
|
||||
bool HasCondBranch = false;
|
||||
TBB = nullptr;
|
||||
FBB = nullptr;
|
||||
for (MachineInstr &MI : MBB)
|
||||
{
|
||||
if(MI.getOpcode() == Teak::BRR_rel7)
|
||||
{
|
||||
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
|
||||
if (HasCondBranch)
|
||||
FBB = TargetBB;
|
||||
else
|
||||
TBB = TargetBB;
|
||||
}
|
||||
else if (MI.getOpcode() == Teak::BRRCond_rel7 || MI.getOpcode() == Teak::BR_imm18)
|
||||
{
|
||||
TBB = MI.getOperand(0).getMBB();
|
||||
Cond.push_back(MI.getOperand(1));
|
||||
//if(MI.getOpcode() == Teak::BRRCond_rel7)
|
||||
// Cond.push_back(MachineOperand::CreateReg(Teak::ICC, false, true));
|
||||
//else
|
||||
// Cond.push_back(MI.getOperand(2));
|
||||
HasCondBranch = true;
|
||||
}
|
||||
else if (MI.getOpcode() == Teak::RET)
|
||||
return true;
|
||||
}
|
||||
else if (MI.getOpcode() == Teak::RET)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// RemoveBranch - Remove the branching code at the end of the specific MBB.
|
||||
/// This is only invoked in cases where AnalyzeBranch returns success. It
|
||||
/// returns the number of instructions that were removed.
|
||||
unsigned TeakInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const {
|
||||
if (MBB.empty())
|
||||
return 0;
|
||||
unsigned NumRemoved = 0;
|
||||
auto I = MBB.end();
|
||||
do {
|
||||
--I;
|
||||
unsigned Opc = I->getOpcode();
|
||||
if ((Opc == Teak::BR_imm18) || (Opc == Teak::BRCond_imm18)) {
|
||||
auto ToDelete = I;
|
||||
++I;
|
||||
MBB.erase(ToDelete);
|
||||
NumRemoved++;
|
||||
}
|
||||
} while (I != MBB.begin());
|
||||
return NumRemoved;
|
||||
unsigned TeakInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const
|
||||
{
|
||||
if(BytesRemoved)
|
||||
*BytesRemoved = 0;
|
||||
if (MBB.empty())
|
||||
return 0;
|
||||
unsigned NumRemoved = 0;
|
||||
auto I = MBB.end();
|
||||
do
|
||||
{
|
||||
--I;
|
||||
unsigned Opc = I->getOpcode();
|
||||
if (Opc == Teak::BRR_rel7 || Opc == Teak::BRRCond_rel7 || Opc == Teak::BR_imm18)
|
||||
{
|
||||
auto ToDelete = I;
|
||||
if(BytesRemoved)
|
||||
*BytesRemoved += getInstSizeInBytes(*ToDelete);
|
||||
++I;
|
||||
MBB.erase(ToDelete);
|
||||
NumRemoved++;
|
||||
}
|
||||
} while (I != MBB.begin());
|
||||
return NumRemoved;
|
||||
}
|
||||
|
||||
// /// InsertBranch - Insert branch code into the end of the specified
|
||||
// /// MachineBasicBlock. The operands to this method are the same as those
|
||||
// /// returned by AnalyzeBranch. This is only invoked in cases where
|
||||
// /// AnalyzeBranch returns success. It returns the number of instructions
|
||||
// /// inserted.
|
||||
// ///
|
||||
// /// It is also invoked by tail merging to add unconditional branches in
|
||||
// /// cases where AnalyzeBranch doesn't apply because there was no original
|
||||
// /// branch to analyze. At least this much must be implemented, else tail
|
||||
// /// merging needs to be disabled.
|
||||
/// InsertBranch - Insert branch code into the end of the specified
|
||||
/// MachineBasicBlock. The operands to this method are the same as those
|
||||
/// returned by AnalyzeBranch. This is only invoked in cases where
|
||||
/// AnalyzeBranch returns success. It returns the number of instructions
|
||||
/// inserted.
|
||||
///
|
||||
/// It is also invoked by tail merging to add unconditional branches in
|
||||
/// cases where AnalyzeBranch doesn't apply because there was no original
|
||||
/// branch to analyze. At least this much must be implemented, else tail
|
||||
/// merging needs to be disabled.
|
||||
unsigned TeakInstrInfo::insertBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
ArrayRef<MachineOperand> Cond,
|
||||
const DebugLoc &DL, int *BytesAdded) const {
|
||||
unsigned NumInserted = 0;
|
||||
|
||||
//Insert any conditional branch.
|
||||
if (Cond.size() > 0) {
|
||||
BuildMI(MBB, MBB.end(), DL, get(Teak::BRCond_imm18)).addMBB(TBB).add(Cond[0]);
|
||||
NumInserted++;
|
||||
}
|
||||
|
||||
// Insert any unconditional branch.
|
||||
if (Cond.empty() || FBB) {
|
||||
BuildMI(MBB, MBB.end(), DL, get(Teak::BR_imm18)).addMBB(Cond.empty() ? TBB : FBB);
|
||||
NumInserted++;
|
||||
}
|
||||
return NumInserted;
|
||||
const DebugLoc &DL, int *BytesAdded) const
|
||||
{
|
||||
unsigned NumInserted = 0;
|
||||
if(BytesAdded)
|
||||
*BytesAdded = 0;
|
||||
|
||||
//Insert any conditional branch.
|
||||
if (Cond.size() > 0)
|
||||
{
|
||||
const MachineInstrBuilder& builder = BuildMI(MBB, MBB.end(), DL, get(Teak::BRRCond_rel7));
|
||||
//if(Cond[0].getImm() != TeakCC::True)
|
||||
// builder.addUse(Teak::ICC, RegState::Implicit);
|
||||
builder.addMBB(TBB)
|
||||
.add(Cond[0]);
|
||||
//.add(Cond[1]);
|
||||
//.addReg(0);
|
||||
NumInserted++;
|
||||
if(BytesAdded)
|
||||
*BytesAdded += 1;
|
||||
}
|
||||
|
||||
// Insert any unconditional branch.
|
||||
if (Cond.empty() || FBB)
|
||||
{
|
||||
BuildMI(MBB, MBB.end(), DL, get(Teak::BRR_rel7))
|
||||
.addMBB(Cond.empty() ? TBB : FBB);
|
||||
// .addImm(TeakCC::True)
|
||||
//.addReg(0);
|
||||
NumInserted++;
|
||||
if(BytesAdded)
|
||||
*BytesAdded += 1;
|
||||
}
|
||||
return NumInserted;
|
||||
}
|
||||
|
||||
bool TeakInstrInfo::reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
|
||||
@ -202,6 +234,52 @@ bool TeakInstrInfo::reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TeakInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const
|
||||
{
|
||||
switch (BranchOpc)
|
||||
{
|
||||
default:
|
||||
llvm_unreachable("unexpected opcode!");
|
||||
case Teak::BR_imm18:
|
||||
case Teak::CALL_imm18:
|
||||
return true;
|
||||
case Teak::BRR_rel7:
|
||||
case Teak::BRRCond_rel7:
|
||||
case Teak::CALLR_rel7:
|
||||
return BrOffset >= -63 && BrOffset <= 64;
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock* TeakInstrInfo::getBranchDestBlock(const MachineInstr &MI) const
|
||||
{
|
||||
switch (MI.getOpcode())
|
||||
{
|
||||
default:
|
||||
llvm_unreachable("unexpected opcode!");
|
||||
case Teak::BR_imm18:
|
||||
case Teak::BRR_rel7:
|
||||
case Teak::BRRCond_rel7:
|
||||
case Teak::CALL_imm18:
|
||||
case Teak::CALLR_rel7:
|
||||
return MI.getOperand(0).getMBB();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned TeakInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB,
|
||||
const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const
|
||||
{
|
||||
auto& MI = *BuildMI(&MBB, DL, get(Teak::BR_imm18))
|
||||
.addMBB(&NewDestBB)
|
||||
.addImm(TeakCC::True)
|
||||
.addReg(0);
|
||||
return getInstSizeInBytes(MI);
|
||||
}
|
||||
|
||||
unsigned TeakInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const
|
||||
{
|
||||
return get(MI.getOpcode()).getSize() >> 1;
|
||||
}
|
||||
|
||||
void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, const DebugLoc &DL,
|
||||
MCRegister DestReg, MCRegister SrcReg,
|
||||
@ -356,6 +434,10 @@ bool TeakInstrInfo::PredicateInstruction(MachineInstr &MI, ArrayRef<MachineOpera
|
||||
{
|
||||
MachineOperand &PMO = MI.getOperand(PIdx);
|
||||
PMO.setImm(Pred[0].getImm());
|
||||
if(Pred[0].getImm() == TeakCC::True)
|
||||
MI.getOperand(PIdx + 1).ChangeToRegister(0, false);
|
||||
else
|
||||
MI.getOperand(PIdx + 1).ChangeToRegister(Teak::ICC, false, true);
|
||||
//MI.getOperand(PIdx+1).setReg(Pred[1].getReg());
|
||||
return true;
|
||||
}
|
||||
|
@ -66,6 +66,12 @@ public:
|
||||
|
||||
virtual bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
||||
|
||||
virtual bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override;
|
||||
virtual MachineBasicBlock* getBranchDestBlock(const MachineInstr &MI) const override;
|
||||
virtual unsigned insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB,
|
||||
const DebugLoc &DL, int64_t BrOffset = 0, RegScavenger *RS = nullptr) const override;
|
||||
virtual unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
|
||||
|
||||
virtual void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, const DebugLoc &DL,
|
||||
MCRegister DestReg, MCRegister SrcReg,
|
||||
|
@ -89,6 +89,14 @@ def imm16_not_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((uint16_t)~N->getZExtValue(), SDLoc(N), MVT::i16);
|
||||
}]>;
|
||||
|
||||
def immUpper16_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF, SDLoc(N), MVT::i40);
|
||||
}]>;
|
||||
|
||||
def immUpper16Signed_XFORM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((N->getSExtValue() >> 16) & 0xFFFF, SDLoc(N), MVT::i40);
|
||||
}]>;
|
||||
|
||||
//def ImmNot16AsmOperand_16: ImmAsmOperand<0,65535> { let Name = "Imm0_65535_16"; }
|
||||
def immNot16_16 : Operand<i16>, ImmLeaf<i16, [{
|
||||
return 1;//Imm >= 0 && Imm < 65536;
|
||||
@ -99,6 +107,18 @@ def immNot16 : Operand<i40>, ImmLeaf<i40, [{
|
||||
return ((~Imm) & 0xFFFFFF0000) == 0;// (~Imm) >= 0 && (~Imm) < 65536;
|
||||
}], imm16_not_XFORM>;
|
||||
|
||||
def immUpper16 : Operand<i40>, ImmLeaf<i40, [{
|
||||
return (Imm & 0xFFFF0000) == Imm;
|
||||
}], immUpper16_XFORM>;
|
||||
|
||||
def immUpper16Signed : Operand<i40>, ImmLeaf<i40, [{
|
||||
return ((int64_t)((int32_t)(Imm & 0xFFFF0000))) == Imm;
|
||||
}], immUpper16Signed_XFORM>;
|
||||
|
||||
def imm32Signed : Operand<i40>, ImmLeaf<i40, [{
|
||||
return (Imm & 0xFF80000000) == 0xFF80000000;
|
||||
}]>;
|
||||
|
||||
def load_postinc : PatFrag<(ops node:$base),
|
||||
(ld node:$base), [{
|
||||
const LoadSDNode* ld = cast<LoadSDNode>(N);
|
||||
@ -237,10 +257,12 @@ let Defs = [ICC] in
|
||||
|
||||
def SET_imm16_regnob16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins i16imm:$val, RegNoBRegs16:$a), "set $val, $a", [(set RegNoBRegs16:$dst, (TeakOr RegNoBRegs16:$a, imm:$val))]>;
|
||||
def SET_imm16_abl : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val, ABRegs:$a), "set $val, ${a}l", [(set ABRegs:$dst, (TeakOr ABRegs:$a, imm0_65535:$val))]>;
|
||||
def SET_imm16_abh : InstTeakImm16<(outs ABRegs:$dst), (ins immUpper16:$val, ABRegs:$a), "set $val, ${a}h", [(set ABRegs:$dst, (TeakOr ABRegs:$a, immUpper16:$val))]>;
|
||||
def SET_imm16_sttmod : InstTeakImm16<(outs SttModRegs:$dst), (ins imm0_65535_16:$val, SttModRegs:$a), "set $val, $a", []>;
|
||||
|
||||
def CHNG_imm16_regnob16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins i16imm:$val, RegNoBRegs16:$a), "chng $val, $a", [(set RegNoBRegs16:$dst, (TeakXor RegNoBRegs16:$a, imm:$val))]>;
|
||||
def CHNG_imm16_abl : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val, ABRegs:$a), "chng $val, ${a}l", [(set ABRegs:$dst, (TeakXor ABRegs:$a, imm0_65535:$val))]>;
|
||||
def CHNG_imm16_abh : InstTeakImm16<(outs ABRegs:$dst), (ins immUpper16:$val, ABRegs:$a), "chng $val, ${a}h", [(set ABRegs:$dst, (TeakXor ABRegs:$a, immUpper16:$val))]>;
|
||||
def CHNG_imm16_sttmod : InstTeakImm16<(outs SttModRegs:$dst), (ins imm0_65535_16:$val, SttModRegs:$a), "chng $val, $a", []>;
|
||||
|
||||
let mayLoad = 1 in
|
||||
@ -276,12 +298,12 @@ let Defs = [ICC] in
|
||||
def MOV_imm16_regnob16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins i16imm:$val), "mov $val, $dst", [(set RegNoBRegs16:$dst, imm:$val)]>;
|
||||
def MOV_imm16neg_ab : InstTeakImm16<(outs ABRegs:$dst), (ins immNeg32768_32767:$val), "mov $val, $dst", [(set ABRegs:$dst, immNeg32768_32767:$val)]>;
|
||||
def MOV_imm16_ab : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val), "mov $val, ${dst}l", [(set ABRegs:$dst, imm0_65535:$val)]>;
|
||||
def MOV_imm16hi_ab : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val), "mov $val, ${dst}h", []>;
|
||||
def MOV_imm16_abh : InstTeakImm16<(outs ABRegs:$dst), (ins immUpper16Signed:$val), "mov $val, ${dst}h", [(set ABRegs:$dst, immUpper16Signed:$val)]>;
|
||||
}
|
||||
|
||||
let isMoveReg = 1 in
|
||||
{
|
||||
let Constraints = "$dst != $src" in
|
||||
let Constraints = "$dst != $src", Uses = [ICC] in
|
||||
def COPY_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$src, pred:$p), "copy $dst, $p", []>;
|
||||
def MOV_ab_ab : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$src), "mov $src, $dst", [/*(set ABRegs:$dst, ABRegs:$src)*/]>;
|
||||
def MOV_regnobp016_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins RegNoBRegs16:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>;
|
||||
@ -322,8 +344,20 @@ def HI16 : SDNodeXForm<imm,
|
||||
return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 16, SDLoc(N), MVT::i40);
|
||||
}]>;
|
||||
|
||||
// def UPPER16 : SDNodeXForm<imm,
|
||||
// [{
|
||||
// return CurDAG->getTargetConstant(N->getZExtValue() & 0xFFFF0000, SDLoc(N), MVT::i40);
|
||||
// }]>;
|
||||
|
||||
// def UPPER24 : SDNodeXForm<imm,
|
||||
// [{
|
||||
// return CurDAG->getTargetConstant(N->getSExtValue() & ~0xFFFF, SDLoc(N), MVT::i40);
|
||||
// }]>;
|
||||
|
||||
// Arbitrary immediates.
|
||||
def : Pat<(i40 imm:$val), (SET_imm16_abl (LO16 imm:$val), (MOV_imm16hi_ab (HI16 imm:$val)))>;
|
||||
def : Pat<(i40 imm32Signed:$val), (SET_imm16_abl (LO16 imm:$val), (MOV_imm16_abh (HI16 imm:$val)))>;
|
||||
def : Pat<(i40 imm:$val), (SET_imm16_abh (HI16 imm:$val), (MOV_imm16_ab (LO16 imm:$val)))>;
|
||||
// def : Pat<(i40 imm:$val), (SET_imm16_abl (LO16 imm:$val), (MOV_imm16hi_ab (HI16 imm:$val)))>;
|
||||
|
||||
let mayStore = 1 in
|
||||
def MOV_al2_memimm16 : InstTeakImm16<(outs), (ins ALRegs:$a, Operand<i16>:$dstAddr), "mov ${a}, [$dstAddr]", [(store ALRegs:$a, imm:$dstAddr)]>;
|
||||
@ -468,13 +502,24 @@ let Uses = [ICC], usesCustomInserter = 1 in
|
||||
}
|
||||
|
||||
let Uses = [ICC], isBranch = 1, isTerminator = 1 in
|
||||
def BRCond_imm18 : InstTeakImm16<(outs), (ins Operand<OtherVT>:$addr, CCOp:$cond), "br $addr, $cond", [(TeakBRICC bb:$addr, imm:$cond)]>;
|
||||
def BRRCond_rel7 : InstTeak<(outs), (ins Operand<OtherVT>:$addr, CCOp:$p), "br $addr, $p", [(TeakBRICC bb:$addr, imm:$p)]>;
|
||||
|
||||
// let Uses = [ICC], isBranch = 1, isTerminator = 1 in
|
||||
// def BRCond_imm18 : InstTeakImm16<(outs), (ins Operand<OtherVT>:$addr, CCOp:$cond), "br $addr, $cond", [(TeakBRICC bb:$addr, imm:$cond)]>;
|
||||
|
||||
let isBarrier = 1, isBranch = 1, isTerminator = 1 in
|
||||
def BR_imm18 : InstTeakImm16<(outs), (ins Operand<OtherVT>:$addr), "br $addr, always", [(br bb:$addr)]>;
|
||||
def BRR_rel7 : InstTeak<(outs), (ins Operand<OtherVT>:$addr), "brr $addr, always", [(br bb:$addr)]>;
|
||||
|
||||
let isCall = 1, Defs = [SP], Uses = [SP] in
|
||||
def CALL_imm : InstTeakImm16<(outs), (ins Operand<i40>:$addr, pred:$p), "call $addr, $p", [(teak_call tglobaladdr:$addr)]>;
|
||||
//def : Pat<(TeakBRICC bb:$addr, imm:$pred), (BRR_rel7 OtherVT:$addr, i40:$pred, i40:ICC)>;
|
||||
|
||||
let isBranch = 1, isTerminator = 1 in
|
||||
def BR_imm18 : InstTeakImm16<(outs), (ins Operand<OtherVT>:$addr, pred:$p), "br $addr, $p", []>;
|
||||
|
||||
let isCall = 1, Uses = [SP] in
|
||||
def CALLR_rel7 : InstTeak<(outs), (ins Operand<i40>:$addr, pred:$p), "callr $addr, $p", []>;
|
||||
|
||||
let isCall = 1, Uses = [SP] in
|
||||
def CALL_imm18 : InstTeakImm16<(outs), (ins Operand<i40>:$addr, pred:$p), "call $addr, $p", [(teak_call tglobaladdr:$addr)]>;
|
||||
|
||||
let isTerminator = 1, isReturn = 1, isBarrier = 1, Defs = [SP], Uses = [SP], mayLoad = 1 in
|
||||
def RET : InstTeak<(outs), (ins pred:$p), "ret $p", [(TeakRetFlag)]>;
|
||||
|
@ -82,14 +82,19 @@ void TeakPassConfig::addPreSched2()
|
||||
addPass(&IfConverterID);
|
||||
}
|
||||
|
||||
bool TeakPassConfig::addInstSelector() {
|
||||
addPass(createTeakISelDag(getTeakTargetMachine(), getOptLevel()));
|
||||
return false;
|
||||
bool TeakPassConfig::addInstSelector()
|
||||
{
|
||||
addPass(createTeakISelDag(getTeakTargetMachine(), getOptLevel()));
|
||||
return false;
|
||||
}
|
||||
|
||||
void TeakPassConfig::addPreEmitPass() {}
|
||||
void TeakPassConfig::addPreEmitPass()
|
||||
{
|
||||
addPass(&BranchRelaxationPassID);
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeTeakTarget() {
|
||||
RegisterTargetMachine<TeakTargetMachine> X(getTheTeakTarget());
|
||||
extern "C" void LLVMInitializeTeakTarget()
|
||||
{
|
||||
RegisterTargetMachine<TeakTargetMachine> X(getTheTeakTarget());
|
||||
}
|
Loading…
Reference in New Issue
Block a user