* Makefile.in, configure.in, configure,
[fw/sdcc] / src / avr / gen.c
index 36fd61eed7e7f6eaeafac4f95143b75aa6f67a93..15955ceedbc5abaa6fc266cb01b79630c149acdb 100644 (file)
@@ -1,26 +1,26 @@
 /*-------------------------------------------------------------------------
-  avrgen.c - source file for code generation for ATMEL AVR
-  
+  gen.c - source file for code generation for ATMEL AVR
+
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (2000)
-  
+
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.
-  
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-  
+
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-  
+
   In other words, you are welcome to use, share and improve this program.
   You are forbidden to forbid anyone else to use, share and improve
   what you give them.   Help stamp out software-hoarding!
-  
+
 
 -------------------------------------------------------------------------*/
 
 #include <string.h>
 #include <ctype.h>
 #include "SDCCglobl.h"
-
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#else
-#ifndef __BORLANDC__
-#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
-#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
-#endif
-#endif
-#endif
+#include "newalloc.h"
 
 #include "common.h"
 #include "SDCCpeeph.h"
 #include "ralloc.h"
 #include "gen.h"
 
-char *aopLiteral (value *val, int offset);
+char *aopLiteral (value * val, int offset);
 extern int allocInfo;
 
-/* this is the down and dirty file with all kinds of 
+/* this is the down and dirty file with all kinds of
    kludgy & hacky stuff. This is what it is all about
    CODE GENERATION for a specific MCU . some of the
    routines may be reusable, will have to see */
 
 static char *zero = "0x00";
-static char *one  = "0x01";
-static char *spname ;
+static char *one = "0x01";
+static char *spname;
 
-char *fReturnAVR[] = {"r16","r17","r18","r19" };
-unsigned fReturnSize = 4; /* shared with ralloc.c */
-char **fReturn = fReturnAVR;
-
-static short rbank = -1;
+char *fReturnAVR[] = { "r16", "r17", "r18", "r19" };
+unsigned fAVRReturnSize = 4;    /* shared with ralloc.c */
+char **fAVRReturn = fReturnAVR;
+static char *larray[4] = { ">", "<", "hlo8", "hhi8" };
 
 static struct {
-    short xPushed;
-    short zPushed;
-    short accInUse;
-    short inLine;
-    short debugLine;
-    short nRegsSaved;
-    set *sendSet;
+        short xPushed;
+        short zPushed;
+        short accInUse;
+        short inLine;
+        short debugLine;
+        short nRegsSaved;
+        set *sendSet;
 } _G;
 
-extern int avr_ptrRegReq ;
+extern int avr_ptrRegReq;
 extern int avr_nRegs;
-extern FILE *codeOutFile;
-static void saverbank (int, iCode *,bool);
+extern struct dbuf_s *codeOutBuf;
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
 
 #define MOVR0(x) if (strcmp(x,"r0")) emitcode("mov","r0,%s",x);
-#define CLRC    emitcode("clc")
-#define SETC    emitcode("stc")
-#define IS_REGIDX(a,r) (a->type == AOP_REG && aop->aopu.aop_reg[0]->rIdx == r)
+#define MOVR24(x) if (strcmp(x,"r24")) emitcode("mov","r24,%s",x);
+#define AOP_ISHIGHREG(a,n) (a->type == AOP_REG && a->aopu.aop_reg[n] && a->aopu.aop_reg[n]->rIdx >= R16_IDX)
+#define CLRC    emitcode("clc","")
+#define SETC    emitcode("stc","")
+#define MOVA(x)
+#define IS_REGIDX(a,r) (a->type == AOP_REG && a->aopu.aop_reg[0]->rIdx == r)
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
 
-static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
-0xE0, 0xC0, 0x80, 0x00};
-static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
-0x07, 0x03, 0x01, 0x00};
-
 #define LSB     0
 #define MSB16   1
 #define MSB24   2
 #define MSB32   3
 
+#if 0
+// PENDING: Unused.
 /*-----------------------------------------------------------------*/
-/* emitcode - writes the code into a file : for now it is simple    */
+/* reAdjustPreg - points a register back to where it should        */
 /*-----------------------------------------------------------------*/
-static void emitcode (char *inst,char *fmt, ...)
+static void
+reAdjustPreg (asmop * aop)
 {
-    va_list ap;
-    char lb[MAX_INLINEASM];  
-    char *lbp = lb;
-
-    va_start(ap,fmt);   
-
-    if (inst && *inst) {
-       if (fmt && *fmt)
-           sprintf(lb,"%s\t",inst);
-       else
-           sprintf(lb,"%s",inst);
-        vsprintf(lb+(strlen(lb)),fmt,ap);
-    }  else
-        vsprintf(lb,fmt,ap);
-
-    while (isspace(*lbp)) lbp++;
-
-    if (lbp && *lbp) 
-        lineCurr = (lineCurr ?
-                    connectLine(lineCurr,newLineNode(lb)) :
-                    (lineHead = newLineNode(lb)));
-    lineCurr->isInline = _G.inLine;
-    lineCurr->isDebug  = _G.debugLine;
-    va_end(ap);
+        int size;
+
+        aop->coff = 0;
+        if ((size = aop->size) <= 1)
+                return;
+        size--;
+        switch (aop->type) {
+        case AOP_X:
+        case AOP_Z:
+                emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name, size);
+                break;
+        }
+
 }
 
 /*-----------------------------------------------------------------*/
-/* getFreePtr - returns X or Z whichever is free or can be pushed  */
+/* outBitC - output a bit C                                        */
 /*-----------------------------------------------------------------*/
-static regs *getFreePtr (iCode *ic, asmop **aopp, bool result, bool zonly)
+static void
+outBitC (operand * result)
 {
-    bool xiu = FALSE , ziu = FALSE;
-    bool xou = FALSE , zou = FALSE;
-
-    /* the logic: if x & z used in the instruction
-    then we are in trouble otherwise */
+        emitcode ("clr", "r0");
+        emitcode ("rol", "r0");
+        outAcc (result);
+}
 
-    /* first check if x & z are used by this
-    instruction, in which case we are in trouble */
-    if ((xiu = bitVectBitValue(ic->rUsed,X_IDX)) &&
-        (ziu = bitVectBitValue(ic->rUsed,Z_IDX))) 
-    {
-        goto endOfWorld;      
-    }
+/*-----------------------------------------------------------------*/
+/* inExcludeList - return 1 if the string is in exclude Reg list   */
+/*-----------------------------------------------------------------*/
+static bool
+inExcludeList (char *s)
+{
+        int i = 0;
 
-    xou = bitVectBitValue(ic->rMask,X_IDX);
-    zou = bitVectBitValue(ic->rMask,Z_IDX);
-
-    /* if no usage of Z then return it */
-    if (!ziu && !zou) {
-        ic->rUsed = bitVectSetBit(ic->rUsed,Z_IDX);
-        (*aopp)->type = AOP_Z;
-
-       (*aopp)->aop_ptr2 = avr_regWithIdx(R31_IDX);
-        return (*aopp)->aopu.aop_ptr = avr_regWithIdx(R30_IDX);
-    }    
-
-    /* if no usage of X then return it */
-    if (!xiu && !xou && !zonly) {
-        ic->rUsed = bitVectSetBit(ic->rUsed,X_IDX);
-        (*aopp)->type = AOP_X;
-        
-       (*aopp)->aop_ptr2 = avr_regWithIdx(R27_IDX);
-        return (*aopp)->aopu.aop_ptr = avr_regWithIdx(R26_IDX);
-    }
+        if (options.excludeRegs[i] &&
+            STRCASECMP (options.excludeRegs[i], "none") == 0)
+                return FALSE;
 
-    /* if z not used then */
-
-    if (!ziu) {
-        /* push it if not already pushed */
-        if (!_G.zPushed) {
-            emitcode ("push","%s",
-                      avr_regWithIdx(R30_IDX)->dname);
-            emitcode ("push","%s",
-                      avr_regWithIdx(R31_IDX)->dname);
-            _G.zPushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,Z_IDX);
-        (*aopp)->type = AOP_Z;
-       (*aopp)->aop_ptr2 = avr_regWithIdx(R31_IDX);
-        return (*aopp)->aopu.aop_ptr = avr_regWithIdx(R30_IDX);
-    }
+        for (i = 0; options.excludeRegs[i]; i++) {
+                if (options.excludeRegs[i] &&
+                    STRCASECMP (s, options.excludeRegs[i]) == 0)
+                        return TRUE;
+        }
+        return FALSE;
+}
 
-    /* now we know they both have usage */
-    /* if x not used in this instruction */
-    if (!xiu && !zonly) {
-        /* push it if not already pushed */
-        if (!_G.xPushed) {
-            emitcode ("push","%s",
-                      avr_regWithIdx(R26_IDX)->dname);
-            emitcode ("push","%s",
-                      avr_regWithIdx(R27_IDX)->dname);
-            _G.xPushed++ ;
-        }
-        
-        ic->rUsed = bitVectSetBit(ic->rUsed,X_IDX);
-        (*aopp)->type = AOP_X;
-
-       (*aopp)->aop_ptr2 = avr_regWithIdx(R27_IDX);
-        return (*aopp)->aopu.aop_ptr = avr_regWithIdx(R26_IDX);
-    }
+/*-----------------------------------------------------------------*/
+/* findLabelBackwards: walks back through the iCode chain looking  */
+/* for the given label. Returns number of iCode instructions     */
+/* between that label and given ic.          */
+/* Returns zero if label not found.          */
+/*-----------------------------------------------------------------*/
+static int
+findLabelBackwards (iCode * ic, int key)
+{
+        int count = 0;
 
+        while (ic->prev) {
+                ic = ic->prev;
+                count++;
 
-endOfWorld :
-    /* I said end of world but not quite end of world yet */
-    /* if this is a result then we can push it on the stack*/
-    if (result) {
-        (*aopp)->type = AOP_STK;    
-        return NULL;
-    }
+                if (ic->op == LABEL && IC_LABEL (ic)->key == key) {
+                        /* printf("findLabelBackwards = %d\n", count); */
+                        return count;
+                }
+        }
 
-    piCode(ic,stdout);
-    /* other wise this is true end of the world */
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "getFreePtr should never reach here");
-    exit(0);
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* newAsmop - creates a new asmOp                                  */
+/* addSign - complete with sign                                    */
 /*-----------------------------------------------------------------*/
-static asmop *newAsmop (short type)
+static void
+addSign (operand * result, int offset, int sign)
 {
-    asmop *aop;
-
-    ALLOC(aop,sizeof(asmop));
-    aop->type = type;
-    return aop;
+        int size = (getDataSize (result) - offset);
+        if (size > 0) {
+                if (sign) {
+                        emitcode ("rlc", "a");
+                        emitcode ("subb", "a,acc");
+                        while (size--)
+                                aopPut (AOP (result), "a", offset++);
+                }
+                else
+                        while (size--)
+                                aopPut (AOP (result), zero, offset++);
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* pointerCode - returns the code for a pointer type               */
+/* isLiteralBit - test if lit == 2^n                               */
 /*-----------------------------------------------------------------*/
-static int pointerCode (link *etype)
+static int
+isLiteralBit (unsigned long lit)
 {
-
-    return PTR_TYPE(SPEC_OCLS(etype));
-
+        unsigned long pw[32] = { 1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
+                0x100L, 0x200L, 0x400L, 0x800L,
+                0x1000L, 0x2000L, 0x4000L, 0x8000L,
+                0x10000L, 0x20000L, 0x40000L, 0x80000L,
+                0x100000L, 0x200000L, 0x400000L, 0x800000L,
+                0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
+                0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L
+        };
+        int idx;
+
+        for (idx = 0; idx < 32; idx++)
+                if (lit == pw[idx])
+                        return idx + 1;
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* aopForSym - for a true symbol                                   */
+/* outAcc - output Acc                                             */
 /*-----------------------------------------------------------------*/
-static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
+static void
+outAcc (operand * result)
 {
-    asmop *aop;
-    memmap *space= SPEC_OCLS(sym->etype);
-
-    /* if already has one */
-    if (sym->aop)
-        return sym->aop;
-
-    /* assign depending on the storage class */
-    /* if it is on the stack */
-    if (sym->onStack) {
-        sym->aop = aop = newAsmop(0);
-        aop->size = getSize(sym->type);
-
-       /* we can use std / ldd instruction */
-       if (sym->stack > 0 && (sym->stack + getSize(sym->type) - 1) <= 63) {
-           aop->type = AOP_STK_D;
-            aop->aopu.aop_stk = sym->stack;
-           return aop;
-       }
-
-       /* otherwise get a free pointer register X/Z */
-        aop->aopu.aop_ptr = getFreePtr(ic,&aop,result,FALSE);
-
-        /* now assign the address of the variable to 
-          the pointer register */
-        if (aop->type != AOP_STK) {
-           emitcode("movw","%s,r28",aop->aopu.aop_ptr->name);
-           if (sym->stack < 0) {
-               if ((sym->stack - _G.nRegsSaved) > -63) {
-                   emitcode("sbiw","%s,0x%02x",
-                            aop->aopu.aop_ptr->name,
-                            (sym->stack - _G.nRegsSaved));
-               } else {
-                   emitcode("subi","%s,lo8(%d)", aop->aopu.aop_ptr->name,
-                            sym->stack - _G.nRegsSaved);
-                   emitcode("sbci","%s,hi8(%d)",aop->aop_ptr2->name,
-                            sym->stack - _G.nRegsSaved);
-               }
-           } else {
-               if (sym->stack <= 63) {
-                   emitcode("adiw","%s,0x%02x",aop->aopu.aop_ptr->name,sym->stack);
-               } else {
-                   emitcode("subi","%s,lo8(-%d)",aop->aopu.aop_ptr->name,sym->stack);
-                   emitcode("sbci","%s,hi8(-%d)",aop->aop_ptr2->name,sym->stack); 
-               }
-           }
-       }
-        return aop;
-    }
-    
-    /* if in bit space */
-    if (IN_BITSPACE(space)) {
-        sym->aop = aop = newAsmop (AOP_CRY);
-        aop->aopu.aop_dir = sym->rname ;
-        aop->size = getSize(sym->type);
-        return aop;
-    }
-    /* if it is in direct space */
-    if (IN_DIRSPACE(space)) {
-        sym->aop = aop = newAsmop (AOP_DIR);
-        aop->aopu.aop_dir = sym->rname ;
-        aop->size = getSize(sym->type);
-        return aop;
-    }
+        int size, offset;
+        size = getDataSize (result);
+        if (size) {
+                aopPut (AOP (result), "r0", 0);
+                size--;
+                offset = 1;
+                /* unsigned or positive */
+                while (size--) {
+                        aopPut (AOP (result), zero, offset++);
+                }
+        }
+}
 
-    /* special case for a function */
-    if (IS_FUNC(sym->type)) {   
-        sym->aop = aop = newAsmop(AOP_IMMD);    
-        ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
-        strcpy(aop->aopu.aop_immd,sym->rname);
-        aop->size = FPTRSIZE; 
-        return aop;
-    }
+#endif  // End Unused code section
 
-    /* only remaining is code / eeprom which will need pointer reg */
-    /* if it is in code space */
-    if (IN_CODESPACE(space))
-        aop->code = 1;
+/*-----------------------------------------------------------------*/
+/* emitcode - writes the code into a file : for now it is simple    */
+/*-----------------------------------------------------------------*/
+static void
+emitcode (char *inst, char *fmt, ...)
+{
+        va_list ap;
+        char lb[INITIAL_INLINEASM];
+        char *lbp = lb;
 
-    sym->aop = aop = newAsmop(0);
-    aop->aopu.aop_ptr = getFreePtr(ic,&aop,result,aop->code);
-    aop->size = getSize(sym->type);
-    emitcode ("ldi","%s,lo8(%s)",aop->aopu.aop_ptr->name,sym->rname);
-    emircode ("ldi","%s,hi8(%s)",aop->aop_ptr2);
+        va_start (ap, fmt);
 
-    return aop;     
+        if (inst && *inst) {
+                if (fmt && *fmt)
+                        sprintf (lb, "%s\t", inst);
+                else
+                        sprintf (lb, "%s", inst);
+                vsprintf (lb + (strlen (lb)), fmt, ap);
+        }
+        else
+                vsprintf (lb, fmt, ap);
+
+        while (isspace ((unsigned char)*lbp))
+                lbp++;
+
+        if (lbp && *lbp)
+                lineCurr = (lineCurr ?
+                            connectLine (lineCurr, newLineNode (lb)) :
+                            (lineHead = newLineNode (lb)));
+        lineCurr->isInline = _G.inLine;
+        lineCurr->isDebug = _G.debugLine;
+        va_end (ap);
 }
 
 /*-----------------------------------------------------------------*/
-/* aopForRemat - rematerialzes an object                           */
+/* avr_emitDebuggerSymbol - associate the current code location  */
+/*   with a debugger symbol                                        */
 /*-----------------------------------------------------------------*/
-static asmop *aopForRemat (symbol *sym)
+void
+avr_emitDebuggerSymbol (char * debugSym)
 {
-    iCode *ic = sym->rematiCode;
-    asmop *aop = newAsmop(AOP_IMMD);
-    int val = 0;
-
-    for (;;) {
-       if (ic->op == '+')
-           val += operandLitValue(IC_RIGHT(ic));
-       else if (ic->op == '-')
-           val -= operandLitValue(IC_RIGHT(ic));
-       else
-           break;
-       
-       ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
-    }
-
-    if (val)
-       sprintf(buffer,"(%s %c 0x%04x)",
-               OP_SYMBOL(IC_LEFT(ic))->rname, 
-               val >= 0 ? '+' : '-',
-               abs(val) & 0xffff);
-    else
-       strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
-
-    ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(buffer)+1);
-    strcpy(aop->aopu.aop_immd,buffer);    
-    return aop;        
+  _G.debugLine = 1;
+  emitcode ("", "%s ==.", debugSym);
+  _G.debugLine = 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* regsInCommon - two operands have some registers in common       */
+/* hasInc - operand is incremented before any other use            */
 /*-----------------------------------------------------------------*/
-static bool regsInCommon (operand *op1, operand *op2)
+static iCode *
+hasInc (operand *op, iCode *ic)
 {
-    symbol *sym1, *sym2;
-    int i;
+        sym_link *type = operandType(op);
+        sym_link *retype = getSpec (type);
+        iCode *lic = ic->next;
+        int isize ;
+
+        if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
+        if (IS_AGGREGATE(type->next)) return NULL;
+        isize = getSize(type->next);
+        while (lic) {
+                /* if operand of the form op = op + <sizeof *op> */
+                if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+                    isOperandEqual(IC_RESULT(lic),op) &&
+                    isOperandLiteral(IC_RIGHT(lic)) &&
+                    operandLitValue(IC_RIGHT(lic)) == isize) {
+                        return lic;
+                }
+                /* if the operand used or deffed */
+                if (bitVectBitValue(OP_USES(op),lic->key) || (lic->defKey == op->key)) {
+                        return NULL;
+                }
+                lic = lic->next;
+        }
+        return NULL;
+}
 
-    /* if they have registers in common */
-    if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
-        return FALSE ;
+/*-----------------------------------------------------------------*/
+/* getFreePtr - returns X or Z whichever is free or can be pushed  */
+/*-----------------------------------------------------------------*/
+static regs *
+getFreePtr (iCode * ic, asmop ** aopp, bool result, bool zonly)
+{
+        bool xiu = FALSE, ziu = FALSE;
+        bool xou = FALSE, zou = FALSE;
 
-    sym1 = OP_SYMBOL(op1);
-    sym2 = OP_SYMBOL(op2);
+        /* the logic: if x & z used in the instruction
+           then we are in trouble otherwise */
 
-    if (sym1->nRegs == 0 || sym2->nRegs == 0)
-        return FALSE ;
+        /* first check if x & z are used by this
+           instruction, in which case we are in trouble */
+        if ((xiu = bitVectBitValue (ic->rUsed, X_IDX)) &&
+            (ziu = bitVectBitValue (ic->rUsed, Z_IDX))) {
+                goto endOfWorld;
+        }
 
-    for (i = 0 ; i < sym1->nRegs ; i++) {
-        int j;
-        if (!sym1->regs[i])
-            continue ;
+        xou = bitVectBitValue (ic->rMask, X_IDX);
+        zou = bitVectBitValue (ic->rMask, Z_IDX);
 
-        for (j = 0 ; j < sym2->nRegs ;j++ ) {
-            if (!sym2->regs[j])
-                continue ;
+        /* if no usage of Z then return it */
+        if (!ziu && !zou) {
+                ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
+                (*aopp)->type = AOP_Z;
 
-            if (sym2->regs[j] == sym1->regs[i])
-                return TRUE ;
+                (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
+                return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
         }
-    }
 
-    return FALSE ;
-}
+        /* if no usage of X then return it */
+        if (!xiu && !xou && !zonly) {
+                ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
+                (*aopp)->type = AOP_X;
 
-/*-----------------------------------------------------------------*/
-/* operandsEqu - equivalent                                        */
-/*-----------------------------------------------------------------*/
-static bool operandsEqu ( operand *op1, operand *op2)
-{
-    symbol *sym1, *sym2;
+                (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
+                return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
+        }
 
-    /* if they not symbols */
-    if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
-        return FALSE;
+        /* if z not used then */
 
-    sym1 = OP_SYMBOL(op1);
-    sym2 = OP_SYMBOL(op2);
+        if (!ziu) {
+                /* push it if not already pushed */
+                if (!_G.zPushed) {
+                        emitcode ("push", "%s",
+                                  avr_regWithIdx (R30_IDX)->dname);
+                        emitcode ("push", "%s",
+                                  avr_regWithIdx (R31_IDX)->dname);
+                        _G.zPushed++;
+                }
 
-    /* if both are itemps & one is spilt
-       and the other is not then false */
-    if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
-       sym1->isspilt != sym2->isspilt )
-       return FALSE ;
+                ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
+                (*aopp)->type = AOP_Z;
+                (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
+                return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
+        }
 
-    /* if they are the same */
-    if (sym1 == sym2)
-        return TRUE ;
+        /* now we know they both have usage */
+        /* if x not used in this instruction */
+        if (!xiu && !zonly) {
+                /* push it if not already pushed */
+                if (!_G.xPushed) {
+                        emitcode ("push", "%s",
+                                  avr_regWithIdx (R26_IDX)->dname);
+                        emitcode ("push", "%s",
+                                  avr_regWithIdx (R27_IDX)->dname);
+                        _G.xPushed++;
+                }
 
-    if (strcmp(sym1->rname,sym2->rname) == 0)
-        return TRUE;
+                ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
+                (*aopp)->type = AOP_X;
 
+                (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
+                return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
+        }
 
-    /* if left is a tmp & right is not */
-    if (IS_ITEMP(op1)  && 
-        !IS_ITEMP(op2) &&
-        sym1->isspilt  &&
-        (sym1->usl.spillLoc == sym2))
-        return TRUE;
 
-    if (IS_ITEMP(op2)  && 
-        !IS_ITEMP(op1) &&
-        sym2->isspilt  &&
-       sym1->level > 0 &&
-        (sym2->usl.spillLoc == sym1))
-        return TRUE ;
+      endOfWorld:
+        /* I said end of world but not quite end of world yet */
+        /* if this is a result then we can push it on the stack */
+        if (result) {
+                (*aopp)->type = AOP_STK;
+                return NULL;
+        }
 
-    return FALSE ;
+        /* other wise this is true end of the world */
+        werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                "getFreePtr should never reach here");
+        exit (0);
 }
 
 /*-----------------------------------------------------------------*/
-/* sameRegs - two asmops have the same registers                   */
+/* newAsmop - creates a new asmOp                                  */
 /*-----------------------------------------------------------------*/
-static bool sameRegs (asmop *aop1, asmop *aop2 )
+static asmop *
+newAsmop (short type)
 {
-    int i;
-
-    if (aop1 == aop2)
-        return TRUE ;
+        asmop *aop;
 
-    if (aop1->type != AOP_REG ||
-        aop2->type != AOP_REG )
-        return FALSE ;
-
-    if (aop1->size != aop2->size )
-        return FALSE ;
-
-    for (i = 0 ; i < aop1->size ; i++ )
-        if (aop1->aopu.aop_reg[i] !=
-            aop2->aopu.aop_reg[i] )
-            return FALSE ;
-
-    return TRUE ;
+        aop = Safe_calloc (1, sizeof (asmop));
+        aop->type = type;
+        return aop;
 }
 
 /*-----------------------------------------------------------------*/
-/* isRegPair - for size 2 if this operand has a register pair      */
+/* pointerCode - returns the code for a pointer type               */
 /*-----------------------------------------------------------------*/
-static int isRegPair (aop *aopp)
+static int
+pointerCode (sym_link * etype)
 {
-    if (!aop || aop->size != 2) return 0;
-    if (aop->type == AOP_X || aop->type == AOP_Y) return 1;
-    if (aop->type != AOP_REG) return 0;
-    if ((aop->aopu.aop_reg[1]->rIdx - 
-        aop->aopu.aop_reg[0]->rIdx) == 1) return 1;
-    return 0;
+
+        return PTR_TYPE (SPEC_OCLS (etype));
+
 }
 
 /*-----------------------------------------------------------------*/
-/* aopOp - allocates an asmop for an operand  :                    */
+/* aopForSym - for a true symbol                                   */
 /*-----------------------------------------------------------------*/
-static void aopOp (operand *op, iCode *ic, bool result)
+static asmop *
+aopForSym (iCode * ic, symbol * sym, bool result)
 {
-    asmop *aop;
-    symbol *sym;
-    int i;
-
-    if (!op)
-        return ;
-
-    /* if this a literal */
-    if (IS_OP_LITERAL(op)) {
-        op->aop = aop = newAsmop(AOP_LIT);
-        aop->aopu.aop_lit = op->operand.valOperand;
-        aop->size = getSize(operandType(op));
-        return;
-    }
-
-    /* if already has a asmop then continue */
-    if (op->aop)
-        return ;
+        asmop *aop;
+        memmap *space = SPEC_OCLS (sym->etype);
+
+        /* if already has one */
+        if (sym->aop)
+                return sym->aop;
+
+        /* assign depending on the storage class */
+        /* if it is on the stack */
+        if (sym->onStack) {
+                sym->aop = aop = newAsmop (0);
+                aop->size = getSize (sym->type);
+
+                /* we can use std / ldd instruction */
+                if (sym->stack > 0
+                    && (sym->stack + getSize (sym->type) - 1) <= 63) {
+                        aop->type = AOP_STK_D;
+                        aop->aopu.aop_stk = sym->stack;
+                        return aop;
+                }
 
-    /* if the underlying symbol has a aop */
-    if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
-        op->aop = OP_SYMBOL(op)->aop;
-        return;
-    }
+                /* otherwise get a free pointer register X/Z */
+                aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, FALSE);
+
+                /* now assign the address of the variable to
+                   the pointer register */
+                if (aop->type != AOP_STK) {
+                        emitcode ("movw", "%s,r28", aop->aopu.aop_ptr->name);
+                        if (sym->stack < 0) {
+                                if ((sym->stack - _G.nRegsSaved) > -63) {
+                                        emitcode ("sbiw", "%s,0x%02x",
+                                                  aop->aopu.aop_ptr->name,
+                                                  (sym->stack -
+                                                   _G.nRegsSaved));
+                                }
+                                else {
+                                        emitcode ("subi", "%s,<(%d)",
+                                                  aop->aopu.aop_ptr->name,
+                                                  sym->stack - _G.nRegsSaved);
+                                        emitcode ("sbci", "%s,>(%d)",
+                                                  aop->aop_ptr2->name,
+                                                  sym->stack - _G.nRegsSaved);
+                                }
+                        }
+                        else {
+                                if (sym->stack <= 63) {
+                                        emitcode ("adiw", "%s,0x%02x",
+                                                  aop->aopu.aop_ptr->name,
+                                                  sym->stack);
+                                }
+                                else {
+                                        emitcode ("subi", "%s,<(-%d)",
+                                                  aop->aopu.aop_ptr->name,
+                                                  sym->stack);
+                                        emitcode ("sbci", "%s,>(-%d)",
+                                                  aop->aop_ptr2->name,
+                                                  sym->stack);
+                                }
+                        }
+                }
+                return aop;
+        }
 
-    /* if this is a true symbol */
-    if (IS_TRUE_SYMOP(op)) {    
-        op->aop = aopForSym(ic,OP_SYMBOL(op),result);
-        return ;
-    }
+        /* if in bit space */
+        if (IN_BITSPACE (space)) {
+                sym->aop = aop = newAsmop (AOP_CRY);
+                aop->aopu.aop_dir = sym->rname;
+                aop->size = getSize (sym->type);
+                return aop;
+        }
+        /* if it is in direct space */
+        if (IN_DIRSPACE (space)) {
+                sym->aop = aop = newAsmop (AOP_DIR);
+                aop->aopu.aop_dir = sym->rname;
+                aop->size = getSize (sym->type);
+                return aop;
+        }
 
-    /* this is a temporary : this has
-    only four choices :
-    a) register
-    b) spillocation
-    c) rematerialize 
-    d) conditional   
-    e) can be a return use only */
+        /* special case for a function */
+        if (IS_FUNC (sym->type)) {
+                sym->aop = aop = newAsmop (AOP_IMMD);
+                aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
+                strcpy (aop->aopu.aop_immd, sym->rname);
+                aop->size = FPTRSIZE;
+                return aop;
+        }
 
-    sym = OP_SYMBOL(op);
+        /* only remaining is code / eeprom which will need pointer reg */
+        /* if it is in code space */
 
+        sym->aop = aop = newAsmop (0);
 
-    /* if the type is a conditional */
-    if (sym->regType == REG_CND) {
-        aop = op->aop = sym->aop = newAsmop(AOP_CRY);
-        aop->size = 0;
-        return;
-    }
+        if (IN_CODESPACE (space))
+                aop->code = 1;
 
-    /* if it is spilt then two situations
-    a) is rematerialize 
-    b) has a spill location */
-    if (sym->isspilt || sym->nRegs == 0) {
+        aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, aop->code);
+        aop->size = getSize (sym->type);
+        emitcode ("ldi", "%s,<(%s)", aop->aopu.aop_ptr->name, sym->rname);
+        emitcode ("ldi", "%s,>(%s)", aop->aop_ptr2);
 
-        /* rematerialize it NOW */
-        if (sym->remat) {
-            sym->aop = op->aop = aop =
-                                      aopForRemat (sym);
-            aop->size = getSize(sym->type);
-            return;
-        }
+        return aop;
+}
 
-       if (sym->accuse) {
-               assert("ACC_USE cannot happen in AVR\n");
-       }
+/*-----------------------------------------------------------------*/
+/* aopForRemat - rematerialzes an object                           */
+/*-----------------------------------------------------------------*/
+static asmop *
+aopForRemat (symbol * sym)
+{
+        iCode *ic = sym->rematiCode;
+        asmop *aop = newAsmop (AOP_IMMD);
+        int val = 0;
+
+        for (;;) {
+                if (ic->op == '+')
+                        val += (int) operandLitValue (IC_RIGHT (ic));
+                else if (ic->op == '-')
+                        val -= (int) operandLitValue (IC_RIGHT (ic));
+                else
+                        break;
 
-        if (sym->ruonly ) {
-            int i;
-            aop = op->aop = sym->aop = newAsmop(AOP_STR);
-            aop->size = getSize(sym->type);
-            for ( i = 0 ; i < fReturnSize ; i++ )
-                aop->aopu.aop_str[i] = fReturn[i];
-            return;
+                ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
         }
 
-        /* else spill location  */
-        sym->aop = op->aop = aop = 
-                                  aopForSym(ic,sym->usl.spillLoc,result);
-        aop->size = getSize(sym->type);
-        return;
-    }
+        if (val)
+                sprintf (buffer, "(%s %c 0x%04x)",
+                         OP_SYMBOL (IC_LEFT (ic))->rname,
+                         val >= 0 ? '+' : '-', abs (val) & 0xffff);
+        else
+                strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
 
-    /* must be in a register */
-    sym->aop = op->aop = aop = newAsmop(AOP_REG);
-    aop->size = sym->nRegs;
-    for ( i = 0 ; i < sym->nRegs ;i++)
-        aop->aopu.aop_reg[i] = sym->regs[i];
+        aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
+        strcpy (aop->aopu.aop_immd, buffer);
+        return aop;
 }
 
 /*-----------------------------------------------------------------*/
-/* freeAsmop - free up the asmop given to an operand               */
-/*----------------------------------------------------------------*/
-static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
-{   
-    asmop *aop ;
+/* regsInCommon - two operands have some registers in common       */
+/*-----------------------------------------------------------------*/
+static bool
+regsInCommon (operand * op1, operand * op2)
+{
+        symbol *sym1, *sym2;
+        int i;
 
-    if (!op)
-        aop = aaop;
-    else 
-        aop = op->aop;
+        /* if they have registers in common */
+        if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+                return FALSE;
 
-    if (!aop)
-        return ;
+        sym1 = OP_SYMBOL (op1);
+        sym2 = OP_SYMBOL (op2);
 
-    if (aop->freed)
-        goto dealloc; 
+        if (sym1->nRegs == 0 || sym2->nRegs == 0)
+                return FALSE;
 
-    aop->freed = 1;
+        for (i = 0; i < sym1->nRegs; i++) {
+                int j;
+                if (!sym1->regs[i])
+                        continue;
 
-    /* depending on the asmop type only three cases need work AOP_RO
-       , AOP_R1 && AOP_STK */
-    switch (aop->type) {
-        case AOP_X :
-            if (_G.xPushed ) {
-                if (pop) {
-                    emitcode ("pop","r26");
-                   emitcode ("pop","r27");
-                    _G.xPushed--;
-                }
-            }
-            bitVectUnSetBit(ic->rUsed,X_IDX);
-            break;
+                for (j = 0; j < sym2->nRegs; j++) {
+                        if (!sym2->regs[j])
+                                continue;
 
-        case AOP_Z :
-            if (_G.zPushed ) {
-                if (pop) {
-                    emitcode ("pop","r30");
-                   emitcode ("pop","r31");
-                    _G.zPushed--;
+                        if (sym2->regs[j] == sym1->regs[i])
+                                return TRUE;
                 }
-            }
-            bitVectUnSetBit(ic->rUsed,Z_IDX);          
-            break;
-
-        case AOP_STK :
-        {
-            int sz = aop->size;    
-            int stk = aop->aopu.aop_stk + aop->size;
-            bitVectUnSetBit(ic->rUsed,X_IDX);
-            bitVectUnSetBit(ic->rUsed,Z_IDX);          
-
-            getFreePtr(ic,&aop,FALSE,0);
-            
-           emitcode ("movw","%s,r28");
-           if (stk) {
-               if (stk <= 63 && stk > 0) {
-                   emitcode ("adiw","%s,0x%02x",aop->aopu.aop_ptr->name,stk+1);
-               } else {
-                   emitcode ("subi","%s,lo8(%d)",aop->aopu.aop_ptr->name,-(stk+1));
-                   emitcode ("sbci","%s,hi8(%d)",aop->aop_ptr2->name,-(stk+1));
-               }
-           }
-
-            while (sz--) {
-                emitcode("pop","r24");
-                emitcode("st","-%s,r24",aop->type == AOP_X ? "X" : "Z");
-                if (!sz) break;
-            }
-            op->aop = aop;
-            freeAsmop(op,NULL,ic,TRUE);
-            if (_G.xPushed) {
-                emitcode("pop","r26");
-                emitcode("pop","r27");
-                _G.xPushed--;
-            }
-
-            if (_G.zPushed) {
-                emitcode("pop","r30");
-                emitcode("pop","r31");
-                _G.zPushed--;
-            }       
         }
-    }
 
-dealloc:
-    /* all other cases just dealloc */
-    if (op ) {
-        op->aop = NULL;
-        if (IS_SYMOP(op)) {
-            OP_SYMBOL(op)->aop = NULL;    
-            /* if the symbol has a spill */
-           if (SPIL_LOC(op))
-                SPIL_LOC(op)->aop = NULL;
-        }
-    }
+        return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
-/* aopGet - for fetching value of the aop                          */
+/* operandsEqu - equivalent                                        */
 /*-----------------------------------------------------------------*/
-static char *aopGet (asmop *aop, int offset)
+static bool
+operandsEqu (operand * op1, operand * op2)
 {
-    char *s = buffer ;
-    char *rs;
-
-    /* offset is greater than
-    size then zero */
-    if (offset > (aop->size - 1) &&
-        aop->type != AOP_LIT)
-        return zero;
-
-    /* depending on type */
-    switch (aop->type) {
-       
-    case AOP_X:
-       if (offset > aop->coff) {
-           emitcode ("adiw","%s,%d",aop->aopu.aop_ptr->name,offset - aop->coff);  
-       }
-       
-       if (offset < aop->coff) {
-           emitcode("sbiw","%s,%d",aop->aopu.aop_ptr->name,aop->coff - offset);
-       }
-       
-       aop->coff = offset ;
-       emitcode("ld","%s,x",
-                    (rs = ((offset & 1) ? "r25" : "r24")));
-       return rs;
-
-    case AOP_Z:
-       if (aop->code) {
-           if (offset > aop->coff) {
-               emitcode("adiw","r30,%d",offset - aop->coff);
-           } else {
-               emitcode("sbiw","r30,%d",aop->coff - offset);
-           }
-           emitcode("lpm","%s,z",(rs = ((offset & 1) ? "r25" : "r24")));
-       } else {
-           /* we can use lds */
-           if (offset  > aop->coff) {
-               emitcode ("ldd","%s,z+%d",(rs = ((offset & 1) ? "r25" : "r24")),
-                         offset - aop->coff);
-           } else {
-               emitcode("sbiw","%s,%d",aop->aopu.aop_ptr->name,aop->coff - offset);
-               aop->coff = offset;
-               emitcode ("ld","%s,z",(rs = ((offset & 1) ? "r25" : "r24")));
-           }
-       }
-       return rs;
-
-    case AOP_IMMD:
-       
-       emitcode ("lds","%s,(%s)+%d",
-                 (rs = ((offset & 1) ? "r25" : "r24")),
-                 aop->aopu.aop_immd, offset);
-       return rs;
-       
-    case AOP_DIR:
-       emitcode ("lds","%s,(%s)+%d",
-                 (rs = ((offset & 1) ? "r25" : "r24")),
-                 aop->aopu.aop_dir, offset);
-       return rs;
-       
-    case AOP_REG:
-       return aop->aopu.aop_reg[offset]->name;
-       
-    case AOP_CRY:
-       assert("cannot be in bit space AOP_CRY\n");
-       break;
-
-    case AOP_LIT:
-       s = aopLiteral(aop->aopu.aop_lit,offset);
-       emitcode("ldi","%s,lo8(%s)",(rs = ((offset & 1)?"r24" : "r25")),s);
-       return rs;
-
-    case AOP_STR:
-       aop->coff = offset ;
-       return aop->aopu.aop_str[offset];
-       
-    case AOP_STK_D:
-       emitcode ("ldd","%s,Y+%d",
-                 (rs = ((offset & 1) ? "r25" : "r24")),                  
-                 aop->aopu.aop_stk+offset);
-       return rs;
-    }
+        symbol *sym1, *sym2;
 
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-           "aopget got unsupported aop->type");
-    exit(0);
-}
-/*-----------------------------------------------------------------*/
-/* aopPut - puts a string for a aop                                */
-/*-----------------------------------------------------------------*/
-static void aopPut (asmop *aop, char *s, int offset)
-{
-    char *d = buffer ;
-    symbol *lbl ;
+        /* if they not symbols */
+        if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+                return FALSE;
 
-    if (aop->size && offset > ( aop->size - 1)) {
-        werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-               "aopPut got offset > aop->size");
-        exit(0);
-    }
+        sym1 = OP_SYMBOL (op1);
+        sym2 = OP_SYMBOL (op2);
 
-    /* will assign value to value */
-    /* depending on where it is ofcourse */
-    switch (aop->type) {
-    case AOP_DIR:
-       if (offset) {
-           sprintf(d,"(%s)+%d", aop->aopu.aop_dir,offset);
-       }
-       else {
-           sprintf(d,"%s",aop->aopu.aop_dir);
-       }
-       
-       emitcode("sts","%s,%s",d,s);
-               break;
-       
-    case AOP_REG:
-       if (toupper(*s) != 'R') {
-           if (s == zero) {
-               emitcode("clr","%s",aop->aopu.aop_reg[offset]->name);
-           } else {
-               emitcode("ldi","r25,%s",s);
-               emitcode("mov","%s,r35",aop->aopu.aop_reg[offset]->name);
-           }
-       } else {
-           if (strcmp( aop->aopu.aop_reg[offset]->name,s)) {
-               emitcode("mov","%s,%s", aop->aopu.aop_reg[offset]->name,s);
-           }
-       }
-       break;
-       
-    case AOP_X:
-       if (offset > aop->coff) {
-           emitcode ("adiw","%s,%d",aop->aopu.aop_ptr->name,offset - aop->coff);  
-       }
-       
-       if (offset < aop->coff) {
-           emitcode("sbiw","%s,%d",aop->aopu.aop_ptr->name,aop->coff - offset);
-       }
-       
-       aop->coff = offset ;
-       emitcode("st","x,%s", s);
-       break;
-       
-    case AOP_Z:
-       if (aop->code) {
-           if (offset > aop->coff) {
-               emitcode("adiw","r30,%d",offset - aop->coff);
-           } else {
-               emitcode("sbiw","r30,%d",aop->coff - offset);
-           }
-           emitcode("lpm","%s,z",s);
-       } else {
-           /* we can use lds */
-           if (offset  > aop->coff) {
-               emitcode ("sdd","z+%d,%s",offset - aop->coff,s);
-           } else {
-               emitcode("sbiw","%s,%d",aop->aopu.aop_ptr->name,aop->coff - offset);
-               aop->coff = offset;
-               emitcode ("ld","%s,z",s);
-           }
-       }
-       break;
-       
-    case AOP_STK:
-       emitcode("push","%s",s);        
-       break;
-       
-    case AOP_CRY:
-       /* if bit variable */
-       assert("bit variable cannot be AOP_CRY\n");
-       break;
-       
-    case AOP_STR:
-       aop->coff = offset;
-       if (strcmp(aop->aopu.aop_str[offset],s))
-           emitcode ("mov","%s,%s",aop->aopu.aop_str[offset],s);
-       break;
-
-    case AOP_STK_D:
-       emitcode ("std","y+%d,%s",offset,s);
-       break;
-
-    default :
-       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-              "aopPut got unsupported aop->type");
-       exit(0);    
-    }    
+        /* if both are itemps & one is spilt
+           and the other is not then false */
+        if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
+            sym1->isspilt != sym2->isspilt) return FALSE;
 
-}
+        /* if they are the same */
+        if (sym1 == sym2)
+                return TRUE;
 
+        if (strcmp (sym1->rname, sym2->rname) == 0)
+                return TRUE;
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* pointToEnd :- points to the last byte of the operand            */
-/*-----------------------------------------------------------------*/
-static void pointToEnd (asmop *aop)
-{
-    int count ;
-    if (!aop)
-        return ;
-
-    aop->coff = count = (aop->size - 1);
-    switch (aop->type) {
-        case AOP_X :
-        case AOP_Z :
-           emitcode("adiw","%s,%d",aop->aopu.aop_ptr->name,count);
-            break;
-    }
 
-}
-#endif
+        /* if left is a tmp & right is not */
+        if (IS_ITEMP (op1) &&
+            !IS_ITEMP (op2) && sym1->isspilt && (sym1->usl.spillLoc == sym2))
+                return TRUE;
 
-/*-----------------------------------------------------------------*/
-/* reAdjustPreg - points a register back to where it should        */
-/*-----------------------------------------------------------------*/
-static void reAdjustPreg (asmop *aop)
-{
-    int size ;
-
-    aop->coff = 0;
-    if ((size = aop->size) <= 1)
-        return ;
-    size-- ;
-    switch (aop->type) {
-        case AOP_X :
-        case AOP_Z :
-           emitcode("sbiw","%s,%d",aop->aopu.aop_ptr->name,size);
-            break;          
-    }
+        if (IS_ITEMP (op2) &&
+            !IS_ITEMP (op1) &&
+            sym2->isspilt && sym1->level > 0 && (sym2->usl.spillLoc == sym1))
+                return TRUE;
 
+        return FALSE;
 }
 
-#define AOP(op) op->aop
-#define AOP_TYPE(op) AOP(op)->type
-#define AOP_SIZE(op) AOP(op)->size
-#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_X || \
-                       AOP_TYPE(x) == AOP_Z))
-#define AOP_INPREG(x) (x && (x->type == AOP_REG &&                      \
-                      (x->aopu.aop_reg[0] == avr_regWithIdx(R26_IDX) || \
-                      x->aopu.aop_reg[0] == avr_regWithIdx(R30_IDX) )))
-
 /*-----------------------------------------------------------------*/
