* Changed banked for nonbanked
[fw/sdcc] / src / z80 / gen.c
index 0782a420cd41d6de258f8052d67edee9279175fa..c22a8105f8c7c76fc9d8448b4cd8addbd3a85310 100644 (file)
   Slightly better genCmp(signed)               20597   159     195B
   Better reg packing, first peephole           20038   163     1873
   With assign packing                          19281   165     1849
   Slightly better genCmp(signed)               20597   159     195B
   Better reg packing, first peephole           20038   163     1873
   With assign packing                          19281   165     1849
+  5/3/00                                       17741   185     17B6
 
   Michael Hope <michaelh@earthling.net>        2000
 
   Michael Hope <michaelh@earthling.net>        2000
-  Based on the mcs51 generator - Sandeep Dutta . sandeep.dutta@usa.net (1998)
-                           and -  Jean-Louis VERN.jlvern@writeme.com (1999)
+  Based on the mcs51 generator - 
+               Sandeep Dutta . sandeep.dutta@usa.net (1998)
+        and -  Jean-Louis VERN.jlvern@writeme.com (1999)
         
   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
         
   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
@@ -30,6 +32,7 @@
   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.
   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
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
    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 */
 
    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 *_z80_return[] = {"l", "h", "e", "d" };
 static char *_gbz80_return[] = { "e", "d", "l", "h" };
 static char **_fReturn;
 static char **_fTmp;
 
 static char *spname ;
 static char *_z80_return[] = {"l", "h", "e", "d" };
 static char *_gbz80_return[] = { "e", "d", "l", "h" };
 static char **_fReturn;
 static char **_fTmp;
 
+/* PENDING: messy */
+static char zero[20];
+
 static char *accUse[] = {"a" };
 static char *accUse[] = {"a" };
+static char *hlUse[] = { "l", "h" };
 short rbank = -1;
 short accInUse = 0 ;
 short inLine = 0;
 short rbank = -1;
 short accInUse = 0 ;
 short inLine = 0;
@@ -77,6 +82,30 @@ extern int ptrRegReq ;
 extern int nRegs;
 extern FILE *codeOutFile;
 set *sendSet = NULL;
 extern int nRegs;
 extern FILE *codeOutFile;
 set *sendSet = NULL;
+
+typedef enum {
+    PAIR_INVALID,
+    PAIR_BC,
+    PAIR_DE,
+    PAIR_HL,
+    PAIR_IY,
+    PAIR_IX,
+    NUM_PAIRS
+} PAIR_ID;
+
+static struct {
+    const char *name;
+    const char *l;
+    const char *h;
+} _pairs[NUM_PAIRS] = {
+    { "??", "?", "?" },
+    { "bc", "c", "b" },
+    { "de", "e", "d" },
+    { "hl", "l", "h" },
+    { "iy", "iy.l?", "iy.h?" },
+    { "ix", "ix.l?", "ix.h?" }
+};
+    
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
@@ -84,19 +113,13 @@ set *sendSet = NULL;
 #define MOVA(x) if (strcmp(x,"a")) emitcode("ld","a,%s",x);
 #define CLRC    emitcode("xor","a,a");
 
 #define MOVA(x) if (strcmp(x,"a")) emitcode("ld","a,%s",x);
 #define CLRC    emitcode("xor","a,a");
 
-#define LABEL_STR      "%05d$"
-
 lineNode *lineHead = NULL;
 lineNode *lineCurr = NULL;
 
 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};
-
-static int _lastStack = 0;
-static int _pushed = 0;
-static int _spoffset;
+static const unsigned char SLMask[] = 
+{0xFF ,0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00};
+static const unsigned char SRMask[] = 
+{0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00};
 
 #define LSB     0
 #define MSB16   1
 
 #define LSB     0
 #define MSB16   1
@@ -104,13 +127,68 @@ static int _spoffset;
 #define MSB32   3
 
 /* Stack frame:
 #define MSB32   3
 
 /* Stack frame:
-
    IX+4                param0  LH
    IX+2                ret     LH
    IX+0                ix      LH
    IX-2                temp0   LH
 */
 
    IX+4                param0  LH
    IX+2                ret     LH
    IX+0                ix      LH
    IX-2                temp0   LH
 */
 
+static struct {
+    struct {
+       AOP_TYPE last_type;
+       const char *lit;
+       int offset;
+    } pairs[NUM_PAIRS];
+    struct {
+       int last;
+       int pushed;
+       int param_offset;
+       int offset;
+       int pushed_bc;
+       int pushed_de;
+    } stack;
+    int frameId;
+} _G;
+
+static char *aopGet(asmop *aop, int offset, bool bit16);
+
+static void _tidyUp(char *buf)
+{
+    /* Clean up the line so that it is 'prettier' */
+    if (strchr(buf, ':')) {
+       /* Is a label - cant do anything */
+       return;
+    }
+    /* Change the first (and probably only) ' ' to a tab so
+       everything lines up.
+    */
+    while (*buf) {
+       if (*buf == ' ') {
+           *buf = '\t';
+           return;
+       }
+       buf++;
+    }
+}
+
+static void emit2(const char *szFormat, ...)
+{
+    char buffer[256];
+    va_list ap;
+
+    va_start(ap, szFormat);
+
+    tvsprintf(buffer, szFormat, ap);
+
+    _tidyUp(buffer);
+    lineCurr = (lineCurr ?
+               connectLine(lineCurr,newLineNode(buffer)) :
+               (lineHead = newLineNode(buffer)));
+
+    lineCurr->isInline = inLine;
+    lineCurr->isDebug  = debugLine;
+}
+
 /*-----------------------------------------------------------------*/
 /* emitcode - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* emitcode - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
@@ -139,6 +217,26 @@ void emitcode (const char *inst, const char *fmt, ...)
     va_end(ap);
 }
 
     va_end(ap);
 }
 
+/* Z80:
+    { "adjustsp", 
+      "\tld hl,#-%d\n"
+      "\tadd hl,sp\n"
+      "\tld sp,hl"
+    }
+    { "prelude",
+       "push bc"
+       "push de"
+       "push ix"
+       "ld ix,#0"
+       "add ix,sp"
+    { "leave" 
+    emitcode("ld", "sp,ix");
+    emitcode("pop", "ix");
+    emitcode("pop", "de");
+    }
+}
+*/
+
 const char *getPairName(asmop *aop)
 {
     if (aop->type == AOP_REG) {
 const char *getPairName(asmop *aop)
 {
     if (aop->type == AOP_REG) {
@@ -167,46 +265,64 @@ const char *getPairName(asmop *aop)
            break;
        }
     }
            break;
        }
     }
-    assert(0);
+    wassert(0);
     return NULL;
 }
 
     return NULL;
 }
 
-/** Returns TRUE if the registers used in aop form a pair (BC, DE, HL) */
-bool isPair(asmop *aop)
+static PAIR_ID getPairId(asmop *aop)
 {
     if (aop->size == 2) {
        if (aop->type == AOP_REG) {
            if ((aop->aopu.aop_reg[0]->rIdx == C_IDX)&&(aop->aopu.aop_reg[1]->rIdx == B_IDX)) {
 {
     if (aop->size == 2) {
        if (aop->type == AOP_REG) {
            if ((aop->aopu.aop_reg[0]->rIdx == C_IDX)&&(aop->aopu.aop_reg[1]->rIdx == B_IDX)) {
-               return TRUE;
+               return PAIR_BC;
            }
            if ((aop->aopu.aop_reg[0]->rIdx == E_IDX)&&(aop->aopu.aop_reg[1]->rIdx == D_IDX)) {
            }
            if ((aop->aopu.aop_reg[0]->rIdx == E_IDX)&&(aop->aopu.aop_reg[1]->rIdx == D_IDX)) {
-               return TRUE;
+               return PAIR_DE;
            }
            if ((aop->aopu.aop_reg[0]->rIdx == L_IDX)&&(aop->aopu.aop_reg[1]->rIdx == H_IDX)) {
            }
            if ((aop->aopu.aop_reg[0]->rIdx == L_IDX)&&(aop->aopu.aop_reg[1]->rIdx == H_IDX)) {
-               return TRUE;
+               return PAIR_HL;
            }
        }
        if (aop->type == AOP_STR) {
            if (!strcmp(aop->aopu.aop_str[0], "c")&&!strcmp(aop->aopu.aop_str[1], "b")) {
            }
        }
        if (aop->type == AOP_STR) {
            if (!strcmp(aop->aopu.aop_str[0], "c")&&!strcmp(aop->aopu.aop_str[1], "b")) {
-               return TRUE;
+               return PAIR_BC;
            }
            if (!strcmp(aop->aopu.aop_str[0], "e")&&!strcmp(aop->aopu.aop_str[1], "d")) {
            }
            if (!strcmp(aop->aopu.aop_str[0], "e")&&!strcmp(aop->aopu.aop_str[1], "d")) {
-               return TRUE;
+               return PAIR_DE;
            }
            if (!strcmp(aop->aopu.aop_str[0], "l")&&!strcmp(aop->aopu.aop_str[1], "h")) {
            }
            if (!strcmp(aop->aopu.aop_str[0], "l")&&!strcmp(aop->aopu.aop_str[1], "h")) {
-               return TRUE;
+               return PAIR_HL;
            }
        }
     }
            }
        }
     }
-    return FALSE;
+    return PAIR_INVALID;
 }
 
 }
 
+/** Returns TRUE if the registers used in aop form a pair (BC, DE, HL) */
+bool isPair(asmop *aop)
+{
+    return (getPairId(aop) != PAIR_INVALID);
+}
+
+bool isPtrPair(asmop *aop)
+{
+    PAIR_ID pairId = getPairId(aop);
+    switch (pairId) {
+    case PAIR_HL:
+    case PAIR_IY:
+    case PAIR_IX:
+       return TRUE;
+    default:
+       return FALSE;
+    }
+}
 /** Push a register pair onto the stack */
 void genPairPush(asmop *aop)
 {
     emitcode("push", "%s", getPairName(aop));
 }
 
 /** Push a register pair onto the stack */
 void genPairPush(asmop *aop)
 {
     emitcode("push", "%s", getPairName(aop));
 }
 
+
 /*-----------------------------------------------------------------*/
 /* newAsmop - creates a new asmOp                                  */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* newAsmop - creates a new asmOp                                  */
 /*-----------------------------------------------------------------*/
@@ -222,10 +338,16 @@ static asmop *newAsmop (short type)
 /*-----------------------------------------------------------------*/
 /* aopForSym - for a true symbol                                   */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* aopForSym - for a true symbol                                   */
 /*-----------------------------------------------------------------*/
-static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
+static asmop *aopForSym (iCode *ic,symbol *sym,bool result, bool requires_a)
 {
     asmop *aop;
 {
     asmop *aop;
-    memmap *space= SPEC_OCLS(sym->etype);
+    memmap *space;
+
+    wassert(ic);
+    wassert(sym);
+    wassert(sym->etype);
+
+    space = SPEC_OCLS(sym->etype);
 
     /* if already has one */
     if (sym->aop)
 
     /* if already has one */
     if (sym->aop)
@@ -233,9 +355,9 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 
     /* Assign depending on the storage class */
     if (sym->onStack || sym->iaccess) {
 
     /* Assign depending on the storage class */
     if (sym->onStack || sym->iaccess) {
+       emitcode("", "; AOP_STK for %s", sym->rname);
         sym->aop = aop = newAsmop(AOP_STK);
         aop->size = getSize(sym->type);
         sym->aop = aop = newAsmop(AOP_STK);
         aop->size = getSize(sym->type);
-
        aop->aopu.aop_stk = sym->stack;
         return aop;
     }
        aop->aopu.aop_stk = sym->stack;
         return aop;
     }
@@ -251,20 +373,24 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 
     if (IS_GB) {
        /* if it is in direct space */
 
     if (IS_GB) {
        /* if it is in direct space */
-       if (IN_DIRSPACE(space)) {
-           sym->aop = aop = newAsmop (AOP_DIR);
+       if (IN_REGSP(space) && !requires_a) {
+           sym->aop = aop = newAsmop (AOP_SFR);
            aop->aopu.aop_dir = sym->rname ;
            aop->size = getSize(sym->type);
            aop->aopu.aop_dir = sym->rname ;
            aop->size = getSize(sym->type);
-           emitcode("", "; AOP_DIR for %s", sym->rname);
+           emitcode("", "; AOP_SFR for %s", sym->rname);
            return aop;
        }
     }
 
     /* only remaining is far space */
     /* in which case DPTR gets the address */
            return aop;
        }
     }
 
     /* only remaining is far space */
     /* in which case DPTR gets the address */
-    sym->aop = aop = newAsmop(AOP_IY);
-    if (!IS_GB)
-       emitcode ("ld","iy,#%s ; a", sym->rname);
+    if (IS_GB) {
+       emitcode("", "; AOP_HL for %s", sym->rname);
+       sym->aop = aop = newAsmop(AOP_HL);
+    }
+    else {
+       sym->aop = aop = newAsmop(AOP_IY);
+    }
     aop->size = getSize(sym->type);
     aop->aopu.aop_dir = sym->rname;
 
     aop->size = getSize(sym->type);
     aop->aopu.aop_dir = sym->rname;
 
@@ -287,6 +413,7 @@ static asmop *aopForRemat (symbol *sym)
     while (1) {
         /* if plus or minus print the right hand side */
         if (ic->op == '+' || ic->op == '-') {
     while (1) {
         /* if plus or minus print the right hand side */
         if (ic->op == '+' || ic->op == '-') {
+           /* PENDING: for re-target */
             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
                     ic->op );
             s += strlen(s);
             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
                     ic->op );
             s += strlen(s);
@@ -390,12 +517,16 @@ bool sameRegs (asmop *aop1, asmop *aop2 )
 {
     int i;
 
 {
     int i;
 
-    if (aop1 == aop2)
-        return TRUE ;
+    if (aop1->type == AOP_SFR ||
+       aop2->type == AOP_SFR)
+       return FALSE;
+
+    if (aop1 == aop2) 
+        return TRUE;
 
     if (aop1->type != AOP_REG ||
         aop2->type != AOP_REG )
 
     if (aop1->type != AOP_REG ||
         aop2->type != AOP_REG )
-        return FALSE ;
+        return FALSE;
 
     if (aop1->size != aop2->size)
         return FALSE ;
 
     if (aop1->size != aop2->size)
         return FALSE ;
@@ -411,7 +542,7 @@ bool sameRegs (asmop *aop1, asmop *aop2 )
 /*-----------------------------------------------------------------*/
 /* aopOp - allocates an asmop for an operand  :                    */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* aopOp - allocates an asmop for an operand  :                    */
 /*-----------------------------------------------------------------*/
-static void aopOp (operand *op, iCode *ic, bool result)
+static void aopOp (operand *op, iCode *ic, bool result, bool requires_a)
 {
     asmop *aop;
     symbol *sym;
 {
     asmop *aop;
     symbol *sym;
@@ -440,7 +571,7 @@ static void aopOp (operand *op, iCode *ic, bool result)
 
     /* if this is a true symbol */
     if (IS_TRUE_SYMOP(op)) {    
 
     /* if this is a true symbol */
     if (IS_TRUE_SYMOP(op)) {    
-        op->aop = aopForSym(ic,OP_SYMBOL(op),result);
+        op->aop = aopForSym(ic, OP_SYMBOL(op), result, requires_a);
         return ;
     }
 
         return ;
     }
 
@@ -475,11 +606,22 @@ static void aopOp (operand *op, iCode *ic, bool result)
 
        if (sym->accuse) {
            int i;
 
        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->accuse == ACCUSE_A) {
+               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];
+           }
+           else if (sym->accuse == ACCUSE_HL) {
+               wassert(!IS_GB);
+               aop = op->aop = sym->aop = newAsmop(AOP_HLREG);
+               aop->size = getSize(sym->type);
+               for ( i = 0 ; i < 2 ; i++ )
+                   aop->aopu.aop_str[i] = hlUse[i];
+           }
+           else
+               wassert(0);
+           return;
        }
 
         if (sym->ruonly ) {
        }
 
         if (sym->ruonly ) {
@@ -493,7 +635,7 @@ static void aopOp (operand *op, iCode *ic, bool result)
 
         /* else spill location  */
         sym->aop = op->aop = aop = 
 
         /* else spill location  */
         sym->aop = op->aop = aop = 
-                                  aopForSym(ic,sym->usl.spillLoc,result);
+                                  aopForSym(ic,sym->usl.spillLoc,result, requires_a);
         aop->size = getSize(sym->type);
         return;
     }
         aop->size = getSize(sym->type);
         return;
     }
@@ -525,11 +667,6 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic)
 
     aop->freed = 1;
 
 
     aop->freed = 1;
 
-    switch (aop->type) {
-    case AOP_STK :
-       break;
-    }
-
 dealloc:
     /* all other cases just dealloc */
     if (op ) {
 dealloc:
     /* all other cases just dealloc */
     if (op ) {
@@ -543,55 +680,262 @@ dealloc:
     }
 }
 
     }
 }
 
-char *aopGetWordLong(asmop *aop, int offset, bool with_hash)
+bool isLitWord(asmop *aop)
+{
+    /*    if (aop->size != 2)
+         return FALSE;*/
+    switch (aop->type) {
+    case AOP_IMMD:
+    case AOP_LIT:
+       return TRUE;
+    default:
+       return FALSE;
+    }
+}
+
+char *aopGetLitWordLong(asmop *aop, int offset, bool with_hash)
 {
     char *s = buffer ;
     char *rs;
 
 {
     char *s = buffer ;
     char *rs;
 
-    if (aop->size != 2)
+#if 0
+    if (aop->size != 2 && aop->type != AOP_HL)
        return NULL;
        return NULL;
-    assert(offset == 0);
-
+#endif
     /* depending on type */
     switch (aop->type) {
     /* depending on type */
     switch (aop->type) {
+    case AOP_HL:
+    case AOP_IY:
     case AOP_IMMD:
     case AOP_IMMD:
-       sprintf (s,"%s%s",with_hash ? "#" : "", aop->aopu.aop_immd);
+       /* PENDING: for re-target */
+       if (with_hash)
+           tsprintf(s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
+       else
+           tsprintf(s, "%s + %d", aop->aopu.aop_immd, offset);
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
-       
     case AOP_LIT: {
        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);
     case AOP_LIT: {
        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);
-
-           sprintf(buffer,"%s0x%04lx", with_hash ? "#" : "", v);
+           if (offset == 2)
+               v >>= 16;
+           if (with_hash)
+               tsprintf(buffer, "!immedword", v);
+           else
+               tsprintf(buffer, "!constword", v);
+           ALLOC_ATOMIC(rs,strlen(buffer)+1);
+           return strcpy (rs,buffer);
+       }
+       else {
+           /* A float */
+           Z80_FLOAT f;
+           convertFloat(&f, floatFromVal(val));
+           if (with_hash) 
+               tsprintf(buffer, "!immedword", f.w[offset/2]);
+           else
+               tsprintf(buffer, "!constword", f.w[offset/2]);
            ALLOC_ATOMIC(rs,strlen(buffer)+1);
            return strcpy (rs,buffer);
        }
            ALLOC_ATOMIC(rs,strlen(buffer)+1);
            return strcpy (rs,buffer);
        }
-       assert(0);
-       return NULL;
     }
     }
+    default:
+       return NULL;
     }
     }
-    return NULL;
 }
 
 char *aopGetWord(asmop *aop, int offset)
 {
 }
 
 char *aopGetWord(asmop *aop, int offset)
 {
-    return aopGetWordLong(aop, offset, TRUE);
+    return aopGetLitWordLong(aop, offset, TRUE);
+}
+
+bool isPtr(const char *s) 
+{
+    if (!strcmp(s, "hl"))
+       return TRUE;
+    if (!strcmp(s, "ix"))
+       return TRUE;
+    if (!strcmp(s, "iy"))
+       return TRUE;
+    return FALSE;
+}
+
+static void adjustPair(const char *pair, int *pold, int new)
+{
+    wassert(pair);
+
+    while (*pold < new) {
+       emitcode("inc", "%s", pair);
+       (*pold)++;
+    }
+    while (*pold > new) {
+       emitcode("dec", "%s", pair);
+       (*pold)--;
+    }
+}
+
+static void spillPair(PAIR_ID pairId)
+{
+    _G.pairs[pairId].last_type = AOP_INVALID;
+    _G.pairs[pairId].lit = NULL;
+}
+
+static void spillCached(void)
+{
+    spillPair(PAIR_HL);
+    spillPair(PAIR_IY);
+}
+
+static bool requiresHL(asmop *aop)
+{
+    switch (aop->type) {
+    case AOP_HL:
+    case AOP_STK:
+       return TRUE;
+    default:
+       return FALSE;
+    }
+}
+
+static void fetchLitPair(PAIR_ID pairId, asmop *left, int offset)
+{
+    const char *l;
+    const char *pair = _pairs[pairId].name;
+    l = aopGetLitWordLong(left, offset, FALSE);
+    wassert(l && pair);
+
+    if (isPtr(pair)) {
+       if (pairId == PAIR_HL || pairId == PAIR_IY) {
+           if (_G.pairs[pairId].last_type == left->type) {
+               if (_G.pairs[pairId].lit && !strcmp(_G.pairs[pairId].lit, l)) {
+                   if (pairId == PAIR_HL && abs(_G.pairs[pairId].offset - offset) < 3) {
+                       adjustPair(pair, &_G.pairs[pairId].offset, offset);
+                       return;
+                   }
+                   if (pairId == PAIR_IY && abs(offset)<127) {
+                       return;
+                   }
+               }
+           }
+       }
+       _G.pairs[pairId].last_type = left->type;
+       _G.pairs[pairId].lit = gc_strdup(l);
+       _G.pairs[pairId].offset = offset;
+    }
+    /* Both a lit on the right and a true symbol on the left */
+    /* PENDING: for re-target */
+#if 0
+    if (offset)
+       emit2("ld %s,!hashedstr + %d", pair, l, offset);
+    else 
+#endif
+       emit2("ld %s,!hashedstr", pair, l);
+}
+
+static void fetchPairLong(PAIR_ID pairId, asmop *aop, int offset)
+{
+    /* if this is remateriazable */
+    if (isLitWord(aop)) {
+       fetchLitPair(pairId, aop, offset);
+    }
+    else { /* we need to get it byte by byte */
+       if (pairId == PAIR_HL && IS_GB && requiresHL(aop)) {
+           aopGet(aop, offset, FALSE);
+           switch (aop->size) {
+           case 1:
+               emit2("ld l,!*hl");
+               emit2("ld h,!immedbyte", 0);
+               break;
+           case 2:
+               emit2("!ldahli");
+               emit2("ld h,!*hl");
+               emit2("ld l,a");
+               break;
+           default:
+               emit2("; WARNING: mlh woosed out.  This code is invalid.");
+           }
+       }
+       else if (IS_Z80 && aop->type == AOP_IY) {
+           /* Instead of fetching relative to IY, just grab directly
+              from the address IY refers to */
+           char *l = aopGetLitWordLong(aop, offset, FALSE);
+           wassert(l);
+           emit2("ld %s,(%s)", _pairs[pairId].name, l);
+       }
+       else {
+           emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, offset, FALSE));
+           emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, offset+1, FALSE));
+       }
+       /* PENDING: check? */
+       if (pairId == PAIR_HL)
+           spillPair(PAIR_HL);
+    }
+}
+
+static void fetchPair(PAIR_ID pairId, asmop *aop)
+{
+    fetchPairLong(pairId, aop, 0);
+}
+
+static void fetchHL(asmop *aop)
+{
+    fetchPair(PAIR_HL, aop);
+}
+
+static void setupPair(PAIR_ID pairId, asmop *aop, int offset)
+{
+    assert(pairId == PAIR_HL || pairId == PAIR_IY);
+
+    switch (aop->type) {
+    case AOP_IY:
+       fetchLitPair(pairId, aop, 0);
+       break;
+    case AOP_HL:
+       fetchLitPair(pairId, aop, offset);
+       _G.pairs[pairId].offset = offset;
+       break;
+    case AOP_STK: {
+       /* Doesnt include _G.stack.pushed */
+       int abso = aop->aopu.aop_stk + offset + _G.stack.offset;
+       if (aop->aopu.aop_stk > 0) {
+           abso += _G.stack.param_offset;
+       }
+       assert(pairId == PAIR_HL);
+       /* In some cases we can still inc or dec hl */
+       if (_G.pairs[pairId].last_type == AOP_STK && abs(_G.pairs[pairId].offset - abso) < 3) {
+           adjustPair(_pairs[pairId].name, &_G.pairs[pairId].offset, abso);
+       }
+       else {
+           emit2("!ldahlsp", abso +_G.stack.pushed);
+       }
+       _G.pairs[pairId].offset = abso;
+       break;
+    }
+    default:
+       wassert(0);
+    }
+    _G.pairs[pairId].last_type = aop->type;
+}
+
+static void emitLabel(int key)
+{
+    emit2("!tlabeldef", key);
+    spillCached();
 }
 
 /*-----------------------------------------------------------------*/
 /* aopGet - for fetching value of the aop                          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* aopGet - for fetching value of the aop                          */
 /*-----------------------------------------------------------------*/
