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
-%token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32
+%token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32 IVAL_TRAM
%start line
}
| 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 {
}
iop->args[2] = (unsigned int)(unsigned long)$6;
$$ = iop;
}
+ | IVAL_TRAM imm_value COMMA imm_value {
+ struct initval_op *iop = xmalloc(sizeof(struct initval_op));
+ iop->type = IVAL_W_TRAM;
+ iop->args[0] = (unsigned int)(unsigned long)$2;
+ iop->args[1] = (unsigned int)(unsigned long)$4;
+ $$ = iop;
+ }
;
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 {
+ $$ = 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 {
}
;
-extended_operlist : decnum COMMA decnum COMMA operand COMMA operand COMMA operand {
+extended_operlist : imm_value COMMA imm_value COMMA operand COMMA operand COMMA operand {
struct operlist *ol = xmalloc(sizeof(struct operlist));
struct operand *mask_oper = xmalloc(sizeof(struct operand));
struct operand *shift_oper = xmalloc(sizeof(struct operand));
| 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;
}
return oper;
}
+
+static void assembler_assertion_failed(void)
+{
+ yyerror("Assembler %assert failed");
+}