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