FSF GCC merge 02/23/03
[official-gcc.git] / gcc / ada / exp_vfpt.adb
blob448864497fb8a0dd2a666eb413d4bc3835a46a54
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 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 -- --
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));
51 Typc : Character;
52 Atyp : Entity_Id;
53 Func : RE_Id;
54 Args : List_Id;
56 begin
57 -- Get arithmetic type, note that we do D stuff in G
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;
67 case Nkind (N) is
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;
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;
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;
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;
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;
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;
111 when others =>
112 Func := RE_Null;
113 raise Program_Error;
115 end case;
117 Args := New_List;
119 if Nkind (N) in N_Binary_Op then
120 Append_To (Args,
121 Convert_To (Atyp, Left_Opnd (N)));
122 end if;
124 Append_To (Args,
125 Convert_To (Atyp, Right_Opnd (N)));
127 Rewrite (N,
128 Convert_To (Typ,
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)));
143 Typc : Character;
144 Func : RE_Id;
145 Atyp : Entity_Id;
146 Revrs : Boolean := False;
147 Args : List_Id;
149 begin
150 -- Get arithmetic type, note that we do D stuff in G
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;
160 case Nkind (N) is
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;
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;
176 Revrs := True;
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;
185 Revrs := True;
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;
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;
201 when others =>
202 Func := RE_Null;
203 raise Program_Error;
205 end case;
207 if not Revrs then
208 Args := New_List (
209 Convert_To (Atyp, Left_Opnd (N)),
210 Convert_To (Atyp, Right_Opnd (N)));
212 else
213 Args := New_List (
214 Convert_To (Atyp, Right_Opnd (N)),
215 Convert_To (Atyp, Left_Opnd (N)));
216 end if;
218 Rewrite (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));
236 CallS : RE_Id;
237 CallT : RE_Id;
238 Func : RE_Id;
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.
251 ---------------
252 -- Call_Type --
253 ---------------
255 function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id is
256 begin
257 -- Vax float formats
259 if Vax_Float (T) then
260 if Digits_Value (T) = VAXFF_Digits then
261 return RE_F;
263 elsif Digits_Value (T) = VAXGF_Digits then
264 return RE_G;
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);
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;
281 -- For all discrete types, use 64-bit integer
283 elsif Is_Discrete_Type (T) then
284 return RE_Q;
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
293 return RE_S;
294 else
295 return RE_T;
296 end if;
297 end if;
298 end Call_Type;
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;
305 elsif Esize (T) = Esize (Standard_Long_Integer) then
306 return Standard_Long_Integer;
308 else
309 return Standard_Integer;
310 end if;
311 end Equivalent_Integer_Type;
314 -- Start of processing for Expand_Vax_Conversion;
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.
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));
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.
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))));
343 elsif Is_Fixed_Point_Type (T_Typ) then
345 -- multiply value by 'small of type, and convert to the corresponding
346 -- integer type.
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))))));
360 -- All other cases.
362 else
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
371 Func := RE_D_To_G;
373 elsif CallS = RE_G and then CallT = RE_D then
374 Func := RE_G_To_D;
376 elsif CallS = RE_G and then CallT = RE_F then
377 Func := RE_G_To_F;
379 elsif CallS = RE_F and then CallT = RE_G then
380 Func := RE_F_To_G;
382 elsif CallS = RE_F and then CallT = RE_S then
383 Func := RE_F_To_S;
385 elsif CallS = RE_S and then CallT = RE_F then
386 Func := RE_S_To_F;
388 elsif CallS = RE_G and then CallT = RE_T then
389 Func := RE_G_To_T;
391 elsif CallS = RE_T and then CallT = RE_G then
392 Func := RE_T_To_G;
394 elsif CallS = RE_F and then CallT = RE_Q then
395 Func := RE_F_To_Q;
397 elsif CallS = RE_Q and then CallT = RE_F then
398 Func := RE_Q_To_F;
400 elsif CallS = RE_G and then CallT = RE_Q then
401 Func := RE_G_To_Q;
403 else pragma Assert (CallS = RE_Q and then CallT = RE_G);
404 Func := RE_Q_To_G;
405 end if;
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;
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);
427 Nod : Node_Id;
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
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.
439 if Vax_Float (Btyp) then
440 -- What we want to construct here is
442 -- x!(y_to_z (1.0E0))
444 -- where
446 -- x is the base type of the literal (Btyp)
448 -- y_to_z is
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
462 RE_Source := RE_S;
463 RE_Target := RE_F;
464 RE_Fncall := RE_S_To_F;
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;
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;
477 Nod := Relocate_Node (N);
479 Set_Etype (Nod, RTE (RE_Source));
480 Set_Analyzed (Nod, True);
482 Nod :=
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);
490 Nod :=
491 Make_Unchecked_Type_Conversion (Loc,
492 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
493 Expression => Nod);
495 Set_Etype (Nod, Typ);
496 Set_Analyzed (Nod, True);
497 Rewrite (N, Nod);
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);
503 end if;
504 end Expand_Vax_Real_Literal;
506 end Exp_VFpt;