Commit 2b48aed1 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by James Bottomley

[SCSI] aic7xxx: Update type check in aicasm grammar

The function type_check() in aicasm grammar code was
never used properly due to a bug.
This patch fixes it up and ensures it's only called if appropriate.

In addition the unused 16bit instruction are disabled, but left in
the code for reference.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 542bd137
...@@ -101,11 +101,12 @@ static void format_3_instr(int opcode, symbol_ref_t *src, ...@@ -101,11 +101,12 @@ static void format_3_instr(int opcode, symbol_ref_t *src,
expression_t *immed, symbol_ref_t *address); expression_t *immed, symbol_ref_t *address);
static void test_readable_symbol(symbol_t *symbol); static void test_readable_symbol(symbol_t *symbol);
static void test_writable_symbol(symbol_t *symbol); static void test_writable_symbol(symbol_t *symbol);
static void type_check(symbol_t *symbol, expression_t *expression, int and_op); static void type_check(symbol_ref_t *sym, expression_t *expression, int and_op);
static void make_expression(expression_t *immed, int value); static void make_expression(expression_t *immed, int value);
static void add_conditional(symbol_t *symbol); static void add_conditional(symbol_t *symbol);
static void add_version(const char *verstring); static void add_version(const char *verstring);
static int is_download_const(expression_t *immed); static int is_download_const(expression_t *immed);
static int is_location_address(symbol_t *symbol);
void yyerror(const char *string); void yyerror(const char *string);
#define SRAM_SYMNAME "SRAM_BASE" #define SRAM_SYMNAME "SRAM_BASE"
...@@ -192,10 +193,10 @@ void yyerror(const char *string); ...@@ -192,10 +193,10 @@ void yyerror(const char *string);
%token <value> T_OR %token <value> T_OR
/* 16 bit extensions */ /* 16 bit extensions, not implemented
%token <value> T_OR16 T_AND16 T_XOR16 T_ADD16 * %token <value> T_OR16 T_AND16 T_XOR16 T_ADD16
%token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG * %token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG
*/
%token T_RET %token T_RET
%token T_NOP %token T_NOP
...@@ -214,7 +215,7 @@ void yyerror(const char *string); ...@@ -214,7 +215,7 @@ void yyerror(const char *string);
%type <expression> expression immediate immediate_or_a %type <expression> expression immediate immediate_or_a
%type <value> export ret f1_opcode f2_opcode f4_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> mode_value mode_list macro_arglist %type <value> mode_value mode_list macro_arglist
...@@ -313,13 +314,13 @@ reg_definition: ...@@ -313,13 +314,13 @@ reg_definition:
stop("Register multiply defined", EX_DATAERR); stop("Register multiply defined", EX_DATAERR);
/* NOTREACHED */ /* NOTREACHED */
} }
cur_symbol = $1; cur_symbol = $1;
cur_symbol->type = cur_symtype; cur_symbol->type = cur_symtype;
initialize_symbol(cur_symbol); initialize_symbol(cur_symbol);
} }
reg_attribute_list reg_attribute_list
'}' '}'
{ {
/* /*
* Default to allowing everything in for registers * Default to allowing everything in for registers
* with no bit or mask definitions. * with no bit or mask definitions.
...@@ -349,7 +350,7 @@ reg_attribute_list: ...@@ -349,7 +350,7 @@ reg_attribute_list:
| reg_attribute_list reg_attribute | reg_attribute_list reg_attribute
; ;
reg_attribute: reg_attribute:
reg_address reg_address
| size | size
| access_mode | access_mode
...@@ -641,14 +642,14 @@ expression: ...@@ -641,14 +642,14 @@ expression:
&($1.referenced_syms), &($1.referenced_syms),
&($3.referenced_syms)); &($3.referenced_syms));
} }
| expression T_EXPR_LSHIFT expression | expression T_EXPR_LSHIFT expression
{ {
$$.value = $1.value << $3.value; $$.value = $1.value << $3.value;
symlist_merge(&$$.referenced_syms, symlist_merge(&$$.referenced_syms,
&$1.referenced_syms, &$1.referenced_syms,
&$3.referenced_syms); &$3.referenced_syms);
} }
| expression T_EXPR_RSHIFT expression | expression T_EXPR_RSHIFT expression
{ {
$$.value = $1.value >> $3.value; $$.value = $1.value >> $3.value;
symlist_merge(&$$.referenced_syms, symlist_merge(&$$.referenced_syms,
...@@ -714,7 +715,7 @@ expression: ...@@ -714,7 +715,7 @@ expression:
; ;
constant: constant:
T_CONST T_SYMBOL expression T_CONST T_SYMBOL expression
{ {
if ($2->type != UNINITIALIZED) { if ($2->type != UNINITIALIZED) {
stop("Re-definition of symbol as a constant", stop("Re-definition of symbol as a constant",
...@@ -1311,14 +1312,18 @@ f2_opcode: ...@@ -1311,14 +1312,18 @@ f2_opcode:
| T_ROR { $$ = AIC_OP_ROR; } | T_ROR { $$ = AIC_OP_ROR; }
; ;
f4_opcode: /*
T_OR16 { $$ = AIC_OP_OR16; } * 16bit opcodes, not used
| T_AND16 { $$ = AIC_OP_AND16; } *
| T_XOR16 { $$ = AIC_OP_XOR16; } *f4_opcode:
| T_ADD16 { $$ = AIC_OP_ADD16; } * T_OR16 { $$ = AIC_OP_OR16; }
| T_ADC16 { $$ = AIC_OP_ADC16; } *| T_AND16 { $$ = AIC_OP_AND16; }
| T_MVI16 { $$ = AIC_OP_MVI16; } *| T_XOR16 { $$ = AIC_OP_XOR16; }
; *| T_ADD16 { $$ = AIC_OP_ADD16; }
*| T_ADC16 { $$ = AIC_OP_ADC16; }
*| T_MVI16 { $$ = AIC_OP_MVI16; }
*;
*/
code: code:
f2_opcode destination ',' expression opt_source ret ';' f2_opcode destination ',' expression opt_source ret ';'
...@@ -1357,6 +1362,7 @@ code: ...@@ -1357,6 +1362,7 @@ code:
code: code:
T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';'
{ {
type_check(&$2, &$4, AIC_OP_OR);
format_3_instr($5, &$2, &$4, &$6); format_3_instr($5, &$2, &$4, &$6);
} }
; ;
...@@ -1528,7 +1534,7 @@ initialize_symbol(symbol_t *symbol) ...@@ -1528,7 +1534,7 @@ initialize_symbol(symbol_t *symbol)
sizeof(struct cond_info)); sizeof(struct cond_info));
break; break;
case MACRO: case MACRO:
symbol->info.macroinfo = symbol->info.macroinfo =
(struct macro_info *)malloc(sizeof(struct macro_info)); (struct macro_info *)malloc(sizeof(struct macro_info));
if (symbol->info.macroinfo == NULL) { if (symbol->info.macroinfo == NULL) {
stop("Can't create macro info", EX_SOFTWARE); stop("Can't create macro info", EX_SOFTWARE);
...@@ -1552,7 +1558,6 @@ add_macro_arg(const char *argtext, int argnum) ...@@ -1552,7 +1558,6 @@ add_macro_arg(const char *argtext, int argnum)
struct macro_arg *marg; struct macro_arg *marg;
int i; int i;
int retval; int retval;
if (cur_symbol == NULL || cur_symbol->type != MACRO) { if (cur_symbol == NULL || cur_symbol->type != MACRO) {
stop("Invalid current symbol for adding macro arg", stop("Invalid current symbol for adding macro arg",
...@@ -1633,8 +1638,10 @@ format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed, ...@@ -1633,8 +1638,10 @@ format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed,
test_writable_symbol(dest->symbol); test_writable_symbol(dest->symbol);
test_readable_symbol(src->symbol); test_readable_symbol(src->symbol);
/* Ensure that immediate makes sense for this destination */ if (!is_location_address(dest->symbol)) {
type_check(dest->symbol, immed, opcode); /* Ensure that immediate makes sense for this destination */
type_check(dest, immed, opcode);
}
/* Allocate sequencer space for the instruction and fill it out */ /* Allocate sequencer space for the instruction and fill it out */
instr = seq_alloc(); instr = seq_alloc();
...@@ -1766,9 +1773,6 @@ format_3_instr(int opcode, symbol_ref_t *src, ...@@ -1766,9 +1773,6 @@ format_3_instr(int opcode, symbol_ref_t *src,
/* Test register permissions */ /* Test register permissions */
test_readable_symbol(src->symbol); test_readable_symbol(src->symbol);
/* Ensure that immediate makes sense for this source */
type_check(src->symbol, immed, opcode);
/* Allocate sequencer space for the instruction and fill it out */ /* Allocate sequencer space for the instruction and fill it out */
instr = seq_alloc(); instr = seq_alloc();
f3_instr = &instr->format.format3; f3_instr = &instr->format.format3;
...@@ -1797,7 +1801,6 @@ format_3_instr(int opcode, symbol_ref_t *src, ...@@ -1797,7 +1801,6 @@ format_3_instr(int opcode, symbol_ref_t *src,
static void static void
test_readable_symbol(symbol_t *symbol) test_readable_symbol(symbol_t *symbol)
{ {
if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) { if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) {
snprintf(errbuf, sizeof(errbuf), snprintf(errbuf, sizeof(errbuf),
"Register %s unavailable in source reg mode %d", "Register %s unavailable in source reg mode %d",
...@@ -1815,7 +1818,6 @@ test_readable_symbol(symbol_t *symbol) ...@@ -1815,7 +1818,6 @@ test_readable_symbol(symbol_t *symbol)
static void static void
test_writable_symbol(symbol_t *symbol) test_writable_symbol(symbol_t *symbol)
{ {
if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) { if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) {
snprintf(errbuf, sizeof(errbuf), snprintf(errbuf, sizeof(errbuf),
"Register %s unavailable in destination reg mode %d", "Register %s unavailable in destination reg mode %d",
...@@ -1831,25 +1833,34 @@ test_writable_symbol(symbol_t *symbol) ...@@ -1831,25 +1833,34 @@ test_writable_symbol(symbol_t *symbol)
} }
static void static void
type_check(symbol_t *symbol, expression_t *expression, int opcode) type_check(symbol_ref_t *sym, expression_t *expression, int opcode)
{ {
symbol_t *symbol = sym->symbol;
symbol_node_t *node; symbol_node_t *node;
int and_op; int and_op;
int8_t value, mask;
and_op = FALSE; and_op = FALSE;
if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ)
and_op = TRUE;
/* /*
* Make sure that we aren't attempting to write something * Make sure that we aren't attempting to write something
* that hasn't been defined. If this is an and operation, * that hasn't been defined. If this is an and operation,
* this is a mask, so "undefined" bits are okay. * this is a mask, so "undefined" bits are okay.
*/ */
if (and_op == FALSE if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ ||
&& (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) { opcode == AIC_OP_JZ || opcode == AIC_OP_JNE ||
opcode == AIC_OP_BMOV)
and_op = TRUE;
/*
* Defaulting to 8 bit logic
*/
mask = (int8_t)~symbol->info.rinfo->valid_bitmask;
value = (int8_t)expression->value;
if (and_op == FALSE && (mask & value) != 0 ) {
snprintf(errbuf, sizeof(errbuf), snprintf(errbuf, sizeof(errbuf),
"Invalid bit(s) 0x%x in immediate written to %s", "Invalid bit(s) 0x%x in immediate written to %s",
expression->value & ~symbol->info.rinfo->valid_bitmask, (mask & value),
symbol->name); symbol->name);
stop(errbuf, EX_DATAERR); stop(errbuf, EX_DATAERR);
/* NOTREACHED */ /* NOTREACHED */
...@@ -1959,3 +1970,13 @@ is_download_const(expression_t *immed) ...@@ -1959,3 +1970,13 @@ is_download_const(expression_t *immed)
return (FALSE); return (FALSE);
} }
static int
is_location_address(symbol_t *sym)
{
if (sym->type == SCBLOC ||
sym->type == SRAMLOC)
return (TRUE);
return (FALSE);
}
...@@ -228,15 +228,15 @@ ret { return T_RET; } ...@@ -228,15 +228,15 @@ ret { return T_RET; }
nop { return T_NOP; } nop { return T_NOP; }
/* ARP2 16bit extensions */ /* ARP2 16bit extensions */
or16 { return T_OR16; } /* or16 { return T_OR16; } */
and16 { return T_AND16; } /* and16 { return T_AND16; }*/
xor16 { return T_XOR16; } /* xor16 { return T_XOR16; }*/
add16 { return T_ADD16; } /* add16 { return T_ADD16; }*/
adc16 { return T_ADC16; } /* adc16 { return T_ADC16; }*/
mvi16 { return T_MVI16; } /* mvi16 { return T_MVI16; }*/
test16 { return T_TEST16; } /* test16 { return T_TEST16; }*/
cmp16 { return T_CMP16; } /* cmp16 { return T_CMP16; }*/
cmpxchg { return T_CMPXCHG; } /* cmpxchg { return T_CMPXCHG; }*/
/* Allowed Symbols */ /* Allowed Symbols */
\<\< { return T_EXPR_LSHIFT; } \<\< { return T_EXPR_LSHIFT; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment