1 %option noyywrap noinput nounput
2 %option 8bit reentrant bison-bridge
3 %option warn nodefault
4 %option bison-locations
5 
6 %{
7 /*
8  *  Copyright(c) 2019-2023 rev.ng Labs Srl. All Rights Reserved.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include <string.h>
25 #include <stdbool.h>
26 
27 #include "hex_regs.h"
28 
29 #include "idef-parser.h"
30 #include "idef-parser.tab.h"
31 
32 /* Keep track of scanner position for error message printout */
33 #define YY_USER_ACTION yylloc->first_column = yylloc->last_column; \
34     for (int i = 0; yytext[i] != '\0'; i++) {   \
35         yylloc->last_column++;                  \
36     }
37 
38 /* Global Error Counter */
39 int error_count;
40 
41 %}
42 
43 /* Definitions */
44 DIGIT                    [0-9]
45 LOWER_ID                 [a-z]
46 UPPER_ID                 [A-Z]
47 ID                       LOWER_ID|UPPER_ID
48 INST_NAME                [A-Z]+[0-9]_([A-Za-z]|[0-9]|_)+
49 HEX_DIGIT                [0-9a-fA-F]
50 REG_ID_32                e|s|d|t|u|v|x|y
51 REG_ID_64                ee|ss|dd|tt|uu|vv|xx|yy
52 SYS_ID_32                s|d
53 SYS_ID_64                ss|dd
54 PRED_ID                  d|s|t|u|v|e|x|x
55 IMM_ID                   r|s|S|u|U
56 VAR_ID                   [a-zA-Z_][a-zA-Z0-9_]*
57 SIGN_ID                  s|u
58 STRING_LIT               \"(\\.|[^"\\])*\"
59 
60 /* Tokens */
61 %%
62 
63 [ \t\f\v]+                { /* Ignore whitespaces. */ }
64 [\n\r]+                   { /* Ignore newlines. */ }
65 ^#.*$                     { /* Ignore linemarkers. */ }
66 
67 {INST_NAME}               { yylval->string = g_string_new(yytext);
68                             return INAME; }
69 "fFLOAT"                 |
70 "fUNFLOAT"               |
71 "fDOUBLE"                |
72 "fUNDOUBLE"              |
73 "0.0"                    |
74 "0x1.0p52"               |
75 "0x1.0p-52"              { return FAIL; }
76 "in"                     { return IN; }
77 "R"{REG_ID_32}"V" {
78                            yylval->rvalue.type = REGISTER_ARG;
79                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
80                            yylval->rvalue.reg.id = yytext[1];
81                            yylval->rvalue.reg.bit_width = 32;
82                            yylval->rvalue.bit_width = 32;
83                            yylval->rvalue.is_dotnew = false;
84                            yylval->rvalue.signedness = SIGNED;
85                            return REG; }
86 "R"{REG_ID_64}"V" {
87                            yylval->rvalue.type = REGISTER_ARG;
88                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
89                            yylval->rvalue.reg.id = yytext[1];
90                            yylval->rvalue.reg.bit_width = 64;
91                            yylval->rvalue.bit_width = 64;
92                            yylval->rvalue.is_dotnew = false;
93                            yylval->rvalue.signedness = SIGNED;
94                            return REG; }
95 "MuV" {
96                            yylval->rvalue.type = REGISTER_ARG;
97                            yylval->rvalue.reg.type = MODIFIER;
98                            yylval->rvalue.reg.id = 'u';
99                            yylval->rvalue.reg.bit_width = 32;
100                            yylval->rvalue.bit_width = 32;
101                            yylval->rvalue.signedness = SIGNED;
102                            return REG; }
103 "C"{REG_ID_32}"V" {
104                            yylval->rvalue.type = REGISTER_ARG;
105                            yylval->rvalue.reg.type = CONTROL;
106                            yylval->rvalue.reg.id = yytext[1];
107                            yylval->rvalue.reg.bit_width = 32;
108                            yylval->rvalue.bit_width = 32;
109                            yylval->rvalue.is_dotnew = false;
110                            yylval->rvalue.signedness = SIGNED;
111                            return REG; }
112 "C"{REG_ID_64}"V" {
113                            yylval->rvalue.type = REGISTER_ARG;
114                            yylval->rvalue.reg.type = CONTROL;
115                            yylval->rvalue.reg.id = yytext[1];
116                            yylval->rvalue.reg.bit_width = 64;
117                            yylval->rvalue.bit_width = 64;
118                            yylval->rvalue.is_dotnew = false;
119                            yylval->rvalue.signedness = SIGNED;
120                            return REG; }
121 {IMM_ID}"iV" {
122                            yylval->rvalue.type = IMMEDIATE;
123                            yylval->rvalue.signedness = SIGNED;
124                            yylval->rvalue.imm.type = VARIABLE;
125                            yylval->rvalue.imm.id = yytext[0];
126                            yylval->rvalue.bit_width = 32;
127                            yylval->rvalue.is_dotnew = false;
128                            return IMM; }
129 "P"{PRED_ID}"V" {
130                            yylval->rvalue.type = PREDICATE;
131                            yylval->rvalue.pred.id = yytext[1];
132                            yylval->rvalue.bit_width = 32;
133                            yylval->rvalue.is_dotnew = false;
134                            yylval->rvalue.signedness = SIGNED;
135                            return PRED; }
136 "P"{PRED_ID}"N" {
137                            yylval->rvalue.type = PREDICATE;
138                            yylval->rvalue.pred.id = yytext[1];
139                            yylval->rvalue.bit_width = 32;
140                            yylval->rvalue.is_dotnew = true;
141                            yylval->rvalue.signedness = SIGNED;
142                            return PRED; }
143 "+="                     { return INC; }
144 "-="                     { return DEC; }
145 "++"                     { return PLUSPLUS; }
146 "&="                     { return ANDA; }
147 "|="                     { return ORA; }
148 "^="                     { return XORA; }
149 "<<"                     { return ASL; }
150 ">>"                     { return ASR; }
151 ">>>"                    { return LSR; }
152 "=="                     { return EQ; }
153 "!="                     { return NEQ; }
154 "<="                     { return LTE; }
155 ">="                     { return GTE; }
156 "&&"                     { return ANDL; }
157 "else"                   { return ELSE; }
158 "for"                    { return FOR; }
159 "fREAD_IREG"             { return ICIRC; }
160 "if"                     { return IF; }
161 "fFRAME_SCRAMBLE"        |
162 "fFRAME_UNSCRAMBLE"      { return FSCR; }
163 "fFRAMECHECK"            { return FCHK; }
164 "Constant_extended"      { return CONSTEXT; }
165 "fCL1_"{DIGIT}           { return LOCNT; }
166 "fbrev"                  { return BREV; }
167 "fSXTN"                  { return SXT; }
168 "fZXTN"                  { return ZXT; }
169 "fDF_MAX"                |
170 "fSF_MAX"                |
171 "fMAX"                   { return MAX; }
172 "fDF_MIN"                |
173 "fSF_MIN"                |
174 "fMIN"                   { return MIN; }
175 "fABS"                   { return ABS; }
176 "fRNDN"                  { return ROUND; }
177 "fCRND"                  { return CROUND; }
178 "fCRNDN"                 { return CROUND; }
179 "fPM_CIRI"               { return CIRCADD; }
180 "fPM_CIRR"               { return CIRCADD; }
181 "fCOUNTONES_"{DIGIT}     { return COUNTONES; }
182 "fSATN"                  { yylval->sat.signedness = SIGNED;
183                            return SAT; }
184 "fSATUN"                 { yylval->sat.signedness = UNSIGNED;
185                            return SAT; }
186 "fCONSTLL"               { yylval->cast.bit_width = 64;
187                            yylval->cast.signedness = SIGNED;
188                            return CAST; }
189 "fSE32_64"               { yylval->cast.bit_width = 64;
190                            yylval->cast.signedness = SIGNED;
191                            return CAST; }
192 "fCAST4_4u"              { yylval->cast.bit_width = 32;
193                            yylval->cast.signedness = UNSIGNED;
194                            return CAST; }
195 "fCAST4_8s"              { yylval->cast.bit_width = 64;
196                            yylval->cast.signedness = SIGNED;
197                            return CAST; }
198 "fCAST4_8u"              { return CAST4_8U; }
199 "fCAST4u"                { yylval->cast.bit_width = 32;
200                            yylval->cast.signedness = UNSIGNED;
201                            return CAST; }
202 "fNEWREG"                |
203 "fCAST4_4s"              |
204 "fCAST4s"                { yylval->cast.bit_width = 32;
205                            yylval->cast.signedness = SIGNED;
206                            return CAST; }
207 "fCAST8_8u"              { yylval->cast.bit_width = 64;
208                            yylval->cast.signedness = UNSIGNED;
209                            return CAST; }
210 "fCAST8u"                { yylval->cast.bit_width = 64;
211                            yylval->cast.signedness = UNSIGNED;
212                            return CAST; }
213 "fCAST8_8s"              |
214 "fCAST8s"                { yylval->cast.bit_width = 64;
215                            yylval->cast.signedness = SIGNED;
216                            return CAST; }
217 "fGETBIT"                { yylval->extract.bit_width = 1;
218                            yylval->extract.storage_bit_width = 1;
219                            yylval->extract.signedness = UNSIGNED;
220                            return EXTRACT; }
221 "fGETBYTE"               { yylval->extract.bit_width = 8;
222                            yylval->extract.storage_bit_width = 8;
223                            yylval->extract.signedness = SIGNED;
224                            return EXTRACT; }
225 "fGETUBYTE"              { yylval->extract.bit_width = 8;
226                            yylval->extract.storage_bit_width = 8;
227                            yylval->extract.signedness = UNSIGNED;
228                            return EXTRACT; }
229 "fGETHALF"               { yylval->extract.bit_width = 16;
230                            yylval->extract.storage_bit_width = 16;
231                            yylval->extract.signedness = SIGNED;
232                            return EXTRACT; }
233 "fGETUHALF"              { yylval->extract.bit_width = 16;
234                            yylval->extract.storage_bit_width = 16;
235                            yylval->extract.signedness = UNSIGNED;
236                            return EXTRACT; }
237 "fGETWORD"               { yylval->extract.bit_width = 32;
238                            yylval->extract.storage_bit_width = 64;
239                            yylval->extract.signedness = SIGNED;
240                            return EXTRACT; }
241 "fGETUWORD"              { yylval->extract.bit_width = 32;
242                            yylval->extract.storage_bit_width = 64;
243                            yylval->extract.signedness = UNSIGNED;
244                            return EXTRACT; }
245 "fEXTRACTU_RANGE"        { return EXTRANGE; }
246 "fSETBIT"                { yylval->cast.bit_width = 1;
247                            yylval->cast.signedness = SIGNED;
248                            return DEPOSIT; }
249 "fSETBYTE"               { yylval->cast.bit_width = 8;
250                            yylval->cast.signedness = SIGNED;
251                            return DEPOSIT; }
252 "fSETHALF"               { yylval->cast.bit_width = 16;
253                            yylval->cast.signedness = SIGNED;
254                            return SETHALF; }
255 "fSETWORD"               { yylval->cast.bit_width = 32;
256                            yylval->cast.signedness = SIGNED;
257                            return DEPOSIT; }
258 "fINSERT_BITS"           { return INSBITS; }
259 "fSETBITS"               { return SETBITS; }
260 "fMPY16UU"               { yylval->mpy.first_bit_width = 16;
261                            yylval->mpy.second_bit_width = 16;
262                            yylval->mpy.first_signedness = UNSIGNED;
263                            yylval->mpy.second_signedness = UNSIGNED;
264                            return MPY; }
265 "fMPY16SU"               { yylval->mpy.first_bit_width = 16;
266                            yylval->mpy.second_bit_width = 16;
267                            yylval->mpy.first_signedness = SIGNED;
268                            yylval->mpy.second_signedness = UNSIGNED;
269                            return MPY; }
270 "fMPY16SS"               { yylval->mpy.first_bit_width = 16;
271                            yylval->mpy.second_bit_width = 16;
272                            yylval->mpy.first_signedness = SIGNED;
273                            yylval->mpy.second_signedness = SIGNED;
274                            return MPY; }
275 "fMPY32UU"               { yylval->mpy.first_bit_width = 32;
276                            yylval->mpy.second_bit_width = 32;
277                            yylval->mpy.first_signedness = UNSIGNED;
278                            yylval->mpy.second_signedness = UNSIGNED;
279                            return MPY; }
280 "fMPY32SU"               { yylval->mpy.first_bit_width = 32;
281                            yylval->mpy.second_bit_width = 32;
282                            yylval->mpy.first_signedness = SIGNED;
283                            yylval->mpy.second_signedness = UNSIGNED;
284                            return MPY; }
285 "fSFMPY"                 |
286 "fMPY32SS"               { yylval->mpy.first_bit_width = 32;
287                            yylval->mpy.second_bit_width = 32;
288                            yylval->mpy.first_signedness = SIGNED;
289                            yylval->mpy.second_signedness = SIGNED;
290                            return MPY; }
291 "fMPY3216SS"             { yylval->mpy.first_bit_width = 32;
292                            yylval->mpy.second_bit_width = 16;
293                            yylval->mpy.first_signedness = SIGNED;
294                            yylval->mpy.second_signedness = SIGNED;
295                            return MPY; }
296 "fMPY3216SU"             { yylval->mpy.first_bit_width = 32;
297                            yylval->mpy.second_bit_width = 16;
298                            yylval->mpy.first_signedness = SIGNED;
299                            yylval->mpy.second_signedness = UNSIGNED;
300                            return MPY; }
301 "fNEWREG_ST"             |
302 "fIMMEXT"                |
303 "fMUST_IMMEXT"           |
304 "fPASS"                  |
305 "fECHO"                  { return IDENTITY; }
306 "(size8u_t)"             { yylval->cast.bit_width = 64;
307                            yylval->cast.signedness = UNSIGNED;
308                            return CAST; }
309 "(unsigned int)"         { yylval->cast.bit_width = 32;
310                            yylval->cast.signedness = UNSIGNED;
311                            return CAST; }
312 "fREAD_PC()"             { return PC; }
313 "USR.LPCFG"              { return LPCFG; }
314 "LOAD_CANCEL(EA)"        { return LOAD_CANCEL; }
315 "STORE_CANCEL(EA)"       { return STORE_CANCEL; }
316 "CANCEL"                 { return CANCEL; }
317 "N"{LOWER_ID}"N"         { yylval->rvalue.type = REGISTER_ARG;
318                            yylval->rvalue.reg.type = DOTNEW;
319                            yylval->rvalue.reg.id = yytext[1];
320                            yylval->rvalue.reg.bit_width = 32;
321                            yylval->rvalue.bit_width = 32;
322                            yylval->rvalue.signedness = UNSIGNED;
323                            return REG; }
324 "fREAD_SP()"             |
325 "SP"                     { yylval->rvalue.type = REGISTER;
326                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
327                            yylval->rvalue.reg.id = HEX_REG_SP;
328                            yylval->rvalue.reg.bit_width = 32;
329                            yylval->rvalue.bit_width = 32;
330                            yylval->rvalue.signedness = UNSIGNED;
331                            return REG; }
332 "fREAD_FP()"             |
333 "FP"                     { yylval->rvalue.type = REGISTER;
334                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
335                            yylval->rvalue.reg.id = HEX_REG_FP;
336                            yylval->rvalue.reg.bit_width = 32;
337                            yylval->rvalue.bit_width = 32;
338                            yylval->rvalue.signedness = UNSIGNED;
339                            return REG; }
340 "fREAD_LR()"             |
341 "LR"                     { yylval->rvalue.type = REGISTER;
342                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
343                            yylval->rvalue.reg.id = HEX_REG_LR;
344                            yylval->rvalue.reg.bit_width = 32;
345                            yylval->rvalue.bit_width = 32;
346                            yylval->rvalue.signedness = UNSIGNED;
347                            return REG; }
348 "fREAD_GP()"             |
349 "GP"                     { yylval->rvalue.type = REGISTER;
350                            yylval->rvalue.reg.type = CONTROL;
351                            yylval->rvalue.reg.id = HEX_REG_GP;
352                            yylval->rvalue.reg.bit_width = 32;
353                            yylval->rvalue.bit_width = 32;
354                            yylval->rvalue.signedness = UNSIGNED;
355                            return REG; }
356 "LC"[01]                 { yylval->rvalue.type = REGISTER;
357                            yylval->rvalue.reg.type = CONTROL;
358                            yylval->rvalue.reg.id = HEX_REG_LC0
359                                                  + (yytext[2] - '0') * 2;
360                            yylval->rvalue.reg.bit_width = 32;
361                            yylval->rvalue.bit_width = 32;
362                            yylval->rvalue.signedness = UNSIGNED;
363                            return REG; }
364 "SA"[01]                 { yylval->rvalue.type = REGISTER;
365                            yylval->rvalue.reg.type = CONTROL;
366                            yylval->rvalue.reg.id = HEX_REG_SA0
367                                                  + (yytext[2] - '0') * 2;
368                            yylval->rvalue.reg.bit_width = 32;
369                            yylval->rvalue.bit_width = 32;
370                            yylval->rvalue.signedness = UNSIGNED;
371                            return REG; }
372 "fREAD_P0()"             { yylval->rvalue.type = PREDICATE;
373                            yylval->rvalue.pred.id = '0';
374                            yylval->rvalue.bit_width = 32;
375                            return PRED; }
376 [pP]{DIGIT}              { yylval->rvalue.type = PREDICATE;
377                            yylval->rvalue.pred.id = yytext[1];
378                            yylval->rvalue.bit_width = 32;
379                            yylval->rvalue.is_dotnew = false;
380                            return PRED; }
381 [pP]{DIGIT}[nN]          { yylval->rvalue.type = PREDICATE;
382                            yylval->rvalue.pred.id = yytext[1];
383                            yylval->rvalue.bit_width = 32;
384                            yylval->rvalue.is_dotnew = true;
385                            return PRED; }
386 "fLSBNEW"                { return LSBNEW; }
387 "N"                      { yylval->rvalue.type = IMMEDIATE;
388                            yylval->rvalue.bit_width = 32;
389                            yylval->rvalue.imm.type = VARIABLE;
390                            yylval->rvalue.imm.id = 'N';
391                            return IMM; }
392 "i"                      { yylval->rvalue.type = IMMEDIATE;
393                            yylval->rvalue.bit_width = 32;
394                            yylval->rvalue.signedness = SIGNED;
395                            yylval->rvalue.imm.type = I;
396                            return IMM; }
397 {SIGN_ID}                { if (yytext[0] == 'u') {
398                                yylval->signedness = UNSIGNED;
399                            } else {
400                                yylval->signedness = SIGNED;
401                            }
402                            return SIGN;
403                          }
404 "0x"{HEX_DIGIT}+         { uint64_t value = strtoull(yytext, NULL, 0);
405                            yylval->rvalue.type = IMMEDIATE;
406                            yylval->rvalue.imm.type = VALUE;
407                            yylval->rvalue.imm.value = value;
408                            if (value <= INT_MAX) {
409                                yylval->rvalue.bit_width = sizeof(int) * 8;
410                                yylval->rvalue.signedness = SIGNED;
411                            } else if (value <= UINT_MAX) {
412                                yylval->rvalue.bit_width = sizeof(unsigned int) * 8;
413                                yylval->rvalue.signedness = UNSIGNED;
414                            } else if (value <= LONG_MAX) {
415                                yylval->rvalue.bit_width = sizeof(long) * 8;
416                                yylval->rvalue.signedness = SIGNED;
417                            } else if (value <= ULONG_MAX) {
418                                yylval->rvalue.bit_width = sizeof(unsigned long) * 8;
419                                yylval->rvalue.signedness = UNSIGNED;
420                            } else {
421                                g_assert_not_reached();
422                            }
423                            return IMM; }
424 {DIGIT}+                 { int64_t value = strtoll(yytext, NULL, 0);
425                            yylval->rvalue.type = IMMEDIATE;
426                            yylval->rvalue.imm.type = VALUE;
427                            yylval->rvalue.imm.value = value;
428                            if (value >= INT_MIN && value <= INT_MAX) {
429                                yylval->rvalue.bit_width = sizeof(int) * 8;
430                                yylval->rvalue.signedness = SIGNED;
431                            } else if (value >= LONG_MIN && value <= LONG_MAX) {
432                                yylval->rvalue.bit_width = sizeof(long) * 8;
433                                yylval->rvalue.signedness = SIGNED;
434                            } else {
435                               g_assert_not_reached();
436                            }
437                            return IMM; }
438 "0x"{HEX_DIGIT}+"ULL"    |
439 {DIGIT}+"ULL"            { yylval->rvalue.type = IMMEDIATE;
440                            yylval->rvalue.bit_width = 64;
441                            yylval->rvalue.signedness = UNSIGNED;
442                            yylval->rvalue.imm.type = VALUE;
443                            yylval->rvalue.imm.value = strtoull(yytext, NULL, 0);
444                            return IMM; }
445 "fLOAD"                  { return LOAD; }
446 "fSTORE"                 { return STORE; }
447 "fROTL"                  { return ROTL; }
448 "fCARRY_FROM_ADD"        { return CARRY_FROM_ADD; }
449 "fADDSAT64"              { return ADDSAT64; }
450 "size"[1248][us]"_t"     { /* Handles "size_t" variants of int types */
451                            const unsigned int bits_per_byte = 8;
452                            const unsigned int bytes = yytext[4] - '0';
453                            yylval->rvalue.bit_width = bits_per_byte * bytes;
454                            if (yytext[5] == 'u') {
455                                yylval->rvalue.signedness = UNSIGNED;
456                            } else {
457                                yylval->rvalue.signedness = SIGNED;
458                            }
459                            return TYPE_SIZE_T; }
460 "unsigned"               { return TYPE_UNSIGNED; }
461 "long"                   { return TYPE_LONG; }
462 "int"                    { return TYPE_INT; }
463 "const"                  { /* Emit no token */ }
464 {VAR_ID}                 { /* Variable name, we adopt the C names convention */
465                            yylval->rvalue.type = VARID;
466                            yylval->rvalue.var.name = g_string_new(yytext);
467                            /* Default to an unknown signedness and 0 width. */
468                            yylval->rvalue.bit_width = 0;
469                            yylval->rvalue.signedness = UNKNOWN_SIGNEDNESS;
470                            return VAR; }
471 "fatal("{STRING_LIT}")"  { /* Emit no token */ }
472 "fHINTJR(RsV)"           { /* Emit no token */ }
473 .                        { return yytext[0]; }
474 
475 %%
476