mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-14 15:28:20 +00:00
Clean up HiPE prologue emission a bit and avoid signed arithmetic tricks.
No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175536 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1433,7 +1433,6 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
bool Is64Bit = STI.is64Bit();
|
bool Is64Bit = STI.is64Bit();
|
||||||
unsigned TlsReg, TlsOffset;
|
unsigned TlsReg, TlsOffset;
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
const X86Subtarget *ST = &MF.getTarget().getSubtarget<X86Subtarget>();
|
|
||||||
|
|
||||||
unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true);
|
unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true);
|
||||||
assert(!MF.getRegInfo().isLiveIn(ScratchReg) &&
|
assert(!MF.getRegInfo().isLiveIn(ScratchReg) &&
|
||||||
@@ -1441,8 +1440,8 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
|
|
||||||
if (MF.getFunction()->isVarArg())
|
if (MF.getFunction()->isVarArg())
|
||||||
report_fatal_error("Segmented stacks do not support vararg functions.");
|
report_fatal_error("Segmented stacks do not support vararg functions.");
|
||||||
if (!ST->isTargetLinux() && !ST->isTargetDarwin() &&
|
if (!STI.isTargetLinux() && !STI.isTargetDarwin() &&
|
||||||
!ST->isTargetWin32() && !ST->isTargetFreeBSD())
|
!STI.isTargetWin32() && !STI.isTargetFreeBSD())
|
||||||
report_fatal_error("Segmented stacks not supported on this platform.");
|
report_fatal_error("Segmented stacks not supported on this platform.");
|
||||||
|
|
||||||
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
|
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
|
||||||
@@ -1480,13 +1479,13 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
|
|
||||||
// Read the limit off the current stacklet off the stack_guard location.
|
// Read the limit off the current stacklet off the stack_guard location.
|
||||||
if (Is64Bit) {
|
if (Is64Bit) {
|
||||||
if (ST->isTargetLinux()) {
|
if (STI.isTargetLinux()) {
|
||||||
TlsReg = X86::FS;
|
TlsReg = X86::FS;
|
||||||
TlsOffset = 0x70;
|
TlsOffset = 0x70;
|
||||||
} else if (ST->isTargetDarwin()) {
|
} else if (STI.isTargetDarwin()) {
|
||||||
TlsReg = X86::GS;
|
TlsReg = X86::GS;
|
||||||
TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90.
|
TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90.
|
||||||
} else if (ST->isTargetFreeBSD()) {
|
} else if (STI.isTargetFreeBSD()) {
|
||||||
TlsReg = X86::FS;
|
TlsReg = X86::FS;
|
||||||
TlsOffset = 0x18;
|
TlsOffset = 0x18;
|
||||||
} else {
|
} else {
|
||||||
@@ -1502,16 +1501,16 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg)
|
BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg)
|
||||||
.addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg);
|
.addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg);
|
||||||
} else {
|
} else {
|
||||||
if (ST->isTargetLinux()) {
|
if (STI.isTargetLinux()) {
|
||||||
TlsReg = X86::GS;
|
TlsReg = X86::GS;
|
||||||
TlsOffset = 0x30;
|
TlsOffset = 0x30;
|
||||||
} else if (ST->isTargetDarwin()) {
|
} else if (STI.isTargetDarwin()) {
|
||||||
TlsReg = X86::GS;
|
TlsReg = X86::GS;
|
||||||
TlsOffset = 0x48 + 90*4;
|
TlsOffset = 0x48 + 90*4;
|
||||||
} else if (ST->isTargetWin32()) {
|
} else if (STI.isTargetWin32()) {
|
||||||
TlsReg = X86::FS;
|
TlsReg = X86::FS;
|
||||||
TlsOffset = 0x14; // pvArbitrary, reserved for application use
|
TlsOffset = 0x14; // pvArbitrary, reserved for application use
|
||||||
} else if (ST->isTargetFreeBSD()) {
|
} else if (STI.isTargetFreeBSD()) {
|
||||||
report_fatal_error("Segmented stacks not supported on FreeBSD i386.");
|
report_fatal_error("Segmented stacks not supported on FreeBSD i386.");
|
||||||
} else {
|
} else {
|
||||||
report_fatal_error("Segmented stacks not supported on this platform.");
|
report_fatal_error("Segmented stacks not supported on this platform.");
|
||||||
@@ -1523,10 +1522,10 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP)
|
BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP)
|
||||||
.addImm(1).addReg(0).addImm(-StackSize).addReg(0);
|
.addImm(1).addReg(0).addImm(-StackSize).addReg(0);
|
||||||
|
|
||||||
if (ST->isTargetLinux() || ST->isTargetWin32()) {
|
if (STI.isTargetLinux() || STI.isTargetWin32()) {
|
||||||
BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg)
|
BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg)
|
||||||
.addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg);
|
.addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg);
|
||||||
} else if (ST->isTargetDarwin()) {
|
} else if (STI.isTargetDarwin()) {
|
||||||
|
|
||||||
// TlsOffset doesn't fit into a mod r/m byte so we need an extra register
|
// TlsOffset doesn't fit into a mod r/m byte so we need an extra register
|
||||||
unsigned ScratchReg2;
|
unsigned ScratchReg2;
|
||||||
@@ -1632,19 +1631,18 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|||||||
void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
|
void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
|
||||||
const X86InstrInfo &TII = *TM.getInstrInfo();
|
const X86InstrInfo &TII = *TM.getInstrInfo();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
const uint64_t SlotSize = TM.getRegisterInfo()->getSlotSize();
|
const unsigned SlotSize = TM.getRegisterInfo()->getSlotSize();
|
||||||
const bool Is64Bit = STI.is64Bit();
|
const bool Is64Bit = STI.is64Bit();
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
// HiPE-specific values
|
// HiPE-specific values
|
||||||
const unsigned HipeLeafWords = 24;
|
const unsigned HipeLeafWords = 24;
|
||||||
const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5;
|
const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5;
|
||||||
const unsigned Guaranteed = HipeLeafWords * SlotSize;
|
const unsigned Guaranteed = HipeLeafWords * SlotSize;
|
||||||
const unsigned CallerStkArity =
|
unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ?
|
||||||
std::max<int>(0, MF.getFunction()->arg_size() - CCRegisteredArgs);
|
MF.getFunction()->arg_size() - CCRegisteredArgs : 0;
|
||||||
unsigned MaxStack =
|
unsigned MaxStack = MFI->getStackSize() + CallerStkArity*SlotSize + SlotSize;
|
||||||
MFI->getStackSize() + CallerStkArity * SlotSize + SlotSize;
|
|
||||||
|
|
||||||
assert(MF.getTarget().getSubtarget<X86Subtarget>().isTargetLinux() &&
|
assert(STI.isTargetLinux() &&
|
||||||
"HiPE prologue is only supported on Linux operating systems.");
|
"HiPE prologue is only supported on Linux operating systems.");
|
||||||
|
|
||||||
// Compute the largest caller's frame that is needed to fit the callees'
|
// Compute the largest caller's frame that is needed to fit the callees'
|
||||||
@@ -1660,31 +1658,37 @@ void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
|
|||||||
for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end();
|
for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end();
|
||||||
MBBI != MBBE; ++MBBI)
|
MBBI != MBBE; ++MBBI)
|
||||||
for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end();
|
for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end();
|
||||||
MI != ME; ++MI)
|
MI != ME; ++MI) {
|
||||||
if (MI->isCall()) {
|
if (!MI->isCall())
|
||||||
// Get callee operand.
|
continue;
|
||||||
const MachineOperand &MO = MI->getOperand(0);
|
|
||||||
const Function *F;
|
|
||||||
|
|
||||||
// Only take account of global function calls (no closures etc.).
|
// Get callee operand.
|
||||||
if (!MO.isGlobal()) continue;
|
const MachineOperand &MO = MI->getOperand(0);
|
||||||
if (!(F = dyn_cast<Function>(MO.getGlobal()))) continue;
|
|
||||||
|
|
||||||
// Do not update 'MaxStack' for primitive and built-in functions
|
// Only take account of global function calls (no closures etc.).
|
||||||
// (encoded with names either starting with "erlang."/"bif_" or not
|
if (!MO.isGlobal())
|
||||||
// having a ".", such as a simple <Module>.<Function>.<Arity>, or an
|
continue;
|
||||||
// "_", such as the BIF "suspend_0") as they are executed on another
|
|
||||||
// stack.
|
|
||||||
if ((F->getName().find("erlang.") != std::string::npos) ||
|
|
||||||
(F->getName().find("bif_") != std::string::npos)) continue;
|
|
||||||
if (F->getName().find_first_of("._") == std::string::npos)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const uint64_t CalleeStkArity =
|
const Function *F = dyn_cast<Function>(MO.getGlobal());
|
||||||
std::max<ssize_t>(0, F->arg_size() - CCRegisteredArgs);
|
if (!F)
|
||||||
MoreStackForCalls = std::max<int64_t>(
|
continue;
|
||||||
MoreStackForCalls, (HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
|
|
||||||
}
|
// Do not update 'MaxStack' for primitive and built-in functions
|
||||||
|
// (encoded with names either starting with "erlang."/"bif_" or not
|
||||||
|
// having a ".", such as a simple <Module>.<Function>.<Arity>, or an
|
||||||
|
// "_", such as the BIF "suspend_0") as they are executed on another
|
||||||
|
// stack.
|
||||||
|
if (F->getName().find("erlang.") != StringRef::npos ||
|
||||||
|
F->getName().find("bif_") != StringRef::npos ||
|
||||||
|
F->getName().find_first_of("._") == StringRef::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned CalleeStkArity =
|
||||||
|
F->arg_size() > CCRegisteredArgs ? F->arg_size()-CCRegisteredArgs : 0;
|
||||||
|
if (HipeLeafWords - 1 > CalleeStkArity)
|
||||||
|
MoreStackForCalls = std::max(MoreStackForCalls,
|
||||||
|
(HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
|
||||||
|
}
|
||||||
MaxStack += MoreStackForCalls;
|
MaxStack += MoreStackForCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user