1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- $Revision: 1.16 $ --
11 -- Copyright (C) 1997-2001 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 with Atree; use Atree;
30 with Einfo; use Einfo;
31 with Nlists; use Nlists;
32 with Nmake; use Nmake;
33 with Rtsfind; use Rtsfind;
34 with Sem_Res; use Sem_Res;
35 with Sinfo; use Sinfo;
36 with Snames; use Snames;
37 with Stand; use Stand;
38 with Tbuild; use Tbuild;
39 with Ttypef; use Ttypef;
40 with Uintp; use Uintp;
41 with Urealp; use Urealp;
43 package body Exp_VFpt is
45 ----------------------
46 -- Expand_Vax_Arith --
47 ----------------------
49 procedure Expand_Vax_Arith (N : Node_Id) is
50 Loc : constant Source_Ptr := Sloc (N);
51 Typ : constant Entity_Id := Base_Type (Etype (N));
58 -- Get arithmetic type, note that we do D stuff in G
60 if Digits_Value (Typ) = VAXFF_Digits then
105 when N_Op_Subtract =>
120 if Nkind (N) in N_Binary_Op then
122 Convert_To (Atyp, Left_Opnd (N)));
126 Convert_To (Atyp, Right_Opnd (N)));
130 Make_Function_Call (Loc,
131 Name => New_Occurrence_Of (RTE (Func), Loc),
132 Parameter_Associations => Args)));
134 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
135 end Expand_Vax_Arith;
137 ---------------------------
138 -- Expand_Vax_Comparison --
139 ---------------------------
141 procedure Expand_Vax_Comparison (N : Node_Id) is
142 Loc : constant Source_Ptr := Sloc (N);
143 Typ : constant Entity_Id := Base_Type (Etype (Left_Opnd (N)));
147 Revrs : Boolean := False;
151 -- Get arithmetic type, note that we do D stuff in G
153 if Digits_Value (Typ) = VAXFF_Digits then
210 Convert_To (Atyp, Left_Opnd (N)),
211 Convert_To (Atyp, Right_Opnd (N)));
215 Convert_To (Atyp, Right_Opnd (N)),
216 Convert_To (Atyp, Left_Opnd (N)));
220 Make_Function_Call (Loc,
221 Name => New_Occurrence_Of (RTE (Func), Loc),
222 Parameter_Associations => Args));
224 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
225 end Expand_Vax_Comparison;
227 ---------------------------
228 -- Expand_Vax_Conversion --
229 ---------------------------
231 procedure Expand_Vax_Conversion (N : Node_Id) is
232 Loc : constant Source_Ptr := Sloc (N);
233 Expr : constant Node_Id := Expression (N);
234 S_Typ : constant Entity_Id := Base_Type (Etype (Expr));
235 T_Typ : constant Entity_Id := Base_Type (Etype (N));
241 function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id;
242 -- Given one of the two types T, determines the coresponding call
243 -- type, i.e. the type to be used for the call (or the result of
244 -- the call). The actual operand is converted to (or from) this type.
245 -- Otyp is the other type, which is useful in figuring out the result.
246 -- The result returned is the RE_Id value for the type entity.
248 function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id;
249 -- Find the predefined integer type that has the same size as the
250 -- fixed-point type T, for use in fixed/float conversions.
256 function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id is
260 if Vax_Float (T) then
261 if Digits_Value (T) = VAXFF_Digits then
264 elsif Digits_Value (T) = VAXGF_Digits then
267 -- For D_Float, leave it as D float if the other operand is
268 -- G_Float, since this is the one conversion that is properly
269 -- supported for D_Float, but otherwise, use G_Float.
271 else pragma Assert (Digits_Value (T) = VAXDF_Digits);
274 and then Digits_Value (Otyp) = VAXGF_Digits
282 -- For all discrete types, use 64-bit integer
284 elsif Is_Discrete_Type (T) then
287 -- For all real types (other than Vax float format), we use the
288 -- IEEE float-type which corresponds in length to the other type
289 -- (which is Vax Float).
291 else pragma Assert (Is_Real_Type (T));
293 if Digits_Value (Otyp) = VAXFF_Digits then
301 function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id is
303 if Esize (T) = Esize (Standard_Long_Long_Integer) then
304 return Standard_Long_Long_Integer;
306 elsif Esize (T) = Esize (Standard_Long_Integer) then
307 return Standard_Long_Integer;
310 return Standard_Integer;
312 end Equivalent_Integer_Type;
315 -- Start of processing for Expand_Vax_Conversion;
318 -- If input and output are the same Vax type, we change the
319 -- conversion to be an unchecked conversion and that's it.
321 if Vax_Float (S_Typ) and then Vax_Float (T_Typ)
322 and then Digits_Value (S_Typ) = Digits_Value (T_Typ)
325 Unchecked_Convert_To (T_Typ, Expr));
328 elsif Is_Fixed_Point_Type (S_Typ) then
330 -- convert the scaled integer value to the target type, and multiply
331 -- by 'Small of type.
334 Make_Op_Multiply (Loc,
336 Make_Type_Conversion (Loc,
337 Subtype_Mark => New_Occurrence_Of (T_Typ, Loc),
339 Unchecked_Convert_To (
340 Equivalent_Integer_Type (S_Typ), Expr)),
342 Make_Real_Literal (Loc, Realval => Small_Value (S_Typ))));
344 elsif Is_Fixed_Point_Type (T_Typ) then
346 -- multiply value by 'small of type, and convert to the corresponding
350 Unchecked_Convert_To (T_Typ,
351 Make_Type_Conversion (Loc,
353 New_Occurrence_Of (Equivalent_Integer_Type (T_Typ), Loc),
355 Make_Op_Multiply (Loc,
358 Make_Real_Literal (Loc,
359 Realval => Ureal_1 / Small_Value (T_Typ))))));
364 -- Compute types for call
366 CallS := Call_Type (S_Typ, T_Typ);
367 CallT := Call_Type (T_Typ, S_Typ);
369 -- Get function and its types
371 if CallS = RE_D and then CallT = RE_G then
374 elsif CallS = RE_G and then CallT = RE_D then
377 elsif CallS = RE_G and then CallT = RE_F then
380 elsif CallS = RE_F and then CallT = RE_G then
383 elsif CallS = RE_F and then CallT = RE_S then
386 elsif CallS = RE_S and then CallT = RE_F then
389 elsif CallS = RE_G and then CallT = RE_T then
392 elsif CallS = RE_T and then CallT = RE_G then
395 elsif CallS = RE_F and then CallT = RE_Q then
398 elsif CallS = RE_Q and then CallT = RE_F then
401 elsif CallS = RE_G and then CallT = RE_Q then
404 else pragma Assert (CallS = RE_Q and then CallT = RE_G);
410 Make_Function_Call (Loc,
411 Name => New_Occurrence_Of (RTE (Func), Loc),
412 Parameter_Associations => New_List (
413 Convert_To (RTE (CallS), Expr)))));
416 Analyze_And_Resolve (N, T_Typ, Suppress => All_Checks);
417 end Expand_Vax_Conversion;
419 -----------------------------
420 -- Expand_Vax_Real_Literal --
421 -----------------------------
423 procedure Expand_Vax_Real_Literal (N : Node_Id) is
424 Loc : constant Source_Ptr := Sloc (N);
425 Typ : constant Entity_Id := Etype (N);
426 Btyp : constant Entity_Id := Base_Type (Typ);
427 Stat : constant Boolean := Is_Static_Expression (N);
433 -- Entities for source, target and function call in conversion
436 -- We do not know how to convert Vax format real literals, so what
437 -- we do is to convert these to be IEEE literals, and introduce the
438 -- necessary conversion operation.
440 if Vax_Float (Btyp) then
441 -- What we want to construct here is
443 -- x!(y_to_z (1.0E0))
447 -- x is the base type of the literal (Btyp)
451 -- s_to_f for F_Float
452 -- t_to_g for G_Float
453 -- t_to_d for D_Float
455 -- The literal is typed as S (for F_Float) or T otherwise
457 -- We do all our own construction, analysis, and expansion here,
458 -- since things are at too low a level to use Analyze or Expand
459 -- to get this built (we get circularities and other strange
460 -- problems if we try!)
462 if Digits_Value (Btyp) = VAXFF_Digits then
465 RE_Fncall := RE_S_To_F;
467 elsif Digits_Value (Btyp) = VAXDF_Digits then
470 RE_Fncall := RE_T_To_D;
472 else pragma Assert (Digits_Value (Btyp) = VAXGF_Digits);
475 RE_Fncall := RE_T_To_G;
478 Nod := Relocate_Node (N);
480 Set_Etype (Nod, RTE (RE_Source));
481 Set_Analyzed (Nod, True);
484 Make_Function_Call (Loc,
485 Name => New_Occurrence_Of (RTE (RE_Fncall), Loc),
486 Parameter_Associations => New_List (Nod));
488 Set_Etype (Nod, RTE (RE_Target));
489 Set_Analyzed (Nod, True);
492 Make_Unchecked_Type_Conversion (Loc,
493 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
496 Set_Etype (Nod, Typ);
497 Set_Analyzed (Nod, True);
500 -- This odd expression is still a static expression. Note that
501 -- the routine Sem_Eval.Expr_Value_R understands this.
503 Set_Is_Static_Expression (N, Stat);
505 end Expand_Vax_Real_Literal;