b43-asm: Terminate instructions with ; instead of |
[b43-tools.git] / assembler / parser.y
1 %{
2
3 /*
4  *   Copyright (C) 2006-2007  Michael Buesch <mb@bu3sch.de>
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License version 2
8  *   as published by the Free Software Foundation.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  */
15
16 #include "main.h"
17 #include "initvals.h"
18 #include "util.h"
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdint.h>
24
25 extern char *yytext;
26 extern void yyerror(char *);
27 extern int yyparse(void);
28 extern int yylex(void);
29
30 static struct operand * store_oper_sanity(struct operand *oper);
31
32 /* The current .section */
33 extern int section;
34 /* Pointer to the current initvals section data structure. */
35 extern struct initvals_sect *cur_initvals_sect;
36
37 %}
38
39 %token SECTION_TEXT SECTION_IVALS
40
41 %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
42
43 %token PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT
44
45 %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
46
47 %token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32
48
49 %start line
50
51 %%
52
53 line    : line_terminator {
54                 /* empty */
55           }
56         | line statement line_terminator {
57                 struct statement *s = $2;
58                 if (section != SECTION_TEXT)
59                         yyerror("Microcode text instruction in non .text section");
60                 memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo));
61                 list_add_tail(&s->list, &infile.sl);
62           }
63         | line section_switch line_terminator {
64           }
65         | line ivals_write line_terminator {
66                 struct initval_op *io = $2;
67                 if (section != SECTION_IVALS)
68                         yyerror("InitVals write in non .initvals section");
69                 memcpy(&io->info, &cur_lineinfo, sizeof(struct lineinfo));
70                 INIT_LIST_HEAD(&io->list);
71                 list_add_tail(&io->list, &cur_initvals_sect->ops);
72           }
73         ;
74
75 /* Allow terminating lines with the ";" char */
76 line_terminator : /* Nothing */
77                 | SEMICOLON line_terminator
78                 ;
79
80 section_switch  : SECTION_TEXT {
81                         section = SECTION_TEXT;
82                   }
83                 | SECTION_IVALS PAREN_OPEN identifier PAREN_CLOSE {
84                         const char *sectname = $3;
85                         struct initvals_sect *s;
86                         cur_initvals_sect = NULL;
87                         /* Search if there already is a section by that name. */
88                         list_for_each_entry(s, &infile.ivals, list) {
89                                 if (strcmp(sectname, s->name) == 0)
90                                         cur_initvals_sect = s;
91                         }
92                         if (!cur_initvals_sect) {
93                                 /* Not found, create a new one. */
94                                 s = xmalloc(sizeof(struct initvals_sect));
95                                 s->name = sectname;
96                                 INIT_LIST_HEAD(&s->ops);
97                                 INIT_LIST_HEAD(&s->list);
98                                 list_add_tail(&s->list, &infile.ivals);
99                                 cur_initvals_sect = s;
100                         }
101                         section = SECTION_IVALS;
102                   }
103                 ;
104
105 ivals_write     : IVAL_MMIO16 hexnum_decnum COMMA hexnum_decnum {
106                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
107                         iop->type = IVAL_W_MMIO16;
108                         iop->args[0] = (unsigned int)(unsigned long)$2;
109                         iop->args[1] = (unsigned int)(unsigned long)$4;
110                         $$ = iop;
111                   }
112                 | IVAL_MMIO32 hexnum_decnum COMMA hexnum_decnum {
113                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
114                         iop->type = IVAL_W_MMIO32;
115                         iop->args[0] = (unsigned int)(unsigned long)$2;
116                         iop->args[1] = (unsigned int)(unsigned long)$4;
117                         $$ = iop;
118                   }
119                 | IVAL_PHY hexnum_decnum COMMA hexnum_decnum {
120                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
121                         iop->type = IVAL_W_PHY;
122                         iop->args[0] = (unsigned int)(unsigned long)$2;
123                         iop->args[1] = (unsigned int)(unsigned long)$4;
124                         $$ = iop;
125                   }
126                 | IVAL_RADIO hexnum_decnum COMMA hexnum_decnum {
127                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
128                         iop->type = IVAL_W_RADIO;
129                         iop->args[0] = (unsigned int)(unsigned long)$2;
130                         iop->args[1] = (unsigned int)(unsigned long)$4;
131                         $$ = iop;
132                   }
133                 | IVAL_SHM16 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
134                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
135                         iop->type = IVAL_W_SHM16;
136                         iop->args[0] = (unsigned int)(unsigned long)$2;
137                         iop->args[1] = (unsigned int)(unsigned long)$4;
138                         iop->args[2] = (unsigned int)(unsigned long)$6;
139                         $$ = iop;
140                   }
141                 | IVAL_SHM32 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
142                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
143                         iop->type = IVAL_W_SHM32;
144                         iop->args[0] = (unsigned int)(unsigned long)$2;
145                         iop->args[1] = (unsigned int)(unsigned long)$4;
146                         iop->args[2] = (unsigned int)(unsigned long)$6;
147                         $$ = iop;
148                   }
149                 ;
150
151 statement       : asmdir {
152                         struct statement *s = xmalloc(sizeof(struct statement));
153                         INIT_LIST_HEAD(&s->list);
154                         s->type = STMT_ASMDIR;
155                         s->u.asmdir = $1;
156                         $$ = s;
157                   }
158                 | label {
159                         struct statement *s = xmalloc(sizeof(struct statement));
160                         INIT_LIST_HEAD(&s->list);
161                         s->type = STMT_LABEL;
162                         s->u.label = $1;
163                         $$ = s;
164                   }
165                 | insn_add {
166                         struct statement *s = xmalloc(sizeof(struct statement));
167                         INIT_LIST_HEAD(&s->list);
168                         s->type = STMT_INSN;
169                         s->u.insn = $1;
170                         $$ = s;
171                   }
172                 | insn_addsc {
173                         struct statement *s = xmalloc(sizeof(struct statement));
174                         INIT_LIST_HEAD(&s->list);
175                         s->type = STMT_INSN;
176                         s->u.insn = $1;
177                         $$ = s;
178                   }
179                 | insn_addc {
180                         struct statement *s = xmalloc(sizeof(struct statement));
181                         INIT_LIST_HEAD(&s->list);
182                         s->type = STMT_INSN;
183                         s->u.insn = $1;
184                         $$ = s;
185                   }
186                 | insn_addscc {
187                         struct statement *s = xmalloc(sizeof(struct statement));
188                         INIT_LIST_HEAD(&s->list);
189                         s->type = STMT_INSN;
190                         s->u.insn = $1;
191                         $$ = s;
192                   }
193                 | insn_sub {
194                         struct statement *s = xmalloc(sizeof(struct statement));
195                         INIT_LIST_HEAD(&s->list);
196                         s->type = STMT_INSN;
197                         s->u.insn = $1;
198                         $$ = s;
199                   }
200                 | insn_subsc {
201                         struct statement *s = xmalloc(sizeof(struct statement));
202                         INIT_LIST_HEAD(&s->list);
203                         s->type = STMT_INSN;
204                         s->u.insn = $1;
205                         $$ = s;
206                   }
207                 | insn_subc {
208                         struct statement *s = xmalloc(sizeof(struct statement));
209                         INIT_LIST_HEAD(&s->list);
210                         s->type = STMT_INSN;
211                         s->u.insn = $1;
212                         $$ = s;
213                   }
214                 | insn_subscc {
215                         struct statement *s = xmalloc(sizeof(struct statement));
216                         INIT_LIST_HEAD(&s->list);
217                         s->type = STMT_INSN;
218                         s->u.insn = $1;
219                         $$ = s;
220                   }
221                 | insn_sra {
222                         struct statement *s = xmalloc(sizeof(struct statement));
223                         INIT_LIST_HEAD(&s->list);
224                         s->type = STMT_INSN;
225                         s->u.insn = $1;
226                         $$ = s;
227                   }
228                 | insn_or {
229                         struct statement *s = xmalloc(sizeof(struct statement));
230                         INIT_LIST_HEAD(&s->list);
231                         s->type = STMT_INSN;
232                         s->u.insn = $1;
233                         $$ = s;
234                   }
235                 | insn_and {
236                         struct statement *s = xmalloc(sizeof(struct statement));
237                         INIT_LIST_HEAD(&s->list);
238                         s->type = STMT_INSN;
239                         s->u.insn = $1;
240                         $$ = s;
241                   }
242                 | insn_xor {
243                         struct statement *s = xmalloc(sizeof(struct statement));
244                         INIT_LIST_HEAD(&s->list);
245                         s->type = STMT_INSN;
246                         s->u.insn = $1;
247                         $$ = s;
248                   }
249                 | insn_sr {
250                         struct statement *s = xmalloc(sizeof(struct statement));
251                         INIT_LIST_HEAD(&s->list);
252                         s->type = STMT_INSN;
253                         s->u.insn = $1;
254                         $$ = s;
255                   }
256                 | insn_srx {
257                         struct statement *s = xmalloc(sizeof(struct statement));
258                         INIT_LIST_HEAD(&s->list);
259                         s->type = STMT_INSN;
260                         s->u.insn = $1;
261                         $$ = s;
262                   }
263                 | insn_sl {
264                         struct statement *s = xmalloc(sizeof(struct statement));
265                         INIT_LIST_HEAD(&s->list);
266                         s->type = STMT_INSN;
267                         s->u.insn = $1;
268                         $$ = s;
269                   }
270                 | insn_rl {
271                         struct statement *s = xmalloc(sizeof(struct statement));
272                         INIT_LIST_HEAD(&s->list);
273                         s->type = STMT_INSN;
274                         s->u.insn = $1;
275                         $$ = s;
276                   }
277                 | insn_rr {
278                         struct statement *s = xmalloc(sizeof(struct statement));
279                         INIT_LIST_HEAD(&s->list);
280                         s->type = STMT_INSN;
281                         s->u.insn = $1;
282                         $$ = s;
283                   }
284                 | insn_nand {
285                         struct statement *s = xmalloc(sizeof(struct statement));
286                         INIT_LIST_HEAD(&s->list);
287                         s->type = STMT_INSN;
288                         s->u.insn = $1;
289                         $$ = s;
290                   }
291                 | insn_orx {
292                         struct statement *s = xmalloc(sizeof(struct statement));
293                         INIT_LIST_HEAD(&s->list);
294                         s->type = STMT_INSN;
295                         s->u.insn = $1;
296                         $$ = s;
297                   }
298                 | insn_mov {
299                         struct statement *s = xmalloc(sizeof(struct statement));
300                         INIT_LIST_HEAD(&s->list);
301                         s->type = STMT_INSN;
302                         s->u.insn = $1;
303                         $$ = s;
304                   }
305                 | insn_jmp {
306                         struct statement *s = xmalloc(sizeof(struct statement));
307                         INIT_LIST_HEAD(&s->list);
308                         s->type = STMT_INSN;
309                         s->u.insn = $1;
310                         $$ = s;
311                   }
312                 | insn_jand {
313                         struct statement *s = xmalloc(sizeof(struct statement));
314                         INIT_LIST_HEAD(&s->list);
315                         s->type = STMT_INSN;
316                         s->u.insn = $1;
317                         $$ = s;
318                   }
319                 | insn_jnand {
320                         struct statement *s = xmalloc(sizeof(struct statement));
321                         INIT_LIST_HEAD(&s->list);
322                         s->type = STMT_INSN;
323                         s->u.insn = $1;
324                         $$ = s;
325                   }
326                 | insn_js {
327                         struct statement *s = xmalloc(sizeof(struct statement));
328                         INIT_LIST_HEAD(&s->list);
329                         s->type = STMT_INSN;
330                         s->u.insn = $1;
331                         $$ = s;
332                   }
333                 | insn_jns {
334                         struct statement *s = xmalloc(sizeof(struct statement));
335                         INIT_LIST_HEAD(&s->list);
336                         s->type = STMT_INSN;
337                         s->u.insn = $1;
338                         $$ = s;
339                   }
340                 | insn_je {
341                         struct statement *s = xmalloc(sizeof(struct statement));
342                         INIT_LIST_HEAD(&s->list);
343                         s->type = STMT_INSN;
344                         s->u.insn = $1;
345                         $$ = s;
346                   }
347                 | insn_jne {
348                         struct statement *s = xmalloc(sizeof(struct statement));
349                         INIT_LIST_HEAD(&s->list);
350                         s->type = STMT_INSN;
351                         s->u.insn = $1;
352                         $$ = s;
353                   }
354                 | insn_jls {
355                         struct statement *s = xmalloc(sizeof(struct statement));
356                         INIT_LIST_HEAD(&s->list);
357                         s->type = STMT_INSN;
358                         s->u.insn = $1;
359                         $$ = s;
360                   }
361                 | insn_jges {
362                         struct statement *s = xmalloc(sizeof(struct statement));
363                         INIT_LIST_HEAD(&s->list);
364                         s->type = STMT_INSN;
365                         s->u.insn = $1;
366                         $$ = s;
367                   }
368                 | insn_jgs {
369                         struct statement *s = xmalloc(sizeof(struct statement));
370                         INIT_LIST_HEAD(&s->list);
371                         s->type = STMT_INSN;
372                         s->u.insn = $1;
373                         $$ = s;
374                   }
375                 | insn_jles {
376                         struct statement *s = xmalloc(sizeof(struct statement));
377                         INIT_LIST_HEAD(&s->list);
378                         s->type = STMT_INSN;
379                         s->u.insn = $1;
380                         $$ = s;
381                   }
382                 | insn_jl {
383                         struct statement *s = xmalloc(sizeof(struct statement));
384                         INIT_LIST_HEAD(&s->list);
385                         s->type = STMT_INSN;
386                         s->u.insn = $1;
387                         $$ = s;
388                   }
389                 | insn_jge {
390                         struct statement *s = xmalloc(sizeof(struct statement));
391                         INIT_LIST_HEAD(&s->list);
392                         s->type = STMT_INSN;
393                         s->u.insn = $1;
394                         $$ = s;
395                   }
396                 | insn_jg {
397                         struct statement *s = xmalloc(sizeof(struct statement));
398                         INIT_LIST_HEAD(&s->list);
399                         s->type = STMT_INSN;
400                         s->u.insn = $1;
401                         $$ = s;
402                   }
403                 | insn_jle {
404                         struct statement *s = xmalloc(sizeof(struct statement));
405                         INIT_LIST_HEAD(&s->list);
406                         s->type = STMT_INSN;
407                         s->u.insn = $1;
408                         $$ = s;
409                   }
410                 | insn_jzx {
411                         struct statement *s = xmalloc(sizeof(struct statement));
412                         INIT_LIST_HEAD(&s->list);
413                         s->type = STMT_INSN;
414                         s->u.insn = $1;
415                         $$ = s;
416                   }
417                 | insn_jnzx {
418                         struct statement *s = xmalloc(sizeof(struct statement));
419                         INIT_LIST_HEAD(&s->list);
420                         s->type = STMT_INSN;
421                         s->u.insn = $1;
422                         $$ = s;
423                   }
424                 | insn_jext {
425                         struct statement *s = xmalloc(sizeof(struct statement));
426                         INIT_LIST_HEAD(&s->list);
427                         s->type = STMT_INSN;
428                         s->u.insn = $1;
429                         $$ = s;
430                   }
431                 | insn_jnext {
432                         struct statement *s = xmalloc(sizeof(struct statement));
433                         INIT_LIST_HEAD(&s->list);
434                         s->type = STMT_INSN;
435                         s->u.insn = $1;
436                         $$ = s;
437                   }
438                 | insn_call {
439                         struct statement *s = xmalloc(sizeof(struct statement));
440                         INIT_LIST_HEAD(&s->list);
441                         s->type = STMT_INSN;
442                         s->u.insn = $1;
443                         $$ = s;
444                   }
445                 | insn_ret {
446                         struct statement *s = xmalloc(sizeof(struct statement));
447                         INIT_LIST_HEAD(&s->list);
448                         s->type = STMT_INSN;
449                         s->u.insn = $1;
450                         $$ = s;
451                   }
452                 | insn_tkiph {
453                         struct statement *s = xmalloc(sizeof(struct statement));
454                         INIT_LIST_HEAD(&s->list);
455                         s->type = STMT_INSN;
456                         s->u.insn = $1;
457                         $$ = s;
458                   }
459                 | insn_tkiphs {
460                         struct statement *s = xmalloc(sizeof(struct statement));
461                         INIT_LIST_HEAD(&s->list);
462                         s->type = STMT_INSN;
463                         s->u.insn = $1;
464                         $$ = s;
465                   }
466                 | insn_tkipl {
467                         struct statement *s = xmalloc(sizeof(struct statement));
468                         INIT_LIST_HEAD(&s->list);
469                         s->type = STMT_INSN;
470                         s->u.insn = $1;
471                         $$ = s;
472                   }
473                 | insn_tkipls {
474                         struct statement *s = xmalloc(sizeof(struct statement));
475                         INIT_LIST_HEAD(&s->list);
476                         s->type = STMT_INSN;
477                         s->u.insn = $1;
478                         $$ = s;
479                   }
480                 | insn_nap {
481                         struct statement *s = xmalloc(sizeof(struct statement));
482                         INIT_LIST_HEAD(&s->list);
483                         s->type = STMT_INSN;
484                         s->u.insn = $1;
485                         $$ = s;
486                   }
487                 | insn_raw {
488                         struct statement *s = xmalloc(sizeof(struct statement));
489                         INIT_LIST_HEAD(&s->list);
490                         s->type = STMT_INSN;
491                         s->u.insn = $1;
492                         $$ = s;
493                   }
494                 ;
495
496 /* ASM directives */
497 asmdir          : ASM_ARCH hexnum_decnum {
498                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
499                         ad->type = ADIR_ARCH;
500                         ad->u.arch = (unsigned int)(unsigned long)$2;
501                         $$ = ad;
502                   }
503                 | ASM_START identifier {
504                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
505                         struct label *label = xmalloc(sizeof(struct label));
506                         label->name = $2;
507                         label->direction = LABELREF_ABSOLUTE;
508                         ad->type = ADIR_START;
509                         ad->u.start = label;
510                         $$ = ad;
511                   }
512                 ;
513
514 label           : LABEL {
515                         struct label *label = xmalloc(sizeof(struct label));
516                         char *l;
517                         l = xstrdup(yytext);
518                         l[strlen(l) - 1] = '\0';
519                         label->name = l;
520                         $$ = label;
521                   }
522                 ;
523
524 /* add */
525 insn_add        : OP_ADD operlist_3 {
526                         struct instruction *insn = xmalloc(sizeof(struct instruction));
527                         insn->op = OP_ADD;
528                         insn->operands = $2;
529                         $$ = insn;
530                   }
531                 ;
532
533 /* add. */
534 insn_addsc      : OP_ADDSC operlist_3 {
535                         struct instruction *insn = xmalloc(sizeof(struct instruction));
536                         insn->op = OP_ADDSC;
537                         insn->operands = $2;
538                         $$ = insn;
539                   }
540                 ;
541
542 /* addc */
543 insn_addc       : OP_ADDC operlist_3 {
544                         struct instruction *insn = xmalloc(sizeof(struct instruction));
545                         insn->op = OP_ADDC;
546                         insn->operands = $2;
547                         $$ = insn;
548                   }
549                 ;
550
551 /* addc. */
552 insn_addscc     : OP_ADDSCC operlist_3 {
553                         struct instruction *insn = xmalloc(sizeof(struct instruction));
554                         insn->op = OP_ADDSCC;
555                         insn->operands = $2;
556                         $$ = insn;
557                   }
558                 ;
559
560 /* sub */
561 insn_sub        : OP_SUB operlist_3 {
562                         struct instruction *insn = xmalloc(sizeof(struct instruction));
563                         insn->op = OP_SUB;
564                         insn->operands = $2;
565                         $$ = insn;
566                   }
567                 ;
568
569 /* sub. */
570 insn_subsc      : OP_SUBSC operlist_3 {
571                         struct instruction *insn = xmalloc(sizeof(struct instruction));
572                         insn->op = OP_SUBSC;
573                         insn->operands = $2;
574                         $$ = insn;
575                   }
576                 ;
577
578 /* subc */
579 insn_subc       : OP_SUBC operlist_3 {
580                         struct instruction *insn = xmalloc(sizeof(struct instruction));
581                         insn->op = OP_SUBC;
582                         insn->operands = $2;
583                         $$ = insn;
584                   }
585                 ;
586
587 /* subc. */
588 insn_subscc     : OP_SUBSCC operlist_3 {
589                         struct instruction *insn = xmalloc(sizeof(struct instruction));
590                         insn->op = OP_SUBSCC;
591                         insn->operands = $2;
592                         $$ = insn;
593                   }
594                 ;
595
596 insn_sra        : OP_SRA operlist_3 {
597                         struct instruction *insn = xmalloc(sizeof(struct instruction));
598                         insn->op = OP_SRA;
599                         insn->operands = $2;
600                         $$ = insn;
601                   }
602                 ;
603
604 insn_or         : OP_OR operlist_3 {
605                         struct instruction *insn = xmalloc(sizeof(struct instruction));
606                         insn->op = OP_OR;
607                         insn->operands = $2;
608                         $$ = insn;
609                   }
610                 ;
611
612 insn_and        : OP_AND operlist_3 {
613                         struct instruction *insn = xmalloc(sizeof(struct instruction));
614                         insn->op = OP_AND;
615                         insn->operands = $2;
616                         $$ = insn;
617                   }
618                 ;
619
620 insn_xor        : OP_XOR operlist_3 {
621                         struct instruction *insn = xmalloc(sizeof(struct instruction));
622                         insn->op = OP_XOR;
623                         insn->operands = $2;
624                         $$ = insn;
625                   }
626                 ;
627
628 insn_sr         : OP_SR operlist_3 {
629                         struct instruction *insn = xmalloc(sizeof(struct instruction));
630                         insn->op = OP_SR;
631                         insn->operands = $2;
632                         $$ = insn;
633                   }
634                 ;
635
636 insn_srx        : OP_SRX extended_operlist {
637                         struct instruction *insn = xmalloc(sizeof(struct instruction));
638                         insn->op = OP_SRX;
639                         insn->operands = $2;
640                         $$ = insn;
641                   }
642                 ;
643
644 insn_sl         : OP_SL operlist_3 {
645                         struct instruction *insn = xmalloc(sizeof(struct instruction));
646                         insn->op = OP_SL;
647                         insn->operands = $2;
648                         $$ = insn;
649                   }
650                 ;
651
652 insn_rl         : OP_RL operlist_3 {
653                         struct instruction *insn = xmalloc(sizeof(struct instruction));
654                         insn->op = OP_RL;
655                         insn->operands = $2;
656                         $$ = insn;
657                   }
658                 ;
659
660 insn_rr         : OP_RR operlist_3 {
661                         struct instruction *insn = xmalloc(sizeof(struct instruction));
662                         insn->op = OP_RR;
663                         insn->operands = $2;
664                         $$ = insn;
665                   }
666                 ;
667
668 insn_nand       : OP_NAND operlist_3 {
669                         struct instruction *insn = xmalloc(sizeof(struct instruction));
670                         insn->op = OP_NAND;
671                         insn->operands = $2;
672                         $$ = insn;
673                   }
674                 ;
675
676 insn_orx        : OP_ORX extended_operlist {
677                         struct instruction *insn = xmalloc(sizeof(struct instruction));
678                         insn->op = OP_ORX;
679                         insn->operands = $2;
680                         $$ = insn;
681                   }
682                 ;
683
684 insn_mov        : OP_MOV operlist_2 {
685                         struct instruction *insn = xmalloc(sizeof(struct instruction));
686                         insn->op = OP_MOV;
687                         insn->operands = $2;
688                         $$ = insn;
689                   }
690                 ;
691
692 insn_jmp        : OP_JMP labelref {
693                         struct instruction *insn = xmalloc(sizeof(struct instruction));
694                         struct operlist *ol = xmalloc(sizeof(struct operlist));
695                         ol->oper[0] = $2;
696                         insn->op = OP_JMP;
697                         insn->operands = ol;
698                         $$ = insn;
699                   }
700                 ;
701
702 insn_jand       : OP_JAND operlist_3 {
703                         struct instruction *insn = xmalloc(sizeof(struct instruction));
704                         insn->op = OP_JAND;
705                         insn->operands = $2;
706                         $$ = insn;
707                   }
708                 ;
709
710 insn_jnand      : OP_JNAND operlist_3 {
711                         struct instruction *insn = xmalloc(sizeof(struct instruction));
712                         insn->op = OP_JNAND;
713                         insn->operands = $2;
714                         $$ = insn;
715                   }
716                 ;
717
718 insn_js         : OP_JS operlist_3 {
719                         struct instruction *insn = xmalloc(sizeof(struct instruction));
720                         insn->op = OP_JS;
721                         insn->operands = $2;
722                         $$ = insn;
723                   }
724                 ;
725
726 insn_jns        : OP_JNS operlist_3 {
727                         struct instruction *insn = xmalloc(sizeof(struct instruction));
728                         insn->op = OP_JNS;
729                         insn->operands = $2;
730                         $$ = insn;
731                   }
732                 ;
733
734 insn_je         : OP_JE operlist_3 {
735                         struct instruction *insn = xmalloc(sizeof(struct instruction));
736                         insn->op = OP_JE;
737                         insn->operands = $2;
738                         $$ = insn;
739                   }
740                 ;
741
742 insn_jne        : OP_JNE operlist_3 {
743                         struct instruction *insn = xmalloc(sizeof(struct instruction));
744                         insn->op = OP_JNE;
745                         insn->operands = $2;
746                         $$ = insn;
747                   }
748                 ;
749
750 insn_jls        : OP_JLS operlist_3 {
751                         struct instruction *insn = xmalloc(sizeof(struct instruction));
752                         insn->op = OP_JLS;
753                         insn->operands = $2;
754                         $$ = insn;
755                   }
756                 ;
757
758 insn_jges       : OP_JGES operlist_3 {
759                         struct instruction *insn = xmalloc(sizeof(struct instruction));
760                         insn->op = OP_JGES;
761                         insn->operands = $2;
762                         $$ = insn;
763                   }
764                 ;
765
766 insn_jgs        : OP_JGS operlist_3 {
767                         struct instruction *insn = xmalloc(sizeof(struct instruction));
768                         insn->op = OP_JGS;
769                         insn->operands = $2;
770                         $$ = insn;
771                   }
772                 ;
773
774 insn_jles       : OP_JLES operlist_3 {
775                         struct instruction *insn = xmalloc(sizeof(struct instruction));
776                         insn->op = OP_JLES;
777                         insn->operands = $2;
778                         $$ = insn;
779                   }
780                 ;
781
782 insn_jl         : OP_JL operlist_3 {
783                         struct instruction *insn = xmalloc(sizeof(struct instruction));
784                         insn->op = OP_JL;
785                         insn->operands = $2;
786                         $$ = insn;
787                   }
788                 ;
789
790 insn_jge        : OP_JGE operlist_3 {
791                         struct instruction *insn = xmalloc(sizeof(struct instruction));
792                         insn->op = OP_JGE;
793                         insn->operands = $2;
794                         $$ = insn;
795                   }
796                 ;
797
798 insn_jg         : OP_JG operlist_3 {
799                         struct instruction *insn = xmalloc(sizeof(struct instruction));
800                         insn->op = OP_JG;
801                         insn->operands = $2;
802                         $$ = insn;
803                   }
804                 ;
805
806 insn_jle        : OP_JLE operlist_3 {
807                         struct instruction *insn = xmalloc(sizeof(struct instruction));
808                         insn->op = OP_JLE;
809                         insn->operands = $2;
810                         $$ = insn;
811                   }
812                 ;
813
814 insn_jzx        : OP_JZX extended_operlist {
815                         struct instruction *insn = xmalloc(sizeof(struct instruction));
816                         insn->op = OP_JZX;
817                         insn->operands = $2;
818                         $$ = insn;
819                   }
820                 ;
821
822 insn_jnzx       : OP_JNZX extended_operlist {
823                         struct instruction *insn = xmalloc(sizeof(struct instruction));
824                         insn->op = OP_JNZX;
825                         insn->operands = $2;
826                         $$ = insn;
827                   }
828                 ;
829
830 insn_jext       : OP_JEXT external_jump_operands {
831                         struct instruction *insn = xmalloc(sizeof(struct instruction));
832                         insn->op = OP_JEXT;
833                         insn->operands = $2;
834                         $$ = insn;
835                   }
836                 ;
837
838 insn_jnext      : OP_JNEXT external_jump_operands {
839                         struct instruction *insn = xmalloc(sizeof(struct instruction));
840                         insn->op = OP_JNEXT;
841                         insn->operands = $2;
842                         $$ = insn;
843                   }
844                 ;
845
846 linkreg         : LR regnr {
847                         $$ = $2;
848                   }
849                 ;
850
851 insn_call       : OP_CALL linkreg COMMA labelref {
852                         struct instruction *insn = xmalloc(sizeof(struct instruction));
853                         struct operlist *ol = xmalloc(sizeof(struct operlist));
854                         struct operand *oper_lr = xmalloc(sizeof(struct operand));
855                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
856                         oper_zero->type = OPER_RAW;
857                         oper_zero->u.raw = 0;
858                         oper_lr->type = OPER_RAW;
859                         oper_lr->u.raw = (unsigned long)$2;
860                         ol->oper[0] = oper_lr;
861                         ol->oper[1] = oper_zero;
862                         ol->oper[2] = $4;
863                         insn->op = OP_CALL;
864                         insn->operands = ol;
865                         $$ = insn;
866                   }
867                 ;
868
869 insn_ret        : OP_RET linkreg COMMA linkreg {
870                         struct instruction *insn = xmalloc(sizeof(struct instruction));
871                         struct operlist *ol = xmalloc(sizeof(struct operlist));
872                         struct operand *oper_lr0 = xmalloc(sizeof(struct operand));
873                         struct operand *oper_lr1 = xmalloc(sizeof(struct operand));
874                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
875                         oper_zero->type = OPER_RAW;
876                         oper_zero->u.raw = 0;
877                         oper_lr0->type = OPER_RAW;
878                         oper_lr0->u.raw = (unsigned long)$2;
879                         oper_lr1->type = OPER_RAW;
880                         oper_lr1->u.raw = (unsigned long)$4;
881                         ol->oper[0] = oper_lr0;
882                         ol->oper[1] = oper_zero;
883                         ol->oper[2] = oper_lr1;
884                         insn->op = OP_RET;
885                         insn->operands = ol;
886                         $$ = insn;
887                   }
888                 ;
889
890 insn_tkiph      : OP_TKIPH operlist_2 {
891                         struct instruction *insn = xmalloc(sizeof(struct instruction));
892                         struct operlist *ol = $2;
893                         struct operand *flags = xmalloc(sizeof(struct operand));
894                         struct immediate *imm = xmalloc(sizeof(struct immediate));
895                         imm->imm = 0x1;
896                         flags->type = OPER_IMM;
897                         flags->u.imm = imm;
898                         ol->oper[2] = ol->oper[1];
899                         ol->oper[1] = flags;
900                         insn->op = OP_TKIPH;
901                         insn->operands = ol;
902                         $$ = insn;
903                   }
904                 ;
905
906 insn_tkiphs     : OP_TKIPHS operlist_2 {
907                         struct instruction *insn = xmalloc(sizeof(struct instruction));
908                         struct operlist *ol = $2;
909                         struct operand *flags = xmalloc(sizeof(struct operand));
910                         struct immediate *imm = xmalloc(sizeof(struct immediate));
911                         imm->imm = 0x1 | 0x2;
912                         flags->type = OPER_IMM;
913                         flags->u.imm = imm;
914                         ol->oper[2] = ol->oper[1];
915                         ol->oper[1] = flags;
916                         insn->op = OP_TKIPH;
917                         insn->operands = ol;
918                         $$ = insn;
919                   }
920                 ;
921
922 insn_tkipl      : OP_TKIPL operlist_2 {
923                         struct instruction *insn = xmalloc(sizeof(struct instruction));
924                         struct operlist *ol = $2;
925                         struct operand *flags = xmalloc(sizeof(struct operand));
926                         struct immediate *imm = xmalloc(sizeof(struct immediate));
927                         imm->imm = 0x0;
928                         flags->type = OPER_IMM;
929                         flags->u.imm = imm;
930                         ol->oper[2] = ol->oper[1];
931                         ol->oper[1] = flags;
932                         insn->op = OP_TKIPH;
933                         insn->operands = ol;
934                         $$ = insn;
935                   }
936                 ;
937
938 insn_tkipls     : OP_TKIPLS operlist_2 {
939                         struct instruction *insn = xmalloc(sizeof(struct instruction));
940                         struct operlist *ol = $2;
941                         struct operand *flags = xmalloc(sizeof(struct operand));
942                         struct immediate *imm = xmalloc(sizeof(struct immediate));
943                         imm->imm = 0x0 | 0x2;
944                         flags->type = OPER_IMM;
945                         flags->u.imm = imm;
946                         ol->oper[2] = ol->oper[1];
947                         ol->oper[1] = flags;
948                         insn->op = OP_TKIPH;
949                         insn->operands = ol;
950                         $$ = insn;
951                   }
952                 ;
953
954 insn_nap        : OP_NAP {
955                         struct instruction *insn = xmalloc(sizeof(struct instruction));
956                         struct operlist *ol = xmalloc(sizeof(struct operlist));
957                         struct operand *regop = xmalloc(sizeof(struct operand));
958                         struct operand *zeroop = xmalloc(sizeof(struct operand));
959                         struct registr *r0 = xmalloc(sizeof(struct registr));
960                         r0->type = GPR;
961                         r0->nr = 0;
962                         regop->type = OPER_REG;
963                         regop->u.reg = r0;
964                         zeroop->type = OPER_RAW;
965                         zeroop->u.raw = 0x000;
966                         ol->oper[0] = regop;
967                         ol->oper[1] = regop;
968                         ol->oper[2] = zeroop;
969                         insn->op = OP_NAP;
970                         insn->operands = ol;
971                         $$ = insn;
972                   }
973                 ;
974
975 insn_raw        : raw_code operlist_3 {
976                         struct instruction *insn = xmalloc(sizeof(struct instruction));
977                         insn->op = RAW_CODE;
978                         insn->operands = $2;
979                         insn->opcode = (unsigned long)$1;
980                         $$ = insn;
981                   }
982                 ;
983
984 raw_code        : RAW_CODE {
985                         yytext++; /* skip @ */
986                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
987                   }
988                 ;
989
990 extended_operlist : decnum COMMA decnum COMMA operand COMMA operand COMMA operand {
991                         struct operlist *ol = xmalloc(sizeof(struct operlist));
992                         struct operand *mask_oper = xmalloc(sizeof(struct operand));
993                         struct operand *shift_oper = xmalloc(sizeof(struct operand));
994                         mask_oper->type = OPER_RAW;
995                         mask_oper->u.raw = (unsigned long)$1;
996                         shift_oper->type = OPER_RAW;
997                         shift_oper->u.raw = (unsigned long)$3;
998                         ol->oper[0] = mask_oper;
999                         ol->oper[1] = shift_oper;
1000                         ol->oper[2] = $5;
1001                         ol->oper[3] = $7;
1002                         ol->oper[4] = store_oper_sanity($9);
1003                         $$ = ol;
1004                   }
1005                 ;
1006
1007 external_jump_operands : imm COMMA operand COMMA operand COMMA labelref {
1008                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1009                         struct operand *cond = xmalloc(sizeof(struct operand));
1010                         cond->type = OPER_IMM;
1011                         cond->u.imm = $1;
1012                         ol->oper[0] = cond;
1013                         ol->oper[1] = $3;
1014                         ol->oper[2] = $5;
1015                         ol->oper[3] = $7;
1016                         $$ = ol;
1017                   }
1018                 ;
1019
1020 operlist_2      : operand COMMA operand {
1021                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1022                         ol->oper[0] = $1;
1023                         ol->oper[1] = store_oper_sanity($3);
1024                         $$ = ol;
1025                   }
1026                 ;
1027
1028 operlist_3      : operand COMMA operand COMMA operand {
1029                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1030                         ol->oper[0] = $1;
1031                         ol->oper[1] = $3;
1032                         ol->oper[2] = store_oper_sanity($5);
1033                         $$ = ol;
1034                   }
1035                 ;
1036
1037 operand         : reg {
1038                         struct operand *oper = xmalloc(sizeof(struct operand));
1039                         oper->type = OPER_REG;
1040                         oper->u.reg = $1;
1041                         $$ = oper;
1042                   }
1043                 | mem {
1044                         struct operand *oper = xmalloc(sizeof(struct operand));
1045                         oper->type = OPER_MEM;
1046                         oper->u.mem = $1;
1047                         $$ = oper;
1048                   }
1049                 | raw_code {
1050                         struct operand *oper = xmalloc(sizeof(struct operand));
1051                         oper->type = OPER_RAW;
1052                         oper->u.raw = (unsigned long)$1;
1053                         $$ = oper;
1054                   }
1055                 | imm {
1056                         struct operand *oper = xmalloc(sizeof(struct operand));
1057                         oper->type = OPER_IMM;
1058                         oper->u.imm = $1;
1059                         $$ = oper;
1060                   }
1061                 | labelref {
1062                         $$ = $1;
1063                   }
1064                 ;
1065
1066 reg             : GPR regnr {
1067                         struct registr *reg = xmalloc(sizeof(struct registr));
1068                         reg->type = GPR;
1069                         reg->nr = (unsigned long)$2;
1070                         $$ = reg;
1071                   }
1072                 | SPR {
1073                         struct registr *reg = xmalloc(sizeof(struct registr));
1074                         reg->type = SPR;
1075                         yytext += 3; /* skip "spr" */
1076                         reg->nr = strtoul(yytext, NULL, 16);
1077                         $$ = reg;
1078                   }
1079                 | OFFR regnr {
1080                         struct registr *reg = xmalloc(sizeof(struct registr));
1081                         reg->type = OFFR;
1082                         reg->nr = (unsigned long)$2;
1083                         $$ = reg;
1084                   }
1085                 ;
1086
1087 mem             : BRACK_OPEN imm BRACK_CLOSE {
1088                         struct memory *mem = xmalloc(sizeof(struct memory));
1089                         struct immediate *offset_imm = $2;
1090                         mem->type = MEM_DIRECT;
1091                         mem->offset = offset_imm->imm;
1092                         free(offset_imm);
1093                         $$ = mem;
1094                   }
1095                 | BRACK_OPEN imm COMMA OFFR regnr BRACK_CLOSE {
1096                         struct memory *mem = xmalloc(sizeof(struct memory));
1097                         struct immediate *offset_imm = $2;
1098                         mem->type = MEM_INDIRECT;
1099                         mem->offset = offset_imm->imm;
1100                         free(offset_imm);
1101                         mem->offr_nr = (unsigned long)$5;
1102                         $$ = mem;
1103                   }
1104                 ;
1105
1106 imm             : hexnum_decnum {
1107                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1108                         imm->imm = (unsigned long)$1;
1109                         $$ = imm;
1110                   }
1111                 | complex_imm {
1112                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1113                         imm->imm = (unsigned long)$1;
1114                         $$ = imm;
1115                   }
1116                 ;
1117
1118 complex_imm     : PAREN_OPEN complex_imm_arg complex_imm_oper complex_imm_arg PAREN_CLOSE {
1119                         unsigned long a = (unsigned long)$2;
1120                         unsigned long b = (unsigned long)$4;
1121                         unsigned long operation = (unsigned long)$3;
1122                         unsigned long res = 31337;
1123                         switch (operation) {
1124                         case PLUS:
1125                                 res = a + b;
1126                                 break;
1127                         case MINUS:
1128                                 res = a - b;
1129                                 break;
1130                         case MULTIPLY:
1131                                 res = a * b;
1132                                 break;
1133                         case DIVIDE:
1134                                 res = a / b;
1135                                 break;
1136                         case BITW_OR:
1137                                 res = a | b;
1138                                 break;
1139                         case BITW_AND:
1140                                 res = a & b;
1141                                 break;
1142                         case BITW_XOR:
1143                                 res = a ^ b;
1144                                 break;
1145                         case LEFTSHIFT:
1146                                 res = a << b;
1147                                 break;
1148                         case RIGHTSHIFT:
1149                                 res = a >> b;
1150                                 break;
1151                         default:
1152                                 yyerror("Internal parser BUG. complex_imm oper unknown");
1153                         }
1154                         $$ = (void *)res;
1155                   }
1156                 | PAREN_OPEN complex_imm PAREN_CLOSE {
1157                         $$ = $2;
1158                   }
1159                 | PAREN_OPEN BITW_NOT complex_imm PAREN_CLOSE {
1160                         unsigned long n = (unsigned long)$3;
1161                         n = ~n;
1162                         $$ = (void *)n;
1163                   }
1164                 | PAREN_OPEN complex_imm_const PAREN_CLOSE {
1165                         $$ = $2;
1166                   }
1167                 ;
1168
1169 complex_imm_oper : PLUS {
1170                         $$ = (void *)(unsigned long)PLUS;
1171                   }
1172                 | MINUS {
1173                         $$ = (void *)(unsigned long)MINUS;
1174                   }
1175                 | MULTIPLY {
1176                         $$ = (void *)(unsigned long)MULTIPLY;
1177                   }
1178                 | DIVIDE {
1179                         $$ = (void *)(unsigned long)DIVIDE;
1180                   }
1181                 | BITW_OR {
1182                         $$ = (void *)(unsigned long)BITW_OR;
1183                   }
1184                 | BITW_AND {
1185                         $$ = (void *)(unsigned long)BITW_AND;
1186                   }
1187                 | BITW_XOR {
1188                         $$ = (void *)(unsigned long)BITW_XOR;
1189                   }
1190                 | LEFTSHIFT {
1191                         $$ = (void *)(unsigned long)LEFTSHIFT;
1192                   }
1193                 | RIGHTSHIFT {
1194                         $$ = (void *)(unsigned long)RIGHTSHIFT;
1195                   }
1196                 ;
1197
1198 complex_imm_arg : complex_imm_const {
1199                         $$ = $1;
1200                   }
1201                 | complex_imm {
1202                         $$ = $1;
1203                   }
1204                 ;
1205
1206 complex_imm_const : hexnum_decnum {
1207                         $$ = $1;
1208                   }
1209                 | BITW_NOT hexnum_decnum {
1210                         unsigned long n = (unsigned long)$2;
1211                         n = ~n;
1212                         $$ = (void *)n;
1213                   }
1214                 ;
1215
1216 hexnum          : HEXNUM {
1217                         while (yytext[0] != 'x') {
1218                                 if (yytext[0] == '\0')
1219                                         yyerror("Internal HEXNUM parser error");
1220                                 yytext++;
1221                         }
1222                         yytext++;
1223                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1224                   }
1225                 ;
1226
1227 decnum          : DECNUM {
1228                         $$ = (void *)(unsigned long)strtol(yytext, NULL, 10);
1229                   }
1230                 ;
1231
1232 hexnum_decnum   : hexnum {
1233                         $$ = $1;
1234                   }
1235                 | decnum {
1236                         $$ = $1;
1237                   }
1238                 ;
1239
1240 labelref        : identifier {
1241                         struct operand *oper = xmalloc(sizeof(struct operand));
1242                         struct label *label = xmalloc(sizeof(struct label));
1243                         label->name = $1;
1244                         label->direction = LABELREF_ABSOLUTE;
1245                         oper->type = OPER_LABEL;
1246                         oper->u.label = label;
1247                         $$ = oper;
1248                   }
1249                 | identifier MINUS {
1250                         struct operand *oper = xmalloc(sizeof(struct operand));
1251                         struct label *label = xmalloc(sizeof(struct label));
1252                         label->name = $1;
1253                         label->direction = LABELREF_RELATIVE_BACK;
1254                         oper->type = OPER_LABEL;
1255                         oper->u.label = label;
1256                         $$ = oper;
1257                   }
1258                 | identifier PLUS {
1259                         struct operand *oper = xmalloc(sizeof(struct operand));
1260                         struct label *label = xmalloc(sizeof(struct label));
1261                         label->name = $1;
1262                         label->direction = LABELREF_RELATIVE_FORWARD;
1263                         oper->type = OPER_LABEL;
1264                         oper->u.label = label;
1265                         $$ = oper;
1266                   }
1267                 ;
1268
1269 regnr           : DECNUM {
1270                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 10);
1271                   }
1272                 ;
1273
1274 identifier      : IDENT {
1275                         $$ = xstrdup(yytext);
1276                   }
1277                 ;
1278
1279 %%
1280
1281 int section = SECTION_TEXT; /* default to .text section */
1282 struct initvals_sect *cur_initvals_sect;
1283
1284 void yyerror(char *str)
1285 {
1286         unsigned int i;
1287
1288         fprintf(stderr,
1289                 "Parser ERROR (file \"%s\", line %u, col %u):\n",
1290                 cur_lineinfo.file,
1291                 cur_lineinfo.lineno,
1292                 cur_lineinfo.column);
1293         fprintf(stderr, "%s\n", cur_lineinfo.linecopy);
1294         for (i = 0; i < cur_lineinfo.column - 1; i++)
1295                 fprintf(stderr, " ");
1296         fprintf(stderr, "^\n");
1297         fprintf(stderr, "%s\n", str);
1298         exit(1);
1299 }
1300
1301 static struct operand * store_oper_sanity(struct operand *oper)
1302 {
1303         if (oper->type == OPER_IMM &&
1304             oper->u.imm->imm != 0) {
1305                 yyerror("Only 0x000 Immediate is allowed for "
1306                         "Output operands");
1307         }
1308         return oper;
1309 }