diff options
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | 93 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aicasm/aicasm_scan.l | 18 |
2 files changed, 66 insertions, 45 deletions
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index 702e2dbd11fb..e1079dd3cc28 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | |||
@@ -101,11 +101,12 @@ static void format_3_instr(int opcode, symbol_ref_t *src, | |||
101 | expression_t *immed, symbol_ref_t *address); | 101 | expression_t *immed, symbol_ref_t *address); |
102 | static void test_readable_symbol(symbol_t *symbol); | 102 | static void test_readable_symbol(symbol_t *symbol); |
103 | static void test_writable_symbol(symbol_t *symbol); | 103 | static void test_writable_symbol(symbol_t *symbol); |
104 | static void type_check(symbol_t *symbol, expression_t *expression, int and_op); | 104 | static void type_check(symbol_ref_t *sym, expression_t *expression, int and_op); |
105 | static void make_expression(expression_t *immed, int value); | 105 | static void make_expression(expression_t *immed, int value); |
106 | static void add_conditional(symbol_t *symbol); | 106 | static void add_conditional(symbol_t *symbol); |
107 | static void add_version(const char *verstring); | 107 | static void add_version(const char *verstring); |
108 | static int is_download_const(expression_t *immed); | 108 | static int is_download_const(expression_t *immed); |
109 | static int is_location_address(symbol_t *symbol); | ||
109 | void yyerror(const char *string); | 110 | void yyerror(const char *string); |
110 | 111 | ||
111 | #define SRAM_SYMNAME "SRAM_BASE" | 112 | #define SRAM_SYMNAME "SRAM_BASE" |
@@ -192,10 +193,10 @@ void yyerror(const char *string); | |||
192 | 193 | ||
193 | %token <value> T_OR | 194 | %token <value> T_OR |
194 | 195 | ||
195 | /* 16 bit extensions */ | 196 | /* 16 bit extensions, not implemented |
196 | %token <value> T_OR16 T_AND16 T_XOR16 T_ADD16 | 197 | * %token <value> T_OR16 T_AND16 T_XOR16 T_ADD16 |
197 | %token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG | 198 | * %token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG |
198 | 199 | */ | |
199 | %token T_RET | 200 | %token T_RET |
200 | 201 | ||
201 | %token T_NOP | 202 | %token T_NOP |
@@ -214,7 +215,7 @@ void yyerror(const char *string); | |||
214 | 215 | ||
215 | %type <expression> expression immediate immediate_or_a | 216 | %type <expression> expression immediate immediate_or_a |
216 | 217 | ||
217 | %type <value> export ret f1_opcode f2_opcode f4_opcode jmp_jc_jnc_call jz_jnz je_jne | 218 | %type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne |
218 | 219 | ||
219 | %type <value> mode_value mode_list macro_arglist | 220 | %type <value> mode_value mode_list macro_arglist |
220 | 221 | ||
@@ -313,13 +314,13 @@ reg_definition: | |||
313 | stop("Register multiply defined", EX_DATAERR); | 314 | stop("Register multiply defined", EX_DATAERR); |
314 | /* NOTREACHED */ | 315 | /* NOTREACHED */ |
315 | } | 316 | } |
316 | cur_symbol = $1; | 317 | cur_symbol = $1; |
317 | cur_symbol->type = cur_symtype; | 318 | cur_symbol->type = cur_symtype; |
318 | initialize_symbol(cur_symbol); | 319 | initialize_symbol(cur_symbol); |
319 | } | 320 | } |
320 | reg_attribute_list | 321 | reg_attribute_list |
321 | '}' | 322 | '}' |
322 | { | 323 | { |
323 | /* | 324 | /* |
324 | * Default to allowing everything in for registers | 325 | * Default to allowing everything in for registers |
325 | * with no bit or mask definitions. | 326 | * with no bit or mask definitions. |
@@ -349,7 +350,7 @@ reg_attribute_list: | |||
349 | | reg_attribute_list reg_attribute | 350 | | reg_attribute_list reg_attribute |
350 | ; | 351 | ; |
351 | 352 | ||
352 | reg_attribute: | 353 | reg_attribute: |
353 | reg_address | 354 | reg_address |
354 | | size | 355 | | size |
355 | | access_mode | 356 | | access_mode |
@@ -641,14 +642,14 @@ expression: | |||
641 | &($1.referenced_syms), | 642 | &($1.referenced_syms), |
642 | &($3.referenced_syms)); | 643 | &($3.referenced_syms)); |
643 | } | 644 | } |
644 | | expression T_EXPR_LSHIFT expression | 645 | | expression T_EXPR_LSHIFT expression |
645 | { | 646 | { |
646 | $$.value = $1.value << $3.value; | 647 | $$.value = $1.value << $3.value; |
647 | symlist_merge(&$$.referenced_syms, | 648 | symlist_merge(&$$.referenced_syms, |
648 | &$1.referenced_syms, | 649 | &$1.referenced_syms, |
649 | &$3.referenced_syms); | 650 | &$3.referenced_syms); |
650 | } | 651 | } |
651 | | expression T_EXPR_RSHIFT expression | 652 | | expression T_EXPR_RSHIFT expression |
652 | { | 653 | { |
653 | $$.value = $1.value >> $3.value; | 654 | $$.value = $1.value >> $3.value; |
654 | symlist_merge(&$$.referenced_syms, | 655 | symlist_merge(&$$.referenced_syms, |
@@ -714,7 +715,7 @@ expression: | |||
714 | ; | 715 | ; |
715 | 716 | ||
716 | constant: | 717 | constant: |
717 | T_CONST T_SYMBOL expression | 718 | T_CONST T_SYMBOL expression |
718 | { | 719 | { |
719 | if ($2->type != UNINITIALIZED) { | 720 | if ($2->type != UNINITIALIZED) { |
720 | stop("Re-definition of symbol as a constant", | 721 | stop("Re-definition of symbol as a constant", |
@@ -1311,14 +1312,18 @@ f2_opcode: | |||
1311 | | T_ROR { $$ = AIC_OP_ROR; } | 1312 | | T_ROR { $$ = AIC_OP_ROR; } |
1312 | ; | 1313 | ; |
1313 | 1314 | ||
1314 | f4_opcode: | 1315 | /* |
1315 | T_OR16 { $$ = AIC_OP_OR16; } | 1316 | * 16bit opcodes, not used |
1316 | | T_AND16 { $$ = AIC_OP_AND16; } | 1317 | * |
1317 | | T_XOR16 { $$ = AIC_OP_XOR16; } | 1318 | *f4_opcode: |
1318 | | T_ADD16 { $$ = AIC_OP_ADD16; } | 1319 | * T_OR16 { $$ = AIC_OP_OR16; } |
1319 | | T_ADC16 { $$ = AIC_OP_ADC16; } | 1320 | *| T_AND16 { $$ = AIC_OP_AND16; } |
1320 | | T_MVI16 { $$ = AIC_OP_MVI16; } | 1321 | *| T_XOR16 { $$ = AIC_OP_XOR16; } |
1321 | ; | 1322 | *| T_ADD16 { $$ = AIC_OP_ADD16; } |
1323 | *| T_ADC16 { $$ = AIC_OP_ADC16; } | ||
1324 | *| T_MVI16 { $$ = AIC_OP_MVI16; } | ||
1325 | *; | ||
1326 | */ | ||
1322 | 1327 | ||
1323 | code: | 1328 | code: |
1324 | f2_opcode destination ',' expression opt_source ret ';' | 1329 | f2_opcode destination ',' expression opt_source ret ';' |
@@ -1357,6 +1362,7 @@ code: | |||
1357 | code: | 1362 | code: |
1358 | T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' | 1363 | T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' |
1359 | { | 1364 | { |
1365 | type_check(&$2, &$4, AIC_OP_OR); | ||
1360 | format_3_instr($5, &$2, &$4, &$6); | 1366 | format_3_instr($5, &$2, &$4, &$6); |
1361 | } | 1367 | } |
1362 | ; | 1368 | ; |
@@ -1528,7 +1534,7 @@ initialize_symbol(symbol_t *symbol) | |||
1528 | sizeof(struct cond_info)); | 1534 | sizeof(struct cond_info)); |
1529 | break; | 1535 | break; |
1530 | case MACRO: | 1536 | case MACRO: |
1531 | symbol->info.macroinfo = | 1537 | symbol->info.macroinfo = |
1532 | (struct macro_info *)malloc(sizeof(struct macro_info)); | 1538 | (struct macro_info *)malloc(sizeof(struct macro_info)); |
1533 | if (symbol->info.macroinfo == NULL) { | 1539 | if (symbol->info.macroinfo == NULL) { |
1534 | stop("Can't create macro info", EX_SOFTWARE); | 1540 | stop("Can't create macro info", EX_SOFTWARE); |
@@ -1552,7 +1558,6 @@ add_macro_arg(const char *argtext, int argnum) | |||
1552 | struct macro_arg *marg; | 1558 | struct macro_arg *marg; |
1553 | int i; | 1559 | int i; |
1554 | int retval; | 1560 | int retval; |
1555 | |||
1556 | 1561 | ||
1557 | if (cur_symbol == NULL || cur_symbol->type != MACRO) { | 1562 | if (cur_symbol == NULL || cur_symbol->type != MACRO) { |
1558 | stop("Invalid current symbol for adding macro arg", | 1563 | 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 | test_writable_symbol(dest->symbol); | 1638 | test_writable_symbol(dest->symbol); |
1634 | test_readable_symbol(src->symbol); | 1639 | test_readable_symbol(src->symbol); |
1635 | 1640 | ||
1636 | /* Ensure that immediate makes sense for this destination */ | 1641 | if (!is_location_address(dest->symbol)) { |
1637 | type_check(dest->symbol, immed, opcode); | 1642 | /* Ensure that immediate makes sense for this destination */ |
1643 | type_check(dest, immed, opcode); | ||
1644 | } | ||
1638 | 1645 | ||
1639 | /* Allocate sequencer space for the instruction and fill it out */ | 1646 | /* Allocate sequencer space for the instruction and fill it out */ |
1640 | instr = seq_alloc(); | 1647 | instr = seq_alloc(); |
@@ -1766,9 +1773,6 @@ format_3_instr(int opcode, symbol_ref_t *src, | |||
1766 | /* Test register permissions */ | 1773 | /* Test register permissions */ |
1767 | test_readable_symbol(src->symbol); | 1774 | test_readable_symbol(src->symbol); |
1768 | 1775 | ||
1769 | /* Ensure that immediate makes sense for this source */ | ||
1770 | type_check(src->symbol, immed, opcode); | ||
1771 | |||
1772 | /* Allocate sequencer space for the instruction and fill it out */ | 1776 | /* Allocate sequencer space for the instruction and fill it out */ |
1773 | instr = seq_alloc(); | 1777 | instr = seq_alloc(); |
1774 | f3_instr = &instr->format.format3; | 1778 | f3_instr = &instr->format.format3; |
@@ -1797,7 +1801,6 @@ format_3_instr(int opcode, symbol_ref_t *src, | |||
1797 | static void | 1801 | static void |
1798 | test_readable_symbol(symbol_t *symbol) | 1802 | test_readable_symbol(symbol_t *symbol) |
1799 | { | 1803 | { |
1800 | |||
1801 | if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) { | 1804 | if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) { |
1802 | snprintf(errbuf, sizeof(errbuf), | 1805 | snprintf(errbuf, sizeof(errbuf), |
1803 | "Register %s unavailable in source reg mode %d", | 1806 | "Register %s unavailable in source reg mode %d", |
@@ -1815,7 +1818,6 @@ test_readable_symbol(symbol_t *symbol) | |||
1815 | static void | 1818 | static void |
1816 | test_writable_symbol(symbol_t *symbol) | 1819 | test_writable_symbol(symbol_t *symbol) |
1817 | { | 1820 | { |
1818 | |||
1819 | if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) { | 1821 | if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) { |
1820 | snprintf(errbuf, sizeof(errbuf), | 1822 | snprintf(errbuf, sizeof(errbuf), |
1821 | "Register %s unavailable in destination reg mode %d", | 1823 | "Register %s unavailable in destination reg mode %d", |
@@ -1831,25 +1833,34 @@ test_writable_symbol(symbol_t *symbol) | |||
1831 | } | 1833 | } |
1832 | 1834 | ||
1833 | static void | 1835 | static void |
1834 | type_check(symbol_t *symbol, expression_t *expression, int opcode) | 1836 | type_check(symbol_ref_t *sym, expression_t *expression, int opcode) |
1835 | { | 1837 | { |
1838 | symbol_t *symbol = sym->symbol; | ||
1836 | symbol_node_t *node; | 1839 | symbol_node_t *node; |
1837 | int and_op; | 1840 | int and_op; |
1841 | int8_t value, mask; | ||
1838 | 1842 | ||
1839 | and_op = FALSE; | 1843 | and_op = FALSE; |
1840 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ) | ||
1841 | and_op = TRUE; | ||
1842 | |||
1843 | /* | 1844 | /* |
1844 | * Make sure that we aren't attempting to write something | 1845 | * Make sure that we aren't attempting to write something |
1845 | * that hasn't been defined. If this is an and operation, | 1846 | * that hasn't been defined. If this is an and operation, |
1846 | * this is a mask, so "undefined" bits are okay. | 1847 | * this is a mask, so "undefined" bits are okay. |
1847 | */ | 1848 | */ |
1848 | if (and_op == FALSE | 1849 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || |
1849 | && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) { | 1850 | opcode == AIC_OP_JZ || opcode == AIC_OP_JNE || |
1851 | opcode == AIC_OP_BMOV) | ||
1852 | and_op = TRUE; | ||
1853 | |||
1854 | /* | ||
1855 | * Defaulting to 8 bit logic | ||
1856 | */ | ||
1857 | mask = (int8_t)~symbol->info.rinfo->valid_bitmask; | ||
1858 | value = (int8_t)expression->value; | ||
1859 | |||
1860 | if (and_op == FALSE && (mask & value) != 0 ) { | ||
1850 | snprintf(errbuf, sizeof(errbuf), | 1861 | snprintf(errbuf, sizeof(errbuf), |
1851 | "Invalid bit(s) 0x%x in immediate written to %s", | 1862 | "Invalid bit(s) 0x%x in immediate written to %s", |
1852 | expression->value & ~symbol->info.rinfo->valid_bitmask, | 1863 | (mask & value), |
1853 | symbol->name); | 1864 | symbol->name); |
1854 | stop(errbuf, EX_DATAERR); | 1865 | stop(errbuf, EX_DATAERR); |
1855 | /* NOTREACHED */ | 1866 | /* NOTREACHED */ |
@@ -1959,3 +1970,13 @@ is_download_const(expression_t *immed) | |||
1959 | 1970 | ||
1960 | return (FALSE); | 1971 | return (FALSE); |
1961 | } | 1972 | } |
1973 | |||
1974 | static int | ||
1975 | is_location_address(symbol_t *sym) | ||
1976 | { | ||
1977 | if (sym->type == SCBLOC || | ||
1978 | sym->type == SRAMLOC) | ||
1979 | return (TRUE); | ||
1980 | return (FALSE); | ||
1981 | } | ||
1982 | |||
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l index 7c3983f868a9..62b6c1bc82c6 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l | |||
@@ -228,15 +228,15 @@ ret { return T_RET; } | |||
228 | nop { return T_NOP; } | 228 | nop { return T_NOP; } |
229 | 229 | ||
230 | /* ARP2 16bit extensions */ | 230 | /* ARP2 16bit extensions */ |
231 | or16 { return T_OR16; } | 231 | /* or16 { return T_OR16; } */ |
232 | and16 { return T_AND16; } | 232 | /* and16 { return T_AND16; }*/ |
233 | xor16 { return T_XOR16; } | 233 | /* xor16 { return T_XOR16; }*/ |
234 | add16 { return T_ADD16; } | 234 | /* add16 { return T_ADD16; }*/ |
235 | adc16 { return T_ADC16; } | 235 | /* adc16 { return T_ADC16; }*/ |
236 | mvi16 { return T_MVI16; } | 236 | /* mvi16 { return T_MVI16; }*/ |
237 | test16 { return T_TEST16; } | 237 | /* test16 { return T_TEST16; }*/ |
238 | cmp16 { return T_CMP16; } | 238 | /* cmp16 { return T_CMP16; }*/ |
239 | cmpxchg { return T_CMPXCHG; } | 239 | /* cmpxchg { return T_CMPXCHG; }*/ |
240 | 240 | ||
241 | /* Allowed Symbols */ | 241 | /* Allowed Symbols */ |
242 | \<\< { return T_EXPR_LSHIFT; } | 242 | \<\< { return T_EXPR_LSHIFT; } |