1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- G N A T . A L T I V E C . L O W _ L E V E L _ V E C T O R S --
8 -- (Soft Binding Version) --
10 -- Copyright (C) 2004-2005, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
35 -- ??? What is exactly needed for the soft case is still a bit unclear on
36 -- some accounts. The expected functional equivalence with the Hard binding
37 -- might require tricky things to be done on some targets.
39 -- Examples that come to mind are endianness variations or differences in the
40 -- base FP model while we need the operation results to be the same as what
41 -- the real AltiVec instructions would do on a PowerPC.
43 with Ada
.Numerics
.Generic_Elementary_Functions
;
44 with Interfaces
; use Interfaces
;
45 with System
.Storage_Elements
; use System
.Storage_Elements
;
47 with GNAT
.Altivec
.Conversions
; use GNAT
.Altivec
.Conversions
;
48 with GNAT
.Altivec
.Low_Level_Interface
; use GNAT
.Altivec
.Low_Level_Interface
;
50 package body GNAT
.Altivec
.Low_Level_Vectors
is
52 -- This package assumes C_float is an IEEE single-precision float type
54 pragma Assert
(C_float
'Machine_Radix = 2);
55 pragma Assert
(C_float
'Machine_Mantissa = 24);
56 pragma Assert
(C_float
'Machine_Emin = -125);
57 pragma Assert
(C_float
'Machine_Emax = 128);
58 pragma Assert
(C_float
'Machine_Rounds);
59 pragma Assert
(not C_float
'Machine_Overflows);
60 pragma Assert
(C_float
'Signed_Zeros);
61 pragma Assert
(C_float
'Denorm);
63 -- Pixel types. As defined in [PIM-2.1 Data types]:
64 -- A 16-bit pixel is 1/5/5/5;
65 -- A 32-bit pixel is 8/8/8/8.
66 -- We use the following records as an intermediate representation, to
69 type Unsigned_1
is mod 2 ** 1;
70 type Unsigned_5
is mod 2 ** 5;
72 type Pixel_16
is record
79 type Pixel_32
is record
86 -- Conversions to/from the pixel records to the integer types that are
87 -- actually stored into the pixel vectors:
89 function To_Pixel
(Source
: unsigned_short
) return Pixel_16
;
90 function To_unsigned_short
(Source
: Pixel_16
) return unsigned_short
;
91 function To_Pixel
(Source
: unsigned_int
) return Pixel_32
;
92 function To_unsigned_int
(Source
: Pixel_32
) return unsigned_int
;
94 package C_float_Operations
is
95 new Ada
.Numerics
.Generic_Elementary_Functions
(C_float
);
97 -- Model of the Vector Status and Control Register (VSCR), as
98 -- defined in [PIM-4.1 Vector Status and Control Register]:
102 -- Positions of the flags in VSCR(0 .. 31):
104 NJ_POS
: constant := 15;
105 SAT_POS
: constant := 31;
107 -- To control overflows, integer operations are done on 64-bit types:
109 SINT64_MIN
: constant := -2 ** 63;
110 SINT64_MAX
: constant := 2 ** 63 - 1;
111 UINT64_MAX
: constant := 2 ** 64 - 1;
113 type SI64
is range SINT64_MIN
.. SINT64_MAX
;
114 type UI64
is mod UINT64_MAX
+ 1;
116 type F64
is digits 15
117 range -16#
0.FFFF_FFFF_FFFF_F8#E
+256 .. 16#
0.FFFF_FFFF_FFFF_F8#E
+256;
122 High
: Natural) return unsigned_int
;
127 High
: Natural) return unsigned_short
;
132 High
: Natural) return unsigned_char
;
137 Value
: Unsigned_1
) return unsigned_int
;
142 Value
: Unsigned_1
) return unsigned_short
;
147 Value
: Unsigned_1
) return unsigned_char
;
149 function NJ_Truncate
(X
: C_float
) return C_float
;
150 -- If NJ and A is a denormalized number, return zero
153 (X
: Integer_Address
;
154 Y
: Integer_Address
) return Integer_Address
;
155 -- [PIM-4.3 Notations and Conventions]
156 -- Align X in a y-byte boundary and return the result
158 function Rnd_To_FP_Nearest
(X
: F64
) return C_float
;
159 -- [PIM-4.3 Notations and Conventions]
161 function Rnd_To_FPI_Near
(X
: F64
) return F64
;
163 function Rnd_To_FPI_Trunc
(X
: F64
) return F64
;
165 function FP_Recip_Est
(X
: C_float
) return C_float
;
166 -- [PIM-4.3 Notations and Conventions]
167 -- 12-bit accurate floating-point estimate of 1/x
170 (Value
: unsigned_char
;
171 Amount
: Natural) return unsigned_char
;
172 -- [PIM-4.3 Notations and Conventions]
176 (Value
: unsigned_short
;
177 Amount
: Natural) return unsigned_short
;
180 (Value
: unsigned_int
;
181 Amount
: Natural) return unsigned_int
;
183 function Recip_SQRT_Est
(X
: C_float
) return C_float
;
186 (Value
: unsigned_char
;
187 Amount
: Natural) return unsigned_char
;
188 -- [PIM-4.3 Notations and Conventions]
192 (Value
: unsigned_short
;
193 Amount
: Natural) return unsigned_short
;
196 (Value
: unsigned_int
;
197 Amount
: Natural) return unsigned_int
;
200 (Value
: unsigned_char
;
201 Amount
: Natural) return unsigned_char
;
202 -- [PIM-4.3 Notations and Conventions]
206 (Value
: unsigned_short
;
207 Amount
: Natural) return unsigned_short
;
210 (Value
: unsigned_int
;
211 Amount
: Natural) return unsigned_int
;
213 Signed_Bool_False
: constant := 0;
214 Signed_Bool_True
: constant := -1;
216 ------------------------------
217 -- Signed_Operations (spec) --
218 ------------------------------
221 type Component_Type
is range <>;
222 type Index_Type
is range <>;
223 type Varray_Type
is array (Index_Type
) of Component_Type
;
225 package Signed_Operations
is
227 function Modular_Result
(X
: SI64
) return Component_Type
;
229 function Saturate
(X
: SI64
) return Component_Type
;
231 function Saturate
(X
: F64
) return Component_Type
;
233 function Sign_Extend
(X
: c_int
) return Component_Type
;
234 -- [PIM-4.3 Notations and Conventions]
237 function abs_vxi
(A
: Varray_Type
) return Varray_Type
;
238 pragma Convention
(LL_Altivec
, abs_vxi
);
240 function abss_vxi
(A
: Varray_Type
) return Varray_Type
;
241 pragma Convention
(LL_Altivec
, abss_vxi
);
243 function vaddsxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
244 pragma Convention
(LL_Altivec
, vaddsxs
);
246 function vavgsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
247 pragma Convention
(LL_Altivec
, vavgsx
);
249 function vcmpgtsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
250 pragma Convention
(LL_Altivec
, vcmpgtsx
);
252 function lvexx
(A
: c_long
; B
: c_ptr
) return Varray_Type
;
253 pragma Convention
(LL_Altivec
, lvexx
);
255 function vmaxsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
256 pragma Convention
(LL_Altivec
, vmaxsx
);
258 function vmrghx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
259 pragma Convention
(LL_Altivec
, vmrghx
);
261 function vmrglx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
262 pragma Convention
(LL_Altivec
, vmrglx
);
264 function vminsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
265 pragma Convention
(LL_Altivec
, vminsx
);
267 function vspltx
(A
: Varray_Type
; B
: c_int
) return Varray_Type
;
268 pragma Convention
(LL_Altivec
, vspltx
);
270 function vspltisx
(A
: c_int
) return Varray_Type
;
271 pragma Convention
(LL_Altivec
, vspltisx
);
273 type Bit_Operation
is
275 (Value
: Component_Type
;
276 Amount
: Natural) return Component_Type
;
281 Shift_Func
: Bit_Operation
) return Varray_Type
;
283 procedure stvexx
(A
: Varray_Type
; B
: c_int
; C
: c_ptr
);
284 pragma Convention
(LL_Altivec
, stvexx
);
286 function vsubsxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
287 pragma Convention
(LL_Altivec
, vsubsxs
);
289 function Check_CR6
(A
: c_int
; D
: Varray_Type
) return c_int
;
290 -- If D is the result of a vcmp operation and A the flag for
291 -- the kind of operation (e.g CR6_LT), check the predicate
292 -- that corresponds to this flag.
294 end Signed_Operations
;
296 ------------------------------
297 -- Signed_Operations (body) --
298 ------------------------------
300 package body Signed_Operations
is
302 Bool_True
: constant Component_Type
:= Signed_Bool_True
;
303 Bool_False
: constant Component_Type
:= Signed_Bool_False
;
305 Number_Of_Elements
: constant Integer :=
306 VECTOR_BIT
/ Component_Type
'Size;
312 function Modular_Result
(X
: SI64
) return Component_Type
is
317 D
:= Component_Type
(UI64
(X
)
318 mod (UI64
(Component_Type
'Last) + 1));
320 D
:= Component_Type
((-(UI64
(-X
)
321 mod (UI64
(Component_Type
'Last) + 1))));
331 function Saturate
(X
: SI64
) return Component_Type
is
335 -- Saturation, as defined in
336 -- [PIM-4.1 Vector Status and Control Register]
338 D
:= Component_Type
(SI64
'Max
339 (SI64
(Component_Type
'First),
341 (SI64
(Component_Type
'Last),
344 if SI64
(D
) /= X
then
345 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
351 function Saturate
(X
: F64
) return Component_Type
is
355 -- Saturation, as defined in
356 -- [PIM-4.1 Vector Status and Control Register]
358 D
:= Component_Type
(F64
'Max
359 (F64
(Component_Type
'First),
361 (F64
(Component_Type
'Last),
365 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
375 function Sign_Extend
(X
: c_int
) return Component_Type
is
377 -- X is usually a 5-bits literal. In the case of the simulator,
378 -- it is an integral parameter, so sign extension is straightforward.
380 return Component_Type
(X
);
387 function abs_vxi
(A
: Varray_Type
) return Varray_Type
is
391 for K
in Varray_Type
'Range loop
392 if A
(K
) /= Component_Type
'First then
393 D
(K
) := abs (A
(K
));
395 D
(K
) := Component_Type
'First;
406 function abss_vxi
(A
: Varray_Type
) return Varray_Type
is
410 for K
in Varray_Type
'Range loop
411 D
(K
) := Saturate
(abs (SI64
(A
(K
))));
421 function vaddsxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
425 for J
in Varray_Type
'Range loop
426 D
(J
) := Saturate
(SI64
(A
(J
)) + SI64
(B
(J
)));
436 function vavgsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
440 for J
in Varray_Type
'Range loop
441 D
(J
) := Component_Type
((SI64
(A
(J
)) + SI64
(B
(J
)) + 1) / 2);
453 B
: Varray_Type
) return Varray_Type
458 for J
in Varray_Type
'Range loop
459 if A
(J
) > B
(J
) then
473 function lvexx
(A
: c_long
; B
: c_ptr
) return Varray_Type
is
476 EA
: Integer_Address
;
480 S
:= 16 / Number_Of_Elements
;
481 EA
:= Bound_Align
(Integer_Address
(A
) + To_Integer
(B
),
482 Integer_Address
(S
));
483 J
:= Index_Type
(((EA
mod 16) / Integer_Address
(S
))
484 + Integer_Address
(Index_Type
'First));
487 Component
: Component_Type
;
488 for Component
'Address use To_Address
(EA
);
500 function vmaxsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
504 for J
in Varray_Type
'Range loop
505 if A
(J
) > B
(J
) then
519 function vmrghx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
521 Offset
: constant Integer := Integer (Index_Type
'First);
522 M
: constant Integer := Number_Of_Elements
/ 2;
525 for J
in 0 .. M
- 1 loop
526 D
(Index_Type
(2 * J
+ Offset
)) := A
(Index_Type
(J
+ Offset
));
527 D
(Index_Type
(2 * J
+ Offset
+ 1)) := B
(Index_Type
(J
+ Offset
));
537 function vmrglx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
539 Offset
: constant Integer := Integer (Index_Type
'First);
540 M
: constant Integer := Number_Of_Elements
/ 2;
543 for J
in 0 .. M
- 1 loop
544 D
(Index_Type
(2 * J
+ Offset
)) := A
(Index_Type
(J
+ Offset
+ M
));
545 D
(Index_Type
(2 * J
+ Offset
+ 1)) :=
546 B
(Index_Type
(J
+ Offset
+ M
));
556 function vminsx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
560 for J
in Varray_Type
'Range loop
561 if A
(J
) < B
(J
) then
575 function vspltx
(A
: Varray_Type
; B
: c_int
) return Varray_Type
is
576 J
: constant Integer :=
577 Integer (B
) mod Number_Of_Elements
578 + Integer (Varray_Type
'First);
582 for K
in Varray_Type
'Range loop
583 D
(K
) := A
(Index_Type
(J
));
593 function vspltisx
(A
: c_int
) return Varray_Type
is
597 for J
in Varray_Type
'Range loop
598 D
(J
) := Sign_Extend
(A
);
611 Shift_Func
: Bit_Operation
) return Varray_Type
614 S
: constant Component_Type
:=
615 Component_Type
(128 / Number_Of_Elements
);
618 for J
in Varray_Type
'Range loop
619 D
(J
) := Shift_Func
(A
(J
), Natural (B
(J
) mod S
));
629 procedure stvexx
(A
: Varray_Type
; B
: c_int
; C
: c_ptr
) is
631 EA
: Integer_Address
;
635 S
:= 16 / Number_Of_Elements
;
636 EA
:= Bound_Align
(Integer_Address
(B
) + To_Integer
(C
),
637 Integer_Address
(S
));
638 J
:= Index_Type
((EA
mod 16) / Integer_Address
(S
)
639 + Integer_Address
(Index_Type
'First));
642 Component
: Component_Type
;
643 for Component
'Address use To_Address
(EA
);
653 function vsubsxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
657 for J
in Varray_Type
'Range loop
658 D
(J
) := Saturate
(SI64
(A
(J
)) - SI64
(B
(J
)));
668 function Check_CR6
(A
: c_int
; D
: Varray_Type
) return c_int
is
669 All_Element
: Boolean := True;
670 Any_Element
: Boolean := False;
673 for J
in Varray_Type
'Range loop
674 All_Element
:= All_Element
and (D
(J
) = Bool_True
);
675 Any_Element
:= Any_Element
or (D
(J
) = Bool_True
);
685 elsif A
= CR6_EQ
then
686 if not Any_Element
then
692 elsif A
= CR6_EQ_REV
then
699 elsif A
= CR6_LT_REV
then
700 if not All_Element
then
710 end Signed_Operations
;
712 --------------------------------
713 -- Unsigned_Operations (spec) --
714 --------------------------------
717 type Component_Type
is mod <>;
718 type Index_Type
is range <>;
719 type Varray_Type
is array (Index_Type
) of Component_Type
;
721 package Unsigned_Operations
is
726 High
: Natural) return Component_Type
;
727 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
728 -- using big endian bit ordering.
733 Value
: Unsigned_1
) return Component_Type
;
734 -- Write Value into X[Where:Where] (if it fits in) and return the result
735 -- (big endian bit ordering).
737 function Modular_Result
(X
: UI64
) return Component_Type
;
739 function Saturate
(X
: UI64
) return Component_Type
;
741 function Saturate
(X
: F64
) return Component_Type
;
743 function Saturate
(X
: SI64
) return Component_Type
;
745 function vadduxm
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
747 function vadduxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
749 function vavgux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
751 function vcmpequx
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
753 function vcmpgtux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
755 function vmaxux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
757 function vminux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
759 type Bit_Operation
is
761 (Value
: Component_Type
;
762 Amount
: Natural) return Component_Type
;
767 ROTL
: Bit_Operation
) return Varray_Type
;
772 Shift_Func
: Bit_Operation
) return Varray_Type
;
773 -- Vector shift (left or right, depending on Shift_Func)
775 function vsubuxm
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
777 function vsubuxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
;
779 function Check_CR6
(A
: c_int
; D
: Varray_Type
) return c_int
;
780 -- If D is the result of a vcmp operation and A the flag for
781 -- the kind of operation (e.g CR6_LT), check the predicate
782 -- that corresponds to this flag.
784 end Unsigned_Operations
;
786 --------------------------------
787 -- Unsigned_Operations (body) --
788 --------------------------------
790 package body Unsigned_Operations
is
792 Number_Of_Elements
: constant Integer :=
793 VECTOR_BIT
/ Component_Type
'Size;
795 Bool_True
: constant Component_Type
:= Component_Type
'Last;
796 Bool_False
: constant Component_Type
:= 0;
802 function Modular_Result
(X
: UI64
) return Component_Type
is
805 D
:= Component_Type
(X
mod (UI64
(Component_Type
'Last) + 1));
813 function Saturate
(X
: UI64
) return Component_Type
is
817 -- Saturation, as defined in
818 -- [PIM-4.1 Vector Status and Control Register]
820 D
:= Component_Type
(UI64
'Max
821 (UI64
(Component_Type
'First),
823 (UI64
(Component_Type
'Last),
826 if UI64
(D
) /= X
then
827 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
833 function Saturate
(X
: SI64
) return Component_Type
is
837 -- Saturation, as defined in
838 -- [PIM-4.1 Vector Status and Control Register]
840 D
:= Component_Type
(SI64
'Max
841 (SI64
(Component_Type
'First),
843 (SI64
(Component_Type
'Last),
846 if SI64
(D
) /= X
then
847 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
853 function Saturate
(X
: F64
) return Component_Type
is
857 -- Saturation, as defined in
858 -- [PIM-4.1 Vector Status and Control Register]
860 D
:= Component_Type
(F64
'Max
861 (F64
(Component_Type
'First),
863 (F64
(Component_Type
'Last),
867 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
880 High
: Natural) return Component_Type
882 Mask
: Component_Type
:= 0;
884 -- The Altivec ABI uses a big endian bit ordering, and we are
885 -- using little endian bit ordering for extracting bits:
887 Low_LE
: constant Natural := Component_Type
'Size - 1 - High
;
888 High_LE
: constant Natural := Component_Type
'Size - 1 - Low
;
891 pragma Assert
(Low
<= Component_Type
'Size);
892 pragma Assert
(High
<= Component_Type
'Size);
894 for J
in Low_LE
.. High_LE
loop
895 Mask
:= Mask
or 2 ** J
;
898 return (X
and Mask
) / 2 ** Low_LE
;
908 Value
: Unsigned_1
) return Component_Type
910 Result
: Component_Type
:= 0;
912 -- The Altivec ABI uses a big endian bit ordering, and we are
913 -- using little endian bit ordering for extracting bits:
915 Where_LE
: constant Natural := Component_Type
'Size - 1 - Where
;
918 pragma Assert
(Where
< Component_Type
'Size);
922 Result
:= X
or 2 ** Where_LE
;
924 Result
:= X
and not (2 ** Where_LE
);
934 function vadduxm
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
938 for J
in Varray_Type
'Range loop
939 D
(J
) := A
(J
) + B
(J
);
949 function vadduxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
953 for J
in Varray_Type
'Range loop
954 D
(J
) := Saturate
(UI64
(A
(J
)) + UI64
(B
(J
)));
964 function vavgux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
968 for J
in Varray_Type
'Range loop
969 D
(J
) := Component_Type
((UI64
(A
(J
)) + UI64
(B
(J
)) + 1) / 2);
981 B
: Varray_Type
) return Varray_Type
986 for J
in Varray_Type
'Range loop
987 if A
(J
) = B
(J
) then
1003 B
: Varray_Type
) return Varray_Type
1007 for J
in Varray_Type
'Range loop
1008 if A
(J
) > B
(J
) then
1011 D
(J
) := Bool_False
;
1022 function vmaxux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
1026 for J
in Varray_Type
'Range loop
1027 if A
(J
) > B
(J
) then
1041 function vminux
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
1045 for J
in Varray_Type
'Range loop
1046 if A
(J
) < B
(J
) then
1063 ROTL
: Bit_Operation
) return Varray_Type
1068 for J
in Varray_Type
'Range loop
1069 D
(J
) := ROTL
(A
(J
), Natural (B
(J
)));
1082 Shift_Func
: Bit_Operation
) return Varray_Type
1085 S
: constant Component_Type
:=
1086 Component_Type
(128 / Number_Of_Elements
);
1089 for J
in Varray_Type
'Range loop
1090 D
(J
) := Shift_Func
(A
(J
), Natural (B
(J
) mod S
));
1100 function vsubuxm
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
1104 for J
in Varray_Type
'Range loop
1105 D
(J
) := A
(J
) - B
(J
);
1115 function vsubuxs
(A
: Varray_Type
; B
: Varray_Type
) return Varray_Type
is
1119 for J
in Varray_Type
'Range loop
1120 D
(J
) := Saturate
(SI64
(A
(J
)) - SI64
(B
(J
)));
1130 function Check_CR6
(A
: c_int
; D
: Varray_Type
) return c_int
is
1131 All_Element
: Boolean := True;
1132 Any_Element
: Boolean := False;
1135 for J
in Varray_Type
'Range loop
1136 All_Element
:= All_Element
and (D
(J
) = Bool_True
);
1137 Any_Element
:= Any_Element
or (D
(J
) = Bool_True
);
1147 elsif A
= CR6_EQ
then
1148 if not Any_Element
then
1154 elsif A
= CR6_EQ_REV
then
1161 elsif A
= CR6_LT_REV
then
1162 if not All_Element
then
1172 end Unsigned_Operations
;
1174 --------------------------------------
1175 -- Signed_Merging_Operations (spec) --
1176 --------------------------------------
1179 type Component_Type
is range <>;
1180 type Index_Type
is range <>;
1181 type Varray_Type
is array (Index_Type
) of Component_Type
;
1182 type Double_Component_Type
is range <>;
1183 type Double_Index_Type
is range <>;
1184 type Double_Varray_Type
is array (Double_Index_Type
)
1185 of Double_Component_Type
;
1187 package Signed_Merging_Operations
is
1189 pragma Assert
(Integer (Varray_Type
'First)
1190 = Integer (Double_Varray_Type
'First));
1191 pragma Assert
(Varray_Type
'Length = 2 * Double_Varray_Type
'Length);
1192 pragma Assert
(2 * Component_Type
'Size = Double_Component_Type
'Size);
1195 (X
: Double_Component_Type
) return Component_Type
;
1198 (Use_Even_Components
: Boolean;
1200 B
: Varray_Type
) return Double_Varray_Type
;
1203 (A
: Double_Varray_Type
;
1204 B
: Double_Varray_Type
) return Varray_Type
;
1205 pragma Convention
(LL_Altivec
, vpksxss
);
1209 Offset
: Natural) return Double_Varray_Type
;
1211 end Signed_Merging_Operations
;
1213 --------------------------------------
1214 -- Signed_Merging_Operations (body) --
1215 --------------------------------------
1217 package body Signed_Merging_Operations
is
1224 (X
: Double_Component_Type
) return Component_Type
1229 -- Saturation, as defined in
1230 -- [PIM-4.1 Vector Status and Control Register]
1232 D
:= Component_Type
(Double_Component_Type
'Max
1233 (Double_Component_Type
(Component_Type
'First),
1234 Double_Component_Type
'Min
1235 (Double_Component_Type
(Component_Type
'Last),
1238 if Double_Component_Type
(D
) /= X
then
1239 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
1250 (Use_Even_Components
: Boolean;
1252 B
: Varray_Type
) return Double_Varray_Type
1254 Double_Offset
: Double_Index_Type
;
1255 Offset
: Index_Type
;
1256 D
: Double_Varray_Type
;
1257 N
: constant Integer :=
1258 Integer (Double_Index_Type
'Last)
1259 - Integer (Double_Index_Type
'First) + 1;
1263 for J
in 0 .. N
- 1 loop
1264 if Use_Even_Components
then
1265 Offset
:= Index_Type
(2 * J
+ Integer (Index_Type
'First));
1267 Offset
:= Index_Type
(2 * J
+ 1 + Integer (Index_Type
'First));
1271 Double_Index_Type
(J
+ Integer (Double_Index_Type
'First));
1272 D
(Double_Offset
) :=
1273 Double_Component_Type
(A
(Offset
))
1274 * Double_Component_Type
(B
(Offset
));
1285 (A
: Double_Varray_Type
;
1286 B
: Double_Varray_Type
) return Varray_Type
1288 N
: constant Index_Type
:=
1289 Index_Type
(Double_Index_Type
'Last);
1291 Offset
: Index_Type
;
1292 Double_Offset
: Double_Index_Type
;
1295 for J
in 0 .. N
- 1 loop
1296 Offset
:= Index_Type
(Integer (J
) + Integer (Index_Type
'First));
1298 Double_Index_Type
(Integer (J
)
1299 + Integer (Double_Index_Type
'First));
1300 D
(Offset
) := Saturate
(A
(Double_Offset
));
1301 D
(Offset
+ N
) := Saturate
(B
(Double_Offset
));
1313 Offset
: Natural) return Double_Varray_Type
1316 D
: Double_Varray_Type
;
1319 for J
in Double_Varray_Type
'Range loop
1320 K
:= Index_Type
(Integer (J
)
1321 - Integer (Double_Index_Type
'First)
1322 + Integer (Index_Type
'First)
1324 D
(J
) := Double_Component_Type
(A
(K
));
1330 end Signed_Merging_Operations
;
1332 ----------------------------------------
1333 -- Unsigned_Merging_Operations (spec) --
1334 ----------------------------------------
1337 type Component_Type
is mod <>;
1338 type Index_Type
is range <>;
1339 type Varray_Type
is array (Index_Type
) of Component_Type
;
1340 type Double_Component_Type
is mod <>;
1341 type Double_Index_Type
is range <>;
1342 type Double_Varray_Type
is array (Double_Index_Type
)
1343 of Double_Component_Type
;
1345 package Unsigned_Merging_Operations
is
1347 pragma Assert
(Integer (Varray_Type
'First)
1348 = Integer (Double_Varray_Type
'First));
1349 pragma Assert
(Varray_Type
'Length = 2 * Double_Varray_Type
'Length);
1350 pragma Assert
(2 * Component_Type
'Size = Double_Component_Type
'Size);
1352 function UI_To_UI_Mod
1353 (X
: Double_Component_Type
;
1354 Y
: Natural) return Component_Type
;
1356 function Saturate
(X
: Double_Component_Type
) return Component_Type
;
1359 (Use_Even_Components
: Boolean;
1361 B
: Varray_Type
) return Double_Varray_Type
;
1364 (A
: Double_Varray_Type
;
1365 B
: Double_Varray_Type
) return Varray_Type
;
1368 (A
: Double_Varray_Type
;
1369 B
: Double_Varray_Type
) return Varray_Type
;
1371 end Unsigned_Merging_Operations
;
1373 ----------------------------------------
1374 -- Unsigned_Merging_Operations (body) --
1375 ----------------------------------------
1377 package body Unsigned_Merging_Operations
is
1383 function UI_To_UI_Mod
1384 (X
: Double_Component_Type
;
1385 Y
: Natural) return Component_Type
is
1388 Z
:= Component_Type
(X
mod 2 ** Y
);
1396 function Saturate
(X
: Double_Component_Type
) return Component_Type
is
1400 -- Saturation, as defined in
1401 -- [PIM-4.1 Vector Status and Control Register]
1403 D
:= Component_Type
(Double_Component_Type
'Max
1404 (Double_Component_Type
(Component_Type
'First),
1405 Double_Component_Type
'Min
1406 (Double_Component_Type
(Component_Type
'Last),
1409 if Double_Component_Type
(D
) /= X
then
1410 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
1421 (Use_Even_Components
: Boolean;
1423 B
: Varray_Type
) return Double_Varray_Type
1425 Double_Offset
: Double_Index_Type
;
1426 Offset
: Index_Type
;
1427 D
: Double_Varray_Type
;
1428 N
: constant Integer :=
1429 Integer (Double_Index_Type
'Last)
1430 - Integer (Double_Index_Type
'First) + 1;
1433 for J
in 0 .. N
- 1 loop
1434 if Use_Even_Components
then
1435 Offset
:= Index_Type
(2 * J
+ Integer (Index_Type
'First));
1437 Offset
:= Index_Type
(2 * J
+ 1 + Integer (Index_Type
'First));
1441 Double_Index_Type
(J
+ Integer (Double_Index_Type
'First));
1442 D
(Double_Offset
) :=
1443 Double_Component_Type
(A
(Offset
))
1444 * Double_Component_Type
(B
(Offset
));
1455 (A
: Double_Varray_Type
;
1456 B
: Double_Varray_Type
) return Varray_Type
1458 S
: constant Natural :=
1459 Double_Component_Type
'Size / 2;
1460 N
: constant Index_Type
:=
1461 Index_Type
(Double_Index_Type
'Last);
1463 Offset
: Index_Type
;
1464 Double_Offset
: Double_Index_Type
;
1467 for J
in 0 .. N
- 1 loop
1468 Offset
:= Index_Type
(Integer (J
) + Integer (Index_Type
'First));
1470 Double_Index_Type
(Integer (J
)
1471 + Integer (Double_Index_Type
'First));
1472 D
(Offset
) := UI_To_UI_Mod
(A
(Double_Offset
), S
);
1473 D
(Offset
+ N
) := UI_To_UI_Mod
(B
(Double_Offset
), S
);
1484 (A
: Double_Varray_Type
;
1485 B
: Double_Varray_Type
) return Varray_Type
1487 N
: constant Index_Type
:=
1488 Index_Type
(Double_Index_Type
'Last);
1490 Offset
: Index_Type
;
1491 Double_Offset
: Double_Index_Type
;
1494 for J
in 0 .. N
- 1 loop
1495 Offset
:= Index_Type
(Integer (J
) + Integer (Index_Type
'First));
1497 Double_Index_Type
(Integer (J
)
1498 + Integer (Double_Index_Type
'First));
1499 D
(Offset
) := Saturate
(A
(Double_Offset
));
1500 D
(Offset
+ N
) := Saturate
(B
(Double_Offset
));
1506 end Unsigned_Merging_Operations
;
1508 package LL_VSC_Operations
is
1509 new Signed_Operations
(signed_char
,
1511 Varray_signed_char
);
1513 package LL_VSS_Operations
is
1514 new Signed_Operations
(signed_short
,
1516 Varray_signed_short
);
1518 package LL_VSI_Operations
is
1519 new Signed_Operations
(signed_int
,
1523 package LL_VUC_Operations
is
1524 new Unsigned_Operations
(unsigned_char
,
1526 Varray_unsigned_char
);
1528 package LL_VUS_Operations
is
1529 new Unsigned_Operations
(unsigned_short
,
1531 Varray_unsigned_short
);
1533 package LL_VUI_Operations
is
1534 new Unsigned_Operations
(unsigned_int
,
1536 Varray_unsigned_int
);
1538 package LL_VSC_LL_VSS_Operations
is
1539 new Signed_Merging_Operations
(signed_char
,
1544 Varray_signed_short
);
1546 package LL_VSS_LL_VSI_Operations
is
1547 new Signed_Merging_Operations
(signed_short
,
1549 Varray_signed_short
,
1554 package LL_VUC_LL_VUS_Operations
is
1555 new Unsigned_Merging_Operations
(unsigned_char
,
1557 Varray_unsigned_char
,
1560 Varray_unsigned_short
);
1562 package LL_VUS_LL_VUI_Operations
is
1563 new Unsigned_Merging_Operations
(unsigned_short
,
1565 Varray_unsigned_short
,
1568 Varray_unsigned_int
);
1577 High
: Natural) return unsigned_int
renames LL_VUI_Operations
.Bits
;
1580 (X
: unsigned_short
;
1582 High
: Natural) return unsigned_short
renames LL_VUS_Operations
.Bits
;
1587 High
: Natural) return unsigned_char
renames LL_VUC_Operations
.Bits
;
1596 Value
: Unsigned_1
) return unsigned_int
1597 renames LL_VUI_Operations
.Write_Bit
;
1600 (X
: unsigned_short
;
1602 Value
: Unsigned_1
) return unsigned_short
1603 renames LL_VUS_Operations
.Write_Bit
;
1608 Value
: Unsigned_1
) return unsigned_char
1609 renames LL_VUC_Operations
.Write_Bit
;
1615 function Bound_Align
1616 (X
: Integer_Address
;
1617 Y
: Integer_Address
) return Integer_Address
1619 D
: Integer_Address
;
1629 function NJ_Truncate
(X
: C_float
) return C_float
is
1633 if (Bits
(VSCR
, NJ_POS
, NJ_POS
) = 1)
1634 and then abs (X
) < 2.0 ** (-126)
1648 -----------------------
1649 -- Rnd_To_FP_Nearest --
1650 -----------------------
1652 function Rnd_To_FP_Nearest
(X
: F64
) return C_float
is
1655 end Rnd_To_FP_Nearest
;
1657 ---------------------
1658 -- Rnd_To_FPI_Near --
1659 ---------------------
1661 function Rnd_To_FPI_Near
(X
: F64
) return F64
is
1665 Result
:= F64
(SI64
(X
));
1667 if (F64
'Ceiling (X
) - X
) = (X
+ 1.0 - F64
'Ceiling (X
)) then
1669 Ceiling
:= F64
'Ceiling (X
);
1670 if Rnd_To_FPI_Trunc
(Ceiling
/ 2.0) * 2.0 = Ceiling
then
1673 Result
:= Ceiling
- 1.0;
1678 end Rnd_To_FPI_Near
;
1680 ----------------------
1681 -- Rnd_To_FPI_Trunc --
1682 ----------------------
1684 function Rnd_To_FPI_Trunc
(X
: F64
) return F64
is
1688 Result
:= F64
'Ceiling (X
);
1690 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1694 and then Result
/= X
1696 Result
:= Result
- 1.0;
1700 end Rnd_To_FPI_Trunc
;
1706 function FP_Recip_Est
(X
: C_float
) return C_float
is
1708 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1709 -- -Inf, or QNaN, the estimate has a relative error no greater
1710 -- than one part in 4096, that is:
1711 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1713 return NJ_Truncate
(1.0 / NJ_Truncate
(X
));
1721 (Value
: unsigned_char
;
1722 Amount
: Natural) return unsigned_char
1724 Result
: Unsigned_8
;
1726 Result
:= Rotate_Left
(Unsigned_8
(Value
), Amount
);
1727 return unsigned_char
(Result
);
1731 (Value
: unsigned_short
;
1732 Amount
: Natural) return unsigned_short
1734 Result
: Unsigned_16
;
1736 Result
:= Rotate_Left
(Unsigned_16
(Value
), Amount
);
1737 return unsigned_short
(Result
);
1741 (Value
: unsigned_int
;
1742 Amount
: Natural) return unsigned_int
1744 Result
: Unsigned_32
;
1746 Result
:= Rotate_Left
(Unsigned_32
(Value
), Amount
);
1747 return unsigned_int
(Result
);
1750 --------------------
1751 -- Recip_SQRT_Est --
1752 --------------------
1754 function Recip_SQRT_Est
(X
: C_float
) return C_float
is
1759 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1760 -- no greater than one part in 4096, that is:
1761 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1763 Result
:= 1.0 / NJ_Truncate
(C_float_Operations
.Sqrt
(NJ_Truncate
(X
)));
1764 return NJ_Truncate
(Result
);
1772 (Value
: unsigned_char
;
1773 Amount
: Natural) return unsigned_char
1775 Result
: Unsigned_8
;
1777 Result
:= Shift_Left
(Unsigned_8
(Value
), Amount
);
1778 return unsigned_char
(Result
);
1782 (Value
: unsigned_short
;
1783 Amount
: Natural) return unsigned_short
1785 Result
: Unsigned_16
;
1787 Result
:= Shift_Left
(Unsigned_16
(Value
), Amount
);
1788 return unsigned_short
(Result
);
1792 (Value
: unsigned_int
;
1793 Amount
: Natural) return unsigned_int
1795 Result
: Unsigned_32
;
1797 Result
:= Shift_Left
(Unsigned_32
(Value
), Amount
);
1798 return unsigned_int
(Result
);
1805 function Shift_Right
1806 (Value
: unsigned_char
;
1807 Amount
: Natural) return unsigned_char
1809 Result
: Unsigned_8
;
1811 Result
:= Shift_Right
(Unsigned_8
(Value
), Amount
);
1812 return unsigned_char
(Result
);
1815 function Shift_Right
1816 (Value
: unsigned_short
;
1817 Amount
: Natural) return unsigned_short
1819 Result
: Unsigned_16
;
1821 Result
:= Shift_Right
(Unsigned_16
(Value
), Amount
);
1822 return unsigned_short
(Result
);
1825 function Shift_Right
1826 (Value
: unsigned_int
;
1827 Amount
: Natural) return unsigned_int
1829 Result
: Unsigned_32
;
1831 Result
:= Shift_Right
(Unsigned_32
(Value
), Amount
);
1832 return unsigned_int
(Result
);
1840 type Signed_Type
is range <>;
1841 type Unsigned_Type
is mod <>;
1842 with function Shift_Right
(Value
: Unsigned_Type
; Amount
: Natural)
1843 return Unsigned_Type
;
1844 function Shift_Right_Arithmetic
1845 (Value
: Signed_Type
;
1846 Amount
: Natural) return Signed_Type
;
1848 function Shift_Right_Arithmetic
1849 (Value
: Signed_Type
;
1850 Amount
: Natural) return Signed_Type
1854 return Signed_Type
(Shift_Right
(Unsigned_Type
(Value
), Amount
));
1856 return -Signed_Type
(Shift_Right
(Unsigned_Type
(-Value
- 1), Amount
)
1859 end Shift_Right_Arithmetic
;
1861 function Shift_Right_A
is new Shift_Right_Arithmetic
(signed_int
,
1865 function Shift_Right_A
is new Shift_Right_Arithmetic
(signed_short
,
1869 function Shift_Right_A
is new Shift_Right_Arithmetic
(signed_char
,
1876 function To_Pixel
(Source
: unsigned_short
) return Pixel_16
is
1878 -- This conversion should not depend on the host endianess;
1879 -- therefore, we cannot use an unchecked conversion.
1884 Target
.T
:= Unsigned_1
(Bits
(Source
, 0, 0) mod 2 ** 1);
1885 Target
.R
:= Unsigned_5
(Bits
(Source
, 1, 5) mod 2 ** 5);
1886 Target
.G
:= Unsigned_5
(Bits
(Source
, 6, 10) mod 2 ** 5);
1887 Target
.B
:= Unsigned_5
(Bits
(Source
, 11, 15) mod 2 ** 5);
1891 function To_Pixel
(Source
: unsigned_int
) return Pixel_32
is
1893 -- This conversion should not depend on the host endianess;
1894 -- therefore, we cannot use an unchecked conversion.
1899 Target
.T
:= unsigned_char
(Bits
(Source
, 0, 7));
1900 Target
.R
:= unsigned_char
(Bits
(Source
, 8, 15));
1901 Target
.G
:= unsigned_char
(Bits
(Source
, 16, 23));
1902 Target
.B
:= unsigned_char
(Bits
(Source
, 24, 31));
1906 ---------------------
1907 -- To_unsigned_int --
1908 ---------------------
1910 function To_unsigned_int
(Source
: Pixel_32
) return unsigned_int
is
1912 -- This conversion should not depend on the host endianess;
1913 -- therefore, we cannot use an unchecked conversion.
1914 -- It should also be the same result, value-wise, on two hosts
1915 -- with the same endianess.
1917 Target
: unsigned_int
:= 0;
1920 -- In big endian bit ordering, Pixel_32 looks like:
1921 -- -------------------------------------
1922 -- | T | R | G | B |
1923 -- -------------------------------------
1924 -- 0 (MSB) 7 15 23 32
1926 -- Sizes of the components: (8/8/8/8)
1928 Target
:= Target
or unsigned_int
(Source
.T
);
1929 Target
:= Shift_Left
(Target
, 8);
1930 Target
:= Target
or unsigned_int
(Source
.R
);
1931 Target
:= Shift_Left
(Target
, 8);
1932 Target
:= Target
or unsigned_int
(Source
.G
);
1933 Target
:= Shift_Left
(Target
, 8);
1934 Target
:= Target
or unsigned_int
(Source
.B
);
1936 end To_unsigned_int
;
1938 -----------------------
1939 -- To_unsigned_short --
1940 -----------------------
1942 function To_unsigned_short
(Source
: Pixel_16
) return unsigned_short
is
1944 -- This conversion should not depend on the host endianess;
1945 -- therefore, we cannot use an unchecked conversion.
1946 -- It should also be the same result, value-wise, on two hosts
1947 -- with the same endianess.
1949 Target
: unsigned_short
:= 0;
1952 -- In big endian bit ordering, Pixel_16 looks like:
1953 -- -------------------------------------
1954 -- | T | R | G | B |
1955 -- -------------------------------------
1956 -- 0 (MSB) 1 5 11 15
1958 -- Sizes of the components: (1/5/5/5)
1960 Target
:= Target
or unsigned_short
(Source
.T
);
1961 Target
:= Shift_Left
(Target
, 5);
1962 Target
:= Target
or unsigned_short
(Source
.R
);
1963 Target
:= Shift_Left
(Target
, 5);
1964 Target
:= Target
or unsigned_short
(Source
.G
);
1965 Target
:= Shift_Left
(Target
, 5);
1966 Target
:= Target
or unsigned_short
(Source
.B
);
1968 end To_unsigned_short
;
1974 function abs_v16qi
(A
: LL_VSC
) return LL_VSC
is
1975 VA
: constant VSC_View
:= To_View
(A
);
1977 return To_Vector
((Values
=>
1978 LL_VSC_Operations
.abs_vxi
(VA
.Values
)));
1985 function abs_v8hi
(A
: LL_VSS
) return LL_VSS
is
1986 VA
: constant VSS_View
:= To_View
(A
);
1988 return To_Vector
((Values
=>
1989 LL_VSS_Operations
.abs_vxi
(VA
.Values
)));
1996 function abs_v4si
(A
: LL_VSI
) return LL_VSI
is
1997 VA
: constant VSI_View
:= To_View
(A
);
1999 return To_Vector
((Values
=>
2000 LL_VSI_Operations
.abs_vxi
(VA
.Values
)));
2007 function abs_v4sf
(A
: LL_VF
) return LL_VF
is
2009 VA
: constant VF_View
:= To_View
(A
);
2012 for J
in Varray_float
'Range loop
2013 D
(J
) := abs (VA
.Values
(J
));
2016 return To_Vector
((Values
=> D
));
2023 function abss_v16qi
(A
: LL_VSC
) return LL_VSC
is
2024 VA
: constant VSC_View
:= To_View
(A
);
2026 return To_Vector
((Values
=>
2027 LL_VSC_Operations
.abss_vxi
(VA
.Values
)));
2034 function abss_v8hi
(A
: LL_VSS
) return LL_VSS
is
2035 VA
: constant VSS_View
:= To_View
(A
);
2037 return To_Vector
((Values
=>
2038 LL_VSS_Operations
.abss_vxi
(VA
.Values
)));
2045 function abss_v4si
(A
: LL_VSI
) return LL_VSI
is
2046 VA
: constant VSI_View
:= To_View
(A
);
2048 return To_Vector
((Values
=>
2049 LL_VSI_Operations
.abss_vxi
(VA
.Values
)));
2056 function vaddubm
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2057 UC
: constant GNAT
.Altivec
.Low_Level_Vectors
.LL_VUC
:=
2059 VA
: constant VUC_View
:=
2061 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
2062 D
: Varray_unsigned_char
;
2065 D
:= LL_VUC_Operations
.vadduxm
(VA
.Values
, VB
.Values
);
2066 return To_LL_VSC
(To_Vector
(VUC_View
'(Values => D)));
2073 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2074 VA : constant VUS_View := To_View (To_LL_VUS (A));
2075 VB : constant VUS_View := To_View (To_LL_VUS (B));
2076 D : Varray_unsigned_short;
2079 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2080 return To_LL_VSS (To_Vector (VUS_View'(Values
=> D
)));
2087 function vadduwm
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
2088 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
2089 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
2090 D
: Varray_unsigned_int
;
2093 D
:= LL_VUI_Operations
.vadduxm
(VA
.Values
, VB
.Values
);
2094 return To_LL_VSI
(To_Vector
(VUI_View
'(Values => D)));
2101 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2102 VA : constant VF_View := To_View (A);
2103 VB : constant VF_View := To_View (B);
2107 for J in Varray_float'Range loop
2108 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2109 + NJ_Truncate (VB.Values (J)));
2112 return To_Vector (VF_View'(Values
=> D
));
2119 function vaddcuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
2120 Addition_Result
: UI64
;
2122 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
2123 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
2126 for J
in Varray_unsigned_int
'Range loop
2128 UI64
(VA
.Values
(J
)) + UI64
(VB
.Values
(J
));
2130 if Addition_Result
> UI64
(unsigned_int
'Last) then
2137 return To_LL_VSI
(To_Vector
(D
));
2144 function vaddubs
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2145 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
2146 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
2149 return To_LL_VSC
(To_Vector
2150 (VUC_View
'(Values =>
2151 (LL_VUC_Operations.vadduxs
2160 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2161 VA : constant VSC_View := To_View (A);
2162 VB : constant VSC_View := To_View (B);
2166 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2167 return To_Vector (D);
2174 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2175 VA : constant VUS_View := To_View (To_LL_VUS (A));
2176 VB : constant VUS_View := To_View (To_LL_VUS (B));
2180 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2181 return To_LL_VSS (To_Vector (D));
2188 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2189 VA : constant VSS_View := To_View (A);
2190 VB : constant VSS_View := To_View (B);
2194 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2195 return To_Vector (D);
2202 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2203 VA : constant VUI_View := To_View (To_LL_VUI (A));
2204 VB : constant VUI_View := To_View (To_LL_VUI (B));
2208 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2209 return To_LL_VSI (To_Vector (D));
2216 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2217 VA : constant VSI_View := To_View (A);
2218 VB : constant VSI_View := To_View (B);
2222 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2223 return To_Vector (D);
2230 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2231 VA : constant VUI_View := To_View (To_LL_VUI (A));
2232 VB : constant VUI_View := To_View (To_LL_VUI (B));
2236 for J in Varray_unsigned_int'Range loop
2237 D.Values (J) := VA.Values (J) and VB.Values (J);
2240 return To_LL_VSI (To_Vector (D));
2247 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2248 VA : constant VUI_View := To_View (To_LL_VUI (A));
2249 VB : constant VUI_View := To_View (To_LL_VUI (B));
2253 for J in Varray_unsigned_int'Range loop
2254 D.Values (J) := VA.Values (J) and not VB.Values (J);
2257 return To_LL_VSI (To_Vector (D));
2264 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2265 VA : constant VUC_View := To_View (To_LL_VUC (A));
2266 VB : constant VUC_View := To_View (To_LL_VUC (B));
2270 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2271 return To_LL_VSC (To_Vector (D));
2278 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2279 VA : constant VSC_View := To_View (A);
2280 VB : constant VSC_View := To_View (B);
2284 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2285 return To_Vector (D);
2292 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2293 VA : constant VUS_View := To_View (To_LL_VUS (A));
2294 VB : constant VUS_View := To_View (To_LL_VUS (B));
2298 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2299 return To_LL_VSS (To_Vector (D));
2306 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2307 VA : constant VSS_View := To_View (A);
2308 VB : constant VSS_View := To_View (B);
2312 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2313 return To_Vector (D);
2320 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2321 VA : constant VUI_View := To_View (To_LL_VUI (A));
2322 VB : constant VUI_View := To_View (To_LL_VUI (B));
2326 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2327 return To_LL_VSI (To_Vector (D));
2334 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2335 VA : constant VSI_View := To_View (A);
2336 VB : constant VSI_View := To_View (B);
2340 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2341 return To_Vector (D);
2348 function vrfip (A : LL_VF) return LL_VF is
2349 VA : constant VF_View := To_View (A);
2353 for J in Varray_float'Range loop
2355 -- If A (J) is infinite, D (J) should be infinite; With
2356 -- IEEE floating points, we can use 'Ceiling
for that purpose
.
2358 D
.Values
(J
) := C_float
'Ceiling (NJ_Truncate
(VA
.Values
(J
)));
2362 return To_Vector
(D
);
2369 function vcmpbfp
(A
: LL_VF
; B
: LL_VF
) return LL_VSI
is
2370 VA
: constant VF_View
:= To_View
(A
);
2371 VB
: constant VF_View
:= To_View
(B
);
2376 for J
in Varray_float
'Range loop
2377 K
:= Vint_Range
(J
);
2380 if NJ_Truncate
(VB
.Values
(J
)) < 0.0 then
2382 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2383 -- word element in B is negative; the corresponding element in A
2384 -- is out of bounds.
2386 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 0, 1);
2387 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 1, 1);
2390 if NJ_Truncate
(VA
.Values
(J
))
2391 <= NJ_Truncate
(VB
.Values
(J
)) then
2392 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 0, 0);
2394 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 0, 1);
2397 if NJ_Truncate
(VA
.Values
(J
))
2398 >= -NJ_Truncate
(VB
.Values
(J
)) then
2399 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 1, 0);
2401 D
.Values
(K
) := Write_Bit
(D
.Values
(K
), 1, 1);
2406 return To_LL_VSI
(To_Vector
(D
));
2413 function vcmpequb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2414 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
2415 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
2419 D
.Values
:= LL_VUC_Operations
.vcmpequx
(VA
.Values
, VB
.Values
);
2420 return To_LL_VSC
(To_Vector
(D
));
2427 function vcmpequh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
2428 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
2429 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
2432 D
.Values
:= LL_VUS_Operations
.vcmpequx
(VA
.Values
, VB
.Values
);
2433 return To_LL_VSS
(To_Vector
(D
));
2440 function vcmpequw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
2441 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
2442 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
2445 D
.Values
:= LL_VUI_Operations
.vcmpequx
(VA
.Values
, VB
.Values
);
2446 return To_LL_VSI
(To_Vector
(D
));
2453 function vcmpeqfp
(A
: LL_VF
; B
: LL_VF
) return LL_VSI
is
2454 VA
: constant VF_View
:= To_View
(A
);
2455 VB
: constant VF_View
:= To_View
(B
);
2460 for J
in Varray_float
'Range loop
2461 K
:= Vint_Range
(J
);
2463 if VA
.Values
(J
) = VB
.Values
(J
) then
2464 D
.Values
(K
) := unsigned_int
'Last;
2470 return To_LL_VSI
(To_Vector
(D
));
2477 function vcmpgefp
(A
: LL_VF
; B
: LL_VF
) return LL_VSI
is
2478 VA
: constant VF_View
:= To_View
(A
);
2479 VB
: constant VF_View
:= To_View
(B
);
2484 for J
in Varray_float
'Range loop
2485 K
:= Vint_Range
(J
);
2487 if VA
.Values
(J
) >= VB
.Values
(J
) then
2488 D
.Values
(K
) := Signed_Bool_True
;
2490 D
.Values
(K
) := Signed_Bool_False
;
2494 return To_Vector
(D
);
2501 function vcmpgtub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2502 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
2503 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
2506 D
.Values
:= LL_VUC_Operations
.vcmpgtux
(VA
.Values
, VB
.Values
);
2507 return To_LL_VSC
(To_Vector
(D
));
2514 function vcmpgtsb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2515 VA
: constant VSC_View
:= To_View
(A
);
2516 VB
: constant VSC_View
:= To_View
(B
);
2519 D
.Values
:= LL_VSC_Operations
.vcmpgtsx
(VA
.Values
, VB
.Values
);
2520 return To_Vector
(D
);
2527 function vcmpgtuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
2528 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
2529 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
2532 D
.Values
:= LL_VUS_Operations
.vcmpgtux
(VA
.Values
, VB
.Values
);
2533 return To_LL_VSS
(To_Vector
(D
));
2540 function vcmpgtsh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
2541 VA
: constant VSS_View
:= To_View
(A
);
2542 VB
: constant VSS_View
:= To_View
(B
);
2545 D
.Values
:= LL_VSS_Operations
.vcmpgtsx
(VA
.Values
, VB
.Values
);
2546 return To_Vector
(D
);
2553 function vcmpgtuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
2554 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
2555 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
2558 D
.Values
:= LL_VUI_Operations
.vcmpgtux
(VA
.Values
, VB
.Values
);
2559 return To_LL_VSI
(To_Vector
(D
));
2566 function vcmpgtsw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
2567 VA
: constant VSI_View
:= To_View
(A
);
2568 VB
: constant VSI_View
:= To_View
(B
);
2571 D
.Values
:= LL_VSI_Operations
.vcmpgtsx
(VA
.Values
, VB
.Values
);
2572 return To_Vector
(D
);
2579 function vcmpgtfp
(A
: LL_VF
; B
: LL_VF
) return LL_VSI
is
2580 VA
: constant VF_View
:= To_View
(A
);
2581 VB
: constant VF_View
:= To_View
(B
);
2586 for J
in Varray_float
'Range loop
2587 K
:= Vint_Range
(J
);
2589 if NJ_Truncate
(VA
.Values
(J
))
2590 > NJ_Truncate
(VB
.Values
(J
)) then
2591 D
.Values
(K
) := Signed_Bool_True
;
2593 D
.Values
(K
) := Signed_Bool_False
;
2597 return To_Vector
(D
);
2604 function vcfux
(A
: LL_VSI
; B
: c_int
) return LL_VF
is
2606 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
2610 for J
in Varray_signed_int
'Range loop
2611 K
:= Vfloat_Range
(J
);
2613 -- Note: The conversion to Integer is safe, as Integers are required
2614 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2615 -- include the range of B (should be 0 .. 255).
2618 C_float
(VA
.Values
(J
)) / (2.0 ** Integer (B
));
2621 return To_Vector
(D
);
2628 function vcfsx
(A
: LL_VSI
; B
: c_int
) return LL_VF
is
2629 VA
: constant VSI_View
:= To_View
(A
);
2634 for J
in Varray_signed_int
'Range loop
2635 K
:= Vfloat_Range
(J
);
2636 D
.Values
(K
) := C_float
(VA
.Values
(J
))
2637 / (2.0 ** Integer (B
));
2640 return To_Vector
(D
);
2647 function vctsxs
(A
: LL_VF
; B
: c_int
) return LL_VSI
is
2648 VA
: constant VF_View
:= To_View
(A
);
2653 for J
in Varray_signed_int
'Range loop
2654 K
:= Vfloat_Range
(J
);
2656 LL_VSI_Operations
.Saturate
2657 (F64
(NJ_Truncate
(VA
.Values
(K
)))
2658 * F64
(2.0 ** Integer (B
)));
2661 return To_Vector
(D
);
2668 function vctuxs
(A
: LL_VF
; B
: c_int
) return LL_VSI
is
2669 VA
: constant VF_View
:= To_View
(A
);
2674 for J
in Varray_unsigned_int
'Range loop
2675 K
:= Vfloat_Range
(J
);
2677 LL_VUI_Operations
.Saturate
2678 (F64
(NJ_Truncate
(VA
.Values
(K
)))
2679 * F64
(2.0 ** Integer (B
)));
2682 return To_LL_VSI
(To_Vector
(D
));
2689 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2691 procedure dss
(A
: c_int
) is
2692 pragma Unreferenced
(A
);
2701 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2712 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2714 procedure dst
(A
: c_ptr
; B
: c_int
; C
: c_int
) is
2715 pragma Unreferenced
(A
);
2716 pragma Unreferenced
(B
);
2717 pragma Unreferenced
(C
);
2726 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2728 procedure dstst
(A
: c_ptr
; B
: c_int
; C
: c_int
) is
2729 pragma Unreferenced
(A
);
2730 pragma Unreferenced
(B
);
2731 pragma Unreferenced
(C
);
2740 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2742 procedure dststt
(A
: c_ptr
; B
: c_int
; C
: c_int
) is
2743 pragma Unreferenced
(A
);
2744 pragma Unreferenced
(B
);
2745 pragma Unreferenced
(C
);
2754 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2756 procedure dstt
(A
: c_ptr
; B
: c_int
; C
: c_int
) is
2757 pragma Unreferenced
(A
);
2758 pragma Unreferenced
(B
);
2759 pragma Unreferenced
(C
);
2768 function vexptefp
(A
: LL_VF
) return LL_VF
is
2769 use C_float_Operations
;
2771 VA
: constant VF_View
:= To_View
(A
);
2775 for J
in Varray_float
'Range loop
2777 -- ??? Check the precision of the operation.
2778 -- As described in [PEM-6 vexptefp]:
2779 -- If theorical_result is equal to 2 at the power of A (J) with
2780 -- infinite precision, we should have:
2781 -- abs ((D (J) - theorical_result) / theorical_result) <= 1/16
2783 D
.Values
(J
) := 2.0 ** NJ_Truncate
(VA
.Values
(J
));
2786 return To_Vector
(D
);
2793 function vrfim
(A
: LL_VF
) return LL_VF
is
2794 VA
: constant VF_View
:= To_View
(A
);
2798 for J
in Varray_float
'Range loop
2800 -- If A (J) is infinite, D (J) should be infinite; With
2801 -- IEEE floating point, we can use 'Ceiling for that purpose.
2803 D
.Values
(J
) := C_float
'Ceiling (NJ_Truncate
(VA
.Values
(J
)));
2805 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2808 if D
.Values
(J
) /= VA
.Values
(J
) then
2809 D
.Values
(J
) := D
.Values
(J
) - 1.0;
2813 return To_Vector
(D
);
2820 function lvx
(A
: c_long
; B
: c_ptr
) return LL_VSI
is
2821 EA
: Integer_Address
;
2824 EA
:= Bound_Align
(Integer_Address
(A
) + To_Integer
(B
), 16);
2828 for D
'Address use To_Address
(EA
);
2838 function lvebx
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2841 D
.Values
:= LL_VSC_Operations
.lvexx
(A
, B
);
2842 return To_Vector
(D
);
2849 function lvehx
(A
: c_long
; B
: c_ptr
) return LL_VSS
is
2852 D
.Values
:= LL_VSS_Operations
.lvexx
(A
, B
);
2853 return To_Vector
(D
);
2860 function lvewx
(A
: c_long
; B
: c_ptr
) return LL_VSI
is
2863 D
.Values
:= LL_VSI_Operations
.lvexx
(A
, B
);
2864 return To_Vector
(D
);
2871 function lvxl
(A
: c_long
; B
: c_ptr
) return LL_VSI
renames
2878 function vlogefp
(A
: LL_VF
) return LL_VF
is
2879 VA
: constant VF_View
:= To_View
(A
);
2883 for J
in Varray_float
'Range loop
2885 -- ??? Check the precision of the operation.
2886 -- As described in [PEM-6 vlogefp]:
2887 -- If theorical_result is equal to the log2 of A (J) with
2888 -- infinite precision, we should have:
2889 -- abs (D (J) - theorical_result) <= 1/32,
2890 -- unless abs(D(J) - 1) <= 1/8.
2893 C_float_Operations
.Log
(NJ_Truncate
(VA
.Values
(J
)), 2.0);
2896 return To_Vector
(D
);
2903 function lvsl
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2904 type bit4_type
is mod 16#F#
+ 1;
2905 for bit4_type
'Alignment use 1;
2906 EA
: Integer_Address
;
2911 EA
:= Integer_Address
(A
) + To_Integer
(B
);
2912 SH
:= bit4_type
(EA
mod 2 ** 4);
2914 for J
in D
.Values
'Range loop
2915 D
.Values
(J
) := unsigned_char
(SH
) + unsigned_char
(J
)
2916 - unsigned_char
(D
.Values
'First);
2919 return To_LL_VSC
(To_Vector
(D
));
2926 function lvsr
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2927 type bit4_type
is mod 16#F#
+ 1;
2928 for bit4_type
'Alignment use 1;
2929 EA
: Integer_Address
;
2934 EA
:= Integer_Address
(A
) + To_Integer
(B
);
2935 SH
:= bit4_type
(EA
mod 2 ** 4);
2937 for J
in D
.Values
'Range loop
2938 D
.Values
(J
) := (16#F#
- unsigned_char
(SH
)) + unsigned_char
(J
);
2941 return To_LL_VSC
(To_Vector
(D
));
2948 function vmaddfp
(A
: LL_VF
; B
: LL_VF
; C
: LL_VF
) return LL_VF
is
2949 VA
: constant VF_View
:= To_View
(A
);
2950 VB
: constant VF_View
:= To_View
(B
);
2951 VC
: constant VF_View
:= To_View
(C
);
2955 for J
in Varray_float
'Range loop
2957 Rnd_To_FP_Nearest
(F64
(VA
.Values
(J
))
2958 * F64
(VB
.Values
(J
))
2959 + F64
(VC
.Values
(J
)));
2962 return To_Vector
(D
);
2969 function vmhaddshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
2970 VA
: constant VSS_View
:= To_View
(A
);
2971 VB
: constant VSS_View
:= To_View
(B
);
2972 VC
: constant VSS_View
:= To_View
(C
);
2976 for J
in Varray_signed_short
'Range loop
2977 D
.Values
(J
) := LL_VSS_Operations
.Saturate
2978 ((SI64
(VA
.Values
(J
)) * SI64
(VB
.Values
(J
)))
2979 / SI64
(2 ** 15) + SI64
(VC
.Values
(J
)));
2982 return To_Vector
(D
);
2989 function vmaxub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
2990 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
2991 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
2994 D
.Values
:= LL_VUC_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
2995 return To_LL_VSC
(To_Vector
(D
));
3002 function vmaxsb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3003 VA
: constant VSC_View
:= To_View
(A
);
3004 VB
: constant VSC_View
:= To_View
(B
);
3007 D
.Values
:= LL_VSC_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3008 return To_Vector
(D
);
3015 function vmaxuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3016 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3017 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3020 D
.Values
:= LL_VUS_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
3021 return To_LL_VSS
(To_Vector
(D
));
3028 function vmaxsh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3029 VA
: constant VSS_View
:= To_View
(A
);
3030 VB
: constant VSS_View
:= To_View
(B
);
3033 D
.Values
:= LL_VSS_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3034 return To_Vector
(D
);
3041 function vmaxuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3042 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3043 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3046 D
.Values
:= LL_VUI_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
3047 return To_LL_VSI
(To_Vector
(D
));
3054 function vmaxsw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3055 VA
: constant VSI_View
:= To_View
(A
);
3056 VB
: constant VSI_View
:= To_View
(B
);
3059 D
.Values
:= LL_VSI_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3060 return To_Vector
(D
);
3067 function vmaxfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
3068 VA
: constant VF_View
:= To_View
(A
);
3069 VB
: constant VF_View
:= To_View
(B
);
3073 for J
in Varray_float
'Range loop
3074 if VA
.Values
(J
) > VB
.Values
(J
) then
3075 D
.Values
(J
) := VA
.Values
(J
);
3077 D
.Values
(J
) := VB
.Values
(J
);
3081 return To_Vector
(D
);
3088 function vmrghb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3089 VA
: constant VSC_View
:= To_View
(A
);
3090 VB
: constant VSC_View
:= To_View
(B
);
3093 D
.Values
:= LL_VSC_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3094 return To_Vector
(D
);
3101 function vmrghh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3102 VA
: constant VSS_View
:= To_View
(A
);
3103 VB
: constant VSS_View
:= To_View
(B
);
3106 D
.Values
:= LL_VSS_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3107 return To_Vector
(D
);
3114 function vmrghw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3115 VA
: constant VSI_View
:= To_View
(A
);
3116 VB
: constant VSI_View
:= To_View
(B
);
3119 D
.Values
:= LL_VSI_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3120 return To_Vector
(D
);
3127 function vmrglb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3128 VA
: constant VSC_View
:= To_View
(A
);
3129 VB
: constant VSC_View
:= To_View
(B
);
3132 D
.Values
:= LL_VSC_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3133 return To_Vector
(D
);
3140 function vmrglh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3141 VA
: constant VSS_View
:= To_View
(A
);
3142 VB
: constant VSS_View
:= To_View
(B
);
3145 D
.Values
:= LL_VSS_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3146 return To_Vector
(D
);
3153 function vmrglw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3154 VA
: constant VSI_View
:= To_View
(A
);
3155 VB
: constant VSI_View
:= To_View
(B
);
3158 D
.Values
:= LL_VSI_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3159 return To_Vector
(D
);
3166 function mfvscr
return LL_VSS
is
3169 for J
in Varray_unsigned_short
'Range loop
3173 D
.Values
(Varray_unsigned_short
'Last) :=
3174 unsigned_short
(VSCR
mod 2 ** unsigned_short
'Size);
3175 D
.Values
(Varray_unsigned_short
'Last - 1) :=
3176 unsigned_short
(VSCR
/ 2 ** unsigned_short
'Size);
3177 return To_LL_VSS
(To_Vector
(D
));
3184 function vminfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
3185 VA
: constant VF_View
:= To_View
(A
);
3186 VB
: constant VF_View
:= To_View
(B
);
3190 for J
in Varray_float
'Range loop
3191 if VA
.Values
(J
) < VB
.Values
(J
) then
3192 D
.Values
(J
) := VA
.Values
(J
);
3194 D
.Values
(J
) := VB
.Values
(J
);
3198 return To_Vector
(D
);
3205 function vminsb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3206 VA
: constant VSC_View
:= To_View
(A
);
3207 VB
: constant VSC_View
:= To_View
(B
);
3210 D
.Values
:= LL_VSC_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3211 return To_Vector
(D
);
3218 function vminub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3219 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3220 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3223 D
.Values
:= LL_VUC_Operations
.vminux
(VA
.Values
, VB
.Values
);
3224 return To_LL_VSC
(To_Vector
(D
));
3231 function vminsh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3232 VA
: constant VSS_View
:= To_View
(A
);
3233 VB
: constant VSS_View
:= To_View
(B
);
3236 D
.Values
:= LL_VSS_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3237 return To_Vector
(D
);
3244 function vminuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3245 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3246 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3249 D
.Values
:= LL_VUS_Operations
.vminux
(VA
.Values
, VB
.Values
);
3250 return To_LL_VSS
(To_Vector
(D
));
3257 function vminsw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3258 VA
: constant VSI_View
:= To_View
(A
);
3259 VB
: constant VSI_View
:= To_View
(B
);
3262 D
.Values
:= LL_VSI_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3263 return To_Vector
(D
);
3270 function vminuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3271 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3272 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3275 D
.Values
:= LL_VUI_Operations
.vminux
(VA
.Values
,
3277 return To_LL_VSI
(To_Vector
(D
));
3284 function vmladduhm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
3285 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3286 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3287 VC
: constant VUS_View
:= To_View
(To_LL_VUS
(C
));
3291 for J
in Varray_unsigned_short
'Range loop
3292 D
.Values
(J
) := VA
.Values
(J
) * VB
.Values
(J
)
3296 return To_LL_VSS
(To_Vector
(D
));
3303 function vmhraddshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
3304 VA
: constant VSS_View
:= To_View
(A
);
3305 VB
: constant VSS_View
:= To_View
(B
);
3306 VC
: constant VSS_View
:= To_View
(C
);
3310 for J
in Varray_signed_short
'Range loop
3312 LL_VSS_Operations
.Saturate
(((SI64
(VA
.Values
(J
))
3313 * SI64
(VB
.Values
(J
))
3316 + SI64
(VC
.Values
(J
))));
3319 return To_Vector
(D
);
3326 function vmsumubm
(A
: LL_VSC
; B
: LL_VSC
; C
: LL_VSI
) return LL_VSI
is
3327 Offset
: Vchar_Range
;
3328 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3329 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3330 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3334 for J
in 0 .. 3 loop
3335 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
3336 D
.Values
(Vint_Range
3337 (J
+ Integer (Vint_Range
'First))) :=
3338 (unsigned_int
(VA
.Values
(Offset
))
3339 * unsigned_int
(VB
.Values
(Offset
)))
3340 + (unsigned_int
(VA
.Values
(Offset
+ 1))
3341 * unsigned_int
(VB
.Values
(1 + Offset
)))
3342 + (unsigned_int
(VA
.Values
(2 + Offset
))
3343 * unsigned_int
(VB
.Values
(2 + Offset
)))
3344 + (unsigned_int
(VA
.Values
(3 + Offset
))
3345 * unsigned_int
(VB
.Values
(3 + Offset
)))
3346 + VC
.Values
(Vint_Range
3347 (J
+ Integer (Varray_unsigned_int
'First)));
3350 return To_LL_VSI
(To_Vector
(D
));
3357 function vmsummbm
(A
: LL_VSC
; B
: LL_VSC
; C
: LL_VSI
) return LL_VSI
is
3358 Offset
: Vchar_Range
;
3359 VA
: constant VSC_View
:= To_View
(A
);
3360 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3361 VC
: constant VSI_View
:= To_View
(C
);
3365 for J
in 0 .. 3 loop
3366 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
3367 D
.Values
(Vint_Range
3368 (J
+ Integer (Varray_unsigned_int
'First))) := 0
3369 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
))
3370 * SI64
(VB
.Values
(Offset
)))
3371 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
+ 1))
3374 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(2 + Offset
))
3377 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(3 + Offset
))
3380 + VC
.Values
(Vint_Range
3381 (J
+ Integer (Varray_unsigned_int
'First)));
3384 return To_Vector
(D
);
3391 function vmsumuhm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3392 Offset
: Vshort_Range
;
3393 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3394 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3395 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3399 for J
in 0 .. 3 loop
3401 Vshort_Range
(2 * J
+ Integer (Vshort_Range
'First));
3402 D
.Values
(Vint_Range
3403 (J
+ Integer (Varray_unsigned_int
'First))) :=
3404 (unsigned_int
(VA
.Values
(Offset
))
3405 * unsigned_int
(VB
.Values
(Offset
)))
3406 + (unsigned_int
(VA
.Values
(Offset
+ 1))
3407 * unsigned_int
(VB
.Values
(1 + Offset
)))
3408 + VC
.Values
(Vint_Range
3409 (J
+ Integer (Vint_Range
'First)));
3412 return To_LL_VSI
(To_Vector
(D
));
3419 function vmsumshm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3420 VA
: constant VSS_View
:= To_View
(A
);
3421 VB
: constant VSS_View
:= To_View
(B
);
3422 VC
: constant VSI_View
:= To_View
(C
);
3423 Offset
: Vshort_Range
;
3427 for J
in 0 .. 3 loop
3429 Vshort_Range
(2 * J
+ Integer (Varray_signed_char
'First));
3430 D
.Values
(Vint_Range
3431 (J
+ Integer (Varray_unsigned_int
'First))) := 0
3432 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
))
3433 * SI64
(VB
.Values
(Offset
)))
3434 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
+ 1))
3437 + VC
.Values
(Vint_Range
3438 (J
+ Integer (Varray_unsigned_int
'First)));
3441 return To_Vector
(D
);
3448 function vmsumuhs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3449 Offset
: Vshort_Range
;
3450 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3451 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3452 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3456 for J
in 0 .. 3 loop
3458 Vshort_Range
(2 * J
+ Integer (Varray_signed_short
'First));
3459 D
.Values
(Vint_Range
3460 (J
+ Integer (Varray_unsigned_int
'First))) :=
3461 LL_VUI_Operations
.Saturate
3462 (UI64
(VA
.Values
(Offset
))
3463 * UI64
(VB
.Values
(Offset
))
3464 + UI64
(VA
.Values
(Offset
+ 1))
3465 * UI64
(VB
.Values
(1 + Offset
))
3468 (J
+ Integer (Varray_unsigned_int
'First)))));
3471 return To_LL_VSI
(To_Vector
(D
));
3478 function vmsumshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3479 VA
: constant VSS_View
:= To_View
(A
);
3480 VB
: constant VSS_View
:= To_View
(B
);
3481 VC
: constant VSI_View
:= To_View
(C
);
3482 Offset
: Vshort_Range
;
3486 for J
in 0 .. 3 loop
3488 Vshort_Range
(2 * J
+ Integer (Varray_signed_short
'First));
3489 D
.Values
(Vint_Range
3490 (J
+ Integer (Varray_signed_int
'First))) :=
3491 LL_VSI_Operations
.Saturate
3492 (SI64
(VA
.Values
(Offset
))
3493 * SI64
(VB
.Values
(Offset
))
3494 + SI64
(VA
.Values
(Offset
+ 1))
3495 * SI64
(VB
.Values
(1 + Offset
))
3498 (J
+ Integer (Varray_signed_int
'First)))));
3501 return To_Vector
(D
);
3508 procedure mtvscr
(A
: LL_VSI
) is
3509 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3511 VSCR
:= VA
.Values
(Varray_unsigned_int
'Last);
3518 function vmuleub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3519 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3520 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3523 D
.Values
:= LL_VUC_LL_VUS_Operations
.vmulxux
(True,
3526 return To_LL_VSS
(To_Vector
(D
));
3533 function vmuleuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3534 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3535 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3538 D
.Values
:= LL_VUS_LL_VUI_Operations
.vmulxux
(True,
3541 return To_LL_VSI
(To_Vector
(D
));
3548 function vmulesb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3549 VA
: constant VSC_View
:= To_View
(A
);
3550 VB
: constant VSC_View
:= To_View
(B
);
3553 D
.Values
:= LL_VSC_LL_VSS_Operations
.vmulxsx
(True,
3556 return To_Vector
(D
);
3563 function vmulesh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3564 VA
: constant VSS_View
:= To_View
(A
);
3565 VB
: constant VSS_View
:= To_View
(B
);
3568 D
.Values
:= LL_VSS_LL_VSI_Operations
.vmulxsx
(True,
3571 return To_Vector
(D
);
3578 function vmuloub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3579 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3580 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3583 D
.Values
:= LL_VUC_LL_VUS_Operations
.vmulxux
(False,
3586 return To_LL_VSS
(To_Vector
(D
));
3593 function vmulouh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3594 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3595 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3599 LL_VUS_LL_VUI_Operations
.vmulxux
(False, VA
.Values
, VB
.Values
);
3600 return To_LL_VSI
(To_Vector
(D
));
3607 function vmulosb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3608 VA
: constant VSC_View
:= To_View
(A
);
3609 VB
: constant VSC_View
:= To_View
(B
);
3612 D
.Values
:= LL_VSC_LL_VSS_Operations
.vmulxsx
(False,
3615 return To_Vector
(D
);
3622 function vmulosh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3623 VA
: constant VSS_View
:= To_View
(A
);
3624 VB
: constant VSS_View
:= To_View
(B
);
3627 D
.Values
:= LL_VSS_LL_VSI_Operations
.vmulxsx
(False,
3630 return To_Vector
(D
);
3637 function vnmsubfp
(A
: LL_VF
; B
: LL_VF
; C
: LL_VF
) return LL_VF
is
3638 VA
: constant VF_View
:= To_View
(A
);
3639 VB
: constant VF_View
:= To_View
(B
);
3640 VC
: constant VF_View
:= To_View
(C
);
3644 for J
in Vfloat_Range
'Range loop
3646 -Rnd_To_FP_Nearest
(F64
(VA
.Values
(J
))
3647 * F64
(VB
.Values
(J
))
3648 - F64
(VC
.Values
(J
)));
3651 return To_Vector
(D
);
3658 function vnor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3659 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3660 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3664 for J
in Vint_Range
'Range loop
3665 D
.Values
(J
) := not (VA
.Values
(J
) or VB
.Values
(J
));
3668 return To_LL_VSI
(To_Vector
(D
));
3675 function vor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3676 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3677 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3681 for J
in Vint_Range
'Range loop
3682 D
.Values
(J
) := VA
.Values
(J
) or VB
.Values
(J
);
3685 return To_LL_VSI
(To_Vector
(D
));
3692 function vpkuhum
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3693 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3694 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3697 D
.Values
:= LL_VUC_LL_VUS_Operations
.vpkuxum
(VA
.Values
, VB
.Values
);
3698 return To_LL_VSC
(To_Vector
(D
));
3705 function vpkuwum
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3706 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3707 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3710 D
.Values
:= LL_VUS_LL_VUI_Operations
.vpkuxum
(VA
.Values
, VB
.Values
);
3711 return To_LL_VSS
(To_Vector
(D
));
3718 function vpkpx
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3719 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3720 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3722 Offset
: Vint_Range
;
3727 for J
in 0 .. 3 loop
3728 Offset
:= Vint_Range
(J
+ Integer (Vshort_Range
'First));
3729 P32
:= To_Pixel
(VA
.Values
(Offset
));
3730 P16
.T
:= Unsigned_1
(P32
.T
mod 2 ** 1);
3731 P16
.R
:= Unsigned_5
(Shift_Right
(P32
.R
, 3) mod 2 ** 5);
3732 P16
.G
:= Unsigned_5
(Shift_Right
(P32
.G
, 3) mod 2 ** 5);
3733 P16
.B
:= Unsigned_5
(Shift_Right
(P32
.B
, 3) mod 2 ** 5);
3734 D
.Values
(Vshort_Range
(Offset
)) := To_unsigned_short
(P16
);
3735 P32
:= To_Pixel
(VB
.Values
(Offset
));
3736 P16
.T
:= Unsigned_1
(P32
.T
mod 2 ** 1);
3737 P16
.R
:= Unsigned_5
(Shift_Right
(P32
.R
, 3) mod 2 ** 5);
3738 P16
.G
:= Unsigned_5
(Shift_Right
(P32
.G
, 3) mod 2 ** 5);
3739 P16
.B
:= Unsigned_5
(Shift_Right
(P32
.B
, 3) mod 2 ** 5);
3740 D
.Values
(Vshort_Range
(Offset
) + 4) := To_unsigned_short
(P16
);
3743 return To_LL_VSS
(To_Vector
(D
));
3750 function vpkuhus
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3751 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3752 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3755 D
.Values
:= LL_VUC_LL_VUS_Operations
.vpkuxus
(VA
.Values
, VB
.Values
);
3756 return To_LL_VSC
(To_Vector
(D
));
3763 function vpkuwus
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3764 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3765 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3768 D
.Values
:= LL_VUS_LL_VUI_Operations
.vpkuxus
(VA
.Values
, VB
.Values
);
3769 return To_LL_VSS
(To_Vector
(D
));
3776 function vpkshss
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3777 VA
: constant VSS_View
:= To_View
(A
);
3778 VB
: constant VSS_View
:= To_View
(B
);
3781 D
.Values
:= LL_VSC_LL_VSS_Operations
.vpksxss
(VA
.Values
, VB
.Values
);
3782 return To_Vector
(D
);
3789 function vpkswss
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3790 VA
: constant VSI_View
:= To_View
(A
);
3791 VB
: constant VSI_View
:= To_View
(B
);
3794 D
.Values
:= LL_VSS_LL_VSI_Operations
.vpksxss
(VA
.Values
, VB
.Values
);
3795 return To_Vector
(D
);
3803 type Signed_Component_Type
is range <>;
3804 type Signed_Index_Type
is range <>;
3805 type Signed_Varray_Type
is
3806 array (Signed_Index_Type
) of Signed_Component_Type
;
3807 type Unsigned_Component_Type
is mod <>;
3808 type Unsigned_Index_Type
is range <>;
3809 type Unsigned_Varray_Type
is
3810 array (Unsigned_Index_Type
) of Unsigned_Component_Type
;
3813 (A
: Signed_Varray_Type
;
3814 B
: Signed_Varray_Type
) return Unsigned_Varray_Type
;
3817 (A
: Signed_Varray_Type
;
3818 B
: Signed_Varray_Type
) return Unsigned_Varray_Type
3820 N
: constant Unsigned_Index_Type
:=
3821 Unsigned_Index_Type
(Signed_Index_Type
'Last);
3822 Offset
: Unsigned_Index_Type
;
3823 Signed_Offset
: Signed_Index_Type
;
3824 D
: Unsigned_Varray_Type
;
3827 (X
: Signed_Component_Type
) return Unsigned_Component_Type
;
3828 -- Saturation, as defined in
3829 -- [PIM-4.1 Vector Status and Control Register]
3836 (X
: Signed_Component_Type
) return Unsigned_Component_Type
3838 D
: Unsigned_Component_Type
;
3841 D
:= Unsigned_Component_Type
3842 (Signed_Component_Type
'Max
3843 (Signed_Component_Type
(Unsigned_Component_Type
'First),
3844 Signed_Component_Type
'Min
3845 (Signed_Component_Type
(Unsigned_Component_Type
'Last),
3847 if Signed_Component_Type
(D
) /= X
then
3848 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
3854 -- Start of processing for vpksxus
3857 for J
in 0 .. N
- 1 loop
3859 Unsigned_Index_Type
(Integer (J
)
3860 + Integer (Unsigned_Index_Type
'First));
3862 Signed_Index_Type
(Integer (J
)
3863 + Integer (Signed_Index_Type
'First));
3864 D
(Offset
) := Saturate
(A
(Signed_Offset
));
3865 D
(Offset
+ N
) := Saturate
(B
(Signed_Offset
));
3875 function vpkshus
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3876 function vpkshus_Instance
is
3877 new vpksxus
(signed_short
,
3879 Varray_signed_short
,
3882 Varray_unsigned_char
);
3884 VA
: constant VSS_View
:= To_View
(A
);
3885 VB
: constant VSS_View
:= To_View
(B
);
3889 D
.Values
:= vpkshus_Instance
(VA
.Values
, VB
.Values
);
3890 return To_LL_VSC
(To_Vector
(D
));
3897 function vpkswus
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3898 function vpkswus_Instance
is
3899 new vpksxus
(signed_int
,
3904 Varray_unsigned_short
);
3906 VA
: constant VSI_View
:= To_View
(A
);
3907 VB
: constant VSI_View
:= To_View
(B
);
3910 D
.Values
:= vpkswus_Instance
(VA
.Values
, VB
.Values
);
3911 return To_LL_VSS
(To_Vector
(D
));
3918 function vperm_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: LL_VSC
) return LL_VSI
is
3919 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3920 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3921 VC
: constant VUC_View
:= To_View
(To_LL_VUC
(C
));
3926 for N
in Vchar_Range
'Range loop
3927 J
:= Vchar_Range
(Integer (Bits
(VC
.Values
(N
), 4, 7))
3928 + Integer (Vchar_Range
'First));
3930 if Bits
(VC
.Values
(N
), 3, 3) = 0 then
3931 D
.Values
(N
) := VA
.Values
(J
);
3933 D
.Values
(N
) := VB
.Values
(J
);
3937 return To_LL_VSI
(To_Vector
(D
));
3944 function vrefp
(A
: LL_VF
) return LL_VF
is
3945 VA
: constant VF_View
:= To_View
(A
);
3949 for J
in Vfloat_Range
'Range loop
3950 D
.Values
(J
) := FP_Recip_Est
(VA
.Values
(J
));
3953 return To_Vector
(D
);
3960 function vrlb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3961 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3962 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3965 D
.Values
:= LL_VUC_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
3966 return To_LL_VSC
(To_Vector
(D
));
3973 function vrlh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3974 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3975 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3978 D
.Values
:= LL_VUS_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
3979 return To_LL_VSS
(To_Vector
(D
));
3986 function vrlw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3987 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3988 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3991 D
.Values
:= LL_VUI_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
3992 return To_LL_VSI
(To_Vector
(D
));
3999 function vrfin
(A
: LL_VF
) return LL_VF
is
4000 VA
: constant VF_View
:= To_View
(A
);
4004 for J
in Vfloat_Range
'Range loop
4005 D
.Values
(J
) := C_float
(Rnd_To_FPI_Near
(F64
(VA
.Values
(J
))));
4008 return To_Vector
(D
);
4015 function vrsqrtefp
(A
: LL_VF
) return LL_VF
is
4016 VA
: constant VF_View
:= To_View
(A
);
4020 for J
in Vfloat_Range
'Range loop
4021 D
.Values
(J
) := Recip_SQRT_Est
(VA
.Values
(J
));
4024 return To_Vector
(D
);
4031 function vsel_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: LL_VSI
) return LL_VSI
is
4032 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4033 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4034 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
4038 for J
in Vint_Range
'Range loop
4039 D
.Values
(J
) := ((not VC
.Values
(J
)) and VA
.Values
(J
))
4040 or (VC
.Values
(J
) and VB
.Values
(J
));
4043 return To_LL_VSI
(To_Vector
(D
));
4050 function vslb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4051 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4052 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4056 LL_VUC_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4057 return To_LL_VSC
(To_Vector
(D
));
4064 function vslh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4065 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4066 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4070 LL_VUS_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4071 return To_LL_VSS
(To_Vector
(D
));
4078 function vslw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4079 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4080 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4084 LL_VUI_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4085 return To_LL_VSI
(To_Vector
(D
));
4092 function vsldoi_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: c_int
) return LL_VSI
is
4093 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4094 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4100 for J
in Vchar_Range
'Range loop
4101 Offset
:= c_int
(J
) + C
;
4102 Bound
:= c_int
(Vchar_Range
'First)
4103 + c_int
(Varray_unsigned_char
'Length);
4105 if Offset
< Bound
then
4106 D
.Values
(J
) := VA
.Values
(Vchar_Range
(Offset
));
4109 VB
.Values
(Vchar_Range
(Offset
- Bound
4110 + c_int
(Vchar_Range
'First)));
4114 return To_LL_VSI
(To_Vector
(D
));
4121 function vsldoi_8hi
(A
: LL_VSS
; B
: LL_VSS
; C
: c_int
) return LL_VSS
is
4123 return To_LL_VSS
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4130 function vsldoi_16qi
(A
: LL_VSC
; B
: LL_VSC
; C
: c_int
) return LL_VSC
is
4132 return To_LL_VSC
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4139 function vsldoi_4sf
(A
: LL_VF
; B
: LL_VF
; C
: c_int
) return LL_VF
is
4141 return To_LL_VF
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4148 function vsl
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4149 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4150 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4152 M
: constant Natural :=
4153 Natural (Bits
(VB
.Values
(Vint_Range
'Last), 29, 31));
4155 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4156 -- must be the same. Otherwise the value placed into D is undefined."
4157 -- ??? Shall we add a optional check for B?
4160 for J
in Vint_Range
'Range loop
4162 D
.Values
(J
) := D
.Values
(J
) + Shift_Left
(VA
.Values
(J
), M
);
4164 if J
/= Vint_Range
'Last then
4166 D
.Values
(J
) + Shift_Right
(VA
.Values
(J
+ 1),
4167 signed_int
'Size - M
);
4171 return To_LL_VSI
(To_Vector
(D
));
4178 function vslo
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4179 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4180 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4182 M
: constant Natural :=
4183 Natural (Bits
(VB
.Values
(Vchar_Range
'Last), 1, 4));
4187 for N
in Vchar_Range
'Range loop
4188 J
:= Natural (N
) + M
;
4190 if J
<= Natural (Vchar_Range
'Last) then
4191 D
.Values
(N
) := VA
.Values
(Vchar_Range
(J
));
4197 return To_LL_VSI
(To_Vector
(D
));
4204 function vspltb
(A
: LL_VSC
; B
: c_int
) return LL_VSC
is
4205 VA
: constant VSC_View
:= To_View
(A
);
4208 D
.Values
:= LL_VSC_Operations
.vspltx
(VA
.Values
, B
);
4209 return To_Vector
(D
);
4216 function vsplth
(A
: LL_VSS
; B
: c_int
) return LL_VSS
is
4217 VA
: constant VSS_View
:= To_View
(A
);
4220 D
.Values
:= LL_VSS_Operations
.vspltx
(VA
.Values
, B
);
4221 return To_Vector
(D
);
4228 function vspltw
(A
: LL_VSI
; B
: c_int
) return LL_VSI
is
4229 VA
: constant VSI_View
:= To_View
(A
);
4232 D
.Values
:= LL_VSI_Operations
.vspltx
(VA
.Values
, B
);
4233 return To_Vector
(D
);
4240 function vspltisb
(A
: c_int
) return LL_VSC
is
4243 D
.Values
:= LL_VSC_Operations
.vspltisx
(A
);
4244 return To_Vector
(D
);
4251 function vspltish
(A
: c_int
) return LL_VSS
is
4254 D
.Values
:= LL_VSS_Operations
.vspltisx
(A
);
4255 return To_Vector
(D
);
4262 function vspltisw
(A
: c_int
) return LL_VSI
is
4265 D
.Values
:= LL_VSI_Operations
.vspltisx
(A
);
4266 return To_Vector
(D
);
4273 function vsrb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4274 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4275 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4279 LL_VUC_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4280 return To_LL_VSC
(To_Vector
(D
));
4287 function vsrh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4288 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4289 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4293 LL_VUS_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4294 return To_LL_VSS
(To_Vector
(D
));
4301 function vsrw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4302 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4303 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4307 LL_VUI_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4308 return To_LL_VSI
(To_Vector
(D
));
4315 function vsrab
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4316 VA
: constant VSC_View
:= To_View
(A
);
4317 VB
: constant VSC_View
:= To_View
(B
);
4321 LL_VSC_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4322 return To_Vector
(D
);
4329 function vsrah
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4330 VA
: constant VSS_View
:= To_View
(A
);
4331 VB
: constant VSS_View
:= To_View
(B
);
4335 LL_VSS_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4336 return To_Vector
(D
);
4343 function vsraw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4344 VA
: constant VSI_View
:= To_View
(A
);
4345 VB
: constant VSI_View
:= To_View
(B
);
4349 LL_VSI_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4350 return To_Vector
(D
);
4357 function vsr
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4358 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4359 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4360 M
: constant Natural :=
4361 Natural (Bits
(VB
.Values
(Vint_Range
'Last), 29, 31));
4365 for J
in Vint_Range
'Range loop
4367 D
.Values
(J
) := D
.Values
(J
) + Shift_Right
(VA
.Values
(J
), M
);
4369 if J
/= Vint_Range
'First then
4372 + Shift_Left
(VA
.Values
(J
- 1), signed_int
'Size - M
);
4376 return To_LL_VSI
(To_Vector
(D
));
4383 function vsro
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4384 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4385 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4386 M
: constant Natural :=
4387 Natural (Bits
(VB
.Values
(Vchar_Range
'Last), 1, 4));
4392 for N
in Vchar_Range
'Range loop
4393 J
:= Natural (N
) - M
;
4395 if J
>= Natural (Vchar_Range
'First) then
4396 D
.Values
(N
) := VA
.Values
(Vchar_Range
(J
));
4402 return To_LL_VSI
(To_Vector
(D
));
4409 procedure stvx
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) is
4410 EA
: Integer_Address
;
4413 EA
:= Bound_Align
(Integer_Address
(B
) + To_Integer
(C
), 16);
4417 for D
'Address use To_Address
(EA
);
4427 procedure stvebx
(A
: LL_VSC
; B
: c_int
; C
: c_ptr
) is
4428 VA
: constant VSC_View
:= To_View
(A
);
4430 LL_VSC_Operations
.stvexx
(VA
.Values
, B
, C
);
4437 procedure stvehx
(A
: LL_VSS
; B
: c_int
; C
: c_ptr
) is
4438 VA
: constant VSS_View
:= To_View
(A
);
4440 LL_VSS_Operations
.stvexx
(VA
.Values
, B
, C
);
4447 procedure stvewx
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) is
4448 VA
: constant VSI_View
:= To_View
(A
);
4450 LL_VSI_Operations
.stvexx
(VA
.Values
, B
, C
);
4457 procedure stvxl
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) renames stvx
;
4463 function vsububm
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4464 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4465 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4468 D
.Values
:= LL_VUC_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4469 return To_LL_VSC
(To_Vector
(D
));
4476 function vsubuhm
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4477 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4478 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4481 D
.Values
:= LL_VUS_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4482 return To_LL_VSS
(To_Vector
(D
));
4489 function vsubuwm
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4490 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4491 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4494 D
.Values
:= LL_VUI_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4495 return To_LL_VSI
(To_Vector
(D
));
4502 function vsubfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
4503 VA
: constant VF_View
:= To_View
(A
);
4504 VB
: constant VF_View
:= To_View
(B
);
4508 for J
in Vfloat_Range
'Range loop
4510 NJ_Truncate
(NJ_Truncate
(VA
.Values
(J
))
4511 - NJ_Truncate
(VB
.Values
(J
)));
4514 return To_Vector
(D
);
4521 function vsubcuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4522 Subst_Result
: SI64
;
4524 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4525 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4529 for J
in Vint_Range
'Range loop
4530 Subst_Result
:= SI64
(VA
.Values
(J
)) - SI64
(VB
.Values
(J
));
4532 if Subst_Result
< SI64
(unsigned_int
'First) then
4539 return To_LL_VSI
(To_Vector
(D
));
4546 function vsububs
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4547 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4548 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4551 D
.Values
:= LL_VUC_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4552 return To_LL_VSC
(To_Vector
(D
));
4559 function vsubsbs
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4560 VA
: constant VSC_View
:= To_View
(A
);
4561 VB
: constant VSC_View
:= To_View
(B
);
4564 D
.Values
:= LL_VSC_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4565 return To_Vector
(D
);
4572 function vsubuhs
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4573 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4574 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4577 D
.Values
:= LL_VUS_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4578 return To_LL_VSS
(To_Vector
(D
));
4585 function vsubshs
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4586 VA
: constant VSS_View
:= To_View
(A
);
4587 VB
: constant VSS_View
:= To_View
(B
);
4590 D
.Values
:= LL_VSS_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4591 return To_Vector
(D
);
4598 function vsubuws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4599 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4600 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4603 D
.Values
:= LL_VUI_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4604 return To_LL_VSI
(To_Vector
(D
));
4611 function vsubsws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4612 VA
: constant VSI_View
:= To_View
(A
);
4613 VB
: constant VSI_View
:= To_View
(B
);
4616 D
.Values
:= LL_VSI_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4617 return To_Vector
(D
);
4624 function vsum4ubs
(A
: LL_VSC
; B
: LL_VSI
) return LL_VSI
is
4625 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4626 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4627 Offset
: Vchar_Range
;
4631 for J
in 0 .. 3 loop
4632 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
4633 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4634 LL_VUI_Operations
.Saturate
4635 (UI64
(VA
.Values
(Offset
))
4636 + UI64
(VA
.Values
(Offset
+ 1))
4637 + UI64
(VA
.Values
(Offset
+ 2))
4638 + UI64
(VA
.Values
(Offset
+ 3))
4639 + UI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4642 return To_LL_VSI
(To_Vector
(D
));
4649 function vsum4sbs
(A
: LL_VSC
; B
: LL_VSI
) return LL_VSI
is
4650 VA
: constant VSC_View
:= To_View
(A
);
4651 VB
: constant VSI_View
:= To_View
(B
);
4652 Offset
: Vchar_Range
;
4656 for J
in 0 .. 3 loop
4657 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
4658 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4659 LL_VSI_Operations
.Saturate
4660 (SI64
(VA
.Values
(Offset
))
4661 + SI64
(VA
.Values
(Offset
+ 1))
4662 + SI64
(VA
.Values
(Offset
+ 2))
4663 + SI64
(VA
.Values
(Offset
+ 3))
4664 + SI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4667 return To_Vector
(D
);
4674 function vsum4shs
(A
: LL_VSS
; B
: LL_VSI
) return LL_VSI
is
4675 VA
: constant VSS_View
:= To_View
(A
);
4676 VB
: constant VSI_View
:= To_View
(B
);
4677 Offset
: Vshort_Range
;
4681 for J
in 0 .. 3 loop
4682 Offset
:= Vshort_Range
(2 * J
+ Integer (Vchar_Range
'First));
4683 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4684 LL_VSI_Operations
.Saturate
4685 (SI64
(VA
.Values
(Offset
))
4686 + SI64
(VA
.Values
(Offset
+ 1))
4687 + SI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4690 return To_Vector
(D
);
4697 function vsum2sws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4698 VA
: constant VSI_View
:= To_View
(A
);
4699 VB
: constant VSI_View
:= To_View
(B
);
4700 Offset
: Vint_Range
;
4704 for J
in 0 .. 1 loop
4705 Offset
:= Vint_Range
(2 * J
+ Integer (Vchar_Range
'First));
4706 D
.Values
(Offset
) := 0;
4707 D
.Values
(Offset
+ 1) :=
4708 LL_VSI_Operations
.Saturate
4709 (SI64
(VA
.Values
(Offset
))
4710 + SI64
(VA
.Values
(Offset
+ 1))
4711 + SI64
(VB
.Values
(Vint_Range
(Offset
+ 1))));
4714 return To_Vector
(D
);
4721 function vsumsws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4722 VA
: constant VSI_View
:= To_View
(A
);
4723 VB
: constant VSI_View
:= To_View
(B
);
4725 Sum_Buffer
: SI64
:= 0;
4728 for J
in Vint_Range
'Range loop
4730 Sum_Buffer
:= Sum_Buffer
+ SI64
(VA
.Values
(J
));
4733 Sum_Buffer
:= Sum_Buffer
+ SI64
(VB
.Values
(Vint_Range
'Last));
4734 D
.Values
(Vint_Range
'Last) := LL_VSI_Operations
.Saturate
(Sum_Buffer
);
4735 return To_Vector
(D
);
4742 function vrfiz
(A
: LL_VF
) return LL_VF
is
4743 VA
: constant VF_View
:= To_View
(A
);
4746 for J
in Vfloat_Range
'Range loop
4747 D
.Values
(J
) := C_float
(Rnd_To_FPI_Trunc
(F64
(VA
.Values
(J
))));
4750 return To_Vector
(D
);
4757 function vupkhsb
(A
: LL_VSC
) return LL_VSS
is
4758 VA
: constant VSC_View
:= To_View
(A
);
4761 D
.Values
:= LL_VSC_LL_VSS_Operations
.vupkxsx
(VA
.Values
, 0);
4762 return To_Vector
(D
);
4769 function vupkhsh
(A
: LL_VSS
) return LL_VSI
is
4770 VA
: constant VSS_View
:= To_View
(A
);
4773 D
.Values
:= LL_VSS_LL_VSI_Operations
.vupkxsx
(VA
.Values
, 0);
4774 return To_Vector
(D
);
4781 function vupkxpx
(A
: LL_VSS
; Offset
: Natural) return LL_VSI
;
4782 -- For vupkhpx and vupklpx (depending on Offset)
4784 function vupkxpx
(A
: LL_VSS
; Offset
: Natural) return LL_VSI
is
4785 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4791 function Sign_Extend
(X
: Unsigned_1
) return unsigned_char
;
4793 function Sign_Extend
(X
: Unsigned_1
) return unsigned_char
is
4803 for J
in Vint_Range
'Range loop
4804 K
:= Vshort_Range
(Integer (J
)
4805 - Integer (Vint_Range
'First)
4806 + Integer (Vshort_Range
'First)
4808 P16
:= To_Pixel
(VA
.Values
(K
));
4809 P32
.T
:= Sign_Extend
(P16
.T
);
4810 P32
.R
:= unsigned_char
(P16
.R
);
4811 P32
.G
:= unsigned_char
(P16
.G
);
4812 P32
.B
:= unsigned_char
(P16
.B
);
4813 D
.Values
(J
) := To_unsigned_int
(P32
);
4816 return To_LL_VSI
(To_Vector
(D
));
4823 function vupkhpx
(A
: LL_VSS
) return LL_VSI
is
4825 return vupkxpx
(A
, 0);
4832 function vupklsb
(A
: LL_VSC
) return LL_VSS
is
4833 VA
: constant VSC_View
:= To_View
(A
);
4837 LL_VSC_LL_VSS_Operations
.vupkxsx
(VA
.Values
,
4838 Varray_signed_short
'Length);
4839 return To_Vector
(D
);
4846 function vupklsh
(A
: LL_VSS
) return LL_VSI
is
4847 VA
: constant VSS_View
:= To_View
(A
);
4851 LL_VSS_LL_VSI_Operations
.vupkxsx
(VA
.Values
,
4852 Varray_signed_int
'Length);
4853 return To_Vector
(D
);
4860 function vupklpx
(A
: LL_VSS
) return LL_VSI
is
4862 return vupkxpx
(A
, Varray_signed_int
'Length);
4869 function vxor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4870 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4871 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4875 for J
in Vint_Range
'Range loop
4876 D
.Values
(J
) := VA
.Values
(J
) xor VB
.Values
(J
);
4879 return To_LL_VSI
(To_Vector
(D
));
4886 function vcmpequb_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4889 D
:= vcmpequb
(B
, C
);
4890 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4897 function vcmpequh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4900 D
:= vcmpequh
(B
, C
);
4901 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4908 function vcmpequw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
4911 D
:= vcmpequw
(B
, C
);
4912 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4919 function vcmpeqfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
4922 D
:= vcmpeqfp
(B
, C
);
4923 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4930 function vcmpgtub_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4933 D
:= vcmpgtub
(B
, C
);
4934 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4941 function vcmpgtuh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4944 D
:= vcmpgtuh
(B
, C
);
4945 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4952 function vcmpgtuw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
4955 D
:= vcmpgtuw
(B
, C
);
4956 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4963 function vcmpgtsb_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4966 D
:= vcmpgtsb
(B
, C
);
4967 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4974 function vcmpgtsh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4977 D
:= vcmpgtsh
(B
, C
);
4978 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4985 function vcmpgtsw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
4988 D
:= vcmpgtsw
(B
, C
);
4989 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4996 function vcmpgefp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
4999 D
:= vcmpgefp
(B
, C
);
5000 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5007 function vcmpgtfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
5010 D
:= vcmpgtfp
(B
, C
);
5011 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5018 function vcmpbfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
5021 D
:= To_View
(vcmpbfp
(B
, C
));
5023 for J
in Vint_Range
'Range loop
5024 -- vcmpbfp is not returning the usual bool vector; do the conversion
5025 if D
.Values
(J
) = 0 then
5026 D
.Values
(J
) := Signed_Bool_False
;
5028 D
.Values
(J
) := Signed_Bool_True
;
5032 return LL_VSI_Operations
.Check_CR6
(A
, D
.Values
);
5035 end GNAT
.Altivec
.Low_Level_Vectors
;