Minor fixes.

Added ConstantPool support.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53951 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes
2008-07-23 16:01:50 +00:00
parent fcf0e86bf2
commit 92e87f2379
5 changed files with 54 additions and 28 deletions

View File

@@ -86,7 +86,7 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::RET, MVT::Other, Custom);
setOperationAction(ISD::JumpTable, MVT::i32, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::f32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
@@ -234,10 +234,14 @@ AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC)
return VReg; return VReg;
} }
// A address must be loaded from a small section if its size is less than the
// small section size threshold. Data in this section must be addressed using
// gp_rel operator.
bool MipsTargetLowering::IsInSmallSection(unsigned Size) {
return (Size > 0 && (Size <= Subtarget->getSSectionThreshold()));
}
// Discover if this global address can be placed into small data/bss section. // Discover if this global address can be placed into small data/bss section.
// This should happen for globals with size less than small section size
// threshold in no abicall environments. Data in this section must be addressed
// using gp_rel operator.
bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV) bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
{ {
const TargetData *TD = getTargetData(); const TargetData *TD = getTargetData();
@@ -258,10 +262,7 @@ bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
return false; return false;
} }
if (Size > 0 && (Size <= Subtarget->getSSectionThreshold())) return IsInSmallSection(Size);
return true;
return false;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -352,8 +353,24 @@ LowerJumpTable(SDOperand Op, SelectionDAG &DAG)
SDOperand MipsTargetLowering:: SDOperand MipsTargetLowering::
LowerConstantPool(SDOperand Op, SelectionDAG &DAG) LowerConstantPool(SDOperand Op, SelectionDAG &DAG)
{ {
assert(0 && "ConstantPool not implemented for MIPS."); SDOperand ResNode;
return SDOperand(); // Not reached ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
Constant *C = N->getConstVal();
SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
// gp_rel relocation
if (!Subtarget->hasABICall() &&
IsInSmallSection(getTargetData()->getABITypeSize(C->getType()))) {
SDOperand GPRelNode = DAG.getNode(MipsISD::GPRel, MVT::i32, CP);
SDOperand GOT = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i32);
ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode);
} else { // %hi/%lo relocation
SDOperand HiPart = DAG.getNode(MipsISD::Hi, MVT::i32, CP);
SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, CP);
ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
}
return ResNode;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@@ -61,8 +61,6 @@ namespace llvm {
{ {
// FrameIndex for return slot. // FrameIndex for return slot.
int ReturnAddrIndex; int ReturnAddrIndex;
// const MipsSubtarget &MipsSubTarget;
public: public:
explicit MipsTargetLowering(MipsTargetMachine &TM); explicit MipsTargetLowering(MipsTargetMachine &TM);
@@ -87,6 +85,7 @@ namespace llvm {
SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall, SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
unsigned CallingConv, SelectionDAG &DAG); unsigned CallingConv, SelectionDAG &DAG);
bool IsGlobalInSmallSection(GlobalValue *GV); bool IsGlobalInSmallSection(GlobalValue *GV);
bool IsInSmallSection(unsigned Size);
// Lower Operand specifics // Lower Operand specifics
SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);

View File

@@ -553,17 +553,24 @@ def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
def : Pat<(MipsJmpLink CPURegs:$dst), def : Pat<(MipsJmpLink CPURegs:$dst),
(JALR CPURegs:$dst)>; (JALR CPURegs:$dst)>;
// GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable // hi/lo relocs
def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
//def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)), def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>; (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>; def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
//def : Pat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)), def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
(ADDiu CPURegs:$hi, tjumptable:$lo)>; (ADDiu CPURegs:$hi, tjumptable:$lo)>;
def : Pat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
def : Pat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)),
(ADDiu CPURegs:$hi, tconstpool:$lo)>;
// gp_rel relocs
def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
(ADDiu CPURegs:$gp, tglobaladdr:$in)>; (ADDiu CPURegs:$gp, tglobaladdr:$in)>;
def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
(ADDiu CPURegs:$gp, tconstpool:$in)>;
// Mips does not have "not", so we expand our way // Mips does not have "not", so we expand our way
def : Pat<(not CPURegs:$in), def : Pat<(not CPURegs:$in),

View File

@@ -19,7 +19,7 @@ using namespace llvm;
MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM):
ELFTargetAsmInfo(TM) { ELFTargetAsmInfo(TM) {
MipsTM = &TM; Subtarget = &TM.getSubtarget<MipsSubtarget>();
AlignmentIsInBytes = false; AlignmentIsInBytes = false;
COMMDirectiveTakesAlignment = true; COMMDirectiveTakesAlignment = true;
@@ -34,21 +34,25 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM):
BSSSection = "\t.section\t.bss"; BSSSection = "\t.section\t.bss";
LCOMMDirective = "\t.lcomm\t"; LCOMMDirective = "\t.lcomm\t";
CStringSection = ".rodata.str"; CStringSection = ".rodata.str";
FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4";
if (!TM.getSubtarget<MipsSubtarget>().hasABICall()) if (!Subtarget->hasABICall()) {
JumpTableDirective = "\t.word\t"; JumpTableDirective = "\t.word\t";
else SmallDataSection = getNamedSection("\t.sdata", SectionFlags::Writeable);
SmallBSSSection = getNamedSection("\t.sbss", SectionFlags::Writeable |
SectionFlags::BSS);
} else
JumpTableDirective = "\t.gpword\t"; JumpTableDirective = "\t.gpword\t";
SmallDataSection = getNamedSection("\t.sdata", SectionFlags::Writeable);
SmallBSSSection = getNamedSection("\t.sbss",
SectionFlags::Writeable | SectionFlags::BSS);
} }
SectionKind::Kind SectionKind::Kind
MipsTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { MipsTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
SectionKind::Kind K = ELFTargetAsmInfo::SectionKindForGlobal(GV); SectionKind::Kind K = ELFTargetAsmInfo::SectionKindForGlobal(GV);
if (Subtarget->hasABICall())
return K;
if (K != SectionKind::Data && K != SectionKind::BSS && if (K != SectionKind::Data && K != SectionKind::BSS &&
K != SectionKind::RODataMergeConst) K != SectionKind::RODataMergeConst)
return K; return K;
@@ -56,8 +60,7 @@ MipsTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
if (isa<GlobalVariable>(GV)) { if (isa<GlobalVariable>(GV)) {
const TargetData *TD = ETM->getTargetData(); const TargetData *TD = ETM->getTargetData();
unsigned Size = TD->getABITypeSize(GV->getType()->getElementType()); unsigned Size = TD->getABITypeSize(GV->getType()->getElementType());
unsigned Threshold = unsigned Threshold = Subtarget->getSSectionThreshold();
MipsTM->getSubtarget<MipsSubtarget>().getSSectionThreshold();
if (Size > 0 && Size <= Threshold) { if (Size > 0 && Size <= Threshold) {
if (K == SectionKind::BSS) if (K == SectionKind::BSS)

View File

@@ -14,11 +14,12 @@
#ifndef MIPSTARGETASMINFO_H #ifndef MIPSTARGETASMINFO_H
#define MIPSTARGETASMINFO_H #define MIPSTARGETASMINFO_H
#include "llvm/Target/TargetAsmInfo.h" #include "MipsSubtarget.h"
#include "llvm/Target/ELFTargetAsmInfo.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "llvm/Target/ELFTargetAsmInfo.h"
namespace llvm { namespace llvm {
@@ -36,8 +37,7 @@ namespace llvm {
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
private: private:
const MipsTargetMachine *MipsTM; const MipsSubtarget *Subtarget;
}; };
} // namespace llvm } // namespace llvm