Fixed signedness issue with 32 bit immediates, added support for relative branches

This commit is contained in:
Gericom 2020-03-29 23:36:59 +02:00
parent 43b2f058d5
commit 0ebd722eea
12 changed files with 277 additions and 101 deletions

View File

@ -6,3 +6,4 @@ ELF_RELOC(R_TEAK_NONE, 0)
ELF_RELOC(R_TEAK_16, 1) ELF_RELOC(R_TEAK_16, 1)
ELF_RELOC(R_TEAK_CALL_IMM18, 2) ELF_RELOC(R_TEAK_CALL_IMM18, 2)
ELF_RELOC(R_TEAK_PTR_IMM16, 3) ELF_RELOC(R_TEAK_PTR_IMM16, 3)
ELF_RELOC(R_TEAK_REL7, 4)

View File

@ -308,7 +308,7 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
TeakCC::CondCodes condition; TeakCC::CondCodes condition;
if(!ParseConditionOp(cc, condition)) if(!ParseConditionOp(cc, condition))
return Error(IDLoc, "Invalid condition code!"); 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::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
Inst.addOperand(MCOperand::createImm((int)condition)); Inst.addOperand(MCOperand::createImm((int)condition));
Out.EmitInstruction(Inst, getSTI()); Out.EmitInstruction(Inst, getSTI());
@ -320,7 +320,7 @@ bool TeakAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, Opera
TeakCC::CondCodes condition; TeakCC::CondCodes condition;
if(!ParseConditionOp(cc, condition)) if(!ParseConditionOp(cc, condition))
return Error(IDLoc, "Invalid condition code!"); 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::createExpr(MCSymbolRefExpr::create(((TeakOperand&)*Operands[1]).getToken(), MCSymbolRefExpr::VK_None, getContext())));
Inst.addOperand(MCOperand::createImm((int)condition)); Inst.addOperand(MCOperand::createImm((int)condition));
Out.EmitInstruction(Inst, getSTI()); Out.EmitInstruction(Inst, getSTI());

View File

@ -50,21 +50,21 @@ public:
} }
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
const static MCFixupKindInfo Infos[Teak::NumTargetFixupKinds] = { const static MCFixupKindInfo Infos[Teak::NumTargetFixupKinds] =
// This table *must* be in the order that the fixup_* kinds are defined in {
// TeakFixupKinds.h. // 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 }, // Name Offset (bits) Size (bits) Flags
{ "fixup_teak_ptr_imm16", 0, 16, 0 }, { "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) { if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind); return MCAsmBackend::getFixupKindInfo(Kind);
}
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!");
"Invalid kind!");
return Infos[Kind - FirstTargetFixupKind]; 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], (read16le(&Data[Offset]) & ~0x30) | (((Value >> 16) & 3) << 4));
write16le(&Data[Offset + 2], Value & 0xFFFF); write16le(&Data[Offset + 2], Value & 0xFFFF);
break; 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: case Teak::fixup_teak_ptr_imm16:
write16le(&Data[Offset + 2], Value); write16le(&Data[Offset + 2], Value);
break; break;

View File

