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-2009, 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 3, 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. --
19 -- As a special exception under Section 7 of GPL version 3, you are granted --
20 -- additional permissions described in the GCC Runtime Library Exception, --
21 -- version 3.1, as published by the Free Software Foundation. --
23 -- You should have received a copy of the GNU General Public License and --
24 -- a copy of the GCC Runtime Library Exception along with this program; --
25 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
26 -- <http://www.gnu.org/licenses/>. --
28 -- GNAT was originally developed by the GNAT team at New York University. --
29 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 ------------------------------------------------------------------------------
33 -- ??? What is exactly needed for the soft case is still a bit unclear on
34 -- some accounts. The expected functional equivalence with the Hard binding
35 -- might require tricky things to be done on some targets.
37 -- Examples that come to mind are endianness variations or differences in the
38 -- base FP model while we need the operation results to be the same as what
39 -- the real AltiVec instructions would do on a PowerPC.
41 with Ada.Numerics.Generic_Elementary_Functions;
42 with Interfaces; use Interfaces;
43 with System.Storage_Elements; use System.Storage_Elements;
45 with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions;
46 with GNAT.Altivec.Low_Level_Interface; use GNAT.Altivec.Low_Level_Interface;
48 package body GNAT.Altivec.Low_Level_Vectors is
50 -- Pixel types. As defined in [PIM-2.1 Data types]:
51 -- A 16-bit pixel is 1/5/5/5;
52 -- A 32-bit pixel is 8/8/8/8.
53 -- We use the following records as an intermediate representation, to
56 type Unsigned_1 is mod 2 ** 1;
57 type Unsigned_5 is mod 2 ** 5;
59 type Pixel_16 is record
66 type Pixel_32 is record
73 -- Conversions to/from the pixel records to the integer types that are
74 -- actually stored into the pixel vectors:
76 function To_Pixel (Source : unsigned_short) return Pixel_16;
77 function To_unsigned_short (Source : Pixel_16) return unsigned_short;
78 function To_Pixel (Source : unsigned_int) return Pixel_32;
79 function To_unsigned_int (Source : Pixel_32) return unsigned_int;
81 package C_float_Operations is
82 new Ada.Numerics.Generic_Elementary_Functions (C_float);
84 -- Model of the Vector Status and Control Register (VSCR), as
85 -- defined in [PIM-4.1 Vector Status and Control Register]:
89 -- Positions of the flags in VSCR(0 .. 31):
91 NJ_POS : constant := 15;
92 SAT_POS : constant := 31;
94 -- To control overflows, integer operations are done on 64-bit types:
96 SINT64_MIN : constant := -2 ** 63;
97 SINT64_MAX : constant := 2 ** 63 - 1;
98 UINT64_MAX : constant := 2 ** 64 - 1;
100 type SI64 is range SINT64_MIN .. SINT64_MAX;
101 type UI64 is mod UINT64_MAX + 1;
103 type F64 is digits 15
104 range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
109 High : Natural) return unsigned_int;
114 High : Natural) return unsigned_short;
119 High : Natural) return unsigned_char;
124 Value : Unsigned_1) return unsigned_int;
129 Value : Unsigned_1) return unsigned_short;
134 Value : Unsigned_1) return unsigned_char;
136 function NJ_Truncate (X : C_float) return C_float;
137 -- If NJ and A is a denormalized number, return zero
140 (X : Integer_Address;
141 Y : Integer_Address) return Integer_Address;
142 -- [PIM-4.3 Notations and Conventions]
143 -- Align X in a y-byte boundary and return the result
145 function Rnd_To_FP_Nearest (X : F64) return C_float;
146 -- [PIM-4.3 Notations and Conventions]
148 function Rnd_To_FPI_Near (X : F64) return F64;
150 function Rnd_To_FPI_Trunc (X : F64) return F64;
152 function FP_Recip_Est (X : C_float) return C_float;
153 -- [PIM-4.3 Notations and Conventions]
154 -- 12-bit accurate floating-point estimate of 1/x
157 (Value : unsigned_char;
158 Amount : Natural) return unsigned_char;
159 -- [PIM-4.3 Notations and Conventions]
163 (Value : unsigned_short;
164 Amount : Natural) return unsigned_short;
167 (Value : unsigned_int;
168 Amount : Natural) return unsigned_int;
170 function Recip_SQRT_Est (X : C_float) return C_float;
173 (Value : unsigned_char;
174 Amount : Natural) return unsigned_char;
175 -- [PIM-4.3 Notations and Conventions]
179 (Value : unsigned_short;
180 Amount : Natural) return unsigned_short;
183 (Value : unsigned_int;
184 Amount : Natural) return unsigned_int;
187 (Value : unsigned_char;
188 Amount : Natural) return unsigned_char;
189 -- [PIM-4.3 Notations and Conventions]
193 (Value : unsigned_short;
194 Amount : Natural) return unsigned_short;
197 (Value : unsigned_int;
198 Amount : Natural) return unsigned_int;
200 Signed_Bool_False : constant := 0;
201 Signed_Bool_True : constant := -1;
203 ------------------------------
204 -- Signed_Operations (spec) --
205 ------------------------------
208 type Component_Type is range <>;
209 type Index_Type is range <>;
210 type Varray_Type is array (Index_Type) of Component_Type;
212 package Signed_Operations is
214 function Modular_Result (X : SI64) return Component_Type;
216 function Saturate (X : SI64) return Component_Type;
218 function Saturate (X : F64) return Component_Type;
220 function Sign_Extend (X : c_int) return Component_Type;
221 -- [PIM-4.3 Notations and Conventions]
224 function abs_vxi (A : Varray_Type) return Varray_Type;
225 pragma Convention (LL_Altivec, abs_vxi);
227 function abss_vxi (A : Varray_Type) return Varray_Type;
228 pragma Convention (LL_Altivec, abss_vxi);
230 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
231 pragma Convention (LL_Altivec, vaddsxs);
233 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
234 pragma Convention (LL_Altivec, vavgsx);
236 function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
237 pragma Convention (LL_Altivec, vcmpgtsx);
239 function lvexx (A : c_long; B : c_ptr) return Varray_Type;
240 pragma Convention (LL_Altivec, lvexx);
242 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
243 pragma Convention (LL_Altivec, vmaxsx);
245 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
246 pragma Convention (LL_Altivec, vmrghx);
248 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
249 pragma Convention (LL_Altivec, vmrglx);
251 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
252 pragma Convention (LL_Altivec, vminsx);
254 function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
255 pragma Convention (LL_Altivec, vspltx);
257 function vspltisx (A : c_int) return Varray_Type;
258 pragma Convention (LL_Altivec, vspltisx);
260 type Bit_Operation is
262 (Value : Component_Type;
263 Amount : Natural) return Component_Type;
268 Shift_Func : Bit_Operation) return Varray_Type;
270 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
271 pragma Convention (LL_Altivec, stvexx);
273 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
274 pragma Convention (LL_Altivec, vsubsxs);
276 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
277 -- If D is the result of a vcmp operation and A the flag for
278 -- the kind of operation (e.g CR6_LT), check the predicate
279 -- that corresponds to this flag.
281 end Signed_Operations;
283 ------------------------------
284 -- Signed_Operations (body) --
285 ------------------------------
287 package body Signed_Operations is
289 Bool_True : constant Component_Type := Signed_Bool_True;
290 Bool_False : constant Component_Type := Signed_Bool_False;
292 Number_Of_Elements : constant Integer :=
293 VECTOR_BIT / Component_Type'Size;
299 function Modular_Result (X : SI64) return Component_Type is
304 D := Component_Type (UI64 (X)
305 mod (UI64 (Component_Type'Last) + 1));
307 D := Component_Type ((-(UI64 (-X)
308 mod (UI64 (Component_Type'Last) + 1))));
318 function Saturate (X : SI64) return Component_Type is
322 -- Saturation, as defined in
323 -- [PIM-4.1 Vector Status and Control Register]
325 D := Component_Type (SI64'Max
326 (SI64 (Component_Type'First),
328 (SI64 (Component_Type'Last),
331 if SI64 (D) /= X then
332 VSCR := Write_Bit (VSCR, SAT_POS, 1);
338 function Saturate (X : F64) return Component_Type is
342 -- Saturation, as defined in
343 -- [PIM-4.1 Vector Status and Control Register]
345 D := Component_Type (F64'Max
346 (F64 (Component_Type'First),
348 (F64 (Component_Type'Last),
352 VSCR := Write_Bit (VSCR, SAT_POS, 1);
362 function Sign_Extend (X : c_int) return Component_Type is
364 -- X is usually a 5-bits literal. In the case of the simulator,
365 -- it is an integral parameter, so sign extension is straightforward.
367 return Component_Type (X);
374 function abs_vxi (A : Varray_Type) return Varray_Type is
378 for K in Varray_Type'Range loop
379 if A (K) /= Component_Type'First then
380 D (K) := abs (A (K));
382 D (K) := Component_Type'First;
393 function abss_vxi (A : Varray_Type) return Varray_Type is
397 for K in Varray_Type'Range loop
398 D (K) := Saturate (abs (SI64 (A (K))));
408 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
412 for J in Varray_Type'Range loop
413 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
423 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
427 for J in Varray_Type'Range loop
428 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
440 B : Varray_Type) return Varray_Type
445 for J in Varray_Type'Range loop
446 if A (J) > B (J) then
460 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
463 EA : Integer_Address;
467 S := 16 / Number_Of_Elements;
468 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
469 Integer_Address (S));
470 J := Index_Type (((EA mod 16) / Integer_Address (S))
471 + Integer_Address (Index_Type'First));
474 Component : Component_Type;
475 for Component'Address use To_Address (EA);
487 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
491 for J in Varray_Type'Range loop
492 if A (J) > B (J) then
506 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
508 Offset : constant Integer := Integer (Index_Type'First);
509 M : constant Integer := Number_Of_Elements / 2;
512 for J in 0 .. M - 1 loop
513 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
514 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
524 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
526 Offset : constant Integer := Integer (Index_Type'First);
527 M : constant Integer := Number_Of_Elements / 2;
530 for J in 0 .. M - 1 loop
531 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
532 D (Index_Type (2 * J + Offset + 1)) :=
533 B (Index_Type (J + Offset + M));
543 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
547 for J in Varray_Type'Range loop
548 if A (J) < B (J) then
562 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
563 J : constant Integer :=
564 Integer (B) mod Number_Of_Elements
565 + Integer (Varray_Type'First);
569 for K in Varray_Type'Range loop
570 D (K) := A (Index_Type (J));
580 function vspltisx (A : c_int) return Varray_Type is
584 for J in Varray_Type'Range loop
585 D (J) := Sign_Extend (A);
598 Shift_Func : Bit_Operation) return Varray_Type
601 S : constant Component_Type :=
602 Component_Type (128 / Number_Of_Elements);
605 for J in Varray_Type'Range loop
606 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
616 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
618 EA : Integer_Address;
622 S := 16 / Number_Of_Elements;
623 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
624 Integer_Address (S));
625 J := Index_Type ((EA mod 16) / Integer_Address (S)
626 + Integer_Address (Index_Type'First));
629 Component : Component_Type;
630 for Component'Address use To_Address (EA);
640 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
644 for J in Varray_Type'Range loop
645 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
655 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
656 All_Element : Boolean := True;
657 Any_Element : Boolean := False;
660 for J in Varray_Type'Range loop
661 All_Element := All_Element and then (D (J) = Bool_True);
662 Any_Element := Any_Element or else (D (J) = Bool_True);
672 elsif A = CR6_EQ then
673 if not Any_Element then
679 elsif A = CR6_EQ_REV then
686 elsif A = CR6_LT_REV then
687 if not All_Element then
697 end Signed_Operations;
699 --------------------------------
700 -- Unsigned_Operations (spec) --
701 --------------------------------
704 type Component_Type is mod <>;
705 type Index_Type is range <>;
706 type Varray_Type is array (Index_Type) of Component_Type;
708 package Unsigned_Operations is
713 High : Natural) return Component_Type;
714 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
715 -- using big endian bit ordering.
720 Value : Unsigned_1) return Component_Type;
721 -- Write Value into X[Where:Where] (if it fits in) and return the result
722 -- (big endian bit ordering).
724 function Modular_Result (X : UI64) return Component_Type;
726 function Saturate (X : UI64) return Component_Type;
728 function Saturate (X : F64) return Component_Type;
730 function Saturate (X : SI64) return Component_Type;
732 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
734 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
736 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
738 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
740 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
742 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
744 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
746 type Bit_Operation is
748 (Value : Component_Type;
749 Amount : Natural) return Component_Type;
754 ROTL : Bit_Operation) return Varray_Type;
759 Shift_Func : Bit_Operation) return Varray_Type;
760 -- Vector shift (left or right, depending on Shift_Func)
762 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
764 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
766 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
767 -- If D is the result of a vcmp operation and A the flag for
768 -- the kind of operation (e.g CR6_LT), check the predicate
769 -- that corresponds to this flag.
771 end Unsigned_Operations;
773 --------------------------------
774 -- Unsigned_Operations (body) --
775 --------------------------------
777 package body Unsigned_Operations is
779 Number_Of_Elements : constant Integer :=
780 VECTOR_BIT / Component_Type'Size;
782 Bool_True : constant Component_Type := Component_Type'Last;
783 Bool_False : constant Component_Type := 0;
789 function Modular_Result (X : UI64) return Component_Type is
792 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
800 function Saturate (X : UI64) return Component_Type is
804 -- Saturation, as defined in
805 -- [PIM-4.1 Vector Status and Control Register]
807 D := Component_Type (UI64'Max
808 (UI64 (Component_Type'First),
810 (UI64 (Component_Type'Last),
813 if UI64 (D) /= X then
814 VSCR := Write_Bit (VSCR, SAT_POS, 1);
820 function Saturate (X : SI64) return Component_Type is
824 -- Saturation, as defined in
825 -- [PIM-4.1 Vector Status and Control Register]
827 D := Component_Type (SI64'Max
828 (SI64 (Component_Type'First),
830 (SI64 (Component_Type'Last),
833 if SI64 (D) /= X then
834 VSCR := Write_Bit (VSCR, SAT_POS, 1);
840 function Saturate (X : F64) return Component_Type is
844 -- Saturation, as defined in
845 -- [PIM-4.1 Vector Status and Control Register]
847 D := Component_Type (F64'Max
848 (F64 (Component_Type'First),
850 (F64 (Component_Type'Last),
854 VSCR := Write_Bit (VSCR, SAT_POS, 1);
867 High : Natural) return Component_Type
869 Mask : Component_Type := 0;
871 -- The Altivec ABI uses a big endian bit ordering, and we are
872 -- using little endian bit ordering for extracting bits:
874 Low_LE : constant Natural := Component_Type'Size - 1 - High;
875 High_LE : constant Natural := Component_Type'Size - 1 - Low;
878 pragma Assert (Low <= Component_Type'Size);
879 pragma Assert (High <= Component_Type'Size);
881 for J in Low_LE .. High_LE loop
882 Mask := Mask or 2 ** J;
885 return (X and Mask) / 2 ** Low_LE;
895 Value : Unsigned_1) return Component_Type
897 Result : Component_Type := 0;
899 -- The Altivec ABI uses a big endian bit ordering, and we are
900 -- using little endian bit ordering for extracting bits:
902 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
905 pragma Assert (Where < Component_Type'Size);
909 Result := X or 2 ** Where_LE;
911 Result := X and not (2 ** Where_LE);
921 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
925 for J in Varray_Type'Range loop
926 D (J) := A (J) + B (J);
936 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
940 for J in Varray_Type'Range loop
941 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
951 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
955 for J in Varray_Type'Range loop
956 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
968 B : Varray_Type) return Varray_Type
973 for J in Varray_Type'Range loop
974 if A (J) = B (J) then
990 B : Varray_Type) return Varray_Type
994 for J in Varray_Type'Range loop
995 if A (J) > B (J) then
1009 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1013 for J in Varray_Type'Range loop
1014 if A (J) > B (J) then
1028 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1032 for J in Varray_Type'Range loop
1033 if A (J) < B (J) then
1050 ROTL : Bit_Operation) return Varray_Type
1055 for J in Varray_Type'Range loop
1056 D (J) := ROTL (A (J), Natural (B (J)));
1069 Shift_Func : Bit_Operation) return Varray_Type
1072 S : constant Component_Type :=
1073 Component_Type (128 / Number_Of_Elements);
1076 for J in Varray_Type'Range loop
1077 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1087 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1091 for J in Varray_Type'Range loop
1092 D (J) := A (J) - B (J);
1102 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1106 for J in Varray_Type'Range loop
1107 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1117 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1118 All_Element : Boolean := True;
1119 Any_Element : Boolean := False;
1122 for J in Varray_Type'Range loop
1123 All_Element := All_Element and then (D (J) = Bool_True);
1124 Any_Element := Any_Element or else (D (J) = Bool_True);
1134 elsif A = CR6_EQ then
1135 if not Any_Element then
1141 elsif A = CR6_EQ_REV then
1148 elsif A = CR6_LT_REV then
1149 if not All_Element then
1159 end Unsigned_Operations;
1161 --------------------------------------
1162 -- Signed_Merging_Operations (spec) --
1163 --------------------------------------
1166 type Component_Type is range <>;
1167 type Index_Type is range <>;
1168 type Varray_Type is array (Index_Type) of Component_Type;
1169 type Double_Component_Type is range <>;
1170 type Double_Index_Type is range <>;
1171 type Double_Varray_Type is array (Double_Index_Type)
1172 of Double_Component_Type;
1174 package Signed_Merging_Operations is
1176 pragma Assert (Integer (Varray_Type'First)
1177 = Integer (Double_Varray_Type'First));
1178 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1179 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1182 (X : Double_Component_Type) return Component_Type;
1185 (Use_Even_Components : Boolean;
1187 B : Varray_Type) return Double_Varray_Type;
1190 (A : Double_Varray_Type;
1191 B : Double_Varray_Type) return Varray_Type;
1192 pragma Convention (LL_Altivec, vpksxss);
1196 Offset : Natural) return Double_Varray_Type;
1198 end Signed_Merging_Operations;
1200 --------------------------------------
1201 -- Signed_Merging_Operations (body) --
1202 --------------------------------------
1204 package body Signed_Merging_Operations is
1211 (X : Double_Component_Type) return Component_Type
1216 -- Saturation, as defined in
1217 -- [PIM-4.1 Vector Status and Control Register]
1219 D := Component_Type (Double_Component_Type'Max
1220 (Double_Component_Type (Component_Type'First),
1221 Double_Component_Type'Min
1222 (Double_Component_Type (Component_Type'Last),
1225 if Double_Component_Type (D) /= X then
1226 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1237 (Use_Even_Components : Boolean;
1239 B : Varray_Type) return Double_Varray_Type
1241 Double_Offset : Double_Index_Type;
1242 Offset : Index_Type;
1243 D : Double_Varray_Type;
1244 N : constant Integer :=
1245 Integer (Double_Index_Type'Last)
1246 - Integer (Double_Index_Type'First) + 1;
1250 for J in 0 .. N - 1 loop
1251 if Use_Even_Components then
1252 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1254 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1258 Double_Index_Type (J + Integer (Double_Index_Type'First));
1259 D (Double_Offset) :=
1260 Double_Component_Type (A (Offset))
1261 * Double_Component_Type (B (Offset));
1272 (A : Double_Varray_Type;
1273 B : Double_Varray_Type) return Varray_Type
1275 N : constant Index_Type :=
1276 Index_Type (Double_Index_Type'Last);
1278 Offset : Index_Type;
1279 Double_Offset : Double_Index_Type;
1282 for J in 0 .. N - 1 loop
1283 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1285 Double_Index_Type (Integer (J)
1286 + Integer (Double_Index_Type'First));
1287 D (Offset) := Saturate (A (Double_Offset));
1288 D (Offset + N) := Saturate (B (Double_Offset));
1300 Offset : Natural) return Double_Varray_Type
1303 D : Double_Varray_Type;
1306 for J in Double_Varray_Type'Range loop
1307 K := Index_Type (Integer (J)
1308 - Integer (Double_Index_Type'First)
1309 + Integer (Index_Type'First)
1311 D (J) := Double_Component_Type (A (K));
1317 end Signed_Merging_Operations;
1319 ----------------------------------------
1320 -- Unsigned_Merging_Operations (spec) --
1321 ----------------------------------------
1324 type Component_Type is mod <>;
1325 type Index_Type is range <>;
1326 type Varray_Type is array (Index_Type) of Component_Type;
1327 type Double_Component_Type is mod <>;
1328 type Double_Index_Type is range <>;
1329 type Double_Varray_Type is array (Double_Index_Type)
1330 of Double_Component_Type;
1332 package Unsigned_Merging_Operations is
1334 pragma Assert (Integer (Varray_Type'First)
1335 = Integer (Double_Varray_Type'First));
1336 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1337 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1339 function UI_To_UI_Mod
1340 (X : Double_Component_Type;
1341 Y : Natural) return Component_Type;
1343 function Saturate (X : Double_Component_Type) return Component_Type;
1346 (Use_Even_Components : Boolean;
1348 B : Varray_Type) return Double_Varray_Type;
1351 (A : Double_Varray_Type;
1352 B : Double_Varray_Type) return Varray_Type;
1355 (A : Double_Varray_Type;
1356 B : Double_Varray_Type) return Varray_Type;
1358 end Unsigned_Merging_Operations;
1360 ----------------------------------------
1361 -- Unsigned_Merging_Operations (body) --
1362 ----------------------------------------
1364 package body Unsigned_Merging_Operations is
1370 function UI_To_UI_Mod
1371 (X : Double_Component_Type;
1372 Y : Natural) return Component_Type is
1375 Z := Component_Type (X mod 2 ** Y);
1383 function Saturate (X : Double_Component_Type) return Component_Type is
1387 -- Saturation, as defined in
1388 -- [PIM-4.1 Vector Status and Control Register]
1390 D := Component_Type (Double_Component_Type'Max
1391 (Double_Component_Type (Component_Type'First),
1392 Double_Component_Type'Min
1393 (Double_Component_Type (Component_Type'Last),
1396 if Double_Component_Type (D) /= X then
1397 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1408 (Use_Even_Components : Boolean;
1410 B : Varray_Type) return Double_Varray_Type
1412 Double_Offset : Double_Index_Type;
1413 Offset : Index_Type;
1414 D : Double_Varray_Type;
1415 N : constant Integer :=
1416 Integer (Double_Index_Type'Last)
1417 - Integer (Double_Index_Type'First) + 1;
1420 for J in 0 .. N - 1 loop
1421 if Use_Even_Components then
1422 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1424 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1428 Double_Index_Type (J + Integer (Double_Index_Type'First));
1429 D (Double_Offset) :=
1430 Double_Component_Type (A (Offset))
1431 * Double_Component_Type (B (Offset));
1442 (A : Double_Varray_Type;
1443 B : Double_Varray_Type) return Varray_Type
1445 S : constant Natural :=
1446 Double_Component_Type'Size / 2;
1447 N : constant Index_Type :=
1448 Index_Type (Double_Index_Type'Last);
1450 Offset : Index_Type;
1451 Double_Offset : Double_Index_Type;
1454 for J in 0 .. N - 1 loop
1455 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1457 Double_Index_Type (Integer (J)
1458 + Integer (Double_Index_Type'First));
1459 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1460 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1471 (A : Double_Varray_Type;
1472 B : Double_Varray_Type) return Varray_Type
1474 N : constant Index_Type :=
1475 Index_Type (Double_Index_Type'Last);
1477 Offset : Index_Type;
1478 Double_Offset : Double_Index_Type;
1481 for J in 0 .. N - 1 loop
1482 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1484 Double_Index_Type (Integer (J)
1485 + Integer (Double_Index_Type'First));
1486 D (Offset) := Saturate (A (Double_Offset));
1487 D (Offset + N) := Saturate (B (Double_Offset));
1493 end Unsigned_Merging_Operations;
1495 package LL_VSC_Operations is
1496 new Signed_Operations (signed_char,
1498 Varray_signed_char);
1500 package LL_VSS_Operations is
1501 new Signed_Operations (signed_short,
1503 Varray_signed_short);
1505 package LL_VSI_Operations is
1506 new Signed_Operations (signed_int,
1510 package LL_VUC_Operations is
1511 new Unsigned_Operations (unsigned_char,
1513 Varray_unsigned_char);
1515 package LL_VUS_Operations is
1516 new Unsigned_Operations (unsigned_short,
1518 Varray_unsigned_short);
1520 package LL_VUI_Operations is
1521 new Unsigned_Operations (unsigned_int,
1523 Varray_unsigned_int);
1525 package LL_VSC_LL_VSS_Operations is
1526 new Signed_Merging_Operations (signed_char,
1531 Varray_signed_short);
1533 package LL_VSS_LL_VSI_Operations is
1534 new Signed_Merging_Operations (signed_short,
1536 Varray_signed_short,
1541 package LL_VUC_LL_VUS_Operations is
1542 new Unsigned_Merging_Operations (unsigned_char,
1544 Varray_unsigned_char,
1547 Varray_unsigned_short);
1549 package LL_VUS_LL_VUI_Operations is
1550 new Unsigned_Merging_Operations (unsigned_short,
1552 Varray_unsigned_short,
1555 Varray_unsigned_int);
1564 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1567 (X : unsigned_short;
1569 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1574 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1583 Value : Unsigned_1) return unsigned_int
1584 renames LL_VUI_Operations.Write_Bit;
1587 (X : unsigned_short;
1589 Value : Unsigned_1) return unsigned_short
1590 renames LL_VUS_Operations.Write_Bit;
1595 Value : Unsigned_1) return unsigned_char
1596 renames LL_VUC_Operations.Write_Bit;
1602 function Bound_Align
1603 (X : Integer_Address;
1604 Y : Integer_Address) return Integer_Address
1606 D : Integer_Address;
1616 function NJ_Truncate (X : C_float) return C_float is
1620 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1621 and then abs (X) < 2.0 ** (-126)
1635 -----------------------
1636 -- Rnd_To_FP_Nearest --
1637 -----------------------
1639 function Rnd_To_FP_Nearest (X : F64) return C_float is
1642 end Rnd_To_FP_Nearest;
1644 ---------------------
1645 -- Rnd_To_FPI_Near --
1646 ---------------------
1648 function Rnd_To_FPI_Near (X : F64) return F64 is
1652 Result := F64 (SI64 (X));
1654 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1656 Ceiling := F64'Ceiling (X);
1657 if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling then
1660 Result := Ceiling - 1.0;
1665 end Rnd_To_FPI_Near;
1667 ----------------------
1668 -- Rnd_To_FPI_Trunc --
1669 ----------------------
1671 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1675 Result := F64'Ceiling (X);
1677 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1681 and then Result /= X
1683 Result := Result - 1.0;
1687 end Rnd_To_FPI_Trunc;
1693 function FP_Recip_Est (X : C_float) return C_float is
1695 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1696 -- -Inf, or QNaN, the estimate has a relative error no greater
1697 -- than one part in 4096, that is:
1698 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1700 return NJ_Truncate (1.0 / NJ_Truncate (X));
1708 (Value : unsigned_char;
1709 Amount : Natural) return unsigned_char
1711 Result : Unsigned_8;
1713 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1714 return unsigned_char (Result);
1718 (Value : unsigned_short;
1719 Amount : Natural) return unsigned_short
1721 Result : Unsigned_16;
1723 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1724 return unsigned_short (Result);
1728 (Value : unsigned_int;
1729 Amount : Natural) return unsigned_int
1731 Result : Unsigned_32;
1733 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1734 return unsigned_int (Result);
1737 --------------------
1738 -- Recip_SQRT_Est --
1739 --------------------
1741 function Recip_SQRT_Est (X : C_float) return C_float is
1746 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1747 -- no greater than one part in 4096, that is:
1748 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1750 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1751 return NJ_Truncate (Result);
1759 (Value : unsigned_char;
1760 Amount : Natural) return unsigned_char
1762 Result : Unsigned_8;
1764 Result := Shift_Left (Unsigned_8 (Value), Amount);
1765 return unsigned_char (Result);
1769 (Value : unsigned_short;
1770 Amount : Natural) return unsigned_short
1772 Result : Unsigned_16;
1774 Result := Shift_Left (Unsigned_16 (Value), Amount);
1775 return unsigned_short (Result);
1779 (Value : unsigned_int;
1780 Amount : Natural) return unsigned_int
1782 Result : Unsigned_32;
1784 Result := Shift_Left (Unsigned_32 (Value), Amount);
1785 return unsigned_int (Result);
1792 function Shift_Right
1793 (Value : unsigned_char;
1794 Amount : Natural) return unsigned_char
1796 Result : Unsigned_8;
1798 Result := Shift_Right (Unsigned_8 (Value), Amount);
1799 return unsigned_char (Result);
1802 function Shift_Right
1803 (Value : unsigned_short;
1804 Amount : Natural) return unsigned_short
1806 Result : Unsigned_16;
1808 Result := Shift_Right (Unsigned_16 (Value), Amount);
1809 return unsigned_short (Result);
1812 function Shift_Right
1813 (Value : unsigned_int;
1814 Amount : Natural) return unsigned_int
1816 Result : Unsigned_32;
1818 Result := Shift_Right (Unsigned_32 (Value), Amount);
1819 return unsigned_int (Result);
1827 type Signed_Type is range <>;
1828 type Unsigned_Type is mod <>;
1829 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1830 return Unsigned_Type;
1831 function Shift_Right_Arithmetic
1832 (Value : Signed_Type;
1833 Amount : Natural) return Signed_Type;
1835 function Shift_Right_Arithmetic
1836 (Value : Signed_Type;
1837 Amount : Natural) return Signed_Type
1841 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1843 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1846 end Shift_Right_Arithmetic;
1848 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1852 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1856 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1863 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1865 -- This conversion should not depend on the host endianness;
1866 -- therefore, we cannot use an unchecked conversion.
1871 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1872 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1873 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1874 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1878 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1880 -- This conversion should not depend on the host endianness;
1881 -- therefore, we cannot use an unchecked conversion.
1886 Target.T := unsigned_char (Bits (Source, 0, 7));
1887 Target.R := unsigned_char (Bits (Source, 8, 15));
1888 Target.G := unsigned_char (Bits (Source, 16, 23));
1889 Target.B := unsigned_char (Bits (Source, 24, 31));
1893 ---------------------
1894 -- To_unsigned_int --
1895 ---------------------
1897 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1899 -- This conversion should not depend on the host endianness;
1900 -- therefore, we cannot use an unchecked conversion.
1901 -- It should also be the same result, value-wise, on two hosts
1902 -- with the same endianness.
1904 Target : unsigned_int := 0;
1907 -- In big endian bit ordering, Pixel_32 looks like:
1908 -- -------------------------------------
1909 -- | T | R | G | B |
1910 -- -------------------------------------
1911 -- 0 (MSB) 7 15 23 32
1913 -- Sizes of the components: (8/8/8/8)
1915 Target := Target or unsigned_int (Source.T);
1916 Target := Shift_Left (Target, 8);
1917 Target := Target or unsigned_int (Source.R);
1918 Target := Shift_Left (Target, 8);
1919 Target := Target or unsigned_int (Source.G);
1920 Target := Shift_Left (Target, 8);
1921 Target := Target or unsigned_int (Source.B);
1923 end To_unsigned_int;
1925 -----------------------
1926 -- To_unsigned_short --
1927 -----------------------
1929 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1931 -- This conversion should not depend on the host endianness;
1932 -- therefore, we cannot use an unchecked conversion.
1933 -- It should also be the same result, value-wise, on two hosts
1934 -- with the same endianness.
1936 Target : unsigned_short := 0;
1939 -- In big endian bit ordering, Pixel_16 looks like:
1940 -- -------------------------------------
1941 -- | T | R | G | B |
1942 -- -------------------------------------
1943 -- 0 (MSB) 1 5 11 15
1945 -- Sizes of the components: (1/5/5/5)
1947 Target := Target or unsigned_short (Source.T);
1948 Target := Shift_Left (Target, 5);
1949 Target := Target or unsigned_short (Source.R);
1950 Target := Shift_Left (Target, 5);
1951 Target := Target or unsigned_short (Source.G);
1952 Target := Shift_Left (Target, 5);
1953 Target := Target or unsigned_short (Source.B);
1955 end To_unsigned_short;
1961 function abs_v16qi (A : LL_VSC) return LL_VSC is
1962 VA : constant VSC_View := To_View (A);
1964 return To_Vector ((Values =>
1965 LL_VSC_Operations.abs_vxi (VA.Values)));
1972 function abs_v8hi (A : LL_VSS) return LL_VSS is
1973 VA : constant VSS_View := To_View (A);
1975 return To_Vector ((Values =>
1976 LL_VSS_Operations.abs_vxi (VA.Values)));
1983 function abs_v4si (A : LL_VSI) return LL_VSI is
1984 VA : constant VSI_View := To_View (A);
1986 return To_Vector ((Values =>
1987 LL_VSI_Operations.abs_vxi (VA.Values)));
1994 function abs_v4sf (A : LL_VF) return LL_VF is
1996 VA : constant VF_View := To_View (A);
1999 for J in Varray_float'Range loop
2000 D (J) := abs (VA.Values (J));
2003 return To_Vector ((Values => D));
2010 function abss_v16qi (A : LL_VSC) return LL_VSC is
2011 VA : constant VSC_View := To_View (A);
2013 return To_Vector ((Values =>
2014 LL_VSC_Operations.abss_vxi (VA.Values)));
2021 function abss_v8hi (A : LL_VSS) return LL_VSS is
2022 VA : constant VSS_View := To_View (A);
2024 return To_Vector ((Values =>
2025 LL_VSS_Operations.abss_vxi (VA.Values)));
2032 function abss_v4si (A : LL_VSI) return LL_VSI is
2033 VA : constant VSI_View := To_View (A);
2035 return To_Vector ((Values =>
2036 LL_VSI_Operations.abss_vxi (VA.Values)));
2043 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2044 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2046 VA : constant VUC_View :=
2048 VB : constant VUC_View := To_View (To_LL_VUC (B));
2049 D : Varray_unsigned_char;
2052 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2053 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2060 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2061 VA : constant VUS_View := To_View (To_LL_VUS (A));
2062 VB : constant VUS_View := To_View (To_LL_VUS (B));
2063 D : Varray_unsigned_short;
2066 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2067 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2074 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2075 VA : constant VUI_View := To_View (To_LL_VUI (A));
2076 VB : constant VUI_View := To_View (To_LL_VUI (B));
2077 D : Varray_unsigned_int;
2080 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2081 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2088 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2089 VA : constant VF_View := To_View (A);
2090 VB : constant VF_View := To_View (B);
2094 for J in Varray_float'Range loop
2095 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2096 + NJ_Truncate (VB.Values (J)));
2099 return To_Vector (VF_View'(Values => D));
2106 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2107 Addition_Result : UI64;
2109 VA : constant VUI_View := To_View (To_LL_VUI (A));
2110 VB : constant VUI_View := To_View (To_LL_VUI (B));
2113 for J in Varray_unsigned_int'Range loop
2115 UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2117 if Addition_Result > UI64 (unsigned_int'Last) then
2124 return To_LL_VSI (To_Vector (D));
2131 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2132 VA : constant VUC_View := To_View (To_LL_VUC (A));
2133 VB : constant VUC_View := To_View (To_LL_VUC (B));
2136 return To_LL_VSC (To_Vector
2137 (VUC_View'(Values =>
2138 (LL_VUC_Operations.vadduxs
2147 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2148 VA : constant VSC_View := To_View (A);
2149 VB : constant VSC_View := To_View (B);
2153 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2154 return To_Vector (D);
2161 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2162 VA : constant VUS_View := To_View (To_LL_VUS (A));
2163 VB : constant VUS_View := To_View (To_LL_VUS (B));
2167 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2168 return To_LL_VSS (To_Vector (D));
2175 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2176 VA : constant VSS_View := To_View (A);
2177 VB : constant VSS_View := To_View (B);
2181 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2182 return To_Vector (D);
2189 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2190 VA : constant VUI_View := To_View (To_LL_VUI (A));
2191 VB : constant VUI_View := To_View (To_LL_VUI (B));
2195 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2196 return To_LL_VSI (To_Vector (D));
2203 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2204 VA : constant VSI_View := To_View (A);
2205 VB : constant VSI_View := To_View (B);
2209 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2210 return To_Vector (D);
2217 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2218 VA : constant VUI_View := To_View (To_LL_VUI (A));
2219 VB : constant VUI_View := To_View (To_LL_VUI (B));
2223 for J in Varray_unsigned_int'Range loop
2224 D.Values (J) := VA.Values (J) and VB.Values (J);
2227 return To_LL_VSI (To_Vector (D));
2234 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2235 VA : constant VUI_View := To_View (To_LL_VUI (A));
2236 VB : constant VUI_View := To_View (To_LL_VUI (B));
2240 for J in Varray_unsigned_int'Range loop
2241 D.Values (J) := VA.Values (J) and not VB.Values (J);
2244 return To_LL_VSI (To_Vector (D));
2251 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2252 VA : constant VUC_View := To_View (To_LL_VUC (A));
2253 VB : constant VUC_View := To_View (To_LL_VUC (B));
2257 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2258 return To_LL_VSC (To_Vector (D));
2265 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2266 VA : constant VSC_View := To_View (A);
2267 VB : constant VSC_View := To_View (B);
2271 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2272 return To_Vector (D);
2279 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2280 VA : constant VUS_View := To_View (To_LL_VUS (A));
2281 VB : constant VUS_View := To_View (To_LL_VUS (B));
2285 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2286 return To_LL_VSS (To_Vector (D));
2293 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2294 VA : constant VSS_View := To_View (A);
2295 VB : constant VSS_View := To_View (B);
2299 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2300 return To_Vector (D);
2307 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2308 VA : constant VUI_View := To_View (To_LL_VUI (A));
2309 VB : constant VUI_View := To_View (To_LL_VUI (B));
2313 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2314 return To_LL_VSI (To_Vector (D));
2321 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2322 VA : constant VSI_View := To_View (A);
2323 VB : constant VSI_View := To_View (B);
2327 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2328 return To_Vector (D);
2335 function vrfip (A : LL_VF) return LL_VF is
2336 VA : constant VF_View := To_View (A);
2340 for J in Varray_float'Range loop
2342 -- If A (J) is infinite, D (J) should be infinite; With
2343 -- IEEE floating points, we can use 'Ceiling for that purpose.
2345 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2349 return To_Vector (D);
2356 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2357 VA : constant VF_View := To_View (A);
2358 VB : constant VF_View := To_View (B);
2363 for J in Varray_float'Range loop
2364 K := Vint_Range (J);
2367 if NJ_Truncate (VB.Values (J)) < 0.0 then
2369 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2370 -- word element in B is negative; the corresponding element in A
2371 -- is out of bounds.
2373 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2374 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2377 if NJ_Truncate (VA.Values (J))
2378 <= NJ_Truncate (VB.Values (J)) then
2379 D.Values (K) := Write_Bit (D.Values (K), 0, 0);
2381 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2384 if NJ_Truncate (VA.Values (J))
2385 >= -NJ_Truncate (VB.Values (J)) then
2386 D.Values (K) := Write_Bit (D.Values (K), 1, 0);
2388 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2393 return To_LL_VSI (To_Vector (D));
2400 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2401 VA : constant VUC_View := To_View (To_LL_VUC (A));
2402 VB : constant VUC_View := To_View (To_LL_VUC (B));
2406 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2407 return To_LL_VSC (To_Vector (D));
2414 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2415 VA : constant VUS_View := To_View (To_LL_VUS (A));
2416 VB : constant VUS_View := To_View (To_LL_VUS (B));
2419 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2420 return To_LL_VSS (To_Vector (D));
2427 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2428 VA : constant VUI_View := To_View (To_LL_VUI (A));
2429 VB : constant VUI_View := To_View (To_LL_VUI (B));
2432 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2433 return To_LL_VSI (To_Vector (D));
2440 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2441 VA : constant VF_View := To_View (A);
2442 VB : constant VF_View := To_View (B);
2447 for J in Varray_float'Range loop
2448 K := Vint_Range (J);
2450 if VA.Values (J) = VB.Values (J) then
2451 D.Values (K) := unsigned_int'Last;
2457 return To_LL_VSI (To_Vector (D));
2464 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2465 VA : constant VF_View := To_View (A);
2466 VB : constant VF_View := To_View (B);
2471 for J in Varray_float'Range loop
2472 K := Vint_Range (J);
2474 if VA.Values (J) >= VB.Values (J) then
2475 D.Values (K) := Signed_Bool_True;
2477 D.Values (K) := Signed_Bool_False;
2481 return To_Vector (D);
2488 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2489 VA : constant VUC_View := To_View (To_LL_VUC (A));
2490 VB : constant VUC_View := To_View (To_LL_VUC (B));
2493 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2494 return To_LL_VSC (To_Vector (D));
2501 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2502 VA : constant VSC_View := To_View (A);
2503 VB : constant VSC_View := To_View (B);
2506 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2507 return To_Vector (D);
2514 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2515 VA : constant VUS_View := To_View (To_LL_VUS (A));
2516 VB : constant VUS_View := To_View (To_LL_VUS (B));
2519 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2520 return To_LL_VSS (To_Vector (D));
2527 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2528 VA : constant VSS_View := To_View (A);
2529 VB : constant VSS_View := To_View (B);
2532 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2533 return To_Vector (D);
2540 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2541 VA : constant VUI_View := To_View (To_LL_VUI (A));
2542 VB : constant VUI_View := To_View (To_LL_VUI (B));
2545 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2546 return To_LL_VSI (To_Vector (D));
2553 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2554 VA : constant VSI_View := To_View (A);
2555 VB : constant VSI_View := To_View (B);
2558 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2559 return To_Vector (D);
2566 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2567 VA : constant VF_View := To_View (A);
2568 VB : constant VF_View := To_View (B);
2573 for J in Varray_float'Range loop
2574 K := Vint_Range (J);
2576 if NJ_Truncate (VA.Values (J))
2577 > NJ_Truncate (VB.Values (J)) then
2578 D.Values (K) := Signed_Bool_True;
2580 D.Values (K) := Signed_Bool_False;
2584 return To_Vector (D);
2591 function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2593 VA : constant VUI_View := To_View (To_LL_VUI (A));
2597 for J in Varray_signed_int'Range loop
2598 K := Vfloat_Range (J);
2600 -- Note: The conversion to Integer is safe, as Integers are required
2601 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2602 -- include the range of B (should be 0 .. 255).
2605 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2608 return To_Vector (D);
2615 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2616 VA : constant VSI_View := To_View (A);
2621 for J in Varray_signed_int'Range loop
2622 K := Vfloat_Range (J);
2623 D.Values (K) := C_float (VA.Values (J))
2624 / (2.0 ** Integer (B));
2627 return To_Vector (D);
2634 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2635 VA : constant VF_View := To_View (A);
2640 for J in Varray_signed_int'Range loop
2641 K := Vfloat_Range (J);
2643 LL_VSI_Operations.Saturate
2644 (F64 (NJ_Truncate (VA.Values (K)))
2645 * F64 (2.0 ** Integer (B)));
2648 return To_Vector (D);
2655 function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2656 VA : constant VF_View := To_View (A);
2661 for J in Varray_unsigned_int'Range loop
2662 K := Vfloat_Range (J);
2664 LL_VUI_Operations.Saturate
2665 (F64 (NJ_Truncate (VA.Values (K)))
2666 * F64 (2.0 ** Integer (B)));
2669 return To_LL_VSI (To_Vector (D));
2676 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2678 procedure dss (A : c_int) is
2679 pragma Unreferenced (A);
2688 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2699 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2701 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2702 pragma Unreferenced (A);
2703 pragma Unreferenced (B);
2704 pragma Unreferenced (C);
2713 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2715 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2716 pragma Unreferenced (A);
2717 pragma Unreferenced (B);
2718 pragma Unreferenced (C);
2727 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2729 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2730 pragma Unreferenced (A);
2731 pragma Unreferenced (B);
2732 pragma Unreferenced (C);
2741 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2743 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2744 pragma Unreferenced (A);
2745 pragma Unreferenced (B);
2746 pragma Unreferenced (C);
2755 function vexptefp (A : LL_VF) return LL_VF is
2756 use C_float_Operations;
2758 VA : constant VF_View := To_View (A);
2762 for J in Varray_float'Range loop
2764 -- ??? Check the precision of the operation.
2765 -- As described in [PEM-6 vexptefp]:
2766 -- If theoretical_result is equal to 2 at the power of A (J) with
2767 -- infinite precision, we should have:
2768 -- abs ((D (J) - theoretical_result) / theoretical_result) <= 1/16
2770 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2773 return To_Vector (D);
2780 function vrfim (A : LL_VF) return LL_VF is
2781 VA : constant VF_View := To_View (A);
2785 for J in Varray_float'Range loop
2787 -- If A (J) is infinite, D (J) should be infinite; With
2788 -- IEEE floating point, we can use 'Ceiling for that purpose.
2790 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2792 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2795 if D.Values (J) /= VA.Values (J) then
2796 D.Values (J) := D.Values (J) - 1.0;
2800 return To_Vector (D);
2807 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2809 -- Simulate the altivec unit behavior regarding what Effective Address
2810 -- is accessed, stripping off the input address least significant bits
2811 -- wrt to vector alignment.
2813 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2814 -- an address within a vector is not necessarily rounded back at the
2815 -- vector start address. Besides, rounding on 16 makes no sense on such
2816 -- targets because the address of a properly aligned vector (that is,
2817 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2818 -- want never to happen.
2820 EA : constant System.Address :=
2823 (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2826 for D'Address use EA;
2836 function lvebx (A : c_long; B : c_ptr) return LL_VSC is
2839 D.Values := LL_VSC_Operations.lvexx (A, B);
2840 return To_Vector (D);
2847 function lvehx (A : c_long; B : c_ptr) return LL_VSS is
2850 D.Values := LL_VSS_Operations.lvexx (A, B);
2851 return To_Vector (D);
2858 function lvewx (A : c_long; B : c_ptr) return LL_VSI is
2861 D.Values := LL_VSI_Operations.lvexx (A, B);
2862 return To_Vector (D);
2869 function lvxl (A : c_long; B : c_ptr) return LL_VSI renames
2876 function vlogefp (A : LL_VF) return LL_VF is
2877 VA : constant VF_View := To_View (A);
2881 for J in Varray_float'Range loop
2883 -- ??? Check the precision of the operation.
2884 -- As described in [PEM-6 vlogefp]:
2885 -- If theorical_result is equal to the log2 of A (J) with
2886 -- infinite precision, we should have:
2887 -- abs (D (J) - theorical_result) <= 1/32,
2888 -- unless abs(D(J) - 1) <= 1/8.
2891 C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2894 return To_Vector (D);
2901 function lvsl (A : c_long; B : c_ptr) return LL_VSC is
2902 type bit4_type is mod 16#F# + 1;
2903 for bit4_type'Alignment use 1;
2904 EA : Integer_Address;
2909 EA := Integer_Address (A) + To_Integer (B);
2910 SH := bit4_type (EA mod 2 ** 4);
2912 for J in D.Values'Range loop
2913 D.Values (J) := unsigned_char (SH) + unsigned_char (J)
2914 - unsigned_char (D.Values'First);
2917 return To_LL_VSC (To_Vector (D));
2924 function lvsr (A : c_long; B : c_ptr) return LL_VSC is
2925 type bit4_type is mod 16#F# + 1;
2926 for bit4_type'Alignment use 1;
2927 EA : Integer_Address;
2932 EA := Integer_Address (A) + To_Integer (B);
2933 SH := bit4_type (EA mod 2 ** 4);
2935 for J in D.Values'Range loop
2936 D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2939 return To_LL_VSC (To_Vector (D));
2946 function vmaddfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
2947 VA : constant VF_View := To_View (A);
2948 VB : constant VF_View := To_View (B);
2949 VC : constant VF_View := To_View (C);
2953 for J in Varray_float'Range loop
2955 Rnd_To_FP_Nearest (F64 (VA.Values (J))
2956 * F64 (VB.Values (J))
2957 + F64 (VC.Values (J)));
2960 return To_Vector (D);
2967 function vmhaddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
2968 VA : constant VSS_View := To_View (A);
2969 VB : constant VSS_View := To_View (B);
2970 VC : constant VSS_View := To_View (C);
2974 for J in Varray_signed_short'Range loop
2975 D.Values (J) := LL_VSS_Operations.Saturate
2976 ((SI64 (VA.Values (J)) * SI64 (VB.Values (J)))
2977 / SI64 (2 ** 15) + SI64 (VC.Values (J)));
2980 return To_Vector (D);
2987 function vmaxub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2988 VA : constant VUC_View := To_View (To_LL_VUC (A));
2989 VB : constant VUC_View := To_View (To_LL_VUC (B));
2992 D.Values := LL_VUC_Operations.vmaxux (VA.Values, VB.Values);
2993 return To_LL_VSC (To_Vector (D));
3000 function vmaxsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3001 VA : constant VSC_View := To_View (A);
3002 VB : constant VSC_View := To_View (B);
3005 D.Values := LL_VSC_Operations.vmaxsx (VA.Values, VB.Values);
3006 return To_Vector (D);
3013 function vmaxuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3014 VA : constant VUS_View := To_View (To_LL_VUS (A));
3015 VB : constant VUS_View := To_View (To_LL_VUS (B));
3018 D.Values := LL_VUS_Operations.vmaxux (VA.Values, VB.Values);
3019 return To_LL_VSS (To_Vector (D));
3026 function vmaxsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3027 VA : constant VSS_View := To_View (A);
3028 VB : constant VSS_View := To_View (B);
3031 D.Values := LL_VSS_Operations.vmaxsx (VA.Values, VB.Values);
3032 return To_Vector (D);
3039 function vmaxuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3040 VA : constant VUI_View := To_View (To_LL_VUI (A));
3041 VB : constant VUI_View := To_View (To_LL_VUI (B));
3044 D.Values := LL_VUI_Operations.vmaxux (VA.Values, VB.Values);
3045 return To_LL_VSI (To_Vector (D));
3052 function vmaxsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3053 VA : constant VSI_View := To_View (A);
3054 VB : constant VSI_View := To_View (B);
3057 D.Values := LL_VSI_Operations.vmaxsx (VA.Values, VB.Values);
3058 return To_Vector (D);
3065 function vmaxfp (A : LL_VF; B : LL_VF) return LL_VF is
3066 VA : constant VF_View := To_View (A);
3067 VB : constant VF_View := To_View (B);
3071 for J in Varray_float'Range loop
3072 if VA.Values (J) > VB.Values (J) then
3073 D.Values (J) := VA.Values (J);
3075 D.Values (J) := VB.Values (J);
3079 return To_Vector (D);
3086 function vmrghb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3087 VA : constant VSC_View := To_View (A);
3088 VB : constant VSC_View := To_View (B);
3091 D.Values := LL_VSC_Operations.vmrghx (VA.Values, VB.Values);
3092 return To_Vector (D);
3099 function vmrghh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3100 VA : constant VSS_View := To_View (A);
3101 VB : constant VSS_View := To_View (B);
3104 D.Values := LL_VSS_Operations.vmrghx (VA.Values, VB.Values);
3105 return To_Vector (D);
3112 function vmrghw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3113 VA : constant VSI_View := To_View (A);
3114 VB : constant VSI_View := To_View (B);
3117 D.Values := LL_VSI_Operations.vmrghx (VA.Values, VB.Values);
3118 return To_Vector (D);
3125 function vmrglb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3126 VA : constant VSC_View := To_View (A);
3127 VB : constant VSC_View := To_View (B);
3130 D.Values := LL_VSC_Operations.vmrglx (VA.Values, VB.Values);
3131 return To_Vector (D);
3138 function vmrglh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3139 VA : constant VSS_View := To_View (A);
3140 VB : constant VSS_View := To_View (B);
3143 D.Values := LL_VSS_Operations.vmrglx (VA.Values, VB.Values);
3144 return To_Vector (D);
3151 function vmrglw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3152 VA : constant VSI_View := To_View (A);
3153 VB : constant VSI_View := To_View (B);
3156 D.Values := LL_VSI_Operations.vmrglx (VA.Values, VB.Values);
3157 return To_Vector (D);
3164 function mfvscr return LL_VSS is
3167 for J in Varray_unsigned_short'Range loop
3171 D.Values (Varray_unsigned_short'Last) :=
3172 unsigned_short (VSCR mod 2 ** unsigned_short'Size);
3173 D.Values (Varray_unsigned_short'Last - 1) :=
3174 unsigned_short (VSCR / 2 ** unsigned_short'Size);
3175 return To_LL_VSS (To_Vector (D));
3182 function vminfp (A : LL_VF; B : LL_VF) return LL_VF is
3183 VA : constant VF_View := To_View (A);
3184 VB : constant VF_View := To_View (B);
3188 for J in Varray_float'Range loop
3189 if VA.Values (J) < VB.Values (J) then
3190 D.Values (J) := VA.Values (J);
3192 D.Values (J) := VB.Values (J);
3196 return To_Vector (D);
3203 function vminsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3204 VA : constant VSC_View := To_View (A);
3205 VB : constant VSC_View := To_View (B);
3208 D.Values := LL_VSC_Operations.vminsx (VA.Values, VB.Values);
3209 return To_Vector (D);
3216 function vminub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3217 VA : constant VUC_View := To_View (To_LL_VUC (A));
3218 VB : constant VUC_View := To_View (To_LL_VUC (B));
3221 D.Values := LL_VUC_Operations.vminux (VA.Values, VB.Values);
3222 return To_LL_VSC (To_Vector (D));
3229 function vminsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3230 VA : constant VSS_View := To_View (A);
3231 VB : constant VSS_View := To_View (B);
3234 D.Values := LL_VSS_Operations.vminsx (VA.Values, VB.Values);
3235 return To_Vector (D);
3242 function vminuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3243 VA : constant VUS_View := To_View (To_LL_VUS (A));
3244 VB : constant VUS_View := To_View (To_LL_VUS (B));
3247 D.Values := LL_VUS_Operations.vminux (VA.Values, VB.Values);
3248 return To_LL_VSS (To_Vector (D));
3255 function vminsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3256 VA : constant VSI_View := To_View (A);
3257 VB : constant VSI_View := To_View (B);
3260 D.Values := LL_VSI_Operations.vminsx (VA.Values, VB.Values);
3261 return To_Vector (D);
3268 function vminuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3269 VA : constant VUI_View := To_View (To_LL_VUI (A));
3270 VB : constant VUI_View := To_View (To_LL_VUI (B));
3273 D.Values := LL_VUI_Operations.vminux (VA.Values,
3275 return To_LL_VSI (To_Vector (D));
3282 function vmladduhm (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3283 VA : constant VUS_View := To_View (To_LL_VUS (A));
3284 VB : constant VUS_View := To_View (To_LL_VUS (B));
3285 VC : constant VUS_View := To_View (To_LL_VUS (C));
3289 for J in Varray_unsigned_short'Range loop
3290 D.Values (J) := VA.Values (J) * VB.Values (J)
3294 return To_LL_VSS (To_Vector (D));
3301 function vmhraddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3302 VA : constant VSS_View := To_View (A);
3303 VB : constant VSS_View := To_View (B);
3304 VC : constant VSS_View := To_View (C);
3308 for J in Varray_signed_short'Range loop
3310 LL_VSS_Operations.Saturate (((SI64 (VA.Values (J))
3311 * SI64 (VB.Values (J))
3314 + SI64 (VC.Values (J))));
3317 return To_Vector (D);
3324 function vmsumubm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3325 Offset : Vchar_Range;
3326 VA : constant VUC_View := To_View (To_LL_VUC (A));
3327 VB : constant VUC_View := To_View (To_LL_VUC (B));
3328 VC : constant VUI_View := To_View (To_LL_VUI (C));
3332 for J in 0 .. 3 loop
3333 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3334 D.Values (Vint_Range
3335 (J + Integer (Vint_Range'First))) :=
3336 (unsigned_int (VA.Values (Offset))
3337 * unsigned_int (VB.Values (Offset)))
3338 + (unsigned_int (VA.Values (Offset + 1))
3339 * unsigned_int (VB.Values (1 + Offset)))
3340 + (unsigned_int (VA.Values (2 + Offset))
3341 * unsigned_int (VB.Values (2 + Offset)))
3342 + (unsigned_int (VA.Values (3 + Offset))
3343 * unsigned_int (VB.Values (3 + Offset)))
3344 + VC.Values (Vint_Range
3345 (J + Integer (Varray_unsigned_int'First)));
3348 return To_LL_VSI (To_Vector (D));
3355 function vmsummbm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3356 Offset : Vchar_Range;
3357 VA : constant VSC_View := To_View (A);
3358 VB : constant VUC_View := To_View (To_LL_VUC (B));
3359 VC : constant VSI_View := To_View (C);
3363 for J in 0 .. 3 loop
3364 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3365 D.Values (Vint_Range
3366 (J + Integer (Varray_unsigned_int'First))) := 0
3367 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3368 * SI64 (VB.Values (Offset)))
3369 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3372 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (2 + Offset))
3375 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (3 + Offset))
3378 + VC.Values (Vint_Range
3379 (J + Integer (Varray_unsigned_int'First)));
3382 return To_Vector (D);
3389 function vmsumuhm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3390 Offset : Vshort_Range;
3391 VA : constant VUS_View := To_View (To_LL_VUS (A));
3392 VB : constant VUS_View := To_View (To_LL_VUS (B));
3393 VC : constant VUI_View := To_View (To_LL_VUI (C));
3397 for J in 0 .. 3 loop
3399 Vshort_Range (2 * J + Integer (Vshort_Range'First));
3400 D.Values (Vint_Range
3401 (J + Integer (Varray_unsigned_int'First))) :=
3402 (unsigned_int (VA.Values (Offset))
3403 * unsigned_int (VB.Values (Offset)))
3404 + (unsigned_int (VA.Values (Offset + 1))
3405 * unsigned_int (VB.Values (1 + Offset)))
3406 + VC.Values (Vint_Range
3407 (J + Integer (Vint_Range'First)));
3410 return To_LL_VSI (To_Vector (D));
3417 function vmsumshm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3418 VA : constant VSS_View := To_View (A);
3419 VB : constant VSS_View := To_View (B);
3420 VC : constant VSI_View := To_View (C);
3421 Offset : Vshort_Range;
3425 for J in 0 .. 3 loop
3427 Vshort_Range (2 * J + Integer (Varray_signed_char'First));
3428 D.Values (Vint_Range
3429 (J + Integer (Varray_unsigned_int'First))) := 0
3430 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3431 * SI64 (VB.Values (Offset)))
3432 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3435 + VC.Values (Vint_Range
3436 (J + Integer (Varray_unsigned_int'First)));
3439 return To_Vector (D);
3446 function vmsumuhs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3447 Offset : Vshort_Range;
3448 VA : constant VUS_View := To_View (To_LL_VUS (A));
3449 VB : constant VUS_View := To_View (To_LL_VUS (B));
3450 VC : constant VUI_View := To_View (To_LL_VUI (C));
3454 for J in 0 .. 3 loop
3456 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3457 D.Values (Vint_Range
3458 (J + Integer (Varray_unsigned_int'First))) :=
3459 LL_VUI_Operations.Saturate
3460 (UI64 (VA.Values (Offset))
3461 * UI64 (VB.Values (Offset))
3462 + UI64 (VA.Values (Offset + 1))
3463 * UI64 (VB.Values (1 + Offset))
3466 (J + Integer (Varray_unsigned_int'First)))));
3469 return To_LL_VSI (To_Vector (D));
3476 function vmsumshs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3477 VA : constant VSS_View := To_View (A);
3478 VB : constant VSS_View := To_View (B);
3479 VC : constant VSI_View := To_View (C);
3480 Offset : Vshort_Range;
3484 for J in 0 .. 3 loop
3486 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3487 D.Values (Vint_Range
3488 (J + Integer (Varray_signed_int'First))) :=
3489 LL_VSI_Operations.Saturate
3490 (SI64 (VA.Values (Offset))
3491 * SI64 (VB.Values (Offset))
3492 + SI64 (VA.Values (Offset + 1))
3493 * SI64 (VB.Values (1 + Offset))
3496 (J + Integer (Varray_signed_int'First)))));
3499 return To_Vector (D);
3506 procedure mtvscr (A : LL_VSI) is
3507 VA : constant VUI_View := To_View (To_LL_VUI (A));
3509 VSCR := VA.Values (Varray_unsigned_int'Last);
3516 function vmuleub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3517 VA : constant VUC_View := To_View (To_LL_VUC (A));
3518 VB : constant VUC_View := To_View (To_LL_VUC (B));
3521 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (True,
3524 return To_LL_VSS (To_Vector (D));
3531 function vmuleuh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3532 VA : constant VUS_View := To_View (To_LL_VUS (A));
3533 VB : constant VUS_View := To_View (To_LL_VUS (B));
3536 D.Values := LL_VUS_LL_VUI_Operations.vmulxux (True,
3539 return To_LL_VSI (To_Vector (D));
3546 function vmulesb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3547 VA : constant VSC_View := To_View (A);
3548 VB : constant VSC_View := To_View (B);
3551 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (True,
3554 return To_Vector (D);
3561 function vmulesh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3562 VA : constant VSS_View := To_View (A);
3563 VB : constant VSS_View := To_View (B);
3566 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (True,
3569 return To_Vector (D);
3576 function vmuloub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3577 VA : constant VUC_View := To_View (To_LL_VUC (A));
3578 VB : constant VUC_View := To_View (To_LL_VUC (B));
3581 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (False,
3584 return To_LL_VSS (To_Vector (D));
3591 function vmulouh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3592 VA : constant VUS_View := To_View (To_LL_VUS (A));
3593 VB : constant VUS_View := To_View (To_LL_VUS (B));
3597 LL_VUS_LL_VUI_Operations.vmulxux (False, VA.Values, VB.Values);
3598 return To_LL_VSI (To_Vector (D));
3605 function vmulosb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3606 VA : constant VSC_View := To_View (A);
3607 VB : constant VSC_View := To_View (B);
3610 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (False,
3613 return To_Vector (D);
3620 function vmulosh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3621 VA : constant VSS_View := To_View (A);
3622 VB : constant VSS_View := To_View (B);
3625 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (False,
3628 return To_Vector (D);
3635 function vnmsubfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
3636 VA : constant VF_View := To_View (A);
3637 VB : constant VF_View := To_View (B);
3638 VC : constant VF_View := To_View (C);
3642 for J in Vfloat_Range'Range loop
3644 -Rnd_To_FP_Nearest (F64 (VA.Values (J))
3645 * F64 (VB.Values (J))
3646 - F64 (VC.Values (J)));
3649 return To_Vector (D);
3656 function vnor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3657 VA : constant VUI_View := To_View (To_LL_VUI (A));
3658 VB : constant VUI_View := To_View (To_LL_VUI (B));
3662 for J in Vint_Range'Range loop
3663 D.Values (J) := not (VA.Values (J) or VB.Values (J));
3666 return To_LL_VSI (To_Vector (D));
3673 function vor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3674 VA : constant VUI_View := To_View (To_LL_VUI (A));
3675 VB : constant VUI_View := To_View (To_LL_VUI (B));
3679 for J in Vint_Range'Range loop
3680 D.Values (J) := VA.Values (J) or VB.Values (J);
3683 return To_LL_VSI (To_Vector (D));
3690 function vpkuhum (A : LL_VSS; B : LL_VSS) return LL_VSC is
3691 VA : constant VUS_View := To_View (To_LL_VUS (A));
3692 VB : constant VUS_View := To_View (To_LL_VUS (B));
3695 D.Values := LL_VUC_LL_VUS_Operations.vpkuxum (VA.Values, VB.Values);
3696 return To_LL_VSC (To_Vector (D));
3703 function vpkuwum (A : LL_VSI; B : LL_VSI) return LL_VSS is
3704 VA : constant VUI_View := To_View (To_LL_VUI (A));
3705 VB : constant VUI_View := To_View (To_LL_VUI (B));
3708 D.Values := LL_VUS_LL_VUI_Operations.vpkuxum (VA.Values, VB.Values);
3709 return To_LL_VSS (To_Vector (D));
3716 function vpkpx (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));
3720 Offset : Vint_Range;
3725 for J in 0 .. 3 loop
3726 Offset := Vint_Range (J + Integer (Vshort_Range'First));
3727 P32 := To_Pixel (VA.Values (Offset));
3728 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3729 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3730 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3731 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3732 D.Values (Vshort_Range (Offset)) := To_unsigned_short (P16);
3733 P32 := To_Pixel (VB.Values (Offset));
3734 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3735 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3736 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3737 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3738 D.Values (Vshort_Range (Offset) + 4) := To_unsigned_short (P16);
3741 return To_LL_VSS (To_Vector (D));
3748 function vpkuhus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3749 VA : constant VUS_View := To_View (To_LL_VUS (A));
3750 VB : constant VUS_View := To_View (To_LL_VUS (B));
3753 D.Values := LL_VUC_LL_VUS_Operations.vpkuxus (VA.Values, VB.Values);
3754 return To_LL_VSC (To_Vector (D));
3761 function vpkuwus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3762 VA : constant VUI_View := To_View (To_LL_VUI (A));
3763 VB : constant VUI_View := To_View (To_LL_VUI (B));
3766 D.Values := LL_VUS_LL_VUI_Operations.vpkuxus (VA.Values, VB.Values);
3767 return To_LL_VSS (To_Vector (D));
3774 function vpkshss (A : LL_VSS; B : LL_VSS) return LL_VSC is
3775 VA : constant VSS_View := To_View (A);
3776 VB : constant VSS_View := To_View (B);
3779 D.Values := LL_VSC_LL_VSS_Operations.vpksxss (VA.Values, VB.Values);
3780 return To_Vector (D);
3787 function vpkswss (A : LL_VSI; B : LL_VSI) return LL_VSS is
3788 VA : constant VSI_View := To_View (A);
3789 VB : constant VSI_View := To_View (B);
3792 D.Values := LL_VSS_LL_VSI_Operations.vpksxss (VA.Values, VB.Values);
3793 return To_Vector (D);
3801 type Signed_Component_Type is range <>;
3802 type Signed_Index_Type is range <>;
3803 type Signed_Varray_Type is
3804 array (Signed_Index_Type) of Signed_Component_Type;
3805 type Unsigned_Component_Type is mod <>;
3806 type Unsigned_Index_Type is range <>;
3807 type Unsigned_Varray_Type is
3808 array (Unsigned_Index_Type) of Unsigned_Component_Type;
3811 (A : Signed_Varray_Type;
3812 B : Signed_Varray_Type) return Unsigned_Varray_Type;
3815 (A : Signed_Varray_Type;
3816 B : Signed_Varray_Type) return Unsigned_Varray_Type
3818 N : constant Unsigned_Index_Type :=
3819 Unsigned_Index_Type (Signed_Index_Type'Last);
3820 Offset : Unsigned_Index_Type;
3821 Signed_Offset : Signed_Index_Type;
3822 D : Unsigned_Varray_Type;
3825 (X : Signed_Component_Type) return Unsigned_Component_Type;
3826 -- Saturation, as defined in
3827 -- [PIM-4.1 Vector Status and Control Register]
3834 (X : Signed_Component_Type) return Unsigned_Component_Type
3836 D : Unsigned_Component_Type;
3839 D := Unsigned_Component_Type
3840 (Signed_Component_Type'Max
3841 (Signed_Component_Type (Unsigned_Component_Type'First),
3842 Signed_Component_Type'Min
3843 (Signed_Component_Type (Unsigned_Component_Type'Last),
3845 if Signed_Component_Type (D) /= X then
3846 VSCR := Write_Bit (VSCR, SAT_POS, 1);
3852 -- Start of processing for vpksxus
3855 for J in 0 .. N - 1 loop
3857 Unsigned_Index_Type (Integer (J)
3858 + Integer (Unsigned_Index_Type'First));
3860 Signed_Index_Type (Integer (J)
3861 + Integer (Signed_Index_Type'First));
3862 D (Offset) := Saturate (A (Signed_Offset));
3863 D (Offset + N) := Saturate (B (Signed_Offset));
3873 function vpkshus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3874 function vpkshus_Instance is
3875 new vpksxus (signed_short,
3877 Varray_signed_short,
3880 Varray_unsigned_char);
3882 VA : constant VSS_View := To_View (A);
3883 VB : constant VSS_View := To_View (B);
3887 D.Values := vpkshus_Instance (VA.Values, VB.Values);
3888 return To_LL_VSC (To_Vector (D));
3895 function vpkswus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3896 function vpkswus_Instance is
3897 new vpksxus (signed_int,
3902 Varray_unsigned_short);
3904 VA : constant VSI_View := To_View (A);
3905 VB : constant VSI_View := To_View (B);
3908 D.Values := vpkswus_Instance (VA.Values, VB.Values);
3909 return To_LL_VSS (To_Vector (D));
3916 function vperm_4si (A : LL_VSI; B : LL_VSI; C : LL_VSC) return LL_VSI is
3917 VA : constant VUC_View := To_View (To_LL_VUC (A));
3918 VB : constant VUC_View := To_View (To_LL_VUC (B));
3919 VC : constant VUC_View := To_View (To_LL_VUC (C));
3924 for N in Vchar_Range'Range loop
3925 J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
3926 + Integer (Vchar_Range'First));
3928 if Bits (VC.Values (N), 3, 3) = 0 then
3929 D.Values (N) := VA.Values (J);
3931 D.Values (N) := VB.Values (J);
3935 return To_LL_VSI (To_Vector (D));
3942 function vrefp (A : LL_VF) return LL_VF is
3943 VA : constant VF_View := To_View (A);
3947 for J in Vfloat_Range'Range loop
3948 D.Values (J) := FP_Recip_Est (VA.Values (J));
3951 return To_Vector (D);
3958 function vrlb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3959 VA : constant VUC_View := To_View (To_LL_VUC (A));
3960 VB : constant VUC_View := To_View (To_LL_VUC (B));
3963 D.Values := LL_VUC_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3964 return To_LL_VSC (To_Vector (D));
3971 function vrlh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3972 VA : constant VUS_View := To_View (To_LL_VUS (A));
3973 VB : constant VUS_View := To_View (To_LL_VUS (B));
3976 D.Values := LL_VUS_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3977 return To_LL_VSS (To_Vector (D));
3984 function vrlw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3985 VA : constant VUI_View := To_View (To_LL_VUI (A));
3986 VB : constant VUI_View := To_View (To_LL_VUI (B));
3989 D.Values := LL_VUI_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3990 return To_LL_VSI (To_Vector (D));
3997 function vrfin (A : LL_VF) return LL_VF is
3998 VA : constant VF_View := To_View (A);
4002 for J in Vfloat_Range'Range loop
4003 D.Values (J) := C_float (Rnd_To_FPI_Near (F64 (VA.Values (J))));
4006 return To_Vector (D);
4013 function vrsqrtefp (A : LL_VF) return LL_VF is
4014 VA : constant VF_View := To_View (A);
4018 for J in Vfloat_Range'Range loop
4019 D.Values (J) := Recip_SQRT_Est (VA.Values (J));
4022 return To_Vector (D);
4029 function vsel_4si (A : LL_VSI; B : LL_VSI; C : LL_VSI) return LL_VSI is
4030 VA : constant VUI_View := To_View (To_LL_VUI (A));
4031 VB : constant VUI_View := To_View (To_LL_VUI (B));
4032 VC : constant VUI_View := To_View (To_LL_VUI (C));
4036 for J in Vint_Range'Range loop
4037 D.Values (J) := ((not VC.Values (J)) and VA.Values (J))
4038 or (VC.Values (J) and VB.Values (J));
4041 return To_LL_VSI (To_Vector (D));
4048 function vslb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4049 VA : constant VUC_View := To_View (To_LL_VUC (A));
4050 VB : constant VUC_View := To_View (To_LL_VUC (B));
4054 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4055 return To_LL_VSC (To_Vector (D));
4062 function vslh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4063 VA : constant VUS_View := To_View (To_LL_VUS (A));
4064 VB : constant VUS_View := To_View (To_LL_VUS (B));
4068 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4069 return To_LL_VSS (To_Vector (D));
4076 function vslw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4077 VA : constant VUI_View := To_View (To_LL_VUI (A));
4078 VB : constant VUI_View := To_View (To_LL_VUI (B));
4082 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4083 return To_LL_VSI (To_Vector (D));
4090 function vsldoi_4si (A : LL_VSI; B : LL_VSI; C : c_int) return LL_VSI is
4091 VA : constant VUC_View := To_View (To_LL_VUC (A));
4092 VB : constant VUC_View := To_View (To_LL_VUC (B));
4098 for J in Vchar_Range'Range loop
4099 Offset := c_int (J) + C;
4100 Bound := c_int (Vchar_Range'First)
4101 + c_int (Varray_unsigned_char'Length);
4103 if Offset < Bound then
4104 D.Values (J) := VA.Values (Vchar_Range (Offset));
4107 VB.Values (Vchar_Range (Offset - Bound
4108 + c_int (Vchar_Range'First)));
4112 return To_LL_VSI (To_Vector (D));
4119 function vsldoi_8hi (A : LL_VSS; B : LL_VSS; C : c_int) return LL_VSS is
4121 return To_LL_VSS (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4128 function vsldoi_16qi (A : LL_VSC; B : LL_VSC; C : c_int) return LL_VSC is
4130 return To_LL_VSC (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4137 function vsldoi_4sf (A : LL_VF; B : LL_VF; C : c_int) return LL_VF is
4139 return To_LL_VF (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4146 function vsl (A : LL_VSI; B : LL_VSI) return LL_VSI is
4147 VA : constant VUI_View := To_View (To_LL_VUI (A));
4148 VB : constant VUI_View := To_View (To_LL_VUI (B));
4150 M : constant Natural :=
4151 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4153 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4154 -- must be the same. Otherwise the value placed into D is undefined."
4155 -- ??? Shall we add a optional check for B?
4158 for J in Vint_Range'Range loop
4160 D.Values (J) := D.Values (J) + Shift_Left (VA.Values (J), M);
4162 if J /= Vint_Range'Last then
4164 D.Values (J) + Shift_Right (VA.Values (J + 1),
4165 signed_int'Size - M);
4169 return To_LL_VSI (To_Vector (D));
4176 function vslo (A : LL_VSI; B : LL_VSI) return LL_VSI is
4177 VA : constant VUC_View := To_View (To_LL_VUC (A));
4178 VB : constant VUC_View := To_View (To_LL_VUC (B));
4180 M : constant Natural :=
4181 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4185 for N in Vchar_Range'Range loop
4186 J := Natural (N) + M;
4188 if J <= Natural (Vchar_Range'Last) then
4189 D.Values (N) := VA.Values (Vchar_Range (J));
4195 return To_LL_VSI (To_Vector (D));
4202 function vspltb (A : LL_VSC; B : c_int) return LL_VSC is
4203 VA : constant VSC_View := To_View (A);
4206 D.Values := LL_VSC_Operations.vspltx (VA.Values, B);
4207 return To_Vector (D);
4214 function vsplth (A : LL_VSS; B : c_int) return LL_VSS is
4215 VA : constant VSS_View := To_View (A);
4218 D.Values := LL_VSS_Operations.vspltx (VA.Values, B);
4219 return To_Vector (D);
4226 function vspltw (A : LL_VSI; B : c_int) return LL_VSI is
4227 VA : constant VSI_View := To_View (A);
4230 D.Values := LL_VSI_Operations.vspltx (VA.Values, B);
4231 return To_Vector (D);
4238 function vspltisb (A : c_int) return LL_VSC is
4241 D.Values := LL_VSC_Operations.vspltisx (A);
4242 return To_Vector (D);
4249 function vspltish (A : c_int) return LL_VSS is
4252 D.Values := LL_VSS_Operations.vspltisx (A);
4253 return To_Vector (D);
4260 function vspltisw (A : c_int) return LL_VSI is
4263 D.Values := LL_VSI_Operations.vspltisx (A);
4264 return To_Vector (D);
4271 function vsrb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4272 VA : constant VUC_View := To_View (To_LL_VUC (A));
4273 VB : constant VUC_View := To_View (To_LL_VUC (B));
4277 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4278 return To_LL_VSC (To_Vector (D));
4285 function vsrh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4286 VA : constant VUS_View := To_View (To_LL_VUS (A));
4287 VB : constant VUS_View := To_View (To_LL_VUS (B));
4291 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4292 return To_LL_VSS (To_Vector (D));
4299 function vsrw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4300 VA : constant VUI_View := To_View (To_LL_VUI (A));
4301 VB : constant VUI_View := To_View (To_LL_VUI (B));
4305 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4306 return To_LL_VSI (To_Vector (D));
4313 function vsrab (A : LL_VSC; B : LL_VSC) return LL_VSC is
4314 VA : constant VSC_View := To_View (A);
4315 VB : constant VSC_View := To_View (B);
4319 LL_VSC_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4320 return To_Vector (D);
4327 function vsrah (A : LL_VSS; B : LL_VSS) return LL_VSS is
4328 VA : constant VSS_View := To_View (A);
4329 VB : constant VSS_View := To_View (B);
4333 LL_VSS_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4334 return To_Vector (D);
4341 function vsraw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4342 VA : constant VSI_View := To_View (A);
4343 VB : constant VSI_View := To_View (B);
4347 LL_VSI_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4348 return To_Vector (D);
4355 function vsr (A : LL_VSI; B : LL_VSI) return LL_VSI is
4356 VA : constant VUI_View := To_View (To_LL_VUI (A));
4357 VB : constant VUI_View := To_View (To_LL_VUI (B));
4358 M : constant Natural :=
4359 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4363 for J in Vint_Range'Range loop
4365 D.Values (J) := D.Values (J) + Shift_Right (VA.Values (J), M);
4367 if J /= Vint_Range'First then
4370 + Shift_Left (VA.Values (J - 1), signed_int'Size - M);
4374 return To_LL_VSI (To_Vector (D));
4381 function vsro (A : LL_VSI; B : LL_VSI) return LL_VSI is
4382 VA : constant VUC_View := To_View (To_LL_VUC (A));
4383 VB : constant VUC_View := To_View (To_LL_VUC (B));
4384 M : constant Natural :=
4385 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4390 for N in Vchar_Range'Range loop
4391 J := Natural (N) - M;
4393 if J >= Natural (Vchar_Range'First) then
4394 D.Values (N) := VA.Values (Vchar_Range (J));
4400 return To_LL_VSI (To_Vector (D));
4407 procedure stvx (A : LL_VSI; B : c_int; C : c_ptr) is
4409 -- Simulate the altivec unit behavior regarding what Effective Address
4410 -- is accessed, stripping off the input address least significant bits
4411 -- wrt to vector alignment (see comment in lvx for further details).
4413 EA : constant System.Address :=
4416 (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4419 for D'Address use EA;
4429 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4430 VA : constant VSC_View := To_View (A);
4432 LL_VSC_Operations.stvexx (VA.Values, B, C);
4439 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4440 VA : constant VSS_View := To_View (A);
4442 LL_VSS_Operations.stvexx (VA.Values, B, C);
4449 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4450 VA : constant VSI_View := To_View (A);
4452 LL_VSI_Operations.stvexx (VA.Values, B, C);
4459 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4465 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4466 VA : constant VUC_View := To_View (To_LL_VUC (A));
4467 VB : constant VUC_View := To_View (To_LL_VUC (B));
4470 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4471 return To_LL_VSC (To_Vector (D));
4478 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4479 VA : constant VUS_View := To_View (To_LL_VUS (A));
4480 VB : constant VUS_View := To_View (To_LL_VUS (B));
4483 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4484 return To_LL_VSS (To_Vector (D));
4491 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4492 VA : constant VUI_View := To_View (To_LL_VUI (A));
4493 VB : constant VUI_View := To_View (To_LL_VUI (B));
4496 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4497 return To_LL_VSI (To_Vector (D));
4504 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4505 VA : constant VF_View := To_View (A);
4506 VB : constant VF_View := To_View (B);
4510 for J in Vfloat_Range'Range loop
4512 NJ_Truncate (NJ_Truncate (VA.Values (J))
4513 - NJ_Truncate (VB.Values (J)));
4516 return To_Vector (D);
4523 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4524 Subst_Result : SI64;
4526 VA : constant VUI_View := To_View (To_LL_VUI (A));
4527 VB : constant VUI_View := To_View (To_LL_VUI (B));
4531 for J in Vint_Range'Range loop
4532 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4534 if Subst_Result < SI64 (unsigned_int'First) then
4541 return To_LL_VSI (To_Vector (D));
4548 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4549 VA : constant VUC_View := To_View (To_LL_VUC (A));
4550 VB : constant VUC_View := To_View (To_LL_VUC (B));
4553 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4554 return To_LL_VSC (To_Vector (D));
4561 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4562 VA : constant VSC_View := To_View (A);
4563 VB : constant VSC_View := To_View (B);
4566 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4567 return To_Vector (D);
4574 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4575 VA : constant VUS_View := To_View (To_LL_VUS (A));
4576 VB : constant VUS_View := To_View (To_LL_VUS (B));
4579 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4580 return To_LL_VSS (To_Vector (D));
4587 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4588 VA : constant VSS_View := To_View (A);
4589 VB : constant VSS_View := To_View (B);
4592 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4593 return To_Vector (D);
4600 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4601 VA : constant VUI_View := To_View (To_LL_VUI (A));
4602 VB : constant VUI_View := To_View (To_LL_VUI (B));
4605 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4606 return To_LL_VSI (To_Vector (D));
4613 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4614 VA : constant VSI_View := To_View (A);
4615 VB : constant VSI_View := To_View (B);
4618 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4619 return To_Vector (D);
4626 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4627 VA : constant VUC_View := To_View (To_LL_VUC (A));
4628 VB : constant VUI_View := To_View (To_LL_VUI (B));
4629 Offset : Vchar_Range;
4633 for J in 0 .. 3 loop
4634 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4635 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4636 LL_VUI_Operations.Saturate
4637 (UI64 (VA.Values (Offset))
4638 + UI64 (VA.Values (Offset + 1))
4639 + UI64 (VA.Values (Offset + 2))
4640 + UI64 (VA.Values (Offset + 3))
4641 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4644 return To_LL_VSI (To_Vector (D));
4651 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4652 VA : constant VSC_View := To_View (A);
4653 VB : constant VSI_View := To_View (B);
4654 Offset : Vchar_Range;
4658 for J in 0 .. 3 loop
4659 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4660 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4661 LL_VSI_Operations.Saturate
4662 (SI64 (VA.Values (Offset))
4663 + SI64 (VA.Values (Offset + 1))
4664 + SI64 (VA.Values (Offset + 2))
4665 + SI64 (VA.Values (Offset + 3))
4666 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4669 return To_Vector (D);
4676 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4677 VA : constant VSS_View := To_View (A);
4678 VB : constant VSI_View := To_View (B);
4679 Offset : Vshort_Range;
4683 for J in 0 .. 3 loop
4684 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4685 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4686 LL_VSI_Operations.Saturate
4687 (SI64 (VA.Values (Offset))
4688 + SI64 (VA.Values (Offset + 1))
4689 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4692 return To_Vector (D);
4699 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4700 VA : constant VSI_View := To_View (A);
4701 VB : constant VSI_View := To_View (B);
4702 Offset : Vint_Range;
4706 for J in 0 .. 1 loop
4707 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4708 D.Values (Offset) := 0;
4709 D.Values (Offset + 1) :=
4710 LL_VSI_Operations.Saturate
4711 (SI64 (VA.Values (Offset))
4712 + SI64 (VA.Values (Offset + 1))
4713 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4716 return To_Vector (D);
4723 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4724 VA : constant VSI_View := To_View (A);
4725 VB : constant VSI_View := To_View (B);
4727 Sum_Buffer : SI64 := 0;
4730 for J in Vint_Range'Range loop
4732 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4735 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4736 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4737 return To_Vector (D);
4744 function vrfiz (A : LL_VF) return LL_VF is
4745 VA : constant VF_View := To_View (A);
4748 for J in Vfloat_Range'Range loop
4749 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4752 return To_Vector (D);
4759 function vupkhsb (A : LL_VSC) return LL_VSS is
4760 VA : constant VSC_View := To_View (A);
4763 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4764 return To_Vector (D);
4771 function vupkhsh (A : LL_VSS) return LL_VSI is
4772 VA : constant VSS_View := To_View (A);
4775 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4776 return To_Vector (D);
4783 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4784 -- For vupkhpx and vupklpx (depending on Offset)
4786 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4787 VA : constant VUS_View := To_View (To_LL_VUS (A));
4793 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4795 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4805 for J in Vint_Range'Range loop
4806 K := Vshort_Range (Integer (J)
4807 - Integer (Vint_Range'First)
4808 + Integer (Vshort_Range'First)
4810 P16 := To_Pixel (VA.Values (K));
4811 P32.T := Sign_Extend (P16.T);
4812 P32.R := unsigned_char (P16.R);
4813 P32.G := unsigned_char (P16.G);
4814 P32.B := unsigned_char (P16.B);
4815 D.Values (J) := To_unsigned_int (P32);
4818 return To_LL_VSI (To_Vector (D));
4825 function vupkhpx (A : LL_VSS) return LL_VSI is
4827 return vupkxpx (A, 0);
4834 function vupklsb (A : LL_VSC) return LL_VSS is
4835 VA : constant VSC_View := To_View (A);
4839 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4840 Varray_signed_short'Length);
4841 return To_Vector (D);
4848 function vupklsh (A : LL_VSS) return LL_VSI is
4849 VA : constant VSS_View := To_View (A);
4853 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4854 Varray_signed_int'Length);
4855 return To_Vector (D);
4862 function vupklpx (A : LL_VSS) return LL_VSI is
4864 return vupkxpx (A, Varray_signed_int'Length);
4871 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4872 VA : constant VUI_View := To_View (To_LL_VUI (A));
4873 VB : constant VUI_View := To_View (To_LL_VUI (B));
4877 for J in Vint_Range'Range loop
4878 D.Values (J) := VA.Values (J) xor VB.Values (J);
4881 return To_LL_VSI (To_Vector (D));
4888 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4891 D := vcmpequb (B, C);
4892 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4899 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4902 D := vcmpequh (B, C);
4903 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4910 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4913 D := vcmpequw (B, C);
4914 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4921 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4924 D := vcmpeqfp (B, C);
4925 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4932 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4935 D := vcmpgtub (B, C);
4936 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4943 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4946 D := vcmpgtuh (B, C);
4947 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4954 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4957 D := vcmpgtuw (B, C);
4958 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4965 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4968 D := vcmpgtsb (B, C);
4969 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4976 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4979 D := vcmpgtsh (B, C);
4980 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4987 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4990 D := vcmpgtsw (B, C);
4991 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4998 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5001 D := vcmpgefp (B, C);
5002 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5009 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5012 D := vcmpgtfp (B, C);
5013 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5020 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5023 D := To_View (vcmpbfp (B, C));
5025 for J in Vint_Range'Range loop
5026 -- vcmpbfp is not returning the usual bool vector; do the conversion
5027 if D.Values (J) = 0 then
5028 D.Values (J) := Signed_Bool_False;
5030 D.Values (J) := Signed_Bool_True;
5034 return LL_VSI_Operations.Check_CR6 (A, D.Values);
5037 end GNAT.Altivec.Low_Level_Vectors;