65bd39dbe1796bbda4c44bf2db9fb0c28236124d
[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    : /* empty */
54         | line statement {
55                 struct statement *s = $2;
56                 if (section != SECTION_TEXT)
57                         yyerror("Microcode text instruction in non .text section");
58                 memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo));
59                 list_add_tail(&s->list, &infile.sl);
60           }
61         | line section_switch {
62           }
63         | line ivals_write {
64                 struct initval_op *io = $2;
65                 if (section != SECTION_IVALS)
66                         yyerror("InitVals write in non .initvals section");
67                 memcpy(&io->info, &cur_lineinfo, sizeof(struct lineinfo));
68                 INIT_LIST_HEAD(&io->list);
69                 list_add_tail(&io->list, &cur_initvals_sect->ops);
70           }
71         ;
72
73 section_switch  : SECTION_TEXT {
74                         section = SECTION_TEXT;
75                   }
76                 | SECTION_IVALS PAREN_OPEN identifier PAREN_CLOSE {
77                         const char *sectname = $3;
78                         struct initvals_sect *s;
79                         cur_initvals_sect = NULL;
80                         /* Search if there already is a section by that name. */
81                         list_for_each_entry(s, &infile.ivals, list) {
82                                 if (strcmp(sectname, s->name) == 0)
83                                         cur_initvals_sect = s;
84                         }
85                         if (!cur_initvals_sect) {
86                                 /* Not found, create a new one. */
87                                 s = xmalloc(sizeof(struct initvals_sect));
88                                 s->name = sectname;
89                                 INIT_LIST_HEAD(&s->ops);
90                                 INIT_LIST_HEAD(&s->list);
91                                 list_add_tail(&s->list, &infile.ivals);
92                                 cur_initvals_sect = s;
93                         }
94                         section = SECTION_IVALS;
95                   }
96                 ;
97
98 ivals_write     : IVAL_MMIO16 hexnum_decnum COMMA hexnum_decnum {
99                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
100                         iop->type = IVAL_W_MMIO16;
101                         iop->args[0] = (unsigned int)(unsigned long)$2;
102                         iop->args[1] = (unsigned int)(unsigned long)$4;
103                         $$ = iop;
104                   }
105                 | IVAL_MMIO32 hexnum_decnum COMMA hexnum_decnum {
106                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
107                         iop->type = IVAL_W_MMIO32;
108                         iop->args[0] = (unsigned int)(unsigned long)$2;
109                         iop->args[1] = (unsigned int)(unsigned long)$4;
110                         $$ = iop;
111                   }
112                 | IVAL_PHY hexnum_decnum COMMA hexnum_decnum {
113                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
114                         iop->type = IVAL_W_PHY;
115                         iop->args[0] = (unsigned int)(unsigned long)$2;
116                         iop->args[1] = (unsigned int)(unsigned long)$4;
117                         $$ = iop;
118                   }
119                 | IVAL_RADIO hexnum_decnum COMMA hexnum_decnum {
120                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
121                         iop->type = IVAL_W_RADIO;
122                         iop->args[0] = (unsigned int)(unsigned long)$2;
123                         iop->args[1] = (unsigned int)(unsigned long)$4;
124                         $$ = iop;
125                   }
126                 | IVAL_SHM16 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
127                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
128                         iop->type = IVAL_W_SHM16;
129                         iop->args[0] = (unsigned int)(unsigned long)$2;
130                         iop->args[1] = (unsigned int)(unsigned long)$4;
131                         iop->args[2] = (unsigned int)(unsigned long)$6;
132                         $$ = iop;
133                   }
134                 | IVAL_SHM32 hexnum_decnum COMMA hexnum_decnum COMMA hexnum_decnum {
135                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
136                         iop->type = IVAL_W_SHM32;
137                         iop->args[0] = (unsigned int)(unsigned long)$2;
138                         iop->args[1] = (unsigned int)(unsigned long)$4;
139                         iop->args[2] = (unsigned int)(unsigned long)$6;
140                         $$ = iop;
141                   }
142                 ;
143
144 statement       : asmdir {
145                         struct statement *s = xmalloc(sizeof(struct statement));
146                         INIT_LIST_HEAD(&s->list);
147                         s->type = STMT_ASMDIR;
148                         s->u.asmdir = $1;
149                         $$ = s;
150                   }
151                 | label {
152                         struct statement *s = xmalloc(sizeof(struct statement));
153                         INIT_LIST_HEAD(&s->list);
154                         s->type = STMT_LABEL;
155                         s->u.label = $1;
156                         $$ = s;
157                   }
158                 | insn_add {
159                         struct statement *s = xmalloc(sizeof(struct statement));
160                         INIT_LIST_HEAD(&s->list);
161                         s->type = STMT_INSN;
162                         s->u.insn = $1;
163                         $$ = s;
164                   }
165                 | insn_addsc {
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_addc {
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_addscc {
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_sub {
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_subsc {
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_subc {
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_subscc {
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_sra {
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_or {
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_and {
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_xor {
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_sr {
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_srx {
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_sl {
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_rl {
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_rr {
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_nand {
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_orx {
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_mov {
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_jmp {
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_jand {
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_jnand {
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_js {
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_jns {
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_je {
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_jne {
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_jls {
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_jges {
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_jgs {
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_jles {
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_jl {
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_jge {
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_jg {
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_jle {
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_jzx {
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_jnzx {
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_jext {
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_jnext {
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_call {
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_ret {
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_tkiph {
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_tkiphs {
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_tkipl {
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_tkipls {
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_nap {
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_raw {
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                 ;
488
489 /* ASM directives */
490 asmdir          : ASM_ARCH hexnum_decnum {
491                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
492                         ad->type = ADIR_ARCH;
493                         ad->u.arch = (unsigned int)(unsigned long)$2;
494                         $$ = ad;
495                   }
496                 | ASM_START identifier {
497                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
498                         struct label *label = xmalloc(sizeof(struct label));
499                         label->name = $2;
500                         label->direction = LABELREF_ABSOLUTE;
501                         ad->type = ADIR_START;
502                         ad->u.start = label;
503                         $$ = ad;
504                   }
505                 ;
506
507 label           : LABEL {
508                         struct label *label = xmalloc(sizeof(struct label));
509                         char *l;
510                         l = xstrdup(yytext);
511                         l[strlen(l) - 1] = '\0';
512                         label->name = l;
513                         $$ = label;
514                   }
515                 ;
516
517 /* add */
518 insn_add        : OP_ADD operlist_3 {
519                         struct instruction *insn = xmalloc(sizeof(struct instruction));
520                         insn->op = OP_ADD;
521                         insn->operands = $2;
522                         $$ = insn;
523                   }
524                 ;
525
526 /* add. */
527 insn_addsc      : OP_ADDSC operlist_3 {
528                         struct instruction *insn = xmalloc(sizeof(struct instruction));
529                         insn->op = OP_ADDSC;
530                         insn->operands = $2;
531                         $$ = insn;
532                   }
533                 ;
534
535 /* addc */
536 insn_addc       : OP_ADDC operlist_3 {
537                         struct instruction *insn = xmalloc(sizeof(struct instruction));
538                         insn->op = OP_ADDC;
539                         insn->operands = $2;
540                         $$ = insn;
541                   }
542                 ;
543
544 /* addc. */
545 insn_addscc     : OP_ADDSCC operlist_3 {
546                         struct instruction *insn = xmalloc(sizeof(struct instruction));
547                         insn->op = OP_ADDSCC;
548                         insn->operands = $2;
549                         $$ = insn;
550                   }
551                 ;
552
553 /* sub */
554 insn_sub        : OP_SUB operlist_3 {
555                         struct instruction *insn = xmalloc(sizeof(struct instruction));
556                         insn->op = OP_SUB;
557                         insn->operands = $2;
558                         $$ = insn;
559                   }
560                 ;
561
562 /* sub. */
563 insn_subsc      : OP_SUBSC operlist_3 {
564                         struct instruction *insn = xmalloc(sizeof(struct instruction));
565                         insn->op = OP_SUBSC;
566                         insn->operands = $2;
567                         $$ = insn;
568                   }
569                 ;
570
571 /* subc */
572 insn_subc       : OP_SUBC operlist_3 {
573                         struct instruction *insn = xmalloc(sizeof(struct instruction));
574                         insn->op = OP_SUBC;
575                         insn->operands = $2;
576                         $$ = insn;
577                   }
578                 ;
579
580 /* subc. */
581 insn_subscc     : OP_SUBSCC operlist_3 {
582                         struct instruction *insn = xmalloc(sizeof(struct instruction));
583                         insn->op = OP_SUBSCC;
584                         insn->operands = $2;
585                         $$ = insn;
586                   }
587                 ;
588
589 insn_sra        : OP_SRA operlist_3 {
590                         struct instruction *insn = xmalloc(sizeof(struct instruction));
591                         insn->op = OP_SRA;
592                         insn->operands = $2;
593                         $$ = insn;
594                   }
595                 ;
596
597 insn_or         : OP_OR operlist_3 {
598                         struct instruction *insn = xmalloc(sizeof(struct instruction));
599                         insn->op = OP_OR;
600                         insn->operands = $2;
601                         $$ = insn;
602                   }
603                 ;
604
605 insn_and        : OP_AND operlist_3 {
606                         struct instruction *insn = xmalloc(sizeof(struct instruction));
607                         insn->op = OP_AND;
608                         insn->operands = $2;
609                         $$ = insn;
610                   }
611                 ;
612
613 insn_xor        : OP_XOR operlist_3 {
614                         struct instruction *insn = xmalloc(sizeof(struct instruction));
615                         insn->op = OP_XOR;
616                         insn->operands = $2;
617                         $$ = insn;
618                   }
619                 ;
620
621 insn_sr         : OP_SR operlist_3 {
622                         struct instruction *insn = xmalloc(sizeof(struct instruction));
623                         insn->op = OP_SR;
624                         insn->operands = $2;
625                         $$ = insn;
626                   }
627                 ;
628
629 insn_srx        : OP_SRX extended_operlist {
630                         struct instruction *insn = xmalloc(sizeof(struct instruction));
631                         insn->op = OP_SRX;
632                         insn->operands = $2;
633                         $$ = insn;
634                   }
635                 ;
636
637 insn_sl         : OP_SL operlist_3 {
638                         struct instruction *insn = xmalloc(sizeof(struct instruction));
639                         insn->op = OP_SL;
640                         insn->operands = $2;
641                         $$ = insn;
642                   }
643                 ;
644
645 insn_rl         : OP_RL operlist_3 {
646                         struct instruction *insn = xmalloc(sizeof(struct instruction));
647                         insn->op = OP_RL;
648                         insn->operands = $2;
649                         $$ = insn;
650                   }
651                 ;
652
653 insn_rr         : OP_RR operlist_3 {
654                         struct instruction *insn = xmalloc(sizeof(struct instruction));
655                         insn->op = OP_RR;
656                         insn->operands = $2;
657                         $$ = insn;
658                   }
659                 ;
660
661 insn_nand       : OP_NAND operlist_3 {
662                         struct instruction *insn = xmalloc(sizeof(struct instruction));
663                         insn->op = OP_NAND;
664                         insn->operands = $2;
665                         $$ = insn;
666                   }
667                 ;
668
669 insn_orx        : OP_ORX extended_operlist {
670                         struct instruction *insn = xmalloc(sizeof(struct instruction));
671                         insn->op = OP_ORX;
672                         insn->operands = $2;
673                         $$ = insn;
674                   }
675                 ;
676
677 insn_mov        : OP_MOV operlist_2 {
678                         struct instruction *insn = xmalloc(sizeof(struct instruction));
679                         insn->op = OP_MOV;
680                         insn->operands = $2;
681                         $$ = insn;
682                   }
683                 ;
684
685 insn_jmp        : OP_JMP labelref {
686                         struct instruction *insn = xmalloc(sizeof(struct instruction));
687                         struct operlist *ol = xmalloc(sizeof(struct operlist));
688                         ol->oper[0] = $2;
689                         insn->op = OP_JMP;
690                         insn->operands = ol;
691                         $$ = insn;
692                   }
693                 ;
694
695 insn_jand       : OP_JAND operlist_3 {
696                         struct instruction *insn = xmalloc(sizeof(struct instruction));
697                         insn->op = OP_JAND;
698                         insn->operands = $2;
699                         $$ = insn;
700                   }
701                 ;
702
703 insn_jnand      : OP_JNAND operlist_3 {
704                         struct instruction *insn = xmalloc(sizeof(struct instruction));
705                         insn->op = OP_JNAND;
706                         insn->operands = $2;
707                         $$ = insn;
708                   }
709                 ;
710
711 insn_js         : OP_JS operlist_3 {
712                         struct instruction *insn = xmalloc(sizeof(struct instruction));
713                         insn->op = OP_JS;
714                         insn->operands = $2;
715                         $$ = insn;
716                   }
717                 ;
718
719 insn_jns        : OP_JNS operlist_3 {
720                         struct instruction *insn = xmalloc(sizeof(struct instruction));
721                         insn->op = OP_JNS;
722                         insn->operands = $2;
723                         $$ = insn;
724                   }
725                 ;
726
727 insn_je         : OP_JE operlist_3 {
728                         struct instruction *insn = xmalloc(sizeof(struct instruction));
729                         insn->op = OP_JE;
730                         insn->operands = $2;
731                         $$ = insn;
732                   }
733                 ;
734
735 insn_jne        : OP_JNE operlist_3 {
736                         struct instruction *insn = xmalloc(sizeof(struct instruction));
737                         insn->op = OP_JNE;
738                         insn->operands = $2;
739                         $$ = insn;
740                   }
741                 ;
742
743 insn_jls        : OP_JLS operlist_3 {
744                         struct instruction *insn = xmalloc(sizeof(struct instruction));
745                         insn->op = OP_JLS;
746                         insn->operands = $2;
747                         $$ = insn;
748                   }
749                 ;
750
751 insn_jges       : OP_JGES operlist_3 {
752                         struct instruction *insn = xmalloc(sizeof(struct instruction));
753                         insn->op = OP_JGES;
754                         insn->operands = $2;
755                         $$ = insn;
756                   }
757                 ;
758
759 insn_jgs        : OP_JGS operlist_3 {
760                         struct instruction *insn = xmalloc(sizeof(struct instruction));
761                         insn->op = OP_JGS;
762                         insn->operands = $2;
763                         $$ = insn;
764                   }
765                 ;
766
767 insn_jles       : OP_JLES operlist_3 {
768                         struct instruction *insn = xmalloc(sizeof(struct instruction));
769                         insn->op = OP_JLES;
770                         insn->operands = $2;
771                         $$ = insn;
772                   }
773                 ;
774
775 insn_jl         : OP_JL operlist_3 {
776                         struct instruction *insn = xmalloc(sizeof(struct instruction));
777                         insn->op = OP_JL;
778                         insn->operands = $2;
779                         $$ = insn;
780                   }
781                 ;
782
783 insn_jge        : OP_JGE operlist_3 {
784                         struct instruction *insn = xmalloc(sizeof(struct instruction));
785                         insn->op = OP_JGE;
786                         insn->operands = $2;
787                         $$ = insn;
788                   }
789                 ;
790
791 insn_jg         : OP_JG operlist_3 {
792                         struct instruction *insn = xmalloc(sizeof(struct instruction));
793                         insn->op = OP_JG;
794                         insn->operands = $2;
795                         $$ = insn;
796                   }
797                 ;
798
799 insn_jle        : OP_JLE operlist_3 {
800                         struct instruction *insn = xmalloc(sizeof(struct instruction));
801                         insn->op = OP_JLE;
802                         insn->operands = $2;
803                         $$ = insn;
804                   }
805                 ;
806
807 insn_jzx        : OP_JZX extended_operlist {
808                         struct instruction *insn = xmalloc(sizeof(struct instruction));
809                         insn->op = OP_JZX;
810                         insn->operands = $2;
811                         $$ = insn;
812                   }
813                 ;
814
815 insn_jnzx       : OP_JNZX extended_operlist {
816                         struct instruction *insn = xmalloc(sizeof(struct instruction));
817                         insn->op = OP_JNZX;
818                         insn->operands = $2;
819                         $$ = insn;
820                   }
821                 ;
822
823 insn_jext       : OP_JEXT external_jump_operands {
824                         struct instruction *insn = xmalloc(sizeof(struct instruction));
825                         insn->op = OP_JEXT;
826                         insn->operands = $2;
827                         $$ = insn;
828                   }
829                 ;
830
831 insn_jnext      : OP_JNEXT external_jump_operands {
832                         struct instruction *insn = xmalloc(sizeof(struct instruction));
833                         insn->op = OP_JNEXT;
834                         insn->operands = $2;
835                         $$ = insn;
836                   }
837                 ;
838
839 linkreg         : LR regnr {
840                         $$ = $2;
841                   }
842                 ;
843
844 insn_call       : OP_CALL linkreg COMMA labelref {
845                         struct instruction *insn = xmalloc(sizeof(struct instruction));
846                         struct operlist *ol = xmalloc(sizeof(struct operlist));
847                         struct operand *oper_lr = xmalloc(sizeof(struct operand));
848                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
849                         oper_zero->type = OPER_RAW;
850                         oper_zero->u.raw = 0;
851                         oper_lr->type = OPER_RAW;
852                         oper_lr->u.raw = (unsigned long)$2;
853                         ol->oper[0] = oper_lr;
854                         ol->oper[1] = oper_zero;
855                         ol->oper[2] = $4;
856                         insn->op = OP_CALL;
857                         insn->operands = ol;
858                         $$ = insn;
859                   }
860                 ;
861
862 insn_ret        : OP_RET linkreg COMMA linkreg {
863                         struct instruction *insn = xmalloc(sizeof(struct instruction));
864                         struct operlist *ol = xmalloc(sizeof(struct operlist));
865                         struct operand *oper_lr0 = xmalloc(sizeof(struct operand));
866                         struct operand *oper_lr1 = xmalloc(sizeof(struct operand));
867                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
868                         oper_zero->type = OPER_RAW;
869                         oper_zero->u.raw = 0;
870                         oper_lr0->type = OPER_RAW;
871                         oper_lr0->u.raw = (unsigned long)$2;
872                         oper_lr1->type = OPER_RAW;
873                         oper_lr1->u.raw = (unsigned long)$4;
874                         ol->oper[0] = oper_lr0;
875                         ol->oper[1] = oper_zero;
876                         ol->oper[2] = oper_lr1;
877                         insn->op = OP_RET;
878                         insn->operands = ol;
879                         $$ = insn;
880                   }
881                 ;
882
883 insn_tkiph      : OP_TKIPH operlist_2 {
884                         struct instruction *insn = xmalloc(sizeof(struct instruction));
885                         struct operlist *ol = $2;
886                         struct operand *flags = xmalloc(sizeof(struct operand));
887                         struct immediate *imm = xmalloc(sizeof(struct immediate));
888                         imm->imm = 0x1;
889                         flags->type = OPER_IMM;
890                         flags->u.imm = imm;
891                         ol->oper[2] = ol->oper[1];
892                         ol->oper[1] = flags;
893                         insn->op = OP_TKIPH;
894                         insn->operands = ol;
895                         $$ = insn;
896                   }
897                 ;
898
899 insn_tkiphs     : OP_TKIPHS operlist_2 {
900                         struct instruction *insn = xmalloc(sizeof(struct instruction));
901                         struct operlist *ol = $2;
902                         struct operand *flags = xmalloc(sizeof(struct operand));
903                         struct immediate *imm = xmalloc(sizeof(struct immediate));
904                         imm->imm = 0x1 | 0x2;
905                         flags->type = OPER_IMM;
906                         flags->u.imm = imm;
907                         ol->oper[2] = ol->oper[1];
908                         ol->oper[1] = flags;
909                         insn->op = OP_TKIPH;
910                         insn->operands = ol;
911                         $$ = insn;
912                   }
913                 ;
914
915 insn_tkipl      : OP_TKIPL operlist_2 {
916                         struct instruction *insn = xmalloc(sizeof(struct instruction));
917                         struct operlist *ol = $2;
918                         struct operand *flags = xmalloc(sizeof(struct operand));
919                         struct immediate *imm = xmalloc(sizeof(struct immediate));
920                         imm->imm = 0x0;
921                         flags->type = OPER_IMM;
922                         flags->u.imm = imm;
923                         ol->oper[2] = ol->oper[1];
924                         ol->oper[1] = flags;
925                         insn->op = OP_TKIPH;
926                         insn->operands = ol;
927                         $$ = insn;
928                   }
929                 ;
930
931 insn_tkipls     : OP_TKIPLS operlist_2 {
932                         struct instruction *insn = xmalloc(sizeof(struct instruction));
933                         struct operlist *ol = $2;
934                         struct operand *flags = xmalloc(sizeof(struct operand));
935                         struct immediate *imm = xmalloc(sizeof(struct immediate));
936                         imm->imm = 0x0 | 0x2;
937                         flags->type = OPER_IMM;
938                         flags->u.imm = imm;
939                         ol->oper[2] = ol->oper[1];
940                         ol->oper[1] = flags;
941                         insn->op = OP_TKIPH;
942                         insn->operands = ol;
943                         $$ = insn;
944                   }
945                 ;
946
947 insn_nap        : OP_NAP {
948                         struct instruction *insn = xmalloc(sizeof(struct instruction));
949                         struct operlist *ol = xmalloc(sizeof(struct operlist));
950                         struct operand *regop = xmalloc(sizeof(struct operand));
951                         struct operand *zeroop = xmalloc(sizeof(struct operand));
952                         struct registr *r0 = xmalloc(sizeof(struct registr));
953                         r0->type = GPR;
954                         r0->nr = 0;
955                         regop->type = OPER_REG;
956                         regop->u.reg = r0;
957                         zeroop->type = OPER_RAW;
958                         zeroop->u.raw = 0x000;
959                         ol->oper[0] = regop;
960                         ol->oper[1] = regop;
961                         ol->oper[2] = zeroop;
962                         insn->op = OP_NAP;
963                         insn->operands = ol;
964                         $$ = insn;
965                   }
966                 ;
967
968 insn_raw        : raw_code operlist_3 {
969                         struct instruction *insn = xmalloc(sizeof(struct instruction));
970                         insn->op = RAW_CODE;
971                         insn->operands = $2;
972                         insn->opcode = (unsigned long)$1;
973                         $$ = insn;
974                   }
975                 ;
976
977 raw_code        : RAW_CODE {
978                         yytext++; /* skip @ */
979                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
980                   }
981                 ;
982
983 extended_operlist : decnum COMMA decnum COMMA operand COMMA operand COMMA operand {
984                         struct operlist *ol = xmalloc(sizeof(struct operlist));
985                         struct operand *mask_oper = xmalloc(sizeof(struct operand));
986                         struct operand *shift_oper = xmalloc(sizeof(struct operand));
987                         mask_oper->type = OPER_RAW;
988                         mask_oper->u.raw = (unsigned long)$1;
989                         shift_oper->type = OPER_RAW;
990                         shift_oper->u.raw = (unsigned long)$3;
991                         ol->oper[0] = mask_oper;
992                         ol->oper[1] = shift_oper;
993                         ol->oper[2] = $5;
994                         ol->oper[3] = $7;
995                         ol->oper[4] = store_oper_sanity($9);
996                         $$ = ol;
997                   }
998                 ;
999
1000 external_jump_operands : hexnum COMMA operand COMMA operand COMMA labelref {
1001                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1002                         struct operand *cond = xmalloc(sizeof(struct operand));
1003                         cond->type = OPER_RAW;
1004                         cond->u.raw = (unsigned long)$1;
1005                         ol->oper[0] = cond;
1006                         ol->oper[1] = $3;
1007                         ol->oper[2] = $5;
1008                         ol->oper[3] = $7;
1009                         $$ = ol;
1010                   }
1011                 ;
1012
1013 operlist_2      : operand COMMA operand {
1014                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1015                         ol->oper[0] = $1;
1016                         ol->oper[1] = store_oper_sanity($3);
1017                         $$ = ol;
1018                   }
1019                 ;
1020
1021 operlist_3      : operand COMMA operand COMMA operand {
1022                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1023                         ol->oper[0] = $1;
1024                         ol->oper[1] = $3;
1025                         ol->oper[2] = store_oper_sanity($5);
1026                         $$ = ol;
1027                   }
1028                 ;
1029
1030 operand         : reg {
1031                         struct operand *oper = xmalloc(sizeof(struct operand));
1032                         oper->type = OPER_REG;
1033                         oper->u.reg = $1;
1034                         $$ = oper;
1035                   }
1036                 | mem {
1037                         struct operand *oper = xmalloc(sizeof(struct operand));
1038                         oper->type = OPER_MEM;
1039                         oper->u.mem = $1;
1040                         $$ = oper;
1041                   }
1042                 | raw_code {
1043                         struct operand *oper = xmalloc(sizeof(struct operand));
1044                         oper->type = OPER_RAW;
1045                         oper->u.raw = (unsigned long)$1;
1046                         $$ = oper;
1047                   }
1048                 | imm {
1049                         struct operand *oper = xmalloc(sizeof(struct operand));
1050                         oper->type = OPER_IMM;
1051                         oper->u.imm = $1;
1052                         $$ = oper;
1053                   }
1054                 | labelref {
1055                         $$ = $1;
1056                   }
1057                 ;
1058
1059 reg             : GPR regnr {
1060                         struct registr *reg = xmalloc(sizeof(struct registr));
1061                         reg->type = GPR;
1062                         reg->nr = (unsigned long)$2;
1063                         $$ = reg;
1064                   }
1065                 | SPR {
1066                         struct registr *reg = xmalloc(sizeof(struct registr));
1067                         reg->type = SPR;
1068                         yytext += 3; /* skip "spr" */
1069                         reg->nr = strtoul(yytext, NULL, 16);
1070                         $$ = reg;
1071                   }
1072                 | OFFR regnr {
1073                         struct registr *reg = xmalloc(sizeof(struct registr));
1074                         reg->type = OFFR;
1075                         reg->nr = (unsigned long)$2;
1076                         $$ = reg;
1077                   }
1078                 ;
1079
1080 mem             : BRACK_OPEN hexnum_decnum BRACK_CLOSE {
1081                         struct memory *mem = xmalloc(sizeof(struct memory));
1082                         mem->type = MEM_DIRECT;
1083                         mem->offset = (unsigned long)$2;
1084                         $$ = mem;
1085                   }
1086                 | BRACK_OPEN hexnum_decnum COMMA OFFR regnr BRACK_CLOSE {
1087                         struct memory *mem = xmalloc(sizeof(struct memory));
1088                         mem->type = MEM_INDIRECT;
1089                         mem->offset = (unsigned long)$2;
1090                         mem->offr_nr = (unsigned long)$5;
1091                         $$ = mem;
1092                   }
1093                 ;
1094
1095 imm             : hexnum {
1096                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1097                         imm->imm = (unsigned long)$1;
1098                         $$ = imm;
1099                   }
1100                 | decnum {
1101                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1102                         imm->imm = (unsigned long)$1;
1103                         $$ = imm;
1104                   }
1105                 | complex_imm {
1106                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1107                         imm->imm = (unsigned long)$1;
1108                         $$ = imm;
1109                   }
1110                 ;
1111
1112 complex_imm     : PAREN_OPEN complex_imm_arg complex_imm_oper complex_imm_arg PAREN_CLOSE {
1113                         unsigned long a = (unsigned long)$2;
1114                         unsigned long b = (unsigned long)$4;
1115                         unsigned long operation = (unsigned long)$3;
1116                         unsigned long res = 31337;
1117                         switch (operation) {
1118                         case PLUS:
1119                                 res = a + b;
1120                                 break;
1121                         case MINUS:
1122                                 res = a - b;
1123                                 break;
1124                         case MULTIPLY:
1125                                 res = a * b;
1126                                 break;
1127                         case DIVIDE:
1128                                 res = a / b;
1129                                 break;
1130                         case BITW_OR:
1131                                 res = a | b;
1132                                 break;
1133                         case BITW_AND:
1134                                 res = a & b;
1135                                 break;
1136                         case BITW_XOR:
1137                                 res = a ^ b;
1138                                 break;
1139                         case LEFTSHIFT:
1140                                 res = a << b;
1141                                 break;
1142                         case RIGHTSHIFT:
1143                                 res = a >> b;
1144                                 break;
1145                         default:
1146                                 yyerror("Internal parser BUG. complex_imm oper unknown");
1147                         }
1148                         $$ = (void *)res;
1149                   }
1150                 | PAREN_OPEN complex_imm PAREN_CLOSE {
1151                         $$ = $2;
1152                   }
1153                 | PAREN_OPEN BITW_NOT complex_imm PAREN_CLOSE {
1154                         unsigned long n = (unsigned long)$3;
1155                         n = ~n;
1156                         $$ = (void *)n;
1157                   }
1158                 | PAREN_OPEN complex_imm_const PAREN_CLOSE {
1159                         $$ = $2;
1160                   }
1161                 ;
1162
1163 complex_imm_oper : PLUS {
1164                         $$ = (void *)(unsigned long)PLUS;
1165                   }
1166                 | MINUS {
1167                         $$ = (void *)(unsigned long)MINUS;
1168                   }
1169                 | MULTIPLY {
1170                         $$ = (void *)(unsigned long)MULTIPLY;
1171                   }
1172                 | DIVIDE {
1173                         $$ = (void *)(unsigned long)DIVIDE;
1174                   }
1175                 | BITW_OR {
1176                         $$ = (void *)(unsigned long)BITW_OR;
1177                   }
1178                 | BITW_AND {
1179                         $$ = (void *)(unsigned long)BITW_AND;
1180                   }
1181                 | BITW_XOR {
1182                         $$ = (void *)(unsigned long)BITW_XOR;
1183                   }
1184                 | LEFTSHIFT {
1185                         $$ = (void *)(unsigned long)LEFTSHIFT;
1186                   }
1187                 | RIGHTSHIFT {
1188                         $$ = (void *)(unsigned long)RIGHTSHIFT;
1189                   }
1190                 ;
1191
1192 complex_imm_arg : complex_imm_const {
1193                         $$ = $1;
1194                   }
1195                 | complex_imm {
1196                         $$ = $1;
1197                   }
1198                 ;
1199
1200 complex_imm_const : hexnum_decnum {
1201                         $$ = $1;
1202                   }
1203                 | BITW_NOT hexnum_decnum {
1204                         unsigned long n = (unsigned long)$2;
1205                         n = ~n;
1206                         $$ = (void *)n;
1207                   }
1208                 ;
1209
1210 hexnum          : HEXNUM {
1211                         while (yytext[0] != 'x') {
1212                                 if (yytext[0] == '\0')
1213                                         yyerror("Internal HEXNUM parser error");
1214                                 yytext++;
1215                         }
1216                         yytext++;
1217                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1218                   }
1219                 ;
1220
1221 decnum          : DECNUM {
1222                         $$ = (void *)(unsigned long)strtol(yytext, NULL, 10);
1223                   }
1224                 ;
1225
1226 hexnum_decnum   : hexnum {
1227                         $$ = $1;
1228                   }
1229                 | decnum {
1230                         $$ = $1;
1231                   }
1232                 ;
1233
1234 labelref        : identifier {
1235                         struct operand *oper = xmalloc(sizeof(struct operand));
1236                         struct label *label = xmalloc(sizeof(struct label));
1237                         label->name = $1;
1238                         label->direction = LABELREF_ABSOLUTE;
1239                         oper->type = OPER_LABEL;
1240                         oper->u.label = label;
1241                         $$ = oper;
1242                   }
1243                 | identifier MINUS {
1244                         struct operand *oper = xmalloc(sizeof(struct operand));
1245                         struct label *label = xmalloc(sizeof(struct label));
1246                         label->name = $1;
1247                         label->direction = LABELREF_RELATIVE_BACK;
1248                         oper->type = OPER_LABEL;
1249                         oper->u.label = label;
1250                         $$ = oper;
1251                   }
1252                 | identifier PLUS {
1253                         struct operand *oper = xmalloc(sizeof(struct operand));
1254                         struct label *label = xmalloc(sizeof(struct label));
1255                         label->name = $1;
1256                         label->direction = LABELREF_RELATIVE_FORWARD;
1257                         oper->type = OPER_LABEL;
1258                         oper->u.label = label;
1259                         $$ = oper;
1260                   }
1261                 ;
1262
1263 regnr           : DECNUM {
1264                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 10);
1265                   }
1266                 ;
1267
1268 identifier      : IDENT {
1269                         $$ = xstrdup(yytext);
1270                   }
1271                 ;
1272
1273 %%
1274
1275 int section = SECTION_TEXT; /* default to .text section */
1276 struct initvals_sect *cur_initvals_sect;
1277
1278 void yyerror(char *str)
1279 {
1280         unsigned int i;
1281
1282         fprintf(stderr,
1283                 "Parser ERROR (file \"%s\", line %u, col %u):\n",
1284                 cur_lineinfo.file,
1285                 cur_lineinfo.lineno,
1286                 cur_lineinfo.column);
1287         fprintf(stderr, "%s\n", cur_lineinfo.linecopy);
1288         for (i = 0; i < cur_lineinfo.column - 1; i++)
1289                 fprintf(stderr, " ");
1290         fprintf(stderr, "^\n");
1291         fprintf(stderr, "%s\n", str);
1292         exit(1);
1293 }
1294
1295 static struct operand * store_oper_sanity(struct operand *oper)
1296 {
1297         if (oper->type == OPER_IMM &&
1298             oper->u.imm->imm != 0) {
1299                 yyerror("Only 0x000 Immediate is allowed for "
1300                         "Output operands");
1301         }
1302         return oper;
1303 }