mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 13:46:13 +00:00
fix some assumptions that pointers can only be 32-bits. With this, we can
now compile: static unsigned long X; void test1() { X = 0; } into: _test1: lis r2, ha16(_X) li r3, 0 stw r3, lo16(_X)(r2) blr Totally amazing :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28839 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
956f43c310
commit
059ca0f5b7
@ -128,7 +128,10 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
|
||||
|
||||
// RET must be custom lowered, to meet ABI requirements
|
||||
setOperationAction(ISD::RET , MVT::Other, Custom);
|
||||
|
||||
@ -583,94 +586,94 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
|
||||
MVT::ValueType PtrVT = Op.getValueType();
|
||||
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
|
||||
Constant *C = CP->get();
|
||||
SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment());
|
||||
SDOperand Zero = DAG.getConstant(0, MVT::i32);
|
||||
SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
|
||||
SDOperand Zero = DAG.getConstant(0, PtrVT);
|
||||
|
||||
const TargetMachine &TM = DAG.getTarget();
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, CPI, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, CPI, Zero);
|
||||
|
||||
// If this is a non-darwin platform, we don't support non-static relo models
|
||||
// yet.
|
||||
if (TM.getRelocationModel() == Reloc::Static ||
|
||||
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
|
||||
// Generate non-pic code that has direct accesses to the constant pool.
|
||||
// The address of the global is just (hi(&g)+lo(&g)).
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero);
|
||||
return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
}
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero);
|
||||
if (TM.getRelocationModel() == Reloc::PIC) {
|
||||
// With PIC, the first instruction is actually "GR+hi(&G)".
|
||||
Hi = DAG.getNode(ISD::ADD, MVT::i32,
|
||||
DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi);
|
||||
Hi = DAG.getNode(ISD::ADD, PtrVT,
|
||||
DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
|
||||
}
|
||||
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero);
|
||||
Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
return Lo;
|
||||
}
|
||||
|
||||
static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
|
||||
MVT::ValueType PtrVT = Op.getValueType();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
|
||||
SDOperand Zero = DAG.getConstant(0, MVT::i32);
|
||||
SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
|
||||
SDOperand Zero = DAG.getConstant(0, PtrVT);
|
||||
|
||||
const TargetMachine &TM = DAG.getTarget();
|
||||
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, JTI, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, JTI, Zero);
|
||||
|
||||
// If this is a non-darwin platform, we don't support non-static relo models
|
||||
// yet.
|
||||
if (TM.getRelocationModel() == Reloc::Static ||
|
||||
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
|
||||
// Generate non-pic code that has direct accesses to the constant pool.
|
||||
// The address of the global is just (hi(&g)+lo(&g)).
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero);
|
||||
return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
}
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero);
|
||||
if (TM.getRelocationModel() == Reloc::PIC) {
|
||||
// With PIC, the first instruction is actually "GR+hi(&G)".
|
||||
Hi = DAG.getNode(ISD::ADD, MVT::i32,
|
||||
Hi = DAG.getNode(ISD::ADD, PtrVT,
|
||||
DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi);
|
||||
}
|
||||
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero);
|
||||
Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
return Lo;
|
||||
}
|
||||
|
||||
static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
MVT::ValueType PtrVT = Op.getValueType();
|
||||
GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
|
||||
GlobalValue *GV = GSDN->getGlobal();
|
||||
SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset());
|
||||
SDOperand Zero = DAG.getConstant(0, MVT::i32);
|
||||
SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset());
|
||||
SDOperand Zero = DAG.getConstant(0, PtrVT);
|
||||
|
||||
const TargetMachine &TM = DAG.getTarget();
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, GA, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, GA, Zero);
|
||||
|
||||
// If this is a non-darwin platform, we don't support non-static relo models
|
||||
// yet.
|
||||
if (TM.getRelocationModel() == Reloc::Static ||
|
||||
!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
|
||||
// Generate non-pic code that has direct accesses to globals.
|
||||
// The address of the global is just (hi(&g)+lo(&g)).
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero);
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero);
|
||||
return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
}
|
||||
|
||||
SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero);
|
||||
if (TM.getRelocationModel() == Reloc::PIC) {
|
||||
// With PIC, the first instruction is actually "GR+hi(&G)".
|
||||
Hi = DAG.getNode(ISD::ADD, MVT::i32,
|
||||
DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi);
|
||||
Hi = DAG.getNode(ISD::ADD, PtrVT,
|
||||
DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
|
||||
}
|
||||
|
||||
SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero);
|
||||
Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo);
|
||||
Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
|
||||
|
||||
if (!GV->hasWeakLinkage() && !GV->hasLinkOnceLinkage() &&
|
||||
(!GV->isExternal() || GV->hasNotBeenReadFromBytecode()))
|
||||
@ -678,7 +681,7 @@ static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
|
||||
// If the global is weak or external, we have to go through the lazy
|
||||
// resolution stub.
|
||||
return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0));
|
||||
return DAG.getLoad(PtrVT, DAG.getEntryNode(), Lo, DAG.getSrcValue(0));
|
||||
}
|
||||
|
||||
static SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
|
||||
|
@ -105,6 +105,13 @@ def RLDICR : MDForm_1<30, 1,
|
||||
|
||||
|
||||
let isLoad = 1, PPC970_Unit = 2 in {
|
||||
def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
|
||||
"lwa $rT, $DS($rA)", LdStLWA,
|
||||
[]>, isPPC64, PPC970_DGroup_Cracked;
|
||||
def LD : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
|
||||
"ld $rT, $DS($rA)", LdStLD,
|
||||
[]>, isPPC64;
|
||||
|
||||
def LWAX : XForm_1<31, 341, (ops G8RC:$rD, memrr:$src),
|
||||
"lwax $rD, $src", LdStLHA,
|
||||
[(set G8RC:$rD, (sextload xaddr:$src, i32))]>, isPPC64,
|
||||
@ -113,23 +120,18 @@ def LDX : XForm_1<31, 21, (ops G8RC:$rD, memrr:$src),
|
||||
"ldx $rD, $src", LdStLD,
|
||||
[(set G8RC:$rD, (load xaddr:$src))]>, isPPC64;
|
||||
}
|
||||
|
||||
|
||||
// DS-Form instructions. Load/Store instructions available in PPC-64
|
||||
//
|
||||
let isLoad = 1, PPC970_Unit = 2 in {
|
||||
def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
|
||||
"lwa $rT, $DS($rA)", LdStLWA,
|
||||
[]>, isPPC64, PPC970_DGroup_Cracked;
|
||||
def LD : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
|
||||
"ld $rT, $DS($rA)", LdStLD,
|
||||
[]>, isPPC64;
|
||||
}
|
||||
let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
|
||||
def STD : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
|
||||
"std $rT, $DS($rA)", LdStSTD,
|
||||
[]>, isPPC64;
|
||||
|
||||
def STDX : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
||||
"stdx $rS, $rA, $rB", LdStSTD,
|
||||
[]>, isPPC64, PPC970_DGroup_Cracked;
|
||||
def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
||||
"stdux $rS, $rA, $rB", LdStSTD,
|
||||
[]>, isPPC64;
|
||||
|
||||
// STD_32/STDX_32 - Just like STD/STDX, but uses a '32-bit' input register.
|
||||
def STD_32 : DSForm_2<62, 0, (ops GPRC:$rT, memrix:$dst),
|
||||
"std $rT, $dst", LdStSTD,
|
||||
@ -138,13 +140,6 @@ def STDX_32 : XForm_8<31, 149, (ops GPRC:$rT, memrr:$dst),
|
||||
"stdx $rT, $dst", LdStSTD,
|
||||
[(PPCstd_32 GPRC:$rT, xaddr:$dst)]>, isPPC64,
|
||||
PPC970_DGroup_Cracked;
|
||||
|
||||
def STDX : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
||||
"stdx $rS, $rA, $rB", LdStSTD,
|
||||
[]>, isPPC64, PPC970_DGroup_Cracked;
|
||||
def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
|
||||
"stdux $rS, $rA, $rB", LdStSTD,
|
||||
[]>, isPPC64;
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,13 +183,13 @@ def s16immX4 : Operand<i32> { // Multiply imm by 4 before printing.
|
||||
def target : Operand<OtherVT> {
|
||||
let PrintMethod = "printBranchOperand";
|
||||
}
|
||||
def calltarget : Operand<i32> {
|
||||
def calltarget : Operand<iPTR> {
|
||||
let PrintMethod = "printCallOperand";
|
||||
}
|
||||
def aaddr : Operand<i32> {
|
||||
def aaddr : Operand<iPTR> {
|
||||
let PrintMethod = "printAbsAddrOperand";
|
||||
}
|
||||
def piclabel: Operand<i32> {
|
||||
def piclabel: Operand<iPTR> {
|
||||
let PrintMethod = "printPICLabel";
|
||||
}
|
||||
def symbolHi: Operand<i32> {
|
||||
@ -202,27 +202,27 @@ def crbitm: Operand<i8> {
|
||||
let PrintMethod = "printcrbitm";
|
||||
}
|
||||
// Address operands
|
||||
def memri : Operand<i32> {
|
||||
def memri : Operand<iPTR> {
|
||||
let PrintMethod = "printMemRegImm";
|
||||
let NumMIOperands = 2;
|
||||
let MIOperandInfo = (ops i32imm, GPRC);
|
||||
}
|
||||
def memrr : Operand<i32> {
|
||||
def memrr : Operand<iPTR> {
|
||||
let PrintMethod = "printMemRegReg";
|
||||
let NumMIOperands = 2;
|
||||
let MIOperandInfo = (ops GPRC, GPRC);
|
||||
}
|
||||
def memrix : Operand<i32> { // memri where the imm is shifted 2 bits.
|
||||
def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits.
|
||||
let PrintMethod = "printMemRegImmShifted";
|
||||
let NumMIOperands = 2;
|
||||
let MIOperandInfo = (ops i32imm, GPRC);
|
||||
}
|
||||
|
||||
// Define PowerPC specific addressing mode.
|
||||
def iaddr : ComplexPattern<i32, 2, "SelectAddrImm", []>;
|
||||
def xaddr : ComplexPattern<i32, 2, "SelectAddrIdx", []>;
|
||||
def xoaddr : ComplexPattern<i32, 2, "SelectAddrIdxOnly",[]>;
|
||||
def ixaddr : ComplexPattern<i32, 2, "SelectAddrImmShift", []>; // "std"
|
||||
def iaddr : ComplexPattern<iPTR, 2, "SelectAddrImm", []>;
|
||||
def xaddr : ComplexPattern<iPTR, 2, "SelectAddrIdx", []>;
|
||||
def xoaddr : ComplexPattern<iPTR, 2, "SelectAddrIdxOnly",[]>;
|
||||
def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", []>; // "std"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PowerPC Instruction Predicate Definitions.
|
||||
@ -957,6 +957,5 @@ def : Pat<(f64 (extload iaddr:$src, f32)),
|
||||
def : Pat<(f64 (extload xaddr:$src, f32)),
|
||||
(FMRSD (LFSX xaddr:$src))>;
|
||||
|
||||
|
||||
include "PPCInstrAltivec.td"
|
||||
include "PPCInstr64Bit.td"
|
||||
|
Loading…
Reference in New Issue
Block a user