-static char *aopGet (asmop *aop, int offset, bool bit16)
+static char *aopGet(asmop *aop, int offset, bool bit16)
 {
     char *s = buffer ;
     char *rs;
 
     /* offset is greater than size then zero */
 {
     char *s = buffer ;
     char *rs;
 
     /* offset is greater than size then zero */
+    /* PENDING: this seems a bit screwed in some pointer cases. */
     if (offset > (aop->size - 1) &&
         aop->type != AOP_LIT)
         return zero;
     if (offset > (aop->size - 1) &&
         aop->type != AOP_LIT)
         return zero;
@@ -599,61 +943,84 @@ static char *aopGet (asmop *aop, int offset, bool bit16)
     /* depending on type */
     switch (aop->type) {
     case AOP_IMMD:
     /* depending on type */
     switch (aop->type) {
     case AOP_IMMD:
+       /* PENDING: re-target */
        if (bit16) 
        if (bit16) 
-           sprintf (s,"#%s",aop->aopu.aop_immd);
+           tsprintf (s,"!immedwords", aop->aopu.aop_immd);
        else
        else
-           if (offset) {
-               assert(offset == 1);
-               sprintf(s,"#>%s",
-                       aop->aopu.aop_immd);
+           switch (offset) {
+           case 2:
+               tsprintf(s, "!bankimmeds", aop->aopu.aop_immd);
+               break;
+           case 1:
+               tsprintf(s, "!msbimmeds", aop->aopu.aop_immd);
+               break;
+           case 0:
+               tsprintf(s, "!lsbimmeds", aop->aopu.aop_immd);
+               break;
+           default:
+               wassert(0);
            }
            }
-           else
-               sprintf(s,"#<%s",
-                       aop->aopu.aop_immd);
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
     case AOP_DIR:
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
     case AOP_DIR:
-       assert(IS_GB);
+       wassert(IS_GB);
        emitcode("ld", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
        sprintf(s, "a");
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
        emitcode("ld", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
        sprintf(s, "a");
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
+    case AOP_SFR:
+       wassert(IS_GB);
+       emitcode("ldh", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
+       sprintf(s, "a");
+       ALLOC_ATOMIC(rs,strlen(s)+1);
+       strcpy(rs,s);   
+       return rs;
+
     case AOP_REG:
        return aop->aopu.aop_reg[offset]->name;
 
     case AOP_REG:
        return aop->aopu.aop_reg[offset]->name;
 
+    case AOP_HL:
+       wassert(IS_GB);
+       setupPair(PAIR_HL, aop, offset);
+       tsprintf(s, "!*hl");
+       return gc_strdup(s);
+
     case AOP_IY:
     case AOP_IY:
-       sprintf(s,"%d(iy)", offset);
+       wassert(IS_Z80);
+       setupPair(PAIR_IY, aop, offset);
+       tsprintf(s,"!*iyx", offset);
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
 
     case AOP_STK:
        if (IS_GB) {
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
 
     case AOP_STK:
        if (IS_GB) {
-           /* We cant really optimise this as we cant afford to
-              change the flags.
-           */
-           emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset);
-           sprintf(s, "(hl)");
+           setupPair(PAIR_HL, aop, offset);
+           tsprintf(s, "!*hl");
        }
        else {
        }
        else {
-           sprintf(s,"%d(ix) ; %u", aop->aopu.aop_stk+offset, offset);
+           tsprintf(s,"!*ixx", aop->aopu.aop_stk+offset);
        }
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
     case AOP_CRY:
        }
        ALLOC_ATOMIC(rs,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
        
     case AOP_CRY:
-       assert(0);
+       wassert(0);
        
     case AOP_ACC:
        if (!offset) {
            return "a";
        }
        
     case AOP_ACC:
        if (!offset) {
            return "a";
        }
-       return "#0x00";
+       return "!zero";
+
+    case AOP_HLREG:
+       wassert(offset < 2);
+       return aop->aopu.aop_str[offset];
 
     case AOP_LIT:
        return aopLiteral (aop->aopu.aop_lit,offset);
 
     case AOP_LIT:
        return aopLiteral (aop->aopu.aop_lit,offset);
@@ -661,16 +1028,14 @@ static char *aopGet (asmop *aop, int offset, bool bit16)
     case AOP_STR:
        aop->coff = offset;
        return aop->aopu.aop_str[offset];
     case AOP_STR:
        aop->coff = offset;
        return aop->aopu.aop_str[offset];
+    default:
+       break;
     }
     }
-
-    fprintf(stderr, "Type %u\n", aop->type);
-
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "aopget got unsupported aop->type");
+    wassertl(0, "aopget got unsupported aop->type");
     exit(0);
 }
 
     exit(0);
 }
 
-bool isRegString(char *s)
+bool isRegString(const char *s)
 {
     if (!strcmp(s, "b") ||
        !strcmp(s, "c") ||
 {
     if (!strcmp(s, "b") ||
        !strcmp(s, "c") ||
@@ -683,12 +1048,13 @@ bool isRegString(char *s)
     return FALSE;
 }
 
     return FALSE;
 }
 
-bool isConstant(char *s)
+bool isConstant(const char *s)
 {
 {
-    return  (*s == '#');
+    /* This is a bit of a hack... */
+    return  (*s == '#' || *s == '$');
 }
 
 }
 
-bool canAssignToPtr(char *s)
+bool canAssignToPtr(const char *s)
 {
     if (isRegString(s))
        return TRUE;
 {
     if (isRegString(s))
        return TRUE;
@@ -700,7 +1066,7 @@ bool canAssignToPtr(char *s)
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                */
 /*-----------------------------------------------------------------*/
-static void aopPut (asmop *aop, char *s, int offset)
+static void aopPut (asmop *aop, const char *s, int offset)
 {
     if (aop->size && offset > ( aop->size - 1)) {
         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
 {
     if (aop->size && offset > ( aop->size - 1)) {
         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
@@ -713,61 +1079,83 @@ static void aopPut (asmop *aop, char *s, int offset)
     switch (aop->type) {
     case AOP_DIR:
        /* Direct.  Hmmm. */
     switch (aop->type) {
     case AOP_DIR:
        /* Direct.  Hmmm. */
-       assert(IS_GB);
-       emitcode("ld", "a,%s", s);
+       wassert(IS_GB);
+       if (strcmp(s, "a"))
+           emitcode("ld", "a,%s", s);
        emitcode("ld", "(%s+%d),a", aop->aopu.aop_dir, offset);
        break;
        
        emitcode("ld", "(%s+%d),a", aop->aopu.aop_dir, offset);
        break;
        
+    case AOP_SFR:
+       wassert(IS_GB);
+       if (strcmp(s, "a"))
+           emitcode("ld", "a,%s", s);
+       emitcode("ldh", "(%s+%d),a", aop->aopu.aop_dir, offset);
+       break;
+       
     case AOP_REG:
     case AOP_REG:
-       /* Dont bother if it's a ld x,x */
-       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
-           emitcode("ld","%s,%s",
-                    aop->aopu.aop_reg[offset]->name,s);
-       }
+       if (!strcmp(s, "!*hl"))
+           emit2("ld %s,!*hl", aop->aopu.aop_reg[offset]->name);
+       else
+           emit2("ld %s,%s",
+                 aop->aopu.aop_reg[offset]->name, s);
        break;
        
     case AOP_IY:
        break;
        
     case AOP_IY:
-       assert(!IS_GB);
+       wassert(!IS_GB);
+       setupPair(PAIR_IY, aop, offset);
        if (!canAssignToPtr(s)) {
        if (!canAssignToPtr(s)) {
-           emitcode("ld", "a,%s", s);
-           emitcode("ld", "%d(iy),a", offset);
+           emit2("ld a,%s", s);
+           emit2("ld !*iyx,a", offset);
        }
        else
        }
        else
-           emitcode("ld", "%d(iy),%s", offset, s);
+           emit2("ld !*iyx,%s", offset, s);
        break;
        break;
+    
+    case AOP_HL:
+       wassert(IS_GB);
+       /* PENDING: for re-target */
+       if (!strcmp(s, "!*hl") || !strcmp(s, "(hl)") || !strcmp(s, "[hl]")) {
+           emit2("ld a,!*hl");
+           s = "a";
+       }
+       setupPair(PAIR_HL, aop, offset);
        
        
+       emit2("ld !*hl,%s", s);
+       break;
+
     case AOP_STK:
        if (IS_GB) {
     case AOP_STK:
        if (IS_GB) {
-           if (!strcmp("(hl)", s)) {
-               emitcode("ld", "a,(hl)");
+           /* PENDING: re-target */
+           if (!strcmp(s, "!*hl") || !strcmp(s, "(hl)") || !strcmp(s, "[hl]")) {
+               emit2("ld a,!*hl");
                s = "a";
            }
                s = "a";
            }
-           emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset);
+           setupPair(PAIR_HL, aop, offset);
            if (!canAssignToPtr(s)) {
            if (!canAssignToPtr(s)) {
-               emitcode("ld", "a,%s", s);
-               emitcode("ld", "(hl),a");
+               emit2("ld a,%s", s);
+               emit2("ld !*hl,a");
            }
            else
            }
            else
-               emitcode("ld", "(hl),%s", s);
+               emit2("ld !*hl,%s", s);
        }
        else {
            if (!canAssignToPtr(s)) {
        }
        else {
            if (!canAssignToPtr(s)) {
-               emitcode("ld", "a,%s", s);
-               emitcode("ld", "%d(ix),a", aop->aopu.aop_stk+offset);
+               emit2("ld a,%s", s);
+               emit2("ld !*ixx,a", aop->aopu.aop_stk+offset);
            }
            else
            }
            else
-               emitcode("ld", "%d(ix),%s", aop->aopu.aop_stk+offset, s);
+               emit2("ld !*ixx,%s", aop->aopu.aop_stk+offset, s);
        }
        break;
        
     case AOP_CRY:
        /* if bit variable */
        if (!aop->aopu.aop_dir) {
        }
        break;
        
     case AOP_CRY:
        /* if bit variable */
        if (!aop->aopu.aop_dir) {
-           emitcode("ld", "a,#0");
-           emitcode("rla", "");
+           emit2("ld a,#0");
+           emit2("rla");
        } else {
            /* In bit space but not in C - cant happen */
        } else {
            /* In bit space but not in C - cant happen */
-           assert(0);
+           wassert(0);
        }
        break;
        
        }
        break;
        
@@ -792,6 +1180,11 @@ static void aopPut (asmop *aop, char *s, int offset)
        }
        break;
 
        }
        break;
 
+    case AOP_HLREG:
+       wassert(offset < 2);
+       emit2("ld %s,%s", aop->aopu.aop_str[offset], s);
+       break;
+
     default :
        werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
               "aopPut got unsupported aop->type");
     default :
        werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
               "aopPut got unsupported aop->type");
@@ -804,6 +1197,20 @@ static void aopPut (asmop *aop, char *s, int offset)
 #define AOP_SIZE(op) AOP(op)->size
 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY))
 
 #define AOP_SIZE(op) AOP(op)->size
 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY))
 
+static void commitPair(asmop *aop, PAIR_ID id)
+{
+    if (id == PAIR_HL && requiresHL(aop)) {
+       emit2("ld a,l");
+       emit2("ld d,h");
+       aopPut(aop, "a", 0);
+       aopPut(aop, "d", 1);
+    }
+    else {
+       aopPut(aop, _pairs[id].l, 0);
+       aopPut(aop, _pairs[id].h, 1);
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* getDataSize - get the operand data size                         */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* getDataSize - get the operand data size                         */
 /*-----------------------------------------------------------------*/
@@ -813,7 +1220,7 @@ int getDataSize(operand *op)
     size = AOP_SIZE(op);
     if(size == 3) {
         /* pointer */
     size = AOP_SIZE(op);
     if(size == 3) {
         /* pointer */
-       assert(0);
+       wassert(0);
     }
     return size;
 }
     }
     return size;
 }
@@ -832,7 +1239,7 @@ static void movLeft2Result (operand *left, int offl,
            aopPut(AOP(result),l,offr);
        }
        else {
            aopPut(AOP(result),l,offr);
        }
        else {
-           assert(0);
+           wassert(0);
         }
     }
 }
         }
     }
 }
