1/**************************************************************************** 2 * * 3 * GNAT COMPILER COMPONENTS * 4 * * 5 * C U I N T P * 6 * * 7 * C Implementation File * 8 * * 9 * Copyright (C) 1992-2015, 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 3, 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 along with GCC; see the file COPYING3. If not see * 19 * <http://www.gnu.org/licenses/>. * 20 * * 21 * GNAT was originally developed by the GNAT team at New York University. * 22 * Extensive contributions were provided by Ada Core Technologies Inc. * 23 * * 24 ****************************************************************************/ 25 26/* This file corresponds to the Ada package body Uintp. It was created 27 manually from the files uintp.ads and uintp.adb. */ 28 29#include "config.h" 30#include "system.h" 31#include "coretypes.h" 32#include "tm.h" 33#include "hash-set.h" 34#include "machmode.h" 35#include "vec.h" 36#include "double-int.h" 37#include "input.h" 38#include "alias.h" 39#include "symtab.h" 40#include "wide-int.h" 41#include "inchash.h" 42#include "tree.h" 43#include "fold-const.h" 44 45#include "ada.h" 46#include "types.h" 47#include "uintp.h" 48#include "ada-tree.h" 49#include "gigi.h" 50 51/* Universal integers are represented by the Uint type which is an index into 52 the Uints_Ptr table containing Uint_Entry values. A Uint_Entry contains an 53 index and length for getting the "digits" of the universal integer from the 54 Udigits_Ptr table. 55 56 For efficiency, this method is used only for integer values larger than the 57 constant Uint_Bias. If a Uint is less than this constant, then it contains 58 the integer value itself. The origin of the Uints_Ptr table is adjusted so 59 that a Uint value of Uint_Bias indexes the first element. 60 61 First define a utility function that operates like build_int_cst_type for 62 integral types and does a conversion for floating-point types. */ 63 64static tree 65build_cst_from_int (tree type, HOST_WIDE_INT low) 66{ 67 if (SCALAR_FLOAT_TYPE_P (type)) 68 return convert (type, build_int_cst (gnat_type_for_size (32, 0), low)); 69 else 70 return build_int_cst_type (type, low); 71} 72 73/* Similar to UI_To_Int, but return a GCC INTEGER_CST or REAL_CST node, 74 depending on whether TYPE is an integral or real type. Overflow is tested 75 by the constant-folding used to build the node. TYPE is the GCC type of 76 the resulting node. */ 77 78tree 79UI_To_gnu (Uint Input, tree type) 80{ 81 /* We might have a TYPE with biased representation and be passed an unbiased 82 value that doesn't fit. We always use an unbiased type to be able to hold 83 any such possible value for intermediate computations and then rely on a 84 conversion back to TYPE to perform the bias adjustment when need be. */ 85 tree comp_type 86 = TREE_CODE (type) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type) 87 ? get_base_type (type) : type; 88 tree gnu_ret; 89 90 if (Input <= Uint_Direct_Last) 91 gnu_ret = build_cst_from_int (comp_type, Input - Uint_Direct_Bias); 92 else 93 { 94 Int Idx = Uints_Ptr[Input].Loc; 95 Pos Length = Uints_Ptr[Input].Length; 96 Int First = Udigits_Ptr[Idx]; 97 tree gnu_base; 98 99 gcc_assert (Length > 0); 100 101 /* The computations we perform below always require a type at least as 102 large as an integer not to overflow. FP types are always fine, but 103 INTEGER or ENUMERAL types we are handed may be too short. We use a 104 base integer type node for the computations in this case and will 105 convert the final result back to the incoming type later on. */ 106 if (!SCALAR_FLOAT_TYPE_P (comp_type) && TYPE_PRECISION (comp_type) < 32) 107 comp_type = gnat_type_for_size (32, 0); 108 109 gnu_base = build_cst_from_int (comp_type, Base); 110 111 gnu_ret = build_cst_from_int (comp_type, First); 112 if (First < 0) 113 for (Idx++, Length--; Length; Idx++, Length--) 114 gnu_ret = fold_build2 (MINUS_EXPR, comp_type, 115 fold_build2 (MULT_EXPR, comp_type, 116 gnu_ret, gnu_base), 117 build_cst_from_int (comp_type, 118 Udigits_Ptr[Idx])); 119 else 120 for (Idx++, Length--; Length; Idx++, Length--) 121 gnu_ret = fold_build2 (PLUS_EXPR, comp_type, 122 fold_build2 (MULT_EXPR, comp_type, 123 gnu_ret, gnu_base), 124 build_cst_from_int (comp_type, 125 Udigits_Ptr[Idx])); 126 } 127 128 gnu_ret = convert (type, gnu_ret); 129 130 /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on GNU_RET. */ 131 while ((TREE_CODE (gnu_ret) == NOP_EXPR 132 || TREE_CODE (gnu_ret) == NON_LVALUE_EXPR) 133 && TREE_TYPE (TREE_OPERAND (gnu_ret, 0)) == TREE_TYPE (gnu_ret)) 134 gnu_ret = TREE_OPERAND (gnu_ret, 0); 135 136 return gnu_ret; 137} 138 139/* Similar to UI_From_Int, but take a GCC INTEGER_CST. We use UI_From_Int 140 when possible, i.e. for a 32-bit signed value, to take advantage of its 141 built-in caching mechanism. For values of larger magnitude, we compute 142 digits into a vector and call Vector_To_Uint. */ 143 144Uint 145UI_From_gnu (tree Input) 146{ 147 tree gnu_type = TREE_TYPE (Input), gnu_base, gnu_temp; 148 /* UI_Base is defined so that 5 Uint digits is sufficient to hold the 149 largest possible signed 64-bit value. */ 150 const int Max_For_Dint = 5; 151 int v[Max_For_Dint], i; 152 Vector_Template temp; 153 Int_Vector vec; 154 155#if HOST_BITS_PER_WIDE_INT == 64 156 /* On 64-bit hosts, tree_fits_shwi_p tells whether the input fits in a 157 signed 64-bit integer. Then a truncation tells whether it fits 158 in a signed 32-bit integer. */ 159 if (tree_fits_shwi_p (Input)) 160 { 161 HOST_WIDE_INT hw_input = tree_to_shwi (Input); 162 if (hw_input == (int) hw_input) 163 return UI_From_Int (hw_input); 164 } 165 else 166 return No_Uint; 167#else 168 /* On 32-bit hosts, tree_fits_shwi_p tells whether the input fits in a 169 signed 32-bit integer. Then a sign test tells whether it fits 170 in a signed 64-bit integer. */ 171 if (tree_fits_shwi_p (Input)) 172 return UI_From_Int (tree_to_shwi (Input)); 173 174 gcc_assert (TYPE_PRECISION (gnu_type) <= 64); 175 if (TYPE_UNSIGNED (gnu_type) 176 && TYPE_PRECISION (gnu_type) == 64 177 && wi::neg_p (Input, SIGNED)) 178 return No_Uint; 179#endif 180 181 gnu_base = build_int_cst (gnu_type, UI_Base); 182 gnu_temp = Input; 183 184 for (i = Max_For_Dint - 1; i >= 0; i--) 185 { 186 v[i] = tree_to_shwi (fold_build1 (ABS_EXPR, gnu_type, 187 fold_build2 (TRUNC_MOD_EXPR, gnu_type, 188 gnu_temp, gnu_base))); 189 gnu_temp = fold_build2 (TRUNC_DIV_EXPR, gnu_type, gnu_temp, gnu_base); 190 } 191 192 temp.Low_Bound = 1; 193 temp.High_Bound = Max_For_Dint; 194 vec.Bounds = &temp; 195 vec.Array = v; 196 return Vector_To_Uint (vec, tree_int_cst_sgn (Input) < 0); 197} 198