Got rid of gc_strdup, added prototype for alt lexer
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 19 Aug 2000 19:05:26 +0000 (19:05 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 19 Aug 2000 19:05:26 +0000 (19:05 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@325 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCerr.c
src/altlex.c [new file with mode: 0644]
src/asm.c
src/z80/gen.c
src/z80/ralloc.c

index eb464c6f6ad195d8c87478f36a0b94b8c78f234d..0ad85971a1be3d50992524b6235e24fab462dca7 100644 (file)
@@ -2,6 +2,14 @@
 
 #include "common.h"
 
+#define USE_STDOUT_FOR_ERRORS          0
+
+#if USE_STDOUT_FOR_ERRORS
+#define ERRSINK                stdout
+#else
+#define ERRSINK                stderr
+#endif
+
 #define ERROR          0
 #define WARNING                1
 extern FILE *lstFile;
@@ -163,10 +171,10 @@ void      werror (int errNum, ... )
                fatalError++ ;
        
        if ( filename && lineno ) {
-               fprintf(stderr,"%s(%d):",filename,lineno);
+               fprintf(ERRSINK, "%s(%d):",filename,lineno);
        }
        va_start(marker,errNum);
-       vfprintf(stderr,ErrTab[errNum].errText,marker);
+       vfprintf(ERRSINK, ErrTab[errNum].errText,marker);
        va_end( marker );
 }
 
diff --git a/src/altlex.c b/src/altlex.c
new file mode 100644 (file)
index 0000000..da1862b
--- /dev/null
@@ -0,0 +1,485 @@
+/** @file altlex.c
+    An alternate lexer to SDCC.lex.
+    In development - ie messy and just plain wrong.
+*/
+#include "common.h"
+#include <assert.h>
+
+FILE *yyin;
+
+int yylineno;
+int column;
+char *currFname;
+char *yytext;
+
+/* Right.  What are the parts of the C stream?  From SDCC.lex:
+   D = [0..9]          digits
+   L = [a..z A..Z _]   alphanumerics and _
+   H = [a..f A..F 0-9] Hex digits
+   E = [eE+-0-9]       Digits in a float
+   FS = [fFlL]         Specifiers for a float
+   IS = [uUlL]         Specifiers for a int
+
+   L[LD]*                      A 'token' - cant think of a good name
+                       Check tokens against the reserved words.
+                       If match 
+                               return the token id.
+                       else 
+                               If in the typedef table, do stuff...
+                               Blah.  See check_type()
+   0[xX]{H}+           Hex number - PENDING: specifiers
+   0{D}+               Octal number - PENDING: specifiers
+   {D}+                        Decimal - PENDING: specifiers
+   Floats              PENDING
+   
+   Exceptions:
+   Comment start       Strip until end of comment.
+   ...                 Ellipses
+
+   So the inputs are:
+      Skip whitespace
+      switch class
+        L      Try to read a token
+        D      Try to read a number
+        Punct  Try to read punct
+*/     
+
+char linebuf[10000];
+int linepos, linelen;
+
+#define INLINE inline
+
+static int underflow(void)
+{
+    linelen = fread(linebuf, 1, sizeof(linebuf), yyin);
+    if (linelen <= 0)
+       return EOF;
+    linepos = 0;
+    return linebuf[linepos++];
+}
+
+static int INLINE ygetc(void)
+{
+    if (linepos < linelen)
+       return linebuf[linepos++];
+    else
+       return underflow();
+};
+
+static int INLINE yungetc(int c)
+{
+    linebuf[--linepos] = c;
+    return 0;
+}
+
+#define GETC()         ygetc()
+#define UNGETC(_a)     yungetc(_a)
+
+//#define GETC()               fgetc(yyin);
+//#define UNGETC(_a)   ungetc(_a, yyin)
+#define ISL(_a)                (isalnum(_a) || _a == '_')
+#define ISALNUM(_a)    isalnum(_a)
+#define ISHEX(_a)      isalnum(_a)
+
+char *stringLiteral (void)
+{
+    static char line[1000];
+    int ch;
+    char *str = line;
+       
+    *str++ = '\"'                      ;
+    /* put into the buffer till we hit the */
+    /* first \" */
+    while (1) {
+
+       ch = GETC();
+       if (!ch)            break       ; /* end of input */
+       /* if it is a \ then everything allowed */
+       if (ch == '\\') {
+           *str++ = ch     ; /* backslash in place */
+           *str++ = GETC()             ; /* 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 = GETC()) && isspace(ch)) ;
+           if (!ch) break              ; 
+           if (ch != '\"') {
+               UNGETC(ch)                      ;
+               break                   ;
+           }
+                 
+           continue            ;
+        }
+       *str++  = ch;     
+    }  
+    *str++ = '\"'                      ;
+    *str = '\0';
+    return line;
+}
+
+void discard_comments(int type)
+{
+    int c;
+    if (type == '*') {
+       do {
+           c = GETC();
+           if (c == '*') {
+               c = GETC();
+               if (c == '/')
+                   return;
+           }
+           else if (c == EOF)
+               return;
+       } while (1);
+    }
+    else if (type == '/') {
+       while (c != '\n' && c != EOF) {
+           c = GETC();
+       }
+    }
+    else {
+       assert(0);
+    }
+}
+
+#define TKEYWORD(_a)   return _a
+
+int check_token(const char *sz)
+{
+    if (!strcmp(sz, "at")) {
+       TKEYWORD(AT)  ; }
+    
+    else if (!strcmp(sz, "auto")) {
+        return(AUTO); }
+    
+    else if (!strcmp(sz, "bit")) {
+        TKEYWORD(BIT) ; }
+    
+    else if (!strcmp(sz, "break")) {
+        return(BREAK); }
+
+    else if (!strcmp(sz, "case")) {
+        return(CASE); }
+
+    else if (!strcmp(sz, "char")) {
+        return(CHAR); }
+
+    else if (!strcmp(sz, "code")) {
+        TKEYWORD(CODE); }
+
+    else if (!strcmp(sz, "const")) {
+        return(CONST); }
+
+    else if (!strcmp(sz, "continue")) {
+        return(CONTINUE); }
+
+    else if (!strcmp(sz, "critical")) {
+        TKEYWORD(CRITICAL); } 
+
+    else if (!strcmp(sz, "data")) {
+        TKEYWORD(DATA);   }
+
+    else if (!strcmp(sz, "default")) {
+        return(DEFAULT); }
+
+    else if (!strcmp(sz, "do")) {
+        return(DO); }
+
+    else if (!strcmp(sz, "double")) {
+        werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
+
+    else if (!strcmp(sz, "else")) {
+        return(ELSE); }
+
+    else if (!strcmp(sz, "enum")) {
+        return(ENUM); }
+
+    else if (!strcmp(sz, "extern")) {
+        return(EXTERN); }
+
+    else if (!strcmp(sz, "far")) {
+        TKEYWORD(XDATA);  }
+
+    else if (!strcmp(sz, "eeprom")) {
+        TKEYWORD(EEPROM);  }
+
+    else if (!strcmp(sz, "float")) {
+        return(FLOAT); }
+
+    else if (!strcmp(sz, "flash")) {
+        TKEYWORD(CODE);}
+
+    else if (!strcmp(sz, "for")) {
+        return(FOR); }
+
+    else if (!strcmp(sz, "goto")) {
+        return(GOTO); }
+
+    else if (!strcmp(sz, "idata")) {
+        TKEYWORD(IDATA);}
+
+    else if (!strcmp(sz, "if")) {
+        return(IF); }
+
+    else if (!strcmp(sz, "int")) {
+        return(INT); }
+
+    else if (!strcmp(sz, "interrupt")) {
+        return(INTERRUPT);}
+
+    else if (!strcmp(sz, "nonbanked")) {
+        TKEYWORD(NONBANKED);}
+
+    else if (!strcmp(sz, "banked")) {
+        TKEYWORD(BANKED);}
+
+    else if (!strcmp(sz, "long")) {
+        return(LONG); }
+
+    else if (!strcmp(sz, "near")) {
+        TKEYWORD(DATA);}
+
+    else if (!strcmp(sz, "pdata")) {
+        TKEYWORD(PDATA); }
+
+    else if (!strcmp(sz, "reentrant")) {
+        TKEYWORD(REENTRANT);}
+
+    else if (!strcmp(sz, "register")) {
+        return(REGISTER); }
+
+    else if (!strcmp(sz, "return")) {
+        return(RETURN); }
+
+    else if (!strcmp(sz, "sfr")) {
+        TKEYWORD(SFR)  ; }
+
+    else if (!strcmp(sz, "sbit")) {
+        TKEYWORD(SBIT) ; }
+
+    else if (!strcmp(sz, "short")) {
+        return(SHORT); }
+
+    else if (!strcmp(sz, "signed")) {
+        return(SIGNED); }
+
+    else if (!strcmp(sz, "sizeof")) {
+        return(SIZEOF); }
+
+    else if (!strcmp(sz, "sram")) {
+        TKEYWORD(XDATA);}
+
+    else if (!strcmp(sz, "static")) {
+        return(STATIC); }
+
+    else if (!strcmp(sz, "struct")) {
+        return(STRUCT); }
+
+    else if (!strcmp(sz, "switch")) {
+        return(SWITCH); }
+
+    else if (!strcmp(sz, "typedef")) {
+        return(TYPEDEF); }
+
+    else if (!strcmp(sz, "union")) {
+        return(UNION); }
+
+    else if (!strcmp(sz, "unsigned")) {
+        return(UNSIGNED); }
+
+    else if (!strcmp(sz, "void")) {
+        return(VOID); }
+
+    else if (!strcmp(sz, "volatile")) {
+        return(VOLATILE); }
+
+    else if (!strcmp(sz, "using")) {
+        TKEYWORD(USING); }
+
+    else if (!strcmp(sz, "while")) {
+        return(WHILE); }
+
+    else if (!strcmp(sz, "xdata")) {
+        TKEYWORD(XDATA); }
+
+    else if (!strcmp(sz, "_data")) {
+        TKEYWORD(_NEAR); }
+
+    else if (!strcmp(sz, "_code")) {
+        TKEYWORD(_CODE); }
+
+    else if (!strcmp(sz, "_eeprom")) {
+        TKEYWORD(_EEPROM); }
+
+    else if (!strcmp(sz, "_flash")) {
+        TKEYWORD(_CODE); }
+
+    else if (!strcmp(sz, "_generic")) {
+        TKEYWORD(_GENERIC); }
+
+    else if (!strcmp(sz, "_near")) {
+        TKEYWORD(_NEAR); }
+
+    else if (!strcmp(sz, "_sram")) {
+        TKEYWORD(_XDATA);}
+
+    else if (!strcmp(sz, "_xdata")) {
+        TKEYWORD(_XDATA);}
+
+    else if (!strcmp(sz, "_pdata")) {
+        TKEYWORD(_PDATA); }
+
+    else if (!strcmp(sz, "_idata")) {
+        TKEYWORD(_IDATA); }
+
+    /* check if it is in the typedef table */
+    if (findSym(TypedefTab,NULL,sz)) {
+       strcpy(yylval.yychar,sz);
+       return (TYPE_NAME) ;
+    }
+    else   {
+       strcpy (yylval.yychar,sz);
+       return(IDENTIFIER);
+    }
+}
+
+int yylex(void)
+{
+    int c;
+    char line[128];
+    char *p;
+
+    c = GETC();
+    while (1) {
+       /* Handle comments first */
+       if (c == '/') {
+           int c2 = GETC();
+           if (c2 == '*' || c2 == '/') {
+               discard_comments(c2);
+               c = GETC();
+               continue;
+           }
+           else
+               UNGETC(c2);
+       }
+       switch (c) {
+       case EOF:
+           return 0;
+       case ' ':
+       case '\t':
+       case '\r':
+       case '\n':
+           /* Skip whitespace */
+           break;
+       case 'a': case 'b': case 'c': case 'd':
+       case 'e': case 'f': case 'g': case 'h':
+       case 'i': case 'j': case 'k': case 'l':
+       case 'm': case 'n': case 'o': case 'p':
+       case 'q': case 'r': case 's': case 't':
+       case 'u': case 'v': case 'w': case 'x':
+       case 'y': case 'z':
+       case 'A': case 'B': case 'C': case 'D':
+       case 'E': case 'F': case 'G': case 'H':
+       case 'I': case 'J': case 'K': case 'L':
+       case 'M': case 'N': case 'O': case 'P':
+       case 'Q': case 'R': case 'S': case 'T':
+       case 'U': case 'V': case 'W': case 'X':
+       case 'Y': case 'Z':
+       case '_':
+           /* Start of a token.  Parse. */
+           p = line;
+           *p++ = c;
+           c = GETC();
+           while (ISL(c)) {
+               *p++ = c;
+               c = GETC();
+           }
+           *p = '\0';
+           UNGETC(c);
+           return check_token(line);
+       case '0': case '1':
+       case '2': case '3': case '4': case '5':
+       case '6': case '7': case '8': case '9':
+           p = line;
+           *p++ = c;
+           c = GETC();
+           if (c == 'x' || c == 'X') {
+               *p++ = c;
+               c = GETC();
+           }
+           while (ISHEX(c)) {
+               *p++ = c;
+               c = GETC();
+           }
+           *p = '\0';
+           UNGETC(c);
+           yylval.val = constVal(line);
+           return CONSTANT;
+       case '\"':
+           /* A string */
+           p = stringLiteral();
+           yylval.val = strVal(p);
+           return(STRING_LITERAL);
+       case '\'':
+           /* ie '\n' */
+           break;
+       case '#':
+           /* Assume a pragma and toast the rest of the line. */
+           c = GETC();
+           while (c != '\n') {
+               c = GETC();
+           }
+           break;
+       case '=':
+       case '&':
+       case '!':
+       case '-':
+       case '+':
+       case '*':
+       case '/':
+       case '%':
+       case '<':
+       case '>':
+       case '^':
+       case '|':
+           /* Cases which can be compounds */
+           return c;
+       case '{':
+           NestLevel++;
+           return c;
+       case '}':
+           NestLevel--;
+           return c;
+       case '.':
+           c = GETC();
+           if (c == '.') {
+               c = GETC();
+               if (c == '.') {
+                   return VAR_ARGS;
+               }
+           }
+           UNGETC(c);
+           /* Fall through */
+       case ',':
+       case ':':
+       case '(': case ')':
+       case '[': case ']':
+       case '~':
+       case '?':
+           /* Special characters that cant be part of a composite */
+           return c;
+       default:
+           printf("Unhandled char %c\n", c);
+       }
+       c = GETC();
+    }
+    return 0;
+}
index 3d2195a7c7f64358d8fc6867b51fef889389c071..1e0dd64b445295ad9ddd29e3a5c51c747ca5c151 100644 (file)
--- a/src/asm.c
+++ b/src/asm.c
@@ -1,6 +1,18 @@
+/** @file asm.c
+    Provides output functions that modify the output string
+    based on the input tokens and the assembler token mapping
+    specification loaded.
+
+    Note that the functions below only handle digit format modifiers.
+    eg %02X is ok, but %lu and %.4u will fail.
+*/
 #include "common.h"
 #include "asm.h"
 
+/* A 'token' is like !blah or %24f and is under the programmers
+   control. */
+#define MAX_TOKEN_LEN          64
+
 static hTab *_h;
 
 static const char *_findMapping(const char *szKey)
@@ -8,10 +20,10 @@ static const char *_findMapping(const char *szKey)
     return shash_find(_h, szKey);
 }
 
-static va_list _iprintf(char *pInto, const char *szFormat, va_list ap)
+static va_list _iprintf(char *pInto, const char *sz, va_list ap)
 {
+    char format[MAX_TOKEN_LEN];
     char *pStart = pInto;
-    char *sz = gc_strdup(szFormat);
     static int count;
 
     while (*sz) {
@@ -40,16 +52,15 @@ static va_list _iprintf(char *pInto, const char *szFormat, va_list ap)
            default:
                {
                    /* Scan out the arg and pass it on to sprintf */
-                   char *p = sz-1, tmp;
+                   char *p = format;
+                   *p++ = '%';
                    while (isdigit(*sz))
-                       sz++;
-                   /* Skip the format */
-                   tmp = *++sz;
-                   *sz = '\0';
-                   vsprintf(pInto, p, ap);
+                       *p++ = *sz++;
+                   *p++ = *sz++;
+                   *p = '\0';
+                   vsprintf(pInto, format, ap);
                    /* PENDING: Assume that the arg length was an int */
                    va_arg(ap, int);
-                   *sz = tmp;
                }
            }
            pInto = pStart + strlen(pStart);
@@ -63,10 +74,11 @@ static va_list _iprintf(char *pInto, const char *szFormat, va_list ap)
     return ap;
 }
 
-void tvsprintf(char *buffer, const char *szFormat, va_list ap)
+void tvsprintf(char *buffer, const char *sz, va_list ap)
 {
-    char *sz = gc_strdup(szFormat);
-    char *pInto = buffer, *p;
+    char *pInto = buffer;
+    char *p;
+    char token[MAX_TOKEN_LEN];
 
     buffer[0] = '\0';
     
@@ -74,37 +86,33 @@ void tvsprintf(char *buffer, const char *szFormat, va_list ap)
        if (*sz == '!') {
            /* Start of a token.  Search until the first
               [non alplha, *] and call it a token. */
-           char old;
            const char *t;
-           p = ++sz;
+           p = token;
+           sz++;
            while (isalpha(*sz) || *sz == '*') {
-               sz++;
+               *p++ = *sz++;
            }
-           old = *sz;
-           *sz = '\0';
+           *p = '\0';
            /* Now find the token in the token list */
-           if ((t = _findMapping(p))) {
+           if ((t = _findMapping(token))) {
                ap = _iprintf(pInto, t, ap);
                pInto = buffer + strlen(buffer);
            }
            else {
-               fprintf(stderr, "Cant find token \"%s\"\n", p);
+               fprintf(stderr, "Cant find token \"%s\"\n", token);
                wassert(0);
            }
-           *sz = old;
        }
        else if (*sz == '%') {
-           char *pFormat = sz;
-           char old;
-           sz++;
-           while (!isalpha(*sz))
-               sz++;
-           sz++;
-           old = *sz;
-           *sz = '\0';
-           vsprintf(pInto, pFormat, ap);
+           p = token;
+           *p++ = *sz++;
+           while (!isalpha(*sz)) {
+               *p++ = *sz++;
+           }
+           *p++ = *sz++;
+           *p = '\0';
+           vsprintf(pInto, token, ap);
            pInto = buffer + strlen(buffer);
-           *sz = old;
            va_arg(ap, int);
        }
        else {
index e33f32818ee3ce5227ba308b9de92db2d7ca8912..003f59462de5f13ed13cb421e938116baddef41c 100644 (file)
@@ -723,8 +723,10 @@ char *aopGetLitWordLong(asmop *aop, int offset, bool with_hash)
        /* otherwise it is fairly simple */
        if (!IS_FLOAT(val->type)) {
            unsigned long v = floatFromVal(val);
+
            if (offset == 2)
                v >>= 16;
+
            if (with_hash)
                tsprintf(buffer, "!immedword", v);
            else
@@ -802,6 +804,26 @@ static bool requiresHL(asmop *aop)
     }
 }
 
+static char *fetchLitSpecial(asmop *aop, bool negate, bool xor)
+{
+    unsigned long v;
+    value * val = aop->aopu.aop_lit;
+
+    wassert(aop->type == AOP_LIT);
+    wassert(!IS_FLOAT(val->type));
+    
+    v = floatFromVal(val);
+
+    if (xor)
+       v ^= 0x8000;
+    if (negate)
+       v = -v;
+    v &= 0xFFFF;
+
+    tsprintf(buffer, "!immedword", v);
+    return gc_strdup(buffer);
+}
+
 static void fetchLitPair(PAIR_ID pairId, asmop *left, int offset)
 {
     const char *l;
@@ -1274,7 +1296,7 @@ void outAcc(operand *result)
 
 /** Take the value in carry and put it into a register
  */
-void outBitC(operand *result)
+void outBitCLong(operand *result, bool swap_sense)
 {
     /* if the result is bit */
     if (AOP_TYPE(result) == AOP_CRY) {
@@ -1284,10 +1306,17 @@ void outBitC(operand *result)
     else {
        emit2("ld a,!zero");
        emit2("rla");
+       if (swap_sense)
+           emit2("xor a,!immedbyte", 1);
         outAcc(result);
     }
 }
 
+void outBitC(operand *result)
+{
+    outBitCLong(result, FALSE);
+}
+
 /*-----------------------------------------------------------------*/
 /* toBoolean - emit code for orl a,operator(sizeop)                */
 /*-----------------------------------------------------------------*/
@@ -2546,7 +2575,7 @@ static void genIfxJump (iCode *ic, char *jval)
 
     /* if true label then we jump if condition
     supplied is true */
-    if ( IC_TRUE(ic) ) {
+    if (IC_TRUE(ic)) {
         jlbl = IC_TRUE(ic);
        if (!strcmp(jval, "a")) {
            inst = "nz";
@@ -2554,6 +2583,9 @@ static void genIfxJump (iCode *ic, char *jval)
        else if (!strcmp(jval, "c")) {
            inst = "c";
        }
+       else if (!strcmp(jval, "nc")) {
+           inst = "nc";
+       }
        else {
            /* The buffer contains the bit on A that we should test */
            inst = "nz";
@@ -2568,6 +2600,9 @@ static void genIfxJump (iCode *ic, char *jval)
        else if (!strcmp(jval, "c")) {
            inst = "nc";
        }
+       else if (!strcmp(jval, "nc")) {
+           inst = "c";
+       }
        else {
            /* The buffer contains the bit on A that we should test */
            inst = "z";
@@ -2579,6 +2614,8 @@ static void genIfxJump (iCode *ic, char *jval)
     }
     else if (!strcmp(jval, "c")) {
     }
+    else if (!strcmp(jval, "nc")) {
+    }
     else {
        emitcode("bit", "%s,a", jval);
     }
@@ -2588,6 +2625,11 @@ static void genIfxJump (iCode *ic, char *jval)
     ic->generated = 1;
 }
 
+const char *getPairIdName(PAIR_ID id)
+{
+    return _pairs[id].name;
+}
+
 /** Generic compare for > or <
  */
 static void genCmp (operand *left,operand *right,
@@ -2595,6 +2637,7 @@ static void genCmp (operand *left,operand *right,
 {
     int size, offset = 0 ;
     unsigned long lit = 0L;
+    bool swap_sense = FALSE;
 
     /* if left & right are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
@@ -2619,6 +2662,30 @@ static void genCmp (operand *left,operand *right,
                emitcode("cp", "%s", aopGet(AOP(right), offset, FALSE));
         } 
        else {
+           /* Special cases:
+              On the GB:
+                 If the left or the right is a lit:
+                       Load -lit into HL, add to right via, check sense.
+           */
+           if (size == 2 && (AOP_TYPE(right) == AOP_LIT || AOP_TYPE(left) == AOP_LIT)) {
+               asmop *lit = AOP(right);
+               asmop *op = AOP(left);
+               swap_sense = TRUE;
+               if (AOP_TYPE(left) == AOP_LIT) {
+                   swap_sense = FALSE;
+                   lit = AOP(left);
+                   op = AOP(right);
+               }
+               if (sign) {
+                   emit2("ld e,%s", aopGet(op, 0, 0));
+                   emit2("ld a,%s", aopGet(op, 1, 0));
+                   emit2("xor a,!immedbyte", 0x80);
+                   emit2("ld d,a");
+               }
+               emit2("ld hl,%s", fetchLitSpecial(lit, TRUE, sign));
+               emit2("add hl,de");
+               goto release;
+           }
             if(AOP_TYPE(right) == AOP_LIT) {
                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
                 /* optimize if(x < 0) or if(x >= 0) */
@@ -2692,15 +2759,15 @@ static void genCmp (operand *left,operand *right,
 
 release:
     if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-        outBitC(result);
+        outBitCLong(result, swap_sense);
     } else {
         /* if the result is used in the next
         ifx conditional branch then generate
         code a little differently */
-        if (ifx )
-            genIfxJump (ifx,"c");
+        if (ifx)
+            genIfxJump(ifx, swap_sense ? "nc" : "c");
         else
-            outBitC(result);
+            outBitCLong(result, swap_sense);
         /* leave the result in acc */
     }
 }
index 90d6f6fbeea25756904d1ae7683bb36579255d69..75127f84b3fb7d8fec6f7284f892e5b0db1be527 100644 (file)
@@ -1899,6 +1899,36 @@ bool opPreservesA(iCode *ic, iCode *uic)
     return FALSE;
 }
 
+static void joinPushes(iCode *ic)
+{
+#if 0
+    if (ic->op == IPUSH &&
+       isOperandLiteral(IC_LEFT(ic)) &&
+       getSize(operandType(IC_LEFT(ic))) == 1 &&
+       ic->next->op == IPUSH &&
+       isOperandLiteral(IC_LEFT(ic->next)) &&
+       getSize(operandType(IC_LEFT(ic->next))) == 1) {
+       /* This is a bit tricky as michaelh doesnt know what he's doing.
+        */
+       /* First upgrade the size of (first) to int */
+       SPEC_NOUN(operandType(IC_LEFT(ic))) = V_INT;
+       SPEC_SHORT(operandType(IC_LEFT(ic))) = 0;
+
+       floatFromVal(AOP
+       /* Now get and join the values */
+       value * val = aop->aopu.aop_lit;
+       /* if it is a float then it gets tricky */
+       /* otherwise it is fairly simple */
+       if (!IS_FLOAT(val->type)) {
+           unsigned long v = floatFromVal(val);
+
+       floatFrom
+       printf("Size %u\n", getSize(operandType(IC_LEFT(ic))));
+       ic->next = ic->next->next;
+    }
+#endif
+}
+
 /** Pack registers for acc use.
     When the result of this operation is small and short lived it may
     be able to be stored in the accumulator.
@@ -2222,6 +2252,7 @@ static void packRegisters (eBBlock *ebp)
            packRegsForAccUse2(ic);
        }
 #endif
+       joinPushes(ic);
     }
 }