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 D (K) := (if A (K) /= Component_Type'First
380 then abs (A (K)) else Component_Type'First);
390 function abss_vxi (A : Varray_Type) return Varray_Type is
394 for K in Varray_Type'Range loop
395 D (K) := Saturate (abs (SI64 (A (K))));
405 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
409 for J in Varray_Type'Range loop
410 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
420 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
424 for J in Varray_Type'Range loop
425 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
437 B : Varray_Type) return Varray_Type
442 for J in Varray_Type'Range loop
443 D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
453 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
456 EA : Integer_Address;
460 S := 16 / Number_Of_Elements;
461 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
462 Integer_Address (S));
463 J := Index_Type (((EA mod 16) / Integer_Address (S))
464 + Integer_Address (Index_Type'First));
467 Component : Component_Type;
468 for Component'Address use To_Address (EA);
480 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
484 for J in Varray_Type'Range loop
485 D (J) := (if A (J) > B (J) then A (J) else B (J));
495 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
497 Offset : constant Integer := Integer (Index_Type'First);
498 M : constant Integer := Number_Of_Elements / 2;
501 for J in 0 .. M - 1 loop
502 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
503 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
513 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
515 Offset : constant Integer := Integer (Index_Type'First);
516 M : constant Integer := Number_Of_Elements / 2;
519 for J in 0 .. M - 1 loop
520 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
521 D (Index_Type (2 * J + Offset + 1)) :=
522 B (Index_Type (J + Offset + M));
532 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
536 for J in Varray_Type'Range loop
537 D (J) := (if A (J) < B (J) then A (J) else B (J));
547 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
548 J : constant Integer :=
549 Integer (B) mod Number_Of_Elements
550 + Integer (Varray_Type'First);
554 for K in Varray_Type'Range loop
555 D (K) := A (Index_Type (J));
565 function vspltisx (A : c_int) return Varray_Type is
569 for J in Varray_Type'Range loop
570 D (J) := Sign_Extend (A);
583 Shift_Func : Bit_Operation) return Varray_Type
586 S : constant Component_Type :=
587 Component_Type (128 / Number_Of_Elements);
590 for J in Varray_Type'Range loop
591 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
601 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
603 EA : Integer_Address;
607 S := 16 / Number_Of_Elements;
608 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
609 Integer_Address (S));
610 J := Index_Type ((EA mod 16) / Integer_Address (S)
611 + Integer_Address (Index_Type'First));
614 Component : Component_Type;
615 for Component'Address use To_Address (EA);
625 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
629 for J in Varray_Type'Range loop
630 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
640 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
641 All_Element : Boolean := True;
642 Any_Element : Boolean := False;
645 for J in Varray_Type'Range loop
646 All_Element := All_Element and then (D (J) = Bool_True);
647 Any_Element := Any_Element or else (D (J) = Bool_True);
657 elsif A = CR6_EQ then
658 if not Any_Element then
664 elsif A = CR6_EQ_REV then
671 elsif A = CR6_LT_REV then
672 if not All_Element then
682 end Signed_Operations;
684 --------------------------------
685 -- Unsigned_Operations (spec) --
686 --------------------------------
689 type Component_Type is mod <>;
690 type Index_Type is range <>;
691 type Varray_Type is array (Index_Type) of Component_Type;
693 package Unsigned_Operations is
698 High : Natural) return Component_Type;
699 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
700 -- using big endian bit ordering.
705 Value : Unsigned_1) return Component_Type;
706 -- Write Value into X[Where:Where] (if it fits in) and return the result
707 -- (big endian bit ordering).
709 function Modular_Result (X : UI64) return Component_Type;
711 function Saturate (X : UI64) return Component_Type;
713 function Saturate (X : F64) return Component_Type;
715 function Saturate (X : SI64) return Component_Type;
717 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
719 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
721 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
723 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
725 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
727 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
729 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
731 type Bit_Operation is
733 (Value : Component_Type;
734 Amount : Natural) return Component_Type;
739 ROTL : Bit_Operation) return Varray_Type;
744 Shift_Func : Bit_Operation) return Varray_Type;
745 -- Vector shift (left or right, depending on Shift_Func)
747 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
749 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
751 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
752 -- If D is the result of a vcmp operation and A the flag for
753 -- the kind of operation (e.g CR6_LT), check the predicate
754 -- that corresponds to this flag.
756 end Unsigned_Operations;
758 --------------------------------
759 -- Unsigned_Operations (body) --
760 --------------------------------
762 package body Unsigned_Operations is
764 Number_Of_Elements : constant Integer :=
765 VECTOR_BIT / Component_Type'Size;
767 Bool_True : constant Component_Type := Component_Type'Last;
768 Bool_False : constant Component_Type := 0;
774 function Modular_Result (X : UI64) return Component_Type is
777 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
785 function Saturate (X : UI64) return Component_Type is
789 -- Saturation, as defined in
790 -- [PIM-4.1 Vector Status and Control Register]
792 D := Component_Type (UI64'Max
793 (UI64 (Component_Type'First),
795 (UI64 (Component_Type'Last),
798 if UI64 (D) /= X then
799 VSCR := Write_Bit (VSCR, SAT_POS, 1);
805 function Saturate (X : SI64) return Component_Type is
809 -- Saturation, as defined in
810 -- [PIM-4.1 Vector Status and Control Register]
812 D := Component_Type (SI64'Max
813 (SI64 (Component_Type'First),
815 (SI64 (Component_Type'Last),
818 if SI64 (D) /= X then
819 VSCR := Write_Bit (VSCR, SAT_POS, 1);
825 function Saturate (X : F64) return Component_Type is
829 -- Saturation, as defined in
830 -- [PIM-4.1 Vector Status and Control Register]
832 D := Component_Type (F64'Max
833 (F64 (Component_Type'First),
835 (F64 (Component_Type'Last),
839 VSCR := Write_Bit (VSCR, SAT_POS, 1);
852 High : Natural) return Component_Type
854 Mask : Component_Type := 0;
856 -- The Altivec ABI uses a big endian bit ordering, and we are
857 -- using little endian bit ordering for extracting bits:
859 Low_LE : constant Natural := Component_Type'Size - 1 - High;
860 High_LE : constant Natural := Component_Type'Size - 1 - Low;
863 pragma Assert (Low <= Component_Type'Size);
864 pragma Assert (High <= Component_Type'Size);
866 for J in Low_LE .. High_LE loop
867 Mask := Mask or 2 ** J;
870 return (X and Mask) / 2 ** Low_LE;
880 Value : Unsigned_1) return Component_Type
882 Result : Component_Type := 0;
884 -- The Altivec ABI uses a big endian bit ordering, and we are
885 -- using little endian bit ordering for extracting bits:
887 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
890 pragma Assert (Where < Component_Type'Size);
894 Result := X or 2 ** Where_LE;
896 Result := X and not (2 ** Where_LE);
906 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
910 for J in Varray_Type'Range loop
911 D (J) := A (J) + B (J);
921 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
925 for J in Varray_Type'Range loop
926 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
936 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
940 for J in Varray_Type'Range loop
941 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
953 B : Varray_Type) return Varray_Type
958 for J in Varray_Type'Range loop
959 D (J) := (if A (J) = B (J) then Bool_True else Bool_False);
971 B : Varray_Type) return Varray_Type
975 for J in Varray_Type'Range loop
976 D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
986 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
990 for J in Varray_Type'Range loop
991 D (J) := (if A (J) > B (J) then A (J) else B (J));
1001 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1005 for J in Varray_Type'Range loop
1006 D (J) := (if A (J) < B (J) then A (J) else B (J));
1019 ROTL : Bit_Operation) return Varray_Type
1024 for J in Varray_Type'Range loop
1025 D (J) := ROTL (A (J), Natural (B (J)));
1038 Shift_Func : Bit_Operation) return Varray_Type
1041 S : constant Component_Type :=
1042 Component_Type (128 / Number_Of_Elements);
1045 for J in Varray_Type'Range loop
1046 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1056 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1060 for J in Varray_Type'Range loop
1061 D (J) := A (J) - B (J);
1071 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1075 for J in Varray_Type'Range loop
1076 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1086 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1087 All_Element : Boolean := True;
1088 Any_Element : Boolean := False;
1091 for J in Varray_Type'Range loop
1092 All_Element := All_Element and then (D (J) = Bool_True);
1093 Any_Element := Any_Element or else (D (J) = Bool_True);
1103 elsif A = CR6_EQ then
1104 if not Any_Element then
1110 elsif A = CR6_EQ_REV then
1117 elsif A = CR6_LT_REV then
1118 if not All_Element then
1128 end Unsigned_Operations;
1130 --------------------------------------
1131 -- Signed_Merging_Operations (spec) --
1132 --------------------------------------
1135 type Component_Type is range <>;
1136 type Index_Type is range <>;
1137 type Varray_Type is array (Index_Type) of Component_Type;
1138 type Double_Component_Type is range <>;
1139 type Double_Index_Type is range <>;
1140 type Double_Varray_Type is array (Double_Index_Type)
1141 of Double_Component_Type;
1143 package Signed_Merging_Operations is
1145 pragma Assert (Integer (Varray_Type'First)
1146 = Integer (Double_Varray_Type'First));
1147 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1148 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1151 (X : Double_Component_Type) return Component_Type;
1154 (Use_Even_Components : Boolean;
1156 B : Varray_Type) return Double_Varray_Type;
1159 (A : Double_Varray_Type;
1160 B : Double_Varray_Type) return Varray_Type;
1161 pragma Convention (LL_Altivec, vpksxss);
1165 Offset : Natural) return Double_Varray_Type;
1167 end Signed_Merging_Operations;
1169 --------------------------------------
1170 -- Signed_Merging_Operations (body) --
1171 --------------------------------------
1173 package body Signed_Merging_Operations is
1180 (X : Double_Component_Type) return Component_Type
1185 -- Saturation, as defined in
1186 -- [PIM-4.1 Vector Status and Control Register]
1188 D := Component_Type (Double_Component_Type'Max
1189 (Double_Component_Type (Component_Type'First),
1190 Double_Component_Type'Min
1191 (Double_Component_Type (Component_Type'Last),
1194 if Double_Component_Type (D) /= X then
1195 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1206 (Use_Even_Components : Boolean;
1208 B : Varray_Type) return Double_Varray_Type
1210 Double_Offset : Double_Index_Type;
1211 Offset : Index_Type;
1212 D : Double_Varray_Type;
1213 N : constant Integer :=
1214 Integer (Double_Index_Type'Last)
1215 - Integer (Double_Index_Type'First) + 1;
1219 for J in 0 .. N - 1 loop
1221 Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
1222 Integer (Index_Type'First));
1225 Double_Index_Type (J + Integer (Double_Index_Type'First));
1226 D (Double_Offset) :=
1227 Double_Component_Type (A (Offset)) *
1228 Double_Component_Type (B (Offset));
1239 (A : Double_Varray_Type;
1240 B : Double_Varray_Type) return Varray_Type
1242 N : constant Index_Type :=
1243 Index_Type (Double_Index_Type'Last);
1245 Offset : Index_Type;
1246 Double_Offset : Double_Index_Type;
1249 for J in 0 .. N - 1 loop
1250 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1252 Double_Index_Type (Integer (J)
1253 + Integer (Double_Index_Type'First));
1254 D (Offset) := Saturate (A (Double_Offset));
1255 D (Offset + N) := Saturate (B (Double_Offset));
1267 Offset : Natural) return Double_Varray_Type
1270 D : Double_Varray_Type;
1273 for J in Double_Varray_Type'Range loop
1274 K := Index_Type (Integer (J)
1275 - Integer (Double_Index_Type'First)
1276 + Integer (Index_Type'First)
1278 D (J) := Double_Component_Type (A (K));
1284 end Signed_Merging_Operations;
1286 ----------------------------------------
1287 -- Unsigned_Merging_Operations (spec) --
1288 ----------------------------------------
1291 type Component_Type is mod <>;
1292 type Index_Type is range <>;
1293 type Varray_Type is array (Index_Type) of Component_Type;
1294 type Double_Component_Type is mod <>;
1295 type Double_Index_Type is range <>;
1296 type Double_Varray_Type is array (Double_Index_Type)
1297 of Double_Component_Type;
1299 package Unsigned_Merging_Operations is
1301 pragma Assert (Integer (Varray_Type'First)
1302 = Integer (Double_Varray_Type'First));
1303 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1304 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1306 function UI_To_UI_Mod
1307 (X : Double_Component_Type;
1308 Y : Natural) return Component_Type;
1310 function Saturate (X : Double_Component_Type) return Component_Type;
1313 (Use_Even_Components : Boolean;
1315 B : Varray_Type) return Double_Varray_Type;
1318 (A : Double_Varray_Type;
1319 B : Double_Varray_Type) return Varray_Type;
1322 (A : Double_Varray_Type;
1323 B : Double_Varray_Type) return Varray_Type;
1325 end Unsigned_Merging_Operations;
1327 ----------------------------------------
1328 -- Unsigned_Merging_Operations (body) --
1329 ----------------------------------------
1331 package body Unsigned_Merging_Operations is
1337 function UI_To_UI_Mod
1338 (X : Double_Component_Type;
1339 Y : Natural) return Component_Type is
1342 Z := Component_Type (X mod 2 ** Y);
1350 function Saturate (X : Double_Component_Type) return Component_Type is
1354 -- Saturation, as defined in
1355 -- [PIM-4.1 Vector Status and Control Register]
1357 D := Component_Type (Double_Component_Type'Max
1358 (Double_Component_Type (Component_Type'First),
1359 Double_Component_Type'Min
1360 (Double_Component_Type (Component_Type'Last),
1363 if Double_Component_Type (D) /= X then
1364 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1375 (Use_Even_Components : Boolean;
1377 B : Varray_Type) return Double_Varray_Type
1379 Double_Offset : Double_Index_Type;
1380 Offset : Index_Type;
1381 D : Double_Varray_Type;
1382 N : constant Integer :=
1383 Integer (Double_Index_Type'Last)
1384 - Integer (Double_Index_Type'First) + 1;
1387 for J in 0 .. N - 1 loop
1389 Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
1390 Integer (Index_Type'First));
1393 Double_Index_Type (J + Integer (Double_Index_Type'First));
1394 D (Double_Offset) :=
1395 Double_Component_Type (A (Offset)) *
1396 Double_Component_Type (B (Offset));
1407 (A : Double_Varray_Type;
1408 B : Double_Varray_Type) return Varray_Type
1410 S : constant Natural :=
1411 Double_Component_Type'Size / 2;
1412 N : constant Index_Type :=
1413 Index_Type (Double_Index_Type'Last);
1415 Offset : Index_Type;
1416 Double_Offset : Double_Index_Type;
1419 for J in 0 .. N - 1 loop
1420 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1422 Double_Index_Type (Integer (J)
1423 + Integer (Double_Index_Type'First));
1424 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1425 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1436 (A : Double_Varray_Type;
1437 B : Double_Varray_Type) return Varray_Type
1439 N : constant Index_Type :=
1440 Index_Type (Double_Index_Type'Last);
1442 Offset : Index_Type;
1443 Double_Offset : Double_Index_Type;
1446 for J in 0 .. N - 1 loop
1447 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1449 Double_Index_Type (Integer (J)
1450 + Integer (Double_Index_Type'First));
1451 D (Offset) := Saturate (A (Double_Offset));
1452 D (Offset + N) := Saturate (B (Double_Offset));
1458 end Unsigned_Merging_Operations;
1460 package LL_VSC_Operations is
1461 new Signed_Operations (signed_char,
1463 Varray_signed_char);
1465 package LL_VSS_Operations is
1466 new Signed_Operations (signed_short,
1468 Varray_signed_short);
1470 package LL_VSI_Operations is
1471 new Signed_Operations (signed_int,
1475 package LL_VUC_Operations is
1476 new Unsigned_Operations (unsigned_char,
1478 Varray_unsigned_char);
1480 package LL_VUS_Operations is
1481 new Unsigned_Operations (unsigned_short,
1483 Varray_unsigned_short);
1485 package LL_VUI_Operations is
1486 new Unsigned_Operations (unsigned_int,
1488 Varray_unsigned_int);
1490 package LL_VSC_LL_VSS_Operations is
1491 new Signed_Merging_Operations (signed_char,
1496 Varray_signed_short);
1498 package LL_VSS_LL_VSI_Operations is
1499 new Signed_Merging_Operations (signed_short,
1501 Varray_signed_short,
1506 package LL_VUC_LL_VUS_Operations is
1507 new Unsigned_Merging_Operations (unsigned_char,
1509 Varray_unsigned_char,
1512 Varray_unsigned_short);
1514 package LL_VUS_LL_VUI_Operations is
1515 new Unsigned_Merging_Operations (unsigned_short,
1517 Varray_unsigned_short,
1520 Varray_unsigned_int);
1529 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1532 (X : unsigned_short;
1534 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1539 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1548 Value : Unsigned_1) return unsigned_int
1549 renames LL_VUI_Operations.Write_Bit;
1552 (X : unsigned_short;
1554 Value : Unsigned_1) return unsigned_short
1555 renames LL_VUS_Operations.Write_Bit;
1560 Value : Unsigned_1) return unsigned_char
1561 renames LL_VUC_Operations.Write_Bit;
1567 function Bound_Align
1568 (X : Integer_Address;
1569 Y : Integer_Address) return Integer_Address
1571 D : Integer_Address;
1581 function NJ_Truncate (X : C_float) return C_float is
1585 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1586 and then abs (X) < 2.0 ** (-126)
1588 D := (if X < 0.0 then -0.0 else +0.0);
1596 -----------------------
1597 -- Rnd_To_FP_Nearest --
1598 -----------------------
1600 function Rnd_To_FP_Nearest (X : F64) return C_float is
1603 end Rnd_To_FP_Nearest;
1605 ---------------------
1606 -- Rnd_To_FPI_Near --
1607 ---------------------
1609 function Rnd_To_FPI_Near (X : F64) return F64 is
1614 Result := F64 (SI64 (X));
1616 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1620 Ceiling := F64'Ceiling (X);
1622 (if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling
1623 then Ceiling else Ceiling - 1.0);
1627 end Rnd_To_FPI_Near;
1629 ----------------------
1630 -- Rnd_To_FPI_Trunc --
1631 ----------------------
1633 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1637 Result := F64'Ceiling (X);
1639 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1643 and then Result /= X
1645 Result := Result - 1.0;
1649 end Rnd_To_FPI_Trunc;
1655 function FP_Recip_Est (X : C_float) return C_float is
1657 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1658 -- -Inf, or QNaN, the estimate has a relative error no greater
1659 -- than one part in 4096, that is:
1660 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1662 return NJ_Truncate (1.0 / NJ_Truncate (X));
1670 (Value : unsigned_char;
1671 Amount : Natural) return unsigned_char
1673 Result : Unsigned_8;
1675 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1676 return unsigned_char (Result);
1680 (Value : unsigned_short;
1681 Amount : Natural) return unsigned_short
1683 Result : Unsigned_16;
1685 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1686 return unsigned_short (Result);
1690 (Value : unsigned_int;
1691 Amount : Natural) return unsigned_int
1693 Result : Unsigned_32;
1695 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1696 return unsigned_int (Result);
1699 --------------------
1700 -- Recip_SQRT_Est --
1701 --------------------
1703 function Recip_SQRT_Est (X : C_float) return C_float is
1708 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1709 -- no greater than one part in 4096, that is:
1710 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1712 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1713 return NJ_Truncate (Result);
1721 (Value : unsigned_char;
1722 Amount : Natural) return unsigned_char
1724 Result : Unsigned_8;
1726 Result := Shift_Left (Unsigned_8 (Value), Amount);
1727 return unsigned_char (Result);
1731 (Value : unsigned_short;
1732 Amount : Natural) return unsigned_short
1734 Result : Unsigned_16;
1736 Result := Shift_Left (Unsigned_16 (Value), Amount);
1737 return unsigned_short (Result);
1741 (Value : unsigned_int;
1742 Amount : Natural) return unsigned_int
1744 Result : Unsigned_32;
1746 Result := Shift_Left (Unsigned_32 (Value), Amount);
1747 return unsigned_int (Result);
1754 function Shift_Right
1755 (Value : unsigned_char;
1756 Amount : Natural) return unsigned_char
1758 Result : Unsigned_8;
1760 Result := Shift_Right (Unsigned_8 (Value), Amount);
1761 return unsigned_char (Result);
1764 function Shift_Right
1765 (Value : unsigned_short;
1766 Amount : Natural) return unsigned_short
1768 Result : Unsigned_16;
1770 Result := Shift_Right (Unsigned_16 (Value), Amount);
1771 return unsigned_short (Result);
1774 function Shift_Right
1775 (Value : unsigned_int;
1776 Amount : Natural) return unsigned_int
1778 Result : Unsigned_32;
1780 Result := Shift_Right (Unsigned_32 (Value), Amount);
1781 return unsigned_int (Result);
1789 type Signed_Type is range <>;
1790 type Unsigned_Type is mod <>;
1791 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1792 return Unsigned_Type;
1793 function Shift_Right_Arithmetic
1794 (Value : Signed_Type;
1795 Amount : Natural) return Signed_Type;
1797 function Shift_Right_Arithmetic
1798 (Value : Signed_Type;
1799 Amount : Natural) return Signed_Type
1803 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1805 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1808 end Shift_Right_Arithmetic;
1810 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1814 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1818 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1825 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1827 -- This conversion should not depend on the host endianness;
1828 -- therefore, we cannot use an unchecked conversion.
1833 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1834 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1835 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1836 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1840 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1842 -- This conversion should not depend on the host endianness;
1843 -- therefore, we cannot use an unchecked conversion.
1848 Target.T := unsigned_char (Bits (Source, 0, 7));
1849 Target.R := unsigned_char (Bits (Source, 8, 15));
1850 Target.G := unsigned_char (Bits (Source, 16, 23));
1851 Target.B := unsigned_char (Bits (Source, 24, 31));
1855 ---------------------
1856 -- To_unsigned_int --
1857 ---------------------
1859 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1861 -- This conversion should not depend on the host endianness;
1862 -- therefore, we cannot use an unchecked conversion.
1863 -- It should also be the same result, value-wise, on two hosts
1864 -- with the same endianness.
1866 Target : unsigned_int := 0;
1869 -- In big endian bit ordering, Pixel_32 looks like:
1870 -- -------------------------------------
1871 -- | T | R | G | B |
1872 -- -------------------------------------
1873 -- 0 (MSB) 7 15 23 32
1875 -- Sizes of the components: (8/8/8/8)
1877 Target := Target or unsigned_int (Source.T);
1878 Target := Shift_Left (Target, 8);
1879 Target := Target or unsigned_int (Source.R);
1880 Target := Shift_Left (Target, 8);
1881 Target := Target or unsigned_int (Source.G);
1882 Target := Shift_Left (Target, 8);
1883 Target := Target or unsigned_int (Source.B);
1885 end To_unsigned_int;
1887 -----------------------
1888 -- To_unsigned_short --
1889 -----------------------
1891 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1893 -- This conversion should not depend on the host endianness;
1894 -- therefore, we cannot use an unchecked conversion.
1895 -- It should also be the same result, value-wise, on two hosts
1896 -- with the same endianness.
1898 Target : unsigned_short := 0;
1901 -- In big endian bit ordering, Pixel_16 looks like:
1902 -- -------------------------------------
1903 -- | T | R | G | B |
1904 -- -------------------------------------
1905 -- 0 (MSB) 1 5 11 15
1907 -- Sizes of the components: (1/5/5/5)
1909 Target := Target or unsigned_short (Source.T);
1910 Target := Shift_Left (Target, 5);
1911 Target := Target or unsigned_short (Source.R);
1912 Target := Shift_Left (Target, 5);
1913 Target := Target or unsigned_short (Source.G);
1914 Target := Shift_Left (Target, 5);
1915 Target := Target or unsigned_short (Source.B);
1917 end To_unsigned_short;
1923 function abs_v16qi (A : LL_VSC) return LL_VSC is
1924 VA : constant VSC_View := To_View (A);
1926 return To_Vector ((Values =>
1927 LL_VSC_Operations.abs_vxi (VA.Values)));
1934 function abs_v8hi (A : LL_VSS) return LL_VSS is
1935 VA : constant VSS_View := To_View (A);
1937 return To_Vector ((Values =>
1938 LL_VSS_Operations.abs_vxi (VA.Values)));
1945 function abs_v4si (A : LL_VSI) return LL_VSI is
1946 VA : constant VSI_View := To_View (A);
1948 return To_Vector ((Values =>
1949 LL_VSI_Operations.abs_vxi (VA.Values)));
1956 function abs_v4sf (A : LL_VF) return LL_VF is
1958 VA : constant VF_View := To_View (A);
1961 for J in Varray_float'Range loop
1962 D (J) := abs (VA.Values (J));
1965 return To_Vector ((Values => D));
1972 function abss_v16qi (A : LL_VSC) return LL_VSC is
1973 VA : constant VSC_View := To_View (A);
1975 return To_Vector ((Values =>
1976 LL_VSC_Operations.abss_vxi (VA.Values)));
1983 function abss_v8hi (A : LL_VSS) return LL_VSS is
1984 VA : constant VSS_View := To_View (A);
1986 return To_Vector ((Values =>
1987 LL_VSS_Operations.abss_vxi (VA.Values)));
1994 function abss_v4si (A : LL_VSI) return LL_VSI is
1995 VA : constant VSI_View := To_View (A);
1997 return To_Vector ((Values =>
1998 LL_VSI_Operations.abss_vxi (VA.Values)));
2005 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2006 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2008 VA : constant VUC_View :=
2010 VB : constant VUC_View := To_View (To_LL_VUC (B));
2011 D : Varray_unsigned_char;
2014 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2015 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2022 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2023 VA : constant VUS_View := To_View (To_LL_VUS (A));
2024 VB : constant VUS_View := To_View (To_LL_VUS (B));
2025 D : Varray_unsigned_short;
2028 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2029 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2036 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2037 VA : constant VUI_View := To_View (To_LL_VUI (A));
2038 VB : constant VUI_View := To_View (To_LL_VUI (B));
2039 D : Varray_unsigned_int;
2042 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2043 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2050 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2051 VA : constant VF_View := To_View (A);
2052 VB : constant VF_View := To_View (B);
2056 for J in Varray_float'Range loop
2057 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2058 + NJ_Truncate (VB.Values (J)));
2061 return To_Vector (VF_View'(Values => D));
2068 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2069 Addition_Result : UI64;
2071 VA : constant VUI_View := To_View (To_LL_VUI (A));
2072 VB : constant VUI_View := To_View (To_LL_VUI (B));
2075 for J in Varray_unsigned_int'Range loop
2076 Addition_Result := UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2078 (if Addition_Result > UI64 (unsigned_int'Last) then 1 else 0);
2081 return To_LL_VSI (To_Vector (D));
2088 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2089 VA : constant VUC_View := To_View (To_LL_VUC (A));
2090 VB : constant VUC_View := To_View (To_LL_VUC (B));
2093 return To_LL_VSC (To_Vector
2094 (VUC_View'(Values =>
2095 (LL_VUC_Operations.vadduxs
2104 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2105 VA : constant VSC_View := To_View (A);
2106 VB : constant VSC_View := To_View (B);
2110 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2111 return To_Vector (D);
2118 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2119 VA : constant VUS_View := To_View (To_LL_VUS (A));
2120 VB : constant VUS_View := To_View (To_LL_VUS (B));
2124 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2125 return To_LL_VSS (To_Vector (D));
2132 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2133 VA : constant VSS_View := To_View (A);
2134 VB : constant VSS_View := To_View (B);
2138 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2139 return To_Vector (D);
2146 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2147 VA : constant VUI_View := To_View (To_LL_VUI (A));
2148 VB : constant VUI_View := To_View (To_LL_VUI (B));
2152 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2153 return To_LL_VSI (To_Vector (D));
2160 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2161 VA : constant VSI_View := To_View (A);
2162 VB : constant VSI_View := To_View (B);
2166 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2167 return To_Vector (D);
2174 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2175 VA : constant VUI_View := To_View (To_LL_VUI (A));
2176 VB : constant VUI_View := To_View (To_LL_VUI (B));
2180 for J in Varray_unsigned_int'Range loop
2181 D.Values (J) := VA.Values (J) and VB.Values (J);
2184 return To_LL_VSI (To_Vector (D));
2191 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2192 VA : constant VUI_View := To_View (To_LL_VUI (A));
2193 VB : constant VUI_View := To_View (To_LL_VUI (B));
2197 for J in Varray_unsigned_int'Range loop
2198 D.Values (J) := VA.Values (J) and not VB.Values (J);
2201 return To_LL_VSI (To_Vector (D));
2208 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2209 VA : constant VUC_View := To_View (To_LL_VUC (A));
2210 VB : constant VUC_View := To_View (To_LL_VUC (B));
2214 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2215 return To_LL_VSC (To_Vector (D));
2222 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2223 VA : constant VSC_View := To_View (A);
2224 VB : constant VSC_View := To_View (B);
2228 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2229 return To_Vector (D);
2236 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2237 VA : constant VUS_View := To_View (To_LL_VUS (A));
2238 VB : constant VUS_View := To_View (To_LL_VUS (B));
2242 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2243 return To_LL_VSS (To_Vector (D));
2250 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2251 VA : constant VSS_View := To_View (A);
2252 VB : constant VSS_View := To_View (B);
2256 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2257 return To_Vector (D);
2264 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2265 VA : constant VUI_View := To_View (To_LL_VUI (A));
2266 VB : constant VUI_View := To_View (To_LL_VUI (B));
2270 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2271 return To_LL_VSI (To_Vector (D));
2278 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2279 VA : constant VSI_View := To_View (A);
2280 VB : constant VSI_View := To_View (B);
2284 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2285 return To_Vector (D);
2292 function vrfip (A : LL_VF) return LL_VF is
2293 VA : constant VF_View := To_View (A);
2297 for J in Varray_float'Range loop
2299 -- If A (J) is infinite, D (J) should be infinite; With
2300 -- IEEE floating points, we can use 'Ceiling for that purpose.
2302 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2306 return To_Vector (D);
2313 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2314 VA : constant VF_View := To_View (A);
2315 VB : constant VF_View := To_View (B);
2320 for J in Varray_float'Range loop
2321 K := Vint_Range (J);
2324 if NJ_Truncate (VB.Values (J)) < 0.0 then
2326 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2327 -- word element in B is negative; the corresponding element in A
2328 -- is out of bounds.
2330 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2331 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2335 (if NJ_Truncate (VA.Values (J)) <= NJ_Truncate (VB.Values (J))
2336 then Write_Bit (D.Values (K), 0, 0)
2337 else Write_Bit (D.Values (K), 0, 1));
2340 (if NJ_Truncate (VA.Values (J)) >= -NJ_Truncate (VB.Values (J))
2341 then Write_Bit (D.Values (K), 1, 0)
2342 else Write_Bit (D.Values (K), 1, 1));
2346 return To_LL_VSI (To_Vector (D));
2353 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2354 VA : constant VUC_View := To_View (To_LL_VUC (A));
2355 VB : constant VUC_View := To_View (To_LL_VUC (B));
2359 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2360 return To_LL_VSC (To_Vector (D));
2367 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2368 VA : constant VUS_View := To_View (To_LL_VUS (A));
2369 VB : constant VUS_View := To_View (To_LL_VUS (B));
2372 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2373 return To_LL_VSS (To_Vector (D));
2380 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2381 VA : constant VUI_View := To_View (To_LL_VUI (A));
2382 VB : constant VUI_View := To_View (To_LL_VUI (B));
2385 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2386 return To_LL_VSI (To_Vector (D));
2393 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2394 VA : constant VF_View := To_View (A);
2395 VB : constant VF_View := To_View (B);
2399 for J in Varray_float'Range loop
2400 D.Values (Vint_Range (J)) :=
2401 (if VA.Values (J) = VB.Values (J) then unsigned_int'Last else 0);
2404 return To_LL_VSI (To_Vector (D));
2411 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2412 VA : constant VF_View := To_View (A);
2413 VB : constant VF_View := To_View (B);
2417 for J in Varray_float'Range loop
2418 D.Values (Vint_Range (J)) :=
2419 (if VA.Values (J) >= VB.Values (J) then Signed_Bool_True
2420 else Signed_Bool_False);
2423 return To_Vector (D);
2430 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2431 VA : constant VUC_View := To_View (To_LL_VUC (A));
2432 VB : constant VUC_View := To_View (To_LL_VUC (B));
2435 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2436 return To_LL_VSC (To_Vector (D));
2443 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2444 VA : constant VSC_View := To_View (A);
2445 VB : constant VSC_View := To_View (B);
2448 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2449 return To_Vector (D);
2456 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2457 VA : constant VUS_View := To_View (To_LL_VUS (A));
2458 VB : constant VUS_View := To_View (To_LL_VUS (B));
2461 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2462 return To_LL_VSS (To_Vector (D));
2469 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2470 VA : constant VSS_View := To_View (A);
2471 VB : constant VSS_View := To_View (B);
2474 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2475 return To_Vector (D);
2482 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2483 VA : constant VUI_View := To_View (To_LL_VUI (A));
2484 VB : constant VUI_View := To_View (To_LL_VUI (B));
2487 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2488 return To_LL_VSI (To_Vector (D));
2495 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2496 VA : constant VSI_View := To_View (A);
2497 VB : constant VSI_View := To_View (B);
2500 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2501 return To_Vector (D);
2508 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2509 VA : constant VF_View := To_View (A);
2510 VB : constant VF_View := To_View (B);
2514 for J in Varray_float'Range loop
2515 D.Values (Vint_Range (J)) :=
2516 (if NJ_Truncate (VA.Values (J)) > NJ_Truncate (VB.Values (J))
2517 then Signed_Bool_True else Signed_Bool_False);
2520 return To_Vector (D);
2527 function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2529 VA : constant VUI_View := To_View (To_LL_VUI (A));
2533 for J in Varray_signed_int'Range loop
2534 K := Vfloat_Range (J);
2536 -- Note: The conversion to Integer is safe, as Integers are required
2537 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2538 -- include the range of B (should be 0 .. 255).
2541 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2544 return To_Vector (D);
2551 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2552 VA : constant VSI_View := To_View (A);
2557 for J in Varray_signed_int'Range loop
2558 K := Vfloat_Range (J);
2559 D.Values (K) := C_float (VA.Values (J))
2560 / (2.0 ** Integer (B));
2563 return To_Vector (D);
2570 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2571 VA : constant VF_View := To_View (A);
2576 for J in Varray_signed_int'Range loop
2577 K := Vfloat_Range (J);
2579 LL_VSI_Operations.Saturate
2580 (F64 (NJ_Truncate (VA.Values (K)))
2581 * F64 (2.0 ** Integer (B)));
2584 return To_Vector (D);
2591 function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2592 VA : constant VF_View := To_View (A);
2597 for J in Varray_unsigned_int'Range loop
2598 K := Vfloat_Range (J);
2600 LL_VUI_Operations.Saturate
2601 (F64 (NJ_Truncate (VA.Values (K)))
2602 * F64 (2.0 ** Integer (B)));
2605 return To_LL_VSI (To_Vector (D));
2612 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2614 procedure dss (A : c_int) is
2615 pragma Unreferenced (A);
2624 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2635 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2637 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2638 pragma Unreferenced (A);
2639 pragma Unreferenced (B);
2640 pragma Unreferenced (C);
2649 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2651 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2652 pragma Unreferenced (A);
2653 pragma Unreferenced (B);
2654 pragma Unreferenced (C);
2663 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2665 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2666 pragma Unreferenced (A);
2667 pragma Unreferenced (B);
2668 pragma Unreferenced (C);
2677 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2679 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2680 pragma Unreferenced (A);
2681 pragma Unreferenced (B);
2682 pragma Unreferenced (C);
2691 function vexptefp (A : LL_VF) return LL_VF is
2692 use C_float_Operations;
2694 VA : constant VF_View := To_View (A);
2698 for J in Varray_float'Range loop
2700 -- ??? Check the precision of the operation.
2701 -- As described in [PEM-6 vexptefp]:
2702 -- If theoretical_result is equal to 2 at the power of A (J) with
2703 -- infinite precision, we should have:
2704 -- abs ((D (J) - theoretical_result) / theoretical_result) <= 1/16
2706 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2709 return To_Vector (D);
2716 function vrfim (A : LL_VF) return LL_VF is
2717 VA : constant VF_View := To_View (A);
2721 for J in Varray_float'Range loop
2723 -- If A (J) is infinite, D (J) should be infinite; With
2724 -- IEEE floating point, we can use 'Ceiling for that purpose.
2726 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2728 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2731 if D.Values (J) /= VA.Values (J) then
2732 D.Values (J) := D.Values (J) - 1.0;
2736 return To_Vector (D);
2743 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2745 -- Simulate the altivec unit behavior regarding what Effective Address
2746 -- is accessed, stripping off the input address least significant bits
2747 -- wrt to vector alignment.
2749 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2750 -- an address within a vector is not necessarily rounded back at the
2751 -- vector start address. Besides, rounding on 16 makes no sense on such
2752 -- targets because the address of a properly aligned vector (that is,
2753 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2754 -- want never to happen.
2756 EA : constant System.Address :=
2759 (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2762 for D'Address use EA;
2772 function lvebx (A : c_long; B : c_ptr) return LL_VSC is
2775 D.Values := LL_VSC_Operations.lvexx (A, B);
2776 return To_Vector (D);
2783 function lvehx (A : c_long; B : c_ptr) return LL_VSS is
2786 D.Values := LL_VSS_Operations.lvexx (A, B);
2787 return To_Vector (D);
2794 function lvewx (A : c_long; B : c_ptr) return LL_VSI is
2797 D.Values := LL_VSI_Operations.lvexx (A, B);
2798 return To_Vector (D);
2805 function lvxl (A : c_long; B : c_ptr) return LL_VSI renames
2812 function vlogefp (A : LL_VF) return LL_VF is
2813 VA : constant VF_View := To_View (A);
2817 for J in Varray_float'Range loop
2819 -- ??? Check the precision of the operation.
2820 -- As described in [PEM-6 vlogefp]:
2821 -- If theorical_result is equal to the log2 of A (J) with
2822 -- infinite precision, we should have:
2823 -- abs (D (J) - theorical_result) <= 1/32,
2824 -- unless abs(D(J) - 1) <= 1/8.
2827 C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2830 return To_Vector (D);
2837 function lvsl (A : c_long; B : c_ptr) return LL_VSC is
2838 type bit4_type is mod 16#F# + 1;
2839 for bit4_type'Alignment use 1;
2840 EA : Integer_Address;
2845 EA := Integer_Address (A) + To_Integer (B);
2846 SH := bit4_type (EA mod 2 ** 4);
2848 for J in D.Values'Range loop
2849 D.Values (J) := unsigned_char (SH) + unsigned_char (J)
2850 - unsigned_char (D.Values'First);
2853 return To_LL_VSC (To_Vector (D));
2860 function lvsr (A : c_long; B : c_ptr) return LL_VSC is
2861 type bit4_type is mod 16#F# + 1;
2862 for bit4_type'Alignment use 1;
2863 EA : Integer_Address;
2868 EA := Integer_Address (A) + To_Integer (B);
2869 SH := bit4_type (EA mod 2 ** 4);
2871 for J in D.Values'Range loop
2872 D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2875 return To_LL_VSC (To_Vector (D));
2882 function vmaddfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
2883 VA : constant VF_View := To_View (A);
2884 VB : constant VF_View := To_View (B);
2885 VC : constant VF_View := To_View (C);
2889 for J in Varray_float'Range loop
2891 Rnd_To_FP_Nearest (F64 (VA.Values (J))
2892 * F64 (VB.Values (J))
2893 + F64 (VC.Values (J)));
2896 return To_Vector (D);
2903 function vmhaddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
2904 VA : constant VSS_View := To_View (A);
2905 VB : constant VSS_View := To_View (B);
2906 VC : constant VSS_View := To_View (C);
2910 for J in Varray_signed_short'Range loop
2911 D.Values (J) := LL_VSS_Operations.Saturate
2912 ((SI64 (VA.Values (J)) * SI64 (VB.Values (J)))
2913 / SI64 (2 ** 15) + SI64 (VC.Values (J)));
2916 return To_Vector (D);
2923 function vmaxub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2924 VA : constant VUC_View := To_View (To_LL_VUC (A));
2925 VB : constant VUC_View := To_View (To_LL_VUC (B));
2928 D.Values := LL_VUC_Operations.vmaxux (VA.Values, VB.Values);
2929 return To_LL_VSC (To_Vector (D));
2936 function vmaxsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2937 VA : constant VSC_View := To_View (A);
2938 VB : constant VSC_View := To_View (B);
2941 D.Values := LL_VSC_Operations.vmaxsx (VA.Values, VB.Values);
2942 return To_Vector (D);
2949 function vmaxuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2950 VA : constant VUS_View := To_View (To_LL_VUS (A));
2951 VB : constant VUS_View := To_View (To_LL_VUS (B));
2954 D.Values := LL_VUS_Operations.vmaxux (VA.Values, VB.Values);
2955 return To_LL_VSS (To_Vector (D));
2962 function vmaxsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2963 VA : constant VSS_View := To_View (A);
2964 VB : constant VSS_View := To_View (B);
2967 D.Values := LL_VSS_Operations.vmaxsx (VA.Values, VB.Values);
2968 return To_Vector (D);
2975 function vmaxuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2976 VA : constant VUI_View := To_View (To_LL_VUI (A));
2977 VB : constant VUI_View := To_View (To_LL_VUI (B));
2980 D.Values := LL_VUI_Operations.vmaxux (VA.Values, VB.Values);
2981 return To_LL_VSI (To_Vector (D));
2988 function vmaxsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2989 VA : constant VSI_View := To_View (A);
2990 VB : constant VSI_View := To_View (B);
2993 D.Values := LL_VSI_Operations.vmaxsx (VA.Values, VB.Values);
2994 return To_Vector (D);
3001 function vmaxfp (A : LL_VF; B : LL_VF) return LL_VF is
3002 VA : constant VF_View := To_View (A);
3003 VB : constant VF_View := To_View (B);
3007 for J in Varray_float'Range loop
3008 D.Values (J) := (if VA.Values (J) > VB.Values (J) then VA.Values (J)
3009 else VB.Values (J));
3012 return To_Vector (D);
3019 function vmrghb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3020 VA : constant VSC_View := To_View (A);
3021 VB : constant VSC_View := To_View (B);
3024 D.Values := LL_VSC_Operations.vmrghx (VA.Values, VB.Values);
3025 return To_Vector (D);
3032 function vmrghh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3033 VA : constant VSS_View := To_View (A);
3034 VB : constant VSS_View := To_View (B);
3037 D.Values := LL_VSS_Operations.vmrghx (VA.Values, VB.Values);
3038 return To_Vector (D);
3045 function vmrghw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3046 VA : constant VSI_View := To_View (A);
3047 VB : constant VSI_View := To_View (B);
3050 D.Values := LL_VSI_Operations.vmrghx (VA.Values, VB.Values);
3051 return To_Vector (D);
3058 function vmrglb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3059 VA : constant VSC_View := To_View (A);
3060 VB : constant VSC_View := To_View (B);
3063 D.Values := LL_VSC_Operations.vmrglx (VA.Values, VB.Values);
3064 return To_Vector (D);
3071 function vmrglh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3072 VA : constant VSS_View := To_View (A);
3073 VB : constant VSS_View := To_View (B);
3076 D.Values := LL_VSS_Operations.vmrglx (VA.Values, VB.Values);
3077 return To_Vector (D);
3084 function vmrglw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3085 VA : constant VSI_View := To_View (A);
3086 VB : constant VSI_View := To_View (B);
3089 D.Values := LL_VSI_Operations.vmrglx (VA.Values, VB.Values);
3090 return To_Vector (D);
3097 function mfvscr return LL_VSS is
3100 for J in Varray_unsigned_short'Range loop
3104 D.Values (Varray_unsigned_short'Last) :=
3105 unsigned_short (VSCR mod 2 ** unsigned_short'Size);
3106 D.Values (Varray_unsigned_short'Last - 1) :=
3107 unsigned_short (VSCR / 2 ** unsigned_short'Size);
3108 return To_LL_VSS (To_Vector (D));
3115 function vminfp (A : LL_VF; B : LL_VF) return LL_VF is
3116 VA : constant VF_View := To_View (A);
3117 VB : constant VF_View := To_View (B);
3121 for J in Varray_float'Range loop
3122 D.Values (J) := (if VA.Values (J) < VB.Values (J) then VA.Values (J)
3123 else VB.Values (J));
3126 return To_Vector (D);
3133 function vminsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3134 VA : constant VSC_View := To_View (A);
3135 VB : constant VSC_View := To_View (B);
3138 D.Values := LL_VSC_Operations.vminsx (VA.Values, VB.Values);
3139 return To_Vector (D);
3146 function vminub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3147 VA : constant VUC_View := To_View (To_LL_VUC (A));
3148 VB : constant VUC_View := To_View (To_LL_VUC (B));
3151 D.Values := LL_VUC_Operations.vminux (VA.Values, VB.Values);
3152 return To_LL_VSC (To_Vector (D));
3159 function vminsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3160 VA : constant VSS_View := To_View (A);
3161 VB : constant VSS_View := To_View (B);
3164 D.Values := LL_VSS_Operations.vminsx (VA.Values, VB.Values);
3165 return To_Vector (D);
3172 function vminuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3173 VA : constant VUS_View := To_View (To_LL_VUS (A));
3174 VB : constant VUS_View := To_View (To_LL_VUS (B));
3177 D.Values := LL_VUS_Operations.vminux (VA.Values, VB.Values);
3178 return To_LL_VSS (To_Vector (D));
3185 function vminsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3186 VA : constant VSI_View := To_View (A);
3187 VB : constant VSI_View := To_View (B);
3190 D.Values := LL_VSI_Operations.vminsx (VA.Values, VB.Values);
3191 return To_Vector (D);
3198 function vminuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3199 VA : constant VUI_View := To_View (To_LL_VUI (A));
3200 VB : constant VUI_View := To_View (To_LL_VUI (B));
3203 D.Values := LL_VUI_Operations.vminux (VA.Values,
3205 return To_LL_VSI (To_Vector (D));
3212 function vmladduhm (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3213 VA : constant VUS_View := To_View (To_LL_VUS (A));
3214 VB : constant VUS_View := To_View (To_LL_VUS (B));
3215 VC : constant VUS_View := To_View (To_LL_VUS (C));
3219 for J in Varray_unsigned_short'Range loop
3220 D.Values (J) := VA.Values (J) * VB.Values (J)
3224 return To_LL_VSS (To_Vector (D));
3231 function vmhraddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3232 VA : constant VSS_View := To_View (A);
3233 VB : constant VSS_View := To_View (B);
3234 VC : constant VSS_View := To_View (C);
3238 for J in Varray_signed_short'Range loop
3240 LL_VSS_Operations.Saturate (((SI64 (VA.Values (J))
3241 * SI64 (VB.Values (J))
3244 + SI64 (VC.Values (J))));
3247 return To_Vector (D);
3254 function vmsumubm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3255 Offset : Vchar_Range;
3256 VA : constant VUC_View := To_View (To_LL_VUC (A));
3257 VB : constant VUC_View := To_View (To_LL_VUC (B));
3258 VC : constant VUI_View := To_View (To_LL_VUI (C));
3262 for J in 0 .. 3 loop
3263 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3264 D.Values (Vint_Range
3265 (J + Integer (Vint_Range'First))) :=
3266 (unsigned_int (VA.Values (Offset))
3267 * unsigned_int (VB.Values (Offset)))
3268 + (unsigned_int (VA.Values (Offset + 1))
3269 * unsigned_int (VB.Values (1 + Offset)))
3270 + (unsigned_int (VA.Values (2 + Offset))
3271 * unsigned_int (VB.Values (2 + Offset)))
3272 + (unsigned_int (VA.Values (3 + Offset))
3273 * unsigned_int (VB.Values (3 + Offset)))
3274 + VC.Values (Vint_Range
3275 (J + Integer (Varray_unsigned_int'First)));
3278 return To_LL_VSI (To_Vector (D));
3285 function vmsummbm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3286 Offset : Vchar_Range;
3287 VA : constant VSC_View := To_View (A);
3288 VB : constant VUC_View := To_View (To_LL_VUC (B));
3289 VC : constant VSI_View := To_View (C);
3293 for J in 0 .. 3 loop
3294 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3295 D.Values (Vint_Range
3296 (J + Integer (Varray_unsigned_int'First))) := 0
3297 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3298 * SI64 (VB.Values (Offset)))
3299 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3302 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (2 + Offset))
3305 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (3 + Offset))
3308 + VC.Values (Vint_Range
3309 (J + Integer (Varray_unsigned_int'First)));
3312 return To_Vector (D);
3319 function vmsumuhm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3320 Offset : Vshort_Range;
3321 VA : constant VUS_View := To_View (To_LL_VUS (A));
3322 VB : constant VUS_View := To_View (To_LL_VUS (B));
3323 VC : constant VUI_View := To_View (To_LL_VUI (C));
3327 for J in 0 .. 3 loop
3329 Vshort_Range (2 * J + Integer (Vshort_Range'First));
3330 D.Values (Vint_Range
3331 (J + Integer (Varray_unsigned_int'First))) :=
3332 (unsigned_int (VA.Values (Offset))
3333 * unsigned_int (VB.Values (Offset)))
3334 + (unsigned_int (VA.Values (Offset + 1))
3335 * unsigned_int (VB.Values (1 + Offset)))
3336 + VC.Values (Vint_Range
3337 (J + Integer (Vint_Range'First)));
3340 return To_LL_VSI (To_Vector (D));
3347 function vmsumshm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3348 VA : constant VSS_View := To_View (A);
3349 VB : constant VSS_View := To_View (B);
3350 VC : constant VSI_View := To_View (C);
3351 Offset : Vshort_Range;
3355 for J in 0 .. 3 loop
3357 Vshort_Range (2 * J + Integer (Varray_signed_char'First));
3358 D.Values (Vint_Range
3359 (J + Integer (Varray_unsigned_int'First))) := 0
3360 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3361 * SI64 (VB.Values (Offset)))
3362 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3365 + VC.Values (Vint_Range
3366 (J + Integer (Varray_unsigned_int'First)));
3369 return To_Vector (D);
3376 function vmsumuhs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3377 Offset : Vshort_Range;
3378 VA : constant VUS_View := To_View (To_LL_VUS (A));
3379 VB : constant VUS_View := To_View (To_LL_VUS (B));
3380 VC : constant VUI_View := To_View (To_LL_VUI (C));
3384 for J in 0 .. 3 loop
3386 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3387 D.Values (Vint_Range
3388 (J + Integer (Varray_unsigned_int'First))) :=
3389 LL_VUI_Operations.Saturate
3390 (UI64 (VA.Values (Offset))
3391 * UI64 (VB.Values (Offset))
3392 + UI64 (VA.Values (Offset + 1))
3393 * UI64 (VB.Values (1 + Offset))
3396 (J + Integer (Varray_unsigned_int'First)))));
3399 return To_LL_VSI (To_Vector (D));
3406 function vmsumshs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3407 VA : constant VSS_View := To_View (A);
3408 VB : constant VSS_View := To_View (B);
3409 VC : constant VSI_View := To_View (C);
3410 Offset : Vshort_Range;
3414 for J in 0 .. 3 loop
3416 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3417 D.Values (Vint_Range
3418 (J + Integer (Varray_signed_int'First))) :=
3419 LL_VSI_Operations.Saturate
3420 (SI64 (VA.Values (Offset))
3421 * SI64 (VB.Values (Offset))
3422 + SI64 (VA.Values (Offset + 1))
3423 * SI64 (VB.Values (1 + Offset))
3426 (J + Integer (Varray_signed_int'First)))));
3429 return To_Vector (D);
3436 procedure mtvscr (A : LL_VSI) is
3437 VA : constant VUI_View := To_View (To_LL_VUI (A));
3439 VSCR := VA.Values (Varray_unsigned_int'Last);
3446 function vmuleub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3447 VA : constant VUC_View := To_View (To_LL_VUC (A));
3448 VB : constant VUC_View := To_View (To_LL_VUC (B));
3451 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (True,
3454 return To_LL_VSS (To_Vector (D));
3461 function vmuleuh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3462 VA : constant VUS_View := To_View (To_LL_VUS (A));
3463 VB : constant VUS_View := To_View (To_LL_VUS (B));
3466 D.Values := LL_VUS_LL_VUI_Operations.vmulxux (True,
3469 return To_LL_VSI (To_Vector (D));
3476 function vmulesb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3477 VA : constant VSC_View := To_View (A);
3478 VB : constant VSC_View := To_View (B);
3481 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (True,
3484 return To_Vector (D);
3491 function vmulesh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3492 VA : constant VSS_View := To_View (A);
3493 VB : constant VSS_View := To_View (B);
3496 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (True,
3499 return To_Vector (D);
3506 function vmuloub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3507 VA : constant VUC_View := To_View (To_LL_VUC (A));
3508 VB : constant VUC_View := To_View (To_LL_VUC (B));
3511 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (False,
3514 return To_LL_VSS (To_Vector (D));
3521 function vmulouh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3522 VA : constant VUS_View := To_View (To_LL_VUS (A));
3523 VB : constant VUS_View := To_View (To_LL_VUS (B));
3527 LL_VUS_LL_VUI_Operations.vmulxux (False, VA.Values, VB.Values);
3528 return To_LL_VSI (To_Vector (D));
3535 function vmulosb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3536 VA : constant VSC_View := To_View (A);
3537 VB : constant VSC_View := To_View (B);
3540 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (False,
3543 return To_Vector (D);
3550 function vmulosh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3551 VA : constant VSS_View := To_View (A);
3552 VB : constant VSS_View := To_View (B);
3555 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (False,
3558 return To_Vector (D);
3565 function vnmsubfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
3566 VA : constant VF_View := To_View (A);
3567 VB : constant VF_View := To_View (B);
3568 VC : constant VF_View := To_View (C);
3572 for J in Vfloat_Range'Range loop
3574 -Rnd_To_FP_Nearest (F64 (VA.Values (J))
3575 * F64 (VB.Values (J))
3576 - F64 (VC.Values (J)));
3579 return To_Vector (D);
3586 function vnor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3587 VA : constant VUI_View := To_View (To_LL_VUI (A));
3588 VB : constant VUI_View := To_View (To_LL_VUI (B));
3592 for J in Vint_Range'Range loop
3593 D.Values (J) := not (VA.Values (J) or VB.Values (J));
3596 return To_LL_VSI (To_Vector (D));
3603 function vor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3604 VA : constant VUI_View := To_View (To_LL_VUI (A));
3605 VB : constant VUI_View := To_View (To_LL_VUI (B));
3609 for J in Vint_Range'Range loop
3610 D.Values (J) := VA.Values (J) or VB.Values (J);
3613 return To_LL_VSI (To_Vector (D));
3620 function vpkuhum (A : LL_VSS; B : LL_VSS) return LL_VSC is
3621 VA : constant VUS_View := To_View (To_LL_VUS (A));
3622 VB : constant VUS_View := To_View (To_LL_VUS (B));
3625 D.Values := LL_VUC_LL_VUS_Operations.vpkuxum (VA.Values, VB.Values);
3626 return To_LL_VSC (To_Vector (D));
3633 function vpkuwum (A : LL_VSI; B : LL_VSI) return LL_VSS is
3634 VA : constant VUI_View := To_View (To_LL_VUI (A));
3635 VB : constant VUI_View := To_View (To_LL_VUI (B));
3638 D.Values := LL_VUS_LL_VUI_Operations.vpkuxum (VA.Values, VB.Values);
3639 return To_LL_VSS (To_Vector (D));
3646 function vpkpx (A : LL_VSI; B : LL_VSI) return LL_VSS is
3647 VA : constant VUI_View := To_View (To_LL_VUI (A));
3648 VB : constant VUI_View := To_View (To_LL_VUI (B));
3650 Offset : Vint_Range;
3655 for J in 0 .. 3 loop
3656 Offset := Vint_Range (J + Integer (Vshort_Range'First));
3657 P32 := To_Pixel (VA.Values (Offset));
3658 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3659 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3660 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3661 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3662 D.Values (Vshort_Range (Offset)) := To_unsigned_short (P16);
3663 P32 := To_Pixel (VB.Values (Offset));
3664 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3665 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3666 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3667 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3668 D.Values (Vshort_Range (Offset) + 4) := To_unsigned_short (P16);
3671 return To_LL_VSS (To_Vector (D));
3678 function vpkuhus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3679 VA : constant VUS_View := To_View (To_LL_VUS (A));
3680 VB : constant VUS_View := To_View (To_LL_VUS (B));
3683 D.Values := LL_VUC_LL_VUS_Operations.vpkuxus (VA.Values, VB.Values);
3684 return To_LL_VSC (To_Vector (D));
3691 function vpkuwus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3692 VA : constant VUI_View := To_View (To_LL_VUI (A));
3693 VB : constant VUI_View := To_View (To_LL_VUI (B));
3696 D.Values := LL_VUS_LL_VUI_Operations.vpkuxus (VA.Values, VB.Values);
3697 return To_LL_VSS (To_Vector (D));
3704 function vpkshss (A : LL_VSS; B : LL_VSS) return LL_VSC is
3705 VA : constant VSS_View := To_View (A);
3706 VB : constant VSS_View := To_View (B);
3709 D.Values := LL_VSC_LL_VSS_Operations.vpksxss (VA.Values, VB.Values);
3710 return To_Vector (D);
3717 function vpkswss (A : LL_VSI; B : LL_VSI) return LL_VSS is
3718 VA : constant VSI_View := To_View (A);
3719 VB : constant VSI_View := To_View (B);
3722 D.Values := LL_VSS_LL_VSI_Operations.vpksxss (VA.Values, VB.Values);
3723 return To_Vector (D);
3731 type Signed_Component_Type is range <>;
3732 type Signed_Index_Type is range <>;
3733 type Signed_Varray_Type is
3734 array (Signed_Index_Type) of Signed_Component_Type;
3735 type Unsigned_Component_Type is mod <>;
3736 type Unsigned_Index_Type is range <>;
3737 type Unsigned_Varray_Type is
3738 array (Unsigned_Index_Type) of Unsigned_Component_Type;
3741 (A : Signed_Varray_Type;
3742 B : Signed_Varray_Type) return Unsigned_Varray_Type;
3745 (A : Signed_Varray_Type;
3746 B : Signed_Varray_Type) return Unsigned_Varray_Type
3748 N : constant Unsigned_Index_Type :=
3749 Unsigned_Index_Type (Signed_Index_Type'Last);
3750 Offset : Unsigned_Index_Type;
3751 Signed_Offset : Signed_Index_Type;
3752 D : Unsigned_Varray_Type;
3755 (X : Signed_Component_Type) return Unsigned_Component_Type;
3756 -- Saturation, as defined in
3757 -- [PIM-4.1 Vector Status and Control Register]
3764 (X : Signed_Component_Type) return Unsigned_Component_Type
3766 D : Unsigned_Component_Type;
3769 D := Unsigned_Component_Type
3770 (Signed_Component_Type'Max
3771 (Signed_Component_Type (Unsigned_Component_Type'First),
3772 Signed_Component_Type'Min
3773 (Signed_Component_Type (Unsigned_Component_Type'Last),
3775 if Signed_Component_Type (D) /= X then
3776 VSCR := Write_Bit (VSCR, SAT_POS, 1);
3782 -- Start of processing for vpksxus
3785 for J in 0 .. N - 1 loop
3787 Unsigned_Index_Type (Integer (J)
3788 + Integer (Unsigned_Index_Type'First));
3790 Signed_Index_Type (Integer (J)
3791 + Integer (Signed_Index_Type'First));
3792 D (Offset) := Saturate (A (Signed_Offset));
3793 D (Offset + N) := Saturate (B (Signed_Offset));
3803 function vpkshus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3804 function vpkshus_Instance is
3805 new vpksxus (signed_short,
3807 Varray_signed_short,
3810 Varray_unsigned_char);
3812 VA : constant VSS_View := To_View (A);
3813 VB : constant VSS_View := To_View (B);
3817 D.Values := vpkshus_Instance (VA.Values, VB.Values);
3818 return To_LL_VSC (To_Vector (D));
3825 function vpkswus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3826 function vpkswus_Instance is
3827 new vpksxus (signed_int,
3832 Varray_unsigned_short);
3834 VA : constant VSI_View := To_View (A);
3835 VB : constant VSI_View := To_View (B);
3838 D.Values := vpkswus_Instance (VA.Values, VB.Values);
3839 return To_LL_VSS (To_Vector (D));
3846 function vperm_4si (A : LL_VSI; B : LL_VSI; C : LL_VSC) return LL_VSI is
3847 VA : constant VUC_View := To_View (To_LL_VUC (A));
3848 VB : constant VUC_View := To_View (To_LL_VUC (B));
3849 VC : constant VUC_View := To_View (To_LL_VUC (C));
3854 for N in Vchar_Range'Range loop
3855 J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
3856 + Integer (Vchar_Range'First));
3858 (if Bits (VC.Values (N), 3, 3) = 0 then VA.Values (J)
3859 else VB.Values (J));
3862 return To_LL_VSI (To_Vector (D));
3869 function vrefp (A : LL_VF) return LL_VF is
3870 VA : constant VF_View := To_View (A);
3874 for J in Vfloat_Range'Range loop
3875 D.Values (J) := FP_Recip_Est (VA.Values (J));
3878 return To_Vector (D);
3885 function vrlb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3886 VA : constant VUC_View := To_View (To_LL_VUC (A));
3887 VB : constant VUC_View := To_View (To_LL_VUC (B));
3890 D.Values := LL_VUC_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3891 return To_LL_VSC (To_Vector (D));
3898 function vrlh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3899 VA : constant VUS_View := To_View (To_LL_VUS (A));
3900 VB : constant VUS_View := To_View (To_LL_VUS (B));
3903 D.Values := LL_VUS_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3904 return To_LL_VSS (To_Vector (D));
3911 function vrlw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3912 VA : constant VUI_View := To_View (To_LL_VUI (A));
3913 VB : constant VUI_View := To_View (To_LL_VUI (B));
3916 D.Values := LL_VUI_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3917 return To_LL_VSI (To_Vector (D));
3924 function vrfin (A : LL_VF) return LL_VF is
3925 VA : constant VF_View := To_View (A);
3929 for J in Vfloat_Range'Range loop
3930 D.Values (J) := C_float (Rnd_To_FPI_Near (F64 (VA.Values (J))));
3933 return To_Vector (D);
3940 function vrsqrtefp (A : LL_VF) return LL_VF is
3941 VA : constant VF_View := To_View (A);
3945 for J in Vfloat_Range'Range loop
3946 D.Values (J) := Recip_SQRT_Est (VA.Values (J));
3949 return To_Vector (D);
3956 function vsel_4si (A : LL_VSI; B : LL_VSI; C : LL_VSI) return LL_VSI is
3957 VA : constant VUI_View := To_View (To_LL_VUI (A));
3958 VB : constant VUI_View := To_View (To_LL_VUI (B));
3959 VC : constant VUI_View := To_View (To_LL_VUI (C));
3963 for J in Vint_Range'Range loop
3964 D.Values (J) := ((not VC.Values (J)) and VA.Values (J))
3965 or (VC.Values (J) and VB.Values (J));
3968 return To_LL_VSI (To_Vector (D));
3975 function vslb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3976 VA : constant VUC_View := To_View (To_LL_VUC (A));
3977 VB : constant VUC_View := To_View (To_LL_VUC (B));
3981 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
3982 return To_LL_VSC (To_Vector (D));
3989 function vslh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3990 VA : constant VUS_View := To_View (To_LL_VUS (A));
3991 VB : constant VUS_View := To_View (To_LL_VUS (B));
3995 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
3996 return To_LL_VSS (To_Vector (D));
4003 function vslw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4004 VA : constant VUI_View := To_View (To_LL_VUI (A));
4005 VB : constant VUI_View := To_View (To_LL_VUI (B));
4009 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4010 return To_LL_VSI (To_Vector (D));
4017 function vsldoi_4si (A : LL_VSI; B : LL_VSI; C : c_int) return LL_VSI is
4018 VA : constant VUC_View := To_View (To_LL_VUC (A));
4019 VB : constant VUC_View := To_View (To_LL_VUC (B));
4025 for J in Vchar_Range'Range loop
4026 Offset := c_int (J) + C;
4027 Bound := c_int (Vchar_Range'First)
4028 + c_int (Varray_unsigned_char'Length);
4030 if Offset < Bound then
4031 D.Values (J) := VA.Values (Vchar_Range (Offset));
4034 VB.Values (Vchar_Range (Offset - Bound
4035 + c_int (Vchar_Range'First)));
4039 return To_LL_VSI (To_Vector (D));
4046 function vsldoi_8hi (A : LL_VSS; B : LL_VSS; C : c_int) return LL_VSS is
4048 return To_LL_VSS (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4055 function vsldoi_16qi (A : LL_VSC; B : LL_VSC; C : c_int) return LL_VSC is
4057 return To_LL_VSC (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4064 function vsldoi_4sf (A : LL_VF; B : LL_VF; C : c_int) return LL_VF is
4066 return To_LL_VF (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4073 function vsl (A : LL_VSI; B : LL_VSI) return LL_VSI is
4074 VA : constant VUI_View := To_View (To_LL_VUI (A));
4075 VB : constant VUI_View := To_View (To_LL_VUI (B));
4077 M : constant Natural :=
4078 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4080 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4081 -- must be the same. Otherwise the value placed into D is undefined."
4082 -- ??? Shall we add a optional check for B?
4085 for J in Vint_Range'Range loop
4087 D.Values (J) := D.Values (J) + Shift_Left (VA.Values (J), M);
4089 if J /= Vint_Range'Last then
4091 D.Values (J) + Shift_Right (VA.Values (J + 1),
4092 signed_int'Size - M);
4096 return To_LL_VSI (To_Vector (D));
4103 function vslo (A : LL_VSI; B : LL_VSI) return LL_VSI is
4104 VA : constant VUC_View := To_View (To_LL_VUC (A));
4105 VB : constant VUC_View := To_View (To_LL_VUC (B));
4107 M : constant Natural :=
4108 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4112 for N in Vchar_Range'Range loop
4113 J := Natural (N) + M;
4115 (if J <= Natural (Vchar_Range'Last) then VA.Values (Vchar_Range (J))
4119 return To_LL_VSI (To_Vector (D));
4126 function vspltb (A : LL_VSC; B : c_int) return LL_VSC is
4127 VA : constant VSC_View := To_View (A);
4130 D.Values := LL_VSC_Operations.vspltx (VA.Values, B);
4131 return To_Vector (D);
4138 function vsplth (A : LL_VSS; B : c_int) return LL_VSS is
4139 VA : constant VSS_View := To_View (A);
4142 D.Values := LL_VSS_Operations.vspltx (VA.Values, B);
4143 return To_Vector (D);
4150 function vspltw (A : LL_VSI; B : c_int) return LL_VSI is
4151 VA : constant VSI_View := To_View (A);
4154 D.Values := LL_VSI_Operations.vspltx (VA.Values, B);
4155 return To_Vector (D);
4162 function vspltisb (A : c_int) return LL_VSC is
4165 D.Values := LL_VSC_Operations.vspltisx (A);
4166 return To_Vector (D);
4173 function vspltish (A : c_int) return LL_VSS is
4176 D.Values := LL_VSS_Operations.vspltisx (A);
4177 return To_Vector (D);
4184 function vspltisw (A : c_int) return LL_VSI is
4187 D.Values := LL_VSI_Operations.vspltisx (A);
4188 return To_Vector (D);
4195 function vsrb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4196 VA : constant VUC_View := To_View (To_LL_VUC (A));
4197 VB : constant VUC_View := To_View (To_LL_VUC (B));
4201 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4202 return To_LL_VSC (To_Vector (D));
4209 function vsrh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4210 VA : constant VUS_View := To_View (To_LL_VUS (A));
4211 VB : constant VUS_View := To_View (To_LL_VUS (B));
4215 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4216 return To_LL_VSS (To_Vector (D));
4223 function vsrw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4224 VA : constant VUI_View := To_View (To_LL_VUI (A));
4225 VB : constant VUI_View := To_View (To_LL_VUI (B));
4229 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4230 return To_LL_VSI (To_Vector (D));
4237 function vsrab (A : LL_VSC; B : LL_VSC) return LL_VSC is
4238 VA : constant VSC_View := To_View (A);
4239 VB : constant VSC_View := To_View (B);
4243 LL_VSC_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4244 return To_Vector (D);
4251 function vsrah (A : LL_VSS; B : LL_VSS) return LL_VSS is
4252 VA : constant VSS_View := To_View (A);
4253 VB : constant VSS_View := To_View (B);
4257 LL_VSS_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4258 return To_Vector (D);
4265 function vsraw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4266 VA : constant VSI_View := To_View (A);
4267 VB : constant VSI_View := To_View (B);
4271 LL_VSI_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4272 return To_Vector (D);
4279 function vsr (A : LL_VSI; B : LL_VSI) return LL_VSI is
4280 VA : constant VUI_View := To_View (To_LL_VUI (A));
4281 VB : constant VUI_View := To_View (To_LL_VUI (B));
4282 M : constant Natural :=
4283 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4287 for J in Vint_Range'Range loop
4289 D.Values (J) := D.Values (J) + Shift_Right (VA.Values (J), M);
4291 if J /= Vint_Range'First then
4294 + Shift_Left (VA.Values (J - 1), signed_int'Size - M);
4298 return To_LL_VSI (To_Vector (D));
4305 function vsro (A : LL_VSI; B : LL_VSI) return LL_VSI is
4306 VA : constant VUC_View := To_View (To_LL_VUC (A));
4307 VB : constant VUC_View := To_View (To_LL_VUC (B));
4308 M : constant Natural :=
4309 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4314 for N in Vchar_Range'Range loop
4315 J := Natural (N) - M;
4317 if J >= Natural (Vchar_Range'First) then
4318 D.Values (N) := VA.Values (Vchar_Range (J));
4324 return To_LL_VSI (To_Vector (D));
4331 procedure stvx (A : LL_VSI; B : c_int; C : c_ptr) is
4333 -- Simulate the altivec unit behavior regarding what Effective Address
4334 -- is accessed, stripping off the input address least significant bits
4335 -- wrt to vector alignment (see comment in lvx for further details).
4337 EA : constant System.Address :=
4340 (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4343 for D'Address use EA;
4353 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4354 VA : constant VSC_View := To_View (A);
4356 LL_VSC_Operations.stvexx (VA.Values, B, C);
4363 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4364 VA : constant VSS_View := To_View (A);
4366 LL_VSS_Operations.stvexx (VA.Values, B, C);
4373 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4374 VA : constant VSI_View := To_View (A);
4376 LL_VSI_Operations.stvexx (VA.Values, B, C);
4383 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4389 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4390 VA : constant VUC_View := To_View (To_LL_VUC (A));
4391 VB : constant VUC_View := To_View (To_LL_VUC (B));
4394 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4395 return To_LL_VSC (To_Vector (D));
4402 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4403 VA : constant VUS_View := To_View (To_LL_VUS (A));
4404 VB : constant VUS_View := To_View (To_LL_VUS (B));
4407 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4408 return To_LL_VSS (To_Vector (D));
4415 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4416 VA : constant VUI_View := To_View (To_LL_VUI (A));
4417 VB : constant VUI_View := To_View (To_LL_VUI (B));
4420 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4421 return To_LL_VSI (To_Vector (D));
4428 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4429 VA : constant VF_View := To_View (A);
4430 VB : constant VF_View := To_View (B);
4434 for J in Vfloat_Range'Range loop
4436 NJ_Truncate (NJ_Truncate (VA.Values (J))
4437 - NJ_Truncate (VB.Values (J)));
4440 return To_Vector (D);
4447 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4448 Subst_Result : SI64;
4450 VA : constant VUI_View := To_View (To_LL_VUI (A));
4451 VB : constant VUI_View := To_View (To_LL_VUI (B));
4455 for J in Vint_Range'Range loop
4456 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4458 (if Subst_Result < SI64 (unsigned_int'First) then 0 else 1);
4461 return To_LL_VSI (To_Vector (D));
4468 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4469 VA : constant VUC_View := To_View (To_LL_VUC (A));
4470 VB : constant VUC_View := To_View (To_LL_VUC (B));
4473 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4474 return To_LL_VSC (To_Vector (D));
4481 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4482 VA : constant VSC_View := To_View (A);
4483 VB : constant VSC_View := To_View (B);
4486 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4487 return To_Vector (D);
4494 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4495 VA : constant VUS_View := To_View (To_LL_VUS (A));
4496 VB : constant VUS_View := To_View (To_LL_VUS (B));
4499 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4500 return To_LL_VSS (To_Vector (D));
4507 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4508 VA : constant VSS_View := To_View (A);
4509 VB : constant VSS_View := To_View (B);
4512 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4513 return To_Vector (D);
4520 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4521 VA : constant VUI_View := To_View (To_LL_VUI (A));
4522 VB : constant VUI_View := To_View (To_LL_VUI (B));
4525 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4526 return To_LL_VSI (To_Vector (D));
4533 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4534 VA : constant VSI_View := To_View (A);
4535 VB : constant VSI_View := To_View (B);
4538 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4539 return To_Vector (D);
4546 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4547 VA : constant VUC_View := To_View (To_LL_VUC (A));
4548 VB : constant VUI_View := To_View (To_LL_VUI (B));
4549 Offset : Vchar_Range;
4553 for J in 0 .. 3 loop
4554 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4555 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4556 LL_VUI_Operations.Saturate
4557 (UI64 (VA.Values (Offset))
4558 + UI64 (VA.Values (Offset + 1))
4559 + UI64 (VA.Values (Offset + 2))
4560 + UI64 (VA.Values (Offset + 3))
4561 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4564 return To_LL_VSI (To_Vector (D));
4571 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4572 VA : constant VSC_View := To_View (A);
4573 VB : constant VSI_View := To_View (B);
4574 Offset : Vchar_Range;
4578 for J in 0 .. 3 loop
4579 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4580 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4581 LL_VSI_Operations.Saturate
4582 (SI64 (VA.Values (Offset))
4583 + SI64 (VA.Values (Offset + 1))
4584 + SI64 (VA.Values (Offset + 2))
4585 + SI64 (VA.Values (Offset + 3))
4586 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4589 return To_Vector (D);
4596 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4597 VA : constant VSS_View := To_View (A);
4598 VB : constant VSI_View := To_View (B);
4599 Offset : Vshort_Range;
4603 for J in 0 .. 3 loop
4604 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4605 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4606 LL_VSI_Operations.Saturate
4607 (SI64 (VA.Values (Offset))
4608 + SI64 (VA.Values (Offset + 1))
4609 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4612 return To_Vector (D);
4619 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4620 VA : constant VSI_View := To_View (A);
4621 VB : constant VSI_View := To_View (B);
4622 Offset : Vint_Range;
4626 for J in 0 .. 1 loop
4627 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4628 D.Values (Offset) := 0;
4629 D.Values (Offset + 1) :=
4630 LL_VSI_Operations.Saturate
4631 (SI64 (VA.Values (Offset))
4632 + SI64 (VA.Values (Offset + 1))
4633 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4636 return To_Vector (D);
4643 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4644 VA : constant VSI_View := To_View (A);
4645 VB : constant VSI_View := To_View (B);
4647 Sum_Buffer : SI64 := 0;
4650 for J in Vint_Range'Range loop
4652 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4655 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4656 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4657 return To_Vector (D);
4664 function vrfiz (A : LL_VF) return LL_VF is
4665 VA : constant VF_View := To_View (A);
4668 for J in Vfloat_Range'Range loop
4669 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4672 return To_Vector (D);
4679 function vupkhsb (A : LL_VSC) return LL_VSS is
4680 VA : constant VSC_View := To_View (A);
4683 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4684 return To_Vector (D);
4691 function vupkhsh (A : LL_VSS) return LL_VSI is
4692 VA : constant VSS_View := To_View (A);
4695 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4696 return To_Vector (D);
4703 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4704 -- For vupkhpx and vupklpx (depending on Offset)
4706 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4707 VA : constant VUS_View := To_View (To_LL_VUS (A));
4713 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4715 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4725 for J in Vint_Range'Range loop
4726 K := Vshort_Range (Integer (J)
4727 - Integer (Vint_Range'First)
4728 + Integer (Vshort_Range'First)
4730 P16 := To_Pixel (VA.Values (K));
4731 P32.T := Sign_Extend (P16.T);
4732 P32.R := unsigned_char (P16.R);
4733 P32.G := unsigned_char (P16.G);
4734 P32.B := unsigned_char (P16.B);
4735 D.Values (J) := To_unsigned_int (P32);
4738 return To_LL_VSI (To_Vector (D));
4745 function vupkhpx (A : LL_VSS) return LL_VSI is
4747 return vupkxpx (A, 0);
4754 function vupklsb (A : LL_VSC) return LL_VSS is
4755 VA : constant VSC_View := To_View (A);
4759 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4760 Varray_signed_short'Length);
4761 return To_Vector (D);
4768 function vupklsh (A : LL_VSS) return LL_VSI is
4769 VA : constant VSS_View := To_View (A);
4773 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4774 Varray_signed_int'Length);
4775 return To_Vector (D);
4782 function vupklpx (A : LL_VSS) return LL_VSI is
4784 return vupkxpx (A, Varray_signed_int'Length);
4791 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4792 VA : constant VUI_View := To_View (To_LL_VUI (A));
4793 VB : constant VUI_View := To_View (To_LL_VUI (B));
4797 for J in Vint_Range'Range loop
4798 D.Values (J) := VA.Values (J) xor VB.Values (J);
4801 return To_LL_VSI (To_Vector (D));
4808 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4811 D := vcmpequb (B, C);
4812 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4819 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4822 D := vcmpequh (B, C);
4823 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4830 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4833 D := vcmpequw (B, C);
4834 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4841 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4844 D := vcmpeqfp (B, C);
4845 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4852 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4855 D := vcmpgtub (B, C);
4856 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4863 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4866 D := vcmpgtuh (B, C);
4867 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4874 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4877 D := vcmpgtuw (B, C);
4878 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4885 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4888 D := vcmpgtsb (B, C);
4889 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4896 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4899 D := vcmpgtsh (B, C);
4900 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4907 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4910 D := vcmpgtsw (B, C);
4911 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4918 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4921 D := vcmpgefp (B, C);
4922 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4929 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4932 D := vcmpgtfp (B, C);
4933 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4940 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4943 D := To_View (vcmpbfp (B, C));
4945 for J in Vint_Range'Range loop
4947 -- vcmpbfp is not returning the usual bool vector; do the conversion
4950 (if D.Values (J) = 0 then Signed_Bool_False else Signed_Bool_True);
4953 return LL_VSI_Operations.Check_CR6 (A, D.Values);
4956 end GNAT.Altivec.Low_Level_Vectors;