Add macro functionality.
Staticize and allow unique naming of data structures so that more than on sequencer program can be statically compiled into the kernel at a time.
This commit is contained in:
parent
d5ccecfad7
commit
7ce72dbaec
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
@ -1180,26 +1444,76 @@ 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 */
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
164
sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y
Normal file
164
sys/dev/aic7xxx/aicasm/aicasm_macro_gram.y
Normal file
@ -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);
|
||||
}
|
154
sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l
Normal file
154
sys/dev/aic7xxx/aicasm/aicasm_macro_scan.l
Normal file
@ -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);
|
||||
}
|
@ -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"
|
||||
#include "aicasm_gram.h"
|
||||
|
||||
#define MAX_STR_CONST 256
|
||||
char string_buf[MAX_STR_CONST];
|
||||
char *string_buf_ptr;
|
||||
int parren_count;
|
||||
int quote_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];
|
||||
%}
|
||||
|
||||
%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;
|
||||
|
||||
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);
|
||||
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user