- int rbo = (byte_order != __FLOAT_WORD_ORDER); /* reverse byte order */
-
- switch (len) {
- case 32:
- {
- union floatIEEE754 u;
- uint32_t tmp;
-
- if (!rbo)
- return (double) *(const float *) ptr;
- /*
- * Need to reverse byte order. Read the opposite from our
- * architecture.
- */
- if (__FLOAT_WORD_ORDER == LITTLE_ENDIAN) {
- /* Read big endian */
- tmp = bitfield_unsigned_read(ptr, 0, 1, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 31, 1, LITTLE_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 1, 8, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 23, 8, LITTLE_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 9, 23, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 0, 23, LITTLE_ENDIAN,
- tmp);
- } else {
- /* Read little endian */
- tmp = bitfield_unsigned_read(ptr, 31, 1, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 0, 1, BIG_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 23, 8, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 1, 8, BIG_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 0, 23, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 9, 23, BIG_ENDIAN,
- tmp);
- }
- return (double) u.v;
- }
- case 64:
- {
- union doubleIEEE754 u;
- uint64_t tmp;
-
- if (!rbo)
- return (double) *(const double *) ptr;
- /*
- * Need to reverse byte order. Read the opposite from our
- * architecture.
- */
- if (__FLOAT_WORD_ORDER == LITTLE_ENDIAN) {
- /* Read big endian */
- tmp = bitfield_unsigned_read(ptr, 0, 1, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 63, 1, LITTLE_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 1, 11, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 52, 11, LITTLE_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 12, 52, BIG_ENDIAN);
- bitfield_unsigned_write(&u.bits, 0, 52, LITTLE_ENDIAN,
- tmp);
- } else {
- /* Read little endian */
- tmp = bitfield_unsigned_read(ptr, 63, 1, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 0, 1, BIG_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 52, 11, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 1, 11, BIG_ENDIAN,
- tmp);
- tmp = bitfield_unsigned_read(ptr, 0, 52, LITTLE_ENDIAN);
- bitfield_unsigned_write(&u.bits, 12, 52, BIG_ENDIAN,
- tmp);
- }
- return u.v;