forked from OSchip/llvm-project
Reapply 80278
Add MO flags to simplify the printing of relocations. Remove the support for printing large code model relocs (which aren't supported anyway). llvm-svn: 80691
This commit is contained in:
parent
d51896311d
commit
0f20a5b338
|
@ -306,44 +306,27 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
|||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
|
||||
bool closeP = false;
|
||||
bool isPIC = (TM.getRelocationModel() == Reloc::PIC_);
|
||||
bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
|
||||
|
||||
// %hi and %lo used on mips gas to load global addresses on
|
||||
// static code. %got is used to load global addresses when
|
||||
// using PIC_. %call16 is used to load direct call targets
|
||||
// on PIC_ and small code size. %call_lo and %call_hi load
|
||||
// direct call targets on PIC_ and large code size.
|
||||
if (MI->getOpcode() == Mips::LUi && !MO.isReg() && !MO.isImm()) {
|
||||
if ((isPIC) && (isCodeLarge))
|
||||
O << "%call_hi(";
|
||||
else
|
||||
O << "%hi(";
|
||||
if (MO.getTargetFlags())
|
||||
closeP = true;
|
||||
} else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isReg() && !MO.isImm()) {
|
||||
const MachineOperand &firstMO = MI->getOperand(opNum-1);
|
||||
if (firstMO.getReg() == Mips::GP)
|
||||
O << "%gp_rel(";
|
||||
|
||||
switch(MO.getTargetFlags()) {
|
||||
case MipsII::MO_GPREL: O << "%gp_rel("; break;
|
||||
case MipsII::MO_GOT_CALL: O << "%call16("; break;
|
||||
case MipsII::MO_GOT:
|
||||
if (MI->getOpcode() == Mips::LW)
|
||||
O << "%got(";
|
||||
else
|
||||
O << "%lo(";
|
||||
closeP = true;
|
||||
} else if ((isPIC) && (MI->getOpcode() == Mips::LW) &&
|
||||
(!MO.isReg()) && (!MO.isImm())) {
|
||||
const MachineOperand &firstMO = MI->getOperand(opNum-1);
|
||||
const MachineOperand &lastMO = MI->getOperand(opNum+1);
|
||||
if ((firstMO.isReg()) && (lastMO.isReg())) {
|
||||
if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() == Mips::GP)
|
||||
&& (!isCodeLarge))
|
||||
O << "%call16(";
|
||||
else if ((firstMO.getReg() != Mips::T9) && (lastMO.getReg() == Mips::GP))
|
||||
O << "%got(";
|
||||
else if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() != Mips::GP)
|
||||
&& (isCodeLarge))
|
||||
O << "%call_lo(";
|
||||
closeP = true;
|
||||
}
|
||||
break;
|
||||
case MipsII::MO_ABS_HILO:
|
||||
if (MI->getOpcode() == Mips::LUi)
|
||||
O << "%hi(";
|
||||
else
|
||||
O << "%lo(";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (MO.getType())
|
||||
{
|
||||
case MachineOperand::MO_Register:
|
||||
|
|
|
@ -322,7 +322,6 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) {
|
|||
/// be loaded with 3 instructions.
|
||||
case MipsISD::JmpLink: {
|
||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||
//bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
|
||||
SDValue Chain = Node->getOperand(0);
|
||||
SDValue Callee = Node->getOperand(1);
|
||||
SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
|
||||
|
|
|
@ -488,7 +488,6 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
|
|||
// FIXME there isn't actually debug info here
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
|
||||
|
||||
if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
|
||||
SDVTList VTs = DAG.getVTList(MVT::i32);
|
||||
|
@ -497,16 +496,22 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
|
|||
|
||||
// %gp_rel relocation
|
||||
if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 0,
|
||||
MipsII::MO_GPREL);
|
||||
SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
|
||||
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
|
||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode);
|
||||
}
|
||||
// %hi/%lo relocation
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 0,
|
||||
MipsII::MO_ABS_HILO);
|
||||
SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GA, 1);
|
||||
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GA);
|
||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo);
|
||||
|
||||
} else { // Abicall relocations, TODO: make this cleaner.
|
||||
} else {
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 0,
|
||||
MipsII::MO_GOT);
|
||||
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
|
||||
DAG.getEntryNode(), GA, NULL, 0);
|
||||
// On functions and global targets not internal linked only
|
||||
|
@ -535,15 +540,17 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG)
|
|||
SDValue HiPart;
|
||||
// FIXME there isn't actually debug info here
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
|
||||
unsigned char OpFlag = IsPIC ? MipsII::MO_GOT : MipsII::MO_ABS_HILO;
|
||||
|
||||
EVT PtrVT = Op.getValueType();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
|
||||
|
||||
if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
|
||||
SDVTList VTs = DAG.getVTList(MVT::i32);
|
||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag);
|
||||
|
||||
if (IsPIC) {
|
||||
SDValue Ops[] = { JTI };
|
||||
HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, Ops, 1);
|
||||
HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1);
|
||||
} else // Emit Load from Global Pointer
|
||||
HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, NULL, 0);
|
||||
|
||||
|
@ -559,7 +566,8 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
|
|||
SDValue ResNode;
|
||||
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
|
||||
Constant *C = N->getConstVal();
|
||||
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
|
||||
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
|
||||
MipsII::MO_ABS_HILO);
|
||||
// FIXME there isn't actually debug info here
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
|
@ -684,6 +692,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
|
||||
|
||||
// Analyze operands of the call, assigning locations to each operand.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
|
@ -792,10 +801,13 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
|
||||
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
|
||||
// node so that legalize doesn't hack it.
|
||||
unsigned char OpFlag = IsPIC ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG;
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(),
|
||||
getPointerTy(), 0, OpFlag);
|
||||
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
|
||||
Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
|
||||
getPointerTy(), OpFlag);
|
||||
|
||||
// MipsJmpLink = #chain, #target_address, #opt_in_flags...
|
||||
// = Chain, Callee, Reg#1, Reg#2, ...
|
||||
|
@ -826,7 +838,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||
// Create a stack location to hold GP when PIC is used. This stack
|
||||
// location is used on function prologue to save GP and also after all
|
||||
// emited CALL's to restore GP.
|
||||
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
|
||||
if (IsPIC) {
|
||||
// Function can have an arbitrary number of calls, so
|
||||
// hold the LastArgStackLoc with the biggest offset.
|
||||
int FI;
|
||||
|
|
|
@ -130,6 +130,38 @@ namespace Mips {
|
|||
}
|
||||
}
|
||||
|
||||
/// MipsII - This namespace holds all of the target specific flags that
|
||||
/// instruction info tracks.
|
||||
///
|
||||
namespace MipsII {
|
||||
/// Target Operand Flag enum.
|
||||
enum TOF {
|
||||
//===------------------------------------------------------------------===//
|
||||
// Mips Specific MachineOperand flags.
|
||||
|
||||
MO_NO_FLAG = 0,
|
||||
|
||||
/// MO_GOT - Represents the offset into the global offset table at which
|
||||
/// the address the relocation entry symbol resides during execution.
|
||||
MO_GOT = 1,
|
||||
|
||||
/// MO_GOT_CALL - Represents the offset into the global offset table at
|
||||
/// which the address of a call site relocation entry symbol resides
|
||||
/// during execution. This is different from the above since this flag
|
||||
/// can only be present in call instructions.
|
||||
MO_GOT_CALL = 2,
|
||||
|
||||
/// MO_GPREL - Represents the offset from the current gp value to be used
|
||||
/// for the relocatable object file being produced.
|
||||
MO_GPREL = 3,
|
||||
|
||||
/// MO_ABS_HILO - Represents the hi or low part of an absolute symbol
|
||||
/// address.
|
||||
MO_ABS_HILO = 4
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
class MipsInstrInfo : public TargetInstrInfoImpl {
|
||||
MipsTargetMachine &TM;
|
||||
const MipsRegisterInfo RI;
|
||||
|
|
Loading…
Reference in New Issue