fwcutter/make: Avoid _DEFAULT_SOURCE warning
[b43-tools.git] / assembler / parser.y
index e75d9f4d371873ae1d0ab2e7d3f3c757e313ad5f..358abbb38000f5a5a6b5e1182af15bafd11e9464 100644 (file)
@@ -1,7 +1,7 @@
 %{
 
 /*
- *   Copyright (C) 2006-2007  Michael Buesch <mb@bu3sch.de>
+ *   Copyright (C) 2006-2010  Michael Buesch <m@bues.ch>
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2
@@ -23,7 +23,7 @@
 #include <stdint.h>
 
 extern char *yytext;
-extern void yyerror(char *);
+extern void yyerror(const char *);
 extern int yyparse(void);
 extern int yylex(void);
 
@@ -43,9 +43,9 @@ extern struct initvals_sect *cur_initvals_sect;
 
 %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_MUL 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_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS 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
 
@@ -149,6 +149,13 @@ ivals_write        : IVAL_MMIO16 imm_value COMMA imm_value {
                        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 {
@@ -169,6 +176,13 @@ statement  : asmdir {
                        s->u.label = $1;
                        $$ = s;
                  }
+               | insn_mul {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
                | insn_add {
                        struct statement *s = xmalloc(sizeof(struct statement));
                        INIT_LIST_HEAD(&s->list);
@@ -386,6 +400,34 @@ statement  : asmdir {
                        s->u.insn = $1;
                        $$ = s;
                  }
+               | insn_jdn {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
+               | insn_jdpz {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
+               | insn_jdp {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
+               | insn_jdnz {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
                | insn_jl {
                        struct statement *s = xmalloc(sizeof(struct statement));
                        INIT_LIST_HEAD(&s->list);
@@ -449,6 +491,13 @@ statement  : asmdir {
                        s->u.insn = $1;
                        $$ = s;
                  }
+               | insn_calls {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
                | insn_ret {
                        struct statement *s = xmalloc(sizeof(struct statement));
                        INIT_LIST_HEAD(&s->list);
@@ -456,6 +505,13 @@ statement  : asmdir {
                        s->u.insn = $1;
                        $$ = s;
                  }
+               | insn_rets {
+                       struct statement *s = xmalloc(sizeof(struct statement));
+                       INIT_LIST_HEAD(&s->list);
+                       s->type = STMT_INSN;
+                       s->u.insn = $1;
+                       $$ = s;
+                 }
                | insn_tkiph {
                        struct statement *s = xmalloc(sizeof(struct statement));
                        INIT_LIST_HEAD(&s->list);
@@ -516,7 +572,12 @@ asmdir             : ASM_ARCH hexnum_decnum {
                        ad->u.start = label;
                        $$ = ad;
                  }
-               | ASM_ASSERT assertion {
+               | asm_assert {
+                       $$ = NULL;
+                 }
+               ;
+
+asm_assert     : ASM_ASSERT assertion {
                        unsigned int ok = (unsigned int)(unsigned long)$2;
                        if (!ok)
                                assembler_assertion_failed();
@@ -565,6 +626,15 @@ label              : LABEL {
                  }
                ;
 
+/* multiply */
+insn_mul       : OP_MUL operlist_3 {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       insn->op = OP_MUL;
+                       insn->operands = $2;
+                       $$ = insn;
+                 }
+               ;
+
 /* add */
 insn_add       : OP_ADD operlist_3 {
                        struct instruction *insn = xmalloc(sizeof(struct instruction));
@@ -871,6 +941,38 @@ insn_jnzx  : OP_JNZX extended_operlist {
                  }
                ;
 
+insn_jdn       : OP_JDN operlist_3 {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       insn->op = OP_JDN;
+                       insn->operands = $2;
+                       $$ = insn;
+                 }
+               ;
+
+insn_jdpz      : OP_JDPZ operlist_3 {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       insn->op = OP_JDPZ;
+                       insn->operands = $2;
+                       $$ = insn;
+                 }
+               ;
+
+insn_jdp       : OP_JDP operlist_3 {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       insn->op = OP_JDP;
+                       insn->operands = $2;
+                       $$ = insn;
+                 }
+               ;
+
+insn_jdnz      : OP_JDNZ operlist_3 {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       insn->op = OP_JDNZ;
+                       insn->operands = $2;
+                       $$ = insn;
+                 }
+               ;
+
 insn_jext      : OP_JEXT external_jump_operands {
                        struct instruction *insn = xmalloc(sizeof(struct instruction));
                        insn->op = OP_JEXT;
@@ -910,6 +1012,24 @@ insn_call : OP_CALL linkreg COMMA labelref {
                  }
                ;
 
+insn_calls     :  OP_CALLS labelref {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       struct operlist *ol = xmalloc(sizeof(struct operlist));
+                       struct operand *oper_r0 = xmalloc(sizeof(struct operand));
+                       struct registr *r0 = xmalloc(sizeof(struct registr));
+                       r0->type = GPR;
+                       r0->nr = 0;
+                       oper_r0->type = OPER_REG;
+                       oper_r0->u.reg = r0;
+                       ol->oper[0] = oper_r0;
+                       ol->oper[1] = oper_r0;
+                       ol->oper[2] = $2;
+                       insn->op = OP_CALLS;
+                       insn->operands = ol;
+                       $$ = insn;
+                 }
+               ;
+
 insn_ret       : OP_RET linkreg COMMA linkreg {
                        struct instruction *insn = xmalloc(sizeof(struct instruction));
                        struct operlist *ol = xmalloc(sizeof(struct operlist));
@@ -931,6 +1051,27 @@ insn_ret  : OP_RET linkreg COMMA linkreg {
                  }
                ;
 
+insn_rets      : OP_RETS {
+                       struct instruction *insn = xmalloc(sizeof(struct instruction));
+                       struct operlist *ol = xmalloc(sizeof(struct operlist));
+                       struct operand *oper_r0 = xmalloc(sizeof(struct operand));
+                       struct operand *oper_zero = xmalloc(sizeof(struct operand));
+                       struct registr *r0 = xmalloc(sizeof(struct registr));
+                       oper_zero->type = OPER_RAW;
+                       oper_zero->u.raw = 0;
+                       r0->type = GPR;
+                       r0->nr = 0;
+                       oper_r0->type = OPER_REG;
+                       oper_r0->u.reg = r0;
+                       ol->oper[0] = oper_r0;
+                       ol->oper[1] = oper_r0;
+                       ol->oper[2] = oper_zero;
+                       insn->op = OP_RETS;
+                       insn->operands = ol;
+                       $$ = insn;
+                 }
+               ;
+
 insn_tkiph     : OP_TKIPH operlist_2 {
                        struct instruction *insn = xmalloc(sizeof(struct instruction));
                        struct operlist *ol = $2;
@@ -1201,6 +1342,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;
@@ -1326,7 +1471,7 @@ identifier        : IDENT {
 int section = SECTION_TEXT; /* default to .text section */
 struct initvals_sect *cur_initvals_sect;
 
-void yyerror(char *str)
+void yyerror(const char *str)
 {
        unsigned int i;