+bool Emitter::gvNeedsNonLazyPtr(const GlobalValue *GV) {
+ // For Darwin, simulate the linktime GOT by using the same non-lazy-pointer
+ // mechanism as 32-bit mode.
+ return (!Is64BitMode || TM.getSubtarget<X86Subtarget>().isTargetDarwin()) &&
+ TM.getSubtarget<X86Subtarget>().GVRequiresExtraLoad(GV, TM, false);
+}
+
+void Emitter::emitDisplacementField(const MachineOperand *RelocOp,
+ int DispVal, intptr_t PCAdj) {
+ // If this is a simple integer displacement that doesn't require a relocation,
+ // emit it now.
+ if (!RelocOp) {
+ emitConstant(DispVal, 4);
+ return;
+ }
+
+ // Otherwise, this is something that requires a relocation. Emit it as such
+ // now.
+ if (RelocOp->isGlobal()) {
+ // In 64-bit static small code model, we could potentially emit absolute.
+ // But it's probably not beneficial.
+ // 89 05 00 00 00 00 mov %eax,0(%rip) # PC-relative
+ // 89 04 25 00 00 00 00 mov %eax,0x0 # Absolute
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+ : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
+ bool NeedStub = isa<Function>(RelocOp->getGlobal());
+ bool Indirect = gvNeedsNonLazyPtr(RelocOp->getGlobal());
+ emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
+ PCAdj, NeedStub, Indirect);
+ } else if (RelocOp->isCPI()) {
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
+ emitConstPoolAddress(RelocOp->getIndex(), rt,
+ RelocOp->getOffset(), PCAdj);
+ } else if (RelocOp->isJTI()) {
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
+ emitJumpTableAddress(RelocOp->getIndex(), rt, PCAdj);
+ } else {
+ assert(0 && "Unknown value to relocate!");
+ }
+}
+