2016-10-26 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / ada / g-alleve.adb
blob962401d98856d41caf4481c8901fa2ea5dc8ef0b
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
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 --
6 -- --
7 -- B o d y --
8 -- (Soft Binding Version) --
9 -- --
10 -- Copyright (C) 2004-2015, Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 3, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- --
19 -- As a special exception under Section 7 of GPL version 3, you are granted --
20 -- additional permissions described in the GCC Runtime Library Exception, --
21 -- version 3.1, as published by the Free Software Foundation. --
22 -- --
23 -- You should have received a copy of the GNU General Public License and --
24 -- a copy of the GCC Runtime Library Exception along with this program; --
25 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
26 -- <http://www.gnu.org/licenses/>. --
27 -- --
28 -- GNAT was originally developed by the GNAT team at New York University. --
29 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 -- --
31 ------------------------------------------------------------------------------
33 -- ??? What is exactly needed for the soft case is still a bit unclear on
34 -- some accounts. The expected functional equivalence with the Hard binding
35 -- might require tricky things to be done on some targets.
37 -- Examples that come to mind are endianness variations or differences in the
38 -- base FP model while we need the operation results to be the same as what
39 -- the real AltiVec instructions would do on a PowerPC.
41 with Ada.Numerics.Generic_Elementary_Functions;
42 with Interfaces; use Interfaces;
43 with System.Storage_Elements; use System.Storage_Elements;
45 with GNAT.Altivec.Conversions; use GNAT.Altivec.Conversions;
46 with GNAT.Altivec.Low_Level_Interface; use GNAT.Altivec.Low_Level_Interface;
48 package body GNAT.Altivec.Low_Level_Vectors is
50 -- Pixel types. As defined in [PIM-2.1 Data types]:
51 -- A 16-bit pixel is 1/5/5/5;
52 -- A 32-bit pixel is 8/8/8/8.
53 -- We use the following records as an intermediate representation, to
54 -- ease computation.
56 type Unsigned_1 is mod 2 ** 1;
57 type Unsigned_5 is mod 2 ** 5;
59 type Pixel_16 is record
60 T : Unsigned_1;
61 R : Unsigned_5;
62 G : Unsigned_5;
63 B : Unsigned_5;
64 end record;
66 type Pixel_32 is record
67 T : unsigned_char;
68 R : unsigned_char;
69 G : unsigned_char;
70 B : unsigned_char;
71 end record;
73 -- Conversions to/from the pixel records to the integer types that are
74 -- actually stored into the pixel vectors:
76 function To_Pixel (Source : unsigned_short) return Pixel_16;
77 function To_unsigned_short (Source : Pixel_16) return unsigned_short;
78 function To_Pixel (Source : unsigned_int) return Pixel_32;
79 function To_unsigned_int (Source : Pixel_32) return unsigned_int;
81 package C_float_Operations is
82 new Ada.Numerics.Generic_Elementary_Functions (C_float);
84 -- Model of the Vector Status and Control Register (VSCR), as
85 -- defined in [PIM-4.1 Vector Status and Control Register]:
87 VSCR : unsigned_int;
89 -- Positions of the flags in VSCR(0 .. 31):
91 NJ_POS : constant := 15;
92 SAT_POS : constant := 31;
94 -- To control overflows, integer operations are done on 64-bit types:
96 SINT64_MIN : constant := -2 ** 63;
97 SINT64_MAX : constant := 2 ** 63 - 1;
98 UINT64_MAX : constant := 2 ** 64 - 1;
100 type SI64 is range SINT64_MIN .. SINT64_MAX;
101 type UI64 is mod UINT64_MAX + 1;
103 type F64 is digits 15
104 range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
106 function Bits
107 (X : unsigned_int;
108 Low : Natural;
109 High : Natural) return unsigned_int;
111 function Bits
112 (X : unsigned_short;
113 Low : Natural;
114 High : Natural) return unsigned_short;
116 function Bits
117 (X : unsigned_char;
118 Low : Natural;
119 High : Natural) return unsigned_char;
121 function Write_Bit
122 (X : unsigned_int;
123 Where : Natural;
124 Value : Unsigned_1) return unsigned_int;
126 function Write_Bit
127 (X : unsigned_short;
128 Where : Natural;
129 Value : Unsigned_1) return unsigned_short;
131 function Write_Bit
132 (X : unsigned_char;
133 Where : Natural;
134 Value : Unsigned_1) return unsigned_char;
136 function NJ_Truncate (X : C_float) return C_float;
137 -- If NJ and A is a denormalized number, return zero
139 function Bound_Align
140 (X : Integer_Address;
141 Y : Integer_Address) return Integer_Address;
142 -- [PIM-4.3 Notations and Conventions]
143 -- Align X in a y-byte boundary and return the result
145 function Rnd_To_FP_Nearest (X : F64) return C_float;
146 -- [PIM-4.3 Notations and Conventions]
148 function Rnd_To_FPI_Near (X : F64) return F64;
150 function Rnd_To_FPI_Trunc (X : F64) return F64;
152 function FP_Recip_Est (X : C_float) return C_float;
153 -- [PIM-4.3 Notations and Conventions]
154 -- 12-bit accurate floating-point estimate of 1/x
156 function ROTL
157 (Value : unsigned_char;
158 Amount : Natural) return unsigned_char;
159 -- [PIM-4.3 Notations and Conventions]
160 -- Rotate left
162 function ROTL
163 (Value : unsigned_short;
164 Amount : Natural) return unsigned_short;
166 function ROTL
167 (Value : unsigned_int;
168 Amount : Natural) return unsigned_int;
170 function Recip_SQRT_Est (X : C_float) return C_float;
172 function Shift_Left
173 (Value : unsigned_char;
174 Amount : Natural) return unsigned_char;
175 -- [PIM-4.3 Notations and Conventions]
176 -- Shift left
178 function Shift_Left
179 (Value : unsigned_short;
180 Amount : Natural) return unsigned_short;
182 function Shift_Left
183 (Value : unsigned_int;
184 Amount : Natural) return unsigned_int;
186 function Shift_Right
187 (Value : unsigned_char;
188 Amount : Natural) return unsigned_char;
189 -- [PIM-4.3 Notations and Conventions]
190 -- Shift Right
192 function Shift_Right
193 (Value : unsigned_short;
194 Amount : Natural) return unsigned_short;
196 function Shift_Right
197 (Value : unsigned_int;
198 Amount : Natural) return unsigned_int;
200 Signed_Bool_False : constant := 0;
201 Signed_Bool_True : constant := -1;
203 ------------------------------
204 -- Signed_Operations (spec) --
205 ------------------------------
207 generic
208 type Component_Type is range <>;
209 type Index_Type is range <>;
210 type Varray_Type is array (Index_Type) of Component_Type;
212 package Signed_Operations is
214 function Modular_Result (X : SI64) return Component_Type;
216 function Saturate (X : SI64) return Component_Type;
218 function Saturate (X : F64) return Component_Type;
220 function Sign_Extend (X : c_int) return Component_Type;
221 -- [PIM-4.3 Notations and Conventions]
222 -- Sign-extend X
224 function abs_vxi (A : Varray_Type) return Varray_Type;
225 pragma Convention (LL_Altivec, abs_vxi);
227 function abss_vxi (A : Varray_Type) return Varray_Type;
228 pragma Convention (LL_Altivec, abss_vxi);
230 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
231 pragma Convention (LL_Altivec, vaddsxs);
233 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
234 pragma Convention (LL_Altivec, vavgsx);
236 function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
237 pragma Convention (LL_Altivec, vcmpgtsx);
239 function lvexx (A : c_long; B : c_ptr) return Varray_Type;
240 pragma Convention (LL_Altivec, lvexx);
242 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
243 pragma Convention (LL_Altivec, vmaxsx);
245 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
246 pragma Convention (LL_Altivec, vmrghx);
248 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
249 pragma Convention (LL_Altivec, vmrglx);
251 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
252 pragma Convention (LL_Altivec, vminsx);
254 function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
255 pragma Convention (LL_Altivec, vspltx);
257 function vspltisx (A : c_int) return Varray_Type;
258 pragma Convention (LL_Altivec, vspltisx);
260 type Bit_Operation is
261 access function
262 (Value : Component_Type;
263 Amount : Natural) return Component_Type;
265 function vsrax
266 (A : Varray_Type;
267 B : Varray_Type;
268 Shift_Func : Bit_Operation) return Varray_Type;
270 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
271 pragma Convention (LL_Altivec, stvexx);
273 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
274 pragma Convention (LL_Altivec, vsubsxs);
276 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
277 -- If D is the result of a vcmp operation and A the flag for
278 -- the kind of operation (e.g CR6_LT), check the predicate
279 -- that corresponds to this flag.
281 end Signed_Operations;
283 ------------------------------
284 -- Signed_Operations (body) --
285 ------------------------------
287 package body Signed_Operations is
289 Bool_True : constant Component_Type := Signed_Bool_True;
290 Bool_False : constant Component_Type := Signed_Bool_False;
292 Number_Of_Elements : constant Integer :=
293 VECTOR_BIT / Component_Type'Size;
295 --------------------
296 -- Modular_Result --
297 --------------------
299 function Modular_Result (X : SI64) return Component_Type is
300 D : Component_Type;
302 begin
303 if X > 0 then
304 D := Component_Type (UI64 (X)
305 mod (UI64 (Component_Type'Last) + 1));
306 else
307 D := Component_Type ((-(UI64 (-X)
308 mod (UI64 (Component_Type'Last) + 1))));
309 end if;
311 return D;
312 end Modular_Result;
314 --------------
315 -- Saturate --
316 --------------
318 function Saturate (X : SI64) return Component_Type is
319 D : Component_Type;
321 begin
322 -- Saturation, as defined in
323 -- [PIM-4.1 Vector Status and Control Register]
325 D := Component_Type (SI64'Max
326 (SI64 (Component_Type'First),
327 SI64'Min
328 (SI64 (Component_Type'Last),
329 X)));
331 if SI64 (D) /= X then
332 VSCR := Write_Bit (VSCR, SAT_POS, 1);
333 end if;
335 return D;
336 end Saturate;
338 function Saturate (X : F64) return Component_Type is
339 D : Component_Type;
341 begin
342 -- Saturation, as defined in
343 -- [PIM-4.1 Vector Status and Control Register]
345 D := Component_Type (F64'Max
346 (F64 (Component_Type'First),
347 F64'Min
348 (F64 (Component_Type'Last),
349 X)));
351 if F64 (D) /= X then
352 VSCR := Write_Bit (VSCR, SAT_POS, 1);
353 end if;
355 return D;
356 end Saturate;
358 -----------------
359 -- Sign_Extend --
360 -----------------
362 function Sign_Extend (X : c_int) return Component_Type is
363 begin
364 -- X is usually a 5-bits literal. In the case of the simulator,
365 -- it is an integral parameter, so sign extension is straightforward.
367 return Component_Type (X);
368 end Sign_Extend;
370 -------------
371 -- abs_vxi --
372 -------------
374 function abs_vxi (A : Varray_Type) return Varray_Type is
375 D : Varray_Type;
377 begin
378 for K in Varray_Type'Range loop
379 D (K) := (if A (K) /= Component_Type'First
380 then abs (A (K)) else Component_Type'First);
381 end loop;
383 return D;
384 end abs_vxi;
386 --------------
387 -- abss_vxi --
388 --------------
390 function abss_vxi (A : Varray_Type) return Varray_Type is
391 D : Varray_Type;
393 begin
394 for K in Varray_Type'Range loop
395 D (K) := Saturate (abs (SI64 (A (K))));
396 end loop;
398 return D;
399 end abss_vxi;
401 -------------
402 -- vaddsxs --
403 -------------
405 function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
406 D : Varray_Type;
408 begin
409 for J in Varray_Type'Range loop
410 D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
411 end loop;
413 return D;
414 end vaddsxs;
416 ------------
417 -- vavgsx --
418 ------------
420 function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
421 D : Varray_Type;
423 begin
424 for J in Varray_Type'Range loop
425 D (J) := Component_Type ((SI64 (A (J)) + SI64 (B (J)) + 1) / 2);
426 end loop;
428 return D;
429 end vavgsx;
431 --------------
432 -- vcmpgtsx --
433 --------------
435 function vcmpgtsx
436 (A : Varray_Type;
437 B : Varray_Type) return Varray_Type
439 D : Varray_Type;
441 begin
442 for J in Varray_Type'Range loop
443 D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
444 end loop;
446 return D;
447 end vcmpgtsx;
449 -----------
450 -- lvexx --
451 -----------
453 function lvexx (A : c_long; B : c_ptr) return Varray_Type is
454 D : Varray_Type;
455 S : Integer;
456 EA : Integer_Address;
457 J : Index_Type;
459 begin
460 S := 16 / Number_Of_Elements;
461 EA := Bound_Align (Integer_Address (A) + To_Integer (B),
462 Integer_Address (S));
463 J := Index_Type (((EA mod 16) / Integer_Address (S))
464 + Integer_Address (Index_Type'First));
466 declare
467 Component : Component_Type;
468 for Component'Address use To_Address (EA);
469 begin
470 D (J) := Component;
471 end;
473 return D;
474 end lvexx;
476 ------------
477 -- vmaxsx --
478 ------------
480 function vmaxsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
481 D : Varray_Type;
483 begin
484 for J in Varray_Type'Range loop
485 D (J) := (if A (J) > B (J) then A (J) else B (J));
486 end loop;
488 return D;
489 end vmaxsx;
491 ------------
492 -- vmrghx --
493 ------------
495 function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type is
496 D : Varray_Type;
497 Offset : constant Integer := Integer (Index_Type'First);
498 M : constant Integer := Number_Of_Elements / 2;
500 begin
501 for J in 0 .. M - 1 loop
502 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset));
503 D (Index_Type (2 * J + Offset + 1)) := B (Index_Type (J + Offset));
504 end loop;
506 return D;
507 end vmrghx;
509 ------------
510 -- vmrglx --
511 ------------
513 function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type is
514 D : Varray_Type;
515 Offset : constant Integer := Integer (Index_Type'First);
516 M : constant Integer := Number_Of_Elements / 2;
518 begin
519 for J in 0 .. M - 1 loop
520 D (Index_Type (2 * J + Offset)) := A (Index_Type (J + Offset + M));
521 D (Index_Type (2 * J + Offset + 1)) :=
522 B (Index_Type (J + Offset + M));
523 end loop;
525 return D;
526 end vmrglx;
528 ------------
529 -- vminsx --
530 ------------
532 function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
533 D : Varray_Type;
535 begin
536 for J in Varray_Type'Range loop
537 D (J) := (if A (J) < B (J) then A (J) else B (J));
538 end loop;
540 return D;
541 end vminsx;
543 ------------
544 -- vspltx --
545 ------------
547 function vspltx (A : Varray_Type; B : c_int) return Varray_Type is
548 J : constant Integer :=
549 Integer (B) mod Number_Of_Elements
550 + Integer (Varray_Type'First);
551 D : Varray_Type;
553 begin
554 for K in Varray_Type'Range loop
555 D (K) := A (Index_Type (J));
556 end loop;
558 return D;
559 end vspltx;
561 --------------
562 -- vspltisx --
563 --------------
565 function vspltisx (A : c_int) return Varray_Type is
566 D : Varray_Type;
568 begin
569 for J in Varray_Type'Range loop
570 D (J) := Sign_Extend (A);
571 end loop;
573 return D;
574 end vspltisx;
576 -----------
577 -- vsrax --
578 -----------
580 function vsrax
581 (A : Varray_Type;
582 B : Varray_Type;
583 Shift_Func : Bit_Operation) return Varray_Type
585 D : Varray_Type;
586 S : constant Component_Type :=
587 Component_Type (128 / Number_Of_Elements);
589 begin
590 for J in Varray_Type'Range loop
591 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
592 end loop;
594 return D;
595 end vsrax;
597 ------------
598 -- stvexx --
599 ------------
601 procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
602 S : Integer;
603 EA : Integer_Address;
604 J : Index_Type;
606 begin
607 S := 16 / Number_Of_Elements;
608 EA := Bound_Align (Integer_Address (B) + To_Integer (C),
609 Integer_Address (S));
610 J := Index_Type ((EA mod 16) / Integer_Address (S)
611 + Integer_Address (Index_Type'First));
613 declare
614 Component : Component_Type;
615 for Component'Address use To_Address (EA);
616 begin
617 Component := A (J);
618 end;
619 end stvexx;
621 -------------
622 -- vsubsxs --
623 -------------
625 function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
626 D : Varray_Type;
628 begin
629 for J in Varray_Type'Range loop
630 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
631 end loop;
633 return D;
634 end vsubsxs;
636 ---------------
637 -- Check_CR6 --
638 ---------------
640 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
641 All_Element : Boolean := True;
642 Any_Element : Boolean := False;
644 begin
645 for J in Varray_Type'Range loop
646 All_Element := All_Element and then (D (J) = Bool_True);
647 Any_Element := Any_Element or else (D (J) = Bool_True);
648 end loop;
650 if A = CR6_LT then
651 if All_Element then
652 return 1;
653 else
654 return 0;
655 end if;
657 elsif A = CR6_EQ then
658 if not Any_Element then
659 return 1;
660 else
661 return 0;
662 end if;
664 elsif A = CR6_EQ_REV then
665 if Any_Element then
666 return 1;
667 else
668 return 0;
669 end if;
671 elsif A = CR6_LT_REV then
672 if not All_Element then
673 return 1;
674 else
675 return 0;
676 end if;
677 end if;
679 return 0;
680 end Check_CR6;
682 end Signed_Operations;
684 --------------------------------
685 -- Unsigned_Operations (spec) --
686 --------------------------------
688 generic
689 type Component_Type is mod <>;
690 type Index_Type is range <>;
691 type Varray_Type is array (Index_Type) of Component_Type;
693 package Unsigned_Operations is
695 function Bits
696 (X : Component_Type;
697 Low : Natural;
698 High : Natural) return Component_Type;
699 -- Return X [Low:High] as defined in [PIM-4.3 Notations and Conventions]
700 -- using big endian bit ordering.
702 function Write_Bit
703 (X : Component_Type;
704 Where : Natural;
705 Value : Unsigned_1) return Component_Type;
706 -- Write Value into X[Where:Where] (if it fits in) and return the result
707 -- (big endian bit ordering).
709 function Modular_Result (X : UI64) return Component_Type;
711 function Saturate (X : UI64) return Component_Type;
713 function Saturate (X : F64) return Component_Type;
715 function Saturate (X : SI64) return Component_Type;
717 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
719 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
721 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type;
723 function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
725 function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
727 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type;
729 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type;
731 type Bit_Operation is
732 access function
733 (Value : Component_Type;
734 Amount : Natural) return Component_Type;
736 function vrlx
737 (A : Varray_Type;
738 B : Varray_Type;
739 ROTL : Bit_Operation) return Varray_Type;
741 function vsxx
742 (A : Varray_Type;
743 B : Varray_Type;
744 Shift_Func : Bit_Operation) return Varray_Type;
745 -- Vector shift (left or right, depending on Shift_Func)
747 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
749 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
751 function Check_CR6 (A : c_int; D : Varray_Type) return c_int;
752 -- If D is the result of a vcmp operation and A the flag for
753 -- the kind of operation (e.g CR6_LT), check the predicate
754 -- that corresponds to this flag.
756 end Unsigned_Operations;
758 --------------------------------
759 -- Unsigned_Operations (body) --
760 --------------------------------
762 package body Unsigned_Operations is
764 Number_Of_Elements : constant Integer :=
765 VECTOR_BIT / Component_Type'Size;
767 Bool_True : constant Component_Type := Component_Type'Last;
768 Bool_False : constant Component_Type := 0;
770 --------------------
771 -- Modular_Result --
772 --------------------
774 function Modular_Result (X : UI64) return Component_Type is
775 D : Component_Type;
776 begin
777 D := Component_Type (X mod (UI64 (Component_Type'Last) + 1));
778 return D;
779 end Modular_Result;
781 --------------
782 -- Saturate --
783 --------------
785 function Saturate (X : UI64) return Component_Type is
786 D : Component_Type;
788 begin
789 -- Saturation, as defined in
790 -- [PIM-4.1 Vector Status and Control Register]
792 D := Component_Type (UI64'Max
793 (UI64 (Component_Type'First),
794 UI64'Min
795 (UI64 (Component_Type'Last),
796 X)));
798 if UI64 (D) /= X then
799 VSCR := Write_Bit (VSCR, SAT_POS, 1);
800 end if;
802 return D;
803 end Saturate;
805 function Saturate (X : SI64) return Component_Type is
806 D : Component_Type;
808 begin
809 -- Saturation, as defined in
810 -- [PIM-4.1 Vector Status and Control Register]
812 D := Component_Type (SI64'Max
813 (SI64 (Component_Type'First),
814 SI64'Min
815 (SI64 (Component_Type'Last),
816 X)));
818 if SI64 (D) /= X then
819 VSCR := Write_Bit (VSCR, SAT_POS, 1);
820 end if;
822 return D;
823 end Saturate;
825 function Saturate (X : F64) return Component_Type is
826 D : Component_Type;
828 begin
829 -- Saturation, as defined in
830 -- [PIM-4.1 Vector Status and Control Register]
832 D := Component_Type (F64'Max
833 (F64 (Component_Type'First),
834 F64'Min
835 (F64 (Component_Type'Last),
836 X)));
838 if F64 (D) /= X then
839 VSCR := Write_Bit (VSCR, SAT_POS, 1);
840 end if;
842 return D;
843 end Saturate;
845 ----------
846 -- Bits --
847 ----------
849 function Bits
850 (X : Component_Type;
851 Low : Natural;
852 High : Natural) return Component_Type
854 Mask : Component_Type := 0;
856 -- The Altivec ABI uses a big endian bit ordering, and we are
857 -- using little endian bit ordering for extracting bits:
859 Low_LE : constant Natural := Component_Type'Size - 1 - High;
860 High_LE : constant Natural := Component_Type'Size - 1 - Low;
862 begin
863 pragma Assert (Low <= Component_Type'Size);
864 pragma Assert (High <= Component_Type'Size);
866 for J in Low_LE .. High_LE loop
867 Mask := Mask or 2 ** J;
868 end loop;
870 return (X and Mask) / 2 ** Low_LE;
871 end Bits;
873 ---------------
874 -- Write_Bit --
875 ---------------
877 function Write_Bit
878 (X : Component_Type;
879 Where : Natural;
880 Value : Unsigned_1) return Component_Type
882 Result : Component_Type := 0;
884 -- The Altivec ABI uses a big endian bit ordering, and we are
885 -- using little endian bit ordering for extracting bits:
887 Where_LE : constant Natural := Component_Type'Size - 1 - Where;
889 begin
890 pragma Assert (Where < Component_Type'Size);
892 case Value is
893 when 1 =>
894 Result := X or 2 ** Where_LE;
895 when 0 =>
896 Result := X and not (2 ** Where_LE);
897 end case;
899 return Result;
900 end Write_Bit;
902 -------------
903 -- vadduxm --
904 -------------
906 function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
907 D : Varray_Type;
909 begin
910 for J in Varray_Type'Range loop
911 D (J) := A (J) + B (J);
912 end loop;
914 return D;
915 end vadduxm;
917 -------------
918 -- vadduxs --
919 -------------
921 function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
922 D : Varray_Type;
924 begin
925 for J in Varray_Type'Range loop
926 D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
927 end loop;
929 return D;
930 end vadduxs;
932 ------------
933 -- vavgux --
934 ------------
936 function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
937 D : Varray_Type;
939 begin
940 for J in Varray_Type'Range loop
941 D (J) := Component_Type ((UI64 (A (J)) + UI64 (B (J)) + 1) / 2);
942 end loop;
944 return D;
945 end vavgux;
947 --------------
948 -- vcmpequx --
949 --------------
951 function vcmpequx
952 (A : Varray_Type;
953 B : Varray_Type) return Varray_Type
955 D : Varray_Type;
957 begin
958 for J in Varray_Type'Range loop
959 D (J) := (if A (J) = B (J) then Bool_True else Bool_False);
960 end loop;
962 return D;
963 end vcmpequx;
965 --------------
966 -- vcmpgtux --
967 --------------
969 function vcmpgtux
970 (A : Varray_Type;
971 B : Varray_Type) return Varray_Type
973 D : Varray_Type;
974 begin
975 for J in Varray_Type'Range loop
976 D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
977 end loop;
979 return D;
980 end vcmpgtux;
982 ------------
983 -- vmaxux --
984 ------------
986 function vmaxux (A : Varray_Type; B : Varray_Type) return Varray_Type is
987 D : Varray_Type;
989 begin
990 for J in Varray_Type'Range loop
991 D (J) := (if A (J) > B (J) then A (J) else B (J));
992 end loop;
994 return D;
995 end vmaxux;
997 ------------
998 -- vminux --
999 ------------
1001 function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1002 D : Varray_Type;
1004 begin
1005 for J in Varray_Type'Range loop
1006 D (J) := (if A (J) < B (J) then A (J) else B (J));
1007 end loop;
1009 return D;
1010 end vminux;
1012 ----------
1013 -- vrlx --
1014 ----------
1016 function vrlx
1017 (A : Varray_Type;
1018 B : Varray_Type;
1019 ROTL : Bit_Operation) return Varray_Type
1021 D : Varray_Type;
1023 begin
1024 for J in Varray_Type'Range loop
1025 D (J) := ROTL (A (J), Natural (B (J)));
1026 end loop;
1028 return D;
1029 end vrlx;
1031 ----------
1032 -- vsxx --
1033 ----------
1035 function vsxx
1036 (A : Varray_Type;
1037 B : Varray_Type;
1038 Shift_Func : Bit_Operation) return Varray_Type
1040 D : Varray_Type;
1041 S : constant Component_Type :=
1042 Component_Type (128 / Number_Of_Elements);
1044 begin
1045 for J in Varray_Type'Range loop
1046 D (J) := Shift_Func (A (J), Natural (B (J) mod S));
1047 end loop;
1049 return D;
1050 end vsxx;
1052 -------------
1053 -- vsubuxm --
1054 -------------
1056 function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1057 D : Varray_Type;
1059 begin
1060 for J in Varray_Type'Range loop
1061 D (J) := A (J) - B (J);
1062 end loop;
1064 return D;
1065 end vsubuxm;
1067 -------------
1068 -- vsubuxs --
1069 -------------
1071 function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1072 D : Varray_Type;
1074 begin
1075 for J in Varray_Type'Range loop
1076 D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1077 end loop;
1079 return D;
1080 end vsubuxs;
1082 ---------------
1083 -- Check_CR6 --
1084 ---------------
1086 function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1087 All_Element : Boolean := True;
1088 Any_Element : Boolean := False;
1090 begin
1091 for J in Varray_Type'Range loop
1092 All_Element := All_Element and then (D (J) = Bool_True);
1093 Any_Element := Any_Element or else (D (J) = Bool_True);
1094 end loop;
1096 if A = CR6_LT then
1097 if All_Element then
1098 return 1;
1099 else
1100 return 0;
1101 end if;
1103 elsif A = CR6_EQ then
1104 if not Any_Element then
1105 return 1;
1106 else
1107 return 0;
1108 end if;
1110 elsif A = CR6_EQ_REV then
1111 if Any_Element then
1112 return 1;
1113 else
1114 return 0;
1115 end if;
1117 elsif A = CR6_LT_REV then
1118 if not All_Element then
1119 return 1;
1120 else
1121 return 0;
1122 end if;
1123 end if;
1125 return 0;
1126 end Check_CR6;
1128 end Unsigned_Operations;
1130 --------------------------------------
1131 -- Signed_Merging_Operations (spec) --
1132 --------------------------------------
1134 generic
1135 type Component_Type is range <>;
1136 type Index_Type is range <>;
1137 type Varray_Type is array (Index_Type) of Component_Type;
1138 type Double_Component_Type is range <>;
1139 type Double_Index_Type is range <>;
1140 type Double_Varray_Type is array (Double_Index_Type)
1141 of Double_Component_Type;
1143 package Signed_Merging_Operations is
1145 pragma Assert (Integer (Varray_Type'First)
1146 = Integer (Double_Varray_Type'First));
1147 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1148 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1150 function Saturate
1151 (X : Double_Component_Type) return Component_Type;
1153 function vmulxsx
1154 (Use_Even_Components : Boolean;
1155 A : Varray_Type;
1156 B : Varray_Type) return Double_Varray_Type;
1158 function vpksxss
1159 (A : Double_Varray_Type;
1160 B : Double_Varray_Type) return Varray_Type;
1161 pragma Convention (LL_Altivec, vpksxss);
1163 function vupkxsx
1164 (A : Varray_Type;
1165 Offset : Natural) return Double_Varray_Type;
1167 end Signed_Merging_Operations;
1169 --------------------------------------
1170 -- Signed_Merging_Operations (body) --
1171 --------------------------------------
1173 package body Signed_Merging_Operations is
1175 --------------
1176 -- Saturate --
1177 --------------
1179 function Saturate
1180 (X : Double_Component_Type) return Component_Type
1182 D : Component_Type;
1184 begin
1185 -- Saturation, as defined in
1186 -- [PIM-4.1 Vector Status and Control Register]
1188 D := Component_Type (Double_Component_Type'Max
1189 (Double_Component_Type (Component_Type'First),
1190 Double_Component_Type'Min
1191 (Double_Component_Type (Component_Type'Last),
1192 X)));
1194 if Double_Component_Type (D) /= X then
1195 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1196 end if;
1198 return D;
1199 end Saturate;
1201 -------------
1202 -- vmulsxs --
1203 -------------
1205 function vmulxsx
1206 (Use_Even_Components : Boolean;
1207 A : Varray_Type;
1208 B : Varray_Type) return Double_Varray_Type
1210 Double_Offset : Double_Index_Type;
1211 Offset : Index_Type;
1212 D : Double_Varray_Type;
1213 N : constant Integer :=
1214 Integer (Double_Index_Type'Last)
1215 - Integer (Double_Index_Type'First) + 1;
1217 begin
1219 for J in 0 .. N - 1 loop
1220 Offset :=
1221 Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
1222 Integer (Index_Type'First));
1224 Double_Offset :=
1225 Double_Index_Type (J + Integer (Double_Index_Type'First));
1226 D (Double_Offset) :=
1227 Double_Component_Type (A (Offset)) *
1228 Double_Component_Type (B (Offset));
1229 end loop;
1231 return D;
1232 end vmulxsx;
1234 -------------
1235 -- vpksxss --
1236 -------------
1238 function vpksxss
1239 (A : Double_Varray_Type;
1240 B : Double_Varray_Type) return Varray_Type
1242 N : constant Index_Type :=
1243 Index_Type (Double_Index_Type'Last);
1244 D : Varray_Type;
1245 Offset : Index_Type;
1246 Double_Offset : Double_Index_Type;
1248 begin
1249 for J in 0 .. N - 1 loop
1250 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1251 Double_Offset :=
1252 Double_Index_Type (Integer (J)
1253 + Integer (Double_Index_Type'First));
1254 D (Offset) := Saturate (A (Double_Offset));
1255 D (Offset + N) := Saturate (B (Double_Offset));
1256 end loop;
1258 return D;
1259 end vpksxss;
1261 -------------
1262 -- vupkxsx --
1263 -------------
1265 function vupkxsx
1266 (A : Varray_Type;
1267 Offset : Natural) return Double_Varray_Type
1269 K : Index_Type;
1270 D : Double_Varray_Type;
1272 begin
1273 for J in Double_Varray_Type'Range loop
1274 K := Index_Type (Integer (J)
1275 - Integer (Double_Index_Type'First)
1276 + Integer (Index_Type'First)
1277 + Offset);
1278 D (J) := Double_Component_Type (A (K));
1279 end loop;
1281 return D;
1282 end vupkxsx;
1284 end Signed_Merging_Operations;
1286 ----------------------------------------
1287 -- Unsigned_Merging_Operations (spec) --
1288 ----------------------------------------
1290 generic
1291 type Component_Type is mod <>;
1292 type Index_Type is range <>;
1293 type Varray_Type is array (Index_Type) of Component_Type;
1294 type Double_Component_Type is mod <>;
1295 type Double_Index_Type is range <>;
1296 type Double_Varray_Type is array (Double_Index_Type)
1297 of Double_Component_Type;
1299 package Unsigned_Merging_Operations is
1301 pragma Assert (Integer (Varray_Type'First)
1302 = Integer (Double_Varray_Type'First));
1303 pragma Assert (Varray_Type'Length = 2 * Double_Varray_Type'Length);
1304 pragma Assert (2 * Component_Type'Size = Double_Component_Type'Size);
1306 function UI_To_UI_Mod
1307 (X : Double_Component_Type;
1308 Y : Natural) return Component_Type;
1310 function Saturate (X : Double_Component_Type) return Component_Type;
1312 function vmulxux
1313 (Use_Even_Components : Boolean;
1314 A : Varray_Type;
1315 B : Varray_Type) return Double_Varray_Type;
1317 function vpkuxum
1318 (A : Double_Varray_Type;
1319 B : Double_Varray_Type) return Varray_Type;
1321 function vpkuxus
1322 (A : Double_Varray_Type;
1323 B : Double_Varray_Type) return Varray_Type;
1325 end Unsigned_Merging_Operations;
1327 ----------------------------------------
1328 -- Unsigned_Merging_Operations (body) --
1329 ----------------------------------------
1331 package body Unsigned_Merging_Operations is
1333 ------------------
1334 -- UI_To_UI_Mod --
1335 ------------------
1337 function UI_To_UI_Mod
1338 (X : Double_Component_Type;
1339 Y : Natural) return Component_Type is
1340 Z : Component_Type;
1341 begin
1342 Z := Component_Type (X mod 2 ** Y);
1343 return Z;
1344 end UI_To_UI_Mod;
1346 --------------
1347 -- Saturate --
1348 --------------
1350 function Saturate (X : Double_Component_Type) return Component_Type is
1351 D : Component_Type;
1353 begin
1354 -- Saturation, as defined in
1355 -- [PIM-4.1 Vector Status and Control Register]
1357 D := Component_Type (Double_Component_Type'Max
1358 (Double_Component_Type (Component_Type'First),
1359 Double_Component_Type'Min
1360 (Double_Component_Type (Component_Type'Last),
1361 X)));
1363 if Double_Component_Type (D) /= X then
1364 VSCR := Write_Bit (VSCR, SAT_POS, 1);
1365 end if;
1367 return D;
1368 end Saturate;
1370 -------------
1371 -- vmulxux --
1372 -------------
1374 function vmulxux
1375 (Use_Even_Components : Boolean;
1376 A : Varray_Type;
1377 B : Varray_Type) return Double_Varray_Type
1379 Double_Offset : Double_Index_Type;
1380 Offset : Index_Type;
1381 D : Double_Varray_Type;
1382 N : constant Integer :=
1383 Integer (Double_Index_Type'Last)
1384 - Integer (Double_Index_Type'First) + 1;
1386 begin
1387 for J in 0 .. N - 1 loop
1388 Offset :=
1389 Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
1390 Integer (Index_Type'First));
1392 Double_Offset :=
1393 Double_Index_Type (J + Integer (Double_Index_Type'First));
1394 D (Double_Offset) :=
1395 Double_Component_Type (A (Offset)) *
1396 Double_Component_Type (B (Offset));
1397 end loop;
1399 return D;
1400 end vmulxux;
1402 -------------
1403 -- vpkuxum --
1404 -------------
1406 function vpkuxum
1407 (A : Double_Varray_Type;
1408 B : Double_Varray_Type) return Varray_Type
1410 S : constant Natural :=
1411 Double_Component_Type'Size / 2;
1412 N : constant Index_Type :=
1413 Index_Type (Double_Index_Type'Last);
1414 D : Varray_Type;
1415 Offset : Index_Type;
1416 Double_Offset : Double_Index_Type;
1418 begin
1419 for J in 0 .. N - 1 loop
1420 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1421 Double_Offset :=
1422 Double_Index_Type (Integer (J)
1423 + Integer (Double_Index_Type'First));
1424 D (Offset) := UI_To_UI_Mod (A (Double_Offset), S);
1425 D (Offset + N) := UI_To_UI_Mod (B (Double_Offset), S);
1426 end loop;
1428 return D;
1429 end vpkuxum;
1431 -------------
1432 -- vpkuxus --
1433 -------------
1435 function vpkuxus
1436 (A : Double_Varray_Type;
1437 B : Double_Varray_Type) return Varray_Type
1439 N : constant Index_Type :=
1440 Index_Type (Double_Index_Type'Last);
1441 D : Varray_Type;
1442 Offset : Index_Type;
1443 Double_Offset : Double_Index_Type;
1445 begin
1446 for J in 0 .. N - 1 loop
1447 Offset := Index_Type (Integer (J) + Integer (Index_Type'First));
1448 Double_Offset :=
1449 Double_Index_Type (Integer (J)
1450 + Integer (Double_Index_Type'First));
1451 D (Offset) := Saturate (A (Double_Offset));
1452 D (Offset + N) := Saturate (B (Double_Offset));
1453 end loop;
1455 return D;
1456 end vpkuxus;
1458 end Unsigned_Merging_Operations;
1460 package LL_VSC_Operations is
1461 new Signed_Operations (signed_char,
1462 Vchar_Range,
1463 Varray_signed_char);
1465 package LL_VSS_Operations is
1466 new Signed_Operations (signed_short,
1467 Vshort_Range,
1468 Varray_signed_short);
1470 package LL_VSI_Operations is
1471 new Signed_Operations (signed_int,
1472 Vint_Range,
1473 Varray_signed_int);
1475 package LL_VUC_Operations is
1476 new Unsigned_Operations (unsigned_char,
1477 Vchar_Range,
1478 Varray_unsigned_char);
1480 package LL_VUS_Operations is
1481 new Unsigned_Operations (unsigned_short,
1482 Vshort_Range,
1483 Varray_unsigned_short);
1485 package LL_VUI_Operations is
1486 new Unsigned_Operations (unsigned_int,
1487 Vint_Range,
1488 Varray_unsigned_int);
1490 package LL_VSC_LL_VSS_Operations is
1491 new Signed_Merging_Operations (signed_char,
1492 Vchar_Range,
1493 Varray_signed_char,
1494 signed_short,
1495 Vshort_Range,
1496 Varray_signed_short);
1498 package LL_VSS_LL_VSI_Operations is
1499 new Signed_Merging_Operations (signed_short,
1500 Vshort_Range,
1501 Varray_signed_short,
1502 signed_int,
1503 Vint_Range,
1504 Varray_signed_int);
1506 package LL_VUC_LL_VUS_Operations is
1507 new Unsigned_Merging_Operations (unsigned_char,
1508 Vchar_Range,
1509 Varray_unsigned_char,
1510 unsigned_short,
1511 Vshort_Range,
1512 Varray_unsigned_short);
1514 package LL_VUS_LL_VUI_Operations is
1515 new Unsigned_Merging_Operations (unsigned_short,
1516 Vshort_Range,
1517 Varray_unsigned_short,
1518 unsigned_int,
1519 Vint_Range,
1520 Varray_unsigned_int);
1522 ----------
1523 -- Bits --
1524 ----------
1526 function Bits
1527 (X : unsigned_int;
1528 Low : Natural;
1529 High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1531 function Bits
1532 (X : unsigned_short;
1533 Low : Natural;
1534 High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1536 function Bits
1537 (X : unsigned_char;
1538 Low : Natural;
1539 High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1541 ---------------
1542 -- Write_Bit --
1543 ---------------
1545 function Write_Bit
1546 (X : unsigned_int;
1547 Where : Natural;
1548 Value : Unsigned_1) return unsigned_int
1549 renames LL_VUI_Operations.Write_Bit;
1551 function Write_Bit
1552 (X : unsigned_short;
1553 Where : Natural;
1554 Value : Unsigned_1) return unsigned_short
1555 renames LL_VUS_Operations.Write_Bit;
1557 function Write_Bit
1558 (X : unsigned_char;
1559 Where : Natural;
1560 Value : Unsigned_1) return unsigned_char
1561 renames LL_VUC_Operations.Write_Bit;
1563 -----------------
1564 -- Bound_Align --
1565 -----------------
1567 function Bound_Align
1568 (X : Integer_Address;
1569 Y : Integer_Address) return Integer_Address
1571 D : Integer_Address;
1572 begin
1573 D := X - X mod Y;
1574 return D;
1575 end Bound_Align;
1577 -----------------
1578 -- NJ_Truncate --
1579 -----------------
1581 function NJ_Truncate (X : C_float) return C_float is
1582 D : C_float;
1584 begin
1585 if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
1586 and then abs (X) < 2.0 ** (-126)
1587 then
1588 D := (if X < 0.0 then -0.0 else +0.0);
1589 else
1590 D := X;
1591 end if;
1593 return D;
1594 end NJ_Truncate;
1596 -----------------------
1597 -- Rnd_To_FP_Nearest --
1598 -----------------------
1600 function Rnd_To_FP_Nearest (X : F64) return C_float is
1601 begin
1602 return C_float (X);
1603 end Rnd_To_FP_Nearest;
1605 ---------------------
1606 -- Rnd_To_FPI_Near --
1607 ---------------------
1609 function Rnd_To_FPI_Near (X : F64) return F64 is
1610 Result : F64;
1611 Ceiling : F64;
1613 begin
1614 Result := F64 (SI64 (X));
1616 if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1618 -- Round to even
1620 Ceiling := F64'Ceiling (X);
1621 Result :=
1622 (if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling
1623 then Ceiling else Ceiling - 1.0);
1624 end if;
1626 return Result;
1627 end Rnd_To_FPI_Near;
1629 ----------------------
1630 -- Rnd_To_FPI_Trunc --
1631 ----------------------
1633 function Rnd_To_FPI_Trunc (X : F64) return F64 is
1634 Result : F64;
1636 begin
1637 Result := F64'Ceiling (X);
1639 -- Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1640 -- +Infinity
1642 if X > 0.0
1643 and then Result /= X
1644 then
1645 Result := Result - 1.0;
1646 end if;
1648 return Result;
1649 end Rnd_To_FPI_Trunc;
1651 ------------------
1652 -- FP_Recip_Est --
1653 ------------------
1655 function FP_Recip_Est (X : C_float) return C_float is
1656 begin
1657 -- ??? [PIM-4.4 vec_re] "For result that are not +0, -0, +Inf,
1658 -- -Inf, or QNaN, the estimate has a relative error no greater
1659 -- than one part in 4096, that is:
1660 -- Abs ((estimate - 1 / x) / (1 / x)) < = 1/4096"
1662 return NJ_Truncate (1.0 / NJ_Truncate (X));
1663 end FP_Recip_Est;
1665 ----------
1666 -- ROTL --
1667 ----------
1669 function ROTL
1670 (Value : unsigned_char;
1671 Amount : Natural) return unsigned_char
1673 Result : Unsigned_8;
1674 begin
1675 Result := Rotate_Left (Unsigned_8 (Value), Amount);
1676 return unsigned_char (Result);
1677 end ROTL;
1679 function ROTL
1680 (Value : unsigned_short;
1681 Amount : Natural) return unsigned_short
1683 Result : Unsigned_16;
1684 begin
1685 Result := Rotate_Left (Unsigned_16 (Value), Amount);
1686 return unsigned_short (Result);
1687 end ROTL;
1689 function ROTL
1690 (Value : unsigned_int;
1691 Amount : Natural) return unsigned_int
1693 Result : Unsigned_32;
1694 begin
1695 Result := Rotate_Left (Unsigned_32 (Value), Amount);
1696 return unsigned_int (Result);
1697 end ROTL;
1699 --------------------
1700 -- Recip_SQRT_Est --
1701 --------------------
1703 function Recip_SQRT_Est (X : C_float) return C_float is
1704 Result : C_float;
1706 begin
1707 -- ???
1708 -- [PIM-4.4 vec_rsqrte] the estimate has a relative error in precision
1709 -- no greater than one part in 4096, that is:
1710 -- abs ((estimate - 1 / sqrt (x)) / (1 / sqrt (x)) <= 1 / 4096"
1712 Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1713 return NJ_Truncate (Result);
1714 end Recip_SQRT_Est;
1716 ----------------
1717 -- Shift_Left --
1718 ----------------
1720 function Shift_Left
1721 (Value : unsigned_char;
1722 Amount : Natural) return unsigned_char
1724 Result : Unsigned_8;
1725 begin
1726 Result := Shift_Left (Unsigned_8 (Value), Amount);
1727 return unsigned_char (Result);
1728 end Shift_Left;
1730 function Shift_Left
1731 (Value : unsigned_short;
1732 Amount : Natural) return unsigned_short
1734 Result : Unsigned_16;
1735 begin
1736 Result := Shift_Left (Unsigned_16 (Value), Amount);
1737 return unsigned_short (Result);
1738 end Shift_Left;
1740 function Shift_Left
1741 (Value : unsigned_int;
1742 Amount : Natural) return unsigned_int
1744 Result : Unsigned_32;
1745 begin
1746 Result := Shift_Left (Unsigned_32 (Value), Amount);
1747 return unsigned_int (Result);
1748 end Shift_Left;
1750 -----------------
1751 -- Shift_Right --
1752 -----------------
1754 function Shift_Right
1755 (Value : unsigned_char;
1756 Amount : Natural) return unsigned_char
1758 Result : Unsigned_8;
1759 begin
1760 Result := Shift_Right (Unsigned_8 (Value), Amount);
1761 return unsigned_char (Result);
1762 end Shift_Right;
1764 function Shift_Right
1765 (Value : unsigned_short;
1766 Amount : Natural) return unsigned_short
1768 Result : Unsigned_16;
1769 begin
1770 Result := Shift_Right (Unsigned_16 (Value), Amount);
1771 return unsigned_short (Result);
1772 end Shift_Right;
1774 function Shift_Right
1775 (Value : unsigned_int;
1776 Amount : Natural) return unsigned_int
1778 Result : Unsigned_32;
1779 begin
1780 Result := Shift_Right (Unsigned_32 (Value), Amount);
1781 return unsigned_int (Result);
1782 end Shift_Right;
1784 -------------------
1785 -- Shift_Right_A --
1786 -------------------
1788 generic
1789 type Signed_Type is range <>;
1790 type Unsigned_Type is mod <>;
1791 with function Shift_Right (Value : Unsigned_Type; Amount : Natural)
1792 return Unsigned_Type;
1793 function Shift_Right_Arithmetic
1794 (Value : Signed_Type;
1795 Amount : Natural) return Signed_Type;
1797 function Shift_Right_Arithmetic
1798 (Value : Signed_Type;
1799 Amount : Natural) return Signed_Type
1801 begin
1802 if Value > 0 then
1803 return Signed_Type (Shift_Right (Unsigned_Type (Value), Amount));
1804 else
1805 return -Signed_Type (Shift_Right (Unsigned_Type (-Value - 1), Amount)
1806 + 1);
1807 end if;
1808 end Shift_Right_Arithmetic;
1810 function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1811 Unsigned_32,
1812 Shift_Right);
1814 function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1815 Unsigned_16,
1816 Shift_Right);
1818 function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1819 Unsigned_8,
1820 Shift_Right);
1821 --------------
1822 -- To_Pixel --
1823 --------------
1825 function To_Pixel (Source : unsigned_short) return Pixel_16 is
1827 -- This conversion should not depend on the host endianness;
1828 -- therefore, we cannot use an unchecked conversion.
1830 Target : Pixel_16;
1832 begin
1833 Target.T := Unsigned_1 (Bits (Source, 0, 0) mod 2 ** 1);
1834 Target.R := Unsigned_5 (Bits (Source, 1, 5) mod 2 ** 5);
1835 Target.G := Unsigned_5 (Bits (Source, 6, 10) mod 2 ** 5);
1836 Target.B := Unsigned_5 (Bits (Source, 11, 15) mod 2 ** 5);
1837 return Target;
1838 end To_Pixel;
1840 function To_Pixel (Source : unsigned_int) return Pixel_32 is
1842 -- This conversion should not depend on the host endianness;
1843 -- therefore, we cannot use an unchecked conversion.
1845 Target : Pixel_32;
1847 begin
1848 Target.T := unsigned_char (Bits (Source, 0, 7));
1849 Target.R := unsigned_char (Bits (Source, 8, 15));
1850 Target.G := unsigned_char (Bits (Source, 16, 23));
1851 Target.B := unsigned_char (Bits (Source, 24, 31));
1852 return Target;
1853 end To_Pixel;
1855 ---------------------
1856 -- To_unsigned_int --
1857 ---------------------
1859 function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1861 -- This conversion should not depend on the host endianness;
1862 -- therefore, we cannot use an unchecked conversion.
1863 -- It should also be the same result, value-wise, on two hosts
1864 -- with the same endianness.
1866 Target : unsigned_int := 0;
1868 begin
1869 -- In big endian bit ordering, Pixel_32 looks like:
1870 -- -------------------------------------
1871 -- | T | R | G | B |
1872 -- -------------------------------------
1873 -- 0 (MSB) 7 15 23 32
1875 -- Sizes of the components: (8/8/8/8)
1877 Target := Target or unsigned_int (Source.T);
1878 Target := Shift_Left (Target, 8);
1879 Target := Target or unsigned_int (Source.R);
1880 Target := Shift_Left (Target, 8);
1881 Target := Target or unsigned_int (Source.G);
1882 Target := Shift_Left (Target, 8);
1883 Target := Target or unsigned_int (Source.B);
1884 return Target;
1885 end To_unsigned_int;
1887 -----------------------
1888 -- To_unsigned_short --
1889 -----------------------
1891 function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1893 -- This conversion should not depend on the host endianness;
1894 -- therefore, we cannot use an unchecked conversion.
1895 -- It should also be the same result, value-wise, on two hosts
1896 -- with the same endianness.
1898 Target : unsigned_short := 0;
1900 begin
1901 -- In big endian bit ordering, Pixel_16 looks like:
1902 -- -------------------------------------
1903 -- | T | R | G | B |
1904 -- -------------------------------------
1905 -- 0 (MSB) 1 5 11 15
1907 -- Sizes of the components: (1/5/5/5)
1909 Target := Target or unsigned_short (Source.T);
1910 Target := Shift_Left (Target, 5);
1911 Target := Target or unsigned_short (Source.R);
1912 Target := Shift_Left (Target, 5);
1913 Target := Target or unsigned_short (Source.G);
1914 Target := Shift_Left (Target, 5);
1915 Target := Target or unsigned_short (Source.B);
1916 return Target;
1917 end To_unsigned_short;
1919 ---------------
1920 -- abs_v16qi --
1921 ---------------
1923 function abs_v16qi (A : LL_VSC) return LL_VSC is
1924 VA : constant VSC_View := To_View (A);
1925 begin
1926 return To_Vector ((Values =>
1927 LL_VSC_Operations.abs_vxi (VA.Values)));
1928 end abs_v16qi;
1930 --------------
1931 -- abs_v8hi --
1932 --------------
1934 function abs_v8hi (A : LL_VSS) return LL_VSS is
1935 VA : constant VSS_View := To_View (A);
1936 begin
1937 return To_Vector ((Values =>
1938 LL_VSS_Operations.abs_vxi (VA.Values)));
1939 end abs_v8hi;
1941 --------------
1942 -- abs_v4si --
1943 --------------
1945 function abs_v4si (A : LL_VSI) return LL_VSI is
1946 VA : constant VSI_View := To_View (A);
1947 begin
1948 return To_Vector ((Values =>
1949 LL_VSI_Operations.abs_vxi (VA.Values)));
1950 end abs_v4si;
1952 --------------
1953 -- abs_v4sf --
1954 --------------
1956 function abs_v4sf (A : LL_VF) return LL_VF is
1957 D : Varray_float;
1958 VA : constant VF_View := To_View (A);
1960 begin
1961 for J in Varray_float'Range loop
1962 D (J) := abs (VA.Values (J));
1963 end loop;
1965 return To_Vector ((Values => D));
1966 end abs_v4sf;
1968 ----------------
1969 -- abss_v16qi --
1970 ----------------
1972 function abss_v16qi (A : LL_VSC) return LL_VSC is
1973 VA : constant VSC_View := To_View (A);
1974 begin
1975 return To_Vector ((Values =>
1976 LL_VSC_Operations.abss_vxi (VA.Values)));
1977 end abss_v16qi;
1979 ---------------
1980 -- abss_v8hi --
1981 ---------------
1983 function abss_v8hi (A : LL_VSS) return LL_VSS is
1984 VA : constant VSS_View := To_View (A);
1985 begin
1986 return To_Vector ((Values =>
1987 LL_VSS_Operations.abss_vxi (VA.Values)));
1988 end abss_v8hi;
1990 ---------------
1991 -- abss_v4si --
1992 ---------------
1994 function abss_v4si (A : LL_VSI) return LL_VSI is
1995 VA : constant VSI_View := To_View (A);
1996 begin
1997 return To_Vector ((Values =>
1998 LL_VSI_Operations.abss_vxi (VA.Values)));
1999 end abss_v4si;
2001 -------------
2002 -- vaddubm --
2003 -------------
2005 function vaddubm (A : LL_VSC; B : LL_VSC) return LL_VSC is
2006 UC : constant GNAT.Altivec.Low_Level_Vectors.LL_VUC :=
2007 To_LL_VUC (A);
2008 VA : constant VUC_View :=
2009 To_View (UC);
2010 VB : constant VUC_View := To_View (To_LL_VUC (B));
2011 D : Varray_unsigned_char;
2013 begin
2014 D := LL_VUC_Operations.vadduxm (VA.Values, VB.Values);
2015 return To_LL_VSC (To_Vector (VUC_View'(Values => D)));
2016 end vaddubm;
2018 -------------
2019 -- vadduhm --
2020 -------------
2022 function vadduhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
2023 VA : constant VUS_View := To_View (To_LL_VUS (A));
2024 VB : constant VUS_View := To_View (To_LL_VUS (B));
2025 D : Varray_unsigned_short;
2027 begin
2028 D := LL_VUS_Operations.vadduxm (VA.Values, VB.Values);
2029 return To_LL_VSS (To_Vector (VUS_View'(Values => D)));
2030 end vadduhm;
2032 -------------
2033 -- vadduwm --
2034 -------------
2036 function vadduwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
2037 VA : constant VUI_View := To_View (To_LL_VUI (A));
2038 VB : constant VUI_View := To_View (To_LL_VUI (B));
2039 D : Varray_unsigned_int;
2041 begin
2042 D := LL_VUI_Operations.vadduxm (VA.Values, VB.Values);
2043 return To_LL_VSI (To_Vector (VUI_View'(Values => D)));
2044 end vadduwm;
2046 ------------
2047 -- vaddfp --
2048 ------------
2050 function vaddfp (A : LL_VF; B : LL_VF) return LL_VF is
2051 VA : constant VF_View := To_View (A);
2052 VB : constant VF_View := To_View (B);
2053 D : Varray_float;
2055 begin
2056 for J in Varray_float'Range loop
2057 D (J) := NJ_Truncate (NJ_Truncate (VA.Values (J))
2058 + NJ_Truncate (VB.Values (J)));
2059 end loop;
2061 return To_Vector (VF_View'(Values => D));
2062 end vaddfp;
2064 -------------
2065 -- vaddcuw --
2066 -------------
2068 function vaddcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2069 Addition_Result : UI64;
2070 D : VUI_View;
2071 VA : constant VUI_View := To_View (To_LL_VUI (A));
2072 VB : constant VUI_View := To_View (To_LL_VUI (B));
2074 begin
2075 for J in Varray_unsigned_int'Range loop
2076 Addition_Result := UI64 (VA.Values (J)) + UI64 (VB.Values (J));
2077 D.Values (J) :=
2078 (if Addition_Result > UI64 (unsigned_int'Last) then 1 else 0);
2079 end loop;
2081 return To_LL_VSI (To_Vector (D));
2082 end vaddcuw;
2084 -------------
2085 -- vaddubs --
2086 -------------
2088 function vaddubs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2089 VA : constant VUC_View := To_View (To_LL_VUC (A));
2090 VB : constant VUC_View := To_View (To_LL_VUC (B));
2092 begin
2093 return To_LL_VSC (To_Vector
2094 (VUC_View'(Values =>
2095 (LL_VUC_Operations.vadduxs
2096 (VA.Values,
2097 VB.Values)))));
2098 end vaddubs;
2100 -------------
2101 -- vaddsbs --
2102 -------------
2104 function vaddsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
2105 VA : constant VSC_View := To_View (A);
2106 VB : constant VSC_View := To_View (B);
2107 D : VSC_View;
2109 begin
2110 D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2111 return To_Vector (D);
2112 end vaddsbs;
2114 -------------
2115 -- vadduhs --
2116 -------------
2118 function vadduhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2119 VA : constant VUS_View := To_View (To_LL_VUS (A));
2120 VB : constant VUS_View := To_View (To_LL_VUS (B));
2121 D : VUS_View;
2123 begin
2124 D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2125 return To_LL_VSS (To_Vector (D));
2126 end vadduhs;
2128 -------------
2129 -- vaddshs --
2130 -------------
2132 function vaddshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
2133 VA : constant VSS_View := To_View (A);
2134 VB : constant VSS_View := To_View (B);
2135 D : VSS_View;
2137 begin
2138 D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2139 return To_Vector (D);
2140 end vaddshs;
2142 -------------
2143 -- vadduws --
2144 -------------
2146 function vadduws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2147 VA : constant VUI_View := To_View (To_LL_VUI (A));
2148 VB : constant VUI_View := To_View (To_LL_VUI (B));
2149 D : VUI_View;
2151 begin
2152 D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2153 return To_LL_VSI (To_Vector (D));
2154 end vadduws;
2156 -------------
2157 -- vaddsws --
2158 -------------
2160 function vaddsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
2161 VA : constant VSI_View := To_View (A);
2162 VB : constant VSI_View := To_View (B);
2163 D : VSI_View;
2165 begin
2166 D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2167 return To_Vector (D);
2168 end vaddsws;
2170 ----------
2171 -- vand --
2172 ----------
2174 function vand (A : LL_VSI; B : LL_VSI) return LL_VSI is
2175 VA : constant VUI_View := To_View (To_LL_VUI (A));
2176 VB : constant VUI_View := To_View (To_LL_VUI (B));
2177 D : VUI_View;
2179 begin
2180 for J in Varray_unsigned_int'Range loop
2181 D.Values (J) := VA.Values (J) and VB.Values (J);
2182 end loop;
2184 return To_LL_VSI (To_Vector (D));
2185 end vand;
2187 -----------
2188 -- vandc --
2189 -----------
2191 function vandc (A : LL_VSI; B : LL_VSI) return LL_VSI is
2192 VA : constant VUI_View := To_View (To_LL_VUI (A));
2193 VB : constant VUI_View := To_View (To_LL_VUI (B));
2194 D : VUI_View;
2196 begin
2197 for J in Varray_unsigned_int'Range loop
2198 D.Values (J) := VA.Values (J) and not VB.Values (J);
2199 end loop;
2201 return To_LL_VSI (To_Vector (D));
2202 end vandc;
2204 ------------
2205 -- vavgub --
2206 ------------
2208 function vavgub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2209 VA : constant VUC_View := To_View (To_LL_VUC (A));
2210 VB : constant VUC_View := To_View (To_LL_VUC (B));
2211 D : VUC_View;
2213 begin
2214 D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2215 return To_LL_VSC (To_Vector (D));
2216 end vavgub;
2218 ------------
2219 -- vavgsb --
2220 ------------
2222 function vavgsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2223 VA : constant VSC_View := To_View (A);
2224 VB : constant VSC_View := To_View (B);
2225 D : VSC_View;
2227 begin
2228 D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2229 return To_Vector (D);
2230 end vavgsb;
2232 ------------
2233 -- vavguh --
2234 ------------
2236 function vavguh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2237 VA : constant VUS_View := To_View (To_LL_VUS (A));
2238 VB : constant VUS_View := To_View (To_LL_VUS (B));
2239 D : VUS_View;
2241 begin
2242 D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2243 return To_LL_VSS (To_Vector (D));
2244 end vavguh;
2246 ------------
2247 -- vavgsh --
2248 ------------
2250 function vavgsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2251 VA : constant VSS_View := To_View (A);
2252 VB : constant VSS_View := To_View (B);
2253 D : VSS_View;
2255 begin
2256 D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2257 return To_Vector (D);
2258 end vavgsh;
2260 ------------
2261 -- vavguw --
2262 ------------
2264 function vavguw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2265 VA : constant VUI_View := To_View (To_LL_VUI (A));
2266 VB : constant VUI_View := To_View (To_LL_VUI (B));
2267 D : VUI_View;
2269 begin
2270 D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2271 return To_LL_VSI (To_Vector (D));
2272 end vavguw;
2274 ------------
2275 -- vavgsw --
2276 ------------
2278 function vavgsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2279 VA : constant VSI_View := To_View (A);
2280 VB : constant VSI_View := To_View (B);
2281 D : VSI_View;
2283 begin
2284 D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2285 return To_Vector (D);
2286 end vavgsw;
2288 -----------
2289 -- vrfip --
2290 -----------
2292 function vrfip (A : LL_VF) return LL_VF is
2293 VA : constant VF_View := To_View (A);
2294 D : VF_View;
2296 begin
2297 for J in Varray_float'Range loop
2299 -- If A (J) is infinite, D (J) should be infinite; With
2300 -- IEEE floating points, we can use 'Ceiling for that purpose.
2302 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2304 end loop;
2306 return To_Vector (D);
2307 end vrfip;
2309 -------------
2310 -- vcmpbfp --
2311 -------------
2313 function vcmpbfp (A : LL_VF; B : LL_VF) return LL_VSI is
2314 VA : constant VF_View := To_View (A);
2315 VB : constant VF_View := To_View (B);
2316 D : VUI_View;
2317 K : Vint_Range;
2319 begin
2320 for J in Varray_float'Range loop
2321 K := Vint_Range (J);
2322 D.Values (K) := 0;
2324 if NJ_Truncate (VB.Values (J)) < 0.0 then
2326 -- [PIM-4.4 vec_cmpb] "If any single-precision floating-point
2327 -- word element in B is negative; the corresponding element in A
2328 -- is out of bounds.
2330 D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2331 D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2333 else
2334 D.Values (K) :=
2335 (if NJ_Truncate (VA.Values (J)) <= NJ_Truncate (VB.Values (J))
2336 then Write_Bit (D.Values (K), 0, 0)
2337 else Write_Bit (D.Values (K), 0, 1));
2339 D.Values (K) :=
2340 (if NJ_Truncate (VA.Values (J)) >= -NJ_Truncate (VB.Values (J))
2341 then Write_Bit (D.Values (K), 1, 0)
2342 else Write_Bit (D.Values (K), 1, 1));
2343 end if;
2344 end loop;
2346 return To_LL_VSI (To_Vector (D));
2347 end vcmpbfp;
2349 --------------
2350 -- vcmpequb --
2351 --------------
2353 function vcmpequb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2354 VA : constant VUC_View := To_View (To_LL_VUC (A));
2355 VB : constant VUC_View := To_View (To_LL_VUC (B));
2356 D : VUC_View;
2358 begin
2359 D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2360 return To_LL_VSC (To_Vector (D));
2361 end vcmpequb;
2363 --------------
2364 -- vcmpequh --
2365 --------------
2367 function vcmpequh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2368 VA : constant VUS_View := To_View (To_LL_VUS (A));
2369 VB : constant VUS_View := To_View (To_LL_VUS (B));
2370 D : VUS_View;
2371 begin
2372 D.Values := LL_VUS_Operations.vcmpequx (VA.Values, VB.Values);
2373 return To_LL_VSS (To_Vector (D));
2374 end vcmpequh;
2376 --------------
2377 -- vcmpequw --
2378 --------------
2380 function vcmpequw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2381 VA : constant VUI_View := To_View (To_LL_VUI (A));
2382 VB : constant VUI_View := To_View (To_LL_VUI (B));
2383 D : VUI_View;
2384 begin
2385 D.Values := LL_VUI_Operations.vcmpequx (VA.Values, VB.Values);
2386 return To_LL_VSI (To_Vector (D));
2387 end vcmpequw;
2389 --------------
2390 -- vcmpeqfp --
2391 --------------
2393 function vcmpeqfp (A : LL_VF; B : LL_VF) return LL_VSI is
2394 VA : constant VF_View := To_View (A);
2395 VB : constant VF_View := To_View (B);
2396 D : VUI_View;
2398 begin
2399 for J in Varray_float'Range loop
2400 D.Values (Vint_Range (J)) :=
2401 (if VA.Values (J) = VB.Values (J) then unsigned_int'Last else 0);
2402 end loop;
2404 return To_LL_VSI (To_Vector (D));
2405 end vcmpeqfp;
2407 --------------
2408 -- vcmpgefp --
2409 --------------
2411 function vcmpgefp (A : LL_VF; B : LL_VF) return LL_VSI is
2412 VA : constant VF_View := To_View (A);
2413 VB : constant VF_View := To_View (B);
2414 D : VSI_View;
2416 begin
2417 for J in Varray_float'Range loop
2418 D.Values (Vint_Range (J)) :=
2419 (if VA.Values (J) >= VB.Values (J) then Signed_Bool_True
2420 else Signed_Bool_False);
2421 end loop;
2423 return To_Vector (D);
2424 end vcmpgefp;
2426 --------------
2427 -- vcmpgtub --
2428 --------------
2430 function vcmpgtub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2431 VA : constant VUC_View := To_View (To_LL_VUC (A));
2432 VB : constant VUC_View := To_View (To_LL_VUC (B));
2433 D : VUC_View;
2434 begin
2435 D.Values := LL_VUC_Operations.vcmpgtux (VA.Values, VB.Values);
2436 return To_LL_VSC (To_Vector (D));
2437 end vcmpgtub;
2439 --------------
2440 -- vcmpgtsb --
2441 --------------
2443 function vcmpgtsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2444 VA : constant VSC_View := To_View (A);
2445 VB : constant VSC_View := To_View (B);
2446 D : VSC_View;
2447 begin
2448 D.Values := LL_VSC_Operations.vcmpgtsx (VA.Values, VB.Values);
2449 return To_Vector (D);
2450 end vcmpgtsb;
2452 --------------
2453 -- vcmpgtuh --
2454 --------------
2456 function vcmpgtuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2457 VA : constant VUS_View := To_View (To_LL_VUS (A));
2458 VB : constant VUS_View := To_View (To_LL_VUS (B));
2459 D : VUS_View;
2460 begin
2461 D.Values := LL_VUS_Operations.vcmpgtux (VA.Values, VB.Values);
2462 return To_LL_VSS (To_Vector (D));
2463 end vcmpgtuh;
2465 --------------
2466 -- vcmpgtsh --
2467 --------------
2469 function vcmpgtsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2470 VA : constant VSS_View := To_View (A);
2471 VB : constant VSS_View := To_View (B);
2472 D : VSS_View;
2473 begin
2474 D.Values := LL_VSS_Operations.vcmpgtsx (VA.Values, VB.Values);
2475 return To_Vector (D);
2476 end vcmpgtsh;
2478 --------------
2479 -- vcmpgtuw --
2480 --------------
2482 function vcmpgtuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2483 VA : constant VUI_View := To_View (To_LL_VUI (A));
2484 VB : constant VUI_View := To_View (To_LL_VUI (B));
2485 D : VUI_View;
2486 begin
2487 D.Values := LL_VUI_Operations.vcmpgtux (VA.Values, VB.Values);
2488 return To_LL_VSI (To_Vector (D));
2489 end vcmpgtuw;
2491 --------------
2492 -- vcmpgtsw --
2493 --------------
2495 function vcmpgtsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2496 VA : constant VSI_View := To_View (A);
2497 VB : constant VSI_View := To_View (B);
2498 D : VSI_View;
2499 begin
2500 D.Values := LL_VSI_Operations.vcmpgtsx (VA.Values, VB.Values);
2501 return To_Vector (D);
2502 end vcmpgtsw;
2504 --------------
2505 -- vcmpgtfp --
2506 --------------
2508 function vcmpgtfp (A : LL_VF; B : LL_VF) return LL_VSI is
2509 VA : constant VF_View := To_View (A);
2510 VB : constant VF_View := To_View (B);
2511 D : VSI_View;
2513 begin
2514 for J in Varray_float'Range loop
2515 D.Values (Vint_Range (J)) :=
2516 (if NJ_Truncate (VA.Values (J)) > NJ_Truncate (VB.Values (J))
2517 then Signed_Bool_True else Signed_Bool_False);
2518 end loop;
2520 return To_Vector (D);
2521 end vcmpgtfp;
2523 -----------
2524 -- vcfux --
2525 -----------
2527 function vcfux (A : LL_VUI; B : c_int) return LL_VF is
2528 VA : constant VUI_View := To_View (A);
2529 D : VF_View;
2530 K : Vfloat_Range;
2532 begin
2533 for J in Varray_signed_int'Range loop
2534 K := Vfloat_Range (J);
2536 -- Note: The conversion to Integer is safe, as Integers are required
2537 -- to include the range -2 ** 15 + 1 .. 2 ** 15 + 1 and therefore
2538 -- include the range of B (should be 0 .. 255).
2540 D.Values (K) :=
2541 C_float (VA.Values (J)) / (2.0 ** Integer (B));
2542 end loop;
2544 return To_Vector (D);
2545 end vcfux;
2547 -----------
2548 -- vcfsx --
2549 -----------
2551 function vcfsx (A : LL_VSI; B : c_int) return LL_VF is
2552 VA : constant VSI_View := To_View (A);
2553 D : VF_View;
2554 K : Vfloat_Range;
2556 begin
2557 for J in Varray_signed_int'Range loop
2558 K := Vfloat_Range (J);
2559 D.Values (K) := C_float (VA.Values (J))
2560 / (2.0 ** Integer (B));
2561 end loop;
2563 return To_Vector (D);
2564 end vcfsx;
2566 ------------
2567 -- vctsxs --
2568 ------------
2570 function vctsxs (A : LL_VF; B : c_int) return LL_VSI is
2571 VA : constant VF_View := To_View (A);
2572 D : VSI_View;
2573 K : Vfloat_Range;
2575 begin
2576 for J in Varray_signed_int'Range loop
2577 K := Vfloat_Range (J);
2578 D.Values (J) :=
2579 LL_VSI_Operations.Saturate
2580 (F64 (NJ_Truncate (VA.Values (K)))
2581 * F64 (2.0 ** Integer (B)));
2582 end loop;
2584 return To_Vector (D);
2585 end vctsxs;
2587 ------------
2588 -- vctuxs --
2589 ------------
2591 function vctuxs (A : LL_VF; B : c_int) return LL_VUI is
2592 VA : constant VF_View := To_View (A);
2593 D : VUI_View;
2594 K : Vfloat_Range;
2596 begin
2597 for J in Varray_unsigned_int'Range loop
2598 K := Vfloat_Range (J);
2599 D.Values (J) :=
2600 LL_VUI_Operations.Saturate
2601 (F64 (NJ_Truncate (VA.Values (K)))
2602 * F64 (2.0 ** Integer (B)));
2603 end loop;
2605 return To_Vector (D);
2606 end vctuxs;
2608 ---------
2609 -- dss --
2610 ---------
2612 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2614 procedure dss (A : c_int) is
2615 pragma Unreferenced (A);
2616 begin
2617 null;
2618 end dss;
2620 ------------
2621 -- dssall --
2622 ------------
2624 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2626 procedure dssall is
2627 begin
2628 null;
2629 end dssall;
2631 ---------
2632 -- dst --
2633 ---------
2635 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2637 procedure dst (A : c_ptr; B : c_int; C : c_int) is
2638 pragma Unreferenced (A);
2639 pragma Unreferenced (B);
2640 pragma Unreferenced (C);
2641 begin
2642 null;
2643 end dst;
2645 -----------
2646 -- dstst --
2647 -----------
2649 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2651 procedure dstst (A : c_ptr; B : c_int; C : c_int) is
2652 pragma Unreferenced (A);
2653 pragma Unreferenced (B);
2654 pragma Unreferenced (C);
2655 begin
2656 null;
2657 end dstst;
2659 ------------
2660 -- dststt --
2661 ------------
2663 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2665 procedure dststt (A : c_ptr; B : c_int; C : c_int) is
2666 pragma Unreferenced (A);
2667 pragma Unreferenced (B);
2668 pragma Unreferenced (C);
2669 begin
2670 null;
2671 end dststt;
2673 ----------
2674 -- dstt --
2675 ----------
2677 -- No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2679 procedure dstt (A : c_ptr; B : c_int; C : c_int) is
2680 pragma Unreferenced (A);
2681 pragma Unreferenced (B);
2682 pragma Unreferenced (C);
2683 begin
2684 null;
2685 end dstt;
2687 --------------
2688 -- vexptefp --
2689 --------------
2691 function vexptefp (A : LL_VF) return LL_VF is
2692 use C_float_Operations;
2694 VA : constant VF_View := To_View (A);
2695 D : VF_View;
2697 begin
2698 for J in Varray_float'Range loop
2700 -- ??? Check the precision of the operation.
2701 -- As described in [PEM-6 vexptefp]:
2702 -- If theoretical_result is equal to 2 at the power of A (J) with
2703 -- infinite precision, we should have:
2704 -- abs ((D (J) - theoretical_result) / theoretical_result) <= 1/16
2706 D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2707 end loop;
2709 return To_Vector (D);
2710 end vexptefp;
2712 -----------
2713 -- vrfim --
2714 -----------
2716 function vrfim (A : LL_VF) return LL_VF is
2717 VA : constant VF_View := To_View (A);
2718 D : VF_View;
2720 begin
2721 for J in Varray_float'Range loop
2723 -- If A (J) is infinite, D (J) should be infinite; With
2724 -- IEEE floating point, we can use 'Ceiling for that purpose.
2726 D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2728 -- Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2729 -- +Infinity:
2731 if D.Values (J) /= VA.Values (J) then
2732 D.Values (J) := D.Values (J) - 1.0;
2733 end if;
2734 end loop;
2736 return To_Vector (D);
2737 end vrfim;
2739 ---------
2740 -- lvx --
2741 ---------
2743 function lvx (A : c_long; B : c_ptr) return LL_VSI is
2745 -- Simulate the altivec unit behavior regarding what Effective Address
2746 -- is accessed, stripping off the input address least significant bits
2747 -- wrt to vector alignment.
2749 -- On targets where VECTOR_ALIGNMENT is less than the vector size (16),
2750 -- an address within a vector is not necessarily rounded back at the
2751 -- vector start address. Besides, rounding on 16 makes no sense on such
2752 -- targets because the address of a properly aligned vector (that is,
2753 -- a proper multiple of VECTOR_ALIGNMENT) could be affected, which we
2754 -- want never to happen.
2756 EA : constant System.Address :=
2757 To_Address
2758 (Bound_Align
2759 (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2761 D : LL_VSI;
2762 for D'Address use EA;
2764 begin
2765 return D;
2766 end lvx;
2768 -----------
2769 -- lvebx --
2770 -----------
2772 function lvebx (A : c_long; B : c_ptr) return LL_VSC is
2773 D : VSC_View;
2774 begin
2775 D.Values := LL_VSC_Operations.lvexx (A, B);
2776 return To_Vector (D);
2777 end lvebx;
2779 -----------
2780 -- lvehx --
2781 -----------
2783 function lvehx (A : c_long; B : c_ptr) return LL_VSS is
2784 D : VSS_View;
2785 begin
2786 D.Values := LL_VSS_Operations.lvexx (A, B);
2787 return To_Vector (D);
2788 end lvehx;
2790 -----------
2791 -- lvewx --
2792 -----------
2794 function lvewx (A : c_long; B : c_ptr) return LL_VSI is
2795 D : VSI_View;
2796 begin
2797 D.Values := LL_VSI_Operations.lvexx (A, B);
2798 return To_Vector (D);
2799 end lvewx;
2801 ----------
2802 -- lvxl --
2803 ----------
2805 function lvxl (A : c_long; B : c_ptr) return LL_VSI renames
2806 lvx;
2808 -------------
2809 -- vlogefp --
2810 -------------
2812 function vlogefp (A : LL_VF) return LL_VF is
2813 VA : constant VF_View := To_View (A);
2814 D : VF_View;
2816 begin
2817 for J in Varray_float'Range loop
2819 -- ??? Check the precision of the operation.
2820 -- As described in [PEM-6 vlogefp]:
2821 -- If theorical_result is equal to the log2 of A (J) with
2822 -- infinite precision, we should have:
2823 -- abs (D (J) - theorical_result) <= 1/32,
2824 -- unless abs(D(J) - 1) <= 1/8.
2826 D.Values (J) :=
2827 C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2828 end loop;
2830 return To_Vector (D);
2831 end vlogefp;
2833 ----------
2834 -- lvsl --
2835 ----------
2837 function lvsl (A : c_long; B : c_ptr) return LL_VSC is
2838 type bit4_type is mod 16#F# + 1;
2839 for bit4_type'Alignment use 1;
2840 EA : Integer_Address;
2841 D : VUC_View;
2842 SH : bit4_type;
2844 begin
2845 EA := Integer_Address (A) + To_Integer (B);
2846 SH := bit4_type (EA mod 2 ** 4);
2848 for J in D.Values'Range loop
2849 D.Values (J) := unsigned_char (SH) + unsigned_char (J)
2850 - unsigned_char (D.Values'First);
2851 end loop;
2853 return To_LL_VSC (To_Vector (D));
2854 end lvsl;
2856 ----------
2857 -- lvsr --
2858 ----------
2860 function lvsr (A : c_long; B : c_ptr) return LL_VSC is
2861 type bit4_type is mod 16#F# + 1;
2862 for bit4_type'Alignment use 1;
2863 EA : Integer_Address;
2864 D : VUC_View;
2865 SH : bit4_type;
2867 begin
2868 EA := Integer_Address (A) + To_Integer (B);
2869 SH := bit4_type (EA mod 2 ** 4);
2871 for J in D.Values'Range loop
2872 D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2873 end loop;
2875 return To_LL_VSC (To_Vector (D));
2876 end lvsr;
2878 -------------
2879 -- vmaddfp --
2880 -------------
2882 function vmaddfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
2883 VA : constant VF_View := To_View (A);
2884 VB : constant VF_View := To_View (B);
2885 VC : constant VF_View := To_View (C);
2886 D : VF_View;
2888 begin
2889 for J in Varray_float'Range loop
2890 D.Values (J) :=
2891 Rnd_To_FP_Nearest (F64 (VA.Values (J))
2892 * F64 (VB.Values (J))
2893 + F64 (VC.Values (J)));
2894 end loop;
2896 return To_Vector (D);
2897 end vmaddfp;
2899 ---------------
2900 -- vmhaddshs --
2901 ---------------
2903 function vmhaddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
2904 VA : constant VSS_View := To_View (A);
2905 VB : constant VSS_View := To_View (B);
2906 VC : constant VSS_View := To_View (C);
2907 D : VSS_View;
2909 begin
2910 for J in Varray_signed_short'Range loop
2911 D.Values (J) := LL_VSS_Operations.Saturate
2912 ((SI64 (VA.Values (J)) * SI64 (VB.Values (J)))
2913 / SI64 (2 ** 15) + SI64 (VC.Values (J)));
2914 end loop;
2916 return To_Vector (D);
2917 end vmhaddshs;
2919 ------------
2920 -- vmaxub --
2921 ------------
2923 function vmaxub (A : LL_VSC; B : LL_VSC) return LL_VSC is
2924 VA : constant VUC_View := To_View (To_LL_VUC (A));
2925 VB : constant VUC_View := To_View (To_LL_VUC (B));
2926 D : VUC_View;
2927 begin
2928 D.Values := LL_VUC_Operations.vmaxux (VA.Values, VB.Values);
2929 return To_LL_VSC (To_Vector (D));
2930 end vmaxub;
2932 ------------
2933 -- vmaxsb --
2934 ------------
2936 function vmaxsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
2937 VA : constant VSC_View := To_View (A);
2938 VB : constant VSC_View := To_View (B);
2939 D : VSC_View;
2940 begin
2941 D.Values := LL_VSC_Operations.vmaxsx (VA.Values, VB.Values);
2942 return To_Vector (D);
2943 end vmaxsb;
2945 ------------
2946 -- vmaxuh --
2947 ------------
2949 function vmaxuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2950 VA : constant VUS_View := To_View (To_LL_VUS (A));
2951 VB : constant VUS_View := To_View (To_LL_VUS (B));
2952 D : VUS_View;
2953 begin
2954 D.Values := LL_VUS_Operations.vmaxux (VA.Values, VB.Values);
2955 return To_LL_VSS (To_Vector (D));
2956 end vmaxuh;
2958 ------------
2959 -- vmaxsh --
2960 ------------
2962 function vmaxsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
2963 VA : constant VSS_View := To_View (A);
2964 VB : constant VSS_View := To_View (B);
2965 D : VSS_View;
2966 begin
2967 D.Values := LL_VSS_Operations.vmaxsx (VA.Values, VB.Values);
2968 return To_Vector (D);
2969 end vmaxsh;
2971 ------------
2972 -- vmaxuw --
2973 ------------
2975 function vmaxuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2976 VA : constant VUI_View := To_View (To_LL_VUI (A));
2977 VB : constant VUI_View := To_View (To_LL_VUI (B));
2978 D : VUI_View;
2979 begin
2980 D.Values := LL_VUI_Operations.vmaxux (VA.Values, VB.Values);
2981 return To_LL_VSI (To_Vector (D));
2982 end vmaxuw;
2984 ------------
2985 -- vmaxsw --
2986 ------------
2988 function vmaxsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
2989 VA : constant VSI_View := To_View (A);
2990 VB : constant VSI_View := To_View (B);
2991 D : VSI_View;
2992 begin
2993 D.Values := LL_VSI_Operations.vmaxsx (VA.Values, VB.Values);
2994 return To_Vector (D);
2995 end vmaxsw;
2997 --------------
2998 -- vmaxsxfp --
2999 --------------
3001 function vmaxfp (A : LL_VF; B : LL_VF) return LL_VF is
3002 VA : constant VF_View := To_View (A);
3003 VB : constant VF_View := To_View (B);
3004 D : VF_View;
3006 begin
3007 for J in Varray_float'Range loop
3008 D.Values (J) := (if VA.Values (J) > VB.Values (J) then VA.Values (J)
3009 else VB.Values (J));
3010 end loop;
3012 return To_Vector (D);
3013 end vmaxfp;
3015 ------------
3016 -- vmrghb --
3017 ------------
3019 function vmrghb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3020 VA : constant VSC_View := To_View (A);
3021 VB : constant VSC_View := To_View (B);
3022 D : VSC_View;
3023 begin
3024 D.Values := LL_VSC_Operations.vmrghx (VA.Values, VB.Values);
3025 return To_Vector (D);
3026 end vmrghb;
3028 ------------
3029 -- vmrghh --
3030 ------------
3032 function vmrghh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3033 VA : constant VSS_View := To_View (A);
3034 VB : constant VSS_View := To_View (B);
3035 D : VSS_View;
3036 begin
3037 D.Values := LL_VSS_Operations.vmrghx (VA.Values, VB.Values);
3038 return To_Vector (D);
3039 end vmrghh;
3041 ------------
3042 -- vmrghw --
3043 ------------
3045 function vmrghw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3046 VA : constant VSI_View := To_View (A);
3047 VB : constant VSI_View := To_View (B);
3048 D : VSI_View;
3049 begin
3050 D.Values := LL_VSI_Operations.vmrghx (VA.Values, VB.Values);
3051 return To_Vector (D);
3052 end vmrghw;
3054 ------------
3055 -- vmrglb --
3056 ------------
3058 function vmrglb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3059 VA : constant VSC_View := To_View (A);
3060 VB : constant VSC_View := To_View (B);
3061 D : VSC_View;
3062 begin
3063 D.Values := LL_VSC_Operations.vmrglx (VA.Values, VB.Values);
3064 return To_Vector (D);
3065 end vmrglb;
3067 ------------
3068 -- vmrglh --
3069 ------------
3071 function vmrglh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3072 VA : constant VSS_View := To_View (A);
3073 VB : constant VSS_View := To_View (B);
3074 D : VSS_View;
3075 begin
3076 D.Values := LL_VSS_Operations.vmrglx (VA.Values, VB.Values);
3077 return To_Vector (D);
3078 end vmrglh;
3080 ------------
3081 -- vmrglw --
3082 ------------
3084 function vmrglw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3085 VA : constant VSI_View := To_View (A);
3086 VB : constant VSI_View := To_View (B);
3087 D : VSI_View;
3088 begin
3089 D.Values := LL_VSI_Operations.vmrglx (VA.Values, VB.Values);
3090 return To_Vector (D);
3091 end vmrglw;
3093 ------------
3094 -- mfvscr --
3095 ------------
3097 function mfvscr return LL_VSS is
3098 D : VUS_View;
3099 begin
3100 for J in Varray_unsigned_short'Range loop
3101 D.Values (J) := 0;
3102 end loop;
3104 D.Values (Varray_unsigned_short'Last) :=
3105 unsigned_short (VSCR mod 2 ** unsigned_short'Size);
3106 D.Values (Varray_unsigned_short'Last - 1) :=
3107 unsigned_short (VSCR / 2 ** unsigned_short'Size);
3108 return To_LL_VSS (To_Vector (D));
3109 end mfvscr;
3111 ------------
3112 -- vminfp --
3113 ------------
3115 function vminfp (A : LL_VF; B : LL_VF) return LL_VF is
3116 VA : constant VF_View := To_View (A);
3117 VB : constant VF_View := To_View (B);
3118 D : VF_View;
3120 begin
3121 for J in Varray_float'Range loop
3122 D.Values (J) := (if VA.Values (J) < VB.Values (J) then VA.Values (J)
3123 else VB.Values (J));
3124 end loop;
3126 return To_Vector (D);
3127 end vminfp;
3129 ------------
3130 -- vminsb --
3131 ------------
3133 function vminsb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3134 VA : constant VSC_View := To_View (A);
3135 VB : constant VSC_View := To_View (B);
3136 D : VSC_View;
3137 begin
3138 D.Values := LL_VSC_Operations.vminsx (VA.Values, VB.Values);
3139 return To_Vector (D);
3140 end vminsb;
3142 ------------
3143 -- vminub --
3144 ------------
3146 function vminub (A : LL_VSC; B : LL_VSC) return LL_VSC is
3147 VA : constant VUC_View := To_View (To_LL_VUC (A));
3148 VB : constant VUC_View := To_View (To_LL_VUC (B));
3149 D : VUC_View;
3150 begin
3151 D.Values := LL_VUC_Operations.vminux (VA.Values, VB.Values);
3152 return To_LL_VSC (To_Vector (D));
3153 end vminub;
3155 ------------
3156 -- vminsh --
3157 ------------
3159 function vminsh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3160 VA : constant VSS_View := To_View (A);
3161 VB : constant VSS_View := To_View (B);
3162 D : VSS_View;
3163 begin
3164 D.Values := LL_VSS_Operations.vminsx (VA.Values, VB.Values);
3165 return To_Vector (D);
3166 end vminsh;
3168 ------------
3169 -- vminuh --
3170 ------------
3172 function vminuh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3173 VA : constant VUS_View := To_View (To_LL_VUS (A));
3174 VB : constant VUS_View := To_View (To_LL_VUS (B));
3175 D : VUS_View;
3176 begin
3177 D.Values := LL_VUS_Operations.vminux (VA.Values, VB.Values);
3178 return To_LL_VSS (To_Vector (D));
3179 end vminuh;
3181 ------------
3182 -- vminsw --
3183 ------------
3185 function vminsw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3186 VA : constant VSI_View := To_View (A);
3187 VB : constant VSI_View := To_View (B);
3188 D : VSI_View;
3189 begin
3190 D.Values := LL_VSI_Operations.vminsx (VA.Values, VB.Values);
3191 return To_Vector (D);
3192 end vminsw;
3194 ------------
3195 -- vminuw --
3196 ------------
3198 function vminuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3199 VA : constant VUI_View := To_View (To_LL_VUI (A));
3200 VB : constant VUI_View := To_View (To_LL_VUI (B));
3201 D : VUI_View;
3202 begin
3203 D.Values := LL_VUI_Operations.vminux (VA.Values,
3204 VB.Values);
3205 return To_LL_VSI (To_Vector (D));
3206 end vminuw;
3208 ---------------
3209 -- vmladduhm --
3210 ---------------
3212 function vmladduhm (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3213 VA : constant VUS_View := To_View (To_LL_VUS (A));
3214 VB : constant VUS_View := To_View (To_LL_VUS (B));
3215 VC : constant VUS_View := To_View (To_LL_VUS (C));
3216 D : VUS_View;
3218 begin
3219 for J in Varray_unsigned_short'Range loop
3220 D.Values (J) := VA.Values (J) * VB.Values (J)
3221 + VC.Values (J);
3222 end loop;
3224 return To_LL_VSS (To_Vector (D));
3225 end vmladduhm;
3227 ----------------
3228 -- vmhraddshs --
3229 ----------------
3231 function vmhraddshs (A : LL_VSS; B : LL_VSS; C : LL_VSS) return LL_VSS is
3232 VA : constant VSS_View := To_View (A);
3233 VB : constant VSS_View := To_View (B);
3234 VC : constant VSS_View := To_View (C);
3235 D : VSS_View;
3237 begin
3238 for J in Varray_signed_short'Range loop
3239 D.Values (J) :=
3240 LL_VSS_Operations.Saturate (((SI64 (VA.Values (J))
3241 * SI64 (VB.Values (J))
3242 + 2 ** 14)
3243 / 2 ** 15
3244 + SI64 (VC.Values (J))));
3245 end loop;
3247 return To_Vector (D);
3248 end vmhraddshs;
3250 --------------
3251 -- vmsumubm --
3252 --------------
3254 function vmsumubm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3255 Offset : Vchar_Range;
3256 VA : constant VUC_View := To_View (To_LL_VUC (A));
3257 VB : constant VUC_View := To_View (To_LL_VUC (B));
3258 VC : constant VUI_View := To_View (To_LL_VUI (C));
3259 D : VUI_View;
3261 begin
3262 for J in 0 .. 3 loop
3263 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3264 D.Values (Vint_Range
3265 (J + Integer (Vint_Range'First))) :=
3266 (unsigned_int (VA.Values (Offset))
3267 * unsigned_int (VB.Values (Offset)))
3268 + (unsigned_int (VA.Values (Offset + 1))
3269 * unsigned_int (VB.Values (1 + Offset)))
3270 + (unsigned_int (VA.Values (2 + Offset))
3271 * unsigned_int (VB.Values (2 + Offset)))
3272 + (unsigned_int (VA.Values (3 + Offset))
3273 * unsigned_int (VB.Values (3 + Offset)))
3274 + VC.Values (Vint_Range
3275 (J + Integer (Varray_unsigned_int'First)));
3276 end loop;
3278 return To_LL_VSI (To_Vector (D));
3279 end vmsumubm;
3281 --------------
3282 -- vmsumumbm --
3283 --------------
3285 function vmsummbm (A : LL_VSC; B : LL_VSC; C : LL_VSI) return LL_VSI is
3286 Offset : Vchar_Range;
3287 VA : constant VSC_View := To_View (A);
3288 VB : constant VUC_View := To_View (To_LL_VUC (B));
3289 VC : constant VSI_View := To_View (C);
3290 D : VSI_View;
3292 begin
3293 for J in 0 .. 3 loop
3294 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
3295 D.Values (Vint_Range
3296 (J + Integer (Varray_unsigned_int'First))) := 0
3297 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3298 * SI64 (VB.Values (Offset)))
3299 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3300 * SI64 (VB.Values
3301 (1 + Offset)))
3302 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (2 + Offset))
3303 * SI64 (VB.Values
3304 (2 + Offset)))
3305 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (3 + Offset))
3306 * SI64 (VB.Values
3307 (3 + Offset)))
3308 + VC.Values (Vint_Range
3309 (J + Integer (Varray_unsigned_int'First)));
3310 end loop;
3312 return To_Vector (D);
3313 end vmsummbm;
3315 --------------
3316 -- vmsumuhm --
3317 --------------
3319 function vmsumuhm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3320 Offset : Vshort_Range;
3321 VA : constant VUS_View := To_View (To_LL_VUS (A));
3322 VB : constant VUS_View := To_View (To_LL_VUS (B));
3323 VC : constant VUI_View := To_View (To_LL_VUI (C));
3324 D : VUI_View;
3326 begin
3327 for J in 0 .. 3 loop
3328 Offset :=
3329 Vshort_Range (2 * J + Integer (Vshort_Range'First));
3330 D.Values (Vint_Range
3331 (J + Integer (Varray_unsigned_int'First))) :=
3332 (unsigned_int (VA.Values (Offset))
3333 * unsigned_int (VB.Values (Offset)))
3334 + (unsigned_int (VA.Values (Offset + 1))
3335 * unsigned_int (VB.Values (1 + Offset)))
3336 + VC.Values (Vint_Range
3337 (J + Integer (Vint_Range'First)));
3338 end loop;
3340 return To_LL_VSI (To_Vector (D));
3341 end vmsumuhm;
3343 --------------
3344 -- vmsumshm --
3345 --------------
3347 function vmsumshm (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3348 VA : constant VSS_View := To_View (A);
3349 VB : constant VSS_View := To_View (B);
3350 VC : constant VSI_View := To_View (C);
3351 Offset : Vshort_Range;
3352 D : VSI_View;
3354 begin
3355 for J in 0 .. 3 loop
3356 Offset :=
3357 Vshort_Range (2 * J + Integer (Varray_signed_char'First));
3358 D.Values (Vint_Range
3359 (J + Integer (Varray_unsigned_int'First))) := 0
3360 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset))
3361 * SI64 (VB.Values (Offset)))
3362 + LL_VSI_Operations.Modular_Result (SI64 (VA.Values (Offset + 1))
3363 * SI64 (VB.Values
3364 (1 + Offset)))
3365 + VC.Values (Vint_Range
3366 (J + Integer (Varray_unsigned_int'First)));
3367 end loop;
3369 return To_Vector (D);
3370 end vmsumshm;
3372 --------------
3373 -- vmsumuhs --
3374 --------------
3376 function vmsumuhs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3377 Offset : Vshort_Range;
3378 VA : constant VUS_View := To_View (To_LL_VUS (A));
3379 VB : constant VUS_View := To_View (To_LL_VUS (B));
3380 VC : constant VUI_View := To_View (To_LL_VUI (C));
3381 D : VUI_View;
3383 begin
3384 for J in 0 .. 3 loop
3385 Offset :=
3386 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3387 D.Values (Vint_Range
3388 (J + Integer (Varray_unsigned_int'First))) :=
3389 LL_VUI_Operations.Saturate
3390 (UI64 (VA.Values (Offset))
3391 * UI64 (VB.Values (Offset))
3392 + UI64 (VA.Values (Offset + 1))
3393 * UI64 (VB.Values (1 + Offset))
3394 + UI64 (VC.Values
3395 (Vint_Range
3396 (J + Integer (Varray_unsigned_int'First)))));
3397 end loop;
3399 return To_LL_VSI (To_Vector (D));
3400 end vmsumuhs;
3402 --------------
3403 -- vmsumshs --
3404 --------------
3406 function vmsumshs (A : LL_VSS; B : LL_VSS; C : LL_VSI) return LL_VSI is
3407 VA : constant VSS_View := To_View (A);
3408 VB : constant VSS_View := To_View (B);
3409 VC : constant VSI_View := To_View (C);
3410 Offset : Vshort_Range;
3411 D : VSI_View;
3413 begin
3414 for J in 0 .. 3 loop
3415 Offset :=
3416 Vshort_Range (2 * J + Integer (Varray_signed_short'First));
3417 D.Values (Vint_Range
3418 (J + Integer (Varray_signed_int'First))) :=
3419 LL_VSI_Operations.Saturate
3420 (SI64 (VA.Values (Offset))
3421 * SI64 (VB.Values (Offset))
3422 + SI64 (VA.Values (Offset + 1))
3423 * SI64 (VB.Values (1 + Offset))
3424 + SI64 (VC.Values
3425 (Vint_Range
3426 (J + Integer (Varray_signed_int'First)))));
3427 end loop;
3429 return To_Vector (D);
3430 end vmsumshs;
3432 ------------
3433 -- mtvscr --
3434 ------------
3436 procedure mtvscr (A : LL_VSI) is
3437 VA : constant VUI_View := To_View (To_LL_VUI (A));
3438 begin
3439 VSCR := VA.Values (Varray_unsigned_int'Last);
3440 end mtvscr;
3442 -------------
3443 -- vmuleub --
3444 -------------
3446 function vmuleub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3447 VA : constant VUC_View := To_View (To_LL_VUC (A));
3448 VB : constant VUC_View := To_View (To_LL_VUC (B));
3449 D : VUS_View;
3450 begin
3451 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (True,
3452 VA.Values,
3453 VB.Values);
3454 return To_LL_VSS (To_Vector (D));
3455 end vmuleub;
3457 -------------
3458 -- vmuleuh --
3459 -------------
3461 function vmuleuh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3462 VA : constant VUS_View := To_View (To_LL_VUS (A));
3463 VB : constant VUS_View := To_View (To_LL_VUS (B));
3464 D : VUI_View;
3465 begin
3466 D.Values := LL_VUS_LL_VUI_Operations.vmulxux (True,
3467 VA.Values,
3468 VB.Values);
3469 return To_LL_VSI (To_Vector (D));
3470 end vmuleuh;
3472 -------------
3473 -- vmulesb --
3474 -------------
3476 function vmulesb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3477 VA : constant VSC_View := To_View (A);
3478 VB : constant VSC_View := To_View (B);
3479 D : VSS_View;
3480 begin
3481 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (True,
3482 VA.Values,
3483 VB.Values);
3484 return To_Vector (D);
3485 end vmulesb;
3487 -------------
3488 -- vmulesh --
3489 -------------
3491 function vmulesh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3492 VA : constant VSS_View := To_View (A);
3493 VB : constant VSS_View := To_View (B);
3494 D : VSI_View;
3495 begin
3496 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (True,
3497 VA.Values,
3498 VB.Values);
3499 return To_Vector (D);
3500 end vmulesh;
3502 -------------
3503 -- vmuloub --
3504 -------------
3506 function vmuloub (A : LL_VSC; B : LL_VSC) return LL_VSS is
3507 VA : constant VUC_View := To_View (To_LL_VUC (A));
3508 VB : constant VUC_View := To_View (To_LL_VUC (B));
3509 D : VUS_View;
3510 begin
3511 D.Values := LL_VUC_LL_VUS_Operations.vmulxux (False,
3512 VA.Values,
3513 VB.Values);
3514 return To_LL_VSS (To_Vector (D));
3515 end vmuloub;
3517 -------------
3518 -- vmulouh --
3519 -------------
3521 function vmulouh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3522 VA : constant VUS_View := To_View (To_LL_VUS (A));
3523 VB : constant VUS_View := To_View (To_LL_VUS (B));
3524 D : VUI_View;
3525 begin
3526 D.Values :=
3527 LL_VUS_LL_VUI_Operations.vmulxux (False, VA.Values, VB.Values);
3528 return To_LL_VSI (To_Vector (D));
3529 end vmulouh;
3531 -------------
3532 -- vmulosb --
3533 -------------
3535 function vmulosb (A : LL_VSC; B : LL_VSC) return LL_VSS is
3536 VA : constant VSC_View := To_View (A);
3537 VB : constant VSC_View := To_View (B);
3538 D : VSS_View;
3539 begin
3540 D.Values := LL_VSC_LL_VSS_Operations.vmulxsx (False,
3541 VA.Values,
3542 VB.Values);
3543 return To_Vector (D);
3544 end vmulosb;
3546 -------------
3547 -- vmulosh --
3548 -------------
3550 function vmulosh (A : LL_VSS; B : LL_VSS) return LL_VSI is
3551 VA : constant VSS_View := To_View (A);
3552 VB : constant VSS_View := To_View (B);
3553 D : VSI_View;
3554 begin
3555 D.Values := LL_VSS_LL_VSI_Operations.vmulxsx (False,
3556 VA.Values,
3557 VB.Values);
3558 return To_Vector (D);
3559 end vmulosh;
3561 --------------
3562 -- vnmsubfp --
3563 --------------
3565 function vnmsubfp (A : LL_VF; B : LL_VF; C : LL_VF) return LL_VF is
3566 VA : constant VF_View := To_View (A);
3567 VB : constant VF_View := To_View (B);
3568 VC : constant VF_View := To_View (C);
3569 D : VF_View;
3571 begin
3572 for J in Vfloat_Range'Range loop
3573 D.Values (J) :=
3574 -Rnd_To_FP_Nearest (F64 (VA.Values (J))
3575 * F64 (VB.Values (J))
3576 - F64 (VC.Values (J)));
3577 end loop;
3579 return To_Vector (D);
3580 end vnmsubfp;
3582 ----------
3583 -- vnor --
3584 ----------
3586 function vnor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3587 VA : constant VUI_View := To_View (To_LL_VUI (A));
3588 VB : constant VUI_View := To_View (To_LL_VUI (B));
3589 D : VUI_View;
3591 begin
3592 for J in Vint_Range'Range loop
3593 D.Values (J) := not (VA.Values (J) or VB.Values (J));
3594 end loop;
3596 return To_LL_VSI (To_Vector (D));
3597 end vnor;
3599 ----------
3600 -- vor --
3601 ----------
3603 function vor (A : LL_VSI; B : LL_VSI) return LL_VSI is
3604 VA : constant VUI_View := To_View (To_LL_VUI (A));
3605 VB : constant VUI_View := To_View (To_LL_VUI (B));
3606 D : VUI_View;
3608 begin
3609 for J in Vint_Range'Range loop
3610 D.Values (J) := VA.Values (J) or VB.Values (J);
3611 end loop;
3613 return To_LL_VSI (To_Vector (D));
3614 end vor;
3616 -------------
3617 -- vpkuhum --
3618 -------------
3620 function vpkuhum (A : LL_VSS; B : LL_VSS) return LL_VSC is
3621 VA : constant VUS_View := To_View (To_LL_VUS (A));
3622 VB : constant VUS_View := To_View (To_LL_VUS (B));
3623 D : VUC_View;
3624 begin
3625 D.Values := LL_VUC_LL_VUS_Operations.vpkuxum (VA.Values, VB.Values);
3626 return To_LL_VSC (To_Vector (D));
3627 end vpkuhum;
3629 -------------
3630 -- vpkuwum --
3631 -------------
3633 function vpkuwum (A : LL_VSI; B : LL_VSI) return LL_VSS is
3634 VA : constant VUI_View := To_View (To_LL_VUI (A));
3635 VB : constant VUI_View := To_View (To_LL_VUI (B));
3636 D : VUS_View;
3637 begin
3638 D.Values := LL_VUS_LL_VUI_Operations.vpkuxum (VA.Values, VB.Values);
3639 return To_LL_VSS (To_Vector (D));
3640 end vpkuwum;
3642 -----------
3643 -- vpkpx --
3644 -----------
3646 function vpkpx (A : LL_VSI; B : LL_VSI) return LL_VSS is
3647 VA : constant VUI_View := To_View (To_LL_VUI (A));
3648 VB : constant VUI_View := To_View (To_LL_VUI (B));
3649 D : VUS_View;
3650 Offset : Vint_Range;
3651 P16 : Pixel_16;
3652 P32 : Pixel_32;
3654 begin
3655 for J in 0 .. 3 loop
3656 Offset := Vint_Range (J + Integer (Vshort_Range'First));
3657 P32 := To_Pixel (VA.Values (Offset));
3658 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3659 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3660 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3661 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3662 D.Values (Vshort_Range (Offset)) := To_unsigned_short (P16);
3663 P32 := To_Pixel (VB.Values (Offset));
3664 P16.T := Unsigned_1 (P32.T mod 2 ** 1);
3665 P16.R := Unsigned_5 (Shift_Right (P32.R, 3) mod 2 ** 5);
3666 P16.G := Unsigned_5 (Shift_Right (P32.G, 3) mod 2 ** 5);
3667 P16.B := Unsigned_5 (Shift_Right (P32.B, 3) mod 2 ** 5);
3668 D.Values (Vshort_Range (Offset) + 4) := To_unsigned_short (P16);
3669 end loop;
3671 return To_LL_VSS (To_Vector (D));
3672 end vpkpx;
3674 -------------
3675 -- vpkuhus --
3676 -------------
3678 function vpkuhus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3679 VA : constant VUS_View := To_View (To_LL_VUS (A));
3680 VB : constant VUS_View := To_View (To_LL_VUS (B));
3681 D : VUC_View;
3682 begin
3683 D.Values := LL_VUC_LL_VUS_Operations.vpkuxus (VA.Values, VB.Values);
3684 return To_LL_VSC (To_Vector (D));
3685 end vpkuhus;
3687 -------------
3688 -- vpkuwus --
3689 -------------
3691 function vpkuwus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3692 VA : constant VUI_View := To_View (To_LL_VUI (A));
3693 VB : constant VUI_View := To_View (To_LL_VUI (B));
3694 D : VUS_View;
3695 begin
3696 D.Values := LL_VUS_LL_VUI_Operations.vpkuxus (VA.Values, VB.Values);
3697 return To_LL_VSS (To_Vector (D));
3698 end vpkuwus;
3700 -------------
3701 -- vpkshss --
3702 -------------
3704 function vpkshss (A : LL_VSS; B : LL_VSS) return LL_VSC is
3705 VA : constant VSS_View := To_View (A);
3706 VB : constant VSS_View := To_View (B);
3707 D : VSC_View;
3708 begin
3709 D.Values := LL_VSC_LL_VSS_Operations.vpksxss (VA.Values, VB.Values);
3710 return To_Vector (D);
3711 end vpkshss;
3713 -------------
3714 -- vpkswss --
3715 -------------
3717 function vpkswss (A : LL_VSI; B : LL_VSI) return LL_VSS is
3718 VA : constant VSI_View := To_View (A);
3719 VB : constant VSI_View := To_View (B);
3720 D : VSS_View;
3721 begin
3722 D.Values := LL_VSS_LL_VSI_Operations.vpksxss (VA.Values, VB.Values);
3723 return To_Vector (D);
3724 end vpkswss;
3726 -------------
3727 -- vpksxus --
3728 -------------
3730 generic
3731 type Signed_Component_Type is range <>;
3732 type Signed_Index_Type is range <>;
3733 type Signed_Varray_Type is
3734 array (Signed_Index_Type) of Signed_Component_Type;
3735 type Unsigned_Component_Type is mod <>;
3736 type Unsigned_Index_Type is range <>;
3737 type Unsigned_Varray_Type is
3738 array (Unsigned_Index_Type) of Unsigned_Component_Type;
3740 function vpksxus
3741 (A : Signed_Varray_Type;
3742 B : Signed_Varray_Type) return Unsigned_Varray_Type;
3744 function vpksxus
3745 (A : Signed_Varray_Type;
3746 B : Signed_Varray_Type) return Unsigned_Varray_Type
3748 N : constant Unsigned_Index_Type :=
3749 Unsigned_Index_Type (Signed_Index_Type'Last);
3750 Offset : Unsigned_Index_Type;
3751 Signed_Offset : Signed_Index_Type;
3752 D : Unsigned_Varray_Type;
3754 function Saturate
3755 (X : Signed_Component_Type) return Unsigned_Component_Type;
3756 -- Saturation, as defined in
3757 -- [PIM-4.1 Vector Status and Control Register]
3759 --------------
3760 -- Saturate --
3761 --------------
3763 function Saturate
3764 (X : Signed_Component_Type) return Unsigned_Component_Type
3766 D : Unsigned_Component_Type;
3768 begin
3769 D := Unsigned_Component_Type
3770 (Signed_Component_Type'Max
3771 (Signed_Component_Type (Unsigned_Component_Type'First),
3772 Signed_Component_Type'Min
3773 (Signed_Component_Type (Unsigned_Component_Type'Last),
3774 X)));
3775 if Signed_Component_Type (D) /= X then
3776 VSCR := Write_Bit (VSCR, SAT_POS, 1);
3777 end if;
3779 return D;
3780 end Saturate;
3782 -- Start of processing for vpksxus
3784 begin
3785 for J in 0 .. N - 1 loop
3786 Offset :=
3787 Unsigned_Index_Type (Integer (J)
3788 + Integer (Unsigned_Index_Type'First));
3789 Signed_Offset :=
3790 Signed_Index_Type (Integer (J)
3791 + Integer (Signed_Index_Type'First));
3792 D (Offset) := Saturate (A (Signed_Offset));
3793 D (Offset + N) := Saturate (B (Signed_Offset));
3794 end loop;
3796 return D;
3797 end vpksxus;
3799 -------------
3800 -- vpkshus --
3801 -------------
3803 function vpkshus (A : LL_VSS; B : LL_VSS) return LL_VSC is
3804 function vpkshus_Instance is
3805 new vpksxus (signed_short,
3806 Vshort_Range,
3807 Varray_signed_short,
3808 unsigned_char,
3809 Vchar_Range,
3810 Varray_unsigned_char);
3812 VA : constant VSS_View := To_View (A);
3813 VB : constant VSS_View := To_View (B);
3814 D : VUC_View;
3816 begin
3817 D.Values := vpkshus_Instance (VA.Values, VB.Values);
3818 return To_LL_VSC (To_Vector (D));
3819 end vpkshus;
3821 -------------
3822 -- vpkswus --
3823 -------------
3825 function vpkswus (A : LL_VSI; B : LL_VSI) return LL_VSS is
3826 function vpkswus_Instance is
3827 new vpksxus (signed_int,
3828 Vint_Range,
3829 Varray_signed_int,
3830 unsigned_short,
3831 Vshort_Range,
3832 Varray_unsigned_short);
3834 VA : constant VSI_View := To_View (A);
3835 VB : constant VSI_View := To_View (B);
3836 D : VUS_View;
3837 begin
3838 D.Values := vpkswus_Instance (VA.Values, VB.Values);
3839 return To_LL_VSS (To_Vector (D));
3840 end vpkswus;
3842 ---------------
3843 -- vperm_4si --
3844 ---------------
3846 function vperm_4si (A : LL_VSI; B : LL_VSI; C : LL_VSC) return LL_VSI is
3847 VA : constant VUC_View := To_View (To_LL_VUC (A));
3848 VB : constant VUC_View := To_View (To_LL_VUC (B));
3849 VC : constant VUC_View := To_View (To_LL_VUC (C));
3850 J : Vchar_Range;
3851 D : VUC_View;
3853 begin
3854 for N in Vchar_Range'Range loop
3855 J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
3856 + Integer (Vchar_Range'First));
3857 D.Values (N) :=
3858 (if Bits (VC.Values (N), 3, 3) = 0 then VA.Values (J)
3859 else VB.Values (J));
3860 end loop;
3862 return To_LL_VSI (To_Vector (D));
3863 end vperm_4si;
3865 -----------
3866 -- vrefp --
3867 -----------
3869 function vrefp (A : LL_VF) return LL_VF is
3870 VA : constant VF_View := To_View (A);
3871 D : VF_View;
3873 begin
3874 for J in Vfloat_Range'Range loop
3875 D.Values (J) := FP_Recip_Est (VA.Values (J));
3876 end loop;
3878 return To_Vector (D);
3879 end vrefp;
3881 ----------
3882 -- vrlb --
3883 ----------
3885 function vrlb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3886 VA : constant VUC_View := To_View (To_LL_VUC (A));
3887 VB : constant VUC_View := To_View (To_LL_VUC (B));
3888 D : VUC_View;
3889 begin
3890 D.Values := LL_VUC_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3891 return To_LL_VSC (To_Vector (D));
3892 end vrlb;
3894 ----------
3895 -- vrlh --
3896 ----------
3898 function vrlh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3899 VA : constant VUS_View := To_View (To_LL_VUS (A));
3900 VB : constant VUS_View := To_View (To_LL_VUS (B));
3901 D : VUS_View;
3902 begin
3903 D.Values := LL_VUS_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3904 return To_LL_VSS (To_Vector (D));
3905 end vrlh;
3907 ----------
3908 -- vrlw --
3909 ----------
3911 function vrlw (A : LL_VSI; B : LL_VSI) return LL_VSI is
3912 VA : constant VUI_View := To_View (To_LL_VUI (A));
3913 VB : constant VUI_View := To_View (To_LL_VUI (B));
3914 D : VUI_View;
3915 begin
3916 D.Values := LL_VUI_Operations.vrlx (VA.Values, VB.Values, ROTL'Access);
3917 return To_LL_VSI (To_Vector (D));
3918 end vrlw;
3920 -----------
3921 -- vrfin --
3922 -----------
3924 function vrfin (A : LL_VF) return LL_VF is
3925 VA : constant VF_View := To_View (A);
3926 D : VF_View;
3928 begin
3929 for J in Vfloat_Range'Range loop
3930 D.Values (J) := C_float (Rnd_To_FPI_Near (F64 (VA.Values (J))));
3931 end loop;
3933 return To_Vector (D);
3934 end vrfin;
3936 ---------------
3937 -- vrsqrtefp --
3938 ---------------
3940 function vrsqrtefp (A : LL_VF) return LL_VF is
3941 VA : constant VF_View := To_View (A);
3942 D : VF_View;
3944 begin
3945 for J in Vfloat_Range'Range loop
3946 D.Values (J) := Recip_SQRT_Est (VA.Values (J));
3947 end loop;
3949 return To_Vector (D);
3950 end vrsqrtefp;
3952 --------------
3953 -- vsel_4si --
3954 --------------
3956 function vsel_4si (A : LL_VSI; B : LL_VSI; C : LL_VSI) return LL_VSI is
3957 VA : constant VUI_View := To_View (To_LL_VUI (A));
3958 VB : constant VUI_View := To_View (To_LL_VUI (B));
3959 VC : constant VUI_View := To_View (To_LL_VUI (C));
3960 D : VUI_View;
3962 begin
3963 for J in Vint_Range'Range loop
3964 D.Values (J) := ((not VC.Values (J)) and VA.Values (J))
3965 or (VC.Values (J) and VB.Values (J));
3966 end loop;
3968 return To_LL_VSI (To_Vector (D));
3969 end vsel_4si;
3971 ----------
3972 -- vslb --
3973 ----------
3975 function vslb (A : LL_VSC; B : LL_VSC) return LL_VSC is
3976 VA : constant VUC_View := To_View (To_LL_VUC (A));
3977 VB : constant VUC_View := To_View (To_LL_VUC (B));
3978 D : VUC_View;
3979 begin
3980 D.Values :=
3981 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
3982 return To_LL_VSC (To_Vector (D));
3983 end vslb;
3985 ----------
3986 -- vslh --
3987 ----------
3989 function vslh (A : LL_VSS; B : LL_VSS) return LL_VSS is
3990 VA : constant VUS_View := To_View (To_LL_VUS (A));
3991 VB : constant VUS_View := To_View (To_LL_VUS (B));
3992 D : VUS_View;
3993 begin
3994 D.Values :=
3995 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
3996 return To_LL_VSS (To_Vector (D));
3997 end vslh;
3999 ----------
4000 -- vslw --
4001 ----------
4003 function vslw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4004 VA : constant VUI_View := To_View (To_LL_VUI (A));
4005 VB : constant VUI_View := To_View (To_LL_VUI (B));
4006 D : VUI_View;
4007 begin
4008 D.Values :=
4009 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Left'Access);
4010 return To_LL_VSI (To_Vector (D));
4011 end vslw;
4013 ----------------
4014 -- vsldoi_4si --
4015 ----------------
4017 function vsldoi_4si (A : LL_VSI; B : LL_VSI; C : c_int) return LL_VSI is
4018 VA : constant VUC_View := To_View (To_LL_VUC (A));
4019 VB : constant VUC_View := To_View (To_LL_VUC (B));
4020 Offset : c_int;
4021 Bound : c_int;
4022 D : VUC_View;
4024 begin
4025 for J in Vchar_Range'Range loop
4026 Offset := c_int (J) + C;
4027 Bound := c_int (Vchar_Range'First)
4028 + c_int (Varray_unsigned_char'Length);
4030 if Offset < Bound then
4031 D.Values (J) := VA.Values (Vchar_Range (Offset));
4032 else
4033 D.Values (J) :=
4034 VB.Values (Vchar_Range (Offset - Bound
4035 + c_int (Vchar_Range'First)));
4036 end if;
4037 end loop;
4039 return To_LL_VSI (To_Vector (D));
4040 end vsldoi_4si;
4042 ----------------
4043 -- vsldoi_8hi --
4044 ----------------
4046 function vsldoi_8hi (A : LL_VSS; B : LL_VSS; C : c_int) return LL_VSS is
4047 begin
4048 return To_LL_VSS (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4049 end vsldoi_8hi;
4051 -----------------
4052 -- vsldoi_16qi --
4053 -----------------
4055 function vsldoi_16qi (A : LL_VSC; B : LL_VSC; C : c_int) return LL_VSC is
4056 begin
4057 return To_LL_VSC (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4058 end vsldoi_16qi;
4060 ----------------
4061 -- vsldoi_4sf --
4062 ----------------
4064 function vsldoi_4sf (A : LL_VF; B : LL_VF; C : c_int) return LL_VF is
4065 begin
4066 return To_LL_VF (vsldoi_4si (To_LL_VSI (A), To_LL_VSI (B), C));
4067 end vsldoi_4sf;
4069 ---------
4070 -- vsl --
4071 ---------
4073 function vsl (A : LL_VSI; B : LL_VSI) return LL_VSI is
4074 VA : constant VUI_View := To_View (To_LL_VUI (A));
4075 VB : constant VUI_View := To_View (To_LL_VUI (B));
4076 D : VUI_View;
4077 M : constant Natural :=
4078 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4080 -- [PIM-4.4 vec_sll] "Note that the three low-order byte elements in B
4081 -- must be the same. Otherwise the value placed into D is undefined."
4082 -- ??? Shall we add a optional check for B?
4084 begin
4085 for J in Vint_Range'Range loop
4086 D.Values (J) := 0;
4087 D.Values (J) := D.Values (J) + Shift_Left (VA.Values (J), M);
4089 if J /= Vint_Range'Last then
4090 D.Values (J) :=
4091 D.Values (J) + Shift_Right (VA.Values (J + 1),
4092 signed_int'Size - M);
4093 end if;
4094 end loop;
4096 return To_LL_VSI (To_Vector (D));
4097 end vsl;
4099 ----------
4100 -- vslo --
4101 ----------
4103 function vslo (A : LL_VSI; B : LL_VSI) return LL_VSI is
4104 VA : constant VUC_View := To_View (To_LL_VUC (A));
4105 VB : constant VUC_View := To_View (To_LL_VUC (B));
4106 D : VUC_View;
4107 M : constant Natural :=
4108 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4109 J : Natural;
4111 begin
4112 for N in Vchar_Range'Range loop
4113 J := Natural (N) + M;
4114 D.Values (N) :=
4115 (if J <= Natural (Vchar_Range'Last) then VA.Values (Vchar_Range (J))
4116 else 0);
4117 end loop;
4119 return To_LL_VSI (To_Vector (D));
4120 end vslo;
4122 ------------
4123 -- vspltb --
4124 ------------
4126 function vspltb (A : LL_VSC; B : c_int) return LL_VSC is
4127 VA : constant VSC_View := To_View (A);
4128 D : VSC_View;
4129 begin
4130 D.Values := LL_VSC_Operations.vspltx (VA.Values, B);
4131 return To_Vector (D);
4132 end vspltb;
4134 ------------
4135 -- vsplth --
4136 ------------
4138 function vsplth (A : LL_VSS; B : c_int) return LL_VSS is
4139 VA : constant VSS_View := To_View (A);
4140 D : VSS_View;
4141 begin
4142 D.Values := LL_VSS_Operations.vspltx (VA.Values, B);
4143 return To_Vector (D);
4144 end vsplth;
4146 ------------
4147 -- vspltw --
4148 ------------
4150 function vspltw (A : LL_VSI; B : c_int) return LL_VSI is
4151 VA : constant VSI_View := To_View (A);
4152 D : VSI_View;
4153 begin
4154 D.Values := LL_VSI_Operations.vspltx (VA.Values, B);
4155 return To_Vector (D);
4156 end vspltw;
4158 --------------
4159 -- vspltisb --
4160 --------------
4162 function vspltisb (A : c_int) return LL_VSC is
4163 D : VSC_View;
4164 begin
4165 D.Values := LL_VSC_Operations.vspltisx (A);
4166 return To_Vector (D);
4167 end vspltisb;
4169 --------------
4170 -- vspltish --
4171 --------------
4173 function vspltish (A : c_int) return LL_VSS is
4174 D : VSS_View;
4175 begin
4176 D.Values := LL_VSS_Operations.vspltisx (A);
4177 return To_Vector (D);
4178 end vspltish;
4180 --------------
4181 -- vspltisw --
4182 --------------
4184 function vspltisw (A : c_int) return LL_VSI is
4185 D : VSI_View;
4186 begin
4187 D.Values := LL_VSI_Operations.vspltisx (A);
4188 return To_Vector (D);
4189 end vspltisw;
4191 ----------
4192 -- vsrb --
4193 ----------
4195 function vsrb (A : LL_VSC; B : LL_VSC) return LL_VSC is
4196 VA : constant VUC_View := To_View (To_LL_VUC (A));
4197 VB : constant VUC_View := To_View (To_LL_VUC (B));
4198 D : VUC_View;
4199 begin
4200 D.Values :=
4201 LL_VUC_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4202 return To_LL_VSC (To_Vector (D));
4203 end vsrb;
4205 ----------
4206 -- vsrh --
4207 ----------
4209 function vsrh (A : LL_VSS; B : LL_VSS) return LL_VSS is
4210 VA : constant VUS_View := To_View (To_LL_VUS (A));
4211 VB : constant VUS_View := To_View (To_LL_VUS (B));
4212 D : VUS_View;
4213 begin
4214 D.Values :=
4215 LL_VUS_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4216 return To_LL_VSS (To_Vector (D));
4217 end vsrh;
4219 ----------
4220 -- vsrw --
4221 ----------
4223 function vsrw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4224 VA : constant VUI_View := To_View (To_LL_VUI (A));
4225 VB : constant VUI_View := To_View (To_LL_VUI (B));
4226 D : VUI_View;
4227 begin
4228 D.Values :=
4229 LL_VUI_Operations.vsxx (VA.Values, VB.Values, Shift_Right'Access);
4230 return To_LL_VSI (To_Vector (D));
4231 end vsrw;
4233 -----------
4234 -- vsrab --
4235 -----------
4237 function vsrab (A : LL_VSC; B : LL_VSC) return LL_VSC is
4238 VA : constant VSC_View := To_View (A);
4239 VB : constant VSC_View := To_View (B);
4240 D : VSC_View;
4241 begin
4242 D.Values :=
4243 LL_VSC_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4244 return To_Vector (D);
4245 end vsrab;
4247 -----------
4248 -- vsrah --
4249 -----------
4251 function vsrah (A : LL_VSS; B : LL_VSS) return LL_VSS is
4252 VA : constant VSS_View := To_View (A);
4253 VB : constant VSS_View := To_View (B);
4254 D : VSS_View;
4255 begin
4256 D.Values :=
4257 LL_VSS_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4258 return To_Vector (D);
4259 end vsrah;
4261 -----------
4262 -- vsraw --
4263 -----------
4265 function vsraw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4266 VA : constant VSI_View := To_View (A);
4267 VB : constant VSI_View := To_View (B);
4268 D : VSI_View;
4269 begin
4270 D.Values :=
4271 LL_VSI_Operations.vsrax (VA.Values, VB.Values, Shift_Right_A'Access);
4272 return To_Vector (D);
4273 end vsraw;
4275 ---------
4276 -- vsr --
4277 ---------
4279 function vsr (A : LL_VSI; B : LL_VSI) return LL_VSI is
4280 VA : constant VUI_View := To_View (To_LL_VUI (A));
4281 VB : constant VUI_View := To_View (To_LL_VUI (B));
4282 M : constant Natural :=
4283 Natural (Bits (VB.Values (Vint_Range'Last), 29, 31));
4284 D : VUI_View;
4286 begin
4287 for J in Vint_Range'Range loop
4288 D.Values (J) := 0;
4289 D.Values (J) := D.Values (J) + Shift_Right (VA.Values (J), M);
4291 if J /= Vint_Range'First then
4292 D.Values (J) :=
4293 D.Values (J)
4294 + Shift_Left (VA.Values (J - 1), signed_int'Size - M);
4295 end if;
4296 end loop;
4298 return To_LL_VSI (To_Vector (D));
4299 end vsr;
4301 ----------
4302 -- vsro --
4303 ----------
4305 function vsro (A : LL_VSI; B : LL_VSI) return LL_VSI is
4306 VA : constant VUC_View := To_View (To_LL_VUC (A));
4307 VB : constant VUC_View := To_View (To_LL_VUC (B));
4308 M : constant Natural :=
4309 Natural (Bits (VB.Values (Vchar_Range'Last), 1, 4));
4310 J : Natural;
4311 D : VUC_View;
4313 begin
4314 for N in Vchar_Range'Range loop
4315 J := Natural (N) - M;
4317 if J >= Natural (Vchar_Range'First) then
4318 D.Values (N) := VA.Values (Vchar_Range (J));
4319 else
4320 D.Values (N) := 0;
4321 end if;
4322 end loop;
4324 return To_LL_VSI (To_Vector (D));
4325 end vsro;
4327 ----------
4328 -- stvx --
4329 ----------
4331 procedure stvx (A : LL_VSI; B : c_int; C : c_ptr) is
4333 -- Simulate the altivec unit behavior regarding what Effective Address
4334 -- is accessed, stripping off the input address least significant bits
4335 -- wrt to vector alignment (see comment in lvx for further details).
4337 EA : constant System.Address :=
4338 To_Address
4339 (Bound_Align
4340 (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4342 D : LL_VSI;
4343 for D'Address use EA;
4345 begin
4346 D := A;
4347 end stvx;
4349 ------------
4350 -- stvewx --
4351 ------------
4353 procedure stvebx (A : LL_VSC; B : c_int; C : c_ptr) is
4354 VA : constant VSC_View := To_View (A);
4355 begin
4356 LL_VSC_Operations.stvexx (VA.Values, B, C);
4357 end stvebx;
4359 ------------
4360 -- stvehx --
4361 ------------
4363 procedure stvehx (A : LL_VSS; B : c_int; C : c_ptr) is
4364 VA : constant VSS_View := To_View (A);
4365 begin
4366 LL_VSS_Operations.stvexx (VA.Values, B, C);
4367 end stvehx;
4369 ------------
4370 -- stvewx --
4371 ------------
4373 procedure stvewx (A : LL_VSI; B : c_int; C : c_ptr) is
4374 VA : constant VSI_View := To_View (A);
4375 begin
4376 LL_VSI_Operations.stvexx (VA.Values, B, C);
4377 end stvewx;
4379 -----------
4380 -- stvxl --
4381 -----------
4383 procedure stvxl (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4385 -------------
4386 -- vsububm --
4387 -------------
4389 function vsububm (A : LL_VSC; B : LL_VSC) return LL_VSC is
4390 VA : constant VUC_View := To_View (To_LL_VUC (A));
4391 VB : constant VUC_View := To_View (To_LL_VUC (B));
4392 D : VUC_View;
4393 begin
4394 D.Values := LL_VUC_Operations.vsubuxm (VA.Values, VB.Values);
4395 return To_LL_VSC (To_Vector (D));
4396 end vsububm;
4398 -------------
4399 -- vsubuhm --
4400 -------------
4402 function vsubuhm (A : LL_VSS; B : LL_VSS) return LL_VSS is
4403 VA : constant VUS_View := To_View (To_LL_VUS (A));
4404 VB : constant VUS_View := To_View (To_LL_VUS (B));
4405 D : VUS_View;
4406 begin
4407 D.Values := LL_VUS_Operations.vsubuxm (VA.Values, VB.Values);
4408 return To_LL_VSS (To_Vector (D));
4409 end vsubuhm;
4411 -------------
4412 -- vsubuwm --
4413 -------------
4415 function vsubuwm (A : LL_VSI; B : LL_VSI) return LL_VSI is
4416 VA : constant VUI_View := To_View (To_LL_VUI (A));
4417 VB : constant VUI_View := To_View (To_LL_VUI (B));
4418 D : VUI_View;
4419 begin
4420 D.Values := LL_VUI_Operations.vsubuxm (VA.Values, VB.Values);
4421 return To_LL_VSI (To_Vector (D));
4422 end vsubuwm;
4424 ------------
4425 -- vsubfp --
4426 ------------
4428 function vsubfp (A : LL_VF; B : LL_VF) return LL_VF is
4429 VA : constant VF_View := To_View (A);
4430 VB : constant VF_View := To_View (B);
4431 D : VF_View;
4433 begin
4434 for J in Vfloat_Range'Range loop
4435 D.Values (J) :=
4436 NJ_Truncate (NJ_Truncate (VA.Values (J))
4437 - NJ_Truncate (VB.Values (J)));
4438 end loop;
4440 return To_Vector (D);
4441 end vsubfp;
4443 -------------
4444 -- vsubcuw --
4445 -------------
4447 function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4448 Subst_Result : SI64;
4450 VA : constant VUI_View := To_View (To_LL_VUI (A));
4451 VB : constant VUI_View := To_View (To_LL_VUI (B));
4452 D : VUI_View;
4454 begin
4455 for J in Vint_Range'Range loop
4456 Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
4457 D.Values (J) :=
4458 (if Subst_Result < SI64 (unsigned_int'First) then 0 else 1);
4459 end loop;
4461 return To_LL_VSI (To_Vector (D));
4462 end vsubcuw;
4464 -------------
4465 -- vsububs --
4466 -------------
4468 function vsububs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4469 VA : constant VUC_View := To_View (To_LL_VUC (A));
4470 VB : constant VUC_View := To_View (To_LL_VUC (B));
4471 D : VUC_View;
4472 begin
4473 D.Values := LL_VUC_Operations.vsubuxs (VA.Values, VB.Values);
4474 return To_LL_VSC (To_Vector (D));
4475 end vsububs;
4477 -------------
4478 -- vsubsbs --
4479 -------------
4481 function vsubsbs (A : LL_VSC; B : LL_VSC) return LL_VSC is
4482 VA : constant VSC_View := To_View (A);
4483 VB : constant VSC_View := To_View (B);
4484 D : VSC_View;
4485 begin
4486 D.Values := LL_VSC_Operations.vsubsxs (VA.Values, VB.Values);
4487 return To_Vector (D);
4488 end vsubsbs;
4490 -------------
4491 -- vsubuhs --
4492 -------------
4494 function vsubuhs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4495 VA : constant VUS_View := To_View (To_LL_VUS (A));
4496 VB : constant VUS_View := To_View (To_LL_VUS (B));
4497 D : VUS_View;
4498 begin
4499 D.Values := LL_VUS_Operations.vsubuxs (VA.Values, VB.Values);
4500 return To_LL_VSS (To_Vector (D));
4501 end vsubuhs;
4503 -------------
4504 -- vsubshs --
4505 -------------
4507 function vsubshs (A : LL_VSS; B : LL_VSS) return LL_VSS is
4508 VA : constant VSS_View := To_View (A);
4509 VB : constant VSS_View := To_View (B);
4510 D : VSS_View;
4511 begin
4512 D.Values := LL_VSS_Operations.vsubsxs (VA.Values, VB.Values);
4513 return To_Vector (D);
4514 end vsubshs;
4516 -------------
4517 -- vsubuws --
4518 -------------
4520 function vsubuws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4521 VA : constant VUI_View := To_View (To_LL_VUI (A));
4522 VB : constant VUI_View := To_View (To_LL_VUI (B));
4523 D : VUI_View;
4524 begin
4525 D.Values := LL_VUI_Operations.vsubuxs (VA.Values, VB.Values);
4526 return To_LL_VSI (To_Vector (D));
4527 end vsubuws;
4529 -------------
4530 -- vsubsws --
4531 -------------
4533 function vsubsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4534 VA : constant VSI_View := To_View (A);
4535 VB : constant VSI_View := To_View (B);
4536 D : VSI_View;
4537 begin
4538 D.Values := LL_VSI_Operations.vsubsxs (VA.Values, VB.Values);
4539 return To_Vector (D);
4540 end vsubsws;
4542 --------------
4543 -- vsum4ubs --
4544 --------------
4546 function vsum4ubs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4547 VA : constant VUC_View := To_View (To_LL_VUC (A));
4548 VB : constant VUI_View := To_View (To_LL_VUI (B));
4549 Offset : Vchar_Range;
4550 D : VUI_View;
4552 begin
4553 for J in 0 .. 3 loop
4554 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4555 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4556 LL_VUI_Operations.Saturate
4557 (UI64 (VA.Values (Offset))
4558 + UI64 (VA.Values (Offset + 1))
4559 + UI64 (VA.Values (Offset + 2))
4560 + UI64 (VA.Values (Offset + 3))
4561 + UI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4562 end loop;
4564 return To_LL_VSI (To_Vector (D));
4565 end vsum4ubs;
4567 --------------
4568 -- vsum4sbs --
4569 --------------
4571 function vsum4sbs (A : LL_VSC; B : LL_VSI) return LL_VSI is
4572 VA : constant VSC_View := To_View (A);
4573 VB : constant VSI_View := To_View (B);
4574 Offset : Vchar_Range;
4575 D : VSI_View;
4577 begin
4578 for J in 0 .. 3 loop
4579 Offset := Vchar_Range (4 * J + Integer (Vchar_Range'First));
4580 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4581 LL_VSI_Operations.Saturate
4582 (SI64 (VA.Values (Offset))
4583 + SI64 (VA.Values (Offset + 1))
4584 + SI64 (VA.Values (Offset + 2))
4585 + SI64 (VA.Values (Offset + 3))
4586 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4587 end loop;
4589 return To_Vector (D);
4590 end vsum4sbs;
4592 --------------
4593 -- vsum4shs --
4594 --------------
4596 function vsum4shs (A : LL_VSS; B : LL_VSI) return LL_VSI is
4597 VA : constant VSS_View := To_View (A);
4598 VB : constant VSI_View := To_View (B);
4599 Offset : Vshort_Range;
4600 D : VSI_View;
4602 begin
4603 for J in 0 .. 3 loop
4604 Offset := Vshort_Range (2 * J + Integer (Vchar_Range'First));
4605 D.Values (Vint_Range (J + Integer (Vint_Range'First))) :=
4606 LL_VSI_Operations.Saturate
4607 (SI64 (VA.Values (Offset))
4608 + SI64 (VA.Values (Offset + 1))
4609 + SI64 (VB.Values (Vint_Range (J + Integer (Vint_Range'First)))));
4610 end loop;
4612 return To_Vector (D);
4613 end vsum4shs;
4615 --------------
4616 -- vsum2sws --
4617 --------------
4619 function vsum2sws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4620 VA : constant VSI_View := To_View (A);
4621 VB : constant VSI_View := To_View (B);
4622 Offset : Vint_Range;
4623 D : VSI_View;
4625 begin
4626 for J in 0 .. 1 loop
4627 Offset := Vint_Range (2 * J + Integer (Vchar_Range'First));
4628 D.Values (Offset) := 0;
4629 D.Values (Offset + 1) :=
4630 LL_VSI_Operations.Saturate
4631 (SI64 (VA.Values (Offset))
4632 + SI64 (VA.Values (Offset + 1))
4633 + SI64 (VB.Values (Vint_Range (Offset + 1))));
4634 end loop;
4636 return To_Vector (D);
4637 end vsum2sws;
4639 -------------
4640 -- vsumsws --
4641 -------------
4643 function vsumsws (A : LL_VSI; B : LL_VSI) return LL_VSI is
4644 VA : constant VSI_View := To_View (A);
4645 VB : constant VSI_View := To_View (B);
4646 D : VSI_View;
4647 Sum_Buffer : SI64 := 0;
4649 begin
4650 for J in Vint_Range'Range loop
4651 D.Values (J) := 0;
4652 Sum_Buffer := Sum_Buffer + SI64 (VA.Values (J));
4653 end loop;
4655 Sum_Buffer := Sum_Buffer + SI64 (VB.Values (Vint_Range'Last));
4656 D.Values (Vint_Range'Last) := LL_VSI_Operations.Saturate (Sum_Buffer);
4657 return To_Vector (D);
4658 end vsumsws;
4660 -----------
4661 -- vrfiz --
4662 -----------
4664 function vrfiz (A : LL_VF) return LL_VF is
4665 VA : constant VF_View := To_View (A);
4666 D : VF_View;
4667 begin
4668 for J in Vfloat_Range'Range loop
4669 D.Values (J) := C_float (Rnd_To_FPI_Trunc (F64 (VA.Values (J))));
4670 end loop;
4672 return To_Vector (D);
4673 end vrfiz;
4675 -------------
4676 -- vupkhsb --
4677 -------------
4679 function vupkhsb (A : LL_VSC) return LL_VSS is
4680 VA : constant VSC_View := To_View (A);
4681 D : VSS_View;
4682 begin
4683 D.Values := LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values, 0);
4684 return To_Vector (D);
4685 end vupkhsb;
4687 -------------
4688 -- vupkhsh --
4689 -------------
4691 function vupkhsh (A : LL_VSS) return LL_VSI is
4692 VA : constant VSS_View := To_View (A);
4693 D : VSI_View;
4694 begin
4695 D.Values := LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values, 0);
4696 return To_Vector (D);
4697 end vupkhsh;
4699 -------------
4700 -- vupkxpx --
4701 -------------
4703 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4704 -- For vupkhpx and vupklpx (depending on Offset)
4706 function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI is
4707 VA : constant VUS_View := To_View (To_LL_VUS (A));
4708 K : Vshort_Range;
4709 D : VUI_View;
4710 P16 : Pixel_16;
4711 P32 : Pixel_32;
4713 function Sign_Extend (X : Unsigned_1) return unsigned_char;
4715 function Sign_Extend (X : Unsigned_1) return unsigned_char is
4716 begin
4717 if X = 1 then
4718 return 16#FF#;
4719 else
4720 return 16#00#;
4721 end if;
4722 end Sign_Extend;
4724 begin
4725 for J in Vint_Range'Range loop
4726 K := Vshort_Range (Integer (J)
4727 - Integer (Vint_Range'First)
4728 + Integer (Vshort_Range'First)
4729 + Offset);
4730 P16 := To_Pixel (VA.Values (K));
4731 P32.T := Sign_Extend (P16.T);
4732 P32.R := unsigned_char (P16.R);
4733 P32.G := unsigned_char (P16.G);
4734 P32.B := unsigned_char (P16.B);
4735 D.Values (J) := To_unsigned_int (P32);
4736 end loop;
4738 return To_LL_VSI (To_Vector (D));
4739 end vupkxpx;
4741 -------------
4742 -- vupkhpx --
4743 -------------
4745 function vupkhpx (A : LL_VSS) return LL_VSI is
4746 begin
4747 return vupkxpx (A, 0);
4748 end vupkhpx;
4750 -------------
4751 -- vupklsb --
4752 -------------
4754 function vupklsb (A : LL_VSC) return LL_VSS is
4755 VA : constant VSC_View := To_View (A);
4756 D : VSS_View;
4757 begin
4758 D.Values :=
4759 LL_VSC_LL_VSS_Operations.vupkxsx (VA.Values,
4760 Varray_signed_short'Length);
4761 return To_Vector (D);
4762 end vupklsb;
4764 -------------
4765 -- vupklsh --
4766 -------------
4768 function vupklsh (A : LL_VSS) return LL_VSI is
4769 VA : constant VSS_View := To_View (A);
4770 D : VSI_View;
4771 begin
4772 D.Values :=
4773 LL_VSS_LL_VSI_Operations.vupkxsx (VA.Values,
4774 Varray_signed_int'Length);
4775 return To_Vector (D);
4776 end vupklsh;
4778 -------------
4779 -- vupklpx --
4780 -------------
4782 function vupklpx (A : LL_VSS) return LL_VSI is
4783 begin
4784 return vupkxpx (A, Varray_signed_int'Length);
4785 end vupklpx;
4787 ----------
4788 -- vxor --
4789 ----------
4791 function vxor (A : LL_VSI; B : LL_VSI) return LL_VSI is
4792 VA : constant VUI_View := To_View (To_LL_VUI (A));
4793 VB : constant VUI_View := To_View (To_LL_VUI (B));
4794 D : VUI_View;
4796 begin
4797 for J in Vint_Range'Range loop
4798 D.Values (J) := VA.Values (J) xor VB.Values (J);
4799 end loop;
4801 return To_LL_VSI (To_Vector (D));
4802 end vxor;
4804 ----------------
4805 -- vcmpequb_p --
4806 ----------------
4808 function vcmpequb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4809 D : LL_VSC;
4810 begin
4811 D := vcmpequb (B, C);
4812 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4813 end vcmpequb_p;
4815 ----------------
4816 -- vcmpequh_p --
4817 ----------------
4819 function vcmpequh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4820 D : LL_VSS;
4821 begin
4822 D := vcmpequh (B, C);
4823 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4824 end vcmpequh_p;
4826 ----------------
4827 -- vcmpequw_p --
4828 ----------------
4830 function vcmpequw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4831 D : LL_VSI;
4832 begin
4833 D := vcmpequw (B, C);
4834 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4835 end vcmpequw_p;
4837 ----------------
4838 -- vcmpeqfp_p --
4839 ----------------
4841 function vcmpeqfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4842 D : LL_VSI;
4843 begin
4844 D := vcmpeqfp (B, C);
4845 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4846 end vcmpeqfp_p;
4848 ----------------
4849 -- vcmpgtub_p --
4850 ----------------
4852 function vcmpgtub_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4853 D : LL_VSC;
4854 begin
4855 D := vcmpgtub (B, C);
4856 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4857 end vcmpgtub_p;
4859 ----------------
4860 -- vcmpgtuh_p --
4861 ----------------
4863 function vcmpgtuh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4864 D : LL_VSS;
4865 begin
4866 D := vcmpgtuh (B, C);
4867 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4868 end vcmpgtuh_p;
4870 ----------------
4871 -- vcmpgtuw_p --
4872 ----------------
4874 function vcmpgtuw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4875 D : LL_VSI;
4876 begin
4877 D := vcmpgtuw (B, C);
4878 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4879 end vcmpgtuw_p;
4881 ----------------
4882 -- vcmpgtsb_p --
4883 ----------------
4885 function vcmpgtsb_p (A : c_int; B : LL_VSC; C : LL_VSC) return c_int is
4886 D : LL_VSC;
4887 begin
4888 D := vcmpgtsb (B, C);
4889 return LL_VSC_Operations.Check_CR6 (A, To_View (D).Values);
4890 end vcmpgtsb_p;
4892 ----------------
4893 -- vcmpgtsh_p --
4894 ----------------
4896 function vcmpgtsh_p (A : c_int; B : LL_VSS; C : LL_VSS) return c_int is
4897 D : LL_VSS;
4898 begin
4899 D := vcmpgtsh (B, C);
4900 return LL_VSS_Operations.Check_CR6 (A, To_View (D).Values);
4901 end vcmpgtsh_p;
4903 ----------------
4904 -- vcmpgtsw_p --
4905 ----------------
4907 function vcmpgtsw_p (A : c_int; B : LL_VSI; C : LL_VSI) return c_int is
4908 D : LL_VSI;
4909 begin
4910 D := vcmpgtsw (B, C);
4911 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4912 end vcmpgtsw_p;
4914 ----------------
4915 -- vcmpgefp_p --
4916 ----------------
4918 function vcmpgefp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4919 D : LL_VSI;
4920 begin
4921 D := vcmpgefp (B, C);
4922 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4923 end vcmpgefp_p;
4925 ----------------
4926 -- vcmpgtfp_p --
4927 ----------------
4929 function vcmpgtfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4930 D : LL_VSI;
4931 begin
4932 D := vcmpgtfp (B, C);
4933 return LL_VSI_Operations.Check_CR6 (A, To_View (D).Values);
4934 end vcmpgtfp_p;
4936 ----------------
4937 -- vcmpbfp_p --
4938 ----------------
4940 function vcmpbfp_p (A : c_int; B : LL_VF; C : LL_VF) return c_int is
4941 D : VSI_View;
4942 begin
4943 D := To_View (vcmpbfp (B, C));
4945 for J in Vint_Range'Range loop
4947 -- vcmpbfp is not returning the usual bool vector; do the conversion
4949 D.Values (J) :=
4950 (if D.Values (J) = 0 then Signed_Bool_False else Signed_Bool_True);
4951 end loop;
4953 return LL_VSI_Operations.Check_CR6 (A, D.Values);
4954 end vcmpbfp_p;
4956 end GNAT.Altivec.Low_Level_Vectors;