-/* genNotFloat - generates not for float operations                */
+/* sameRegs - two asmops have the same registers                   */
 /*-----------------------------------------------------------------*/
-static void genNotFloat (operand *op, operand *res)
+static bool
+sameRegs (asmop * aop1, asmop * aop2)
 {
-    int size, offset;
-    char *l;
-    symbol *tlbl ;
+        int i;
 
-    /* we will put 127 in the first byte of 
-    the result */
-    aopPut(AOP(res),"127",0);
-    size = AOP_SIZE(op) - 1;
-    offset = 1;
+        if (aop1 == aop2)
+                return TRUE;
 
-    l = aopGet(op->aop,offset++);
-    MOVR0(l);    
+        if (aop1->type != AOP_REG || aop2->type != AOP_REG)
+                return FALSE;
 
-    while(size--) {
-        emitcode("or","R0,%s", aopGet(op->aop, offset++);
-    }
-    tlbl = newiTempLabel(NULL);
-
-    tlbl = newiTempLabel(NULL);
-    aopPut(res->aop,zero,1);
-    emitcode("cpi","r0,0");
-    emitcode("breq","L%05d",tlbl->key);
-    aopPut(res->aop,one,1);
-    emitcode("","L%05d:",tlbl->key);
-
-    size = res->aop->size - 2;
-    offset = 2;    
-    /* put zeros in the rest */
-    while (size--) 
-        aopPut(res->aop,zero,offset++);
-}
+        if (aop1->size != aop2->size)
+                return FALSE;
 
-/*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is            */   
-/* a generic pointer type.                                        */
-/*-----------------------------------------------------------------*/ 
-static int opIsGptr(operand *op)
-{
-    link *type = operandType(op);
-    
-    if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
-    {
-        return 1;
-    }
-    return 0;        
-}
+        for (i = 0; i < aop1->size; i++)
+                if (aop1->aopu.aop_reg[i] != aop2->aopu.aop_reg[i])
+                        return FALSE;
 
-/*-----------------------------------------------------------------*/
-/* getDataSize - get the operand data size                         */
-/*-----------------------------------------------------------------*/
-static int getDataSize(operand *op)
-{
-    int size;
-    size = AOP_SIZE(op);
-    if (size == GPTRSIZE)
-    {
-        link *type = operandType(op);
-        if (IS_GENPTR(type))
-        {
-            /* generic pointer; arithmetic operations
-             * should ignore the high byte (pointer type).
-             */
-            size--;
-        }
-    }
-    return size;
+        return TRUE;
 }
 
 /*-----------------------------------------------------------------*/
-/* outAcc - output Acc                                             */
+/* isRegPair - for size 2 if this operand has a register pair      */
 /*-----------------------------------------------------------------*/
-static void outAcc(operand *result)
+static int
+isRegPair (asmop * aop)
 {
-    int size, offset;
-    size = getDataSize(result);
-    if(size){
-        aopPut(AOP(result),"r0",0);
-        size--;
-        offset = 1;
-        /* unsigned or positive */
-        while(size--){
-            aopPut(AOP(result),zero,offset++);
-        }
-    }
+        if (!aop || aop->size < 2)
+                return 0;
+        if (aop->type == AOP_X || aop->type == AOP_Z)
+                return 1;
+        if (aop->type != AOP_REG)
+                return 0;
+        if ( ((aop->aopu.aop_reg[1]->rIdx - aop->aopu.aop_reg[0]->rIdx) == 1) &&
+             (aop->aopu.aop_reg[0]->rIdx & 1) == 0)
+
+                return 1;
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* outBitC - output a bit C                                        */
+/* allHigh - all registers are high registers                      */
 /*-----------------------------------------------------------------*/
-static void outBitC(operand *result)
+static int allHigh (asmop * aop)
 {
-    emitcode("clr","r0");
-    emitcode("rol","r0");
-    outAcc(result);
-}
+        int i;
 
-/*-----------------------------------------------------------------*/
-/* toBoolean - emit code for orl a,operator(sizeop)                */
-/*-----------------------------------------------------------------*/
-static void toBoolean(operand *oper)
-{
-    int size = AOP_SIZE(oper) ;
-    int offset = 0;
-    emitcode ("clr","r0");
-    while (size--) 
-        emitcode("or","r0,%s",aopGet(AOP(oper),offset++));
+        if (aop->type == AOP_X || aop->type == AOP_Z)
+                return 1;
+        if (aop->type != AOP_REG)
+                return 0;
+        for (i=0; i < aop->size ; i++ )
+                if (aop->aopu.aop_reg[i]->rIdx < R16_IDX) return 0;
+        return 1;
 }
 
-
 /*-----------------------------------------------------------------*/
-/* genNot - generate code for ! operation                          */
+/* aopOp - allocates an asmop for an operand  :                    */
 /*-----------------------------------------------------------------*/
-static void genNot (iCode *ic)
+static void
+aopOp (operand * op, iCode * ic, bool result)
 {
-    symbol *tlbl;
-    link *optype = operandType(IC_LEFT(ic));
-    int size, offset = 1;
-
-    /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
-
-    /* if type float then do float */
-    if (IS_FLOAT(optype)) {
-        genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
-        goto release;
-    }
-    emitcode("clr","r24");
-    tlbl = newiTempLabel(NULL);
-    toBoolean(IC_LEFT(ic));
-    emitcode("bne","L%05d",tlbl->key);
-    emitcode("ldi","r24,1");
-    emitcode("","L%05d:",tlbl->key);
-    aopPut(AOP(IC_RESULT(ic)),"r24",0);
-    size = AOP_SIZE(IC_RESULT(ic)) -1;
-    while (size--) aopPut(AOP(IC_RESULT(ic)),zero,offset++);
-    
-
-release:    
-    /* release the aops */
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
+        asmop *aop;
+        symbol *sym;
+        int i;
 
+        if (!op)
+                return;
 
-/*-----------------------------------------------------------------*/
-/* genCpl - generate code for complement                           */
-/*-----------------------------------------------------------------*/
-static void genCpl (iCode *ic)
-{
-    int offset = 0;
-    int size ;
-    int samer;
-
-    /* assign asmOps to operand & result */
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
-    samer = sameRegs(AOP(IC_LEFT(ic),AOP(IC_RESULT(ic))));
-    size = AOP_SIZE(IC_RESULT(ic));
-    while (size--) {
-        char *l = aopGet(AOP(IC_LEFT(ic)),offset);
-       if (samer) {
-           emitcode ("com","%s",l);
-       } else {
-           aopPut(AOP(IC_RESULT(ic)),l,offset);
-           emitcode ("com","%s",aopGet(AOP(IC_RESULT(ic)),offset++));
-       }
-    }
+        /* if this a literal */
+        if (IS_OP_LITERAL (op)) {
+                op->aop = aop = newAsmop (AOP_LIT);
+                aop->aopu.aop_lit = op->operand.valOperand;
+                aop->size = getSize (operandType (op));
+                return;
+        }
 
+        /* if already has a asmop then continue */
+        if (op->aop)
+                return;
 
-release:
-    /* release the aops */
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
+        /* if the underlying symbol has a aop */
+        if (IS_SYMOP (op) && OP_SYMBOL (op)->aop) {
+                op->aop = OP_SYMBOL (op)->aop;
+                return;
+        }
 
-/*-----------------------------------------------------------------*/
-/* genUminusFloat - unary minus for floating points                */
-/*-----------------------------------------------------------------*/
-static void genUminusFloat(operand *op,operand *result)
-{
-    int size ,offset =0 ;
-    char *l;
-    /* for this we just need to flip the 
-    first it then copy the rest in place */
-    size = AOP_SIZE(op) - 1;
-    l = aopGet(AOP(op),3);
-    
-    emitcode("ldi","r24,0x80");
-    if (sameRegs(AOP(op),AOP(result))) {
-       emitcode("eor","%s,r24",l);
-    } else {
-       aopPut(AOP(result),l,3);
-       emitcode("eor","%s,r24",aopGet(AOP(result),3));
-    }
-    while(size--) {
-        aopPut(AOP(result), aopGet(AOP(op),offset), offset);
-        offset++;
-    }          
-}
+        /* if this is a true symbol */
+        if (IS_TRUE_SYMOP (op)) {
+                op->aop = aopForSym (ic, OP_SYMBOL (op), result);
+                return;
+        }
 
-/*-----------------------------------------------------------------*/
-/* genUminus - unary minus code generation                         */
-/*-----------------------------------------------------------------*/
-static void genUminus (iCode *ic)
-{
-    int offset ,size ;
-    link *optype, *rtype;
-    int samer ;
+        /* this is a temporary : this has
+           only four choices :
+           a) register
+           b) spillocation
+           c) rematerialize
+           d) conditional
+           e) can be a return use only */
 
-    /* assign asmops */
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    aopOp(IC_RESULT(ic),ic,TRUE);
+        sym = OP_SYMBOL (op);
 
-    optype = operandType(IC_LEFT(ic));
-    rtype = operandType(IC_RESULT(ic));
 
-    /* if float then do float stuff */
-    if (IS_FLOAT(optype)) {
-        genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
-        goto release;
-    }
+        /* if the type is a conditional */
+        if (sym->regType & REG_CND) {
+                aop = op->aop = sym->aop = newAsmop (AOP_CRY);
+                aop->size = 0;
+                return;
+        }
 
-    /* otherwise subtract from zero */
-    size = AOP_SIZE(IC_LEFT(ic));
-    offset = 0 ;
-    samer = sameRegs(AOP(IC_LEFT(ic)),AOP(IC_RESULT(ic)));
-    CLRC;
-    while(size--) {
-        char *l = aopGet(AOP(IC_LEFT(ic)),offset);
-       if (samer) {
-           emitcode("clr","r0");
-           emitcode("sbc","r0,%s",l);
-           aopPut(AOP(IC_RESULT(ic)),"r0",offset++);
-       } else {
-           char *s;
-           emitcode("clr","%s",s=aopGet(IC_RESULT(ic),offset++));
-           emitcode("sbc","%s,%s",s,l);
-       }
-    }
+        /* if it is spilt then two situations
+           a) is rematerialize
+           b) has a spill location */
+        if (sym->isspilt || sym->nRegs == 0) {
 
-    /* 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))))) {
-       symbol *tlbl = newiTempLabel(NULL);
-        emitcode("clr","r0");
-       emitcode("brcc","L%05d",tlbl->key);
-       emitcode("com","r0");
-       emitcode("","L%05d:",tlbl->key);
-        while (size--) 
-            aopPut(AOP(IC_RESULT(ic)),"r0",offset++);
-    }       
-
-release:
-    /* release the aops */
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
-}
+                asmop *oldAsmOp = NULL;
 
-/*-----------------------------------------------------------------*/
-/* assignResultValue -                                            */
-/*-----------------------------------------------------------------*/
-static void assignResultValue(operand * oper)
-{
-       int offset = 0;
-       int size = AOP_SIZE(oper);
-       while (size--) {
-               aopPut(AOP(oper),fReturn[offset],offset);
-               offset++;
-       }
-}
-
-/*-----------------------------------------------------------------*/
-/* saveZreg - if indirect call then save z-pointer register        */
-/*-----------------------------------------------------------------*/
-static void saveZreg (iCode *ic)
-{
-       /* only if live accross this call */
-       if (ic->regSaved == 0 && 
-           (bitVectBitValue(ic->rMask,R30_IDX) ||
-           bitVectBitValue(ic->rMask,R31_IDX))) {
-           ic->regsSaved = 1;
-           emitcode("push","r30");
-           emitcode("push","r31");
-       }
-}
+                /* rematerialize it NOW */
+                if (sym->remat) {
+                        sym->aop = op->aop = aop = aopForRemat (sym);
+                        aop->size = getSize (sym->type);
+                        return;
+                }
 
-/*-----------------------------------------------------------------*/
-/* popZreg - restore values of zreg                                */
-/*-----------------------------------------------------------------*/
-static void popZreg (iCode *ic)
-{
-    if (ic->regsSaved) {
-       emitcode ("pop","r31");
-       emitcode ("pop","r30");
-    }
-}
+                if (sym->accuse) {
+                        assert ("ACC_USE cannot happen in AVR\n");
+                }
 
-/*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex  */
-/*-----------------------------------------------------------------*/
-static void genIpush (iCode *ic)
-{
-    int size, offset = 0 ;
-    char *l;
-
-
-    if (!ic->parmPush) {
-        /* and the item is spilt then do nothing */
-        if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
-            return ;
-    } else {
-           iCode *lic ; 
-           for (lic = ic->next ; lic ; lic = lic->next) 
-                   if (lic->op == PCALL) break;
-           if (lic) saveZreg(lic);
-    }
+                if (sym->ruonly) {
+                        int i;
+                        aop = op->aop = sym->aop = newAsmop (AOP_STR);
+                        aop->size = getSize (sym->type);
+                        for (i = 0; i < (int) fAVRReturnSize; i++)
+                                aop->aopu.aop_str[i] = fAVRReturn[i];
+                        return;
+                }
 
-    /* this is a paramter push */
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    size = AOP_SIZE(IC_LEFT(ic));
-    while (size--) {
-        l = aopGet(AOP(IC_LEFT(ic)),offset++);
-       emitcode("push","%s",l);
-    }       
+                /* else spill location  */
+                if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+                    /* force a new aop if sizes differ */
+                    oldAsmOp = sym->usl.spillLoc->aop;
+                    sym->usl.spillLoc->aop = NULL;
+                }
+                sym->aop = op->aop = aop =
+                        aopForSym (ic, sym->usl.spillLoc, result);
+                if (getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+                        /* Don't reuse the new aop, go with the last one */
+                        sym->usl.spillLoc->aop = oldAsmOp;
+                }
+                aop->size = getSize (sym->type);
+                return;
+        }
 
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+        /* must be in a register */
+        sym->aop = op->aop = aop = newAsmop (AOP_REG);
+        aop->size = sym->nRegs;
+        for (i = 0; i < sym->nRegs; i++)
+                aop->aopu.aop_reg[i] = sym->regs[i];
 }
 
 /*-----------------------------------------------------------------*/
-/* genIpop - recover the registers: can happen only for spilling   */
-/*-----------------------------------------------------------------*/
-static void genIpop (iCode *ic)
+/* freeAsmop - free up the asmop given to an operand               */
+/*----------------------------------------------------------------*/
+static void
+freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
 {
-    int size,offset ;
+        asmop *aop;
 
+        if (!op)
+                aop = aaop;
+        else
+                aop = op->aop;
+
+        if (!aop)
+                return;
+
+        if (aop->freed)
+                goto dealloc;
+
+        aop->freed = 1;
+
+        /* depending on the asmop type only three cases need work AOP_RO
+           , AOP_R1 && AOP_STK */
+        switch (aop->type) {
+        case AOP_X:
+                if (_G.xPushed) {
+                        if (pop) {
+                                emitcode ("pop", "r26");
+                                emitcode ("pop", "r27");
+                                _G.xPushed--;
+                        }
+                }
+                bitVectUnSetBit (ic->rUsed, X_IDX);
+                break;
 
-    /* if the temp was not pushed then */
-    if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
-        return ;
+        case AOP_Z:
+                if (_G.zPushed) {
+                        if (pop) {
+                                emitcode ("pop", "r30");
+                                emitcode ("pop", "r31");
+                                _G.zPushed--;
+                        }
+                }
+                bitVectUnSetBit (ic->rUsed, Z_IDX);
+                break;
 
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    size = AOP_SIZE(IC_LEFT(ic));
-    offset = (size-1);
-    while (size--) 
-        emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--));
+        case AOP_STK:
+                {
+                        int sz = aop->size;
+                        int stk = aop->aopu.aop_stk + aop->size;
+                        bitVectUnSetBit (ic->rUsed, X_IDX);
+                        bitVectUnSetBit (ic->rUsed, Z_IDX);
+
+                        getFreePtr (ic, &aop, FALSE, 0);
+
+                        emitcode ("movw", "%s,r28");
+                        if (stk) {
+                                if (stk <= 63 && stk > 0) {
+                                        emitcode ("adiw", "%s,0x%02x",
+                                                  aop->aopu.aop_ptr->name,
+                                                  stk + 1);
+                                }
+                                else {
+                                        emitcode ("subi", "%s,<(%d)",
+                                                  aop->aopu.aop_ptr->name,
+                                                  -(stk + 1));
+                                        emitcode ("sbci", "%s,>(%d)",
+                                                  aop->aop_ptr2->name,
+                                                  -(stk + 1));
+                                }
+                        }
+
+                        while (sz--) {
+                                emitcode ("pop", "r24");
+                                emitcode ("st", "-%s,r24",
+                                          aop->type == AOP_X ? "X" : "Z");
+                                if (!sz)
+                                        break;
+                        }
+                        op->aop = aop;
+                        freeAsmop (op, NULL, ic, TRUE);
+                        if (_G.xPushed) {
+                                emitcode ("pop", "r26");
+                                emitcode ("pop", "r27");
+                                _G.xPushed--;
+                        }
+
+                        if (_G.zPushed) {
+                                emitcode ("pop", "r30");
+                                emitcode ("pop", "r31");
+                                _G.zPushed--;
+                        }
+                }
+        }
 
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+      dealloc:
+        /* all other cases just dealloc */
+        if (op) {
+                op->aop = NULL;
+                if (IS_SYMOP (op)) {
+                        OP_SYMBOL (op)->aop = NULL;
+                        /* if the symbol has a spill */
+                        if (SPIL_LOC (op))
+                                SPIL_LOC (op)->aop = NULL;
+                }
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genCall - generates a call statement                            */
+/* aopGet - for fetching value of the aop                          */
 /*-----------------------------------------------------------------*/
-static void genCall (iCode *ic)
+static char *
+aopGet (asmop * aop, int offset)
 {
-    link *detype;   
-
-    /* if send set is not empty the assign */
-    if (_G.sendSet) {
-       iCode *sic ;
-
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.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);
-               if (strcmp(l,fReturn[offset]))
-                   emitcode("mov","%s,%s",
-                            fReturn[offset],
-                            l);
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-       }
-       _G.sendSet = NULL;
-    }
-    /* make the call */
-    emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                           OP_SYMBOL(IC_LEFT(ic))->rname :
-                           OP_SYMBOL(IC_LEFT(ic))->name));
-
-    /* if we need assign a result value */
-    if ((IS_ITEMP(IC_RESULT(ic)) && 
-         (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-          OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
-        IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
-        aopOp(IC_RESULT(ic),ic,FALSE);
-       assignResultValue(IC_RESULT(ic));
-        freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
-    }
+        char *s = buffer;
+        char *rs;
 
-    /* adjust the stack for parameters if required */
-    if (IC_LEFT(ic)->parmBytes) {
-        if (IC_LEFT(ic)->parmBytes > 63) {
-           emitcode("sbiw","r28,%d",IC_LEFT(ic)->parmBytes);
-       } else {
-           emitcode("subi","r28,lo8(%d)",IC_LEFT(ic)->parmBytes);
-           emitcode("sbci","r29,hi8(%d)",IC_LEFT(ic)->parmBytes);
-       }
-    }
+        /* offset is greater than
+           size then zero */
+        if (offset > (aop->size - 1) && aop->type != AOP_LIT)
+                return zero;
 
-}
+        /* depending on type */
+        switch (aop->type) {
 
-/*-----------------------------------------------------------------*/
-/* genPcall - generates a call by pointer statement                */
-/*-----------------------------------------------------------------*/
-static void genPcall (iCode *ic)
-{
-    link *detype;
-
-    if (!ic->regsSaved) saveZreg(ic);
-
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    emitcode("mov","r30",aopGet(AOP(IC_LEFT(ic)),0));
-    emitcode("mov","r31",aopGet(AOP(IC_RIGHT(ic)),0));
-    freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
-
-    /* if send set is not empty the assign */
-    if (_G.sendSet) {
-       iCode *sic ;
-
-       for (sic = setFirstItem(_G.sendSet) ; sic ; 
-            sic = setNextItem(_G.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);
-               if (strcmp(l,fReturn[offset]))
-                   emitcode("mov","%s,%s",
-                            fReturn[offset],
-                            l);
-               offset++;
-           }
-           freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-       }
-       _G.sendSet = NULL;
-    }
+        case AOP_X:
+                if (offset > aop->coff) {
+                        emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
+                                  offset - aop->coff);
+                }
 
-    emitcode("icall","");
+                if (offset < aop->coff) {
+                        emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
+                                  aop->coff - offset);
+                }
 
-    /* if we need assign a result value */
-    if ((IS_ITEMP(IC_RESULT(ic)) &&
-         (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-          OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
-        IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+                aop->coff = offset;
+                emitcode ("ld", "%s,x",
+                          (rs = ((offset & 1) ? "r25" : "r24")));
+                return rs;
+
+        case AOP_Z:
+                if (aop->code) {
+                        if (offset > aop->coff) {
+                                emitcode ("adiw", "r30,%d",
+                                          offset - aop->coff);
+                        }
+                        else {
+                                emitcode ("sbiw", "r30,%d",
+                                          aop->coff - offset);
+                        }
+                        emitcode ("lpm", "%s,z",
+                                  (rs = ((offset & 1) ? "r25" : "r24")));
+                }
+                else {
+                        /* we can use lds */
+                        if (offset > aop->coff) {
+                                emitcode ("ldd", "%s,z+%d",
+                                          (rs =
+                                           ((offset & 1) ? "r25" : "r24")),
+                                          offset - aop->coff);
+                        }
+                        else {
+                                emitcode ("sbiw", "%s,%d",
+                                          aop->aopu.aop_ptr->name,
+                                          aop->coff - offset);
+                                aop->coff = offset;
+                                emitcode ("ld", "%s,z",
+                                          (rs =
+                                           ((offset & 1) ? "r25" : "r24")));
+                        }
+                }
+                return rs;
 
-        aopOp(IC_RESULT(ic),ic,FALSE);
+        case AOP_IMMD:
 
-       assignResultValue(IC_RESULT(ic));
-        freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-    }
+                emitcode ("lds", "%s,(%s)+%d",
+                          (rs = ((offset & 1) ? "r25" : "r24")),
+                          aop->aopu.aop_immd, offset);
+                return rs;
 
-    /* adjust the stack for parameters if 
-    required */
-    if (IC_LEFT(ic)->parmBytes) {
-        int i;
-        if (IC_LEFT(ic)->parmBytes > 3) {
-            emitcode("mov","a,%s",spname);
-            emitcode("add","a,#0x%02x", (- IC_LEFT(ic)->parmBytes) & 0xff);
-            emitcode("mov","%s,a",spname);
-        } else 
-            for ( i = 0 ; i <  IC_LEFT(ic)->parmBytes ;i++)
-                emitcode("dec","%s",spname);
+        case AOP_DIR:
+                emitcode ("lds", "%s,(%s)+%d",
+                          (rs = ((offset & 1) ? "r25" : "r24")),
+                          aop->aopu.aop_dir, offset);
+                return rs;
 
-    }
+        case AOP_REG:
+                return aop->aopu.aop_reg[offset]->name;
 
-    /* adjust the stack for parameters if required */
-    if (IC_LEFT(ic)->parmBytes) {
-        if (IC_LEFT(ic)->parmBytes > 63) {
-           emitcode("sbiw","r28,%d",IC_LEFT(ic)->parmBytes);
-       } else {
-           emitcode("subi","r28,lo8(%d)",IC_LEFT(ic)->parmBytes);
-           emitcode("sbci","r29,hi8(%d)",IC_LEFT(ic)->parmBytes);
-       }
-    }
-    if (ic->regsSaved) popZregs(ic);
+        case AOP_CRY:
+                assert ("cannot be in bit space AOP_CRY\n");
+                break;
+
+        case AOP_LIT:
+                s = aopLiteral (aop->aopu.aop_lit, offset);
+                emitcode ("ldi", "%s,<(%s)",
+                          (rs = ((offset & 1) ? "r24" : "r25")), s);
+                return rs;
+
+        case AOP_STR:
+                aop->coff = offset;
+                return aop->aopu.aop_str[offset];
+
+        case AOP_STK_D:
+                emitcode ("ldd", "%s,Y+%d",
+                          (rs = ((offset & 1) ? "r25" : "r24")),
+                          aop->aopu.aop_stk + offset);
+                return rs;
+        }
+
+        werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                "aopget got unsupported aop->type");
+        exit (0);
 }
 
 /*-----------------------------------------------------------------*/
-/* resultRemat - result  is rematerializable                       */
+/* aopPut - puts a string for a aop                                */
 /*-----------------------------------------------------------------*/
-static int resultRemat (iCode *ic)
+static void
+aopPut (asmop * aop, char *s, int offset)
 {
-    if (SKIP_IC(ic) || ic->op == IFX)
-        return 0;
-
-    if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
-        symbol *sym = OP_SYMBOL(IC_RESULT(ic));
-        if (sym->remat && !POINTER_SET(ic)) 
-            return 1;
-    }
+        char *d = buffer;
 
-    return 0;
-}
+        if (aop->size && offset > (aop->size - 1)) {
+                werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                        "aopPut got offset > aop->size");
+                exit (0);
+        }
 
-#ifdef __BORLANDC__
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
+        /* will assign value to value */
+        /* depending on where it is ofcourse */
+        switch (aop->type) {
+        case AOP_DIR:
+                if (offset) {
+                        sprintf (d, "(%s)+%d", aop->aopu.aop_dir, offset);
+                }
+                else {
+                        sprintf (d, "%s", aop->aopu.aop_dir);
+                }
 
-/*-----------------------------------------------------------------*/
-/* inExcludeList - return 1 if the string is in exclude Reg list   */
-/*-----------------------------------------------------------------*/
-static bool inExcludeList(char *s)
-{
-    int i =0;
-    
-    if (options.excludeRegs[i] &&
-    STRCASECMP(options.excludeRegs[i],"none") == 0)
-       return FALSE ;
-
-    for ( i = 0 ; options.excludeRegs[i]; i++) {
-       if (options.excludeRegs[i] &&
-        STRCASECMP(s,options.excludeRegs[i]) == 0)
-           return TRUE;
-    }
-    return FALSE ;
-}
+                emitcode ("sts", "%s,%s", d, s);
+                break;
 
-/*-----------------------------------------------------------------*/
-/* genFunction - generated code for function entry                 */
-/*-----------------------------------------------------------------*/
-static void genFunction (iCode *ic)
-{
-    symbol *sym;
-    link *fetype;
-    int i = 0;
+        case AOP_REG:
+                if (toupper ((unsigned char)*s) != 'R') {
+                        if (s == zero) {
+                                emitcode ("clr", "%s",
+                                          aop->aopu.aop_reg[offset]->name);
+                        }
+                        else {
+                                emitcode ("ldi", "r25,%s", s);
+                                emitcode ("mov", "%s,r35",
+                                          aop->aopu.aop_reg[offset]->name);
+                        }
+                }
+                else {
+                        if (strcmp (aop->aopu.aop_reg[offset]->name, s)) {
+                                emitcode ("mov", "%s,%s",
+                                          aop->aopu.aop_reg[offset]->name, s);
+                        }
+                }
+                break;
 
-    _G.nRegsSaved = 0;
-    /* create the function header */
-    emitcode(";","-----------------------------------------");
-    emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
-    emitcode(";","-----------------------------------------");
+        case AOP_X:
+                if (offset > aop->coff) {
+                        emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
+                                  offset - aop->coff);
+                }
 
-    emitcode("","%s:",sym->rname);
-    fetype = getSpec(operandType(IC_LEFT(ic)));
+                if (offset < aop->coff) {
+                        emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
+                                  aop->coff - offset);
+                }
 
-    /* if critical function then turn interrupts off */
-    if (SPEC_CRTCL(fetype))
-        emitcode("cli");
+                aop->coff = offset;
+                emitcode ("st", "x,%s", s);
+                break;
 
-    if (IS_ISR(sym->etype)) {
-    }
+        case AOP_Z:
+                if (aop->code) {
+                        if (offset > aop->coff) {
+                                emitcode ("adiw", "r30,%d",
+                                          offset - aop->coff);
+                        }
+                        else {
+                                emitcode ("sbiw", "r30,%d",
+                                          aop->coff - offset);
+                        }
+                        emitcode ("lpm", "%s,z", s);
+                }
+                else {
+                        /* we can use lds */
+                        if (offset > aop->coff) {
+                                emitcode ("sdd", "z+%d,%s",
+                                          offset - aop->coff, s);
+                        }
+                        else {
+                                emitcode ("sbiw", "%s,%d",
+                                          aop->aopu.aop_ptr->name,
+                                          aop->coff - offset);
+                                aop->coff = offset;
+                                emitcode ("ld", "%s,z", s);
+                        }
+                }
+                break;
 
-    /* save the preserved registers that are used in this function */
-    for (i = R2_IDX ; i <= R15_IDX ; i++ ) {
-       if (bitVectBitValue(sym->regsUsed,i)) {
-           _G.nRegsSaved++;
-           emitcode("push","%s",avr_regWithIdx(i)->name);
-       }
-    }
-    /* now for the pointer registers */
-    if (bitVectBitValue(sym->regsUsed,R26_IDX)) {
-       _G.nRegsSaved++;
-       emitcode("push","r26");
-    }
-    if (bitVectBitValue(sym->regsUsed,R27_IDX)) {
-       _G.nRegsSaved++;
-       emitcode("push","r27");
-    }
-    if (bitVectBitValue(sym->regsUsed,R30_IDX)) {
-       _G.nRegsSaved++;
-       emitcode("push","r30");
-    }
-    if (bitVectBitValue(sym->regsUsed,R31_IDX)) {
-       _G.nRegsSaved++;
-       emitcode("push","r31");
-    }
-    /* adjust the stack for the function */
-    if (sym->stack) {
-       emitcode ("push","r28");
-       emitcode ("push","r29");
-       emitcode ("in","r28,__SP_L__");
-       emitcode ("in","r29,__SP_H__");
-       if (sym->stack <= 63) {
-           emitcode("sbiw","r28,%d",sym->stack);
-       } else {
-           emitcode ("subi","r28,lo8(%d)",sym->stack);
-           emitcode ("sbci","r29,hi8(%d)",sym->stack);
-       }
-       emitcode("out","__SP_L__,r28");
-       emitcode("out","__SP_H__,r29");
-    }
-}
+        case AOP_STK:
+                emitcode ("push", "%s", s);
+                break;
 
-/*-----------------------------------------------------------------*/
-/* genEndFunction - generates epilogue for functions               */
-/*-----------------------------------------------------------------*/
-static void genEndFunction (iCode *ic)
-{
-    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
-
-    /* restore stack pointer */
-    if (sym->stack <= 63) {
-       emitcode("adiw","r28,%d",sym->stack);
-    } else {
-       emitcode ("subi","r28,lo8(-%d)",sym->stack);
-       emitcode ("sbci","r29,hi8(-%d)",sym->stack);
-    }
-    emitcode("out","__SP_L__,r28");
-    emitcode("out","__SP_H__,r29");
+        case AOP_CRY:
+                /* if used only for a condition code check */
+                assert (toupper ((unsigned char)*s) == 'R');
+                if (offset == 0) {
+                        emitcode ("xrl", "r0,r0");
+                        emitcode ("cpi", "%s,0", s);
+                }
+                else {
+                        emitcode ("cpc", "r0,%s", s);
+                }
+                break;
 
-    /* pop frame pointer */
-    emitcode ("pop","r29");
-    emitcode ("pop","r28");
+        case AOP_STR:
+                aop->coff = offset;
+                if (strcmp (aop->aopu.aop_str[offset], s))
+                        emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset],
+                                  s);
+                break;
 
-    /* restore preserved registers */
-    if (bitVectBitValue(sym->regsUsed,R31_IDX)) {
-       _G.nRegsSaved--;
-       emitcode("pop","r31");
-    }
-    if (bitVectBitValue(sym->regsUsed,R30_IDX)) {
-       _G.nRegsSaved--;
-       emitcode("pop","r30");
-    }
-    if (bitVectBitValue(sym->regsUsed,R27_IDX)) {
-       _G.nRegsSaved--;
-       emitcode("push","r27");
-    }
-    if (bitVectBitValue(sym->regsUsed,R26_IDX)) {
-       _G.nRegsSaved--;
-       emitcode("push","r26");
-    }
-    for (i = R15_IDX ; i >= R2_IDX ; i-- ) {
-       if (bitVectBitValue(sym->regsUsed,i)) {
-           _G.nRegsSaved--;
-           emitcode("pop","%s",avr_regWithIdx(i)->name);
-       }
-    }
+        case AOP_STK_D:
+                emitcode ("std", "y+%d,%s", offset, s);
+                break;
 
-    if (IS_ISR(sym->etype)) {
-    }
+        default:
+                werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                        "aopPut got unsupported aop->type");
+                exit (0);
+        }
 
-    if (SPEC_CRTCL(fetype))
-        emitcode("sti");
 }
 
