1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- G N A T . B Y T E _ S W A P P I N G --
9 -- Copyright (C) 2006-2010, AdaCore --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- This is a machine-specific version of this package.
33 -- It uses instructions available on Intel 486 processors (or later).
35 with Interfaces
; use Interfaces
;
36 with System
.Machine_Code
; use System
.Machine_Code
;
37 with Ada
.Unchecked_Conversion
;
39 package body GNAT
.Byte_Swapping
is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
45 function Swapped32
(Value
: Unsigned_32
) return Unsigned_32
;
46 pragma Inline_Always
(Swapped32
);
52 function Swapped2
(Input
: Item
) return Item
is
54 function As_U16
is new Ada
.Unchecked_Conversion
55 (Source
=> Item
, Target
=> Unsigned_16
);
57 function As_Item
is new Ada
.Unchecked_Conversion
58 (Source
=> Unsigned_16
, Target
=> Item
);
60 X
: Unsigned_16
:= As_U16
(Input
);
64 Unsigned_16
'Asm_Output ("=q", X
),
65 Unsigned_16
'Asm_Input ("0", X
));
73 function Swapped4
(Input
: Item
) return Item
is
75 function As_U32
is new Ada
.Unchecked_Conversion
76 (Source
=> Item
, Target
=> Unsigned_32
);
78 function As_Item
is new Ada
.Unchecked_Conversion
79 (Source
=> Unsigned_32
, Target
=> Item
);
81 X
: Unsigned_32
:= As_U32
(Input
);
85 Unsigned_32
'Asm_Output ("=r", X
),
86 Unsigned_32
'Asm_Input ("0", X
));
94 function Swapped8
(Input
: Item
) return Item
is
96 function As_U64
is new Ada
.Unchecked_Conversion
97 (Source
=> Item
, Target
=> Unsigned_64
);
99 X
: constant Unsigned_64
:= As_U64
(Input
);
101 type Two_Words
is array (0 .. 1) of Unsigned_32
;
102 for Two_Words
'Component_Size use Unsigned_32
'Size;
104 function As_Item
is new Ada
.Unchecked_Conversion
105 (Source
=> Two_Words
, Target
=> Item
);
112 (Unsigned_32
'Asm_Output ("=r", Result
(0)),
113 Unsigned_32
'Asm_Output ("=r", Result
(1))),
115 (Unsigned_32
'Asm_Input ("0",
116 Swapped32
(Unsigned_32
(X
and 16#
0000_0000_FFFF_FFFF#
))),
117 Unsigned_32
'Asm_Input ("1",
118 Swapped32
(Unsigned_32
(Shift_Right
(X
, 32))))));
119 return As_Item
(Result
);
126 procedure Swap2
(Location
: System
.Address
) is
129 for X
'Address use Location
;
132 Asm
("xchgb %b0,%h0",
133 Unsigned_16
'Asm_Output ("=q", X
),
134 Unsigned_16
'Asm_Input ("0", X
));
141 procedure Swap4
(Location
: System
.Address
) is
144 for X
'Address use Location
;
148 Unsigned_32
'Asm_Output ("=r", X
),
149 Unsigned_32
'Asm_Input ("0", X
));
156 function Swapped32
(Value
: Unsigned_32
) return Unsigned_32
is
157 X
: Unsigned_32
:= Value
;
160 Unsigned_32
'Asm_Output ("=r", X
),
161 Unsigned_32
'Asm_Input ("0", X
));
169 procedure Swap8
(Location
: System
.Address
) is
172 for X
'Address use Location
;
174 type Two_Words
is array (0 .. 1) of Unsigned_32
;
175 for Two_Words
'Component_Size use Unsigned_32
'Size;
178 for Words
'Address use Location
;
183 (Unsigned_32
'Asm_Output ("=r", Words
(0)),
184 Unsigned_32
'Asm_Output ("=r", Words
(1))),
186 (Unsigned_32
'Asm_Input ("0",
187 Swapped32
(Unsigned_32
(X
and 16#
0000_0000_FFFF_FFFF#
))),
188 Unsigned_32
'Asm_Input ("1",
189 Swapped32
(Unsigned_32
(Shift_Right
(X
, 32))))));
192 end GNAT
.Byte_Swapping
;