2011-11-06 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / ada / g-bytswa-x86.adb
blobcc47b7298353f4b6ee7d8b50e64d77cb643c8ba8
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- G N A T . B Y T E _ S W A P P I N G --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2006-2010, AdaCore --
10 -- --
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. --
17 -- --
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. --
21 -- --
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/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
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);
48 --------------
49 -- Swapped2 --
50 --------------
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);
62 begin
63 Asm ("xchgb %b0,%h0",
64 Unsigned_16'Asm_Output ("=q", X),
65 Unsigned_16'Asm_Input ("0", X));
66 return As_Item (X);
67 end Swapped2;
69 --------------
70 -- Swapped4 --
71 --------------
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);
83 begin
84 Asm ("bswap %0",
85 Unsigned_32'Asm_Output ("=r", X),
86 Unsigned_32'Asm_Input ("0", X));
87 return As_Item (X);
88 end Swapped4;
90 --------------
91 -- Swapped8 --
92 --------------
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);
107 Result : Two_Words;
109 begin
110 Asm ("xchgl %0,%1",
111 Outputs =>
112 (Unsigned_32'Asm_Output ("=r", Result (0)),
113 Unsigned_32'Asm_Output ("=r", Result (1))),
114 Inputs =>
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);
120 end Swapped8;
122 -----------
123 -- Swap2 --
124 -----------
126 procedure Swap2 (Location : System.Address) is
128 X : Unsigned_16;
129 for X'Address use Location;
131 begin
132 Asm ("xchgb %b0,%h0",
133 Unsigned_16'Asm_Output ("=q", X),
134 Unsigned_16'Asm_Input ("0", X));
135 end Swap2;
137 -----------
138 -- Swap4 --
139 -----------
141 procedure Swap4 (Location : System.Address) is
143 X : Unsigned_32;
144 for X'Address use Location;
146 begin
147 Asm ("bswap %0",
148 Unsigned_32'Asm_Output ("=r", X),
149 Unsigned_32'Asm_Input ("0", X));
150 end Swap4;
152 ---------------
153 -- Swapped32 --
154 ---------------
156 function Swapped32 (Value : Unsigned_32) return Unsigned_32 is
157 X : Unsigned_32 := Value;
158 begin
159 Asm ("bswap %0",
160 Unsigned_32'Asm_Output ("=r", X),
161 Unsigned_32'Asm_Input ("0", X));
162 return X;
163 end Swapped32;
165 -----------
166 -- Swap8 --
167 -----------
169 procedure Swap8 (Location : System.Address) is
171 X : Unsigned_64;
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;
177 Words : Two_Words;
178 for Words'Address use Location;
180 begin
181 Asm ("xchgl %0,%1",
182 Outputs =>
183 (Unsigned_32'Asm_Output ("=r", Words (0)),
184 Unsigned_32'Asm_Output ("=r", Words (1))),
185 Inputs =>
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))))));
190 end Swap8;
192 end GNAT.Byte_Swapping;