Example #1
0
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) {
Example #2
0
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;
}