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;