#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 *);
-pCode *AssembleLine(char *line);
extern void printpBlock(FILE *of, pBlock *pb);
static int labelOffset=0;
pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
unsigned int pic14aopLiteral (value *val, int offset);
const char *AopType(short type);
-static iCode *ifxForOp ( operand *op, iCode *ic );
-#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
static char *spname = "sp";
char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
-//char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
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;
about an iCode ifx that makes it easier to generate code.
*/
typedef struct resolvedIfx {
- symbol *lbl; /* pointer to a label */
+ symbol *lbl; /* pointer to a label */
int condition; /* true or false ifx */
- int generated; /* set true when the code associated with the ifx
- * is generated */
+ int generated; /* set true when the code associated with the ifx
+ * is generated */
} resolvedIfx;
extern int pic14_ptrRegReq ;
{
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);
if (sym->onStack && options.stack10bit)
{
- /* It's on the 10 bit stack, which is located in
- * far data space.
+ /* It's on the 10 bit stack, which is located in
+ * far data space.
*/
//DEBUGpic14_emitcode(";","%d",__LINE__);
}
/*-----------------------------------------------------------------*/
-/* pic14_sameRegs - two asmops have the same registers */
+/* pic14_sameRegs - two asmops have the same registers */
/*-----------------------------------------------------------------*/
bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
{
}
/*-----------------------------------------------------------------*/
-/* aopOp - allocates an asmop for an operand : */
+/* aopOp - allocates an asmop for an operand : */
/*-----------------------------------------------------------------*/
void aopOp (operand *op, iCode *ic, bool result)
{
if (!op)
return ;
- // DEBUGpic14_emitcode(";","%d",__LINE__);
/* if this a literal */
if (IS_OP_LITERAL(op)) {
op->aop = aop = newAsmop(AOP_LIT);
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;
+ }
}
{
pCodeOp *pcop = aop->aopu.pcop;
DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
if(pcop->name) {
- DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
- //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
- sprintf(s,"%s", pcop->name);
+ if (offset) {
+ DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
+ sprintf(s,"(%s+%d)", pcop->name,offset);
+ } else {
+ DEBUGpic14_emitcode(";","%s",pcop->name);
+ sprintf(s,"%s", pcop->name);
+ }
} else
sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
}
/*-----------------------------------------------------------------*/
-/* popGetTempReg - create a new temporary pCodeOp */
+/* popReleaseTempReg - create a new temporary pCodeOp */
/*-----------------------------------------------------------------*/
void popReleaseTempReg(pCodeOp *pcop)
{
}
/*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion */
+/* popGetLit - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGetLit(unsigned int lit)
{
/*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion */
+/* popGetWithString - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGetWithString(char *str, int isExtern)
{
//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;
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
pcop->type = PO_DIR;
- /*
- if (offset)
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
- else
- sprintf(s,"%s",aop->aopu.aop_dir);
- pcop->name = Safe_calloc(1,strlen(s)+1);
- strcpy(pcop->name,s);
- */
pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
strcpy(pcop->name,aop->aopu.aop_dir);
PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
PCOR(pcop)->instance = offset;
pcop->type = PCOR(pcop)->r->pc_type;
//rs = aop->aopu.aop_reg[offset]->name;
- DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
+ DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
return pcop;
}
*/
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));
sym_link *type = operandType(op);
if (IS_GENPTR(type))
{
- /* generic pointer; arithmetic operations
- * should ignore the high byte (pointer type).
+ /* generic pointer; arithmetic operations
+ * should ignore the high byte (pointer type).
*/
size--;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/*-----------------------------------------------------------------*/
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 */
AopType(AOP_TYPE(IC_LEFT(sic))));
if(!firstTimeThruLoop) {
- /* If this is not the first time we've been through the loop
- * then we need to save the parameter in a temporary
- * register. The last byte of the last parameter is
+ /* If this is not the first time we've been through the loop
+ * then we need to save the parameter in a temporary
+ * register. The last byte of the last parameter is
* passed in W. */
emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
}
emitpcode(POC_CALL,popGetWithString(name,isExtern));
if (isExtern) {
- emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
+ emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
}
GpsuedoStkPtr=0;
/* if we need assign a result value */
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);
}
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
-registers :-) */
+ registers :-) */
if (!FUNC_REGBANK(sym->type)) {
/* if this function does not call any other
{
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));
}
freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
jumpret:
-/* generate a jump to the return label
+ /* generate a jump to the return label
if the next is not the return statement */
if (!(ic->next && ic->next->op == LABEL &&
IC_LABEL(ic->next) == returnLabel)) {
/*-----------------------------------------------------------------*/
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);
default:
emitpcode(POC_MOVFW, popGet(AOP(right),0));
emitpcode(POC_ADDLW, popGetLit(0x80));
- emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 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))
return NULL ;
- /* if this has register type condition and
- the next instruction is ifx with the same operand
+ /* 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 &&
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);
switch(lit & 0xff) {
case 0x00:
/* and'ing with 0 has clears the result */
- pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
emitpcode(POC_CLRF,popGet(AOP(result),offset));
break;
case 0xff:
int p = my_powof2( (~lit) & 0xff );
if(p>=0) {
/* only one bit is set in the literal, so use a bcf instruction */
- pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
} else {
- pic14_emitcode("movlw","0x%x", (lit & 0xff));
- pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
if(know_W != (int)(lit&0xff))
emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
know_W = lit &0xff;
int t = (lit >> (offset*8)) & 0x0FFL;
switch(t) {
case 0x00:
- pic14_emitcode("clrf","%s",
- aopGet(AOP(result),offset,FALSE,FALSE));
emitpcode(POC_CLRF,popGet(AOP(result),offset));
break;
case 0xff:
if(AOP_TYPE(left) != AOP_ACC) {
- pic14_emitcode("movf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s",
- aopGet(AOP(result),offset,FALSE,FALSE));
emitpcode(POC_MOVFW,popGet(AOP(left),offset));
}
emitpcode(POC_MOVWF,popGet(AOP(result),offset));
if(AOP_TYPE(left) == AOP_ACC) {
emitpcode(POC_ANDLW, popGetLit(t));
} else {
- pic14_emitcode("movlw","0x%x",t);
- pic14_emitcode("andwf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s",
- aopGet(AOP(result),offset,FALSE,FALSE));
-
emitpcode(POC_MOVLW, popGetLit(t));
emitpcode(POC_ANDFW,popGet(AOP(left),offset));
}
}
if (AOP_TYPE(left) == AOP_ACC) {
- pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
emitpcode(POC_ANDFW,popGet(AOP(right),offset));
} else {
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("andwf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
emitpcode(POC_MOVFW,popGet(AOP(right),offset));
emitpcode(POC_ANDFW,popGet(AOP(left),offset));
}
- pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
emitpcode(POC_MOVWF,popGet(AOP(result),offset));
}
}
int size, offset=0;
unsigned long lit = 0L;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp((left = IC_LEFT(ic)),ic,FALSE);
else if((AOP_TYPE(result) == AOP_CRY) && ifx)
genIfxJump(ifx, "c");
goto release ;
- }
-
- // if(val | 0xZZ) - size = 0, ifx != FALSE -
- // bit = val | 0xZZ - size = 1, ifx = FALSE -
- if((AOP_TYPE(right) == AOP_LIT) &&
+ }
+
+ // if(val | 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val | 0xZZ - size = 1, ifx = FALSE -
+ if((AOP_TYPE(right) == AOP_LIT) &&
(AOP_TYPE(result) == AOP_CRY) &&
(AOP_TYPE(left) != AOP_CRY)){
- if(lit){
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
- // result = 1
- if(size)
- pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
- else
- continueIfTrue(ifx);
- goto release;
- } else {
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
- // lit = 0, result = boolean(left)
- if(size)
- pic14_emitcode(";XXX setb","c");
- pic14_toBoolean(right);
- if(size){
- symbol *tlbl = newiTempLabel(NULL);
- pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- } else {
- genIfxJump (ifx,"a");
- goto release;
- }
- }
- pic14_outBitC(result);
- goto release ;
- }
-
- /* if left is same as result */
- if(pic14_sameRegs(AOP(result),AOP(left))){
- int know_W = -1;
- for(;size--; offset++,lit>>=8) {
- if(AOP_TYPE(right) == AOP_LIT){
- if((lit & 0xff) == 0)
- /* or'ing with 0 has no effect */
- continue;
- else {
- int p = my_powof2(lit & 0xff);
- if(p>=0) {
- /* only one bit is set in the literal, so use a bsf instruction */
- emitpcode(POC_BSF,
- newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
- } else {
- if(know_W != (int)(lit & 0xff))
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- know_W = lit & 0xff;
- emitpcode(POC_IORWF, popGet(AOP(left),offset));
- }
-
- }
- } else {
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORFW, popGet(AOP(right),offset));
- pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_IORWF, popGet(AOP(left),offset));
-
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-
- }
- }
- }
- } else {
- // left & result in different registers
- if(AOP_TYPE(result) == AOP_CRY){
- // result = bit
- // if(size), result in bit
- // if(!size && ifx), conditional oper: if(left | right)
- symbol *tlbl = newiTempLabel(NULL);
- int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-
-
- if(size)
- pic14_emitcode(";XXX setb","c");
- while(sizer--){
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode(";XXX orl","a,%s",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
- offset++;
- }
- if(size){
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(result);
- } else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- } else for(;(size--);offset++){
- // normal case
- // result = left & right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- if (AOP_TYPE(left) != AOP_ACC) {
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
-
- break;
- default:
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORLW, popGetLit(t));
- } else {
- emitpcode(POC_MOVLW, popGetLit(t));
- emitpcode(POC_IORFW, popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
- continue;
- }
-
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORWF, popGet(AOP(right),offset));
- pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_IORFW, popGet(AOP(left),offset));
-
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("iorwf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
- }
- }
-
+ if(lit){
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ // result = 1
+ if(size)
+ pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
+ else
+ continueIfTrue(ifx);
+ goto release;
+ } else {
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ // lit = 0, result = boolean(left)
+ if(size)
+ pic14_emitcode(";XXX setb","c");
+ pic14_toBoolean(right);
+ if(size){
+ symbol *tlbl = newiTempLabel(NULL);
+ pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ } else {
+ genIfxJump (ifx,"a");
+ goto release;
+ }
+ }
+ pic14_outBitC(result);
+ goto release ;
+ }
+
+ /* if left is same as result */
+ if(pic14_sameRegs(AOP(result),AOP(left))){
+ int know_W = -1;
+ for(;size--; offset++,lit>>=8) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ if((lit & 0xff) == 0)
+ /* or'ing with 0 has no effect */
+ continue;
+ else {
+ int p = my_powof2(lit & 0xff);
+ if(p>=0) {
+ /* only one bit is set in the literal, so use a bsf instruction */
+ emitpcode(POC_BSF,
+ newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+ } else {
+ if(know_W != (int)(lit & 0xff))
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ know_W = lit & 0xff;
+ emitpcode(POC_IORWF, popGet(AOP(left),offset));
+ }
+
+ }
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORFW, popGet(AOP(right),offset));
+ pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+ emitpcode(POC_IORWF, popGet(AOP(left),offset));
+
+ pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left | right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+ if(size)
+ pic14_emitcode(";XXX setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode(";XXX orl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else for(;(size--);offset++){
+ // normal case
+ // result = left | right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ if (AOP_TYPE(left) != AOP_ACC) {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+
+ break;
+ default:
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORLW, popGetLit(t));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(t));
+ emitpcode(POC_IORFW, popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+ continue;
+ }
+
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORFW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_IORFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+ }
+
release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
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");
}
// and better if result is SFR
if (AOP_TYPE(left) == AOP_ACC) {
emitpcode(POC_XORFW,popGet(AOP(right),offset));
- pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
} else {
emitpcode(POC_MOVFW,popGet(AOP(right),offset));
emitpcode(POC_XORFW,popGet(AOP(left),offset));
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
}
if ( AOP_TYPE(result) != AOP_ACC){
emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
}
}
}
/*-----------------------------------------------------------------*/
static void genInline (iCode *ic)
{
- char *buffer, *bp, *bp1;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- _G.inLine += (!options.asmpeep);
-
- buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
- strcpy(buffer,IC_INLINE(ic));
-
- /* emit each line as a code */
- while (*bp) {
- if (*bp == '\n') {
- *bp++ = '\0';
-
- if(*bp1)
- addpCode2pBlock(pb,AssembleLine(bp1));
- bp1 = bp;
- } else {
- if (*bp == ':') {
- bp++;
- *bp = '\0';
- bp++;
- pic14_emitcode(bp1,"");
- bp1 = bp;
- } else
- bp++;
- }
- }
- if ((bp1 != bp) && *bp1)
- addpCode2pBlock(pb,AssembleLine(bp1));
-
- Safe_free(buffer);
-
- _G.inLine -= (!options.asmpeep);
+ char *buffer, *bp, *bp1;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ _G.inLine += (!options.asmpeep);
+
+ buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
+ strcpy(buffer,IC_INLINE(ic));
+
+ /* emit each line as a code */
+ while (*bp) {
+ if (*bp == '\n') {
+ *bp++ = '\0';
+
+ if(*bp1)
+ addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+ bp1 = bp;
+ } else {
+ if (*bp == ':') {
+ bp++;
+ *bp = '\0';
+ bp++;
+
+ /* print label, use this special format with NULL directive
+ * to denote that the argument should not be indented with tab */
+ addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
+
+ bp1 = bp;
+ } else
+ bp++;
+ }
+ }
+ if ((bp1 != bp) && *bp1)
+ addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+
+ Safe_free(buffer);
+
+ _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));
/*-----------------------------------------------------------------*/
/* AccRol - rotate left accumulator by known count */
/*-----------------------------------------------------------------*/
-static void AccRol (int shCount)
+static void AccRol (operand *op,int offset,int shCount)
{
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
shCount &= 0x0007; // shCount : 0..7
switch(shCount){
break;
case 1 :
pic14_emitcode("rl","a");
+ emitpcode(POC_RLF,popGet(AOP(op),offset));
break;
case 2 :
pic14_emitcode("rl","a");
pic14_emitcode("rl","a");
+ emitpcode(POC_RLF,popGet(AOP(op),offset));
+ emitpcode(POC_RLF,popGet(AOP(op),offset));
break;
case 3 :
pic14_emitcode("swap","a");
pic14_emitcode("rr","a");
+ emitpcode(POC_SWAPF,popGet(AOP(op),offset));
+ emitpcode(POC_RRF,popGet(AOP(op),offset));
break;
case 4 :
pic14_emitcode("swap","a");
+ emitpcode(POC_SWAPF,popGet(AOP(op),offset));
break;
case 5 :
pic14_emitcode("swap","a");
pic14_emitcode("rl","a");
+ emitpcode(POC_SWAPF,popGet(AOP(op),offset));
+ emitpcode(POC_RLF,popGet(AOP(op),offset));
break;
case 6 :
pic14_emitcode("rr","a");
pic14_emitcode("rr","a");
+ emitpcode(POC_RRF,popGet(AOP(op),offset));
+ emitpcode(POC_RRF,popGet(AOP(op),offset));
break;
case 7 :
pic14_emitcode("rr","a");
+ emitpcode(POC_RRF,popGet(AOP(op),offset));
break;
}
}
/*-----------------------------------------------------------------*/
/* AccLsh - left shift accumulator by known count */
/*-----------------------------------------------------------------*/
-static void AccLsh (int 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");
- else
- if(shCount == 2) {
- pic14_emitcode("add","a,acc");
- pic14_emitcode("add","a,acc");
- } else {
- /* rotate left accumulator */
- AccRol(shCount);
- /* and kill the lower order bits */
- pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
- }
+ if(shCount != 0) {
+ if (shCount == 1)
+ {
+ emitCLRC;
+ emitpcode (POC_RLF, popGet (AOP(op), 0));
+ } else {
+ /* 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));
+ }
}
}
/*-----------------------------------------------------------------*/
/* AccRsh - right shift accumulator by known count */
/*-----------------------------------------------------------------*/
-static void AccRsh (int shCount)
+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(8 - shCount);
+ 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));
case 2:
case 3:
if(sign)
- emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
else
emitCLRC;
}
}
-
/*-----------------------------------------------------------------*/
/* 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(shCount);
+ 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(shCount);
+ 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)
{
operand *left,*right, *result;
int size, offset;
+ unsigned long lit = 0L;
char *l;
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 */
}
}
+ if(AOP_TYPE(left) == AOP_LIT)
+ lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
+
size = AOP_SIZE(result);
/* if it is only one byte then */
if (size == 1) {
- if(optimized_for_speed) {
+ if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
emitpcode(POC_SWAPFW, popGet(AOP(left),0));
emitpcode(POC_ANDLW, popGetLit(0xf0));
emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
tlbl = newiTempLabel(NULL);
if (!pic14_sameRegs(AOP(left),AOP(result))) {
- 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
size = AOP_SIZE(result);
offset=0;
while (size--) {
- /*
- l = aopGet(AOP(left),offset,FALSE,TRUE);
- if (*l == '@' && IS_AOP_PREG(result)) {
-
- pic14_emitcode("mov","a,%s",l);
- aopPut(AOP(result),"a",offset);
- } else
- aopPut(AOP(result),l,offset);
+ /*
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && IS_AOP_PREG(result)) {
+ pic14_emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else
+ aopPut(AOP(result),l,offset);
*/
emitpcode(POC_MOVFW, popGet(AOP(left),offset));
emitpcode(POC_MOVWF, popGet(AOP(result),offset));
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 */
/*-----------------------------------------------------------------*/
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
-static void genUnpackBits (operand *result, char *rname, int ptype)
+static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
{
- int shCnt ;
- int rlen = 0 ;
- sym_link *etype;
- int offset = 0 ;
-
+ int shCnt;
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ 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));
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* single bit field case */
+ if (blen == 1) {
+ if (ifx) { /* that is for an if statement */
+ pCodeOp *pcop;
+ resolvedIfx rIfx;
+ resolveIfx(&rIfx,ifx);
+ if (ptype == -1) /* direct */
+ 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);
+ emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+ 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(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(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) {
case POINTER:
case IPOINTER:
- pic14_emitcode("mov","a,@%s",rname);
+// pic14_emitcode("mov","a,@%s",rname);
+ emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
break;
case PPOINTER:
pic14_emitcode("lcall","__gptrget");
break;
}
-
+
/* if we have bitdisplacement then it fits */
/* into this byte completely or if length is */
/* less than a byte */
- if ((shCnt = SPEC_BSTR(etype)) ||
- (SPEC_BLEN(etype) <= 8)) {
+ if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) {
/* shift right acc */
- AccRsh(shCnt);
+ AccRsh(left,0,shCnt);
pic14_emitcode("anl","a,#0x%02x",
((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
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++;
}
}
#endif
/*-----------------------------------------------------------------*/
-/* genNearPointerGet - pic14_emitcode for near pointer fetch */
+/* genNearPointerGet - pic14_emitcode for near pointer fetch */
/*-----------------------------------------------------------------*/
static void genNearPointerGet (operand *left,
operand *result,
iCode *ic)
{
asmop *aop = NULL;
- //regs *preg = NULL ;
- char *rname ;
- sym_link *rtype, *retype;
- sym_link *ltype = operandType(left);
- //char buffer[80];
-
+ sym_link *ltype = operandType(left);
+ sym_link *rtype = operandType(result);
+ sym_link *retype= getSpec(rtype); /* bitfield type information */
+ int direct = 0;
+
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- rtype = operandType(result);
- retype= getSpec(rtype);
aopOp(left,ic,FALSE);
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 ;
}
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp (result,ic,FALSE);
- /* if the value is already in a pointer register
- then don't need anything more */
- if (!AOP_INPREG(AOP(left))) {
+ /* Check if can access directly instead of via a pointer */
+ if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
+ direct = 1;
+ }
+
+ /* If the pointer value is not in a the FSR then need to put it in */
+ if (!AOP_INPREG(AOP(left)) && !direct) {
/* otherwise get a free pointer register */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /*
- aop = newAsmop(0);
- preg = getFreePtr(ic,&aop,FALSE);
- pic14_emitcode("mov","%s,%s",
- preg->name,
- aopGet(AOP(left),0,FALSE,TRUE));
- rname = preg->name ;
- */
- rname ="BAD";
- } else
- rname = aopGet(AOP(left),0,FALSE,FALSE);
+ 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));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
+ }
- aopOp (result,ic,FALSE);
+// sym_link *etype;
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genUnpackBits (result,rname,POINTER);
+ genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
else {
/* we have can just get the values */
int size = AOP_SIZE(result);
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- emitpcode(POC_MOVFW,popGet(AOP(left),0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
while(size--) {
- emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
- emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
- if(size)
+ if (direct)
+ emitpcode(POC_MOVWF,popGet(AOP(left),0));
+ else
+ emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+ if (AOP_TYPE(result) == AOP_LIT) {
+ emitpcode(POC_MOVLW,popGet(AOP(result),offset));
+ } else {
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ }
+ if (size && !direct)
emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+ offset++;
}
- /*
- while (size--) {
- if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
-
- pic14_emitcode("mov","a,@%s",rname);
- aopPut(AOP(result),"a",offset);
- } else {
- sprintf(buffer,"@%s",rname);
- aopPut(AOP(result),buffer,offset);
- }
- offset++ ;
- if (size)
- pic14_emitcode("inc","%s",rname);
- }
- */
}
/* now some housekeeping stuff */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
freeAsmop(NULL,aop,ic,TRUE);
} else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
belongs */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (AOP_SIZE(result) > 1 &&
ic->depth )) {
int size = AOP_SIZE(result) - 1;
while (size--)
- pic14_emitcode("dec","%s",rname);
+ emitpcode(POC_DECF, popCopyReg(&pc_fsr));
}
}
/* done */
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
-
+
}
/*-----------------------------------------------------------------*/
char *rname ;
sym_link *rtype, *retype;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
rtype = operandType(result);
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genUnpackBits (result,rname,PPOINTER);
+ genUnpackBits (result,left,rname,PPOINTER,0);
else {
/* we have can just get the values */
int size = AOP_SIZE(result);
int size, offset ;
sym_link *retype = getSpec(operandType(result));
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(left,ic,FALSE);
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genUnpackBits(result,"dptr",FPOINTER);
+ genUnpackBits(result,left,"dptr",FPOINTER,0);
else {
size = AOP_SIZE(result);
offset = 0 ;
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genUnpackBits(result,"dptr",CPOINTER);
+ genUnpackBits(result,left,"dptr",CPOINTER,0);
else {
size = AOP_SIZE(result);
offset = 0 ;
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;
}
}
/*-----------------------------------------------------------------*/
-/* genPackBits - generates code for packed bit storage */
+/* emitPtrByteGet - for legacy 8051 emits code to get a byte into */
+/* A through a pointer register (R0, R1, or DPTR). The original */
+/* value of A can be preserved in B. */
+/* PIC has to use INDF register. */
/*-----------------------------------------------------------------*/
-static void genPackBits (sym_link *etype ,
- operand *right ,
- char *rname, int p_type)
-{
- int shCount = 0 ;
- int offset = 0 ;
- int rLen = 0 ;
- int blen, bstr ;
- char *l ;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- blen = SPEC_BLEN(etype);
- bstr = SPEC_BSTR(etype);
-
- l = aopGet(AOP(right),offset++,FALSE,FALSE);
- MOVA(l);
-
- /* if the bit lenth is less than or */
- /* it exactly fits a byte then */
- if (SPEC_BLEN(etype) <= 8 ) {
- shCount = SPEC_BSTR(etype) ;
+static void
+emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
+{
+ FENTRY;
+ switch (p_type)
+ {
+ case IPOINTER:
+ case POINTER:
+ if (preserveAinB)
+ pic14_emitcode ("mov", "b,a");
+// pic14_emitcode ("mov", "a,@%s", rname);
+ emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
+ break;
- /* shift left acc */
- AccLsh(shCount);
+ case PPOINTER:
+ if (preserveAinB)
+ pic14_emitcode ("mov", "b,a");
+ pic14_emitcode ("movx", "a,@%s", rname);
+ break;
- if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
-
-
- switch (p_type) {
- case POINTER:
- pic14_emitcode ("mov","b,a");
- pic14_emitcode("mov","a,@%s",rname);
- break;
-
- case FPOINTER:
- pic14_emitcode ("mov","b,a");
- pic14_emitcode("movx","a,@dptr");
- break;
-
- case GPOINTER:
- pic14_emitcode ("push","b");
- pic14_emitcode ("push","acc");
- pic14_emitcode ("lcall","__gptrget");
- pic14_emitcode ("pop","b");
- break;
- }
-
- pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
- ((unsigned char)(0xFF << (blen+bstr)) |
- (unsigned char)(0xFF >> (8-bstr)) ) );
- pic14_emitcode ("orl","a,b");
- if (p_type == GPOINTER)
- pic14_emitcode("pop","b");
- }
- }
-
- switch (p_type) {
- case POINTER:
- pic14_emitcode("mov","@%s,a",rname);
+ case FPOINTER:
+ if (preserveAinB)
+ pic14_emitcode ("mov", "b,a");
+ pic14_emitcode ("movx", "a,@dptr");
break;
- case FPOINTER:
- pic14_emitcode("movx","@dptr,a");
+ case CPOINTER:
+ if (preserveAinB)
+ pic14_emitcode ("mov", "b,a");
+ pic14_emitcode ("clr", "a");
+ pic14_emitcode ("movc", "a,@a+dptr");
break;
- case GPOINTER:
- DEBUGpic14_emitcode(";lcall","__gptrput");
+ case GPOINTER:
+ if (preserveAinB)
+ {
+ pic14_emitcode ("push", "b");
+ pic14_emitcode ("push", "acc");
+ }
+ pic14_emitcode ("lcall", "__gptrget");
+ if (preserveAinB)
+ pic14_emitcode ("pop", "b");
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* emitPtrByteSet - emits code to set a byte from src through a */
+/* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */
+/*-----------------------------------------------------------------*/
+static void
+emitPtrByteSet (char *rname, int p_type, char *src)
+{
+ FENTRY;
+ switch (p_type)
+ {
+ case IPOINTER:
+ case POINTER:
+ if (*src=='@')
+ {
+ MOVA (src);
+ pic14_emitcode ("mov", "@%s,a", rname);
+ }
+ else
+// pic14_emitcode ("mov", "@%s,%s", rname, src);
+ emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
break;
- }
-
- /* if we r done */
- if ( SPEC_BLEN(etype) <= 8 )
- return ;
-
- pic14_emitcode("inc","%s",rname);
- rLen = SPEC_BLEN(etype) ;
-
- /* now generate for lengths greater than one byte */
- while (1) {
- l = aopGet(AOP(right),offset++,FALSE,TRUE);
+ case PPOINTER:
+ MOVA (src);
+ pic14_emitcode ("movx", "@%s,a", rname);
+ break;
- rLen -= 8 ;
- if (rLen <= 0 )
- break ;
+ case FPOINTER:
+ MOVA (src);
+ pic14_emitcode ("movx", "@dptr,a");
+ break;
- switch (p_type) {
- case POINTER:
- if (*l == '@') {
- MOVA(l);
- pic14_emitcode("mov","@%s,a",rname);
- } else
- pic14_emitcode("mov","@%s,%s",rname,l);
- break;
-
- case FPOINTER:
- MOVA(l);
- pic14_emitcode("movx","@dptr,a");
- break;
-
- case GPOINTER:
- MOVA(l);
- DEBUGpic14_emitcode(";lcall","__gptrput");
- break;
- }
- pic14_emitcode ("inc","%s",rname);
- }
+ case GPOINTER:
+ MOVA (src);
+ pic14_emitcode ("lcall", "__gptrput");
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage */
+/*-----------------------------------------------------------------*/
+static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
+{
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ 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__);
- MOVA(l);
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
- /* last last was not complete */
- if (rLen) {
- /* save the byte & read byte */
- switch (p_type) {
- case POINTER:
- pic14_emitcode ("mov","b,a");
- pic14_emitcode("mov","a,@%s",rname);
- break;
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ mask = ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr)));
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with a bitfield length <8 and literal source
+ */
+ int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ if (blen == 1) {
+ if (p_type == -1) {
+ pCodeOp *pcop;
+ if (AOP(result)->type == AOP_PCODE)
+ pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
+ else
+ pcop = popGet(AOP(result),0);
+ emitpcode(lit?POC_BSF:POC_BCF,pcop);
+ } else {
+ emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
+ }
+ return;
+ } else {
+ litval = lit << bstr;
+ litval &= (~mask) & 0xff;
+ if (p_type == -1)
+ emitpcode(POC_MOVFW,popGet(AOP(result),0));
+ else
+ emitPtrByteGet (rname, p_type, FALSE);
+ if ((mask|litval)!=0xff)
+ emitpcode(POC_ANDLW,popGetLit(mask));
+ if (litval)
+ emitpcode(POC_IORLW,popGetLit(litval));
+ }
+ }
+ else
+ {
+ 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_RRFW,popGet(AOP(right),0));
+ emitSKPC;
+ emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+ emitSKPNC;
+ 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
+ */
+ if (AOP_TYPE (right) == AOP_CRY)
+ pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
+ else
+ {
+ MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+ pic14_emitcode ("rrc","a");
+ }
+ emitPtrByteGet (rname, p_type, FALSE);
+ pic14_emitcode ("mov","acc.%d,c",bstr);
+ }
+ }
+ else
+ {
+ //bool pushedB;
+ /* Case with a bitfield length < 8 and arbitrary source
+ */
+ MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+ /* shift and mask source value */
+ AccLsh (right,0,bstr);
+ pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
+ emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
+
+ //pushedB = pushB ();
+ if (p_type == -1)
+ emitpcode(POC_MOVFW,popGet(AOP(result),0));
+ else
+ emitPtrByteGet (rname, p_type, TRUE);
+
+ pic14_emitcode ("anl", "a,#0x%02x", mask);
+ pic14_emitcode ("orl", "a,b");
+ emitpcode(POC_ANDLW,popGetLit(mask));
+ emitpcode(POC_IORFW,popGet(AOP(right),0));
+ if (p_type == GPOINTER)
+ pic14_emitcode ("pop", "b");
+
+ //popB (pushedB);
+ }
+ }
+
+ if (p_type == -1)
+ emitpcode(POC_MOVWF,popGet(AOP(result),0));
+ else
+ emitPtrByteSet (rname, p_type, "a");
+ return;
+ }
+
+ /* Bit length is greater than 7 bits. In this case, copy */
+ /* all except the partial byte at the end */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ emitPtrByteSet (rname, p_type,
+ aopGet (AOP (right), offset++, FALSE, TRUE) );
+ if (rlen>8)
+ pic14_emitcode ("inc", "%s", rname);
+ }
+
+ /* If there was a partial byte at the end */
+ if (rlen)
+ {
+ mask = (((unsigned char) -1 << rlen) & 0xff);
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with partial byte and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval >>= (blen-rlen);
+ litval &= (~mask) & 0xff;
+ emitPtrByteGet (rname, p_type, FALSE);
+ if ((mask|litval)!=0xff)
+ pic14_emitcode ("anl","a,#0x%02x", mask);
+ if (litval)
+ pic14_emitcode ("orl","a,#0x%02x", litval);
+ }
+ else
+ {
+ //bool pushedB;
+ /* Case with partial byte and arbitrary source
+ */
+ MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
+ pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
- case FPOINTER:
- pic14_emitcode ("mov","b,a");
- pic14_emitcode("movx","a,@dptr");
- break;
+ //pushedB = pushB ();
+ /* transfer A to B and get next byte */
+ emitPtrByteGet (rname, p_type, TRUE);
- case GPOINTER:
- pic14_emitcode ("push","b");
- pic14_emitcode ("push","acc");
- pic14_emitcode ("lcall","__gptrget");
- pic14_emitcode ("pop","b");
- break;
- }
-
- pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
- pic14_emitcode ("orl","a,b");
- }
-
- if (p_type == GPOINTER)
- pic14_emitcode("pop","b");
+ pic14_emitcode ("anl", "a,#0x%02x", mask);
+ pic14_emitcode ("orl", "a,b");
+ if (p_type == GPOINTER)
+ pic14_emitcode ("pop", "b");
+
+ //popB (pushedB);
+ }
+ emitPtrByteSet (rname, p_type, "a");
+ }
- switch (p_type) {
-
- case POINTER:
- pic14_emitcode("mov","@%s,a",rname);
- break;
-
- case FPOINTER:
- pic14_emitcode("movx","@dptr,a");
- break;
-
- case GPOINTER:
- DEBUGpic14_emitcode(";lcall","__gptrput");
- break;
+}
+
+/*-----------------------------------------------------------------*/
+/* 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));
+ } else {
+ if (PCOP(AOP(result))->type == PO_LITERAL) {
+ int addrs = PCOL(AOP(result))->lit;
+ emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
+ } else {
+ emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
+ if(AOP_SIZE(result) > 1) {
+ emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
+ emitpcode(POC_BSF, 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) {
- pic14_emitcode("movlw","%d",lit);
- pic14_emitcode("movwf","%s",buffer);
-
emitpcode(POC_MOVLW, popGetLit(lit&0xff));
- //emitpcode(POC_MOVWF, popRegFromString(buffer));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
-
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
} else {
- pic14_emitcode("clrf","%s",buffer);
- //emitpcode(POC_CLRF, popRegFromString(buffer));
- emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),offset));
}
- }else {
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s",buffer);
-
+ } else {
emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- //emitpcode(POC_MOVWF, popRegFromString(buffer));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
-
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
}
offset++;
}
/*-----------------------------------------------------------------*/
-/* genNearPointerSet - pic14_emitcode for near pointer put */
+/* genNearPointerSet - pic14_emitcode for near pointer put */
/*-----------------------------------------------------------------*/
static void genNearPointerSet (operand *right,
operand *result,
iCode *ic)
{
asmop *aop = NULL;
- char *l;
- sym_link *retype;
sym_link *ptype = operandType(result);
+ sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec(ptype);
+ int direct = 0;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- retype= getSpec(operandType(right));
-
aopOp(result,ic,FALSE);
/* if the result is rematerializable &
in data space & not a bit variable */
//if (AOP_TYPE(result) == AOP_IMMD &&
- if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
+ if (AOP_TYPE(result) == AOP_PCODE &&
DCL_TYPE(ptype) == POINTER &&
- !IS_BITFIELD(retype)) {
+ !IS_BITVAR (retype) &&
+ !IS_BITVAR (letype)) {
genDataPointerSet (right,result,ic);
freeAsmop(result,NULL,ic,TRUE);
return;
}
-
+
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(right,ic,FALSE);
DEBUGpic14_AopType(__LINE__,NULL,right,result);
- /* if the value is already in a pointer register
- then don't need anything more */
- if (!AOP_INPREG(AOP(result))) {
- /* otherwise get a free pointer register */
- //aop = newAsmop(0);
- //preg = getFreePtr(ic,&aop,FALSE);
+ /* Check if can access directly instead of via a pointer */
+ if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
+ direct = 1;
+ }
+
+ /* If the pointer value is not in a the FSR then need to put it in */
+ if (!AOP_INPREG(AOP(result)) && !direct) {
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- //pic14_emitcode("mov","%s,%s",
- // preg->name,
- // aopGet(AOP(result),0,FALSE,TRUE));
- //rname = preg->name ;
- //pic14_emitcode("movwf","fsr");
- emitpcode(POC_MOVFW, popGet(AOP(result),0));
+ if (PCOP(AOP(result))->type == PO_LITERAL)
+ emitpcode(POC_MOVLW, popGet(AOP(result),0));
+ else
+ emitpcode(POC_MOVFW, popGet(AOP(result),0));
emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
- goto release;
-
- }// else
- // rname = aopGet(AOP(result),0,FALSE,FALSE);
-
-
- /* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype)) {
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "The programmer is obviously confused");
- //genPackBits (retype,right,rname,POINTER);
- exit(1);
}
- else {
+
+ /* Must set/reset IRP bit for use with FSR. */
+ /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
+ if (!direct)
+ SetIrp(result);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
+ genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
+ } else {
/* we have can just get the values */
int size = AOP_SIZE(right);
int offset = 0 ;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
while (size--) {
- l = aopGet(AOP(right),offset,FALSE,TRUE);
+ char *l = aopGet(AOP(right),offset,FALSE,TRUE);
if (*l == '@' ) {
- //MOVA(l);
- //pic14_emitcode("mov","@%s,a",rname);
- pic14_emitcode("movf","indf,w ;1");
+ emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
} else {
-
if (AOP_TYPE(right) == AOP_LIT) {
- unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
- if(lit) {
- pic14_emitcode("movlw","%s",l);
- pic14_emitcode("movwf","indf ;2");
- } else
- pic14_emitcode("clrf","indf");
- }else {
- pic14_emitcode("movf","%s,w",l);
- pic14_emitcode("movwf","indf ;2");
+ emitpcode(POC_MOVLW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
}
- //pic14_emitcode("mov","@%s,%s",rname,l);
+ if (direct)
+ emitpcode(POC_MOVWF,popGet(AOP(result),0));
+ else
+ emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
}
- if (size)
- pic14_emitcode("incf","fsr,f ;3");
- //pic14_emitcode("inc","%s",rname);
+ if (size && !direct)
+ emitpcode(POC_INCF,popCopyReg(&pc_fsr));
offset++;
}
}
/* we had to allocate for this iCode */
freeAsmop(NULL,aop,ic,TRUE);
} else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
belongs */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (AOP_SIZE(right) > 1 &&
ic->depth )) {
int size = AOP_SIZE(right) - 1;
while (size--)
- pic14_emitcode("decf","fsr,f");
- //pic14_emitcode("dec","%s",rname);
+ emitpcode(POC_DECF, popCopyReg(&pc_fsr));
}
}
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* done */
-release:
+
freeAsmop(right,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
char *rname , *l;
sym_link *retype;
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
retype= getSpec(operandType(right));
/* if bitfield then unpack the bits */
if (IS_BITFIELD(retype))
- genPackBits (retype,right,rname,PPOINTER);
+ genPackBits (retype,result,right,rname,PPOINTER);
else {
/* we have can just get the values */
int size = AOP_SIZE(right);
int size, offset ;
sym_link *retype = getSpec(operandType(right));
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(result,ic,FALSE);
/* if bit then unpack */
if (IS_BITFIELD(retype))
- genPackBits(retype,right,"dptr",FPOINTER);
+ genPackBits(retype,result,right,"dptr",FPOINTER);
else {
size = AOP_SIZE(right);
offset = 0 ;
static void genGenPointerSet (operand *right,
operand *result, iCode *ic)
{
- int size, offset ;
+ sym_link *ptype = operandType(result);
sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec (ptype);
+ FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(result,ic,FALSE);
aopOp(right,ic,FALSE);
- size = AOP_SIZE(right);
DEBUGpic14_AopType(__LINE__,NULL,right,result);
pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
}
- else { /* we need to get it byte by byte */
- //char *l = aopGet(AOP(result),0,FALSE,FALSE);
- size = AOP_SIZE(right);
- offset = 0 ;
-
- /* hack hack! see if this the FSR. If so don't load W */
- if(AOP_TYPE(right) != AOP_ACC) {
-
-
- emitpcode(POC_MOVFW,popGet(AOP(result),0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-
- if(AOP_SIZE(result) > 1) {
- emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
- emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
-
- }
-
- //if(size==2)
- //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
- //if(size==4) {
- // emitpcode(POC_MOVLW,popGetLit(0xfd));
- // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
- //}
-
- while(size--) {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
- emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-
- if(size)
- emitpcode(POC_INCF,popCopyReg(&pc_fsr));
- }
-
-
- goto release;
- }
-
- if(aopIdx(AOP(result),0) != 4) {
-
- emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
- goto release;
- }
-
- emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
- goto release;
-
+ else {
+ emitpcode(POC_MOVFW,popGet(AOP(result),0));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
+
+ /* Must set/reset IRP bit for use with FSR. */
+ /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
+ SetIrp(result);
}
}
- /* so dptr know contains the address */
-
-
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genPackBits(retype,right,"dptr",GPOINTER);
- else {
- size = AOP_SIZE(right);
- offset = 0 ;
-
- DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
+ genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
+ } else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
while (size--) {
-
- emitpcode(POC_MOVFW,popGet(AOP(result),offset));
- emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
-
- if (AOP_TYPE(right) == AOP_LIT)
- emitpcode(POC_MOVLW, popGet(AOP(right),offset));
- else
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
-
- emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
-
+ char *l = aopGet(AOP(right),offset,FALSE,TRUE);
+ if (*l == '@' ) {
+ emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+ } else {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ emitpcode(POC_MOVLW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ }
+ emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+ }
+ if (size)
+ emitpcode(POC_INCF,popCopyReg(&pc_fsr));
offset++;
}
}
-release:
freeAsmop(right,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
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
break;
case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
if (ic->next &&
ic->next->op == IFX &&
regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
case GE_OP:
case NE_OP:
- /* note these two are xlated by algebraic equivalence
+ /* note these two are xlated by algebraic equivalence
during parsing SDCC.y */
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
"got '>=' or '<=' shouldn't have come here");
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;
+}