OSDN Git Service

Delete all lines containing "$Revision:".
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_vfpt.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             E X P _ V F P T                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                                                                          --
10 --          Copyright (C) 1997-2001 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 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 with Atree;    use Atree;
29 with Einfo;    use Einfo;
30 with Nlists;   use Nlists;
31 with Nmake;    use Nmake;
32 with Rtsfind;  use Rtsfind;
33 with Sem_Res;  use Sem_Res;
34 with Sinfo;    use Sinfo;
35 with Snames;   use Snames;
36 with Stand;    use Stand;
37 with Tbuild;   use Tbuild;
38 with Ttypef;   use Ttypef;
39 with Uintp;    use Uintp;
40 with Urealp;   use Urealp;
41
42 package body Exp_VFpt is
43
44    ----------------------
45    -- Expand_Vax_Arith --
46    ----------------------
47
48    procedure Expand_Vax_Arith (N : Node_Id) is
49       Loc   : constant Source_Ptr := Sloc (N);
50       Typ   : constant Entity_Id  := Base_Type (Etype (N));
51       Typc  : Character;
52       Atyp  : Entity_Id;
53       Func  : RE_Id;
54       Args  : List_Id;
55
56    begin
57       --  Get arithmetic type, note that we do D stuff in G
58
59       if Digits_Value (Typ) = VAXFF_Digits then
60          Typc := 'F';
61          Atyp := RTE (RE_F);
62       else
63          Typc := 'G';
64          Atyp := RTE (RE_G);
65       end if;
66
67       case Nkind (N) is
68
69          when N_Op_Abs =>
70             if Typc = 'F' then
71                Func := RE_Abs_F;
72             else
73                Func := RE_Abs_G;
74             end if;
75
76          when N_Op_Add =>
77             if Typc = 'F' then
78                Func := RE_Add_F;
79             else
80                Func := RE_Add_G;
81             end if;
82
83          when N_Op_Divide =>
84             if Typc = 'F' then
85                Func := RE_Div_F;
86             else
87                Func := RE_Div_G;
88             end if;
89
90          when N_Op_Multiply =>
91             if Typc = 'F' then
92                Func := RE_Mul_F;
93             else
94                Func := RE_Mul_G;
95             end if;
96
97          when N_Op_Minus =>
98             if Typc = 'F' then
99                Func := RE_Neg_F;
100             else
101                Func := RE_Neg_G;
102             end if;
103
104          when N_Op_Subtract =>
105             if Typc = 'F' then
106                Func := RE_Sub_F;
107             else
108                Func := RE_Sub_G;
109             end if;
110
111          when others =>
112             Func := RE_Null;
113             raise Program_Error;
114
115       end case;
116
117       Args := New_List;
118
119       if Nkind (N) in N_Binary_Op then
120          Append_To (Args,
121            Convert_To (Atyp, Left_Opnd (N)));
122       end if;
123
124       Append_To (Args,
125         Convert_To (Atyp, Right_Opnd (N)));
126
127       Rewrite (N,
128         Convert_To (Typ,
129           Make_Function_Call (Loc,
130             Name => New_Occurrence_Of (RTE (Func), Loc),
131             Parameter_Associations => Args)));
132
133       Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
134    end Expand_Vax_Arith;
135
136    ---------------------------
137    -- Expand_Vax_Comparison --
138    ---------------------------
139
140    procedure Expand_Vax_Comparison (N : Node_Id) is
141       Loc   : constant Source_Ptr := Sloc (N);
142       Typ   : constant Entity_Id  := Base_Type (Etype (Left_Opnd (N)));
143       Typc  : Character;
144       Func  : RE_Id;
145       Atyp  : Entity_Id;
146       Revrs : Boolean := False;
147       Args  : List_Id;
148
149    begin
150       --  Get arithmetic type, note that we do D stuff in G
151
152       if Digits_Value (Typ) = VAXFF_Digits then
153          Typc := 'F';
154          Atyp := RTE (RE_F);
155       else
156          Typc := 'G';
157          Atyp := RTE (RE_G);
158       end if;
159
160       case Nkind (N) is
161
162          when N_Op_Eq =>
163             if Typc = 'F' then
164                Func := RE_Eq_F;
165             else
166                Func := RE_Eq_G;
167             end if;
168
169          when N_Op_Ge =>
170             if Typc = 'F' then
171                Func := RE_Le_F;
172             else
173                Func := RE_Le_G;
174             end if;
175
176             Revrs := True;
177
178          when N_Op_Gt =>
179             if Typc = 'F' then
180                Func := RE_Lt_F;
181             else
182                Func := RE_Lt_G;
183             end if;
184
185             Revrs := True;
186
187          when N_Op_Le =>
188             if Typc = 'F' then
189                Func := RE_Le_F;
190             else
191                Func := RE_Le_G;
192             end if;
193
194          when N_Op_Lt =>
195             if Typc = 'F' then
196                Func := RE_Lt_F;
197             else
198                Func := RE_Lt_G;
199             end if;
200
201          when others =>
202             Func := RE_Null;
203             raise Program_Error;
204
205       end case;
206
207       if not Revrs then
208          Args := New_List (
209            Convert_To (Atyp, Left_Opnd  (N)),
210            Convert_To (Atyp, Right_Opnd (N)));
211
212       else
213          Args := New_List (
214            Convert_To (Atyp, Right_Opnd (N)),
215            Convert_To (Atyp, Left_Opnd  (N)));
216       end if;
217
218       Rewrite (N,
219         Make_Function_Call (Loc,
220           Name => New_Occurrence_Of (RTE (Func), Loc),
221           Parameter_Associations => Args));
222
223       Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
224    end Expand_Vax_Comparison;
225
226    ---------------------------
227    -- Expand_Vax_Conversion --
228    ---------------------------
229
230    procedure Expand_Vax_Conversion (N : Node_Id) is
231       Loc   : constant Source_Ptr := Sloc (N);
232       Expr  : constant Node_Id    := Expression (N);
233       S_Typ : constant Entity_Id  := Base_Type (Etype (Expr));
234       T_Typ : constant Entity_Id  := Base_Type (Etype (N));
235
236       CallS : RE_Id;
237       CallT : RE_Id;
238       Func  : RE_Id;
239
240       function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id;
241       --  Given one of the two types T, determines the coresponding call
242       --  type, i.e. the type to be used for the call (or the result of
243       --  the call). The actual operand is converted to (or from) this type.
244       --  Otyp is the other type, which is useful in figuring out the result.
245       --  The result returned is the RE_Id value for the type entity.
246
247       function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id;
248       --  Find the predefined integer type that has the same size as the
249       --  fixed-point type T, for use in fixed/float conversions.
250
251       ---------------
252       -- Call_Type --
253       ---------------
254
255       function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id is
256       begin
257          --  Vax float formats
258
259          if Vax_Float (T) then
260             if Digits_Value (T) = VAXFF_Digits then
261                return RE_F;
262
263             elsif Digits_Value (T) = VAXGF_Digits then
264                return RE_G;
265
266             --  For D_Float, leave it as D float if the other operand is
267             --  G_Float, since this is the one conversion that is properly
268             --  supported for D_Float, but otherwise, use G_Float.
269
270             else pragma Assert (Digits_Value (T) = VAXDF_Digits);
271
272                if Vax_Float (Otyp)
273                  and then Digits_Value (Otyp) = VAXGF_Digits
274                then
275                   return RE_D;
276                else
277                   return RE_G;
278                end if;
279             end if;
280
281          --  For all discrete types, use 64-bit integer
282
283          elsif Is_Discrete_Type (T) then
284             return RE_Q;
285
286          --  For all real types (other than Vax float format), we use the
287          --  IEEE float-type which corresponds in length to the other type
288          --  (which is Vax Float).
289
290          else pragma Assert (Is_Real_Type (T));
291
292             if Digits_Value (Otyp) = VAXFF_Digits then
293                return RE_S;
294             else
295                return RE_T;
296             end if;
297          end if;
298       end Call_Type;
299
300       function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id is
301       begin
302          if Esize (T) = Esize (Standard_Long_Long_Integer) then
303             return Standard_Long_Long_Integer;
304
305          elsif Esize (T) = Esize (Standard_Long_Integer) then
306             return  Standard_Long_Integer;
307
308          else
309             return Standard_Integer;
310          end if;
311       end Equivalent_Integer_Type;
312
313
314    --  Start of processing for Expand_Vax_Conversion;
315
316    begin
317       --  If input and output are the same Vax type, we change the
318       --  conversion to be an unchecked conversion and that's it.
319
320       if Vax_Float (S_Typ) and then Vax_Float (T_Typ)
321         and then Digits_Value (S_Typ) = Digits_Value (T_Typ)
322       then
323          Rewrite (N,
324            Unchecked_Convert_To (T_Typ, Expr));
325
326
327       elsif Is_Fixed_Point_Type (S_Typ) then
328
329          --  convert the scaled integer value to the target type, and multiply
330          --  by 'Small of type.
331
332          Rewrite (N,
333             Make_Op_Multiply (Loc,
334               Left_Opnd =>
335                 Make_Type_Conversion (Loc,
336                   Subtype_Mark => New_Occurrence_Of (T_Typ, Loc),
337                   Expression   =>
338                     Unchecked_Convert_To (
339                       Equivalent_Integer_Type (S_Typ), Expr)),
340               Right_Opnd =>
341                 Make_Real_Literal (Loc, Realval => Small_Value (S_Typ))));
342
343       elsif Is_Fixed_Point_Type (T_Typ) then
344
345          --  multiply value by 'small of type, and convert to the corresponding
346          --  integer type.
347
348          Rewrite (N,
349            Unchecked_Convert_To (T_Typ,
350              Make_Type_Conversion (Loc,
351                Subtype_Mark =>
352                  New_Occurrence_Of (Equivalent_Integer_Type (T_Typ), Loc),
353                Expression =>
354                  Make_Op_Multiply (Loc,
355                    Left_Opnd => Expr,
356                    Right_Opnd =>
357                      Make_Real_Literal (Loc,
358                        Realval => Ureal_1 / Small_Value (T_Typ))))));
359
360       --  All other cases.
361
362       else
363          --  Compute types for call
364
365          CallS := Call_Type (S_Typ, T_Typ);
366          CallT := Call_Type (T_Typ, S_Typ);
367
368          --  Get function and its types
369
370          if CallS = RE_D and then CallT = RE_G then
371             Func := RE_D_To_G;
372
373          elsif CallS = RE_G and then CallT = RE_D then
374             Func := RE_G_To_D;
375
376          elsif CallS = RE_G and then CallT = RE_F then
377             Func := RE_G_To_F;
378
379          elsif CallS = RE_F and then CallT = RE_G then
380             Func := RE_F_To_G;
381
382          elsif CallS = RE_F and then CallT = RE_S then
383             Func := RE_F_To_S;
384
385          elsif CallS = RE_S and then CallT = RE_F then
386             Func := RE_S_To_F;
387
388          elsif CallS = RE_G and then CallT = RE_T then
389             Func := RE_G_To_T;
390
391          elsif CallS = RE_T and then CallT = RE_G then
392             Func := RE_T_To_G;
393
394          elsif CallS = RE_F and then CallT = RE_Q then
395             Func := RE_F_To_Q;
396
397          elsif CallS = RE_Q and then CallT = RE_F then
398             Func := RE_Q_To_F;
399
400          elsif CallS = RE_G and then CallT = RE_Q then
401             Func := RE_G_To_Q;
402
403          else pragma Assert (CallS = RE_Q and then CallT = RE_G);
404             Func := RE_Q_To_G;
405          end if;
406
407          Rewrite (N,
408            Convert_To (T_Typ,
409              Make_Function_Call (Loc,
410                Name => New_Occurrence_Of (RTE (Func), Loc),
411                Parameter_Associations => New_List (
412                  Convert_To (RTE (CallS), Expr)))));
413       end if;
414
415       Analyze_And_Resolve (N, T_Typ, Suppress => All_Checks);
416    end Expand_Vax_Conversion;
417
418    -----------------------------
419    -- Expand_Vax_Real_Literal --
420    -----------------------------
421
422    procedure Expand_Vax_Real_Literal (N : Node_Id) is
423       Loc  : constant Source_Ptr := Sloc (N);
424       Typ  : constant Entity_Id  := Etype (N);
425       Btyp : constant Entity_Id  := Base_Type (Typ);
426       Stat : constant Boolean    := Is_Static_Expression (N);
427       Nod  : Node_Id;
428
429       RE_Source : RE_Id;
430       RE_Target : RE_Id;
431       RE_Fncall : RE_Id;
432       --  Entities for source, target and function call in conversion
433
434    begin
435       --  We do not know how to convert Vax format real literals, so what
436       --  we do is to convert these to be IEEE literals, and introduce the
437       --  necessary conversion operation.
438
439       if Vax_Float (Btyp) then
440          --  What we want to construct here is
441
442          --    x!(y_to_z (1.0E0))
443
444          --  where
445
446          --    x is the base type of the literal (Btyp)
447
448          --    y_to_z is
449
450          --      s_to_f for F_Float
451          --      t_to_g for G_Float
452          --      t_to_d for D_Float
453
454          --  The literal is typed as S (for F_Float) or T otherwise
455
456          --  We do all our own construction, analysis, and expansion here,
457          --  since things are at too low a level to use Analyze or Expand
458          --  to get this built (we get circularities and other strange
459          --  problems if we try!)
460
461          if Digits_Value (Btyp) = VAXFF_Digits then
462             RE_Source := RE_S;
463             RE_Target := RE_F;
464             RE_Fncall := RE_S_To_F;
465
466          elsif Digits_Value (Btyp) = VAXDF_Digits then
467             RE_Source := RE_T;
468             RE_Target := RE_D;
469             RE_Fncall := RE_T_To_D;
470
471          else pragma Assert (Digits_Value (Btyp) = VAXGF_Digits);
472             RE_Source := RE_T;
473             RE_Target := RE_G;
474             RE_Fncall := RE_T_To_G;
475          end if;
476
477          Nod := Relocate_Node (N);
478
479          Set_Etype (Nod, RTE (RE_Source));
480          Set_Analyzed (Nod, True);
481
482          Nod :=
483            Make_Function_Call (Loc,
484              Name => New_Occurrence_Of (RTE (RE_Fncall), Loc),
485              Parameter_Associations => New_List (Nod));
486
487          Set_Etype (Nod, RTE (RE_Target));
488          Set_Analyzed (Nod, True);
489
490          Nod :=
491            Make_Unchecked_Type_Conversion (Loc,
492              Subtype_Mark => New_Occurrence_Of (Typ, Loc),
493              Expression   => Nod);
494
495          Set_Etype (Nod, Typ);
496          Set_Analyzed (Nod, True);
497          Rewrite (N, Nod);
498
499          --  This odd expression is still a static expression. Note that
500          --  the routine Sem_Eval.Expr_Value_R understands this.
501
502          Set_Is_Static_Expression (N, Stat);
503       end if;
504    end Expand_Vax_Real_Literal;
505
506 end Exp_VFpt;