mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-03 11:08:32 +00:00
Combine MovePCtoStack + POP32r into one instruction MOVPC32r so it can be moved if needed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45605 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d94b6a16fe
commit
0475ab58b8
@ -32,14 +32,14 @@ using namespace llvm;
|
|||||||
|
|
||||||
STATISTIC(EmittedInsts, "Number of machine instrs printed");
|
STATISTIC(EmittedInsts, "Number of machine instrs printed");
|
||||||
|
|
||||||
static std::string computePICLabel(unsigned FnNum,
|
static std::string getPICLabelString(unsigned FnNum,
|
||||||
const TargetAsmInfo *TAI,
|
const TargetAsmInfo *TAI,
|
||||||
const X86Subtarget* Subtarget) {
|
const X86Subtarget* Subtarget) {
|
||||||
std::string label;
|
std::string label;
|
||||||
if (Subtarget->isTargetDarwin())
|
if (Subtarget->isTargetDarwin())
|
||||||
label = "\"L" + utostr_32(FnNum) + "$pb\"";
|
label = "\"L" + utostr_32(FnNum) + "$pb\"";
|
||||||
else if (Subtarget->isTargetELF())
|
else if (Subtarget->isTargetELF())
|
||||||
label = ".Lllvm$" + utostr_32(FnNum) + "$piclabel";
|
label = ".Lllvm$" + utostr_32(FnNum) + "." + "$piclabel";
|
||||||
else
|
else
|
||||||
assert(0 && "Don't know how to print PIC label!\n");
|
assert(0 && "Don't know how to print PIC label!\n");
|
||||||
|
|
||||||
@ -318,8 +318,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
|
if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
|
||||||
O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
|
O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget);
|
||||||
<< "$pb\"";
|
|
||||||
} else {
|
} else {
|
||||||
if (GV->hasDLLImportLinkage()) {
|
if (GV->hasDLLImportLinkage()) {
|
||||||
O << "__imp_";
|
O << "__imp_";
|
||||||
@ -420,7 +419,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
|||||||
// popl %some_register
|
// popl %some_register
|
||||||
// addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
|
// addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
|
||||||
O << " + [.-"
|
O << " + [.-"
|
||||||
<< computePICLabel(getFunctionNumber(), TAI, Subtarget) << "]";
|
<< getPICLabelString(getFunctionNumber(), TAI, Subtarget) << "]";
|
||||||
|
|
||||||
if (isCallOp)
|
if (isCallOp)
|
||||||
O << "@PLT";
|
O << "@PLT";
|
||||||
@ -515,11 +514,11 @@ void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
|
|||||||
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
|
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
|
||||||
<< '_' << uid << '\n';
|
<< '_' << uid << '\n';
|
||||||
else
|
else
|
||||||
O << '-' << computePICLabel(getFunctionNumber(), TAI, Subtarget) << '\n';
|
O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
|
void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
|
||||||
std::string label = computePICLabel(getFunctionNumber(), TAI, Subtarget);
|
std::string label = getPICLabelString(getFunctionNumber(), TAI, Subtarget);
|
||||||
O << label << "\n" << label << ":";
|
O << label << "\n" << label << ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ namespace {
|
|||||||
return "X86 Machine Code Emitter";
|
return "X86 Machine Code Emitter";
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitInstruction(const MachineInstr &MI);
|
void emitInstruction(const MachineInstr &MI,
|
||||||
|
const TargetInstrDescriptor *Desc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
|
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
|
||||||
@ -112,8 +113,14 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
MBB != E; ++MBB) {
|
MBB != E; ++MBB) {
|
||||||
MCE.StartMachineBasicBlock(MBB);
|
MCE.StartMachineBasicBlock(MBB);
|
||||||
for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
|
for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
|
||||||
I != E; ++I)
|
I != E; ++I) {
|
||||||
emitInstruction(*I);
|
const TargetInstrDescriptor *Desc = I->getInstrDescriptor();
|
||||||
|
emitInstruction(*I, Desc);
|
||||||
|
// MOVPC32r is basically a call plus a pop instruction.
|
||||||
|
if (Desc->Opcode == X86::MOVPC32r)
|
||||||
|
emitInstruction(*I, &II->get(X86::POP32r));
|
||||||
|
NumEmitted++; // Keep track of the # of mi's emitted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (MCE.finishFunction(MF));
|
} while (MCE.finishFunction(MF));
|
||||||
|
|
||||||
@ -519,10 +526,8 @@ unsigned Emitter::determineREX(const MachineInstr &MI) {
|
|||||||
return REX;
|
return REX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emitter::emitInstruction(const MachineInstr &MI) {
|
void Emitter::emitInstruction(const MachineInstr &MI,
|
||||||
NumEmitted++; // Keep track of the # of mi's emitted
|
const TargetInstrDescriptor *Desc) {
|
||||||
|
|
||||||
const TargetInstrDescriptor *Desc = MI.getInstrDescriptor();
|
|
||||||
unsigned Opcode = Desc->Opcode;
|
unsigned Opcode = Desc->Opcode;
|
||||||
|
|
||||||
// Emit the repeat opcode prefix as needed.
|
// Emit the repeat opcode prefix as needed.
|
||||||
@ -587,8 +592,10 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
switch (Desc->TSFlags & X86II::FormMask) {
|
switch (Desc->TSFlags & X86II::FormMask) {
|
||||||
default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!");
|
default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!");
|
||||||
case X86II::Pseudo:
|
case X86II::Pseudo:
|
||||||
#ifndef NDEBUG
|
// Remember the current PC offset, this is the PIC relocation
|
||||||
|
// base address.
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
|
#ifndef NDEBUG
|
||||||
default:
|
default:
|
||||||
assert(0 && "psuedo instructions should be removed before code emission");
|
assert(0 && "psuedo instructions should be removed before code emission");
|
||||||
case TargetInstrInfo::INLINEASM:
|
case TargetInstrInfo::INLINEASM:
|
||||||
@ -607,13 +614,20 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
case X86::IMPLICIT_DEF_VR128:
|
case X86::IMPLICIT_DEF_VR128:
|
||||||
case X86::FP_REG_KILL:
|
case X86::FP_REG_KILL:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
case X86::MOVPC32r:
|
||||||
|
// This emits the "call" portion of this pseudo instruction.
|
||||||
|
MCE.emitByte(BaseOpcode);
|
||||||
|
emitConstant(0, sizeOfImm(Desc));
|
||||||
|
PICBase = MCE.getCurrentPCOffset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
CurOp = NumOps;
|
CurOp = NumOps;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X86II::RawFrm:
|
case X86II::RawFrm:
|
||||||
MCE.emitByte(BaseOpcode);
|
MCE.emitByte(BaseOpcode);
|
||||||
|
|
||||||
if (CurOp != NumOps) {
|
if (CurOp != NumOps) {
|
||||||
const MachineOperand &MO = MI.getOperand(CurOp++);
|
const MachineOperand &MO = MI.getOperand(CurOp++);
|
||||||
if (MO.isMachineBasicBlock()) {
|
if (MO.isMachineBasicBlock()) {
|
||||||
@ -631,11 +645,6 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
assert(0 && "Unknown RawFrm operand!");
|
assert(0 && "Unknown RawFrm operand!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the current PC offset, this is the PIC relocation
|
|
||||||
// base address.
|
|
||||||
if (Opcode == X86::MovePCtoStack)
|
|
||||||
PICBase = MCE.getCurrentPCOffset();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X86II::AddRegFrm:
|
case X86II::AddRegFrm:
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "X86InstrBuilder.h"
|
#include "X86InstrBuilder.h"
|
||||||
#include "X86ISelLowering.h"
|
#include "X86ISelLowering.h"
|
||||||
|
#include "X86MachineFunctionInfo.h"
|
||||||
#include "X86RegisterInfo.h"
|
#include "X86RegisterInfo.h"
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "X86TargetMachine.h"
|
#include "X86TargetMachine.h"
|
||||||
@ -988,25 +989,24 @@ SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
|
|||||||
assert(!Subtarget->is64Bit() && "X86-64 PIC uses RIP relative addressing");
|
assert(!Subtarget->is64Bit() && "X86-64 PIC uses RIP relative addressing");
|
||||||
if (!GlobalBaseReg) {
|
if (!GlobalBaseReg) {
|
||||||
// Insert the set of GlobalBaseReg into the first MBB of the function
|
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||||
MachineBasicBlock &FirstMBB = BB->getParent()->front();
|
MachineFunction *MF = BB->getParent();
|
||||||
|
MachineBasicBlock &FirstMBB = MF->front();
|
||||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||||
MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
|
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||||
unsigned PC = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
|
unsigned PC = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
|
||||||
|
|
||||||
const TargetInstrInfo *TII = TM.getInstrInfo();
|
const TargetInstrInfo *TII = TM.getInstrInfo();
|
||||||
// Operand of MovePCtoStack is completely ignored by asm printer. It's
|
// Operand of MovePCtoStack is completely ignored by asm printer. It's
|
||||||
// only used in JIT code emission as displacement to pc.
|
// only used in JIT code emission as displacement to pc.
|
||||||
BuildMI(FirstMBB, MBBI, TII->get(X86::MovePCtoStack)).addImm(0);
|
BuildMI(FirstMBB, MBBI, TII->get(X86::MOVPC32r), PC).addImm(0);
|
||||||
BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), PC);
|
|
||||||
|
|
||||||
// If we're using vanilla 'GOT' PIC style, we should use relative addressing
|
// If we're using vanilla 'GOT' PIC style, we should use relative addressing
|
||||||
// not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
|
// not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
|
||||||
if (TM.getRelocationModel() == Reloc::PIC_ &&
|
if (TM.getRelocationModel() == Reloc::PIC_ &&
|
||||||
Subtarget->isPICStyleGOT()) {
|
Subtarget->isPICStyleGOT()) {
|
||||||
GlobalBaseReg = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
|
GlobalBaseReg = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
|
||||||
BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg).
|
BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg)
|
||||||
addReg(PC).
|
.addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
|
||||||
addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
|
|
||||||
} else {
|
} else {
|
||||||
GlobalBaseReg = PC;
|
GlobalBaseReg = PC;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,9 @@ def IMPLICIT_DEF_GR32 : I<0, Pseudo, (outs GR32:$dst), (ins),
|
|||||||
// Nop
|
// Nop
|
||||||
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
|
def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
|
||||||
|
|
||||||
|
// PIC base
|
||||||
|
def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label),
|
||||||
|
"call\t$label\n\tpop{l}\t$reg", []>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Control Flow Instructions...
|
// Control Flow Instructions...
|
||||||
@ -408,9 +411,6 @@ def POPFD : I<0x9D, RawFrm, (outs), (ins), "popf", []>;
|
|||||||
let Defs = [ESP], Uses = [ESP, EFLAGS] in
|
let Defs = [ESP], Uses = [ESP, EFLAGS] in
|
||||||
def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
|
def PUSHFD : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
|
||||||
|
|
||||||
def MovePCtoStack : Ii32<0xE8, RawFrm, (outs), (ins piclabel:$label),
|
|
||||||
"call\t$label", []>;
|
|
||||||
|
|
||||||
let isTwoAddress = 1 in // GR32 = bswap GR32
|
let isTwoAddress = 1 in // GR32 = bswap GR32
|
||||||
def BSWAP32r : I<0xC8, AddRegFrm,
|
def BSWAP32r : I<0xC8, AddRegFrm,
|
||||||
(outs GR32:$dst), (ins GR32:$src),
|
(outs GR32:$dst), (ins GR32:$src),
|
||||||
|
@ -37,20 +37,20 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
|
|||||||
/// stack frame in bytes.
|
/// stack frame in bytes.
|
||||||
unsigned CalleeSavedFrameSize;
|
unsigned CalleeSavedFrameSize;
|
||||||
|
|
||||||
/// BytesToPopOnReturn - amount of bytes function pops on return.
|
/// BytesToPopOnReturn - Number of bytes function pops on return.
|
||||||
/// Used on windows platform for stdcall & fastcall name decoration
|
/// Used on windows platform for stdcall & fastcall name decoration
|
||||||
unsigned BytesToPopOnReturn;
|
unsigned BytesToPopOnReturn;
|
||||||
|
|
||||||
/// If the function requires additional name decoration, DecorationStyle holds
|
/// DecorationStyle - If the function requires additional name decoration,
|
||||||
/// the right way to do so.
|
/// DecorationStyle holds the right way to do so.
|
||||||
NameDecorationStyle DecorationStyle;
|
NameDecorationStyle DecorationStyle;
|
||||||
|
|
||||||
// FrameIndex for return slot.
|
/// ReturnAddrIndex - FrameIndex for return slot.
|
||||||
int ReturnAddrIndex;
|
int ReturnAddrIndex;
|
||||||
|
|
||||||
// Delta the ReturnAddr stack slot is moved
|
/// TailCallReturnAddrDelta - Delta the ReturnAddr stack slot is moved
|
||||||
// Used for creating an area before the register spill area on the stack
|
/// Used for creating an area before the register spill area on the stack
|
||||||
// the returnaddr can be savely move to this area
|
/// the returnaddr can be savely move to this area
|
||||||
int TailCallReturnAddrDelta;
|
int TailCallReturnAddrDelta;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -59,7 +59,7 @@ public:
|
|||||||
BytesToPopOnReturn(0),
|
BytesToPopOnReturn(0),
|
||||||
DecorationStyle(None),
|
DecorationStyle(None),
|
||||||
ReturnAddrIndex(0),
|
ReturnAddrIndex(0),
|
||||||
TailCallReturnAddrDelta(0){}
|
TailCallReturnAddrDelta(0) {}
|
||||||
|
|
||||||
X86MachineFunctionInfo(MachineFunction &MF) : ForceFramePointer(false),
|
X86MachineFunctionInfo(MachineFunction &MF) : ForceFramePointer(false),
|
||||||
CalleeSavedFrameSize(0),
|
CalleeSavedFrameSize(0),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user