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 *);
+void pic16_genMult16X16_16(operand *, operand *, operand *);
+void pic16_genMult32X32_32(operand *, operand *, operand *);
pCode *pic16_AssembleLine(char *line, int peeps);
extern void pic16_printpBlock(FILE *of, pBlock *pb);
static asmop *newAsmop (short type);
short debugLine;
short nRegsSaved;
set *sendSet;
+ int interruptvector;
} _G;
/* Resolved ifx structure. This structure stores information
/*-----------------------------------------------------------------*/
static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
{
+
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
if(!resIfx)
return;
- // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
resIfx->condition = 1; /* assume that the ifx is true */
resIfx->generated = 0; /* indicate that the ifx has not been used */
if(!ifx) {
resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
-/*
+
+#if 1
DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
__FUNCTION__,__LINE__,resIfx->lbl->key);
-*/
+#endif
+
} else {
if(IC_TRUE(ifx)) {
resIfx->lbl = IC_TRUE(ifx);
*/
}
- // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+ DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
}
#if 0
return sym->aop;
}
+ /* if symbol was initially placed onStack then we must re-place it
+ * to direct memory, since pic16 does not have a specific stack */
+ if(sym->onStack) {
+ sym->onStack = 0;
+ SPEC_OCLS( sym->etype ) = data;
+ space = data;
+ }
+
+
+#if 1
/* assign depending on the storage class */
/* if it is on the stack or indirectly addressable */
/* space we need to assign either r0 or r1 to it */
if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
- DEBUGpic16_emitcode("; ***", "sum->onStack || sym->iaccess");
+ DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
+ __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
sym->aop = aop = newAsmop(0);
aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
aop->aopu.aop_stk = sym->stack;
return aop;
}
-
+#endif
+
if (sym->onStack && options.stack10bit)
{
/* It's on the 10 bit stack, which is located in
pCodeOp *pic16_popGetTempReg(void)
{
pCodeOp *pcop;
+ symbol *cfunc;
+
+// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ cfunc = currFunc;
+ currFunc = NULL;
pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
PCOR(pcop)->r->isFree=0;
/* push value on stack */
- pic16_pushpCodeOp( pcop );
+ pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
}
+ currFunc = cfunc;
+
return pcop;
}
/*-----------------------------------------------------------------*/
void pic16_popReleaseTempReg(pCodeOp *pcop)
{
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
PCOR(pcop)->r->isFree = 1;
- pic16_poppCodeOp( pcop );
+ pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
}
}
/*-----------------------------------------------------------------*/
/* push pcop into stack */
void pic16_pushpCodeOp(pCodeOp *pcop)
{
+// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
}
if(size>1) {
/* 16-bits, result in PRODL:WREG */
pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1)));
}
if(size>2) {
/* 24-bits, result in PRODH:PRODL:WREG */
pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
-
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2)));
}
if(size>3) {
/* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
-
-// pic16_emitpcode(POC_MOVFF,
-// pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3)));
}
} else {
/* >32-bits, result on stack, and FSR0 points to beginning.
pic16_emitcode("dec","%s",spname);
}
+#if 0
/* if register bank was saved then pop them */
if (ic->bankSaved)
unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
/* if we hade saved some registers then unsave them */
if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
unsaveRegisters (ic);
+#endif
}
// FIXME Disabled writes to PCLATU because of gpsim problems
#if 0
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
+#else
+ fprintf(stderr,
+"WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
+Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
#endif
+
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
// note: MOVFF to PCL not allowed
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
{
symbol *sym;
sym_link *ftype;
-
+
DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
labelOffset += (max_key+4);
ftype = operandType(IC_LEFT(ic));
sym = OP_SYMBOL(IC_LEFT(ic));
- if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) {
+ if(IFFUNC_ISISR(sym->type /*ftype*/)) {
/* create an absolute section at the interrupt vector:
- * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */
- int ivec;
+ * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
symbol *asym;
char asymname[128];
-
+ pBlock *apb;
+
{
int i, found=-1;
sym = OP_SYMBOL( IC_LEFT(ic));
for(i=0;i<=2;i++) {
-// fprintf(stderr, "comparing name int %d\t%s with %s\n",
-// i, interrupts[i]->name, sym->name);
if(interrupts[i]->name
&& !STRCASECMP(interrupts[i]->name, sym->name)) {
found = i;
if(found == -1) {
fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
__FILE__, __LINE__, sym->name);
- exit(-1);
+ assert( 0 );
}
- ivec = found;
+ _G.interruptvector = found;
}
- sprintf(asymname, "ivec_%d_%s", ivec, sym->name);
+
+ sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
asym = newSymbol(asymname, 0);
- pic16_emitcode(";","-----------------------------------------");
- pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name);
- pic16_emitcode(";","-----------------------------------------");
- pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name));
- pic16_pBlockConvert2Absolute(pb);
+ apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
+ pic16_addpBlock( apb );
- pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname ));
+ pic16_addpCode2pBlock(apb,
+ pic16_newpCodeCharP(";-----------------------------------------"));
+
+
+ pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+
+ pic16_addpCode2pBlock(apb,
+ pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
/* mark the end of this tiny function */
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+ pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
{
absSym *abSym;
abSym = Safe_calloc(1, sizeof(absSym));
abSym->name = Safe_strdup( asymname );
- switch( ivec ) {
+ switch( _G.interruptvector ) {
case 0: abSym->address = 0x000000; break;
case 1: abSym->address = 0x000008; break;
case 2: abSym->address = 0x000018; break;
pic16_emitcode("","%s:",sym->rname);
pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
+
{
absSym *ab;
pic16_pBlockConvert2Absolute(pb);
break;
}
-
+
}
if (IFFUNC_ISISR(sym->type)) {
int i;
/* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ if(!(_G.interruptvector == 1)) {
+
+ /* do not save WREG,STATUS,BSR for high priority interrupts
+ * because they are stored in the hardware shadow registers already */
+
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ }
+
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
- pic16_pBlockConvert2ISR(pb);
+// pic16_pBlockConvert2ISR(pb);
/* if any registers used */
if (sym->regsUsed) {
// fprintf(stderr, "function name: %s\n", sym->name);
if(strcmp(sym->name, "main")) {
- if(!options.ommitFramePtr || sym->regsUsed) {
+ if(/*!options.ommitFramePtr || */sym->regsUsed) {
/* setup the stack frame */
pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
/* if callee-save to be used for this function
* then save the registers being used in this function */
- if (IFFUNC_CALLEESAVES(sym->type)) {
+// if (IFFUNC_CALLEESAVES(sym->type))
+ {
int i;
-
-// fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
-
+
+// fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
+
+// pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+
/* if any registers used */
if (sym->regsUsed) {
/* save the registers used */
DEBUGpic16_emitcode("; **", "Saving used registers in stack");
for ( i = 0 ; i < sym->regsUsed->size ; i++) {
if (bitVectBitValue(sym->regsUsed,i)) {
+
// fprintf(stderr, "%s:%d function %s uses register %s\n",
// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
// pic16_regWithIdx(i)->name);
pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+
// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
// &pic16_pc_postdec1, 0));
+
_G.nRegsSaved++;
}
}
}
#endif
- /* restore the register bank */
- if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
- pic16_emitcode ("pop","psw");
-
if (IFFUNC_ISISR(sym->type)) {
-
/* now we need to restore the registers */
-
/* if any registers used */
if (sym->regsUsed) {
int i;
DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
for ( i = sym->regsUsed->size; i >= 0; i--) {
if (bitVectBitValue(sym->regsUsed,i)) {
-// fprintf(stderr, "%s:%d function %s uses register %s\n",
+
+// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
// pic16_regWithIdx(i)->name);
-
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
- &pic16_pc_preinc1,
- PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+ pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+
+// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+// &pic16_pc_preinc1,
+// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
}
}
}
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+
+ if(!(_G.interruptvector == 1)) {
+ /* do not restore interrupt vector for WREG,STATUS,BSR
+ * for high priority interrupt, see genFunction */
+
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ }
+ _G.interruptvector = 0; /* sanity check */
+
+// pic16_pBlockConvert2ISR(pb);
+
/* if debug then send end of function */
/* if (options.debug && currFunc) */
_G.debugLine = 0;
}
-#if 0
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
- pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
- pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
- pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
-#endif
-
pic16_emitpcodeNULLop(POC_RETFIE);
- }
- else {
+ } else {
if (IFFUNC_ISCRITICAL(sym->type))
pic16_emitcode("setb","ea");
- /* if any registers used */
- if (sym->regsUsed) {
- int i;
- /* save the registers used */
- DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
- for ( i = sym->regsUsed->size; i >= 0; i--) {
- if (bitVectBitValue(sym->regsUsed,i)) {
-// fprintf(stderr, "%s:%d function %s uses register %s\n",
-// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-// pic16_regWithIdx(i)->name);
-
- pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
- &pic16_pc_preinc1,
- PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+// pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ int i;
+ /* save the registers used */
+ DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+ for ( i = sym->regsUsed->size; i >= 0; i--) {
+ if (bitVectBitValue(sym->regsUsed,i)) {
+
+// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
+// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+// pic16_regWithIdx(i)->name);
+
+ pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+
+// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+// &pic16_pc_preinc1,
+// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+ _G.nRegsSaved--;
+ }
}
}
- }
+ pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
+ /* if debug then send end of function */
+ if (currFunc) {
+ _G.debugLine = 1;
+ pic16_emitcode(";","C$%s$%d$%d$%d ==.",
+ FileBaseName(ic->filename),currFunc->lastLine,
+ ic->level,ic->block);
+ if (IS_STATIC(currFunc->etype))
+ pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
+ else
+ pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
+ _G.debugLine = 0;
+ }
- /* if debug then send end of function */
- if (currFunc) {
- _G.debugLine = 1;
- pic16_emitcode(";","C$%s$%d$%d$%d ==.",
- FileBaseName(ic->filename),currFunc->lastLine,
- ic->level,ic->block);
- if (IS_STATIC(currFunc->etype))
- pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
- else
- pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
- _G.debugLine = 0;
- }
-
- /* insert code to restore stack frame, if user enabled it
- * and function is not main() */
+ /* insert code to restore stack frame, if user enabled it
+ * and function is not main() */
- if(strcmp(sym->name, "main")) {
- if(!options.ommitFramePtr || sym->regsUsed) {
- /* restore stack frame */
- if(STACK_MODEL_LARGE)
+
+ if(strcmp(sym->name, "main")) {
+ if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
+ /* restore stack frame */
+ if(STACK_MODEL_LARGE)
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
- pic16_emitpcode(POC_MOVFF,
- pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+ pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+ }
}
- }
- pic16_emitcode ("return","");
- pic16_emitpcodeNULLop(POC_RETURN);
+ pic16_emitcode ("return","");
+ pic16_emitpcodeNULLop(POC_RETURN);
- /* Mark the end of a function */
- pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
- }
+ /* Mark the end of a function */
+ pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+ }
}
/*-----------------------------------------------------------------*/
static void genLabel (iCode *ic)
{
+
+
/* special case never generate */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (IC_LABEL(ic) == entryLabel)
operand *right,
operand *result)
{
- sym_link *opetype = operandType(result);
-
- // symbol *lbl ;
- int size,offset;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
left = t;
}
- size = AOP_SIZE(result);
- if(size == 1) {
+ /* size is already checked in genMult == 1 */
+// size = AOP_SIZE(result);
- if (AOP_TYPE(right) == AOP_LIT){
- pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
- pic16_aopGet(AOP(result),0,FALSE,FALSE));
- } else {
- pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
- pic16_aopGet(AOP(result),0,FALSE,FALSE));
- }
- pic16_genMult8X8_8 (left, right,result);
- } else { // (size > 1)
+ if (AOP_TYPE(right) == AOP_LIT){
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ } else {
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ }
+
+ pic16_genMult8X8_8 (left, right,result);
+
+#if 0
pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
pic16_aopGet(AOP(right),0,FALSE,FALSE),
pic16_aopGet(AOP(left),0,FALSE,FALSE),
pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
//pic16_aopPut(AOP(result),"a",offset++);
}
+#endif
+
+
}
+/*-----------------------------------------------------------------*/
+/* genMultOneWord : 16 bit multiplication */
+/*-----------------------------------------------------------------*/
+static void genMultOneWord (operand *left,
+ operand *right,
+ operand *result)
+{
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+ DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
+
+ /* (if two literals, the value is computed before)
+ * if one literal, literal on the right */
+ if (AOP_TYPE(left) == AOP_LIT){
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ /* size is checked already == 2 */
+// size = AOP_SIZE(result);
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ } else {
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ }
+
+ pic16_genMult16X16_16(left, right,result);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMultOneLong : 32 bit multiplication */
+/*-----------------------------------------------------------------*/
+static void genMultOneLong (operand *left,
+ operand *right,
+ operand *result)
+{
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+ DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
+
+ /* (if two literals, the value is computed before)
+ * if one literal, literal on the right */
+ if (AOP_TYPE(left) == AOP_LIT){
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ /* size is checked already == 4 */
+// size = AOP_SIZE(result);
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ } else {
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ }
+
+ pic16_genMult32X32_32(left, right,result);
+}
+
+
+
/*-----------------------------------------------------------------*/
/* genMult - generates code for multiplication */
/*-----------------------------------------------------------------*/
static void genMult (iCode *ic)
{
- operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign the amsops */
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign the amsops */
+ pic16_aopOp (left,ic,FALSE);
+ pic16_aopOp (right,ic,FALSE);
+ pic16_aopOp (result,ic,TRUE);
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
- /* special cases first */
- /* both are bits */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right)== AOP_CRY) {
- genMultbits(left,right,result);
- goto release ;
- }
+ /* special cases first *
+ * both are bits */
+ if (AOP_TYPE(left) == AOP_CRY
+ && AOP_TYPE(right)== AOP_CRY) {
+ genMultbits(left,right,result);
+ goto release ;
+ }
- /* if both are of size == 1 */
- if (AOP_SIZE(left) == 1 &&
- AOP_SIZE(right) == 1 ) {
- genMultOneByte(left,right,result);
- goto release ;
- }
+ /* if both are of size == 1 */
+ if(AOP_SIZE(left) == 1
+ && AOP_SIZE(right) == 1) {
+ genMultOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 2 */
+ if(AOP_SIZE(left) == 2
+ && AOP_SIZE(right) == 2) {
+ genMultOneWord(left, right, result);
+ goto release;
+ }
+
+ /* if both are of size == 4 */
+ if(AOP_SIZE(left) == 4
+ && AOP_SIZE(right) == 4) {
+ genMultOneLong(left, right, result);
+ goto release;
+ }
+
+ pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
- pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
- /* should have been converted to function call */
+ fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+ /* should have been converted to function call */
assert(0) ;
release :
- pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genSkipc(resolvedIfx *rifx)
{
+ DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
+
if(!rifx)
return;
else
emitSKPNC;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
rifx->generated = 1;
}
/*-----------------------------------------------------------------*/
static void genSkipz2(resolvedIfx *rifx, int invert_condition)
{
+ DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
+
if(!rifx)
return;
end the carry flag is set then we know that
left is greater than right */
- // {
-
symbol *lbl = newiTempLabel(NULL);
+#if 0
+ fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
+ __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
+#endif
+
#ifndef _swapp
if(AOP_TYPE(right) == AOP_LIT) {
pic16_emitpLabel(lbl->key);
+// pic16_emitpLabel(truelbl->key);
//if(emitFinalCheck)
genSkipc(&rFalseIfx);
if(sign)
pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
} else {
/* this byte of the lit is zero,
- *if it's not the last then OR in the variable */
+ * if it's not the last then OR in the variable */
if(size)
pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
}
pic16_emitpLabel(lbl->key);
rFalseIfx.condition ^= 1;
+
genSkipc(&rFalseIfx);
}
int res_offset = 0; /* the result may be a different size then left or right */
int res_size = AOP_SIZE(result);
resolvedIfx rIfx;
- symbol *lbl;
+ symbol *lbl, *lbl_done;
unsigned long lit = 0L;
+ int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
if(result)
DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
resolveIfx(&rIfx,ifx);
lbl = newiTempLabel(NULL);
+ lbl_done = newiTempLabel(NULL);
/* if the left side is a literal or
if(AOP_TYPE(right) == AOP_LIT)
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ if ( regsInCommon(left, result) || regsInCommon(right, result) )
+ preserve_result = 1;
+
+ if(result && !preserve_result)
+ {
+ int i;
+ for(i = 0; i < AOP_SIZE(result); i++)
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+ }
+
+
/* if the right side is a literal then anything goes */
if (AOP_TYPE(right) == AOP_LIT &&
AOP_TYPE(left) != AOP_DIR ) {
switch(size) {
case 2:
genc16bit2lit(left, lit, 0);
- emitSKPNZ;
+ emitSKPZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
break;
default:
pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
}
- emitSKPNZ;
+ emitSKPZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
offset++;
if(res_offset < res_size-1)
int lbl_key = lbl->key;
if(result) {
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
+ // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
//pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
}else {
DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
__FUNCTION__,__LINE__);
return;
}
-
+
/* switch(size) { */
/* case 2: */
/* genc16bit2lit(left, lit, 0); */
break;
case 1:
pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
+ //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
emit_skip=0;
break;
case 0xff:
}
}
- pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
+ if(result && preserve_result)
+ {
+ int i;
+ for(i = 0; i < AOP_SIZE(result); i++)
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+ }
+
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
+
+ if(result && preserve_result)
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
+
if(!rIfx.condition)
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
pic16_emitpLabel(lbl->key);
+ if(result && preserve_result)
+ {
+ int i;
+ for(i = 0; i < AOP_SIZE(result); i++)
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
+
+ pic16_emitpLabel(lbl_done->key);
+ }
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(ifx)
}
+#if 0
+ /* the code below is completely untested
+ * it just allows ulong2fs.c compile -- VR */
+
+ ic = ic->next;
+ fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
+ __FILE__, __FUNCTION__, __LINE__);
+
+ /* if this has register type condition and
+ the next instruction is ifx with the same operand
+ and live to of the operand is upto the ifx only then */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key &&
+ OP_SYMBOL(op)->liveTo <= ic->next->seq )
+ return ic->next;
+
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key) {
+ DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
+ return ic->next;
+ }
+
+ fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
+ __FILE__, __FUNCTION__, __LINE__);
+
+// return ic->next->next; /* this just might work */ /* FIXME FIXME */
+#endif
return NULL;
}
/*-----------------------------------------------------------------*/
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");
pic16_aopOp(right,ic,FALSE);
size = AOP_SIZE(right);
- fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
-#if 1
+// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+
+#if 0
if ( AOP_TYPE(result) == AOP_PCODE) {
fprintf(stderr,"genDataPointerSet %s, %d\n",
AOP(result)->aopu.pcop->name,
}
if(options.iCodeInAsm) {
+ char *l;
/* insert here code to print iCode as comment */
- pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic));
+ l = Safe_strdup(printILine(ic));
+ pic16_emitpcomment("ic:%d: %s", ic->seq, l);
}
/* if the result is marked as