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-2007, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 -- ??? What is exactly needed for the soft case is still a bit unclear on
36 -- some accounts. The expected functional equivalence with the Hard binding
37 -- might require tricky things to be done on some targets.
39 -- Examples that come to mind are endianness variations or differences in the
40 -- base FP model while we need the operation results to be the same as what
41 -- the real AltiVec instructions would do on a PowerPC.
43 with Ada.Numerics.Generic_Elementary_Functions;
44 with Interfaces; use Interfaces;
45 with System.Storage_Elements; use System.Storage_Elements;
47 with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions;
48 with GNAT.Altivec.Low_Level_Interface; use GNAT.Altivec.Low_Level_Interface;
50 package body GNAT.Altivec.Low_Level_Vectors is
52 -- Pixel types. As defined in [PIM-2.1 Data types]:
53 -- A 16-bit pixel is 1/5/5/5;
54 -- A 32-bit pixel is 8/8/8/8.
55 -- We use the following records as an intermediate representation, to
58 type Unsigned_1 is mod 2 ** 1;
59 type Unsigned_5 is mod 2 ** 5;
61 type Pixel_16 is record
68 type Pixel_32 is record
75 -- Conversions to/from the pixel records to the integer types that are
76 -- actually stored into the pixel vectors:
78 function To_Pixel (Source : unsigned_short) return Pixel_16;
79 function To_unsigned_short (Source : Pixel_16) return unsigned_short;
80 function To_Pixel (Source : unsigned_int) return Pixel_32;
81 function To_unsigned_int (Source : Pixel_32) return unsigned_int;
83 package C_float_Operations is
84 new Ada.Numerics.Generic_Elementary_Functions (C_float);
86 -- Model of the Vector Status and Control Register (VSCR), as
87 -- defined in [PIM-4.1 Vector Status and Control Register]:
91 -- Positions of the flags in VSCR(0 .. 31):
93 NJ_POS : constant := 15;
94 SAT_POS : constant := 31;
96 -- To control overflows, integer operations are done on 64-bit types:
98 SINT64_MIN : constant := -2 ** 63;
99 SINT64_MAX : constant := 2 ** 63 - 1;
100 UINT64_MAX : constant := 2 ** 64 - 1;
102 type SI64 is range SINT64_MIN .. SINT64_MAX;
103 type UI64 is mod UINT64_MAX + 1;
105 type F64 is digits 15
106 range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
111 High : Natural) return unsigned_int;
116 High : Natural) return unsigned_short;
121 High : Natural) return unsigned_char;
126 Value : Unsigned_1) return unsigned_int;
131 Value : Unsigned_1) return unsigned_short;
136 Value : Unsigned_1) return unsigned_char;
138 function NJ_Truncate (X : C_float) return C_float;
139 -- If NJ and A is a denormalized number, return zero
142 (X : Integer_Address;
143 Y : Integer_Address) return Integer_Address;
144 -- [PIM-4.3 Notations and Conventions]
145 -- Align X in a y-byte boundary and return the result
147 function Rnd_To_FP_Nearest (X : F64) return C_float;
148 -- [PIM-4.3 Notations and Conventions]
150 function Rnd_To_FPI_Near (X : F64) return F64;
152 function Rnd_To_FPI_Trunc (X : F64) return F64;
154 function FP_Recip_Est (X : C_float) return C_float;
155 -- [PIM-4.3 Notations and Conventions]
156 -- 12-bit accurate floating-point estimate of 1/x
159 (Value : unsigned_char;
160 Amount : Natural) return unsigned_char;
161 -- [PIM-4.3 Notations and Conventions]
165 (Value : unsigned_short;
166 Amount : Natural) return unsigned_short;
169 (Value : unsigned_int;
170 Amount : Natural) return unsigned_int;
172 function Recip_SQRT_Est (X : C_float) return C_float;
175 (Value : unsigned_char;
176 Amount : Natural) return unsigned_char;
177 -- [PIM-4.3 Notations and Conventions]
181 (Value : unsigned_short;
182 Amount : Natural) return unsigned_short;
185 (Value : unsigned_int;
186 Amount : Natural) return unsigned_int;
189 (Value : unsigned_char;
190 Amount : Natural) return unsigned_char;
191 -- [PIM-4.3 Notations and Conventions]
195 (Value : unsigned_short;
196 Amount : Natural) return unsigned_short;
199 (Value : unsigned_int;
200 Amount : Natural) return unsigned_int;
202 Signed_Bool_False : constant := 0;
203 Signed_Bool_True : constant := -1;
205 ------------------------------
206 -- Signed_Operations (spec) --
207 ------------------------------
210 type Component_Type is range <>;
211 type Index_Type is range <>;
212 type Varray_Type is array (Index_Type) of Component_Type;
214 package Signed_Operations is
216 function Modular_Result (X : SI64) return Component_Type;
218 function Saturate (X : SI64) return Component_Type;
220 function Saturate (X : F64) return Component_Type;
222 function Sign_Extend (X : c_int) return Component_Type;
223 -- [PIM-4.3 Notations and Conventions]
226 function abs_vxi (A : Varray_Type) return Varray_Type;
227 pragma Convention (LL_Altivec, abs_vxi);
229 function abss_vxi (A : Varray_Type) return Varray_Type;
230 pragma Convention (LL_Altivec, abss_vxi);
232 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
233 pragma Convention (LL_Altivec, vaddsxs);
235 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
236 pragma Convention (LL_Altivec, vavgsx);
238 function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
239 pragma Convention (LL_Altivec, vcmpgtsx);
241 function lvexx (A : c_long; B : c_ptr) return Varray_Type;
242 pragma Convention (LL_Altivec, lvexx);
244 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
245 pragma Convention (LL_Altivec, vmaxsx);
247 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
248 pragma Convention (LL_Altivec, vmrghx);
250 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
251 pragma Convention (LL_Altivec, vmrglx);
253 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
254 pragma Convention (LL_Altivec, vminsx);
256 function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
257 pragma Convention (LL_Altivec, vspltx);
259 function vspltisx (A : c_int) return Varray_Type;
260 pragma Convention (LL_Altivec, vspltisx);
262 type Bit_Operation is
264 (Value : Component_Type;
265 Amount : Natural) return Component_Type;
270 Shift_Func : Bit_Operation) return Varray_Type;
272 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
273 pragma Convention (LL_Altivec, stvexx);
275 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
276 pragma Convention (LL_Altivec, vsubsxs);
278 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
279 -- If D is the result of a vcmp operation and A the flag for
280 -- the kind of operation (e.g CR6_LT), check the predicate
281 -- that corresponds to this flag.
283 end Signed_Operations;
285 ------------------------------
286 -- Signed_Operations (body) --
287 ------------------------------
289 package body Signed_Operations is
291 Bool_True : constant Component_Type := Signed_Bool_True;
292 Bool_False : constant Component_Type := Signed_Bool_False;
294 Number_Of_Elements : constant Integer :=
295 VECTOR_BIT / Component_Type'Size;
301 function Modular_Result (X : SI64) return Component_Type is
306 D := Component_Type (UI64 (X)
307 mod (UI64 (Component_Type'Last) + 1));
309 D := Component_Type ((-(UI64 (-X)
310 mod (UI64 (Component_Type'Last) + 1))));
320 function Saturate (X : SI64) return Component_Type is
324 -- Saturation, as defined in
325 -- [PIM-4.1 Vector Status and Control Register]
327 D := Component_Type (SI64'Max
328 (SI64 (Component_Type'First),
330 (SI64 (Component_Type'Last),
333 if SI64 (D) /= X then
334 VSCR := Write_Bit (VSCR, SAT_POS, 1);
340 function Saturate (X : F64) return Component_Type is
344 -- Saturation, as defined in
345 -- [PIM-4.1 Vector Status and Control Register]
347 D := Component_Type (F64'Max
348 (F64 (Component_Type'First),
350 (F64 (Component_Type'Last),
354 VSCR := Write_Bit (VSCR, SAT_POS, 1);
364 function Sign_Extend (X : c_int) return Component_Type is
366 -- X is usually a 5-bits literal. In the case of the simulator,
367 -- it is an integral parameter, so sign extension is straightforward.
369 return Component_Type (X);
376 function abs_vxi (A : Varray_Type) return Varray_Type is
380 for K in Varray_Type'Range loop
381 if A (K) /= Component_Type'First then
382 D (K) := abs (A (K));
384 D (K) := Component_Type'First;
395 function abss_vxi (A : Varray_Type) return Varray_Type is
399 for K in Varray_Type'Range loop
400 D (K) := Saturate (abs (SI64 (A (K))));
410 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
414 for J in Varray_Type'Range loop
415 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
425 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
429 for J in Varray_Type'Range loop
430 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
442 B : Varray_Type) return Varray_Type
447 for J in Varray_Type'Range loop
448 if A (J) > B (J) then
462 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
465 EA : Integer_Address;
469 S := 16 / Number_Of_Elements;
470 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
471 Integer_Address (S));
472 J := Index_Type (((EA mod 16) / Integer_Address (S))
473 + Integer_Address (Index_Type'First));
476 Component : Component_Type;
477 for Component'Address use To_Address (EA);
489 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
493 for J in Varray_Type'Range loop
494 if A (J) > B (J) then
508 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
510 Offset : constant Integer := Integer (Index_Type'First);
511 M : constant Integer := Number_Of_Elements / 2;
514 for J in 0 .. M - 1 loop
515 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
516 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
526 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
528 Offset : constant Integer := Integer (Index_Type'First);
529 M : constant Integer := Number_Of_Elements / 2;
532 for J in 0 .. M - 1 loop
533 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
534 D (Index_Type (2 * J + Offset + 1)) :=
535 B (Index_Type (J + Offset + M));
545 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
549 for J in Varray_Type'Range loop
550 if A (J) < B (J) then
564 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
565 J : constant Integer :=
566 Integer (B) mod Number_Of_Elements
567 + Integer (Varray_Type'First);
571 for K in Varray_Type'Range loop
572 D (K) := A (Index_Type (J));
582 function vspltisx (A : c_int) return Varray_Type is
586 for J in Varray_Type'Range loop
587 D (J) := Sign_Extend (A);
600 Shift_Func : Bit_Operation) return Varray_Type
603 S : constant Component_Type :=
604 Component_Type (128 / Number_Of_Elements);
607 for J in Varray_Type'Range loop
608 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
618 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
620 EA : Integer_Address;
624 S := 16 / Number_Of_Elements;
625 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
626 Integer_Address (S));
627 J := Index_Type ((EA mod 16) / Integer_Address (S)
628 + Integer_Address (Index_Type'First));
631 Component : Component_Type;
632 for Component'Address use To_Address (EA);
642 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
646 for J in Varray_Type'Range loop
647 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
657 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
658 All_Element : Boolean := True;
659 Any_Element : Boolean := False;
662 for J in Varray_Type'Range loop
663 All_Element := All_Element and (D (J) = Bool_True);
664 Any_Element := Any_Element or (D (J) = Bool_True);
674 elsif A = CR6_EQ then
675 if not Any_Element then
681 elsif A = CR6_EQ_REV then
688 elsif A = CR6_LT_REV then
689 if not All_Element then
699 end Signed_Operations;
701 --------------------------------
702 -- Unsigned_Operations (spec) --
703 --------------------------------
706 type Component_Type is mod <>;
707 type Index_Type is range <>;
708 type Varray_Type is array (Index_Type) of Component_Type;
710 package Unsigned_Operations is
715 High : Natural) return Component_Type;
716 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
717 -- using big endian bit ordering.
722 Value : Unsigned_1) return Component_Type;
723 -- Write Value into X[Where:Where] (if it fits in) and return the result
724 -- (big endian bit ordering).
726 function Modular_Result (X : UI64) return Component_Type;
728 function Saturate (X : UI64) return Component_Type;
730 function Saturate (X : F64) return Component_Type;
732 function Saturate (X : SI64) return Component_Type;
734 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
736 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
738 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
740 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
742 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
744 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
746 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
748 type Bit_Operation is
750 (Value : Component_Type;
751 Amount : Natural) return Component_Type;
756 ROTL : Bit_Operation) return Varray_Type;
761 Shift_Func : Bit_Operation) return Varray_Type;
762 -- Vector shift (left or right, depending on Shift_Func)
764 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
766 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
768 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
769 -- If D is the result of a vcmp operation and A the flag for
770 -- the kind of operation (e.g CR6_LT), check the predicate
771 -- that corresponds to this flag.
773 end Unsigned_Operations;
775 --------------------------------
776 -- Unsigned_Operations (body) --
777 --------------------------------
779 package body Unsigned_Operations is
781 Number_Of_Elements : constant Integer :=
782 VECTOR_BIT / Component_Type'Size;
784 Bool_True : constant Component_Type := Component_Type'Last;
785 Bool_False : constant Component_Type := 0;
791 function Modular_Result (X : UI64) return Component_Type is
794 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
802 function Saturate (X : UI64) return Component_Type is
806 -- Saturation, as defined in
807 -- [PIM-4.1 Vector Status and Control Register]
809 D := Component_Type (UI64'Max
810 (UI64 (Component_Type'First),
812 (UI64 (Component_Type'Last),
815 if UI64 (D) /= X then
816 VSCR := Write_Bit (VSCR, SAT_POS, 1);
822 function Saturate (X : SI64) return Component_Type is
826 -- Saturation, as defined in
827 -- [PIM-4.1 Vector Status and Control Register]
829 D := Component_Type (SI64'Max
830 (SI64 (Component_Type'First),
832 (SI64 (Component_Type'Last),
835 if SI64 (D) /= X then
836 VSCR := Write_Bit (VSCR, SAT_POS, 1);
842 function Saturate (X : F64) return Component_Type is
846 -- Saturation, as defined in
847 -- [PIM-4.1 Vector Status and Control Register]
849 D := Component_Type (F64'Max
850 (F64 (Component_Type'First),
852 (F64 (Component_Type'Last),
856 VSCR := Write_Bit (VSCR, SAT_POS, 1);
869 High : Natural) return Component_Type
871 Mask : Component_Type := 0;
873 -- The Altivec ABI uses a big endian bit ordering, and we are
874 -- using little endian bit ordering for extracting bits:
876 Low_LE : constant Natural := Component_Type'Size - 1 - High;
877 High_LE : constant Natural := Component_Type'Size - 1 - Low;
880 pragma Assert (Low <= Component_Type'Size);
881 pragma Assert (High <= Component_Type'Size);
883 for J in Low_LE .. High_LE loop
884 Mask := Mask or 2 ** J;
887 return (X and Mask) / 2 ** Low_LE;
897 Value : Unsigned_1) return Component_Type
899 Result : Component_Type := 0;
901 -- The Altivec ABI uses a big endian bit ordering, and we are
902 -- using little endian bit ordering for extracting bits:
904 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
907 pragma Assert (Where < Component_Type'Size);
911 Result := X or 2 ** Where_LE;
913 Result := X and not (2 ** Where_LE);
923 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
927 for J in Varray_Type'Range loop
928 D (J) := A (J) + B (J);
938 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
942 for J in Varray_Type'Range loop
943 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
953 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
957 for J in Varray_Type'Range loop
958 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
970 B : Varray_Type) return Varray_Type
975 for J in Varray_Type'Range loop
976 if A (J) = B (J) then
992 B : Varray_Type) return Varray_Type
996 for J in Varray_Type'Range loop
997 if A (J) > B (J) then
1000 D (J) := Bool_False;
1011 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1015 for J in Varray_Type'Range loop
1016 if A (J) > B (J) then
1030 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1034 for J in Varray_Type'Range loop
1035 if A (J) < B (J) then
1052 ROTL : Bit_Operation) return Varray_Type
1057 for J in Varray_Type'Range loop
1058 D (J) := ROTL (A (J), Natural (B (J)));
1071 Shift_Func : Bit_Operation) return Varray_Type
1074 S : constant Component_Type :=
1075 Component_Type (128 / Number_Of_Elements);
1078 for J in Varray_Type'Range loop
1079 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1089 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1093 for J in Varray_Type'Range loop
1094 D (J) := A (J) - B (J);
1104 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1108 for J in Varray_Type'Range loop
1109 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1119 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1120 All_Element : Boolean := True;
1121 Any_Element : Boolean := False;
1124 for J in Varray_Type'Range loop
1125 All_Element := All_Element and (D (J) = Bool_True);
1126 Any_Element := Any_Element or (D (J) = Bool_True);
1136 elsif A = CR6_EQ then
1137 if not Any_Element then
1143 elsif A = CR6_EQ_REV then
1150 elsif A = CR6_LT_REV then
1151 if not All_Element then
1161 end Unsigned_Operations;
1163 --------------------------------------
1164 -- Signed_Merging_Operations (spec) --
1165 --------------------------------------
1168 type Component_Type is range <>;
1169 type Index_Type is range <>;
1170 type Varray_Type is array (Index_Type) of Component_Type;
1171 type Double_Component_Type is range <>;
1172 type Double_Index_Type is range <>;
1173 type Double_Varray_Type is array (Double_Index_Type)
1174 of Double_Component_Type;
1176 package Signed_Merging_Operations is
1178 pragma Assert (Integer (Varray_Type'First)
1179 = Integer (Double_Varray_Type'First));
1180 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1181 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1184 (X : Double_Component_Type) return Component_Type;
1187 (Use_Even_Components : Boolean;
1189 B : Varray_Type) return Double_Varray_Type;
1192 (A : Double_Varray_Type;
1193 B : Double_Varray_Type) return Varray_Type;
1194 pragma Convention (LL_Altivec, vpksxss);
1198 Offset : Natural) return Double_Varray_Type;
1200 end Signed_Merging_Operations;
1202 --------------------------------------
1203 -- Signed_Merging_Operations (body) --
1204 --------------------------------------
1206 package body Signed_Merging_Operations is
1213 (X : Double_Component_Type) return Component_Type
1218 -- Saturation, as defined in
1219 -- [PIM-4.1 Vector Status and Control Register]
1221 D := Component_Type (Double_Component_Type'Max
1222 (Double_Component_Type (Component_Type'First),
1223 Double_Component_Type'Min
1224 (Double_Component_Type (Component_Type'Last),
1227 if Double_Component_Type (D) /= X then
1228 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1239 (Use_Even_Components : Boolean;
1241 B : Varray_Type) return Double_Varray_Type
1243 Double_Offset : Double_Index_Type;
1244 Offset : Index_Type;
1245 D : Double_Varray_Type;
1246 N : constant Integer :=
1247 Integer (Double_Index_Type'Last)
1248 - Integer (Double_Index_Type'First) + 1;
1252 for J in 0 .. N - 1 loop
1253 if Use_Even_Components then
1254 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1256 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1260 Double_Index_Type (J + Integer (Double_Index_Type'First));
1261 D (Double_Offset) :=
1262 Double_Component_Type (A (Offset))
1263 * Double_Component_Type (B (Offset));
1274 (A : Double_Varray_Type;
1275 B : Double_Varray_Type) return Varray_Type
1277 N : constant Index_Type :=
1278 Index_Type (Double_Index_Type'Last);
1280 Offset : Index_Type;
1281 Double_Offset : Double_Index_Type;
1284 for J in 0 .. N - 1 loop
1285 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1287 Double_Index_Type (Integer (J)
1288 + Integer (Double_Index_Type'First));
1289 D (Offset) := Saturate (A (Double_Offset));
1290 D (Offset + N) := Saturate (B (Double_Offset));
1302 Offset : Natural) return Double_Varray_Type
1305 D : Double_Varray_Type;
1308 for J in Double_Varray_Type'Range loop
1309 K := Index_Type (Integer (J)
1310 - Integer (Double_Index_Type'First)
1311 + Integer (Index_Type'First)
1313 D (J) := Double_Component_Type (A (K));
1319 end Signed_Merging_Operations;
1321 ----------------------------------------
1322 -- Unsigned_Merging_Operations (spec) --
1323 ----------------------------------------
1326 type Component_Type is mod <>;
1327 type Index_Type is range <>;
1328 type Varray_Type is array (Index_Type) of Component_Type;
1329 type Double_Component_Type is mod <>;
1330 type Double_Index_Type is range <>;
1331 type Double_Varray_Type is array (Double_Index_Type)
1332 of Double_Component_Type;
1334 package Unsigned_Merging_Operations is
1336 pragma Assert (Integer (Varray_Type'First)
1337 = Integer (Double_Varray_Type'First));
1338 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1339 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1341 function UI_To_UI_Mod
1342 (X : Double_Component_Type;
1343 Y : Natural) return Component_Type;
1345 function Saturate (X : Double_Component_Type) return Component_Type;
1348 (Use_Even_Components : Boolean;
1350 B : Varray_Type) return Double_Varray_Type;
1353 (A : Double_Varray_Type;
1354 B : Double_Varray_Type) return Varray_Type;
1357 (A : Double_Varray_Type;
1358 B : Double_Varray_Type) return Varray_Type;
1360 end Unsigned_Merging_Operations;
1362 ----------------------------------------
1363 -- Unsigned_Merging_Operations (body) --
1364 ----------------------------------------
1366 package body Unsigned_Merging_Operations is
1372 function UI_To_UI_Mod
1373 (X : Double_Component_Type;
1374 Y : Natural) return Component_Type is
1377 Z := Component_Type (X mod 2 ** Y);
1385 function Saturate (X : Double_Component_Type) return Component_Type is
1389 -- Saturation, as defined in
1390 -- [PIM-4.1 Vector Status and Control Register]
1392 D := Component_Type (Double_Component_Type'Max
1393 (Double_Component_Type (Component_Type'First),
1394 Double_Component_Type'Min
1395 (Double_Component_Type (Component_Type'Last),
1398 if Double_Component_Type (D) /= X then
1399 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1410 (Use_Even_Components : Boolean;
1412 B : Varray_Type) return Double_Varray_Type
1414 Double_Offset : Double_Index_Type;
1415 Offset : Index_Type;
1416 D : Double_Varray_Type;
1417 N : constant Integer :=
1418 Integer (Double_Index_Type'Last)
1419 - Integer (Double_Index_Type'First) + 1;
1422 for J in 0 .. N - 1 loop
1423 if Use_Even_Components then
1424 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1426 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1430 Double_Index_Type (J + Integer (Double_Index_Type'First));
1431 D (Double_Offset) :=
1432 Double_Component_Type (A (Offset))
1433 * Double_Component_Type (B (Offset));
1444 (A : Double_Varray_Type;
1445 B : Double_Varray_Type) return Varray_Type
1447 S : constant Natural :=
1448 Double_Component_Type'Size / 2;
1449 N : constant Index_Type :=
1450 Index_Type (Double_Index_Type'Last);
1452 Offset : Index_Type;
1453 Double_Offset : Double_Index_Type;
1456 for J in 0 .. N - 1 loop
1457 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1459 Double_Index_Type (Integer (J)
1460 + Integer (Double_Index_Type'First));
1461 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1462 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1473 (A : Double_Varray_Type;
1474 B : Double_Varray_Type) return Varray_Type
1476 N : constant Index_Type :=
1477 Index_Type (Double_Index_Type'Last);
1479 Offset : Index_Type;
1480 Double_Offset : Double_Index_Type;
1483 for J in 0 .. N - 1 loop
1484 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1486 Double_Index_Type (Integer (J)
1487 + Integer (Double_Index_Type'First));
1488 D (Offset) := Saturate (A (Double_Offset));
1489 D (Offset + N) := Saturate (B (Double_Offset));
1495 end Unsigned_Merging_Operations;
1497 package LL_VSC_Operations is
1498 new Signed_Operations (signed_char,
1500 Varray_signed_char);
1502 package LL_VSS_Operations is
1503 new Signed_Operations (signed_short,
1505 Varray_signed_short);
1507 package LL_VSI_Operations is
1508 new Signed_Operations (signed_int,
1512 package LL_VUC_Operations is
1513 new Unsigned_Operations (unsigned_char,
1515 Varray_unsigned_char);
1517 package LL_VUS_Operations is
1518 new Unsigned_Operations (unsigned_short,
1520 Varray_unsigned_short);
1522 package LL_VUI_Operations is
1523 new Unsigned_Operations (unsigned_int,
1525 Varray_unsigned_int);
1527 package LL_VSC_LL_VSS_Operations is
1528 new Signed_Merging_Operations (signed_char,
1533 Varray_signed_short);
1535 package LL_VSS_LL_VSI_Operations is
1536 new Signed_Merging_Operations (signed_short,
1538 Varray_signed_short,
1543 package LL_VUC_LL_VUS_Operations is
1544 new Unsigned_Merging_Operations (unsigned_char,
1546 Varray_unsigned_char,
1549 Varray_unsigned_short);
1551 package LL_VUS_LL_VUI_Operations is
1552 new Unsigned_Merging_Operations (unsigned_short,
1554 Varray_unsigned_short,
1557 Varray_unsigned_int);
1566 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1569 (X : unsigned_short;
1571 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1576 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1585 Value : Unsigned_1) return unsigned_int
1586 renames LL_VUI_Operations.Write_Bit;
1589 (X : unsigned_short;
1591 Value : Unsigned_1) return unsigned_short
1592 renames LL_VUS_Operations.Write_Bit;
1597 Value : Unsigned_1) return unsigned_char
1598 renames LL_VUC_Operations.Write_Bit;
1604 function Bound_Align
1605 (X : Integer_Address;
1606 Y : Integer_Address) return Integer_Address
1608 D : Integer_Address;
1618 function NJ_Truncate (X : C_float) return C_float is
1622 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1623 and then abs (X) < 2.0 ** (-126)
1637 -----------------------
1638 -- Rnd_To_FP_Nearest --
1639 -----------------------
1641 function Rnd_To_FP_Nearest (X : F64) return C_float is
1644 end Rnd_To_FP_Nearest;
1646 ---------------------
1647 -- Rnd_To_FPI_Near --
1648 ---------------------
1650 function Rnd_To_FPI_Near (X : F64) return F64 is
1654 Result := F64 (SI64 (X));
1656 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1658 Ceiling := F64'Ceiling (X);
1659 if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling then
1662 Result := Ceiling - 1.0;
1667 end Rnd_To_FPI_Near;
1669 ----------------------
1670 -- Rnd_To_FPI_Trunc --
1671 ----------------------
1673 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1677 Result := F64'Ceiling (X);
1679 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1683 and then Result /= X
1685 Result := Result - 1.0;
1689 end Rnd_To_FPI_Trunc;
1695 function FP_Recip_Est (X : C_float) return C_float is
1697 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1698 -- -Inf, or QNaN, the estimate has a relative error no greater
1699 -- than one part in 4096, that is:
1700 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1702 return NJ_Truncate (1.0 / NJ_Truncate (X));
1710 (Value : unsigned_char;
1711 Amount : Natural) return unsigned_char
1713 Result : Unsigned_8;
1715 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1716 return unsigned_char (Result);
1720 (Value : unsigned_short;
1721 Amount : Natural) return unsigned_short
1723 Result : Unsigned_16;
1725 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1726 return unsigned_short (Result);
1730 (Value : unsigned_int;
1731 Amount : Natural) return unsigned_int
1733 Result : Unsigned_32;
1735 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1736 return unsigned_int (Result);
1739 --------------------
1740 -- Recip_SQRT_Est --
1741 --------------------
1743 function Recip_SQRT_Est (X : C_float) return C_float is
1748 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1749 -- no greater than one part in 4096, that is:
1750 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1752 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1753 return NJ_Truncate (Result);
1761 (Value : unsigned_char;
1762 Amount : Natural) return unsigned_char
1764 Result : Unsigned_8;
1766 Result := Shift_Left (Unsigned_8 (Value), Amount);
1767 return unsigned_char (Result);
1771 (Value : unsigned_short;
1772 Amount : Natural) return unsigned_short
1774 Result : Unsigned_16;
1776 Result := Shift_Left (Unsigned_16 (Value), Amount);
1777 return unsigned_short (Result);
1781 (Value : unsigned_int;
1782 Amount : Natural) return unsigned_int
1784 Result : Unsigned_32;
1786 Result := Shift_Left (Unsigned_32 (Value), Amount);
1787 return unsigned_int (Result);
1794 function Shift_Right
1795 (Value : unsigned_char;
1796 Amount : Natural) return unsigned_char
1798 Result : Unsigned_8;
1800 Result := Shift_Right (Unsigned_8 (Value), Amount);
1801 return unsigned_char (Result);
1804 function Shift_Right
1805 (Value : unsigned_short;
1806 Amount : Natural) return unsigned_short
1808 Result : Unsigned_16;
1810 Result := Shift_Right (Unsigned_16 (Value), Amount);
1811 return unsigned_short (Result);
1814 function Shift_Right
1815 (Value : unsigned_int;
1816 Amount : Natural) return unsigned_int
1818 Result : Unsigned_32;
1820 Result := Shift_Right (Unsigned_32 (Value), Amount);
1821 return unsigned_int (Result);
1829 type Signed_Type is range <>;
1830 type Unsigned_Type is mod <>;
1831 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1832 return Unsigned_Type;
1833 function Shift_Right_Arithmetic
1834 (Value : Signed_Type;
1835 Amount : Natural) return Signed_Type;
1837 function Shift_Right_Arithmetic
1838 (Value : Signed_Type;
1839 Amount : Natural) return Signed_Type
1843 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1845 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1848 end Shift_Right_Arithmetic;
1850 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1854 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1858 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1865 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1867 -- This conversion should not depend on the host endianess;
1868 -- therefore, we cannot use an unchecked conversion.
1873 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1874 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1875 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1876 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1880 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1882 -- This conversion should not depend on the host endianess;
1883 -- therefore, we cannot use an unchecked conversion.
1888 Target.T := unsigned_char (Bits (Source, 0, 7));
1889 Target.R := unsigned_char (Bits (Source, 8, 15));
1890 Target.G := unsigned_char (Bits (Source, 16, 23));
1891 Target.B := unsigned_char (Bits (Source, 24, 31));
1895 ---------------------
1896 -- To_unsigned_int --
1897 ---------------------
1899 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1901 -- This conversion should not depend on the host endianess;
1902 -- therefore, we cannot use an unchecked conversion.
1903 -- It should also be the same result, value-wise, on two hosts
1904 -- with the same endianess.
1906 Target : unsigned_int := 0;
1909 -- In big endian bit ordering, Pixel_32 looks like:
1910 -- -------------------------------------
1911 -- | T | R | G | B |
1912 -- -------------------------------------
1913 -- 0 (MSB) 7 15 23 32
1915 -- Sizes of the components: (8/8/8/8)
1917 Target := Target or unsigned_int (Source.T);
1918 Target := Shift_Left (Target, 8);
1919 Target := Target or unsigned_int (Source.R);
1920 Target := Shift_Left (Target, 8);
1921 Target := Target or unsigned_int (Source.G);
1922 Target := Shift_Left (Target, 8);
1923 Target := Target or unsigned_int (Source.B);
1925 end To_unsigned_int;
1927 -----------------------
1928 -- To_unsigned_short --
1929 -----------------------
1931 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1933 -- This conversion should not depend on the host endianess;
1934 -- therefore, we cannot use an unchecked conversion.
1935 -- It should also be the same result, value-wise, on two hosts
1936 -- with the same endianess.
1938 Target : unsigned_short := 0;
1941 -- In big endian bit ordering, Pixel_16 looks like:
1942 -- -------------------------------------
1943 -- | T | R | G | B |
1944 -- -------------------------------------
1945 -- 0 (MSB) 1 5 11 15
1947 -- Sizes of the components: (1/5/5/5)
1949 Target := Target or unsigned_short (Source.T);
1950 Target := Shift_Left (Target, 5);
1951 Target := Target or unsigned_short (Source.R);
1952 Target := Shift_Left (Target, 5);
1953 Target := Target or unsigned_short (Source.G);
1954 Target := Shift_Left (Target, 5);
1955 Target := Target or unsigned_short (Source.B);
1957 end To_unsigned_short;
1963 function abs_v16qi (A : LL_VSC) return LL_VSC is
1964 VA : constant VSC_View := To_View (A);
1966 return To_Vector ((Values =>
1967 LL_VSC_Operations.abs_vxi (VA.Values)));
1974 function abs_v8hi (A : LL_VSS) return LL_VSS is
1975 VA : constant VSS_View := To_View (A);
1977 return To_Vector ((Values =>
1978 LL_VSS_Operations.abs_vxi (VA.Values)));
1985 function abs_v4si (A : LL_VSI) return LL_VSI is
1986 VA : constant VSI_View := To_View (A);
1988 return To_Vector ((Values =>
1989 LL_VSI_Operations.abs_vxi (VA.Values)));
1996 function abs_v4sf (A : LL_VF) return LL_VF is
1998 VA : constant VF_View := To_View (A);
2001 for J in Varray_float'Range loop
2002 D (J) := abs (VA.Values (J));
2005 return To_Vector ((Values => D));
2012 function abss_v16qi (A : LL_VSC) return LL_VSC is
2013 VA : constant VSC_View := To_View (A);
2015 return To_Vector ((Values =>
2016 LL_VSC_Operations.abss_vxi (VA.Values)));
2023 function abss_v8hi (A : LL_VSS) return LL_VSS is
2024 VA : constant VSS_View := To_View (A);
2026 return To_Vector ((Values =>
2027 LL_VSS_Operations.abss_vxi (VA.Values)));
2034 function abss_v4si (A : LL_VSI) return LL_VSI is
2035 VA : constant VSI_View := To_View (A);
2037 return To_Vector ((Values =>
2038 LL_VSI_Operations.abss_vxi (VA.Values)));
2045 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2046 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2048 VA : constant VUC_View :=
2050 VB : constant VUC_View := To_View (To_LL_VUC (B));
2051 D : Varray_unsigned_char;
2054 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2055 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2062 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2063 VA : constant VUS_View := To_View (To_LL_VUS (A));
2064 VB : constant VUS_View := To_View (To_LL_VUS (B));
2065 D : Varray_unsigned_short;
2068 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2069 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2076 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2077 VA : constant VUI_View := To_View (To_LL_VUI (A));
2078 VB : constant VUI_View := To_View (To_LL_VUI (B));
2079 D : Varray_unsigned_int;
2082 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2083 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2090 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2091 VA : constant VF_View := To_View (A);
2092 VB : constant VF_View := To_View (B);
2096 for J in Varray_float'Range loop
2097 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2098 + NJ_Truncate (VB.Values (J)));
2101 return To_Vector (VF_View'(Values => D));
2108 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2109 Addition_Result : UI64;
2111 VA : constant VUI_View := To_View (To_LL_VUI (A));
2112 VB : constant VUI_View := To_View (To_LL_VUI (B));
2115 for J in Varray_unsigned_int'Range loop
2117 UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2119 if Addition_Result > UI64 (unsigned_int'Last) then
2126 return To_LL_VSI (To_Vector (D));
2133 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2134 VA : constant VUC_View := To_View (To_LL_VUC (A));
2135 VB : constant VUC_View := To_View (To_LL_VUC (B));
2138 return To_LL_VSC (To_Vector
2139 (VUC_View'(Values =>
2140 (LL_VUC_Operations.vadduxs
2149 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2150 VA : constant VSC_View := To_View (A);
2151 VB : constant VSC_View := To_View (B);
2155 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2156 return To_Vector (D);
2163 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2164 VA : constant VUS_View := To_View (To_LL_VUS (A));
2165 VB : constant VUS_View := To_View (To_LL_VUS (B));
2169 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2170 return To_LL_VSS (To_Vector (D));
2177 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2178 VA : constant VSS_View := To_View (A);
2179 VB : constant VSS_View := To_View (B);
2183 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2184 return To_Vector (D);
2191 function vadduws (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 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2198 return To_LL_VSI (To_Vector (D));
2205 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2206 VA : constant VSI_View := To_View (A);
2207 VB : constant VSI_View := To_View (B);
2211 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2212 return To_Vector (D);
2219 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2220 VA : constant VUI_View := To_View (To_LL_VUI (A));
2221 VB : constant VUI_View := To_View (To_LL_VUI (B));
2225 for J in Varray_unsigned_int'Range loop
2226 D.Values (J) := VA.Values (J) and VB.Values (J);
2229 return To_LL_VSI (To_Vector (D));
2236 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2237 VA : constant VUI_View := To_View (To_LL_VUI (A));
2238 VB : constant VUI_View := To_View (To_LL_VUI (B));
2242 for J in Varray_unsigned_int'Range loop
2243 D.Values (J) := VA.Values (J) and not VB.Values (J);
2246 return To_LL_VSI (To_Vector (D));
2253 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2254 VA : constant VUC_View := To_View (To_LL_VUC (A));
2255 VB : constant VUC_View := To_View (To_LL_VUC (B));
2259 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2260 return To_LL_VSC (To_Vector (D));
2267 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2268 VA : constant VSC_View := To_View (A);
2269 VB : constant VSC_View := To_View (B);
2273 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2274 return To_Vector (D);
2281 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2282 VA : constant VUS_View := To_View (To_LL_VUS (A));
2283 VB : constant VUS_View := To_View (To_LL_VUS (B));
2287 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2288 return To_LL_VSS (To_Vector (D));
2295 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2296 VA : constant VSS_View := To_View (A);
2297 VB : constant VSS_View := To_View (B);
2301 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2302 return To_Vector (D);
2309 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2310 VA : constant VUI_View := To_View (To_LL_VUI (A));
2311 VB : constant VUI_View := To_View (To_LL_VUI (B));
2315 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2316 return To_LL_VSI (To_Vector (D));
2323 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2324 VA : constant VSI_View := To_View (A);
2325 VB : constant VSI_View := To_View (B);
2329 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2330 return To_Vector (D);
2337 function vrfip (A : LL_VF) return LL_VF is
2338 VA : constant VF_View := To_View (A);
2342 for J in Varray_float'Range loop
2344 -- If A (J) is infinite, D (J) should be infinite; With
2345 -- IEEE floating points, we can use 'Ceiling for that purpose.
2347 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2351 return To_Vector (D);
2358 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2359 VA : constant VF_View := To_View (A);
2360 VB : constant VF_View := To_View (B);
2365 for J in Varray_float'Range loop
2366 K := Vint_Range (J);
2369 if NJ_Truncate (VB.Values (J)) < 0.0 then
2371 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2372 -- word element in B is negative; the corresponding element in A
2373 -- is out of bounds.
2375 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2376 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2379 if NJ_Truncate (VA.Values (J))
2380 <= NJ_Truncate (VB.Values (J)) then
2381 D.Values (K) := Write_Bit (D.Values (K), 0, 0);
2383 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2386 if NJ_Truncate (VA.Values (J))
2387 >= -NJ_Truncate (VB.Values (J)) then
2388 D.Values (K) := Write_Bit (D.Values (K), 1, 0);
2390 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2395 return To_LL_VSI (To_Vector (D));
2402 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2403 VA : constant VUC_View := To_View (To_LL_VUC (A));
2404 VB : constant VUC_View := To_View (To_LL_VUC (B));
2408 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2409 return To_LL_VSC (To_Vector (D));
2416 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2417 VA : constant VUS_View := To_View (To_LL_VUS (A));
2418 VB : constant VUS_View := To_View (To_LL_VUS (B));
2421 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2422 return To_LL_VSS (To_Vector (D));
2429 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2430 VA : constant VUI_View := To_View (To_LL_VUI (A));
2431 VB : constant VUI_View := To_View (To_LL_VUI (B));
2434 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2435 return To_LL_VSI (To_Vector (D));
2442 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2443 VA : constant VF_View := To_View (A);
2444 VB : constant VF_View := To_View (B);
2449 for J in Varray_float'Range loop
2450 K := Vint_Range (J);
2452 if VA.Values (J) = VB.Values (J) then
2453 D.Values (K) := unsigned_int'Last;
2459 return To_LL_VSI (To_Vector (D));
2466 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2467 VA : constant VF_View := To_View (A);
2468 VB : constant VF_View := To_View (B);
2473 for J in Varray_float'Range loop
2474 K := Vint_Range (J);
2476 if VA.Values (J) >= VB.Values (J) then
2477 D.Values (K) := Signed_Bool_True;
2479 D.Values (K) := Signed_Bool_False;
2483 return To_Vector (D);
2490 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2491 VA : constant VUC_View := To_View (To_LL_VUC (A));
2492 VB : constant VUC_View := To_View (To_LL_VUC (B));
2495 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2496 return To_LL_VSC (To_Vector (D));
2503 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2504 VA : constant VSC_View := To_View (A);
2505 VB : constant VSC_View := To_View (B);
2508 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2509 return To_Vector (D);
2516 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2517 VA : constant VUS_View := To_View (To_LL_VUS (A));
2518 VB : constant VUS_View := To_View (To_LL_VUS (B));
2521 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2522 return To_LL_VSS (To_Vector (D));
2529 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2530 VA : constant VSS_View := To_View (A);
2531 VB : constant VSS_View := To_View (B);
2534 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2535 return To_Vector (D);
2542 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2543 VA : constant VUI_View := To_View (To_LL_VUI (A));
2544 VB : constant VUI_View := To_View (To_LL_VUI (B));
2547 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2548 return To_LL_VSI (To_Vector (D));
2555 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2556 VA : constant VSI_View := To_View (A);
2557 VB : constant VSI_View := To_View (B);
2560 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2561 return To_Vector (D);
2568 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2569 VA : constant VF_View := To_View (A);
2570 VB : constant VF_View := To_View (B);
2575 for J in Varray_float'Range loop
2576 K := Vint_Range (J);
2578 if NJ_Truncate (VA.Values (J))
2579 > NJ_Truncate (VB.Values (J)) then
2580 D.Values (K) := Signed_Bool_True;
2582 D.Values (K) := Signed_Bool_False;
2586 return To_Vector (D);
2593 function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2595 VA : constant VUI_View := To_View (To_LL_VUI (A));
2599 for J in Varray_signed_int'Range loop
2600 K := Vfloat_Range (J);
2602 -- Note: The conversion to Integer is safe, as Integers are required
2603 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2604 -- include the range of B (should be 0 .. 255).
2607 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2610 return To_Vector (D);
2617 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2618 VA : constant VSI_View := To_View (A);
2623 for J in Varray_signed_int'Range loop
2624 K := Vfloat_Range (J);
2625 D.Values (K) := C_float (VA.Values (J))
2626 / (2.0 ** Integer (B));
2629 return To_Vector (D);
2636 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2637 VA : constant VF_View := To_View (A);
2642 for J in Varray_signed_int'Range loop
2643 K := Vfloat_Range (J);
2645 LL_VSI_Operations.Saturate
2646 (F64 (NJ_Truncate (VA.Values (K)))
2647 * F64 (2.0 ** Integer (B)));
2650 return To_Vector (D);
2657 function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2658 VA : constant VF_View := To_View (A);
2663 for J in Varray_unsigned_int'Range loop
2664 K := Vfloat_Range (J);
2666 LL_VUI_Operations.Saturate
2667 (F64 (NJ_Truncate (VA.Values (K)))
2668 * F64 (2.0 ** Integer (B)));
2671 return To_LL_VSI (To_Vector (D));
2678 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2680 procedure dss (A : c_int) is
2681 pragma Unreferenced (A);
2690 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2701 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2703 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2704 pragma Unreferenced (A);
2705 pragma Unreferenced (B);
2706 pragma Unreferenced (C);
2715 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2717 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2718 pragma Unreferenced (A);
2719 pragma Unreferenced (B);
2720 pragma Unreferenced (C);
2729 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2731 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2732 pragma Unreferenced (A);
2733 pragma Unreferenced (B);
2734 pragma Unreferenced (C);
2743 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2745 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2746 pragma Unreferenced (A);
2747 pragma Unreferenced (B);
2748 pragma Unreferenced (C);
2757 function vexptefp (A : LL_VF) return LL_VF is
2758 use C_float_Operations;
2760 VA : constant VF_View := To_View (A);
2764 for J in Varray_float'Range loop
2766 -- ??? Check the precision of the operation.
2767 -- As described in [PEM-6 vexptefp]:
2768 -- If theorical_result is equal to 2 at the power of A (J) with
2769 -- infinite precision, we should have:
2770 -- abs ((D (J) - theorical_result) / theorical_result) <= 1/16
2772 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2775 return To_Vector (D);
2782 function vrfim (A : LL_VF) return LL_VF is
2783 VA : constant VF_View := To_View (A);
2787 for J in Varray_float'Range loop
2789 -- If A (J) is infinite, D (J) should be infinite; With
2790 -- IEEE floating point, we can use 'Ceiling for that purpose.
2792 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2794 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2797 if D.Values (J) /= VA.Values (J) then
2798 D.Values (J) := D.Values (J) - 1.0;
2802 return To_Vector (D);
2809 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2811 -- Simulate the altivec unit behavior regarding what Effective Address
2812 -- is accessed, stripping off the input address least significant bits
2813 -- wrt to vector alignment.
2815 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2816 -- an address within a vector is not necessarily rounded back at the
2817 -- vector start address. Besides, rounding on 16 makes no sense on such
2818 -- targets because the address of a properly aligned vector (that is,
2819 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2820 -- want never to happen.
2822 EA : constant System.Address :=
2825 (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2828 for D'Address use EA;
2838 function lvebx (A : c_long; B : c_ptr) return LL_VSC is
2841 D.Values := LL_VSC_Operations.lvexx (A, B);
2842 return To_Vector (D);
2849 function lvehx (A : c_long; B : c_ptr) return LL_VSS is
2852 D.Values := LL_VSS_Operations.lvexx (A, B);
2853 return To_Vector (D);
2860 function lvewx (A : c_long; B : c_ptr) return LL_VSI is
2863 D.Values := LL_VSI_Operations.lvexx (A, B);
2864 return To_Vector (D);
2871 function lvxl (A : c_long; B : c_ptr) return LL_VSI renames
2878 function vlogefp (A : LL_VF) return LL_VF is
2879 VA : constant VF_View := To_View (A);
2883 for J in Varray_float'Range loop
2885 -- ??? Check the precision of the operation.
2886 -- As described in [PEM-6 vlogefp]:
2887 -- If theorical_result is equal to the log2 of A (J) with
2888 -- infinite precision, we should have:
2889 -- abs (D (J) - theorical_result) <= 1/32,
2890 -- unless abs(D(J) - 1) <= 1/8.
2893 C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2896 return To_Vector (D);
2903 function lvsl (A : c_long; B : c_ptr) return LL_VSC is
2904 type bit4_type is mod 16#F# + 1;
2905 for bit4_type'Alignment use 1;
2906 EA : Integer_Address;
2911 EA := Integer_Address (A) + To_Integer (B);
2912 SH := bit4_type (EA mod 2 ** 4);
2914 for J in D.Values'Range loop
2915 D.Values (J) := unsigned_char (SH) + unsigned_char (J)
2916 - unsigned_char (D.Values'First);
2919 return To_LL_VSC (To_Vector (D));
2926 function lvsr (A : c_long; B : c_ptr) return LL_VSC is
2927 type bit4_type is mod 16#F# + 1;
2928 for bit4_type'Alignment use 1;
2929 EA : Integer_Address;
2934 EA := Integer_Address (A) + To_Integer (B);
2935 SH := bit4_type (EA mod 2 ** 4);
2937 for J in D.Values'Range loop
2938 D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2941 return To_LL_VSC (To_Vector (D));
2948 function vmaddfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
2949 VA : constant VF_View := To_View (A);
2950 VB : constant VF_View := To_View (B);
2951 VC : constant VF_View := To_View (C);
2955 for J in Varray_float'Range loop
2957 Rnd_To_FP_Nearest (F64 (VA.Values (J))
2958 * F64 (VB.Values (J))
2959 + F64 (VC.Values (J)));
2962 return To_Vector (D);
2969 function vmhaddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
2970 VA : constant VSS_View := To_View (A);
2971 VB : constant VSS_View := To_View (B);
2972 VC : constant VSS_View := To_View (C);
2976 for J in Varray_signed_short'Range loop
2977 D.Values (J) := LL_VSS_Operations.Saturate
2978 ((SI64 (VA.Values (J)) * SI64 (VB.Values (J)))
2979 / SI64 (2 ** 15) + SI64 (VC.Values (J)));
2982 return To_Vector (D);
2989 function vmaxub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2990 VA : constant VUC_View := To_View (To_LL_VUC (A));
2991 VB : constant VUC_View := To_View (To_LL_VUC (B));
2994 D.Values := LL_VUC_Operations.vmaxux (VA.Values, VB.Values);
2995 return To_LL_VSC (To_Vector (D));
3002 function vmaxsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3003 VA : constant VSC_View := To_View (A);
3004 VB : constant VSC_View := To_View (B);
3007 D.Values := LL_VSC_Operations.vmaxsx (VA.Values, VB.Values);
3008 return To_Vector (D);
3015 function vmaxuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3016 VA : constant VUS_View := To_View (To_LL_VUS (A));
3017 VB : constant VUS_View := To_View (To_LL_VUS (B));
3020 D.Values := LL_VUS_Operations.vmaxux (VA.Values, VB.Values);
3021 return To_LL_VSS (To_Vector (D));
3028 function vmaxsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3029 VA : constant VSS_View := To_View (A);
3030 VB : constant VSS_View := To_View (B);
3033 D.Values := LL_VSS_Operations.vmaxsx (VA.Values, VB.Values);
3034 return To_Vector (D);
3041 function vmaxuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3042 VA : constant VUI_View := To_View (To_LL_VUI (A));
3043 VB : constant VUI_View := To_View (To_LL_VUI (B));
3046 D.Values := LL_VUI_Operations.vmaxux (VA.Values, VB.Values);
3047 return To_LL_VSI (To_Vector (D));
3054 function vmaxsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3055 VA : constant VSI_View := To_View (A);
3056 VB : constant VSI_View := To_View (B);
3059 D.Values := LL_VSI_Operations.vmaxsx (VA.Values, VB.Values);
3060 return To_Vector (D);
3067 function vmaxfp (A : LL_VF; B : LL_VF) return LL_VF is
3068 VA : constant VF_View := To_View (A);
3069 VB : constant VF_View := To_View (B);
3073 for J in Varray_float'Range loop
3074 if VA.Values (J) > VB.Values (J) then
3075 D.Values (J) := VA.Values (J);
3077 D.Values (J) := VB.Values (J);
3081 return To_Vector (D);
3088 function vmrghb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3089 VA : constant VSC_View := To_View (A);
3090 VB : constant VSC_View := To_View (B);
3093 D.Values := LL_VSC_Operations.vmrghx (VA.Values, VB.Values);
3094 return To_Vector (D);
3101 function vmrghh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3102 VA : constant VSS_View := To_View (A);
3103 VB : constant VSS_View := To_View (B);
3106 D.Values := LL_VSS_Operations.vmrghx (VA.Values, VB.Values);
3107 return To_Vector (D);
3114 function vmrghw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3115 VA : constant VSI_View := To_View (A);
3116 VB : constant VSI_View := To_View (B);
3119 D.Values := LL_VSI_Operations.vmrghx (VA.Values, VB.Values);
3120 return To_Vector (D);
3127 function vmrglb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3128 VA : constant VSC_View := To_View (A);
3129 VB : constant VSC_View := To_View (B);
3132 D.Values := LL_VSC_Operations.vmrglx (VA.Values, VB.Values);
3133 return To_Vector (D);
3140 function vmrglh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3141 VA : constant VSS_View := To_View (A);
3142 VB : constant VSS_View := To_View (B);
3145 D.Values := LL_VSS_Operations.vmrglx (VA.Values, VB.Values);
3146 return To_Vector (D);
3153 function vmrglw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3154 VA : constant VSI_View := To_View (A);
3155 VB : constant VSI_View := To_View (B);
3158 D.Values := LL_VSI_Operations.vmrglx (VA.Values, VB.Values);
3159 return To_Vector (D);
3166 function mfvscr return LL_VSS is
3169 for J in Varray_unsigned_short'Range loop
3173 D.Values (Varray_unsigned_short'Last) :=
3174 unsigned_short (VSCR mod 2 ** unsigned_short'Size);
3175 D.Values (Varray_unsigned_short'Last - 1) :=
3176 unsigned_short (VSCR / 2 ** unsigned_short'Size);
3177 return To_LL_VSS (To_Vector (D));
3184 function vminfp (A : LL_VF; B : LL_VF) return LL_VF is
3185 VA : constant VF_View := To_View (A);
3186 VB : constant VF_View := To_View (B);
3190 for J in Varray_float'Range loop
3191 if VA.Values (J) < VB.Values (J) then
3192 D.Values (J) := VA.Values (J);
3194 D.Values (J) := VB.Values (J);
3198 return To_Vector (D);
3205 function vminsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3206 VA : constant VSC_View := To_View (A);
3207 VB : constant VSC_View := To_View (B);
3210 D.Values := LL_VSC_Operations.vminsx (VA.Values, VB.Values);
3211 return To_Vector (D);
3218 function vminub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3219 VA : constant VUC_View := To_View (To_LL_VUC (A));
3220 VB : constant VUC_View := To_View (To_LL_VUC (B));
3223 D.Values := LL_VUC_Operations.vminux (VA.Values, VB.Values);
3224 return To_LL_VSC (To_Vector (D));
3231 function vminsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3232 VA : constant VSS_View := To_View (A);
3233 VB : constant VSS_View := To_View (B);
3236 D.Values := LL_VSS_Operations.vminsx (VA.Values, VB.Values);
3237 return To_Vector (D);
3244 function vminuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3245 VA : constant VUS_View := To_View (To_LL_VUS (A));
3246 VB : constant VUS_View := To_View (To_LL_VUS (B));
3249 D.Values := LL_VUS_Operations.vminux (VA.Values, VB.Values);
3250 return To_LL_VSS (To_Vector (D));
3257 function vminsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3258 VA : constant VSI_View := To_View (A);
3259 VB : constant VSI_View := To_View (B);
3262 D.Values := LL_VSI_Operations.vminsx (VA.Values, VB.Values);
3263 return To_Vector (D);
3270 function vminuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3271 VA : constant VUI_View := To_View (To_LL_VUI (A));
3272 VB : constant VUI_View := To_View (To_LL_VUI (B));
3275 D.Values := LL_VUI_Operations.vminux (VA.Values,
3277 return To_LL_VSI (To_Vector (D));
3284 function vmladduhm (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3285 VA : constant VUS_View := To_View (To_LL_VUS (A));
3286 VB : constant VUS_View := To_View (To_LL_VUS (B));
3287 VC : constant VUS_View := To_View (To_LL_VUS (C));
3291 for J in Varray_unsigned_short'Range loop
3292 D.Values (J) := VA.Values (J) * VB.Values (J)
3296 return To_LL_VSS (To_Vector (D));
3303 function vmhraddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3304 VA : constant VSS_View := To_View (A);
3305 VB : constant VSS_View := To_View (B);
3306 VC : constant VSS_View := To_View (C);
3310 for J in Varray_signed_short'Range loop
3312 LL_VSS_Operations.Saturate (((SI64 (VA.Values (J))
3313 * SI64 (VB.Values (J))
3316 + SI64 (VC.Values (J))));
3319 return To_Vector (D);
3326 function vmsumubm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3327 Offset : Vchar_Range;
3328 VA : constant VUC_View := To_View (To_LL_VUC (A));
3329 VB : constant VUC_View := To_View (To_LL_VUC (B));
3330 VC : constant VUI_View := To_View (To_LL_VUI (C));
3334 for J in 0 .. 3 loop
3335 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3336 D.Values (Vint_Range
3337 (J + Integer (Vint_Range'First))) :=
3338 (unsigned_int (VA.Values (Offset))
3339 * unsigned_int (VB.Values (Offset)))
3340 + (unsigned_int (VA.Values (Offset + 1))
3341 * unsigned_int (VB.Values (1 + Offset)))
3342 + (unsigned_int (VA.Values (2 + Offset))
3343 * unsigned_int (VB.Values (2 + Offset)))
3344 + (unsigned_int (VA.Values (3 + Offset))
3345 * unsigned_int (VB.Values (3 + Offset)))
3346 + VC.Values (Vint_Range
3347 (J + Integer (Varray_unsigned_int'First)));
3350 return To_LL_VSI (To_Vector (D));
3357 function vmsummbm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3358 Offset : Vchar_Range;
3359 VA : constant VSC_View := To_View (A);
3360 VB : constant VUC_View := To_View (To_LL_VUC (B));
3361 VC : constant VSI_View := To_View (C);
3365 for J in 0 .. 3 loop
3366 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3367 D.Values (Vint_Range
3368 (J + Integer (Varray_unsigned_int'First))) := 0
3369 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3370 * SI64 (VB.Values (Offset)))
3371 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3374 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (2 + Offset))
3377 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (3 + Offset))
3380 + VC.Values (Vint_Range
3381 (J + Integer (Varray_unsigned_int'First)));
3384 return To_Vector (D);
3391 function vmsumuhm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3392 Offset : Vshort_Range;
3393 VA : constant VUS_View := To_View (To_LL_VUS (A));
3394 VB : constant VUS_View := To_View (To_LL_VUS (B));
3395 VC : constant VUI_View := To_View (To_LL_VUI (C));
3399 for J in 0 .. 3 loop
3401 Vshort_Range (2 * J + Integer (Vshort_Range'First));
3402 D.Values (Vint_Range
3403 (J + Integer (Varray_unsigned_int'First))) :=
3404 (unsigned_int (VA.Values (Offset))
3405 * unsigned_int (VB.Values (Offset)))
3406 + (unsigned_int (VA.Values (Offset + 1))
3407 * unsigned_int (VB.Values (1 + Offset)))
3408 + VC.Values (Vint_Range
3409 (J + Integer (Vint_Range'First)));
3412 return To_LL_VSI (To_Vector (D));
3419 function vmsumshm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3420 VA : constant VSS_View := To_View (A);
3421 VB : constant VSS_View := To_View (B);
3422 VC : constant VSI_View := To_View (C);
3423 Offset : Vshort_Range;
3427 for J in 0 .. 3 loop
3429 Vshort_Range (2 * J + Integer (Varray_signed_char'First));
3430 D.Values (Vint_Range
3431 (J + Integer (Varray_unsigned_int'First))) := 0
3432 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3433 * SI64 (VB.Values (Offset)))
3434 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3437 + VC.Values (Vint_Range
3438 (J + Integer (Varray_unsigned_int'First)));
3441 return To_Vector (D);
3448 function vmsumuhs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3449 Offset : Vshort_Range;
3450 VA : constant VUS_View := To_View (To_LL_VUS (A));
3451 VB : constant VUS_View := To_View (To_LL_VUS (B));
3452 VC : constant VUI_View := To_View (To_LL_VUI (C));
3456 for J in 0 .. 3 loop
3458 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3459 D.Values (Vint_Range
3460 (J + Integer (Varray_unsigned_int'First))) :=
3461 LL_VUI_Operations.Saturate
3462 (UI64 (VA.Values (Offset))
3463 * UI64 (VB.Values (Offset))
3464 + UI64 (VA.Values (Offset + 1))
3465 * UI64 (VB.Values (1 + Offset))
3468 (J + Integer (Varray_unsigned_int'First)))));
3471 return To_LL_VSI (To_Vector (D));
3478 function vmsumshs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3479 VA : constant VSS_View := To_View (A);
3480 VB : constant VSS_View := To_View (B);
3481 VC : constant VSI_View := To_View (C);
3482 Offset : Vshort_Range;
3486 for J in 0 .. 3 loop
3488 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3489 D.Values (Vint_Range
3490 (J + Integer (Varray_signed_int'First))) :=
3491 LL_VSI_Operations.Saturate
3492 (SI64 (VA.Values (Offset))
3493 * SI64 (VB.Values (Offset))
3494 + SI64 (VA.Values (Offset + 1))
3495 * SI64 (VB.Values (1 + Offset))
3498 (J + Integer (Varray_signed_int'First)))));
3501 return To_Vector (D);
3508 procedure mtvscr (A : LL_VSI) is
3509 VA : constant VUI_View := To_View (To_LL_VUI (A));
3511 VSCR := VA.Values (Varray_unsigned_int'Last);
3518 function vmuleub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3519 VA : constant VUC_View := To_View (To_LL_VUC (A));
3520 VB : constant VUC_View := To_View (To_LL_VUC (B));
3523 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (True,
3526 return To_LL_VSS (To_Vector (D));
3533 function vmuleuh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3534 VA : constant VUS_View := To_View (To_LL_VUS (A));
3535 VB : constant VUS_View := To_View (To_LL_VUS (B));
3538 D.Values := LL_VUS_LL_VUI_Operations.vmulxux (True,
3541 return To_LL_VSI (To_Vector (D));
3548 function vmulesb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3549 VA : constant VSC_View := To_View (A);
3550 VB : constant VSC_View := To_View (B);
3553 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (True,
3556 return To_Vector (D);
3563 function vmulesh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3564 VA : constant VSS_View := To_View (A);
3565 VB : constant VSS_View := To_View (B);
3568 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (True,
3571 return To_Vector (D);
3578 function vmuloub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3579 VA : constant VUC_View := To_View (To_LL_VUC (A));
3580 VB : constant VUC_View := To_View (To_LL_VUC (B));
3583 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (False,
3586 return To_LL_VSS (To_Vector (D));
3593 function vmulouh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3594 VA : constant VUS_View := To_View (To_LL_VUS (A));
3595 VB : constant VUS_View := To_View (To_LL_VUS (B));
3599 LL_VUS_LL_VUI_Operations.vmulxux (False, VA.Values, VB.Values);
3600 return To_LL_VSI (To_Vector (D));
3607 function vmulosb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3608 VA : constant VSC_View := To_View (A);
3609 VB : constant VSC_View := To_View (B);
3612 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (False,
3615 return To_Vector (D);
3622 function vmulosh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3623 VA : constant VSS_View := To_View (A);
3624 VB : constant VSS_View := To_View (B);
3627 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (False,
3630 return To_Vector (D);
3637 function vnmsubfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
3638 VA : constant VF_View := To_View (A);
3639 VB : constant VF_View := To_View (B);
3640 VC : constant VF_View := To_View (C);
3644 for J in Vfloat_Range'Range loop
3646 -Rnd_To_FP_Nearest (F64 (VA.Values (J))
3647 * F64 (VB.Values (J))
3648 - F64 (VC.Values (J)));
3651 return To_Vector (D);
3658 function vnor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3659 VA : constant VUI_View := To_View (To_LL_VUI (A));
3660 VB : constant VUI_View := To_View (To_LL_VUI (B));
3664 for J in Vint_Range'Range loop
3665 D.Values (J) := not (VA.Values (J) or VB.Values (J));
3668 return To_LL_VSI (To_Vector (D));
3675 function vor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3676 VA : constant VUI_View := To_View (To_LL_VUI (A));
3677 VB : constant VUI_View := To_View (To_LL_VUI (B));
3681 for J in Vint_Range'Range loop
3682 D.Values (J) := VA.Values (J) or VB.Values (J);
3685 return To_LL_VSI (To_Vector (D));
3692 function vpkuhum (A : LL_VSS; B : LL_VSS) return LL_VSC is
3693 VA : constant VUS_View := To_View (To_LL_VUS (A));
3694 VB : constant VUS_View := To_View (To_LL_VUS (B));
3697 D.Values := LL_VUC_LL_VUS_Operations.vpkuxum (VA.Values, VB.Values);
3698 return To_LL_VSC (To_Vector (D));
3705 function vpkuwum (A : LL_VSI; B : LL_VSI) return LL_VSS is
3706 VA : constant VUI_View := To_View (To_LL_VUI (A));
3707 VB : constant VUI_View := To_View (To_LL_VUI (B));
3710 D.Values := LL_VUS_LL_VUI_Operations.vpkuxum (VA.Values, VB.Values);
3711 return To_LL_VSS (To_Vector (D));
3718 function vpkpx (A : LL_VSI; B : LL_VSI) return LL_VSS is
3719 VA : constant VUI_View := To_View (To_LL_VUI (A));
3720 VB : constant VUI_View := To_View (To_LL_VUI (B));
3722 Offset : Vint_Range;
3727 for J in 0 .. 3 loop
3728 Offset := Vint_Range (J + Integer (Vshort_Range'First));
3729 P32 := To_Pixel (VA.Values (Offset));
3730 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3731 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3732 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3733 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3734 D.Values (Vshort_Range (Offset)) := To_unsigned_short (P16);
3735 P32 := To_Pixel (VB.Values (Offset));
3736 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3737 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3738 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3739 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3740 D.Values (Vshort_Range (Offset) + 4) := To_unsigned_short (P16);
3743 return To_LL_VSS (To_Vector (D));
3750 function vpkuhus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3751 VA : constant VUS_View := To_View (To_LL_VUS (A));
3752 VB : constant VUS_View := To_View (To_LL_VUS (B));
3755 D.Values := LL_VUC_LL_VUS_Operations.vpkuxus (VA.Values, VB.Values);
3756 return To_LL_VSC (To_Vector (D));
3763 function vpkuwus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3764 VA : constant VUI_View := To_View (To_LL_VUI (A));
3765 VB : constant VUI_View := To_View (To_LL_VUI (B));
3768 D.Values := LL_VUS_LL_VUI_Operations.vpkuxus (VA.Values, VB.Values);
3769 return To_LL_VSS (To_Vector (D));
3776 function vpkshss (A : LL_VSS; B : LL_VSS) return LL_VSC is
3777 VA : constant VSS_View := To_View (A);
3778 VB : constant VSS_View := To_View (B);
3781 D.Values := LL_VSC_LL_VSS_Operations.vpksxss (VA.Values, VB.Values);
3782 return To_Vector (D);
3789 function vpkswss (A : LL_VSI; B : LL_VSI) return LL_VSS is
3790 VA : constant VSI_View := To_View (A);
3791 VB : constant VSI_View := To_View (B);
3794 D.Values := LL_VSS_LL_VSI_Operations.vpksxss (VA.Values, VB.Values);
3795 return To_Vector (D);
3803 type Signed_Component_Type is range <>;
3804 type Signed_Index_Type is range <>;
3805 type Signed_Varray_Type is
3806 array (Signed_Index_Type) of Signed_Component_Type;
3807 type Unsigned_Component_Type is mod <>;
3808 type Unsigned_Index_Type is range <>;
3809 type Unsigned_Varray_Type is
3810 array (Unsigned_Index_Type) of Unsigned_Component_Type;
3813 (A : Signed_Varray_Type;
3814 B : Signed_Varray_Type) return Unsigned_Varray_Type;
3817 (A : Signed_Varray_Type;
3818 B : Signed_Varray_Type) return Unsigned_Varray_Type
3820 N : constant Unsigned_Index_Type :=
3821 Unsigned_Index_Type (Signed_Index_Type'Last);
3822 Offset : Unsigned_Index_Type;
3823 Signed_Offset : Signed_Index_Type;
3824 D : Unsigned_Varray_Type;
3827 (X : Signed_Component_Type) return Unsigned_Component_Type;
3828 -- Saturation, as defined in
3829 -- [PIM-4.1 Vector Status and Control Register]
3836 (X : Signed_Component_Type) return Unsigned_Component_Type
3838 D : Unsigned_Component_Type;
3841 D := Unsigned_Component_Type
3842 (Signed_Component_Type'Max
3843 (Signed_Component_Type (Unsigned_Component_Type'First),
3844 Signed_Component_Type'Min
3845 (Signed_Component_Type (Unsigned_Component_Type'Last),
3847 if Signed_Component_Type (D) /= X then
3848 VSCR := Write_Bit (VSCR, SAT_POS, 1);
3854 -- Start of processing for vpksxus
3857 for J in 0 .. N - 1 loop
3859 Unsigned_Index_Type (Integer (J)
3860 + Integer (Unsigned_Index_Type'First));
3862 Signed_Index_Type (Integer (J)
3863 + Integer (Signed_Index_Type'First));
3864 D (Offset) := Saturate (A (Signed_Offset));
3865 D (Offset + N) := Saturate (B (Signed_Offset));
3875 function vpkshus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3876 function vpkshus_Instance is
3877 new vpksxus (signed_short,
3879 Varray_signed_short,
3882 Varray_unsigned_char);
3884 VA : constant VSS_View := To_View (A);
3885 VB : constant VSS_View := To_View (B);
3889 D.Values := vpkshus_Instance (VA.Values, VB.Values);
3890 return To_LL_VSC (To_Vector (D));
3897 function vpkswus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3898 function vpkswus_Instance is
3899 new vpksxus (signed_int,
3904 Varray_unsigned_short);
3906 VA : constant VSI_View := To_View (A);
3907 VB : constant VSI_View := To_View (B);
3910 D.Values := vpkswus_Instance (VA.Values, VB.Values);
3911 return To_LL_VSS (To_Vector (D));
3918 function vperm_4si (A : LL_VSI; B : LL_VSI; C : LL_VSC) return LL_VSI is
3919 VA : constant VUC_View := To_View (To_LL_VUC (A));
3920 VB : constant VUC_View := To_View (To_LL_VUC (B));
3921 VC : constant VUC_View := To_View (To_LL_VUC (C));
3926 for N in Vchar_Range'Range loop
3927 J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
3928 + Integer (Vchar_Range'First));
3930 if Bits (VC.Values (N), 3, 3) = 0 then
3931 D.Values (N) := VA.Values (J);
3933 D.Values (N) := VB.Values (J);
3937 return To_LL_VSI (To_Vector (D));
3944 function vrefp (A : LL_VF) return LL_VF is
3945 VA : constant VF_View := To_View (A);
3949 for J in Vfloat_Range'Range loop
3950 D.Values (J) := FP_Recip_Est (VA.Values (J));
3953 return To_Vector (D);
3960 function vrlb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3961 VA : constant VUC_View := To_View (To_LL_VUC (A));
3962 VB : constant VUC_View := To_View (To_LL_VUC (B));
3965 D.Values := LL_VUC_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3966 return To_LL_VSC (To_Vector (D));
3973 function vrlh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3974 VA : constant VUS_View := To_View (To_LL_VUS (A));
3975 VB : constant VUS_View := To_View (To_LL_VUS (B));
3978 D.Values := LL_VUS_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3979 return To_LL_VSS (To_Vector (D));
3986 function vrlw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3987 VA : constant VUI_View := To_View (To_LL_VUI (A));
3988 VB : constant VUI_View := To_View (To_LL_VUI (B));
3991 D.Values := LL_VUI_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3992 return To_LL_VSI (To_Vector (D));
3999 function vrfin (A : LL_VF) return LL_VF is
4000 VA : constant VF_View := To_View (A);
4004 for J in Vfloat_Range'Range loop
4005 D.Values (J) := C_float (Rnd_To_FPI_Near (F64 (VA.Values (J))));
4008 return To_Vector (D);
4015 function vrsqrtefp (A : LL_VF) return LL_VF is
4016 VA : constant VF_View := To_View (A);
4020 for J in Vfloat_Range'Range loop
4021 D.Values (J) := Recip_SQRT_Est (VA.Values (J));
4024 return To_Vector (D);
4031 function vsel_4si (A : LL_VSI; B : LL_VSI; C : LL_VSI) return LL_VSI is
4032 VA : constant VUI_View := To_View (To_LL_VUI (A));
4033 VB : constant VUI_View := To_View (To_LL_VUI (B));
4034 VC : constant VUI_View := To_View (To_LL_VUI (C));
4038 for J in Vint_Range'Range loop
4039 D.Values (J) := ((not VC.Values (J)) and VA.Values (J))
4040 or (VC.Values (J) and VB.Values (J));
4043 return To_LL_VSI (To_Vector (D));
4050 function vslb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4051 VA : constant VUC_View := To_View (To_LL_VUC (A));
4052 VB : constant VUC_View := To_View (To_LL_VUC (B));
4056 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4057 return To_LL_VSC (To_Vector (D));
4064 function vslh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4065 VA : constant VUS_View := To_View (To_LL_VUS (A));
4066 VB : constant VUS_View := To_View (To_LL_VUS (B));
4070 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4071 return To_LL_VSS (To_Vector (D));
4078 function vslw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4079 VA : constant VUI_View := To_View (To_LL_VUI (A));
4080 VB : constant VUI_View := To_View (To_LL_VUI (B));
4084 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4085 return To_LL_VSI (To_Vector (D));
4092 function vsldoi_4si (A : LL_VSI; B : LL_VSI; C : c_int) return LL_VSI is
4093 VA : constant VUC_View := To_View (To_LL_VUC (A));
4094 VB : constant VUC_View := To_View (To_LL_VUC (B));
4100 for J in Vchar_Range'Range loop
4101 Offset := c_int (J) + C;
4102 Bound := c_int (Vchar_Range'First)
4103 + c_int (Varray_unsigned_char'Length);
4105 if Offset < Bound then
4106 D.Values (J) := VA.Values (Vchar_Range (Offset));
4109 VB.Values (Vchar_Range (Offset - Bound
4110 + c_int (Vchar_Range'First)));
4114 return To_LL_VSI (To_Vector (D));
4121 function vsldoi_8hi (A : LL_VSS; B : LL_VSS; C : c_int) return LL_VSS is
4123 return To_LL_VSS (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4130 function vsldoi_16qi (A : LL_VSC; B : LL_VSC; C : c_int) return LL_VSC is
4132 return To_LL_VSC (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4139 function vsldoi_4sf (A : LL_VF; B : LL_VF; C : c_int) return LL_VF is
4141 return To_LL_VF (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4148 function vsl (A : LL_VSI; B : LL_VSI) return LL_VSI is
4149 VA : constant VUI_View := To_View (To_LL_VUI (A));
4150 VB : constant VUI_View := To_View (To_LL_VUI (B));
4152 M : constant Natural :=
4153 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4155 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4156 -- must be the same. Otherwise the value placed into D is undefined."
4157 -- ??? Shall we add a optional check for B?
4160 for J in Vint_Range'Range loop
4162 D.Values (J) := D.Values (J) + Shift_Left (VA.Values (J), M);
4164 if J /= Vint_Range'Last then
4166 D.Values (J) + Shift_Right (VA.Values (J + 1),
4167 signed_int'Size - M);
4171 return To_LL_VSI (To_Vector (D));
4178 function vslo (A : LL_VSI; B : LL_VSI) return LL_VSI is
4179 VA : constant VUC_View := To_View (To_LL_VUC (A));
4180 VB : constant VUC_View := To_View (To_LL_VUC (B));
4182 M : constant Natural :=
4183 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4187 for N in Vchar_Range'Range loop
4188 J := Natural (N) + M;
4190 if J <= Natural (Vchar_Range'Last) then
4191 D.Values (N) := VA.Values (Vchar_Range (J));
4197 return To_LL_VSI (To_Vector (D));
4204 function vspltb (A : LL_VSC; B : c_int) return LL_VSC is
4205 VA : constant VSC_View := To_View (A);
4208 D.Values := LL_VSC_Operations.vspltx (VA.Values, B);
4209 return To_Vector (D);
4216 function vsplth (A : LL_VSS; B : c_int) return LL_VSS is
4217 VA : constant VSS_View := To_View (A);
4220 D.Values := LL_VSS_Operations.vspltx (VA.Values, B);
4221 return To_Vector (D);
4228 function vspltw (A : LL_VSI; B : c_int) return LL_VSI is
4229 VA : constant VSI_View := To_View (A);
4232 D.Values := LL_VSI_Operations.vspltx (VA.Values, B);
4233 return To_Vector (D);
4240 function vspltisb (A : c_int) return LL_VSC is
4243 D.Values := LL_VSC_Operations.vspltisx (A);
4244 return To_Vector (D);
4251 function vspltish (A : c_int) return LL_VSS is
4254 D.Values := LL_VSS_Operations.vspltisx (A);
4255 return To_Vector (D);
4262 function vspltisw (A : c_int) return LL_VSI is
4265 D.Values := LL_VSI_Operations.vspltisx (A);
4266 return To_Vector (D);
4273 function vsrb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4274 VA : constant VUC_View := To_View (To_LL_VUC (A));
4275 VB : constant VUC_View := To_View (To_LL_VUC (B));
4279 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4280 return To_LL_VSC (To_Vector (D));
4287 function vsrh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4288 VA : constant VUS_View := To_View (To_LL_VUS (A));
4289 VB : constant VUS_View := To_View (To_LL_VUS (B));
4293 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4294 return To_LL_VSS (To_Vector (D));
4301 function vsrw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4302 VA : constant VUI_View := To_View (To_LL_VUI (A));
4303 VB : constant VUI_View := To_View (To_LL_VUI (B));
4307 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4308 return To_LL_VSI (To_Vector (D));
4315 function vsrab (A : LL_VSC; B : LL_VSC) return LL_VSC is
4316 VA : constant VSC_View := To_View (A);
4317 VB : constant VSC_View := To_View (B);
4321 LL_VSC_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4322 return To_Vector (D);
4329 function vsrah (A : LL_VSS; B : LL_VSS) return LL_VSS is
4330 VA : constant VSS_View := To_View (A);
4331 VB : constant VSS_View := To_View (B);
4335 LL_VSS_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4336 return To_Vector (D);
4343 function vsraw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4344 VA : constant VSI_View := To_View (A);
4345 VB : constant VSI_View := To_View (B);
4349 LL_VSI_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4350 return To_Vector (D);
4357 function vsr (A : LL_VSI; B : LL_VSI) return LL_VSI is
4358 VA : constant VUI_View := To_View (To_LL_VUI (A));
4359 VB : constant VUI_View := To_View (To_LL_VUI (B));
4360 M : constant Natural :=
4361 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4365 for J in Vint_Range'Range loop
4367 D.Values (J) := D.Values (J) + Shift_Right (VA.Values (J), M);
4369 if J /= Vint_Range'First then
4372 + Shift_Left (VA.Values (J - 1), signed_int'Size - M);
4376 return To_LL_VSI (To_Vector (D));
4383 function vsro (A : LL_VSI; B : LL_VSI) return LL_VSI is
4384 VA : constant VUC_View := To_View (To_LL_VUC (A));
4385 VB : constant VUC_View := To_View (To_LL_VUC (B));
4386 M : constant Natural :=
4387 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4392 for N in Vchar_Range'Range loop
4393 J := Natural (N) - M;
4395 if J >= Natural (Vchar_Range'First) then
4396 D.Values (N) := VA.Values (Vchar_Range (J));
4402 return To_LL_VSI (To_Vector (D));
4409 procedure stvx (A : LL_VSI; B : c_int; C : c_ptr) is
4411 -- Simulate the altivec unit behavior regarding what Effective Address
4412 -- is accessed, stripping off the input address least significant bits
4413 -- wrt to vector alignment (see comment in lvx for further details).
4415 EA : constant System.Address :=
4418 (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4421 for D'Address use EA;
4431 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4432 VA : constant VSC_View := To_View (A);
4434 LL_VSC_Operations.stvexx (VA.Values, B, C);
4441 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4442 VA : constant VSS_View := To_View (A);
4444 LL_VSS_Operations.stvexx (VA.Values, B, C);
4451 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4452 VA : constant VSI_View := To_View (A);
4454 LL_VSI_Operations.stvexx (VA.Values, B, C);
4461 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4467 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4468 VA : constant VUC_View := To_View (To_LL_VUC (A));
4469 VB : constant VUC_View := To_View (To_LL_VUC (B));
4472 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4473 return To_LL_VSC (To_Vector (D));
4480 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4481 VA : constant VUS_View := To_View (To_LL_VUS (A));
4482 VB : constant VUS_View := To_View (To_LL_VUS (B));
4485 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4486 return To_LL_VSS (To_Vector (D));
4493 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4494 VA : constant VUI_View := To_View (To_LL_VUI (A));
4495 VB : constant VUI_View := To_View (To_LL_VUI (B));
4498 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4499 return To_LL_VSI (To_Vector (D));
4506 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4507 VA : constant VF_View := To_View (A);
4508 VB : constant VF_View := To_View (B);
4512 for J in Vfloat_Range'Range loop
4514 NJ_Truncate (NJ_Truncate (VA.Values (J))
4515 - NJ_Truncate (VB.Values (J)));
4518 return To_Vector (D);
4525 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4526 Subst_Result : SI64;
4528 VA : constant VUI_View := To_View (To_LL_VUI (A));
4529 VB : constant VUI_View := To_View (To_LL_VUI (B));
4533 for J in Vint_Range'Range loop
4534 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4536 if Subst_Result < SI64 (unsigned_int'First) then
4543 return To_LL_VSI (To_Vector (D));
4550 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4551 VA : constant VUC_View := To_View (To_LL_VUC (A));
4552 VB : constant VUC_View := To_View (To_LL_VUC (B));
4555 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4556 return To_LL_VSC (To_Vector (D));
4563 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4564 VA : constant VSC_View := To_View (A);
4565 VB : constant VSC_View := To_View (B);
4568 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4569 return To_Vector (D);
4576 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4577 VA : constant VUS_View := To_View (To_LL_VUS (A));
4578 VB : constant VUS_View := To_View (To_LL_VUS (B));
4581 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4582 return To_LL_VSS (To_Vector (D));
4589 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4590 VA : constant VSS_View := To_View (A);
4591 VB : constant VSS_View := To_View (B);
4594 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4595 return To_Vector (D);
4602 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4603 VA : constant VUI_View := To_View (To_LL_VUI (A));
4604 VB : constant VUI_View := To_View (To_LL_VUI (B));
4607 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4608 return To_LL_VSI (To_Vector (D));
4615 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4616 VA : constant VSI_View := To_View (A);
4617 VB : constant VSI_View := To_View (B);
4620 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4621 return To_Vector (D);
4628 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4629 VA : constant VUC_View := To_View (To_LL_VUC (A));
4630 VB : constant VUI_View := To_View (To_LL_VUI (B));
4631 Offset : Vchar_Range;
4635 for J in 0 .. 3 loop
4636 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4637 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4638 LL_VUI_Operations.Saturate
4639 (UI64 (VA.Values (Offset))
4640 + UI64 (VA.Values (Offset + 1))
4641 + UI64 (VA.Values (Offset + 2))
4642 + UI64 (VA.Values (Offset + 3))
4643 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4646 return To_LL_VSI (To_Vector (D));
4653 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4654 VA : constant VSC_View := To_View (A);
4655 VB : constant VSI_View := To_View (B);
4656 Offset : Vchar_Range;
4660 for J in 0 .. 3 loop
4661 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4662 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4663 LL_VSI_Operations.Saturate
4664 (SI64 (VA.Values (Offset))
4665 + SI64 (VA.Values (Offset + 1))
4666 + SI64 (VA.Values (Offset + 2))
4667 + SI64 (VA.Values (Offset + 3))
4668 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4671 return To_Vector (D);
4678 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4679 VA : constant VSS_View := To_View (A);
4680 VB : constant VSI_View := To_View (B);
4681 Offset : Vshort_Range;
4685 for J in 0 .. 3 loop
4686 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4687 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4688 LL_VSI_Operations.Saturate
4689 (SI64 (VA.Values (Offset))
4690 + SI64 (VA.Values (Offset + 1))
4691 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4694 return To_Vector (D);
4701 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4702 VA : constant VSI_View := To_View (A);
4703 VB : constant VSI_View := To_View (B);
4704 Offset : Vint_Range;
4708 for J in 0 .. 1 loop
4709 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4710 D.Values (Offset) := 0;
4711 D.Values (Offset + 1) :=
4712 LL_VSI_Operations.Saturate
4713 (SI64 (VA.Values (Offset))
4714 + SI64 (VA.Values (Offset + 1))
4715 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4718 return To_Vector (D);
4725 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4726 VA : constant VSI_View := To_View (A);
4727 VB : constant VSI_View := To_View (B);
4729 Sum_Buffer : SI64 := 0;
4732 for J in Vint_Range'Range loop
4734 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4737 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4738 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4739 return To_Vector (D);
4746 function vrfiz (A : LL_VF) return LL_VF is
4747 VA : constant VF_View := To_View (A);
4750 for J in Vfloat_Range'Range loop
4751 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4754 return To_Vector (D);
4761 function vupkhsb (A : LL_VSC) return LL_VSS is
4762 VA : constant VSC_View := To_View (A);
4765 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4766 return To_Vector (D);
4773 function vupkhsh (A : LL_VSS) return LL_VSI is
4774 VA : constant VSS_View := To_View (A);
4777 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4778 return To_Vector (D);
4785 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4786 -- For vupkhpx and vupklpx (depending on Offset)
4788 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4789 VA : constant VUS_View := To_View (To_LL_VUS (A));
4795 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4797 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4807 for J in Vint_Range'Range loop
4808 K := Vshort_Range (Integer (J)
4809 - Integer (Vint_Range'First)
4810 + Integer (Vshort_Range'First)
4812 P16 := To_Pixel (VA.Values (K));
4813 P32.T := Sign_Extend (P16.T);
4814 P32.R := unsigned_char (P16.R);
4815 P32.G := unsigned_char (P16.G);
4816 P32.B := unsigned_char (P16.B);
4817 D.Values (J) := To_unsigned_int (P32);
4820 return To_LL_VSI (To_Vector (D));
4827 function vupkhpx (A : LL_VSS) return LL_VSI is
4829 return vupkxpx (A, 0);
4836 function vupklsb (A : LL_VSC) return LL_VSS is
4837 VA : constant VSC_View := To_View (A);
4841 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4842 Varray_signed_short'Length);
4843 return To_Vector (D);
4850 function vupklsh (A : LL_VSS) return LL_VSI is
4851 VA : constant VSS_View := To_View (A);
4855 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4856 Varray_signed_int'Length);
4857 return To_Vector (D);
4864 function vupklpx (A : LL_VSS) return LL_VSI is
4866 return vupkxpx (A, Varray_signed_int'Length);
4873 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4874 VA : constant VUI_View := To_View (To_LL_VUI (A));
4875 VB : constant VUI_View := To_View (To_LL_VUI (B));
4879 for J in Vint_Range'Range loop
4880 D.Values (J) := VA.Values (J) xor VB.Values (J);
4883 return To_LL_VSI (To_Vector (D));
4890 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4893 D := vcmpequb (B, C);
4894 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4901 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4904 D := vcmpequh (B, C);
4905 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4912 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4915 D := vcmpequw (B, C);
4916 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4923 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4926 D := vcmpeqfp (B, C);
4927 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4934 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4937 D := vcmpgtub (B, C);
4938 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4945 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4948 D := vcmpgtuh (B, C);
4949 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4956 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4959 D := vcmpgtuw (B, C);
4960 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4967 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4970 D := vcmpgtsb (B, C);
4971 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4978 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4981 D := vcmpgtsh (B, C);
4982 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4989 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4992 D := vcmpgtsw (B, C);
4993 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5000 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5003 D := vcmpgefp (B, C);
5004 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5011 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5014 D := vcmpgtfp (B, C);
5015 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5022 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5025 D := To_View (vcmpbfp (B, C));
5027 for J in Vint_Range'Range loop
5028 -- vcmpbfp is not returning the usual bool vector; do the conversion
5029 if D.Values (J) = 0 then
5030 D.Values (J) := Signed_Bool_False;
5032 D.Values (J) := Signed_Bool_True;
5036 return LL_VSI_Operations.Check_CR6 (A, D.Values);
5039 end GNAT.Altivec.Low_Level_Vectors;