diff options
-rw-r--r-- | sys/dev/aic7xxx/aicasm/Makefile | 15 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm.c | 81 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm.h | 40 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_gram.y | 484 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_insformat.h | 40 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y | 164 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l | 154 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_scan.l | 323 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_symbol.c | 68 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aicasm/aicasm_symbol.h | 87 |
10 files changed, 1248 insertions, 208 deletions
diff --git a/sys/dev/aic7xxx/aicasm/Makefile b/sys/dev/aic7xxx/aicasm/Makefile index aca0fe1..2099dd5 100644 --- a/sys/dev/aic7xxx/aicasm/Makefile +++ b/sys/dev/aic7xxx/aicasm/Makefile @@ -5,12 +5,13 @@ PROG= aicasm CSRCS= aicasm.c aicasm_symbol.c -GENSRCS= aicasm_gram.c aicasm_scan.c +YSRCS= aicasm_gram.y aicasm_macro_gram.y +LSRCS= aicasm_scan.l aicasm_macro_scan.l -GENHDRS= y.tab.h +GENHDRS= aicasm_gram.h aicasm_macro_gram.h -SRCS= ${GENSRCS} ${CSRCS} -CLEANFILES+= ${GENSRCS} ${GENHDRS} y.output +SRCS= ${GENHDRS} ${CSRCS} ${YSRCS} ${LSRCS} +CLEANFILES+= ${GENHDRS} ${YSRCS:R:C/(.*)/\1.output/g} DPADD+= ${LIBL} LDADD+= -ll @@ -21,10 +22,12 @@ LDADD+= -ll DEPENDFILE= .endif -CFLAGS+= -I/usr/include -I. -I../../../dev/aic7xxx/aicasm +CFLAGS+= -I/usr/include -I. NOMAN= noman +YFLAGS= -b ${.TARGET:R} ${.TARGET:M*macro*:S/$(.TARGET)/-p mm/} -d +LFLAGS+= ${.TARGET:M*macro*:S/$(.TARGET)/-Pmm/} -.ifdef DEBUG +.ifdef AICASM_DEBUG CFLAGS+= -DDEBUG -g YFLAGS+= -t -v LFLAGS+= -d diff --git a/sys/dev/aic7xxx/aicasm/aicasm.c b/sys/dev/aic7xxx/aicasm/aicasm.c index dfb3ef7..760d79f 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm.c +++ b/sys/dev/aic7xxx/aicasm/aicasm.c @@ -1,7 +1,8 @@ /* * Aic7xxx SCSI host adapter firmware asssembler * - * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. + * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs. + * Copyright (c) 2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -9,26 +10,34 @@ * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm.c#8 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#14 $ * * $FreeBSD$ */ @@ -37,12 +46,19 @@ #include <ctype.h> #include <inttypes.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <unistd.h> +#if linux +#include <endian.h> +#else +#include <machine/endian.h> +#endif + #include "aicasm.h" #include "aicasm_symbol.h" #include "aicasm_insformat.h" @@ -75,6 +91,8 @@ char *regfilename; FILE *regfile; char *listfilename; FILE *listfile; +int src_mode; +int dst_mode; static STAILQ_HEAD(,instruction) seq_program; struct cs_tailq cs_tailq; @@ -83,7 +101,9 @@ symlist_t patch_functions; #if DEBUG extern int yy_flex_debug; +extern int mm_flex_debug; extern int yydebug; +extern int mmdebug; #endif extern FILE *yyin; extern int yyparse(void); @@ -116,7 +136,9 @@ main(int argc, char *argv[]) listfile = NULL; #if DEBUG yy_flex_debug = 0; + mm_flex_debug = 0; yydebug = 0; + mmdebug = 0; #endif while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != -1) { switch(ch) { @@ -124,8 +146,10 @@ main(int argc, char *argv[]) #if DEBUG if (strcmp(optarg, "s") == 0) { yy_flex_debug = 1; + mm_flex_debug = 1; } else if (strcmp(optarg, "p") == 0) { yydebug = 1; + mmdebug = 1; } else { fprintf(stderr, "%s: -d Requires either an " "'s' or 'p' argument\n", appname); @@ -228,8 +252,7 @@ main(int argc, char *argv[]) if (retval == 0) { if (SLIST_FIRST(&scope_stack) == NULL || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) { - stop("Unterminated conditional expression", - EX_DATAERR); + stop("Unterminated conditional expression", EX_DATAERR); /* NOTREACHED */ } @@ -340,6 +363,10 @@ output_code() } fprintf(ofile, "\n};\n\n"); + if (patch_arg_list == NULL) + stop("Patch argument list not defined", + EX_DATAERR); + /* * Output patch information. Patch functions first. */ @@ -347,31 +374,33 @@ output_code() cur_node != NULL; cur_node = SLIST_NEXT(cur_node,links)) { fprintf(ofile, -"static int ahc_patch%d_func(struct ahc_softc *ahc); +"static int aic_patch%d_func(%s); static int -ahc_patch%d_func(struct ahc_softc *ahc) +aic_patch%d_func(%s) { return (%s); }\n\n", cur_node->symbol->info.condinfo->func_num, + patch_arg_list, cur_node->symbol->info.condinfo->func_num, + patch_arg_list, cur_node->symbol->name); } fprintf(ofile, -"typedef int patch_func_t (struct ahc_softc *); -struct patch { +"typedef int patch_func_t (%s); +static struct patch { patch_func_t *patch_func; uint32_t begin :10, skip_instr :10, skip_patch :12; -} patches[] = {\n"); +} patches[] = {\n", patch_arg_list); for(cur_patch = STAILQ_FIRST(&patches); cur_patch != NULL; cur_patch = STAILQ_NEXT(cur_patch,links)) { - fprintf(ofile, "%s\t{ ahc_patch%d_func, %d, %d, %d }", + fprintf(ofile, "%s\t{ aic_patch%d_func, %d, %d, %d }", cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n", cur_patch->patch_func, cur_patch->begin, cur_patch->skip_instr, cur_patch->skip_patch); @@ -380,7 +409,7 @@ struct patch { fprintf(ofile, "\n};\n"); fprintf(ofile, -"struct cs { +"static struct cs { u_int16_t begin; u_int16_t end; } critical_sections[] = {\n"); @@ -396,8 +425,8 @@ struct patch { fprintf(ofile, "\n};\n"); fprintf(ofile, -"const int num_critical_sections = sizeof(critical_sections) - / sizeof(*critical_sections);\n"); +"static const int num_critical_sections = sizeof(critical_sections) + / sizeof(*critical_sections);\n"); fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); } diff --git a/sys/dev/aic7xxx/aicasm/aicasm.h b/sys/dev/aic7xxx/aicasm/aicasm.h index 361a9b2..61fe708 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm.h +++ b/sys/dev/aic7xxx/aicasm/aicasm.h @@ -2,6 +2,7 @@ * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters * * Copyright (c) 1997 Justin T. Gibbs. + * Copyright (c) 2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,25 +11,33 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm.h#5 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#9 $ * * $FreeBSD$ */ @@ -69,10 +78,15 @@ extern int includes_search_curdir; /* False if we've seen -I- */ extern char *appname; extern int yylineno; extern char *yyfilename; +extern char *patch_arg_list; extern char *versions; +extern int src_mode; +extern int dst_mode; +struct symbol; void stop(const char *errstring, int err_code); void include_file(char *file_name, include_type type); +void expand_macro(struct symbol *macro_symbol); struct instruction *seq_alloc(void); struct critical_section *cs_alloc(void); struct scope *scope_alloc(void); diff --git a/sys/dev/aic7xxx/aicasm/aicasm_gram.y b/sys/dev/aic7xxx/aicasm/aicasm_gram.y index f562e6e..fde3f02 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm_gram.y +++ b/sys/dev/aic7xxx/aicasm/aicasm_gram.y @@ -3,6 +3,7 @@ * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. * * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. + * Copyright (c) 2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,36 +12,46 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm_gram.y#7 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#14 $ * * $FreeBSD$ */ +#include <sys/types.h> + #include <inttypes.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> -#include <sys/types.h> #ifdef __linux__ #include "../queue.h" #else @@ -53,21 +64,29 @@ int yylineno; char *yyfilename; +char *patch_arg_list; char *versions; +static char errbuf[255]; +static char regex_pattern[255]; static symbol_t *cur_symbol; +static symbol_t *scb_or_sram_symbol; static symtype cur_symtype; -static symbol_t *accumulator; +static symbol_ref_t accumulator; +static symbol_ref_t mode_ptr; static symbol_ref_t allones; static symbol_ref_t allzeros; static symbol_ref_t none; static symbol_ref_t sindex; static int instruction_ptr; +static int num_srams; static int sram_or_scb_offset; static int download_constant_count; static int in_critical_section; static void process_bitmask(int mask_type, symbol_t *sym, int mask); static void initialize_symbol(symbol_t *symbol); +static void add_macro_arg(const char *argtext, int position); +static void add_macro_body(const char *bodytext); static void process_register(symbol_t **p_symbol); static void format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed, symbol_ref_t *src, int ret); @@ -83,13 +102,12 @@ static void add_conditional(symbol_t *symbol); static void add_version(const char *verstring); static int is_download_const(expression_t *immed); -#define YYDEBUG 1 #define SRAM_SYMNAME "SRAM_BASE" #define SCB_SYMNAME "SCB_BASE" %} %union { - int value; + u_int value; char *str; symbol_t *sym; symbol_ref_t sym_ref; @@ -100,6 +118,8 @@ static int is_download_const(expression_t *immed); %token <value> T_CONST +%token T_EXPORT + %token T_DOWNLOAD %token T_SCB @@ -110,10 +130,22 @@ static int is_download_const(expression_t *immed); %token T_SIZE +%token T_EXPR_LSHIFT + +%token T_EXPR_RSHIFT + %token <value> T_ADDRESS %token T_ACCESS_MODE +%token T_MODES + +%token T_DEFINE + +%token T_SET_SRC_MODE + +%token T_SET_DST_MODE + %token <value> T_MODE %token T_BEGIN_CS @@ -126,11 +158,11 @@ static int is_download_const(expression_t *immed); %token <value> T_NUMBER -%token <str> T_PATH T_STRING +%token <str> T_PATH T_STRING T_ARG T_MACROBODY %token <sym> T_CEXPR -%token T_EOF T_INCLUDE T_VERSION +%token T_EOF T_INCLUDE T_VERSION T_PATCH_ARG_LIST %token <value> T_SHR T_SHL T_ROR T_ROL @@ -154,7 +186,7 @@ static int is_download_const(expression_t *immed); %token T_NOP -%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX +%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX T_MODE_PTR %token T_A @@ -168,13 +200,15 @@ static int is_download_const(expression_t *immed); %type <expression> expression immediate immediate_or_a -%type <value> ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne +%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne -%type <value> numerical_value +%type <value> numerical_value mode_value mode_list macro_arglist %left '|' %left '&' +%left T_EXPR_LSHIFT T_EXPR_RSHIFT %left '+' '-' +%left '*' '/' %right '~' %nonassoc UMINUS %% @@ -182,18 +216,26 @@ static int is_download_const(expression_t *immed); program: include | program include +| patch_arg_list +| program patch_arg_list | version | program version | register | program register | constant | program constant +| macrodefn +| program macrodefn | scratch_ram | program scratch_ram | scb | program scb | label | program label +| set_src_mode +| program set_src_mode +| set_dst_mode +| program set_dst_mode | critical_section_start | program critical_section_start | critical_section_end @@ -215,6 +257,18 @@ include: } ; +patch_arg_list: + T_PATCH_ARG_LIST '=' T_STRING + { + if (patch_arg_list != NULL) + stop("Patch argument list multiply defined", + EX_DATAERR); + patch_arg_list = strdup($3); + if (patch_arg_list == NULL) + stop("Unable to record patch arg list", EX_SOFTWARE); + } +; + version: T_VERSION '=' T_STRING { add_version($3); } @@ -271,10 +325,12 @@ reg_attribute: reg_address | size | access_mode +| modes | bit_defn | mask_defn | alias | accumulator +| mode_pointer | allones | allzeros | none @@ -292,6 +348,18 @@ size: T_SIZE T_NUMBER { cur_symbol->info.rinfo->size = $2; + if (scb_or_sram_symbol != NULL) { + u_int max_addr; + u_int sym_max_addr; + + max_addr = scb_or_sram_symbol->info.rinfo->address + + scb_or_sram_symbol->info.rinfo->size; + sym_max_addr = cur_symbol->info.rinfo->address + + cur_symbol->info.rinfo->size; + + if (sym_max_addr > max_addr) + stop("SCB or SRAM space exhausted", EX_DATAERR); + } } ; @@ -302,6 +370,54 @@ access_mode: } ; +modes: + T_MODES mode_list + { + cur_symbol->info.rinfo->modes = $2; + } +; + +mode_list: + mode_value + { + $$ = $1; + } +| mode_list ',' mode_value + { + $$ = $1 | $3; + } +; + +mode_value: + T_NUMBER + { + if ($1 > 4) { + stop("Valid register modes range between 0 and 4.", + EX_DATAERR); + /* NOTREACHED */ + } + + $$ = (0x1 << $1); + } +| T_SYMBOL + { + symbol_t *symbol; + + symbol = $1; + if (symbol->type != CONST) { + stop("Only \"const\" symbols allowed in " + "mode definitions.", EX_DATAERR); + /* NOTREACHED */ + } + if (symbol->info.cinfo->value > 4) { + stop("Valid register modes range between 0 and 4.", + EX_DATAERR); + /* NOTREACHED */ + } + $$ = (0x1 << symbol->info.cinfo->value); + } +; + bit_defn: T_BIT T_SYMBOL T_NUMBER { @@ -333,12 +449,24 @@ alias: accumulator: T_ACCUM { - if (accumulator != NULL) { + if (accumulator.symbol != NULL) { stop("Only one accumulator definition allowed", EX_DATAERR); /* NOTREACHED */ } - accumulator = cur_symbol; + accumulator.symbol = cur_symbol; + } +; + +mode_pointer: + T_MODE_PTR + { + if (mode_ptr.symbol != NULL) { + stop("Only one mode pointer definition allowed", + EX_DATAERR); + /* NOTREACHED */ + } + mode_ptr.symbol = cur_symbol; } ; @@ -419,6 +547,34 @@ expression: &($1.referenced_syms), &($3.referenced_syms)); } +| expression '*' expression + { + $$.value = $1.value * $3.value; + symlist_merge(&($$.referenced_syms), + &($1.referenced_syms), + &($3.referenced_syms)); + } +| expression '/' expression + { + $$.value = $1.value / $3.value; + symlist_merge(&($$.referenced_syms), + &($1.referenced_syms), + &($3.referenced_syms)); + } +| expression T_EXPR_LSHIFT expression + { + $$.value = $1.value << $3.value; + symlist_merge(&$$.referenced_syms, + &$1.referenced_syms, + &$3.referenced_syms); + } +| expression T_EXPR_RSHIFT expression + { + $$.value = $1.value >> $3.value; + symlist_merge(&$$.referenced_syms, + &$1.referenced_syms, + &$3.referenced_syms); + } | '(' expression ')' { $$ = $2; @@ -462,12 +618,10 @@ expression: case UNINITIALIZED: default: { - char buf[255]; - - snprintf(buf, sizeof(buf), + snprintf(errbuf, sizeof(errbuf), "Undefined symbol %s referenced", symbol->name); - stop(buf, EX_DATAERR); + stop(errbuf, EX_DATAERR); /* NOTREACHED */ break; } @@ -488,7 +642,6 @@ constant: $2->type = CONST; initialize_symbol($2); $2->info.cinfo->value = $3; - $2->info.cinfo->define = $1; } | T_CONST T_SYMBOL T_DOWNLOAD { @@ -505,7 +658,54 @@ constant: $2->type = DOWNLOAD_CONST; initialize_symbol($2); $2->info.cinfo->value = download_constant_count++; - $2->info.cinfo->define = FALSE; + } +; + +macrodefn_prologue: + T_DEFINE T_SYMBOL + { + if ($2->type != UNINITIALIZED) { + stop("Re-definition of symbol as a macro", + EX_DATAERR); + /* NOTREACHED */ + } + cur_symbol = $2; + cur_symbol->type = MACRO; + initialize_symbol(cur_symbol); + } +; + +macrodefn: + macrodefn_prologue T_MACROBODY + { + add_macro_body($2); + } +| macrodefn_prologue '(' macro_arglist ')' T_MACROBODY + { + add_macro_body($5); + cur_symbol->info.macroinfo->narg = $3; + } +; + +macro_arglist: + { + /* Macros can take no arguments */ + $$ = 0; + } +| T_ARG + { + $$ = 1; + add_macro_arg($1, 0); + } +| macro_arglist ',' T_ARG + { + if ($1 == 0) { + stop("Comma without preceeding argument in arg list", + EX_DATAERR); + /* NOTREACHED */ + } + $$ = $1 + 1; + add_macro_arg($3, $1); } ; @@ -523,13 +723,10 @@ numerical_value: scratch_ram: T_SRAM '{' { + snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME, + num_srams); cur_symbol = symtable_get(SRAM_SYMNAME); cur_symtype = SRAMLOC; - if (cur_symbol->type != UNINITIALIZED) { - stop("Only one SRAM definition allowed", - EX_DATAERR); - /* NOTREACHED */ - } cur_symbol->type = SRAMLOC; initialize_symbol(cur_symbol); } @@ -537,10 +734,15 @@ scratch_ram: { sram_or_scb_offset = cur_symbol->info.rinfo->address; } - scb_or_sram_reg_list + size + { + scb_or_sram_symbol = cur_symbol; + } + scb_or_sram_attributes '}' { cur_symbol = NULL; + scb_or_sram_symbol = NULL; } ; @@ -563,13 +765,25 @@ scb: { sram_or_scb_offset = cur_symbol->info.rinfo->address; } - scb_or_sram_reg_list + size + { + scb_or_sram_symbol = cur_symbol; + } + scb_or_sram_attributes '}' { cur_symbol = NULL; + scb_or_sram_symbol = NULL; } ; +scb_or_sram_attributes: + /* NULL definition is okay */ +| modes +| scb_or_sram_reg_list +| modes scb_or_sram_reg_list +; + scb_or_sram_reg_list: reg_definition | scb_or_sram_reg_list reg_definition @@ -610,11 +824,11 @@ reg_symbol: } | T_A { - if (accumulator == NULL) { + if (accumulator.symbol == NULL) { stop("No accumulator has been defined", EX_DATAERR); /* NOTREACHED */ } - $$.symbol = accumulator; + $$.symbol = accumulator.symbol; $$.offset = 0; } ; @@ -635,6 +849,14 @@ immediate: immediate_or_a: expression { + if ($1.value == 0 && is_download_const(&$1) == 0) { + snprintf(errbuf, sizeof(errbuf), + "\nExpression evaluates to 0 and thus " + "references the accumulator.\n " + "If this is the desired effect, use 'A' " + "instead.\n"); + stop(errbuf, EX_DATAERR); + } $$ = $1; } | T_A @@ -667,8 +889,22 @@ ret: { $$ = 1; } ; +set_src_mode: + T_SET_SRC_MODE T_NUMBER ';' + { + src_mode = $2; + } +; + +set_dst_mode: + T_SET_DST_MODE T_NUMBER ';' + { + dst_mode = $2; + } +; + critical_section_start: - T_BEGIN_CS + T_BEGIN_CS ';' { critical_section_t *cs; @@ -683,7 +919,7 @@ critical_section_start: } critical_section_end: - T_END_CS + T_END_CS ';' { critical_section_t *cs; @@ -696,16 +932,23 @@ critical_section_end: in_critical_section = FALSE; } +export: + { $$ = 0; } +| T_EXPORT + { $$ = 1; } +; + label: - T_SYMBOL ':' + export T_SYMBOL ':' { - if ($1->type != UNINITIALIZED) { + if ($2->type != UNINITIALIZED) { stop("Program label multiply defined", EX_DATAERR); /* NOTREACHED */ } - $1->type = LABEL; - initialize_symbol($1); - $1->info.linfo->address = instruction_ptr; + $2->type = LABEL; + initialize_symbol($2); + $2->info.linfo->address = instruction_ptr; + $2->info.linfo->exported = $1; } ; @@ -1119,6 +1362,16 @@ initialize_symbol(symbol_t *symbol) } memset(symbol->info.rinfo, 0, sizeof(struct reg_info)); + /* + * Default to allowing access in all register modes + * or to the mode specified by the SCB or SRAM space + * we are in. + */ + if (scb_or_sram_symbol != NULL) + symbol->info.rinfo->modes = + scb_or_sram_symbol->info.rinfo->modes; + else + symbol->info.rinfo->modes = ~0; break; case ALIAS: symbol->info.ainfo = @@ -1172,6 +1425,17 @@ initialize_symbol(symbol_t *symbol) memset(symbol->info.condinfo, 0, sizeof(struct cond_info)); break; + case MACRO: + symbol->info.macroinfo = + (struct macro_info *)malloc(sizeof(struct macro_info)); + if (symbol->info.macroinfo == NULL) { + stop("Can't create macro info", EX_SOFTWARE); + /* NOTREACHED */ + } + memset(symbol->info.macroinfo, 0, + sizeof(struct macro_info)); + STAILQ_INIT(&symbol->info.macroinfo->args); + break; default: stop("Call to initialize_symbol with invalid symbol type", EX_SOFTWARE); @@ -1181,25 +1445,75 @@ initialize_symbol(symbol_t *symbol) } static void +add_macro_arg(const char *argtext, int argnum) +{ + struct macro_arg *marg; + int i; + int retval; + + + if (cur_symbol == NULL || cur_symbol->type != MACRO) { + stop("Invalid current symbol for adding macro arg", + EX_SOFTWARE); + /* NOTREACHED */ + } + + marg = (struct macro_arg *)malloc(sizeof(*marg)); + if (marg == NULL) { + stop("Can't create macro_arg structure", EX_SOFTWARE); + /* NOTREACHED */ + } + marg->replacement_text = NULL; + retval = snprintf(regex_pattern, sizeof(regex_pattern), + "[^-/A-Za-z0-9_](%s)([^-/A-Za-z0-9_]|$)", + argtext); + if (retval >= sizeof(regex_pattern)) { + stop("Regex text buffer too small for arg", + EX_SOFTWARE); + /* NOTREACHED */ + } + retval = regcomp(&marg->arg_regex, regex_pattern, REG_EXTENDED); + if (retval != 0) { + stop("Regex compilation failed", EX_SOFTWARE); + /* NOTREACHED */ + } + STAILQ_INSERT_TAIL(&cur_symbol->info.macroinfo->args, marg, links); +} + +static void +add_macro_body(const char *bodytext) +{ + if (cur_symbol == NULL || cur_symbol->type != MACRO) { + stop("Invalid current symbol for adding macro arg", + EX_SOFTWARE); + /* NOTREACHED */ + } + cur_symbol->info.macroinfo->body = strdup(bodytext); + if (cur_symbol->info.macroinfo->body == NULL) { + stop("Can't duplicate macro body text", EX_SOFTWARE); + /* NOTREACHED */ + } +} + +static void process_register(symbol_t **p_symbol) { - char buf[255]; symbol_t *symbol = *p_symbol; if (symbol->type == UNINITIALIZED) { - snprintf(buf, sizeof(buf), "Undefined register %s", + snprintf(errbuf, sizeof(errbuf), "Undefined register %s", symbol->name); - stop(buf, EX_DATAERR); + stop(errbuf, EX_DATAERR); /* NOTREACHED */ } else if (symbol->type == ALIAS) { *p_symbol = symbol->info.ainfo->parent; } else if ((symbol->type != REGISTER) && (symbol->type != SCBLOC) && (symbol->type != SRAMLOC)) { - snprintf(buf, sizeof(buf), + snprintf(errbuf, sizeof(errbuf), "Specified symbol %s is not a register", symbol->name); - stop(buf, EX_DATAERR); + stop(errbuf, EX_DATAERR); } } @@ -1233,6 +1547,47 @@ format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed, if (is_download_const(immed)) f1_instr->parity = 1; + else if (dest->symbol == mode_ptr.symbol) { + u_int src_value; + u_int dst_value; + + /* + * Attempt to update mode information if + * we are operating on the mode register. + */ + if (src->symbol == allones.symbol) + src_value = 0xFF; + else if (src->symbol == allzeros.symbol) + src_value = 0; + else if (src->symbol == mode_ptr.symbol) + src_value = (dst_mode << 4) | src_mode; + else + goto cant_update; + + switch (opcode) { + case AIC_OP_AND: + dst_value = src_value & immed->value; + break; + case AIC_OP_XOR: + dst_value = src_value ^ immed->value; + break; + case AIC_OP_ADD: + dst_value = (src_value + immed->value) & 0xFF; + break; + case AIC_OP_OR: + dst_value = src_value | immed->value; + break; + break; + case AIC_OP_BMOV: + dst_value = src_value; + break; + default: + goto cant_update; + } + src_mode = dst_value & 0xF; + dst_mode = (dst_value >> 4) & 0xF; +cant_update: + } symlist_free(&immed->referenced_syms); instruction_ptr++; @@ -1341,6 +1696,14 @@ format_3_instr(int opcode, symbol_ref_t *src, static void test_readable_symbol(symbol_t *symbol) { + + if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) { + snprintf(errbuf, sizeof(errbuf), + "Register %s unavailable in source reg mode %d", + symbol->name, src_mode); + stop(errbuf, EX_DATAERR); + } + if (symbol->info.rinfo->mode == WO) { stop("Write Only register specified as source", EX_DATAERR); @@ -1351,6 +1714,14 @@ test_readable_symbol(symbol_t *symbol) static void test_writable_symbol(symbol_t *symbol) { + + if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) { + snprintf(errbuf, sizeof(errbuf), + "Register %s unavailable in destination reg mode %d", + symbol->name, dst_mode); + stop(errbuf, EX_DATAERR); + } + if (symbol->info.rinfo->mode == RO) { stop("Read Only register specified as destination", EX_DATAERR); @@ -1363,7 +1734,6 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) { symbol_node_t *node; int and_op; - char buf[255]; and_op = FALSE; if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ) @@ -1376,11 +1746,11 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) */ if (and_op == FALSE && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) { - snprintf(buf, sizeof(buf), + snprintf(errbuf, sizeof(errbuf), "Invalid bit(s) 0x%x in immediate written to %s", expression->value & ~symbol->info.rinfo->valid_bitmask, symbol->name); - stop(buf, EX_DATAERR); + stop(errbuf, EX_DATAERR); /* NOTREACHED */ } @@ -1388,7 +1758,7 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) * Now make sure that all of the symbols referenced by the * expression are defined for this register. */ - if(symbol->info.rinfo->typecheck_masks != FALSE) { + if (symbol->info.rinfo->typecheck_masks != FALSE) { for(node = expression->referenced_syms.slh_first; node != NULL; node = node->links.sle_next) { @@ -1396,11 +1766,11 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) || node->symbol->type == BIT) && symlist_search(&node->symbol->info.minfo->symrefs, symbol->name) == NULL) { - snprintf(buf, sizeof(buf), + snprintf(errbuf, sizeof(errbuf), "Invalid bit or mask %s " "for register %s", node->symbol->name, symbol->name); - stop(buf, EX_DATAERR); + stop(errbuf, EX_DATAERR); /* NOTREACHED */ } } diff --git a/sys/dev/aic7xxx/aicasm/aicasm_insformat.h b/sys/dev/aic7xxx/aicasm/aicasm_insformat.h index 9ac15e7..4ce57b8 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm_insformat.h +++ b/sys/dev/aic7xxx/aicasm/aicasm_insformat.h @@ -11,35 +11,37 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm_insformat.h#4 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#8 $ * * $FreeBSD$ */ -#if linux -#include <endian.h> -#else -#include <machine/endian.h> -#endif - struct ins_format1 { #if BYTE_ORDER == LITTLE_ENDIAN uint32_t immediate : 8, diff --git a/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y b/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y new file mode 100644 index 0000000..31ca9a5 --- /dev/null +++ b/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y @@ -0,0 +1,164 @@ +%{ +/* + * Sub-parser for macro invocation in the Aic7xxx SCSI + * Host adapter sequencer assembler. + * + * Copyright (c) 2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id$ + * + * $FreeBSD$ + */ + +#include <sys/types.h> + +#include <inttypes.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> + +#ifdef __linux__ +#include "../queue.h" +#else +#include <sys/queue.h> +#endif + +#include "aicasm.h" +#include "aicasm_symbol.h" +#include "aicasm_insformat.h" + +static symbol_t *macro_symbol; + +static void add_macro_arg(const char *argtext, int position); + +%} + +%union { + int value; + char *str; + symbol_t *sym; +} + + +%token <str> T_ARG + +%token <sym> T_SYMBOL + +%type <value> macro_arglist + +%% + +macrocall: + T_SYMBOL '(' + { + macro_symbol = $1; + } + macro_arglist ')' + { + if (macro_symbol->info.macroinfo->narg != $4) { + printf("Narg == %d", macro_symbol->info.macroinfo->narg); + stop("Too few arguments for macro invocation", + EX_DATAERR); + /* NOTREACHED */ + } + macro_symbol = NULL; + YYACCEPT; + } +; + +macro_arglist: + { + /* Macros can take 0 arguments */ + $$ = 0; + } +| T_ARG + { + $$ = 1; + add_macro_arg($1, 1); + } +| macro_arglist ',' T_ARG + { + if ($1 == 0) { + stop("Comma without preceeding argument in arg list", + EX_DATAERR); + /* NOTREACHED */ + } + $$ = $1 + 1; + add_macro_arg($3, $$); + } +; + +%% + +static void +add_macro_arg(const char *argtext, int argnum) +{ + struct macro_arg *marg; + int i; + + if (macro_symbol == NULL || macro_symbol->type != MACRO) { + stop("Invalid current symbol for adding macro arg", + EX_SOFTWARE); + /* NOTREACHED */ + } + /* + * Macro Invocation. Find the appropriate argument and fill + * in the replace ment text for this call. + */ + i = 0; + STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { + i++; + if (i == argnum) + break; + } + if (marg == NULL) { + stop("Too many arguments for macro invocation", EX_DATAERR); + /* NOTREACHED */ + } + marg->replacement_text = strdup(argtext); + if (marg->replacement_text == NULL) { + stop("Unable to replicate replacement text", EX_SOFTWARE); + /* NOTREACHED */ + } +} + +void +mmerror(const char *string) +{ + stop(string, EX_DATAERR); +} diff --git a/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l b/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l new file mode 100644 index 0000000..a0741b4 --- /dev/null +++ b/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l @@ -0,0 +1,154 @@ +%{ +/* + * Sub-Lexical Analyzer for macro invokation in + * the Aic7xxx SCSI Host adapter sequencer assembler. + * + * Copyright (c) 2001 Adaptec Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $Id$ + * + * $FreeBSD$ + */ + +#include <sys/types.h> + +#include <limits.h> +#include <regex.h> +#include <stdio.h> +#include <string.h> +#include <sysexits.h> +#ifdef __linux__ +#include "../queue.h" +#else +#include <sys/queue.h> +#endif + +#include "aicasm.h" +#include "aicasm_symbol.h" +#include "aicasm_macro_gram.h" + +#define MAX_STR_CONST 4096 +static char string_buf[MAX_STR_CONST]; +static char *string_buf_ptr; +static int parren_count; +static char buf[255]; +%} + +WORD [A-Za-z_][-A-Za-z_0-9]* +SPACE [ \t]+ +MCARG [^(), \t]+ + +%x ARGLIST + +%% +\n { + ++yylineno; + } +<ARGLIST>{SPACE} ; +<ARGLIST>\( { + parren_count++; + if (parren_count == 1) { + string_buf_ptr = string_buf; + return ('('); + } + *string_buf_ptr++ = '('; + } +<ARGLIST>\) { + if (parren_count == 1) { + if (string_buf_ptr != string_buf) { + /* + * Return an argument and + * rescan this parren so we + * can return it as well. + */ + *string_buf_ptr = '\0'; + mmlval.str = string_buf; + string_buf_ptr = string_buf; + unput(')'); + return T_ARG; + } + BEGIN INITIAL; + return (')'); + } + parren_count--; + *string_buf_ptr++ = ')'; + } +<ARGLIST>{MCARG} { + char *yptr; + + yptr = mmtext; + while (*yptr) + *string_buf_ptr++ = *yptr++; + } +<ARGLIST>\, { + if (string_buf_ptr != string_buf) { + /* + * Return an argument and + * rescan this comma so we + * can return it as well. + */ + *string_buf_ptr = '\0'; + mmlval.str = string_buf; + string_buf_ptr = string_buf; + unput(','); + return T_ARG; + } + return ','; + } +{WORD}[(] { + /* May be a symbol or a macro invocation. */ + mmlval.sym = symtable_get(mmtext); + if (mmlval.sym->type != MACRO) { + stop("Expecting Macro Name", + EX_DATAERR); + } + unput('('); + parren_count = 0; + BEGIN ARGLIST; + return T_SYMBOL; + } +. { + snprintf(buf, sizeof(buf), "Invalid character " + "'%c'", mmtext[0]); + stop(buf, EX_DATAERR); + } +%% + +int +mmwrap() +{ + stop("EOF encountered in macro call", EX_DATAERR); +} diff --git a/sys/dev/aic7xxx/aicasm/aicasm_scan.l b/sys/dev/aic7xxx/aicasm/aicasm_scan.l index 4be3727..edf303a 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm_scan.l +++ b/sys/dev/aic7xxx/aicasm/aicasm_scan.l @@ -2,7 +2,8 @@ /* * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. * - * Copyright (c) 1997, 1998 Justin T. Gibbs. + * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. + * Copyright (c) 2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,25 +12,33 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#5 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 $ * * $FreeBSD$ */ @@ -37,6 +46,7 @@ #include <sys/types.h> #include <limits.h> +#include <regex.h> #include <stdio.h> #include <string.h> #include <sysexits.h> @@ -48,25 +58,31 @@ #include "aicasm.h" #include "aicasm_symbol.h" -#include "y.tab.h" - -#define MAX_STR_CONST 256 -char string_buf[MAX_STR_CONST]; -char *string_buf_ptr; -int parren_count; -int quote_count; +#include "aicasm_gram.h" + +/* This is used for macro body capture too, so err on the large size. */ +#define MAX_STR_CONST 4096 +static char string_buf[MAX_STR_CONST]; +static char *string_buf_ptr; +static int parren_count; +static int quote_count; +static char buf[255]; %} -%option nounput - -PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* +PATH ([/]*[-A-Za-z0-9_.])+ WORD [A-Za-z_][-A-Za-z_0-9]* SPACE [ \t]+ +MCARG [^(), \t]+ +MBODY ((\\[^\n])*[^\n\\]*)+ %x COMMENT %x CEXPR %x INCLUDE %x STRING +%x MACRODEF +%x MACROARGLIST +%x MACROCALLARGS +%x MACROBODY %% \n { ++yylineno; } @@ -115,6 +131,7 @@ if[ \t]*\( { } VERSION { return T_VERSION; } +PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } \" { string_buf_ptr = string_buf; BEGIN STRING; @@ -133,14 +150,16 @@ VERSION { return T_VERSION; } yylval.str = string_buf; return T_STRING; } -{SPACE} ; +{SPACE} ; /* Register/SCB/SRAM definition keywords */ +export { return T_EXPORT; } register { return T_REGISTER; } const { yylval.value = FALSE; return T_CONST; } download { return T_DOWNLOAD; } address { return T_ADDRESS; } access_mode { return T_ACCESS_MODE; } +modes { return T_MODES; } RW|RO|WO { if (strcmp(yytext, "RW") == 0) yylval.value = RW; @@ -152,6 +171,8 @@ RW|RO|WO { } BEGIN_CRITICAL { return T_BEGIN_CS; } END_CRITICAL { return T_END_CS; } +SET_SRC_MODE { return T_SET_SRC_MODE; } +SET_DST_MODE { return T_SET_DST_MODE; } bit { return T_BIT; } mask { return T_MASK; } alias { return T_ALIAS; } @@ -159,6 +180,7 @@ size { return T_SIZE; } scb { return T_SCB; } scratch_ram { return T_SRAM; } accumulator { return T_ACCUM; } +mode_pointer { return T_MODE_PTR; } allones { return T_ALLONES; } allzeros { return T_ALLZEROS; } none { return T_NONE; } @@ -199,7 +221,9 @@ nop { return T_NOP; } else { return T_ELSE; } /* Allowed Symbols */ -[-+,:()~|&."{};<>[\]!=] { return yytext[0]; } +\<\< { return T_EXPR_LSHIFT; } +\>\> { return T_EXPR_RSHIFT; } +[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; } /* Number processing */ 0[0-7]* { @@ -216,7 +240,6 @@ else { return T_ELSE; } yylval.value = strtol(yytext, NULL, 10); return T_NUMBER; } - /* Include Files */ #include{SPACE} { BEGIN INCLUDE; @@ -231,13 +254,7 @@ else { return T_ELSE; } quote_count++; return yytext[0]; } -<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } - - /* For parsing C include files with #define foo */ -#define { yylval.value = TRUE; return T_CONST; } - /* Throw away macros */ -#define[^\n]*[()]+[^\n]* ; -<INITIAL,INCLUDE>{PATH} { +<INCLUDE>{PATH} { char *yptr; yptr = yytext; @@ -248,12 +265,158 @@ else { return T_ELSE; } *string_buf_ptr = '\0'; return T_PATH; } +<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } +#define{SPACE} { + BEGIN MACRODEF; + return T_DEFINE; + } +<MACRODEF>{WORD}{SPACE} { + char *yptr; -{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } + /* Strip space and return as a normal symbol */ + yptr = yytext; + while (*yptr != ' ' && *yptr != '\t') + yptr++; + *yptr = '\0'; + yylval.sym = symtable_get(yytext); + string_buf_ptr = string_buf; + BEGIN MACROBODY; + return T_SYMBOL; + } +<MACRODEF>{WORD}\( { + /* + * We store the symbol with its opening + * parren so we can differentiate macros + * that take args from macros with the + * same name that do not take args as + * is allowed in C. + */ + BEGIN MACROARGLIST; + yylval.sym = symtable_get(yytext); + unput('('); + return T_SYMBOL; + } +<MACROARGLIST>{WORD} { + yylval.str = yytext; + return T_ARG; + } +<MACROARGLIST>{SPACE} ; +<MACROARGLIST>[(,] { + return yytext[0]; + } +<MACROARGLIST>[)] { + string_buf_ptr = string_buf; + BEGIN MACROBODY; + return ')'; + } +<MACROARGLIST>. { + snprintf(buf, sizeof(buf), "Invalid character " + "'%c' in macro argument list", + yytext[0]); + stop(buf, EX_DATAERR); + } +<MACROCALLARGS>{SPACE} ; +<MACROCALLARGS>\( { + parren_count++; + if (parren_count == 1) + return ('('); + *string_buf_ptr++ = '('; + } +<MACROCALLARGS>\) { + parren_count--; + if (parren_count == 0) { + BEGIN INITIAL; + return (')'); + } + *string_buf_ptr++ = ')'; + } +<MACROCALLARGS>{MCARG} { + char *yptr; -. { - char buf[255]; + yptr = yytext; + while (*yptr) + *string_buf_ptr++ = *yptr++; + } +<MACROCALLARGS>\, { + if (string_buf_ptr != string_buf) { + /* + * Return an argument and + * rescan this comma so we + * can return it as well. + */ + *string_buf_ptr = '\0'; + yylval.str = string_buf; + string_buf_ptr = string_buf; + unput(','); + return T_ARG; + } + return ','; + } +<MACROBODY>\\\n { + /* Eat escaped newlines. */ + ++yylineno; + } +<MACROBODY>\n { + /* Macros end on the first unescaped newline. */ + BEGIN INITIAL; + *string_buf_ptr = '\0'; + yylval.str = string_buf; + ++yylineno; + return T_MACROBODY; + } +<MACROBODY>{MBODY} { + char *yptr; + yptr = yytext; + while (*yptr) + *string_buf_ptr++ = *yptr++; + } +{WORD}\( { + char *yptr; + char *ycopy; + + /* May be a symbol or a macro invocation. */ + yylval.sym = symtable_get(yytext); + if (yylval.sym->type == MACRO) { + YY_BUFFER_STATE old_state; + YY_BUFFER_STATE temp_state; + + ycopy = strdup(yytext); + yptr = ycopy + yyleng; + while (yptr > ycopy) + unput(*--yptr); + old_state = YY_CURRENT_BUFFER; + temp_state = + yy_create_buffer(stdin, + YY_BUF_SIZE); + yy_switch_to_buffer(temp_state); + mm_switch_to_buffer(old_state); + mmparse(); + mm_switch_to_buffer(temp_state); + yy_switch_to_buffer(old_state); + mm_delete_buffer(temp_state); + expand_macro(yylval.sym); + } else { + if (yylval.sym->type == UNINITIALIZED) { + /* Try without the '(' */ + symbol_delete(yylval.sym); + yytext[yyleng-1] = '\0'; + yylval.sym = + symtable_get(yytext); + } + unput('('); + return T_SYMBOL; + } + } +{WORD} { + yylval.sym = symtable_get(yytext); + if (yylval.sym->type == MACRO) { + expand_macro(yylval.sym); + } else { + return T_SYMBOL; + } + } +. { snprintf(buf, sizeof(buf), "Invalid character " "'%c'", yytext[0]); stop(buf, EX_DATAERR); @@ -322,6 +485,92 @@ include_file(char *file_name, include_type type) yyfilename = strdup(file_name); } +static void next_substitution(struct symbol *mac_symbol, const char *body_pos, + const char **next_match, + struct macro_arg **match_marg, regmatch_t *match); + +void +expand_macro(struct symbol *macro_symbol) +{ + struct macro_arg *marg; + struct macro_arg *match_marg; + const char *body_head; + const char *body_pos; + const char *next_match; + + /* + * Due to the nature of unput, we must work + * backwards through the macro body performing + * any expansions. + */ + body_head = macro_symbol->info.macroinfo->body; + body_pos = body_head + strlen(body_head); + while (body_pos > body_head) { + regmatch_t match; + + next_match = body_head; + match_marg = NULL; + next_substitution(macro_symbol, body_pos, &next_match, + &match_marg, &match); + + /* Put back everything up until the replacement. */ + while (body_pos > next_match) + unput(*--body_pos); + + /* Perform the replacement. */ + if (match_marg != NULL) { + const char *strp; + + next_match = match_marg->replacement_text; + strp = next_match + strlen(next_match); + while (strp > next_match) + unput(*--strp); + + /* Skip past the unexpanded macro arg. */ + body_pos -= match.rm_eo - match.rm_so; + } + } + + /* Cleanup replacement text. */ + STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { + free(marg->replacement_text); + } +} + +/* + * Find the next substitution in the macro working backwards from + * body_pos until the beginning of the macro buffer. next_match + * should be initialized to the beginning of the macro buffer prior + * to calling this routine. + */ +static void +next_substitution(struct symbol *mac_symbol, const char *body_pos, + const char **next_match, struct macro_arg **match_marg, + regmatch_t *match) +{ + regmatch_t matches[2]; + struct macro_arg *marg; + const char *search_pos; + int retval; + + do { + search_pos = *next_match; + + STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) { + + retval = regexec(&marg->arg_regex, search_pos, 2, + matches, 0); + if (retval == 0 + && (matches[1].rm_eo + search_pos) <= body_pos + && (matches[1].rm_eo + search_pos) > *next_match) { + *match = matches[1]; + *next_match = match->rm_eo + search_pos; + *match_marg = marg; + } + } + } while (search_pos != *next_match); +} + int yywrap() { diff --git a/sys/dev/aic7xxx/aicasm/aicasm_symbol.c b/sys/dev/aic7xxx/aicasm/aicasm_symbol.c index e0af1a8..15e6a4d 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm_symbol.c +++ b/sys/dev/aic7xxx/aicasm/aicasm_symbol.c @@ -10,25 +10,33 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm_symbol.c#7 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#13 $ * * $FreeBSD$ */ @@ -41,6 +49,7 @@ #include <db.h> #endif #include <fcntl.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -310,12 +319,15 @@ symtable_dump(FILE *ofile) symlist_t constants; symlist_t download_constants; symlist_t aliases; + symlist_t exported_labels; + u_int i; SLIST_INIT(®isters); SLIST_INIT(&masks); SLIST_INIT(&constants); SLIST_INIT(&download_constants); SLIST_INIT(&aliases); + SLIST_INIT(&exported_labels); if (symtable != NULL) { DBT key; @@ -337,10 +349,8 @@ symtable_dump(FILE *ofile) symlist_add(&masks, cursym, SYMLIST_SORT); break; case CONST: - if (cursym->info.cinfo->define == FALSE) { - symlist_add(&constants, cursym, - SYMLIST_INSERT_HEAD); - } + symlist_add(&constants, cursym, + SYMLIST_INSERT_HEAD); break; case DOWNLOAD_CONST: symlist_add(&download_constants, cursym, @@ -350,6 +360,12 @@ symtable_dump(FILE *ofile) symlist_add(&aliases, cursym, SYMLIST_INSERT_HEAD); break; + case LABEL: + if (cursym->info.linfo->exported == 0) + break; + symlist_add(&exported_labels, cursym, + SYMLIST_INSERT_HEAD); + break; default: break; } @@ -395,7 +411,7 @@ symtable_dump(FILE *ofile) %s */\n", versions); while (SLIST_FIRST(®isters) != NULL) { symbol_node_t *curnode; - u_int8_t value; + u_int value; char *tab_str; char *tab_str2; @@ -455,7 +471,7 @@ symtable_dump(FILE *ofile) fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); - while (SLIST_FIRST(&download_constants) != NULL) { + for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { symbol_node_t *curnode; curnode = SLIST_FIRST(&download_constants); @@ -465,6 +481,20 @@ symtable_dump(FILE *ofile) curnode->symbol->info.cinfo->value); free(curnode); } + fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); + + fprintf(ofile, "\n\n/* Exported Labels */\n"); + + while (SLIST_FIRST(&exported_labels) != NULL) { + symbol_node_t *curnode; + + curnode = SLIST_FIRST(&exported_labels); + SLIST_REMOVE_HEAD(&exported_labels, links); + fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", + curnode->symbol->name, + curnode->symbol->info.linfo->address); + free(curnode); + } } } diff --git a/sys/dev/aic7xxx/aicasm/aicasm_symbol.h b/sys/dev/aic7xxx/aicasm/aicasm_symbol.h index a14cb69..b7b8382 100644 --- a/sys/dev/aic7xxx/aicasm/aicasm_symbol.h +++ b/sys/dev/aic7xxx/aicasm/aicasm_symbol.h @@ -10,25 +10,33 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the - * GNU Public License ("GPL"). + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/src/aic7xxx/aicasm/aicasm_symbol.h#4 $ + * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#10 $ * * $FreeBSD$ */ @@ -50,8 +58,9 @@ typedef enum { CONST, DOWNLOAD_CONST, LABEL, - CONDITIONAL -}symtype; + CONDITIONAL, + MACRO +} symtype; typedef enum { RO = 0x01, @@ -60,10 +69,11 @@ typedef enum { }amode_t; struct reg_info { - u_int8_t address; + u_int address; int size; amode_t mode; u_int8_t valid_bitmask; + u_int8_t modes; int typecheck_masks; }; @@ -75,8 +85,8 @@ struct mask_info { }; struct const_info { - u_int8_t value; - int define; + u_int value; + int define; }; struct alias_info { @@ -85,12 +95,26 @@ struct alias_info { struct label_info { int address; + int exported; }; struct cond_info { int func_num; }; +struct macro_arg { + STAILQ_ENTRY(macro_arg) links; + regex_t arg_regex; + char *replacement_text; +}; +STAILQ_HEAD(macro_arg_list, macro_arg) args; + +struct macro_info { + struct macro_arg_list args; + int narg; + const char* body; +}; + typedef struct expression_info { symlist_t referenced_syms; int value; @@ -100,12 +124,13 @@ typedef struct symbol { char *name; symtype type; union { - struct reg_info *rinfo; - struct mask_info *minfo; + struct reg_info *rinfo; + struct mask_info *minfo; struct const_info *cinfo; struct alias_info *ainfo; struct label_info *linfo; - struct cond_info *condinfo; + struct cond_info *condinfo; + struct macro_info *macroinfo; }info; } symbol_t; @@ -153,25 +178,25 @@ TAILQ_HEAD(cs_tailq, critical_section); SLIST_HEAD(scope_list, scope); TAILQ_HEAD(scope_tailq, scope); -void symbol_delete(symbol_t *symbol); +void symbol_delete __P((symbol_t *symbol)); -void symtable_open(void); +void symtable_open __P((void)); -void symtable_close(void); +void symtable_close __P((void)); symbol_t * - symtable_get(char *name); + symtable_get __P((char *name)); symbol_node_t * - symlist_search(symlist_t *symlist, char *symname); + symlist_search __P((symlist_t *symlist, char *symname)); void - symlist_add(symlist_t *symlist, symbol_t *symbol, int how); + symlist_add __P((symlist_t *symlist, symbol_t *symbol, int how)); #define SYMLIST_INSERT_HEAD 0x00 #define SYMLIST_SORT 0x01 -void symlist_free(symlist_t *symlist); +void symlist_free __P((symlist_t *symlist)); -void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, - symlist_t *symlist_src2); -void symtable_dump(FILE *ofile); +void symlist_merge __P((symlist_t *symlist_dest, symlist_t *symlist_src1, + symlist_t *symlist_src2)); +void symtable_dump __P((FILE *ofile)); |