1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- G N A T . A L T I V E C . L O W _ L E V E L _ V E C T O R S --
8 -- (Soft Binding Version) --
10 -- Copyright (C) 2004-2006, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 -- ??? What is exactly needed for the soft case is still a bit unclear on
36 -- some accounts. The expected functional equivalence with the Hard binding
37 -- might require tricky things to be done on some targets.
39 -- Examples that come to mind are endianness variations or differences in the
40 -- base FP model while we need the operation results to be the same as what
41 -- the real AltiVec instructions would do on a PowerPC.
43 with Ada.Numerics.Generic_Elementary_Functions;
44 with Interfaces; use Interfaces;
45 with System.Storage_Elements; use System.Storage_Elements;
47 with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions;
48 with GNAT.Altivec.Low_Level_Interface; use GNAT.Altivec.Low_Level_Interface;
50 package body GNAT.Altivec.Low_Level_Vectors is
52 -- This package assumes C_float is an IEEE single-precision float type
54 pragma Assert (C_float'Machine_Radix = 2);
55 pragma Assert (C_float'Machine_Mantissa = 24);
56 pragma Assert (C_float'Machine_Emin = -125);
57 pragma Assert (C_float'Machine_Emax = 128);
58 pragma Assert (C_float'Machine_Rounds);
59 pragma Assert (not C_float'Machine_Overflows);
60 pragma Assert (C_float'Signed_Zeros);
61 pragma Assert (C_float'Denorm);
63 -- Pixel types. As defined in [PIM-2.1 Data types]:
64 -- A 16-bit pixel is 1/5/5/5;
65 -- A 32-bit pixel is 8/8/8/8.
66 -- We use the following records as an intermediate representation, to
69 type Unsigned_1 is mod 2 ** 1;
70 type Unsigned_5 is mod 2 ** 5;
72 type Pixel_16 is record
79 type Pixel_32 is record
86 -- Conversions to/from the pixel records to the integer types that are
87 -- actually stored into the pixel vectors:
89 function To_Pixel (Source : unsigned_short) return Pixel_16;
90 function To_unsigned_short (Source : Pixel_16) return unsigned_short;
91 function To_Pixel (Source : unsigned_int) return Pixel_32;
92 function To_unsigned_int (Source : Pixel_32) return unsigned_int;
94 package C_float_Operations is
95 new Ada.Numerics.Generic_Elementary_Functions (C_float);
97 -- Model of the Vector Status and Control Register (VSCR), as
98 -- defined in [PIM-4.1 Vector Status and Control Register]:
102 -- Positions of the flags in VSCR(0 .. 31):
104 NJ_POS : constant := 15;
105 SAT_POS : constant := 31;
107 -- To control overflows, integer operations are done on 64-bit types:
109 SINT64_MIN : constant := -2 ** 63;
110 SINT64_MAX : constant := 2 ** 63 - 1;
111 UINT64_MAX : constant := 2 ** 64 - 1;
113 type SI64 is range SINT64_MIN .. SINT64_MAX;
114 type UI64 is mod UINT64_MAX + 1;
116 type F64 is digits 15
117 range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
122 High : Natural) return unsigned_int;
127 High : Natural) return unsigned_short;
132 High : Natural) return unsigned_char;
137 Value : Unsigned_1) return unsigned_int;
142 Value : Unsigned_1) return unsigned_short;
147 Value : Unsigned_1) return unsigned_char;
149 function NJ_Truncate (X : C_float) return C_float;
150 -- If NJ and A is a denormalized number, return zero
153 (X : Integer_Address;
154 Y : Integer_Address) return Integer_Address;
155 -- [PIM-4.3 Notations and Conventions]
156 -- Align X in a y-byte boundary and return the result
158 function Rnd_To_FP_Nearest (X : F64) return C_float;
159 -- [PIM-4.3 Notations and Conventions]
161 function Rnd_To_FPI_Near (X : F64) return F64;
163 function Rnd_To_FPI_Trunc (X : F64) return F64;
165 function FP_Recip_Est (X : C_float) return C_float;
166 -- [PIM-4.3 Notations and Conventions]
167 -- 12-bit accurate floating-point estimate of 1/x
170 (Value : unsigned_char;
171 Amount : Natural) return unsigned_char;
172 -- [PIM-4.3 Notations and Conventions]
176 (Value : unsigned_short;
177 Amount : Natural) return unsigned_short;
180 (Value : unsigned_int;
181 Amount : Natural) return unsigned_int;
183 function Recip_SQRT_Est (X : C_float) return C_float;
186 (Value : unsigned_char;
187 Amount : Natural) return unsigned_char;
188 -- [PIM-4.3 Notations and Conventions]
192 (Value : unsigned_short;
193 Amount : Natural) return unsigned_short;
196 (Value : unsigned_int;
197 Amount : Natural) return unsigned_int;
200 (Value : unsigned_char;
201 Amount : Natural) return unsigned_char;
202 -- [PIM-4.3 Notations and Conventions]
206 (Value : unsigned_short;
207 Amount : Natural) return unsigned_short;
210 (Value : unsigned_int;
211 Amount : Natural) return unsigned_int;
213 Signed_Bool_False : constant := 0;
214 Signed_Bool_True : constant := -1;
216 ------------------------------
217 -- Signed_Operations (spec) --
218 ------------------------------
221 type Component_Type is range <>;
222 type Index_Type is range <>;
223 type Varray_Type is array (Index_Type) of Component_Type;
225 package Signed_Operations is
227 function Modular_Result (X : SI64) return Component_Type;
229 function Saturate (X : SI64) return Component_Type;
231 function Saturate (X : F64) return Component_Type;
233 function Sign_Extend (X : c_int) return Component_Type;
234 -- [PIM-4.3 Notations and Conventions]
237 function abs_vxi (A : Varray_Type) return Varray_Type;
238 pragma Convention (LL_Altivec, abs_vxi);
240 function abss_vxi (A : Varray_Type) return Varray_Type;
241 pragma Convention (LL_Altivec, abss_vxi);
243 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
244 pragma Convention (LL_Altivec, vaddsxs);
246 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
247 pragma Convention (LL_Altivec, vavgsx);
249 function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
250 pragma Convention (LL_Altivec, vcmpgtsx);
252 function lvexx (A : c_long; B : c_ptr) return Varray_Type;
253 pragma Convention (LL_Altivec, lvexx);
255 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
256 pragma Convention (LL_Altivec, vmaxsx);
258 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
259 pragma Convention (LL_Altivec, vmrghx);
261 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
262 pragma Convention (LL_Altivec, vmrglx);
264 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
265 pragma Convention (LL_Altivec, vminsx);
267 function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
268 pragma Convention (LL_Altivec, vspltx);
270 function vspltisx (A : c_int) return Varray_Type;
271 pragma Convention (LL_Altivec, vspltisx);
273 type Bit_Operation is
275 (Value : Component_Type;
276 Amount : Natural) return Component_Type;
281 Shift_Func : Bit_Operation) return Varray_Type;
283 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
284 pragma Convention (LL_Altivec, stvexx);
286 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
287 pragma Convention (LL_Altivec, vsubsxs);
289 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
290 -- If D is the result of a vcmp operation and A the flag for
291 -- the kind of operation (e.g CR6_LT), check the predicate
292 -- that corresponds to this flag.
294 end Signed_Operations;
296 ------------------------------
297 -- Signed_Operations (body) --
298 ------------------------------
300 package body Signed_Operations is
302 Bool_True : constant Component_Type := Signed_Bool_True;
303 Bool_False : constant Component_Type := Signed_Bool_False;
305 Number_Of_Elements : constant Integer :=
306 VECTOR_BIT / Component_Type'Size;
312 function Modular_Result (X : SI64) return Component_Type is
317 D := Component_Type (UI64 (X)
318 mod (UI64 (Component_Type'Last) + 1));
320 D := Component_Type ((-(UI64 (-X)
321 mod (UI64 (Component_Type'Last) + 1))));
331 function Saturate (X : SI64) return Component_Type is
335 -- Saturation, as defined in
336 -- [PIM-4.1 Vector Status and Control Register]
338 D := Component_Type (SI64'Max
339 (SI64 (Component_Type'First),
341 (SI64 (Component_Type'Last),
344 if SI64 (D) /= X then
345 VSCR := Write_Bit (VSCR, SAT_POS, 1);
351 function Saturate (X : F64) return Component_Type is
355 -- Saturation, as defined in
356 -- [PIM-4.1 Vector Status and Control Register]
358 D := Component_Type (F64'Max
359 (F64 (Component_Type'First),
361 (F64 (Component_Type'Last),
365 VSCR := Write_Bit (VSCR, SAT_POS, 1);
375 function Sign_Extend (X : c_int) return Component_Type is
377 -- X is usually a 5-bits literal. In the case of the simulator,
378 -- it is an integral parameter, so sign extension is straightforward.
380 return Component_Type (X);
387 function abs_vxi (A : Varray_Type) return Varray_Type is
391 for K in Varray_Type'Range loop
392 if A (K) /= Component_Type'First then
393 D (K) := abs (A (K));
395 D (K) := Component_Type'First;
406 function abss_vxi (A : Varray_Type) return Varray_Type is
410 for K in Varray_Type'Range loop
411 D (K) := Saturate (abs (SI64 (A (K))));
421 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
425 for J in Varray_Type'Range loop
426 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
436 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
440 for J in Varray_Type'Range loop
441 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
453 B : Varray_Type) return Varray_Type
458 for J in Varray_Type'Range loop
459 if A (J) > B (J) then
473 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
476 EA : Integer_Address;
480 S := 16 / Number_Of_Elements;
481 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
482 Integer_Address (S));
483 J := Index_Type (((EA mod 16) / Integer_Address (S))
484 + Integer_Address (Index_Type'First));
487 Component : Component_Type;
488 for Component'Address use To_Address (EA);
500 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
504 for J in Varray_Type'Range loop
505 if A (J) > B (J) then
519 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
521 Offset : constant Integer := Integer (Index_Type'First);
522 M : constant Integer := Number_Of_Elements / 2;
525 for J in 0 .. M - 1 loop
526 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
527 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
537 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
539 Offset : constant Integer := Integer (Index_Type'First);
540 M : constant Integer := Number_Of_Elements / 2;
543 for J in 0 .. M - 1 loop
544 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
545 D (Index_Type (2 * J + Offset + 1)) :=
546 B (Index_Type (J + Offset + M));
556 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
560 for J in Varray_Type'Range loop
561 if A (J) < B (J) then
575 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
576 J : constant Integer :=
577 Integer (B) mod Number_Of_Elements
578 + Integer (Varray_Type'First);
582 for K in Varray_Type'Range loop
583 D (K) := A (Index_Type (J));
593 function vspltisx (A : c_int) return Varray_Type is
597 for J in Varray_Type'Range loop
598 D (J) := Sign_Extend (A);
611 Shift_Func : Bit_Operation) return Varray_Type
614 S : constant Component_Type :=
615 Component_Type (128 / Number_Of_Elements);
618 for J in Varray_Type'Range loop
619 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
629 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
631 EA : Integer_Address;
635 S := 16 / Number_Of_Elements;
636 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
637 Integer_Address (S));
638 J := Index_Type ((EA mod 16) / Integer_Address (S)
639 + Integer_Address (Index_Type'First));
642 Component : Component_Type;
643 for Component'Address use To_Address (EA);
653 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
657 for J in Varray_Type'Range loop
658 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
668 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
669 All_Element : Boolean := True;
670 Any_Element : Boolean := False;
673 for J in Varray_Type'Range loop
674 All_Element := All_Element and (D (J) = Bool_True);
675 Any_Element := Any_Element or (D (J) = Bool_True);
685 elsif A = CR6_EQ then
686 if not Any_Element then
692 elsif A = CR6_EQ_REV then
699 elsif A = CR6_LT_REV then
700 if not All_Element then
710 end Signed_Operations;
712 --------------------------------
713 -- Unsigned_Operations (spec) --
714 --------------------------------
717 type Component_Type is mod <>;
718 type Index_Type is range <>;
719 type Varray_Type is array (Index_Type) of Component_Type;
721 package Unsigned_Operations is
726 High : Natural) return Component_Type;
727 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
728 -- using big endian bit ordering.
733 Value : Unsigned_1) return Component_Type;
734 -- Write Value into X[Where:Where] (if it fits in) and return the result
735 -- (big endian bit ordering).
737 function Modular_Result (X : UI64) return Component_Type;
739 function Saturate (X : UI64) return Component_Type;
741 function Saturate (X : F64) return Component_Type;
743 function Saturate (X : SI64) return Component_Type;
745 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
747 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
749 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
751 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
753 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
755 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
757 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
759 type Bit_Operation is
761 (Value : Component_Type;
762 Amount : Natural) return Component_Type;
767 ROTL : Bit_Operation) return Varray_Type;
772 Shift_Func : Bit_Operation) return Varray_Type;
773 -- Vector shift (left or right, depending on Shift_Func)
775 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
777 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
779 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
780 -- If D is the result of a vcmp operation and A the flag for
781 -- the kind of operation (e.g CR6_LT), check the predicate
782 -- that corresponds to this flag.
784 end Unsigned_Operations;
786 --------------------------------
787 -- Unsigned_Operations (body) --
788 --------------------------------
790 package body Unsigned_Operations is
792 Number_Of_Elements : constant Integer :=
793 VECTOR_BIT / Component_Type'Size;
795 Bool_True : constant Component_Type := Component_Type'Last;
796 Bool_False : constant Component_Type := 0;
802 function Modular_Result (X : UI64) return Component_Type is
805 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
813 function Saturate (X : UI64) return Component_Type is
817 -- Saturation, as defined in
818 -- [PIM-4.1 Vector Status and Control Register]
820 D := Component_Type (UI64'Max
821 (UI64 (Component_Type'First),
823 (UI64 (Component_Type'Last),
826 if UI64 (D) /= X then
827 VSCR := Write_Bit (VSCR, SAT_POS, 1);
833 function Saturate (X : SI64) return Component_Type is
837 -- Saturation, as defined in
838 -- [PIM-4.1 Vector Status and Control Register]
840 D := Component_Type (SI64'Max
841 (SI64 (Component_Type'First),
843 (SI64 (Component_Type'Last),
846 if SI64 (D) /= X then
847 VSCR := Write_Bit (VSCR, SAT_POS, 1);
853 function Saturate (X : F64) return Component_Type is
857 -- Saturation, as defined in
858 -- [PIM-4.1 Vector Status and Control Register]
860 D := Component_Type (F64'Max
861 (F64 (Component_Type'First),
863 (F64 (Component_Type'Last),
867 VSCR := Write_Bit (VSCR, SAT_POS, 1);
880 High : Natural) return Component_Type
882 Mask : Component_Type := 0;
884 -- The Altivec ABI uses a big endian bit ordering, and we are
885 -- using little endian bit ordering for extracting bits:
887 Low_LE : constant Natural := Component_Type'Size - 1 - High;
888 High_LE : constant Natural := Component_Type'Size - 1 - Low;
891 pragma Assert (Low <= Component_Type'Size);
892 pragma Assert (High <= Component_Type'Size);
894 for J in Low_LE .. High_LE loop
895 Mask := Mask or 2 ** J;
898 return (X and Mask) / 2 ** Low_LE;
908 Value : Unsigned_1) return Component_Type
910 Result : Component_Type := 0;
912 -- The Altivec ABI uses a big endian bit ordering, and we are
913 -- using little endian bit ordering for extracting bits:
915 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
918 pragma Assert (Where < Component_Type'Size);
922 Result := X or 2 ** Where_LE;
924 Result := X and not (2 ** Where_LE);
934 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
938 for J in Varray_Type'Range loop
939 D (J) := A (J) + B (J);
949 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
953 for J in Varray_Type'Range loop
954 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
964 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
968 for J in Varray_Type'Range loop
969 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
981 B : Varray_Type) return Varray_Type
986 for J in Varray_Type'Range loop
987 if A (J) = B (J) then
1003 B : Varray_Type) return Varray_Type
1007 for J in Varray_Type'Range loop
1008 if A (J) > B (J) then
1011 D (J) := Bool_False;
1022 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1026 for J in Varray_Type'Range loop
1027 if A (J) > B (J) then
1041 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1045 for J in Varray_Type'Range loop
1046 if A (J) < B (J) then
1063 ROTL : Bit_Operation) return Varray_Type
1068 for J in Varray_Type'Range loop
1069 D (J) := ROTL (A (J), Natural (B (J)));
1082 Shift_Func : Bit_Operation) return Varray_Type
1085 S : constant Component_Type :=
1086 Component_Type (128 / Number_Of_Elements);
1089 for J in Varray_Type'Range loop
1090 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1100 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1104 for J in Varray_Type'Range loop
1105 D (J) := A (J) - B (J);
1115 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1119 for J in Varray_Type'Range loop
1120 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1130 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1131 All_Element : Boolean := True;
1132 Any_Element : Boolean := False;
1135 for J in Varray_Type'Range loop
1136 All_Element := All_Element and (D (J) = Bool_True);
1137 Any_Element := Any_Element or (D (J) = Bool_True);
1147 elsif A = CR6_EQ then
1148 if not Any_Element then
1154 elsif A = CR6_EQ_REV then
1161 elsif A = CR6_LT_REV then
1162 if not All_Element then
1172 end Unsigned_Operations;
1174 --------------------------------------
1175 -- Signed_Merging_Operations (spec) --
1176 --------------------------------------
1179 type Component_Type is range <>;
1180 type Index_Type is range <>;
1181 type Varray_Type is array (Index_Type) of Component_Type;
1182 type Double_Component_Type is range <>;
1183 type Double_Index_Type is range <>;
1184 type Double_Varray_Type is array (Double_Index_Type)
1185 of Double_Component_Type;
1187 package Signed_Merging_Operations is
1189 pragma Assert (Integer (Varray_Type'First)
1190 = Integer (Double_Varray_Type'First));
1191 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1192 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1195 (X : Double_Component_Type) return Component_Type;
1198 (Use_Even_Components : Boolean;
1200 B : Varray_Type) return Double_Varray_Type;
1203 (A : Double_Varray_Type;
1204 B : Double_Varray_Type) return Varray_Type;
1205 pragma Convention (LL_Altivec, vpksxss);
1209 Offset : Natural) return Double_Varray_Type;
1211 end Signed_Merging_Operations;
1213 --------------------------------------
1214 -- Signed_Merging_Operations (body) --
1215 --------------------------------------
1217 package body Signed_Merging_Operations is
1224 (X : Double_Component_Type) return Component_Type
1229 -- Saturation, as defined in
1230 -- [PIM-4.1 Vector Status and Control Register]
1232 D := Component_Type (Double_Component_Type'Max
1233 (Double_Component_Type (Component_Type'First),
1234 Double_Component_Type'Min
1235 (Double_Component_Type (Component_Type'Last),
1238 if Double_Component_Type (D) /= X then
1239 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1250 (Use_Even_Components : Boolean;
1252 B : Varray_Type) return Double_Varray_Type
1254 Double_Offset : Double_Index_Type;
1255 Offset : Index_Type;
1256 D : Double_Varray_Type;
1257 N : constant Integer :=
1258 Integer (Double_Index_Type'Last)
1259 - Integer (Double_Index_Type'First) + 1;
1263 for J in 0 .. N - 1 loop
1264 if Use_Even_Components then
1265 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1267 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1271 Double_Index_Type (J + Integer (Double_Index_Type'First));
1272 D (Double_Offset) :=
1273 Double_Component_Type (A (Offset))
1274 * Double_Component_Type (B (Offset));
1285 (A : Double_Varray_Type;
1286 B : Double_Varray_Type) return Varray_Type
1288 N : constant Index_Type :=
1289 Index_Type (Double_Index_Type'Last);
1291 Offset : Index_Type;
1292 Double_Offset : Double_Index_Type;
1295 for J in 0 .. N - 1 loop
1296 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1298 Double_Index_Type (Integer (J)
1299 + Integer (Double_Index_Type'First));
1300 D (Offset) := Saturate (A (Double_Offset));
1301 D (Offset + N) := Saturate (B (Double_Offset));
1313 Offset : Natural) return Double_Varray_Type
1316 D : Double_Varray_Type;
1319 for J in Double_Varray_Type'Range loop
1320 K := Index_Type (Integer (J)
1321 - Integer (Double_Index_Type'First)
1322 + Integer (Index_Type'First)
1324 D (J) := Double_Component_Type (A (K));
1330 end Signed_Merging_Operations;
1332 ----------------------------------------
1333 -- Unsigned_Merging_Operations (spec) --
1334 ----------------------------------------
1337 type Component_Type is mod <>;
1338 type Index_Type is range <>;
1339 type Varray_Type is array (Index_Type) of Component_Type;
1340 type Double_Component_Type is mod <>;
1341 type Double_Index_Type is range <>;
1342 type Double_Varray_Type is array (Double_Index_Type)
1343 of Double_Component_Type;
1345 package Unsigned_Merging_Operations is
1347 pragma Assert (Integer (Varray_Type'First)
1348 = Integer (Double_Varray_Type'First));
1349 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1350 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1352 function UI_To_UI_Mod
1353 (X : Double_Component_Type;
1354 Y : Natural) return Component_Type;
1356 function Saturate (X : Double_Component_Type) return Component_Type;
1359 (Use_Even_Components : Boolean;
1361 B : Varray_Type) return Double_Varray_Type;
1364 (A : Double_Varray_Type;
1365 B : Double_Varray_Type) return Varray_Type;
1368 (A : Double_Varray_Type;
1369 B : Double_Varray_Type) return Varray_Type;
1371 end Unsigned_Merging_Operations;
1373 ----------------------------------------
1374 -- Unsigned_Merging_Operations (body) --
1375 ----------------------------------------
1377 package body Unsigned_Merging_Operations is
1383 function UI_To_UI_Mod
1384 (X : Double_Component_Type;
1385 Y : Natural) return Component_Type is
1388 Z := Component_Type (X mod 2 ** Y);
1396 function Saturate (X : Double_Component_Type) return Component_Type is
1400 -- Saturation, as defined in
1401 -- [PIM-4.1 Vector Status and Control Register]
1403 D := Component_Type (Double_Component_Type'Max
1404 (Double_Component_Type (Component_Type'First),
1405 Double_Component_Type'Min
1406 (Double_Component_Type (Component_Type'Last),
1409 if Double_Component_Type (D) /= X then
1410 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1421 (Use_Even_Components : Boolean;
1423 B : Varray_Type) return Double_Varray_Type
1425 Double_Offset : Double_Index_Type;
1426 Offset : Index_Type;
1427 D : Double_Varray_Type;
1428 N : constant Integer :=
1429 Integer (Double_Index_Type'Last)
1430 - Integer (Double_Index_Type'First) + 1;
1433 for J in 0 .. N - 1 loop
1434 if Use_Even_Components then
1435 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1437 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1441 Double_Index_Type (J + Integer (Double_Index_Type'First));
1442 D (Double_Offset) :=
1443 Double_Component_Type (A (Offset))
1444 * Double_Component_Type (B (Offset));
1455 (A : Double_Varray_Type;
1456 B : Double_Varray_Type) return Varray_Type
1458 S : constant Natural :=
1459 Double_Component_Type'Size / 2;
1460 N : constant Index_Type :=
1461 Index_Type (Double_Index_Type'Last);
1463 Offset : Index_Type;
1464 Double_Offset : Double_Index_Type;
1467 for J in 0 .. N - 1 loop
1468 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1470 Double_Index_Type (Integer (J)
1471 + Integer (Double_Index_Type'First));
1472 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1473 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1484 (A : Double_Varray_Type;
1485 B : Double_Varray_Type) return Varray_Type
1487 N : constant Index_Type :=
1488 Index_Type (Double_Index_Type'Last);
1490 Offset : Index_Type;
1491 Double_Offset : Double_Index_Type;
1494 for J in 0 .. N - 1 loop
1495 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1497 Double_Index_Type (Integer (J)
1498 + Integer (Double_Index_Type'First));
1499 D (Offset) := Saturate (A (Double_Offset));
1500 D (Offset + N) := Saturate (B (Double_Offset));
1506 end Unsigned_Merging_Operations;
1508 package LL_VSC_Operations is
1509 new Signed_Operations (signed_char,
1511 Varray_signed_char);
1513 package LL_VSS_Operations is
1514 new Signed_Operations (signed_short,
1516 Varray_signed_short);
1518 package LL_VSI_Operations is
1519 new Signed_Operations (signed_int,
1523 package LL_VUC_Operations is
1524 new Unsigned_Operations (unsigned_char,
1526 Varray_unsigned_char);
1528 package LL_VUS_Operations is
1529 new Unsigned_Operations (unsigned_short,
1531 Varray_unsigned_short);
1533 package LL_VUI_Operations is
1534 new Unsigned_Operations (unsigned_int,
1536 Varray_unsigned_int);
1538 package LL_VSC_LL_VSS_Operations is
1539 new Signed_Merging_Operations (signed_char,
1544 Varray_signed_short);
1546 package LL_VSS_LL_VSI_Operations is
1547 new Signed_Merging_Operations (signed_short,
1549 Varray_signed_short,
1554 package LL_VUC_LL_VUS_Operations is
1555 new Unsigned_Merging_Operations (unsigned_char,
1557 Varray_unsigned_char,
1560 Varray_unsigned_short);
1562 package LL_VUS_LL_VUI_Operations is
1563 new Unsigned_Merging_Operations (unsigned_short,
1565 Varray_unsigned_short,
1568 Varray_unsigned_int);
1577 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1580 (X : unsigned_short;
1582 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1587 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1596 Value : Unsigned_1) return unsigned_int
1597 renames LL_VUI_Operations.Write_Bit;
1600 (X : unsigned_short;
1602 Value : Unsigned_1) return unsigned_short
1603 renames LL_VUS_Operations.Write_Bit;
1608 Value : Unsigned_1) return unsigned_char
1609 renames LL_VUC_Operations.Write_Bit;
1615 function Bound_Align
1616 (X : Integer_Address;
1617 Y : Integer_Address) return Integer_Address
1619 D : Integer_Address;
1629 function NJ_Truncate (X : C_float) return C_float is
1633 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1634 and then abs (X) < 2.0 ** (-126)
1648 -----------------------
1649 -- Rnd_To_FP_Nearest --
1650 -----------------------
1652 function Rnd_To_FP_Nearest (X : F64) return C_float is
1655 end Rnd_To_FP_Nearest;
1657 ---------------------
1658 -- Rnd_To_FPI_Near --
1659 ---------------------
1661 function Rnd_To_FPI_Near (X : F64) return F64 is
1665 Result := F64 (SI64 (X));
1667 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1669 Ceiling := F64'Ceiling (X);
1670 if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling then
1673 Result := Ceiling - 1.0;
1678 end Rnd_To_FPI_Near;
1680 ----------------------
1681 -- Rnd_To_FPI_Trunc --
1682 ----------------------
1684 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1688 Result := F64'Ceiling (X);
1690 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1694 and then Result /= X
1696 Result := Result - 1.0;
1700 end Rnd_To_FPI_Trunc;
1706 function FP_Recip_Est (X : C_float) return C_float is
1708 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1709 -- -Inf, or QNaN, the estimate has a relative error no greater
1710 -- than one part in 4096, that is:
1711 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1713 return NJ_Truncate (1.0 / NJ_Truncate (X));
1721 (Value : unsigned_char;
1722 Amount : Natural) return unsigned_char
1724 Result : Unsigned_8;
1726 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1727 return unsigned_char (Result);
1731 (Value : unsigned_short;
1732 Amount : Natural) return unsigned_short
1734 Result : Unsigned_16;
1736 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1737 return unsigned_short (Result);
1741 (Value : unsigned_int;
1742 Amount : Natural) return unsigned_int
1744 Result : Unsigned_32;
1746 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1747 return unsigned_int (Result);
1750 --------------------
1751 -- Recip_SQRT_Est --
1752 --------------------
1754 function Recip_SQRT_Est (X : C_float) return C_float is
1759 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1760 -- no greater than one part in 4096, that is:
1761 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1763 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1764 return NJ_Truncate (Result);
1772 (Value : unsigned_char;
1773 Amount : Natural) return unsigned_char
1775 Result : Unsigned_8;
1777 Result := Shift_Left (Unsigned_8 (Value), Amount);
1778 return unsigned_char (Result);
1782 (Value : unsigned_short;
1783 Amount : Natural) return unsigned_short
1785 Result : Unsigned_16;
1787 Result := Shift_Left (Unsigned_16 (Value), Amount);
1788 return unsigned_short (Result);
1792 (Value : unsigned_int;
1793 Amount : Natural) return unsigned_int
1795 Result : Unsigned_32;
1797 Result := Shift_Left (Unsigned_32 (Value), Amount);
1798 return unsigned_int (Result);
1805 function Shift_Right
1806 (Value : unsigned_char;
1807 Amount : Natural) return unsigned_char
1809 Result : Unsigned_8;
1811 Result := Shift_Right (Unsigned_8 (Value), Amount);
1812 return unsigned_char (Result);
1815 function Shift_Right
1816 (Value : unsigned_short;
1817 Amount : Natural) return unsigned_short
1819 Result : Unsigned_16;
1821 Result := Shift_Right (Unsigned_16 (Value), Amount);
1822 return unsigned_short (Result);
1825 function Shift_Right
1826 (Value : unsigned_int;
1827 Amount : Natural) return unsigned_int
1829 Result : Unsigned_32;
1831 Result := Shift_Right (Unsigned_32 (Value), Amount);
1832 return unsigned_int (Result);
1840 type Signed_Type is range <>;
1841 type Unsigned_Type is mod <>;
1842 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1843 return Unsigned_Type;
1844 function Shift_Right_Arithmetic
1845 (Value : Signed_Type;
1846 Amount : Natural) return Signed_Type;
1848 function Shift_Right_Arithmetic
1849 (Value : Signed_Type;
1850 Amount : Natural) return Signed_Type
1854 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1856 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1859 end Shift_Right_Arithmetic;
1861 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1865 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1869 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1876 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1878 -- This conversion should not depend on the host endianess;
1879 -- therefore, we cannot use an unchecked conversion.
1884 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1885 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1886 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1887 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1891 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1893 -- This conversion should not depend on the host endianess;
1894 -- therefore, we cannot use an unchecked conversion.
1899 Target.T := unsigned_char (Bits (Source, 0, 7));
1900 Target.R := unsigned_char (Bits (Source, 8, 15));
1901 Target.G := unsigned_char (Bits (Source, 16, 23));
1902 Target.B := unsigned_char (Bits (Source, 24, 31));
1906 ---------------------
1907 -- To_unsigned_int --
1908 ---------------------
1910 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1912 -- This conversion should not depend on the host endianess;
1913 -- therefore, we cannot use an unchecked conversion.
1914 -- It should also be the same result, value-wise, on two hosts
1915 -- with the same endianess.
1917 Target : unsigned_int := 0;
1920 -- In big endian bit ordering, Pixel_32 looks like:
1921 -- -------------------------------------
1922 -- | T | R | G | B |
1923 -- -------------------------------------
1924 -- 0 (MSB) 7 15 23 32
1926 -- Sizes of the components: (8/8/8/8)
1928 Target := Target or unsigned_int (Source.T);
1929 Target := Shift_Left (Target, 8);
1930 Target := Target or unsigned_int (Source.R);
1931 Target := Shift_Left (Target, 8);
1932 Target := Target or unsigned_int (Source.G);
1933 Target := Shift_Left (Target, 8);
1934 Target := Target or unsigned_int (Source.B);
1936 end To_unsigned_int;
1938 -----------------------
1939 -- To_unsigned_short --
1940 -----------------------
1942 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1944 -- This conversion should not depend on the host endianess;
1945 -- therefore, we cannot use an unchecked conversion.
1946 -- It should also be the same result, value-wise, on two hosts
1947 -- with the same endianess.
1949 Target : unsigned_short := 0;
1952 -- In big endian bit ordering, Pixel_16 looks like:
1953 -- -------------------------------------
1954 -- | T | R | G | B |
1955 -- -------------------------------------
1956 -- 0 (MSB) 1 5 11 15
1958 -- Sizes of the components: (1/5/5/5)
1960 Target := Target or unsigned_short (Source.T);
1961 Target := Shift_Left (Target, 5);
1962 Target := Target or unsigned_short (Source.R);
1963 Target := Shift_Left (Target, 5);
1964 Target := Target or unsigned_short (Source.G);
1965 Target := Shift_Left (Target, 5);
1966 Target := Target or unsigned_short (Source.B);
1968 end To_unsigned_short;
1974 function abs_v16qi (A : LL_VSC) return LL_VSC is
1975 VA : constant VSC_View := To_View (A);
1977 return To_Vector ((Values =>
1978 LL_VSC_Operations.abs_vxi (VA.Values)));
1985 function abs_v8hi (A : LL_VSS) return LL_VSS is
1986 VA : constant VSS_View := To_View (A);
1988 return To_Vector ((Values =>
1989 LL_VSS_Operations.abs_vxi (VA.Values)));
1996 function abs_v4si (A : LL_VSI) return LL_VSI is
1997 VA : constant VSI_View := To_View (A);
1999 return To_Vector ((Values =>
2000 LL_VSI_Operations.abs_vxi (VA.Values)));
2007 function abs_v4sf (A : LL_VF) return LL_VF is
2009 VA : constant VF_View := To_View (A);
2012 for J in Varray_float'Range loop
2013 D (J) := abs (VA.Values (J));
2016 return To_Vector ((Values => D));
2023 function abss_v16qi (A : LL_VSC) return LL_VSC is
2024 VA : constant VSC_View := To_View (A);
2026 return To_Vector ((Values =>
2027 LL_VSC_Operations.abss_vxi (VA.Values)));
2034 function abss_v8hi (A : LL_VSS) return LL_VSS is
2035 VA : constant VSS_View := To_View (A);
2037 return To_Vector ((Values =>
2038 LL_VSS_Operations.abss_vxi (VA.Values)));
2045 function abss_v4si (A : LL_VSI) return LL_VSI is
2046 VA : constant VSI_View := To_View (A);
2048 return To_Vector ((Values =>
2049 LL_VSI_Operations.abss_vxi (VA.Values)));
2056 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2057 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2059 VA : constant VUC_View :=
2061 VB : constant VUC_View := To_View (To_LL_VUC (B));
2062 D : Varray_unsigned_char;
2065 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2066 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2073 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2074 VA : constant VUS_View := To_View (To_LL_VUS (A));
2075 VB : constant VUS_View := To_View (To_LL_VUS (B));
2076 D : Varray_unsigned_short;
2079 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2080 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2087 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2088 VA : constant VUI_View := To_View (To_LL_VUI (A));
2089 VB : constant VUI_View := To_View (To_LL_VUI (B));
2090 D : Varray_unsigned_int;
2093 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2094 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2101 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2102 VA : constant VF_View := To_View (A);
2103 VB : constant VF_View := To_View (B);
2107 for J in Varray_float'Range loop
2108 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2109 + NJ_Truncate (VB.Values (J)));
2112 return To_Vector (VF_View'(Values => D));
2119 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2120 Addition_Result : UI64;
2122 VA : constant VUI_View := To_View (To_LL_VUI (A));
2123 VB : constant VUI_View := To_View (To_LL_VUI (B));
2126 for J in Varray_unsigned_int'Range loop
2128 UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2130 if Addition_Result > UI64 (unsigned_int'Last) then
2137 return To_LL_VSI (To_Vector (D));
2144 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2145 VA : constant VUC_View := To_View (To_LL_VUC (A));
2146 VB : constant VUC_View := To_View (To_LL_VUC (B));
2149 return To_LL_VSC (To_Vector
2150 (VUC_View'(Values =>
2151 (LL_VUC_Operations.vadduxs
2160 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2161 VA : constant VSC_View := To_View (A);
2162 VB : constant VSC_View := To_View (B);
2166 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2167 return To_Vector (D);
2174 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2175 VA : constant VUS_View := To_View (To_LL_VUS (A));
2176 VB : constant VUS_View := To_View (To_LL_VUS (B));
2180 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2181 return To_LL_VSS (To_Vector (D));
2188 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2189 VA : constant VSS_View := To_View (A);
2190 VB : constant VSS_View := To_View (B);
2194 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2195 return To_Vector (D);
2202 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2203 VA : constant VUI_View := To_View (To_LL_VUI (A));
2204 VB : constant VUI_View := To_View (To_LL_VUI (B));
2208 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2209 return To_LL_VSI (To_Vector (D));
2216 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2217 VA : constant VSI_View := To_View (A);
2218 VB : constant VSI_View := To_View (B);
2222 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2223 return To_Vector (D);
2230 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2231 VA : constant VUI_View := To_View (To_LL_VUI (A));
2232 VB : constant VUI_View := To_View (To_LL_VUI (B));
2236 for J in Varray_unsigned_int'Range loop
2237 D.Values (J) := VA.Values (J) and VB.Values (J);
2240 return To_LL_VSI (To_Vector (D));
2247 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2248 VA : constant VUI_View := To_View (To_LL_VUI (A));
2249 VB : constant VUI_View := To_View (To_LL_VUI (B));
2253 for J in Varray_unsigned_int'Range loop
2254 D.Values (J) := VA.Values (J) and not VB.Values (J);
2257 return To_LL_VSI (To_Vector (D));
2264 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2265 VA : constant VUC_View := To_View (To_LL_VUC (A));
2266 VB : constant VUC_View := To_View (To_LL_VUC (B));
2270 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2271 return To_LL_VSC (To_Vector (D));
2278 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2279 VA : constant VSC_View := To_View (A);
2280 VB : constant VSC_View := To_View (B);
2284 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2285 return To_Vector (D);
2292 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2293 VA : constant VUS_View := To_View (To_LL_VUS (A));
2294 VB : constant VUS_View := To_View (To_LL_VUS (B));
2298 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2299 return To_LL_VSS (To_Vector (D));
2306 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2307 VA : constant VSS_View := To_View (A);
2308 VB : constant VSS_View := To_View (B);
2312 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2313 return To_Vector (D);
2320 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2321 VA : constant VUI_View := To_View (To_LL_VUI (A));
2322 VB : constant VUI_View := To_View (To_LL_VUI (B));
2326 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2327 return To_LL_VSI (To_Vector (D));
2334 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2335 VA : constant VSI_View := To_View (A);
2336 VB : constant VSI_View := To_View (B);
2340 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2341 return To_Vector (D);
2348 function vrfip (A : LL_VF) return LL_VF is
2349 VA : constant VF_View := To_View (A);
2353 for J in Varray_float'Range loop
2355 -- If A (J) is infinite, D (J) should be infinite; With
2356 -- IEEE floating points, we can use 'Ceiling for that purpose.
2358 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2362 return To_Vector (D);
2369 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2370 VA : constant VF_View := To_View (A);
2371 VB : constant VF_View := To_View (B);
2376 for J in Varray_float'Range loop
2377 K := Vint_Range (J);
2380 if NJ_Truncate (VB.Values (J)) < 0.0 then
2382 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2383 -- word element in B is negative; the corresponding element in A
2384 -- is out of bounds.
2386 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2387 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2390 if NJ_Truncate (VA.Values (J))
2391 <= NJ_Truncate (VB.Values (J)) then
2392 D.Values (K) := Write_Bit (D.Values (K), 0, 0);
2394 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2397 if NJ_Truncate (VA.Values (J))
2398 >= -NJ_Truncate (VB.Values (J)) then
2399 D.Values (K) := Write_Bit (D.Values (K), 1, 0);
2401 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2406 return To_LL_VSI (To_Vector (D));
2413 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2414 VA : constant VUC_View := To_View (To_LL_VUC (A));
2415 VB : constant VUC_View := To_View (To_LL_VUC (B));
2419 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2420 return To_LL_VSC (To_Vector (D));
2427 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2428 VA : constant VUS_View := To_View (To_LL_VUS (A));
2429 VB : constant VUS_View := To_View (To_LL_VUS (B));
2432 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2433 return To_LL_VSS (To_Vector (D));
2440 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2441 VA : constant VUI_View := To_View (To_LL_VUI (A));
2442 VB : constant VUI_View := To_View (To_LL_VUI (B));
2445 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2446 return To_LL_VSI (To_Vector (D));
2453 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2454 VA : constant VF_View := To_View (A);
2455 VB : constant VF_View := To_View (B);
2460 for J in Varray_float'Range loop
2461 K := Vint_Range (J);
2463 if VA.Values (J) = VB.Values (J) then
2464 D.Values (K) := unsigned_int'Last;
2470 return To_LL_VSI (To_Vector (D));
2477 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2478 VA : constant VF_View := To_View (A);
2479 VB : constant VF_View := To_View (B);
2484 for J in Varray_float'Range loop
2485 K := Vint_Range (J);
2487 if VA.Values (J) >= VB.Values (J) then
2488 D.Values (K) := Signed_Bool_True;
2490 D.Values (K) := Signed_Bool_False;
2494 return To_Vector (D);
2501 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2502 VA : constant VUC_View := To_View (To_LL_VUC (A));
2503 VB : constant VUC_View := To_View (To_LL_VUC (B));
2506 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2507 return To_LL_VSC (To_Vector (D));
2514 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2515 VA : constant VSC_View := To_View (A);
2516 VB : constant VSC_View := To_View (B);
2519 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2520 return To_Vector (D);
2527 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2528 VA : constant VUS_View := To_View (To_LL_VUS (A));
2529 VB : constant VUS_View := To_View (To_LL_VUS (B));
2532 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2533 return To_LL_VSS (To_Vector (D));
2540 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2541 VA : constant VSS_View := To_View (A);
2542 VB : constant VSS_View := To_View (B);
2545 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2546 return To_Vector (D);
2553 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2554 VA : constant VUI_View := To_View (To_LL_VUI (A));
2555 VB : constant VUI_View := To_View (To_LL_VUI (B));
2558 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2559 return To_LL_VSI (To_Vector (D));
2566 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2567 VA : constant VSI_View := To_View (A);
2568 VB : constant VSI_View := To_View (B);
2571 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2572 return To_Vector (D);
2579 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2580 VA : constant VF_View := To_View (A);
2581 VB : constant VF_View := To_View (B);
2586 for J in Varray_float'Range loop
2587 K := Vint_Range (J);
2589 if NJ_Truncate (VA.Values (J))
2590 > NJ_Truncate (VB.Values (J)) then
2591 D.Values (K) := Signed_Bool_True;
2593 D.Values (K) := Signed_Bool_False;
2597 return To_Vector (D);
2604 function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2606 VA : constant VUI_View := To_View (To_LL_VUI (A));
2610 for J in Varray_signed_int'Range loop
2611 K := Vfloat_Range (J);
2613 -- Note: The conversion to Integer is safe, as Integers are required
2614 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2615 -- include the range of B (should be 0 .. 255).
2618 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2621 return To_Vector (D);
2628 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2629 VA : constant VSI_View := To_View (A);
2634 for J in Varray_signed_int'Range loop
2635 K := Vfloat_Range (J);
2636 D.Values (K) := C_float (VA.Values (J))
2637 / (2.0 ** Integer (B));
2640 return To_Vector (D);
2647 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2648 VA : constant VF_View := To_View (A);
2653 for J in Varray_signed_int'Range loop
2654 K := Vfloat_Range (J);
2656 LL_VSI_Operations.Saturate
2657 (F64 (NJ_Truncate (VA.Values (K)))
2658 * F64 (2.0 ** Integer (B)));
2661 return To_Vector (D);
2668 function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2669 VA : constant VF_View := To_View (A);
2674 for J in Varray_unsigned_int'Range loop
2675 K := Vfloat_Range (J);
2677 LL_VUI_Operations.Saturate
2678 (F64 (NJ_Truncate (VA.Values (K)))
2679 * F64 (2.0 ** Integer (B)));
2682 return To_LL_VSI (To_Vector (D));
2689 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2691 procedure dss (A : c_int) is
2692 pragma Unreferenced (A);
2701 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2712 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2714 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2715 pragma Unreferenced (A);
2716 pragma Unreferenced (B);
2717 pragma Unreferenced (C);
2726 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2728 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2729 pragma Unreferenced (A);
2730 pragma Unreferenced (B);
2731 pragma Unreferenced (C);
2740 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2742 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2743 pragma Unreferenced (A);
2744 pragma Unreferenced (B);
2745 pragma Unreferenced (C);
2754 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2756 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2757 pragma Unreferenced (A);
2758 pragma Unreferenced (B);
2759 pragma Unreferenced (C);
2768 function vexptefp (A : LL_VF) return LL_VF is
2769 use C_float_Operations;
2771 VA : constant VF_View := To_View (A);
2775 for J in Varray_float'Range loop
2777 -- ??? Check the precision of the operation.
2778 -- As described in [PEM-6 vexptefp]:
2779 -- If theorical_result is equal to 2 at the power of A (J) with
2780 -- infinite precision, we should have:
2781 -- abs ((D (J) - theorical_result) / theorical_result) <= 1/16
2783 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2786 return To_Vector (D);
2793 function vrfim (A : LL_VF) return LL_VF is
2794 VA : constant VF_View := To_View (A);
2798 for J in Varray_float'Range loop
2800 -- If A (J) is infinite, D (J) should be infinite; With
2801 -- IEEE floating point, we can use 'Ceiling for that purpose.
2803 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2805 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2808 if D.Values (J) /= VA.Values (J) then
2809 D.Values (J) := D.Values (J) - 1.0;
2813 return To_Vector (D);
2820 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2822 -- Simulate the altivec unit behavior regarding what Effective Address
2823 -- is accessed, stripping off the input address least significant bits
2824 -- wrt to vector alignment.
2826 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2827 -- an address within a vector is not necessarily rounded back at the
2828 -- vector start address. Besides, rounding on 16 makes no sense on such
2829 -- targets because the address of a properly aligned vector (that is,
2830 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2831 -- want never to happen.
2833 EA : constant System.Address :=
2836 (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2839 for D'Address use EA;
2849 function lvebx (A : c_long; B : c_ptr) return LL_VSC is
2852 D.Values := LL_VSC_Operations.lvexx (A, B);
2853 return To_Vector (D);
2860 function lvehx (A : c_long; B : c_ptr) return LL_VSS is
2863 D.Values := LL_VSS_Operations.lvexx (A, B);
2864 return To_Vector (D);
2871 function lvewx (A : c_long; B : c_ptr) return LL_VSI is
2874 D.Values := LL_VSI_Operations.lvexx (A, B);
2875 return To_Vector (D);
2882 function lvxl (A : c_long; B : c_ptr) return LL_VSI renames
2889 function vlogefp (A : LL_VF) return LL_VF is
2890 VA : constant VF_View := To_View (A);
2894 for J in Varray_float'Range loop
2896 -- ??? Check the precision of the operation.
2897 -- As described in [PEM-6 vlogefp]:
2898 -- If theorical_result is equal to the log2 of A (J) with
2899 -- infinite precision, we should have:
2900 -- abs (D (J) - theorical_result) <= 1/32,
2901 -- unless abs(D(J) - 1) <= 1/8.
2904 C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2907 return To_Vector (D);
2914 function lvsl (A : c_long; B : c_ptr) return LL_VSC is
2915 type bit4_type is mod 16#F# + 1;
2916 for bit4_type'Alignment use 1;
2917 EA : Integer_Address;
2922 EA := Integer_Address (A) + To_Integer (B);
2923 SH := bit4_type (EA mod 2 ** 4);
2925 for J in D.Values'Range loop
2926 D.Values (J) := unsigned_char (SH) + unsigned_char (J)
2927 - unsigned_char (D.Values'First);
2930 return To_LL_VSC (To_Vector (D));
2937 function lvsr (A : c_long; B : c_ptr) return LL_VSC is
2938 type bit4_type is mod 16#F# + 1;
2939 for bit4_type'Alignment use 1;
2940 EA : Integer_Address;
2945 EA := Integer_Address (A) + To_Integer (B);
2946 SH := bit4_type (EA mod 2 ** 4);
2948 for J in D.Values'Range loop
2949 D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2952 return To_LL_VSC (To_Vector (D));
2959 function vmaddfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
2960 VA : constant VF_View := To_View (A);
2961 VB : constant VF_View := To_View (B);
2962 VC : constant VF_View := To_View (C);
2966 for J in Varray_float'Range loop
2968 Rnd_To_FP_Nearest (F64 (VA.Values (J))
2969 * F64 (VB.Values (J))
2970 + F64 (VC.Values (J)));
2973 return To_Vector (D);
2980 function vmhaddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
2981 VA : constant VSS_View := To_View (A);
2982 VB : constant VSS_View := To_View (B);
2983 VC : constant VSS_View := To_View (C);
2987 for J in Varray_signed_short'Range loop
2988 D.Values (J) := LL_VSS_Operations.Saturate
2989 ((SI64 (VA.Values (J)) * SI64 (VB.Values (J)))
2990 / SI64 (2 ** 15) + SI64 (VC.Values (J)));
2993 return To_Vector (D);
3000 function vmaxub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3001 VA : constant VUC_View := To_View (To_LL_VUC (A));
3002 VB : constant VUC_View := To_View (To_LL_VUC (B));
3005 D.Values := LL_VUC_Operations.vmaxux (VA.Values, VB.Values);
3006 return To_LL_VSC (To_Vector (D));
3013 function vmaxsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3014 VA : constant VSC_View := To_View (A);
3015 VB : constant VSC_View := To_View (B);
3018 D.Values := LL_VSC_Operations.vmaxsx (VA.Values, VB.Values);
3019 return To_Vector (D);
3026 function vmaxuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3027 VA : constant VUS_View := To_View (To_LL_VUS (A));
3028 VB : constant VUS_View := To_View (To_LL_VUS (B));
3031 D.Values := LL_VUS_Operations.vmaxux (VA.Values, VB.Values);
3032 return To_LL_VSS (To_Vector (D));
3039 function vmaxsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3040 VA : constant VSS_View := To_View (A);
3041 VB : constant VSS_View := To_View (B);
3044 D.Values := LL_VSS_Operations.vmaxsx (VA.Values, VB.Values);
3045 return To_Vector (D);
3052 function vmaxuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3053 VA : constant VUI_View := To_View (To_LL_VUI (A));
3054 VB : constant VUI_View := To_View (To_LL_VUI (B));
3057 D.Values := LL_VUI_Operations.vmaxux (VA.Values, VB.Values);
3058 return To_LL_VSI (To_Vector (D));
3065 function vmaxsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3066 VA : constant VSI_View := To_View (A);
3067 VB : constant VSI_View := To_View (B);
3070 D.Values := LL_VSI_Operations.vmaxsx (VA.Values, VB.Values);
3071 return To_Vector (D);
3078 function vmaxfp (A : LL_VF; B : LL_VF) return LL_VF is
3079 VA : constant VF_View := To_View (A);
3080 VB : constant VF_View := To_View (B);
3084 for J in Varray_float'Range loop
3085 if VA.Values (J) > VB.Values (J) then
3086 D.Values (J) := VA.Values (J);
3088 D.Values (J) := VB.Values (J);
3092 return To_Vector (D);
3099 function vmrghb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3100 VA : constant VSC_View := To_View (A);
3101 VB : constant VSC_View := To_View (B);
3104 D.Values := LL_VSC_Operations.vmrghx (VA.Values, VB.Values);
3105 return To_Vector (D);
3112 function vmrghh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3113 VA : constant VSS_View := To_View (A);
3114 VB : constant VSS_View := To_View (B);
3117 D.Values := LL_VSS_Operations.vmrghx (VA.Values, VB.Values);
3118 return To_Vector (D);
3125 function vmrghw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3126 VA : constant VSI_View := To_View (A);
3127 VB : constant VSI_View := To_View (B);
3130 D.Values := LL_VSI_Operations.vmrghx (VA.Values, VB.Values);
3131 return To_Vector (D);
3138 function vmrglb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3139 VA : constant VSC_View := To_View (A);
3140 VB : constant VSC_View := To_View (B);
3143 D.Values := LL_VSC_Operations.vmrglx (VA.Values, VB.Values);
3144 return To_Vector (D);
3151 function vmrglh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3152 VA : constant VSS_View := To_View (A);
3153 VB : constant VSS_View := To_View (B);
3156 D.Values := LL_VSS_Operations.vmrglx (VA.Values, VB.Values);
3157 return To_Vector (D);
3164 function vmrglw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3165 VA : constant VSI_View := To_View (A);
3166 VB : constant VSI_View := To_View (B);
3169 D.Values := LL_VSI_Operations.vmrglx (VA.Values, VB.Values);
3170 return To_Vector (D);
3177 function mfvscr return LL_VSS is
3180 for J in Varray_unsigned_short'Range loop
3184 D.Values (Varray_unsigned_short'Last) :=
3185 unsigned_short (VSCR mod 2 ** unsigned_short'Size);
3186 D.Values (Varray_unsigned_short'Last - 1) :=
3187 unsigned_short (VSCR / 2 ** unsigned_short'Size);
3188 return To_LL_VSS (To_Vector (D));
3195 function vminfp (A : LL_VF; B : LL_VF) return LL_VF is
3196 VA : constant VF_View := To_View (A);
3197 VB : constant VF_View := To_View (B);
3201 for J in Varray_float'Range loop
3202 if VA.Values (J) < VB.Values (J) then
3203 D.Values (J) := VA.Values (J);
3205 D.Values (J) := VB.Values (J);
3209 return To_Vector (D);
3216 function vminsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3217 VA : constant VSC_View := To_View (A);
3218 VB : constant VSC_View := To_View (B);
3221 D.Values := LL_VSC_Operations.vminsx (VA.Values, VB.Values);
3222 return To_Vector (D);
3229 function vminub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3230 VA : constant VUC_View := To_View (To_LL_VUC (A));
3231 VB : constant VUC_View := To_View (To_LL_VUC (B));
3234 D.Values := LL_VUC_Operations.vminux (VA.Values, VB.Values);
3235 return To_LL_VSC (To_Vector (D));
3242 function vminsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3243 VA : constant VSS_View := To_View (A);
3244 VB : constant VSS_View := To_View (B);
3247 D.Values := LL_VSS_Operations.vminsx (VA.Values, VB.Values);
3248 return To_Vector (D);
3255 function vminuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3256 VA : constant VUS_View := To_View (To_LL_VUS (A));
3257 VB : constant VUS_View := To_View (To_LL_VUS (B));
3260 D.Values := LL_VUS_Operations.vminux (VA.Values, VB.Values);
3261 return To_LL_VSS (To_Vector (D));
3268 function vminsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3269 VA : constant VSI_View := To_View (A);
3270 VB : constant VSI_View := To_View (B);
3273 D.Values := LL_VSI_Operations.vminsx (VA.Values, VB.Values);
3274 return To_Vector (D);
3281 function vminuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3282 VA : constant VUI_View := To_View (To_LL_VUI (A));
3283 VB : constant VUI_View := To_View (To_LL_VUI (B));
3286 D.Values := LL_VUI_Operations.vminux (VA.Values,
3288 return To_LL_VSI (To_Vector (D));
3295 function vmladduhm (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3296 VA : constant VUS_View := To_View (To_LL_VUS (A));
3297 VB : constant VUS_View := To_View (To_LL_VUS (B));
3298 VC : constant VUS_View := To_View (To_LL_VUS (C));
3302 for J in Varray_unsigned_short'Range loop
3303 D.Values (J) := VA.Values (J) * VB.Values (J)
3307 return To_LL_VSS (To_Vector (D));
3314 function vmhraddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3315 VA : constant VSS_View := To_View (A);
3316 VB : constant VSS_View := To_View (B);
3317 VC : constant VSS_View := To_View (C);
3321 for J in Varray_signed_short'Range loop
3323 LL_VSS_Operations.Saturate (((SI64 (VA.Values (J))
3324 * SI64 (VB.Values (J))
3327 + SI64 (VC.Values (J))));
3330 return To_Vector (D);
3337 function vmsumubm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3338 Offset : Vchar_Range;
3339 VA : constant VUC_View := To_View (To_LL_VUC (A));
3340 VB : constant VUC_View := To_View (To_LL_VUC (B));
3341 VC : constant VUI_View := To_View (To_LL_VUI (C));
3345 for J in 0 .. 3 loop
3346 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3347 D.Values (Vint_Range
3348 (J + Integer (Vint_Range'First))) :=
3349 (unsigned_int (VA.Values (Offset))
3350 * unsigned_int (VB.Values (Offset)))
3351 + (unsigned_int (VA.Values (Offset + 1))
3352 * unsigned_int (VB.Values (1 + Offset)))
3353 + (unsigned_int (VA.Values (2 + Offset))
3354 * unsigned_int (VB.Values (2 + Offset)))
3355 + (unsigned_int (VA.Values (3 + Offset))
3356 * unsigned_int (VB.Values (3 + Offset)))
3357 + VC.Values (Vint_Range
3358 (J + Integer (Varray_unsigned_int'First)));
3361 return To_LL_VSI (To_Vector (D));
3368 function vmsummbm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3369 Offset : Vchar_Range;
3370 VA : constant VSC_View := To_View (A);
3371 VB : constant VUC_View := To_View (To_LL_VUC (B));
3372 VC : constant VSI_View := To_View (C);
3376 for J in 0 .. 3 loop
3377 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3378 D.Values (Vint_Range
3379 (J + Integer (Varray_unsigned_int'First))) := 0
3380 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3381 * SI64 (VB.Values (Offset)))
3382 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3385 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (2 + Offset))
3388 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (3 + Offset))
3391 + VC.Values (Vint_Range
3392 (J + Integer (Varray_unsigned_int'First)));
3395 return To_Vector (D);
3402 function vmsumuhm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3403 Offset : Vshort_Range;
3404 VA : constant VUS_View := To_View (To_LL_VUS (A));
3405 VB : constant VUS_View := To_View (To_LL_VUS (B));
3406 VC : constant VUI_View := To_View (To_LL_VUI (C));
3410 for J in 0 .. 3 loop
3412 Vshort_Range (2 * J + Integer (Vshort_Range'First));
3413 D.Values (Vint_Range
3414 (J + Integer (Varray_unsigned_int'First))) :=
3415 (unsigned_int (VA.Values (Offset))
3416 * unsigned_int (VB.Values (Offset)))
3417 + (unsigned_int (VA.Values (Offset + 1))
3418 * unsigned_int (VB.Values (1 + Offset)))
3419 + VC.Values (Vint_Range
3420 (J + Integer (Vint_Range'First)));
3423 return To_LL_VSI (To_Vector (D));
3430 function vmsumshm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3431 VA : constant VSS_View := To_View (A);
3432 VB : constant VSS_View := To_View (B);
3433 VC : constant VSI_View := To_View (C);
3434 Offset : Vshort_Range;
3438 for J in 0 .. 3 loop
3440 Vshort_Range (2 * J + Integer (Varray_signed_char'First));
3441 D.Values (Vint_Range
3442 (J + Integer (Varray_unsigned_int'First))) := 0
3443 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3444 * SI64 (VB.Values (Offset)))
3445 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3448 + VC.Values (Vint_Range
3449 (J + Integer (Varray_unsigned_int'First)));
3452 return To_Vector (D);
3459 function vmsumuhs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3460 Offset : Vshort_Range;
3461 VA : constant VUS_View := To_View (To_LL_VUS (A));
3462 VB : constant VUS_View := To_View (To_LL_VUS (B));
3463 VC : constant VUI_View := To_View (To_LL_VUI (C));
3467 for J in 0 .. 3 loop
3469 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3470 D.Values (Vint_Range
3471 (J + Integer (Varray_unsigned_int'First))) :=
3472 LL_VUI_Operations.Saturate
3473 (UI64 (VA.Values (Offset))
3474 * UI64 (VB.Values (Offset))
3475 + UI64 (VA.Values (Offset + 1))
3476 * UI64 (VB.Values (1 + Offset))
3479 (J + Integer (Varray_unsigned_int'First)))));
3482 return To_LL_VSI (To_Vector (D));
3489 function vmsumshs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3490 VA : constant VSS_View := To_View (A);
3491 VB : constant VSS_View := To_View (B);
3492 VC : constant VSI_View := To_View (C);
3493 Offset : Vshort_Range;
3497 for J in 0 .. 3 loop
3499 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3500 D.Values (Vint_Range
3501 (J + Integer (Varray_signed_int'First))) :=
3502 LL_VSI_Operations.Saturate
3503 (SI64 (VA.Values (Offset))
3504 * SI64 (VB.Values (Offset))
3505 + SI64 (VA.Values (Offset + 1))
3506 * SI64 (VB.Values (1 + Offset))
3509 (J + Integer (Varray_signed_int'First)))));
3512 return To_Vector (D);
3519 procedure mtvscr (A : LL_VSI) is
3520 VA : constant VUI_View := To_View (To_LL_VUI (A));
3522 VSCR := VA.Values (Varray_unsigned_int'Last);
3529 function vmuleub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3530 VA : constant VUC_View := To_View (To_LL_VUC (A));
3531 VB : constant VUC_View := To_View (To_LL_VUC (B));
3534 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (True,
3537 return To_LL_VSS (To_Vector (D));
3544 function vmuleuh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3545 VA : constant VUS_View := To_View (To_LL_VUS (A));
3546 VB : constant VUS_View := To_View (To_LL_VUS (B));
3549 D.Values := LL_VUS_LL_VUI_Operations.vmulxux (True,
3552 return To_LL_VSI (To_Vector (D));
3559 function vmulesb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3560 VA : constant VSC_View := To_View (A);
3561 VB : constant VSC_View := To_View (B);
3564 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (True,
3567 return To_Vector (D);
3574 function vmulesh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3575 VA : constant VSS_View := To_View (A);
3576 VB : constant VSS_View := To_View (B);
3579 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (True,
3582 return To_Vector (D);
3589 function vmuloub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3590 VA : constant VUC_View := To_View (To_LL_VUC (A));
3591 VB : constant VUC_View := To_View (To_LL_VUC (B));
3594 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (False,
3597 return To_LL_VSS (To_Vector (D));
3604 function vmulouh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3605 VA : constant VUS_View := To_View (To_LL_VUS (A));
3606 VB : constant VUS_View := To_View (To_LL_VUS (B));
3610 LL_VUS_LL_VUI_Operations.vmulxux (False, VA.Values, VB.Values);
3611 return To_LL_VSI (To_Vector (D));
3618 function vmulosb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3619 VA : constant VSC_View := To_View (A);
3620 VB : constant VSC_View := To_View (B);
3623 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (False,
3626 return To_Vector (D);
3633 function vmulosh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3634 VA : constant VSS_View := To_View (A);
3635 VB : constant VSS_View := To_View (B);
3638 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (False,
3641 return To_Vector (D);
3648 function vnmsubfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
3649 VA : constant VF_View := To_View (A);
3650 VB : constant VF_View := To_View (B);
3651 VC : constant VF_View := To_View (C);
3655 for J in Vfloat_Range'Range loop
3657 -Rnd_To_FP_Nearest (F64 (VA.Values (J))
3658 * F64 (VB.Values (J))
3659 - F64 (VC.Values (J)));
3662 return To_Vector (D);
3669 function vnor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3670 VA : constant VUI_View := To_View (To_LL_VUI (A));
3671 VB : constant VUI_View := To_View (To_LL_VUI (B));
3675 for J in Vint_Range'Range loop
3676 D.Values (J) := not (VA.Values (J) or VB.Values (J));
3679 return To_LL_VSI (To_Vector (D));
3686 function vor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3687 VA : constant VUI_View := To_View (To_LL_VUI (A));
3688 VB : constant VUI_View := To_View (To_LL_VUI (B));
3692 for J in Vint_Range'Range loop
3693 D.Values (J) := VA.Values (J) or VB.Values (J);
3696 return To_LL_VSI (To_Vector (D));
3703 function vpkuhum (A : LL_VSS; B : LL_VSS) return LL_VSC is
3704 VA : constant VUS_View := To_View (To_LL_VUS (A));
3705 VB : constant VUS_View := To_View (To_LL_VUS (B));
3708 D.Values := LL_VUC_LL_VUS_Operations.vpkuxum (VA.Values, VB.Values);
3709 return To_LL_VSC (To_Vector (D));
3716 function vpkuwum (A : LL_VSI; B : LL_VSI) return LL_VSS is
3717 VA : constant VUI_View := To_View (To_LL_VUI (A));
3718 VB : constant VUI_View := To_View (To_LL_VUI (B));
3721 D.Values := LL_VUS_LL_VUI_Operations.vpkuxum (VA.Values, VB.Values);
3722 return To_LL_VSS (To_Vector (D));
3729 function vpkpx (A : LL_VSI; B : LL_VSI) return LL_VSS is
3730 VA : constant VUI_View := To_View (To_LL_VUI (A));
3731 VB : constant VUI_View := To_View (To_LL_VUI (B));
3733 Offset : Vint_Range;
3738 for J in 0 .. 3 loop
3739 Offset := Vint_Range (J + Integer (Vshort_Range'First));
3740 P32 := To_Pixel (VA.Values (Offset));
3741 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3742 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3743 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3744 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3745 D.Values (Vshort_Range (Offset)) := To_unsigned_short (P16);
3746 P32 := To_Pixel (VB.Values (Offset));
3747 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3748 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3749 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3750 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3751 D.Values (Vshort_Range (Offset) + 4) := To_unsigned_short (P16);
3754 return To_LL_VSS (To_Vector (D));
3761 function vpkuhus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3762 VA : constant VUS_View := To_View (To_LL_VUS (A));
3763 VB : constant VUS_View := To_View (To_LL_VUS (B));
3766 D.Values := LL_VUC_LL_VUS_Operations.vpkuxus (VA.Values, VB.Values);
3767 return To_LL_VSC (To_Vector (D));
3774 function vpkuwus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3775 VA : constant VUI_View := To_View (To_LL_VUI (A));
3776 VB : constant VUI_View := To_View (To_LL_VUI (B));
3779 D.Values := LL_VUS_LL_VUI_Operations.vpkuxus (VA.Values, VB.Values);
3780 return To_LL_VSS (To_Vector (D));
3787 function vpkshss (A : LL_VSS; B : LL_VSS) return LL_VSC is
3788 VA : constant VSS_View := To_View (A);
3789 VB : constant VSS_View := To_View (B);
3792 D.Values := LL_VSC_LL_VSS_Operations.vpksxss (VA.Values, VB.Values);
3793 return To_Vector (D);
3800 function vpkswss (A : LL_VSI; B : LL_VSI) return LL_VSS is
3801 VA : constant VSI_View := To_View (A);
3802 VB : constant VSI_View := To_View (B);
3805 D.Values := LL_VSS_LL_VSI_Operations.vpksxss (VA.Values, VB.Values);
3806 return To_Vector (D);
3814 type Signed_Component_Type is range <>;
3815 type Signed_Index_Type is range <>;
3816 type Signed_Varray_Type is
3817 array (Signed_Index_Type) of Signed_Component_Type;
3818 type Unsigned_Component_Type is mod <>;
3819 type Unsigned_Index_Type is range <>;
3820 type Unsigned_Varray_Type is
3821 array (Unsigned_Index_Type) of Unsigned_Component_Type;
3824 (A : Signed_Varray_Type;
3825 B : Signed_Varray_Type) return Unsigned_Varray_Type;
3828 (A : Signed_Varray_Type;
3829 B : Signed_Varray_Type) return Unsigned_Varray_Type
3831 N : constant Unsigned_Index_Type :=
3832 Unsigned_Index_Type (Signed_Index_Type'Last);
3833 Offset : Unsigned_Index_Type;
3834 Signed_Offset : Signed_Index_Type;
3835 D : Unsigned_Varray_Type;
3838 (X : Signed_Component_Type) return Unsigned_Component_Type;
3839 -- Saturation, as defined in
3840 -- [PIM-4.1 Vector Status and Control Register]
3847 (X : Signed_Component_Type) return Unsigned_Component_Type
3849 D : Unsigned_Component_Type;
3852 D := Unsigned_Component_Type
3853 (Signed_Component_Type'Max
3854 (Signed_Component_Type (Unsigned_Component_Type'First),
3855 Signed_Component_Type'Min
3856 (Signed_Component_Type (Unsigned_Component_Type'Last),
3858 if Signed_Component_Type (D) /= X then
3859 VSCR := Write_Bit (VSCR, SAT_POS, 1);
3865 -- Start of processing for vpksxus
3868 for J in 0 .. N - 1 loop
3870 Unsigned_Index_Type (Integer (J)
3871 + Integer (Unsigned_Index_Type'First));
3873 Signed_Index_Type (Integer (J)
3874 + Integer (Signed_Index_Type'First));
3875 D (Offset) := Saturate (A (Signed_Offset));
3876 D (Offset + N) := Saturate (B (Signed_Offset));
3886 function vpkshus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3887 function vpkshus_Instance is
3888 new vpksxus (signed_short,
3890 Varray_signed_short,
3893 Varray_unsigned_char);
3895 VA : constant VSS_View := To_View (A);
3896 VB : constant VSS_View := To_View (B);
3900 D.Values := vpkshus_Instance (VA.Values, VB.Values);
3901 return To_LL_VSC (To_Vector (D));
3908 function vpkswus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3909 function vpkswus_Instance is
3910 new vpksxus (signed_int,
3915 Varray_unsigned_short);
3917 VA : constant VSI_View := To_View (A);
3918 VB : constant VSI_View := To_View (B);
3921 D.Values := vpkswus_Instance (VA.Values, VB.Values);
3922 return To_LL_VSS (To_Vector (D));
3929 function vperm_4si (A : LL_VSI; B : LL_VSI; C : LL_VSC) return LL_VSI is
3930 VA : constant VUC_View := To_View (To_LL_VUC (A));
3931 VB : constant VUC_View := To_View (To_LL_VUC (B));
3932 VC : constant VUC_View := To_View (To_LL_VUC (C));
3937 for N in Vchar_Range'Range loop
3938 J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
3939 + Integer (Vchar_Range'First));
3941 if Bits (VC.Values (N), 3, 3) = 0 then
3942 D.Values (N) := VA.Values (J);
3944 D.Values (N) := VB.Values (J);
3948 return To_LL_VSI (To_Vector (D));
3955 function vrefp (A : LL_VF) return LL_VF is
3956 VA : constant VF_View := To_View (A);
3960 for J in Vfloat_Range'Range loop
3961 D.Values (J) := FP_Recip_Est (VA.Values (J));
3964 return To_Vector (D);
3971 function vrlb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3972 VA : constant VUC_View := To_View (To_LL_VUC (A));
3973 VB : constant VUC_View := To_View (To_LL_VUC (B));
3976 D.Values := LL_VUC_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3977 return To_LL_VSC (To_Vector (D));
3984 function vrlh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3985 VA : constant VUS_View := To_View (To_LL_VUS (A));
3986 VB : constant VUS_View := To_View (To_LL_VUS (B));
3989 D.Values := LL_VUS_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3990 return To_LL_VSS (To_Vector (D));
3997 function vrlw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3998 VA : constant VUI_View := To_View (To_LL_VUI (A));
3999 VB : constant VUI_View := To_View (To_LL_VUI (B));
4002 D.Values := LL_VUI_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
4003 return To_LL_VSI (To_Vector (D));
4010 function vrfin (A : LL_VF) return LL_VF is
4011 VA : constant VF_View := To_View (A);
4015 for J in Vfloat_Range'Range loop
4016 D.Values (J) := C_float (Rnd_To_FPI_Near (F64 (VA.Values (J))));
4019 return To_Vector (D);
4026 function vrsqrtefp (A : LL_VF) return LL_VF is
4027 VA : constant VF_View := To_View (A);
4031 for J in Vfloat_Range'Range loop
4032 D.Values (J) := Recip_SQRT_Est (VA.Values (J));
4035 return To_Vector (D);
4042 function vsel_4si (A : LL_VSI; B : LL_VSI; C : LL_VSI) return LL_VSI is
4043 VA : constant VUI_View := To_View (To_LL_VUI (A));
4044 VB : constant VUI_View := To_View (To_LL_VUI (B));
4045 VC : constant VUI_View := To_View (To_LL_VUI (C));
4049 for J in Vint_Range'Range loop
4050 D.Values (J) := ((not VC.Values (J)) and VA.Values (J))
4051 or (VC.Values (J) and VB.Values (J));
4054 return To_LL_VSI (To_Vector (D));
4061 function vslb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4062 VA : constant VUC_View := To_View (To_LL_VUC (A));
4063 VB : constant VUC_View := To_View (To_LL_VUC (B));
4067 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4068 return To_LL_VSC (To_Vector (D));
4075 function vslh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4076 VA : constant VUS_View := To_View (To_LL_VUS (A));
4077 VB : constant VUS_View := To_View (To_LL_VUS (B));
4081 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4082 return To_LL_VSS (To_Vector (D));
4089 function vslw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4090 VA : constant VUI_View := To_View (To_LL_VUI (A));
4091 VB : constant VUI_View := To_View (To_LL_VUI (B));
4095 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4096 return To_LL_VSI (To_Vector (D));
4103 function vsldoi_4si (A : LL_VSI; B : LL_VSI; C : c_int) return LL_VSI is
4104 VA : constant VUC_View := To_View (To_LL_VUC (A));
4105 VB : constant VUC_View := To_View (To_LL_VUC (B));
4111 for J in Vchar_Range'Range loop
4112 Offset := c_int (J) + C;
4113 Bound := c_int (Vchar_Range'First)
4114 + c_int (Varray_unsigned_char'Length);
4116 if Offset < Bound then
4117 D.Values (J) := VA.Values (Vchar_Range (Offset));
4120 VB.Values (Vchar_Range (Offset - Bound
4121 + c_int (Vchar_Range'First)));
4125 return To_LL_VSI (To_Vector (D));
4132 function vsldoi_8hi (A : LL_VSS; B : LL_VSS; C : c_int) return LL_VSS is
4134 return To_LL_VSS (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4141 function vsldoi_16qi (A : LL_VSC; B : LL_VSC; C : c_int) return LL_VSC is
4143 return To_LL_VSC (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4150 function vsldoi_4sf (A : LL_VF; B : LL_VF; C : c_int) return LL_VF is
4152 return To_LL_VF (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4159 function vsl (A : LL_VSI; B : LL_VSI) return LL_VSI is
4160 VA : constant VUI_View := To_View (To_LL_VUI (A));
4161 VB : constant VUI_View := To_View (To_LL_VUI (B));
4163 M : constant Natural :=
4164 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4166 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4167 -- must be the same. Otherwise the value placed into D is undefined."
4168 -- ??? Shall we add a optional check for B?
4171 for J in Vint_Range'Range loop
4173 D.Values (J) := D.Values (J) + Shift_Left (VA.Values (J), M);
4175 if J /= Vint_Range'Last then
4177 D.Values (J) + Shift_Right (VA.Values (J + 1),
4178 signed_int'Size - M);
4182 return To_LL_VSI (To_Vector (D));
4189 function vslo (A : LL_VSI; B : LL_VSI) return LL_VSI is
4190 VA : constant VUC_View := To_View (To_LL_VUC (A));
4191 VB : constant VUC_View := To_View (To_LL_VUC (B));
4193 M : constant Natural :=
4194 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4198 for N in Vchar_Range'Range loop
4199 J := Natural (N) + M;
4201 if J <= Natural (Vchar_Range'Last) then
4202 D.Values (N) := VA.Values (Vchar_Range (J));
4208 return To_LL_VSI (To_Vector (D));
4215 function vspltb (A : LL_VSC; B : c_int) return LL_VSC is
4216 VA : constant VSC_View := To_View (A);
4219 D.Values := LL_VSC_Operations.vspltx (VA.Values, B);
4220 return To_Vector (D);
4227 function vsplth (A : LL_VSS; B : c_int) return LL_VSS is
4228 VA : constant VSS_View := To_View (A);
4231 D.Values := LL_VSS_Operations.vspltx (VA.Values, B);
4232 return To_Vector (D);
4239 function vspltw (A : LL_VSI; B : c_int) return LL_VSI is
4240 VA : constant VSI_View := To_View (A);
4243 D.Values := LL_VSI_Operations.vspltx (VA.Values, B);
4244 return To_Vector (D);
4251 function vspltisb (A : c_int) return LL_VSC is
4254 D.Values := LL_VSC_Operations.vspltisx (A);
4255 return To_Vector (D);
4262 function vspltish (A : c_int) return LL_VSS is
4265 D.Values := LL_VSS_Operations.vspltisx (A);
4266 return To_Vector (D);
4273 function vspltisw (A : c_int) return LL_VSI is
4276 D.Values := LL_VSI_Operations.vspltisx (A);
4277 return To_Vector (D);
4284 function vsrb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4285 VA : constant VUC_View := To_View (To_LL_VUC (A));
4286 VB : constant VUC_View := To_View (To_LL_VUC (B));
4290 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4291 return To_LL_VSC (To_Vector (D));
4298 function vsrh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4299 VA : constant VUS_View := To_View (To_LL_VUS (A));
4300 VB : constant VUS_View := To_View (To_LL_VUS (B));
4304 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4305 return To_LL_VSS (To_Vector (D));
4312 function vsrw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4313 VA : constant VUI_View := To_View (To_LL_VUI (A));
4314 VB : constant VUI_View := To_View (To_LL_VUI (B));
4318 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4319 return To_LL_VSI (To_Vector (D));
4326 function vsrab (A : LL_VSC; B : LL_VSC) return LL_VSC is
4327 VA : constant VSC_View := To_View (A);
4328 VB : constant VSC_View := To_View (B);
4332 LL_VSC_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4333 return To_Vector (D);
4340 function vsrah (A : LL_VSS; B : LL_VSS) return LL_VSS is
4341 VA : constant VSS_View := To_View (A);
4342 VB : constant VSS_View := To_View (B);
4346 LL_VSS_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4347 return To_Vector (D);
4354 function vsraw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4355 VA : constant VSI_View := To_View (A);
4356 VB : constant VSI_View := To_View (B);
4360 LL_VSI_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4361 return To_Vector (D);
4368 function vsr (A : LL_VSI; B : LL_VSI) return LL_VSI is
4369 VA : constant VUI_View := To_View (To_LL_VUI (A));
4370 VB : constant VUI_View := To_View (To_LL_VUI (B));
4371 M : constant Natural :=
4372 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4376 for J in Vint_Range'Range loop
4378 D.Values (J) := D.Values (J) + Shift_Right (VA.Values (J), M);
4380 if J /= Vint_Range'First then
4383 + Shift_Left (VA.Values (J - 1), signed_int'Size - M);
4387 return To_LL_VSI (To_Vector (D));
4394 function vsro (A : LL_VSI; B : LL_VSI) return LL_VSI is
4395 VA : constant VUC_View := To_View (To_LL_VUC (A));
4396 VB : constant VUC_View := To_View (To_LL_VUC (B));
4397 M : constant Natural :=
4398 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4403 for N in Vchar_Range'Range loop
4404 J := Natural (N) - M;
4406 if J >= Natural (Vchar_Range'First) then
4407 D.Values (N) := VA.Values (Vchar_Range (J));
4413 return To_LL_VSI (To_Vector (D));
4420 procedure stvx (A : LL_VSI; B : c_int; C : c_ptr) is
4422 -- Simulate the altivec unit behavior regarding what Effective Address
4423 -- is accessed, stripping off the input address least significant bits
4424 -- wrt to vector alignment (see comment in lvx for further details).
4426 EA : constant System.Address :=
4429 (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4432 for D'Address use EA;
4442 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4443 VA : constant VSC_View := To_View (A);
4445 LL_VSC_Operations.stvexx (VA.Values, B, C);
4452 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4453 VA : constant VSS_View := To_View (A);
4455 LL_VSS_Operations.stvexx (VA.Values, B, C);
4462 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4463 VA : constant VSI_View := To_View (A);
4465 LL_VSI_Operations.stvexx (VA.Values, B, C);
4472 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4478 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4479 VA : constant VUC_View := To_View (To_LL_VUC (A));
4480 VB : constant VUC_View := To_View (To_LL_VUC (B));
4483 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4484 return To_LL_VSC (To_Vector (D));
4491 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4492 VA : constant VUS_View := To_View (To_LL_VUS (A));
4493 VB : constant VUS_View := To_View (To_LL_VUS (B));
4496 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4497 return To_LL_VSS (To_Vector (D));
4504 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4505 VA : constant VUI_View := To_View (To_LL_VUI (A));
4506 VB : constant VUI_View := To_View (To_LL_VUI (B));
4509 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4510 return To_LL_VSI (To_Vector (D));
4517 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4518 VA : constant VF_View := To_View (A);
4519 VB : constant VF_View := To_View (B);
4523 for J in Vfloat_Range'Range loop
4525 NJ_Truncate (NJ_Truncate (VA.Values (J))
4526 - NJ_Truncate (VB.Values (J)));
4529 return To_Vector (D);
4536 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4537 Subst_Result : SI64;
4539 VA : constant VUI_View := To_View (To_LL_VUI (A));
4540 VB : constant VUI_View := To_View (To_LL_VUI (B));
4544 for J in Vint_Range'Range loop
4545 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4547 if Subst_Result < SI64 (unsigned_int'First) then
4554 return To_LL_VSI (To_Vector (D));
4561 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4562 VA : constant VUC_View := To_View (To_LL_VUC (A));
4563 VB : constant VUC_View := To_View (To_LL_VUC (B));
4566 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4567 return To_LL_VSC (To_Vector (D));
4574 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4575 VA : constant VSC_View := To_View (A);
4576 VB : constant VSC_View := To_View (B);
4579 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4580 return To_Vector (D);
4587 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4588 VA : constant VUS_View := To_View (To_LL_VUS (A));
4589 VB : constant VUS_View := To_View (To_LL_VUS (B));
4592 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4593 return To_LL_VSS (To_Vector (D));
4600 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4601 VA : constant VSS_View := To_View (A);
4602 VB : constant VSS_View := To_View (B);
4605 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4606 return To_Vector (D);
4613 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4614 VA : constant VUI_View := To_View (To_LL_VUI (A));
4615 VB : constant VUI_View := To_View (To_LL_VUI (B));
4618 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4619 return To_LL_VSI (To_Vector (D));
4626 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4627 VA : constant VSI_View := To_View (A);
4628 VB : constant VSI_View := To_View (B);
4631 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4632 return To_Vector (D);
4639 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4640 VA : constant VUC_View := To_View (To_LL_VUC (A));
4641 VB : constant VUI_View := To_View (To_LL_VUI (B));
4642 Offset : Vchar_Range;
4646 for J in 0 .. 3 loop
4647 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4648 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4649 LL_VUI_Operations.Saturate
4650 (UI64 (VA.Values (Offset))
4651 + UI64 (VA.Values (Offset + 1))
4652 + UI64 (VA.Values (Offset + 2))
4653 + UI64 (VA.Values (Offset + 3))
4654 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4657 return To_LL_VSI (To_Vector (D));
4664 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4665 VA : constant VSC_View := To_View (A);
4666 VB : constant VSI_View := To_View (B);
4667 Offset : Vchar_Range;
4671 for J in 0 .. 3 loop
4672 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4673 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4674 LL_VSI_Operations.Saturate
4675 (SI64 (VA.Values (Offset))
4676 + SI64 (VA.Values (Offset + 1))
4677 + SI64 (VA.Values (Offset + 2))
4678 + SI64 (VA.Values (Offset + 3))
4679 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4682 return To_Vector (D);
4689 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4690 VA : constant VSS_View := To_View (A);
4691 VB : constant VSI_View := To_View (B);
4692 Offset : Vshort_Range;
4696 for J in 0 .. 3 loop
4697 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4698 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4699 LL_VSI_Operations.Saturate
4700 (SI64 (VA.Values (Offset))
4701 + SI64 (VA.Values (Offset + 1))
4702 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4705 return To_Vector (D);
4712 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4713 VA : constant VSI_View := To_View (A);
4714 VB : constant VSI_View := To_View (B);
4715 Offset : Vint_Range;
4719 for J in 0 .. 1 loop
4720 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4721 D.Values (Offset) := 0;
4722 D.Values (Offset + 1) :=
4723 LL_VSI_Operations.Saturate
4724 (SI64 (VA.Values (Offset))
4725 + SI64 (VA.Values (Offset + 1))
4726 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4729 return To_Vector (D);
4736 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4737 VA : constant VSI_View := To_View (A);
4738 VB : constant VSI_View := To_View (B);
4740 Sum_Buffer : SI64 := 0;
4743 for J in Vint_Range'Range loop
4745 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4748 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4749 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4750 return To_Vector (D);
4757 function vrfiz (A : LL_VF) return LL_VF is
4758 VA : constant VF_View := To_View (A);
4761 for J in Vfloat_Range'Range loop
4762 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4765 return To_Vector (D);
4772 function vupkhsb (A : LL_VSC) return LL_VSS is
4773 VA : constant VSC_View := To_View (A);
4776 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4777 return To_Vector (D);
4784 function vupkhsh (A : LL_VSS) return LL_VSI is
4785 VA : constant VSS_View := To_View (A);
4788 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4789 return To_Vector (D);
4796 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4797 -- For vupkhpx and vupklpx (depending on Offset)
4799 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4800 VA : constant VUS_View := To_View (To_LL_VUS (A));
4806 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4808 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4818 for J in Vint_Range'Range loop
4819 K := Vshort_Range (Integer (J)
4820 - Integer (Vint_Range'First)
4821 + Integer (Vshort_Range'First)
4823 P16 := To_Pixel (VA.Values (K));
4824 P32.T := Sign_Extend (P16.T);
4825 P32.R := unsigned_char (P16.R);
4826 P32.G := unsigned_char (P16.G);
4827 P32.B := unsigned_char (P16.B);
4828 D.Values (J) := To_unsigned_int (P32);
4831 return To_LL_VSI (To_Vector (D));
4838 function vupkhpx (A : LL_VSS) return LL_VSI is
4840 return vupkxpx (A, 0);
4847 function vupklsb (A : LL_VSC) return LL_VSS is
4848 VA : constant VSC_View := To_View (A);
4852 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4853 Varray_signed_short'Length);
4854 return To_Vector (D);
4861 function vupklsh (A : LL_VSS) return LL_VSI is
4862 VA : constant VSS_View := To_View (A);
4866 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4867 Varray_signed_int'Length);
4868 return To_Vector (D);
4875 function vupklpx (A : LL_VSS) return LL_VSI is
4877 return vupkxpx (A, Varray_signed_int'Length);
4884 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4885 VA : constant VUI_View := To_View (To_LL_VUI (A));
4886 VB : constant VUI_View := To_View (To_LL_VUI (B));
4890 for J in Vint_Range'Range loop
4891 D.Values (J) := VA.Values (J) xor VB.Values (J);
4894 return To_LL_VSI (To_Vector (D));
4901 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4904 D := vcmpequb (B, C);
4905 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4912 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4915 D := vcmpequh (B, C);
4916 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4923 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4926 D := vcmpequw (B, C);
4927 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4934 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4937 D := vcmpeqfp (B, C);
4938 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4945 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4948 D := vcmpgtub (B, C);
4949 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4956 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4959 D := vcmpgtuh (B, C);
4960 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4967 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4970 D := vcmpgtuw (B, C);
4971 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4978 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4981 D := vcmpgtsb (B, C);
4982 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4989 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4992 D := vcmpgtsh (B, C);
4993 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
5000 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
5003 D := vcmpgtsw (B, C);
5004 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5011 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5014 D := vcmpgefp (B, C);
5015 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5022 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5025 D := vcmpgtfp (B, C);
5026 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5033 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5036 D := To_View (vcmpbfp (B, C));
5038 for J in Vint_Range'Range loop
5039 -- vcmpbfp is not returning the usual bool vector; do the conversion
5040 if D.Values (J) = 0 then
5041 D.Values (J) := Signed_Bool_False;
5043 D.Values (J) := Signed_Bool_True;
5047 return LL_VSI_Operations.Check_CR6 (A, D.Values);
5050 end GNAT.Altivec.Low_Level_Vectors;