+#define AOP(op) op->aop
+#define AOP_TYPE(op) AOP(op)->type
+#define AOP_SIZE(op) AOP(op)->size
+#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_X || \
+                       AOP_TYPE(x) == AOP_Z))
+#define AOP_INPREG(x) (x && (x->type == AOP_REG &&                      \
+                      ((x->aopu.aop_reg[0] == avr_regWithIdx(R26_IDX) && x->aopu.aop_reg[1] == avr_regWithIdx(R27_IDX)) || \
+                       (x->aopu.aop_reg[0] == avr_regWithIdx(R30_IDX) && x->aopu.aop_reg[1] == avr_regWithIdx(R31_IDX)) )))
+#define AOP_ISX(x) (x && (x->type == AOP_REG &&                      \
+                      ((x->aopu.aop_reg[0] == avr_regWithIdx(R26_IDX) && x->aopu.aop_reg[1] == avr_regWithIdx(R27_IDX)))))
+#define AOP_ISZ(x) (x && (x->type == AOP_REG &&                      \
+                      ((x->aopu.aop_reg[0] == avr_regWithIdx(R30_IDX) && x->aopu.aop_reg[1] == avr_regWithIdx(R31_IDX)))))
+
 /*-----------------------------------------------------------------*/
-/* genRet - generate code for return statement                     */
+/* genNotFloat - generates not for float operations                */
 /*-----------------------------------------------------------------*/
-static void genRet (iCode *ic)
+static void
+genNotFloat (operand * op, operand * res)
 {
-    int size,offset = 0 , pushed = 0;
-    
-    /* if we have no return value then
-       just generate the "ret" */
-    if (!IC_LEFT(ic)) 
-       goto jumpret;       
-    
-    /* we have something to return then
-       move the return value into place */
-    aopOp(IC_LEFT(ic),ic,FALSE);
-    size = AOP_SIZE(IC_LEFT(ic));
-    
-    while (size--) {
-       char *l ;
-       l = aopGet(AOP(IC_LEFT(ic)),offset);
-       if (strcmp(fReturn[offset],l))
-           emitcode("mov","%s,%s",fReturn[offset++],l);
-    }    
-
-    freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
-    
- jumpret:
-       /* generate a jump to the return label
-          if the next is not the return statement */
-    if (!(ic->next && ic->next->op == LABEL &&
-         IC_LABEL(ic->next) == returnLabel))
-       
-       emitcode("rjmp","L%05d",returnLabel->key);
-    
+        int size, offset;
+        char *l;
+        symbol *tlbl;
+
+        /* we will put 127 in the first byte of
+           the result */
+        aopPut (AOP (res), "127", 0);
+        size = AOP_SIZE (op) - 1;
+        offset = 1;
+
+        l = aopGet (op->aop, offset++);
+        MOVR0 (l);
+
+        while (size--) {
+                emitcode ("or", "R0,%s", aopGet (op->aop, offset++));
+        }
+        tlbl = newiTempLabel (NULL);
+
+        tlbl = newiTempLabel (NULL);
+        aopPut (res->aop, zero, 1);
+        emitcode ("cpi", "r0,0");
+        emitcode ("breq", "L%05d", tlbl->key);
+        aopPut (res->aop, one, 1);
+        emitcode ("", "L%05d:", tlbl->key);
+
+        size = res->aop->size - 2;
+        offset = 2;
+        /* put zeros in the rest */
+        while (size--)
+                aopPut (res->aop, zero, offset++);
 }
 
 /*-----------------------------------------------------------------*/
-/* genLabel - generates a label                                    */
+/* opIsGptr: returns non-zero if the passed operand is       */
+/* a generic pointer type.             */
 /*-----------------------------------------------------------------*/
-static void genLabel (iCode *ic)
+static int
+opIsGptr (operand * op)
 {
-    /* special case never generate */
-    if (IC_LABEL(ic) == entryLabel)
-        return ;
+        sym_link *type = operandType (op);
 
-    emitcode("","L%05d:",IC_LABEL(ic)->key);
+        if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type)) {
+                return 1;
+        }
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* genGoto - generates a ljmp                                      */
+/* getDataSize - get the operand data size                         */
 /*-----------------------------------------------------------------*/
-static void genGoto (iCode *ic)
+static int
+getDataSize (operand * op)
 {
-    emitcode ("rjmp","L%05d:",(IC_LABEL(ic)->key+100));
+        int size;
+        size = AOP_SIZE (op);
+        if (size == GPTRSIZE) {
+                sym_link *type = operandType (op);
+                if (IS_GENPTR (type)) {
+                        /* generic pointer; arithmetic operations
+                         * should ignore the high byte (pointer type).
+                         */
+                        size--;
+                }
+        }
+        return size;
 }
 
 /*-----------------------------------------------------------------*/
-/* findLabelBackwards: walks back through the iCode chain looking  */
-/* for the given label. Returns number of iCode instructions      */
-/* between that label and given ic.                               */
-/* Returns zero if label not found.                               */
+/* toBoolean - emit code for orl a,operator(sizeop)                */
 /*-----------------------------------------------------------------*/
-static int findLabelBackwards(iCode *ic, int key)
+static void
+toBoolean (operand * oper, char *r, bool clr)
 {
-    int count = 0;
-    
-    while (ic->prev)
-    {
-        ic = ic->prev;
-        count++;
-        
-        if (ic->op == LABEL && IC_LABEL(ic)->key == key)
-        {
-            /* printf("findLabelBackwards = %d\n", count); */
-            return count;
+        int size = AOP_SIZE (oper);
+        int offset = 0;
+        if (clr) {
+                emitcode ("clr", "%s", r);
+                while (size--)
+                        emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
+        } else {
+                size--;
+                emitcode("mov","%s,%s",r,aopGet (AOP (oper), offset++));
+                if (size) while (size--) emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
         }
-    }
-    
-    return 0;
 }
 
+
 /*-----------------------------------------------------------------*/
-/* genPlusIncr :- does addition with increment if possible         */
+/* genNot - generate code for ! operation                          */
 /*-----------------------------------------------------------------*/
-static bool genPlusIncr (iCode *ic)
+static void
+genNot (iCode * ic)
 {
-    unsigned int icount ;
-    
-    /* will try to generate an increment */
-    /* if the right side is not a literal 
-       we cannot */
-    if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
-        return FALSE ;
-    
-    icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
-    
-    /* if the sizes are greater than 2 or they are not the same regs
-       then we cannot */
-    if (AOP_SIZE(IC_RESULT(ic)) > 2 ||
-        AOP_SIZE(IC_LEFT(ic)) > 2   ||
-       !sameRegs(AOP(IC_LEFT(ic)),AOP(IC_RIGHT(ic))))
-        return FALSE ;
-    
-    /* so we know LEFT & RESULT in the same registers and add
-       amount <= 63 */
-    /* for short & char types */
-    if (AOP_SIZE(IC_RESULT(ic)) < 2) {
-       if (icount == 1) {
-           emitcode("inc","%s",aopGet(AOP(IC_LEFT(ic)),0));
-           return TRUE;
-       } 
-       emicode("subi","%s,lo8(%d)",aopGet(AOP(IC_LEFT(ic)),0),-icount);
-       return TRUE;
-    }
+        symbol *tlbl;
+        sym_link *optype = operandType (IC_LEFT (ic));
+        int size, offset = 1;
 
-    /* if register pair and starts with 26/30 then adiw */
-    if (isRegPair(AOP(IC_RESULT(ic))) && icount > 0 && icount < 64 &&
-       ( IS_REGIDX(AOP(IC_RESULT(ic)),R26_IDX) ||
-         IS_REGIDX(AOP(IC_RESULT(ic)),R30_IDX) )) {
-       emitcode("adiw","%s,%d",aopGet(AOP(IC_RESULT(ic)),0),icount);
-       return TRUE;
-    }
-    
-    /* use subi */
-    emitcode("subi","%s,lo8(%d)",aopGet(AOP(IC_RESULT(ic)),0),-icount);
-    emitcode("sbci","%s,hi8(%d)",aopGet(AOP(IC_RESULT(ic)),1),-icount);
-    return TRUE;
-}
+        /* assign asmOps to operand & result */
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        aopOp (IC_RESULT (ic), ic, TRUE);
 
-/* This is the pure and virtuous version of this code.
- * I'm pretty certain it's right, but not enough to toss the old 
- * code just yet...
- */
-static void adjustArithmeticResult(iCode *ic)
-{
-    if (opIsGptr(IC_RESULT(ic)) &&
-       opIsGptr(IC_LEFT(ic))   &&
-       !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
-    {
-       aopPut(AOP(IC_RESULT(ic)),
-              aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1),
-              GPTRSIZE - 1);
-    }
+        /* if type float then do float */
+        if (IS_FLOAT (optype)) {
+                genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
+                goto release;
+        }
+        emitcode ("clr", "r24");
+        tlbl = newiTempLabel (NULL);
+        size = AOP_SIZE (IC_LEFT (ic));
+        offset = 0;
+        if (size == 1) {
+                emitcode ("cpse", "%s,r24", aopGet (AOP (IC_LEFT (ic)), 0));
+        }
+        else {
+                while (size--) {
+                        if (offset)
+                                emitcode ("cpc", "%s,r24",
+                                          aopGet (AOP (IC_LEFT (ic)),
+                                                  offset));
+                        else
+                                emitcode ("cpi", "%s,0",
+                                          aopGet (AOP (IC_LEFT (ic)),
+                                                  offset));
+                        offset++;
+                }
+                emitcode ("bne", "L%05d", tlbl->key);
+        }
+        emitcode ("ldi", "r24,1");
+        emitcode ("", "L%05d:", tlbl->key);
+        aopPut (AOP (IC_RESULT (ic)), "r24", 0);
+        size = AOP_SIZE (IC_RESULT (ic)) - 1;
+        offset = 1;
+        while (size--)
+                aopPut (AOP (IC_RESULT (ic)), zero, offset++);
 
-    if (opIsGptr(IC_RESULT(ic)) &&
-        opIsGptr(IC_RIGHT(ic))   &&
-       !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
-    {
-       aopPut(AOP(IC_RESULT(ic)),
-              aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1),
-              GPTRSIZE - 1);
-    }
 
-    if (opIsGptr(IC_RESULT(ic))           &&
-        AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE   &&
-        AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE  &&
-        !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
-        !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
-        char buffer[5];
-        sprintf(buffer,"%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
-        aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
-     }
+      release:
+        /* release the aops */
+        freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* genPlus - generates code for addition                           */
+/* genCpl - generate code for complement                           */
 /*-----------------------------------------------------------------*/
-static void genPlus (iCode *ic)
+static void
+genCpl (iCode * ic)
 {
-    int size, offset = 0;
-
-    /* special cases :- */
-
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RIGHT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
-
-    /* if I can do an increment instead
-    of add then GOOD for ME */
-    if (genPlusIncr (ic) == TRUE)
-        goto release;   
-
-    size = getDataSize(IC_RESULT(ic));
-
-    while(size--){
-       aopPut(AOP(IC_RESULT(ic)),aopGet(AOP(IC_RIGHT(ic)),offset),offset);
-       if(offset == 0)
-           emitcode("add","%s,%s",aopGet(AOP(IC_RESULT(ic)),offset),
-                    aopGet(AOP(IC_LEFT(ic)),offset));
-       else
-           emitcode("adc","%s,%s",aopGet(AOP(IC_RESULT(ic)),offset),
-                    aopGet(AOP(IC_LEFT(ic)),offset));
-       }
-    }
+        int offset = 0;
+        int size;
+        int samer;
+
+        /* assign asmOps to operand & result */
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        aopOp (IC_RESULT (ic), ic, TRUE);
+        samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
+        size = AOP_SIZE (IC_RESULT (ic));
+        while (size--) {
+                char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+                if (samer) {
+                        emitcode ("com", "%s", l);
+                }
+                else {
+                        aopPut (AOP (IC_RESULT (ic)), l, offset);
+                        emitcode ("com", "%s",
+                                  aopGet (AOP (IC_RESULT (ic)), offset));
+                }
+                offset++;
+        }
 
-    adjustArithmeticResult(ic);
+        /* release the aops */
+        freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
 
-release:
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+/*-----------------------------------------------------------------*/
+/* genUminusFloat - unary minus for floating points                */
+/*-----------------------------------------------------------------*/
+static void
+genUminusFloat (operand * op, operand * result)
+{
+        int size, offset = 0;
+        char *l;
+        /* for this we just need to flip the
+           first it then copy the rest in place */
+        size = AOP_SIZE (op) - 1;
+        l = aopGet (AOP (op), 3);
+
+        emitcode ("ldi", "r24,0x80");
+        if (sameRegs (AOP (op), AOP (result))) {
+                emitcode ("eor", "%s,r24", l);
+        }
+        else {
+                aopPut (AOP (result), l, 3);
+                emitcode ("eor", "%s,r24", aopGet (AOP (result), 3));
+        }
+        while (size--) {
+                aopPut (AOP (result), aopGet (AOP (op), offset), offset);
+                offset++;
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genMinusDec :- does subtraction with deccrement if possible     */
+/* genUminus - unary minus code generation                         */
 /*-----------------------------------------------------------------*/
-static bool genMinusDec (iCode *ic)
+static void
+genUminus (iCode * ic)
 {
-    unsigned int icount ;
-    
-    /* will try to generate an increment */
-    /* if the right side is not a literal 
-       we cannot */
-    if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
-        return FALSE ;
-    
-    icount = floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
-    
-    /* if the sizes are greater than 2 or they are not the same regs
-       then we cannot */
-    if (AOP_SIZE(IC_RESULT(ic)) > 2 ||
-        AOP_SIZE(IC_LEFT(ic)) > 2   ||
-       !sameRegs(AOP(IC_LEFT(ic)),AOP(IC_RIGHT(ic))))
-        return FALSE ;
-    
-    /* so we know LEFT & RESULT in the same registers and add
-       amount <= 63 */
-    /* for short & char types */
-    if (AOP_SIZE(IC_RESULT(ic)) < 2) {
-       if (icount == 1) {
-           emitcode("dec","%s",aopGet(AOP(IC_LEFT(ic)),0));
-           return TRUE;
-       } 
-       emicode("subi","%s,lo8(%d)",aopGet(AOP(IC_LEFT(ic)),0),icount);
-       return TRUE;
-    }
+        int offset, size;
+        sym_link *optype, *rtype;
+        int samer;
 
-    /* if register pair and starts with 26/30 then adiw */
-    if (isRegPair(AOP(IC_RESULT(ic))) && icount > 0 && icount < 64 &&
-       ( IS_REGIDX(AOP(IC_RESULT(ic)),R26_IDX) ||
-         IS_REGIDX(AOP(IC_RESULT(ic)),R30_IDX) )) {
-       emitcode("sbiw","%s,%d",aopGet(AOP(IC_RESULT(ic)),0),icount);
-       return TRUE;
-    }
-    
-    /* use subi */
-    emitcode("subi","%s,lo8(%d)",aopGet(AOP(IC_RESULT(ic)),0),icount);
-    emitcode("sbci","%s,hi8(%d)",aopGet(AOP(IC_RESULT(ic)),1),icount);
-    return TRUE;
+        /* assign asmops */
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        aopOp (IC_RESULT (ic), ic, TRUE);
+
+        optype = operandType (IC_LEFT (ic));
+        rtype = operandType (IC_RESULT (ic));
+
+        /* if float then do float stuff */
+        if (IS_FLOAT (optype)) {
+                genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
+                goto release;
+        }
+
+        /* otherwise subtract from zero */
+        size = AOP_SIZE (IC_LEFT (ic));
+        offset = 0;
+        samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
+        if (size == 1) {
+                if (samer) {
+                        emitcode ("neg", "%s",
+                                  aopGet (AOP (IC_LEFT (ic)), 0));
+                }
+                else {
+                        aopPut (AOP (IC_RESULT (ic)),
+                                aopGet (AOP (IC_LEFT (ic)), 0), 0);
+                        emitcode ("neg", "%s",
+                                  aopGet (AOP (IC_RESULT (ic)), 0));
+                }
+        }
+        else {
+                offset = size - 1;
+                while (size--) {
+                        char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+                        if (!samer) {
+                                aopPut (AOP (IC_RESULT (ic)), l, offset);
+                                l = aopGet (AOP (IC_RESULT (ic)), offset);
+                        }
+                        if (offset)
+                                emitcode ("com", "%s", l);
+                        else
+                                emitcode ("neg", "%s", l);
+                        offset--;
+                }
+                size = AOP_SIZE (IC_LEFT (ic)) - 1;
+                offset = 1;
+                while (size--) {
+                        emitcode ("sbci", "%s,0xff",
+                                  aopGet (AOP (IC_RESULT (ic)), 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))))) {
+                symbol *tlbl = newiTempLabel (NULL);
+                emitcode ("clr", "r0");
+                emitcode ("brcc", "L%05d", tlbl->key);
+                emitcode ("com", "r0");
+                emitcode ("", "L%05d:", tlbl->key);
+                while (size--)
+                        aopPut (AOP (IC_RESULT (ic)), "r0", offset++);
+        }
+
+      release:
+        /* release the aops */
+        freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* addSign - complete with sign                                    */
+/* assignResultValue -               */
 /*-----------------------------------------------------------------*/
-static void addSign(operand *result, int offset, int sign)
+static void
+assignResultValue (operand * oper)
 {
-    int size = (getDataSize(result) - offset);
-    if(size > 0){
-        if(sign){
-            emitcode("rlc","a");
-            emitcode("subb","a,acc");
-            while(size--)
-                aopPut(AOP(result),"a",offset++); 
-        } else
-            while(size--)
-                aopPut(AOP(result),zero,offset++);
-    }
+        int offset = 0;
+        int size = AOP_SIZE (oper);
+        while (size--) {
+                aopPut (AOP (oper), fAVRReturn[offset], offset);
+                offset++;
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genMinus - generates code for subtraction                       */
+/* saveZreg - if indirect call then save z-pointer register        */
 /*-----------------------------------------------------------------*/
-static void genMinus (iCode *ic)
+static void
+saveZreg (iCode * ic)
 {
-    int size, offset = 0;
-    unsigned long lit = 0L;
-    
-    aopOp (IC_LEFT(ic),ic,FALSE);
-    aopOp (IC_RIGHT(ic),ic,FALSE);
-    aopOp (IC_RESULT(ic),ic,TRUE);
-    
-    /* if I can do an decrement instead
-       of subtract then GOOD for ME */
-    if (genMinusDec (ic) == TRUE)
-        goto release;   
-    
-    size = getDataSize(IC_RESULT(ic));   
-    
-    while (size--) {
-       aopPut(AOP(IC_RESULT(ic)),aopGet(AOP(IC_RIGHT(ic)),offset),offset);
-       if(offset == 0)
-           emitcode("sub","%s,%s",aopGet(AOP(IC_RESULT(ic)),offset),
-                    aopGet(AOP(IC_LEFT(ic)),offset));
-       else
-           emitcode("sbc","%s,%s",aopGet(AOP(IC_RESULT(ic)),offset),
-                    aopGet(AOP(IC_LEFT(ic)),offset));
-    }
-
-    adjustArithmeticResult(ic);
-    
- release:
-    freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+        /* only if live accross this call */
+        if (ic->regsSaved == 0 &&
+            (bitVectBitValue (ic->rMask, R30_IDX) ||
+             bitVectBitValue (ic->rMask, R31_IDX))) {
+                ic->regsSaved = 1;
+                emitcode ("push", "r30");
+                emitcode ("push", "r31");
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genMultOneByte : 8 bit multiplication & division                */
+/* popZreg - restore values of zreg                                */
 /*-----------------------------------------------------------------*/
-static void genMultOneByte (operand *left,
-                            operand *right,
-                            operand *result)
+static void
+popZreg (iCode * ic)
 {
-    link *opetype = operandType(result);
-    char *l ;
-    symbol *lbl ;
-    int size,offset;
-    
-    /* (if two literals, the value is computed before) */
-    /* if one literal, literal on the right */
-    if (AOP_TYPE(left) == AOP_LIT){
-        operand *t = right;
-        right = left;
-        left = t;
-    }
-    
-    size = AOP_SIZE(result);
-
-    if (SPEC_USIGN(opetype)) {
-       emitcode("mul","%s,%s",
-                aopGet(IC_LEFT(ic),0),
-                aopGet(IC_RIGHT(ic),0));
-    } else {
-       emitcode("muls","%s,%s",
-                aopGet(IC_LEFT(ic),0),
-                aopGet(IC_RIGHT(ic),0));
-    }
-    aopPut(AOP(IC_RESULT(ic)),"r0",0);
-    if (size > 1){
-       aopPut(AOP(IC_RESULT(ic)),"r1",1);
-       offset = 2;
-       size -= 2;
-       if (SPEC_USIGN(opetype)) {
-           while(size--) {
-               aopPut(AOP(IC_RESULT(ic)),zero,offset++);
-           }
-       } else {
-           lbl = newiTempLabel(NULL);
-           emitcode("ldi","r24,0");
-           emitcode("brcc","L%05d",lbl->key);
-           emitcode("ldi","r24,lo8(-1)");
-           emitcode("","L%05d:",lbl->key);
-           while (size--) aopPut(AOP(IC_RESULT(ic)),"r24",offset++);
-       }
-    }
-    return;
+        if (ic->regsSaved) {
+                emitcode ("pop", "r31");
+                emitcode ("pop", "r30");
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genMult - generates code for multiplication                     */
+/* genIpush - genrate code for pushing this gets a little complex  */
 /*-----------------------------------------------------------------*/
-static void genMult (iCode *ic)
+static void
+genIpush (iCode * ic)
 {
-    operand *left = IC_LEFT(ic);
-    operand *right = IC_RIGHT(ic);
-    operand *result= IC_RESULT(ic);   
-
-    /* assign the amsops */
-    aopOp (left,ic,FALSE);
-    aopOp (right,ic,FALSE);
-    aopOp (result,ic,TRUE);
-
-    /* if both are of size == 1 */
-    if (AOP_SIZE(left) == 1 &&
-        AOP_SIZE(right) == 1 ) {
-        genMultOneByte(left,right,result);
-        goto release ;
-    }
+        int size, offset = 0;
+        char *l;
 
-    /* should have been converted to function call */       
-    assert(1) ;
 
-release :
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+        if (!ic->parmPush) {
+                /* and the item is spilt then do nothing */
+                if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+                        return;
+        }
+        else {
+                iCode *lic;
+                for (lic = ic->next; lic; lic = lic->next)
+                        if (lic->op == PCALL)
+                                break;
+                if (lic)
+                        saveZreg (lic);
+        }
+
+        /* this is a paramter push */
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        size = AOP_SIZE (IC_LEFT (ic));
+        while (size--) {
+                l = aopGet (AOP (IC_LEFT (ic)), offset++);
+                emitcode ("push", "%s", l);
+        }
+
+        freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genDiv - generates code for division                            */
+/* genIpop - recover the registers: can happen only for spilling   */
 /*-----------------------------------------------------------------*/
-static void genDiv (iCode *ic)
+static void
+genIpop (iCode * ic)
 {
-    /* should have been converted to function call */
-    assert(1);
+        int size, offset;
+
+
+        /* if the temp was not pushed then */
+        if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+                return;
+
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        size = AOP_SIZE (IC_LEFT (ic));
+        offset = (size - 1);
+        while (size--)
+                emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--));
+
+        freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genMod - generates code for division                            */
+/* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
-static void genMod (iCode *ic)
+static void
+genCall (iCode * ic)
 {
-    /* should have been converted to function call */
-    assert(1);
+
+        /* if send set is not empty then assign */
+        if (_G.sendSet) {
+                iCode *sic;
+                int rnum = 16;
+                for (sic = setFirstItem (_G.sendSet); sic;
+                     sic = setNextItem (_G.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);
+                                char *b = buffer;
+                                sprintf (buffer, "r%d", rnum++);
+                                if (strcmp (l, b))
+                                        emitcode ("mov", "%s,%s", b, l);
+                                offset++;
+                        }
+                        freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+                }
+                _G.sendSet = NULL;
+        }
+        /* make the call */
+        emitcode ("call", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+                                 OP_SYMBOL (IC_LEFT (ic))->rname :
+                                 OP_SYMBOL (IC_LEFT (ic))->name));
+
+        /* if we need assign a result value */
+        if ((IS_ITEMP (IC_RESULT (ic)) &&
+             (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+              OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+            IS_TRUE_SYMOP (IC_RESULT (ic))) {
+
+                aopOp (IC_RESULT (ic), ic, FALSE);
+                assignResultValue (IC_RESULT (ic));
+                freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+        }
+
+        /* adjust the stack for parameters if required */
+        if (ic->parmBytes) {
+                if (ic->parmBytes > 63) {
+                        emitcode ("sbiw", "r28,%d", ic->parmBytes);
+                }
+                else {
+                        emitcode ("subi", "r28,<(%d)",
+                                  ic->parmBytes);
+                        emitcode ("sbci", "r29,>(%d)",
+                                  ic->parmBytes);
+                }
+        }
 
 }
 
 /*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
+/* genPcall - generates a call by pointer statement                */
 /*-----------------------------------------------------------------*/
-static void genCmpGt (iCode *ic, iCode *ifx)
+static void
+genPcall (iCode * ic)
 {
-    /* should have transformed by the parser */
-    assert(1);
-}
 
-enum {
-    AVR_EQ = 0,
-    AVR_NE,
-    AVR_LT,
-    AVR_GE
-};
+        if (!ic->regsSaved)
+                saveZreg (ic);
+
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        emitcode ("mov", "r30", aopGet (AOP (IC_LEFT (ic)), 0));
+        emitcode ("mov", "r31", aopGet (AOP (IC_RIGHT (ic)), 0));
+        freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+        /* if send set is not empty the assign */
+        if (_G.sendSet) {
+                iCode *sic;
+                int rnum = 16;
+                for (sic = setFirstItem (_G.sendSet); sic;
+                     sic = setNextItem (_G.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);
+                                char *b = buffer;
+                                sprintf (b, "r%d", rnum++);
+                                if (strcmp (l, b))
+                                        emitcode ("mov", "%s,%s", b, l);
+                                offset++;
+                        }
+                        freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+                }
+                _G.sendSet = NULL;
+        }
 
-/*-----------------------------------------------------------------*/
-/* revavrcnd - reverse a conditional for avr                       */
-/*-----------------------------------------------------------------*/
-static int revavrcnd(int type)
-{
-    static struct {
-       int type, rtype;
-    } rar[] = { { AVR_EQ, AVR_NE}, {AVR_LT, AVR_GE}};
-    int i;
-
-    for (i = 0 ; i < (sizeof(rar)/sizeof(rar[0]));i++) {
-       if (rar[i].type == type) return rar[i].rtype;
-       if (rar[i].rtype== type) return rar[i].type;
-    }
-    assert(1); /* cannot happen */
-}
+        emitcode ("icall", "");
 
-static char *br_name[4] = {"breq","brne","brlt","brge"};
-static char *br_uname[4]= {"breq","brne","brlo","brcc"};
+        /* if we need assign a result value */
+        if ((IS_ITEMP (IC_RESULT (ic)) &&
+             (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+              OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+            IS_TRUE_SYMOP (IC_RESULT (ic))) {
 
-/*-----------------------------------------------------------------*/
-/* genBranch - generate the branch instruction                     */
-/*-----------------------------------------------------------------*/
-static void genBranch (iCode *ifx, int br_type, int sign)
-{
-    int tj = (IC_TRUE(ifx) ? 1 : 0) ;
-
-    if (tj) { /* if true jump */
-       char *nm = (sign ? br_name[br_type] : br_uname[br_type]);
-       emitcode(nm,"L%05d",IC_TRUE(ifx)->key);
-    } else { /* if false jump */
-       int rtype = revavrcnd(br_type);
-       char *nm = (sign ? br_name[rtype] : br_uname[rtype]);
-       emitcode(nm,"L%05d",IC_FALSE(ifx)->key);
-    }
-    ifx->generated = 1;
+                aopOp (IC_RESULT (ic), ic, FALSE);
+
+                assignResultValue (IC_RESULT (ic));
+                freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+        }
+
+        /* adjust the stack for parameters if
+           required */
+        if (ic->parmBytes) {
+                int i;
+                if (ic->parmBytes > 3) {
+                        emitcode ("mov", "a,%s", spname);
+                        emitcode ("add", "a,#0x%02x",
+                                  (-ic->parmBytes) & 0xff);
+                        emitcode ("mov", "%s,a", spname);
+                }
+                else
+                        for (i = 0; i < ic->parmBytes; i++)
+                                emitcode ("dec", "%s", spname);
+
+        }
+
+        /* adjust the stack for parameters if required */
+        if (ic->parmBytes) {
+                if (ic->parmBytes > 63) {
+                        emitcode ("sbiw", "r28,%d", ic->parmBytes);
+                }
+                else {
+                        emitcode ("subi", "r28,<(%d)",
+                                  ic->parmBytes);
+                        emitcode ("sbci", "r29,>(%d)",
+                                  ic->parmBytes);
+                }
+        }
+        if (ic->regsSaved)
+                popZreg (ic);
 }
 
 /*-----------------------------------------------------------------*/
-/* genCmpLt - less than comparisons                                */
+/* resultRemat - result  is rematerializable                       */
 /*-----------------------------------------------------------------*/
-static void genCmpLt (iCode *ic, iCode *ifx)
+static int
+resultRemat (iCode * ic)
 {
-    operand *left, *right, *result;
-    link *letype , *retype;
-    symbol *lbl;
-    int sign, size, offset =0;
-
-    left = IC_LEFT(ic);
-    right= IC_RIGHT(ic);
-    result = IC_RESULT(ic);
-
-    letype = getSpec(operandType(left));
-    retype =getSpec(operandType(right));
-    sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
-
-    /* assign the amsops */
-    aopOp (left,ic,FALSE);
-    aopOp (right,ic,FALSE);
-    aopOp (result,ic,TRUE);
-    size = AOP_SIZE(AOP(left));
-
-    if (ifx) {
-       if (size == 1) {
-           if (AOP_TYPE(AOP(right)) == AOP_LIT) {
-               emitcode("cpi","%s,lo8(%d)",aopGet(AOP(left),0),
-                        (int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
-               genBranch(ifx,AVR_LT);
-           } else { /* right != literal */
-               emitcode("cp","%s,%s",aopGet(AOP(left),0),aopGet(AOP(right),0));
-               genBranch(ifx,AVR_LT);
-       } else { /* size != 1 */
-           while (size--) {
-               if (offset = 0) 
-                   emitcode("cp","%s,%s",aopGet(AOP(left),0),aopGet(AOP(right),0));
-               else
-                   emitcode("cpc","%s,%s",aopGet(AOP(left),offset),aopGet(AOP(right),offset));
-               offset++;
-           }
-           genBranch(ifx,AVR_LT);
-       }
-    } else { /* no ifx */
-       emitCode("clr","r0");
-       while (size--) {
-           if (offset = 0) 
-               emitcode("cp","%s,%s",aopGet(AOP(left),0),aopGet(AOP(right),0));
-           else
-               emitcode("cpc","%s,%s",aopGet(AOP(left),offset),aopGet(AOP(right),offset));
-           offset++;
-       }
-       lbl = newiTempLabel(NULL);
-       if (sign) emitcode(br_uname[AVR_GE],"L%05d",lbl->key);
-       else emitcode(br_name[AVR_GE],"L%05d",lbl->key);
-       emitcode("inc","r0");
-       emitcode("","L%05d:",lbl->key);
-       aopPut(AOP(result),"r0",0);
-       size = AOP_SIZE(AOP(result)) - 1;
-       offset = 1;
-       while (size--) aopPut(AOP(result),zero,offset++);
-    }
+        if (SKIP_IC (ic) || ic->op == IFX)
+                return 0;
+
+        if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))) {
+                symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+                if (sym->remat && !POINTER_SET (ic))
+                        return 1;
+        }
 
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+        return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to                          */
+/* genFunction - generated code for function entry                 */
 /*-----------------------------------------------------------------*/
-static void genCmpEq (iCode *ic, iCode *ifx)
+static void
+genFunction (iCode * ic)
 {
-    operand *left, *right, *result;
-
-    aopOp((left=IC_LEFT(ic)),ic,FALSE);
-    aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
-    /* if literal, literal on the right or 
-    if the right is in a pointer register and left 
-    is not */
-    if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
-        (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
-        operand *t = IC_RIGHT(ic);
-        IC_RIGHT(ic) = IC_LEFT(ic);
-        IC_LEFT(ic) = t;
-    }
+        symbol *sym;
+        sym_link *ftype;
+        int i = 0;
+
+        _G.nRegsSaved = 0;
+        /* create the function header */
+        emitcode (";", "-----------------------------------------");
+        emitcode (";", " function %s",
+                  (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+        emitcode (";", "-----------------------------------------");
+
+        emitcode ("", "%s:", sym->rname);
+        ftype = operandType (IC_LEFT (ic));
 
+        /* if critical function then turn interrupts off */
+        if (IFFUNC_ISCRITICAL (ftype))
+                emitcode ("cli", "");
 
-release:
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);
+        if (IFFUNC_ISISR (sym->type)) {
+        }
+
+        /* save the preserved registers that are used in this function */
+        for (i = R2_IDX; i <= R15_IDX; i++) {
+                if (bitVectBitValue (sym->regsUsed, i)) {
+                        _G.nRegsSaved++;
+                        emitcode ("push", "%s", avr_regWithIdx (i)->name);
+                }
+        }
+        /* now for the pointer registers */
+        if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
+                _G.nRegsSaved++;
+                emitcode ("push", "r26");
+        }
+        if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
+                _G.nRegsSaved++;
+                emitcode ("push", "r27");
+        }
+        if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
+                _G.nRegsSaved++;
+                emitcode ("push", "r30");
+        }
+        if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
+                _G.nRegsSaved++;
+                emitcode ("push", "r31");
+        }
+        /* adjust the stack for the function */
+        if (sym->stack) {
+                emitcode ("push", "r28");
+                emitcode ("push", "r29");
+                emitcode ("in", "r28,__SP_L__");
+                emitcode ("in", "r29,__SP_H__");
+                if (sym->stack <= 63) {
+                        emitcode ("sbiw", "r28,%d", sym->stack);
+                }
+                else {
+                        emitcode ("subi", "r28,<(%d)", sym->stack);
+                        emitcode ("sbci", "r29,>(%d)", sym->stack);
+                }
+                emitcode ("out", "__SP_L__,r28");
+                emitcode ("out", "__SP_H__,r29");
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* ifxForOp - returns the icode containing the ifx for operand     */
+/* genEndFunction - generates epilogue for functions               */
 /*-----------------------------------------------------------------*/
-static iCode *ifxForOp ( operand *op, iCode *ic )
+static void
+genEndFunction (iCode * ic)
 {
-    /* if true symbol then needs to be assigned */
-    if (IS_TRUE_SYMOP(op))
-        return NULL ;
-
-    /* if this has register type condition and
-    the next instruction is ifx with the same operand
-    and live to of the operand is upto the ifx only then */
-    if (ic->next &&
-        ic->next->op == IFX &&
-        IC_COND(ic->next)->key == op->key &&
-        OP_SYMBOL(op)->liveTo <= ic->next->seq )
-        return ic->next;
-
-    return NULL;
+        symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+        int i;
+
+        /* restore stack pointer */
+        if (sym->stack) {
+                if (sym->stack <= 63) {
+                        emitcode ("adiw", "r28,%d", sym->stack);
+                }
+                else {
+                        emitcode ("subi", "r28,<(-%d)", sym->stack);
+                        emitcode ("sbci", "r29,>(-%d)", sym->stack);
+                }
+                emitcode ("out", "__SP_L__,r28");
+                emitcode ("out", "__SP_H__,r29");
+
+                /* pop frame pointer */
+                emitcode ("pop", "r29");
+                emitcode ("pop", "r28");
+        }
+        /* restore preserved registers */
+        if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
+                _G.nRegsSaved--;
+                emitcode ("pop", "r31");
+        }
+        if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
+                _G.nRegsSaved--;
+                emitcode ("pop", "r30");
+        }
+        if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
+                _G.nRegsSaved--;
+                emitcode ("pop", "r27");
+        }
+        if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
+                _G.nRegsSaved--;
+                emitcode ("pop", "r26");
+        }
+        for (i = R15_IDX; i >= R2_IDX; i--) {
+                if (bitVectBitValue (sym->regsUsed, i)) {
+                        _G.nRegsSaved--;
+                        emitcode ("pop", "%s", avr_regWithIdx (i)->name);
+                }
+        }
+
+        if (IFFUNC_ISCRITICAL (sym->type))
+                emitcode ("sti", "");
+
+        if (options.debug && currFunc) {
+                debugFile->writeEndFunction (currFunc, ic, 1);
+        }
+
+        if (IFFUNC_ISISR (sym->type)) {
+                emitcode ("rti", "");
+        }
+        else {
+                emitcode ("ret", "");
+        }
+
 }
+
 /*-----------------------------------------------------------------*/
-/* genAndOp - for && operation                                     */
+/* genRet - generate code for return statement                     */
 /*-----------------------------------------------------------------*/
-static void genAndOp (iCode *ic)
+static void
+genRet (iCode * ic)
 {
-    operand *left,*right, *result;
-    symbol *tlbl;
-
-    /* note here that && operations that are in an
-    if statement are taken away by backPatchLabels
-    only those used in arthmetic operations remain */
-    aopOp((left=IC_LEFT(ic)),ic,FALSE);
-    aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,FALSE);
-
-    /* if both are bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right) == AOP_CRY ) {
-        emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-        emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
-        outBitC(result);
-    } else {
-        tlbl = newiTempLabel(NULL);
-        toBoolean(left);    
-        emitcode("jz","%05d$",tlbl->key+100);
-        toBoolean(right);
-        emitcode("","%05d$:",tlbl->key+100);
-        outBitAcc(result);
-    }
+        int size, offset = 0;
 
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);
-}
+        /* if we have no return value then
+           just generate the "ret" */
+        if (!IC_LEFT (ic))
+                goto jumpret;
 
+        /* we have something to return then
+           move the return value into place */
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        size = AOP_SIZE (IC_LEFT (ic));
 
-/*-----------------------------------------------------------------*/
-/* genOrOp - for || operation                                      */
-/*-----------------------------------------------------------------*/
-static void genOrOp (iCode *ic)
-{
-    operand *left,*right, *result;
-    symbol *tlbl;
-
-    /* note here that || operations that are in an
-    if statement are taken away by backPatchLabels
-    only those used in arthmetic operations remain */
-    aopOp((left=IC_LEFT(ic)),ic,FALSE);
-    aopOp((right=IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,FALSE);
-
-    /* if both are bit variables */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right) == AOP_CRY ) {
-        emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-        emitcode("orl","c,%s",AOP(right)->aopu.aop_dir);
-        outBitC(result);
-    } else {
-        tlbl = newiTempLabel(NULL);
-        toBoolean(left);
-        emitcode("jnz","%05d$",tlbl->key+100);
-        toBoolean(right);
-        emitcode("","%05d$:",tlbl->key+100);
-        outBitAcc(result);
-    }
+        while (size--) {
+                if (AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) {
+                        emitcode ("ldi", "%s,%s(%d)", fAVRReturn[offset],
+                                  larray[offset],
+                                  (int) ulFromVal (AOP (IC_LEFT (ic))->
+                                                      aopu.aop_lit), offset);
+                }
+                else {
+                        char *l;
+                        l = aopGet (AOP (IC_LEFT (ic)), offset);
+                        if (strcmp (fAVRReturn[offset], l))
+                                emitcode ("mov", "%s,%s", fAVRReturn[offset],
+                                          l);
+                }
+                offset++;
+        }
+
+        freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+      jumpret:
+        /* generate a jump to the return label
+           if the next is not the return statement */
+        if (!(ic->next && ic->next->op == LABEL &&
+              IC_LABEL (ic->next) == returnLabel))
+
+                emitcode ("rjmp", "L%05d", returnLabel->key);
 
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);            
 }
 
 /*-----------------------------------------------------------------*/
-/* isLiteralBit - test if lit == 2^n                               */
+/* genLabel - generates a label                                    */
 /*-----------------------------------------------------------------*/
-static int isLiteralBit(unsigned long lit)
+static void
+genLabel (iCode * ic)
 {
-    unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
-    0x100L,0x200L,0x400L,0x800L,
-    0x1000L,0x2000L,0x4000L,0x8000L,
-    0x10000L,0x20000L,0x40000L,0x80000L,
-    0x100000L,0x200000L,0x400000L,0x800000L,
-    0x1000000L,0x2000000L,0x4000000L,0x8000000L,
-    0x10000000L,0x20000000L,0x40000000L,0x80000000L};
-    int idx;
-    
-    for(idx = 0; idx < 32; idx++)
-        if(lit == pw[idx])
-            return idx+1;
-    return 0;
+        /* special case never generate */
+        if (IC_LABEL (ic) == entryLabel)
+                return;
+
+        emitcode ("", "L%05d:", IC_LABEL (ic)->key);
 }
 
 /*-----------------------------------------------------------------*/
-/* continueIfTrue -                                                */
+/* genGoto - generates a ljmp                                      */
 /*-----------------------------------------------------------------*/
-static void continueIfTrue (iCode *ic)
+static void
+genGoto (iCode * ic)
 {
-    if(IC_TRUE(ic))
-        emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100);
-    ic->generated = 1;
+        emitcode ("rjmp", "L%05d", (IC_LABEL (ic)->key));
 }
 
 /*-----------------------------------------------------------------*/
-/* jmpIfTrue -                                                     */
+/* genPlusIncr :- does addition with increment if possible         */
 /*-----------------------------------------------------------------*/
-static void jumpIfTrue (iCode *ic)
+static bool
+genPlusIncr (iCode * ic)
 {
-    if(!IC_TRUE(ic))
-        emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100);
-    ic->generated = 1;
+        unsigned int icount;
+        int offset = 0;
+
+        /* will try to generate an increment */
+        /* if the right side is not a literal
+           we cannot */
+        if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+                return FALSE;
+
+        icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.
+                                             aop_lit);
+
+        /* if the sizes are greater than 2 or they are not the same regs
+           then we cannot */
+        if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+                return FALSE;
+
+        /* so we know LEFT & RESULT in the same registers and add
+           amount <= 63 */
+        /* for short & char types */
+        if (AOP_SIZE (IC_RESULT (ic)) < 2) {
+                if (icount == 1) {
+                        emitcode ("inc", "%s",
+                                  aopGet (AOP (IC_LEFT (ic)), 0));
+                        return TRUE;
+                }
+                if (AOP_ISHIGHREG( AOP (IC_LEFT (ic)),0)) {
+                        emitcode ("subi", "%s,<(%d)",
+                                  aopGet (AOP (IC_LEFT (ic)), 0), 0-icount);
+                        return TRUE;
+                }
+        }
+
+        for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
+                if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
+        }
+
+        if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
+                /* if register pair and starts with 26/30 then adiw */
+                if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
+                    && icount < 64
+                    && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
+                        IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
+                        IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
+                        emitcode ("adiw", "%s,%d",
+                                  aopGet (AOP (IC_RESULT (ic)), 0), icount);
+                        return TRUE;
+                }
+
+                /* use subi */
+                emitcode ("subi", "%s,<(%d)",
+                          aopGet (AOP (IC_RESULT (ic)), 0), 0-icount);
+                emitcode ("sbci", "%s,>(%d)",
+                          aopGet (AOP (IC_RESULT (ic)), 1), 0-icount);
+                return TRUE;
+        }
+
+        /* for 32 bit longs */
+        emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
+                  0-icount);
+        emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
+                  0-icount);
+        emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
+                  0-icount);
+        emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
+                  0-icount);
+        return TRUE;
+
 }
 
