poke-devel
[Top][All Lists]
Advanced

[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?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]