OSDN Git Service

cc47b7298353f4b6ee7d8b50e64d77cb643c8ba8
[pf3gnuchains/gcc-fork.git] / gcc / ada / g-bytswa-x86.adb
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 ------------------------------------------------------------------------------
31
32 --  This is a machine-specific version of this package.
33 --  It uses instructions available on Intel 486 processors (or later).
34
35 with Interfaces;          use Interfaces;
36 with System.Machine_Code; use System.Machine_Code;
37 with Ada.Unchecked_Conversion;
38
39 package body GNAT.Byte_Swapping is
40
41    -----------------------
42    -- Local Subprograms --
43    -----------------------
44
45    function Swapped32 (Value : Unsigned_32) return Unsigned_32;
46    pragma Inline_Always (Swapped32);
47
48    --------------
49    -- Swapped2 --
50    --------------
51
52    function Swapped2 (Input : Item) return Item is
53
54       function As_U16 is new Ada.Unchecked_Conversion
55          (Source => Item, Target => Unsigned_16);
56
57       function As_Item is new Ada.Unchecked_Conversion
58          (Source => Unsigned_16, Target => Item);
59
60       X : Unsigned_16 := As_U16 (Input);
61
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;
68
69    --------------
70    -- Swapped4 --
71    --------------
72
73    function Swapped4 (Input : Item) return Item is
74
75       function As_U32 is new Ada.Unchecked_Conversion
76          (Source => Item, Target => Unsigned_32);
77
78       function As_Item is new Ada.Unchecked_Conversion
79          (Source => Unsigned_32, Target => Item);
80
81       X : Unsigned_32 := As_U32 (Input);
82
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;
89
90    --------------
91    -- Swapped8 --
92    --------------
93
94    function Swapped8 (Input : Item) return Item is
95
96       function As_U64 is new Ada.Unchecked_Conversion
97          (Source => Item, Target => Unsigned_64);
98
99       X : constant Unsigned_64 := As_U64 (Input);
100
101       type Two_Words is array (0 .. 1) of Unsigned_32;
102       for Two_Words'Component_Size use Unsigned_32'Size;
103
104       function As_Item is new Ada.Unchecked_Conversion
105         (Source => Two_Words, Target => Item);
106
107       Result : Two_Words;
108
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;
121
122    -----------
123    -- Swap2 --
124    -----------
125
126    procedure Swap2 (Location : System.Address) is
127
128       X : Unsigned_16;
129       for X'Address use Location;
130
131    begin
132       Asm ("xchgb %b0,%h0",
133            Unsigned_16'Asm_Output ("=q", X),
134            Unsigned_16'Asm_Input ("0", X));
135    end Swap2;
136
137    -----------
138    -- Swap4 --
139    -----------
140
141    procedure Swap4 (Location : System.Address) is
142
143       X : Unsigned_32;
144       for X'Address use Location;
145
146    begin
147       Asm ("bswap %0",
148            Unsigned_32'Asm_Output ("=r", X),
149            Unsigned_32'Asm_Input ("0", X));
150    end Swap4;
151
152    ---------------
153    -- Swapped32 --
154    ---------------
155
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;
164
165    -----------
166    -- Swap8 --
167    -----------
168
169    procedure Swap8 (Location : System.Address) is
170
171       X : Unsigned_64;
172       for X'Address use Location;
173
174       type Two_Words is array (0 .. 1) of Unsigned_32;
175       for Two_Words'Component_Size use Unsigned_32'Size;
176
177       Words : Two_Words;
178       for Words'Address use Location;
179
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;
191
192 end GNAT.Byte_Swapping;