-/*-----------------------------------------------------------------*/
-/* jmpTrueOrFalse -                                                */
-/*-----------------------------------------------------------------*/
-static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
+/* This is the pure and virtuous version of this code.
+ * I'm pretty certain it's right, but not enough to toss the old
+ * code just yet...
+ */
+static void
+adjustArithmeticResult (iCode * ic)
 {
-    // ugly but optimized by peephole
-    if(IC_TRUE(ic)){
-        symbol *nlbl = newiTempLabel(NULL);
-        emitcode("sjmp","%05d$",nlbl->key+100);                 
-        emitcode("","%05d$:",tlbl->key+100);
-        emitcode("ljmp","%05d$",IC_TRUE(ic)->key+100);
-        emitcode("","%05d$:",nlbl->key+100);
-    }
-    else{
-        emitcode("ljmp","%05d$",IC_FALSE(ic)->key+100);
-        emitcode("","%05d$:",tlbl->key+100);
-    }
-    ic->generated = 1;
+        if (opIsGptr (IC_RESULT (ic)) &&
+            opIsGptr (IC_LEFT (ic)) &&
+            !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)))) {
+                aopPut (AOP (IC_RESULT (ic)),
+                        aopGet (AOP (IC_LEFT (ic)), GPTRSIZE - 1),
+                        GPTRSIZE - 1);
+        }
+
+        if (opIsGptr (IC_RESULT (ic)) &&
+            opIsGptr (IC_RIGHT (ic)) &&
+            !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)))) {
+                aopPut (AOP (IC_RESULT (ic)),
+                        aopGet (AOP (IC_RIGHT (ic)), GPTRSIZE - 1),
+                        GPTRSIZE - 1);
+        }
+
+        if (opIsGptr (IC_RESULT (ic)) &&
+            AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
+            AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
+            !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
+            !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)))) {
+                char buffer[5];
+                sprintf (buffer, "%d",
+                         pointerCode (getSpec (operandType (IC_LEFT (ic)))));
+                aopPut (AOP (IC_RESULT (ic)), buffer, GPTRSIZE - 1);
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genAnd  - code for and                                          */
+/* genPlus - generates code for addition                           */
 /*-----------------------------------------------------------------*/
-static void genAnd (iCode *ic, iCode *ifx)
+static void
+genPlus (iCode * ic)
 {
-    operand *left, *right, *result;
-    int size, offset=0;  
-    unsigned long lit = 0L;
-    int bytelit = 0;
-    char buffer[10];
-
-    aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
-#ifdef DEBUG_TYPE
-    emitcode("","; Type res[%d] = l[%d]&r[%d]",
-             AOP_TYPE(result),
-             AOP_TYPE(left), AOP_TYPE(right));
-    emitcode("","; Size res[%d] = l[%d]&r[%d]",
-             AOP_SIZE(result),
-             AOP_SIZE(left), AOP_SIZE(right));
-#endif
+        int size, offset = 0;
+        int samer;
+        char *l;
 
-    /* if left is a literal & right is not then exchange them */
-    if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-       AOP_NEEDSACC(left)) {
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+        /* special cases :- */
 
-    /* if result = right then exchange them */
-    if(sameRegs(AOP(result),AOP(right))){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        aopOp (IC_RIGHT (ic), ic, FALSE);
+        aopOp (IC_RESULT (ic), ic, TRUE);
 
-    /* if right is bit then exchange them */
-    if (AOP_TYPE(right) == AOP_CRY &&
-        AOP_TYPE(left) != AOP_CRY){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
-    size = AOP_SIZE(result);
-
-    // if(bit & yy)
-    // result = bit & yy;
-    if (AOP_TYPE(left) == AOP_CRY){
-        // c = bit & literal;
-        if(AOP_TYPE(right) == AOP_LIT){
-            if(lit & 1) {
-                if(size && sameRegs(AOP(result),AOP(left)))
-                    // no change
-                    goto release;
-                emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-            } else {
-                // bit(result) = 0;
-                if(size && (AOP_TYPE(result) == AOP_CRY)){
-                    emitcode("clr","%s",AOP(result)->aopu.aop_dir);
-                    goto release;
-                }
-                if((AOP_TYPE(result) == AOP_CRY) && ifx){
-                    jumpIfTrue(ifx);
-                    goto release;
-                }
-                emitcode("clr","c");
-            }
-        } else {
-            if (AOP_TYPE(right) == AOP_CRY){
-                // c = bit & bit;
-                emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-                emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
-            } else {
-                // c = bit & val;
-                MOVA(aopGet(AOP(right),0,FALSE,FALSE));
-                // c = lsb
-                emitcode("rrc","a");
-                emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
-            }
-        }
-        // bit = c
-        // val = c
-        if(size)
-            outBitC(result);
-        // if(bit & ...)
-        else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
-        goto release ;
-    }
+        /* if I can do an increment instead
+           of add then GOOD for ME */
+        if (genPlusIncr (ic) == TRUE)
+                goto release;
+
+        size = getDataSize (IC_RESULT (ic));
+        samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+
+        while (size--) {
+                if (!samer)
+                        aopPut (AOP (IC_RESULT (ic)),
+                                aopGet (AOP (IC_LEFT (ic)), offset), offset);
+
+                if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
+
+                        if (offset == 0)
+                                l = "add";
+                        else
+                                l = "adc";
 
-    // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
-    // bit = val & 0xZZ     - size = 1, ifx = FALSE -
-    if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
-        int posbit = isLiteralBit(lit);
-        /* left &  2^n */
-        if(posbit){
-            posbit--;
-            MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
-            // bit = left & 2^n
-            if(size)
-                emitcode("mov","c,acc.%d",posbit&0x07);
-            // if(left &  2^n)
-            else{
-                if(ifx){
-                    sprintf(buffer,"acc.%d",posbit&0x07);
-                    genIfxJump(ifx, buffer);
+                        emitcode (l, "%s,%s",
+                                  aopGet (AOP (IC_RESULT (ic)), offset),
+                                  aopGet (AOP (IC_RIGHT (ic)), offset));
                 }
-                goto release;
-            }
-        } else {
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizel = AOP_SIZE(left);
-            if(size)
-                emitcode("setb","c");
-            while(sizel--){
-                if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
-                    MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
-                    // byte ==  2^n ?
-                    if((posbit = isLiteralBit(bytelit)) != 0)
-                        emitcode("jb","acc.%d,%05d$",(posbit-1)&0x07,tlbl->key+100);
-                    else{
-                        if(bytelit != 0x0FFL)
-                            emitcode("anl","a,%s",
-                                     aopGet(AOP(right),offset,FALSE,TRUE));
-                        emitcode("jnz","%05d$",tlbl->key+100);
-                    }
+                else {
+                        if (AOP_ISHIGHREG( AOP( IC_RESULT(ic)),offset)) {
+                                if (offset == 0)
+                                        l = "subi";
+                                else
+                                        l = "sbci";
+
+                                emitcode (l, "%s,%s(-%d)",
+                                          aopGet (AOP (IC_RESULT (ic)), offset),
+                                          larray[offset],
+                                          (int) ulFromVal (AOP (IC_RIGHT (ic))->
+                                                              aopu.aop_lit));
+                        } else {
+                                if (offset == 0)
+                                        l = "add";
+                                else
+                                        l = "adc";
+
+                                emitcode (l, "%s,%s",
+                                          aopGet (AOP (IC_RESULT (ic)), offset),
+                                          aopGet (AOP (IC_RIGHT (ic)), offset));
+                        }
                 }
                 offset++;
-            }
-            // bit = left & literal
-            if(size){
-                emitcode("clr","c");
-                emitcode("","%05d$:",tlbl->key+100);
-            }
-            // if(left & literal)
-            else{
-                if(ifx)
-                    jmpTrueOrFalse(ifx, tlbl);
-                goto release ;
-            }
         }
-        outBitC(result);
-        goto release ;
-    }
 
-    /* if left is same as result */
-    if(sameRegs(AOP(result),AOP(left))){
-        for(;size--; offset++) {
-            if(AOP_TYPE(right) == AOP_LIT){
-                if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF)
-                    continue;
-                else 
-                   if (bytelit == 0)
-                       aopPut(AOP(result),zero,offset);
-                   else 
-                       if (IS_AOP_PREG(result)) {
-                           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                           emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                           aopPut(AOP(result),"a",offset);
-                       } else
-                           emitcode("anl","%s,%s",
-                                    aopGet(AOP(left),offset,FALSE,TRUE),
-                                    aopGet(AOP(right),offset,FALSE,FALSE));
-            } else {
-               if (AOP_TYPE(left) == AOP_ACC)
-                   emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-               else {
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                   if (IS_AOP_PREG(result)) {
-                       emitcode("anl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-
-                   } else
-                       emitcode("anl","%s,a",
-                                aopGet(AOP(left),offset,FALSE,TRUE));
-               }
-            }
-        }
-    } else {
-        // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
-            // result = bit
-            // if(size), result in bit
-            // if(!size && ifx), conditional oper: if(left & right)
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
-            if(size)
-                emitcode("setb","c");
-            while(sizer--){
-                MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                emitcode("anl","a,%s",
-                         aopGet(AOP(left),offset,FALSE,FALSE));
-                emitcode("jnz","%05d$",tlbl->key+100);
-                offset++;
-            }
-            if(size){
-                CLRC;
-                emitcode("","%05d$:",tlbl->key+100);
-                outBitC(result);
-            } else if(ifx)
-                jmpTrueOrFalse(ifx, tlbl);
-        } else {
-           for(;(size--);offset++) {
-               // normal case
-               // result = left & right
-               if(AOP_TYPE(right) == AOP_LIT){
-                   if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF){
-                       aopPut(AOP(result),
-                              aopGet(AOP(left),offset,FALSE,FALSE),
-                              offset);
-                       continue;
-                   } else if(bytelit == 0){
-                       aopPut(AOP(result),zero,offset);
-                       continue;
-                   }
-               }
-               // faster than result <- left, anl result,right
-               // and better if result is SFR
-               if (AOP_TYPE(left) == AOP_ACC) 
-                   emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-               else {
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                   emitcode("anl","a,%s",
-                            aopGet(AOP(left),offset,FALSE,FALSE));
-               }
-               aopPut(AOP(result),"a",offset);
-           }
-       }
-    }
+        adjustArithmeticResult (ic);
 
-release :
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+      release:
+        freeAsmop (IC_LEFT (ic), NULL, ic,
+                   (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (IC_RIGHT (ic), NULL, ic,
+                   (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genOr  - code for or                                            */
+/* genMinusDec :- does subtraction with deccrement if possible     */
 /*-----------------------------------------------------------------*/
-static void genOr (iCode *ic, iCode *ifx)
+static bool
+genMinusDec (iCode * ic)
 {
-    operand *left, *right, *result;
-    int size, offset=0;
-    unsigned long lit = 0L;
-
-    aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
-#ifdef DEBUG_TYPE
-    emitcode("","; Type res[%d] = l[%d]&r[%d]",
-             AOP_TYPE(result),
-             AOP_TYPE(left), AOP_TYPE(right));
-    emitcode("","; Size res[%d] = l[%d]&r[%d]",
-             AOP_SIZE(result),
-             AOP_SIZE(left), AOP_SIZE(right));
-#endif
-
-    /* if left is a literal & right is not then exchange them */
-    if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-       AOP_NEEDSACC(left)) {
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-
-    /* if result = right then exchange them */
-    if(sameRegs(AOP(result),AOP(right))){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-
-    /* if right is bit then exchange them */
-    if (AOP_TYPE(right) == AOP_CRY &&
-        AOP_TYPE(left) != AOP_CRY){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
-    size = AOP_SIZE(result);
-
-    // if(bit | yy)
-    // xx = bit | yy;
-    if (AOP_TYPE(left) == AOP_CRY){
-        if(AOP_TYPE(right) == AOP_LIT){
-            // c = bit & literal;
-            if(lit){
-                // lit != 0 => result = 1
-                if(AOP_TYPE(result) == AOP_CRY){
-                    if(size)
-                        emitcode("setb","%s",AOP(result)->aopu.aop_dir);
-                    else if(ifx)
-                        continueIfTrue(ifx);
-                    goto release;
+        unsigned int icount;
+        int offset ;
+
+        /* will try to generate an increment */
+        /* if the right side is not a literal
+           we cannot */
+        if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+                return FALSE;
+
+        icount =
+                (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.
+                                             aop_lit);
+
+        /* if the sizes are greater than 2 or they are not the same regs
+           then we cannot */
+        if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+                return FALSE;
+
+        /* so we know LEFT & RESULT in the same registers and add
+           amount <= 63 */
+        /* for short & char types */
+        if (AOP_SIZE (IC_RESULT (ic)) < 2) {
+                if (icount == 1) {
+                        emitcode ("dec", "%s",
+                                  aopGet (AOP (IC_LEFT (ic)), 0));
+                        return TRUE;
                 }
-                emitcode("setb","c");
-            } else {
-                // lit == 0 => result = left
-                if(size && sameRegs(AOP(result),AOP(left)))
-                    goto release;
-                emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-            }
-        } else {
-            if (AOP_TYPE(right) == AOP_CRY){
-                // c = bit | bit;
-                emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-                emitcode("orl","c,%s",AOP(left)->aopu.aop_dir);
-            }
-            else{
-                // c = bit | val;
-                symbol *tlbl = newiTempLabel(NULL);
-                if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
-                    emitcode("setb","c");
-                emitcode("jb","%s,%05d$",
-                         AOP(left)->aopu.aop_dir,tlbl->key+100);
-                toBoolean(right);
-                emitcode("jnz","%05d$",tlbl->key+100);
-                if((AOP_TYPE(result) == AOP_CRY) && ifx){
-                    jmpTrueOrFalse(ifx, tlbl);
-                    goto release;
-                } else {
-                    CLRC;
-                    emitcode("","%05d$:",tlbl->key+100);
+                if (AOP_ISHIGHREG( AOP ( IC_LEFT(ic)),0)) {
+                        emitcode ("subi", "%s,<(%d)",
+                                  aopGet (AOP (IC_LEFT (ic)), 0), icount);
+                        return TRUE;
                 }
-            }
         }
-        // bit = c
-        // val = c
-        if(size)
-            outBitC(result);
-        // if(bit | ...)
-        else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
-        goto release ;
-    }
 
-    // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
-    // bit = val | 0xZZ     - size = 1, ifx = FALSE -
-    if((AOP_TYPE(right) == AOP_LIT) &&
-       (AOP_TYPE(result) == AOP_CRY) &&
-       (AOP_TYPE(left) != AOP_CRY)){
-        if(lit){
-            // result = 1
-            if(size)
-                emitcode("setb","%s",AOP(result)->aopu.aop_dir);
-            else 
-                continueIfTrue(ifx);
-            goto release;
-        } else {
-            // lit = 0, result = boolean(left)
-            if(size)
-                emitcode("setb","c");
-            toBoolean(right);
-            if(size){
-                symbol *tlbl = newiTempLabel(NULL);
-                emitcode("jnz","%05d$",tlbl->key+100);
-                CLRC;
-                emitcode("","%05d$:",tlbl->key+100);
-            } else {
-                genIfxJump (ifx,"a");
-                goto release;
-            }
+        for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
+                if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
         }
-        outBitC(result);
-        goto release ;
-    }
 
-    /* if left is same as result */
-    if(sameRegs(AOP(result),AOP(left))){
-        for(;size--; offset++) {
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
-                    continue;
-                else 
-                   if (IS_AOP_PREG(left)) {
-                       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                       emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else
-                       emitcode("orl","%s,%s",
-                                aopGet(AOP(left),offset,FALSE,TRUE),
-                                aopGet(AOP(right),offset,FALSE,FALSE));
-            } else {
-               if (AOP_TYPE(left) == AOP_ACC) 
-                   emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-               else {              
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                   if (IS_AOP_PREG(left)) {
-                       emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else
-                       emitcode("orl","%s,a",
-                                aopGet(AOP(left),offset,FALSE,TRUE));
-               }
-            }
-        }
-    } else {
-        // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
-            // result = bit
-            // if(size), result in bit
-            // if(!size && ifx), conditional oper: if(left | right)
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-            if(size)
-                emitcode("setb","c");
-            while(sizer--){
-                MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                emitcode("orl","a,%s",
-                         aopGet(AOP(left),offset,FALSE,FALSE));
-                emitcode("jnz","%05d$",tlbl->key+100);
-                offset++;
-            }
-            if(size){
-                CLRC;
-                emitcode("","%05d$:",tlbl->key+100);
-                outBitC(result);
-            } else if(ifx)
-                jmpTrueOrFalse(ifx, tlbl);
-        } else for(;(size--);offset++){
-            // normal case
-            // result = left & right
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
-                    aopPut(AOP(result),
-                           aopGet(AOP(left),offset,FALSE,FALSE),
-                           offset);
-                    continue;
+        if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
+                /* if register pair and starts with 26/30 then adiw */
+                if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
+                    && icount < 64
+                    && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
+                        IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
+                        IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
+                        emitcode ("sbiw", "%s,%d",
+                                  aopGet (AOP (IC_RESULT (ic)), 0), icount);
+                        return TRUE;
                 }
-            }
-            // faster than result <- left, anl result,right
-            // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC) 
-               emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-           else {
-               MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-               emitcode("orl","a,%s",
-                        aopGet(AOP(left),offset,FALSE,FALSE));
-           }
-           aopPut(AOP(result),"a",offset);                     
+
+                /* use subi */
+                emitcode ("subi", "%s,<(%d)",
+                          aopGet (AOP (IC_RESULT (ic)), 0), icount);
+                emitcode ("sbci", "%s,>(%d)",
+                          aopGet (AOP (IC_RESULT (ic)), 1), icount);
+                return TRUE;
         }
-    }
+        /* for 32 bit longs */
+        emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
+                  icount);
+        emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
+                  icount);
+        emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
+                  icount);
+        emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
+                  icount);
+        return TRUE;
 
-release :
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
 }
 
 /*-----------------------------------------------------------------*/
-/* genXor - code for xclusive or                                   */
+/* genMinus - generates code for subtraction                       */
 /*-----------------------------------------------------------------*/
-static void genXor (iCode *ic, iCode *ifx)
+static void
+genMinus (iCode * ic)
 {
-    operand *left, *right, *result;
-    int size, offset=0;
-    unsigned long lit = 0L;
-
-    aopOp((left = IC_LEFT(ic)),ic,FALSE);
-    aopOp((right= IC_RIGHT(ic)),ic,FALSE);
-    aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
-#ifdef DEBUG_TYPE
-    emitcode("","; Type res[%d] = l[%d]&r[%d]",
-             AOP_TYPE(result),
-             AOP_TYPE(left), AOP_TYPE(right));
-    emitcode("","; Size res[%d] = l[%d]&r[%d]",
-             AOP_SIZE(result),
-             AOP_SIZE(left), AOP_SIZE(right));
-#endif
+        int size, offset = 0, samer;
+        char *l;
 
-    /* if left is a literal & right is not ||
-       if left needs acc & right does not */
-    if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
-       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+        aopOp (IC_LEFT (ic), ic, FALSE);
+        aopOp (IC_RIGHT (ic), ic, FALSE);
+        aopOp (IC_RESULT (ic), ic, TRUE);
 
-    /* if result = right then exchange them */
-    if(sameRegs(AOP(result),AOP(right))){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
+        /* if I can do an decrement instead
+           of subtract then GOOD for ME */
+        if (genMinusDec (ic) == TRUE)
+                goto release;
 
-    /* if right is bit then exchange them */
-    if (AOP_TYPE(right) == AOP_CRY &&
-        AOP_TYPE(left) != AOP_CRY){
-        operand *tmp = right ;
-        right = left;
-        left = tmp;
-    }
-    if(AOP_TYPE(right) == AOP_LIT)
-        lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
-    size = AOP_SIZE(result);
-
-    // if(bit ^ yy)
-    // xx = bit ^ yy;
-    if (AOP_TYPE(left) == AOP_CRY){
-        if(AOP_TYPE(right) == AOP_LIT){
-            // c = bit & literal;
-            if(lit>>1){
-                // lit>>1  != 0 => result = 1
-                if(AOP_TYPE(result) == AOP_CRY){
-                    if(size)
-                        emitcode("setb","%s",AOP(result)->aopu.aop_dir);
-                    else if(ifx)
-                        continueIfTrue(ifx);
-                    goto release;
-                }
-                emitcode("setb","c");
-            } else{
-                // lit == (0 or 1)
-                if(lit == 0){
-                    // lit == 0, result = left
-                    if(size && sameRegs(AOP(result),AOP(left)))
-                        goto release;
-                    emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                } else{
-                    // lit == 1, result = not(left)
-                    if(size && sameRegs(AOP(result),AOP(left))){
-                        emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
-                        goto release;
-                    } else {
-                        emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
-                        emitcode("cpl","c");
-                    }
-                }
-            }
+        size = getDataSize (IC_RESULT (ic));
+        samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+        while (size--) {
+                if (!samer)
+                        aopPut (AOP (IC_RESULT (ic)),
+                                aopGet (AOP (IC_LEFT (ic)), offset), offset);
 
-        } else {
-            // right != literal
-            symbol *tlbl = newiTempLabel(NULL);
-            if (AOP_TYPE(right) == AOP_CRY){
-                // c = bit ^ bit;
-                emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-            }
-            else{
-                int sizer = AOP_SIZE(right);
-                // c = bit ^ val
-                // if val>>1 != 0, result = 1
-                emitcode("setb","c");
-                while(sizer){
-                    MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
-                    if(sizer == 1)
-                        // test the msb of the lsb
-                        emitcode("anl","a,#0xfe");
-                    emitcode("jnz","%05d$",tlbl->key+100);
-                   sizer--;
-                }
-                // val = (0,1)
-                emitcode("rrc","a");
-            }
-            emitcode("jnb","%s,%05d$",AOP(left)->aopu.aop_dir,(tlbl->key+100));
-            emitcode("cpl","c");
-            emitcode("","%05d$:",(tlbl->key+100));
-        }
-        // bit = c
-        // val = c
-        if(size)
-            outBitC(result);
-        // if(bit | ...)
-        else if((AOP_TYPE(result) == AOP_CRY) && ifx)
-            genIfxJump(ifx, "c");           
-        goto release ;
-    }
+                if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
 
-    if(sameRegs(AOP(result),AOP(left))){
-        /* if left is same as result */
-        for(;size--; offset++) {
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
-                    continue;
-                else
-                   if (IS_AOP_PREG(left)) {
-                       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                       emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else 
-                       emitcode("xrl","%s,%s",
-                                aopGet(AOP(left),offset,FALSE,TRUE),
-                                aopGet(AOP(right),offset,FALSE,FALSE));
-            } else {
-               if (AOP_TYPE(left) == AOP_ACC)
-                   emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-               else {
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                   if (IS_AOP_PREG(left)) {
-                       emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
-                       aopPut(AOP(result),"a",offset);
-                   } else
-                       emitcode("xrl","%s,a",
-                                aopGet(AOP(left),offset,FALSE,TRUE));
-               }
-            }
-        }
-    } else {
-        // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
-            // result = bit
-            // if(size), result in bit
-            // if(!size && ifx), conditional oper: if(left ^ right)
-            symbol *tlbl = newiTempLabel(NULL);
-            int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
-            if(size)
-                emitcode("setb","c");
-            while(sizer--){
-                if((AOP_TYPE(right) == AOP_LIT) &&
-                   (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
-                    MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
-                } else {
-                    MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-                    emitcode("xrl","a,%s",
-                             aopGet(AOP(left),offset,FALSE,FALSE));
+                        if (offset == 0)
+                                l = "sub";
+                        else
+                                l = "sbc";
+
+                        emitcode (l, "%s,%s",
+                                  aopGet (AOP (IC_RESULT (ic)), offset),
+                                  aopGet (AOP (IC_RIGHT (ic)), offset));
                 }
-                emitcode("jnz","%05d$",tlbl->key+100);
-                offset++;
-            }
-            if(size){
-                CLRC;
-                emitcode("","%05d$:",tlbl->key+100);
-                outBitC(result);
-            } else if(ifx)
-                jmpTrueOrFalse(ifx, tlbl);
-        } else for(;(size--);offset++){
-            // normal case
-            // result = left & right
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
-                    aopPut(AOP(result),
-                           aopGet(AOP(left),offset,FALSE,FALSE),
-                           offset);
-                    continue;
+                else {
+                        if (AOP_ISHIGHREG(AOP (IC_RESULT (ic)),offset)) {
+                                if (offset == 0)
+                                        l = "subi";
+                                else
+                                        l = "sbci";
+
+                                emitcode (l, "%s,%s(%d)",
+                                          aopGet (AOP (IC_RESULT (ic)), offset),
+                                          larray[offset],
+                                          (int) ulFromVal (AOP (IC_RIGHT (ic))->
+                                                              aopu.aop_lit));
+                        } else {
+                                if (offset == 0)
+                                        l = "sub";
+                                else
+                                        l = "sbc";
+
+                                emitcode (l, "%s,%s",
+                                          aopGet (AOP (IC_RESULT (ic)), offset),
+                                          aopGet (AOP (IC_RIGHT (ic)), offset));
+                        }
                 }
-            }
-            // faster than result <- left, anl result,right
-            // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC)
-               emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
-           else {
-               MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
-               emitcode("xrl","a,%s",
-                        aopGet(AOP(left),offset,FALSE,TRUE));
-           }
-           aopPut(AOP(result),"a",offset);
+                offset++;
         }
-    }
 
-release :
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE);     
+        adjustArithmeticResult (ic);
+
+      release:
+        freeAsmop (IC_LEFT (ic), NULL, ic,
+                   (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (IC_RIGHT (ic), NULL, ic,
+                   (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genInline - write the inline code out                           */
+/* genMultOneByte : 8 bit multiplication & division                */
 /*-----------------------------------------------------------------*/
-static void genInline (iCode *ic)
+static void
+genMultOneByte (operand * left, operand * right, operand * result)
 {
-    char buffer[MAX_INLINEASM];
-    char *bp = buffer;
-    char *bp1= buffer;
-    
-    _G.inLine += (!options.asmpeep);
-    strcpy(buffer,IC_INLINE(ic));
-
-    /* emit each line as a code */
-    while (*bp) {
-        if (*bp == '\n') {
-            *bp++ = '\0';
-            emitcode(bp1,"");
-            bp1 = bp;
-        } else {
-            if (*bp == ':') {
-                bp++;
-                *bp = '\0';
-                bp++;
-                emitcode(bp1,"");
-                bp1 = bp;
-            } else
-                bp++;
+        sym_link *opetype = operandType (result);
+        symbol *lbl;
+        int size, offset;
+
+        /* (if two literals, the value is computed before) */
+        /* if one literal, literal on the right */
+        if (AOP_TYPE (left) == AOP_LIT) {
+                operand *t = right;
+                right = left;
+                left = t;
         }
-    }
-    if (bp1 != bp)
-        emitcode(bp1,"");
-    /*     emitcode("",buffer); */
-    _G.inLine -= (!options.asmpeep);
-}
 
-/*-----------------------------------------------------------------*/
-/* genRRC - rotate right with carry                                */
-/*-----------------------------------------------------------------*/
-static void genRRC (iCode *ic)
-{
-    operand *left , *result ;
-    int size, offset = 0;
-    char *l;    
-
-    /* rotate right with carry */
-    left = IC_LEFT(ic);
-    result=IC_RESULT(ic);
-    aopOp (left,ic,FALSE);
-    aopOp (result,ic,FALSE);
-
-    /* move it to the result */
-    size = AOP_SIZE(result);    
-    offset = size - 1 ;
-    CLRC;
-    while (size--) {
-        l = aopGet(AOP(left),offset,FALSE,FALSE);
-        MOVA(l);
-        emitcode("rrc","a");
-        if (AOP_SIZE(result) > 1)
-            aopPut(AOP(result),"a",offset--);
-    }
-    /* now we need to put the carry into the
-    highest order byte of the result */
-    if (AOP_SIZE(result) > 1) {
-        l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
-        MOVA(l);
-    }
-    emitcode("mov","acc.7,c");
-    aopPut(AOP(result),"a",AOP_SIZE(result)-1);
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
-}
+        size = AOP_SIZE (result);
 
-/*-----------------------------------------------------------------*/
-/* genRLC - generate code for rotate left with carry               */
-/*-----------------------------------------------------------------*/
-static void genRLC (iCode *ic)
-{    
-    operand *left , *result ;
-    int size, offset = 0;
-    char *l;    
-
-    /* rotate right with carry */
-    left = IC_LEFT(ic);
-    result=IC_RESULT(ic);
-    aopOp (left,ic,FALSE);
-    aopOp (result,ic,FALSE);
-
-    /* move it to the result */
-    size = AOP_SIZE(result);    
-    offset = 0 ;
-    if (size--) {
-        l = aopGet(AOP(left),offset,FALSE,FALSE);
-        MOVA(l);
-        emitcode("add","a,acc");
-        if (AOP_SIZE(result) > 1)
-            aopPut(AOP(result),"a",offset++);
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,FALSE);
-            MOVA(l);
-            emitcode("rlc","a");
-            if (AOP_SIZE(result) > 1)
-                aopPut(AOP(result),"a",offset++);
+        if (SPEC_USIGN (opetype)) {
+                emitcode ("mul", "%s,%s", aopGet (AOP (left), 0),
+                          aopGet (AOP (right), 0));
         }
-    }
-    /* now we need to put the carry into the
-    highest order byte of the result */
-    if (AOP_SIZE(result) > 1) {
-        l = aopGet(AOP(result),0,FALSE,FALSE);
-        MOVA(l);
-    }
-    emitcode("mov","acc.0,c");
-    aopPut(AOP(result),"a",0);
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+        else {
+                emitcode ("muls", "%s,%s", aopGet (AOP (left), 0),
+                          aopGet (AOP (right), 0));
+        }
+        aopPut (AOP (result), "r0", 0);
+        if (size > 1) {
+                aopPut (AOP (result), "r1", 1);
+                offset = 2;
+                size -= 2;
+                if (SPEC_USIGN (opetype)) {
+                        while (size--) {
+                                aopPut (AOP (result), zero, offset++);
+                        }
+                }
+                else {
+                        if (size) {
+                                lbl = newiTempLabel (NULL);
+                                emitcode ("ldi", "r24,0");
+                                emitcode ("brcc", "L%05d", lbl->key);
+                                emitcode ("ldi", "r24,0xff)");
+                                emitcode ("", "L%05d:", lbl->key);
+                                while (size--)
+                                        aopPut (AOP (result), "r24",
+                                                offset++);
+                        }
+                }
+        }
+        return;
 }
 
 /*-----------------------------------------------------------------*/
-/* genGetHbit - generates code get highest order bit               */
+/* genMult - generates code for multiplication                     */
 /*-----------------------------------------------------------------*/
-static void genGetHbit (iCode *ic)
+static void
+genMult (iCode * ic)
 {
-    operand *left, *result;
-    left = IC_LEFT(ic);
-    result=IC_RESULT(ic);
-    aopOp (left,ic,FALSE);
-    aopOp (result,ic,FALSE);
-
-    /* get the highest order byte into a */
-    MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
-    if(AOP_TYPE(result) == AOP_CRY){
-        emitcode("rlc","a");
-        outBitC(result);
-    }
-    else{
-        emitcode("rl","a");
-        emitcode("anl","a,#0x01");
-        outAcc(result);
-    }
+        operand *left = IC_LEFT (ic);
+        operand *right = IC_RIGHT (ic);
+        operand *result = IC_RESULT (ic);
+
+        /* assign the amsops */
+        aopOp (left, ic, FALSE);
+        aopOp (right, ic, FALSE);
+        aopOp (result, ic, TRUE);
+
+        /* if both are of size == 1 */
+        if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) {
+                genMultOneByte (left, right, result);
+                goto release;
+        }
 
+        /* should have been converted to function call */
+        assert (0);
 
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+      release:
+        freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccRol - rotate left accumulator by known count                 */
+/* genDiv - generates code for division                            */
 /*-----------------------------------------------------------------*/
-static void AccRol (int shCount)
+static void
+genDiv (iCode * ic)
 {
-    shCount &= 0x0007;              // shCount : 0..7
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            emitcode("rl","a");
-            break;
-        case 2 :
-            emitcode("rl","a");
-            emitcode("rl","a");
-            break;
-        case 3 :
-            emitcode("swap","a");
-            emitcode("rr","a");
-            break;
-        case 4 :
-            emitcode("swap","a");
-            break;
-        case 5 :
-            emitcode("swap","a");
-            emitcode("rl","a");
-            break;
-        case 6 :
-            emitcode("rr","a");
-            emitcode("rr","a");
-            break;
-        case 7 :
-            emitcode("rr","a");
-            break;
-    }
+        /* should have been converted to function call */
+        assert (0);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccLsh - left shift accumulator by known count                  */
+/* genMod - generates code for division                            */
 /*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
+static void
+genMod (iCode * ic)
 {
-    if(shCount != 0){
-        if(shCount == 1)
-            emitcode("add","a,acc");
-        else 
-           if(shCount == 2) {
-            emitcode("add","a,acc");
-            emitcode("add","a,acc");
-        } else {
-            /* rotate left accumulator */
-            AccRol(shCount);
-            /* and kill the lower order bits */
-            emitcode("anl","a,#0x%02x", SLMask[shCount]);
-        }
-    }
+        /* should have been converted to function call */
+        assert (0);
+
 }
 
+enum {
+        AVR_EQ = 0,
+        AVR_NE,
+        AVR_LT,
+        AVR_GE
+};
+
 /*-----------------------------------------------------------------*/
-/* AccRsh - right shift accumulator by known count                 */
+/* revavrcnd - reverse a conditional for avr                       */
 /*-----------------------------------------------------------------*/
-static void AccRsh (int shCount)
+static int
+revavrcnd (int type)
 {
-    if(shCount != 0){
-        if(shCount == 1){
-            CLRC;
-            emitcode("rrc","a");
-        } else {
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            emitcode("anl","a,#0x%02x", SRMask[shCount]);
+        static struct {
+                int type, rtype;
+        } rar[] = {
+                {
+                AVR_EQ, AVR_NE}
+                , {
+                AVR_LT, AVR_GE}
+        };
+        int i;
+
+        for (i = 0; i < (sizeof (rar) / sizeof (rar[0])); i++) {
+                if (rar[i].type == type)
+                        return rar[i].rtype;
+                if (rar[i].rtype == type)
+                        return rar[i].type;
         }
-    }
+        assert (0);             /* cannot happen */
+        return 0;               /* makes the compiler happy */
 }
 
+static char *br_name[4] = { "breq", "brne", "brlt", "brge" };
+static char *br_uname[4] = { "breq", "brne", "brlo", "brcc" };
+
 /*-----------------------------------------------------------------*/
-/* AccSRsh - signed right shift accumulator by known count                 */
+/* genBranch - generate the branch instruction                     */
 /*-----------------------------------------------------------------*/
-static void AccSRsh (int shCount)
+static void
+genBranch (iCode * ifx, int br_type, int sign)
 {
-    symbol *tlbl ;
-    if(shCount != 0){
-        if(shCount == 1){
-            emitcode("mov","c,acc.7");
-            emitcode("rrc","a");
-        } else if(shCount == 2){
-            emitcode("mov","c,acc.7");
-            emitcode("rrc","a");
-            emitcode("mov","c,acc.7");
-            emitcode("rrc","a");
-        } else {
-            tlbl = newiTempLabel(NULL);
-            /* rotate right accumulator */
-            AccRol(8 - shCount);
-            /* and kill the higher order bits */
-            emitcode("anl","a,#0x%02x", SRMask[shCount]);
-            emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100);
-            emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);
-            emitcode("","%05d$:",tlbl->key+100);
+        int tj = (IC_TRUE (ifx) ? 1 : 0);
+
+        if (tj) {               /* if true jump */
+                char *nm = (sign ? br_name[br_type] : br_uname[br_type]);
+                emitcode (nm, "L%05d", IC_TRUE (ifx)->key);
         }
-    }
+        else {                  /* if false jump */
+                int rtype = revavrcnd (br_type);
+                char *nm = (sign ? br_name[rtype] : br_uname[rtype]);
+                emitcode (nm, "L%05d", IC_FALSE (ifx)->key);
+        }
+        ifx->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
-/* shiftR1Left2Result - shift right one byte from left to result   */
+/* genCmp - compare & jump                                         */
 /*-----------------------------------------------------------------*/
-static void shiftR1Left2Result (operand *left, int offl,
-                                operand *result, int offr,
-                                int shCount, int sign)
+static void
+genCmp (iCode * ic, iCode * ifx, int br_type)
 {
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift right accumulator */
-    if(sign)
-        AccSRsh(shCount);
-    else
-        AccRsh(shCount);
-    aopPut(AOP(result),"a",offr);
+        operand *left, *right, *result;
+        sym_link *letype, *retype;
+        symbol *lbl;
+        int sign, size, offset = 0;
+
+        left = IC_LEFT (ic);
+        right = IC_RIGHT (ic);
+        result = IC_RESULT (ic);
+
+        letype = getSpec (operandType (left));
+        retype = getSpec (operandType (right));
+        sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
+
+        /* assign the amsops */
+        aopOp (left, ic, FALSE);
+        aopOp (right, ic, FALSE);
+        aopOp (result, ic, TRUE);
+        size = AOP_SIZE (left);
+
+        if (ifx) {
+                if (size == 1) {
+                        if (AOP_TYPE (right) == AOP_LIT) {
+                                emitcode ("cpi", "%s,<(%d)",
+                                          aopGet (AOP (left), 0),
+                                          (int) ulFromVal (AOP (IC_RIGHT (ic))->
+                                                        aopu.aop_lit));
+                                genBranch (ifx, br_type, sign);
+                        }
+                        else {  /* right != literal */
+                                emitcode ("cp", "%s,%s",
+                                          aopGet (AOP (left), 0),
+                                          aopGet (AOP (right), 0));
+                                genBranch (ifx, br_type, sign);
+                        }
+                }
+                else {          /* size != 1 */
+                        while (size--) {
+                                if (offset == 0)
+                                        emitcode ("cp", "%s,%s",
+                                                  aopGet (AOP (left), 0),
+                                                  aopGet (AOP (right), 0));
+                                else
+                                        emitcode ("cpc", "%s,%s",
+                                                  aopGet (AOP (left), offset),
+                                                  aopGet (AOP (right),
+                                                          offset));
+                                offset++;
+                        }
+                        genBranch (ifx, br_type, sign);
+                }
+        }
+        else {                  /* no ifx */
+                emitcode ("clr", "r0");
+                while (size--) {
+                        if (offset == 0)
+                                emitcode ("cp", "%s,%s",
+                                          aopGet (AOP (left), 0),
+                                          aopGet (AOP (right), 0));
+                        else
+                                emitcode ("cpc", "%s,%s",
+                                          aopGet (AOP (left), offset),
+                                          aopGet (AOP (right), offset));
+                        offset++;
+                }
+                lbl = newiTempLabel (NULL);
+                br_type = revavrcnd (br_type);
+                if (sign)
+                        emitcode (br_uname[br_type], "L%05d", lbl->key);
+                else
+                        emitcode (br_name[br_type], "L%05d", lbl->key);
+                emitcode ("inc", "r0");
+                emitcode ("", "L%05d:", lbl->key);
+                aopPut (AOP (result), "r0", 0);
+                size = AOP_SIZE (result) - 1;
+                offset = 1;
+                while (size--)
+                        aopPut (AOP (result), zero, offset++);
+        }
+
+        freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* shiftL1Left2Result - shift left one byte from left to result    */
+/* genCmpGt :- greater than comparison                             */
 /*-----------------------------------------------------------------*/
-static void shiftL1Left2Result (operand *left, int offl,
-                                operand *result, int offr, int shCount)
+static void
+genCmpGt (iCode * ic, iCode * ifx)
 {
-    char *l;
-    l = aopGet(AOP(left),offl,FALSE,FALSE);
-    MOVA(l);
-    /* shift left accumulator */
-    AccLsh(shCount);
-    aopPut(AOP(result),"a",offr);
+        /* should have transformed by the parser */
+        assert (0);
 }
 
 /*-----------------------------------------------------------------*/
-/* movLeft2Result - move byte from left to result                  */
+/* genCmpLt - less than comparisons                                */
 /*-----------------------------------------------------------------*/
-static void movLeft2Result (operand *left, int offl,
-                            operand *result, int offr, int sign)
+static void
+genCmpLt (iCode * ic, iCode * ifx)
 {
-    char *l;
-    if(!sameRegs(AOP(left),AOP(result)) || (offl != offr)){
-        l = aopGet(AOP(left),offl,FALSE,FALSE);
-
-        if (*l == '@' && (IS_AOP_PREG(result))) {
-            emitcode("mov","a,%s",l);
-            aopPut(AOP(result),"a",offr);
-        } else {
-            if(!sign)
-                aopPut(AOP(result),l,offr);
-            else{
-                /* MSB sign in acc.7 ! */
-                if(getDataSize(left) == offl+1){
-                    emitcode("mov","a,%s",l);
-                    aopPut(AOP(result),"a",offr);
-                }
-            }
-        }
-    }
+        genCmp (ic, ifx, AVR_LT);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccAXRrl1 - right rotate c->a:x->c by 1                         */
+/* genCmpEq - generates code for equal to                          */
 /*-----------------------------------------------------------------*/
-static void AccAXRrl1 (char *x)
+static void
+genCmpEq (iCode * ic, iCode * ifx)
 {
-    emitcode("rrc","a");
-    emitcode("xch","a,%s", x);
-    emitcode("rrc","a");
-    emitcode("xch","a,%s", x);
+        genCmp (ic, ifx, AVR_EQ);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
+/* genCmpNe - generates code for not equal to                      */
 /*-----------------------------------------------------------------*/
-static void AccAXLrl1 (char *x)
+static void
+genCmpNe (iCode * ic, iCode * ifx)
 {
-    emitcode("xch","a,%s",x);
-    emitcode("rlc","a");
-    emitcode("xch","a,%s",x);
-    emitcode("rlc","a");
+        genCmp (ic, ifx, AVR_NE);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccAXLsh1 - left shift a:x<-0 by 1                              */
+/* genCmpGe - generates code for greater than equal to             */
 /*-----------------------------------------------------------------*/
-static void AccAXLsh1 (char *x)
+static void
+genCmpGe (iCode * ic, iCode * ifx)
 {
-    emitcode("xch","a,%s",x);
-    emitcode("add","a,acc");
-    emitcode("xch","a,%s",x);
-    emitcode("rlc","a");
+        genCmp (ic, ifx, AVR_GE);
 }
 
 /*-----------------------------------------------------------------*/
-/* AccAXLsh - left shift a:x by known count (0..7)                 */
+/* genCmpLe - generates code for less than equal to                */
 /*-----------------------------------------------------------------*/
-static void AccAXLsh (char *x, int shCount)
+static void
+genCmpLe (iCode * ic, iCode * ifx)
 {
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            AccAXLsh1(x);
-            break;
-        case 2 :
-            AccAXLsh1(x);
-            AccAXLsh1(x);
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD
-            AccRol(shCount);            // BBBAAAAA:CCCCCDDD
-            emitcode("anl","a,#0x%02x",
-                     SLMask[shCount]);  // BBB00000:CCCCCDDD
-            emitcode("xch","a,%s",x);   // CCCCCDDD:BBB00000
-            AccRol(shCount);            // DDDCCCCC:BBB00000
-            emitcode("xch","a,%s",x);   // BBB00000:DDDCCCCC
-            emitcode("xrl","a,%s",x);   // (BBB^DDD)CCCCC:DDDCCCCC
-            emitcode("xch","a,%s",x);   // DDDCCCCC:(BBB^DDD)CCCCC
-            emitcode("anl","a,#0x%02x",
-                     SLMask[shCount]);  // DDD00000:(BBB^DDD)CCCCC
-            emitcode("xch","a,%s",x);   // (BBB^DDD)CCCCC:DDD00000
-            emitcode("xrl","a,%s",x);   // BBBCCCCC:DDD00000            
-            break;
-        case 6 :                        // AAAAAABB:CCCCCCDD
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000BB:CCCCCCDD
-            emitcode("mov","c,acc.0");  // c = B
-            emitcode("xch","a,%s",x);   // CCCCCCDD:000000BB
-            AccAXRrl1(x);               // BCCCCCCD:D000000B
-            AccAXRrl1(x);               // BBCCCCCC:DD000000
-            break;
-        case 7 :                        // a:x <<= 7
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000B:CCCCCCCD
-            emitcode("mov","c,acc.0");  // c = B
-            emitcode("xch","a,%s",x);   // CCCCCCCD:0000000B
-            AccAXRrl1(x);               // BCCCCCCC:D0000000
-            break;
-        default :
-            break;
-    }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRsh - right shift a:x known count (0..7)                   */
-/*-----------------------------------------------------------------*/
-static void AccAXRsh (char *x, int shCount)
-{   
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            break;
-        case 2 :
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            CLRC;
-            AccAXRrl1(x);               // 0->a:x
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD = a:x
-            AccRol(8 - shCount);        // BBBAAAAA:DDDCCCCC
-            emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
-            AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000CCCCC:BBBAAAAA
-            emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
-            emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
-            emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
-            emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
-            emitcode("xch","a,%s",x);   // 000AAAAA:BBBCCCCC
-            break;
-        case 6 :                        // AABBBBBB:CCDDDDDD
-            emitcode("mov","c,acc.7");
-            AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
-            AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
-            emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000AA:BBBBBBCC
-            break;
-        case 7 :                        // ABBBBBBB:CDDDDDDD
-            emitcode("mov","c,acc.7");  // c = A
-            AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
-            emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000A:BBBBBBBC
-            break;
-        default :
-            break;
-    }
-}
+        operand *left = IC_LEFT (ic);
+        operand *right = IC_RIGHT (ic);
 
-/*-----------------------------------------------------------------*/
-/* AccAXRshS - right shift signed a:x known count (0..7)           */
-/*-----------------------------------------------------------------*/
-static void AccAXRshS (char *x, int shCount)
-{   
-    symbol *tlbl ;
-    switch(shCount){
-        case 0 :
-            break;
-        case 1 :
-            emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            break;
-        case 2 :
-            emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            emitcode("mov","c,acc.7");
-            AccAXRrl1(x);               // s->a:x
-            break;
-        case 3 :
-        case 4 :
-        case 5 :                        // AAAAABBB:CCCCCDDD = a:x
-            tlbl = newiTempLabel(NULL);
-            AccRol(8 - shCount);        // BBBAAAAA:CCCCCDDD
-            emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
-            AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000CCCCC:BBBAAAAA
-            emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
-            emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
-            emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
-            emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
-            emitcode("xch","a,%s",x);   // 000SAAAA:BBBCCCCC
-            emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); 
-            emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 111AAAAA:BBBCCCCC
-            emitcode("","%05d$:",tlbl->key+100);
-            break;                      // SSSSAAAA:BBBCCCCC
-        case 6 :                        // AABBBBBB:CCDDDDDD
-            tlbl = newiTempLabel(NULL);
-            emitcode("mov","c,acc.7");
-            AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
-            AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
-            emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 000000AA:BBBBBBCC
-            emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); 
-            emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 111111AA:BBBBBBCC
-            emitcode("","%05d$:",tlbl->key+100);
-            break;
-        case 7 :                        // ABBBBBBB:CDDDDDDD
-            tlbl = newiTempLabel(NULL);
-            emitcode("mov","c,acc.7");  // c = A
-            AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
-            emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
-            emitcode("anl","a,#0x%02x",
-                     SRMask[shCount]);  // 0000000A:BBBBBBBC
-            emitcode("jnb","acc.%d,%05d$",7-shCount,tlbl->key+100); 
-            emitcode("orl","a,#0x%02x",
-                     (unsigned char)~SRMask[shCount]);  // 1111111A:BBBBBBBC
-            emitcode("","%05d$:",tlbl->key+100);
-            break;
-        default :
-            break;
-    }
+        IC_RIGHT (ic) = left;
+        IC_LEFT (ic) = right;
+        genCmp (ic, ifx, AVR_GE);
 }
 
 /*-----------------------------------------------------------------*/
-/* shiftL2Left2Result - shift left two bytes from left to result   */
+/* ifxForOp - returns the icode containing the ifx for operand     */
 /*-----------------------------------------------------------------*/
-static void shiftL2Left2Result (operand *left, int offl,
-                                operand *result, int offr, int shCount)
+static iCode *
+ifxForOp (operand * op, iCode * ic)
 {
-    if(sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       /* don't crash result[offr] */
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-       emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    } else {
-       movLeft2Result(left,offl, result, offr, 0);
-       MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    }
-    /* ax << shCount (x = lsb(result))*/
-    AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    aopPut(AOP(result),"a",offr+MSB16);
-}
+        /* if true symbol then needs to be assigned */
+        if (IS_TRUE_SYMOP (op))
+                return NULL;
+
+        /* if this has register type condition and
+           the next instruction is ifx with the same operand
+           and live to of the operand is upto the ifx only then */
+        if (ic->next &&
+            ic->next->op == IFX &&
+            IC_COND (ic->next)->key == op->key &&
+            OP_SYMBOL (op)->liveTo <= ic->next->seq) return ic->next;
 
+        return NULL;
+}
 
 /*-----------------------------------------------------------------*/
-/* shiftR2Left2Result - shift right two bytes from left to result  */
+/* genAndOp - for && operation                                     */
 /*-----------------------------------------------------------------*/
-static void shiftR2Left2Result (operand *left, int offl,
-                                operand *result, int offr,
-                                int shCount, int sign)
+static void
+genAndOp (iCode * ic)
 {
-    if(sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       /* don't crash result[offr] */
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-       emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    } else {
-       movLeft2Result(left,offl, result, offr, 0);
-       MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    }
-    /* a:x >> shCount (x = lsb(result))*/
-    if(sign)
-        AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    else
-        AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    if(getDataSize(result) > 1)
-        aopPut(AOP(result),"a",offr+MSB16);
+        operand *left, *right, *result;
+        symbol *tlbl;
+        int size, offset;
+
+        /* 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);
+
+        tlbl = newiTempLabel (NULL);
+        toBoolean (left, "r0", TRUE);
+        toBoolean (right, "r1", TRUE);
+        emitcode ("and", "r0,r1");
+        emitcode ("ldi", "r24,1");
+        emitcode ("breq", "L%05d", tlbl->key);
+        emitcode ("dec", "r24");
+        emitcode ("", "L%05d:", tlbl->key);
+        aopPut (AOP (result), "r24", 0);
+        size = AOP_SIZE (result) - 1;
+        offset = 1;
+        while (size--)
+                aopPut (AOP (result), zero, offset++);
+
+        freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* shiftLLeftOrResult - shift left one byte from left, or to result*/
+/* genOrOp - for || operation                                      */
 /*-----------------------------------------------------------------*/
-static void shiftLLeftOrResult (operand *left, int offl,
-                                operand *result, int offr, int shCount)
+static void
+genOrOp (iCode * ic)
 {
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift left accumulator */
-    AccLsh(shCount);
-    /* or with result */
-    emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-    /* back to result */
-    aopPut(AOP(result),"a",offr);
+        operand *left, *right, *result;
+        symbol *tlbl;
+        int size, offset;
+
+        /* 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);
+
+        tlbl = newiTempLabel (NULL);
+        toBoolean (left, "r0", TRUE);
+        toBoolean (right, "r0", FALSE);
+        emitcode ("ldi", "r24,1");
+        emitcode ("breq", "L%05d", tlbl->key);
+        emitcode ("dec", "r24");
+        emitcode ("", "L%05d:", tlbl->key);
+        aopPut (AOP (result), "r24", 0);
+        size = AOP_SIZE (result) - 1;
+        offset = 1;
+        while (size--)
+                aopPut (AOP (result), zero, offset++);
+
+        freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
+enum {
+        AVR_AND = 0, AVR_OR, AVR_XOR
+};
+static char *bopnames_lit[] = { "andi", "ori" };
+static char *bopnames[] = { "and", "or", "eor" };
 /*-----------------------------------------------------------------*/
-/* shiftRLeftOrResult - shift right one byte from left,or to result*/
+/* genBitWise - generate bitwise operations                        */
 /*-----------------------------------------------------------------*/
-static void shiftRLeftOrResult (operand *left, int offl,
-                                operand *result, int offr, int shCount)
+static void
+genBitWise (iCode * ic, iCode * ifx, int bitop)
 {
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift right accumulator */
-    AccRsh(shCount);
-    /* or with result */
-    emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-    /* back to result */
-    aopPut(AOP(result),"a",offr);
-}
+        operand *left, *right, *result;
+        int size, offset = 0;
+        char *l;
+        symbol *lbl, *lbl1;
+        int samerl, samerr;
+
+        aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+        aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+        aopOp ((result = IC_RESULT (ic)), ic, TRUE);
+
+        size = AOP_SIZE (left);
+        offset = 0;
+        if (ifx) {              /* used only for jumps */
+                if (AOP_TYPE (right) == AOP_LIT &&
+                    (bitop == AVR_AND || bitop == AVR_OR)) {
+                        int lit =
+                                (int) ulFromVal (AOP (right)->aopu.
+                                                    aop_lit);
+                        int p2 = powof2 (lit);
+                        if (bitop == AVR_AND && (p2 >= 0)) {    /* right side is a power of 2 */
+                                l = aopGet (AOP (left), p2 / 8);
+                                if (IC_TRUE (ifx)) {
+                                        emitcode ("sbrc", "%s,%d", l,
+                                                  (p2 % 8));
+                                        emitcode ("rjmp", "L%05d",
+                                                  IC_TRUE (ifx)->key);
+                                }
+                                else {
+                                        emitcode ("sbrs", "%s,%d", l,
+                                                  (p2 % 8));
+                                        emitcode ("rjmp", "L%05d",
+                                                  IC_FALSE (ifx)->key);
+                                }
+                        }
+                        else {  /* right not power of two */
+                                int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+                                if (size == 1) {
+                                        if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),0)) {
+                                                emitcode (bopnames_lit[bitop],
+                                                          "%s,<(%d)",
+                                                          aopGet (AOP (IC_LEFT (ic)), 0), lit);
+                                        }
+                                        else {
+                                                MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
+                                                emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
+                                        }
+                                        lbl = newiTempLabel (NULL);
+                                        if (IC_TRUE (ifx)) {
+                                                emitcode ("breq", "L%05d", lbl->key);
+                                                emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+                                        }
+                                        else {
+                                                emitcode ("brne", "L%05d", lbl->key);
+                                                emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+                                        }
+                                        emitcode ("", "L%05d:", lbl->key);
+                                }
+                                else if (size == 2) {
+                                        emitcode ("mov", "r24,%s", aopGet (AOP (IC_LEFT (ic)), 0));
+                                        emitcode ("mov", "r25,%s", aopGet (AOP (IC_LEFT (ic)), 1));
+                                        emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
+                                        emitcode (bopnames_lit[bitop], "r25,>(%d)", lit);
+                                        emitcode ("sbiw", "r24,0");
+                                        lbl = newiTempLabel (NULL);
+                                        if (IC_TRUE (ifx)) {
+                                                emitcode ("breq", "L%05d", lbl->key);
+                                                emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+                                        }
+                                        else {
+                                                emitcode ("brne", "L%05d", lbl->key);
+                                                emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+                                        }
+                                        emitcode ("", "L%05d:", lbl->key);
+                                }
+                                else {
+                                        lbl = newiTempLabel (NULL);
+                                        lbl1 = newiTempLabel (NULL);
+                                        while (size--) {
+                                                if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset)) {
+                                                        emitcode (bopnames_lit [bitop], "%s,<(%d)",
+                                                                  aopGet (AOP (IC_LEFT (ic)), offset),
+                                                                  lit);
+                                                }
+                                                else {
+                                                        char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+                                                        MOVR24 (l);
+                                                        emitcode ("andi", "r24,<(%d)", lit);
+                                                }
+                                                emitcode ("brne", "L%05d", lbl->key);
+                                                offset++;
+                                        }
+                                        /* all are zero */
+                                        if (IC_FALSE (ifx))
+                                                emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+                                        else
+                                                emitcode ("rjmp", "L%05d", lbl1->key);
+                                        emitcode ("", "L%05d:", lbl->key);
+                                        /* not zero */
+                                        if (IC_TRUE (ifx))
+                                                emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+                                        emitcode ("", "L%05d:", lbl1->key);
+
+                                }
+                        }
+                }
+                else {          /* right is not a literal */
+                        int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+                        int reh = OP_SYMBOL (right)->liveTo <= ic->seq;
+                        if (size == 1) {
+                                if (eh) {
+                                        emitcode (bopnames[bitop], "%s,%s", aopGet (AOP (IC_LEFT (ic)), 0),
+                                                  aopGet (AOP (IC_RIGHT (ic)), 0));
+                                }
+                                else if (reh) {
+                                        emitcode (bopnames[bitop], "%s,%s",
+                                                  aopGet (AOP (IC_RIGHT (ic)), 0),
+                                                  aopGet (AOP (IC_LEFT (ic)), 0));
+                                }
+                                else {
+                                        MOVR0 (aopGet (AOP (IC_LEFT (ic)), 0));
+                                        emitcode (bopnames[bitop], "r0,%s",
+                                                  aopGet (AOP (IC_RIGHT (ic)), 0));
+                                }
+                                lbl = newiTempLabel (NULL);
+                                if (IC_TRUE (ifx)) {
+                                        emitcode ("breq", "L%05d", lbl->key);
+                                        emitcode ("rjmp", "L%05d",
+                                                  IC_TRUE (ifx)->key);
+                                }
+                                else {
+                                        emitcode ("brne", "L%05d", lbl->key);
+                                        emitcode ("rjmp", "L%05d",
+                                                  IC_FALSE (ifx)->key);
+                                }
+                                emitcode ("", "L%05d:", lbl->key);
+                        }
+                        else if (size == 2) {
+                                emitcode ("mov", "r24,%s",
+                                          aopGet (AOP (IC_LEFT (ic)), 0));
+                                emitcode ("mov", "r25,%s",
+                                          aopGet (AOP (IC_LEFT (ic)), 1));
+                                emitcode (bopnames[bitop], "r24,%s",
+                                          aopGet (AOP (IC_RIGHT (ic)), 0));
+                                emitcode (bopnames[bitop], "r25,%s",
+                                          aopGet (AOP (IC_RIGHT (ic)), 1));
+                                emitcode ("sbiw", "r24,0");
+                                lbl = newiTempLabel (NULL);
+                                if (IC_TRUE (ifx)) {
+                                        emitcode ("breq", "L%05d", lbl->key);
+                                        emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+                                }
+                                else {
+                                        emitcode ("brne", "L%05d", lbl->key);
+                                        emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+                                }
+                                emitcode ("", "L%05d:", lbl->key);
+                        }
+                        else {
+                                lbl = newiTempLabel (NULL);
+                                lbl1 = newiTempLabel (NULL);
+                                while (size--) {
+                                        if (eh) {
+                                                emitcode (bopnames[bitop], "%s,%s",
+                                                          aopGet (AOP (IC_LEFT (ic)), offset),
+                                                          aopGet (AOP (IC_RIGHT (ic)), offset));
+                                        }
+                                        else if (reh) {
+                                                emitcode (bopnames[bitop], "%s,%s",
+                                                          aopGet (AOP (IC_RIGHT (ic)), offset),
+                                                          aopGet (AOP (IC_LEFT (ic)), offset));
+                                        }
+                                        else {
+                                                MOVR0 (aopGet (AOP (IC_LEFT (ic)), offset));
+                                                emitcode (bopnames[bitop], "r0,%s",
+                                                          aopGet (AOP (IC_RIGHT (ic)), offset));
+                                        }
+                                        emitcode ("brne", "L%05d", lbl->key);
+                                        offset++;
+                                }
+                                /* all are zero */
+                                if (IC_FALSE (ifx))
+                                        emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+                                else
+                                        emitcode ("rjmp", "L%05d", lbl1->key);
+                                emitcode ("", "L%05d:", lbl->key);
+                                /* not zero */
+                                if (IC_TRUE (ifx))
+                                        emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+                                emitcode ("", "L%05d:", lbl1->key);
+
+                        }
+                }
+                goto release;
+        }
 
-/*-----------------------------------------------------------------*/
-/* genlshOne - left shift a one byte quantity by known count       */
-/*-----------------------------------------------------------------*/
-static void genlshOne (operand *result, operand *left, int shCount)
-{       
-    shiftL1Left2Result(left, LSB, result, LSB, shCount);
+        /* result needs to go a register */
+        samerl = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+        samerr = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)));
+        while (size--) {
+                if (AOP_TYPE (right) == AOP_LIT) {
+                        unsigned int lit =
+                                (int) ulFromVal (AOP (right)->aopu.
+                                                    aop_lit);
+                        if (((lit >> (8 * offset)) & 0xff) == 0) {
+                                if (bitop == AVR_AND) {
+                                        aopPut (AOP (result), zero, offset++);
+                                        continue;
+                                }
+                                else if (bitop == AVR_OR) {
+                                        if (!samerl)
+                                                aopPut (AOP (result),
+                                                        aopGet (AOP (left),
+                                                                offset),
+                                                        offset);
+                                        offset++;
+                                        continue;
+                                }
+                        }
+                }
+                if (samerl) {
+                        if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT &&
+                            AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset) &&
+                            (bitop == AVR_AND || bitop == AVR_OR)) {
+                                emitcode (bopnames_lit[bitop], "%s,%s(%d)",
+                                          aopGet (AOP (IC_LEFT (ic)), offset),
+                                          larray[offset],
+                                          (int) ulFromVal (AOP (right)-> aopu.aop_lit));
+                        }
+                        else {
+                                emitcode (bopnames[bitop], "%s,%s",
+                                          aopGet (AOP (IC_LEFT (ic)), offset),
+                                          aopGet (AOP (IC_RIGHT (ic)), offset));
+                        }
+                }
+                else if (samerr) {
+                        emitcode (bopnames[bitop], "%s,%s",
+                                  aopGet (AOP (IC_RIGHT (ic)), offset),
+                                  aopGet (AOP (IC_LEFT (ic)), offset));
+                }
+                else {
+                        aopPut (AOP (IC_RESULT (ic)),
+                                aopGet (AOP (IC_LEFT (ic)), offset), offset);
+                        emitcode (bopnames[bitop],
+                                  aopGet (AOP (IC_RESULT (ic)), offset),
+                                  aopGet (AOP (IC_RIGHT (ic)), offset));
+                }
+                offset++;
+        }
+      release:
+        freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genlshTwo - left shift two bytes by known amount != 0           */
+/* genAnd  - code for and                                          */
 /*-----------------------------------------------------------------*/
-static void genlshTwo (operand *result,operand *left, int shCount)
+static void
+genAnd (iCode * ic, iCode * ifx)
 {
-    int size;
-    
-    size = getDataSize(result);
-
-    /* if shCount >= 8 */
-    if (shCount >= 8) {
-        shCount -= 8 ;
-
-        if (size > 1){
-            if (shCount)
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-            else 
-                movLeft2Result(left, LSB, result, MSB16, 0);
-        }
-        aopPut(AOP(result),zero,LSB);   
-    }
-
-    /*  1 <= shCount <= 7 */
-    else {  
-        if(size == 1)
-            shiftL1Left2Result(left, LSB, result, LSB, shCount); 
-        else 
-            shiftL2Left2Result(left, LSB, result, LSB, shCount);
-    }
+        genBitWise (ic, ifx, AVR_AND);
 }
 
 /*-----------------------------------------------------------------*/
-/* shiftLLong - shift left one long from left to result            */
-/* offl = LSB or MSB16                                             */
+/* genOr  - code for or                                            */
 /*-----------------------------------------------------------------*/
-static void shiftLLong (operand *left, operand *result, int offr )
+static void
+genOr (iCode * ic, iCode * ifx)
 {
-    char *l;
-    int size = AOP_SIZE(result);
-
-    if(size >= LSB+offr){
-        l = aopGet(AOP(left),LSB,FALSE,FALSE);
-        MOVA(l);
-        emitcode("add","a,acc");
-       if (sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB16+offr && offr != LSB )
-           emitcode("xch","a,%s",
-                    aopGet(AOP(left),LSB+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",LSB+offr);
-    }
-
-    if(size >= MSB16+offr){
-       if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
-           l = aopGet(AOP(left),MSB16,FALSE,FALSE);
-           MOVA(l);
-       }
-        emitcode("rlc","a");
-       if (sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB24+offr && offr != LSB)
-           emitcode("xch","a,%s",
-                    aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",MSB16+offr);
-    }
-
-    if(size >= MSB24+offr){
-       if (!(sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
-           l = aopGet(AOP(left),MSB24,FALSE,FALSE);
-           MOVA(l);
-       }
-        emitcode("rlc","a");
-       if (sameRegs(AOP(left),AOP(result)) && 
-           size >= MSB32+offr && offr != LSB )
-           emitcode("xch","a,%s",
-                    aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
-       else        
-           aopPut(AOP(result),"a",MSB24+offr);
-    }
-
-    if(size > MSB32+offr){
-       if (!(sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
-           l = aopGet(AOP(left),MSB32,FALSE,FALSE);
-           MOVA(l);    
-       }
-        emitcode("rlc","a");
-        aopPut(AOP(result),"a",MSB32+offr);
-    }
-    if(offr != LSB)
-        aopPut(AOP(result),zero,LSB);       
+        genBitWise (ic, ifx, AVR_OR);
 }
 
 /*-----------------------------------------------------------------*/
-/* genlshFour - shift four byte by a known amount != 0             */
+/* genXor - code for xclusive or                                   */
 /*-----------------------------------------------------------------*/
-static void genlshFour (operand *result, operand *left, int shCount)
+static void
+genXor (iCode * ic, iCode * ifx)
 {
-    int size;
-
-    size = AOP_SIZE(result);
-
-    /* if shifting more that 3 bytes */
-    if (shCount >= 24 ) {
-        shCount -= 24;
-        if (shCount)
-            /* lowest order of left goes to the highest
-            order of the destination */
-            shiftL1Left2Result(left, LSB, result, MSB32, shCount);
-        else
-            movLeft2Result(left, LSB, result, MSB32, 0);
-        aopPut(AOP(result),zero,LSB);
-        aopPut(AOP(result),zero,MSB16);
-        aopPut(AOP(result),zero,MSB32);
-        return;
-    }
-
-    /* more than two bytes */
-    else if ( shCount >= 16 ) {
-        /* lower order two bytes goes to higher order two bytes */
-        shCount -= 16;
-        /* if some more remaining */
-        if (shCount)
-            shiftL2Left2Result(left, LSB, result, MSB24, shCount);
-        else {
-            movLeft2Result(left, MSB16, result, MSB32, 0);
-            movLeft2Result(left, LSB, result, MSB24, 0);
-        }
-        aopPut(AOP(result),zero,MSB16);
-        aopPut(AOP(result),zero,LSB);
-        return;
-    }    
-
-    /* if more than 1 byte */
-    else if ( shCount >= 8 ) {
-        /* lower order three bytes goes to higher order  three bytes */
-        shCount -= 8;
-        if(size == 2){
-            if(shCount)
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-            else
-                movLeft2Result(left, LSB, result, MSB16, 0);
-        }
-        else{   /* size = 4 */
-            if(shCount == 0){
-                movLeft2Result(left, MSB24, result, MSB32, 0);
-                movLeft2Result(left, MSB16, result, MSB24, 0);
-                movLeft2Result(left, LSB, result, MSB16, 0);
-                aopPut(AOP(result),zero,LSB);
-            }
-            else if(shCount == 1)
-                shiftLLong(left, result, MSB16);
-            else{
-                shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
-                shiftL1Left2Result(left, LSB, result, MSB16, shCount);
-                shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
-                aopPut(AOP(result),zero,LSB);
-            }
-        }
-    }
-
-    /* 1 <= shCount <= 7 */
-    else if(shCount <= 2){
-        shiftLLong(left, result, LSB);
-        if(shCount == 2)
-            shiftLLong(result, result, LSB);
-    }
-    /* 3 <= shCount <= 7, optimize */
-    else{
-        shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
-        shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
-        shiftL2Left2Result(left, LSB, result, LSB, shCount);
-    }
+        genBitWise (ic, ifx, AVR_XOR);
 }
 
 /*-----------------------------------------------------------------*/
-/* genLeftShiftLiteral - left shifting by known count              */
+/* genInline - write the inline code out                           */
 /*-----------------------------------------------------------------*/
-static void genLeftShiftLiteral (operand *left,
-                                 operand *right,
-                                 operand *result,
-                                 iCode *ic)
-{    
-    int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-    int size;
-
-    freeAsmop(right,NULL,ic,TRUE);
-
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+static void
+genInline (iCode * ic)
+{
+  char *buffer, *bp, *bp1;
+  bool inComment = FALSE;
 
-    size = getSize(operandType(result));
+  _G.inLine += (!options.asmpeep);
 
-#if VIEW_SIZE
-    emitcode("; shift left ","result %d, left %d",size,
-             AOP_SIZE(left));
-#endif
+  buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
 
-    /* I suppose that the left size >= result size */
-    if(shCount == 0){
-        while(size--){
-            movLeft2Result(left, size, result, size, 0);
+  /* emit each line as a code */
+  while (*bp)
+    {
+      switch (*bp)
+        {
+        case ';':
+          inComment = TRUE;
+          ++bp;
+          break;
+
+        case '\n':
+          inComment = FALSE;
+          *bp++ = '\0';
+          emitcode (bp1, "");
+          bp1 = bp;
+          break;
+
+        default:
+          /* Add \n for labels, not dirs such as c:\mydir */
+          if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
+            {
+              ++bp;
+              *bp = '\0';
+              ++bp;
+              emitcode (bp1, "");
+              bp1 = bp;
+            }
+          else
+            ++bp;
+          break;
         }
     }
+    if (bp1 != bp)
+      emitcode (bp1, "");
 
-    else if(shCount >= (size * 8))
-        while(size--)
-            aopPut(AOP(result),zero,size);
-    else{
-        switch (size) {
-            case 1:
-                genlshOne (result,left,shCount);
-                break;
-
-            case 2:
-            case 3:
-                genlshTwo (result,left,shCount);
-                break;
+    Safe_free (buffer);
 
-            case 4:
-                genlshFour (result,left,shCount);
-                break;
-        }
-    }
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+    _G.inLine -= (!options.asmpeep);
 }
 
 /*-----------------------------------------------------------------*/
-/* genLeftShift - generates code for left shifting                 */
+/* genRotC - rotate right/left with carry , lr = 1 rotate right    */
 /*-----------------------------------------------------------------*/
-static void genLeftShift (iCode *ic)
+static void
+genRotC (iCode * ic, int lr)
 {
-    operand *left,*right, *result;
-    int size, offset;
-    char *l;
-    symbol *tlbl , *tlbl1;
-
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
-
-    aopOp(right,ic,FALSE);
-
-    /* if the shift count is known then do it 
-    as efficiently as possible */
-    if (AOP_TYPE(right) == AOP_LIT) {
-        genLeftShiftLiteral (left,right,result,ic);
-        return ;
-    }
-
-    /* shift count is unknown then we have to form 
-    a loop get the loop count in B : Note: we take
-    only the lower order byte since shifting
-    more that 32 bits make no sense anyway, ( the
-    largest size of an object can be only 32 bits ) */  
-
-    emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-    /* now move the left to the result if they are not the
-    same */
-    if (!sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && (IS_AOP_PREG(result))) {
-
-                emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
+        operand *left, *result;
+        int size, offset = 0;
+
+        /* rotate right with carry */
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
+        aopOp (left, ic, FALSE);
+        aopOp (result, ic, FALSE);
+
+        /* move it to the result */
+        size = AOP_SIZE (result);
+        if (!sameRegs (AOP (left), AOP (result))) {
+                offset = 0;
+                while (size--) {
+                        aopPut (AOP (result),
+                                aopGet (AOP (left), offset), offset);
+                        offset++;
+                }
+                size = AOP_SIZE (result);
         }
-    }
+        if (lr)
+                offset = size - 1;
+        else
+                offset = 0;
 
-    tlbl = newiTempLabel(NULL);
-    size = AOP_SIZE(result);
-    offset = 0 ;   
-    tlbl1 = newiTempLabel(NULL);
-
-    /* if it is only one byte then */
-    if (size == 1) {
-       symbol *tlbl1 = newiTempLabel(NULL);
-
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       emitcode("sjmp","%05d$",tlbl1->key+100); 
-        emitcode("","%05d$:",tlbl->key+100);
-        emitcode("add","a,acc");
-       emitcode("","%05d$:",tlbl1->key+100);
-        emitcode("djnz","b,%05d$",tlbl->key+100);      
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
-    
-    reAdjustPreg(AOP(result));    
-    
-    emitcode("sjmp","%05d$",tlbl1->key+100); 
-    emitcode("","%05d$:",tlbl->key+100);    
-    l = aopGet(AOP(result),offset,FALSE,FALSE);
-    MOVA(l);
-    emitcode("add","a,acc");         
-    aopPut(AOP(result),"a",offset++);
-    while (--size) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        emitcode("rlc","a");         
-        aopPut(AOP(result),"a",offset++);
-    }
-    reAdjustPreg(AOP(result));
+        CLRC;
+        emitcode ("sbrc", "%s,%d", aopGet (AOP (result), offset),
+                  (lr ? 0 : 7));
+        emitcode ("sec", "");
 
-    emitcode("","%05d$:",tlbl1->key+100);
-    emitcode("djnz","b,%05d$",tlbl->key+100);
-release:
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+        while (size--) {
+                emitcode ((lr ? "ror" : "rol"), "%s",
+                          aopGet (AOP (result), offset));
+                if (lr)
+                        offset--;
+                else
+                        offset++;
+        }
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genrshOne - right shift a one byte quantity by known count      */
+/* genRRC - rotate right with carry                                */
 /*-----------------------------------------------------------------*/
-static void genrshOne (operand *result, operand *left,
-                       int shCount, int sign)
+static void
+genRRC (iCode * ic)
 {
-    shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
+        genRotC (ic, 1);
 }
 
 /*-----------------------------------------------------------------*/
-/* genrshTwo - right shift two bytes by known amount != 0          */
+/* genRLC - generate code for rotate left with carry               */
 /*-----------------------------------------------------------------*/
-static void genrshTwo (operand *result,operand *left,
-                       int shCount, int sign)
+static void
+genRLC (iCode * ic)
 {
-    /* if shCount >= 8 */
-    if (shCount >= 8) {
-        shCount -= 8 ;
-        if (shCount)
-            shiftR1Left2Result(left, MSB16, result, LSB,
-                               shCount, sign);
-        else 
-            movLeft2Result(left, MSB16, result, LSB, sign);
-        addSign(result, MSB16, sign);
-    }
-
-    /*  1 <= shCount <= 7 */
-    else
-        shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
+        genRotC (ic, 0);
 }
 
 /*-----------------------------------------------------------------*/
-/* shiftRLong - shift right one long from left to result           */
-/* offl = LSB or MSB16                                             */
+/* genGetHbit - generates code get highest order bit               */
 /*-----------------------------------------------------------------*/
-static void shiftRLong (operand *left, int offl,
-                        operand *result, int sign)
+static void
+genGetHbit (iCode * ic)
 {
-    if(!sign)
-        emitcode("clr","c");
-    MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
-    if(sign)
-        emitcode("mov","c,acc.7");
-    emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB32-offl);
-    if(offl == MSB16)
-        /* add sign of "a" */
-        addSign(result, MSB32, sign);
-
-    MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
-    emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB24-offl);
-
-    MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
-    emitcode("rrc","a");
-    aopPut(AOP(result),"a",MSB16-offl);
-
-    if(offl == LSB){
-        MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
-        emitcode("rrc","a");
-        aopPut(AOP(result),"a",LSB);
-    }
+        operand *left, *result;
+        int size, offset;
+
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
+        aopOp (left, ic, FALSE);
+        aopOp (result, ic, FALSE);
+
+        size = AOP_SIZE (result);
+        if (!sameRegs (AOP (left), AOP (result))) {
+                emitcode ("clr", "%s", aopGet (AOP (result), size - 1));
+                emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
+                emitcode ("subi", "%s,<(-1)",
+                          aopGet (AOP (result), size - 1));
+        }
+        else {
+                emitcode ("clr", "r0");
+                emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
+                emitcode ("subi", "r0,<(-1)");
+                aopPut (AOP (result), "r0", 0);
+        }
+        offset = 1;
+        size--;
+        while (size--) {
+                emitcode ("clr", aopGet (AOP (result), offset++));
+        }
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genrshFour - shift four byte by a known amount != 0             */
+/* genShiftLeftLit - shift left by a known amount                  */
 /*-----------------------------------------------------------------*/
-static void genrshFour (operand *result, operand *left,
-                        int shCount, int sign)
+static void
+genShiftLeftLit (iCode * ic)
 {
-    /* if shifting more that 3 bytes */
-    if(shCount >= 24 ) {
-        shCount -= 24;
-        if(shCount)
-            shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
-        else
-            movLeft2Result(left, MSB32, result, LSB, sign);
-        addSign(result, MSB16, sign);
-    }
-    else if(shCount >= 16){
-        shCount -= 16;
-        if(shCount)
-            shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
-        else{
-            movLeft2Result(left, MSB24, result, LSB, 0);
-            movLeft2Result(left, MSB32, result, MSB16, sign);
-        }
-        addSign(result, MSB24, sign);
-    }
-    else if(shCount >= 8){
-        shCount -= 8;
-        if(shCount == 1)
-            shiftRLong(left, MSB16, result, sign);
-        else if(shCount == 0){
-            movLeft2Result(left, MSB16, result, LSB, 0);
-            movLeft2Result(left, MSB24, result, MSB16, 0);
-            movLeft2Result(left, MSB32, result, MSB24, sign);
-            addSign(result, MSB32, sign);
-        }
-        else{
-            shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
-            shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
-            /* the last shift is signed */
-            shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
-            addSign(result, MSB32, sign);
-        }
-    }
-    else{   /* 1 <= shCount <= 7 */
-        if(shCount <= 2){
-            shiftRLong(left, LSB, result, sign);
-            if(shCount == 2)
-                shiftRLong(result, LSB, result, sign);
+        operand *left, *right, *result;
+        int size, shCount, offset = 0;
+        int lByteZ = 0;
+
+        right = IC_RIGHT (ic);
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
+
+        aopOp (left, ic, FALSE);
+        aopOp (result, ic, FALSE);
+        size = AOP_SIZE (result);
+        shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+
+        if (shCount > (size * 8 - 1)) {
+                while (size--)
+                        aopPut (AOP (result), zero, offset++);
+                goto release;
         }
-        else{
-            shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
-            shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
-            shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
+        switch (size) {
+        case 1:
+                if (!sameRegs (AOP (left), AOP (result)))
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+                if (shCount >= 4) {
+                        if (AOP_ISHIGHREG(AOP(result),0)) {
+                                emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                                emitcode ("andi", "%s,0xf0");
+                        } else {
+                                emitcode ("ldi","r24,0xf0");
+                                emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                                emitcode ("and", "%s,r24");
+                        }
+                        shCount -= 4;
+                }
+                if (shCount == 1) {
+                        emitcode ("add", "%s,%s", aopGet (AOP (result), 0),
+                                  aopGet (AOP (result), 0));
+                        shCount--;
+                }
+                while (shCount--)
+                        emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+                break;
+        case 2:
+                if (shCount >= 12) {
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 1);
+                        aopPut (AOP (result), zero, 0);
+                        emitcode ("swap", "%s", aopGet (AOP (result), 1));
+                        if (AOP_ISHIGHREG(AOP(result),1)) {
+                                emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
+                        } else {
+                                emitcode ("ldi","r24,0xf0");
+                                emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
+                        }
+                        shCount -= 12;
+                        lByteZ = 1;
+                }
+                if (shCount >= 8) {
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 1);
+                        aopPut (AOP (result), zero, 0);
+                        shCount -= 8;
+                        lByteZ = 1;
+                }
+                if (shCount >= 4) {
+                        shCount -= 4;
+                        if (!sameRegs (AOP (left), AOP (result))) {
+                                aopPut (AOP (result), aopGet (AOP (left), 0),
+                                        0);
+                                aopPut (AOP (result), aopGet (AOP (left), 1),
+                                        1);
+                        }
+                        emitcode ("mov", "r24,%s", aopGet (AOP (result), 0));
+                        emitcode ("andi", "r24,0x0f");
+                        if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
+                                emitcode("ldi","r25,0xf0");
+                        }
+                        emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                        if (AOP_ISHIGHREG(AOP(result),0)) {
+                                emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 0));
+                        } else {
+                                emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
+                        }
+                        emitcode ("swap", "%s", aopGet (AOP (result), 1));
+                        if (AOP_ISHIGHREG(AOP(result),1)) {
+                                emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
+                        } else {
+                                emitcode ("and", "%s,r25", aopGet (AOP (result), 1));
+                        }
+                        emitcode ("or", "%s,r24", aopGet (AOP (result), 1));
+                        while (shCount--) {
+                                emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+                                emitcode ("rol", "%s", aopGet (AOP (result), 1));
+                        }
+                }
+                if (!lByteZ && !sameRegs (AOP (result), AOP (left))
+                    && shCount) {
+                        offset = 0;
+                        while (size--) {
+                                aopPut (AOP (result),
+                                        aopGet (AOP (left), offset), offset);
+                                offset++;
+                        }
+                }
+                while (shCount--) {
+                        if (lByteZ) {
+                                emitcode ("lsl", "%s", aopGet (AOP (result), 1));
+                        }
+                        else {
+                                emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+                                emitcode ("rol", "%s", aopGet (AOP (result), 1));
+                        }
+                }
+                break;
+        case 3:
+                assert ("shifting generic pointer ?\n");
+                break;
+        case 4:
+                /* 32 bits we do only byte boundaries */
+                if (shCount >= 24) {
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+                        aopPut (AOP (result), zero, 2);
+                        aopPut (AOP (result), zero, 1);
+                        aopPut (AOP (result), zero, 0);
+                        lByteZ = 3;
+                        shCount -= 24;
+                }
+                if (shCount >= 16) {
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+                        aopPut (AOP (result), aopGet (AOP (left), 1), 2);
+                        aopPut (AOP (result), zero, 1);
+                        aopPut (AOP (result), zero, 0);
+                        lByteZ = 2;
+                        shCount -= 16;
+                }
+                if (shCount >= 8) {
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+                        aopPut (AOP (result), aopGet (AOP (left), 1), 2);
+                        aopPut (AOP (result), aopGet (AOP (left), 2), 1);
+                        aopPut (AOP (result), zero, 0);
+                        shCount -= 8;
+                        lByteZ = 1;
+                }
+                if (!lByteZ && !sameRegs (AOP (left), AOP (right))) {
+                        offset = 0;
+                        while (size--) {
+                                aopPut (AOP (result),
+                                        aopGet (AOP (left), offset), offset);
+                                offset++;
+                        }
+                        offset = 0;
+                        size = AOP_SIZE (result);
+                }
+                if (shCount) {
+                        switch (lByteZ) {
+                        case 0:
+                                while (shCount--) {
+                                        emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 1));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 2));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 3));
+                                }
+                                break;
+                        case 1:
+                                while (shCount--) {
+                                        emitcode ("lsl", "%s", aopGet (AOP (result), 1));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 2));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 3));
+                                }
+                                break;
+                        case 2:
+                                while (shCount--) {
+                                        emitcode ("lsl", "%s", aopGet (AOP (result), 2));
+                                        emitcode ("rol", "%s", aopGet (AOP (result), 3));
+                                }
+                                break;
+                        case 3:
+                                while (shCount--) {
+                                        emitcode ("lsl", "%s", aopGet (AOP (result), 3));
+                                }
+                                break;
+                        }
+                }
         }
