From c2fad415b6342c706063788283ab01d840d2ad25 Mon Sep 17 00:00:00 2001 From: tecodev Date: Fri, 11 Nov 2005 23:09:56 +0000 Subject: [PATCH] * src/pic/gen.c: handle FPOINTERS like POINTERS everywhere * src/pic16/gen.c (pic16_derefPtr): now works for non-pointers as well, compute pointer's type from operand, (genUnpackBits,genPackBits): handle FPOINTERS correctly, re-indented, improved single bit reads, fixes bug #1353379 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3946 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 8 + src/pic/gen.c | 18 +- src/pic16/gen.c | 548 +++++++++++++++++++++++++----------------------- 3 files changed, 307 insertions(+), 267 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5fecc7c9..a53cba07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-11-11 Raphael Neider + + * src/pic/gen.c: handle FPOINTERS like POINTERS everywhere + * src/pic16/gen.c (pic16_derefPtr): now works for non-pointers as well, + compute pointer's type from operand, + (genUnpackBits,genPackBits): handle FPOINTERS correctly, re-indented, + improved single bit reads, fixes bug #1353379 + 2005-11-09 Borut Razem * support/scripts/sdcc.nsi: added lib/pic to the package diff --git a/src/pic/gen.c b/src/pic/gen.c index 9a221d25..4a4a1890 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -48,6 +48,10 @@ #define GPTRTAG_DATA 0x00 #define GPTRTAG_CODE 0x80 +/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */ +#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) +#define PIC_IS_FARPTR(x) (PIC_IS_DATA_PTR(x)) + extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void genMult8X8_8 (operand *, operand *,operand *); @@ -8450,6 +8454,7 @@ emitPtrByteGet (operand *src, int p_type, bool alreadyAddressed) switch (p_type) { case POINTER: + case FPOINTER: if (!alreadyAddressed) setup_fsr (src); emitpcode(POC_MOVFW, popCopyReg (&pc_fsr)); break; @@ -8491,6 +8496,7 @@ emitPtrByteSet (operand *dst, int p_type, bool alreadyAddressed) switch (p_type) { case POINTER: + case FPOINTER: if (!alreadyAddressed) setup_fsr (dst); emitpcode(POC_MOVWF, popCopyReg (&pc_fsr)); break; @@ -8559,6 +8565,7 @@ static void genUnpackBits (operand *result, operand *left, int ptype, iCode *ifx break; case POINTER: + case FPOINTER: case GPOINTER: case CPOINTER: emitPtrByteGet (left, ptype, FALSE); @@ -8596,6 +8603,7 @@ static void genUnpackBits (operand *result, operand *left, int ptype, iCode *ifx break; case POINTER: + case FPOINTER: case GPOINTER: case CPOINTER: emitPtrByteGet (left, ptype, FALSE); @@ -8692,7 +8700,7 @@ static void genNearPointerGet (operand *left, lower 128 bytes of space */ if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && !IS_BITVAR(retype) && - DCL_TYPE(ltype) == POINTER) { + PIC_IS_DATA_PTR(ltype)) { genDataPointerGet (left,result,ic); return ; } @@ -9126,6 +9134,7 @@ static void genPointerGet (iCode *ic) switch (p_type) { case POINTER: + case FPOINTER: //case IPOINTER: genNearPointerGet (left,result,ic); break; @@ -9192,6 +9201,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,int p_typ break; case POINTER: + case FPOINTER: setup_fsr (result); emitpcode(lit?POC_BSF:POC_BCF,newpCodeOpBit(PCOP(&pc_indf)->name,bstr,0)); break; @@ -9231,6 +9241,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,int p_typ break; case POINTER: + case FPOINTER: case GPOINTER: emitPtrByteGet(result, p_type, FALSE); if ((litval|mask) != 0x00ff) @@ -9267,6 +9278,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,int p_typ break; case POINTER: + case FPOINTER: case GPOINTER: emitPtrByteGet (result, p_type, FALSE); emitpcode(POC_BTFSS, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0)); @@ -9308,6 +9320,7 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,int p_typ break; case POINTER: + case FPOINTER: case GPOINTER: emitPtrByteGet (result, p_type, FALSE); emitpcode(POC_ANDLW, popGetLit (mask)); @@ -9449,7 +9462,7 @@ static void genNearPointerSet (operand *right, in data space & not a bit variable */ //if (AOP_TYPE(result) == AOP_IMMD && if (AOP_TYPE(result) == AOP_PCODE && - DCL_TYPE(ptype) == POINTER && + PIC_IS_DATA_PTR(ptype) && !IS_BITVAR (retype) && !IS_BITVAR (letype)) { genDataPointerSet (right,result,ic); @@ -9774,6 +9787,7 @@ static void genPointerSet (iCode *ic) switch (p_type) { case POINTER: + case FPOINTER: //case IPOINTER: genNearPointerSet (right,result,ic); break; diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 1f03cbb6..ca0e63d2 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -59,6 +59,10 @@ * more reliable and (sigh) slighly slower. */ #define USE_SIMPLE_GENCMP 1 +/* The PIC port(s) do not need to distinguish between POINTER and FPOINTER. */ +#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) +#define PIC_IS_FARPTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) + extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void pic16_genMult8X8_8 (operand *, operand *,operand *); @@ -10449,6 +10453,17 @@ void pic16_loadFSR0(operand *op, int lit) /*----------------------------------------------------------------*/ static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup) { + if (!IS_PTR(operandType(ptr))) + { + if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(ptr), 0)); + else pic16_mov2w (AOP(ptr), 0); + return; + } + + //assert (IS_DECL(operandType(ptr)) && (p_type == DCL_TYPE(operandType(ptr)))); + /* We might determine pointer type right here: */ + p_type = DCL_TYPE(operandType(ptr)); + switch (p_type) { case FPOINTER: case POINTER: @@ -10500,107 +10515,105 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp sym_link *etype, *letype; int blen=0, bstr=0; int lbstr; + int same; + pCodeOp *op; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - etype = getSpec(operandType(result)); - letype = getSpec(operandType(left)); - -// if(IS_BITFIELD(etype)) { - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); -// } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + etype = getSpec(operandType(result)); + letype = getSpec(operandType(left)); - lbstr = SPEC_BSTR( letype ); + // if(IS_BITFIELD(etype)) { + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); + // } - DEBUGpic16_emitcode ("; ***","%s %d - reading %s bitfield int %s destination",__FUNCTION__,__LINE__, - SPEC_USIGN(OP_SYM_ETYPE(left)) ? "an unsigned" : "a signed", SPEC_USIGN(OP_SYM_TYPE(result)) ? "an unsigned" : "a signed"); - -#if 1 - if((blen == 1) && (bstr < 8)) { - /* it is a single bit, so use the appropriate bit instructions */ - DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__); + lbstr = SPEC_BSTR( letype ); - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - - // distinguish (p->bitfield) and p.bitfield, remat seems to work... - if(!IS_PTR(operandType(left))/* && OP_SYMBOL(left)->remat && (ptype == POINTER)*/) { - /* workaround to reduce the extra lfsr instruction */ - pic16_emitpcode(POC_BTFSC, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr)); - } else { - /* this code does only handle __data pointers correctly */ - assert (IS_DATA_PTR(operandType(left))); - pic16_loadFSR0 (left, 0); - pic16_emitpcode(POC_BTFSC, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); - } + DEBUGpic16_emitcode ("; ***","%s %d - reading %s bitfield int %s destination",__FUNCTION__,__LINE__, + SPEC_USIGN(OP_SYM_ETYPE(left)) ? "an unsigned" : "a signed", SPEC_USIGN(OP_SYM_TYPE(result)) ? "an unsigned" : "a signed"); - if (SPEC_USIGN(OP_SYM_ETYPE(left))) { - /* unsigned bitfields result in either 0 or 1 */ - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); - } else { - /* signed bitfields result in either 0 or -1 */ - pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_wreg)); - } - pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 )); - - pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); - return; +#if 1 + if((blen == 1) && (bstr < 8) + && (!IS_PTR(operandType(left)) || PIC_IS_DATA_PTR(operandType(left)))) { + /* it is a single bit, so use the appropriate bit instructions */ + DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__); + + same = pic16_sameRegs(AOP(left),AOP(result)); + op = (same ? pic16_popCopyReg(&pic16_pc_wreg) : pic16_popGet (AOP(result),0)); + pic16_emitpcode(POC_CLRF, op); + + if(!IS_PTR(operandType(left))) { + /* workaround to reduce the extra lfsr instruction */ + pic16_emitpcode(POC_BTFSC, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr)); + } else { + assert (PIC_IS_DATA_PTR (operandType(left))); + pic16_loadFSR0 (left, 0); + pic16_emitpcode(POC_BTFSC, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); } -#endif - - /* the following call to pic16_loadFSR0 is temporary until - * optimization to handle single bit assignments is added - * to the function. Until then use the old safe way! -- VR */ - - if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) { - // access symbol directly - pic16_mov2w (AOP(left), 0); + if (SPEC_USIGN(OP_SYM_ETYPE(left))) { + /* unsigned bitfields result in either 0 or 1 */ + pic16_emitpcode(POC_INCF, op); } else { - pic16_derefPtr (left, ptype, 0, NULL); + /* signed bitfields result in either 0 or -1 */ + pic16_emitpcode(POC_DECF, op); + } + if (same) { + pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 )); } - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { - - /* shift right acc */ - AccRsh(shCnt, 0); + pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); + return; + } - pic16_emitpcode(POC_ANDLW, pic16_popGetLit( - (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); +#endif -/* VR -- normally I would use the following, but since we use the hack, - * to avoid the masking from AccRsh, why not mask it right now? */ + if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) { + // access symbol directly + pic16_mov2w (AOP(left), 0); + } else { + pic16_derefPtr (left, ptype, 0, NULL); + } -/* - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); -*/ + /* 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)) { - /* extend signed bitfields to 8 bits */ - if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen < 8)) - { - assert (blen + bstr > 0); - pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr + blen - 1)); - pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xFF << (bstr + blen))); - } + /* shift right acc */ + AccRsh(shCnt, 0); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); - pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); - return ; - } + /* VR -- normally I would use the following, but since we use the hack, + * to avoid the masking from AccRsh, why not mask it right now? */ + /* + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); + */ + /* extend signed bitfields to 8 bits */ + if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen < 8)) + { + assert (blen + bstr > 0); + pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr + blen - 1)); + pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xFF << (bstr + blen))); + } - fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); - fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); - exit(-1); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); return ; + } + + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); + + return ; } @@ -11299,222 +11312,227 @@ static void genPackBits (sym_link *etype , operand *result, int blen, bstr ; sym_link *retype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); - retype = getSpec(operandType(right)); + retype = getSpec(operandType(right)); - if(AOP_TYPE(right) == AOP_LIT) { - if((blen == 1) && (bstr < 8)) { - unsigned long lit; - /* it is a single bit, so use the appropriate bit instructions */ + if(AOP_TYPE(right) == AOP_LIT) { + if((blen == 1) && (bstr < 8)) { + unsigned long lit; + /* it is a single bit, so use the appropriate bit instructions */ - DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__); - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); -// pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - if(OP_SYMBOL(result)->remat && (p_type == POINTER) && (result)) { - /* workaround to reduce the extra lfsr instruction */ - if(lit) { - pic16_emitpcode(POC_BSF, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); - } else { - pic16_emitpcode(POC_BCF, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); - } - } else { - pic16_loadFSR0(result, 0); - if(lit) { - pic16_emitpcode(POC_BSF, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); - } else { - pic16_emitpcode(POC_BCF, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); - } - } - - return; - } - /* move literal to W */ - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); - offset++; - } else - if(IS_BITFIELD(retype) - && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR) - && (blen == 1)) { - int rblen, rbstr; + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + if(!IS_PTR(operandType(result))) { + /* workaround to reduce the extra lfsr instruction */ + if(lit) { + pic16_emitpcode(POC_BSF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } else { + pic16_emitpcode(POC_BCF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } + } else { + if (PIC_IS_DATA_PTR(operandType(result))) { + pic16_loadFSR0(result, 0); + pic16_emitpcode(lit ? POC_BSF : POC_BCF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + } else { + /* get old value */ + pic16_derefPtr (result, p_type, 0, NULL); + pic16_emitpcode(lit ? POC_BSF : POC_BCF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + /* write back new value */ + pic16_derefPtr (result, p_type, 1, NULL); + } + } - rblen = SPEC_BLEN( retype ); - rbstr = SPEC_BSTR( retype ); - + return; + } + /* move literal to W */ + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); + offset++; + } else + if(IS_BITFIELD(retype) + && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR) + && (blen == 1)) { + int rblen, rbstr; - if(IS_BITFIELD(etype)) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0)); - pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); - } else { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - } - - pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr)); - - if(IS_BITFIELD(etype)) { - pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); - } else { - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); - } + rblen = SPEC_BLEN( retype ); + rbstr = SPEC_BSTR( retype ); - pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0)); - - return; - } else { - /* move right to W */ - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); - } - /* if the bit length is less than or */ - /* it exactly fits a byte then */ - if((shCnt=SPEC_BSTR(etype)) - || SPEC_BLEN(etype) <= 8 ) { - int fsr0_setup = 0; - - if (blen != 8 || bstr != 0) { - // we need to combine the value with the old value - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); - - DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt, - SPEC_BSTR(etype), SPEC_BLEN(etype)); - - /* shift left acc */ - AccLsh(shCnt); - - /* using PRODH as a temporary register here */ - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); - - if (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) { - /* access symbol directly */ - pic16_mov2w (AOP(result), 0); - } else { - /* get old value */ - pic16_derefPtr (result, p_type, 0, &fsr0_setup); - } -#if 1 - pic16_emitpcode(POC_ANDLW, pic16_popGetLit( - (unsigned char)((unsigned char)(0xff << (blen+bstr)) | - (unsigned char)(0xff >> (8-bstr))) )); - pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); - } // if (blen != 8 || bstr != 0) - - /* write new value back */ - if (IS_SYMOP(result) & !IS_PTR(operandType(result))) { - pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); - } else { - pic16_derefPtr (result, p_type, 1, &fsr0_setup); - } -#endif + if(IS_BITFIELD(etype)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + } else { + pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); + } - return; - } + pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr)); + if(IS_BITFIELD(etype)) { + pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + } else { + pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); + } -#if 0 - fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); - fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); - exit(-1); -#endif + pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0)); + return; + } else { + /* move right to W */ + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); + } - pic16_loadFSR0(result, 0); // load FSR0 with address of result - rLen = SPEC_BLEN(etype)-8; - - /* now generate for lengths greater than one byte */ - while (1) { - rLen -= 8 ; - if (rLen <= 0 ) { - mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset); - break ; - } + /* if the bit length is less than or */ + /* it exactly fits a byte then */ + if((shCnt=SPEC_BSTR(etype)) + || SPEC_BLEN(etype) <= 8 ) { + int fsr0_setup = 0; - switch (p_type) { - case POINTER: - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0)); - break; + if (blen != 8 || bstr != 0) { + // we need to combine the value with the old value + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); -/* - case FPOINTER: - MOVA(l); - pic16_emitcode("movx","@dptr,a"); - break; + DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt, + SPEC_BSTR(etype), SPEC_BLEN(etype)); - case GPOINTER: - MOVA(l); - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; -*/ - default: - assert(0); - } + /* shift left acc */ + AccLsh(shCnt); + /* using PRODH as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); - pic16_mov2w(AOP(right), offset++); + if (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) { + /* access symbol directly */ + pic16_mov2w (AOP(result), 0); + } else { + /* get old value */ + pic16_derefPtr (result, p_type, 0, &fsr0_setup); + } +#if 1 + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (unsigned char)((unsigned char)(0xff << (blen+bstr)) | + (unsigned char)(0xff >> (8-bstr))) )); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + } // if (blen != 8 || bstr != 0) + + /* write new value back */ + if (IS_SYMOP(result) & !IS_PTR(operandType(result))) { + pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); + } else { + pic16_derefPtr (result, p_type, 1, &fsr0_setup); } +#endif - /* last last was not complete */ - if (rLen) { - /* save the byte & read byte */ - switch (p_type) { - case POINTER: -// pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); - pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - break; + return; + } -/* - case FPOINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("movx","a,@dptr"); - break; - case GPOINTER: - pic16_emitcode ("push","b"); - pic16_emitcode ("push","acc"); - pic16_emitcode ("lcall","__gptrget"); - pic16_emitcode ("pop","b"); - break; -*/ - default: - assert(0); - } - DEBUGpic16_emitcode(";", "rLen = %i", rLen); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen)); - pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); -// pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); -// pic16_emitcode ("orl","a,b"); - } +#if 0 + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); +#endif -// if (p_type == GPOINTER) -// pic16_emitcode("pop","b"); - switch (p_type) { + pic16_loadFSR0(result, 0); // load FSR0 with address of result + rLen = SPEC_BLEN(etype)-8; + + /* now generate for lengths greater than one byte */ + while (1) { + rLen -= 8 ; + if (rLen <= 0 ) { + mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset); + break ; + } + switch (p_type) { case POINTER: - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); -// pic16_emitcode("mov","@%s,a",rname); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0)); break; -/* - case FPOINTER: - pic16_emitcode("movx","@dptr,a"); + + /* + case FPOINTER: + MOVA(l); + pic16_emitcode("movx","@dptr,a"); + break; + + case GPOINTER: + MOVA(l); + DEBUGpic16_emitcode(";lcall","__gptrput"); + break; + */ + default: + assert(0); + } + + + pic16_mov2w(AOP(right), offset++); + } + + /* last last was not complete */ + if (rLen) { + /* save the byte & read byte */ + switch (p_type) { + case POINTER: + // pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); break; - - case GPOINTER: - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; -*/ + + /* + case FPOINTER: + pic16_emitcode ("mov","b,a"); + pic16_emitcode("movx","a,@dptr"); + break; + + case GPOINTER: + pic16_emitcode ("push","b"); + pic16_emitcode ("push","acc"); + pic16_emitcode ("lcall","__gptrget"); + pic16_emitcode ("pop","b"); + break; + */ default: - assert(0); + assert(0); } - -// pic16_freeAsmop(right, NULL, ic, TRUE); + DEBUGpic16_emitcode(";", "rLen = %i", rLen); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen)); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + // pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); + // pic16_emitcode ("orl","a,b"); + } + + // if (p_type == GPOINTER) + // pic16_emitcode("pop","b"); + + switch (p_type) { + + case POINTER: + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + // pic16_emitcode("mov","@%s,a",rname); + break; + /* + case FPOINTER: + pic16_emitcode("movx","@dptr,a"); + break; + + case GPOINTER: + DEBUGpic16_emitcode(";lcall","__gptrput"); + break; + */ + default: + assert(0); + } + + // pic16_freeAsmop(right, NULL, ic, TRUE); } + /*-----------------------------------------------------------------*/ /* genDataPointerSet - remat pointer to data space */ /*-----------------------------------------------------------------*/ -- 2.30.2