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