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 47 int yylineno; 48 char *yyfilename; 49 static symbol_t *cur_symbol; 50 static symtype cur_symtype; 51 static symbol_t *accumulator; 52 static symbol_ref_t allones; 53 static symbol_ref_t allzeros; 54 static symbol_ref_t none; 55 static symbol_ref_t sindex; 56 static int instruction_ptr; 57 static int sram_or_scb_offset; 58 static patch_t *cur_patch; 59 60 static void process_bitmask __P((int mask_type, symbol_t *sym, int mask)); 61 static void initialize_symbol __P((symbol_t *symbol)); 62 static void process_register __P((symbol_t **p_symbol)); 63 static void format_1_instr __P((int opcode, symbol_ref_t *dest, 64 expression_t *immed, symbol_ref_t *src, 65 int ret)); 66 static void format_2_instr __P((int opcode, symbol_ref_t *dest, 67 expression_t *places, symbol_ref_t *src, 68 int ret)); 69 static void format_3_instr __P((int opcode, symbol_ref_t *src, 70 expression_t *immed, symbol_ref_t *address)); 71 static void test_readable_symbol __P((symbol_t *symbol)); 72 static void test_writable_symbol __P((symbol_t *symbol)); 73 static void type_check __P((symbol_t *symbol, expression_t *expression, 74 int and_op)); 75 static void make_expression __P((expression_t *immed, int value)); 76 static 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 164 program: 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 183 include: 184 T_INCLUDE '<' T_PATH '>' 185 { include_file($3, BRACKETED_INCLUDE); } 186 | T_INCLUDE '"' T_PATH '"' 187 { include_file($3, QUOTED_INCLUDE); } 188 ; 189 190 register: 191 T_REGISTER { cur_symtype = REGISTER; } reg_definition 192 ; 193 194 reg_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 232 reg_attribute_list: 233 reg_attribute 234 | reg_attribute_list reg_attribute 235 ; 236 237 reg_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 251 reg_address: 252 T_ADDRESS T_NUMBER 253 { 254 cur_symbol->info.rinfo->address = $2; 255 } 256 ; 257 258 size: 259 T_SIZE T_NUMBER 260 { 261 cur_symbol->info.rinfo->size = $2; 262 } 263 ; 264 265 access_mode: 266 T_ACCESS_MODE T_MODE 267 { 268 cur_symbol->info.rinfo->mode = $2; 269 } 270 ; 271 272 bit_defn: 273 T_BIT T_SYMBOL T_NUMBER 274 { 275 process_bitmask(BIT, $2, $3); 276 } 277 ; 278 279 mask_defn: 280 T_MASK T_SYMBOL expression 281 { 282 process_bitmask(MASK, $2, $3.value); 283 } 284 ; 285 286 alias: 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 300 accumulator: 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 312 allones: 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 324 allzeros: 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 336 none: 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 348 sindex: 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 360 expression: 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 446 constant: 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 461 scratch_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 485 scb: 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 509 scb_or_sram_reg_list: 510 reg_definition 511 | scb_or_sram_reg_list reg_definition 512 ; 513 514 reg_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 543 destination: 544 reg_symbol 545 { 546 test_writable_symbol($1.symbol); 547 $$ = $1; 548 } 549 ; 550 551 immediate: 552 expression 553 { $$ = $1; } 554 ; 555 556 immediate_or_a: 557 expression 558 { 559 $$ = $1; 560 } 561 | T_A 562 { 563 SLIST_INIT(&$$.referenced_syms); 564 $$.value = 0; 565 } 566 ; 567 568 source: 569 reg_symbol 570 { 571 test_readable_symbol($1.symbol); 572 $$ = $1; 573 } 574 ; 575 576 opt_source: 577 { 578 $$.symbol = NULL; 579 $$.offset = 0; 580 } 581 | ',' source 582 { $$ = $2; } 583 ; 584 585 ret: 586 { $$ = 0; } 587 | T_RET 588 { $$ = 1; } 589 ; 590 591 label: 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 604 address: 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 637 conditional: 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 650 conditional: 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 668 conditional: 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 680 option_list: 681 '(' option_symbol_list ')' 682 | '!' option_list 683 { 684 cur_patch->negative = cur_patch->negative ? FALSE : TRUE; 685 } 686 ; 687 688 option_symbol_list: 689 T_SYMBOL 690 { 691 add_conditional($1); 692 } 693 | option_list '|' T_SYMBOL 694 { 695 add_conditional($3); 696 } 697 ; 698 699 f1_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 706 code: 707 f1_opcode destination ',' immediate_or_a opt_source ret ';' 708 { 709 format_1_instr($1, &$2, &$4, &$5, $6); 710 } 711 ; 712 713 code: 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 720 code: 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 730 code: 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 740 code: 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 754 code: 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 771 code: 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 781 code: 782 T_MVI destination ',' immediate_or_a ret ';' 783 { 784 format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5); 785 } 786 ; 787 788 code: 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 798 code: 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 808 code: 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 827 f2_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 834 code: 835 f2_opcode destination ',' expression opt_source ret ';' 836 { 837 format_2_instr($1, &$2, &$4, &$5, $6); 838 } 839 ; 840 841 jmp_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 848 jz_jnz: 849 T_JZ { $$ = AIC_OP_JZ; } 850 | T_JNZ { $$ = AIC_OP_JNZ; } 851 ; 852 853 je_jne: 854 T_JE { $$ = AIC_OP_JE; } 855 | T_JNE { $$ = AIC_OP_JNE; } 856 ; 857 858 code: 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 868 code: 869 T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';' 870 { 871 format_3_instr($5, &$2, &$4, &$6); 872 } 873 ; 874 875 code: 876 T_TEST source ',' immediate_or_a jz_jnz address ';' 877 { 878 format_3_instr($5, &$2, &$4, &$6); 879 } 880 ; 881 882 code: 883 T_CMP source ',' immediate_or_a je_jne address ';' 884 { 885 format_3_instr($5, &$2, &$4, &$6); 886 } 887 ; 888 889 code: 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 899 code: 900 T_MVI immediate jmp_jc_jnc_call address ';' 901 { 902 format_3_instr($3, &allzeros, &$2, &$4); 903 } 904 ; 905 906 %% 907 908 static void 909 process_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 956 static void 957 initialize_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 1037 static void 1038 process_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 1061 static void 1062 format_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 1095 static void 1096 format_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 1159 static void 1160 format_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 1198 static void 1199 test_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 1209 static void 1210 test_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 1220 static void 1221 type_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 1271 static void 1272 make_expression(immed, value) 1273 expression_t *immed; 1274 int value; 1275 { 1276 SLIST_INIT(&immed->referenced_syms); 1277 immed->value = value & 0xff; 1278 } 1279 1280 static void 1281 add_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 1299 void 1300 yyerror(string) 1301 const char *string; 1302 { 1303 stop(string, EX_DATAERR); 1304 } 1305