[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Byte endianess vs Bit endianess
From: |
Jose E. Marchesi |
Subject: |
Re: Byte endianess vs Bit endianess |
Date: |
Mon, 18 Nov 2019 17:10:02 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) |
Hi John.
Further to my discussions with José on IRC ...
Perhaps there needs to be some more powerful way of dealing with
situations where byte-endianess is distinct from bit-endianess. As
José says bit-endianess is (almost) always big endian. That is to
say, that the MSB of a byte appears earlier in memory than the LSB (it
would be an unusual machine which did it the other way around, but who
knows ...)
If the byte-endianess is the same as the bit-endianess (ie big-endian)
there is no problem. However in the little endian case, things get
messy when dealing with bit fields which do not start/end on byte
boundaries.
This raised its ugly head in the context of implementing ieee754
floating point numbers. Consider a C program fragment:
extern FILE *fp
double dp = -100;
fwrite (&dp, sizeof dp, 1, fp);
This writes a double precision floating point number to a file. On a
big-endian machine, it'll appear in the file as:
C059 0000 0000 0000 0000
and this can be easily parsed using the Poke fragment
deftype ieee754_double = struct
{
int<1> sign;
int<11> exponenent;
int<52> fraction;
};
(ieee754_double @ NULL)
Here sign=1 (the MSB of C0), and exponent is 0x405 (the lower 7 bits
of C0 juxtaposed with the upper four bits of 59).
fraction=9 0000 0000 0000 0000
This means, - 1.10010000000000000000 (base2) x 2^6 == -100 base10 --- No
problem.
However, on a little endian machine, the C program above will write:
0000 0000 0000 59c0
Ok this means that the C implementation treats the IEEE number as a
64-bit integral (8 bytes) endianness-wise.
To me it seems like the IOS is doing the right thing: it knows how to
arrange sub-byte integers in the surrounding bytes. Egeyar is right in
that the IOS should only know about the objects it is asked to
read/write. All we have to do in that regard is to document that the
bit-endianness is always big, with examples, in the manual.
So how could we handle cases like this? An option you could use right
now is to use field labels to place the fields at the right offset
depending on the current endianness (get_endian.) Something like:
deftype IEEE754_Double =
struct
{
defun sign_offset = int:
{
if (get_offset == ENDIAN_BIG)
return 0;
else
return WHATEVER;
}
/* Same for the others... */
int<1> sign @ sign_offset;
int<11> exponent @ exponent_offset;
int<52> fraction @ fraction_offset;
};
Yes using defuns is clunky, I really need to add support for a ternary
conditional operator... will do one of these nights.
Another alternative would be to add the ability to define "endianness
groups" in Poke structs:
deftype IEEE754_Double =
struct
{
endian
{
int<52> fraction @ fraction_offset;
int<11> exponent @ exponent_offset;
int<1> sign @ sign_offset;
};
};
That would make the compiler to generate peek/poke instructions assuming
the whole group shall be written as a discrete integral, endian wise.
wdyt?