-    }
+
+      release:
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genRightShiftLiteral - right shifting by known count            */
+/* genLeftShift - generates code for left shifting                 */
 /*-----------------------------------------------------------------*/
-static void genRightShiftLiteral (operand *left,
-                                  operand *right,
-                                  operand *result,
-                                  iCode *ic,
-                                  int sign)
-{    
-    int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-    int size;
+static void
+genLeftShift (iCode * ic)
+{
+        operand *left, *right, *result;
+        int size, offset;
+        symbol *tlbl;
 
-    freeAsmop(right,NULL,ic,TRUE);
+        right = IC_RIGHT (ic);
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
 
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
+        aopOp (right, ic, FALSE);
 
-#if VIEW_SIZE
-    emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
-             AOP_SIZE(left));
-#endif
+        if (AOP_TYPE (right) == AOP_LIT) {
+                genShiftLeftLit (ic);
+                return;
+        }
 
-    size = getDataSize(left);
-    /* test the LEFT size !!! */
+        /* unknown count */
+        aopOp (left, ic, FALSE);
+        aopOp (result, ic, FALSE);
+        size = AOP_SIZE (result);
+        offset = 0;
+        if (AOP_SIZE (right) > 1) {
+                if (isRegPair (AOP (right))) {
+                        emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
+                }
+                else {
+                        emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+                        emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
+                }
+        }
+        else {
+                emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+        }
+        if (!sameRegs (AOP (left), AOP (result))) {
+                while (size--) {
+                        aopPut (AOP (result), aopGet (AOP (left), offset),
+                                offset);
+                        offset++;
+                }
+                size = AOP_SIZE (result);
+        }
+        tlbl = newiTempLabel (NULL);
+        emitcode ("", "L%05d:", tlbl->key);
+        offset = 0;
+        while (size--) {
+                if (offset)
+                        emitcode ("rol", "%s", aopGet (AOP (result), offset));
+                else
+                        emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+                offset++;
+        }
+        if (AOP_SIZE (right) > 1)
+                emitcode ("sbiw", "r24,1");
+        else
+                emitcode ("dec", "r24");
+        emitcode ("brne", "L%05d", tlbl->key);
 
-    /* I suppose that the left size >= result size */
-    if(shCount == 0){
-        size = getDataSize(result);
-        while(size--)
-            movLeft2Result(left, size, result, size, 0);
-    }
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
+}
 
