* 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))
+#define PIC_IS_TAGGED(x) (IS_GENPTR(x) || IS_CODEPTR(x))
+
+/* If you change these, you also have to update the library files
+ * device/lib/pic16/libsdcc/gptr{get,put}{1,2,3,4}.c */
+#define GPTR_TAG_DATA 0x80
+#define GPTR_TAG_EEPROM 0x40
+#define GPTR_TAG_CODE 0x00 /* must be 0 becaue of UPPER(sym)==0 */
+
+/* Wrapper to execute `code' at most once. */
+#define PERFORM_ONCE(id,code) do { static char id = 0; if (!id) { id = 1; code } } while (0)
+
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 *);
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
va_start(ap,fmt);
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
if(!pic16_debug_verbose)
return;
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
va_start(ap,fmt);
DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
//sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
if (offset) {
- sprintf(s,"(%s + %d)", pcop->name, offset);
+ sprintf(s,"(%s + %d)", pic16_get_op (pcop, NULL, 0), offset);
} else {
- sprintf(s,"%s", pcop->name);
+ sprintf(s,"%s", pic16_get_op (pcop, NULL, 0));
}
} else
sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
}
}
+static void pic16_movLit2f(pCodeOp *pc, int lit)
+{
+ if (0 == (lit & 0x00ff))
+ {
+ pic16_emitpcode (POC_CLRF, pc);
+ } else if (0xff == (lit & 0x00ff))
+ {
+ pic16_emitpcode (POC_SETF, pc);
+ } else {
+ pic16_emitpcode (POC_MOVLW, pic16_popGetLit (lit & 0x00ff));
+ if (pc->type != PO_WREG) pic16_emitpcode (POC_MOVWF, pc);
+ }
+}
+
static void mov2fp(pCodeOp *dst, asmop *src, int offset)
{
if(is_LitAOp(src)) {
}
}
-
-#if !defined(GEN_Not)
-/*-----------------------------------------------------------------*/
-/* genNot - generate code for ! operation */
-/*-----------------------------------------------------------------*/
-static void pic16_genNot (iCode *ic)
-{
- symbol *tlbl;
- int size;
-
- FENTRY;
- /* assign asmOps to operand & result */
- pic16_aopOp (IC_LEFT(ic),ic,FALSE);
- pic16_aopOp (IC_RESULT(ic),ic,TRUE);
-
- DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
- /* if in bit space then a special case */
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
- if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
- pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- } else {
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
- pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- }
- goto release;
- }
-
- size = AOP_SIZE(IC_LEFT(ic));
- if(size == 1) {
- pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
- pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- goto release;
- }
- pic16_toBoolean(IC_LEFT(ic));
-
- tlbl = newiTempLabel(NULL);
- pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
- pic16_outBitC(IC_RESULT(ic));
-
- release:
- /* release the aops */
- pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-#endif
-
-
-#if !defined(GEN_Cpl)
-/*-----------------------------------------------------------------*/
-/* genCpl - generate code for complement */
-/*-----------------------------------------------------------------*/
-static void pic16_genCpl (iCode *ic)
-{
- int offset = 0;
- int size ;
-
- FENTRY;
- /* assign asmOps to operand & result */
- pic16_aopOp (IC_LEFT(ic),ic,FALSE);
- pic16_aopOp (IC_RESULT(ic),ic,TRUE);
-
- /* if both are in bit space then
- a special case */
- if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
- AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
-
- pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
- pic16_emitcode("cpl","c");
- pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
- goto release;
- }
-
- size = AOP_SIZE(IC_RESULT(ic));
- while (size--) {
-/*
- char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
- MOVA(l);
- pic16_emitcode("cpl","a");
- pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
-*/
- if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
- } else {
- pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- }
- offset++;
-
- }
-
-
-release:
- /* release the aops */
- pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-#endif
-
/*-----------------------------------------------------------------*/
/* genUminusFloat - unary minus for floating points */
/*-----------------------------------------------------------------*/
/* for this we just need to flip the
first it then copy the rest in place */
size = AOP_SIZE(op);
+ assert( size == AOP_SIZE(result) );
while(size--) {
pic16_mov2f(AOP(result), AOP(op), offset);
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 (IS_FLOAT(optype) || IS_FIXED(optype)) {
+ if(IS_FIXED(optype))
+ debugf("implement fixed16x16 type\n", 0);
+
+ genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
+ goto release;
}
/* otherwise subtract from zero by taking the 2's complement */
size = AOP_SIZE(IC_LEFT(ic));
+ assert( size == AOP_SIZE(IC_RESULT(ic)) );
label = newiTempLabel ( NULL );
if (pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
{
- if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
+ if((AOP(op)->type == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_IMMEDIATE)) {
pic16_emitpcode(POC_MOVFW, src);
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
} else {
}
if(is_LitOp(op)) {
- if(/*(OP_LIVETO(op) <= ic->seq) &&*/ (lit == 0)) {
- pic16_emitpcode(POC_CLRF, dest);
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
- if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
- }
+ pic16_movLit2f(dest, lit);
} else {
if(dest->type == PO_WREG && (offset == 0)) {
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
FENTRY;
- assert (AOP_SIZE(left) == AOP_SIZE(right));
assert (left && right);
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
size = AOP_SIZE(right) - 1;
mask = (0x100UL << (size*8)) - 1;
pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
} // if
} else {
+ /* using PRODL as a temporary register here */
pCodeOp *pctemp = pic16_popCopyReg(&pic16_pc_prodl);
//pCodeOp *pctemp = pic16_popGetTempReg(1);
pic16_mov2w (AOP(left), size);
/* signed compare */
DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
+ /* using PRODL:PRODH as a temporary register here */
pct = pic16_popCopyReg(&pic16_pc_prodl);
pct2 = pic16_popCopyReg(&pic16_pc_prodh);
tlbl = newiTempLabel( NULL );
pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
}
+ assert( AOP_SIZE(left) == AOP_SIZE(right) );
for(i=0; i < AOP_SIZE(left); i++)
{
if(AOP_TYPE(left) != AOP_ACC)
bp -= 8;
ofs++;
}
-
+
pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
* to denote that the argument should not be indented with tab */
pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
bp1 = bp;
+ } if (*bp == ';') {
+ /* advance to end of line (prevent splitting of comments at ':' */
+ while (*bp && *bp != '\n') {
+ bp++;
+ } // while
} else
bp++;
}
else
movLeft2Result(left, MSB16, result, LSB);
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
-
- if(sign) {
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16));
- }
+ pic16_addSign (result, 1, sign);
}
/* 1 <= shCount <= 7 */
/*----------------------------------------------------------------*/
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:
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);
+ // }
-#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 {
- pic16_loadFSR0 (left, 0);
- pic16_emitpcode(POC_BTFSC,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
- }
-
- pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
+ 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");
- pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));
- 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)) {
+ pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result)));
+ return;
+ }
- /* shift right acc */
- AccRsh(shCnt, 0);
+#endif
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
- (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
+ if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) {
+ // access symbol directly
+ pic16_mov2w (AOP(left), 0);
+ } else {
+ pic16_derefPtr (left, ptype, 0, NULL);
+ }
-/* 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 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)) {
-/*
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
-*/
+ /* shift right acc */
+ AccRsh(shCnt, 0);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- return ;
- }
+ pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
+ (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
+ /* 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 ;
}
}
+#if 0
+/* This code is not adjusted to PIC16 and fails utterly.
+ * On the other hand: PIC16 does not support xdata (the only mem FPOINTERs are used for) anyway... */
+
/*-----------------------------------------------------------------*/
/* genFarPointerGet - gget value from far space */
/*-----------------------------------------------------------------*/
pic16_freeAsmop(result,NULL,ic,TRUE);
}
+#endif
#if 0
/*-----------------------------------------------------------------*/
the pointer values */
switch (p_type) {
case POINTER:
+ case FPOINTER:
case IPOINTER:
genNearPointerGet (left,result,ic);
break;
genPagedPointerGet(left,result,ic);
break;
+#if 0
+ /* PICs do not support FAR pointers... */
+ /* MUST move them somewhere; handle FPOINTERs like POINTERS or like GPOINTERs?!? */
case FPOINTER:
genFarPointerGet (left,result,ic);
break;
+#endif
case CPOINTER:
genConstPointerGet (left,result,ic);
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 */
/*-----------------------------------------------------------------*/
}
lit = lit >> (8*offset);
- if(lit&0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
- } else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
- }
+ pic16_movLit2f(pic16_popGet(AOP(result),offset), lit);
} else {
pic16_mov2w(AOP(right), offset);
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
}
+#if 0
+/* This code is not adjusted to PIC16 and fails utterly...
+ * On the other hand: PIC16 has no xdata anyway (the only memory FPOINTERs are use for) */
+
/*-----------------------------------------------------------------*/
/* genFarPointerSet - set value from far space */
/*-----------------------------------------------------------------*/
pic16_freeAsmop(right,NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*/
/* genGenPointerSet - set value from generic pointer space */
the pointer values */
switch (p_type) {
case POINTER:
+ case FPOINTER:
case IPOINTER:
genNearPointerSet (right,result,ic);
break;
genPagedPointerSet (right,result,ic);
break;
+#if 0
+ /* MUST move them somewhere; handle FPOINTERs like POINTERS or like GPOINTERs?!? */
case FPOINTER:
genFarPointerSet (right,result,ic);
break;
+#endif
case GPOINTER:
genGenPointerSet (right,result,ic);
static void genAssign (iCode *ic)
{
operand *result, *right;
+ sym_link *restype, *rtype;
int size, offset,know_W;
unsigned long lit = 0L;
/* bit variables done */
/* general case */
size = AOP_SIZE(result);
+ restype = operandType(result);
+ rtype = operandType(right);
offset = 0 ;
if(AOP_TYPE(right) == AOP_LIT) {
- if(!IS_FLOAT(operandType( right )))
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
- else {
- union {
- unsigned long lit_int;
- float lit_float;
- } info;
-
- /* take care if literal is a float */
- info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
- lit = info.lit_int;
+ if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right))))
+ {
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+
+ /* patch tag for literals that are cast to pointers */
+ if (IS_CODEPTR(restype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(__code*)literal'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+ } else {
+ if (IS_GENPTR(restype))
+ {
+ if (IS_CODEPTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __code*)'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+ } else if (PIC_IS_DATA_PTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __data*)'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+ } else if (!IS_PTR(rtype) || IS_GENPTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)literal' -- accepting specified tag %02x\n", ic->filename, ic->lineno, (unsigned char)(lit >> 16));
+ } else if (IS_PTR(rtype)) {
+ fprintf (stderr, "%s:%u: WARNING: `(generic*)literal' -- assuming __data space\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+ }
}
+ }
+ } else {
+ union {
+ unsigned long lit_int;
+ float lit_float;
+ } info;
+
+
+ if(IS_FIXED16X16(operandType(right))) {
+ lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit));
+ } else {
+ /* take care if literal is a float */
+ info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = info.lit_int;
+ }
+ }
}
// fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
goto release;
}
-
-
#if 0
/* VR - What is this?! */
if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
know_W=-1;
while (size--) {
- DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
+ DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
if(AOP_TYPE(right) == AOP_LIT) {
if(lit&0xff) {
if(know_W != (lit&0xff))
release:
pic16_freeAsmop (right,NULL,ic,FALSE);
pic16_freeAsmop (result,NULL,ic,TRUE);
-}
+}
/*-----------------------------------------------------------------*/
/* genJumpTab - generates code for jump table */
&& IS_BITFIELD(getSpec(rtype))) {
DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
}
+
+ /* port from pic14 to cope with generic pointers */
+ if (PIC_IS_TAGGED(restype))
+ {
+ operand *result = IC_RESULT(ic);
+ //operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ int tag = 0xff;
+
+ /* copy common part */
+ int max, size = AOP_SIZE(result);
+ if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ max = size;
+ while (size--)
+ {
+ pic16_mov2w (AOP(right), size);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
+ } // while
+
+ /* upcast into generic pointer type? */
+ if (IS_GENPTR(restype)
+ && !PIC_IS_TAGGED(rtype)
+ && (AOP_SIZE(result) > max))
+ {
+ /* determine appropriate tag for right */
+ if (PIC_IS_DATA_PTR(rtype))
+ tag = GPTR_TAG_DATA;
+ else if (IS_CODEPTR(rtype))
+ tag = GPTR_TAG_CODE;
+ else if (PIC_IS_DATA_PTR(ctype)) {
+ //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__data*)(non-pointer)'\n", ic->filename, ic->lineno);
+ tag = GPTR_TAG_DATA;
+ } else if (IS_CODEPTR(ctype)) {
+ //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__code*)(non-pointer)'\n", ic->filename, ic->lineno);
+ tag = GPTR_TAG_CODE;
+ } else if (IS_PTR(rtype)) {
+ PERFORM_ONCE(weirdcast,
+ fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assumimg __data space\n", ic->filename, ic->lineno);
+ );
+ tag = GPTR_TAG_DATA;
+ } else {
+ PERFORM_ONCE(weirdcast,
+ fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assumimg __data space\n", ic->filename, ic->lineno);
+ );
+ tag = GPTR_TAG_DATA;
+ }
+
+ assert (AOP_SIZE(result) == 3);
+ /* zero-extend address... */
+ for (size = max; size < AOP_SIZE(result)-1; size++)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ /* ...and add tag */
+ pic16_movLit2f(pic16_popGet(AOP(result), AOP_SIZE(result)-1), tag);
+ } else if (IS_CODEPTR(restype) && AOP_SIZE(result) > max) {
+ //fprintf (stderr, "%s:%u: INFO: code pointer\n", ic->filename, ic->lineno);
+ for (size = max; size < AOP_SIZE(result)-1; size++)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), size));
+ /* add __code tag */
+ pic16_movLit2f (pic16_popGet(AOP(result), AOP_SIZE(result)-1), GPTR_TAG_CODE);
+ } else if (AOP_SIZE(result) > max) {
+ /* extend non-pointers */
+ //fprintf (stderr, "%s:%u: zero-extending value cast to pointer\n", ic->filename, ic->lineno);
+ pic16_addSign(result, max, 0);
+ } // if
+ goto release;
+ }
/* if they are the same size : or less */
if (AOP_SIZE(result) <= AOP_SIZE(right)) {
switch (p_type) {
case IPOINTER:
case POINTER:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
-// pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
+ case FPOINTER:
+ pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
break;
case CPOINTER:
pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
break;
- case FPOINTER:
- pic16_emitcode(";BUG!? ","%d",__LINE__);
- l = one;
- break;
case PPOINTER:
pic16_emitcode(";BUG!? ","%d",__LINE__);
l = "#0x03";
case GPOINTER:
if (GPTRSIZE > AOP_SIZE(right)) {
- // assume data pointer... THIS MIGHT BE WRONG!
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
+ // assume __data pointer... THIS MIGHT BE WRONG!
+ pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
} else {
pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
}