b43-asm: Add an option to print the code sizes after assembling.
[b43-tools.git] / assembler / parser.y
index 753be084c1d98925335a3fc4cbec1cfe30750beb..4bdb9ec6dc8516b2335961057a3a61decdd1760d 100644 (file)
@@ -38,7 +38,7 @@ extern struct initvals_sect *cur_initvals_sect;
 
 %token SECTION_TEXT SECTION_IVALS
 
-%token ASM_ARCH ASM_START SPR GPR OFFR LR COMMA BRACK_OPEN BRACK_CLOSE PAREN_OPEN PAREN_CLOSE HEXNUM DECNUM ARCH_NEWWORLD ARCH_OLDWORLD LABEL IDENT LABELREF
+%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 PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT
 
@@ -50,17 +50,19 @@ extern struct initvals_sect *cur_initvals_sect;
 
 %%
 
-line   : /* empty */
-       | line statement {
+line   : line_terminator {
+               /* empty */
+         }
+       | 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);
          }
-       | line section_switch {
+       | line section_switch line_terminator {
          }
-       | line ivals_write {
+       | line ivals_write line_terminator {
                struct initval_op *io = $2;
                if (section != SECTION_IVALS)
                        yyerror("InitVals write in non .initvals section");
@@ -70,6 +72,11 @@ line : /* empty */
          }
        ;
 
+/* Allow terminating lines with the ";" char */
+line_terminator : /* Nothing */
+               | SEMICOLON line_terminator
+               ;
+
 section_switch : SECTION_TEXT {
                        section = SECTION_TEXT;
                  }
@@ -487,8 +494,11 @@ statement  : asmdir {
                ;
 
 /* ASM directives */
-asmdir         : asmarch {
-                       $$ = $1;
+asmdir         : ASM_ARCH hexnum_decnum {
+                       struct asmdir *ad = xmalloc(sizeof(struct asmdir));
+                       ad->type = ADIR_ARCH;
+                       ad->u.arch = (unsigned int)(unsigned long)$2;
+                       $$ = ad;
                  }
                | ASM_START identifier {
                        struct asmdir *ad = xmalloc(sizeof(struct asmdir));
@@ -501,20 +511,6 @@ asmdir             : asmarch {
                  }
                ;
 
-asmarch                : ASM_ARCH ARCH_NEWWORLD {
-                       struct asmdir *ad = xmalloc(sizeof(struct asmdir));
-                       ad->type = ADIR_ARCH;
-                       ad->u.arch = NEWWORLD;
-                       $$ = ad;
-                 }
-               | ASM_ARCH ARCH_OLDWORLD {
-                       struct asmdir *ad = xmalloc(sizeof(struct asmdir));
-                       ad->type = ADIR_ARCH;
-                       ad->u.arch = OLDWORLD;
-                       $$ = ad;
-                 }
-               ;
-
 label          : LABEL {
                        struct label *label = xmalloc(sizeof(struct label));
                        char *l;
@@ -1008,15 +1004,13 @@ extended_operlist : decnum COMMA decnum COMMA operand COMMA operand COMMA operan
                  }
                ;
 
-external_jump_operands : hexnum COMMA operand COMMA operand COMMA labelref {
+external_jump_operands : imm COMMA labelref {
                        struct operlist *ol = xmalloc(sizeof(struct operlist));
                        struct operand *cond = xmalloc(sizeof(struct operand));
-                       cond->type = OPER_RAW;
-                       cond->u.raw = (unsigned long)$1;
+                       cond->type = OPER_IMM;
+                       cond->u.imm = $1;
                        ol->oper[0] = cond;
                        ol->oper[1] = $3;
-                       ol->oper[2] = $5;
-                       ol->oper[3] = $7;
                        $$ = ol;
                  }
                ;
@@ -1088,27 +1082,26 @@ reg             : GPR regnr {
                  }
                ;
 
-mem            : BRACK_OPEN hexnum_decnum BRACK_CLOSE {
+mem            : BRACK_OPEN imm BRACK_CLOSE {
                        struct memory *mem = xmalloc(sizeof(struct memory));
+                       struct immediate *offset_imm = $2;
                        mem->type = MEM_DIRECT;
-                       mem->offset = (unsigned long)$2;
+                       mem->offset = offset_imm->imm;
+                       free(offset_imm);
                        $$ = mem;
                  }
-               | BRACK_OPEN hexnum_decnum COMMA OFFR regnr BRACK_CLOSE {
+               | BRACK_OPEN imm COMMA OFFR regnr BRACK_CLOSE {
                        struct memory *mem = xmalloc(sizeof(struct memory));
+                       struct immediate *offset_imm = $2;
                        mem->type = MEM_INDIRECT;
-                       mem->offset = (unsigned long)$2;
+                       mem->offset = offset_imm->imm;
+                       free(offset_imm);
                        mem->offr_nr = (unsigned long)$5;
                        $$ = mem;
                  }
                ;
 
-imm            : hexnum {
-                       struct immediate *imm = xmalloc(sizeof(struct immediate));
-                       imm->imm = (unsigned long)$1;
-                       $$ = imm;
-                 }
-               | decnum {
+imm            : hexnum_decnum {
                        struct immediate *imm = xmalloc(sizeof(struct immediate));
                        imm->imm = (unsigned long)$1;
                        $$ = imm;