mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 07:17:36 +00:00
Hexagon: Add constant extender support framework.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176358 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -2800,7 +2800,26 @@ isConditionalStore (const MachineInstr* MI) const {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
|
||||
return((F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask);
|
||||
}
|
||||
|
||||
/// immediateExtend - Changes the instruction in place to one using an immediate
|
||||
/// extender.
|
||||
void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const {
|
||||
assert((isExtendable(MI)||isConstExtended(MI)) &&
|
||||
"Instruction must be extendable");
|
||||
// Find which operand is extendable.
|
||||
short ExtOpNum = getCExtOpNum(MI);
|
||||
MachineOperand &MO = MI->getOperand(ExtOpNum);
|
||||
// This needs to be something we understand.
|
||||
assert((MO.isMBB() || MO.isImm()) &&
|
||||
"Branch with unknown extendable field type");
|
||||
// Mark given operand as extended.
|
||||
MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
|
||||
}
|
||||
|
||||
DFAPacketizer *HexagonInstrInfo::
|
||||
CreateTargetScheduleState(const TargetMachine *TM,
|
||||
@@ -2827,3 +2846,155 @@ bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
|
||||
|
||||
// Constant extenders are allowed only for V4 and above.
|
||||
if (!Subtarget.hasV4TOps())
|
||||
return false;
|
||||
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
|
||||
if (isExtended) // Instruction must be extended.
|
||||
return true;
|
||||
|
||||
unsigned isExtendable = (F >> HexagonII::ExtendablePos)
|
||||
& HexagonII::ExtendableMask;
|
||||
if (!isExtendable)
|
||||
return false;
|
||||
|
||||
short ExtOpNum = getCExtOpNum(MI);
|
||||
const MachineOperand &MO = MI->getOperand(ExtOpNum);
|
||||
// Use MO operand flags to determine if MO
|
||||
// has the HMOTF_ConstExtended flag set.
|
||||
if (MO.getTargetFlags() && HexagonII::HMOTF_ConstExtended)
|
||||
return true;
|
||||
// If this is a Machine BB address we are talking about, and it is
|
||||
// not marked as extended, say so.
|
||||
if (MO.isMBB())
|
||||
return false;
|
||||
|
||||
// We could be using an instruction with an extendable immediate and shoehorn
|
||||
// a global address into it. If it is a global address it will be constant
|
||||
// extended. We do this for COMBINE.
|
||||
// We currently only handle isGlobal() because it is the only kind of
|
||||
// object we are going to end up with here for now.
|
||||
// In the future we probably should add isSymbol(), etc.
|
||||
if (MO.isGlobal() || MO.isSymbol())
|
||||
return true;
|
||||
|
||||
// If the extendable operand is not 'Immediate' type, the instruction should
|
||||
// have 'isExtended' flag set.
|
||||
assert(MO.isImm() && "Extendable operand must be Immediate type");
|
||||
|
||||
int MinValue = getMinValue(MI);
|
||||
int MaxValue = getMaxValue(MI);
|
||||
int ImmValue = MO.getImm();
|
||||
|
||||
return (ImmValue < MinValue || ImmValue > MaxValue);
|
||||
}
|
||||
|
||||
// Returns true if a particular operand is extendable for an instruction.
|
||||
bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
|
||||
unsigned short OperandNum) const {
|
||||
// Constant extenders are allowed only for V4 and above.
|
||||
if (!Subtarget.hasV4TOps())
|
||||
return false;
|
||||
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
|
||||
return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
|
||||
== OperandNum;
|
||||
}
|
||||
|
||||
// Returns Operand Index for the constant extended instruction.
|
||||
unsigned short HexagonInstrInfo::getCExtOpNum(const MachineInstr *MI) const {
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
|
||||
}
|
||||
|
||||
// Returns the min value that doesn't need to be extended.
|
||||
int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const {
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
|
||||
& HexagonII::ExtentSignedMask;
|
||||
unsigned bits = (F >> HexagonII::ExtentBitsPos)
|
||||
& HexagonII::ExtentBitsMask;
|
||||
|
||||
if (isSigned) // if value is signed
|
||||
return -1 << (bits - 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the max value that doesn't need to be extended.
|
||||
int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const {
|
||||
const uint64_t F = MI->getDesc().TSFlags;
|
||||
unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
|
||||
& HexagonII::ExtentSignedMask;
|
||||
unsigned bits = (F >> HexagonII::ExtentBitsPos)
|
||||
& HexagonII::ExtentBitsMask;
|
||||
|
||||
if (isSigned) // if value is signed
|
||||
return ~(-1 << (bits - 1));
|
||||
else
|
||||
return ~(-1 << bits);
|
||||
}
|
||||
|
||||
// Returns true if an instruction can be converted into a non-extended
|
||||
// equivalent instruction.
|
||||
bool HexagonInstrInfo::NonExtEquivalentExists (const MachineInstr *MI) const {
|
||||
|
||||
short NonExtOpcode;
|
||||
// Check if the instruction has a register form that uses register in place
|
||||
// of the extended operand, if so return that as the non-extended form.
|
||||
if (Hexagon::getRegForm(MI->getOpcode()) >= 0)
|
||||
return true;
|
||||
|
||||
if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
|
||||
// Check addressing mode and retreive non-ext equivalent instruction.
|
||||
|
||||
switch (getAddrMode(MI)) {
|
||||
case HexagonII::Absolute :
|
||||
// Load/store with absolute addressing mode can be converted into
|
||||
// base+offset mode.
|
||||
NonExtOpcode = Hexagon::getBasedWithImmOffset(MI->getOpcode());
|
||||
break;
|
||||
case HexagonII::BaseImmOffset :
|
||||
// Load/store with base+offset addressing mode can be converted into
|
||||
// base+register offset addressing mode. However left shift operand should
|
||||
// be set to 0.
|
||||
NonExtOpcode = Hexagon::getBaseWithRegOffset(MI->getOpcode());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (NonExtOpcode < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns opcode of the non-extended equivalent instruction.
|
||||
short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
|
||||
|
||||
// Check if the instruction has a register form that uses register in place
|
||||
// of the extended operand, if so return that as the non-extended form.
|
||||
short NonExtOpcode = Hexagon::getRegForm(MI->getOpcode());
|
||||
if (NonExtOpcode >= 0)
|
||||
return NonExtOpcode;
|
||||
|
||||
if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
|
||||
// Check addressing mode and retreive non-ext equivalent instruction.
|
||||
switch (getAddrMode(MI)) {
|
||||
case HexagonII::Absolute :
|
||||
return Hexagon::getBasedWithImmOffset(MI->getOpcode());
|
||||
case HexagonII::BaseImmOffset :
|
||||
return Hexagon::getBaseWithRegOffset(MI->getOpcode());
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -180,6 +180,17 @@ public:
|
||||
unsigned getImmExtForm(const MachineInstr* MI) const;
|
||||
unsigned getNormalBranchForm(const MachineInstr* MI) const;
|
||||
|
||||
|
||||
void immediateExtend(MachineInstr *MI) const;
|
||||
bool isConstExtended(MachineInstr *MI) const;
|
||||
unsigned getAddrMode(const MachineInstr* MI) const;
|
||||
bool isOperandExtended(const MachineInstr *MI,
|
||||
unsigned short OperandNum) const;
|
||||
unsigned short getCExtOpNum(const MachineInstr *MI) const;
|
||||
int getMinValue(const MachineInstr *MI) const;
|
||||
int getMaxValue(const MachineInstr *MI) const;
|
||||
bool NonExtEquivalentExists (const MachineInstr *MI) const;
|
||||
short getNonExtOpcode(const MachineInstr *MI) const;
|
||||
private:
|
||||
int getMatchingCondBranchOpcode(int Opc, bool sense) const;
|
||||
|
||||
|
||||
@@ -17,35 +17,36 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#define DEBUG_TYPE "packets"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/DFAPacketizer.h"
|
||||
#include "llvm/CodeGen/LatencyPriorityQueue.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/CodeGen/LatencyPriorityQueue.h"
|
||||
#include "llvm/CodeGen/SchedulerRegistry.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace llvm;
|
||||
@@ -257,7 +258,7 @@ void HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) {
|
||||
|
||||
bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) {
|
||||
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
|
||||
assert(QII->isExtended(MI) &&
|
||||
assert((QII->isExtended(MI) || QII->isConstExtended(MI)) &&
|
||||
"Should only be called for constant extended instructions");
|
||||
MachineFunction *MF = MI->getParent()->getParent();
|
||||
MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
|
||||
@@ -3196,7 +3197,7 @@ HexagonPacketizerList::addToPacket(MachineInstr *MI) {
|
||||
MachineInstr *nvjMI = MII;
|
||||
assert(ResourceTracker->canReserveResources(MI));
|
||||
ResourceTracker->reserveResources(MI);
|
||||
if (QII->isExtended(MI) &&
|
||||
if ((QII->isExtended(MI) || QII->isConstExtended(MI)) &&
|
||||
!tryAllocateResourcesForConstExt(MI)) {
|
||||
endPacket(MBB, MI);
|
||||
ResourceTracker->reserveResources(MI);
|
||||
@@ -3216,7 +3217,7 @@ HexagonPacketizerList::addToPacket(MachineInstr *MI) {
|
||||
&& (!tryAllocateResourcesForConstExt(nvjMI)
|
||||
|| !ResourceTracker->canReserveResources(nvjMI)))
|
||||
|| // For non-extended instruction, no need to allocate extra 4 bytes.
|
||||
(!QII->isExtended(nvjMI) &&
|
||||
(!QII->isExtended(nvjMI) &&
|
||||
!ResourceTracker->canReserveResources(nvjMI)))
|
||||
{
|
||||
endPacket(MBB, MI);
|
||||
@@ -3232,7 +3233,7 @@ HexagonPacketizerList::addToPacket(MachineInstr *MI) {
|
||||
CurrentPacketMIs.push_back(MI);
|
||||
CurrentPacketMIs.push_back(nvjMI);
|
||||
} else {
|
||||
if ( QII->isExtended(MI)
|
||||
if ( (QII->isExtended(MI) || QII->isConstExtended(MI))
|
||||
&& ( !tryAllocateResourcesForConstExt(MI)
|
||||
|| !ResourceTracker->canReserveResources(MI)))
|
||||
{
|
||||
|
||||
@@ -154,6 +154,28 @@ namespace HexagonII {
|
||||
|
||||
// *** The code above must match HexagonInstrFormat*.td *** //
|
||||
|
||||
// Hexagon specific MO operand flag mask.
|
||||
enum HexagonMOTargetFlagVal {
|
||||
//===------------------------------------------------------------------===//
|
||||
// Hexagon Specific MachineOperand flags.
|
||||
MO_NO_FLAG,
|
||||
|
||||
HMOTF_ConstExtended = 1,
|
||||
|
||||
/// MO_PCREL - On a symbol operand, indicates a PC-relative relocation
|
||||
/// Used for computing a global address for PIC compilations
|
||||
MO_PCREL,
|
||||
|
||||
/// MO_GOT - Indicates a GOT-relative relocation
|
||||
MO_GOT,
|
||||
|
||||
// Low or high part of a symbol.
|
||||
MO_LO16, MO_HI16,
|
||||
|
||||
// Offset from the base of the SDA.
|
||||
MO_GPREL
|
||||
};
|
||||
|
||||
} // End namespace HexagonII.
|
||||
|
||||
} // End namespace llvm.
|
||||
|
||||
Reference in New Issue
Block a user