|
|
1.1 root 1: /* NeXTSTEP mach-o pic support functions.
2: Copyright (C) 1992, 1994 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: /*
21: * flag_pic = 1 ... generate only indirections
22: * flag_pic = 2 ... generate indirections and pure code
23: */
24:
25:
26: /*
27: * This module assumes that (const (symbol_ref "foo")) is
28: * a legal pic reference, which will not be changed.
29: */
30: #include "config.h"
31:
32: #ifdef MACHO_PIC
33:
34: #include "tree.h"
35: #include "rtl.h"
36: #include "output.h"
37: #include "machopic.h"
38: #include "insn-config.h"
39: #include "insn-flags.h"
40:
41: #include <stdio.h>
42:
43: /* Answer if the symbol named IDENT is known to be defined in
44: the current module. It is critical, that it *never* says
45: something is defined, when it isn't. However, it is ok to be
46: sloppy on the other end of the scale, it will only generate
47: worse code than if it guessed correct. */
48:
49: static tree machopic_defined_list = 0;
50:
51: extern int flag_dave_indirect;
52:
53: enum machopic_addr_class
54: machopic_classify_ident (ident)
55: tree ident;
56: {
57: char *name = IDENTIFIER_POINTER (ident);
58: int lprefix = (name[0] == '*'
59: && (name[1] == 'L'
60: || (name[1] == '"' && name[2] == 'L')));
61:
62: tree temp, decl = (tree)lookup_name (ident);
63:
64: if (!decl)
65: {
66: if (lprefix)
67: {
68: char *name = IDENTIFIER_POINTER (ident);
69: while (*name++)
70: {
71: if (! strncmp (name, "$stub\0", 6))
72: return MACHOPIC_DEFINED_FUNCTION;
73: }
74: return MACHOPIC_DEFINED_DATA;
75: }
76:
77: for (temp = machopic_defined_list;
78: temp != NULL_TREE;
79: temp = TREE_CHAIN (temp))
80: {
81: if (ident == TREE_VALUE (temp))
82: return MACHOPIC_DEFINED_DATA;
83: }
84:
85: return MACHOPIC_UNDEFINED;
86: }
87:
88: /* variable declarations */
89: else if (TREE_CODE (decl) == VAR_DECL)
90: {
91: if ((DECL_INITIAL (decl)
92: || TREE_STATIC (decl))
93: && ! TREE_PUBLIC (decl))
94: return MACHOPIC_DEFINED_DATA;
95: }
96:
97: /* function declarations */
98: else if (TREE_CODE (decl) == FUNCTION_DECL)
99: {
100: if (TREE_STATIC (decl)
101: || TREE_ASM_WRITTEN (decl))
102: return MACHOPIC_DEFINED_FUNCTION;
103: }
104:
105: for (temp = machopic_defined_list;
106: temp != NULL_TREE;
107: temp = TREE_CHAIN (temp))
108: {
109: if (ident == TREE_VALUE (temp))
110: if (TREE_CODE (decl) == FUNCTION_DECL)
111: return MACHOPIC_DEFINED_FUNCTION;
112: else
113: return MACHOPIC_DEFINED_DATA;
114: }
115:
116: if (TREE_CODE (decl) == FUNCTION_DECL)
117: {
118: if (lprefix)
119: return MACHOPIC_DEFINED_FUNCTION;
120: else
121: return MACHOPIC_UNDEFINED_FUNCTION;
122: }
123: else
124: {
125: if (lprefix)
126: return MACHOPIC_DEFINED_DATA;
127: else
128: return MACHOPIC_UNDEFINED_DATA;
129: }
130: }
131:
132:
133: enum machopic_addr_class
134: machopic_classify_name (name)
135: char *name;
136: {
137: return machopic_classify_ident (get_identifier (name));
138: }
139:
140: int
141: machopic_ident_defined_p (ident)
142: tree ident;
143: {
144: switch (machopic_classify_ident (ident))
145: {
146: case MACHOPIC_UNDEFINED:
147: case MACHOPIC_UNDEFINED_DATA:
148: case MACHOPIC_UNDEFINED_FUNCTION:
149: return 0;
150: default:
151: return 1;
152: }
153: }
154:
155: int
156: machopic_name_defined_p (name)
157: char *name;
158: {
159: return machopic_ident_defined_p (get_identifier (name));
160: }
161:
162: void
163: machopic_define_ident (ident)
164: tree ident;
165: {
166: if (!machopic_ident_defined_p (ident))
167: machopic_defined_list =
168: perm_tree_cons (NULL_TREE, ident, machopic_defined_list);
169: }
170:
171: void
172: machopic_define_name (name)
173: char *name;
174: {
175: machopic_define_ident (get_identifier (name));
176: }
177:
178: /* This is a static to make inline functions work. The rtx */
179: /* representing the PIC base symbol allways points to here. */
180: static char function_base[256];
181:
182: char*
183: machopic_function_base_name ()
184: {
185: static char *name = 0, *curr_name;
186: static int base = 0;
187:
188: curr_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
189:
190: if (name != curr_name)
191: {
192: current_function_uses_pic_offset_table = 1;
193:
194: if (strchr (curr_name, ' '))
195: sprintf (function_base, "*\"L%s$pic_base\"", curr_name);
196: else
197: sprintf (function_base, "*L%s$pic_base", curr_name);
198:
199: name = curr_name;
200: }
201:
202: return function_base;
203: }
204:
205: static tree machopic_non_lazy_pointers = 0;
206:
207: char*
208: machopic_non_lazy_ptr_name (name)
209: char *name;
210: {
211: tree temp, ident = get_identifier (name);
212:
213: for (temp = machopic_non_lazy_pointers;
214: temp != NULL_TREE;
215: temp = TREE_CHAIN (temp))
216: {
217: if (ident == TREE_VALUE (temp))
218: return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
219: }
220:
221: {
222: char buffer[256];
223: tree ptr_name;
224:
225: strcpy (buffer, "*L");
226: if (name[0] == '*')
227: strcat (buffer, name+1);
228: else
229: {
230: strcat (buffer, "_");
231: strcat (buffer, name);
232: }
233:
234: strcat (buffer, "$non_lazy_ptr");
235: ptr_name = get_identifier (buffer);
236:
237: machopic_non_lazy_pointers
238: = perm_tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
239:
240: return IDENTIFIER_POINTER (ptr_name);
241: }
242: }
243:
244: static tree machopic_stubs = 0;
245:
246: char*
247: machopic_stub_name (name)
248: char *name;
249: {
250: tree temp, ident = get_identifier (name);
251:
252: for (temp = machopic_stubs;
253: temp != NULL_TREE;
254: temp = TREE_CHAIN (temp))
255: {
256: if (ident == TREE_VALUE (temp))
257: return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
258: }
259:
260: {
261: char buffer[256];
262: tree ptr_name;
263:
264: strcpy (buffer, "*L");
265: if (name[0] == '*')
266: {
267: strcat (buffer, name+1);
268: }
269: else
270: {
271: strcat (buffer, "_");
272: strcat (buffer, name);
273: }
274:
275: strcat (buffer, "$stub");
276: ptr_name = get_identifier (buffer);
277:
278: machopic_stubs = perm_tree_cons (ptr_name, ident, machopic_stubs);
279:
280: return IDENTIFIER_POINTER (ptr_name);
281: }
282: }
283:
284: /*
285: * Transfrom ORIG, which any data source to the corresponding
286: * source using indirections.
287: */
288:
289: rtx
290: machopic_indirect_data_reference (orig, reg)
291: rtx orig, reg;
292: {
293: rtx ptr_ref = orig;
294:
295: if (! MACHOPIC_INDIRECT)
296: return orig;
297:
298: if (GET_CODE (orig) == SYMBOL_REF)
299: {
300: char *name = XSTR (orig, 0);
301:
302: if (machopic_name_defined_p (name))
303: {
304: #ifdef HAVE_hi_sum
305: rtx hi_sum;
306: rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
307: machopic_function_base_name ());
308: rtx offset = gen_rtx (CONST, Pmode, gen_rtx (MINUS, Pmode, orig, pic_base));
309:
310:
311: if (reg == 0) abort ();
312:
313: hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
314: gen_rtx (PLUS, Pmode,
315: pic_offset_table_rtx,
316: gen_rtx (HIGH, Pmode, offset)));
317:
318: #if 1
319: emit_insn (hi_sum);
320: #else
321: emit_insn (gen_rtx (PARALLEL, VOIDmode,
322: gen_rtvec (2,
323: hi_sum,
324: gen_rtx (USE, VOIDmode,
325: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
326: #endif
327:
328: emit_insn (gen_rtx (SET, Pmode, reg,
329: gen_rtx (LO_SUM, Pmode,
330: HI_SUM_TARGET_RTX,
331: offset)));
332:
333: {
334: rtx insn = get_last_insn ();
335: rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
336:
337: if (note)
338: XEXP (note, 0) = orig;
339: else
340: REG_NOTES (insn) = gen_rtx (EXPR_LIST,
341: REG_EQUAL, orig, REG_NOTES (insn));
342: }
343:
344: orig = reg;
345: #else
346: #ifdef HAVE_lo_sum
347: rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
348: machopic_function_base_name ());
349:
350: if (reg == 0) abort ();
351:
352: emit_insn (gen_rtx (SET, VOIDmode, reg,
353: gen_rtx (HIGH, Pmode,
354: gen_rtx (CONST, Pmode,
355: gen_rtx (MINUS, Pmode,
356: orig, pic_base)))));
357: emit_insn (gen_rtx (SET, VOIDmode, reg,
358: gen_rtx (LO_SUM, Pmode, reg,
359: gen_rtx (CONST, Pmode,
360: gen_rtx (MINUS, Pmode,
361: orig, pic_base)))));
362: emit_insn (gen_rtx (USE, VOIDmode,
363: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
364:
365: orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
366: #endif
367: #endif
368: return orig;
369: }
370:
371:
372: if (flag_dave_indirect)
373: {
374: extern tree string_type_node;
375: extern tree char_array_type_node;
376: tree params;
377: tree call;
378: tree get_addr_decl;
379:
380: if (reg == 0)
381: reg = gen_reg_rtx (Pmode);
382:
383: get_addr_decl
384: = (tree) lookup_name (get_identifier ("__get_address"));
385: if (get_addr_decl == 0)
386: error ("cannot find declaration for __get_address");
387:
388: params = build_string (strlen (name), name);
389: TREE_TYPE (params) = char_array_type_node;
390: params = build1 (ADDR_EXPR, string_type_node, params);
391: params = build_tree_list (NULL_TREE, params);
392:
393: call = (tree) build_function_call (get_addr_decl, params);
394: expand_call (call, reg, 0);
395: RTX_UNCHANGING_P (reg) = 1;
396: return reg;
397: }
398: else /* kevin_indirect */
399: {
400: ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
401: machopic_non_lazy_ptr_name (name));
402:
403:
404: /* generating real pure code */
405: /*
406: if (MACHOPIC_PURE)
407: ptr_ref = machopic_legitimize_pic_address (ptr_ref, SImode, reg);
408: */
409: ptr_ref = gen_rtx (MEM, Pmode, ptr_ref);
410: RTX_UNCHANGING_P (ptr_ref) = 1;
411: }
412:
413: return ptr_ref;
414: }
415: else if (GET_CODE (orig) == CONST)
416: {
417: rtx base, offset, result;
418:
419: /* legitimize both operands of the PLUS */
420: if (GET_CODE (XEXP (orig, 0)) == PLUS)
421: {
422: base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0), reg);
423: orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
424: base == reg ? 0 : reg);
425: }
426: else
427: return orig;
428:
429: if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
430: result = plus_constant_for_output (base, INTVAL (orig));
431: else
432: result = gen_rtx (PLUS, Pmode, base, orig);
433:
434: if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
435: RTX_UNCHANGING_P (result) = 1;
436:
437: if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
438: {
439: if (reg)
440: {
441: emit_move_insn (reg, result);
442: result = reg;
443: }
444: else
445: {
446: result = force_reg (GET_MODE (result), result);
447: }
448: }
449:
450: return result;
451:
452: }
453: else if (GET_CODE (orig) == MEM)
454: {
455: XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
456: return ptr_ref;
457: }
458: else
459: return ptr_ref;
460: }
461:
462:
463: /*
464: * Transform TARGET (a MEM), which is a function call target, to the
465: * corresponding symbol_stub if nessecary. Return the a new MEM.
466: */
467:
468: rtx
469: machopic_indirect_call_target (target)
470: rtx target;
471: {
472: if (GET_CODE (target) != MEM)
473: return target;
474: if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
475: {
476: enum machine_mode mode = GET_MODE (XEXP (target, 0));
477: char *name = XSTR (XEXP (target, 0), 0);
478: if (!machopic_name_defined_p (name))
479: {
480: if (flag_dave_indirect)
481: {
482: XEXP (target, 0) = force_reg (Pmode, XEXP (target, 0));
483: }
484: else /* kevin_indirect */
485: {
486: char *stub_name = (char*)machopic_stub_name (name);
487: XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
488: RTX_UNCHANGING_P (target) = 1;
489: }
490: }
491: }
492: return target;
493: }
494:
495:
496: rtx
497: machopic_legitimize_pic_address (orig, mode, reg)
498: rtx orig, reg;
499: enum machine_mode mode;
500: {
501: rtx pic_ref = orig;
502:
503: if (! MACHOPIC_PURE)
504: return orig;
505:
506: /* First handle a simple SYMBOL_REF or LABEL_REF */
507: if (GET_CODE (orig) == LABEL_REF
508: || (GET_CODE (orig) == SYMBOL_REF
509: #if 0
510: && !((machopic_classify_name (XSTR (orig, 0))
511: == MACHOPIC_DEFINED_FUNCTION)
512: && XSTR (orig, 0)[0] == '*')
513: #endif
514: ))
515: {
516: /* addr(foo) = &func+(foo-func) */
517: rtx equiv = orig;
518: rtx pic_base;
519: orig = machopic_indirect_data_reference (orig, reg);
520: if (GET_CODE (orig) == PLUS
521: && GET_CODE (XEXP (orig, 0)) == REG)
522: {
523: if (reg == 0)
524: return force_reg (mode, orig);
525:
526: emit_move_insn (reg, orig);
527: return reg;
528: }
529:
530: pic_base = gen_rtx (SYMBOL_REF, Pmode,
531: machopic_function_base_name ());
532:
533: if (GET_CODE (orig) == MEM)
534: {
535: if (reg == 0)
536: abort ();
537: #ifdef HAVE_lo_sum
538: if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
539: || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
540: {
541: #ifdef HAVE_hi_sum
542: rtx hi_sum;
543: rtx offset = gen_rtx (CONST, Pmode,
544: gen_rtx (MINUS, Pmode, XEXP (orig, 0), pic_base));
545:
546:
547: if (reg == 0)
548: if (reload_in_progress)
549: abort ();
550: else
551: reg = gen_reg_rtx (Pmode);
552:
553: hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
554: gen_rtx (PLUS, Pmode,
555: pic_offset_table_rtx,
556: gen_rtx (HIGH, Pmode, offset)));
557:
558: #if 1
559: emit_insn (hi_sum);
560: #else
561: emit_insn (gen_rtx (PARALLEL, VOIDmode,
562: gen_rtvec (2,
563: hi_sum,
564: gen_rtx (USE, VOIDmode,
565: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
566: #endif
567: emit_insn (gen_rtx (SET, VOIDmode, reg,
568: gen_rtx (MEM, GET_MODE (orig),
569: gen_rtx (LO_SUM, Pmode,
570: HI_SUM_TARGET_RTX,
571: offset))));
572: pic_ref = reg;
573:
574: #else
575: emit_insn (gen_rtx (USE, VOIDmode,
576: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
577:
578: emit_insn (gen_rtx (SET, VOIDmode, reg,
579: gen_rtx (HIGH, Pmode,
580: gen_rtx (CONST, Pmode,
581: gen_rtx (MINUS, Pmode,
582: XEXP (orig, 0),
583: pic_base)))));
584: emit_insn (gen_rtx (SET, VOIDmode, reg,
585: gen_rtx (LO_SUM, Pmode, reg,
586: gen_rtx (CONST, Pmode,
587: gen_rtx (MINUS, Pmode,
588: XEXP (orig, 0),
589: pic_base)))));
590: pic_ref = gen_rtx (PLUS, Pmode,
591: pic_offset_table_rtx, reg);
592: #endif
593: }
594: else
595: #endif
596: {
597: emit_insn (gen_rtx (USE, VOIDmode,
598: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
599:
600: pic_ref = gen_rtx (PLUS, Pmode,
601: pic_offset_table_rtx,
602: gen_rtx (CONST, Pmode,
603: gen_rtx (MINUS, Pmode,
604: XEXP (orig, 0),
605: pic_base)));
606: }
607:
608: #ifndef HAVE_hi_sum
609: RTX_UNCHANGING_P (pic_ref) = 1;
610: emit_move_insn (reg, pic_ref);
611: pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
612: #endif
613: }
614: else
615: {
616:
617: #ifdef HAVE_lo_sum
618: if (GET_CODE (orig) == SYMBOL_REF
619: || GET_CODE (orig) == LABEL_REF)
620: {
621: #ifdef HAVE_hi_sum
622: rtx hi_sum;
623: rtx offset = gen_rtx (CONST, Pmode,
624: gen_rtx (MINUS, Pmode, orig, pic_base));
625:
626: if (reg == 0)
627: if (reload_in_progress)
628: abort ();
629: else
630: reg = gen_reg_rtx (SImode);
631:
632: hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
633: gen_rtx (PLUS, Pmode,
634: pic_offset_table_rtx,
635: gen_rtx (HIGH, Pmode, offset)));
636:
637: #if 1
638: emit_insn (hi_sum);
639: #else
640: emit_insn (gen_rtx (PARALLEL, VOIDmode,
641: gen_rtvec (2,
642: hi_sum,
643: gen_rtx (USE, VOIDmode,
644: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
645: #endif
646: emit_insn (gen_rtx (SET, VOIDmode, reg,
647: gen_rtx (LO_SUM, Pmode,
648: HI_SUM_TARGET_RTX,
649: offset)));
650: pic_ref = reg;
651: #else
652: emit_insn (gen_rtx (SET, VOIDmode, reg,
653: gen_rtx (HIGH, Pmode,
654: gen_rtx (CONST, Pmode,
655: gen_rtx (MINUS, Pmode,
656: orig, pic_base)))));
657: emit_insn (gen_rtx (SET, VOIDmode, reg,
658: gen_rtx (LO_SUM, Pmode, reg,
659: gen_rtx (CONST, Pmode,
660: gen_rtx (MINUS, Pmode,
661: orig, pic_base)))));
662: pic_ref = gen_rtx (PLUS, Pmode,
663: pic_offset_table_rtx, reg);
664: #endif
665: }
666: else
667: #endif
668: if (GET_CODE (orig) == REG)
669: {
670: return orig;
671: }
672: else
673: {
674: emit_insn (gen_rtx (USE, VOIDmode,
675: gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
676:
677: pic_ref = gen_rtx (PLUS, Pmode,
678: pic_offset_table_rtx,
679: gen_rtx (CONST, Pmode,
680: gen_rtx (MINUS, Pmode,
681: orig, pic_base)));
682: }
683: }
684:
685: RTX_UNCHANGING_P (pic_ref) = 1;
686:
687: if (reg == 0)
688: return force_reg (mode, pic_ref);
689: else
690: {
691: if (GET_CODE (pic_ref) != REG)
692: emit_move_insn (reg, pic_ref);
693: else
694: reg = pic_ref;
695:
696: {
697: rtx insn = get_last_insn ();
698: rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
699:
700: if (note)
701: XEXP (note, 0) = equiv;
702: else
703: REG_NOTES (insn) = gen_rtx (EXPR_LIST,
704: REG_EQUAL, equiv, REG_NOTES (insn));
705: }
706:
707: return reg;
708: }
709: }
710:
711: else if (GET_CODE (orig) == SYMBOL_REF)
712: return orig;
713:
714: else if (GET_CODE (orig) == PLUS
715: && (GET_CODE (XEXP (orig, 0)) == MEM
716: || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
717: || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
718: && XEXP (orig, 0) != pic_offset_table_rtx
719: && GET_CODE (XEXP (orig, 1)) != REG)
720:
721: {
722: rtx base, offset;
723: int is_complex;
724:
725: is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
726:
727: base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
728: orig = machopic_legitimize_pic_address (XEXP (orig, 1),
729: Pmode, base == reg ? 0 : reg);
730: if (GET_CODE (orig) == CONST_INT)
731: {
732: pic_ref = plus_constant_for_output (base, INTVAL (orig));
733: is_complex = 1;
734: }
735: else
736: {
737: pic_ref = gen_rtx (PLUS, Pmode, base, orig);
738: }
739:
740: if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
741: RTX_UNCHANGING_P (pic_ref) = 1;
742:
743: if (reg && is_complex)
744: {
745: emit_move_insn (reg, pic_ref);
746: pic_ref = reg;
747: }
748: /* Likewise, should we set special REG_NOTEs here? */
749: }
750:
751: else if (GET_CODE (orig) == CONST)
752: {
753: return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
754: }
755:
756: else if (GET_CODE (orig) == MEM
757: && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
758: {
759: rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
760:
761: emit_move_insn (reg, gen_rtx (MEM, GET_MODE (orig), addr));
762: pic_ref = reg;
763: }
764:
765: return pic_ref;
766: }
767:
768:
769: void
770: machopic_finish (asm_out_file)
771: FILE *asm_out_file;
772: {
773: tree temp;
774:
775: for (temp = machopic_stubs;
776: temp != NULL_TREE;
777: temp = TREE_CHAIN (temp))
778: {
779: char symb[256];
780: char stub[256];
781: char *symb_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
782: char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
783:
784: if (symb_name[0] == '*')
785: strcpy (symb, symb_name+1);
786: else
787: symb[0] = '_', strcpy (symb+1, symb_name);
788:
789: if (stub_name[0] == '*')
790: strcpy (stub, stub_name+1);
791: else
792: stub[0] = '_', strcpy (stub+1, stub_name);
793:
794: /* must be in aux-out.c */
795: machopic_output_stub (asm_out_file, symb, stub);
796:
797: }
798:
799: for (temp = machopic_non_lazy_pointers;
800: temp != NULL_TREE;
801: temp = TREE_CHAIN (temp))
802: {
803: char *symb_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
804: char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
805:
806:
807: if (machopic_ident_defined_p (TREE_VALUE (temp)))
808: {
809: char symb[256];
810:
811: if (symb_name[0] == '*')
812: strcpy (symb, symb_name+1);
813: else
814: strcpy (symb, symb_name);
815:
816: readonly_data_section ();
817: assemble_label (lazy_name);
818: assemble_integer (gen_rtx (SYMBOL_REF, Pmode, symb_name),
819: GET_MODE_SIZE (Pmode), 1);
820: }
821: else
822: {
823: machopic_nl_symbol_ptr_section ();
824: assemble_name (asm_out_file, lazy_name);
825: fprintf (asm_out_file, ":\n");
826:
827: fprintf (asm_out_file, "\t.indirect_symbol ");
828: assemble_name (asm_out_file, symb_name);
829: fprintf (asm_out_file, "\n");
830:
831: assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode), 1);
832: }
833: }
834: }
835:
836: int
837: machopic_operand_p (op)
838: rtx op;
839: {
840: if (MACHOPIC_JUST_INDIRECT)
841: {
842: while (GET_CODE (op) == CONST)
843: op = XEXP (op, 0);
844:
845: if (GET_CODE (op) == SYMBOL_REF)
846: return machopic_name_defined_p (XSTR (op, 0));
847: else
848: return 0;
849: }
850:
851: while (GET_CODE (op) == CONST)
852: op = XEXP (op, 0);
853:
854: if (GET_CODE (op) == MINUS
855: && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
856: && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
857: && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
858: && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
859: {
860: return 1;
861: }
862:
863: #if 0
864: else if (GET_CODE (op) == SYMBOL_REF
865: && (machopic_classify_name (XSTR (op, 0))
866: == MACHOPIC_DEFINED_FUNCTION))
867: {
868: return 1;
869: }
870: #endif
871:
872: return 0;
873: }
874:
875: #endif
876:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.