Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / scsi / aic7xxx / aicasm / aicasm_scan.l
diff --git a/kernel/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/kernel/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
new file mode 100644 (file)
index 0000000..93c8667
--- /dev/null
@@ -0,0 +1,622 @@
+%{
+/*
+ * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
+ *
+ * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
+ * Copyright (c) 2001, 2002 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <inttypes.h>
+#include <limits.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysexits.h>
+#ifdef __linux__
+#include "../queue.h"
+#else
+#include <sys/queue.h>
+#endif
+
+#include "aicasm.h"
+#include "aicasm_symbol.h"
+#include "aicasm_gram.h"
+
+/* This is used for macro body capture too, so err on the large size. */
+#define MAX_STR_CONST 4096
+static char string_buf[MAX_STR_CONST];
+static char *string_buf_ptr;
+static int  parren_count;
+static int  quote_count;
+static char buf[255];
+%}
+
+PATH           ([/]*[-A-Za-z0-9_.])+
+WORD           [A-Za-z_][-A-Za-z_0-9]*
+SPACE          [ \t]+
+MCARG          [^(), \t]+
+MBODY          ((\\[^\n])*[^\n\\]*)+
+
+%x COMMENT
+%x CEXPR
+%x INCLUDE
+%x STRING
+%x MACRODEF
+%x MACROARGLIST
+%x MACROCALLARGS
+%x MACROBODY
+
+%%
+\n                     { ++yylineno; }
+\r                     ;
+"/*"                   { BEGIN COMMENT;  /* Enter comment eating state */ }
+<COMMENT>"/*"          { fprintf(stderr, "Warning! Comment within comment."); }
+<COMMENT>\n            { ++yylineno; }
+<COMMENT>[^*/\n]*      ;
+<COMMENT>"*"+[^*/\n]*  ;
+<COMMENT>"/"+[^*/\n]*  ;
+<COMMENT>"*"+"/"       { BEGIN INITIAL; }
+if[ \t]*\(             {
+                               string_buf_ptr = string_buf;
+                               parren_count = 1;
+                               BEGIN CEXPR;
+                               return T_IF;
+                       }
+<CEXPR>\(              {       *string_buf_ptr++ = '('; parren_count++; }
+<CEXPR>\)              {
+                               parren_count--;
+                               if (parren_count == 0) {
+                                       /* All done */
+                                       BEGIN INITIAL;
+                                       *string_buf_ptr = '\0';
+                                       yylval.sym = symtable_get(string_buf);
+                                       return T_CEXPR;
+                               } else {
+                                       *string_buf_ptr++ = ')';
+                               }
+                       }
+<CEXPR>\n              { ++yylineno; }
+<CEXPR>\r              ;
+<CEXPR>[^()\n]+        {
+                               char *yptr;
+
+                               yptr = yytext;
+                               while (*yptr != '\0') {
+                                       /* Remove duplicate spaces */
+                                       if (*yptr == '\t')
+                                               *yptr = ' ';
+                                       if (*yptr == ' '
+                                        && string_buf_ptr != string_buf
+                                        && string_buf_ptr[-1] == ' ')
+                                               yptr++;
+                                       else 
+                                               *string_buf_ptr++ = *yptr++;
+                               }
+                       }
+else                   { return T_ELSE; }
+VERSION                        { return T_VERSION; }
+PREFIX                 { return T_PREFIX; }
+PATCH_ARG_LIST         { return T_PATCH_ARG_LIST; }
+\"                     {
+                               string_buf_ptr = string_buf;
+                               BEGIN STRING;
+                       }
+<STRING>[^"]+          {
+                               char *yptr;
+
+                               yptr = yytext;
+                               while (*yptr)
+                                       *string_buf_ptr++ = *yptr++;
+                       }
+<STRING>\"             {
+                               /* All done */
+                               BEGIN INITIAL;
+                               *string_buf_ptr = '\0';
+                               yylval.str = string_buf;
+                               return T_STRING;
+                       }
+{SPACE}                         ;
+
+       /* Register/SCB/SRAM definition keywords */
+export                 { return T_EXPORT; }
+register               { return T_REGISTER; }
+const                  { yylval.value = FALSE; return T_CONST; }
+download               { return T_DOWNLOAD; }
+address                        { return T_ADDRESS; }
+count                  { return T_COUNT; }
+access_mode            { return T_ACCESS_MODE; }
+dont_generate_debug_code { return T_DONT_GENERATE_DEBUG_CODE; }
+modes                  { return T_MODES; }
+RW|RO|WO               {
+                                if (strcmp(yytext, "RW") == 0)
+                                       yylval.value = RW;
+                                else if (strcmp(yytext, "RO") == 0)
+                                       yylval.value = RO;
+                                else
+                                       yylval.value = WO;
+                                return T_MODE;
+                       }
+field                  { return T_FIELD; }
+enum                   { return T_ENUM; }
+mask                   { return T_MASK; }
+alias                  { return T_ALIAS; }
+size                   { return T_SIZE; }
+scb                    { return T_SCB; }
+scratch_ram            { return T_SRAM; }
+accumulator            { return T_ACCUM; }
+mode_pointer           { return T_MODE_PTR; }
+allones                        { return T_ALLONES; }
+allzeros               { return T_ALLZEROS; }
+none                   { return T_NONE; }
+sindex                 { return T_SINDEX; }
+A                      { return T_A; }
+
+       /* Instruction Formatting */
+PAD_PAGE               { return T_PAD_PAGE; }
+BEGIN_CRITICAL         { return T_BEGIN_CS; }
+END_CRITICAL           { return T_END_CS; }
+SET_SRC_MODE           { return T_SET_SRC_MODE; }
+SET_DST_MODE           { return T_SET_DST_MODE; }
+
+       /* Opcodes */
+shl                    { return T_SHL; }
+shr                    { return T_SHR; }
+ror                    { return T_ROR; }
+rol                    { return T_ROL; }
+mvi                    { return T_MVI; }
+mov                    { return T_MOV; }
+clr                    { return T_CLR; }
+jmp                    { return T_JMP; }
+jc                     { return T_JC;  }
+jnc                    { return T_JNC; }
+je                     { return T_JE;  }
+jne                    { return T_JNE; }
+jz                     { return T_JZ;  }
+jnz                    { return T_JNZ; }
+call                   { return T_CALL; }
+add                    { return T_ADD; }
+adc                    { return T_ADC; }
+bmov                   { return T_BMOV; }
+inc                    { return T_INC; }
+dec                    { return T_DEC; }
+stc                    { return T_STC; }
+clc                    { return T_CLC; }
+cmp                    { return T_CMP; }
+not                    { return T_NOT; }
+xor                    { return T_XOR; }
+test                   { return T_TEST;}
+and                    { return T_AND; }
+or                     { return T_OR;  }
+ret                    { return T_RET; }
+nop                    { return T_NOP; }
+
+       /* ARP2 16bit extensions */
+       /* or16                 { return T_OR16; } */
+       /* and16                        { return T_AND16; }*/
+       /* xor16                        { return T_XOR16; }*/
+       /* add16                        { return T_ADD16; }*/
+       /* adc16                        { return T_ADC16; }*/
+       /* mvi16                        { return T_MVI16; }*/
+       /* test16                       { return T_TEST16; }*/
+       /* cmp16                        { return T_CMP16; }*/
+       /* cmpxchg                      { return T_CMPXCHG; }*/
+
+       /* Allowed Symbols */
+\<\<                   { return T_EXPR_LSHIFT; }
+\>\>                   { return T_EXPR_RSHIFT; }
+[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
+
+       /* Number processing */
+0[0-7]*                        {
+                               yylval.value = strtol(yytext, NULL, 8);
+                               return T_NUMBER;
+                       }
+
+0[xX][0-9a-fA-F]+      {
+                               yylval.value = strtoul(yytext + 2, NULL, 16);
+                               return T_NUMBER;
+                       }
+
+[1-9][0-9]*            {
+                               yylval.value = strtol(yytext, NULL, 10);
+                               return T_NUMBER;
+                       }
+       /* Include Files */
+#include{SPACE}                {
+                               BEGIN INCLUDE;
+                               quote_count = 0;
+                               return T_INCLUDE;
+                       }
+<INCLUDE>[<]           { return yytext[0]; }
+<INCLUDE>[>]           { BEGIN INITIAL; return yytext[0]; }
+<INCLUDE>[\"]          {
+                               if (quote_count != 0)
+                                       BEGIN INITIAL;
+                               quote_count++;
+                               return yytext[0];
+                       }
+<INCLUDE>{PATH}                {
+                               char *yptr;
+
+                               yptr = yytext;
+                               string_buf_ptr = string_buf;
+                               while (*yptr)
+                                       *string_buf_ptr++ = *yptr++;
+                               yylval.str = string_buf;
+                               *string_buf_ptr = '\0';
+                               return T_PATH;
+                       }
+<INCLUDE>.             { stop("Invalid include line", EX_DATAERR); }
+#define{SPACE}         {
+                               BEGIN MACRODEF;
+                               return T_DEFINE;
+                       }
+<MACRODEF>{WORD}{SPACE}        { 
+                               char *yptr;
+
+                               /* Strip space and return as a normal symbol */
+                               yptr = yytext;
+                               while (*yptr != ' ' && *yptr != '\t')
+                                       yptr++;
+                               *yptr = '\0';
+                               yylval.sym = symtable_get(yytext);
+                               string_buf_ptr = string_buf;
+                               BEGIN MACROBODY;
+                               return T_SYMBOL;
+                       }
+<MACRODEF>{WORD}\(     {
+                               /*
+                                * We store the symbol with its opening
+                                * parren so we can differentiate macros
+                                * that take args from macros with the
+                                * same name that do not take args as
+                                * is allowed in C.
+                                */
+                               BEGIN MACROARGLIST;
+                               yylval.sym = symtable_get(yytext);
+                               unput('(');
+                               return T_SYMBOL;
+                       }
+<MACROARGLIST>{WORD}   {
+                               yylval.str = yytext;
+                               return T_ARG;
+                       }
+<MACROARGLIST>{SPACE}   ;
+<MACROARGLIST>[(,]     {
+                               return yytext[0];
+                       }
+<MACROARGLIST>[)]      {
+                               string_buf_ptr = string_buf;
+                               BEGIN MACROBODY;
+                               return ')';
+                       }
+<MACROARGLIST>.                {
+                               snprintf(buf, sizeof(buf), "Invalid character "
+                                        "'%c' in macro argument list",
+                                        yytext[0]);
+                               stop(buf, EX_DATAERR);
+                       }
+<MACROCALLARGS>{SPACE}  ;
+<MACROCALLARGS>\(      {
+                               parren_count++;
+                               if (parren_count == 1)
+                                       return ('(');
+                               *string_buf_ptr++ = '(';
+                       }
+<MACROCALLARGS>\)      {
+                               parren_count--;
+                               if (parren_count == 0) {
+                                       BEGIN INITIAL;
+                                       return (')');
+                               }
+                               *string_buf_ptr++ = ')';
+                       }
+<MACROCALLARGS>{MCARG} {
+                               char *yptr;
+
+                               yptr = yytext;
+                               while (*yptr)
+                                       *string_buf_ptr++ = *yptr++;
+                       }
+<MACROCALLARGS>\,      {
+                               if (string_buf_ptr != string_buf) {
+                                       /*
+                                        * Return an argument and
+                                        * rescan this comma so we
+                                        * can return it as well.
+                                        */
+                                       *string_buf_ptr = '\0';
+                                       yylval.str = string_buf;
+                                       string_buf_ptr = string_buf;
+                                       unput(',');
+                                       return T_ARG;
+                               }
+                               return ',';
+                       }
+<MACROBODY>\\\n                {
+                               /* Eat escaped newlines. */
+                               ++yylineno;
+                       }
+<MACROBODY>\r          ;
+<MACROBODY>\n          {
+                               /* Macros end on the first unescaped newline. */
+                               BEGIN INITIAL;
+                               *string_buf_ptr = '\0';
+                               yylval.str = string_buf;
+                               ++yylineno;
+                               return T_MACROBODY;
+                       }
+<MACROBODY>{MBODY}     {
+                               char *yptr;
+                               char c;
+
+                               yptr = yytext;
+                               while (c = *yptr++) {
+                                       /*
+                                        * Strip carriage returns.
+                                        */
+                                       if (c == '\r')
+                                               continue;
+                                       *string_buf_ptr++ = c;
+                               }
+                       }
+{WORD}\(               {
+                               char *yptr;
+                               char *ycopy;
+
+                               /* May be a symbol or a macro invocation. */
+                               yylval.sym = symtable_get(yytext);
+                               if (yylval.sym->type == MACRO) {
+                                       YY_BUFFER_STATE old_state;
+                                       YY_BUFFER_STATE temp_state;
+
+                                       ycopy = strdup(yytext);
+                                       yptr = ycopy + yyleng;
+                                       while (yptr > ycopy)
+                                               unput(*--yptr);
+                                       old_state = YY_CURRENT_BUFFER;
+                                       temp_state =
+                                           yy_create_buffer(stdin,
+                                                            YY_BUF_SIZE);
+                                       yy_switch_to_buffer(temp_state);
+                                       mm_switch_to_buffer(old_state);
+                                       mmparse();
+                                       mm_switch_to_buffer(temp_state);
+                                       yy_switch_to_buffer(old_state);
+                                       mm_delete_buffer(temp_state);
+                                       expand_macro(yylval.sym);
+                               } else {
+                                       if (yylval.sym->type == UNINITIALIZED) {
+                                               /* Try without the '(' */
+                                               symbol_delete(yylval.sym);
+                                               yytext[yyleng-1] = '\0';
+                                               yylval.sym =
+                                                   symtable_get(yytext);
+                                       }
+                                       unput('(');
+                                       return T_SYMBOL;
+                               }
+                       }
+{WORD}                 {
+                               yylval.sym = symtable_get(yytext);
+                               if (yylval.sym->type == MACRO) {
+                                       expand_macro(yylval.sym);
+                               } else {
+                                       return T_SYMBOL;
+                               }
+                       }
+.                      { 
+                               snprintf(buf, sizeof(buf), "Invalid character "
+                                        "'%c'", yytext[0]);
+                               stop(buf, EX_DATAERR);
+                       }
+%%
+
+typedef struct include {
+        YY_BUFFER_STATE  buffer;
+        int              lineno;
+        char            *filename;
+       SLIST_ENTRY(include) links;
+}include_t;
+
+SLIST_HEAD(, include) include_stack;
+
+void
+include_file(char *file_name, include_type type)
+{
+       FILE *newfile;
+       include_t *include;
+
+       newfile = NULL;
+       /* Try the current directory first */
+       if (includes_search_curdir != 0 || type == SOURCE_FILE)
+               newfile = fopen(file_name, "r");
+
+       if (newfile == NULL && type != SOURCE_FILE) {
+                path_entry_t include_dir;
+                for (include_dir = search_path.slh_first;
+                     include_dir != NULL;                
+                     include_dir = include_dir->links.sle_next) {
+                       char fullname[PATH_MAX];
+
+                       if ((include_dir->quoted_includes_only == TRUE)
+                        && (type != QUOTED_INCLUDE))
+                               continue;
+
+                       snprintf(fullname, sizeof(fullname),
+                                "%s/%s", include_dir->directory, file_name);
+
+                       if ((newfile = fopen(fullname, "r")) != NULL)
+                               break;
+                }
+        }
+
+       if (newfile == NULL) {
+               perror(file_name);
+               stop("Unable to open input file", EX_SOFTWARE);
+               /* NOTREACHED */
+       }
+
+       if (type != SOURCE_FILE) {
+               include = (include_t *)malloc(sizeof(include_t));
+               if (include == NULL) {
+                       stop("Unable to allocate include stack entry",
+                            EX_SOFTWARE);
+                       /* NOTREACHED */
+               }
+               include->buffer = YY_CURRENT_BUFFER;
+               include->lineno = yylineno;
+               include->filename = yyfilename;
+               SLIST_INSERT_HEAD(&include_stack, include, links);
+       }
+       yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
+       yylineno = 1;
+       yyfilename = strdup(file_name);
+}
+
+static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
+                             const char **next_match,
+                             struct macro_arg **match_marg, regmatch_t *match);
+
+void
+expand_macro(struct symbol *macro_symbol)
+{
+       struct macro_arg *marg;
+       struct macro_arg *match_marg;
+       const char *body_head;
+       const char *body_pos;
+       const char *next_match;
+
+       /*
+        * Due to the nature of unput, we must work
+        * backwards through the macro body performing
+        * any expansions.
+        */
+       body_head = macro_symbol->info.macroinfo->body;
+       body_pos = body_head + strlen(body_head);
+       while (body_pos > body_head) {
+               regmatch_t match;
+
+               next_match = body_head;
+               match_marg = NULL;
+               next_substitution(macro_symbol, body_pos, &next_match,
+                                 &match_marg, &match);
+
+               /* Put back everything up until the replacement. */
+               while (body_pos > next_match)
+                       unput(*--body_pos);
+
+               /* Perform the replacement. */
+               if (match_marg != NULL) {
+                       const char *strp;
+
+                       next_match = match_marg->replacement_text;
+                       strp = next_match + strlen(next_match);
+                       while (strp > next_match)
+                               unput(*--strp);
+
+                       /* Skip past the unexpanded macro arg. */
+                       body_pos -= match.rm_eo - match.rm_so;
+               }
+       }
+
+       /* Cleanup replacement text. */
+       STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
+               free(marg->replacement_text);
+       }
+}
+
+/*
+ * Find the next substitution in the macro working backwards from
+ * body_pos until the beginning of the macro buffer.  next_match
+ * should be initialized to the beginning of the macro buffer prior
+ * to calling this routine.
+ */
+static void
+next_substitution(struct symbol *mac_symbol, const char *body_pos,
+                 const char **next_match, struct macro_arg **match_marg,
+                 regmatch_t *match)
+{
+       regmatch_t        matches[2];
+       struct macro_arg *marg;
+       const char       *search_pos;
+       int               retval;
+
+       do {
+               search_pos = *next_match;
+
+               STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
+
+                       retval = regexec(&marg->arg_regex, search_pos, 2,
+                                        matches, 0);
+                       if (retval == 0
+                        && (matches[1].rm_eo + search_pos) <= body_pos
+                        && (matches[1].rm_eo + search_pos) > *next_match) {
+                               *match = matches[1];
+                               *next_match = match->rm_eo + search_pos;
+                               *match_marg = marg;
+                       }
+               }
+       } while (search_pos != *next_match);
+}
+
+int
+yywrap()
+{
+       include_t *include;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER);
+       (void)fclose(yyin);
+       if (yyfilename != NULL)
+               free(yyfilename);
+       yyfilename = NULL;
+       include = include_stack.slh_first;
+       if (include != NULL) {
+               yy_switch_to_buffer(include->buffer);
+               yylineno = include->lineno;
+               yyfilename = include->filename;
+               SLIST_REMOVE_HEAD(&include_stack, links);
+               free(include);
+               return (0);
+       }
+       return (1);
+}