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:
// 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);
// %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
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);
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();
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;
// 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, ...
// 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;