2005-12-29 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / ada / exp_vfpt.adb
blobde2fae1045982ec4ca7d92cc9e04523531a59967
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ V F P T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1997-2005, 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 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Atree; use Atree;
28 with Einfo; use Einfo;
29 with Nlists; use Nlists;
30 with Nmake; use Nmake;
31 with Rtsfind; use Rtsfind;
32 with Sem_Res; use Sem_Res;
33 with Sinfo; use Sinfo;
34 with Stand; use Stand;
35 with Tbuild; use Tbuild;
36 with Ttypef; use Ttypef;
37 with Uintp; use Uintp;
38 with Urealp; use Urealp;
40 package body Exp_VFpt is
42 ----------------------
43 -- Expand_Vax_Arith --
44 ----------------------
46 procedure Expand_Vax_Arith (N : Node_Id) is
47 Loc : constant Source_Ptr := Sloc (N);
48 Typ : constant Entity_Id := Base_Type (Etype (N));
49 Typc : Character;
50 Atyp : Entity_Id;
51 Func : RE_Id;
52 Args : List_Id;
54 begin
55 -- Get arithmetic type, note that we do D stuff in G
57 if Digits_Value (Typ) = VAXFF_Digits then
58 Typc := 'F';
59 Atyp := RTE (RE_F);
60 else
61 Typc := 'G';
62 Atyp := RTE (RE_G);
63 end if;
65 case Nkind (N) is
67 when N_Op_Abs =>
68 if Typc = 'F' then
69 Func := RE_Abs_F;
70 else
71 Func := RE_Abs_G;
72 end if;
74 when N_Op_Add =>
75 if Typc = 'F' then
76 Func := RE_Add_F;
77 else
78 Func := RE_Add_G;
79 end if;
81 when N_Op_Divide =>
82 if Typc = 'F' then
83 Func := RE_Div_F;
84 else
85 Func := RE_Div_G;
86 end if;
88 when N_Op_Multiply =>
89 if Typc = 'F' then
90 Func := RE_Mul_F;
91 else
92 Func := RE_Mul_G;
93 end if;
95 when N_Op_Minus =>
96 if Typc = 'F' then
97 Func := RE_Neg_F;
98 else
99 Func := RE_Neg_G;
100 end if;
102 when N_Op_Subtract =>
103 if Typc = 'F' then
104 Func := RE_Sub_F;
105 else
106 Func := RE_Sub_G;
107 end if;
109 when others =>
110 Func := RE_Null;
111 raise Program_Error;
113 end case;
115 Args := New_List;
117 if Nkind (N) in N_Binary_Op then
118 Append_To (Args,
119 Convert_To (Atyp, Left_Opnd (N)));
120 end if;
122 Append_To (Args,
123 Convert_To (Atyp, Right_Opnd (N)));
125 Rewrite (N,
126 Convert_To (Typ,
127 Make_Function_Call (Loc,
128 Name => New_Occurrence_Of (RTE (Func), Loc),
129 Parameter_Associations => Args)));
131 Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
132 end Expand_Vax_Arith;
134 ---------------------------
135 -- Expand_Vax_Comparison --
136 ---------------------------
138 procedure Expand_Vax_Comparison (N : Node_Id) is
139 Loc : constant Source_Ptr := Sloc (N);
140 Typ : constant Entity_Id := Base_Type (Etype (Left_Opnd (N)));
141 Typc : Character;
142 Func : RE_Id;
143 Atyp : Entity_Id;
144 Revrs : Boolean := False;
145 Args : List_Id;
147 begin
148 -- Get arithmetic type, note that we do D stuff in G
150 if Digits_Value (Typ) = VAXFF_Digits then
151 Typc := 'F';
152 Atyp := RTE (RE_F);
153 else
154 Typc := 'G';
155 Atyp := RTE (RE_G);
156 end if;
158 case Nkind (N) is
160 when N_Op_Eq =>
161 if Typc = 'F' then
162 Func := RE_Eq_F;
163 else
164 Func := RE_Eq_G;
165 end if;
167 when N_Op_Ge =>
168 if Typc = 'F' then
169 Func := RE_Le_F;
170 else
171 Func := RE_Le_G;
172 end if;
174 Revrs := True;
176 when N_Op_Gt =>
177 if Typc = 'F' then
178 Func := RE_Lt_F;
179 else
180 Func := RE_Lt_G;
181 end if;
183 Revrs := True;
185 when N_Op_Le =>
186 if Typc = 'F' then
187 Func := RE_Le_F;
188 else
189 Func := RE_Le_G;
190 end if;
192 when N_Op_Lt =>
193 if Typc = 'F' then
194 Func := RE_Lt_F;
195 else
196 Func := RE_Lt_G;
197 end if;
199 when N_Op_Ne =>
200 if Typc = 'F' then
201 Func := RE_Ne_F;
202 else
203 Func := RE_Ne_G;
204 end if;
206 when others =>
207 Func := RE_Null;
208 raise Program_Error;
210 end case;
212 if not Revrs then
213 Args := New_List (
214 Convert_To (Atyp, Left_Opnd (N)),
215 Convert_To (Atyp, Right_Opnd (N)));
217 else
218 Args := New_List (
219 Convert_To (Atyp, Right_Opnd (N)),
220 Convert_To (Atyp, Left_Opnd (N)));
221 end if;
223 Rewrite (N,
224 Make_Function_Call (Loc,
225 Name => New_Occurrence_Of (RTE (Func), Loc),
226 Parameter_Associations => Args));
228 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
229 end Expand_Vax_Comparison;
231 ---------------------------
232 -- Expand_Vax_Conversion --
233 ---------------------------
235 procedure Expand_Vax_Conversion (N : Node_Id) is
236 Loc : constant Source_Ptr := Sloc (N);
237 Expr : constant Node_Id := Expression (N);
238 S_Typ : constant Entity_Id := Base_Type (Etype (Expr));
239 T_Typ : constant Entity_Id := Base_Type (Etype (N));
241 CallS : RE_Id;
242 CallT : RE_Id;
243 Func : RE_Id;
245 function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id;
246 -- Given one of the two types T, determines the coresponding call
247 -- type, i.e. the type to be used for the call (or the result of
248 -- the call). The actual operand is converted to (or from) this type.
249 -- Otyp is the other type, which is useful in figuring out the result.
250 -- The result returned is the RE_Id value for the type entity.
252 function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id;
253 -- Find the predefined integer type that has the same size as the
254 -- fixed-point type T, for use in fixed/float conversions.
256 ---------------
257 -- Call_Type --
258 ---------------
260 function Call_Type (T : Entity_Id; Otyp : Entity_Id) return RE_Id is
261 begin
262 -- Vax float formats
264 if Vax_Float (T) then
265 if Digits_Value (T) = VAXFF_Digits then
266 return RE_F;
268 elsif Digits_Value (T) = VAXGF_Digits then
269 return RE_G;
271 -- For D_Float, leave it as D float if the other operand is
272 -- G_Float, since this is the one conversion that is properly
273 -- supported for D_Float, but otherwise, use G_Float.
275 else pragma Assert (Digits_Value (T) = VAXDF_Digits);
277 if Vax_Float (Otyp)
278 and then Digits_Value (Otyp) = VAXGF_Digits
279 then
280 return RE_D;
281 else
282 return RE_G;
283 end if;
284 end if;
286 -- For all discrete types, use 64-bit integer
288 elsif Is_Discrete_Type (T) then
289 return RE_Q;
291 -- For all real types (other than Vax float format), we use the
292 -- IEEE float-type which corresponds in length to the other type
293 -- (which is Vax Float).
295 else pragma Assert (Is_Real_Type (T));
297 if Digits_Value (Otyp) = VAXFF_Digits then
298 return RE_S;
299 else
300 return RE_T;
301 end if;
302 end if;
303 end Call_Type;
305 -------------------------------------------------
306 -- Expand_Multiply_Fixed_By_Fixed_Giving_Fixed --
307 -------------------------------------------------
309 function Equivalent_Integer_Type (T : Entity_Id) return Entity_Id is
310 begin
311 if Esize (T) = Esize (Standard_Long_Long_Integer) then
312 return Standard_Long_Long_Integer;
313 elsif Esize (T) = Esize (Standard_Long_Integer) then
314 return Standard_Long_Integer;
315 else
316 return Standard_Integer;
317 end if;
318 end Equivalent_Integer_Type;
320 -- Start of processing for Expand_Vax_Conversion;
322 begin
323 -- If input and output are the same Vax type, we change the
324 -- conversion to be an unchecked conversion and that's it.
326 if Vax_Float (S_Typ) and then Vax_Float (T_Typ)
327 and then Digits_Value (S_Typ) = Digits_Value (T_Typ)
328 then
329 Rewrite (N,
330 Unchecked_Convert_To (T_Typ, Expr));
332 -- Case of conversion of fixed-point type to Vax_Float type
334 elsif Is_Fixed_Point_Type (S_Typ) then
336 -- If Conversion_OK set, then we introduce an intermediate IEEE
337 -- target type since we are expecting the code generator to handle
338 -- the case of integer to IEEE float.
340 if Conversion_OK (N) then
341 Rewrite (N,
342 Convert_To (T_Typ, OK_Convert_To (Universal_Real, Expr)));
344 -- Otherwise, convert the scaled integer value to the target type,
345 -- and multiply by 'Small of type.
347 else
348 Rewrite (N,
349 Make_Op_Multiply (Loc,
350 Left_Opnd =>
351 Make_Type_Conversion (Loc,
352 Subtype_Mark => New_Occurrence_Of (T_Typ, Loc),
353 Expression =>
354 Unchecked_Convert_To (
355 Equivalent_Integer_Type (S_Typ), Expr)),
356 Right_Opnd =>
357 Make_Real_Literal (Loc, Realval => Small_Value (S_Typ))));
358 end if;
360 -- Case of conversion of Vax_Float type to fixed-point type
362 elsif Is_Fixed_Point_Type (T_Typ) then
364 -- If Conversion_OK set, then we introduce an intermediate IEEE
365 -- target type, since we are expecting the code generator to handle
366 -- the case of IEEE float to integer.
368 if Conversion_OK (N) then
369 Rewrite (N,
370 OK_Convert_To (T_Typ, Convert_To (Universal_Real, Expr)));
372 -- Otherwise, multiply value by 'small of type, and convert to the
373 -- corresponding integer type.
375 else
376 Rewrite (N,
377 Unchecked_Convert_To (T_Typ,
378 Make_Type_Conversion (Loc,
379 Subtype_Mark =>
380 New_Occurrence_Of (Equivalent_Integer_Type (T_Typ), Loc),
381 Expression =>
382 Make_Op_Multiply (Loc,
383 Left_Opnd => Expr,
384 Right_Opnd =>
385 Make_Real_Literal (Loc,
386 Realval => Ureal_1 / Small_Value (T_Typ))))));
387 end if;
389 -- All other cases
391 else
392 -- Compute types for call
394 CallS := Call_Type (S_Typ, T_Typ);
395 CallT := Call_Type (T_Typ, S_Typ);
397 -- Get function and its types
399 if CallS = RE_D and then CallT = RE_G then
400 Func := RE_D_To_G;
402 elsif CallS = RE_G and then CallT = RE_D then
403 Func := RE_G_To_D;
405 elsif CallS = RE_G and then CallT = RE_F then
406 Func := RE_G_To_F;
408 elsif CallS = RE_F and then CallT = RE_G then
409 Func := RE_F_To_G;
411 elsif CallS = RE_F and then CallT = RE_S then
412 Func := RE_F_To_S;
414 elsif CallS = RE_S and then CallT = RE_F then
415 Func := RE_S_To_F;
417 elsif CallS = RE_G and then CallT = RE_T then
418 Func := RE_G_To_T;
420 elsif CallS = RE_T and then CallT = RE_G then
421 Func := RE_T_To_G;
423 elsif CallS = RE_F and then CallT = RE_Q then
424 Func := RE_F_To_Q;
426 elsif CallS = RE_Q and then CallT = RE_F then
427 Func := RE_Q_To_F;
429 elsif CallS = RE_G and then CallT = RE_Q then
430 Func := RE_G_To_Q;
432 else pragma Assert (CallS = RE_Q and then CallT = RE_G);
433 Func := RE_Q_To_G;
434 end if;
436 Rewrite (N,
437 Convert_To (T_Typ,
438 Make_Function_Call (Loc,
439 Name => New_Occurrence_Of (RTE (Func), Loc),
440 Parameter_Associations => New_List (
441 Convert_To (RTE (CallS), Expr)))));
442 end if;
444 Analyze_And_Resolve (N, T_Typ, Suppress => All_Checks);
445 end Expand_Vax_Conversion;
447 -----------------------------
448 -- Expand_Vax_Real_Literal --
449 -----------------------------
451 procedure Expand_Vax_Real_Literal (N : Node_Id) is
452 Loc : constant Source_Ptr := Sloc (N);
453 Typ : constant Entity_Id := Etype (N);
454 Btyp : constant Entity_Id := Base_Type (Typ);
455 Stat : constant Boolean := Is_Static_Expression (N);
456 Nod : Node_Id;
458 RE_Source : RE_Id;
459 RE_Target : RE_Id;
460 RE_Fncall : RE_Id;
461 -- Entities for source, target and function call in conversion
463 begin
464 -- We do not know how to convert Vax format real literals, so what
465 -- we do is to convert these to be IEEE literals, and introduce the
466 -- necessary conversion operation.
468 if Vax_Float (Btyp) then
469 -- What we want to construct here is
471 -- x!(y_to_z (1.0E0))
473 -- where
475 -- x is the base type of the literal (Btyp)
477 -- y_to_z is
479 -- s_to_f for F_Float
480 -- t_to_g for G_Float
481 -- t_to_d for D_Float
483 -- The literal is typed as S (for F_Float) or T otherwise
485 -- We do all our own construction, analysis, and expansion here,
486 -- since things are at too low a level to use Analyze or Expand
487 -- to get this built (we get circularities and other strange
488 -- problems if we try!)
490 if Digits_Value (Btyp) = VAXFF_Digits then
491 RE_Source := RE_S;
492 RE_Target := RE_F;
493 RE_Fncall := RE_S_To_F;
495 elsif Digits_Value (Btyp) = VAXDF_Digits then
496 RE_Source := RE_T;
497 RE_Target := RE_D;
498 RE_Fncall := RE_T_To_D;
500 else pragma Assert (Digits_Value (Btyp) = VAXGF_Digits);
501 RE_Source := RE_T;
502 RE_Target := RE_G;
503 RE_Fncall := RE_T_To_G;
504 end if;
506 Nod := Relocate_Node (N);
508 Set_Etype (Nod, RTE (RE_Source));
509 Set_Analyzed (Nod, True);
511 Nod :=
512 Make_Function_Call (Loc,
513 Name => New_Occurrence_Of (RTE (RE_Fncall), Loc),
514 Parameter_Associations => New_List (Nod));
516 Set_Etype (Nod, RTE (RE_Target));
517 Set_Analyzed (Nod, True);
519 Nod :=
520 Make_Unchecked_Type_Conversion (Loc,
521 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
522 Expression => Nod);
524 Set_Etype (Nod, Typ);
525 Set_Analyzed (Nod, True);
526 Rewrite (N, Nod);
528 -- This odd expression is still a static expression. Note that
529 -- the routine Sem_Eval.Expr_Value_R understands this.
531 Set_Is_Static_Expression (N, Stat);
532 end if;
533 end Expand_Vax_Real_Literal;
535 ----------------------
536 -- Expand_Vax_Valid --
537 ----------------------
539 procedure Expand_Vax_Valid (N : Node_Id) is
540 Loc : constant Source_Ptr := Sloc (N);
541 Pref : constant Node_Id := Prefix (N);
542 Ptyp : constant Entity_Id := Root_Type (Etype (Pref));
543 Rtyp : constant Entity_Id := Etype (N);
544 Vtyp : RE_Id;
545 Func : RE_Id;
547 begin
548 if Digits_Value (Ptyp) = VAXFF_Digits then
549 Func := RE_Valid_F;
550 Vtyp := RE_F;
551 elsif Digits_Value (Ptyp) = VAXDF_Digits then
552 Func := RE_Valid_D;
553 Vtyp := RE_D;
554 else pragma Assert (Digits_Value (Ptyp) = VAXGF_Digits);
555 Func := RE_Valid_G;
556 Vtyp := RE_G;
557 end if;
559 Rewrite (N,
560 Convert_To (Rtyp,
561 Make_Function_Call (Loc,
562 Name => New_Occurrence_Of (RTE (Func), Loc),
563 Parameter_Associations => New_List (
564 Convert_To (RTE (Vtyp), Pref)))));
566 Analyze_And_Resolve (N);
567 end Expand_Vax_Valid;
569 end Exp_VFpt;