00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "arith.internal.h"
00041
00042
00043
00044 int
00045 ar_add_integer
00046 (ar_data *result, const AR_TYPE *resulttype,
00047 const ar_data *opnd1, const AR_TYPE *opnd1type,
00048 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00049
00050 int status;
00051 int carry, overflow;
00052 long partialsum;
00053 int opnd1sign, opnd2sign;
00054
00055 switch (AR_INT_SIZE (*opnd1type)) {
00056 case AR_INT_SIZE_8:
00057 opnd1sign = INT8_SIGN(opnd1) != 0;
00058 opnd2sign = INT8_SIGN(opnd2) != 0;
00059
00060 partialsum = (long)opnd1->ar_i8.part5 + opnd2->ar_i8.part5;
00061 result->ar_i8.part5 = partialsum & 0xFF;
00062 carry = partialsum >> 8;
00063 ZERO_INT8_UPPER(result);
00064
00065 if (AR_SIGNEDNESS (*opnd1type) == AR_UNSIGNED)
00066 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00067 else if ((opnd1sign == opnd2sign) &&
00068 (opnd1sign != (INT8_SIGN(result) != 0)))
00069
00070
00071
00072
00073 status = AR_STAT_OVERFLOW;
00074 else
00075 status = AR_STAT_OK;
00076
00077
00078 if (IS_INT8_ZERO(result))
00079 status |= AR_STAT_ZERO;
00080 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
00081 INT8_SIGN(result))
00082 status |= AR_STAT_NEGATIVE;
00083 break;
00084
00085 case AR_INT_SIZE_16:
00086 opnd1sign = INT16_SIGN(opnd1) != 0;
00087 opnd2sign = INT16_SIGN(opnd2) != 0;
00088
00089 partialsum = (long)opnd1->ar_i64.part4 + opnd2->ar_i64.part4;
00090 result->ar_i64.part4 = partialsum & 0xFFFF;
00091 carry = partialsum >> 16;
00092 ZERO_INT16_UPPER(result);
00093
00094 if (AR_SIGNEDNESS (*opnd1type) == AR_UNSIGNED)
00095 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00096 else if ((opnd1sign == opnd2sign) &&
00097 (opnd1sign != (INT16_SIGN(result) != 0)))
00098
00099
00100
00101
00102 status = AR_STAT_OVERFLOW;
00103 else
00104 status = AR_STAT_OK;
00105
00106
00107 if (IS_INT16_ZERO(result))
00108 status |= AR_STAT_ZERO;
00109 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
00110 INT16_SIGN(result))
00111 status |= AR_STAT_NEGATIVE;
00112 break;
00113
00114 case AR_INT_SIZE_32:
00115 opnd1sign = INT32_SIGN(opnd1) != 0;
00116 opnd2sign = INT32_SIGN(opnd2) != 0;
00117
00118 partialsum = (long)opnd1->ar_i64.part4 + opnd2->ar_i64.part4;
00119 result->ar_i64.part4 = partialsum & 0xFFFF;
00120 carry = partialsum >> 16;
00121
00122 partialsum = (long)opnd1->ar_i64.part3 + opnd2->ar_i64.part3 +
00123 carry;
00124 result->ar_i64.part3 = partialsum & 0xFFFF;
00125 carry = partialsum >> 16;
00126 ZERO_INT32_UPPER(result);
00127
00128 if (AR_SIGNEDNESS (*opnd1type) == AR_UNSIGNED)
00129 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00130 else if ((opnd1sign == opnd2sign) &&
00131 (opnd1sign != (INT32_SIGN(result) != 0)))
00132
00133
00134
00135
00136 status = AR_STAT_OVERFLOW;
00137 else
00138 status = AR_STAT_OK;
00139
00140
00141 if (IS_INT32_ZERO(result))
00142 status |= AR_STAT_ZERO;
00143 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
00144 INT32_SIGN(result))
00145 status |= AR_STAT_NEGATIVE;
00146 break;
00147
00148 case AR_INT_SIZE_46:
00149 case AR_INT_SIZE_64:
00150 opnd1sign = INT64_SIGN(opnd1) != 0;
00151 opnd2sign = INT64_SIGN(opnd2) != 0;
00152
00153 partialsum = (long)opnd1->ar_i64.part4 + opnd2->ar_i64.part4;
00154 result->ar_i64.part4 = partialsum & 0xFFFF;
00155 carry = partialsum >> 16;
00156
00157 partialsum = (long)opnd1->ar_i64.part3 + opnd2->ar_i64.part3 +
00158 carry;
00159 result->ar_i64.part3 = partialsum & 0xFFFF;
00160 carry = partialsum >> 16;
00161
00162 partialsum = (long)opnd1->ar_i64.part2 + opnd2->ar_i64.part2 +
00163 carry;
00164 result->ar_i64.part2 = partialsum & 0xFFFF;
00165 carry = partialsum >> 16;
00166
00167 partialsum = (long)opnd1->ar_i64.part1 + opnd2->ar_i64.part1 +
00168 carry;
00169 result->ar_i64.part1 = partialsum & 0xFFFF;
00170 carry = partialsum >> 16;
00171
00172 if (AR_SIGNEDNESS (*opnd1type) == AR_UNSIGNED)
00173 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00174 else if ((opnd1sign == opnd2sign) &&
00175 (opnd1sign != (INT64_SIGN(result) != 0)))
00176
00177
00178
00179
00180 status = AR_STAT_OVERFLOW;
00181 else
00182 status = AR_STAT_OK;
00183
00184
00185 if (IS_INT64_ZERO(result))
00186 status |= AR_STAT_ZERO;
00187 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
00188 INT64_SIGN(result))
00189 status |= AR_STAT_NEGATIVE;
00190 break;
00191
00192 default:
00193 return (AR_STAT_INVALID_TYPE);
00194 }
00195
00196 return status;
00197 }
00198
00199
00200 int
00201 ar_subtract_integer
00202 (ar_data *result, const AR_TYPE *resulttype, int *flags,
00203 const ar_data *opnd1, const AR_TYPE *opnd1type,
00204 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00205
00206 int status;
00207 long sign, zero, overflow, carry;
00208 long partialdiff;
00209 int opnd1sign, opnd2sign;
00210
00211 if (*resulttype != *opnd1type ||
00212 *resulttype != *opnd2type ||
00213 AR_CLASS (*resulttype) != AR_CLASS_INT)
00214 return AR_STAT_INVALID_TYPE;
00215
00216 switch (AR_INT_SIZE (*opnd1type)) {
00217 case AR_INT_SIZE_8:
00218 opnd1sign = INT8_SIGN(opnd1) != 0;
00219 opnd2sign = INT8_SIGN(opnd2) != 0;
00220
00221 partialdiff = (long) opnd1->ar_i8.part5 - opnd2->ar_i8.part5;
00222 result->ar_i8.part5 = partialdiff & 0xFFFF;
00223 carry = partialdiff < 0;
00224 ZERO_INT8_UPPER(result);
00225
00226
00227
00228
00229 overflow = ((opnd1sign != opnd2sign) &&
00230 (opnd1sign != (INT8_SIGN(result) != 0)));
00231 zero = IS_INT8_ZERO(result);
00232 sign = !!INT8_SIGN(result);
00233
00234
00235 if (flags)
00236 *flags = (sign << 3) | (zero << 2) | (overflow << 1) |
00237 carry;
00238
00239 if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED)
00240 status = overflow ? AR_STAT_OVERFLOW : AR_STAT_OK;
00241 else
00242 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00243 break;
00244
00245 case AR_INT_SIZE_16:
00246 opnd1sign = INT16_SIGN(opnd1) != 0;
00247 opnd2sign = INT16_SIGN(opnd2) != 0;
00248
00249 partialdiff = (long) opnd1->ar_i64.part4 - opnd2->ar_i64.part4;
00250 result->ar_i64.part4 = partialdiff & 0xFFFF;
00251 carry = partialdiff < 0;
00252 ZERO_INT16_UPPER(result);
00253
00254
00255
00256
00257 overflow = ((opnd1sign != opnd2sign) &&
00258 (opnd1sign != (INT16_SIGN(result) != 0)));
00259 zero = IS_INT16_ZERO(result);
00260 sign = !!INT16_SIGN(result);
00261
00262
00263 if (flags)
00264 *flags = (sign << 3) | (zero << 2) | (overflow << 1) |
00265 carry;
00266
00267 if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED)
00268 status = overflow ? AR_STAT_OVERFLOW : AR_STAT_OK;
00269 else
00270 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00271 break;
00272
00273 case AR_INT_SIZE_32:
00274 opnd1sign = INT32_SIGN(opnd1) != 0;
00275 opnd2sign = INT32_SIGN(opnd2) != 0;
00276
00277 partialdiff = (long) opnd1->ar_i64.part4 - opnd2->ar_i64.part4;
00278 result->ar_i64.part4 = partialdiff & 0xFFFF;
00279 carry = partialdiff < 0;
00280
00281 partialdiff = (long) opnd1->ar_i64.part3 - opnd2->ar_i64.part3 -
00282 carry;
00283 result->ar_i64.part3 = partialdiff & 0xFFFF;
00284 carry = partialdiff < 0;
00285 ZERO_INT32_UPPER(result);
00286
00287
00288
00289
00290 overflow = ((opnd1sign != opnd2sign) &&
00291 (opnd1sign != (INT32_SIGN(result) != 0)));
00292 zero = IS_INT32_ZERO(result);
00293 sign = !!INT32_SIGN(result);
00294
00295
00296 if (flags)
00297 *flags = (sign << 3) | (zero << 2) | (overflow << 1) |
00298 carry;
00299
00300 if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED)
00301 status = overflow ? AR_STAT_OVERFLOW : AR_STAT_OK;
00302 else
00303 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00304 break;
00305
00306 case AR_INT_SIZE_46:
00307 case AR_INT_SIZE_64:
00308 opnd1sign = INT64_SIGN(opnd1) != 0;
00309 opnd2sign = INT64_SIGN(opnd2) != 0;
00310
00311 partialdiff = (long) opnd1->ar_i64.part4 - opnd2->ar_i64.part4;
00312 result->ar_i64.part4 = partialdiff & 0xFFFF;
00313 carry = partialdiff < 0;
00314
00315 partialdiff = (long) opnd1->ar_i64.part3 - opnd2->ar_i64.part3 -
00316 carry;
00317 result->ar_i64.part3 = partialdiff & 0xFFFF;
00318 carry = partialdiff < 0;
00319
00320 partialdiff = (long) opnd1->ar_i64.part2 - opnd2->ar_i64.part2 -
00321 carry;
00322 result->ar_i64.part2 = partialdiff & 0xFFFF;
00323 carry = partialdiff < 0;
00324
00325 partialdiff = (long) opnd1->ar_i64.part1 - opnd2->ar_i64.part1 -
00326 carry;
00327 result->ar_i64.part1 = partialdiff & 0xFFFF;
00328 carry = partialdiff < 0;
00329
00330
00331
00332
00333 overflow = ((opnd1sign != opnd2sign) &&
00334 (opnd1sign != (INT64_SIGN(result) != 0)));
00335 zero = IS_INT64_ZERO(result);
00336 sign = !!INT64_SIGN(result);
00337
00338
00339 if (flags)
00340 *flags = (sign << 3) | (zero << 2) | (overflow << 1) |
00341 carry;
00342
00343 if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED)
00344 status = overflow ? AR_STAT_OVERFLOW : AR_STAT_OK;
00345 else
00346 status = carry ? AR_STAT_OVERFLOW : AR_STAT_OK;
00347 break;
00348
00349 default:
00350 return (AR_STAT_INVALID_TYPE);
00351 }
00352
00353 return status | AR_status ((AR_DATA*)result, resulttype);
00354 }
00355
00356
00357
00358 static
00359 int
00360 ar_add_pointer
00361 (ar_data *result, const AR_TYPE *resulttype,
00362 const ar_data *opnd1, const AR_TYPE *opnd1type,
00363 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00364
00365 ar_data temp, ptropnd, intopnd;
00366 AR_TYPE temptype, ptropndtype, intopndtype;
00367 AR_TYPE shifttype = AR_Int_64_U;
00368
00369 if (AR_CLASS (*opnd1type) == AR_CLASS_POINTER) {
00370 ptropnd = *opnd1;
00371 intopnd = *opnd2;
00372 ptropndtype = *opnd1type;
00373 intopndtype = *opnd2type;
00374 } else {
00375 ptropnd = *opnd2;
00376 intopnd = *opnd1;
00377 ptropndtype = *opnd2type;
00378 intopndtype = *opnd1type;
00379 }
00380
00381 if (*resulttype != ptropndtype ||
00382 AR_CLASS (intopndtype) != AR_CLASS_INT ||
00383 AR_POINTER_FORMAT (ptropndtype) == AR_POINTER_FCTN)
00384 return AR_STAT_INVALID_TYPE;
00385
00386 if (AR_POINTER_FORMAT (ptropndtype) == AR_POINTER_CHAR) {
00387
00388 ar_dblshift (&temp, &shifttype, &ptropnd, &ptropnd, 128-3);
00389 ptropnd = temp;
00390 }
00391
00392 ar_add_integer (result, &intopndtype,
00393 &ptropnd, &intopndtype,
00394 &intopnd, &intopndtype);
00395
00396 if (AR_POINTER_FORMAT (ptropndtype) == AR_POINTER_CHAR) {
00397
00398 ar_dblshift (&temp, &shifttype, result, result, 3);
00399 result->ar_i64 = temp.ar_i64;
00400 }
00401
00402 ar_clear_unused_bits (result, resulttype);
00403
00404 return AR_STAT_OK;
00405 }
00406
00407
00408
00409 static
00410 int
00411 ar_subtract_pointer
00412 (ar_data *result, const AR_TYPE *resulttype,
00413 const ar_data *opnd1, const AR_TYPE *opnd1type,
00414 const ar_data *opnd2, const AR_TYPE *opnd2type) {
00415
00416 ar_data temp1, temp2;
00417 AR_TYPE temp1type, temp2type;
00418 AR_TYPE shifttype = AR_Int_64_U;
00419
00420 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_FCTN)
00421 return AR_STAT_INVALID_TYPE;
00422
00423 if (AR_CLASS (*opnd2type) == AR_CLASS_POINTER) {
00424
00425 if (*opnd1type != *opnd2type ||
00426 AR_CLASS (*resulttype) != AR_CLASS_INT ||
00427 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 &&
00428 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 &&
00429 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 &&
00430 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 &&
00431 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64)
00432 return AR_STAT_INVALID_TYPE;
00433 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_CHAR) {
00434
00435 ar_dblshift (&temp1, &shifttype, opnd1, opnd1, 128-3);
00436 ar_dblshift (&temp2, &shifttype, opnd2, opnd2, 128-3);
00437 } else {
00438 temp1 = *opnd1;
00439 temp2 = *opnd2;
00440 }
00441 return ar_subtract_integer (result, resulttype, (int *)0,
00442 &temp1, resulttype,
00443 &temp2, resulttype);
00444 }
00445
00446 if (AR_CLASS (*opnd2type) == AR_CLASS_INT) {
00447 if (*resulttype != *opnd1type ||
00448 AR_INT_SIZE (*opnd2type) != AR_INT_SIZE_8 &&
00449 AR_INT_SIZE (*opnd2type) != AR_INT_SIZE_16 &&
00450 AR_INT_SIZE (*opnd2type) != AR_INT_SIZE_32 &&
00451 AR_INT_SIZE (*opnd2type) != AR_INT_SIZE_46 &&
00452 AR_INT_SIZE (*opnd2type) != AR_INT_SIZE_64)
00453 return AR_STAT_INVALID_TYPE;
00454 if (AR_POINTER_FORMAT (*resulttype) == AR_POINTER_CHAR)
00455 ar_dblshift (&temp1, &shifttype, opnd1, opnd1, 128-3);
00456 else
00457 temp1 = *opnd1;
00458 ar_subtract_integer (result, opnd2type, (int *)0,
00459 &temp1, opnd2type,
00460 opnd2, opnd2type);
00461 if (AR_POINTER_FORMAT (*resulttype) == AR_POINTER_CHAR) {
00462 ar_dblshift (&temp1, &shifttype, result, result, 3);
00463 result->ar_i64 = temp1.ar_i64;
00464 }
00465 ar_clear_unused_bits (result, resulttype);
00466 return AR_STAT_OK;
00467 }
00468
00469 return AR_STAT_INVALID_TYPE;
00470 }
00471
00472
00473
00474 int
00475 AR_add (AR_DATA *res, const AR_TYPE *resulttype,
00476 const AR_DATA *op1, const AR_TYPE *opnd1type,
00477 const AR_DATA *op2, const AR_TYPE *opnd2type) {
00478
00479 ar_data* result = (ar_data*)res;
00480 ar_data* opnd1 = (ar_data*)op1;
00481 ar_data* opnd2 = (ar_data*)op2;
00482
00483 int status = AR_STAT_OK, restat, imstat;
00484
00485 ar_data tmp1, tmp2;
00486
00487 if (AR_CLASS (*opnd1type) == AR_CLASS_POINTER ||
00488 AR_CLASS (*opnd2type) == AR_CLASS_POINTER)
00489 return ar_add_pointer (result, resulttype,
00490 opnd1, opnd1type,
00491 opnd2, opnd2type);
00492
00493 if (AR_CLASS (*opnd1type) == AR_CLASS_INT) {
00494 if (*resulttype != *opnd1type ||
00495 *resulttype != *opnd2type ||
00496 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 &&
00497 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 &&
00498 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 &&
00499 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 &&
00500 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64)
00501 return AR_STAT_INVALID_TYPE;
00502 status = ar_add_integer (result, resulttype,
00503 opnd1, opnd1type,
00504 opnd2, opnd2type);
00505 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED)
00506 status &= ~AR_STAT_OVERFLOW;
00507 return status;
00508 }
00509
00510 if (AR_CLASS (*opnd1type) == AR_CLASS_FLOAT) {
00511
00512 if (*resulttype != *opnd1type || *resulttype != *opnd2type)
00513 return AR_STAT_INVALID_TYPE;
00514
00515 switch (*resulttype) {
00516 case AR_Float_Cray1_64:
00517 case AR_Float_Cray1_64_F:
00518 status = ar_cfadd64 (&result->ar_f64,
00519 &opnd1->ar_f64, &opnd2->ar_f64);
00520 if (ar_state_register.ar_truncate_bits > 0)
00521 ar_CRAY_64_trunc(&result->ar_f64);
00522 return status;
00523
00524 case AR_Float_Cray1_128:
00525 return ar_cfadd128 (&result->ar_f128,
00526 &opnd1->ar_f128, &opnd2->ar_f128);
00527 case AR_Float_IEEE_NR_32:
00528 case AR_Float_IEEE_ZE_32:
00529 case AR_Float_IEEE_UP_32:
00530 case AR_Float_IEEE_DN_32:
00531 return ar_ifadd32 (&result->ar_ieee32,
00532 &opnd1->ar_ieee32, &opnd2->ar_ieee32,
00533 ROUND_MODE (*resulttype));
00534 case AR_Float_IEEE_NR_64:
00535 case AR_Float_IEEE_ZE_64:
00536 case AR_Float_IEEE_UP_64:
00537 case AR_Float_IEEE_DN_64:
00538 return ar_ifadd64 (&result->ar_ieee64,
00539 &opnd1->ar_ieee64, &opnd2->ar_ieee64,
00540 ROUND_MODE (*resulttype));
00541 case AR_Float_IEEE_NR_128:
00542 case AR_Float_IEEE_ZE_128:
00543 case AR_Float_IEEE_UP_128:
00544 case AR_Float_IEEE_DN_128:
00545 return ar_ifadd128 (&result->ar_ieee128,
00546 &opnd1->ar_ieee128, &opnd2->ar_ieee128,
00547 ROUND_MODE (*resulttype));
00548 case AR_Complex_Cray1_64:
00549 case AR_Complex_Cray1_64_F:
00550 restat = ar_cfadd64 (&result->ar_cplx_f64.real,
00551 &opnd1->ar_cplx_f64.real,
00552 &opnd2->ar_cplx_f64.real);
00553 if (ar_state_register.ar_truncate_bits > 0)
00554 ar_CRAY_64_trunc(&result->ar_cplx_f64.real);
00555 imstat = ar_cfadd64 (&result->ar_cplx_f64.imag,
00556 &opnd1->ar_cplx_f64.imag,
00557 &opnd2->ar_cplx_f64.imag);
00558 if (ar_state_register.ar_truncate_bits > 0)
00559 ar_CRAY_64_trunc(&result->ar_cplx_f64.imag);
00560 status = (restat | imstat) &
00561 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00562 status |= restat & imstat & AR_STAT_ZERO;
00563 return status;
00564 case AR_Complex_Cray1_128:
00565 restat = ar_cfadd128 (&result->ar_cplx_f128.real,
00566 &opnd1->ar_cplx_f128.real,
00567 &opnd2->ar_cplx_f128.real);
00568 imstat = ar_cfadd128 (&result->ar_cplx_f128.imag,
00569 &opnd1->ar_cplx_f128.imag,
00570 &opnd2->ar_cplx_f128.imag);
00571 status = (restat | imstat) &
00572 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00573 status |= restat & imstat & AR_STAT_ZERO;
00574 return status;
00575 case AR_Complex_IEEE_NR_32:
00576 case AR_Complex_IEEE_ZE_32:
00577 case AR_Complex_IEEE_UP_32:
00578 case AR_Complex_IEEE_DN_32:
00579 {
00580 AR_IEEE_32 o1, o2, rslt;
00581
00582 CPLX32_REAL_TO_IEEE32(o1, opnd1->ar_cplx_ieee32);
00583 CPLX32_REAL_TO_IEEE32(o2, opnd2->ar_cplx_ieee32);
00584 restat = ar_ifadd32 (&rslt, &o1, &o2,
00585 ROUND_MODE (*resulttype));
00586 IEEE32_TO_CPLX32_REAL(result->ar_cplx_ieee32, rslt);
00587
00588 CPLX32_IMAG_TO_IEEE32(o1, opnd1->ar_cplx_ieee32);
00589 CPLX32_IMAG_TO_IEEE32(o2, opnd2->ar_cplx_ieee32);
00590 imstat = ar_ifadd32 (&rslt, &o1, &o2,
00591 ROUND_MODE (*resulttype));
00592 IEEE32_TO_CPLX32_IMAG(result->ar_cplx_ieee32, rslt);
00593
00594 status = (restat | imstat) &
00595 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00596 status |= restat & imstat & AR_STAT_ZERO;
00597 return status;
00598 }
00599 case AR_Complex_IEEE_NR_64:
00600 case AR_Complex_IEEE_ZE_64:
00601 case AR_Complex_IEEE_UP_64:
00602 case AR_Complex_IEEE_DN_64:
00603 restat = ar_ifadd64 (&result->ar_cplx_ieee64.real,
00604 &opnd1->ar_cplx_ieee64.real,
00605 &opnd2->ar_cplx_ieee64.real,
00606 ROUND_MODE (*resulttype));
00607 imstat = ar_ifadd64 (&result->ar_cplx_ieee64.imag,
00608 &opnd1->ar_cplx_ieee64.imag,
00609 &opnd2->ar_cplx_ieee64.imag,
00610 ROUND_MODE (*resulttype));
00611 status = (restat | imstat) &
00612 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00613 status |= restat & imstat & AR_STAT_ZERO;
00614 return status;
00615 case AR_Complex_IEEE_NR_128:
00616 case AR_Complex_IEEE_ZE_128:
00617 case AR_Complex_IEEE_UP_128:
00618 case AR_Complex_IEEE_DN_128:
00619 restat = ar_ifadd128 (&result->ar_cplx_ieee128.real,
00620 &opnd1->ar_cplx_ieee128.real,
00621 &opnd2->ar_cplx_ieee128.real,
00622 ROUND_MODE (*resulttype));
00623 imstat = ar_ifadd128 (&result->ar_cplx_ieee128.imag,
00624 &opnd1->ar_cplx_ieee128.imag,
00625 &opnd2->ar_cplx_ieee128.imag,
00626 ROUND_MODE (*resulttype));
00627 status = (restat | imstat) &
00628 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00629 status |= restat & imstat & AR_STAT_ZERO;
00630 return status;
00631 default:
00632 return AR_STAT_INVALID_TYPE;
00633 }
00634 }
00635
00636 return AR_STAT_INVALID_TYPE;
00637 }
00638
00639
00640
00641 int
00642 AR_subtract
00643 (AR_DATA *res, const AR_TYPE *resulttype,
00644 const AR_DATA *op1, const AR_TYPE *opnd1type,
00645 const AR_DATA *op2, const AR_TYPE *opnd2type) {
00646
00647 ar_data* result = (ar_data*)res;
00648 ar_data* opnd1 = (ar_data*)op1;
00649 ar_data* opnd2 = (ar_data*)op2;
00650
00651 int status, restat, imstat;
00652
00653 ar_data tmp1, tmp2;
00654
00655 if (AR_CLASS (*opnd1type) == AR_CLASS_POINTER)
00656 return ar_subtract_pointer (result, resulttype,
00657 opnd1, opnd1type,
00658 opnd2, opnd2type);
00659
00660 if (AR_CLASS (*opnd1type) == AR_CLASS_INT) {
00661 status = ar_subtract_integer (result, resulttype, (int *)0,
00662 opnd1, opnd1type,
00663 opnd2, opnd2type);
00664 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED)
00665 status &= ~AR_STAT_OVERFLOW;
00666 return status;
00667 }
00668
00669 if (AR_CLASS (*opnd1type) == AR_CLASS_FLOAT) {
00670 if (*resulttype != *opnd1type || *resulttype != *opnd2type)
00671 return AR_STAT_INVALID_TYPE;
00672 switch (*resulttype) {
00673 case AR_Float_Cray1_64:
00674 case AR_Float_Cray1_64_F:
00675 status = ar_cfsub64 (&result->ar_f64,
00676 &opnd1->ar_f64, &opnd2->ar_f64);
00677 if (ar_state_register.ar_truncate_bits > 0)
00678 ar_CRAY_64_trunc(&result->ar_f64);
00679 return status;
00680
00681 case AR_Float_Cray1_128:
00682 return ar_cfsub128 (&result->ar_f128,
00683 &opnd1->ar_f128, &opnd2->ar_f128);
00684 case AR_Float_IEEE_NR_32:
00685 case AR_Float_IEEE_ZE_32:
00686 case AR_Float_IEEE_DN_32:
00687 case AR_Float_IEEE_UP_32:
00688 return ar_ifsub32 (&result->ar_ieee32,
00689 &opnd1->ar_ieee32, &opnd2->ar_ieee32,
00690 ROUND_MODE (*resulttype));
00691 case AR_Float_IEEE_NR_64:
00692 case AR_Float_IEEE_ZE_64:
00693 case AR_Float_IEEE_DN_64:
00694 case AR_Float_IEEE_UP_64:
00695 return ar_ifsub64 (&result->ar_ieee64,
00696 &opnd1->ar_ieee64, &opnd2->ar_ieee64,
00697 ROUND_MODE (*resulttype));
00698 case AR_Float_IEEE_NR_128:
00699 case AR_Float_IEEE_ZE_128:
00700 case AR_Float_IEEE_DN_128:
00701 case AR_Float_IEEE_UP_128:
00702 return ar_ifsub128 (&result->ar_ieee128,
00703 &opnd1->ar_ieee128, &opnd2->ar_ieee128,
00704 ROUND_MODE (*resulttype));
00705 case AR_Complex_Cray1_64:
00706 case AR_Complex_Cray1_64_F:
00707 restat = ar_cfsub64 (&result->ar_cplx_f64.real,
00708 &opnd1->ar_cplx_f64.real,
00709 &opnd2->ar_cplx_f64.real);
00710 if (ar_state_register.ar_truncate_bits > 0)
00711 ar_CRAY_64_trunc(&result->ar_cplx_f64.real);
00712 imstat = ar_cfsub64 (&result->ar_cplx_f64.imag,
00713 &opnd1->ar_cplx_f64.imag,
00714 &opnd2->ar_cplx_f64.imag);
00715 if (ar_state_register.ar_truncate_bits > 0)
00716 ar_CRAY_64_trunc(&result->ar_cplx_f64.imag);
00717 status = (restat | imstat) &
00718 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00719 status |= restat & imstat & AR_STAT_ZERO;
00720 return status;
00721 case AR_Complex_Cray1_128:
00722 restat = ar_cfsub128 (&result->ar_cplx_f128.real,
00723 &opnd1->ar_cplx_f128.real,
00724 &opnd2->ar_cplx_f128.real);
00725 imstat = ar_cfsub128 (&result->ar_cplx_f128.imag,
00726 &opnd1->ar_cplx_f128.imag,
00727 &opnd2->ar_cplx_f128.imag);
00728 status = (restat | imstat) &
00729 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00730 status |= restat & imstat & AR_STAT_ZERO;
00731 return status;
00732 case AR_Complex_IEEE_NR_32:
00733 case AR_Complex_IEEE_ZE_32:
00734 case AR_Complex_IEEE_UP_32:
00735 case AR_Complex_IEEE_DN_32:
00736 {
00737 AR_IEEE_32 o1, o2, rslt;
00738
00739 CPLX32_REAL_TO_IEEE32(o1, opnd1->ar_cplx_ieee32);
00740 CPLX32_REAL_TO_IEEE32(o2, opnd2->ar_cplx_ieee32);
00741 restat = ar_ifsub32 (&rslt, &o1, &o2,
00742 ROUND_MODE (*resulttype));
00743 IEEE32_TO_CPLX32_REAL(result->ar_cplx_ieee32, rslt);
00744
00745 CPLX32_IMAG_TO_IEEE32(o1, opnd1->ar_cplx_ieee32);
00746 CPLX32_IMAG_TO_IEEE32(o2, opnd2->ar_cplx_ieee32);
00747 imstat = ar_ifsub32 (&rslt, &o1, &o2,
00748 ROUND_MODE (*resulttype));
00749 IEEE32_TO_CPLX32_IMAG(result->ar_cplx_ieee32, rslt);
00750
00751 status = (restat | imstat) &
00752 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00753 status |= restat & imstat & AR_STAT_ZERO;
00754 return status;
00755 }
00756 case AR_Complex_IEEE_NR_64:
00757 case AR_Complex_IEEE_ZE_64:
00758 case AR_Complex_IEEE_UP_64:
00759 case AR_Complex_IEEE_DN_64:
00760 restat = ar_ifsub64 (&result->ar_cplx_ieee64.real,
00761 &opnd1->ar_cplx_ieee64.real,
00762 &opnd2->ar_cplx_ieee64.real,
00763 ROUND_MODE (*resulttype));
00764 imstat = ar_ifsub64 (&result->ar_cplx_ieee64.imag,
00765 &opnd1->ar_cplx_ieee64.imag,
00766 &opnd2->ar_cplx_ieee64.imag,
00767 ROUND_MODE (*resulttype));
00768 status = (restat | imstat) &
00769 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00770 status |= restat & imstat & AR_STAT_ZERO;
00771 return status;
00772 case AR_Complex_IEEE_NR_128:
00773 case AR_Complex_IEEE_ZE_128:
00774 case AR_Complex_IEEE_UP_128:
00775 case AR_Complex_IEEE_DN_128:
00776 restat = ar_ifsub128 (&result->ar_cplx_ieee128.real,
00777 &opnd1->ar_cplx_ieee128.real,
00778 &opnd2->ar_cplx_ieee128.real,
00779 ROUND_MODE (*resulttype));
00780 imstat = ar_ifsub128 (&result->ar_cplx_ieee128.imag,
00781 &opnd1->ar_cplx_ieee128.imag,
00782 &opnd2->ar_cplx_ieee128.imag,
00783 ROUND_MODE (*resulttype));
00784 status = (restat | imstat) &
00785 ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
00786 status |= restat & imstat & AR_STAT_ZERO;
00787 return status;
00788 default:
00789 return AR_STAT_INVALID_TYPE;
00790 }
00791 }
00792
00793 return AR_STAT_INVALID_TYPE;
00794 }
00795
00796
00797
00798 int
00799 ar_negate_integer
00800 (ar_data *result, const AR_TYPE *resulttype,
00801 const ar_data *opnd, const AR_TYPE *opndtype) {
00802
00803 ar_data temp, temp1;
00804 int status;
00805
00806 if (AR_CLASS (*opndtype) != AR_CLASS_INT)
00807 return AR_STAT_INVALID_TYPE;
00808
00809 switch (AR_INT_SIZE (*opndtype)) {
00810 case AR_INT_SIZE_8:
00811
00812 temp.ar_i8.part5 = 0xFF ^ opnd->ar_i8.part5;
00813
00814
00815 temp1.ar_i8.part5 = 1;
00816 break;
00817
00818 case AR_INT_SIZE_16:
00819
00820 temp.ar_i64.part4 = 0xFFFF ^ opnd->ar_i64.part4;
00821
00822
00823 temp1.ar_i64.part4 = 1;
00824 break;
00825
00826 case AR_INT_SIZE_32:
00827
00828 temp.ar_i64.part3 = 0xFFFF ^ opnd->ar_i64.part3;
00829 temp.ar_i64.part4 = 0xFFFF ^ opnd->ar_i64.part4;
00830
00831
00832 temp1.ar_i64.part3 = 0;
00833 temp1.ar_i64.part4 = 1;
00834 break;
00835
00836 case AR_INT_SIZE_46:
00837 case AR_INT_SIZE_64:
00838
00839 temp.ar_i64.part1 = 0xFFFF ^ opnd->ar_i64.part1;
00840 temp.ar_i64.part2 = 0xFFFF ^ opnd->ar_i64.part2;
00841 temp.ar_i64.part3 = 0xFFFF ^ opnd->ar_i64.part3;
00842 temp.ar_i64.part4 = 0xFFFF ^ opnd->ar_i64.part4;
00843
00844
00845 temp1.ar_i64.part1 = 0;
00846 temp1.ar_i64.part2 = 0;
00847 temp1.ar_i64.part3 = 0;
00848 temp1.ar_i64.part4 = 1;
00849 break;
00850
00851 default:
00852 return (AR_STAT_INVALID_TYPE);
00853 }
00854
00855 status = ar_add_integer (result, resulttype,
00856 &temp, opndtype,
00857 &temp1, opndtype);
00858 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED)
00859 status &= ~AR_STAT_OVERFLOW;
00860 else if((status&AR_STAT_OVERFLOW) && (status&AR_STAT_NEGATIVE)) {
00861 switch (AR_INT_SIZE (*resulttype)) {
00862 case AR_INT_SIZE_8:
00863 if(result->ar_i8.part5 == 0x80)
00864 status = (status^AR_STAT_OVERFLOW) |
00865 AR_STAT_SEMIVALID;
00866 break;
00867
00868 case AR_INT_SIZE_16:
00869 if(result->ar_i64.part4 == 0x8000)
00870 status = (status^AR_STAT_OVERFLOW) |
00871 AR_STAT_SEMIVALID;
00872 break;
00873
00874 case AR_INT_SIZE_32:
00875 if(result->ar_i64.part3 == 0x8000 &&
00876 result->ar_i64.part4 == 0)
00877 status = (status^AR_STAT_OVERFLOW) |
00878 AR_STAT_SEMIVALID;
00879 break;
00880
00881 case AR_INT_SIZE_46:
00882 case AR_INT_SIZE_64:
00883 if (result->ar_i64.part1 == 0x8000 &&
00884 result->ar_i64.part2 == 0 &&
00885 result->ar_i64.part3 == 0 &&
00886 result->ar_i64.part4 == 0)
00887 status = (status^AR_STAT_OVERFLOW) |
00888 AR_STAT_SEMIVALID;
00889 break;
00890
00891 default:
00892 return (AR_STAT_INVALID_TYPE);
00893 }
00894 }
00895
00896 return status;
00897 }
00898
00899
00900
00901 int
00902 ar_negate_float
00903 (ar_data *result, const AR_TYPE *resulttype,
00904 const ar_data *opnd, const AR_TYPE *opndtype) {
00905
00906 if (*resulttype != *opndtype ||
00907 AR_CLASS (*resulttype) != AR_CLASS_FLOAT)
00908 return AR_STAT_INVALID_TYPE;
00909
00910 if (AR_FLOAT_FORMAT (*resulttype) == AR_FLOAT_CRAY) {
00911 if (AR_FLOAT_SIZE (*resulttype) == AR_FLOAT_64) {
00912 result->ar_f64 = opnd->ar_f64;
00913 if (result->ar_f64.expo |
00914 result->ar_f64.coeff0 | result->ar_f64.coeff1 |
00915 result->ar_f64.coeff2) {
00916 result->ar_f64.sign ^= 1;
00917 return AR_STAT_OK;
00918 } else
00919 return AR_STAT_ZERO;
00920 }
00921 if (AR_FLOAT_SIZE (*resulttype) == AR_FLOAT_128) {
00922 result->ar_f128 = opnd->ar_f128;
00923 if (result->ar_f128.expo |
00924 result->ar_f128.coeff0 | result->ar_f128.coeff1 |
00925 result->ar_f128.coeff2 | result->ar_f128.coeff3 |
00926 result->ar_f128.coeff4 | result->ar_f128.coeff5) {
00927 result->ar_f128.sign ^= 1;
00928 return AR_STAT_OK;
00929 } else
00930 return AR_STAT_ZERO;
00931 }
00932 return AR_STAT_INVALID_TYPE;
00933 }
00934
00935
00936 if (AR_FLOAT_SIZE (*resulttype) == AR_FLOAT_32) {
00937 result->ar_ieee32 = opnd->ar_ieee32;
00938 result->ar_ieee32.sign ^= 1;
00939 return AR_status ((AR_DATA*)result, resulttype);
00940 }
00941
00942 if (AR_FLOAT_SIZE (*resulttype) == AR_FLOAT_64) {
00943 result->ar_ieee64 = opnd->ar_ieee64;
00944 result->ar_ieee64.sign ^= 1;
00945 return AR_status ((AR_DATA*)result, resulttype);
00946 }
00947
00948 if (AR_FLOAT_SIZE (*resulttype) == AR_FLOAT_128) {
00949 if (HOST_IS_MIPS) {
00950 result->ar_mips128 = opnd->ar_mips128;
00951 result->ar_mips128.sign ^= 1;
00952 result->ar_mips128.signl ^= 1;
00953 }
00954 else {
00955 result->ar_ieee128 = opnd->ar_ieee128;
00956 result->ar_ieee128.sign ^= 1;
00957 }
00958 return AR_status ((AR_DATA*)result, resulttype);
00959 }
00960
00961 return AR_STAT_INVALID_TYPE;
00962 }
00963
00964
00965 static
00966 int
00967 ar_negate_complex
00968 (ar_data *result, const AR_TYPE *resulttype,
00969 const ar_data *opnd, const AR_TYPE *opndtype) {
00970
00971 int status, restat, imstat;
00972 ar_data re, im, nre, nim;
00973 AR_TYPE reimtype, cplxtype;
00974
00975 if (*resulttype != *opndtype ||
00976 AR_CLASS (*resulttype) != AR_CLASS_FLOAT ||
00977 AR_FLOAT_IS_COMPLEX (*resulttype) != AR_FLOAT_COMPLEX)
00978 return AR_STAT_INVALID_TYPE;
00979
00980 status = ar_decompose_complex (&re, &im, &reimtype, opnd, opndtype);
00981 status |= restat = ar_negate_float (&nre, &reimtype, &re, &reimtype);
00982 status |= imstat = ar_negate_float (&nim, &reimtype, &im, &reimtype);
00983 status |= ar_compose_complex (result, &cplxtype, &nre, &nim, &reimtype);
00984 status &= ~(AR_STAT_NEGATIVE | AR_STAT_ZERO);
00985 status |= restat & imstat & AR_STAT_ZERO;
00986 return status;
00987 }
00988
00989
00990
00991 int
00992 AR_negate
00993 (AR_DATA *res, const AR_TYPE *resulttype,
00994 const AR_DATA *opd, const AR_TYPE *opndtype) {
00995
00996 ar_data* result = (ar_data*)res;
00997 ar_data* opnd = (ar_data*)opd;
00998
00999 if (*resulttype != *opndtype)
01000 return AR_STAT_INVALID_TYPE;
01001 if (AR_CLASS (*resulttype) == AR_CLASS_INT)
01002 return ar_negate_integer (result, resulttype, opnd, opndtype);
01003 if (AR_CLASS (*resulttype) == AR_CLASS_FLOAT)
01004 if (AR_FLOAT_IS_COMPLEX (*resulttype) == AR_FLOAT_COMPLEX)
01005 return ar_negate_complex (result, resulttype, opnd, opndtype);
01006 else
01007 return ar_negate_float (result, resulttype, opnd, opndtype);
01008 return AR_STAT_INVALID_TYPE;
01009 }
01010
01011
01012
01013 int
01014 ar_multiply_integer
01015 (ar_data *result, const AR_TYPE *resulttype,
01016 const ar_data *opnd1, const AR_TYPE *opnd1type,
01017 const ar_data *opnd2, const AR_TYPE *opnd2type) {
01018
01019 ar_data multiplicand, multiplier, accum, newaccum, temp;
01020 AR_TYPE uint32_artype = AR_Int_32_U;
01021 AR_TYPE uint64_artype = AR_Int_64_U;
01022 unsigned long partialmult;
01023 int status = AR_STAT_OK;
01024 int result_negative;
01025
01026 int part_a, part_b, part_c, part_d, part_e, part_f, part_g, part_h;
01027
01028 switch (AR_INT_SIZE (*opnd1type)) {
01029 case AR_INT_SIZE_8:
01030 result_negative = AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01031 INT8_SIGN(opnd1);
01032 if (result_negative)
01033 ar_negate_integer (&multiplicand, opnd1type, opnd1,
01034 opnd1type);
01035 else
01036 multiplicand.ar_i8 = opnd1->ar_i8;
01037 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED &&
01038 INT8_SIGN(opnd2)) {
01039 result_negative ^= 1;
01040 ar_negate_integer (&multiplier, opnd2type, opnd2,
01041 opnd2type);
01042 } else
01043 multiplier.ar_i8 = opnd2->ar_i8;
01044
01045
01046 part_a = multiplicand.ar_i8.part5;
01047 part_b = multiplier.ar_i8.part5;
01048
01049
01050 partialmult = part_a * part_b;
01051 if (partialmult >> 8)
01052 status |= AR_STAT_OVERFLOW;
01053 ZERO_INT8_UPPER(&accum);
01054 accum.ar_i8.part5 = partialmult;
01055
01056 if (result_negative) {
01057 ar_negate_integer (result, resulttype, &accum,
01058 resulttype);
01059 if (!INT8_SIGN(result) && !IS_INT8_ZERO(result))
01060 status |= AR_STAT_OVERFLOW;
01061 } else {
01062 result->ar_i8 = accum.ar_i8;
01063 if (INT8_SIGN(result) &&
01064 (AR_SIGNEDNESS(*resulttype) == AR_SIGNED)) {
01065 status |= AR_STAT_OVERFLOW;
01066 }
01067 }
01068
01069
01070 status &= AR_STAT_OVERFLOW;
01071 if (IS_INT8_ZERO(result))
01072 status |= AR_STAT_ZERO;
01073 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
01074 INT8_SIGN(result))
01075 status |= AR_STAT_NEGATIVE;
01076 break;
01077
01078 case AR_INT_SIZE_16:
01079 result_negative = AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01080 INT16_SIGN(opnd1);
01081 if (result_negative)
01082 ar_negate_integer (&multiplicand, opnd1type, opnd1,
01083 opnd1type);
01084 else
01085 multiplicand.ar_i64 = opnd1->ar_i64;
01086 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED &&
01087 INT16_SIGN(opnd2)) {
01088 result_negative ^= 1;
01089 ar_negate_integer (&multiplier, opnd2type, opnd2,
01090 opnd2type);
01091 } else
01092 multiplier.ar_i64 = opnd2->ar_i64;
01093
01094
01095 part_a = multiplicand.ar_i64.part4;
01096 part_b = multiplier.ar_i64.part4;
01097
01098
01099 partialmult = part_a * part_b;
01100 if (partialmult >> 16)
01101 status |= AR_STAT_OVERFLOW;
01102 ZERO_INT16_UPPER(&accum);
01103 accum.ar_i64.part4 = partialmult;
01104
01105 if (result_negative) {
01106 ar_negate_integer (result, resulttype, &accum,
01107 resulttype);
01108 if (!INT16_SIGN(result) && !IS_INT16_ZERO(result))
01109 status |= AR_STAT_OVERFLOW;
01110 } else {
01111 result->ar_i64 = accum.ar_i64;
01112 if (INT16_SIGN(result) &&
01113 (AR_SIGNEDNESS(*resulttype) == AR_SIGNED)) {
01114 status |= AR_STAT_OVERFLOW;
01115 }
01116 }
01117
01118
01119 status &= AR_STAT_OVERFLOW;
01120 if (IS_INT16_ZERO(result))
01121 status |= AR_STAT_ZERO;
01122 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
01123 INT16_SIGN(result))
01124 status |= AR_STAT_NEGATIVE;
01125 break;
01126
01127 case AR_INT_SIZE_32:
01128 result_negative = AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01129 INT32_SIGN(opnd1);
01130 if (result_negative)
01131 ar_negate_integer (&multiplicand, opnd1type, opnd1,
01132 opnd1type);
01133 else
01134 multiplicand.ar_i64 = opnd1->ar_i64;
01135 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED &&
01136 INT32_SIGN(opnd2)) {
01137 result_negative ^= 1;
01138 ar_negate_integer (&multiplier, opnd2type, opnd2,
01139 opnd2type);
01140 } else
01141 multiplier.ar_i64 = opnd2->ar_i64;
01142
01143
01144 part_a = multiplicand.ar_i64.part3;
01145 part_b = multiplicand.ar_i64.part4;
01146 part_c = multiplier.ar_i64.part3;
01147 part_d = multiplier.ar_i64.part4;
01148
01149
01150 partialmult = part_b * part_d;
01151 ZERO_INT32_UPPER(&accum);
01152 accum.ar_i64.part3 = (partialmult & 0xFFFF0000) >> 16;
01153 accum.ar_i64.part4 = partialmult & 0xFFFF;
01154
01155 newaccum.ar_i64.part1 = newaccum.ar_i64.part2 = 0;
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 if (part_d) {
01167
01168
01169
01170
01171 if (part_a) {
01172 partialmult = part_a * part_d;
01173 if (partialmult >> 16)
01174 status |= AR_STAT_OVERFLOW;
01175 temp.ar_i64.part3 = partialmult;
01176 temp.ar_i64.part4 = 0;
01177 status |= ar_add_integer (&newaccum,
01178 &uint32_artype,
01179 &accum,
01180 &uint32_artype,
01181 &temp,
01182 &uint32_artype);
01183 accum.ar_i64 = newaccum.ar_i64;
01184 }
01185 }
01186
01187
01188 if (part_c) {
01189
01190
01191 if (part_b) {
01192 partialmult = part_b * part_c;
01193 if (partialmult >> 16)
01194 status |= AR_STAT_OVERFLOW;
01195 temp.ar_i64.part3 = partialmult;
01196 temp.ar_i64.part4 = 0;
01197 status |= ar_add_integer (&newaccum,
01198 &uint32_artype,
01199 &accum,
01200 &uint32_artype,
01201 &temp,
01202 &uint32_artype);
01203 accum.ar_i64 = newaccum.ar_i64;
01204 }
01205
01206
01207 if (part_a)
01208 status |= AR_STAT_OVERFLOW;
01209 }
01210
01211
01212
01213 if (result_negative) {
01214 ar_negate_integer (result, resulttype, &accum,
01215 resulttype);
01216 if (!INT32_SIGN(result) && !IS_INT32_ZERO(result))
01217 status |= AR_STAT_OVERFLOW;
01218 } else {
01219 result->ar_i64 = accum.ar_i64;
01220 if (INT32_SIGN(result) &&
01221 (AR_SIGNEDNESS(*resulttype) == AR_SIGNED)) {
01222 status |= AR_STAT_OVERFLOW;
01223 }
01224 }
01225
01226
01227 status &= AR_STAT_OVERFLOW;
01228 if (IS_INT32_ZERO(result))
01229 status |= AR_STAT_ZERO;
01230 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
01231 INT32_SIGN(result))
01232 status |= AR_STAT_NEGATIVE;
01233 break;
01234
01235 case AR_INT_SIZE_46:
01236 case AR_INT_SIZE_64:
01237 if (*opnd1type == AR_Int_46_S && INT_OVERFLOWS_46_BITS(*opnd1))
01238 status |= AR_STAT_OVERFLOW;
01239 if (*opnd2type == AR_Int_46_S && INT_OVERFLOWS_46_BITS(*opnd2))
01240 status |= AR_STAT_OVERFLOW;
01241
01242 result_negative = AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01243 INT64_SIGN(opnd1);
01244 if (result_negative)
01245 ar_negate_integer (&multiplicand, opnd1type, opnd1,
01246 opnd1type);
01247 else
01248 multiplicand.ar_i64 = opnd1->ar_i64;
01249 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED &&
01250 INT64_SIGN(opnd2)) {
01251 result_negative ^= 1;
01252 ar_negate_integer (&multiplier, opnd2type, opnd2,
01253 opnd2type);
01254 } else
01255 multiplier.ar_i64 = opnd2->ar_i64;
01256
01257
01258 part_a = multiplicand.ar_i64.part1;
01259 part_b = multiplicand.ar_i64.part2;
01260 part_c = multiplicand.ar_i64.part3;
01261 part_d = multiplicand.ar_i64.part4;
01262 part_e = multiplier.ar_i64.part1;
01263 part_f = multiplier.ar_i64.part2;
01264 part_g = multiplier.ar_i64.part3;
01265 part_h = multiplier.ar_i64.part4;
01266
01267
01268 partialmult = part_d * part_h;
01269 ZERO_INT32_UPPER(&accum);
01270 accum.ar_i64.part3 = (partialmult & 0xFFFF0000) >> 16;
01271 accum.ar_i64.part4 = partialmult & 0xFFFF;
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 if (part_h) {
01285
01286
01287
01288
01289 if (part_c) {
01290 partialmult = part_c * part_h;
01291 temp.ar_i64.part1 = temp.ar_i64.part4 = 0;
01292 temp.ar_i64.part2 = partialmult >> 16;
01293 temp.ar_i64.part3 = partialmult;
01294 status |= ar_add_integer (&newaccum,
01295 &uint64_artype,
01296 &accum,
01297 &uint64_artype,
01298 &temp,
01299 &uint64_artype);
01300 accum.ar_i64 = newaccum.ar_i64;
01301 }
01302
01303
01304 if (part_b) {
01305 partialmult = part_b * part_h;
01306 temp.ar_i64.part1 = partialmult >> 16;
01307 temp.ar_i64.part2 = partialmult;
01308 temp.ar_i64.part3 = temp.ar_i64.part4 = 0;
01309 status |= ar_add_integer (&newaccum,
01310 &uint64_artype,
01311 &accum,
01312 &uint64_artype,
01313 &temp,
01314 &uint64_artype);
01315 accum.ar_i64 = newaccum.ar_i64;
01316 }
01317
01318
01319 if (part_a) {
01320 partialmult = part_a * part_h;
01321 if (partialmult >> 16)
01322 status |= AR_STAT_OVERFLOW;
01323 temp.ar_i64.part1 = partialmult;
01324 temp.ar_i64.part2 = temp.ar_i64.part3 =
01325 temp.ar_i64.part4 = 0;
01326 status |= ar_add_integer (&newaccum,
01327 &uint64_artype,
01328 &accum,
01329 &uint64_artype,
01330 &temp,
01331 &uint64_artype);
01332 accum.ar_i64 = newaccum.ar_i64;
01333 }
01334 }
01335
01336
01337 if (part_g) {
01338
01339
01340 if (part_d) {
01341 partialmult = part_d * part_g;
01342 temp.ar_i64.part1 = temp.ar_i64.part4 = 0;
01343 temp.ar_i64.part2 = partialmult >> 16;
01344 temp.ar_i64.part3 = partialmult;
01345 status |= ar_add_integer (&newaccum,
01346 &uint64_artype,
01347 &accum,
01348 &uint64_artype,
01349 &temp,
01350 &uint64_artype);
01351 accum.ar_i64 = newaccum.ar_i64;
01352 }
01353
01354
01355 if (part_c) {
01356 partialmult = part_c * part_g;
01357 temp.ar_i64.part1 = partialmult >> 16;
01358 temp.ar_i64.part2 = partialmult;
01359 temp.ar_i64.part3 = temp.ar_i64.part4 = 0;
01360 status |= ar_add_integer (&newaccum,
01361 &uint64_artype,
01362 &accum,
01363 &uint64_artype,
01364 &temp,
01365 &uint64_artype);
01366 accum.ar_i64 = newaccum.ar_i64;
01367 }
01368
01369
01370 if (part_b) {
01371 partialmult = part_b * part_g;
01372 if (partialmult >> 16)
01373 status |= AR_STAT_OVERFLOW;
01374 temp.ar_i64.part1 = partialmult;
01375 temp.ar_i64.part2 = temp.ar_i64.part3 =
01376 temp.ar_i64.part4 = 0;
01377 status |= ar_add_integer (&newaccum,
01378 &uint64_artype,
01379 &accum,
01380 &uint64_artype,
01381 &temp,
01382 &uint64_artype);
01383 accum.ar_i64 = newaccum.ar_i64;
01384 }
01385
01386
01387 if (part_a)
01388 status |= AR_STAT_OVERFLOW;
01389 }
01390
01391
01392 if (part_f) {
01393
01394
01395 if (part_d) {
01396 partialmult = part_d * part_f;
01397 temp.ar_i64.part1 = partialmult >> 16;
01398 temp.ar_i64.part2 = partialmult;
01399 temp.ar_i64.part3 = temp.ar_i64.part4 = 0;
01400 status |= ar_add_integer (&newaccum,
01401 &uint64_artype,
01402 &accum,
01403 &uint64_artype,
01404 &temp,
01405 &uint64_artype);
01406 accum.ar_i64 = newaccum.ar_i64;
01407 }
01408
01409
01410 if (part_c) {
01411 partialmult = part_c * part_f;
01412 if (partialmult >> 16)
01413 status |= AR_STAT_OVERFLOW;
01414 temp.ar_i64.part1 = partialmult;
01415 temp.ar_i64.part2 = temp.ar_i64.part3 =
01416 temp.ar_i64.part4 = 0;
01417 status |= ar_add_integer (&newaccum,
01418 &uint64_artype,
01419 &accum,
01420 &uint64_artype,
01421 &temp,
01422 &uint64_artype);
01423 accum.ar_i64 = newaccum.ar_i64;
01424 }
01425
01426
01427 if (part_a | part_b)
01428 status |= AR_STAT_OVERFLOW;
01429 }
01430
01431
01432 if (part_e) {
01433
01434
01435 if (part_d) {
01436 partialmult = part_d * part_e;
01437 if (partialmult >> 16)
01438 status |= AR_STAT_OVERFLOW;
01439 temp.ar_i64.part1 = partialmult;
01440 temp.ar_i64.part2 = temp.ar_i64.part3 =
01441 temp.ar_i64.part4 = 0;
01442 status |= ar_add_integer (&newaccum,
01443 &uint64_artype,
01444 &accum,
01445 &uint64_artype,
01446 &temp,
01447 &uint64_artype);
01448 accum.ar_i64 = newaccum.ar_i64;
01449 }
01450
01451
01452 if (part_a | part_b | part_c)
01453 status |= AR_STAT_OVERFLOW;
01454 }
01455
01456
01457
01458 if (result_negative) {
01459 ar_negate_integer (result, resulttype, &accum,
01460 resulttype);
01461 if (!INT64_SIGN(result) && !IS_INT64_ZERO(result))
01462 status |= AR_STAT_OVERFLOW;
01463 } else {
01464 result->ar_i64 = accum.ar_i64;
01465 if (INT64_SIGN(result) &&
01466 (AR_SIGNEDNESS(*resulttype) == AR_SIGNED)) {
01467 status |= AR_STAT_OVERFLOW;
01468 }
01469 }
01470
01471 if (*resulttype == AR_Int_46_S &&
01472 INT_OVERFLOWS_46_BITS (*result))
01473 status |= AR_STAT_OVERFLOW;
01474
01475
01476 status &= AR_STAT_OVERFLOW;
01477 if (IS_INT64_ZERO(result))
01478 status |= AR_STAT_ZERO;
01479 else if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
01480 INT64_SIGN(result))
01481 status |= AR_STAT_NEGATIVE;
01482 break;
01483
01484 default:
01485 return (AR_STAT_INVALID_TYPE);
01486 }
01487
01488 return status;
01489 }
01490
01491
01492 static
01493 int
01494 ar_multiply_float
01495 (ar_data *result, const AR_TYPE *resulttype,
01496 const ar_data *opnd1, const AR_TYPE *opnd1type,
01497 const ar_data *opnd2, const AR_TYPE *opnd2type) {
01498
01499 int status;
01500
01501 ar_data tmp1, tmp2;
01502
01503 switch (*opnd1type) {
01504 case AR_Float_Cray1_64:
01505 case AR_Float_Cray1_64_F:
01506 status = ar_cfmul64 (&result->ar_f64,
01507 &opnd1->ar_f64, &opnd2->ar_f64,
01508 ROUND_MODE (*opnd1type));
01509 if (ar_state_register.ar_truncate_bits > 0)
01510 ar_CRAY_64_trunc(&result->ar_f64);
01511 return status;
01512
01513 case AR_Float_Cray1_128:
01514 return ar_cfmul128 (&result->ar_f128,
01515 &opnd1->ar_f128, &opnd2->ar_f128,
01516 ROUND_MODE (*opnd1type));
01517 case AR_Float_IEEE_NR_32:
01518 case AR_Float_IEEE_ZE_32:
01519 case AR_Float_IEEE_UP_32:
01520 case AR_Float_IEEE_DN_32:
01521 return ar_ifmul32 (&result->ar_ieee32,
01522 &opnd1->ar_ieee32, &opnd2->ar_ieee32,
01523 ROUND_MODE (*opnd1type));
01524 case AR_Float_IEEE_NR_64:
01525 case AR_Float_IEEE_ZE_64:
01526 case AR_Float_IEEE_UP_64:
01527 case AR_Float_IEEE_DN_64:
01528 return ar_ifmul64 (&result->ar_ieee64,
01529 &opnd1->ar_ieee64, &opnd2->ar_ieee64,
01530 ROUND_MODE (*opnd1type));
01531 case AR_Float_IEEE_NR_128:
01532 case AR_Float_IEEE_ZE_128:
01533 case AR_Float_IEEE_UP_128:
01534 case AR_Float_IEEE_DN_128:
01535 return ar_ifmul128 (&result->ar_ieee128,
01536 &opnd1->ar_ieee128, &opnd2->ar_ieee128,
01537 ROUND_MODE (*opnd1type));
01538 default:
01539 return AR_STAT_INVALID_TYPE;
01540 }
01541 }
01542
01543
01544 static
01545 int
01546 ar_multiply_complex
01547 (ar_data *result, const AR_TYPE *resulttype,
01548 const ar_data *opnd1, const AR_TYPE *opnd1type,
01549 const ar_data *opnd2, const AR_TYPE *opnd2type) {
01550
01551 AR_DATA a, b, c, d, ac, bd, ad, bc, re, im;
01552 AR_TYPE reimtype1, reimtype2, temptype;
01553 int status, restat, imstat;
01554
01555
01556
01557 status = ar_decompose_complex ((ar_data*)&a, (ar_data*)&b, &reimtype1,
01558 opnd1, opnd1type);
01559 status |= ar_decompose_complex ((ar_data*)&c, (ar_data*)&d, &reimtype2,
01560 opnd2, opnd2type);
01561
01562 status |= AR_multiply (&ac, &reimtype1, &a, &reimtype1, &c, &reimtype2);
01563 status |= AR_multiply (&bd, &reimtype1, &b, &reimtype1, &d, &reimtype2);
01564 status |= AR_multiply (&ad, &reimtype1, &a, &reimtype1, &d, &reimtype2);
01565 status |= AR_multiply (&bc, &reimtype1, &b, &reimtype1, &c, &reimtype2);
01566
01567 restat = AR_subtract (&re, &reimtype1, &ac, &reimtype1, &bd, &reimtype1);
01568 imstat = AR_add (&im, &reimtype1, &ad, &reimtype1, &bc, &reimtype1);
01569 status |= restat | imstat;
01570
01571 status |= ar_compose_complex (result, &temptype,
01572 (ar_data*)&re, (ar_data*)&im, &reimtype1);
01573
01574 status &= ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
01575 status |= restat | imstat | AR_STAT_ZERO;
01576 return status;
01577 }
01578
01579
01580
01581 int
01582 AR_multiply
01583 (AR_DATA *res, const AR_TYPE *resulttype,
01584 const AR_DATA *op1, const AR_TYPE *opnd1type,
01585 const AR_DATA *op2, const AR_TYPE *opnd2type) {
01586
01587 ar_data* result = (ar_data*)res;
01588 ar_data* opnd1 = (ar_data*)op1;
01589 ar_data* opnd2 = (ar_data*)op2;
01590
01591 if (*resulttype != *opnd1type || *resulttype != *opnd2type)
01592 return AR_STAT_INVALID_TYPE;
01593
01594 if (AR_CLASS (*resulttype) == AR_CLASS_INT)
01595 if (AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 &&
01596 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 &&
01597 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 &&
01598 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 &&
01599 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64) {
01600 return AR_STAT_INVALID_TYPE;
01601 }
01602 else {
01603 int status;
01604
01605 status = ar_multiply_integer(result, resulttype,
01606 opnd1, opnd1type,
01607 opnd2, opnd2type);
01608 if (AR_SIGNEDNESS(*resulttype) == AR_UNSIGNED) {
01609
01610 status &= ~AR_STAT_OVERFLOW;
01611 }
01612
01613 return (status);
01614 }
01615
01616 if (AR_CLASS (*resulttype) == AR_CLASS_FLOAT)
01617 if (AR_FLOAT_IS_COMPLEX (*resulttype) == AR_FLOAT_COMPLEX)
01618 return ar_multiply_complex (result, resulttype,
01619 opnd1, opnd1type,
01620 opnd2, opnd2type);
01621 else
01622 return ar_multiply_float (result, resulttype,
01623 opnd1, opnd1type,
01624 opnd2, opnd2type);
01625
01626 return AR_STAT_INVALID_TYPE;
01627 }
01628
01629
01630
01631 int
01632 ar_divide_integer
01633 (ar_data *result1, const AR_TYPE *result1type,
01634 ar_data *result2, const AR_TYPE *result2type,
01635 const ar_data *opnd1, const AR_TYPE *opnd1type,
01636 const ar_data *opnd2, const AR_TYPE *opnd2type) {
01637
01638 ar_data dividend, divisor, accum, shiftcount, temp;
01639 ar_data lzdividend, lzdivisor;
01640
01641 AR_TYPE type8 = AR_Int_8_U;
01642 AR_TYPE type16 = AR_Int_16_U;
01643 AR_TYPE type32 = AR_Int_32_U;
01644 AR_TYPE type64 = AR_Int_64_U;
01645
01646 int opnd1sign, opnd2sign;
01647 int seqcount;
01648
01649 switch (AR_INT_SIZE (*opnd1type)) {
01650 case AR_INT_SIZE_8:
01651 ZERO_INT8_UPPER(result1);
01652 ZERO_INT8_UPPER(result2);
01653
01654
01655 if (IS_INT8_ZERO(opnd2)) {
01656 ZERO_INT8(result1);
01657 ZERO_INT8(result2);
01658 return AR_STAT_OVERFLOW;
01659 }
01660
01661 if (IS_INT8_ZERO(opnd1)) {
01662 ZERO_INT8(result1);
01663 ZERO_INT8(result2);
01664 return AR_STAT_ZERO;
01665 }
01666
01667 opnd1sign = INT8_SIGN(opnd1) != 0;
01668 opnd2sign = INT8_SIGN(opnd2) != 0;
01669
01670 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01671 ar_negate_integer (÷nd, opnd1type,
01672 opnd1, opnd1type);
01673 else
01674 dividend = *opnd1;
01675
01676 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED && opnd2sign)
01677 ar_negate_integer (&divisor, opnd2type,
01678 opnd2, opnd2type);
01679 else
01680 divisor = *opnd2;
01681
01682 ZERO_INT8_UPPER(÷nd);
01683 ZERO_INT8_UPPER(&divisor );
01684 ZERO_INT8_UPPER(&temp );
01685
01686 ZERO_INT8_ALL(&accum);
01687
01688
01689 AR_leadz ((AR_DATA*)&lzdividend, &type8,
01690 (AR_DATA*)÷nd, &type8);
01691 AR_leadz ((AR_DATA*)&lzdivisor, &type8,
01692 (AR_DATA*)&divisor, &type8);
01693 ar_subtract_integer (&shiftcount, &type8, (int *) 0,
01694 &lzdivisor, &type8,
01695 &lzdividend, &type8);
01696
01697 if (!INT8_SIGN(&shiftcount)) {
01698 if (shiftcount.ar_i8.part5 & 0xF8)
01699 ar_internal_error (2001, __FILE__, __LINE__);
01700 seqcount = shiftcount.ar_i8.part5 + 1;
01701 AR_shiftl ((AR_DATA*)&temp, &type8,
01702 (AR_DATA*)&divisor, &type8,
01703 (AR_DATA*)&shiftcount, &type8);
01704 divisor = temp;
01705
01706 shiftcount.ar_i8.part5 = 1;
01707
01708 do {
01709 AR_shiftl ((AR_DATA*)&temp, &type8,
01710 (AR_DATA*)&accum, &type8,
01711 (AR_DATA*)&shiftcount, &type8);
01712 accum = temp;
01713 ar_subtract_integer (&temp, &type8, (int *)0,
01714 ÷nd, &type8,
01715 &divisor, &type8);
01716 if (!INT8_SIGN(&temp)) {
01717 accum.ar_i8.part5 |= 1;
01718 dividend = temp;
01719 }
01720 AR_shiftr ((AR_DATA*)&temp, &type8,
01721 (AR_DATA*)&divisor, &type8,
01722 (AR_DATA*)&shiftcount, &type8);
01723 divisor = temp;
01724
01725 } while (--seqcount > 0);
01726 }
01727
01728 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01729 opnd1sign != opnd2sign)
01730 ar_negate_integer (result1, result1type,
01731 &accum, &type8);
01732 else
01733 result1->ar_i64 = accum.ar_i64;
01734
01735 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01736 ar_negate_integer (result2, result2type,
01737 ÷nd, &type8);
01738 else
01739 result2->ar_i64 = dividend.ar_i64;
01740 break;
01741
01742 case AR_INT_SIZE_16:
01743 ZERO_INT16_UPPER(result1);
01744 ZERO_INT16_UPPER(result2);
01745
01746
01747 if (IS_INT16_ZERO(opnd2)) {
01748 ZERO_INT16(result1);
01749 ZERO_INT16(result2);
01750 return AR_STAT_OVERFLOW;
01751 }
01752
01753 if (IS_INT16_ZERO(opnd1)) {
01754 ZERO_INT16(result1);
01755 ZERO_INT16(result2);
01756 return AR_STAT_ZERO;
01757 }
01758
01759 opnd1sign = INT16_SIGN(opnd1) != 0;
01760 opnd2sign = INT16_SIGN(opnd2) != 0;
01761
01762 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01763 ar_negate_integer (÷nd, opnd1type,
01764 opnd1, opnd1type);
01765 else
01766 dividend = *opnd1;
01767
01768 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED && opnd2sign)
01769 ar_negate_integer (&divisor, opnd2type,
01770 opnd2, opnd2type);
01771 else
01772 divisor = *opnd2;
01773
01774 ZERO_INT16_UPPER(÷nd);
01775 ZERO_INT16_UPPER(&divisor );
01776 ZERO_INT16_UPPER(&temp );
01777
01778 ZERO_INT16_ALL(&accum);
01779
01780
01781 AR_leadz ((AR_DATA*)&lzdividend, &type16,
01782 (AR_DATA*)÷nd, &type16);
01783 AR_leadz ((AR_DATA*)&lzdivisor, &type16,
01784 (AR_DATA*)&divisor, &type16);
01785 ar_subtract_integer (&shiftcount, &type16, (int *) 0,
01786 &lzdivisor, &type16,
01787 &lzdividend, &type16);
01788
01789 if (!INT16_SIGN(&shiftcount)) {
01790 if (shiftcount.ar_i64.part4 & 0xFFF0)
01791 ar_internal_error (2001, __FILE__, __LINE__);
01792 seqcount = shiftcount.ar_i64.part4 + 1;
01793 AR_shiftl ((AR_DATA*)&temp, &type16,
01794 (AR_DATA*)&divisor, &type16,
01795 (AR_DATA*)&shiftcount, &type16);
01796 divisor = temp;
01797
01798 shiftcount.ar_i64.part4 = 1;
01799
01800 do {
01801 AR_shiftl ((AR_DATA*)&temp, &type16,
01802 (AR_DATA*)&accum, &type16,
01803 (AR_DATA*)&shiftcount, &type16);
01804 accum = temp;
01805 ar_subtract_integer (&temp, &type16, (int *)0,
01806 ÷nd, &type16,
01807 &divisor, &type16);
01808 if (!INT16_SIGN(&temp)) {
01809 accum.ar_i64.part4 |= 1;
01810 dividend = temp;
01811 }
01812 AR_shiftr ((AR_DATA*)&temp, &type16,
01813 (AR_DATA*)&divisor, &type16,
01814 (AR_DATA*)&shiftcount, &type16);
01815 divisor = temp;
01816
01817 } while (--seqcount > 0);
01818 }
01819
01820 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01821 opnd1sign != opnd2sign)
01822 ar_negate_integer (result1, result1type,
01823 &accum, &type16);
01824 else
01825 result1->ar_i64 = accum.ar_i64;
01826
01827 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01828 ar_negate_integer (result2, result2type,
01829 ÷nd, &type16);
01830 else
01831 result2->ar_i64 = dividend.ar_i64;
01832 break;
01833
01834 case AR_INT_SIZE_32:
01835 ZERO_INT32_UPPER(result1);
01836 ZERO_INT32_UPPER(result2);
01837
01838
01839 if (IS_INT32_ZERO(opnd2)) {
01840 ZERO_INT32(result1);
01841 ZERO_INT32(result2);
01842 return AR_STAT_OVERFLOW;
01843 }
01844
01845 if (IS_INT32_ZERO(opnd1)) {
01846 ZERO_INT32(result1);
01847 ZERO_INT32(result2);
01848 return AR_STAT_ZERO;
01849 }
01850
01851 opnd1sign = INT32_SIGN(opnd1) != 0;
01852 opnd2sign = INT32_SIGN(opnd2) != 0;
01853
01854 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01855 ar_negate_integer (÷nd, opnd1type,
01856 opnd1, opnd1type);
01857 else
01858 dividend = *opnd1;
01859
01860 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED && opnd2sign)
01861 ar_negate_integer (&divisor, opnd2type,
01862 opnd2, opnd2type);
01863 else
01864 divisor = *opnd2;
01865
01866 ZERO_INT32_UPPER(÷nd);
01867 ZERO_INT32_UPPER(&divisor );
01868 ZERO_INT32_UPPER(&temp );
01869
01870 ZERO_INT32_ALL(&accum);
01871
01872
01873 AR_leadz ((AR_DATA*)&lzdividend, &type32,
01874 (AR_DATA*)÷nd, &type32);
01875 AR_leadz ((AR_DATA*)&lzdivisor, &type32,
01876 (AR_DATA*)&divisor, &type32);
01877 ar_subtract_integer (&shiftcount, &type32, (int *) 0,
01878 &lzdivisor, &type32,
01879 &lzdividend, &type32);
01880
01881 if (!INT32_SIGN(&shiftcount)) {
01882 if (shiftcount.ar_i64.part3 |
01883 shiftcount.ar_i64.part4 & 0xFFE0)
01884 ar_internal_error (2001, __FILE__, __LINE__);
01885 seqcount = shiftcount.ar_i64.part4 + 1;
01886 AR_shiftl ((AR_DATA*)&temp, &type32,
01887 (AR_DATA*)&divisor, &type32,
01888 (AR_DATA*)&shiftcount, &type32);
01889 divisor = temp;
01890
01891 shiftcount.ar_i64.part3 = 0;
01892 shiftcount.ar_i64.part4 = 1;
01893
01894 do {
01895 AR_shiftl ((AR_DATA*)&temp, &type32,
01896 (AR_DATA*)&accum, &type32,
01897 (AR_DATA*)&shiftcount, &type32);
01898 accum = temp;
01899 ar_subtract_integer (&temp, &type32, (int *)0,
01900 ÷nd, &type32,
01901 &divisor, &type32);
01902 if (!INT32_SIGN(&temp)) {
01903 accum.ar_i64.part4 |= 1;
01904 dividend = temp;
01905 }
01906 AR_shiftr ((AR_DATA*)&temp, &type32,
01907 (AR_DATA*)&divisor, &type32,
01908 (AR_DATA*)&shiftcount, &type32);
01909 divisor = temp;
01910
01911 } while (--seqcount > 0);
01912 }
01913
01914 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
01915 opnd1sign != opnd2sign)
01916 ar_negate_integer (result1, result1type,
01917 &accum, &type32);
01918 else
01919 result1->ar_i64 = accum.ar_i64;
01920
01921 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01922 ar_negate_integer (result2, result2type,
01923 ÷nd, &type32);
01924 else
01925 result2->ar_i64 = dividend.ar_i64;
01926 break;
01927
01928 case AR_INT_SIZE_46:
01929 case AR_INT_SIZE_64:
01930
01931 if (IS_INT64_ZERO(opnd2)) {
01932 ZERO_INT64(result1);
01933 ZERO_INT64(result2);
01934 return AR_STAT_OVERFLOW;
01935 }
01936
01937 if (IS_INT64_ZERO(opnd1)) {
01938 ZERO_INT64(result1);
01939 ZERO_INT64(result2);
01940 return AR_STAT_ZERO;
01941 }
01942
01943 opnd1sign = INT64_SIGN(opnd1) != 0;
01944 opnd2sign = INT64_SIGN(opnd2) != 0;
01945
01946 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
01947 ar_negate_integer (÷nd, opnd1type,
01948 opnd1, opnd1type);
01949 else
01950 dividend = *opnd1;
01951
01952 if (AR_SIGNEDNESS (*opnd2type) == AR_SIGNED && opnd2sign)
01953 ar_negate_integer (&divisor, opnd2type, opnd2,
01954 opnd2type);
01955 else
01956 divisor = *opnd2;
01957
01958 ZERO_INT64_ALL(&accum);
01959
01960
01961 AR_leadz ((AR_DATA*)&lzdividend, &type64,
01962 (AR_DATA*)÷nd, &type64);
01963 AR_leadz ((AR_DATA*)&lzdivisor, &type64,
01964 (AR_DATA*)&divisor, &type64);
01965 ar_subtract_integer (&shiftcount, &type64, (int *) 0,
01966 &lzdivisor, &type64,
01967 &lzdividend, &type64);
01968
01969 if (!INT64_SIGN(&shiftcount)) {
01970 if (shiftcount.ar_i64.part1 |
01971 shiftcount.ar_i64.part2 |
01972 shiftcount.ar_i64.part3 |
01973 shiftcount.ar_i64.part4 & 0xFFC0)
01974 ar_internal_error (2001, __FILE__, __LINE__);
01975 seqcount = shiftcount.ar_i64.part4 + 1;
01976 AR_shiftl ((AR_DATA*)&temp, &type64,
01977 (AR_DATA*)&divisor, &type64,
01978 (AR_DATA*)&shiftcount, &type64);
01979 divisor = temp;
01980
01981 shiftcount.ar_i64.part1 = shiftcount.ar_i64.part2 =
01982 shiftcount.ar_i64.part3 = 0;
01983 shiftcount.ar_i64.part4 = 1;
01984
01985 do {
01986 AR_shiftl ((AR_DATA*)&temp, &type64,
01987 (AR_DATA*)&accum, &type64,
01988 (AR_DATA*)&shiftcount, &type64);
01989 accum = temp;
01990 ar_subtract_integer (&temp, &type64,
01991 (int *)0,
01992 ÷nd, &type64,
01993 &divisor, &type64);
01994 if (!INT64_SIGN(&temp)) {
01995 accum.ar_i64.part4 |= 1;
01996 dividend = temp;
01997 }
01998 AR_shiftr ((AR_DATA*)&temp, &type64,
01999 (AR_DATA*)&divisor, &type64,
02000 (AR_DATA*)&shiftcount, &type64);
02001 divisor = temp;
02002
02003 } while (--seqcount > 0);
02004 }
02005
02006 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED &&
02007 opnd1sign != opnd2sign)
02008 ar_negate_integer (result1, result1type,
02009 &accum, &type64);
02010 else
02011 result1->ar_i64 = accum.ar_i64;
02012
02013 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED && opnd1sign)
02014 ar_negate_integer (result2, result2type,
02015 ÷nd, &type64);
02016 else
02017 result2->ar_i64 = dividend.ar_i64;
02018 break;
02019
02020 default:
02021 return (AR_STAT_INVALID_TYPE);
02022 }
02023
02024 return AR_STAT_OK;
02025 }
02026
02027
02028 static
02029 int
02030 ar_divide_float
02031 (ar_data *result, const AR_TYPE *resulttype,
02032 const ar_data *opnd1, const AR_TYPE *opnd1type,
02033 const ar_data *opnd2, const AR_TYPE *opnd2type) {
02034
02035 int status;
02036
02037 ar_data tmp1, tmp2;
02038
02039 switch (*opnd1type) {
02040 case AR_Float_Cray1_64:
02041 case AR_Float_Cray1_64_F:
02042 return ar_cfdiv64 (&result->ar_f64,
02043 &opnd1->ar_f64, &opnd2->ar_f64,
02044 ROUND_MODE (*opnd1type));
02045 case AR_Float_Cray1_128:
02046 return ar_cfdiv128 (&result->ar_f128,
02047 &opnd1->ar_f128, &opnd2->ar_f128,
02048 ROUND_MODE (*opnd1type));
02049 case AR_Float_IEEE_NR_32:
02050 case AR_Float_IEEE_ZE_32:
02051 case AR_Float_IEEE_UP_32:
02052 case AR_Float_IEEE_DN_32:
02053 return ar_ifdiv32 (&result->ar_ieee32,
02054 &opnd1->ar_ieee32, &opnd2->ar_ieee32,
02055 ROUND_MODE (*opnd1type));
02056 case AR_Float_IEEE_NR_64:
02057 case AR_Float_IEEE_ZE_64:
02058 case AR_Float_IEEE_UP_64:
02059 case AR_Float_IEEE_DN_64:
02060 return ar_ifdiv64 (&result->ar_ieee64,
02061 &opnd1->ar_ieee64, &opnd2->ar_ieee64,
02062 ROUND_MODE (*opnd1type));
02063 case AR_Float_IEEE_NR_128:
02064 case AR_Float_IEEE_ZE_128:
02065 case AR_Float_IEEE_UP_128:
02066 case AR_Float_IEEE_DN_128:
02067 return ar_ifdiv128 (&result->ar_ieee128,
02068 &opnd1->ar_ieee128, &opnd2->ar_ieee128,
02069 ROUND_MODE (*opnd1type));
02070 default:
02071 return AR_STAT_INVALID_TYPE;
02072 }
02073 }
02074
02075
02076
02077 int
02078 AR_divide
02079 (AR_DATA *res, const AR_TYPE *resulttype,
02080 const AR_DATA *op1, const AR_TYPE *opnd1type,
02081 const AR_DATA *op2, const AR_TYPE *opnd2type) {
02082
02083 ar_data* result = (ar_data*)res;
02084 ar_data* opnd1 = (ar_data*)op1;
02085 ar_data* opnd2 = (ar_data*)op2;
02086
02087 int status, restat, imstat;
02088 ar_data modresult, real1, imag1, real2, imag2, realq, imagq;
02089 AR_TYPE reimtype, scrtype;
02090
02091 if (*resulttype == *opnd1type &&
02092 AR_CLASS (*resulttype) == AR_CLASS_FLOAT &&
02093 AR_FLOAT_IS_COMPLEX (*resulttype) == AR_FLOAT_COMPLEX) {
02094 status = ar_decompose_complex (&real1, &imag1, &reimtype,
02095 opnd1, opnd1type);
02096 if (reimtype == *opnd2type) {
02097
02098 restat = ar_divide_float (&realq, &reimtype,
02099 &real1, &reimtype,
02100 opnd2, opnd2type);
02101 imstat = ar_divide_float (&imagq, &reimtype,
02102 &imag1, &reimtype,
02103 opnd2, opnd2type);
02104 status |= ar_compose_complex (result, &scrtype,
02105 &realq, &imagq,
02106 &reimtype);
02107 status |= restat | imstat;
02108 status &= ~(AR_STAT_ZERO | AR_STAT_NEGATIVE);
02109 status |= restat & imstat & AR_STAT_ZERO;
02110 return status;
02111 }
02112 }
02113
02114 if (*resulttype != *opnd1type || *resulttype != *opnd2type)
02115 return AR_STAT_INVALID_TYPE;
02116
02117 if (AR_CLASS (*opnd1type) == AR_CLASS_INT) {
02118 if (AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_8 &&
02119 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_16 &&
02120 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_32 &&
02121 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_46 &&
02122 AR_INT_SIZE (*opnd1type) != AR_INT_SIZE_64)
02123 return AR_STAT_INVALID_TYPE;
02124 status = ar_divide_integer (result, resulttype,
02125 &modresult, resulttype,
02126 opnd1, opnd1type,
02127 opnd2, opnd2type);
02128 if (AR_SIGNEDNESS (*opnd1type) == AR_SIGNED) {
02129 if ((*opnd1type == AR_Int_46_S &&
02130 INT_OVERFLOWS_46_BITS (*opnd1)) ||
02131 (*opnd2type == AR_Int_46_S &&
02132 INT_OVERFLOWS_46_BITS (*opnd2)) ||
02133 (*resulttype == AR_Int_46_S &&
02134 INT_OVERFLOWS_46_BITS (*result)))
02135 status |= AR_STAT_OVERFLOW;
02136 switch (AR_INT_SIZE (*opnd1type)) {
02137 case AR_INT_SIZE_8:
02138 if (!IS_INT8_ZERO(result) &&
02139 (INT8_SIGN(opnd1) ^
02140 INT8_SIGN(opnd2) ^
02141 INT8_SIGN(result)))
02142
02143 status |= AR_STAT_OVERFLOW;
02144 break;
02145
02146 case AR_INT_SIZE_16:
02147 if (!IS_INT16_ZERO(result) &&
02148 (INT16_SIGN(opnd1) ^
02149 INT16_SIGN(opnd2) ^
02150 INT16_SIGN(result)))
02151
02152 status |= AR_STAT_OVERFLOW;
02153 break;
02154
02155 case AR_INT_SIZE_32:
02156 if (!IS_INT32_ZERO(result) &&
02157 (INT32_SIGN(opnd1) ^
02158 INT32_SIGN(opnd2) ^
02159 INT32_SIGN(result)))
02160
02161 status |= AR_STAT_OVERFLOW;
02162 break;
02163
02164 case AR_INT_SIZE_46:
02165 case AR_INT_SIZE_64:
02166 if (!IS_INT64_ZERO(result) &&
02167 (INT64_SIGN(opnd1) ^
02168 INT64_SIGN(opnd2) ^
02169 INT64_SIGN(result)))
02170
02171 status |= AR_STAT_OVERFLOW;
02172 break;
02173
02174 default:
02175 return (AR_STAT_INVALID_TYPE);
02176 }
02177 }
02178
02179 return status |= AR_status ((AR_DATA*)result, resulttype);
02180 }
02181
02182 if (AR_CLASS (*opnd1type) == AR_CLASS_FLOAT)
02183 if (AR_FLOAT_IS_COMPLEX (*opnd1type) == AR_FLOAT_COMPLEX)
02184 return ar_divide_complex (result, resulttype,
02185 opnd1, opnd1type,
02186 opnd2, opnd2type);
02187 else
02188 return ar_divide_float (result, resulttype,
02189 opnd1, opnd1type,
02190 opnd2, opnd2type);
02191
02192 return AR_STAT_INVALID_TYPE;
02193 }
02194
02195
02196 int
02197 AR_modulo
02198 (AR_DATA *result, const AR_TYPE *resulttype,
02199 const AR_DATA *opnd1, const AR_TYPE *opnd1type,
02200 const AR_DATA *opnd2, const AR_TYPE *opnd2type) {
02201
02202
02203
02204
02205
02206
02207
02208
02209 return AR_mod(result, resulttype, opnd1, opnd1type, opnd2, opnd2type);
02210 }
02211
02212 int
02213 AR_mod (AR_DATA *res, const AR_TYPE *resulttype,
02214 const AR_DATA *op1, const AR_TYPE *opnd1type,
02215 const AR_DATA *op2, const AR_TYPE *opnd2type) {
02216
02217 ar_data* result = (ar_data*)res;
02218 ar_data* opnd1 = (ar_data*)op1;
02219 ar_data* opnd2 = (ar_data*)op2;
02220
02221 int status;
02222 ar_data divresult;
02223
02224 if (*resulttype != *opnd1type ||
02225 *resulttype != *opnd2type ||
02226 AR_CLASS (*resulttype) != AR_CLASS_INT ||
02227 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 &&
02228 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 &&
02229 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 &&
02230 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 &&
02231 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64)
02232 return AR_STAT_INVALID_TYPE;
02233
02234 status = ar_divide_integer (&divresult, resulttype,
02235 result, resulttype,
02236 opnd1, opnd1type,
02237 opnd2, opnd2type);
02238
02239 status |= AR_status ((AR_DATA*)result, resulttype);
02240
02241 if (AR_SIGNEDNESS (*resulttype) == AR_SIGNED &&
02242 !(status & AR_STAT_ZERO)) {
02243 switch (AR_INT_SIZE (*opnd1type)) {
02244 case AR_INT_SIZE_8:
02245 if (INT8_SIGN(result) ^ INT8_SIGN(opnd1))
02246 status |= AR_STAT_OVERFLOW;
02247 break;
02248
02249 case AR_INT_SIZE_16:
02250 if (INT16_SIGN(result) ^ INT16_SIGN(opnd1))
02251 status |= AR_STAT_OVERFLOW;
02252 break;
02253
02254 case AR_INT_SIZE_32:
02255 if (INT32_SIGN(result) ^ INT32_SIGN(opnd1))
02256 status |= AR_STAT_OVERFLOW;
02257 break;
02258
02259 case AR_INT_SIZE_46:
02260 case AR_INT_SIZE_64:
02261 if (INT64_SIGN(result) ^ INT64_SIGN(opnd1))
02262 status |= AR_STAT_OVERFLOW;
02263 break;
02264 }
02265 }
02266
02267 return status;
02268 }
02269
02270
02271
02272 int
02273 AR_add_ptr_int
02274 (AR_DATA *res, const AR_TYPE *resulttype,
02275 const AR_DATA *op1, const AR_TYPE *opnd1type,
02276 const AR_DATA *op2, const AR_TYPE *opnd2type,
02277 const AR_DATA *op3, const AR_TYPE *opnd3type) {
02278
02279 ar_data* result = (ar_data*)res;
02280 ar_data* opnd1 = (ar_data*)op1;
02281 ar_data* opnd2 = (ar_data*)op2;
02282 ar_data* opnd3 = (ar_data*)op3;
02283
02284 ar_data ptropnd, sizeopnd, intopnd, signextend;
02285 AR_TYPE sint64 = AR_Int_64_S;
02286 int status;
02287
02288 if (*resulttype != *opnd1type ||
02289 AR_CLASS (*opnd1type) != AR_CLASS_POINTER ||
02290 AR_CLASS (*opnd2type) != AR_CLASS_INT ||
02291 AR_CLASS (*opnd3type) != AR_CLASS_INT ||
02292 AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_FCTN)
02293 return AR_STAT_INVALID_TYPE;
02294
02295 status = ar_convert_to_integral(&sizeopnd, &sint64, opnd2, opnd2type);
02296 if (status & ~AR_STAT_ZERO)
02297
02298
02299 return AR_STAT_UNDEFINED;
02300
02301 status = ar_convert_to_integral(&intopnd, &sint64, opnd3, opnd3type);
02302 status |= ar_multiply_integer(&intopnd, &sint64, &intopnd, &sint64,
02303 &sizeopnd, &sint64);
02304
02305 if (INT64_SIGN(&intopnd))
02306 signextend.ar_i64.part1 = signextend.ar_i64.part2 =
02307 signextend.ar_i64.part3 = signextend.ar_i64.part4 = 0xffff;
02308 else
02309 signextend.ar_i64.part1 = signextend.ar_i64.part2 =
02310 signextend.ar_i64.part3 = signextend.ar_i64.part4 = 0;
02311
02312 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_CHAR) {
02313
02314 ar_dblshift(&ptropnd, &sint64, opnd1, opnd1, 128-3);
02315
02316 if (intopnd.ar_i64.part4 & 0x7)
02317
02318 return AR_STAT_UNDEFINED;
02319
02320
02321 ar_dblshift(&intopnd, &sint64, &signextend, &intopnd, 3);
02322 }
02323 else if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_WORD) {
02324 ptropnd = *opnd1;
02325
02326 if (intopnd.ar_i64.part4 & 0x3f)
02327
02328 return AR_STAT_UNDEFINED;
02329
02330
02331 ar_dblshift(&intopnd, &sint64, &signextend, &intopnd, 6);
02332 }
02333 else {
02334 ptropnd = *opnd1;
02335
02336 if (intopnd.ar_i64.part4 & 0x7)
02337
02338 return AR_STAT_UNDEFINED;
02339
02340
02341 ar_dblshift(&intopnd, &sint64, &signextend, &intopnd, 3);
02342 }
02343
02344 status |= ar_add_integer(result, &sint64, &ptropnd, &sint64,
02345 &intopnd, &sint64);
02346
02347 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_CHAR) {
02348
02349 ar_dblshift (result, &sint64, result, result, 3);
02350 }
02351 else if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_WORD) {
02352 if ((AR_POINTER_SIZE (*opnd1type) == AR_POINTER_64) &&
02353 (result->ar_i64.part1 & 0xff00) != 0)
02354 status |= AR_STAT_OVERFLOW;
02355 else if ((AR_POINTER_SIZE (*opnd1type) == AR_POINTER_32) &&
02356 (result->ar_i64.part1 != 0 ||
02357 result->ar_i64.part2 != 0))
02358 status |= AR_STAT_OVERFLOW;
02359 else if ((AR_POINTER_SIZE (*opnd1type) == AR_POINTER_24) &&
02360 (result->ar_i64.part1 != 0 ||
02361 result->ar_i64.part2 != 0 ||
02362 (result->ar_i64.part3 & 0xff00) != 0))
02363 status |= AR_STAT_OVERFLOW;
02364 }
02365
02366 ar_clear_unused_bits (result, resulttype);
02367 status = (status & AR_STAT_OVERFLOW) | AR_status((AR_DATA*)result, resulttype);
02368
02369 return status;
02370 }
02371
02372
02373
02374 int
02375 AR_subtract_ptr_ptr
02376 (AR_DATA *res, const AR_TYPE *resulttype,
02377 const AR_DATA *op1, const AR_TYPE *opnd1type,
02378 const AR_DATA *op2, const AR_TYPE *opnd2type,
02379 const AR_DATA *op3, const AR_TYPE *opnd3type) {
02380
02381 ar_data* result = (ar_data*)res;
02382 ar_data* opnd1 = (ar_data*)op1;
02383 ar_data* opnd2 = (ar_data*)op2;
02384 ar_data* opnd3 = (ar_data*)op3;
02385
02386 ar_data ptr1opnd, ptr2opnd, sizeopnd, modresult;
02387 AR_TYPE sint64 = AR_Int_64_S;
02388 int status;
02389
02390 if (*opnd1type != *opnd3type ||
02391 AR_CLASS (*opnd1type) != AR_CLASS_POINTER ||
02392 AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_FCTN)
02393 return AR_STAT_INVALID_TYPE;
02394
02395 if (AR_CLASS (*opnd2type) != AR_CLASS_INT ||
02396 AR_CLASS (*resulttype) != AR_CLASS_INT)
02397 return AR_STAT_INVALID_TYPE;
02398
02399 status = ar_convert_to_integral(&sizeopnd, &sint64, opnd2, opnd2type);
02400
02401
02402 if (status & ~AR_STAT_ZERO)
02403 return AR_STAT_UNDEFINED;
02404
02405 if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_CHAR) {
02406
02407 ar_dblshift(&ptr1opnd, &sint64, opnd1, opnd1, 128-3);
02408 ar_dblshift(&ptr2opnd, &sint64, opnd3, opnd3, 128-3);
02409
02410
02411 if (sizeopnd.ar_i64.part4 & 0x7)
02412 return AR_STAT_UNDEFINED;
02413 }
02414 else if (AR_POINTER_FORMAT (*opnd1type) == AR_POINTER_WORD) {
02415
02416 ar_dblshift(&ptr1opnd, &sint64, (const ar_data*)&AR_const_zero, opnd1, 128-3);
02417 ar_dblshift(&ptr2opnd, &sint64, (const ar_data*)&AR_const_zero, opnd3, 128-3);
02418
02419
02420 if (sizeopnd.ar_i64.part4 & 0x3f)
02421 return AR_STAT_UNDEFINED;
02422 }
02423 else {
02424 ptr1opnd = *opnd1;
02425 ptr2opnd = *opnd3;
02426
02427
02428 if (sizeopnd.ar_i64.part4 & 0x7)
02429 return AR_STAT_UNDEFINED;
02430 }
02431
02432
02433 ar_dblshift(&sizeopnd, &sint64, (const ar_data*)&AR_const_zero, &sizeopnd, 3);
02434
02435 status = ar_subtract_integer(result, &sint64, (int *)0,
02436 &ptr1opnd, &sint64, &ptr2opnd, &sint64);
02437 status &= AR_STAT_OVERFLOW;
02438 status |= ar_divide_integer(result, &sint64, &modresult, &sint64,
02439 result, &sint64, &sizeopnd, &sint64);
02440
02441 if (modresult.ar_i64.part1 | modresult.ar_i64.part2 |
02442 modresult.ar_i64.part3 | modresult.ar_i64.part4) {
02443 status |= AR_STAT_INEXACT;
02444 }
02445
02446 return status;
02447 }
02448
02449
02450 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";
02451 static char rcsid [] = "$Id: math.c,v 1.1.1.1 2002-05-22 20:06:19 dsystem Exp $";