[BACK]Return to aicasm_gram.y CVS log [TXT][DIR] Up to [local] / sys / dev / microcode / aic7xxx

Annotation of sys/dev/microcode/aic7xxx/aicasm_gram.y, Revision 1.1.1.1

1.1       nbrk        1: %{
                      2: /*     $OpenBSD: aicasm_gram.y,v 1.16 2007/07/07 23:59:36 krw Exp $    */
                      3: /*     $NetBSD: aicasm_gram.y,v 1.3 2003/04/19 19:26:11 fvdl Exp $     */
                      4:
                      5: /*
                      6:  * Parser for the Aic7xxx SCSI Host adapter sequencer assembler.
                      7:  *
                      8:  * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
                      9:  * Copyright (c) 2001, 2002 Adaptec Inc.
                     10:  * All rights reserved.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions, and the following disclaimer,
                     17:  *    without modification.
                     18:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
                     19:  *    substantially similar to the "NO WARRANTY" disclaimer below
                     20:  *    ("Disclaimer") and any redistribution must be conditioned upon
                     21:  *    including a substantially similar Disclaimer requirement for further
                     22:  *    binary redistribution.
                     23:  * 3. Neither the names of the above-listed copyright holders nor the names
                     24:  *    of any contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * Alternatively, this software may be distributed under the terms of the
                     28:  * GNU General Public License ("GPL") version 2 as published by the Free
                     29:  * Software Foundation.
                     30:  *
                     31:  * NO WARRANTY
                     32:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     33:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     34:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
                     35:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     36:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     37:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     38:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     39:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     40:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     41:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     42:  * POSSIBILITY OF SUCH DAMAGES.
                     43:  *
                     44:  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_gram.y,v 1.23 2003/01/20 18:02:11 gibbs Exp $
                     45:  */
                     46:
                     47: #include <sys/types.h>
                     48:
                     49: #include <inttypes.h>
                     50: #include <regex.h>
                     51: #include <stdio.h>
                     52: #include <stdlib.h>
                     53: #include <string.h>
                     54: #include <sysexits.h>
                     55:
                     56: #ifdef __linux__
                     57: #include "../queue.h"
                     58: #else
                     59: #include <sys/queue.h>
                     60: #endif
                     61:
                     62: #include "aicasm.h"
                     63: #include "aicasm_symbol.h"
                     64: #include "aicasm_insformat.h"
                     65:
                     66: int yylineno;
                     67: char *yyfilename;
                     68: char stock_prefix[] = "aic_";
                     69: char *prefix = stock_prefix;
                     70: char *patch_arg_list;
                     71: char *versions;
                     72: static char errbuf[255];
                     73: static char regex_pattern[255];
                     74: static symbol_t *cur_symbol;
                     75: static symbol_t *field_symbol;
                     76: static symbol_t *scb_or_sram_symbol;
                     77: static symtype cur_symtype;
                     78: static symbol_ref_t accumulator;
                     79: static symbol_ref_t mode_ptr;
                     80: static symbol_ref_t allones;
                     81: static symbol_ref_t allzeros;
                     82: static symbol_ref_t none;
                     83: static symbol_ref_t sindex;
                     84: static int instruction_ptr;
                     85: static int num_srams;
                     86: static int sram_or_scb_offset;
                     87: static int download_constant_count;
                     88: static int in_critical_section;
                     89: static u_int enum_increment;
                     90: static u_int enum_next_value;
                     91:
                     92: static void process_field(int field_type, symbol_t *sym, int mask);
                     93: static void initialize_symbol(symbol_t *symbol);
                     94: static void add_macro_arg(const char *argtext, int position);
                     95: static void add_macro_body(const char *bodytext);
                     96: static void process_register(symbol_t **p_symbol);
                     97: static void format_1_instr(int opcode, symbol_ref_t *dest,
                     98:                           expression_t *immed, symbol_ref_t *src, int ret);
                     99: static void format_2_instr(int opcode, symbol_ref_t *dest,
                    100:                           expression_t *places, symbol_ref_t *src, int ret);
                    101: static void format_3_instr(int opcode, symbol_ref_t *src,
                    102:                           expression_t *immed, symbol_ref_t *address);
                    103: static void test_readable_symbol(symbol_t *symbol);
                    104: static void test_writable_symbol(symbol_t *symbol);
                    105: static void type_check(symbol_t *symbol, expression_t *expression, int and_op);
                    106: static void make_expression(expression_t *immed, int value);
                    107: static void add_conditional(symbol_t *symbol);
                    108: static void add_version(const char *verstring);
                    109: static int  is_download_const(expression_t *immed);
                    110:
                    111: #define SRAM_SYMNAME "SRAM_BASE"
                    112: #define SCB_SYMNAME "SCB_BASE"
                    113: %}
                    114:
                    115: %union {
                    116:        u_int           value;
                    117:        char            *str;
                    118:        symbol_t        *sym;
                    119:        symbol_ref_t    sym_ref;
                    120:        expression_t    expression;
                    121: }
                    122:
                    123: %token T_REGISTER
                    124:
                    125: %token <value> T_CONST
                    126:
                    127: %token T_EXPORT
                    128:
                    129: %token T_DOWNLOAD
                    130:
                    131: %token T_SCB
                    132:
                    133: %token T_SRAM
                    134:
                    135: %token T_ALIAS
                    136:
                    137: %token T_SIZE
                    138:
                    139: %token T_EXPR_LSHIFT
                    140:
                    141: %token T_EXPR_RSHIFT
                    142:
                    143: %token <value> T_ADDRESS
                    144:
                    145: %token T_ACCESS_MODE
                    146:
                    147: %token T_MODES
                    148:
                    149: %token T_DEFINE
                    150:
                    151: %token T_SET_SRC_MODE
                    152:
                    153: %token T_SET_DST_MODE
                    154:
                    155: %token <value> T_MODE
                    156:
                    157: %token T_BEGIN_CS
                    158:
                    159: %token T_END_CS
                    160:
                    161: %token T_FIELD
                    162:
                    163: %token T_ENUM
                    164:
                    165: %token T_MASK
                    166:
                    167: %token <value> T_NUMBER
                    168:
                    169: %token <str> T_PATH T_STRING T_ARG T_MACROBODY
                    170:
                    171: %token <sym> T_CEXPR
                    172:
                    173: %token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST
                    174:
                    175: %token <value> T_SHR T_SHL T_ROR T_ROL
                    176:
                    177: %token <value> T_MVI T_MOV T_CLR T_BMOV
                    178:
                    179: %token <value> T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL
                    180:
                    181: %token <value> T_ADD T_ADC
                    182:
                    183: %token <value> T_INC T_DEC
                    184:
                    185: %token <value> T_STC T_CLC
                    186:
                    187: %token <value> T_CMP T_NOT T_XOR
                    188:
                    189: %token <value> T_TEST T_AND
                    190:
                    191: %token <value> T_OR
                    192:
                    193: %token T_RET
                    194:
                    195: %token T_NOP
                    196:
                    197: %token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX T_MODE_PTR
                    198:
                    199: %token T_A
                    200:
                    201: %token <sym> T_SYMBOL
                    202:
                    203: %token T_NL
                    204:
                    205: %token T_IF T_ELSE T_ELSE_IF T_ENDIF
                    206:
                    207: %type <sym_ref> reg_symbol address destination source opt_source
                    208:
                    209: %type <expression> expression immediate immediate_or_a
                    210:
                    211: %type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
                    212:
                    213: %type <value> mode_value mode_list macro_arglist
                    214:
                    215: %left '|'
                    216: %left '&'
                    217: %left T_EXPR_LSHIFT T_EXPR_RSHIFT
                    218: %left '+' '-'
                    219: %left '*' '/'
                    220: %right '~'
                    221: %nonassoc UMINUS
                    222: %%
                    223:
                    224: program:
                    225:        include
                    226: |      program include
                    227: |      prefix
                    228: |      program prefix
                    229: |      patch_arg_list
                    230: |      program patch_arg_list
                    231: |      version
                    232: |      program version
                    233: |      register
                    234: |      program register
                    235: |      constant
                    236: |      program constant
                    237: |      macrodefn
                    238: |      program macrodefn
                    239: |      scratch_ram
                    240: |      program scratch_ram
                    241: |      scb
                    242: |      program scb
                    243: |      label
                    244: |      program label
                    245: |      set_src_mode
                    246: |      program set_src_mode
                    247: |      set_dst_mode
                    248: |      program set_dst_mode
                    249: |      critical_section_start
                    250: |      program critical_section_start
                    251: |      critical_section_end
                    252: |      program critical_section_end
                    253: |      conditional
                    254: |      program conditional
                    255: |      code
                    256: |      program code
                    257: ;
                    258:
                    259: include:
                    260:        T_INCLUDE '<' T_PATH '>'
                    261:        {
                    262:                include_file($3, BRACKETED_INCLUDE);
                    263:        }
                    264: |      T_INCLUDE '"' T_PATH '"'
                    265:        {
                    266:                include_file($3, QUOTED_INCLUDE);
                    267:        }
                    268: ;
                    269:
                    270: prefix:
                    271:        T_PREFIX '=' T_STRING
                    272:        {
                    273:                if (prefix != stock_prefix)
                    274:                        stop("Prefix multiply defined",
                    275:                             EX_DATAERR);
                    276:                prefix = strdup($3);
                    277:                if (prefix == NULL)
                    278:                        stop("Unable to record prefix", EX_SOFTWARE);
                    279:        }
                    280: ;
                    281:
                    282: patch_arg_list:
                    283:        T_PATCH_ARG_LIST '=' T_STRING
                    284:        {
                    285:                if (patch_arg_list != NULL)
                    286:                        stop("Patch argument list multiply defined",
                    287:                             EX_DATAERR);
                    288:                patch_arg_list = strdup($3);
                    289:                if (patch_arg_list == NULL)
                    290:                        stop("Unable to record patch arg list", EX_SOFTWARE);
                    291:        }
                    292: ;
                    293:
                    294: version:
                    295:        T_VERSION '=' T_STRING
                    296:        { add_version($3); }
                    297: ;
                    298:
                    299: register:
                    300:        T_REGISTER { cur_symtype = REGISTER; } reg_definition
                    301: ;
                    302:
                    303: reg_definition:
                    304:        T_SYMBOL '{'
                    305:                {
                    306:                        if ($1->type != UNINITIALIZED) {
                    307:                                stop("Register multiply defined", EX_DATAERR);
                    308:                                /* NOTREACHED */
                    309:                        }
                    310:                        cur_symbol = $1;
                    311:                        cur_symbol->type = cur_symtype;
                    312:                        initialize_symbol(cur_symbol);
                    313:                }
                    314:                reg_attribute_list
                    315:        '}'
                    316:                {
                    317:                        /*
                    318:                         * Default to allowing everything in for registers
                    319:                         * with no bit or mask definitions.
                    320:                         */
                    321:                        if (cur_symbol->info.rinfo->valid_bitmask == 0)
                    322:                                cur_symbol->info.rinfo->valid_bitmask = 0xFF;
                    323:
                    324:                        if (cur_symbol->info.rinfo->size == 0)
                    325:                                cur_symbol->info.rinfo->size = 1;
                    326:
                    327:                        /*
                    328:                         * This might be useful for registers too.
                    329:                         */
                    330:                        if (cur_symbol->type != REGISTER) {
                    331:                                if (cur_symbol->info.rinfo->address == 0)
                    332:                                        cur_symbol->info.rinfo->address =
                    333:                                            sram_or_scb_offset;
                    334:                                sram_or_scb_offset +=
                    335:                                    cur_symbol->info.rinfo->size;
                    336:                        }
                    337:                        cur_symbol = NULL;
                    338:                }
                    339: ;
                    340:
                    341: reg_attribute_list:
                    342:        reg_attribute
                    343: |      reg_attribute_list reg_attribute
                    344: ;
                    345:
                    346: reg_attribute:
                    347:        reg_address
                    348: |      size
                    349: |      access_mode
                    350: |      modes
                    351: |      field_defn
                    352: |      enum_defn
                    353: |      mask_defn
                    354: |      alias
                    355: |      accumulator
                    356: |      mode_pointer
                    357: |      allones
                    358: |      allzeros
                    359: |      none
                    360: |      sindex
                    361: ;
                    362:
                    363: reg_address:
                    364:        T_ADDRESS T_NUMBER
                    365:        {
                    366:                cur_symbol->info.rinfo->address = $2;
                    367:        }
                    368: ;
                    369:
                    370: size:
                    371:        T_SIZE T_NUMBER
                    372:        {
                    373:                cur_symbol->info.rinfo->size = $2;
                    374:                if (scb_or_sram_symbol != NULL) {
                    375:                        u_int max_addr;
                    376:                        u_int sym_max_addr;
                    377:
                    378:                        max_addr = scb_or_sram_symbol->info.rinfo->address
                    379:                                 + scb_or_sram_symbol->info.rinfo->size;
                    380:                        sym_max_addr = cur_symbol->info.rinfo->address
                    381:                                     + cur_symbol->info.rinfo->size;
                    382:
                    383:                        if (sym_max_addr > max_addr)
                    384:                                stop("SCB or SRAM space exhausted", EX_DATAERR);
                    385:                }
                    386:        }
                    387: ;
                    388:
                    389: access_mode:
                    390:        T_ACCESS_MODE T_MODE
                    391:        {
                    392:                cur_symbol->info.rinfo->mode = $2;
                    393:        }
                    394: ;
                    395:
                    396: modes:
                    397:        T_MODES mode_list
                    398:        {
                    399:                cur_symbol->info.rinfo->modes = $2;
                    400:        }
                    401: ;
                    402:
                    403: mode_list:
                    404:        mode_value
                    405:        {
                    406:                $$ = $1;
                    407:        }
                    408: |      mode_list ',' mode_value
                    409:        {
                    410:                $$ = $1 | $3;
                    411:        }
                    412: ;
                    413:
                    414: mode_value:
                    415:        T_NUMBER
                    416:        {
                    417:                if ($1 > 4) {
                    418:                        stop("Valid register modes range between 0 and 4.",
                    419:                             EX_DATAERR);
                    420:                        /* NOTREACHED */
                    421:                }
                    422:
                    423:                $$ = (0x1 << $1);
                    424:        }
                    425: |      T_SYMBOL
                    426:        {
                    427:                symbol_t *symbol;
                    428:
                    429:                symbol = $1;
                    430:                if (symbol->type != CONST) {
                    431:                        stop("Only \"const\" symbols allowed in "
                    432:                             "mode definitions.", EX_DATAERR);
                    433:                        /* NOTREACHED */
                    434:                }
                    435:                if (symbol->info.cinfo->value > 4) {
                    436:                        stop("Valid register modes range between 0 and 4.",
                    437:                             EX_DATAERR);
                    438:                        /* NOTREACHED */
                    439:                }
                    440:                $$ = (0x1 << symbol->info.cinfo->value);
                    441:        }
                    442: ;
                    443:
                    444: field_defn:
                    445:        T_FIELD
                    446:                {
                    447:                        field_symbol = NULL;
                    448:                        enum_next_value = 0;
                    449:                        enum_increment = 1;
                    450:                }
                    451:        '{' enum_entry_list '}'
                    452: |      T_FIELD T_SYMBOL expression
                    453:                {
                    454:                        process_field(FIELD, $2, $3.value);
                    455:                        field_symbol = $2;
                    456:                        enum_next_value = 0;
                    457:                        enum_increment = 0x01 << (ffs($3.value) - 1);
                    458:                }
                    459:        '{' enum_entry_list '}'
                    460: |      T_FIELD T_SYMBOL expression
                    461:        {
                    462:                process_field(FIELD, $2, $3.value);
                    463:        }
                    464: ;
                    465:
                    466: enum_defn:
                    467:        T_ENUM
                    468:                {
                    469:                        field_symbol = NULL;
                    470:                        enum_next_value = 0;
                    471:                        enum_increment = 1;
                    472:                }
                    473:        '{' enum_entry_list '}'
                    474: |      T_ENUM T_SYMBOL expression
                    475:                {
                    476:                        process_field(ENUM, $2, $3.value);
                    477:                        field_symbol = $2;
                    478:                        enum_next_value = 0;
                    479:                        enum_increment = 0x01 << (ffs($3.value) - 1);
                    480:                }
                    481:        '{' enum_entry_list '}'
                    482: ;
                    483:
                    484: enum_entry_list:
                    485:        enum_entry
                    486: |      enum_entry_list ',' enum_entry
                    487: ;
                    488:
                    489: enum_entry:
                    490:        T_SYMBOL
                    491:        {
                    492:                process_field(ENUM_ENTRY, $1, enum_next_value);
                    493:                enum_next_value += enum_increment;
                    494:        }
                    495: |      T_SYMBOL expression
                    496:        {
                    497:                process_field(ENUM_ENTRY, $1, $2.value);
                    498:                enum_next_value = $2.value + enum_increment;
                    499:        }
                    500: ;
                    501:
                    502: mask_defn:
                    503:        T_MASK T_SYMBOL expression
                    504:        {
                    505:                process_field(MASK, $2, $3.value);
                    506:        }
                    507: ;
                    508:
                    509: alias:
                    510:        T_ALIAS T_SYMBOL
                    511:        {
                    512:                if ($2->type != UNINITIALIZED) {
                    513:                        stop("Re-definition of register alias",
                    514:                             EX_DATAERR);
                    515:                        /* NOTREACHED */
                    516:                }
                    517:                $2->type = ALIAS;
                    518:                initialize_symbol($2);
                    519:                $2->info.ainfo->parent = cur_symbol;
                    520:        }
                    521: ;
                    522:
                    523: accumulator:
                    524:        T_ACCUM
                    525:        {
                    526:                if (accumulator.symbol != NULL) {
                    527:                        stop("Only one accumulator definition allowed",
                    528:                             EX_DATAERR);
                    529:                        /* NOTREACHED */
                    530:                }
                    531:                accumulator.symbol = cur_symbol;
                    532:        }
                    533: ;
                    534:
                    535: mode_pointer:
                    536:        T_MODE_PTR
                    537:        {
                    538:                if (mode_ptr.symbol != NULL) {
                    539:                        stop("Only one mode pointer definition allowed",
                    540:                             EX_DATAERR);
                    541:                        /* NOTREACHED */
                    542:                }
                    543:                mode_ptr.symbol = cur_symbol;
                    544:        }
                    545: ;
                    546:
                    547: allones:
                    548:        T_ALLONES
                    549:        {
                    550:                if (allones.symbol != NULL) {
                    551:                        stop("Only one definition of allones allowed",
                    552:                             EX_DATAERR);
                    553:                        /* NOTREACHED */
                    554:                }
                    555:                allones.symbol = cur_symbol;
                    556:        }
                    557: ;
                    558:
                    559: allzeros:
                    560:        T_ALLZEROS
                    561:        {
                    562:                if (allzeros.symbol != NULL) {
                    563:                        stop("Only one definition of allzeros allowed",
                    564:                             EX_DATAERR);
                    565:                        /* NOTREACHED */
                    566:                }
                    567:                allzeros.symbol = cur_symbol;
                    568:        }
                    569: ;
                    570:
                    571: none:
                    572:        T_NONE
                    573:        {
                    574:                if (none.symbol != NULL) {
                    575:                        stop("Only one definition of none allowed",
                    576:                             EX_DATAERR);
                    577:                        /* NOTREACHED */
                    578:                }
                    579:                none.symbol = cur_symbol;
                    580:        }
                    581: ;
                    582:
                    583: sindex:
                    584:        T_SINDEX
                    585:        {
                    586:                if (sindex.symbol != NULL) {
                    587:                        stop("Only one definition of sindex allowed",
                    588:                             EX_DATAERR);
                    589:                        /* NOTREACHED */
                    590:                }
                    591:                sindex.symbol = cur_symbol;
                    592:        }
                    593: ;
                    594:
                    595: expression:
                    596:        expression '|' expression
                    597:        {
                    598:                 $$.value = $1.value | $3.value;
                    599:                 symlist_merge(&$$.referenced_syms,
                    600:                               &$1.referenced_syms,
                    601:                               &$3.referenced_syms);
                    602:        }
                    603: |      expression '&' expression
                    604:        {
                    605:                $$.value = $1.value & $3.value;
                    606:                symlist_merge(&$$.referenced_syms,
                    607:                               &$1.referenced_syms,
                    608:                               &$3.referenced_syms);
                    609:        }
                    610: |      expression '+' expression
                    611:        {
                    612:                $$.value = $1.value + $3.value;
                    613:                symlist_merge(&$$.referenced_syms,
                    614:                               &$1.referenced_syms,
                    615:                               &$3.referenced_syms);
                    616:        }
                    617: |      expression '-' expression
                    618:        {
                    619:                $$.value = $1.value - $3.value;
                    620:                symlist_merge(&($$.referenced_syms),
                    621:                               &($1.referenced_syms),
                    622:                               &($3.referenced_syms));
                    623:        }
                    624: |      expression '*' expression
                    625:        {
                    626:                $$.value = $1.value * $3.value;
                    627:                symlist_merge(&($$.referenced_syms),
                    628:                               &($1.referenced_syms),
                    629:                               &($3.referenced_syms));
                    630:        }
                    631: |      expression '/' expression
                    632:        {
                    633:                $$.value = $1.value / $3.value;
                    634:                symlist_merge(&($$.referenced_syms),
                    635:                               &($1.referenced_syms),
                    636:                               &($3.referenced_syms));
                    637:        }
                    638: |      expression T_EXPR_LSHIFT expression
                    639:        {
                    640:                $$.value = $1.value << $3.value;
                    641:                symlist_merge(&$$.referenced_syms,
                    642:                               &$1.referenced_syms,
                    643:                               &$3.referenced_syms);
                    644:        }
                    645: |      expression T_EXPR_RSHIFT expression
                    646:        {
                    647:                $$.value = $1.value >> $3.value;
                    648:                symlist_merge(&$$.referenced_syms,
                    649:                               &$1.referenced_syms,
                    650:                               &$3.referenced_syms);
                    651:        }
                    652: |      '(' expression ')'
                    653:        {
                    654:                $$ = $2;
                    655:        }
                    656: |      '~' expression
                    657:        {
                    658:                $$ = $2;
                    659:                $$.value = (~$$.value) & 0xFF;
                    660:        }
                    661: |      '-' expression %prec UMINUS
                    662:        {
                    663:                $$ = $2;
                    664:                $$.value = -$$.value;
                    665:        }
                    666: |      T_NUMBER
                    667:        {
                    668:                $$.value = $1;
                    669:                SLIST_INIT(&$$.referenced_syms);
                    670:        }
                    671: |      T_SYMBOL
                    672:        {
                    673:                symbol_t *symbol;
                    674:
                    675:                symbol = $1;
                    676:                switch (symbol->type) {
                    677:                case ALIAS:
                    678:                        symbol = $1->info.ainfo->parent;
                    679:                case REGISTER:
                    680:                case SCBLOC:
                    681:                case SRAMLOC:
                    682:                        $$.value = symbol->info.rinfo->address;
                    683:                        break;
                    684:                case MASK:
                    685:                case FIELD:
                    686:                case ENUM:
                    687:                case ENUM_ENTRY:
                    688:                        $$.value = symbol->info.finfo->value;
                    689:                        break;
                    690:                case DOWNLOAD_CONST:
                    691:                case CONST:
                    692:                        $$.value = symbol->info.cinfo->value;
                    693:                        break;
                    694:                case UNINITIALIZED:
                    695:                default:
                    696:                {
                    697:                        snprintf(errbuf, sizeof(errbuf),
                    698:                                 "Undefined symbol %s referenced",
                    699:                                 symbol->name);
                    700:                        stop(errbuf, EX_DATAERR);
                    701:                        /* NOTREACHED */
                    702:                        break;
                    703:                }
                    704:                }
                    705:                SLIST_INIT(&$$.referenced_syms);
                    706:                symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD);
                    707:        }
                    708: ;
                    709:
                    710: constant:
                    711:        T_CONST T_SYMBOL expression
                    712:        {
                    713:                if ($2->type != UNINITIALIZED) {
                    714:                        stop("Re-definition of symbol as a constant",
                    715:                             EX_DATAERR);
                    716:                        /* NOTREACHED */
                    717:                }
                    718:                $2->type = CONST;
                    719:                initialize_symbol($2);
                    720:                $2->info.cinfo->value = $3.value;
                    721:        }
                    722: |      T_CONST T_SYMBOL T_DOWNLOAD
                    723:        {
                    724:                if ($1) {
                    725:                        stop("Invalid downloaded constant declaration",
                    726:                             EX_DATAERR);
                    727:                        /* NOTREACHED */
                    728:                }
                    729:                if ($2->type != UNINITIALIZED) {
                    730:                        stop("Re-definition of symbol as a downloaded constant",
                    731:                             EX_DATAERR);
                    732:                        /* NOTREACHED */
                    733:                }
                    734:                $2->type = DOWNLOAD_CONST;
                    735:                initialize_symbol($2);
                    736:                $2->info.cinfo->value = download_constant_count++;
                    737:        }
                    738: ;
                    739:
                    740: macrodefn_prologue:
                    741:        T_DEFINE T_SYMBOL
                    742:        {
                    743:                if ($2->type != UNINITIALIZED) {
                    744:                        stop("Re-definition of symbol as a macro",
                    745:                             EX_DATAERR);
                    746:                        /* NOTREACHED */
                    747:                }
                    748:                cur_symbol = $2;
                    749:                cur_symbol->type = MACRO;
                    750:                initialize_symbol(cur_symbol);
                    751:        }
                    752: ;
                    753:
                    754: macrodefn:
                    755:        macrodefn_prologue T_MACROBODY
                    756:        {
                    757:                add_macro_body($2);
                    758:        }
                    759: |      macrodefn_prologue '(' macro_arglist ')' T_MACROBODY
                    760:        {
                    761:                add_macro_body($5);
                    762:                cur_symbol->info.macroinfo->narg = $3;
                    763:        }
                    764: ;
                    765:
                    766: macro_arglist:
                    767:        {
                    768:                /* Macros can take no arguments */
                    769:                $$ = 0;
                    770:        }
                    771: |      T_ARG
                    772:        {
                    773:                $$ = 1;
                    774:                add_macro_arg($1, 0);
                    775:        }
                    776: |      macro_arglist ',' T_ARG
                    777:        {
                    778:                if ($1 == 0) {
                    779:                        stop("Comma without preceding argument in arg list",
                    780:                             EX_DATAERR);
                    781:                        /* NOTREACHED */
                    782:                }
                    783:                $$ = $1 + 1;
                    784:                add_macro_arg($3, $1);
                    785:        }
                    786: ;
                    787:
                    788: scratch_ram:
                    789:        T_SRAM '{'
                    790:                {
                    791:                        snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME,
                    792:                                 num_srams);
                    793:                        cur_symbol = symtable_get(SRAM_SYMNAME);
                    794:                        cur_symtype = SRAMLOC;
                    795:                        cur_symbol->type = SRAMLOC;
                    796:                        initialize_symbol(cur_symbol);
                    797:                }
                    798:                reg_address
                    799:                {
                    800:                        sram_or_scb_offset = cur_symbol->info.rinfo->address;
                    801:                }
                    802:                size
                    803:                {
                    804:                        scb_or_sram_symbol = cur_symbol;
                    805:                }
                    806:                scb_or_sram_attributes
                    807:        '}'
                    808:                {
                    809:                        cur_symbol = NULL;
                    810:                        scb_or_sram_symbol = NULL;
                    811:                }
                    812: ;
                    813:
                    814: scb:
                    815:        T_SCB '{'
                    816:                {
                    817:                        cur_symbol = symtable_get(SCB_SYMNAME);
                    818:                        cur_symtype = SCBLOC;
                    819:                        if (cur_symbol->type != UNINITIALIZED) {
                    820:                                stop("Only one SRAM definition allowed",
                    821:                                     EX_SOFTWARE);
                    822:                                /* NOTREACHED */
                    823:                        }
                    824:                        cur_symbol->type = SCBLOC;
                    825:                        initialize_symbol(cur_symbol);
                    826:                        /* 64 bytes of SCB space */
                    827:                        cur_symbol->info.rinfo->size = 64;
                    828:                }
                    829:                reg_address
                    830:                {
                    831:                        sram_or_scb_offset = cur_symbol->info.rinfo->address;
                    832:                }
                    833:                size
                    834:                {
                    835:                        scb_or_sram_symbol = cur_symbol;
                    836:                }
                    837:                scb_or_sram_attributes
                    838:        '}'
                    839:                {
                    840:                        cur_symbol = NULL;
                    841:                        scb_or_sram_symbol = NULL;
                    842:                }
                    843: ;
                    844:
                    845: scb_or_sram_attributes:
                    846:        /* NULL definition is okay */
                    847: |      modes
                    848: |      scb_or_sram_reg_list
                    849: |      modes scb_or_sram_reg_list
                    850: ;
                    851:
                    852: scb_or_sram_reg_list:
                    853:        reg_definition
                    854: |      scb_or_sram_reg_list reg_definition
                    855: ;
                    856:
                    857: reg_symbol:
                    858:        T_SYMBOL
                    859:        {
                    860:                process_register(&$1);
                    861:                $$.symbol = $1;
                    862:                $$.offset = 0;
                    863:        }
                    864: |      T_SYMBOL '[' T_SYMBOL ']'
                    865:        {
                    866:                process_register(&$1);
                    867:                if ($3->type != CONST) {
                    868:                        stop("register offset must be a constant", EX_DATAERR);
                    869:                        /* NOTREACHED */
                    870:                }
                    871:                if (($3->info.cinfo->value + 1) > $1->info.rinfo->size) {
                    872:                        stop("Accessing offset beyond range of register",
                    873:                             EX_DATAERR);
                    874:                        /* NOTREACHED */
                    875:                }
                    876:                $$.symbol = $1;
                    877:                $$.offset = $3->info.cinfo->value;
                    878:        }
                    879: |      T_SYMBOL '[' T_NUMBER ']'
                    880:        {
                    881:                process_register(&$1);
                    882:                if (($3 + 1) > $1->info.rinfo->size) {
                    883:                        stop("Accessing offset beyond range of register",
                    884:                             EX_DATAERR);
                    885:                        /* NOTREACHED */
                    886:                }
                    887:                $$.symbol = $1;
                    888:                $$.offset = $3;
                    889:        }
                    890: |      T_A
                    891:        {
                    892:                if (accumulator.symbol == NULL) {
                    893:                        stop("No accumulator has been defined", EX_DATAERR);
                    894:                        /* NOTREACHED */
                    895:                }
                    896:                $$.symbol = accumulator.symbol;
                    897:                $$.offset = 0;
                    898:        }
                    899: ;
                    900:
                    901: destination:
                    902:        reg_symbol
                    903:        {
                    904:                test_writable_symbol($1.symbol);
                    905:                $$ = $1;
                    906:        }
                    907: ;
                    908:
                    909: immediate:
                    910:        expression
                    911:        { $$ = $1; }
                    912: ;
                    913:
                    914: immediate_or_a:
                    915:        expression
                    916:        {
                    917:                if ($1.value == 0 && is_download_const(&$1) == 0) {
                    918:                        snprintf(errbuf, sizeof(errbuf),
                    919:                                 "\nExpression evaluates to 0 and thus "
                    920:                                 "references the accumulator.\n "
                    921:                                 "If this is the desired effect, use 'A' "
                    922:                                 "instead.\n");
                    923:                        stop(errbuf, EX_DATAERR);
                    924:                }
                    925:                $$ = $1;
                    926:        }
                    927: |      T_A
                    928:        {
                    929:                SLIST_INIT(&$$.referenced_syms);
                    930:                symlist_add(&$$.referenced_syms, accumulator.symbol,
                    931:                            SYMLIST_INSERT_HEAD);
                    932:                $$.value = 0;
                    933:        }
                    934: ;
                    935:
                    936: source:
                    937:        reg_symbol
                    938:        {
                    939:                test_readable_symbol($1.symbol);
                    940:                $$ = $1;
                    941:        }
                    942: ;
                    943:
                    944: opt_source:
                    945:        {
                    946:                $$.symbol = NULL;
                    947:                $$.offset = 0;
                    948:        }
                    949: |      ',' source
                    950:        { $$ = $2; }
                    951: ;
                    952:
                    953: ret:
                    954:        { $$ = 0; }
                    955: |      T_RET
                    956:        { $$ = 1; }
                    957: ;
                    958:
                    959: set_src_mode:
                    960:        T_SET_SRC_MODE T_NUMBER ';'
                    961:        {
                    962:                src_mode = $2;
                    963:        }
                    964: ;
                    965:
                    966: set_dst_mode:
                    967:        T_SET_DST_MODE T_NUMBER ';'
                    968:        {
                    969:                dst_mode = $2;
                    970:        }
                    971: ;
                    972:
                    973: critical_section_start:
                    974:        T_BEGIN_CS ';'
                    975:        {
                    976:                critical_section_t *cs;
                    977:
                    978:                if (in_critical_section != FALSE) {
                    979:                        stop("Critical Section within Critical Section",
                    980:                             EX_DATAERR);
                    981:                        /* NOTREACHED */
                    982:                }
                    983:                cs = cs_alloc();
                    984:                cs->begin_addr = instruction_ptr;
                    985:                in_critical_section = TRUE;
                    986:        }
                    987: ;
                    988:
                    989: critical_section_end:
                    990:        T_END_CS ';'
                    991:        {
                    992:                critical_section_t *cs;
                    993:
                    994:                if (in_critical_section == FALSE) {
                    995:                        stop("Unballanced 'end_cs'", EX_DATAERR);
                    996:                        /* NOTREACHED */
                    997:                }
                    998:                cs = TAILQ_LAST(&cs_tailq, cs_tailq);
                    999:                cs->end_addr = instruction_ptr;
                   1000:                in_critical_section = FALSE;
                   1001:        }
                   1002: ;
                   1003:
                   1004: export:
                   1005:        { $$ = 0; }
                   1006: |      T_EXPORT
                   1007:        { $$ = 1; }
                   1008: ;
                   1009:
                   1010: label:
                   1011:        export T_SYMBOL ':'
                   1012:        {
                   1013:                if ($2->type != UNINITIALIZED) {
                   1014:                        stop("Program label multiply defined", EX_DATAERR);
                   1015:                        /* NOTREACHED */
                   1016:                }
                   1017:                $2->type = LABEL;
                   1018:                initialize_symbol($2);
                   1019:                $2->info.linfo->address = instruction_ptr;
                   1020:                $2->info.linfo->exported = $1;
                   1021:        }
                   1022: ;
                   1023:
                   1024: address:
                   1025:        T_SYMBOL
                   1026:        {
                   1027:                $$.symbol = $1;
                   1028:                $$.offset = 0;
                   1029:        }
                   1030: |      T_SYMBOL '+' T_NUMBER
                   1031:        {
                   1032:                $$.symbol = $1;
                   1033:                $$.offset = $3;
                   1034:        }
                   1035: |      T_SYMBOL '-' T_NUMBER
                   1036:        {
                   1037:                $$.symbol = $1;
                   1038:                $$.offset = -$3;
                   1039:        }
                   1040: |      '.'
                   1041:        {
                   1042:                $$.symbol = NULL;
                   1043:                $$.offset = 0;
                   1044:        }
                   1045: |      '.' '+' T_NUMBER
                   1046:        {
                   1047:                $$.symbol = NULL;
                   1048:                $$.offset = $3;
                   1049:        }
                   1050: |      '.' '-' T_NUMBER
                   1051:        {
                   1052:                $$.symbol = NULL;
                   1053:                $$.offset = -$3;
                   1054:        }
                   1055: ;
                   1056:
                   1057: conditional:
                   1058:        T_IF T_CEXPR '{'
                   1059:        {
                   1060:                scope_t *new_scope;
                   1061:
                   1062:                add_conditional($2);
                   1063:                new_scope = scope_alloc();
                   1064:                new_scope->type = SCOPE_IF;
                   1065:                new_scope->begin_addr = instruction_ptr;
                   1066:                new_scope->func_num = $2->info.condinfo->func_num;
                   1067:        }
                   1068: |      T_ELSE T_IF T_CEXPR '{'
                   1069:        {
                   1070:                scope_t *new_scope;
                   1071:                scope_t *scope_context;
                   1072:                scope_t *last_scope;
                   1073:
                   1074:                /*
                   1075:                 * Ensure that the previous scope is either an
                   1076:                 * if or and else if.
                   1077:                 */
                   1078:                scope_context = SLIST_FIRST(&scope_stack);
                   1079:                last_scope = TAILQ_LAST(&scope_context->inner_scope,
                   1080:                                        scope_tailq);
                   1081:                if (last_scope == NULL
                   1082:                 || last_scope->type == T_ELSE) {
                   1083:
                   1084:                        stop("'else if' without leading 'if'", EX_DATAERR);
                   1085:                        /* NOTREACHED */
                   1086:                }
                   1087:                add_conditional($3);
                   1088:                new_scope = scope_alloc();
                   1089:                new_scope->type = SCOPE_ELSE_IF;
                   1090:                new_scope->begin_addr = instruction_ptr;
                   1091:                new_scope->func_num = $3->info.condinfo->func_num;
                   1092:        }
                   1093: |      T_ELSE '{'
                   1094:        {
                   1095:                scope_t *new_scope;
                   1096:                scope_t *scope_context;
                   1097:                scope_t *last_scope;
                   1098:
                   1099:                /*
                   1100:                 * Ensure that the previous scope is either an
                   1101:                 * if or and else if.
                   1102:                 */
                   1103:                scope_context = SLIST_FIRST(&scope_stack);
                   1104:                last_scope = TAILQ_LAST(&scope_context->inner_scope,
                   1105:                                        scope_tailq);
                   1106:                if (last_scope == NULL
                   1107:                 || last_scope->type == SCOPE_ELSE) {
                   1108:
                   1109:                        stop("'else' without leading 'if'", EX_DATAERR);
                   1110:                        /* NOTREACHED */
                   1111:                }
                   1112:                new_scope = scope_alloc();
                   1113:                new_scope->type = SCOPE_ELSE;
                   1114:                new_scope->begin_addr = instruction_ptr;
                   1115:        }
                   1116: ;
                   1117:
                   1118: conditional:
                   1119:        '}'
                   1120:        {
                   1121:                scope_t *scope_context;
                   1122:
                   1123:                scope_context = SLIST_FIRST(&scope_stack);
                   1124:                if (scope_context->type == SCOPE_ROOT) {
                   1125:                        stop("Unexpected '}' encountered", EX_DATAERR);
                   1126:                        /* NOTREACHED */
                   1127:                }
                   1128:
                   1129:                scope_context->end_addr = instruction_ptr;
                   1130:
                   1131:                /* Pop the scope */
                   1132:                SLIST_REMOVE_HEAD(&scope_stack, scope_stack_links);
                   1133:
                   1134:                process_scope(scope_context);
                   1135:
                   1136:                if (SLIST_FIRST(&scope_stack) == NULL) {
                   1137:                        stop("Unexpected '}' encountered", EX_DATAERR);
                   1138:                        /* NOTREACHED */
                   1139:                }
                   1140:        }
                   1141: ;
                   1142:
                   1143: f1_opcode:
                   1144:        T_AND { $$ = AIC_OP_AND; }
                   1145: |      T_XOR { $$ = AIC_OP_XOR; }
                   1146: |      T_ADD { $$ = AIC_OP_ADD; }
                   1147: |      T_ADC { $$ = AIC_OP_ADC; }
                   1148: ;
                   1149:
                   1150: code:
                   1151:        f1_opcode destination ',' immediate_or_a opt_source ret ';'
                   1152:        {
                   1153:                format_1_instr($1, &$2, &$4, &$5, $6);
                   1154:        }
                   1155: ;
                   1156:
                   1157: code:
                   1158:        T_OR reg_symbol ',' immediate_or_a opt_source ret ';'
                   1159:        {
                   1160:                format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6);
                   1161:        }
                   1162: ;
                   1163:
                   1164: code:
                   1165:        T_INC destination opt_source ret ';'
                   1166:        {
                   1167:                expression_t immed;
                   1168:
                   1169:                make_expression(&immed, 1);
                   1170:                format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
                   1171:        }
                   1172: ;
                   1173:
                   1174: code:
                   1175:        T_DEC destination opt_source ret ';'
                   1176:        {
                   1177:                expression_t immed;
                   1178:
                   1179:                make_expression(&immed, -1);
                   1180:                format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
                   1181:        }
                   1182: ;
                   1183:
                   1184: code:
                   1185:        T_CLC ret ';'
                   1186:        {
                   1187:                expression_t immed;
                   1188:
                   1189:                make_expression(&immed, -1);
                   1190:                format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2);
                   1191:        }
                   1192: |      T_CLC T_MVI destination ',' immediate_or_a ret ';'
                   1193:        {
                   1194:                format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6);
                   1195:        }
                   1196: ;
                   1197:
                   1198: code:
                   1199:        T_STC ret ';'
                   1200:        {
                   1201:                expression_t immed;
                   1202:
                   1203:                make_expression(&immed, 1);
                   1204:                format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2);
                   1205:        }
                   1206: |      T_STC destination ret ';'
                   1207:        {
                   1208:                expression_t immed;
                   1209:
                   1210:                make_expression(&immed, 1);
                   1211:                format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3);
                   1212:        }
                   1213: ;
                   1214:
                   1215: code:
                   1216:        T_BMOV destination ',' source ',' immediate ret ';'
                   1217:        {
                   1218:                format_1_instr(AIC_OP_BMOV, &$2, &$6, &$4, $7);
                   1219:        }
                   1220: ;
                   1221:
                   1222: code:
                   1223:        T_MOV destination ',' source ret ';'
                   1224:        {
                   1225:                expression_t immed;
                   1226:
                   1227:                make_expression(&immed, 1);
                   1228:                format_1_instr(AIC_OP_BMOV, &$2, &immed, &$4, $5);
                   1229:        }
                   1230: ;
                   1231:
                   1232: code:
                   1233:        T_MVI destination ',' immediate ret ';'
                   1234:        {
                   1235:                if ($4.value == 0
                   1236:                 && is_download_const(&$4) == 0) {
                   1237:                        expression_t immed;
                   1238:
                   1239:                        /*
                   1240:                         * Allow move immediates of 0 so that macros,
                   1241:                         * that can't know the immediate's value and
                   1242:                         * otherwise compensate, still work.
                   1243:                         */
                   1244:                        make_expression(&immed, 1);
                   1245:                        format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5);
                   1246:                } else {
                   1247:                        format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
                   1248:                }
                   1249:        }
                   1250: ;
                   1251:
                   1252: code:
                   1253:        T_NOT destination opt_source ret ';'
                   1254:        {
                   1255:                expression_t immed;
                   1256:
                   1257:                make_expression(&immed, 0xff);
                   1258:                format_1_instr(AIC_OP_XOR, &$2, &immed, &$3, $4);
                   1259:        }
                   1260: ;
                   1261:
                   1262: code:
                   1263:        T_CLR destination ret ';'
                   1264:        {
                   1265:                expression_t immed;
                   1266:
                   1267:                make_expression(&immed, 0xff);
                   1268:                format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3);
                   1269:        }
                   1270: ;
                   1271:
                   1272: code:
                   1273:        T_NOP ret ';'
                   1274:        {
                   1275:                expression_t immed;
                   1276:
                   1277:                make_expression(&immed, 0xff);
                   1278:                format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, $2);
                   1279:        }
                   1280: ;
                   1281:
                   1282: code:
                   1283:        T_RET ';'
                   1284:        {
                   1285:                expression_t immed;
                   1286:
                   1287:                make_expression(&immed, 0xff);
                   1288:                format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE);
                   1289:        }
                   1290: ;
                   1291:
                   1292:        /*
                   1293:         * This grammer differs from the one in the aic7xxx
                   1294:         * reference manual since the grammer listed there is
                   1295:         * ambiguous and causes a shift/reduce conflict.
                   1296:         * It also seems more logical as the "immediate"
                   1297:         * argument is listed as the second arg like the
                   1298:         * other formats.
                   1299:         */
                   1300:
                   1301: f2_opcode:
                   1302:        T_SHL { $$ = AIC_OP_SHL; }
                   1303: |      T_SHR { $$ = AIC_OP_SHR; }
                   1304: |      T_ROL { $$ = AIC_OP_ROL; }
                   1305: |      T_ROR { $$ = AIC_OP_ROR; }
                   1306: ;
                   1307:
                   1308: code:
                   1309:        f2_opcode destination ',' expression opt_source ret ';'
                   1310:        {
                   1311:                format_2_instr($1, &$2, &$4, &$5, $6);
                   1312:        }
                   1313: ;
                   1314:
                   1315: jmp_jc_jnc_call:
                   1316:        T_JMP   { $$ = AIC_OP_JMP; }
                   1317: |      T_JC    { $$ = AIC_OP_JC; }
                   1318: |      T_JNC   { $$ = AIC_OP_JNC; }
                   1319: |      T_CALL  { $$ = AIC_OP_CALL; }
                   1320: ;
                   1321:
                   1322: jz_jnz:
                   1323:        T_JZ    { $$ = AIC_OP_JZ; }
                   1324: |      T_JNZ   { $$ = AIC_OP_JNZ; }
                   1325: ;
                   1326:
                   1327: je_jne:
                   1328:        T_JE    { $$ = AIC_OP_JE; }
                   1329: |      T_JNE   { $$ = AIC_OP_JNE; }
                   1330: ;
                   1331:
                   1332: code:
                   1333:        jmp_jc_jnc_call address ';'
                   1334:        {
                   1335:                expression_t immed;
                   1336:
                   1337:                make_expression(&immed, 0);
                   1338:                format_3_instr($1, &sindex, &immed, &$2);
                   1339:        }
                   1340: ;
                   1341:
                   1342: code:
                   1343:        T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';'
                   1344:        {
                   1345:                format_3_instr($5, &$2, &$4, &$6);
                   1346:        }
                   1347: ;
                   1348:
                   1349: code:
                   1350:        T_TEST source ',' immediate_or_a jz_jnz address ';'
                   1351:        {
                   1352:                format_3_instr($5, &$2, &$4, &$6);
                   1353:        }
                   1354: ;
                   1355:
                   1356: code:
                   1357:        T_CMP source ',' immediate_or_a je_jne address ';'
                   1358:        {
                   1359:                format_3_instr($5, &$2, &$4, &$6);
                   1360:        }
                   1361: ;
                   1362:
                   1363: code:
                   1364:        T_MOV source jmp_jc_jnc_call address ';'
                   1365:        {
                   1366:                expression_t immed;
                   1367:
                   1368:                make_expression(&immed, 0);
                   1369:                format_3_instr($3, &$2, &immed, &$4);
                   1370:        }
                   1371: ;
                   1372:
                   1373: code:
                   1374:        T_MVI immediate jmp_jc_jnc_call address ';'
                   1375:        {
                   1376:                format_3_instr($3, &allzeros, &$2, &$4);
                   1377:        }
                   1378: ;
                   1379:
                   1380: %%
                   1381:
                   1382: static void
                   1383: process_field(int field_type, symbol_t *sym, int value)
                   1384: {
                   1385:        /*
                   1386:         * Add the current register to its
                   1387:         * symbol list, if it already exists,
                   1388:         * warn if we are setting it to a
                   1389:         * different value, or in the bit to
                   1390:         * the "allowed bits" of this register.
                   1391:         */
                   1392:        if (sym->type == UNINITIALIZED) {
                   1393:                sym->type = field_type;
                   1394:                initialize_symbol(sym);
                   1395:                sym->info.finfo->value = value;
                   1396:                if (field_type != ENUM_ENTRY) {
                   1397:                        if (field_type != MASK && value == 0) {
                   1398:                                stop("Empty Field, or Enum", EX_DATAERR);
                   1399:                                /* NOTREACHED */
                   1400:                        }
                   1401:                        sym->info.finfo->value = value;
                   1402:                        sym->info.finfo->mask = value;
                   1403:                } else if (field_symbol != NULL) {
                   1404:                        sym->info.finfo->mask = field_symbol->info.finfo->value;
                   1405:                } else {
                   1406:                        sym->info.finfo->mask = 0xFF;
                   1407:                }
                   1408:        } else if (sym->type != field_type) {
                   1409:                stop("Field definition mirrors a definition of the same "
                   1410:                     " name, but a different type", EX_DATAERR);
                   1411:                /* NOTREACHED */
                   1412:        } else if (value != sym->info.finfo->value) {
                   1413:                stop("Field redefined with a conflicting value", EX_DATAERR);
                   1414:                /* NOTREACHED */
                   1415:        }
                   1416:        /* Fail if this symbol is already listed */
                   1417:        if (symlist_search(&(sym->info.finfo->symrefs),
                   1418:                           cur_symbol->name) != NULL) {
                   1419:                stop("Field defined multiple times for register", EX_DATAERR);
                   1420:                /* NOTREACHED */
                   1421:        }
                   1422:        symlist_add(&(sym->info.finfo->symrefs), cur_symbol,
                   1423:                    SYMLIST_INSERT_HEAD);
                   1424:        cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask;
                   1425:        cur_symbol->info.rinfo->typecheck_masks = TRUE;
                   1426:        symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT);
                   1427: }
                   1428:
                   1429: static void
                   1430: initialize_symbol(symbol_t *symbol)
                   1431: {
                   1432:        switch (symbol->type) {
                   1433:        case UNINITIALIZED:
                   1434:                stop("Call to initialize_symbol with type field unset",
                   1435:                     EX_SOFTWARE);
                   1436:                /* NOTREACHED */
                   1437:                break;
                   1438:        case REGISTER:
                   1439:        case SRAMLOC:
                   1440:        case SCBLOC:
                   1441:                symbol->info.rinfo =
                   1442:                    (struct reg_info *)malloc(sizeof(struct reg_info));
                   1443:                if (symbol->info.rinfo == NULL) {
                   1444:                        stop("Can't create register info", EX_SOFTWARE);
                   1445:                        /* NOTREACHED */
                   1446:                }
                   1447:                memset(symbol->info.rinfo, 0,
                   1448:                       sizeof(struct reg_info));
                   1449:                SLIST_INIT(&(symbol->info.rinfo->fields));
                   1450:                /*
                   1451:                 * Default to allowing access in all register modes
                   1452:                 * or to the mode specified by the SCB or SRAM space
                   1453:                 * we are in.
                   1454:                 */
                   1455:                if (scb_or_sram_symbol != NULL)
                   1456:                        symbol->info.rinfo->modes =
                   1457:                            scb_or_sram_symbol->info.rinfo->modes;
                   1458:                else
                   1459:                        symbol->info.rinfo->modes = ~0;
                   1460:                break;
                   1461:        case ALIAS:
                   1462:                symbol->info.ainfo =
                   1463:                    (struct alias_info *)malloc(sizeof(struct alias_info));
                   1464:                if (symbol->info.ainfo == NULL) {
                   1465:                        stop("Can't create alias info", EX_SOFTWARE);
                   1466:                        /* NOTREACHED */
                   1467:                }
                   1468:                memset(symbol->info.ainfo, 0,
                   1469:                       sizeof(struct alias_info));
                   1470:                break;
                   1471:        case MASK:
                   1472:        case FIELD:
                   1473:        case ENUM:
                   1474:        case ENUM_ENTRY:
                   1475:                symbol->info.finfo =
                   1476:                    (struct field_info *)malloc(sizeof(struct field_info));
                   1477:                if (symbol->info.finfo == NULL) {
                   1478:                        stop("Can't create field info", EX_SOFTWARE);
                   1479:                        /* NOTREACHED */
                   1480:                }
                   1481:                memset(symbol->info.finfo, 0, sizeof(struct field_info));
                   1482:                SLIST_INIT(&(symbol->info.finfo->symrefs));
                   1483:                break;
                   1484:        case CONST:
                   1485:        case DOWNLOAD_CONST:
                   1486:                symbol->info.cinfo =
                   1487:                    (struct const_info *)malloc(sizeof(struct const_info));
                   1488:                if (symbol->info.cinfo == NULL) {
                   1489:                        stop("Can't create alias info", EX_SOFTWARE);
                   1490:                        /* NOTREACHED */
                   1491:                }
                   1492:                memset(symbol->info.cinfo, 0,
                   1493:                       sizeof(struct const_info));
                   1494:                break;
                   1495:        case LABEL:
                   1496:                symbol->info.linfo =
                   1497:                    (struct label_info *)malloc(sizeof(struct label_info));
                   1498:                if (symbol->info.linfo == NULL) {
                   1499:                        stop("Can't create label info", EX_SOFTWARE);
                   1500:                        /* NOTREACHED */
                   1501:                }
                   1502:                memset(symbol->info.linfo, 0,
                   1503:                       sizeof(struct label_info));
                   1504:                break;
                   1505:        case CONDITIONAL:
                   1506:                symbol->info.condinfo =
                   1507:                    (struct cond_info *)malloc(sizeof(struct cond_info));
                   1508:                if (symbol->info.condinfo == NULL) {
                   1509:                        stop("Can't create conditional info", EX_SOFTWARE);
                   1510:                        /* NOTREACHED */
                   1511:                }
                   1512:                memset(symbol->info.condinfo, 0,
                   1513:                       sizeof(struct cond_info));
                   1514:                break;
                   1515:        case MACRO:
                   1516:                symbol->info.macroinfo =
                   1517:                    (struct macro_info *)malloc(sizeof(struct macro_info));
                   1518:                if (symbol->info.macroinfo == NULL) {
                   1519:                        stop("Can't create macro info", EX_SOFTWARE);
                   1520:                        /* NOTREACHED */
                   1521:                }
                   1522:                memset(symbol->info.macroinfo, 0,
                   1523:                       sizeof(struct macro_info));
                   1524:                TAILQ_INIT(&symbol->info.macroinfo->args);
                   1525:                break;
                   1526:        default:
                   1527:                stop("Call to initialize_symbol with invalid symbol type",
                   1528:                     EX_SOFTWARE);
                   1529:                /* NOTREACHED */
                   1530:                break;
                   1531:        }
                   1532: }
                   1533:
                   1534: static void
                   1535: add_macro_arg(const char *argtext, int argnum)
                   1536: {
                   1537:        struct macro_arg *marg;
                   1538:        int i;
                   1539:        int retval;
                   1540:
                   1541:
                   1542:        if (cur_symbol == NULL || cur_symbol->type != MACRO) {
                   1543:                stop("Invalid current symbol for adding macro arg",
                   1544:                     EX_SOFTWARE);
                   1545:                /* NOTREACHED */
                   1546:        }
                   1547:
                   1548:        marg = (struct macro_arg *)malloc(sizeof(*marg));
                   1549:        if (marg == NULL) {
                   1550:                stop("Can't create macro_arg structure", EX_SOFTWARE);
                   1551:                /* NOTREACHED */
                   1552:        }
                   1553:        marg->replacement_text = NULL;
                   1554:        retval = snprintf(regex_pattern, sizeof(regex_pattern),
                   1555:                          "[^-/A-Za-z0-9_](%s)([^-/A-Za-z0-9_]|$)",
                   1556:                          argtext);
                   1557:        if (retval == -1 || retval >= sizeof(regex_pattern)) {
                   1558:                stop("Regex text buffer too small for arg",
                   1559:                     EX_SOFTWARE);
                   1560:                /* NOTREACHED */
                   1561:        }
                   1562:        retval = regcomp(&marg->arg_regex, regex_pattern, REG_EXTENDED);
                   1563:        if (retval != 0) {
                   1564:                stop("Regex compilation failed", EX_SOFTWARE);
                   1565:                /* NOTREACHED */
                   1566:        }
                   1567:        TAILQ_INSERT_TAIL(&cur_symbol->info.macroinfo->args, marg, links);
                   1568: }
                   1569:
                   1570: static void
                   1571: add_macro_body(const char *bodytext)
                   1572: {
                   1573:        if (cur_symbol == NULL || cur_symbol->type != MACRO) {
                   1574:                stop("Invalid current symbol for adding macro arg",
                   1575:                     EX_SOFTWARE);
                   1576:                /* NOTREACHED */
                   1577:        }
                   1578:        cur_symbol->info.macroinfo->body = strdup(bodytext);
                   1579:        if (cur_symbol->info.macroinfo->body == NULL) {
                   1580:                stop("Can't duplicate macro body text", EX_SOFTWARE);
                   1581:                /* NOTREACHED */
                   1582:        }
                   1583: }
                   1584:
                   1585: static void
                   1586: process_register(symbol_t **p_symbol)
                   1587: {
                   1588:        symbol_t *symbol = *p_symbol;
                   1589:
                   1590:        if (symbol->type == UNINITIALIZED) {
                   1591:                snprintf(errbuf, sizeof(errbuf), "Undefined register %s",
                   1592:                         symbol->name);
                   1593:                stop(errbuf, EX_DATAERR);
                   1594:                /* NOTREACHED */
                   1595:        } else if (symbol->type == ALIAS) {
                   1596:                *p_symbol = symbol->info.ainfo->parent;
                   1597:        } else if ((symbol->type != REGISTER)
                   1598:                && (symbol->type != SCBLOC)
                   1599:                && (symbol->type != SRAMLOC)) {
                   1600:                snprintf(errbuf, sizeof(errbuf),
                   1601:                         "Specified symbol %s is not a register",
                   1602:                         symbol->name);
                   1603:                stop(errbuf, EX_DATAERR);
                   1604:        }
                   1605: }
                   1606:
                   1607: static void
                   1608: format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed,
                   1609:               symbol_ref_t *src, int ret)
                   1610: {
                   1611:        struct instruction *instr;
                   1612:        struct ins_format1 *f1_instr;
                   1613:
                   1614:        if (src->symbol == NULL)
                   1615:                src = dest;
                   1616:
                   1617:        /* Test register permissions */
                   1618:        test_writable_symbol(dest->symbol);
                   1619:        test_readable_symbol(src->symbol);
                   1620:
                   1621:        /* Ensure that immediate makes sense for this destination */
                   1622:        type_check(dest->symbol, immed, opcode);
                   1623:
                   1624:        /* Allocate sequencer space for the instruction and fill it out */
                   1625:        instr = seq_alloc();
                   1626:        f1_instr = &instr->format.format1;
                   1627:        f1_instr->ret = ret ? 1 : 0;
                   1628:        f1_instr->opcode = opcode;
                   1629:        f1_instr->destination = dest->symbol->info.rinfo->address
                   1630:                              + dest->offset;
                   1631:        f1_instr->source = src->symbol->info.rinfo->address
                   1632:                         + src->offset;
                   1633:        f1_instr->immediate = immed->value;
                   1634:
                   1635:        if (is_download_const(immed))
                   1636:                f1_instr->parity = 1;
                   1637:        else if (dest->symbol == mode_ptr.symbol) {
                   1638:                u_int src_value;
                   1639:                u_int dst_value;
                   1640:
                   1641:                /*
                   1642:                 * Attempt to update mode information if
                   1643:                 * we are operating on the mode register.
                   1644:                 */
                   1645:                if (src->symbol == allones.symbol)
                   1646:                        src_value = 0xFF;
                   1647:                else if (src->symbol == allzeros.symbol)
                   1648:                        src_value = 0;
                   1649:                else if (src->symbol == mode_ptr.symbol)
                   1650:                        src_value = (dst_mode << 4) | src_mode;
                   1651:                else
                   1652:                        goto cant_update;
                   1653:
                   1654:                switch (opcode) {
                   1655:                case AIC_OP_AND:
                   1656:                        dst_value = src_value & immed->value;
                   1657:                        break;
                   1658:                case AIC_OP_XOR:
                   1659:                        dst_value = src_value ^ immed->value;
                   1660:                        break;
                   1661:                case AIC_OP_ADD:
                   1662:                        dst_value = (src_value + immed->value) & 0xFF;
                   1663:                        break;
                   1664:                case AIC_OP_OR:
                   1665:                        dst_value = src_value | immed->value;
                   1666:                        break;
                   1667:                case AIC_OP_BMOV:
                   1668:                        dst_value = src_value;
                   1669:                        break;
                   1670:                default:
                   1671:                        goto cant_update;
                   1672:                }
                   1673:                src_mode = dst_value & 0xF;
                   1674:                dst_mode = (dst_value >> 4) & 0xF;
                   1675:        }
                   1676:
                   1677: cant_update:
                   1678:        symlist_free(&immed->referenced_syms);
                   1679:        instruction_ptr++;
                   1680: }
                   1681:
                   1682: static void
                   1683: format_2_instr(int opcode, symbol_ref_t *dest, expression_t *places,
                   1684:               symbol_ref_t *src, int ret)
                   1685: {
                   1686:        struct instruction *instr;
                   1687:        struct ins_format2 *f2_instr;
                   1688:        uint8_t shift_control;
                   1689:
                   1690:        if (src->symbol == NULL)
                   1691:                src = dest;
                   1692:
                   1693:        /* Test register permissions */
                   1694:        test_writable_symbol(dest->symbol);
                   1695:        test_readable_symbol(src->symbol);
                   1696:
                   1697:        /* Allocate sequencer space for the instruction and fill it out */
                   1698:        instr = seq_alloc();
                   1699:        f2_instr = &instr->format.format2;
                   1700:        f2_instr->ret = ret ? 1 : 0;
                   1701:        f2_instr->opcode = AIC_OP_ROL;
                   1702:        f2_instr->destination = dest->symbol->info.rinfo->address
                   1703:                              + dest->offset;
                   1704:        f2_instr->source = src->symbol->info.rinfo->address
                   1705:                         + src->offset;
                   1706:        if (places->value > 8 || places->value <= 0) {
                   1707:                stop("illegal shift value", EX_DATAERR);
                   1708:                /* NOTREACHED */
                   1709:        }
                   1710:        switch (opcode) {
                   1711:        case AIC_OP_SHL:
                   1712:                if (places->value == 8)
                   1713:                        shift_control = 0xf0;
                   1714:                else
                   1715:                        shift_control = (places->value << 4) | places->value;
                   1716:                break;
                   1717:        case AIC_OP_SHR:
                   1718:                if (places->value == 8) {
                   1719:                        shift_control = 0xf8;
                   1720:                } else {
                   1721:                        shift_control = (places->value << 4)
                   1722:                                      | (8 - places->value)
                   1723:                                      | 0x08;
                   1724:                }
                   1725:                break;
                   1726:        case AIC_OP_ROL:
                   1727:                shift_control = places->value & 0x7;
                   1728:                break;
                   1729:        case AIC_OP_ROR:
                   1730:                shift_control = (8 - places->value) | 0x08;
                   1731:                break;
                   1732:        default:
                   1733:                shift_control = 0; /* Quiet Compiler */
                   1734:                stop("Invalid shift operation specified", EX_SOFTWARE);
                   1735:                /* NOTREACHED */
                   1736:                break;
                   1737:        };
                   1738:        f2_instr->shift_control = shift_control;
                   1739:        symlist_free(&places->referenced_syms);
                   1740:        instruction_ptr++;
                   1741: }
                   1742:
                   1743: static void
                   1744: format_3_instr(int opcode, symbol_ref_t *src,
                   1745:               expression_t *immed, symbol_ref_t *address)
                   1746: {
                   1747:        struct instruction *instr;
                   1748:        struct ins_format3 *f3_instr;
                   1749:        int addr;
                   1750:
                   1751:        /* Test register permissions */
                   1752:        test_readable_symbol(src->symbol);
                   1753:
                   1754:        /* Ensure that immediate makes sense for this source */
                   1755:        type_check(src->symbol, immed, opcode);
                   1756:
                   1757:        /* Allocate sequencer space for the instruction and fill it out */
                   1758:        instr = seq_alloc();
                   1759:        f3_instr = &instr->format.format3;
                   1760:        if (address->symbol == NULL) {
                   1761:                /* 'dot' referrence.  Use the current instruction pointer */
                   1762:                addr = instruction_ptr + address->offset;
                   1763:        } else if (address->symbol->type == UNINITIALIZED) {
                   1764:                /* forward reference */
                   1765:                addr = address->offset;
                   1766:                instr->patch_label = address->symbol;
                   1767:        } else
                   1768:                addr = address->symbol->info.linfo->address + address->offset;
                   1769:        f3_instr->opcode = opcode;
                   1770:        f3_instr->address = addr;
                   1771:        f3_instr->source = src->symbol->info.rinfo->address
                   1772:                         + src->offset;
                   1773:        f3_instr->immediate = immed->value;
                   1774:
                   1775:        if (is_download_const(immed))
                   1776:                f3_instr->parity = 1;
                   1777:
                   1778:        symlist_free(&immed->referenced_syms);
                   1779:        instruction_ptr++;
                   1780: }
                   1781:
                   1782: static void
                   1783: test_readable_symbol(symbol_t *symbol)
                   1784: {
                   1785:
                   1786:        if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) {
                   1787:                snprintf(errbuf, sizeof(errbuf),
                   1788:                        "Register %s unavailable in source reg mode %d",
                   1789:                        symbol->name, src_mode);
                   1790:                stop(errbuf, EX_DATAERR);
                   1791:        }
                   1792:
                   1793:        if (symbol->info.rinfo->mode == WO) {
                   1794:                stop("Write Only register specified as source",
                   1795:                     EX_DATAERR);
                   1796:                /* NOTREACHED */
                   1797:        }
                   1798: }
                   1799:
                   1800: static void
                   1801: test_writable_symbol(symbol_t *symbol)
                   1802: {
                   1803:
                   1804:        if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) {
                   1805:                snprintf(errbuf, sizeof(errbuf),
                   1806:                        "Register %s unavailable in destination reg mode %d",
                   1807:                        symbol->name, dst_mode);
                   1808:                stop(errbuf, EX_DATAERR);
                   1809:        }
                   1810:
                   1811:        if (symbol->info.rinfo->mode == RO) {
                   1812:                stop("Read Only register specified as destination",
                   1813:                     EX_DATAERR);
                   1814:                /* NOTREACHED */
                   1815:        }
                   1816: }
                   1817:
                   1818: static void
                   1819: type_check(symbol_t *symbol, expression_t *expression, int opcode)
                   1820: {
                   1821:        symbol_node_t *node;
                   1822:        int and_op;
                   1823:
                   1824:        and_op = FALSE;
                   1825:        if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
                   1826:                and_op = TRUE;
                   1827:
                   1828:        /*
                   1829:         * Make sure that we aren't attempting to write something
                   1830:         * that hasn't been defined.  If this is an and operation,
                   1831:         * this is a mask, so "undefined" bits are okay.
                   1832:         */
                   1833:        if (and_op == FALSE
                   1834:         && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) {
                   1835:                snprintf(errbuf, sizeof(errbuf),
                   1836:                         "Invalid bit(s) 0x%x in immediate written to %s",
                   1837:                         expression->value & ~symbol->info.rinfo->valid_bitmask,
                   1838:                         symbol->name);
                   1839:                stop(errbuf, EX_DATAERR);
                   1840:                /* NOTREACHED */
                   1841:        }
                   1842:
                   1843:        /*
                   1844:         * Now make sure that all of the symbols referenced by the
                   1845:         * expression are defined for this register.
                   1846:         */
                   1847:        if (symbol->info.rinfo->typecheck_masks != FALSE) {
                   1848:                SLIST_FOREACH(node, &expression->referenced_syms, links) {
                   1849:                        if ((node->symbol->type == MASK
                   1850:                          || node->symbol->type == FIELD
                   1851:                          || node->symbol->type == ENUM
                   1852:                          || node->symbol->type == ENUM_ENTRY)
                   1853:                         && symlist_search(&node->symbol->info.finfo->symrefs,
                   1854:                                           symbol->name) == NULL) {
                   1855:                                snprintf(errbuf, sizeof(errbuf),
                   1856:                                         "Invalid field or mask %s "
                   1857:                                         "for register %s",
                   1858:                                         node->symbol->name, symbol->name);
                   1859:                                stop(errbuf, EX_DATAERR);
                   1860:                                /* NOTREACHED */
                   1861:                        }
                   1862:                }
                   1863:        }
                   1864: }
                   1865:
                   1866: static void
                   1867: make_expression(expression_t *immed, int value)
                   1868: {
                   1869:        SLIST_INIT(&immed->referenced_syms);
                   1870:        immed->value = value & 0xff;
                   1871: }
                   1872:
                   1873: static void
                   1874: add_conditional(symbol_t *symbol)
                   1875: {
                   1876:        static int numfuncs;
                   1877:
                   1878:        if (numfuncs == 0) {
                   1879:                /* add a special conditional, "0" */
                   1880:                symbol_t *false_func;
                   1881:
                   1882:                false_func = symtable_get("0");
                   1883:                if (false_func->type != UNINITIALIZED) {
                   1884:                        stop("Conditional expression '0' "
                   1885:                             "conflicts with a symbol", EX_DATAERR);
                   1886:                        /* NOTREACHED */
                   1887:                }
                   1888:                false_func->type = CONDITIONAL;
                   1889:                initialize_symbol(false_func);
                   1890:                false_func->info.condinfo->func_num = numfuncs++;
                   1891:                symlist_add(&patch_functions, false_func, SYMLIST_INSERT_HEAD);
                   1892:        }
                   1893:
                   1894:        /* This condition has occurred before */
                   1895:        if (symbol->type == CONDITIONAL)
                   1896:                return;
                   1897:
                   1898:        if (symbol->type != UNINITIALIZED) {
                   1899:                stop("Conditional expression conflicts with a symbol",
                   1900:                     EX_DATAERR);
                   1901:                /* NOTREACHED */
                   1902:        }
                   1903:
                   1904:        symbol->type = CONDITIONAL;
                   1905:        initialize_symbol(symbol);
                   1906:        symbol->info.condinfo->func_num = numfuncs++;
                   1907:        symlist_add(&patch_functions, symbol, SYMLIST_INSERT_HEAD);
                   1908: }
                   1909:
                   1910: static void
                   1911: add_version(const char *verstring)
                   1912: {
                   1913:        const char *q, prefix[] = " * ";
                   1914:        char *p;
                   1915:        int newlen;
                   1916:        int oldlen;
                   1917:
                   1918:        newlen = strlen(verstring) + strlen(prefix);
                   1919:        oldlen = 0;
                   1920:        if (versions != NULL)
                   1921:                oldlen = strlen(versions);
                   1922:        versions = realloc(versions, newlen + oldlen + 2);
                   1923:        if (versions == NULL)
                   1924:                stop("Can't allocate version string", EX_SOFTWARE);
                   1925:        strcpy(&versions[oldlen], prefix);
                   1926:        for (p = &versions[oldlen + strlen(prefix)], q = verstring; *q; q++) {
                   1927:                if (*q == '$')
                   1928:                        continue;
                   1929:                *p++ = *q;
                   1930:        }
                   1931:        *p++ = '\n';
                   1932:        *p = '\0';
                   1933: }
                   1934:
                   1935: void
                   1936: yyerror(const char *string)
                   1937: {
                   1938:        stop(string, EX_DATAERR);
                   1939: }
                   1940:
                   1941: static int
                   1942: is_download_const(expression_t *immed)
                   1943: {
                   1944:        if ((!SLIST_EMPTY(&immed->referenced_syms))
                   1945:         && (SLIST_FIRST(&immed->referenced_syms)->symbol->type == DOWNLOAD_CONST))
                   1946:                return (TRUE);
                   1947:
                   1948:        return (FALSE);
                   1949: }

CVSweb