--- /dev/null
+#
+#
+#
+
+# HACK
+PORT = mcs51
+
+# Version
+VERSION = @VERSION@
+VERSIONHI = @VERSIONHI@
+VERSIONLO = @VERSIONLO@
+VERSIONP = @VERSIONP@
+
+# Programs
+SHELL = /bin/sh
+CC = @CC@
+CPP = @CPP@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+YACC = @YACC@
+LEX = @LEX@
+AWK = @AWK@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+datadir = @datadir@
+includedir = @includedir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+infodir = @infodir@
+srcdir = @srcdir@
+
+# Flags
+DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@)
+CPPFLAGS = @CPPFLAGS@ -I$(PRJDIR) -I$(PRJDIR)/support
+CFLAGS = @CFLAGS@ -Wall
+M_OR_MM = @M_OR_MM@
+
+# Shared settings between all the sub Makefiles
+# Done here so that we don't have to start a Make from the top levelport
+# directory.
+
+# Library compilation options
+SCC = $(PRJDIR)/src/sdcc
+SAS = $(PRJDIR)/as/$(PORT)/as
+CLEANSPEC = *.lst *.asm *.sym *~ *.cdb
device/include/Makefile
device/lib/Makefile
debugger/mcs51/Makefile
+Makefile.common:Makefile.common.in
sdccconf.h:sdccconf_in.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
device/include/Makefile
device/lib/Makefile
debugger/mcs51/Makefile
+Makefile.common:Makefile.common.in
"}
EOF
cat >> $CONFIG_STATUS <<\EOF
device/include/Makefile
device/lib/Makefile
debugger/mcs51/Makefile
+Makefile.common:Makefile.common.in
)
# End of configure/configure.in
+++ /dev/null
-sdcdb.o: sdcdb.c sdcdb.h ../../sdccconf.h ../../support/gc/gc.h \
- ../../src/SDCCset.h ../../src/SDCChasht.h ../../src/SDCCbitv.h \
- symtab.h simi.h break.h cmd.h
-symtab.o: symtab.c sdcdb.h ../../sdccconf.h ../../support/gc/gc.h \
- ../../src/SDCCset.h ../../src/SDCChasht.h ../../src/SDCCbitv.h \
- symtab.h
-simi.o: simi.c sdcdb.h ../../sdccconf.h ../../support/gc/gc.h \
- ../../src/SDCCset.h ../../src/SDCChasht.h ../../src/SDCCbitv.h simi.h
-SDCCset.o: ../../src/SDCCset.c ../../src/SDCCset.h \
- ../../support/gc/gc.h
-break.o: break.c sdcdb.h ../../sdccconf.h ../../support/gc/gc.h \
- ../../src/SDCCset.h ../../src/SDCChasht.h ../../src/SDCCbitv.h \
- symtab.h break.h simi.h
-cmd.o: cmd.c sdcdb.h ../../sdccconf.h ../../support/gc/gc.h \
- ../../src/SDCCset.h ../../src/SDCChasht.h ../../src/SDCCbitv.h \
- symtab.h simi.h break.h cmd.h
-SDCChasht.o: ../../src/SDCChasht.c ../../src/SDCChasht.h \
- ../../support/gc/gc.h
#
#
-# Version
-VERSION = @VERSION@
-VERSIONHI = @VERSIONHI@
-VERSIONLO = @VERSIONLO@
-VERSIONP = @VERSIONP@
-
-# Programs
-SHELL = /bin/sh
-CC = @CC@
-CPP = @CPP@
-RANLIB = @RANLIB@
-INSTALL = @INSTALL@
-YACC = @YACC@
-LEX = @LEX@
-AWK = @AWK@
-# Directories
PRJDIR = ..
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-libdir = @libdir@
-datadir = @datadir@
-includedir = @includedir@
-mandir = @mandir@
-man1dir = $(mandir)/man1
-man2dir = $(mandir)/man2
-infodir = @infodir@
-srcdir = @srcdir@
-
-# Flags
-DEFS = $(subs -DHAVE_CONFIG_H,,@DEFS@)
-CPPFLAGS = @CPPFLAGS@ -I$(PRJDIR) -I$(PRJDIR)/support
-CFLAGS = @CFLAGS@ -Wall
-M_OR_MM = @M_OR_MM@
-LIBS = -lgc @LIBS@
+include $(PRJDIR)/Makefile.common
+
+LIBS = $(PORT)/port.a -lgc @LIBS@
LIBDIRS = -L$(PRJDIR)/support/gc
OBJECTS = SDCCy.o SDCClex.o SDCCerr.o SDCChasht.o SDCCmain.o \
SDCCsymt.o SDCCopt.o SDCCast.o SDCCmem.o SDCCval.o \
- SDCCralloc.o SDCCicode.o SDCCbitv.o SDCCset.o SDCClabel.o \
+ SDCCicode.o SDCCbitv.o SDCCset.o SDCClabel.o \
SDCCBBlock.o SDCCloop.o SDCCcse.o SDCCcflow.o SDCCdflow.o \
- SDCClrange.o SDCCptropt.o SDCCgen51.o SDCCpeeph.o SDCCglue.o spawn.o
+ SDCClrange.o SDCCptropt.o SDCCpeeph.o SDCCglue.o spawn.o
SOURCES = $(patsubst %.o,%.c,$(OBJECTS))
TARGET = $(PRJDIR)/bin/sdcc
# Compiling entire program or any subproject
# ------------------------------------------
-all: checkconf $(PRJDIR)/support/gc/libgc.a $(TARGET)
+all: port checkconf $(PRJDIR)/support/gc/libgc.a $(TARGET)
+
+port:
+ $(MAKE) -C $(PORT)
$(PRJDIR)/support/gc/libgc.a:
cd $(PRJDIR)/support/gc && $(MAKE)
+++ /dev/null
-/* A lexical scanner generated by flex */
-
-/* Scanner skeleton version:
- * $Header$
- */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-
-#include <stdio.h>
-
-
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
-#endif
-#endif
-
-
-#ifdef __cplusplus
-
-#include <stdlib.h>
-#include <unistd.h>
-
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_PROTOS
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#define YY_USE_CONST
-#define YY_USE_PROTOS
-#endif
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#define YY_BUF_SIZE 16384
-
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-
-extern int yyleng;
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-/* The funky do-while in the following #define is used to turn the definition
- * int a single C statement (which needs a semi-colon terminator). This
- * avoids problems with code like:
- *
- * if ( condition_holds )
- * yyless( 5 );
- * else
- * do_something_else();
- *
- * Prior to using the do-while the compiler would get upset at the
- * "else" because it interpreted the "if" statement as being all
- * done when it reached the ';' after the yyless() call.
- */
-
-/* Return all but the first 'n' matched characters back to the input stream. */
-
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- *yy_cp = yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yytext_ptr )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-typedef unsigned int yy_size_t;
-
-
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
- };
-
-static YY_BUFFER_STATE yy_current_buffer = 0;
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- */
-#define YY_CURRENT_BUFFER yy_current_buffer
-
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-
-
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart YY_PROTO(( FILE *input_file ));
-
-void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
-void yy_load_buffer_state YY_PROTO(( void ));
-YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
-void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
-void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
-
-YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
-YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
-
-static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
-static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
-static void yy_flex_free YY_PROTO(( void * ));
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
-
-typedef unsigned char YY_CHAR;
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-typedef int yy_state_type;
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state YY_PROTO(( void ));
-static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
-static int yy_get_next_buffer YY_PROTO(( void ));
-static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yytext_ptr = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 123
-#define YY_END_OF_BUFFER 124
-static yyconst short int yy_accept[767] =
- { 0,
- 0, 0, 0, 0, 124, 122, 121, 120, 122, 103,
- 69, 109, 102, 122, 97, 98, 107, 106, 94, 105,
- 101, 108, 64, 64, 95, 91, 110, 96, 111, 114,
- 61, 99, 100, 112, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 92, 113, 93, 104, 122, 121, 120,
- 122, 103, 69, 122, 109, 102, 122, 98, 107, 106,
- 94, 105, 101, 108, 64, 64, 95, 91, 110, 96,
- 111, 114, 61, 99, 100, 112, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-
- 61, 61, 61, 61, 61, 92, 113, 93, 104, 3,
- 4, 3, 119, 90, 76, 85, 77, 0, 0, 74,
- 82, 72, 83, 73, 84, 0, 67, 5, 75, 68,
- 63, 0, 64, 0, 64, 81, 87, 89, 88, 80,
- 61, 78, 61, 61, 61, 61, 61, 61, 61, 61,
- 6, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 18, 61, 61, 61, 61, 61, 61, 61, 61, 28,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 79, 86, 0,
- 0, 119, 90, 0, 0, 76, 85, 77, 0, 0,
-
- 0, 74, 82, 72, 83, 73, 84, 0, 67, 5,
- 75, 68, 63, 0, 64, 0, 64, 81, 87, 89,
- 88, 80, 61, 78, 61, 61, 61, 61, 61, 61,
- 61, 61, 6, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 18, 61, 61, 61, 61, 61, 61, 61,
- 61, 28, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 79,
- 86, 0, 65, 60, 0, 67, 67, 0, 68, 63,
- 0, 66, 62, 71, 70, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 8, 61, 61, 61, 61, 61,
-
- 61, 61, 61, 61, 61, 61, 61, 23, 61, 25,
- 61, 61, 29, 61, 61, 61, 61, 61, 61, 61,
- 37, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 0, 0, 0, 65, 0,
- 60, 0, 67, 67, 0, 68, 63, 0, 66, 62,
- 71, 70, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 8, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 23, 61, 25, 61, 61, 29,
- 61, 61, 61, 61, 61, 61, 61, 37, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-
- 61, 61, 0, 0, 67, 0, 67, 0, 68, 66,
- 62, 1, 61, 61, 61, 61, 61, 61, 61, 7,
- 61, 10, 11, 12, 61, 61, 61, 16, 61, 61,
- 20, 21, 61, 61, 26, 61, 61, 31, 32, 61,
- 61, 61, 61, 38, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 48, 61, 61, 61, 0, 0,
- 0, 0, 0, 67, 0, 67, 0, 68, 66, 62,
- 1, 61, 61, 61, 61, 61, 61, 61, 7, 61,
- 10, 11, 12, 61, 61, 61, 16, 61, 61, 20,
- 21, 61, 61, 26, 61, 61, 31, 32, 61, 61,
-
- 61, 61, 38, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 48, 61, 61, 61, 0, 0, 67,
- 54, 53, 61, 61, 56, 61, 61, 9, 13, 61,
- 61, 61, 61, 61, 24, 27, 61, 33, 61, 61,
- 61, 39, 61, 61, 61, 61, 61, 61, 46, 61,
- 50, 61, 51, 52, 0, 0, 0, 0, 0, 67,
- 54, 53, 61, 61, 56, 61, 61, 9, 13, 61,
- 61, 61, 61, 61, 24, 27, 61, 33, 61, 61,
- 61, 39, 61, 61, 61, 61, 61, 61, 46, 61,
- 50, 61, 51, 52, 0, 61, 59, 58, 57, 61,
-
- 61, 61, 19, 22, 61, 61, 61, 36, 40, 41,
- 42, 43, 44, 61, 61, 61, 0, 0, 115, 0,
- 0, 0, 61, 59, 58, 57, 61, 61, 61, 19,
- 22, 61, 61, 61, 36, 40, 41, 42, 43, 44,
- 61, 61, 61, 0, 61, 61, 61, 17, 61, 61,
- 61, 45, 61, 61, 0, 0, 115, 0, 0, 0,
- 61, 61, 61, 17, 61, 61, 61, 45, 61, 61,
- 2, 55, 14, 15, 61, 61, 35, 47, 49, 0,
- 0, 0, 0, 116, 0, 0, 0, 55, 14, 15,
- 61, 61, 35, 47, 49, 30, 34, 0, 0, 0,
-
- 0, 116, 0, 0, 0, 30, 34, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 117, 0, 0, 0,
- 0, 117, 65, 117, 0, 0, 0, 0, 0, 0,
- 0, 118, 0, 0, 0, 0, 118, 65, 118, 0,
- 0, 0, 0, 117, 0, 0, 0, 0, 0, 0,
- 118, 117, 0, 0, 118, 0
- } ;
-
-static yyconst int yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 2, 2, 4, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 5, 6, 7, 8, 1, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 22, 23, 24,
- 25, 26, 27, 1, 28, 28, 28, 28, 29, 30,
- 31, 31, 31, 31, 31, 32, 31, 31, 31, 31,
- 31, 31, 31, 31, 33, 31, 31, 34, 31, 31,
- 35, 36, 37, 38, 39, 1, 40, 41, 42, 43,
-
- 44, 45, 46, 47, 48, 31, 49, 50, 51, 52,
- 53, 54, 31, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst int yy_meta[68] =
- { 0,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
- 3, 1, 1, 1, 1, 1, 1, 1, 1, 4,
- 4, 1, 1, 1, 1, 1, 1, 4, 4, 4,
- 5, 5, 5, 5, 1, 1, 1, 1, 5, 4,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 1, 1, 1, 1
- } ;
-
-static yyconst short int yy_base[785] =
- { 0,
- 0, 67, 132, 133, 1347, 1348, 1348, 1348, 1343, 1320,
- 1348, 1319, 127, 1307, 1348, 1348, 1317, 123, 1348, 124,
- 122, 130, 155, 133, 1348, 1348, 121, 1316, 131, 1348,
- 0, 1348, 1348, 1315, 150, 101, 112, 154, 142, 118,
- 168, 1286, 167, 1285, 1293, 1293, 1291, 179, 1272, 122,
- 1280, 1285, 1288, 1348, 138, 1348, 1348, 1318, 1317, 1316,
- 194, 203, 1315, 188, 205, 219, 211, 1314, 220, 225,
- 1313, 229, 231, 244, 258, 253, 1312, 1311, 236, 241,
- 255, 1310, 319, 1309, 1308, 247, 253, 123, 209, 347,
- 260, 338, 351, 1266, 232, 1265, 1273, 1273, 1271, 348,
-
- 1252, 242, 1260, 1265, 1268, 1298, 385, 1297, 1296, 1348,
- 1348, 1263, 1348, 1348, 1348, 1348, 1348, 128, 158, 1348,
- 1348, 1348, 1348, 1348, 1348, 1288, 386, 1348, 1348, 393,
- 424, 412, 402, 0, 443, 1280, 1348, 1348, 1348, 1279,
- 0, 1348, 1247, 1249, 1261, 1256, 1256, 1254, 1254, 1253,
- 0, 1238, 1237, 1249, 1236, 1251, 182, 1242, 1232, 1243,
- 1229, 1230, 1227, 1227, 1228, 1229, 1226, 1223, 1239, 0,
- 1221, 1225, 1236, 1235, 382, 1226, 1218, 1219, 243, 228,
- 1223, 1216, 261, 1221, 185, 1220, 1227, 1348, 1348, 1254,
- 242, 1253, 1252, 399, 386, 1251, 1250, 1249, 437, 458,
-
- 400, 1248, 1247, 1246, 1245, 1244, 1243, 300, 468, 1242,
- 1241, 487, 509, 450, 478, 556, 531, 434, 1240, 1239,
- 1238, 471, 0, 1237, 1192, 1194, 1206, 1201, 1201, 1199,
- 1199, 1198, 0, 1183, 1182, 1194, 1181, 1196, 434, 1187,
- 1177, 1188, 1174, 1175, 1172, 1172, 1173, 1174, 1171, 1168,
- 1184, 0, 1166, 1170, 1181, 1180, 458, 1171, 1163, 1164,
- 346, 400, 1168, 1161, 410, 1166, 369, 1165, 1172, 1199,
- 1198, 1157, 1348, 1348, 505, 1348, 558, 541, 1348, 507,
- 400, 562, 522, 1348, 1348, 1157, 1164, 1149, 1153, 1164,
- 1163, 1162, 1161, 1147, 0, 1159, 1154, 1142, 1152, 428,
-
- 1138, 1154, 1153, 1151, 1147, 1139, 1145, 0, 1148, 0,
- 1134, 1129, 1141, 1138, 1128, 1125, 1129, 1132, 1121, 1121,
- 0, 1122, 1124, 1131, 1117, 1115, 1115, 1127, 1117, 1121,
- 1116, 1124, 1126, 1115, 1107, 553, 439, 469, 1151, 593,
- 1150, 603, 1149, 605, 621, 1148, 598, 607, 631, 670,
- 1147, 1146, 1106, 1113, 1098, 1102, 1113, 1112, 1111, 1110,
- 1096, 0, 1108, 1103, 1091, 1101, 449, 1087, 1103, 1102,
- 1100, 1096, 1088, 1094, 0, 1097, 0, 1083, 1078, 1090,
- 1087, 1077, 1074, 1078, 1081, 1070, 1070, 0, 1071, 1073,
- 1080, 1066, 1064, 1064, 1076, 1066, 1070, 1065, 1073, 1075,
-
- 1064, 1056, 1069, 503, 638, 645, 1348, 513, 674, 1348,
- 589, 0, 1067, 1070, 1065, 1051, 1052, 1049, 1048, 0,
- 1055, 0, 0, 0, 1046, 1054, 1053, 0, 1042, 1049,
- 0, 0, 1043, 1040, 0, 1056, 1040, 0, 0, 1054,
- 1036, 1036, 1036, 0, 1033, 1045, 1035, 1039, 1044, 1043,
- 1041, 1031, 1036, 1035, 0, 1023, 1035, 1038, 1072, 491,
- 502, 635, 633, 697, 652, 1064, 665, 711, 1063, 675,
- 0, 1030, 1033, 1028, 1014, 1015, 1012, 1011, 0, 1018,
- 0, 0, 0, 1009, 1017, 1016, 0, 1005, 1012, 0,
- 0, 1006, 1003, 0, 1019, 1003, 0, 0, 1017, 999,
-
- 999, 999, 0, 996, 1008, 998, 1002, 1007, 1006, 1004,
- 994, 999, 998, 0, 986, 998, 1001, 1000, 524, 714,
- 0, 0, 984, 998, 0, 997, 996, 0, 0, 983,
- 992, 983, 988, 979, 0, 0, 975, 0, 974, 971,
- 975, 0, 983, 980, 982, 966, 975, 977, 0, 968,
- 0, 971, 0, 0, 996, 672, 558, 694, 728, 733,
- 0, 0, 962, 976, 0, 975, 974, 0, 0, 961,
- 970, 961, 966, 957, 0, 0, 953, 0, 952, 949,
- 953, 0, 961, 958, 960, 944, 953, 955, 0, 946,
- 0, 949, 0, 0, 940, 947, 0, 0, 0, 936,
-
- 953, 935, 0, 0, 933, 950, 945, 0, 0, 0,
- 0, 0, 0, 943, 943, 936, 980, 677, 972, 676,
- 604, 746, 935, 0, 0, 0, 924, 941, 923, 0,
- 0, 921, 938, 933, 0, 0, 0, 0, 0, 0,
- 931, 931, 924, 894, 893, 855, 838, 0, 833, 834,
- 830, 0, 839, 837, 551, 877, 1348, 747, 689, 726,
- 837, 833, 826, 0, 819, 820, 816, 0, 827, 825,
- 1348, 0, 0, 0, 810, 808, 0, 0, 0, 806,
- 820, 566, 763, 846, 718, 741, 744, 0, 0, 0,
- 799, 796, 0, 0, 0, 0, 0, 797, 796, 671,
-
- 847, 1348, 768, 758, 761, 0, 0, 796, 684, 588,
- 771, 762, 768, 671, 674, 782, 784, 781, 782, 0,
- 626, 492, 755, 796, 797, 791, 0, 586, 602, 800,
- 787, 808, 0, 547, 799, 0, 788, 802, 804, 806,
- 821, 0, 809, 818, 819, 820, 826, 0, 543, 489,
- 811, 825, 831, 451, 822, 835, 836, 421, 312, 837,
- 307, 285, 845, 211, 182, 1348, 891, 896, 898, 903,
- 908, 143, 913, 918, 923, 928, 933, 938, 943, 948,
- 953, 958, 963, 968
- } ;
-
-static yyconst short int yy_def[785] =
- { 0,
- 766, 766, 767, 767, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 768, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 769, 766, 766, 766, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 766, 766, 766, 766, 770, 770, 770,
- 770, 770, 770, 770, 770, 770, 771, 770, 770, 770,
- 770, 770, 770, 770, 770, 770, 770, 770, 770, 770,
- 770, 770, 766, 770, 770, 770, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-
- 83, 83, 83, 83, 83, 770, 770, 770, 770, 766,
- 766, 766, 766, 766, 766, 766, 766, 768, 768, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 772, 766, 766, 766, 766, 766, 766,
- 769, 766, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 766, 766, 770,
- 766, 770, 770, 770, 770, 770, 770, 770, 771, 768,
-
- 771, 770, 770, 770, 770, 770, 770, 770, 770, 770,
- 770, 770, 770, 770, 770, 770, 770, 770, 770, 770,
- 770, 770, 83, 770, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 770,
- 770, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 772, 766, 766, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
-
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 766, 770, 770, 770, 768,
- 770, 770, 770, 770, 770, 770, 770, 770, 770, 770,
- 770, 770, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-
- 83, 83, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 766, 770,
- 770, 768, 770, 770, 770, 770, 770, 770, 770, 770,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 766, 766, 766,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 766, 773, 770, 768, 770, 770,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 766, 769, 769, 769, 769, 769,
-
- 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, 769, 766, 773, 770, 774,
- 770, 768, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 766, 769, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 766, 774, 766, 774, 775, 768,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 766, 769, 769, 769, 769, 769, 769, 769, 769, 766,
- 766, 774, 775, 770, 776, 768, 768, 83, 83, 83,
- 83, 83, 83, 83, 83, 769, 769, 766, 766, 774,
-
- 776, 766, 776, 768, 768, 83, 83, 766, 766, 774,
- 776, 768, 768, 766, 766, 774, 776, 768, 768, 777,
- 766, 774, 774, 776, 778, 768, 777, 766, 774, 774,
- 776, 778, 777, 778, 768, 779, 774, 774, 776, 776,
- 780, 779, 774, 774, 776, 776, 780, 779, 780, 781,
- 774, 776, 776, 781, 774, 776, 776, 782, 783, 776,
- 782, 783, 776, 784, 784, 0, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766
- } ;
-
-static yyconst short int yy_nxt[1416] =
- { 0,
- 6, 7, 8, 9, 7, 10, 11, 6, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 31, 31,
- 31, 31, 31, 31, 32, 6, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 31, 43, 31, 44,
- 31, 45, 31, 46, 47, 48, 49, 50, 51, 52,
- 53, 31, 31, 54, 55, 56, 57, 58, 59, 60,
- 61, 59, 62, 63, 64, 65, 66, 67, 15, 68,
- 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- 79, 80, 81, 82, 83, 83, 83, 83, 83, 83,
-
- 83, 84, 58, 85, 86, 87, 88, 89, 90, 91,
- 92, 93, 94, 83, 95, 83, 96, 83, 97, 83,
- 98, 99, 100, 101, 102, 103, 104, 105, 83, 83,
- 106, 107, 108, 109, 111, 111, 116, 121, 273, 126,
- 123, 127, 127, 128, 136, 137, 283, 122, 124, 125,
- 130, 117, 135, 135, 129, 139, 140, 151, 152, 153,
- 766, 132, 188, 119, 133, 133, 154, 162, 118, 163,
- 112, 112, 130, 183, 131, 131, 132, 184, 164, 233,
- 234, 159, 133, 132, 702, 160, 133, 133, 134, 143,
- 133, 144, 145, 155, 161, 146, 192, 147, 132, 191,
-
- 156, 148, 189, 149, 133, 191, 157, 165, 158, 169,
- 150, 170, 133, 702, 191, 134, 191, 166, 171, 176,
- 167, 190, 200, 177, 299, 178, 179, 193, 197, 196,
- 191, 191, 332, 300, 333, 180, 191, 194, 181, 203,
- 191, 195, 191, 198, 202, 205, 201, 191, 208, 204,
- 209, 209, 191, 206, 207, 191, 235, 210, 191, 218,
- 219, 336, 336, 236, 191, 220, 191, 325, 211, 191,
- 212, 224, 217, 217, 251, 212, 252, 213, 213, 221,
- 222, 214, 326, 253, 215, 215, 214, 702, 323, 215,
- 215, 216, 225, 265, 226, 227, 214, 266, 228, 241,
-
- 229, 214, 215, 242, 230, 324, 231, 215, 329, 657,
- 215, 191, 243, 232, 702, 215, 330, 341, 216, 190,
- 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
- 191, 190, 190, 190, 190, 190, 190, 190, 223, 223,
- 190, 190, 190, 190, 190, 190, 223, 223, 223, 223,
- 223, 223, 223, 190, 190, 190, 190, 223, 223, 223,
- 223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, 190, 190, 190, 190, 237, 244, 258, 245,
- 247, 390, 259, 238, 260, 261, 191, 191, 246, 239,
-
- 248, 240, 190, 249, 262, 127, 127, 263, 391, 270,
- 191, 200, 277, 277, 275, 276, 399, 276, 400, 282,
- 282, 278, 279, 657, 279, 317, 281, 318, 281, 275,
- 276, 282, 282, 133, 133, 276, 278, 279, 319, 392,
- 338, 130, 279, 131, 131, 191, 337, 339, 200, 271,
- 191, 133, 132, 657, 393, 280, 280, 396, 351, 133,
- 130, 191, 135, 135, 348, 397, 348, 132, 273, 349,
- 349, 132, 201, 280, 133, 133, 366, 340, 340, 191,
- 191, 280, 191, 425, 426, 367, 132, 209, 209, 191,
- 460, 657, 133, 119, 657, 352, 342, 343, 191, 343,
-
- 133, 384, 191, 385, 484, 485, 344, 344, 461, 215,
- 215, 342, 343, 191, 386, 345, 346, 343, 346, 404,
- 191, 404, 405, 405, 405, 405, 212, 215, 213, 213,
- 345, 346, 409, 409, 556, 215, 346, 214, 280, 280,
- 347, 347, 191, 520, 520, 766, 729, 557, 212, 766,
- 217, 217, 214, 411, 411, 408, 280, 408, 347, 214,
- 409, 409, 215, 215, 280, 459, 347, 191, 657, 191,
- 700, 411, 336, 336, 214, 350, 350, 277, 277, 411,
- 215, 282, 282, 350, 350, 350, 406, 407, 215, 407,
- 657, 410, 716, 410, 680, 350, 350, 350, 350, 350,
-
- 350, 406, 407, 273, 657, 462, 410, 407, 621, 191,
- 681, 410, 340, 340, 191, 191, 191, 463, 191, 463,
- 411, 411, 464, 464, 344, 344, 349, 349, 119, 347,
- 347, 736, 191, 465, 466, 467, 466, 467, 411, 558,
- 468, 468, 191, 659, 191, 273, 411, 347, 465, 466,
- 349, 349, 464, 464, 466, 347, 737, 405, 405, 519,
- 469, 519, 469, 191, 520, 520, 559, 276, 559, 276,
- 119, 560, 560, 657, 619, 469, 191, 728, 657, 619,
- 469, 191, 276, 620, 468, 468, 191, 276, 620, 350,
- 350, 684, 710, 409, 409, 658, 658, 350, 350, 350,
-
- 685, 470, 470, 279, 273, 279, 470, 470, 191, 350,
- 350, 350, 350, 350, 350, 622, 464, 464, 279, 470,
- 702, 721, 191, 279, 470, 720, 343, 470, 343, 119,
- 468, 468, 470, 520, 520, 715, 273, 703, 703, 191,
- 346, 343, 346, 407, 191, 407, 343, 560, 560, 657,
- 660, 273, 560, 560, 273, 346, 273, 657, 407, 682,
- 346, 119, 466, 407, 466, 684, 658, 658, 273, 686,
- 702, 273, 273, 702, 685, 717, 119, 466, 273, 119,
- 711, 119, 466, 705, 657, 687, 702, 703, 703, 702,
- 657, 273, 273, 119, 730, 704, 119, 119, 702, 118,
-
- 731, 273, 657, 119, 657, 724, 702, 733, 702, 273,
- 118, 657, 712, 657, 718, 713, 119, 119, 733, 719,
- 657, 702, 702, 118, 657, 722, 119, 702, 118, 726,
- 739, 748, 734, 702, 119, 725, 748, 702, 702, 702,
- 743, 723, 735, 734, 741, 746, 740, 702, 714, 702,
- 709, 708, 707, 744, 738, 706, 749, 191, 745, 699,
- 698, 749, 755, 750, 697, 751, 696, 758, 695, 694,
- 693, 692, 691, 752, 753, 690, 689, 756, 688, 657,
- 679, 678, 757, 760, 677, 676, 675, 674, 763, 759,
- 764, 110, 110, 110, 110, 110, 118, 118, 673, 118,
-
- 118, 141, 141, 190, 190, 190, 190, 190, 199, 199,
- 199, 199, 199, 618, 618, 618, 618, 618, 656, 656,
- 656, 656, 656, 683, 683, 683, 683, 683, 701, 701,
- 701, 701, 701, 727, 672, 727, 727, 727, 732, 732,
- 732, 732, 732, 742, 671, 742, 742, 742, 747, 747,
- 747, 747, 747, 754, 754, 754, 754, 754, 761, 761,
- 761, 761, 761, 762, 762, 762, 762, 762, 765, 765,
- 765, 765, 765, 670, 669, 668, 667, 666, 665, 664,
- 663, 662, 661, 191, 655, 654, 653, 652, 651, 650,
- 649, 648, 647, 646, 645, 644, 643, 642, 641, 640,
-
- 639, 638, 637, 636, 635, 634, 633, 632, 631, 630,
- 629, 628, 627, 626, 625, 624, 623, 617, 616, 615,
- 614, 613, 612, 611, 610, 609, 608, 607, 606, 605,
- 604, 603, 602, 601, 600, 599, 598, 597, 596, 595,
- 594, 593, 592, 591, 590, 589, 588, 587, 586, 585,
- 584, 583, 582, 581, 580, 579, 578, 577, 576, 575,
- 574, 573, 572, 571, 570, 569, 568, 567, 566, 565,
- 564, 563, 562, 561, 191, 191, 555, 554, 553, 552,
- 551, 550, 549, 548, 547, 546, 545, 544, 543, 542,
- 541, 540, 539, 538, 537, 536, 535, 534, 533, 532,
-
- 531, 530, 529, 528, 527, 526, 525, 524, 523, 522,
- 521, 518, 517, 516, 515, 514, 513, 512, 511, 510,
- 509, 508, 507, 506, 505, 504, 503, 502, 501, 500,
- 499, 498, 497, 496, 495, 494, 493, 492, 491, 490,
- 489, 488, 487, 486, 483, 482, 481, 480, 479, 478,
- 477, 476, 475, 474, 473, 472, 471, 191, 191, 191,
- 191, 191, 191, 458, 457, 456, 455, 454, 453, 452,
- 451, 450, 449, 448, 447, 446, 445, 444, 443, 442,
- 441, 440, 439, 438, 437, 436, 435, 434, 433, 432,
- 431, 430, 429, 428, 427, 424, 423, 422, 421, 420,
-
- 419, 418, 417, 416, 415, 414, 413, 412, 403, 191,
- 191, 402, 401, 398, 395, 394, 389, 388, 387, 383,
- 382, 381, 380, 379, 378, 377, 376, 375, 374, 373,
- 372, 371, 370, 369, 368, 365, 364, 363, 362, 361,
- 360, 359, 358, 357, 356, 355, 354, 353, 191, 191,
- 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
- 191, 191, 191, 191, 191, 191, 335, 334, 331, 328,
- 327, 322, 321, 320, 316, 315, 314, 313, 312, 311,
- 310, 309, 308, 307, 306, 305, 304, 303, 302, 301,
- 298, 297, 296, 295, 294, 293, 292, 291, 290, 289,
-
- 288, 287, 286, 285, 284, 274, 272, 191, 191, 191,
- 269, 268, 267, 264, 257, 256, 255, 254, 250, 191,
- 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
- 187, 186, 185, 182, 175, 174, 173, 172, 168, 142,
- 138, 120, 119, 115, 114, 113, 766, 5, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
-
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766
- } ;
-
-static yyconst short int yy_chk[1416] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 3, 4, 13, 18, 118, 21,
- 20, 21, 21, 22, 27, 27, 772, 18, 20, 20,
- 24, 13, 24, 24, 22, 29, 29, 36, 36, 37,
- 119, 24, 55, 118, 24, 24, 37, 40, 119, 40,
- 3, 4, 23, 50, 23, 23, 24, 50, 40, 88,
- 88, 39, 24, 23, 765, 39, 23, 23, 23, 35,
- 24, 35, 35, 38, 39, 35, 61, 35, 23, 64,
-
- 38, 35, 55, 35, 23, 61, 38, 41, 38, 43,
- 35, 43, 23, 764, 62, 23, 65, 41, 43, 48,
- 41, 67, 67, 48, 157, 48, 48, 62, 66, 65,
- 66, 69, 185, 157, 185, 48, 70, 64, 48, 70,
- 72, 64, 73, 66, 69, 72, 67, 79, 73, 70,
- 73, 73, 80, 72, 72, 74, 89, 74, 86, 79,
- 79, 191, 191, 89, 76, 80, 81, 180, 74, 75,
- 76, 86, 76, 76, 95, 75, 95, 75, 75, 81,
- 81, 76, 180, 95, 76, 76, 75, 762, 179, 75,
- 75, 75, 87, 102, 87, 87, 76, 102, 87, 91,
-
- 87, 75, 76, 91, 87, 179, 87, 75, 183, 761,
- 76, 208, 91, 87, 759, 75, 183, 208, 75, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 90, 92, 100, 92,
- 93, 261, 100, 90, 100, 100, 107, 195, 92, 90,
-
- 93, 90, 201, 93, 100, 127, 127, 100, 261, 107,
- 194, 201, 130, 130, 127, 127, 267, 127, 267, 281,
- 281, 130, 130, 758, 130, 175, 132, 175, 132, 127,
- 127, 132, 132, 133, 133, 127, 130, 130, 175, 262,
- 195, 131, 130, 131, 131, 218, 194, 199, 199, 107,
- 337, 133, 131, 754, 262, 131, 131, 265, 218, 133,
- 135, 214, 135, 135, 214, 265, 214, 131, 200, 214,
- 214, 135, 199, 131, 135, 135, 239, 200, 200, 209,
- 338, 131, 222, 300, 300, 239, 135, 209, 209, 215,
- 337, 750, 135, 200, 722, 222, 209, 209, 212, 209,
-
- 135, 257, 460, 257, 367, 367, 212, 212, 338, 215,
- 215, 209, 209, 461, 257, 212, 212, 209, 212, 275,
- 213, 275, 404, 404, 275, 275, 213, 215, 213, 213,
- 212, 212, 408, 408, 460, 215, 212, 213, 280, 280,
- 213, 213, 217, 519, 519, 749, 722, 461, 217, 734,
- 217, 217, 213, 283, 283, 278, 280, 278, 213, 217,
- 278, 278, 217, 217, 280, 336, 213, 216, 682, 557,
- 682, 283, 336, 336, 217, 216, 216, 277, 277, 283,
- 217, 282, 282, 216, 216, 216, 277, 277, 217, 277,
- 710, 282, 710, 282, 655, 216, 216, 216, 216, 216,
-
- 216, 277, 277, 340, 729, 340, 282, 277, 557, 347,
- 655, 282, 340, 340, 342, 621, 344, 342, 348, 342,
- 411, 411, 342, 342, 344, 344, 348, 348, 340, 347,
- 347, 728, 345, 344, 344, 345, 344, 345, 411, 462,
- 345, 345, 349, 621, 463, 462, 411, 347, 344, 344,
- 349, 349, 463, 463, 344, 347, 729, 405, 405, 406,
- 349, 406, 349, 465, 406, 406, 465, 405, 465, 405,
- 462, 465, 465, 700, 556, 349, 467, 721, 620, 618,
- 349, 350, 405, 556, 467, 467, 470, 405, 618, 350,
- 350, 659, 700, 409, 409, 620, 620, 350, 350, 350,
-
- 659, 350, 350, 409, 558, 409, 470, 470, 464, 350,
- 350, 350, 350, 350, 350, 558, 464, 464, 409, 350,
- 685, 715, 468, 409, 470, 714, 464, 350, 464, 558,
- 468, 468, 470, 520, 520, 709, 660, 685, 685, 559,
- 468, 464, 468, 520, 560, 520, 464, 559, 559, 658,
- 622, 686, 560, 560, 687, 468, 622, 723, 520, 658,
- 468, 660, 560, 520, 560, 683, 658, 658, 704, 660,
- 703, 705, 712, 711, 683, 711, 686, 560, 713, 687,
- 703, 622, 560, 687, 716, 660, 717, 703, 703, 731,
- 737, 718, 719, 704, 723, 686, 705, 712, 724, 725,
-
- 724, 726, 730, 713, 738, 717, 739, 725, 740, 735,
- 732, 743, 704, 751, 712, 705, 718, 719, 732, 713,
- 744, 745, 746, 741, 755, 716, 726, 752, 747, 719,
- 731, 741, 725, 753, 735, 718, 747, 756, 757, 760,
- 737, 716, 726, 732, 735, 740, 731, 763, 708, 701,
- 699, 698, 692, 738, 730, 691, 741, 684, 739, 681,
- 680, 747, 751, 743, 676, 744, 675, 755, 670, 669,
- 667, 666, 665, 745, 746, 663, 662, 752, 661, 656,
- 654, 653, 753, 757, 651, 650, 649, 647, 760, 756,
- 763, 767, 767, 767, 767, 767, 768, 768, 646, 768,
-
- 768, 769, 769, 770, 770, 770, 770, 770, 771, 771,
- 771, 771, 771, 773, 773, 773, 773, 773, 774, 774,
- 774, 774, 774, 775, 775, 775, 775, 775, 776, 776,
- 776, 776, 776, 777, 645, 777, 777, 777, 778, 778,
- 778, 778, 778, 779, 644, 779, 779, 779, 780, 780,
- 780, 780, 780, 781, 781, 781, 781, 781, 782, 782,
- 782, 782, 782, 783, 783, 783, 783, 783, 784, 784,
- 784, 784, 784, 643, 642, 641, 634, 633, 632, 629,
- 628, 627, 623, 619, 617, 616, 615, 614, 607, 606,
- 605, 602, 601, 600, 596, 595, 592, 590, 588, 587,
-
- 586, 585, 584, 583, 581, 580, 579, 577, 574, 573,
- 572, 571, 570, 567, 566, 564, 563, 555, 552, 550,
- 548, 547, 546, 545, 544, 543, 541, 540, 539, 537,
- 534, 533, 532, 531, 530, 527, 526, 524, 523, 518,
- 517, 516, 515, 513, 512, 511, 510, 509, 508, 507,
- 506, 505, 504, 502, 501, 500, 499, 496, 495, 493,
- 492, 489, 488, 486, 485, 484, 480, 478, 477, 476,
- 475, 474, 473, 472, 469, 466, 459, 458, 457, 456,
- 454, 453, 452, 451, 450, 449, 448, 447, 446, 445,
- 443, 442, 441, 440, 437, 436, 434, 433, 430, 429,
-
- 427, 426, 425, 421, 419, 418, 417, 416, 415, 414,
- 413, 403, 402, 401, 400, 399, 398, 397, 396, 395,
- 394, 393, 392, 391, 390, 389, 387, 386, 385, 384,
- 383, 382, 381, 380, 379, 378, 376, 374, 373, 372,
- 371, 370, 369, 368, 366, 365, 364, 363, 361, 360,
- 359, 358, 357, 356, 355, 354, 353, 352, 351, 346,
- 343, 341, 339, 335, 334, 333, 332, 331, 330, 329,
- 328, 327, 326, 325, 324, 323, 322, 320, 319, 318,
- 317, 316, 315, 314, 313, 312, 311, 309, 307, 306,
- 305, 304, 303, 302, 301, 299, 298, 297, 296, 294,
-
- 293, 292, 291, 290, 289, 288, 287, 286, 272, 271,
- 270, 269, 268, 266, 264, 263, 260, 259, 258, 256,
- 255, 254, 253, 251, 250, 249, 248, 247, 246, 245,
- 244, 243, 242, 241, 240, 238, 237, 236, 235, 234,
- 232, 231, 230, 229, 228, 227, 226, 225, 224, 221,
- 220, 219, 211, 210, 207, 206, 205, 204, 203, 202,
- 198, 197, 196, 193, 192, 190, 187, 186, 184, 182,
- 181, 178, 177, 176, 174, 173, 172, 171, 169, 168,
- 167, 166, 165, 164, 163, 162, 161, 160, 159, 158,
- 156, 155, 154, 153, 152, 150, 149, 148, 147, 146,
-
- 145, 144, 143, 140, 136, 126, 112, 109, 108, 106,
- 105, 104, 103, 101, 99, 98, 97, 96, 94, 85,
- 84, 82, 78, 77, 71, 68, 63, 60, 59, 58,
- 53, 52, 51, 49, 47, 46, 45, 44, 42, 34,
- 28, 17, 14, 12, 10, 9, 5, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
-
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "SDCC.lex"
-#define INITIAL 0
-/*-----------------------------------------------------------------------
- SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
- 8/16 bit microcontrollers)
- Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
--------------------------------------------------------------------------*/
-#line 32 "SDCC.lex"
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "SDCCglobl.h"
-#include "SDCCsymt.h"
-#include "SDCCval.h"
-#include "SDCCast.h"
-#include "SDCCy.h"
-#include "SDCChasht.h"
-#include "SDCCmem.h"
-
-char *stringLiteral();
-char *currFname;
-
-extern int lineno ;
-extern char *filename ;
-extern char *fullSrcFileName ;
-int yylineno = 1 ;
-void count() ;
-void comment();
-int process_pragma(char *);
-#undef yywrap
-
-int yywrap YY_PROTO((void))
-{
- return(1);
-}
-
-char asmbuff[MAX_INLINEASM] ;
-char *asmp ;
-extern int check_type ( );
-extern int checkCurrFile (char *);
-extern int processPragma (char *);
-extern int printListing (int );
-struct optimize save_optimize ;
-struct options save_options ;
-
- enum {
- P_SAVE = 1,
- P_RESTORE ,
- P_NOINDUCTION,
- P_NOINVARIANT,
- P_INDUCTION ,
- P_STACKAUTO ,
- P_NOJTBOUND ,
- P_NOOVERLAY ,
- P_NOGCSE ,
- P_CALLEE_SAVES,
- P_EXCLUDE ,
- P_LOOPREV
- };
-
-#define asm 1
-
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap YY_PROTO(( void ));
-#else
-extern int yywrap YY_PROTO(( void ));
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-static void yyunput YY_PROTO(( int c, char *buf_ptr ));
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
-#else
-static int input YY_PROTO(( void ));
-#endif
-#endif
-
-#if YY_STACK_USED
-static int yy_start_stack_ptr = 0;
-static int yy_start_stack_depth = 0;
-static int *yy_start_stack = 0;
-#ifndef YY_NO_PUSH_STATE
-static void yy_push_state YY_PROTO(( int new_state ));
-#endif
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state YY_PROTO(( void ));
-#endif
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state YY_PROTO(( void ));
-#endif
-
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
-
-#ifdef YY_MALLOC_DECL
-YY_MALLOC_DECL
-#else
-#if __STDC__
-#ifndef __cplusplus
-#include <stdlib.h>
-#endif
-#else
-/* Just try to get by without declaring the routines. This will fail
- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
- * or sizeof(void*) != sizeof(int).
- */
-#endif
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( yy_current_buffer->yy_is_interactive ) \
- { \
- int c = '*', n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
- && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" );
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL int yylex YY_PROTO(( void ))
-#endif
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- if ( yyleng > 0 ) \
- yy_current_buffer->yy_at_bol = \
- (yytext[yyleng - 1] == '\n'); \
- YY_USER_ACTION
-
-YY_DECL
- {
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
-
-#line 87 "SDCC.lex"
-
-
- if ( yy_init )
- {
- yy_init = 0;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yy_start )
- yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! yy_current_buffer )
- yy_current_buffer =
- yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_load_buffer_state();
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yy_start;
- yy_current_state += YY_AT_BOL();
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 767 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 1348 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-
-do_action: /* This label is used only to access EOF actions. */
-
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yy_hold_char;
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 88 "SDCC.lex"
-{ count(); asmp = asmbuff ;BEGIN(asm) ;}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 89 "SDCC.lex"
-{ count() ;
- *asmp = '\0' ;
- strcpy(yylval.yyinline,asmbuff) ;
- BEGIN(INITIAL) ;
- return (INLINEASM) ; }
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 94 "SDCC.lex"
-{ *asmp++ = yytext[0] ; }
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 95 "SDCC.lex"
-{ count(); *asmp++ = '\n' ;}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 96 "SDCC.lex"
-{ comment(); }
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 97 "SDCC.lex"
-{ count(); return(AT) ; }
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 98 "SDCC.lex"
-{ count(); return(AUTO); }
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 99 "SDCC.lex"
-{ count(); return(BIT) ; }
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 100 "SDCC.lex"
-{ count(); return(BREAK); }
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 101 "SDCC.lex"
-{ count(); return(CASE); }
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 102 "SDCC.lex"
-{ count(); return(CHAR); }
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 103 "SDCC.lex"
-{ count(); return(CODE); }
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 104 "SDCC.lex"
-{ count(); return(CONST); }
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 105 "SDCC.lex"
-{ count(); return(CONTINUE); }
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 106 "SDCC.lex"
-{ count(); return(CRITICAL); }
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 107 "SDCC.lex"
-{ count(); return(DATA); }
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 108 "SDCC.lex"
-{ count(); return(DEFAULT); }
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 109 "SDCC.lex"
-{ count(); return(DO); }
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 110 "SDCC.lex"
-{ count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 111 "SDCC.lex"
-{ count(); return(ELSE); }
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 112 "SDCC.lex"
-{ count(); return(ENUM); }
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 113 "SDCC.lex"
-{ count(); return(EXTERN); }
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 114 "SDCC.lex"
-{ count(); return(XDATA); }
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 115 "SDCC.lex"
-{ count(); return(FLOAT); }
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 116 "SDCC.lex"
-{ count(); return(FOR); }
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 117 "SDCC.lex"
-{ count(); return(GOTO); }
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 118 "SDCC.lex"
-{ count(); return(IDATA);}
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 119 "SDCC.lex"
-{ count(); return(IF); }
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 120 "SDCC.lex"
-{ count(); return(INT); }
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 121 "SDCC.lex"
-{ count(); return(INTERRUPT);}
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 122 "SDCC.lex"
-{ count(); return(LONG); }
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 123 "SDCC.lex"
-{ count(); return(DATA);}
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 124 "SDCC.lex"
-{ count(); return(PDATA); }
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 125 "SDCC.lex"
-{ count(); return(REENTRANT);}
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 126 "SDCC.lex"
-{ count(); return(REGISTER); }
- YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 127 "SDCC.lex"
-{ count(); return(RETURN); }
- YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 128 "SDCC.lex"
-{ count(); return(SFR) ; }
- YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 129 "SDCC.lex"
-{ count(); return(SBIT) ; }
- YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 130 "SDCC.lex"
-{ count(); return(SHORT); }
- YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 131 "SDCC.lex"
-{ count(); return(SIGNED); }
- YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 132 "SDCC.lex"
-{ count(); return(SIZEOF); }
- YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 133 "SDCC.lex"
-{ count(); return(STATIC); }
- YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 134 "SDCC.lex"
-{ count(); return(STRUCT); }
- YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 135 "SDCC.lex"
-{ count(); return(SWITCH); }
- YY_BREAK
-case 45:
-YY_RULE_SETUP
-#line 136 "SDCC.lex"
-{ count(); return(TYPEDEF); }
- YY_BREAK
-case 46:
-YY_RULE_SETUP
-#line 137 "SDCC.lex"
-{ count(); return(UNION); }
- YY_BREAK
-case 47:
-YY_RULE_SETUP
-#line 138 "SDCC.lex"
-{ count(); return(UNSIGNED); }
- YY_BREAK
-case 48:
-YY_RULE_SETUP
-#line 139 "SDCC.lex"
-{ count(); return(VOID); }
- YY_BREAK
-case 49:
-YY_RULE_SETUP
-#line 140 "SDCC.lex"
-{ count(); return(VOLATILE); }
- YY_BREAK
-case 50:
-YY_RULE_SETUP
-#line 141 "SDCC.lex"
-{ count(); return(USING); }
- YY_BREAK
-case 51:
-YY_RULE_SETUP
-#line 142 "SDCC.lex"
-{ count(); return(WHILE); }
- YY_BREAK
-case 52:
-YY_RULE_SETUP
-#line 143 "SDCC.lex"
-{ count(); return(XDATA); }
- YY_BREAK
-case 53:
-YY_RULE_SETUP
-#line 144 "SDCC.lex"
-{ count(); return(_NEAR); }
- YY_BREAK
-case 54:
-YY_RULE_SETUP
-#line 145 "SDCC.lex"
-{ count(); return(_CODE); }
- YY_BREAK
-case 55:
-YY_RULE_SETUP
-#line 146 "SDCC.lex"
-{ count(); return(_GENERIC); }
- YY_BREAK
-case 56:
-YY_RULE_SETUP
-#line 147 "SDCC.lex"
-{ count(); return(_NEAR); }
- YY_BREAK
-case 57:
-YY_RULE_SETUP
-#line 148 "SDCC.lex"
-{ count(); return(_XDATA);}
- YY_BREAK
-case 58:
-YY_RULE_SETUP
-#line 149 "SDCC.lex"
-{ count () ; return(_PDATA); }
- YY_BREAK
-case 59:
-YY_RULE_SETUP
-#line 150 "SDCC.lex"
-{ count () ; return(_IDATA); }
- YY_BREAK
-case 60:
-YY_RULE_SETUP
-#line 151 "SDCC.lex"
-{ count(); return(VAR_ARGS);}
- YY_BREAK
-case 61:
-YY_RULE_SETUP
-#line 152 "SDCC.lex"
-{ count(); return(check_type()); }
- YY_BREAK
-case 62:
-YY_RULE_SETUP
-#line 153 "SDCC.lex"
-{ count(); yylval.val = constVal(yytext); return(CONSTANT); }
- YY_BREAK
-case 63:
-YY_RULE_SETUP
-#line 154 "SDCC.lex"
-{ count(); yylval.val = constVal(yytext); return(CONSTANT); }
- YY_BREAK
-case 64:
-YY_RULE_SETUP
-#line 155 "SDCC.lex"
-{ count(); yylval.val = constVal(yytext); return(CONSTANT); }
- YY_BREAK
-case 65:
-YY_RULE_SETUP
-#line 156 "SDCC.lex"
-{ count();yylval.val = charVal (yytext); return(CONSTANT); }
- YY_BREAK
-case 66:
-YY_RULE_SETUP
-#line 157 "SDCC.lex"
-{ count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
- YY_BREAK
-case 67:
-YY_RULE_SETUP
-#line 158 "SDCC.lex"
-{ count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
- YY_BREAK
-case 68:
-YY_RULE_SETUP
-#line 159 "SDCC.lex"
-{ count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
- YY_BREAK
-case 69:
-YY_RULE_SETUP
-#line 160 "SDCC.lex"
-{ count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
- YY_BREAK
-case 70:
-YY_RULE_SETUP
-#line 161 "SDCC.lex"
-{ count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
- YY_BREAK
-case 71:
-YY_RULE_SETUP
-#line 162 "SDCC.lex"
-{ count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
- YY_BREAK
-case 72:
-YY_RULE_SETUP
-#line 163 "SDCC.lex"
-{ count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
- YY_BREAK
-case 73:
-YY_RULE_SETUP
-#line 164 "SDCC.lex"
-{ count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
- YY_BREAK
-case 74:
-YY_RULE_SETUP
-#line 165 "SDCC.lex"
-{ count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
- YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 166 "SDCC.lex"
-{ count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
- YY_BREAK
-case 76:
-YY_RULE_SETUP
-#line 167 "SDCC.lex"
-{ count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
- YY_BREAK
-case 77:
-YY_RULE_SETUP
-#line 168 "SDCC.lex"
-{ count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
- YY_BREAK
-case 78:
-YY_RULE_SETUP
-#line 169 "SDCC.lex"
-{ count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
- YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 170 "SDCC.lex"
-{ count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
- YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 171 "SDCC.lex"
-{ count(); return(RIGHT_OP); }
- YY_BREAK
-case 81:
-YY_RULE_SETUP
-#line 172 "SDCC.lex"
-{ count(); return(LEFT_OP); }
- YY_BREAK
-case 82:
-YY_RULE_SETUP
-#line 173 "SDCC.lex"
-{ count(); return(INC_OP); }
- YY_BREAK
-case 83:
-YY_RULE_SETUP
-#line 174 "SDCC.lex"
-{ count(); return(DEC_OP); }
- YY_BREAK
-case 84:
-YY_RULE_SETUP
-#line 175 "SDCC.lex"
-{ count(); return(PTR_OP); }
- YY_BREAK
-case 85:
-YY_RULE_SETUP
-#line 176 "SDCC.lex"
-{ count(); return(AND_OP); }
- YY_BREAK
-case 86:
-YY_RULE_SETUP
-#line 177 "SDCC.lex"
-{ count(); return(OR_OP); }
- YY_BREAK
-case 87:
-YY_RULE_SETUP
-#line 178 "SDCC.lex"
-{ count(); return(LE_OP); }
- YY_BREAK
-case 88:
-YY_RULE_SETUP
-#line 179 "SDCC.lex"
-{ count(); return(GE_OP); }
- YY_BREAK
-case 89:
-YY_RULE_SETUP
-#line 180 "SDCC.lex"
-{ count(); return(EQ_OP); }
- YY_BREAK
-case 90:
-YY_RULE_SETUP
-#line 181 "SDCC.lex"
-{ count(); return(NE_OP); }
- YY_BREAK
-case 91:
-YY_RULE_SETUP
-#line 182 "SDCC.lex"
-{ count(); return(';'); }
- YY_BREAK
-case 92:
-YY_RULE_SETUP
-#line 183 "SDCC.lex"
-{ count() ; NestLevel++ ; return('{'); }
- YY_BREAK
-case 93:
-YY_RULE_SETUP
-#line 184 "SDCC.lex"
-{ count(); NestLevel--; return('}'); }
- YY_BREAK
-case 94:
-YY_RULE_SETUP
-#line 185 "SDCC.lex"
-{ count(); return(','); }
- YY_BREAK
-case 95:
-YY_RULE_SETUP
-#line 186 "SDCC.lex"
-{ count(); return(':'); }
- YY_BREAK
-case 96:
-YY_RULE_SETUP
-#line 187 "SDCC.lex"
-{ count(); return('='); }
- YY_BREAK
-case 97:
-YY_RULE_SETUP
-#line 188 "SDCC.lex"
-{ count(); return('('); }
- YY_BREAK
-case 98:
-YY_RULE_SETUP
-#line 189 "SDCC.lex"
-{ count(); return(')'); }
- YY_BREAK
-case 99:
-YY_RULE_SETUP
-#line 190 "SDCC.lex"
-{ count(); return('['); }
- YY_BREAK
-case 100:
-YY_RULE_SETUP
-#line 191 "SDCC.lex"
-{ count(); return(']'); }
- YY_BREAK
-case 101:
-YY_RULE_SETUP
-#line 192 "SDCC.lex"
-{ count(); return('.'); }
- YY_BREAK
-case 102:
-YY_RULE_SETUP
-#line 193 "SDCC.lex"
-{ count(); return('&'); }
- YY_BREAK
-case 103:
-YY_RULE_SETUP
-#line 194 "SDCC.lex"
-{ count(); return('!'); }
- YY_BREAK
-case 104:
-YY_RULE_SETUP
-#line 195 "SDCC.lex"
-{ count(); return('~'); }
- YY_BREAK
-case 105:
-YY_RULE_SETUP
-#line 196 "SDCC.lex"
-{ count(); return('-'); }
- YY_BREAK
-case 106:
-YY_RULE_SETUP
-#line 197 "SDCC.lex"
-{ count(); return('+'); }
- YY_BREAK
-case 107:
-YY_RULE_SETUP
-#line 198 "SDCC.lex"
-{ count(); return('*'); }
- YY_BREAK
-case 108:
-YY_RULE_SETUP
-#line 199 "SDCC.lex"
-{ count(); return('/'); }
- YY_BREAK
-case 109:
-YY_RULE_SETUP
-#line 200 "SDCC.lex"
-{ count(); return('%'); }
- YY_BREAK
-case 110:
-YY_RULE_SETUP
-#line 201 "SDCC.lex"
-{ count(); return('<'); }
- YY_BREAK
-case 111:
-YY_RULE_SETUP
-#line 202 "SDCC.lex"
-{ count(); return('>'); }
- YY_BREAK
-case 112:
-YY_RULE_SETUP
-#line 203 "SDCC.lex"
-{ count(); return('^'); }
- YY_BREAK
-case 113:
-YY_RULE_SETUP
-#line 204 "SDCC.lex"
-{ count(); return('|'); }
- YY_BREAK
-case 114:
-YY_RULE_SETUP
-#line 205 "SDCC.lex"
-{ count(); return('?'); }
- YY_BREAK
-case 115:
-YY_RULE_SETUP
-#line 206 "SDCC.lex"
-{ count(); checkCurrFile(yytext); }
- YY_BREAK
-case 116:
-YY_RULE_SETUP
-#line 207 "SDCC.lex"
-{ count(); process_pragma(yytext); }
- YY_BREAK
-case 117:
-YY_RULE_SETUP
-#line 209 "SDCC.lex"
-{ werror(E_PRE_PROC_FAILED,yytext);count(); }
- YY_BREAK
-case 118:
-YY_RULE_SETUP
-#line 210 "SDCC.lex"
-{ werror(W_PRE_PROC_WARNING,yytext);count(); }
- YY_BREAK
-case 119:
-YY_RULE_SETUP
-#line 211 "SDCC.lex"
-{ count(); }
- YY_BREAK
-case 120:
-YY_RULE_SETUP
-#line 212 "SDCC.lex"
-{ count(); }
- YY_BREAK
-case 121:
-YY_RULE_SETUP
-#line 213 "SDCC.lex"
-{ count(); }
- YY_BREAK
-case 122:
-YY_RULE_SETUP
-#line 214 "SDCC.lex"
-{ count() ; }
- YY_BREAK
-case 123:
-YY_RULE_SETUP
-#line 215 "SDCC.lex"
-ECHO;
- YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(asm):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between yy_current_buffer and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yy_current_buffer->yy_input_file = yyin;
- yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yy_c_buf_p;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yy_did_buffer_switch_on_eof = 0;
-
- if ( yywrap() )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p =
- yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yy_c_buf_p =
- &yy_current_buffer->yy_ch_buf[yy_n_chars];
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
- } /* end of yylex */
-
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-
-static int yy_get_next_buffer()
- {
- register char *dest = yy_current_buffer->yy_ch_buf;
- register char *source = yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( yy_current_buffer->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- yy_current_buffer->yy_n_chars = yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- yy_current_buffer->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-#ifdef YY_USES_REJECT
- YY_FATAL_ERROR(
-"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-#else
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = yy_current_buffer;
-
- int yy_c_buf_p_offset =
- (int) (yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yy_flex_realloc( (void *) b->yy_ch_buf,
- b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = yy_current_buffer->yy_buf_size -
- number_to_move - 1;
-#endif
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
- yy_n_chars, num_to_read );
-
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- if ( yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- yy_current_buffer->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- yy_n_chars += number_to_move;
- yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
-
- return ret_val;
- }
-
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-static yy_state_type yy_get_previous_state()
- {
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = yy_start;
- yy_current_state += YY_AT_BOL();
-
- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 767 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
- }
-
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
-
-#ifdef YY_USE_PROTOS
-static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
-#else
-static yy_state_type yy_try_NUL_trans( yy_current_state )
-yy_state_type yy_current_state;
-#endif
- {
- register int yy_is_jam;
- register char *yy_cp = yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 767 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 766);
-
- return yy_is_jam ? 0 : yy_current_state;
- }
-
-
-#ifndef YY_NO_UNPUT
-#ifdef YY_USE_PROTOS
-static void yyunput( int c, register char *yy_bp )
-#else
-static void yyunput( c, yy_bp )
-int c;
-register char *yy_bp;
-#endif
- {
- register char *yy_cp = yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yy_hold_char;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yy_n_chars + 2;
- register char *dest = &yy_current_buffer->yy_ch_buf[
- yy_current_buffer->yy_buf_size + 2];
- register char *source =
- &yy_current_buffer->yy_ch_buf[number_to_move];
-
- while ( source > yy_current_buffer->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- yy_current_buffer->yy_n_chars =
- yy_n_chars = yy_current_buffer->yy_buf_size;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
-
- yytext_ptr = yy_bp;
- yy_hold_char = *yy_cp;
- yy_c_buf_p = yy_cp;
- }
-#endif /* ifndef YY_NO_UNPUT */
-
-
-#ifdef __cplusplus
-static int yyinput()
-#else
-static int input()
-#endif
- {
- int c;
-
- *yy_c_buf_p = yy_hold_char;
-
- if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- /* This was really a NUL. */
- *yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yy_c_buf_p - yytext_ptr;
- ++yy_c_buf_p;
-
- switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart( yyin );
-
- /* fall through */
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap() )
- return EOF;
-
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p = yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
- *yy_c_buf_p = '\0'; /* preserve yytext */
- yy_hold_char = *++yy_c_buf_p;
-
- yy_current_buffer->yy_at_bol = (c == '\n');
-
- return c;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yyrestart( FILE *input_file )
-#else
-void yyrestart( input_file )
-FILE *input_file;
-#endif
- {
- if ( ! yy_current_buffer )
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_init_buffer( yy_current_buffer, input_file );
- yy_load_buffer_state();
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-#else
-void yy_switch_to_buffer( new_buffer )
-YY_BUFFER_STATE new_buffer;
-#endif
- {
- if ( yy_current_buffer == new_buffer )
- return;
-
- if ( yy_current_buffer )
- {
- /* Flush out information for old buffer. */
- *yy_c_buf_p = yy_hold_char;
- yy_current_buffer->yy_buf_pos = yy_c_buf_p;
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- yy_current_buffer = new_buffer;
- yy_load_buffer_state();
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yy_did_buffer_switch_on_eof = 1;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_load_buffer_state( void )
-#else
-void yy_load_buffer_state()
-#endif
- {
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
- yyin = yy_current_buffer->yy_input_file;
- yy_hold_char = *yy_c_buf_p;
- }
-
-
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-#else
-YY_BUFFER_STATE yy_create_buffer( file, size )
-FILE *file;
-int size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer( b, file );
-
- return b;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_delete_buffer( YY_BUFFER_STATE b )
-#else
-void yy_delete_buffer( b )
-YY_BUFFER_STATE b;
-#endif
- {
- if ( ! b )
- return;
-
- if ( b == yy_current_buffer )
- yy_current_buffer = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yy_flex_free( (void *) b->yy_ch_buf );
-
- yy_flex_free( (void *) b );
- }
-
-
-#ifndef YY_ALWAYS_INTERACTIVE
-#ifndef YY_NEVER_INTERACTIVE
-extern int isatty YY_PROTO(( int ));
-#endif
-#endif
-
-#ifdef YY_USE_PROTOS
-void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
-#else
-void yy_init_buffer( b, file )
-YY_BUFFER_STATE b;
-FILE *file;
-#endif
-
-
- {
- yy_flush_buffer( b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
-#if YY_ALWAYS_INTERACTIVE
- b->yy_is_interactive = 1;
-#else
-#if YY_NEVER_INTERACTIVE
- b->yy_is_interactive = 0;
-#else
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-#endif
-#endif
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_flush_buffer( YY_BUFFER_STATE b )
-#else
-void yy_flush_buffer( b )
-YY_BUFFER_STATE b;
-#endif
-
- {
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == yy_current_buffer )
- yy_load_buffer_state();
- }
-
-
-#ifndef YY_NO_SCAN_BUFFER
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
-#else
-YY_BUFFER_STATE yy_scan_buffer( base, size )
-char *base;
-yy_size_t size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer( b );
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_STRING
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
-#else
-YY_BUFFER_STATE yy_scan_string( yy_str )
-yyconst char *yy_str;
-#endif
- {
- int len;
- for ( len = 0; yy_str[len]; ++len )
- ;
-
- return yy_scan_bytes( yy_str, len );
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_BYTES
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
-#else
-YY_BUFFER_STATE yy_scan_bytes( bytes, len )
-yyconst char *bytes;
-int len;
-#endif
- {
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = len + 2;
- buf = (char *) yy_flex_alloc( n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
-
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer( buf, n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_PUSH_STATE
-#ifdef YY_USE_PROTOS
-static void yy_push_state( int new_state )
-#else
-static void yy_push_state( new_state )
-int new_state;
-#endif
- {
- if ( yy_start_stack_ptr >= yy_start_stack_depth )
- {
- yy_size_t new_size;
-
- yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yy_start_stack_depth * sizeof( int );
-
- if ( ! yy_start_stack )
- yy_start_stack = (int *) yy_flex_alloc( new_size );
-
- else
- yy_start_stack = (int *) yy_flex_realloc(
- (void *) yy_start_stack, new_size );
-
- if ( ! yy_start_stack )
- YY_FATAL_ERROR(
- "out of memory expanding start-condition stack" );
- }
-
- yy_start_stack[yy_start_stack_ptr++] = YY_START;
-
- BEGIN(new_state);
- }
-#endif
-
-
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
- {
- if ( --yy_start_stack_ptr < 0 )
- YY_FATAL_ERROR( "start-condition stack underflow" );
-
- BEGIN(yy_start_stack[yy_start_stack_ptr]);
- }
-#endif
-
-
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
- {
- return yy_start_stack[yy_start_stack_ptr - 1];
- }
-#endif
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
-#else
-static void yy_fatal_error( msg )
-char msg[];
-#endif
- {
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
- }
-
-
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- yytext[yyleng] = yy_hold_char; \
- yy_c_buf_p = yytext + n; \
- yy_hold_char = *yy_c_buf_p; \
- *yy_c_buf_p = '\0'; \
- yyleng = n; \
- } \
- while ( 0 )
-
-
-/* Internal utility routines. */
-
-#ifndef yytext_ptr
-#ifdef YY_USE_PROTOS
-static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
-#else
-static void yy_flex_strncpy( s1, s2, n )
-char *s1;
-yyconst char *s2;
-int n;
-#endif
- {
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
- }
-#endif
-
-#ifdef YY_NEED_STRLEN
-#ifdef YY_USE_PROTOS
-static int yy_flex_strlen( yyconst char *s )
-#else
-static int yy_flex_strlen( s )
-yyconst char *s;
-#endif
- {
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
- }
-#endif
-
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_alloc( yy_size_t size )
-#else
-static void *yy_flex_alloc( size )
-yy_size_t size;
-#endif
- {
- return (void *) malloc( size );
- }
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_realloc( void *ptr, yy_size_t size )
-#else
-static void *yy_flex_realloc( ptr, size )
-void *ptr;
-yy_size_t size;
-#endif
- {
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
- }
-
-#ifdef YY_USE_PROTOS
-static void yy_flex_free( void *ptr )
-#else
-static void yy_flex_free( ptr )
-void *ptr;
-#endif
- {
- free( ptr );
- }
-
-#if YY_MAIN
-int main()
- {
- yylex();
- return 0;
- }
-#endif
-#line 215 "SDCC.lex"
-
-
-int checkCurrFile ( char *s)
-{
- char lineNum[10] ;
- int lNum ;
- char *tptr ;
-
- /* first check if this is a #line */
- if ( strncmp(s,"#line",5) )
- return 0 ;
-
- /* get to the line number */
- while (!isdigit(*s))
- s++ ;
- tptr = lineNum ;
- while (isdigit(*s))
- *tptr++ = *s++ ;
- *tptr = '\0';
- sscanf(lineNum,"%d",&lNum);
-
- /* now see if we have a file name */
- while (*s != '\"' && *s)
- s++ ;
-
- /* if we don't have a filename then */
- /* set the current line number to */
- /* line number if printFlag is on */
- if (!*s) {
- yylineno = lNum ;
- return 0;
- }
-
- /* if we have a filename then check */
- /* if it is "standard in" if yes then */
- /* get the currentfile name info */
- s++ ;
-
- if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
- yylineno = lNum - 2;
- currFname = fullSrcFileName ;
- } else {
- char *sb = s;
- /* mark the end of the filename */
- while (*s != '"') s++;
- *s = '\0';
- ALLOC_ATOMIC(currFname,strlen(sb)+1);
- strcpy(currFname,sb);
- yylineno = lNum - 2;
- }
- filename = currFname ;
- return 0;
-}
-
-void comment()
-{
- char c, c1;
-
-loop:
- while ((c = input()) != '*' && c != 0)
- if ( c == '\n')
- yylineno++ ;
-
- if ((c1 = input()) != '/' && c != 0) {
- if ( c1 == '\n' )
- yylineno++ ;
-
- unput(c1);
- goto loop;
- }
-
-}
-
-
-
-int column = 0;
-int plineIdx=0;
-
-void count()
-{
- int i;
- for (i = 0; yytext[i] != '\0'; i++) {
- if (yytext[i] == '\n') {
- column = 0;
- lineno = ++yylineno ;
- }
- else
- if (yytext[i] == '\t')
- column += 8 - (column % 8);
- else
- column++;
- }
-
- /* ECHO; */
-}
-
-int check_type()
-{
- /* check if it is in the typedef table */
- if (findSym(TypedefTab,NULL,yytext)) {
- strcpy(yylval.yychar,yytext);
- return (TYPE_NAME) ;
- }
- else {
- strcpy (yylval.yychar,yytext);
- return(IDENTIFIER);
- }
-}
-
-char strLitBuff[2048] ;
-
-char *stringLiteral ()
-{
- int ch;
- char *str = strLitBuff ;
-
- *str++ = '\"' ;
- /* put into the buffer till we hit the */
- /* first \" */
- while (1) {
-
- ch = input() ;
- if (!ch) break ; /* end of input */
- /* if it is a \ then everything allowed */
- if (ch == '\\') {
- *str++ = ch ; /* backslash in place */
- *str++ = input() ; /* following char in place */
- continue ; /* carry on */
- }
-
- /* if new line we have a new line break */
- if (ch == '\n') break ;
-
- /* if this is a quote then we have work to do */
- /* find the next non whitespace character */
- /* if that is a double quote then carry on */
- if (ch == '\"') {
-
- while ((ch = input()) && isspace(ch)) ;
- if (!ch) break ;
- if (ch != '\"') {
- unput(ch) ;
- break ;
- }
-
- continue ;
- }
- *str++ = ch;
- }
- *str++ = '\"' ;
- *str = '\0';
- return strLitBuff ;
-}
-
-void doPragma (int op, char *cp)
-{
- switch (op) {
- case P_SAVE:
- memcpy(&save_options,&options,sizeof(options));
- memcpy(&save_optimize,&optimize,sizeof(optimize));
- break;
- case P_RESTORE:
- memcpy(&options,&save_options,sizeof(options));
- memcpy(&optimize,&save_optimize,sizeof(optimize));
- break;
- case P_NOINDUCTION:
- optimize.loopInduction = 0 ;
- break;
- case P_NOINVARIANT:
- optimize.loopInvariant = 0 ;
- break;
- case P_INDUCTION:
- optimize.loopInduction = 1 ;
- break;
- case P_STACKAUTO:
- options.stackAuto = 1;
- break;
- case P_NOJTBOUND:
- optimize.noJTabBoundary = 1;
- break;
- case P_NOGCSE:
- optimize.global_cse = 0;
- break;
- case P_NOOVERLAY:
- options.noOverlay = 1;
- break;
- case P_CALLEE_SAVES:
- {
- int i=0;
- /* append to the functions already listed
- in callee-saves */
- for (; options.calleeSaves[i] ;i++);
- parseWithComma(&options.calleeSaves[i],strdup(cp));
- }
- break;
- case P_EXCLUDE:
- parseWithComma(options.excludeRegs,strdup(cp));
- break;
- case P_LOOPREV:
- optimize.noLoopReverse = 1;
- break;
- }
-}
-
-int process_pragma(char *s)
-{
- char *cp ;
- /* find the pragma */
- while (strncmp(s,"#pragma",7))
- s++;
- s += 7;
-
- /* look for the directive */
- while(isspace(*s)) s++;
-
- cp = s;
- /* look for the end of the directive */
- while ((! isspace(*s)) &&
- (*s != '\n'))
- s++ ;
-
- /* now compare and do what needs to be done */
- if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
- doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
- doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
- doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
- doPragma (P_NOINVARIANT,NULL) ;
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
- doPragma (P_INDUCTION,NULL) ;
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
- doPragma (P_STACKAUTO,NULL);
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
- doPragma (P_NOJTBOUND,NULL);
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
- doPragma (P_NOGCSE,NULL);
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
- doPragma (P_NOOVERLAY,NULL);
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
- doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
- doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
- return 0;
- }
-
- if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
- doPragma(P_EXCLUDE,NULL);
- return 0;
- }
-
- werror(W_UNKNOWN_PRAGMA,cp);
- return 0;
-}
+++ /dev/null
-
-/* A Bison parser, made from SDCC.y
- by GNU Bison version 1.28 */
-
-#define YYBISON 1 /* Identify Bison output. */
-
-#define IDENTIFIER 257
-#define TYPE_NAME 258
-#define CONSTANT 259
-#define STRING_LITERAL 260
-#define SIZEOF 261
-#define PTR_OP 262
-#define INC_OP 263
-#define DEC_OP 264
-#define LEFT_OP 265
-#define RIGHT_OP 266
-#define LE_OP 267
-#define GE_OP 268
-#define EQ_OP 269
-#define NE_OP 270
-#define AND_OP 271
-#define OR_OP 272
-#define MUL_ASSIGN 273
-#define DIV_ASSIGN 274
-#define MOD_ASSIGN 275
-#define ADD_ASSIGN 276
-#define SUB_ASSIGN 277
-#define LEFT_ASSIGN 278
-#define RIGHT_ASSIGN 279
-#define AND_ASSIGN 280
-#define XOR_ASSIGN 281
-#define OR_ASSIGN 282
-#define TYPEDEF 283
-#define EXTERN 284
-#define STATIC 285
-#define AUTO 286
-#define REGISTER 287
-#define CODE 288
-#define INTERRUPT 289
-#define SFR 290
-#define AT 291
-#define SBIT 292
-#define REENTRANT 293
-#define USING 294
-#define XDATA 295
-#define DATA 296
-#define IDATA 297
-#define PDATA 298
-#define VAR_ARGS 299
-#define CRITICAL 300
-#define CHAR 301
-#define SHORT 302
-#define INT 303
-#define LONG 304
-#define SIGNED 305
-#define UNSIGNED 306
-#define FLOAT 307
-#define DOUBLE 308
-#define CONST 309
-#define VOLATILE 310
-#define VOID 311
-#define BIT 312
-#define STRUCT 313
-#define UNION 314
-#define ENUM 315
-#define ELIPSIS 316
-#define RANGE 317
-#define FAR 318
-#define _XDATA 319
-#define _CODE 320
-#define _GENERIC 321
-#define _NEAR 322
-#define _PDATA 323
-#define _IDATA 324
-#define CASE 325
-#define DEFAULT 326
-#define IF 327
-#define ELSE 328
-#define SWITCH 329
-#define WHILE 330
-#define DO 331
-#define FOR 332
-#define GOTO 333
-#define CONTINUE 334
-#define BREAK 335
-#define RETURN 336
-#define INLINEASM 337
-#define IFX 338
-#define ADDRESS_OF 339
-#define GET_VALUE_AT_ADDRESS 340
-#define SPIL 341
-#define UNSPIL 342
-#define GETHBIT 343
-#define BITWISEAND 344
-#define UNARYMINUS 345
-#define IPUSH 346
-#define IPOP 347
-#define PCALL 348
-#define ENDFUNCTION 349
-#define JUMPTABLE 350
-#define RRC 351
-#define RLC 352
-#define CAST 353
-#define CALL 354
-#define PARAM 355
-#define NULLOP 356
-#define BLOCK 357
-#define LABEL 358
-#define RECEIVE 359
-#define SEND 360
-
-#line 24 "SDCC.y"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "SDCCglobl.h"
-#include "SDCCsymt.h"
-#include "SDCChasht.h"
-#include "SDCCval.h"
-#include "SDCCmem.h"
-#include "SDCCast.h"
-extern int yyerror (char *);
-extern FILE *yyin;
-extern char srcLstFname[];
-int NestLevel = 0 ; /* current NestLevel */
-int stackPtr = 1 ; /* stack pointer */
-int xstackPtr = 0 ; /* xstack pointer */
-int reentrant = 0 ;
-int blockNo = 0 ; /* sequential block number */
-int currBlockno=0 ;
-extern int yylex();
-int yyparse(void);
-extern int noLineno ;
-char lbuff[1024]; /* local buffer */
-
-/* break & continue stacks */
-STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
-STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
-STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
-STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
-STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
-
-value *cenum = NULL ; /* current enumeration type chain*/
-
-
-#line 58 "SDCC.y"
-typedef union {
- symbol *sym ; /* symbol table pointer */
- structdef *sdef; /* structure definition */
- char yychar[SDCC_NAME_MAX+1];
- link *lnk ; /* declarator or specifier */
- int yyint; /* integer value returned */
- value *val ; /* for integer constant */
- initList *ilist; /* initial list */
- char yyinline[MAX_INLINEASM]; /* inlined assembler code */
- ast *asts; /* expression tree */
-} YYSTYPE;
-#include <stdio.h>
-
-#ifndef __cplusplus
-#ifndef __STDC__
-#define const
-#endif
-#endif
-
-
-
-#define YYFINAL 392
-#define YYFLAG -32768
-#define YYNTBASE 131
-
-#define YYTRANSLATE(x) ((unsigned)(x) <= 360 ? yytranslate[x] : 218)
-
-static const short yytranslate[] = { 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 118, 2, 2, 2, 120, 113, 2, 107,
- 108, 114, 115, 112, 116, 111, 119, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 126, 128, 121,
- 127, 122, 125, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 109, 2, 110, 123, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 129, 124, 130, 117, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 104, 105, 106
-};
-
-#if YYDEBUG != 0
-static const short yyprhs[] = { 0,
- 0, 2, 5, 7, 9, 12, 16, 18, 21, 24,
- 26, 28, 30, 32, 35, 37, 39, 41, 45, 47,
- 49, 54, 58, 63, 67, 71, 74, 77, 79, 83,
- 85, 88, 91, 94, 97, 102, 104, 106, 108, 110,
- 112, 114, 116, 121, 123, 127, 131, 135, 137, 141,
- 145, 147, 151, 155, 157, 161, 165, 169, 173, 175,
- 179, 183, 185, 189, 191, 195, 197, 201, 203, 207,
- 209, 213, 215, 221, 223, 227, 229, 231, 233, 235,
- 237, 239, 241, 243, 245, 247, 249, 251, 255, 257,
- 260, 264, 266, 269, 271, 274, 276, 280, 282, 286,
- 288, 290, 292, 294, 296, 299, 301, 305, 307, 309,
- 311, 313, 315, 317, 319, 321, 323, 325, 327, 329,
- 331, 333, 335, 337, 339, 341, 343, 345, 347, 349,
- 355, 358, 360, 362, 364, 365, 367, 369, 372, 376,
- 378, 382, 384, 387, 391, 396, 402, 405, 407, 411,
- 414, 417, 418, 420, 423, 425, 428, 430, 434, 438,
- 443, 447, 448, 454, 459, 461, 464, 467, 471, 474,
- 476, 478, 480, 482, 484, 486, 487, 489, 492, 494,
- 498, 500, 504, 506, 510, 512, 516, 519, 521, 523,
- 526, 528, 530, 533, 537, 540, 544, 548, 553, 556,
- 560, 564, 569, 571, 575, 580, 582, 586, 588, 590,
- 592, 594, 596, 598, 601, 605, 610, 614, 616, 618,
- 621, 625, 626, 631, 632, 638, 641, 643, 646, 648,
- 651, 653, 656, 659, 660, 667, 668, 675, 677, 679,
- 681, 687, 695, 705, 706, 708, 712, 715, 718, 721,
- 725
-};
-
-static const short yyrhs[] = { 132,
- 0, 131, 132, 0, 133, 0, 159, 0, 180, 136,
- 0, 160, 180, 136, 0, 135, 0, 135, 134, 0,
- 40, 5, 0, 39, 0, 46, 0, 164, 0, 202,
- 0, 205, 202, 0, 217, 0, 5, 0, 138, 0,
- 107, 157, 108, 0, 6, 0, 137, 0, 139, 109,
- 157, 110, 0, 139, 107, 108, 0, 139, 107, 140,
- 108, 0, 139, 111, 217, 0, 139, 8, 217, 0,
- 139, 9, 0, 139, 10, 0, 155, 0, 155, 112,
- 140, 0, 139, 0, 9, 141, 0, 10, 141, 0,
- 142, 143, 0, 7, 141, 0, 7, 107, 193, 108,
- 0, 113, 0, 114, 0, 115, 0, 116, 0, 117,
- 0, 118, 0, 141, 0, 107, 193, 108, 143, 0,
- 143, 0, 144, 114, 143, 0, 144, 119, 143, 0,
- 144, 120, 143, 0, 144, 0, 145, 115, 144, 0,
- 145, 116, 144, 0, 145, 0, 146, 11, 145, 0,
- 146, 12, 145, 0, 146, 0, 147, 121, 146, 0,
- 147, 122, 146, 0, 147, 13, 146, 0, 147, 14,
- 146, 0, 147, 0, 148, 15, 147, 0, 148, 16,
- 147, 0, 148, 0, 149, 113, 148, 0, 149, 0,
- 150, 123, 149, 0, 150, 0, 151, 124, 150, 0,
- 151, 0, 152, 17, 151, 0, 152, 0, 153, 18,
- 152, 0, 153, 0, 153, 125, 153, 126, 154, 0,
- 154, 0, 141, 156, 155, 0, 127, 0, 19, 0,
- 20, 0, 21, 0, 22, 0, 23, 0, 24, 0,
- 25, 0, 26, 0, 27, 0, 28, 0, 155, 0,
- 157, 112, 155, 0, 154, 0, 160, 128, 0, 160,
- 161, 128, 0, 163, 0, 163, 160, 0, 165, 0,
- 165, 160, 0, 162, 0, 161, 112, 162, 0, 180,
- 0, 180, 127, 196, 0, 29, 0, 30, 0, 31,
- 0, 32, 0, 33, 0, 35, 5, 0, 166, 0,
- 166, 37, 5, 0, 47, 0, 48, 0, 49, 0,
- 50, 0, 51, 0, 52, 0, 57, 0, 55, 0,
- 56, 0, 53, 0, 41, 0, 34, 0, 42, 0,
- 43, 0, 44, 0, 58, 0, 168, 0, 176, 0,
- 4, 0, 167, 0, 38, 0, 36, 0, 169, 170,
- 129, 172, 130, 0, 169, 171, 0, 59, 0, 60,
- 0, 171, 0, 0, 217, 0, 173, 0, 172, 173,
- 0, 187, 174, 128, 0, 175, 0, 174, 112, 175,
- 0, 180, 0, 126, 158, 0, 180, 126, 158, 0,
- 61, 129, 177, 130, 0, 61, 217, 129, 177, 130,
- 0, 61, 217, 0, 178, 0, 177, 112, 178, 0,
- 217, 179, 0, 127, 158, 0, 0, 181, 0, 184,
- 181, 0, 182, 0, 182, 134, 0, 217, 0, 107,
- 180, 108, 0, 182, 109, 110, 0, 182, 109, 158,
- 110, 0, 182, 107, 108, 0, 0, 182, 107, 183,
- 190, 108, 0, 182, 107, 188, 108, 0, 185, 0,
- 185, 187, 0, 185, 184, 0, 185, 187, 184, 0,
- 186, 114, 0, 65, 0, 66, 0, 69, 0, 70,
- 0, 68, 0, 67, 0, 0, 165, 0, 187, 165,
- 0, 189, 0, 189, 112, 62, 0, 217, 0, 189,
- 112, 217, 0, 191, 0, 191, 112, 45, 0, 192,
- 0, 191, 112, 192, 0, 187, 180, 0, 193, 0,
- 187, 0, 187, 194, 0, 184, 0, 195, 0, 184,
- 195, 0, 107, 194, 108, 0, 109, 110, 0, 109,
- 158, 110, 0, 195, 109, 110, 0, 195, 109, 158,
- 110, 0, 107, 108, 0, 107, 190, 108, 0, 195,
- 107, 108, 0, 195, 107, 190, 108, 0, 155, 0,
- 129, 197, 130, 0, 129, 197, 112, 130, 0, 196,
- 0, 197, 112, 196, 0, 199, 0, 202, 0, 207,
- 0, 209, 0, 214, 0, 216, 0, 83, 128, 0,
- 217, 126, 198, 0, 71, 158, 126, 198, 0, 72,
- 126, 198, 0, 129, 0, 130, 0, 200, 201, 0,
- 200, 206, 201, 0, 0, 200, 205, 203, 201, 0,
- 0, 200, 205, 204, 206, 201, 0, 1, 128, 0,
- 159, 0, 205, 159, 0, 198, 0, 206, 198, 0,
- 128, 0, 157, 128, 0, 74, 198, 0, 0, 73,
- 107, 157, 108, 198, 208, 0, 0, 75, 107, 157,
- 108, 210, 198, 0, 76, 0, 77, 0, 78, 0,
- 211, 107, 157, 108, 198, 0, 212, 198, 76, 107,
- 157, 108, 128, 0, 213, 107, 215, 128, 215, 128,
- 215, 108, 198, 0, 0, 157, 0, 79, 217, 128,
- 0, 80, 128, 0, 81, 128, 0, 82, 128, 0,
- 82, 157, 128, 0, 3, 0
-};
-
-#endif
-
-#if YYDEBUG != 0
-static const short yyrline[] = { 0,
- 120, 121, 125, 126, 134, 139, 148, 149, 153, 159,
- 163, 167, 177, 178, 186, 187, 188, 189, 193, 197,
- 198, 199, 201, 205, 212, 218, 220, 225, 226, 230,
- 231, 232, 233, 234, 235, 239, 240, 241, 242, 243,
- 244, 248, 249, 253, 254, 255, 256, 260, 261, 262,
- 266, 267, 268, 272, 273, 274, 275, 284, 296, 297,
- 298, 311, 312, 316, 317, 321, 322, 326, 327, 332,
- 333, 338, 339, 347, 348, 390, 391, 392, 393, 394,
- 395, 396, 397, 398, 399, 400, 404, 405, 409, 413,
- 414, 431, 432, 445, 446, 462, 463, 467, 468, 473,
- 478, 483, 488, 493, 501, 505, 506, 516, 521, 527,
- 532, 538, 543, 548, 553, 559, 564, 569, 574, 579,
- 584, 589, 594, 603, 604, 608, 617, 621, 627, 637,
- 652, 662, 663, 667, 668, 676, 687, 688, 700, 720,
- 721, 729, 730, 734, 741, 746, 762, 779, 780, 787,
- 799, 805, 818, 819, 827, 828, 832, 833, 834, 843,
- 859, 860, 860, 873, 884, 885, 890, 895, 927, 938,
- 939, 940, 941, 942, 943, 944, 948, 949, 953, 954,
- 958, 959, 967, 968, 972, 973, 981, 990, 998, 999,
- 1011, 1012, 1013, 1017, 1018, 1023, 1029, 1035, 1043, 1044,
- 1045, 1046, 1050, 1051, 1052, 1056, 1057, 1061, 1062, 1063,
- 1064, 1065, 1066, 1067, 1076, 1077, 1078, 1081, 1084, 1088,
- 1089, 1090, 1092, 1093, 1096, 1097, 1101, 1112, 1136, 1137,
- 1141, 1142, 1146, 1147, 1152, 1153, 1168, 1176, 1189, 1202,
- 1220, 1228, 1236, 1264, 1265, 1269, 1274, 1287, 1297, 1298,
- 1302
-};
-#endif
-
-
-#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
-
-static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER",
-"TYPE_NAME","CONSTANT","STRING_LITERAL","SIZEOF","PTR_OP","INC_OP","DEC_OP",
-"LEFT_OP","RIGHT_OP","LE_OP","GE_OP","EQ_OP","NE_OP","AND_OP","OR_OP","MUL_ASSIGN",
-"DIV_ASSIGN","MOD_ASSIGN","ADD_ASSIGN","SUB_ASSIGN","LEFT_ASSIGN","RIGHT_ASSIGN",
-"AND_ASSIGN","XOR_ASSIGN","OR_ASSIGN","TYPEDEF","EXTERN","STATIC","AUTO","REGISTER",
-"CODE","INTERRUPT","SFR","AT","SBIT","REENTRANT","USING","XDATA","DATA","IDATA",
-"PDATA","VAR_ARGS","CRITICAL","CHAR","SHORT","INT","LONG","SIGNED","UNSIGNED",
-"FLOAT","DOUBLE","CONST","VOLATILE","VOID","BIT","STRUCT","UNION","ENUM","ELIPSIS",
-"RANGE","FAR","_XDATA","_CODE","_GENERIC","_NEAR","_PDATA","_IDATA","CASE","DEFAULT",
-"IF","ELSE","SWITCH","WHILE","DO","FOR","GOTO","CONTINUE","BREAK","RETURN","INLINEASM",
-"IFX","ADDRESS_OF","GET_VALUE_AT_ADDRESS","SPIL","UNSPIL","GETHBIT","BITWISEAND",
-"UNARYMINUS","IPUSH","IPOP","PCALL","ENDFUNCTION","JUMPTABLE","RRC","RLC","CAST",
-"CALL","PARAM","NULLOP","BLOCK","LABEL","RECEIVE","SEND","'('","')'","'['","']'",
-"'.'","','","'&'","'*'","'+'","'-'","'~'","'!'","'/'","'%'","'<'","'>'","'^'",
-"'|'","'?'","':'","'='","';'","'{'","'}'","file","external_definition","function_definition",
-"using_reentrant","using_reentrant_interrupt","function_body","primary_expr",
-"string_literal","postfix_expr","argument_expr_list","unary_expr","unary_operator",
-"cast_expr","multiplicative_expr","additive_expr","shift_expr","relational_expr",
-"equality_expr","and_expr","exclusive_or_expr","inclusive_or_expr","logical_and_expr",
-"logical_or_expr","conditional_expr","assignment_expr","assignment_operator",
-"expr","constant_expr","declaration","declaration_specifiers","init_declarator_list",
-"init_declarator","storage_class_specifier","Interrupt_storage","type_specifier",
-"type_specifier2","sfr_reg_bit","struct_or_union_specifier","struct_or_union",
-"opt_stag","stag","struct_declaration_list","struct_declaration","struct_declarator_list",
-"struct_declarator","enum_specifier","enumerator_list","enumerator","opt_assign_expr",
-"declarator","declarator2_using_reentrant","declarator2","@1","pointer","far_near_pointer",
-"far_near","type_specifier_list","parameter_identifier_list","identifier_list",
-"parameter_type_list","parameter_list","parameter_declaration","type_name","abstract_declarator",
-"abstract_declarator2","initializer","initializer_list","statement","labeled_statement",
-"start_block","end_block","compound_statement","@2","@3","declaration_list",
-"statement_list","expression_statement","else_statement","selection_statement",
-"@4","while","do","for","iteration_statement","expr_opt","jump_statement","identifier", NULL
-};
-#endif
-
-static const short yyr1[] = { 0,
- 131, 131, 132, 132, 133, 133, 134, 134, 135, 135,
- 135, 135, 136, 136, 137, 137, 137, 137, 138, 139,
- 139, 139, 139, 139, 139, 139, 139, 140, 140, 141,
- 141, 141, 141, 141, 141, 142, 142, 142, 142, 142,
- 142, 143, 143, 144, 144, 144, 144, 145, 145, 145,
- 146, 146, 146, 147, 147, 147, 147, 147, 148, 148,
- 148, 149, 149, 150, 150, 151, 151, 152, 152, 153,
- 153, 154, 154, 155, 155, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 157, 157, 158, 159,
- 159, 160, 160, 160, 160, 161, 161, 162, 162, 163,
- 163, 163, 163, 163, 164, 165, 165, 166, 166, 166,
- 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
- 166, 166, 166, 166, 166, 166, 166, 167, 167, 168,
- 168, 169, 169, 170, 170, 171, 172, 172, 173, 174,
- 174, 175, 175, 175, 176, 176, 176, 177, 177, 178,
- 179, 179, 180, 180, 181, 181, 182, 182, 182, 182,
- 182, 183, 182, 182, 184, 184, 184, 184, 185, 186,
- 186, 186, 186, 186, 186, 186, 187, 187, 188, 188,
- 189, 189, 190, 190, 191, 191, 192, 192, 193, 193,
- 194, 194, 194, 195, 195, 195, 195, 195, 195, 195,
- 195, 195, 196, 196, 196, 197, 197, 198, 198, 198,
- 198, 198, 198, 198, 199, 199, 199, 200, 201, 202,
- 202, 203, 202, 204, 202, 202, 205, 205, 206, 206,
- 207, 207, 208, 208, 209, 210, 209, 211, 212, 213,
- 214, 214, 214, 215, 215, 216, 216, 216, 216, 216,
- 217
-};
-
-static const short yyr2[] = { 0,
- 1, 2, 1, 1, 2, 3, 1, 2, 2, 1,
- 1, 1, 1, 2, 1, 1, 1, 3, 1, 1,
- 4, 3, 4, 3, 3, 2, 2, 1, 3, 1,
- 2, 2, 2, 2, 4, 1, 1, 1, 1, 1,
- 1, 1, 4, 1, 3, 3, 3, 1, 3, 3,
- 1, 3, 3, 1, 3, 3, 3, 3, 1, 3,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 5, 1, 3, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 1, 2,
- 3, 1, 2, 1, 2, 1, 3, 1, 3, 1,
- 1, 1, 1, 1, 2, 1, 3, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 5,
- 2, 1, 1, 1, 0, 1, 1, 2, 3, 1,
- 3, 1, 2, 3, 4, 5, 2, 1, 3, 2,
- 2, 0, 1, 2, 1, 2, 1, 3, 3, 4,
- 3, 0, 5, 4, 1, 2, 2, 3, 2, 1,
- 1, 1, 1, 1, 1, 0, 1, 2, 1, 3,
- 1, 3, 1, 3, 1, 3, 2, 1, 1, 2,
- 1, 1, 2, 3, 2, 3, 3, 4, 2, 3,
- 3, 4, 1, 3, 4, 1, 3, 1, 1, 1,
- 1, 1, 1, 2, 3, 4, 3, 1, 1, 2,
- 3, 0, 4, 0, 5, 2, 1, 2, 1, 2,
- 1, 2, 2, 0, 6, 0, 6, 1, 1, 1,
- 5, 7, 9, 0, 1, 3, 2, 2, 2, 3,
- 1
-};
-
-static const short yydefact[] = { 176,
- 251, 126, 100, 101, 102, 103, 104, 119, 129, 128,
- 118, 120, 121, 122, 108, 109, 110, 111, 112, 113,
- 117, 115, 116, 114, 123, 132, 133, 0, 170, 171,
- 175, 174, 172, 173, 176, 176, 1, 3, 4, 176,
- 92, 94, 106, 127, 124, 135, 125, 0, 153, 155,
- 0, 165, 0, 157, 0, 147, 0, 2, 90, 0,
- 96, 0, 93, 95, 0, 0, 131, 136, 0, 218,
- 5, 227, 176, 0, 13, 0, 0, 10, 0, 11,
- 162, 0, 156, 7, 12, 154, 177, 167, 166, 169,
- 0, 148, 152, 0, 158, 176, 91, 0, 6, 107,
- 0, 226, 98, 16, 19, 0, 0, 0, 0, 0,
- 0, 0, 238, 239, 240, 0, 0, 0, 0, 0,
- 0, 36, 37, 38, 39, 40, 41, 231, 219, 20,
- 17, 30, 42, 0, 44, 48, 51, 54, 59, 62,
- 64, 66, 68, 70, 72, 74, 87, 0, 229, 208,
- 220, 209, 224, 0, 210, 211, 0, 0, 0, 212,
- 213, 15, 228, 14, 105, 9, 161, 0, 0, 179,
- 181, 159, 42, 89, 0, 15, 8, 178, 168, 0,
- 145, 0, 150, 0, 97, 0, 203, 99, 0, 137,
- 176, 0, 34, 0, 31, 32, 0, 0, 0, 0,
- 0, 247, 248, 249, 0, 214, 0, 176, 0, 0,
- 26, 27, 0, 0, 0, 77, 78, 79, 80, 81,
- 82, 83, 84, 85, 86, 76, 0, 33, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 232, 0,
- 0, 230, 221, 0, 0, 244, 0, 189, 0, 183,
- 185, 188, 164, 0, 160, 149, 151, 146, 206, 0,
- 130, 138, 0, 0, 140, 142, 0, 0, 217, 0,
- 0, 246, 250, 18, 176, 0, 191, 190, 192, 0,
- 25, 22, 0, 28, 0, 24, 75, 45, 46, 47,
- 49, 50, 52, 53, 57, 58, 55, 56, 60, 61,
- 63, 65, 67, 69, 71, 0, 88, 223, 0, 0,
- 0, 245, 0, 215, 176, 187, 191, 163, 0, 180,
- 182, 0, 204, 143, 176, 139, 0, 35, 216, 0,
- 236, 199, 0, 0, 195, 0, 193, 0, 0, 43,
- 23, 0, 21, 0, 225, 0, 0, 244, 184, 186,
- 205, 207, 141, 144, 234, 0, 200, 194, 196, 201,
- 0, 197, 0, 29, 73, 241, 0, 0, 0, 235,
- 237, 202, 198, 0, 244, 233, 242, 0, 0, 243,
- 0, 0
-};
-
-static const short yydefgoto[] = { 36,
- 37, 38, 83, 84, 71, 130, 131, 132, 293, 133,
- 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 227, 148, 175, 72, 73, 60,
- 61, 41, 85, 87, 43, 44, 45, 46, 66, 67,
- 189, 190, 274, 275, 47, 91, 92, 183, 48, 49,
- 50, 168, 51, 52, 53, 258, 169, 170, 343, 260,
- 261, 262, 288, 289, 188, 270, 149, 150, 74, 151,
- 152, 250, 251, 76, 154, 155, 380, 156, 366, 157,
- 158, 159, 160, 323, 161, 176
-};
-
-static const short yypact[] = { 1568,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768, 11,-32768,-32768,
--32768,-32768,-32768,-32768, 317, 1267,-32768,-32768,-32768, 53,
- 1610, 1610, -7,-32768,-32768, 19,-32768, 634,-32768, 165,
- 30, 1193, -26,-32768, 19, 21, 45,-32768,-32768, -33,
--32768, 598,-32768,-32768, 173, 55, 58,-32768, 62,-32768,
--32768,-32768, 53, 412,-32768, 634, 189,-32768, 191,-32768,
- 24, 906,-32768, 126,-32768,-32768,-32768,-32768, 1193,-32768,
- -93,-32768, 70, 19,-32768, 317,-32768, 430,-32768,-32768,
- 1452,-32768, 72,-32768,-32768, 987, 1022, 1022, 1034, 76,
- 100, 102,-32768,-32768,-32768, 19, 84, 92, 776, 93,
- 892,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, 40, 348, 1034,-32768, -44, -15, 46, 12, 129,
- 110, 105, 101, 212, 16,-32768,-32768, -25,-32768,-32768,
--32768,-32768, 699, 496,-32768,-32768, 123, 695, 125,-32768,
--32768, 108,-32768,-32768,-32768,-32768,-32768, 1452, 136, 134,
--32768,-32768,-32768,-32768, 137,-32768,-32768,-32768,-32768, 19,
--32768, 1034,-32768, -69,-32768, 430,-32768,-32768, 784,-32768,
- 812, 892,-32768, 1034,-32768,-32768, 122, 695, 1034, 1034,
- 124,-32768,-32768,-32768, 27,-32768, 2, 1411, 145, 19,
--32768,-32768, 951, 1034, 19,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768, 1034,-32768, 1034, 1034,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,-32768, 130,
- 695,-32768,-32768, 1034, 178, 1034, 695, 1119, 147, 149,
--32768,-32768,-32768, 18,-32768,-32768,-32768,-32768,-32768, -58,
--32768,-32768, 1034, 31,-32768, 139, 154, 695,-32768, 63,
- 65,-32768,-32768,-32768, 1487, 963, -62,-32768, 4, 1034,
--32768,-32768, 158, 163, 52,-32768,-32768,-32768,-32768,-32768,
- -44, -44, -15, -15, 46, 46, 46, 46, 12, 12,
- 129, 110, 105, 101, 212, -2,-32768,-32768, 496, 71,
- 166, 170, 155,-32768, 1335,-32768, 29,-32768, 1376,-32768,
--32768, 232,-32768,-32768, 60,-32768, 1034,-32768,-32768, 695,
--32768,-32768, 177, 179,-32768, 176, 4, 1160, 975,-32768,
--32768, 1034,-32768, 1034,-32768, 695, 1034, 1034,-32768,-32768,
--32768,-32768,-32768,-32768, 214, 695,-32768,-32768,-32768,-32768,
- 181,-32768, 180,-32768,-32768,-32768, 77, 164, 695,-32768,
--32768,-32768,-32768, 168, 1034,-32768,-32768, 185, 695,-32768,
- 294,-32768
-};
-
-static const short yypgoto[] = {-32768,
- 261,-32768, 215,-32768, 236,-32768,-32768,-32768, -50, 161,
--32768, -122, -165, -42, -20, -14, 61, 64, 67, 59,
- 66, 68, -78, -96,-32768, -108, -104, 17, 41,-32768,
- 209,-32768,-32768, 23,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, 117,-32768, -27,-32768, 219, 138,-32768, -34, -48,
--32768,-32768, -45,-32768,-32768, 14,-32768,-32768, -160,-32768,
- -13, -103, -265, -258, -176,-32768, -56,-32768,-32768, -145,
- -24,-32768,-32768, 235, 73,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768, -343,-32768, 0
-};
-
-
-#define YYLAST 1675
-
-
-static const short yytable[] = { 54,
- 57, 187, 86, 174, 197, 62, 88, 259, 253, 269,
- 205, 228, 207, 1, 378, 246, 39, 209, 180, 344,
- 1, 1, 42, 75, 236, 237, 1, 56, 347, 65,
- 174, 1, 1, 246, 54, 54, 181, 75, 103, 54,
- 40, 388, 180, 179, 285, 68, 286, 210, 211, 212,
- 54, 164, 39, 332, 93, 1, 234, 235, 42, 344,
- 268, 103, 1, 42, 42, 89, 301, 302, 347, 229,
- 42, 333, 54, 162, 230, 231, 40, 267, 96, 330,
- 171, 63, 64, 207, 42, 207, 248, 90, 277, 187,
- 280, 281, 163, 93, 97, 54, 42, 252, 42, 232,
- 233, 255, 249, 174, 318, 295, 298, 299, 300, 284,
- 348, 178, 349, 248, 191, 201, 294, 29, 30, 31,
- 32, 33, 34, 354, 29, 30, 31, 32, 33, 34,
- 297, 167, 238, 239, 208, 325, 35, 286, 248, 55,
- 247, 279, 335, 240, 241, 320, 213, 322, 214, 94,
- 215, 317, 95, 162, 283, 362, 276, 162, 336, 35,
- 77, 353, 287, 248, 78, 79, 35, 350, 334, 163,
- 340, 80, 341, 355, 248, 42, 248, 100, 356, 93,
- 59, 346, 248, 101, 384, 273, -134, 371, 248, 102,
- 54, 303, 304, 165, 174, 166, 182, 162, 98, 77,
- 324, 198, 191, 78, 79, 208, 199, 174, 200, 291,
- 80, 202, 327, 178, 296, 305, 306, 307, 308, 203,
- 206, 339, 242, 326, 244, 309, 310, 243, 245, 254,
- 178, 256, 364, 257, 1, 187, 104, 105, 106, 287,
- 107, 108, 173, 263, 373, 264, 265, 278, 377, 322,
- 162, 282, 290, 321, 328, 294, 162, 54, 174, 129,
- 329, 338, 252, 331, 337, 351, 193, 195, 196, 173,
- 174, 81, 357, 82, 352, 375, 322, 162, 86, 327,
- 178, 248, 358, 365, 367, 369, 368, 379, 382, 383,
- 57, 385, 389, 392, 173, 387, 58, 99, 177, 376,
- 276, 374, 311, 314, 185, 272, 312, 363, 153, 381,
- 313, 315, 184, 0, 316, 360, 0, 266, 162, 1,
- 0, 0, 386, 319, 54, 0, 54, 0, 0, 0,
- 0, 0, 390, 0, 54, 0, 0, 0, 121, 162,
- 0, 0, 173, 0, 122, 123, 124, 125, 126, 127,
- 0, 0, 0, 0, 0, 162, 0, 0, 0, 0,
- 186, 361, 0, 0, 0, 162, 216, 217, 218, 219,
- 220, 221, 222, 223, 224, 225, 0, 0, 162, 0,
- 0, 29, 30, 31, 32, 33, 34, 0, 162, 173,
- 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 173, 173, 173, 173, 0, 0,
- 0, 0, 69, 0, 1, 2, 104, 105, 106, 0,
- 107, 108, 0, 35, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 173, 104, 105, 106, 0, 107, 108,
- 3, 4, 5, 6, 7, 8, 173, 9, 0, 10,
- 173, 0, 11, 12, 13, 14, 0, 0, 15, 16,
- 17, 18, 19, 20, 21, 0, 22, 23, 24, 25,
- 26, 27, 28, 0, 226, 0, 0, 0, 0, 0,
- 0, 0, 109, 110, 111, 0, 112, 113, 114, 115,
- 116, 117, 118, 119, 120, 0, 69, 173, 1, 0,
- 104, 105, 106, 0, 107, 108, 0, 0, 0, 173,
- 0, 0, 0, 0, 173, 0, 0, 0, 121, 0,
- 0, 0, 0, 0, 122, 123, 124, 125, 126, 127,
- 0, 0, 0, 0, 0, 0, 121, 0, 0, 128,
- 70, 129, 122, 123, 124, 125, 126, 127, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 186, 0,
- 0, 0, 0, 0, 0, 0, 109, 110, 111, 0,
- 112, 113, 114, 115, 116, 117, 118, 119, 120, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 69, 0,
- 0, 2, 121, 0, 0, 0, 0, 0, 122, 123,
- 124, 125, 126, 127, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 128, 70, 129, 3, 4, 5, 6,
- 7, 8, 0, 9, 69, 10, 0, 2, 11, 12,
- 13, 14, 0, 0, 15, 16, 17, 18, 19, 20,
- 21, 0, 22, 23, 24, 25, 26, 27, 28, 0,
- 0, 0, 3, 4, 5, 6, 7, 8, 0, 9,
- 0, 10, 0, 0, 11, 12, 13, 14, 0, 0,
- 15, 16, 17, 18, 19, 20, 21, 0, 22, 23,
- 24, 25, 26, 27, 28, 69, 0, 1, 0, 104,
- 105, 106, 2, 107, 108, 0, 0, 0, 0, -98,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 98, -98, 70, 3, 4, 5,
- 6, 7, 8, 0, 9, 0, 10, 0, 0, 11,
- 12, 13, 14, 0, 0, 15, 16, 17, 18, 19,
- 20, 21, 0, 22, 23, 24, 25, 26, 27, 28,
- 0, 0, 70, 0, 0, 109, 110, 111, 0, 112,
- 113, 114, 115, 116, 117, 118, 119, 120, 1, 0,
- 104, 105, 106, 0, 107, 108, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 121, 0, 0, 0, 0, 0, 122, 123, 124,
- 125, 126, 127, 0, 1, 2, 0, 8, 0, 9,
- 0, 10, 128, 70, 11, 12, 13, 14, -222, 0,
- 15, 16, 17, 18, 19, 20, 21, 0, 22, 23,
- 24, 25, 26, 27, 28, 8, 0, 9, 0, 10,
- 0, 0, 11, 12, 13, 14, 0, 0, 15, 16,
- 17, 18, 19, 20, 21, 0, 22, 23, 24, 25,
- 26, 27, 28, 0, 0, 0, 29, 30, 31, 32,
- 33, 34, 121, 0, 0, 0, 0, 0, 122, 123,
- 124, 125, 126, 127, 1, 2, 104, 105, 106, 0,
- 107, 108, 0, 204, 0, 0, 0, 0, 1, 0,
- 104, 105, 106, 271, 107, 108, 0, 0, 35, 0,
- 0, 0, 0, 0, 0, 8, 0, 9, 0, 10,
- 0, 0, 11, 12, 13, 14, 0, 273, 15, 16,
- 17, 18, 19, 20, 21, 0, 22, 23, 24, 25,
- 26, 27, 28, 1, 0, 104, 105, 106, 0, 107,
- 108, 0, 0, 0, 0, 1, 0, 104, 105, 106,
- 0, 107, 108, 0, 0, 0, 0, 1, 0, 104,
- 105, 106, 0, 107, 108, 0, 0, 0, 0, 1,
- 0, 104, 105, 106, 0, 107, 108, 0, 121, 0,
- 0, 0, 0, 0, 122, 123, 124, 125, 126, 127,
- 0, 0, 121, 0, 0, 172, 0, 0, 122, 123,
- 124, 125, 126, 127, 1, 0, 104, 105, 106, 0,
- 107, 108, 0, 0, 0, 0, 1, 0, 104, 105,
- 106, 0, 107, 108, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 121, 292, 0,
- 0, 0, 0, 122, 123, 124, 125, 126, 127, 121,
- 0, 0, 345, 0, 0, 122, 123, 124, 125, 126,
- 127, 121, 0, 0, 372, 0, 0, 122, 123, 124,
- 125, 126, 127, 192, 0, 0, 0, 0, 0, 122,
- 123, 124, 125, 126, 127, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 2, 0, 0, 0, 0, 0, 194, 0,
- 0, 0, 0, 0, 122, 123, 124, 125, 126, 127,
- 121, 0, 0, 0, 0, 0, 122, 123, 124, 125,
- 126, 127, 8, 0, 9, 0, 10, 0, 0, 11,
- 12, 13, 14, 2, 0, 15, 16, 17, 18, 19,
- 20, 21, 0, 22, 23, 24, 25, 26, 27, 28,
- 0, 0, 0, 29, 30, 31, 32, 33, 34, 0,
- 0, 0, 0, 8, 0, 9, 2, 10, 0, 0,
- 11, 12, 13, 14, 0, 0, 15, 16, 17, 18,
- 19, 20, 21, 0, 22, 23, 24, 25, 26, 27,
- 28, 0, 0, 0, 0, 325, 8, 286, 9, 0,
- 10, 0, -176, 11, 12, 13, 14, 0, 0, 15,
- 16, 17, 18, 19, 20, 21, 0, 22, 23, 24,
- 25, 26, 27, 28, 0, 0, 0, 29, 30, 31,
- 32, 33, 34, 0, 0, 0, 391, 370, 0, 1,
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 3, 4, 5, 6, 7,
- 8, 0, 9, 0, 10, 0, -176, 11, 12, 13,
- 14, 0, 0, 15, 16, 17, 18, 19, 20, 21,
- 0, 22, 23, 24, 25, 26, 27, 28, 0, 0,
- 0, 29, 30, 31, 32, 33, 34, 1, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,
- 9, 0, 10, 35, 0, 11, 12, 13, 14, 2,
- 0, 15, 16, 17, 18, 19, 20, 21, 0, 22,
- 23, 24, 25, 26, 27, 28, 0, 0, 0, 29,
- 30, 31, 32, 33, 34, 0, 0, 0, 0, 8,
- 0, 9, 0, 10, 2, 0, 11, 12, 13, 14,
- 359, 0, 15, 16, 17, 18, 19, 20, 21, 0,
- 22, 23, 24, 25, 26, 27, 28, 0, 0, 0,
- 0, 325, 342, 286, 8, 0, 9, 0, 10, 0,
- 0, 11, 12, 13, 14, 2, 0, 15, 16, 17,
- 18, 19, 20, 21, 0, 22, 23, 24, 25, 26,
- 27, 28, 0, 0, 0, 29, 30, 31, 32, 33,
- 34, 0, 0, 0, 0, 8, 0, 9, 0, 10,
- 2, 0, 11, 12, 13, 14, 0, 0, 15, 16,
- 17, 18, 19, 20, 21, 0, 22, 23, 24, 25,
- 26, 27, 28, 0, 0, 0, 0, 285, -189, 286,
- 8, 0, 9, 0, 10, 0, 0, 11, 12, 13,
- 14, 0, 0, 15, 16, 17, 18, 19, 20, 21,
- 0, 22, 23, 24, 25, 26, 27, 28, 0, 0,
- 0, 29, 30, 31, 32, 33, 34, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 285, 342, 286, 3, 4, 5, 6,
- 7, 8, 0, 9, 0, 10, 0, 0, 11, 12,
- 13, 14, 0, 2, 15, 16, 17, 18, 19, 20,
- 21, 0, 22, 23, 24, 25, 26, 27, 28, 0,
- 0, 0, 29, 30, 31, 32, 33, 34, 3, 4,
- 5, 6, 7, 8, 0, 9, 0, 10, 0, 0,
- 11, 12, 13, 14, 0, 0, 15, 16, 17, 18,
- 19, 20, 21, 0, 22, 23, 24, 25, 26, 27,
- 28, 0, 0, 0, 35
-};
-
-static const short yycheck[] = { 0,
- 35, 98, 51, 82, 109, 40, 52, 168, 154, 186,
- 119, 134, 121, 3, 358, 18, 0, 121, 112, 285,
- 3, 3, 0, 48, 13, 14, 3, 28, 287, 37,
- 109, 3, 3, 18, 35, 36, 130, 62, 73, 40,
- 0, 385, 112, 89, 107, 46, 109, 8, 9, 10,
- 51, 76, 36, 112, 55, 3, 11, 12, 36, 325,
- 130, 96, 3, 41, 42, 52, 232, 233, 327, 114,
- 48, 130, 73, 74, 119, 120, 36, 182, 112, 62,
- 81, 41, 42, 192, 62, 194, 112, 114, 192, 186,
- 199, 200, 76, 94, 128, 96, 74, 154, 76, 115,
- 116, 158, 128, 182, 250, 214, 229, 230, 231, 108,
- 107, 89, 109, 112, 101, 116, 213, 65, 66, 67,
- 68, 69, 70, 126, 65, 66, 67, 68, 69, 70,
- 227, 108, 121, 122, 121, 107, 107, 109, 112, 129,
- 125, 198, 112, 15, 16, 254, 107, 256, 109, 129,
- 111, 248, 108, 154, 128, 332, 191, 158, 128, 107,
- 35, 110, 208, 112, 39, 40, 107, 290, 273, 153,
- 108, 46, 108, 319, 112, 153, 112, 5, 108, 180,
- 128, 286, 112, 129, 108, 126, 129, 348, 112, 128,
- 191, 234, 235, 5, 273, 5, 127, 198, 127, 35,
- 257, 126, 189, 39, 40, 192, 107, 286, 107, 210,
- 46, 128, 258, 191, 215, 236, 237, 238, 239, 128,
- 128, 278, 113, 258, 124, 240, 241, 123, 17, 107,
- 208, 107, 337, 126, 3, 332, 5, 6, 7, 285,
- 9, 10, 82, 108, 349, 112, 110, 126, 357, 358,
- 251, 128, 108, 76, 108, 352, 257, 258, 337, 130,
- 112, 108, 319, 264, 126, 108, 106, 107, 108, 109,
- 349, 107, 107, 109, 112, 354, 385, 278, 327, 325,
- 258, 112, 128, 340, 108, 110, 108, 74, 108, 110,
- 325, 128, 108, 0, 134, 128, 36, 62, 84, 356,
- 335, 352, 242, 245, 96, 189, 243, 335, 74, 366,
- 244, 246, 94, -1, 247, 329, -1, 180, 319, 3,
- -1, -1, 379, 251, 325, -1, 327, -1, -1, -1,
- -1, -1, 389, -1, 335, -1, -1, -1, 107, 340,
- -1, -1, 182, -1, 113, 114, 115, 116, 117, 118,
- -1, -1, -1, -1, -1, 356, -1, -1, -1, -1,
- 129, 130, -1, -1, -1, 366, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, -1, -1, 379, -1,
- -1, 65, 66, 67, 68, 69, 70, -1, 389, 229,
- 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247, -1, -1,
- -1, -1, 1, -1, 3, 4, 5, 6, 7, -1,
- 9, 10, -1, 107, -1, -1, -1, -1, -1, -1,
- -1, -1, 3, 273, 5, 6, 7, -1, 9, 10,
- 29, 30, 31, 32, 33, 34, 286, 36, -1, 38,
- 290, -1, 41, 42, 43, 44, -1, -1, 47, 48,
- 49, 50, 51, 52, 53, -1, 55, 56, 57, 58,
- 59, 60, 61, -1, 127, -1, -1, -1, -1, -1,
- -1, -1, 71, 72, 73, -1, 75, 76, 77, 78,
- 79, 80, 81, 82, 83, -1, 1, 337, 3, -1,
- 5, 6, 7, -1, 9, 10, -1, -1, -1, 349,
- -1, -1, -1, -1, 354, -1, -1, -1, 107, -1,
- -1, -1, -1, -1, 113, 114, 115, 116, 117, 118,
- -1, -1, -1, -1, -1, -1, 107, -1, -1, 128,
- 129, 130, 113, 114, 115, 116, 117, 118, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 129, -1,
- -1, -1, -1, -1, -1, -1, 71, 72, 73, -1,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 1, -1,
- -1, 4, 107, -1, -1, -1, -1, -1, 113, 114,
- 115, 116, 117, 118, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 128, 129, 130, 29, 30, 31, 32,
- 33, 34, -1, 36, 1, 38, -1, 4, 41, 42,
- 43, 44, -1, -1, 47, 48, 49, 50, 51, 52,
- 53, -1, 55, 56, 57, 58, 59, 60, 61, -1,
- -1, -1, 29, 30, 31, 32, 33, 34, -1, 36,
- -1, 38, -1, -1, 41, 42, 43, 44, -1, -1,
- 47, 48, 49, 50, 51, 52, 53, -1, 55, 56,
- 57, 58, 59, 60, 61, 1, -1, 3, -1, 5,
- 6, 7, 4, 9, 10, -1, -1, -1, -1, 112,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 127, 128, 129, 29, 30, 31,
- 32, 33, 34, -1, 36, -1, 38, -1, -1, 41,
- 42, 43, 44, -1, -1, 47, 48, 49, 50, 51,
- 52, 53, -1, 55, 56, 57, 58, 59, 60, 61,
- -1, -1, 129, -1, -1, 71, 72, 73, -1, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 3, -1,
- 5, 6, 7, -1, 9, 10, -1, 4, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 107, -1, -1, -1, -1, -1, 113, 114, 115,
- 116, 117, 118, -1, 3, 4, -1, 34, -1, 36,
- -1, 38, 128, 129, 41, 42, 43, 44, 130, -1,
- 47, 48, 49, 50, 51, 52, 53, -1, 55, 56,
- 57, 58, 59, 60, 61, 34, -1, 36, -1, 38,
- -1, -1, 41, 42, 43, 44, -1, -1, 47, 48,
- 49, 50, 51, 52, 53, -1, 55, 56, 57, 58,
- 59, 60, 61, -1, -1, -1, 65, 66, 67, 68,
- 69, 70, 107, -1, -1, -1, -1, -1, 113, 114,
- 115, 116, 117, 118, 3, 4, 5, 6, 7, -1,
- 9, 10, -1, 128, -1, -1, -1, -1, 3, -1,
- 5, 6, 7, 130, 9, 10, -1, -1, 107, -1,
- -1, -1, -1, -1, -1, 34, -1, 36, -1, 38,
- -1, -1, 41, 42, 43, 44, -1, 126, 47, 48,
- 49, 50, 51, 52, 53, -1, 55, 56, 57, 58,
- 59, 60, 61, 3, -1, 5, 6, 7, -1, 9,
- 10, -1, -1, -1, -1, 3, -1, 5, 6, 7,
- -1, 9, 10, -1, -1, -1, -1, 3, -1, 5,
- 6, 7, -1, 9, 10, -1, -1, -1, -1, 3,
- -1, 5, 6, 7, -1, 9, 10, -1, 107, -1,
- -1, -1, -1, -1, 113, 114, 115, 116, 117, 118,
- -1, -1, 107, -1, -1, 110, -1, -1, 113, 114,
- 115, 116, 117, 118, 3, -1, 5, 6, 7, -1,
- 9, 10, -1, -1, -1, -1, 3, -1, 5, 6,
- 7, -1, 9, 10, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 107, 108, -1,
- -1, -1, -1, 113, 114, 115, 116, 117, 118, 107,
- -1, -1, 110, -1, -1, 113, 114, 115, 116, 117,
- 118, 107, -1, -1, 110, -1, -1, 113, 114, 115,
- 116, 117, 118, 107, -1, -1, -1, -1, -1, 113,
- 114, 115, 116, 117, 118, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, -1, -1, -1, -1, -1, 107, -1,
- -1, -1, -1, -1, 113, 114, 115, 116, 117, 118,
- 107, -1, -1, -1, -1, -1, 113, 114, 115, 116,
- 117, 118, 34, -1, 36, -1, 38, -1, -1, 41,
- 42, 43, 44, 4, -1, 47, 48, 49, 50, 51,
- 52, 53, -1, 55, 56, 57, 58, 59, 60, 61,
- -1, -1, -1, 65, 66, 67, 68, 69, 70, -1,
- -1, -1, -1, 34, -1, 36, 4, 38, -1, -1,
- 41, 42, 43, 44, -1, -1, 47, 48, 49, 50,
- 51, 52, 53, -1, 55, 56, 57, 58, 59, 60,
- 61, -1, -1, -1, -1, 107, 34, 109, 36, -1,
- 38, -1, 114, 41, 42, 43, 44, -1, -1, 47,
- 48, 49, 50, 51, 52, 53, -1, 55, 56, 57,
- 58, 59, 60, 61, -1, -1, -1, 65, 66, 67,
- 68, 69, 70, -1, -1, -1, 0, 108, -1, 3,
- 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 29, 30, 31, 32, 33,
- 34, -1, 36, -1, 38, -1, 114, 41, 42, 43,
- 44, -1, -1, 47, 48, 49, 50, 51, 52, 53,
- -1, 55, 56, 57, 58, 59, 60, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, 3, 4, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 34, -1,
- 36, -1, 38, 107, -1, 41, 42, 43, 44, 4,
- -1, 47, 48, 49, 50, 51, 52, 53, -1, 55,
- 56, 57, 58, 59, 60, 61, -1, -1, -1, 65,
- 66, 67, 68, 69, 70, -1, -1, -1, -1, 34,
- -1, 36, -1, 38, 4, -1, 41, 42, 43, 44,
- 45, -1, 47, 48, 49, 50, 51, 52, 53, -1,
- 55, 56, 57, 58, 59, 60, 61, -1, -1, -1,
- -1, 107, 108, 109, 34, -1, 36, -1, 38, -1,
- -1, 41, 42, 43, 44, 4, -1, 47, 48, 49,
- 50, 51, 52, 53, -1, 55, 56, 57, 58, 59,
- 60, 61, -1, -1, -1, 65, 66, 67, 68, 69,
- 70, -1, -1, -1, -1, 34, -1, 36, -1, 38,
- 4, -1, 41, 42, 43, 44, -1, -1, 47, 48,
- 49, 50, 51, 52, 53, -1, 55, 56, 57, 58,
- 59, 60, 61, -1, -1, -1, -1, 107, 108, 109,
- 34, -1, 36, -1, 38, -1, -1, 41, 42, 43,
- 44, -1, -1, 47, 48, 49, 50, 51, 52, 53,
- -1, 55, 56, 57, 58, 59, 60, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 3, 4, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 107, 108, 109, 29, 30, 31, 32,
- 33, 34, -1, 36, -1, 38, -1, -1, 41, 42,
- 43, 44, -1, 4, 47, 48, 49, 50, 51, 52,
- 53, -1, 55, 56, 57, 58, 59, 60, 61, -1,
- -1, -1, 65, 66, 67, 68, 69, 70, 29, 30,
- 31, 32, 33, 34, -1, 36, -1, 38, -1, -1,
- 41, 42, 43, 44, -1, -1, 47, 48, 49, 50,
- 51, 52, 53, -1, 55, 56, 57, 58, 59, 60,
- 61, -1, -1, -1, 107
-};
-/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/misc/bison.simple"
-/* This file comes from bison-1.28. */
-
-/* Skeleton output parser for bison,
- Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* This is the parser code that is written into each bison parser
- when the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
-
-#ifndef YYSTACK_USE_ALLOCA
-#ifdef alloca
-#define YYSTACK_USE_ALLOCA
-#else /* alloca not defined */
-#ifdef __GNUC__
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#else /* not GNU C. */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#define YYSTACK_USE_ALLOCA
-#include <alloca.h>
-#else /* not sparc */
-/* We think this test detects Watcom and Microsoft C. */
-/* This used to test MSDOS, but that is a bad idea
- since that symbol is in the user namespace. */
-#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#if 0 /* No need for malloc.h, which pollutes the namespace;
- instead, just don't use alloca. */
-#include <malloc.h>
-#endif
-#else /* not MSDOS, or __TURBOC__ */
-#if defined(_AIX)
-/* I don't know what this was needed for, but it pollutes the namespace.
- So I turned it off. rms, 2 May 1997. */
-/* #include <malloc.h> */
- #pragma alloca
-#define YYSTACK_USE_ALLOCA
-#else /* not MSDOS, or __TURBOC__, or _AIX */
-#if 0
-#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
- and on HPUX 10. Eventually we can turn this on. */
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#endif /* __hpux */
-#endif
-#endif /* not _AIX */
-#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc */
-#endif /* not GNU C */
-#endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
-
-#ifdef YYSTACK_USE_ALLOCA
-#define YYSTACK_ALLOC alloca
-#else
-#define YYSTACK_ALLOC malloc
-#endif
-
-/* Note: there must be only one dollar sign in this file.
- It is replaced by the list of actions, each action
- as one case of the switch. */
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY -2
-#define YYEOF 0
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
-/* Like YYERROR except do call yyerror.
- This remains here temporarily to ease the
- transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-#define YYFAIL goto yyerrlab
-#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(token, value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { yychar = (token), yylval = (value); \
- yychar1 = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
- goto yybackup; \
- } \
- else \
- { yyerror ("syntax error: cannot back up"); YYERROR; } \
-while (0)
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-#ifndef YYPURE
-#define YYLEX yylex()
-#endif
-
-#ifdef YYPURE
-#ifdef YYLSP_NEEDED
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval, &yylloc)
-#endif
-#else /* not YYLSP_NEEDED */
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval)
-#endif
-#endif /* not YYLSP_NEEDED */
-#endif
-
-/* If nonreentrant, generate the variables here */
-
-#ifndef YYPURE
-
-int yychar; /* the lookahead symbol */
-YYSTYPE yylval; /* the semantic value of the */
- /* lookahead symbol */
-
-#ifdef YYLSP_NEEDED
-YYLTYPE yylloc; /* location data for the lookahead */
- /* symbol */
-#endif
-
-int yynerrs; /* number of parse errors so far */
-#endif /* not YYPURE */
-
-#if YYDEBUG != 0
-int yydebug; /* nonzero means print parse trace */
-/* Since this is uninitialized, it does not stop multiple parsers
- from coexisting. */
-#endif
-
-/* YYINITDEPTH indicates the initial size of the parser's stacks */
-
-#ifndef YYINITDEPTH
-#define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH is the maximum size the stacks can grow to
- (effective only if the built-in stack extension method is used). */
-
-#if YYMAXDEPTH == 0
-#undef YYMAXDEPTH
-#endif
-
-#ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
-#endif
-\f
-/* Define __yy_memcpy. Note that the size argument
- should be passed with type unsigned int, because that is what the non-GCC
- definitions require. With GCC, __builtin_memcpy takes an arg
- of type size_t, but it can handle unsigned int. */
-
-#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
-#else /* not GNU C or C++ */
-#ifndef __cplusplus
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (to, from, count)
- char *to;
- char *from;
- unsigned int count;
-{
- register char *f = from;
- register char *t = to;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#else /* __cplusplus */
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (char *to, char *from, unsigned int count)
-{
- register char *t = to;
- register char *f = from;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#endif
-#endif
-\f
-#line 217 "/usr/share/misc/bison.simple"
-
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
- into yyparse. The argument should have type void *.
- It should actually point to an object.
- Grammar actions can access the variable by casting it
- to the proper pointer type. */
-
-#ifdef YYPARSE_PARAM
-#ifdef __cplusplus
-#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#else /* not __cplusplus */
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#endif /* not __cplusplus */
-#else /* not YYPARSE_PARAM */
-#define YYPARSE_PARAM_ARG
-#define YYPARSE_PARAM_DECL
-#endif /* not YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-#ifdef YYPARSE_PARAM
-int yyparse (void *);
-#else
-int yyparse (void);
-#endif
-#endif
-
-int
-yyparse(YYPARSE_PARAM_ARG)
- YYPARSE_PARAM_DECL
-{
- register int yystate;
- register int yyn;
- register short *yyssp;
- register YYSTYPE *yyvsp;
- int yyerrstatus; /* number of tokens to shift before error messages enabled */
- int yychar1 = 0; /* lookahead token as an internal (translated) token number */
-
- short yyssa[YYINITDEPTH]; /* the state stack */
- YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
-
- short *yyss = yyssa; /* refer to the stacks thru separate pointers */
- YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
-
-#ifdef YYLSP_NEEDED
- YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
-
-#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
-#else
-#define YYPOPSTACK (yyvsp--, yyssp--)
-#endif
-
- int yystacksize = YYINITDEPTH;
- int yyfree_stacks = 0;
-
-#ifdef YYPURE
- int yychar;
- YYSTYPE yylval;
- int yynerrs;
-#ifdef YYLSP_NEEDED
- YYLTYPE yylloc;
-#endif
-#endif
-
- YYSTYPE yyval; /* the variable used to return */
- /* semantic values from the action */
- /* routines */
-
- int yylen;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Starting parse\n");
-#endif
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss - 1;
- yyvsp = yyvs;
-#ifdef YYLSP_NEEDED
- yylsp = yyls;
-#endif
-
-/* Push a new state, which is found in yystate . */
-/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks. */
-yynewstate:
-
- *++yyssp = yystate;
-
- if (yyssp >= yyss + yystacksize - 1)
- {
- /* Give user a chance to reallocate the stack */
- /* Use copies of these so that the &'s don't force the real ones into memory. */
- YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
-#ifdef YYLSP_NEEDED
- YYLTYPE *yyls1 = yyls;
-#endif
-
- /* Get the current used size of the three stacks, in elements. */
- int size = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- /* Each stack pointer address is followed by the size of
- the data in use in that stack, in bytes. */
-#ifdef YYLSP_NEEDED
- /* This used to be a conditional around just the two extra args,
- but that might be undefined if yyoverflow is a macro. */
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yyls1, size * sizeof (*yylsp),
- &yystacksize);
-#else
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yystacksize);
-#endif
-
- yyss = yyss1; yyvs = yyvs1;
-#ifdef YYLSP_NEEDED
- yyls = yyls1;
-#endif
-#else /* no yyoverflow */
- /* Extend the stack our own way. */
- if (yystacksize >= YYMAXDEPTH)
- {
- yyerror("parser stack overflow");
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 2;
- }
- yystacksize *= 2;
- if (yystacksize > YYMAXDEPTH)
- yystacksize = YYMAXDEPTH;
-#ifndef YYSTACK_USE_ALLOCA
- yyfree_stacks = 1;
-#endif
- yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss, (char *)yyss1,
- size * (unsigned int) sizeof (*yyssp));
- yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs, (char *)yyvs1,
- size * (unsigned int) sizeof (*yyvsp));
-#ifdef YYLSP_NEEDED
- yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls, (char *)yyls1,
- size * (unsigned int) sizeof (*yylsp));
-#endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + size - 1;
- yyvsp = yyvs + size - 1;
-#ifdef YYLSP_NEEDED
- yylsp = yyls + size - 1;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Stack size increased to %d\n", yystacksize);
-#endif
-
- if (yyssp >= yyss + yystacksize - 1)
- YYABORT;
- }
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Entering state %d\n", yystate);
-#endif
-
- goto yybackup;
- yybackup:
-
-/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
-/* yyresume: */
-
- /* First try to decide what to do without reference to lookahead token. */
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* yychar is either YYEMPTY or YYEOF
- or a valid token in external form. */
-
- if (yychar == YYEMPTY)
- {
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Reading a token: ");
-#endif
- yychar = YYLEX;
- }
-
- /* Convert token to internal form (in yychar1) for indexing tables with */
-
- if (yychar <= 0) /* This means end of input. */
- {
- yychar1 = 0;
- yychar = YYEOF; /* Don't call YYLEX any more */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Now at end of input.\n");
-#endif
- }
- else
- {
- yychar1 = YYTRANSLATE(yychar);
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
- /* Give the individual parser a way to print the precise meaning
- of a token, for further debugging info. */
-#ifdef YYPRINT
- YYPRINT (stderr, yychar, yylval);
-#endif
- fprintf (stderr, ")\n");
- }
-#endif
- }
-
- yyn += yychar1;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
- goto yydefault;
-
- yyn = yytable[yyn];
-
- /* yyn is what to do for this token type in this state.
- Negative => reduce, -yyn is rule number.
- Positive => shift, yyn is new state.
- New state is final state => don't bother to shift,
- just return success.
- 0, or most negative number => error. */
-
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrlab;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Shift the lookahead token. */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
-#endif
-
- /* Discard the token being shifted unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- /* count tokens shifted since error; after three, turn off error status. */
- if (yyerrstatus) yyerrstatus--;
-
- yystate = yyn;
- goto yynewstate;
-
-/* Do the default action for the current state. */
-yydefault:
-
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
-
-/* Do a reduction. yyn is the number of a rule to reduce with. */
-yyreduce:
- yylen = yyr2[yyn];
- if (yylen > 0)
- yyval = yyvsp[1-yylen]; /* implement default value of the action */
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- int i;
-
- fprintf (stderr, "Reducing via rule %d (line %d), ",
- yyn, yyrline[yyn]);
-
- /* Print the symbols being reduced, and their result. */
- for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
- fprintf (stderr, "%s ", yytname[yyrhs[i]]);
- fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
- }
-#endif
-
-
- switch (yyn) {
-
-case 3:
-#line 125 "SDCC.y"
-{ blockNo=0;;
- break;}
-case 4:
-#line 126 "SDCC.y"
-{
- addSymChain (yyvsp[0].sym);
- allocVariables (yyvsp[0].sym) ;
- cleanUpLevel (SymbolTab,1);
- ;
- break;}
-case 5:
-#line 134 "SDCC.y"
-{ /* function type not specified */
- /* assume it to be 'int' */
- addDecl(yyvsp[-1].sym,0,newIntLink());
- yyval.asts = createFunction(yyvsp[-1].sym,yyvsp[0].asts);
- ;
- break;}
-case 6:
-#line 140 "SDCC.y"
-{
- pointerTypes(yyvsp[-1].sym->type,copyLinkChain(yyvsp[-2].lnk));
- addDecl(yyvsp[-1].sym,0,yyvsp[-2].lnk);
- yyval.asts = createFunction(yyvsp[-1].sym,yyvsp[0].asts);
- ;
- break;}
-case 8:
-#line 149 "SDCC.y"
-{ yyval.lnk = mergeSpec(yyvsp[-1].lnk,yyvsp[0].lnk); ;
- break;}
-case 9:
-#line 153 "SDCC.y"
-{
- yyval.lnk = newLink() ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_BNKF(yyval.lnk) = 1;
- SPEC_BANK(yyval.lnk) = (int) floatFromVal(yyvsp[0].val);
- ;
- break;}
-case 10:
-#line 159 "SDCC.y"
-{ yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_RENT(yyval.lnk) = 1;
- ;
- break;}
-case 11:
-#line 163 "SDCC.y"
-{ yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_CRTCL(yyval.lnk) = 1;
- ;
- break;}
-case 12:
-#line 168 "SDCC.y"
-{
- yyval.lnk = newLink () ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_INTN(yyval.lnk) = yyvsp[0].yyint ;
- SPEC_INTRTN(yyval.lnk) = 1;
- ;
- break;}
-case 14:
-#line 179 "SDCC.y"
-{
- werror(E_OLD_STYLE,(yyvsp[-1].sym ? yyvsp[-1].sym->name: "")) ;
- exit(1);
- ;
- break;}
-case 15:
-#line 186 "SDCC.y"
-{ yyval.asts = newAst(EX_VALUE,symbolVal(yyvsp[0].sym)); ;
- break;}
-case 16:
-#line 187 "SDCC.y"
-{ yyval.asts = newAst(EX_VALUE,yyvsp[0].val); ;
- break;}
-case 18:
-#line 189 "SDCC.y"
-{ yyval.asts = yyvsp[-1].asts ; ;
- break;}
-case 19:
-#line 193 "SDCC.y"
-{ yyval.asts = newAst(EX_VALUE,yyvsp[0].val); ;
- break;}
-case 21:
-#line 198 "SDCC.y"
-{ yyval.asts = newNode ('[', yyvsp[-3].asts, yyvsp[-1].asts) ; ;
- break;}
-case 22:
-#line 199 "SDCC.y"
-{ yyval.asts = newNode (CALL,yyvsp[-2].asts,NULL);
- yyval.asts->left->funcName = 1;;
- break;}
-case 23:
-#line 202 "SDCC.y"
-{
- yyval.asts = newNode (CALL,yyvsp[-3].asts,yyvsp[-1].asts) ; yyval.asts->left->funcName = 1;
- ;
- break;}
-case 24:
-#line 206 "SDCC.y"
-{
- yyvsp[0].sym = newSymbol(yyvsp[0].sym->name,NestLevel);
- yyvsp[0].sym->implicit = 1;
- yyval.asts = newNode(PTR_OP,newNode('&',yyvsp[-2].asts,NULL),newAst(EX_VALUE,symbolVal(yyvsp[0].sym)));
-/* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
- ;
- break;}
-case 25:
-#line 213 "SDCC.y"
-{
- yyvsp[0].sym = newSymbol(yyvsp[0].sym->name,NestLevel);
- yyvsp[0].sym->implicit = 1;
- yyval.asts = newNode(PTR_OP,yyvsp[-2].asts,newAst(EX_VALUE,symbolVal(yyvsp[0].sym)));
- ;
- break;}
-case 26:
-#line 219 "SDCC.y"
-{ yyval.asts = newNode(INC_OP,yyvsp[-1].asts,NULL);;
- break;}
-case 27:
-#line 221 "SDCC.y"
-{ yyval.asts = newNode(DEC_OP,yyvsp[-1].asts,NULL); ;
- break;}
-case 29:
-#line 226 "SDCC.y"
-{ yyval.asts = newNode(PARAM,yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 31:
-#line 231 "SDCC.y"
-{ yyval.asts = newNode(INC_OP,NULL,yyvsp[0].asts); ;
- break;}
-case 32:
-#line 232 "SDCC.y"
-{ yyval.asts = newNode(DEC_OP,NULL,yyvsp[0].asts); ;
- break;}
-case 33:
-#line 233 "SDCC.y"
-{ yyval.asts = newNode(yyvsp[-1].yyint,yyvsp[0].asts,NULL) ; ;
- break;}
-case 34:
-#line 234 "SDCC.y"
-{ yyval.asts = newNode(SIZEOF,NULL,yyvsp[0].asts); ;
- break;}
-case 35:
-#line 235 "SDCC.y"
-{ yyval.asts = newAst(EX_VALUE,sizeofOp(yyvsp[-1].lnk)); ;
- break;}
-case 36:
-#line 239 "SDCC.y"
-{ yyval.yyint = '&' ;;
- break;}
-case 37:
-#line 240 "SDCC.y"
-{ yyval.yyint = '*' ;;
- break;}
-case 38:
-#line 241 "SDCC.y"
-{ yyval.yyint = '+' ;;
- break;}
-case 39:
-#line 242 "SDCC.y"
-{ yyval.yyint = '-' ;;
- break;}
-case 40:
-#line 243 "SDCC.y"
-{ yyval.yyint = '~' ;;
- break;}
-case 41:
-#line 244 "SDCC.y"
-{ yyval.yyint = '!' ;;
- break;}
-case 43:
-#line 249 "SDCC.y"
-{ yyval.asts = newNode(CAST,newAst(EX_LINK,yyvsp[-2].lnk),yyvsp[0].asts); ;
- break;}
-case 45:
-#line 254 "SDCC.y"
-{ yyval.asts = newNode('*',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 46:
-#line 255 "SDCC.y"
-{ yyval.asts = newNode('/',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 47:
-#line 256 "SDCC.y"
-{ yyval.asts = newNode('%',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 49:
-#line 261 "SDCC.y"
-{ yyval.asts=newNode('+',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 50:
-#line 262 "SDCC.y"
-{ yyval.asts=newNode('-',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 52:
-#line 267 "SDCC.y"
-{ yyval.asts = newNode(LEFT_OP,yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 53:
-#line 268 "SDCC.y"
-{ yyval.asts = newNode(RIGHT_OP,yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 55:
-#line 273 "SDCC.y"
-{ yyval.asts = newNode('<',yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 56:
-#line 274 "SDCC.y"
-{ yyval.asts = newNode('>',yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 57:
-#line 275 "SDCC.y"
-{
- /* $$ = newNode(LE_OP,$1,$3); */
- /* getting 8051 specific here : will change
- LE_OP operation to "not greater than" i.e.
- ( a <= b ) === ( ! ( a > b )) */
- yyval.asts = newNode('!',
- newNode('>', yyvsp[-2].asts , yyvsp[0].asts ),
- NULL);
- ;
- break;}
-case 58:
-#line 284 "SDCC.y"
-{
- /* $$ = newNode(GE_OP,$1,$3) ; */
- /* getting 8051 specific here : will change
- GE_OP operation to "not less than" i.e.
- ( a >= b ) === ( ! ( a < b )) */
- yyval.asts = newNode('!',
- newNode('<', yyvsp[-2].asts , yyvsp[0].asts ),
- NULL);
- ;
- break;}
-case 60:
-#line 297 "SDCC.y"
-{ yyval.asts = newNode(EQ_OP,yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 61:
-#line 299 "SDCC.y"
-{
- /* $$ = newNode(NE_OP,$1,$3); */
- /* NE_OP changed :
- expr1 != expr2 is equivalent to
- (! expr1 == expr2) */
- yyval.asts = newNode('!',
- newNode(EQ_OP,yyvsp[-2].asts,yyvsp[0].asts),
- NULL);
- ;
- break;}
-case 63:
-#line 312 "SDCC.y"
-{ yyval.asts = newNode('&',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 65:
-#line 317 "SDCC.y"
-{ yyval.asts = newNode('^',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 67:
-#line 322 "SDCC.y"
-{ yyval.asts = newNode('|',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 69:
-#line 328 "SDCC.y"
-{ yyval.asts = newNode(AND_OP,yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 71:
-#line 334 "SDCC.y"
-{ yyval.asts = newNode(OR_OP,yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 73:
-#line 340 "SDCC.y"
-{
- yyval.asts = newNode(':',yyvsp[-2].asts,yyvsp[0].asts) ;
- yyval.asts = newNode('?',yyvsp[-4].asts,yyval.asts) ;
- ;
- break;}
-case 75:
-#line 349 "SDCC.y"
-{
-
- switch (yyvsp[-1].yyint) {
- case '=':
- yyval.asts = newNode(yyvsp[-1].yyint,yyvsp[-2].asts,yyvsp[0].asts);
- break;
- case MUL_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('*',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case DIV_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('/',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case ADD_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('+',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case SUB_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('-',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case LEFT_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode(LEFT_OP,copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case RIGHT_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode(RIGHT_OP,copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case AND_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('&',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case XOR_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('^',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- case OR_ASSIGN:
- yyval.asts = newNode('=',yyvsp[-2].asts,newNode('|',copyAst(yyvsp[-2].asts),yyvsp[0].asts));
- break;
- default :
- yyval.asts = NULL;
- }
-
- ;
- break;}
-case 76:
-#line 390 "SDCC.y"
-{ yyval.yyint = '=' ;;
- break;}
-case 88:
-#line 405 "SDCC.y"
-{ yyval.asts = newNode(',',yyvsp[-2].asts,yyvsp[0].asts);;
- break;}
-case 90:
-#line 413 "SDCC.y"
-{ yyval.sym = NULL ; ;
- break;}
-case 91:
-#line 415 "SDCC.y"
-{
- /* add the specifier list to the id */
- symbol *sym , *sym1;
-
- for (sym1 = sym = reverseSyms(yyvsp[-1].sym);sym != NULL;sym = sym->next) {
- link *lnk = copyLinkChain(yyvsp[-2].lnk);
- /* do the pointer stuff */
- pointerTypes(sym->type,lnk);
- addDecl (sym,0,lnk) ;
- }
-
- yyval.sym = sym1 ;
- ;
- break;}
-case 92:
-#line 431 "SDCC.y"
-{ yyval.lnk = yyvsp[0].lnk; ;
- break;}
-case 93:
-#line 432 "SDCC.y"
-{
- /* if the decl $2 is not a specifier */
- /* find the spec and replace it */
- if ( !IS_SPEC(yyvsp[0].lnk)) {
- link *lnk = yyvsp[0].lnk ;
- while (lnk && !IS_SPEC(lnk->next))
- lnk = lnk->next;
- lnk->next = mergeSpec(yyvsp[-1].lnk,lnk->next);
- yyval.lnk = yyvsp[0].lnk ;
- }
- else
- yyval.lnk = mergeSpec(yyvsp[-1].lnk,yyvsp[0].lnk);
- ;
- break;}
-case 94:
-#line 445 "SDCC.y"
-{ yyval.lnk = yyvsp[0].lnk; ;
- break;}
-case 95:
-#line 446 "SDCC.y"
-{
- /* if the decl $2 is not a specifier */
- /* find the spec and replace it */
- if ( !IS_SPEC(yyvsp[0].lnk)) {
- link *lnk = yyvsp[0].lnk ;
- while (lnk && !IS_SPEC(lnk->next))
- lnk = lnk->next;
- lnk->next = mergeSpec(yyvsp[-1].lnk,lnk->next);
- yyval.lnk = yyvsp[0].lnk ;
- }
- else
- yyval.lnk = mergeSpec(yyvsp[-1].lnk,yyvsp[0].lnk);
- ;
- break;}
-case 97:
-#line 463 "SDCC.y"
-{ yyvsp[0].sym->next = yyvsp[-2].sym ; yyval.sym = yyvsp[0].sym;;
- break;}
-case 98:
-#line 467 "SDCC.y"
-{ yyvsp[0].sym->ival = NULL ; ;
- break;}
-case 99:
-#line 468 "SDCC.y"
-{ yyvsp[-2].sym->ival = yyvsp[0].ilist ; ;
- break;}
-case 100:
-#line 473 "SDCC.y"
-{
- yyval.lnk = newLink () ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_TYPEDEF(yyval.lnk) = 1 ;
- ;
- break;}
-case 101:
-#line 478 "SDCC.y"
-{
- yyval.lnk = newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_EXTR(yyval.lnk) = 1 ;
- ;
- break;}
-case 102:
-#line 483 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_STAT(yyval.lnk) = 1 ;
- ;
- break;}
-case 103:
-#line 488 "SDCC.y"
-{
- yyval.lnk = newLink () ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_AUTO ;
- ;
- break;}
-case 104:
-#line 493 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_REGISTER ;
- ;
- break;}
-case 105:
-#line 501 "SDCC.y"
-{ yyval.yyint = (int) floatFromVal(yyvsp[0].val) ; ;
- break;}
-case 107:
-#line 507 "SDCC.y"
-{
- /* add this to the storage class specifier */
- SPEC_ABSA(yyvsp[-2].lnk) = 1; /* set the absolute addr flag */
- /* now get the abs addr from value */
- SPEC_ADDR(yyvsp[-2].lnk) = (int) floatFromVal (yyvsp[0].val) ;
- ;
- break;}
-case 108:
-#line 516 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_CHAR ;
- ;
- break;}
-case 109:
-#line 521 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_LONG(yyval.lnk) = 0 ;
- SPEC_SHORT(yyval.lnk) = 1 ;
- ;
- break;}
-case 110:
-#line 527 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_INT ;
- ;
- break;}
-case 111:
-#line 532 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_LONG(yyval.lnk) = 1 ;
- SPEC_SHORT(yyval.lnk) = 0;
- ;
- break;}
-case 112:
-#line 538 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_USIGN(yyval.lnk) = 0 ;
- ;
- break;}
-case 113:
-#line 543 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_USIGN(yyval.lnk) = 1 ;
- ;
- break;}
-case 114:
-#line 548 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_VOID ;
- ;
- break;}
-case 115:
-#line 553 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_CONSTANT ;
- SPEC_CONST(yyval.lnk) = 1;
- ;
- break;}
-case 116:
-#line 559 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_VOLATILE(yyval.lnk) = 1 ;
- ;
- break;}
-case 117:
-#line 564 "SDCC.y"
-{
- yyval.lnk=newLink();
- SPEC_NOUN(yyval.lnk) = V_FLOAT;
- yyval.lnk->class = SPECIFIER ;
- ;
- break;}
-case 118:
-#line 569 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_XDATA ;
- ;
- break;}
-case 119:
-#line 574 "SDCC.y"
-{
- yyval.lnk = newLink () ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_CODE ;
- ;
- break;}
-case 120:
-#line 579 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_DATA ;
- ;
- break;}
-case 121:
-#line 584 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_IDATA ;
- ;
- break;}
-case 122:
-#line 589 "SDCC.y"
-{
- yyval.lnk = newLink ();
- yyval.lnk->class = SPECIFIER ;
- SPEC_SCLS(yyval.lnk) = S_PDATA ;
- ;
- break;}
-case 123:
-#line 594 "SDCC.y"
-{
- yyval.lnk=newLink();
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_BIT ;
- SPEC_SCLS(yyval.lnk) = S_BIT ;
- SPEC_BLEN(yyval.lnk) = 1;
- SPEC_BSTR(yyval.lnk) = 0;
- ;
- break;}
-case 125:
-#line 604 "SDCC.y"
-{
- cenum = NULL ;
- yyval.lnk = yyvsp[0].lnk ;
- ;
- break;}
-case 126:
-#line 609 "SDCC.y"
-{
- symbol *sym;
- link *p ;
-
- sym = findSym(TypedefTab,NULL,yyvsp[0].yychar) ;
- yyval.lnk = p = copyLinkChain(sym->type);
- SPEC_TYPEDEF(getSpec(p)) = 0;
- ;
- break;}
-case 128:
-#line 621 "SDCC.y"
-{
- yyval.lnk = newLink() ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_SBIT;
- SPEC_SCLS(yyval.lnk) = S_SBIT;
- ;
- break;}
-case 129:
-#line 627 "SDCC.y"
-{
- yyval.lnk = newLink() ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_CHAR;
- SPEC_SCLS(yyval.lnk) = S_SFR ;
- SPEC_USIGN(yyval.lnk) = 1 ;
- ;
- break;}
-case 130:
-#line 638 "SDCC.y"
-{
- structdef *sdef ;
-
- /* Create a structdef */
- sdef = yyvsp[-3].sdef ;
- sdef->fields = reverseSyms(yyvsp[-1].sym) ; /* link the fields */
- sdef->size = compStructSize(yyvsp[-4].yyint,sdef); /* update size of */
-
- /* Create the specifier */
- yyval.lnk = newLink () ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_STRUCT;
- SPEC_STRUCT(yyval.lnk)= sdef ;
- ;
- break;}
-case 131:
-#line 653 "SDCC.y"
-{
- yyval.lnk = newLink() ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_STRUCT;
- SPEC_STRUCT(yyval.lnk) = yyvsp[0].sdef ;
- ;
- break;}
-case 132:
-#line 662 "SDCC.y"
-{ yyval.yyint = STRUCT ; ;
- break;}
-case 133:
-#line 663 "SDCC.y"
-{ yyval.yyint = UNION ; ;
- break;}
-case 135:
-#line 668 "SDCC.y"
-{ /* synthesize a name add to structtable */
- yyval.sdef = newStruct(genSymName(NestLevel)) ;
- yyval.sdef->level = NestLevel ;
- addSym (StructTab, yyval.sdef, yyval.sdef->tag,yyval.sdef->level,currBlockno) ;
- ;
- break;}
-case 136:
-#line 676 "SDCC.y"
-{ /* add name to structure table */
- yyval.sdef = findSymWithBlock (StructTab,yyvsp[0].sym,currBlockno);
- if (! yyval.sdef ) {
- yyval.sdef = newStruct(yyvsp[0].sym->name) ;
- yyval.sdef->level = NestLevel ;
- addSym (StructTab, yyval.sdef, yyval.sdef->tag,yyval.sdef->level,currBlockno) ;
- }
- ;
- break;}
-case 138:
-#line 689 "SDCC.y"
-{
- symbol *sym = yyvsp[0].sym;
- /* go to the end of the chain */
- while (sym->next) sym = sym->next;
-
- sym->next = yyvsp[-1].sym ;
- yyval.sym = yyvsp[0].sym;
- ;
- break;}
-case 139:
-#line 701 "SDCC.y"
-{
- /* add this type to all the symbols */
- symbol *sym ;
- for ( sym = yyvsp[-1].sym ; sym != NULL ; sym = sym->next ) {
-
- pointerTypes(sym->type,copyLinkChain(yyvsp[-2].lnk));
- if (!sym->type) {
- sym->type = copyLinkChain(yyvsp[-2].lnk);
- sym->etype = getSpec(sym->type);
- }
- else
- addDecl (sym,0,cloneSpec(yyvsp[-2].lnk));
-
- }
- yyval.sym = yyvsp[-1].sym;
- ;
- break;}
-case 141:
-#line 722 "SDCC.y"
-{
- yyvsp[0].sym->next = yyvsp[-2].sym ;
- yyval.sym = yyvsp[0].sym ;
- ;
- break;}
-case 143:
-#line 730 "SDCC.y"
-{
- yyval.sym = newSymbol (genSymName(NestLevel),NestLevel) ;
- yyval.sym->bitVar = (int) floatFromVal(constExprValue(yyvsp[0].asts,TRUE));
- ;
- break;}
-case 144:
-#line 735 "SDCC.y"
-{
- yyvsp[-2].sym->bitVar = (int) floatFromVal(constExprValue(yyvsp[0].asts,TRUE));
- ;
- break;}
-case 145:
-#line 741 "SDCC.y"
-{
- addSymChain (yyvsp[-1].sym);
- allocVariables(reverseSyms(yyvsp[-1].sym)) ;
- yyval.lnk = copyLinkChain(cenum->type);
- ;
- break;}
-case 146:
-#line 746 "SDCC.y"
-{
- symbol *csym ;
-
- yyvsp[-3].sym->type = copyLinkChain(cenum->type);
- yyvsp[-3].sym->etype = getSpec(yyvsp[-3].sym->type);
- /* add this to the enumerator table */
- if (!(csym=findSym(enumTab,yyvsp[-3].sym,yyvsp[-3].sym->name)) &&
- (csym && csym->level == yyvsp[-3].sym->level))
- werror(E_DUPLICATE_TYPEDEF,csym->name);
-
- addSym ( enumTab,yyvsp[-3].sym,yyvsp[-3].sym->name,yyvsp[-3].sym->level,yyvsp[-3].sym->block);
- addSymChain (yyvsp[-1].sym);
- allocVariables (reverseSyms(yyvsp[-1].sym));
- yyval.lnk = copyLinkChain(cenum->type);
- SPEC_SCLS(getSpec(yyval.lnk)) = 0 ;
- ;
- break;}
-case 147:
-#line 762 "SDCC.y"
-{
- symbol *csym ;
-
- /* check the enumerator table */
- if ((csym = findSym(enumTab,yyvsp[0].sym,yyvsp[0].sym->name)))
- yyval.lnk = copyLinkChain(csym->type);
- else {
- yyval.lnk = newLink() ;
- yyval.lnk->class = SPECIFIER ;
- SPEC_NOUN(yyval.lnk) = V_INT ;
- }
-
- SPEC_SCLS(getSpec(yyval.lnk)) = 0 ;
- ;
- break;}
-case 149:
-#line 780 "SDCC.y"
-{
- yyvsp[0].sym->next = yyvsp[-2].sym ;
- yyval.sym = yyvsp[0].sym ;
- ;
- break;}
-case 150:
-#line 787 "SDCC.y"
-{
- /* make the symbol one level up */
- yyvsp[-1].sym->level-- ;
- yyvsp[-1].sym->type = copyLinkChain(yyvsp[0].val->type);
- yyvsp[-1].sym->etype= getSpec(yyvsp[-1].sym->type);
- SPEC_ENUM(yyvsp[-1].sym->etype) = 1;
- yyval.sym = yyvsp[-1].sym ;
-
- ;
- break;}
-case 151:
-#line 799 "SDCC.y"
-{
- value *val ;
-
- val = constExprValue(yyvsp[0].asts,TRUE);
- yyval.val = cenum = val ;
- ;
- break;}
-case 152:
-#line 805 "SDCC.y"
-{
- if (cenum) {
- sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
- yyval.val = cenum = constVal(lbuff);
- }
- else {
- sprintf(lbuff,"%d",0);
- yyval.val = cenum = constVal(lbuff);
- }
- ;
- break;}
-case 153:
-#line 818 "SDCC.y"
-{ yyval.sym = yyvsp[0].sym; ;
- break;}
-case 154:
-#line 820 "SDCC.y"
-{
- addDecl (yyvsp[0].sym,0,reverseLink(yyvsp[-1].lnk));
- yyval.sym = yyvsp[0].sym ;
- ;
- break;}
-case 155:
-#line 827 "SDCC.y"
-{ yyval.sym = yyvsp[0].sym ; ;
- break;}
-case 156:
-#line 828 "SDCC.y"
-{ addDecl (yyvsp[-1].sym,0,yyvsp[0].lnk); ;
- break;}
-case 158:
-#line 833 "SDCC.y"
-{ yyval.sym = yyvsp[-1].sym; ;
- break;}
-case 159:
-#line 835 "SDCC.y"
-{
- link *p;
-
- p = newLink ();
- DCL_TYPE(p) = ARRAY ;
- DCL_ELEM(p) = 0 ;
- addDecl(yyvsp[-2].sym,0,p);
- ;
- break;}
-case 160:
-#line 844 "SDCC.y"
-{
- link *p ;
- value *tval;
-
- p = (tval = constExprValue(yyvsp[-1].asts,TRUE))->etype;
- /* if it is not a constant then Error */
- if ( SPEC_SCLS(p) != S_LITERAL)
- werror(E_CONST_EXPECTED) ;
- else {
- p = newLink ();
- DCL_TYPE(p) = ARRAY ;
- DCL_ELEM(p) = (int) floatFromVal(tval) ;
- addDecl(yyvsp[-3].sym,0,p);
- }
- ;
- break;}
-case 161:
-#line 859 "SDCC.y"
-{ addDecl (yyvsp[-2].sym,FUNCTION,NULL) ; ;
- break;}
-case 162:
-#line 860 "SDCC.y"
-{ NestLevel++ ; currBlockno++; ;
- break;}
-case 163:
-#line 861 "SDCC.y"
-{
-
- addDecl (yyvsp[-4].sym,FUNCTION,NULL) ;
-
- yyvsp[-4].sym->hasVargs = IS_VARG(yyvsp[-1].val);
- yyvsp[-4].sym->args = reverseVal(yyvsp[-1].val) ;
-
- /* nest level was incremented to take care of the parms */
- NestLevel-- ;
- currBlockno--;
- yyval.sym = yyvsp[-4].sym;
- ;
- break;}
-case 164:
-#line 874 "SDCC.y"
-{
- werror(E_OLD_STYLE,yyvsp[-3].sym->name) ;
-
- /* assume it returns an it */
- yyvsp[-3].sym->type = yyvsp[-3].sym->etype = newIntLink();
- yyval.sym = yyvsp[-3].sym ;
- ;
- break;}
-case 165:
-#line 884 "SDCC.y"
-{ yyval.lnk = yyvsp[0].lnk ;;
- break;}
-case 166:
-#line 886 "SDCC.y"
-{
- yyval.lnk = yyvsp[-1].lnk ;
- DCL_TSPEC(yyvsp[-1].lnk) = yyvsp[0].lnk;
- ;
- break;}
-case 167:
-#line 891 "SDCC.y"
-{
- yyval.lnk = yyvsp[-1].lnk ;
- yyval.lnk->next = yyvsp[0].lnk ;
- ;
- break;}
-case 168:
-#line 896 "SDCC.y"
-{
- yyval.lnk = yyvsp[-2].lnk ;
- if (IS_SPEC(yyvsp[-1].lnk) && DCL_TYPE(yyvsp[0].lnk) == UPOINTER) {
- DCL_PTR_CONST(yyvsp[-2].lnk) = SPEC_CONST(yyvsp[-1].lnk);
- DCL_PTR_VOLATILE(yyvsp[-2].lnk) = SPEC_VOLATILE(yyvsp[-1].lnk);
- switch (SPEC_SCLS(yyvsp[-1].lnk)) {
- case S_XDATA:
- DCL_TYPE(yyvsp[0].lnk) = FPOINTER;
- break;
- case S_IDATA:
- DCL_TYPE(yyvsp[0].lnk) = IPOINTER ;
- break;
- case S_PDATA:
- DCL_TYPE(yyvsp[0].lnk) = PPOINTER ;
- break;
- case S_DATA:
- DCL_TYPE(yyvsp[0].lnk) = POINTER ;
- break;
- case S_CODE:
- DCL_PTR_CONST(yyvsp[0].lnk) = 1;
- DCL_TYPE(yyvsp[0].lnk) = CPOINTER ;
- break;
- }
- }
- else
- werror (W_PTR_TYPE_INVALID);
- yyval.lnk->next = yyvsp[0].lnk ;
- ;
- break;}
-case 169:
-#line 927 "SDCC.y"
-{
- if (yyvsp[-1].lnk == NULL) {
- yyval.lnk = newLink();
- DCL_TYPE(yyval.lnk) = POINTER ;
- }
- else
- yyval.lnk = yyvsp[-1].lnk ;
- ;
- break;}
-case 170:
-#line 938 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = FPOINTER ; ;
- break;}
-case 171:
-#line 939 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = CPOINTER ; DCL_PTR_CONST(yyval.lnk) = 1;;
- break;}
-case 172:
-#line 940 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = PPOINTER ; ;
- break;}
-case 173:
-#line 941 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = IPOINTER ; ;
- break;}
-case 174:
-#line 942 "SDCC.y"
-{ yyval.lnk = NULL ; ;
- break;}
-case 175:
-#line 943 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = GPOINTER ; ;
- break;}
-case 176:
-#line 944 "SDCC.y"
-{ yyval.lnk = newLink() ; DCL_TYPE(yyval.lnk) = UPOINTER ; ;
- break;}
-case 178:
-#line 949 "SDCC.y"
-{ yyval.lnk = mergeSpec (yyvsp[-1].lnk,yyvsp[0].lnk); ;
- break;}
-case 182:
-#line 960 "SDCC.y"
-{
- yyvsp[0].sym->next = yyvsp[-2].sym;
- yyval.sym = yyvsp[0].sym ;
- ;
- break;}
-case 184:
-#line 968 "SDCC.y"
-{ yyvsp[-2].val->vArgs = 1;;
- break;}
-case 186:
-#line 974 "SDCC.y"
-{
- yyvsp[0].val->next = yyvsp[-2].val ;
- yyval.val = yyvsp[0].val ;
- ;
- break;}
-case 187:
-#line 982 "SDCC.y"
-{
- symbol *loop ;
- pointerTypes(yyvsp[0].sym->type,yyvsp[-1].lnk);
- addDecl (yyvsp[0].sym,0,yyvsp[-1].lnk);
- for (loop=yyvsp[0].sym;loop;loop->_isparm=1,loop=loop->next);
- addSymChain (yyvsp[0].sym);
- yyval.val = symbolVal(yyvsp[0].sym);
- ;
- break;}
-case 188:
-#line 990 "SDCC.y"
-{
- yyval.val = newValue() ;
- yyval.val->type = yyvsp[0].lnk;
- yyval.val->etype = getSpec(yyval.val->type);
- ;
- break;}
-case 189:
-#line 998 "SDCC.y"
-{ yyval.lnk = yyvsp[0].lnk ;;
- break;}
-case 190:
-#line 1000 "SDCC.y"
-{
- /* go to the end of the list */
- link *p;
- pointerTypes(yyvsp[0].lnk,yyvsp[-1].lnk);
- for ( p = yyvsp[0].lnk ; p->next ; p=p->next);
- p->next = yyvsp[-1].lnk ;
- yyval.lnk = yyvsp[0].lnk ;
- ;
- break;}
-case 191:
-#line 1011 "SDCC.y"
-{ yyval.lnk = reverseLink(yyvsp[0].lnk); ;
- break;}
-case 193:
-#line 1013 "SDCC.y"
-{ yyvsp[-1].lnk = reverseLink(yyvsp[-1].lnk); yyvsp[-1].lnk->next = yyvsp[0].lnk ; yyval.lnk = yyvsp[-1].lnk;;
- break;}
-case 194:
-#line 1017 "SDCC.y"
-{ yyval.lnk = yyvsp[-1].lnk ; ;
- break;}
-case 195:
-#line 1018 "SDCC.y"
-{
- yyval.lnk = newLink ();
- DCL_TYPE(yyval.lnk) = ARRAY ;
- DCL_ELEM(yyval.lnk) = 0 ;
- ;
- break;}
-case 196:
-#line 1023 "SDCC.y"
-{
- value *val ;
- yyval.lnk = newLink ();
- DCL_TYPE(yyval.lnk) = ARRAY ;
- DCL_ELEM(yyval.lnk) = (int) floatFromVal(val = constExprValue(yyvsp[-1].asts,TRUE));
- ;
- break;}
-case 197:
-#line 1029 "SDCC.y"
-{
- yyval.lnk = newLink ();
- DCL_TYPE(yyval.lnk) = ARRAY ;
- DCL_ELEM(yyval.lnk) = 0 ;
- yyval.lnk->next = yyvsp[-2].lnk ;
- ;
- break;}
-case 198:
-#line 1036 "SDCC.y"
-{
- value *val ;
- yyval.lnk = newLink ();
- DCL_TYPE(yyval.lnk) = ARRAY ;
- DCL_ELEM(yyval.lnk) = (int) floatFromVal(val = constExprValue(yyvsp[-1].asts,TRUE));
- yyval.lnk->next = yyvsp[-3].lnk ;
- ;
- break;}
-case 199:
-#line 1043 "SDCC.y"
-{ yyval.lnk = NULL;;
- break;}
-case 200:
-#line 1044 "SDCC.y"
-{ yyval.lnk = NULL;;
- break;}
-case 203:
-#line 1050 "SDCC.y"
-{ yyval.ilist = newiList(INIT_NODE,yyvsp[0].asts); ;
- break;}
-case 204:
-#line 1051 "SDCC.y"
-{ yyval.ilist = newiList(INIT_DEEP,revinit(yyvsp[-1].ilist)); ;
- break;}
-case 205:
-#line 1052 "SDCC.y"
-{ yyval.ilist = newiList(INIT_DEEP,revinit(yyvsp[-2].ilist)); ;
- break;}
-case 207:
-#line 1057 "SDCC.y"
-{ yyvsp[0].ilist->next = yyvsp[-2].ilist; yyval.ilist = yyvsp[0].ilist; ;
- break;}
-case 214:
-#line 1067 "SDCC.y"
-{
- ast *ex = newNode(INLINEASM,NULL,NULL);
- ALLOC_ATOMIC(ex->values.inlineasm,strlen(yyvsp[-1].yyinline));
- strcpy(ex->values.inlineasm,yyvsp[-1].yyinline);
- yyval.asts = ex;
- ;
- break;}
-case 215:
-#line 1076 "SDCC.y"
-{ yyval.asts = createLabel(yyvsp[-2].sym,yyvsp[0].asts); ;
- break;}
-case 216:
-#line 1077 "SDCC.y"
-{ yyval.asts = createCase(STACK_PEEK(swStk),yyvsp[-2].asts,yyvsp[0].asts); ;
- break;}
-case 217:
-#line 1078 "SDCC.y"
-{ yyval.asts = createDefault(STACK_PEEK(swStk),yyvsp[0].asts); ;
- break;}
-case 218:
-#line 1081 "SDCC.y"
-{ STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; ;
- break;}
-case 219:
-#line 1084 "SDCC.y"
-{ currBlockno = STACK_POP(blockNum); ;
- break;}
-case 220:
-#line 1088 "SDCC.y"
-{ yyval.asts = createBlock(NULL,NULL); ;
- break;}
-case 221:
-#line 1089 "SDCC.y"
-{ yyval.asts = createBlock(NULL,yyvsp[-1].asts) ; ;
- break;}
-case 222:
-#line 1091 "SDCC.y"
-{ addSymChain(yyvsp[0].sym); ;
- break;}
-case 223:
-#line 1092 "SDCC.y"
-{ yyval.asts = createBlock(yyvsp[-2].sym,NULL) ; ;
- break;}
-case 224:
-#line 1094 "SDCC.y"
-{ addSymChain (yyvsp[0].sym); ;
- break;}
-case 225:
-#line 1096 "SDCC.y"
-{yyval.asts = createBlock(yyvsp[-3].sym,yyvsp[-1].asts) ; ;
- break;}
-case 226:
-#line 1097 "SDCC.y"
-{ yyval.asts = NULL ; ;
- break;}
-case 227:
-#line 1102 "SDCC.y"
-{
- /* if this is typedef declare it immediately */
- if ( yyvsp[0].sym && IS_TYPEDEF(yyvsp[0].sym->etype)) {
- allocVariables (yyvsp[0].sym);
- yyval.sym = NULL ;
- }
- else
- yyval.sym = yyvsp[0].sym ;
- ;
- break;}
-case 228:
-#line 1113 "SDCC.y"
-{
- symbol *sym;
-
- /* if this is a typedef */
- if (yyvsp[0].sym && IS_TYPEDEF(yyvsp[0].sym->etype)) {
- allocVariables (yyvsp[0].sym);
- yyval.sym = yyvsp[-1].sym ;
- }
- else {
- /* get to the end of the previous decl */
- if ( yyvsp[-1].sym ) {
- yyval.sym = sym = yyvsp[-1].sym ;
- while (sym->next)
- sym = sym->next ;
- sym->next = yyvsp[0].sym;
- }
- else
- yyval.sym = yyvsp[0].sym ;
- }
- ;
- break;}
-case 230:
-#line 1137 "SDCC.y"
-{ yyval.asts = newNode(NULLOP,yyvsp[-1].asts,yyvsp[0].asts) ;;
- break;}
-case 231:
-#line 1141 "SDCC.y"
-{ yyval.asts = NULL;;
- break;}
-case 233:
-#line 1146 "SDCC.y"
-{ yyval.asts = yyvsp[0].asts ; ;
- break;}
-case 234:
-#line 1147 "SDCC.y"
-{ yyval.asts = NULL;;
- break;}
-case 235:
-#line 1152 "SDCC.y"
-{ noLineno++ ; yyval.asts = createIf (yyvsp[-3].asts, yyvsp[-1].asts, yyvsp[0].asts ); noLineno--;;
- break;}
-case 236:
-#line 1153 "SDCC.y"
-{
- ast *ex ;
- static int swLabel = 0 ;
-
- /* create a node for expression */
- ex = newNode(SWITCH,yyvsp[-1].asts,NULL);
- STACK_PUSH(swStk,ex); /* save it in the stack */
- ex->values.switchVals.swNum = swLabel ;
-
- /* now create the label */
- sprintf(lbuff,"_swBrk_%d",swLabel++);
- yyval.sym = newSymbol(lbuff,NestLevel);
- /* put label in the break stack */
- STACK_PUSH(breakStack,yyval.sym);
- ;
- break;}
-case 237:
-#line 1168 "SDCC.y"
-{
- /* get back the switch form the stack */
- yyval.asts = STACK_POP(swStk) ;
- yyval.asts->right = newNode (NULLOP,yyvsp[0].asts,createLabel(yyvsp[-1].sym,NULL));
- STACK_POP(breakStack);
- ;
- break;}
-case 238:
-#line 1176 "SDCC.y"
-{ /* create and push the continue , break & body labels */
- static int Lblnum = 0 ;
- /* continue */
- sprintf (lbuff,"_whilecontinue_%d",Lblnum);
- STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
- /* break */
- sprintf (lbuff,"_whilebreak_%d",Lblnum);
- STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
- /* body */
- sprintf (lbuff,"_whilebody_%d",Lblnum++);
- yyval.sym = newSymbol(lbuff,NestLevel);
- ;
- break;}
-case 239:
-#line 1189 "SDCC.y"
-{ /* create and push the continue , break & body Labels */
- static int Lblnum = 0 ;
-
- /* continue */
- sprintf(lbuff,"_docontinue_%d",Lblnum);
- STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
- /* break */
- sprintf (lbuff,"_dobreak_%d",Lblnum);
- STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
- /* do body */
- sprintf (lbuff,"_dobody_%d",Lblnum++);
- yyval.sym = newSymbol (lbuff,NestLevel);
- ;
- break;}
-case 240:
-#line 1202 "SDCC.y"
-{ /* create & push continue, break & body labels */
- static int Lblnum = 0 ;
-
- /* continue */
- sprintf (lbuff,"_forcontinue_%d",Lblnum);
- STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
- /* break */
- sprintf (lbuff,"_forbreak_%d",Lblnum);
- STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
- /* body */
- sprintf (lbuff,"_forbody_%d",Lblnum);
- yyval.sym = newSymbol(lbuff,NestLevel);
- /* condition */
- sprintf (lbuff,"_forcond_%d",Lblnum++);
- STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
- ;
- break;}
-case 241:
-#line 1221 "SDCC.y"
-{
- noLineno++ ;
- yyval.asts = createWhile ( yyvsp[-4].sym, STACK_POP(continueStack),
- STACK_POP(breakStack), yyvsp[-2].asts, yyvsp[0].asts );
- yyval.asts->lineno = yyvsp[-4].sym->lineDef ;
- noLineno-- ;
- ;
- break;}
-case 242:
-#line 1229 "SDCC.y"
-{
- noLineno++ ;
- yyval.asts = createDo ( yyvsp[-6].sym , STACK_POP(continueStack),
- STACK_POP(breakStack), yyvsp[-2].asts, yyvsp[-5].asts);
- yyval.asts->lineno = yyvsp[-6].sym->lineDef ;
- noLineno-- ;
- ;
- break;}
-case 243:
-#line 1237 "SDCC.y"
-{
- noLineno++ ;
-
- /* if break or continue statement present
- then create a general case loop */
- if (STACK_PEEK(continueStack)->isref ||
- STACK_PEEK(breakStack)->isref) {
- yyval.asts = createFor (yyvsp[-8].sym, STACK_POP(continueStack),
- STACK_POP(breakStack) ,
- STACK_POP(forStack) ,
- yyvsp[-6].asts , yyvsp[-4].asts , yyvsp[-2].asts, yyvsp[0].asts );
- } else {
- yyval.asts = newNode(FOR,yyvsp[0].asts,NULL);
- AST_FOR(yyval.asts,trueLabel) = yyvsp[-8].sym;
- AST_FOR(yyval.asts,continueLabel) = STACK_POP(continueStack);
- AST_FOR(yyval.asts,falseLabel) = STACK_POP(breakStack);
- AST_FOR(yyval.asts,condLabel) = STACK_POP(forStack) ;
- AST_FOR(yyval.asts,initExpr) = yyvsp[-6].asts;
- AST_FOR(yyval.asts,condExpr) = yyvsp[-4].asts;
- AST_FOR(yyval.asts,loopExpr) = yyvsp[-2].asts;
- }
-
- noLineno-- ;
- ;
- break;}
-case 244:
-#line 1264 "SDCC.y"
-{ yyval.asts = NULL ; ;
- break;}
-case 246:
-#line 1269 "SDCC.y"
-{
- yyvsp[-1].sym->islbl = 1;
- yyval.asts = newAst(EX_VALUE,symbolVal(yyvsp[-1].sym));
- yyval.asts = newNode(GOTO,yyval.asts,NULL);
- ;
- break;}
-case 247:
-#line 1274 "SDCC.y"
-{
- /* make sure continue is in context */
- if (STACK_PEEK(continueStack) == NULL) {
- werror(E_BREAK_CONTEXT);
- yyval.asts = NULL;
- }
- else {
- yyval.asts = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
- yyval.asts = newNode(GOTO,yyval.asts,NULL);
- /* mark the continue label as referenced */
- STACK_PEEK(continueStack)->isref = 1;
- }
- ;
- break;}
-case 248:
-#line 1287 "SDCC.y"
-{
- if (STACK_PEEK(breakStack) == NULL) {
- werror(E_BREAK_CONTEXT);
- yyval.asts = NULL;
- } else {
- yyval.asts = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
- yyval.asts = newNode(GOTO,yyval.asts,NULL);
- STACK_PEEK(breakStack)->isref = 1;
- }
- ;
- break;}
-case 249:
-#line 1297 "SDCC.y"
-{ yyval.asts = newNode(RETURN,NULL,NULL) ; ;
- break;}
-case 250:
-#line 1298 "SDCC.y"
-{ yyval.asts = newNode(RETURN,NULL,yyvsp[-1].asts) ; ;
- break;}
-case 251:
-#line 1302 "SDCC.y"
-{ yyval.sym = newSymbol (yyvsp[0].yychar,NestLevel) ; ;
- break;}
-}
- /* the action file gets copied in in place of this dollarsign */
-#line 543 "/usr/share/misc/bison.simple"
-\f
- yyvsp -= yylen;
- yyssp -= yylen;
-#ifdef YYLSP_NEEDED
- yylsp -= yylen;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
-#endif
-
- *++yyvsp = yyval;
-
-#ifdef YYLSP_NEEDED
- yylsp++;
- if (yylen == 0)
- {
- yylsp->first_line = yylloc.first_line;
- yylsp->first_column = yylloc.first_column;
- yylsp->last_line = (yylsp-1)->last_line;
- yylsp->last_column = (yylsp-1)->last_column;
- yylsp->text = 0;
- }
- else
- {
- yylsp->last_line = (yylsp+yylen-1)->last_line;
- yylsp->last_column = (yylsp+yylen-1)->last_column;
- }
-#endif
-
- /* Now "shift" the result of the reduction.
- Determine what state that goes to,
- based on the state we popped back to
- and the rule number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
- if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTBASE];
-
- goto yynewstate;
-
-yyerrlab: /* here on detecting error */
-
- if (! yyerrstatus)
- /* If not already recovering from an error, report this error. */
- {
- ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (yyn > YYFLAG && yyn < YYLAST)
- {
- int size = 0;
- char *msg;
- int x, count;
-
- count = 0;
- /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- size += strlen(yytname[x]) + 15, count++;
- msg = (char *) malloc(size + 15);
- if (msg != 0)
- {
- strcpy(msg, "parse error");
-
- if (count < 5)
- {
- count = 0;
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- {
- strcat(msg, count == 0 ? ", expecting `" : " or `");
- strcat(msg, yytname[x]);
- strcat(msg, "'");
- count++;
- }
- }
- yyerror(msg);
- free(msg);
- }
- else
- yyerror ("parse error; also virtual memory exceeded");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror("parse error");
- }
-
- goto yyerrlab1;
-yyerrlab1: /* here on error raised explicitly by an action */
-
- if (yyerrstatus == 3)
- {
- /* if just tried and failed to reuse lookahead token after an error, discard it. */
-
- /* return failure if at end of input */
- if (yychar == YYEOF)
- YYABORT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
-#endif
-
- yychar = YYEMPTY;
- }
-
- /* Else will try to reuse lookahead token
- after shifting the error token. */
-
- yyerrstatus = 3; /* Each real token shifted decrements this */
-
- goto yyerrhandle;
-
-yyerrdefault: /* current state does not do anything special for the error token. */
-
-#if 0
- /* This is wrong; only states that explicitly want error tokens
- should shift them. */
- yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
- if (yyn) goto yydefault;
-#endif
-
-yyerrpop: /* pop the current state because it cannot handle the error token */
-
- if (yyssp == yyss) YYABORT;
- yyvsp--;
- yystate = *--yyssp;
-#ifdef YYLSP_NEEDED
- yylsp--;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "Error: state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
-#endif
-
-yyerrhandle:
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yyerrdefault;
-
- yyn += YYTERROR;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
- goto yyerrdefault;
-
- yyn = yytable[yyn];
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrpop;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrpop;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting error token, ");
-#endif
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- yystate = yyn;
- goto yynewstate;
-
- yyacceptlab:
- /* YYACCEPT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 0;
-
- yyabortlab:
- /* YYABORT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 1;
-}
-#line 1304 "SDCC.y"
-
-
-extern unsigned char *yytext;
-extern int column;
-extern char *filename;
-extern int fatalError;
-
-int yyerror(char *s)
-{
- fflush(stdout);
-
- if ( yylineno )
- fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",
- filename,yylineno,
- s,yytext,column);
- fatalError++;
- return 0;
-}
-
--- /dev/null
+PRJDIR = ../..
+
+include $(PRJDIR)/Makefile.common
+
+OBJ = gen.o ralloc.o
+LIB = port.a
+
+CFLAGS = -ggdb -Wall
+CFLAGS += -I.. -I. -I../..
+
+all: $(LIB)
+
+$(LIB): $(OBJ)
+ rm -f $(LIB)
+ ar r $(LIB) $(OBJ)
+ ranlib $(LIB)
+
+clean:
+ rm -f $(LIB) *.o *~
--- /dev/null
+/*-------------------------------------------------------------------------
+ SDCCgen51.c - source file for code generation for 8051
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+ and - Jean-Louis VERN.jlvern@writeme.com (1999)
+ Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+
+-------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "SDCCglobl.h"
+
+#ifdef HAVE_SYS_ISA_DEFS_H
+#include <sys/isa_defs.h>
+#else
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#else
+#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
+#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
+#endif
+#endif
+
+#include "SDCCast.h"
+#include "SDCCmem.h"
+#include "SDCCy.h"
+#include "SDCChasht.h"
+#include "SDCCbitv.h"
+#include "SDCCset.h"
+#include "SDCCicode.h"
+#include "SDCClabel.h"
+#include "SDCCBBlock.h"
+#include "SDCCloop.h"
+#include "SDCCcse.h"
+#include "SDCCcflow.h"
+#include "SDCCdflow.h"
+#include "SDCClrange.h"
+#include "SDCCralloc.h"
+#include "SDCCgen51.h"
+#include "SDCCpeeph.h"
+
+/* this is the down and dirty file with all kinds of
+kludgy & hacky stuff. This is what it is all about
+CODE GENERATION for a specific MCU . some of the
+routines may be reusable, will have to see */
+
+static char *zero = "#0x00";
+static char *one = "#0x01";
+static char *spname ;
+static char *fReturn[] = {"dpl","dph","b","a" };
+static char *accUse[] = {"a","b"};
+short r0Pushed = 0;
+short r1Pushed = 0;
+short rbank = -1;
+short accInUse = 0 ;
+short inLine = 0;
+short debugLine = 0;
+short nregssaved = 0;
+extern int ptrRegReq ;
+extern int nRegs;
+extern FILE *codeOutFile;
+set *sendSet = NULL;
+static void saverbank (int, iCode *,bool);
+#define RESULTONSTACK(x) \
+ (IC_RESULT(x) && IC_RESULT(x)->aop && \
+ IC_RESULT(x)->aop->type == AOP_STK )
+
+#define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x);
+#define CLRC emitcode("clr","c");
+
+lineNode *lineHead = NULL;
+lineNode *lineCurr = NULL;
+
+unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
+0xE0, 0xC0, 0x80, 0x00};
+unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
+0x07, 0x03, 0x01, 0x00};
+
+#define LSB 0
+#define MSB16 1
+#define MSB24 2
+#define MSB32 3
+
+/*-----------------------------------------------------------------*/
+/* emitcode - writes the code into a file : for now it is simple */
+/*-----------------------------------------------------------------*/
+void emitcode (char *inst,char *fmt, ...)
+{
+ va_list ap;
+ char lb[MAX_INLINEASM];
+ char *lbp = lb;
+
+ va_start(ap,fmt);
+
+ if (inst && *inst) {
+ if (fmt && *fmt)
+ sprintf(lb,"%s\t",inst);
+ else
+ sprintf(lb,"%s",inst);
+ vsprintf(lb+(strlen(lb)),fmt,ap);
+ } else
+ vsprintf(lb,fmt,ap);
+
+ while (isspace(*lbp)) lbp++;
+
+ if (lbp && *lbp)
+ lineCurr = (lineCurr ?
+ connectLine(lineCurr,newLineNode(lb)) :
+ (lineHead = newLineNode(lb)));
+ lineCurr->isInline = inLine;
+ lineCurr->isDebug = debugLine;
+ va_end(ap);
+}
+
+/*-----------------------------------------------------------------*/
+/* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
+/*-----------------------------------------------------------------*/
+static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
+{
+ bool r0iu = FALSE , r1iu = FALSE;
+ bool r0ou = FALSE , r1ou = FALSE;
+
+ /* the logic: if r0 & r1 used in the instruction
+ then we are in trouble otherwise */
+
+ /* first check if r0 & r1 are used by this
+ instruction, in which case we are in trouble */
+ if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
+ (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
+ goto endOfWorld;
+
+
+ r0ou = bitVectBitValue(ic->rMask,R0_IDX);
+ r1ou = bitVectBitValue(ic->rMask,R1_IDX);
+
+ /* if no usage of r0 then return it */
+ if (!r0iu && !r0ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
+ (*aopp)->type = AOP_R0;
+ return (*aopp)->aopu.aop_ptr = regWithIdx(R0_IDX);
+ }
+
+ /* if no usage of r1 then return it */
+ if (!r1iu && !r1ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
+ (*aopp)->type = AOP_R1;
+ return (*aopp)->aopu.aop_ptr = regWithIdx(R1_IDX);
+ }
+
+ /* now we know they both have usage */
+ /* if r0 not used in this instruction */
+ if (!r0iu) {
+ /* push it if not already pushed */
+ if (!r0Pushed) {
+ emitcode ("push","%s",
+ regWithIdx(R0_IDX)->dname);
+ r0Pushed++ ;
+ }
+
+ ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
+ (*aopp)->type = AOP_R0;
+
+ return (*aopp)->aopu.aop_ptr = regWithIdx(R0_IDX);
+ }
+
+ /* if r1 not used then */
+
+ if (!r1iu) {
+ /* push it if not already pushed */
+ if (!r1Pushed) {
+ emitcode ("push","%s",
+ regWithIdx(R1_IDX)->dname);
+ r1Pushed++ ;
+ }
+
+ ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
+ (*aopp)->type = AOP_R1;
+ return regWithIdx(R1_IDX);
+ }
+
+
+endOfWorld :
+ /* I said end of world but not quite end of world yet */
+ /* if this is a result then we canpush it on the stack*/
+ if (result) {
+ (*aopp)->type = AOP_STK;
+ return NULL;
+ }
+
+ piCode(ic,stdout);
+ /* other wise this is true end of the world */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "getFreePtr should never reach here");
+ exit(0);
+}
+
+/*-----------------------------------------------------------------*/
+/* newAsmop - creates a new asmOp */
+/*-----------------------------------------------------------------*/
+static asmop *newAsmop (short type)
+{
+ asmop *aop;
+
+ ALLOC(aop,sizeof(asmop));
+ aop->type = type;
+ return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* pointerCode - returns the code for a pointer type */
+/*-----------------------------------------------------------------*/
+static int pointerCode (link *etype)
+{
+ int p_type;
+ if (SPEC_OCLS(etype)->codesp ) {
+ p_type = CPOINTER ;
+ }
+ else
+ if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+ p_type = FPOINTER ;
+ else
+ if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+ p_type = PPOINTER;
+ else
+ if (SPEC_OCLS(etype) == idata )
+ p_type = IPOINTER;
+ else
+ p_type = POINTER ;
+ return p_type;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopForSym - for a true symbol */
+/*-----------------------------------------------------------------*/
+static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
+{
+ asmop *aop;
+ memmap *space= SPEC_OCLS(sym->etype);
+
+ /* if already has one */
+ if (sym->aop)
+ return sym->aop;
+
+ /* assign depending on the storage class */
+ /* if it is on the stack or indirectly addressable */
+ /* space we need to assign either r0 or r1 to it */
+ if (sym->onStack || sym->iaccess) {
+ sym->aop = aop = newAsmop(0);
+ aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
+ aop->size = getSize(sym->type);
+
+ /* now assign the address of the variable to
+ the pointer register */
+ if (aop->type != AOP_STK) {
+
+ if (sym->onStack) {
+
+ if ( accInUse )
+ emitcode("push","acc");
+
+ emitcode("mov","a,_bp");
+ emitcode("add","a,#0x%02x",
+ ((sym->stack < 0) ?
+ ((char)(sym->stack - nregssaved )) :
+ ((char)sym->stack)) & 0xff);
+ emitcode("mov","%s,a",
+ aop->aopu.aop_ptr->name);
+
+ if ( accInUse )
+ emitcode("pop","acc");
+
+ } else
+ emitcode("mov","%s,#%s",
+ aop->aopu.aop_ptr->name,
+ sym->rname);
+ aop->paged = space->paged;
+ } else
+ aop->aopu.aop_stk = sym->stack;
+ return aop;
+ }
+
+ /* if in bit space */
+ if (IN_BITSPACE(space)) {
+ sym->aop = aop = newAsmop (AOP_CRY);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ return aop;
+ }
+ /* if it is in direct space */
+ if (IN_DIRSPACE(space)) {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ return aop;
+ }
+
+ /* special case for a function */
+ if (IS_FUNC(sym->type)) {
+ sym->aop = aop = newAsmop(AOP_IMMD);
+ ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
+ strcpy(aop->aopu.aop_immd,sym->rname);
+ aop->size = 2;
+ return aop;
+ }
+
+ /* only remaining is far space */
+ /* in which case DPTR gets the address */
+ sym->aop = aop = newAsmop(AOP_DPTR);
+ emitcode ("mov","dptr,#%s", sym->rname);
+ aop->size = getSize(sym->type);
+
+ /* if it is in code space */
+ if (IN_CODESPACE(space))
+ aop->code = 1;
+
+ return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopForRemat - rematerialzes an object */
+/*-----------------------------------------------------------------*/
+static asmop *aopForRemat (symbol *sym)
+{
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+ asmop *aop = newAsmop(AOP_IMMD);
+
+ while (1) {
+
+ /* if plus or minus print the right hand side */
+ if (ic->op == '+' || ic->op == '-') {
+ sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
+ ic->op );
+ s += strlen(s);
+ ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ continue ;
+ }
+
+ /* we reached the end */
+ sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
+ break;
+ }
+
+ ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(buffer)+1);
+ strcpy(aop->aopu.aop_immd,buffer);
+ return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* regsInCommon - two operands have some registers in common */
+/*-----------------------------------------------------------------*/
+bool regsInCommon (operand *op1, operand *op2)
+{
+ symbol *sym1, *sym2;
+ int i;
+
+ /* if they have registers in common */
+ if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
+ return FALSE ;
+
+ sym1 = OP_SYMBOL(op1);
+ sym2 = OP_SYMBOL(op2);
+
+ if (sym1->nRegs == 0 || sym2->nRegs == 0)
+ return FALSE ;
+
+ for (i = 0 ; i < sym1->nRegs ; i++) {
+ int j;
+ if (!sym1->regs[i])
+ continue ;
+
+ for (j = 0 ; j < sym2->nRegs ;j++ ) {
+ if (!sym2->regs[j])
+ continue ;
+
+ if (sym2->regs[j] == sym1->regs[i])
+ return TRUE ;
+ }
+ }
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsEqu - equivalent */
+/*-----------------------------------------------------------------*/
+bool operandsEqu ( operand *op1, operand *op2)
+{
+ symbol *sym1, *sym2;
+
+ /* if they not symbols */
+ if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
+ return FALSE;
+
+ sym1 = OP_SYMBOL(op1);
+ sym2 = OP_SYMBOL(op2);
+
+ /* if both are itemps & one is spilt
+ and the other is not then false */
+ if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
+ sym1->isspilt != sym2->isspilt )
+ return FALSE ;
+
+ /* if they are the same */
+ if (sym1 == sym2)
+ return TRUE ;
+
+ if (strcmp(sym1->rname,sym2->rname) == 0)
+ return TRUE;
+
+
+ /* if left is a tmp & right is not */
+ if (IS_ITEMP(op1) &&
+ !IS_ITEMP(op2) &&
+ sym1->isspilt &&
+ (sym1->usl.spillLoc == sym2))
+ return TRUE;
+
+ if (IS_ITEMP(op2) &&
+ !IS_ITEMP(op1) &&
+ sym2->isspilt &&
+ sym1->level > 0 &&
+ (sym2->usl.spillLoc == sym1))
+ return TRUE ;
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* sameRegs - two asmops have the same registers */
+/*-----------------------------------------------------------------*/
+bool sameRegs (asmop *aop1, asmop *aop2 )
+{
+ int i;
+
+ if (aop1 == aop2)
+ return TRUE ;
+
+ if (aop1->type != AOP_REG ||
+ aop2->type != AOP_REG )
+ return FALSE ;
+
+ if (aop1->size != aop2->size )
+ return FALSE ;
+
+ for (i = 0 ; i < aop1->size ; i++ )
+ if (aop1->aopu.aop_reg[i] !=
+ aop2->aopu.aop_reg[i] )
+ return FALSE ;
+
+ return TRUE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopOp - allocates an asmop for an operand : */
+/*-----------------------------------------------------------------*/
+static void aopOp (operand *op, iCode *ic, bool result)
+{
+ asmop *aop;
+ symbol *sym;
+ int i;
+
+ if (!op)
+ return ;
+
+ /* if this a literal */
+ if (IS_OP_LITERAL(op)) {
+ op->aop = aop = newAsmop(AOP_LIT);
+ aop->aopu.aop_lit = op->operand.valOperand;
+ aop->size = getSize(operandType(op));
+ return;
+ }
+
+ /* if already has a asmop then continue */
+ if (op->aop)
+ return ;
+
+ /* if the underlying symbol has a aop */
+ if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
+ op->aop = OP_SYMBOL(op)->aop;
+ return;
+ }
+
+ /* if this is a true symbol */
+ if (IS_TRUE_SYMOP(op)) {
+ op->aop = aopForSym(ic,OP_SYMBOL(op),result);
+ return ;
+ }
+
+ /* this is a temporary : this has
+ only four choices :
+ a) register
+ b) spillocation
+ c) rematerialize
+ d) conditional
+ e) can be a return use only */
+
+ sym = OP_SYMBOL(op);
+
+
+ /* if the type is a conditional */
+ if (sym->regType == REG_CND) {
+ aop = op->aop = sym->aop = newAsmop(AOP_CRY);
+ aop->size = 0;
+ return;
+ }
+
+ /* if it is spilt then two situations
+ a) is rematerialize
+ b) has a spill location */
+ if (sym->isspilt || sym->nRegs == 0) {
+
+ /* rematerialize it NOW */
+ if (sym->remat) {
+ sym->aop = op->aop = aop =
+ aopForRemat (sym);
+ aop->size = getSize(sym->type);
+ return;
+ }
+
+ if (sym->accuse) {
+ int i;
+ aop = op->aop = sym->aop = newAsmop(AOP_ACC);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < 2 ; i++ )
+ aop->aopu.aop_str[i] = accUse[i];
+ return;
+ }
+
+ if (sym->ruonly ) {
+ int i;
+ aop = op->aop = sym->aop = newAsmop(AOP_STR);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < 4 ; i++ )
+ aop->aopu.aop_str[i] = fReturn[i];
+ return;
+ }
+
+ /* else spill location */
+ sym->aop = op->aop = aop =
+ aopForSym(ic,sym->usl.spillLoc,result);
+ aop->size = getSize(sym->type);
+ return;
+ }
+
+ /* must be in a register */
+ sym->aop = op->aop = aop = newAsmop(AOP_REG);
+ aop->size = sym->nRegs;
+ for ( i = 0 ; i < sym->nRegs ;i++)
+ aop->aopu.aop_reg[i] = sym->regs[i];
+}
+
+/*-----------------------------------------------------------------*/
+/* freeAsmop - free up the asmop given to an operand */
+/*----------------------------------------------------------------*/
+static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
+{
+ asmop *aop ;
+
+ if (!op)
+ aop = aaop;
+ else
+ aop = op->aop;
+
+ if (!aop)
+ return ;
+
+ if (aop->freed)
+ goto dealloc;
+
+ aop->freed = 1;
+
+ /* depending on the asmop type only three cases need work AOP_RO
+ , AOP_R1 && AOP_STK */
+ switch (aop->type) {
+ case AOP_R0 :
+ if (r0Pushed ) {
+ if (pop) {
+ emitcode ("pop","ar0");
+ r0Pushed--;
+ }
+ }
+ bitVectUnSetBit(ic->rUsed,R0_IDX);
+ break;
+
+ case AOP_R1 :
+ if (r1Pushed ) {
+ if (pop) {
+ emitcode ("pop","ar1");
+ r1Pushed--;
+ }
+ }
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
+ break;
+
+ case AOP_STK :
+ {
+ int sz = aop->size;
+ int stk = aop->aopu.aop_stk + aop->size;
+ bitVectUnSetBit(ic->rUsed,R0_IDX);
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
+
+ getFreePtr(ic,&aop,FALSE);
+ if (stk) {
+ emitcode ("mov","a,_bp");
+ emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
+ emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
+ } else
+ emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
+
+ while (sz--) {
+ emitcode("pop","acc");
+ emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
+ if (!sz) break;
+ emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ }
+ op->aop = aop;
+ freeAsmop(op,NULL,ic,TRUE);
+ if (r0Pushed) {
+ emitcode("pop","ar0");
+ r0Pushed--;
+ }
+
+ if (r1Pushed) {
+ emitcode("pop","ar1");
+ r1Pushed--;
+ }
+ }
+ }
+
+dealloc:
+ /* all other cases just dealloc */
+ if (op ) {
+ op->aop = NULL;
+ if (IS_SYMOP(op)) {
+ OP_SYMBOL(op)->aop = NULL;
+ /* if the symbol has a spill */
+ if (SPIL_LOC(op))
+ SPIL_LOC(op)->aop = NULL;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* aopLiteral - string from a literal value */
+/*-----------------------------------------------------------------*/
+char *aopLiteral (value *val, int offset)
+{
+ char *rs;
+ union {
+ float f;
+ unsigned char c[4];
+ } fl;
+
+ /* if it is a float then it gets tricky */
+ /* otherwise it is fairly simple */
+ if (!IS_FLOAT(val->type)) {
+ unsigned long v = floatFromVal(val);
+
+ v >>= (offset * 8);
+ sprintf(buffer,"#0x%02x",((char) v) & 0xff);
+ ALLOC_ATOMIC(rs,strlen(buffer)+1);
+ return strcpy (rs,buffer);
+ }
+
+ /* it is type float */
+ fl.f = (float) floatFromVal(val);
+#ifdef _BIG_ENDIAN
+ sprintf(buffer,"#0x%02x",fl.c[3-offset]);
+#else
+ sprintf(buffer,"#0x%02x",fl.c[offset]);
+#endif
+ ALLOC_ATOMIC(rs,strlen(buffer)+1);
+ return strcpy (rs,buffer);
+}
+
+/*-----------------------------------------------------------------*/
+/* aopGet - for fetching value of the aop */
+/*-----------------------------------------------------------------*/
+static char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
+{
+ char *s = buffer ;
+ char *rs;
+
+ /* offset is greater than
+ size then zero */
+ if (offset > (aop->size - 1) &&
+ aop->type != AOP_LIT)
+ return zero;
+
+ /* depending on type */
+ switch (aop->type) {
+
+ case AOP_R0:
+ case AOP_R1:
+ /* if we need to increment it */
+ while (offset > aop->coff) {
+ emitcode ("inc","%s",aop->aopu.aop_ptr->name);
+ aop->coff++;
+ }
+
+ while (offset < aop->coff) {
+ emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ aop->coff--;
+ }
+
+ aop->coff = offset ;
+ if (aop->paged) {
+ emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
+ return (dname ? "acc" : "a");
+ }
+ sprintf(s,"@%s",aop->aopu.aop_ptr->name);
+ ALLOC_ATOMIC(rs,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_DPTR:
+ while (offset > aop->coff) {
+ emitcode ("inc","dptr");
+ aop->coff++;
+ }
+
+ while (offset < aop->coff) {
+ emitcode("lcall","__decdptr");
+ aop->coff--;
+ }
+
+ aop->coff = offset;
+ if (aop->code) {
+ emitcode("clr","a");
+ emitcode("movc","a,@a+dptr");
+ }
+ else
+ emitcode("movx","a,@dptr");
+ return (dname ? "acc" : "a");
+
+
+ case AOP_IMMD:
+ if (bit16)
+ sprintf (s,"#(%s)",aop->aopu.aop_immd);
+ else
+ if (offset)
+ sprintf(s,"#(%s >> %d)",
+ aop->aopu.aop_immd,
+ offset*8);
+ else
+ sprintf(s,"#%s",
+ aop->aopu.aop_immd);
+ ALLOC_ATOMIC(rs,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_DIR:
+ if (offset)
+ sprintf(s,"(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
+ else
+ sprintf(s,"%s",aop->aopu.aop_dir);
+ ALLOC_ATOMIC(rs,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_REG:
+ if (dname)
+ return aop->aopu.aop_reg[offset]->dname;
+ else
+ return aop->aopu.aop_reg[offset]->name;
+
+ case AOP_CRY:
+ emitcode("clr","a");
+ emitcode("mov","c,%s",aop->aopu.aop_dir);
+ emitcode("rlc","a") ;
+ return (dname ? "acc" : "a");
+
+ case AOP_ACC:
+ if (!offset && dname)
+ return "acc";
+ return aop->aopu.aop_str[offset];
+
+ case AOP_LIT:
+ return aopLiteral (aop->aopu.aop_lit,offset);
+
+ case AOP_STR:
+ aop->coff = offset ;
+ if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+ dname)
+ return "acc";
+
+ return aop->aopu.aop_str[offset];
+
+ }
+
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopget got unsupported aop->type");
+ exit(0);
+}
+/*-----------------------------------------------------------------*/
+/* aopPut - puts a string for a aop */
+/*-----------------------------------------------------------------*/
+static void aopPut (asmop *aop, char *s, int offset)
+{
+ char *d = buffer ;
+ symbol *lbl ;
+
+ if (aop->size && offset > ( aop->size - 1)) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut got offset > aop->size");
+ exit(0);
+ }
+
+ /* will assign value to value */
+ /* depending on where it is ofcourse */
+ switch (aop->type) {
+ case AOP_DIR:
+ if (offset)
+ sprintf(d,"(%s + %d)",
+ aop->aopu.aop_dir,offset);
+ else
+ sprintf(d,"%s",aop->aopu.aop_dir);
+
+ if (strcmp(d,s))
+ emitcode("mov","%s,%s",d,s);
+
+ break;
+
+ case AOP_REG:
+ if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
+ strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
+ if (*s == '@' ||
+ strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 )
+ emitcode("mov","%s,%s",
+ aop->aopu.aop_reg[offset]->dname,s);
+ else
+ emitcode("mov","%s,%s",
+ aop->aopu.aop_reg[offset]->name,s);
+ }
+ break;
+
+ case AOP_DPTR:
+ if (aop->code) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut writting to code space");
+ exit(0);
+ }
+
+ while (offset > aop->coff) {
+ aop->coff++;
+ emitcode ("inc","dptr");
+ }
+
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ emitcode("lcall","__decdptr");
+ }
+
+ aop->coff = offset;
+
+ /* if not in accumulater */
+ MOVA(s);
+
+ emitcode ("movx","@dptr,a");
+ break;
+
+ case AOP_R0:
+ case AOP_R1:
+ while (offset > aop->coff) {
+ aop->coff++;
+ emitcode("inc","%s",aop->aopu.aop_ptr->name);
+ }
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ emitcode ("dec","%s",aop->aopu.aop_ptr->name);
+ }
+ aop->coff = offset;
+
+ if (aop->paged) {
+ MOVA(s);
+ emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
+
+ } else
+ if (*s == '@') {
+ MOVA(s);
+ emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
+ } else
+ if (strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 ) {
+ char buffer[10];
+ sprintf(buffer,"a%s",s);
+ emitcode("mov","@%s,%s",
+ aop->aopu.aop_ptr->name,buffer);
+ } else
+ emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
+
+ break;
+
+ case AOP_STK:
+ if (strcmp(s,"a") == 0)
+ emitcode("push","acc");
+ else
+ emitcode("push","%s",s);
+
+ break;
+
+ case AOP_CRY:
+ /* if bit variable */
+ if (!aop->aopu.aop_dir) {
+ emitcode("clr","a");
+ emitcode("rlc","a");
+ } else {
+ if (s == zero)
+ emitcode("clr","%s",aop->aopu.aop_dir);
+ else
+ if (s == one)
+ emitcode("setb","%s",aop->aopu.aop_dir);
+ else
+ if (!strcmp(s,"c"))
+ emitcode("mov","%s,c",aop->aopu.aop_dir);
+ else {
+ lbl = newiTempLabel(NULL);
+
+ if (strcmp(s,"a")) {
+ MOVA(s);
+ }
+ emitcode("cjne","a,#0x01,%05d$",lbl->key+100);
+ emitcode("","%05d$:",lbl->key+100);
+ emitcode("cpl","c");
+ emitcode("mov","%s,c",aop->aopu.aop_dir);
+ }
+ }
+ break;
+
+ case AOP_STR:
+ aop->coff = offset;
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ emitcode ("mov","%s,%s",aop->aopu.aop_str[offset],s);
+ break;
+
+ case AOP_ACC:
+ aop->coff = offset;
+ if (!offset && (strcmp(s,"acc") == 0))
+ break;
+
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ emitcode ("mov","%s,%s",aop->aopu.aop_str[offset],s);
+ break;
+
+ default :
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut got unsupported aop->type");
+ exit(0);
+ }
+
+}
+
+
+#if 0
+/*-----------------------------------------------------------------*/
+/* pointToEnd :- points to the last byte of the operand */
+/*-----------------------------------------------------------------*/
+static void pointToEnd (asmop *aop)
+{
+ int count ;
+ if (!aop)
+ return ;
+
+ aop->coff = count = (aop->size - 1);
+ switch (aop->type) {
+ case AOP_R0 :
+ case AOP_R1 :
+ while (count--)
+ emitcode("inc","%s",aop->aopu.aop_ptr->name);
+ break;
+ case AOP_DPTR :
+ while (count--)
+ emitcode("inc","dptr");
+ break;
+ }
+
+}
+#endif
+
+/*-----------------------------------------------------------------*/
+/* reAdjustPreg - points a register back to where it should */
+/*-----------------------------------------------------------------*/
+static void reAdjustPreg (asmop *aop)
+{
+ int size ;
+
+ aop->coff = 0;
+ if ((size = aop->size) <= 1)
+ return ;
+ size-- ;
+ switch (aop->type) {
+ case AOP_R0 :
+ case AOP_R1 :
+ while (size--)
+ emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ break;
+ case AOP_DPTR :
+ while (size--)
+ emitcode("lcall","__decdptr");
+ break;
+
+ }
+
+}
+
+#define AOP(op) op->aop
+#define AOP_TYPE(op) AOP(op)->type
+#define AOP_SIZE(op) AOP(op)->size
+#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
+ AOP_TYPE(x) == AOP_R0))
+
+#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
+ AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged))
+
+#define AOP_INPREG(x) (x && (x->type == AOP_REG && \
+ (x->aopu.aop_reg[0] == regWithIdx(R0_IDX) || \
+ x->aopu.aop_reg[0] == regWithIdx(R1_IDX) )))
+
+/*-----------------------------------------------------------------*/
+/* genNotFloat - generates not for float operations */
+/*-----------------------------------------------------------------*/
+static void genNotFloat (operand *op, operand *res)
+{
+ int size, offset;
+ char *l;
+ symbol *tlbl ;
+
+ /* we will put 127 in the first byte of
+ the result */
+ aopPut(AOP(res),"#127",0);
+ size = AOP_SIZE(op) - 1;
+ offset = 1;
+
+ l = aopGet(op->aop,offset++,FALSE,FALSE);
+ MOVA(l);
+
+ while(size--) {
+ emitcode("orl","a,%s",
+ aopGet(op->aop,
+ offset++,FALSE,FALSE));
+ }
+ tlbl = newiTempLabel(NULL);
+
+ tlbl = newiTempLabel(NULL);
+ aopPut(res->aop,one,1);
+ emitcode("jz","%05d$",(tlbl->key+100));
+ aopPut(res->aop,zero,1);
+ emitcode("","%05d$:",(tlbl->key+100));
+
+ size = res->aop->size - 2;
+ offset = 2;
+ /* put zeros in the rest */
+ while (size--)
+ aopPut(res->aop,zero,offset++);
+}
+
+/*-----------------------------------------------------------------*/
+/* getDataSize - get the operand data size */
+/*-----------------------------------------------------------------*/
+int getDataSize(operand *op)
+{
+ int size;
+ size = AOP_SIZE(op);
+ if(size == 3)
+ /* pointer */
+ size--;
+ return size;
+}
+
+/*-----------------------------------------------------------------*/
+/* outAcc - output Acc */
+/*-----------------------------------------------------------------*/
+void outAcc(operand *result)
+{
+ int size, offset;
+ size = getDataSize(result);
+ if(size){
+ aopPut(AOP(result),"a",0);
+ size--;
+ offset = 1;
+ /* unsigned or positive */
+ while(size--){
+ aopPut(AOP(result),zero,offset++);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* outBitC - output a bit C */
+/*-----------------------------------------------------------------*/
+void outBitC(operand *result)
+{
+ /* if the result is bit */
+ if (AOP_TYPE(result) == AOP_CRY)
+ aopPut(AOP(result),"c",0);
+ else {
+ emitcode("clr","a");
+ emitcode("rlc","a");
+ outAcc(result);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* toBoolean - emit code for orl a,operator(sizeop) */
+/*-----------------------------------------------------------------*/
+void toBoolean(operand *oper)
+{
+ int size = AOP_SIZE(oper) - 1;
+ int offset = 1;
+ MOVA(aopGet(AOP(oper),0,FALSE,FALSE));
+ while (size--)
+ emitcode("orl","a,%s",aopGet(AOP(oper),offset++,FALSE,FALSE));
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genNot - generate code for ! operation */
+/*-----------------------------------------------------------------*/
+static void genNot (iCode *ic)
+{
+ symbol *tlbl;
+ link *optype = operandType(IC_LEFT(ic));
+
+ /* assign asmOps to operand & result */
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ /* if in bit space then a special case */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
+ emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
+ emitcode("cpl","c");
+ outBitC(IC_RESULT(ic));
+ goto release;
+ }
+
+ /* if type float then do float */
+ if (IS_FLOAT(optype)) {
+ genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
+ goto release;
+ }
+
+ toBoolean(IC_LEFT(ic));
+
+ tlbl = newiTempLabel(NULL);
+ emitcode("cjne","a,#0x01,%05d$",tlbl->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitC(IC_RESULT(ic));
+
+release:
+ /* release the aops */
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genCpl - generate code for complement */
+/*-----------------------------------------------------------------*/
+static void genCpl (iCode *ic)
+{
+ int offset = 0;
+ int size ;
+
+
+ /* assign asmOps to operand & result */
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ /* if both are in bit space then
+ a special case */
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
+ emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
+ emitcode("cpl","c");
+ emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
+ goto release;
+ }
+
+ size = AOP_SIZE(IC_RESULT(ic));
+ while (size--) {
+ char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("cpl","a");
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+
+release:
+ /* release the aops */
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genUminusFloat - unary minus for floating points */
+/*-----------------------------------------------------------------*/
+static void genUminusFloat(operand *op,operand *result)
+{
+ int size ,offset =0 ;
+ char *l;
+ /* for this we just need to flip the
+ first it then copy the rest in place */
+ size = AOP_SIZE(op) - 1;
+ l = aopGet(AOP(op),3,FALSE,FALSE);
+
+ MOVA(l);
+
+ emitcode("cpl","acc.7");
+ aopPut(AOP(result),"a",3);
+
+ while(size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(op),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genUminus - unary minus code generation */
+/*-----------------------------------------------------------------*/
+static void genUminus (iCode *ic)
+{
+ int offset ,size ;
+ link *optype, *rtype;
+
+
+ /* assign asmops */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ aopOp(IC_RESULT(ic),ic,TRUE);
+
+ /* if both in bit space then special
+ case */
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
+ emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
+ emitcode("cpl","c");
+ emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
+ goto release;
+ }
+
+ optype = operandType(IC_LEFT(ic));
+ rtype = operandType(IC_RESULT(ic));
+
+ /* if float then do float stuff */
+ if (IS_FLOAT(optype)) {
+ genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
+ goto release;
+ }
+
+ /* otherwise subtract from zero */
+ size = AOP_SIZE(IC_LEFT(ic));
+ offset = 0 ;
+ CLRC ;
+ while(size--) {
+ char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
+ if (!strcmp(l,"a")) {
+ emitcode("cpl","a");
+ emitcode("inc","a");
+ } else {
+ emitcode("clr","a");
+ emitcode("subb","a,%s",l);
+ }
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+ /* if any remaining bytes in the result */
+ /* we just need to propagate the sign */
+ if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
+ emitcode("rlc","a");
+ emitcode("subb","a,acc");
+ while (size--)
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+release:
+ /* release the aops */
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* saveRegisters - will look for a call and save the registers */
+/*-----------------------------------------------------------------*/
+static void saveRegisters(iCode *lic)
+{
+ int i;
+ iCode *ic;
+ bitVect *rsave;
+ link *detype;
+
+ /* look for call */
+ for (ic = lic ; ic ; ic = ic->next)
+ if (ic->op == CALL || ic->op == PCALL)
+ break;
+
+ if (!ic) {
+ fprintf(stderr,"found parameter push with no function call\n");
+ return ;
+ }
+
+ /* if the registers have been saved already then
+ do nothing */
+ if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
+ return ;
+
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
+ ic->rUsed);
+
+ ic->regsSaved = 1;
+ if (options.useXstack) {
+ if (bitVectBitValue(rsave,R0_IDX))
+ emitcode("mov","b,r0");
+ emitcode("mov","r0,%s",spname);
+ for (i = 0 ; i < nRegs ; i++) {
+ if (bitVectBitValue(rsave,i)) {
+ if (i == R0_IDX)
+ emitcode("mov","a,b");
+ else
+ emitcode("mov","a,%s",regWithIdx(i)->name);
+ emitcode("movx","@r0,a");
+ emitcode("inc","r0");
+ }
+ }
+ emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ emitcode("mov","r0,b");
+ } else
+ for (i = 0 ; i < nRegs ; i++) {
+ if (bitVectBitValue(rsave,i))
+ emitcode("push","%s",regWithIdx(i)->dname);
+ }
+
+ detype = getSpec(operandType(IC_LEFT(ic)));
+ if (detype &&
+ (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
+ IS_ISR(currFunc->etype) &&
+ !ic->bankSaved)
+
+ saverbank(SPEC_BANK(detype),ic,TRUE);
+
+}
+/*-----------------------------------------------------------------*/
+/* unsaveRegisters - pop the pushed registers */
+/*-----------------------------------------------------------------*/
+static void unsaveRegisters (iCode *ic)
+{
+ int i;
+ bitVect *rsave;
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
+ ic->rUsed);
+
+ if (options.useXstack) {
+ emitcode("mov","r0,%s",spname);
+ for (i = nRegs ; i >= 0 ; i--) {
+ if (bitVectBitValue(rsave,i)) {
+ emitcode("dec","r0");
+ emitcode("movx","a,@r0");
+ if (i == R0_IDX)
+ emitcode("mov","b,a");
+ else
+ emitcode("mov","%s,a",regWithIdx(i)->name);
+ }
+
+ }
+ emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ emitcode("mov","r0,b");
+ } else
+ for (i = nRegs ; i >= 0 ; i--) {
+ if (bitVectBitValue(rsave,i))
+ emitcode("pop","%s",regWithIdx(i)->dname);
+ }
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pushSide - */
+/*-----------------------------------------------------------------*/
+void pushSide(operand * oper, int size)
+{
+ int offset = 0;
+ while (size--) {
+ char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
+ if (AOP_TYPE(oper) != AOP_REG &&
+ AOP_TYPE(oper) != AOP_DIR &&
+ strcmp(l,"a") ) {
+ emitcode("mov","a,%s",l);
+ emitcode("push","acc");
+ } else
+ emitcode("push","%s",l);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* assignResultValue - */
+/*-----------------------------------------------------------------*/
+void assignResultValue(operand * oper)
+{
+ int offset = 0;
+ int size = AOP_SIZE(oper);
+ while (size--) {
+ aopPut(AOP(oper),fReturn[offset],offset);
+ offset++;
+ }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genXpush - pushes onto the external stack */
+/*-----------------------------------------------------------------*/
+static void genXpush (iCode *ic)
+{
+ asmop *aop = newAsmop(0);
+ regs *r ;
+ int size,offset = 0;
+
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ r = getFreePtr(ic,&aop,FALSE);
+
+
+ emitcode("mov","%s,_spx",r->name);
+
+ size = AOP_SIZE(IC_LEFT(ic));
+ while(size--) {
+
+ char *l = aopGet(AOP(IC_LEFT(ic)),
+ offset++,FALSE,FALSE);
+ MOVA(l);
+ emitcode("movx","@%s,a",r->name);
+ emitcode("inc","%s",r->name);
+
+ }
+
+
+ emitcode("mov","_spx,%s",r->name);
+
+ freeAsmop(NULL,aop,ic,TRUE);
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIpush - genrate code for pushing this gets a little complex */
+/*-----------------------------------------------------------------*/
+static void genIpush (iCode *ic)
+{
+ int size, offset = 0 ;
+ char *l;
+
+
+ /* if this is not a parm push : ie. it is spill push
+ and spill push is always done on the local stack */
+ if (!ic->parmPush) {
+
+ /* and the item is spilt then do nothing */
+ if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
+ return ;
+
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+ /* push it on the stack */
+ while(size--) {
+ l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
+ if (*l == '#') {
+ MOVA(l);
+ l = "acc";
+ }
+ emitcode("push","%s",l);
+ }
+ return ;
+ }
+
+ /* this is a paramter push: in this case we call
+ the routine to find the call and save those
+ registers that need to be saved */
+ saveRegisters(ic);
+
+ /* if use external stack then call the external
+ stack pushing routine */
+ if (options.useXstack) {
+ genXpush(ic);
+ return ;
+ }
+
+ /* then do the push */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+
+
+ // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ while (size--) {
+ l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
+ if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
+ AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
+ strcmp(l,"a") ) {
+ emitcode("mov","a,%s",l);
+ emitcode("push","acc");
+ } else
+ emitcode("push","%s",l);
+ }
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIpop - recover the registers: can happen only for spilling */
+/*-----------------------------------------------------------------*/
+static void genIpop (iCode *ic)
+{
+ int size,offset ;
+
+
+ /* if the temp was not pushed then */
+ if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
+ return ;
+
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+ offset = (size-1);
+ while (size--)
+ emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
+ FALSE,TRUE));
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* unsaverbank - restores the resgister bank from stack */
+/*-----------------------------------------------------------------*/
+static void unsaverbank (int bank,iCode *ic,bool popPsw)
+{
+ int i;
+ asmop *aop ;
+ regs *r = NULL;
+
+ if (popPsw) {
+ if (options.useXstack) {
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+
+
+ emitcode("mov","%s,_spx",r->name);
+ emitcode("movx","a,@%s",r->name);
+ emitcode("mov","psw,a");
+ emitcode("dec","%s",r->name);
+
+ }else
+ emitcode ("pop","psw");
+ }
+
+ for (i = (nRegs - 1) ; i >= 0 ;i--) {
+ if (options.useXstack) {
+ emitcode("movx","a,@%s",r->name);
+ emitcode("mov","(%s+%d),a",
+ regs8051[i].base,8*bank+regs8051[i].offset);
+ emitcode("dec","%s",r->name);
+
+ } else
+ emitcode("pop","(%s+%d)",
+ regs8051[i].base,8*bank+regs8051[i].offset);
+ }
+
+ if (options.useXstack) {
+
+ emitcode("mov","_spx,%s",r->name);
+ freeAsmop(NULL,aop,ic,TRUE);
+
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* saverbank - saves an entire register bank on the stack */
+/*-----------------------------------------------------------------*/
+static void saverbank (int bank, iCode *ic, bool pushPsw)
+{
+ int i;
+ asmop *aop ;
+ regs *r = NULL;
+
+ if (options.useXstack) {
+
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+ emitcode("mov","%s,_spx",r->name);
+
+ }
+
+ for (i = 0 ; i < nRegs ;i++) {
+ if (options.useXstack) {
+ emitcode("inc","%s",r->name);
+ emitcode("mov","a,(%s+%d)",
+ regs8051[i].base,8*bank+regs8051[i].offset);
+ emitcode("movx","@%s,a",r->name);
+ } else
+ emitcode("push","(%s+%d)",
+ regs8051[i].base,8*bank+regs8051[i].offset);
+ }
+
+ if (pushPsw) {
+ if (options.useXstack) {
+ emitcode("mov","a,psw");
+ emitcode("movx","@%s,a",r->name);
+ emitcode("inc","%s",r->name);
+ emitcode("mov","_spx,%s",r->name);
+ freeAsmop (NULL,aop,ic,TRUE);
+
+ } else
+ emitcode("push","psw");
+
+ emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
+ }
+ ic->bankSaved = 1;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genCall - generates a call statement */
+/*-----------------------------------------------------------------*/
+static void genCall (iCode *ic)
+{
+ link *detype;
+
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters(ic);
+
+ /* if we are calling a function that is not using
+ the same register bank then we need to save the
+ destination registers on the stack */
+ detype = getSpec(operandType(IC_LEFT(ic)));
+ if (detype &&
+ (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
+ IS_ISR(currFunc->etype) &&
+ !ic->bankSaved)
+
+ saverbank(SPEC_BANK(detype),ic,TRUE);
+
+ /* if send set is not empty the assign */
+ if (sendSet) {
+ iCode *sic ;
+
+ for (sic = setFirstItem(sendSet) ; sic ;
+ sic = setNextItem(sendSet)) {
+ int size, offset = 0;
+ aopOp(IC_LEFT(sic),sic,FALSE);
+ size = AOP_SIZE(IC_LEFT(sic));
+ while (size--) {
+ char *l = aopGet(AOP(IC_LEFT(sic)),offset,
+ FALSE,FALSE);
+ if (strcmp(l,fReturn[offset]))
+ emitcode("mov","%s,%s",
+ fReturn[offset],
+ l);
+ offset++;
+ }
+ freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+ }
+ sendSet = NULL;
+ }
+ /* make the call */
+ emitcode("lcall","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
+ OP_SYMBOL(IC_LEFT(ic))->rname :
+ OP_SYMBOL(IC_LEFT(ic))->name));
+
+ /* if we need assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+ OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+ IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+ accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ accInUse--;
+
+ assignResultValue(IC_RESULT(ic));
+
+ freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+ }
+
+ /* adjust the stack for parameters if
+ required */
+ if (IC_LEFT(ic)->parmBytes) {
+ int i;
+ if (IC_LEFT(ic)->parmBytes > 3) {
+ emitcode("mov","a,%s",spname);
+ emitcode("add","a,#0x%02x", (- IC_LEFT(ic)->parmBytes) & 0xff);
+ emitcode("mov","%s,a",spname);
+ } else
+ for ( i = 0 ; i < IC_LEFT(ic)->parmBytes ;i++)
+ emitcode("dec","%s",spname);
+
+ }
+
+ /* if register bank was saved then pop them */
+ if (ic->bankSaved)
+ unsaverbank(SPEC_BANK(detype),ic,TRUE);
+
+ /* if we hade saved some registers then unsave them */
+ if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
+ unsaveRegisters (ic);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPcall - generates a call by pointer statement */
+/*-----------------------------------------------------------------*/
+static void genPcall (iCode *ic)
+{
+ link *detype;
+ symbol *rlbl = newiTempLabel(NULL);
+
+
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters(ic);
+
+ /* if we are calling a function that is not using
+ the same register bank then we need to save the
+ destination registers on the stack */
+ detype = getSpec(operandType(IC_LEFT(ic)));
+ if (detype &&
+ IS_ISR(currFunc->etype) &&
+ (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
+ saverbank(SPEC_BANK(detype),ic,TRUE);
+
+
+ /* push the return address on to the stack */
+ emitcode("mov","a,#%05d$",(rlbl->key+100));
+ emitcode("push","acc");
+ emitcode("mov","a,#(%05d$ >> 8)",(rlbl->key+100));
+ emitcode("push","acc");
+
+ /* now push the calling address */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+
+ pushSide(IC_LEFT(ic), 2);
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+
+ /* if send set is not empty the assign */
+ if (sendSet) {
+ iCode *sic ;
+
+ for (sic = setFirstItem(sendSet) ; sic ;
+ sic = setNextItem(sendSet)) {
+ int size, offset = 0;
+ aopOp(IC_LEFT(sic),sic,FALSE);
+ size = AOP_SIZE(IC_LEFT(sic));
+ while (size--) {
+ char *l = aopGet(AOP(IC_LEFT(sic)),offset,
+ FALSE,FALSE);
+ if (strcmp(l,fReturn[offset]))
+ emitcode("mov","%s,%s",
+ fReturn[offset],
+ l);
+ offset++;
+ }
+ freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+ }
+ sendSet = NULL;
+ }
+
+ emitcode("ret","");
+ emitcode("","%05d$:",(rlbl->key+100));
+
+
+ /* if we need assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+ OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
+ IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+ accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ accInUse--;
+
+ assignResultValue(IC_RESULT(ic));
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ }
+
+ /* adjust the stack for parameters if
+ required */
+ if (IC_LEFT(ic)->parmBytes) {
+ int i;
+ if (IC_LEFT(ic)->parmBytes > 3) {
+ emitcode("mov","a,%s",spname);
+ emitcode("add","a,#0x%02x", (- IC_LEFT(ic)->parmBytes) & 0xff);
+ emitcode("mov","%s,a",spname);
+ } else
+ for ( i = 0 ; i < IC_LEFT(ic)->parmBytes ;i++)
+ emitcode("dec","%s",spname);
+
+ }
+
+ /* if register bank was saved then unsave them */
+ if (detype &&
+ (SPEC_BANK(currFunc->etype) !=
+ SPEC_BANK(detype)))
+ unsaverbank(SPEC_BANK(detype),ic,TRUE);
+
+ /* if we hade saved some registers then
+ unsave them */
+ if (ic->regsSaved)
+ unsaveRegisters (ic);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* resultRemat - result is rematerializable */
+/*-----------------------------------------------------------------*/
+static int resultRemat (iCode *ic)
+{
+ if (SKIP_IC(ic) || ic->op == IFX)
+ return 0;
+
+ if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
+ symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+ if (sym->remat && !POINTER_SET(ic))
+ return 1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* inExcludeList - return 1 if the string is in exclude Reg list */
+/*-----------------------------------------------------------------*/
+static bool inExcludeList(char *s)
+{
+ int i =0;
+
+ if (options.excludeRegs[i] &&
+ strcasecmp(options.excludeRegs[i],"none") == 0)
+ return FALSE ;
+
+ for ( i = 0 ; options.excludeRegs[i]; i++) {
+ if (options.excludeRegs[i] &&
+ strcasecmp(s,options.excludeRegs[i]) == 0)
+ return TRUE;
+ }
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* genFunction - generated code for function entry */
+/*-----------------------------------------------------------------*/
+static void genFunction (iCode *ic)
+{
+ symbol *sym;
+ link *fetype;
+
+ nregssaved = 0;
+ /* create the function header */
+ emitcode(";","-----------------------------------------");
+ emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
+ emitcode(";","-----------------------------------------");
+
+ emitcode("","%s:",sym->rname);
+ fetype = getSpec(operandType(IC_LEFT(ic)));
+
+ /* if critical function then turn interrupts off */
+ if (SPEC_CRTCL(fetype))
+ emitcode("clr","ea");
+
+ /* here we need to generate the equates for the
+ register bank if required */
+ if (SPEC_BANK(fetype) != rbank) {
+ int i ;
+
+ rbank = SPEC_BANK(fetype);
+ for ( i = 0 ; i < nRegs ; i++ ) {
+ if (strcmp(regs8051[i].base,"0") == 0)
+ emitcode("","%s = 0x%02x",
+ regs8051[i].dname,
+ 8*rbank+regs8051[i].offset);
+ else
+ emitcode ("","%s = %s + 0x%02x",
+ regs8051[i].dname,
+ regs8051[i].base,
+ 8*rbank+regs8051[i].offset);
+ }
+ }
+
+ /* if this is an interrupt service routine then
+ save acc, b, dpl, dph */
+ if (IS_ISR(sym->etype)) {
+
+ if (!inExcludeList("acc"))
+ emitcode ("push","acc");
+ if (!inExcludeList("b"))
+ emitcode ("push","b");
+ if (!inExcludeList("dpl"))
+ emitcode ("push","dpl");
+ if (!inExcludeList("dph"))
+ emitcode ("push","dph");
+
+ /* if this isr has no bank i.e. is going to
+ run with bank 0 , then we need to save more
+ registers :-) */
+ if (!SPEC_BANK(sym->etype)) {
+
+ /* if this function does not call any other
+ function then we can be economical and
+ save only those registers that are used */
+ if (! sym->hasFcall) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ emitcode("push","%s",regWithIdx(i)->dname);
+ }
+ }
+
+ } else {
+ /* this function has a function call cannot
+ determines register usage so we will have the
+ entire bank */
+ saverbank(0,ic,FALSE);
+ }
+ }
+ } else {
+ /* if callee-save to be used for this function
+ then save the registers being used in this function */
+ if (sym->calleeSave) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
+ emitcode("push","%s",regWithIdx(i)->dname);
+ nregssaved++;
+ }
+ }
+ }
+ }
+ }
+
+ /* set the register bank to the desired value */
+ if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
+ emitcode("push","psw");
+ emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
+ }
+
+ if (IS_RENT(sym->etype) || options.stackAuto) {
+
+ if (options.useXstack) {
+ emitcode("mov","r0,%s",spname);
+ emitcode("mov","a,_bp");
+ emitcode("movx","@r0,a");
+ emitcode("inc","%s",spname);
+ }
+ else
+ /* set up the stack */
+ emitcode ("push","_bp"); /* save the callers stack */
+ emitcode ("mov","_bp,%s",spname);
+ }
+
+ /* adjust the stack for the function */
+ if (sym->stack) {
+
+ int i = sym->stack;
+ if (i > 256 )
+ werror(W_STACK_OVERFLOW,sym->name);
+
+ if (i > 3 && sym->recvSize < 4) {
+
+ emitcode ("mov","a,sp");
+ emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
+ emitcode ("mov","sp,a");
+
+ }
+ else
+ while(i--)
+ emitcode("inc","sp");
+ }
+
+ if (sym->xstack) {
+
+ emitcode ("mov","a,_spx");
+ emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
+ emitcode ("mov","_spx,a");
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndFunction - generates epilogue for functions */
+/*-----------------------------------------------------------------*/
+static void genEndFunction (iCode *ic)
+{
+ symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+
+ if (IS_RENT(sym->etype) || options.stackAuto)
+ emitcode ("mov","%s,_bp",spname);
+
+ /* if use external stack but some variables were
+ added to the local stack then decrement the
+ local stack */
+ if (options.useXstack && sym->stack) {
+ emitcode("mov","a,sp");
+ emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
+ emitcode("mov","sp,a");
+ }
+
+
+ if ((IS_RENT(sym->etype) || options.stackAuto)) {
+ if (options.useXstack) {
+ emitcode("mov","r0,%s",spname);
+ emitcode("movx","a,@r0");
+ emitcode("mov","_bp,a");
+ emitcode("dec","%s",spname);
+ }
+ else
+ emitcode ("pop","_bp");
+ }
+
+ /* restore the register bank */
+ if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
+ emitcode ("pop","psw");
+
+ if (IS_ISR(sym->etype)) {
+
+ /* now we need to restore the registers */
+ /* if this isr has no bank i.e. is going to
+ run with bank 0 , then we need to save more
+ registers :-) */
+ if (!SPEC_BANK(sym->etype)) {
+
+ /* if this function does not call any other
+ function then we can be economical and
+ save only those registers that are used */
+ if (! sym->hasFcall) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ emitcode("pop","%s",regWithIdx(i)->dname);
+ }
+ }
+
+ } else {
+ /* this function has a function call cannot
+ determines register usage so we will have the
+ entire bank */
+ unsaverbank(0,ic,FALSE);
+ }
+ }
+
+ if (!inExcludeList("dph"))
+ emitcode ("pop","dph");
+ if (!inExcludeList("dpl"))
+ emitcode ("pop","dpl");
+ if (!inExcludeList("b"))
+ emitcode ("pop","b");
+ if (!inExcludeList("acc"))
+ emitcode ("pop","acc");
+
+ if (SPEC_CRTCL(sym->etype))
+ emitcode("setb","ea");
+
+ /* if debug then send end of function */
+/* if (options.debug && currFunc) { */
+ if (currFunc) {
+ debugLine = 1;
+ emitcode("","C$%s$%d$%d$%d ==.",
+ ic->filename,currFunc->lastLine,
+ ic->level,ic->block);
+ if (IS_STATIC(currFunc->etype))
+ emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
+ else
+ emitcode("","XG$%s$0$0 ==.",currFunc->name);
+ debugLine = 0;
+ }
+
+ emitcode ("reti","");
+ }
+ else {
+ if (SPEC_CRTCL(sym->etype))
+ emitcode("setb","ea");
+
+ if (sym->calleeSave) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ emitcode("pop","%s",regWithIdx(i)->dname);
+ }
+ }
+
+ }
+
+ /* if debug then send end of function */
+/* if (options.debug && currFunc) { */
+ if (currFunc) {
+ debugLine = 1;
+ emitcode("","C$%s$%d$%d$%d ==.",
+ ic->filename,currFunc->lastLine,
+ ic->level,ic->block);
+ if (IS_STATIC(currFunc->etype))
+ emitcode("","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
+ else
+ emitcode("","XG$%s$0$0 ==.",currFunc->name);
+ debugLine = 0;
+ }
+
+ emitcode ("ret","");
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genRet - generate code for return statement */
+/*-----------------------------------------------------------------*/
+static void genRet (iCode *ic)
+{
+ int size,offset = 0 , pushed = 0;
+
+ /* if we have no return value then
+ just generate the "ret" */
+ if (!IC_LEFT(ic))
+ goto jumpret;
+
+ /* we have something to return then
+ move the return value into place */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ while (size--) {
+ char *l ;
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
+ l = aopGet(AOP(IC_LEFT(ic)),offset++,
+ FALSE,TRUE);
+ emitcode("push","%s",l);
+ pushed++;
+ } else {
+ l = aopGet(AOP(IC_LEFT(ic)),offset,
+ FALSE,FALSE);
+ if (strcmp(fReturn[offset],l))
+ emitcode("mov","%s,%s",fReturn[offset++],l);
+ }
+ }
+
+ if (pushed) {
+ while(pushed) {
+ pushed--;
+ if (strcmp(fReturn[pushed],"a"))
+ emitcode("pop",fReturn[pushed]);
+ else
+ emitcode("pop","acc");
+ }
+ }
+ freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
+
+ jumpret:
+ /* generate a jump to the return label
+ if the next is not the return statement */
+ if (!(ic->next && ic->next->op == LABEL &&
+ IC_LABEL(ic->next) == returnLabel))
+
+ emitcode("ljmp","%05d$",(returnLabel->key+100));
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genLabel - generates a label */
+/*-----------------------------------------------------------------*/
+static void genLabel (iCode *ic)
+{
+ /* special case never generate */
+ if (IC_LABEL(ic) == entryLabel)
+ return ;
+
+ emitcode("","%05d$:",(IC_LABEL(ic)->key+100));
+}
+
+/*-----------------------------------------------------------------*/
+/* genGoto - generates a ljmp */
+/*-----------------------------------------------------------------*/
+static void genGoto (iCode *ic)
+{
+ emitcode ("ljmp","%05d$",(IC_LABEL(ic)->key+100));
+}
+
+/*-----------------------------------------------------------------*/
+/* genPlusIncr :- does addition with increment if possible */
+/*-----------------------------------------------------------------*/
+static bool genPlusIncr (iCode *ic)
+{
+ unsigned int icount ;
+ unsigned int size = getDataSize(IC_RESULT(ic));
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
+ return FALSE ;
+
+ /* if the literal value of the right hand side
+ is greater than 4 then it is not worth it */
+ if ((icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4)
+ return FALSE ;
+
+ /* if increment 16 bits in register */
+ if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
+ (size > 1) &&
+ (icount == 1)) {
+ symbol *tlbl = newiTempLabel(NULL);
+ emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0x00,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)
+ ,tlbl->key+100);
+ else {
+ emitcode("clr","a");
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)
+ ,tlbl->key+100);
+ }
+
+ emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ if(size == 4){
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0x00,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)
+ ,tlbl->key+100);
+ else
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)
+ ,tlbl->key+100);
+
+ emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0x00,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)
+ ,tlbl->key+100);
+ else{
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)
+ ,tlbl->key+100);
+ }
+ emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
+ }
+ emitcode("","%05d$:",tlbl->key+100);
+ return TRUE;
+ }
+
+ /* if the sizes are greater than 1 then we cannot */
+ if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
+ AOP_SIZE(IC_LEFT(ic)) > 1 )
+ return FALSE ;
+
+ /* we can if the aops of the left & result match or
+ if they are in registers and the registers are the
+ same */
+ if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+
+ if (icount > 3) {
+ MOVA(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ emitcode("add","a,#0x%02x",((char) icount) & 0xff);
+ aopPut(AOP(IC_RESULT(ic)),"a",0);
+ } else {
+
+ while (icount--)
+ emitcode ("inc","%s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ }
+
+ return TRUE ;
+ }
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* outBitAcc - output a bit in acc */
+/*-----------------------------------------------------------------*/
+void outBitAcc(operand *result)
+{
+ symbol *tlbl = newiTempLabel(NULL);
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY){
+ aopPut(AOP(result),"a",0);
+ }
+ else {
+ emitcode("jz","%05d$",tlbl->key+100);
+ emitcode("mov","a,%s",one);
+ emitcode("","%05d$:",tlbl->key+100);
+ outAcc(result);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genPlusBits - generates code for addition of two bits */
+/*-----------------------------------------------------------------*/
+static void genPlusBits (iCode *ic)
+{
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
+ symbol *lbl = newiTempLabel(NULL);
+ emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
+ emitcode("jnb","%s,%05d$",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
+ emitcode("cpl","c");
+ emitcode("","%05d$:",(lbl->key+100));
+ outBitC(IC_RESULT(ic));
+ }
+ else{
+ emitcode("clr","a");
+ emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
+ emitcode("rlc","a");
+ emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ emitcode("addc","a,#0x00");
+ outAcc(IC_RESULT(ic));
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genPlus - generates code for addition */
+/*-----------------------------------------------------------------*/
+static void genPlus (iCode *ic)
+{
+ int size, offset = 0;
+
+ /* special cases :- */
+
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RIGHT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ /* if literal, literal on the right or
+ if left requires ACC or right is already
+ in ACC */
+ if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
+ (AOP_NEEDSACC(IC_LEFT(ic))) ||
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_ACC ){
+ operand *t = IC_RIGHT(ic);
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = t;
+ }
+
+ /* if both left & right are in bit
+ space */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
+ genPlusBits (ic);
+ goto release ;
+ }
+
+ /* if left in bit space & right literal */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
+ emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
+ /* if result in bit space */
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
+ if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L)
+ emitcode("cpl","c");
+ outBitC(IC_RESULT(ic));
+ } else {
+ size = getDataSize(IC_RESULT(ic));
+ while (size--) {
+ MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ emitcode("addc","a,#00");
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+ }
+ goto release ;
+ }
+
+ /* if I can do an increment instead
+ of add then GOOD for ME */
+ if (genPlusIncr (ic) == TRUE)
+ goto release;
+
+ size = getDataSize(IC_RESULT(ic));
+
+ while(size--){
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+ if(offset == 0)
+ emitcode("add","a,%s",
+ aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ else
+ emitcode("addc","a,%s",
+ aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ } else {
+ MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ if(offset == 0)
+ emitcode("add","a,%s",
+ aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+ else
+ emitcode("addc","a,%s",
+ aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+ }
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) < 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) < 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,2);
+ }
+release:
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinusDec :- does subtraction with deccrement if possible */
+/*-----------------------------------------------------------------*/
+static bool genMinusDec (iCode *ic)
+{
+ unsigned int icount ;
+ unsigned int size = getDataSize(IC_RESULT(ic));
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
+ return FALSE ;
+
+ /* if the literal value of the right hand side
+ is greater than 4 then it is not worth it */
+ if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4)
+ return FALSE ;
+
+ size = getDataSize(IC_RESULT(ic));
+ /* if decrement 16 bits in register */
+ if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
+ (size > 1) &&
+ (icount == 1)) {
+ symbol *tlbl = newiTempLabel(NULL);
+ emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0xff,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)
+ ,tlbl->key+100);
+ else{
+ emitcode("mov","a,#0xff");
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE)
+ ,tlbl->key+100);
+ }
+ emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ if(size == 4){
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0xff,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)
+ ,tlbl->key+100);
+ else{
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE)
+ ,tlbl->key+100);
+ }
+ emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
+ IS_AOP_PREG(IC_RESULT(ic)))
+ emitcode("cjne","%s,#0xff,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)
+ ,tlbl->key+100);
+ else{
+ emitcode("cjne","a,%s,%05d$"
+ ,aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE)
+ ,tlbl->key+100);
+ }
+ emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
+ }
+ emitcode("","%05d$:",tlbl->key+100);
+ return TRUE;
+ }
+
+ /* if the sizes are greater than 1 then we cannot */
+ if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
+ AOP_SIZE(IC_LEFT(ic)) > 1 )
+ return FALSE ;
+
+ /* we can if the aops of the left & result match or
+ if they are in registers and the registers are the
+ same */
+ if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+
+ while (icount--)
+ emitcode ("dec","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ return TRUE ;
+ }
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* addSign - complete with sign */
+/*-----------------------------------------------------------------*/
+static void addSign(operand *result, int offset, int sign)
+{
+ int size = (getDataSize(result) - offset);
+ if(size > 0){
+ if(sign){
+ emitcode("rlc","a");
+ emitcode("subb","a,acc");
+ while(size--)
+ aopPut(AOP(result),"a",offset++);
+ } else
+ while(size--)
+ aopPut(AOP(result),zero,offset++);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinusBits - generates code for subtraction of two bits */
+/*-----------------------------------------------------------------*/
+static void genMinusBits (iCode *ic)
+{
+ symbol *lbl = newiTempLabel(NULL);
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
+ emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir);
+ emitcode("jnb","%s,%05d$",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100));
+ emitcode("cpl","c");
+ emitcode("","%05d$:",(lbl->key+100));
+ outBitC(IC_RESULT(ic));
+ }
+ else{
+ emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ emitcode("subb","a,acc");
+ emitcode("jnb","%s,%05d$",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100));
+ emitcode("inc","a");
+ emitcode("","%05d$:",(lbl->key+100));
+ aopPut(AOP(IC_RESULT(ic)),"a",0);
+ addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic)))));
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinus - generates code for subtraction */
+/*-----------------------------------------------------------------*/
+static void genMinus (iCode *ic)
+{
+ int size, offset = 0;
+ unsigned long lit = 0L;
+
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RIGHT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ /* special cases :- */
+ /* if both left & right are in bit space */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
+ genMinusBits (ic);
+ goto release ;
+ }
+
+ /* if I can do an decrement instead
+ of subtract then GOOD for ME */
+ if (genMinusDec (ic) == TRUE)
+ goto release;
+
+ size = getDataSize(IC_RESULT(ic));
+
+ if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT){
+ CLRC;
+ }
+ else{
+ lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ lit = - (long)lit;
+ }
+
+ /* if literal, add a,#-lit, else normal subb */
+ while (size--) {
+ MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
+ if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
+ emitcode("subb","a,%s",
+ aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ else{
+ /* first add without previous c */
+ if(!offset)
+ emitcode("add","a,#0x%02x",
+ (unsigned int)(lit & 0x0FFL));
+ else
+ emitcode("addc","a,#0x%02x",
+ (unsigned int)((lit >> (offset*8)) & 0x0FFL));
+ }
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) < 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) < 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,2);
+ }
+release:
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genMultbits :- multiplication of bits */
+/*-----------------------------------------------------------------*/
+static void genMultbits (operand *left,
+ operand *right,
+ operand *result)
+{
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
+ outBitC(result);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genMultOneByte : 8 bit multiplication & division */
+/*-----------------------------------------------------------------*/
+static void genMultOneByte (operand *left,
+ operand *right,
+ operand *result)
+{
+ link *opetype = operandType(result);
+ char *l ;
+ symbol *lbl ;
+ int size,offset;
+
+ /* (if two literals, the value is computed before) */
+ /* if one literal, literal on the right */
+ if (AOP_TYPE(left) == AOP_LIT){
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ size = AOP_SIZE(result);
+ /* signed or unsigned */
+ emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("mul","ab");
+ /* if result size = 1, mul signed = mul unsigned */
+ aopPut(AOP(result),"a",0);
+ if (size > 1){
+ if (SPEC_USIGN(opetype)){
+ aopPut(AOP(result),"b",1);
+ if (size > 2)
+ /* for filling the MSBs */
+ emitcode("clr","a");
+ }
+ else{
+ emitcode("mov","a,b");
+
+ /* adjust the MSB if left or right neg */
+
+ /* if one literal */
+ if (AOP_TYPE(right) == AOP_LIT){
+ /* AND literal negative */
+ if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
+ /* adjust MSB (c==0 after mul) */
+ emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
+ }
+ }
+ else{
+ lbl = newiTempLabel(NULL);
+ emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("cjne","a,#0x80,%05d$", (lbl->key+100));
+ emitcode("","%05d$:",(lbl->key+100));
+ emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ lbl = newiTempLabel(NULL);
+ emitcode("jc","%05d$",(lbl->key+100));
+ emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
+ emitcode("","%05d$:",(lbl->key+100));
+ }
+
+ lbl = newiTempLabel(NULL);
+ emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ emitcode("cjne","a,#0x80,%05d$", (lbl->key+100));
+ emitcode("","%05d$:",(lbl->key+100));
+ emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ lbl = newiTempLabel(NULL);
+ emitcode("jc","%05d$",(lbl->key+100));
+ emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("","%05d$:",(lbl->key+100));
+
+ aopPut(AOP(result),"a",1);
+ if(size > 2){
+ /* get the sign */
+ emitcode("rlc","a");
+ emitcode("subb","a,acc");
+ }
+ }
+ size -= 2;
+ offset = 2;
+ if (size > 0)
+ while (size--)
+ aopPut(AOP(result),"a",offset++);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMult - generates code for multiplication */
+/*-----------------------------------------------------------------*/
+static void genMult (iCode *ic)
+{
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ /* special cases first */
+ /* both are bits */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right)== AOP_CRY) {
+ genMultbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genMultOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(1) ;
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivbits :- division of bits */
+/*-----------------------------------------------------------------*/
+static void genDivbits (operand *left,
+ operand *right,
+ operand *result)
+{
+
+ char *l;
+
+ /* the result must be bit */
+ emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+
+ MOVA(l);
+
+ emitcode("div","ab");
+ emitcode("rrc","a");
+ aopPut(AOP(result),"c",0);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivOneByte : 8 bit division */
+/*-----------------------------------------------------------------*/
+static void genDivOneByte (operand *left,
+ operand *right,
+ operand *result)
+{
+ link *opetype = operandType(result);
+ char *l ;
+ symbol *lbl ;
+ int size,offset;
+
+ size = AOP_SIZE(result) - 1;
+ offset = 1;
+ /* signed or unsigned */
+ if (SPEC_USIGN(opetype)) {
+ /* unsigned is easy */
+ emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("div","ab");
+ aopPut(AOP(result),"a",0);
+ while (size--)
+ aopPut(AOP(result),zero,offset++);
+ return ;
+ }
+
+ /* signed is a little bit more difficult */
+
+ /* save the signs of the operands */
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
+ emitcode("push","acc"); /* save it on the stack */
+
+ /* now sign adjust for both left & right */
+ l = aopGet(AOP(right),0,FALSE,FALSE);
+ MOVA(l);
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ emitcode("cpl","a");
+ emitcode("inc","a");
+ emitcode("","%05d$:",(lbl->key+100));
+ emitcode("mov","b,a");
+
+ /* sign adjust left side */
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ emitcode("cpl","a");
+ emitcode("inc","a");
+ emitcode("","%05d$:",(lbl->key+100));
+
+ /* now the division */
+ emitcode("div","ab");
+ /* we are interested in the lower order
+ only */
+ emitcode("mov","b,a");
+ lbl = newiTempLabel(NULL);
+ emitcode("pop","acc");
+ /* if there was an over flow we don't
+ adjust the sign of the result */
+ emitcode("jb","ov,%05d$",(lbl->key+100));
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ CLRC;
+ emitcode("clr","a");
+ emitcode("subb","a,b");
+ emitcode("mov","b,a");
+ emitcode("","%05d$:",(lbl->key+100));
+
+ /* now we are done */
+ aopPut(AOP(result),"b",0);
+ if(size > 0){
+ emitcode("mov","c,b.7");
+ emitcode("subb","a,acc");
+ }
+ while (size--)
+ aopPut(AOP(result),"a",offset++);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDiv - generates code for division */
+/*-----------------------------------------------------------------*/
+static void genDiv (iCode *ic)
+{
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ /* special cases first */
+ /* both are bits */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right)== AOP_CRY) {
+ genDivbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genDivOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(1);
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genModbits :- modulus of bits */
+/*-----------------------------------------------------------------*/
+static void genModbits (operand *left,
+ operand *right,
+ operand *result)
+{
+
+ char *l;
+
+ /* the result must be bit */
+ emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+
+ MOVA(l);
+
+ emitcode("div","ab");
+ emitcode("mov","a,b");
+ emitcode("rrc","a");
+ aopPut(AOP(result),"c",0);
+}
+
+/*-----------------------------------------------------------------*/
+/* genModOneByte : 8 bit modulus */
+/*-----------------------------------------------------------------*/
+static void genModOneByte (operand *left,
+ operand *right,
+ operand *result)
+{
+ link *opetype = operandType(result);
+ char *l ;
+ symbol *lbl ;
+
+ /* signed or unsigned */
+ if (SPEC_USIGN(opetype)) {
+ /* unsigned is easy */
+ emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("div","ab");
+ aopPut(AOP(result),"b",0);
+ return ;
+ }
+
+ /* signed is a little bit more difficult */
+
+ /* save the signs of the operands */
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+
+ emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("push","acc"); /* save it on the stack */
+
+ /* now sign adjust for both left & right */
+ l = aopGet(AOP(right),0,FALSE,FALSE);
+ MOVA(l);
+
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ emitcode("cpl","a");
+ emitcode("inc","a");
+ emitcode("","%05d$:",(lbl->key+100));
+ emitcode("mov","b,a");
+
+ /* sign adjust left side */
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ emitcode("cpl","a");
+ emitcode("inc","a");
+ emitcode("","%05d$:",(lbl->key+100));
+
+ /* now the multiplication */
+ emitcode("div","ab");
+ /* we are interested in the lower order
+ only */
+ lbl = newiTempLabel(NULL);
+ emitcode("pop","acc");
+ /* if there was an over flow we don't
+ adjust the sign of the result */
+ emitcode("jb","ov,%05d$",(lbl->key+100));
+ emitcode("jnb","acc.7,%05d$",(lbl->key+100));
+ CLRC ;
+ emitcode("clr","a");
+ emitcode("subb","a,b");
+ emitcode("mov","b,a");
+ emitcode("","%05d$:",(lbl->key+100));
+
+ /* now we are done */
+ aopPut(AOP(result),"b",0);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genMod - generates code for division */
+/*-----------------------------------------------------------------*/
+static void genMod (iCode *ic)
+{
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ /* special cases first */
+ /* both are bits */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right)== AOP_CRY) {
+ genModbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genModOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(1);
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIfxJump :- will create a jump depending on the ifx */
+/*-----------------------------------------------------------------*/
+static void genIfxJump (iCode *ic, char *jval)
+{
+ symbol *jlbl ;
+ symbol *tlbl = newiTempLabel(NULL);
+ char *inst;
+
+ /* if true label then we jump if condition
+ supplied is true */
+ if ( IC_TRUE(ic) ) {
+ jlbl = IC_TRUE(ic);
+ inst = ((strcmp(jval,"a") == 0 ? "jz" :
+ (strcmp(jval,"c") == 0 ? "jnc" : "jnb" )));
+ }
+ else {
+ /* false label is present */
+ jlbl = IC_FALSE(ic) ;
+ inst = ((strcmp(jval,"a") == 0 ? "jnz" :
+ (strcmp(jval,"c") == 0 ? "jc" : "jb" )));
+ }
+ if (strcmp(inst,"jb") == 0 || strcmp(inst,"jnb") == 0)
+ emitcode(inst,"%s,%05d$",jval,(tlbl->key+100));
+ else
+ emitcode(inst,"%05d$",tlbl->key+100);
+ emitcode("ljmp","%05d$",jlbl->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+
+ /* mark the icode as generated */
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmp :- greater or less than comparison */
+/*-----------------------------------------------------------------*/
+static void genCmp (operand *left,operand *right,
+ operand *result, iCode *ifx, int sign)
+{
+ int size, offset = 0 ;
+ unsigned long lit = 0L;
+
+ /* if left & right are bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY ) {
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
+ } else {
+ /* subtract right from left if at the
+ end the carry flag is set then we know that
+ left is greater than right */
+ size = max(AOP_SIZE(left),AOP_SIZE(right));
+
+ /* if unsigned char cmp with lit, do cjne left,#right,zz */
+ if((size == 1) && !sign &&
+ (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
+ symbol *lbl = newiTempLabel(NULL);
+ emitcode("cjne","%s,%s,%05d$",
+ aopGet(AOP(left),offset,FALSE,FALSE),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ lbl->key+100);
+ emitcode("","%05d$:",lbl->key+100);
+ } else {
+ if(AOP_TYPE(right) == AOP_LIT){
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ /* optimize if(x < 0) or if(x >= 0) */
+ if(lit == 0L){
+ if(!sign){
+ CLRC;
+ }
+ else{
+ MOVA(aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE));
+ if(!(AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) && ifx){
+ genIfxJump (ifx,"acc.7");
+ return;
+ }
+ else
+ emitcode("rlc","a");
+ }
+ goto release;
+ }
+ }
+ CLRC;
+ while (size--) {
+ MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
+ if (sign && size == 0) {
+ emitcode("xrl","a,#0x80");
+ if (AOP_TYPE(right) == AOP_LIT){
+ unsigned long lit = (unsigned long)
+ floatFromVal(AOP(right)->aopu.aop_lit);
+ emitcode("subb","a,#0x%02x",
+ 0x80 ^ (unsigned int)((lit >> (offset*8)) & 0x0FFL));
+ } else {
+ emitcode("mov","b,%s",aopGet(AOP(right),offset++,FALSE,FALSE));
+ emitcode("xrl","b,#0x80");
+ emitcode("subb","a,b");
+ }
+ } else
+ emitcode("subb","a,%s",aopGet(AOP(right),offset++,FALSE,FALSE));
+ }
+ }
+ }
+
+release:
+ if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+ outBitC(result);
+ } else {
+ /* if the result is used in the next
+ ifx conditional branch then generate
+ code a little differently */
+ if (ifx )
+ genIfxJump (ifx,"c");
+ else
+ outBitC(result);
+ /* leave the result in acc */
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpGt :- greater than comparison */
+/*-----------------------------------------------------------------*/
+static void genCmpGt (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ link *letype , *retype;
+ int sign ;
+
+ left = IC_LEFT(ic);
+ right= IC_RIGHT(ic);
+ result = IC_RESULT(ic);
+
+ letype = getSpec(operandType(left));
+ retype =getSpec(operandType(right));
+ sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ genCmp(right, left, result, ifx, sign);
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpLt - less than comparisons */
+/*-----------------------------------------------------------------*/
+static void genCmpLt (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ link *letype , *retype;
+ int sign ;
+
+ left = IC_LEFT(ic);
+ right= IC_RIGHT(ic);
+ result = IC_RESULT(ic);
+
+ letype = getSpec(operandType(left));
+ retype =getSpec(operandType(right));
+ sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ genCmp(left, right, result, ifx, sign);
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* gencjneshort - compare and jump if not equal */
+/*-----------------------------------------------------------------*/
+static void gencjneshort(operand *left, operand *right, symbol *lbl)
+{
+ int size = max(AOP_SIZE(left),AOP_SIZE(right));
+ int offset = 0;
+ unsigned long lit = 0L;
+
+ /* if the left side is a literal or
+ if the right is in a pointer register and left
+ is not */
+ if ((AOP_TYPE(left) == AOP_LIT) ||
+ (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+
+ /* if the right side is a literal then anything goes */
+ if (AOP_TYPE(right) == AOP_LIT &&
+ AOP_TYPE(left) != AOP_DIR ) {
+ while (size--) {
+ emitcode("cjne","%s,%s,%05d$",
+ aopGet(AOP(left),offset,FALSE,FALSE),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ lbl->key+100);
+ offset++;
+ }
+ }
+
+ /* if the right side is in a register or in direct space or
+ if the left is a pointer register & right is not */
+ else if (AOP_TYPE(right) == AOP_REG ||
+ AOP_TYPE(right) == AOP_DIR ||
+ (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
+ (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
+ while (size--) {
+ MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
+ if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
+ ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
+ emitcode("jnz","%05d$",lbl->key+100);
+ else
+ emitcode("cjne","a,%s,%05d$",
+ aopGet(AOP(right),offset,FALSE,TRUE),
+ lbl->key+100);
+ offset++;
+ }
+ } else {
+ /* right is a pointer reg need both a & b */
+ while(size--) {
+ char *l = aopGet(AOP(left),offset,FALSE,FALSE);
+ if(strcmp(l,"b"))
+ emitcode("mov","b,%s",l);
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("cjne","a,b,%05d$",lbl->key+100);
+ offset++;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* gencjne - compare and jump if not equal */
+/*-----------------------------------------------------------------*/
+static void gencjne(operand *left, operand *right, symbol *lbl)
+{
+ symbol *tlbl = newiTempLabel(NULL);
+
+ gencjneshort(left, right, lbl);
+
+ emitcode("mov","a,%s",one);
+ emitcode("sjmp","%05d$",tlbl->key+100);
+ emitcode("","%05d$:",lbl->key+100);
+ emitcode("clr","a");
+ emitcode("","%05d$:",tlbl->key+100);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpEq - generates code for equal to */
+/*-----------------------------------------------------------------*/
+static void genCmpEq (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ /* if literal, literal on the right or
+ if the right is in a pointer register and left
+ is not */
+ if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
+ (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+ operand *t = IC_RIGHT(ic);
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = t;
+ }
+
+ if(ifx && !AOP_SIZE(result)){
+ symbol *tlbl;
+ /* if they are both bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ if(lit == 0L){
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("cpl","c");
+ } else if(lit == 1L) {
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ emitcode("clr","c");
+ }
+ /* AOP_TYPE(right) == AOP_CRY */
+ } else {
+ symbol *lbl = newiTempLabel(NULL);
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("jb","%s,%05d$",AOP(right)->aopu.aop_dir,(lbl->key+100));
+ emitcode("cpl","c");
+ emitcode("","%05d$:",(lbl->key+100));
+ }
+ /* if true label then we jump if condition
+ supplied is true */
+ tlbl = newiTempLabel(NULL);
+ if ( IC_TRUE(ifx) ) {
+ emitcode("jnc","%05d$",tlbl->key+100);
+ emitcode("ljmp","%05d$",IC_TRUE(ifx)->key+100);
+ } else {
+ emitcode("jc","%05d$",tlbl->key+100);
+ emitcode("ljmp","%05d$",IC_FALSE(ifx)->key+100);
+ }
+ emitcode("","%05d$:",tlbl->key+100);
+ } else {
+ tlbl = newiTempLabel(NULL);
+ gencjneshort(left, right, tlbl);
+ if ( IC_TRUE(ifx) ) {
+ emitcode("ljmp","%05d$",IC_TRUE(ifx)->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ } else {
+ symbol *lbl = newiTempLabel(NULL);
+ emitcode("sjmp","%05d$",lbl->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ emitcode("ljmp","%05d$",IC_FALSE(ifx)->key+100);
+ emitcode("","%05d$:",lbl->key+100);
+ }
+ }
+ /* mark the icode as generated */
+ ifx->generated = 1;
+ goto release ;
+ }
+
+ /* if they are both bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ if(lit == 0L){
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("cpl","c");
+ } else if(lit == 1L) {
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ emitcode("clr","c");
+ }
+ /* AOP_TYPE(right) == AOP_CRY */
+ } else {
+ symbol *lbl = newiTempLabel(NULL);
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("jb","%s,%05d$",AOP(right)->aopu.aop_dir,(lbl->key+100));
+ emitcode("cpl","c");
+ emitcode("","%05d$:",(lbl->key+100));
+ }
+ /* c = 1 if egal */
+ if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
+ outBitC(result);
+ goto release ;
+ }
+ if (ifx) {
+ genIfxJump (ifx,"c");
+ goto release ;
+ }
+ /* if the result is used in an arithmetic operation
+ then put the result in place */
+ outBitC(result);
+ } else {
+ gencjne(left,right,newiTempLabel(NULL));
+ if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+ if (ifx) {
+ genIfxJump (ifx,"a");
+ goto release ;
+ }
+ /* if the result is used in an arithmetic operation
+ then put the result in place */
+ if (AOP_TYPE(result) != AOP_CRY)
+ outAcc(result);
+ /* leave the result in acc */
+ }
+
+release:
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* ifxForOp - returns the icode containing the ifx for operand */
+/*-----------------------------------------------------------------*/
+static iCode *ifxForOp ( operand *op, iCode *ic )
+{
+ /* if true symbol then needs to be assigned */
+ if (IS_TRUE_SYMOP(op))
+ return NULL ;
+
+ /* if this has register type condition and
+ the next instruction is ifx with the same operand
+ and live to of the operand is upto the ifx only then */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key &&
+ OP_SYMBOL(op)->liveTo <= ic->next->seq )
+ return ic->next;
+
+ return NULL;
+}
+/*-----------------------------------------------------------------*/
+/* genAndOp - for && operation */
+/*-----------------------------------------------------------------*/
+static void genAndOp (iCode *ic)
+{
+ operand *left,*right, *result;
+ symbol *tlbl;
+
+ /* note here that && operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,FALSE);
+
+ /* if both are bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY ) {
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
+ outBitC(result);
+ } else {
+ tlbl = newiTempLabel(NULL);
+ toBoolean(left);
+ emitcode("jz","%05d$",tlbl->key+100);
+ toBoolean(right);
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitAcc(result);
+ }
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genOrOp - for || operation */
+/*-----------------------------------------------------------------*/
+static void genOrOp (iCode *ic)
+{
+ operand *left,*right, *result;
+ symbol *tlbl;
+
+ /* note here that || operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,FALSE);
+
+ /* if both are bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY ) {
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("orl","c,%s",AOP(right)->aopu.aop_dir);
+ outBitC(result);
+ } else {
+ tlbl = newiTempLabel(NULL);
+ toBoolean(left);
+ emitcode("jnz","%05d$",tlbl->key+100);
+ toBoolean(right);
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitAcc(result);
+ }
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* isLiteralBit - test if lit == 2^n */
+/*-----------------------------------------------------------------*/
+int isLiteralBit(unsigned long lit)
+{
+ unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
+ 0x100L,0x200L,0x400L,0x800L,
+ 0x1000L,0x2000L,0x4000L,0x8000L,
+ 0x10000L,0x20000L,0x40000L,0x80000L,
+ 0x100000L,0x200000L,0x400000L,0x800000L,
+ 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
+ 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
+ int idx;
+
+ for(idx = 0; idx < 32; idx++)
+ if(lit == pw[idx])
+ return idx+1;
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* continueIfTrue - */
+/*-----------------------------------------------------------------*/
+static void continueIfTrue (iCode *ic)
+{
+ if(IC_TRUE(ic))
+ emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100);
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* jmpIfTrue - */
+/*-----------------------------------------------------------------*/
+static void jumpIfTrue (iCode *ic)
+{
+ if(!IC_TRUE(ic))
+ emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100);
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* jmpTrueOrFalse - */
+/*-----------------------------------------------------------------*/
+static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
+{
+ // ugly but optimized by peephole
+ if(IC_TRUE(ic)){
+ symbol *nlbl = newiTempLabel(NULL);
+ emitcode("sjmp","%05d$",nlbl->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100);
+ emitcode("","%05d$:",nlbl->key+100);
+ }
+ else{
+ emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ }
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genAnd - code for and */
+/*-----------------------------------------------------------------*/
+static void genAnd (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+ int bytelit = 0;
+ char buffer[10];
+
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+#ifdef DEBUG_TYPE
+ emitcode("","; Type res[%d] = l[%d]&r[%d]",
+ AOP_TYPE(result),
+ AOP_TYPE(left), AOP_TYPE(right));
+ emitcode("","; Size res[%d] = l[%d]&r[%d]",
+ AOP_SIZE(result),
+ AOP_SIZE(left), AOP_SIZE(right));
+#endif
+
+ /* if left is a literal & right is not then exchange them */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ AOP_NEEDSACC(left)) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ // if(bit & yy)
+ // result = bit & yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ // c = bit & literal;
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(lit & 1) {
+ if(size && sameRegs(AOP(result),AOP(left)))
+ // no change
+ goto release;
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ // bit(result) = 0;
+ if(size && (AOP_TYPE(result) == AOP_CRY)){
+ emitcode("clr","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ }
+ if((AOP_TYPE(result) == AOP_CRY) && ifx){
+ jumpIfTrue(ifx);
+ goto release;
+ }
+ emitcode("clr","c");
+ }
+ } else {
+ if (AOP_TYPE(right) == AOP_CRY){
+ // c = bit & bit;
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ // c = bit & val;
+ MOVA(aopGet(AOP(right),0,FALSE,FALSE));
+ // c = lsb
+ emitcode("rrc","a");
+ emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ }
+ }
+ // bit = c
+ // val = c
+ if(size)
+ outBitC(result);
+ // if(bit & ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ // if(val & 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val & 0xZZ - size = 1, ifx = FALSE -
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (AOP_TYPE(result) == AOP_CRY) &&
+ (AOP_TYPE(left) != AOP_CRY)){
+ int posbit = isLiteralBit(lit);
+ /* left & 2^n */
+ if(posbit){
+ posbit--;
+ MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
+ // bit = left & 2^n
+ if(size)
+ emitcode("mov","c,acc.%d",posbit&0x07);
+ // if(left & 2^n)
+ else{
+ if(ifx){
+ sprintf(buffer,"acc.%d",posbit&0x07);
+ genIfxJump(ifx, buffer);
+ }
+ goto release;
+ }
+ } else {
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizel = AOP_SIZE(left);
+ if(size)
+ emitcode("setb","c");
+ while(sizel--){
+ if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+ MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
+ // byte == 2^n ?
+ if((posbit = isLiteralBit(bytelit)) != 0)
+ emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100);
+ else{
+ if(bytelit != 0x0FFL)
+ emitcode("anl","a,%s",
+ aopGet(AOP(right),offset,FALSE,TRUE));
+ emitcode("jnz","%05d$",tlbl->key+100);
+ }
+ }
+ offset++;
+ }
+ // bit = left & literal
+ if(size){
+ emitcode("clr","c");
+ emitcode("","%05d$:",tlbl->key+100);
+ }
+ // if(left & literal)
+ else{
+ if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ goto release ;
+ }
+ }
+ outBitC(result);
+ goto release ;
+ }
+
+ /* if left is same as result */
+ if(sameRegs(AOP(result),AOP(left))){
+ for(;size--; offset++) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF)
+ continue;
+ else
+ if (bytelit == 0)
+ aopPut(AOP(result),zero,offset);
+ else
+ if (IS_AOP_PREG(result)) {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ emitcode("anl","%s,%s",
+ aopGet(AOP(left),offset,FALSE,TRUE),
+ aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ if (IS_AOP_PREG(result)) {
+ emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+
+ } else
+ emitcode("anl","%s,a",
+ aopGet(AOP(left),offset,FALSE,TRUE));
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left & right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
+ if(size)
+ emitcode("setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("anl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ emitcode("jnz","%05d$",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else {
+ for(;(size--);offset++) {
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF){
+ aopPut(AOP(result),
+ aopGet(AOP(left),offset,FALSE,FALSE),
+ offset);
+ continue;
+ } else if(bytelit == 0){
+ aopPut(AOP(result),zero,offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("anl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ aopPut(AOP(result),"a",offset);
+ }
+ }
+ }
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genOr - code for or */
+/*-----------------------------------------------------------------*/
+static void genOr (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+#ifdef DEBUG_TYPE
+ emitcode("","; Type res[%d] = l[%d]&r[%d]",
+ AOP_TYPE(result),
+ AOP_TYPE(left), AOP_TYPE(right));
+ emitcode("","; Size res[%d] = l[%d]&r[%d]",
+ AOP_SIZE(result),
+ AOP_SIZE(left), AOP_SIZE(right));
+#endif
+
+ /* if left is a literal & right is not then exchange them */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ AOP_NEEDSACC(left)) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ // if(bit | yy)
+ // xx = bit | yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ if(AOP_TYPE(right) == AOP_LIT){
+ // c = bit & literal;
+ if(lit){
+ // lit != 0 => result = 1
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(size)
+ emitcode("setb","%s",AOP(result)->aopu.aop_dir);
+ else if(ifx)
+ continueIfTrue(ifx);
+ goto release;
+ }
+ emitcode("setb","c");
+ } else {
+ // lit == 0 => result = left
+ if(size && sameRegs(AOP(result),AOP(left)))
+ goto release;
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ }
+ } else {
+ if (AOP_TYPE(right) == AOP_CRY){
+ // c = bit | bit;
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ emitcode("orl","c,%s",AOP(left)->aopu.aop_dir);
+ }
+ else{
+ // c = bit | val;
+ symbol *tlbl = newiTempLabel(NULL);
+ if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
+ emitcode("setb","c");
+ emitcode("jb","%s,%05d$",
+ AOP(left)->aopu.aop_dir,tlbl->key+100);
+ toBoolean(right);
+ emitcode("jnz","%05d$",tlbl->key+100);
+ if((AOP_TYPE(result) == AOP_CRY) && ifx){
+ jmpTrueOrFalse(ifx, tlbl);
+ goto release;
+ } else {
+ CLRC;
+ emitcode("","%05d$:",tlbl->key+100);
+ }
+ }
+ }
+ // bit = c
+ // val = c
+ if(size)
+ outBitC(result);
+ // if(bit | ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ // if(val | 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val | 0xZZ - size = 1, ifx = FALSE -
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (AOP_TYPE(result) == AOP_CRY) &&
+ (AOP_TYPE(left) != AOP_CRY)){
+ if(lit){
+ // result = 1
+ if(size)
+ emitcode("setb","%s",AOP(result)->aopu.aop_dir);
+ else
+ continueIfTrue(ifx);
+ goto release;
+ } else {
+ // lit = 0, result = boolean(left)
+ if(size)
+ emitcode("setb","c");
+ toBoolean(right);
+ if(size){
+ symbol *tlbl = newiTempLabel(NULL);
+ emitcode("jnz","%05d$",tlbl->key+100);
+ CLRC;
+ emitcode("","%05d$:",tlbl->key+100);
+ } else {
+ genIfxJump (ifx,"a");
+ goto release;
+ }
+ }
+ outBitC(result);
+ goto release ;
+ }
+
+ /* if left is same as result */
+ if(sameRegs(AOP(result),AOP(left))){
+ for(;size--; offset++) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+ continue;
+ else
+ if (IS_AOP_PREG(left)) {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ emitcode("orl","%s,%s",
+ aopGet(AOP(left),offset,FALSE,TRUE),
+ aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ if (IS_AOP_PREG(left)) {
+ emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ emitcode("orl","%s,a",
+ aopGet(AOP(left),offset,FALSE,TRUE));
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left | right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+ if(size)
+ emitcode("setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("orl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ emitcode("jnz","%05d$",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else for(;(size--);offset++){
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
+ aopPut(AOP(result),
+ aopGet(AOP(left),offset,FALSE,FALSE),
+ offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("orl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ aopPut(AOP(result),"a",offset);
+ }
+ }
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genXor - code for xclusive or */
+/*-----------------------------------------------------------------*/
+static void genXor (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+#ifdef DEBUG_TYPE
+ emitcode("","; Type res[%d] = l[%d]&r[%d]",
+ AOP_TYPE(result),
+ AOP_TYPE(left), AOP_TYPE(right));
+ emitcode("","; Size res[%d] = l[%d]&r[%d]",
+ AOP_SIZE(result),
+ AOP_SIZE(left), AOP_SIZE(right));
+#endif
+
+ /* if left is a literal & right is not ||
+ if left needs acc & right does not */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ // if(bit ^ yy)
+ // xx = bit ^ yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ if(AOP_TYPE(right) == AOP_LIT){
+ // c = bit & literal;
+ if(lit>>1){
+ // lit>>1 != 0 => result = 1
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(size)
+ emitcode("setb","%s",AOP(result)->aopu.aop_dir);
+ else if(ifx)
+ continueIfTrue(ifx);
+ goto release;
+ }
+ emitcode("setb","c");
+ } else{
+ // lit == (0 or 1)
+ if(lit == 0){
+ // lit == 0, result = left
+ if(size && sameRegs(AOP(result),AOP(left)))
+ goto release;
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else{
+ // lit == 1, result = not(left)
+ if(size && sameRegs(AOP(result),AOP(left))){
+ emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ } else {
+ emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ emitcode("cpl","c");
+ }
+ }
+ }
+
+ } else {
+ // right != literal
+ symbol *tlbl = newiTempLabel(NULL);
+ if (AOP_TYPE(right) == AOP_CRY){
+ // c = bit ^ bit;
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ }
+ else{
+ int sizer = AOP_SIZE(right);
+ // c = bit ^ val
+ // if val>>1 != 0, result = 1
+ emitcode("setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
+ if(sizer == 1)
+ // test the msb of the lsb
+ emitcode("anl","a,#0xfe");
+ emitcode("jnz","%05d$",tlbl->key+100);
+ }
+ // val = (0,1)
+ emitcode("rrc","a");
+ }
+ emitcode("jnb","%s,%05d$",AOP(left)->aopu.aop_dir,(tlbl->key+100));
+ emitcode("cpl","c");
+ emitcode("","%05d$:",(tlbl->key+100));
+ }
+ // bit = c
+ // val = c
+ if(size)
+ outBitC(result);
+ // if(bit | ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ if(sameRegs(AOP(result),AOP(left))){
+ /* if left is same as result */
+ for(;size--; offset++) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+ continue;
+ else
+ if (IS_AOP_PREG(left)) {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ emitcode("xrl","%s,%s",
+ aopGet(AOP(left),offset,FALSE,TRUE),
+ aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ if (IS_AOP_PREG(left)) {
+ emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ emitcode("xrl","%s,a",
+ aopGet(AOP(left),offset,FALSE,TRUE));
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left ^ right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+ if(size)
+ emitcode("setb","c");
+ while(sizer--){
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
+ MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
+ } else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("xrl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ emitcode("jnz","%05d$",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ emitcode("","%05d$:",tlbl->key+100);
+ outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else for(;(size--);offset++){
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
+ aopPut(AOP(result),
+ aopGet(AOP(left),offset,FALSE,FALSE),
+ offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC)
+ emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ emitcode("xrl","a,%s",
+ aopGet(AOP(left),offset,FALSE,TRUE));
+ }
+ aopPut(AOP(result),"a",offset);
+ }
+ }
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genInline - write the inline code out */
+/*-----------------------------------------------------------------*/
+static void genInline (iCode *ic)
+{
+ char buffer[MAX_INLINEASM];
+ char *bp = buffer;
+ char *bp1= buffer;
+
+ inLine += (!options.asmpeep);
+ strcpy(buffer,IC_INLINE(ic));
+
+ /* emit each line as a code */
+ while (*bp) {
+ if (*bp == '\n') {
+ *bp++ = '\0';
+ emitcode(bp1,"");
+ bp1 = bp;
+ } else {
+ if (*bp == ':') {
+ bp++;
+ *bp = '\0';
+ bp++;
+ emitcode(bp1,"");
+ bp1 = bp;
+ } else
+ bp++;
+ }
+ }
+ if (bp1 != bp)
+ emitcode(bp1,"");
+ /* emitcode("",buffer); */
+ inLine -= (!options.asmpeep);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRRC - rotate right with carry */
+/*-----------------------------------------------------------------*/
+static void genRRC (iCode *ic)
+{
+ operand *left , *result ;
+ int size, offset = 0;
+ char *l;
+
+ /* rotate right with carry */
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ /* move it to the result */
+ size = AOP_SIZE(result);
+ offset = size - 1 ;
+ CLRC;
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("rrc","a");
+ if (AOP_SIZE(result) > 1)
+ aopPut(AOP(result),"a",offset--);
+ }
+ /* now we need to put the carry into the
+ highest order byte of the result */
+ if (AOP_SIZE(result) > 1) {
+ l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
+ MOVA(l);
+ }
+ emitcode("mov","acc.7,c");
+ aopPut(AOP(result),"a",AOP_SIZE(result)-1);
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRLC - generate code for rotate left with carry */
+/*-----------------------------------------------------------------*/
+static void genRLC (iCode *ic)
+{
+ operand *left , *result ;
+ int size, offset = 0;
+ char *l;
+
+ /* rotate right with carry */
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ /* move it to the result */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ if (size--) {
+ l = aopGet(AOP(left),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("add","a,acc");
+ if (AOP_SIZE(result) > 1)
+ aopPut(AOP(result),"a",offset++);
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("rlc","a");
+ if (AOP_SIZE(result) > 1)
+ aopPut(AOP(result),"a",offset++);
+ }
+ }
+ /* now we need to put the carry into the
+ highest order byte of the result */
+ if (AOP_SIZE(result) > 1) {
+ l = aopGet(AOP(result),0,FALSE,FALSE);
+ MOVA(l);
+ }
+ emitcode("mov","acc.0,c");
+ aopPut(AOP(result),"a",0);
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGetHbit - generates code get highest order bit */
+/*-----------------------------------------------------------------*/
+static void genGetHbit (iCode *ic)
+{
+ operand *left, *result;
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ /* get the highest order byte into a */
+ MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
+ if(AOP_TYPE(result) == AOP_CRY){
+ emitcode("rlc","a");
+ outBitC(result);
+ }
+ else{
+ emitcode("rl","a");
+ emitcode("anl","a,#0x01");
+ outAcc(result);
+ }
+
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* AccRol - rotate left accumulator by known count */
+/*-----------------------------------------------------------------*/
+static void AccRol (int shCount)
+{
+ shCount &= 0x0007; // shCount : 0..7
+ switch(shCount){
+ case 0 :
+ break;
+ case 1 :
+ emitcode("rl","a");
+ break;
+ case 2 :
+ emitcode("rl","a");
+ emitcode("rl","a");
+ break;
+ case 3 :
+ emitcode("swap","a");
+ emitcode("rr","a");
+ break;
+ case 4 :
+ emitcode("swap","a");
+ break;
+ case 5 :
+ emitcode("swap","a");
+ emitcode("rl","a");
+ break;
+ case 6 :
+ emitcode("rr","a");
+ emitcode("rr","a");
+ break;
+ case 7 :
+ emitcode("rr","a");
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccLsh - left shift accumulator by known count */
+/*-----------------------------------------------------------------*/
+static void AccLsh (int shCount)
+{
+ if(shCount != 0){
+ if(shCount == 1)
+ emitcode("add","a,acc");
+ else
+ if(shCount == 2) {
+ emitcode("add","a,acc");
+ emitcode("add","a,acc");
+ } else {
+ /* rotate left accumulator */
+ AccRol(shCount);
+ /* and kill the lower order bits */
+ emitcode("anl","a,#0x%02x", SLMask[shCount]);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccRsh - right shift accumulator by known count */
+/*-----------------------------------------------------------------*/
+static void AccRsh (int shCount)
+{
+ if(shCount != 0){
+ if(shCount == 1){
+ CLRC;
+ emitcode("rrc","a");
+ } else {
+ /* rotate right accumulator */
+ AccRol(8 - shCount);
+ /* and kill the higher order bits */
+ emitcode("anl","a,#0x%02x", SRMask[shCount]);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccSRsh - signed right shift accumulator by known count */
+/*-----------------------------------------------------------------*/
+static void AccSRsh (int shCount)
+{
+ symbol *tlbl ;
+ if(shCount != 0){
+ if(shCount == 1){
+ emitcode("mov","c,acc.7");
+ emitcode("rrc","a");
+ } else if(shCount == 2){
+ emitcode("mov","c,acc.7");
+ emitcode("rrc","a");
+ emitcode("mov","c,acc.7");
+ emitcode("rrc","a");
+ } else {
+ tlbl = newiTempLabel(NULL);
+ /* rotate right accumulator */
+ AccRol(8 - shCount);
+ /* and kill the higher order bits */
+ emitcode("anl","a,#0x%02x", SRMask[shCount]);
+ emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100);
+ emitcode("orl","a,#0x%02x",
+ (unsigned char)~SRMask[shCount]);
+ emitcode("","%05d$:",tlbl->key+100);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftR1Left2Result - shift right one byte from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftR1Left2Result (operand *left, int offl,
+ operand *result, int offr,
+ int shCount, int sign)
+{
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ /* shift right accumulator */
+ if(sign)
+ AccSRsh(shCount);
+ else
+ AccRsh(shCount);
+ aopPut(AOP(result),"a",offr);
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftL1Left2Result - shift left one byte from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftL1Left2Result (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ char *l;
+ l = aopGet(AOP(left),offl,FALSE,FALSE);
+ MOVA(l);
+ /* shift left accumulator */
+ AccLsh(shCount);
+ aopPut(AOP(result),"a",offr);
+}
+
+/*-----------------------------------------------------------------*/
+/* movLeft2Result - move byte from left to result */
+/*-----------------------------------------------------------------*/
+static void movLeft2Result (operand *left, int offl,
+ operand *result, int offr, int sign)
+{
+ char *l;
+ if(!sameRegs(AOP(left),AOP(result)) || (offl != offr)){
+ l = aopGet(AOP(left),offl,FALSE,FALSE);
+
+ if (*l == '@' && (IS_AOP_PREG(result))) {
+ emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offr);
+ } else {
+ if(!sign)
+ aopPut(AOP(result),l,offr);
+ else{
+ /* MSB sign in acc.7 ! */
+ if(getDataSize(left) == offl+1){
+ emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offr);
+ }
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXRrl1 - right rotate c->a:x->c by 1 */
+/*-----------------------------------------------------------------*/
+static void AccAXRrl1 (char *x)
+{
+ emitcode("rrc","a");
+ emitcode("xch","a,%s", x);
+ emitcode("rrc","a");
+ emitcode("xch","a,%s", x);
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
+/*-----------------------------------------------------------------*/
+static void AccAXLrl1 (char *x)
+{
+ emitcode("xch","a,%s",x);
+ emitcode("rlc","a");
+ emitcode("xch","a,%s",x);
+ emitcode("rlc","a");
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXLsh1 - left shift a:x<-0 by 1 */
+/*-----------------------------------------------------------------*/
+static void AccAXLsh1 (char *x)
+{
+ emitcode("xch","a,%s",x);
+ emitcode("add","a,acc");
+ emitcode("xch","a,%s",x);
+ emitcode("rlc","a");
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXLsh - left shift a:x by known count (0..7) */
+/*-----------------------------------------------------------------*/
+static void AccAXLsh (char *x, int shCount)
+{
+ switch(shCount){
+ case 0 :
+ break;
+ case 1 :
+ AccAXLsh1(x);
+ break;
+ case 2 :
+ AccAXLsh1(x);
+ AccAXLsh1(x);
+ break;
+ case 3 :
+ case 4 :
+ case 5 : // AAAAABBB:CCCCCDDD
+ AccRol(shCount); // BBBAAAAA:CCCCCDDD
+ emitcode("anl","a,#0x%02x",
+ SLMask[shCount]); // BBB00000:CCCCCDDD
+ emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
+ AccRol(shCount); // DDDCCCCC:BBB00000
+ emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
+ emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
+ emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
+ emitcode("anl","a,#0x%02x",
+ SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
+ emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
+ emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
+ break;
+ case 6 : // AAAAAABB:CCCCCCDD
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000000BB:CCCCCCDD
+ emitcode("mov","c,acc.0"); // c = B
+ emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
+ AccAXRrl1(x); // BCCCCCCD:D000000B
+ AccAXRrl1(x); // BBCCCCCC:DD000000
+ break;
+ case 7 : // a:x <<= 7
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 0000000B:CCCCCCCD
+ emitcode("mov","c,acc.0"); // c = B
+ emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
+ AccAXRrl1(x); // BCCCCCCC:D0000000
+ break;
+ default :
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXRsh - right shift a:x known count (0..7) */
+/*-----------------------------------------------------------------*/
+static void AccAXRsh (char *x, int shCount)
+{
+ switch(shCount){
+ case 0 :
+ break;
+ case 1 :
+ CLRC;
+ AccAXRrl1(x); // 0->a:x
+ break;
+ case 2 :
+ CLRC;
+ AccAXRrl1(x); // 0->a:x
+ CLRC;
+ AccAXRrl1(x); // 0->a:x
+ break;
+ case 3 :
+ case 4 :
+ case 5 : // AAAAABBB:CCCCCDDD = a:x
+ AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
+ emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
+ AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000CCCCC:BBBAAAAA
+ emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
+ emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
+ emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
+ emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
+ emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
+ break;
+ case 6 : // AABBBBBB:CCDDDDDD
+ emitcode("mov","c,acc.7");
+ AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
+ AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
+ emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000000AA:BBBBBBCC
+ break;
+ case 7 : // ABBBBBBB:CDDDDDDD
+ emitcode("mov","c,acc.7"); // c = A
+ AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
+ emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 0000000A:BBBBBBBC
+ break;
+ default :
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccAXRshS - right shift signed a:x known count (0..7) */
+/*-----------------------------------------------------------------*/
+static void AccAXRshS (char *x, int shCount)
+{
+ symbol *tlbl ;
+ switch(shCount){
+ case 0 :
+ break;
+ case 1 :
+ emitcode("mov","c,acc.7");
+ AccAXRrl1(x); // s->a:x
+ break;
+ case 2 :
+ emitcode("mov","c,acc.7");
+ AccAXRrl1(x); // s->a:x
+ emitcode("mov","c,acc.7");
+ AccAXRrl1(x); // s->a:x
+ break;
+ case 3 :
+ case 4 :
+ case 5 : // AAAAABBB:CCCCCDDD = a:x
+ tlbl = newiTempLabel(NULL);
+ AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
+ emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
+ AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000CCCCC:BBBAAAAA
+ emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
+ emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
+ emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
+ emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
+ emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
+ emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100);
+ emitcode("orl","a,#0x%02x",
+ (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
+ emitcode("","%05d$:",tlbl->key+100);
+ break; // SSSSAAAA:BBBCCCCC
+ case 6 : // AABBBBBB:CCDDDDDD
+ tlbl = newiTempLabel(NULL);
+ emitcode("mov","c,acc.7");
+ AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
+ AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
+ emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 000000AA:BBBBBBCC
+ emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100);
+ emitcode("orl","a,#0x%02x",
+ (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
+ emitcode("","%05d$:",tlbl->key+100);
+ break;
+ case 7 : // ABBBBBBB:CDDDDDDD
+ tlbl = newiTempLabel(NULL);
+ emitcode("mov","c,acc.7"); // c = A
+ AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
+ emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
+ emitcode("anl","a,#0x%02x",
+ SRMask[shCount]); // 0000000A:BBBBBBBC
+ emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100);
+ emitcode("orl","a,#0x%02x",
+ (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
+ emitcode("","%05d$:",tlbl->key+100);
+ break;
+ default :
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftL2Left2Result - shift left two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftL2Left2Result (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ if(sameRegs(AOP(result), AOP(left)) &&
+ ((offl + MSB16) == offr)){
+ /* don't crash result[offr] */
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ } else {
+ movLeft2Result(left,offl, result, offr, 0);
+ MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ /* ax << shCount (x = lsb(result))*/
+ AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ aopPut(AOP(result),"a",offr+MSB16);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* shiftR2Left2Result - shift right two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftR2Left2Result (operand *left, int offl,
+ operand *result, int offr,
+ int shCount, int sign)
+{
+ if(sameRegs(AOP(result), AOP(left)) &&
+ ((offl + MSB16) == offr)){
+ /* don't crash result[offr] */
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ } else {
+ movLeft2Result(left,offl, result, offr, 0);
+ MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ /* a:x >> shCount (x = lsb(result))*/
+ if(sign)
+ AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ else
+ AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ if(getDataSize(result) > 1)
+ aopPut(AOP(result),"a",offr+MSB16);
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftLLeftOrResult - shift left one byte from left, or to result*/
+/*-----------------------------------------------------------------*/
+static void shiftLLeftOrResult (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ /* shift left accumulator */
+ AccLsh(shCount);
+ /* or with result */
+ emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
+ /* back to result */
+ aopPut(AOP(result),"a",offr);
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRLeftOrResult - shift right one byte from left,or to result*/
+/*-----------------------------------------------------------------*/
+static void shiftRLeftOrResult (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ /* shift right accumulator */
+ AccRsh(shCount);
+ /* or with result */
+ emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
+ /* back to result */
+ aopPut(AOP(result),"a",offr);
+}
+
+/*-----------------------------------------------------------------*/
+/* genlshOne - left shift a one byte quantity by known count */
+/*-----------------------------------------------------------------*/
+static void genlshOne (operand *result, operand *left, int shCount)
+{
+ shiftL1Left2Result(left, LSB, result, LSB, shCount);
+}
+
+/*-----------------------------------------------------------------*/
+/* genlshTwo - left shift two bytes by known amount != 0 */
+/*-----------------------------------------------------------------*/
+static void genlshTwo (operand *result,operand *left, int shCount)
+{
+ int size = AOP_SIZE(result);
+
+ if (size == 3)
+ size--;
+
+ /* if shCount >= 8 */
+ if (shCount >= 8) {
+ shCount -= 8 ;
+
+ if (size > 1){
+ if (shCount)
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB16, 0);
+ }
+ aopPut(AOP(result),zero,LSB);
+ }
+
+ /* 1 <= shCount <= 7 */
+ else {
+ if(size == 1)
+ shiftL1Left2Result(left, LSB, result, LSB, shCount);
+ else
+ shiftL2Left2Result(left, LSB, result, LSB, shCount);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftLLong - shift left one long from left to result */
+/* offl = LSB or MSB16 */
+/*-----------------------------------------------------------------*/
+static void shiftLLong (operand *left, operand *result, int offr )
+{
+ char *l;
+ int size = AOP_SIZE(result);
+
+ if(size >= LSB+offr){
+ l = aopGet(AOP(left),LSB,FALSE,FALSE);
+ MOVA(l);
+ emitcode("add","a,acc");
+ if (sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB16+offr && offr != LSB )
+ emitcode("xch","a,%s",
+ aopGet(AOP(left),LSB+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",LSB+offr);
+ }
+
+ if(size >= MSB16+offr){
+ if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
+ l = aopGet(AOP(left),MSB16,FALSE,FALSE);
+ MOVA(l);
+ }
+ emitcode("rlc","a");
+ if (sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB24+offr && offr != LSB)
+ emitcode("xch","a,%s",
+ aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",MSB16+offr);
+ }
+
+ if(size >= MSB24+offr){
+ if (!(sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
+ l = aopGet(AOP(left),MSB24,FALSE,FALSE);
+ MOVA(l);
+ }
+ emitcode("rlc","a");
+ if (sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB32+offr && offr != LSB )
+ emitcode("xch","a,%s",
+ aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",MSB24+offr);
+ }
+
+ if(size > MSB32+offr){
+ if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
+ l = aopGet(AOP(left),MSB32,FALSE,FALSE);
+ MOVA(l);
+ }
+ emitcode("rlc","a");
+ aopPut(AOP(result),"a",MSB32+offr);
+ }
+ if(offr != LSB)
+ aopPut(AOP(result),zero,LSB);
+}
+
+/*-----------------------------------------------------------------*/
+/* genlshFour - shift four byte by a known amount != 0 */
+/*-----------------------------------------------------------------*/
+static void genlshFour (operand *result, operand *left, int shCount)
+{
+ int size;
+
+ size = AOP_SIZE(result);
+
+ /* if shifting more that 3 bytes */
+ if (shCount >= 24 ) {
+ shCount -= 24;
+ if (shCount)
+ /* lowest order of left goes to the highest
+ order of the destination */
+ shiftL1Left2Result(left, LSB, result, MSB32, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB32, 0);
+ aopPut(AOP(result),zero,LSB);
+ aopPut(AOP(result),zero,MSB16);
+ aopPut(AOP(result),zero,MSB32);
+ return;
+ }
+
+ /* more than two bytes */
+ else if ( shCount >= 16 ) {
+ /* lower order two bytes goes to higher order two bytes */
+ shCount -= 16;
+ /* if some more remaining */
+ if (shCount)
+ shiftL2Left2Result(left, LSB, result, MSB24, shCount);
+ else {
+ movLeft2Result(left, MSB16, result, MSB32, 0);
+ movLeft2Result(left, LSB, result, MSB24, 0);
+ }
+ aopPut(AOP(result),zero,MSB16);
+ aopPut(AOP(result),zero,LSB);
+ return;
+ }
+
+ /* if more than 1 byte */
+ else if ( shCount >= 8 ) {
+ /* lower order three bytes goes to higher order three bytes */
+ shCount -= 8;
+ if(size == 2){
+ if(shCount)
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB16, 0);
+ }
+ else{ /* size = 4 */
+ if(shCount == 0){
+ movLeft2Result(left, MSB24, result, MSB32, 0);
+ movLeft2Result(left, MSB16, result, MSB24, 0);
+ movLeft2Result(left, LSB, result, MSB16, 0);
+ aopPut(AOP(result),zero,LSB);
+ }
+ else if(shCount == 1)
+ shiftLLong(left, result, MSB16);
+ else{
+ shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
+ aopPut(AOP(result),zero,LSB);
+ }
+ }
+ }
+
+ /* 1 <= shCount <= 7 */
+ else if(shCount <= 2){
+ shiftLLong(left, result, LSB);
+ if(shCount == 2)
+ shiftLLong(result, result, LSB);
+ }
+ /* 3 <= shCount <= 7, optimize */
+ else{
+ shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
+ shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
+ shiftL2Left2Result(left, LSB, result, LSB, shCount);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genLeftShiftLiteral - left shifting by known count */
+/*-----------------------------------------------------------------*/
+static void genLeftShiftLiteral (operand *left,
+ operand *right,
+ operand *result,
+ iCode *ic)
+{
+ int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
+ int size;
+
+ freeAsmop(right,NULL,ic,TRUE);
+
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ size = getSize(operandType(result));
+
+#if VIEW_SIZE
+ emitcode("; shift left ","result %d, left %d",size,
+ AOP_SIZE(left));
+#endif
+
+ /* I suppose that the left size >= result size */
+ if(shCount == 0){
+ while(size--){
+ movLeft2Result(left, size, result, size, 0);
+ }
+ }
+
+ else if(shCount >= (size * 8))
+ while(size--)
+ aopPut(AOP(result),zero,size);
+ else{
+ switch (size) {
+ case 1:
+ genlshOne (result,left,shCount);
+ break;
+
+ case 2:
+ case 3:
+ genlshTwo (result,left,shCount);
+ break;
+
+ case 4:
+ genlshFour (result,left,shCount);
+ break;
+ }
+ }
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genLeftShift - generates code for left shifting */
+/*-----------------------------------------------------------------*/
+static void genLeftShift (iCode *ic)
+{
+ operand *left,*right, *result;
+ int size, offset;
+ char *l;
+ symbol *tlbl , *tlbl1;
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+
+ /* if the shift count is known then do it
+ as efficiently as possible */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ genLeftShiftLiteral (left,right,result,ic);
+ return ;
+ }
+
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("inc","b");
+ freeAsmop (right,NULL,ic,TRUE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs(AOP(left),AOP(result)) &&
+ AOP_SIZE(result) > 1) {
+
+ size = AOP_SIZE(result);
+ offset=0;
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && (IS_AOP_PREG(result))) {
+
+ emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else
+ aopPut(AOP(result),l,offset);
+ offset++;
+ }
+ }
+
+ tlbl = newiTempLabel(NULL);
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ tlbl1 = newiTempLabel(NULL);
+
+ /* if it is only one byte then */
+ if (size == 1) {
+ symbol *tlbl1 = newiTempLabel(NULL);
+
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ emitcode("add","a,acc");
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ reAdjustPreg(AOP(result));
+
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ l = aopGet(AOP(result),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("add","a,acc");
+ aopPut(AOP(result),"a",offset++);
+ while (--size) {
+ l = aopGet(AOP(result),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("rlc","a");
+ aopPut(AOP(result),"a",offset++);
+ }
+ reAdjustPreg(AOP(result));
+
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+release:
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genrshOne - right shift a one byte quantity by known count */
+/*-----------------------------------------------------------------*/
+static void genrshOne (operand *result, operand *left,
+ int shCount, int sign)
+{
+ shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
+}
+
+/*-----------------------------------------------------------------*/
+/* genrshTwo - right shift two bytes by known amount != 0 */
+/*-----------------------------------------------------------------*/
+static void genrshTwo (operand *result,operand *left,
+ int shCount, int sign)
+{
+ /* if shCount >= 8 */
+ if (shCount >= 8) {
+ shCount -= 8 ;
+ if (shCount)
+ shiftR1Left2Result(left, MSB16, result, LSB,
+ shCount, sign);
+ else
+ movLeft2Result(left, MSB16, result, LSB, sign);
+ addSign(result, MSB16, sign);
+ }
+
+ /* 1 <= shCount <= 7 */
+ else
+ shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRLong - shift right one long from left to result */
+/* offl = LSB or MSB16 */
+/*-----------------------------------------------------------------*/
+static void shiftRLong (operand *left, int offl,
+ operand *result, int sign)
+{
+ if(!sign)
+ emitcode("clr","c");
+ MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
+ if(sign)
+ emitcode("mov","c,acc.7");
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",MSB32-offl);
+ if(offl == MSB16)
+ /* add sign of "a" */
+ addSign(result, MSB32, sign);
+
+ MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",MSB24-offl);
+
+ MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",MSB16-offl);
+
+ if(offl == LSB){
+ MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",LSB);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genrshFour - shift four byte by a known amount != 0 */
+/*-----------------------------------------------------------------*/
+static void genrshFour (operand *result, operand *left,
+ int shCount, int sign)
+{
+ /* if shifting more that 3 bytes */
+ if(shCount >= 24 ) {
+ shCount -= 24;
+ if(shCount)
+ shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
+ else
+ movLeft2Result(left, MSB32, result, LSB, sign);
+ addSign(result, MSB16, sign);
+ }
+ else if(shCount >= 16){
+ shCount -= 16;
+ if(shCount)
+ shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
+ else{
+ movLeft2Result(left, MSB24, result, LSB, 0);
+ movLeft2Result(left, MSB32, result, MSB16, sign);
+ }
+ addSign(result, MSB24, sign);
+ }
+ else if(shCount >= 8){
+ shCount -= 8;
+ if(shCount == 1)
+ shiftRLong(left, MSB16, result, sign);
+ else if(shCount == 0){
+ movLeft2Result(left, MSB16, result, LSB, 0);
+ movLeft2Result(left, MSB24, result, MSB16, 0);
+ movLeft2Result(left, MSB32, result, MSB24, sign);
+ addSign(result, MSB32, sign);
+ }
+ else{
+ shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
+ shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
+ /* the last shift is signed */
+ shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
+ addSign(result, MSB32, sign);
+ }
+ }
+ else{ /* 1 <= shCount <= 7 */
+ if(shCount <= 2){
+ shiftRLong(left, LSB, result, sign);
+ if(shCount == 2)
+ shiftRLong(result, LSB, result, sign);
+ }
+ else{
+ shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
+ shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
+ shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genRightShiftLiteral - right shifting by known count */
+/*-----------------------------------------------------------------*/
+static void genRightShiftLiteral (operand *left,
+ operand *right,
+ operand *result,
+ iCode *ic,
+ int sign)
+{
+ int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
+ int size;
+
+ freeAsmop(right,NULL,ic,TRUE);
+
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+#if VIEW_SIZE
+ emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
+ AOP_SIZE(left));
+#endif
+
+ size = getDataSize(left);
+ /* test the LEFT size !!! */
+
+ /* I suppose that the left size >= result size */
+ if(shCount == 0){
+ size = getDataSize(result);
+ while(size--)
+ movLeft2Result(left, size, result, size, 0);
+ }
+
+ else if(shCount >= (size * 8)){
+ if(sign)
+ /* get sign in acc.7 */
+ MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
+ addSign(result, LSB, sign);
+ } else{
+ switch (size) {
+ case 1:
+ genrshOne (result,left,shCount,sign);
+ break;
+
+ case 2:
+ genrshTwo (result,left,shCount,sign);
+ break;
+
+ case 4:
+ genrshFour (result,left,shCount,sign);
+ break;
+ default :
+ break;
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genSignedRightShift - right shift of signed number */
+/*-----------------------------------------------------------------*/
+static void genSignedRightShift (iCode *ic)
+{
+ operand *right, *left, *result;
+ int size, offset;
+ char *l;
+ symbol *tlbl, *tlbl1 ;
+
+ /* we do it the hard way put the shift count in b
+ and loop thru preserving the sign */
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+
+
+ if ( AOP_TYPE(right) == AOP_LIT) {
+ genRightShiftLiteral (left,right,result,ic,1);
+ return ;
+ }
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("inc","b");
+ freeAsmop (right,NULL,ic,TRUE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs(AOP(left),AOP(result)) &&
+ AOP_SIZE(result) > 1) {
+
+ size = AOP_SIZE(result);
+ offset=0;
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && IS_AOP_PREG(result)) {
+
+ emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else
+ aopPut(AOP(result),l,offset);
+ offset++;
+ }
+ }
+
+ /* mov the highest order bit to OVR */
+ tlbl = newiTempLabel(NULL);
+ tlbl1= newiTempLabel(NULL);
+
+ size = AOP_SIZE(result);
+ offset = size - 1;
+ emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
+ emitcode("rlc","a");
+ emitcode("mov","ov,c");
+ /* if it is only one byte then */
+ if (size == 1) {
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ emitcode("mov","c,ov");
+ emitcode("rrc","a");
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ reAdjustPreg(AOP(result));
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ emitcode("mov","c,ov");
+ while (size--) {
+ l = aopGet(AOP(result),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",offset--);
+ }
+ reAdjustPreg(AOP(result));
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+
+release:
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRightShift - generate code for right shifting */
+/*-----------------------------------------------------------------*/
+static void genRightShift (iCode *ic)
+{
+ operand *right, *left, *result;
+ link *retype ;
+ int size, offset;
+ char *l;
+ symbol *tlbl, *tlbl1 ;
+
+ /* if signed then we do it the hard way preserve the
+ sign bit moving it inwards */
+ retype = getSpec(operandType(IC_RESULT(ic)));
+
+ if (!SPEC_USIGN(retype)) {
+ genSignedRightShift (ic);
+ return ;
+ }
+
+ /* signed & unsigned types are treated the same : i.e. the
+ signed is NOT propagated inwards : quoting from the
+ ANSI - standard : "for E1 >> E2, is equivalent to division
+ by 2**E2 if unsigned or if it has a non-negative value,
+ otherwise the result is implementation defined ", MY definition
+ is that the sign does not get propagated */
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+
+ /* if the shift count is known then do it
+ as efficiently as possible */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ genRightShiftLiteral (left,right,result,ic, 0);
+ return ;
+ }
+
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ emitcode("inc","b");
+ freeAsmop (right,NULL,ic,TRUE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs(AOP(left),AOP(result)) &&
+ AOP_SIZE(result) > 1) {
+
+ size = AOP_SIZE(result);
+ offset=0;
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && IS_AOP_PREG(result)) {
+
+ emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else
+ aopPut(AOP(result),l,offset);
+ offset++;
+ }
+ }
+
+ tlbl = newiTempLabel(NULL);
+ tlbl1= newiTempLabel(NULL);
+ size = AOP_SIZE(result);
+ offset = size - 1;
+
+ /* if it is only one byte then */
+ if (size == 1) {
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ CLRC;
+ emitcode("rrc","a");
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ reAdjustPreg(AOP(result));
+ emitcode("sjmp","%05d$",tlbl1->key+100);
+ emitcode("","%05d$:",tlbl->key+100);
+ CLRC;
+ while (size--) {
+ l = aopGet(AOP(result),offset,FALSE,FALSE);
+ MOVA(l);
+ emitcode("rrc","a");
+ aopPut(AOP(result),"a",offset--);
+ }
+ reAdjustPreg(AOP(result));
+
+ emitcode("","%05d$:",tlbl1->key+100);
+ emitcode("djnz","b,%05d$",tlbl->key+100);
+
+release:
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits */
+/*-----------------------------------------------------------------*/
+static void genUnpackBits (operand *result, char *rname, int ptype)
+{
+ int shCnt ;
+ int rlen = 0 ;
+ link *etype;
+ int offset = 0 ;
+
+ etype = getSpec(operandType(result));
+
+ /* read the first byte */
+ switch (ptype) {
+
+ case POINTER:
+ case IPOINTER:
+ emitcode("mov","a,@%s",rname);
+ break;
+
+ case PPOINTER:
+ emitcode("movx","a,@%s",rname);
+ break;
+
+ case FPOINTER:
+ emitcode("movx","a,@dptr");
+ break;
+
+ case CPOINTER:
+ emitcode("clr","a");
+ emitcode("movc","a","@a+dptr");
+ break;
+
+ case GPOINTER:
+ emitcode("lcall","__gptrget");
+ break;
+ }
+
+ /* if we have bitdisplacement then it fits */
+ /* into this byte completely or if length is */
+ /* less than a byte */
+ if ((shCnt = SPEC_BSTR(etype)) ||
+ (SPEC_BLEN(etype) <= 8)) {
+
+ /* shift right acc */
+ AccRsh(shCnt);
+
+ emitcode("anl","a,#0x%02x",
+ ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
+ aopPut(AOP(result),"a",offset);
+ return ;
+ }
+
+ /* bit field did not fit in a byte */
+ rlen = SPEC_BLEN(etype) - 8;
+ aopPut(AOP(result),"a",offset++);
+
+ while (1) {
+
+ switch (ptype) {
+ case POINTER:
+ case IPOINTER:
+ emitcode("inc","%s",rname);
+ emitcode("mov","a,@%s",rname);
+ break;
+
+ case PPOINTER:
+ emitcode("inc","%s",rname);
+ emitcode("movx","a,@%s",rname);
+ break;
+
+ case FPOINTER:
+ emitcode("inc","dptr");
+ emitcode("movx","a,@dptr");
+ break;
+
+ case CPOINTER:
+ emitcode("clr","a");
+ emitcode("inc","dptr");
+ emitcode("movc","a","@a+dptr");
+ break;
+
+ case GPOINTER:
+ emitcode("inc","dptr");
+ emitcode("lcall","__gptrget");
+ break;
+ }
+
+ rlen -= 8;
+ /* if we are done */
+ if ( rlen <= 0 )
+ break ;
+
+ aopPut(AOP(result),"a",offset++);
+
+ }
+
+ if (rlen) {
+ emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
+ aopPut(AOP(result),"a",offset);
+ }
+
+ return ;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genDataPointerGet - generates code when ptr offset is known */
+/*-----------------------------------------------------------------*/
+static void genDataPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ char *l;
+ char buffer[256];
+ int size , offset = 0;
+ aopOp(result,ic,TRUE);
+
+ /* get the string representation of the name */
+ l = aopGet(AOP(left),0,FALSE,TRUE);
+ size = AOP_SIZE(result);
+ while (size--) {
+ if (offset)
+ sprintf(buffer,"(%s + %d)",l+1,offset);
+ else
+ sprintf(buffer,"%s",l+1);
+ aopPut(AOP(result),buffer,offset++);
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNearPointerGet - emitcode for near pointer fetch */
+/*-----------------------------------------------------------------*/
+static void genNearPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname ;
+ link *rtype, *retype;
+ link *ltype = operandType(left);
+ char buffer[80];
+
+ rtype = operandType(result);
+ retype= getSpec(rtype);
+
+ aopOp(left,ic,FALSE);
+
+ /* if left is rematerialisable and
+ result is not bit variable type and
+ the left is pointer to data space i.e
+ lower 128 bytes of space */
+ if (AOP_TYPE(left) == AOP_IMMD &&
+ !IS_BITVAR(retype) &&
+ DCL_TYPE(ltype) == POINTER) {
+ genDataPointerGet (left,result,ic);
+ return ;
+ }
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(left))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(left),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(left),0,FALSE,FALSE);
+
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp (result,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR(retype))
+ genUnpackBits (result,rname,POINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(result);
+ int offset = 0 ;
+
+ while (size--) {
+ if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
+
+ emitcode("mov","a,@%s",rname);
+ aopPut(AOP(result),"a",offset);
+ } else {
+ sprintf(buffer,"@%s",rname);
+ aopPut(AOP(result),buffer,offset);
+ }
+ offset++ ;
+ if (size)
+ emitcode("inc","%s",rname);
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(result) > 1 &&
+ !OP_SYMBOL(left)->remat &&
+ ( OP_SYMBOL(left)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(result) - 1;
+ while (size--)
+ emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(result,NULL,ic,TRUE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPagedPointerGet - emitcode for paged pointer fetch */
+/*-----------------------------------------------------------------*/
+static void genPagedPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname ;
+ link *rtype, *retype;
+
+ rtype = operandType(result);
+ retype= getSpec(rtype);
+
+ aopOp(left,ic,FALSE);
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(left))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(left),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(left),0,FALSE,FALSE);
+
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp (result,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR(retype))
+ genUnpackBits (result,rname,PPOINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(result);
+ int offset = 0 ;
+
+ while (size--) {
+
+ emitcode("movx","a,@%s",rname);
+ aopPut(AOP(result),"a",offset);
+
+ offset++ ;
+
+ if (size)
+ emitcode("inc","%s",rname);
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(result) > 1 &&
+ !OP_SYMBOL(left)->remat &&
+ ( OP_SYMBOL(left)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(result) - 1;
+ while (size--)
+ emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(result,NULL,ic,TRUE);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarPointerGet - gget value from far space */
+/*-----------------------------------------------------------------*/
+static void genFarPointerGet (operand *left,
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ link *retype = getSpec(operandType(result));
+
+ aopOp(left,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(left) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(left) == AOP_IMMD)
+ emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp(result,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR(retype))
+ genUnpackBits(result,"dptr",FPOINTER);
+ else {
+ size = AOP_SIZE(result);
+ offset = 0 ;
+
+ while (size--) {
+ emitcode("movx","a,@dptr");
+ aopPut(AOP(result),"a",offset++);
+ if (size)
+ emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* emitcodePointerGet - gget value from code space */
+/*-----------------------------------------------------------------*/
+static void emitcodePointerGet (operand *left,
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ link *retype = getSpec(operandType(result));
+
+ aopOp(left,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(left) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(left) == AOP_IMMD)
+ emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp(result,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR(retype))
+ genUnpackBits(result,"dptr",CPOINTER);
+ else {
+ size = AOP_SIZE(result);
+ offset = 0 ;
+
+ while (size--) {
+ emitcode("clr","a");
+ emitcode("movc","a,@a+dptr");
+ aopPut(AOP(result),"a",offset++);
+ if (size)
+ emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGenPointerGet - gget value from generic pointer space */
+/*-----------------------------------------------------------------*/
+static void genGenPointerGet (operand *left,
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ link *retype = getSpec(operandType(result));
+
+ aopOp(left,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(left) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(left) == AOP_IMMD) {
+ emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+ emitcode("mov","b,#%d",pointerCode(retype));
+ }
+ else { /* we need to get it byte by byte */
+ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp(result,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR(retype))
+ genUnpackBits(result,"dptr",GPOINTER);
+ else {
+ size = AOP_SIZE(result);
+ offset = 0 ;
+
+ while (size--) {
+ emitcode("lcall","__gptrget");
+ aopPut(AOP(result),"a",offset++);
+ if (size)
+ emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPointerGet - generate code for pointer get */
+/*-----------------------------------------------------------------*/
+static void genPointerGet (iCode *ic)
+{
+ operand *left, *result ;
+ link *type, *etype;
+ int p_type;
+
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic) ;
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType(left);
+ etype = getSpec(type);
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR(type) && !IS_FUNC(type->next))
+ p_type = DCL_TYPE(type);
+ else {
+
+ /* we have to go by the storage class */
+ if (SPEC_OCLS(etype)->codesp ) {
+ p_type = CPOINTER ;
+ }
+ else
+ if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+ p_type = FPOINTER ;
+ else
+ if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+ p_type = PPOINTER;
+ else
+ if (SPEC_OCLS(etype) == idata )
+ p_type = IPOINTER;
+ else
+ p_type = POINTER ;
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case IPOINTER:
+ genNearPointerGet (left,result,ic);
+ break;
+
+ case PPOINTER:
+ genPagedPointerGet(left,result,ic);
+ break;
+
+ case FPOINTER:
+ genFarPointerGet (left,result,ic);
+ break;
+
+ case CPOINTER:
+ emitcodePointerGet (left,result,ic);
+ break;
+
+ case GPOINTER:
+ genGenPointerGet (left,result,ic);
+ break;
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage */
+/*-----------------------------------------------------------------*/
+static void genPackBits (link *etype ,
+ operand *right ,
+ char *rname, int p_type)
+{
+ int shCount = 0 ;
+ int offset = 0 ;
+ int rLen = 0 ;
+ int blen, bstr ;
+ char *l ;
+
+ blen = SPEC_BLEN(etype);
+ bstr = SPEC_BSTR(etype);
+
+ l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+
+ /* if the bit lenth is less than or */
+ /* it exactly fits a byte then */
+ if (SPEC_BLEN(etype) <= 8 ) {
+ shCount = SPEC_BSTR(etype) ;
+
+ /* shift left acc */
+ AccLsh(shCount);
+
+ if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
+
+
+ switch (p_type) {
+ case POINTER:
+ emitcode ("mov","b,a");
+ emitcode("mov","a,@%s",rname);
+ break;
+
+ case FPOINTER:
+ emitcode ("mov","b,a");
+ emitcode("movx","a,@dptr");
+ break;
+
+ case GPOINTER:
+ emitcode ("push","b");
+ emitcode ("push","acc");
+ emitcode ("lcall","__gptrget");
+ emitcode ("pop","b");
+ break;
+ }
+
+ emitcode ("anl","a,#0x%02x",(unsigned char)
+ ((unsigned char)(0xFF << (blen+bstr)) |
+ (unsigned char)(0xFF >> (8-bstr)) ) );
+ emitcode ("orl","a,b");
+ if (p_type == GPOINTER)
+ emitcode("pop","b");
+ }
+ }
+
+ switch (p_type) {
+ case POINTER:
+ emitcode("mov","@%s,a",rname);
+ break;
+
+ case FPOINTER:
+ emitcode("movx","@dptr,a");
+ break;
+
+ case GPOINTER:
+ emitcode("lcall","__gptrput");
+ break;
+ }
+
+ /* if we r done */
+ if ( SPEC_BLEN(etype) <= 8 )
+ return ;
+
+ emitcode("inc","%s",rname);
+ rLen = SPEC_BLEN(etype) ;
+
+ /* now generate for lengths greater than one byte */
+ while (1) {
+
+ l = aopGet(AOP(right),offset++,FALSE,TRUE);
+
+ rLen -= 8 ;
+ if (rLen <= 0 )
+ break ;
+
+ switch (p_type) {
+ case POINTER:
+ if (*l == '@') {
+ MOVA(l);
+ emitcode("mov","@%s,a",rname);
+ } else
+ emitcode("mov","@%s,%s",rname,l);
+ break;
+
+ case FPOINTER:
+ MOVA(l);
+ emitcode("movx","@dptr,a");
+ break;
+
+ case GPOINTER:
+ MOVA(l);
+ emitcode("lcall","__gptrput");
+ break;
+ }
+ emitcode ("inc","%s",rname);
+ }
+
+ MOVA(l);
+
+ /* last last was not complete */
+ if (rLen) {
+ /* save the byte & read byte */
+ switch (p_type) {
+ case POINTER:
+ emitcode ("mov","b,a");
+ emitcode("mov","a,@%s",rname);
+ break;
+
+ case FPOINTER:
+ emitcode ("mov","b,a");
+ emitcode("movx","a,@dptr");
+ break;
+
+ case GPOINTER:
+ emitcode ("push","b");
+ emitcode ("push","acc");
+ emitcode ("lcall","__gptrget");
+ emitcode ("pop","b");
+ break;
+ }
+
+ emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
+ emitcode ("orl","a,b");
+ }
+
+ if (p_type == GPOINTER)
+ emitcode("pop","b");
+
+ switch (p_type) {
+
+ case POINTER:
+ emitcode("mov","@%s,a",rname);
+ break;
+
+ case FPOINTER:
+ emitcode("movx","@dptr,a");
+ break;
+
+ case GPOINTER:
+ emitcode("lcall","__gptrput");
+ break;
+ }
+}
+/*-----------------------------------------------------------------*/
+/* genDataPointerSet - remat pointer to data space */
+/*-----------------------------------------------------------------*/
+static void genDataPointerSet(operand *right,
+ operand *result,
+ iCode *ic)
+{
+ int size, offset = 0 ;
+ char *l, buffer[256];
+
+ aopOp(right,ic,FALSE);
+
+ l = aopGet(AOP(result),0,FALSE,TRUE);
+ size = AOP_SIZE(right);
+ while (size--) {
+ if (offset)
+ sprintf(buffer,"(%s + %d)",l+1,offset);
+ else
+ sprintf(buffer,"%s",l+1);
+ emitcode("mov","%s,%s",buffer,
+ aopGet(AOP(right),offset++,FALSE,FALSE));
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNearPointerSet - emitcode for near pointer put */
+/*-----------------------------------------------------------------*/
+static void genNearPointerSet (operand *right,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname , *l;
+ link *retype;
+ link *ptype = operandType(result);
+
+ retype= getSpec(operandType(right));
+
+ aopOp(result,ic,FALSE);
+
+ /* if the result is rematerializable &
+ in data space & not a bit variable */
+ if (AOP_TYPE(result) == AOP_IMMD &&
+ DCL_TYPE(ptype) == POINTER &&
+ !IS_BITVAR(retype)) {
+ genDataPointerSet (right,result,ic);
+ return;
+ }
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(result))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(result),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(result),0,FALSE,FALSE);
+
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp (right,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR(retype))
+ genPackBits (retype,right,rname,POINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+
+ while (size--) {
+ l = aopGet(AOP(right),offset,FALSE,TRUE);
+ if (*l == '@' ) {
+ MOVA(l);
+ emitcode("mov","@%s,a",rname);
+ } else
+ emitcode("mov","@%s,%s",rname,l);
+ if (size)
+ emitcode("inc","%s",rname);
+ offset++;
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(right) > 1 &&
+ !OP_SYMBOL(result)->remat &&
+ ( OP_SYMBOL(result)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(right) - 1;
+ while (size--)
+ emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(right,NULL,ic,TRUE);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPagedPointerSet - emitcode for Paged pointer put */
+/*-----------------------------------------------------------------*/
+static void genPagedPointerSet (operand *right,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname , *l;
+ link *retype;
+
+ retype= getSpec(operandType(right));
+
+ aopOp(result,ic,FALSE);
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(result))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(result),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(result),0,FALSE,FALSE);
+
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp (right,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR(retype))
+ genPackBits (retype,right,rname,PPOINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+
+ while (size--) {
+ l = aopGet(AOP(right),offset,FALSE,TRUE);
+
+ MOVA(l);
+ emitcode("movx","@%s,a",rname);
+
+ if (size)
+ emitcode("inc","%s",rname);
+
+ offset++;
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(right) > 1 &&
+ !OP_SYMBOL(result)->remat &&
+ ( OP_SYMBOL(result)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(right) - 1;
+ while (size--)
+ emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(right,NULL,ic,TRUE);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarPointerSet - set value from far space */
+/*-----------------------------------------------------------------*/
+static void genFarPointerSet (operand *right,
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ link *retype = getSpec(operandType(right));
+
+ aopOp(result,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(result) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(result) == AOP_IMMD)
+ emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
+ emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp(right,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR(retype))
+ genPackBits(retype,right,"dptr",FPOINTER);
+ else {
+ size = AOP_SIZE(right);
+ offset = 0 ;
+
+ while (size--) {
+ char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ emitcode("movx","@dptr,a");
+ if (size)
+ emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGenPointerSet - set value from generic pointer space */
+/*-----------------------------------------------------------------*/
+static void genGenPointerSet (operand *right,
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ link *retype = getSpec(operandType(right));
+
+ aopOp(result,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(result) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(result) == AOP_IMMD) {
+ emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
+ emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
+ }
+ else { /* we need to get it byte by byte */
+ emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
+ emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
+ emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp(right,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR(retype))
+ genPackBits(retype,right,"dptr",GPOINTER);
+ else {
+ size = AOP_SIZE(right);
+ offset = 0 ;
+
+ while (size--) {
+ char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ emitcode("lcall","__gptrput");
+ if (size)
+ emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPointerSet - stores the value into a pointer location */
+/*-----------------------------------------------------------------*/
+static void genPointerSet (iCode *ic)
+{
+ operand *right, *result ;
+ link *type, *etype;
+ int p_type;
+
+ right = IC_RIGHT(ic);
+ result = IC_RESULT(ic) ;
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType(result);
+ etype = getSpec(type);
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR(type) && !IS_FUNC(type->next)) {
+ p_type = DCL_TYPE(type);
+ }
+ else {
+
+ /* we have to go by the storage class */
+ if (SPEC_OCLS(etype)->codesp ) {
+ p_type = CPOINTER ;
+ }
+ else
+ if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+ p_type = FPOINTER ;
+ else
+ if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+ p_type = PPOINTER ;
+ else
+ if (SPEC_OCLS(etype) == idata )
+ p_type = IPOINTER ;
+ else
+ p_type = POINTER ;
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case IPOINTER:
+ genNearPointerSet (right,result,ic);
+ break;
+
+ case PPOINTER:
+ genPagedPointerSet (right,result,ic);
+ break;
+
+ case FPOINTER:
+ genFarPointerSet (right,result,ic);
+ break;
+
+ case GPOINTER:
+ genGenPointerSet (right,result,ic);
+ break;
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genIfx - generate code for Ifx statement */
+/*-----------------------------------------------------------------*/
+static void genIfx (iCode *ic, iCode *popIc)
+{
+ operand *cond = IC_COND(ic);
+ int isbit =0;
+
+ aopOp(cond,ic,FALSE);
+
+ /* get the value into acc */
+ if (AOP_TYPE(cond) != AOP_CRY)
+ toBoolean(cond);
+ else
+ isbit = 1;
+ /* the result is now in the accumulator */
+ freeAsmop(cond,NULL,ic,TRUE);
+
+ /* if there was something to be popped then do it */
+ if (popIc)
+ genIpop(popIc);
+
+ /* if the condition is a bit variable */
+ if (isbit && IS_ITEMP(cond) &&
+ SPIL_LOC(cond))
+ genIfxJump(ic,SPIL_LOC(cond)->rname);
+ else
+ if (isbit && !IS_ITEMP(cond))
+ genIfxJump(ic,OP_SYMBOL(cond)->rname);
+ else
+ genIfxJump(ic,"a");
+
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genAddrOf - generates code for address of */
+/*-----------------------------------------------------------------*/
+static void genAddrOf (iCode *ic)
+{
+ symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+ int size, offset ;
+
+ aopOp(IC_RESULT(ic),ic,FALSE);
+
+ /* if the operand is on the stack then we
+ need to get the stack offset of this
+ variable */
+ if (sym->onStack) {
+ /* if it has an offset then we need to compute
+ it */
+ if (sym->stack) {
+ emitcode("mov","a,_bp");
+ emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
+ aopPut(AOP(IC_RESULT(ic)),"a",0);
+ } else
+ /* we can just move _bp */
+ aopPut(AOP(IC_RESULT(ic)),"_bp",0);
+ /* fill the result with zero */
+ size = AOP_SIZE(IC_RESULT(ic)) - 1;
+ offset = 1;
+ while (size--)
+ aopPut(AOP(IC_RESULT(ic)),zero,offset++);
+
+ goto release;
+ }
+
+ /* object not on stack then we need the name */
+ size = AOP_SIZE(IC_RESULT(ic));
+ offset = 0;
+
+ while (size--) {
+ char s[SDCC_NAME_MAX];
+ if (offset)
+ sprintf(s,"#(%s >> %d)",
+ sym->rname,
+ offset*8);
+ else
+ sprintf(s,"#%s",sym->rname);
+ aopPut(AOP(IC_RESULT(ic)),s,offset++);
+ }
+
+release:
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarFarAssign - assignment when both are in far space */
+/*-----------------------------------------------------------------*/
+static void genFarFarAssign (operand *result, operand *right, iCode *ic)
+{
+ int size = AOP_SIZE(right);
+ int offset = 0;
+ char *l ;
+ /* first push the right side on to the stack */
+ while (size--) {
+ l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ emitcode ("push","acc");
+ }
+
+ freeAsmop(right,NULL,ic,FALSE);
+ /* now assign DPTR to result */
+ aopOp(result,ic,FALSE);
+ size = AOP_SIZE(result);
+ while (size--) {
+ emitcode ("pop","acc");
+ aopPut(AOP(result),"a",--offset);
+ }
+ freeAsmop(result,NULL,ic,FALSE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genAssign - generate code for assignment */
+/*-----------------------------------------------------------------*/
+static void genAssign (iCode *ic)
+{
+ operand *result, *right;
+ int size, offset ;
+ unsigned long lit = 0L;
+
+ result = IC_RESULT(ic);
+ right = IC_RIGHT(ic) ;
+
+ /* if they are the same */
+ if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
+
+ aopOp(right,ic,FALSE);
+
+ /* special case both in far space */
+ if (AOP_TYPE(right) == AOP_DPTR &&
+ IS_TRUE_SYMOP(result) &&
+ isOperandInFarSpace(result)) {
+
+ genFarFarAssign (result,right,ic);
+ return ;
+ }
+
+ aopOp(result,ic,TRUE);
+
+ /* if they are the same registers */
+ if (sameRegs(AOP(right),AOP(result)))
+ goto release;
+
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ if (((int) operandLitValue(right)))
+ aopPut(AOP(result),one,0);
+ else
+ aopPut(AOP(result),zero,0);
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ aopPut(AOP(result),"c",0);
+ goto release ;
+ }
+
+ /* we need to or */
+ toBoolean(right);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ if((size > 1) &&
+ (AOP_TYPE(result) != AOP_REG) &&
+ (AOP_TYPE(right) == AOP_LIT) &&
+ !IS_FLOAT(operandType(right)) &&
+ (lit < 256L)){
+ emitcode("clr","a");
+ while (size--) {
+ if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0)
+ aopPut(AOP(result),"a",size);
+ else
+ aopPut(AOP(result),
+ aopGet(AOP(right),size,FALSE,FALSE),
+ size);
+ }
+ } else {
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ }
+
+release:
+ freeAsmop (right,NULL,ic,FALSE);
+ freeAsmop (result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genJumpTab - genrates code for jump table */
+/*-----------------------------------------------------------------*/
+static void genJumpTab (iCode *ic)
+{
+ symbol *jtab;
+ char *l;
+
+ aopOp(IC_JTCOND(ic),ic,FALSE);
+ /* get the condition into accumulator */
+ l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
+ MOVA(l);
+ /* multiply by three */
+ emitcode("add","a,acc");
+ emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
+ freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
+
+ jtab = newiTempLabel(NULL);
+ emitcode("mov","dptr,#%05d$",jtab->key+100);
+ emitcode("jmp","@a+dptr");
+ emitcode("","%05d$:",jtab->key+100);
+ /* now generate the jump labels */
+ for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
+ jtab = setNextItem(IC_JTLABELS(ic)))
+ emitcode("ljmp","%05d$",jtab->key+100);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genCast - gen code for casting */
+/*-----------------------------------------------------------------*/
+static void genCast (iCode *ic)
+{
+ operand *result = IC_RESULT(ic);
+ link *ctype = operandType(IC_LEFT(ic));
+ operand *right = IC_RIGHT(ic);
+ int size, offset ;
+
+ /* if they are equivalent then do nothing */
+ if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
+
+ aopOp(right,ic,FALSE) ;
+ aopOp(result,ic,FALSE);
+
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ if (((int) operandLitValue(right)))
+ aopPut(AOP(result),one,0);
+ else
+ aopPut(AOP(result),zero,0);
+
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ aopPut(AOP(result),"c",0);
+ goto release ;
+ }
+
+ /* we need to or */
+ toBoolean(right);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ /* if they are the same size : or less */
+ if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+
+ /* if they are in the same place */
+ if (sameRegs(AOP(right),AOP(result)))
+ goto release;
+
+ /* if they in different places then copy */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ goto release;
+ }
+
+
+ /* if the result is of type pointer */
+ if (IS_PTR(ctype)) {
+
+ int p_type;
+ link *type = operandType(right);
+ link *etype = getSpec(type);
+
+ /* pointer to generic pointer */
+ if (IS_GENPTR(ctype)) {
+ char *l = zero;
+
+ if (IS_PTR(type))
+ p_type = DCL_TYPE(type);
+ else {
+ /* we have to go by the storage class */
+ if (SPEC_OCLS(etype)->codesp )
+ p_type = CPOINTER ;
+ else
+ if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+ p_type = FPOINTER ;
+ else
+ if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+ p_type = PPOINTER;
+ else
+ if (SPEC_OCLS(etype) == idata )
+ p_type = IPOINTER ;
+ else
+ p_type = POINTER ;
+ }
+
+ /* the first two bytes are known */
+ size = 2;
+ offset = 0 ;
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ /* the last byte depending on type */
+ switch (p_type) {
+ case IPOINTER:
+ case POINTER:
+ l = zero;
+ break;
+ case FPOINTER:
+ l = one;
+ break;
+ case CPOINTER:
+ l = "#0x02";
+ break;
+ case PPOINTER:
+ l = "#0x03";
+ break;
+
+ default:
+ /* this should never happen */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "got unknown pointer type");
+ exit(1);
+ }
+ aopPut(AOP(result),l,2);
+ goto release ;
+ }
+
+ /* just copy the pointers */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ goto release ;
+ }
+
+ /* so we now know that the size of destination is greater
+ than the size of the source */
+ /* we move to result for the size of source */
+ size = AOP_SIZE(right);
+ offset = 0 ;
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+
+ /* now depending on the sign of the destination */
+ size = AOP_SIZE(result) - AOP_SIZE(right);
+ /* if unsigned or not an integral type */
+ if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
+ while (size--)
+ aopPut(AOP(result),zero,offset++);
+ } else {
+ /* we need to extend the sign :{ */
+ char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,
+ FALSE,FALSE);
+ MOVA(l);
+ emitcode("rlc","a");
+ emitcode("subb","a,acc");
+ while (size--)
+ aopPut(AOP(result),"a",offset++);
+ }
+
+ /* we are done hurray !!!! */
+
+release:
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDjnz - generate decrement & jump if not zero instrucion */
+/*-----------------------------------------------------------------*/
+static int genDjnz (iCode *ic, iCode *ifx)
+{
+ symbol *lbl, *lbl1;
+ if (!ifx)
+ return 0;
+
+ /* if the if condition has a false label
+ then we cannot save */
+ if (IC_FALSE(ifx))
+ return 0;
+
+ /* if the minus is not of the form
+ a = a - 1 */
+ if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
+ !IS_OP_LITERAL(IC_RIGHT(ic)))
+ return 0;
+
+ if (operandLitValue(IC_RIGHT(ic)) != 1)
+ return 0;
+
+ /* if the size of this greater than one then no
+ saving */
+ if (getSize(operandType(IC_RESULT(ic))) > 1)
+ return 0;
+
+ /* otherwise we can save BIG */
+ lbl = newiTempLabel(NULL);
+ lbl1= newiTempLabel(NULL);
+
+ aopOp(IC_RESULT(ic),ic,FALSE);
+
+ if (IS_AOP_PREG(IC_RESULT(ic))) {
+ emitcode("dec","%s",
+ aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ emitcode("jnz","%05d$",lbl->key+100);
+ } else {
+ emitcode ("djnz","%s,%05d$",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
+ lbl->key+100);
+ }
+ emitcode ("sjmp","%05d$",lbl1->key+100);
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("ljmp","%05d$",IC_TRUE(ifx)->key+100);
+ emitcode ("","%05d$:",lbl1->key+100);
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ ifx->generated = 1;
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genReceive - generate code for a receive iCode */
+/*-----------------------------------------------------------------*/
+static void genReceive (iCode *ic)
+{
+ if (isOperandInFarSpace(IC_RESULT(ic)) &&
+ ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
+ IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
+
+ int size = getSize(operandType(IC_RESULT(ic)));
+ int offset = 4 - size;
+ while (size--) {
+ emitcode ("push","%s", (strcmp(fReturn[3 - offset],"a") ?
+ fReturn[3 - offset] : "acc"));
+ offset++;
+ }
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_RESULT(ic));
+ offset = 0;
+ while (size--) {
+ emitcode ("pop","acc");
+ aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+ } else {
+ accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ accInUse--;
+ assignResultValue(IC_RESULT(ic));
+ }
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* gen51Code - generate code for 8051 based controllers */
+/*-----------------------------------------------------------------*/
+void gen51Code (iCode *lic)
+{
+ iCode *ic;
+ int cln = 0;
+
+ lineHead = lineCurr = NULL;
+
+ /* if debug information required */
+/* if (options.debug && currFunc) { */
+ if (currFunc) {
+ cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
+ debugLine = 1;
+ if (IS_STATIC(currFunc->etype))
+ emitcode("","F%s$%s$0$0 ==.",moduleName,currFunc->name);
+ else
+ emitcode("","G$%s$0$0 ==.",currFunc->name);
+ debugLine = 0;
+ }
+ /* stack pointer name */
+ if (options.useXstack)
+ spname = "_spx";
+ else
+ spname = "sp";
+
+
+ for (ic = lic ; ic ; ic = ic->next ) {
+
+ if ( cln != ic->lineno ) {
+ if ( options.debug ) {
+ debugLine = 1;
+ emitcode("","C$%s$%d$%d$%d ==.",
+ ic->filename,ic->lineno,
+ ic->level,ic->block);
+ debugLine = 0;
+ }
+ emitcode(";","%s %d",ic->filename,ic->lineno);
+ cln = ic->lineno ;
+ }
+ /* if the result is marked as
+ spilt and rematerializable or code for
+ this has already been generated then
+ do nothing */
+ if (resultRemat(ic) || ic->generated )
+ continue ;
+
+ /* depending on the operation */
+ switch (ic->op) {
+ case '!' :
+ genNot(ic);
+ break;
+
+ case '~' :
+ genCpl(ic);
+ break;
+
+ case UNARYMINUS:
+ genUminus (ic);
+ break;
+
+ case IPUSH:
+ genIpush (ic);
+ break;
+
+ case IPOP:
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
+ genIfx (ic->next,ic);
+ else
+ genIpop (ic);
+ break;
+
+ case CALL:
+ genCall (ic);
+ break;
+
+ case PCALL:
+ genPcall (ic);
+ break;
+
+ case FUNCTION:
+ genFunction (ic);
+ break;
+
+ case ENDFUNCTION:
+ genEndFunction (ic);
+ break;
+
+ case RETURN:
+ genRet (ic);
+ break;
+
+ case LABEL:
+ genLabel (ic);
+ break;
+
+ case GOTO:
+ genGoto (ic);
+ break;
+
+ case '+' :
+ genPlus (ic) ;
+ break;
+
+ case '-' :
+ if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
+ genMinus (ic);
+ break;
+
+ case '*' :
+ genMult (ic);
+ break;
+
+ case '/' :
+ genDiv (ic) ;
+ break;
+
+ case '%' :
+ genMod (ic);
+ break;
+
+ case '>' :
+ genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case '<' :
+ genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case LE_OP:
+ case GE_OP:
+ case NE_OP:
+
+ /* note these two are xlated by algebraic equivalence
+ during parsing SDCC.y */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "got '>=' or '<=' shouldn't have come here");
+ break;
+
+ case EQ_OP:
+ genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case AND_OP:
+ genAndOp (ic);
+ break;
+
+ case OR_OP:
+ genOrOp (ic);
+ break;
+
+ case '^' :
+ genXor (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case '|' :
+ genOr (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case BITWISEAND:
+ genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case INLINEASM:
+ genInline (ic);
+ break;
+
+ case RRC:
+ genRRC (ic);
+ break;
+
+ case RLC:
+ genRLC (ic);
+ break;
+
+ case GETHBIT:
+ genGetHbit (ic);
+ break;
+
+ case LEFT_OP:
+ genLeftShift (ic);
+ break;
+
+ case RIGHT_OP:
+ genRightShift (ic);
+ break;
+
+ case GET_VALUE_AT_ADDRESS:
+ genPointerGet(ic);
+ break;
+
+ case '=' :
+ if (POINTER_SET(ic))
+ genPointerSet(ic);
+ else
+ genAssign(ic);
+ break;
+
+ case IFX:
+ genIfx (ic,NULL);
+ break;
+
+ case ADDRESS_OF:
+ genAddrOf (ic);
+ break;
+
+ case JUMPTABLE:
+ genJumpTab (ic);
+ break;
+
+ case CAST:
+ genCast (ic);
+ break;
+
+ case RECEIVE:
+ genReceive(ic);
+ break;
+
+ case SEND:
+ addSet(&sendSet,ic);
+ break;
+
+ default :
+ ic = ic;
+ /* piCode(ic,stdout); */
+
+ }
+ }
+
+
+ /* now we are ready to call the
+ peep hole optimizer */
+ if (!options.nopeep)
+ peepHole (&lineHead);
+
+ /* now do the actual printing */
+ printLine (lineHead,codeOutFile);
+ return;
+}
--- /dev/null
+/*-------------------------------------------------------------------------
+ SDCCgen51.h - header file for code generation for 8051
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#ifndef SDCCGEN51_H
+#define SDCCGEN51_H
+
+enum {
+ AOP_LIT = 1,
+ AOP_REG, AOP_DIR,
+ AOP_DPTR,AOP_R0,AOP_R1,
+ AOP_STK ,AOP_IMMD, AOP_STR,
+ AOP_CRY, AOP_ACC };
+
+/* type asmop : a homogenised type for
+ all the different spaces an operand can be
+ in */
+typedef struct asmop {
+
+ short type ; /* can have values
+ AOP_LIT - operand is a literal value
+ AOP_REG - is in registers
+ AOP_DIR - direct just a name
+ AOP_DPTR - dptr contains address of operand
+ AOP_R0/R1 - r0/r1 contains address of operand
+ AOP_STK - should be pushed on stack this
+ can happen only for the result
+ AOP_IMMD - immediate value for eg. remateriazable
+ AOP_CRY - carry contains the value of this
+ AOP_STR - array of strings
+ AOP_ACC - result is in the acc:b pair
+ */
+ short coff ; /* current offset */
+ short size ; /* total size */
+ unsigned code :1 ; /* is in Code space */
+ unsigned paged:1 ; /* in paged memory */
+ unsigned freed:1 ; /* already freed */
+ union {
+ value *aop_lit ; /* if literal */
+ regs *aop_reg[4]; /* array of registers */
+ char *aop_dir ; /* if direct */
+ regs *aop_ptr ; /* either -> to r0 or r1 */
+ char *aop_immd; /* if immediate others are implied */
+ int aop_stk ; /* stack offset when AOP_STK */
+ char *aop_str[4]; /* just a string array containing the location */
+ } aopu;
+} asmop;
+
+void gen51Code (iCode *);
+
+
+#endif
--- /dev/null
+/*------------------------------------------------------------------------
+
+ SDCCralloc.c - source file for register allocation. (8051) specific
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "SDCCglobl.h"
+#include "SDCCast.h"
+#include "SDCCmem.h"
+#include "SDCCy.h"
+#include "SDCChasht.h"
+#include "SDCCbitv.h"
+#include "SDCCset.h"
+#include "SDCCicode.h"
+#include "SDCClabel.h"
+#include "SDCCBBlock.h"
+#include "SDCCloop.h"
+#include "SDCCcse.h"
+#include "SDCCcflow.h"
+#include "SDCCdflow.h"
+#include "SDCClrange.h"
+#include "SDCCralloc.h"
+
+/*-----------------------------------------------------------------*/
+/* At this point we start getting processor specific although */
+/* some routines are non-processor specific & can be reused when */
+/* targetting other processors. The decision for this will have */
+/* to be made on a routine by routine basis */
+/* routines used to pack registers are most definitely not reusable*/
+/* since the pack the registers depending strictly on the MCU */
+/*-----------------------------------------------------------------*/
+
+bitVect *spiltSet = NULL ;
+set *stackSpil = NULL;
+bitVect *regAssigned = NULL;
+short blockSpil = 0;
+int slocNum = 0 ;
+extern void gen51Code(iCode *);
+int ptrRegReq = 0; /* one byte pointer register required */
+bitVect *funcrUsed = NULL; /* registers used in a function */
+int stackExtend = 0;
+int dataExtend = 0;
+
+/* 8051 registers */
+regs regs8051[] =
+{
+
+ { REG_GPR ,R2_IDX , REG_GPR , "r2", "ar2", "0", 2, 1 },
+ { REG_GPR ,R3_IDX , REG_GPR , "r3", "ar3", "0", 3, 1 },
+ { REG_GPR ,R4_IDX , REG_GPR , "r4", "ar4", "0", 4, 1 },
+ { REG_GPR ,R5_IDX , REG_GPR , "r5", "ar5", "0", 5, 1 },
+ { REG_GPR ,R6_IDX , REG_GPR , "r6", "ar6", "0", 6, 1 },
+ { REG_GPR ,R7_IDX , REG_GPR , "r7", "ar7", "0", 7, 1 },
+ { REG_PTR ,R0_IDX , REG_PTR , "r0" , "ar0", "0", 0, 1 },
+ { REG_PTR ,R1_IDX , REG_PTR , "r1" , "ar1", "0", 1, 1 },
+ { REG_GPR ,X8_IDX , REG_GPR , "x8", "x8" , "xreg", 0, 1 },
+ { REG_GPR ,X9_IDX , REG_GPR , "x9", "x9" , "xreg", 1, 1 },
+ { REG_GPR ,X10_IDX,REG_GPR , "x10", "x10", "xreg", 2, 1 },
+ { REG_GPR ,X11_IDX,REG_GPR , "x11", "x11", "xreg", 3, 1 },
+ { REG_GPR ,X12_IDX,REG_GPR , "x12", "x12", "xreg", 4, 1 },
+ { REG_CND ,CND_IDX,REG_CND , "C" , "C" , "xreg", 0, 1 },
+};
+int nRegs = 13;
+void spillThis (symbol *);
+
+/*-----------------------------------------------------------------*/
+/* allocReg - allocates register of given type */
+/*-----------------------------------------------------------------*/
+regs *allocReg (short type)
+{
+ int i;
+
+ for ( i = 0 ; i < nRegs ; i++ ) {
+
+ /* if type is given as 0 then any
+ free register will do */
+ if (!type &&
+ regs8051[i].isFree ) {
+ regs8051[i].isFree = 0;
+ if (currFunc)
+ currFunc->regsUsed =
+ bitVectSetBit(currFunc->regsUsed,i);
+ return ®s8051[i];
+ }
+ /* other wise look for specific type
+ of register */
+ if (regs8051[i].isFree &&
+ regs8051[i].type == type) {
+ regs8051[i].isFree = 0;
+ if (currFunc)
+ currFunc->regsUsed =
+ bitVectSetBit(currFunc->regsUsed,i);
+ return ®s8051[i];
+ }
+ }
+ return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* regWithIdx - returns pointer to register wit index number */
+/*-----------------------------------------------------------------*/
+regs *regWithIdx (int idx)
+{
+ int i ;
+
+ for (i=0;i < nRegs;i++)
+ if (regs8051[i].rIdx == idx)
+ return ®s8051[i];
+
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "regWithIdx not found");
+ exit(1);
+}
+
+/*-----------------------------------------------------------------*/
+/* freeReg - frees a register */
+/*-----------------------------------------------------------------*/
+void freeReg (regs *reg)
+{
+ reg->isFree = 1;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* nFreeRegs - returns number of free registers */
+/*-----------------------------------------------------------------*/
+int nFreeRegs (int type)
+{
+ int i;
+ int nfr=0;
+
+ for (i = 0 ; i < nRegs; i++ )
+ if (regs8051[i].isFree && regs8051[i].type == type)
+ nfr++;
+ return nfr;
+}
+
+/*-----------------------------------------------------------------*/
+/* nfreeRegsType - free registers with type */
+/*-----------------------------------------------------------------*/
+int nfreeRegsType (int type)
+{
+ int nfr ;
+ if (type == REG_PTR) {
+ if ((nfr = nFreeRegs(type)) == 0)
+ return nFreeRegs(REG_GPR);
+ }
+
+ return nFreeRegs(type);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* allDefsOutOfRange - all definitions are out of a range */
+/*-----------------------------------------------------------------*/
+bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
+{
+ int i ;
+
+ if (!defs)
+ return TRUE ;
+
+ for ( i = 0 ;i < defs->size ; i++ ) {
+ iCode *ic;
+
+ if (bitVectBitValue(defs,i) &&
+ (ic = hTabItemWithKey(iCodehTab,i)) &&
+ ( ic->seq >= fseq && ic->seq <= toseq))
+
+ return FALSE;
+
+ }
+
+ return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* computeSpillable - given a point find the spillable live ranges */
+/*-----------------------------------------------------------------*/
+bitVect *computeSpillable (iCode *ic)
+{
+ bitVect *spillable ;
+
+ /* spillable live ranges are those that are live at this
+ point . the following categories need to be subtracted
+ from this set.
+ a) - those that are already spilt
+ b) - if being used by this one
+ c) - defined by this one */
+
+ spillable = bitVectCopy(ic->rlive);
+ spillable =
+ bitVectCplAnd(spillable,spiltSet); /* those already spilt */
+ spillable =
+ bitVectCplAnd(spillable,ic->uses); /* used in this one */
+ bitVectUnSetBit(spillable,ic->defKey);
+ spillable = bitVectIntersect(spillable,regAssigned);
+ return spillable;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* noSpilLoc - return true if a variable has no spil location */
+/*-----------------------------------------------------------------*/
+int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
+{
+ return (sym->usl.spillLoc ? 0 : 1);
+}
+
+/*-----------------------------------------------------------------*/
+/* hasSpilLoc - will return 1 if the symbol has spil location */
+/*-----------------------------------------------------------------*/
+int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return (sym->usl.spillLoc ? 1 : 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* directSpilLoc - will return 1 if the splilocation is in direct */
+/*-----------------------------------------------------------------*/
+int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ if ( sym->usl.spillLoc &&
+ (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
+ return 1;
+ else
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
+/* but is not used as a pointer */
+/*-----------------------------------------------------------------*/
+int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* rematable - will return 1 if the remat flag is set */
+/*-----------------------------------------------------------------*/
+int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return sym->remat;
+}
+
+/*-----------------------------------------------------------------*/
+/* notUsedInBlock - not used in this block */
+/*-----------------------------------------------------------------*/
+int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
+ allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
+/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
+}
+
+/*-----------------------------------------------------------------*/
+/* notUsedInRemaining - not used or defined in remain of the block */
+/*-----------------------------------------------------------------*/
+int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
+ allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
+}
+
+/*-----------------------------------------------------------------*/
+/* allLRs - return true for all */
+/*-----------------------------------------------------------------*/
+int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
+{
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* liveRangesWith - applies function to a given set of live range */
+/*-----------------------------------------------------------------*/
+set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
+ eBBlock *ebp, iCode *ic)
+{
+ set *rset = NULL;
+ int i;
+
+ if (!lrs || !lrs->size)
+ return NULL;
+
+ for ( i = 1 ; i < lrs->size ; i++ ) {
+ symbol *sym;
+ if (!bitVectBitValue(lrs,i))
+ continue ;
+
+ /* if we don't find it in the live range
+ hash table we are in serious trouble */
+ if (!(sym = hTabItemWithKey(liveRanges,i))) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "liveRangesWith could not find liveRange");
+ exit(1);
+ }
+
+ if (func(sym,ebp,ic) && bitVectBitValue(regAssigned,sym->key))
+ addSetHead(&rset,sym);
+ }
+
+ return rset;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* leastUsedLR - given a set determines which is the least used */
+/*-----------------------------------------------------------------*/
+symbol *leastUsedLR (set *sset)
+{
+ symbol *sym = NULL, *lsym = NULL ;
+
+ sym = lsym = setFirstItem(sset);
+
+ if (!lsym)
+ return NULL;
+
+ for (; lsym; lsym = setNextItem(sset)) {
+
+ /* if usage is the same then prefer
+ the spill the smaller of the two */
+ if ( lsym->used == sym->used )
+ if (getSize(lsym->type) < getSize(sym->type))
+ sym = lsym;
+
+ /* if less usage */
+ if (lsym->used < sym->used )
+ sym = lsym;
+
+ }
+
+ setToNull((void **)&sset);
+ sym->blockSpil = 0;
+ return sym;
+}
+
+/*-----------------------------------------------------------------*/
+/* noOverLap - will iterate through the list looking for over lap */
+/*-----------------------------------------------------------------*/
+int noOverLap (set *itmpStack, symbol *fsym)
+{
+ symbol *sym;
+
+
+ for (sym = setFirstItem(itmpStack); sym;
+ sym = setNextItem(itmpStack)) {
+ if (sym->liveTo > fsym->liveFrom )
+ return 0;
+
+ }
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* isFree - will return 1 if the a free spil location is found */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(isFree)
+{
+ symbol *sym = item;
+ V_ARG(symbol **,sloc);
+ V_ARG(symbol *,fsym);
+
+ /* if already found */
+ if (*sloc)
+ return 0;
+
+ /* if it is free && and the itmp assigned to
+ this does not have any overlapping live ranges
+ with the one currently being assigned and
+ the size can be accomodated */
+ if (sym->isFree &&
+ noOverLap(sym->usl.itmpStack,fsym) &&
+ getSize(sym->type) >= getSize(fsym->type)) {
+ *sloc = sym;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* spillLRWithPtrReg :- will spil those live ranges which use PTR */
+/*-----------------------------------------------------------------*/
+void spillLRWithPtrReg (symbol *forSym)
+{
+ symbol *lrsym;
+ regs *r0,*r1;
+ int k;
+
+ if (!regAssigned ||
+ bitVectIsZero(regAssigned))
+ return;
+
+ r0 = regWithIdx(R0_IDX);
+ r1 = regWithIdx(R1_IDX);
+
+ /* for all live ranges */
+ for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ;
+ lrsym = hTabNextItem(liveRanges,&k) ) {
+ int j;
+
+ /* if no registers assigned to it or
+ spilt */
+ /* if it does not overlap with this then
+ not need to spill it */
+
+ if (lrsym->isspilt || !lrsym->nRegs ||
+ (lrsym->liveTo < forSym->liveFrom))
+ continue ;
+
+ /* go thru the registers : if it is either
+ r0 or r1 then spil it */
+ for (j = 0 ; j < lrsym->nRegs ; j++ )
+ if (lrsym->regs[j] == r0 ||
+ lrsym->regs[j] == r1 ) {
+ spillThis (lrsym);
+ break;
+ }
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* createStackSpil - create a location on the stack to spil */
+/*-----------------------------------------------------------------*/
+symbol *createStackSpil (symbol *sym)
+{
+ symbol *sloc= NULL;
+ int useXstack, model, noOverlay;
+ int stackAuto;
+
+ /* first go try and find a free one that is already
+ existing on the stack */
+ if (applyToSet(stackSpil,isFree,&sloc, sym)) {
+ /* found a free one : just update & return */
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil= 1;
+ sloc->isFree = 0;
+ addSetHead(&sloc->usl.itmpStack,sym);
+ return sym;
+ }
+
+ /* could not then have to create one , this is the hard part
+ we need to allocate this on the stack : this is really a
+ hack!! but cannot think of anything better at this time */
+
+ sprintf(buffer,"sloc%d",slocNum++);
+ sloc = newiTemp(buffer);
+
+ /* set the type to the spilling symbol */
+ sloc->type = copyLinkChain(sym->type);
+ sloc->etype = getSpec(sloc->type);
+ SPEC_SCLS(sloc->etype) = S_AUTO ;
+ SPEC_EXTR(sloc->etype) = 0;
+
+ /* we don't allow it to be allocated`
+ onto the external stack since : so we
+ temporarily turn it off ; we also
+ turn off memory model to prevent
+ the spil from going to the external storage
+ and turn off overlaying
+ */
+
+ useXstack = options.useXstack;
+ model = options.model;
+ noOverlay = options.noOverlay;
+ stackAuto = options.stackAuto;
+ options.noOverlay = 1;
+ options.model = options.useXstack = 0;
+
+ allocLocal(sloc);
+
+ options.useXstack = useXstack;
+ options.model = model;
+ options.noOverlay = noOverlay;
+ options.stackAuto = stackAuto;
+ sloc->isref = 1; /* to prevent compiler warning */
+
+ /* if it is on the stack then update the stack */
+ if (IN_STACK(sloc->etype)) {
+ currFunc->stack += getSize(sloc->type);
+ stackExtend += getSize(sloc->type);
+ } else
+ dataExtend += getSize(sloc->type);
+
+ /* add it to the stackSpil set */
+ addSetHead(&stackSpil,sloc);
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil = 1;
+
+ /* add it to the set of itempStack set
+ of the spill location */
+ addSetHead(&sloc->usl.itmpStack,sym);
+ return sym;
+}
+
+/*-----------------------------------------------------------------*/
+/* isSpiltOnStack - returns true if the spil location is on stack */
+/*-----------------------------------------------------------------*/
+bool isSpiltOnStack (symbol *sym)
+{
+ link *etype;
+
+ if (!sym)
+ return FALSE ;
+
+ if (!sym->isspilt)
+ return FALSE ;
+
+/* if (sym->stackSpil) */
+/* return TRUE; */
+
+ if (!sym->usl.spillLoc)
+ return FALSE;
+
+ etype = getSpec(sym->usl.spillLoc->type);
+ if (IN_STACK(etype))
+ return TRUE;
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* spillThis - spils a specific operand */
+/*-----------------------------------------------------------------*/
+void spillThis (symbol *sym)
+{
+ int i;
+ /* if this is rematerializable or has a spillLocation
+ we are okay, else we need to create a spillLocation
+ for it */
+ if (!(sym->remat || sym->usl.spillLoc))
+ createStackSpil (sym);
+
+
+ /* mark it has spilt & put it in the spilt set */
+ sym->isspilt = 1;
+ spiltSet = bitVectSetBit(spiltSet,sym->key);
+
+ bitVectUnSetBit(regAssigned,sym->key);
+
+ for (i = 0 ; i < sym->nRegs ; i++)
+
+ if (sym->regs[i]) {
+ freeReg(sym->regs[i]);
+ sym->regs[i] = NULL;
+ }
+
+ /* if spilt on stack then free up r0 & r1
+ if they could have been assigned to some
+ LIVE ranges */
+ if (!ptrRegReq && isSpiltOnStack(sym)) {
+ ptrRegReq++ ;
+ spillLRWithPtrReg(sym);
+ }
+
+ if (sym->usl.spillLoc && !sym->remat)
+ sym->usl.spillLoc->allocreq = 1;
+ return;
+}
+
+/*-----------------------------------------------------------------*/
+/* selectSpil - select a iTemp to spil : rather a simple procedure */
+/*-----------------------------------------------------------------*/
+symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
+{
+ bitVect *lrcs= NULL ;
+ set *selectS ;
+ symbol *sym;
+
+ /* get the spillable live ranges */
+ lrcs = computeSpillable (ic);
+
+ /* get all live ranges that are rematerizable */
+ if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
+
+ /* return the least used of these */
+ return leastUsedLR(selectS);
+ }
+
+ /* get live ranges with spillLocations in direct space */
+ if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
+ sym = leastUsedLR(selectS);
+ strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ?
+ sym->usl.spillLoc->rname :
+ sym->usl.spillLoc->name));
+ sym->spildir = 1;
+ /* mark it as allocation required */
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* if the symbol is local to the block then */
+ if (forSym->liveTo < ebp->lSeq ) {
+
+ /* check if there are any live ranges allocated
+ to registers that are not used in this block */
+ if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
+ sym = leastUsedLR(selectS);
+ /* if this is not rematerializable */
+ if (!sym->remat) {
+ blockSpil++;
+ sym->blockSpil = 1;
+ }
+ return sym;
+ }
+
+ /* check if there are any live ranges that not
+ used in the remainder of the block */
+ if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
+ sym = leastUsedLR (selectS);
+ if (!sym->remat) {
+ sym->remainSpil = 1;
+ blockSpil++;
+ }
+ return sym;
+ }
+ }
+
+ /* find live ranges with spillocation && not used as pointers */
+ if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
+
+ sym = leastUsedLR(selectS);
+ /* mark this as allocation required */
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* find live ranges with spillocation */
+ if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
+
+ sym = leastUsedLR(selectS);
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* couldn't find then we need to create a spil
+ location on the stack , for which one? the least
+ used ofcourse */
+ if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
+
+ /* return a created spil location */
+ sym = createStackSpil(leastUsedLR(selectS));
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* this is an extreme situation we will spill
+ this one : happens very rarely but it does happen */
+ spillThis ( forSym );
+ return forSym ;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* spilSomething - spil some variable & mark registers as free */
+/*-----------------------------------------------------------------*/
+bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
+{
+ symbol *ssym;
+ int i ;
+
+ /* get something we can spil */
+ ssym = selectSpil(ic,ebp,forSym);
+
+ /* mark it as spilt */
+ ssym->isspilt = 1;
+ spiltSet = bitVectSetBit(spiltSet,ssym->key);
+
+ /* mark it as not register assigned &
+ take it away from the set */
+ bitVectUnSetBit(regAssigned,ssym->key);
+
+ /* mark the registers as free */
+ for (i = 0 ; i < ssym->nRegs ;i++ )
+ if (ssym->regs[i])
+ freeReg(ssym->regs[i]);
+
+ /* if spilt on stack then free up r0 & r1
+ if they could have been assigned to as gprs */
+ if (!ptrRegReq && isSpiltOnStack(ssym) ) {
+ ptrRegReq++ ;
+ spillLRWithPtrReg(ssym);
+ }
+
+ /* if this was a block level spil then insert push & pop
+ at the start & end of block respectively */
+ if (ssym->blockSpil) {
+ iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
+ /* add push to the start of the block */
+ addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ?
+ ebp->sch->next : ebp->sch));
+ nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock(ebp,nic,NULL);
+ }
+
+ /* if spilt because not used in the remainder of the
+ block then add a push before this instruction and
+ a pop at the end of the block */
+ if (ssym->remainSpil) {
+
+ iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
+ /* add push just before this instruction */
+ addiCodeToeBBlock(ebp,nic,ic);
+
+ nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock(ebp,nic,NULL);
+ }
+
+ if (ssym == forSym )
+ return FALSE ;
+ else
+ return TRUE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegPtr - will try for PTR if not a GPR type if not spil */
+/*-----------------------------------------------------------------*/
+regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
+{
+ regs *reg;
+
+ tryAgain:
+ /* try for a ptr type */
+ if ((reg = allocReg(REG_PTR)))
+ return reg;
+
+ /* try for gpr type */
+ if ((reg = allocReg(REG_GPR)))
+ return reg;
+
+ /* we have to spil */
+ if (!spilSomething (ic,ebp,sym))
+ return NULL ;
+
+ /* this looks like an infinite loop but
+ in really selectSpil will abort */
+ goto tryAgain ;
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegGpr - will try for GPR if not spil */
+/*-----------------------------------------------------------------*/
+regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
+{
+ regs *reg;
+
+ tryAgain:
+ /* try for gpr type */
+ if ((reg = allocReg(REG_GPR)))
+ return reg;
+
+ if (!ptrRegReq)
+ if ((reg = allocReg(REG_PTR)))
+ return reg ;
+
+ /* we have to spil */
+ if (!spilSomething (ic,ebp,sym))
+ return NULL ;
+
+ /* this looks like an infinite loop but
+ in really selectSpil will abort */
+ goto tryAgain ;
+}
+
+/*-----------------------------------------------------------------*/
+/* symHasReg - symbol has a given register */
+/*-----------------------------------------------------------------*/
+static bool symHasReg(symbol *sym,regs *reg)
+{
+ int i;
+
+ for ( i = 0 ; i < sym->nRegs ; i++)
+ if (sym->regs[i] == reg)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* deassignLRs - check the live to and if they have registers & are*/
+/* not spilt then free up the registers */
+/*-----------------------------------------------------------------*/
+void deassignLRs (iCode *ic, eBBlock *ebp)
+{
+ symbol *sym;
+ int k;
+ symbol *result;
+
+ for (sym = hTabFirstItem(liveRanges,&k); sym;
+ sym = hTabNextItem(liveRanges,&k)) {
+
+ symbol *psym= NULL;
+ /* if it does not end here */
+ if (sym->liveTo > ic->seq )
+ continue ;
+
+ /* if it was spilt on stack then we can
+ mark the stack spil location as free */
+ if (sym->isspilt ) {
+ if (sym->stackSpil) {
+ sym->usl.spillLoc->isFree = 1;
+ sym->stackSpil = 0;
+ }
+ continue ;
+ }
+
+ if (!bitVectBitValue(regAssigned,sym->key))
+ continue;
+
+ /* special case check if this is an IFX &
+ the privious one was a pop and the
+ previous one was not spilt then keep track
+ of the symbol */
+ if (ic->op == IFX && ic->prev &&
+ ic->prev->op == IPOP &&
+ !ic->prev->parmPush &&
+ !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt)
+ psym = OP_SYMBOL(IC_LEFT(ic->prev));
+
+ if (sym->nRegs) {
+ int i = 0;
+
+ bitVectUnSetBit(regAssigned,sym->key);
+
+ /* if the result of this one needs registers
+ and does not have it then assign it right
+ away */
+ if (IC_RESULT(ic) &&
+ ! (SKIP_IC2(ic) || /* not a special icode */
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == RETURN ||
+ POINTER_SET(ic)) &&
+ (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
+ result->liveTo > ic->seq && /* and will live beyond this */
+ result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->regType == sym->regType && /* same register types */
+ result->nRegs && /* which needs registers */
+ ! result->isspilt && /* and does not already have them */
+ ! result->remat &&
+ ! bitVectBitValue(regAssigned,result->key) &&
+ /* the number of free regs + number of regs in this LR
+ can accomodate the what result Needs */
+ ((nfreeRegsType(result->regType) +
+ sym->nRegs) >= result->nRegs)
+ ) {
+
+ for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
+ if (i < sym->nRegs )
+ result->regs[i] = sym->regs[i] ;
+ else
+ result->regs[i] = getRegGpr (ic,ebp,result);
+
+ regAssigned = bitVectSetBit(regAssigned,result->key);
+
+ }
+
+ /* free the remaining */
+ for (; i < sym->nRegs ; i++) {
+ if (psym) {
+ if (!symHasReg(psym,sym->regs[i]))
+ freeReg(sym->regs[i]);
+ } else
+ freeReg(sym->regs[i]);
+ }
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* reassignLR - reassign this to registers */
+/*-----------------------------------------------------------------*/
+void reassignLR (operand *op)
+{
+ symbol *sym = OP_SYMBOL(op);
+ int i;
+
+ /* not spilt any more */
+ sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
+ bitVectUnSetBit(spiltSet,sym->key);
+
+ regAssigned = bitVectSetBit(regAssigned,sym->key);
+
+ blockSpil--;
+
+ for (i=0;i<sym->nRegs;i++)
+ sym->regs[i]->isFree = 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* willCauseSpill - determines if allocating will cause a spill */
+/*-----------------------------------------------------------------*/
+int willCauseSpill ( int nr, int rt)
+{
+ /* first check if there are any avlb registers
+ of te type required */
+ if (rt == REG_PTR) {
+ /* special case for pointer type
+ if pointer type not avlb then
+ check for type gpr */
+ if (nFreeRegs(rt) >= nr)
+ return 0;
+ if (nFreeRegs(REG_GPR) >= nr)
+ return 0;
+ } else {
+ if (ptrRegReq) {
+ if (nFreeRegs(rt) >= nr)
+ return 0;
+ } else {
+ if (nFreeRegs(REG_PTR) +
+ nFreeRegs(REG_GPR) >= nr)
+ return 0;
+ }
+ }
+
+ /* it will cause a spil */
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* positionRegs - the allocator can allocate same registers to res-*/
+/* ult and operand, if this happens make sure they are in the same */
+/* position as the operand otherwise chaos results */
+/*-----------------------------------------------------------------*/
+static void positionRegs (symbol *result, symbol *opsym, int lineno)
+{
+ int count = min(result->nRegs,opsym->nRegs);
+ int i , j = 0, shared = 0;
+
+ /* if the result has been spilt then cannot share */
+ if (opsym->isspilt)
+ return ;
+ again:
+ shared = 0;
+ /* first make sure that they actually share */
+ for ( i = 0 ; i < count; i++ ) {
+ for (j = 0 ; j < count ; j++ ) {
+ if (result->regs[i] == opsym->regs[j] && i !=j) {
+ shared = 1;
+ goto xchgPositions;
+ }
+ }
+ }
+ xchgPositions:
+ if (shared) {
+ regs *tmp = result->regs[i];
+ result->regs[i] = result->regs[j];
+ result->regs[j] = tmp;
+ goto again;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* serialRegAssign - serially allocate registers to the variables */
+/*-----------------------------------------------------------------*/
+void serialRegAssign (eBBlock **ebbs, int count)
+{
+ int i;
+
+ /* for all blocks */
+ for (i = 0; i < count ; i++ ) {
+
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel ))
+ continue ;
+
+ /* of all instructions do */
+ for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
+
+ /* if this is an ipop that means some live
+ range will have to be assigned again */
+ if (ic->op == IPOP)
+ reassignLR (IC_LEFT(ic));
+
+ /* if result is present && is a true symbol */
+ if (IC_RESULT(ic) && ic->op != IFX &&
+ IS_TRUE_SYMOP(IC_RESULT(ic)))
+ OP_SYMBOL(IC_RESULT(ic))->allocreq = 1;
+
+ /* take away registers from live
+ ranges that end at this instruction */
+ deassignLRs (ic, ebbs[i]) ;
+
+ /* some don't need registers */
+ if (SKIP_IC2(ic) ||
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ (IC_RESULT(ic) &&POINTER_SET(ic)) )
+ continue;
+
+ /* now we need to allocate registers
+ only for the result */
+ if (IC_RESULT(ic)) {
+ symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+ bitVect *spillable;
+ int willCS ;
+ int j;
+ int ptrRegSet = 0;
+
+ /* if it does not need or is spilt
+ or is already assigned to registers
+ or will not live beyond this instructions */
+ if (!sym->nRegs ||
+ sym->isspilt ||
+ bitVectBitValue(regAssigned,sym->key) ||
+ sym->liveTo <= ic->seq)
+ continue ;
+
+ /* if some liverange has been spilt at the block level
+ and this one live beyond this block then spil this
+ to be safe */
+ if (blockSpil && sym->liveTo > ebbs[i]->lSeq) {
+ spillThis (sym);
+ continue ;
+ }
+ /* if trying to allocate this will cause
+ a spill and there is nothing to spill
+ or this one is rematerializable then
+ spill this one */
+ willCS = willCauseSpill(sym->nRegs,sym->regType);
+ spillable = computeSpillable(ic);
+ if ( sym->remat ||
+ (willCS && bitVectIsZero(spillable) ) ) {
+
+ spillThis (sym) ;
+ continue ;
+
+ }
+
+ /* if it has a spillocation & is used less than
+ all other live ranges then spill this */
+ if ( willCS && sym->usl.spillLoc ) {
+
+ symbol *leastUsed =
+ leastUsedLR(liveRangesWith (spillable ,
+ allLRs,
+ ebbs[i],
+ ic));
+ if (leastUsed &&
+ leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ }
+
+ /* if we need ptr regs for the right side
+ then mark it */
+ if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
+ ptrRegReq++;
+ ptrRegSet = 1;
+ }
+ /* else we assign registers to it */
+ regAssigned = bitVectSetBit(regAssigned,sym->key);
+
+ for (j = 0 ; j < sym->nRegs ;j++ ) {
+ if (sym->regType == REG_PTR)
+ sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
+ else
+ sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
+
+ /* if the allocation falied which means
+ this was spilt then break */
+ if (!sym->regs[j])
+ break;
+ }
+ /* if it shares registers with operands make sure
+ that they are in the same position */
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
+ OP_SYMBOL(IC_LEFT(ic))->nRegs && ic->op != '=')
+ positionRegs(OP_SYMBOL(IC_RESULT(ic)),
+ OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
+ /* do the same for the right operand */
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
+ OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
+ positionRegs(OP_SYMBOL(IC_RESULT(ic)),
+ OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
+
+ if (ptrRegSet) {
+ ptrRegReq--;
+ ptrRegSet = 0;
+ }
+
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* rUmaskForOp :- returns register mask for an operand */
+/*-----------------------------------------------------------------*/
+bitVect *rUmaskForOp (operand *op)
+{
+ bitVect *rumask;
+ symbol *sym;
+ int j;
+
+ /* only temporaries are assigned registers */
+ if (!IS_ITEMP(op))
+ return NULL;
+
+ sym = OP_SYMBOL(op);
+
+ /* if spilt or no registers assigned to it
+ then nothing */
+ if (sym->isspilt || !sym->nRegs)
+ return NULL;
+
+ rumask = newBitVect(nRegs);
+
+ for (j = 0; j < sym->nRegs; j++) {
+ rumask = bitVectSetBit(rumask,
+ sym->regs[j]->rIdx);
+ }
+
+ return rumask;
+}
+
+/*-----------------------------------------------------------------*/
+/* regsUsedIniCode :- returns bit vector of registers used in iCode*/
+/*-----------------------------------------------------------------*/
+bitVect *regsUsedIniCode (iCode *ic)
+{
+ bitVect *rmask = newBitVect(nRegs);
+
+ /* do the special cases first */
+ if (ic->op == IFX ) {
+ rmask = bitVectUnion(rmask,
+ rUmaskForOp(IC_COND(ic)));
+ goto ret;
+ }
+
+ /* for the jumptable */
+ if (ic->op == JUMPTABLE) {
+ rmask = bitVectUnion(rmask,
+ rUmaskForOp(IC_JTCOND(ic)));
+
+ goto ret;
+ }
+
+ /* of all other cases */
+ if (IC_LEFT(ic))
+ rmask = bitVectUnion(rmask,
+ rUmaskForOp(IC_LEFT(ic)));
+
+
+ if (IC_RIGHT(ic))
+ rmask = bitVectUnion(rmask,
+ rUmaskForOp(IC_RIGHT(ic)));
+
+ if (IC_RESULT(ic))
+ rmask = bitVectUnion(rmask,
+ rUmaskForOp(IC_RESULT(ic)));
+
+ ret:
+ return rmask;
+}
+
+/*-----------------------------------------------------------------*/
+/* createRegMask - for each instruction will determine the regsUsed*/
+/*-----------------------------------------------------------------*/
+void createRegMask (eBBlock **ebbs, int count)
+{
+ int i;
+
+ /* for all blocks */
+ for (i = 0; i < count ; i++ ) {
+ iCode *ic ;
+
+ if ( ebbs[i]->noPath &&
+ ( ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel ))
+ continue ;
+
+ /* for all instructions */
+ for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
+
+ int j;
+
+ if (SKIP_IC2(ic) || !ic->rlive)
+ continue ;
+
+ /* first mark the registers used in this
+ instruction */
+ ic->rUsed = regsUsedIniCode(ic);
+ funcrUsed = bitVectUnion(funcrUsed,ic->rUsed);
+
+ /* now create the register mask for those
+ registers that are in use : this is a
+ super set of ic->rUsed */
+ ic->rMask = newBitVect(nRegs+1);
+
+ /* for all live Ranges alive at this point */
+ for (j = 1; j < ic->rlive->size; j++ ) {
+ symbol *sym;
+ int k;
+
+ /* if not alive then continue */
+ if (!bitVectBitValue(ic->rlive,j))
+ continue ;
+
+ /* find the live range we are interested in */
+ if (!(sym = hTabItemWithKey(liveRanges,j))) {
+ werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "createRegMask cannot find live range");
+ exit(0);
+ }
+
+ /* if no register assigned to it */
+ if (!sym->nRegs || sym->isspilt)
+ continue ;
+
+ /* for all the registers allocated to it */
+ for (k = 0 ; k < sym->nRegs ;k++)
+ if (sym->regs[k])
+ ic->rMask =
+ bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var */
+/*-----------------------------------------------------------------*/
+char *rematStr (symbol *sym)
+{
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+
+ while (1) {
+
+ /* if plus or minus print the right hand side */
+ if (ic->op == '+' || ic->op == '-') {
+ sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
+ ic->op );
+ s += strlen(s);
+ ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ continue ;
+ }
+
+ /* we reached the end */
+ sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
+ break;
+ }
+
+ return buffer ;
+}
+
+/*-----------------------------------------------------------------*/
+/* regTypeNum - computes the type & number of registers required */
+/*-----------------------------------------------------------------*/
+void regTypeNum ()
+{
+ symbol *sym;
+ int k;
+ iCode *ic;
+
+ /* for each live range do */
+ for ( sym = hTabFirstItem(liveRanges,&k); sym ;
+ sym = hTabNextItem(liveRanges,&k)) {
+
+ /* if used zero times then no registers needed */
+ if ((sym->liveTo - sym->liveFrom) == 0)
+ continue ;
+
+
+ /* if the live range is a temporary */
+ if (sym->isitmp) {
+
+ /* if the type is marked as a conditional */
+ if (sym->regType == REG_CND)
+ continue ;
+
+ /* if used in return only then we don't
+ need registers */
+ if (sym->ruonly || sym->accuse) {
+ if (IS_AGGREGATE(sym->type) || sym->isptr)
+ sym->type = aggrToPtr(sym->type,FALSE);
+ continue ;
+ }
+
+ /* if the symbol has only one definition &
+ that definition is a get_pointer and the
+ pointer we are getting is rematerializable and
+ in "data" space */
+
+ if (bitVectnBitsOn(sym->defs) == 1 &&
+ (ic = hTabItemWithKey(iCodehTab,
+ bitVectFirstBit(sym->defs))) &&
+ POINTER_GET(ic) &&
+ !IS_BITVAR(sym->etype)) {
+
+
+ /* if remat in data space */
+ if (OP_SYMBOL(IC_LEFT(ic))->remat &&
+ DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
+
+ /* create a psuedo symbol & force a spil */
+ symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
+ psym->type = sym->type;
+ psym->etype = sym->etype;
+ strcpy(psym->rname,psym->name);
+ sym->isspilt = 1;
+ sym->usl.spillLoc = psym;
+ continue ;
+ }
+
+ /* if in data space or idata space then try to
+ allocate pointer register */
+
+ }
+
+ /* if not then we require registers */
+ sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
+ getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
+ getSize(sym->type));
+
+ if (sym->nRegs > 4) {
+ fprintf(stderr,"allocated more than 4 or 0 registers for type ");
+ printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
+ }
+
+ /* determine the type of register required */
+ if (sym->nRegs == 1 &&
+ IS_PTR(sym->type) &&
+ sym->uptr)
+ sym->regType = REG_PTR ;
+ else
+ sym->regType = REG_GPR ;
+
+ } else
+ /* for the first run we don't provide */
+ /* registers for true symbols we will */
+ /* see how things go */
+ sym->nRegs = 0 ;
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* freeAllRegs - mark all registers as free */
+/*-----------------------------------------------------------------*/
+void freeAllRegs()
+{
+ int i;
+
+ for (i=0;i< nRegs;i++ )
+ regs8051[i].isFree = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* deallocStackSpil - this will set the stack pointer back */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(deallocStackSpil)
+{
+ symbol *sym = item;
+
+ deallocLocal(sym);
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* farSpacePackable - returns the packable icode for far variables */
+/*-----------------------------------------------------------------*/
+static iCode *farSpacePackable (iCode *ic)
+{
+ iCode *dic ;
+
+ /* go thru till we find a definition for the
+ symbol on the right */
+ for ( dic = ic->prev ; dic ; dic = dic->prev) {
+
+ /* if the definition is a call then no */
+ if ((dic->op == CALL || dic->op == PCALL) &&
+ IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
+ return NULL;
+ }
+
+ /* if shift by unknown amount then not */
+ if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
+ IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
+ return NULL;
+
+ /* if pointer get and size > 1 */
+ if (POINTER_GET(dic) &&
+ getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
+ return NULL ;
+
+ if (POINTER_SET(dic) &&
+ getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
+ return NULL ;
+
+ /* if any three is a true symbol in far space */
+ if (IC_RESULT(dic) &&
+ IS_TRUE_SYMOP(IC_RESULT(dic)) &&
+ isOperandInFarSpace(IC_RESULT(dic)))
+ return NULL;
+
+ if (IC_RIGHT(dic) &&
+ IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
+ isOperandInFarSpace(IC_RIGHT(dic)) &&
+ !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
+ return NULL;
+
+ if (IC_LEFT(dic) &&
+ IS_TRUE_SYMOP(IC_LEFT(dic)) &&
+ isOperandInFarSpace(IC_LEFT(dic)) &&
+ !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
+ return NULL;
+
+ if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
+ if ( (dic->op == LEFT_OP ||
+ dic->op == RIGHT_OP ||
+ dic->op == '-') &&
+ IS_OP_LITERAL(IC_RIGHT(dic)))
+ return NULL;
+ else
+ return dic;
+ }
+ }
+
+ return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegsForAssign - register reduction for assignment */
+/*-----------------------------------------------------------------*/
+int packRegsForAssign (iCode *ic,eBBlock *ebp)
+{
+ iCode *dic, *sic;
+
+ if (
+/* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */
+ !IS_ITEMP(IC_RIGHT(ic)) ||
+ OP_LIVETO(IC_RIGHT(ic)) > ic->seq ||
+ OP_SYMBOL(IC_RIGHT(ic))->isind)
+ return 0;
+
+ /* if the true symbol is defined in far space or on stack
+ then we should not since this will increase register pressure */
+ if (isOperandInFarSpace(IC_RESULT(ic))) {
+ if ((dic = farSpacePackable(ic)))
+ goto pack;
+ else
+ return 0;
+
+ }
+ /* find the definition of iTempNN scanning backwards if we find a
+ a use of the true symbol in before we find the definition then
+ we cannot */
+ for ( dic = ic->prev ; dic ; dic = dic->prev) {
+
+ /* if there is a function call and this is
+ a parameter & not my parameter then don't pack it */
+ if ( (dic->op == CALL || dic->op == PCALL) &&
+ (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
+ !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
+ dic = NULL;
+ break;
+ }
+
+ if (SKIP_IC2(dic))
+ continue;
+
+ if (IS_SYMOP(IC_RESULT(dic)) &&
+ IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
+ if (POINTER_SET(dic))
+ dic = NULL;
+
+ break;
+ }
+
+ if (IS_SYMOP(IC_RIGHT(dic)) &&
+ (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
+ IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
+ dic = NULL;
+ break;
+ }
+
+ if (IS_SYMOP(IC_LEFT(dic)) &&
+ (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
+ IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
+ dic = NULL;
+ break;
+ }
+
+ if (POINTER_SET(dic) &&
+ IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
+ dic = NULL ;
+ break;
+ }
+ }
+
+ if (!dic)
+ return 0 ; /* did not find */
+
+ /* if the result is on stack or iaccess then it must be
+ the same atleast one of the operands */
+ if (OP_SYMBOL(IC_RESULT(ic))->onStack ||
+ OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
+
+ /* the operation has only one symbol
+ operator then we can pack */
+ if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
+ (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
+ goto pack;
+
+ if (!((IC_LEFT(dic) &&
+ IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
+ (IC_RIGHT(dic) &&
+ IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
+ return 0;
+ }
+pack:
+ /* found the definition */
+ /* replace the result with the result of */
+ /* this assignment and remove this assignment */
+ IC_RESULT(dic) = IC_RESULT(ic) ;
+
+ if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
+ OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
+ }
+ /* delete from liverange table also
+ delete from all the points inbetween and the new
+ one */
+ for ( sic = dic; sic != ic ; sic = sic->next ) {
+ bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
+ if (IS_ITEMP(IC_RESULT(dic)))
+ bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
+ }
+
+ remiCodeFromeBBlock(ebp,ic);
+ return 1;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* findAssignToSym : scanning backwards looks for first assig found*/
+/*-----------------------------------------------------------------*/
+iCode *findAssignToSym (operand *op,iCode *ic)
+{
+ iCode *dic;
+
+ for (dic = ic->prev ; dic ; dic = dic->prev) {
+
+ /* if definition by assignment */
+ if (dic->op == '=' &&
+ !POINTER_SET(dic) &&
+ IC_RESULT(dic)->key == op->key
+/* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
+ ) {
+
+ /* we are interested only if defined in far space */
+ /* or in stack space in case of + & - */
+
+ /* if assigned to a non-symbol then return
+ true */
+ if (!IS_SYMOP(IC_RIGHT(dic)))
+ break ;
+
+ /* if the symbol is in far space then
+ we should not */
+ if (isOperandInFarSpace(IC_RIGHT(dic)))
+ return NULL ;
+
+ /* for + & - operations make sure that
+ if it is on the stack it is the same
+ as one of the three operands */
+ if ((ic->op == '+' || ic->op == '-') &&
+ OP_SYMBOL(IC_RIGHT(dic))->onStack) {
+
+ if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
+ IC_LEFT(ic)->key != IC_RIGHT(dic)->key &&
+ IC_RIGHT(ic)->key != IC_RIGHT(dic)->key)
+ return NULL;
+ }
+
+ break ;
+
+ }
+
+ /* if we find an usage then we cannot delete it */
+ if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
+ return NULL;
+
+ if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
+ return NULL;
+
+ if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
+ return NULL;
+ }
+
+ /* now make sure that the right side of dic
+ is not defined between ic & dic */
+ if (dic) {
+ iCode *sic = dic->next ;
+
+ for (; sic != ic ; sic = sic->next)
+ if (IC_RESULT(sic) &&
+ IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
+ return NULL;
+ }
+
+ return dic;
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegsForSupport :- reduce some registers for support calls */
+/*-----------------------------------------------------------------*/
+int packRegsForSupport (iCode *ic, eBBlock *ebp)
+{
+ int change = 0 ;
+ /* for the left & right operand :- look to see if the
+ left was assigned a true symbol in far space in that
+ case replace them */
+ if (IS_ITEMP(IC_LEFT(ic)) &&
+ OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
+ iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
+ iCode *sic;
+
+ if (!dic)
+ goto right ;
+
+ /* found it we need to remove it from the
+ block */
+ for ( sic = dic; sic != ic ; sic = sic->next )
+ bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
+
+ IC_LEFT(ic)->operand.symOperand =
+ IC_RIGHT(dic)->operand.symOperand;
+ IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
+ remiCodeFromeBBlock(ebp,dic);
+ change++;
+ }
+
+ /* do the same for the right operand */
+ right:
+ if (!change &&
+ IS_ITEMP(IC_RIGHT(ic)) &&
+ OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
+ iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
+ iCode *sic;
+
+ if (!dic)
+ return change ;
+
+ /* if this is a subtraction & the result
+ is a true symbol in far space then don't pack */
+ if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
+ link *etype =getSpec(operandType(IC_RESULT(dic)));
+ if (IN_FARSPACE(SPEC_OCLS(etype)))
+ return change ;
+ }
+ /* found it we need to remove it from the
+ block */
+ for ( sic = dic; sic != ic ; sic = sic->next )
+ bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
+
+ IC_RIGHT(ic)->operand.symOperand =
+ IC_RIGHT(dic)->operand.symOperand;
+ IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
+
+ remiCodeFromeBBlock(ebp,dic);
+ change ++;
+ }
+
+ return change ;
+}
+
+#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+
+
+/*-----------------------------------------------------------------*/
+/* packRegsForOneuse : - will reduce some registers for single Use */
+/*-----------------------------------------------------------------*/
+static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
+{
+ bitVect *uses ;
+ iCode *dic, *sic;
+
+ /* if returning a literal then do nothing */
+ if (!IS_SYMOP(op))
+ return NULL;
+
+ /* only upto 2 bytes since we cannot predict
+ the usage of b, & acc */
+ if (getSize(operandType(op)) > 2 &&
+ ic->op != RETURN &&
+ ic->op != SEND)
+ return NULL;
+
+ /* this routine will mark the a symbol as used in one
+ instruction use only && if the defintion is local
+ (ie. within the basic block) && has only one definition &&
+ that definiion is either a return value from a
+ function or does not contain any variables in
+ far space */
+ uses = bitVectCopy(OP_USES(op));
+ bitVectUnSetBit(uses,ic->key); /* take away this iCode */
+ if (!bitVectIsZero(uses)) /* has other uses */
+ return NULL ;
+
+ /* if it has only one defintion */
+ if (bitVectnBitsOn(OP_DEFS(op)) > 1)
+ return NULL ; /* has more than one definition */
+
+ /* get the that definition */
+ if (!(dic =
+ hTabItemWithKey(iCodehTab,
+ bitVectFirstBit(OP_DEFS(op)))))
+ return NULL ;
+
+ /* found the definition now check if it is local */
+ if (dic->seq < ebp->fSeq ||
+ dic->seq > ebp->lSeq)
+ return NULL ; /* non-local */
+
+ /* now check if it is the return from
+ a function call */
+ if (dic->op == CALL || dic->op == PCALL ) {
+ if (ic->op != SEND && ic->op != RETURN) {
+ OP_SYMBOL(op)->ruonly = 1;
+ return dic;
+ }
+ dic = dic->next ;
+ }
+
+
+ /* otherwise check that the definition does
+ not contain any symbols in far space */
+ if (isOperandInFarSpace(IC_LEFT(dic)) ||
+ isOperandInFarSpace(IC_RIGHT(dic)) ||
+ IS_OP_RUONLY(IC_LEFT(ic)) ||
+ IS_OP_RUONLY(IC_RIGHT(ic)) ) {
+ return NULL;
+ }
+
+ /* if pointer set then make sure the pointer
+ is one byte */
+ if (POINTER_SET(dic) &&
+ !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
+ return NULL ;
+
+ if (POINTER_GET(dic) &&
+ !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
+ return NULL ;
+
+ sic = dic;
+
+ /* also make sure the intervenening instructions
+ don't have any thing in far space */
+ for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
+
+ /* if there is an intervening function call then no */
+ if (dic->op == CALL || dic->op == PCALL)
+ return NULL;
+ /* if pointer set then make sure the pointer
+ is one byte */
+ if (POINTER_SET(dic) &&
+ !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
+ return NULL ;
+
+ if (POINTER_GET(dic) &&
+ !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
+ return NULL ;
+
+ /* if address of & the result is remat the okay */
+ if (dic->op == ADDRESS_OF &&
+ OP_SYMBOL(IC_RESULT(dic))->remat)
+ continue ;
+
+ /* if operand has size of three or more & this
+ operation is a '*','/' or '%' then 'b' may
+ cause a problem */
+ if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
+ getSize(aggrToPtr(operandType(op),FALSE)) >= 3)
+ return NULL;
+
+ /* if left or right or result is in far space */
+ if (isOperandInFarSpace(IC_LEFT(dic)) ||
+ isOperandInFarSpace(IC_RIGHT(dic)) ||
+ isOperandInFarSpace(IC_RESULT(dic)) ||
+ IS_OP_RUONLY(IC_LEFT(dic)) ||
+ IS_OP_RUONLY(IC_RIGHT(dic)) ||
+ IS_OP_RUONLY(IC_RESULT(dic)) ) {
+ return NULL;
+ }
+ }
+
+ OP_SYMBOL(op)->ruonly = 1;
+ return sic;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
+/*-----------------------------------------------------------------*/
+static bool isBitwiseOptimizable (iCode *ic)
+{
+ link *ltype = getSpec(operandType(IC_LEFT(ic)));
+ link *rtype = getSpec(operandType(IC_RIGHT(ic)));
+
+ /* bitwise operations are considered optimizable
+ under the following conditions (Jean-Louis VERN)
+
+ x & lit
+ bit & bit
+ bit & x
+ bit ^ bit
+ bit ^ x
+ x ^ lit
+ x | lit
+ bit | bit
+ bit | x
+ */
+ if ( IS_LITERAL(rtype) ||
+ (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
+ return TRUE ;
+ else
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegsForAccUse - pack registers for acc use */
+/*-----------------------------------------------------------------*/
+void packRegsForAccUse (iCode *ic)
+{
+ iCode *uic;
+
+ /* if + or - then it has to be one byte result */
+ if ((ic->op == '+' || ic->op == '-')
+ && getSize(operandType(IC_RESULT(ic))) > 1)
+ return ;
+
+ /* if shift operation make sure right side is not a literal */
+ if (ic->op == RIGHT_OP &&
+ ( isOperandLiteral(IC_RIGHT(ic)) ||
+ getSize(operandType(IC_RESULT(ic))) > 1))
+ return ;
+
+ if (ic->op == LEFT_OP &&
+ ( isOperandLiteral(IC_RIGHT(ic)) ||
+ getSize(operandType(IC_RESULT(ic))) > 1))
+ return ;
+
+
+ /* has only one definition */
+ if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
+ return ;
+
+ /* has only one use */
+ if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
+ return ;
+
+ /* and the usage immediately follows this iCode */
+ if (!(uic = hTabItemWithKey(iCodehTab,
+ bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
+ return ;
+
+ if (ic->next != uic)
+ return ;
+
+ /* if it is a conditional branch then we definitely can */
+ if (uic->op == IFX )
+ goto accuse;
+
+ if ( uic->op == JUMPTABLE )
+ return ;
+
+ /* if the usage is not is an assignment
+ or an arithmetic / bitwise / shift operation then not */
+ if (POINTER_SET(uic) &&
+ getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
+ return;
+
+ if (uic->op != '=' &&
+ !IS_ARITHMETIC_OP(uic) &&
+ !IS_BITWISE_OP(uic) &&
+ uic->op != LEFT_OP &&
+ uic->op != RIGHT_OP )
+ return;
+
+ /* if used in ^ operation then make sure right is not a
+ literl */
+ if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
+ return ;
+
+ /* if shift operation make sure right side is not a literal */
+ if (uic->op == RIGHT_OP &&
+ ( isOperandLiteral(IC_RIGHT(uic)) ||
+ getSize(operandType(IC_RESULT(uic))) > 1))
+ return ;
+
+ if (uic->op == LEFT_OP &&
+ ( isOperandLiteral(IC_RIGHT(uic)) ||
+ getSize(operandType(IC_RESULT(uic))) > 1))
+ return ;
+
+ /* make sure that the result of this icode is not on the
+ stack, since acc is used to compute stack offset */
+ if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
+ OP_SYMBOL(IC_RESULT(uic))->onStack)
+ return ;
+
+ /* if either one of them in far space then we cannot */
+ if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
+ isOperandInFarSpace(IC_LEFT(uic))) ||
+ (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
+ isOperandInFarSpace(IC_RIGHT(uic))))
+ return ;
+
+ /* if the usage has only one operand then we can */
+ if (IC_LEFT(uic) == NULL ||
+ IC_RIGHT(uic) == NULL)
+ goto accuse;
+
+ /* make sure this is on the left side if not
+ a '+' since '+' is commutative */
+ if (ic->op != '+' &&
+ IC_LEFT(uic)->key != IC_RESULT(ic)->key)
+ return;
+
+ /* if one of them is a literal then we can */
+ if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
+ (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
+ OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+ return ;
+ }
+
+ /* if the other one is not on stack then we can */
+ if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
+ (IS_ITEMP(IC_RIGHT(uic)) ||
+ (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
+ !OP_SYMBOL(IC_RIGHT(uic))->onStack)))
+ goto accuse;
+
+ if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
+ (IS_ITEMP(IC_LEFT(uic)) ||
+ (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
+ !OP_SYMBOL(IC_LEFT(uic))->onStack)))
+ goto accuse ;
+
+ return ;
+
+ accuse:
+ OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* packForPush - hueristics to reduce iCode for pushing */
+/*-----------------------------------------------------------------*/
+static void packForPush(iCode *ic, eBBlock *ebp)
+{
+ iCode *dic;
+
+ if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
+ return ;
+
+ /* must have only definition & one usage */
+ if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
+ bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )
+ return ;
+
+ /* find the definition */
+ if (!(dic = hTabItemWithKey(iCodehTab,
+ bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
+ return ;
+
+ if (dic->op != '=' || POINTER_SET(dic))
+ return;
+
+ /* we now we know that it has one & only one def & use
+ and the that the definition is an assignment */
+ IC_LEFT(ic) = IC_RIGHT(dic);
+
+ remiCodeFromeBBlock(ebp,dic);
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegisters - does some transformations to reduce register */
+/* pressure */
+/*-----------------------------------------------------------------*/
+static void packRegisters (eBBlock *ebp)
+{
+ iCode *ic ;
+ int change = 0 ;
+
+ while (1) {
+
+ change = 0;
+
+ /* look for assignments of the form */
+ /* iTempNN = TRueSym (someoperation) SomeOperand */
+ /* .... */
+ /* TrueSym := iTempNN:1 */
+ for ( ic = ebp->sch ; ic ; ic = ic->next ) {
+
+
+ /* find assignment of the form TrueSym := iTempNN:1 */
+ if (ic->op == '=' && !POINTER_SET(ic))
+ change += packRegsForAssign(ic,ebp);
+ }
+
+ if (!change)
+ break;
+ }
+
+ for ( ic = ebp->sch ; ic ; ic = ic->next ) {
+
+ /* if this is an itemp & result of a address of a true sym
+ then mark this as rematerialisable */
+ if (ic->op == ADDRESS_OF &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+ IS_TRUE_SYMOP(IC_LEFT(ic)) &&
+ bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
+ !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
+
+ OP_SYMBOL(IC_RESULT(ic))->remat = 1;
+ OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
+ OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
+
+ }
+
+ /* if straight assignment then carry remat flag if
+ this is the only definition */
+ if (ic->op == '=' &&
+ !POINTER_SET(ic) &&
+ IS_SYMOP(IC_RIGHT(ic)) &&
+ OP_SYMBOL(IC_RIGHT(ic))->remat &&
+ bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
+
+ OP_SYMBOL(IC_RESULT(ic))->remat =
+ OP_SYMBOL(IC_RIGHT(ic))->remat;
+ OP_SYMBOL(IC_RESULT(ic))->rematiCode =
+ OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
+ }
+
+ /* if this is a +/- operation with a rematerizable
+ then mark this as rematerializable as well only
+ if the literal value is within the range -255 and + 255
+ the assembler cannot handle it other wise */
+ if ((ic->op == '+' || ic->op == '-') &&
+
+ (IS_SYMOP(IC_LEFT(ic)) &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+ OP_SYMBOL(IC_LEFT(ic))->remat &&
+ bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
+ IS_OP_LITERAL(IC_RIGHT(ic))) ) {
+
+ int i = operandLitValue(IC_RIGHT(ic));
+ if ( i < 255 && i > -255) {
+ OP_SYMBOL(IC_RESULT(ic))->remat = 1;
+ OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
+ OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
+ }
+ }
+
+ /* mark the pointer usages */
+ if (POINTER_SET(ic))
+ OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
+
+ if (POINTER_GET(ic))
+ OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
+
+ if (!SKIP_IC2(ic)) {
+ /* if we are using a symbol on the stack
+ then we should say ptrRegReq */
+ if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
+ ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
+ OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
+ else
+ if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
+ ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
+ OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
+ else {
+ if (IS_SYMOP(IC_LEFT(ic)))
+ ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
+ OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP(IC_RIGHT(ic)))
+ ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
+ OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP(IC_RESULT(ic)))
+ ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
+ OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);
+ }
+ }
+
+ /* if the condition of an if instruction
+ is defined in the previous instruction then
+ mark the itemp as a conditional */
+ if ((IS_CONDITIONAL(ic) ||
+ ( ( ic->op == BITWISEAND ||
+ ic->op == '|' ||
+ ic->op == '^' ) &&
+ isBitwiseOptimizable(ic))) &&
+ ic->next && ic->next->op == IFX &&
+ isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
+ OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
+
+ OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;
+ continue ;
+ }
+
+ /* reduce for support function calls */
+ if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
+ packRegsForSupport (ic,ebp);
+
+ /* some cases the redundant moves can
+ can be eliminated for return statements */
+ if ((ic->op == RETURN || ic->op == SEND) &&
+ !isOperandInFarSpace(IC_LEFT(ic)) &&
+ !options.model)
+ packRegsForOneuse (ic,IC_LEFT(ic),ebp);
+
+ /* if pointer set & left has a size more than
+ one and right is not in far space */
+ if (POINTER_SET(ic) &&
+ !isOperandInFarSpace(IC_RIGHT(ic)) &&
+ !OP_SYMBOL(IC_RESULT(ic))->remat &&
+ !IS_OP_RUONLY(IC_RIGHT(ic)) &&
+ getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
+
+ packRegsForOneuse (ic,IC_RESULT(ic),ebp);
+
+ /* if pointer get */
+ if (POINTER_GET(ic) &&
+ !isOperandInFarSpace(IC_RESULT(ic))&&
+ !OP_SYMBOL(IC_LEFT(ic))->remat &&
+ !IS_OP_RUONLY(IC_RESULT(ic)) &&
+ getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
+
+ packRegsForOneuse (ic,IC_LEFT(ic),ebp);
+
+
+ /* if this is cast for intergral promotion then
+ check if only use of the definition of the
+ operand being casted/ if yes then replace
+ the result of that arithmetic operation with
+ this result and get rid of the cast */
+ if (ic->op == CAST) {
+ link *fromType = operandType(IC_RIGHT(ic));
+ link *toType = operandType(IC_LEFT(ic));
+
+ if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
+ getSize(fromType) != getSize(toType) ) {
+
+ iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
+ if (dic) {
+ if (IS_ARITHMETIC_OP(dic)) {
+ IC_RESULT(dic) = IC_RESULT(ic);
+ remiCodeFromeBBlock(ebp,ic);
+ ic = ic->prev;
+ } else
+ OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0;
+ }
+ } else {
+
+ /* if the type from and type to are the same
+ then if this is the only use then packit */
+ if (checkType(operandType(IC_RIGHT(ic)),
+ operandType(IC_LEFT(ic))) == 1) {
+ iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
+ if (dic) {
+ IC_RESULT(dic) = IC_RESULT(ic);
+ remiCodeFromeBBlock(ebp,ic);
+ ic = ic->prev;
+ }
+ }
+ }
+ }
+
+ /* pack for PUSH
+ iTempNN := (some variable in farspace) V1
+ push iTempNN ;
+ -------------
+ push V1
+ */
+ if (ic->op == IPUSH ) {
+ packForPush(ic,ebp);
+ }
+
+
+ /* pack registers for accumulator use, when the
+ result of an arithmetic or bit wise operation
+ has only one use, that use is immediately following
+ the defintion and the using iCode has only one
+ operand or has two operands but one is literal &
+ the result of that operation is not on stack then
+ we can leave the result of this operation in acc:b
+ combination */
+ if ((IS_ARITHMETIC_OP(ic)
+
+ || IS_BITWISE_OP(ic)
+
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
+
+ ) &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+ getSize(operandType(IC_RESULT(ic))) <= 2)
+
+ packRegsForAccUse (ic);
+
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* assignRegisters - assigns registers to each live range as need */
+/*-----------------------------------------------------------------*/
+void assignRegisters (eBBlock **ebbs, int count)
+{
+ iCode *ic;
+ int i ;
+
+ setToNull((void *)&funcrUsed);
+ ptrRegReq = stackExtend = dataExtend = 0;
+ /* if not register extentions then reduce number
+ of registers */
+ if (options.regExtend)
+ nRegs = 13;
+ else
+ nRegs = 8;
+
+ /* change assignments this will remove some
+ live ranges reducing some register pressure */
+ for (i = 0 ; i < count ;i++ )
+ packRegisters (ebbs[i]);
+
+ if (options.dump_pack)
+ dumpEbbsToFileExt(".dumppack",ebbs,count);
+
+ /* first determine for each live range the number of
+ registers & the type of registers required for each */
+ regTypeNum ();
+
+ /* and serially allocate registers */
+ serialRegAssign(ebbs,count);
+
+ /* if stack was extended then tell the user */
+ if (stackExtend) {
+/* werror(W_TOOMANY_SPILS,"stack", */
+/* stackExtend,currFunc->name,""); */
+ stackExtend = 0 ;
+ }
+
+ if (dataExtend) {
+/* werror(W_TOOMANY_SPILS,"data space", */
+/* dataExtend,currFunc->name,""); */
+ dataExtend = 0 ;
+ }
+
+ /* after that create the register mask
+ for each of the instruction */
+ createRegMask (ebbs,count);
+
+ /* redo that offsets for stacked automatic variables */
+ redoStackOffsets ();
+
+ if (options.dump_rassgn)
+ dumpEbbsToFileExt(".dumprassgn",ebbs,count);
+
+ /* now get back the chain */
+ ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
+
+
+ gen51Code(ic);
+
+ /* free up any stackSpil locations allocated */
+ applyToSet(stackSpil,deallocStackSpil);
+ slocNum = 0;
+ setToNull((void **)&stackSpil);
+ setToNull((void **)&spiltSet);
+ /* mark all registers as free */
+ freeAllRegs();
+
+ return ;
+}
--- /dev/null
+/*-------------------------------------------------------------------------
+
+ SDCCralloc.h - header file register allocation
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+#include "SDCCicode.h"
+#include "SDCCBBlock.h"
+#ifndef SDCCRALLOC_H
+#define SDCCRALLOC_H 1
+
+enum { R2_IDX = 0, R3_IDX , R4_IDX ,
+ R5_IDX ,R6_IDX , R7_IDX ,
+ R0_IDX ,R1_IDX , X8_IDX ,
+ X9_IDX ,X10_IDX , X11_IDX ,
+ X12_IDX ,CND_IDX };
+
+
+#define REG_PTR 0x01
+#define REG_GPR 0x02
+#define REG_CND 0x04
+/* definition for the registers */
+typedef struct regs
+{
+ short type; /* can have value
+ REG_GPR, REG_PTR or REG_CND */
+ short rIdx ; /* index into register table */
+ short otype;
+ char *name ; /* name */
+ char *dname; /* name when direct access needed */
+ char *base ; /* base address */
+ short offset; /* offset from the base */
+ unsigned isFree :1; /* is currently unassigned */
+} regs;
+extern regs regs8051[];
+
+void assignRegisters (eBBlock **, int );
+regs *regWithIdx (int);
+
+#endif
+++ /dev/null
-cppalloc.o: cppalloc.c config.h i386/i386.h i386/xm-linux.h
-cpperror.o: cpperror.c cpplib.h
-cppexp.o: cppexp.c config.h i386/i386.h i386/xm-linux.h cpplib.h
-cpphash.o: cpphash.c cpplib.h cpphash.h
-cpplib.o: cpplib.c ../../sdccconf.h config.h i386/i386.h \
- i386/xm-linux.h cpplib.h cpphash.h
-cppmain.o: cppmain.c cpplib.h
+++ /dev/null
-# Generated automatically from Makefile.in by configure.
-# Primary targets:
-# gc.a - builds basic library
-# libgc.a - builds library for use with g++ "-fgc-keyword" extension
-# c++ - adds C++ interface to library
-# cords - adds cords (heavyweight strings) to library
-# test - prints porting information, then builds basic version of gc.a,
-# and runs some tests of collector and cords. Does not add cords or
-# c++ interface to gc.a
-# cord/de - builds dumb editor based on cords.
-ABI_FLAG=
-CC = gcc $(ABI_FLAG)
-CXX = c++ $(ABI_FLAG)
-AS = as $(ABI_FLAG)
-PRJDIR = ../..
-srcdir = .
-# The above doesn't work with gas, which doesn't run cpp.
-# Define AS as `gcc -c -x assembler-with-cpp' instead.
-# Under Irix 6, you will have to specify the ABI for as if you specify
-# it for the C compiler.
-
-CFLAGS= -O2 -DATOMIC_UNCOLLECTABLE -DNO_SIGNALS -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION -DSILENT -I /usr/local/include
-
-# For dynamic library builds, it may be necessary to add flags to generate
-# PIC code, e.g. -fPIC on Linux.
-
-# Setjmp_test may yield overly optimistic results when compiled
-# without optimization.
-# -DSILENT disables statistics printing, and improves performance.
-# -DCHECKSUMS reports on erroneously clear dirty bits, and unexpectedly
-# altered stubborn objects, at substantial performance cost.
-# Use only for incremental collector debugging.
-# -DFIND_LEAK causes the collector to assume that all inaccessible
-# objects should have been explicitly deallocated, and reports exceptions.
-# Finalization and the test program are not usable in this mode.
-# -DSOLARIS_THREADS enables support for Solaris (thr_) threads.
-# (Clients should also define SOLARIS_THREADS and then include
-# gc.h before performing thr_ or dl* or GC_ operations.)
-# Must also define -D_REENTRANT.
-# -D_SOLARIS_PTHREADS enables support for Solaris pthreads.
-# Define SOLARIS_THREADS as well.
-# -DIRIX_THREADS enables support for Irix pthreads. See README.irix.
-# _DLINUX_THREADS enables support for Xavier Leroy's Linux threads.
-# see README.linux. -D_REENTRANT may also be required.
-# -DALL_INTERIOR_POINTERS allows all pointers to the interior
-# of objects to be recognized. (See gc_priv.h for consequences.)
-# -DSMALL_CONFIG tries to tune the collector for small heap sizes,
-# usually causing it to use less space in such situations.
-# Incremental collection no longer works in this case.
-# -DLARGE_CONFIG tunes the collector for unusually large heaps.
-# Necessary for heaps larger than about 500 MB on most machines.
-# Recommended for heaps larger than about 64 MB.
-# -DDONT_ADD_BYTE_AT_END is meaningful only with
-# -DALL_INTERIOR_POINTERS. Normally -DALL_INTERIOR_POINTERS
-# causes all objects to be padded so that pointers just past the end of
-# an object can be recognized. This can be expensive. (The padding
-# is normally more than one byte due to alignment constraints.)
-# -DDONT_ADD_BYTE_AT_END disables the padding.
-# -DNO_SIGNALS does not disable signals during critical parts of
-# the GC process. This is no less correct than many malloc
-# implementations, and it sometimes has a significant performance
-# impact. However, it is dangerous for many not-quite-ANSI C
-# programs that call things like printf in asynchronous signal handlers.
-# -DNO_EXECUTE_PERMISSION may cause some or all of the heap to not
-# have execute permission, i.e. it may be impossible to execute
-# code from the heap. Currently this only affects the incremental
-# collector on UNIX machines. It may greatly improve its performance,
-# since this may avoid some expensive cache synchronization.
-# -DOPERATOR_NEW_ARRAY declares that the C++ compiler supports the
-# new syntax "operator new[]" for allocating and deleting arrays.
-# See gc_cpp.h for details. No effect on the C part of the collector.
-# This is defined implicitly in a few environments.
-# -DREDIRECT_MALLOC=X causes malloc, realloc, and free to be defined
-# as aliases for X, GC_realloc, and GC_free, respectively.
-# Calloc is redefined in terms of the new malloc. X should
-# be either GC_malloc or GC_malloc_uncollectable.
-# The former is occasionally useful for working around leaks in code
-# you don't want to (or can't) look at. It may not work for
-# existing code, but it often does. Neither works on all platforms,
-# since some ports use malloc or calloc to obtain system memory.
-# (Probably works for UNIX, and win32.)
-# -DIGNORE_FREE turns calls to free into a noop. Only useful with
-# -DREDIRECT_MALLOC.
-# -DNO_DEBUGGING removes GC_dump and the debugging routines it calls.
-# Reduces code size slightly at the expense of debuggability.
-# -DJAVA_FINALIZATION makes it somewhat safer to finalize objects out of
-# order by specifying a nonstandard finalization mark procedure (see
-# finalize.c). Objects reachable from finalizable objects will be marked
-# in a sepearte postpass, and hence their memory won't be reclaimed.
-# Not recommended unless you are implementing a language that specifies
-# these semantics.
-# -DFINALIZE_ON_DEMAND causes finalizers to be run only in response
-# to explicit GC_invoke_finalizers() calls.
-# -DATOMIC_UNCOLLECTABLE includes code for GC_malloc_atomic_uncollectable.
-# This is useful if either the vendor malloc implementation is poor,
-# or if REDIRECT_MALLOC is used.
-# -DHBLKSIZE=ddd, where ddd is a power of 2 between 512 and 16384, explicitly
-# sets the heap block size. Each heap block is devoted to a single size and
-# kind of object. For the incremental collector it makes sense to match
-# the most likely page size. Otherwise large values result in more
-# fragmentation, but generally better performance for large heaps.
-# -DUSE_MMAP use MMAP instead of sbrk to get new memory.
-# Works for Solaris and Irix.
-# -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than
-# GC_scratch_alloc() to get stack memory.
-# -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever
-# the garbage collector detects a value that looks almost, but not quite,
-# like a pointer, print both the address containing the value, and the
-# value of the near-bogus-pointer. Can be used to identifiy regions of
-# memory that are likely to contribute misidentified pointers.
-# -DOLD_BLOCK_ALLOC Use the old, possibly faster, large block
-# allocation strategy. The new strategy tries harder to minimize
-# fragmentation, sometimes at the expense of spending more time in the
-# large block allocator and/or collecting more frequently.
-# If you expect the allocator to promtly use an explicitly expanded
-# heap, this is highly recommended.
-#
-
-
-
-LIBGC_CFLAGS= -O -DNO_SIGNALS -DSILENT \
- -DREDIRECT_MALLOC=GC_malloc_uncollectable \
- -DDONT_ADD_BYTE_AT_END -DALL_INTERIOR_POINTERS
-# Flags for building libgc.a -- the last two are required.
-
-CXXFLAGS= $(CFLAGS)
-AR= ar
-RANLIB= ranlib
-
-
-# Redefining srcdir allows object code for the nonPCR version of the collector
-# to be generated in different directories. In this case, the destination directory
-# should contain a copy of the original include directory.
-srcdir = .
-
-OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o
-
-CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c
-
-CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c cord/cord.h cord/ec.h cord/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC cord/SCOPTIONS.amiga cord/SMakefile.amiga
-
-CORD_OBJS= cord/cordbscs.o cord/cordxtra.o cord/cordprnt.o
-
-SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
- sparc_mach_dep.s gc.h gc_typed.h gc_hdrs.h gc_priv.h gc_private.h \
- gcconfig.h gc_mark.h include/gc_inl.h include/gc_inline.h gc.man \
- threadlibs.c if_mach.c if_not_there.c gc_cpp.cc gc_cpp.h weakpointer.h \
- gcc_support.c mips_ultrix_mach_dep.s include/gc_alloc.h gc_alloc.h \
- include/new_gc_alloc.h include/javaxfc.h sparc_sunos4_mach_dep.s \
- solaris_threads.h $(CORD_SRCS)
-
-OTHER_FILES= Makefile PCR-Makefile OS2_MAKEFILE NT_MAKEFILE BCC_MAKEFILE \
- README test.c test_cpp.cc setjmp_t.c SMakefile.amiga \
- SCoptions.amiga README.amiga README.win32 cord/README \
- cord/gc.h include/gc.h include/gc_typed.h include/cord.h \
- include/ec.h include/private/cord_pos.h include/private/gcconfig.h \
- include/private/gc_hdrs.h include/private/gc_priv.h \
- include/gc_cpp.h README.rs6000 \
- include/weakpointer.h README.QUICK callprocs pc_excludes \
- barrett_diagram README.OS2 README.Mac MacProjects.sit.hqx \
- MacOS.c EMX_MAKEFILE makefile.depend README.debugging \
- include/gc_cpp.h Mac_files/datastart.c Mac_files/dataend.c \
- Mac_files/MacOS_config.h Mac_files/MacOS_Test_config.h \
- add_gc_prefix.c README.solaris2 README.sgi README.hp README.uts \
- win32_threads.c NT_THREADS_MAKEFILE gc.mak README.dj Makefile.dj \
- README.alpha README.linux version.h Makefile.DLLs gc_watcom.asm \
- WCC_MAKEFILE
-
-CORD_INCLUDE_FILES= $(srcdir)/gc.h $(srcdir)/cord/cord.h $(srcdir)/cord/ec.h \
- $(srcdir)/cord/private/cord_pos.h
-
-UTILS= if_mach if_not_there threadlibs
-
-# Libraries needed for curses applications. Only needed for de.
-CURSES= -lcurses -ltermlib
-
-# The following is irrelevant on most systems. But a few
-# versions of make otherwise fork the shell specified in
-# the SHELL environment variable.
-SHELL= /bin/sh
-
-SPECIALCFLAGS =
-# Alternative flags to the C compiler for mach_dep.c.
-# Mach_dep.c often doesn't like optimization, and it's
-# not time-critical anyway.
-# Set SPECIALCFLAGS to -q nodirect_code on Encore.
-
-#all: checkconf libgc.a gctest
-all: checkconf libgc.a
-
-pcr: PCR-Makefile gc_private.h gc_hdrs.h gc.h gcconfig.h mach_dep.o $(SRCS)
- make -f PCR-Makefile depend
- make -f PCR-Makefile
-
-$(OBJS) test.o dyn_load.o dyn_load_sunos53.o: $(srcdir)/gc_priv.h $(srcdir)/gc_hdrs.h $(srcdir)/gc.h \
- $(srcdir)/gcconfig.h $(srcdir)/gc_typed.h Makefile
-# The dependency on Makefile is needed. Changing
-# options such as -DSILENT affects the size of GC_arrays,
-# invalidating all .o files that rely on gc_priv.h
-
-mark.o typd_mlc.o finalize.o: $(srcdir)/gc_mark.h
-
-base_lib libgc.a: $(OBJS) dyn_load.o $(UTILS)
- echo > base_lib
- rm -f on_sparc_sunos5_1
- ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_1
- ./if_mach SPARC SUNOS5 $(AR) rus libgc.a $(OBJS) dyn_load.o
- ./if_not_there on_sparc_sunos5_1 $(AR) ru libgc.a $(OBJS) dyn_load.o
- ./if_not_there on_sparc_sunos5_1 $(RANLIB) libgc.a || cat /dev/null
-# ignore ranlib failure; that usually means it doesn't exist, and isn't needed
-
-cords: $(CORD_OBJS) cord/cordtest $(UTILS)
- rm -f on_sparc_sunos5_3
- ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_3
- ./if_mach SPARC SUNOS5 $(AR) rus libgc.a $(CORD_OBJS)
- ./if_not_there on_sparc_sunos5_3 $(AR) ru libgc.a $(CORD_OBJS)
- ./if_not_there on_sparc_sunos5_3 $(RANLIB) libgc.a || cat /dev/null
-
-gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/gc_cpp.h $(srcdir)/gc.h Makefile
- $(CXX) -c $(CXXFLAGS) $(srcdir)/gc_cpp.cc
-
-test_cpp: $(srcdir)/test_cpp.cc $(srcdir)/gc_cpp.h gc_cpp.o $(srcdir)/gc.h \
-base_lib $(UTILS)
- rm -f test_cpp
- ./if_mach HP_PA "" $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o libgc.a -ldld
- ./if_not_there test_cpp $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/test_cpp.cc gc_cpp.o libgc.a `./threadlibs`
-
-c++: gc_cpp.o $(srcdir)/gc_cpp.h test_cpp
- rm -f on_sparc_sunos5_4
- ./if_mach SPARC SUNOS5 touch on_sparc_sunos5_4
- ./if_mach SPARC SUNOS5 $(AR) rus libgc.a gc_cpp.o
- ./if_not_there on_sparc_sunos5_4 $(AR) ru libgc.a gc_cpp.o
- ./if_not_there on_sparc_sunos5_4 $(RANLIB) libgc.a || cat /dev/null
- ./test_cpp 1
- echo > c++
-
-dyn_load_sunos53.o: dyn_load.c
- $(CC) $(CFLAGS) -DSUNOS53_SHARED_LIB -c $(srcdir)/dyn_load.c -o $@
-
-# SunOS5 shared library version of the collector
-sunos5gc.so: $(OBJS) dyn_load_sunos53.o
- $(CC) -G -o sunos5gc.so $(OBJS) dyn_load_sunos53.o -ldl
- ln sunos5gc.so libgc.so
-
-# Alpha/OSF shared library version of the collector
-libalphagc.so: $(OBJS)
- ld -shared -o libalphagc.so $(OBJS) dyn_load.o -lc
- ln libalphagc.so libgc.so
-
-# IRIX shared library version of the collector
-libirixgc.so: $(OBJS) dyn_load.o
- ld -shared $(ABI_FLAG) -o libirixgc.so $(OBJS) dyn_load.o -lc
- ln libirixgc.so libgc.so
-
-# Linux shared library version of the collector
-liblinuxgc.so: $(OBJS) dyn_load.o
- gcc -shared -o liblinuxgc.so $(OBJS) dyn_load.o -lo
- ln liblinuxgc.so libgc.so
-
-mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ultrix_mach_dep.s $(srcdir)/rs6000_mach_dep.s $(UTILS)
- rm -f mach_dep.o
- ./if_mach MIPS IRIX5 $(AS) -o mach_dep.o $(srcdir)/mips_sgi_mach_dep.s
- ./if_mach MIPS RISCOS $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
- ./if_mach MIPS ULTRIX $(AS) -o mach_dep.o $(srcdir)/mips_ultrix_mach_dep.s
- ./if_mach RS6000 "" $(AS) -o mach_dep.o $(srcdir)/rs6000_mach_dep.s
- ./if_mach ALPHA "" $(AS) -o mach_dep.o $(srcdir)/alpha_mach_dep.s
- ./if_mach SPARC SUNOS5 $(AS) -o mach_dep.o $(srcdir)/sparc_mach_dep.s
- ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
- ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
-
-mark_rts.o: $(srcdir)/mark_rts.c if_mach if_not_there $(UTILS)
- rm -f mark_rts.o
- -./if_mach ALPHA OSF1 $(CC) -c $(CFLAGS) -Wo,-notail $(srcdir)/mark_rts.c
- ./if_not_there mark_rts.o $(CC) -c $(CFLAGS) $(srcdir)/mark_rts.c
-# Work-around for DEC optimizer tail recursion elimination bug.
-# The ALPHA-specific line should be removed if gcc is used.
-
-alloc.o: version.h
-
-cord/cordbscs.o: $(srcdir)/cord/cordbscs.c $(CORD_INCLUDE_FILES)
- $(CC) $(CFLAGS) -c $(srcdir)/cord/cordbscs.c
- mv cordbscs.o cord/cordbscs.o
-# not all compilers understand -o filename
-
-cord/cordxtra.o: $(srcdir)/cord/cordxtra.c $(CORD_INCLUDE_FILES)
- $(CC) $(CFLAGS) -c $(srcdir)/cord/cordxtra.c
- mv cordxtra.o cord/cordxtra.o
-
-cord/cordprnt.o: $(srcdir)/cord/cordprnt.c $(CORD_INCLUDE_FILES)
- $(CC) $(CFLAGS) -c $(srcdir)/cord/cordprnt.c
- mv cordprnt.o cord/cordprnt.o
-
-cord/cordtest: $(srcdir)/cord/cordtest.c $(CORD_OBJS) libgc.a $(UTILS)
- rm -f cord/cordtest
- ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) libgc.a -lucb
- ./if_mach HP_PA "" $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) libgc.a -ldld
- ./if_not_there cord/cordtest $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/cordtest.c $(CORD_OBJS) libgc.a `./threadlibs`
-
-cord/de: $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a $(UTILS)
- rm -f cord/de
- ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a $(CURSES) -lucb `./threadlibs`
- ./if_mach HP_PA "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a $(CURSES) -ldld
- ./if_mach RS6000 "" $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a -lcurses
- ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a -lcurses `./threadlibs`
- ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a -lcurses
- ./if_not_there cord/de $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/de.c cord/cordbscs.o cord/cordxtra.o libgc.a $(CURSES) `./threadlibs`
-
-if_mach: $(srcdir)/if_mach.c $(srcdir)/gcconfig.h
- $(CC) $(CFLAGS) -o if_mach $(srcdir)/if_mach.c
-
-threadlibs: $(srcdir)/threadlibs.c $(srcdir)/gcconfig.h Makefile
- $(CC) $(CFLAGS) -o threadlibs $(srcdir)/threadlibs.c
-
-if_not_there: $(srcdir)/if_not_there.c
- $(CC) $(CFLAGS) -o if_not_there $(srcdir)/if_not_there.c
-
-clean:
- rm -f libgc.a *.o gctest gctest_dyn_link test_cpp \
- setjmp_test mon.out gmon.out a.out core if_not_there if_mach \
- threadlibs $(CORD_OBJS) cord/cordtest cord/de
- -rm -f *~
-
-gctest: test.o libgc.a if_mach if_not_there
- rm -f gctest
- ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o gctest test.o libgc.a -lucb
- ./if_mach HP_PA "" $(CC) $(CFLAGS) -o gctest test.o libgc.a -ldld
- ./if_not_there gctest $(CC) $(CFLAGS) -o gctest test.o libgc.a `./threadlibs`
-
-# If an optimized setjmp_test generates a segmentation fault,
-# odds are your compiler is broken. Gctest may still work.
-# Try compiling setjmp_t.c unoptimized.
-setjmp_test: $(srcdir)/setjmp_t.c $(srcdir)/gc.h if_mach if_not_there
- $(CC) $(CFLAGS) -o setjmp_test $(srcdir)/setjmp_t.c
-
-test: KandRtest cord/cordtest
- cord/cordtest
-
-# Those tests that work even with a K&R C compiler:
-KandRtest: setjmp_test gctest
- ./setjmp_test
- ./gctest
-
-add_gc_prefix: add_gc_prefix.c
- $(CC) -o add_gc_prefix $(srcdir)/add_gc_prefix.c
-
-gc.tar: $(SRCS) $(OTHER_FILES) add_gc_prefix
- ./add_gc_prefix $(SRCS) $(OTHER_FILES) > /tmp/gc.tar-files
- (cd $(srcdir)/.. ; tar cvfh - `cat /tmp/gc.tar-files`) > gc.tar
-
-pc_gc.tar: $(SRCS) $(OTHER_FILES)
- tar cvfX pc_gc.tar pc_excludes $(SRCS) $(OTHER_FILES)
-
-floppy: pc_gc.tar
- -mmd a:/cord
- -mmd a:/cord/private
- -mmd a:/include
- -mmd a:/include/private
- mkdir /tmp/pc_gc
- cat pc_gc.tar | (cd /tmp/pc_gc; tar xvf -)
- -mcopy -tmn /tmp/pc_gc/* a:
- -mcopy -tmn /tmp/pc_gc/cord/* a:/cord
- -mcopy -mn /tmp/pc_gc/cord/de_win.ICO a:/cord
- -mcopy -tmn /tmp/pc_gc/cord/private/* a:/cord/private
- -mcopy -tmn /tmp/pc_gc/include/* a:/include
- -mcopy -tmn /tmp/pc_gc/include/private/* a:/include/private
- rm -r /tmp/pc_gc
-
-gc.tar.Z: gc.tar
- compress gc.tar
-
-gc.tar.gz: gc.tar
- gzip gc.tar
-
-lint: $(CSRCS) test.c
- lint -DLINT $(CSRCS) test.c | egrep -v "possible pointer alignment problem|abort|exit|sbrk|mprotect|syscall"
-
-# BTL: added to test shared library version of collector.
-# Currently works only under SunOS5. Requires GC_INIT call from statically
-# loaded client code.
-ABSDIR = `pwd`
-gctest_dyn_link: test.o libgc.so
- $(CC) -L$(ABSDIR) -R$(ABSDIR) -o gctest_dyn_link test.o -lgc -ldl -lthread
-
-gctest_irix_dyn_link: test.o libirixgc.so
- $(CC) -L$(ABSDIR) -o gctest_irix_dyn_link test.o -lirixgc
-
-test_dll.o: test.c libgc_globals.h
- $(CC) $(CFLAGS) -DGC_USE_DLL -c test.c -o test_dll.o
-
-test_dll: test_dll.o libgc_dll.a libgc.dll
- $(CC) test_dll.o -L$(ABSDIR) -lgc_dll -o test_dll
-
-SYM_PREFIX-libgc=GC
-
-# Uncomment the following line to build a GNU win32 DLL
-# include Makefile.DLLs
-
-reserved_namespace: $(SRCS)
- for file in $(SRCS) test.c test_cpp.cc; do \
- sed s/GC_/_GC_/g < $$file > tmp; \
- cp tmp $$file; \
- done
-
-user_namespace: $(SRCS)
- for file in $(SRCS) test.c test_cpp.cc; do \
- sed s/_GC_/GC_/g < $$file > tmp; \
- cp tmp $$file; \
- done
-
-# Remake configuration
-checkconf:
- @if [ -f $(srcdir)/../devel ]; then \
- $(MAKE) -f $(srcdir)/conf.mk freshconf \
- srcdir="$(srcdir)" PRJDIR="$(PRJDIR)"; \
- fi
-
-# End of Makefile