mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Insert instructions to the entry basic block which initializes the global
pointer register. This is the first of the series of patches which clean up the way global pointer register is used. The patches will make the following improvements: - Make $gp an allocatable temporary register rather than reserving it. - Use a virtual register as the global pointer register and let the register allocator decide which register to assign to it or whether spill/reloads are needed. - Make sure $gp is valid at the entry of a called function, which is necessary for functions using lazy binding. - Remove the need for emitting .cprestore and .cpload directives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156671 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b08174c0b1
commit
27ba61df9f
@ -126,20 +126,13 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
|
||||
unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
|
||||
bool FixGlobalBaseReg = MipsFI->globalBaseRegFixed();
|
||||
|
||||
if (Subtarget.isABI_O32() && FixGlobalBaseReg)
|
||||
// $gp is the global base register.
|
||||
V0 = V1 = GlobalBaseReg;
|
||||
else {
|
||||
const TargetRegisterClass *RC;
|
||||
RC = Subtarget.isABI_N64() ?
|
||||
(const TargetRegisterClass*)&Mips::CPU64RegsRegClass :
|
||||
(const TargetRegisterClass*)&Mips::CPURegsRegClass;
|
||||
const TargetRegisterClass *RC = Subtarget.isABI_N64() ?
|
||||
(const TargetRegisterClass*)&Mips::CPU64RegsRegClass :
|
||||
(const TargetRegisterClass*)&Mips::CPURegsRegClass;
|
||||
|
||||
V0 = RegInfo.createVirtualRegister(RC);
|
||||
V1 = RegInfo.createVirtualRegister(RC);
|
||||
}
|
||||
V0 = RegInfo.createVirtualRegister(RC);
|
||||
V1 = RegInfo.createVirtualRegister(RC);
|
||||
|
||||
if (Subtarget.isABI_N64()) {
|
||||
MF.getRegInfo().addLiveIn(Mips::T9_64);
|
||||
@ -154,7 +147,10 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0).addReg(Mips::T9_64);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
} else if (MF.getTarget().getRelocationModel() == Reloc::Static) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MF.getTarget().getRelocationModel() == Reloc::Static) {
|
||||
// Set global register to __gnu_local_gp.
|
||||
//
|
||||
// lui $v0, %hi(__gnu_local_gp)
|
||||
@ -163,27 +159,48 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
|
||||
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
|
||||
} else {
|
||||
MF.getRegInfo().addLiveIn(Mips::T9);
|
||||
MBB.addLiveIn(Mips::T9);
|
||||
|
||||
if (Subtarget.isABI_N32()) {
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// addu $v1, $v0, $t9
|
||||
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
} else if (!MipsFI->globalBaseRegFixed()) {
|
||||
assert(Subtarget.isABI_O32());
|
||||
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::SETGP2), GlobalBaseReg)
|
||||
.addReg(Mips::T9);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MF.getRegInfo().addLiveIn(Mips::T9);
|
||||
MBB.addLiveIn(Mips::T9);
|
||||
|
||||
if (Subtarget.isABI_N32()) {
|
||||
// lui $v0, %hi(%neg(%gp_rel(fname)))
|
||||
// addu $v1, $v0, $t9
|
||||
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
|
||||
const GlobalValue *FName = MF.getFunction();
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
|
||||
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(Subtarget.isABI_O32());
|
||||
|
||||
// For O32 ABI, the following instruction sequence is emitted to initialize
|
||||
// the global base register:
|
||||
//
|
||||
// 0. lui $2, %hi(_gp_disp)
|
||||
// 1. addiu $2, $2, %lo(_gp_disp)
|
||||
// 2. addu $globalbasereg, $2, $t9
|
||||
//
|
||||
// We emit only the last instruction here.
|
||||
//
|
||||
// GNU linker requires that the first two instructions appear at the beginning
|
||||
// of a funtion and no instructions be inserted before or between them.
|
||||
// The two instructions are emitted during lowering to MC layer in order to
|
||||
// avoid any reordering.
|
||||
//
|
||||
// Register $2 (Mips::V0) is added to the list of live-in registers to ensure
|
||||
// the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
|
||||
// reads it.
|
||||
MF.getRegInfo().addLiveIn(Mips::V0);
|
||||
MBB.addLiveIn(Mips::V0);
|
||||
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
|
||||
.addReg(Mips::V0).addReg(Mips::T9);
|
||||
}
|
||||
|
||||
bool MipsDAGToDAGISel::ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI,
|
||||
|
@ -43,8 +43,8 @@ entry:
|
||||
; STATICGP: lui $[[R0:[0-9]+]], %hi(__gnu_local_gp)
|
||||
; STATICGP: addiu $[[GP:[0-9]+]], $[[R0]], %lo(__gnu_local_gp)
|
||||
; STATICGP: lw ${{[0-9]+}}, %gottprel(t2)($[[GP]])
|
||||
; STATIC: lui $gp, %hi(__gnu_local_gp)
|
||||
; STATIC: addiu $gp, $gp, %lo(__gnu_local_gp)
|
||||
; STATIC: lui $[[R0:[0-9]+]], %hi(__gnu_local_gp)
|
||||
; STATIC: addiu ${{[a-z0-9]+}}, $[[R0]], %lo(__gnu_local_gp)
|
||||
; STATIC: rdhwr $3, $29
|
||||
; STATIC: lw $[[R0:[0-9]+]], %gottprel(t2)($gp)
|
||||
; STATIC: addu $[[R1:[0-9]+]], $3, $[[R0]]
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux %s -o - | elf-dump --dump-section-data | FileCheck %s
|
||||
; DISABLED: llc -filetype=obj -mtriple mipsel-unknown-linux %s -o - | elf-dump --dump-section-data | FileCheck %s
|
||||
; RUN: false
|
||||
; XFAIL: *
|
||||
|
||||
; FIXME: use assembler instead of llc when it becomes available.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user