-    else if(shCount >= (size * 8)){
-        if(sign)
-            /* get sign in acc.7 */
-            MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
-        addSign(result, LSB, sign);
-    } else{
+/*-----------------------------------------------------------------*/
+/* genShiftRightLit - generate for right shift with known count    */
+/*-----------------------------------------------------------------*/
+static void
+genShiftRightLit (iCode * ic)
+{
+        operand *left = IC_LEFT (ic)
+        , *right = IC_RIGHT (ic)
+        , *result = IC_RESULT (ic);
+        int size, shCount, offset = 0;
+        int hByteZ = 0;
+        sym_link *letype = getSpec (operandType (left));
+        int sign = !SPEC_USIGN (letype);
+
+        right = IC_RIGHT (ic);
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
+
+        aopOp (left, ic, FALSE);
+        aopOp (result, ic, FALSE);
+        size = AOP_SIZE (result);
+        shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+
+        /* if signed then give up and use a loop to shift */
+        if (sign) {
+                symbol *tlbl;
+                if (!sameRegs (AOP (left), AOP (result))) {
+                        while (size--) {
+                                aopPut (AOP (result),
+                                        aopGet (AOP (left), offset), offset);
+                                offset++;
+                        }
+                        size = AOP_SIZE (result);
+                        offset = 0;
+                }
+                /* be as economical as possible */
+                if (shCount <= 4) {
+                        while (shCount--) {
+                                size = AOP_SIZE (result);
+                                offset = size - 1;
+                                while (size--) {
+                                        /* highest order byte */
+                                        if (offset == (AOP_SIZE(result)-1))
+                                                emitcode ("asr", "%s", aopGet (AOP (result), offset));
+                                        else
+                                                emitcode ("ror", "%s", aopGet (AOP (result), offset));
+                                        offset--;
+                                }
+                        }
+                }
+                else {
+                        emitcode ("ldi", "r24,<(%d)", shCount);
+                        tlbl = newiTempLabel (NULL);
+                        emitcode ("", "L%05d:", tlbl->key);
+                        offset = size - 1;
+                        while (size--) {
+                                if (offset == (AOP_SIZE(result) - 1))
+                                        emitcode ("asr", "%s", aopGet (AOP (result), offset));
+                                else
+                                        emitcode ("ror", "%s", aopGet (AOP (result), offset));
+                                offset--;
+                        }
+                        emitcode ("dec", "r24");
+                        emitcode ("brne", "L%05d", tlbl->key);
+                }
+                goto release;
+        }
+        if (shCount > (size * 8 - 1)) {
+                while (size--)
+                        aopPut (AOP (result), zero, offset++);
+                goto release;
+        }
+        /* for unsigned we can much more efficient */
         switch (size) {
-            case 1:
-                genrshOne (result,left,shCount,sign);
+        case 1:
+                if (!sameRegs (AOP (left), AOP (result)))
+                        aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+                if (shCount >= 4) {
+                        emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                        if (AOP_ISHIGHREG(AOP(result),0)) {
+                                emitcode ("andi", "%s,0x0f",aopGet(AOP(result),0));
+                        } else {
+                                emitcode ("ldi","r24,0x0f");
+                                emitcode ("and", "%s,r24",aopGet(AOP(result),0));
+                        }
+                        shCount -= 4;
+                }
+                while (shCount--)
+                        emitcode ("lsr", "%s", aopGet (AOP (result), 0));
                 break;
+        case 2:
+                if (shCount >= 12) {
+                        aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+                        aopPut (AOP (result), zero, 1);
+                        emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                        if (AOP_ISHIGHREG(AOP(result),0)) {
+                                emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
+                        } else {
+                                emitcode ("ldi","r24,0x0f");
+                                emitcode ("and", "%s,r24",aopGet(AOP(result),0));
+                        }
+                        shCount -= 12;
+                        hByteZ = 1;
+                }
+                if (shCount >= 8) {
+                        aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+                        aopPut (AOP (result), zero, 1);
+                        shCount -= 8;
+                        hByteZ = 1;
+                }
+                if (shCount >= 4) {
+                        shCount -= 4;
+                        if (!sameRegs (AOP (left), AOP (result))) {
+                                aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+                                aopPut (AOP (result), aopGet (AOP (left), 1), 1);
+                        }
+                        if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
+                                emitcode("ldi","r25,0x0f");
+                        }
+                        emitcode ("mov", "r24,%s", aopGet (AOP (result), 1));
+                        emitcode ("andi", "r24,0xf0");
+                        emitcode ("swap", "%s", aopGet (AOP (result), 0));
+                        if (AOP_ISHIGHREG(AOP(result),0)) {
+                                emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
+                        } else {
+                                emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
+                        }
+                        emitcode ("or", "%s,r24", aopGet (AOP (result), 0));
+                        emitcode ("swap", "%s", aopGet (AOP (result), 1));
+                        if (AOP_ISHIGHREG(AOP(result),1)) {
+                                emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 1));
+                        } else {
+                                emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
+                        }
+                        while (shCount--) {
+                                emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+                                emitcode ("ror", "%s", aopGet (AOP (result), 0));
+                        }
 
-            case 2:
-                genrshTwo (result,left,shCount,sign);
+                }
+                if (!hByteZ && !sameRegs (AOP (result), AOP (left))
+                    && shCount) {
+                        offset = 0;
+                        while (size--) {
+                                aopPut (AOP (result), aopGet (AOP (left), offset), offset);
+                                offset++;
+                        }
+                }
+                while (shCount--) {
+                        if (hByteZ) {
+                                emitcode ("lsr", "%s", aopGet (AOP (result), 0));
+                        }
+                        else {
+                                emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+                                emitcode ("ror", "%s", aopGet (AOP (result), 0));
+                        }
+                }
                 break;
 
-            case 4:
-                genrshFour (result,left,shCount,sign);
-                break;
-            default :
+        case 3:
+                assert ("shifting generic pointer ?\n");
                 break;
+        case 4:
+                /* 32 bits we do only byte boundaries */
+                if (shCount >= 24) {
+                        aopPut (AOP (result), aopGet (AOP (left), 3), 0);
+                        aopPut (AOP (result), zero, 1);
+                        aopPut (AOP (result), zero, 2);
+                        aopPut (AOP (result), zero, 3);
+                        hByteZ = 3;
+                        shCount -= 24;
+                }
+                if (shCount >= 16) {
+                        aopPut (AOP (result), aopGet (AOP (left), 3), 1);
+                        aopPut (AOP (result), aopGet (AOP (left), 2), 0);
+                        aopPut (AOP (result), zero, 2);
+                        aopPut (AOP (result), zero, 3);
+                        hByteZ = 2;
+                        shCount -= 16;
+                }
+                if (shCount >= 8) {
+                        aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+                        aopPut (AOP (result), aopGet (AOP (left), 2), 1);
+                        aopPut (AOP (result), aopGet (AOP (left), 3), 2);
+                        aopPut (AOP (result), zero, 3);
+                        shCount -= 8;
+                        hByteZ = 1;
+                }
+                if (!hByteZ && !sameRegs (AOP (left), AOP (right))) {
+                        offset = 0;
+                        while (size--) {
+                                aopPut (AOP (result),
+                                        aopGet (AOP (left), offset), offset);
+                                offset++;
+                        }
+                        offset = 0;
+                        size = AOP_SIZE (result);
+                }
+                if (shCount) {
+                        switch (hByteZ) {
+                        case 0:
+                                while (shCount--) {
+                                        emitcode ("lsr", "%s", aopGet (AOP (result), 3));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 2));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 1));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 0));
+                                }
+                                break;
+                        case 1:
+                                while (shCount--) {
+                                        emitcode ("lsr", "%s", aopGet (AOP (result), 2));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 1));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 0));
+                                }
+                                break;
+                        case 2:
+                                while (shCount--) {
+                                        emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+                                        emitcode ("ror", "%s", aopGet (AOP (result), 0));
+                                }
+                                break;
+                        case 3:
+                                while (shCount--) {
+                                        emitcode ("lsr", "%s", aopGet (AOP (result), 0));
+                                }
+                                break;
+                        }
+                }
         }
-
-        freeAsmop(left,NULL,ic,TRUE);
-        freeAsmop(result,NULL,ic,TRUE);
-    }
+      release:
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genSignedRightShift - right shift of signed number              */
+/* genRightShift - generate code for right shifting                */
 /*-----------------------------------------------------------------*/
-static void genSignedRightShift (iCode *ic)
+static void
+genRightShift (iCode * ic)
 {
-    operand *right, *left, *result;
-    int size, offset;
-    char *l;
-    symbol *tlbl, *tlbl1 ;
+        operand *right, *left, *result;
+        sym_link *letype;
+        int size, offset;
+        int sign = 0, first = 1;
+        symbol *tlbl;
 
-    /* we do it the hard way put the shift count in b
-    and loop thru preserving the sign */
+        aopOp (right = IC_RIGHT (ic), ic, FALSE);
 
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
-
-    aopOp(right,ic,FALSE);  
+        if (AOP_TYPE (right) == AOP_LIT) {
+                genShiftRightLit (ic);
+                return;
+        }
+        /* unknown count */
+        if (AOP_SIZE (right) > 1) {
+                if (isRegPair (AOP (right))) {
+                        emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
+                }
+                else {
+                        emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+                        emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
+                }
+        }
+        else {
+                emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+        }
+        aopOp (left = IC_LEFT (ic), ic, FALSE);
+        aopOp (result = IC_RESULT (ic), ic, FALSE);
+        size = AOP_SIZE (result);
+        tlbl = newiTempLabel (NULL);
+        emitcode ("", "L%05d:", tlbl->key);
+        offset = size - 1;
+        letype = getSpec (operandType (left));
+        sign = !SPEC_USIGN (letype);
+        if (!sameRegs (AOP (left), AOP (result))) {
+                while (size--) {
+                        aopPut (AOP (result), aopGet (AOP (left), offset), offset);
+                        offset++;
+                }
+                size = AOP_SIZE (result);
+        }
+        size = AOP_SIZE (result);
+        while (size--) {
+                if (first) {
+                        if (sign)
+                                emitcode ("asr", "%s", aopGet (AOP (result), offset));
+                        else
+                                emitcode ("lsr", "%s", aopGet (AOP (result), offset));
+                        first = 0;
+                }
+                else
+                        emitcode ("ror", "%s", aopGet (AOP (result), offset));
+                offset--;
+        }
+        if (AOP_SIZE (right) > 1)
+                emitcode ("sbiw", "r24,1");
+        else
+                emitcode ("dec", "r24");
+        emitcode ("brne", "L%05d", tlbl->key);
 
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
+}
 
