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;
%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
}
| 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 {
}
;
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));
ad->u.start = label;
$$ = ad;
}
+ | 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 {
}
return oper;
}
+
+static void assembler_assertion_failed(void)
+{
+ yyerror("Assembler %assert failed");
+}
^{WS}*"%"{WS}*arch { update_lineinfo(); return ASM_ARCH; }
^{WS}*"%"{WS}*start { update_lineinfo(); return ASM_START; }
+^{WS}*"%"{WS}*assert { update_lineinfo(); return ASM_ASSERT; }
^{WS}*\.text{WS}*$ { update_lineinfo(); return SECTION_TEXT; }
^{WS}*\.initvals/\({IDENTIFIER}\) { update_lineinfo(); return SECTION_IVALS; }
\( { update_lineinfo(); return PAREN_OPEN; }
\) { update_lineinfo(); return PAREN_CLOSE; }
+== { update_lineinfo(); return EQUAL; }
+!= { update_lineinfo(); return NOT_EQUAL; }
+\|\| { update_lineinfo(); return LOGICAL_OR; }
+\&\& { update_lineinfo(); return LOGICAL_AND; }
\+ { update_lineinfo(); return PLUS; }
\- { update_lineinfo(); return MINUS; }
\* { update_lineinfo(); return MULTIPLY; }