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
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/* 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%%
342static 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
512static 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
519static 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
546void
547set_start_state (void)
548{
549  BEGIN KEYWORD;
550}
551