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