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-2006, 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
2822 -- Simulate the altivec unit behavior regarding what Effective Address
2823 -- is accessed, stripping off the input address least significant bits
2824 -- wrt to vector alignment.
2826 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2827 -- an address within a vector is not necessarily rounded back at the
2828 -- vector start address. Besides, rounding on 16 makes no sense on such
2829 -- targets because the address of a properly aligned vector (that is,
2830 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2831 -- want never to happen.
2833 EA
: constant System
.Address
:=
2836 (Integer_Address
(A
) + To_Integer
(B
), VECTOR_ALIGNMENT
));
2839 for D
'Address use EA
;
2849 function lvebx
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2852 D
.Values
:= LL_VSC_Operations
.lvexx
(A
, B
);
2853 return To_Vector
(D
);
2860 function lvehx
(A
: c_long
; B
: c_ptr
) return LL_VSS
is
2863 D
.Values
:= LL_VSS_Operations
.lvexx
(A
, B
);
2864 return To_Vector
(D
);
2871 function lvewx
(A
: c_long
; B
: c_ptr
) return LL_VSI
is
2874 D
.Values
:= LL_VSI_Operations
.lvexx
(A
, B
);
2875 return To_Vector
(D
);
2882 function lvxl
(A
: c_long
; B
: c_ptr
) return LL_VSI
renames
2889 function vlogefp
(A
: LL_VF
) return LL_VF
is
2890 VA
: constant VF_View
:= To_View
(A
);
2894 for J
in Varray_float
'Range loop
2896 -- ??? Check the precision of the operation.
2897 -- As described in [PEM-6 vlogefp]:
2898 -- If theorical_result is equal to the log2 of A (J) with
2899 -- infinite precision, we should have:
2900 -- abs (D (J) - theorical_result) <= 1/32,
2901 -- unless abs(D(J) - 1) <= 1/8.
2904 C_float_Operations
.Log
(NJ_Truncate
(VA
.Values
(J
)), 2.0);
2907 return To_Vector
(D
);
2914 function lvsl
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2915 type bit4_type
is mod 16#F#
+ 1;
2916 for bit4_type
'Alignment use 1;
2917 EA
: Integer_Address
;
2922 EA
:= Integer_Address
(A
) + To_Integer
(B
);
2923 SH
:= bit4_type
(EA
mod 2 ** 4);
2925 for J
in D
.Values
'Range loop
2926 D
.Values
(J
) := unsigned_char
(SH
) + unsigned_char
(J
)
2927 - unsigned_char
(D
.Values
'First);
2930 return To_LL_VSC
(To_Vector
(D
));
2937 function lvsr
(A
: c_long
; B
: c_ptr
) return LL_VSC
is
2938 type bit4_type
is mod 16#F#
+ 1;
2939 for bit4_type
'Alignment use 1;
2940 EA
: Integer_Address
;
2945 EA
:= Integer_Address
(A
) + To_Integer
(B
);
2946 SH
:= bit4_type
(EA
mod 2 ** 4);
2948 for J
in D
.Values
'Range loop
2949 D
.Values
(J
) := (16#F#
- unsigned_char
(SH
)) + unsigned_char
(J
);
2952 return To_LL_VSC
(To_Vector
(D
));
2959 function vmaddfp
(A
: LL_VF
; B
: LL_VF
; C
: LL_VF
) return LL_VF
is
2960 VA
: constant VF_View
:= To_View
(A
);
2961 VB
: constant VF_View
:= To_View
(B
);
2962 VC
: constant VF_View
:= To_View
(C
);
2966 for J
in Varray_float
'Range loop
2968 Rnd_To_FP_Nearest
(F64
(VA
.Values
(J
))
2969 * F64
(VB
.Values
(J
))
2970 + F64
(VC
.Values
(J
)));
2973 return To_Vector
(D
);
2980 function vmhaddshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
2981 VA
: constant VSS_View
:= To_View
(A
);
2982 VB
: constant VSS_View
:= To_View
(B
);
2983 VC
: constant VSS_View
:= To_View
(C
);
2987 for J
in Varray_signed_short
'Range loop
2988 D
.Values
(J
) := LL_VSS_Operations
.Saturate
2989 ((SI64
(VA
.Values
(J
)) * SI64
(VB
.Values
(J
)))
2990 / SI64
(2 ** 15) + SI64
(VC
.Values
(J
)));
2993 return To_Vector
(D
);
3000 function vmaxub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3001 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3002 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3005 D
.Values
:= LL_VUC_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
3006 return To_LL_VSC
(To_Vector
(D
));
3013 function vmaxsb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3014 VA
: constant VSC_View
:= To_View
(A
);
3015 VB
: constant VSC_View
:= To_View
(B
);
3018 D
.Values
:= LL_VSC_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3019 return To_Vector
(D
);
3026 function vmaxuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3027 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3028 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3031 D
.Values
:= LL_VUS_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
3032 return To_LL_VSS
(To_Vector
(D
));
3039 function vmaxsh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3040 VA
: constant VSS_View
:= To_View
(A
);
3041 VB
: constant VSS_View
:= To_View
(B
);
3044 D
.Values
:= LL_VSS_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3045 return To_Vector
(D
);
3052 function vmaxuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3053 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3054 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3057 D
.Values
:= LL_VUI_Operations
.vmaxux
(VA
.Values
, VB
.Values
);
3058 return To_LL_VSI
(To_Vector
(D
));
3065 function vmaxsw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3066 VA
: constant VSI_View
:= To_View
(A
);
3067 VB
: constant VSI_View
:= To_View
(B
);
3070 D
.Values
:= LL_VSI_Operations
.vmaxsx
(VA
.Values
, VB
.Values
);
3071 return To_Vector
(D
);
3078 function vmaxfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
3079 VA
: constant VF_View
:= To_View
(A
);
3080 VB
: constant VF_View
:= To_View
(B
);
3084 for J
in Varray_float
'Range loop
3085 if VA
.Values
(J
) > VB
.Values
(J
) then
3086 D
.Values
(J
) := VA
.Values
(J
);
3088 D
.Values
(J
) := VB
.Values
(J
);
3092 return To_Vector
(D
);
3099 function vmrghb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3100 VA
: constant VSC_View
:= To_View
(A
);
3101 VB
: constant VSC_View
:= To_View
(B
);
3104 D
.Values
:= LL_VSC_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3105 return To_Vector
(D
);
3112 function vmrghh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3113 VA
: constant VSS_View
:= To_View
(A
);
3114 VB
: constant VSS_View
:= To_View
(B
);
3117 D
.Values
:= LL_VSS_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3118 return To_Vector
(D
);
3125 function vmrghw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3126 VA
: constant VSI_View
:= To_View
(A
);
3127 VB
: constant VSI_View
:= To_View
(B
);
3130 D
.Values
:= LL_VSI_Operations
.vmrghx
(VA
.Values
, VB
.Values
);
3131 return To_Vector
(D
);
3138 function vmrglb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3139 VA
: constant VSC_View
:= To_View
(A
);
3140 VB
: constant VSC_View
:= To_View
(B
);
3143 D
.Values
:= LL_VSC_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3144 return To_Vector
(D
);
3151 function vmrglh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3152 VA
: constant VSS_View
:= To_View
(A
);
3153 VB
: constant VSS_View
:= To_View
(B
);
3156 D
.Values
:= LL_VSS_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3157 return To_Vector
(D
);
3164 function vmrglw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3165 VA
: constant VSI_View
:= To_View
(A
);
3166 VB
: constant VSI_View
:= To_View
(B
);
3169 D
.Values
:= LL_VSI_Operations
.vmrglx
(VA
.Values
, VB
.Values
);
3170 return To_Vector
(D
);
3177 function mfvscr
return LL_VSS
is
3180 for J
in Varray_unsigned_short
'Range loop
3184 D
.Values
(Varray_unsigned_short
'Last) :=
3185 unsigned_short
(VSCR
mod 2 ** unsigned_short
'Size);
3186 D
.Values
(Varray_unsigned_short
'Last - 1) :=
3187 unsigned_short
(VSCR
/ 2 ** unsigned_short
'Size);
3188 return To_LL_VSS
(To_Vector
(D
));
3195 function vminfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
3196 VA
: constant VF_View
:= To_View
(A
);
3197 VB
: constant VF_View
:= To_View
(B
);
3201 for J
in Varray_float
'Range loop
3202 if VA
.Values
(J
) < VB
.Values
(J
) then
3203 D
.Values
(J
) := VA
.Values
(J
);
3205 D
.Values
(J
) := VB
.Values
(J
);
3209 return To_Vector
(D
);
3216 function vminsb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3217 VA
: constant VSC_View
:= To_View
(A
);
3218 VB
: constant VSC_View
:= To_View
(B
);
3221 D
.Values
:= LL_VSC_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3222 return To_Vector
(D
);
3229 function vminub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3230 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3231 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3234 D
.Values
:= LL_VUC_Operations
.vminux
(VA
.Values
, VB
.Values
);
3235 return To_LL_VSC
(To_Vector
(D
));
3242 function vminsh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3243 VA
: constant VSS_View
:= To_View
(A
);
3244 VB
: constant VSS_View
:= To_View
(B
);
3247 D
.Values
:= LL_VSS_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3248 return To_Vector
(D
);
3255 function vminuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3256 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3257 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3260 D
.Values
:= LL_VUS_Operations
.vminux
(VA
.Values
, VB
.Values
);
3261 return To_LL_VSS
(To_Vector
(D
));
3268 function vminsw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3269 VA
: constant VSI_View
:= To_View
(A
);
3270 VB
: constant VSI_View
:= To_View
(B
);
3273 D
.Values
:= LL_VSI_Operations
.vminsx
(VA
.Values
, VB
.Values
);
3274 return To_Vector
(D
);
3281 function vminuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3282 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3283 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3286 D
.Values
:= LL_VUI_Operations
.vminux
(VA
.Values
,
3288 return To_LL_VSI
(To_Vector
(D
));
3295 function vmladduhm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
3296 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3297 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3298 VC
: constant VUS_View
:= To_View
(To_LL_VUS
(C
));
3302 for J
in Varray_unsigned_short
'Range loop
3303 D
.Values
(J
) := VA
.Values
(J
) * VB
.Values
(J
)
3307 return To_LL_VSS
(To_Vector
(D
));
3314 function vmhraddshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSS
) return LL_VSS
is
3315 VA
: constant VSS_View
:= To_View
(A
);
3316 VB
: constant VSS_View
:= To_View
(B
);
3317 VC
: constant VSS_View
:= To_View
(C
);
3321 for J
in Varray_signed_short
'Range loop
3323 LL_VSS_Operations
.Saturate
(((SI64
(VA
.Values
(J
))
3324 * SI64
(VB
.Values
(J
))
3327 + SI64
(VC
.Values
(J
))));
3330 return To_Vector
(D
);
3337 function vmsumubm
(A
: LL_VSC
; B
: LL_VSC
; C
: LL_VSI
) return LL_VSI
is
3338 Offset
: Vchar_Range
;
3339 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3340 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3341 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3345 for J
in 0 .. 3 loop
3346 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
3347 D
.Values
(Vint_Range
3348 (J
+ Integer (Vint_Range
'First))) :=
3349 (unsigned_int
(VA
.Values
(Offset
))
3350 * unsigned_int
(VB
.Values
(Offset
)))
3351 + (unsigned_int
(VA
.Values
(Offset
+ 1))
3352 * unsigned_int
(VB
.Values
(1 + Offset
)))
3353 + (unsigned_int
(VA
.Values
(2 + Offset
))
3354 * unsigned_int
(VB
.Values
(2 + Offset
)))
3355 + (unsigned_int
(VA
.Values
(3 + Offset
))
3356 * unsigned_int
(VB
.Values
(3 + Offset
)))
3357 + VC
.Values
(Vint_Range
3358 (J
+ Integer (Varray_unsigned_int
'First)));
3361 return To_LL_VSI
(To_Vector
(D
));
3368 function vmsummbm
(A
: LL_VSC
; B
: LL_VSC
; C
: LL_VSI
) return LL_VSI
is
3369 Offset
: Vchar_Range
;
3370 VA
: constant VSC_View
:= To_View
(A
);
3371 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3372 VC
: constant VSI_View
:= To_View
(C
);
3376 for J
in 0 .. 3 loop
3377 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
3378 D
.Values
(Vint_Range
3379 (J
+ Integer (Varray_unsigned_int
'First))) := 0
3380 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
))
3381 * SI64
(VB
.Values
(Offset
)))
3382 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
+ 1))
3385 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(2 + Offset
))
3388 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(3 + Offset
))
3391 + VC
.Values
(Vint_Range
3392 (J
+ Integer (Varray_unsigned_int
'First)));
3395 return To_Vector
(D
);
3402 function vmsumuhm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3403 Offset
: Vshort_Range
;
3404 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3405 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3406 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3410 for J
in 0 .. 3 loop
3412 Vshort_Range
(2 * J
+ Integer (Vshort_Range
'First));
3413 D
.Values
(Vint_Range
3414 (J
+ Integer (Varray_unsigned_int
'First))) :=
3415 (unsigned_int
(VA
.Values
(Offset
))
3416 * unsigned_int
(VB
.Values
(Offset
)))
3417 + (unsigned_int
(VA
.Values
(Offset
+ 1))
3418 * unsigned_int
(VB
.Values
(1 + Offset
)))
3419 + VC
.Values
(Vint_Range
3420 (J
+ Integer (Vint_Range
'First)));
3423 return To_LL_VSI
(To_Vector
(D
));
3430 function vmsumshm
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3431 VA
: constant VSS_View
:= To_View
(A
);
3432 VB
: constant VSS_View
:= To_View
(B
);
3433 VC
: constant VSI_View
:= To_View
(C
);
3434 Offset
: Vshort_Range
;
3438 for J
in 0 .. 3 loop
3440 Vshort_Range
(2 * J
+ Integer (Varray_signed_char
'First));
3441 D
.Values
(Vint_Range
3442 (J
+ Integer (Varray_unsigned_int
'First))) := 0
3443 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
))
3444 * SI64
(VB
.Values
(Offset
)))
3445 + LL_VSI_Operations
.Modular_Result
(SI64
(VA
.Values
(Offset
+ 1))
3448 + VC
.Values
(Vint_Range
3449 (J
+ Integer (Varray_unsigned_int
'First)));
3452 return To_Vector
(D
);
3459 function vmsumuhs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3460 Offset
: Vshort_Range
;
3461 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3462 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3463 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
3467 for J
in 0 .. 3 loop
3469 Vshort_Range
(2 * J
+ Integer (Varray_signed_short
'First));
3470 D
.Values
(Vint_Range
3471 (J
+ Integer (Varray_unsigned_int
'First))) :=
3472 LL_VUI_Operations
.Saturate
3473 (UI64
(VA
.Values
(Offset
))
3474 * UI64
(VB
.Values
(Offset
))
3475 + UI64
(VA
.Values
(Offset
+ 1))
3476 * UI64
(VB
.Values
(1 + Offset
))
3479 (J
+ Integer (Varray_unsigned_int
'First)))));
3482 return To_LL_VSI
(To_Vector
(D
));
3489 function vmsumshs
(A
: LL_VSS
; B
: LL_VSS
; C
: LL_VSI
) return LL_VSI
is
3490 VA
: constant VSS_View
:= To_View
(A
);
3491 VB
: constant VSS_View
:= To_View
(B
);
3492 VC
: constant VSI_View
:= To_View
(C
);
3493 Offset
: Vshort_Range
;
3497 for J
in 0 .. 3 loop
3499 Vshort_Range
(2 * J
+ Integer (Varray_signed_short
'First));
3500 D
.Values
(Vint_Range
3501 (J
+ Integer (Varray_signed_int
'First))) :=
3502 LL_VSI_Operations
.Saturate
3503 (SI64
(VA
.Values
(Offset
))
3504 * SI64
(VB
.Values
(Offset
))
3505 + SI64
(VA
.Values
(Offset
+ 1))
3506 * SI64
(VB
.Values
(1 + Offset
))
3509 (J
+ Integer (Varray_signed_int
'First)))));
3512 return To_Vector
(D
);
3519 procedure mtvscr
(A
: LL_VSI
) is
3520 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3522 VSCR
:= VA
.Values
(Varray_unsigned_int
'Last);
3529 function vmuleub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3530 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3531 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3534 D
.Values
:= LL_VUC_LL_VUS_Operations
.vmulxux
(True,
3537 return To_LL_VSS
(To_Vector
(D
));
3544 function vmuleuh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3545 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3546 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3549 D
.Values
:= LL_VUS_LL_VUI_Operations
.vmulxux
(True,
3552 return To_LL_VSI
(To_Vector
(D
));
3559 function vmulesb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3560 VA
: constant VSC_View
:= To_View
(A
);
3561 VB
: constant VSC_View
:= To_View
(B
);
3564 D
.Values
:= LL_VSC_LL_VSS_Operations
.vmulxsx
(True,
3567 return To_Vector
(D
);
3574 function vmulesh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3575 VA
: constant VSS_View
:= To_View
(A
);
3576 VB
: constant VSS_View
:= To_View
(B
);
3579 D
.Values
:= LL_VSS_LL_VSI_Operations
.vmulxsx
(True,
3582 return To_Vector
(D
);
3589 function vmuloub
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3590 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3591 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3594 D
.Values
:= LL_VUC_LL_VUS_Operations
.vmulxux
(False,
3597 return To_LL_VSS
(To_Vector
(D
));
3604 function vmulouh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3605 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3606 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3610 LL_VUS_LL_VUI_Operations
.vmulxux
(False, VA
.Values
, VB
.Values
);
3611 return To_LL_VSI
(To_Vector
(D
));
3618 function vmulosb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSS
is
3619 VA
: constant VSC_View
:= To_View
(A
);
3620 VB
: constant VSC_View
:= To_View
(B
);
3623 D
.Values
:= LL_VSC_LL_VSS_Operations
.vmulxsx
(False,
3626 return To_Vector
(D
);
3633 function vmulosh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSI
is
3634 VA
: constant VSS_View
:= To_View
(A
);
3635 VB
: constant VSS_View
:= To_View
(B
);
3638 D
.Values
:= LL_VSS_LL_VSI_Operations
.vmulxsx
(False,
3641 return To_Vector
(D
);
3648 function vnmsubfp
(A
: LL_VF
; B
: LL_VF
; C
: LL_VF
) return LL_VF
is
3649 VA
: constant VF_View
:= To_View
(A
);
3650 VB
: constant VF_View
:= To_View
(B
);
3651 VC
: constant VF_View
:= To_View
(C
);
3655 for J
in Vfloat_Range
'Range loop
3657 -Rnd_To_FP_Nearest
(F64
(VA
.Values
(J
))
3658 * F64
(VB
.Values
(J
))
3659 - F64
(VC
.Values
(J
)));
3662 return To_Vector
(D
);
3669 function vnor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3670 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3671 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3675 for J
in Vint_Range
'Range loop
3676 D
.Values
(J
) := not (VA
.Values
(J
) or VB
.Values
(J
));
3679 return To_LL_VSI
(To_Vector
(D
));
3686 function vor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3687 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3688 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3692 for J
in Vint_Range
'Range loop
3693 D
.Values
(J
) := VA
.Values
(J
) or VB
.Values
(J
);
3696 return To_LL_VSI
(To_Vector
(D
));
3703 function vpkuhum
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3704 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3705 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3708 D
.Values
:= LL_VUC_LL_VUS_Operations
.vpkuxum
(VA
.Values
, VB
.Values
);
3709 return To_LL_VSC
(To_Vector
(D
));
3716 function vpkuwum
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3717 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3718 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3721 D
.Values
:= LL_VUS_LL_VUI_Operations
.vpkuxum
(VA
.Values
, VB
.Values
);
3722 return To_LL_VSS
(To_Vector
(D
));
3729 function vpkpx
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3730 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3731 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3733 Offset
: Vint_Range
;
3738 for J
in 0 .. 3 loop
3739 Offset
:= Vint_Range
(J
+ Integer (Vshort_Range
'First));
3740 P32
:= To_Pixel
(VA
.Values
(Offset
));
3741 P16
.T
:= Unsigned_1
(P32
.T
mod 2 ** 1);
3742 P16
.R
:= Unsigned_5
(Shift_Right
(P32
.R
, 3) mod 2 ** 5);
3743 P16
.G
:= Unsigned_5
(Shift_Right
(P32
.G
, 3) mod 2 ** 5);
3744 P16
.B
:= Unsigned_5
(Shift_Right
(P32
.B
, 3) mod 2 ** 5);
3745 D
.Values
(Vshort_Range
(Offset
)) := To_unsigned_short
(P16
);
3746 P32
:= To_Pixel
(VB
.Values
(Offset
));
3747 P16
.T
:= Unsigned_1
(P32
.T
mod 2 ** 1);
3748 P16
.R
:= Unsigned_5
(Shift_Right
(P32
.R
, 3) mod 2 ** 5);
3749 P16
.G
:= Unsigned_5
(Shift_Right
(P32
.G
, 3) mod 2 ** 5);
3750 P16
.B
:= Unsigned_5
(Shift_Right
(P32
.B
, 3) mod 2 ** 5);
3751 D
.Values
(Vshort_Range
(Offset
) + 4) := To_unsigned_short
(P16
);
3754 return To_LL_VSS
(To_Vector
(D
));
3761 function vpkuhus
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3762 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3763 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3766 D
.Values
:= LL_VUC_LL_VUS_Operations
.vpkuxus
(VA
.Values
, VB
.Values
);
3767 return To_LL_VSC
(To_Vector
(D
));
3774 function vpkuwus
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3775 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3776 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
3779 D
.Values
:= LL_VUS_LL_VUI_Operations
.vpkuxus
(VA
.Values
, VB
.Values
);
3780 return To_LL_VSS
(To_Vector
(D
));
3787 function vpkshss
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3788 VA
: constant VSS_View
:= To_View
(A
);
3789 VB
: constant VSS_View
:= To_View
(B
);
3792 D
.Values
:= LL_VSC_LL_VSS_Operations
.vpksxss
(VA
.Values
, VB
.Values
);
3793 return To_Vector
(D
);
3800 function vpkswss
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3801 VA
: constant VSI_View
:= To_View
(A
);
3802 VB
: constant VSI_View
:= To_View
(B
);
3805 D
.Values
:= LL_VSS_LL_VSI_Operations
.vpksxss
(VA
.Values
, VB
.Values
);
3806 return To_Vector
(D
);
3814 type Signed_Component_Type
is range <>;
3815 type Signed_Index_Type
is range <>;
3816 type Signed_Varray_Type
is
3817 array (Signed_Index_Type
) of Signed_Component_Type
;
3818 type Unsigned_Component_Type
is mod <>;
3819 type Unsigned_Index_Type
is range <>;
3820 type Unsigned_Varray_Type
is
3821 array (Unsigned_Index_Type
) of Unsigned_Component_Type
;
3824 (A
: Signed_Varray_Type
;
3825 B
: Signed_Varray_Type
) return Unsigned_Varray_Type
;
3828 (A
: Signed_Varray_Type
;
3829 B
: Signed_Varray_Type
) return Unsigned_Varray_Type
3831 N
: constant Unsigned_Index_Type
:=
3832 Unsigned_Index_Type
(Signed_Index_Type
'Last);
3833 Offset
: Unsigned_Index_Type
;
3834 Signed_Offset
: Signed_Index_Type
;
3835 D
: Unsigned_Varray_Type
;
3838 (X
: Signed_Component_Type
) return Unsigned_Component_Type
;
3839 -- Saturation, as defined in
3840 -- [PIM-4.1 Vector Status and Control Register]
3847 (X
: Signed_Component_Type
) return Unsigned_Component_Type
3849 D
: Unsigned_Component_Type
;
3852 D
:= Unsigned_Component_Type
3853 (Signed_Component_Type
'Max
3854 (Signed_Component_Type
(Unsigned_Component_Type
'First),
3855 Signed_Component_Type
'Min
3856 (Signed_Component_Type
(Unsigned_Component_Type
'Last),
3858 if Signed_Component_Type
(D
) /= X
then
3859 VSCR
:= Write_Bit
(VSCR
, SAT_POS
, 1);
3865 -- Start of processing for vpksxus
3868 for J
in 0 .. N
- 1 loop
3870 Unsigned_Index_Type
(Integer (J
)
3871 + Integer (Unsigned_Index_Type
'First));
3873 Signed_Index_Type
(Integer (J
)
3874 + Integer (Signed_Index_Type
'First));
3875 D
(Offset
) := Saturate
(A
(Signed_Offset
));
3876 D
(Offset
+ N
) := Saturate
(B
(Signed_Offset
));
3886 function vpkshus
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSC
is
3887 function vpkshus_Instance
is
3888 new vpksxus
(signed_short
,
3890 Varray_signed_short
,
3893 Varray_unsigned_char
);
3895 VA
: constant VSS_View
:= To_View
(A
);
3896 VB
: constant VSS_View
:= To_View
(B
);
3900 D
.Values
:= vpkshus_Instance
(VA
.Values
, VB
.Values
);
3901 return To_LL_VSC
(To_Vector
(D
));
3908 function vpkswus
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSS
is
3909 function vpkswus_Instance
is
3910 new vpksxus
(signed_int
,
3915 Varray_unsigned_short
);
3917 VA
: constant VSI_View
:= To_View
(A
);
3918 VB
: constant VSI_View
:= To_View
(B
);
3921 D
.Values
:= vpkswus_Instance
(VA
.Values
, VB
.Values
);
3922 return To_LL_VSS
(To_Vector
(D
));
3929 function vperm_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: LL_VSC
) return LL_VSI
is
3930 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3931 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3932 VC
: constant VUC_View
:= To_View
(To_LL_VUC
(C
));
3937 for N
in Vchar_Range
'Range loop
3938 J
:= Vchar_Range
(Integer (Bits
(VC
.Values
(N
), 4, 7))
3939 + Integer (Vchar_Range
'First));
3941 if Bits
(VC
.Values
(N
), 3, 3) = 0 then
3942 D
.Values
(N
) := VA
.Values
(J
);
3944 D
.Values
(N
) := VB
.Values
(J
);
3948 return To_LL_VSI
(To_Vector
(D
));
3955 function vrefp
(A
: LL_VF
) return LL_VF
is
3956 VA
: constant VF_View
:= To_View
(A
);
3960 for J
in Vfloat_Range
'Range loop
3961 D
.Values
(J
) := FP_Recip_Est
(VA
.Values
(J
));
3964 return To_Vector
(D
);
3971 function vrlb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
3972 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
3973 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
3976 D
.Values
:= LL_VUC_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
3977 return To_LL_VSC
(To_Vector
(D
));
3984 function vrlh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
3985 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
3986 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
3989 D
.Values
:= LL_VUS_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
3990 return To_LL_VSS
(To_Vector
(D
));
3997 function vrlw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
3998 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
3999 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4002 D
.Values
:= LL_VUI_Operations
.vrlx
(VA
.Values
, VB
.Values
, ROTL
'Access);
4003 return To_LL_VSI
(To_Vector
(D
));
4010 function vrfin
(A
: LL_VF
) return LL_VF
is
4011 VA
: constant VF_View
:= To_View
(A
);
4015 for J
in Vfloat_Range
'Range loop
4016 D
.Values
(J
) := C_float
(Rnd_To_FPI_Near
(F64
(VA
.Values
(J
))));
4019 return To_Vector
(D
);
4026 function vrsqrtefp
(A
: LL_VF
) return LL_VF
is
4027 VA
: constant VF_View
:= To_View
(A
);
4031 for J
in Vfloat_Range
'Range loop
4032 D
.Values
(J
) := Recip_SQRT_Est
(VA
.Values
(J
));
4035 return To_Vector
(D
);
4042 function vsel_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: LL_VSI
) return LL_VSI
is
4043 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4044 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4045 VC
: constant VUI_View
:= To_View
(To_LL_VUI
(C
));
4049 for J
in Vint_Range
'Range loop
4050 D
.Values
(J
) := ((not VC
.Values
(J
)) and VA
.Values
(J
))
4051 or (VC
.Values
(J
) and VB
.Values
(J
));
4054 return To_LL_VSI
(To_Vector
(D
));
4061 function vslb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4062 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4063 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4067 LL_VUC_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4068 return To_LL_VSC
(To_Vector
(D
));
4075 function vslh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4076 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4077 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4081 LL_VUS_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4082 return To_LL_VSS
(To_Vector
(D
));
4089 function vslw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4090 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4091 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4095 LL_VUI_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Left
'Access);
4096 return To_LL_VSI
(To_Vector
(D
));
4103 function vsldoi_4si
(A
: LL_VSI
; B
: LL_VSI
; C
: c_int
) return LL_VSI
is
4104 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4105 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4111 for J
in Vchar_Range
'Range loop
4112 Offset
:= c_int
(J
) + C
;
4113 Bound
:= c_int
(Vchar_Range
'First)
4114 + c_int
(Varray_unsigned_char
'Length);
4116 if Offset
< Bound
then
4117 D
.Values
(J
) := VA
.Values
(Vchar_Range
(Offset
));
4120 VB
.Values
(Vchar_Range
(Offset
- Bound
4121 + c_int
(Vchar_Range
'First)));
4125 return To_LL_VSI
(To_Vector
(D
));
4132 function vsldoi_8hi
(A
: LL_VSS
; B
: LL_VSS
; C
: c_int
) return LL_VSS
is
4134 return To_LL_VSS
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4141 function vsldoi_16qi
(A
: LL_VSC
; B
: LL_VSC
; C
: c_int
) return LL_VSC
is
4143 return To_LL_VSC
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4150 function vsldoi_4sf
(A
: LL_VF
; B
: LL_VF
; C
: c_int
) return LL_VF
is
4152 return To_LL_VF
(vsldoi_4si
(To_LL_VSI
(A
), To_LL_VSI
(B
), C
));
4159 function vsl
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4160 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4161 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4163 M
: constant Natural :=
4164 Natural (Bits
(VB
.Values
(Vint_Range
'Last), 29, 31));
4166 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4167 -- must be the same. Otherwise the value placed into D is undefined."
4168 -- ??? Shall we add a optional check for B?
4171 for J
in Vint_Range
'Range loop
4173 D
.Values
(J
) := D
.Values
(J
) + Shift_Left
(VA
.Values
(J
), M
);
4175 if J
/= Vint_Range
'Last then
4177 D
.Values
(J
) + Shift_Right
(VA
.Values
(J
+ 1),
4178 signed_int
'Size - M
);
4182 return To_LL_VSI
(To_Vector
(D
));
4189 function vslo
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4190 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4191 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4193 M
: constant Natural :=
4194 Natural (Bits
(VB
.Values
(Vchar_Range
'Last), 1, 4));
4198 for N
in Vchar_Range
'Range loop
4199 J
:= Natural (N
) + M
;
4201 if J
<= Natural (Vchar_Range
'Last) then
4202 D
.Values
(N
) := VA
.Values
(Vchar_Range
(J
));
4208 return To_LL_VSI
(To_Vector
(D
));
4215 function vspltb
(A
: LL_VSC
; B
: c_int
) return LL_VSC
is
4216 VA
: constant VSC_View
:= To_View
(A
);
4219 D
.Values
:= LL_VSC_Operations
.vspltx
(VA
.Values
, B
);
4220 return To_Vector
(D
);
4227 function vsplth
(A
: LL_VSS
; B
: c_int
) return LL_VSS
is
4228 VA
: constant VSS_View
:= To_View
(A
);
4231 D
.Values
:= LL_VSS_Operations
.vspltx
(VA
.Values
, B
);
4232 return To_Vector
(D
);
4239 function vspltw
(A
: LL_VSI
; B
: c_int
) return LL_VSI
is
4240 VA
: constant VSI_View
:= To_View
(A
);
4243 D
.Values
:= LL_VSI_Operations
.vspltx
(VA
.Values
, B
);
4244 return To_Vector
(D
);
4251 function vspltisb
(A
: c_int
) return LL_VSC
is
4254 D
.Values
:= LL_VSC_Operations
.vspltisx
(A
);
4255 return To_Vector
(D
);
4262 function vspltish
(A
: c_int
) return LL_VSS
is
4265 D
.Values
:= LL_VSS_Operations
.vspltisx
(A
);
4266 return To_Vector
(D
);
4273 function vspltisw
(A
: c_int
) return LL_VSI
is
4276 D
.Values
:= LL_VSI_Operations
.vspltisx
(A
);
4277 return To_Vector
(D
);
4284 function vsrb
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4285 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4286 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4290 LL_VUC_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4291 return To_LL_VSC
(To_Vector
(D
));
4298 function vsrh
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4299 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4300 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4304 LL_VUS_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4305 return To_LL_VSS
(To_Vector
(D
));
4312 function vsrw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4313 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4314 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4318 LL_VUI_Operations
.vsxx
(VA
.Values
, VB
.Values
, Shift_Right
'Access);
4319 return To_LL_VSI
(To_Vector
(D
));
4326 function vsrab
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4327 VA
: constant VSC_View
:= To_View
(A
);
4328 VB
: constant VSC_View
:= To_View
(B
);
4332 LL_VSC_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4333 return To_Vector
(D
);
4340 function vsrah
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4341 VA
: constant VSS_View
:= To_View
(A
);
4342 VB
: constant VSS_View
:= To_View
(B
);
4346 LL_VSS_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4347 return To_Vector
(D
);
4354 function vsraw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4355 VA
: constant VSI_View
:= To_View
(A
);
4356 VB
: constant VSI_View
:= To_View
(B
);
4360 LL_VSI_Operations
.vsrax
(VA
.Values
, VB
.Values
, Shift_Right_A
'Access);
4361 return To_Vector
(D
);
4368 function vsr
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4369 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4370 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4371 M
: constant Natural :=
4372 Natural (Bits
(VB
.Values
(Vint_Range
'Last), 29, 31));
4376 for J
in Vint_Range
'Range loop
4378 D
.Values
(J
) := D
.Values
(J
) + Shift_Right
(VA
.Values
(J
), M
);
4380 if J
/= Vint_Range
'First then
4383 + Shift_Left
(VA
.Values
(J
- 1), signed_int
'Size - M
);
4387 return To_LL_VSI
(To_Vector
(D
));
4394 function vsro
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4395 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4396 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4397 M
: constant Natural :=
4398 Natural (Bits
(VB
.Values
(Vchar_Range
'Last), 1, 4));
4403 for N
in Vchar_Range
'Range loop
4404 J
:= Natural (N
) - M
;
4406 if J
>= Natural (Vchar_Range
'First) then
4407 D
.Values
(N
) := VA
.Values
(Vchar_Range
(J
));
4413 return To_LL_VSI
(To_Vector
(D
));
4420 procedure stvx
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) is
4422 -- Simulate the altivec unit behavior regarding what Effective Address
4423 -- is accessed, stripping off the input address least significant bits
4424 -- wrt to vector alignment (see comment in lvx for further details).
4426 EA
: constant System
.Address
:=
4429 (Integer_Address
(B
) + To_Integer
(C
), VECTOR_ALIGNMENT
));
4432 for D
'Address use EA
;
4442 procedure stvebx
(A
: LL_VSC
; B
: c_int
; C
: c_ptr
) is
4443 VA
: constant VSC_View
:= To_View
(A
);
4445 LL_VSC_Operations
.stvexx
(VA
.Values
, B
, C
);
4452 procedure stvehx
(A
: LL_VSS
; B
: c_int
; C
: c_ptr
) is
4453 VA
: constant VSS_View
:= To_View
(A
);
4455 LL_VSS_Operations
.stvexx
(VA
.Values
, B
, C
);
4462 procedure stvewx
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) is
4463 VA
: constant VSI_View
:= To_View
(A
);
4465 LL_VSI_Operations
.stvexx
(VA
.Values
, B
, C
);
4472 procedure stvxl
(A
: LL_VSI
; B
: c_int
; C
: c_ptr
) renames stvx
;
4478 function vsububm
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4479 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4480 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4483 D
.Values
:= LL_VUC_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4484 return To_LL_VSC
(To_Vector
(D
));
4491 function vsubuhm
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4492 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4493 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4496 D
.Values
:= LL_VUS_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4497 return To_LL_VSS
(To_Vector
(D
));
4504 function vsubuwm
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4505 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4506 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4509 D
.Values
:= LL_VUI_Operations
.vsubuxm
(VA
.Values
, VB
.Values
);
4510 return To_LL_VSI
(To_Vector
(D
));
4517 function vsubfp
(A
: LL_VF
; B
: LL_VF
) return LL_VF
is
4518 VA
: constant VF_View
:= To_View
(A
);
4519 VB
: constant VF_View
:= To_View
(B
);
4523 for J
in Vfloat_Range
'Range loop
4525 NJ_Truncate
(NJ_Truncate
(VA
.Values
(J
))
4526 - NJ_Truncate
(VB
.Values
(J
)));
4529 return To_Vector
(D
);
4536 function vsubcuw
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4537 Subst_Result
: SI64
;
4539 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4540 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4544 for J
in Vint_Range
'Range loop
4545 Subst_Result
:= SI64
(VA
.Values
(J
)) - SI64
(VB
.Values
(J
));
4547 if Subst_Result
< SI64
(unsigned_int
'First) then
4554 return To_LL_VSI
(To_Vector
(D
));
4561 function vsububs
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4562 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4563 VB
: constant VUC_View
:= To_View
(To_LL_VUC
(B
));
4566 D
.Values
:= LL_VUC_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4567 return To_LL_VSC
(To_Vector
(D
));
4574 function vsubsbs
(A
: LL_VSC
; B
: LL_VSC
) return LL_VSC
is
4575 VA
: constant VSC_View
:= To_View
(A
);
4576 VB
: constant VSC_View
:= To_View
(B
);
4579 D
.Values
:= LL_VSC_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4580 return To_Vector
(D
);
4587 function vsubuhs
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4588 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4589 VB
: constant VUS_View
:= To_View
(To_LL_VUS
(B
));
4592 D
.Values
:= LL_VUS_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4593 return To_LL_VSS
(To_Vector
(D
));
4600 function vsubshs
(A
: LL_VSS
; B
: LL_VSS
) return LL_VSS
is
4601 VA
: constant VSS_View
:= To_View
(A
);
4602 VB
: constant VSS_View
:= To_View
(B
);
4605 D
.Values
:= LL_VSS_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4606 return To_Vector
(D
);
4613 function vsubuws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4614 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4615 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4618 D
.Values
:= LL_VUI_Operations
.vsubuxs
(VA
.Values
, VB
.Values
);
4619 return To_LL_VSI
(To_Vector
(D
));
4626 function vsubsws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4627 VA
: constant VSI_View
:= To_View
(A
);
4628 VB
: constant VSI_View
:= To_View
(B
);
4631 D
.Values
:= LL_VSI_Operations
.vsubsxs
(VA
.Values
, VB
.Values
);
4632 return To_Vector
(D
);
4639 function vsum4ubs
(A
: LL_VSC
; B
: LL_VSI
) return LL_VSI
is
4640 VA
: constant VUC_View
:= To_View
(To_LL_VUC
(A
));
4641 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4642 Offset
: Vchar_Range
;
4646 for J
in 0 .. 3 loop
4647 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
4648 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4649 LL_VUI_Operations
.Saturate
4650 (UI64
(VA
.Values
(Offset
))
4651 + UI64
(VA
.Values
(Offset
+ 1))
4652 + UI64
(VA
.Values
(Offset
+ 2))
4653 + UI64
(VA
.Values
(Offset
+ 3))
4654 + UI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4657 return To_LL_VSI
(To_Vector
(D
));
4664 function vsum4sbs
(A
: LL_VSC
; B
: LL_VSI
) return LL_VSI
is
4665 VA
: constant VSC_View
:= To_View
(A
);
4666 VB
: constant VSI_View
:= To_View
(B
);
4667 Offset
: Vchar_Range
;
4671 for J
in 0 .. 3 loop
4672 Offset
:= Vchar_Range
(4 * J
+ Integer (Vchar_Range
'First));
4673 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4674 LL_VSI_Operations
.Saturate
4675 (SI64
(VA
.Values
(Offset
))
4676 + SI64
(VA
.Values
(Offset
+ 1))
4677 + SI64
(VA
.Values
(Offset
+ 2))
4678 + SI64
(VA
.Values
(Offset
+ 3))
4679 + SI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4682 return To_Vector
(D
);
4689 function vsum4shs
(A
: LL_VSS
; B
: LL_VSI
) return LL_VSI
is
4690 VA
: constant VSS_View
:= To_View
(A
);
4691 VB
: constant VSI_View
:= To_View
(B
);
4692 Offset
: Vshort_Range
;
4696 for J
in 0 .. 3 loop
4697 Offset
:= Vshort_Range
(2 * J
+ Integer (Vchar_Range
'First));
4698 D
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First))) :=
4699 LL_VSI_Operations
.Saturate
4700 (SI64
(VA
.Values
(Offset
))
4701 + SI64
(VA
.Values
(Offset
+ 1))
4702 + SI64
(VB
.Values
(Vint_Range
(J
+ Integer (Vint_Range
'First)))));
4705 return To_Vector
(D
);
4712 function vsum2sws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4713 VA
: constant VSI_View
:= To_View
(A
);
4714 VB
: constant VSI_View
:= To_View
(B
);
4715 Offset
: Vint_Range
;
4719 for J
in 0 .. 1 loop
4720 Offset
:= Vint_Range
(2 * J
+ Integer (Vchar_Range
'First));
4721 D
.Values
(Offset
) := 0;
4722 D
.Values
(Offset
+ 1) :=
4723 LL_VSI_Operations
.Saturate
4724 (SI64
(VA
.Values
(Offset
))
4725 + SI64
(VA
.Values
(Offset
+ 1))
4726 + SI64
(VB
.Values
(Vint_Range
(Offset
+ 1))));
4729 return To_Vector
(D
);
4736 function vsumsws
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4737 VA
: constant VSI_View
:= To_View
(A
);
4738 VB
: constant VSI_View
:= To_View
(B
);
4740 Sum_Buffer
: SI64
:= 0;
4743 for J
in Vint_Range
'Range loop
4745 Sum_Buffer
:= Sum_Buffer
+ SI64
(VA
.Values
(J
));
4748 Sum_Buffer
:= Sum_Buffer
+ SI64
(VB
.Values
(Vint_Range
'Last));
4749 D
.Values
(Vint_Range
'Last) := LL_VSI_Operations
.Saturate
(Sum_Buffer
);
4750 return To_Vector
(D
);
4757 function vrfiz
(A
: LL_VF
) return LL_VF
is
4758 VA
: constant VF_View
:= To_View
(A
);
4761 for J
in Vfloat_Range
'Range loop
4762 D
.Values
(J
) := C_float
(Rnd_To_FPI_Trunc
(F64
(VA
.Values
(J
))));
4765 return To_Vector
(D
);
4772 function vupkhsb
(A
: LL_VSC
) return LL_VSS
is
4773 VA
: constant VSC_View
:= To_View
(A
);
4776 D
.Values
:= LL_VSC_LL_VSS_Operations
.vupkxsx
(VA
.Values
, 0);
4777 return To_Vector
(D
);
4784 function vupkhsh
(A
: LL_VSS
) return LL_VSI
is
4785 VA
: constant VSS_View
:= To_View
(A
);
4788 D
.Values
:= LL_VSS_LL_VSI_Operations
.vupkxsx
(VA
.Values
, 0);
4789 return To_Vector
(D
);
4796 function vupkxpx
(A
: LL_VSS
; Offset
: Natural) return LL_VSI
;
4797 -- For vupkhpx and vupklpx (depending on Offset)
4799 function vupkxpx
(A
: LL_VSS
; Offset
: Natural) return LL_VSI
is
4800 VA
: constant VUS_View
:= To_View
(To_LL_VUS
(A
));
4806 function Sign_Extend
(X
: Unsigned_1
) return unsigned_char
;
4808 function Sign_Extend
(X
: Unsigned_1
) return unsigned_char
is
4818 for J
in Vint_Range
'Range loop
4819 K
:= Vshort_Range
(Integer (J
)
4820 - Integer (Vint_Range
'First)
4821 + Integer (Vshort_Range
'First)
4823 P16
:= To_Pixel
(VA
.Values
(K
));
4824 P32
.T
:= Sign_Extend
(P16
.T
);
4825 P32
.R
:= unsigned_char
(P16
.R
);
4826 P32
.G
:= unsigned_char
(P16
.G
);
4827 P32
.B
:= unsigned_char
(P16
.B
);
4828 D
.Values
(J
) := To_unsigned_int
(P32
);
4831 return To_LL_VSI
(To_Vector
(D
));
4838 function vupkhpx
(A
: LL_VSS
) return LL_VSI
is
4840 return vupkxpx
(A
, 0);
4847 function vupklsb
(A
: LL_VSC
) return LL_VSS
is
4848 VA
: constant VSC_View
:= To_View
(A
);
4852 LL_VSC_LL_VSS_Operations
.vupkxsx
(VA
.Values
,
4853 Varray_signed_short
'Length);
4854 return To_Vector
(D
);
4861 function vupklsh
(A
: LL_VSS
) return LL_VSI
is
4862 VA
: constant VSS_View
:= To_View
(A
);
4866 LL_VSS_LL_VSI_Operations
.vupkxsx
(VA
.Values
,
4867 Varray_signed_int
'Length);
4868 return To_Vector
(D
);
4875 function vupklpx
(A
: LL_VSS
) return LL_VSI
is
4877 return vupkxpx
(A
, Varray_signed_int
'Length);
4884 function vxor
(A
: LL_VSI
; B
: LL_VSI
) return LL_VSI
is
4885 VA
: constant VUI_View
:= To_View
(To_LL_VUI
(A
));
4886 VB
: constant VUI_View
:= To_View
(To_LL_VUI
(B
));
4890 for J
in Vint_Range
'Range loop
4891 D
.Values
(J
) := VA
.Values
(J
) xor VB
.Values
(J
);
4894 return To_LL_VSI
(To_Vector
(D
));
4901 function vcmpequb_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4904 D
:= vcmpequb
(B
, C
);
4905 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4912 function vcmpequh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4915 D
:= vcmpequh
(B
, C
);
4916 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4923 function vcmpequw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
4926 D
:= vcmpequw
(B
, C
);
4927 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4934 function vcmpeqfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
4937 D
:= vcmpeqfp
(B
, C
);
4938 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4945 function vcmpgtub_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4948 D
:= vcmpgtub
(B
, C
);
4949 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4956 function vcmpgtuh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4959 D
:= vcmpgtuh
(B
, C
);
4960 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4967 function vcmpgtuw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
4970 D
:= vcmpgtuw
(B
, C
);
4971 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4978 function vcmpgtsb_p
(A
: c_int
; B
: LL_VSC
; C
: LL_VSC
) return c_int
is
4981 D
:= vcmpgtsb
(B
, C
);
4982 return LL_VSC_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
4989 function vcmpgtsh_p
(A
: c_int
; B
: LL_VSS
; C
: LL_VSS
) return c_int
is
4992 D
:= vcmpgtsh
(B
, C
);
4993 return LL_VSS_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5000 function vcmpgtsw_p
(A
: c_int
; B
: LL_VSI
; C
: LL_VSI
) return c_int
is
5003 D
:= vcmpgtsw
(B
, C
);
5004 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5011 function vcmpgefp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
5014 D
:= vcmpgefp
(B
, C
);
5015 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5022 function vcmpgtfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
5025 D
:= vcmpgtfp
(B
, C
);
5026 return LL_VSI_Operations
.Check_CR6
(A
, To_View
(D
).Values
);
5033 function vcmpbfp_p
(A
: c_int
; B
: LL_VF
; C
: LL_VF
) return c_int
is
5036 D
:= To_View
(vcmpbfp
(B
, C
));
5038 for J
in Vint_Range
'Range loop
5039 -- vcmpbfp is not returning the usual bool vector; do the conversion
5040 if D
.Values
(J
) = 0 then
5041 D
.Values
(J
) := Signed_Bool_False
;
5043 D
.Values
(J
) := Signed_Bool_True
;
5047 return LL_VSI_Operations
.Check_CR6
(A
, D
.Values
);
5050 end GNAT
.Altivec
.Low_Level_Vectors
;