|
|
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.