b43-asm, b43-dasm: Add 5 new instructions.
[b43-tools.git] / assembler / scanner.l
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 "parser.h"
17 #include "main.h"
18 #include "util.h"
19
20 #include <stdio.h>
21 #include <ctype.h>
22
23
24 static void interpret_cppinfo(const char *);
25 static void update_lineinfo(void);
26
27 static inline void log_current_line(void)
28 {
29         size_t len;
30
31         len = min(sizeof(cur_lineinfo.linecopy) - 1, strlen(yytext));
32         memcpy(cur_lineinfo.linecopy, yytext, len);
33         cur_lineinfo.linecopy[len] = '\0';
34 }
35
36 %}
37
38 IDENTIFIER      ([a-zA-Z_][0-9a-zA-Z_]*)
39 WS              ([ \t])
40 NEWLINE         ((\r)|(\n)|(\r\n))
41
42 %%
43
44 ^.*$                                    { log_current_line(); REJECT; }
45 #{WS}+[0-9]+{WS}+\".*\"[0-9 \t]*{NEWLINE}       { interpret_cppinfo(yytext); }
46
47
48 {WS}+                   { update_lineinfo(); /* whitespace */ }
49 {NEWLINE}               { cur_lineinfo.lineno++; update_lineinfo(); }
50
51 ^{WS}*"%"{WS}*arch      { update_lineinfo(); return ASM_ARCH; }
52 ^{WS}*"%"{WS}*start     { update_lineinfo(); return ASM_START; }
53 "%"{WS}*assert          { update_lineinfo(); return ASM_ASSERT; }
54
55 ^{WS}*\.text{WS}*$                      { update_lineinfo(); return SECTION_TEXT; }
56 ^{WS}*\.initvals/\({IDENTIFIER}\)       { update_lineinfo(); return SECTION_IVALS; }
57
58 spr[0-9a-fA-F]{1,4}     { update_lineinfo(); return SPR; }
59 r/([0-9]|([1-5][0-9])|(6[0-3])) { update_lineinfo(); return GPR; }
60 off/[0-6]               { update_lineinfo(); return OFFR; }
61 lr/[0-3]                { update_lineinfo(); return LR; }
62
63 ,                       { update_lineinfo(); return COMMA; }
64 ;                       { update_lineinfo(); return SEMICOLON; }
65 \[                      { update_lineinfo(); return BRACK_OPEN; }
66 \]                      { update_lineinfo(); return BRACK_CLOSE; }
67 \(                      { update_lineinfo(); return PAREN_OPEN; }
68 \)                      { update_lineinfo(); return PAREN_CLOSE; }
69
70 ==                      { update_lineinfo(); return EQUAL; }
71 !=                      { update_lineinfo(); return NOT_EQUAL; }
72 \|\|                    { update_lineinfo(); return LOGICAL_OR; }
73 \&\&                    { update_lineinfo(); return LOGICAL_AND; }
74 \+                      { update_lineinfo(); return PLUS; }
75 \-                      { update_lineinfo(); return MINUS; }
76 \*                      { update_lineinfo(); return MULTIPLY; }
77 \/                      { update_lineinfo(); return DIVIDE; }
78 \|                      { update_lineinfo(); return BITW_OR; }
79 \&                      { update_lineinfo(); return BITW_AND; }
80 \^                      { update_lineinfo(); return BITW_XOR; }
81 \~                      { update_lineinfo(); return BITW_NOT; }
82 \<\<                    { update_lineinfo(); return LEFTSHIFT; }
83 \>\>                    { update_lineinfo(); return RIGHTSHIFT; }
84
85 mul                     { update_lineinfo(); return OP_MUL; }
86
87 add                     { update_lineinfo(); return OP_ADD; }
88 add\.                   { update_lineinfo(); return OP_ADDSC; }
89 addc                    { update_lineinfo(); return OP_ADDC; }
90 addc\.                  { update_lineinfo(); return OP_ADDSCC; }
91
92 sub                     { update_lineinfo(); return OP_SUB; }
93 sub\.                   { update_lineinfo(); return OP_SUBSC; }
94 subc                    { update_lineinfo(); return OP_SUBC; }
95 subc\.                  { update_lineinfo(); return OP_SUBSCC; }
96
97 sra                     { update_lineinfo(); return OP_SRA; }
98 or                      { update_lineinfo(); return OP_OR; }
99 and                     { update_lineinfo(); return OP_AND; }
100 xor                     { update_lineinfo(); return OP_XOR; }
101 sr                      { update_lineinfo(); return OP_SR; }
102 srx                     { update_lineinfo(); return OP_SRX; }
103 sl                      { update_lineinfo(); return OP_SL; }
104 rl                      { update_lineinfo(); return OP_RL; }
105 rr                      { update_lineinfo(); return OP_RR; }
106 nand                    { update_lineinfo(); return OP_NAND; }
107 orx                     { update_lineinfo(); return OP_ORX; }
108 mov                     { update_lineinfo(); return OP_MOV; }
109
110 jmp                     { update_lineinfo(); return OP_JMP; }
111 jand                    { update_lineinfo(); return OP_JAND; }
112 jnand                   { update_lineinfo(); return OP_JNAND; }
113 js                      { update_lineinfo(); return OP_JS; }
114 jns                     { update_lineinfo(); return OP_JNS; }
115 je                      { update_lineinfo(); return OP_JE; }
116 jne                     { update_lineinfo(); return OP_JNE; }
117 jls                     { update_lineinfo(); return OP_JLS; }
118 jges                    { update_lineinfo(); return OP_JGES; }
119 jgs                     { update_lineinfo(); return OP_JGS; }
120 jles                    { update_lineinfo(); return OP_JLES; }
121 jl                      { update_lineinfo(); return OP_JL; }
122 jge                     { update_lineinfo(); return OP_JGE; }
123 jg                      { update_lineinfo(); return OP_JG; }
124 jle                     { update_lineinfo(); return OP_JLE; }
125 jdn                     { update_lineinfo(); return OP_JDN; }
126 jdpz                    { update_lineinfo(); return OP_JDPZ; }
127 jdp                     { update_lineinfo(); return OP_JDP; }
128 jdnz                    { update_lineinfo(); return OP_JDNZ; }
129 jzx                     { update_lineinfo(); return OP_JZX; }
130 jnzx                    { update_lineinfo(); return OP_JNZX; }
131 jext                    { update_lineinfo(); return OP_JEXT; }
132 jnext                   { update_lineinfo(); return OP_JNEXT; }
133
134 call                    { update_lineinfo(); return OP_CALL; }
135 calls                   { update_lineinfo(); return OP_CALLS; }
136 ret                     { update_lineinfo(); return OP_RET; }
137 rets                    { update_lineinfo(); return OP_RETS; }
138
139 tkiph                   { update_lineinfo(); return OP_TKIPH; }
140 tkiphs                  { update_lineinfo(); return OP_TKIPHS; }
141 tkipl                   { update_lineinfo(); return OP_TKIPL; }
142 tkipls                  { update_lineinfo(); return OP_TKIPLS; }
143
144 nap                     { update_lineinfo(); return OP_NAP; }
145
146 mmio16                  { update_lineinfo(); return IVAL_MMIO16; }
147 mmio32                  { update_lineinfo(); return IVAL_MMIO32; }
148 phy                     { update_lineinfo(); return IVAL_PHY; }
149 radio                   { update_lineinfo(); return IVAL_RADIO; }
150 shm16                   { update_lineinfo(); return IVAL_SHM16; }
151 shm32                   { update_lineinfo(); return IVAL_SHM32; }
152 tram                    { update_lineinfo(); return IVAL_TRAM; }
153
154 @[0-9a-fA-F]{1,4}       { update_lineinfo(); return RAW_CODE; }
155
156 0x[0-9a-fA-F]+          { update_lineinfo(); return HEXNUM; }
157 -?[0-9]+                { update_lineinfo(); return DECNUM; }
158
159 {IDENTIFIER}:           { update_lineinfo(); return LABEL; }
160 {IDENTIFIER}            { update_lineinfo(); return IDENT; }
161
162 %%
163
164 struct lineinfo cur_lineinfo;
165
166 static inline const char * strip_leading_ws(const char *str)
167 {
168         while (*str != '\0' && isspace(*str))
169                 str++;
170         return str;
171 }
172
173 static void interpret_cppinfo(const char *str)
174 {
175         const char * const orig = str;
176         char tmp[64];
177         const char *found;
178         char *tail;
179
180         /* This will interpret lines added by CPP.
181          * They look like:
182          *     # lineno "filename" flags...
183          */
184
185         str = strip_leading_ws(str);
186         if (*str != '#')
187                 goto error;
188         str++; /* skip # character */
189         str = strip_leading_ws(str);
190         if (*str == '\0')
191                 goto error;
192
193         /* Line number */
194         found = strchr(str, ' ');
195         if (!found)
196                 goto error;
197         memset(tmp, 0, sizeof(tmp));
198         memcpy(tmp, str, min(sizeof(tmp) - 1, (size_t)(found - str)));
199         cur_lineinfo.lineno = strtoul(tmp, &tail, 0);
200         if (*tail != '\0')
201                 goto error;
202         str = strip_leading_ws(found);
203
204         /* File name */
205         if (*str != '\"')
206                 goto error;
207         str++;
208         if (*str == '\0')
209                 goto error;
210         found = strchr(str, '\"');
211         if (!found)
212                 goto error;
213         memset(cur_lineinfo.file, 0, sizeof(cur_lineinfo.file));
214         memcpy(cur_lineinfo.file, str, min(sizeof(cur_lineinfo.file) - 1,
215                                            (size_t)(found - str)));
216
217         /* We ignore the flags. */
218
219         return;
220 error:
221         fprintf(stderr, "Invalid CPP line directive:  %s\n", orig);
222         exit(1);
223 }
224
225 static void update_lineinfo(void)
226 {
227         int i = 0;
228
229         while (yytext[i] != '\0') {
230                 switch (yytext[i]) {
231                 case '\r':
232                 case '\n':
233                         cur_lineinfo.column = 0;
234                         break;
235                 case '\t':
236                         cur_lineinfo.column += 8 - (cur_lineinfo.column % 8);
237                         break;
238                 default:
239                         cur_lineinfo.column++;
240                 }
241                 i++;
242         }
243 }