^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Aic7xxx SCSI host adapter firmware assembler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2001, 2002 Adaptec Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 2. Redistributions in binary form must reproduce at minimum a disclaimer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * substantially similar to the "NO WARRANTY" disclaimer below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * ("Disclaimer") and any redistribution must be conditioned upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * including a substantially similar Disclaimer requirement for further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * binary redistribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * 3. Neither the names of the above-listed copyright holders nor the names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * of any contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * POSSIBILITY OF SUCH DAMAGES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * $FreeBSD$
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <regex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <sysexits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #if linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <machine/endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "aicasm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "aicasm_symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "aicasm_insformat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) typedef struct patch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) STAILQ_ENTRY(patch) links;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int patch_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u_int begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u_int skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u_int skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) } patch_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) STAILQ_HEAD(patch_list, patch) patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void usage(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void back_patch(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void output_code(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void output_listing(char *ifilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void dump_scope(scope_t *scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void emit_patch(scope_t *scope, int patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int check_patch(patch_t **start_patch, int start_instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int *skip_addr, int *func_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct path_list search_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int includes_search_curdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) char *appname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) char *stock_include_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) FILE *ofile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) char *ofilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) char *regfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) FILE *regfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) char *listfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) FILE *listfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) char *regdiagfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) FILE *regdiagfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int src_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int dst_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static STAILQ_HEAD(,instruction) seq_program;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct cs_tailq cs_tailq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct scope_list scope_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) symlist_t patch_functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) extern int yy_flex_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) extern int mm_flex_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) extern int yydebug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) extern int mmdebug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) extern FILE *yyin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) extern int yyparse(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int main(int argc, char *argv[]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) extern char *optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) extern int optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) char *inputfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) scope_t *sentinal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) STAILQ_INIT(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SLIST_INIT(&search_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) STAILQ_INIT(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) TAILQ_INIT(&cs_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) SLIST_INIT(&scope_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Set Sentinal scope node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) sentinal = scope_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sentinal->type = SCOPE_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) includes_search_curdir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) appname = *argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) regfile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) listfile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) yy_flex_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mm_flex_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) yydebug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mmdebug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) switch(ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (strcmp(optarg, "s") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) yy_flex_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mm_flex_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else if (strcmp(optarg, "p") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) yydebug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mmdebug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) fprintf(stderr, "%s: -d Requires either an "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) "'s' or 'p' argument\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) stop("-d: Assembler not built with debugging "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "information", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) stock_include_file = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Create a program listing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if ((listfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) listfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Don't complain about the -nostdinc directrive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (strcmp(optarg, "ostdinc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) fprintf(stderr, "%s: Unknown option -%c%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) appname, ch, optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if ((ofile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ofilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Create Register Diagnostic "printing" Functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if ((regdiagfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) regdiagfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if ((regfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) regfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) path_entry_t include_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (strcmp(optarg, "-") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (includes_search_curdir == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) fprintf(stderr, "%s: Warning - '-I-' "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) "specified multiple "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "times\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) includes_search_curdir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) for (include_dir = SLIST_FIRST(&search_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) include_dir != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) include_dir = SLIST_NEXT(include_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) links))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * All entries before a '-I-' only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * apply to includes specified with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * quotes instead of "<>".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) include_dir->quoted_includes_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) include_dir =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) (path_entry_t)malloc(sizeof(*include_dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (include_dir == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) stop(NULL, EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) include_dir->directory = strdup(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (include_dir->directory == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) stop(NULL, EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) include_dir->quoted_includes_only = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) SLIST_INSERT_HEAD(&search_path, include_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) argc -= optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) argv += optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (argc != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fprintf(stderr, "%s: No input file specified\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (regdiagfile != NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) && (regfile == NULL || stock_include_file == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) "%s: The -p option requires the -r and -i options.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) symtable_open();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) inputfilename = *argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) include_file(*argv, SOURCE_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) retval = yyparse();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (SLIST_FIRST(&scope_stack) == NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) stop("Unterminated conditional expression", EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Process outmost scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) process_scope(SLIST_FIRST(&scope_stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Decend the tree of scopes and insert/emit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * patches as appropriate. We perform a depth first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * tranversal, recursively handling each scope.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* start at the root scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dump_scope(SLIST_FIRST(&scope_stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Patch up forward jump addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) back_patch();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ofile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) output_code();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (regfile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) symtable_dump(regfile, regdiagfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (listfile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) output_listing(inputfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) stop(NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) usage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) (void)fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) " [-r register_output_file [-p register_diag_file -i includefile]]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) " [-l program_list_file]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) " input_file\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) exit(EX_USAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) back_patch()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cur_instr = STAILQ_NEXT(cur_instr, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (cur_instr->patch_label != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct ins_format3 *f3_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u_int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (cur_instr->patch_label->type != LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) char buf[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) snprintf(buf, sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) "Undefined label %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) cur_instr->patch_label->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) stop(buf, EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) f3_instr = &cur_instr->format.format3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) address = f3_instr->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) address += cur_instr->patch_label->info.linfo->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) f3_instr->address = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) output_code()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) critical_section_t *cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) symbol_node_t *cur_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int instrcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) instrcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) "/*\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) " * DO NOT EDIT - This file is automatically generated\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) " * from the following source files:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) " *\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "%s */\n", versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) fprintf(ofile, "static const uint8_t seqprog[] = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cur_instr = STAILQ_NEXT(cur_instr, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) cur_instr->format.bytes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) cur_instr->format.bytes[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) cur_instr->format.bytes[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) cur_instr->format.bytes[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) instrcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (patch_arg_list == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) stop("Patch argument list not defined",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * Output patch information. Patch functions first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) "typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) for (cur_node = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cur_node != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) cur_node = SLIST_NEXT(cur_node,links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) "static %spatch_func_t %spatch%d_func;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) "static int\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) "%spatch%d_func(%s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) "{\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) " return (%s);\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) "}\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cur_node->symbol->info.condinfo->func_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) cur_node->symbol->info.condinfo->func_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) patch_arg_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) cur_node->symbol->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "static const struct patch {\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) " %spatch_func_t *patch_func;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) " uint32_t begin :10,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) " skip_instr :10,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) " skip_patch :12;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "} patches[] = {\n", prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for (cur_patch = STAILQ_FIRST(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) cur_patch != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) cur_patch = STAILQ_NEXT(cur_patch,links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) cur_patch->patch_func, cur_patch->begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) cur_patch->skip_instr, cur_patch->skip_patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "static const struct cs {\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) " uint16_t begin;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) " uint16_t end;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) "} critical_sections[] = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) for (cs = TAILQ_FIRST(&cs_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) cs != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) cs = TAILQ_NEXT(cs, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) fprintf(ofile, "%s\t{ %d, %d }",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cs->begin_addr, cs->end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) "#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dump_scope(scope_t *scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) scope_t *cur_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * Emit the first patch for this scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) emit_patch(scope, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Dump each scope within this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) cur_scope = TAILQ_FIRST(&scope->inner_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) while (cur_scope != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dump_scope(cur_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) cur_scope = TAILQ_NEXT(cur_scope, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Emit the second, closing, patch for this scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) emit_patch(scope, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) emit_patch(scope_t *scope, int patch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) patch_info_t *pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) patch_t *new_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pinfo = &scope->patches[patch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (pinfo->skip_instr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* No-Op patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) new_patch = (patch_t *)malloc(sizeof(*new_patch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (new_patch == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) stop("Could not malloc patch structure", EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) memset(new_patch, 0, sizeof(*new_patch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (patch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) new_patch->patch_func = scope->func_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) new_patch->begin = scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) new_patch->patch_func = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) new_patch->begin = scope->end_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) new_patch->skip_instr = pinfo->skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) new_patch->skip_patch = pinfo->skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) STAILQ_INSERT_TAIL(&patches, new_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) output_listing(char *ifilename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) char buf[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) FILE *ifile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) symbol_node_t *cur_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int *func_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int instrcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int instrptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int func_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int skip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) instrcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) instrptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) line = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) skip_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if ((ifile = fopen(ifilename, "r")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) perror(ifilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) stop(NULL, EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * Determine which options to apply to this listing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cur_func != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) cur_func = SLIST_NEXT(cur_func, links))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) func_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) func_values = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (func_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) func_values = (int *)malloc(func_count * sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (func_values == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) stop("Could not malloc", EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) func_values[0] = 0; /* FALSE func */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) func_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * Ask the user to fill in the return values for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * the rest of the functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) for (cur_func = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cur_func = SLIST_NEXT(cur_func, links), func_count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) fprintf(stdout, "\n(%s)\n", cur_func->symbol->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) fprintf(stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) "Enter the return value for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) "this expression[T/F]:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) input = getchar();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) input = toupper(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (input == 'T') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) func_values[func_count] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) } else if (input == 'F') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) func_values[func_count] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (isatty(fileno(stdin)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) putchar(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) fprintf(stdout, "\nThanks!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Now output the listing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cur_patch = STAILQ_FIRST(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (check_patch(&cur_patch, instrcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &skip_addr, func_values) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* Don't count this instruction as it is in a patch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * that was removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) while (line < cur_instr->srcline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) fgets(buf, sizeof(buf), ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) fprintf(listfile, " \t%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cur_instr->format.bytes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cur_instr->format.bytes[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) cur_instr->format.bytes[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) cur_instr->format.bytes[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Macro expansions can cause several instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * to be output for a single source line. Only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * advance the line once in these cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (line == cur_instr->srcline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) fgets(buf, sizeof(buf), ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fprintf(listfile, "\t%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) fprintf(listfile, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) instrptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* Dump the remainder of the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) while(fgets(buf, sizeof(buf), ifile) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) fprintf(listfile, " %s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) fclose(ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) check_patch(patch_t **start_patch, int start_instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int *skip_addr, int *func_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cur_patch = *start_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) while (cur_patch != NULL && start_instr == cur_patch->begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (func_vals[cur_patch->patch_func] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* Start rejecting code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *skip_addr = start_instr + cur_patch->skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) for (skip = cur_patch->skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) skip > 0 && cur_patch != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) skip--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) cur_patch = STAILQ_NEXT(cur_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Accepted this patch. Advance to the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * one and wait for our intruction pointer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * hit this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) cur_patch = STAILQ_NEXT(cur_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *start_patch = cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (start_instr < *skip_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* Still skipping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * Print out error information if appropriate, and clean up before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * terminating the program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) stop(const char *string, int err_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (string != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) fprintf(stderr, "%s: ", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (yyfilename != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) fprintf(stderr, "Stopped at file %s, line %d - ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) yyfilename, yylineno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) fprintf(stderr, "%s\n", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (ofile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) fclose(ofile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) appname, ofilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) unlink(ofilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (regfile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) fclose(regfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) appname, regfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) unlink(regfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (listfile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) fclose(listfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) appname, listfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) unlink(listfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) symlist_free(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) symtable_close();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) exit(err_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct instruction *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) seq_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct instruction *new_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) new_instr = (struct instruction *)malloc(sizeof(struct instruction));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (new_instr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) stop("Unable to malloc instruction object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) memset(new_instr, 0, sizeof(*new_instr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) STAILQ_INSERT_TAIL(&seq_program, new_instr, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) new_instr->srcline = yylineno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return new_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) critical_section_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) cs_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) critical_section_t *new_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (new_cs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) stop("Unable to malloc critical_section object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) memset(new_cs, 0, sizeof(*new_cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return new_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) scope_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) scope_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) scope_t *new_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) new_scope = (scope_t *)malloc(sizeof(scope_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (new_scope == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) stop("Unable to malloc scope object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) memset(new_scope, 0, sizeof(*new_scope));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) TAILQ_INIT(&new_scope->inner_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (SLIST_FIRST(&scope_stack) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) new_scope, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* This patch is now the current scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return new_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) process_scope(scope_t *scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * We are "leaving" this scope. We should now have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * enough information to process the lists of scopes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * we encapsulate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) scope_t *cur_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) u_int skip_patch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) u_int skip_instr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) skip_patch_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) skip_instr_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) while (cur_scope != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u_int patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) patch0_patch_skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) switch (cur_scope->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) case SCOPE_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case SCOPE_ELSE_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (skip_instr_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* Create a tail patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) patch0_patch_skip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) cur_scope->patches[1].skip_patch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) skip_patch_count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) cur_scope->patches[1].skip_instr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) skip_instr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* Count Head patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) patch0_patch_skip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* Count any patches contained in our inner scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) patch0_patch_skip += cur_scope->inner_scope_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) cur_scope->patches[0].skip_patch = patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) cur_scope->patches[0].skip_instr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) cur_scope->end_addr - cur_scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) skip_instr_count += cur_scope->patches[0].skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) skip_patch_count += patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (cur_scope->type == SCOPE_IF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) scope->inner_scope_patches += skip_patch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) skip_patch_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) skip_instr_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) case SCOPE_ELSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* Count any patches contained in our innter scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) skip_patch_count += cur_scope->inner_scope_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) skip_instr_count += cur_scope->end_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) - cur_scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case SCOPE_ROOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) stop("Unexpected scope type encountered", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }