PIC port - Scott Dattalo scott@dattalo.com (2000)
PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
- Vangelis Rokas vrokas@otenet.gr (2003,2004,2005)
+ Bug Fixes - Raphael Neider rneider@web.de (2004,2005)
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
static asmop *newAsmop (short type);
static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
-static void mov2f(asmop *dst, asmop *src, int offset);
static void mov2fp(pCodeOp *dst, asmop *src, int offset);
static pCodeOp *pic16_popRegFromIdx(int rIdx);
pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
}
-void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* gen.h defines a macro pic16_emitpcode that allows for debug information to be inserted on demand
+ * NEVER call pic16_emitpcode_real directly, please... */
+void pic16_emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
{
if(pcop)
sym->usl.spillLoc->offset, op);
} else {
fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __FUNCTION__, __LINE__);
- DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
+ pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
assert (getSize(sym->type) <= 1);
aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);
}
pCodeOpReg *pcor;
pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcor->pcop.type = pc->pcop.type;
+ memcpy (pcor, pc, sizeof (pCodeOpReg));
+ pcor->r->wasUsed = 1;
+
+ //pcor->pcop.type = pc->pcop.type;
if(pc->pcop.name) {
if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
} else
pcor->pcop.name = NULL;
- pcor->r = pc->r;
- pcor->rIdx = pc->rIdx;
- pcor->r->wasUsed=1;
- pcor->instance = pc->instance;
+ //pcor->r = pc->r;
+ //pcor->rIdx = pc->rIdx;
+ //pcor->r->wasUsed=1;
+ //pcor->instance = pc->instance;
// DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
}
-static void mov2f(asmop *dst, asmop *src, int offset)
+void pic16_mov2f(asmop *dst, asmop *src, int offset)
{
if(is_LitAOp(src)) {
pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
size = AOP_SIZE(op);
while(size--) {
- mov2f(AOP(result), AOP(op), offset);
+ pic16_mov2f(AOP(result), AOP(op), offset);
offset++;
}
* wrapper segment at vector address. The user should take care for
* this instead. -- VR */
- if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) =! INTNO_UNSPEC)) {
+ if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) != INTNO_UNSPEC)) {
asym = newSymbol(asymname, 0);
apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
pic16_addpBlock( apb );
pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
- pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+ //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+ //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0)));
+ pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
/* mark the end of this tiny function */
pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
left = right;
right = dummy;
- performedLt ^= 1; // instead of "left < right" we check for "right >= left+1"
+ performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
} else if (isAOP_LIT(right)) {
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
} // if
pctemp = pic16_popGetTempReg(1);
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
}
-// }
if(ifx)ifx->generated = 1;
static void genInline (iCode *ic)
{
char *buffer, *bp, *bp1;
- char *cbuf;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
}
bp = bp1 = buffer;
- cbuf = Safe_strdup( buffer );
-
+#if 0
+ /* This is an experimental code for #pragma inline
+ and is temporarily disabled for 2.5.0 release */
if(asmInlineMap)
{
symbol *sym;
char *s;
+ char *cbuf;
int cblen;
cbuf = Safe_strdup(buffer);
bp = bp1 = buffer;
}
+#endif /* 0 */
/* emit each line as a code */
while (*bp) {
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
}
} else {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr));
}
default:
#endif
{
/* we don't know if left is a literal or a register, take care -- VR */
- mov2f(AOP(result), AOP(left), offset);
+ pic16_mov2f(AOP(result), AOP(left), offset);
}
offset++;
}
#if 1
/* this is already done, why change it? */
if (!pic16_sameRegs(AOP(left),AOP(result))) {
- mov2f(AOP(result), AOP(left), 0);
+ pic16_mov2f(AOP(result), AOP(left), 0);
}
#endif
} else {
/* we don't know if left is a literal or a register, take care -- VR */
- mov2f(AOP(result), AOP(left), offset);
+ pic16_mov2f(AOP(result), AOP(left), offset);
}
offset++;
}
tlbl = newiTempLabel(NULL);
if (!pic16_sameRegs(AOP(left),AOP(result))) {
- mov2f(AOP(result), AOP(left), 0);
+ pic16_mov2f(AOP(result), AOP(left), 0);
// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
if(sign) {
pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16));
}
}
if(shCount == 0){
assert (res_size <= lsize);
while (res_size--) {
- mov2f (AOP(result), AOP(left), res_size);
+ pic16_mov2f (AOP(result), AOP(left), res_size);
} // for
}
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
if(sign) {
pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
}
} else {
// (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20)
// This is fine, as it only occurs for left shifting with negative count which is not standardized!
for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) {
- mov2f (AOP(result),AOP(left), offset);
+ pic16_mov2f (AOP(result),AOP(left), offset);
} // for
// if result is longer than left, fill with zeros (or sign)
}
}
+/*----------------------------------------------------------------*/
+/* pic16_derefPtr - move one byte from the location ptr points to */
+/* to WREG (doWrite == 0) or one byte from WREG */
+/* to the location ptr points to (doWrite != 0) */
+/*----------------------------------------------------------------*/
+static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup)
+{
+ switch (p_type) {
+ case FPOINTER:
+ case POINTER:
+ if (!fsr0_setup || !*fsr0_setup)
+ {
+ pic16_loadFSR0( ptr, 0 );
+ if (fsr0_setup) *fsr0_setup = 1;
+ }
+ if (doWrite)
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+ else
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+ break;
+
+ case GPOINTER:
+ if (AOP(ptr)->aopu.aop_reg[2]) {
+ if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+ // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
+ pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+ pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),1), pic16_popCopyReg(&pic16_pc_prodl)));
+ pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(ptr),2));
+ pic16_callGenericPointerRW(doWrite, 1);
+ } else {
+ // data pointer (just 2 byte given)
+ if (!fsr0_setup || !*fsr0_setup)
+ {
+ pic16_loadFSR0( ptr, 0 );
+ if (fsr0_setup) *fsr0_setup = 1;
+ }
+ if (doWrite)
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+ else
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+ }
+ break;
+
+ default:
+ assert (0 && "invalid pointer type specified");
+ break;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
{
int shCnt ;
- int rlen = 0 ;
sym_link *etype, *letype;
int blen=0, bstr=0;
int lbstr;
- int offset = 0 ;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
etype = getSpec(operandType(result));
pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
// distinguish (p->bitfield) and p.bitfield, remat seems to work...
- if(OP_SYMBOL(left)->remat && (ptype == POINTER) && (result)) {
+ 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));
* optimization to handle single bit assignments is added
* to the function. Until then use the old safe way! -- VR */
- if (OP_SYMBOL(left)->remat) {
+ if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) {
// access symbol directly
pic16_mov2w (AOP(left), 0);
} else {
- pic16_loadFSR0( left, 0 );
-
- /* read the first byte */
- switch (ptype) {
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- case GPOINTER:
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
- break;
- case CPOINTER:
- pic16_emitcode("clr","a");
- pic16_emitcode("movc","a","@a+dptr");
- assert (0);
- break;
- }
+ pic16_derefPtr (left, ptype, 0, NULL);
}
/* if we have bitdisplacement then it fits */
fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
exit(-1);
- /* bit field did not fit in a byte */
- rlen = SPEC_BLEN(etype) - 8;
- pic16_aopPut(AOP(result),"a",offset++);
-
- while (1) {
-
- switch (ptype) {
- case POINTER:
- case IPOINTER:
- pic16_emitcode("inc","%s",rname);
- pic16_emitcode("mov","a,@%s",rname);
- break;
-
- case PPOINTER:
- pic16_emitcode("inc","%s",rname);
- pic16_emitcode("movx","a,@%s",rname);
- break;
-
- case FPOINTER:
- pic16_emitcode("inc","dptr");
- pic16_emitcode("movx","a,@dptr");
- break;
-
- case CPOINTER:
- pic16_emitcode("clr","a");
- pic16_emitcode("inc","dptr");
- pic16_emitcode("movc","a","@a+dptr");
- break;
-
- case GPOINTER:
- pic16_emitcode("inc","dptr");
- pic16_emitcode("lcall","__gptrget");
- break;
- }
-
- rlen -= 8;
- /* if we are done */
- if ( rlen <= 0 )
- break ;
-
- pic16_aopPut(AOP(result),"a",offset++);
-
- }
-
- if (rlen) {
- pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
- pic16_aopPut(AOP(result),"a",offset);
- }
-
return ;
}
// asmop *aop = NULL;
//regs *preg = NULL ;
sym_link *rtype, *retype;
- sym_link *ltype = operandType(left);
+ sym_link *ltype, *letype;
FENTRY;
rtype = operandType(result);
retype= getSpec(rtype);
+ ltype = operandType(left);
+ letype= getSpec(ltype);
pic16_aopOp(left,ic,FALSE);
}
#endif
-
- /* if the value is already in a pointer register
- * then don't need anything more */
- if (1 || !AOP_INPREG(AOP(left))) { // AOP_INPREG(AOP(left)) is not always correct...
- /* otherwise get a free pointer register */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- ;
- }
-
/* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype))
+ if (IS_BITFIELD(letype))
genUnpackBits (result, left, NULL, POINTER);
else {
/* we have can just get the values */
operand *result, iCode *ic)
{
int size, offset, lit;
- sym_link *retype = getSpec(operandType(result));
+ sym_link *letype = getSpec(operandType(left));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_aopOp(left,ic,FALSE);
size = AOP_SIZE(result);
DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
+
+ /* if bit then unpack */
+ if (IS_BITFIELD(letype)) {
+ genUnpackBits(result,left,"BAD",GPOINTER);
+ goto release;
+ }
if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
goto release;
}
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genUnpackBits(result,left,"BAD",GPOINTER);
-
release:
pic16_freeAsmop(left,NULL,ic,TRUE);
pic16_freeAsmop(result,NULL,ic,TRUE);
/* using PRODH as a temporary register here */
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
- if (OP_SYMBOL(result)->remat) {
- // access symbol directly
- pic16_mov2w (AOP(result), 0);
- } else {
- /* get old value */
- switch (p_type) {
- case FPOINTER:
- case POINTER:
- pic16_loadFSR0( result, 0 );
- fsr0_setup = 1;
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-// pic16_emitcode ("mov","b,a");
-// pic16_emitcode("mov","a,@%s",rname);
- break;
-
- case GPOINTER:
- if (AOP(result)->aopu.aop_reg[2]) {
- // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
- pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
- pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-
- pic16_callGenericPointerRW(0, 1);
- } else {
- // data pointer (just 2 byte given)
- pic16_loadFSR0( result, 0 );
- fsr0_setup = 1;
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
- }
-
- // warnings will be emitted below
- //pic16_emitpcomment ("; =?= genPackBits, GPOINTER...");
- //werror(W_POSSBUG2, __FILE__, __LINE__);
- break;
-
- default:
- assert (0 && "invalid pointer type specified");
- break;
+ 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)) |
} // if (blen != 8 || bstr != 0)
/* write new value back */
- if (OP_SYMBOL(result)->remat) {
- pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
- } else {
- switch (p_type) {
- case FPOINTER:
- case POINTER:
- if (!fsr0_setup) pic16_loadFSR0( result, 0 );
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
- break;
-
- case GPOINTER:
- if (AOP(result)->aopu.aop_reg[2]) {
- // prepare call to __gptrset1, this is actually genGenPointerSet(WREG, result, ?ic?)
- pic16_emitpcode (POC_MOVWF, pic16_popCopyReg (pic16_stack_postdec/*pic16_pc_postdec1*/));
- pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl)));
- pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2));
-
- pic16_callGenericPointerRW(1, 1);
- } else {
- // data pointer (just 2 byte given)
- if (!fsr0_setup) pic16_loadFSR0( result, 0 );
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
- }
-
- // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY)
- //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access");
- werror(W_POSSBUG2, __FILE__, __LINE__);
- break;
-
- default:
- assert (0 && "invalid pointer type specified");
- break;
- }
+ 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
pic16_aopOp(right,ic,FALSE);
DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
- /* if the value is already in a pointer register
- * then don't need anything more */
- if (1 || !AOP_INPREG(AOP(result))) { // AOP_INPREG(AOP(result)) is not always correct...
- /* otherwise get a free pointer register */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- ;
- }
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
/* if bitfield then unpack the bits */
if (IS_BITFIELD(resetype)) {
genPackBits (resetype, result, right, NULL, POINTER);
operand *result, iCode *ic)
{
int size;
- sym_link *retype = getSpec(operandType(right));
+ sym_link *retype = getSpec(operandType(result));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
-
/* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
/* value of right+0 is placed on stack, which will be retrieved
move it to the correct pointer register */
type = operandType(result);
etype = getSpec(type);
+
/* if left is of type of pointer then it is simple */
if (IS_PTR(type) && !IS_FUNC(type->next)) {
p_type = DCL_TYPE(type);
if (AOP_TYPE(right) == AOP_REG) {
DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__);
while (size--) {
-
pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++));
} // while
goto release;
}
+ /* when do we have to read the program memory?
+ * - if right itself is a symbol in code space
+ * (we don't care what it points to if it's a pointer)
+ * - AND right is not a function (we would want its address)
+ */
if(AOP_TYPE(right) != AOP_LIT
- && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+ && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right)))
&& !IS_FUNC(OP_SYM_TYPE(right))
- ) {
+ && !IS_ITEMP(right))
+ {
DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
pic16_popCopyReg(&pic16_pc_tblptru)));
}
- size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result));
+ /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */
+ size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result));
while(size--) {
pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
offset++;
}
- size = getSize(OP_SYM_ETYPE(right));
+ /* FIXME: for pointers we need to extend differently (according
+ * to pointer type DATA/CODE/EEPROM/... :*/
+ size = getSize(OP_SYM_TYPE(right));
if(AOP_SIZE(result) > size) {
size = AOP_SIZE(result) - size;
while(size--) {
while (size--) {
if(offset < AOP_SIZE(right)) {
DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
- mov2f(AOP(result), AOP(right), offset);
+ pic16_mov2f(AOP(result), AOP(right), offset);
/*
if ((AOP_TYPE(right) == AOP_PCODE) &&
AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
while (size--) {
if(!_G.resDirect)
- mov2f(AOP(result), AOP(right), offset);
+ pic16_mov2f(AOP(result), AOP(right), offset);
offset++;
}
/* Save one instruction of casting char to int */
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
} else {
pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));