b43-asm: Allow terminating lines with |
[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 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                 | BITW_OR line_terminator
78
79 section_switch  : SECTION_TEXT {
80                         section = SECTION_TEXT;
81                   }
82                 | SECTION_IVALS PAREN_OPEN identifier PAREN_CLOSE {
83                         const char *sectname = $3;
84                         struct initvals_sect *s;
85                         cur_initvals_sect = NULL;
86                         /* Search if there already is a section by that name. */
87                         list_for_each_entry(s, &infile.ivals, list) {
88                                 if (strcmp(sectname, s->name) == 0)
89                                         cur_initvals_sect = s;
90                         }
91                         if (!cur_initvals_sect) {
92                                 /* Not found, create a new one. */
93                                 s = xmalloc(sizeof(struct initvals_sect));
94                                 s->name = sectname;
95                                 INIT_LIST_HEAD(&s->ops);
96                                 INIT_LIST_HEAD(&s->list);
97                                 list_add_tail(&s->list, &infile.ivals);
98                                 cur_initvals_sect = s;
99                         }
100                         section = SECTION_IVALS;
101                   }
102                 ;
103
104 ivals_write     : IVAL_MMIO16 hexnum_decnum COMMA hexnum_decnum {
105                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
106                         iop->type = IVAL_W_MMIO16;
107                         iop->args[0] = (unsigned int)(unsigned long)$2;
108                         iop->args[1] = (unsigned int)(unsigned long)$4;
109                         $$ = iop;
110                   }
111                 | IVAL_MMIO32 hexnum_decnum COMMA hexnum_decnum {
112                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
113                         iop->type = IVAL_W_MMIO32;
114                         iop->args[0] = (unsigned int)(unsigned long)$2;
115                         iop->args[1] = (unsigned int)(unsigned long)$4;
116                         $$ = iop;
117                   }
118                 | IVAL_PHY hexnum_decnum COMMA hexnum_decnum {
119                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
120                         iop->type = IVAL_W_PHY;
121                         iop->args[0] = (unsigned int)(unsigned long)$2;
122                         iop->args[1] = (unsigned int)(unsigned long)$4;
123                         $$ = iop;
124                   }
125                 | IVAL_RADIO hexnum_decnum COMMA hexnum_decnum {
126                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
127                         iop->type = IVAL_W_RADIO;
128                         iop->args[0] = (unsigned int)(unsigned long)$2;
129                         iop->args[1] = (unsigned int)(unsigned long)$4;
130                         $$ = iop;
131                   }
132                 | IVAL_SHM16 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
133                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
134                         iop->type = IVAL_W_SHM16;
135                         iop->args[0] = (unsigned int)(unsigned long)$2;
136                         iop->args[1] = (unsigned int)(unsigned long)$4;
137                         iop->args[2] = (unsigned int)(unsigned long)$6;
138                         $$ = iop;
139                   }
140                 | IVAL_SHM32 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
141                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
142                         iop->type = IVAL_W_SHM32;
143                         iop->args[0] = (unsigned int)(unsigned long)$2;
144                         iop->args[1] = (unsigned int)(unsigned long)$4;
145                         iop->args[2] = (unsigned int)(unsigned long)$6;
146                         $$ = iop;
147                   }
148                 ;
149
150 statement       : asmdir {
151                         struct statement *s = xmalloc(sizeof(struct statement));
152                         INIT_LIST_HEAD(&s->list);
153                         s->type = STMT_ASMDIR;
154                         s->u.asmdir = $1;
155                         $$ = s;
156                   }
157                 | label {
158                         struct statement *s = xmalloc(sizeof(struct statement));
159                         INIT_LIST_HEAD(&s->list);
160                         s->type = STMT_LABEL;
161                         s->u.label = $1;
162                         $$ = s;
163                   }
164                 | insn_add {
165                         struct statement *s = xmalloc(sizeof(struct statement));
166                         INIT_LIST_HEAD(&s->list);
167                         s->type = STMT_INSN;
168                         s->u.insn = $1;
169                         $$ = s;
170                   }
171                 | insn_addsc {
172                         struct statement *s = xmalloc(sizeof(struct statement));
173                         INIT_LIST_HEAD(&s->list);
174                         s->type = STMT_INSN;
175                         s->u.insn = $1;
176                         $$ = s;
177                   }
178                 | insn_addc {
179                         struct statement *s = xmalloc(sizeof(struct statement));
180                         INIT_LIST_HEAD(&s->list);
181                         s->type = STMT_INSN;
182                         s->u.insn = $1;
183                         $$ = s;
184                   }
185                 | insn_addscc {
186                         struct statement *s = xmalloc(sizeof(struct statement));
187                         INIT_LIST_HEAD(&s->list);
188                         s->type = STMT_INSN;
189                         s->u.insn = $1;
190                         $$ = s;
191                   }
192                 | insn_sub {
193                         struct statement *s = xmalloc(sizeof(struct statement));
194                         INIT_LIST_HEAD(&s->list);
195                         s->type = STMT_INSN;
196                         s->u.insn = $1;
197                         $$ = s;
198                   }
199                 | insn_subsc {
200                         struct statement *s = xmalloc(sizeof(struct statement));
201                         INIT_LIST_HEAD(&s->list);
202                         s->type = STMT_INSN;
203                         s->u.insn = $1;
204                         $$ = s;
205                   }
206                 | insn_subc {
207                         struct statement *s = xmalloc(sizeof(struct statement));
208                         INIT_LIST_HEAD(&s->list);
209                         s->type = STMT_INSN;
210                         s->u.insn = $1;
211                         $$ = s;
212                   }
213                 | insn_subscc {
214                         struct statement *s = xmalloc(sizeof(struct statement));
215                         INIT_LIST_HEAD(&s->list);
216                         s->type = STMT_INSN;
217                         s->u.insn = $1;
218                         $$ = s;
219                   }
220                 | insn_sra {
221                         struct statement *s = xmalloc(sizeof(struct statement));
222                         INIT_LIST_HEAD(&s->list);
223                         s->type = STMT_INSN;
224                         s->u.insn = $1;
225                         $$ = s;
226                   }
227                 | insn_or {
228                         struct statement *s = xmalloc(sizeof(struct statement));
229                         INIT_LIST_HEAD(&s->list);
230                         s->type = STMT_INSN;
231                         s->u.insn = $1;
232                         $$ = s;
233                   }
234                 | insn_and {
235                         struct statement *s = xmalloc(sizeof(struct statement));
236                         INIT_LIST_HEAD(&s->list);
237                         s->type = STMT_INSN;
238                         s->u.insn = $1;
239                         $$ = s;
240                   }
241                 | insn_xor {
242                         struct statement *s = xmalloc(sizeof(struct statement));
243                         INIT_LIST_HEAD(&s->list);
244                         s->type = STMT_INSN;
245                         s->u.insn = $1;
246                         $$ = s;
247                   }
248                 | insn_sr {
249                         struct statement *s = xmalloc(sizeof(struct statement));
250                         INIT_LIST_HEAD(&s->list);
251                         s->type = STMT_INSN;
252                         s->u.insn = $1;
253                         $$ = s;
254                   }
255                 | insn_srx {
256                         struct statement *s = xmalloc(sizeof(struct statement));
257                         INIT_LIST_HEAD(&s->list);
258                         s->type = STMT_INSN;
259                         s->u.insn = $1;
260                         $$ = s;
261                   }
262                 | insn_sl {
263                         struct statement *s = xmalloc(sizeof(struct statement));
264                         INIT_LIST_HEAD(&s->list);
265                         s->type = STMT_INSN;
266                         s->u.insn = $1;
267                         $$ = s;
268                   }
269                 | insn_rl {
270                         struct statement *s = xmalloc(sizeof(struct statement));
271                         INIT_LIST_HEAD(&s->list);
272                         s->type = STMT_INSN;
273                         s->u.insn = $1;
274                         $$ = s;
275                   }
276                 | insn_rr {
277                         struct statement *s = xmalloc(sizeof(struct statement));
278                         INIT_LIST_HEAD(&s->list);
279                         s->type = STMT_INSN;
280                         s->u.insn = $1;
281                         $$ = s;
282                   }
283                 | insn_nand {
284                         struct statement *s = xmalloc(sizeof(struct statement));
285                         INIT_LIST_HEAD(&s->list);
286                         s->type = STMT_INSN;
287                         s->u.insn = $1;
288                         $$ = s;
289                   }
290                 | insn_orx {
291                         struct statement *s = xmalloc(sizeof(struct statement));
292                         INIT_LIST_HEAD(&s->list);
293                         s->type = STMT_INSN;
294                         s->u.insn = $1;
295                         $$ = s;
296                   }
297                 | insn_mov {
298                         struct statement *s = xmalloc(sizeof(struct statement));
299                         INIT_LIST_HEAD(&s->list);
300                         s->type = STMT_INSN;
301                         s->u.insn = $1;
302                         $$ = s;
303                   }
304                 | insn_jmp {
305                         struct statement *s = xmalloc(sizeof(struct statement));
306                         INIT_LIST_HEAD(&s->list);
307                         s->type = STMT_INSN;
308                         s->u.insn = $1;
309                         $$ = s;
310                   }
311                 | insn_jand {
312                         struct statement *s = xmalloc(sizeof(struct statement));
313                         INIT_LIST_HEAD(&s->list);
314                         s->type = STMT_INSN;
315                         s->u.insn = $1;
316                         $$ = s;
317                   }
318                 | insn_jnand {
319                         struct statement *s = xmalloc(sizeof(struct statement));
320                         INIT_LIST_HEAD(&s->list);
321                         s->type = STMT_INSN;
322                         s->u.insn = $1;
323                         $$ = s;
324                   }
325                 | insn_js {
326                         struct statement *s = xmalloc(sizeof(struct statement));
327                         INIT_LIST_HEAD(&s->list);
328                         s->type = STMT_INSN;
329                         s->u.insn = $1;
330                         $$ = s;
331                   }
332                 | insn_jns {
333                         struct statement *s = xmalloc(sizeof(struct statement));
334                         INIT_LIST_HEAD(&s->list);
335                         s->type = STMT_INSN;
336                         s->u.insn = $1;
337                         $$ = s;
338                   }
339                 | insn_je {
340                         struct statement *s = xmalloc(sizeof(struct statement));
341                         INIT_LIST_HEAD(&s->list);
342                         s->type = STMT_INSN;
343                         s->u.insn = $1;
344                         $$ = s;
345                   }
346                 | insn_jne {
347                         struct statement *s = xmalloc(sizeof(struct statement));
348                         INIT_LIST_HEAD(&s->list);
349                         s->type = STMT_INSN;
350                         s->u.insn = $1;
351                         $$ = s;
352                   }
353                 | insn_jls {
354                         struct statement *s = xmalloc(sizeof(struct statement));
355                         INIT_LIST_HEAD(&s->list);
356                         s->type = STMT_INSN;
357                         s->u.insn = $1;
358                         $$ = s;
359                   }
360                 | insn_jges {
361                         struct statement *s = xmalloc(sizeof(struct statement));
362                         INIT_LIST_HEAD(&s->list);
363                         s->type = STMT_INSN;
364                         s->u.insn = $1;
365                         $$ = s;
366                   }
367                 | insn_jgs {
368                         struct statement *s = xmalloc(sizeof(struct statement));
369                         INIT_LIST_HEAD(&s->list);
370                         s->type = STMT_INSN;
371                         s->u.insn = $1;
372                         $$ = s;
373                   }
374                 | insn_jles {
375                         struct statement *s = xmalloc(sizeof(struct statement));
376                         INIT_LIST_HEAD(&s->list);
377                         s->type = STMT_INSN;
378                         s->u.insn = $1;
379                         $$ = s;
380                   }
381                 | insn_jl {
382                         struct statement *s = xmalloc(sizeof(struct statement));
383                         INIT_LIST_HEAD(&s->list);
384                         s->type = STMT_INSN;
385                         s->u.insn = $1;
386                         $$ = s;
387                   }
388                 | insn_jge {
389                         struct statement *s = xmalloc(sizeof(struct statement));
390                         INIT_LIST_HEAD(&s->list);
391                         s->type = STMT_INSN;
392                         s->u.insn = $1;
393                         $$ = s;
394                   }
395                 | insn_jg {
396                         struct statement *s = xmalloc(sizeof(struct statement));
397                         INIT_LIST_HEAD(&s->list);
398                         s->type = STMT_INSN;
399                         s->u.insn = $1;
400                         $$ = s;
401                   }
402                 | insn_jle {
403                         struct statement *s = xmalloc(sizeof(struct statement));
404                         INIT_LIST_HEAD(&s->list);
405                         s->type = STMT_INSN;
406                         s->u.insn = $1;
407                         $$ = s;
408                   }
409                 | insn_jzx {
410                         struct statement *s = xmalloc(sizeof(struct statement));
411                         INIT_LIST_HEAD(&s->list);
412                         s->type = STMT_INSN;
413                         s->u.insn = $1;
414                         $$ = s;
415                   }
416                 | insn_jnzx {
417                         struct statement *s = xmalloc(sizeof(struct statement));
418                         INIT_LIST_HEAD(&s->list);
419                         s->type = STMT_INSN;
420                         s->u.insn = $1;
421                         $$ = s;
422                   }
423                 | insn_jext {
424                         struct statement *s = xmalloc(sizeof(struct statement));
425                         INIT_LIST_HEAD(&s->list);
426                         s->type = STMT_INSN;
427                         s->u.insn = $1;
428                         $$ = s;
429                   }
430                 | insn_jnext {
431                         struct statement *s = xmalloc(sizeof(struct statement));
432                         INIT_LIST_HEAD(&s->list);
433                         s->type = STMT_INSN;
434                         s->u.insn = $1;
435                         $$ = s;
436                   }
437                 | insn_call {
438                         struct statement *s = xmalloc(sizeof(struct statement));
439                         INIT_LIST_HEAD(&s->list);
440                         s->type = STMT_INSN;
441                         s->u.insn = $1;
442                         $$ = s;
443                   }
444                 | insn_ret {
445                         struct statement *s = xmalloc(sizeof(struct statement));
446                         INIT_LIST_HEAD(&s->list);
447                         s->type = STMT_INSN;
448                         s->u.insn = $1;
449                         $$ = s;
450                   }
451                 | insn_tkiph {
452                         struct statement *s = xmalloc(sizeof(struct statement));
453                         INIT_LIST_HEAD(&s->list);
454                         s->type = STMT_INSN;
455                         s->u.insn = $1;
456                         $$ = s;
457                   }
458                 | insn_tkiphs {
459                         struct statement *s = xmalloc(sizeof(struct statement));
460                         INIT_LIST_HEAD(&s->list);
461                         s->type = STMT_INSN;
462                         s->u.insn = $1;
463                         $$ = s;
464                   }
465                 | insn_tkipl {
466                         struct statement *s = xmalloc(sizeof(struct statement));
467                         INIT_LIST_HEAD(&s->list);
468                         s->type = STMT_INSN;
469                         s->u.insn = $1;
470                         $$ = s;
471                   }
472                 | insn_tkipls {
473                         struct statement *s = xmalloc(sizeof(struct statement));
474                         INIT_LIST_HEAD(&s->list);
475                         s->type = STMT_INSN;
476                         s->u.insn = $1;
477                         $$ = s;
478                   }
479                 | insn_nap {
480                         struct statement *s = xmalloc(sizeof(struct statement));
481                         INIT_LIST_HEAD(&s->list);
482                         s->type = STMT_INSN;
483                         s->u.insn = $1;
484                         $$ = s;
485                   }
486                 | insn_raw {
487                         struct statement *s = xmalloc(sizeof(struct statement));
488                         INIT_LIST_HEAD(&s->list);
489                         s->type = STMT_INSN;
490                         s->u.insn = $1;
491                         $$ = s;
492                   }
493                 ;
494
495 /* ASM directives */
496 asmdir          : ASM_ARCH hexnum_decnum {
497                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
498                         ad->type = ADIR_ARCH;
499                         ad->u.arch = (unsigned int)(unsigned long)$2;
500                         $$ = ad;
501                   }
502                 | ASM_START identifier {
503                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
504                         struct label *label = xmalloc(sizeof(struct label));
505                         label->name = $2;
506                         label->direction = LABELREF_ABSOLUTE;
507                         ad->type = ADIR_START;
508                         ad->u.start = label;
509                         $$ = ad;
510                   }
511                 ;
512
513 label           : LABEL {
514                         struct label *label = xmalloc(sizeof(struct label));
515                         char *l;
516                         l = xstrdup(yytext);
517                         l[strlen(l) - 1] = '\0';
518                         label->name = l;
519                         $$ = label;
520                   }
521                 ;
522
523 /* add */
524 insn_add        : OP_ADD operlist_3 {
525                         struct instruction *insn = xmalloc(sizeof(struct instruction));
526                         insn->op = OP_ADD;
527                         insn->operands = $2;
528                         $$ = insn;
529                   }
530                 ;
531
532 /* add. */
533 insn_addsc      : OP_ADDSC operlist_3 {
534                         struct instruction *insn = xmalloc(sizeof(struct instruction));
535                         insn->op = OP_ADDSC;
536                         insn->operands = $2;
537                         $$ = insn;
538                   }
539                 ;
540
541 /* addc */
542 insn_addc       : OP_ADDC operlist_3 {
543                         struct instruction *insn = xmalloc(sizeof(struct instruction));
544                         insn->op = OP_ADDC;
545                         insn->operands = $2;
546                         $$ = insn;
547                   }
548                 ;
549
550 /* addc. */
551 insn_addscc     : OP_ADDSCC operlist_3 {
552                         struct instruction *insn = xmalloc(sizeof(struct instruction));
553                         insn->op = OP_ADDSCC;
554                         insn->operands = $2;
555                         $$ = insn;
556                   }
557                 ;
558
559 /* sub */
560 insn_sub        : OP_SUB operlist_3 {
561                         struct instruction *insn = xmalloc(sizeof(struct instruction));
562                         insn->op = OP_SUB;
563                         insn->operands = $2;
564                         $$ = insn;
565                   }
566                 ;
567
568 /* sub. */
569 insn_subsc      : OP_SUBSC operlist_3 {
570                         struct instruction *insn = xmalloc(sizeof(struct instruction));
571                         insn->op = OP_SUBSC;
572                         insn->operands = $2;
573                         $$ = insn;
574                   }
575                 ;
576
577 /* subc */
578 insn_subc       : OP_SUBC operlist_3 {
579                         struct instruction *insn = xmalloc(sizeof(struct instruction));
580                         insn->op = OP_SUBC;
581                         insn->operands = $2;
582                         $$ = insn;
583                   }
584                 ;
585
586 /* subc. */
587 insn_subscc     : OP_SUBSCC operlist_3 {
588                         struct instruction *insn = xmalloc(sizeof(struct instruction));
589                         insn->op = OP_SUBSCC;
590                         insn->operands = $2;
591                         $$ = insn;
592                   }
593                 ;
594
595 insn_sra        : OP_SRA operlist_3 {
596                         struct instruction *insn = xmalloc(sizeof(struct instruction));
597                         insn->op = OP_SRA;
598                         insn->operands = $2;
599                         $$ = insn;
600                   }
601                 ;
602
603 insn_or         : OP_OR operlist_3 {
604                         struct instruction *insn = xmalloc(sizeof(struct instruction));
605                         insn->op = OP_OR;
606                         insn->operands = $2;
607                         $$ = insn;
608                   }
609                 ;
610
611 insn_and        : OP_AND operlist_3 {
612                         struct instruction *insn = xmalloc(sizeof(struct instruction));
613                         insn->op = OP_AND;
614                         insn->operands = $2;
615                         $$ = insn;
616                   }
617                 ;
618
619 insn_xor        : OP_XOR operlist_3 {
620                         struct instruction *insn = xmalloc(sizeof(struct instruction));
621                         insn->op = OP_XOR;
622                         insn->operands = $2;
623                         $$ = insn;
624                   }
625                 ;
626
627 insn_sr         : OP_SR operlist_3 {
628                         struct instruction *insn = xmalloc(sizeof(struct instruction));
629                         insn->op = OP_SR;
630                         insn->operands = $2;
631                         $$ = insn;
632                   }
633                 ;
634
635 insn_srx        : OP_SRX extended_operlist {
636                         struct instruction *insn = xmalloc(sizeof(struct instruction));
637                         insn->op = OP_SRX;
638                         insn->operands = $2;
639                         $$ = insn;
640                   }
641                 ;
642
643 insn_sl         : OP_SL operlist_3 {
644                         struct instruction *insn = xmalloc(sizeof(struct instruction));
645                         insn->op = OP_SL;
646                         insn->operands = $2;
647                         $$ = insn;
648                   }
649                 ;
650
651 insn_rl         : OP_RL operlist_3 {
652                         struct instruction *insn = xmalloc(sizeof(struct instruction));
653                         insn->op = OP_RL;
654                         insn->operands = $2;
655                         $$ = insn;
656                   }
657                 ;
658
659 insn_rr         : OP_RR operlist_3 {
660                         struct instruction *insn = xmalloc(sizeof(struct instruction));
661                         insn->op = OP_RR;
662                         insn->operands = $2;
663                         $$ = insn;
664                   }
665                 ;
666
667 insn_nand       : OP_NAND operlist_3 {
668                         struct instruction *insn = xmalloc(sizeof(struct instruction));
669                         insn->op = OP_NAND;
670                         insn->operands = $2;
671                         $$ = insn;
672                   }
673                 ;
674
675 insn_orx        : OP_ORX extended_operlist {
676                         struct instruction *insn = xmalloc(sizeof(struct instruction));
677                         insn->op = OP_ORX;
678                         insn->operands = $2;
679                         $$ = insn;
680                   }
681                 ;
682
683 insn_mov        : OP_MOV operlist_2 {
684                         struct instruction *insn = xmalloc(sizeof(struct instruction));
685                         insn->op = OP_MOV;
686                         insn->operands = $2;
687                         $$ = insn;
688                   }
689                 ;
690
691 insn_jmp        : OP_JMP labelref {
692                         struct instruction *insn = xmalloc(sizeof(struct instruction));
693                         struct operlist *ol = xmalloc(sizeof(struct operlist));
694                         ol->oper[0] = $2;
695                         insn->op = OP_JMP;
696                         insn->operands = ol;
697                         $$ = insn;
698                   }
699                 ;
700
701 insn_jand       : OP_JAND operlist_3 {
702                         struct instruction *insn = xmalloc(sizeof(struct instruction));
703                         insn->op = OP_JAND;
704                         insn->operands = $2;
705                         $$ = insn;
706                   }
707                 ;
708
709 insn_jnand      : OP_JNAND operlist_3 {
710                         struct instruction *insn = xmalloc(sizeof(struct instruction));
711                         insn->op = OP_JNAND;
712                         insn->operands = $2;
713                         $$ = insn;
714                   }
715                 ;
716
717 insn_js         : OP_JS operlist_3 {
718                         struct instruction *insn = xmalloc(sizeof(struct instruction));
719                         insn->op = OP_JS;
720                         insn->operands = $2;
721                         $$ = insn;
722                   }
723                 ;
724
725 insn_jns        : OP_JNS operlist_3 {
726                         struct instruction *insn = xmalloc(sizeof(struct instruction));
727                         insn->op = OP_JNS;
728                         insn->operands = $2;
729                         $$ = insn;
730                   }
731                 ;
732
733 insn_je         : OP_JE operlist_3 {
734                         struct instruction *insn = xmalloc(sizeof(struct instruction));
735                         insn->op = OP_JE;
736                         insn->operands = $2;
737                         $$ = insn;
738                   }
739                 ;
740
741 insn_jne        : OP_JNE operlist_3 {
742                         struct instruction *insn = xmalloc(sizeof(struct instruction));
743                         insn->op = OP_JNE;
744                         insn->operands = $2;
745                         $$ = insn;
746                   }
747                 ;
748
749 insn_jls        : OP_JLS operlist_3 {
750                         struct instruction *insn = xmalloc(sizeof(struct instruction));
751                         insn->op = OP_JLS;
752                         insn->operands = $2;
753                         $$ = insn;
754                   }
755                 ;
756
757 insn_jges       : OP_JGES operlist_3 {
758                         struct instruction *insn = xmalloc(sizeof(struct instruction));
759                         insn->op = OP_JGES;
760                         insn->operands = $2;
761                         $$ = insn;
762                   }
763                 ;
764
765 insn_jgs        : OP_JGS operlist_3 {
766                         struct instruction *insn = xmalloc(sizeof(struct instruction));
767                         insn->op = OP_JGS;
768                         insn->operands = $2;
769                         $$ = insn;
770                   }
771                 ;
772
773 insn_jles       : OP_JLES operlist_3 {
774                         struct instruction *insn = xmalloc(sizeof(struct instruction));
775                         insn->op = OP_JLES;
776                         insn->operands = $2;
777                         $$ = insn;
778                   }
779                 ;
780
781 insn_jl         : OP_JL operlist_3 {
782                         struct instruction *insn = xmalloc(sizeof(struct instruction));
783                         insn->op = OP_JL;
784                         insn->operands = $2;
785                         $$ = insn;
786                   }
787                 ;
788
789 insn_jge        : OP_JGE operlist_3 {
790                         struct instruction *insn = xmalloc(sizeof(struct instruction));
791                         insn->op = OP_JGE;
792                         insn->operands = $2;
793                         $$ = insn;
794                   }
795                 ;
796
797 insn_jg         : OP_JG operlist_3 {
798                         struct instruction *insn = xmalloc(sizeof(struct instruction));
799                         insn->op = OP_JG;
800                         insn->operands = $2;
801                         $$ = insn;
802                   }
803                 ;
804
805 insn_jle        : OP_JLE operlist_3 {
806                         struct instruction *insn = xmalloc(sizeof(struct instruction));
807                         insn->op = OP_JLE;
808                         insn->operands = $2;
809                         $$ = insn;
810                   }
811                 ;
812
813 insn_jzx        : OP_JZX extended_operlist {
814                         struct instruction *insn = xmalloc(sizeof(struct instruction));
815                         insn->op = OP_JZX;
816                         insn->operands = $2;
817                         $$ = insn;
818                   }
819                 ;
820
821 insn_jnzx       : OP_JNZX extended_operlist {
822                         struct instruction *insn = xmalloc(sizeof(struct instruction));
823                         insn->op = OP_JNZX;
824                         insn->operands = $2;
825                         $$ = insn;
826                   }
827                 ;
828
829 insn_jext       : OP_JEXT external_jump_operands {
830                         struct instruction *insn = xmalloc(sizeof(struct instruction));
831                         insn->op = OP_JEXT;
832                         insn->operands = $2;
833                         $$ = insn;
834                   }
835                 ;
836
837 insn_jnext      : OP_JNEXT external_jump_operands {
838                         struct instruction *insn = xmalloc(sizeof(struct instruction));
839                         insn->op = OP_JNEXT;
840                         insn->operands = $2;
841                         $$ = insn;
842                   }
843                 ;
844
845 linkreg         : LR regnr {
846                         $$ = $2;
847                   }
848                 ;
849
850 insn_call       : OP_CALL linkreg COMMA labelref {
851                         struct instruction *insn = xmalloc(sizeof(struct instruction));
852                         struct operlist *ol = xmalloc(sizeof(struct operlist));
853                         struct operand *oper_lr = xmalloc(sizeof(struct operand));
854                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
855                         oper_zero->type = OPER_RAW;
856                         oper_zero->u.raw = 0;
857                         oper_lr->type = OPER_RAW;
858                         oper_lr->u.raw = (unsigned long)$2;
859                         ol->oper[0] = oper_lr;
860                         ol->oper[1] = oper_zero;
861                         ol->oper[2] = $4;
862                         insn->op = OP_CALL;
863                         insn->operands = ol;
864                         $$ = insn;
865                   }
866                 ;
867
868 insn_ret        : OP_RET linkreg COMMA linkreg {
869                         struct instruction *insn = xmalloc(sizeof(struct instruction));
870                         struct operlist *ol = xmalloc(sizeof(struct operlist));
871                         struct operand *oper_lr0 = xmalloc(sizeof(struct operand));
872                         struct operand *oper_lr1 = xmalloc(sizeof(struct operand));
873                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
874                         oper_zero->type = OPER_RAW;
875                         oper_zero->u.raw = 0;
876                         oper_lr0->type = OPER_RAW;
877                         oper_lr0->u.raw = (unsigned long)$2;
878                         oper_lr1->type = OPER_RAW;
879                         oper_lr1->u.raw = (unsigned long)$4;
880                         ol->oper[0] = oper_lr0;
881                         ol->oper[1] = oper_zero;
882                         ol->oper[2] = oper_lr1;
883                         insn->op = OP_RET;
884                         insn->operands = ol;
885                         $$ = insn;
886                   }
887                 ;
888
889 insn_tkiph      : OP_TKIPH operlist_2 {
890                         struct instruction *insn = xmalloc(sizeof(struct instruction));
891                         struct operlist *ol = $2;
892                         struct operand *flags = xmalloc(sizeof(struct operand));
893                         struct immediate *imm = xmalloc(sizeof(struct immediate));
894                         imm->imm = 0x1;
895                         flags->type = OPER_IMM;
896                         flags->u.imm = imm;
897                         ol->oper[2] = ol->oper[1];
898                         ol->oper[1] = flags;
899                         insn->op = OP_TKIPH;
900                         insn->operands = ol;
901                         $$ = insn;
902                   }
903                 ;
904
905 insn_tkiphs     : OP_TKIPHS operlist_2 {
906                         struct instruction *insn = xmalloc(sizeof(struct instruction));
907                         struct operlist *ol = $2;
908                         struct operand *flags = xmalloc(sizeof(struct operand));
909                         struct immediate *imm = xmalloc(sizeof(struct immediate));
910                         imm->imm = 0x1 | 0x2;
911                         flags->type = OPER_IMM;
912                         flags->u.imm = imm;
913                         ol->oper[2] = ol->oper[1];
914                         ol->oper[1] = flags;
915                         insn->op = OP_TKIPH;
916                         insn->operands = ol;
917                         $$ = insn;
918                   }
919                 ;
920
921 insn_tkipl      : OP_TKIPL operlist_2 {
922                         struct instruction *insn = xmalloc(sizeof(struct instruction));
923                         struct operlist *ol = $2;
924                         struct operand *flags = xmalloc(sizeof(struct operand));
925                         struct immediate *imm = xmalloc(sizeof(struct immediate));
926                         imm->imm = 0x0;
927                         flags->type = OPER_IMM;
928                         flags->u.imm = imm;
929                         ol->oper[2] = ol->oper[1];
930                         ol->oper[1] = flags;
931                         insn->op = OP_TKIPH;
932                         insn->operands = ol;
933                         $$ = insn;
934                   }
935                 ;
936
937 insn_tkipls     : OP_TKIPLS operlist_2 {
938                         struct instruction *insn = xmalloc(sizeof(struct instruction));
939                         struct operlist *ol = $2;
940                         struct operand *flags = xmalloc(sizeof(struct operand));
941                         struct immediate *imm = xmalloc(sizeof(struct immediate));
942                         imm->imm = 0x0 | 0x2;
943                         flags->type = OPER_IMM;
944                         flags->u.imm = imm;
945                         ol->oper[2] = ol->oper[1];
946                         ol->oper[1] = flags;
947                         insn->op = OP_TKIPH;
948                         insn->operands = ol;
949                         $$ = insn;
950                   }
951                 ;
952
953 insn_nap        : OP_NAP {
954                         struct instruction *insn = xmalloc(sizeof(struct instruction));
955                         struct operlist *ol = xmalloc(sizeof(struct operlist));
956                         struct operand *regop = xmalloc(sizeof(struct operand));
957                         struct operand *zeroop = xmalloc(sizeof(struct operand));
958                         struct registr *r0 = xmalloc(sizeof(struct registr));
959                         r0->type = GPR;
960                         r0->nr = 0;
961                         regop->type = OPER_REG;
962                         regop->u.reg = r0;
963                         zeroop->type = OPER_RAW;
964                         zeroop->u.raw = 0x000;
965                         ol->oper[0] = regop;
966                         ol->oper[1] = regop;
967                         ol->oper[2] = zeroop;
968                         insn->op = OP_NAP;
969                         insn->operands = ol;
970                         $$ = insn;
971                   }
972                 ;
973
974 insn_raw        : raw_code operlist_3 {
975                         struct instruction *insn = xmalloc(sizeof(struct instruction));
976                         insn->op = RAW_CODE;
977                         insn->operands = $2;
978                         insn->opcode = (unsigned long)$1;
979                         $$ = insn;
980                   }
981                 ;
982
983 raw_code        : RAW_CODE {
984                         yytext++; /* skip @ */
985                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
986                   }
987                 ;
988
989 extended_operlist : decnum COMMA decnum COMMA operand COMMA operand COMMA operand {
990                         struct operlist *ol = xmalloc(sizeof(struct operlist));
991                         struct operand *mask_oper = xmalloc(sizeof(struct operand));
992                         struct operand *shift_oper = xmalloc(sizeof(struct operand));
993                         mask_oper->type = OPER_RAW;
994                         mask_oper->u.raw = (unsigned long)$1;
995                         shift_oper->type = OPER_RAW;
996                         shift_oper->u.raw = (unsigned long)$3;
997                         ol->oper[0] = mask_oper;
998                         ol->oper[1] = shift_oper;
999                         ol->oper[2] = $5;
1000                         ol->oper[3] = $7;
1001                         ol->oper[4] = store_oper_sanity($9);
1002                         $$ = ol;
1003                   }
1004                 ;
1005
1006 external_jump_operands : imm COMMA operand COMMA operand COMMA labelref {
1007                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1008                         struct operand *cond = xmalloc(sizeof(struct operand));
1009                         cond->type = OPER_IMM;
1010                         cond->u.imm = $1;
1011                         ol->oper[0] = cond;
1012                         ol->oper[1] = $3;
1013                         ol->oper[2] = $5;
1014                         ol->oper[3] = $7;
1015                         $$ = ol;
1016                   }
1017                 ;
1018
1019 operlist_2      : operand COMMA operand {
1020                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1021                         ol->oper[0] = $1;
1022                         ol->oper[1] = store_oper_sanity($3);
1023                         $$ = ol;
1024                   }
1025                 ;
1026
1027 operlist_3      : operand COMMA operand COMMA operand {
1028                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1029                         ol->oper[0] = $1;
1030                         ol->oper[1] = $3;
1031                         ol->oper[2] = store_oper_sanity($5);
1032                         $$ = ol;
1033                   }
1034                 ;
1035
1036 operand         : reg {
1037                         struct operand *oper = xmalloc(sizeof(struct operand));
1038                         oper->type = OPER_REG;
1039                         oper->u.reg = $1;
1040                         $$ = oper;
1041                   }
1042                 | mem {
1043                         struct operand *oper = xmalloc(sizeof(struct operand));
1044                         oper->type = OPER_MEM;
1045                         oper->u.mem = $1;
1046                         $$ = oper;
1047                   }
1048                 | raw_code {
1049                         struct operand *oper = xmalloc(sizeof(struct operand));
1050                         oper->type = OPER_RAW;
1051                         oper->u.raw = (unsigned long)$1;
1052                         $$ = oper;
1053                   }
1054                 | imm {
1055                         struct operand *oper = xmalloc(sizeof(struct operand));
1056                         oper->type = OPER_IMM;
1057                         oper->u.imm = $1;
1058                         $$ = oper;
1059                   }
1060                 | labelref {
1061                         $$ = $1;
1062                   }
1063                 ;
1064
1065 reg             : GPR regnr {
1066                         struct registr *reg = xmalloc(sizeof(struct registr));
1067                         reg->type = GPR;
1068                         reg->nr = (unsigned long)$2;
1069                         $$ = reg;
1070                   }
1071                 | SPR {
1072                         struct registr *reg = xmalloc(sizeof(struct registr));
1073                         reg->type = SPR;
1074                         yytext += 3; /* skip "spr" */
1075                         reg->nr = strtoul(yytext, NULL, 16);
1076                         $$ = reg;
1077                   }
1078                 | OFFR regnr {
1079                         struct registr *reg = xmalloc(sizeof(struct registr));
1080                         reg->type = OFFR;
1081                         reg->nr = (unsigned long)$2;
1082                         $$ = reg;
1083                   }
1084                 ;
1085
1086 mem             : BRACK_OPEN hexnum_decnum BRACK_CLOSE {
1087                         struct memory *mem = xmalloc(sizeof(struct memory));
1088                         mem->type = MEM_DIRECT;
1089                         mem->offset = (unsigned long)$2;
1090                         $$ = mem;
1091                   }
1092                 | BRACK_OPEN hexnum_decnum COMMA OFFR regnr BRACK_CLOSE {
1093                         struct memory *mem = xmalloc(sizeof(struct memory));
1094                         mem->type = MEM_INDIRECT;
1095                         mem->offset = (unsigned long)$2;
1096                         mem->offr_nr = (unsigned long)$5;
1097                         $$ = mem;
1098                   }
1099                 ;
1100
1101 imm             : hexnum {
1102                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1103                         imm->imm = (unsigned long)$1;
1104                         $$ = imm;
1105                   }
1106                 | 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 }