aicasm_gram.y revision 26997
1%{ 2/* 3 * Parser for the Aic7xxx SCSI Host adapter sequencer assembler. 4 * 5 * Copyright (c) 1997 Justin T. Gibbs. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: gram.y,v 1.1 1997/03/16 07:08:16 gibbs Exp $ 33 */ 34 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> 38#include <sysexits.h> 39 40#include <sys/types.h> 41#include <sys/queue.h> 42 43#include "aic7xxx_asm.h" 44#include "symbol.h" 45#include "sequencer.h" 46 47int yylineno; 48char *yyfilename; 49static symbol_t *cur_symbol; 50static symtype cur_symtype; 51static symbol_t *accumulator; 52static symbol_ref_t allones; 53static symbol_ref_t allzeros; 54static symbol_ref_t none; 55static symbol_ref_t sindex; 56static int instruction_ptr; 57static int sram_or_scb_offset; 58static patch_t *cur_patch; 59 60static void process_bitmask __P((int mask_type, symbol_t *sym, int mask)); 61static void initialize_symbol __P((symbol_t *symbol)); 62static void process_register __P((symbol_t **p_symbol)); 63static void format_1_instr __P((int opcode, symbol_ref_t *dest, 64 expression_t *immed, symbol_ref_t *src, 65 int ret)); 66static void format_2_instr __P((int opcode, symbol_ref_t *dest, 67 expression_t *places, symbol_ref_t *src, 68 int ret)); 69static void format_3_instr __P((int opcode, symbol_ref_t *src, 70 expression_t *immed, symbol_ref_t *address)); 71static void test_readable_symbol __P((symbol_t *symbol)); 72static void test_writable_symbol __P((symbol_t *symbol)); 73static void type_check __P((symbol_t *symbol, expression_t *expression, 74 int and_op)); 75static void make_expression __P((expression_t *immed, int value)); 76static void add_conditional __P((symbol_t *symbol)); 77 78#define YYDEBUG 1 79#define SRAM_SYMNAME "SRAM_BASE" 80#define SCB_SYMNAME "SCB_BASE" 81%} 82 83%union { 84 int value; 85 char *str; 86 symbol_t *sym; 87 symbol_ref_t sym_ref; 88 expression_t expression; 89} 90 91%token T_REGISTER 92 93%token <value> T_CONST 94 95%token T_SCB 96 97%token T_SRAM 98 99%token T_ALIAS 100 101%token T_SIZE 102 103%token <value> T_ADDRESS 104 105%token T_ACCESS_MODE 106 107%token <value> T_MODE 108 109%token T_BIT 110 111%token T_MASK 112 113%token <value> T_NUMBER 114 115%token <str> T_PATH 116 117%token T_EOF T_INCLUDE 118 119%token <value> T_SHR T_SHL T_ROR T_ROL 120 121%token <value> T_MVI T_MOV T_CLR 122 123%token <value> T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL 124 125%token <value> T_ADD T_ADC 126 127%token <value> T_INC T_DEC 128 129%token <value> T_STC T_CLC 130 131%token <value> T_CMP T_XOR 132 133%token <value> T_TEST T_AND 134 135%token <value> T_OR 136 137%token T_RET 138 139%token T_NOP 140 141%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX 142 143%token T_A 144 145%token <sym> T_SYMBOL 146 147%token T_NL 148 149%token T_IF T_ELSE T_ENDIF 150 151%type <sym_ref> reg_symbol address destination source opt_source 152 153%type <expression> expression immediate immediate_or_a 154 155%type <value> ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne 156 157%left '|' 158%left '&' 159%left '+' '-' 160%right '~' 161%nonassoc UMINUS 162%% 163 164program: 165 include 166| program include 167| register 168| program register 169| constant 170| program constant 171| scratch_ram 172| program scratch_ram 173| scb 174| program scb 175| label 176| program label 177| conditional 178| program conditional 179| code 180| program code 181; 182 183include: 184 T_INCLUDE '<' T_PATH '>' 185 { include_file($3, BRACKETED_INCLUDE); } 186| T_INCLUDE '"' T_PATH '"' 187 { include_file($3, QUOTED_INCLUDE); } 188; 189 190register: 191 T_REGISTER { cur_symtype = REGISTER; } reg_definition 192; 193 194reg_definition: 195 T_SYMBOL '{' 196 { 197 if ($1->type != UNINITIALIZED) { 198 stop("Register multiply defined", EX_DATAERR); 199 /* NOTREACHED */ 200 } 201 cur_symbol = $1; 202 cur_symbol->type = cur_symtype; 203 initialize_symbol(cur_symbol); 204 } 205 reg_attribute_list 206 '}' 207 { 208 /* 209 * Default to allowing everything in for registers 210 * with no bit or mask definitions. 211 */ 212 if (cur_symbol->info.rinfo->valid_bitmask == 0) 213 cur_symbol->info.rinfo->valid_bitmask = 0xFF; 214 215 if (cur_symbol->info.rinfo->size == 0) 216 cur_symbol->info.rinfo->size = 1; 217 218 /* 219 * This might be useful for registers too. 220 */ 221 if (cur_symbol->type != REGISTER) { 222 if (cur_symbol->info.rinfo->address == 0) 223 cur_symbol->info.rinfo->address = 224 sram_or_scb_offset; 225 sram_or_scb_offset += 226 cur_symbol->info.rinfo->size; 227 } 228 cur_symbol = NULL; 229 } 230; 231 232reg_attribute_list: 233 reg_attribute 234| reg_attribute_list reg_attribute 235; 236 237reg_attribute: 238 reg_address 239| size 240| access_mode 241| bit_defn 242| mask_defn 243| alias 244| accumulator 245| allones 246| allzeros 247| none 248| sindex 249; 250 251reg_address: 252 T_ADDRESS T_NUMBER 253 { 254 cur_symbol->info.rinfo->address = $2; 255 } 256; 257 258size: 259 T_SIZE T_NUMBER 260 { 261 cur_symbol->info.rinfo->size = $2; 262 } 263; 264 265access_mode: 266 T_ACCESS_MODE T_MODE 267 { 268 cur_symbol->info.rinfo->mode = $2; 269 } 270; 271 272bit_defn: 273 T_BIT T_SYMBOL T_NUMBER 274 { 275 process_bitmask(BIT, $2, $3); 276 } 277; 278 279mask_defn: 280 T_MASK T_SYMBOL expression 281 { 282 process_bitmask(MASK, $2, $3.value); 283 } 284; 285 286alias: 287 T_ALIAS T_SYMBOL 288 { 289 if ($2->type != UNINITIALIZED) { 290 stop("Re-definition of register alias", 291 EX_DATAERR); 292 /* NOTREACHED */ 293 } 294 $2->type = ALIAS; 295 initialize_symbol($2); 296 $2->info.ainfo->parent = cur_symbol; 297 } 298; 299 300accumulator: 301 T_ACCUM 302 { 303 if (accumulator != NULL) { 304 stop("Only one accumulator definition allowed", 305 EX_DATAERR); 306 /* NOTREACHED */ 307 } 308 accumulator = cur_symbol; 309 } 310; 311 312allones: 313 T_ALLONES 314 { 315 if (allones.symbol != NULL) { 316 stop("Only one definition of allones allowed", 317 EX_DATAERR); 318 /* NOTREACHED */ 319 } 320 allones.symbol = cur_symbol; 321 } 322; 323 324allzeros: 325 T_ALLZEROS 326 { 327 if (allzeros.symbol != NULL) { 328 stop("Only one definition of allzeros allowed", 329 EX_DATAERR); 330 /* NOTREACHED */ 331 } 332 allzeros.symbol = cur_symbol; 333 } 334; 335 336none: 337 T_NONE 338 { 339 if (none.symbol != NULL) { 340 stop("Only one definition of none allowed", 341 EX_DATAERR); 342 /* NOTREACHED */ 343 } 344 none.symbol = cur_symbol; 345 } 346; 347 348sindex: 349 T_SINDEX 350 { 351 if (sindex.symbol != NULL) { 352 stop("Only one definition of sindex allowed", 353 EX_DATAERR); 354 /* NOTREACHED */ 355 } 356 sindex.symbol = cur_symbol; 357 } 358; 359 360expression: 361 expression '|' expression 362 { 363 $$.value = $1.value | $3.value; 364 symlist_merge(&$$.referenced_syms, 365 &$1.referenced_syms, 366 &$3.referenced_syms); 367 } 368| expression '&' expression 369 { 370 $$.value = $1.value & $3.value; 371 symlist_merge(&$$.referenced_syms, 372 &$1.referenced_syms, 373 &$3.referenced_syms); 374 } 375| expression '+' expression 376 { 377 $$.value = $1.value + $3.value; 378 symlist_merge(&$$.referenced_syms, 379 &$1.referenced_syms, 380 &$3.referenced_syms); 381 } 382| expression '-' expression 383 { 384 $$.value = $1.value - $3.value; 385 symlist_merge(&($$.referenced_syms), 386 &($1.referenced_syms), 387 &($3.referenced_syms)); 388 } 389| '(' expression ')' 390 { 391 $$ = $2; 392 } 393| '~' expression 394 { 395 $$ = $2; 396 $$.value = (~$$.value) & 0xFF; 397 } 398| '-' expression %prec UMINUS 399 { 400 $$ = $2; 401 $$.value = -$$.value; 402 } 403| T_NUMBER 404 { 405 $$.value = $1; 406 SLIST_INIT(&$$.referenced_syms); 407 } 408| T_SYMBOL 409 { 410 symbol_t *symbol; 411 412 symbol = $1; 413 switch (symbol->type) { 414 case ALIAS: 415 symbol = $1->info.ainfo->parent; 416 case REGISTER: 417 case SCBLOC: 418 case SRAMLOC: 419 $$.value = symbol->info.rinfo->address; 420 break; 421 case MASK: 422 case BIT: 423 $$.value = symbol->info.minfo->mask; 424 break; 425 case CONST: 426 $$.value = symbol->info.cinfo->value; 427 break; 428 case UNINITIALIZED: 429 default: 430 { 431 char buf[255]; 432 433 snprintf(buf, sizeof(buf), 434 "Undefined symbol %s referenced", 435 symbol->name); 436 stop(buf, EX_DATAERR); 437 /* NOTREACHED */ 438 break; 439 } 440 } 441 SLIST_INIT(&$$.referenced_syms); 442 symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD); 443 } 444; 445 446constant: 447 T_CONST T_SYMBOL T_NUMBER 448 { 449 if ($2->type != UNINITIALIZED) { 450 stop("Re-definition of constant variable", 451 EX_DATAERR); 452 /* NOTREACHED */ 453 } 454 $2->type = CONST; 455 initialize_symbol($2); 456 $2->info.cinfo->value = $3; 457 $2->info.cinfo->define = $1; 458 } 459; 460 461scratch_ram: 462 T_SRAM '{' 463 { 464 cur_symbol = symtable_get(SRAM_SYMNAME); 465 cur_symtype = SRAMLOC; 466 if (cur_symbol->type != UNINITIALIZED) { 467 stop("Only one SRAM definition allowed", 468 EX_DATAERR); 469 /* NOTREACHED */ 470 } 471 cur_symbol->type = SRAMLOC; 472 initialize_symbol(cur_symbol); 473 } 474 reg_address 475 { 476 sram_or_scb_offset = cur_symbol->info.rinfo->address; 477 } 478 scb_or_sram_reg_list 479 '}' 480 { 481 cur_symbol = NULL; 482 } 483; 484 485scb: 486 T_SCB '{' 487 { 488 cur_symbol = symtable_get(SCB_SYMNAME); 489 cur_symtype = SCBLOC; 490 if (cur_symbol->type != UNINITIALIZED) { 491 stop("Only one SRAM definition allowed", 492 EX_SOFTWARE); 493 /* NOTREACHED */ 494 } 495 cur_symbol->type = SCBLOC; 496 initialize_symbol(cur_symbol); 497 } 498 reg_address 499 { 500 sram_or_scb_offset = cur_symbol->info.rinfo->address; 501 } 502 scb_or_sram_reg_list 503 '}' 504 { 505 cur_symbol = NULL; 506 } 507; 508 509scb_or_sram_reg_list: 510 reg_definition 511| scb_or_sram_reg_list reg_definition 512; 513 514reg_symbol: 515 T_SYMBOL 516 { 517 process_register(&$1); 518 $$.symbol = $1; 519 $$.offset = 0; 520 } 521| T_SYMBOL '[' T_NUMBER ']' 522 { 523 process_register(&$1); 524 if (($3 + 1) > $1->info.rinfo->size) { 525 stop("Accessing offset beyond range of register", 526 EX_DATAERR); 527 /* NOTREACHED */ 528 } 529 $$.symbol = $1; 530 $$.offset = $3; 531 } 532| T_A 533 { 534 if (accumulator == NULL) { 535 stop("No accumulator has been defined", EX_DATAERR); 536 /* NOTREACHED */ 537 } 538 $$.symbol = accumulator; 539 $$.offset = 0; 540 } 541; 542 543destination: 544 reg_symbol 545 { 546 test_writable_symbol($1.symbol); 547 $$ = $1; 548 } 549; 550 551immediate: 552 expression 553 { $$ = $1; } 554; 555 556immediate_or_a: 557 expression 558 { 559 $$ = $1; 560 } 561| T_A 562 { 563 SLIST_INIT(&$$.referenced_syms); 564 $$.value = 0; 565 } 566; 567 568source: 569 reg_symbol 570 { 571 test_readable_symbol($1.symbol); 572 $$ = $1; 573 } 574; 575 576opt_source: 577 { 578 $$.symbol = NULL; 579 $$.offset = 0; 580 } 581| ',' source 582 { $$ = $2; } 583; 584 585ret: 586 { $$ = 0; } 587| T_RET 588 { $$ = 1; } 589; 590 591label: 592 T_SYMBOL ':' 593 { 594 if ($1->type != UNINITIALIZED) { 595 stop("Program label multiply defined", EX_DATAERR); 596 /* NOTREACHED */ 597 } 598 $1->type = LABEL; 599 initialize_symbol($1); 600 $1->info.linfo->address = instruction_ptr; 601 } 602; 603 604address: 605 T_SYMBOL 606 { 607 $$.symbol = $1; 608 $$.offset = 0; 609 } 610| T_SYMBOL '+' T_NUMBER 611 { 612 $$.symbol = $1; 613 $$.offset = $3; 614 } 615| T_SYMBOL '-' T_NUMBER 616 { 617 $$.symbol = $1; 618 $$.offset = -$3; 619 } 620| '.' 621 { 622 $$.symbol = NULL; 623 $$.offset = 0; 624 } 625| '.' '+' T_NUMBER 626 { 627 $$.symbol = NULL; 628 $$.offset = $3; 629 } 630| '.' '-' T_NUMBER 631 { 632 $$.symbol = NULL; 633 $$.offset = -$3; 634 } 635; 636 637conditional: 638 T_IF 639 { 640 if (cur_patch != NULL) { 641 stop("Nested .if directive", EX_DATAERR); 642 /* NOTREACHED */ 643 } 644 cur_patch = patch_alloc(); 645 cur_patch->begin = instruction_ptr; 646 } 647 option_list 648; 649 650conditional: 651 T_ELSE 652 { 653 patch_t *next_patch; 654 655 if (cur_patch == NULL) { 656 stop(".else outsize of .if", EX_DATAERR); 657 /* NOTREACHED */ 658 } 659 cur_patch->end = instruction_ptr; 660 next_patch = patch_alloc(); 661 next_patch->options = cur_patch->options; 662 next_patch->negative = cur_patch->negative ? FALSE : TRUE; 663 cur_patch = next_patch; 664 cur_patch->begin = instruction_ptr; 665 } 666; 667 668conditional: 669 T_ENDIF 670 { 671 if (cur_patch == NULL) { 672 stop(".endif outsize of .if", EX_DATAERR); 673 /* NOTREACHED */ 674 } 675 cur_patch->end = instruction_ptr; 676 cur_patch = NULL; 677 } 678; 679 680option_list: 681 '(' option_symbol_list ')' 682| '!' option_list 683 { 684 cur_patch->negative = cur_patch->negative ? FALSE : TRUE; 685 } 686; 687 688option_symbol_list: 689 T_SYMBOL 690 { 691 add_conditional($1); 692 } 693| option_list '|' T_SYMBOL 694 { 695 add_conditional($3); 696 } 697; 698 699f1_opcode: 700 T_AND { $$ = AIC_OP_AND; } 701| T_XOR { $$ = AIC_OP_XOR; } 702| T_ADD { $$ = AIC_OP_ADD; } 703| T_ADC { $$ = AIC_OP_ADC; } 704; 705 706code: 707 f1_opcode destination ',' immediate_or_a opt_source ret ';' 708 { 709 format_1_instr($1, &$2, &$4, &$5, $6); 710 } 711; 712 713code: 714 T_OR reg_symbol ',' immediate_or_a opt_source ret ';' 715 { 716 format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6); 717 } 718; 719 720code: 721 T_INC destination opt_source ret ';' 722 { 723 expression_t immed; 724 725 make_expression(&immed, 1); 726 format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); 727 } 728; 729 730code: 731 T_DEC destination opt_source ret ';' 732 { 733 expression_t immed; 734 735 make_expression(&immed, -1); 736 format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4); 737 } 738; 739 740code: 741 T_CLC ret ';' 742 { 743 expression_t immed; 744 745 make_expression(&immed, -1); 746 format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2); 747 } 748| T_CLC T_MVI destination ',' immediate_or_a ret ';' 749 { 750 format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6); 751 } 752; 753 754code: 755 T_STC ret ';' 756 { 757 expression_t immed; 758 759 make_expression(&immed, 1); 760 format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2); 761 } 762| T_STC destination ret ';' 763 { 764 expression_t immed; 765 766 make_expression(&immed, 1); 767 format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3); 768 } 769; 770 771code: 772 T_MOV destination ',' source ret ';' 773 { 774 expression_t immed; 775 776 make_expression(&immed, 0xff); 777 format_1_instr(AIC_OP_AND, &$2, &immed, &$4, $5); 778 } 779; 780 781code: 782 T_MVI destination ',' immediate_or_a ret ';' 783 { 784 format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); 785 } 786; 787 788code: 789 T_CLR destination ret ';' 790 { 791 expression_t immed; 792 793 make_expression(&immed, 0xff); 794 format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3); 795 } 796; 797 798code: 799 T_NOP ';' 800 { 801 expression_t immed; 802 803 make_expression(&immed, 0xff); 804 format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, FALSE); 805 } 806; 807 808code: 809 T_RET ';' 810 { 811 expression_t immed; 812 813 make_expression(&immed, 0xff); 814 format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE); 815 } 816; 817 818 /* 819 * This grammer differs from the one in the aic7xxx 820 * reference manual since the grammer listed there is 821 * ambiguous and causes a shift/reduce conflict. 822 * It also seems more logical as the "immediate" 823 * argument is listed as the second arg like the 824 * other formats. 825 */ 826 827f2_opcode: 828 T_SHL { $$ = AIC_OP_SHL; } 829| T_SHR { $$ = AIC_OP_SHR; } 830| T_ROL { $$ = AIC_OP_ROL; } 831| T_ROR { $$ = AIC_OP_ROR; } 832; 833 834code: 835 f2_opcode destination ',' expression opt_source ret ';' 836 { 837 format_2_instr($1, &$2, &$4, &$5, $6); 838 } 839; 840 841jmp_jc_jnc_call: 842 T_JMP { $$ = AIC_OP_JMP; } 843| T_JC { $$ = AIC_OP_JC; } 844| T_JNC { $$ = AIC_OP_JNC; } 845| T_CALL { $$ = AIC_OP_CALL; } 846; 847 848jz_jnz: 849 T_JZ { $$ = AIC_OP_JZ; } 850| T_JNZ { $$ = AIC_OP_JNZ; } 851; 852 853je_jne: 854 T_JE { $$ = AIC_OP_JE; } 855| T_JNE { $$ = AIC_OP_JNE; } 856; 857 858code: 859 jmp_jc_jnc_call address ';' 860 { 861 expression_t immed; 862 863 make_expression(&immed, 0); 864 format_3_instr($1, &sindex, &immed, &$2); 865 } 866; 867 868code: 869 T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' 870 { 871 format_3_instr($5, &$2, &$4, &$6); 872 } 873; 874 875code: 876 T_TEST source ',' immediate_or_a jz_jnz address ';' 877 { 878 format_3_instr($5, &$2, &$4, &$6); 879 } 880; 881 882code: 883 T_CMP source ',' immediate_or_a je_jne address ';' 884 { 885 format_3_instr($5, &$2, &$4, &$6); 886 } 887; 888 889code: 890 T_MOV source jmp_jc_jnc_call address ';' 891 { 892 expression_t immed; 893 894 make_expression(&immed, 0); 895 format_3_instr($3, &$2, &immed, &$4); 896 } 897; 898 899code: 900 T_MVI immediate jmp_jc_jnc_call address ';' 901 { 902 format_3_instr($3, &allzeros, &$2, &$4); 903 } 904; 905 906%% 907 908static void 909process_bitmask(mask_type, sym, mask) 910 int mask_type; 911 symbol_t *sym; 912 int mask; 913{ 914 /* 915 * Add the current register to its 916 * symbol list, if it already exists, 917 * warn if we are setting it to a 918 * different value, or in the bit to 919 * the "allowed bits" of this register. 920 */ 921 if (sym->type == UNINITIALIZED) { 922 sym->type = mask_type; 923 initialize_symbol(sym); 924 if (mask_type == BIT) { 925 if (mask == 0) { 926 stop("Bitmask with no bits set", EX_DATAERR); 927 /* NOTREACHED */ 928 } 929 if ((mask & ~(0x01 << (ffs(mask) - 1))) != 0) { 930 stop("Bitmask with more than one bit set", 931 EX_DATAERR); 932 /* NOTREACHED */ 933 } 934 } 935 sym->info.minfo->mask = mask; 936 } else if (sym->type != mask_type) { 937 stop("Bit definition mirrors a definition of the same " 938 " name, but a different type", EX_DATAERR); 939 /* NOTREACHED */ 940 } else if (mask != sym->info.minfo->mask) { 941 stop("Bitmask redefined with a conflicting value", EX_DATAERR); 942 /* NOTREACHED */ 943 } 944 /* Fail if this symbol is already listed */ 945 if (symlist_search(&(sym->info.minfo->symrefs), 946 cur_symbol->name) != NULL) { 947 stop("Bitmask defined multiple times for register", EX_DATAERR); 948 /* NOTREACHED */ 949 } 950 symlist_add(&(sym->info.minfo->symrefs), cur_symbol, 951 SYMLIST_INSERT_HEAD); 952 cur_symbol->info.rinfo->valid_bitmask |= mask; 953 cur_symbol->info.rinfo->typecheck_masks = TRUE; 954} 955 956static void 957initialize_symbol(symbol) 958 symbol_t *symbol; 959{ 960 switch (symbol->type) { 961 case UNINITIALIZED: 962 stop("Call to initialize_symbol with type field unset", 963 EX_SOFTWARE); 964 /* NOTREACHED */ 965 break; 966 case REGISTER: 967 case SRAMLOC: 968 case SCBLOC: 969 symbol->info.rinfo = 970 (struct reg_info *)malloc(sizeof(struct reg_info)); 971 if (symbol->info.rinfo == NULL) { 972 stop("Can't create register info", EX_SOFTWARE); 973 /* NOTREACHED */ 974 } 975 memset(symbol->info.rinfo, 0, 976 sizeof(struct reg_info)); 977 break; 978 case ALIAS: 979 symbol->info.ainfo = 980 (struct alias_info *)malloc(sizeof(struct alias_info)); 981 if (symbol->info.ainfo == NULL) { 982 stop("Can't create alias info", EX_SOFTWARE); 983 /* NOTREACHED */ 984 } 985 memset(symbol->info.ainfo, 0, 986 sizeof(struct alias_info)); 987 break; 988 case MASK: 989 case BIT: 990 symbol->info.minfo = 991 (struct mask_info *)malloc(sizeof(struct mask_info)); 992 if (symbol->info.minfo == NULL) { 993 stop("Can't create bitmask info", EX_SOFTWARE); 994 /* NOTREACHED */ 995 } 996 memset(symbol->info.minfo, 0, sizeof(struct mask_info)); 997 SLIST_INIT(&(symbol->info.minfo->symrefs)); 998 break; 999 case CONST: 1000 symbol->info.cinfo = 1001 (struct const_info *)malloc(sizeof(struct const_info)); 1002 if (symbol->info.cinfo == NULL) { 1003 stop("Can't create alias info", EX_SOFTWARE); 1004 /* NOTREACHED */ 1005 } 1006 memset(symbol->info.cinfo, 0, 1007 sizeof(struct const_info)); 1008 break; 1009 case LABEL: 1010 symbol->info.linfo = 1011 (struct label_info *)malloc(sizeof(struct label_info)); 1012 if (symbol->info.linfo == NULL) { 1013 stop("Can't create label info", EX_SOFTWARE); 1014 /* NOTREACHED */ 1015 } 1016 memset(symbol->info.linfo, 0, 1017 sizeof(struct label_info)); 1018 break; 1019 case CONDITIONAL: 1020 symbol->info.condinfo = 1021 (struct cond_info *)malloc(sizeof(struct cond_info)); 1022 if (symbol->info.condinfo == NULL) { 1023 stop("Can't create conditional info", EX_SOFTWARE); 1024 /* NOTREACHED */ 1025 } 1026 memset(symbol->info.condinfo, 0, 1027 sizeof(struct cond_info)); 1028 break; 1029 default: 1030 stop("Call to initialize_symbol with invalid symbol type", 1031 EX_SOFTWARE); 1032 /* NOTREACHED */ 1033 break; 1034 } 1035} 1036 1037static void 1038process_register(p_symbol) 1039 symbol_t **p_symbol; 1040{ 1041 char buf[255]; 1042 symbol_t *symbol = *p_symbol; 1043 1044 if (symbol->type == UNINITIALIZED) { 1045 snprintf(buf, sizeof(buf), "Undefined register %s", 1046 symbol->name); 1047 stop(buf, EX_DATAERR); 1048 /* NOTREACHED */ 1049 } else if (symbol->type == ALIAS) { 1050 *p_symbol = symbol->info.ainfo->parent; 1051 } else if ((symbol->type != REGISTER) 1052 && (symbol->type != SCBLOC) 1053 && (symbol->type != SRAMLOC)) { 1054 snprintf(buf, sizeof(buf), 1055 "Specified symbol %s is not a register", 1056 symbol->name); 1057 stop(buf, EX_DATAERR); 1058 } 1059} 1060 1061static void 1062format_1_instr(opcode, dest, immed, src, ret) 1063 int opcode; 1064 symbol_ref_t *dest; 1065 expression_t *immed; 1066 symbol_ref_t *src; 1067 int ret; 1068{ 1069 struct instruction *instr; 1070 struct ins_format1 *f1_instr; 1071 1072 if (src->symbol == NULL) 1073 src = dest; 1074 1075 /* Test register permissions */ 1076 test_writable_symbol(dest->symbol); 1077 test_readable_symbol(src->symbol); 1078 1079 /* Ensure that immediate makes sense for this destination */ 1080 type_check(dest->symbol, immed, opcode); 1081 1082 /* Allocate sequencer space for the instruction and fill it out */ 1083 instr = seq_alloc(); 1084 f1_instr = &instr->format.format1; 1085 f1_instr->opcode_ret = (opcode << 1) | (ret ? RETURN_BIT : 0); 1086 f1_instr->destination = dest->symbol->info.rinfo->address 1087 + dest->offset; 1088 f1_instr->source = src->symbol->info.rinfo->address 1089 + src->offset; 1090 f1_instr->immediate = immed->value; 1091 symlist_free(&immed->referenced_syms); 1092 instruction_ptr++; 1093} 1094 1095static void 1096format_2_instr(opcode, dest, places, src, ret) 1097 int opcode; 1098 symbol_ref_t *dest; 1099 expression_t *places; 1100 symbol_ref_t *src; 1101 int ret; 1102{ 1103 struct instruction *instr; 1104 struct ins_format2 *f2_instr; 1105 u_int8_t shift_control; 1106 1107 if (src->symbol == NULL) 1108 src = dest; 1109 1110 /* Test register permissions */ 1111 test_writable_symbol(dest->symbol); 1112 test_readable_symbol(src->symbol); 1113 1114 /* Allocate sequencer space for the instruction and fill it out */ 1115 instr = seq_alloc(); 1116 f2_instr = &instr->format.format2; 1117 f2_instr->opcode_ret = (AIC_OP_ROL << 1) | (ret ? RETURN_BIT : 0); 1118 f2_instr->destination = dest->symbol->info.rinfo->address 1119 + dest->offset; 1120 f2_instr->source = src->symbol->info.rinfo->address 1121 + src->offset; 1122 if (places->value > 8 || places->value <= 0) { 1123 stop("illegal shift value", EX_DATAERR); 1124 /* NOTREACHED */ 1125 } 1126 switch (opcode) { 1127 case AIC_OP_SHL: 1128 if (places->value == 8) 1129 shift_control = 0xf0; 1130 else 1131 shift_control = (places->value << 4) | places->value; 1132 break; 1133 case AIC_OP_SHR: 1134 if (places->value == 8) { 1135 shift_control = 0xf8; 1136 } else { 1137 shift_control = (places->value << 4) 1138 | (8 - places->value) 1139 | 0x08; 1140 } 1141 break; 1142 case AIC_OP_ROL: 1143 shift_control = places->value & 0x7; 1144 break; 1145 case AIC_OP_ROR: 1146 shift_control = (8 - places->value) | 0x08; 1147 break; 1148 default: 1149 shift_control = 0; /* Quiet Compiler */ 1150 stop("Invalid shift operation specified", EX_SOFTWARE); 1151 /* NOTREACHED */ 1152 break; 1153 }; 1154 f2_instr->shift_control = shift_control; 1155 symlist_free(&places->referenced_syms); 1156 instruction_ptr++; 1157} 1158 1159static void 1160format_3_instr(opcode, src, immed, address) 1161 int opcode; 1162 symbol_ref_t *src; 1163 expression_t *immed; 1164 symbol_ref_t *address; 1165{ 1166 struct instruction *instr; 1167 struct ins_format3 *f3_instr; 1168 int addr; 1169 1170 /* Test register permissions */ 1171 test_readable_symbol(src->symbol); 1172 1173 /* Ensure that immediate makes sense for this source */ 1174 type_check(src->symbol, immed, opcode); 1175 1176 /* Allocate sequencer space for the instruction and fill it out */ 1177 instr = seq_alloc(); 1178 f3_instr = &instr->format.format3; 1179 if (address->symbol == NULL) { 1180 /* 'dot' referrence. Use the current instruction pointer */ 1181 addr = instruction_ptr + address->offset; 1182 } else if (address->symbol->type == UNINITIALIZED) { 1183 /* forward reference */ 1184 addr = address->offset; 1185 instr->patch_label = address->symbol; 1186 } else 1187 addr = address->symbol->info.linfo->address + address->offset; 1188 f3_instr->opcode_addr = (opcode << 1) 1189 | ((addr >> 8) & 0x01); 1190 f3_instr->address = addr & 0xff; 1191 f3_instr->source = src->symbol->info.rinfo->address 1192 + src->offset; 1193 f3_instr->immediate = immed->value; 1194 symlist_free(&immed->referenced_syms); 1195 instruction_ptr++; 1196} 1197 1198static void 1199test_readable_symbol(symbol) 1200 symbol_t *symbol; 1201{ 1202 if (symbol->info.rinfo->mode == WO) { 1203 stop("Write Only register specified as source", 1204 EX_DATAERR); 1205 /* NOTREACHED */ 1206 } 1207} 1208 1209static void 1210test_writable_symbol(symbol) 1211 symbol_t *symbol; 1212{ 1213 if (symbol->info.rinfo->mode == RO) { 1214 stop("Read Only register specified as destination", 1215 EX_DATAERR); 1216 /* NOTREACHED */ 1217 } 1218} 1219 1220static void 1221type_check(symbol, expression, opcode) 1222 symbol_t *symbol; 1223 expression_t *expression; 1224 int opcode; 1225{ 1226 symbol_node_t *node; 1227 int and_op; 1228 char buf[255]; 1229 1230 and_op = FALSE; 1231 if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ) 1232 and_op = TRUE; 1233 /* 1234 * Make sure that we aren't attempting to write something 1235 * that hasn't been defined. If this is an and operation, 1236 * this is a mask, so "undefined" bits are okay. 1237 */ 1238 if (and_op == FALSE 1239 && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) { 1240 snprintf(buf, sizeof(buf), 1241 "Invalid bit(s) 0x%x in immediate written to %s", 1242 expression->value & ~symbol->info.rinfo->valid_bitmask, 1243 symbol->name); 1244 stop(buf, EX_DATAERR); 1245 /* NOTREACHED */ 1246 } 1247 1248 /* 1249 * Now make sure that all of the symbols referenced by the 1250 * expression are defined for this register. 1251 */ 1252 if(symbol->info.rinfo->typecheck_masks != FALSE) { 1253 for(node = expression->referenced_syms.slh_first; 1254 node != NULL; 1255 node = node->links.sle_next) { 1256 if ((node->symbol->type == MASK 1257 || node->symbol->type == BIT) 1258 && symlist_search(&node->symbol->info.minfo->symrefs, 1259 symbol->name) == NULL) { 1260 snprintf(buf, sizeof(buf), 1261 "Invalid bit or mask %s " 1262 "for register %s", 1263 node->symbol->name, symbol->name); 1264 stop(buf, EX_DATAERR); 1265 /* NOTREACHED */ 1266 } 1267 } 1268 } 1269} 1270 1271static void 1272make_expression(immed, value) 1273 expression_t *immed; 1274 int value; 1275{ 1276 SLIST_INIT(&immed->referenced_syms); 1277 immed->value = value & 0xff; 1278} 1279 1280static void 1281add_conditional(symbol) 1282 symbol_t *symbol; 1283{ 1284 static int numoptions = 1; 1285 1286 if (symbol->type == UNINITIALIZED) { 1287 symbol->type = CONDITIONAL; 1288 initialize_symbol(symbol); 1289 symbol->info.condinfo->value = 0x01 << numoptions++; 1290 symlist_add(&patch_options, symbol, SYMLIST_INSERT_HEAD); 1291 } else if (symbol->type != CONDITIONAL) { 1292 stop("Conditional symbol mirrors other symbol", 1293 EX_DATAERR); 1294 /* NOTREACHED */ 1295 } 1296 cur_patch->options |= symbol->info.condinfo->value; 1297} 1298 1299void 1300yyerror(string) 1301 const char *string; 1302{ 1303 stop(string, EX_DATAERR); 1304} 1305