123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- #if __STDC__
- #include <stdarg.h>
- extern out(char *, ...);
- extern error(char *, ...);
- #else
- #include <varargs.h>
- #endif
- #include "decl.h"
- /* All the functions in this file will be called by the parser.
- */
- extern char *strindex();
- static struct Op_info { char *name, *type; }
- op_info[ MAX_OPERANDS] = { { 0, 0}};
- static int n_ops = 0; /* Number of opertands of current
- * assembly instruction.
- */
- static char *assem_instr = 0; /* Name of the current assembly instr */
- static Bool restriction = FALSE; /* Is there a restriction on the
- * current operand?
- */
- File *outfile;
- save_instr( instr, len)
- char *instr;
- int len;
- {
- assem_instr = Salloc( instr, len + 1);
- }
- save_name( name, len)
- char *name;
- int len;
- {
- op_info[ n_ops].name = Salloc( name, len + 1);
- }
- save_type( type, len)
- char *type;
- int len;
- {
- op_info[ n_ops].type = Salloc( type, len + 1);
- restriction = TRUE;
- }
- pr_header()
- {
- out( "%s_instr", assem_instr);
- param_list();
- out( "{\n");
- save_mnem( assem_instr);
- }
- param_list()
- {
- int i;
- out( "(");
- if ( n_ops > 0) {
- out( " %s", op_info[0].name);
- for ( i = 1; i < n_ops; i++)
- out( ", %s", op_info[i].name);
- }
- out( ")\n");
- if ( n_ops > 0) {
- out( "struct t_operand *%s", op_info[0].name);
- for ( i = 1; i < n_ops; i++)
- out( ", *%s", op_info[i].name);
- out( ";\n");
- }
- }
- pr_restriction()
- {
- int i;
- Bool more = FALSE;
- if ( !restriction)
- return;
- out( "if ( ");
- for ( i = 0; i < n_ops; i++)
- if ( op_info[i].type != 0) {
- if ( more)
- out( " &&");
- out( " %s( %s)", op_info[i].type, op_info[i].name);
- more = TRUE;
- }
- out( ") ");
- }
- pr_warning()
- {
- if ( restriction)
- out( "else\nerror( \"No match for %s\");\n", assem_instr);
- restriction = FALSE;
- }
- clear_restriction()
- {
- restriction = FALSE;
- }
- char *skip_string( str)
- char *str;
- /* returns position after the first '"'-charcter, look out for '\' escape
- * sequence
- */
- {
- for ( str++; *str != '"' || *(str-1) == '\\'; str++);
- return( str + 1);
- }
- pr_subroutine( str)
- char *str;
- {
- out( "%s;\n", str);
- }
- #include <ctype.h>
- pr_call( str)
- char *str;
- /* Ouput 'str', but keep track of the number of bytes and take care of
- * conversions like %$.
- */
- {
- if ( strncmp( "text", str, 4) == 0 && isdigit( *(str+4)))
- out( "cur_pos += %d;\n", *(str+4) - '0');
- else if ( strncmp( "reloc", str, 5) == 0 && isdigit( *(str+5)))
- out( "cur_pos += %d;\n", *(str+5) - '0');
- pr_text_with_conversions( str);
- out( "fprint( outfile, \";\");");
- }
- pr_end()
- {
- out( "fprint( outfile, \"}\\n\");");
- }
- pr_els()
- {
- out( "fprint( outfile, \"else\\n\");");
- }
- pr_else()
- {
- out( "fprint( outfile, \"else {\\n\");");
- }
- pr_question( quest)
- char *quest;
- {
- out( "fprint( outfile, \"if\");");
- pr_text_with_conversions( quest);
- out( "fprint( outfile, \"{\\n\");");
- }
- init_table()
- {
- outfile = STDOUT;
- out( "#include \"as.h\"\n");
- out( "#include \"as_parser.h\"\n");
- }
- clean()
- /* Free space, allocated during the parsing of an entry in 'as_table'.
- */
- {
- int i;
- if ( assem_instr != 0) {
- free( assem_instr);
- assem_instr = 0;
- }
- for ( i = 0; i < n_ops; i++) {
- free( op_info[i].name);
- op_info[i].name = 0;
- if ( op_info[i].type != 0) {
- free( op_info[i].type);
- op_info[i].type = 0;
- }
- }
- n_ops = 0;
- }
- operand_clean()
- /* Free space for the operands */
- {
- int i;
- for ( i = 0; i < n_ops; i++) {
- free( op_info[i].name);
- op_info[i].name = 0;
- if ( op_info[i].type != 0) {
- free( op_info[i].type);
- op_info[i].type = 0;
- }
- }
- n_ops = 0;
- }
- #if __STDC__
- /*VARARGS*/
- out(char *fmt, ...)
- {
- va_list pvar;
- va_start(pvar, fmt);
- doprnt( outfile, fmt, pvar);
- va_end(pvar);
- }
- extern int nerrors;
- /*VARARGS*/
- error(char *fmt, ...)
- {
- va_list pvar;
- nerrors++;
- va_start(pvar, fmt);
- fprint( STDERR, "!! ERROR : ");
- doprnt( STDERR, fmt, pvar);
- fprint( STDERR, " !!\n");
- va_end(pvar);
- }
- #else
- /*VARARGS*/
- out(va_alist)
- va_dcl
- {
- va_list pvar;
- char *fmt;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
- doprnt( outfile, fmt, pvar);
- va_end(pvar);
- }
- extern int nerrors;
- /*VARARGS*/
- error(va_alist)
- va_dcl
- {
- char *fmt;
- va_list pvar;
- nerrors++;
- va_start(pvar);
- fmt = va_arg(pvar, char *);
- fprint( STDERR, "!! ERROR : ");
- doprnt( STDERR, fmt, pvar);
- fprint( STDERR, " !!\n");
- va_end(pvar);
- }
- #endif
- inc_ops()
- {
- n_ops++;
- }
- /**********************************/
- char *mnemonic[ MAX_MNEMONICS];
- int n_mnems = 0;
- save_mnem( mnem)
- char *mnem;
- {
- if ( n_mnems == MAX_MNEMONICS)
- error( "too many assembler instructions!! MAX_MNEMONICS = %d",
- MAX_MNEMONICS);
- else
- mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
- }
- end_table()
- /* Flush information in the array 'mnemonic'
- */
- {
- int i;
- quicksort( 0, n_mnems - 1);
-
- out( "char *mnemonic[] = {\n");
- for ( i = 0; i < n_mnems - 1; i++)
- out( "\t\"%s\",\n", mnemonic[i]);
- out( "\t\"%s\"};\n\n", mnemonic[ n_mnems-1]);
- out( "int (*instruction[])() = {\n");
- for ( i = 0; i < n_mnems - 1; i++)
- out( "\t%s_instr,\n", mnemonic[i]);
- out( "\t%s_instr};\n\n", mnemonic[ n_mnems-1]);
- out( "int n_mnems = %d;\n", n_mnems);
- }
- quicksort( lower, upper)
- int lower, upper;
- /* Sort the array 'mnemonic'.
- */
- {
- char *key, *tmp;
- int index1, index2;
- if ( lower >= upper)
- return;
- key = mnemonic[lower];
- index1 = lower;
- index2 = upper+1;
- while ( index1 < index2) {
- do
- index1++;
- while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
- do
- index2--;
- while ( strcmp( mnemonic[index2], key) > 0);
- if ( index1 < index2) {
- tmp = mnemonic[index2];
- mnemonic[index2] = mnemonic[index1];
- mnemonic[index1] = tmp;
- }
- }
- mnemonic[lower] = mnemonic[index2];
- mnemonic[index2] = key;
- quicksort( lower, index2-1);
- quicksort( index2+1, upper);
- }
|