patch-2.4.22 linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
Next file: linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
Previous file: linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm.h
Back to the patch index
Back to the overall index
- Lines: 458
- Date:
2003-08-25 04:44:42.000000000 -0700
- Orig file:
linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
- Orig date:
2003-06-13 07:51:36.000000000 -0700
diff -urN linux-2.4.21/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y linux-2.4.22/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -3,7 +3,7 @@
* Parser for the Aic7xxx SCSI Host adapter sequencer assembler.
*
* Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
- * Copyright (c) 2001 Adaptec Inc.
+ * Copyright (c) 2001, 2002 Adaptec Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,9 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#15 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $
*
- * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.11.2.5 2002/04/29 19:36:36 gibbs Exp $
+ * $FreeBSD$
*/
#include <sys/types.h>
@@ -64,11 +64,14 @@
int yylineno;
char *yyfilename;
+char stock_prefix[] = "aic_";
+char *prefix = stock_prefix;
char *patch_arg_list;
char *versions;
static char errbuf[255];
static char regex_pattern[255];
static symbol_t *cur_symbol;
+static symbol_t *field_symbol;
static symbol_t *scb_or_sram_symbol;
static symtype cur_symtype;
static symbol_ref_t accumulator;
@@ -82,8 +85,10 @@
static int sram_or_scb_offset;
static int download_constant_count;
static int in_critical_section;
+static u_int enum_increment;
+static u_int enum_next_value;
-static void process_bitmask(int mask_type, symbol_t *sym, int mask);
+static void process_field(int field_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);
@@ -152,7 +157,9 @@
%token T_END_CS
-%token T_BIT
+%token T_FIELD
+
+%token T_ENUM
%token T_MASK
@@ -162,7 +169,7 @@
%token <sym> T_CEXPR
-%token T_EOF T_INCLUDE T_VERSION T_PATCH_ARG_LIST
+%token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST
%token <value> T_SHR T_SHL T_ROR T_ROL
@@ -202,7 +209,7 @@
%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
-%type <value> numerical_value mode_value mode_list macro_arglist
+%type <value> mode_value mode_list macro_arglist
%left '|'
%left '&'
@@ -216,6 +223,8 @@
program:
include
| program include
+| prefix
+| program prefix
| patch_arg_list
| program patch_arg_list
| version
@@ -257,6 +266,18 @@
}
;
+prefix:
+ T_PREFIX '=' T_STRING
+ {
+ if (prefix != stock_prefix)
+ stop("Prefix multiply defined",
+ EX_DATAERR);
+ prefix = strdup($3);
+ if (prefix == NULL)
+ stop("Unable to record prefix", EX_SOFTWARE);
+ }
+;
+
patch_arg_list:
T_PATCH_ARG_LIST '=' T_STRING
{
@@ -326,7 +347,8 @@
| size
| access_mode
| modes
-| bit_defn
+| field_defn
+| enum_defn
| mask_defn
| alias
| accumulator
@@ -418,17 +440,68 @@
}
;
-bit_defn:
- T_BIT T_SYMBOL T_NUMBER
+field_defn:
+ T_FIELD
+ {
+ field_symbol = NULL;
+ enum_next_value = 0;
+ enum_increment = 1;
+ }
+ '{' enum_entry_list '}'
+| T_FIELD T_SYMBOL expression
+ {
+ process_field(FIELD, $2, $3.value);
+ field_symbol = $2;
+ enum_next_value = 0;
+ enum_increment = 0x01 << (ffs($3.value) - 1);
+ }
+ '{' enum_entry_list '}'
+| T_FIELD T_SYMBOL expression
+ {
+ process_field(FIELD, $2, $3.value);
+ }
+;
+
+enum_defn:
+ T_ENUM
+ {
+ field_symbol = NULL;
+ enum_next_value = 0;
+ enum_increment = 1;
+ }
+ '{' enum_entry_list '}'
+| T_ENUM T_SYMBOL expression
+ {
+ process_field(ENUM, $2, $3.value);
+ field_symbol = $2;
+ enum_next_value = 0;
+ enum_increment = 0x01 << (ffs($3.value) - 1);
+ }
+ '{' enum_entry_list '}'
+;
+
+enum_entry_list:
+ enum_entry
+| enum_entry_list ',' enum_entry
+;
+
+enum_entry:
+ T_SYMBOL
{
- process_bitmask(BIT, $2, $3);
+ process_field(ENUM_ENTRY, $1, enum_next_value);
+ enum_next_value += enum_increment;
+ }
+| T_SYMBOL expression
+ {
+ process_field(ENUM_ENTRY, $1, $2.value);
+ enum_next_value = $2.value + enum_increment;
}
;
mask_defn:
T_MASK T_SYMBOL expression
{
- process_bitmask(MASK, $2, $3.value);
+ process_field(MASK, $2, $3.value);
}
;
@@ -608,8 +681,10 @@
$$.value = symbol->info.rinfo->address;
break;
case MASK:
- case BIT:
- $$.value = symbol->info.minfo->mask;
+ case FIELD:
+ case ENUM:
+ case ENUM_ENTRY:
+ $$.value = symbol->info.finfo->value;
break;
case DOWNLOAD_CONST:
case CONST:
@@ -632,7 +707,7 @@
;
constant:
- T_CONST T_SYMBOL numerical_value
+ T_CONST T_SYMBOL expression
{
if ($2->type != UNINITIALIZED) {
stop("Re-definition of symbol as a constant",
@@ -641,7 +716,7 @@
}
$2->type = CONST;
initialize_symbol($2);
- $2->info.cinfo->value = $3;
+ $2->info.cinfo->value = $3.value;
}
| T_CONST T_SYMBOL T_DOWNLOAD
{
@@ -709,17 +784,6 @@
}
;
-numerical_value:
- T_NUMBER
- {
- $$ = $1;
- }
-| '-' T_NUMBER
- {
- $$ = -$2;
- }
-;
-
scratch_ram:
T_SRAM '{'
{
@@ -862,6 +926,8 @@
| T_A
{
SLIST_INIT(&$$.referenced_syms);
+ symlist_add(&$$.referenced_syms, accumulator.symbol,
+ SYMLIST_INSERT_HEAD);
$$.value = 0;
}
;
@@ -917,6 +983,7 @@
cs->begin_addr = instruction_ptr;
in_critical_section = TRUE;
}
+;
critical_section_end:
T_END_CS ';'
@@ -931,6 +998,7 @@
cs->end_addr = instruction_ptr;
in_critical_section = FALSE;
}
+;
export:
{ $$ = 0; }
@@ -1161,9 +1229,22 @@
;
code:
- T_MVI destination ',' immediate_or_a ret ';'
+ T_MVI destination ',' immediate ret ';'
{
- format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
+ if ($4.value == 0
+ && is_download_const(&$4) == 0) {
+ expression_t immed;
+
+ /*
+ * Allow move immediates of 0 so that macros,
+ * that can't know the immediate's value and
+ * otherwise compensate, still work.
+ */
+ make_expression(&immed, 1);
+ format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5);
+ } else {
+ format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
+ }
}
;
@@ -1298,7 +1379,7 @@
%%
static void
-process_bitmask(int mask_type, symbol_t *sym, int mask)
+process_field(int field_type, symbol_t *sym, int value)
{
/*
* Add the current register to its
@@ -1308,52 +1389,54 @@
* the "allowed bits" of this register.
*/
if (sym->type == UNINITIALIZED) {
- sym->type = mask_type;
+ sym->type = field_type;
initialize_symbol(sym);
- if (mask_type == BIT) {
- if (mask == 0) {
- stop("Bitmask with no bits set", EX_DATAERR);
- /* NOTREACHED */
- }
- if ((mask & ~(0x01 << (ffs(mask) - 1))) != 0) {
- stop("Bitmask with more than one bit set",
- EX_DATAERR);
+ sym->info.finfo->value = value;
+ if (field_type != ENUM_ENTRY) {
+ if (field_type != MASK && value == 0) {
+ stop("Empty Field, or Enum", EX_DATAERR);
/* NOTREACHED */
}
+ sym->info.finfo->value = value;
+ sym->info.finfo->mask = value;
+ } else if (field_symbol != NULL) {
+ sym->info.finfo->mask = field_symbol->info.finfo->value;
+ } else {
+ sym->info.finfo->mask = 0xFF;
}
- sym->info.minfo->mask = mask;
- } else if (sym->type != mask_type) {
- stop("Bit definition mirrors a definition of the same "
+ } else if (sym->type != field_type) {
+ stop("Field definition mirrors a definition of the same "
" name, but a different type", EX_DATAERR);
/* NOTREACHED */
- } else if (mask != sym->info.minfo->mask) {
- stop("Bitmask redefined with a conflicting value", EX_DATAERR);
+ } else if (value != sym->info.finfo->value) {
+ stop("Field redefined with a conflicting value", EX_DATAERR);
/* NOTREACHED */
}
/* Fail if this symbol is already listed */
- if (symlist_search(&(sym->info.minfo->symrefs),
+ if (symlist_search(&(sym->info.finfo->symrefs),
cur_symbol->name) != NULL) {
- stop("Bitmask defined multiple times for register", EX_DATAERR);
+ stop("Field defined multiple times for register", EX_DATAERR);
/* NOTREACHED */
}
- symlist_add(&(sym->info.minfo->symrefs), cur_symbol,
+ symlist_add(&(sym->info.finfo->symrefs), cur_symbol,
SYMLIST_INSERT_HEAD);
- cur_symbol->info.rinfo->valid_bitmask |= mask;
+ cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask;
cur_symbol->info.rinfo->typecheck_masks = TRUE;
+ symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT);
}
static void
initialize_symbol(symbol_t *symbol)
{
switch (symbol->type) {
- case UNINITIALIZED:
+ case UNINITIALIZED:
stop("Call to initialize_symbol with type field unset",
EX_SOFTWARE);
/* NOTREACHED */
break;
- case REGISTER:
- case SRAMLOC:
- case SCBLOC:
+ case REGISTER:
+ case SRAMLOC:
+ case SCBLOC:
symbol->info.rinfo =
(struct reg_info *)malloc(sizeof(struct reg_info));
if (symbol->info.rinfo == NULL) {
@@ -1362,6 +1445,7 @@
}
memset(symbol->info.rinfo, 0,
sizeof(struct reg_info));
+ SLIST_INIT(&(symbol->info.rinfo->fields));
/*
* Default to allowing access in all register modes
* or to the mode specified by the SCB or SRAM space
@@ -1373,7 +1457,7 @@
else
symbol->info.rinfo->modes = ~0;
break;
- case ALIAS:
+ case ALIAS:
symbol->info.ainfo =
(struct alias_info *)malloc(sizeof(struct alias_info));
if (symbol->info.ainfo == NULL) {
@@ -1383,19 +1467,21 @@
memset(symbol->info.ainfo, 0,
sizeof(struct alias_info));
break;
- case MASK:
- case BIT:
- symbol->info.minfo =
- (struct mask_info *)malloc(sizeof(struct mask_info));
- if (symbol->info.minfo == NULL) {
- stop("Can't create bitmask info", EX_SOFTWARE);
+ case MASK:
+ case FIELD:
+ case ENUM:
+ case ENUM_ENTRY:
+ symbol->info.finfo =
+ (struct field_info *)malloc(sizeof(struct field_info));
+ if (symbol->info.finfo == NULL) {
+ stop("Can't create field info", EX_SOFTWARE);
/* NOTREACHED */
}
- memset(symbol->info.minfo, 0, sizeof(struct mask_info));
- SLIST_INIT(&(symbol->info.minfo->symrefs));
+ memset(symbol->info.finfo, 0, sizeof(struct field_info));
+ SLIST_INIT(&(symbol->info.finfo->symrefs));
break;
- case CONST:
- case DOWNLOAD_CONST:
+ case CONST:
+ case DOWNLOAD_CONST:
symbol->info.cinfo =
(struct const_info *)malloc(sizeof(struct const_info));
if (symbol->info.cinfo == NULL) {
@@ -1577,7 +1663,6 @@
case AIC_OP_OR:
dst_value = src_value | immed->value;
break;
- break;
case AIC_OP_BMOV:
dst_value = src_value;
break;
@@ -1586,9 +1671,9 @@
}
src_mode = dst_value & 0xF;
dst_mode = (dst_value >> 4) & 0xF;
-cant_update:
}
+cant_update:
symlist_free(&immed->referenced_syms);
instruction_ptr++;
}
@@ -1763,11 +1848,13 @@
node != NULL;
node = node->links.sle_next) {
if ((node->symbol->type == MASK
- || node->symbol->type == BIT)
- && symlist_search(&node->symbol->info.minfo->symrefs,
+ || node->symbol->type == FIELD
+ || node->symbol->type == ENUM
+ || node->symbol->type == ENUM_ENTRY)
+ && symlist_search(&node->symbol->info.finfo->symrefs,
symbol->name) == NULL) {
snprintf(errbuf, sizeof(errbuf),
- "Invalid bit or mask %s "
+ "Invalid field or mask %s "
"for register %s",
node->symbol->name, symbol->name);
stop(errbuf, EX_DATAERR);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)