]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/bfin-lex.l
gas local label and dollar label handling
[thirdparty/binutils-gdb.git] / gas / config / bfin-lex.l
1 %option noyywrap
2
3 /* bfin-lex.l ADI Blackfin lexer
4 Copyright (C) 2005-2022 Free Software Foundation, Inc.
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22 %{
23 #include "bfin-defs.h"
24 #include "config/bfin-parse.h"
25
26 static long parse_int (char **end);
27 static int parse_halfreg (Register *r, int cl, char *hr);
28 static int parse_reg (Register *r, int type, char *rt);
29 int yylex (void);
30
31 #define _REG yylval.reg
32
33 /* Flex generates static functions "input" & "unput" which are not used. */
34 #define YY_NO_INPUT
35 #define YY_NO_UNPUT
36
37 %}
38
39 /* Define Start States ... Actually we will use exclusion.
40 If no start state is specified it should match any state
41 and <INITIAL> would match some keyword rules only with
42 initial. */
43 %s KEYWORD
44 %s FLAGS
45
46 %%
47 [sS][fF][tT][rR][eE][sS][eE][tT] _REG.regno = REG_sftreset; return REG;
48 [oO][mM][oO][dD][eE] _REG.regno = REG_omode; return REG;
49 [iI][dD][lL][eE]_[rR][eE][qQ] _REG.regno = REG_idle_req; return REG;
50 [hH][wW][eE][rR][rR][cC][aA][uU][sS][eE] _REG.regno = REG_hwerrcause; return REG;
51 [eE][xX][cC][aA][uU][sS][eE] _REG.regno = REG_excause; return REG;
52 [eE][mM][uU][cC][aA][uU][sS][eE] _REG.regno = REG_emucause; return REG;
53 <FLAGS>[zZ] return Z;
54 <FLAGS>[xX] return X;
55 [wW]32 yylval.value = M_W32; return MMOD;
56 [wW] return W;
57 [vV][iI][tT]_[mM][aA][xX] return VIT_MAX;
58 [vV] return V; /* Special: V is a statflag and a modifier. */
59 [uU][sS][pP] _REG.regno = REG_USP; return REG;
60 [tT][lL] return TL;
61 [tT][hH] return TH;
62 [tT][fF][uU] yylval.value = M_TFU; return MMOD;
63 [tT][eE][sS][tT][sS][eE][tT] return TESTSET;
64 <FLAGS>[tT] yylval.value = M_T; return MMOD;
65 <FLAGS>[sS] return S;
66 [sS][yY][sS][cC][fF][gG] _REG.regno = REG_SYSCFG; return REG;
67 [sS][tT][iI] return STI;
68 [sS][sS][yY][nN][cC] return SSYNC;
69 [sS][pP]"."[lL] _REG.regno = REG_SP; _REG.flags = F_REG_LOW; return HALF_REG;
70 [sS][pP]"."[hH] _REG.regno = REG_SP; _REG.flags = F_REG_HIGH; return HALF_REG;
71 [sS][pP] _REG.regno = REG_SP; return REG;
72 [sS][iI][gG][nN][bB][iI][tT][sS] return SIGNBITS;
73 [sS][iI][gG][nN] return SIGN;
74 [sS][eE][qQ][sS][tT][aA][tT] _REG.regno = REG_SEQSTAT; return REG;
75 [sS][eE][aA][rR][cC][hH] return SEARCH;
76 [sS][hH][iI][fF][tT] return SHIFT;
77 [sS][cC][oO] return SCO;
78
79 [sS][aA][aA] return SAA;
80 [sS]2[rR][nN][dD] yylval.value = M_S2RND; return MMOD;
81 [rR][tT][xX] return RTX;
82 [rR][tT][sS] return RTS;
83 [rR][tT][nN] return RTN;
84 [rR][tT][iI] return RTI;
85 [rR][tT][eE] return RTE;
86 [rR][oO][tT] return ROT;
87 [rR][nN][dD]20 return RND20;
88 [rR][nN][dD]12 return RND12;
89 [rR][nN][dD][lL] return RNDL;
90 [rR][nN][dD][hH] return RNDH;
91 [rR][nN][dD] return RND;
92
93 [rR][0-7]"."[lLhHbB] return parse_halfreg(&yylval.reg, T_REG_R, yytext);
94
95 [rR][eE][tT][sS] _REG.regno = REG_RETS; return REG;
96 [rR][eE][tT][iI] _REG.regno = REG_RETI; return REG;
97 [rR][eE][tT][xX] _REG.regno = REG_RETX; return REG;
98 [rR][eE][tT][nN] _REG.regno = REG_RETN; return REG;
99 [rR][eE][tT][eE] _REG.regno = REG_RETE; return REG;
100 [eE][mM][uU][dD][aA][tT] _REG.regno = REG_EMUDAT; return REG;
101 [rR][aA][iI][sS][eE] return RAISE;
102
103 [rR][0-7] return parse_reg (&yylval.reg, T_REG_R, yytext);
104
105 [rR] return R;
106 [pP][rR][nN][tT] return PRNT;
107 [pP][cC] return PC;
108 [pP][aA][cC][kK] return PACK;
109
110 [pP][0-5]"."[lLhH] return parse_halfreg (&yylval.reg, T_REG_P, yytext);
111 [pP][0-5] return parse_reg (&yylval.reg, T_REG_P, yytext);
112
113 [oO][uU][tT][cC] return OUTC;
114 [oO][nN][eE][sS] return ONES;
115
116 [nN][oO][tT] return NOT;
117 [nN][oO][pP] return NOP;
118 [mM][nN][oO][pP] return MNOP;
119 [nN][sS] return NS;
120
121
122 [mM][iI][nN] return MIN;
123 [mM][aA][xX] return MAX;
124
125 [mM][0-3]"."[lLhH] return parse_halfreg (&yylval.reg, T_REG_M, yytext);
126 [mM][0-3] return parse_reg (&yylval.reg, T_REG_M, yytext);
127
128 <FLAGS>[mM] return M;
129 [lL][tT] return LT;
130 [lL][sS][hH][iI][fF][tT] return LSHIFT;
131 [lL][sS][eE][tT][uU][pP] return LSETUP;
132 [lL][oO][oO][pP] return LOOP;
133 [lL][oO][oO][pP]_[bB][eE][gG][iI][nN] return LOOP_BEGIN;
134 [lL][oO][oO][pP]_[eE][nN][dD] return LOOP_END;
135
136 [lL][eE] return LE;
137 [lL][cC]0 _REG.regno = REG_LC0; return REG;
138 [lL][tT]0 _REG.regno = REG_LT0; return REG;
139 [lL][bB]0 _REG.regno = REG_LB0; return REG;
140 [lL][cC]1 _REG.regno = REG_LC1; return REG;
141 [lL][tT]1 _REG.regno = REG_LT1; return REG;
142 [lL][bB]1 _REG.regno = REG_LB1; return REG;
143
144 [lL][0-3]"."[lLhH] return parse_halfreg (&yylval.reg, T_REG_L, yytext);
145 [lL][0-3] return parse_reg (&yylval.reg, T_REG_L, yytext);
146 [lL][oO] return LO;
147 [jJ][uU][mM][pP]"."[sS] { BEGIN 0; return JUMP_DOT_S;}
148 [jJ][uU][mM][pP]"."[lL] { BEGIN 0; return JUMP_DOT_L;}
149 [jJ][uU][mM][pP] { BEGIN 0; return JUMP;}
150 [jJ][uU][mM][pP]"."[xX] { BEGIN 0; return JUMP_DOT_L; }
151 [iI][uU] yylval.value = M_IU; return MMOD;
152 [iI][sS][sS]2 yylval.value = M_ISS2; return MMOD;
153 [iI][sS] yylval.value = M_IS; return MMOD;
154 [iI][hH] yylval.value = M_IH; return MMOD;
155 [iI][fF] return IF;
156 [iI][0-3]"."[lLhH] return parse_halfreg (&yylval.reg, T_REG_I, yytext);
157 [iI][0-3] return parse_reg (&yylval.reg, T_REG_I, yytext);
158 [hH][lL][tT] return HLT;
159 [hH][iI] return HI;
160 [gG][tT] return GT;
161 [gG][eE] return GE;
162 [fF][uU] yylval.value = M_FU; return MMOD;
163 [fF][pP] _REG.regno = REG_FP; return REG;
164 [fF][pP]"."[lL] _REG.regno = REG_FP; _REG.flags = F_REG_LOW; return HALF_REG;
165 [fF][pP]"."[hH] _REG.regno = REG_FP; _REG.flags = F_REG_HIGH; return HALF_REG;
166
167 [eE][xX][tT][rR][aA][cC][tT] return EXTRACT;
168 [eE][xX][pP][aA][dD][jJ] return EXPADJ;
169 [eE][xX][cC][pP][tT] return EXCPT;
170 [eE][mM][uU][eE][xX][cC][pP][tT] return EMUEXCPT;
171 [dD][iI][vV][sS] return DIVS;
172 [dD][iI][vV][qQ] return DIVQ;
173 [dD][iI][sS][aA][lL][gG][nN][eE][xX][cC][pP][tT] return DISALGNEXCPT;
174 [dD][eE][pP][oO][sS][iI][tT] return DEPOSIT;
175 [dD][bB][gG][hH][aA][lL][tT] return DBGHALT;
176 [dD][bB][gG][cC][mM][pP][lL][xX] return DBGCMPLX;
177 [dD][bB][gG][aA][lL] return DBGAL;
178 [dD][bB][gG][aA][hH] return DBGAH;
179 [dD][bB][gG][aA] return DBGA;
180 [dD][bB][gG] return DBG;
181 [cC][yY][cC][lL][eE][sS]2 { _REG.regno = REG_CYCLES2; return REG; }
182 [cC][yY][cC][lL][eE][sS] { _REG.regno = REG_CYCLES; return REG; }
183 [cC][sS][yY][nN][cC] return CSYNC;
184 [cC][oO] return CO;
185 [cC][lL][iI] return CLI;
186
187 [cC][cC] _REG.regno = REG_CC; return CCREG;
188 [cC][aA][lL][lL]"."[xX] { BEGIN 0; return CALL;}
189 [cC][aA][lL][lL] { BEGIN 0; return CALL;}
190 [bB][yY][tT][eE][uU][nN][pP][aA][cC][kK] return BYTEUNPACK;
191 [bB][yY][tT][eE][pP][aA][cC][kK] return BYTEPACK;
192 [bB][yY][tT][eE][oO][pP]16[mM] return BYTEOP16M;
193 [bB][yY][tT][eE][oO][pP]16[pP] return BYTEOP16P;
194 [bB][yY][tT][eE][oO][pP]3[pP] return BYTEOP3P;
195 [bB][yY][tT][eE][oO][pP]2[pP] return BYTEOP2P;
196 [bB][yY][tT][eE][oO][pP]1[pP] return BYTEOP1P;
197 [bB][yY] return BY;
198 [bB][xX][oO][rR][sS][hH][iI][fF][tT] return BXORSHIFT;
199 [bB][xX][oO][rR] return BXOR;
200
201 [bB][rR][eE][vV] return BREV;
202 [bB][pP] return BP;
203 [bB][iI][tT][tT][sS][tT] return BITTST;
204 [bB][iI][tT][tT][gG][lL] return BITTGL;
205 [bB][iI][tT][sS][eE][tT] return BITSET;
206 [bB][iI][tT][mM][uU][xX] return BITMUX;
207 [bB][iI][tT][cC][lL][rR] return BITCLR;
208 [bB][0-3]"."[lLhH] return parse_halfreg (&yylval.reg, T_REG_B, yytext);
209 [bB][0-3] return parse_reg (&yylval.reg, T_REG_B, yytext);
210 [bB] return B;
211 [aA][zZ] _REG.regno = S_AZ; return STATUS_REG;
212 [aA][nN] _REG.regno = S_AN; return STATUS_REG;
213 [aA][cC]0_[cC][oO][pP][yY] _REG.regno = S_AC0_COPY; return STATUS_REG;
214 [vV]_[cC][oO][pP][yY] _REG.regno = S_V_COPY; return STATUS_REG;
215 [aA][qQ] _REG.regno = S_AQ; return STATUS_REG;
216 [aA][cC]0 _REG.regno = S_AC0; return STATUS_REG;
217 [aA][cC]1 _REG.regno = S_AC1; return STATUS_REG;
218 [aA][vV]0 _REG.regno = S_AV0; return STATUS_REG;
219 [aA][vV]0[sS] _REG.regno = S_AV0S; return STATUS_REG;
220 [aA][vV]1 _REG.regno = S_AV1; return STATUS_REG;
221 [aA][vV]1[sS] _REG.regno = S_AV1S; return STATUS_REG;
222 [vV][sS] _REG.regno = S_VS; return STATUS_REG;
223 [rR][nN][dD]_[mM][oO][dD] _REG.regno = S_RND_MOD; return STATUS_REG;
224
225
226 [aA][sS][tT][aA][tT] _REG.regno = REG_ASTAT; return REG;
227 [aA][sS][hH][iI][fF][tT] return ASHIFT;
228 [aA][sS][lL] return ASL;
229 [aA][sS][rR] return ASR;
230 [aA][lL][iI][gG][nN]8 return ALIGN8;
231 [aA][lL][iI][gG][nN]16 return ALIGN16;
232 [aA][lL][iI][gG][nN]24 return ALIGN24;
233 [aA]1"."[lL] return A_ONE_DOT_L;
234 [aA]0"."[lL] return A_ZERO_DOT_L;
235 [aA]1"."[hH] return A_ONE_DOT_H;
236 [aA]0"."[hH] return A_ZERO_DOT_H;
237 [aA][bB][sS] return ABS;
238 [aA][bB][oO][rR][tT] return ABORT;
239 [aA]1"."[xX] _REG.regno = REG_A1x; return REG;
240 [aA]1"."[wW] _REG.regno = REG_A1w; return REG;
241 [aA]1 _REG.regno = REG_A1; return REG_A_DOUBLE_ONE;
242 [aA]0"."[xX] _REG.regno = REG_A0x; return REG;
243 [aA]0"."[wW] _REG.regno = REG_A0w; return REG;
244 [aA]0 _REG.regno = REG_A0; return REG_A_DOUBLE_ZERO;
245 [Gg][Oo][Tt] return GOT;
246 [Gg][Oo][Tt]"17"[Mm]"4" return GOT17M4;
247 [Ff][Uu][Nn][Cc][Dd][Ee][Ss][Cc]"_"[Gg][Oo][Tt]"17"[Mm]"4" return FUNCDESC_GOT17M4;
248 [Pp][Ll][Tt][Pp][Cc] return PLTPC;
249
250
251 "~" return TILDA;
252 "|=" return _BAR_ASSIGN;
253 "|" return BAR;
254 "^=" return _CARET_ASSIGN;
255 "^" return CARET;
256 "]" return RBRACK;
257 "[" return LBRACK;
258 ">>>=" return _GREATER_GREATER_GREATER_THAN_ASSIGN;
259 ">>=" return _GREATER_GREATER_ASSIGN;
260 ">>>" return _GREATER_GREATER_GREATER;
261 ">>" return GREATER_GREATER;
262 "==" return _ASSIGN_ASSIGN;
263 "=" return ASSIGN;
264 "<=" return _LESS_THAN_ASSIGN;
265 "<<=" return _LESS_LESS_ASSIGN;
266 "<<" return LESS_LESS;
267 "<" return LESS_THAN;
268 "(" BEGIN(FLAGS); return LPAREN;
269 ")" BEGIN(INITIAL); return RPAREN;
270 ":" return COLON;
271 "/" return SLASH;
272 "-=" return _MINUS_ASSIGN;
273 "+|+" return _PLUS_BAR_PLUS;
274 "-|+" return _MINUS_BAR_PLUS;
275 "+|-" return _PLUS_BAR_MINUS;
276 "-|-" return _MINUS_BAR_MINUS;
277 "--" return _MINUS_MINUS;
278 "-" return MINUS;
279 "," return COMMA;
280 "+=" return _PLUS_ASSIGN;
281 "++" return _PLUS_PLUS;
282 "+" return PLUS;
283 "*=" return _STAR_ASSIGN;
284 "*" return STAR;
285 "&=" return _AMPERSAND_ASSIGN;
286 "&" return AMPERSAND;
287 "%" return PERCENT;
288 "!" return BANG;
289 ";" return SEMICOLON;
290 "=!" return _ASSIGN_BANG;
291 "||" return DOUBLE_BAR;
292 "@" return AT;
293 <KEYWORD>[pP][rR][eE][fF][eE][tT][cC][hH] return PREFETCH;
294 <KEYWORD>[uU][nN][lL][iI][nN][kK] return UNLINK;
295 <KEYWORD>[lL][iI][nN][kK] return LINK;
296 <KEYWORD>[iI][dD][lL][eE] return IDLE;
297 <KEYWORD>[iI][fF][lL][uU][sS][hH] return IFLUSH;
298 <KEYWORD>[fF][lL][uU][sS][hH][iI][nN][vV] return FLUSHINV;
299 <KEYWORD>[fF][lL][uU][sS][hH] return FLUSH;
300 ([0-9]+)|(0[xX][0-9a-fA-F]+)|([bhfodBHOFD]#[0-9a-fA-F]+)|(0"."[0-9]+) {
301 yylval.value = parse_int (&yytext);
302 return NUMBER;
303 }
304 [[:alpha:]\x80-\xff_$.][[:alnum:]\x80-\xff_$.]* {
305 yylval.symbol = symbol_find_or_make (yytext);
306 symbol_mark_used (yylval.symbol);
307 return SYMBOL;
308 }
309 [0-9][bfBF] {
310 char *name;
311 char *ref = strdup (yytext);
312 if (ref[1] == 'b' || ref[1] == 'B')
313 {
314 name = fb_label_name (ref[0] - '0', 0);
315 yylval.symbol = symbol_find (name);
316
317 if ((yylval.symbol != NULL)
318 && (S_IS_DEFINED (yylval.symbol)))
319 return SYMBOL;
320 as_bad ("backward reference to unknown label %d:",
321 (int) (ref[0] - '0'));
322 }
323 else if (ref[1] == 'f' || ref[1] == 'F')
324 {
325 /* Forward reference. Expect symbol to be undefined or
326 unknown. undefined: seen it before. unknown: never seen
327 it before.
328
329 Construct a local label name, then an undefined symbol.
330 Just return it as never seen before. */
331
332 name = fb_label_name (ref[0] - '0', 1);
333 yylval.symbol = symbol_find_or_make (name);
334 /* We have no need to check symbol properties. */
335 return SYMBOL;
336 }
337 }
338 [ \t\n] ;
339 "/*".*"*/" ;
340 . return yytext[0];
341 %%
342 static long parse_int (char **end)
343 {
344 char fmt = '\0';
345 int not_done = 1;
346 int shiftvalue = 0;
347 const char *char_bag;
348 unsigned long value = 0;
349 char *arg = *end;
350
351 while (*arg && *arg == ' ')
352 arg++;
353
354 switch (*arg)
355 {
356 case '1':
357 case '2':
358 case '3':
359 case '4':
360 case '5':
361 case '6':
362 case '7':
363 case '8':
364 case '9':
365 fmt = 'd';
366 break;
367
368 case '0': /* Accept different formatted integers hex octal and binary. */
369 {
370 char c = *++arg;
371 arg++;
372 if (c == 'x' || c == 'X') /* Hex input. */
373 fmt = 'h';
374 else if (c == 'b' || c == 'B')
375 fmt = 'b';
376 else if (c == '.')
377 fmt = 'f';
378 else
379 { /* Octal. */
380 arg--;
381 fmt = 'o';
382 }
383 break;
384 }
385
386 case 'd':
387 case 'D':
388 case 'h':
389 case 'H':
390 case 'o':
391 case 'O':
392 case 'b':
393 case 'B':
394 case 'f':
395 case 'F':
396 {
397 fmt = *arg++;
398 if (*arg == '#')
399 arg++;
400 }
401 }
402
403 switch (fmt)
404 {
405 case 'h':
406 case 'H':
407 shiftvalue = 4;
408 char_bag = "0123456789ABCDEFabcdef";
409 break;
410
411 case 'o':
412 case 'O':
413 shiftvalue = 3;
414 char_bag = "01234567";
415 break;
416
417 case 'b':
418 case 'B':
419 shiftvalue = 1;
420 char_bag = "01";
421 break;
422
423 /* The assembler allows for fractional constants to be created
424 by either the 0.xxxx or the f#xxxx format
425
426 i.e. 0.5 would result in 0x4000
427
428 note .5 would result in the identifier .5.
429
430 The assembler converts to fractional format 1.15 by the simple rule:
431
432 value = (short) (finput * (1 << 15)). */
433
434 case 'f':
435 case 'F':
436 {
437 float fval = 0.0;
438 float pos = 10.0;
439 while (1)
440 {
441 int c;
442 c = *arg++;
443
444 if (c >= '0' && c <= '9')
445 {
446 float digit = (c - '0') / pos;
447 fval = fval + digit;
448 pos = pos * 10.0;
449 }
450 else
451 {
452 *--arg = c;
453 value = (short) (fval * (1 << 15));
454 break;
455 }
456 }
457 *end = arg+1;
458 return value;
459 }
460
461 case 'd':
462 case 'D':
463 default:
464 {
465 while (1)
466 {
467 char c;
468 c = *arg++;
469 if (c >= '0' && c <= '9')
470 value = (value * 10) + (c - '0');
471 else
472 {
473 /* Constants that are suffixed with k|K are multiplied by 1024
474 This suffix is only allowed on decimal constants. */
475 if (c == 'k' || c == 'K')
476 value *= 1024;
477 else
478 *--arg = c;
479 break;
480 }
481 }
482 *end = arg+1;
483 return value;
484 }
485 }
486
487 while (not_done)
488 {
489 char c;
490 c = *arg++;
491 if (c == 0 || !strchr (char_bag, c))
492 {
493 not_done = 0;
494 *--arg = c;
495 }
496 else
497 {
498 if (c >= 'a' && c <= 'z')
499 c = c - ('a' - '9') + 1;
500 else if (c >= 'A' && c <= 'Z')
501 c = c - ('A' - '9') + 1;
502
503 c -= '0';
504 value = (value << shiftvalue) + c;
505 }
506 }
507 *end = arg+1;
508 return value;
509 }
510
511
512 static int parse_reg (Register *r, int cl, char *rt)
513 {
514 r->regno = cl | (rt[1] - '0');
515 r->flags = F_REG_NONE;
516 return REG;
517 }
518
519 static int parse_halfreg (Register *r, int cl, char *rt)
520 {
521 r->regno = cl | (rt[1] - '0');
522
523 switch (rt[3])
524 {
525 case 'b':
526 case 'B':
527 return BYTE_DREG;
528
529 case 'l':
530 case 'L':
531 r->flags = F_REG_LOW;
532 break;
533
534 case 'h':
535 case 'H':
536 r->flags = F_REG_HIGH;
537 break;
538 }
539
540 return HALF_REG;
541 }
542
543 /* Our start state is KEYWORD as we have
544 command keywords such as PREFETCH. */
545
546 void
547 set_start_state (void)
548 {
549 BEGIN KEYWORD;
550 }