home *** CD-ROM | disk | FTP | other *** search
- /* next.c: Functions for NeXT as target machine for GNU C compiler. */
-
- /* Note that the include below means that we can't debug routines in
- i386.c when running on a COFF system. */
-
- #include "i386/i386.c"
- #include "next/nextstep.c"
-
- void
- machopic_output_stub (file, symb, stub)
- FILE *file;
- const char *symb, *stub;
- {
- unsigned int length;
- char *binder_name, *symbol_name, *lazy_ptr_name;
- static int label = 0;
- label += 1;
-
- length = strlen(stub);
- binder_name = alloca(length + 32);
- GEN_BINDER_NAME_FOR_STUB(binder_name, stub, length);
-
- length = strlen(symb);
- symbol_name = alloca(length + 32);
- GEN_SYMBOL_NAME_FOR_SYMBOL(symbol_name, symb, length);
-
- lazy_ptr_name = alloca(length + 32);
- GEN_LAZY_PTR_NAME_FOR_SYMBOL(lazy_ptr_name, symb, length);
-
- if (MACHOPIC_PURE)
- machopic_picsymbol_stub_section ();
- else
- machopic_symbol_stub_section ();
-
- fprintf (file, "%s:\n", stub);
- fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
-
- if (MACHOPIC_PURE)
- {
- fprintf (file, "\tcall LPC$%d\nLPC$%d:\tpopl %%eax\n", label, label);
- fprintf (file, "\tmovl %s-LPC$%d(%%eax),%%edx\n", lazy_ptr_name, label);
- fprintf (file, "\tjmp %%edx\n");
- }
- else
- {
- fprintf (file, "\tjmp *%s\n", lazy_ptr_name);
- }
-
- fprintf (file, "%s:\n", binder_name);
-
- if (MACHOPIC_PURE)
- {
- fprintf (file, "\tlea %s-LPC$%d(%%eax),%%eax\n", lazy_ptr_name, label);
- fprintf (file, "\tpushl %%eax\n");
- }
- else
- {
- fprintf (file, "\t pushl $%s\n", lazy_ptr_name);
- }
-
- fprintf (file, "\tjmp dyld_stub_binding_helper\n");
-
- machopic_lazy_symbol_ptr_section ();
- fprintf (file, "%s:\n", lazy_ptr_name);
- fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
- fprintf (file, "\t.long %s\n", binder_name);
- }
-
- i386_finalize_machopic()
- {
- extern int current_function_uses_pic_offset_table;
- int const_double = const_double_used();
-
- if (PIC_OFFSET_TABLE_REGNUM >= FIRST_PSEUDO_REGISTER
- && regno_reg_rtx [PIC_OFFSET_TABLE_REGNUM])
- pic_offset_table_rtx = regno_reg_rtx [PIC_OFFSET_TABLE_REGNUM];
-
- if (!current_function_uses_pic_offset_table)
- {
- current_function_uses_pic_offset_table =
- profile_flag
- | profile_block_flag
- | get_pool_size()
- | current_function_uses_const_pool
- | const_double_used ();
-
- if (current_function_uses_pic_offset_table) {
- rtx first_insn = next_real_insn (get_insns());
-
- if (!first_insn)
- return;
-
- emit_insn_before(gen_rtx(SET, VOIDmode,
- pic_offset_table_rtx,
- gen_rtx(PC, VOIDmode)),
- first_insn);
-
- emit_insn_after(gen_rtx(USE, VOIDmode,
- pic_offset_table_rtx),
- get_last_insn());
- }
- }
- else if (const_double)
- {
- emit_insn_after(gen_rtx(USE, VOIDmode,
- pic_offset_table_rtx),
- get_last_insn());
- }
- }
-