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 167with System; 168 169package 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 416private 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 427end GNAT.Altivec; 428