asm/dasm: Improve cflags
[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 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_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_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_add {
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_addsc {
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_addc {
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_addscc {
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_sub {
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_subsc {
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_subc {
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_subscc {
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_sra {
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_or {
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_and {
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_xor {
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_sr {
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_srx {
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_sl {
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_rl {
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_rr {
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_nand {
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_orx {
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_mov {
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_jmp {
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_jand {
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_jnand {
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_js {
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_jns {
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_je {
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_jne {
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_jls {
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_jges {
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_jgs {
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_jles {
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_jl {
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_jge {
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_jg {
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_jle {
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_jzx {
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_jnzx {
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_jext {
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_jnext {
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_call {
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_calls {
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_ret {
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_rets {
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_tkiph {
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_tkiphs {
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_tkipl {
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_tkipls {
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_nap {
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_raw {
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                 ;
523
524 /* ASM directives */
525 asmdir          : ASM_ARCH hexnum_decnum {
526                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
527                         ad->type = ADIR_ARCH;
528                         ad->u.arch = (unsigned int)(unsigned long)$2;
529                         $$ = ad;
530                   }
531                 | ASM_START identifier {
532                         struct asmdir *ad = xmalloc(sizeof(struct asmdir));
533                         struct label *label = xmalloc(sizeof(struct label));
534                         label->name = $2;
535                         label->direction = LABELREF_ABSOLUTE;
536                         ad->type = ADIR_START;
537                         ad->u.start = label;
538                         $$ = ad;
539                   }
540                 | asm_assert {
541                         $$ = NULL;
542                   }
543                 ;
544
545 asm_assert      : ASM_ASSERT assertion {
546                         unsigned int ok = (unsigned int)(unsigned long)$2;
547                         if (!ok)
548                                 assembler_assertion_failed();
549                         $$ = NULL;
550                   }
551                 ;
552
553 assertion       : PAREN_OPEN assert_expr PAREN_CLOSE {
554                         $$ = $2;
555                   }
556                 | PAREN_OPEN assertion LOGICAL_OR assertion PAREN_CLOSE {
557                         unsigned int a = (unsigned int)(unsigned long)$2;
558                         unsigned int b = (unsigned int)(unsigned long)$4;
559                         unsigned int result = (a || b);
560                         $$ = (void *)(unsigned long)result;
561                   }
562                 | PAREN_OPEN assertion LOGICAL_AND assertion PAREN_CLOSE {
563                         unsigned int a = (unsigned int)(unsigned long)$2;
564                         unsigned int b = (unsigned int)(unsigned long)$4;
565                         unsigned int result = (a && b);
566                         $$ = (void *)(unsigned long)result;
567                   }
568                 ;
569
570 assert_expr     : imm_value EQUAL imm_value {
571                         unsigned int a = (unsigned int)(unsigned long)$1;
572                         unsigned int b = (unsigned int)(unsigned long)$3;
573                         unsigned int result = (a == b);
574                         $$ = (void *)(unsigned long)result;
575                   }
576                 | imm_value NOT_EQUAL imm_value {
577                         unsigned int a = (unsigned int)(unsigned long)$1;
578                         unsigned int b = (unsigned int)(unsigned long)$3;
579                         unsigned int result = (a != b);
580                         $$ = (void *)(unsigned long)result;
581                   }
582                 ;
583
584 label           : LABEL {
585                         struct label *label = xmalloc(sizeof(struct label));
586                         char *l;
587                         l = xstrdup(yytext);
588                         l[strlen(l) - 1] = '\0';
589                         label->name = l;
590                         $$ = label;
591                   }
592                 ;
593
594 /* add */
595 insn_add        : OP_ADD operlist_3 {
596                         struct instruction *insn = xmalloc(sizeof(struct instruction));
597                         insn->op = OP_ADD;
598                         insn->operands = $2;
599                         $$ = insn;
600                   }
601                 ;
602
603 /* add. */
604 insn_addsc      : OP_ADDSC operlist_3 {
605                         struct instruction *insn = xmalloc(sizeof(struct instruction));
606                         insn->op = OP_ADDSC;
607                         insn->operands = $2;
608                         $$ = insn;
609                   }
610                 ;
611
612 /* addc */
613 insn_addc       : OP_ADDC operlist_3 {
614                         struct instruction *insn = xmalloc(sizeof(struct instruction));
615                         insn->op = OP_ADDC;
616                         insn->operands = $2;
617                         $$ = insn;
618                   }
619                 ;
620
621 /* addc. */
622 insn_addscc     : OP_ADDSCC operlist_3 {
623                         struct instruction *insn = xmalloc(sizeof(struct instruction));
624                         insn->op = OP_ADDSCC;
625                         insn->operands = $2;
626                         $$ = insn;
627                   }
628                 ;
629
630 /* sub */
631 insn_sub        : OP_SUB operlist_3 {
632                         struct instruction *insn = xmalloc(sizeof(struct instruction));
633                         insn->op = OP_SUB;
634                         insn->operands = $2;
635                         $$ = insn;
636                   }
637                 ;
638
639 /* sub. */
640 insn_subsc      : OP_SUBSC operlist_3 {
641                         struct instruction *insn = xmalloc(sizeof(struct instruction));
642                         insn->op = OP_SUBSC;
643                         insn->operands = $2;
644                         $$ = insn;
645                   }
646                 ;
647
648 /* subc */
649 insn_subc       : OP_SUBC operlist_3 {
650                         struct instruction *insn = xmalloc(sizeof(struct instruction));
651                         insn->op = OP_SUBC;
652                         insn->operands = $2;
653                         $$ = insn;
654                   }
655                 ;
656
657 /* subc. */
658 insn_subscc     : OP_SUBSCC operlist_3 {
659                         struct instruction *insn = xmalloc(sizeof(struct instruction));
660                         insn->op = OP_SUBSCC;
661                         insn->operands = $2;
662                         $$ = insn;
663                   }
664                 ;
665
666 insn_sra        : OP_SRA operlist_3 {
667                         struct instruction *insn = xmalloc(sizeof(struct instruction));
668                         insn->op = OP_SRA;
669                         insn->operands = $2;
670                         $$ = insn;
671                   }
672                 ;
673
674 insn_or         : OP_OR operlist_3 {
675                         struct instruction *insn = xmalloc(sizeof(struct instruction));
676                         insn->op = OP_OR;
677                         insn->operands = $2;
678                         $$ = insn;
679                   }
680                 ;
681
682 insn_and        : OP_AND operlist_3 {
683                         struct instruction *insn = xmalloc(sizeof(struct instruction));
684                         insn->op = OP_AND;
685                         insn->operands = $2;
686                         $$ = insn;
687                   }
688                 ;
689
690 insn_xor        : OP_XOR operlist_3 {
691                         struct instruction *insn = xmalloc(sizeof(struct instruction));
692                         insn->op = OP_XOR;
693                         insn->operands = $2;
694                         $$ = insn;
695                   }
696                 ;
697
698 insn_sr         : OP_SR operlist_3 {
699                         struct instruction *insn = xmalloc(sizeof(struct instruction));
700                         insn->op = OP_SR;
701                         insn->operands = $2;
702                         $$ = insn;
703                   }
704                 ;
705
706 insn_srx        : OP_SRX extended_operlist {
707                         struct instruction *insn = xmalloc(sizeof(struct instruction));
708                         insn->op = OP_SRX;
709                         insn->operands = $2;
710                         $$ = insn;
711                   }
712                 ;
713
714 insn_sl         : OP_SL operlist_3 {
715                         struct instruction *insn = xmalloc(sizeof(struct instruction));
716                         insn->op = OP_SL;
717                         insn->operands = $2;
718                         $$ = insn;
719                   }
720                 ;
721
722 insn_rl         : OP_RL operlist_3 {
723                         struct instruction *insn = xmalloc(sizeof(struct instruction));
724                         insn->op = OP_RL;
725                         insn->operands = $2;
726                         $$ = insn;
727                   }
728                 ;
729
730 insn_rr         : OP_RR operlist_3 {
731                         struct instruction *insn = xmalloc(sizeof(struct instruction));
732                         insn->op = OP_RR;
733                         insn->operands = $2;
734                         $$ = insn;
735                   }
736                 ;
737
738 insn_nand       : OP_NAND operlist_3 {
739                         struct instruction *insn = xmalloc(sizeof(struct instruction));
740                         insn->op = OP_NAND;
741                         insn->operands = $2;
742                         $$ = insn;
743                   }
744                 ;
745
746 insn_orx        : OP_ORX extended_operlist {
747                         struct instruction *insn = xmalloc(sizeof(struct instruction));
748                         insn->op = OP_ORX;
749                         insn->operands = $2;
750                         $$ = insn;
751                   }
752                 ;
753
754 insn_mov        : OP_MOV operlist_2 {
755                         struct instruction *insn = xmalloc(sizeof(struct instruction));
756                         insn->op = OP_MOV;
757                         insn->operands = $2;
758                         $$ = insn;
759                   }
760                 ;
761
762 insn_jmp        : OP_JMP labelref {
763                         struct instruction *insn = xmalloc(sizeof(struct instruction));
764                         struct operlist *ol = xmalloc(sizeof(struct operlist));
765                         ol->oper[0] = $2;
766                         insn->op = OP_JMP;
767                         insn->operands = ol;
768                         $$ = insn;
769                   }
770                 ;
771
772 insn_jand       : OP_JAND operlist_3 {
773                         struct instruction *insn = xmalloc(sizeof(struct instruction));
774                         insn->op = OP_JAND;
775                         insn->operands = $2;
776                         $$ = insn;
777                   }
778                 ;
779
780 insn_jnand      : OP_JNAND operlist_3 {
781                         struct instruction *insn = xmalloc(sizeof(struct instruction));
782                         insn->op = OP_JNAND;
783                         insn->operands = $2;
784                         $$ = insn;
785                   }
786                 ;
787
788 insn_js         : OP_JS operlist_3 {
789                         struct instruction *insn = xmalloc(sizeof(struct instruction));
790                         insn->op = OP_JS;
791                         insn->operands = $2;
792                         $$ = insn;
793                   }
794                 ;
795
796 insn_jns        : OP_JNS operlist_3 {
797                         struct instruction *insn = xmalloc(sizeof(struct instruction));
798                         insn->op = OP_JNS;
799                         insn->operands = $2;
800                         $$ = insn;
801                   }
802                 ;
803
804 insn_je         : OP_JE operlist_3 {
805                         struct instruction *insn = xmalloc(sizeof(struct instruction));
806                         insn->op = OP_JE;
807                         insn->operands = $2;
808                         $$ = insn;
809                   }
810                 ;
811
812 insn_jne        : OP_JNE operlist_3 {
813                         struct instruction *insn = xmalloc(sizeof(struct instruction));
814                         insn->op = OP_JNE;
815                         insn->operands = $2;
816                         $$ = insn;
817                   }
818                 ;
819
820 insn_jls        : OP_JLS operlist_3 {
821                         struct instruction *insn = xmalloc(sizeof(struct instruction));
822                         insn->op = OP_JLS;
823                         insn->operands = $2;
824                         $$ = insn;
825                   }
826                 ;
827
828 insn_jges       : OP_JGES operlist_3 {
829                         struct instruction *insn = xmalloc(sizeof(struct instruction));
830                         insn->op = OP_JGES;
831                         insn->operands = $2;
832                         $$ = insn;
833                   }
834                 ;
835
836 insn_jgs        : OP_JGS operlist_3 {
837                         struct instruction *insn = xmalloc(sizeof(struct instruction));
838                         insn->op = OP_JGS;
839                         insn->operands = $2;
840                         $$ = insn;
841                   }
842                 ;
843
844 insn_jles       : OP_JLES operlist_3 {
845                         struct instruction *insn = xmalloc(sizeof(struct instruction));
846                         insn->op = OP_JLES;
847                         insn->operands = $2;
848                         $$ = insn;
849                   }
850                 ;
851
852 insn_jl         : OP_JL operlist_3 {
853                         struct instruction *insn = xmalloc(sizeof(struct instruction));
854                         insn->op = OP_JL;
855                         insn->operands = $2;
856                         $$ = insn;
857                   }
858                 ;
859
860 insn_jge        : OP_JGE operlist_3 {
861                         struct instruction *insn = xmalloc(sizeof(struct instruction));
862                         insn->op = OP_JGE;
863                         insn->operands = $2;
864                         $$ = insn;
865                   }
866                 ;
867
868 insn_jg         : OP_JG operlist_3 {
869                         struct instruction *insn = xmalloc(sizeof(struct instruction));
870                         insn->op = OP_JG;
871                         insn->operands = $2;
872                         $$ = insn;
873                   }
874                 ;
875
876 insn_jle        : OP_JLE operlist_3 {
877                         struct instruction *insn = xmalloc(sizeof(struct instruction));
878                         insn->op = OP_JLE;
879                         insn->operands = $2;
880                         $$ = insn;
881                   }
882                 ;
883
884 insn_jzx        : OP_JZX extended_operlist {
885                         struct instruction *insn = xmalloc(sizeof(struct instruction));
886                         insn->op = OP_JZX;
887                         insn->operands = $2;
888                         $$ = insn;
889                   }
890                 ;
891
892 insn_jnzx       : OP_JNZX extended_operlist {
893                         struct instruction *insn = xmalloc(sizeof(struct instruction));
894                         insn->op = OP_JNZX;
895                         insn->operands = $2;
896                         $$ = insn;
897                   }
898                 ;
899
900 insn_jext       : OP_JEXT external_jump_operands {
901                         struct instruction *insn = xmalloc(sizeof(struct instruction));
902                         insn->op = OP_JEXT;
903                         insn->operands = $2;
904                         $$ = insn;
905                   }
906                 ;
907
908 insn_jnext      : OP_JNEXT external_jump_operands {
909                         struct instruction *insn = xmalloc(sizeof(struct instruction));
910                         insn->op = OP_JNEXT;
911                         insn->operands = $2;
912                         $$ = insn;
913                   }
914                 ;
915
916 linkreg         : LR regnr {
917                         $$ = $2;
918                   }
919                 ;
920
921 insn_call       : OP_CALL linkreg COMMA labelref {
922                         struct instruction *insn = xmalloc(sizeof(struct instruction));
923                         struct operlist *ol = xmalloc(sizeof(struct operlist));
924                         struct operand *oper_lr = xmalloc(sizeof(struct operand));
925                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
926                         oper_zero->type = OPER_RAW;
927                         oper_zero->u.raw = 0;
928                         oper_lr->type = OPER_RAW;
929                         oper_lr->u.raw = (unsigned long)$2;
930                         ol->oper[0] = oper_lr;
931                         ol->oper[1] = oper_zero;
932                         ol->oper[2] = $4;
933                         insn->op = OP_CALL;
934                         insn->operands = ol;
935                         $$ = insn;
936                   }
937                 ;
938
939 insn_calls      :  OP_CALLS labelref {
940                         struct instruction *insn = xmalloc(sizeof(struct instruction));
941                         struct operlist *ol = xmalloc(sizeof(struct operlist));
942                         struct operand *oper_r0 = xmalloc(sizeof(struct operand));
943                         struct registr *r0 = xmalloc(sizeof(struct registr));
944                         r0->type = GPR;
945                         r0->nr = 0;
946                         oper_r0->type = OPER_REG;
947                         oper_r0->u.reg = r0;
948                         ol->oper[0] = oper_r0;
949                         ol->oper[1] = oper_r0;
950                         ol->oper[2] = $2;
951                         insn->op = OP_CALLS;
952                         insn->operands = ol;
953                         $$ = insn;
954                   }
955                 ;
956
957 insn_ret        : OP_RET linkreg COMMA linkreg {
958                         struct instruction *insn = xmalloc(sizeof(struct instruction));
959                         struct operlist *ol = xmalloc(sizeof(struct operlist));
960                         struct operand *oper_lr0 = xmalloc(sizeof(struct operand));
961                         struct operand *oper_lr1 = xmalloc(sizeof(struct operand));
962                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
963                         oper_zero->type = OPER_RAW;
964                         oper_zero->u.raw = 0;
965                         oper_lr0->type = OPER_RAW;
966                         oper_lr0->u.raw = (unsigned long)$2;
967                         oper_lr1->type = OPER_RAW;
968                         oper_lr1->u.raw = (unsigned long)$4;
969                         ol->oper[0] = oper_lr0;
970                         ol->oper[1] = oper_zero;
971                         ol->oper[2] = oper_lr1;
972                         insn->op = OP_RET;
973                         insn->operands = ol;
974                         $$ = insn;
975                   }
976                 ;
977
978 insn_rets       : OP_RETS {
979                         struct instruction *insn = xmalloc(sizeof(struct instruction));
980                         struct operlist *ol = xmalloc(sizeof(struct operlist));
981                         struct operand *oper_r0 = xmalloc(sizeof(struct operand));
982                         struct operand *oper_zero = xmalloc(sizeof(struct operand));
983                         struct registr *r0 = xmalloc(sizeof(struct registr));
984                         oper_zero->type = OPER_RAW;
985                         oper_zero->u.raw = 0;
986                         r0->type = GPR;
987                         r0->nr = 0;
988                         oper_r0->type = OPER_REG;
989                         oper_r0->u.reg = r0;
990                         ol->oper[0] = oper_r0;
991                         ol->oper[1] = oper_r0;
992                         ol->oper[2] = oper_zero;
993                         insn->op = OP_RETS;
994                         insn->operands = ol;
995                         $$ = insn;
996                   }
997                 ;
998
999 insn_tkiph      : OP_TKIPH operlist_2 {
1000                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1001                         struct operlist *ol = $2;
1002                         struct operand *flags = xmalloc(sizeof(struct operand));
1003                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1004                         imm->imm = 0x1;
1005                         flags->type = OPER_IMM;
1006                         flags->u.imm = imm;
1007                         ol->oper[2] = ol->oper[1];
1008                         ol->oper[1] = flags;
1009                         insn->op = OP_TKIPH;
1010                         insn->operands = ol;
1011                         $$ = insn;
1012                   }
1013                 ;
1014
1015 insn_tkiphs     : OP_TKIPHS operlist_2 {
1016                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1017                         struct operlist *ol = $2;
1018                         struct operand *flags = xmalloc(sizeof(struct operand));
1019                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1020                         imm->imm = 0x1 | 0x2;
1021                         flags->type = OPER_IMM;
1022                         flags->u.imm = imm;
1023                         ol->oper[2] = ol->oper[1];
1024                         ol->oper[1] = flags;
1025                         insn->op = OP_TKIPH;
1026                         insn->operands = ol;
1027                         $$ = insn;
1028                   }
1029                 ;
1030
1031 insn_tkipl      : OP_TKIPL operlist_2 {
1032                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1033                         struct operlist *ol = $2;
1034                         struct operand *flags = xmalloc(sizeof(struct operand));
1035                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1036                         imm->imm = 0x0;
1037                         flags->type = OPER_IMM;
1038                         flags->u.imm = imm;
1039                         ol->oper[2] = ol->oper[1];
1040                         ol->oper[1] = flags;
1041                         insn->op = OP_TKIPH;
1042                         insn->operands = ol;
1043                         $$ = insn;
1044                   }
1045                 ;
1046
1047 insn_tkipls     : OP_TKIPLS operlist_2 {
1048                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1049                         struct operlist *ol = $2;
1050                         struct operand *flags = xmalloc(sizeof(struct operand));
1051                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1052                         imm->imm = 0x0 | 0x2;
1053                         flags->type = OPER_IMM;
1054                         flags->u.imm = imm;
1055                         ol->oper[2] = ol->oper[1];
1056                         ol->oper[1] = flags;
1057                         insn->op = OP_TKIPH;
1058                         insn->operands = ol;
1059                         $$ = insn;
1060                   }
1061                 ;
1062
1063 insn_nap        : OP_NAP {
1064                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1065                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1066                         struct operand *regop = xmalloc(sizeof(struct operand));
1067                         struct operand *zeroop = xmalloc(sizeof(struct operand));
1068                         struct registr *r0 = xmalloc(sizeof(struct registr));
1069                         r0->type = GPR;
1070                         r0->nr = 0;
1071                         regop->type = OPER_REG;
1072                         regop->u.reg = r0;
1073                         zeroop->type = OPER_RAW;
1074                         zeroop->u.raw = 0x000;
1075                         ol->oper[0] = regop;
1076                         ol->oper[1] = regop;
1077                         ol->oper[2] = zeroop;
1078                         insn->op = OP_NAP;
1079                         insn->operands = ol;
1080                         $$ = insn;
1081                   }
1082                 ;
1083
1084 insn_raw        : raw_code operlist_3 {
1085                         struct instruction *insn = xmalloc(sizeof(struct instruction));
1086                         insn->op = RAW_CODE;
1087                         insn->operands = $2;
1088                         insn->opcode = (unsigned long)$1;
1089                         $$ = insn;
1090                   }
1091                 ;
1092
1093 raw_code        : RAW_CODE {
1094                         yytext++; /* skip @ */
1095                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1096                   }
1097                 ;
1098
1099 extended_operlist : imm_value COMMA imm_value COMMA operand COMMA operand COMMA operand {
1100                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1101                         struct operand *mask_oper = xmalloc(sizeof(struct operand));
1102                         struct operand *shift_oper = xmalloc(sizeof(struct operand));
1103                         mask_oper->type = OPER_RAW;
1104                         mask_oper->u.raw = (unsigned long)$1;
1105                         shift_oper->type = OPER_RAW;
1106                         shift_oper->u.raw = (unsigned long)$3;
1107                         ol->oper[0] = mask_oper;
1108                         ol->oper[1] = shift_oper;
1109                         ol->oper[2] = $5;
1110                         ol->oper[3] = $7;
1111                         ol->oper[4] = store_oper_sanity($9);
1112                         $$ = ol;
1113                   }
1114                 ;
1115
1116 external_jump_operands : imm COMMA labelref {
1117                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1118                         struct operand *cond = xmalloc(sizeof(struct operand));
1119                         cond->type = OPER_IMM;
1120                         cond->u.imm = $1;
1121                         ol->oper[0] = cond;
1122                         ol->oper[1] = $3;
1123                         $$ = ol;
1124                   }
1125                 ;
1126
1127 operlist_2      : operand COMMA operand {
1128                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1129                         ol->oper[0] = $1;
1130                         ol->oper[1] = store_oper_sanity($3);
1131                         $$ = ol;
1132                   }
1133                 ;
1134
1135 operlist_3      : operand COMMA operand COMMA operand {
1136                         struct operlist *ol = xmalloc(sizeof(struct operlist));
1137                         ol->oper[0] = $1;
1138                         ol->oper[1] = $3;
1139                         ol->oper[2] = store_oper_sanity($5);
1140                         $$ = ol;
1141                   }
1142                 ;
1143
1144 operand         : reg {
1145                         struct operand *oper = xmalloc(sizeof(struct operand));
1146                         oper->type = OPER_REG;
1147                         oper->u.reg = $1;
1148                         $$ = oper;
1149                   }
1150                 | mem {
1151                         struct operand *oper = xmalloc(sizeof(struct operand));
1152                         oper->type = OPER_MEM;
1153                         oper->u.mem = $1;
1154                         $$ = oper;
1155                   }
1156                 | raw_code {
1157                         struct operand *oper = xmalloc(sizeof(struct operand));
1158                         oper->type = OPER_RAW;
1159                         oper->u.raw = (unsigned long)$1;
1160                         $$ = oper;
1161                   }
1162                 | imm {
1163                         struct operand *oper = xmalloc(sizeof(struct operand));
1164                         oper->type = OPER_IMM;
1165                         oper->u.imm = $1;
1166                         $$ = oper;
1167                   }
1168                 | labelref {
1169                         $$ = $1;
1170                   }
1171                 ;
1172
1173 reg             : GPR regnr {
1174                         struct registr *reg = xmalloc(sizeof(struct registr));
1175                         reg->type = GPR;
1176                         reg->nr = (unsigned long)$2;
1177                         $$ = reg;
1178                   }
1179                 | SPR {
1180                         struct registr *reg = xmalloc(sizeof(struct registr));
1181                         reg->type = SPR;
1182                         yytext += 3; /* skip "spr" */
1183                         reg->nr = strtoul(yytext, NULL, 16);
1184                         $$ = reg;
1185                   }
1186                 | OFFR regnr {
1187                         struct registr *reg = xmalloc(sizeof(struct registr));
1188                         reg->type = OFFR;
1189                         reg->nr = (unsigned long)$2;
1190                         $$ = reg;
1191                   }
1192                 ;
1193
1194 mem             : BRACK_OPEN imm BRACK_CLOSE {
1195                         struct memory *mem = xmalloc(sizeof(struct memory));
1196                         struct immediate *offset_imm = $2;
1197                         mem->type = MEM_DIRECT;
1198                         mem->offset = offset_imm->imm;
1199                         free(offset_imm);
1200                         $$ = mem;
1201                   }
1202                 | BRACK_OPEN imm COMMA OFFR regnr BRACK_CLOSE {
1203                         struct memory *mem = xmalloc(sizeof(struct memory));
1204                         struct immediate *offset_imm = $2;
1205                         mem->type = MEM_INDIRECT;
1206                         mem->offset = offset_imm->imm;
1207                         free(offset_imm);
1208                         mem->offr_nr = (unsigned long)$5;
1209                         $$ = mem;
1210                   }
1211                 ;
1212
1213 imm             : imm_value {
1214                         struct immediate *imm = xmalloc(sizeof(struct immediate));
1215                         imm->imm = (unsigned long)$1;
1216                         $$ = imm;
1217                   }
1218                 ;
1219
1220 imm_value       : hexnum_decnum {
1221                         $$ = $1;
1222                   }
1223                 | complex_imm {
1224                         $$ = $1;
1225                   }
1226                 ;
1227
1228 complex_imm     : PAREN_OPEN complex_imm_arg complex_imm_oper complex_imm_arg PAREN_CLOSE {
1229                         unsigned long a = (unsigned long)$2;
1230                         unsigned long b = (unsigned long)$4;
1231                         unsigned long operation = (unsigned long)$3;
1232                         unsigned long res = 31337;
1233                         switch (operation) {
1234                         case PLUS:
1235                                 res = a + b;
1236                                 break;
1237                         case MINUS:
1238                                 res = a - b;
1239                                 break;
1240                         case MULTIPLY:
1241                                 res = a * b;
1242                                 break;
1243                         case DIVIDE:
1244                                 res = a / b;
1245                                 break;
1246                         case BITW_OR:
1247                                 res = a | b;
1248                                 break;
1249                         case BITW_AND:
1250                                 res = a & b;
1251                                 break;
1252                         case BITW_XOR:
1253                                 res = a ^ b;
1254                                 break;
1255                         case LEFTSHIFT:
1256                                 res = a << b;
1257                                 break;
1258                         case RIGHTSHIFT:
1259                                 res = a >> b;
1260                                 break;
1261                         default:
1262                                 yyerror("Internal parser BUG. complex_imm oper unknown");
1263                         }
1264                         $$ = (void *)res;
1265                   }
1266                 | PAREN_OPEN complex_imm PAREN_CLOSE {
1267                         $$ = $2;
1268                   }
1269                 | PAREN_OPEN asm_assert PAREN_CLOSE {
1270                         /* Inline assertion. Always return zero */
1271                         $$ = (void *)(unsigned long)(unsigned int)0;
1272                   }
1273                 | PAREN_OPEN BITW_NOT complex_imm PAREN_CLOSE {
1274                         unsigned long n = (unsigned long)$3;
1275                         n = ~n;
1276                         $$ = (void *)n;
1277                   }
1278                 | PAREN_OPEN complex_imm_const PAREN_CLOSE {
1279                         $$ = $2;
1280                   }
1281                 ;
1282
1283 complex_imm_oper : PLUS {
1284                         $$ = (void *)(unsigned long)PLUS;
1285                   }
1286                 | MINUS {
1287                         $$ = (void *)(unsigned long)MINUS;
1288                   }
1289                 | MULTIPLY {
1290                         $$ = (void *)(unsigned long)MULTIPLY;
1291                   }
1292                 | DIVIDE {
1293                         $$ = (void *)(unsigned long)DIVIDE;
1294                   }
1295                 | BITW_OR {
1296                         $$ = (void *)(unsigned long)BITW_OR;
1297                   }
1298                 | BITW_AND {
1299                         $$ = (void *)(unsigned long)BITW_AND;
1300                   }
1301                 | BITW_XOR {
1302                         $$ = (void *)(unsigned long)BITW_XOR;
1303                   }
1304                 | LEFTSHIFT {
1305                         $$ = (void *)(unsigned long)LEFTSHIFT;
1306                   }
1307                 | RIGHTSHIFT {
1308                         $$ = (void *)(unsigned long)RIGHTSHIFT;
1309                   }
1310                 ;
1311
1312 complex_imm_arg : complex_imm_const {
1313                         $$ = $1;
1314                   }
1315                 | complex_imm {
1316                         $$ = $1;
1317                   }
1318                 ;
1319
1320 complex_imm_const : hexnum_decnum {
1321                         $$ = $1;
1322                   }
1323                 | BITW_NOT hexnum_decnum {
1324                         unsigned long n = (unsigned long)$2;
1325                         n = ~n;
1326                         $$ = (void *)n;
1327                   }
1328                 ;
1329
1330 hexnum          : HEXNUM {
1331                         while (yytext[0] != 'x') {
1332                                 if (yytext[0] == '\0')
1333                                         yyerror("Internal HEXNUM parser error");
1334                                 yytext++;
1335                         }
1336                         yytext++;
1337                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 16);
1338                   }
1339                 ;
1340
1341 decnum          : DECNUM {
1342                         $$ = (void *)(unsigned long)strtol(yytext, NULL, 10);
1343                   }
1344                 ;
1345
1346 hexnum_decnum   : hexnum {
1347                         $$ = $1;
1348                   }
1349                 | decnum {
1350                         $$ = $1;
1351                   }
1352                 ;
1353
1354 labelref        : identifier {
1355                         struct operand *oper = xmalloc(sizeof(struct operand));
1356                         struct label *label = xmalloc(sizeof(struct label));
1357                         label->name = $1;
1358                         label->direction = LABELREF_ABSOLUTE;
1359                         oper->type = OPER_LABEL;
1360                         oper->u.label = label;
1361                         $$ = oper;
1362                   }
1363                 | identifier MINUS {
1364                         struct operand *oper = xmalloc(sizeof(struct operand));
1365                         struct label *label = xmalloc(sizeof(struct label));
1366                         label->name = $1;
1367                         label->direction = LABELREF_RELATIVE_BACK;
1368                         oper->type = OPER_LABEL;
1369                         oper->u.label = label;
1370                         $$ = oper;
1371                   }
1372                 | identifier PLUS {
1373                         struct operand *oper = xmalloc(sizeof(struct operand));
1374                         struct label *label = xmalloc(sizeof(struct label));
1375                         label->name = $1;
1376                         label->direction = LABELREF_RELATIVE_FORWARD;
1377                         oper->type = OPER_LABEL;
1378                         oper->u.label = label;
1379                         $$ = oper;
1380                   }
1381                 ;
1382
1383 regnr           : DECNUM {
1384                         $$ = (void *)(unsigned long)strtoul(yytext, NULL, 10);
1385                   }
1386                 ;
1387
1388 identifier      : IDENT {
1389                         $$ = xstrdup(yytext);
1390                   }
1391                 ;
1392
1393 %%
1394
1395 int section = SECTION_TEXT; /* default to .text section */
1396 struct initvals_sect *cur_initvals_sect;
1397
1398 void yyerror(char *str)
1399 {
1400         unsigned int i;
1401
1402         fprintf(stderr,
1403                 "Parser ERROR (file \"%s\", line %u, col %u):\n",
1404                 cur_lineinfo.file,
1405                 cur_lineinfo.lineno,
1406                 cur_lineinfo.column);
1407         fprintf(stderr, "%s\n", cur_lineinfo.linecopy);
1408         for (i = 0; i < cur_lineinfo.column - 1; i++)
1409                 fprintf(stderr, " ");
1410         fprintf(stderr, "^\n");
1411         fprintf(stderr, "%s\n", str);
1412         exit(1);
1413 }
1414
1415 static struct operand * store_oper_sanity(struct operand *oper)
1416 {
1417         if (oper->type == OPER_IMM &&
1418             oper->u.imm->imm != 0) {
1419                 yyerror("Only 0x000 Immediate is allowed for "
1420                         "Output operands");
1421         }
1422         return oper;
1423 }
1424
1425 static void assembler_assertion_failed(void)
1426 {
1427         yyerror("Assembler %assert failed");
1428 }