From 0ebd722eea765bfd1e22bea6ae9f703b23ce93a2 Mon Sep 17 00:00:00 2001 From: Gericom Date: Sun, 29 Mar 2020 23:36:59 +0200 Subject: [PATCH] Fixed signedness issue with 32 bit immediates, added support for relative branches --- .../llvm/BinaryFormat/ELFRelocs/Teak.def | 1 + .../Target/Teak/AsmParser/TeakAsmParser.cpp | 4 +- .../Teak/MCTargetDesc/TeakAsmBackend.cpp | 27 ++- .../Teak/MCTargetDesc/TeakELFObjectWriter.cpp | 3 + .../Target/Teak/MCTargetDesc/TeakFixupKinds.h | 1 + .../Teak/MCTargetDesc/TeakMCCodeEmitter.cpp | 27 ++- llvm/lib/Target/Teak/TeakISelDAGToDAG.cpp | 17 ++ llvm/lib/Target/Teak/TeakISelLowering.cpp | 10 +- llvm/lib/Target/Teak/TeakInstrInfo.cpp | 206 ++++++++++++------ llvm/lib/Target/Teak/TeakInstrInfo.h | 6 + llvm/lib/Target/Teak/TeakInstrInfo.td | 59 ++++- llvm/lib/Target/Teak/TeakTargetMachine.cpp | 17 +- 12 files changed, 277 insertions(+), 101 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/Teak.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/Teak.def index 1f9cfbdb52d..e1fa7a5fe0f 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/Teak.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/Teak.def @@ -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) diff --git a/llvm/lib/Target/Teak/AsmParser/TeakAsmParser.cpp b/llvm/lib/Target/Teak/AsmParser/TeakAsmParser.cpp index de4d4504d04..e87616f15b0 100644 --- a/llvm/lib/Target/Teak/AsmParser/TeakAsmParser.cpp +++ b/llvm/lib/Target/Teak/AsmParser/TeakAsmParser.cpp @@ -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()); diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakAsmBackend.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakAsmBackend.cpp index 9dd7d595e33..8735efb55a0 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakAsmBackend.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakAsmBackend.cpp @@ -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; diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakELFObjectWriter.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFObjectWriter.cpp index 5d32e7a2489..4ae53dcda9c 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakELFObjectWriter.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFObjectWriter.cpp @@ -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; diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakFixupKinds.h b/llvm/lib/Target/Teak/MCTargetDesc/TeakFixupKinds.h index 8aa9308b67a..110de1e7a1d 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakFixupKinds.h +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakFixupKinds.h @@ -16,6 +16,7 @@ namespace llvm { namespace Teak { enum Fixups { fixup_teak_call_imm18 = FirstTargetFixupKind, + fixup_teak_rel7, fixup_teak_ptr_imm16, // Marker diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp index ba9f629eb0f..dd5ac0ac478 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp @@ -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 diff --git a/llvm/lib/Target/Teak/TeakISelDAGToDAG.cpp b/llvm/lib/Target/Teak/TeakISelDAGToDAG.cpp index 03e4e5694d8..6da0bef7d68 100644 --- a/llvm/lib/Target/Teak/TeakISelDAGToDAG.cpp +++ b/llvm/lib/Target/Teak/TeakISelDAGToDAG.cpp @@ -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()) { diff --git a/llvm/lib/Target/Teak/TeakISelLowering.cpp b/llvm/lib/Target/Teak/TeakISelLowering.cpp index bd9770be252..ba3fea459cd 100644 --- a/llvm/lib/Target/Teak/TeakISelLowering.cpp +++ b/llvm/lib/Target/Teak/TeakISelLowering.cpp @@ -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()) diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.cpp b/llvm/lib/Target/Teak/TeakInstrInfo.cpp index 3365d53ab7a..2f882742180 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.cpp +++ b/llvm/lib/Target/Teak/TeakInstrInfo.cpp @@ -94,80 +94,112 @@ TeakInstrInfo::TeakInstrInfo() bool TeakInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl &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 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 &Cond) const @@ -202,6 +234,52 @@ bool TeakInstrInfo::reverseBranchCondition(SmallVectorImpl &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 &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, diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.td b/llvm/lib/Target/Teak/TeakInstrInfo.td index be6d701b90e..5ff695a85ea 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.td +++ b/llvm/lib/Target/Teak/TeakInstrInfo.td @@ -89,6 +89,14 @@ def imm16_not_XFORM : SDNodeXFormgetTargetConstant((uint16_t)~N->getZExtValue(), SDLoc(N), MVT::i16); }]>; +def immUpper16_XFORM : SDNodeXFormgetTargetConstant((N->getZExtValue() >> 16) & 0xFFFF, SDLoc(N), MVT::i40); +}]>; + +def immUpper16Signed_XFORM : SDNodeXFormgetTargetConstant((N->getSExtValue() >> 16) & 0xFFFF, SDLoc(N), MVT::i40); +}]>; + //def ImmNot16AsmOperand_16: ImmAsmOperand<0,65535> { let Name = "Imm0_65535_16"; } def immNot16_16 : Operand, ImmLeaf= 0 && Imm < 65536; @@ -99,6 +107,18 @@ def immNot16 : Operand, ImmLeaf= 0 && (~Imm) < 65536; }], imm16_not_XFORM>; +def immUpper16 : Operand, ImmLeaf; + +def immUpper16Signed : Operand, ImmLeaf; + +def imm32Signed : Operand, ImmLeaf; + def load_postinc : PatFrag<(ops node:$base), (ld node:$base), [{ const LoadSDNode* ld = cast(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 : SDNodeXFormgetTargetConstant((unsigned)N->getZExtValue() >> 16, SDLoc(N), MVT::i40); }]>; +// def UPPER16 : SDNodeXFormgetTargetConstant(N->getZExtValue() & 0xFFFF0000, SDLoc(N), MVT::i40); +// }]>; + +// def UPPER24 : SDNodeXFormgetTargetConstant(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:$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:$addr, CCOp:$cond), "br $addr, $cond", [(TeakBRICC bb:$addr, imm:$cond)]>; +def BRRCond_rel7 : InstTeak<(outs), (ins Operand:$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:$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:$addr), "br $addr, always", [(br bb:$addr)]>; +def BRR_rel7 : InstTeak<(outs), (ins Operand:$addr), "brr $addr, always", [(br bb:$addr)]>; -let isCall = 1, Defs = [SP], Uses = [SP] in -def CALL_imm : InstTeakImm16<(outs), (ins Operand:$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:$addr, pred:$p), "br $addr, $p", []>; + +let isCall = 1, Uses = [SP] in +def CALLR_rel7 : InstTeak<(outs), (ins Operand:$addr, pred:$p), "callr $addr, $p", []>; + +let isCall = 1, Uses = [SP] in +def CALL_imm18 : InstTeakImm16<(outs), (ins Operand:$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)]>; diff --git a/llvm/lib/Target/Teak/TeakTargetMachine.cpp b/llvm/lib/Target/Teak/TeakTargetMachine.cpp index cc274b0f997..88a896f68ac 100644 --- a/llvm/lib/Target/Teak/TeakTargetMachine.cpp +++ b/llvm/lib/Target/Teak/TeakTargetMachine.cpp @@ -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 X(getTheTeakTarget()); +extern "C" void LLVMInitializeTeakTarget() +{ + RegisterTargetMachine X(getTheTeakTarget()); } \ No newline at end of file