aopForRemat (symbol * sym)
{
iCode *ic = sym->rematiCode;
- asmop *aop = newAsmop (AOP_IMMD);
+ asmop *aop = NULL;
int ptr_type=0;
int val = 0;
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
}
- if (val)
- sprintf (buffer, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ic))->rname,
- val >= 0 ? '+' : '-',
- abs (val) & 0xffff);
- else
- strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+ if (ic->op == ADDRESS_OF)
+ {
+ if (val)
+ sprintf (buffer, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ic))->rname,
+ val >= 0 ? '+' : '-',
+ abs (val) & 0xffff);
+ else
+ strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
- 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) {
+ aop = newAsmop (AOP_IMMD);
+ 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);
- }
+ }
+ }
+ else if (ic->op == '=')
+ {
+ val += (int) operandLitValue (IC_RIGHT (ic));
+ val &= 0xffff;
+ sprintf (buffer, "0x%04x", val);
+ aop = newAsmop (AOP_LIT);
+ aop->aopu.aop_lit = constVal (buffer);
+ }
+ else
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "unexpected rematerialization");
+
+
return aop;
}
case AOP_LIT:
if (bit16)
- return aopLiteralLong (aop->aopu.aop_lit, loffset, 2);
+ return aopLiteralLong (aop->aopu.aop_lit, /*loffset*/ 0, 2);
else
return aopLiteral (aop->aopu.aop_lit, loffset);
emitcode ("", "%05d$:", (tlbl->key + 100));
}
else
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "Bad rIdx in asmToBool");
- return;
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "Bad rIdx in asmToBool");
+ return;
+ }
+ break;
case AOP_EXT:
if (resultInA)
needpula = FALSE;
{
char *sub;
int size, offset = 0;
+
+ asmop *leftOp, *rightOp;
D(emitcode ("; genMinus",""));
size = getDataSize (IC_RESULT (ic));
- asmop *leftOp, *rightOp;
leftOp = AOP(IC_LEFT(ic));
rightOp = AOP(IC_RIGHT(ic));
emitcode ("rola", "");
hc08_dirtyReg (hc08_reg_a, FALSE);
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
+ hc08_freeReg (hc08_reg_a);
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* genSwap - generates code to swap nibbles or bytes */
+/*-----------------------------------------------------------------*/
+static void
+genSwap (iCode * ic)
+{
+ operand *left, *result;
+
+ D(emitcode ("; genSwap",""));
+
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ switch (AOP_SIZE (left))
+ {
+ case 1: /* swap nibbles in byte */
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ emitcode ("nsa", "");
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ storeRegToAop (hc08_reg_a, AOP (result), 0);
+ hc08_freeReg (hc08_reg_a);
+ break;
+ case 2: /* swap bytes in a word */
+ if (operandsEqu (left, result))
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ hc08_useReg (hc08_reg_a);
+ transferAopAop (AOP (left), 1, AOP (result), 0);
+ storeRegToAop (hc08_reg_a, AOP (result), 1);
+ hc08_freeReg (hc08_reg_a);
+ }
+ else
+ {
+ transferAopAop (AOP (left), 0, AOP (result), 1);
+ transferAopAop (AOP (left), 1, AOP (result), 0);
+ }
+ break;
+ default:
+ wassertl(FALSE, "unsupported SWAP operand size");
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
#if 0
/*-----------------------------------------------------------------*/
/* AccRol - rotate left accumulator by known count */
return;
}
- shCount &= 0x000f; // shCount : 0..7
+ shCount &= 0x000f; // shCount : 0..f
/* if we can beat 2n cycles or bytes for some special case, do it here */
switch (shCount)
** rola 1 1 bcde fgh0 0000 000a 0
** lslx 1 1 cdef gh00 0000 000a b
** rola 1 1 cdef gh00 0000 00ab 0
- ** clrx 1 1 0000 0000 0000 000a 0
+ ** clrx 1 1 0000 0000 0000 00ab 0
** total: 6 cycles, 6 bytes
*/
loadRegFromConst (hc08_reg_x, zero);
;
}
- /* lslx/rola is only 2 cycles and bytes, so an unrolled loop is often */
+ /* lsrx/rora is only 2 cycles and bytes, so an unrolled loop is often */
/* the fastest and shortest. */
for (i=0;i<shCount;i++)
{
- rmwWithReg ("lsl", hc08_reg_x);
- rmwWithReg ("rol", hc08_reg_a);
+ rmwWithReg ("lsr", hc08_reg_x);
+ rmwWithReg ("ror", hc08_reg_a);
}
}
}
-/*-----------------------------------------------------------------*/
-/* AccAXRsh1 - right shift 0->a:x->c by 1 */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRsh1 (char *x)
-{
- emitcode ("lsra", "");
- emitcode ("ror", "%s", x);
-}
-
-
-/*-----------------------------------------------------------------*/
-/* AccAXRshS1 - signed right shift s->a:x->c by 1 */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRshS1 (char *x)
-{
- emitcode ("asra", "");
- emitcode ("ror", "%s", x);
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLrl1 (char *x)
-{
- emitcode ("rol", "%s", x);
- emitcode ("rola", "");
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLsh1 - left shift a:x<-0 by 1 */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLsh1 (char *x)
-{
- emitcode ("lsl", "%s", x);
- emitcode ("rola", "");
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLsh - left shift a:x by known count (0..7) */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLsh (char *x, int shCount)
-{
- int i;
-
- for (i=0;i<shCount;i++) {
- AccAXLsh1 (x);
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRsh - right shift a:x known count (0..7) */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRsh (char *x, int shCount)
-{
- int i;
-
- for (i=0;i<shCount;i++) {
- AccAXRsh1 (x);
- }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRshS - right shift signed a:x known count (0..7) */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRshS (char *x, int shCount)
-{
- int i;
-
- for (i=0;i<shCount;i++) {
- AccAXRshS1 (x);
- }
-}
-
/*-----------------------------------------------------------------*/
/* shiftL2Left2Result - shift left two bytes from left to result */
/*-----------------------------------------------------------------*/
D(emitcode ("; genlshTwo",""));
+
size = getDataSize (result);
/* if shCount >= 8 */
if (size > 1)
{
- if (shCount)
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
- else
- movLeft2Result (left, LSB, result, MSB16, 0);
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ AccLsh (shCount);
+ storeRegToAop (hc08_reg_a, AOP (result), 1);
}
storeConstToAop(zero, AOP (result), LSB);
}
/* 1 <= shCount <= 7 */
else
{
- if (size == 1)
- shiftL1Left2Result (left, LSB, result, LSB, shCount);
- else
- shiftL2Left2Result (left, LSB, result, LSB, shCount);
+ loadRegFromAop (hc08_reg_xa, AOP (left), 0);
+ XAccLsh (shCount);
+ storeRegToFullAop (hc08_reg_xa, AOP (result), 0);
}
}
freeAsmop (result, NULL, ic, TRUE);
}
+#if 0
/*-----------------------------------------------------------------*/
/* genNearPointerGet - emitcode for near pointer fetch */
/*-----------------------------------------------------------------*/
}
hc08_freeReg (hc08_reg_hx);
-
}
-
+#endif
/*-----------------------------------------------------------------*/
/* genFarPointerGet - get value from far space */
}
/* special case when cast remat */
- if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+ if (p_type == GPOINTER && IS_SYMOP(left) && OP_SYMBOL(left)->remat &&
IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
type = operandType (left);
emitcode ("and", "#0x%02x", mask);
emitcode ("ora", "1,s");
emitcode ("sta", ",x");
+ pullReg (hc08_reg_a);
}
hc08_freeReg (hc08_reg_a);
freeAsmop (NULL, derefaop, ic, TRUE);
}
+#if 0
/*-----------------------------------------------------------------*/
/* genNearPointerSet - emitcode for near pointer put */
/*-----------------------------------------------------------------*/
hc08_freeReg (hc08_reg_hx);
}
-
+#endif
/*-----------------------------------------------------------------*/
/* genFarPointerSet - set value from far space */
if (operandLitValue (IC_RIGHT (ic)) != 1)
return 0;
+ /* dbnz doesn't support extended mode */
+ if (isOperandInFarSpace (IC_RESULT (ic)))
+ return 0;
+
/* if the size of this greater than one then no
saving */
// if (getSize (operandType (IC_RESULT (ic))) > 1)
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+ operand *op;
+ int size, offset;
+
+ D(emitcode("; genDummyRead",""));
+
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+
+ aopOp (op, ic, FALSE);
+
+ size = AOP_SIZE (op);
+ offset = 0;
+
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (op), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
+ {
+
+ aopOp (op, ic, FALSE);
+
+ size = AOP_SIZE (op);
+ offset = 0;
+
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (op), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+ D(emitcode("; genCritical",""));
+
+ if (IC_RESULT (ic))
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ emitcode ("tpa", "");
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ emitcode ("sei", "");
+
+ if (IC_RESULT (ic))
+ storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), 0);
+ else
+ pushReg (hc08_reg_a, FALSE);
+
+ hc08_freeReg (hc08_reg_a);
+ if (IC_RESULT (ic))
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+ D(emitcode("; genEndCritical",""));
+
+ if (IC_RIGHT (ic))
+ {
+ aopOp (IC_RIGHT (ic), ic, FALSE);
+ loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (ic)), 0);
+ emitcode ("tap", "");
+ hc08_freeReg (hc08_reg_a);
+ freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE);
+ }
+ else
+ {
+ pullReg (hc08_reg_a);
+ emitcode ("tap", "");
+ }
+}
+
+
/*-----------------------------------------------------------------*/
/* genhc08Code - generate code for HC08 based controllers */
/*-----------------------------------------------------------------*/
addSet (&_G.sendSet, ic);
break;
+ case DUMMY_READ_VOLATILE:
+ genDummyRead (ic);
+ break;
+
+ case CRITICAL:
+ genCritical (ic);
+ break;
+
+ case ENDCRITICAL:
+ genEndCritical (ic);
+ break;
+
+ case SWAP:
+ genSwap (ic);
+ break;
+
default:
ic = ic;
}