2 * Sources of the "INTEGER ARITHMETIC" group instructions
5 /* $Id: do_intar.c,v 2.5 1994/06/24 10:46:29 ceriel Exp $ */
17 PRIVATE long adi(), sbi(), dvi(), mli(), rmi(), ngi(), sli(), sri();
22 /* ADI w: Addition (*) */
23 register long t = spop(arg_wi(l));
25 LOG(("@I6 DoADI(%ld)", l));
27 npush(adi(spop(l), t, l), l);
33 /* SBI w: Subtraction (*) */
34 register long t = spop(arg_wi(l));
36 LOG(("@I6 DoSBI(%ld)", l));
38 npush(sbi(spop(l), t, l), l);
44 /* MLI w: Multiplication (*) */
45 register long t = spop(arg_wi(l));
47 LOG(("@I6 DoMLI(%ld)", l));
49 npush(mli(spop(l), t, l), l);
55 /* DVI w: Division (*) */
56 register long t = spop(arg_wi(l));
58 LOG(("@I6 DoDVI(%ld)", l));
60 npush(dvi(spop(l), t), l);
66 /* RMI w: Remainder (*) */
67 register long t = spop(arg_wi(l));
69 LOG(("@I6 DoRMI(%ld)", l));
71 npush(rmi(spop(l), t), l);
77 /* NGI w: Negate (two's complement) (*) */
79 LOG(("@I6 DoNGI(%ld)", l));
82 npush(ngi(spop(l), l), l);
88 /* SLI w: Shift left (*) */
89 register long t = swpop();
91 LOG(("@I6 DoSLI(%ld)", l));
94 npush(sli(spop(l), t, l), l);
100 /* SRI w: Shift right (*) */
101 register long t = swpop();
103 LOG(("@I6 DoSRI(%ld)", l));
106 npush(sri(spop(l), t, l), l);
109 #define i_maxs(n) ((n == 2) ? I_MAXS2 : I_MAXS4)
110 #define i_mins(n) ((n == 2) ? I_MINS2 : I_MINS4)
112 PRIVATE long adi(w1, w2, nbytes) /* returns w1 + w2 */
116 if (must_test && !(IgnMask&BIT(EIOVFL))) {
117 if (w1 > 0 && w2 > 0) {
118 if (i_maxs(nbytes) - w1 < w2)
121 else if (w1 < 0 && w2 < 0) {
122 if (i_mins(nbytes) - w1 > w2)
129 PRIVATE long sbi(w1, w2, nbytes) /* returns w1 - w2 */
133 if (must_test && !(IgnMask&BIT(EIOVFL))) {
134 if (w2 < 0 && w1 > 0) {
135 if (i_maxs(nbytes) + w2 < w1)
138 else if (w2 > 0 && w1 < 0) {
139 if (i_mins(nbytes) + w2 > w1) {
147 #define labs(w) ((w < 0) ? (-w) : w)
149 PRIVATE long mli(w1, w2, nbytes) /* returns w1 * w2 */
153 if (w1 == 0 || w2 == 0)
156 if (must_test && !(IgnMask&BIT(EIOVFL))) {
157 if ((w1 > 0 && w2 > 0) || (w2 < 0 && w1 < 0)) {
158 if ( w1 == i_mins(nbytes) || w2 == i_mins(nbytes)
159 || (i_maxs(nbytes) / labs(w1)) < labs(w2)
165 if (i_mins(nbytes) / w1 > w2)
168 else if (i_mins(nbytes) / w2 > w1) {
175 PRIVATE long dvi(w1, w2)
179 if (!(IgnMask&BIT(EIDIVZ))) {
187 PRIVATE long rmi(w1, w2)
191 if (!(IgnMask&BIT(EIDIVZ))) {
199 PRIVATE long ngi(w1, nbytes)
203 if (must_test && !(IgnMask&BIT(EIOVFL))) {
204 if (w1 == i_mins(nbytes)) {
211 PRIVATE long sli(w1, w2, nbytes) /* w1 << w2 */
217 /* check shift distance */
222 if (w2 >= nbytes*8) {
228 if (!(IgnMask&BIT(EIOVFL))) {
230 if ( (w1 >= 0 && (w1 >> (nbytes*8 - w2)) != 0)
231 || (w1 < 0 && (w1 >> (nbytes*8 - w2)) != -1)
238 /* calculate result */
243 PRIVATE long sri(w1, w2, nbytes) /* w1 >> w2 */
249 /* check shift distance */
254 if (w2 >= nbytes*8) {
261 /* calculate result */