|
|
1.1 root 1: /* Output bytecodes for GNU C-compiler.
1.1.1.2 root 2: Copyright (C) 1993, 1994 Free Software Foundation, Inc.
1.1 root 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
1.1.1.3 ! root 18: the Free Software Foundation, 59 Temple Place - Suite 330,
! 19: Boston, MA 02111-1307, USA. */
1.1 root 20:
21:
22: #include "config.h"
1.1.1.2 root 23: #ifdef __STDC__
24: #include <stdarg.h>
25: #else
26: #include <varargs.h>
27: #endif
1.1 root 28: #include "machmode.h"
29: #include "rtl.h"
30: #include "real.h"
31: #include "obstack.h"
32: #include "bytecode.h"
33: #ifdef __GNUC__
34: #include "bytetypes.h"
35: #endif
36: #include "bc-emit.h"
37: #include "bc-opcode.h"
38: #include "bc-typecd.h"
39: #include "bi-run.h"
40:
41: #include <stdio.h>
42:
43: extern char *xmalloc (), *xrealloc ();
44: extern void free ();
45:
46: extern struct obstack *rtl_obstack;
47:
48: /* Indexed by mode class, gives the narrowest mode for each class. */
49:
1.1.1.2 root 50: extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
1.1 root 51:
52: /* Commonly used modes. */
53: /* Mode whose width is BITS_PER_UNIT */
1.1.1.2 root 54: extern enum machine_mode byte_mode;
1.1 root 55:
56: /* Mode whose width is BITS_PER_WORD */
1.1.1.2 root 57: extern enum machine_mode word_mode;
1.1 root 58:
59: /* Vector indexed by opcode giving info about the args for each opcode. */
60: static struct arityvec arityvec[] = {
61: #include "bc-arity.h"
62: };
63:
64: /* How to print a symbol name for the assembler. */
65: static void
66: prsym (file, s)
67: FILE *file;
68: char *s;
69: {
70: if (*s == '*')
71: fprintf (file, "%s", s + 1);
72: else
73:
74: #ifdef NAMES_HAVE_UNDERSCORES
75: fprintf (file, "_%s", s);
76: #else
77: fprintf (file, "%s", s);
78: #endif
79:
80: }
81:
82: /* Maintain a bucket hash table for symbol names. */
83:
84: #define HASH_BITS 32
85: #define HASH_SIZE 509
86:
87: static struct bc_sym *hashtab[HASH_SIZE];
88:
89: static unsigned int
90: hash (name)
91: char *name;
92: {
93: unsigned int hash = 0;
94:
95: while (*name)
96: {
97: hash = hash << 3 | hash >> HASH_BITS - 3;
98: hash += *name++;
99: }
100:
101: return hash % HASH_SIZE;
102: }
103:
104:
105: /* Look up the named symbol, creating it if it doesn't exist. */
106: struct bc_sym *
107: sym_lookup (name)
108: char *name;
109: {
110: int i;
111: struct bc_sym *s;
112:
113: i = hash (name);
114: for (s = hashtab[i]; s; s = s->next)
115: if (!strcmp (s->name, name))
116: return s;
117:
118: s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
119: s->name = xmalloc (strlen (name) + 1);
120: strcpy (s->name, name);
121: s->defined = s->global = s->common = 0;
122: s->val = 0;
123: s->next = hashtab[i];
124: hashtab[i] = s;
125: return s;
126: }
127:
128:
129: /* Write out .globl and common symbols to the named file. */
130: static void
131: bc_sym_write (file)
132: FILE *file;
133: {
134: int i;
135: struct bc_sym *s;
136:
137: for (i = 0; i < HASH_SIZE; ++i)
138: for (s = hashtab[i]; s; s = s->next)
139: {
140: if (s->global)
141: {
142: fprintf (file, "\n\t.globl ");
143: prsym (file, s->name);
144: putc ('\n', file);
145: if (s->common)
146: {
147: fprintf (file, "\n\t.comm ");
148: prsym (file, s->name);
1.1.1.2 root 149: fprintf (file, ", %lu\n", s->val);
1.1 root 150: }
151: }
152: else if (s->common)
153: {
154: fprintf (file, "\n\t.lcomm ");
155: prsym (file, s->name);
1.1.1.2 root 156: fprintf (file, ", %lu\n", s->val);
1.1 root 157: }
158: }
159: }
160:
161:
162:
163:
164: /* Create and initialize a new segment. */
165: static struct bc_seg *
166: seg_create ()
167: {
168: struct bc_seg *result;
169:
170: result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
171: result->alloc = 256;
172: result->data = xmalloc (result->alloc);
173: result->size = 0;
174: result->syms = 0;
175: result->relocs = 0;
176: return result;
177: }
178:
179:
180: /* Advance the segment index to the next alignment boundary. */
181: static void
182: seg_align (seg, log)
183: struct bc_seg *seg;
184: int log;
185: {
186: unsigned int oldsize = seg->size;
187:
188: seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
189: if (seg->size > seg->alloc)
190: {
191: while (seg->size > seg->alloc)
192: seg->alloc *= 2;
193: seg->data = xrealloc (seg->data, seg->alloc);
194: }
195: bzero (seg->data + oldsize, seg->size - oldsize);
196: }
197:
198:
199: /* Append the given data to the given segment. */
200: static void
201: seg_data (seg, data, size)
202: struct bc_seg *seg;
203: char *data;
204: unsigned int size;
205: {
206: if (seg->size + size > seg->alloc)
207: {
208: while (seg->size + size > seg->alloc)
209: seg->alloc *= 2;
210: seg->data = xrealloc (seg->data, seg->alloc);
211: }
212:
213: bcopy (data, seg->data + seg->size, size);
214: seg->size += size;
215: }
216:
217:
218: /* Append a zero-filled skip to the given segment. */
219: static void
220: seg_skip (seg, size)
221: struct bc_seg *seg;
222: unsigned int size;
223: {
224: if (seg->size + size > seg->alloc)
225: {
226: while (seg->size + size > seg->alloc)
227: seg->alloc *= 2;
228: seg->data = xrealloc (seg->data, seg->alloc);
229: }
230:
231: memset (seg->data + seg->size, 0, size);
232: seg->size += size;
233: }
234:
235:
236: /* Define the given name as the current offset in the given segment. It
237: is an error if the name is already defined. Return 0 or 1 indicating
238: failure or success respectively. */
239: static int
240: seg_defsym (seg, name)
241: struct bc_seg *seg;
242: char *name;
243: {
244: struct bc_sym *sym;
245: struct bc_segsym *segsym;
246:
247: sym = sym_lookup (name);
248: if (sym->defined)
249: return 0;
250:
251: sym->defined = 1;
252: sym->val = seg->size;
253: segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
254: segsym->sym = sym;
255: segsym->next = seg->syms;
256: seg->syms = segsym;
257: return 1;
258: }
259:
260:
261: /* Generate in seg's data a reference to the given sym, adjusted by
262: the given offset. */
263: static void
264: seg_refsym (seg, name, offset)
265: struct bc_seg *seg;
266: char *name;
267: int offset;
268: {
269: struct bc_sym *sym;
270: struct bc_segreloc *segreloc;
271:
272: sym = sym_lookup (name);
273: segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
274: segreloc->offset = seg->size;
275: segreloc->sym = sym;
276: segreloc->next = seg->relocs;
277: seg->relocs = segreloc;
278: seg_data (seg, (char *) &offset, sizeof offset);
279: }
280:
281:
282: /* Concatenate the contents of given segments into the first argument. */
283: static void
284: seg_concat (result, seg)
285: struct bc_seg *result, *seg;
286: {
287: unsigned int fix;
288: struct bc_segsym *segsym;
289: struct bc_segreloc *segreloc;
290:
291: seg_align (result, MACHINE_SEG_ALIGN);
292: fix = result->size;
293: seg_data (result, seg->data, seg->size);
294: free (seg->data);
295:
296: /* Go through the symbols and relocs of SEG, adjusting their offsets
297: for their new location in RESULT. */
298: if (seg->syms)
299: {
300: segsym = seg->syms;
301: do
302: segsym->sym->val += fix;
303: while (segsym->next && (segsym = segsym->next));
304: segsym->next = result->syms;
305: result->syms = seg->syms;
306: }
307: if (seg->relocs)
308: {
309: segreloc = seg->relocs;
310: do
311: segreloc->offset += fix;
312: while (segreloc->next && (segreloc = segreloc->next));
313: segreloc->next = result->relocs;
314: result->relocs = seg->relocs;
315: }
316:
317: free ((char *) seg);
318: }
319:
320: /* Write a segment to a file. */
321: static void
322: bc_seg_write (seg, file)
323: struct bc_seg *seg;
324: FILE *file;
325: {
326: struct bc_segsym *segsym, *nsegsym, *psegsym;
327: struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
328: int i, offset, flag;
329:
330: /* Reverse the list of symbols. */
331: for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
332: {
333: nsegsym = segsym->next;
334: segsym->next = psegsym;
335: psegsym = segsym;
336: }
337: seg->syms = psegsym;
338:
339: /* Reverse the list of relocs. */
340: for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
341: {
342: nsegreloc = segreloc->next;
343: segreloc->next = psegreloc;
344: psegreloc = segreloc;
345: }
346: seg->relocs = psegreloc;
347:
348: /* Output each byte of the segment. */
349: for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
350: {
351: while (segsym && segsym->sym->val == i)
352: {
353: if (i % 8 != 0)
354: putc ('\n', file);
355:
356: BC_WRITE_SEGSYM (segsym, file);
357: segsym = segsym->next;
358: flag = 1;
359: }
360: if (segreloc && segreloc->offset == i)
361: {
362: if (i % 8 != 0)
363: putc ('\n', file);
364:
1.1.1.2 root 365: bcopy (seg->data + i, (char *) &offset, sizeof (int));
1.1 root 366: i += sizeof (int) - 1;
367:
368: BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
369: segreloc = segreloc->next;
370: flag = 1;
371: }
372: else
373: {
374: if (i % 8 == 0 || flag)
375: BC_START_BYTECODE_LINE (file);
376:
377: BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
378: seg->data[i] & 0xFF,
379: file);
380: flag = 0;
381: if (i % 8 == 7)
382: putc ('\n', file);
383: }
384: }
385:
386: /* Paranoia check--we should have visited all syms and relocs during
387: the output pass. */
388:
389: if (segsym || segreloc)
390: abort ();
391: }
392:
393:
394:
395: /* Text and data segments of the object file in making. */
396: static struct bc_seg *bc_text_seg;
397: static struct bc_seg *bc_data_seg;
398:
399: /* Called before anything else in this module. */
400: void
401: bc_initialize ()
402: {
403: int min_class_size[(int) MAX_MODE_CLASS];
404: enum machine_mode mode;
405: int i;
406:
407: bc_init_mode_to_code_map ();
408:
409: bc_text_seg = seg_create ();
410: bc_data_seg = seg_create ();
411:
412: dconst0 = REAL_VALUE_ATOF ("0", DFmode);
413: dconst1 = REAL_VALUE_ATOF ("1", DFmode);
414: dconst2 = REAL_VALUE_ATOF ("2", DFmode);
415: dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
416:
417: /* Find the narrowest mode for each class and compute the word and byte
418: modes. */
419:
420: for (i = 0; i < (int) MAX_MODE_CLASS; i++)
421: min_class_size[i] = 1000;
422:
423: for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
424: mode = (enum machine_mode) ((int) mode + 1))
425: {
426: if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
427: {
428: class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
429: min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
430: }
431: if (GET_MODE_CLASS (mode) == MODE_INT
432: && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
433: byte_mode = mode;
434:
435: if (GET_MODE_CLASS (mode) == MODE_INT
436: && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
437: word_mode = mode;
438: }
439: }
440:
441:
442: /* External addresses referenced in a function. Rather than trying to
443: work relocatable address directly into bytecoded functions (which would
444: require us to provide hairy location info and possibly obey alignment
1.1.1.3 ! root 445: rules imposed by the architecture) we build an auxiliary table of
1.1 root 446: pointer constants, and encode just offsets into this table into the
447: actual bytecode. */
448: static struct bc_seg *ptrconsts;
449:
450: /* Trampoline code for the function entry. */
451: struct bc_seg *trampoline;
452:
453: /* Actual byte code of the function. */
454: struct bc_seg *bytecode;
455:
456: /* List of labels defined in the function. */
457: struct bc_label *labels;
458:
459: /* List of label references in the function. */
460: struct bc_labelref *labelrefs;
461:
462:
463: /* Add symbol to pointer table. Return offset into table where
464: pointer was stored. The offset usually goes into the bytecode
465: stream as a constP literal. */
466: int
467: bc_define_pointer (p)
468: char *p;
469: {
470: int offset = ptrconsts->size;
471:
472: seg_refsym (ptrconsts, p, 0);
473: return offset;
474: }
475:
476:
477: /* Begin a bytecoded function. */
478: int
479: bc_begin_function (name)
480: char *name;
481: {
482: ptrconsts = seg_create ();
483: trampoline = seg_create ();
484: bytecode = seg_create ();
485: return seg_defsym (trampoline, name);
486: }
487:
488:
489: /* Force alignment in inline bytecode. */
490: void
491: bc_align_bytecode (align)
492: int align;
493: {
494: seg_align (bytecode, align);
495: }
496:
497:
498: /* Emit data inline into bytecode. */
499: void
500: bc_emit_bytecode_const (data, size)
501: char *data;
502: unsigned int size;
503: {
504: if (bytecode)
505: seg_data (bytecode, data, size);
506: }
507:
508:
509: /* Create a new "bytecode label", to have its value defined later.
510: Bytecode labels have nothing to do with the object file symbol table,
511: and are purely local to a given bytecoded function. */
512: struct bc_label *
513: bc_get_bytecode_label ()
514: {
515: struct bc_label *result;
516:
517: result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
518: result->defined = 0;
519: result->next = labels;
520: result->uid = 0;
521: labels = result;
522: return result;
523: }
524:
525:
526: /* Define the given label with the current location counter. */
527: int
528: bc_emit_bytecode_labeldef (label)
529: struct bc_label *label;
530: {
531: extern int bc_new_uid ();
532:
533: if (!label || label->defined)
534: return 0;
535:
536: label->offset = bytecode->size;
537: label->defined = 1;
538: label->uid = bc_new_uid ();
539:
540: #ifdef DEBUG_PRINT_CODE
541: fprintf (stderr, "$%lx:\n", label);
542: #endif
543:
544: return 1;
545: }
546:
547:
548: /* Generate a location-relative reference to the given bytecode label.
549: It need not be defined yet; label references will be backpatched later. */
550: void
551: bc_emit_bytecode_labelref (label)
552: struct bc_label *label;
553: {
554: struct bc_labelref *labelref;
555: static int zero;
556:
557: labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
558: labelref->label = label;
559: labelref->offset = bytecode->size;
560: labelref->next = labelrefs;
561: labelrefs = labelref;
562:
563: #ifdef DEBUG_PRINT_CODE
564: fprintf (stderr, " $%lx", label);
565: #endif
566:
567: seg_data (bytecode, (char *) &zero, sizeof zero);
568: }
569:
570:
571: /* Emit a reference to an external address; generate the reference in the
572: ptrconst area, and emit an offset in the bytecode. */
573: void
574: bc_emit_code_labelref (name, offset)
575: char *name;
576: int offset;
577: {
578: int ptroff;
579:
580: ptroff = ptrconsts->size / sizeof (char *);
581: seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
582: seg_refsym (ptrconsts, name, offset);
583:
584: #ifdef DEBUG_PRINT_CODE
585: fprintf (stderr, " [external <%x> %s]", ptroff, name);
586: #endif
587: }
588:
589:
590: /* Backpatch label references in the byte code, and concatenate the bytecode
591: and pointer constant segments to the cumulative text for the object file.
592: Return a label name for the pointer constants region. */
593: char *
594: bc_end_function ()
595: {
596: int addr;
597: struct bc_label *label, *next;
598: struct bc_labelref *ref, *nextref;
599: char ptrconsts_label[20];
600: static int nlab;
601:
602: /* Backpatch bytecode label references. */
603: for (ref = labelrefs; ref; ref = ref->next)
604: if (ref->label->defined)
605: {
606: addr = ref->label->offset;
1.1.1.2 root 607: bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
1.1 root 608: }
609:
610: /* Free the chains of labelrefs and labeldefs. */
611: for (ref = labelrefs; ref; ref = nextref)
612: {
613: nextref = ref->next;
614: free ((char *) ref);
615: }
616:
617: for (label = labels; label; label = next)
618: {
619: next = label->next;
620: free ((char *) label);
621: }
622:
623: seg_concat (trampoline, bytecode);
624: seg_align (trampoline, MACHINE_SEG_ALIGN);
625: sprintf (ptrconsts_label, "*LP%d", nlab++);
626: seg_defsym (trampoline, ptrconsts_label);
627: seg_concat (trampoline, ptrconsts);
628: seg_concat (bc_text_seg, trampoline);
629:
630: labels = 0;
631: labelrefs = 0;
632: trampoline = 0;
633: bytecode = 0;
634: ptrconsts = 0;
635:
636: return sym_lookup (ptrconsts_label)->name;
637: }
638:
639: /* Force alignment in const data. */
640: void
641: bc_align_const (align)
642: int align;
643: {
644: seg_align (bc_text_seg, align);
645: }
646:
647: /* Emit const data. */
648: void
649: bc_emit_const (data, size)
650: char *data;
651: unsigned int size;
652: {
653: seg_data (bc_text_seg, data, size);
654: }
655:
656: /* Emit a zero-filled constant skip. */
657: void
658: bc_emit_const_skip (size)
659: unsigned int size;
660: {
661: seg_skip (bc_text_seg, size);
662: }
663:
664: /* Emit a label definition in const data. */
665: int
666: bc_emit_const_labeldef (name)
667: char *name;
668: {
669: return seg_defsym (bc_text_seg, name);
670: }
671:
672: /* Emit a label reference in const data. */
673: void
674: bc_emit_const_labelref (name, offset)
675: char *name;
676: int offset;
677: {
678: seg_refsym (bc_text_seg, name, offset);
679: }
680:
681: /* Force alignment in data. */
682: void
683: bc_align_data (align)
684: int align;
685: {
686: seg_align (bc_data_seg, align);
687: }
688:
689: /* Emit data. */
690: void
691: bc_emit_data (data, size)
692: char *data;
693: unsigned int size;
694: {
695: seg_data (bc_data_seg, data, size);
696: }
697:
698: /* Emit a zero-filled data skip. */
699: void
700: bc_emit_data_skip (size)
701: unsigned int size;
702: {
703: seg_skip (bc_data_seg, size);
704: }
705:
706: /* Emit label definition in data. */
707: int
708: bc_emit_data_labeldef (name)
709: char *name;
710: {
711: return seg_defsym (bc_data_seg, name);
712: }
713:
714: /* Emit label reference in data. */
715: void
716: bc_emit_data_labelref (name, offset)
717: char *name;
718: int offset;
719: {
720: seg_refsym (bc_data_seg, name, offset);
721: }
722:
723: /* Emit a common block of the given name and size. Note that
724: when the .o file is actually written non-global "common"
725: blocks will have to be turned into space in the data section. */
726: int
727: bc_emit_common (name, size)
728: char *name;
729: unsigned int size;
730: {
731: struct bc_sym *sym;
732:
733: sym = sym_lookup (name);
734: if (sym->defined)
735: return 0;
736:
737: sym->defined = 1;
738: sym->common = 1;
739: sym->val = size;
740: return 1;
741: }
742:
743: /* Globalize the given label. */
744: void
745: bc_globalize_label (name)
746: char *name;
747: {
748: struct bc_sym *sym;
749:
750: sym = sym_lookup (name);
751: sym->global = 1;
752: }
753:
754: static enum { in_text, in_data } section = in_text;
755:
756: void
757: bc_text ()
758: {
759: section = in_text;
760: }
761:
762: void
763: bc_data ()
764: {
765: section = in_data;
766: }
767:
768: void
769: bc_align (align)
770: int align;
771: {
772: if (section == in_text)
773: bc_align_const (align);
774: else
775: bc_align_data (align);
776: }
777:
778: void
779: bc_emit (data, size)
780: char *data;
781: unsigned int size;
782: {
783: if (section == in_text)
784: bc_emit_const (data, size);
785: else
786: bc_emit_data (data, size);
787: }
788:
789: void
790: bc_emit_skip (size)
791: unsigned int size;
792: {
793: if (section == in_text)
794: bc_emit_const_skip (size);
795: else
796: bc_emit_data_skip (size);
797: }
798:
799: int
800: bc_emit_labeldef (name)
801: char *name;
802: {
803: if (section == in_text)
804: return bc_emit_const_labeldef (name);
805: else
806: return bc_emit_data_labeldef (name);
807: }
808:
809: void
810: bc_emit_labelref (name, offset)
811: char *name;
812: int offset;
813: {
814: if (section == in_text)
815: bc_emit_const_labelref (name, offset);
816: else
817: bc_emit_data_labelref (name, offset);
818: }
819:
820: void
821: bc_write_file (file)
822: FILE *file;
823: {
824: BC_WRITE_FILE (file);
825: }
826:
827:
828: /* Allocate a new bytecode rtx.
829: If you supply a null BC_LABEL, we generate one. */
830:
831: rtx
832: bc_gen_rtx (label, offset, bc_label)
833: char *label;
834: int offset;
835: struct bc_label *bc_label;
836: {
837: rtx r;
838:
839: if (bc_label == 0)
840: bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
841:
842: r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
843: bc_label->offset = offset;
844:
845: return r;
846: }
847:
848:
849: /* Print bytecode rtx */
850: void
851: bc_print_rtl (fp, r)
852: FILE *fp;
853: rtx r;
854: {
855: #if 0 /* This needs to get fixed to really work again. */
856: /* BC_WRITE_RTL has a definition
857: that doesn't even make sense for this use. */
858: BC_WRITE_RTL (r, fp);
859: #endif
860: }
861:
862:
863: /* Emit a bytecode, keeping a running tally of the stack depth. */
864: void
865: bc_emit_bytecode (bytecode)
866: enum bytecode_opcode bytecode;
867: {
868: char byte;
869: static int prev_lineno = -1;
870:
1.1.1.2 root 871: byte = (char) bytecode;
1.1 root 872:
873: #ifdef BCDEBUG_PRINT_CODE
874: if (lineno != prev_lineno)
875: {
876: fprintf (stderr, "<line %d>\n", lineno);
877: prev_lineno = lineno;
878: }
879:
880: fputs (opcode_name[(unsigned int) bytecode], stderr);
881: #endif
882:
883: /* Due to errors we are often requested to output bytecodes that
884: will cause an interpreter stack undeflow when executed. Instead of
885: dumping core on such occasions, we omit the bytecode. Erroneous code
886: should not be executed, regardless. This makes life much easier, since
887: we don't have to deceive ourselves about the known stack depth. */
888:
889: bc_emit_bytecode_const (&byte, 1);
890:
891: if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
892: {
893: if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
894: max_stack_depth = stack_depth;
895: }
896:
897: #ifdef VALIDATE_STACK_FOR_BC
898: VALIDATE_STACK_FOR_BC ();
899: #endif
900: }
901:
902:
903: #ifdef BCDEBUG_PRINT_CODE
904: #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
905: #else
906: #define PRLIT(X,Y)
907: #endif
908:
909: /* Emit a complete bytecode instruction, expecting the correct number
910: of literal values in the call. First argument is the instruction, the
911: remaining arguments are literals of size HOST_WIDE_INT or smaller. */
912: void
1.1.1.2 root 913: bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
1.1 root 914: {
1.1.1.2 root 915: #ifndef __STDC__
1.1 root 916: enum bytecode_opcode opcode;
1.1.1.2 root 917: #endif
918: va_list arguments;
1.1 root 919: int nliteral, instruction;
920:
1.1.1.2 root 921: VA_START (arguments, opcode);
1.1 root 922:
1.1.1.2 root 923: #ifndef __STDC__
924: opcode = va_arg (arguments, enum bytecode_opcode);
925: #endif
1.1 root 926:
927: /* Emit instruction bytecode */
928: bc_emit_bytecode (opcode);
929: instruction = (int) opcode;
930:
931: /* Loop literals and emit as bytecode constants */
932: for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
933: {
934: switch (arityvec[instruction].literals[nliteral])
935: {
936: /* This conditional is a kludge, but it's necessary
937: because TYPE might be long long. */
938: #ifdef __GNUC__
939: /* Expand definitions into case statements */
940: #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
941: case CODE: \
942: { \
943: TYPE temp = va_arg (arguments, TYPE); \
944: bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
945: PRLIT (TYPE, &temp); } \
946: break;
947:
948: #include "bc-typecd.def"
949:
950: #undef DEFTYPECODE
951: #endif /* __GNUC__ */
952:
953: default:
954: abort ();
955: }
956: }
957:
958: #ifdef BCDEBUG_PRINT_CODE
959: fputc ('\n', stderr);
960: #endif
961: }
962:
963: /* Emit the machine-code interface trampoline at the beginning of a byte
964: coded function. The argument is a label name of the interpreter
965: bytecode callinfo structure; the return value is a label name for
966: the beginning of the actual bytecode. */
967: char *
968: bc_emit_trampoline (callinfo)
969: char *callinfo;
970: {
971: char mylab[20];
972: static int n;
973:
974: sprintf (mylab, "*LB%d", n++);
975:
976: BC_EMIT_TRAMPOLINE (trampoline, callinfo);
977:
978: seg_defsym (bytecode, mylab);
979: return sym_lookup (mylab)->name;
980: }
981:
982:
983: /* Simple strdup */
984: char *
985: bc_xstrdup (str)
986: char *str;
987: {
988: char *tmp = xmalloc (strlen (str) + 1);
989:
990: strcpy (tmp, str);
991: return tmp;
992: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.