comp.lang.ada
 help / color / mirror / Atom feed
* Byte Swapping
@ 2016-12-02 16:23 Jeffrey R. Carter
  2016-12-02 19:28 ` Randy Brukardt
  0 siblings, 1 reply; 2+ messages in thread
From: Jeffrey R. Carter @ 2016-12-02 16:23 UTC (permalink / raw)


Recently on Ada-Comment there was a discussion of a GNAT aspect that changes the 
byte order of scalars. Brukardt said, "In the past, we have not be willing to 
require compilers to be able to generate byte swapping code." However, I think 
the standard has required compilers to generate byte-swapping code since Ada 83.

On a little-endian, twos-complement, byte-addressable machine, such as x86, we 
could say

Byte_Size : constant := 8;
Word_Size : constant := 2 * Byte_Size;

type Byte is range -(2 ** (Byte_Size - 1) ) .. 2 ** (Byte_Size - 1) - 1;
for Byte'Size use Byte_Size;
type Word is range -(2 ** (Word_Size - 1) ) .. 2 ** (Word_Size - 1) - 1;
for Word'Size use Word_Size;
-- Signed types for Ada-83 compatibility

type Unswapped_Bytes is record
    MSB : Byte;
    LSB : Byte;
end record;

for Unswapped_Bytes use record
    MSB at 1 range 0 .. 7;
    LSB at 0 range 0 .. 7;
end record;
for Unswapped_Bytes'Size use Word_Size;
-- Default LE byte order: LSB at offset 0, MSB at offset 1

type Swapped_Bytes is new Unswapped_Bytes;

for Swapped_Bytes use record
    MSB at 0 range 0 .. 7;
    LSB at 1 range 0 .. 7;
end record;
for Swapped_Bytes'Size use Word_Size;
-- BE byte order: MSB at offset 0, LSB at offset 1

IIUC, type conversion between these two record types performs byte swapping. So, 
with

function To_Unswapped is new Unchecked_Conversion
    (Source => Word, Target => Unswapped_Bytes);
function To_Word is new Unchecked_Conversion
    (Source => Swapped_Bytes, Target => Word);

W : Word;

To_Word (Swapped_Bytes (To_Unswapped (W) ) )

produces a Word with the bytes of W swapped. Barring any errors I've injected, 
this should be valid Ada 83 and all later version of the language.

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Byte Swapping
  2016-12-02 16:23 Byte Swapping Jeffrey R. Carter
@ 2016-12-02 19:28 ` Randy Brukardt
  0 siblings, 0 replies; 2+ messages in thread
From: Randy Brukardt @ 2016-12-02 19:28 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:o1s73q$qmg$1@dont-email.me...
> Recently on Ada-Comment there was a discussion of a GNAT aspect that 
> changes the byte order of scalars. Brukardt said, "In the past, we have 
> not be willing to require compilers to be able to generate byte swapping 
> code." However, I think the standard has required compilers to generate 
> byte-swapping code since Ada 83.
>
> On a little-endian, twos-complement, byte-addressable machine, such as 
> x86, we could say
>
> Byte_Size : constant := 8;
> Word_Size : constant := 2 * Byte_Size;
>
> type Byte is range -(2 ** (Byte_Size - 1) ) .. 2 ** (Byte_Size - 1) - 1;
> for Byte'Size use Byte_Size;
> type Word is range -(2 ** (Word_Size - 1) ) .. 2 ** (Word_Size - 1) - 1;
> for Word'Size use Word_Size;
> -- Signed types for Ada-83 compatibility
>
> type Unswapped_Bytes is record
>    MSB : Byte;
>    LSB : Byte;
> end record;
>
> for Unswapped_Bytes use record
>    MSB at 1 range 0 .. 7;
>    LSB at 0 range 0 .. 7;
> end record;
> for Unswapped_Bytes'Size use Word_Size;
> -- Default LE byte order: LSB at offset 0, MSB at offset 1
>
> type Swapped_Bytes is new Unswapped_Bytes;
>
> for Swapped_Bytes use record
>    MSB at 0 range 0 .. 7;
>    LSB at 1 range 0 .. 7;
> end record;
> for Swapped_Bytes'Size use Word_Size;
> -- BE byte order: MSB at offset 0, LSB at offset 1
>
> IIUC, type conversion between these two record types performs byte 
> swapping. So, with
>
> function To_Unswapped is new Unchecked_Conversion
>    (Source => Word, Target => Unswapped_Bytes);
> function To_Word is new Unchecked_Conversion
>    (Source => Swapped_Bytes, Target => Word);
>
> W : Word;
>
> To_Word (Swapped_Bytes (To_Unswapped (W) ) )
>
> produces a Word with the bytes of W swapped. Barring any errors I've 
> injected, this should be valid Ada 83 and all later version of the 
> language.

Sure, but that's typcially implemented by doing a component-by-component 
assignment into a temporary (and the rep. clause is illegal for any 
by-reference type). That code is very slow, but that's OK because type 
conversions like this are rare in the language and occur rarely even when 
they are used.

The suggested aspect would require the compiler to be able to generate byte 
swapping code for a component reference. While that wouldn't be commonly 
used, when it is used, the code would have to be as efficient as possible as 
it would probably occur a lot. So the degree of effort is quite different.

To put it another way, a value type conversion "feels" expensive (one tries 
to avoid them), while a component access "feels" cheap (one does not try to 
avoid them), and the generated code needs to reflect that.

This is the crux of my (mild) objection to this idea: it makes component 
access for some record types quite expensive, and I doubt that most users 
would want to pay that cost regularly. The proper way to deal with data in 
the wrong byte-sex is to swap it as soon as possible and then process it in 
the native byte-sex. That means that the programmer has to be aware of it; 
trying to make a truly machine-independent format is somewhat of a mistake, 
as the code would be very slow on some targets. Don't see how that helps 
anything.

                                            Randy.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-12-02 19:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-02 16:23 Byte Swapping Jeffrey R. Carter
2016-12-02 19:28 ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox