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_CALL_IMM18, 2)
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;
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());

View File

@ -50,21 +50,21 @@ public:
}
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.
//
// 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) {
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;

View File

@ -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;

View File

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

View File

@ -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

View File

@ -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()) {

View File

@ -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())

View File

@ -94,22 +94,29 @@ TeakInstrInfo::TeakInstrInfo()
bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
bool AllowModify) const
{
bool HasCondBranch = false;
TBB = nullptr;
FBB = nullptr;
for (MachineInstr &MI : MBB) {
if (MI.getOpcode() == Teak::BR_imm18) {
for (MachineInstr &MI : MBB)
{
if(MI.getOpcode() == Teak::BRR_rel7)
{
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
if (HasCondBranch) {
if (HasCondBranch)
FBB = TargetBB;
} else {
else
TBB = TargetBB;
}
} else if (MI.getOpcode() == Teak::BRCond_imm18) {
MachineBasicBlock *TargetBB = MI.getOperand(0).getMBB();
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)
@ -121,16 +128,23 @@ bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TB
/// 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 {
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 {
do
{
--I;
unsigned Opc = I->getOpcode();
if ((Opc == Teak::BR_imm18) || (Opc == Teak::BRCond_imm18)) {
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++;
@ -139,33 +153,51 @@ unsigned TeakInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved)
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 {
const DebugLoc &DL, int *BytesAdded) const
{
unsigned NumInserted = 0;
if(BytesAdded)
*BytesAdded = 0;
//Insert any conditional branch.
if (Cond.size() > 0) {
BuildMI(MBB, MBB.end(), DL, get(Teak::BRCond_imm18)).addMBB(TBB).add(Cond[0]);
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::BR_imm18)).addMBB(Cond.empty() ? TBB : FBB);
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;
}
@ -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;
}

View File

@ -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,

View File

@ -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)]>;

View File

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