diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp index 3ae5f8c308a..78f84249447 100644 --- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp @@ -306,29 +306,44 @@ 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); - if (MO.getTargetFlags()) + // %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("; closeP = true; - - switch(MO.getTargetFlags()) { - default: - llvm_unreachable("Unknown target flag on GV operand"); - 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 if ((MI->getOpcode() == Mips::ADDiu) && !MO.isReg() && !MO.isImm()) { + const MachineOperand &firstMO = MI->getOperand(opNum-1); + if (firstMO.getReg() == Mips::GP) + O << "%gp_rel("; else O << "%lo("; - break; - case MipsII::MO_ABS_HILO: - if (MI->getOpcode() == Mips::LUi) - O << "%hi("; - else - O << "%lo("; - break; + 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; + } } - + switch (MO.getType()) { case MachineOperand::MO_Register: diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index f2dec31d29b..ca72ff03dc7 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -322,6 +322,7 @@ 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); diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 261c421aa3e..710bc945ef2 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -488,6 +488,7 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { // FIXME there isn't actually debug info here DebugLoc dl = Op.getDebugLoc(); GlobalValue *GV = cast(Op)->getGlobal(); + SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32); if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { SDVTList VTs = DAG.getVTList(MVT::i32); @@ -496,20 +497,16 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { // %gp_rel relocation if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) { - SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, 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, 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 { - SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32, MipsII::MO_GOT); + } else { // Abicall relocations, TODO: make this cleaner. SDValue ResNode = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), GA, NULL, 0); // On functions and global targets not internal linked only @@ -687,7 +684,6 @@ 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 ArgLocs; @@ -796,11 +792,10 @@ 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(Callee)) - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy(), OpFlag); + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) - Callee = DAG.getTargetExternalSymbol(S->getSymbol(),getPointerTy(), OpFlag); + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); // MipsJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... @@ -831,7 +826,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 (IsPIC) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. int FI; diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 2f273ebce88..ebb9f8ab8be 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -130,38 +130,6 @@ 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;