X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Favr%2Fgen.c;h=e9fc7a733525936f86cc8a029120841f074bbcef;hb=4db4740164fed3cb25145cfdaadb986fc0690507;hp=28667c5d2cd54685cf1c9f4bcb04728930f707e2;hpb=9d5f12eb51d5fb0966bf499cd271fd7cb270ee10;p=fw%2Fsdcc diff --git a/src/avr/gen.c b/src/avr/gen.c index 28667c5d..e9fc7a73 100644 --- a/src/avr/gen.c +++ b/src/avr/gen.c @@ -1,5 +1,5 @@ /*------------------------------------------------------------------------- - 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) @@ -31,19 +31,6 @@ #include "SDCCglobl.h" #include "newalloc.h" -#ifdef HAVE_SYS_ISA_DEFS_H -#include -#else -#ifdef HAVE_ENDIAN_H -#include -#else -#if !defined(__BORLANDC__) && !defined(_MSC_VER) -#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 "common.h" #include "SDCCpeeph.h" #include "ralloc.h" @@ -64,9 +51,8 @@ static char *spname; char *fReturnAVR[] = { "r16", "r17", "r18", "r19" }; unsigned fAVRReturnSize = 4; /* shared with ralloc.c */ char **fAVRReturn = fReturnAVR; -static short rbank = -1; -static char *larray[4] = { "lo8", "hi8", "hlo8", "hhi8" }; -static char *tscr[4] = { "r0", "r1", "r24", "r25" }; +static char *larray[4] = { ">", "<", "hlo8", "hhi8" }; + static struct { short xPushed; short zPushed; @@ -80,7 +66,6 @@ static struct { extern int avr_ptrRegReq; extern int avr_nRegs; extern FILE *codeOutFile; -static void saverbank (int, iCode *, bool); #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) @@ -96,18 +81,152 @@ static void saverbank (int, iCode *, bool); 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. +/*-----------------------------------------------------------------*/ +/* 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; + } + +} + +/*-----------------------------------------------------------------*/ +/* outBitC - output a bit C */ +/*-----------------------------------------------------------------*/ +static void +outBitC (operand * result) +{ + emitcode ("clr", "r0"); + emitcode ("rol", "r0"); + outAcc (result); +} + +/*-----------------------------------------------------------------*/ +/* 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; +} + +/*-----------------------------------------------------------------*/ +/* 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++; + + if (ic->op == LABEL && IC_LABEL (ic)->key == key) { + /* printf("findLabelBackwards = %d\n", count); */ + return count; + } + } + + return 0; +} + +/*-----------------------------------------------------------------*/ +/* addSign - complete with sign */ +/*-----------------------------------------------------------------*/ +static void +addSign (operand * result, int offset, int sign) +{ + int size = (getDataSize (result) - offset); + if (size > 0) { + if (sign) { + emitcode ("rlc", "a"); + emitcode ("subb", "a,acc"); + while (size--) + aopPut (AOP (result), "a", offset++); + } + else + while (size--) + aopPut (AOP (result), zero, offset++); + } +} + +/*-----------------------------------------------------------------*/ +/* isLiteralBit - test if lit == 2^n */ +/*-----------------------------------------------------------------*/ +static int +isLiteralBit (unsigned long lit) +{ + unsigned long pw[32] = { 1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L, + 0x100L, 0x200L, 0x400L, 0x800L, + 0x1000L, 0x2000L, 0x4000L, 0x8000L, + 0x10000L, 0x20000L, 0x40000L, 0x80000L, + 0x100000L, 0x200000L, 0x400000L, 0x800000L, + 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L, + 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L + }; + int idx; + + for (idx = 0; idx < 32; idx++) + if (lit == pw[idx]) + return idx + 1; + return 0; +} + +/*-----------------------------------------------------------------*/ +/* outAcc - output Acc */ +/*-----------------------------------------------------------------*/ +static void +outAcc (operand * result) +{ + 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++); + } + } +} + +#endif // End Unused code section + /*-----------------------------------------------------------------*/ /* emitcode - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -115,7 +234,7 @@ static void emitcode (char *inst, char *fmt, ...) { va_list ap; - char lb[MAX_INLINEASM]; + char lb[INITIAL_INLINEASM]; char *lbp = lb; va_start (ap, fmt); @@ -142,34 +261,47 @@ emitcode (char *inst, char *fmt, ...) va_end (ap); } +/*-----------------------------------------------------------------*/ +/* avr_emitDebuggerSymbol - associate the current code location */ +/* with a debugger symbol */ +/*-----------------------------------------------------------------*/ +void +avr_emitDebuggerSymbol (char * debugSym) +{ + _G.debugLine = 1; + emitcode ("", "%s ==.", debugSym); + _G.debugLine = 0; +} + /*-----------------------------------------------------------------*/ /* hasInc - operand is incremented before any other use */ /*-----------------------------------------------------------------*/ static iCode * hasInc (operand *op, iCode *ic) { - sym_link *type = operandType(op); - sym_link *retype = getSpec (type); - iCode *lic = ic->next; - int isize ; + 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; - isize = getSize(type->next); - while (lic) { - /* if operand of the form op = 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(ic->uses,op->key) || ((unsigned) ic->defKey == op->key)) { - return NULL; - } - lic = lic->next; - } - return NULL; + 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 + */ + 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; } /*-----------------------------------------------------------------*/ @@ -330,10 +462,10 @@ aopForSym (iCode * ic, symbol * sym, bool result) _G.nRegsSaved)); } else { - emitcode ("subi", "%s,lo8(%d)", + emitcode ("subi", "%s,<(%d)", aop->aopu.aop_ptr->name, sym->stack - _G.nRegsSaved); - emitcode ("sbci", "%s,hi8(%d)", + emitcode ("sbci", "%s,>(%d)", aop->aop_ptr2->name, sym->stack - _G.nRegsSaved); } @@ -345,10 +477,10 @@ aopForSym (iCode * ic, symbol * sym, bool result) sym->stack); } else { - emitcode ("subi", "%s,lo8(-%d)", + emitcode ("subi", "%s,<(-%d)", aop->aopu.aop_ptr->name, sym->stack); - emitcode ("sbci", "%s,hi8(-%d)", + emitcode ("sbci", "%s,>(-%d)", aop->aop_ptr2->name, sym->stack); } @@ -391,8 +523,8 @@ aopForSym (iCode * ic, symbol * sym, bool result) 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); - emitcode ("ldi", "%s,hi8(%s)", aop->aop_ptr2); + emitcode ("ldi", "%s,<(%s)", aop->aopu.aop_ptr->name, sym->rname); + emitcode ("ldi", "%s,>(%s)", aop->aop_ptr2); return aop; } @@ -537,7 +669,7 @@ sameRegs (asmop * aop1, asmop * aop2) static int isRegPair (asmop * aop) { - if (!aop || aop->size != 2) + if (!aop || aop->size < 2) return 0; if (aop->type == AOP_X || aop->type == AOP_Z) return 1; @@ -550,6 +682,22 @@ isRegPair (asmop * aop) return 0; } +/*-----------------------------------------------------------------*/ +/* allHigh - all registers are high registers */ +/*-----------------------------------------------------------------*/ +static int allHigh (asmop * aop) +{ + int i; + + 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; +} + /*-----------------------------------------------------------------*/ /* aopOp - allocates an asmop for an operand : */ /*-----------------------------------------------------------------*/ @@ -599,7 +747,7 @@ aopOp (operand * op, iCode * ic, bool result) /* if the type is a conditional */ - if (sym->regType == REG_CND) { + if (sym->regType & REG_CND) { aop = op->aop = sym->aop = newAsmop (AOP_CRY); aop->size = 0; return; @@ -631,6 +779,10 @@ aopOp (operand * op, iCode * ic, bool result) } /* else spill location */ + if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { + /* force a new aop if sizes differ */ + sym->usl.spillLoc->aop = NULL; + } sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result); aop->size = getSize (sym->type); @@ -707,10 +859,10 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop) stk + 1); } else { - emitcode ("subi", "%s,lo8(%d)", + emitcode ("subi", "%s,<(%d)", aop->aopu.aop_ptr->name, -(stk + 1)); - emitcode ("sbci", "%s,hi8(%d)", + emitcode ("sbci", "%s,>(%d)", aop->aop_ptr2->name, -(stk + 1)); } @@ -840,7 +992,7 @@ aopGet (asmop * aop, int offset) case AOP_LIT: s = aopLiteral (aop->aopu.aop_lit, offset); - emitcode ("ldi", "%s,lo8(%s)", + emitcode ("ldi", "%s,<(%s)", (rs = ((offset & 1) ? "r24" : "r25")), s); return rs; @@ -986,27 +1138,6 @@ aopPut (asmop * aop, char *s, int offset) } -/*-----------------------------------------------------------------*/ -/* 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; - } - -} - #define AOP(op) op->aop #define AOP_TYPE(op) AOP(op)->type #define AOP_SIZE(op) AOP(op)->size @@ -1093,36 +1224,6 @@ getDataSize (operand * op) return size; } -/*-----------------------------------------------------------------*/ -/* outAcc - output Acc */ -/*-----------------------------------------------------------------*/ -static void -outAcc (operand * result) -{ - 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++); - } - } -} - -/*-----------------------------------------------------------------*/ -/* outBitC - output a bit C */ -/*-----------------------------------------------------------------*/ -static void -outBitC (operand * result) -{ - emitcode ("clr", "r0"); - emitcode ("rol", "r0"); - outAcc (result); -} - /*-----------------------------------------------------------------*/ /* toBoolean - emit code for orl a,operator(sizeop) */ /*-----------------------------------------------------------------*/ @@ -1131,10 +1232,15 @@ toBoolean (operand * oper, char *r, bool clr) { int size = AOP_SIZE (oper); int offset = 0; - if (clr) + if (clr) { emitcode ("clr", "%s", r); - while (size--) - emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++)); + 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++)); + } } @@ -1310,7 +1416,7 @@ genUminus (iCode * ic) size = AOP_SIZE (IC_LEFT (ic)) - 1; offset = 1; while (size--) { - emitcode ("sbci", "%s,lo8(-1)", + emitcode ("sbci", "%s,0xff", aopGet (AOP (IC_RESULT (ic)), offset++)); } } @@ -1439,7 +1545,7 @@ static void genCall (iCode * ic) { - /* if send set is not empty the assign */ + /* if send set is not empty then assign */ if (_G.sendSet) { iCode *sic; int rnum = 16; @@ -1483,9 +1589,9 @@ genCall (iCode * ic) emitcode ("sbiw", "r28,%d", ic->parmBytes); } else { - emitcode ("subi", "r28,lo8(%d)", + emitcode ("subi", "r28,<(%d)", ic->parmBytes); - emitcode ("sbci", "r29,hi8(%d)", + emitcode ("sbci", "r29,>(%d)", ic->parmBytes); } } @@ -1566,9 +1672,9 @@ genPcall (iCode * ic) emitcode ("sbiw", "r28,%d", ic->parmBytes); } else { - emitcode ("subi", "r28,lo8(%d)", + emitcode ("subi", "r28,<(%d)", ic->parmBytes); - emitcode ("sbci", "r29,hi8(%d)", + emitcode ("sbci", "r29,>(%d)", ic->parmBytes); } } @@ -1600,26 +1706,6 @@ resultRemat (iCode * ic) #define STRCASECMP strcasecmp #endif -/*-----------------------------------------------------------------*/ -/* inExcludeList - return 1 if the string is in exclude Reg list */ -/*-----------------------------------------------------------------*/ -static bool -inExcludeList (char *s) -{ - int i = 0; - - if (options.excludeRegs[i] && - STRCASECMP (options.excludeRegs[i], "none") == 0) - return FALSE; - - for (i = 0; options.excludeRegs[i]; i++) { - if (options.excludeRegs[i] && - STRCASECMP (s, options.excludeRegs[i]) == 0) - return TRUE; - } - return FALSE; -} - /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ /*-----------------------------------------------------------------*/ @@ -1627,7 +1713,7 @@ static void genFunction (iCode * ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; int i = 0; _G.nRegsSaved = 0; @@ -1638,13 +1724,13 @@ genFunction (iCode * ic) emitcode (";", "-----------------------------------------"); emitcode ("", "%s:", sym->rname); - fetype = getSpec (operandType (IC_LEFT (ic))); + ftype = operandType (IC_LEFT (ic)); /* if critical function then turn interrupts off */ - if (SPEC_CRTCL (fetype)) + if (IFFUNC_ISCRITICAL (ftype)) emitcode ("cli", ""); - if (IS_ISR (sym->etype)) { + if (IFFUNC_ISISR (sym->type)) { } /* save the preserved registers that are used in this function */ @@ -1681,8 +1767,8 @@ genFunction (iCode * ic) emitcode ("sbiw", "r28,%d", sym->stack); } else { - emitcode ("subi", "r28,lo8(%d)", sym->stack); - emitcode ("sbci", "r29,hi8(%d)", sym->stack); + emitcode ("subi", "r28,<(%d)", sym->stack); + emitcode ("sbci", "r29,>(%d)", sym->stack); } emitcode ("out", "__SP_L__,r28"); emitcode ("out", "__SP_H__,r29"); @@ -1704,8 +1790,8 @@ genEndFunction (iCode * ic) emitcode ("adiw", "r28,%d", sym->stack); } else { - emitcode ("subi", "r28,lo8(-%d)", sym->stack); - emitcode ("sbci", "r29,hi8(-%d)", sym->stack); + emitcode ("subi", "r28,<(-%d)", sym->stack); + emitcode ("sbci", "r29,>(-%d)", sym->stack); } emitcode ("out", "__SP_L__,r28"); emitcode ("out", "__SP_H__,r29"); @@ -1738,10 +1824,14 @@ genEndFunction (iCode * ic) } } - if (SPEC_CRTCL (sym->etype)) + if (IFFUNC_ISCRITICAL (sym->type)) emitcode ("sti", ""); - if (IS_ISR (sym->etype)) { + if (options.debug && currFunc) { + debugFile->writeEndFunction (currFunc, ic, 1); + } + + if (IFFUNC_ISISR (sym->type)) { emitcode ("rti", ""); } else { @@ -1816,31 +1906,7 @@ genLabel (iCode * ic) static void genGoto (iCode * ic) { - emitcode ("rjmp", "L%05d:", (IC_LABEL (ic)->key + 100)); -} - -/*-----------------------------------------------------------------*/ -/* 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++; - - if (ic->op == LABEL && IC_LABEL (ic)->key == key) { - /* printf("findLabelBackwards = %d\n", count); */ - return count; - } - } - - return 0; + emitcode ("rjmp", "L%05d", (IC_LABEL (ic)->key)); } /*-----------------------------------------------------------------*/ @@ -1850,6 +1916,7 @@ static bool genPlusIncr (iCode * ic) { unsigned int icount; + int offset = 0; /* will try to generate an increment */ /* if the right side is not a literal @@ -1857,8 +1924,7 @@ genPlusIncr (iCode * ic) if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) return FALSE; - icount = - (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu. + icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu. aop_lit); /* if the sizes are greater than 2 or they are not the same regs @@ -1875,34 +1941,41 @@ genPlusIncr (iCode * ic) aopGet (AOP (IC_LEFT (ic)), 0)); return TRUE; } - emitcode ("subi", "%s,lo8(%d)", - aopGet (AOP (IC_LEFT (ic)), 0), 0-icount); - 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)), R30_IDX))) { + && (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,lo8(%d)", + emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0), 0-icount); - emitcode ("sbci", "%s,hi8(%d)", + emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1), 0-icount); return TRUE; } /* for 32 bit longs */ - emitcode ("subi", "%s,lo8(%d)", aopGet (AOP (IC_RESULT (ic)), 0), + emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0), 0-icount); - emitcode ("sbci", "%s,hi8(%d)", aopGet (AOP (IC_RESULT (ic)), 1), + 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); @@ -1988,16 +2061,27 @@ genPlus (iCode * ic) aopGet (AOP (IC_RIGHT (ic)), offset)); } else { - if (offset == 0) - l = "subi"; - else - l = "sbci"; - - emitcode (l, "%s,%s(-%d)", - aopGet (AOP (IC_RESULT (ic)), offset), - larray[offset], - (int) floatFromVal (AOP (IC_RIGHT (ic))-> - aopu.aop_lit)); + 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) floatFromVal (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++; } @@ -2019,6 +2103,7 @@ static bool genMinusDec (iCode * ic) { unsigned int icount; + int offset ; /* will try to generate an increment */ /* if the right side is not a literal @@ -2032,7 +2117,7 @@ genMinusDec (iCode * ic) /* 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_RIGHT (ic)))) + if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)))) return FALSE; /* so we know LEFT & RESULT in the same registers and add @@ -2044,33 +2129,40 @@ genMinusDec (iCode * ic) aopGet (AOP (IC_LEFT (ic)), 0)); return TRUE; } - emitcode ("subi", "%s,lo8(%d)", - aopGet (AOP (IC_LEFT (ic)), 0), icount); - return TRUE; + if (AOP_ISHIGHREG( AOP ( IC_LEFT(ic)),0)) { + emitcode ("subi", "%s,<(%d)", + aopGet (AOP (IC_LEFT (ic)), 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)), R30_IDX))) { + && (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; } /* use subi */ - emitcode ("subi", "%s,lo8(%d)", + emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0), icount); - emitcode ("sbci", "%s,hi8(%d)", + emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1), icount); return TRUE; } /* for 32 bit longs */ - emitcode ("subi", "%s,lo8(%d)", aopGet (AOP (IC_RESULT (ic)), 0), + emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0), icount); - emitcode ("sbci", "%s,hi8(%d)", aopGet (AOP (IC_RESULT (ic)), 1), + emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1), icount); emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2), icount); @@ -2080,26 +2172,6 @@ genMinusDec (iCode * ic) } -/*-----------------------------------------------------------------*/ -/* addSign - complete with sign */ -/*-----------------------------------------------------------------*/ -static void -addSign (operand * result, int offset, int sign) -{ - int size = (getDataSize (result) - offset); - if (size > 0) { - if (sign) { - emitcode ("rlc", "a"); - emitcode ("subb", "a,acc"); - while (size--) - aopPut (AOP (result), "a", offset++); - } - else - while (size--) - aopPut (AOP (result), zero, offset++); - } -} - /*-----------------------------------------------------------------*/ /* genMinus - generates code for subtraction */ /*-----------------------------------------------------------------*/ @@ -2137,16 +2209,27 @@ genMinus (iCode * ic) aopGet (AOP (IC_RIGHT (ic)), offset)); } else { - if (offset == 0) - l = "subi"; - else - l = "sbci"; - - emitcode (l, "%s,%s(%d)", - aopGet (AOP (IC_RESULT (ic)), offset), - larray[offset], - (int) floatFromVal (AOP (IC_RIGHT (ic))-> - aopu.aop_lit)); + 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) floatFromVal (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)); + } } offset++; } @@ -2204,7 +2287,7 @@ genMultOneByte (operand * left, operand * right, operand * result) lbl = newiTempLabel (NULL); emitcode ("ldi", "r24,0"); emitcode ("brcc", "L%05d", lbl->key); - emitcode ("ldi", "r24,lo8(-1)"); + emitcode ("ldi", "r24,0xff)"); emitcode ("", "L%05d:", lbl->key); while (size--) aopPut (AOP (result), "r24", @@ -2237,7 +2320,7 @@ genMult (iCode * ic) } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -2252,7 +2335,7 @@ static void genDiv (iCode * ic) { /* should have been converted to function call */ - assert (1); + assert (0); } /*-----------------------------------------------------------------*/ @@ -2262,7 +2345,7 @@ static void genMod (iCode * ic) { /* should have been converted to function call */ - assert (1); + assert (0); } @@ -2295,7 +2378,7 @@ revavrcnd (int type) if (rar[i].rtype == type) return rar[i].type; } - assert (1); /* cannot happen */ + assert (0); /* cannot happen */ return 0; /* makes the compiler happy */ } @@ -2350,7 +2433,7 @@ genCmp (iCode * ic, iCode * ifx, int br_type) if (ifx) { if (size == 1) { if (AOP_TYPE (right) == AOP_LIT) { - emitcode ("cpi", "%s,lo8(%d)", + emitcode ("cpi", "%s,<(%d)", aopGet (AOP (left), 0), (int) floatFromVal (AOP (IC_RIGHT (ic))-> @@ -2420,7 +2503,7 @@ static void genCmpGt (iCode * ic, iCode * ifx) { /* should have transformed by the parser */ - assert (1); + assert (0); } /*-----------------------------------------------------------------*/ @@ -2566,28 +2649,6 @@ genOrOp (iCode * ic) freeAsmop (result, NULL, ic, TRUE); } -/*-----------------------------------------------------------------*/ -/* isLiteralBit - test if lit == 2^n */ -/*-----------------------------------------------------------------*/ -static int -isLiteralBit (unsigned long lit) -{ - unsigned long pw[32] = { 1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L, - 0x100L, 0x200L, 0x400L, 0x800L, - 0x1000L, 0x2000L, 0x4000L, 0x8000L, - 0x10000L, 0x20000L, 0x40000L, 0x80000L, - 0x100000L, 0x200000L, 0x400000L, 0x800000L, - 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L, - 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L - }; - int idx; - - for (idx = 0; idx < 32; idx++) - if (lit == pw[idx]) - return idx + 1; - return 0; -} - enum { AVR_AND = 0, AVR_OR, AVR_XOR }; @@ -2638,12 +2699,12 @@ genBitWise (iCode * ic, iCode * ifx, int bitop) if (size == 1) { if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),0)) { emitcode (bopnames_lit[bitop], - "%s,lo8(%d)", + "%s,<(%d)", aopGet (AOP (IC_LEFT (ic)), 0), lit); } else { MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0)); - emitcode (bopnames_lit[bitop], "r24,lo8(%d)", lit); + emitcode (bopnames_lit[bitop], "r24,<(%d)", lit); } lbl = newiTempLabel (NULL); if (IC_TRUE (ifx)) { @@ -2659,8 +2720,8 @@ genBitWise (iCode * ic, iCode * ifx, int bitop) 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,lo8(%d)", lit); - emitcode (bopnames_lit[bitop], "r25,hi8(%d)", lit); + 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)) { @@ -2678,14 +2739,14 @@ genBitWise (iCode * ic, iCode * ifx, int bitop) lbl1 = newiTempLabel (NULL); while (size--) { if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset)) { - emitcode (bopnames_lit [bitop], "%s,lo8(%d)", + 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,lo8(%d)", lit); + emitcode ("andi", "r24,<(%d)", lit); } emitcode ("brne", "L%05d", lbl->key); offset++; @@ -2886,11 +2947,11 @@ genXor (iCode * ic, iCode * ifx) static void genInline (iCode * ic) { - char buffer[MAX_INLINEASM]; - char *bp = buffer; - char *bp1 = buffer; + char *buffer, *bp, *bp1; _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy (buffer, IC_INLINE (ic)); /* emit each line as a code */ @@ -3002,13 +3063,13 @@ genGetHbit (iCode * ic) 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,lo8(-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,lo8(-1)"); + emitcode ("subi", "r0,<(-1)"); aopPut (AOP (result), "r0", 0); } offset = 1; @@ -3313,34 +3374,34 @@ genShiftRightLit (iCode * ic) aopGet (AOP (left), offset), offset); offset++; } - size = size = AOP_SIZE (result); + size = AOP_SIZE (result); offset = 0; } /* be as economical as possible */ if (shCount <= 4) { - offset = size - 1; while (shCount--) { - offset = size - 1; size = AOP_SIZE (result); + offset = size - 1; while (size--) { - if (offset == (size - 1)) + /* highest order byte */ + if (offset == (AOP_SIZE(result)-1)) emitcode ("asr", "%s", aopGet (AOP (result), offset)); else - emitcode ("lsr", "%s", aopGet (AOP (result), offset)); - offset--; + emitcode ("ror", "%s", aopGet (AOP (result), offset)); + offset--; } } } else { - emitcode ("ldi", "r24,lo8(%d)", shCount); + emitcode ("ldi", "r24,<(%d)", shCount); tlbl = newiTempLabel (NULL); emitcode ("", "L%05d:", tlbl->key); offset = size - 1; while (size--) { - if (offset == (size - 1)) + if (offset == (AOP_SIZE(result) - 1)) emitcode ("asr", "%s", aopGet (AOP (result), offset)); else - emitcode ("lsr", "%s", aopGet (AOP (result), offset)); + emitcode ("ror", "%s", aopGet (AOP (result), offset)); offset--; } emitcode ("dec", "r24"); @@ -4014,10 +4075,13 @@ genGenPointerGet (operand * left, operand * result, iCode * ic, iCode *pi) } else { aop = newAsmop(0); getFreePtr(ic,&aop,FALSE,TRUE); - - emitcode ("mov", "r30,%s", aopGet (AOP (left), 0)); - emitcode ("mov", "r31,%s", aopGet (AOP (left), 1)); - emitcode ("mov", "r0,%s", aopGet (AOP (left), 2)); + 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; } @@ -4523,6 +4587,10 @@ genPointerSet (iCode * ic, iCode *pi) case GPOINTER: genGenPointerSet (right, result, ic, pi); break; + + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerSet: illegal pointer type"); } } @@ -4536,6 +4604,7 @@ genIfx (iCode * ic, iCode * popIc) operand *cond = IC_COND (ic); char *cname ; symbol *lbl; + int tob = 0; aopOp (cond, ic, FALSE); @@ -4543,24 +4612,26 @@ genIfx (iCode * ic, iCode * popIc) if (AOP_SIZE(cond) == 1 && AOP_ISHIGHREG(AOP(cond),0)) { cname = aopGet(AOP(cond),0); } else { - toBoolean (cond, "r24", 1); + 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) + if (popIc) { genIpop (popIc); - - emitcode("cpi","%s,0",cname); + emitcode("cpi","%s,0",cname); + } else if (!tob) emitcode("cpi","%s,0",cname); + lbl = newiTempLabel(NULL); if (IC_TRUE(ic)) { - emitcode ("brne","L%05d",lbl->key); + emitcode ("breq","L%05d",lbl->key); emitcode ("jmp","L%05d",IC_TRUE(ic)->key); emitcode ("","L%05d:",lbl->key); } else { - emitcode ("breq","L%05d",lbl->key); + emitcode ("brne","L%05d",lbl->key); emitcode ("jmp","L%05d",IC_FALSE(ic)->key); emitcode ("","L%05d:",lbl->key); } @@ -4577,42 +4648,57 @@ genAddrOf (iCode * 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 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); + 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 { - /* we can just move _bp */ - aopPut (AOP (IC_RESULT (ic)), "_bp", 0); + 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)) - 1; - - - if (options.stack10bit && size < (FPTRSIZE - 1)) { - fprintf (stderr, - "*** warning: pointer to stack var truncated.\n"); - } - - offset = 1; + size = AOP_SIZE (IC_RESULT (ic)) - 2; + offset = 2; while (size--) { - /* Yuck! */ - if (options.stack10bit && offset == 2) { - aopPut (AOP (IC_RESULT (ic)), "#0x40", - offset++); - } - else { - aopPut (AOP (IC_RESULT (ic)), zero, offset++); - } + aopPut (AOP (IC_RESULT (ic)), zero, offset++); } goto release; @@ -4621,13 +4707,13 @@ genAddrOf (iCode * ic) /* 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 >> %d)", sym->rname, offset * 8); + sprintf (s, ">(%s)", sym->rname); else - sprintf (s, "#%s", sym->rname); + sprintf (s, "<(%s)", sym->rname); aopPut (AOP (IC_RESULT (ic)), s, offset++); } @@ -4858,8 +4944,6 @@ genCast (iCode * ic) /* pointer to generic pointer */ if (IS_GENPTR (ctype)) { - char *l = zero; - if (IS_PTR (type)) p_type = DCL_TYPE (type); else { @@ -4875,30 +4959,22 @@ genCast (iCode * ic) aopGet (AOP (right), offset), 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); + + /* 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); } - aopPut (AOP (result), l, GPTRSIZE - 1); - goto release; + + sprintf(gpValStr, "#0x%x", gpVal); + aopPut (AOP (result), gpValStr, GPTRSIZE - 1); + } + goto release; } /* just copy the pointers */ @@ -4931,8 +5007,11 @@ genCast (iCode * ic) } 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--) @@ -5004,7 +5083,8 @@ genDjnz (iCode * ic, iCode * ifx) static char *recvregs[8] = { "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23" }; -static recvCnt = 0; + +static int recvCnt = 0; /*-----------------------------------------------------------------*/ /* genReceive - generate code for a receive iCode */ @@ -5022,6 +5102,18 @@ genReceive (iCode * ic) 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",""); + + ic = ic; +} + /*-----------------------------------------------------------------*/ /* gen51Code - generate code for 8051 based controllers */ /*-----------------------------------------------------------------*/ @@ -5037,12 +5129,8 @@ genAVRCode (iCode * lic) if (allocInfo) printAllocInfo (currFunc, codeOutFile); /* if debug information required */ - /* if (options.debug && currFunc) { */ - if (currFunc) { - cdbSymbol (currFunc, cdbFile, FALSE, TRUE); - _G.debugLine = 1; - emitcode ("", ".type %s,@function", currFunc->name); - _G.debugLine = 0; + if (options.debug && currFunc) { + debugFile->writeFunction (currFunc, lic); } /* stack pointer name */ spname = "sp"; @@ -5052,11 +5140,7 @@ genAVRCode (iCode * lic) if (cln != ic->lineno) { if (options.debug) { - _G.debugLine = 1; - emitcode ("", "C$%s$%d$%d$%d ==.", - FileBaseName (ic->filename), - ic->lineno, ic->level, ic->block); - _G.debugLine = 0; + debugFile->writeCLine (ic); } emitcode (";", "%s %d", ic->filename, ic->lineno); cln = ic->lineno; @@ -5253,6 +5337,10 @@ genAVRCode (iCode * lic) addSet (&_G.sendSet, ic); break; + case DUMMY_READ_VOLATILE: + genDummyRead (ic); + break; + default: ic = ic; }