Setting up repository
[linux-libre-firmware.git] / b43-tools / assembler / parser.y
1 %{
2
3 /*
4  *   Copyright (C) 2006-2010  Michael Buesch <m@bues.ch>
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(const char *);
27 extern int yyparse(void);
28 extern int yylex(void);
29
30 static struct operand * store_oper_sanity(struct operand *oper);
31 static void assembler_assertion_failed(void);
32
33 /* The current .section */
34 extern int section;
35 /* Pointer to the current initvals section data structure. */
36 extern struct initvals_sect *cur_initvals_sect;
37
38 %}
39
40 %token SECTION_TEXT SECTION_IVALS
41
42 %token ASM_ARCH ASM_START ASM_ASSERT SPR GPR OFFR LR COMMA SEMICOLON BRACK_OPEN BRACK_CLOSE PAREN_OPEN PAREN_CLOSE HEXNUM DECNUM ARCH_NEWWORLD ARCH_OLDWORLD LABEL IDENT LABELREF
43
44 %token EQUAL NOT_EQUAL LOGICAL_OR LOGICAL_AND PLUS MINUS MULTIPLY DIVIDE BITW_OR BITW_AND BITW_XOR BITW_NOT LEFTSHIFT RIGHTSHIFT
45
46 %token OP_MUL OP_ADD OP_ADDSC OP_ADDC OP_ADDSCC OP_SUB OP_SUBSC OP_SUBC OP_SUBSCC OP_SRA OP_OR OP_AND OP_XOR OP_SR OP_SRX OP_SL OP_RL OP_RR OP_NAND OP_ORX OP_MOV OP_JMP OP_JAND OP_JNAND OP_JS OP_JNS OP_JE OP_JNE OP_JLS OP_JGES OP_JGS OP_JLES OP_JL OP_JGE OP_JG OP_JLE OP_JZX OP_JNZX OP_JEXT OP_JNEXT OP_JDN OP_JDPZ OP_JDP OP_JDNZ OP_CALL OP_CALLS OP_RET OP_RETS OP_TKIPH OP_TKIPHS OP_TKIPL OP_TKIPLS OP_NAP RAW_CODE
47
48 %token IVAL_MMIO16 IVAL_MMIO32 IVAL_PHY IVAL_RADIO IVAL_SHM16 IVAL_SHM32 IVAL_TRAM
49
50 %start line
51
52 %%
53
54 line    : line_terminator {
55                 /* empty */
56           }
57         | line statement line_terminator {
58                 struct statement *s = $2;
59                 if (s) {
60                         if (section != SECTION_TEXT)
61                                 yyerror("Microcode text instruction in non .text section");
62                         memcpy(&s->info, &cur_lineinfo, sizeof(struct lineinfo));
63                         list_add_tail(&s->list, &infile.sl);
64                 }
65           }
66         | line section_switch line_terminator {
67           }
68         | line ivals_write line_terminator {
69                 struct initval_op *io = $2;
70                 if (section != SECTION_IVALS)
71                         yyerror("InitVals write in non .initvals section");
72                 memcpy(&io->info, &cur_lineinfo, sizeof(struct lineinfo));
73                 INIT_LIST_HEAD(&io->list);
74                 list_add_tail(&io->list, &cur_initvals_sect->ops);
75           }
76         ;
77
78 /* Allow terminating lines with the ";" char */
79 line_terminator : /* Nothing */
80                 | SEMICOLON line_terminator
81                 ;
82
83 section_switch  : SECTION_TEXT {
84                         section = SECTION_TEXT;
85                   }
86                 | SECTION_IVALS PAREN_OPEN identifier PAREN_CLOSE {
87                         const char *sectname = $3;
88                         struct initvals_sect *s;
89                         cur_initvals_sect = NULL;
90                         /* Search if there already is a section by that name. */
91                         list_for_each_entry(s, &infile.ivals, list) {
92                                 if (strcmp(sectname, s->name) == 0)
93                                         cur_initvals_sect = s;
94                         }
95                         if (!cur_initvals_sect) {
96                                 /* Not found, create a new one. */
97                                 s = xmalloc(sizeof(struct initvals_sect));
98                                 s->name = sectname;
99                                 INIT_LIST_HEAD(&s->ops);
100                                 INIT_LIST_HEAD(&s->list);
101                                 list_add_tail(&s->list, &infile.ivals);
102                                 cur_initvals_sect = s;
103                         }
104                         section = SECTION_IVALS;
105                   }
106                 ;
107
108 ivals_write     : IVAL_MMIO16 imm_value COMMA imm_value {
109                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
110                         iop->type = IVAL_W_MMIO16;
111                         iop->args[0] = (unsigned int)(unsigned long)$2;
112                         iop->args[1] = (unsigned int)(unsigned long)$4;
113                         $$ = iop;
114                   }
115                 | IVAL_MMIO32 imm_value COMMA imm_value {
116                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
117                         iop->type = IVAL_W_MMIO32;
118                         iop->args[0] = (unsigned int)(unsigned long)$2;
119                         iop->args[1] = (unsigned int)(unsigned long)$4;
120                         $$ = iop;
121                   }
122                 | IVAL_PHY imm_value COMMA imm_value {
123                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
124                         iop->type = IVAL_W_PHY;
125                         iop->args[0] = (unsigned int)(unsigned long)$2;
126                         iop->args[1] = (unsigned int)(unsigned long)$4;
127                         $$ = iop;
128                   }
129                 | IVAL_RADIO imm_value COMMA imm_value {
130                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
131                         iop->type = IVAL_W_RADIO;
132                         iop->args[0] = (unsigned int)(unsigned long)$2;
133                         iop->args[1] = (unsigned int)(unsigned long)$4;
134                         $$ = iop;
135                   }
136                 | IVAL_SHM16 imm_value COMMA imm_value COMMA imm_value {
137                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
138                         iop->type = IVAL_W_SHM16;
139                         iop->args[0] = (unsigned int)(unsigned long)$2;
140                         iop->args[1] = (unsigned int)(unsigned long)$4;
141                         iop->args[2] = (unsigned int)(unsigned long)$6;
142                         $$ = iop;
143                   }
144                 | IVAL_SHM32 imm_value COMMA imm_value COMMA imm_value {
145                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
146                         iop->type = IVAL_W_SHM32;
147                         iop->args[0] = (unsigned int)(unsigned long)$2;
148                         iop->args[1] = (unsigned int)(unsigned long)$4;
149                         iop->args[2] = (unsigned int)(unsigned long)$6;
150                         $$ = iop;
151                   }
152                 | IVAL_TRAM imm_value COMMA imm_value {
153                         struct initval_op *iop = xmalloc(sizeof(struct initval_op));
154                         iop->type = IVAL_W_TRAM;
155                         iop->args[0] = (unsigned int)(unsigned long)$2;
156                         iop->args[1] = (unsigned int)(unsigned long)$4;
157                         $$ = iop;
158                   }
159                 ;
160
161 statement       : asmdir {
162                         struct asmdir *ad = $1;
163                         if (ad) {
164                                 struct statement *s = xmalloc(sizeof(struct statement));
165                                 INIT_LIST_HEAD(&s->list);
166                                 s->type = STMT_ASMDIR;
167                                 s->u.asmdir = $1;
168                                 $$ = s;
169                         } else
170                                 $$ = NULL;
171                   }
172                 | label {
173                         struct statement *s = xmalloc(sizeof(struct statement));
174                         INIT_LIST_HEAD(&s->list);
175                         s->type = STMT_LABEL;
176                         s->u.label = $1;
177                         $$ = s;
178                   }
179                 | insn_mul {
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_add {
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_addsc {
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_addc {
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_addscc {
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_sub {
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_subsc {
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_subc {
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_subscc {
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_sra {
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_or {
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_and {
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_xor {
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_sr {
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_srx {
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_sl {
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_rl {
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_rr {
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_nand {
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_orx {
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_mov {
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_jmp {
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_jand {
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_jnand {
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_js {
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_jns {
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_je {
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_jne {
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_jls {
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_jges {
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_jgs {
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_jles {
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_jdn {
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_jdpz {
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_jdp {
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_jdnz {
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_jl {
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_jge {
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_jg {
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_jle {
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_jzx {
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_jnzx {
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_jext {
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_jnext {
481                         struct statement *s = xmalloc(sizeof(struct statement));
482                         INIT_LIST_HEAD(&s->list);
483                         s->type = STMT_INSN;
484                         s->u.insn = $1;
485                         $$ = s;
486                   }
487                 | insn_call {
488                         struct statement *s = xmalloc(sizeof(struct statement));
489                         INIT_LIST_HEAD(&s->list);
490                         s->type = STMT_INSN;
491                         s->u.insn = $1;
492                         $$ = s;
493                   }
494                 | insn_calls {
495                         struct statement *s = xmalloc(sizeof(struct statement));
496                         INIT_LIST_HEAD(&s->list);
497                         s->type = STMT_INSN;
498                         s->u.insn = $1;
499                         $$ = s;
500                   }
501                 | insn_ret {
502                         struct statement *s = xmalloc(sizeof(struct statement));
503                         INIT_LIST_HEAD(&s->list);
504                         s->type = STMT_INSN;
505                         s->u.insn = $1;
506                         $$ = s;
507                   }
508                 | insn_rets {
509                         struct statement *s = xmalloc(sizeof(struct statement));
510                         INIT_LIST_HEAD(&s->list);
511                         s->type = STMT_INSN;
512                         s->u.insn = $1;
513                         $$ = s;
514                   }
515                 | insn_tkiph {
516                         struct statement *s = xmalloc(sizeof(struct statement));
517                         INIT_LIST_HEAD(&s->list);
518                         s->type = STMT_INSN;
519                         s->u.insn = $1;
520                         $$ = s;
521                   }
522                 | insn_tkiphs {
523                         struct statement *s = xmalloc(sizeof(struct statement));
524                         INIT_LIST_HEAD(&s->list);
525                         s->type = STMT_INSN;
526                         s->u.insn = $1;
527                         $$ = s;
528                   }
529                 | insn_tkipl {
530                         struct statement *s = xmalloc(sizeof(struct statement));
531                         INIT_LIST_HEAD(&s->list);
532                         s->type = STMT_INSN;
533                         s->u.insn = $1;
534                         $$ = s;
535                   }
536                 | insn_tkipls {
537                         struct statement *s = xmalloc(sizeof(struct statement));
538                         INIT_LIST_HEAD(&s->list);
539                         s->type = STMT_INSN;
540                         s->u.insn = $1;
541                         $$ = s;
542                   }
543                 | insn_nap {
544                         struct statement *s = xmalloc(sizeof(struct statement));
545                         INIT_LIST_HEAD(&s->list);
546                         s->type = STMT_INSN;
547                         s->u.insn = $1;
548                         $$ = s;
549                   }
550                 | insn_raw {
551                         struct statement *s = xmalloc(sizeof(struct statement));
552                         INIT_LIST_HEAD(&s->list);
553                         s->type = STMT_INSN;
554                         s->u.insn = $1;
555                         $$ = s;
556                   }
557                 ;
558
559 /* ASM directives */
560 asmdir          : ASM_ARCH hexnum_decnum {
561                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
562                         ad->type = ADIR_ARCH;
563                         ad->u.arch = (unsigned int)(unsigned long)$2;
564                         $$ = ad;
565                   }
566                 | ASM_START identifier {
567                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
568                         struct label *label = xmalloc(sizeof(struct label));
569                         label->name = $2;
570                         label->direction = LABELREF_ABSOLUTE;
571                         ad->type = ADIR_START;
572                         ad->u.start = label;
573                         $$ = ad;
574                   }
575                 | asm_assert {
576                         $$ = NULL;
577                   }
578                 ;
579
580 asm_assert      : ASM_ASSERT assertion {
581                         unsigned int ok = (unsigned int)(unsigned long)$2;
582                         if (!ok)
583                                 assembler_assertion_failed();
584                         $$ = NULL;
585                   }
586                 ;
587
588 assertion       : PAREN_OPEN assert_expr PAREN_CLOSE {
589                         $$ = $2;
590                   }
591                 | PAREN_OPEN assertion LOGICAL_OR assertion PAREN_CLOSE {
592                         unsigned int a = (unsigned int)(unsigned long)$2;
593                         unsigned int b = (unsigned int)(unsigned long)$4;
594                         unsigned int result = (a || b);
595                         $$ = (void *)(unsigned long)result;
596                   }
597                 | PAREN_OPEN assertion LOGICAL_AND assertion PAREN_CLOSE {
598                         unsigned int a = (unsigned int)(unsigned long)$2;
599                         unsigned int b = (unsigned int)(unsigned long)$4;
600                         unsigned int result = (a && b);
601                         $$ = (void *)(unsigned long)result;
602                   }
603                 ;
604
605 assert_expr     : imm_value EQUAL imm_value {
606                         unsigned int a = (unsigned int)(unsigned long)$1;
607                         unsigned int b = (unsigned int)(unsigned long)$3;
608                         unsigned int result = (a == b);
609                         $$ = (void *)(unsigned long)result;
610                   }
611                 | imm_value NOT_EQUAL imm_value {
612                         unsigned int a = (unsigned int)(unsigned long)$1;
613                         unsigned int b = (unsigned int)(unsigned long)$3;
614                         unsigned int result = (a != b);
615                         $$ = (void *)(unsigned long)result;
616                   }
617                 ;
618
619 label           : LABEL {
620                         struct label *label = xmalloc(sizeof(struct label));
621                         char *l;
622                         l = xstrdup(yytext);
623                         l[strlen(l) - 1] = '\0';
624                         label->name = l;
625                         $$ = label;
626                   }
627                 ;
628
629 /* multiply */
630 insn_mul        : OP_MUL operlist_3 {
631                         struct instruction *insn = xmalloc(sizeof(struct instruction));
632                         insn->op = OP_MUL;
633                         insn->operands = $2;
634                         $$ = insn;
635                   }
636                 ;
637
638 /* add */
639 insn_add        : OP_ADD operlist_3 {
640                         struct instruction *insn = xmalloc(sizeof(struct instruction));
641                         insn->op = OP_ADD;
642                         insn->operands = $2;
643                         $$ = insn;
644                   }
645                 ;
646
647 /* add. */
648 insn_addsc      : OP_ADDSC operlist_3 {
649                         struct instruction *insn = xmalloc(sizeof(struct instruction));
650                         insn->op = OP_ADDSC;
651                         insn->operands = $2;
652                         $$ = insn;
653                   }
654                 ;
655
656 /* addc */
657 insn_addc       : OP_ADDC operlist_3 {
658                         struct instruction *insn = xmalloc(sizeof(struct instruction));
659                         insn->op = OP_ADDC;
660                         insn->operands = $2;
661                         $$ = insn;
662                   }
663                 ;
664
665 /* addc. */
666 insn_addscc     : OP_ADDSCC operlist_3 {
667                         struct instruction *insn = xmalloc(sizeof(struct instruction));
668                         insn->op = OP_ADDSCC;
669                         insn->operands = $2;
670                         $$ = insn;
671                   }
672                 ;
673
674 /* sub */
675 insn_sub        : OP_SUB operlist_3 {
676                         struct instruction *insn = xmalloc(sizeof(struct instruction));
677                         insn->op = OP_SUB;
678                         insn->operands = $2;
679                         $$ = insn;
680                   }
681                 ;
682
683 /* sub. */
684 insn_subsc      : OP_SUBSC operlist_3 {
685                         struct instruction *insn = xmalloc(sizeof(struct instruction));
686                         insn->op = OP_SUBSC;
687                         insn->operands = $2;
688                         $$ = insn;
689                   }
690                 ;
691
692 /* subc */
693 insn_subc       : OP_SUBC operlist_3 {
694                         struct instruction *insn = xmalloc(sizeof(struct instruction));
695                         insn->op = OP_SUBC;
696                         insn->operands = $2;
697                         $$ = insn;
698                   }
699                 ;
700
701 /* subc. */
702 insn_subscc     : OP_SUBSCC operlist_3 {
703                         struct instruction *insn = xmalloc(sizeof(struct instruction));
704                         insn->op = OP_SUBSCC;
705                         insn->operands = $2;
706                         $$ = insn;
707                   }
708                 ;
709
710 insn_sra        : OP_SRA operlist_3 {
711                         struct instruction *insn = xmalloc(sizeof(struct instruction));
712                         insn->op = OP_SRA;
713                         insn->operands = $2;
714                         $$ = insn;
715                   }
716                 ;
717
718 insn_or         : OP_OR operlist_3 {
719                         struct instruction *insn = xmalloc(sizeof(struct instruction));
720                         insn->op = OP_OR;
721                         insn->operands = $2;
722                         $$ = insn;
723                   }
724                 ;
725
726 insn_and        : OP_AND operlist_3 {
727                         struct instruction *insn = xmalloc(sizeof(struct instruction));
728                         insn->op = OP_AND;
729                         insn->operands = $2;
730                         $$ = insn;
731                   }
732                 ;
733
734 insn_xor        : OP_XOR operlist_3 {
735                         struct instruction *insn = xmalloc(sizeof(struct instruction));
736                         insn->op = OP_XOR;
737                         insn->operands = $2;
738                         $$ = insn;
739                   }
740                 ;
741
742 insn_sr         : OP_SR operlist_3 {
743                         struct instruction *insn = xmalloc(sizeof(struct instruction));
744                         insn->op = OP_SR;
745                         insn->operands = $2;
746                         $$ = insn;
747                   }
748                 ;
749
750 insn_srx        : OP_SRX extended_operlist {
751                         struct instruction *insn = xmalloc(sizeof(struct instruction));
752                         insn->op = OP_SRX;
753                         insn->operands = $2;
754                         $$ = insn;
755                   }
756                 ;
757
758 insn_sl         : OP_SL operlist_3 {
759                         struct instruction *insn = xmalloc(sizeof(struct instruction));
760                         insn->op = OP_SL;
761                         insn->operands = $2;
762                         $$ = insn;
763                   }
764                 ;
765
766 insn_rl         : OP_RL operlist_3 {
767                         struct instruction *insn = xmalloc(sizeof(struct instruction));
768                         insn->op = OP_RL;
769                         insn->operands = $2;
770                         $$ = insn;
771                   }
772                 ;
773
774 insn_rr         : OP_RR operlist_3 {
775                         struct instruction *insn = xmalloc(sizeof(struct instruction));
776                         insn->op = OP_RR;
777                         insn->operands = $2;
778                         $$ = insn;
779                   }
780                 ;
781
782 insn_nand       : OP_NAND operlist_3 {
783                         struct instruction *insn = xmalloc(sizeof(struct instruction));
784                         insn->op = OP_NAND;
785                         insn->operands = $2;
786                         $$ = insn;
787                   }
788                 ;
789
790 insn_orx        : OP_ORX extended_operlist {
791                         struct instruction *insn = xmalloc(sizeof(struct instruction));
792                         insn->op = OP_ORX;
793                         insn->operands = $2;
794                         $$ = insn;
795                   }
796                 ;
797
798 insn_mov        : OP_MOV operlist_2 {
799                         struct instruction *insn = xmalloc(sizeof(struct instruction));
800                         insn->op = OP_MOV;
801                         insn->operands = $2;
802                         $$ = insn;
803                   }
804                 ;
805
806 insn_jmp        : OP_JMP labelref {
807                         struct instruction *insn = xmalloc(sizeof(struct instruction));
808                         struct operlist *ol = xmalloc(sizeof(struct operlist));
809                         ol->oper[0] = $2;
810                         insn->op = OP_JMP;
811                         insn->operands = ol;
812                         $$ = insn;
813                   }
814                 ;
815
816 insn_jand       : OP_JAND operlist_3 {
817                         struct instruction *insn = xmalloc(sizeof(struct instruction));
818                         insn->op = OP_JAND;
819                         insn->operands = $2;
820                         $$ = insn;
821                   }
822                 ;
823
824 insn_jnand      : OP_JNAND operlist_3 {
825                         struct instruction *insn = xmalloc(sizeof(struct instruction));
826                         insn->op = OP_JNAND;
827                         insn->operands = $2;
828                         $$ = insn;
829                   }
830                 ;
831
832 insn_js         : OP_JS operlist_3 {
833                         struct instruction *insn = xmalloc(sizeof(struct instruction));
834                         insn->op = OP_JS;
835                         insn->operands = $2;
836                         $$ = insn;
837                   }
838                 ;
839
840 insn_jns        : OP_JNS operlist_3 {
841                         struct instruction *insn = xmalloc(sizeof(struct instruction));
842                         insn->op = OP_JNS;
843                         insn->operands = $2;
844                         $$ = insn;
845                   }
846                 ;
847
848 insn_je         : OP_JE operlist_3 {
849                         struct instruction *insn = xmalloc(sizeof(struct instruction));
850                         insn->op = OP_JE;
851                         insn->operands = $2;
852                         $$ = insn;
853                   }
854                 ;
855
856 insn_jne        : OP_JNE operlist_3 {
857                         struct instruction *insn = xmalloc(sizeof(struct instruction));
858                         insn->op = OP_JNE;
859                         insn->operands = $2;
860                         $$ = insn;
861                   }
862                 ;
863
864 insn_jls        : OP_JLS operlist_3 {
865                         struct instruction *insn = xmalloc(sizeof(struct instruction));
866                         insn->op = OP_JLS;
867                         insn->operands = $2;
868                         $$ = insn;
869                   }
870                 ;
871
872 insn_jges       : OP_JGES operlist_3 {
873                         struct instruction *insn = xmalloc(sizeof(struct instruction));
874                         insn->op = OP_JGES;
875                         insn->operands = $2;
876                         $$ = insn;
877                   }
878                 ;
879
880 insn_jgs        : OP_JGS operlist_3 {
881                         struct instruction *insn = xmalloc(sizeof(struct instruction));
882                         insn->op = OP_JGS;
883                         insn->operands = $2;
884                         $$ = insn;
885                   }
886                 ;
887
888 insn_jles       : OP_JLES operlist_3 {
889                         struct instruction *insn = xmalloc(sizeof(struct instruction));
890                         insn->op = OP_JLES;
891                         insn->operands = $2;
892                         $$ = insn;
893                   }
894                 ;
895
896 insn_jl         : OP_JL operlist_3 {
897                         struct instruction *insn = xmalloc(sizeof(struct instruction));
898                         insn->op = OP_JL;
899                         insn->operands = $2;
900                         $$ = insn;
901                   }
902                 ;
903
904 insn_jge        : OP_JGE operlist_3 {
905                         struct instruction *insn = xmalloc(sizeof(struct instruction));
906                         insn->op = OP_JGE;
907                         insn->operands = $2;
908                         $$ = insn;
909                   }
910                 ;
911
912 insn_jg         : OP_JG operlist_3 {
913                         struct instruction *insn = xmalloc(sizeof(struct instruction));
914                         insn->op = OP_JG;
915                         insn->operands = $2;
916                         $$ = insn;
917                   }
918                 ;
919
920 insn_jle        : OP_JLE operlist_3 {
921                         struct instruction *insn = xmalloc(sizeof(struct instruction));
922                         insn->op = OP_JLE;
923                         insn->operands = $2;
924                         $$ = insn;
925                   }
926                 ;
927
928 insn_jzx        : OP_JZX extended_operlist {
929                         struct instruction *insn = xmalloc(sizeof(struct instruction));
930                         insn->op = OP_JZX;
931                         insn->operands = $2;
932                         $$ = insn;
933                   }
934                 ;
935
936 insn_jnzx       : OP_JNZX extended_operlist {
937                         struct instruction *insn = xmalloc(sizeof(struct instruction));
938                         insn->op = OP_JNZX;
939                         insn->operands = $2;
940                         $$ = insn;
941                   }
942                 ;
943
944 insn_jdn        : OP_JDN operlist_3 {
945                         struct instruction *insn = xmalloc(sizeof(struct instruction));
946                         insn->op = OP_JDN;
947                         insn->operands = $2;
948                         $$ = insn;
949                   }
950                 ;
951
952 insn_jdpz       : OP_JDPZ operlist_3 {
953                         struct instruction *insn = xmalloc(sizeof(struct instruction));
954                         insn->op = OP_JDPZ;
955                         insn->operands = $2;
956                         $$ = insn;
957                   }
958                 ;
959
960 insn_jdp        : OP_JDP operlist_3 {
961                         struct instruction *insn = xmalloc(sizeof(struct instruction));
962                         insn->op = OP_JDP;
963                         insn->operands = $2;
964                         $$ = insn;
965                   }
966                 ;
967
968 insn_jdnz       : OP_JDNZ operlist_3 {
969                         struct instruction *insn = xmalloc(sizeof(struct instruction));
970                         insn->op = OP_JDNZ;
971                         insn->operands = $2;
972                         $$ = insn;
973                   }
974                 ;
975
976 insn_jext       : OP_JEXT external_jump_operands {
977                         struct instruction *insn = xmalloc(sizeof(struct instruction));
978                         insn->op = OP_JEXT;
979                         insn->operands = $2;
980                         $$ = insn;
981                   }
982                 ;
983
984 insn_jnext      : OP_JNEXT external_jump_operands {
985                         struct instruction *insn = xmalloc(sizeof(struct instruction));
986                         insn->op = OP_JNEXT;
987                         insn->operands = $2;
988                         $$ = insn;
989                   }
990                 ;
991
992 linkreg         : LR regnr {
993                         $$ = $2;
994                   }
995                 ;
996
997 insn_call       : OP_CALL linkreg COMMA labelref {
998                         struct instruction *insn = xmalloc(sizeof(struct instruction));
999                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1000                         struct operand *oper_lr = xmalloc(sizeof(struct operand));
1001                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
1002                         oper_zero->type = OPER_RAW;
1003                         oper_zero->u.raw = 0;
1004                         oper_lr->type = OPER_RAW;
1005                         oper_lr->u.raw = (unsigned long)$2;
1006                         ol->oper[0] = oper_lr;
1007                         ol->oper[1] = oper_zero;
1008                         ol->oper[2] = $4;
1009                         insn->op = OP_CALL;
1010                         insn->operands = ol;
1011                         $$ = insn;
1012                   }
1013                 ;
1014
1015 insn_calls      :  OP_CALLS labelref {
1016                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1017                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1018                         struct operand *oper_r0 = xmalloc(sizeof(struct operand));
1019                         struct registr *r0 = xmalloc(sizeof(struct registr));
1020                         r0->type = GPR;
1021                         r0->nr = 0;
1022                         oper_r0->type = OPER_REG;
1023                         oper_r0->u.reg = r0;
1024                         ol->oper[0] = oper_r0;
1025                         ol->oper[1] = oper_r0;
1026                         ol->oper[2] = $2;
1027                         insn->op = OP_CALLS;
1028                         insn->operands = ol;
1029                         $$ = insn;
1030                   }
1031                 ;
1032
1033 insn_ret        : OP_RET linkreg COMMA linkreg {
1034                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1035                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1036                         struct operand *oper_lr0 = xmalloc(sizeof(struct operand));
1037                         struct operand *oper_lr1 = xmalloc(sizeof(struct operand));
1038                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
1039                         oper_zero->type = OPER_RAW;
1040                         oper_zero->u.raw = 0;
1041                         oper_lr0->type = OPER_RAW;
1042                         oper_lr0->u.raw = (unsigned long)$2;
1043                         oper_lr1->type = OPER_RAW;
1044                         oper_lr1->u.raw = (unsigned long)$4;
1045                         ol->oper[0] = oper_lr0;
1046                         ol->oper[1] = oper_zero;
1047                         ol->oper[2] = oper_lr1;
1048                         insn->op = OP_RET;
1049                         insn->operands = ol;
1050                         $$ = insn;
1051                   }
1052                 ;
1053
1054 insn_rets       : OP_RETS {
1055                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1056                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1057                         struct operand *oper_r0 = xmalloc(sizeof(struct operand));
1058                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
1059                         struct registr *r0 = xmalloc(sizeof(struct registr));
1060                         oper_zero->type = OPER_RAW;
1061                         oper_zero->u.raw = 0;
1062                         r0->type = GPR;
1063                         r0->nr = 0;
1064                         oper_r0->type = OPER_REG;
1065                         oper_r0->u.reg = r0;
1066                         ol->oper[0] = oper_r0;
1067                         ol->oper[1] = oper_r0;
1068                         ol->oper[2] = oper_zero;
1069                         insn->op = OP_RETS;
1070                         insn->operands = ol;
1071                         $$ = insn;
1072                   }
1073                 ;
1074
1075 insn_tkiph      : OP_TKIPH operlist_2 {
1076                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1077                         struct operlist *ol = $2;
1078                         struct operand *flags = xmalloc(sizeof(struct operand));
1079                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1080                         imm->imm = 0x1;
1081                         flags->type = OPER_IMM;
1082                         flags->u.imm = imm;
1083                         ol->oper[2] = ol->oper[1];
1084                         ol->oper[1] = flags;
1085                         insn->op = OP_TKIPH;
1086                         insn->operands = ol;
1087                         $$ = insn;
1088                   }
1089                 ;
1090
1091 insn_tkiphs     : OP_TKIPHS operlist_2 {
1092                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1093                         struct operlist *ol = $2;
1094                         struct operand *flags = xmalloc(sizeof(struct operand));
1095                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1096                         imm->imm = 0x1 | 0x2;
1097                         flags->type = OPER_IMM;
1098                         flags->u.imm = imm;
1099                         ol->oper[2] = ol->oper[1];
1100                         ol->oper[1] = flags;
1101                         insn->op = OP_TKIPH;
1102                         insn->operands = ol;
1103                         $$ = insn;
1104                   }
1105                 ;
1106
1107 insn_tkipl      : OP_TKIPL operlist_2 {
1108                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1109                         struct operlist *ol = $2;
1110                         struct operand *flags = xmalloc(sizeof(struct operand));
1111                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1112                         imm->imm = 0x0;
1113                         flags->type = OPER_IMM;
1114                         flags->u.imm = imm;
1115                         ol->oper[2] = ol->oper[1];
1116                         ol->oper[1] = flags;
1117                         insn->op = OP_TKIPH;
1118                         insn->operands = ol;
1119                         $$ = insn;
1120                   }
1121                 ;
1122
1123 insn_tkipls     : OP_TKIPLS operlist_2 {
1124                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1125                         struct operlist *ol = $2;
1126                         struct operand *flags = xmalloc(sizeof(struct operand));
1127                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1128                         imm->imm = 0x0 | 0x2;
1129                         flags->type = OPER_IMM;
1130                         flags->u.imm = imm;
1131                         ol->oper[2] = ol->oper[1];
1132                         ol->oper[1] = flags;
1133                         insn->op = OP_TKIPH;
1134                         insn->operands = ol;
1135                         $$ = insn;
1136                   }
1137                 ;
1138
1139 insn_nap        : OP_NAP {
1140                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1141                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1142                         struct operand *regop = xmalloc(sizeof(struct operand));
1143                         struct operand *zeroop = xmalloc(sizeof(struct operand));
1144                         struct registr *r0 = xmalloc(sizeof(struct registr));
1145                         r0->type = GPR;
1146                         r0->nr = 0;
1147                         regop->type = OPER_REG;
1148                         regop->u.reg = r0;
1149                         zeroop->type = OPER_RAW;
1150                         zeroop->u.raw = 0x000;
1151                         ol->oper[0] = regop;
1152                         ol->oper[1] = regop;
1153                         ol->oper[2] = zeroop;
1154                         insn->op = OP_NAP;
1155                         insn->operands = ol;
1156                         $$ = insn;
1157                   }
1158                 ;
1159
1160 insn_raw        : raw_code operlist_3 {
1161                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1162                         insn->op = RAW_CODE;
1163                         insn->operands = $2;
1164                         insn->opcode = (unsigned long)$1;
1165                         $$ = insn;
1166                   }
1167                 ;
1168
1169 raw_code        : RAW_CODE {
1170                         yytext++; /* skip @ */
1171                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1172                   }
1173                 ;
1174
1175 extended_operlist : imm_value COMMA imm_value COMMA operand COMMA operand COMMA operand {
1176                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1177                         struct operand *mask_oper = xmalloc(sizeof(struct operand));
1178                         struct operand *shift_oper = xmalloc(sizeof(struct operand));
1179                         mask_oper->type = OPER_RAW;
1180                         mask_oper->u.raw = (unsigned long)$1;
1181                         shift_oper->type = OPER_RAW;
1182                         shift_oper->u.raw = (unsigned long)$3;
1183                         ol->oper[0] = mask_oper;
1184                         ol->oper[1] = shift_oper;
1185                         ol->oper[2] = $5;
1186                         ol->oper[3] = $7;
1187                         ol->oper[4] = store_oper_sanity($9);
1188                         $$ = ol;
1189                   }
1190                 ;
1191
1192 external_jump_operands : imm COMMA labelref {
1193                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1194                         struct operand *cond = xmalloc(sizeof(struct operand));
1195                         cond->type = OPER_IMM;
1196                         cond->u.imm = $1;
1197                         ol->oper[0] = cond;
1198                         ol->oper[1] = $3;
1199                         $$ = ol;
1200                   }
1201                 ;
1202
1203 operlist_2      : operand COMMA operand {
1204                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1205                         ol->oper[0] = $1;
1206                         ol->oper[1] = store_oper_sanity($3);
1207                         $$ = ol;
1208                   }
1209                 ;
1210
1211 operlist_3      : operand COMMA operand COMMA operand {
1212                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1213                         ol->oper[0] = $1;
1214                         ol->oper[1] = $3;
1215                         ol->oper[2] = store_oper_sanity($5);
1216                         $$ = ol;
1217                   }
1218                 ;
1219
1220 operand         : reg {
1221                         struct operand *oper = xmalloc(sizeof(struct operand));
1222                         oper->type = OPER_REG;
1223                         oper->u.reg = $1;
1224                         $$ = oper;
1225                   }
1226                 | mem {
1227                         struct operand *oper = xmalloc(sizeof(struct operand));
1228                         oper->type = OPER_MEM;
1229                         oper->u.mem = $1;
1230                         $$ = oper;
1231                   }
1232                 | raw_code {
1233                         struct operand *oper = xmalloc(sizeof(struct operand));
1234                         oper->type = OPER_RAW;
1235                         oper->u.raw = (unsigned long)$1;
1236                         $$ = oper;
1237                   }
1238                 | imm {
1239                         struct operand *oper = xmalloc(sizeof(struct operand));
1240                         oper->type = OPER_IMM;
1241                         oper->u.imm = $1;
1242                         $$ = oper;
1243                   }
1244                 | labelref {
1245                         $$ = $1;
1246                   }
1247                 ;
1248
1249 reg             : GPR regnr {
1250                         struct registr *reg = xmalloc(sizeof(struct registr));
1251                         reg->type = GPR;
1252                         reg->nr = (unsigned long)$2;
1253                         $$ = reg;
1254                   }
1255                 | SPR {
1256                         struct registr *reg = xmalloc(sizeof(struct registr));
1257                         reg->type = SPR;
1258                         yytext += 3; /* skip "spr" */
1259                         reg->nr = strtoul(yytext, NULL, 16);
1260                         $$ = reg;
1261                   }
1262                 | OFFR regnr {
1263                         struct registr *reg = xmalloc(sizeof(struct registr));
1264                         reg->type = OFFR;
1265                         reg->nr = (unsigned long)$2;
1266                         $$ = reg;
1267                   }
1268                 ;
1269
1270 mem             : BRACK_OPEN imm BRACK_CLOSE {
1271                         struct memory *mem = xmalloc(sizeof(struct memory));
1272                         struct immediate *offset_imm = $2;
1273                         mem->type = MEM_DIRECT;
1274                         mem->offset = offset_imm->imm;
1275                         free(offset_imm);
1276                         $$ = mem;
1277                   }
1278                 | BRACK_OPEN imm COMMA OFFR regnr BRACK_CLOSE {
1279                         struct memory *mem = xmalloc(sizeof(struct memory));
1280                         struct immediate *offset_imm = $2;
1281                         mem->type = MEM_INDIRECT;
1282                         mem->offset = offset_imm->imm;
1283                         free(offset_imm);
1284                         mem->offr_nr = (unsigned long)$5;
1285                         $$ = mem;
1286                   }
1287                 ;
1288
1289 imm             : imm_value {
1290                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1291                         imm->imm = (unsigned long)$1;
1292                         $$ = imm;
1293                   }
1294                 ;
1295
1296 imm_value       : hexnum_decnum {
1297                         $$ = $1;
1298                   }
1299                 | complex_imm {
1300                         $$ = $1;
1301                   }
1302                 ;
1303
1304 complex_imm     : PAREN_OPEN complex_imm_arg complex_imm_oper complex_imm_arg PAREN_CLOSE {
1305                         unsigned long a = (unsigned long)$2;
1306                         unsigned long b = (unsigned long)$4;
1307                         unsigned long operation = (unsigned long)$3;
1308                         unsigned long res = 31337;
1309                         switch (operation) {
1310                         case PLUS:
1311                                 res = a + b;
1312                                 break;
1313                         case MINUS:
1314                                 res = a - b;
1315                                 break;
1316                         case MULTIPLY:
1317                                 res = a * b;
1318                                 break;
1319                         case DIVIDE:
1320                                 res = a / b;
1321                                 break;
1322                         case BITW_OR:
1323                                 res = a | b;
1324                                 break;
1325                         case BITW_AND:
1326                                 res = a & b;
1327                                 break;
1328                         case BITW_XOR:
1329                                 res = a ^ b;
1330                                 break;
1331                         case LEFTSHIFT:
1332                                 res = a << b;
1333                                 break;
1334                         case RIGHTSHIFT:
1335                                 res = a >> b;
1336                                 break;
1337                         default:
1338                                 yyerror("Internal parser BUG. complex_imm oper unknown");
1339                         }
1340                         $$ = (void *)res;
1341                   }
1342                 | PAREN_OPEN complex_imm PAREN_CLOSE {
1343                         $$ = $2;
1344                   }
1345                 | PAREN_OPEN asm_assert PAREN_CLOSE {
1346                         /* Inline assertion. Always return zero */
1347                         $$ = (void *)(unsigned long)(unsigned int)0;
1348                   }
1349                 | PAREN_OPEN BITW_NOT complex_imm PAREN_CLOSE {
1350                         unsigned long n = (unsigned long)$3;
1351                         n = ~n;
1352                         $$ = (void *)n;
1353                   }
1354                 | PAREN_OPEN complex_imm_const PAREN_CLOSE {
1355                         $$ = $2;
1356                   }
1357                 ;
1358
1359 complex_imm_oper : PLUS {
1360                         $$ = (void *)(unsigned long)PLUS;
1361                   }
1362                 | MINUS {
1363                         $$ = (void *)(unsigned long)MINUS;
1364                   }
1365                 | MULTIPLY {
1366                         $$ = (void *)(unsigned long)MULTIPLY;
1367                   }
1368                 | DIVIDE {
1369                         $$ = (void *)(unsigned long)DIVIDE;
1370                   }
1371                 | BITW_OR {
1372                         $$ = (void *)(unsigned long)BITW_OR;
1373                   }
1374                 | BITW_AND {
1375                         $$ = (void *)(unsigned long)BITW_AND;
1376                   }
1377                 | BITW_XOR {
1378                         $$ = (void *)(unsigned long)BITW_XOR;
1379                   }
1380                 | LEFTSHIFT {
1381                         $$ = (void *)(unsigned long)LEFTSHIFT;
1382                   }
1383                 | RIGHTSHIFT {
1384                         $$ = (void *)(unsigned long)RIGHTSHIFT;
1385                   }
1386                 ;
1387
1388 complex_imm_arg : complex_imm_const {
1389                         $$ = $1;
1390                   }
1391                 | complex_imm {
1392                         $$ = $1;
1393                   }
1394                 ;
1395
1396 complex_imm_const : hexnum_decnum {
1397                         $$ = $1;
1398                   }
1399                 | BITW_NOT hexnum_decnum {
1400                         unsigned long n = (unsigned long)$2;
1401                         n = ~n;
1402                         $$ = (void *)n;
1403                   }
1404                 ;
1405
1406 hexnum          : HEXNUM {
1407                         while (yytext[0] != 'x') {
1408                                 if (yytext[0] == '\0')
1409                                         yyerror("Internal HEXNUM parser error");
1410                                 yytext++;
1411                         }
1412                         yytext++;
1413                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1414                   }
1415                 ;
1416
1417 decnum          : DECNUM {
1418                         $$ = (void *)(unsigned long)strtol(yytext, NULL, 10);
1419                   }
1420                 ;
1421
1422 hexnum_decnum   : hexnum {
1423                         $$ = $1;
1424                   }
1425                 | decnum {
1426                         $$ = $1;
1427                   }
1428                 ;
1429
1430 labelref        : identifier {
1431                         struct operand *oper = xmalloc(sizeof(struct operand));
1432                         struct label *label = xmalloc(sizeof(struct label));
1433                         label->name = $1;
1434                         label->direction = LABELREF_ABSOLUTE;
1435                         oper->type = OPER_LABEL;
1436                         oper->u.label = label;
1437                         $$ = oper;
1438                   }
1439                 | identifier MINUS {
1440                         struct operand *oper = xmalloc(sizeof(struct operand));
1441                         struct label *label = xmalloc(sizeof(struct label));
1442                         label->name = $1;
1443                         label->direction = LABELREF_RELATIVE_BACK;
1444                         oper->type = OPER_LABEL;
1445                         oper->u.label = label;
1446                         $$ = oper;
1447                   }
1448                 | identifier PLUS {
1449                         struct operand *oper = xmalloc(sizeof(struct operand));
1450                         struct label *label = xmalloc(sizeof(struct label));
1451                         label->name = $1;
1452                         label->direction = LABELREF_RELATIVE_FORWARD;
1453                         oper->type = OPER_LABEL;
1454                         oper->u.label = label;
1455                         $$ = oper;
1456                   }
1457                 ;
1458
1459 regnr           : DECNUM {
1460                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 10);
1461                   }
1462                 ;
1463
1464 identifier      : IDENT {
1465                         $$ = xstrdup(yytext);
1466                   }
1467                 ;
1468
1469 %%
1470
1471 int section = SECTION_TEXT; /* default to .text section */
1472 struct initvals_sect *cur_initvals_sect;
1473
1474 void yyerror(const char *str)
1475 {
1476         unsigned int i;
1477
1478         fprintf(stderr,
1479                 "Parser ERROR (file \"%s\", line %u, col %u):\n",
1480                 cur_lineinfo.file,
1481                 cur_lineinfo.lineno,
1482                 cur_lineinfo.column);
1483         fprintf(stderr, "%s\n", cur_lineinfo.linecopy);
1484         for (i = 0; i < cur_lineinfo.column - 1; i++)
1485                 fprintf(stderr, " ");
1486         fprintf(stderr, "^\n");
1487         fprintf(stderr, "%s\n", str);
1488         exit(1);
1489 }
1490
1491 static struct operand * store_oper_sanity(struct operand *oper)
1492 {
1493         if (oper->type == OPER_IMM &&
1494             oper->u.imm->imm != 0) {
1495                 yyerror("Only 0x000 Immediate is allowed for "
1496                         "Output operands");
1497         }
1498         return oper;
1499 }
1500
1501 static void assembler_assertion_failed(void)
1502 {
1503         yyerror("Assembler %assert failed");
1504 }