-    if ( AOP_TYPE(right) == AOP_LIT) {
-       genRightShiftLiteral (left,right,result,ic,1);
-       return ;
-    }
-        /* shift count is unknown then we have to form 
-       a loop get the loop count in B : Note: we take
-       only the lower order byte since shifting
-       more that 32 bits make no sense anyway, ( the
-       largest size of an object can be only 32 bits ) */  
-
-    emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-    /* now move the left to the result if they are not the
-    same */
-    if (!sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && IS_AOP_PREG(result)) {
+/*-----------------------------------------------------------------*/
+/* RRsh - shift right rn by known count                            */
+/*-----------------------------------------------------------------*/
+static void
+RRsh (int shCount,int reg)
+{
+        shCount &= 0x0007;      // shCount : 0..7
 
-                emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
+        switch (shCount) {
+        case 0:
+                break;
+        case 1:
+                emitcode ("lsr", "r%d",reg);
+                break;
+        case 2:
+                emitcode ("lsr", "r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                break;
+        case 3:
+                emitcode ("swap", "r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                break;
+        case 4:
+                emitcode ("swap", "r%d",reg);
+                break;
+        case 5:
+                emitcode ("swap", "r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                break;
+        case 6:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                break;
+        case 7:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                break;
         }
-    }
-
-    /* mov the highest order bit to OVR */    
-    tlbl = newiTempLabel(NULL);
-    tlbl1= newiTempLabel(NULL);
-
-    size = AOP_SIZE(result);
-    offset = size - 1;
-    emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
-    emitcode("rlc","a");
-    emitcode("mov","ov,c");
-    /* if it is only one byte then */
-    if (size == 1) {
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       emitcode("sjmp","%05d$",tlbl1->key+100);
-        emitcode("","%05d$:",tlbl->key+100);
-        emitcode("mov","c,ov");
-        emitcode("rrc","a");
-       emitcode("","%05d$:",tlbl1->key+100);
-        emitcode("djnz","b,%05d$",tlbl->key+100);
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
+}
 
-    reAdjustPreg(AOP(result));
-    emitcode("sjmp","%05d$",tlbl1->key+100);
-    emitcode("","%05d$:",tlbl->key+100);    
-    emitcode("mov","c,ov");
-    while (size--) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        emitcode("rrc","a");         
-        aopPut(AOP(result),"a",offset--);
-    }
-    reAdjustPreg(AOP(result));
-    emitcode("","%05d$:",tlbl1->key+100);
-    emitcode("djnz","b,%05d$",tlbl->key+100);
+/*-----------------------------------------------------------------*/
+/* RLsh - shift left rn by known count                             */
+/*-----------------------------------------------------------------*/
+static void
+RLsh (int shCount, int reg)
+{
+        shCount &= 0x0007;      // shCount : 0..7
 
-release:
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+        switch (shCount) {
+        case 0:
+                break;
+        case 1:
+                emitcode ("lsl", "r%d",reg);
+                break;
+        case 2:
+                emitcode ("lsl", "r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                break;
+        case 3:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsr", "r%d",reg);
+                break;
+        case 4:
+                emitcode ("swap", "r%d",reg);
+                break;
+        case 5:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                break;
+        case 6:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                break;
+        case 7:
+                emitcode ("swap","r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                emitcode ("lsl", "r%d",reg);
+                break;
+        }
 }
 
 /*-----------------------------------------------------------------*/
-/* genRightShift - generate code for right shifting                */
+/* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
-static void genRightShift (iCode *ic)
+static void
+genUnpackBits (operand * result, char *rname, int ptype)
 {
-    operand *right, *left, *result;
-    link *retype ;
-    int size, offset;
-    char *l;
-    symbol *tlbl, *tlbl1 ;
-
-    /* if signed then we do it the hard way preserve the
-    sign bit moving it inwards */
-    retype = getSpec(operandType(IC_RESULT(ic)));
-
-    if (!SPEC_USIGN(retype)) {
-        genSignedRightShift (ic);
-        return ;
-    }
+        int shCnt;
+        int rlen = 0;
+        sym_link *etype;
+        int offset = 0;
+        int rsize;
+
+        etype = getSpec (operandType (result));
+        rsize = getSize (operandType (result));
+        /* read the first byte  */
+        switch (ptype) {
+
+        case POINTER:
+        case IPOINTER:
+        case PPOINTER:
+        case FPOINTER:
+                emitcode ("ld", "r24,%s+", rname);
+                break;
 
-    /* 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 */
+        case CPOINTER:
+                emitcode ("lpm", "r24,%s+", rname);
+                break;
 
-    right = IC_RIGHT(ic);
-    left  = IC_LEFT(ic);
-    result = IC_RESULT(ic);
+        case GPOINTER:
+                emitcode ("call","__gptrget_pi");
+                emitcode ("mov","r24,r0");
+                break;
+        }
 
-    aopOp(right,ic,FALSE);
+        rlen = SPEC_BLEN (etype);
 
-    /* if the shift count is known then do it 
-    as efficiently as possible */
-    if (AOP_TYPE(right) == AOP_LIT) {
-        genRightShiftLiteral (left,right,result,ic, 0);
-        return ;
-    }
+        /* if we have bitdisplacement then it fits   */
+        /* into this byte completely or if length is */
+        /* less than a byte                          */
+        if ((shCnt = SPEC_BSTR (etype)) || (SPEC_BLEN (etype) <= 8)) {
 
-    /* shift count is unknown then we have to form 
-    a loop get the loop count in B : Note: we take
-    only the lower order byte since shifting
-    more that 32 bits make no sense anyway, ( the
-    largest size of an object can be only 32 bits ) */  
-
-    emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
-    aopOp(left,ic,FALSE);
-    aopOp(result,ic,FALSE);
-
-    /* now move the left to the result if they are not the
-    same */
-    if (!sameRegs(AOP(left),AOP(result)) && 
-        AOP_SIZE(result) > 1) {
-
-        size = AOP_SIZE(result);
-        offset=0;
-        while (size--) {
-            l = aopGet(AOP(left),offset,FALSE,TRUE);
-            if (*l == '@' && IS_AOP_PREG(result)) {
+                /* shift right acc */
+                RRsh (shCnt,24);
 
-                emitcode("mov","a,%s",l);
-                aopPut(AOP(result),"a",offset);
-            } else
-                aopPut(AOP(result),l,offset);
-            offset++;
+                emitcode ("andi", "r24,lo(0x%x)",
+                          ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
+                aopPut (AOP (result), "r24", offset++);
+                goto finish;
         }
-    }
 
-    tlbl = newiTempLabel(NULL);
-    tlbl1= newiTempLabel(NULL);
-    size = AOP_SIZE(result);
-    offset = size - 1;
-
-    /* if it is only one byte then */
-    if (size == 1) {
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       emitcode("sjmp","%05d$",tlbl1->key+100);
-        emitcode("","%05d$:",tlbl->key+100);
-        CLRC;
-        emitcode("rrc","a");
-       emitcode("","%05d$:",tlbl1->key+100);
-        emitcode("djnz","b,%05d$",tlbl->key+100);
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
+        /* bit field did not fit in a byte  */
+        aopPut (AOP (result), "r24", offset++);
 
-    reAdjustPreg(AOP(result));
-    emitcode("sjmp","%05d$",tlbl1->key+100);
-    emitcode("","%05d$:",tlbl->key+100);    
-    CLRC;
-    while (size--) {
-        l = aopGet(AOP(result),offset,FALSE,FALSE);
-        MOVA(l);
-        emitcode("rrc","a");         
-        aopPut(AOP(result),"a",offset--);
-    }
-    reAdjustPreg(AOP(result));
+        while (1) {
 
-    emitcode("","%05d$:",tlbl1->key+100);
-    emitcode("djnz","b,%05d$",tlbl->key+100);
+                switch (ptype) {
 
-release:
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
-}
+                case POINTER:
+                case IPOINTER:
+                case PPOINTER:
+                case FPOINTER:
+                        emitcode ("ld", "r24,%s+");
+                        break;
 
-/*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits               */
-/*-----------------------------------------------------------------*/
-static void genUnpackBits (operand *result, char *rname, int ptype)
-{    
-    int shCnt ;
-    int rlen = 0 ;
-    link *etype;
-    int offset = 0 ;
-
-    etype = getSpec(operandType(result));
-
-    /* read the first byte  */
-    switch (ptype) {
-
-    case POINTER:
-    case IPOINTER:
-       emitcode("mov","a,@%s",rname);
-       break;
-       
-    case PPOINTER:
-       emitcode("movx","a,@%s",rname);
-       break;
-       
-    case FPOINTER:
-       emitcode("movx","a,@dptr");
-       break;
-
-    case CPOINTER:
-       emitcode("clr","a");
-       emitcode("movc","a","@a+dptr");
-       break;
-
-    case GPOINTER:
-       emitcode("lcall","__gptrget");
-       break;
-    }
+                case CPOINTER:
+                        emitcode ("lpm", "r24,%s+");
+                        break;
 
-    /* if we have bitdisplacement then it fits   */
-    /* into this byte completely or if length is */
-    /* less than a byte                          */
-    if ((shCnt = SPEC_BSTR(etype)) || 
-        (SPEC_BLEN(etype) <= 8))  {
+                case GPOINTER:
+                        emitcode ("call", "__gptrget_pi");
+                        break;
+                }
 
-        /* shift right acc */
-        AccRsh(shCnt);
+                rlen -= 8;
+                /* if we are done */
+                if (rlen < 8)
+                        break;
 
-        emitcode("anl","a,#0x%02x",
-                 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
-        aopPut(AOP(result),"a",offset);
-        return ;
-    }
+                aopPut (AOP (result), "r24", offset++);
 
-    /* bit field did not fit in a byte  */
-    rlen = SPEC_BLEN(etype) - 8;
-    aopPut(AOP(result),"a",offset++);
-
-    while (1)  {
-
-       switch (ptype) {
-       case POINTER:
-       case IPOINTER:
-           emitcode("inc","%s",rname);
-           emitcode("mov","a,@%s",rname);
-           break;
-           
-       case PPOINTER:
-           emitcode("inc","%s",rname);
-           emitcode("movx","a,@%s",rname);
-           break;
-
-       case FPOINTER:
-           emitcode("inc","dptr");
-           emitcode("movx","a,@dptr");
-           break;
-           
-       case CPOINTER:
-           emitcode("clr","a");
-           emitcode("inc","dptr");
-           emitcode("movc","a","@a+dptr");
-           break;
-           
-       case GPOINTER:
-           emitcode("inc","dptr");
-           emitcode("lcall","__gptrget");
-           break;
-       }
-
-       rlen -= 8;            
-       /* if we are done */
-       if ( rlen <= 0 )
-           break ;
-       
-       aopPut(AOP(result),"a",offset++);
-                                     
-    }
-    
-    if (rlen) {
-       emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
-       aopPut(AOP(result),"a",offset);        
-    }
-    
-    return ;
-}
+        }
+
+        if (rlen) {
+                aopPut (AOP (result), "r24", offset++);
+        }
 
+      finish:
+        if (offset < rsize) {
+                rsize -= offset;
+                while (rsize--)
+                        aopPut (AOP (result), zero, offset++);
+        }
+        return;
+}
 
 /*-----------------------------------------------------------------*/
 /* genDataPointerGet - generates code when ptr offset is known     */
 /*-----------------------------------------------------------------*/
-static void genDataPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+static void
+genDataPointerGet (operand * left, operand * result, iCode * ic)
 {
-    char *l;
-    char buffer[256];
-    int size , offset = 0;
-    aopOp(result,ic,TRUE);
-
-    /* get the string representation of the name */
-    l = aopGet(AOP(left),0,FALSE,TRUE);
-    size = AOP_SIZE(result);
-    while (size--) {
-       if (offset)
-           sprintf(buffer,"(%s + %d)",l+1,offset);
-       else
-           sprintf(buffer,"%s",l+1);
-       aopPut(AOP(result),buffer,offset++);
-    }
+        char *l;
+        char buffer[256];
+        int size, offset = 0;
+        aopOp (result, ic, TRUE);
+
+        /* get the string representation of the name */
+        l = aopGet (AOP (left), 0);
+        size = AOP_SIZE (result);
+        while (size--) {
+                if (offset)
+                        sprintf (buffer, "(%s + %d)", l, offset);
+                else
+                        sprintf (buffer, "%s", l);
+                emitcode ("lds", "%s,%s", aopGet (AOP (result), offset++),
+                          buffer);
+        }
 
-    freeAsmop(left,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genNearPointerGet - emitcode for near pointer fetch             */
 /*-----------------------------------------------------------------*/
-static void genNearPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
+static void
+genMemPointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
 {
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname ;
-    link *rtype, *retype;
-    link *ltype = operandType(left);    
-    char buffer[80];
-
-    rtype = operandType(result);
-    retype= getSpec(rtype);
-    
-    aopOp(left,ic,FALSE);
-    
-    /* if left is rematerialisable and
-       result is not bit variable type and
-       the left is pointer to data space i.e
-       lower 128 bytes of space */
-    if (AOP_TYPE(left) == AOP_IMMD &&
-       !IS_BITVAR(retype)         &&
-       DCL_TYPE(ltype) == POINTER) {
-       genDataPointerGet (left,result,ic);
-       return ;
-    }
-    
-       /* if the value is already in a pointer register
-       then don't need anything more */
-    if (!AOP_INPREG(AOP(left))) {
-       /* otherwise get a free pointer register */
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(left),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(left),0,FALSE,FALSE);
-    
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp (result,ic,FALSE);
-    
-      /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genUnpackBits (result,rname,POINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(result);
-       int offset = 0 ;        
-       
-       while (size--) {
-           if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
-
-               emitcode("mov","a,@%s",rname);
-               aopPut(AOP(result),"a",offset);
-           } else {
-               sprintf(buffer,"@%s",rname);
-               aopPut(AOP(result),buffer,offset);
-           }
-           offset++ ;
-           if (size)
-               emitcode("inc","%s",rname);
-       }
-    }
+        asmop *aop = NULL;
+        regs *preg = NULL;
+        int gotFreePtr = 0;
+        char *rname, *frname = NULL;
+        sym_link *rtype, *retype;
+        sym_link *ltype = operandType (left);
+
+        rtype = operandType (result);
+        retype = getSpec (rtype);
+
+        aopOp (left, ic, FALSE);
+
+        /* if left is rematerialisable and
+           result is not bit variable type and
+           the left is pointer to data space i.e
+           lower 128 bytes of space */
+        if (AOP_TYPE (left) == AOP_IMMD &&
+            !IS_BITVAR (retype) && DCL_TYPE (ltype) == POINTER) {
+                genDataPointerGet (left, result, ic);
+                return;
+        }
 
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-       freeAsmop(NULL,aop,ic,TRUE);
-    } else { 
-       /* we did not allocate which means left
-          already in a pointer register, then
-          if size > 0 && this could be used again
-          we have to point it back to where it 
-          belongs */
-       if (AOP_SIZE(result) > 1 &&
-           !OP_SYMBOL(left)->remat &&
-           ( OP_SYMBOL(left)->liveTo > ic->seq ||
-             ic->depth )) {
-           int size = AOP_SIZE(result) - 1;
-           while (size--)
-               emitcode("dec","%s",rname);
-       }
-    }
+        /* if the value is already in a pointer register
+           then don't need anything more */
+        if (!AOP_INPREG (AOP (left))) {
+                /* otherwise get a free pointer register */
+                aop = newAsmop (0);
+                preg = getFreePtr (ic, &aop, FALSE, 0);
+                if (isRegPair (AOP (left) )) {
+                        emitcode ("movw", "%s,%s",
+                                  aop->aopu.aop_ptr->name,
+                                  aopGet(AOP(left),0));
+                } else {
+                        emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+                                  aopGet (AOP (left), 0));
+                        emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+                                  aopGet (AOP (left), 1));
+                }
+                gotFreePtr = 1;
+        }
+        else {
+                aop = AOP(left);
+                frname = aopGet(aop,0);
+        }
+        if (AOP_ISX(aop)) {
+                rname = "X";
+        } else if (AOP_ISZ(aop)) {
+                rname = "Z";
+        } else {
+                werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                        "pointer not in correct register");
+                exit (0);
+        }
 
-    /* done */
-    freeAsmop(result,NULL,ic,TRUE);
-     
-}
+        aopOp (result, ic, FALSE);
 
-/*-----------------------------------------------------------------*/
-/* genPagedPointerGet - emitcode for paged pointer fetch           */
-/*-----------------------------------------------------------------*/
-static void genPagedPointerGet (operand *left, 
-                              operand *result, 
-                              iCode *ic)
-{
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname ;
-    link *rtype, *retype;    
-
-    rtype = operandType(result);
-    retype= getSpec(rtype);
-    
-    aopOp(left,ic,FALSE);
-
-  /* if the value is already in a pointer register
-       then don't need anything more */
-    if (!AOP_INPREG(AOP(left))) {
-       /* otherwise get a free pointer register */
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(left),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(left),0,FALSE,FALSE);
-    
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp (result,ic,FALSE);
-
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genUnpackBits (result,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(result);
-       int offset = 0 ;        
-       
-       while (size--) {
-           
-           emitcode("movx","a,@%s",rname);
-           aopPut(AOP(result),"a",offset);
-           
-           offset++ ;
-           
-           if (size)
-               emitcode("inc","%s",rname);
-       }
-    }
+        /* if bitfield then unpack the bits */
+        if (IS_BITVAR (retype))
+                genUnpackBits (result, rname, POINTER);
+        else {
+                /* we have can just get the values */
+                int size = AOP_SIZE (result);
+                int offset = 0;
+
+                while (size--) {
+                        if (size || pi) {
+                                emitcode ("ld","%s,%s+",aopGet(AOP(result),offset), rname);
+                        } else {
+                                emitcode ("ld","%s,%s",aopGet(AOP(result),offset), rname);
+                        }
+                }
+        }
 
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-       freeAsmop(NULL,aop,ic,TRUE);
-    } else { 
-       /* we did not allocate which means left
-          already in a pointer register, then
-          if size > 0 && this could be used again
-          we have to point it back to where it 
-          belongs */
-       if (AOP_SIZE(result) > 1 &&
-           !OP_SYMBOL(left)->remat &&
-           ( OP_SYMBOL(left)->liveTo > ic->seq ||
-             ic->depth )) {
-           int size = AOP_SIZE(result) - 1;
-           while (size--)
-               emitcode("dec","%s",rname);
-       }
-    }
+        /* now some housekeeping stuff */
+        if (gotFreePtr) {
+                /* we had to allocate for this iCode */
+                if (pi) {
+                        if (isRegPair (AOP (left) )) {
+                                emitcode ("movw", "%s,%s",
+                                          aopGet (AOP(left),0),
+                                          aop->aopu.aop_ptr->name);
+                        } else {
+                                emitcode ("mov", "%s,%s",
+                                          aopGet (AOP (left), 0),
+                                          aop->aopu.aop_ptr->name);
+                                emitcode ("mov", "%s,%s",
+                                          aopGet (AOP (left), 1),
+                                          aop->aop_ptr2->name);
+                        }
+                }
+                freeAsmop (NULL, aop, ic, TRUE);
+        } else {
+
+                /* we did not allocate which means left
+                   already in a pointer register, then
+                   if size > 0 && this could be used again
+                   we have to point it back to where it
+                   belongs */
+                if ((AOP_SIZE (result) > 1 &&
+                     !OP_SYMBOL (left)->remat &&
+                     (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) && !pi) {
+                        int size = AOP_SIZE (result) - 1;
+                        emitcode ("sbiw", "%s,%d",frname,size);
+                }
+        }
+
+        /* done */
+        if (pi) pi->generated = 1;
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 
-    /* done */
-    freeAsmop(result,NULL,ic,TRUE);
-    
-       
 }
 
 /*-----------------------------------------------------------------*/
-/* genFarPointerGet - gget value from far space                    */
+/* genCodePointerGet - gget value from code space                  */
 /*-----------------------------------------------------------------*/
-static void genFarPointerGet (operand *left,
-                              operand *result, iCode *ic)
+static void
+genCodePointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
 {
-    int size, offset ;
-    link *retype = getSpec(operandType(result));
-
-    aopOp(left,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD)
-            emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
-        }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE);
+        int size, offset;
+        sym_link *retype = getSpec (operandType (result));
+        asmop *aop = NULL;
+        int gotFreePtr = 0;
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
+        aopOp (left, ic, FALSE);
 
-        while (size--) {
-            emitcode("movx","a,@dptr");
-            aopPut(AOP(result),"a",offset++);
-            if (size)
-                emitcode("inc","dptr");
+        /* if the operand is already in Z register
+           then we do nothing else we move the value to Z register */
+        if (AOP_ISZ(AOP(left))) {
+                aop = AOP (left);
+        } else {
+                aop = newAsmop(0);
+                getFreePtr(ic,&aop,FALSE,TRUE);
+                if (isRegPair(AOP (left))) {
+                        emitcode ("movw","r30,%s",aopGet (AOP (left), 0));
+                } else {
+                        emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
+                        emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
+                }
+                gotFreePtr = 1;
         }
-    }
 
-    freeAsmop(result,NULL,ic,TRUE);
-}
+        aopOp (result, ic, FALSE);
 
-/*-----------------------------------------------------------------*/
-/* emitcodePointerGet - gget value from code space                  */
-/*-----------------------------------------------------------------*/
-static void emitcodePointerGet (operand *left,
-                                operand *result, iCode *ic)
-{
-    int size, offset ;
-    link *retype = getSpec(operandType(result));
-
-    aopOp(left,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD)
-            emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
+        /* if bit then unpack */
+        if (IS_BITVAR (retype))
+                genUnpackBits (result, "Z", CPOINTER);
+        else {
+                size = AOP_SIZE (result);
+                offset = 0;
+
+                while (size--) {
+                        if (size || pi) {
+                                emitcode ("lpm","%s,Z+",aopGet(AOP(result),offset++));
+                        } else {
+                                emitcode ("lpm","%s,Z",aopGet(AOP(result),offset++));
+                        }
+                }
         }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",CPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
+        /* now some housekeeping stuff */
+        if (gotFreePtr) {
+                /* we had to allocate for this iCode */
+                if (pi) {
+                        if (isRegPair(AOP (left))) {
+                                emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
+                        } else {
+                                emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
+                                emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
+                        }
+                }
+                freeAsmop (NULL, aop, ic, TRUE);
+        } else {
 
-        while (size--) {
-            emitcode("clr","a");
-            emitcode("movc","a,@a+dptr");
-            aopPut(AOP(result),"a",offset++);
-            if (size)
-                emitcode("inc","dptr");
+                /* we did not allocate which means left
+                   already in a pointer register, then
+                   if size > 0 && this could be used again
+                   we have to point it back to where it
+                   belongs */
+                if ((AOP_SIZE (result) > 1 &&
+                     !OP_SYMBOL (left)->remat &&
+                     (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
+                    !pi) {
+                        int size = AOP_SIZE (result) - 1;
+                        emitcode ("sbiw", "r30,%d",size);
+                }
         }
-    }
 
-    freeAsmop(result,NULL,ic,TRUE);
+        /* done */
+        if (pi) pi->generated=1;
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
+
 }
 
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet - gget value from generic pointer space        */
 /*-----------------------------------------------------------------*/
-static void genGenPointerGet (operand *left,
-                              operand *result, iCode *ic)
+static void
+genGenPointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
 {
-    int size, offset ;
-    link *retype = getSpec(operandType(result));
-
-    aopOp(left,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(left) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(left) == AOP_IMMD) {
-            emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
-           emitcode("mov","b,#%d",pointerCode(retype));
-       }
-        else { /* we need to get it byte by byte */
-            emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
-            emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
-               emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
-            }
-            else
-            {
-               emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
-            }
+        int size, offset;
+        int gotFreePtr = 0;
+        sym_link *retype = getSpec (operandType (result));
+        asmop *aop = NULL;
+
+        aopOp (left, ic, FALSE);
+
+        /* if the operand is already in dptr
+           then we do nothing else we move the value to dptr */
+        if (AOP_ISZ(AOP(left))) {
+                aop = AOP(left);
+        } else {
+                aop = newAsmop(0);
+                getFreePtr(ic,&aop,FALSE,TRUE);
+                if (isRegPair(AOP(left))) {
+                        emitcode ("movw", "r30,%s", aopGet (AOP (left), 0));
+                } else {
+                        emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
+                        emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
+                }
+                emitcode ("mov", "r24,%s", aopGet (AOP (left), 2));
+                gotFreePtr=1;
         }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE); 
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genUnpackBits(result,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(result);
-        offset = 0 ;
+        /* so Z register now contains the address */
 
-        while (size--) {
-            emitcode("lcall","__gptrget");
-            aopPut(AOP(result),"a",offset++);
-            if (size)
-                emitcode("inc","dptr");
+        aopOp (result, ic, FALSE);
+
+        /* if bit then unpack */
+        if (IS_BITVAR (retype))
+                genUnpackBits (result, "Z", GPOINTER);
+        else {
+                size = AOP_SIZE (result);
+                offset = 0;
+
+                while (size--) {
+                        if (size || pi)
+                                emitcode ("call", "__gptrget_pi");
+                        else
+                                emitcode ("call", "__gptrget");
+                        aopPut (AOP (result), "r0", offset++);
+                }
         }
-    }
 
-    freeAsmop(result,NULL,ic,TRUE);
+
+        /* now some housekeeping stuff */
+        if (gotFreePtr) {
+                /* we had to allocate for this iCode */
+                if (pi) {
+                        if (isRegPair(AOP (left))) {
+                                emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
+                        } else {
+                                emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
+                                emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
+                        }
+                }
+                freeAsmop (NULL, aop, ic, TRUE);
+        } else {
+
+                /* we did not allocate which means left
+                   already in a pointer register, then
+                   if size > 0 && this could be used again
+                   we have to point it back to where it
+                   belongs */
+                if ((AOP_SIZE (result) > 1 &&
+                     !OP_SYMBOL (left)->remat &&
+                     (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
+                    !pi) {
+                        int size = AOP_SIZE (result) - 1;
+                        emitcode ("sbiw", "r30,%d",size);
+                }
+        }
+        if (pi) pi->generated=1;
+        freeAsmop (left, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
-static void genPointerGet (iCode *ic)
+static void
+genPointerGet (iCode * ic, iCode *pi)
 {
-    operand *left, *result ;
-    link *type, *etype;
-    int p_type;
-
-    left = IC_LEFT(ic);
-    result = IC_RESULT(ic) ;
-
-    /* depending on the type of pointer we need to
-    move it to the correct pointer register */
-    type = operandType(left);
-    etype = getSpec(type);
-    /* if left is of type of pointer then it is simple */
-    if (IS_PTR(type) && !IS_FUNC(type->next)) 
-        p_type = DCL_TYPE(type);
-    else {
-       /* we have to go by the storage class */
-       p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/*     if (SPEC_OCLS(etype)->codesp ) { */
-/*         p_type = CPOINTER ;  */
-/*     } */
-/*     else */
-/*         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*             p_type = FPOINTER ; */
-/*         else */
-/*             if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*                 p_type = PPOINTER; */
-/*             else */
-/*                 if (SPEC_OCLS(etype) == idata ) */
-/*                     p_type = IPOINTER; */
-/*                 else */
-/*                     p_type = POINTER ; */
-    }
+        operand *left, *result;
+        sym_link *type, *etype;
+        int p_type;
+
+        left = IC_LEFT (ic);
+        result = IC_RESULT (ic);
+
+        /* depending on the type of pointer we need to
+           move it to the correct pointer register */
+        type = operandType (left);
+        etype = getSpec (type);
+        /* if left is of type of pointer then it is simple */
+        if (IS_PTR (type) && !IS_FUNC (type->next))
+                p_type = DCL_TYPE (type);
+        else {
+                /* we have to go by the storage class */
+                p_type = PTR_TYPE (SPEC_OCLS (etype));
 
-    /* now that we have the pointer type we assign
-    the pointer values */
-    switch (p_type) {
 
-    case POINTER:      
-    case IPOINTER:
-       genNearPointerGet (left,result,ic);
-       break;
+        }
 
-    case PPOINTER:
-       genPagedPointerGet(left,result,ic);
-       break;
+        /* now that we have the pointer type we assign
+           the pointer values */
+        switch (p_type) {
 
-    case FPOINTER:
-       genFarPointerGet (left,result,ic);
-       break;
+        case POINTER:
+        case IPOINTER:
+        case PPOINTER:
+        case FPOINTER:
+                genMemPointerGet (left, result, ic, pi);
+                break;
 
-    case CPOINTER:
-       emitcodePointerGet (left,result,ic);
-       break;
+        case CPOINTER:
+                genCodePointerGet (left, result, ic, pi);
+                break;
 
-    case GPOINTER:
-       genGenPointerGet (left,result,ic);
-       break;
-    }
+        case GPOINTER:
+                genGenPointerGet (left, result, ic, pi);
+                break;
+        }
 
 }
 
 /*-----------------------------------------------------------------*/
 /* genPackBits - generates code for packed bit storage             */
 /*-----------------------------------------------------------------*/
-static void genPackBits (link    *etype ,
-                         operand *right ,
-                         char *rname, int p_type)
+static void
+genPackBits (sym_link * etype,
+             operand * right,
+             char *rname, int p_type)
 {
-    int shCount = 0 ;
-    int offset = 0  ;
-    int rLen = 0 ;
-    int blen, bstr ;   
-    char *l ;
+        int shCount = 0;
+        int offset = 0;
+        int rLen = 0;
+        int blen, bstr;
+        char *l;
+
+        blen = SPEC_BLEN (etype);
+        bstr = SPEC_BSTR (etype);
+
+        l = aopGet (AOP (right), offset++);
+        MOVR24 (l);
+
+        /* if the bit lenth is less than or    */
+        /* it exactly fits a byte then         */
+        if (SPEC_BLEN (etype) <= 8) {
+                shCount = SPEC_BSTR (etype);
+
+                /* shift left acc */
+                RLsh (shCount,24);
+
+                if (SPEC_BLEN (etype) < 8) {                    /* if smaller than a byte */
+
+                        switch (p_type) {
+                        case POINTER:
+                        case IPOINTER:
+                        case PPOINTER:
+                        case FPOINTER:
+                                emitcode ("ld", "r1,%s",rname);
+                                break;
+
+                        case GPOINTER:
+                                emitcode ("push", "r1");
+                                emitcode ("push", "r24");
+                                emitcode ("call", "__gptrget");
+                                emitcode ("pop", "r1");
+                                emitcode ("mov","r24,r0");
+                                break;
+                        }
+
+                        emitcode ("andi", "r24,#0x%02x", (unsigned char)
+                                  ((unsigned char) (0xFF << (blen + bstr)) |
+                                   (unsigned char) (0xFF >> (8 - bstr))));
+                        emitcode ("or", "r24,r1");
+                        if (p_type == GPOINTER)
+                                emitcode ("pop", "r1");
+                }
+        }
+
+        switch (p_type) {
+        case POINTER:
+        case IPOINTER:
+        case PPOINTER:
+        case FPOINTER:
+                emitcode("st","%s+,r24");
+                break;
 
-    blen = SPEC_BLEN(etype);
-    bstr = SPEC_BSTR(etype);
+        case GPOINTER:
+                emitcode("mov","r0,r24");
+                emitcode ("call", "__gptrput_pi");
+                break;
+        }
 
-    l = aopGet(AOP(right),offset++,FALSE,FALSE);
-    MOVA(l);   
+        /* if we r done */
+        if (SPEC_BLEN (etype) <= 8)
+                return;
 
-    /* if the bit lenth is less than or    */
-    /* it exactly fits a byte then         */
-    if (SPEC_BLEN(etype) <= 8 )  {
-        shCount = SPEC_BSTR(etype) ;
+        rLen = SPEC_BLEN (etype);
 
-        /* shift left acc */
-        AccLsh(shCount);
+        /* now generate for lengths greater than one byte */
+        while (1) {
 
-        if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
+                l = aopGet (AOP (right), offset++);
 
+                rLen -= 8;
+                if (rLen < 8)
+                        break;
 
-            switch (p_type) {
+                switch (p_type) {
                 case POINTER:
-                    emitcode ("mov","b,a");
-                    emitcode("mov","a,@%s",rname);
-                    break;
-
+                case IPOINTER:
+                case PPOINTER:
                 case FPOINTER:
-                    emitcode ("mov","b,a");
-                    emitcode("movx","a,@dptr");
-                    break;
+                        emitcode ("st", "%s+,%s",rname,l);
+                        break;
 
                 case GPOINTER:
-                    emitcode ("push","b");
-                    emitcode ("push","acc");
-                    emitcode ("lcall","__gptrget");
-                    emitcode ("pop","b");
-                    break;
-            }
-
-            emitcode ("anl","a,#0x%02x",(unsigned char)
-                      ((unsigned char)(0xFF << (blen+bstr)) | 
-                       (unsigned char)(0xFF >> (8-bstr)) ) );
-            emitcode ("orl","a,b");
-            if (p_type == GPOINTER)
-                emitcode("pop","b");
+                        MOVR0 (l);
+                        emitcode ("lcall", "__gptrput_pi");
+                        break;
+                }
         }
-    }
-
-    switch (p_type) {
-        case POINTER:
-            emitcode("mov","@%s,a",rname);
-            break;
-
-        case FPOINTER:
-            emitcode("movx","@dptr,a");
-            break;
-
-        case GPOINTER:
-            emitcode("lcall","__gptrput");
-            break;
-    }
-
-    /* if we r done */
-    if ( SPEC_BLEN(etype) <= 8 )
-        return ;
-
-    emitcode("inc","%s",rname);
-    rLen = SPEC_BLEN(etype) ;     
-
-    /* now generate for lengths greater than one byte */
-    while (1) {
 
-        l = aopGet(AOP(right),offset++,FALSE,TRUE);
+        MOVR24 (l);
 
-        rLen -= 8 ;
-        if (rLen <= 0 )
-            break ;
-
-        switch (p_type) {
-            case POINTER:
-                if (*l == '@') {
-                    MOVA(l);
-                    emitcode("mov","@%s,a",rname);
-                } else
-                    emitcode("mov","@%s,%s",rname,l);
-                break;
-
-            case FPOINTER:
-                MOVA(l);
-                emitcode("movx","@dptr,a");
-                break;
+        /* last last was not complete */
+        if (rLen) {
+                /* save the byte & read byte */
+                switch (p_type) {
+                case POINTER:
+                case IPOINTER:
+                case PPOINTER:
+                case FPOINTER:
+                        emitcode ("st","%s+,r24",rname);
+                        break;
+                case GPOINTER:
+                        emitcode ("push", "r1");
+                        emitcode ("push", "r24");
+                        emitcode ("lcall", "__gptrget");
+                        emitcode ("mov","r24,r0");
+                        emitcode ("pop", "r1");
+                        break;
+                }
 
-            case GPOINTER:
-                MOVA(l);
-                emitcode("lcall","__gptrput");
-                break;  
-        }   
-        emitcode ("inc","%s",rname);
-    }
+                emitcode ("andi", "r24,0x%02x", (((unsigned char) -1 << rLen) & 0xff));
+                emitcode ("or", "r24,r1");
+        }
 
-    MOVA(l);
+        if (p_type == GPOINTER)
+                emitcode ("pop", "r1");
 
-    /* last last was not complete */
-    if (rLen)   {
-        /* save the byte & read byte */
         switch (p_type) {
-            case POINTER:
-                emitcode ("mov","b,a");
-                emitcode("mov","a,@%s",rname);
-                break;
 
-            case FPOINTER:
-                emitcode ("mov","b,a");
-                emitcode("movx","a,@dptr");
+        case POINTER:
+        case IPOINTER:
+        case PPOINTER:
+        case FPOINTER:
+                emitcode ("st", "%s,r24", rname);
                 break;
 
-            case GPOINTER:
-                emitcode ("push","b");
-                emitcode ("push","acc");
-                emitcode ("lcall","__gptrget");
-                emitcode ("pop","b");
+        case GPOINTER:
+                emitcode ("mov","r0,r24");
+                emitcode ("call", "__gptrput");
                 break;
         }
-
-        emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
-        emitcode ("orl","a,b");
-    }
-
-    if (p_type == GPOINTER)
-        emitcode("pop","b");
-
-    switch (p_type) {
-
-    case POINTER:
-       emitcode("mov","@%s,a",rname);
-       break;
-       
-    case FPOINTER:
-       emitcode("movx","@dptr,a");
-       break;
-       
-    case GPOINTER:
-       emitcode("lcall","__gptrput");
-       break;                  
-    }
 }
+
 /*-----------------------------------------------------------------*/
 /* genDataPointerSet - remat pointer to data space                 */
 /*-----------------------------------------------------------------*/
-static void genDataPointerSet(operand *right,
-                             operand *result,
-                             iCode *ic)
+static void
+genDataPointerSet (operand * right, operand * result, iCode * ic)
 {
-    int size, offset = 0 ;
-    char *l, buffer[256];
-
-    aopOp(right,ic,FALSE);
-    
-    l = aopGet(AOP(result),0,FALSE,TRUE);
-    size = AOP_SIZE(right);
-    while (size--) {
-       if (offset)
-           sprintf(buffer,"(%s + %d)",l+1,offset);
-       else
-           sprintf(buffer,"%s",l+1);
-       emitcode("mov","%s,%s",buffer,
-                aopGet(AOP(right),offset++,FALSE,FALSE));
-    }
+        int size, offset = 0;
+        char *l, buffer[256];
+
+        aopOp (right, ic, FALSE);
+
+        l = aopGet (AOP (result), 0);
+        size = AOP_SIZE (right);
+        while (size--) {
+                if (offset)
+                        sprintf (buffer, "(%s + %d)", l, offset);
+                else
+                        sprintf (buffer, "%s", l);
+                emitcode ("sts", "%s,%s", buffer,
+                          aopGet (AOP (right), offset++));
+        }
 
-    freeAsmop(right,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genNearPointerSet - emitcode for near pointer put                */
+/* genNearPointerSet - emitcode for near pointer put               */
 /*-----------------------------------------------------------------*/
-static void genNearPointerSet (operand *right,
-                               operand *result, 
-                               iCode *ic)
+static void
+genMemPointerSet (operand * right, operand * result, iCode * ic, iCode *pi)
 {
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname , *l;
-    link *retype;
-    link *ptype = operandType(result);
-    
-    retype= getSpec(operandType(right));
-
-    aopOp(result,ic,FALSE);
-    
-    /* if the result is rematerializable &
-       in data space & not a bit variable */
-    if (AOP_TYPE(result) == AOP_IMMD &&
-       DCL_TYPE(ptype) == POINTER   &&
-       !IS_BITVAR(retype)) {
-       genDataPointerSet (right,result,ic);
-       return;
-    }
-
-    /* if the value is already in a pointer register
-    then don't need anything more */
-    if (!AOP_INPREG(AOP(result))) {
-        /* otherwise get a free pointer register */
-        aop = newAsmop(0);
-        preg = getFreePtr(ic,&aop,FALSE);
-        emitcode("mov","%s,%s",
-                 preg->name,
-                 aopGet(AOP(result),0,FALSE,TRUE));
-        rname = preg->name ;
-    } else
-        rname = aopGet(AOP(result),0,FALSE,FALSE);
-
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp (right,ic,FALSE);
-
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-        genPackBits (retype,right,rname,POINTER);
-    else {
-        /* we have can just get the values */
-        int size = AOP_SIZE(right);
-        int offset = 0 ;    
-
-        while (size--) {
-            l = aopGet(AOP(right),offset,FALSE,TRUE);
-            if (*l == '@' ) {
-                MOVA(l);
-                emitcode("mov","@%s,a",rname);
-            } else
-                emitcode("mov","@%s,%s",rname,l);
-            if (size)
-                emitcode("inc","%s",rname);
-            offset++;
+        asmop *aop = NULL;
+        char *frname = NULL, *rname, *l;
+        int gotFreePtr = 0;
+        sym_link *retype;
+        sym_link *ptype = operandType (result);
+
+        retype = getSpec (operandType (right));
+
+        aopOp (result, ic, FALSE);
+
+        /* if the result is rematerializable &
+           in data space & not a bit variable */
+        if (AOP_TYPE (result) == AOP_IMMD &&
+            DCL_TYPE (ptype) == POINTER && !IS_BITVAR (retype)) {
+                genDataPointerSet (right, result, ic);
+                return;
+        }
+        if (!AOP_INPREG(AOP(result))) {
+                /* otherwise get a free pointer register */
+                aop = newAsmop (0);
+                getFreePtr (ic, &aop, FALSE, 0);
+                if (isRegPair (AOP (result) )) {
+                        emitcode ("movw", "%s,%s",aop->aopu.aop_ptr->name,
+                                  aopGet(AOP (result), 0));
+                } else {
+                        emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+                                  aopGet (AOP (result), 0));
+                        emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+                                  aopGet (AOP (result), 1));
+                }
+                gotFreePtr = 1;
+        } else {
+                aop = AOP(result);
+                frname = aopGet(aop,0);
         }
-    }
 
-    /* now some housekeeping stuff */
-    if (aop) {
-        /* we had to allocate for this iCode */
-        freeAsmop(NULL,aop,ic,TRUE);
-    } else { 
-        /* we did not allocate which means left
-        already in a pointer register, then
-        if size > 0 && this could be used again
-        we have to point it back to where it 
-        belongs */
-        if (AOP_SIZE(right) > 1 &&
-            !OP_SYMBOL(result)->remat &&
-            ( OP_SYMBOL(result)->liveTo > ic->seq ||
-              ic->depth )) {
-            int size = AOP_SIZE(right) - 1;
-            while (size--)
-                emitcode("dec","%s",rname);
+        aopOp (right, ic, FALSE);
+        if (AOP_ISX(aop)) {
+                rname = "X";
+        } else if (AOP_ISZ(aop)) {
+                rname = "Z";
+        } else {
+                werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                        "pointer not in correct register");
+                exit (0);
+        }
+        /* if bitfield then unpack the bits */
+        if (IS_BITVAR (retype))
+                genPackBits (retype, right, rname, POINTER);
+        else {
+                /* we have can just get the values */
+                int size = AOP_SIZE (right);
+                int offset = 0;
+
+                while (size--) {
+                        l = aopGet (AOP (right), offset);
+                        if (size || pi)
+                                emitcode ("st", "%s+,%s", rname,l);
+                        else
+                                emitcode ("st", "%s,%s", rname,l);
+                        offset++;
+                }
         }
-    }
 
-    /* done */
-    freeAsmop(right,NULL,ic,TRUE);
+        /* now some housekeeping stuff */
+        if (gotFreePtr) {
+                /* we had to allocate for this iCode */
+                if (pi) {
+                        if (isRegPair (AOP (result) )) {
+                                emitcode ("movw", "%s,%s",
+                                          aopGet(AOP(result),0),
+                                          aop->aopu.aop_ptr->name);
+                        } else {
+                                emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+                                          aopGet (AOP (result), 0));
+                                emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+                                          aopGet (AOP (result), 1));
+                        }
+                }
+                freeAsmop (NULL, aop, ic, TRUE);
+        } else {
 
+                /* we did not allocate which means left
+                   already in a pointer register, then
+                   if size > 0 && this could be used again
+                   we have to point it back to where it
+                   belongs */
+                if ((AOP_SIZE (right) > 1 &&
+                     !OP_SYMBOL (result)->remat &&
+                     (OP_SYMBOL (right)->liveTo > ic->seq || ic->depth)) && !pi) {
+                        int size = AOP_SIZE (right) - 1;
+                        emitcode ("sbiw", "%s,%d",frname,size);
+                }
+        }
 
+        /* done */
+        if (pi) pi->generated = 1;
+        freeAsmop (result, NULL, ic, TRUE);
+        freeAsmop (right, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genPagedPointerSet - emitcode for Paged pointer put             */
+/* genGenPointerSet - set value from generic pointer space         */
 /*-----------------------------------------------------------------*/
-static void genPagedPointerSet (operand *right,
-                              operand *result, 
-                              iCode *ic)
+static void
+genGenPointerSet (operand * right, operand * result, iCode * ic, iCode *pi)
 {
-    asmop *aop = NULL;
-    regs *preg = NULL ;
-    char *rname , *l;
-    link *retype;
-       
-    retype= getSpec(operandType(right));
-    
-    aopOp(result,ic,FALSE);
-    
-    /* if the value is already in a pointer register
-       then don't need anything more */
-    if (!AOP_INPREG(AOP(result))) {
-       /* otherwise get a free pointer register */
-       aop = newAsmop(0);
-       preg = getFreePtr(ic,&aop,FALSE);
-       emitcode("mov","%s,%s",
-               preg->name,
-               aopGet(AOP(result),0,FALSE,TRUE));
-       rname = preg->name ;
-    } else
-       rname = aopGet(AOP(result),0,FALSE,FALSE);
-    
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp (right,ic,FALSE);
-
-    /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genPackBits (retype,right,rname,PPOINTER);
-    else {
-       /* we have can just get the values */
-       int size = AOP_SIZE(right);
-       int offset = 0 ;        
-       
-       while (size--) {
-           l = aopGet(AOP(right),offset,FALSE,TRUE);
-           
-           MOVA(l);
-           emitcode("movx","@%s,a",rname);
-
-           if (size)
-               emitcode("inc","%s",rname);
-
-           offset++;
-       }
-    }
-    
-    /* now some housekeeping stuff */
-    if (aop) {
-       /* we had to allocate for this iCode */
-       freeAsmop(NULL,aop,ic,TRUE);
-    } else { 
-       /* we did not allocate which means left
-          already in a pointer register, then
-          if size > 0 && this could be used again
-          we have to point it back to where it 
-          belongs */
-       if (AOP_SIZE(right) > 1 &&
-           !OP_SYMBOL(result)->remat &&
-           ( OP_SYMBOL(result)->liveTo > ic->seq ||
-             ic->depth )) {
-           int size = AOP_SIZE(right) - 1;
-           while (size--)
-               emitcode("dec","%s",rname);
-       }
-    }
+        int size, offset;
+        int gotFreePtr = 0;
+        sym_link *retype = getSpec (operandType (right));
+        asmop *aop = NULL;
 
-    /* done */
-    freeAsmop(right,NULL,ic,TRUE);
-    
-       
-}
+        aopOp (result, ic, FALSE);
 
-/*-----------------------------------------------------------------*/
-/* genFarPointerSet - set value from far space                     */
-/*-----------------------------------------------------------------*/
-static void genFarPointerSet (operand *right,
-                              operand *result, iCode *ic)
-{
-    int size, offset ;
-    link *retype = getSpec(operandType(right));
-
-    aopOp(result,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(result) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(result) == AOP_IMMD)
-            emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
-        else { /* we need to get it byte by byte */
-            emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
-            emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
-            }
+        /* if the operand is already in dptr
+           then we do nothing else we move the value to dptr */
+        if (AOP_ISZ(AOP(result))) {
+                aop = AOP(right);
+        } else {
+                aop = newAsmop(0);
+                getFreePtr(ic,&aop,FALSE,TRUE);
+                if (isRegPair(AOP(result))) {
+                        emitcode ("movw", "r30,%s", aopGet (AOP (result), 0));
+                } else {
+                        emitcode ("mov", "r30,%s", aopGet (AOP (result), 0));
+                        emitcode ("mov", "r31,%s", aopGet (AOP (result), 1));
+                }
+                emitcode ("mov", "r24,%s",  aopGet (AOP (result), 2));
+                gotFreePtr=1;
         }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp(right,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",FPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
+        /* so Z register now contains the address */
+        aopOp (right, ic, FALSE);
 
-        while (size--) {
-            char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
-            MOVA(l);
-            emitcode("movx","@dptr,a");
-            if (size)
-                emitcode("inc","dptr");
-        }
-    }
+        /* if bit then unpack */
+        if (IS_BITVAR (retype))
+                genUnpackBits (result, "Z", GPOINTER);
+        else {
+                size = AOP_SIZE (right);
+                offset = 0;
 
-    freeAsmop(right,NULL,ic,TRUE);
-}
+                while (size--) {
+                        char *l = aopGet(AOP (right), offset++);
+                        MOVR0(l);
 
-/*-----------------------------------------------------------------*/
-/* genGenPointerSet - set value from generic pointer space         */
-/*-----------------------------------------------------------------*/
-static void genGenPointerSet (operand *right,
-                              operand *result, iCode *ic)
-{
-    int size, offset ;
-    link *retype = getSpec(operandType(right));
-
-    aopOp(result,ic,FALSE);
-
-    /* if the operand is already in dptr 
-    then we do nothing else we move the value to dptr */
-    if (AOP_TYPE(result) != AOP_STR) {
-        /* if this is remateriazable */
-        if (AOP_TYPE(result) == AOP_IMMD) {
-            emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
-            emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
-        }
-        else { /* we need to get it byte by byte */
-            emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
-            emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
-               emitcode("mov","b,%s",aopGet(AOP(result),3,FALSE,FALSE));
-            }
-            else
-            {
-               emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
-            }
+                        if (size || pi)
+                                emitcode ("call", "__gptrput_pi");
+                        else
+                                emitcode ("call", "__gptrput");
+                }
         }
-    }
-    /* so dptr know contains the address */
-    freeAsmop(result,NULL,ic,TRUE);
-    aopOp(right,ic,FALSE);
 
-    /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",GPOINTER);
-    else {
-        size = AOP_SIZE(right);
-        offset = 0 ;
+        /* now some housekeeping stuff */
+        if (gotFreePtr) {
+                /* we had to allocate for this iCode */
+                if (pi) {
+                        if (isRegPair(AOP(result))) {
+                                emitcode ("movw", "%s,r30", aopGet (AOP (result), 0));
+                        } else {
+                                emitcode ("mov", "%s,r30", aopGet (AOP (result), 0));
+                                emitcode ("mov", "%s,r31", aopGet (AOP (result), 1));
+                        }
+                }
+                freeAsmop (NULL, aop, ic, TRUE);
+        } else {
 
-        while (size--) {
-            char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
-            MOVA(l);
-            emitcode("lcall","__gptrput");
-            if (size)
-                emitcode("inc","dptr");
+                /* we did not allocate which means left
+                   already in a pointer register, then
+                   if size > 0 && this could be used again
+                   we have to point it back to where it
+                   belongs */
+                if ((AOP_SIZE (right) > 1 &&
+                     !OP_SYMBOL (result)->remat &&
+                     (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) && !pi) {
+                        int size = AOP_SIZE (right) - 1;
+                        emitcode ("sbiw", "r30,%d",size);
+                }
         }
-    }
-
-    freeAsmop(right,NULL,ic,TRUE);
+        if (pi) pi->generated = 1;
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
 /* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
-static void genPointerSet (iCode *ic)
-{    
-    operand *right, *result ;
-    link *type, *etype;
-    int p_type;
-
-    right = IC_RIGHT(ic);
-    result = IC_RESULT(ic) ;
-
-    /* depending on the type of pointer we need to
-    move it to the correct pointer register */
-    type = operandType(result);
-    etype = getSpec(type);
-    /* if left is of type of pointer then it is simple */
-    if (IS_PTR(type) && !IS_FUNC(type->next)) {
-        p_type = DCL_TYPE(type);
-    }
-    else {
-       /* we have to go by the storage class */
-       p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/*     if (SPEC_OCLS(etype)->codesp ) { */
-/*         p_type = CPOINTER ;  */
-/*     } */
-/*     else */
-/*         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*             p_type = FPOINTER ; */
-/*         else */
-/*             if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*                 p_type = PPOINTER ; */
-/*             else */
-/*                 if (SPEC_OCLS(etype) == idata ) */
-/*                     p_type = IPOINTER ; */
-/*                 else */
-/*                     p_type = POINTER ; */
-    }
+static void
+genPointerSet (iCode * ic, iCode *pi)
+{
+        operand *right, *result;
+        sym_link *type, *etype;
+        int p_type;
+
+        right = IC_RIGHT (ic);
+        result = IC_RESULT (ic);
+
+        /* depending on the type of pointer we need to
+           move it to the correct pointer register */
+        type = operandType (result);
+        etype = getSpec (type);
+        /* if left is of type of pointer then it is simple */
+        if (IS_PTR (type) && !IS_FUNC (type->next)) {
+                p_type = DCL_TYPE (type);
+        }
+        else {
+                /* we have to go by the storage class */
+                p_type = PTR_TYPE (SPEC_OCLS (etype));
 
-    /* now that we have the pointer type we assign
-    the pointer values */
-    switch (p_type) {
+        }
 
-    case POINTER:
-    case IPOINTER:
-       genNearPointerSet (right,result,ic);
-       break;
+        /* now that we have the pointer type we assign
+           the pointer values */
+        switch (p_type) {
 
-    case PPOINTER:
-       genPagedPointerSet (right,result,ic);
-       break;
+        case POINTER:
+        case IPOINTER:
+        case PPOINTER:
+        case FPOINTER:
+                genMemPointerSet (right, result, ic, pi);
+                break;
 
-    case FPOINTER:
-       genFarPointerSet (right,result,ic);
-       break;
+        case GPOINTER:
+                genGenPointerSet (right, result, ic, pi);
+                break;
 
-    case GPOINTER:
-       genGenPointerSet (right,result,ic);
-       break;
-    }
+        default:
+          werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                  "genPointerSet: illegal pointer type");
+        }
 
 }
 
 /*-----------------------------------------------------------------*/
 /* genIfx - generate code for Ifx statement                        */
 /*-----------------------------------------------------------------*/
-static void genIfx (iCode *ic, iCode *popIc)
+static void
+genIfx (iCode * ic, iCode * popIc)
 {
-    operand *cond = IC_COND(ic);
-    int isbit =0;
-
-    aopOp(cond,ic,FALSE);
-
-    /* get the value into acc */
-    if (AOP_TYPE(cond) != AOP_CRY)
-        toBoolean(cond);
-    else
-        isbit = 1;
-    /* the result is now in the accumulator */
-    freeAsmop(cond,NULL,ic,TRUE);
-
-    /* if there was something to be popped then do it */
-    if (popIc)
-        genIpop(popIc);
-
-    /* if the condition is  a bit variable */
-    if (isbit && IS_ITEMP(cond) && 
-       SPIL_LOC(cond))
-       genIfxJump(ic,SPIL_LOC(cond)->rname);
-    else
-       if (isbit && !IS_ITEMP(cond))
-           genIfxJump(ic,OP_SYMBOL(cond)->rname);
-       else
-           genIfxJump(ic,"a");
-
-    ic->generated = 1;
+        operand *cond = IC_COND (ic);
+        char *cname ;
+        symbol *lbl;
+        int tob = 0;
+
+        aopOp (cond, ic, FALSE);
+
+        /* get the value into acc */
+        if (AOP_SIZE(cond) == 1 && AOP_ISHIGHREG(AOP(cond),0)) {
+                cname = aopGet(AOP(cond),0);
+        } else {
+                toBoolean (cond, "r24", 0);
+                tob = 1;
+                cname = "r24";
+        }
+        /* the result is now in the accumulator */
+        freeAsmop (cond, NULL, ic, TRUE);
+
+        /* if there was something to be popped then do it */
+        if (popIc) {
+                genIpop (popIc);
+                emitcode("cpi","%s,0",cname);
+        } else if (!tob) emitcode("cpi","%s,0",cname);
+
+        lbl = newiTempLabel(NULL);
+        if (IC_TRUE(ic)) {
+                emitcode ("breq","L%05d",lbl->key);
+                emitcode ("jmp","L%05d",IC_TRUE(ic)->key);
+                emitcode ("","L%05d:",lbl->key);
+        } else {
+                emitcode ("brne","L%05d",lbl->key);
+                emitcode ("jmp","L%05d",IC_FALSE(ic)->key);
+                emitcode ("","L%05d:",lbl->key);
+        }
+        ic->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* genAddrOf - generates code for address of                       */
 /*-----------------------------------------------------------------*/
-static void genAddrOf (iCode *ic)
+static void
+genAddrOf (iCode * ic)
 {
-    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
-    int size, offset ;
-
-    aopOp(IC_RESULT(ic),ic,FALSE);
+        symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+        int size, offset;
+
+        aopOp (IC_RESULT (ic), ic, FALSE);
+        assert(AOP_SIZE(IC_RESULT(ic)) >= 2);
+        /* if the operand is on the stack then we
+           need to get the stack offset of this
+           variable */
+        if (sym->onStack) {
+                /* if it has an offset then we need to compute it */
+                if (sym->stack) {
+                        if (allHigh(AOP(IC_RESULT(ic)))) {
+                                if (isRegPair (AOP(IC_RESULT(ic)))) {
+                                        emitcode ("movw","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
+                                } else {
+                                        emitcode ("mov","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
+                                        emitcode ("mov","%s,r29",aopGet(AOP(IC_RESULT(ic)),1));
+                                }
+                                if (sym->stack < 0) {
+                                        emitcode("subi","%s,<(%d)",aopGet(AOP(IC_RESULT(ic)),0),-sym->stack);
+                                        emitcode("sbci","%s,>(%d)",aopGet(AOP(IC_RESULT(ic)),1),-sym->stack);
+                                } else {
+                                        emitcode("subi","%s,<(-%d)",aopGet(AOP(IC_RESULT(ic)),0),sym->stack);
+                                        emitcode("sbci","%s,>(-%d)",aopGet(AOP(IC_RESULT(ic)),1),sym->stack);
+                                }
+                        } else {
+                                emitcode("movw","r24,r28");
+                                if (sym->stack > -63 && sym->stack < 63) {
+                                        if (sym->stack < 0)
+                                                emitcode("sbiw","r24,%d",-sym->stack);
+                                        else
+                                                emitcode("sbiw","r24,%d",sym->stack);
+                                } else {
+                                        if (sym->stack < 0) {
+                                                emitcode("subi","r24,<(%d)",-sym->stack);
+                                                emitcode("sbci","r25,>(%d)",-sym->stack);
+                                        } else {
+                                                emitcode("subi","r24,<(-%d)",sym->stack);
+                                                emitcode("sbci","r25,>(-%d)",sym->stack);
+                                        }
+                                }
+
+                                aopPut(AOP(IC_RESULT(ic)),"r24",0);
+                                aopPut(AOP(IC_RESULT(ic)),"r25",1);
+                        }
+                }
+                else {
+                        aopPut(AOP(IC_RESULT(ic)),"r28",0);
+                        aopPut(AOP(IC_RESULT(ic)),"r29",1);
+                }
+                /* fill the result with zero */
+                size = AOP_SIZE (IC_RESULT (ic)) - 2;
+                offset = 2;
+                while (size--) {
+                        aopPut (AOP (IC_RESULT (ic)), zero, offset++);
+                }
 
-    /* if the operand is on the stack then we 
-    need to get the stack offset of this
-    variable */
-    if (sym->onStack) {
-        /* if it has an offset then we need to compute
-        it */
-        if (sym->stack) {
-            emitcode("mov","a,_bp");
-            emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
-            aopPut(AOP(IC_RESULT(ic)),"a",0);       
-        } else {
-            /* we can just move _bp */
-            aopPut(AOP(IC_RESULT(ic)),"_bp",0);
-        }
-        /* fill the result with zero */
-        size = AOP_SIZE(IC_RESULT(ic)) - 1;
-        
-        
-        if (options.stack10bit && size < (FPTRSIZE - 1))
-        {
-            fprintf(stderr, 
-                   "*** warning: pointer to stack var truncated.\n");
-        }
-        
-        offset = 1;
-        while (size--)
-        {
-            /* Yuck! */
-            if (options.stack10bit && offset == 2)
-            {
-                aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
-            }
-            else
-            {
-               aopPut(AOP(IC_RESULT(ic)),zero,offset++);
-            }
+                goto release;
         }
 
-        goto release;
-    }
-
-    /* object not on stack then we need the name */
-    size = AOP_SIZE(IC_RESULT(ic));
-    offset = 0;
-
-    while (size--) {
-        char s[SDCC_NAME_MAX];
-        if (offset) 
-            sprintf(s,"#(%s >> %d)",
-                    sym->rname,
-                    offset*8);
-        else
-            sprintf(s,"#%s",sym->rname);
-        aopPut(AOP(IC_RESULT(ic)),s,offset++);
-    }
+        /* object not on stack then we need the name */
+        size = AOP_SIZE (IC_RESULT (ic));
+        offset = 0;
+        assert(size<=2);
+        while (size--) {
+                char s[SDCC_NAME_MAX];
+                if (offset)
+                        sprintf (s, ">(%s)", sym->rname);
+                else
+                        sprintf (s, "<(%s)", sym->rname);
+                aopPut (AOP (IC_RESULT (ic)), s, offset++);
+        }
 
-release:
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+      release:
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 
 }
 
 /*-----------------------------------------------------------------*/
 /* genFarFarAssign - assignment when both are in far space         */
 /*-----------------------------------------------------------------*/
-static void genFarFarAssign (operand *result, operand *right, iCode *ic)
+static void
+genFarFarAssign (operand * result, operand * right, iCode * ic)
 {
-    int size = AOP_SIZE(right);
-    int offset = 0;
-    char *l ;
-    /* first push the right side on to the stack */
-    while (size--) {
-       l = aopGet(AOP(right),offset++,FALSE,FALSE);
-       MOVA(l);
-       emitcode ("push","acc");
-    }
-    
-    freeAsmop(right,NULL,ic,FALSE);
-    /* now assign DPTR to result */
-    aopOp(result,ic,FALSE);
-    size = AOP_SIZE(result);
-    while (size--) {
-       emitcode ("pop","acc");
-       aopPut(AOP(result),"a",--offset);
-    }
-    freeAsmop(result,NULL,ic,FALSE);
-       
+        int size = AOP_SIZE (right);
+        int offset = 0;
+        char *l;
+        /* first push the right side on to the stack */
+        while (size--) {
+                l = aopGet (AOP (right), offset++);
+                MOVA (l);
+                emitcode ("push", "acc");
+        }
+
+        freeAsmop (right, NULL, ic, FALSE);
+        /* now assign DPTR to result */
+        aopOp (result, ic, FALSE);
+        size = AOP_SIZE (result);
+        while (size--) {
+                emitcode ("pop", "acc");
+                aopPut (AOP (result), "a", --offset);
+        }
+        freeAsmop (result, NULL, ic, FALSE);
+
 }
 
 /*-----------------------------------------------------------------*/
 /* genAssign - generate code for assignment                        */
 /*-----------------------------------------------------------------*/
-static void genAssign (iCode *ic)
+static void
+genAssign (iCode * ic)
 {
-    operand *result, *right;
-    int size, offset ;
-       unsigned long lit = 0L;
-
-    result = IC_RESULT(ic);
-    right  = IC_RIGHT(ic) ;
-
-    /* if they are the same */
-    if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
-        return ;
-
-    aopOp(right,ic,FALSE);
-    
-    /* special case both in far space */
-    if ((AOP_TYPE(right) == AOP_DPTR ||
-         AOP_TYPE(right) == AOP_DPTR2) &&
-       IS_TRUE_SYMOP(result)       &&
-       isOperandInFarSpace(result)) {
-       
-       genFarFarAssign (result,right,ic);
-       return ;
-    }
+        operand *result, *right;
+        int size, offset;
+        unsigned long lit = 0L;
+
+        result = IC_RESULT (ic);
+        right = IC_RIGHT (ic);
 
-    aopOp(result,ic,TRUE);
+        /* if they are the same */
+        if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+                return;
 
-    /* if they are the same registers */
-    if (sameRegs(AOP(right),AOP(result)))
-        goto release;
+        aopOp (right, ic, FALSE);
 
-    /* if the result is a bit */
-    if (AOP_TYPE(result) == AOP_CRY) {
+        /* special case both in far space */
+        if (AOP_TYPE (right) == AOP_DPTR &&
+            IS_TRUE_SYMOP (result) && isOperandInFarSpace (result)) {
 
-        /* if the right size is a literal then
-        we know what the value is */
-        if (AOP_TYPE(right) == AOP_LIT) {
-            if (((int) operandLitValue(right))) 
-                aopPut(AOP(result),one,0);
-            else
-                aopPut(AOP(result),zero,0);
-            goto release;
+                genFarFarAssign (result, right, ic);
+                return;
         }
 
-        /* the right is also a bit variable */
-        if (AOP_TYPE(right) == AOP_CRY) {
-            emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-            aopPut(AOP(result),"c",0);
-            goto release ;
+        aopOp (result, ic, TRUE);
+
+        /* if they are the same registers */
+        if (sameRegs (AOP (right), AOP (result)))
+                goto release;
+
+        /* if the result is a bit */
+        if (AOP_TYPE (result) == AOP_CRY) {
+
+                /* if the right size is a literal then
+                   we know what the value is */
+                if (AOP_TYPE (right) == AOP_LIT) {
+                        if (((int) operandLitValue (right)))
+                                aopPut (AOP (result), one, 0);
+                        else
+                                aopPut (AOP (result), zero, 0);
+                        goto release;
+                }
+
+                /* the right is also a bit variable */
+                if (AOP_TYPE (right) == AOP_CRY) {
+                        emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+                        aopPut (AOP (result), "c", 0);
+                        goto release;
+                }
+
+                /* we need to or */
+                toBoolean (right, "", 0);
+                aopPut (AOP (result), "a", 0);
+                goto release;
         }
 
-        /* we need to or */
-        toBoolean(right);
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
+        /* bit variables done */
+        /* general case */
+        size = AOP_SIZE (result);
+        offset = 0;
+        if (AOP_TYPE (right) == AOP_LIT)
+                lit = ulFromVal (AOP (right)->aopu.
+                                                      aop_lit);
+        if ((size > 1) && (AOP_TYPE (result) != AOP_REG)
+            && (AOP_TYPE (right) == AOP_LIT)
+            && !IS_FLOAT (operandType (right)) && (lit < 256L)) {
+                emitcode ("clr", "a");
+                while (size--) {
+                        if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) ==
+                            0) aopPut (AOP (result), "a", size);
+                        else
+                                aopPut (AOP (result),
+                                        aopGet (AOP (right), size), size);
+                }
+        }
+        else {
+                while (size--) {
+                        aopPut (AOP (result),
+                                aopGet (AOP (right), offset), offset);
+                        offset++;
+                }
+        }
 
-    /* bit variables done */
-    /* general case */
-    size = AOP_SIZE(result);
-    offset = 0 ;
-    if(AOP_TYPE(right) == AOP_LIT)
-       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-    if((size > 1) &&
-       (AOP_TYPE(result) != AOP_REG) &&
-       (AOP_TYPE(right) == AOP_LIT) &&
-       !IS_FLOAT(operandType(right)) &&
-       (lit < 256L)){
-       emitcode("clr","a");
-       while (size--) {
-           if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0)
-               aopPut(AOP(result),"a",size);
-           else
-               aopPut(AOP(result),
-                      aopGet(AOP(right),size,FALSE,FALSE),
-                      size);
-       }
-    } else {
-       while (size--) {
-           aopPut(AOP(result),
-                  aopGet(AOP(right),offset,FALSE,FALSE),
-                  offset);
-           offset++;
-       }
-    }
-    
-release:
-    freeAsmop (right,NULL,ic,FALSE);
-    freeAsmop (result,NULL,ic,TRUE);
-}   
+      release:
+        freeAsmop (right, NULL, ic, FALSE);
+        freeAsmop (result, NULL, ic, TRUE);
+}
 
 /*-----------------------------------------------------------------*/
 /* genJumpTab - genrates code for jump table                       */
 /*-----------------------------------------------------------------*/
-static void genJumpTab (iCode *ic)
+static void
+genJumpTab (iCode * ic)
 {
-    symbol *jtab;
-    char *l;
-
-    aopOp(IC_JTCOND(ic),ic,FALSE);
-    /* get the condition into accumulator */
-    l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
-    MOVA(l);
-    /* multiply by three */
-    emitcode("add","a,acc");
-    emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
-    freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
-
-    jtab = newiTempLabel(NULL);
-    emitcode("mov","dptr,#%05d$",jtab->key+100);
-    emitcode("jmp","@a+dptr");
-    emitcode("","%05d$:",jtab->key+100);
-    /* now generate the jump labels */
-    for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
-         jtab = setNextItem(IC_JTLABELS(ic)))
-        emitcode("ljmp","%05d$",jtab->key+100);
+        symbol *jtab;
+        char *l;
+
+        aopOp (IC_JTCOND (ic), ic, FALSE);
+        /* get the condition into accumulator */
+        l = aopGet (AOP (IC_JTCOND (ic)), 0);
+        MOVA (l);
+        /* multiply by three */
+        emitcode ("add", "a,acc");
+        emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0));
+        freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+
+        jtab = newiTempLabel (NULL);
+        emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
+        emitcode ("jmp", "@a+dptr");
+        emitcode ("", "%05d$:", jtab->key + 100);
+        /* now generate the jump labels */
+        for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
+             jtab = setNextItem (IC_JTLABELS (ic)))
+                emitcode ("ljmp", "%05d$", jtab->key + 100);
 
 }
 
 /*-----------------------------------------------------------------*/
 /* genCast - gen code for casting                                  */
 /*-----------------------------------------------------------------*/
-static void genCast (iCode *ic)
+static void
+genCast (iCode * ic)
 {
-    operand *result = IC_RESULT(ic);
-    link *ctype = operandType(IC_LEFT(ic));
-    link *rtype = operandType(IC_RIGHT(ic));
-    operand *right = IC_RIGHT(ic);
-    int size, offset ;
-
-    /* if they are equivalent then do nothing */
-    if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
-        return ;
-
-    aopOp(right,ic,FALSE) ;
-    aopOp(result,ic,FALSE);
-
-    /* if the result is a bit */
-    if (AOP_TYPE(result) == AOP_CRY) {
-        /* if the right size is a literal then
-        we know what the value is */
-        if (AOP_TYPE(right) == AOP_LIT) {
-            if (((int) operandLitValue(right))) 
-                aopPut(AOP(result),one,0);
-            else
-                aopPut(AOP(result),zero,0);
-
-            goto release;
-        }
-
-        /* the right is also a bit variable */
-        if (AOP_TYPE(right) == AOP_CRY) {
-            emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-            aopPut(AOP(result),"c",0);
-            goto release ;
-        }
-
-        /* we need to or */
-        toBoolean(right);
-        aopPut(AOP(result),"a",0);
-        goto release ;
-    }
+        operand *result = IC_RESULT (ic);
+        sym_link *ctype = operandType (IC_LEFT (ic));
+        sym_link *rtype = operandType (IC_RIGHT (ic));
+        operand *right = IC_RIGHT (ic);
+        int size, offset;
+
+        /* if they are equivalent then do nothing */
+        if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+                return;
+
+        aopOp (right, ic, FALSE);
+        aopOp (result, ic, FALSE);
+
+        /* if the result is a bit */
+        if (AOP_TYPE (result) == AOP_CRY) {
+                /* if the right size is a literal then
+                   we know what the value is */
+                if (AOP_TYPE (right) == AOP_LIT) {
+                        if (((int) operandLitValue (right)))
+                                aopPut (AOP (result), one, 0);
+                        else
+                                aopPut (AOP (result), zero, 0);
 
-    /* if they are the same size : or less */
-    if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+                        goto release;
+                }
 
-        /* if they are in the same place */
-        if (sameRegs(AOP(right),AOP(result)))
-            goto release;
+                /* the right is also a bit variable */
+                if (AOP_TYPE (right) == AOP_CRY) {
+                        emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+                        aopPut (AOP (result), "c", 0);
+                        goto release;
+                }
 
-        /* if they in different places then copy */
-        size = AOP_SIZE(result);
-        offset = 0 ;
-        while (size--) {
-            aopPut(AOP(result),
-                   aopGet(AOP(right),offset,FALSE,FALSE),
-                   offset);
-            offset++;
+                /* we need to or */
+                toBoolean (right, "", 0);
+                aopPut (AOP (result), "a", 0);
+                goto release;
         }
-        goto release;
-    }
 
+        /* if they are the same size : or less */
+        if (AOP_SIZE (result) <= AOP_SIZE (right)) {
 
-    /* if the result is of type pointer */
-    if (IS_PTR(ctype)) {
-
-       int p_type;
-       link *type = operandType(right);
-       link *etype = getSpec(type);
-
-       /* pointer to generic pointer */
-       if (IS_GENPTR(ctype)) {
-           char *l = zero;
-           
-           if (IS_PTR(type)) 
-               p_type = DCL_TYPE(type);
-           else {
-               /* we have to go by the storage class */
-               p_type = PTR_TYPE(SPEC_OCLS(etype));
-           }
-               
-           /* the first two bytes are known */
-           size = GPTRSIZE - 1; 
-           offset = 0 ;
-           while (size--) {
-               aopPut(AOP(result),
-                      aopGet(AOP(right),offset,FALSE,FALSE),
-                      offset);
-               offset++;
-           }
-           /* the last byte depending on type */
-           switch (p_type) {
-           case IPOINTER:
-           case POINTER:
-               l = zero;
-               break;
-           case FPOINTER:
-               l = one;
-               break;
-           case CPOINTER:
-               l = "#0x02";
-               break;                          
-           case PPOINTER:
-               l = "#0x03";
-               break;
-               
-           default:
-               /* this should never happen */
-               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                      "got unknown pointer type");
-               exit(1);
-           }
-           aopPut(AOP(result),l, GPTRSIZE - 1);            
-           goto release ;
-       }
-       
-       /* just copy the pointers */
-       size = AOP_SIZE(result);
-       offset = 0 ;
-       while (size--) {
-           aopPut(AOP(result),
-                  aopGet(AOP(right),offset,FALSE,FALSE),
-                  offset);
-           offset++;
-       }
-       goto release ;
-    }
-    
-    /* so we now know that the size of destination is greater
-    than the size of the source */
-    /* we move to result for the size of source */
-    size = AOP_SIZE(right);
-    offset = 0 ;
-    while (size--) {
-        aopPut(AOP(result),
-               aopGet(AOP(right),offset,FALSE,FALSE),
-               offset);
-        offset++;
-    }
+                /* if they are in the same place */
+                if (sameRegs (AOP (right), AOP (result)))
+                        goto release;
 
-    /* now depending on the sign of the source && destination */
-    size = AOP_SIZE(result) - AOP_SIZE(right);
-    /* if unsigned or not an integral type */
-    if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
-        while (size--)
-            aopPut(AOP(result),zero,offset++);
-    } else {
-        /* we need to extend the sign :{ */
-        char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,
-                         FALSE,FALSE);
-        MOVA(l);
-        emitcode("rlc","a");
-        emitcode("subb","a,acc");
-        while (size--)
-            aopPut(AOP(result),"a",offset++);   
-    }
+                /* if they in different places then copy */
+                size = AOP_SIZE (result);
+                offset = 0;
+                while (size--) {
+                        aopPut (AOP (result),
+                                aopGet (AOP (right), offset), offset);
+                        offset++;
+                }
+                goto release;
+        }
+
+
+        /* if the result is of type pointer */
+        if (IS_PTR (ctype)) {
+
+                int p_type;
+                sym_link *type = operandType (right);
+                sym_link *etype = getSpec (type);
+
+                /* pointer to generic pointer */
+                if (IS_GENPTR (ctype)) {
+                        if (IS_PTR (type))
+                                p_type = DCL_TYPE (type);
+                        else {
+                                /* we have to go by the storage class */
+                                p_type = PTR_TYPE (SPEC_OCLS (etype));
+                        }
+
+                        /* the first two bytes are known */
+                        size = GPTRSIZE - 1;
+                        offset = 0;
+                        while (size--) {
+                                aopPut (AOP (result),
+                                        aopGet (AOP (right), offset), offset);
+                                offset++;
+                        }
+
+                    /* the last byte depending on type */
+                    {
+                        int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
+                        char gpValStr[10];
+
+                        if (gpVal == -1)
+                        {
+                            // pointerTypeToGPByte will have bitched.
+                            exit(1);
+                        }
+
+                        sprintf(gpValStr, "#0x%x", gpVal);
+                        aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
+                    }
+                    goto release;
+                }
+
+                /* just copy the pointers */
+                size = AOP_SIZE (result);
+                offset = 0;
+                while (size--) {
+                        aopPut (AOP (result),
+                                aopGet (AOP (right), offset), offset);
+                        offset++;
+                }
+                goto release;
+        }
+
+        /* so we now know that the size of destination is greater
+           than the size of the source */
+        /* we move to result for the size of source */
+        size = AOP_SIZE (right);
+        offset = 0;
+        while (size--) {
+                aopPut (AOP (result), aopGet (AOP (right), offset), offset);
+                offset++;
+        }
+
+        /* now depending on the sign of the source && destination */
+        size = AOP_SIZE (result) - AOP_SIZE (right);
+        /* if unsigned or not an integral type */
+        if (SPEC_USIGN (rtype) || !IS_SPEC (rtype)) {
+                while (size--)
+                        aopPut (AOP (result), zero, offset++);
+        }
+        else {
+                /* we need to extend the sign :{ */
+                // PENDING: Does nothing on avr
+#if 0
+                char *l = aopGet (AOP (right), AOP_SIZE (right) - 1);
+                MOVA (l);
+#endif
+                emitcode ("rlc", "a");
+                emitcode ("subb", "a,acc");
+                while (size--)
+                        aopPut (AOP (result), "a", offset++);
+        }
 
-    /* we are done hurray !!!! */
+        /* we are done hurray !!!! */
 
-release:
-    freeAsmop(right,NULL,ic,TRUE);
-    freeAsmop(result,NULL,ic,TRUE);
+      release:
+        freeAsmop (right, NULL, ic, TRUE);
+        freeAsmop (result, NULL, ic, TRUE);
 
 }
 
 /*-----------------------------------------------------------------*/
 /* genDjnz - generate decrement & jump if not zero instrucion      */
 /*-----------------------------------------------------------------*/
-static int genDjnz (iCode *ic, iCode *ifx)
+static int
+genDjnz (iCode * ic, iCode * ifx)
 {
-    symbol *lbl, *lbl1;
-    if (!ifx)
-       return 0;
-    
-    /* if the if condition has a false label
-       then we cannot save */
-    if (IC_FALSE(ifx))
-       return 0;
-
-    /* if the minus is not of the form 
-       a = a - 1 */
-    if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
-       !IS_OP_LITERAL(IC_RIGHT(ic)))
-       return 0;
-
-    if (operandLitValue(IC_RIGHT(ic)) != 1)
-       return 0;
-
-    /* if the size of this greater than one then no
-       saving */
-    if (getSize(operandType(IC_RESULT(ic))) > 1)
-       return 0;
-
-    /* otherwise we can save BIG */
-    lbl = newiTempLabel(NULL);
-    lbl1= newiTempLabel(NULL);
-
-    aopOp(IC_RESULT(ic),ic,FALSE);
-    
-    if (IS_AOP_PREG(IC_RESULT(ic))) {
-       emitcode("dec","%s",
-                aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-       emitcode("jnz","%05d$",lbl->key+100);
-    } else {   
-       emitcode ("djnz","%s,%05d$",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
-                 lbl->key+100);
-    }
-    emitcode ("sjmp","%05d$",lbl1->key+100);
-    emitcode ("","%05d$:",lbl->key+100);
-    emitcode ("ljmp","%05d$",IC_TRUE(ifx)->key+100);
-    emitcode ("","%05d$:",lbl1->key+100);
-    
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-    ifx->generated = 1;
-    return 1;
+        symbol *lbl, *lbl1;
+        if (!ifx)
+                return 0;
+
+        /* if the if condition has a false label
+           then we cannot save */
+        if (IC_FALSE (ifx))
+                return 0;
+
+        /* if the minus is not of the form
+           a = a - 1 */
+        if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
+            !IS_OP_LITERAL (IC_RIGHT (ic)))
+                return 0;
+
+        if (operandLitValue (IC_RIGHT (ic)) != 1)
+                return 0;
+
+        /* if the size of this greater than one then no
+           saving */
+        if (getSize (operandType (IC_RESULT (ic))) > 1)
+                return 0;
+
+        /* otherwise we can save BIG */
+        lbl = newiTempLabel (NULL);
+        lbl1 = newiTempLabel (NULL);
+
+        aopOp (IC_RESULT (ic), ic, FALSE);
+
+        if (IS_AOP_PREG (IC_RESULT (ic))) {
+                emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0));
+                emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0));
+                emitcode ("jnz", "%05d$", lbl->key + 100);
+        }
+        else {
+                emitcode ("djnz", "%s,%05d$",
+                          aopGet (AOP (IC_RESULT (ic)), 0), lbl->key + 100);
+        }
+        emitcode ("sjmp", "%05d$", lbl1->key + 100);
+        emitcode ("", "%05d$:", lbl->key + 100);
+        emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+        emitcode ("", "%05d$:", lbl1->key + 100);
+
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+        ifx->generated = 1;
+        return 1;
 }
 
+static char *recvregs[8] = {
+        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23"
+};
+
+static int recvCnt = 0;
+
 /*-----------------------------------------------------------------*/
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
-static void genReceive (iCode *ic)
-{    
-    if (isOperandInFarSpace(IC_RESULT(ic)) && 
-       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
-         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
-
-       int size = getSize(operandType(IC_RESULT(ic)));
-       int offset =  fReturnSize - size;
-       while (size--) {
-           emitcode ("push","%s", (strcmp(fReturn[fReturnSize - offset - 1],"a") ?
-                                   fReturn[fReturnSize - offset - 1] : "acc"));
-           offset++;
-       }
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       size = AOP_SIZE(IC_RESULT(ic));
-       offset = 0;
-       while (size--) {
-           emitcode ("pop","acc");
-           aopPut (AOP(IC_RESULT(ic)),"a",offset++);
-       }
-       
-    } else {
-       _G.accInUse++;
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       _G.accInUse--;
-       assignResultValue(IC_RESULT(ic));       
-    }
+static void
+genReceive (iCode * ic)
+{
+        int size, offset = 0;
+        aopOp (IC_RESULT (ic), ic, FALSE);
+        size = AOP_SIZE (IC_RESULT (ic));
+        while (size--) {
+                aopPut (AOP (IC_RESULT (ic)), recvregs[recvCnt++], offset);
+                offset++;
+        }
+        freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  emitcode (";     genDummyRead","");
+  emitcode (";     not implemented","");
 
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+  ic = ic;
 }
 
 /*-----------------------------------------------------------------*/
 /* gen51Code - generate code for 8051 based controllers            */
 /*-----------------------------------------------------------------*/
-void gen51Code (iCode *lic)
+void
+genAVRCode (iCode * lic)
 {
-    iCode *ic;
-    int cln = 0;
-
-    lineHead = lineCurr = NULL;
-
-    /* print the allocation information */
-    if (allocInfo)
-       printAllocInfo( currFunc, codeOutFile);
-    /* if debug information required */
-/*     if (options.debug && currFunc) { */
-    if (currFunc) {
-       cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
-       _G.debugLine = 1;
-       if (IS_STATIC(currFunc->etype))
-           emitcode("","F%s$%s$0$0 ==.",moduleName,currFunc->name); 
-       else
-           emitcode("","G$%s$0$0 ==.",currFunc->name);
-       _G.debugLine = 0;
-    }
-    /* stack pointer name */
-    if (options.useXstack)
-       spname = "_spx";
-    else
-       spname = "sp";
-    
-    for (ic = lic ; ic ; ic = ic->next ) {
-       
-       if ( cln != ic->lineno ) {
-           if ( options.debug ) {
-               _G.debugLine = 1;
-               emitcode("","C$%s$%d$%d$%d ==.",
-                        ic->filename,ic->lineno,
-                        ic->level,ic->block);
-               _G.debugLine = 0;
-           }
-           emitcode(";","%s %d",ic->filename,ic->lineno);
-           cln = ic->lineno ;
-       }
-       /* if the result is marked as
-          spilt and rematerializable or code for
-          this has already been generated then
-          do nothing */
-       if (resultRemat(ic) || ic->generated ) 
-           continue ;
-       
-       /* depending on the operation */
-       switch (ic->op) {
-       case '!' :
-           genNot(ic);
-           break;
-           
-       case '~' :
-           genCpl(ic);
-           break;
-           
-       case UNARYMINUS:
-           genUminus (ic);
-           break;
-           
-       case IPUSH:
-           genIpush (ic);
-           break;
-           
-       case IPOP:
-           /* IPOP happens only when trying to restore a 
-              spilt live range, if there is an ifx statement
-              following this pop then the if statement might
-              be using some of the registers being popped which
-              would destory the contents of the register so
-              we need to check for this condition and handle it */
-           if (ic->next            && 
-               ic->next->op == IFX &&
-               regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
-               genIfx (ic->next,ic);
-           else
-               genIpop (ic);
-           break; 
-           
-       case CALL:
-           genCall (ic);
-           break;
-           
-       case PCALL:
-           genPcall (ic);
-           break;
-           
-       case FUNCTION:
-           genFunction (ic);
-           break;
-           
-       case ENDFUNCTION:
-           genEndFunction (ic);
-           break;
-           
-       case RETURN:
-           genRet (ic);
-           break;
-           
-       case LABEL:
-           genLabel (ic);
-           break;
-           
-       case GOTO:
-           genGoto (ic);
-           break;
-           
-       case '+' :
-           genPlus (ic) ;
-           break;
-           
-       case '-' :
-           if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
-               genMinus (ic);
-           break;
-           
-       case '*' :
-           genMult (ic);
-           break;
-           
-       case '/' :
-           genDiv (ic) ;
-           break;
-           
-       case '%' :
-           genMod (ic);
-           break;
-           
-       case '>' :
-           genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
-           break;
-           
-       case '<' :
-           genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;
-           
-       case LE_OP:
-           genCmpLe (ic,ifxForOp(IC_RESULT(ic),ic));
-           break
-
-       case GE_OP:
-           genCmpGe (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;
-
-       case NE_OP:
-           genCmpNe (ic,ifxForOp(IC_RESULT(ic),ic));       
-           break;      
-           
-       case EQ_OP:
-           genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;          
-           
-       case AND_OP:
-           genAndOp (ic);
-           break;
-           
-       case OR_OP:
-           genOrOp (ic);
-           break;
-           
-       case '^' :
-           genXor (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;
-           
-       case '|' :
-               genOr (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;
-           
-       case BITWISEAND:
-            genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
-           break;
-           
-       case INLINEASM:
-           genInline (ic);
-           break;
-           
-       case RRC:
-           genRRC (ic);
-           break;
-           
-       case RLC:
-           genRLC (ic);
-           break;
-           
-       case GETHBIT:
-           genGetHbit (ic);
-           break;
-           
-       case LEFT_OP:
-           genLeftShift (ic);
-           break;
-           
-       case RIGHT_OP:
-           genRightShift (ic);
-           break;
-           
-       case GET_VALUE_AT_ADDRESS:
-           genPointerGet(ic);
-           break;
-           
-       case '=' :
-           if (POINTER_SET(ic))
-               genPointerSet(ic);
-           else
-               genAssign(ic);
-           break;
-           
-       case IFX:
-           genIfx (ic,NULL);
-           break;
-           
-       case ADDRESS_OF:
-           genAddrOf (ic);
-           break;
-           
-       case JUMPTABLE:
-           genJumpTab (ic);
-           break;
-           
-       case CAST:
-           genCast (ic);
-           break;
-           
-       case RECEIVE:
-           genReceive(ic);
-           break;
-           
-       case SEND:
-           addSet(&_G.sendSet,ic);
-           break;
-
-       default :
-           ic = ic;
-           /*      piCode(ic,stdout); */
-           
+        iCode *ic;
+        int cln = 0;
+
+        lineHead = lineCurr = NULL;
+        recvCnt = 0;
+        /* print the allocation information */
+        if (allocInfo)
+                printAllocInfo (currFunc, codeOutBuf);
+        /* if debug information required */
+        if (options.debug && currFunc) {
+                debugFile->writeFunction (currFunc, lic);
         }
-    }
-    
+        /* stack pointer name */
+        spname = "sp";
 
-    /* now we are ready to call the 
-       peep hole optimizer */
-    if (!options.nopeep)
-       peepHole (&lineHead);
 
-    /* now do the actual printing */
-    printLine (lineHead,codeOutFile);    
-    return;
+        for (ic = lic; ic; ic = ic->next) {
+
+                if (cln != ic->lineno) {
+                        if (options.debug) {
+                                debugFile->writeCLine (ic);
+                        }
+                        emitcode (";", "%s %d", ic->filename, ic->lineno);
+                        cln = ic->lineno;
+                }
+                /* if the result is marked as
+                   spilt and rematerializable or code for
+                   this has already been generated then
+                   do nothing */
+                if (resultRemat (ic) || ic->generated)
+                        continue;
+
+                /* depending on the operation */
+                switch (ic->op) {
+                case '!':
+                        genNot (ic);
+                        break;
+
+                case '~':
+                        genCpl (ic);
+                        break;
+
+                case UNARYMINUS:
+                        genUminus (ic);
+                        break;
+
+                case IPUSH:
+                        genIpush (ic);
+                        break;
+
+                case IPOP:
+                        /* IPOP happens only when trying to restore a
+                           spilt live range, if there is an ifx statement
+                           following this pop then the if statement might
+                           be using some of the registers being popped which
+                           would destory the contents of the register so
+                           we need to check for this condition and handle it */
+                        if (ic->next &&
+                            ic->next->op == IFX &&
+                            regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
+                                genIfx (ic->next, ic);
+                        else
+                                genIpop (ic);
+                        break;
+
+                case CALL:
+                        genCall (ic);
+                        break;
+
+                case PCALL:
+                        genPcall (ic);
+                        break;
+
+                case FUNCTION:
+                        genFunction (ic);
+                        break;
+
+                case ENDFUNCTION:
+                        genEndFunction (ic);
+                        break;
+
+                case RETURN:
+                        genRet (ic);
+                        break;
+
+                case LABEL:
+                        genLabel (ic);
+                        break;
+
+                case GOTO:
+                        genGoto (ic);
+                        break;
+
+                case '+':
+                        genPlus (ic);
+                        break;
+
+                case '-':
+                        if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
+                                genMinus (ic);
+                        break;
+
+                case '*':
+                        genMult (ic);
+                        break;
+
+                case '/':
+                        genDiv (ic);
+                        break;
+
+                case '%':
+                        genMod (ic);
+                        break;
+
+                case '>':
+                        genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case '<':
+                        genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case LE_OP:
+                        genCmpLe (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case GE_OP:
+                        genCmpGe (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case NE_OP:
+                        genCmpNe (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case EQ_OP:
+                        genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case AND_OP:
+                        genAndOp (ic);
+                        break;
+
+                case OR_OP:
+                        genOrOp (ic);
+                        break;
+
+                case '^':
+                        genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case '|':
+                        genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case BITWISEAND:
+                        genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+                        break;
+
+                case INLINEASM:
+                        genInline (ic);
+                        break;
+
+                case RRC:
+                        genRRC (ic);
+                        break;
+
+                case RLC:
+                        genRLC (ic);
+                        break;
+
+                case GETHBIT:
+                        genGetHbit (ic);
+                        break;
+
+                case LEFT_OP:
+                        genLeftShift (ic);
+                        break;
+
+                case RIGHT_OP:
+                        genRightShift (ic);
+                        break;
+
+                case GET_VALUE_AT_ADDRESS:
+                        genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
+                        break;
+
+                case '=':
+                        if (POINTER_SET (ic))
+                                genPointerSet (ic, hasInc(IC_RESULT(ic),ic));
+                        else
+                                genAssign (ic);
+                        break;
+
+                case IFX:
+                        genIfx (ic, NULL);
+                        break;
+
+                case ADDRESS_OF:
+                        genAddrOf (ic);
+                        break;
+
+                case JUMPTABLE:
+                        genJumpTab (ic);
+                        break;
+
+                case CAST:
+                        genCast (ic);
+                        break;
+
+                case RECEIVE:
+                        genReceive (ic);
+                        break;
+
+                case SEND:
+                        addSet (&_G.sendSet, ic);
+                        break;
+
+                case DUMMY_READ_VOLATILE:
+                        genDummyRead (ic);
+                        break;
+
+                default:
+                        ic = ic;
+                }
+        }
+
+
+        /* now we are ready to call the
+           peep hole optimizer */
+        if (!options.nopeep)
+                peepHole (&lineHead);
+
+        /* now do the actual printing */
+        printLine (lineHead, codeOutBuf);
+        return;
 }