OSDN Git Service

2009-04-08 Thomas Quinot <quinot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-geveop.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
4 --                                                                          --
5 --      S Y S T E M . G E N E R I C _ V E C T O R _ O P E R A T I O N S     --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2002-2007, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 with System;                    use System;
35 with System.Address_Operations; use System.Address_Operations;
36 with System.Storage_Elements;   use System.Storage_Elements;
37
38 with Ada.Unchecked_Conversion;
39
40 package body System.Generic_Vector_Operations is
41
42    IU : constant Integer := Integer (Storage_Unit);
43    VU : constant Address := Address (Vectors.Vector'Size / IU);
44    EU : constant Address := Address (Element_Array'Component_Size / IU);
45
46    ----------------------
47    -- Binary_Operation --
48    ----------------------
49
50    procedure Binary_Operation
51      (R, X, Y : System.Address;
52       Length  : System.Storage_Elements.Storage_Count)
53    is
54       RA : Address := R;
55       XA : Address := X;
56       YA : Address := Y;
57       --  Address of next element to process in R, X and Y
58
59       VI : constant Integer_Address := To_Integer (VU);
60
61       Unaligned : constant Integer_Address :=
62                     Boolean'Pos (ModA (OrA (OrA (RA, XA), YA), VU) /= 0) - 1;
63       --  Zero iff one or more argument addresses is not aligned, else all 1's
64
65       type Vector_Ptr is access all Vectors.Vector;
66       type Element_Ptr is access all Element;
67
68       function VP is new Ada.Unchecked_Conversion (Address, Vector_Ptr);
69       function EP is new Ada.Unchecked_Conversion (Address, Element_Ptr);
70
71       SA : constant Address :=
72              AddA (XA, To_Address
73                          ((Integer_Address (Length) / VI * VI) and Unaligned));
74       --  First address of argument X to start serial processing
75
76    begin
77       while XA < SA loop
78          VP (RA).all := Vector_Op (VP (XA).all, VP (YA).all);
79          XA := AddA (XA, VU);
80          YA := AddA (YA, VU);
81          RA := AddA (RA, VU);
82       end loop;
83
84       while XA < X + Length loop
85          EP (RA).all := Element_Op (EP (XA).all, EP (YA).all);
86          XA := AddA (XA, EU);
87          YA := AddA (YA, EU);
88          RA := AddA (RA, EU);
89       end loop;
90    end Binary_Operation;
91
92    ----------------------
93    -- Unary_Operation --
94    ----------------------
95
96    procedure Unary_Operation
97      (R, X    : System.Address;
98       Length  : System.Storage_Elements.Storage_Count)
99    is
100       RA : Address := R;
101       XA : Address := X;
102       --  Address of next element to process in R and X
103
104       VI : constant Integer_Address := To_Integer (VU);
105
106       Unaligned : constant Integer_Address :=
107                     Boolean'Pos (ModA (OrA (RA, XA), VU) /= 0) - 1;
108       --  Zero iff one or more argument addresses is not aligned, else all 1's
109
110       type Vector_Ptr is access all Vectors.Vector;
111       type Element_Ptr is access all Element;
112
113       function VP is new Ada.Unchecked_Conversion (Address, Vector_Ptr);
114       function EP is new Ada.Unchecked_Conversion (Address, Element_Ptr);
115
116       SA : constant Address :=
117              AddA (XA, To_Address
118                          ((Integer_Address (Length) / VI * VI) and Unaligned));
119       --  First address of argument X to start serial processing
120
121    begin
122       while XA < SA loop
123          VP (RA).all := Vector_Op (VP (XA).all);
124          XA := AddA (XA, VU);
125          RA := AddA (RA, VU);
126       end loop;
127
128       while XA < X + Length loop
129          EP (RA).all := Element_Op (EP (XA).all);
130          XA := AddA (XA, EU);
131          RA := AddA (RA, EU);
132       end loop;
133    end Unary_Operation;
134
135 end System.Generic_Vector_Operations;