Operands(expr);
switch(tp->tp_fund) {
case T_INTEGER:
- C_dvi(tp->tp_size);
+ if ((int)(tp->tp_size) == word_size) {
+ C_cal((int)(tp->tp_size) == (int)word_size
+ ? "dvi"
+ : "dvil");
+ }
+ C_asp(2*tp->tp_size);
+ C_lfr(tp->tp_size);
break;
case T_POINTER:
case T_EQUAL:
Operands(expr);
switch(tp->tp_fund) {
case T_INTEGER:
- C_rmi(tp->tp_size);
+ if ((int)(tp->tp_size) == word_size) {
+ C_cal((int)(tp->tp_size) == (int)word_size
+ ? "rmi"
+ : "rmil");
+ }
+ C_asp(2*tp->tp_size);
+ C_lfr(tp->tp_size);
break;
case T_POINTER:
case T_EQUAL:
node_error(expp, "division by 0");
return;
}
-#if (-1)/2==0
- o1 /= o2;
-#else
- if (o1 == 0) break;
if ((o1 < 0) != (o2 < 0)) {
- o1 = o1/o2 + 1;
+ if (o1 < 0) o1 = -o1;
+ else o2 = -o2;
+ o1 = -((o1+o2-1)/o2);
}
else {
o1 /= o2;
}
-#endif
break;
-
case MOD:
if (o2 == 0) {
node_error(expp, "modulo by 0");
return;
}
-#if (-1)/2==0
- o1 %= o2;
-#else
- if (o1 == 0) break;
if ((o1 < 0) != (o2 < 0)) {
- o1 -= (o1 / o2 + 1) * o2;
+ if (o1 < 0) o1 = -o1;
+ else o2 = -o2;
+ o1 = ((o1+o2-1)/o2) * o2 - o1;
}
else {
o1 %= o2;
}
-#endif
break;
case '+':
--- /dev/null
+/*
+ (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ See the copyright notice in the ACK home directory, in the file "Copyright".
+*/
+
+/*
+ Module: implementation of DIV and MOD
+ Author: Ceriel J.H. Jacobs
+ Version: $Header$
+ Reason: We cannot use DVI and RMI, because DVI rounds towards 0
+ and Modula-2 requires truncation
+*/
+
+#include <em_abs.h>
+
+int
+dvi(j,i)
+ int j,i;
+{
+ if (j == 0) TRP(EIDIVZ);
+ if ((i < 0) != (j < 0)) {
+ if (i < 0) i = -i;
+ else j = -j;
+ return -((i+j-1)/j);
+ }
+ else return i/j;
+}
+
+long
+dvil(j,i)
+ long j,i;
+{
+ if (j == 0) TRP(EIDIVZ);
+ if ((i < 0) != (j < 0)) {
+ if (i < 0) i = -i;
+ else j = -j;
+ return -((i+j-1)/j);
+ }
+ else return i/j;
+}
+
+int
+rmi(j,i)
+ int j,i;
+{
+ if (j == 0) TRP(EIDIVZ);
+ if (i == 0) return 0;
+ if ((i < 0) != (j < 0)) {
+ if (i < 0) i = -i;
+ else j = -j;
+ return j*((i+j-1)/j)-i;
+ }
+ else return i%j;
+}
+
+long
+rmil(j,i)
+ long j,i;
+{
+ if (j == 0) TRP(EIDIVZ);
+ if (i == 0) return 0L;
+ if ((i < 0) != (j < 0)) {
+ if (i < 0) i = -i;
+ else j = -j;
+ return j*((i+j-1)/j)-i;
+ }
+ else return i%j;
+}