(x->aopu.aop_reg[0] == ds390_regWithIdx(R0_IDX) || \
x->aopu.aop_reg[0] == ds390_regWithIdx(R1_IDX) )))
+/* Workaround for DS80C390 bug: div ab may return bogus results
+ * if A is accessed in instruction immediately before the div.
+ *
+ * Will be fixed in B4 rev of processor, Dallas claims.
+ */
+
+#define LOAD_AB_FOR_DIV(LEFT, RIGHT, L) \
+ if (!AOP_NEEDSACC(RIGHT)) \
+ { \
+ /* We can load A first, then B, since \
+ * B (the RIGHT operand) won't clobber A, \
+ * thus avoiding touching A right before the div. \
+ */ \
+ D(emitcode(";", "DS80C390 div bug: rearranged ops.");); \
+ L = aopGet(AOP(LEFT),0,FALSE,FALSE); \
+ MOVA(L); \
+ emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE));\
+ } \
+ else \
+ { \
+ /* Just stuff in a nop after loading A. */ \
+ emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE));\
+ L = aopGet(AOP(LEFT),0,FALSE,FALSE); \
+ MOVA(L); \
+ emitcode("nop", "; workaround for DS80C390 div bug."); \
+ }
+
/*-----------------------------------------------------------------*/
/* genNotFloat - generates not for float operations */
/*-----------------------------------------------------------------*/
char *l;
- /* the result must be bit */
- emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
-
- MOVA(l);
-
- emitcode("clr","c"); //jwk
+ /* the result must be bit */
+ LOAD_AB_FOR_DIV(left, right, l);
emitcode("div","ab");
emitcode("rrc","a");
aopPut(AOP(result),"c",0);
/* signed or unsigned */
if (SPEC_USIGN(opetype)) {
/* unsigned is easy */
- emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
- emitcode("clr","c"); //jwk
+ LOAD_AB_FOR_DIV(left, right, l);
emitcode("div","ab");
aopPut(AOP(result),"a",0);
while (size--)
emitcode("","%05d$:",(lbl->key+100));
/* now the division */
- emitcode("clr","c"); //jwk
+ emitcode("nop", "; workaround for DS80C390 div bug.");
emitcode("div","ab");
/* we are interested in the lower order
only */
char *l;
/* the result must be bit */
- emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
-
- MOVA(l);
-
- emitcode("clr","c"); //jwk
+ LOAD_AB_FOR_DIV(left, right, l);
emitcode("div","ab");
emitcode("mov","a,b");
emitcode("rrc","a");
/* signed or unsigned */
if (SPEC_USIGN(opetype)) {
/* unsigned is easy */
- emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
- emitcode("clr","c"); //jwk
+ LOAD_AB_FOR_DIV(left, right, l);
emitcode("div","ab");
aopPut(AOP(result),"b",0);
return ;
emitcode("","%05d$:",(lbl->key+100));
/* now the multiplication */
- emitcode("clr","c"); //jwk
+ emitcode("nop", "; workaround for DS80C390 div bug.");
emitcode("div","ab");
/* we are interested in the lower order
only */