Commit 3bd4f014 authored by Michael Büsch's avatar Michael Büsch

Add support for assemble-time assertions.

Signed-off-by: Michael Büsch's avatarMichael Buesch <mb@bu3sch.de>
parent 5f3a128f
......@@ -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,11 +56,13 @@ line : line_terminator {
}
| line statement line_terminator {
struct statement *s = $2;
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 {
}
| line ivals_write line_terminator {
......@@ -149,11 +152,15 @@ ivals_write : IVAL_MMIO16 imm_value COMMA imm_value {
;
statement : asmdir {
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,43 @@ asmdir : ASM_ARCH hexnum_decnum {
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 {
......@@ -1308,3 +1352,8 @@ static struct operand * store_oper_sanity(struct operand *oper)
}
return oper;
}
static void assembler_assertion_failed(void)
{
yyerror("Assembler %assert failed");
}
......@@ -51,6 +51,7 @@ NEWLINE ((\r)|(\n)|(\r\n))
^{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; }
......@@ -67,6 +68,10 @@ lr/[0-3] { update_lineinfo(); return LR; }
\( { 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; }
......
......@@ -28,6 +28,10 @@
#define ECOND_MAC_ON (0x20 | 4)
%assert ((((1))) == ((((2 - 1) & 0xFF))))
%assert ((1 == 2) || (1 == (0xFF & 1)))
%assert (1 != (~1))
%assert ((1 == (2 - 1)) && (2 == 2))
.text
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment