OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ada/] [g-alleve.adb] - Blame information for rev 292

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
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-2009, 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
------------------------------------------------------------------------------
32
 
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.
36
 
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.
40
 
41
with Ada.Numerics.Generic_Elementary_Functions;
42
with Interfaces;                       use Interfaces;
43
with System.Storage_Elements;          use System.Storage_Elements;
44
 
45
with GNAT.Altivec.Conversions;         use  GNAT.Altivec.Conversions;
46
with GNAT.Altivec.Low_Level_Interface; use  GNAT.Altivec.Low_Level_Interface;
47
 
48
package body GNAT.Altivec.Low_Level_Vectors is
49
 
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.
55
 
56
   type Unsigned_1 is mod 2 ** 1;
57
   type Unsigned_5 is mod 2 ** 5;
58
 
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;
65
 
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;
72
 
73
   --  Conversions to/from the pixel records to the integer types that are
74
   --  actually stored into the pixel vectors:
75
 
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;
80
 
81
   package C_float_Operations is
82
     new Ada.Numerics.Generic_Elementary_Functions (C_float);
83
 
84
   --  Model of the Vector Status and Control Register (VSCR), as
85
   --  defined in [PIM-4.1 Vector Status and Control Register]:
86
 
87
   VSCR : unsigned_int;
88
 
89
   --  Positions of the flags in VSCR(0 .. 31):
90
 
91
   NJ_POS   : constant := 15;
92
   SAT_POS  : constant := 31;
93
 
94
   --  To control overflows, integer operations are done on 64-bit types:
95
 
96
   SINT64_MIN : constant := -2 ** 63;
97
   SINT64_MAX : constant := 2 ** 63 - 1;
98
   UINT64_MAX : constant := 2 ** 64 - 1;
99
 
100
   type SI64 is range SINT64_MIN .. SINT64_MAX;
101
   type UI64 is mod UINT64_MAX + 1;
102
 
103
   type F64 is digits 15
104
     range -16#0.FFFF_FFFF_FFFF_F8#E+256 .. 16#0.FFFF_FFFF_FFFF_F8#E+256;
105
 
106
   function Bits
107
     (X    : unsigned_int;
108
      Low  : Natural;
109
      High : Natural) return unsigned_int;
110
 
111
   function Bits
112
     (X    : unsigned_short;
113
      Low  : Natural;
114
      High : Natural) return unsigned_short;
115
 
116
   function Bits
117
     (X    : unsigned_char;
118
      Low  : Natural;
119
      High : Natural) return unsigned_char;
120
 
121
   function Write_Bit
122
     (X     : unsigned_int;
123
      Where : Natural;
124
      Value : Unsigned_1) return unsigned_int;
125
 
126
   function Write_Bit
127
     (X     : unsigned_short;
128
      Where : Natural;
129
      Value : Unsigned_1) return unsigned_short;
130
 
131
   function Write_Bit
132
     (X     : unsigned_char;
133
      Where : Natural;
134
      Value : Unsigned_1) return unsigned_char;
135
 
136
   function NJ_Truncate (X : C_float) return C_float;
137
   --  If NJ and A is a denormalized number, return zero
138
 
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
144
 
145
   function Rnd_To_FP_Nearest (X : F64) return C_float;
146
   --  [PIM-4.3 Notations and Conventions]
147
 
148
   function Rnd_To_FPI_Near (X : F64) return F64;
149
 
150
   function Rnd_To_FPI_Trunc (X : F64) return F64;
151
 
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
155
 
156
   function ROTL
157
     (Value  : unsigned_char;
158
      Amount : Natural) return unsigned_char;
159
   --  [PIM-4.3 Notations and Conventions]
160
   --  Rotate left
161
 
162
   function ROTL
163
     (Value  : unsigned_short;
164
      Amount : Natural) return unsigned_short;
165
 
166
   function ROTL
167
     (Value  : unsigned_int;
168
      Amount : Natural) return unsigned_int;
169
 
170
   function Recip_SQRT_Est (X : C_float) return C_float;
171
 
172
   function Shift_Left
173
     (Value  : unsigned_char;
174
      Amount : Natural) return unsigned_char;
175
   --  [PIM-4.3 Notations and Conventions]
176
   --  Shift left
177
 
178
   function Shift_Left
179
     (Value  : unsigned_short;
180
      Amount : Natural) return unsigned_short;
181
 
182
   function Shift_Left
183
     (Value  : unsigned_int;
184
      Amount : Natural) return unsigned_int;
185
 
186
   function Shift_Right
187
     (Value  : unsigned_char;
188
      Amount : Natural) return unsigned_char;
189
   --  [PIM-4.3 Notations and Conventions]
190
   --  Shift Right
191
 
192
   function Shift_Right
193
     (Value  : unsigned_short;
194
      Amount : Natural) return unsigned_short;
195
 
196
   function Shift_Right
197
     (Value  : unsigned_int;
198
      Amount : Natural) return unsigned_int;
199
 
200
   Signed_Bool_False : constant := 0;
201
   Signed_Bool_True  : constant := -1;
202
 
203
   ------------------------------
204
   -- Signed_Operations (spec) --
205
   ------------------------------
206
 
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;
211
 
212
   package Signed_Operations is
213
 
214
      function Modular_Result (X : SI64) return Component_Type;
215
 
216
      function Saturate (X : SI64) return Component_Type;
217
 
218
      function Saturate (X : F64) return Component_Type;
219
 
220
      function Sign_Extend (X : c_int) return Component_Type;
221
      --  [PIM-4.3 Notations and Conventions]
222
      --  Sign-extend X
223
 
224
      function abs_vxi (A : Varray_Type) return Varray_Type;
225
      pragma Convention (LL_Altivec, abs_vxi);
226
 
227
      function abss_vxi (A : Varray_Type) return Varray_Type;
228
      pragma Convention (LL_Altivec, abss_vxi);
229
 
230
      function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
231
      pragma Convention (LL_Altivec, vaddsxs);
232
 
233
      function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
234
      pragma Convention (LL_Altivec, vavgsx);
235
 
236
      function vcmpgtsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
237
      pragma Convention (LL_Altivec, vcmpgtsx);
238
 
239
      function lvexx (A : c_long; B : c_ptr) return Varray_Type;
240
      pragma Convention (LL_Altivec, lvexx);
241
 
242
      function vmaxsx (A : Varray_Type;  B : Varray_Type) return Varray_Type;
243
      pragma Convention (LL_Altivec, vmaxsx);
244
 
245
      function vmrghx (A : Varray_Type; B : Varray_Type) return Varray_Type;
246
      pragma Convention (LL_Altivec, vmrghx);
247
 
248
      function vmrglx (A : Varray_Type; B : Varray_Type) return Varray_Type;
249
      pragma Convention (LL_Altivec, vmrglx);
250
 
251
      function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type;
252
      pragma Convention (LL_Altivec, vminsx);
253
 
254
      function vspltx (A : Varray_Type; B : c_int) return Varray_Type;
255
      pragma Convention (LL_Altivec, vspltx);
256
 
257
      function vspltisx (A : c_int) return Varray_Type;
258
      pragma Convention (LL_Altivec, vspltisx);
259
 
260
      type Bit_Operation is
261
        access function
262
        (Value  : Component_Type;
263
         Amount : Natural) return Component_Type;
264
 
265
      function vsrax
266
        (A          : Varray_Type;
267
         B          : Varray_Type;
268
         Shift_Func : Bit_Operation) return Varray_Type;
269
 
270
      procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr);
271
      pragma Convention (LL_Altivec, stvexx);
272
 
273
      function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
274
      pragma Convention (LL_Altivec, vsubsxs);
275
 
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.
280
 
281
   end Signed_Operations;
282
 
283
   ------------------------------
284
   -- Signed_Operations (body) --
285
   ------------------------------
286
 
287
   package body Signed_Operations is
288
 
289
      Bool_True  : constant Component_Type := Signed_Bool_True;
290
      Bool_False : constant Component_Type := Signed_Bool_False;
291
 
292
      Number_Of_Elements : constant Integer :=
293
                             VECTOR_BIT / Component_Type'Size;
294
 
295
      --------------------
296
      -- Modular_Result --
297
      --------------------
298
 
299
      function Modular_Result (X : SI64) return Component_Type is
300
         D : Component_Type;
301
 
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;
310
 
311
         return D;
312
      end Modular_Result;
313
 
314
      --------------
315
      -- Saturate --
316
      --------------
317
 
318
      function Saturate (X : SI64) return Component_Type is
319
         D : Component_Type;
320
 
321
      begin
322
         --  Saturation, as defined in
323
         --  [PIM-4.1 Vector Status and Control Register]
324
 
325
         D := Component_Type (SI64'Max
326
                              (SI64 (Component_Type'First),
327
                               SI64'Min
328
                               (SI64 (Component_Type'Last),
329
                                X)));
330
 
331
         if SI64 (D) /= X then
332
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
333
         end if;
334
 
335
         return D;
336
      end Saturate;
337
 
338
      function Saturate (X : F64) return Component_Type is
339
         D : Component_Type;
340
 
341
      begin
342
         --  Saturation, as defined in
343
         --  [PIM-4.1 Vector Status and Control Register]
344
 
345
         D := Component_Type (F64'Max
346
                              (F64 (Component_Type'First),
347
                               F64'Min
348
                               (F64 (Component_Type'Last),
349
                                X)));
350
 
351
         if F64 (D) /= X then
352
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
353
         end if;
354
 
355
         return D;
356
      end Saturate;
357
 
358
      -----------------
359
      -- Sign_Extend --
360
      -----------------
361
 
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.
366
 
367
         return Component_Type (X);
368
      end Sign_Extend;
369
 
370
      -------------
371
      -- abs_vxi --
372
      -------------
373
 
374
      function abs_vxi (A : Varray_Type) return Varray_Type is
375
         D : Varray_Type;
376
 
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;
382
 
383
         return D;
384
      end abs_vxi;
385
 
386
      --------------
387
      -- abss_vxi --
388
      --------------
389
 
390
      function abss_vxi (A : Varray_Type) return Varray_Type is
391
         D : Varray_Type;
392
 
393
      begin
394
         for K in Varray_Type'Range loop
395
            D (K) := Saturate (abs (SI64 (A (K))));
396
         end loop;
397
 
398
         return D;
399
      end abss_vxi;
400
 
401
      -------------
402
      -- vaddsxs --
403
      -------------
404
 
405
      function vaddsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
406
         D : Varray_Type;
407
 
408
      begin
409
         for J in Varray_Type'Range loop
410
            D (J) := Saturate (SI64 (A (J)) + SI64 (B (J)));
411
         end loop;
412
 
413
         return D;
414
      end vaddsxs;
415
 
416
      ------------
417
      -- vavgsx --
418
      ------------
419
 
420
      function vavgsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
421
         D : Varray_Type;
422
 
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;
427
 
428
         return D;
429
      end vavgsx;
430
 
431
      --------------
432
      -- vcmpgtsx --
433
      --------------
434
 
435
      function vcmpgtsx
436
        (A : Varray_Type;
437
         B : Varray_Type) return Varray_Type
438
      is
439
         D : Varray_Type;
440
 
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;
445
 
446
         return D;
447
      end vcmpgtsx;
448
 
449
      -----------
450
      -- lvexx --
451
      -----------
452
 
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;
458
 
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));
465
 
466
         declare
467
            Component : Component_Type;
468
            for Component'Address use To_Address (EA);
469
         begin
470
            D (J) := Component;
471
         end;
472
 
473
         return D;
474
      end lvexx;
475
 
476
      ------------
477
      -- vmaxsx --
478
      ------------
479
 
480
      function vmaxsx (A : Varray_Type;  B : Varray_Type) return Varray_Type is
481
         D : Varray_Type;
482
 
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;
487
 
488
         return D;
489
      end vmaxsx;
490
 
491
      ------------
492
      -- vmrghx --
493
      ------------
494
 
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;
499
 
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;
505
 
506
         return D;
507
      end vmrghx;
508
 
509
      ------------
510
      -- vmrglx --
511
      ------------
512
 
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;
517
 
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;
524
 
525
         return D;
526
      end vmrglx;
527
 
528
      ------------
529
      -- vminsx --
530
      ------------
531
 
532
      function vminsx (A : Varray_Type; B : Varray_Type) return Varray_Type is
533
         D : Varray_Type;
534
 
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;
539
 
540
         return D;
541
      end vminsx;
542
 
543
      ------------
544
      -- vspltx --
545
      ------------
546
 
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;
552
 
553
      begin
554
         for K in Varray_Type'Range loop
555
            D (K) := A (Index_Type (J));
556
         end loop;
557
 
558
         return D;
559
      end vspltx;
560
 
561
      --------------
562
      -- vspltisx --
563
      --------------
564
 
565
      function vspltisx (A : c_int) return Varray_Type is
566
         D : Varray_Type;
567
 
568
      begin
569
         for J in Varray_Type'Range loop
570
            D (J) := Sign_Extend (A);
571
         end loop;
572
 
573
         return D;
574
      end vspltisx;
575
 
576
      -----------
577
      -- vsrax --
578
      -----------
579
 
580
      function vsrax
581
        (A          : Varray_Type;
582
         B          : Varray_Type;
583
         Shift_Func : Bit_Operation) return Varray_Type
584
      is
585
         D : Varray_Type;
586
         S : constant Component_Type :=
587
               Component_Type (128 / Number_Of_Elements);
588
 
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;
593
 
594
         return D;
595
      end vsrax;
596
 
597
      ------------
598
      -- stvexx --
599
      ------------
600
 
601
      procedure stvexx (A : Varray_Type; B : c_int; C : c_ptr) is
602
         S  : Integer;
603
         EA : Integer_Address;
604
         J  : Index_Type;
605
 
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));
612
 
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;
620
 
621
      -------------
622
      -- vsubsxs --
623
      -------------
624
 
625
      function vsubsxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
626
         D : Varray_Type;
627
 
628
      begin
629
         for J in Varray_Type'Range loop
630
            D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
631
         end loop;
632
 
633
         return D;
634
      end vsubsxs;
635
 
636
      ---------------
637
      -- Check_CR6 --
638
      ---------------
639
 
640
      function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
641
         All_Element : Boolean := True;
642
         Any_Element : Boolean := False;
643
 
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;
649
 
650
         if A = CR6_LT then
651
            if All_Element then
652
               return 1;
653
            else
654
               return 0;
655
            end if;
656
 
657
         elsif A = CR6_EQ then
658
            if not Any_Element then
659
               return 1;
660
            else
661
               return 0;
662
            end if;
663
 
664
         elsif A = CR6_EQ_REV then
665
            if Any_Element then
666
               return 1;
667
            else
668
               return 0;
669
            end if;
670
 
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;
678
 
679
         return 0;
680
      end Check_CR6;
681
 
682
   end Signed_Operations;
683
 
684
   --------------------------------
685
   -- Unsigned_Operations (spec) --
686
   --------------------------------
687
 
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;
692
 
693
   package Unsigned_Operations is
694
 
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.
701
 
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).
708
 
709
      function Modular_Result (X : UI64) return Component_Type;
710
 
711
      function Saturate (X : UI64) return Component_Type;
712
 
713
      function Saturate (X : F64) return Component_Type;
714
 
715
      function Saturate (X : SI64) return Component_Type;
716
 
717
      function vadduxm  (A : Varray_Type; B : Varray_Type) return Varray_Type;
718
 
719
      function vadduxs  (A : Varray_Type; B : Varray_Type) return Varray_Type;
720
 
721
      function vavgux   (A : Varray_Type; B : Varray_Type) return Varray_Type;
722
 
723
      function vcmpequx (A : Varray_Type; B : Varray_Type) return Varray_Type;
724
 
725
      function vcmpgtux (A : Varray_Type; B : Varray_Type) return Varray_Type;
726
 
727
      function vmaxux   (A : Varray_Type; B : Varray_Type) return Varray_Type;
728
 
729
      function vminux   (A : Varray_Type; B : Varray_Type) return Varray_Type;
730
 
731
      type Bit_Operation is
732
        access function
733
        (Value  : Component_Type;
734
         Amount : Natural) return Component_Type;
735
 
736
      function vrlx
737
        (A    : Varray_Type;
738
         B    : Varray_Type;
739
         ROTL : Bit_Operation) return Varray_Type;
740
 
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)
746
 
747
      function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type;
748
 
749
      function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type;
750
 
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.
755
 
756
   end Unsigned_Operations;
757
 
758
   --------------------------------
759
   -- Unsigned_Operations (body) --
760
   --------------------------------
761
 
762
   package body Unsigned_Operations is
763
 
764
      Number_Of_Elements : constant Integer :=
765
                             VECTOR_BIT / Component_Type'Size;
766
 
767
      Bool_True  : constant Component_Type := Component_Type'Last;
768
      Bool_False : constant Component_Type := 0;
769
 
770
      --------------------
771
      -- Modular_Result --
772
      --------------------
773
 
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;
780
 
781
      --------------
782
      -- Saturate --
783
      --------------
784
 
785
      function Saturate (X : UI64) return Component_Type is
786
         D : Component_Type;
787
 
788
      begin
789
         --  Saturation, as defined in
790
         --  [PIM-4.1 Vector Status and Control Register]
791
 
792
         D := Component_Type (UI64'Max
793
                              (UI64 (Component_Type'First),
794
                               UI64'Min
795
                               (UI64 (Component_Type'Last),
796
                                X)));
797
 
798
         if UI64 (D) /= X then
799
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
800
         end if;
801
 
802
         return D;
803
      end Saturate;
804
 
805
      function Saturate (X : SI64) return Component_Type is
806
         D : Component_Type;
807
 
808
      begin
809
         --  Saturation, as defined in
810
         --  [PIM-4.1 Vector Status and Control Register]
811
 
812
         D := Component_Type (SI64'Max
813
                              (SI64 (Component_Type'First),
814
                               SI64'Min
815
                               (SI64 (Component_Type'Last),
816
                                X)));
817
 
818
         if SI64 (D) /= X then
819
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
820
         end if;
821
 
822
         return D;
823
      end Saturate;
824
 
825
      function Saturate (X : F64) return Component_Type is
826
         D : Component_Type;
827
 
828
      begin
829
         --  Saturation, as defined in
830
         --  [PIM-4.1 Vector Status and Control Register]
831
 
832
         D := Component_Type (F64'Max
833
                              (F64 (Component_Type'First),
834
                               F64'Min
835
                               (F64 (Component_Type'Last),
836
                                X)));
837
 
838
         if F64 (D) /= X then
839
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
840
         end if;
841
 
842
         return D;
843
      end Saturate;
844
 
845
      ----------
846
      -- Bits --
847
      ----------
848
 
849
      function Bits
850
        (X    : Component_Type;
851
         Low  : Natural;
852
         High : Natural) return Component_Type
853
      is
854
         Mask : Component_Type := 0;
855
 
856
         --  The Altivec ABI uses a big endian bit ordering, and we are
857
         --  using little endian bit ordering for extracting bits:
858
 
859
         Low_LE  : constant Natural := Component_Type'Size - 1 - High;
860
         High_LE : constant Natural := Component_Type'Size - 1 - Low;
861
 
862
      begin
863
         pragma Assert (Low <= Component_Type'Size);
864
         pragma Assert (High <= Component_Type'Size);
865
 
866
         for J in Low_LE .. High_LE loop
867
            Mask := Mask or 2 ** J;
868
         end loop;
869
 
870
         return (X and Mask) / 2 ** Low_LE;
871
      end Bits;
872
 
873
      ---------------
874
      -- Write_Bit --
875
      ---------------
876
 
877
      function Write_Bit
878
        (X     : Component_Type;
879
         Where : Natural;
880
         Value : Unsigned_1) return Component_Type
881
      is
882
         Result   : Component_Type := 0;
883
 
884
         --  The Altivec ABI uses a big endian bit ordering, and we are
885
         --  using little endian bit ordering for extracting bits:
886
 
887
         Where_LE : constant Natural := Component_Type'Size - 1 - Where;
888
 
889
      begin
890
         pragma Assert (Where < Component_Type'Size);
891
 
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;
898
 
899
         return Result;
900
      end Write_Bit;
901
 
902
      -------------
903
      -- vadduxm --
904
      -------------
905
 
906
      function vadduxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
907
         D : Varray_Type;
908
 
909
      begin
910
         for J in Varray_Type'Range loop
911
            D (J) := A (J) + B (J);
912
         end loop;
913
 
914
         return D;
915
      end vadduxm;
916
 
917
      -------------
918
      -- vadduxs --
919
      -------------
920
 
921
      function vadduxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
922
         D : Varray_Type;
923
 
924
      begin
925
         for J in Varray_Type'Range loop
926
            D (J) := Saturate (UI64 (A (J)) + UI64 (B (J)));
927
         end loop;
928
 
929
         return D;
930
      end vadduxs;
931
 
932
      ------------
933
      -- vavgux --
934
      ------------
935
 
936
      function vavgux (A : Varray_Type; B : Varray_Type) return Varray_Type is
937
         D : Varray_Type;
938
 
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;
943
 
944
         return D;
945
      end vavgux;
946
 
947
      --------------
948
      -- vcmpequx --
949
      --------------
950
 
951
      function vcmpequx
952
        (A : Varray_Type;
953
         B : Varray_Type) return Varray_Type
954
      is
955
         D : Varray_Type;
956
 
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;
961
 
962
         return D;
963
      end vcmpequx;
964
 
965
      --------------
966
      -- vcmpgtux --
967
      --------------
968
 
969
      function vcmpgtux
970
        (A : Varray_Type;
971
         B : Varray_Type) return Varray_Type
972
      is
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;
978
 
979
         return D;
980
      end vcmpgtux;
981
 
982
      ------------
983
      -- vmaxux --
984
      ------------
985
 
986
      function vmaxux (A : Varray_Type;  B : Varray_Type) return Varray_Type is
987
         D : Varray_Type;
988
 
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;
993
 
994
         return D;
995
      end vmaxux;
996
 
997
      ------------
998
      -- vminux --
999
      ------------
1000
 
1001
      function vminux (A : Varray_Type; B : Varray_Type) return Varray_Type is
1002
         D : Varray_Type;
1003
 
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;
1008
 
1009
         return D;
1010
      end vminux;
1011
 
1012
      ----------
1013
      -- vrlx --
1014
      ----------
1015
 
1016
      function vrlx
1017
        (A    : Varray_Type;
1018
         B    : Varray_Type;
1019
         ROTL : Bit_Operation) return Varray_Type
1020
      is
1021
         D : Varray_Type;
1022
 
1023
      begin
1024
         for J in Varray_Type'Range loop
1025
            D (J) := ROTL (A (J), Natural (B (J)));
1026
         end loop;
1027
 
1028
         return D;
1029
      end vrlx;
1030
 
1031
      ----------
1032
      -- vsxx --
1033
      ----------
1034
 
1035
      function vsxx
1036
        (A          : Varray_Type;
1037
         B          : Varray_Type;
1038
         Shift_Func : Bit_Operation) return Varray_Type
1039
      is
1040
         D : Varray_Type;
1041
         S : constant Component_Type :=
1042
               Component_Type (128 / Number_Of_Elements);
1043
 
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;
1048
 
1049
         return D;
1050
      end vsxx;
1051
 
1052
      -------------
1053
      -- vsubuxm --
1054
      -------------
1055
 
1056
      function vsubuxm (A : Varray_Type; B : Varray_Type) return Varray_Type is
1057
         D : Varray_Type;
1058
 
1059
      begin
1060
         for J in Varray_Type'Range loop
1061
            D (J) := A (J) - B (J);
1062
         end loop;
1063
 
1064
         return D;
1065
      end vsubuxm;
1066
 
1067
      -------------
1068
      -- vsubuxs --
1069
      -------------
1070
 
1071
      function vsubuxs (A : Varray_Type; B : Varray_Type) return Varray_Type is
1072
         D : Varray_Type;
1073
 
1074
      begin
1075
         for J in Varray_Type'Range loop
1076
            D (J) := Saturate (SI64 (A (J)) - SI64 (B (J)));
1077
         end loop;
1078
 
1079
         return D;
1080
      end vsubuxs;
1081
 
1082
      ---------------
1083
      -- Check_CR6 --
1084
      ---------------
1085
 
1086
      function Check_CR6 (A : c_int; D : Varray_Type) return c_int is
1087
         All_Element : Boolean := True;
1088
         Any_Element : Boolean := False;
1089
 
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;
1095
 
1096
         if A = CR6_LT then
1097
            if All_Element then
1098
               return 1;
1099
            else
1100
               return 0;
1101
            end if;
1102
 
1103
         elsif A = CR6_EQ then
1104
            if not Any_Element then
1105
               return 1;
1106
            else
1107
               return 0;
1108
            end if;
1109
 
1110
         elsif A = CR6_EQ_REV then
1111
            if Any_Element then
1112
               return 1;
1113
            else
1114
               return 0;
1115
            end if;
1116
 
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;
1124
 
1125
         return 0;
1126
      end Check_CR6;
1127
 
1128
   end Unsigned_Operations;
1129
 
1130
   --------------------------------------
1131
   -- Signed_Merging_Operations (spec) --
1132
   --------------------------------------
1133
 
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;
1142
 
1143
   package Signed_Merging_Operations is
1144
 
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);
1149
 
1150
      function Saturate
1151
        (X : Double_Component_Type) return Component_Type;
1152
 
1153
      function vmulxsx
1154
        (Use_Even_Components : Boolean;
1155
         A                   : Varray_Type;
1156
         B                   : Varray_Type) return Double_Varray_Type;
1157
 
1158
      function vpksxss
1159
        (A : Double_Varray_Type;
1160
         B : Double_Varray_Type) return Varray_Type;
1161
      pragma Convention (LL_Altivec, vpksxss);
1162
 
1163
      function vupkxsx
1164
        (A      : Varray_Type;
1165
         Offset : Natural) return Double_Varray_Type;
1166
 
1167
   end Signed_Merging_Operations;
1168
 
1169
   --------------------------------------
1170
   -- Signed_Merging_Operations (body) --
1171
   --------------------------------------
1172
 
1173
   package body Signed_Merging_Operations is
1174
 
1175
      --------------
1176
      -- Saturate --
1177
      --------------
1178
 
1179
      function Saturate
1180
        (X : Double_Component_Type) return Component_Type
1181
      is
1182
         D : Component_Type;
1183
 
1184
      begin
1185
         --  Saturation, as defined in
1186
         --  [PIM-4.1 Vector Status and Control Register]
1187
 
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)));
1193
 
1194
         if Double_Component_Type (D) /= X then
1195
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
1196
         end if;
1197
 
1198
         return D;
1199
      end Saturate;
1200
 
1201
      -------------
1202
      -- vmulsxs --
1203
      -------------
1204
 
1205
      function vmulxsx
1206
        (Use_Even_Components : Boolean;
1207
         A                   : Varray_Type;
1208
         B                   : Varray_Type) return Double_Varray_Type
1209
      is
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;
1216
 
1217
      begin
1218
 
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));
1223
 
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;
1230
 
1231
         return D;
1232
      end vmulxsx;
1233
 
1234
      -------------
1235
      -- vpksxss --
1236
      -------------
1237
 
1238
      function vpksxss
1239
        (A : Double_Varray_Type;
1240
         B : Double_Varray_Type) return Varray_Type
1241
      is
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;
1247
 
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;
1257
 
1258
         return D;
1259
      end vpksxss;
1260
 
1261
      -------------
1262
      -- vupkxsx --
1263
      -------------
1264
 
1265
      function vupkxsx
1266
        (A      : Varray_Type;
1267
         Offset : Natural) return Double_Varray_Type
1268
      is
1269
         K : Index_Type;
1270
         D : Double_Varray_Type;
1271
 
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;
1280
 
1281
         return D;
1282
      end vupkxsx;
1283
 
1284
   end Signed_Merging_Operations;
1285
 
1286
   ----------------------------------------
1287
   -- Unsigned_Merging_Operations (spec) --
1288
   ----------------------------------------
1289
 
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;
1298
 
1299
   package Unsigned_Merging_Operations is
1300
 
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);
1305
 
1306
      function UI_To_UI_Mod
1307
        (X : Double_Component_Type;
1308
         Y : Natural) return Component_Type;
1309
 
1310
      function Saturate (X : Double_Component_Type) return Component_Type;
1311
 
1312
      function vmulxux
1313
        (Use_Even_Components : Boolean;
1314
         A                   : Varray_Type;
1315
         B                   : Varray_Type) return Double_Varray_Type;
1316
 
1317
      function vpkuxum
1318
        (A : Double_Varray_Type;
1319
         B : Double_Varray_Type) return Varray_Type;
1320
 
1321
      function vpkuxus
1322
        (A : Double_Varray_Type;
1323
         B : Double_Varray_Type) return Varray_Type;
1324
 
1325
   end Unsigned_Merging_Operations;
1326
 
1327
   ----------------------------------------
1328
   -- Unsigned_Merging_Operations (body) --
1329
   ----------------------------------------
1330
 
1331
   package body Unsigned_Merging_Operations is
1332
 
1333
      ------------------
1334
      -- UI_To_UI_Mod --
1335
      ------------------
1336
 
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;
1345
 
1346
      --------------
1347
      -- Saturate --
1348
      --------------
1349
 
1350
      function Saturate (X : Double_Component_Type) return Component_Type is
1351
         D : Component_Type;
1352
 
1353
      begin
1354
         --  Saturation, as defined in
1355
         --  [PIM-4.1 Vector Status and Control Register]
1356
 
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)));
1362
 
1363
         if Double_Component_Type (D) /= X then
1364
            VSCR := Write_Bit (VSCR, SAT_POS, 1);
1365
         end if;
1366
 
1367
         return D;
1368
      end Saturate;
1369
 
1370
      -------------
1371
      -- vmulxux --
1372
      -------------
1373
 
1374
      function vmulxux
1375
        (Use_Even_Components : Boolean;
1376
         A                   : Varray_Type;
1377
         B                   : Varray_Type) return Double_Varray_Type
1378
      is
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;
1385
 
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));
1391
 
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;
1398
 
1399
         return D;
1400
      end vmulxux;
1401
 
1402
      -------------
1403
      -- vpkuxum --
1404
      -------------
1405
 
1406
      function vpkuxum
1407
        (A : Double_Varray_Type;
1408
         B : Double_Varray_Type) return Varray_Type
1409
      is
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;
1417
 
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;
1427
 
1428
         return D;
1429
      end vpkuxum;
1430
 
1431
      -------------
1432
      -- vpkuxus --
1433
      -------------
1434
 
1435
      function vpkuxus
1436
        (A : Double_Varray_Type;
1437
         B : Double_Varray_Type) return Varray_Type
1438
      is
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;
1444
 
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;
1454
 
1455
         return D;
1456
      end vpkuxus;
1457
 
1458
   end Unsigned_Merging_Operations;
1459
 
1460
   package LL_VSC_Operations is
1461
     new Signed_Operations (signed_char,
1462
                            Vchar_Range,
1463
                            Varray_signed_char);
1464
 
1465
   package LL_VSS_Operations is
1466
     new Signed_Operations (signed_short,
1467
                            Vshort_Range,
1468
                            Varray_signed_short);
1469
 
1470
   package LL_VSI_Operations is
1471
     new Signed_Operations (signed_int,
1472
                            Vint_Range,
1473
                            Varray_signed_int);
1474
 
1475
   package LL_VUC_Operations is
1476
     new Unsigned_Operations (unsigned_char,
1477
                              Vchar_Range,
1478
                              Varray_unsigned_char);
1479
 
1480
   package LL_VUS_Operations is
1481
     new Unsigned_Operations (unsigned_short,
1482
                              Vshort_Range,
1483
                              Varray_unsigned_short);
1484
 
1485
   package LL_VUI_Operations is
1486
     new Unsigned_Operations (unsigned_int,
1487
                              Vint_Range,
1488
                              Varray_unsigned_int);
1489
 
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);
1497
 
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);
1505
 
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);
1513
 
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);
1521
 
1522
   ----------
1523
   -- Bits --
1524
   ----------
1525
 
1526
   function Bits
1527
     (X    : unsigned_int;
1528
      Low  : Natural;
1529
      High : Natural) return unsigned_int renames LL_VUI_Operations.Bits;
1530
 
1531
   function Bits
1532
     (X    : unsigned_short;
1533
      Low  : Natural;
1534
      High : Natural) return unsigned_short renames LL_VUS_Operations.Bits;
1535
 
1536
   function Bits
1537
     (X    : unsigned_char;
1538
      Low  : Natural;
1539
      High : Natural) return unsigned_char renames LL_VUC_Operations.Bits;
1540
 
1541
   ---------------
1542
   -- Write_Bit --
1543
   ---------------
1544
 
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;
1550
 
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;
1556
 
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;
1562
 
1563
   -----------------
1564
   -- Bound_Align --
1565
   -----------------
1566
 
1567
   function Bound_Align
1568
     (X : Integer_Address;
1569
      Y : Integer_Address) return Integer_Address
1570
   is
1571
      D : Integer_Address;
1572
   begin
1573
      D := X - X mod Y;
1574
      return D;
1575
   end Bound_Align;
1576
 
1577
   -----------------
1578
   -- NJ_Truncate --
1579
   -----------------
1580
 
1581
   function NJ_Truncate (X : C_float) return C_float is
1582
      D : C_float;
1583
 
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;
1592
 
1593
      return D;
1594
   end NJ_Truncate;
1595
 
1596
   -----------------------
1597
   -- Rnd_To_FP_Nearest --
1598
   -----------------------
1599
 
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;
1604
 
1605
   ---------------------
1606
   -- Rnd_To_FPI_Near --
1607
   ---------------------
1608
 
1609
   function Rnd_To_FPI_Near (X : F64) return F64 is
1610
      Result  : F64;
1611
      Ceiling : F64;
1612
 
1613
   begin
1614
      Result := F64 (SI64 (X));
1615
 
1616
      if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
1617
 
1618
         --  Round to even
1619
 
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;
1625
 
1626
      return Result;
1627
   end Rnd_To_FPI_Near;
1628
 
1629
   ----------------------
1630
   -- Rnd_To_FPI_Trunc --
1631
   ----------------------
1632
 
1633
   function Rnd_To_FPI_Trunc (X : F64) return F64 is
1634
      Result : F64;
1635
 
1636
   begin
1637
      Result := F64'Ceiling (X);
1638
 
1639
      --  Rnd_To_FPI_Trunc rounds toward 0, 'Ceiling rounds toward
1640
      --  +Infinity
1641
 
1642
      if X > 0.0
1643
        and then Result /= X
1644
      then
1645
         Result := Result - 1.0;
1646
      end if;
1647
 
1648
      return Result;
1649
   end Rnd_To_FPI_Trunc;
1650
 
1651
   ------------------
1652
   -- FP_Recip_Est --
1653
   ------------------
1654
 
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"
1661
 
1662
      return NJ_Truncate (1.0 / NJ_Truncate (X));
1663
   end FP_Recip_Est;
1664
 
1665
   ----------
1666
   -- ROTL --
1667
   ----------
1668
 
1669
   function ROTL
1670
     (Value  : unsigned_char;
1671
      Amount : Natural) return unsigned_char
1672
   is
1673
      Result : Unsigned_8;
1674
   begin
1675
      Result := Rotate_Left (Unsigned_8 (Value), Amount);
1676
      return unsigned_char (Result);
1677
   end ROTL;
1678
 
1679
   function ROTL
1680
     (Value  : unsigned_short;
1681
      Amount : Natural) return unsigned_short
1682
   is
1683
      Result : Unsigned_16;
1684
   begin
1685
      Result := Rotate_Left (Unsigned_16 (Value), Amount);
1686
      return unsigned_short (Result);
1687
   end ROTL;
1688
 
1689
   function ROTL
1690
     (Value  : unsigned_int;
1691
      Amount : Natural) return unsigned_int
1692
   is
1693
      Result : Unsigned_32;
1694
   begin
1695
      Result := Rotate_Left (Unsigned_32 (Value), Amount);
1696
      return unsigned_int (Result);
1697
   end ROTL;
1698
 
1699
   --------------------
1700
   -- Recip_SQRT_Est --
1701
   --------------------
1702
 
1703
   function Recip_SQRT_Est (X : C_float) return C_float is
1704
      Result : C_float;
1705
 
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"
1711
 
1712
      Result := 1.0 / NJ_Truncate (C_float_Operations.Sqrt (NJ_Truncate (X)));
1713
      return NJ_Truncate (Result);
1714
   end Recip_SQRT_Est;
1715
 
1716
   ----------------
1717
   -- Shift_Left --
1718
   ----------------
1719
 
1720
   function Shift_Left
1721
     (Value  : unsigned_char;
1722
      Amount : Natural) return unsigned_char
1723
   is
1724
      Result : Unsigned_8;
1725
   begin
1726
      Result := Shift_Left (Unsigned_8 (Value), Amount);
1727
      return unsigned_char (Result);
1728
   end Shift_Left;
1729
 
1730
   function Shift_Left
1731
     (Value  : unsigned_short;
1732
      Amount : Natural) return unsigned_short
1733
   is
1734
      Result : Unsigned_16;
1735
   begin
1736
      Result := Shift_Left (Unsigned_16 (Value), Amount);
1737
      return unsigned_short (Result);
1738
   end Shift_Left;
1739
 
1740
   function Shift_Left
1741
     (Value  : unsigned_int;
1742
      Amount : Natural) return unsigned_int
1743
   is
1744
      Result : Unsigned_32;
1745
   begin
1746
      Result := Shift_Left (Unsigned_32 (Value), Amount);
1747
      return unsigned_int (Result);
1748
   end Shift_Left;
1749
 
1750
   -----------------
1751
   -- Shift_Right --
1752
   -----------------
1753
 
1754
   function Shift_Right
1755
     (Value  : unsigned_char;
1756
      Amount : Natural) return unsigned_char
1757
   is
1758
      Result : Unsigned_8;
1759
   begin
1760
      Result := Shift_Right (Unsigned_8 (Value), Amount);
1761
      return unsigned_char (Result);
1762
   end Shift_Right;
1763
 
1764
   function Shift_Right
1765
     (Value  : unsigned_short;
1766
      Amount : Natural) return unsigned_short
1767
   is
1768
      Result : Unsigned_16;
1769
   begin
1770
      Result := Shift_Right (Unsigned_16 (Value), Amount);
1771
      return unsigned_short (Result);
1772
   end Shift_Right;
1773
 
1774
   function Shift_Right
1775
     (Value  : unsigned_int;
1776
      Amount : Natural) return unsigned_int
1777
   is
1778
      Result : Unsigned_32;
1779
   begin
1780
      Result := Shift_Right (Unsigned_32 (Value), Amount);
1781
      return unsigned_int (Result);
1782
   end Shift_Right;
1783
 
1784
   -------------------
1785
   -- Shift_Right_A --
1786
   -------------------
1787
 
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;
1796
 
1797
   function Shift_Right_Arithmetic
1798
     (Value  : Signed_Type;
1799
      Amount : Natural) return Signed_Type
1800
   is
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;
1809
 
1810
   function Shift_Right_A is new Shift_Right_Arithmetic (signed_int,
1811
                                                         Unsigned_32,
1812
                                                         Shift_Right);
1813
 
1814
   function Shift_Right_A is new Shift_Right_Arithmetic (signed_short,
1815
                                                         Unsigned_16,
1816
                                                         Shift_Right);
1817
 
1818
   function Shift_Right_A is new Shift_Right_Arithmetic (signed_char,
1819
                                                         Unsigned_8,
1820
                                                         Shift_Right);
1821
   --------------
1822
   -- To_Pixel --
1823
   --------------
1824
 
1825
   function To_Pixel (Source : unsigned_short) return Pixel_16 is
1826
 
1827
      --  This conversion should not depend on the host endianness;
1828
      --  therefore, we cannot use an unchecked conversion.
1829
 
1830
      Target : Pixel_16;
1831
 
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;
1839
 
1840
   function To_Pixel (Source : unsigned_int) return Pixel_32 is
1841
 
1842
      --  This conversion should not depend on the host endianness;
1843
      --  therefore, we cannot use an unchecked conversion.
1844
 
1845
      Target : Pixel_32;
1846
 
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;
1854
 
1855
   ---------------------
1856
   -- To_unsigned_int --
1857
   ---------------------
1858
 
1859
   function To_unsigned_int (Source : Pixel_32) return unsigned_int is
1860
 
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.
1865
 
1866
      Target : unsigned_int := 0;
1867
 
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
1874
      --
1875
      --  Sizes of the components: (8/8/8/8)
1876
      --
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;
1886
 
1887
   -----------------------
1888
   -- To_unsigned_short --
1889
   -----------------------
1890
 
1891
   function To_unsigned_short (Source : Pixel_16) return unsigned_short is
1892
 
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.
1897
 
1898
      Target : unsigned_short := 0;
1899
 
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
1906
      --
1907
      --  Sizes of the components: (1/5/5/5)
1908
      --
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;
1918
 
1919
   ---------------
1920
   -- abs_v16qi --
1921
   ---------------
1922
 
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;
1929
 
1930
   --------------
1931
   -- abs_v8hi --
1932
   --------------
1933
 
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;
1940
 
1941
   --------------
1942
   -- abs_v4si --
1943
   --------------
1944
 
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;
1951
 
1952
   --------------
1953
   -- abs_v4sf --
1954
   --------------
1955
 
1956
   function abs_v4sf (A : LL_VF) return LL_VF is
1957
      D  : Varray_float;
1958
      VA : constant VF_View := To_View (A);
1959
 
1960
   begin
1961
      for J in Varray_float'Range loop
1962
         D (J) := abs (VA.Values (J));
1963
      end loop;
1964
 
1965
      return To_Vector ((Values => D));
1966
   end abs_v4sf;
1967
 
1968
   ----------------
1969
   -- abss_v16qi --
1970
   ----------------
1971
 
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;
1978
 
1979
   ---------------
1980
   -- abss_v8hi --
1981
   ---------------
1982
 
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;
1989
 
1990
   ---------------
1991
   -- abss_v4si --
1992
   ---------------
1993
 
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;
2000
 
2001
   -------------
2002
   -- vaddubm --
2003
   -------------
2004
 
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;
2012
 
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;
2017
 
2018
   -------------
2019
   -- vadduhm --
2020
   -------------
2021
 
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;
2026
 
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;
2031
 
2032
   -------------
2033
   -- vadduwm --
2034
   -------------
2035
 
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;
2040
 
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;
2045
 
2046
   ------------
2047
   -- vaddfp --
2048
   ------------
2049
 
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;
2054
 
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;
2060
 
2061
      return To_Vector (VF_View'(Values => D));
2062
   end vaddfp;
2063
 
2064
   -------------
2065
   -- vaddcuw --
2066
   -------------
2067
 
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));
2073
 
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;
2080
 
2081
      return To_LL_VSI (To_Vector (D));
2082
   end vaddcuw;
2083
 
2084
   -------------
2085
   -- vaddubs --
2086
   -------------
2087
 
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));
2091
 
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;
2099
 
2100
   -------------
2101
   -- vaddsbs --
2102
   -------------
2103
 
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;
2108
 
2109
   begin
2110
      D.Values := LL_VSC_Operations.vaddsxs (VA.Values, VB.Values);
2111
      return To_Vector (D);
2112
   end vaddsbs;
2113
 
2114
   -------------
2115
   -- vadduhs --
2116
   -------------
2117
 
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;
2122
 
2123
   begin
2124
      D.Values := LL_VUS_Operations.vadduxs (VA.Values, VB.Values);
2125
      return To_LL_VSS (To_Vector (D));
2126
   end vadduhs;
2127
 
2128
   -------------
2129
   -- vaddshs --
2130
   -------------
2131
 
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;
2136
 
2137
   begin
2138
      D.Values := LL_VSS_Operations.vaddsxs (VA.Values, VB.Values);
2139
      return To_Vector (D);
2140
   end vaddshs;
2141
 
2142
   -------------
2143
   -- vadduws --
2144
   -------------
2145
 
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;
2150
 
2151
   begin
2152
      D.Values := LL_VUI_Operations.vadduxs (VA.Values, VB.Values);
2153
      return To_LL_VSI (To_Vector (D));
2154
   end vadduws;
2155
 
2156
   -------------
2157
   -- vaddsws --
2158
   -------------
2159
 
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;
2164
 
2165
   begin
2166
      D.Values := LL_VSI_Operations.vaddsxs (VA.Values, VB.Values);
2167
      return To_Vector (D);
2168
   end vaddsws;
2169
 
2170
   ----------
2171
   -- vand --
2172
   ----------
2173
 
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;
2178
 
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;
2183
 
2184
      return To_LL_VSI (To_Vector (D));
2185
   end vand;
2186
 
2187
   -----------
2188
   -- vandc --
2189
   -----------
2190
 
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;
2195
 
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;
2200
 
2201
      return To_LL_VSI (To_Vector (D));
2202
   end vandc;
2203
 
2204
   ------------
2205
   -- vavgub --
2206
   ------------
2207
 
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;
2212
 
2213
   begin
2214
      D.Values := LL_VUC_Operations.vavgux (VA.Values, VB.Values);
2215
      return To_LL_VSC (To_Vector (D));
2216
   end vavgub;
2217
 
2218
   ------------
2219
   -- vavgsb --
2220
   ------------
2221
 
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;
2226
 
2227
   begin
2228
      D.Values := LL_VSC_Operations.vavgsx (VA.Values, VB.Values);
2229
      return To_Vector (D);
2230
   end vavgsb;
2231
 
2232
   ------------
2233
   -- vavguh --
2234
   ------------
2235
 
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;
2240
 
2241
   begin
2242
      D.Values := LL_VUS_Operations.vavgux (VA.Values, VB.Values);
2243
      return To_LL_VSS (To_Vector (D));
2244
   end vavguh;
2245
 
2246
   ------------
2247
   -- vavgsh --
2248
   ------------
2249
 
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;
2254
 
2255
   begin
2256
      D.Values := LL_VSS_Operations.vavgsx (VA.Values, VB.Values);
2257
      return To_Vector (D);
2258
   end vavgsh;
2259
 
2260
   ------------
2261
   -- vavguw --
2262
   ------------
2263
 
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;
2268
 
2269
   begin
2270
      D.Values := LL_VUI_Operations.vavgux (VA.Values, VB.Values);
2271
      return To_LL_VSI (To_Vector (D));
2272
   end vavguw;
2273
 
2274
   ------------
2275
   -- vavgsw --
2276
   ------------
2277
 
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;
2282
 
2283
   begin
2284
      D.Values := LL_VSI_Operations.vavgsx (VA.Values, VB.Values);
2285
      return To_Vector (D);
2286
   end vavgsw;
2287
 
2288
   -----------
2289
   -- vrfip --
2290
   -----------
2291
 
2292
   function vrfip (A : LL_VF) return LL_VF is
2293
      VA : constant VF_View := To_View (A);
2294
      D  : VF_View;
2295
 
2296
   begin
2297
      for J in Varray_float'Range loop
2298
 
2299
         --  If A (J) is infinite, D (J) should be infinite; With
2300
         --  IEEE floating points, we can use 'Ceiling for that purpose.
2301
 
2302
         D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2303
 
2304
      end loop;
2305
 
2306
      return To_Vector (D);
2307
   end vrfip;
2308
 
2309
   -------------
2310
   -- vcmpbfp --
2311
   -------------
2312
 
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;
2318
 
2319
   begin
2320
      for J in Varray_float'Range loop
2321
         K := Vint_Range (J);
2322
         D.Values (K) := 0;
2323
 
2324
         if NJ_Truncate (VB.Values (J)) < 0.0 then
2325
 
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.
2329
 
2330
            D.Values (K) := Write_Bit (D.Values (K), 0, 1);
2331
            D.Values (K) := Write_Bit (D.Values (K), 1, 1);
2332
 
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));
2338
 
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;
2345
 
2346
      return To_LL_VSI (To_Vector (D));
2347
   end vcmpbfp;
2348
 
2349
   --------------
2350
   -- vcmpequb --
2351
   --------------
2352
 
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;
2357
 
2358
   begin
2359
      D.Values := LL_VUC_Operations.vcmpequx (VA.Values, VB.Values);
2360
      return To_LL_VSC (To_Vector (D));
2361
   end vcmpequb;
2362
 
2363
   --------------
2364
   -- vcmpequh --
2365
   --------------
2366
 
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;
2375
 
2376
   --------------
2377
   -- vcmpequw --
2378
   --------------
2379
 
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;
2388
 
2389
   --------------
2390
   -- vcmpeqfp --
2391
   --------------
2392
 
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;
2397
 
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;
2403
 
2404
      return To_LL_VSI (To_Vector (D));
2405
   end vcmpeqfp;
2406
 
2407
   --------------
2408
   -- vcmpgefp --
2409
   --------------
2410
 
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;
2415
 
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;
2422
 
2423
      return To_Vector (D);
2424
   end vcmpgefp;
2425
 
2426
   --------------
2427
   -- vcmpgtub --
2428
   --------------
2429
 
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;
2438
 
2439
   --------------
2440
   -- vcmpgtsb --
2441
   --------------
2442
 
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;
2451
 
2452
   --------------
2453
   -- vcmpgtuh --
2454
   --------------
2455
 
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;
2464
 
2465
   --------------
2466
   -- vcmpgtsh --
2467
   --------------
2468
 
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;
2477
 
2478
   --------------
2479
   -- vcmpgtuw --
2480
   --------------
2481
 
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;
2490
 
2491
   --------------
2492
   -- vcmpgtsw --
2493
   --------------
2494
 
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;
2503
 
2504
   --------------
2505
   -- vcmpgtfp --
2506
   --------------
2507
 
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;
2512
 
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;
2519
 
2520
      return To_Vector (D);
2521
   end vcmpgtfp;
2522
 
2523
   -----------
2524
   -- vcfux --
2525
   -----------
2526
 
2527
   function vcfux (A : LL_VSI; B : c_int) return LL_VF is
2528
      D  : VF_View;
2529
      VA : constant VUI_View := To_View (To_LL_VUI (A));
2530
      K  : Vfloat_Range;
2531
 
2532
   begin
2533
      for J in Varray_signed_int'Range loop
2534
         K := Vfloat_Range (J);
2535
 
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).
2539
 
2540
         D.Values (K) :=
2541
           C_float (VA.Values (J)) / (2.0 ** Integer (B));
2542
      end loop;
2543
 
2544
      return To_Vector (D);
2545
   end vcfux;
2546
 
2547
   -----------
2548
   -- vcfsx --
2549
   -----------
2550
 
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;
2555
 
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;
2562
 
2563
      return To_Vector (D);
2564
   end vcfsx;
2565
 
2566
   ------------
2567
   -- vctsxs --
2568
   ------------
2569
 
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;
2574
 
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;
2583
 
2584
      return To_Vector (D);
2585
   end vctsxs;
2586
 
2587
   ------------
2588
   -- vctuxs --
2589
   ------------
2590
 
2591
   function vctuxs (A : LL_VF; B : c_int) return LL_VSI is
2592
      VA : constant VF_View := To_View (A);
2593
      D  : VUI_View;
2594
      K  : Vfloat_Range;
2595
 
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;
2604
 
2605
      return To_LL_VSI (To_Vector (D));
2606
   end vctuxs;
2607
 
2608
   ---------
2609
   -- dss --
2610
   ---------
2611
 
2612
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2613
 
2614
   procedure dss (A : c_int) is
2615
      pragma Unreferenced (A);
2616
   begin
2617
      null;
2618
   end dss;
2619
 
2620
   ------------
2621
   -- dssall --
2622
   ------------
2623
 
2624
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2625
 
2626
   procedure dssall is
2627
   begin
2628
      null;
2629
   end dssall;
2630
 
2631
   ---------
2632
   -- dst --
2633
   ---------
2634
 
2635
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2636
 
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;
2644
 
2645
   -----------
2646
   -- dstst --
2647
   -----------
2648
 
2649
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2650
 
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;
2658
 
2659
   ------------
2660
   -- dststt --
2661
   ------------
2662
 
2663
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2664
 
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;
2672
 
2673
   ----------
2674
   -- dstt --
2675
   ----------
2676
 
2677
   --  No-ops, as allowed by [PEM-5.2.1.1 Data Stream Touch (dst)]:
2678
 
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;
2686
 
2687
   --------------
2688
   -- vexptefp --
2689
   --------------
2690
 
2691
   function vexptefp (A : LL_VF) return LL_VF is
2692
      use C_float_Operations;
2693
 
2694
      VA : constant VF_View := To_View (A);
2695
      D  : VF_View;
2696
 
2697
   begin
2698
      for J in Varray_float'Range loop
2699
 
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
2705
 
2706
         D.Values (J) := 2.0 ** NJ_Truncate (VA.Values (J));
2707
      end loop;
2708
 
2709
      return To_Vector (D);
2710
   end vexptefp;
2711
 
2712
   -----------
2713
   -- vrfim --
2714
   -----------
2715
 
2716
   function vrfim (A : LL_VF) return LL_VF is
2717
      VA : constant VF_View := To_View (A);
2718
      D  : VF_View;
2719
 
2720
   begin
2721
      for J in Varray_float'Range loop
2722
 
2723
         --  If A (J) is infinite, D (J) should be infinite; With
2724
         --  IEEE floating point, we can use 'Ceiling for that purpose.
2725
 
2726
         D.Values (J) := C_float'Ceiling (NJ_Truncate (VA.Values (J)));
2727
 
2728
         --  Vrfim rounds toward -Infinity, whereas 'Ceiling rounds toward
2729
         --  +Infinity:
2730
 
2731
         if D.Values (J) /= VA.Values (J) then
2732
            D.Values (J) := D.Values (J) - 1.0;
2733
         end if;
2734
      end loop;
2735
 
2736
      return To_Vector (D);
2737
   end vrfim;
2738
 
2739
   ---------
2740
   -- lvx --
2741
   ---------
2742
 
2743
   function lvx (A : c_long; B : c_ptr) return LL_VSI is
2744
 
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.
2748
 
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.
2755
 
2756
      EA : constant System.Address :=
2757
             To_Address
2758
               (Bound_Align
2759
                  (Integer_Address (A) + To_Integer (B), VECTOR_ALIGNMENT));
2760
 
2761
      D : LL_VSI;
2762
      for D'Address use EA;
2763
 
2764
   begin
2765
      return D;
2766
   end lvx;
2767
 
2768
   -----------
2769
   -- lvebx --
2770
   -----------
2771
 
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;
2778
 
2779
   -----------
2780
   -- lvehx --
2781
   -----------
2782
 
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;
2789
 
2790
   -----------
2791
   -- lvewx --
2792
   -----------
2793
 
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;
2800
 
2801
   ----------
2802
   -- lvxl --
2803
   ----------
2804
 
2805
   function lvxl  (A : c_long; B : c_ptr) return LL_VSI renames
2806
     lvx;
2807
 
2808
   -------------
2809
   -- vlogefp --
2810
   -------------
2811
 
2812
   function vlogefp (A : LL_VF) return LL_VF is
2813
      VA : constant VF_View := To_View (A);
2814
      D  : VF_View;
2815
 
2816
   begin
2817
      for J in Varray_float'Range loop
2818
 
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.
2825
 
2826
         D.Values (J) :=
2827
           C_float_Operations.Log (NJ_Truncate (VA.Values (J)), 2.0);
2828
      end loop;
2829
 
2830
      return To_Vector (D);
2831
   end vlogefp;
2832
 
2833
   ----------
2834
   -- lvsl --
2835
   ----------
2836
 
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;
2843
 
2844
   begin
2845
      EA := Integer_Address (A) + To_Integer (B);
2846
      SH := bit4_type (EA mod 2 ** 4);
2847
 
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;
2852
 
2853
      return To_LL_VSC (To_Vector (D));
2854
   end lvsl;
2855
 
2856
   ----------
2857
   -- lvsr --
2858
   ----------
2859
 
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;
2866
 
2867
   begin
2868
      EA := Integer_Address (A) + To_Integer (B);
2869
      SH := bit4_type (EA mod 2 ** 4);
2870
 
2871
      for J in D.Values'Range loop
2872
         D.Values (J) := (16#F# - unsigned_char (SH)) + unsigned_char (J);
2873
      end loop;
2874
 
2875
      return To_LL_VSC (To_Vector (D));
2876
   end lvsr;
2877
 
2878
   -------------
2879
   -- vmaddfp --
2880
   -------------
2881
 
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;
2887
 
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;
2895
 
2896
      return To_Vector (D);
2897
   end vmaddfp;
2898
 
2899
   ---------------
2900
   -- vmhaddshs --
2901
   ---------------
2902
 
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;
2908
 
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;
2915
 
2916
      return To_Vector (D);
2917
   end vmhaddshs;
2918
 
2919
   ------------
2920
   -- vmaxub --
2921
   ------------
2922
 
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;
2931
 
2932
   ------------
2933
   -- vmaxsb --
2934
   ------------
2935
 
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;
2944
 
2945
   ------------
2946
   -- vmaxuh --
2947
   ------------
2948
 
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;
2957
 
2958
   ------------
2959
   -- vmaxsh --
2960
   ------------
2961
 
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;
2970
 
2971
   ------------
2972
   -- vmaxuw --
2973
   ------------
2974
 
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;
2983
 
2984
   ------------
2985
   -- vmaxsw --
2986
   ------------
2987
 
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;
2996
 
2997
   --------------
2998
   -- vmaxsxfp --
2999
   --------------
3000
 
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;
3005
 
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;
3011
 
3012
      return To_Vector (D);
3013
   end vmaxfp;
3014
 
3015
   ------------
3016
   -- vmrghb --
3017
   ------------
3018
 
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;
3027
 
3028
   ------------
3029
   -- vmrghh --
3030
   ------------
3031
 
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;
3040
 
3041
   ------------
3042
   -- vmrghw --
3043
   ------------
3044
 
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;
3053
 
3054
   ------------
3055
   -- vmrglb --
3056
   ------------
3057
 
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;
3066
 
3067
   ------------
3068
   -- vmrglh --
3069
   ------------
3070
 
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;
3079
 
3080
   ------------
3081
   -- vmrglw --
3082
   ------------
3083
 
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;
3092
 
3093
   ------------
3094
   -- mfvscr --
3095
   ------------
3096
 
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;
3103
 
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;
3110
 
3111
   ------------
3112
   -- vminfp --
3113
   ------------
3114
 
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;
3119
 
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;
3125
 
3126
      return To_Vector (D);
3127
   end vminfp;
3128
 
3129
   ------------
3130
   -- vminsb --
3131
   ------------
3132
 
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;
3141
 
3142
   ------------
3143
   -- vminub --
3144
   ------------
3145
 
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;
3154
 
3155
   ------------
3156
   -- vminsh --
3157
   ------------
3158
 
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;
3167
 
3168
   ------------
3169
   -- vminuh --
3170
   ------------
3171
 
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;
3180
 
3181
   ------------
3182
   -- vminsw --
3183
   ------------
3184
 
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;
3193
 
3194
   ------------
3195
   -- vminuw --
3196
   ------------
3197
 
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;
3207
 
3208
   ---------------
3209
   -- vmladduhm --
3210
   ---------------
3211
 
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;
3217
 
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;
3223
 
3224
      return To_LL_VSS (To_Vector (D));
3225
   end vmladduhm;
3226
 
3227
   ----------------
3228
   -- vmhraddshs --
3229
   ----------------
3230
 
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;
3236
 
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;
3246
 
3247
      return To_Vector (D);
3248
   end vmhraddshs;
3249
 
3250
   --------------
3251
   -- vmsumubm --
3252
   --------------
3253
 
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;
3260
 
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;
3277
 
3278
      return To_LL_VSI (To_Vector (D));
3279
   end vmsumubm;
3280
 
3281
   --------------
3282
   -- vmsumumbm --
3283
   --------------
3284
 
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;
3291
 
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;
3311
 
3312
      return To_Vector (D);
3313
   end vmsummbm;
3314
 
3315
   --------------
3316
   -- vmsumuhm --
3317
   --------------
3318
 
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;
3325
 
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;
3339
 
3340
      return To_LL_VSI (To_Vector (D));
3341
   end vmsumuhm;
3342
 
3343
   --------------
3344
   -- vmsumshm --
3345
   --------------
3346
 
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;
3353
 
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;
3368
 
3369
      return To_Vector (D);
3370
   end vmsumshm;
3371
 
3372
   --------------
3373
   -- vmsumuhs --
3374
   --------------
3375
 
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;
3382
 
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;
3398
 
3399
      return To_LL_VSI (To_Vector (D));
3400
   end vmsumuhs;
3401
 
3402
   --------------
3403
   -- vmsumshs --
3404
   --------------
3405
 
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;
3412
 
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;
3428
 
3429
      return To_Vector (D);
3430
   end vmsumshs;
3431
 
3432
   ------------
3433
   -- mtvscr --
3434
   ------------
3435
 
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;
3441
 
3442
   -------------
3443
   -- vmuleub --
3444
   -------------
3445
 
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;
3456
 
3457
   -------------
3458
   -- vmuleuh --
3459
   -------------
3460
 
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;
3471
 
3472
   -------------
3473
   -- vmulesb --
3474
   -------------
3475
 
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;
3486
 
3487
   -------------
3488
   -- vmulesh --
3489
   -------------
3490
 
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;
3501
 
3502
   -------------
3503
   -- vmuloub --
3504
   -------------
3505
 
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;
3516
 
3517
   -------------
3518
   -- vmulouh --
3519
   -------------
3520
 
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;
3530
 
3531
   -------------
3532
   -- vmulosb --
3533
   -------------
3534
 
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;
3545
 
3546
   -------------
3547
   -- vmulosh --
3548
   -------------
3549
 
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;
3560
 
3561
   --------------
3562
   -- vnmsubfp --
3563
   --------------
3564
 
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;
3570
 
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;
3578
 
3579
      return To_Vector (D);
3580
   end vnmsubfp;
3581
 
3582
   ----------
3583
   -- vnor --
3584
   ----------
3585
 
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;
3590
 
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;
3595
 
3596
      return To_LL_VSI (To_Vector (D));
3597
   end vnor;
3598
 
3599
   ----------
3600
   -- vor --
3601
   ----------
3602
 
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;
3607
 
3608
   begin
3609
      for J in Vint_Range'Range loop
3610
         D.Values (J) := VA.Values (J) or VB.Values (J);
3611
      end loop;
3612
 
3613
      return To_LL_VSI (To_Vector (D));
3614
   end vor;
3615
 
3616
   -------------
3617
   -- vpkuhum --
3618
   -------------
3619
 
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;
3628
 
3629
   -------------
3630
   -- vpkuwum --
3631
   -------------
3632
 
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;
3641
 
3642
   -----------
3643
   -- vpkpx --
3644
   -----------
3645
 
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;
3653
 
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;
3670
 
3671
      return To_LL_VSS (To_Vector (D));
3672
   end vpkpx;
3673
 
3674
   -------------
3675
   -- vpkuhus --
3676
   -------------
3677
 
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;
3686
 
3687
   -------------
3688
   -- vpkuwus --
3689
   -------------
3690
 
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;
3699
 
3700
   -------------
3701
   -- vpkshss --
3702
   -------------
3703
 
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;
3712
 
3713
   -------------
3714
   -- vpkswss --
3715
   -------------
3716
 
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;
3725
 
3726
   -------------
3727
   -- vpksxus --
3728
   -------------
3729
 
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;
3739
 
3740
   function vpksxus
3741
     (A : Signed_Varray_Type;
3742
      B : Signed_Varray_Type) return Unsigned_Varray_Type;
3743
 
3744
   function vpksxus
3745
     (A : Signed_Varray_Type;
3746
      B : Signed_Varray_Type) return Unsigned_Varray_Type
3747
   is
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;
3753
 
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]
3758
 
3759
      --------------
3760
      -- Saturate --
3761
      --------------
3762
 
3763
      function Saturate
3764
        (X : Signed_Component_Type) return Unsigned_Component_Type
3765
      is
3766
         D : Unsigned_Component_Type;
3767
 
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;
3778
 
3779
         return D;
3780
      end Saturate;
3781
 
3782
      --  Start of processing for vpksxus
3783
 
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;
3795
 
3796
      return D;
3797
   end vpksxus;
3798
 
3799
   -------------
3800
   -- vpkshus --
3801
   -------------
3802
 
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);
3811
 
3812
      VA : constant VSS_View := To_View (A);
3813
      VB : constant VSS_View := To_View (B);
3814
      D  : VUC_View;
3815
 
3816
   begin
3817
      D.Values := vpkshus_Instance (VA.Values, VB.Values);
3818
      return To_LL_VSC (To_Vector (D));
3819
   end vpkshus;
3820
 
3821
   -------------
3822
   -- vpkswus --
3823
   -------------
3824
 
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);
3833
 
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;
3841
 
3842
   ---------------
3843
   -- vperm_4si --
3844
   ---------------
3845
 
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;
3852
 
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;
3861
 
3862
      return To_LL_VSI (To_Vector (D));
3863
   end vperm_4si;
3864
 
3865
   -----------
3866
   -- vrefp --
3867
   -----------
3868
 
3869
   function vrefp (A : LL_VF) return LL_VF is
3870
      VA : constant VF_View := To_View (A);
3871
      D  : VF_View;
3872
 
3873
   begin
3874
      for J in Vfloat_Range'Range loop
3875
         D.Values (J) := FP_Recip_Est (VA.Values (J));
3876
      end loop;
3877
 
3878
      return To_Vector (D);
3879
   end vrefp;
3880
 
3881
   ----------
3882
   -- vrlb --
3883
   ----------
3884
 
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;
3893
 
3894
   ----------
3895
   -- vrlh --
3896
   ----------
3897
 
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;
3906
 
3907
   ----------
3908
   -- vrlw --
3909
   ----------
3910
 
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;
3919
 
3920
   -----------
3921
   -- vrfin --
3922
   -----------
3923
 
3924
   function vrfin (A : LL_VF) return LL_VF is
3925
      VA : constant VF_View := To_View (A);
3926
      D  : VF_View;
3927
 
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;
3932
 
3933
      return To_Vector (D);
3934
   end vrfin;
3935
 
3936
   ---------------
3937
   -- vrsqrtefp --
3938
   ---------------
3939
 
3940
   function vrsqrtefp (A : LL_VF) return LL_VF is
3941
      VA : constant VF_View := To_View (A);
3942
      D  : VF_View;
3943
 
3944
   begin
3945
      for J in Vfloat_Range'Range loop
3946
         D.Values (J) := Recip_SQRT_Est (VA.Values (J));
3947
      end loop;
3948
 
3949
      return To_Vector (D);
3950
   end vrsqrtefp;
3951
 
3952
   --------------
3953
   -- vsel_4si --
3954
   --------------
3955
 
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;
3961
 
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;
3967
 
3968
      return To_LL_VSI (To_Vector (D));
3969
   end vsel_4si;
3970
 
3971
   ----------
3972
   -- vslb --
3973
   ----------
3974
 
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;
3984
 
3985
   ----------
3986
   -- vslh --
3987
   ----------
3988
 
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;
3998
 
3999
   ----------
4000
   -- vslw --
4001
   ----------
4002
 
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;
4012
 
4013
   ----------------
4014
   -- vsldoi_4si --
4015
   ----------------
4016
 
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;
4023
 
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);
4029
 
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;
4038
 
4039
      return To_LL_VSI (To_Vector (D));
4040
   end vsldoi_4si;
4041
 
4042
   ----------------
4043
   -- vsldoi_8hi --
4044
   ----------------
4045
 
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;
4050
 
4051
   -----------------
4052
   -- vsldoi_16qi --
4053
   -----------------
4054
 
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;
4059
 
4060
   ----------------
4061
   -- vsldoi_4sf --
4062
   ----------------
4063
 
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;
4068
 
4069
   ---------
4070
   -- vsl --
