OSDN Git Service

2011-08-05 Yannick Moy <moy@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / g-altive.ads
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                         G N A T . A L T I V E C                          --
6 --                                                                          --
7 --                                 S p e c                                  --
8 --                                                                          --
9 --          Copyright (C) 2004-2011, Free Software Foundation, Inc.         --
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 -------------------------
33 -- General description --
34 -------------------------
35
36 --  This is the root of a package hierarchy offering an Ada binding to the
37 --  PowerPC AltiVec extensions, a set of 128bit vector types together with a
38 --  set of subprograms operating on them. Relevant documents are:
39
40 --  o AltiVec Technology, Programming Interface Manual (1999-06)
41 --    to which we will refer as [PIM], describes the data types, the
42 --    functional interface and the ABI conventions.
43
44 --  o AltiVec Technology, Programming Environments Manual (2002-02)
45 --    to which we will refer as [PEM], describes the hardware architecture
46 --    and instruction set.
47
48 --  These documents, as well as a number of others of general interest on the
49 --  AltiVec technology, are available from the Motorola/AltiVec Web site at:
50
51 --  http://www.freescale.com/altivec
52
53 --  The binding interface is structured to allow alternate implementations:
54 --  for real AltiVec capable targets, and for other targets. In the latter
55 --  case, everything is emulated in software. The two versions are referred
56 --  to as:
57
58 --  o The Hard binding for AltiVec capable targets (with the appropriate
59 --    hardware support and corresponding instruction set)
60
61 --  o The Soft binding for other targets (with the low level primitives
62 --    emulated in software).
63
64 --  In addition, interfaces that are not strictly part of the base AltiVec API
65 --  are provided, such as vector conversions to and from array representations,
66 --  which are of interest for client applications (e.g. for vector
67 --  initialization purposes).
68
69 --  Only the soft binding is available today
70
71 -----------------------------------------
72 -- General package architecture survey --
73 -----------------------------------------
74
75 --  The various vector representations are all "containers" of elementary
76 --  values, the possible types of which are declared in this root package to
77 --  be generally accessible.
78
79 --  From the user standpoint, the binding materializes as a consistent
80 --  hierarchy of units:
81
82 --                             GNAT.Altivec
83 --                           (component types)
84 --                                   |
85 --          o----------------o----------------o-------------o
86 --          |                |                |             |
87 --    Vector_Types   Vector_Operations   Vector_Views   Conversions
88
89 --  The user can manipulate vectors through two families of types: Vector
90 --  types and View types.
91
92 --  Vector types are defined in the GNAT.Altivec.Vector_Types package
93
94 --  On these types, users can apply the Altivec operations defined in
95 --  GNAT.Altivec.Vector_Operations. Their layout is opaque and may vary across
96 --  configurations, for it is typically target-endianness dependant.
97
98 --  Vector_Types and Vector_Operations implement the core binding to the
99 --  AltiVec API, as described in [PIM-2.1 data types] and [PIM-4 AltiVec
100 --  operations and predicates].
101
102 --  View types are defined in the GNAT.Altivec.Vector_Views package
103
104 --  These types do not represent Altivec vectors per se, in the sense that the
105 --  Altivec_Operations are not available for them. They are intended to allow
106 --  Vector initializations as well as access to the Vector component values.
107
108 --  The GNAT.Altivec.Conversions package is provided to convert a View to the
109 --  corresponding Vector and vice-versa.
110
111 ---------------------------
112 -- Underlying principles --
113 ---------------------------
114
115 --  Internally, the binding relies on an abstraction of the Altivec API, a
116 --  rich set of functions around a core of low level primitives mapping to
117 --  AltiVec instructions. See for instance "vec_add" in [PIM-4.4 Generic and
118 --  Specific AltiVec operations], with no less than six result/arguments
119 --  combinations of byte vector types that map to "vaddubm".
120
121 --  The "soft" version is a software emulation of the low level primitives.
122
123 --  The "hard" version would map to real AltiVec instructions via GCC builtins
124 --  and inlining.
125
126 -------------------
127 -- Example usage --
128 -------------------
129
130 --  Here is a sample program declaring and initializing two vectors, 'add'ing
131 --  them and displaying the result components:
132
133 --  with GNAT.Altivec.Vector_Types;      use GNAT.Altivec.Vector_Types;
134 --  with GNAT.Altivec.Vector_Operations; use GNAT.Altivec.Vector_Operations;
135 --  with GNAT.Altivec.Vector_Views;      use GNAT.Altivec.Vector_Views;
136 --  with GNAT.Altivec.Conversions;       use GNAT.Altivec.Conversions;
137
138 --  use GNAT.Altivec;
139
140 --  with Ada.Text_IO; use Ada.Text_IO;
141
142 --  procedure Sample is
143 --     Va : Vector_Unsigned_Int := To_Vector ((Values => (1, 2, 3, 4)));
144 --     Vb : Vector_Unsigned_Int := To_Vector ((Values => (1, 2, 3, 4)));
145
146 --     Vs : Vector_Unsigned_Int;
147 --     Vs_View : VUI_View;
148 --  begin
149 --     Vs := Vec_Add (Va, Vb);
150 --     Vs_View := To_View (Vs);
151
152 --     for I in Vs_View.Values'Range loop
153 --        Put_Line (Unsigned_Int'Image (Vs_View.Values (I)));
154 --     end loop;
155 --  end;
156
157 --  $ gnatmake sample.adb
158 --  [...]
159 --  $ ./sample
160 --  2
161 --  4
162 --  6
163 --  8
164
165 ------------------------------------------------------------------------------
166
167 with System;
168
169 package GNAT.Altivec is
170
171    --  Definitions of constants and vector/array component types common to all
172    --  the versions of the binding.
173
174    --  All the vector types are 128bits
175
176    VECTOR_BIT : constant := 128;
177
178    -------------------------------------------
179    -- [PIM-2.3.1 Alignment of vector types] --
180    -------------------------------------------
181
182    --  "A defined data item of any vector data type in memory is always
183    --  aligned on a 16-byte boundary. A pointer to any vector data type always
184    --  points to a 16-byte boundary. The compiler is responsible for aligning
185    --  vector data types on 16-byte boundaries."
186
187    VECTOR_ALIGNMENT : constant := Natural'Min (16, Standard'Maximum_Alignment);
188    --  This value is used to set the alignment of vector datatypes in both the
189    --  hard and the soft binding implementations.
190    --
191    --  We want this value to never be greater than 16, because none of the
192    --  binding implementations requires larger alignments and such a value
193    --  would cause useless space to be allocated/wasted for vector objects.
194    --  Furthermore, the alignment of 16 matches the hard binding leading to
195    --  a more faithful emulation.
196    --
197    --  It needs to be exactly 16 for the hard binding, and the initializing
198    --  expression is just right for this purpose since Maximum_Alignment is
199    --  expected to be 16 for the real Altivec ABI.
200    --
201    --  The soft binding doesn't rely on strict 16byte alignment, and we want
202    --  the value to be no greater than Standard'Maximum_Alignment in this case
203    --  to ensure it is supported on every possible target.
204
205    -------------------------------------------------------
206    -- [PIM-2.1] Data Types - Interpretation of contents --
207    -------------------------------------------------------
208
209    ---------------------
210    -- char components --
211    ---------------------
212
213    CHAR_BIT    : constant := 8;
214    SCHAR_MIN   : constant := -2 ** (CHAR_BIT - 1);
215    SCHAR_MAX   : constant := 2 ** (CHAR_BIT - 1) - 1;
216    UCHAR_MAX   : constant := 2 ** CHAR_BIT - 1;
217
218    type unsigned_char is mod UCHAR_MAX + 1;
219    for unsigned_char'Size use CHAR_BIT;
220
221    type signed_char is range SCHAR_MIN .. SCHAR_MAX;
222    for signed_char'Size use CHAR_BIT;
223
224    subtype bool_char is unsigned_char;
225    --  ??? There is a difference here between what the Altivec Technology
226    --  Programming Interface Manual says and what GCC says. In the manual,
227    --  vector_bool_char is a vector_unsigned_char, while in altivec.h it
228    --  is a vector_signed_char.
229
230    bool_char_True  : constant bool_char := bool_char'Last;
231    bool_char_False : constant bool_char := 0;
232
233    ----------------------
234    -- short components --
235    ----------------------
236
237    SHORT_BIT   : constant := 16;
238    SSHORT_MIN  : constant := -2 ** (SHORT_BIT - 1);
239    SSHORT_MAX  : constant := 2 ** (SHORT_BIT - 1) - 1;
240    USHORT_MAX  : constant := 2 ** SHORT_BIT - 1;
241
242    type unsigned_short is mod USHORT_MAX + 1;
243    for unsigned_short'Size use SHORT_BIT;
244
245    subtype unsigned_short_int is unsigned_short;
246
247    type signed_short is range SSHORT_MIN .. SSHORT_MAX;
248    for signed_short'Size use SHORT_BIT;
249
250    subtype signed_short_int is signed_short;
251
252    subtype bool_short is unsigned_short;
253    --  ??? See bool_char
254
255    bool_short_True  : constant bool_short := bool_short'Last;
256    bool_short_False : constant bool_short := 0;
257
258    subtype bool_short_int is bool_short;
259
260    --------------------
261    -- int components --
262    --------------------
263
264    INT_BIT     : constant := 32;
265    SINT_MIN    : constant := -2 ** (INT_BIT - 1);
266    SINT_MAX    : constant := 2 ** (INT_BIT - 1) - 1;
267    UINT_MAX    : constant := 2 ** INT_BIT - 1;
268
269    type unsigned_int is mod UINT_MAX + 1;
270    for unsigned_int'Size use INT_BIT;
271
272    type signed_int is range SINT_MIN .. SINT_MAX;
273    for signed_int'Size use INT_BIT;
274
275    subtype bool_int is unsigned_int;
276    --  ??? See bool_char
277
278    bool_int_True  : constant bool_int := bool_int'Last;
279    bool_int_False : constant bool_int := 0;
280
281    ----------------------
282    -- float components --
283    ----------------------
284
285    FLOAT_BIT   : constant := 32;
286    FLOAT_DIGIT : constant := 6;
287    FLOAT_MIN   : constant := -16#0.FFFF_FF#E+32;
288    FLOAT_MAX   : constant := 16#0.FFFF_FF#E+32;
289
290    type C_float is digits FLOAT_DIGIT range FLOAT_MIN .. FLOAT_MAX;
291    for C_float'Size use FLOAT_BIT;
292    --  Altivec operations always use the standard native floating-point
293    --  support of the target. Note that this means that there may be
294    --  minor differences in results between targets when the floating-
295    --  point implementations are slightly different, as would happen
296    --  with normal non-Altivec floating-point operations. In particular
297    --  the Altivec simulations may yield slightly different results
298    --  from those obtained on a true hardware Altivec target if the
299    --  floating-point implementation is not 100% compatible.
300
301    ----------------------
302    -- pixel components --
303    ----------------------
304
305    subtype pixel is unsigned_short;
306
307    -----------------------------------------------------------
308    -- Subtypes for variants found in the GCC implementation --
309    -----------------------------------------------------------
310
311    subtype c_int is signed_int;
312    subtype c_short is c_int;
313
314    LONG_BIT  : constant := 32;
315    --  Some of the GCC builtins are built with "long" arguments and
316    --  expect SImode to come in.
317
318    SLONG_MIN : constant := -2 ** (LONG_BIT - 1);
319    SLONG_MAX : constant :=  2 ** (LONG_BIT - 1) - 1;
320    ULONG_MAX : constant :=  2 ** LONG_BIT - 1;
321
322    type signed_long   is range SLONG_MIN .. SLONG_MAX;
323    type unsigned_long is mod ULONG_MAX + 1;
324
325    subtype c_long is signed_long;
326
327    subtype c_ptr is System.Address;
328
329    ---------------------------------------------------------
330    -- Access types, for the sake of some argument passing --
331    ---------------------------------------------------------
332
333    type signed_char_ptr    is access all signed_char;
334    type unsigned_char_ptr  is access all unsigned_char;
335
336    type short_ptr          is access all c_short;
337    type signed_short_ptr   is access all signed_short;
338    type unsigned_short_ptr is access all unsigned_short;
339
340    type int_ptr            is access all c_int;
341    type signed_int_ptr     is access all signed_int;
342    type unsigned_int_ptr   is access all unsigned_int;
343
344    type long_ptr           is access all c_long;
345    type signed_long_ptr    is access all signed_long;
346    type unsigned_long_ptr  is access all unsigned_long;
347
348    type float_ptr          is access all Float;
349
350    --
351
352    type const_signed_char_ptr    is access constant signed_char;
353    type const_unsigned_char_ptr  is access constant unsigned_char;
354
355    type const_short_ptr          is access constant c_short;
356    type const_signed_short_ptr   is access constant signed_short;
357    type const_unsigned_short_ptr is access constant unsigned_short;
358
359    type const_int_ptr            is access constant c_int;
360    type const_signed_int_ptr     is access constant signed_int;
361    type const_unsigned_int_ptr   is access constant unsigned_int;
362
363    type const_long_ptr           is access constant c_long;
364    type const_signed_long_ptr    is access constant signed_long;
365    type const_unsigned_long_ptr  is access constant unsigned_long;
366
367    type const_float_ptr          is access constant Float;
368
369    --  Access to const volatile arguments need specialized types
370
371    type volatile_float is new Float;
372    pragma Volatile (volatile_float);
373
374    type volatile_signed_char is new signed_char;
375    pragma Volatile (volatile_signed_char);
376
377    type volatile_unsigned_char is new unsigned_char;
378    pragma Volatile (volatile_unsigned_char);
379
380    type volatile_signed_short is new signed_short;
381    pragma Volatile (volatile_signed_short);
382
383    type volatile_unsigned_short is new unsigned_short;
384    pragma Volatile (volatile_unsigned_short);
385
386    type volatile_signed_int is new signed_int;
387    pragma Volatile (volatile_signed_int);
388
389    type volatile_unsigned_int is new unsigned_int;
390    pragma Volatile (volatile_unsigned_int);
391
392    type volatile_signed_long is new signed_long;
393    pragma Volatile (volatile_signed_long);
394
395    type volatile_unsigned_long is new unsigned_long;
396    pragma Volatile (volatile_unsigned_long);
397
398    type constv_char_ptr           is access constant volatile_signed_char;
399    type constv_signed_char_ptr    is access constant volatile_signed_char;
400    type constv_unsigned_char_ptr  is access constant volatile_unsigned_char;
401
402    type constv_short_ptr          is access constant volatile_signed_short;
403    type constv_signed_short_ptr   is access constant volatile_signed_short;
404    type constv_unsigned_short_ptr is access constant volatile_unsigned_short;
405
406    type constv_int_ptr            is access constant volatile_signed_int;
407    type constv_signed_int_ptr     is access constant volatile_signed_int;
408    type constv_unsigned_int_ptr   is access constant volatile_unsigned_int;
409
410    type constv_long_ptr           is access constant volatile_signed_long;
411    type constv_signed_long_ptr    is access constant volatile_signed_long;
412    type constv_unsigned_long_ptr  is access constant volatile_unsigned_long;
413
414    type constv_float_ptr  is access constant volatile_float;
415
416 private
417
418    -----------------------
419    -- Various constants --
420    -----------------------
421
422    CR6_EQ     : constant := 0;
423    CR6_EQ_REV : constant := 1;
424    CR6_LT     : constant := 2;
425    CR6_LT_REV : constant := 3;
426
427 end GNAT.Altivec;