@@ -850,7 +1257,7 @@ void outAcc(operand *result)
         offset = 1;
         /* unsigned or positive */
         while (size--){
         offset = 1;
         /* unsigned or positive */
         while (size--){
-            aopPut(AOP(result),zero,offset++);
+            aopPut(AOP(result), zero, offset++);
         }
     }
 }
         }
     }
 }
@@ -865,8 +1272,8 @@ void outBitC(operand *result)
         aopPut(AOP(result),"blah",0);
     }
     else {
         aopPut(AOP(result),"blah",0);
     }
     else {
-       emitcode("ld", "a,#0");
-       emitcode("rla", "");
+       emit2("ld a,!zero");
+       emit2("rla");
         outAcc(result);
     }
 }
         outAcc(result);
     }
 }
@@ -900,17 +1307,17 @@ static void genNot (iCode *ic)
     link *optype = operandType(IC_LEFT(ic));
 
     /* assign asmOps to operand & result */
     link *optype = operandType(IC_LEFT(ic));
 
     /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
+    aopOp (IC_LEFT(ic),ic,FALSE, TRUE);
+    aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
 
     /* if in bit space then a special case */
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
 
     /* if in bit space then a special case */
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
-       assert(0);
+       wassert(0);
     }
 
     /* if type float then do float */
     if (IS_FLOAT(optype)) {
     }
 
     /* if type float then do float */
     if (IS_FLOAT(optype)) {
-       assert(0);
+       wassert(0);
     }
 
     toBoolean(IC_LEFT(ic));
     }
 
     toBoolean(IC_LEFT(ic));
@@ -919,7 +1326,7 @@ static void genNot (iCode *ic)
        If A == 0, !A = 1
        else A = 0
        So if A = 0, A-1 = 0xFF and C is set, rotate C into reg. */
        If A == 0, !A = 1
        else A = 0
        So if A = 0, A-1 = 0xFF and C is set, rotate C into reg. */
-    emitcode("sub", "a,#0x01");
+    emit2("sub a,!one");
     outBitC(IC_RESULT(ic));
 
     /* release the aops */
     outBitC(IC_RESULT(ic));
 
     /* release the aops */
@@ -937,14 +1344,14 @@ static void genCpl (iCode *ic)
 
 
     /* assign asmOps to operand & result */
 
 
     /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
+    aopOp (IC_LEFT(ic),ic,FALSE, FALSE);
+    aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
 
     /* 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 ) { 
 
     /* 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 ) { 
-       assert(0);
+       wassert(0);
     } 
 
     size = AOP_SIZE(IC_RESULT(ic));
     } 
 
     size = AOP_SIZE(IC_RESULT(ic));
@@ -969,14 +1376,14 @@ static void genUminus (iCode *ic)
     link *optype, *rtype;
 
     /* assign asmops */
     link *optype, *rtype;
 
     /* assign asmops */
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    aopOp(IC_RESULT(ic),ic,TRUE);
+    aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
+    aopOp(IC_RESULT(ic),ic,TRUE, FALSE);
 
     /* if both in bit space then special
     case */
     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
 
     /* if both in bit space then special
     case */
     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
-       assert(0);
+       wassert(0);
         goto release;
     } 
 
         goto release;
     } 
 
@@ -985,7 +1392,7 @@ static void genUminus (iCode *ic)
 
     /* if float then do float stuff */
     if (IS_FLOAT(optype)) {
 
     /* if float then do float stuff */
     if (IS_FLOAT(optype)) {
-       assert(0);
+       wassert(0);
         goto release;
     }
 
         goto release;
     }
 
@@ -995,16 +1402,16 @@ static void genUminus (iCode *ic)
     CLRC ;
     while(size--) {
         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE);
     CLRC ;
     while(size--) {
         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE);
-       emitcode("ld", "a,#0");
-       emitcode("sbc","a,%s",l);
+       emit2("ld a,!zero");
+       emit2("sbc 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))))) {
         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("sbc","a,a");
+        emit2("rlc a");
+        emit2("sbc a,a");
         while (size--) 
             aopPut(AOP(IC_RESULT(ic)),"a",offset++);
     }       
         while (size--) 
             aopPut(AOP(IC_RESULT(ic)),"a",offset++);
     }       
@@ -1015,42 +1422,48 @@ release:
     freeAsmop(IC_RESULT(ic),NULL,ic);
 }
 
     freeAsmop(IC_RESULT(ic),NULL,ic);
 }
 
-static bool requiresHL(asmop *aop)
+static void _push(PAIR_ID pairId)
 {
 {
-    switch (aop->type) {
-    case AOP_STK:
-       return TRUE;
-    default:
-       return FALSE;
-    }
+    emit2("push %s", _pairs[pairId].name);
+    _G.stack.pushed += 2;
+}
+
+static void _pop(PAIR_ID pairId)
+{
+    emit2("pop %s", _pairs[pairId].name);
+    _G.stack.pushed -= 2;
 }
 
 }
 
+
 /*-----------------------------------------------------------------*/
 /* assignResultValue -                                            */
 /*-----------------------------------------------------------------*/
 void assignResultValue(operand * oper)
 {
 /*-----------------------------------------------------------------*/
 /* assignResultValue -                                            */
 /*-----------------------------------------------------------------*/
 void assignResultValue(operand * oper)
 {
-    int offset = 0;
     int size = AOP_SIZE(oper);
     int size = AOP_SIZE(oper);
+    bool topInA = 0;
 
 
-    assert(size <= 2);
+    wassert(size <= 4);
+    topInA = requiresHL(AOP(oper));
 
 
-    while (size--) {
-       aopPut(AOP(oper),_fReturn[offset],offset);
-       offset++;
-    }
-}
-
-static void fetchHL(asmop *aop)
-{
-    if (IS_GB && requiresHL(aop)) {
-       emitcode("ld", "a,%s", aopGet(aop, 0, FALSE));
-       emitcode("ld", "h,%s", aopGet(aop, 1, FALSE));
-       emitcode("ld", "l,a");
+#if 0
+    if (!IS_GB)
+       wassert(size <= 2);
+#endif
+    if (IS_GB && size == 4 && requiresHL(AOP(oper))) {
+       /* We do it the hard way here. */
+       _push(PAIR_HL);
+       aopPut(AOP(oper), _fReturn[0], 0);
+       aopPut(AOP(oper), _fReturn[1], 1);
+       emitcode("pop", "de");
+       _G.stack.pushed -= 2;
+       aopPut(AOP(oper), _fReturn[0], 2);
+       aopPut(AOP(oper), _fReturn[1], 3);
     }
     else {
     }
     else {
-       emitcode("ld", "l,%s", aopGet(aop, 0, FALSE));
-       emitcode("ld", "h,%s", aopGet(aop, 1, FALSE));
+       while (size--) {
+           aopPut(AOP(oper), _fReturn[size], size);
+       }
     }
 }
 
     }
 }
 
@@ -1062,7 +1475,6 @@ static void genIpush (iCode *ic)
     int size, offset = 0 ;
     char *l;
 
     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) {
     /* 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) {
@@ -1070,22 +1482,29 @@ static void genIpush (iCode *ic)
         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
             return ;
 
         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
             return ;
 
-        aopOp(IC_LEFT(ic),ic,FALSE);
+        aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
         size = AOP_SIZE(IC_LEFT(ic));
         /* push it on the stack */
        if (isPair(AOP(IC_LEFT(ic)))) {
            emitcode("push", getPairName(AOP(IC_LEFT(ic))));
         size = AOP_SIZE(IC_LEFT(ic));
         /* push it on the stack */
        if (isPair(AOP(IC_LEFT(ic)))) {
            emitcode("push", getPairName(AOP(IC_LEFT(ic))));
-           _pushed += 2;
+           _G.stack.pushed += 2;
        }
        else {
            offset = size;
            while (size--) {
        }
        else {
            offset = size;
            while (size--) {
-               l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
                /* Simple for now - load into A and PUSH AF */
                /* Simple for now - load into A and PUSH AF */
-               emitcode("ld", "a,%s", l);
-               emitcode("push", "af");
-               emitcode("inc", "sp");
-               _pushed++;
+               if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+                   char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+                   wassert(l);
+                   emit2("ld a,(%s)", l);
+               }
+               else {
+                   l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+                   emit2("ld a,%s", l);
+               }
+               emit2("push af");
+               emit2("inc sp");
+               _G.stack.pushed++;
            }
        }
        return ;        
            }
        }
        return ;        
@@ -1095,37 +1514,47 @@ static void genIpush (iCode *ic)
        at this point? */
 
     /* then do the push */
        at this point? */
 
     /* then do the push */
-    aopOp(IC_LEFT(ic),ic,FALSE);
+    aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
 
     size = AOP_SIZE(IC_LEFT(ic));
 
     if (isPair(AOP(IC_LEFT(ic)))) {
 
     size = AOP_SIZE(IC_LEFT(ic));
 
     if (isPair(AOP(IC_LEFT(ic)))) {
-       _pushed+=2;
+       _G.stack.pushed+=2;
        emitcode("push", "%s", getPairName(AOP(IC_LEFT(ic))));
     }
     else {
        if (size == 2) {
        emitcode("push", "%s", getPairName(AOP(IC_LEFT(ic))));
     }
     else {
        if (size == 2) {
-           char *s = aopGetWord(AOP(IC_LEFT(ic)), 0);
-           if (s) {
-               emitcode("ld", "hl,%s", s);
-               emitcode("push", "hl");
-               _pushed+=2;
-           }
-           else {
-               /* Optimise here - load into HL then push HL */
-               fetchHL(AOP(IC_LEFT(ic)));
-               emitcode("push", "hl");
-               _pushed += 2;
-           }
+           fetchHL(AOP(IC_LEFT(ic)));
+           emitcode("push", "hl");
+           spillPair(PAIR_HL);
+           _G.stack.pushed += 2;
+           goto release;
+       }
+       if (size == 4) {
+           fetchPairLong(PAIR_HL, AOP(IC_LEFT(ic)), 2);
+           emitcode("push", "hl");
+           spillPair(PAIR_HL);
+           _G.stack.pushed += 2;
+           fetchPairLong(PAIR_HL, AOP(IC_LEFT(ic)), 0);
+           emitcode("push", "hl");
+           spillPair(PAIR_HL);
+           _G.stack.pushed += 2;
            goto release;
        }
        offset = size;
        while (size--) {
            goto release;
        }
        offset = size;
        while (size--) {
-           l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
-           emitcode("ld", "a,%s", l);
+           if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+               char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+               wassert(l);
+               emit2("ld a,(%s)", l);
+           }
+           else {
+               l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+               emit2("ld a,%s", l);
+           }
            emitcode("push", "af");
            emitcode("inc", "sp");
            emitcode("push", "af");
            emitcode("inc", "sp");
-           _pushed++;
+           _G.stack.pushed++;
        }       
     }
  release:
        }       
     }
  release:
@@ -1144,7 +1573,7 @@ static void genIpop (iCode *ic)
     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
         return ;
 
     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
         return ;
 
-    aopOp(IC_LEFT(ic),ic,FALSE);
+    aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
     size = AOP_SIZE(IC_LEFT(ic));
     offset = (size-1);
     if (isPair(AOP(IC_LEFT(ic)))) {
     size = AOP_SIZE(IC_LEFT(ic));
     offset = (size-1);
     if (isPair(AOP(IC_LEFT(ic)))) {
@@ -1154,6 +1583,7 @@ static void genIpop (iCode *ic)
        while (size--) {
            emitcode("dec", "sp");
            emitcode("pop", "hl");
        while (size--) {
            emitcode("dec", "sp");
            emitcode("pop", "hl");
+           spillPair(PAIR_HL);
            aopPut(AOP(IC_LEFT(ic)), "l", offset--);
        }
     }
            aopPut(AOP(IC_LEFT(ic)), "l", offset--);
        }
     }
@@ -1161,63 +1591,190 @@ static void genIpop (iCode *ic)
     freeAsmop(IC_LEFT(ic),NULL,ic);
 }
 
     freeAsmop(IC_LEFT(ic),NULL,ic);
 }
 
+static int _isPairUsed(iCode *ic, PAIR_ID pairId)
+{
+    int ret = 0;
+    switch (pairId) {
+    case PAIR_DE:
+       if (bitVectBitValue(ic->rUsed, D_IDX))
+           ret++;
+       if (bitVectBitValue(ic->rUsed, E_IDX))
+           ret++;
+       break;
+    default:
+       wassert(0);
+    }
+    return ret;
+}
+
+static int _opUsesPair(operand *op, iCode *ic, PAIR_ID pairId)
+{
+    int ret = 0;
+    asmop *aop;
+    symbol *sym = OP_SYMBOL(op);
+
+    if (sym->isspilt || sym->nRegs == 0)
+       return 0;
+
+    aopOp(op, ic, FALSE, FALSE);
+    
+    aop = AOP(op);
+    if (aop->type == AOP_REG) {
+       int i;
+       for (i=0; i < aop->size; i++) {
+           if (pairId == PAIR_DE) {
+               emit2("; name %s", aop->aopu.aop_reg[i]->name);
+               if (!strcmp(aop->aopu.aop_reg[i]->name, "e"))
+                   ret++;
+               if (!strcmp(aop->aopu.aop_reg[i]->name, "d"))
+                   ret++;
+           }
+           else {
+               wassert(0);
+           }
+       }
+    }
+
+    freeAsmop(IC_LEFT(ic),NULL,ic);
+    return ret;
+}
+
+/* This is quite unfortunate */
+static void setArea(int inHome)
+{
+    static int lastArea = 0;
+    
+    if (lastArea != inHome) {
+       if (inHome) {
+           const char *sz = port->mem.code_name;
+           port->mem.code_name = "HOME";
+           emit2("!area", CODE_NAME);
+           port->mem.code_name = sz;
+       }
+       else
+           emit2("!area", CODE_NAME);
+       lastArea = inHome;
+    }
+}
+
 /** Emit the code for a call statement 
  */
 /** Emit the code for a call statement 
  */
-static void emitCall (iCode *ic, bool ispcall)
+static void emitCall(iCode *ic, bool ispcall)
 {
 {
-    int isPrintf = 0;
+    int pushed_de = 0;
+    link *detype = getSpec(operandType(IC_LEFT(ic)));
+
+    if (IS_BANKED(detype)) 
+       emit2("; call to a banked function");
 
     /* if caller saves & we have not saved then */
     if (!ic->regsSaved) {
        /* PENDING */
     }
 
     /* if caller saves & we have not saved then */
     if (!ic->regsSaved) {
        /* PENDING */
     }
-
+    
     /* if send set is not empty then assign */
     if (sendSet) {
     /* if send set is not empty then 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);
-               if (strcmp(l, _fReturn[offset]))
-                   emitcode("ld","%s,%s",
-                            _fReturn[offset],
-                            l);
-               offset++;
+       iCode *sic;
+       int send = 0;
+       int n = elementsInSet(sendSet);
+       if (IS_Z80 && n == 2 && _isPairUsed(ic, PAIR_DE)) {
+           /* Only push de if it is used and if it's not used
+              in the return value */
+           /* Panic if partly used */
+           if (_opUsesPair(IC_RESULT(ic), ic, PAIR_DE) == 1) {
+               emit2("; Warning: de crossover");
            }
            }
+           else if (!_opUsesPair(IC_RESULT(ic), ic, PAIR_DE)) {
+               /* Store away de */
+               _push(PAIR_DE);
+               pushed_de = 1;
+           }
+       }
+       /* PENDING: HACK */
+       if (IS_Z80 && n == 2 ) {
+           /* Want to load HL first, then DE as HL may = DE */
+           sic = setFirstItem(sendSet);
+           sic = setNextItem(sendSet);
+           aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
+           fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
+           send++;
            freeAsmop (IC_LEFT(sic),NULL,sic);
            freeAsmop (IC_LEFT(sic),NULL,sic);
+           sic = setFirstItem(sendSet);
+           aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
+           fetchPair(PAIR_DE, AOP(IC_LEFT(sic)));
+           send++;
+           freeAsmop (IC_LEFT(sic),NULL,sic);
+       }
+       else {
+           for (sic = setFirstItem(sendSet) ; sic ; 
+                sic = setNextItem(sendSet)) {
+               int size;
+               aopOp(IC_LEFT(sic),sic,FALSE, FALSE);
+               size = AOP_SIZE(IC_LEFT(sic));
+               wassert(size <= 2);
+               /* Always send in pairs */
+               switch (send) {
+               case 0:
+                   if (IS_Z80 && n == 1)
+                       fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
+                   else
+                       fetchPair(PAIR_DE, AOP(IC_LEFT(sic)));
+                   break;
+               case 1:
+                   fetchPair(PAIR_HL, AOP(IC_LEFT(sic)));
+                   break;
+               default:
+                   /* Send set too big */
+                   wassert(0);
+               }
+               send++;
+               freeAsmop (IC_LEFT(sic),NULL,sic);
+           }
        }
        sendSet = NULL;
        }
        sendSet = NULL;
