Made everything static
-------------------------------------------------------------------------*/
-#define D(x)
-//#define D(x) x
+//#define D(x)
+#define D(x) x
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_SYS_ISA_DEFS_H
#include <sys/isa_defs.h>
#else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#else
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#else
#endif
#endif
#endif
+#endif
#include "common.h"
#include "SDCCpeeph.h"
if (IS_FUNC (sym->type))
{
sym->aop = aop = newAsmop (AOP_IMMD);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
- strcpy (aop->aopu.aop_immd, sym->rname);
+ aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
aop->size = FPTRSIZE;
return aop;
}
{
iCode *ic = sym->rematiCode;
asmop *aop = newAsmop (AOP_IMMD);
+ int ptr_type=0;
int val = 0;
for (;;)
val += (int) operandLitValue (IC_RIGHT (ic));
else if (ic->op == '-')
val -= (int) operandLitValue (IC_RIGHT (ic));
- else
- break;
+ else if (IS_CAST_ICODE(ic)) {
+ sym_link *from_type = operandType(IC_RIGHT(ic));
+ aop->aopu.aop_immd.from_cast_remat = 1;
+ ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ ptr_type = DCL_TYPE(from_type);
+ if (ptr_type == IPOINTER) {
+ // bug #481053
+ ptr_type = POINTER;
+ }
+ continue ;
+ } else break;
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
}
else
strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd, buffer);
+ aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+ /* set immd2 field if required */
+ if (aop->aopu.aop_immd.from_cast_remat) {
+ sprintf(buffer,"#0x%02x",ptr_type);
+ aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+ }
+
return 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++)
case AOP_IMMD:
- if (bit16)
- sprintf (s, "#%s", aop->aopu.aop_immd);
+ if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) {
+ sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
+ } else if (bit16)
+ sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
else if (offset)
sprintf (s, "#(%s >> %d)",
- aop->aopu.aop_immd,
+ aop->aopu.aop_immd.aop_immd1,
offset * 8);
else
sprintf (s, "#%s",
- aop->aopu.aop_immd);
+ aop->aopu.aop_immd.aop_immd1);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
if (strcmp (s, "a") == 0)
emitcode ("push", "acc");
else
- emitcode ("push", "%s", s);
+ if (*s=='@') {
+ MOVA(s);
+ emitcode ("push", "acc");
+ } else {
+ emitcode ("push", s);
+ }
break;
}
{
symbol *lbl = newiTempLabel (NULL);
- emitcode ("clr", "c; oops");
+ emitcode ("clr", "c");
emitcode ("jz", "%05d$", lbl->key + 100);
emitcode ("cpl", "c");
emitcode ("", "%05d$:", lbl->key + 100);
char *l;
symbol *tlbl;
+ D(emitcode (";", "genNotFloat"));
+
/* we will put 127 in the first byte of
the result */
aopPut (AOP (res), "#127", 0);
symbol *tlbl;
sym_link *optype = operandType (IC_LEFT (ic));
+ D(emitcode (";", "genNot"));
+
/* assign asmOps to operand & result */
aopOp (IC_LEFT (ic), ic, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE);
int size;
+ D(emitcode (";", "genCpl"));
+
/* assign asmOps to operand & result */
aopOp (IC_LEFT (ic), ic, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE);
{
int size, offset = 0;
char *l;
+
+ D(emitcode (";", "genUminusFloat"));
+
/* for this we just need to flip the
first it then copy the rest in place */
size = AOP_SIZE (op) - 1;
sym_link *optype, *rtype;
+ D(emitcode (";", "genUminus"));
+
/* assign asmops */
aopOp (IC_LEFT (ic), ic, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE);
int i;
iCode *ic;
bitVect *rsave;
- sym_link *detype;
/* look for call */
for (ic = lic; ic; ic = ic->next)
/* 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) ||
- SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT (ic))))
+ if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
+ IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic))))
return;
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- ic->rUsed);
+ /* safe the registers in use at this time but skip the
+ ones for the result */
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ mcs51_rUmaskForOp (IC_RESULT(ic)));
ic->regsSaved = 1;
if (options.useXstack)
if (bitVectBitValue (rsave, i))
emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
}
-
- detype = getSpec (operandType (IC_LEFT (ic)));
-
}
+
/*-----------------------------------------------------------------*/
/* unsaveRegisters - pop the pushed registers */
/*-----------------------------------------------------------------*/
{
int i;
bitVect *rsave;
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- ic->rUsed);
+
+ /* restore the registers in use at this time but skip the
+ ones for the result */
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ mcs51_rUmaskForOp (IC_RESULT(ic)));
if (options.useXstack)
{
regs *r;
int size, offset = 0;
+ D(emitcode (";", "genXpush"));
+
aopOp (IC_LEFT (ic), ic, FALSE);
r = getFreePtr (ic, &aop, FALSE);
{
int size, offset;
+ D(emitcode (";", "genIpop"));
/* if the temp was not pushed then */
if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
static void
genCall (iCode * ic)
{
- sym_link *detype;
+ sym_link *dtype;
bool restoreBank = FALSE;
bool swapBanks = FALSE;
D(emitcode(";", "genCall"));
+
/* if send set is not empty the assign */
if (_G.sendSet)
{
/* 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 && !SPEC_NAKED(detype) &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype))
+ dtype = operandType (IC_LEFT (ic));
+ if (dtype && !IFFUNC_ISNAKED(dtype) &&
+ (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+ IFFUNC_ISISR (currFunc->type))
{
if (!ic->bankSaved)
{
/* This is unexpected; the bank should have been saved in
* genFunction.
*/
- saveRBank (SPEC_BANK (detype), ic, FALSE);
+ saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
restoreBank = TRUE;
}
swapBanks = TRUE;
if (swapBanks)
{
emitcode ("mov", "psw,#0x%02x",
- ((SPEC_BANK(detype)) << 3) & 0xff);
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
}
/* make the call */
if (swapBanks)
{
emitcode ("mov", "psw,#0x%02x",
- ((SPEC_BANK(currFunc->etype)) << 3) & 0xff);
+ ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
}
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+ OP_SYMBOL (IC_RESULT (ic))->accuse ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
}
/* if we hade saved some registers then unsave them */
- if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
unsaveRegisters (ic);
/* if register bank was saved then pop them */
if (restoreBank)
- unsaveRBank (SPEC_BANK (detype), ic, FALSE);
+ unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
}
/*-----------------------------------------------------------------*/
static void
genPcall (iCode * ic)
{
- sym_link *detype;
+ sym_link *dtype;
symbol *rlbl = newiTempLabel (NULL);
+ bool restoreBank=FALSE;
+ D(emitcode(";", "genPCall"));
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
/* if we are calling a 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 &&
- IS_ISR (currFunc->etype) &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
- saveRBank (SPEC_BANK (detype), ic, TRUE);
-
+ dtype = operandType (IC_LEFT (ic));
+ if (dtype && !FUNC_ISNAKED(dtype) &&
+ IFFUNC_ISISR (currFunc->type) &&
+ (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
+ saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+ restoreBank=TRUE;
+ }
/* push the return address on to the stack */
emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
}
/* if register bank was saved then unsave them */
- if (detype &&
- (SPEC_BANK (currFunc->etype) !=
- SPEC_BANK (detype)))
- unsaveRBank (SPEC_BANK (detype), ic, TRUE);
+ if (restoreBank)
+ unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
/* if we hade saved some registers then
unsave them */
- if (ic->regsSaved)
+ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
unsaveRegisters (ic);
-
}
/*-----------------------------------------------------------------*/
genFunction (iCode * ic)
{
symbol *sym;
- sym_link *fetype;
+ sym_link *ftype;
bool switchedPSW = FALSE;
_G.nRegsSaved = 0;
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
- fetype = getSpec (operandType (IC_LEFT (ic)));
+ ftype = operandType (IC_LEFT (ic));
- if (SPEC_NAKED(fetype))
+ if (IFFUNC_ISNAKED(ftype))
{
emitcode(";", "naked function: no prologue.");
return;
}
/* if critical function then turn interrupts off */
- if (SPEC_CRTCL (fetype))
+ if (IFFUNC_ISCRITICAL (ftype))
emitcode ("clr", "ea");
/* here we need to generate the equates for the
register bank if required */
- if (SPEC_BANK (fetype) != rbank)
+ if (FUNC_REGBANK (ftype) != rbank)
{
int i;
- rbank = SPEC_BANK (fetype);
+ rbank = FUNC_REGBANK (ftype);
for (i = 0; i < mcs51_nRegs; i++)
{
if (strcmp (regs8051[i].base, "0") == 0)
/* if this is an interrupt service routine then
save acc, b, dpl, dph */
- if (IS_ISR (sym->etype))
+ if (IFFUNC_ISISR (sym->type))
{
if (!inExcludeList ("acc"))
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
registers :-) */
- if (!SPEC_BANK (sym->etype))
+ if (!FUNC_REGBANK (sym->type))
{
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
- if (!sym->hasFcall)
+ if (!IFFUNC_HASFCALL(sym->type))
{
int i;
*/
unsigned long banksToSave = 0;
- if (sym->hasFcall)
+ if (IFFUNC_HASFCALL(sym->type))
{
#define MAX_REGISTER_BANKS 4
if (i->op == CALL)
{
- sym_link *detype;
+ sym_link *dtype;
- detype = getSpec(operandType (IC_LEFT(i)));
- if (detype
- && SPEC_BANK(detype) != SPEC_BANK(sym->etype))
+ dtype = operandType (IC_LEFT(i));
+ if (dtype
+ && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
{
/* Mark this bank for saving. */
- if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS)
+ if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
{
- werror(E_NO_SUCH_BANK, SPEC_BANK(detype));
+ werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
}
else
{
- banksToSave |= (1 << SPEC_BANK(detype));
+ banksToSave |= (1 << FUNC_REGBANK(dtype));
}
/* And note that we don't need to do it in
*/
emitcode ("push", "psw");
emitcode ("mov", "psw,#0x%02x",
- (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+ (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
switchedPSW = TRUE;
}
}
}
}
+ // jwk: this needs a closer look
SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
}
}
{
/* if callee-save to be used for this function
then save the registers being used in this function */
- if (sym->calleeSave)
+ if (IFFUNC_CALLEESAVES(sym->type))
{
int i;
}
/* set the register bank to the desired value */
- if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+ if ((FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
&& !switchedPSW)
{
emitcode ("push", "psw");
- emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+ emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
}
- if (IS_RENT (sym->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
{
if (options.useXstack)
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- if (SPEC_NAKED(sym->etype))
+ if (IFFUNC_ISNAKED(sym->type))
{
emitcode(";", "naked function: no epilogue.");
return;
}
- if (IS_RENT (sym->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
{
emitcode ("mov", "%s,_bp", spname);
}
}
- if ((IS_RENT (sym->etype) || options.stackAuto))
+ if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
{
if (options.useXstack)
{
}
/* restore the register bank */
- if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+ if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
{
- if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype)
+ if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
|| !options.useXstack)
{
/* Special case of ISR using non-zero bank with useXstack
}
}
- if (IS_ISR (sym->etype))
+ if (IFFUNC_ISISR (sym->type))
{
/* now we need to restore the registers */
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
registers :-) */
- if (!SPEC_BANK (sym->etype))
+ if (!FUNC_REGBANK (sym->type))
{
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
- if (!sym->hasFcall)
+ if (!IFFUNC_HASFCALL(sym->type))
{
int i;
* Restore any register banks saved by genFunction
* in reverse order.
*/
+ // jwk: this needs a closer look
unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
int ix;
if (!inExcludeList ("acc"))
emitcode ("pop", "acc");
- if (SPEC_CRTCL (sym->etype))
+ if (IFFUNC_ISCRITICAL (sym->type))
emitcode ("setb", "ea");
/* if debug then send end of function */
}
else
{
- if (SPEC_CRTCL (sym->etype))
+ if (IFFUNC_ISCRITICAL (sym->type))
emitcode ("setb", "ea");
- if (sym->calleeSave)
+ if (IFFUNC_CALLEESAVES(sym->type))
{
int i;
{
int size, offset = 0, pushed = 0;
+ D(emitcode (";", "genRet"));
+
/* if we have no return value then
just generate the "ret" */
if (!IC_LEFT (ic))
if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
return FALSE;
+ D(emitcode (";", "genPlusIncr"));
+
/* if increment 16 bits in register */
if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
(size > 1) &&
static void
genPlusBits (iCode * ic)
{
+ D(emitcode (";", "genPlusBits"));
+
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
symbol *lbl = newiTempLabel (NULL);
/* special cases :- */
+ D(emitcode (";", "genPlus"));
+
aopOp (IC_LEFT (ic), ic, FALSE);
aopOp (IC_RIGHT (ic), ic, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE);
if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
return FALSE;
+ D(emitcode (";", "genMinusDec"));
+
/* if decrement 16 bits in register */
if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
(size > 1) &&
genMinusBits (iCode * ic)
{
symbol *lbl = newiTempLabel (NULL);
+
+ D(emitcode (";", "genMinusBits"));
+
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
int size, offset = 0;
unsigned long lit = 0L;
+ D(emitcode (";", "genMinus"));
+
aopOp (IC_LEFT (ic), ic, FALSE);
aopOp (IC_RIGHT (ic), ic, FALSE);
aopOp (IC_RESULT (ic), ic, TRUE);
operand * right,
operand * result)
{
+ D(emitcode (";", "genMultbits"));
+
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
outBitC (result);
symbol *lbl;
int size=AOP_SIZE(result);
+ D(emitcode (";", "genMultOneByte"));
+
if (size<1 || size>2) {
// this should never happen
fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
+ D(emitcode (";", "genMult"));
+
/* assign the amsops */
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
}
/* if both are of size == 1 */
- if (AOP_SIZE (left) == 1 &&
- AOP_SIZE (right) == 1)
+#if 0 // one of them can be a sloc shared with the result
+ if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1)
+#else
+ if (getSize(operandType(left)) == 1 &&
+ getSize(operandType(right)) == 1)
+#endif
{
genMultOneByte (left, right, result);
goto release;
}
/* should have been converted to function call */
- assert (1);
+ fprintf (stderr, "left: %d right: %d\n", getSize(OP_SYMBOL(left)->type),
+ getSize(OP_SYMBOL(right)->type));
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
char *l;
+ D(emitcode (";", "genDivbits"));
+
/* the result must be bit */
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
l = aopGet (AOP (left), 0, FALSE, FALSE);
symbol *lbl;
int size, offset;
+ D(emitcode (";", "genDivOneByte"));
+
size = AOP_SIZE (result) - 1;
offset = 1;
/* signed or unsigned */
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
+ D(emitcode (";", "genDiv"));
+
/* assign the amsops */
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
}
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
char *l;
+ D(emitcode (";", "genModbits"));
+
/* the result must be bit */
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
l = aopGet (AOP (left), 0, FALSE, FALSE);
char *l;
symbol *lbl;
+ D(emitcode (";", "genModOneByte"));
+
/* signed or unsigned */
if (SPEC_USIGN (opetype))
{
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
+ D(emitcode (";", "genMod"));
+
/* assign the amsops */
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
}
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
symbol *tlbl = newiTempLabel (NULL);
char *inst;
+ D(emitcode (";", "genIfxJump"));
+
/* if true label then we jump if condition
supplied is true */
if (IC_TRUE (ic))
int size, offset = 0;
unsigned long lit = 0L;
+ D(emitcode (";", "genCmp"));
+
/* if left & right are bit variables */
if (AOP_TYPE (left) == AOP_CRY &&
AOP_TYPE (right) == AOP_CRY)
sym_link *letype, *retype;
int sign;
+ D(emitcode (";", "genCmpGt"));
+
left = IC_LEFT (ic);
right = IC_RIGHT (ic);
result = IC_RESULT (ic);
sym_link *letype, *retype;
int sign;
+ D(emitcode (";", "genCmpLt"));
+
left = IC_LEFT (ic);
right = IC_RIGHT (ic);
result = IC_RESULT (ic);
{
operand *left, *right, *result;
+ D(emitcode (";", "genCmpEq"));
+
aopOp ((left = IC_LEFT (ic)), ic, FALSE);
aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
iCode *lic = ic->next;
int isize ;
+ /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
+ if (!IS_SYMOP(op)) return NULL;
+
if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
isize = getSize(type->next);
while (lic) {
if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
return NULL;
}
+ /* if GOTO or IFX */
+ if (lic->op == IFX || lic->op == GOTO) break;
lic = lic->next;
}
return NULL;
operand *left, *right, *result;
symbol *tlbl;
+ D(emitcode (";", "genAndOp"));
+
/* note here that && operations that are in an
if statement are taken away by backPatchLabels
only those used in arthmetic operations remain */
operand *left, *right, *result;
symbol *tlbl;
+ D(emitcode (";", "genOrOp"));
+
/* note here that || operations that are in an
if statement are taken away by backPatchLabels
only those used in arthmetic operations remain */
int bytelit = 0;
char buffer[10];
+ D(emitcode (";", "genAnd"));
+
aopOp ((left = IC_LEFT (ic)), ic, FALSE);
aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
int size, offset = 0;
unsigned long lit = 0L;
+ D(emitcode (";", "genOr"));
+
aopOp ((left = IC_LEFT (ic)), ic, FALSE);
aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
int size, offset = 0;
unsigned long lit = 0L;
+ D(emitcode (";", "genXor"));
+
aopOp ((left = IC_LEFT (ic)), ic, FALSE);
aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
{
char *buffer, *bp, *bp1;
+ D(emitcode (";", "genInline"));
+
_G.inLine += (!options.asmpeep);
buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
int size, offset = 0;
char *l;
+ D(emitcode (";", "genRRC"));
+
/* rotate right with carry */
left = IC_LEFT (ic);
result = IC_RESULT (ic);
int size, offset = 0;
char *l;
+ D(emitcode (";", "genRLC"));
+
/* rotate right with carry */
left = IC_LEFT (ic);
result = IC_RESULT (ic);
genGetHbit (iCode * ic)
{
operand *left, *result;
+
+ D(emitcode (";", "genGetHbit"));
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
aopOp (left, ic, FALSE);
static void
genlshOne (operand * result, operand * left, int shCount)
{
+ D(emitcode (";", "genlshOne"));
+
shiftL1Left2Result (left, LSB, result, LSB, shCount);
}
{
int size;
+ D(emitcode (";", "genlshTwo"));
+
size = getDataSize (result);
/* if shCount >= 8 */
{
int size;
+ D(emitcode (";", "genlshFour"));
+
size = AOP_SIZE (result);
/* if shifting more that 3 bytes */
int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
int size;
+ D(emitcode (";", "genLeftShiftLiteral"));
+
freeAsmop (right, NULL, ic, TRUE);
aopOp (left, ic, FALSE);
char *l;
symbol *tlbl, *tlbl1;
+ D(emitcode (";", "genLeftShift"));
+
right = IC_RIGHT (ic);
left = IC_LEFT (ic);
result = IC_RESULT (ic);
genrshOne (operand * result, operand * left,
int shCount, int sign)
{
+ D(emitcode (";", "genrshOne"));
+
shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
}
genrshTwo (operand * result, operand * left,
int shCount, int sign)
{
+ D(emitcode (";", "genrshTwo"));
+
/* if shCount >= 8 */
if (shCount >= 8)
{
genrshFour (operand * result, operand * left,
int shCount, int sign)
{
+ D(emitcode (";", "genrshFour"));
+
/* if shifting more that 3 bytes */
if (shCount >= 24)
{
int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
int size;
+ D(emitcode (";", "genRightShiftLiteral"));
+
freeAsmop (right, NULL, ic, TRUE);
aopOp (left, ic, FALSE);
char *l;
symbol *tlbl, *tlbl1;
+ D(emitcode (";", "genSignedRightShift"));
+
/* we do it the hard way put the shift count in b
and loop thru preserving the sign */
char *l;
symbol *tlbl, *tlbl1;
+ D(emitcode (";", "genRightShift"));
+
/* if signed then we do it the hard way preserve the
sign bit moving it inwards */
retype = getSpec (operandType (IC_RESULT (ic)));
int offset = 0;
int rsize;
+ D(emitcode (";", "genUnpackBits"));
+
etype = getSpec (operandType (result));
rsize = getSize (operandType (result));
/* read the first byte */
char *l;
char buffer[256];
int size, offset = 0;
+
+ D(emitcode (";", "genDataPointerGet"));
+
aopOp (result, ic, TRUE);
/* get the string representation of the name */
sym_link *ltype = operandType (left);
char buffer[80];
+ D(emitcode (";", "genNearPointerGet"));
+
rtype = operandType (result);
retype = getSpec (rtype);
char *rname;
sym_link *rtype, *retype;
+ D(emitcode (";", "genPagedPointerGet"));
+
rtype = operandType (result);
retype = getSpec (rtype);
int size, offset;
sym_link *retype = getSpec (operandType (result));
+ D(emitcode (";", "genFarPointerGet"));
+
aopOp (left, ic, FALSE);
/* if the operand is already in dptr
int size, offset;
sym_link *retype = getSpec (operandType (result));
+ D(emitcode (";", "genCodePointerGet"));
+
aopOp (left, ic, FALSE);
/* if the operand is already in dptr
int size, offset;
sym_link *retype = getSpec (operandType (result));
+ D(emitcode (";", "genGenPointerGet"));
+
aopOp (left, ic, FALSE);
/* if the operand is already in dptr
if (AOP_TYPE (left) == AOP_IMMD)
{
emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
- emitcode ("mov", "b,#%d", pointerCode (retype));
+ if (AOP(left)->aopu.aop_immd.from_cast_remat)
+ emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE));
+ else
+ emitcode ("mov", "b,#%d", pointerCode (retype));
}
else
{ /* we need to get it byte by byte */
if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
aopPut ( AOP (left), "dpl", 0);
aopPut ( AOP (left), "dph", 1);
+ aopPut ( AOP (left), "b", 2);
pi->generated = 1;
}
freeAsmop (left, NULL, ic, TRUE);
sym_link *type, *etype;
int p_type;
+ D(emitcode (";", "genPointerGet"));
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
p_type = PTR_TYPE (SPEC_OCLS (etype));
}
+ /* special case when cast remat */
+ if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+ IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+ left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+ type = type = operandType (left);
+ p_type = DCL_TYPE (type);
+ }
/* now that we have the pointer type we assign
the pointer values */
switch (p_type)
int blen, bstr;
char *l;
+ D(emitcode (";", "genPackBits"));
+
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
int size, offset = 0;
char *l, buffer[256];
+ D(emitcode (";", "genDataPointerSet"));
+
aopOp (right, ic, FALSE);
l = aopGet (AOP (result), 0, FALSE, TRUE);
sym_link *retype, *letype;
sym_link *ptype = operandType (result);
+ D(emitcode (";", "genNearPointerSet"));
+
retype = getSpec (operandType (right));
letype = getSpec (ptype);
aopOp (result, ic, FALSE);
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);
- emitcode ("mov", "%s,%s",
- preg->name,
- aopGet (AOP (result), 0, FALSE, TRUE));
- rname = preg->name;
+ if (
+ //AOP_TYPE (result) == AOP_STK
+ IS_AOP_PREG(result)
+ )
+ {
+ // Aha, it is a pointer, just in disguise.
+ rname = aopGet (AOP (result), 0, FALSE, FALSE);
+ if (*rname != '@')
+ {
+ fprintf(stderr, "probable internal error: unexpected rname @ %s:%d\n",
+ __FILE__, __LINE__);
+ }
+ else
+ {
+ // Expected case.
+ rname++; // skip the '@'.
+ }
+ }
+ else
+ {
+ /* otherwise get a free pointer register */
+ aop = newAsmop (0);
+ preg = getFreePtr (ic, &aop, FALSE);
+ emitcode ("mov", "%s,%s",
+ preg->name,
+ aopGet (AOP (result), 0, FALSE, TRUE));
+ rname = preg->name;
+ }
+ }
+ else
+ {
+ rname = aopGet (AOP (result), 0, FALSE, FALSE);
}
- else
- rname = aopGet (AOP (result), 0, FALSE, FALSE);
aopOp (right, ic, FALSE);
-
+
/* if bitfield then unpack the bits */
if (IS_BITVAR (retype) || IS_BITVAR (letype))
genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
char *rname, *l;
sym_link *retype, *letype;
+ D(emitcode (";", "genPagedPointerSet"));
+
retype = getSpec (operandType (right));
letype = getSpec (operandType (result));
int size, offset;
sym_link *retype = getSpec (operandType (right));
sym_link *letype = getSpec (operandType (result));
+
+ D(emitcode (";", "genFarPointerSet"));
+
aopOp (result, ic, FALSE);
/* if the operand is already in dptr
sym_link *retype = getSpec (operandType (right));
sym_link *letype = getSpec (operandType (result));
+ D(emitcode (";", "genGenPointerSet"));
+
aopOp (result, ic, FALSE);
/* if the operand is already in dptr
if (AOP_TYPE (result) == AOP_IMMD)
{
emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
- emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
+ if (AOP(result)->aopu.aop_immd.from_cast_remat)
+ emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE));
+ else
+ emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
}
else
{ /* we need to get it byte by byte */
if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
aopPut (AOP(result),"dpl",0);
aopPut (AOP(result),"dph",1);
+ aopPut (AOP(result),"b",2);
pi->generated=1;
}
freeAsmop (result, NULL, ic, TRUE);
sym_link *type, *etype;
int p_type;
+ D(emitcode (";", "genPointerSet"));
+
right = IC_RIGHT (ic);
result = IC_RESULT (ic);
p_type = PTR_TYPE (SPEC_OCLS (etype));
}
+ /* special case when cast remat */
+ if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
+ IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
+ result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
+ type = type = operandType (result);
+ p_type = DCL_TYPE (type);
+ }
/* now that we have the pointer type we assign
the pointer values */
switch (p_type)
operand *cond = IC_COND (ic);
int isbit = 0;
+ D(emitcode (";", "genIfx"));
+
aopOp (cond, ic, FALSE);
/* get the value into acc */
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
int size, offset;
+ D(emitcode (";", "genAddrOf"));
+
aopOp (IC_RESULT (ic), ic, FALSE);
/* if the operand is on the stack then we
if (sym->stack)
{
emitcode ("mov", "a,_bp");
- emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+ emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ?
+ ((char) (sym->stack - _G.nRegsSaved)) :
+ ((char) sym->stack)) & 0xff);
aopPut (AOP (IC_RESULT (ic)), "a", 0);
}
else
int size = AOP_SIZE (right);
int offset = 0;
char *l;
+
+ D(emitcode (";", "genFarFarAssign"));
+
/* first push the right side on to the stack */
while (size--)
{
symbol *jtab;
char *l;
+ D(emitcode (";", "genJumpTab"));
+
aopOp (IC_JTCOND (ic), ic, FALSE);
/* get the condition into accumulator */
l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
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 */
if (!ifx)
return 0;
+ D(emitcode (";", "genDjnz"));
+
/* if the if condition has a false label
then we cannot save */
if (IC_FALSE (ifx))
static void
genReceive (iCode * ic)
{
+ D(emitcode (";", "genReceive"));
+
if (isOperandInFarSpace (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->isspilt ||
IS_TRUE_SYMOP (IC_RESULT (ic))))
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;
+
+ D(emitcode (";", "gen51AggregateAssign"));
+
+ 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 */
/*-----------------------------------------------------------------*/
addSet (&_G.sendSet, ic);
break;
+ case ARRAYINIT:
+ gen51AggregateAssign(ic);
+ break;
+
default:
ic = ic;
}