home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OpenStep (Enterprise)
/
OpenStepENTCD.toast
/
OEDEV
/
GNUSRC.Z
/
next.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-12
|
3KB
|
110 lines
/* 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());
}
}