#include "pcode.h"
#include "gen.h"
-
extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
void genMult8X8_8 (operand *, operand *,operand *);
unsigned int pic14aopLiteral (value *val, int offset);
const char *AopType(short type);
-#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
+#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff)
/* this is the down and dirty file with all kinds of
kludgy & hacky stuff. This is what it is all about
unsigned fReturnSizePic = 4; /* shared with ralloc.c */
static char **fReturn = fReturnpic14;
-static char *accUse[] = {"a","b"};
+//static char *accUse[] = {"a","b"};
//static short rbank = -1;
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
- if(!debug_verbose)
+ if(!debug_verbose && !options.debug)
return;
va_start(ap,fmt);
va_end(ap);
}
+static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
+{
+#if defined (HAVE_VSNPRINTF)
+ vsnprintf (buf, size, fmt, ap);
+#elif defined (HAVE_VSPRINTF)
+ vsprintf (buf, size, fmt, ap);
+ if (strlen (buf) >= size)
+ {
+ fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
+ }
+#elif defined (HAVE_SNPRINTF)
+ snprintf (buf, size, "vs(n)printf required");
+#elif defined (HAVE_SRINTF)
+ sprintf (buf, "vs(n)printf required");
+ if (strlen (buf) >= size)
+ {
+ fprintf (stderr, "Safe_vsnprintf: buffer (size %u) has overflown\n", size);
+ }
+#else
+ assert ( !"neither vsnprintf nor vsprintf is present -- unable to proceed" );
+#endif
+}
+
+void emitpComment (const char *fmt, ...)
+{
+ va_list va;
+ char buffer[4096];
+
+ va_start (va, fmt);
+ if (pb) {
+ Safe_vsnprintf (buffer, 4096, fmt, va);
+ //fprintf (stderr, "%s\n" ,buffer);
+ addpCode2pBlock (pb, newpCodeCharP (buffer));
+ }
+ va_end (va);
+}
void emitpLabel(int key)
{
addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
}
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* gen.h defines a macro emitpcode that should be used to call emitpcode
+ * as this allows for easy debugging (ever asked the question: where was
+ * this instruction geenrated? Here is the answer... */
+void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
{
if(pcop)
addpCode2pBlock(pb,newpCode(poc,pcop));
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
va_start(ap,fmt);
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 */
+ resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL); / * oops, there is no ifx. so create a label */
/*
DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
__FUNCTION__,__LINE__,resIfx->lbl->key);
return;
}
+#if 0
+ /* WREG is not usable as an ordinary operand with PIC architecture,
+ * one might introduce a scratch register that can be used to make
+ * WREG accesible as an operand... disable WREG for now */
if (sym->accuse) {
int i;
aop = op->aop = sym->aop = newAsmop(AOP_ACC);
DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
return;
}
+#endif
if (sym->ruonly ) {
if(sym->isptr) { // && sym->uptr
}
/* else spill location */
- if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* force a new aop if sizes differ */
- sym->usl.spillLoc->aop = NULL;
- }
- DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
- __FUNCTION__,__LINE__,
- sym->usl.spillLoc->rname,
- sym->rname, sym->usl.spillLoc->offset);
-
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
- aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
- getSize(sym->type),
- sym->usl.spillLoc->offset);
- aop->size = getSize(sym->type);
+ if (sym->usl.spillLoc)
+ {
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+ {
+ /* force a new aop if sizes differ */
+ sym->usl.spillLoc->aop = NULL;
+ }
+ DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+ __FUNCTION__,__LINE__,
+ sym->usl.spillLoc->rname,
+ sym->rname, sym->usl.spillLoc->offset);
+
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+ aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
+ getSize(sym->type),
+ sym->usl.spillLoc->offset);
+ aop->size = getSize(sym->type);
- return;
+ return;
+ }
}
{
//DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* offset is greater than
size then zero */
+
+ if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0))))
+ {
+ fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size);
+ }
+ assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0)));
+ /* XXX: still needed for BIT operands (AOP_CRY) */
if (offset > (aop->size - 1) &&
aop->type != AOP_LIT)
return NULL; //zero;
*/
case AOP_PCODE:
- DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
+ pcop = NULL;
+ DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
__LINE__,
((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
- pcop = pCodeOpCopy(aop->aopu.pcop);
- PCOI(pcop)->offset = offset;
+ //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
+ switch (aop->aopu.pcop->type)
+ {
+ case PO_IMMEDIATE:
+ pcop = pCodeOpCopy (aop->aopu.pcop);
+ /* usually we want to access the memory at "<symbol> + offset" (using ->index),
+ * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
+ PCOI(pcop)->index += offset;
+ //PCOI(pcop)->offset = 0;
+ break;
+ case PO_DIR:
+ pcop = pCodeOpCopy (aop->aopu.pcop);
+ PCOR(pcop)->instance = offset;
+ break;
+ default:
+ assert ( !"unhandled pCode type" );
+ break;
+ } // switch
return pcop;
}
"popGet got unsupported aop->type");
exit(0);
}
+
+/*-----------------------------------------------------------------*/
+/* popGetAddr - access the low/high word of a symbol (immediate) */
+/* (for non-PO_IMMEDIATEs this is the same as poGet) */
+/*-----------------------------------------------------------------*/
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
+{
+ if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
+ {
+ pCodeOp *pcop = aop->aopu.pcop;
+ pcop = pCodeOpCopy (pcop);
+ /* usually we want to access the memory at "<symbol> + offset" (using ->index),
+ * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
+ PCOI(pcop)->offset += offset;
+ PCOI(pcop)->index += index;
+ return pcop;
+ } else {
+ return popGet (aop, offset + index);
+ }
+}
+
/*-----------------------------------------------------------------*/
/* aopPut - puts a string for a aop */
/*-----------------------------------------------------------------*/
DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
- if ( aop->type == AOP_PCODE ||
- aop->type == AOP_LIT ||
- aop->type == AOP_IMMD )
- emitpcode(POC_MOVLW,popGet(aop,offset));
+ if ( aop_isLitLike (aop) )
+ emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
else
emitpcode(POC_MOVFW,popGet(aop,offset));
/*-----------------------------------------------------------------*/
static void genNot (iCode *ic)
{
- symbol *tlbl;
+ //symbol *tlbl;
int size;
+
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* assign asmOps to operand & result */
goto release;
}
+ assert (!pic14_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
size = AOP_SIZE(IC_LEFT(ic));
- if(size == 1) {
- emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_ANDLW,popGetLit(1));
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- goto release;
+ emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+ mov2w (AOP(IC_LEFT(ic)),0);
+ while (--size > 0)
+ {
+ if (aop_isLitLike (AOP(IC_LEFT(ic))))
+ emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
+ else
+ emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
}
- pic14_toBoolean(IC_LEFT(ic));
-
- tlbl = newiTempLabel(NULL);
- pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(IC_RESULT(ic));
+ emitSKPNZ;
+ emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+ goto release;
release:
/* release the aops */
operand *left, *result;
int size, offset=0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left = IC_LEFT(ic)),ic,FALSE);
int size ,offset =0 ;
char *l;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* for this we just need to flip the
first it then copy the rest in place */
int size, i;
sym_link *optype, *rtype;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* assign asmops */
bitVect *rsave;
sym_link *dtype;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* look for call */
for (ic = lic ; ic ; ic = ic->next)
int i;
bitVect *rsave;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* find the registers in use at this time
and push them away to safety */
{
int size = AOP_SIZE(oper);
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
/*-----------------------------------------------------------------*/
static void genIpush (iCode *ic)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
/*-----------------------------------------------------------------*/
static void genIpop (iCode *ic)
{
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
int size,offset ;
/*-----------------------------------------------------------------*/
static void unsaverbank (int bank,iCode *ic,bool popPsw)
{
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
int i;
/*-----------------------------------------------------------------*/
static void saverbank (int bank, iCode *ic, bool pushPsw)
{
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
int i;
unsigned char *name;
int isExtern;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if caller saves & we have not saved then */
pCodeOp *pcop;
operand *left;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
emitpcode(POC_GOTO,pcop);
emitpLabel(albl->key);
- poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+ poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW );
- emitpcode(poc,popGet(AOP(left),1));
+ emitpcode(poc,popGetAddr(AOP(left),1,0));
emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
- emitpcode(poc,popGet(AOP(left),0));
+ emitpcode(poc,popGetAddr(AOP(left),0,0));
emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
emitpLabel(blbl->key);
static int resultRemat (iCode *ic)
{
// DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
+
if (SKIP_IC(ic) || ic->op == IFX)
return 0;
symbol *sym;
sym_link *ftype;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
labelOffset += (max_key+4);
{
symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
{
int size,offset = 0 , pushed = 0;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if we have no return value then
just generate the "ret" */
AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
- emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
}else {
emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
}
/*-----------------------------------------------------------------*/
static void genLabel (iCode *ic)
{
+ FENTRY;
+
/* special case never generate */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (IC_LABEL(ic) == entryLabel)
//tsd
static void genGoto (iCode *ic)
{
+ FENTRY;
+
emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
}
operand *right,
operand *result)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!pic14_sameRegs(AOP(result),AOP(right)))
// symbol *lbl ;
int size,offset;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic14_AopType(__LINE__,left,right,result);
DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
operand *right = IC_RIGHT(ic);
operand *result= IC_RESULT(ic);
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* assign the amsops */
aopOp (left,ic,FALSE);
char *l;
+ FENTRY;
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* the result must be bit */
pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
symbol *lbl ;
int size,offset;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
size = AOP_SIZE(result) - 1;
offset = 1;
operand *right = IC_RIGHT(ic);
operand *result= IC_RESULT(ic);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* assign the amsops */
aopOp (left,ic,FALSE);
char *l;
+ FENTRY;
/* the result must be bit */
pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
l = aopGet(AOP(left),0,FALSE,FALSE);
char *l ;
symbol *lbl ;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* signed or unsigned */
if (SPEC_USIGN(opetype)) {
operand *right = IC_RIGHT(ic);
operand *result= IC_RESULT(ic);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* assign the amsops */
aopOp (left,ic,FALSE);
static void genIfxJump (iCode *ic, char *jval)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if true label then we jump if condition
supplied is true */
/*-----------------------------------------------------------------*/
static void genSkip(iCode *ifx,int status_bit)
{
+ FENTRY;
if(!ifx)
return;
/*-----------------------------------------------------------------*/
static void genSkipc(resolvedIfx *rifx)
{
+ FENTRY;
if(!rifx)
return;
if(rifx->condition)
- emitSKPC;
- else
emitSKPNC;
+ else
+ emitSKPC;
emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+ emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
rifx->generated = 1;
}
/*-----------------------------------------------------------------*/
static void genSkipz2(resolvedIfx *rifx, int invert_condition)
{
+ FENTRY;
if(!rifx)
return;
/*-----------------------------------------------------------------*/
static void genSkipz(iCode *ifx, int condition)
{
+ FENTRY;
if(!ifx)
return;
pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
}
+
+#if 0
/*-----------------------------------------------------------------*/
/* genSkipCond */
/*-----------------------------------------------------------------*/
static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
{
+ FENTRY;
if(!rifx)
return;
emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
rifx->generated = 1;
}
+#endif
#if 0
/*-----------------------------------------------------------------*/
}
#endif
+
+#define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE)
+#define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT)
+#define DEBUGpc emitpComment
+
+/*-----------------------------------------------------------------*/
+/* mov2w_regOrLit :- move to WREG either the offset's byte from */
+/* aop (if it's NOT a literal) or from lit (if */
+/* aop is a literal) */
+/*-----------------------------------------------------------------*/
+void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
+ if (aop->type == AOP_LIT) {
+ emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF));
+ } else {
+ emitpcode (POC_MOVFW, popGet (aop, offset));
+ }
+}
+
+/* genCmp performs a left < right comparison, stores
+ * the outcome in result (if != NULL) and generates
+ * control flow code for the ifx (if != NULL).
+ *
+ * This version leaves in sequences like
+ * "B[CS]F STATUS,0; BTFS[CS] STATUS,0"
+ * which should be optmized by the peephole
+ * optimizer - RN 2005-01-01 */
+static void genCmp (operand *left,operand *right,
+ operand *result, iCode *ifx, int sign)
+{
+ resolvedIfx rIfx;
+ int size;
+ int offs;
+ symbol *templbl;
+ operand *dummy;
+ unsigned long lit;
+ unsigned long mask;
+ int performedLt;
+ int invert_result = 0;
+
+ FENTRY;
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+ assert (left && right);
+
+ size = AOP_SIZE(right) - 1;
+ mask = (0x100UL << (size*8)) - 1;
+ // in the end CARRY holds "left < right" (performedLt == 1) or "left >= right" (performedLt == 0)
+ performedLt = 1;
+ templbl = NULL;
+ lit = 0;
+
+ resolveIfx (&rIfx, ifx);
+
+ /**********************************************************************
+ * handle bits - bit compares are promoted to int compares seemingly! *
+ **********************************************************************/
+#if 0
+ // THIS IS COMPLETELY UNTESTED!
+ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY) {
+ pCodeOp *pcleft = pic16_popGet(AOP(left), 0);
+ pCodeOp *pcright = pic16_popGet(AOP(right), 0);
+ assert (pcleft->type == PO_GPR_BIT && pcright->type == PO_GPR_BIT);
+
+ emitSETC;
+ // 1 < {0,1} is false --> clear C by skipping the next instruction
+ //pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (AOP(left),0), PCORB(pcleft)->bit);
+ pic16_emitpcode (POC_BTFSS, pic16_popGet (AOP(left), 0));
+ // {0,1} < 0 is false --> clear C by NOT skipping the next instruction
+ pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (pic16_popGet(AOP(right),0), PCORB(pcright)->bit));
+ emitCLRC; // only skipped for left=0 && right=1
+
+ goto correct_result_in_carry;
+ } // if
+#endif
+
+ /*************************************************
+ * make sure that left is register (or the like) *
+ *************************************************/
+ if (!isAOP_REGlike(left)) {
+ DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right));
+ assert (isAOP_LIT(left));
+ assert (isAOP_REGlike(right));
+ // swap left and right
+ // left < right <==> right > left <==> (right >= left + 1)
+ lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+
+ if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
+ // MAXVALUE < right? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } // if
+
+ // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed),
+ // that's why we handled it above.
+ lit++;
+
+ dummy = left;
+ left = right;
+ right = dummy;
+
+ performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
+ } else if (isAOP_LIT(right)) {
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ } // if
+
+ assert (isAOP_REGlike(left)); // left must be register or the like
+ assert (isAOP_REGlike(right) || isAOP_LIT(right)); // right may be register-like or a literal
+
+ /*************************************************
+ * special cases go here *
+ *************************************************/
+
+ if (isAOP_LIT(right)) {
+ if (!sign) {
+ // unsigned comparison to a literal
+ DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
+ if (lit == 0) {
+ // unsigned left < 0? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } else {
+ // signed comparison to a literal
+ DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
+ if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
+ // signed left < 0x80000000? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } else if (lit == 0) {
+ // compare left < 0; set CARRY if SIGNBIT(left) is set
+ if (performedLt) emitSETC; else emitCLRC;
+ emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } // if (!sign)
+ } // right is literal
+
+ /*************************************************
+ * perform a general case comparison *
+ * make sure we get CARRY==1 <==> left >= right *
+ *************************************************/
+ // compare most significant bytes
+ //DEBUGpc ("comparing bytes at offset %d", size);
+ if (!sign) {
+ // unsigned comparison
+ pic14_mov2w_regOrLit (AOP(right), lit, size);
+ emitpcode (POC_SUBFW, popGet (AOP(left), size));
+ } else {
+ // signed comparison
+ // (add 2^n to both operands then perform an unsigned comparison)
+ if (isAOP_LIT(right)) {
+ // left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0)
+ unsigned char litbyte = (lit >> (8*size)) & 0xFF;
+
+ if (litbyte == 0x80) {
+ // left >= 0x80 -- always true, but more bytes to come
+ mov2w (AOP(left), size);
+ emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
+ emitSETC;
+ } else {
+ // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+ } // if
+ } else {
+ pCodeOp *pctemp = popGetTempReg();
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_MOVWF, pctemp);
+ mov2w (AOP(right), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_SUBFW, pctemp);
+ popReleaseTempReg(pctemp);
+ }
+ } // if (!sign)
+
+ // compare remaining bytes (treat as unsigned case from above)
+ templbl = newiTempLabel ( NULL );
+ offs = size;
+ while (offs--) {
+ //DEBUGpc ("comparing bytes at offset %d", offs);
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (templbl->key));
+ pic14_mov2w_regOrLit (AOP(right), lit, offs);
+ emitpcode (POC_SUBFW, popGet (AOP(left), offs));
+ } // while (offs)
+ emitpLabel (templbl->key);
+ goto result_in_carry;
+
+result_in_carry:
+
+ /****************************************************
+ * now CARRY contains the result of the comparison: *
+ * SUBWF sets CARRY iff *
+ * F-W >= 0 <==> F >= W <==> !(F < W) *
+ * (F=left, W=right) *
+ ****************************************************/
+
+ if (performedLt) {
+ invert_result = 1;
+ // value will be used in the following genSkipc()
+ rIfx.condition ^= 1;
+ } // if
+
+correct_result_in_carry:
+
+ // assign result to variable (if neccessary)
+ if (result && AOP_TYPE(result) != AOP_CRY) {
+ //DEBUGpc ("assign result");
+ size = AOP_SIZE(result);
+ while (size--) {
+ emitpcode (POC_CLRF, popGet (AOP(result), size));
+ } // while
+ if (invert_result) {
+ emitSKPC;
+ emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
+ } else {
+ emitpcode (POC_RLF, popGet (AOP(result), 0));
+ }
+ } // if (result)
+
+ // perform conditional jump
+ if (ifx) {
+ //DEBUGpc ("generate control flow");
+ genSkipc (&rIfx);
+ ifx->generated = 1;
+ } // if
+}
+
+
+#if 0
+/* OLD VERSION -- BUGGY, DO NOT USE */
+
/*-----------------------------------------------------------------*/
/* genCmp :- greater or less than comparison */
/*-----------------------------------------------------------------*/
resolvedIfx rFalseIfx;
// resolvedIfx rTrueIfx;
symbol *truelbl;
+
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/*
if(ifx) {
} else {
emitpcode(POC_ADDLW, popGetLit(0x80));
emitpcode(POC_ADDLW, popGetLit(i^0x80));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
} else {
genSkipz2(&rFalseIfx,1);
} else {
emitpcode(POC_ADDLW, popGetLit(i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
}
emitSKPNZ;
}
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
if(ifx) ifx->generated = 1;
return;
emitpcode(POC_MOVFW, popGet(AOP(left),size));
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
emitpcode(POC_MOVFW, popGet(AOP(left),size));
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
emitpcode(POC_SUBFW, popGet(AOP(left),size));
}
//rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
emitpLabel(lbl->key);
//if(emitFinalCheck)
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(sign)
emitpLabel(truelbl->key);
emitpcode(POC_ADDLW, popGetLit(0x80));
emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
break;
}
if(ifx) ifx->generated = 1;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
rFalseIfx.condition ^= 1;
if (AOP_TYPE(result) == AOP_CRY) {
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
} else {
DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
}
rFalseIfx.condition ^= 1;
//rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
emitpcode(POC_SUBFW, popGet(AOP(right),0));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
emitpLabel(truelbl->key);
emitpLabel(lbl->key);
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
if(sign)
emitpcode(POC_ADDLW, popGetLit(0x80));
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
return;
emitpcode(POC_CLRF, popGet(AOP(result),0));
emitpcode(POC_RLF, popGet(AOP(result),0));
} else {
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
- //genSkipc(&rFalseIfx);
+ //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
return;
}
}
+#endif
/*-----------------------------------------------------------------*/
/* genCmpGt :- greater than comparison */
sym_link *letype , *retype;
int sign ;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
left = IC_LEFT(ic);
right= IC_RIGHT(ic);
sym_link *letype , *retype;
int sign ;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
left = IC_LEFT(ic);
right= IC_RIGHT(ic);
{
int i;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
if( (lit&0xff) == 0)
i=1;
/*-----------------------------------------------------------------*/
static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
{
- int size = max(AOP_SIZE(left),AOP_SIZE(right));
+ int size = min(AOP_SIZE(left),AOP_SIZE(right));
int offset = 0;
- int res_offset = 0; /* the result may be a different size then left or right */
- int res_size = AOP_SIZE(result);
- resolvedIfx rIfx;
+ //resolvedIfx rIfx;
symbol *lbl;
- unsigned long lit = 0L;
+ //unsigned long lit = 0L;
+ FENTRY;
+ if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
+ emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
+ return;
+ }
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ assert (!pic14_sameRegs (AOP(left), AOP(result)));
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
+ if (AOP_SIZE(result)) {
+ for (offset = 0; offset < AOP_SIZE(result); offset++)
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ }
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+ //resolveIfx(&rIfx,ifx);
+ lbl = newiTempLabel (NULL);
+ while (size--)
+ {
+ mov2w (AOP(right),size);
+ emitpcode (POC_XORFW, popGet (AOP(left), size));
+ if (size)
+ {
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (lbl->key));
+ }
+ } // while
+ emitpLabel (lbl->key);
+ if (AOP_SIZE(result)) {
+ emitSKPNZ;
+ emitpcode (POC_INCF, popGet (AOP(result), 0));
+ } else {
+ assert (ifx);
+ genSkipz (ifx, NULL != IC_TRUE(ifx));
+ ifx->generated = 1;
+ }
+ return;
+#if 0
if(result)
+ {
DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
- resolveIfx(&rIfx,ifx);
- lbl = newiTempLabel(NULL);
+ assert (!pic14_sameRegs (AOP(result), AOP(left)));
+ assert (!pic14_sameRegs (AOP(result), AOP(right)));
+ for (offset=0; offset < AOP_SIZE(result); offset++)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ } // for offset
+ }
/* if the left side is a literal or
emitpcode(POC_GOTO,popGetLabel(lbl->key));
break;
default:
+ offset = 0;
while (size--) {
if(lit & 0xff) {
emitpcode(POC_MOVFW,popGet(AOP(left),offset));
emitSKPNZ;
emitpcode(POC_GOTO,popGetLabel(lbl->key));
offset++;
- if(res_offset < res_size-1)
- res_offset++;
lit >>= 8;
}
break;
//int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
int lbl_key = lbl->key;
- if(result) {
- emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- }else {
+ if(!result) {
DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
fprintf(stderr, "%s %d error - expecting result to be non_null\n",
__FUNCTION__,__LINE__);
/* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
/* break; */
/* default: */
+ offset = 0;
while (size--) {
int emit_skip=1;
if((AOP_TYPE(left) == AOP_DIR) &&
break;
case 1:
emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
- emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- //emitpcode(POC_GOTO,popGetLabel(lbl->key));
+ //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ emitpcode(POC_GOTO,popGetLabel(lbl->key));
emit_skip=0;
break;
case 0xff:
else
emitSKPNZ;
emitpcode(POC_GOTO,popGetLabel(lbl_key));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
}
if(ifx)
ifx->generated=1;
}
emit_skip++;
offset++;
- if(res_offset < res_size-1)
- res_offset++;
}
/* break; */
/* } */
} else if(AOP_TYPE(right) == AOP_REG &&
AOP_TYPE(left) != AOP_DIR){
-
+
+ offset = 0;
while(size--) {
emitpcode(POC_MOVFW,popGet(AOP(left),offset));
emitpcode(POC_XORFW,popGet(AOP(right),offset));
emitSKPZ;
emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
offset++;
- if(res_offset < res_size-1)
- res_offset++;
}
}else{
/* right is a pointer reg need both a & b */
+ offset = 0;
while(size--) {
char *l = aopGet(AOP(left),offset,FALSE,FALSE);
if(strcmp(l,"b"))
}
}
- emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ emitpcode(POC_INCF,popGet(AOP(result),0));
if(!rIfx.condition)
emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
if(ifx)
ifx->generated = 1;
+#endif
}
#if 0
unsigned long lit = 0L;
int size,offset=0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(ifx)
/* if literal, literal on the right or
if the right is in a pointer register and left
is not */
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
- (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+ if (aop_isLitLike (AOP(IC_LEFT(ic)))
+ || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
operand *tmp = right ;
right = left;
left = tmp;
tlbl = newiTempLabel(NULL);
while(size--) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORFW,popGet(AOP(right),offset));
+ mov2w (AOP(right),offset); /* right might be litLike() */
+ emitpcode(POC_XORFW,popGet(AOP(left),offset));
if ( IC_TRUE(ifx) ) {
if(size) {
/*-----------------------------------------------------------------*/
static iCode *ifxForOp ( operand *op, iCode *ic )
{
+ FENTRY;
/* if true symbol then needs to be assigned */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (IS_TRUE_SYMOP(op))
operand *left,*right, *result;
/* symbol *tlbl; */
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* note here that && operations that are in an
if statement are taken away by backPatchLabels
/* note here that || operations that are in an
if statement are taken away by backPatchLabels
only those used in arthmetic operations remain */
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left=IC_LEFT(ic)),ic,FALSE);
aopOp((right=IC_RIGHT(ic)),ic,FALSE);
0x10000000L,0x20000000L,0x40000000L,0x80000000L};
int idx;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
for(idx = 0; idx < 32; idx++)
if(lit == pw[idx])
/*-----------------------------------------------------------------*/
static void continueIfTrue (iCode *ic)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(IC_TRUE(ic))
pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
/*-----------------------------------------------------------------*/
static void jumpIfTrue (iCode *ic)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!IC_TRUE(ic))
pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
/*-----------------------------------------------------------------*/
static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
{
+ FENTRY;
// ugly but optimized by peephole
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(IC_TRUE(ic)){
int bytelit = 0;
resolvedIfx rIfx;
-
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left = IC_LEFT(ic)),ic,FALSE);
aopOp((right= IC_RIGHT(ic)),ic,FALSE);
int size, offset=0;
unsigned long lit = 0L;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left = IC_LEFT(ic)),ic,FALSE);
int size, offset=0;
unsigned long lit = 0L;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left = IC_LEFT(ic)),ic,FALSE);
pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
goto release;
} else {
+ assert ( !"incomplete genXor" );
pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
pic14_emitcode("cpl","c");
}
{
char *buffer, *bp, *bp1;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
_G.inLine += (!options.asmpeep);
operand *left , *result ;
int size, offset = 0, same;
+ FENTRY;
/* rotate right with carry */
left = IC_LEFT(ic);
result=IC_RESULT(ic);
int size, offset = 0;
int same;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* rotate right with carry */
left = IC_LEFT(ic);
aopOp (left,ic,FALSE);
aopOp (result,ic,FALSE);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* get the highest order byte into a */
MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
/*-----------------------------------------------------------------*/
static void AccRol (operand *op,int offset,int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
shCount &= 0x0007; // shCount : 0..7
switch(shCount){
/*-----------------------------------------------------------------*/
static void AccLsh (operand *op,int offset,int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(shCount != 0){
- /*
- if(shCount == 1) {
- pic14_emitcode("add","a,acc");
+ if(shCount != 0) {
+ if (shCount == 1)
+ {
emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
+ emitpcode (POC_RLF, popGet (AOP(op), 0));
} else {
- if(shCount == 2) {
- pic14_emitcode("add","a,acc");
- emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
- pic14_emitcode("add","a,acc");
- emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
- } else {
- */
- {
- {
- /* rotate left accumulator */
- AccRol(op,offset,shCount);
- /* and kill the lower order bits */
- pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
- emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
- }
+ /* rotate left accumulator */
+ AccRol(op,offset,shCount);
+ /* and kill the lower order bits */
+ emitpcode(POC_MOVLW,popGetLit(SLMask[shCount]));
+ emitpcode (POC_ANDWF, popGet (AOP(op),0));
}
}
}
/*-----------------------------------------------------------------*/
static void AccRsh (operand *op,int offset,int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(shCount != 0){
if(shCount == 1){
- CLRC;
- pic14_emitcode("rrc","a");
+ emitCLRC;
+ emitpcode (POC_RRF, popGet (AOP(op), 0));
} else {
/* rotate right accumulator */
AccRol(op,offset,8 - shCount);
/* and kill the higher order bits */
- pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
+ emitpcode (POC_MOVLW, popGetLit (SRMask[shCount]));
+ emitpcode (POC_ANDWF, popGet (AOP(op),0));
}
}
}
}
}
}
-#endif
+
/*-----------------------------------------------------------------*/
/* shiftR1Left2Result - shift right one byte from left to result */
/*-----------------------------------------------------------------*/
{
int same;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
{
int same;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
int same;
// char *l;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
}
}
+#endif
/*-----------------------------------------------------------------*/
/* movLeft2Result - move byte from left to result */
operand *result, int offr)
{
char *l;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
l = aopGet(AOP(left),offl,FALSE,FALSE);
}
}
+/*-----------------------------------------------------------------*/
+/* shiftLeft_Left2ResultLit - shift left by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=size-1; i >= 0; i--)
+ movLeft2Result (left, i, result, offr + i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+ if (same && offr) {
+ shiftLeft_Left2ResultLit (left, result, 8 * offr);
+ shiftLeft_Left2ResultLit (result, result, shCount);
+ return; /* prevent clearing result again */
+ } else {
+ emitCLRC;
+ for (i=0; i < size; i++) {
+ if (same && !offr) {
+ emitpcode (POC_RLF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RLFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ } // if
+ } // for
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+ for (i = size - 2; i >= 0; i--)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+ } // for i
+ break;
+
+ case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+ for (i = size-2; i >= 0; i--) {
+ emitpcode (POC_RRFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ emitpcode (POC_RRF, popGet (AOP(result), offr));
+ break;
+
+ default:
+ shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+ shiftLeft_Left2ResultLit (result, result, 1);
+ return; /* prevent clearing result again */
+ break;
+ } // switch
+
+ while (0 < offr--)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ } // while
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRight_Left2ResultLit - shift right by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ if (size)
+ {
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=0; i < size; i++)
+ movLeft2Result (left, i + offr, result, i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+ emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+ if (same && offr) {
+ shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+ shiftRight_Left2ResultLit (result, result, shCount, sign);
+ return; /* prevent sign-extending result again */
+ } else {
+ emitCLRC;
+ if (sign) {
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+ emitSETC;
+ }
+ for (i = size-1; i >= 0; i--) {
+ if (same && !offr) {
+ emitpcode (POC_RRF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ }
+ } // for i
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_MOVWF, popGet(AOP(result), 0));
+
+ for (i = 1; i < size; i++)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i));
+ } // for i
+
+ if (sign)
+ {
+ emitpcode (POC_MOVLW, popGetLit (0xF0));
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+ emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+ } // if
+ break;
+
+ case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RLFW, popGet (AOP(left), offr));
+ for (i = 0; i < size-1; i++) {
+ emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+ if (!sign) {
+ emitpcode (POC_RLF, popGet (AOP(result), size-1));
+ } else {
+ emitSKPNC;
+ emitpcode (POC_DECF, popGet (AOP(result), size-1));
+ }
+ break;
+
+ default:
+ shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+ shiftRight_Left2ResultLit (result, result, 1, sign);
+ return; /* prevent sign extending result again */
+ break;
+ } // switch
+ } // if
+
+ addSign (result, size, sign);
+}
+
+#if 0
/*-----------------------------------------------------------------*/
/* shiftL2Left2Result - shift left two bytes from left to result */
/*-----------------------------------------------------------------*/
static void shiftL2Left2Result (operand *left, int offl,
operand *result, int offr, int shCount)
{
-
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
}
}
+
/*-----------------------------------------------------------------*/
/* shiftR2Left2Result - shift right two bytes from left to result */
/*-----------------------------------------------------------------*/
{
int same=0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
same = pic14_sameRegs(AOP(result), AOP(left));
}
}
-
/*-----------------------------------------------------------------*/
/* shiftLLeftOrResult - shift left one byte from left, or to result*/
/*-----------------------------------------------------------------*/
static void shiftLLeftOrResult (operand *left, int offl,
operand *result, int offr, int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+
/* shift left accumulator */
AccLsh(left,offl,shCount);
/* or with result */
- pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
- /* back to result */
- aopPut(AOP(result),"a",offr);
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
static void shiftRLeftOrResult (operand *left, int offl,
operand *result, int offr, int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+
/* shift right accumulator */
AccRsh(left,offl,shCount);
/* or with result */
- pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
- /* back to result */
- aopPut(AOP(result),"a",offr);
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genlshOne (operand *result, operand *left, int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
shiftL1Left2Result(left, LSB, result, LSB, shCount);
}
{
int size;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
size = pic14_getDataSize(result);
char *l;
int size = AOP_SIZE(result);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(size >= LSB+offr){
l = aopGet(AOP(left),LSB,FALSE,FALSE);
{
int size;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
size = AOP_SIZE(result);
shiftL2Left2Result(left, LSB, result, LSB, shCount);
}
}
+#endif
+#if 0
/*-----------------------------------------------------------------*/
/* genLeftShiftLiteral - left shifting by known count */
/*-----------------------------------------------------------------*/
iCode *ic)
{
int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- int size;
+ //int size;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
freeAsmop(right,NULL,ic,TRUE);
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
-
+
size = getSize(operandType(result));
#if VIEW_SIZE
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*
* genMultiAsm - repeat assembly instruction for size of register.
int offset = 0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!reg)
symbol *tlbl , *tlbl1;
pCodeOp *pctemp;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
right = IC_RIGHT(ic);
result = IC_RESULT(ic);
aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
/* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
- genLeftShiftLiteral (left,right,result,ic);
+ shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
return ;
}
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
+ /* this code fails for RIGHT == RESULT */
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
/* now move the left to the result if they are not the
same */
tlbl = newiTempLabel(NULL);
if (!pic14_sameRegs(AOP(left),AOP(result))) {
- if (AOP_TYPE(left) == AOP_LIT)
- emitpcode(POC_MOVLW, popGetLit(lit));
- else
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ mov2w (AOP(left), 0);
emitpcode(POC_MOVWF, popGet(AOP(result),0));
}
freeAsmop(result,NULL,ic,TRUE);
}
+#if 0
/*-----------------------------------------------------------------*/
/* genrshOne - right shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
static void genrshOne (operand *result, operand *left,
int shCount, int sign)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
}
static void genrshTwo (operand *result,operand *left,
int shCount, int sign)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if shCount >= 8 */
if (shCount >= 8) {
static void shiftRLong (operand *left, int offl,
operand *result, int sign)
{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!sign)
- pic14_emitcode("clr","c");
- MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
- if(sign)
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB32-offl);
- if(offl == MSB16)
- /* add sign of "a" */
- addSign(result, MSB32, sign);
+ int size, same;
- MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB24-offl);
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB16-offl);
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
- if(offl == LSB){
- MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",LSB);
- }
+ if (sign)
+ emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
+ else
+ emitCLRC;
+
+ assert (offl >= 0 && offl < size);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ /* perform the shift */
+ while (size--)
+ {
+ if (same && !offl) {
+ emitpcode (POC_RRF, popGet (AOP(result), size));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), size));
+ emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
+ }
+ } // while
+
+ addSign (result, AOP_SIZE(left) - offl, sign);
}
/*-----------------------------------------------------------------*/
static void genrshFour (operand *result, operand *left,
int shCount, int sign)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if shifting more that 3 bytes */
if(shCount >= 24 ) {
int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
int lsize,res_size;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
freeAsmop(right,NULL,ic,TRUE);
/* I suppose that the left size >= result size */
if(shCount == 0){
while(res_size--)
- movLeft2Result(left, lsize, result, res_size);
+ movLeft2Result(left, res_size, result, res_size);
}
else if(shCount >= (lsize * 8)){
}
}
-
+
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*/
/* genSignedRightShift - right shift of signed number */
/* we do it the hard way put the shift count in b
and loop thru preserving the sign */
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
right = IC_RIGHT(ic);
if ( AOP_TYPE(right) == AOP_LIT) {
- genRightShiftLiteral (left,right,result,ic,1);
+ shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
+ //genRightShiftLiteral (left,right,result,ic,1);
return ;
}
/* shift count is unknown then we have to form
char *l;
symbol *tlbl, *tlbl1 ;
+ FENTRY;
/* if signed then we do it the hard way preserve the
sign bit moving it inwards */
retype = getSpec(operandType(IC_RESULT(ic)));
result = IC_RESULT(ic);
aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
/* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
- genRightShiftLiteral (left,right,result,ic, 0);
+ shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0);
+ //genRightShiftLiteral (left,right,result,ic, 0);
return ;
}
pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
pic14_emitcode("inc","b");
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
/* now move the left to the result if they are not the
same */
int blen; /* bitfield length */
int bstr; /* bitfield starting bit within byte */
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
etype = getSpec(operandType(result));
rsize = getSize (operandType (result));
resolvedIfx rIfx;
resolveIfx(&rIfx,ifx);
if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
else
pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
ifx->generated=1;
} else {
pCodeOp *pcop;
+ int i;
+ assert (!pic14_sameRegs (AOP(result), AOP(left)));
+ for (i=0; i < AOP_SIZE(result); i++)
+ emitpcode (POC_CLRF, popGet (AOP(result), i));
if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
else
pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
emitpcode(POC_BTFSC,pcop);
- emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
-
- if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
- else
- pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
- emitpcode(POC_BTFSS,pcop);
- emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
+ emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),0,0));
}
return;
}
+ {
+ static int has_warned=0;
+ if (!has_warned)
+ {
+ fprintf (stderr, "%s: bitfields with more than 1 bit are probably broken...", __FUNCTION__);
+ has_warned=1;
+ }
+ }
+
/* read the first byte */
switch (ptype) {
return ;
}
-#if 0
+#if 1
/*-----------------------------------------------------------------*/
/* genDataPointerGet - generates code when ptr offset is known */
/*-----------------------------------------------------------------*/
static void genDataPointerGet (operand *left,
- operand *result,
- iCode *ic)
+ operand *result,
+ iCode *ic)
{
int size , offset = 0;
-
-
+
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
* address, but different types. for the pic code, we could omit
* the following
*/
-
aopOp(result,ic,TRUE);
+ if (pic14_sameRegs (AOP(left), AOP(result)))
+ return;
+
DEBUGpic14_AopType(__LINE__,left,NULL,result);
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ //emitpcode(POC_MOVFW, popGet(AOP(left),0));
size = AOP_SIZE(result);
+ if (size > AOP_SIZE(left)) size = AOP_SIZE(left);
while (size--) {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
emitpcode(POC_MOVWF, popGet(AOP(result),offset));
offset++;
}
sym_link *retype= getSpec(rtype); /* bitfield type information */
int direct = 0;
-
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
!IS_BITVAR(retype) &&
DCL_TYPE(ltype) == POINTER) {
- //genDataPointerGet (left,result,ic);
+ genDataPointerGet (left,result,ic);
return ;
}
if (!AOP_INPREG(AOP(left)) && !direct) {
/* otherwise get a free pointer register */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (PCOP(AOP(result))->type == PO_LITERAL)
+ if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */
emitpcode(POC_MOVLW, popGet(AOP(left),0));
else
emitpcode(POC_MOVFW, popGet(AOP(left),0));
char *rname ;
sym_link *rtype, *retype;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
rtype = operandType(result);
int size, offset ;
sym_link *retype = getSpec(operandType(result));
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(left,ic,FALSE);
int size, offset ;
sym_link *retype = getSpec(operandType(result));
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
operand *result, iCode *ic)
{
//sym_link *retype = getSpec(operandType(result));
- symbol *albl = newiTempLabel(NULL);
- symbol *blbl = newiTempLabel(NULL);
+ symbol *albl, *blbl;//, *clbl;
PIC_OPCODE poc;
+ int i, size, lit;
pCodeOp *pcop;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
+ size = AOP_SIZE(result);
DEBUGpic14_AopType(__LINE__,left,NULL,result);
DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
-
- emitpcode(POC_CALL,popGetLabel(albl->key));
- pcop = popGetLabel(blbl->key);
- emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
- emitpcode(POC_GOTO,pcop);
- emitpLabel(albl->key);
-
- poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-
- emitpcode(poc,popGet(AOP(left),1));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
- emitpcode(poc,popGet(AOP(left),0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
-
- emitpLabel(blbl->key);
-
- emitpcode(POC_MOVWF,popGet(AOP(result),0));
-
+
+ lit = aop_isLitLike (AOP(left));
+ poc = lit ? POC_MOVLW : POC_MOVFW;
+
+ if (lit)
+ {
+ for (i = 0; i < size; i++)
+ {
+ albl = newiTempLabel(NULL);
+ blbl = newiTempLabel(NULL);
+
+ emitpcode(POC_CALL,popGetLabel(albl->key));
+ pcop = popGetLabel(blbl->key);
+ emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+ emitpcode(POC_GOTO,pcop);
+
+ emitpLabel(albl->key);
+ emitpcode(poc,popGetAddr(AOP(left),1,i));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+ emitpcode(poc,popGetAddr(AOP(left),0,i));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+ emitpLabel(blbl->key);
+ emitpcode(POC_MOVWF,popGet(AOP(result),i));
+ } // for
+ } else {
+ albl = newiTempLabel(NULL);
+ blbl = newiTempLabel(NULL);
+ //clbl = newiTempLabel(NULL);
+
+ emitpcode (POC_GOTO, popGetLabel (blbl->key));
+
+ emitpLabel(albl->key);
+ emitpcode(poc,popGet(AOP(left),1));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+ emitpcode(poc,popGet(AOP(left),0));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+ emitpLabel(blbl->key);
+
+ for (i = 0; i < size; i++)
+ {
+ emitpcode(POC_CALL,popGetLabel(albl->key));
+ /* the next two instructions (plus clbl) might be useless... */
+ //pcop = popGetLabel(clbl->key);
+ //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+ //emitpcode(POC_GOTO,pcop);
+ //emitpLabel(clbl->key);
+
+ if (i+1 < size) {
+ emitpcode (POC_INCF, popGet (AOP(left), 0));
+ emitSKPNZ;
+ emitpcode (POC_INCF, popGet (AOP(left), 1));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),i));
+ } // for
+ if (size > 1) {
+ /* restore left's value */
+ emitpcode (POC_MOVLW, popGetLit (size-1));
+ emitpcode (POC_SUBWF, popGet (AOP(left), 0));
+ emitSKPC;
+ emitpcode (POC_DECF, popGet (AOP(left), 1));
+ } // if
+ } // if (lit)
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
{
operand *left, *result ;
sym_link *type, *etype;
- int p_type;
+ int p_type = -1;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
left = IC_LEFT(ic);
break;
case GPOINTER:
- if (IS_PTR_CONST(type))
+ if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype))
genConstPointerGet (left,result,ic);
else
genGenPointerGet (left,result,ic);
break;
+ default:
+ assert ( !"unhandled pointer type" );
+ break;
}
}
static void
emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
{
- switch (p_type)
+ FENTRY;
+ switch (p_type)
{
case IPOINTER:
case POINTER:
static void
emitPtrByteSet (char *rname, int p_type, char *src)
{
- switch (p_type)
+ FENTRY;
+ switch (p_type)
{
case IPOINTER:
case POINTER:
int bstr; /* bitfield starting bit within byte */
int litval; /* source literal value (if AOP_LIT) */
unsigned char mask; /* bitmask within current byte */
-
+
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
blen = SPEC_BLEN (etype);
if (p_type == -1) {
pCodeOp *pcop;
if (AOP(result)->type == AOP_PCODE)
- pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
else
pcop = popGet(AOP(result),0);
emitpcode(lit?POC_BSF:POC_BCF,pcop);
if (blen==1) {
if (p_type == -1) {
/* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
- emitpcode(POC_RLF,popGet(AOP(right),0));
+ emitpcode(POC_RRFW,popGet(AOP(right),0));
emitSKPC;
- emitpcode(POC_BCF,popGet(AOP(result),0));
+ emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
emitSKPNC;
- emitpcode(POC_BSF,popGet(AOP(result),0));
+ emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+ return;
} else if (p_type!=GPOINTER) {
/* Case with a bitfield length == 1 and no generic pointer
*/
/* SetIrp - Set IRP bit */
/*-----------------------------------------------------------------*/
void SetIrp(operand *result) {
+ FENTRY;
if (AOP_TYPE(result) == AOP_LIT) {
unsigned lit = (unsigned)operandLitValue(result);
emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
/* genDataPointerSet - remat pointer to data space */
/*-----------------------------------------------------------------*/
static void genDataPointerSet(operand *right,
- operand *result,
- iCode *ic)
+ operand *result,
+ iCode *ic)
{
int size, offset = 0 ;
- char *l, buffer[256];
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(right,ic,FALSE);
+ aopOp(result,ic,FALSE);
- l = aopGet(AOP(result),0,FALSE,TRUE);
size = AOP_SIZE(right);
/*
if ( AOP_TYPE(result) == AOP_PCODE) {
// tsd, was l+1 - the underline `_' prefix was being stripped
while (size--) {
- if (offset) {
- sprintf(buffer,"(%s + %d)",l,offset);
- fprintf(stderr,"oops %s\n",buffer);
- } else
- sprintf(buffer,"%s",l);
+ emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
if (AOP_TYPE(right) == AOP_LIT) {
unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
lit = lit >> (8*offset);
if(lit&0xff) {
emitpcode(POC_MOVLW, popGetLit(lit&0xff));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
} else {
- emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),offset));
}
} else {
emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
}
offset++;
int direct = 0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(result,ic,FALSE);
char *rname , *l;
sym_link *retype;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
retype= getSpec(operandType(right));
int size, offset ;
sym_link *retype = getSpec(operandType(right));
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(result,ic,FALSE);
sym_link *retype = getSpec(operandType(right));
sym_link *letype = getSpec (ptype);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(result,ic,FALSE);
sym_link *type, *etype;
int p_type;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
right = IC_RIGHT(ic);
operand *cond = IC_COND(ic);
int isbit =0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(cond,ic,FALSE);
operand *right, *result, *left;
int size, offset ;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((result=IC_RESULT(ic)),ic,TRUE);
DEBUGpic14_AopType(__LINE__,left,right,result);
+ assert (IS_SYMOP (left));
+
+ /* sanity check: generic pointers to code space are not yet supported,
+ * pionters to codespace must not be assigned addresses of __data values. */
+ #if 0
+ fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
+ fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
+ fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
+ fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
+ fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
+#endif
+
+ if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ }
size = AOP_SIZE(IC_RESULT(ic));
offset = 0;
result = IC_RESULT(ic);
right = IC_RIGHT(ic) ;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* if they are the same */
/* if they are the same registers */
if (pic14_sameRegs(AOP(right),AOP(result)))
goto release;
+
+ /* special case: assign from __code */
+ if (!IS_ITEMP(right) /* --> iTemps never reside in __code */
+ && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
+ && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */
+ && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
+ {
+ emitpComment ("genAssign from CODESPACE");
+ genConstPointerGet (right, result, ic);
+ goto release;
+ }
+ /* just for symmetry reasons... */
+ if (!IS_ITEMP(result)
+ && IS_SYMOP (result)
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
+ {
+ assert ( !"cannot write to CODESPACE" );
+ }
+
/* if the result is a bit */
if (AOP_TYPE(result) == AOP_CRY) {
symbol *jtab;
char *l;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(IC_JTCOND(ic),ic,FALSE);
*/
static int genMixedOperation (iCode *ic)
{
+ FENTRY;
#if 0
operand *result = IC_RESULT(ic);
sym_link *ctype = operandType(IC_LEFT(ic));
operand *right = IC_RIGHT(ic);
int size, offset ;
+ FENTRY;
DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
/* if they are equivalent then do nothing */
if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- emitpcode(POC_MOVLW, popGet(AOP(right),0));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_MOVLW, popGet(AOP(right),1));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
emitpcode(POC_MOVWF, popGet(AOP(result),1));
if(AOP_SIZE(result) <2)
fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
if ((AOP_TYPE(right) == AOP_PCODE) &&
AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- emitpcode(POC_MOVLW, popGet(AOP(right),offset));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0));
emitpcode(POC_MOVWF, popGet(AOP(result),offset));
} else {
aopPut(AOP(result),
static int genDjnz (iCode *ic, iCode *ifx)
{
symbol *lbl, *lbl1;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (!ifx)
/*-----------------------------------------------------------------*/
static void genReceive (iCode *ic)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (isOperandInFarSpace(IC_RESULT(ic)) &&
static void
genDummyRead (iCode * ic)
{
+ FENTRY;
pic14_emitcode ("; genDummyRead","");
pic14_emitcode ("; not implemented","");
{
iCode *ic;
int cln = 0;
+ const char *cline;
+ FENTRY;
lineHead = lineCurr = NULL;
pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
for (ic = lic ; ic ; ic = ic->next ) {
- DEBUGpic14_emitcode(";ic","");
- if ( cln != ic->lineno ) {
- if ( options.debug ) {
- debugFile->writeCLine (ic);
- }
- /*
- pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
- pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
- printCLine(ic->filename, ic->lineno));
- */
- if (!options.noCcodeInAsm) {
- addpCode2pBlock(pb,
- newpCodeCSource(ic->lineno,
- ic->filename,
- printCLine(ic->filename, ic->lineno)));
- }
-
- cln = ic->lineno ;
- }
+ //DEBUGpic14_emitcode(";ic","");
+ //fprintf (stderr, "in ic loop\n");
+ //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
+ //ic->lineno, printCLine(ic->filename, ic->lineno));
- // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
+ if (!options.noCcodeInAsm && (cln != ic->lineno)) {
+ cln = ic->lineno;
+ //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
+ cline = printCLine (ic->filename, ic->lineno);
+ if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
+ addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
+ //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
+ }
+ if (options.iCodeInAsm) {
+ emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
+ }
/* if the result is marked as
spilt and rematerializable or code for
this has already been generated then
return;
}
+
+int
+aop_isLitLike (asmop *aop)
+{
+ assert (aop);
+ if (aop->type == AOP_LIT) return 1;
+ if (aop->type == AOP_IMMD) return 1;
+ if ((aop->type == AOP_PCODE) &&
+ ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE)))
+ {
+ /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
+ * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
+ return 1;
+ }
+ return 0;
+}
+
+int
+op_isLitLike (operand *op)
+{
+ assert (op);
+ if (aop_isLitLike (AOP(op))) return 1;
+ return 0;
+}