Newer aic sequencer assembler. From FreeBSD, written by Justin Gibbs.

Ported to NetBSD by Pascal Renauld at Network Storage Solutions, Inc.
Some Makefile changes by me.

The 79xx code isn't yet used, driver for that to follow shortly.
This commit is contained in:
fvdl 2003-04-19 19:26:10 +00:00
parent 40565542e4
commit 7e92a81099
15 changed files with 10048 additions and 1916 deletions

View File

@ -0,0 +1,39 @@
# $NetBSD: Makefile,v 1.7 2003/04/19 19:26:10 fvdl Exp $
7XXX_SEQ= aic7xxx.seq
7XXX_SEQHDR= aic7xxx_seq.h
7XXX_REGHDR= aic7xxx_reg.h
79XX_SEQ= aic79xx.seq
79XX_SEQHDR= aic79xx_seq.h
79XX_REGHDR= aic79xx_reg.h
AICASMINCS=-I/usr/include -I${.CURDIR}/../../.. -I.
PROG= aicasm
SRCS= aicasm.c aicasm_symbol.c aicasm_scan.l aicasm_macro_scan.l \
aicasm_gram.y aicasm_macro_gram.y
YHEADER=1
DPADD+= ${LIBL} ${LIBY}
LDADD+= -ll -ly
NOSHARE=# defined
.include <bsd.prog.mk>
#
# XXXfvdl must come after the .include. Yes, it's ugly.
#
LFLAGS+= ${.TARGET:M*macro*:S/$(.TARGET)/-Pmm/}
YFLAGS+= ${.TARGET:M*macro*:S/$(.TARGET)/-p mm/}
regen: 7xxx_headers 79xx_headers
7xxx_headers: ${PROG} ${7XXX_SEQ}
./${PROG} ${AICASMINCS} -o ${7XXX_SEQHDR} -r ${7XXX_REGHDR} ${7XXX_SEQ}
79xx_headers: ${PROG} ${79XX_SEQ}
./${PROG} ${AICASMINCS} -o ${79XX_SEQHDR} -r ${79XX_REGHDR} ${79XX_SEQ}

View File

