#ifdef HAVE_ENDIAN_H
#include <endian.h>
#else
+#ifndef __BORLANDC__
#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
#endif
#endif
+#endif
#include "common.h"
#include "SDCCpeeph.h"
static char *zero = "#0x00";
static char *one = "#0x01";
static char *spname ;
-static char *fReturn[] = {"dpl","dph","b","a" };
+
+char *fReturn8051[] = {"dpl","dph","b","a" };
+char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
+unsigned fReturnSize = 4; /* shared with ralloc.c */
+char **fReturn = fReturn8051;
static char *accUse[] = {"a","b"};
static short rbank = -1;
instruction, in which case we are in trouble */
if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
(r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
+ {
goto endOfWorld;
-
+ }
r0ou = bitVectBitValue(ic->rMask,R0_IDX);
r1ou = bitVectBitValue(ic->rMask,R1_IDX);
if (!r0iu && !r0ou) {
ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
(*aopp)->type = AOP_R0;
+
return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R0_IDX);
}
if (!r1iu && !r1ou) {
ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
(*aopp)->type = AOP_R1;
+
return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R1_IDX);
}
mcs51_regWithIdx(R0_IDX)->dname);
_G.r0Pushed++ ;
}
-
+
ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
(*aopp)->type = AOP_R0;
mcs51_regWithIdx(R1_IDX)->dname);
_G.r1Pushed++ ;
}
-
+
ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
(*aopp)->type = AOP_R1;
return mcs51_regWithIdx(R1_IDX);
}
-
endOfWorld :
/* I said end of world but not quite end of world yet */
- /* if this is a result then we canpush it on the stack*/
+ /* if this is a result then we can push it on the stack*/
if (result) {
(*aopp)->type = AOP_STK;
return NULL;
static int pointerCode (link *etype)
{
int p_type;
- if (SPEC_OCLS(etype)->codesp ) {
- p_type = CPOINTER ;
- }
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- p_type = FPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- p_type = PPOINTER;
- else
- if (SPEC_OCLS(etype) == idata )
- p_type = IPOINTER;
- else
- p_type = POINTER ;
- return p_type;
+
+ return PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) { */
+/* p_type = CPOINTER ; */
+/* } */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER; */
+/* else */
+/* p_type = POINTER ; */
+/* return p_type; */
}
/*-----------------------------------------------------------------*/
/* assign depending on the storage class */
/* if it is on the stack or indirectly addressable */
/* space we need to assign either r0 or r1 to it */
- if (sym->onStack || sym->iaccess) {
+ if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
sym->aop = aop = newAsmop(0);
aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
aop->size = getSize(sym->type);
if (aop->type != AOP_STK) {
if (sym->onStack) {
-
if ( _G.accInUse )
emitcode("push","acc");
if ( _G.accInUse )
emitcode("pop","acc");
-
} else
emitcode("mov","%s,#%s",
aop->aopu.aop_ptr->name,
aop->aopu.aop_stk = sym->stack;
return aop;
}
+
+ if (sym->onStack && options.stack10bit)
+ {
+ /* It's on the 10 bit stack, which is located in
+ * far data space.
+ */
+
+ if (result)
+ {
+ fprintf(stderr,
+ "*** Internal error: 10 bit stack var used as result.\n");
+ emitcode(";", "look at me!");
+ }
+
+
+ if ( _G.accInUse )
+ emitcode("push","acc");
+
+ emitcode("mov","a,_bp");
+ emitcode("add","a,#0x%02x",
+ ((sym->stack < 0) ?
+ ((char)(sym->stack - _G.nRegsSaved )) :
+ ((char)sym->stack)) & 0xff);
+
+ if (/* result */ 1)
+ {
+ emitcode (";", "#switchDPTR(2)");
+ }
+ emitcode ("mov","dpx,#0x40");
+ emitcode ("mov","dph,#0x00");
+ emitcode ("mov", "dpl, a");
+ if (/* result */ 1)
+ {
+ emitcode (";", "#switchDPTR(1)");
+ }
+
+ if ( _G.accInUse )
+ emitcode("pop","acc");
+
+ if (/* !result */ 0)
+ {
+ sym->aop = aop = newAsmop(AOP_DPTR);
+ }
+ else
+ {
+ sym->aop = aop = newAsmop(AOP_DPTR2);
+ }
+ aop->size = getSize(sym->type);
+ return aop;
+ }
/* if in bit space */
if (IN_BITSPACE(space)) {
sym->aop = aop = newAsmop(AOP_IMMD);
ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
strcpy(aop->aopu.aop_immd,sym->rname);
- aop->size = 2;
+ aop->size = FPTRSIZE;
return aop;
}
int i;
aop = op->aop = sym->aop = newAsmop(AOP_STR);
aop->size = getSize(sym->type);
- for ( i = 0 ; i < 4 ; i++ )
+ for ( i = 0 ; i < fReturnSize ; i++ )
aop->aopu.aop_str[i] = fReturn[i];
return;
}
bitVectUnSetBit(ic->rUsed,R1_IDX);
getFreePtr(ic,&aop,FALSE);
+
+ if (options.stack10bit)
+ {
+ /* I'm not sure what to do here yet... */
+ /* #STUB */
+ fprintf(stderr,
+ "*** Warning: probably generating bad code for "
+ "10 bit stack mode.\n");
+ }
+
if (stk) {
emitcode ("mov","a,_bp");
emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
- } else
+ } else {
emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
+ }
while (sz--) {
emitcode("pop","acc");
return rs;
case AOP_DPTR:
+ case AOP_DPTR2:
+
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(2)");
+ }
+
while (offset > aop->coff) {
emitcode ("inc","dptr");
aop->coff++;
}
else
emitcode("movx","a,@dptr");
+
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(1)");
+ }
+
return (dname ? "acc" : "a");
break;
case AOP_DPTR:
+ case AOP_DPTR2:
+
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(2)");
+ }
+
if (aop->code) {
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
"aopPut writting to code space");
MOVA(s);
emitcode ("movx","@dptr,a");
+
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(1)");
+ }
break;
case AOP_R0:
if (strcmp(s,"a")) {
MOVA(s);
- }
- emitcode("cjne","a,#0x01,%05d$",lbl->key+100);
- emitcode("","%05d$:",lbl->key+100);
+ }
+ emitcode("clr","c");
+ emitcode("jz","%05d$",lbl->key+100);
emitcode("cpl","c");
+ emitcode("","%05d$:",lbl->key+100);
emitcode("mov","%s,c",aop->aopu.aop_dir);
}
}
while (size--)
emitcode("dec","%s",aop->aopu.aop_ptr->name);
break;
- case AOP_DPTR :
+ case AOP_DPTR :
+ case AOP_DPTR2:
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(2)");
+ }
while (size--)
emitcode("lcall","__decdptr");
+
+ if (aop->type == AOP_DPTR2)
+ {
+ emitcode (";", "#switchDPTR(1)");
+ }
break;
}
AOP_TYPE(x) == AOP_R0))
#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \
- AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged))
+ AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
+ AOP(x)->paged))
#define AOP_INPREG(x) (x && (x->type == AOP_REG && \
(x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \
aopPut(res->aop,zero,offset++);
}
+/*-----------------------------------------------------------------*/
+/* opIsGptr: returns non-zero if the passed operand is */
+/* a generic pointer type. */
+/*-----------------------------------------------------------------*/
+static int opIsGptr(operand *op)
+{
+ link *type = operandType(op);
+
+ if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
+ {
+ return 1;
+ }
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* getDataSize - get the operand data size */
/*-----------------------------------------------------------------*/
{
int size;
size = AOP_SIZE(op);
- if(size == 3)
- /* pointer */
- size--;
+ if (size == GPTRSIZE)
+ {
+ link *type = operandType(op);
+ if (IS_GENPTR(type))
+ {
+ /* generic pointer; arithmetic operations
+ * should ignore the high byte (pointer type).
+ */
+ size--;
+ }
+ }
return size;
}
emitcode("push","acc");
emitcode("mov","a,#(%05d$ >> 8)",(rlbl->key+100));
emitcode("push","acc");
+
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov","a,#(%05d$ >> 16)",(rlbl->key+100));
+ emitcode("push","acc");
+ }
/* now push the calling address */
aopOp(IC_LEFT(ic),ic,FALSE);
- pushSide(IC_LEFT(ic), 2);
+ pushSide(IC_LEFT(ic), FPTRSIZE);
freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
return 0;
}
+#ifdef __BORLANDC__
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
/*-----------------------------------------------------------------*/
/* inExcludeList - return 1 if the string is in exclude Reg list */
/*-----------------------------------------------------------------*/
int i =0;
if (options.excludeRegs[i] &&
- strcasecmp(options.excludeRegs[i],"none") == 0)
+ STRCASECMP(options.excludeRegs[i],"none") == 0)
return FALSE ;
for ( i = 0 ; options.excludeRegs[i]; i++) {
if (options.excludeRegs[i] &&
- strcasecmp(s,options.excludeRegs[i]) == 0)
+ STRCASECMP(s,options.excludeRegs[i]) == 0)
return TRUE;
}
return FALSE ;
emitcode ("push","dpl");
if (!inExcludeList("dph"))
emitcode ("push","dph");
-
+ if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
+ emitcode ("push", "dpx");
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
registers :-) */
emitcode("inc","%s",spname);
}
else
+ {
/* set up the stack */
emitcode ("push","_bp"); /* save the callers stack */
+ }
emitcode ("mov","_bp,%s",spname);
}
symbol *sym = OP_SYMBOL(IC_LEFT(ic));
if (IS_RENT(sym->etype) || options.stackAuto)
+ {
emitcode ("mov","%s,_bp",spname);
+ }
/* if use external stack but some variables were
added to the local stack then decrement the
emitcode("dec","%s",spname);
}
else
+ {
emitcode ("pop","_bp");
+ }
}
/* restore the register bank */
}
}
+ if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
+ emitcode ("pop", "dpx");
if (!inExcludeList("dph"))
emitcode ("pop","dph");
if (!inExcludeList("dpl"))
while (size--) {
char *l ;
if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
+ /* #NOCHANGE */
l = aopGet(AOP(IC_LEFT(ic)),offset++,
FALSE,TRUE);
emitcode("push","%s",l);
emitcode ("ljmp","%05d$",(IC_LABEL(ic)->key+100));
}
+/*-----------------------------------------------------------------*/
+/* findLabelBackwards: walks back through the iCode chain looking */
+/* for the given label. Returns number of iCode instructions */
+/* between that label and given ic. */
+/* Returns zero if label not found. */
+/*-----------------------------------------------------------------*/
+static int findLabelBackwards(iCode *ic, int key)
+{
+ int count = 0;
+
+ while (ic->prev)
+ {
+ ic = ic->prev;
+ count++;
+
+ if (ic->op == LABEL && IC_LABEL(ic)->key == key)
+ {
+ /* printf("findLabelBackwards = %d\n", count); */
+ return count;
+ }
+ }
+
+ /* printf("findLabelBackwards: not found.\n"); */
+
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* genPlusIncr :- does addition with increment if possible */
/*-----------------------------------------------------------------*/
if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
(size > 1) &&
(icount == 1)) {
- symbol *tlbl = newiTempLabel(NULL);
+ symbol *tlbl;
+ int emitTlbl;
+ int labelRange;
+
+ /* If the next instruction is a goto and the goto target
+ * is < 10 instructions previous to this, we can generate
+ * jumps straight to that target.
+ */
+ if (ic->next && ic->next->op == GOTO
+ && (labelRange = findLabelBackwards(ic, IC_LABEL(ic->next)->key)) != 0
+ && labelRange <= 10 )
+ {
+ emitcode(";", "tail increment optimized");
+ tlbl = IC_LABEL(ic->next);
+ emitTlbl = 0;
+ }
+ else
+ {
+ tlbl = newiTempLabel(NULL);
+ emitTlbl = 1;
+ }
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
}
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- if(size == 4){
+ if (size > 2)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0x00,%05d$"
,tlbl->key+100);
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ }
+ if (size > 3)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0x00,%05d$"
}
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
}
- emitcode("","%05d$:",tlbl->key+100);
+
+ if (emitTlbl)
+ {
+ emitcode("","%05d$:",tlbl->key+100);
+ }
return TRUE;
}
}
}
+#if 0
+/* This is the original version of this code.
+ *
+ * This is being kept around for reference,
+ * because I am not entirely sure I got it right...
+ */
+static void adjustArithmeticResult(iCode *ic)
+{
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) < 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) < 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,2);
+ }
+}
+#else
+/* This is the pure and virtuous version of this code.
+ * I'm pretty certain it's right, but not enough to toss the old
+ * code just yet...
+ */
+static void adjustArithmeticResult(iCode *ic)
+{
+ if (opIsGptr(IC_RESULT(ic)) &&
+ opIsGptr(IC_LEFT(ic)) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ {
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
+ }
+
+ if (opIsGptr(IC_RESULT(ic)) &&
+ opIsGptr(IC_RIGHT(ic)) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ {
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
+ }
+
+ if (opIsGptr(IC_RESULT(ic)) &&
+ AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
+ AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
+ }
+}
+#endif
+
/*-----------------------------------------------------------------*/
/* genPlus - generates code for addition */
/*-----------------------------------------------------------------*/
aopPut(AOP(IC_RESULT(ic)),"a",offset++);
}
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
- 2);
+ adjustArithmeticResult(ic);
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_RIGHT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
- 2);
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) < 3 &&
- AOP_SIZE(IC_RIGHT(ic)) < 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- aopPut(AOP(IC_RESULT(ic)),buffer,2);
- }
release:
freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
static bool genMinusDec (iCode *ic)
{
unsigned int icount ;
- unsigned int size = getDataSize(IC_RESULT(ic));
+ unsigned int size = getDataSize(IC_RESULT(ic));
/* will try to generate an increment */
/* if the right side is not a literal
if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4)
return FALSE ;
- size = getDataSize(IC_RESULT(ic));
/* if decrement 16 bits in register */
if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
(size > 1) &&
(icount == 1)) {
- symbol *tlbl = newiTempLabel(NULL);
+ symbol *tlbl;
+ int emitTlbl;
+ int labelRange;
+
+ /* If the next instruction is a goto and the goto target
+ * is <= 10 instructions previous to this, we can generate
+ * jumps straight to that target.
+ */
+ if (ic->next && ic->next->op == GOTO
+ && (labelRange = findLabelBackwards(ic, IC_LABEL(ic->next)->key)) != 0
+ && labelRange <= 10 )
+ {
+ emitcode(";", "tail decrement optimized");
+ tlbl = IC_LABEL(ic->next);
+ emitTlbl = 0;
+ }
+ else
+ {
+ tlbl = newiTempLabel(NULL);
+ emitTlbl = 1;
+ }
+
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
,tlbl->key+100);
}
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- if(size == 4){
+ if (size > 2)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0xff,%05d$"
,tlbl->key+100);
}
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ }
+ if (size > 3)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0xff,%05d$"
}
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
}
- emitcode("","%05d$:",tlbl->key+100);
+ if (emitTlbl)
+ {
+ emitcode("","%05d$:",tlbl->key+100);
+ }
return TRUE;
}
}
aopPut(AOP(IC_RESULT(ic)),"a",offset++);
}
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
- 2);
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_RIGHT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
- 2);
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) < 3 &&
- AOP_SIZE(IC_RIGHT(ic)) < 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- aopPut(AOP(IC_RESULT(ic)),buffer,2);
- }
+ adjustArithmeticResult(ic);
+
release:
freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
// c = bit ^ val
// if val>>1 != 0, result = 1
emitcode("setb","c");
- while(sizer--){
+ while(sizer){
MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
if(sizer == 1)
// test the msb of the lsb
emitcode("anl","a,#0xfe");
emitcode("jnz","%05d$",tlbl->key+100);
+ sizer--;
}
// val = (0,1)
emitcode("rrc","a");
/*-----------------------------------------------------------------*/
static void genlshTwo (operand *result,operand *left, int shCount)
{
- int size = AOP_SIZE(result);
-
- if (size == 3)
- size--;
+ int size;
+
+ size = getDataSize(result);
/* if shCount >= 8 */
if (shCount >= 8) {
else { /* we need to get it byte by byte */
emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
}
}
/* so dptr know contains the address */
else { /* we need to get it byte by byte */
emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
}
}
/* so dptr know contains the address */
else { /* we need to get it byte by byte */
emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
- emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
+ }
+ else
+ {
+ emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
}
}
/* so dptr know contains the address */
freeAsmop(left,NULL,ic,TRUE);
- aopOp(result,ic,FALSE);
+ aopOp(result,ic,FALSE);
/* if bit then unpack */
if (IS_BITVAR(retype))
if (IS_PTR(type) && !IS_FUNC(type->next))
p_type = DCL_TYPE(type);
else {
-
/* we have to go by the storage class */
- if (SPEC_OCLS(etype)->codesp ) {
- p_type = CPOINTER ;
- }
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- p_type = FPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- p_type = PPOINTER;
- else
- if (SPEC_OCLS(etype) == idata )
- p_type = IPOINTER;
- else
- p_type = POINTER ;
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) { */
+/* p_type = CPOINTER ; */
+/* } */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER; */
+/* else */
+/* p_type = POINTER ; */
}
/* now that we have the pointer type we assign
else { /* we need to get it byte by byte */
emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ }
}
}
/* so dptr know contains the address */
else { /* we need to get it byte by byte */
emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
- emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ emitcode("mov","b,%s",aopGet(AOP(result),3,FALSE,FALSE));
+ }
+ else
+ {
+ emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ }
}
}
/* so dptr know contains the address */
p_type = DCL_TYPE(type);
}
else {
-
/* we have to go by the storage class */
- if (SPEC_OCLS(etype)->codesp ) {
- p_type = CPOINTER ;
- }
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- p_type = FPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- p_type = PPOINTER ;
- else
- if (SPEC_OCLS(etype) == idata )
- p_type = IPOINTER ;
- else
- p_type = POINTER ;
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) { */
+/* p_type = CPOINTER ; */
+/* } */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER ; */
+/* else */
+/* p_type = POINTER ; */
}
/* now that we have the pointer type we assign
emitcode("mov","a,_bp");
emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
aopPut(AOP(IC_RESULT(ic)),"a",0);
- } else
+ } else {
/* we can just move _bp */
aopPut(AOP(IC_RESULT(ic)),"_bp",0);
+ }
/* fill the result with zero */
size = AOP_SIZE(IC_RESULT(ic)) - 1;
+
+
+ if (options.stack10bit && size < (FPTRSIZE - 1))
+ {
+ fprintf(stderr,
+ "*** warning: pointer to stack var truncated.\n");
+ }
+
offset = 1;
- while (size--)
- aopPut(AOP(IC_RESULT(ic)),zero,offset++);
+ while (size--)
+ {
+ /* Yuck! */
+ if (options.stack10bit && offset == 2)
+ {
+ aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
+ }
+ else
+ {
+ aopPut(AOP(IC_RESULT(ic)),zero,offset++);
+ }
+ }
goto release;
}
aopOp(right,ic,FALSE);
/* special case both in far space */
+ /* However, if we are using 10 bit stack mode,
+ * the result should be held in DPTR2,
+ * so we can operate without the special case.
+ *
+ * I think.
+ */
if (AOP_TYPE(right) == AOP_DPTR &&
IS_TRUE_SYMOP(result) &&
isOperandInFarSpace(result)) {
-
- genFarFarAssign (result,right,ic);
- return ;
+
+ if (!options.stack10bit)
+ {
+ genFarFarAssign (result,right,ic);
+ return ;
+ }
+ else
+ {
+ fprintf(stderr, "*** 10bit stack opt 1\n");
+ emitcode(";", "look at me: optimization possible?\n");
+ }
}
aopOp(result,ic,TRUE);
/* pointer to generic pointer */
if (IS_GENPTR(ctype)) {
- char *l = zero;
-
- if (IS_PTR(type))
- p_type = DCL_TYPE(type);
- else {
- /* we have to go by the storage class */
- if (SPEC_OCLS(etype)->codesp )
- p_type = CPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- p_type = FPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- p_type = PPOINTER;
- else
- if (SPEC_OCLS(etype) == idata )
- p_type = IPOINTER ;
- else
- p_type = POINTER ;
- }
+ char *l = zero;
+
+ if (IS_PTR(type))
+ p_type = DCL_TYPE(type);
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) */
+/* p_type = CPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER ; */
+/* else */
+/* p_type = POINTER ; */
+ }
- /* the first two bytes are known */
- size = 2;
- offset = 0 ;
- while (size--) {
- aopPut(AOP(result),
- aopGet(AOP(right),offset,FALSE,FALSE),
- offset);
- offset++;
- }
- /* the last byte depending on type */
- switch (p_type) {
- case IPOINTER:
- case POINTER:
- l = zero;
- break;
- case FPOINTER:
- l = one;
- break;
- case CPOINTER:
- l = "#0x02";
- break;
- case PPOINTER:
- l = "#0x03";
- break;
-
- default:
- /* this should never happen */
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "got unknown pointer type");
- exit(1);
- }
- aopPut(AOP(result),l,2);
- goto release ;
+ /* the first two bytes are known */
+ size = GPTRSIZE - 1;
+ offset = 0 ;
+ while (size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ /* the last byte depending on type */
+ switch (p_type) {
+ case IPOINTER:
+ case POINTER:
+ l = zero;
+ break;
+ case FPOINTER:
+ l = one;
+ break;
+ case CPOINTER:
+ l = "#0x02";
+ break;
+ case PPOINTER:
+ l = "#0x03";
+ break;
+
+ default:
+ /* this should never happen */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "got unknown pointer type");
+ exit(1);
+ }
+ aopPut(AOP(result),l, GPTRSIZE - 1);
+ goto release ;
}
/* just copy the pointers */
IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
int size = getSize(operandType(IC_RESULT(ic)));
- int offset = 4 - size;
+ int offset = fReturnSize - size;
while (size--) {
- emitcode ("push","%s", (strcmp(fReturn[3 - offset],"a") ?
- fReturn[3 - offset] : "acc"));
+ emitcode ("push","%s", (strcmp(fReturn[fReturnSize - offset - 1],"a") ?
+ fReturn[fReturnSize - offset - 1] : "acc"));
offset++;
}
aopOp(IC_RESULT(ic),ic,FALSE);