X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdfp.c;h=90ca2a2a4f2926f3ced3598af446fecd0babb6f8;hb=220efacb0728f20f4b70122089cc5ce27f7f1bcd;hp=88ffdedbcfb41baf5272a9a3616801e495ff070f;hpb=c8ac5d9a0464767d7091606c4d55aaaf8edc511a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dfp.c b/gcc/dfp.c index 88ffdedbcfb..90ca2a2a4f2 100644 --- a/gcc/dfp.c +++ b/gcc/dfp.c @@ -1,5 +1,6 @@ /* Decimal floating point support. - Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software + Foundation, Inc. This file is part of GCC. @@ -36,6 +37,10 @@ along with GCC; see the file COPYING3. If not see #include "decimal32.h" #include "decNumber.h" +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN 0 +#endif + /* Initialize R (a real with the decimal flag set) from DN. Can utilize status passed in via CONTEXT, if a previous operation had interesting status. */ @@ -46,8 +51,6 @@ decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context) memset (r, 0, sizeof (REAL_VALUE_TYPE)); r->cl = rvc_normal; - if (decNumberIsZero (dn)) - r->cl = rvc_zero; if (decNumberIsNaN (dn)) r->cl = rvc_nan; if (decNumberIsInfinite (dn)) @@ -121,7 +124,7 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn) dn->bits ^= DECNEG; } -/* Encode a real into an IEEE 754R decimal32 type. */ +/* Encode a real into an IEEE 754 decimal32 type. */ void encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, @@ -130,17 +133,19 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, decNumber dn; decimal32 d32; decContext set; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; - decimal_to_decnumber (r, &dn); + decimal_to_decnumber (r, &dn); decimal32FromNumber (&d32, &dn, &set); - buf[0] = *(uint32_t *) d32.bytes; + memcpy (&image, d32.bytes, sizeof (int32_t)); + buf[0] = image; } -/* Decode an IEEE 754R decimal32 type into a real. */ +/* Decode an IEEE 754 decimal32 type into a real. */ void decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, @@ -149,17 +154,19 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, decNumber dn; decimal32 d32; decContext set; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; - *((uint32_t *) d32.bytes) = (uint32_t) buf[0]; + image = buf[0]; + memcpy (&d32.bytes, &image, sizeof (int32_t)); decimal32ToNumber (&d32, &dn); - decimal_from_decnumber (r, &dn, &set); + decimal_from_decnumber (r, &dn, &set); } -/* Encode a real into an IEEE 754R decimal64 type. */ +/* Encode a real into an IEEE 754 decimal64 type. */ void encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, @@ -168,6 +175,7 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, decNumber dn; decimal64 d64; decContext set; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; @@ -175,31 +183,56 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, decimal_to_decnumber (r, &dn); decimal64FromNumber (&d64, &dn, &set); - buf[0] = *(uint32_t *) &d64.bytes[0]; - buf[1] = *(uint32_t *) &d64.bytes[4]; + if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) + { + memcpy (&image, &d64.bytes[0], sizeof (int32_t)); + buf[0] = image; + memcpy (&image, &d64.bytes[4], sizeof (int32_t)); + buf[1] = image; + } + else + { + memcpy (&image, &d64.bytes[4], sizeof (int32_t)); + buf[0] = image; + memcpy (&image, &d64.bytes[0], sizeof (int32_t)); + buf[1] = image; + } } -/* Decode an IEEE 754R decimal64 type into a real. */ +/* Decode an IEEE 754 decimal64 type into a real. */ void decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, REAL_VALUE_TYPE *r, const long *buf) -{ +{ decNumber dn; decimal64 d64; decContext set; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; - *((uint32_t *) &d64.bytes[0]) = (uint32_t) buf[0]; - *((uint32_t *) &d64.bytes[4]) = (uint32_t) buf[1]; + if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) + { + image = buf[0]; + memcpy (&d64.bytes[0], &image, sizeof (int32_t)); + image = buf[1]; + memcpy (&d64.bytes[4], &image, sizeof (int32_t)); + } + else + { + image = buf[1]; + memcpy (&d64.bytes[0], &image, sizeof (int32_t)); + image = buf[0]; + memcpy (&d64.bytes[4], &image, sizeof (int32_t)); + } decimal64ToNumber (&d64, &dn); - decimal_from_decnumber (r, &dn, &set); + decimal_from_decnumber (r, &dn, &set); } -/* Encode a real into an IEEE 754R decimal128 type. */ +/* Encode a real into an IEEE 754 decimal128 type. */ void encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, @@ -208,6 +241,7 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, decNumber dn; decContext set; decimal128 d128; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; @@ -215,13 +249,31 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, decimal_to_decnumber (r, &dn); decimal128FromNumber (&d128, &dn, &set); - buf[0] = *(uint32_t *) &d128.bytes[0]; - buf[1] = *(uint32_t *) &d128.bytes[4]; - buf[2] = *(uint32_t *) &d128.bytes[8]; - buf[3] = *(uint32_t *) &d128.bytes[12]; + if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) + { + memcpy (&image, &d128.bytes[0], sizeof (int32_t)); + buf[0] = image; + memcpy (&image, &d128.bytes[4], sizeof (int32_t)); + buf[1] = image; + memcpy (&image, &d128.bytes[8], sizeof (int32_t)); + buf[2] = image; + memcpy (&image, &d128.bytes[12], sizeof (int32_t)); + buf[3] = image; + } + else + { + memcpy (&image, &d128.bytes[12], sizeof (int32_t)); + buf[0] = image; + memcpy (&image, &d128.bytes[8], sizeof (int32_t)); + buf[1] = image; + memcpy (&image, &d128.bytes[4], sizeof (int32_t)); + buf[2] = image; + memcpy (&image, &d128.bytes[0], sizeof (int32_t)); + buf[3] = image; + } } -/* Decode an IEEE 754R decimal128 type into a real. */ +/* Decode an IEEE 754 decimal128 type into a real. */ void decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, @@ -230,17 +282,36 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, decNumber dn; decimal128 d128; decContext set; + int32_t image; decContextDefault (&set, DEC_INIT_DECIMAL128); set.traps = 0; - *((uint32_t *) &d128.bytes[0]) = (uint32_t) buf[0]; - *((uint32_t *) &d128.bytes[4]) = (uint32_t) buf[1]; - *((uint32_t *) &d128.bytes[8]) = (uint32_t) buf[2]; - *((uint32_t *) &d128.bytes[12]) = (uint32_t) buf[3]; + if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN) + { + image = buf[0]; + memcpy (&d128.bytes[0], &image, sizeof (int32_t)); + image = buf[1]; + memcpy (&d128.bytes[4], &image, sizeof (int32_t)); + image = buf[2]; + memcpy (&d128.bytes[8], &image, sizeof (int32_t)); + image = buf[3]; + memcpy (&d128.bytes[12], &image, sizeof (int32_t)); + } + else + { + image = buf[3]; + memcpy (&d128.bytes[0], &image, sizeof (int32_t)); + image = buf[2]; + memcpy (&d128.bytes[4], &image, sizeof (int32_t)); + image = buf[1]; + memcpy (&d128.bytes[8], &image, sizeof (int32_t)); + image = buf[0]; + memcpy (&d128.bytes[12], &image, sizeof (int32_t)); + } decimal128ToNumber (&d128, &dn); - decimal_from_decnumber (r, &dn, &set); + decimal_from_decnumber (r, &dn, &set); } /* Helper function to convert from a binary real internal @@ -294,10 +365,10 @@ decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b, decimal_from_binary (&b1, b); b = &b1; } - + /* Convert into decNumber form for comparison operation. */ decContextDefault (&set, DEC_INIT_DECIMAL128); - set.traps = 0; + set.traps = 0; decimal128ToNumber ((const decimal128 *) a->sig, &dn2); decimal128ToNumber ((const decimal128 *) b->sig, &dn3); @@ -311,7 +382,7 @@ decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b, return 0; else if (decNumberIsNegative (&dn)) return -1; - else + else return 1; } @@ -364,7 +435,7 @@ decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r) binary and decimal types. */ void -decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode, +decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode, const REAL_VALUE_TYPE *a) { const struct real_format *fmt = REAL_MODE_FORMAT (mode); @@ -413,7 +484,7 @@ decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, if (subtract_p) decNumberSubtract (&dn, &dn2, &dn3, &set); - else + else decNumberAdd (&dn, &dn2, &dn3, &set); decimal_from_decnumber (r, &dn, &set); @@ -530,7 +601,7 @@ decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh, decNumberZero (&dn3); decNumberRescale (&dn, &dn2, &dn3, &set); - /* Conver to REAL_VALUE_TYPE and call appropriate conversion + /* Convert to REAL_VALUE_TYPE and call appropriate conversion function. */ decNumberToString (&dn, string); real_from_string (&to, string); @@ -626,7 +697,7 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code, void decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode) -{ +{ const char *max; switch (mode)