int ar_convert_to_integral (ar_data *result, const AR_TYPE *resulttype, const ar_data *opnd, const AR_TYPE *opndtype) { int status = AR_STAT_OK; int maxnegint; int rsltsz, opndsz; if (AR_CLASS (*opndtype) == AR_CLASS_FLOAT) { switch (*opndtype) { case AR_Float_Cray1_64: case AR_Float_Cray1_64_F: status = ar_cfix64 (&result->ar_i64, &opnd->ar_f64, 64); break; case AR_Float_Cray1_128: status = ar_cfix128 (&result->ar_i64, &opnd->ar_f128, 64); break; case AR_Float_IEEE_NR_32: case AR_Float_IEEE_ZE_32: case AR_Float_IEEE_UP_32: case AR_Float_IEEE_DN_32: status = ar_ifix32 (&result->ar_i64, &opnd->ar_ieee32, 64, ROUND_MODE (*opndtype)); break; case AR_Float_IEEE_NR_64: case AR_Float_IEEE_ZE_64: case AR_Float_IEEE_UP_64: case AR_Float_IEEE_DN_64: status = ar_ifix64 (&result->ar_i64, &opnd->ar_ieee64, 64, ROUND_MODE (*opndtype)); break; case AR_Float_IEEE_NR_128: case AR_Float_IEEE_ZE_128: case AR_Float_IEEE_UP_128: case AR_Float_IEEE_DN_128: status = ar_ifix128 (&result->ar_i64, &opnd->ar_ieee128, 64, ROUND_MODE (*opndtype)); break; case AR_Complex_Cray1_64: case AR_Complex_Cray1_64_F: status = ar_cfix64 (&result->ar_i64, &opnd->ar_cplx_f64.real, 64); break; case AR_Complex_Cray1_128: status = ar_cfix128 (&result->ar_i64, &opnd->ar_cplx_f128.real, 64); break; case AR_Complex_IEEE_NR_32: case AR_Complex_IEEE_ZE_32: case AR_Complex_IEEE_UP_32: case AR_Complex_IEEE_DN_32: { AR_IEEE_32 realpart; CPLX32_REAL_TO_IEEE32(realpart, opnd->ar_cplx_ieee32); status = ar_ifix32 (&result->ar_i64, &realpart, 64, ROUND_MODE (*opndtype)); break; } case AR_Complex_IEEE_NR_64: case AR_Complex_IEEE_ZE_64: case AR_Complex_IEEE_UP_64: case AR_Complex_IEEE_DN_64: status = ar_ifix64 (&result->ar_i64, &opnd->ar_cplx_ieee64.real, 64, ROUND_MODE (*opndtype)); break; case AR_Complex_IEEE_NR_128: case AR_Complex_IEEE_ZE_128: case AR_Complex_IEEE_UP_128: case AR_Complex_IEEE_DN_128: status = ar_ifix128(&result->ar_i64, &opnd->ar_cplx_ieee128.real, 64, ROUND_MODE (*opndtype)); break; default: return AR_STAT_INVALID_TYPE; } } else if (AR_CLASS (*opndtype) == AR_CLASS_POINTER) { result->ar_i64 = opnd->ar_i64; } else if (AR_CLASS (*opndtype) == AR_CLASS_INT) { if (*opndtype != AR_Int_8_S && *resulttype == AR_Int_8_S) { result->ar_i8.part1 = opnd->ar_i64.part1; result->ar_i8.part2 = opnd->ar_i64.part2; result->ar_i8.part3 = opnd->ar_i64.part3; result->ar_i8.part4 = opnd->ar_i64.part4 >> 8; result->ar_i8.part5 = opnd->ar_i64.part4; } else if (*opndtype == AR_Int_8_S && *resulttype != AR_Int_8_S) {
int ar_convert_to_integral (ar_data *result, const AR_TYPE *resulttype, const ar_data *opnd, const AR_TYPE *opndtype) { int status = AR_STAT_OK; int maxnegint; int rsltsz, opndsz; if (AR_CLASS (*opndtype) == AR_CLASS_FLOAT) { switch (*opndtype) { case AR_Float_Cray1_64: case AR_Float_Cray1_64_F: status = ar_cfix64 (&result->ar_i64, &opnd->ar_f64, 64); break; case AR_Float_Cray1_128: status = ar_cfix128 (&result->ar_i64, &opnd->ar_f128, 64); break; case AR_Float_IEEE_NR_32: case AR_Float_IEEE_ZE_32: case AR_Float_IEEE_UP_32: case AR_Float_IEEE_DN_32: status = ar_ifix32 (&result->ar_i64, &opnd->ar_ieee32, 64, ROUND_MODE (*opndtype)); break; case AR_Float_IEEE_NR_64: case AR_Float_IEEE_ZE_64: case AR_Float_IEEE_UP_64: case AR_Float_IEEE_DN_64: status = ar_ifix64 (&result->ar_i64, &opnd->ar_ieee64, 64, ROUND_MODE (*opndtype)); break; case AR_Float_IEEE_NR_128: case AR_Float_IEEE_ZE_128: case AR_Float_IEEE_UP_128: case AR_Float_IEEE_DN_128: status = ar_ifix128 (&result->ar_i64, &opnd->ar_ieee128, 64, ROUND_MODE (*opndtype)); break; case AR_Complex_Cray1_64: case AR_Complex_Cray1_64_F: status = ar_cfix64 (&result->ar_i64, &opnd->ar_cplx_f64.real, 64); break; case AR_Complex_Cray1_128: status = ar_cfix128 (&result->ar_i64, &opnd->ar_cplx_f128.real, 64); break; case AR_Complex_IEEE_NR_32: case AR_Complex_IEEE_ZE_32: case AR_Complex_IEEE_UP_32: case AR_Complex_IEEE_DN_32: { AR_IEEE_32 realpart; CPLX32_REAL_TO_IEEE32(realpart, opnd->ar_cplx_ieee32); status = ar_ifix32 (&result->ar_i64, &realpart, 64, ROUND_MODE (*opndtype)); break; } case AR_Complex_IEEE_NR_64: case AR_Complex_IEEE_ZE_64: case AR_Complex_IEEE_UP_64: case AR_Complex_IEEE_DN_64: status = ar_ifix64 (&result->ar_i64, &opnd->ar_cplx_ieee64.real, 64, ROUND_MODE (*opndtype)); break; case AR_Complex_IEEE_NR_128: case AR_Complex_IEEE_ZE_128: case AR_Complex_IEEE_UP_128: case AR_Complex_IEEE_DN_128: status = ar_ifix128(&result->ar_i64, &opnd->ar_cplx_ieee128.real, 64, ROUND_MODE (*opndtype)); break; default: return AR_STAT_INVALID_TYPE; } } else if (AR_CLASS (*opndtype) == AR_CLASS_POINTER) { result->ar_i64 = opnd->ar_i64; } else if (AR_CLASS (*opndtype) == AR_CLASS_INT) { result->ar_i64 = opnd->ar_i64; opndsz = AR_INT_SIZE(*opndtype); if(opndsz == AR_INT_SIZE_46) opndsz = AR_INT_SIZE_64; rsltsz = AR_INT_SIZE(*resulttype); if(rsltsz == AR_INT_SIZE_46) rsltsz = AR_INT_SIZE_64; if (AR_SIGNEDNESS (*opndtype) == AR_SIGNED) { /* operand is signed; sign extend to 64-bit int */ if (opndsz == AR_INT_SIZE_8 && INT8_SIGN(opnd)) { /* 8-bit operand is negative; extend the sign */ maxnegint = IS_INT8_UPPER_ZERO(opnd) && (opnd->ar_i8.part5 == 0x80); result->ar_i8.part1 = 0xFFFF; result->ar_i8.part2 = 0xFFFF; result->ar_i8.part3 = 0xFFFF; result->ar_i8.part4 = 0xFF; } else if (opndsz == AR_INT_SIZE_16 && INT16_SIGN(opnd)) { maxnegint = IS_INT16_UPPER_ZERO(opnd) && (opnd->ar_i64.part4 == 0x8000); /* 16-bit operand is negative; extend the sign*/ result->ar_i64.part1 = 0xFFFF; result->ar_i64.part2 = 0xFFFF; result->ar_i64.part3 = 0xFFFF; } else if (opndsz == AR_INT_SIZE_24 && INT24_SIGN(opnd)) { maxnegint = IS_INT24_UPPER_ZERO(opnd) && (opnd->ar_i64.part3 == 0x80) && (opnd->ar_i64.part4 == 0x0); /* 24-bit operand is negative; extend the sign*/ result->ar_i64.part1 = 0xFFFF; result->ar_i64.part2 = 0xFFFF; result->ar_i64.part3 |= 0xFF00; } else if (opndsz == AR_INT_SIZE_32 && INT32_SIGN(opnd)) { maxnegint = IS_INT32_UPPER_ZERO(opnd) && (opnd->ar_i64.part3 == 0x8000) && (opnd->ar_i64.part4 == 0); /* 32-bit operand is negative; extend the sign*/ result->ar_i64.part1 = 0xFFFF; result->ar_i64.part2 = 0xFFFF; } else maxnegint = (opnd->ar_i64.part1 == 0x8000) && (opnd->ar_i64.part2 == 0) && (opnd->ar_i64.part3 == 0) && (opnd->ar_i64.part4 == 0); if ((result->ar_i64.part1 & 0x8000) && (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED)) { /* operand is negative and result is unsigned; original value cannot be preserved */ if(opndsz == rsltsz) status |= AR_STAT_SEMIVALID; if(opndsz != rsltsz || !maxnegint) status |= AR_STAT_OVERFLOW; } } else if (AR_SIGNEDNESS(*resulttype) == AR_SIGNED && rsltsz == opndsz) { /* operand is unsigned, same size result is signed */ switch (AR_INT_SIZE (*opndtype)) { case AR_INT_SIZE_8: if (INT8_SIGN(opnd)) { status |= AR_STAT_SEMIVALID; if(opnd->ar_i8.part5 != 0x80) status |= AR_STAT_OVERFLOW; } break; case AR_INT_SIZE_16: if (INT16_SIGN(opnd)) { status |= AR_STAT_SEMIVALID; if(opnd->ar_i64.part4 != 0x8000) status |= AR_STAT_OVERFLOW; } break; case AR_INT_SIZE_24: if (INT24_SIGN(opnd)) { status |= AR_STAT_SEMIVALID; if(opnd->ar_i64.part3 != 0x80 || opnd->ar_i64.part4 != 0) status |= AR_STAT_OVERFLOW; } break; case AR_INT_SIZE_32: if (INT32_SIGN(opnd)) { status |= AR_STAT_SEMIVALID; if(opnd->ar_i64.part3 != 0x8000 || opnd->ar_i64.part4 != 0) status |= AR_STAT_OVERFLOW; } break; case AR_INT_SIZE_46: case AR_INT_SIZE_64: if(INT64_SIGN(opnd)) { status |= AR_STAT_SEMIVALID; if(opnd->ar_i64.part1 != 0x8000 || opnd->ar_i64.part2 != 0 || opnd->ar_i64.part3 != 0 || opnd->ar_i64.part4 != 0) status |= AR_STAT_OVERFLOW; } break; default: return (AR_STAT_INVALID_TYPE); } if(status & (AR_STAT_SEMIVALID | AR_STAT_OVERFLOW)) status |= AR_STAT_NEGATIVE; } else { /* operand is unsigned and result is different size */ if (INT64_SIGN(result) && (AR_SIGNEDNESS(*resulttype) == AR_SIGNED)) { /* result is negative; we have overflow */ status |= AR_STAT_OVERFLOW; } } } else return AR_STAT_INVALID_TYPE; /* At this point, regardless of the original operand type, we've converted it to a 64-bit int. Now, check for overflow, negative. */ if(!(status & AR_STAT_SEMIVALID)) switch (*resulttype) { case AR_Int_8_S: if (!(result->ar_i8.part1 == 0xffff && result->ar_i8.part2 == 0xffff && result->ar_i8.part3 == 0xffff && result->ar_i8.part4 == 0xff && INT8_SIGN(result) == 0x80)&& !(IS_INT8_UPPER_ZERO(result) && INT8_SIGN(result) == 0)) { status |= AR_STAT_OVERFLOW; } if (INT8_SIGN(result)) status |= AR_STAT_NEGATIVE; break; case AR_Int_8_U: if (!IS_INT8_UPPER_ZERO(result)) { status |= AR_STAT_OVERFLOW; } break; case AR_Int_16_S: if (!(result->ar_i64.part1 == 0xffff && result->ar_i64.part2 == 0xffff && result->ar_i64.part3 == 0xffff && INT16_SIGN(result) == 0x8000)&& !(IS_INT16_UPPER_ZERO(result) && INT16_SIGN(result) == 0)) { status |= AR_STAT_OVERFLOW; } if (INT16_SIGN(result)) status |= AR_STAT_NEGATIVE; break; case AR_Int_16_U: if (!IS_INT16_UPPER_ZERO(result)) { status |= AR_STAT_OVERFLOW; } break; case AR_Int_24_S: if (!(result->ar_i64.part1 == 0xffff && result->ar_i64.part2 == 0xffff && (result->ar_i64.part3&0xff00) == 0xff00 && INT24_SIGN(result) == 0x0080)&& !(IS_INT24_UPPER_ZERO(result) && INT24_SIGN(result) == 0)) { status |= AR_STAT_OVERFLOW; } if (INT24_SIGN(result)) status |= AR_STAT_NEGATIVE; break; case AR_Int_24_U: if (!IS_INT24_UPPER_ZERO(result)) { status |= AR_STAT_OVERFLOW; } break; case AR_Int_32_S: if (!(result->ar_i64.part1 == 0xffff && result->ar_i64.part2 == 0xffff && INT32_SIGN(result) == 0x8000)&& !(IS_INT32_UPPER_ZERO(result) && INT32_SIGN(result) == 0)) { status |= AR_STAT_OVERFLOW; } if (INT32_SIGN(result)) status |= AR_STAT_NEGATIVE; break; case AR_Int_32_U: if (!IS_INT32_UPPER_ZERO(result)) { status |= AR_STAT_OVERFLOW; } break; case AR_Int_46_S: if (INT_OVERFLOWS_46_BITS(*result)) status |= AR_STAT_OVERFLOW; if (INT64_SIGN(result)) status |= AR_STAT_NEGATIVE; break; case AR_Int_64_S: if (INT64_SIGN(result)) status |= AR_STAT_NEGATIVE; break; } ar_clear_unused_bits(result, resulttype); if (IS_INT64_ZERO(result)) status |= AR_STAT_ZERO; return status; }