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