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); ...@@ -28,6 +28,7 @@ extern int yyparse(void);
extern int yylex(void); extern int yylex(void);
static struct operand * store_oper_sanity(struct operand *oper); static struct operand * store_oper_sanity(struct operand *oper);
static void assembler_assertion_failed(void);
/* The current .section */ /* The current .section */
extern int section; extern int section;
...@@ -38,9 +39,9 @@ extern struct initvals_sect *cur_initvals_sect; ...@@ -38,9 +39,9 @@ extern struct initvals_sect *cur_initvals_sect;
%token SECTION_TEXT SECTION_IVALS %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 %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 { ...@@ -55,10 +56,12 @@ line : line_terminator {
} }
| line statement line_terminator { | line statement line_terminator {
struct statement *s = $2; struct statement *s = $2;
if (section != SECTION_TEXT) if (s) {
yyerror("Microcode text instruction in non .text section"); if (section != SECTION_TEXT)
memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo)); yyerror("Microcode text instruction in non .text section");
list_add_tail(&s->list, &infile.sl); memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo));
list_add_tail(&s->list, &infile.sl);
}
} }
| line section_switch line_terminator { | line section_switch line_terminator {
} }
...@@ -149,11 +152,15 @@ ivals_write : IVAL_MMIO16 imm_value COMMA imm_value { ...@@ -149,11 +152,15 @@ ivals_write : IVAL_MMIO16 imm_value COMMA imm_value {
; ;
statement : asmdir { statement : asmdir {
struct statement *s = xmalloc(sizeof(struct statement)); struct asmdir *ad = $1;
INIT_LIST_HEAD(&s->list); if (ad) {
s->type = STMT_ASMDIR; struct statement *s = xmalloc(sizeof(struct statement));
s->u.asmdir = $1; INIT_LIST_HEAD(&s->list);
$$ = s; s->type = STMT_ASMDIR;
s->u.asmdir = $1;
$$ = s;
} else
$$ = NULL;
} }
| label { | label {
struct statement *s = xmalloc(sizeof(struct statement)); struct statement *s = xmalloc(sizeof(struct statement));
...@@ -509,6 +516,43 @@ asmdir : ASM_ARCH hexnum_decnum { ...@@ -509,6 +516,43 @@ asmdir : ASM_ARCH hexnum_decnum {
ad->u.start = label; ad->u.start = label;
$$ = ad; $$ = 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 { label : LABEL {
...@@ -1308,3 +1352,8 @@ static struct operand * store_oper_sanity(struct operand *oper) ...@@ -1308,3 +1352,8 @@ static struct operand * store_oper_sanity(struct operand *oper)
} }
return oper; return oper;
} }
static void assembler_assertion_failed(void)
{
yyerror("Assembler %assert failed");
}
...@@ -51,6 +51,7 @@ NEWLINE ((\r)|(\n)|(\r\n)) ...@@ -51,6 +51,7 @@ NEWLINE ((\r)|(\n)|(\r\n))
^{WS}*"%"{WS}*arch { update_lineinfo(); return ASM_ARCH; } ^{WS}*"%"{WS}*arch { update_lineinfo(); return ASM_ARCH; }
^{WS}*"%"{WS}*start { update_lineinfo(); return ASM_START; } ^{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}*\.text{WS}*$ { update_lineinfo(); return SECTION_TEXT; }
^{WS}*\.initvals/\({IDENTIFIER}\) { update_lineinfo(); return SECTION_IVALS; } ^{WS}*\.initvals/\({IDENTIFIER}\) { update_lineinfo(); return SECTION_IVALS; }
...@@ -67,6 +68,10 @@ lr/[0-3] { update_lineinfo(); return LR; } ...@@ -67,6 +68,10 @@ lr/[0-3] { update_lineinfo(); return LR; }
\( { update_lineinfo(); return PAREN_OPEN; } \( { update_lineinfo(); return PAREN_OPEN; }
\) { update_lineinfo(); return PAREN_CLOSE; } \) { 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 PLUS; }
\- { update_lineinfo(); return MINUS; } \- { update_lineinfo(); return MINUS; }
\* { update_lineinfo(); return MULTIPLY; } \* { update_lineinfo(); return MULTIPLY; }
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
#define ECOND_MAC_ON (0x20 | 4) #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 .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