func = __muldiv[1][bwd][su];
else if (op == '%')
func = __muldiv[2][bwd][su];
+ else if (op == RRC)
+ func = __rlrr[1][bwd][su];
+ else if (op == RLC)
+ func = __rlrr[0][bwd][su];
+ else if (op == RIGHT_OP)
+ func = __rlrr[1][bwd][su];
+ else if (op == LEFT_OP)
+ func = __rlrr[0][bwd][su];
else
assert (0);
goto found;
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
-
}
else
{
-
/* compiled as reentrant then push */
/* push right */
if (IS_REGPARM (func->args->next->etype))
- newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+ {
+ newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+ }
else
{
newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
newic->parmPush = 1;
- bytesPushed += getSize(type);
+
+ bytesPushed += getSize(operandType(IC_RIGHT(ic)));
}
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
/* insert push left */
if (IS_REGPARM (func->args->etype))
- newic = newiCode (SEND, IC_LEFT (ic), NULL);
+ {
+ newic = newiCode (SEND, IC_LEFT (ic), NULL);
+ }
else
{
newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
newic->parmPush = 1;
- bytesPushed += getSize(type);
+
+ bytesPushed += getSize(operandType(IC_LEFT(ic)));
}
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
/* if long / int mult or divide or mod */
if (ic->op == '*' || ic->op == '/' || ic->op == '%')
{
-
sym_link *type = operandType (IC_LEFT (ic));
- if (IS_INTEGRAL (type) && getSize (type) > port->muldiv.native_below)
- convilong (ic, ebbs[i], type, ic->op);
+ if (IS_INTEGRAL (type) && getSize (type) > port->support.muldiv)
+ {
+ convilong (ic, ebbs[i], type, ic->op);
+ }
}
+
+ if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
+ {
+ sym_link *type = operandType (IC_LEFT (ic));
+
+ if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
+ {
+ convilong (ic, ebbs[i], type, ic->op);
+ }
+ }
}
}
}
sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
sym_link *floatType;
-static void
-_makeRegParam (symbol * sym)
-{
- value *val;
-
- val = sym->args; /* loop thru all the arguments */
-
- /* reset regparm for the port */
- (*port->reset_regparms) ();
- while (val)
- {
- SPEC_REGPARM (val->etype) = 1;
- val = val->next;
- }
-}
-
static char *
_mangleFunctionName(char *in)
{
{
"s", "u"
};
+ const char *srlrr[] =
+ {
+ "rl", "rr"
+ };
- int bwd, su, muldivmod, tofrom;
+ int bwd, su, muldivmod, tofrom, rlrr;
floatType = newFloatLink ();
sbwd[bwd]);
__muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
- if (bwd < port->muldiv.force_reg_param_below)
- _makeRegParam (__muldiv[muldivmod][bwd][su]);
+ }
+ }
+ }
+
+ for (rlrr = 0; rlrr < 2; rlrr++)
+ {
+ for (bwd = 0; bwd < 3; bwd++)
+ {
+ for (su = 0; su < 2; su++)
+ {
+ sprintf (buffer, "_%s%s%s",
+ srlrr[rlrr],
+ ssu[su],
+ sbwd[bwd]);
+ __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
+ SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1;
}
}
}
char *s = buffer;
char *rs;
-#if 0
- if (aop->size != 2 && aop->type != AOP_HL)
- return NULL;
-#endif
/* depending on type */
switch (aop->type)
{
tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
else
tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
- rs = Safe_calloc (1, strlen (s) + 1);
- strcpy (rs, s);
- return rs;
+
+ return gc_strdup(s);
+
case AOP_LIT:
{
value *val = aop->aopu.aop_lit;
unsigned long v = (unsigned long) floatFromVal (val);
if (offset == 2)
- v >>= 16;
+ {
+ v >>= 16;
+ }
+ else if (offset == 0)
+ {
+ // OK
+ }
+ else
+ {
+ wassertl(0, "Encountered an invalid offset while fetching a literal");
+ }
if (with_hash)
tsprintf (buffer, "!immedword", v);
else
tsprintf (buffer, "!constword", v);
- rs = Safe_calloc (1, strlen (buffer) + 1);
- return strcpy (rs, buffer);
+
+ return gc_strdup(buffer);
}
else
{
{
const char *l;
const char *pair = _pairs[pairId].name;
- l = aopGetLitWordLong (left, 0, FALSE);
+ l = aopGetLitWordLong (left, offset, FALSE);
wassert (l && pair);
if (isPtr (pair))
_G.pairs[pairId].offset = offset;
}
/* Both a lit on the right and a true symbol on the left */
- if (offset)
- emit2 ("ld %s,!hashedstr + %u", pair, l, offset);
- else
- emit2 ("ld %s,!hashedstr", pair, l);
+ emit2 ("ld %s,!hashedstr", pair, l);
}
static void
if (!ic->parmPush)
{
wassertl(0, "Encountered an unsupported spill push.");
-#if 0
- /* and the item is spilt then do nothing */
- if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
- return;
-
- aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
- size = AOP_SIZE (IC_LEFT (ic));
- /* push it on the stack */
- if (isPair (AOP (IC_LEFT (ic))))
- {
- emit2 ("push %s", getPairName (AOP (IC_LEFT (ic))));
- _G.stack.pushed += 2;
- }
- else
- {
- offset = size;
- while (size--)
- {
- /* Simple for now - load into A and PUSH AF */
- if (AOP (IC_LEFT (ic))->type == AOP_IY)
- {
- char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
- wassert (l);
- emit2 ("ld a,(%s)", l);
- }
- else
- {
- l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
- emit2 ("ld a,%s", l);
- }
- emit2 ("push af");
- emit2 ("inc sp");
- _G.stack.pushed++;
- }
- }
-#endif
return;
}
static void
shiftR2Left2Result (operand * left, int offl,
operand * result, int offr,
- int shCount, int sign)
+ int shCount, int is_signed)
{
+ int size = 2;
+ int offset = 0;
+ symbol *tlbl, *tlbl1;
+ const char *l;
+
movLeft2Result (left, offl, result, offr, 0);
movLeft2Result (left, offl + 1, result, offr + 1, 0);
- if (sign)
+ /* if (AOP(result)->type == AOP_REG) { */
+
+ tlbl = newiTempLabel (NULL);
+ tlbl1 = newiTempLabel (NULL);
+
+ /* Left is already in result - so now do the shift */
+ if (shCount > 1)
{
- wassert (0);
+ emit2 ("ld a,!immedbyte+1", shCount);
+ emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+ emitLabel (tlbl->key + 100);
}
- else
+
+ offset = 0;
+ while (size--)
{
- /* if (AOP(result)->type == AOP_REG) { */
- int size = 2;
- int offset = 0;
- symbol *tlbl, *tlbl1;
- const char *l;
-
- tlbl = newiTempLabel (NULL);
- tlbl1 = newiTempLabel (NULL);
-
- /* Left is already in result - so now do the shift */
- if (shCount > 1)
- {
- emit2 ("ld a,!immedbyte+1", shCount);
- emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
- }
-
- emit2 ("or a,a");
- offset = size;
- while (size--)
- {
- l = aopGet (AOP (result), --offset, FALSE);
- emit2 ("rr %s", l);
- }
- if (shCount > 1)
- {
- emitLabel (tlbl1->key + 100);
- emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
- }
+ l = aopGet (AOP (result), size, FALSE);
+ if (offset == 0)
+ {
+ emit2 ("%s %s", is_signed ? "sra" : "srl", l);
+ }
+ else
+ {
+ emit2 ("rr %s", l);
+ }
+ offset++;
+ }
+ if (shCount > 1)
+ {
+ emitLabel (tlbl1->key + 100);
+ emit2 ("dec a");
+ emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
}
}
emit2 ("or a,a");
while (size--)
{
- l = aopGet (AOP (result), offset++, FALSE);
+ l = aopGet (AOP (result), offset, FALSE);
+
emit2 ("rl %s", l);
+
+ offset++;
}
if (shCount > 1)
{
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
emitLabel (tlbl->key + 100);
l = aopGet (AOP (result), offset, FALSE);
+
emit2 ("or a,a");
+
while (size--)
{
l = aopGet (AOP (result), offset++, FALSE);
/* genrshOne - left shift two bytes by known amount != 0 */
/*-----------------------------------------------------------------*/
static void
-genrshOne (operand * result, operand * left, int shCount)
+genrshOne (operand * result, operand * left, int shCount, int is_signed)
{
/* Errk */
int size = AOP_SIZE (result);
wassert (shCount < 8);
l = aopGet (AOP (left), 0, FALSE);
+
+ emit2 ("or a,a");
+
if (AOP (result)->type == AOP_REG)
{
aopPut (AOP (result), l, 0);
l = aopGet (AOP (result), 0, FALSE);
while (shCount--)
- emit2 ("srl %s", l);
+ {
+ emit2 ("%s %s", is_signed ? "sra" : "srl", l);
+ }
}
else
{
_moveA (l);
while (shCount--)
{
- emit2 ("srl a");
+ emit2 ("%s a", is_signed ? "sra" : "srl");
}
aopPut (AOP (result), "a", 0);
}
genRightShiftLiteral (operand * left,
operand * right,
operand * result,
- iCode * ic)
+ iCode * ic,
+ int sign)
{
int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
int size;
switch (size)
{
case 1:
- genrshOne (result, left, shCount);
+ genrshOne (result, left, shCount, sign);
break;
case 2:
/* PENDING: sign support */
- genrshTwo (result, left, shCount, FALSE);
+ genrshTwo (result, left, shCount, sign);
break;
case 4:
- wassert (0);
+ wassertl (0, "Asked to shift right a long which should be a function call");
break;
default:
- wassert (0);
+ wassertl (0, "Entered default case in right shift delegate");
}
}
freeAsmop (left, NULL, ic);
as efficiently as possible */
if (AOP_TYPE (right) == AOP_LIT)
{
- genRightShiftLiteral (left, right, result, ic);
+ genRightShiftLiteral (left, right, result, ic, is_signed);
return;
}
l = aopGet (AOP (result), offset--, FALSE);
if (first)
{
- if (is_signed)
- emit2 ("sra %s", l);
- else
- emit2 ("srl %s", l);
+ emit2 ("%s %s", is_signed ? "sra" : "srl", l);
first = 0;
}
else
- emit2 ("rr %s", l);
+ {
+ emit2 ("rr %s", l);
+ }
}
emitLabel (tlbl1->key + 100);
emit2 ("dec a");