1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
10 -- Copyright (C) 1997-2001 Free Software Foundation, Inc. --
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. --
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). --
26 ------------------------------------------------------------------------------
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
;
42 package body Exp_VFpt
is
44 ----------------------
45 -- Expand_Vax_Arith --
46 ----------------------
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
));
57 -- Get arithmetic type, note that we do D stuff in G
59 if Digits_Value
(Typ
) = VAXFF_Digits
then
104 when N_Op_Subtract
=>
119 if Nkind
(N
) in N_Binary_Op
then
121 Convert_To
(Atyp
, Left_Opnd
(N
)));
125 Convert_To
(Atyp
, Right_Opnd
(N
)));
129 Make_Function_Call
(Loc
,
130 Name
=> New_Occurrence_Of
(RTE
(Func
), Loc
),
131 Parameter_Associations
=> Args
)));
133 Analyze_And_Resolve
(N
, Typ
, Suppress
=> All_Checks
);
134 end Expand_Vax_Arith
;
136 ---------------------------
137 -- Expand_Vax_Comparison --
138 ---------------------------
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
)));
146 Revrs
: Boolean := False;
150 -- Get arithmetic type, note that we do D stuff in G
152 if Digits_Value
(Typ
) = VAXFF_Digits
then
209 Convert_To
(Atyp
, Left_Opnd
(N
)),
210 Convert_To
(Atyp
, Right_Opnd
(N
)));
214 Convert_To
(Atyp
, Right_Opnd
(N
)),
215 Convert_To
(Atyp
, Left_Opnd
(N
)));
219 Make_Function_Call
(Loc
,
220 Name
=> New_Occurrence_Of
(RTE
(Func
), Loc
),
221 Parameter_Associations
=> Args
));
223 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
224 end Expand_Vax_Comparison
;
226 ---------------------------
227 -- Expand_Vax_Conversion --
228 ---------------------------
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
));
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.
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.
255 function Call_Type
(T
: Entity_Id
; Otyp
: Entity_Id
) return RE_Id
is
259 if Vax_Float
(T
) then
260 if Digits_Value
(T
) = VAXFF_Digits
then
263 elsif Digits_Value
(T
) = VAXGF_Digits
then
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.
270 else pragma Assert
(Digits_Value
(T
) = VAXDF_Digits
);
273 and then Digits_Value
(Otyp
) = VAXGF_Digits
281 -- For all discrete types, use 64-bit integer
283 elsif Is_Discrete_Type
(T
) then
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).
290 else pragma Assert
(Is_Real_Type
(T
));
292 if Digits_Value
(Otyp
) = VAXFF_Digits
then
300 function Equivalent_Integer_Type
(T
: Entity_Id
) return Entity_Id
is
302 if Esize
(T
) = Esize
(Standard_Long_Long_Integer
) then
303 return Standard_Long_Long_Integer
;
305 elsif Esize
(T
) = Esize
(Standard_Long_Integer
) then
306 return Standard_Long_Integer
;
309 return Standard_Integer
;
311 end Equivalent_Integer_Type
;
314 -- Start of processing for Expand_Vax_Conversion;
317 -- If input and output are the same Vax type, we change the
318 -- conversion to be an unchecked conversion and that's it.
320 if Vax_Float
(S_Typ
) and then Vax_Float
(T_Typ
)
321 and then Digits_Value
(S_Typ
) = Digits_Value
(T_Typ
)
324 Unchecked_Convert_To
(T_Typ
, Expr
));
327 elsif Is_Fixed_Point_Type
(S_Typ
) then
329 -- convert the scaled integer value to the target type, and multiply
330 -- by 'Small of type.
333 Make_Op_Multiply
(Loc
,
335 Make_Type_Conversion
(Loc
,
336 Subtype_Mark
=> New_Occurrence_Of
(T_Typ
, Loc
),
338 Unchecked_Convert_To
(
339 Equivalent_Integer_Type
(S_Typ
), Expr
)),
341 Make_Real_Literal
(Loc
, Realval
=> Small_Value
(S_Typ
))));
343 elsif Is_Fixed_Point_Type
(T_Typ
) then
345 -- multiply value by 'small of type, and convert to the corresponding
349 Unchecked_Convert_To
(T_Typ
,
350 Make_Type_Conversion
(Loc
,
352 New_Occurrence_Of
(Equivalent_Integer_Type
(T_Typ
), Loc
),
354 Make_Op_Multiply
(Loc
,
357 Make_Real_Literal
(Loc
,
358 Realval
=> Ureal_1
/ Small_Value
(T_Typ
))))));
363 -- Compute types for call
365 CallS
:= Call_Type
(S_Typ
, T_Typ
);
366 CallT
:= Call_Type
(T_Typ
, S_Typ
);
368 -- Get function and its types
370 if CallS
= RE_D
and then CallT
= RE_G
then
373 elsif CallS
= RE_G
and then CallT
= RE_D
then
376 elsif CallS
= RE_G
and then CallT
= RE_F
then
379 elsif CallS
= RE_F
and then CallT
= RE_G
then
382 elsif CallS
= RE_F
and then CallT
= RE_S
then
385 elsif CallS
= RE_S
and then CallT
= RE_F
then
388 elsif CallS
= RE_G
and then CallT
= RE_T
then
391 elsif CallS
= RE_T
and then CallT
= RE_G
then
394 elsif CallS
= RE_F
and then CallT
= RE_Q
then
397 elsif CallS
= RE_Q
and then CallT
= RE_F
then
400 elsif CallS
= RE_G
and then CallT
= RE_Q
then
403 else pragma Assert
(CallS
= RE_Q
and then CallT
= RE_G
);
409 Make_Function_Call
(Loc
,
410 Name
=> New_Occurrence_Of
(RTE
(Func
), Loc
),
411 Parameter_Associations
=> New_List
(
412 Convert_To
(RTE
(CallS
), Expr
)))));
415 Analyze_And_Resolve
(N
, T_Typ
, Suppress
=> All_Checks
);
416 end Expand_Vax_Conversion
;
418 -----------------------------
419 -- Expand_Vax_Real_Literal --
420 -----------------------------
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
);
432 -- Entities for source, target and function call in conversion
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.
439 if Vax_Float
(Btyp
) then
440 -- What we want to construct here is
442 -- x!(y_to_z (1.0E0))
446 -- x is the base type of the literal (Btyp)
450 -- s_to_f for F_Float
451 -- t_to_g for G_Float
452 -- t_to_d for D_Float
454 -- The literal is typed as S (for F_Float) or T otherwise
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!)
461 if Digits_Value
(Btyp
) = VAXFF_Digits
then
464 RE_Fncall
:= RE_S_To_F
;
466 elsif Digits_Value
(Btyp
) = VAXDF_Digits
then
469 RE_Fncall
:= RE_T_To_D
;
471 else pragma Assert
(Digits_Value
(Btyp
) = VAXGF_Digits
);
474 RE_Fncall
:= RE_T_To_G
;
477 Nod
:= Relocate_Node
(N
);
479 Set_Etype
(Nod
, RTE
(RE_Source
));
480 Set_Analyzed
(Nod
, True);
483 Make_Function_Call
(Loc
,
484 Name
=> New_Occurrence_Of
(RTE
(RE_Fncall
), Loc
),
485 Parameter_Associations
=> New_List
(Nod
));
487 Set_Etype
(Nod
, RTE
(RE_Target
));
488 Set_Analyzed
(Nod
, True);
491 Make_Unchecked_Type_Conversion
(Loc
,
492 Subtype_Mark
=> New_Occurrence_Of
(Typ
, Loc
),
495 Set_Etype
(Nod
, Typ
);
496 Set_Analyzed
(Nod
, True);
499 -- This odd expression is still a static expression. Note that
500 -- the routine Sem_Eval.Expr_Value_R understands this.
502 Set_Is_Static_Expression
(N
, Stat
);
504 end Expand_Vax_Real_Literal
;