bfin-lex.l revision 1.1.1.5
1/* bfin-lex.l  ADI Blackfin lexer
2   Copyright (C) 2005-2016 Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   GAS is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GAS; see the file COPYING.  If not, write to the Free
18   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19   02110-1301, USA.  */
20%{
21
22#include "as.h"
23#include "bfin-defs.h"
24#include "bfin-parse.h"
25
26static long parse_int (char **end);
27static int parse_halfreg (Register *r, int cl, char *hr);
28static int parse_reg (Register *r, int type, char *rt);
29int yylex (void);
30
31#define _REG yylval.reg
32
33
34%}
35
36/* Define Start States ... Actually we will use exclusion.
37   If no start state is specified it should match any state
38   and <INITIAL> would match some keyword rules only with
39   initial.  */
40%s KEYWORD
41%s FLAGS
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<FLAGS>[zZ]                             return Z;
51<FLAGS>[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<FLAGS>[tT]                             yylval.value = M_T; return MMOD;
62<FLAGS>[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<FLAGS>[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[pP]           return BYTEOP2P;
193[bB][yY][tT][eE][oO][pP]1[pP]           return BYTEOP1P;
194[bB][yY]                                return BY;
195[bB][xX][oO][rR][sS][hH][iI][fF][tT]    return BXORSHIFT;
196[bB][xX][oO][rR]                        return BXOR;
197
198[bB][rR][eE][vV]                        return BREV;
199[bB][pP]                                return BP;
200[bB][iI][tT][tT][sS][tT]                return BITTST;
201[bB][iI][tT][tT][gG][lL]                return BITTGL;
202[bB][iI][tT][sS][eE][tT]                return BITSET;
203[bB][iI][tT][mM][uU][xX]                return BITMUX;
204[bB][iI][tT][cC][lL][rR]                return BITCLR;
205[bB][0-3]"."[lLhH]  return parse_halfreg (&yylval.reg, T_REG_B, yytext);
206[bB][0-3]           return parse_reg (&yylval.reg, T_REG_B, yytext);
207[bB]                                    return B;
208[aA][zZ]  _REG.regno = S_AZ;   return STATUS_REG;
209[aA][nN]  _REG.regno = S_AN;   return STATUS_REG;
210[aA][cC]0_[cC][oO][pP][yY]  _REG.regno = S_AC0_COPY; return STATUS_REG;
211[vV]_[cC][oO][pP][yY]       _REG.regno = S_V_COPY;   return STATUS_REG;
212[aA][qQ]  _REG.regno = S_AQ;   return STATUS_REG;
213[aA][cC]0 _REG.regno = S_AC0;  return STATUS_REG;
214[aA][cC]1 _REG.regno = S_AC1;  return STATUS_REG;
215[aA][vV]0 _REG.regno = S_AV0;  return STATUS_REG;
216[aA][vV]0[sS] _REG.regno = S_AV0S; return STATUS_REG;
217[aA][vV]1 _REG.regno = S_AV1;  return STATUS_REG;
218[aA][vV]1[sS] _REG.regno = S_AV1S; return STATUS_REG;
219[vV][sS]  _REG.regno = S_VS;   return STATUS_REG;
220[rR][nN][dD]_[mM][oO][dD]  _REG.regno = S_RND_MOD; return STATUS_REG;
221
222
223[aA][sS][tT][aA][tT]   _REG.regno = REG_ASTAT; return REG;
224[aA][sS][hH][iI][fF][tT]                return ASHIFT;
225[aA][sS][lL]                            return ASL;
226[aA][sS][rR]                            return ASR;
227[aA][lL][iI][gG][nN]8                   return ALIGN8;
228[aA][lL][iI][gG][nN]16                  return ALIGN16;
229[aA][lL][iI][gG][nN]24                  return ALIGN24;
230[aA]1"."[lL]    return A_ONE_DOT_L;
231[aA]0"."[lL]    return A_ZERO_DOT_L;
232[aA]1"."[hH]    return A_ONE_DOT_H;
233[aA]0"."[hH]    return A_ZERO_DOT_H;
234[aA][bB][sS]                            return ABS;
235[aA][bB][oO][rR][tT]                    return ABORT;
236[aA]1"."[xX]    _REG.regno = REG_A1x; return REG;
237[aA]1"."[wW]    _REG.regno = REG_A1w; return REG;
238[aA]1           _REG.regno = REG_A1;  return REG_A_DOUBLE_ONE;
239[aA]0"."[xX]    _REG.regno = REG_A0x; return REG;
240[aA]0"."[wW]    _REG.regno = REG_A0w; return REG;
241[aA]0           _REG.regno = REG_A0;  return REG_A_DOUBLE_ZERO;
242[Gg][Oo][Tt]	return GOT;
243[Gg][Oo][Tt]"17"[Mm]"4" return GOT17M4;
244[Ff][Uu][Nn][Cc][Dd][Ee][Ss][Cc]"_"[Gg][Oo][Tt]"17"[Mm]"4" return FUNCDESC_GOT17M4;
245[Pp][Ll][Tt][Pp][Cc]	return PLTPC;
246
247
248"~"                     return TILDA;
249"|="                    return _BAR_ASSIGN;
250"|"                     return BAR;
251"^="                    return _CARET_ASSIGN;
252"^"                     return CARET;
253"]"                     return RBRACK;
254"["                     return LBRACK;
255">>>="                  return _GREATER_GREATER_GREATER_THAN_ASSIGN;
256">>="                   return _GREATER_GREATER_ASSIGN;
257">>>"                   return _GREATER_GREATER_GREATER;
258">>"                    return GREATER_GREATER;
259"=="                    return _ASSIGN_ASSIGN;
260"="                     return ASSIGN;
261"<="                    return _LESS_THAN_ASSIGN;
262"<<="                   return _LESS_LESS_ASSIGN;
263"<<"                    return LESS_LESS;
264"<"                     return LESS_THAN;
265"("                     BEGIN(FLAGS); return LPAREN;
266")"                     BEGIN(INITIAL); return RPAREN;
267":"                     return COLON;
268"/"                     return SLASH;
269"-="                    return _MINUS_ASSIGN;
270"+|+"					return _PLUS_BAR_PLUS;
271"-|+"					return _MINUS_BAR_PLUS;
272"+|-"					return _PLUS_BAR_MINUS;
273"-|-"					return _MINUS_BAR_MINUS;
274"--"                    return _MINUS_MINUS;
275"-"                     return MINUS;
276","                     return COMMA;
277"+="                    return _PLUS_ASSIGN;
278"++"                    return _PLUS_PLUS;
279"+"                     return PLUS;
280"*="                    return _STAR_ASSIGN;
281"*"                     return STAR;
282"&="                    return _AMPERSAND_ASSIGN;
283"&"                     return AMPERSAND;
284"%"                     return PERCENT;
285"!"                     return BANG;
286";"                     return SEMICOLON;
287"=!"			return _ASSIGN_BANG;
288"||"			return DOUBLE_BAR;
289"@"			return AT;
290<KEYWORD>[pP][rR][eE][fF][eE][tT][cC][hH]        return PREFETCH;
291<KEYWORD>[uU][nN][lL][iI][nN][kK]                return UNLINK;
292<KEYWORD>[lL][iI][nN][kK]                        return LINK;
293<KEYWORD>[iI][dD][lL][eE]                        return IDLE;
294<KEYWORD>[iI][fF][lL][uU][sS][hH]                return IFLUSH;
295<KEYWORD>[fF][lL][uU][sS][hH][iI][nN][vV]        return FLUSHINV;
296<KEYWORD>[fF][lL][uU][sS][hH]                    return FLUSH;
297([0-9]+)|(0[xX][0-9a-fA-F]+)|([bhfodBHOFD]#[0-9a-fA-F]+)|(0"."[0-9]+) {
298    yylval.value = parse_int (&yytext);
299    return NUMBER;
300  }
301[[:alpha:]\x80-\xff_$.][[:alnum:]\x80-\xff_$.]* {
302    yylval.symbol = symbol_find_or_make (yytext);
303    symbol_mark_used (yylval.symbol);
304    return SYMBOL;
305  }
306[0-9][bfBF] {
307    char *name;
308    char *ref = strdup (yytext);
309    if (ref[1] == 'b' || ref[1] == 'B')
310      {
311        name = fb_label_name ((int) (ref[0] - '0'), 0);
312	yylval.symbol = symbol_find (name);
313
314	if ((yylval.symbol != NULL)
315             && (S_IS_DEFINED (yylval.symbol)))
316          return SYMBOL;
317	as_bad ("backward reference to unknown label %d:",
318						  (int) (ref[0] - '0'));
319      }
320    else if (ref[1] == 'f' || ref[1] == 'F')
321      {
322        /* Forward reference.  Expect symbol to be undefined or
323           unknown.  undefined: seen it before.  unknown: never seen
324           it before.
325
326           Construct a local label name, then an undefined symbol.
327           Just return it as never seen before.  */
328
329        name = fb_label_name ((int) (ref[0] - '0'), 1);
330	yylval.symbol = symbol_find_or_make (name);
331	/* We have no need to check symbol properties.  */
332	return SYMBOL;
333      }
334  }
335[ \t\n]                                    ;
336"/*".*"*/"                                 ;
337.                                          return yytext[0];
338%%
339static long parse_int (char **end)
340{
341  char fmt = '\0';
342  int not_done = 1;
343  int shiftvalue = 0;
344  char * char_bag;
345  long value = 0;
346  char *arg = *end;
347
348  while (*arg && *arg == ' ')
349    arg++;
350
351  switch (*arg)
352    {
353      case '1':
354      case '2':
355      case '3':
356      case '4':
357      case '5':
358      case '6':
359      case '7':
360      case '8':
361      case '9':
362        fmt = 'd';
363        break;
364
365      case '0':  /* Accept different formated integers hex octal and binary. */
366        {
367	  char c = *++arg;
368          arg++;
369	  if (c == 'x' || c == 'X') /* Hex input.  */
370	    fmt = 'h';
371	  else if (c == 'b' || c == 'B')
372	    fmt = 'b';
373	  else if (c == '.')
374	    fmt = 'f';
375	  else
376            {             /* Octal.  */
377	      arg--;
378	      fmt = 'o';
379	    }
380	  break;
381        }
382
383      case 'd':
384      case 'D':
385      case 'h':
386      case 'H':
387      case 'o':
388      case 'O':
389      case 'b':
390      case 'B':
391      case 'f':
392      case 'F':
393        {
394	  fmt = *arg++;
395	  if (*arg == '#')
396	    arg++;
397        }
398    }
399
400  switch (fmt)
401    {
402      case 'h':
403      case 'H':
404        shiftvalue = 4;
405        char_bag = "0123456789ABCDEFabcdef";
406        break;
407
408      case 'o':
409      case 'O':
410        shiftvalue = 3;
411        char_bag = "01234567";
412        break;
413
414      case 'b':
415      case 'B':
416        shiftvalue = 1;
417        char_bag = "01";
418        break;
419
420/* The assembler allows for fractional constants to be created
421   by either the 0.xxxx or the f#xxxx format
422
423   i.e.   0.5 would result in 0x4000
424
425   note .5 would result in the identifier .5.
426
427   The assembler converts to fractional format 1.15 by the simple rule:
428
429             value = (short) (finput * (1 << 15)).  */
430
431      case 'f':
432      case 'F':
433        {
434          float fval = 0.0;
435          float pos = 10.0;
436          while (1)
437            {
438              int c;
439              c = *arg++;
440
441              if (c >= '0' && c <= '9')
442                {
443                  float digit = (c - '0') / pos;
444                  fval = fval + digit;
445                  pos = pos * 10.0;
446                }
447              else
448                {
449	          *--arg = c;
450                  value = (short) (fval * (1 << 15));
451                  break;
452                }
453            }
454          *end = arg+1;
455          return value;
456        }
457
458      case 'd':
459      case 'D':
460      default:
461        {
462          while (1)
463            {
464              char c;
465              c = *arg++;
466              if (c >= '0' && c <= '9')
467                value = (value * 10) + (c - '0');
468              else
469                {
470                  /* Constants that are suffixed with k|K are multiplied by 1024
471                     This suffix is only allowed on decimal constants. */
472                  if (c == 'k' || c == 'K')
473                    value *= 1024;
474                  else
475                    *--arg = c;
476                  break;
477                }
478            }
479          *end = arg+1;
480          return value;
481        }
482    }
483
484  while (not_done)
485    {
486      char c;
487      c = *arg++;
488      if (c == 0 || !strchr (char_bag, c))
489	{
490          not_done = 0;
491          *--arg = c;
492        }
493      else
494        {
495          if (c >= 'a' && c <= 'z')
496            c = c - ('a' - '9') + 1;
497          else if (c >= 'A' && c <= 'Z')
498            c = c - ('A' - '9') + 1;
499
500          c -= '0';
501          value = (value << shiftvalue) + c;
502        }
503    }
504  *end = arg+1;
505  return value;
506}
507
508
509static int parse_reg (Register *r, int cl, char *rt)
510{
511  r->regno = cl | (rt[1] - '0');
512  r->flags = F_REG_NONE;
513  return REG;
514}
515
516static int parse_halfreg (Register *r, int cl, char *rt)
517{
518  r->regno = cl | (rt[1] - '0');
519
520  switch (rt[3])
521    {
522      case 'b':
523      case 'B':
524	return BYTE_DREG;
525
526      case 'l':
527      case 'L':
528	r->flags = F_REG_LOW;
529	break;
530
531      case 'h':
532      case 'H':
533	r->flags = F_REG_HIGH;
534	break;
535    }
536
537  return HALF_REG;
538}
539
540/* Our start state is KEYWORD as we have
541   command keywords such as PREFETCH.  */
542
543void
544set_start_state (void)
545{
546  BEGIN KEYWORD;
547}
548
549
550#ifndef yywrap
551int
552yywrap ()
553{
554  return 1;
555}
556#endif
557