1 /* Output bytecodes for GNU C-compiler.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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)
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.
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. */
29 #include "bytetypes.h"
32 #include "bc-opcode.h"
33 #include "bc-typecd.h"
38 extern char *xmalloc (), *xrealloc ();
41 extern struct obstack *rtl_obstack;
43 /* Indexed by mode class, gives the narrowest mode for each class. */
45 extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
47 /* Commonly used modes. */
48 /* Mode whose width is BITS_PER_UNIT */
49 extern enum machine_mode byte_mode;
51 /* Mode whose width is BITS_PER_WORD */
52 extern enum machine_mode word_mode;
54 /* Vector indexed by opcode giving info about the args for each opcode. */
55 static struct arityvec arityvec[] = {
59 /* How to print a symbol name for the assembler. */
66 fprintf (file, "%s", s + 1);
69 #ifdef NAMES_HAVE_UNDERSCORES
70 fprintf (file, "_%s", s);
72 fprintf (file, "%s", s);
77 /* Maintain a bucket hash table for symbol names. */
82 static struct bc_sym *hashtab[HASH_SIZE];
88 unsigned int hash = 0;
92 hash = hash << 3 | hash >> HASH_BITS - 3;
96 return hash % HASH_SIZE;
100 /* Look up the named symbol, creating it if it doesn't exist. */
109 for (s = hashtab[i]; s; s = s->next)
110 if (!strcmp (s->name, name))
113 s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
114 s->name = xmalloc (strlen (name) + 1);
115 strcpy (s->name, name);
116 s->defined = s->global = s->common = 0;
118 s->next = hashtab[i];
124 /* Write out .globl and common symbols to the named file. */
132 for (i = 0; i < HASH_SIZE; ++i)
133 for (s = hashtab[i]; s; s = s->next)
137 fprintf (file, "\n\t.globl ");
138 prsym (file, s->name);
142 fprintf (file, "\n\t.comm ");
143 prsym (file, s->name);
144 fprintf (file, ", %d\n", s->val);
149 fprintf (file, "\n\t.lcomm ");
150 prsym (file, s->name);
151 fprintf (file, ", %d\n", s->val);
159 /* Create and initialize a new segment. */
160 static struct bc_seg *
163 struct bc_seg *result;
165 result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
167 result->data = xmalloc (result->alloc);
175 /* Advance the segment index to the next alignment boundary. */
181 unsigned int oldsize = seg->size;
183 seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
184 if (seg->size > seg->alloc)
186 while (seg->size > seg->alloc)
188 seg->data = xrealloc (seg->data, seg->alloc);
190 bzero (seg->data + oldsize, seg->size - oldsize);
194 /* Append the given data to the given segment. */
196 seg_data (seg, data, size)
201 if (seg->size + size > seg->alloc)
203 while (seg->size + size > seg->alloc)
205 seg->data = xrealloc (seg->data, seg->alloc);
208 bcopy (data, seg->data + seg->size, size);
213 /* Append a zero-filled skip to the given segment. */
219 if (seg->size + size > seg->alloc)
221 while (seg->size + size > seg->alloc)
223 seg->data = xrealloc (seg->data, seg->alloc);
226 memset (seg->data + seg->size, 0, size);
231 /* Define the given name as the current offset in the given segment. It
232 is an error if the name is already defined. Return 0 or 1 indicating
233 failure or success respectively. */
235 seg_defsym (seg, name)
240 struct bc_segsym *segsym;
242 sym = sym_lookup (name);
247 sym->val = seg->size;
248 segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
250 segsym->next = seg->syms;
256 /* Generate in seg's data a reference to the given sym, adjusted by
259 seg_refsym (seg, name, offset)
265 struct bc_segreloc *segreloc;
267 sym = sym_lookup (name);
268 segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
269 segreloc->offset = seg->size;
271 segreloc->next = seg->relocs;
272 seg->relocs = segreloc;
273 seg_data (seg, (char *) &offset, sizeof offset);
277 /* Concatenate the contents of given segments into the first argument. */
279 seg_concat (result, seg)
280 struct bc_seg *result, *seg;
283 struct bc_segsym *segsym;
284 struct bc_segreloc *segreloc;
286 seg_align (result, MACHINE_SEG_ALIGN);
288 seg_data (result, seg->data, seg->size);
291 /* Go through the symbols and relocs of SEG, adjusting their offsets
292 for their new location in RESULT. */
297 segsym->sym->val += fix;
298 while (segsym->next && (segsym = segsym->next));
299 segsym->next = result->syms;
300 result->syms = seg->syms;
304 segreloc = seg->relocs;
306 segreloc->offset += fix;
307 while (segreloc->next && (segreloc = segreloc->next));
308 segreloc->next = result->relocs;
309 result->relocs = seg->relocs;
315 /* Write a segment to a file. */
317 bc_seg_write (seg, file)
321 struct bc_segsym *segsym, *nsegsym, *psegsym;
322 struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
325 /* Reverse the list of symbols. */
326 for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
328 nsegsym = segsym->next;
329 segsym->next = psegsym;
334 /* Reverse the list of relocs. */
335 for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
337 nsegreloc = segreloc->next;
338 segreloc->next = psegreloc;
339 psegreloc = segreloc;
341 seg->relocs = psegreloc;
343 /* Output each byte of the segment. */
344 for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
346 while (segsym && segsym->sym->val == i)
351 BC_WRITE_SEGSYM (segsym, file);
352 segsym = segsym->next;
355 if (segreloc && segreloc->offset == i)
360 offset = *(int *) (seg->data + i);
361 i += sizeof (int) - 1;
363 BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
364 segreloc = segreloc->next;
369 if (i % 8 == 0 || flag)
370 BC_START_BYTECODE_LINE (file);
372 BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
381 /* Paranoia check--we should have visited all syms and relocs during
384 if (segsym || segreloc)
390 /* Text and data segments of the object file in making. */
391 static struct bc_seg *bc_text_seg;
392 static struct bc_seg *bc_data_seg;
394 /* Called before anything else in this module. */
398 int min_class_size[(int) MAX_MODE_CLASS];
399 enum machine_mode mode;
402 bc_init_mode_to_code_map ();
404 bc_text_seg = seg_create ();
405 bc_data_seg = seg_create ();
407 dconst0 = REAL_VALUE_ATOF ("0", DFmode);
408 dconst1 = REAL_VALUE_ATOF ("1", DFmode);
409 dconst2 = REAL_VALUE_ATOF ("2", DFmode);
410 dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
412 /* Find the narrowest mode for each class and compute the word and byte
415 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
416 min_class_size[i] = 1000;
418 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
419 mode = (enum machine_mode) ((int) mode + 1))
421 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
423 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
424 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
426 if (GET_MODE_CLASS (mode) == MODE_INT
427 && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
430 if (GET_MODE_CLASS (mode) == MODE_INT
431 && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
437 /* External addresses referenced in a function. Rather than trying to
438 work relocatable address directly into bytecoded functions (which would
439 require us to provide hairy location info and possibly obey alignment
440 rules imposed by the architecture) we build an auxilary table of
441 pointer constants, and encode just offsets into this table into the
443 static struct bc_seg *ptrconsts;
445 /* Trampoline code for the function entry. */
446 struct bc_seg *trampoline;
448 /* Actual byte code of the function. */
449 struct bc_seg *bytecode;
451 /* List of labels defined in the function. */
452 struct bc_label *labels;
454 /* List of label references in the function. */
455 struct bc_labelref *labelrefs;
458 /* Add symbol to pointer table. Return offset into table where
459 pointer was stored. The offset usually goes into the bytecode
460 stream as a constP literal. */
462 bc_define_pointer (p)
465 int offset = ptrconsts->size;
467 seg_refsym (ptrconsts, p, 0);
472 /* Begin a bytecoded function. */
474 bc_begin_function (name)
477 ptrconsts = seg_create ();
478 trampoline = seg_create ();
479 bytecode = seg_create ();
480 return seg_defsym (trampoline, name);
484 /* Force alignment in inline bytecode. */
486 bc_align_bytecode (align)
489 seg_align (bytecode, align);
493 /* Emit data inline into bytecode. */
495 bc_emit_bytecode_const (data, size)
500 seg_data (bytecode, data, size);
504 /* Create a new "bytecode label", to have its value defined later.
505 Bytecode labels have nothing to do with the object file symbol table,
506 and are purely local to a given bytecoded function. */
508 bc_get_bytecode_label ()
510 struct bc_label *result;
512 result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
514 result->next = labels;
521 /* Define the given label with the current location counter. */
523 bc_emit_bytecode_labeldef (label)
524 struct bc_label *label;
526 extern int bc_new_uid ();
528 if (!label || label->defined)
531 label->offset = bytecode->size;
533 label->uid = bc_new_uid ();
535 #ifdef DEBUG_PRINT_CODE
536 fprintf (stderr, "$%lx:\n", label);
543 /* Generate a location-relative reference to the given bytecode label.
544 It need not be defined yet; label references will be backpatched later. */
546 bc_emit_bytecode_labelref (label)
547 struct bc_label *label;
549 struct bc_labelref *labelref;
552 labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
553 labelref->label = label;
554 labelref->offset = bytecode->size;
555 labelref->next = labelrefs;
556 labelrefs = labelref;
558 #ifdef DEBUG_PRINT_CODE
559 fprintf (stderr, " $%lx", label);
562 seg_data (bytecode, (char *) &zero, sizeof zero);
566 /* Emit a reference to an external address; generate the reference in the
567 ptrconst area, and emit an offset in the bytecode. */
569 bc_emit_code_labelref (name, offset)
575 ptroff = ptrconsts->size / sizeof (char *);
576 seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
577 seg_refsym (ptrconsts, name, offset);
579 #ifdef DEBUG_PRINT_CODE
580 fprintf (stderr, " [external <%x> %s]", ptroff, name);
585 /* Backpatch label references in the byte code, and concatenate the bytecode
586 and pointer constant segments to the cumulative text for the object file.
587 Return a label name for the pointer constants region. */
592 struct bc_label *label, *next;
593 struct bc_labelref *ref, *nextref;
594 char ptrconsts_label[20];
597 /* Backpatch bytecode label references. */
598 for (ref = labelrefs; ref; ref = ref->next)
599 if (ref->label->defined)
601 addr = ref->label->offset;
602 bcopy (&addr, bytecode->data + ref->offset, sizeof addr);
605 /* Free the chains of labelrefs and labeldefs. */
606 for (ref = labelrefs; ref; ref = nextref)
612 for (label = labels; label; label = next)
615 free ((char *) label);
618 seg_concat (trampoline, bytecode);
619 seg_align (trampoline, MACHINE_SEG_ALIGN);
620 sprintf (ptrconsts_label, "*LP%d", nlab++);
621 seg_defsym (trampoline, ptrconsts_label);
622 seg_concat (trampoline, ptrconsts);
623 seg_concat (bc_text_seg, trampoline);
631 return sym_lookup (ptrconsts_label)->name;
634 /* Force alignment in const data. */
636 bc_align_const (align)
639 seg_align (bc_text_seg, align);
642 /* Emit const data. */
644 bc_emit_const (data, size)
648 seg_data (bc_text_seg, data, size);
651 /* Emit a zero-filled constant skip. */
653 bc_emit_const_skip (size)
656 seg_skip (bc_text_seg, size);
659 /* Emit a label definition in const data. */
661 bc_emit_const_labeldef (name)
664 return seg_defsym (bc_text_seg, name);
667 /* Emit a label reference in const data. */
669 bc_emit_const_labelref (name, offset)
673 seg_refsym (bc_text_seg, name, offset);
676 /* Force alignment in data. */
678 bc_align_data (align)
681 seg_align (bc_data_seg, align);
686 bc_emit_data (data, size)
690 seg_data (bc_data_seg, data, size);
693 /* Emit a zero-filled data skip. */
695 bc_emit_data_skip (size)
698 seg_skip (bc_data_seg, size);
701 /* Emit label definition in data. */
703 bc_emit_data_labeldef (name)
706 return seg_defsym (bc_data_seg, name);
709 /* Emit label reference in data. */
711 bc_emit_data_labelref (name, offset)
715 seg_refsym (bc_data_seg, name, offset);
718 /* Emit a common block of the given name and size. Note that
719 when the .o file is actually written non-global "common"
720 blocks will have to be turned into space in the data section. */
722 bc_emit_common (name, size)
728 sym = sym_lookup (name);
738 /* Globalize the given label. */
740 bc_globalize_label (name)
745 sym = sym_lookup (name);
749 static enum { in_text, in_data } section = in_text;
767 if (section == in_text)
768 bc_align_const (align);
770 bc_align_data (align);
778 if (section == in_text)
779 bc_emit_const (data, size);
781 bc_emit_data (data, size);
788 if (section == in_text)
789 bc_emit_const_skip (size);
791 bc_emit_data_skip (size);
795 bc_emit_labeldef (name)
798 if (section == in_text)
799 return bc_emit_const_labeldef (name);
801 return bc_emit_data_labeldef (name);
805 bc_emit_labelref (name, offset)
809 if (section == in_text)
810 bc_emit_const_labelref (name, offset);
812 bc_emit_data_labelref (name, offset);
819 BC_WRITE_FILE (file);
823 /* Allocate a new bytecode rtx.
824 If you supply a null BC_LABEL, we generate one. */
827 bc_gen_rtx (label, offset, bc_label)
830 struct bc_label *bc_label;
835 bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
837 r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
838 bc_label->offset = offset;
844 /* Print bytecode rtx */
850 #if 0 /* This needs to get fixed to really work again. */
851 /* BC_WRITE_RTL has a definition
852 that doesn't even make sense for this use. */
853 BC_WRITE_RTL (r, fp);
858 /* Emit a bytecode, keeping a running tally of the stack depth. */
860 bc_emit_bytecode (bytecode)
861 enum bytecode_opcode bytecode;
864 int npushes = arityvec[(int) bytecode].noutputs - arityvec[(int) bytecode].ninputs;
865 static int prev_lineno = -1;
869 #ifdef BCDEBUG_PRINT_CODE
870 if (lineno != prev_lineno)
872 fprintf (stderr, "<line %d>\n", lineno);
873 prev_lineno = lineno;
876 fputs (opcode_name[(unsigned int) bytecode], stderr);
879 /* Due to errors we are often requested to output bytecodes that
880 will cause an interpreter stack undeflow when executed. Instead of
881 dumping core on such occasions, we omit the bytecode. Erroneous code
882 should not be executed, regardless. This makes life much easier, since
883 we don't have to deceive ourselves about the known stack depth. */
885 bc_emit_bytecode_const (&byte, 1);
887 if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
889 if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
890 max_stack_depth = stack_depth;
893 #ifdef VALIDATE_STACK_FOR_BC
894 VALIDATE_STACK_FOR_BC ();
899 #ifdef BCDEBUG_PRINT_CODE
900 #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
905 /* Emit a complete bytecode instruction, expecting the correct number
906 of literal values in the call. First argument is the instruction, the
907 remaining arguments are literals of size HOST_WIDE_INT or smaller. */
909 bc_emit_instruction (va_alist)
913 enum bytecode_opcode opcode;
914 int nliteral, instruction;
917 va_start (arguments);
919 /* Emit instruction bytecode */
920 opcode = va_arg (arguments, enum bytecode_opcode);
921 bc_emit_bytecode (opcode);
922 instruction = (int) opcode;
924 /* Loop literals and emit as bytecode constants */
925 for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
927 HOST_WIDE_INT literal;
929 switch (arityvec[instruction].literals[nliteral])
931 /* This conditional is a kludge, but it's necessary
932 because TYPE might be long long. */
934 /* Expand definitions into case statements */
935 #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
938 TYPE temp = va_arg (arguments, TYPE); \
939 bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
940 PRLIT (TYPE, &temp); } \
943 #include "bc-typecd.def"
946 #endif /* __GNUC__ */
953 #ifdef BCDEBUG_PRINT_CODE
954 fputc ('\n', stderr);
958 /* Emit the machine-code interface trampoline at the beginning of a byte
959 coded function. The argument is a label name of the interpreter
960 bytecode callinfo structure; the return value is a label name for
961 the beginning of the actual bytecode. */
963 bc_emit_trampoline (callinfo)
969 sprintf (mylab, "*LB%d", n++);
971 BC_EMIT_TRAMPOLINE (trampoline, callinfo);
973 seg_defsym (bytecode, mylab);
974 return sym_lookup (mylab)->name;
983 char *tmp = xmalloc (strlen (str) + 1);