Made everything static
-------------------------------------------------------------------------*/
+#define D(x)
+//#define D(x) x
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
#endif
/* first check if r0 & r1 are used by this
instruction, in which case we are in trouble */
- if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
- (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
- {
+ r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+ r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+ if (r0iu && r1iu) {
goto endOfWorld;
}
/* other wise this is true end of the world */
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"getFreePtr should never reach here");
- exit (0);
+ exit (1);
}
/*-----------------------------------------------------------------*/
aopForSym (iCode * ic, symbol * sym, bool result)
{
asmop *aop;
- memmap *space = SPEC_OCLS (sym->etype);
+ memmap *space;
+
+ wassertl (ic != NULL, "Got a null iCode");
+ wassertl (sym != NULL, "Got a null symbol");
+
+ space = SPEC_OCLS (sym->etype);
/* if already has one */
if (sym->aop)
sym = OP_SYMBOL (op);
-
/* if the type is a conditional */
if (sym->regType == REG_CND)
{
if (sym->ruonly)
{
unsigned i;
+
aop = op->aop = sym->aop = newAsmop (AOP_STR);
aop->size = getSize (sym->type);
for (i = 0; i < fReturnSizeMCS51; i++)
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"aopget got unsupported aop->type");
- exit (0);
+ exit (1);
}
/*-----------------------------------------------------------------*/
/* aopPut - puts a string for a aop */
{
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"aopPut got offset > aop->size");
- exit (0);
+ exit (1);
}
/* will assign value to value */
{
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"aopPut writting to code space");
- exit (0);
+ exit (1);
}
while (offset > aop->coff)
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"aopPut got unsupported aop->type");
- exit (0);
+ exit (1);
}
}
return;
}
- /* if the registers have been saved already then
+ /* if the registers have been saved already or don't need to be then
do nothing */
- if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+ if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave) ||
+ SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT (ic))))
return;
/* find the registers in use at this time
detype = getSpec (operandType (IC_LEFT (ic)));
-#if 0 // why should we do this here??? jwk20011105
- if (detype &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype) &&
- !ic->bankSaved)
- saveRBank (SPEC_BANK (detype), ic, TRUE);
-#endif
-
}
/*-----------------------------------------------------------------*/
/* unsaveRegisters - pop the pushed registers */
int size, offset = 0;
char *l;
+ D(emitcode (";", "genIpush"));
+
/* if this is not a parm push : ie. it is spill push
and spill push is always done on the local stack */
if (!ic->parmPush)
bool restoreBank = FALSE;
bool swapBanks = FALSE;
+ D(emitcode(";", "genCall"));
/* if send set is not empty the assign */
if (_G.sendSet)
{
_G.sendSet = NULL;
}
- /* if we are calling a function that is not using
+ /* if we are calling a not _naked function that is not using
the same register bank then we need to save the
destination registers on the stack */
detype = getSpec (operandType (IC_LEFT (ic)));
- if (detype &&
+ if (detype && !SPEC_NAKED(detype) &&
(SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
IS_ISR (currFunc->etype))
{
emitcode ("", "%s:", sym->rname);
fetype = getSpec (operandType (IC_LEFT (ic)));
+ if (SPEC_NAKED(fetype))
+ {
+ emitcode(";", "naked function: no prologue.");
+ return;
+ }
+
/* if critical function then turn interrupts off */
if (SPEC_CRTCL (fetype))
emitcode ("clr", "ea");
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+ if (SPEC_NAKED(sym->etype))
+ {
+ emitcode(";", "naked function: no epilogue.");
+ return;
+ }
+
if (IS_RENT (sym->etype) || options.stackAuto)
{
emitcode ("mov", "%s,_bp", spname);
emitcode ("setb", "ea");
/* if debug then send end of function */
-/* if (options.debug && currFunc) { */
- if (currFunc)
+ /* if (options.debug && currFunc) */
+ if (options.debug && currFunc)
{
_G.debugLine = 1;
emitcode ("", "C$%s$%d$%d$%d ==.",
}
/* if debug then send end of function */
- if (currFunc)
+ if (options.debug && currFunc)
{
_G.debugLine = 1;
emitcode ("", "C$%s$%d$%d$%d ==.",
else
{
/* first add without previous c */
- if (!offset)
- emitcode ("add", "a,#0x%02x",
- (unsigned int) (lit & 0x0FFL));
- else
+ if (!offset) {
+ if (!size && lit==-1) {
+ emitcode ("dec", "a");
+ } else {
+ emitcode ("add", "a,#0x%02x",
+ (unsigned int) (lit & 0x0FFL));
+ }
+ } else {
emitcode ("addc", "a,#0x%02x",
(unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ }
}
aopPut (AOP (IC_RESULT (ic)), "a", offset++);
}
symbol *lbl;
int size=AOP_SIZE(result);
- //emitcode (";",__FUNCTION__);
if (size<1 || size>2) {
// this should never happen
fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
//emitcode (";", "signed");
emitcode ("clr", "F0"); // reset sign flag
- emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
lbl=newiTempLabel(NULL);
emitcode ("inc", "a");
emitcode ("", "%05d$:", lbl->key+100);
- emitcode ("xch", "a,b");
/* if literal */
if (AOP_TYPE(right)==AOP_LIT) {
+ signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
- if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) {
- // two's complement for literal<0
- emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
- emitcode ("cpl", "a");
- emitcode ("inc", "a");
+ if (val < 0) {
+ emitcode ("cpl", "F0"); // complement sign flag
+ emitcode ("mov", "b,#0x%02x", -val);
+ } else {
+ emitcode ("mov", "b,#0x%02x", val);
}
} else {
lbl=newiTempLabel(NULL);
+ emitcode ("mov", "b,a");
+ emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE));
emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
// right side is negative, 8-bit two's complement
- emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
+ emitcode ("cpl", "F0"); // complement sign flag
emitcode ("cpl", "a");
emitcode ("inc", "a");
emitcode ("", "%05d$:", lbl->key+100);
return lic;
}
/* if the operand used or deffed */
- if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) {
+ if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
return NULL;
}
lic = lic->next;
emitcode ("setb", "c");
while (sizer--)
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
- emitcode ("anl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ } else {
+ if (AOP_TYPE(left)==AOP_ACC) {
+ emitcode("mov", "b,a");
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode("anl", "a,b");
+ }else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE));
+ }
+ }
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
emitcode ("setb", "c");
while (sizer--)
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
- emitcode ("orl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("orl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ } else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("orl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE));
+ }
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
}
else
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
- emitcode ("xrl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ } else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE));
+ }
}
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
/* move it to the result */
size = AOP_SIZE (result);
offset = size - 1;
+ if (size == 1) { /* special case for 1 byte */
+ l = aopGet (AOP (left), offset, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("rr", "a");
+ goto release;
+ }
CLRC;
while (size--)
{
MOVA (l);
}
emitcode ("mov", "acc.7,c");
+ release:
aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
{
l = aopGet (AOP (left), offset, FALSE, FALSE);
MOVA (l);
+ if (size == 0) { /* special case for 1 byte */
+ emitcode("rl","a");
+ goto release;
+ }
emitcode ("add", "a,acc");
if (AOP_SIZE (result) > 1)
aopPut (AOP (result), "a", offset++);
MOVA (l);
}
emitcode ("mov", "acc.0,c");
+ release:
aopPut (AOP (result), "a", 0);
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
break;
case 2:
- case 3:
genlshTwo (result, left, shCount);
break;
case 4:
genlshFour (result, left, shCount);
break;
+ default:
+ fprintf(stderr, "*** ack! mystery literal shift!\n");
+ break;
}
}
freeAsmop (left, NULL, ic, TRUE);
shiftRLong (operand * left, int offl,
operand * result, int sign)
{
- if (!sign)
- emitcode ("clr", "c");
+ int isSameRegs=sameRegs(AOP(left),AOP(result));
+
+ if (isSameRegs && offl>1) {
+ // we are in big trouble, but this shouldn't happen
+ werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
+ }
+
MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
- if (sign)
+
+ if (offl==MSB16) {
+ // shift is > 8
+ if (sign) {
+ emitcode ("rlc", "a");
+ emitcode ("subb", "a,acc");
+ emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE));
+ } else {
+ aopPut (AOP(result), zero, MSB32);
+ }
+ }
+
+ if (!sign) {
+ emitcode ("clr", "c");
+ } else {
emitcode ("mov", "c,acc.7");
- emitcode ("rrc", "a");
- aopPut (AOP (result), "a", MSB32 - offl);
- if (offl == MSB16)
- /* add sign of "a" */
- addSign (result, MSB32, sign);
+ }
- MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
emitcode ("rrc", "a");
- aopPut (AOP (result), "a", MSB24 - offl);
- MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+ if (isSameRegs && offl==MSB16) {
+ emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE));
+ } else {
+ aopPut (AOP (result), "a", MSB32);
+ MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
+ }
+
+ emitcode ("rrc", "a");
+ if (isSameRegs && offl==1) {
+ emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE));
+ } else {
+ aopPut (AOP (result), "a", MSB24);
+ MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+ }
emitcode ("rrc", "a");
aopPut (AOP (result), "a", MSB16 - offl);
case CPOINTER:
emitcode ("clr", "a");
- emitcode ("movc", "a,%s", "@a+dptr");
+ emitcode ("movc", "a,@a+dptr");
break;
case GPOINTER:
case CPOINTER:
emitcode ("clr", "a");
emitcode ("inc", "dptr");
- emitcode ("movc", "a", "@a+dptr");
+ emitcode ("movc", "a,@a+dptr");
break;
case GPOINTER:
}
else
rname = aopGet (AOP (left), 0, FALSE, FALSE);
-
- aopOp (result, ic, FALSE);
+
+ //aopOp (result, ic, FALSE);
+ aopOp (result, ic, result?TRUE:FALSE);
/* if bitfield then unpack the bits */
if (IS_BITVAR (retype))
genDataPointerSet (right, result, ic);
return;
}
-
+
/* if the value is already in a pointer register
then don't need anything more */
if (!AOP_INPREG (AOP (result)))
int size, offset;
unsigned long lit = 0L;
+ D(emitcode(";","genAssign"));
+
result = IC_RESULT (ic);
right = IC_RIGHT (ic);
operand *right = IC_RIGHT (ic);
int size, offset;
+ D(emitcode(";", "genCast"));
+
/* if they are equivalent then do nothing */
if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
return;
aopOp (result, ic, FALSE);
/* if the result is a bit */
- if (AOP_TYPE (result) == AOP_CRY)
+ // if (AOP_TYPE (result) == AOP_CRY /* works only for true symbols */
+ if (IS_BITVAR(OP_SYMBOL(result)->type))
{
/* if the right size is a literal then
we know what the value is */
p_type = DCL_TYPE (type);
else
{
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
+ if (SPEC_SCLS(etype)==S_REGISTER) {
+ // let's assume it is a generic pointer
+ p_type=GPOINTER;
+ } else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE (SPEC_OCLS (etype));
+ }
}
/* the first two bytes are known */
case CPOINTER:
l = "#0x02";
break;
- case PPOINTER:
+ case GPOINTER:
+ l = "0x03";
+ break;
+ case PPOINTER: // what the fck is this?
l = "#0x03";
break;
/* now depending on the sign of the source && destination */
size = AOP_SIZE (result) - AOP_SIZE (right);
/* if unsigned or not an integral type */
- if (SPEC_USIGN (rtype) || !IS_SPEC (rtype))
+ if (SPEC_USIGN (rtype) || !IS_SPEC (rtype) || AOP_TYPE(right)==AOP_CRY)
{
while (size--)
aopPut (AOP (result), zero, offset++);
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* gen51AggregateAssign - copy complete array's or structures */
+/*-----------------------------------------------------------------*/
+void gen51AggregateAssign(iCode *ic) {
+ operand *left=IC_LEFT(ic);
+ operand *right=IC_RIGHT(ic);
+ char *fromName=OP_SYMBOL(right)->rname;
+ char *toName=OP_SYMBOL(left)->rname;
+ int fromSize=getSize(OP_SYMBOL(right)->type);
+ int toSize=getSize(OP_SYMBOL(left)->type);
+ int count=toSize;
+
+ if (SPEC_OCLS(OP_SYMBOL(left)->etype)!=xdata ||
+ SPEC_OCLS(OP_SYMBOL(right)->etype)!=code) {
+ // well, this code isn't used yet from anywhere else as for initialising
+ fprintf (stderr, "*** error: %s:%d can only assign aggregates from cseg to xseg for now\n", ic->filename, ic->lineno);
+ exit (457);
+ }
+
+ if (fromSize!=toSize) {
+ fprintf (stderr, "*** error: %s:%d aggregates have different size\n",
+ ic->filename, ic->lineno);
+ exit (821);
+ }
+
+#if 1
+ // use the generic memcpy() for now
+ emitcode (";", "initialize %s", OP_SYMBOL(IC_LEFT(ic))->name);
+ emitcode ("mov", "dptr,#_memcpy_PARM_2");
+ emitcode ("mov", "a,#%s", fromName);
+ emitcode ("movx", "@dptr,a");
+ emitcode ("inc", "dptr");
+ emitcode ("mov", "a,#(%s>>8)", fromName);
+ emitcode ("movx", "@dptr,a");
+ emitcode ("inc", "dptr");
+ emitcode ("mov", "a,#%02x; only from cseg for now", 2);
+ emitcode ("movx", "@dptr,a");
+ emitcode ("mov", "dptr,#_memcpy_PARM_3");
+ emitcode ("mov", "a,#(%d>>0); number of bytes", count);
+ emitcode ("movx", "@dptr,a");
+ emitcode ("inc", "dptr");
+ emitcode ("mov", "a,#(%d>>8)", count);
+ emitcode ("movx", "@dptr,a");
+ emitcode ("mov", "dptr,#%s", toName);
+ emitcode ("mov", "b,#%02x; only to xseg for now", 1);
+ emitcode ("lcall", "_memcpy");
+#else
+ // more efficient, but will require the native_memcpy_cs2xs
+ emitcode ("mov", "r0,#%s", fromName);
+ emitcode ("mov", "r1,#(%s>>8)", fromName);
+ emitcode ("mov", "r2,#%s", toName);
+ emitcode ("mov", "r3,#(%s>>8)", toName);
+ emitcode ("mov", "r4,#%d", count);
+ emitcode ("mov", "r5,#(%d>>8)", count);
+ emitcode ("lcall", "_native_memcpy_cs2xs");
+#endif
+}
+
/*-----------------------------------------------------------------*/
/* gen51Code - generate code for 8051 based controllers */
/*-----------------------------------------------------------------*/
if (allocInfo)
printAllocInfo (currFunc, codeOutFile);
/* if debug information required */
-/* if (options.debug && currFunc) { */
- if (currFunc)
+ /* if (options.debug && currFunc) { */
+ if (options.debug && currFunc)
{
cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
_G.debugLine = 1;
addSet (&_G.sendSet, ic);
break;
+ case ARRAYINIT:
+ gen51AggregateAssign(ic);
+ break;
+
default:
ic = ic;
}