4071
   ---------
4072
 
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));
4079
 
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?
4083
 
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);
4088
 
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;
4095
 
4096
      return To_LL_VSI (To_Vector (D));
4097
   end vsl;
4098
 
4099
   ----------
4100
   -- vslo --
4101
   ----------
4102
 
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;
4110
 
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;
4118
 
4119
      return To_LL_VSI (To_Vector (D));
4120
   end vslo;
4121
 
4122
   ------------
4123
   -- vspltb --
4124
   ------------
4125
 
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;
4133
 
4134
   ------------
4135
   -- vsplth --
4136
   ------------
4137
 
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;
4145
 
4146
   ------------
4147
   -- vspltw --
4148
   ------------
4149
 
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;
4157
 
4158
   --------------
4159
   -- vspltisb --
4160
   --------------
4161
 
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;
4168
 
4169
   --------------
4170
   -- vspltish --
4171
   --------------
4172
 
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;
4179
 
4180
   --------------
4181
   -- vspltisw --
4182
   --------------
4183
 
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;
4190
 
4191
   ----------
4192
   -- vsrb --
4193
   ----------
4194
 
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;
4204
 
4205
   ----------
4206
   -- vsrh --
4207
   ----------
4208
 
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;
4218
 
4219
   ----------
4220
   -- vsrw --
4221
   ----------
4222
 
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;
4232
 
4233
   -----------
4234
   -- vsrab --
4235
   -----------
4236
 
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;
4246
 
4247
   -----------
4248
   -- vsrah --
4249
   -----------
4250
 
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;
4260
 
4261
   -----------
4262
   -- vsraw --
4263
   -----------
4264
 
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;
4274
 
4275
   ---------
4276
   -- vsr --
4277
   ---------
4278
 
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;
4285
 
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);
4290
 
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;
4297
 
4298
      return To_LL_VSI (To_Vector (D));
4299
   end vsr;
4300
 
4301
   ----------
4302
   -- vsro --
4303
   ----------
4304
 
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;
4312
 
4313
   begin
4314
      for N in Vchar_Range'Range loop
4315
         J := Natural (N) - M;
4316
 
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;
4323
 
4324
      return To_LL_VSI (To_Vector (D));
4325
   end vsro;
4326
 
4327
   ----------
4328
   -- stvx --
4329
   ----------
4330
 
4331
   procedure stvx   (A : LL_VSI; B : c_int; C : c_ptr) is
4332
 
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).
4336
 
4337
      EA : constant System.Address :=
4338
             To_Address
4339
               (Bound_Align
4340
                  (Integer_Address (B) + To_Integer (C), VECTOR_ALIGNMENT));
4341
 
4342
      D  : LL_VSI;
4343
      for D'Address use EA;
4344
 
4345
   begin
4346
      D := A;
4347
   end stvx;
4348
 
4349
   ------------
4350
   -- stvewx --
4351
   ------------
4352
 
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;
4358
 
4359
   ------------
4360
   -- stvehx --
4361
   ------------
4362
 
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;
4368
 
4369
   ------------
4370
   -- stvewx --
4371
   ------------
4372
 
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;
4378
 
4379
   -----------
4380
   -- stvxl --
4381
   -----------
4382
 
4383
   procedure stvxl   (A : LL_VSI; B : c_int; C : c_ptr) renames stvx;
4384
 
4385
   -------------
4386
   -- vsububm --
4387
   -------------
4388
 
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;
4397
 
4398
   -------------
4399
   -- vsubuhm --
4400
   -------------
4401
 
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;
4410
 
4411
   -------------
4412
   -- vsubuwm --
4413
   -------------
4414
 
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;
4423
 
4424
   ------------
4425
   -- vsubfp --
4426
   ------------
4427
 
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;
4432
 
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;
4439
 
4440
      return To_Vector (D);
4441
   end vsubfp;
4442
 
4443
   -------------
4444
   -- vsubcuw --
4445
   -------------
4446
 
4447
   function vsubcuw (A : LL_VSI; B : LL_VSI) return LL_VSI is
4448
      Subst_Result : SI64;
4449
 
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;
4453
 
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;
4460
 
4461
      return To_LL_VSI (To_Vector (D));
4462
   end vsubcuw;
4463
 
4464
   -------------
4465
   -- vsububs --
4466
   -------------
4467
 
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;
4476
 
4477
   -------------
4478
   -- vsubsbs --
4479
   -------------
4480
 
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;
4489
 
4490
   -------------
4491
   -- vsubuhs --
4492
   -------------
4493
 
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;
4502
 
4503
   -------------
4504
   -- vsubshs --
4505
   -------------
4506
 
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;
4515
 
4516
   -------------
4517
   -- vsubuws --
4518
   -------------
4519
 
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;
4528
 
4529
   -------------
4530
   -- vsubsws --
4531
   -------------
4532
 
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;
4541
 
4542
   --------------
4543
   -- vsum4ubs --
4544
   --------------
4545
 
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;
4551
 
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;
4563
 
4564
      return To_LL_VSI (To_Vector (D));
4565
   end vsum4ubs;
4566
 
4567
   --------------
4568
   -- vsum4sbs --
4569
   --------------
4570
 
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;
4576
 
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;
4588
 
4589
      return To_Vector (D);
4590
   end vsum4sbs;
4591
 
4592
   --------------
4593
   -- vsum4shs --
4594
   --------------
4595
 
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;
4601
 
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;
4611
 
4612
      return To_Vector (D);
4613
   end vsum4shs;
4614
 
4615
   --------------
4616
   -- vsum2sws --
4617
   --------------
4618
 
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;
4624
 
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;
4635
 
4636
      return To_Vector (D);
4637
   end vsum2sws;
4638
 
4639
   -------------
4640
   -- vsumsws --
4641
   -------------
4642
 
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;
4648
 
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;
4654
 
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;
4659
 
4660
   -----------
4661
   -- vrfiz --
4662
   -----------
4663
 
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;
4671
 
4672
      return To_Vector (D);
4673
   end vrfiz;
4674
 
4675
   -------------
4676
   -- vupkhsb --
4677
   -------------
4678
 
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;
4686
 
4687
   -------------
4688
   -- vupkhsh --
4689
   -------------
4690
 
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;
4698
 
4699
   -------------
4700
   -- vupkxpx --
4701
   -------------
4702
 
4703
   function vupkxpx (A : LL_VSS; Offset : Natural) return LL_VSI;
4704
   --  For vupkhpx and vupklpx (depending on Offset)
4705
 
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;
4712
 
4713
      function Sign_Extend (X : Unsigned_1) return unsigned_char;
4714
 
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;
4723
 
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;
4737
 
4738
      return To_LL_VSI (To_Vector (D));
4739
   end vupkxpx;
4740
 
4741
   -------------
4742
   -- vupkhpx --
4743
   -------------
4744
 
4745
   function vupkhpx (A : LL_VSS) return LL_VSI is
4746
   begin
4747
      return vupkxpx (A, 0);
4748
   end vupkhpx;
4749
 
4750
   -------------
4751
   -- vupklsb --
4752
   -------------
4753
 
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;
4763
 
4764
   -------------
4765
   -- vupklsh --
4766
   -------------
4767
 
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;
4777
 
4778
   -------------
4779
   -- vupklpx --
4780
   -------------
4781
 
4782
   function vupklpx (A : LL_VSS) return LL_VSI is
4783
   begin
4784
      return vupkxpx (A, Varray_signed_int'Length);
4785
   end vupklpx;
4786
 
4787
   ----------
4788
   -- vxor --
4789
   ----------
4790
 
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;
4795
 
4796
   begin
4797
      for J in Vint_Range'Range loop
4798
         D.Values (J) := VA.Values (J) xor VB.Values (J);
4799
      end loop;
4800
 
4801
      return To_LL_VSI (To_Vector (D));
4802
   end vxor;
4803
 
4804
   ----------------
4805
   -- vcmpequb_p --
4806
   ----------------
4807
 
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;
4814
 
4815
   ----------------
4816
   -- vcmpequh_p --
4817
   ----------------
4818
 
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;
4825
 
4826
   ----------------
4827
   -- vcmpequw_p --
4828
   ----------------
4829
 
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;
4836
 
4837
   ----------------
4838
   -- vcmpeqfp_p --
4839
   ----------------
4840
 
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;
4847
 
4848
   ----------------
4849
   -- vcmpgtub_p --
4850
   ----------------
4851
 
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;
4858
 
4859
   ----------------
4860
   -- vcmpgtuh_p --
4861
   ----------------
4862
 
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;
4869
 
4870
   ----------------
4871
   -- vcmpgtuw_p --
4872
   ----------------
4873
 
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;
4880
 
4881
   ----------------
4882
   -- vcmpgtsb_p --
4883
   ----------------
4884
 
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;
4891
 
4892
   ----------------
4893
   -- vcmpgtsh_p --
4894
   ----------------
4895
 
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;
4902
 
4903
   ----------------
4904
   -- vcmpgtsw_p --
4905
   ----------------
4906
 
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;
4913
 
4914
   ----------------
4915
   -- vcmpgefp_p --
4916
   ----------------
4917
 
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;
4924
 
4925
   ----------------
4926
   -- vcmpgtfp_p --
4927
   ----------------
4928
 
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;
4935
 
4936
   ----------------
4937
   -- vcmpbfp_p --
4938
   ----------------
4939
 
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));
4944
 
4945
      for J in Vint_Range'Range loop
4946
 
4947
         --  vcmpbfp is not returning the usual bool vector; do the conversion
4948
 
4949
         D.Values (J) :=
4950
           (if D.Values (J) = 0 then Signed_Bool_False else Signed_Bool_True);
4951
      end loop;
4952
 
4953
      return LL_VSI_Operations.Check_CR6 (A, D.Values);
4954
   end vcmpbfp_p;
4955
 
4956
end GNAT.Altivec.Low_Level_Vectors;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.