@ -50,6 +50,9 @@ unsigned TeakELFObjectWriter::getRelocType(MCContext &Ctx,
case Teak::fixup_teak_call_imm18: case Teak::fixup_teak_call_imm18:
Type = ELF::R_TEAK_CALL_IMM18; Type = ELF::R_TEAK_CALL_IMM18;
break; break;
case Teak::fixup_teak_rel7:
Type = ELF::R_TEAK_REL7;
break;
case Teak::fixup_teak_ptr_imm16: case Teak::fixup_teak_ptr_imm16:
Type = ELF::R_TEAK_PTR_IMM16; Type = ELF::R_TEAK_PTR_IMM16;
break; break;

View File

@ -16,6 +16,7 @@ namespace llvm {
namespace Teak { namespace Teak {
enum Fixups { enum Fixups {
fixup_teak_call_imm18 = FirstTargetFixupKind, fixup_teak_call_imm18 = FirstTargetFixupKind,
fixup_teak_rel7,
fixup_teak_ptr_imm16, fixup_teak_ptr_imm16,
// Marker // Marker

View File

@ -408,16 +408,23 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::AND_memrn_a: case Teak::AND_memrn_a:
EmitConstant(0x8280 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS); EmitConstant(0x8280 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break; 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::BR_imm18:
case Teak::BRCond_imm18:
{ {
unsigned cond = MI.getOpcode() == Teak::BR_imm18 ? TeakCC::True : MI.getOperand(1).getImm(); EmitConstant(0x4180 | MI.getOperand(1).getImm(), 2, OS);
EmitConstant(0x4180 | cond, 2, OS);
EmitConstant(0, 2, OS); EmitConstant(0, 2, OS);
Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), MCFixupKind(Teak::fixup_teak_call_imm18))); Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), MCFixupKind(Teak::fixup_teak_call_imm18)));
break; 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(0x41C0 | MI.getOperand(1).getImm(), 2, OS);
EmitConstant(0, 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_regnob16:
case Teak::CHNG_imm16_abl: case Teak::CHNG_imm16_abl:
case Teak::CHNG_imm16_abh:
{ {
unsigned aReg = MI.getOperand(0).getReg(); unsigned aReg = MI.getOperand(0).getReg();
if(MI.getOpcode() == Teak::CHNG_imm16_abl) if(MI.getOpcode() == Teak::CHNG_imm16_abl)
aReg = teakGetAbLReg(aReg); aReg = teakGetAbLReg(aReg);
else if(MI.getOpcode() == Teak::CHNG_imm16_abh)
aReg = teakGetAbHReg(aReg);
if(aReg == Teak::R6) if(aReg == Teak::R6)
EmitConstant(0x47BA, 2, OS); EmitConstant(0x47BA, 2, OS);
else else
@ -536,12 +546,12 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::MOV_imm16_regnob16: case Teak::MOV_imm16_regnob16:
case Teak::MOV_imm16neg_ab: case Teak::MOV_imm16neg_ab:
case Teak::MOV_imm16_ab: case Teak::MOV_imm16_ab:
case Teak::MOV_imm16hi_ab: case Teak::MOV_imm16_abh:
{ {
unsigned reg = MI.getOperand(0).getReg(); unsigned reg = MI.getOperand(0).getReg();
if(MI.getOpcode() == Teak::MOV_imm16_ab) if(MI.getOpcode() == Teak::MOV_imm16_ab)
reg = teakGetAbLReg(reg); reg = teakGetAbLReg(reg);
else if(MI.getOpcode() == Teak::MOV_imm16hi_ab) else if(MI.getOpcode() == Teak::MOV_imm16_abh)
reg = teakGetAbHReg(reg); reg = teakGetAbHReg(reg);
if(reg == Teak::R6) if(reg == Teak::R6)
EmitConstant(0x0023, 2, OS); EmitConstant(0x0023, 2, OS);
@ -549,7 +559,7 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitConstant(0x5E00 | encodeRegisterOp(reg), 2, OS); EmitConstant(0x5E00 | encodeRegisterOp(reg), 2, OS);
else else
EmitConstant(0x5E20 | (encodeBxOp(reg) << 8), 2, OS); 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); EmitConstant(MI.getOperand(1).getImm() & 0xFFFF, 2, OS);
else else
{ {
@ -760,10 +770,13 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::SET_imm16_regnob16: case Teak::SET_imm16_regnob16:
case Teak::SET_imm16_abl: case Teak::SET_imm16_abl:
case Teak::SET_imm16_abh:
{ {
unsigned aReg = MI.getOperand(0).getReg(); unsigned aReg = MI.getOperand(0).getReg();
if(MI.getOpcode() == Teak::SET_imm16_abl) if(MI.getOpcode() == Teak::SET_imm16_abl)
aReg = teakGetAbLReg(aReg); aReg = teakGetAbLReg(aReg);
else if(MI.getOpcode() == Teak::SET_imm16_abh)
aReg = teakGetAbHReg(aReg);
if(aReg == Teak::R6) if(aReg == Teak::R6)
EmitConstant(0x47B8, 2, OS); EmitConstant(0x47B8, 2, OS);
else else

View File

@ -49,6 +49,7 @@ namespace
// SDNode *SelectMoveImmediate(SDNode *N); // SDNode *SelectMoveImmediate(SDNode *N);
// SDNode *SelectConditionalBranch(SDNode *N); // SDNode *SelectConditionalBranch(SDNode *N);
bool SelectLoad(SDNode* N); bool SelectLoad(SDNode* N);
//bool SelectBRICC(SDNode* node);
// Include the pieces autogenerated from the target description. // Include the pieces autogenerated from the target description.
#include "TeakGenDAGISel.inc" #include "TeakGenDAGISel.inc"
@ -144,6 +145,18 @@ bool TeakDAGToDAGISel::SelectLoad(SDNode* node)
return false; 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) void TeakDAGToDAGISel::Select(SDNode* N)
{ {
switch (N->getOpcode()) switch (N->getOpcode())
@ -152,6 +165,10 @@ void TeakDAGToDAGISel::Select(SDNode* N)
if(SelectLoad(N)) if(SelectLoad(N))
return; return;
break; break;
// case TeakISD::BRICC:
// if(SelectBRICC(N))
// return;
// break;
} }
// if (N->isMachineOpcode()) { // if (N->isMachineOpcode()) {

View File

@ -976,7 +976,7 @@ MachineBasicBlock* TeakTargetLowering::EmitInstrWithCustomInserter(MachineInstr
llvm_unreachable("Unknown SELECT_CC!"); llvm_unreachable("Unknown SELECT_CC!");
case Teak::SELECT_CC_Int_ICC: case Teak::SELECT_CC_Int_ICC:
case Teak::SELECT_CC_Int_ICC_i16: 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); F->insert(It, SinkMBB);
// Transfer the remainder of ThisMBB and its successor edges to SinkMBB. // Transfer the remainder of ThisMBB and its successor edges to SinkMBB.
SinkMBB->splice(SinkMBB->begin(), ThisMBB, SinkMBB->splice(SinkMBB->begin(), ThisMBB, std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
std::next(MachineBasicBlock::iterator(MI)), ThisMBB->end());
SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB); SinkMBB->transferSuccessorsAndUpdatePHIs(ThisMBB);
// Set the new successors for ThisMBB. // Set the new successors for ThisMBB.
@ -1019,13 +1018,14 @@ MachineBasicBlock* TeakTargetLowering::ExpandSelectCC(MachineInstr &MI, MachineB
BuildMI(ThisMBB, dl, TII.get(BROpcode)) BuildMI(ThisMBB, dl, TII.get(BROpcode))
.addMBB(SinkMBB) .addMBB(SinkMBB)
.addImm(CC); .addImm(CC);
//.addReg(Teak::ICC, RegState::Implicit);
//.addReg(Teak::ICC, RegState::Implicit);
// IfFalseMBB just falls through to SinkMBB. // IfFalseMBB just falls through to SinkMBB.
IfFalseMBB->addSuccessor(SinkMBB); IfFalseMBB->addSuccessor(SinkMBB);
// %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ] // %Result = phi [ %TrueValue, ThisMBB ], [ %FalseValue, IfFalseMBB ]
BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(Teak::PHI), BuildMI(*SinkMBB, SinkMBB->begin(), dl, TII.get(Teak::PHI), MI.getOperand(0).getReg())
MI.getOperand(0).getReg())
.addReg(MI.getOperand(1).getReg()) .addReg(MI.getOperand(1).getReg())
.addMBB(ThisMBB) .addMBB(ThisMBB)
.addReg(MI.getOperand(2).getReg()) .addReg(MI.getOperand(2).getReg())

View File

@ -94,80 +94,112 @@ TeakInstrInfo::TeakInstrInfo()
bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB, MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const { bool AllowModify) const
bool HasCondBranch = false; {
TBB = nullptr; bool HasCondBranch = false;
FBB = nullptr; TBB = nullptr;
for (MachineInstr &MI : MBB) { FBB = nullptr;
if (MI.getOpcode() == Teak::BR_imm18) { for (MachineInstr &MI : MBB)
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB(); {
if (HasCondBranch) { if(MI.getOpcode() == Teak::BRR_rel7)
FBB = TargetBB; {
} else { MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
TBB = TargetBB; if (HasCondBranch)
} FBB = TargetBB;
} else if (MI.getOpcode() == Teak::BRCond_imm18) { else
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB(); TBB = TargetBB;
TBB = TargetBB; }
Cond.push_back(MI.getOperand(1)); else if (MI.getOpcode() == Teak::BRRCond_rel7 || MI.getOpcode() == Teak::BR_imm18)
HasCondBranch = true; {
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 false;
return true;
}
return false;
} }
/// RemoveBranch - Remove the branching code at the end of the specific MBB. /// RemoveBranch - Remove the branching code at the end of the specific MBB.
/// This is only invoked in cases where AnalyzeBranch returns success. It /// This is only invoked in cases where AnalyzeBranch returns success. It
/// returns the number of instructions that were removed. /// returns the number of instructions that were removed.
unsigned TeakInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { unsigned TeakInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const
if (MBB.empty()) {
return 0; if(BytesRemoved)
unsigned NumRemoved = 0; *BytesRemoved = 0;
auto I = MBB.end(); if (MBB.empty())
do { return 0;
--I; unsigned NumRemoved = 0;
unsigned Opc = I->getOpcode(); auto I = MBB.end();
if ((Opc == Teak::BR_imm18) || (Opc == Teak::BRCond_imm18)) { do
auto ToDelete = I; {
++I; --I;
MBB.erase(ToDelete); unsigned Opc = I->getOpcode();
NumRemoved++; if (Opc == Teak::BRR_rel7 || Opc == Teak::BRRCond_rel7 || Opc == Teak::BR_imm18)
} {
} while (I != MBB.begin()); auto ToDelete = I;
return NumRemoved; 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 /// InsertBranch - Insert branch code into the end of the specified
// /// MachineBasicBlock. The operands to this method are the same as those /// MachineBasicBlock. The operands to this method are the same as those
// /// returned by AnalyzeBranch. This is only invoked in cases where /// returned by AnalyzeBranch. This is only invoked in cases where
// /// AnalyzeBranch returns success. It returns the number of instructions /// AnalyzeBranch returns success. It returns the number of instructions
// /// inserted. /// inserted.
// /// ///
// /// It is also invoked by tail merging to add unconditional branches in /// It is also invoked by tail merging to add unconditional branches in
// /// cases where AnalyzeBranch doesn't apply because there was no original /// cases where AnalyzeBranch doesn't apply because there was no original
// /// branch to analyze. At least this much must be implemented, else tail /// branch to analyze. At least this much must be implemented, else tail
// /// merging needs to be disabled. /// merging needs to be disabled.
unsigned TeakInstrInfo::insertBranch(MachineBasicBlock &MBB, unsigned TeakInstrInfo::insertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *TBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB, MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL, int *BytesAdded) const { const DebugLoc &DL, int *BytesAdded) const
unsigned NumInserted = 0; {
unsigned NumInserted = 0;
//Insert any conditional branch. if(BytesAdded)
if (Cond.size() > 0) { *BytesAdded = 0;
BuildMI(MBB, MBB.end(), DL, get(Teak::BRCond_imm18)).addMBB(TBB).add(Cond[0]);
NumInserted++; //Insert any conditional branch.
} if (Cond.size() > 0)
{
// Insert any unconditional branch. const MachineInstrBuilder& builder = BuildMI(MBB, MBB.end(), DL, get(Teak::BRRCond_rel7));
if (Cond.empty() || FBB) { //if(Cond[0].getImm() != TeakCC::True)
BuildMI(MBB, MBB.end(), DL, get(Teak::BR_imm18)).addMBB(Cond.empty() ? TBB : FBB); // builder.addUse(Teak::ICC, RegState::Implicit);
NumInserted++; builder.addMBB(TBB)
} .add(Cond[0]);
return NumInserted; //.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 bool TeakInstrInfo::reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
@ -202,6 +234,52 @@ bool TeakInstrInfo::reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond
return false; 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, void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, const DebugLoc &DL, MachineBasicBlock::iterator I, const DebugLoc &DL,
MCRegister DestReg, MCRegister SrcReg, MCRegister DestReg, MCRegister SrcReg,
@ -356,6 +434,10 @@ bool TeakInstrInfo::PredicateInstruction(MachineInstr &MI, ArrayRef<MachineOpera
{ {
MachineOperand &PMO = MI.getOperand(PIdx); MachineOperand &PMO = MI.getOperand(PIdx);
PMO.setImm(Pred[0].getImm()); 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()); //MI.getOperand(PIdx+1).setReg(Pred[1].getReg());
return true; return true;
} }

View File

@ -66,6 +66,12 @@ public:
virtual bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 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, virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, const DebugLoc &DL, MachineBasicBlock::iterator I, const DebugLoc &DL,
MCRegister DestReg, MCRegister SrcReg, MCRegister DestReg, MCRegister SrcReg,

View File

@ -89,6 +89,14 @@ def imm16_not_XFORM : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant((uint16_t)~N->getZExtValue(), SDLoc(N), MVT::i16); 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 ImmNot16AsmOperand_16: ImmAsmOperand<0,65535> { let Name = "Imm0_65535_16"; }
def immNot16_16 : Operand<i16>, ImmLeaf<i16, [{ def immNot16_16 : Operand<i16>, ImmLeaf<i16, [{
return 1;//Imm >= 0 && Imm < 65536; return 1;//Imm >= 0 && Imm < 65536;
@ -99,6 +107,18 @@ def immNot16 : Operand<i40>, ImmLeaf<i40, [{
return ((~Imm) & 0xFFFFFF0000) == 0;// (~Imm) >= 0 && (~Imm) < 65536; return ((~Imm) & 0xFFFFFF0000) == 0;// (~Imm) >= 0 && (~Imm) < 65536;
}], imm16_not_XFORM>; }], 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), def load_postinc : PatFrag<(ops node:$base),
(ld node:$base), [{ (ld node:$base), [{
const LoadSDNode* ld = cast<LoadSDNode>(N); 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_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_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 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_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_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", []>; def CHNG_imm16_sttmod : InstTeakImm16<(outs SttModRegs:$dst), (ins imm0_65535_16:$val, SttModRegs:$a), "chng $val, $a", []>;
let mayLoad = 1 in 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_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_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_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 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 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_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)*/]>; 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); 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. // 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 let mayStore = 1 in
def MOV_al2_memimm16 : InstTeakImm16<(outs), (ins ALRegs:$a, Operand<i16>:$dstAddr), "mov ${a}, [$dstAddr]", [(store ALRegs:$a, imm:$dstAddr)]>; 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 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 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 : Pat<(TeakBRICC bb:$addr, imm:$pred), (BRR_rel7 OtherVT:$addr, i40:$pred, i40:ICC)>;
def CALL_imm : InstTeakImm16<(outs), (ins Operand<i40>:$addr, pred:$p), "call $addr, $p", [(teak_call tglobaladdr:$addr)]>;
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 let isTerminator = 1, isReturn = 1, isBarrier = 1, Defs = [SP], Uses = [SP], mayLoad = 1 in
def RET : InstTeak<(outs), (ins pred:$p), "ret $p", [(TeakRetFlag)]>; def RET : InstTeak<(outs), (ins pred:$p), "ret $p", [(TeakRetFlag)]>;

View File

@ -82,14 +82,19 @@ void TeakPassConfig::addPreSched2()
addPass(&IfConverterID); addPass(&IfConverterID);
} }
bool TeakPassConfig::addInstSelector() { bool TeakPassConfig::addInstSelector()
addPass(createTeakISelDag(getTeakTargetMachine(), getOptLevel())); {
return false; addPass(createTeakISelDag(getTeakTargetMachine(), getOptLevel()));
return false;
} }
void TeakPassConfig::addPreEmitPass() {} void TeakPassConfig::addPreEmitPass()
{
addPass(&BranchRelaxationPassID);
}
// Force static initialization. // Force static initialization.
extern "C" void LLVMInitializeTeakTarget() { extern "C" void LLVMInitializeTeakTarget()
RegisterTargetMachine<TeakTargetMachine> X(getTheTeakTarget()); {
RegisterTargetMachine<TeakTargetMachine> X(getTheTeakTarget());
} }