@ -1,24 +0,0 @@
# $NetBSD: Makefile.sequencer,v 1.3 2001/12/12 01:50:04 tv Exp $
SEQHEADER=aic7xxx_seq.h
REGHEADER=aic7xxx_reg.h
AICASMINCS=-I/usr/include -I../../..
PROG= aicasm
SRCS= aicasm.c aicasm_symbol.c aicasm_scan.l aicasm_gram.y
YHEADER=1
DPADD+= ${LIBL}
LDADD+= -ll
NOSHARE=# defined
.include <bsd.prog.mk>
regen: headers
headers: ${PROG} aic7xxx.seq
./${PROG} ${AICASMINCS} -o ${SEQHEADER} -r ${REGHEADER} aic7xxx.seq

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,10 @@
/* $NetBSD: aicasm.c,v 1.3 2001/01/22 14:30:44 jdolecek Exp $ */
/* $NetBSD: aicasm.c,v 1.4 2003/04/19 19:26:10 fvdl Exp $ */
/*
* Aic7xxx SCSI host adapter firmware asssembler
*
* Copyright (c) 1997, 1998 Justin T. Gibbs.
* Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
* Copyright (c) 2001, 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -11,37 +12,56 @@
* 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.
*
* 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
* 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 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm.c,v 1.23 1999/08/28 00:41:25 peter Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.c,v 1.35 2002/08/31 06:39:40 gibbs Exp $
*/
#include <sys/types.h>
#include <sys/mman.h>
#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 "sequencer.h"
#include "aicasm_insformat.h"
typedef struct patch {
STAILQ_ENTRY(patch) links;
@ -55,8 +75,8 @@ STAILQ_HEAD(patch_list, patch) patches;
static void usage(void);
static void back_patch(void);
static void output_code(FILE *ofile);
static void output_listing(FILE *listfile, char *ifilename);
static void output_code(void);
static void output_listing(char *ifilename);
static void dump_scope(scope_t *scope);
static void emit_patch(scope_t *scope, int patch);
static int check_patch(patch_t **start_patch, int start_instr,
@ -65,28 +85,36 @@ static int check_patch(patch_t **start_patch, int start_instr,
struct path_list search_path;
int includes_search_curdir;
char *appname;
char *stock_include_file;
FILE *ofile;
char *ofilename;
char *regfilename;
FILE *regfile;
char *listfilename;
FILE *listfile;
char *regdiagfilename;
FILE *regdiagfile;
int src_mode;
int dst_mode;
static STAILQ_HEAD(,instruction) seq_program;
struct cs_tailq cs_tailq;
struct scope_list scope_stack;
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 __P((void));
extern int yyparse(void);
int main(int argc, char *argv[]);
int
main(argc, argv)
int argc;
char *argv[];
main(int argc, char *argv[])
{
extern char *optarg;
extern int optind;
@ -98,6 +126,7 @@ main(argc, argv)
STAILQ_INIT(&patches);
SLIST_INIT(&search_path);
STAILQ_INIT(&seq_program);
TAILQ_INIT(&cs_tailq);
SLIST_INIT(&scope_stack);
/* Set Sentinal scope node */
@ -110,16 +139,20 @@ main(argc, 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) {
while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {
switch(ch) {
case 'd':
#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);
@ -130,6 +163,9 @@ main(argc, argv)
"information", EX_SOFTWARE);
#endif
break;
case 'i':
stock_include_file = optarg;
break;
case 'l':
/* Create a program listing */
if ((listfile = fopen(optarg, "w")) == NULL) {
@ -154,6 +190,14 @@ main(argc, argv)
}
ofilename = optarg;
break;
case 'p':
/* Create Register Diagnostic "printing" Functions */
if ((regdiagfile = fopen(optarg, "w")) == NULL) {
perror(optarg);
stop(NULL, EX_CANTCREAT);
}
regdiagfilename = optarg;
break;
case 'r':
if ((regfile = fopen(optarg, "w")) == NULL) {
perror(optarg);
@ -174,8 +218,8 @@ main(argc, argv)
includes_search_curdir = 0;
for (include_dir = SLIST_FIRST(&search_path);
include_dir != NULL;
include_dir =
SLIST_NEXT(include_dir, links))
include_dir = SLIST_NEXT(include_dir,
links))
/*
* All entries before a '-I-' only
* apply to includes specified with
@ -215,6 +259,14 @@ main(argc, argv)
/* NOTREACHED */
}
if (regdiagfile != NULL
&& (regfile == NULL || stock_include_file == NULL)) {
fprintf(stderr,
"%s: The -p option requires the -r and -i options.\n",
appname);
usage();
/* NOTREACHED */
}
symtable_open();
inputfilename = *argv;
include_file(*argv, SOURCE_FILE);
@ -222,8 +274,7 @@ main(argc, 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 */
}
@ -241,12 +292,11 @@ main(argc, argv)
back_patch();
if (ofile != NULL)
output_code(ofile);
if (regfile != NULL) {
symtable_dump(regfile);
}
output_code();
if (regfile != NULL)
symtable_dump(regfile, regdiagfile);
if (listfile != NULL)
output_listing(listfile, inputfilename);
output_listing(inputfilename);
}
stop(NULL, 0);
@ -259,10 +309,10 @@ usage()
{
(void)fprintf(stderr,
"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]
[-r register_output_file] [-l program_list_file]
input_file\n",
appname);
"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
" [-r register_output_file [-p register_diag_file -i includefile]]\n"
" [-l program_list_file]\n"
" input_file\n", appname);
exit(EX_USAGE);
}
@ -271,9 +321,9 @@ back_patch()
{
struct instruction *cur_instr;
for(cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links)) {
for (cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links)) {
if (cur_instr->patch_label != NULL) {
struct ins_format3 *f3_instr;
u_int address;
@ -296,78 +346,113 @@ back_patch()
}
static void
output_code(ofile)
FILE *ofile;
output_code()
{
struct instruction *cur_instr;
patch_t *cur_patch;
critical_section_t *cs;
symbol_node_t *cur_node;
int instrcount;
instrcount = 0;
fprintf(ofile,
"/*
* DO NOT EDIT - This file is automatically generated.
*/\n");
"/*\n"
" * DO NOT EDIT - This file is automatically generated\n"
" * from the following source files:\n"
" *\n"
"%s */\n", versions);
fprintf(ofile, "static const u_int8_t seqprog[] = {\n");
for(cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links)) {
fprintf(ofile, "static uint8_t seqprog[] = {\n");
for (cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links)) {
fprintf(ofile, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
#if _BYTE_ORDER == _BIG_ENDIAN
cur_instr->format.bytes[3],
cur_instr->format.bytes[2],
cur_instr->format.bytes[1],
cur_instr->format.bytes[0]);
#else
fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
#if BYTE_ORDER == LITTLE_ENDIAN
cur_instr->format.bytes[0],
cur_instr->format.bytes[1],
cur_instr->format.bytes[2],
cur_instr->format.bytes[3]);
#else
cur_instr->format.bytes[3],
cur_instr->format.bytes[2],
cur_instr->format.bytes[1],
cur_instr->format.bytes[0]);
#endif
instrcount++;
}
fprintf(ofile, "};\n\n");
fprintf(ofile, "\n};\n\n");
if (patch_arg_list == NULL)
stop("Patch argument list not defined",
EX_DATAERR);
/*
* Output patch information. Patch functions first.
*/
for(cur_node = SLIST_FIRST(&patch_functions);
cur_node != NULL;
cur_node = SLIST_NEXT(cur_node,links)) {
fprintf(ofile,
"static int ahc_patch%d_func(struct ahc_softc *ahc);
fprintf(ofile,
"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);
static int
ahc_patch%d_func(struct ahc_softc *ahc)
{
return (%s);
}\n\n",
for (cur_node = SLIST_FIRST(&patch_functions);
cur_node != NULL;
cur_node = SLIST_NEXT(cur_node,links)) {
fprintf(ofile,
"static %spatch_func_t %spatch%d_func;\n"
"\n"
"static int\n"
"%spatch%d_func(%s)\n"
"{\n"
" return (%s);\n"
"}\n\n",
prefix,
prefix,
cur_node->symbol->info.condinfo->func_num,
prefix,
cur_node->symbol->info.condinfo->func_num,
patch_arg_list,
cur_node->symbol->name);
}
fprintf(ofile,
"typedef int patch_func_t __P((struct ahc_softc *));
const struct patch {
patch_func_t *patch_func;
u_int32_t begin :10,
skip_instr :10,
skip_patch :12;
} patches[] = {\n");
"static struct patch {\n"
" %spatch_func_t *patch_func;\n"
" uint32_t begin :10,\n"
" skip_instr :10,\n"
" skip_patch :12;\n"
"} patches[] = {\n", prefix);
for(cur_patch = STAILQ_FIRST(&patches);
cur_patch != NULL;
cur_patch = STAILQ_NEXT(cur_patch,links)) {
fprintf(ofile, "\t{ ahc_patch%d_func, %d, %d, %d },\n",
for (cur_patch = STAILQ_FIRST(&patches);
cur_patch != NULL;
cur_patch = STAILQ_NEXT(cur_patch,links)) {
fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",
cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
prefix,
cur_patch->patch_func, cur_patch->begin,
cur_patch->skip_instr, cur_patch->skip_patch);
}
fprintf(ofile, "\n};\n");
fprintf(ofile, "\n};\n\n");
fprintf(ofile,
"static struct cs {\n"
" uint16_t begin;\n"
" uint16_t end;\n"
"} critical_sections[] = {\n");
for (cs = TAILQ_FIRST(&cs_tailq);
cs != NULL;
cs = TAILQ_NEXT(cs, links)) {
fprintf(ofile, "%s\t{ %d, %d }",
cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
cs->begin_addr, cs->end_addr);
}
fprintf(ofile, "\n};\n\n");
fprintf(ofile,
"static const int num_critical_sections = sizeof(critical_sections)\n"
" / sizeof(*critical_sections);\n");
fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
}
@ -432,7 +517,7 @@ emit_patch(scope_t *scope, int patch)
}
void
output_listing(FILE *listfile, char *ifilename)
output_listing(char *ifilename)
{
char buf[1024];
FILE *ifile;
@ -463,6 +548,7 @@ output_listing(FILE *listfile, char *ifilename)
cur_func = SLIST_NEXT(cur_func, links))
func_count++;
func_values = NULL;
if (func_count != 0) {
func_values = (int *)malloc(func_count * sizeof(int));
@ -509,9 +595,9 @@ output_listing(FILE *listfile, char *ifilename)
/* Now output the listing */
cur_patch = STAILQ_FIRST(&patches);
for(cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
for (cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
if (check_patch(&cur_patch, instrcount,
&skip_addr, func_values) == 0) {
@ -527,10 +613,17 @@ output_listing(FILE *listfile, char *ifilename)
line++;
}
fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
#if BYTE_ORDER == LITTLE_ENDIAN
cur_instr->format.bytes[0],
cur_instr->format.bytes[1],
cur_instr->format.bytes[2],
cur_instr->format.bytes[3]);
#else
cur_instr->format.bytes[3],
cur_instr->format.bytes[2],
cur_instr->format.bytes[1],
cur_instr->format.bytes[0]);
#endif
fgets(buf, sizeof(buf), ifile);
fprintf(listfile, "\t%s", buf);
line++;
@ -583,9 +676,7 @@ check_patch(patch_t **start_patch, int start_instr,
* terminating the program.
*/
void
stop(string, err_code)
const char *string;
int err_code;
stop(const char *string, int err_code)
{
if (string != NULL) {
fprintf(stderr, "%s: ", appname);
@ -643,6 +734,20 @@ seq_alloc()
return new_instr;
}
critical_section_t *
cs_alloc()
{
critical_section_t *new_cs;
new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));
if (new_cs == NULL)
stop("Unable to malloc critical_section object", EX_SOFTWARE);
memset(new_cs, 0, sizeof(*new_cs));
TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);
return new_cs;
}
scope_t *
scope_alloc()
{

View File

@ -1,9 +1,10 @@
/* $NetBSD: aicasm.h,v 1.1 2000/03/15 02:09:13 fvdl Exp $ */
/* $NetBSD: aicasm.h,v 1.2 2003/04/19 19:26:10 fvdl Exp $ */
/*
* Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters
*
* Copyright (c) 1997 Justin T. Gibbs.
* Copyright (c) 2001, 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -12,38 +13,39 @@
* 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.
*
* 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
* 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 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm.h,v 1.6 1999/12/06 18:23:30 gibbs Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm.h,v 1.16 2002/08/31 06:39:40 gibbs Exp $
*/
#ifdef __linux__
#include "../queue.h"
#else
#include <sys/queue.h>
#ifdef __NetBSD__
#define STAILQ_EMPTY SIMPLEQ_EMPTY
#define STAILQ_FIRST SIMPLEQ_FIRST
#define STAILQ_NEXT SIMPLEQ_NEXT
#define STAILQ_ENTRY SIMPLEQ_ENTRY
#define STAILQ_INIT SIMPLEQ_INIT
#define STAILQ_HEAD SIMPLEQ_HEAD
#define STAILQ_INSERT_AFTER SIMPLEQ_INSERT_AFTER
#define STAILQ_INSERT_HEAD SIMPLEQ_INSERT_HEAD
#define STAILQ_INSERT_TAIL SIMPLEQ_INSERT_TAIL
#endif
#ifndef TRUE
@ -69,15 +71,25 @@ typedef enum {
SLIST_HEAD(path_list, path_entry);
extern struct path_list search_path;
extern struct cs_tailq cs_tailq;
extern struct scope_list scope_stack;
extern struct symlist patch_functions;
extern int includes_search_curdir; /* False if we've seen -I- */
extern char *appname;
extern char *stock_include_file;
extern int yylineno;
extern char *yyfilename;
extern char *prefix;
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);
void process_scope(struct scope *);

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
/* $NetBSD: sequencer.h,v 1.1 2000/03/15 02:09:15 fvdl Exp $ */
/* $NetBSD: aicasm_insformat.h,v 1.1 2003/04/19 19:26:11 fvdl Exp $ */
/*
* Instruction formats for the sequencer program downloaded to
* Aic7xxx SCSI host adapters
*
* Copyright (c) 1997, 1998 Justin T. Gibbs.
* Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -13,39 +13,45 @@
* 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
* 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/sequencer.h,v 1.6 1999/12/06 18:23:31 gibbs Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_insformat.h,v 1.8 2002/11/27 07:06:43 scottl Exp $
*/
#include <machine/endian.h>
struct ins_format1 {
#if _BYTE_ORDER == _LITTLE_ENDIAN
u_int32_t immediate : 8,
#if BYTE_ORDER == LITTLE_ENDIAN
uint32_t immediate : 8,
source : 9,
destination : 9,
ret : 1,
opcode : 4,
parity : 1;
#else
u_int32_t parity : 1,
uint32_t parity : 1,
opcode : 4,
ret : 1,
destination : 9,
@ -55,15 +61,15 @@ struct ins_format1 {
};
struct ins_format2 {
#if _BYTE_ORDER == _LITTLE_ENDIAN
u_int32_t shift_control : 8,
#if BYTE_ORDER == LITTLE_ENDIAN
uint32_t shift_control : 8,
source : 9,
destination : 9,
ret : 1,
opcode : 4,
parity : 1;
#else
u_int32_t parity : 1,
uint32_t parity : 1,
opcode : 4,
ret : 1,
destination : 9,
@ -73,14 +79,14 @@ struct ins_format2 {
};
struct ins_format3 {
#if _BYTE_ORDER == _LITTLE_ENDIAN
u_int32_t immediate : 8,
#if BYTE_ORDER == LITTLE_ENDIAN
uint32_t immediate : 8,
source : 9,
address : 10,
opcode : 4,
parity : 1;
#else
u_int32_t parity : 1,
uint32_t parity : 1,
opcode : 4,
address : 10,
source : 9,
@ -92,8 +98,8 @@ union ins_formats {
struct ins_format1 format1;
struct ins_format2 format2;
struct ins_format3 format3;
u_int8_t bytes[4];
u_int32_t integer;
uint8_t bytes[4];
uint32_t integer;
};
struct instruction {
union ins_formats format;

View File

@ -0,0 +1,164 @@
%{
/* $NetBSD: aicasm_macro_gram.y,v 1.1 2003/04/19 19:26:11 fvdl Exp $ */
/*
* 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y,v 1.2 2002/08/31 06:39:40 gibbs Exp $
*/
#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, &macro_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);
}

View File

@ -0,0 +1,155 @@
%{
/* $NetBSD: aicasm_macro_scan.l,v 1.1 2003/04/19 19:26:11 fvdl Exp $ */
/*
* 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l,v 1.4 2002/09/27 03:23:02 gibbs Exp $
*/
#include <sys/types.h>
#include <inttypes.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 = yytext;
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(yytext);
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'", yytext[0]);
stop(buf, EX_DATAERR);
}
%%
int
mmwrap()
{
stop("EOF encountered in macro call", EX_DATAERR);
}

View File

@ -1,10 +1,10 @@
%{
/* $NetBSD: aicasm_scan.l,v 1.2 2002/06/02 01:20:36 lukem Exp $ */
/* $NetBSD: aicasm_scan.l,v 1.3 2003/04/19 19:26:11 fvdl Exp $ */
/*
* 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, 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -13,53 +13,76 @@
* 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.
*
* 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
* 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 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm_scan.l,v 1.8 1999/12/06 18:23:30 gibbs Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.21 2002/09/27 03:23:02 gibbs Exp $
*/
#include <sys/types.h>
#include <inttypes.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"
#ifdef __NetBSD__
#include "aicasm_gram.h"
#else
#include "y.tab.h"
#endif
#define MAX_STR_CONST 256
char string_buf[MAX_STR_CONST];
char *string_buf_ptr;
int parren_count;
/* 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];
%}
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; }
@ -90,21 +113,54 @@ if[ \t]*\( {
}
}
<CEXPR>\n { ++yylineno; }
<CEXPR>[^()\n]+ {
char *yptr = yytext;
<CEXPR>[^()\n]+ {
char *yptr;
while (*yptr != '\0')
*string_buf_ptr++ = *yptr++;
yptr = yytext;
while (*yptr != '\0') {
/* Remove duplicate spaces */
if (*yptr == '\t')
*yptr = ' ';
if (*yptr == ' '
&& string_buf_ptr != string_buf
&& string_buf_ptr[-1] == ' ')
yptr++;
else
*string_buf_ptr++ = *yptr++;
}
}
{SPACE} ;
VERSION { return T_VERSION; }
PREFIX { return T_PREFIX; }
PATCH_ARG_LIST { return T_PATCH_ARG_LIST; }
\" {
string_buf_ptr = string_buf;
BEGIN STRING;
}
<STRING>[^"]+ {
char *yptr;
yptr = yytext;
while (*yptr)
*string_buf_ptr++ = *yptr++;
}
<STRING>\" {
/* All done */
BEGIN INITIAL;
*string_buf_ptr = '\0';
yylval.str = string_buf;
return T_STRING;
}
{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;
@ -114,13 +170,19 @@ RW|RO|WO {
yylval.value = WO;
return T_MODE;
}
bit { return T_BIT; }
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; }
field { return T_FIELD; }
enum { return T_ENUM; }
mask { return T_MASK; }
alias { return T_ALIAS; }
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; }
@ -151,6 +213,7 @@ dec { return T_DEC; }
stc { return T_STC; }
clc { return T_CLC; }
cmp { return T_CMP; }
not { return T_NOT; }
xor { return T_XOR; }
test { return T_TEST;}
and { return T_AND; }
@ -160,7 +223,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]* {
@ -177,25 +242,183 @@ else { return T_ELSE; }
yylval.value = strtol(yytext, NULL, 10);
return T_NUMBER;
}
/* Include Files */
#include { return T_INCLUDE; BEGIN INCLUDE;}
<INCLUDE>[<>\"] { return yytext[0]; }
<INCLUDE>{PATH} { yylval.str = strdup(yytext); return T_PATH; }
<INCLUDE>; { BEGIN INITIAL; return yytext[0]; }
#include{SPACE} {
BEGIN INCLUDE;
quote_count = 0;
return T_INCLUDE;
}
<INCLUDE>[<] { return yytext[0]; }
<INCLUDE>[>] { BEGIN INITIAL; return yytext[0]; }
<INCLUDE>[\"] {
if (quote_count != 0)
BEGIN INITIAL;
quote_count++;
return yytext[0];
}
<INCLUDE>{PATH} {
char *yptr;
yptr = yytext;
string_buf_ptr = string_buf;
while (*yptr)
*string_buf_ptr++ = *yptr++;
yylval.str = string_buf;
*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;
/* For parsing C include files with #define foo */
#define { yylval.value = TRUE; return T_CONST; }
/* Throw away macros */
#define[^\n]*[()]+[^\n]* ;
{PATH} { yylval.str = strdup(yytext); return T_PATH; }
/* 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;
{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; }
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;
}
}
. {
char buf[255];
snprintf(buf, sizeof(buf), "Invalid character "
"'%c'", yytext[0]);
stop(buf, EX_DATAERR);
@ -212,9 +435,7 @@ typedef struct include {
SLIST_HEAD(, include) include_stack;
void
include_file(file_name, type)
char *file_name;
include_type type;
include_file(char *file_name, include_type type)
{
FILE *newfile;
include_t *include;
@ -226,7 +447,9 @@ include_file(file_name, type)
if (newfile == NULL && type != SOURCE_FILE) {
path_entry_t include_dir;
SLIST_FOREACH(include_dir, &search_path, links) {
for (include_dir = search_path.slh_first;
include_dir != NULL;
include_dir = include_dir->links.sle_next) {
char fullname[PATH_MAX];
if ((include_dir->quoted_includes_only == TRUE)
@ -264,6 +487,92 @@ include_file(file_name, 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, &macro_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()
{
@ -274,7 +583,7 @@ yywrap()
if (yyfilename != NULL)
free(yyfilename);
yyfilename = NULL;
include = SLIST_FIRST(&include_stack);
include = include_stack.slh_first;
if (include != NULL) {
yy_switch_to_buffer(include->buffer);
yylineno = include->lineno;

View File

@ -1,9 +1,10 @@
/* $NetBSD: aicasm_symbol.c,v 1.2 2002/06/02 01:20:36 lukem Exp $ */
/* $NetBSD: aicasm_symbol.c,v 1.3 2003/04/19 19:26:11 fvdl Exp $ */
/*
* Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
*
* Copyright (c) 1997 Justin T. Gibbs.
* Copyright (c) 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -12,42 +13,57 @@
* 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.
*
* 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
* 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 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm_symbol.c,v 1.8 1999/12/06 18:23:30 gibbs Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.23 2003/01/20 18:01:37 gibbs Exp $
*/
#include <sys/types.h>
#ifdef __linux__
#include "aicdb.h"
#else
#include <db.h>
#endif
#include <fcntl.h>
#include <inttypes.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include "aicasm.h"
#include "aicasm_symbol.h"
#include "aicasm.h"
static DB *symtable;
symbol_t *
symbol_create(name)
char *name;
symbol_create(char *name)
{
symbol_t *new_symbol;
@ -58,13 +74,14 @@ symbol_create(name)
}
memset(new_symbol, 0, sizeof(*new_symbol));
new_symbol->name = strdup(name);
if (new_symbol->name == NULL)
stop("Unable to strdup symbol name", EX_SOFTWARE);
new_symbol->type = UNINITIALIZED;
return (new_symbol);
}
void
symbol_delete(symbol)
symbol_t *symbol;
symbol_delete(symbol_t *symbol)
{
if (symtable != NULL) {
DBT key;
@ -85,10 +102,12 @@ symbol_delete(symbol)
free(symbol->info.ainfo);
break;
case MASK:
case BIT:
if (symbol->info.minfo != NULL) {
symlist_free(&symbol->info.minfo->symrefs);
free(symbol->info.minfo);
case FIELD:
case ENUM:
case ENUM_ENTRY:
if (symbol->info.finfo != NULL) {
symlist_free(&symbol->info.finfo->symrefs);
free(symbol->info.finfo);
}
break;
case DOWNLOAD_CONST:
@ -144,8 +163,7 @@ symtable_close()
* if a lookup fails.
*/
symbol_t *
symtable_get(name)
char *name;
symtable_get(char *name)
{
symbol_t *stored_ptr;
DBT key;
@ -184,9 +202,7 @@ symtable_get(name)
}
symbol_node_t *
symlist_search(symlist, symname)
symlist_t *symlist;
char *symname;
symlist_search(symlist_t *symlist, char *symname)
{
symbol_node_t *curnode;
@ -200,10 +216,7 @@ symlist_search(symlist, symname)
}
void
symlist_add(symlist, symbol, how)
symlist_t *symlist;
symbol_t *symbol;
int how;
symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
{
symbol_node_t *newnode;
@ -215,17 +228,19 @@ symlist_add(symlist, symbol, how)
newnode->symbol = symbol;
if (how == SYMLIST_SORT) {
symbol_node_t *curnode;
int mask;
int field;
mask = FALSE;
field = FALSE;
switch(symbol->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
break;
case BIT:
case FIELD:
case MASK:
mask = TRUE;
case ENUM:
case ENUM_ENTRY:
field = TRUE;
break;
default:
stop("symlist_add: Invalid symbol type for sorting",
@ -235,9 +250,12 @@ symlist_add(symlist, symbol, how)
curnode = SLIST_FIRST(symlist);
if (curnode == NULL
|| (mask && (curnode->symbol->info.minfo->mask >
newnode->symbol->info.minfo->mask))
|| (!mask && (curnode->symbol->info.rinfo->address >
|| (field
&& (curnode->symbol->type > newnode->symbol->type
|| (curnode->symbol->type == newnode->symbol->type
&& (curnode->symbol->info.finfo->value >
newnode->symbol->info.finfo->value))))
|| (!field && (curnode->symbol->info.rinfo->address >
newnode->symbol->info.rinfo->address))) {
SLIST_INSERT_HEAD(symlist, newnode, links);
return;
@ -252,10 +270,14 @@ symlist_add(symlist, symbol, how)
symbol_t *cursymbol;
cursymbol = SLIST_NEXT(curnode, links)->symbol;
if ((mask && (cursymbol->info.minfo->mask >
symbol->info.minfo->mask))
|| (!mask &&(cursymbol->info.rinfo->address >
symbol->info.rinfo->address))){
if ((field
&& (cursymbol->type > symbol->type
|| (cursymbol->type == symbol->type
&& (cursymbol->info.finfo->value >
symbol->info.finfo->value))))
|| (!field
&& (cursymbol->info.rinfo->address >
symbol->info.rinfo->address))) {
SLIST_INSERT_AFTER(curnode, newnode,
links);
break;
@ -269,8 +291,7 @@ symlist_add(symlist, symbol, how)
}
void
symlist_free(symlist)
symlist_t *symlist;
symlist_free(symlist_t *symlist)
{
symbol_node_t *node1, *node2;
@ -284,10 +305,8 @@ symlist_free(symlist)
}
void
symlist_merge(symlist_dest, symlist_src1, symlist_src2)
symlist_t *symlist_dest;
symlist_t *symlist_src1;
symlist_t *symlist_src2;
symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
symlist_t *symlist_src2)
{
symbol_node_t *node;
@ -303,172 +322,356 @@ symlist_merge(symlist_dest, symlist_src1, symlist_src2)
}
void
symtable_dump(ofile)
FILE *ofile;
aic_print_file_prologue(FILE *ofile)
{
if (ofile == NULL)
return;
fprintf(ofile,
"/*\n"
" * DO NOT EDIT - This file is automatically generated\n"
" * from the following source files:\n"
" *\n"
"%s */\n",
versions);
}
void
aic_print_include(FILE *dfile, char *include_file)
{
if (dfile == NULL)
return;
fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
}
void
aic_print_reg_dump_types(FILE *ofile)
{
if (ofile == NULL)
return;
fprintf(ofile,
"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
"typedef struct %sreg_parse_entry {\n"
" char *name;\n"
" uint8_t value;\n"
" uint8_t mask;\n"
"} %sreg_parse_entry_t;\n"
"\n",
prefix, prefix, prefix);
}
static void
aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
{
if (dfile == NULL)
return;
fprintf(dfile,
"static %sreg_parse_entry_t %s_parse_table[] = {\n",
prefix,
regnode->symbol->name);
}
static void
aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
symbol_node_t *regnode, u_int num_entries)
{
char *lower_name;
char *letter;
lower_name = strdup(regnode->symbol->name);
if (lower_name == NULL)
stop("Unable to strdup symbol name", EX_SOFTWARE);
for (letter = lower_name; *letter != '\0'; letter++)
*letter = tolower(*letter);
if (dfile != NULL) {
if (num_entries != 0)
fprintf(dfile,
"\n"
"};\n"
"\n");
fprintf(dfile,
"int\n"
"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
"{\n"
" return (%sprint_register(%s%s, %d, \"%s\",\n"
" 0x%02x, regvalue, cur_col, wrap));\n"
"}\n"
"\n",
prefix,
lower_name,
prefix,
num_entries != 0 ? regnode->symbol->name : "NULL",
num_entries != 0 ? "_parse_table" : "",
num_entries,
regnode->symbol->name,
regnode->symbol->info.rinfo->address);
}
fprintf(ofile,
"#if AIC_DEBUG_REGISTERS\n"
"%sreg_print_t %s%s_print;\n"
"#else\n"
"#define %s%s_print(regvalue, cur_col, wrap) \\\n"
" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
"#endif\n"
"\n",
prefix,
prefix,
lower_name,
prefix,
lower_name,
prefix,
regnode->symbol->name,
regnode->symbol->info.rinfo->address);
}
static void
aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
{
int num_tabs;
if (dfile == NULL)
return;
fprintf(dfile,
" { \"%s\",",
curnode->symbol->name);
num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
while (num_tabs-- > 0)
fputc('\t', dfile);
fprintf(dfile, "0x%02x, 0x%02x }",
curnode->symbol->info.finfo->value,
curnode->symbol->info.finfo->mask);
}
void
symtable_dump(FILE *ofile, FILE *dfile)
{
/*
* Sort the registers by address with a simple insertion sort.
* Put bitmasks next to the first register that defines them.
* Put constants at the end.
*/
symlist_t registers;
symlist_t masks;
symlist_t constants;
symlist_t download_constants;
symlist_t aliases;
symlist_t registers;
symlist_t masks;
symlist_t constants;
symlist_t download_constants;
symlist_t aliases;
symlist_t exported_labels;
symbol_node_t *curnode;
symbol_node_t *regnode;
DBT key;
DBT data;
int flag;
u_int i;
if (symtable == NULL)
return;
SLIST_INIT(&registers);
SLIST_INIT(&masks);
SLIST_INIT(&constants);
SLIST_INIT(&download_constants);
SLIST_INIT(&aliases);
SLIST_INIT(&exported_labels);
flag = R_FIRST;
while (symtable->seq(symtable, &key, &data, flag) == 0) {
symbol_t *cursym;
if (symtable != NULL) {
DBT key;
DBT data;
int flag = R_FIRST;
memcpy(&cursym, data.data, sizeof(cursym));
switch(cursym->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
symlist_add(&registers, cursym, SYMLIST_SORT);
break;
case MASK:
case FIELD:
case ENUM:
case ENUM_ENTRY:
symlist_add(&masks, cursym, SYMLIST_SORT);
break;
case CONST:
symlist_add(&constants, cursym,
SYMLIST_INSERT_HEAD);
break;
case DOWNLOAD_CONST:
symlist_add(&download_constants, cursym,
SYMLIST_INSERT_HEAD);
break;
case ALIAS:
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;
}
flag = R_NEXT;
}
while (symtable->seq(symtable, &key, &data, flag) == 0) {
symbol_t *cursym;
/* Register dianostic functions/declarations first. */
aic_print_file_prologue(ofile);
aic_print_reg_dump_types(ofile);
aic_print_file_prologue(dfile);
aic_print_include(dfile, stock_include_file);
SLIST_FOREACH(curnode, &registers, links) {
memcpy(&cursym, data.data, sizeof(cursym));
switch(cursym->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
symlist_add(&registers, cursym, SYMLIST_SORT);
break;
case MASK:
case BIT:
symlist_add(&masks, cursym, SYMLIST_SORT);
break;
case CONST:
if (cursym->info.cinfo->define == FALSE) {
symlist_add(&constants, cursym,
SYMLIST_INSERT_HEAD);
}
break;
case DOWNLOAD_CONST:
symlist_add(&download_constants, cursym,
SYMLIST_INSERT_HEAD);
break;
case ALIAS:
symlist_add(&aliases, cursym,
SYMLIST_INSERT_HEAD);
break;
default:
break;
switch(curnode->symbol->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
{
symlist_t *fields;
symbol_node_t *fieldnode;
int num_entries;
num_entries = 0;
fields = &curnode->symbol->info.rinfo->fields;
SLIST_FOREACH(fieldnode, fields, links) {
if (num_entries == 0)
aic_print_reg_dump_start(dfile,
curnode);
else if (dfile != NULL)
fputs(",\n", dfile);
num_entries++;
aic_print_reg_dump_entry(dfile, fieldnode);
}
flag = R_NEXT;
aic_print_reg_dump_end(ofile, dfile,
curnode, num_entries);
}
/* Put in the masks and bits */
while (! SLIST_EMPTY(&masks)) {
symbol_node_t *curnode;
symbol_node_t *regnode;
char *regname;
curnode = SLIST_FIRST(&masks);
SLIST_REMOVE_HEAD(&masks, links);
regnode =
SLIST_FIRST(&curnode->symbol->info.minfo->symrefs);
regname = regnode->symbol->name;
regnode = symlist_search(&registers, regname);
SLIST_INSERT_AFTER(regnode, curnode, links);
default:
break;
}
}
/* Add the aliases */
while (! SLIST_EMPTY(&aliases)) {
symbol_node_t *curnode;
symbol_node_t *regnode;
char *regname;
/* Fold in the masks and bits */
while (SLIST_FIRST(&masks) != NULL) {
char *regname;
curnode = SLIST_FIRST(&aliases);
SLIST_REMOVE_HEAD(&aliases, links);
curnode = SLIST_FIRST(&masks);
SLIST_REMOVE_HEAD(&masks, links);
regname = curnode->symbol->info.ainfo->parent->name;
regnode = symlist_search(&registers, regname);
SLIST_INSERT_AFTER(regnode, curnode, links);
regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
regname = regnode->symbol->name;
regnode = symlist_search(&registers, regname);
SLIST_INSERT_AFTER(regnode, curnode, links);
}
/* Add the aliases */
while (SLIST_FIRST(&aliases) != NULL) {
char *regname;
curnode = SLIST_FIRST(&aliases);
SLIST_REMOVE_HEAD(&aliases, links);
regname = curnode->symbol->info.ainfo->parent->name;
regnode = symlist_search(&registers, regname);
SLIST_INSERT_AFTER(regnode, curnode, links);
}
/* Output generated #defines. */
while (SLIST_FIRST(&registers) != NULL) {
symbol_node_t *curnode;
u_int value;
char *tab_str;
char *tab_str2;
curnode = SLIST_FIRST(&registers);
SLIST_REMOVE_HEAD(&registers, links);
switch(curnode->symbol->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
fprintf(ofile, "\n");
value = curnode->symbol->info.rinfo->address;
tab_str = "\t";
tab_str2 = "\t\t";
break;
case ALIAS:
{
symbol_t *parent;
parent = curnode->symbol->info.ainfo->parent;
value = parent->info.rinfo->address;
tab_str = "\t";
tab_str2 = "\t\t";
break;
}
/* Output what we have */
fprintf(ofile,
"/*
* DO NOT EDIT - This file is automatically generated.
*/\n");
while (! SLIST_EMPTY(&registers)) {
symbol_node_t *curnode;
u_int8_t value;
char *tab_str;
char *tab_str2;
curnode = SLIST_FIRST(&registers);
SLIST_REMOVE_HEAD(&registers, links);
switch(curnode->symbol->type) {
case REGISTER:
case SCBLOC:
case SRAMLOC:
fprintf(ofile, "\n");
value = curnode->symbol->info.rinfo->address;
tab_str = "\t";
tab_str2 = "\t\t";
break;
case ALIAS:
{
symbol_t *parent;
parent = curnode->symbol->info.ainfo->parent;
value = parent->info.rinfo->address;
tab_str = "\t";
tab_str2 = "\t\t";
break;
}
case MASK:
case BIT:
value = curnode->symbol->info.minfo->mask;
tab_str = "\t\t";
tab_str2 = "\t";
break;
default:
value = 0; /* Quiet compiler */
tab_str = NULL;
tab_str2 = NULL;
stop("symtable_dump: Invalid symbol type "
"encountered", EX_SOFTWARE);
break;
}
fprintf(ofile, "#define%s%-16s%s0x%02x\n",
tab_str, curnode->symbol->name, tab_str2,
value);
free(curnode);
case MASK:
case FIELD:
case ENUM:
case ENUM_ENTRY:
value = curnode->symbol->info.finfo->value;
tab_str = "\t\t";
tab_str2 = "\t";
break;
default:
value = 0; /* Quiet compiler */
tab_str = NULL;
tab_str2 = NULL;
stop("symtable_dump: Invalid symbol type "
"encountered", EX_SOFTWARE);
break;
}
fprintf(ofile, "\n\n");
fprintf(ofile, "#define%s%-16s%s0x%02x\n",
tab_str, curnode->symbol->name, tab_str2,
value);
free(curnode);
}
fprintf(ofile, "\n\n");
while (! SLIST_EMPTY(&constants)) {
symbol_node_t *curnode;
while (SLIST_FIRST(&constants) != NULL) {
symbol_node_t *curnode;
curnode = SLIST_FIRST(&constants);
SLIST_REMOVE_HEAD(&constants, links);
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
curnode->symbol->name,
curnode->symbol->info.cinfo->value);
free(curnode);
}
curnode = SLIST_FIRST(&constants);
SLIST_REMOVE_HEAD(&constants, links);
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
curnode->symbol->name,
curnode->symbol->info.cinfo->value);
free(curnode);
}
fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
while (! SLIST_EMPTY(&download_constants)) {
symbol_node_t *curnode;
for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
symbol_node_t *curnode;
curnode = SLIST_FIRST(&download_constants);
SLIST_REMOVE_HEAD(&download_constants, links);
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
curnode->symbol->name,
curnode->symbol->info.cinfo->value);
free(curnode);
}
curnode = SLIST_FIRST(&download_constants);
SLIST_REMOVE_HEAD(&download_constants, links);
fprintf(ofile, "#define\t%-8s\t0x%02x\n",
curnode->symbol->name,
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);
}
}

View File

@ -1,9 +1,10 @@
/* $NetBSD: aicasm_symbol.h,v 1.1 2000/03/15 02:09:15 fvdl Exp $ */
/* $NetBSD: aicasm_symbol.h,v 1.2 2003/04/19 19:26:11 fvdl Exp $ */
/*
* Aic7xxx SCSI host adapter firmware asssembler symbol table definitions
*
* Copyright (c) 1997 Justin T. Gibbs.
* Copyright (c) 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -12,25 +13,40 @@
* 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.
*
* 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
* 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 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.
*
* $FreeBSD: src/sys/dev/aic7xxx/aicasm_symbol.h,v 1.6 1999/12/06 18:23:31 gibbs Exp $
* $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.h,v 1.16 2002/08/31 06:39:41 gibbs Exp $
*/
#ifdef __linux__
#include "../queue.h"
#else
#include <sys/queue.h>
#endif
typedef enum {
UNINITIALIZED,
@ -38,13 +54,16 @@ typedef enum {
ALIAS,
SCBLOC,
SRAMLOC,
ENUM_ENTRY,
FIELD,
MASK,
BIT,
ENUM,
CONST,
DOWNLOAD_CONST,
LABEL,
CONDITIONAL
}symtype;
CONDITIONAL,
MACRO
} symtype;
typedef enum {
RO = 0x01,
@ -52,24 +71,27 @@ typedef enum {
RW = 0x03
}amode_t;
struct reg_info {
u_int8_t address;
int size;
amode_t mode;
u_int8_t valid_bitmask;
int typecheck_masks;
};
typedef SLIST_HEAD(symlist, symbol_node) symlist_t;
struct mask_info {
struct reg_info {
u_int address;
int size;
amode_t mode;
symlist_t fields;
uint8_t valid_bitmask;
uint8_t modes;
int typecheck_masks;
};
struct field_info {
symlist_t symrefs;
u_int8_t mask;
uint8_t value;
uint8_t mask;
};
struct const_info {
u_int8_t value;
int define;
u_int value;
int define;
};
struct alias_info {
@ -78,12 +100,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;
@ -93,12 +129,13 @@ typedef struct symbol {
char *name;
symtype type;
union {
struct reg_info *rinfo;
struct mask_info *minfo;
struct reg_info *rinfo;
struct field_info *finfo;
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;
@ -110,7 +147,13 @@ typedef struct symbol_ref {
typedef struct symbol_node {
SLIST_ENTRY(symbol_node) links;
symbol_t *symbol;
}symbol_node_t;
} symbol_node_t;
typedef struct critical_section {
TAILQ_ENTRY(critical_section) links;
int begin_addr;
int end_addr;
} critical_section_t;
typedef enum {
SCOPE_ROOT,
@ -136,28 +179,29 @@ typedef struct scope {
int func_num;
} scope_t;
TAILQ_HEAD(cs_tailq, critical_section);
SLIST_HEAD(scope_list, scope);
TAILQ_HEAD(scope_tailq, scope);
void symbol_delete __P((symbol_t *symbol));
void symbol_delete(symbol_t *symbol);
void symtable_open __P((void));
void symtable_open(void);
void symtable_close __P((void));
void symtable_close(void);
symbol_t *
symtable_get __P((char *name));
symtable_get(char *name);
symbol_node_t *
symlist_search __P((symlist_t *symlist, char *symname));
symlist_search(symlist_t *symlist, char *symname);
void
symlist_add __P((symlist_t *symlist, symbol_t *symbol, int how));
symlist_add(symlist_t *symlist, symbol_t *symbol, int how);
#define SYMLIST_INSERT_HEAD 0x00
#define SYMLIST_SORT 0x01
void symlist_free __P((symlist_t *symlist));
void symlist_free(symlist_t *symlist);
void symlist_merge __P((symlist_t *symlist_dest, symlist_t *symlist_src1,
symlist_t *symlist_src2));
void symtable_dump __P((FILE *ofile));
void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
symlist_t *symlist_src2);
void symtable_dump(FILE *ofile, FILE *dfile);