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