+       if (pushed_de) {
+       }
     }
 
     if (ispcall) {
     }
 
     if (ispcall) {
-       symbol *rlbl = newiTempLabel(NULL);
-
-       emitcode("ld", "hl,#" LABEL_STR, (rlbl->key+100));
-       emitcode("push", "hl");
+       if (IS_BANKED(detype)) {
+           werror(W_INDIR_BANKED);
+       }
+       aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
 
 
-       aopOp(IC_LEFT(ic),ic,FALSE);
-       emitcode("ld", "l,%s", aopGet(AOP(IC_LEFT(ic)), 0,FALSE));
-       emitcode("ld", "h,%s", aopGet(AOP(IC_LEFT(ic)), 1,FALSE));
+       if (isLitWord(AOP(IC_LEFT(ic)))) {
+           emitcode("", "; Special case where the pCall is to a constant");
+           emitcode("call", aopGetLitWordLong(AOP(IC_LEFT(ic)), 0, FALSE));
+       }
+       else {
+           symbol *rlbl = newiTempLabel(NULL);
+           spillPair(PAIR_HL);
+           emit2("ld hl,!immed!tlabel", (rlbl->key+100));
+           emitcode("push", "hl");
+           _G.stack.pushed += 2;
+           
+           fetchHL(AOP(IC_LEFT(ic)));
+           emit2("jp !*hl");
+           emit2("!tlabeldef", (rlbl->key+100));
+           _G.stack.pushed -= 2;
+       }
        freeAsmop(IC_LEFT(ic),NULL,ic); 
        freeAsmop(IC_LEFT(ic),NULL,ic); 
-       
-       emitcode("jp", "(hl)");
-       emitcode("","%05d$:",(rlbl->key+100));
     }
     else {
     }
     else {
-       /* make the call */
        char *name = OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
            OP_SYMBOL(IC_LEFT(ic))->rname :
            OP_SYMBOL(IC_LEFT(ic))->name;
        char *name = OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
            OP_SYMBOL(IC_LEFT(ic))->rname :
            OP_SYMBOL(IC_LEFT(ic))->name;
-       emitcode("call", "%s", name);
-       if (!strcmp(name, "__printf"))
-           isPrintf = 1;
-
+       if (IS_BANKED(detype)) {
+           emit2("call banked_call");
+           emit2("!dws", name);
+           emit2("!dw !bankimmeds", name);
+       }
+       else {
+           /* make the call */
+           emit2("call %s", name);
+       }
     }
     }
+    spillCached();
 
     /* if we need assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic)) && 
 
     /* if we need assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic)) && 
@@ -1226,7 +1783,7 @@ static void emitCall (iCode *ic, bool ispcall)
         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
 
         accInUse++;
         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
 
         accInUse++;
-        aopOp(IC_RESULT(ic),ic,FALSE);
+        aopOp(IC_RESULT(ic),ic,FALSE, FALSE);
         accInUse--;
 
        assignResultValue(IC_RESULT(ic));
         accInUse--;
 
        assignResultValue(IC_RESULT(ic));
@@ -1237,25 +1794,30 @@ static void emitCall (iCode *ic, bool ispcall)
     /* adjust the stack for parameters if required */
     if (IC_LEFT(ic)->parmBytes) {
        int i = IC_LEFT(ic)->parmBytes;
     /* adjust the stack for parameters if required */
     if (IC_LEFT(ic)->parmBytes) {
        int i = IC_LEFT(ic)->parmBytes;
-       emitcode("", ";parmBytes = %u\n", i);
-       if (isPrintf)
-           i+=2;
-       _pushed -= i;
-       if (i>6) {
-           emitcode("ld", "hl,#%d", i);
-           emitcode("add", "hl,sp");
-           emitcode("ld", "sp,hl");
+       _G.stack.pushed -= i;
+       if (IS_GB) {
+           emit2("!ldaspsp", i);
        }
        else {
        }
        else {
-           while (i>1) {
-               emitcode("pop", "hl");
-               i-=2;
+           spillCached();
+           if (i>6) {
+               emitcode("ld", "hl,#%d", i);
+               emitcode("add", "hl,sp");
+               emitcode("ld", "sp,hl");
            }
            }
-           if (i) 
-               emitcode("inc", "sp");
+           else {
+               while (i>1) {
+                   emitcode("pop", "hl");
+                   i-=2;
+               }
+               if (i) 
+                   emitcode("inc", "sp");
+           }
+           spillCached();
        }
     }
        }
     }
-
+    if (pushed_de)
+       _pop(PAIR_DE);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1263,6 +1825,7 @@ static void emitCall (iCode *ic, bool ispcall)
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
+    link *detype = getSpec(operandType(IC_LEFT(ic)));
     emitCall(ic, FALSE);
 }
 
     emitCall(ic, FALSE);
 }
 
@@ -1296,49 +1859,70 @@ static int resultRemat (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genFunction (iCode *ic)
 {
 /*-----------------------------------------------------------------*/
 static void genFunction (iCode *ic)
 {
-    symbol *sym;
+    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
     link *fetype;
 
     nregssaved = 0;
     link *fetype;
 
     nregssaved = 0;
-    /* create the function header */
-    emitcode(";","-----------------------------------------");
-    emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
-    emitcode(";","-----------------------------------------");
+    setArea(IS_NONBANKED(sym->etype));
 
 
-    emitcode("","%s:",sym->rname);
+    /* create the function header */
+    emit2("!functionheader", sym->name);
+    /* PENDING: portability. */
+    emit2("__%s_start:", sym->rname);
+    emit2("!functionlabeldef", sym->rname);
+   
     fetype = getSpec(operandType(IC_LEFT(ic)));
     fetype = getSpec(operandType(IC_LEFT(ic)));
-
+    
     /* if critical function then turn interrupts off */
     if (SPEC_CRTCL(fetype))
     /* if critical function then turn interrupts off */
     if (SPEC_CRTCL(fetype))
-        emitcode("di","");
+       emit2("!di");
 
     /* if this is an interrupt service routine then
     save acc, b, dpl, dph  */
     if (IS_ISR(sym->etype)) {
 
     /* if this is an interrupt service routine then
     save acc, b, dpl, dph  */
     if (IS_ISR(sym->etype)) {
-       emitcode("push", "af");
-       emitcode("push", "bc");
-       emitcode("push", "de");
-       emitcode("push", "hl");
+       emit2("!pusha");
     }
     /* PENDING: callee-save etc */
 
     }
     /* PENDING: callee-save etc */
 
-    /* adjust the stack for the function */
-    emitcode("push", "bc");
-    if (!IS_GB) {
-       emitcode("push", "de");
-       emitcode("push", "ix");
-       emitcode("ld", "ix,#0");
-       emitcode("add", "ix,sp");
+    /* If BC or DE are used, then push */
+    _G.stack.pushed_bc = 0;
+    _G.stack.pushed_de = 0;
+    _G.stack.param_offset = 0;
+    if (sym->regsUsed) {
+       int i;
+       for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+           if (bitVectBitValue(sym->regsUsed, i)) {
+               switch (i) {
+               case C_IDX:
+               case B_IDX:
+                   _G.stack.pushed_bc = 1;
+                   break;
+               case D_IDX:
+               case E_IDX:
+                   if (IS_Z80)
+                       _G.stack.pushed_de = 1;
+                   break;
+               }
+           }
+       }
+       if (_G.stack.pushed_bc) {
+           emit2("push bc");
+           _G.stack.param_offset += 2;
+       }
+       if (_G.stack.pushed_de) {
+           emit2("push de");
+           _G.stack.param_offset += 2;
+       }
     }
 
     }
 
-    _lastStack = sym->stack;
+    /* adjust the stack for the function */
+    _G.stack.last = sym->stack;
 
 
-    if (sym->stack) {
-       emitcode("ld", "hl,#-%d", sym->stack);
-       emitcode("add", "hl,sp");
-       emitcode("ld", "sp,hl");
-    }
-    _spoffset = sym->stack;
+    if (sym->stack)
+       emit2("!enterx", sym->stack);
+    else
+       emit2("!enter");
+    _G.stack.offset = sym->stack;
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1349,11 +1933,11 @@ static void genEndFunction (iCode *ic)
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
     if (IS_ISR(sym->etype)) {
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
     if (IS_ISR(sym->etype)) {
-       assert(0);
+       wassert(0);
     }
     else {
         if (SPEC_CRTCL(sym->etype))
     }
     else {
         if (SPEC_CRTCL(sym->etype))
-            emitcode("ei", "");
+           emit2("!ei");
        
        /* PENDING: calleeSave */
 
        
        /* PENDING: calleeSave */
 
@@ -1369,23 +1953,23 @@ static void genEndFunction (iCode *ic)
                emitcode("","XG$%s$0$0 ==.",currFunc->name);
            debugLine = 0;
        }
                emitcode("","XG$%s$0$0 ==.",currFunc->name);
            debugLine = 0;
        }
-       if (!IS_GB) {
-           emitcode("ld", "sp,ix");
-           emitcode("pop", "ix");
-           emitcode("pop", "de");
-       }
-       else {
-           if (_spoffset) {
-               emitcode("ld", "hl,#%d", _spoffset);
-               emitcode("add", "hl,sp");
-               emitcode("ld", "sp,hl");
-           }
-       }
-       emitcode("pop", "bc");
-       emitcode("ret", "");
+       if (_G.stack.offset)
+           emit2("!leavex", _G.stack.offset);
+       else
+           emit2("!leave");
+
+       if (_G.stack.pushed_de)
+           emit2("pop de");
+       if (_G.stack.pushed_bc)
+           emit2("pop bc");
+       /* Both baned and non-banked just ret */
+       emit2("ret");
+       
+       /* PENDING: portability. */
+       emit2("__%s_end:", sym->rname);
     }
     }
-    _pushed = 0;
-    _spoffset = 0;
+    _G.stack.pushed = 0;
+    _G.stack.offset = 0;
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1405,18 +1989,29 @@ static void genRet (iCode *ic)
     
     /* we have something to return then
        move the return value into place */
     
     /* we have something to return then
        move the return value into place */
-    aopOp(IC_LEFT(ic),ic,FALSE);
+    aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
     size = AOP_SIZE(IC_LEFT(ic));
     
     if ((size == 2) && ((l = aopGetWord(AOP(IC_LEFT(ic)), 0)))) {
     size = AOP_SIZE(IC_LEFT(ic));
     
     if ((size == 2) && ((l = aopGetWord(AOP(IC_LEFT(ic)), 0)))) {
+       if (IS_GB) {
+           emitcode("ld", "de,%s", l);
+       }
+       else {
            emitcode("ld", "hl,%s", l);
            emitcode("ld", "hl,%s", l);
+       }
     }
     else {
     }
     else {
-       while (size--) {
-           l = aopGet(AOP(IC_LEFT(ic)),offset,
-                      FALSE);
-           if (strcmp(_fReturn[offset],l))
-               emitcode("ld","%s,%s", _fReturn[offset++],l);
+       if (IS_GB && size == 4 && requiresHL(AOP(IC_LEFT(ic)))) {
+           fetchPair(PAIR_DE, AOP(IC_LEFT(ic)));
+           fetchPairLong(PAIR_HL, AOP(IC_LEFT(ic)), 2);
+       }
+       else {
+           while (size--) {
+               l = aopGet(AOP(IC_LEFT(ic)),offset,
+                          FALSE);
+               if (strcmp(_fReturn[offset],l))
+                   emitcode("ld","%s,%s", _fReturn[offset++],l);
+           }
        }
     }
     freeAsmop (IC_LEFT(ic),NULL,ic);
        }
     }
     freeAsmop (IC_LEFT(ic),NULL,ic);
@@ -1427,7 +2022,7 @@ static void genRet (iCode *ic)
     if (!(ic->next && ic->next->op == LABEL &&
          IC_LABEL(ic->next) == returnLabel))
        
     if (!(ic->next && ic->next->op == LABEL &&
          IC_LABEL(ic->next) == returnLabel))
        
-       emitcode("jp",  LABEL_STR ,(returnLabel->key+100));
+       emit2("jp !tlabel", returnLabel->key+100);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1439,7 +2034,7 @@ static void genLabel (iCode *ic)
     if (IC_LABEL(ic) == entryLabel)
         return ;
 
     if (IC_LABEL(ic) == entryLabel)
         return ;
 
-    emitcode("", LABEL_STR ":",(IC_LABEL(ic)->key+100));
+    emitLabel(IC_LABEL(ic)->key+100);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1447,7 +2042,7 @@ static void genLabel (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genGoto (iCode *ic)
 {
 /*-----------------------------------------------------------------*/
 static void genGoto (iCode *ic)
 {
-    emitcode ("jp", LABEL_STR ,(IC_LABEL(ic)->key+100));
+    emit2("jp !tlabel", IC_LABEL(ic)->key+100);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1457,7 +2052,8 @@ static bool genPlusIncr (iCode *ic)
 {
     unsigned int icount ;
     unsigned int size = getDataSize(IC_RESULT(ic));
 {
     unsigned int icount ;
     unsigned int size = getDataSize(IC_RESULT(ic));
-    
+    PAIR_ID resultId = getPairId(AOP(IC_RESULT(ic)));
+
     /* will try to generate an increment */
     /* if the right side is not a literal 
        we cannot */
     /* will try to generate an increment */
     /* if the right side is not a literal 
        we cannot */
@@ -1467,55 +2063,56 @@ static bool genPlusIncr (iCode *ic)
     emitcode("", "; genPlusIncr");
 
     icount = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
     emitcode("", "; genPlusIncr");
 
     icount = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
-
+    
     /* If result is a pair */
     /* If result is a pair */
-    if (isPair(AOP(IC_RESULT(ic)))) {
-       char *left = aopGetWordLong(AOP(IC_LEFT(ic)), 0, FALSE);
-       if (left) {
-           /* Both a lit on the right and a true symbol on the left */
-           emitcode("ld", "%s,#%s + %d", getPairName(AOP(IC_RESULT(ic))), left, icount);
+    if (resultId != PAIR_INVALID) {
+       if (isLitWord(AOP(IC_LEFT(ic)))) {
+           fetchLitPair(getPairId(AOP(IC_RESULT(ic))), AOP(IC_LEFT(ic)), icount);
            return TRUE;
        }
            return TRUE;
        }
+       if (isPair(AOP(IC_LEFT(ic))) && resultId == PAIR_HL && icount > 2) {
+           fetchPair(resultId, AOP(IC_RIGHT(ic)));
+           emitcode("add", "hl,%s", getPairName(AOP(IC_LEFT(ic))));
+           return TRUE;
+       }
+       if (icount > 5)
+           return FALSE;
+       /* Inc a pair */
+       if (!sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+           if (icount > 2)
+               return FALSE;
+           movLeft2Result(IC_LEFT(ic), 0, IC_RESULT(ic), 0, 0);
+           movLeft2Result(IC_LEFT(ic), 1, IC_RESULT(ic), 1, 0);
+       }
+       while (icount--) {
+           emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic))));
+       }
+       return TRUE;
     }
 
     /* if the literal value of the right hand side
        is greater than 4 then it is not worth it */
     if (icount > 4)
     }
 
     /* if the literal value of the right hand side
        is greater than 4 then it is not worth it */
     if (icount > 4)
-        return FALSE ;
+        return FALSE;
 
 
-    /* Inc a pair */
-    if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
-       isPair(AOP(IC_RESULT(ic)))) {
-       while (icount--) {
-           emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic))));
-       }
-       return TRUE;
-    }
     /* if increment 16 bits in register */
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
     /* 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));
-       emitcode("jp", "nz," LABEL_STR ,tlbl->key+100);
-    
-       emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE));
-       if(size == 4) {
-           assert(0);
+        size > 1 &&
+        icount == 1
+       ) {
+       int offset = 0;
+       symbol *tlbl = NULL;
+       tlbl = newiTempLabel(NULL);
+       while (size--) {
+           emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)), offset++, FALSE));
+           if (size) {
+               emit2("!shortjp nz,!tlabel", tlbl->key+100);
+           }
        }
        }
-       emitcode("", LABEL_STR ":",tlbl->key+100);
+       emitLabel(tlbl->key+100);
         return TRUE;
     }
 
         return TRUE;
     }
 
-    /* If result is a pair */
-    if (isPair(AOP(IC_RESULT(ic)))) {
-       movLeft2Result(IC_LEFT(ic), 0, IC_RESULT(ic), 0, 0);
-       movLeft2Result(IC_LEFT(ic), 1, IC_RESULT(ic), 1, 0);
-       while (icount--)
-           emitcode("inc", "%s", getPairName(AOP(IC_RESULT(ic))));
-       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   )
     /* if the sizes are greater than 1 then we cannot */
     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
         AOP_SIZE(IC_LEFT(ic)) > 1   )
@@ -1527,7 +2124,6 @@ static bool genPlusIncr (iCode *ic)
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
        while (icount--)
            emitcode ("inc","%s",aopGet(AOP(IC_LEFT(ic)),0, FALSE));
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
        while (icount--)
            emitcode ("inc","%s",aopGet(AOP(IC_LEFT(ic)),0, FALSE));
-       
         return TRUE ;
     }
     
         return TRUE ;
     }
     
@@ -1542,12 +2138,12 @@ void outBitAcc(operand *result)
     symbol *tlbl = newiTempLabel(NULL);
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY){
     symbol *tlbl = newiTempLabel(NULL);
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY){
-       assert(0);
+       wassert(0);
     }
     else {
     }
     else {
-        emitcode("jp","z," LABEL_STR ,tlbl->key+100);
-        emitcode("ld","a,%s",one);
-        emitcode("", LABEL_STR ":",tlbl->key+100);
+        emit2("!shortjp z,!tlabel", tlbl->key+100);
+       emit2("ld a,!one");
+       emitLabel(tlbl->key+100);
         outAcc(result);
     }
 }
         outAcc(result);
     }
 }
@@ -1561,9 +2157,9 @@ static void genPlus (iCode *ic)
 
     /* special cases :- */
 
 
     /* special cases :- */
 
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RIGHT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
+    aopOp (IC_LEFT(ic),ic,FALSE, FALSE);
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE);
+    aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
 
     /* Swap the left and right operands if:
 
 
     /* Swap the left and right operands if:
 
@@ -1584,14 +2180,14 @@ static void genPlus (iCode *ic)
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
        /* Cant happen */
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
        /* Cant happen */
