static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
static void mov2w (asmop *aop, int offset);
-static int aopIdx (asmop *aop, int offset);
+//static int aopIdx (asmop *aop, int offset);
int pic16_labelOffset=0;
extern int pic16_debug_verbose;
short ipushRegs;
set *sendSet;
int interruptvector;
+ int usefastretfie;
} _G;
/* Resolved ifx structure. This structure stores information
fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
assert( 0 );
+ return NULL;
#if 0
/* the logic: if r0 & r1 used in the instruction
then we are in trouble otherwise */
return aop;
}
+#if 0
static int aopIdx (asmop *aop, int offset)
{
if(!aop)
return aop->aopu.aop_reg[offset]->rIdx;
}
+#endif
+
/*-----------------------------------------------------------------*/
/* regsInCommon - two operands have some registers in common */
/*-----------------------------------------------------------------*/
* save acc, b, dpl, dph */
if (IFFUNC_ISISR(sym->type)) {
int i;
+
+ _G.usefastretfie = 1; /* use shadow registers by default */
/* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
if(!(_G.interruptvector == 1)) {
/* do not save WREG,STATUS,BSR for high priority interrupts
* because they are stored in the hardware shadow registers already */
-
+ _G.usefastretfie = 0;
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
}
+
+ /* these should really be optimized somehow, because not all
+ * interrupt handlers modify them */
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
debugFile->writeEndFunction (currFunc, ic, 1);
}
+ if(_G.usefastretfie)
+ pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
+ else
pic16_emitpcodeNULLop(POC_RETFIE);
+ _G.usefastretfie = 0;
} else {
if (IFFUNC_ISCRITICAL(sym->type))
pic16_emitcode("setb","ea");
}
}
- pic16_emitcode ("return","");
pic16_emitpcodeNULLop(POC_RETURN);
/* Mark the end of a function */
} else {
symbol *tlbl = newiTempLabel(NULL);
int sizel = AOP_SIZE(left);
+
if(size)
- pic16_emitcode("setb","c");
- while(sizel--){
- if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+ emitSETC;
+
+ while(sizel--) {
+ if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
+
+ /* patch provided by Aaron Colwell */
+ if((posbit = isLiteralBit(bytelit)) != 0) {
+ pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
+ (posbit-1),0, PO_GPR_REGISTER));
+
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
+ } else {
+ if (bytelit == 0xff) {
+ /* Aaron had a MOVF instruction here, changed to MOVFW cause
+ * a peephole could optimize it out -- VR */
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
+ pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
+ }
+
+ pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
+ pic16_popGetLabel(tlbl->key));
+ }
+
+#if 0
+ /* old code, left here for reference -- VR 09/2004 */
MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
// byte == 2^n ?
if((posbit = isLiteralBit(bytelit)) != 0)
pic16_emitcode("anl","a,%s",
pic16_aopGet(AOP(right),offset,FALSE,TRUE));
pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
- }
+ }
+#endif
}
offset++;
}
// bit = left & literal
- if(size){
- pic16_emitcode("clr","c");
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ if(size) {
+ emitCLRC;
+ pic16_emitpLabel(tlbl->key);
}
// if(left & literal)
- else{
- if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- goto release ;
+ else {
+ if(ifx) {
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
+ pic16_emitpLabel(tlbl->key);
+ ifx->generated = 1;
+ }
+ goto release;
}
}
+
pic16_outBitC(result);
goto release ;
}
pic16_freeAsmop(result,NULL,ic,TRUE);
}
+
+void pic16_loadFSR0(operand *op)
+{
+ pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
+}
+
/*-----------------------------------------------------------------*/
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
-static void genUnpackBits (operand *result, char *rname, int ptype)
+static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
{
int shCnt ;
int rlen = 0 ;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
etype = getSpec(operandType(result));
+ /* 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 */
+ pic16_loadFSR0( left );
+
/* read the first byte */
switch (ptype) {
case POINTER:
pic16_freeAsmop(result,NULL,ic,TRUE);
}
-void pic16_loadFSR0(operand *op)
-{
- pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
-}
/*-----------------------------------------------------------------*/
&& ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
|| (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
{
- pic16_loadFSR0( left ); // patch 10
+ if(!IS_BITFIELD(retype))
+ pic16_loadFSR0( left ); // patch 10
} else {
// set up FSR0 with address from left
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genUnpackBits (result, NULL, POINTER);
+ genUnpackBits (result, left, NULL, POINTER);
else {
/* we have can just get the values */
int size = AOP_SIZE(result);
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genUnpackBits (result,rname,PPOINTER);
+ genUnpackBits (result,left,rname,PPOINTER);
else {
/* we have can just get the values */
int size = AOP_SIZE(result);
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genUnpackBits(result,"dptr",FPOINTER);
+ genUnpackBits(result,left,"dptr",FPOINTER);
else {
size = AOP_SIZE(result);
offset = 0 ;
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genUnpackBits(result,"dptr",CPOINTER);
+ genUnpackBits(result,left,"dptr",CPOINTER);
else {
size = AOP_SIZE(result);
offset = 0 ;
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genUnpackBits(result,"BAD",GPOINTER);
+ genUnpackBits(result,left,"BAD",GPOINTER);
release:
pic16_freeAsmop(left,NULL,ic,TRUE);
/*-----------------------------------------------------------------*/
/* genPackBits - generates code for packed bit storage */
/*-----------------------------------------------------------------*/
-static void genPackBits (sym_link *etype ,
+static void genPackBits (sym_link *etype , operand *result,
operand *right ,
char *rname, int p_type)
{
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
// pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
- if(lit) {
- pic16_emitpcode(POC_BSF,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+ if((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_emitpcode(POC_BCF,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+
+ 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;
&& ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
|| (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
{
+ if(!IS_BITFIELD(resetype))
pic16_loadFSR0( result ); // patch 10
} else {
// set up FSR0 with address of result
/* if bitfield then unpack the bits */
if (IS_BITFIELD(resetype)) {
- genPackBits (resetype, right, NULL, POINTER);
+ genPackBits (resetype, result, right, NULL, POINTER);
} else {
/* we have can just get the values */
int size = AOP_SIZE(right);
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genPackBits (retype,right,rname,PPOINTER);
+ genPackBits (retype,result,right,rname,PPOINTER);
else {
/* we have can just get the values */
int size = AOP_SIZE(right);
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genPackBits(retype,right,"dptr",FPOINTER);
+ genPackBits(retype,result,right,"dptr",FPOINTER);
else {
size = AOP_SIZE(right);
offset = 0 ;
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genPackBits(retype,right,"dptr",GPOINTER);
+ genPackBits(retype,result,right,"dptr",GPOINTER);
else {
size = AOP_SIZE(right);
offset = 0 ;
if(AOP_TYPE(right) != AOP_LIT
&& IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) {
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( (AOP_TYPE(right) == AOP_PCODE)
&& ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
|| (AOP(right)->aopu.pcop->type == PO_DIR)))
{
+ 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_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),
+#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__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(aopIdx(AOP(result),0) == 4) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- assert(0);
+
+ /* 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;
// assert(0);
DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
}
+#endif
know_W=-1;
while (size--) {