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