|
|
1.1 ! root 1: ! 2: /* next.c: Functions for NeXT as target machine for GNU C compiler. */ ! 3: ! 4: #include "pa/pa.c" ! 5: #include "nextstep.c" ! 6: #include "machopic.h" ! 7: ! 8: void add_vararg_func PROTO((char *, char)); ! 9: int check_vararg_func PROTO((char *)); ! 10: int check_duplicate_entry PROTO((char *)); ! 11: ! 12: #define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB) ! 13: #define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB) ! 14: #define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB)) ! 15: ! 16: static tree stub_list = 0; ! 17: ! 18: /* Following function adds the compiler generated stub for handling ! 19: procedure calls to the linked list. ! 20: */ ! 21: ! 22: void ! 23: add_compiler_stub(label_name, function_name, line_number) ! 24: tree label_name; ! 25: tree function_name; ! 26: int line_number; ! 27: { ! 28: tree stub; ! 29: ! 30: stub = build_tree_list (function_name, label_name); ! 31: TREE_TYPE (stub) = build_int_2 (line_number, 0); ! 32: TREE_CHAIN (stub) = stub_list; ! 33: stub_list = stub; ! 34: } ! 35: ! 36: /* Following function outputs the compiler generated stub for handling ! 37: procedure calls from the linked list and initialises the linked list. ! 38: */ ! 39: void output_compiler_stub() ! 40: { ! 41: char tmp_buf[256]; ! 42: char label_buf[256]; ! 43: char *label; ! 44: tree tmp_stub, stub; ! 45: ! 46: for (stub = stub_list; stub; stub = TREE_CHAIN (stub)) ! 47: { ! 48: fprintf (asm_out_file, "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub))); ! 49: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 50: if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 51: fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub)); ! 52: #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ ! 53: ! 54: #ifdef ASM_GENERATE_LABELREF ! 55: ASM_GENERATE_LABELREF (label_buf, ! 56: IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))); ! 57: #else ! 58: label_buf[0] = '_'; ! 59: strcpy (label_buf+1, IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))); ! 60: #endif ! 61: ! 62: if (flag_pic == 2) ! 63: { ! 64: char *local = IDENTIFIER_POINTER (STUB_LABEL_NAME (stub)); ! 65: label = machopic_stub_name (label_buf+1); ! 66: ! 67: if (label[0] == '*') label += 1; ! 68: ! 69: sprintf (tmp_buf, "bl L$%s,%%%%r19\n\tnop\nL$%s:", local, local); ! 70: output_asm_insn (tmp_buf, 0); ! 71: ! 72: output_asm_insn ("depi 0,31,2,%%r19", 0); ! 73: ! 74: sprintf (tmp_buf, "addil L`%s-L$%s,%%%%r19", label, local); ! 75: output_asm_insn (tmp_buf, 0); ! 76: ! 77: sprintf (tmp_buf, "ldo R`%s-L$%s(%%%%r1),%%%%r19", label, local); ! 78: output_asm_insn (tmp_buf, 0); ! 79: ! 80: output_asm_insn ("be,n 0(4,%%r19)", 0); ! 81: } ! 82: else ! 83: { ! 84: label = label_buf; ! 85: ! 86: strcpy (tmp_buf, "ldil L%'"); ! 87: strcat (tmp_buf, label); ! 88: ! 89: strcat (tmp_buf, ",%%r1\n\tble,n R%'"); ! 90: strcat (tmp_buf, label); ! 91: ! 92: strcat (tmp_buf, "(4,%%r1)"); ! 93: ! 94: output_asm_insn (tmp_buf, 0); ! 95: } ! 96: ! 97: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 98: if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 99: fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub)); ! 100: #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ ! 101: } ! 102: ! 103: stub_list = 0; ! 104: } ! 105: ! 106: /* Following function checks in the link list whether the function name is ! 107: already there or not. ! 108: */ ! 109: int no_previous_def(function_name) ! 110: tree function_name; ! 111: { ! 112: tree stub; ! 113: for (stub = stub_list; stub; stub = TREE_CHAIN (stub)) ! 114: { ! 115: if (function_name == STUB_FUNCTION_NAME (stub)) ! 116: return 0; ! 117: } ! 118: return 1; ! 119: } ! 120: ! 121: /* Following function gets the label name from the previous definition of ! 122: the function ! 123: */ ! 124: tree get_prev_label(function_name) ! 125: tree function_name; ! 126: { ! 127: tree stub; ! 128: for (stub = stub_list; stub; stub = TREE_CHAIN (stub)) ! 129: { ! 130: if (function_name == STUB_FUNCTION_NAME (stub)) ! 131: return STUB_LABEL_NAME (stub); ! 132: } ! 133: return 0; ! 134: } ! 135: ! 136: struct vararg_list ! 137: { ! 138: char function_name[256]; ! 139: char flag; ! 140: struct vararg_list *next_stub; ! 141: }; ! 142: ! 143: struct vararg_list *startvararg, *currvararg; ! 144: ! 145: /* Following function adds the function name to the linked list. ! 146: If function is a variable argument function make flag = 1 else 0; ! 147: */ ! 148: void add_vararg_func(function_name, flag) ! 149: char *function_name; ! 150: char flag; ! 151: { ! 152: struct vararg_list *temppointer; ! 153: ! 154: if (check_duplicate_entry(function_name)) ! 155: { ! 156: return; ! 157: } ! 158: ! 159: temppointer = (struct vararg_list *)calloc(sizeof(struct vararg_list), 1); ! 160: strcpy(temppointer->function_name, function_name); ! 161: temppointer->flag = flag; ! 162: if (startvararg == NULL) ! 163: { ! 164: startvararg = temppointer; ! 165: } ! 166: else ! 167: { ! 168: currvararg->next_stub = temppointer; ! 169: } ! 170: ! 171: currvararg = temppointer; ! 172: currvararg->next_stub = NULL; ! 173: } ! 174: ! 175: /* Following function checks in the link list whether the function name is ! 176: already there or not for vararg functions ! 177: */ ! 178: int check_vararg_func(function_name) ! 179: char *function_name; ! 180: { ! 181: struct vararg_list *temppointer; ! 182: ! 183: temppointer = startvararg; ! 184: while (temppointer) ! 185: { ! 186: if (!strcmp(temppointer->function_name, function_name)) ! 187: { ! 188: if (temppointer->flag == '1') ! 189: return 1; ! 190: else ! 191: return 0; ! 192: } ! 193: temppointer = temppointer->next_stub; ! 194: } ! 195: return 1; ! 196: } ! 197: /* Following function checks in the link list whether the function name is ! 198: already there or not for all functions ! 199: */ ! 200: int check_duplicate_entry(function_name) ! 201: char *function_name; ! 202: { ! 203: struct vararg_list *temppointer; ! 204: ! 205: temppointer = startvararg; ! 206: while (temppointer) ! 207: { ! 208: if (!strcmp(temppointer->function_name, function_name)) ! 209: { ! 210: return 1; ! 211: } ! 212: temppointer = temppointer->next_stub; ! 213: } ! 214: return 0; ! 215: } ! 216: ! 217: add_profiler_info(insn, label_buf, line_number) ! 218: rtx insn; ! 219: char *label_buf; ! 220: int line_number; ! 221: { ! 222: tree labelname; ! 223: tree funcname; ! 224: ! 225: labelname = get_identifier(label_buf); ! 226: funcname = get_identifier("mcount"); ! 227: add_compiler_stub(labelname, funcname, line_number); ! 228: } ! 229: ! 230: char* ! 231: output_profile_call (rtx insn, rtx* operands) ! 232: { ! 233: rtx label_rtx = gen_label_rtx (); ! 234: static char buf[256]; ! 235: static char temp_buf[300]; ! 236: char *the_label; ! 237: int i; ! 238: rtx prev_insn; ! 239: int line_number; ! 240: ! 241: ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", ! 242: CODE_LABEL_NUMBER (label_rtx)); ! 243: ! 244: if (temp_buf[0] == '*') ! 245: the_label = temp_buf+1; ! 246: ! 247: else ! 248: the_label = temp_buf; ! 249: ! 250: strcpy(buf, "jbsr mcount,%%r2,"); ! 251: strcat(buf, the_label); ! 252: output_asm_insn (buf, operands); ! 253: prev_insn = insn; ! 254: while (prev_insn && GET_CODE(prev_insn) != NOTE) ! 255: { ! 256: prev_insn = PREV_INSN (prev_insn); ! 257: }; ! 258: line_number = prev_insn ? NOTE_LINE_NUMBER(prev_insn) : 0; ! 259: add_profiler_info(insn, the_label, line_number); ! 260: return "ldo %0(%%r2),%%r25"; ! 261: } ! 262: ! 263: void ! 264: machopic_output_stub (file, symb, stub) ! 265: FILE *file; ! 266: const char *symb, *stub; ! 267: { ! 268: static int label = 0; ! 269: label += 1; ! 270: ! 271: if (MACHOPIC_PURE) ! 272: machopic_picsymbol_stub_section (); ! 273: else ! 274: machopic_symbol_stub_section (); ! 275: ! 276: fprintf (file, "%s:\n", stub); ! 277: fprintf (file, "\t.indirect_symbol %s\n", symb); ! 278: ! 279: if (MACHOPIC_PURE) ! 280: { ! 281: fprintf (file, "\taddil L`L%s$lazy_ptr-%s,%%r19\n", symb, stub); ! 282: fprintf (file, "\tldw R`L%s$lazy_ptr-%s(%%r1),%%r19\n", symb, stub); ! 283: fprintf (file, "\tbe,n 0(4,%%r19)\n"); ! 284: } ! 285: else ! 286: { ! 287: fprintf (file, "\tjmp *L%s$lazy_ptr\n", symb); ! 288: } ! 289: ! 290: fprintf (file, "%s_binder:\n", stub); ! 291: ! 292: if (MACHOPIC_PURE) ! 293: { ! 294: char *binder = machopic_non_lazy_ptr_name ("*dyld_stub_binding_helper"); ! 295: if (binder[0] == '*') binder += 1; ! 296: fprintf (file, "\taddil L`L%s$lazy_ptr-%s_binder,%%r19\n", symb, stub); ! 297: fprintf (file, "\tldo R`L%s$lazy_ptr-%s_binder(%%r1),%%r31\n", symb, stub); ! 298: fprintf (file, "\taddil L`%s-%s_binder,%%r19\n", binder, stub); ! 299: fprintf (file, "\tldw R`%s-%s_binder(%%r1),%%r19\n", binder, stub); ! 300: fprintf (file, "\tbe,n 0(4,%%r19)\n"); ! 301: } ! 302: else ! 303: { ! 304: fprintf (file, "\t pushl $L%s$lazy_ptr\n", symb); ! 305: fprintf (file, "\tjmp dyld_stub_binding_helper\n"); ! 306: } ! 307: ! 308: ! 309: machopic_lazy_symbol_ptr_section (); ! 310: fprintf (file, "L%s$lazy_ptr:\n", symb); ! 311: fprintf (file, "\t.indirect_symbol %s\n", symb); ! 312: fprintf (file, "\t.long %s_binder\n", stub); ! 313: } ! 314:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.