|
|
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 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: 21: #include "config.h" 1.1.1.2 ! root 22: #ifdef __STDC__ ! 23: #include <stdarg.h> ! 24: #else ! 25: #include <varargs.h> ! 26: #endif 1.1 root 27: #include "machmode.h" 28: #include "rtl.h" 29: #include "real.h" 30: #include "obstack.h" 31: #include "bytecode.h" 32: #ifdef __GNUC__ 33: #include "bytetypes.h" 34: #endif 35: #include "bc-emit.h" 36: #include "bc-opcode.h" 37: #include "bc-typecd.h" 38: #include "bi-run.h" 39: 40: #include <stdio.h> 41: 42: extern char *xmalloc (), *xrealloc (); 43: extern void free (); 44: 45: extern struct obstack *rtl_obstack; 46: 47: /* Indexed by mode class, gives the narrowest mode for each class. */ 48: 1.1.1.2 ! root 49: extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS]; 1.1 root 50: 51: /* Commonly used modes. */ 52: /* Mode whose width is BITS_PER_UNIT */ 1.1.1.2 ! root 53: extern enum machine_mode byte_mode; 1.1 root 54: 55: /* Mode whose width is BITS_PER_WORD */ 1.1.1.2 ! root 56: extern enum machine_mode word_mode; 1.1 root 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); 1.1.1.2 ! root 148: fprintf (file, ", %lu\n", s->val); 1.1 root 149: } 150: } 151: else if (s->common) 152: { 153: fprintf (file, "\n\t.lcomm "); 154: prsym (file, s->name); 1.1.1.2 ! root 155: fprintf (file, ", %lu\n", s->val); 1.1 root 156: } 157: } 158: } 159: 160: 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: 1.1.1.2 ! root 364: bcopy (seg->data + i, (char *) &offset, sizeof (int)); 1.1 root 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: 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 auxilary 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; 1.1.1.2 ! root 606: bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr); 1.1 root 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: 1.1.1.2 ! root 870: byte = (char) bytecode; 1.1 root 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 1.1.1.2 ! root 912: bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...)) 1.1 root 913: { 1.1.1.2 ! root 914: #ifndef __STDC__ 1.1 root 915: enum bytecode_opcode opcode; 1.1.1.2 ! root 916: #endif ! 917: va_list arguments; 1.1 root 918: int nliteral, instruction; 919: 1.1.1.2 ! root 920: VA_START (arguments, opcode); 1.1 root 921: 1.1.1.2 ! root 922: #ifndef __STDC__ ! 923: opcode = va_arg (arguments, enum bytecode_opcode); ! 924: #endif 1.1 root 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: #ifdef BCDEBUG_PRINT_CODE 958: fputc ('\n', stderr); 959: #endif 960: } 961: 962: /* Emit the machine-code interface trampoline at the beginning of a byte 963: coded function. The argument is a label name of the interpreter 964: bytecode callinfo structure; the return value is a label name for 965: the beginning of the actual bytecode. */ 966: char * 967: bc_emit_trampoline (callinfo) 968: char *callinfo; 969: { 970: char mylab[20]; 971: static int n; 972: 973: sprintf (mylab, "*LB%d", n++); 974: 975: BC_EMIT_TRAMPOLINE (trampoline, callinfo); 976: 977: seg_defsym (bytecode, mylab); 978: return sym_lookup (mylab)->name; 979: } 980: 981: 982: /* Simple strdup */ 983: char * 984: bc_xstrdup (str) 985: char *str; 986: { 987: char *tmp = xmalloc (strlen (str) + 1); 988: 989: strcpy (tmp, str); 990: return tmp; 991: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.