-       assert(0);
+       wassert(0);
     }
 
     /* if left in bit space & right literal */
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
        /* Can happen I guess */
     }
 
     /* if left in bit space & right literal */
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
         AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
        /* Can happen I guess */
-       assert(0);
+       wassert(0);
     }
 
     /* if I can do an increment instead
     }
 
     /* if I can do an increment instead
@@ -1599,14 +2195,16 @@ static void genPlus (iCode *ic)
     if (genPlusIncr (ic) == TRUE)
         goto release;   
 
     if (genPlusIncr (ic) == TRUE)
         goto release;   
 
+    emit2("; genPlusIncr failed");
+
     size = getDataSize(IC_RESULT(ic));
 
     /* Special case when left and right are constant */
     if (isPair(AOP(IC_RESULT(ic)))) {
        char *left, *right;
        
     size = getDataSize(IC_RESULT(ic));
 
     /* Special case when left and right are constant */
     if (isPair(AOP(IC_RESULT(ic)))) {
        char *left, *right;
        
-       left = aopGetWordLong(AOP(IC_LEFT(ic)), 0, FALSE);
-       right = aopGetWordLong(AOP(IC_RIGHT(ic)), 0, FALSE);
+       left = aopGetLitWordLong(AOP(IC_LEFT(ic)), 0, FALSE);
+       right = aopGetLitWordLong(AOP(IC_RIGHT(ic)), 0, FALSE);
        if (left && right) {
            /* It's a pair */
            /* PENDING: fix */
        if (left && right) {
            /* It's a pair */
            /* PENDING: fix */
@@ -1617,38 +2215,94 @@ static void genPlus (iCode *ic)
        }
     }
 
        }
     }
 
+    if (isPair(AOP(IC_RIGHT(ic))) && getPairId(AOP(IC_RESULT(ic))) == PAIR_HL) {
+       /* Fetch into HL then do the add */
+       spillPair(PAIR_HL);
+       fetchPair(PAIR_HL, AOP(IC_LEFT(ic)));
+       emitcode("add", "hl,%s", getPairName(AOP(IC_RIGHT(ic))));
+       goto release;
+    }
+
+    /* Special case:
+       ld hl,sp+n trashes C so we cant afford to do it during an
+       add with stack based varibles.  Worst case is:
+               ld  hl,sp+left
+       ld  a,(hl)
+       ld  hl,sp+right
+       add (hl)
+       ld  hl,sp+result
+       ld  (hl),a
+       ld  hl,sp+left+1
+       ld  a,(hl)
+       ld  hl,sp+right+1
+       adc (hl)
+       ld  hl,sp+result+1
+       ld  (hl),a
+       So you cant afford to load up hl if either left, right, or result
+       is on the stack (*sigh*)  The alt is:
+       ld  hl,sp+left
+       ld  de,(hl)
+       ld  hl,sp+right
+       ld  hl,(hl)
+       add hl,de
+       ld  hl,sp+result
+       ld  (hl),hl
+       Combinations in here are:
+        * If left or right are in bc then the loss is small - trap later
+        * If the result is in bc then the loss is also small
+    */
+    if (IS_GB) {
+       if (AOP_TYPE(IC_LEFT(ic)) == AOP_STK ||
+           AOP_TYPE(IC_RIGHT(ic)) == AOP_STK ||
+           AOP_TYPE(IC_RESULT(ic)) == AOP_STK) {
+           if ((AOP_SIZE(IC_LEFT(ic)) == 2 ||
+               AOP_SIZE(IC_RIGHT(ic)) == 2) &&
+               (AOP_SIZE(IC_LEFT(ic)) <= 2 &&
+                AOP_SIZE(IC_RIGHT(ic)) <= 2)) {
+               if (getPairId(AOP(IC_RIGHT(ic))) == PAIR_BC) {
+                   /* Swap left and right */
+                   operand *t = IC_RIGHT(ic);
+                   IC_RIGHT(ic) = IC_LEFT(ic);
+                   IC_LEFT(ic) = t;
+               }
+               if (getPairId(AOP(IC_LEFT(ic))) == PAIR_BC) {
+                   fetchPair(PAIR_HL, AOP(IC_RIGHT(ic)));
+                   emit2("add hl,bc");
+               }
+               else {
+                   fetchPair(PAIR_DE, AOP(IC_LEFT(ic)));
+                   fetchPair(PAIR_HL, AOP(IC_RIGHT(ic)));
+                   emit2("add hl,de");
+               }
+               commitPair(AOP(IC_RESULT(ic)), PAIR_HL);
+               goto release;
+           }
+           else if (size == 4) {
+               emit2("; WARNING: This add is probably broken.\n");
+           }
+       }
+    }
+
     while(size--) {
        if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
            MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE));
            if(offset == 0)
     while(size--) {
        if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
            MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE));
            if(offset == 0)
-               emitcode("add","a,%s",
-                        aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
+               emit2("add a,%s",
+                     aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
            else
            else
-               emitcode("adc","a,%s",
-                        aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
+               emit2("adc a,%s",
+                     aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
        } else {
        } else {
-           MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
+           MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE));
            if(offset == 0)
            if(offset == 0)
-               emitcode("add","a,%s",
-                        aopGet(AOP(IC_LEFT(ic)),offset,FALSE));
+               emit2("add a,%s",
+                     aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
            else
            else
-               emitcode("adc","a,%s",
-                        aopGet(AOP(IC_LEFT(ic)),offset,FALSE));
+               emit2("adc a,%s",
+                     aopGet(AOP(IC_RIGHT(ic)),offset,FALSE));
        }
        }
-        aopPut(AOP(IC_RESULT(ic)),"a",offset++);      
+       aopPut(AOP(IC_RESULT(ic)),"a",offset++);      
     }
     }
-
-    /* Some kind of pointer arith. */
-    if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
-       AOP_SIZE(IC_LEFT(ic)) == 3   &&
-       !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
-       assert(0);
-
-     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
-       AOP_SIZE(IC_RIGHT(ic)) == 3   &&
-       !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
-        assert(0);
-
    
 release:
     freeAsmop(IC_LEFT(ic),NULL,ic);
    
 release:
     freeAsmop(IC_LEFT(ic),NULL,ic);
@@ -1688,9 +2342,9 @@ static bool genMinusDec (iCode *ic)
     
        emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE));
        if(size == 4) {
     
        emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE));
        if(size == 4) {
-           assert(0);
+           wassert(0);
        }
        }
-       emitcode("", LABEL_STR ":",tlbl->key+100);
+       emitLabel(tlbl->key+100);
         return TRUE;
     }
 #endif
         return TRUE;
     }
 #endif
@@ -1736,15 +2390,15 @@ static void genMinus (iCode *ic)
     int size, offset = 0;
     unsigned long lit = 0L;
 
     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);
+    aopOp (IC_LEFT(ic),ic,FALSE, FALSE);
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE);
+    aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
 
     /* 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) {
 
     /* 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) {
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
         goto release ;
     }
 
@@ -1761,7 +2415,47 @@ static void genMinus (iCode *ic)
         lit = - (long)lit;
     }
 
         lit = - (long)lit;
     }
 
-
+    /* Same logic as genPlus */
+    if (IS_GB) {
+       if (AOP_TYPE(IC_LEFT(ic)) == AOP_STK ||
+           AOP_TYPE(IC_RIGHT(ic)) == AOP_STK ||
+           AOP_TYPE(IC_RESULT(ic)) == AOP_STK) {
+           if ((AOP_SIZE(IC_LEFT(ic)) == 2 ||
+               AOP_SIZE(IC_RIGHT(ic)) == 2) &&
+               (AOP_SIZE(IC_LEFT(ic)) <= 2 &&
+                AOP_SIZE(IC_RIGHT(ic)) <= 2)) {
+               PAIR_ID left = getPairId(AOP(IC_LEFT(ic)));
+               PAIR_ID right = getPairId(AOP(IC_RIGHT(ic)));
+
+               if (left == PAIR_INVALID && right == PAIR_INVALID) {
+                   left = PAIR_DE;
+                   right = PAIR_HL;
+               }
+               else if (right == PAIR_INVALID)
+                   right = PAIR_DE;
+               else if (left == PAIR_INVALID)
+                   left = PAIR_DE;
+               
+               fetchPair(left, AOP(IC_LEFT(ic)));
+               /* Order is important.  Right may be HL */
+               fetchPair(right, AOP(IC_RIGHT(ic)));
+
+               emit2("ld a,%s", _pairs[left].l);
+               emit2("sub a,%s", _pairs[right].l);
+               emit2("ld e,a");
+               emit2("ld a,%s", _pairs[left].h);
+               emit2("sbc a,%s", _pairs[right].h);
+
+               aopPut(AOP(IC_RESULT(ic)), "a", 1);
+               aopPut(AOP(IC_RESULT(ic)), "e", 0);
+               goto release;
+           }
+           else if (size == 4) {
+               emit2("; WARNING: This sub is probably broken.\n");
+           }
+       }
+    }
+    
     /* if literal, add a,#-lit, else normal subb */
     while (size--) {
        MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE));    
     /* if literal, add a,#-lit, else normal subb */
     while (size--) {
        MOVA(aopGet(AOP(IC_LEFT(ic)),offset,FALSE));    
@@ -1776,11 +2470,9 @@ static void genMinus (iCode *ic)
        else{
            /* first add without previous c */
            if (!offset)
        else{
            /* first add without previous c */
            if (!offset)
-               emitcode("add","a,#0x%02x",
-                        (unsigned int)(lit & 0x0FFL));
+               emit2("add a,!immedbyte", (unsigned int)(lit & 0x0FFL));
            else
            else
-               emitcode("adc","a,#0x%02x",
-                        (unsigned int)((lit >> (offset*8)) & 0x0FFL));
+               emit2("adc a,!immedbyte", (unsigned int)((lit >> (offset*8)) & 0x0FFL));
        }
        aopPut(AOP(IC_RESULT(ic)),"a",offset++);      
     }
        }
        aopPut(AOP(IC_RESULT(ic)),"a",offset++);      
     }
