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)
+ Bug Fixes - Raphael Neider <rneider AT 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
/* 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))
+#define IS_DIRECT(op) ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR))
+
+/* 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 *);
{
va_list ap;
char lb[INITIAL_INLINEASM];
- unsigned char *lbp = lb;
+ unsigned char *lbp = (unsigned char *)lb;
va_start(ap,fmt);
{
va_list ap;
char lb[INITIAL_INLINEASM];
- unsigned char *lbp = lb;
+ unsigned char *lbp = (unsigned char *)lb;
if(!pic16_debug_verbose)
return;
bool fsr0iu = FALSE, fsr0ou;
bool fsr2iu = FALSE, fsr2ou;
- fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
+ //fprintf(stderr, "%s:%s:%d: getting free ptr from ic = %c result: %d\n", __FILE__, __FUNCTION__, __LINE__, ic->op, result);
fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
(*aopp)->type = AOP_FSR0;
- fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
+ //fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
}
for(i=0;i<aop->size;i++) {
/* initialise for stack access via frame pointer */
- // operands on stack are accessible via "FSR2 + index" with index
+ // operands on stack are accessible via "{FRAME POINTER} + index" with index
// starting at 2 for arguments and growing from 0 downwards for
// local variables (index == 0 is not assigned so we add one here)
{
}
/* if it is in direct space */
if (IN_DIRSPACE(space)) {
- sym->aop = aop = newAsmop (AOP_DIR);
- aop->aopu.aop_dir = sym->rname ;
- aop->size = getSize(sym->type);
- DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
- pic16_allocDirReg( IC_LEFT(ic) );
- return aop;
- }
-
+ if(!strcmp(sym->rname, "_WREG")) {
+ sym->aop = aop = newAsmop (AOP_ACC);
+ aop->size = getSize(sym->type); /* should always be 1 */
+ assert(aop->size == 1);
+ DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size);
+ return (aop);
+ } else {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
+ pic16_allocDirReg( IC_LEFT(ic) );
+ return (aop);
+ }
+ }
if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
sym->aop = aop = newAsmop (AOP_DIR);
/*-----------------------------------------------------------------*/
/* aopForRemat - rematerialzes an object */
/*-----------------------------------------------------------------*/
-static asmop *aopForRemat (operand *op) // x symbol *sym)
+static asmop *aopForRemat (operand *op, bool result) // x symbol *sym)
{
symbol *sym = OP_SYMBOL(op);
operand *refop;
DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
}
+// if(!result) /* fixme-vr */
for (;;) {
oldic = ic;
/* rematerialize it NOW */
if (sym->remat) {
- sym->aop = op->aop = aop = aopForRemat (op);
+ sym->aop = op->aop = aop = aopForRemat (op, result);
// aop->size = getSize(sym->type);
// DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
return;
return rs;
case AOP_REG:
- //if (dname)
- // return aop->aopu.aop_reg[offset]->dname;
- //else
- return aop->aopu.aop_reg[offset]->name;
+ return aop->aopu.aop_reg[offset]->name;
case AOP_CRY:
- //pic16_emitcode(";","%d",__LINE__);
return aop->aopu.aop_dir;
case AOP_ACC:
return (rs);
case AOP_LIT:
- sprintf(s,"0X%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
+ sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
rs = Safe_calloc(1,strlen(s)+1);
strcpy(rs,s);
return rs;
// return "acc";
if(!strcmp(aop->aopu.aop_str[offset], "WREG")) {
aop->type = AOP_ACC;
- return Safe_strdup("WREG");
+ return Safe_strdup("_WREG");
}
DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
/*-----------------------------------------------------------------*/
pCodeOp *pic16_popGetTempReg(int lock)
{
- pCodeOp *pcop;
+ pCodeOp *pcop=NULL;
symbol *cfunc;
// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
cfunc = currFunc;
currFunc = NULL;
+#if 0
+ {
+ regs *rr;
+ int i;
+
+ /* this code might seem better but it does the *same* job with
+ * the old code, it all depends on ralloc.c to get a free/unused
+ * register */
+
+ i=0;
+ while(i < pic16_nRegs) {
+ rr = pic16_typeRegWithIdx(i, REG_GPR, 0);
+ fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr);
+ if((!rr || (rr && rr->isFree))
+ && !bitVectBitValue(cfunc->regsUsed, i)) {
+ pcop = pic16_newpCodeOpReg( i );
+ PCOR(pcop)->r->wasUsed = 1;
+ PCOR(pcop)->r->isFree = 0;
+ break;
+ }
+ i++;
+ }
+
+ if(pcop) {
+ pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+ }
+ }
+#else
pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
PCOR(pcop)->r->wasUsed=1;
/* push value on stack */
pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
}
+#endif
currFunc = cfunc;
/*-----------------------------------------------------------------*/
/* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
/*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetLabel(unsigned int key)
+pCodeOp *pic16_popGetLabel(int key)
{
DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
return pic16_newpCodeOpLit(lit);
}
+/* Allow for 12 bit literals (LFSR x, <here!>). */
+pCodeOp *pic16_popGetLit12(int lit)
+{
+ return pic16_newpCodeOpLit12(lit);
+}
+
/*-----------------------------------------------------------------*/
/* pic16_popGetLit2 - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
//pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
+// PCOR(pcop)->r->wasUsed = 1;
/* make sure that register doesn't exist,
* and operand isn't NULL
// __FUNCTION__, __LINE__, str, size, offset);
PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
- fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
+ //fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
}
PCOR(pcop)->instance = offset;
pCodeOp *pcop;
// DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
-
+// fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx);
+
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
PCOR(pcop)->rIdx = rIdx;
PCOR(pcop)->r = pic16_regWithIdx(rIdx);
-
+ if(!PCOR(pcop)->r)
+ PCOR(pcop)->r = pic16_allocWithIdx(rIdx);
+
PCOR(pcop)->r->isFree = 0;
PCOR(pcop)->r->wasUsed = 1;
/*-----------------------------------------------------------------*/
pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
{
- //char *s = buffer ;
- char *rs;
+// char *s = buffer ;
+// char *rs;
pCodeOp *pcop;
- FENTRY2;
- /* offset is greater than
- size then zero */
+ FENTRY2;
+ /* offset is greater than
+ * size then zero */
// if (offset > (aop->size - 1) &&
// aop->type != AOP_LIT)
/* depending on type */
switch (aop->type) {
-
- case AOP_R0:
- case AOP_R1:
- case AOP_DPTR:
- case AOP_DPTR2:
- DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
- fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
- assert( 0 );
- return NULL;
-
-
- case AOP_FSR0:
- case AOP_FSR2:
- pcop = Safe_calloc(1, sizeof(pCodeOpReg));
- PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
- PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
- PCOR(pcop)->r->wasUsed = 1;
- PCOR(pcop)->r->isFree = 0;
+ case AOP_R0:
+ case AOP_R1:
+ case AOP_DPTR:
+ case AOP_DPTR2:
+ DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
+ fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
+ assert( 0 );
+ return NULL;
+
+ case AOP_FSR0:
+ case AOP_FSR2:
+ pcop = Safe_calloc(1, sizeof(pCodeOpReg));
+ PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
+ PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
+ PCOR(pcop)->r->wasUsed = 1;
+ PCOR(pcop)->r->isFree = 0;
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
- return (pcop);
-
- case AOP_IMMD:
- DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
- return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
-
- case AOP_STA:
- /* pCodeOp is already allocated from aopForSym */
- DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
- pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
-
- return (pcop);
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+ return (pcop);
+
+ case AOP_IMMD:
+ DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
+ return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
+
+ case AOP_STA:
+ /* pCodeOp is already allocated from aopForSym */
+ DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
+ pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
+ return (pcop);
- case AOP_ACC:
- {
- int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
+ case AOP_ACC:
+ {
+ int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
- fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
+ fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
- DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
+ DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
- PCOR(pcop)->r->wasUsed=1;
- PCOR(pcop)->r->isFree=0;
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
-// rs = aop->aopu.aop_reg[offset]->name;
-// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
- return pcop;
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
+ return pcop;
// return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
// return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
// assert( 0 );
- }
+ }
case AOP_DIR:
- DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
+ DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir);
return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
#if 0
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
// pcop->type = PO_GPR_REGISTER;
PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
PCOR(pcop)->r->wasUsed=1;
PCOR(pcop)->r->isFree=0;
pcop->type = PCOR(pcop)->r->pc_type;
DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type));
- rs = aop->aopu.aop_reg[offset]->name;
- DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
+// rs = aop->aopu.aop_reg[offset]->name;
+// DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
return pcop;
}
}
}
+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)) {
symbol *sym;
sym = newSymbol( GSTACK_TEST_NAME , 0 );
- sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME);
+ sprintf(sym->rname, "%s", /*port->fun_prefix,*/ GSTACK_TEST_NAME);
// strcpy(sym->rname, GSTACK_TEST_NAME);
checkAddSym(&externs, sym);
}
void pic16_pushpCodeOp(pCodeOp *pcop)
{
// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec )));
if(pic16_options.gstack)
pic16_testStackOverflow();
{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(_G.resDirect)return;
+
if(is_LitAOp(aop)) {
pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
// pushaop(AOP(IC_LEFT(sic)), size);
- pic16_mov2w (AOP(IC_LEFT(sic)), size);
-
+ pic16_mov2w( AOP(IC_LEFT(sic)), size );
+
if(!_G.resDirect)
pushw();
}
/*-----------------------------------------------------------------*/
static void genPcall (iCode *ic)
{
- sym_link *ftype, *fntype;
+ sym_link *fntype;
int stackParms=0;
symbol *retlbl = newiTempLabel(NULL);
pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
FENTRY;
- ftype = OP_SYM_TYPE(IC_LEFT(ic));
fntype = operandType( IC_LEFT(ic) )->next;
/* if send set is not empty the assign */
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_intcon));
/* make the call by writing the pointer into pc */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
+ mov2fp(pic16_popCopyReg(&pic16_pc_pclatu), AOP(IC_LEFT(ic)), 2);
+ mov2fp(pic16_popCopyReg(&pic16_pc_pclath), AOP(IC_LEFT(ic)), 1);
// note: MOVFF to PCL not allowed
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
+ pic16_mov2w(AOP(IC_LEFT(ic)), 0);
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
/* if callee-save to be used for this function
* then save the registers being used in this function */
// if (IFFUNC_CALLEESAVES(sym->type))
- {
+ if(strcmp(sym->name, "main")) {
int i;
/* if any registers used */
if (sym->regsUsed) {
- /* save the registers used */
- DEBUGpic16_emitcode("; **", "Saving used registers in stack");
- pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i)) {
- pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
- _G.nRegsSaved++;
-
- if(!pic16_regWithIdx(i)->wasUsed) {
- fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
- __FILE__, __LINE__, pic16_regWithIdx(i)->name);
- pic16_regWithIdx(i)->wasUsed = 1;
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
+
+ if(!xinst) {
+ /* save the registers used */
+ DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+#if 0
+ fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i);
+#endif
+ pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+ _G.nRegsSaved++;
+
+ if(!pic16_regWithIdx(i)->wasUsed) {
+ fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0\n",
+ __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+ pic16_regWithIdx(i)->wasUsed = 1;
+ }
+ }
+ }
+ } else {
+
+ /* xinst */
+ DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers");
+ for(i=0;i<sym->regsUsed->size;i++) {
+ if(bitVectBitValue(sym->regsUsed, i)) {
+ _G.nRegsSaved++;
}
}
+
+// pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved)));
}
+
pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
+
}
}
}
}
- if (sym->regsUsed) {
+ if (strcmp(sym->name, "main") && sym->regsUsed) {
int i;
pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
}
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));
} else {
if (AOP_TYPE(left) == AOP_ACC) {
pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
- pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
} else {
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
- pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
}
}
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- pic16_emitcode("movf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+// pic16_emitcode("movf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movwf","%s",
+// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
break;
default:
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- pic16_emitcode("movlw","0x%x",t);
- pic16_emitcode("iorwf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+// pic16_emitcode("movlw","0x%x",t);
+// pic16_emitcode("iorwf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movwf","%s",
+// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
}
continue;
// and better if result is SFR
if (AOP_TYPE(left) == AOP_ACC) {
pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
- pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
} else {
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
- pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("iorwf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
}
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
}
}
/*-----------------------------------------------------------------*/
/* AccLsh - left shift accumulator by known count */
/*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
+static void AccLsh (int shCount, int doMask)
{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
switch(shCount){
pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
break;
}
-
- pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+ if (doMask) {
+ /* no masking is required in genPackBits */
+ pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+ }
}
/*-----------------------------------------------------------------*/
// l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
// MOVA(l);
/* shift left accumulator */
- //AccLsh(shCount); // don't comment out just yet...
+ //AccLsh(shCount, 1); // don't comment out just yet...
// pic16_aopPut(AOP(result),"a",offr);
switch(shCount) {
pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
/* shift left accumulator */
- AccLsh(shCount);
+ AccLsh(shCount, 1);
/* or with result */
/* back to result */
pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
operand *result,
iCode *ic)
{
- int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit));
+ int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit));
int size;
FENTRY;
iCode *ic,
int sign)
{
- int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit));
+ int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit));
int lsize,res_size;
pic16_freeAsmop(right,NULL,ic,TRUE);
/* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */
void pic16_loadFSR0(operand *op, int lit)
{
- if(OP_SYMBOL(op)->remat || is_LitOp( op )) {
- pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+ if((IS_SYMOP(op) && OP_SYMBOL(op)->remat) || is_LitOp( op )) {
+ if (AOP_TYPE(op) == AOP_LIT) {
+ /* handle 12 bit integers correctly */
+ unsigned int val = (unsigned int)floatFromVal(AOP(op)->aopu.aop_lit);
+ if ((val & 0x0fff) != val) {
+ fprintf (stderr, "WARNING: Accessing memory at 0x%x truncated to 0x%x.\n",
+ val, (val & 0x0fff) );
+ val &= 0x0fff;
+ }
+ pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetLit12(val)));
+ } else {
+ pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+ }
} else {
- assert (!OP_SYMBOL(op)->remat);
+ assert (!IS_SYMOP(op) || !OP_SYMBOL(op)->remat);
// set up FSR0 with address of result
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
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));
+ mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(ptr), 0);
+ mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(ptr), 1);
+ pic16_mov2w(AOP(ptr), 2);
pic16_callGenericPointerRW(doWrite, 1);
} else {
// data pointer (just 2 byte given)
#if 1
if((blen == 1) && (bstr < 8)
- && (!IS_PTR(operandType(left)) || PIC_IS_DATA_PTR(operandType(left)))) {
+ && (!IS_PTR(operandType(left)) || IS_DIRECT(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__);
op = (same ? pic16_popCopyReg(&pic16_pc_wreg) : pic16_popGet (AOP(result),0));
pic16_emitpcode(POC_CLRF, op);
- if(!IS_PTR(operandType(left))) {
+ if(!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
/* workaround to reduce the extra lfsr instruction */
pic16_emitpcode(POC_BTFSC,
pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
#endif
- if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) {
+ if (!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
// access symbol directly
pic16_mov2w (AOP(left), 0);
} else {
}
-static void genDataPointerGet(operand *left,
- operand *result,
- iCode *ic)
+static void genDataPointerGet(operand *left, operand *result, iCode *ic)
{
int size, offset = 0, leoffset=0 ;
// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
-#if 0
- /* The following tests may save a redudant movff instruction when
- * accessing unions */
-
- /* if they are the same */
- if (operandsEqu (left, result)) {
- DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
- goto release;
- }
-#endif
-
-#if 0
- /* if they are the same registers */
- if (pic16_sameRegs(AOP(left),AOP(result))) {
- DEBUGpic16_emitcode("; ***", "left and result registers are same");
- goto release;
- }
-#endif
-
#if 1
if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
}
#endif
-
-#if 0
- if ( AOP_TYPE(left) == AOP_PCODE) {
- fprintf(stderr,"genDataPointerGet %s, %d\n",
- AOP(left)->aopu.pcop->name,
- (AOP(left)->aopu.pcop->type == PO_DIR)?
- PCOR(AOP(left)->aopu.pcop)->instance:
- PCOI(AOP(left)->aopu.pcop)->offset);
- }
-#endif
-
if(AOP(left)->aopu.pcop->type == PO_DIR)
leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
} else { /* we need to get it byte by byte */
/* set up WREG:PRODL:FSR0L with address from left */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
-
+ mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(left), 0);
+ mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(left), 1);
+ pic16_mov2w(AOP(left), 2);
pic16_callGenericPointerRW(0, size);
assignResultValue(result, 1);
pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
} else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
+ mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(left), 0);
+ mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(left), 1);
+ mov2fp(pic16_popCopyReg(&pic16_pc_tblptru), AOP(left), 2);
}
while(size--) {
int offset = 0 ;
int rLen = 0 ;
int blen, bstr ;
+ int shifted_and_masked = 0;
+ unsigned long lit = (unsigned long)-1;
sym_link *retype;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
retype = getSpec(operandType(right));
if(AOP_TYPE(right) == AOP_LIT) {
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.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__);
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
- // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
- if(!IS_PTR(operandType(result))) {
+ if(!IS_PTR(operandType(result)) || IS_DIRECT(result)) {
/* workaround to reduce the extra lfsr instruction */
if(lit) {
pic16_emitpcode(POC_BSF,
return;
}
- /* move literal to W */
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
+ /* IORLW below is more efficient */
+ //pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & ((1UL << blen) - 1)) << bstr));
+ lit = (lit & ((1UL << blen) - 1)) << bstr;
+ shifted_and_masked = 1;
offset++;
} else
- if(IS_BITFIELD(retype)
+ if (IS_DIRECT(result) && !IS_PTR(operandType(result))
+ && IS_BITFIELD(retype)
&& (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
&& (blen == 1)) {
int rblen, rbstr;
rblen = SPEC_BLEN( retype );
rbstr = SPEC_BSTR( retype );
-
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));
if (blen != 8 || bstr != 0) {
// we need to combine the value with the old value
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
+ if(!shifted_and_masked)
+ {
+ 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));
+ DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
+ SPEC_BSTR(etype), SPEC_BLEN(etype));
- /* shift left acc */
- AccLsh(shCnt);
+ /* shift left acc, do NOT mask the result again */
+ AccLsh(shCnt, 0);
- /* using PRODH as a temporary register here */
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+ /* 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*/) {
+ if ((IS_SYMOP(result) && !IS_PTR(operandType (result)))
+ || IS_DIRECT(result)) {
/* access symbol directly */
pic16_mov2w (AOP(result), 0);
} else {
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 (!shifted_and_masked) {
+ pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+ } else {
+ /* We have the shifted and masked (literal) right value in `lit' */
+ if (lit != 0)
+ pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
+ }
} // if (blen != 8 || bstr != 0)
/* write new value back */
- if (IS_SYMOP(result) & !IS_PTR(operandType(result))) {
+ if ((IS_SYMOP(result) && !IS_PTR(operandType(result)))
+ || IS_DIRECT(result)) {
pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
} else {
pic16_derefPtr (result, p_type, 1, &fsr0_setup);
operand *result,
iCode *ic)
{
- int size, offset = 0, resoffset=0 ;
+ int size, offset = 0, resoffset=0 ;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_aopOp(right,ic,FALSE);
}
#endif
- if(AOP(result)->aopu.pcop->type == PO_DIR)
- resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
+ if(AOP(result)->aopu.pcop->type == PO_DIR)
+ resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
- while (size--) {
- if (AOP_TYPE(right) == AOP_LIT) {
- unsigned int lit;
-
- if(!IS_FLOAT(operandType( right )))
- lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
- else {
- union {
- unsigned long lit_int;
- float lit_float;
- } info;
+ while (size--) {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ unsigned int lit;
+
+ if(!IS_FLOAT(operandType( right )))
+ lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->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(IC_RIGHT(ic))->aopu.aop_lit);
- lit = info.lit_int;
- }
-
+ /* take care if literal is a float */
+ info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ lit = info.lit_int;
+ }
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
sym_link *ptype = operandType(result);
sym_link *resetype;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- retype= getSpec(operandType(right));
- resetype = getSpec(operandType(result));
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ retype= getSpec(operandType(right));
+ resetype = getSpec(operandType(result));
- pic16_aopOp(result,ic,FALSE);
+ pic16_aopOp(result,ic,FALSE);
- /* if the result is rematerializable &
- * in data space & not a bit variable */
+ /* if the result is rematerializable &
+ * in data space & not a bit variable */
- /* and result is not a bit variable */
- if (AOP_TYPE(result) == AOP_PCODE
-// && AOP_TYPE(result) == AOP_IMMD
- && DCL_TYPE(ptype) == POINTER
- && !IS_BITFIELD(retype)
- && !IS_BITFIELD(resetype)) {
-
- genDataPointerSet (right,result,ic);
- pic16_freeAsmop(result,NULL,ic,TRUE);
- return;
- }
+ /* and result is not a bit variable */
+ if (AOP_TYPE(result) == AOP_PCODE
+// && AOP_TYPE(result) == AOP_IMMD
+ && DCL_TYPE(ptype) == POINTER
+ && !IS_BITFIELD(retype)
+ && !IS_BITFIELD(resetype)) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_aopOp(right,ic,FALSE);
- DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
+ genDataPointerSet (right,result,ic);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
+ return;
+ }
- /* if bitfield then unpack the bits */
- if (IS_BITFIELD(resetype)) {
- genPackBits (resetype, result, right, NULL, POINTER);
- } else {
- /* we have can just get the values */
- int size = AOP_SIZE(right);
- int offset = 0 ;
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_aopOp(right,ic,FALSE);
+ DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
- pic16_loadFSR0(result, 0);
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--) {
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
- if (size) {
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
- } else {
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
- }
- } else { // no literal
- if(size) {
- pic16_emitpcode(POC_MOVFF,
- pic16_popGet2p(pic16_popGet(AOP(right),offset),
- pic16_popCopyReg(&pic16_pc_postinc0)));
- } else {
- pic16_emitpcode(POC_MOVFF,
- pic16_popGet2p(pic16_popGet(AOP(right),offset),
- pic16_popCopyReg(&pic16_pc_indf0)));
- }
- }
- offset++;
- }
- }
+ /* if bitfield then unpack the bits */
+ if (IS_BITFIELD(resetype)) {
+ genPackBits (resetype, result, right, NULL, POINTER);
+ } else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* now some housekeeping stuff */
- if (aop) {
- /* we had to allocate for this iCode */
- pic16_freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- * already in a pointer register, then
- * if size > 0 && this could be used again
- * we have to point it back to where it
- * belongs */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (AOP_SIZE(right) > 1
- && !OP_SYMBOL(result)->remat
- && ( OP_SYMBOL(result)->liveTo > ic->seq
- || ic->depth )) {
-
- int size = AOP_SIZE(right) - 1;
-
- while (size--)
- pic16_emitcode("decf","fsr0,f");
- //pic16_emitcode("dec","%s",rname);
+ pic16_loadFSR0(result, 0);
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ while (size--) {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+ if (size) {
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
+ } else {
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
}
+ } else { // no literal
+ if(size) {
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popGet2p(pic16_popGet(AOP(right),offset),
+ pic16_popCopyReg(&pic16_pc_postinc0)));
+ } else {
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popGet2p(pic16_popGet(AOP(right),offset),
+ pic16_popCopyReg(&pic16_pc_indf0)));
+ }
+ }
+
+ offset++;
}
+ }
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ pic16_freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ * already in a pointer register, then
+ * if size > 0 && this could be used again
+ * we have to point it back to where it
+ * belongs */
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (AOP_SIZE(right) > 1
+ && !OP_SYMBOL(result)->remat
+ && ( OP_SYMBOL(result)->liveTo > ic->seq
+ || ic->depth )) {
+
+ int size = AOP_SIZE(right) - 1;
+
+ while (size--)
+ pic16_emitcode("decf","fsr0,f");
+ //pic16_emitcode("dec","%s",rname);
+ }
+ }
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* done */
/* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
/* value of right+0 is placed on stack, which will be retrieved
- * by the support function this restoring the stack. The important
+ * by the support function thus restoring the stack. The important
* thing is that there is no need to manually restore stack pointer
* here */
pushaop(AOP(right), 0);
// starting at 2 for arguments and growing from 0 downwards for
// local variables (index == 0 is not assigned so we add one here)
{
- int soffs = OP_SYMBOL( IC_LEFT(ic))->stack;
- if (soffs <= 0) {
- assert (soffs < 0);
- soffs++;
- } // if
- DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs);
- pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF ));
- pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo));
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF ));
- pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi));
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1));
+ int soffs = OP_SYMBOL( IC_LEFT(ic))->stack;
+
+ if (soffs <= 0) {
+ assert (soffs < 0);
+ soffs++;
+ } // if
+
+ DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs);
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF ));
+ pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo));
+ pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF ));
+ pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi));
+ pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1));
}
goto release;
static void genAssign (iCode *ic)
{
operand *result, *right;
+ sym_link *restype, *rtype;
int size, offset,know_W;
unsigned long lit = 0L;
- result = IC_RESULT(ic);
- right = IC_RIGHT(ic) ;
+ result = IC_RESULT(ic);
+ right = IC_RIGHT(ic) ;
- FENTRY;
+ FENTRY;
- /* if they are the same */
- if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
- return ;
+ /* if they are the same */
+ if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
- /* reversed order operands are aopOp'ed so that result operand
- * is effective in case right is a stack symbol. This maneauver
- * allows to use the _G.resDirect flag later */
- pic16_aopOp(result,ic,TRUE);
- pic16_aopOp(right,ic,FALSE);
+ /* reversed order operands are aopOp'ed so that result operand
+ * is effective in case right is a stack symbol. This maneauver
+ * allows to use the _G.resDirect flag later */
+ pic16_aopOp(result,ic,TRUE);
+ pic16_aopOp(right,ic,FALSE);
- DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
+ DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
- /* if they are the same registers */
- if (pic16_sameRegs(AOP(right),AOP(result)))
- goto release;
+ /* if they are the same registers */
+ if (pic16_sameRegs(AOP(right),AOP(result)))
+ goto release;
- /* if the result is a bit */
- if (AOP_TYPE(result) == AOP_CRY) {
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE(right) == AOP_LIT) {
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
- pic16_popGet(AOP(result),0));
+ pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+ pic16_popGet(AOP(result),0));
- if (((int) operandLitValue(right)))
- pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- else
- pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- goto release;
- }
+ if (((int) operandLitValue(right)))
+ pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ else
+ pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+
+ goto release ;
+ }
- /* the right is also a bit variable */
- if (AOP_TYPE(right) == AOP_CRY) {
+ /* we need to or */
pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_toBoolean(right);
+ emitSKPZ;
pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
-
- pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
+ //pic16_aopPut(AOP(result),"a",0);
goto release ;
}
- /* we need to or */
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_toBoolean(right);
- emitSKPZ;
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
- //pic16_aopPut(AOP(result),"a",0);
- goto release ;
- }
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE(result);
+ offset = 0 ;
/* 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 )) || IS_FIXED(operandType(right))))
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
- else{
- union {
- unsigned long lit_int;
- float lit_float;
- } info;
-
+ if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right))))
+ {
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
- 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;
- }
+ /* 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,
// sizeof(unsigned long int), sizeof(float));
- 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_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);
-
- // set up table pointer
- if(is_LitOp(right)) {
-// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
- } else {
-// fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
- pic16_popCopyReg(&pic16_pc_tblptrl)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
- pic16_popCopyReg(&pic16_pc_tblptrh)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
- pic16_popCopyReg(&pic16_pc_tblptru)));
- }
+ 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;
+ }
- /* 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),
- pic16_popGet(AOP(result),offset)));
- offset++;
- }
+ /* 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_SYM_ETYPE(right)))
+ && !IS_FUNC(OP_SYM_TYPE(right))
+ && !IS_ITEMP(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--) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
- offset++;
- }
- }
- goto release;
- }
+ 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);
+
+ // set up table pointer
+ if(is_LitOp(right)) {
+// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
+ } else {
+// fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
+ pic16_popCopyReg(&pic16_pc_tblptrl)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
+ pic16_popCopyReg(&pic16_pc_tblptrh)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
+ pic16_popCopyReg(&pic16_pc_tblptru)));
+ }
- if (AOP_TYPE(right) == AOP_LIT && IS_SYMOP(result) && IS_GENPTR(OP_SYM_TYPE(result)))
- {
- /* Arrg -- a literal is cast into a generic pointer: how shall we decide which TAG
- * to assign (__data, __code, __eeprom, ???)??? */
- fprintf (stderr, "%s:%u(%s): creating generic pointer from literal defaults to __data TYPE*.\n\tPlease explicitly cast to (__data|__code) TYPE* in line %u if neccessary!\n",
- __FILE__, __LINE__, __FUNCTION__, ic->lineno);
- /* assume __data space */
- lit = (lit & 0x00ffff) | 0x800000;
- //exit (-1);
- }
+ /* 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),
+ pic16_popGet(AOP(result),offset)));
+ offset++;
+ }
+ /* 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--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
+ offset++;
+ }
+ }
+ goto release;
+ }
#if 0
-/* VR - What is this?! */
- if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(aopIdx(AOP(result),0) == 4) {
-
- /* this is a workaround to save value of right into wreg too,
- * value of wreg is going to be used later */
+ /* VR - What is this?! */
+ if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- goto release;
- } else
+
+ if(aopIdx(AOP(result),0) == 4) {
+ /* this is a workaround to save value of right into wreg too,
+ * value of wreg is going to be used later */
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ goto release;
+ } else
// assert(0);
DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
- }
+ }
#endif
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))
} else {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!_G.resDirect) /* use this aopForSym feature */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+ if(!_G.resDirect) { /* use this aopForSym feature */
+ if(AOP_TYPE(result) == AOP_ACC) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+ } else
+ if(AOP_TYPE(right) == AOP_ACC) {
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+ }
+ }
+ }
+
+ offset++;
}
-
- offset++;
- }
- release:
+release:
pic16_freeAsmop (right,NULL,ic,FALSE);
pic16_freeAsmop (result,NULL,ic,TRUE);
-}
+}
/*-----------------------------------------------------------------*/
/* genJumpTab - generates code for jump table */
}
/* port from pic14 to cope with generic pointers */
- if (IS_PTR(restype))
+ 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__);
- /* warn if we discard generic opinter tag */
- if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
- {
- //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
- } // if
-
max = size;
while (size--)
{
pic16_mov2w (AOP(right), size);
pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
} // while
- pic16_addSign(result, max, 0);
/* upcast into generic pointer type? */
- if (IS_GENPTR(restype) && !IS_GENPTR(rtype))
+ if (IS_GENPTR(restype)
+ && !PIC_IS_TAGGED(rtype)
+ && (AOP_SIZE(result) > max))
{
- //fprintf (stderr, "%s:%u: must determine pointer type (IS_PTR: %d, DCL_TYPE: %d)\n", __FUNCTION__, __LINE__, IS_PTR(rtype), IS_PTR(rtype) ? DCL_TYPE(rtype) : 0);
- if (IS_PTR(rtype))
- {
- switch (DCL_TYPE(rtype))
- {
- case POINTER: /* __data */
- case FPOINTER: /* __data */
- assert (AOP_SIZE(right) == 2);
- tag = 0x80;
- break;
-
- case CPOINTER: /* __code */
- assert (AOP_SIZE(right) == 2);
- tag = 0x00;
- break;
-
- case GPOINTER: /* unknown destination, __data or __code */
- assert (AOP_SIZE(right) == 3);
- /* tag taken from right operand */
- break;
-
- default:
- assert (!"unhandled pointer type");
- } // switch
+ /* 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 {
- /* convert other values into pointers to __data space */
- fprintf (stderr, "%s:%u(%s): creating generic pointer from non-pointer type -- assuming __data space\n", __FILE__, __LINE__, __FUNCTION__);
- tag = 0x80;
+ 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);
- if (tag == 0) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 2));
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(tag));
- pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), 2));
- }
+ /* 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;
}
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));
}
l = Safe_strdup(printILine(ic));
pic16_emitpcomment("ic:%d: %s", ic->seq, l);
}
-
+
/* if the result is marked as
* spilt and rematerializable or code for
* this has already been generated then