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-2005, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 -- ??? What is exactly needed for the soft case is still a bit unclear on
36 -- some accounts. The expected functional equivalence with the Hard binding
37 -- might require tricky things to be done on some targets.
39 -- Examples that come to mind are endianness variations or differences in the
40 -- base FP model while we need the operation results to be the same as what
41 -- the real AltiVec instructions would do on a PowerPC.
43 with Ada.Numerics.Generic_Elementary_Functions;
44 with Interfaces; use Interfaces;
45 with System.Storage_Elements; use System.Storage_Elements;
47 with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions;
48 with GNAT.Altivec.Low_Level_Interface; use GNAT.Altivec.Low_Level_Interface;
50 package body GNAT.Altivec.Low_Level_Vectors is
52 -- This package assumes C_float is an IEEE single-precision float type
54 pragma Assert (C_float'Machine_Radix = 2);
55 pragma Assert (C_float'Machine_Mantissa = 24);
56 pragma Assert (C_float'Machine_Emin = -125);
57 pragma Assert (C_float'Machine_Emax = 128);
58 pragma Assert (C_float'Machine_Rounds);
59 pragma Assert (not C_float'Machine_Overflows);
60 pragma Assert (C_float'Signed_Zeros);
61 pragma Assert (C_float'Denorm);
63 -- Pixel types. As defined in [PIM-2.1 Data types]:
64 -- A 16-bit pixel is 1/5/5/5;
65 -- A 32-bit pixel is 8/8/8/8.
66 -- We use the following records as an intermediate representation, to
69 type Unsigned_1 is mod 2 ** 1;
70 type Unsigned_5 is mod 2 ** 5;
72 type Pixel_16 is record
79 type Pixel_32 is record
86 -- Conversions to/from the pixel records to the integer types that are
87 -- actually stored into the pixel vectors:
89 function To_Pixel (Source : unsigned_short) return Pixel_16;
90 function To_unsigned_short (Source : Pixel_16) return unsigned_short;
91 function To_Pixel (Source : unsigned_int) return Pixel_32;
92 function To_unsigned_int (Source : Pixel_32) return unsigned_int;
94 package C_float_Operations is
95 new Ada.Numerics.Generic_Elementary_Functions (C_float);
97 -- Model of the Vector Status and Control Register (VSCR), as
98 -- defined in [PIM-4.1 Vector Status and Control Register]:
102 -- Positions of the flags in VSCR(0 .. 31):
104 NJ_POS : constant := 15;
105 SAT_POS : constant := 31;
107 -- To control overflows, integer operations are done on 64-bit types:
109 SINT64_MIN : constant := -2 ** 63;
110 SINT64_MAX : constant := 2 ** 63 - 1;
111 UINT64_MAX : constant := 2 ** 64 - 1;
113 type SI64 is range SINT64_MIN .. SINT64_MAX;
114 type UI64 is mod UINT64_MAX + 1;
116 type F64 is digits 15
117 range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
122 High : Natural) return unsigned_int;
127 High : Natural) return unsigned_short;
132 High : Natural) return unsigned_char;
137 Value : Unsigned_1) return unsigned_int;
142 Value : Unsigned_1) return unsigned_short;
147 Value : Unsigned_1) return unsigned_char;
149 function NJ_Truncate (X : C_float) return C_float;
150 -- If NJ and A is a denormalized number, return zero
153 (X : Integer_Address;
154 Y : Integer_Address) return Integer_Address;
155 -- [PIM-4.3 Notations and Conventions]
156 -- Align X in a y-byte boundary and return the result
158 function Rnd_To_FP_Nearest (X : F64) return C_float;
159 -- [PIM-4.3 Notations and Conventions]
161 function Rnd_To_FPI_Near (X : F64) return F64;
163 function Rnd_To_FPI_Trunc (X : F64) return F64;
165 function FP_Recip_Est (X : C_float) return C_float;
166 -- [PIM-4.3 Notations and Conventions]
167 -- 12-bit accurate floating-point estimate of 1/x
170 (Value : unsigned_char;
171 Amount : Natural) return unsigned_char;
172 -- [PIM-4.3 Notations and Conventions]
176 (Value : unsigned_short;
177 Amount : Natural) return unsigned_short;
180 (Value : unsigned_int;
181 Amount : Natural) return unsigned_int;
183 function Recip_SQRT_Est (X : C_float) return C_float;
186 (Value : unsigned_char;
187 Amount : Natural) return unsigned_char;
188 -- [PIM-4.3 Notations and Conventions]
192 (Value : unsigned_short;
193 Amount : Natural) return unsigned_short;
196 (Value : unsigned_int;
197 Amount : Natural) return unsigned_int;
200 (Value : unsigned_char;
201 Amount : Natural) return unsigned_char;
202 -- [PIM-4.3 Notations and Conventions]
206 (Value : unsigned_short;
207 Amount : Natural) return unsigned_short;
210 (Value : unsigned_int;
211 Amount : Natural) return unsigned_int;
213 Signed_Bool_False : constant := 0;
214 Signed_Bool_True : constant := -1;
216 ------------------------------
217 -- Signed_Operations (spec) --
218 ------------------------------
221 type Component_Type is range <>;
222 type Index_Type is range <>;
223 type Varray_Type is array (Index_Type) of Component_Type;
225 package Signed_Operations is
227 function Modular_Result (X : SI64) return Component_Type;
229 function Saturate (X : SI64) return Component_Type;
231 function Saturate (X : F64) return Component_Type;
233 function Sign_Extend (X : c_int) return Component_Type;
234 -- [PIM-4.3 Notations and Conventions]
237 function abs_vxi (A : Varray_Type) return Varray_Type;
238 pragma Convention (LL_Altivec, abs_vxi);
240 function abss_vxi (A : Varray_Type) return Varray_Type;
241 pragma Convention (LL_Altivec, abss_vxi);
243 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
244 pragma Convention (LL_Altivec, vaddsxs);
246 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
247 pragma Convention (LL_Altivec, vavgsx);
249 function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
250 pragma Convention (LL_Altivec, vcmpgtsx);
252 function lvexx (A : c_long; B : c_ptr) return Varray_Type;
253 pragma Convention (LL_Altivec, lvexx);
255 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
256 pragma Convention (LL_Altivec, vmaxsx);
258 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
259 pragma Convention (LL_Altivec, vmrghx);
261 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
262 pragma Convention (LL_Altivec, vmrglx);
264 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
265 pragma Convention (LL_Altivec, vminsx);
267 function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
268 pragma Convention (LL_Altivec, vspltx);
270 function vspltisx (A : c_int) return Varray_Type;
271 pragma Convention (LL_Altivec, vspltisx);
273 type Bit_Operation is
275 (Value : Component_Type;
276 Amount : Natural) return Component_Type;
281 Shift_Func : Bit_Operation) return Varray_Type;
283 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
284 pragma Convention (LL_Altivec, stvexx);
286 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
287 pragma Convention (LL_Altivec, vsubsxs);
289 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
290 -- If D is the result of a vcmp operation and A the flag for
291 -- the kind of operation (e.g CR6_LT), check the predicate
292 -- that corresponds to this flag.
294 end Signed_Operations;
296 ------------------------------
297 -- Signed_Operations (body) --
298 ------------------------------
300 package body Signed_Operations is
302 Bool_True : constant Component_Type := Signed_Bool_True;
303 Bool_False : constant Component_Type := Signed_Bool_False;
305 Number_Of_Elements : constant Integer :=
306 VECTOR_BIT / Component_Type'Size;
312 function Modular_Result (X : SI64) return Component_Type is
317 D := Component_Type (UI64 (X)
318 mod (UI64 (Component_Type'Last) + 1));
320 D := Component_Type ((-(UI64 (-X)
321 mod (UI64 (Component_Type'Last) + 1))));
331 function Saturate (X : SI64) return Component_Type is
335 -- Saturation, as defined in
336 -- [PIM-4.1 Vector Status and Control Register]
338 D := Component_Type (SI64'Max
339 (SI64 (Component_Type'First),
341 (SI64 (Component_Type'Last),
344 if SI64 (D) /= X then
345 VSCR := Write_Bit (VSCR, SAT_POS, 1);
351 function Saturate (X : F64) return Component_Type is
355 -- Saturation, as defined in
356 -- [PIM-4.1 Vector Status and Control Register]
358 D := Component_Type (F64'Max
359 (F64 (Component_Type'First),
361 (F64 (Component_Type'Last),
365 VSCR := Write_Bit (VSCR, SAT_POS, 1);
375 function Sign_Extend (X : c_int) return Component_Type is
377 -- X is usually a 5-bits literal. In the case of the simulator,
378 -- it is an integral parameter, so sign extension is straightforward.
380 return Component_Type (X);
387 function abs_vxi (A : Varray_Type) return Varray_Type is
391 for K in Varray_Type'Range loop
392 if A (K) /= Component_Type'First then
393 D (K) := abs (A (K));
395 D (K) := Component_Type'First;
406 function abss_vxi (A : Varray_Type) return Varray_Type is
410 for K in Varray_Type'Range loop
411 D (K) := Saturate (abs (SI64 (A (K))));
421 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
425 for J in Varray_Type'Range loop
426 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
436 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
440 for J in Varray_Type'Range loop
441 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
453 B : Varray_Type) return Varray_Type
458 for J in Varray_Type'Range loop
459 if A (J) > B (J) then
473 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
476 EA : Integer_Address;
480 S := 16 / Number_Of_Elements;
481 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
482 Integer_Address (S));
483 J := Index_Type (((EA mod 16) / Integer_Address (S))
484 + Integer_Address (Index_Type'First));
487 Component : Component_Type;
488 for Component'Address use To_Address (EA);
500 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
504 for J in Varray_Type'Range loop
505 if A (J) > B (J) then
519 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
521 Offset : constant Integer := Integer (Index_Type'First);
522 M : constant Integer := Number_Of_Elements / 2;
525 for J in 0 .. M - 1 loop
526 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
527 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
537 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
539 Offset : constant Integer := Integer (Index_Type'First);
540 M : constant Integer := Number_Of_Elements / 2;
543 for J in 0 .. M - 1 loop
544 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
545 D (Index_Type (2 * J + Offset + 1)) :=
546 B (Index_Type (J + Offset + M));
556 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
560 for J in Varray_Type'Range loop
561 if A (J) < B (J) then
575 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
576 J : constant Integer :=
577 Integer (B) mod Number_Of_Elements
578 + Integer (Varray_Type'First);
582 for K in Varray_Type'Range loop
583 D (K) := A (Index_Type (J));
593 function vspltisx (A : c_int) return Varray_Type is
597 for J in Varray_Type'Range loop
598 D (J) := Sign_Extend (A);
611 Shift_Func : Bit_Operation) return Varray_Type
614 S : constant Component_Type :=
615 Component_Type (128 / Number_Of_Elements);
618 for J in Varray_Type'Range loop
619 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
629 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
631 EA : Integer_Address;
635 S := 16 / Number_Of_Elements;
636 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
637 Integer_Address (S));
638 J := Index_Type ((EA mod 16) / Integer_Address (S)
639 + Integer_Address (Index_Type'First));
642 Component : Component_Type;
643 for Component'Address use To_Address (EA);
653 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
657 for J in Varray_Type'Range loop
658 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
668 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
669 All_Element : Boolean := True;
670 Any_Element : Boolean := False;
673 for J in Varray_Type'Range loop
674 All_Element := All_Element and (D (J) = Bool_True);
675 Any_Element := Any_Element or (D (J) = Bool_True);
685 elsif A = CR6_EQ then
686 if not Any_Element then
692 elsif A = CR6_EQ_REV then
699 elsif A = CR6_LT_REV then
700 if not All_Element then
710 end Signed_Operations;
712 --------------------------------
713 -- Unsigned_Operations (spec) --
714 --------------------------------
717 type Component_Type is mod <>;
718 type Index_Type is range <>;
719 type Varray_Type is array (Index_Type) of Component_Type;
721 package Unsigned_Operations is
726 High : Natural) return Component_Type;
727 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
728 -- using big endian bit ordering.
733 Value : Unsigned_1) return Component_Type;
734 -- Write Value into X[Where:Where] (if it fits in) and return the result
735 -- (big endian bit ordering).
737 function Modular_Result (X : UI64) return Component_Type;
739 function Saturate (X : UI64) return Component_Type;
741 function Saturate (X : F64) return Component_Type;
743 function Saturate (X : SI64) return Component_Type;
745 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
747 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
749 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
751 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
753 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
755 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
757 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
759 type Bit_Operation is
761 (Value : Component_Type;
762 Amount : Natural) return Component_Type;
767 ROTL : Bit_Operation) return Varray_Type;
772 Shift_Func : Bit_Operation) return Varray_Type;
773 -- Vector shift (left or right, depending on Shift_Func)
775 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
777 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
779 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
780 -- If D is the result of a vcmp operation and A the flag for
781 -- the kind of operation (e.g CR6_LT), check the predicate
782 -- that corresponds to this flag.
784 end Unsigned_Operations;
786 --------------------------------
787 -- Unsigned_Operations (body) --
788 --------------------------------
790 package body Unsigned_Operations is
792 Number_Of_Elements : constant Integer :=
793 VECTOR_BIT / Component_Type'Size;
795 Bool_True : constant Component_Type := Component_Type'Last;
796 Bool_False : constant Component_Type := 0;
802 function Modular_Result (X : UI64) return Component_Type is
805 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
813 function Saturate (X : UI64) return Component_Type is
817 -- Saturation, as defined in
818 -- [PIM-4.1 Vector Status and Control Register]
820 D := Component_Type (UI64'Max
821 (UI64 (Component_Type'First),
823 (UI64 (Component_Type'Last),
826 if UI64 (D) /= X then
827 VSCR := Write_Bit (VSCR, SAT_POS, 1);
833 function Saturate (X : SI64) return Component_Type is
837 -- Saturation, as defined in
838 -- [PIM-4.1 Vector Status and Control Register]
840 D := Component_Type (SI64'Max
841 (SI64 (Component_Type'First),
843 (SI64 (Component_Type'Last),
846 if SI64 (D) /= X then
847 VSCR := Write_Bit (VSCR, SAT_POS, 1);
853 function Saturate (X : F64) return Component_Type is
857 -- Saturation, as defined in
858 -- [PIM-4.1 Vector Status and Control Register]
860 D := Component_Type (F64'Max
861 (F64 (Component_Type'First),
863 (F64 (Component_Type'Last),
867 VSCR := Write_Bit (VSCR, SAT_POS, 1);
880 High : Natural) return Component_Type
882 Mask : Component_Type := 0;
884 -- The Altivec ABI uses a big endian bit ordering, and we are
885 -- using little endian bit ordering for extracting bits:
887 Low_LE : constant Natural := Component_Type'Size - 1 - High;
888 High_LE : constant Natural := Component_Type'Size - 1 - Low;
891 pragma Assert (Low <= Component_Type'Size);
892 pragma Assert (High <= Component_Type'Size);
894 for J in Low_LE .. High_LE loop
895 Mask := Mask or 2 ** J;
898 return (X and Mask) / 2 ** Low_LE;
908 Value : Unsigned_1) return Component_Type
910 Result : Component_Type := 0;
912 -- The Altivec ABI uses a big endian bit ordering, and we are
913 -- using little endian bit ordering for extracting bits:
915 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
918 pragma Assert (Where < Component_Type'Size);
922 Result := X or 2 ** Where_LE;
924 Result := X and not (2 ** Where_LE);
934 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
938 for J in Varray_Type'Range loop
939 D (J) := A (J) + B (J);
949 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
953 for J in Varray_Type'Range loop
954 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
964 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
968 for J in Varray_Type'Range loop
969 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
981 B : Varray_Type) return Varray_Type
986 for J in Varray_Type'Range loop
987 if A (J) = B (J) then
1003 B : Varray_Type) return Varray_Type
1007 for J in Varray_Type'Range loop
1008 if A (J) > B (J) then
1011 D (J) := Bool_False;
1022 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1026 for J in Varray_Type'Range loop
1027 if A (J) > B (J) then
1041 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1045 for J in Varray_Type'Range loop
1046 if A (J) < B (J) then
1063 ROTL : Bit_Operation) return Varray_Type
1068 for J in Varray_Type'Range loop
1069 D (J) := ROTL (A (J), Natural (B (J)));
1082 Shift_Func : Bit_Operation) return Varray_Type
1085 S : constant Component_Type :=
1086 Component_Type (128 / Number_Of_Elements);
1089 for J in Varray_Type'Range loop
1090 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1100 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1104 for J in Varray_Type'Range loop
1105 D (J) := A (J) - B (J);
1115 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1119 for J in Varray_Type'Range loop
1120 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1130 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1131 All_Element : Boolean := True;
1132 Any_Element : Boolean := False;
1135 for J in Varray_Type'Range loop
1136 All_Element := All_Element and (D (J) = Bool_True);
1137 Any_Element := Any_Element or (D (J) = Bool_True);
1147 elsif A = CR6_EQ then
1148 if not Any_Element then
1154 elsif A = CR6_EQ_REV then
1161 elsif A = CR6_LT_REV then
1162 if not All_Element then
1172 end Unsigned_Operations;
1174 --------------------------------------
1175 -- Signed_Merging_Operations (spec) --
1176 --------------------------------------
1179 type Component_Type is range <>;
1180 type Index_Type is range <>;
1181 type Varray_Type is array (Index_Type) of Component_Type;
1182 type Double_Component_Type is range <>;
1183 type Double_Index_Type is range <>;
1184 type Double_Varray_Type is array (Double_Index_Type)
1185 of Double_Component_Type;
1187 package Signed_Merging_Operations is
1189 pragma Assert (Integer (Varray_Type'First)
1190 = Integer (Double_Varray_Type'First));
1191 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1192 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1195 (X : Double_Component_Type) return Component_Type;
1198 (Use_Even_Components : Boolean;
1200 B : Varray_Type) return Double_Varray_Type;
1203 (A : Double_Varray_Type;
1204 B : Double_Varray_Type) return Varray_Type;
1205 pragma Convention (LL_Altivec, vpksxss);
1209 Offset : Natural) return Double_Varray_Type;
1211 end Signed_Merging_Operations;
1213 --------------------------------------
1214 -- Signed_Merging_Operations (body) --
1215 --------------------------------------
1217 package body Signed_Merging_Operations is
1224 (X : Double_Component_Type) return Component_Type
1229 -- Saturation, as defined in
1230 -- [PIM-4.1 Vector Status and Control Register]
1232 D := Component_Type (Double_Component_Type'Max
1233 (Double_Component_Type (Component_Type'First),
1234 Double_Component_Type'Min
1235 (Double_Component_Type (Component_Type'Last),
1238 if Double_Component_Type (D) /= X then
1239 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1250 (Use_Even_Components : Boolean;
1252 B : Varray_Type) return Double_Varray_Type
1254 Double_Offset : Double_Index_Type;
1255 Offset : Index_Type;
1256 D : Double_Varray_Type;
1257 N : constant Integer :=
1258 Integer (Double_Index_Type'Last)
1259 - Integer (Double_Index_Type'First) + 1;
1263 for J in 0 .. N - 1 loop
1264 if Use_Even_Components then
1265 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1267 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1271 Double_Index_Type (J + Integer (Double_Index_Type'First));
1272 D (Double_Offset) :=
1273 Double_Component_Type (A (Offset))
1274 * Double_Component_Type (B (Offset));
1285 (A : Double_Varray_Type;
1286 B : Double_Varray_Type) return Varray_Type
1288 N : constant Index_Type :=
1289 Index_Type (Double_Index_Type'Last);
1291 Offset : Index_Type;
1292 Double_Offset : Double_Index_Type;
1295 for J in 0 .. N - 1 loop
1296 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1298 Double_Index_Type (Integer (J)
1299 + Integer (Double_Index_Type'First));
1300 D (Offset) := Saturate (A (Double_Offset));
1301 D (Offset + N) := Saturate (B (Double_Offset));
1313 Offset : Natural) return Double_Varray_Type
1316 D : Double_Varray_Type;
1319 for J in Double_Varray_Type'Range loop
1320 K := Index_Type (Integer (J)
1321 - Integer (Double_Index_Type'First)
1322 + Integer (Index_Type'First)
1324 D (J) := Double_Component_Type (A (K));
1330 end Signed_Merging_Operations;
1332 ----------------------------------------
1333 -- Unsigned_Merging_Operations (spec) --
1334 ----------------------------------------
1337 type Component_Type is mod <>;
1338 type Index_Type is range <>;
1339 type Varray_Type is array (Index_Type) of Component_Type;
1340 type Double_Component_Type is mod <>;
1341 type Double_Index_Type is range <>;
1342 type Double_Varray_Type is array (Double_Index_Type)
1343 of Double_Component_Type;
1345 package Unsigned_Merging_Operations is
1347 pragma Assert (Integer (Varray_Type'First)
1348 = Integer (Double_Varray_Type'First));
1349 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1350 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1352 function UI_To_UI_Mod
1353 (X : Double_Component_Type;
1354 Y : Natural) return Component_Type;
1356 function Saturate (X : Double_Component_Type) return Component_Type;
1359 (Use_Even_Components : Boolean;
1361 B : Varray_Type) return Double_Varray_Type;
1364 (A : Double_Varray_Type;
1365 B : Double_Varray_Type) return Varray_Type;
1368 (A : Double_Varray_Type;
1369 B : Double_Varray_Type) return Varray_Type;
1371 end Unsigned_Merging_Operations;
1373 ----------------------------------------
1374 -- Unsigned_Merging_Operations (body) --
1375 ----------------------------------------
1377 package body Unsigned_Merging_Operations is
1383 function UI_To_UI_Mod
1384 (X : Double_Component_Type;
1385 Y : Natural) return Component_Type is
1388 Z := Component_Type (X mod 2 ** Y);
1396 function Saturate (X : Double_Component_Type) return Component_Type is
1400 -- Saturation, as defined in
1401 -- [PIM-4.1 Vector Status and Control Register]
1403 D := Component_Type (Double_Component_Type'Max
1404 (Double_Component_Type (Component_Type'First),
1405 Double_Component_Type'Min
1406 (Double_Component_Type (Component_Type'Last),
1409 if Double_Component_Type (D) /= X then
1410 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1421 (Use_Even_Components : Boolean;
1423 B : Varray_Type) return Double_Varray_Type
1425 Double_Offset : Double_Index_Type;
1426 Offset : Index_Type;
1427 D : Double_Varray_Type;
1428 N : constant Integer :=
1429 Integer (Double_Index_Type'Last)
1430 - Integer (Double_Index_Type'First) + 1;
1433 for J in 0 .. N - 1 loop
1434 if Use_Even_Components then
1435 Offset := Index_Type (2 * J + Integer (Index_Type'First));
1437 Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
1441 Double_Index_Type (J + Integer (Double_Index_Type'First));
1442 D (Double_Offset) :=
1443 Double_Component_Type (A (Offset))
1444 * Double_Component_Type (B (Offset));
1455 (A : Double_Varray_Type;
1456 B : Double_Varray_Type) return Varray_Type
1458 S : constant Natural :=
1459 Double_Component_Type'Size / 2;
1460 N : constant Index_Type :=
1461 Index_Type (Double_Index_Type'Last);
1463 Offset : Index_Type;
1464 Double_Offset : Double_Index_Type;
1467 for J in 0 .. N - 1 loop
1468 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1470 Double_Index_Type (Integer (J)
1471 + Integer (Double_Index_Type'First));
1472 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1473 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1484 (A : Double_Varray_Type;
1485 B : Double_Varray_Type) return Varray_Type
1487 N : constant Index_Type :=
1488 Index_Type (Double_Index_Type'Last);
1490 Offset : Index_Type;
1491 Double_Offset : Double_Index_Type;
1494 for J in 0 .. N - 1 loop
1495 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1497 Double_Index_Type (Integer (J)
1498 + Integer (Double_Index_Type'First));
1499 D (Offset) := Saturate (A (Double_Offset));
1500 D (Offset + N) := Saturate (B (Double_Offset));
1506 end Unsigned_Merging_Operations;
1508 package LL_VSC_Operations is
1509 new Signed_Operations (signed_char,
1511 Varray_signed_char);
1513 package LL_VSS_Operations is
1514 new Signed_Operations (signed_short,
1516 Varray_signed_short);
1518 package LL_VSI_Operations is
1519 new Signed_Operations (signed_int,
1523 package LL_VUC_Operations is
1524 new Unsigned_Operations (unsigned_char,
1526 Varray_unsigned_char);
1528 package LL_VUS_Operations is
1529 new Unsigned_Operations (unsigned_short,
1531 Varray_unsigned_short);
1533 package LL_VUI_Operations is
1534 new Unsigned_Operations (unsigned_int,
1536 Varray_unsigned_int);
1538 package LL_VSC_LL_VSS_Operations is
1539 new Signed_Merging_Operations (signed_char,
1544 Varray_signed_short);
1546 package LL_VSS_LL_VSI_Operations is
1547 new Signed_Merging_Operations (signed_short,
1549 Varray_signed_short,
1554 package LL_VUC_LL_VUS_Operations is
1555 new Unsigned_Merging_Operations (unsigned_char,
1557 Varray_unsigned_char,
1560 Varray_unsigned_short);
1562 package LL_VUS_LL_VUI_Operations is
1563 new Unsigned_Merging_Operations (unsigned_short,
1565 Varray_unsigned_short,
1568 Varray_unsigned_int);
1577 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1580 (X : unsigned_short;
1582 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1587 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1596 Value : Unsigned_1) return unsigned_int
1597 renames LL_VUI_Operations.Write_Bit;
1600 (X : unsigned_short;
1602 Value : Unsigned_1) return unsigned_short
1603 renames LL_VUS_Operations.Write_Bit;
1608 Value : Unsigned_1) return unsigned_char
1609 renames LL_VUC_Operations.Write_Bit;
1615 function Bound_Align
1616 (X : Integer_Address;
1617 Y : Integer_Address) return Integer_Address
1619 D : Integer_Address;
1629 function NJ_Truncate (X : C_float) return C_float is
1633 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1634 and then abs (X) < 2.0 ** (-126)
1648 -----------------------
1649 -- Rnd_To_FP_Nearest --
1650 -----------------------
1652 function Rnd_To_FP_Nearest (X : F64) return C_float is
1655 end Rnd_To_FP_Nearest;
1657 ---------------------
1658 -- Rnd_To_FPI_Near --
1659 ---------------------
1661 function Rnd_To_FPI_Near (X : F64) return F64 is
1665 Result := F64 (SI64 (X));
1667 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1669 Ceiling := F64'Ceiling (X);
1670 if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling then
1673 Result := Ceiling - 1.0;
1678 end Rnd_To_FPI_Near;
1680 ----------------------
1681 -- Rnd_To_FPI_Trunc --
1682 ----------------------
1684 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1688 Result := F64'Ceiling (X);
1690 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1694 and then Result /= X
1696 Result := Result - 1.0;
1700 end Rnd_To_FPI_Trunc;
1706 function FP_Recip_Est (X : C_float) return C_float is
1708 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1709 -- -Inf, or QNaN, the estimate has a relative error no greater
1710 -- than one part in 4096, that is:
1711 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1713 return NJ_Truncate (1.0 / NJ_Truncate (X));
1721 (Value : unsigned_char;
1722 Amount : Natural) return unsigned_char
1724 Result : Unsigned_8;
1726 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1727 return unsigned_char (Result);
1731 (Value : unsigned_short;
1732 Amount : Natural) return unsigned_short
1734 Result : Unsigned_16;
1736 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1737 return unsigned_short (Result);
1741 (Value : unsigned_int;
1742 Amount : Natural) return unsigned_int
1744 Result : Unsigned_32;
1746 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1747 return unsigned_int (Result);
1750 --------------------
1751 -- Recip_SQRT_Est --
1752 --------------------
1754 function Recip_SQRT_Est (X : C_float) return C_float is
1759 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1760 -- no greater than one part in 4096, that is:
1761 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1763 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1764 return NJ_Truncate (Result);
1772 (Value : unsigned_char;
1773 Amount : Natural) return unsigned_char
1775 Result : Unsigned_8;
1777 Result := Shift_Left (Unsigned_8 (Value), Amount);
1778 return unsigned_char (Result);
1782 (Value : unsigned_short;
1783 Amount : Natural) return unsigned_short
1785 Result : Unsigned_16;
1787 Result := Shift_Left (Unsigned_16 (Value), Amount);
1788 return unsigned_short (Result);
1792 (Value : unsigned_int;
1793 Amount : Natural) return unsigned_int
1795 Result : Unsigned_32;
1797 Result := Shift_Left (Unsigned_32 (Value), Amount);
1798 return unsigned_int (Result);
1805 function Shift_Right
1806 (Value : unsigned_char;
1807 Amount : Natural) return unsigned_char
1809 Result : Unsigned_8;
1811 Result := Shift_Right (Unsigned_8 (Value), Amount);
1812 return unsigned_char (Result);
1815 function Shift_Right
1816 (Value : unsigned_short;
1817 Amount : Natural) return unsigned_short
1819 Result : Unsigned_16;
1821 Result := Shift_Right (Unsigned_16 (Value), Amount);
1822 return unsigned_short (Result);
1825 function Shift_Right
1826 (Value : unsigned_int;
1827 Amount : Natural) return unsigned_int
1829 Result : Unsigned_32;
1831 Result := Shift_Right (Unsigned_32 (Value), Amount);
1832 return unsigned_int (Result);
1840 type Signed_Type is range <>;
1841 type Unsigned_Type is mod <>;
1842 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1843 return Unsigned_Type;
1844 function Shift_Right_Arithmetic
1845 (Value : Signed_Type;
1846 Amount : Natural) return Signed_Type;
1848 function Shift_Right_Arithmetic
1849 (Value : Signed_Type;
1850 Amount : Natural) return Signed_Type
1854 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1856 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1859 end Shift_Right_Arithmetic;
1861 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1865 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1869 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1876 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1878 -- This conversion should not depend on the host endianess;
1879 -- therefore, we cannot use an unchecked conversion.
1884 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1885 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1886 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1887 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1891 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1893 -- This conversion should not depend on the host endianess;
1894 -- therefore, we cannot use an unchecked conversion.
1899 Target.T := unsigned_char (Bits (Source, 0, 7));
1900 Target.R := unsigned_char (Bits (Source, 8, 15));
1901 Target.G := unsigned_char (Bits (Source, 16, 23));
1902 Target.B := unsigned_char (Bits (Source, 24, 31));
1906 ---------------------
1907 -- To_unsigned_int --
1908 ---------------------
1910 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1912 -- This conversion should not depend on the host endianess;
1913 -- therefore, we cannot use an unchecked conversion.
1914 -- It should also be the same result, value-wise, on two hosts
1915 -- with the same endianess.
1917 Target : unsigned_int := 0;
1920 -- In big endian bit ordering, Pixel_32 looks like:
1921 -- -------------------------------------
1922 -- | T | R | G | B |
1923 -- -------------------------------------
1924 -- 0 (MSB) 7 15 23 32
1926 -- Sizes of the components: (8/8/8/8)
1928 Target := Target or unsigned_int (Source.T);
1929 Target := Shift_Left (Target, 8);
1930 Target := Target or unsigned_int (Source.R);
1931 Target := Shift_Left (Target, 8);
1932 Target := Target or unsigned_int (Source.G);
1933 Target := Shift_Left (Target, 8);
1934 Target := Target or unsigned_int (Source.B);
1936 end To_unsigned_int;
1938 -----------------------
1939 -- To_unsigned_short --
1940 -----------------------
1942 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1944 -- This conversion should not depend on the host endianess;
1945 -- therefore, we cannot use an unchecked conversion.
1946 -- It should also be the same result, value-wise, on two hosts
1947 -- with the same endianess.
1949 Target : unsigned_short := 0;
1952 -- In big endian bit ordering, Pixel_16 looks like:
1953 -- -------------------------------------
1954 -- | T | R | G | B |
1955 -- -------------------------------------
1956 -- 0 (MSB) 1 5 11 15
1958 -- Sizes of the components: (1/5/5/5)
1960 Target := Target or unsigned_short (Source.T);
1961 Target := Shift_Left (Target, 5);
1962 Target := Target or unsigned_short (Source.R);
1963 Target := Shift_Left (Target, 5);
1964 Target := Target or unsigned_short (Source.G);
1965 Target := Shift_Left (Target, 5);
1966 Target := Target or unsigned_short (Source.B);
1968 end To_unsigned_short;
1974 function abs_v16qi (A : LL_VSC) return LL_VSC is
1975 VA : constant VSC_View := To_View (A);
1977 return To_Vector ((Values =>
1978 LL_VSC_Operations.abs_vxi (VA.Values)));
1985 function abs_v8hi (A : LL_VSS) return LL_VSS is
1986 VA : constant VSS_View := To_View (A);
1988 return To_Vector ((Values =>
1989 LL_VSS_Operations.abs_vxi (VA.Values)));
1996 function abs_v4si (A : LL_VSI) return LL_VSI is
1997 VA : constant VSI_View := To_View (A);
1999 return To_Vector ((Values =>
2000 LL_VSI_Operations.abs_vxi (VA.Values)));
2007 function abs_v4sf (A : LL_VF) return LL_VF is
2009 VA : constant VF_View := To_View (A);
2012 for J in Varray_float'Range loop
2013 D (J) := abs (VA.Values (J));
2016 return To_Vector ((Values => D));
2023 function abss_v16qi (A : LL_VSC) return LL_VSC is
2024 VA : constant VSC_View := To_View (A);
2026 return To_Vector ((Values =>
2027 LL_VSC_Operations.abss_vxi (VA.Values)));
2034 function abss_v8hi (A : LL_VSS) return LL_VSS is
2035 VA : constant VSS_View := To_View (A);
2037 return To_Vector ((Values =>
2038 LL_VSS_Operations.abss_vxi (VA.Values)));
2045 function abss_v4si (A : LL_VSI) return LL_VSI is
2046 VA : constant VSI_View := To_View (A);
2048 return To_Vector ((Values =>
2049 LL_VSI_Operations.abss_vxi (VA.Values)));
2056 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2057 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2059 VA : constant VUC_View :=
2061 VB : constant VUC_View := To_View (To_LL_VUC (B));
2062 D : Varray_unsigned_char;
2065 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2066 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2073 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2074 VA : constant VUS_View := To_View (To_LL_VUS (A));
2075 VB : constant VUS_View := To_View (To_LL_VUS (B));
2076 D : Varray_unsigned_short;
2079 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2080 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2087 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2088 VA : constant VUI_View := To_View (To_LL_VUI (A));
2089 VB : constant VUI_View := To_View (To_LL_VUI (B));
2090 D : Varray_unsigned_int;
2093 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2094 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2101 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2102 VA : constant VF_View := To_View (A);
2103 VB : constant VF_View := To_View (B);
2107 for J in Varray_float'Range loop
2108 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2109 + NJ_Truncate (VB.Values (J)));
2112 return To_Vector (VF_View'(Values => D));
2119 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2120 Addition_Result : UI64;
2122 VA : constant VUI_View := To_View (To_LL_VUI (A));
2123 VB : constant VUI_View := To_View (To_LL_VUI (B));
2126 for J in Varray_unsigned_int'Range loop
2128 UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2130 if Addition_Result > UI64 (unsigned_int'Last) then
2137 return To_LL_VSI (To_Vector (D));
2144 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2145 VA : constant VUC_View := To_View (To_LL_VUC (A));
2146 VB : constant VUC_View := To_View (To_LL_VUC (B));
2149 return To_LL_VSC (To_Vector
2150 (VUC_View'(Values =>
2151 (LL_VUC_Operations.vadduxs
2160 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2161 VA : constant VSC_View := To_View (A);
2162 VB : constant VSC_View := To_View (B);
2166 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2167 return To_Vector (D);
2174 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2175 VA : constant VUS_View := To_View (To_LL_VUS (A));
2176 VB : constant VUS_View := To_View (To_LL_VUS (B));
2180 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2181 return To_LL_VSS (To_Vector (D));
2188 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2189 VA : constant VSS_View := To_View (A);
2190 VB : constant VSS_View := To_View (B);
2194 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2195 return To_Vector (D);
2202 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2203 VA : constant VUI_View := To_View (To_LL_VUI (A));
2204 VB : constant VUI_View := To_View (To_LL_VUI (B));
2208 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2209 return To_LL_VSI (To_Vector (D));
2216 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2217 VA : constant VSI_View := To_View (A);
2218 VB : constant VSI_View := To_View (B);
2222 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2223 return To_Vector (D);
2230 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2231 VA : constant VUI_View := To_View (To_LL_VUI (A));
2232 VB : constant VUI_View := To_View (To_LL_VUI (B));
2236 for J in Varray_unsigned_int'Range loop
2237 D.Values (J) := VA.Values (J) and VB.Values (J);
2240 return To_LL_VSI (To_Vector (D));
2247 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2248 VA : constant VUI_View := To_View (To_LL_VUI (A));
2249 VB : constant VUI_View := To_View (To_LL_VUI (B));
2253 for J in Varray_unsigned_int'Range loop
2254 D.Values (J) := VA.Values (J) and not VB.Values (J);
2257 return To_LL_VSI (To_Vector (D));
2264 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2265 VA : constant VUC_View := To_View (To_LL_VUC (A));
2266 VB : constant VUC_View := To_View (To_LL_VUC (B));
2270 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2271 return To_LL_VSC (To_Vector (D));
2278 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2279 VA : constant VSC_View := To_View (A);
2280 VB : constant VSC_View := To_View (B);
2284 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2285 return To_Vector (D);
2292 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2293 VA : constant VUS_View := To_View (To_LL_VUS (A));
2294 VB : constant VUS_View := To_View (To_LL_VUS (B));
2298 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2299 return To_LL_VSS (To_Vector (D));
2306 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2307 VA : constant VSS_View := To_View (A);
2308 VB : constant VSS_View := To_View (B);
2312 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2313 return To_Vector (D);
2320 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2321 VA : constant VUI_View := To_View (To_LL_VUI (A));
2322 VB : constant VUI_View := To_View (To_LL_VUI (B));
2326 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2327 return To_LL_VSI (To_Vector (D));
2334 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2335 VA : constant VSI_View := To_View (A);
2336 VB : constant VSI_View := To_View (B);
2340 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2341 return To_Vector (D);
2348 function vrfip (A : LL_VF) return LL_VF is
2349 VA : constant VF_View := To_View (A);
2353 for J in Varray_float'Range loop
2355 -- If A (J) is infinite, D (J) should be infinite; With
2356 -- IEEE floating points, we can use 'Ceiling for that purpose.
2358 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2362 return To_Vector (D);
2369 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2370 VA : constant VF_View := To_View (A);
2371 VB : constant VF_View := To_View (B);
2376 for J in Varray_float'Range loop
2377 K := Vint_Range (J);
2380 if NJ_Truncate (VB.Values (J)) < 0.0 then
2382 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2383 -- word element in B is negative; the corresponding element in A
2384 -- is out of bounds.
2386 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2387 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2390 if NJ_Truncate (VA.Values (J))
2391 <= NJ_Truncate (VB.Values (J)) then
2392 D.Values (K) := Write_Bit (D.Values (K), 0, 0);
2394 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2397 if NJ_Truncate (VA.Values (J))
2398 >= -NJ_Truncate (VB.Values (J)) then
2399 D.Values (K) := Write_Bit (D.Values (K), 1, 0);
2401 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2406 return To_LL_VSI (To_Vector (D));
2413 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2414 VA : constant VUC_View := To_View (To_LL_VUC (A));
2415 VB : constant VUC_View := To_View (To_LL_VUC (B));
2419 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2420 return To_LL_VSC (To_Vector (D));
2427 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2428 VA : constant VUS_View := To_View (To_LL_VUS (A));
2429 VB : constant VUS_View := To_View (To_LL_VUS (B));
2432 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2433 return To_LL_VSS (To_Vector (D));
2440 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2441 VA : constant VUI_View := To_View (To_LL_VUI (A));
2442 VB : constant VUI_View := To_View (To_LL_VUI (B));
2445 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2446 return To_LL_VSI (To_Vector (D));
2453 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2454 VA : constant VF_View := To_View (A);
2455 VB : constant VF_View := To_View (B);
2460 for J in Varray_float'Range loop
2461 K := Vint_Range (J);
2463 if VA.Values (J) = VB.Values (J) then
2464 D.Values (K) := unsigned_int'Last;
2470 return To_LL_VSI (To_Vector (D));
2477 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2478 VA : constant VF_View := To_View (A);
2479 VB : constant VF_View := To_View (B);
2484 for J in Varray_float'Range loop
2485 K := Vint_Range (J);
2487 if VA.Values (J) >= VB.Values (J) then
2488 D.Values (K) := Signed_Bool_True;
2490 D.Values (K) := Signed_Bool_False;
2494 return To_Vector (D);
2501 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2502 VA : constant VUC_View := To_View (To_LL_VUC (A));
2503 VB : constant VUC_View := To_View (To_LL_VUC (B));
2506 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2507 return To_LL_VSC (To_Vector (D));
2514 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2515 VA : constant VSC_View := To_View (A);
2516 VB : constant VSC_View := To_View (B);
2519 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2520 return To_Vector (D);
2527 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2528 VA : constant VUS_View := To_View (To_LL_VUS (A));
2529 VB : constant VUS_View := To_View (To_LL_VUS (B));
2532 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2533 return To_LL_VSS (To_Vector (D));
2540 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2541 VA : constant VSS_View := To_View (A);
2542 VB : constant VSS_View := To_View (B);
2545 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2546 return To_Vector (D);
2553 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2554 VA : constant VUI_View := To_View (To_LL_VUI (A));
2555 VB : constant VUI_View := To_View (To_LL_VUI (B));
2558 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2559 return To_LL_VSI (To_Vector (D));
2566 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2567 VA : constant VSI_View := To_View (A);
2568 VB : constant VSI_View := To_View (B);
2571 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2572 return To_Vector (D);
2579 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2580 VA : constant VF_View := To_View (A);
2581 VB : constant VF_View := To_View (B);
2586 for J in Varray_float'Range loop
2587 K := Vint_Range (J);
2589 if NJ_Truncate (VA.Values (J))
2590 > NJ_Truncate (VB.Values (J)) then
2591 D.Values (K) := Signed_Bool_True;
2593 D.Values (K) := Signed_Bool_False;
2597 return To_Vector (D);
2604 function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2606 VA : constant VUI_View := To_View (To_LL_VUI (A));
2610 for J in Varray_signed_int'Range loop
2611 K := Vfloat_Range (J);
2613 -- Note: The conversion to Integer is safe, as Integers are required
2614 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2615 -- include the range of B (should be 0 .. 255).
2618 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2621 return To_Vector (D);
2628 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2629 VA : constant VSI_View := To_View (A);
2634 for J in Varray_signed_int'Range loop
2635 K := Vfloat_Range (J);
2636 D.Values (K) := C_float (VA.Values (J))
2637 / (2.0 ** Integer (B));
2640 return To_Vector (D);
2647 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2648 VA : constant VF_View := To_View (A);
2653 for J in Varray_signed_int'Range loop
2654 K := Vfloat_Range (J);
2656 LL_VSI_Operations.Saturate
2657 (F64 (NJ_Truncate (VA.Values (K)))
2658 * F64 (2.0 ** Integer (B)));
2661 return To_Vector (D);
2668 function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2669 VA : constant VF_View := To_View (A);
2674 for J in Varray_unsigned_int'Range loop
2675 K := Vfloat_Range (J);
2677 LL_VUI_Operations.Saturate
2678 (F64 (NJ_Truncate (VA.Values (K)))
2679 * F64 (2.0 ** Integer (B)));
2682 return To_LL_VSI (To_Vector (D));
2689 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2691 procedure dss (A : c_int) is
2692 pragma Unreferenced (A);
2701 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2712 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2714 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2715 pragma Unreferenced (A);
2716 pragma Unreferenced (B);
2717 pragma Unreferenced (C);
2726 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2728 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2729 pragma Unreferenced (A);
2730 pragma Unreferenced (B);
2731 pragma Unreferenced (C);
2740 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2742 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2743 pragma Unreferenced (A);
2744 pragma Unreferenced (B);
2745 pragma Unreferenced (C);
2754 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2756 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2757 pragma Unreferenced (A);
2758 pragma Unreferenced (B);
2759 pragma Unreferenced (C);
2768 function vexptefp (A : LL_VF) return LL_VF is
2769 use C_float_Operations;
2771 VA : constant VF_View := To_View (A);
2775 for J in Varray_float'Range loop
2777 -- ??? Check the precision of the operation.
2778 -- As described in [PEM-6 vexptefp]:
2779 -- If theorical_result is equal to 2 at the power of A (J) with
2780 -- infinite precision, we should have:
2781 -- abs ((D (J) - theorical_result) / theorical_result) <= 1/16
2783 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2786 return To_Vector (D);
2793 function vrfim (A : LL_VF) return LL_VF is
2794 VA : constant VF_View := To_View (A);
2798 for J in Varray_float'Range loop
2800 -- If A (J) is infinite, D (J) should be infinite; With
2801 -- IEEE floating point, we can use 'Ceiling for that purpose.
2803 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2805 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2808 if D.Values (J) /= VA.Values (J) then
2809 D.Values (J) := D.Values (J) - 1.0;
2813 return To_Vector (D);
2820 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2821 EA : Integer_Address;
2824 EA := Bound_Align (Integer_Address (A) + To_Integer (B), 16);
2828 for D'Address use To_Address (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
4410 EA : Integer_Address;
4413 EA := Bound_Align (Integer_Address (B) + To_Integer (C), 16);
4417 for D'Address use To_Address (EA);
4427 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4428 VA : constant VSC_View := To_View (A);
4430 LL_VSC_Operations.stvexx (VA.Values, B, C);
4437 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4438 VA : constant VSS_View := To_View (A);
4440 LL_VSS_Operations.stvexx (VA.Values, B, C);
4447 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4448 VA : constant VSI_View := To_View (A);
4450 LL_VSI_Operations.stvexx (VA.Values, B, C);
4457 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4463 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4464 VA : constant VUC_View := To_View (To_LL_VUC (A));
4465 VB : constant VUC_View := To_View (To_LL_VUC (B));
4468 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4469 return To_LL_VSC (To_Vector (D));
4476 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4477 VA : constant VUS_View := To_View (To_LL_VUS (A));
4478 VB : constant VUS_View := To_View (To_LL_VUS (B));
4481 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4482 return To_LL_VSS (To_Vector (D));
4489 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4490 VA : constant VUI_View := To_View (To_LL_VUI (A));
4491 VB : constant VUI_View := To_View (To_LL_VUI (B));
4494 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4495 return To_LL_VSI (To_Vector (D));
4502 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4503 VA : constant VF_View := To_View (A);
4504 VB : constant VF_View := To_View (B);
4508 for J in Vfloat_Range'Range loop
4510 NJ_Truncate (NJ_Truncate (VA.Values (J))
4511 - NJ_Truncate (VB.Values (J)));
4514 return To_Vector (D);
4521 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4522 Subst_Result : SI64;
4524 VA : constant VUI_View := To_View (To_LL_VUI (A));
4525 VB : constant VUI_View := To_View (To_LL_VUI (B));
4529 for J in Vint_Range'Range loop
4530 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4532 if Subst_Result < SI64 (unsigned_int'First) then
4539 return To_LL_VSI (To_Vector (D));
4546 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4547 VA : constant VUC_View := To_View (To_LL_VUC (A));
4548 VB : constant VUC_View := To_View (To_LL_VUC (B));
4551 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4552 return To_LL_VSC (To_Vector (D));
4559 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4560 VA : constant VSC_View := To_View (A);
4561 VB : constant VSC_View := To_View (B);
4564 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4565 return To_Vector (D);
4572 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4573 VA : constant VUS_View := To_View (To_LL_VUS (A));
4574 VB : constant VUS_View := To_View (To_LL_VUS (B));
4577 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4578 return To_LL_VSS (To_Vector (D));
4585 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4586 VA : constant VSS_View := To_View (A);
4587 VB : constant VSS_View := To_View (B);
4590 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4591 return To_Vector (D);
4598 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4599 VA : constant VUI_View := To_View (To_LL_VUI (A));
4600 VB : constant VUI_View := To_View (To_LL_VUI (B));
4603 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4604 return To_LL_VSI (To_Vector (D));
4611 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4612 VA : constant VSI_View := To_View (A);
4613 VB : constant VSI_View := To_View (B);
4616 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4617 return To_Vector (D);
4624 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4625 VA : constant VUC_View := To_View (To_LL_VUC (A));
4626 VB : constant VUI_View := To_View (To_LL_VUI (B));
4627 Offset : Vchar_Range;
4631 for J in 0 .. 3 loop
4632 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4633 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4634 LL_VUI_Operations.Saturate
4635 (UI64 (VA.Values (Offset))
4636 + UI64 (VA.Values (Offset + 1))
4637 + UI64 (VA.Values (Offset + 2))
4638 + UI64 (VA.Values (Offset + 3))
4639 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4642 return To_LL_VSI (To_Vector (D));
4649 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4650 VA : constant VSC_View := To_View (A);
4651 VB : constant VSI_View := To_View (B);
4652 Offset : Vchar_Range;
4656 for J in 0 .. 3 loop
4657 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4658 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4659 LL_VSI_Operations.Saturate
4660 (SI64 (VA.Values (Offset))
4661 + SI64 (VA.Values (Offset + 1))
4662 + SI64 (VA.Values (Offset + 2))
4663 + SI64 (VA.Values (Offset + 3))
4664 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4667 return To_Vector (D);
4674 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4675 VA : constant VSS_View := To_View (A);
4676 VB : constant VSI_View := To_View (B);
4677 Offset : Vshort_Range;
4681 for J in 0 .. 3 loop
4682 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4683 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4684 LL_VSI_Operations.Saturate
4685 (SI64 (VA.Values (Offset))
4686 + SI64 (VA.Values (Offset + 1))
4687 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4690 return To_Vector (D);
4697 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4698 VA : constant VSI_View := To_View (A);
4699 VB : constant VSI_View := To_View (B);
4700 Offset : Vint_Range;
4704 for J in 0 .. 1 loop
4705 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4706 D.Values (Offset) := 0;
4707 D.Values (Offset + 1) :=
4708 LL_VSI_Operations.Saturate
4709 (SI64 (VA.Values (Offset))
4710 + SI64 (VA.Values (Offset + 1))
4711 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4714 return To_Vector (D);
4721 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4722 VA : constant VSI_View := To_View (A);
4723 VB : constant VSI_View := To_View (B);
4725 Sum_Buffer : SI64 := 0;
4728 for J in Vint_Range'Range loop
4730 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4733 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4734 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4735 return To_Vector (D);
4742 function vrfiz (A : LL_VF) return LL_VF is
4743 VA : constant VF_View := To_View (A);
4746 for J in Vfloat_Range'Range loop
4747 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4750 return To_Vector (D);
4757 function vupkhsb (A : LL_VSC) return LL_VSS is
4758 VA : constant VSC_View := To_View (A);
4761 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4762 return To_Vector (D);
4769 function vupkhsh (A : LL_VSS) return LL_VSI is
4770 VA : constant VSS_View := To_View (A);
4773 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4774 return To_Vector (D);
4781 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4782 -- For vupkhpx and vupklpx (depending on Offset)
4784 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4785 VA : constant VUS_View := To_View (To_LL_VUS (A));
4791 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4793 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4803 for J in Vint_Range'Range loop
4804 K := Vshort_Range (Integer (J)
4805 - Integer (Vint_Range'First)
4806 + Integer (Vshort_Range'First)
4808 P16 := To_Pixel (VA.Values (K));
4809 P32.T := Sign_Extend (P16.T);
4810 P32.R := unsigned_char (P16.R);
4811 P32.G := unsigned_char (P16.G);
4812 P32.B := unsigned_char (P16.B);
4813 D.Values (J) := To_unsigned_int (P32);
4816 return To_LL_VSI (To_Vector (D));
4823 function vupkhpx (A : LL_VSS) return LL_VSI is
4825 return vupkxpx (A, 0);
4832 function vupklsb (A : LL_VSC) return LL_VSS is
4833 VA : constant VSC_View := To_View (A);
4837 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4838 Varray_signed_short'Length);
4839 return To_Vector (D);
4846 function vupklsh (A : LL_VSS) return LL_VSI is
4847 VA : constant VSS_View := To_View (A);
4851 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4852 Varray_signed_int'Length);
4853 return To_Vector (D);
4860 function vupklpx (A : LL_VSS) return LL_VSI is
4862 return vupkxpx (A, Varray_signed_int'Length);
4869 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4870 VA : constant VUI_View := To_View (To_LL_VUI (A));
4871 VB : constant VUI_View := To_View (To_LL_VUI (B));
4875 for J in Vint_Range'Range loop
4876 D.Values (J) := VA.Values (J) xor VB.Values (J);
4879 return To_LL_VSI (To_Vector (D));
4886 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4889 D := vcmpequb (B, C);
4890 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4897 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4900 D := vcmpequh (B, C);
4901 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4908 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4911 D := vcmpequw (B, C);
4912 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4919 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4922 D := vcmpeqfp (B, C);
4923 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4930 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4933 D := vcmpgtub (B, C);
4934 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4941 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4944 D := vcmpgtuh (B, C);
4945 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4952 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4955 D := vcmpgtuw (B, C);
4956 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4963 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4966 D := vcmpgtsb (B, C);
4967 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4974 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4977 D := vcmpgtsh (B, C);
4978 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4985 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4988 D := vcmpgtsw (B, C);
4989 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4996 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4999 D := vcmpgefp (B, C);
5000 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5007 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5010 D := vcmpgtfp (B, C);
5011 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
5018 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
5021 D := To_View (vcmpbfp (B, C));
5023 for J in Vint_Range'Range loop
5024 -- vcmpbfp is not returning the usual bool vector; do the conversion
5025 if D.Values (J) = 0 then
5026 D.Values (J) := Signed_Bool_False;
5028 D.Values (J) := Signed_Bool_True;
5032 return LL_VSI_Operations.Check_CR6 (A, D.Values);
5035 end GNAT.Altivec.Low_Level_Vectors;