llvm.org GIT mirror llvm / aabe38b
Preliminary PIC JIT support for X86 (32-bit) / Darwin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45313 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 12 years ago
5 changed file(s) with 89 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
3636 const TargetData *TD;
3737 TargetMachine &TM;
3838 MachineCodeEmitter &MCE;
39 intptr_t PICBase;
3940 bool Is64BitMode;
41 bool IsPIC;
4042 public:
4143 static char ID;
4244 explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
4345 : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
44 MCE(mce), Is64BitMode(false) {}
46 MCE(mce), PICBase(0), Is64BitMode(false),
47 IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
4548 Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
4649 const X86InstrInfo &ii, const TargetData &td, bool is64)
4750 : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
48 MCE(mce), Is64BitMode(is64) {}
51 MCE(mce), PICBase(0), Is64BitMode(is64),
52 IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
4953
5054 bool runOnMachineFunction(MachineFunction &MF);
5155
5761
5862 private:
5963 void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
60 void emitPCRelativeValue(intptr_t Address);
61 void emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub);
62 void emitGlobalAddressForPtr(GlobalValue *GV, unsigned Reloc,
63 int Disp = 0, unsigned PCAdj = 0);
64 void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
64 void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
65 int Disp = 0, intptr_t PCAdj = 0,
66 bool DoesntNeedStub = false, bool isPIC = false);
67 void emitExternalSymbolAddress(const char *ES, unsigned Reloc,
68 bool isPIC = false);
6569 void emitConstPoolAddress(unsigned CPI, unsigned Reloc, int Disp = 0,
66 unsigned PCAdj = 0);
67 void emitJumpTableAddress(unsigned JTI, unsigned Reloc, unsigned PCAdj = 0);
70 intptr_t PCAdj = 0, bool isPIC = false);
71 void emitJumpTableAddress(unsigned JTI, unsigned Reloc,
72 intptr_t PCAdj = 0, bool isPIC = false);
6873
6974 void emitDisplacementField(const MachineOperand *RelocOp, int DispVal,
70 unsigned PCAdj = 0);
75 intptr_t PCAdj = 0);
7176
7277 void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField);
7378 void emitSIBByte(unsigned SS, unsigned Index, unsigned Base);
7580
7681 void emitMemModRMByte(const MachineInstr &MI,
7782 unsigned Op, unsigned RegOpcodeField,
78 unsigned PCAdj = 0);
83 intptr_t PCAdj = 0);
7984
8085 unsigned getX86RegNum(unsigned RegNo);
8186 bool isX86_64ExtendedReg(const MachineOperand &MO);
112117 } while (MCE.finishFunction(MF));
113118
114119 return false;
115 }
116
117 /// emitPCRelativeValue - Emit a PC relative address.
118 ///
119 void Emitter::emitPCRelativeValue(intptr_t Address) {
120 MCE.emitWordLE(Address-MCE.getCurrentPCValue()-4);
121120 }
122121
123122 /// emitPCRelativeBlockAddress - This method keeps track of the information
132131 MCE.emitWordLE(0);
133132 }
134133
135 /// emitGlobalAddressForCall - Emit the specified address to the code stream
136 /// assuming this is part of a function call, which is PC relative.
137 ///
138 void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub) {
139 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
140 X86::reloc_pcrel_word, GV, 0,
141 DoesntNeedStub));
142 MCE.emitWordLE(0);
143 }
144
145134 /// emitGlobalAddress - Emit the specified address to the code stream assuming
146135 /// this is part of a "take the address of a global" instruction.
147136 ///
148 void Emitter::emitGlobalAddressForPtr(GlobalValue *GV, unsigned Reloc,
149 int Disp /* = 0 */,
150 unsigned PCAdj /* = 0 */) {
137 void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
138 int Disp /* = 0 */, intptr_t PCAdj /* = 0 */,
139 bool DoesntNeedStub /* = false */,
140 bool isPIC /* = false */) {
141 if (isPIC)
142 PCAdj += PICBase;
151143 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
152 GV, PCAdj));
144 GV, PCAdj, DoesntNeedStub));
153145 if (Reloc == X86::reloc_absolute_dword)
154146 MCE.emitWordLE(0);
155147 MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
158150 /// emitExternalSymbolAddress - Arrange for the address of an external symbol to
159151 /// be emitted to the current location in the function, and allow it to be PC
160152 /// relative.
161 void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
153 void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc,
154 bool isPIC /* = false */) {
155 intptr_t PCAdj = isPIC ? PICBase : 0;
162156 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
163 Reloc, ES));
157 Reloc, ES, PCAdj));
164158 if (Reloc == X86::reloc_absolute_dword)
165159 MCE.emitWordLE(0);
166160 MCE.emitWordLE(0);
171165 /// relative.
172166 void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
173167 int Disp /* = 0 */,
174 unsigned PCAdj /* = 0 */) {
168 intptr_t PCAdj /* = 0 */,
169 bool isPIC /* = false */) {
170 if (isPIC)
171 PCAdj += PICBase;
175172 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
176173 Reloc, CPI, PCAdj));
177174 if (Reloc == X86::reloc_absolute_dword)
183180 /// be emitted to the current location in the function, and allow it to be PC
184181 /// relative.
185182 void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
186 unsigned PCAdj /* = 0 */) {
183 intptr_t PCAdj /* = 0 */,
184 bool isPIC /* = false */) {
185 if (isPIC)
186 PCAdj += PICBase;
187187 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
188188 Reloc, JTI, PCAdj));
189189 if (Reloc == X86::reloc_absolute_dword)
225225 }
226226
227227 void Emitter::emitDisplacementField(const MachineOperand *RelocOp,
228 int DispVal, unsigned PCAdj) {
228 int DispVal, intptr_t PCAdj) {
229229 // If this is a simple integer displacement that doesn't require a relocation,
230230 // emit it now.
231231 if (!RelocOp) {
240240 // But it's probably not beneficial.
241241 // 89 05 00 00 00 00 mov %eax,0(%rip) # PC-relative
242242 // 89 04 25 00 00 00 00 mov %eax,0x0 # Absolute
243 unsigned rt= Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
244 emitGlobalAddressForPtr(RelocOp->getGlobal(), rt,
245 RelocOp->getOffset(), PCAdj);
243 unsigned rt= Is64BitMode ? X86::reloc_pcrel_word
244 : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
245 emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
246 PCAdj, false, IsPIC);
246247 } else if (RelocOp->isConstantPoolIndex()) {
247248 // Must be in 64-bit mode.
248249 emitConstPoolAddress(RelocOp->getConstantPoolIndex(), X86::reloc_pcrel_word,
249 RelocOp->getOffset(), PCAdj);
250 RelocOp->getOffset(), PCAdj, IsPIC);
250251 } else if (RelocOp->isJumpTableIndex()) {
251252 // Must be in 64-bit mode.
252253 emitJumpTableAddress(RelocOp->getJumpTableIndex(), X86::reloc_pcrel_word,
253 PCAdj);
254 PCAdj, IsPIC);
254255 } else {
255256 assert(0 && "Unknown value to relocate!");
256257 }
258259
259260 void Emitter::emitMemModRMByte(const MachineInstr &MI,
260261 unsigned Op, unsigned RegOpcodeField,
261 unsigned PCAdj) {
262 intptr_t PCAdj) {
262263 const MachineOperand &Op3 = MI.getOperand(Op+3);
263264 int DispVal = 0;
264265 const MachineOperand *DispForReloc = 0;
604605 bool NeedStub = Is64BitMode ||
605606 Opcode == X86::TAILJMPd ||
606607 Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
607 emitGlobalAddressForCall(MO.getGlobal(), !NeedStub);
608 emitGlobalAddress(MO.getGlobal(), X86::reloc_pcrel_word,
609 0, 0, !NeedStub, false);
608610 } else if (MO.isExternalSymbol()) {
609 emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
611 emitExternalSymbolAddress(MO.getSymbolName(),
612 X86::reloc_pcrel_word, false);
610613 } else if (MO.isImmediate()) {
611614 emitConstant(MO.getImm(), sizeOfImm(Desc));
612615 } else {
613616 assert(0 && "Unknown RawFrm operand!");
614617 }
615618 }
619
620 // Remember the current PC offset, this is the PIC relocation
621 // base address.
622 if (Opcode == X86::MovePCtoStack)
623 PICBase = MCE.getCurrentPCOffset();
616624 break;
617625
618626 case X86II::AddRegFrm:
624632 if (MO1.isImmediate())
625633 emitConstant(MO1.getImm(), Size);
626634 else {
627 unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
635 unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
636 : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
628637 if (Opcode == X86::MOV64ri)
629638 rt = X86::reloc_absolute_dword; // FIXME: add X86II flag?
630639 if (MO1.isGlobalAddress())
631 emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
640 emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), false, IsPIC);
632641 else if (MO1.isExternalSymbol())
633 emitExternalSymbolAddress(MO1.getSymbolName(), rt);
642 emitExternalSymbolAddress(MO1.getSymbolName(), rt, IsPIC);
634643 else if (MO1.isConstantPoolIndex())
635 emitConstPoolAddress(MO1.getConstantPoolIndex(), rt);
644 emitConstPoolAddress(MO1.getConstantPoolIndex(), rt, IsPIC);
636645 else if (MO1.isJumpTableIndex())
637 emitJumpTableAddress(MO1.getJumpTableIndex(), rt);
646 emitJumpTableAddress(MO1.getJumpTableIndex(), rt, IsPIC);
638647 }
639648 }
640649 break;
667676 break;
668677
669678 case X86II::MRMSrcMem: {
670 unsigned PCAdj = (CurOp+5 != NumOps) ? sizeOfImm(Desc) : 0;
679 intptr_t PCAdj = (CurOp+5 != NumOps) ? sizeOfImm(Desc) : 0;
671680
672681 MCE.emitByte(BaseOpcode);
673682 emitMemModRMByte(MI, CurOp+1, getX86RegNum(MI.getOperand(CurOp).getReg()),
693702 emitConstant(MO1.getImm(), Size);
694703 else {
695704 unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
696 : X86::reloc_absolute_word;
705 : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
697706 if (Opcode == X86::MOV64ri32)
698707 rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
699708 if (MO1.isGlobalAddress())
700 emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
709 emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), false, IsPIC);
701710 else if (MO1.isExternalSymbol())
702 emitExternalSymbolAddress(MO1.getSymbolName(), rt);
711 emitExternalSymbolAddress(MO1.getSymbolName(), rt, IsPIC);
703712 else if (MO1.isConstantPoolIndex())
704 emitConstPoolAddress(MO1.getConstantPoolIndex(), rt);
713 emitConstPoolAddress(MO1.getConstantPoolIndex(), rt, IsPIC);
705714 else if (MO1.isJumpTableIndex())
706 emitJumpTableAddress(MO1.getJumpTableIndex(), rt);
715 emitJumpTableAddress(MO1.getJumpTableIndex(), rt, IsPIC);
707716 }
708717 }
709718 break;
712721 case X86II::MRM2m: case X86II::MRM3m:
713722 case X86II::MRM4m: case X86II::MRM5m:
714723 case X86II::MRM6m: case X86II::MRM7m: {
715 unsigned PCAdj = (CurOp+4 != NumOps) ?
724 intptr_t PCAdj = (CurOp+4 != NumOps) ?
716725 (MI.getOperand(CurOp+4).isImmediate() ? sizeOfImm(Desc) : 4) : 0;
717726
718727 MCE.emitByte(BaseOpcode);
727736 emitConstant(MO.getImm(), Size);
728737 else {
729738 unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
730 : X86::reloc_absolute_word;
739 : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
731740 if (Opcode == X86::MOV64mi32)
732741 rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
733742 if (MO.isGlobalAddress())
734 emitGlobalAddressForPtr(MO.getGlobal(), rt, MO.getOffset());
743 emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), false, IsPIC);
735744 else if (MO.isExternalSymbol())
736 emitExternalSymbolAddress(MO.getSymbolName(), rt);
745 emitExternalSymbolAddress(MO.getSymbolName(), rt, IsPIC);
737746 else if (MO.isConstantPoolIndex())
738 emitConstPoolAddress(MO.getConstantPoolIndex(), rt);
747 emitConstPoolAddress(MO.getConstantPoolIndex(), rt, IsPIC);
739748 else if (MO.isJumpTableIndex())
740 emitJumpTableAddress(MO.getJumpTableIndex(), rt);
749 emitJumpTableAddress(MO.getJumpTableIndex(), rt, IsPIC);
741750 }
742751 }
743752 break;
436436 case X86::reloc_pcrel_word: {
437437 // PC relative relocation, add the relocated value to the value already in
438438 // memory, after we adjust it for where the PC is.
439 ResultPtr = ResultPtr-(intptr_t)RelocPos-4-MR->getConstantVal();
439 ResultPtr = ResultPtr -(intptr_t)RelocPos - 4 - MR->getConstantVal();
440 *((unsigned*)RelocPos) += (unsigned)ResultPtr;
441 break;
442 }
443 case X86::reloc_picrel_word: {
444 // PIC base relative relocation, add the relocated value to the value
445 // already in memory, after we adjust it for where the PIC base is.
446 ResultPtr = ResultPtr - ((intptr_t)Function + MR->getConstantVal());
440447 *((unsigned*)RelocPos) += (unsigned)ResultPtr;
441448 break;
442449 }
2222 // the value already in memory, after we adjust it for where the PC is.
2323 reloc_pcrel_word = 0,
2424
25 // reloc_picrel_word - PIC base relative relocation, add the relocated
26 // value to the value already in memory, after we adjust it for where the
27 // PIC base is.
28 reloc_picrel_word = 1,
29
2530 // reloc_absolute_word, reloc_absolute_dword - Absolute relocation, just
2631 // add the relocated value to the value already in memory.
27 reloc_absolute_word = 1,
28 reloc_absolute_dword = 2
32 reloc_absolute_word = 2,
33 reloc_absolute_dword = 3
2934 };
3035 }
3136 }
117117 FrameInfo(TargetFrameInfo::StackGrowsDown,
118118 Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
119119 InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
120 DefRelocModel = getRelocationModel();
120121 if (getRelocationModel() == Reloc::Default)
121122 if (Subtarget.isTargetDarwin() || Subtarget.isTargetCygMing())
122123 setRelocationModel(Reloc::DynamicNoPIC);
169170 bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
170171 bool DumpAsm, MachineCodeEmitter &MCE) {
171172 // FIXME: Move this to TargetJITInfo!
172 setRelocationModel(Reloc::Static);
173 if (DefRelocModel == Reloc::Default)
174 setRelocationModel(Reloc::Static);
173175 Subtarget.setPICStyle(PICStyle::None);
174176
175177 // JIT cannot ensure globals are placed in the lower 4G of address.
3333 X86JITInfo JITInfo;
3434 X86TargetLowering TLInfo;
3535 X86ELFWriterInfo ELFWriterInfo;
36 Reloc::Model DefRelocModel; // Reloc model before it's overridden.
3637
3738 protected:
3839 virtual const TargetAsmInfo *createTargetAsmInfo() const;