summaryrefslogtreecommitdiff
path: root/sys/dev/microcode/aic7xxx/aicasm_gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/microcode/aic7xxx/aicasm_gram.y')
-rw-r--r--sys/dev/microcode/aic7xxx/aicasm_gram.y121
1 files changed, 111 insertions, 10 deletions
diff --git a/sys/dev/microcode/aic7xxx/aicasm_gram.y b/sys/dev/microcode/aic7xxx/aicasm_gram.y
index 38b0dbcb53e..c2889c5c2ba 100644
--- a/sys/dev/microcode/aic7xxx/aicasm_gram.y
+++ b/sys/dev/microcode/aic7xxx/aicasm_gram.y
@@ -2,7 +2,7 @@
/*
* Parser for the Aic7xxx SCSI Host adapter sequencer assembler.
*
- * 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
@@ -14,6 +14,9 @@
* 2. The name of the author may not 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").
+ *
* 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
@@ -26,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/dev/aic7xxx/aicasm_gram.y,v 1.8 1999/12/06 18:23:30 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.15 2001/07/18 21:03:32 gibbs Exp $
*/
#include <stdio.h>
@@ -43,6 +46,7 @@
int yylineno;
char *yyfilename;
+char *versions;
static symbol_t *cur_symbol;
static symtype cur_symtype;
static symbol_t *accumulator;
@@ -53,6 +57,7 @@ static symbol_ref_t sindex;
static int instruction_ptr;
static int sram_or_scb_offset;
static int download_constant_count;
+static int in_critical_section;
static void process_bitmask __P((int mask_type, symbol_t *sym, int mask));
static void initialize_symbol __P((symbol_t *symbol));
@@ -71,6 +76,7 @@ static void type_check __P((symbol_t *symbol, expression_t *expression,
int and_op));
static void make_expression __P((expression_t *immed, int value));
static void add_conditional __P((symbol_t *symbol));
+static void add_version __P((const char *));
static int is_download_const __P((expression_t *immed));
#define YYDEBUG 1
@@ -106,17 +112,21 @@ static int is_download_const __P((expression_t *immed));
%token <value> T_MODE
+%token T_BEGIN_CS
+
+%token T_END_CS
+
%token T_BIT
%token T_MASK
%token <value> T_NUMBER
-%token <str> T_PATH
+%token <str> T_PATH T_STRING
%token <sym> T_CEXPR
-%token T_EOF T_INCLUDE
+%token T_EOF T_INCLUDE T_VERSION
%token <value> T_SHR T_SHL T_ROR T_ROL
@@ -130,7 +140,7 @@ static int is_download_const __P((expression_t *immed));
%token <value> T_STC T_CLC
-%token <value> T_CMP T_XOR
+%token <value> T_CMP T_NOT T_XOR
%token <value> T_TEST T_AND
@@ -168,6 +178,8 @@ static int is_download_const __P((expression_t *immed));
program:
include
| program include
+| version
+| program version
| register
| program register
| constant
@@ -178,6 +190,10 @@ program:
| program scb
| label
| program label
+| critical_section_start
+| program critical_section_start
+| critical_section_end
+| program critical_section_end
| conditional
| program conditional
| code
@@ -186,9 +202,18 @@ program:
include:
T_INCLUDE '<' T_PATH '>'
- { include_file($3, BRACKETED_INCLUDE); }
+ {
+ include_file($3, BRACKETED_INCLUDE);
+ }
| T_INCLUDE '"' T_PATH '"'
- { include_file($3, QUOTED_INCLUDE); }
+ {
+ include_file($3, QUOTED_INCLUDE);
+ }
+;
+
+version:
+ T_VERSION '=' T_STRING
+ { add_version($3); }
;
register:
@@ -527,6 +552,8 @@ scb:
}
cur_symbol->type = SCBLOC;
initialize_symbol(cur_symbol);
+ /* 64 bytes of SCB space */
+ cur_symbol->info.rinfo->size = 64;
}
reg_address
{
@@ -551,6 +578,21 @@ reg_symbol:
$$.symbol = $1;
$$.offset = 0;
}
+| T_SYMBOL '[' T_SYMBOL ']'
+ {
+ process_register(&$1);
+ if ($3->type != CONST) {
+ stop("register offset must be a constant", EX_DATAERR);
+ /* NOTREACHED */
+ }
+ if (($3->info.cinfo->value + 1) > $1->info.rinfo->size) {
+ stop("Accessing offset beyond range of register",
+ EX_DATAERR);
+ /* NOTREACHED */
+ }
+ $$.symbol = $1;
+ $$.offset = $3->info.cinfo->value;
+ }
| T_SYMBOL '[' T_NUMBER ']'
{
process_register(&$1);
@@ -621,6 +663,35 @@ ret:
{ $$ = 1; }
;
+critical_section_start:
+ T_BEGIN_CS
+ {
+ critical_section_t *cs;
+
+ if (in_critical_section != FALSE) {
+ stop("Critical Section within Critical Section",
+ EX_DATAERR);
+ /* NOTREACHED */
+ }
+ cs = cs_alloc();
+ cs->begin_addr = instruction_ptr;
+ in_critical_section = TRUE;
+ }
+
+critical_section_end:
+ T_END_CS
+ {
+ critical_section_t *cs;
+
+ if (in_critical_section == FALSE) {
+ stop("Unballanced 'end_cs'", EX_DATAERR);
+ /* NOTREACHED */
+ }
+ cs = TAILQ_LAST(&cs_tailq, cs_tailq);
+ cs->end_addr = instruction_ptr;
+ in_critical_section = FALSE;
+ }
+
label:
T_SYMBOL ':'
{
@@ -732,7 +803,6 @@ conditional:
'}'
{
scope_t *scope_context;
- scope_t *last_scope;
scope_context = SLIST_FIRST(&scope_stack);
if (scope_context->type == SCOPE_ROOT) {
@@ -838,8 +908,8 @@ code:
{
expression_t immed;
- make_expression(&immed, 0xff);
- format_1_instr(AIC_OP_AND, &$2, &immed, &$4, $5);
+ make_expression(&immed, 1);
+ format_1_instr(AIC_OP_BMOV, &$2, &immed, &$4, $5);
}
;
@@ -847,6 +917,16 @@ code:
T_MVI destination ',' immediate_or_a ret ';'
{
format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
+ }
+;
+
+code:
+ T_NOT destination opt_source ret ';'
+ {
+ expression_t immed;
+
+ make_expression(&immed, 0xff);
+ format_1_instr(AIC_OP_XOR, &$2, &immed, &$3, $4);
}
;
@@ -1391,6 +1471,27 @@ add_conditional(symbol)
symlist_add(&patch_functions, symbol, SYMLIST_INSERT_HEAD);
}
+static void
+add_version(verstring)
+const char *verstring;
+{
+ const char prefix[] = " * ";
+ int newlen;
+ int oldlen;
+
+ newlen = strlen(verstring) + strlen(prefix);
+ oldlen = 0;
+ if (versions != NULL)
+ oldlen = strlen(versions);
+ versions = realloc(versions, newlen + oldlen + 2);
+ if (versions == NULL)
+ stop("Can't allocate version string", EX_SOFTWARE);
+ strcpy(&versions[oldlen], prefix);
+ strcpy(&versions[oldlen + strlen(prefix)], verstring);
+ versions[newlen + oldlen] = '\n';
+ versions[newlen + oldlen + 1] = '\0';
+}
+
void
yyerror(string)
const char *string;