home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / a-uintp.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  107 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                        GNAT COMPILER COMPONENTS                          */
  4. /*                                                                          */
  5. /*                              A - U I N T P                               */
  6. /*                                                                          */
  7. /*                          C Implementation File                           */
  8. /*                                                                          */
  9. /*                            $Revision: 1.21 $                             */
  10. /*                                                                          */
  11. /*           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          */
  12. /*                                                                          */
  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, 675 Mass Ave, Cambridge, MA 02139, USA. */
  22. /*                                                                          */
  23. /****************************************************************************/
  24.  
  25. /* This file corresponds to the Ada package body Uintp. It was created
  26.    manually from the files uintp.ads and uintp.adb. */
  27.  
  28. #include "config.h"
  29. #include "tree.h"
  30. #include "a-ada.h"
  31. #include "a-types.h"
  32. #include "a-atree.h"
  33. #include "a-nlists.h"
  34. #include "a-elists.h"
  35. #include "a-sinfo.h"
  36. #include "a-einfo.h"
  37. #include "a-namet.h"
  38. #include "a-string.h"
  39. #include "a-uintp.h"
  40.  
  41. /* Universal integers are represented by the Uint type which is an index into
  42.    the Uints_Ptr table containing Uint_Entry values.  A Uint_Entry contains an
  43.    index and length for getting the "digits" of the universal integer from the
  44.    Udigits_Ptr table.
  45.  
  46.    For efficiency, this method is used only for integer values larger than the
  47.    constant Uint_Bias.  If a Uint is less than this constant, then it contains
  48.    the integer value itself.  The origin of the Uints_Ptr table is adjusted so
  49.    that a Uint value of Uint_Bias indexes the first element.  */
  50.  
  51. /* Similarly to UI_To_Int, but return a GCC INTEGER_CST.  Overflow is tested
  52.    by the constant-folding used to build the node.  TYPE is the GCC type of the
  53.    resulting node.  */
  54.  
  55. tree
  56. UI_To_gnu (Input, type)
  57.      Uint Input;
  58.      tree type;
  59. {
  60.   tree gnu_ret;
  61.  
  62.   if (Input <= Uint_Direct_Last)
  63.     gnu_ret = convert (type, build_int_2 (Input - Uint_Direct_Bias, 
  64.                       Input < Uint_Direct_Bias ? -1 : 0));
  65.   else
  66.     {
  67.       Int Idx =    Uints_Ptr[Input].Loc;
  68.       Pos Length = Uints_Ptr[Input].Length;
  69.       Int First = Udigits_Ptr[Idx];
  70.       /* Do computations in integer type or TYPE whichever is wider, then
  71.      convert later.  This avoid overflow if type is short integer.  */
  72.       tree comp_type
  73.     = (TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node)
  74.        ? type : integer_type_node);
  75.       tree gnu_base = convert (comp_type, build_int_2 (Base, 0));
  76.  
  77.       if (Length <= 0)
  78.     gigi_abort (601);
  79.  
  80.       gnu_ret = convert (comp_type, build_int_2 (First, First < 0 ? -1 : 0));
  81.       if (First < 0)
  82.     for (Idx++, Length--; Length; Idx++, Length--)
  83.       gnu_ret = fold (build (MINUS_EXPR, comp_type,
  84.                  fold (build (MULT_EXPR, comp_type,
  85.                           gnu_ret, gnu_base)),
  86.                  convert (comp_type,
  87.                       build_int_2 (Udigits_Ptr[Idx], 0))));
  88.       else
  89.     for (Idx++, Length--; Length; Idx++, Length--)
  90.       gnu_ret = fold (build (PLUS_EXPR, comp_type,
  91.                  fold (build (MULT_EXPR, comp_type,
  92.                           gnu_ret, gnu_base)),
  93.                  convert (comp_type,
  94.                       build_int_2 (Udigits_Ptr[Idx], 0))));
  95.     }
  96.  
  97.   gnu_ret = convert (type, gnu_ret);
  98.  
  99.   /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on GNU_RET.  */
  100.   while ((TREE_CODE (gnu_ret) == NOP_EXPR
  101.       || TREE_CODE (gnu_ret) == NON_LVALUE_EXPR)
  102.      && TREE_TYPE (TREE_OPERAND (gnu_ret, 0)) == TREE_TYPE (gnu_ret))
  103.     gnu_ret = TREE_OPERAND (gnu_ret, 0);
  104.  
  105.   return gnu_ret;
  106. }
  107.