import CLabel ( CLabel, pprCLabel, externallyVisibleCLabel,
labelDynamic, mkAsmTempLabel, entryLblToInfoLbl )
+#if HAVE_SUBSECTIONS_VIA_SYMBOLS
+import CLabel ( mkDeadStripPreventer )
+#endif
import Panic ( panic )
import Unique ( pprUnique )
pprNatCmmTop (CmmProc info lbl params blocks) =
pprSectionHeader Text $$
(if not (null info)
- then vcat (map pprData info)
- $$ pprLabel (entryLblToInfoLbl lbl)
+ then
+#if HAVE_SUBSECTIONS_VIA_SYMBOLS
+ pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
+ <> char ':' $$
+#endif
+ vcat (map pprData info) $$
+ pprLabel (entryLblToInfoLbl lbl)
else empty) $$
(case blocks of
[] -> empty
(if null info then pprLabel lbl else empty) $$
-- the first block doesn't get a label:
vcat (map pprInstr instrs) $$
- vcat (map pprBasicBlock rest))
+ vcat (map pprBasicBlock rest)
+ )
+#if HAVE_SUBSECTIONS_VIA_SYMBOLS
+ -- If we are using the .subsections_via_symbols directive
+ -- (available on recent versions of Darwin),
+ -- we have to make sure that there is some kind of reference
+ -- from the entry code to a label on the _top_ of of the info table,
+ -- so that the linker will not think it is unreferenced and dead-strip
+ -- it. That's why the label is called a DeadStripPreventer (_dsp).
+ $$ if not (null info)
+ then text "\t.long "
+ <+> pprCLabel_asm (entryLblToInfoLbl lbl)
+ <+> char '-'
+ <+> pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
+ else empty
+#endif
pprBasicBlock :: NatBasicBlock -> Doc
-- -----------------------------------------------------------------------------
-- pprData: print a 'CmmStatic'
-#if defined(linux_TARGET_OS)
-#if defined(powerpc_TARGET_ARCH) || defined(i386_TARGET_ARCH)
- -- Hack to make dynamic linking work
-pprSectionHeader ReadOnlyData
- | not opt_PIC && not opt_Static
- = pprSectionHeader Data
-#endif
-#endif
-
pprSectionHeader Text
= ptext
IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
- ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
+ ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 2"),
SLIT(".section .rodata\n\t.align 2"))
,))))
+pprSectionHeader RelocatableReadOnlyData
+ = ptext
+ IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
+ ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
+ ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
+ ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
+ SLIT(".data\n\t.align 2"))
+ ,))))
pprSectionHeader UninitialisedData
= ptext
IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")
ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
]
+pprInstr (FETCHGOT reg)
+ = vcat [ ptext SLIT("\tcall 1f"),
+ hcat [ ptext SLIT("1:\tpopl\t"), pprReg I32 reg ],
+ hcat [ ptext SLIT("\taddl\t$_GLOBAL_OFFSET_TABLE_+(.-1b), "),
+ pprReg I32 reg ]
+ ]
-- Emit code to make hi_reg:lo_reg be the 64-bit product of hi_reg and lo_reg
pprInstr_imul64 hi_reg lo_reg