@@ -1788,7 +2480,7 @@ static void genMinus (iCode *ic)
     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
        AOP_SIZE(IC_LEFT(ic)) == 3   &&
        !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
     if (AOP_SIZE(IC_RESULT(ic)) == 3 && 
        AOP_SIZE(IC_LEFT(ic)) == 3   &&
        !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
-       assert(0);
+       wassert(0);
 
 release:
     freeAsmop(IC_LEFT(ic),NULL,ic);
 
 release:
     freeAsmop(IC_LEFT(ic),NULL,ic);
@@ -1802,7 +2494,7 @@ release:
 static void genMult (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
 static void genMult (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
-    assert(0);
+    wassert(0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1811,7 +2503,7 @@ static void genMult (iCode *ic)
 static void genDiv (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
 static void genDiv (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
-    assert(0);
+    wassert(0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1820,7 +2512,7 @@ static void genDiv (iCode *ic)
 static void genMod (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
 static void genMod (iCode *ic)
 {
     /* Shouldn't occur - all done through function calls */
-    assert(0);
+    wassert(0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1869,7 +2561,7 @@ static void genIfxJump (iCode *ic, char *jval)
     else {
        emitcode("bit", "%s,a", jval);
     }
     else {
        emitcode("bit", "%s,a", jval);
     }
-    emitcode("jp", "%s," LABEL_STR , inst, jlbl->key+100);
+    emit2("jp %s,!tlabel", inst, jlbl->key+100);
 
     /* mark the icode as generated */
     ic->generated = 1;
 
     /* mark the icode as generated */
     ic->generated = 1;
@@ -1887,7 +2579,7 @@ static void genCmp (operand *left,operand *right,
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
        /* Cant happen on the Z80 */
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
        /* Cant happen on the Z80 */
-       assert(0);
+       wassert(0);
     } else {
         /* subtract right from left if at the
         end the carry flag is set then we know that
     } else {
         /* subtract right from left if at the
         end the carry flag is set then we know that
@@ -1899,11 +2591,11 @@ static void genCmp (operand *left,operand *right,
            (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
            emitcode("ld", "a,%s", aopGet(AOP(left), offset, FALSE));
            if (sign) {
            (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
            emitcode("ld", "a,%s", aopGet(AOP(left), offset, FALSE));
            if (sign) {
-               emitcode("xor", "a,#0x80");
-               emitcode("cp", "%s^0x80", aopGet(AOP(right), offset, FALSE));
+               emit2("xor a,!immedbyte", 0x80);
+               emit2("cp %s^!constbyte", aopGet(AOP(right), offset, FALSE), 0x80);
            }
            else 
            }
            else 
-               emitcode("cp", "%s ; 7", aopGet(AOP(right), offset, FALSE));
+               emitcode("cp", "%s", aopGet(AOP(right), offset, FALSE));
         } 
        else {
             if(AOP_TYPE(right) == AOP_LIT) {
         } 
        else {
             if(AOP_TYPE(right) == AOP_LIT) {
@@ -1933,24 +2625,24 @@ static void genCmp (operand *left,operand *right,
                if (AOP_TYPE(left) == AOP_LIT){
                    unsigned long lit = (unsigned long)
                        floatFromVal(AOP(left)->aopu.aop_lit);
                if (AOP_TYPE(left) == AOP_LIT){
                    unsigned long lit = (unsigned long)
                        floatFromVal(AOP(left)->aopu.aop_lit);
-                   emitcode("ld", "%s,#0x%02x", _fTmp[0],
+                   emit2("ld %s,!immedbyte", _fTmp[0],
                             0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL));
                }
                else {
                    emitcode("ld", "a,%s", aopGet(AOP(left), size-1, FALSE));
                             0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL));
                }
                else {
                    emitcode("ld", "a,%s", aopGet(AOP(left), size-1, FALSE));
-                   emitcode("xor", "a,#0x80");
+                   emit2("xor a,!immedbyte", 0x80);
                    emitcode("ld", "%s,a", _fTmp[0]);
                    fDidXor = TRUE;
                }
                if (AOP_TYPE(right) == AOP_LIT) {
                    unsigned long lit = (unsigned long)
                        floatFromVal(AOP(right)->aopu.aop_lit);
                    emitcode("ld", "%s,a", _fTmp[0]);
                    fDidXor = TRUE;
                }
                if (AOP_TYPE(right) == AOP_LIT) {
                    unsigned long lit = (unsigned long)
                        floatFromVal(AOP(right)->aopu.aop_lit);
-                   emitcode("ld", "%s,#0x%02x", _fTmp[1],
+                   emit2("ld %s,!immedbyte", _fTmp[1],
                             0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL));
                }
                else {
                    emitcode("ld", "a,%s", aopGet(AOP(right), size-1, FALSE));
                             0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL));
                }
                else {
                    emitcode("ld", "a,%s", aopGet(AOP(right), size-1, FALSE));
-                   emitcode("xor", "a,#0x80");
+                   emit2("xor a,!immedbyte", 0x80);
                    emitcode("ld", "%s,a", _fTmp[1]);
                    fDidXor = TRUE;
                }
                    emitcode("ld", "%s,a", _fTmp[1]);
                    fDidXor = TRUE;
                }
@@ -1962,15 +2654,16 @@ static void genCmp (operand *left,operand *right,
            }
             while (size--) {
                /* Do a long subtract */
            }
             while (size--) {
                /* Do a long subtract */
-               if (!sign || size
+               if (!sign || size ) {
                    MOVA(aopGet(AOP(left),offset,FALSE));
                    MOVA(aopGet(AOP(left),offset,FALSE));
+               }
                 if (sign && size == 0) {
                    emitcode("ld", "a,%s", _fTmp[0]);
                    emitcode("sbc", "a,%s", _fTmp[1]);
                }
                else {
                    /* Subtract through, propagating the carry */
                 if (sign && size == 0) {
                    emitcode("ld", "a,%s", _fTmp[0]);
                    emitcode("sbc", "a,%s", _fTmp[1]);
                }
                else {
                    /* Subtract through, propagating the carry */
-                   emitcode("sbc","a,%s",aopGet(AOP(right),offset++,FALSE));
+                   emitcode("sbc","a,%s ; 2",aopGet(AOP(right),offset++,FALSE));
                }
             }
         }
                }
             }
         }
@@ -2008,9 +2701,9 @@ static void genCmpGt (iCode *ic, iCode *ifx)
     retype =getSpec(operandType(right));
     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
     /* assign the amsops */
     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);
+    aopOp (left,ic,FALSE, FALSE);
+    aopOp (right,ic,FALSE, FALSE);
+    aopOp (result,ic,TRUE, FALSE);
 
     genCmp(right, left, result, ifx, sign);
 
 
     genCmp(right, left, result, ifx, sign);
 
@@ -2037,9 +2730,9 @@ static void genCmpLt (iCode *ic, iCode *ifx)
     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
 
     /* assign the amsops */
     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
 
     /* assign the amsops */
-    aopOp (left,ic,FALSE);
-    aopOp (right,ic,FALSE);
-    aopOp (result,ic,TRUE);
+    aopOp (left,ic,FALSE, FALSE);
+    aopOp (right,ic,FALSE, FALSE);
+    aopOp (result,ic,TRUE, FALSE);
 
     genCmp(left, right, result, ifx, sign);
 
 
     genCmp(left, right, result, ifx, sign);
 
@@ -2070,15 +2763,31 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
     /* if the right side is a literal then anything goes */
     if (AOP_TYPE(right) == AOP_LIT &&
         AOP_TYPE(left) != AOP_DIR ) {
     /* if the right side is a literal then anything goes */
     if (AOP_TYPE(right) == AOP_LIT &&
         AOP_TYPE(left) != AOP_DIR ) {
-        while (size--) {
-           emitcode("ld", "a,%s ; 2", aopGet(AOP(left),offset,FALSE));
-           if ((AOP_TYPE(right) == AOP_LIT) && lit == 0)
+       if (lit == 0) {
+           emitcode("ld", "a,%s", aopGet(AOP(left), offset, FALSE));
+           if (size > 1) {
+               size--;
+               offset++;
+               while (size--) {
+                   emitcode("or", "a,%s", aopGet(AOP(left), offset, FALSE));
+               }
+           }
+           else {
                emitcode("or", "a,a");
                emitcode("or", "a,a");
-           else 
-               emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE));
-            emitcode("jp", "nz," LABEL_STR , lbl->key+100);
-            offset++;
-        }
+           }
+           emit2("jp nz,!tlabel", lbl->key+100);
+       }
+       else {
+           while (size--) {
+               emitcode("ld", "a,%s ; 2", aopGet(AOP(left),offset,FALSE));
+               if ((AOP_TYPE(right) == AOP_LIT) && lit == 0)
+                   emitcode("or", "a,a");
+               else 
+                   emitcode("cp", "a,%s", aopGet(AOP(right),offset,FALSE));
+               emit2("jp nz,!tlabel", 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 */    
     }
     /* if the right side is in a register or in direct space or
     if the left is a pointer register & right is not */    
@@ -2090,10 +2799,10 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
             if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
                ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
                /* PENDING */
             if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
                ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
                /* PENDING */
-                emitcode("jp","nz," LABEL_STR ,lbl->key+100);
+                emit2("jp nz,!tlabel", lbl->key+100);
             else {
                emitcode("cp", "%s ; 4", aopGet(AOP(right),offset,FALSE));
             else {
                emitcode("cp", "%s ; 4", aopGet(AOP(right),offset,FALSE));
-               emitcode("jp", "nz," LABEL_STR , lbl->key+100);
+               emit2("jp nz,!tlabel", lbl->key+100);
            }
             offset++;
         }
            }
             offset++;
         }
@@ -2101,10 +2810,9 @@ static void gencjneshort(operand *left, operand *right, symbol *lbl)
         /* right is a pointer reg need both a & b */
        /* PENDING: is this required? */
         while(size--) {
         /* right is a pointer reg need both a & b */
        /* PENDING: is this required? */
         while(size--) {
-            char *l = aopGet(AOP(left),offset,FALSE);
             MOVA(aopGet(AOP(right),offset,FALSE));
             MOVA(aopGet(AOP(right),offset,FALSE));
-           emitcode("cp", "%s ; 5", l);
-           emitcode("jr", "nz," LABEL_STR, lbl->key+100);
+           emitcode("cp", "%s ; 5", aopGet(AOP(left), offset, FALSE));
+           emit2("!shortjp nz,!tlabel", lbl->key+100);
             offset++;
         }
     }
             offset++;
         }
     }
@@ -2120,11 +2828,11 @@ static void gencjne(operand *left, operand *right, symbol *lbl)
     gencjneshort(left, right, lbl);
 
     /* PENDING: ?? */
     gencjneshort(left, right, lbl);
 
     /* PENDING: ?? */
-    emitcode("ld","a,%s",one);
-    emitcode("jp", LABEL_STR ,tlbl->key+100);
-    emitcode("", LABEL_STR ":",lbl->key+100);
+    emit2("ld a,!one");
+    emit2("!shortjp !tlabel", tlbl->key+100);
+    emitLabel(lbl->key+100);
     emitcode("xor","a,a");
     emitcode("xor","a,a");
-    emitcode("", LABEL_STR ":",tlbl->key+100);
+    emitLabel(tlbl->key+100);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2134,9 +2842,9 @@ static void genCmpEq (iCode *ic, iCode *ifx)
 {
     operand *left, *right, *result;
 
 {
     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);
+    aopOp((left=IC_LEFT(ic)),ic,FALSE, FALSE);
+    aopOp((right=IC_RIGHT(ic)),ic,FALSE, FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE);
 
     /* Swap operands if it makes the operation easier. ie if:
        1.  Left is a literal.
 
     /* Swap operands if it makes the operation easier. ie if:
        1.  Left is a literal.
@@ -2152,20 +2860,20 @@ static void genCmpEq (iCode *ic, iCode *ifx)
         /* if they are both bit variables */
         if (AOP_TYPE(left) == AOP_CRY &&
             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
         /* if they are both bit variables */
         if (AOP_TYPE(left) == AOP_CRY &&
             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-           assert(0);
+           wassert(0);
         } else {
             tlbl = newiTempLabel(NULL);
             gencjneshort(left, right, tlbl);
             if ( IC_TRUE(ifx) ) {
         } else {
             tlbl = newiTempLabel(NULL);
             gencjneshort(left, right, tlbl);
             if ( IC_TRUE(ifx) ) {
-                emitcode("jp", LABEL_STR ,IC_TRUE(ifx)->key+100);
-                emitcode("", LABEL_STR ":",tlbl->key+100);                
+               emit2("jp !tlabel", IC_TRUE(ifx)->key+100);
+               emitLabel(tlbl->key+100);
             } else {
                /* PENDING: do this better */
                 symbol *lbl = newiTempLabel(NULL);
             } else {
                /* PENDING: do this better */
                 symbol *lbl = newiTempLabel(NULL);
-                emitcode("jp", LABEL_STR ,lbl->key+100);
-                emitcode("", LABEL_STR ":",tlbl->key+100);                
-                emitcode("jp", LABEL_STR ,IC_FALSE(ifx)->key+100);
-                emitcode("", LABEL_STR ":",lbl->key+100);             
+               emit2("!shortjp !tlabel", lbl->key+100);
+                emitLabel(tlbl->key+100);
+                emit2("jp !tlabel", IC_FALSE(ifx)->key+100);
+               emitLabel(lbl->key+100);             
             }
         }
         /* mark the icode as generated */
             }
         }
         /* mark the icode as generated */
@@ -2176,11 +2884,11 @@ static void genCmpEq (iCode *ic, iCode *ifx)
     /* if they are both bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
     /* if they are both bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
-       assert(0);
+       wassert(0);
     } else {
         gencjne(left,right,newiTempLabel(NULL));    
         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
     } else {
         gencjne(left,right,newiTempLabel(NULL));    
         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
-           assert(0);
+           wassert(0);
         }
         if (ifx) {
            genIfxJump(ifx,"a");
         }
         if (ifx) {
            genIfxJump(ifx,"a");
@@ -2232,20 +2940,20 @@ static void genAndOp (iCode *ic)
     /* note here that && operations that are in an if statement are
        taken away by backPatchLabels only those used in arthmetic
        operations remain */
     /* 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);
+    aopOp((left=IC_LEFT(ic)),ic,FALSE, TRUE);
+    aopOp((right=IC_RIGHT(ic)),ic,FALSE, TRUE);
+    aopOp((result=IC_RESULT(ic)),ic,FALSE, FALSE);
 
     /* if both are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
 
     /* if both are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
-       assert(0);
+       wassert(0);
     } else {
         tlbl = newiTempLabel(NULL);
         toBoolean(left);    
     } else {
         tlbl = newiTempLabel(NULL);
         toBoolean(left);    
-        emitcode("jp","z," LABEL_STR ,tlbl->key+100);
+       emit2("!shortjp z,!tlabel", tlbl->key+100);
         toBoolean(right);
         toBoolean(right);
-        emitcode("", LABEL_STR ":",tlbl->key+100);
+       emitLabel(tlbl->key+100);
         outBitAcc(result);
     }
 
         outBitAcc(result);
     }
 
@@ -2265,20 +2973,20 @@ static void genOrOp (iCode *ic)
     /* note here that || operations that are in an
        if statement are taken away by backPatchLabels
        only those used in arthmetic operations remain */
     /* 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);
+    aopOp((left=IC_LEFT(ic)),ic,FALSE, TRUE);
+    aopOp((right=IC_RIGHT(ic)),ic,FALSE, TRUE);
+    aopOp((result=IC_RESULT(ic)),ic,FALSE, FALSE);
 
     /* if both are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
 
     /* if both are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
         AOP_TYPE(right) == AOP_CRY ) {
-       assert(0);
+       wassert(0);
     } else {
         tlbl = newiTempLabel(NULL);
         toBoolean(left);
     } else {
         tlbl = newiTempLabel(NULL);
         toBoolean(left);
-        emitcode("jp","nz," LABEL_STR,tlbl->key+100);
+       emit2("!shortjp nz,!tlabel", tlbl->key+100);
         toBoolean(right);
         toBoolean(right);
-        emitcode("", LABEL_STR,tlbl->key+100);
+       emitLabel(tlbl->key+100);
         outBitAcc(result);
     }
 
         outBitAcc(result);
     }
 
@@ -2307,6 +3015,26 @@ int isLiteralBit(unsigned long lit)
     return 0;
 }
 
     return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* jmpTrueOrFalse -                                                */
+/*-----------------------------------------------------------------*/
+static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
+{
+    // ugly but optimized by peephole
+    if(IC_TRUE(ic)){
+        symbol *nlbl = newiTempLabel(NULL);
+       emit2("jp !tlabel", nlbl->key+100);                 
+        emitLabel(tlbl->key+100);
+       emit2("jp !tlabel", IC_TRUE(ic)->key+100);
+        emitLabel(nlbl->key+100);
+    }
+    else{
+       emit2("jp !tlabel", IC_FALSE(ic)->key+100);
+        emitLabel(tlbl->key+100);
+    }
+    ic->generated = 1;
+}
+
 /*-----------------------------------------------------------------*/
 /* genAnd  - code for and                                          */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* genAnd  - code for and                                          */
 /*-----------------------------------------------------------------*/
@@ -2317,9 +3045,9 @@ static void genAnd (iCode *ic, iCode *ifx)
     unsigned long lit = 0L;
     int bytelit = 0;
 
     unsigned long lit = 0L;
     int bytelit = 0;
 
-    aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
+    aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE);
+    aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE);
 
 #ifdef DEBUG_TYPE
     emitcode("","; Type res[%d] = l[%d]&r[%d]",
 
 #ifdef DEBUG_TYPE
     emitcode("","; Type res[%d] = l[%d]&r[%d]",
@@ -2358,7 +3086,7 @@ static void genAnd (iCode *ic, iCode *ifx)
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
         goto release ;
     }
 
@@ -2374,7 +3102,7 @@ static void genAnd (iCode *ic, iCode *ifx)
             MOVA(aopGet(AOP(left),posbit>>3,FALSE));
             // bit = left & 2^n
             if(size) {
             MOVA(aopGet(AOP(left),posbit>>3,FALSE));
             // bit = left & 2^n
             if(size) {
-               assert(0);
+               wassert(0);
                 emitcode("mov","c,acc.%d",posbit&0x07);
            }
             // if(left &  2^n)
                 emitcode("mov","c,acc.%d",posbit&0x07);
            }
             // if(left &  2^n)
@@ -2384,7 +3112,7 @@ static void genAnd (iCode *ic, iCode *ifx)
                     genIfxJump(ifx, buffer);
                 }
                else {
                     genIfxJump(ifx, buffer);
                 }
                else {
-                   assert(0);
+                   wassert(0);
                }
                 goto release;
             }
                }
                 goto release;
             }
@@ -2392,7 +3120,7 @@ static void genAnd (iCode *ic, iCode *ifx)
             symbol *tlbl = newiTempLabel(NULL);
             int sizel = AOP_SIZE(left);
             if(size) {
             symbol *tlbl = newiTempLabel(NULL);
             int sizel = AOP_SIZE(left);
             if(size) {
-               assert(0);
+               wassert(0);
                 emitcode("setb","c");
            }
             while(sizel--){
                 emitcode("setb","c");
            }
             while(sizel--){
@@ -2400,14 +3128,17 @@ static void genAnd (iCode *ic, iCode *ifx)
                     MOVA( aopGet(AOP(left),offset,FALSE));
                     // byte ==  2^n ?
                     if((posbit = isLiteralBit(bytelit)) != 0) {
                     MOVA( aopGet(AOP(left),offset,FALSE));
                     // byte ==  2^n ?
                     if((posbit = isLiteralBit(bytelit)) != 0) {
-                       assert(0);
+                       wassert(0);
                         emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100);
                    }
                     else{
                         if(bytelit != 0x0FFL)
                             emitcode("and","a,%s",
                                      aopGet(AOP(right),offset,FALSE));
                         emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100);
                    }
                     else{
                         if(bytelit != 0x0FFL)
                             emitcode("and","a,%s",
                                      aopGet(AOP(right),offset,FALSE));
-                        emitcode("jr","nz, %05d$",tlbl->key+100);
+                       else
+                           /* For the flags */
+                           emit2("or a,a");
+                        emit2("!shortjp nz,!tlabel", tlbl->key+100);
                     }
                 }
                 offset++;
                     }
                 }
                 offset++;
@@ -2415,16 +3146,12 @@ static void genAnd (iCode *ic, iCode *ifx)
             // bit = left & literal
             if (size){
                 emitcode("clr","c");
             // bit = left & literal
             if (size){
                 emitcode("clr","c");
-                emitcode("","%05d$:",tlbl->key+100);
+               emit2("!tlabeldef", tlbl->key+100);
             }
             // if(left & literal)
             else{
                 if(ifx)
             }
             // if(left & literal)
             else{
                 if(ifx)
-#if 0
                     jmpTrueOrFalse(ifx, tlbl);
                     jmpTrueOrFalse(ifx, tlbl);
-#else
-               assert(0);
-#endif
                 goto release ;
             }
         }
                 goto release ;
             }
         }
@@ -2445,25 +3172,26 @@ static void genAnd (iCode *ic, iCode *ifx)
                        MOVA(aopGet(AOP(left),offset,FALSE));
                        emitcode("and","a,%s",
                                 aopGet(AOP(right),offset,FALSE));
                        MOVA(aopGet(AOP(left),offset,FALSE));
                        emitcode("and","a,%s",
                                 aopGet(AOP(right),offset,FALSE));
-                       emitcode("ld", "%s,a", aopGet(AOP(left),offset,FALSE));
+                       aopPut(AOP(left), "a", offset);
                    }
                }
 
             } else {
                if (AOP_TYPE(left) == AOP_ACC) {
                    }
                }
 
             } else {
                if (AOP_TYPE(left) == AOP_ACC) {
-                   assert(0);
+                   wassert(0);
                }
                else {
                }
                else {
-                   MOVA(aopGet(AOP(right),offset,FALSE));
-                   emitcode("and","%s,a",
-                            aopGet(AOP(left),offset,FALSE));
+                   MOVA(aopGet(AOP(left),offset,FALSE));
+                   emitcode("and","a,%s",
+                            aopGet(AOP(right),offset,FALSE));
+                   aopPut(AOP(left), "a", offset);
                }
             }
         }
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
                }
             }
         }
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
-           assert(0);
+           wassert(0);
         } else {
            for(;(size--);offset++) {
                // normal case
         } else {
            for(;(size--);offset++) {
                // normal case
@@ -2484,9 +3212,9 @@ static void genAnd (iCode *ic, iCode *ifx)
                if (AOP_TYPE(left) == AOP_ACC) 
                    emitcode("and","a,%s",aopGet(AOP(right),offset,FALSE));
                else {
                if (AOP_TYPE(left) == AOP_ACC) 
                    emitcode("and","a,%s",aopGet(AOP(right),offset,FALSE));
                else {
-                   MOVA(aopGet(AOP(right),offset,FALSE));
+                   MOVA(aopGet(AOP(left),offset,FALSE));
                    emitcode("and","a,%s",
                    emitcode("and","a,%s",
-                            aopGet(AOP(left),offset,FALSE));
+                            aopGet(AOP(right),offset,FALSE));
                }
                aopPut(AOP(result),"a",offset);
            }
                }
                aopPut(AOP(result),"a",offset);
            }
@@ -2509,9 +3237,9 @@ static void genOr (iCode *ic, iCode *ifx)
     int size, offset=0;
     unsigned long lit = 0L;
 
     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);
+    aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE);
+    aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE);
 
 #if 1
     emitcode("","; Type res[%d] = l[%d]&r[%d]",
 
 #if 1
     emitcode("","; Type res[%d] = l[%d]&r[%d]",
@@ -2550,14 +3278,14 @@ static void genOr (iCode *ic, iCode *ifx)
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
     if((AOP_TYPE(right) == AOP_LIT) &&
        (AOP_TYPE(result) == AOP_CRY) &&
        (AOP_TYPE(left) != AOP_CRY)){
         goto release ;
     }
 
     if((AOP_TYPE(right) == AOP_LIT) &&
        (AOP_TYPE(result) == AOP_CRY) &&
        (AOP_TYPE(left) != AOP_CRY)){
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
         goto release ;
     }
 
@@ -2567,25 +3295,27 @@ static void genOr (iCode *ic, iCode *ifx)
             if(AOP_TYPE(right) == AOP_LIT){
                 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
                     continue;
             if(AOP_TYPE(right) == AOP_LIT){
                 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
                     continue;
-                else 
-                   emitcode("or","%s,%s; 5",
-                            aopGet(AOP(left),offset,FALSE),
+                else {
+                   MOVA(aopGet(AOP(left),offset,FALSE));
+                   emitcode("or","a,%s",
                             aopGet(AOP(right),offset,FALSE));
                             aopGet(AOP(right),offset,FALSE));
+                   aopPut(AOP(result),"a", offset);
+               }
             } else {
                if (AOP_TYPE(left) == AOP_ACC) 
             } else {
                if (AOP_TYPE(left) == AOP_ACC) 
-                   emitcode("or","a,%s ; 6",aopGet(AOP(right),offset,FALSE));
+                   emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE));
                else {              
                else {              
-                   MOVA(aopGet(AOP(right),offset,FALSE));
-                   emitcode("or","a,%s ; 7",
-                            aopGet(AOP(left),offset,FALSE));
-                   aopPut(AOP(result),"a ; 8",0);
+                   MOVA(aopGet(AOP(left),offset,FALSE));
+                   emitcode("or","a,%s",
+                            aopGet(AOP(right),offset,FALSE));
+                   aopPut(AOP(result),"a", offset);
                }
             }
         }
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
                }
             }
         }
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
-           assert(0);
+           wassert(0);
         } else for(;(size--);offset++){
             // normal case
             // result = left & right
         } else for(;(size--);offset++){
             // normal case
             // result = left & right
@@ -2602,9 +3332,9 @@ static void genOr (iCode *ic, iCode *ifx)
            if (AOP_TYPE(left) == AOP_ACC) 
                emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE));
            else {
            if (AOP_TYPE(left) == AOP_ACC) 
                emitcode("or","a,%s",aopGet(AOP(right),offset,FALSE));
            else {
-               MOVA(aopGet(AOP(right),offset,FALSE));
+               MOVA(aopGet(AOP(left),offset,FALSE));
                emitcode("or","a,%s",
                emitcode("or","a,%s",
-                        aopGet(AOP(left),offset,FALSE));
+                        aopGet(AOP(right),offset,FALSE));
            }
            aopPut(AOP(result),"a",offset);                     
            /* PENDING: something weird is going on here.  Add exception. */
            }
            aopPut(AOP(result),"a",offset);                     
            /* PENDING: something weird is going on here.  Add exception. */
@@ -2628,9 +3358,9 @@ static void genXor (iCode *ic, iCode *ifx)
     int size, offset=0;
     unsigned long lit = 0L;
 
     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);
+    aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE);
+    aopOp((right= IC_RIGHT(ic)),ic,FALSE, FALSE);
+    aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE);
 
     /* if left is a literal & right is not then exchange them */
     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
 
     /* if left is a literal & right is not then exchange them */
     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
@@ -2660,14 +3390,14 @@ static void genXor (iCode *ic, iCode *ifx)
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
     size = AOP_SIZE(result);
 
     if (AOP_TYPE(left) == AOP_CRY){
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
     if((AOP_TYPE(right) == AOP_LIT) &&
        (AOP_TYPE(result) == AOP_CRY) &&
        (AOP_TYPE(left) != AOP_CRY)){
         goto release ;
     }
 
     if((AOP_TYPE(right) == AOP_LIT) &&
        (AOP_TYPE(result) == AOP_CRY) &&
        (AOP_TYPE(left) != AOP_CRY)){
-       assert(0);
+       wassert(0);
         goto release ;
     }
 
         goto release ;
     }
 
@@ -2697,7 +3427,7 @@ static void genXor (iCode *ic, iCode *ifx)
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
     } else {
         // left & result in different registers
         if(AOP_TYPE(result) == AOP_CRY){
-           assert(0);
+           wassert(0);
         } else for(;(size--);offset++){
             // normal case
             // result = left & right
         } else for(;(size--);offset++){
             // normal case
             // result = left & right
@@ -2769,7 +3499,7 @@ static void genInline (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genRRC (iCode *ic)
 {
 /*-----------------------------------------------------------------*/
 static void genRRC (iCode *ic)
 {
-    assert(0);
+    wassert(0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2777,7 +3507,7 @@ static void genRRC (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genRLC (iCode *ic)
 {    
 /*-----------------------------------------------------------------*/
 static void genRLC (iCode *ic)
 {    
-    assert(0);
+    wassert(0);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2787,16 +3517,11 @@ static void shiftR2Left2Result (operand *left, int offl,
                                 operand *result, int offr,
                                 int shCount, int sign)
 {
                                 operand *result, int offr,
                                 int shCount, int sign)
 {
-    if(sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       assert(0);
-    } else {
-       movLeft2Result(left, offl, result, offr, 0);
-       movLeft2Result(left, offl+1, result, offr+1, 0);
-    }
+    movLeft2Result(left, offl, result, offr, 0);
+    movLeft2Result(left, offl+1, result, offr+1, 0);
 
     if (sign) {
 
     if (sign) {
-       assert(0);
+       wassert(0);
     }
     else {
        /*      if (AOP(result)->type == AOP_REG) {*/
     }
     else {
        /*      if (AOP(result)->type == AOP_REG) {*/
@@ -2805,13 +3530,14 @@ static void shiftR2Left2Result (operand *left, int offl,
            symbol *tlbl , *tlbl1;
            char *l;
 
            symbol *tlbl , *tlbl1;
            char *l;
 
+           tlbl = newiTempLabel(NULL);
+           tlbl1 = newiTempLabel(NULL);
+               
            /* Left is already in result - so now do the shift */
            if (shCount>1) {
            /* Left is already in result - so now do the shift */
            if (shCount>1) {
-               emitcode("ld","a,#%u+1", shCount);
-               tlbl = newiTempLabel(NULL);
-               tlbl1 = newiTempLabel(NULL);
-               emitcode("jp", LABEL_STR ,tlbl1->key+100); 
-               emitcode("", LABEL_STR ":",tlbl->key+100);    
+               emit2("ld a,!immedbyte+1", shCount);
+               emit2("!shortjp !tlabel", tlbl1->key+100); 
+               emitLabel(tlbl->key+100);    
            }
 
            emitcode("or", "a,a");
            }
 
            emitcode("or", "a,a");
@@ -2821,9 +3547,9 @@ static void shiftR2Left2Result (operand *left, int offl,
                emitcode("rr","%s", l);         
            }
            if (shCount>1) {
                emitcode("rr","%s", l);         
            }
            if (shCount>1) {
-               emitcode("", LABEL_STR ":",tlbl1->key+100);
+               emitLabel(tlbl1->key+100);
                emitcode("dec", "a");
                emitcode("dec", "a");
-               emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+               emit2("!shortjp nz,!tlabel", tlbl->key+100);
            }
     }
 }
            }
     }
 }
@@ -2836,7 +3562,7 @@ static void shiftL2Left2Result (operand *left, int offl,
 {
     if(sameRegs(AOP(result), AOP(left)) &&
        ((offl + MSB16) == offr)){
 {
     if(sameRegs(AOP(result), AOP(left)) &&
        ((offl + MSB16) == offr)){
-       assert(0);
+       wassert(0);
     } else {
        /* Copy left into result */
        movLeft2Result(left, offl, result, offr, 0);
     } else {
        /* Copy left into result */
        movLeft2Result(left, offl, result, offr, 0);
@@ -2850,13 +3576,14 @@ static void shiftL2Left2Result (operand *left, int offl,
        symbol *tlbl , *tlbl1;
        char *l;
 
        symbol *tlbl , *tlbl1;
        char *l;
 
+       tlbl = newiTempLabel(NULL);
+       tlbl1 = newiTempLabel(NULL);
+
        /* Left is already in result - so now do the shift */
        if (shCount>1) {
        /* Left is already in result - so now do the shift */
        if (shCount>1) {
-           emitcode("ld","a,#%u+1", shCount);
-           tlbl = newiTempLabel(NULL);
-           tlbl1 = newiTempLabel(NULL);
-           emitcode("jp", LABEL_STR ,tlbl1->key+100); 
-           emitcode("", LABEL_STR ":",tlbl->key+100);    
+           emit2("ld a,!immedbyte+1", shCount);
+           emit2("!shortjp !tlabel", tlbl1->key+100); 
+           emitLabel(tlbl->key+100);    
        }
 
        emitcode("or", "a,a");
        }
 
        emitcode("or", "a,a");
@@ -2865,9 +3592,9 @@ static void shiftL2Left2Result (operand *left, int offl,
            emitcode("rl","%s", l);         
        }
        if (shCount>1) {
            emitcode("rl","%s", l);         
        }
        if (shCount>1) {
-           emitcode("", LABEL_STR ":",tlbl1->key+100);
+           emitLabel(tlbl1->key+100);
            emitcode("dec", "a");
            emitcode("dec", "a");
-           emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+           emit2("!shortjp nz,!tlabel", tlbl->key+100);
        }
     }
 }
        }
     }
 }
@@ -2919,19 +3646,19 @@ static void AccRol (int shCount)
 /*-----------------------------------------------------------------*/
 static void AccLsh (int shCount)
 {
 /*-----------------------------------------------------------------*/
 static void AccLsh (int shCount)
 {
-    if(shCount != 0){
-        if(shCount == 1)
+    if(shCount != 0) {
+        if(shCount == 1) {
             emitcode("add","a,a");
             emitcode("add","a,a");
-        else 
-           if(shCount == 2) {
-            emitcode("add","a,a");
-            emitcode("add","a,a");
-        } else {
-            /* rotate left accumulator */
-            AccRol(shCount);
-            /* and kill the lower order bits */
-            emitcode("and","a,#0x%02x", SLMask[shCount]);
-        }
+       }
+        else if(shCount == 2) {
+           emitcode("add","a,a");
+           emitcode("add","a,a");
+       } else {
+           /* rotate left accumulator */
+           AccRol(shCount);
+           /* and kill the lower order bits */
+           emit2("and a,!immedbyte", SLMask[shCount]);
+       }
     }
 }
 
     }
 }
 
@@ -2957,29 +3684,30 @@ static void genlshTwo (operand *result,operand *left, int shCount)
 {
     int size = AOP_SIZE(result);
 
 {
     int size = AOP_SIZE(result);
 
-    assert(size==2);
+    wassert(size==2);
 
     /* if shCount >= 8 */
     if (shCount >= 8) {
         shCount -= 8 ;
 
     /* if shCount >= 8 */
     if (shCount >= 8) {
         shCount -= 8 ;
-
         if (size > 1){
             if (shCount) {
                 movLeft2Result(left, LSB, result, MSB16, 0);
                aopPut(AOP(result),zero, 0);   
         if (size > 1){
             if (shCount) {
                 movLeft2Result(left, LSB, result, MSB16, 0);
                aopPut(AOP(result),zero, 0);   
-               shiftL1Left2Result(left, MSB16, result, MSB16, shCount-8);
+               shiftL1Left2Result(left, MSB16, result, MSB16, shCount);
            }
             else {
                 movLeft2Result(left, LSB, result, MSB16, 0);
                aopPut(AOP(result),zero, 0);   
            }
         }
            }
             else {
                 movLeft2Result(left, LSB, result, MSB16, 0);
                aopPut(AOP(result),zero, 0);   
            }
         }
-        aopPut(AOP(result),zero,LSB);   
+       else {
+           aopPut(AOP(result),zero,LSB);   
+       }
     }
     /*  1 <= shCount <= 7 */
     else {  
         if(size == 1) {
     }
     /*  1 <= shCount <= 7 */
     else {  
         if(size == 1) {
-           assert(0);
+           wassert(0);
        }
         else {
             shiftL2Left2Result(left, LSB, result, LSB, shCount);
        }
         else {
             shiftL2Left2Result(left, LSB, result, LSB, shCount);
@@ -3008,8 +3736,8 @@ static void genLeftShiftLiteral (operand *left,
 
     freeAsmop(right,NULL,ic);
 
 
     freeAsmop(right,NULL,ic);
 
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    aopOp(left,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, FALSE);
 
     size = getSize(operandType(result));
 
 
     size = getSize(operandType(result));
 
@@ -3020,7 +3748,7 @@ static void genLeftShiftLiteral (operand *left,
 
     /* I suppose that the left size >= result size */
     if (shCount == 0) {
 
     /* I suppose that the left size >= result size */
     if (shCount == 0) {
-       assert(0);
+       wassert(0);
     }
 
     else if(shCount >= (size * 8))
     }
 
     else if(shCount >= (size * 8))
@@ -3035,10 +3763,10 @@ static void genLeftShiftLiteral (operand *left,
            genlshTwo (result,left,shCount);
            break;
        case 4:
            genlshTwo (result,left,shCount);
            break;
        case 4:
-           assert(0);
+           wassert(0);
            break;
        default:
            break;
        default:
-           assert(0);
+           wassert(0);
         }
     }
     freeAsmop(left,NULL,ic);
         }
     }
     freeAsmop(left,NULL,ic);
@@ -3059,7 +3787,7 @@ static void genLeftShift (iCode *ic)
     left  = IC_LEFT(ic);
     result = IC_RESULT(ic);
 
     left  = IC_LEFT(ic);
     result = IC_RESULT(ic);
 
-    aopOp(right,ic,FALSE);
+    aopOp(right,ic,FALSE, FALSE);
 
     /* if the shift count is known then do it 
     as efficiently as possible */
 
     /* if the shift count is known then do it 
     as efficiently as possible */
@@ -3075,8 +3803,8 @@ static void genLeftShift (iCode *ic)
     emitcode("ld","a,%s",aopGet(AOP(right),0,FALSE));
     emitcode("inc","a");
     freeAsmop (right,NULL,ic);
     emitcode("ld","a,%s",aopGet(AOP(right),0,FALSE));
     emitcode("inc","a");
     freeAsmop (right,NULL,ic);
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    aopOp(left,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, FALSE);
 
     /* now move the left to the result if they are not the
        same */
 
     /* now move the left to the result if they are not the
        same */
@@ -3107,23 +3835,24 @@ static void genLeftShift (iCode *ic)
     offset = 0 ;   
     tlbl1 = newiTempLabel(NULL);
 
     offset = 0 ;   
     tlbl1 = newiTempLabel(NULL);
 
-    emitcode("jp", LABEL_STR ,tlbl1->key+100); 
-    emitcode("", LABEL_STR ":",tlbl->key+100);    
+    emit2("!shortjp !tlabel", tlbl1->key+100); 
+    emitLabel(tlbl->key+100);    
     l = aopGet(AOP(result),offset,FALSE);
     emitcode("or", "a,a");
     while (size--) {
         l = aopGet(AOP(result),offset++,FALSE);
         emitcode("rl","%s", l);         
     }
     l = aopGet(AOP(result),offset,FALSE);
     emitcode("or", "a,a");
     while (size--) {
         l = aopGet(AOP(result),offset++,FALSE);
         emitcode("rl","%s", l);         
     }
-    emitcode("", LABEL_STR ":",tlbl1->key+100);
+    emitLabel(tlbl1->key+100);
     emitcode("dec", "a");
     emitcode("dec", "a");
-    emitcode("jp","nz," LABEL_STR ,tlbl->key+100);
+    emit2("!shortjp nz,!tlabel", tlbl->key+100);
 
     freeAsmop(left,NULL,ic);
     freeAsmop(result,NULL,ic);
 }
 
 
     freeAsmop(left,NULL,ic);
     freeAsmop(result,NULL,ic);
 }
 
-/* genlshTwo - left shift two bytes by known amount != 0           */
+/*-----------------------------------------------------------------*/
+/* genrshOne - left shift two bytes by known amount != 0           */
 /*-----------------------------------------------------------------*/
 static void genrshOne (operand *result,operand *left, int shCount)
 {
 /*-----------------------------------------------------------------*/
 static void genrshOne (operand *result,operand *left, int shCount)
 {
@@ -3131,8 +3860,8 @@ static void genrshOne (operand *result,operand *left, int shCount)
     int size = AOP_SIZE(result);
     char *l;
 
     int size = AOP_SIZE(result);
     char *l;
 
-    assert(size==1);
-    assert(shCount<8);
+    wassert(size==1);
+    wassert(shCount<8);
 
     l = aopGet(AOP(left),0,FALSE);
     if (AOP(result)->type == AOP_REG) {
 
     l = aopGet(AOP(left),0,FALSE);
     if (AOP(result)->type == AOP_REG) {
@@ -3156,15 +3885,10 @@ static void genrshOne (operand *result,operand *left, int shCount)
 static void AccRsh (int shCount)
 {
     if(shCount != 0){
 static void AccRsh (int shCount)
 {
     if(shCount != 0){
-        if(shCount == 1){
-            CLRC;
-            emitcode("rr","a");
-        } else {
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            emitcode("and","a,#0x%02x", SRMask[shCount]);
-        }
+       /* rotate right accumulator */
+       AccRol(8 - shCount);
+       /* and kill the higher order bits */
+       emit2("and a,!immedbyte", SRMask[shCount]);
     }
 }
 
     }
 }
 
@@ -3177,7 +3901,7 @@ static void shiftR1Left2Result (operand *left, int offl,
 {
     MOVA(aopGet(AOP(left),offl,FALSE));
     if (sign) {
 {
     MOVA(aopGet(AOP(left),offl,FALSE));
     if (sign) {
-       assert(0);
+       wassert(0);
     }
     else {
         AccRsh(shCount);
     }
     else {
         AccRsh(shCount);
@@ -3193,16 +3917,15 @@ static void genrshTwo (operand *result,operand *left,
 {
     /* if shCount >= 8 */
     if (shCount >= 8) {
 {
     /* if shCount >= 8 */
     if (shCount >= 8) {
-        shCount -= 8 ;
+        shCount -= 8;
         if (shCount) {
         if (shCount) {
-           assert(0);
             shiftR1Left2Result(left, MSB16, result, LSB,
                                shCount, sign);
        }
         else {
             movLeft2Result(left, MSB16, result, LSB, sign);
             shiftR1Left2Result(left, MSB16, result, LSB,
                                shCount, sign);
        }
         else {
             movLeft2Result(left, MSB16, result, LSB, sign);
-           aopPut(AOP(result),zero,1);
        }
        }
+       aopPut(AOP(result),zero,1);
     }
     /*  1 <= shCount <= 7 */
     else {
     }
     /*  1 <= shCount <= 7 */
     else {
@@ -3223,8 +3946,8 @@ static void genRightShiftLiteral (operand *left,
 
     freeAsmop(right,NULL,ic);
 
 
     freeAsmop(right,NULL,ic);
 
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    aopOp(left,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, FALSE);
 
     size = getSize(operandType(result));
 
 
     size = getSize(operandType(result));
 
@@ -3233,7 +3956,7 @@ static void genRightShiftLiteral (operand *left,
 
     /* I suppose that the left size >= result size */
     if (shCount == 0) {
 
     /* I suppose that the left size >= result size */
     if (shCount == 0) {
-       assert(0);
+       wassert(0);
     }
 
     else if(shCount >= (size * 8))
     }
 
     else if(shCount >= (size * 8))
@@ -3249,10 +3972,10 @@ static void genRightShiftLiteral (operand *left,
            genrshTwo(result, left, shCount, FALSE);
            break;
        case 4:
            genrshTwo(result, left, shCount, FALSE);
            break;
        case 4:
-           assert(0);
+           wassert(0);
            break;
        default:
            break;
        default:
-           assert(0);
+           wassert(0);
         }
     }
     freeAsmop(left,NULL,ic);
         }
     }
     freeAsmop(left,NULL,ic);
@@ -3264,58 +3987,129 @@ static void genRightShiftLiteral (operand *left,
 /*-----------------------------------------------------------------*/
 static void genRightShift (iCode *ic)
 {
 /*-----------------------------------------------------------------*/
 static void genRightShift (iCode *ic)
 {
-    operand *left,*right, *result;
+    operand *right, *left, *result;
+    link *retype ;
+    int size, offset, first = 1;
+    char *l;
+    bool is_signed;
+
+    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)));
+
+    is_signed = !SPEC_USIGN(retype);
+
+    /* 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);
 
 
     right = IC_RIGHT(ic);
     left  = IC_LEFT(ic);
     result = IC_RESULT(ic);
 
-    aopOp(right,ic,FALSE);
+    aopOp(right,ic,FALSE, FALSE);
 
     /* if the shift count is known then do it 
     as efficiently as possible */
     if (AOP_TYPE(right) == AOP_LIT) {
 
     /* if the shift count is known then do it 
     as efficiently as possible */
     if (AOP_TYPE(right) == AOP_LIT) {
-        genRightShiftLiteral (left,right,result,ic);
-        return ;
+        genRightShiftLiteral(left,right,result,ic);
+        return;
     }
     }
-    else {
-       assert(0);
+
+    aopOp(left,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, 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);
+           aopPut(AOP(result),l,offset);
+            offset++;
+        }
+    }
+
+    emitcode("ld", "a,%s",aopGet(AOP(right),0,FALSE));
+    emitcode("inc","a");
+    freeAsmop (right, NULL, ic);
+
+    tlbl = newiTempLabel(NULL);
+    tlbl1= newiTempLabel(NULL);
+    size = AOP_SIZE(result);
+    offset = size - 1;
+
+    emit2("!shortjp !tlabel", tlbl1->key+100);
+    emitLabel(tlbl->key+100);
+    while (size--) {
+        l = aopGet(AOP(result),offset--,FALSE);
+       if (first) {
+           if (is_signed)
+               emitcode("sra", "%s", l);
+           else
+               emitcode("srl", "%s", l);
+           first = 0;
+       }
+       else
+           emitcode("rr", "%s", l);
     }
     }
+    emitLabel(tlbl1->key+100);
+    emitcode("dec", "a");
+    emit2("!shortjp nz,!tlabel", tlbl->key+100);
+
+    freeAsmop(left,NULL,ic);
+    freeAsmop(result,NULL,ic);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* genGenPointerGet - gget value from generic pointer space        */
+/* genGenPointerGet -  get value from generic pointer space        */
 /*-----------------------------------------------------------------*/
 static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
     int size, offset ;
     link *retype = getSpec(operandType(result));
 /*-----------------------------------------------------------------*/
 static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
     int size, offset ;
     link *retype = getSpec(operandType(result));
+    int pair = PAIR_HL;
 
 
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+    if (IS_GB)
+       pair = PAIR_DE;
 
 
-    if (isPair(AOP(left)) && (AOP_SIZE(result)==1)) {
+    aopOp(left,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, FALSE);
+    
+    if (isPair(AOP(left)) && AOP_SIZE(result)==1) {
        /* Just do it */
        /* Just do it */
-       emitcode("ld", "a,(%s)", getPairName(AOP(left)));
-       aopPut(AOP(result),"a", 0);
+       if (isPtrPair(AOP(left))) 
+           {
+               tsprintf(buffer, "!*pair", getPairName(AOP(left)));
+               aopPut(AOP(result), buffer, 0);
+           }
+       else {
+           emit2("ld a,!*pair", getPairName(AOP(left)));
+           aopPut(AOP(result),"a", 0);
+       }
        freeAsmop(left,NULL,ic);
        goto release;
     }
 
     /* For now we always load into IY */
     /* if this is remateriazable */
        freeAsmop(left,NULL,ic);
        goto release;
     }
 
     /* For now we always load into IY */
     /* if this is remateriazable */
-    if (AOP_TYPE(left) == AOP_IMMD)
-       emitcode("ld","hl,%s",aopGet(AOP(left),0,TRUE));
-    else { /* we need to get it byte by byte */
-       fetchHL(AOP(left));
-    }
+    fetchPair(pair, AOP(left));
+
     /* so iy now contains the address */
     freeAsmop(left,NULL,ic);
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) {
     /* so iy now contains the address */
     freeAsmop(left,NULL,ic);
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) {
-       assert(0);
+       wassert(0);
     }
     else {
         size = AOP_SIZE(result);
     }
     else {
         size = AOP_SIZE(result);
@@ -3323,15 +4117,15 @@ static void genGenPointerGet (operand *left,
 
         while (size--) {
            /* PENDING: make this better */
 
         while (size--) {
            /* PENDING: make this better */
-           if (AOP(result)->type == AOP_REG) {
-               aopPut(AOP(result),"(hl)",offset++);
+           if (!IS_GB && AOP(result)->type == AOP_REG) {
+               aopPut(AOP(result), "!*hl", offset++);
            }
            else {
            }
            else {
-               emitcode("ld", "a,(hl)", offset);
+               emit2("ld a,!*pair", _pairs[pair].name);
                aopPut(AOP(result),"a",offset++);
            }
            if (size) {
                aopPut(AOP(result),"a",offset++);
            }
            if (size) {
-               emitcode("inc", "hl");
+               emit2("inc %s", _pairs[pair].name);
            }
         }
     }
            }
         }
     }
@@ -3374,39 +4168,40 @@ static void genGenPointerSet (operand *right,
 {    
     int size, offset ;
     link *retype = getSpec(operandType(right));
 {    
     int size, offset ;
     link *retype = getSpec(operandType(right));
+    PAIR_ID pairId = PAIR_HL;
+
+    aopOp(result,ic,FALSE, FALSE);
+    aopOp(right,ic,FALSE, FALSE);
 
 
-    aopOp(result,ic,FALSE);
-    aopOp(right,ic,FALSE);
+    if (IS_GB)
+       pairId = PAIR_DE;
 
     /* Handle the exceptions first */
     if (isPair(AOP(result)) && (AOP_SIZE(right)==1)) {
        /* Just do it */
        char *l = aopGet(AOP(right), 0, FALSE);
 
     /* Handle the exceptions first */
     if (isPair(AOP(result)) && (AOP_SIZE(right)==1)) {
        /* Just do it */
        char *l = aopGet(AOP(right), 0, FALSE);
-       MOVA(l);
-       emitcode("ld", "(%s),a", getPairName(AOP(result)));
-       freeAsmop(result,NULL,ic);
+       const char *pair = getPairName(AOP(result));
+       if (canAssignToPtr(l) && isPtr(pair)) {
+           emit2("ld !*pair,%s", pair, l);
+       }
+       else {
+           MOVA(l);
+           emit2("ld !*pair,a", pair);
+       }
        goto release;
     }
        
     /* if the operand is already in dptr 
        then we do nothing else we move the value to dptr */
     if (AOP_TYPE(result) != AOP_STR) {
        goto release;
     }
        
     /* 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("", "; Error 2");
-           emitcode("ld", "hl,%s", aopGet(AOP(result), 0, TRUE));
-        }
-        else { /* we need to get it byte by byte */
-           /* PENDING: do this better */
-           fetchHL(AOP(result));
-        }
+       fetchPair(pairId, AOP(result));
     }
     /* so hl know contains the address */
     freeAsmop(result,NULL,ic);
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) {
     }
     /* so hl know contains the address */
     freeAsmop(result,NULL,ic);
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) {
-       assert(0);
+       wassert(0);
     }
     else {
         size = AOP_SIZE(right);
     }
     else {
         size = AOP_SIZE(right);
@@ -3414,16 +4209,15 @@ static void genGenPointerSet (operand *right,
 
         while (size--) {
             char *l = aopGet(AOP(right),offset,FALSE);
 
         while (size--) {
             char *l = aopGet(AOP(right),offset,FALSE);
-
-           if (isRegOrLit(AOP(right))) {
-               emitcode("ld", "(hl),%s", l);
+           if (isRegOrLit(AOP(right)) && !IS_GB) {
+               emit2("ld !*pair,%s", _pairs[pairId].name, l);
            }
            else {
                MOVA(l);
            }
            else {
                MOVA(l);
-               emitcode("ld", "(hl),a", offset);
+               emit2("ld !*pair,a", _pairs[pairId].name);
            }
            if (size) {
            }
            if (size) {
-               emitcode("inc", "hl");
+               emitcode("inc", _pairs[pairId].name);
            }
            offset++;
         }
            }
            offset++;
         }
@@ -3459,7 +4253,7 @@ static void genIfx (iCode *ic, iCode *popIc)
     operand *cond = IC_COND(ic);
     int isbit =0;
 
     operand *cond = IC_COND(ic);
     int isbit =0;
 
-    aopOp(cond,ic,FALSE);
+    aopOp(cond,ic,FALSE, TRUE);
 
     /* get the value into acc */
     if (AOP_TYPE(cond) != AOP_CRY)
 
     /* get the value into acc */
     if (AOP_TYPE(cond) != AOP_CRY)
@@ -3493,36 +4287,42 @@ static void genAddrOf (iCode *ic)
 {
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
 {
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
-    aopOp(IC_RESULT(ic),ic,FALSE);
+    aopOp(IC_RESULT(ic),ic,FALSE, FALSE);
 
     /* if the operand is on the stack then we 
     need to get the stack offset of this
     variable */
 
     /* 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 (IS_GB) {
-           emitcode("lda", "hl,%d+%d(sp)", sym->stack, _spoffset);
+    if (IS_GB) {
+       if (sym->onStack) {
+           spillCached();
+           if (sym->stack <= 0) {
+               emit2("!ldahlsp", sym->stack + _G.stack.pushed + _G.stack.offset);
+           }
+           else {
+               emit2("!ldahlsp", sym->stack + _G.stack.pushed + _G.stack.offset + _G.stack.param_offset);
+           }
            emitcode("ld", "d,h");
            emitcode("ld", "e,l");
            emitcode("ld", "d,h");
            emitcode("ld", "e,l");
-           aopPut(AOP(IC_RESULT(ic)), "e", 0);
-           aopPut(AOP(IC_RESULT(ic)), "d", 1);
-           goto end;
        }
        else {
        }
        else {
-           emitcode("push", "de");
-           emitcode("push", "ix");
-           emitcode("pop", "hl");
-           emitcode("ld", "de,#%d", sym->stack);
-           emitcode("add", "hl,de");
-           emitcode("pop", "de");
+           emit2("ld de,!hashedstr", sym->rname);
        }
        }
+       aopPut(AOP(IC_RESULT(ic)), "e", 0);
+       aopPut(AOP(IC_RESULT(ic)), "d", 1);
     }
     else {
     }
     else {
-       emitcode("ld", "hl,#%s", sym->rname);
+       spillCached();
+       if (sym->onStack) {
+           /* if it has an offset  then we need to compute it */
+           emitcode("ld", "hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset);
+           emitcode("add", "hl,sp");
+       }
+       else {
+           emitcode("ld", "hl,#%s", sym->rname);
+       }
+       aopPut(AOP(IC_RESULT(ic)), "l", 0);
+       aopPut(AOP(IC_RESULT(ic)), "h", 1);
     }
     }
-    aopPut(AOP(IC_RESULT(ic)), "l", 0);
-    aopPut(AOP(IC_RESULT(ic)), "h", 1);
-end:
     freeAsmop(IC_RESULT(ic),NULL,ic);
 }
 
     freeAsmop(IC_RESULT(ic),NULL,ic);
 }
 
@@ -3546,8 +4346,8 @@ static void genAssign (iCode *ic)
     }
 #endif
 
     }
 #endif
 
-    aopOp(right,ic,FALSE);
-    aopOp(result,ic,TRUE);
+    aopOp(right,ic,FALSE, FALSE);
+    aopOp(result,ic,TRUE, FALSE);
 
     /* if they are the same registers */
     if (sameRegs(AOP(right),AOP(result))) {
 
     /* if they are the same registers */
     if (sameRegs(AOP(right),AOP(result))) {
@@ -3557,7 +4357,7 @@ static void genAssign (iCode *ic)
 
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY) {
 
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY) {
-       assert(0);
+       wassert(0);
     }
 
     /* general case */
     }
 
     /* general case */
@@ -3566,7 +4366,10 @@ static void genAssign (iCode *ic)
 
     if(AOP_TYPE(right) == AOP_LIT)
        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
 
     if(AOP_TYPE(right) == AOP_LIT)
        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-    if((size > 1) &&
+    if (isPair(AOP(result))) {
+       fetchPair(getPairId(AOP(result)), AOP(right));
+    }
+    else if((size > 1) &&
        (AOP_TYPE(result) != AOP_REG) &&
        (AOP_TYPE(right) == AOP_LIT) &&
        !IS_FLOAT(operandType(right)) &&
        (AOP_TYPE(result) != AOP_REG) &&
        (AOP_TYPE(right) == AOP_LIT) &&
        !IS_FLOAT(operandType(right)) &&
@@ -3586,7 +4389,7 @@ static void genAssign (iCode *ic)
                    aopPut(AOP(result),"a",offset);
                }
                else {
                    aopPut(AOP(result),"a",offset);
                }
                else {
-                   aopPut(AOP(result), "#0", offset);
+                   aopPut(AOP(result), zero, offset);
                }
            }
            else
                }
            }
            else
@@ -3595,11 +4398,24 @@ static void genAssign (iCode *ic)
                       offset);
            offset++;
        }
                       offset);
            offset++;
        }
+    }
+    else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result)) && IS_GB) {
+       /* Special case.  Load into a and d, then load out. */
+       MOVA(aopGet(AOP(right), 0, FALSE));
+       emitcode("ld", "e,%s", aopGet(AOP(right), 1, FALSE));
+       aopPut(AOP(result), "a", 0);
+       aopPut(AOP(result), "e", 1);
     } else {
        while (size--) {
     } else {
        while (size--) {
-           aopPut(AOP(result),
-                  aopGet(AOP(right),offset,FALSE),
-                  offset);
+           /* PENDING: do this check better */
+           if (requiresHL(AOP(right)) && requiresHL(AOP(result))) {
+               MOVA(aopGet(AOP(right), offset, FALSE));
+               aopPut(AOP(result), "a", offset);
+           }
+           else 
+               aopPut(AOP(result),
+                      aopGet(AOP(right),offset,FALSE),
+                      offset);
            offset++;
        }
     }
            offset++;
        }
     }
@@ -3617,27 +4433,28 @@ static void genJumpTab (iCode *ic)
     symbol *jtab;
     char *l;
 
     symbol *jtab;
     char *l;
 
-    aopOp(IC_JTCOND(ic),ic,FALSE);
+    aopOp(IC_JTCOND(ic),ic,FALSE, FALSE);
     /* get the condition into accumulator */
     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE);
     /* get the condition into accumulator */
     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE);
-    MOVA(l);
     if (!IS_GB)
        emitcode("push", "de");
     emitcode("ld", "e,%s", l);
     if (!IS_GB)
        emitcode("push", "de");
     emitcode("ld", "e,%s", l);
-    emitcode("ld", "d,#0");
+    emit2("ld d,!zero");
     jtab = newiTempLabel(NULL);
     jtab = newiTempLabel(NULL);
-    emitcode("ld", "hl,#" LABEL_STR, jtab->key+100);
+    spillCached();
+    emit2("ld hl,!immed!tlabel", jtab->key+100);
+    emitcode("add", "hl,de");
     emitcode("add", "hl,de");
     emitcode("add", "hl,de");
     freeAsmop(IC_JTCOND(ic),NULL,ic);
     if (!IS_GB)
        emitcode("pop", "de");
     emitcode("add", "hl,de");
     emitcode("add", "hl,de");
     freeAsmop(IC_JTCOND(ic),NULL,ic);
     if (!IS_GB)
        emitcode("pop", "de");
-    emitcode("jp", "(hl)");
-    emitcode("","%05d$:",jtab->key+100);
+    emit2("jp !*hl");
+    emitLabel(jtab->key+100);
     /* now generate the jump labels */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
          jtab = setNextItem(IC_JTLABELS(ic)))
     /* now generate the jump labels */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
          jtab = setNextItem(IC_JTLABELS(ic)))
-        emitcode("jp", LABEL_STR, jtab->key+100);
+       emit2("jp !tlabel", jtab->key+100);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -3654,12 +4471,12 @@ static void genCast (iCode *ic)
     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
         return ;
 
     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
         return ;
 
-    aopOp(right,ic,FALSE;
-    aopOp(result,ic,FALSE);
+    aopOp(right,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, FALSE);
 
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY) {
 
     /* if the result is a bit */
     if (AOP_TYPE(result) == AOP_CRY) {
-       assert(0);
+       wassert(0);
     }
 
     /* if they are the same size : or less */
     }
 
     /* if they are the same size : or less */
@@ -3685,7 +4502,7 @@ static void genCast (iCode *ic)
 #if 0
     /* if the result is of type pointer */
     if (IS_PTR(ctype)) {
 #if 0
     /* if the result is of type pointer */
     if (IS_PTR(ctype)) {
-       assert(0);
+       wassert(0);
     }
 #endif
     
     }
 #endif
     
@@ -3732,10 +4549,10 @@ static void genReceive (iCode *ic)
     if (isOperandInFarSpace(IC_RESULT(ic)) && 
        ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
          IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
     if (isOperandInFarSpace(IC_RESULT(ic)) && 
        ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
          IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
-       assert(0);
+       wassert(0);
     } else {
        accInUse++;
     } else {
        accInUse++;
-       aopOp(IC_RESULT(ic),ic,FALSE);  
+       aopOp(IC_RESULT(ic),ic,FALSE, FALSE);  
        accInUse--;
        assignResultValue(IC_RESULT(ic));       
     }
        accInUse--;
        assignResultValue(IC_RESULT(ic));       
     }
@@ -3760,6 +4577,7 @@ void genZ80Code (iCode *lic)
        _fReturn = _z80_return;
        _fTmp = _z80_return;
     }
        _fReturn = _z80_return;
        _fTmp = _z80_return;
     }
+    tsprintf(zero, "!zero");
 
     lineHead = lineCurr = NULL;
 
 
     lineHead = lineCurr = NULL;
 
@@ -3965,7 +4783,7 @@ void genZ80Code (iCode *lic)
            
        case GETHBIT:
            emitcode("", "; genHBIT");
            
        case GETHBIT:
            emitcode("", "; genHBIT");
-           assert(0);
+           wassert(0);
            
        case LEFT_OP:
            emitcode("", "; genLeftShift");
            
        case LEFT_OP:
            emitcode("", "; genLeftShift");
@@ -4038,6 +4856,6 @@ void genZ80Code (iCode *lic)
        peepHole (&lineHead);
 
     /* now do the actual printing */
        peepHole (&lineHead);
 
     /* now do the actual printing */
-    printLine (lineHead,codeOutFile);
+    printLine (lineHead, codeOutFile);
     return;
 }
     return;
 }