include/
[external/binutils.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