home *** CD-ROM | disk | FTP | other *** search
- /* next.c: Functions for NeXT as target machine for GNU C compiler. */
-
- #include "sparc/sparc.c"
- #include "next/nextstep.c"
- #include "next/machopic.h"
-
- #define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
- do { \
- const char *symbol_ = (SYMBOL); \
- char *buffer_ = (BUF); \
- if (symbol_[0] == '"') \
- { \
- sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
- } \
- else if (name_needs_quotes(symbol_)) \
- { \
- sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
- } \
- else \
- { \
- sprintf(buffer_, "L%d$%s", (N), symbol_); \
- } \
- } while (0)
-
- // Generate PIC and indirect symbol stubs
- void
- machopic_output_stub (file, symb, stub)
- FILE *file;
- const char *symb, *stub;
- {
- unsigned int length;
- char *binder_name, *symbol_name, *lazy_ptr_name;
- char *local_label_0, *local_label_1, *local_label_2;
- 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);
-
- local_label_0 = alloca(length + 32);
- GEN_LOCAL_LABEL_FOR_SYMBOL(local_label_0, symb, length, 0);
-
- local_label_1 = alloca(length + 32);
- GEN_LOCAL_LABEL_FOR_SYMBOL(local_label_1, symb, length, 1);
-
- local_label_2 = alloca(length + 32);
- GEN_LOCAL_LABEL_FOR_SYMBOL(local_label_2, symb, length, 2);
-
- 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, "\tmov %%o7,%%g4\n");
- fprintf(file, "%s:\n\tcall %s\n", local_label_0, local_label_1);
- fprintf(file, "\tsethi %%hi(%s-%s),%%g6\n",
- lazy_ptr_name, local_label_0);
- fprintf(file, "%s:\n\tor %%g6,%%lo(%s-%s),%%g6\n", local_label_1,
- lazy_ptr_name, local_label_0);
- fprintf(file, "\tld [%%g6+%%o7],%%g6\n");
- fprintf(file, "\tjmp %%g6\n");
- fprintf(file, "\tmov %%g4,%%o7\n");
- } else {
- fprintf(file, "\tsethi %%hi(%s),%%g6\n", lazy_ptr_name);
- fprintf(file, "\tld [%%g6+%%lo(%s),%g6\n", lazy_ptr_name);
- fprintf(file, "\tjmp %g6\n\tnop\n");
- }
-
- fprintf (file, "%s:\n", binder_name);
-
- if (MACHOPIC_PURE) {
- char *binder = machopic_non_lazy_ptr_name ("*dyld_stub_binding_helper");
- machopic_validate_non_lazy_ptr (binder);
-
- if (binder[0] == '*')
- binder += 1;
- fprintf(file, "\tcall %s\n", local_label_2);
- fprintf(file, "\tsethi %%hi(%s-%s),%%g6\n", binder, binder_name);
- fprintf(file, "%s:\n\tor %%g6,%%lo(%s-%s),%%g6\n", local_label_2,
- binder, binder_name);
- fprintf(file, "\tld [%%g6+%%o7],%%g6\n");
- fprintf(file, "\tsethi %%hi(%s-%s),%%g5\n", lazy_ptr_name, binder_name);
- fprintf(file, "\tor %%g5,%%lo(%s-%s),%%g5\n", lazy_ptr_name,
- binder_name);
- fprintf(file, "\tjmp %%g6\n\tadd %%g5,%%o7,%%g5\n");
- } else {
- fprintf(file, "\tsethi %%hi(%s),%%g5\n", lazy_ptr_name);
- fprintf(file, "\tsethi %%hi(dyld_stub_binding_helper),%%g6\n");
- fprintf(file, "\tjmp %%g6+%%lo(dyld_stub_binding_helper\n");
- fprintf(file, "\tor %%g5,%%lo(%s),%%g5\n", lazy_ptr_name);
- }
-
- 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);
- }
-
-