X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=assembler%2Fparser.y;h=50065bab65e6b7f514c800052aaea51d0c393cf4;hb=c2202e82a4da7ec25c1d5866f617b644bdcbb73e;hp=f0151211741a9073e532eb690fbf681dcb2f1d99;hpb=5f3a128fbff51dd6fe6f7549d777cf3bdef62982;p=b43-tools.git diff --git a/assembler/parser.y b/assembler/parser.y index f015121..50065ba 100644 --- a/assembler/parser.y +++ b/assembler/parser.y @@ -28,6 +28,7 @@ extern int yyparse(void); extern int yylex(void); static struct operand * store_oper_sanity(struct operand *oper); +static void assembler_assertion_failed(void); /* The current .section */ extern int section; @@ -38,9 +39,9 @@ extern struct initvals_sect *cur_initvals_sect; %token SECTION_TEXT SECTION_IVALS -%token ASM_ARCH ASM_START SPR GPR OFFR LR COMMA SEMICOLON BRACK_OPEN BRACK_CLOSE PAREN_OPEN PAREN_CLOSE HEXNUM DECNUM ARCH_NEWWORLD ARCH_OLDWORLD LABEL IDENT LABELREF +%token ASM_ARCH ASM_START ASM_ASSERT SPR GPR OFFR LR COMMA SEMICOLON BRACK_OPEN BRACK_CLOSE PAREN_OPEN PAREN_CLOSE HEXNUM DECNUM ARCH_NEWWORLD ARCH_OLDWORLD LABEL IDENT LABELREF -%token PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT +%token EQUAL NOT_EQUAL LOGICAL_OR LOGICAL_AND PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT %token OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_CALL OP_RET OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE @@ -55,10 +56,12 @@ line : line_terminator { } | line statement line_terminator { struct statement *s = $2; - if (section != SECTION_TEXT) - yyerror("Microcode text instruction in non .text section"); - memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo)); - list_add_tail(&s->list, &infile.sl); + if (s) { + if (section != SECTION_TEXT) + yyerror("Microcode text instruction in non .text section"); + memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo)); + list_add_tail(&s->list, &infile.sl); + } } | line section_switch line_terminator { } @@ -149,11 +152,15 @@ ivals_write : IVAL_MMIO16 imm_value COMMA imm_value { ; statement : asmdir { - struct statement *s = xmalloc(sizeof(struct statement)); - INIT_LIST_HEAD(&s->list); - s->type = STMT_ASMDIR; - s->u.asmdir = $1; - $$ = s; + struct asmdir *ad = $1; + if (ad) { + struct statement *s = xmalloc(sizeof(struct statement)); + INIT_LIST_HEAD(&s->list); + s->type = STMT_ASMDIR; + s->u.asmdir = $1; + $$ = s; + } else + $$ = NULL; } | label { struct statement *s = xmalloc(sizeof(struct statement)); @@ -509,6 +516,48 @@ asmdir : ASM_ARCH hexnum_decnum { ad->u.start = label; $$ = ad; } + | asm_assert { + $$ = NULL; + } + ; + +asm_assert : ASM_ASSERT assertion { + unsigned int ok = (unsigned int)(unsigned long)$2; + if (!ok) + assembler_assertion_failed(); + $$ = NULL; + } + ; + +assertion : PAREN_OPEN assert_expr PAREN_CLOSE { + $$ = $2; + } + | PAREN_OPEN assertion LOGICAL_OR assertion PAREN_CLOSE { + unsigned int a = (unsigned int)(unsigned long)$2; + unsigned int b = (unsigned int)(unsigned long)$4; + unsigned int result = (a || b); + $$ = (void *)(unsigned long)result; + } + | PAREN_OPEN assertion LOGICAL_AND assertion PAREN_CLOSE { + unsigned int a = (unsigned int)(unsigned long)$2; + unsigned int b = (unsigned int)(unsigned long)$4; + unsigned int result = (a && b); + $$ = (void *)(unsigned long)result; + } + ; + +assert_expr : imm_value EQUAL imm_value { + unsigned int a = (unsigned int)(unsigned long)$1; + unsigned int b = (unsigned int)(unsigned long)$3; + unsigned int result = (a == b); + $$ = (void *)(unsigned long)result; + } + | imm_value NOT_EQUAL imm_value { + unsigned int a = (unsigned int)(unsigned long)$1; + unsigned int b = (unsigned int)(unsigned long)$3; + unsigned int result = (a != b); + $$ = (void *)(unsigned long)result; + } ; label : LABEL { @@ -1157,6 +1206,10 @@ complex_imm : PAREN_OPEN complex_imm_arg complex_imm_oper complex_imm_arg PAREN_ | PAREN_OPEN complex_imm PAREN_CLOSE { $$ = $2; } + | PAREN_OPEN asm_assert PAREN_CLOSE { + /* Inline assertion. Always return zero */ + $$ = (void *)(unsigned long)(unsigned int)0; + } | PAREN_OPEN BITW_NOT complex_imm PAREN_CLOSE { unsigned long n = (unsigned long)$3; n = ~n; @@ -1308,3 +1361,8 @@ static struct operand * store_oper_sanity(struct operand *oper) } return oper; } + +static void assembler_assertion_failed(void) +{ + yyerror("Assembler %assert failed"); +}