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