Beispiel #1
0
int
gfc_interpret_integer (int kind, unsigned char *buffer, size_t buffer_size,
		   mpz_t integer)
{
  mpz_init (integer);
  gfc_conv_tree_to_mpz (integer,
			native_interpret_expr (gfc_get_int_type (kind),
					       buffer, buffer_size));
  return size_integer (kind);
}
/* Converts a GMP integer into a backend tree node.  */
tree
gfc_conv_mpz_to_tree (mpz_t i, int kind)
{
  HOST_WIDE_INT high;
  unsigned HOST_WIDE_INT low;

  if (mpz_fits_slong_p (i))
    {
      /* Note that HOST_WIDE_INT is never smaller than long.  */
      low = mpz_get_si (i);
      high = mpz_sgn (i) < 0 ? -1 : 0;
    }
  else
    {
      unsigned HOST_WIDE_INT words[2];
      size_t count;

      /* Since we know that the value is not zero (mpz_fits_slong_p),
	 we know that at one word will be written, but we don't know
	 about the second.  It's quicker to zero the second word before
	 that conditionally clear it later.  */
      words[1] = 0;

      /* Extract the absolute value into words.  */
      mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i);

      /* We assume that all numbers are in range for its type, and that
	 we never create a type larger than 2*HWI, which is the largest
	 that the middle-end can handle.  */
      gcc_assert (count == 1 || count == 2);

      low = words[0];
      high = words[1];

      /* Negate if necessary.  */
      if (mpz_sgn (i) < 0)
	{
	  if (low == 0)
	    high = -high;
	  else
	    low = -low, high = ~high;
	}
    }

  return build_int_cst_wide (gfc_get_int_type (kind), low, high);
}
Beispiel #3
0
tree
gfc_conv_constant_to_tree (gfc_expr * expr)
{
  tree res;

  gcc_assert (expr->expr_type == EXPR_CONSTANT);

  /* If it is has a prescribed memory representation, we build a string
     constant and VIEW_CONVERT to its type.  */
 
  switch (expr->ts.type)
    {
    case BT_INTEGER:
      if (expr->representation.string)
	return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
			 gfc_get_int_type (expr->ts.kind),
			 gfc_build_string_const (expr->representation.length,
						 expr->representation.string));
      else
	return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);

    case BT_REAL:
      if (expr->representation.string)
	return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
			 gfc_get_real_type (expr->ts.kind),
			 gfc_build_string_const (expr->representation.length,
						 expr->representation.string));
      else
	return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind, expr->is_snan);

    case BT_LOGICAL:
      if (expr->representation.string)
	{
	  tree tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
			gfc_get_int_type (expr->ts.kind),
			gfc_build_string_const (expr->representation.length,
						expr->representation.string));
	  if (!integer_zerop (tmp) && !integer_onep (tmp))
	    gfc_warning ("Assigning value other than 0 or 1 to LOGICAL"
			 " has undefined result at %L", &expr->where);
	  return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
	}
      else
	return build_int_cst (gfc_get_logical_type (expr->ts.kind),
			      expr->value.logical);

    case BT_COMPLEX:
      if (expr->representation.string)
	return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
			 gfc_get_complex_type (expr->ts.kind),
			 gfc_build_string_const (expr->representation.length,
						 expr->representation.string));
      else
	{
	  tree real = gfc_conv_mpfr_to_tree (mpc_realref (expr->value.complex),
					  expr->ts.kind, expr->is_snan);
	  tree imag = gfc_conv_mpfr_to_tree (mpc_imagref (expr->value.complex),
					  expr->ts.kind, expr->is_snan);

	  return build_complex (gfc_typenode_for_spec (&expr->ts),
				real, imag);
	}

    case BT_CHARACTER:
      res = gfc_build_wide_string_const (expr->ts.kind,
					 expr->value.character.length,
					 expr->value.character.string);
      return res;

    case BT_HOLLERITH:
      return gfc_build_string_const (expr->representation.length,
				     expr->representation.string);

    default:
      fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
		   gfc_typename (&expr->ts));
    }
}
Beispiel #4
0
tree
gfc_conv_mpz_to_tree (mpz_t i, int kind)
{
  double_int val = mpz_get_double_int (gfc_get_int_type (kind), i, true);
  return double_int_to_tree (gfc_get_int_type (kind), val);
}
Beispiel #5
0
static size_t
size_integer (int kind)
{
  return GET_MODE_SIZE (TYPE_MODE (gfc_get_int_type (kind)));;
}
Beispiel #6
0
tree
gfc_conv_mpz_to_tree (mpz_t i, int kind)
{
  wide_int val = wi::from_mpz (gfc_get_int_type (kind), i, true);
  return wide_int_to_tree (gfc_get_int_type (kind), val);
}
void
gfc_init_types (void)
{
  char name_buf[16];
  int index;
  tree type;
  unsigned n;
  unsigned HOST_WIDE_INT hi;
  unsigned HOST_WIDE_INT lo;

  /* Create and name the types.  */
#define PUSH_TYPE(name, node) \
  pushdecl (build_decl (TYPE_DECL, get_identifier (name), node))

  for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_int_type (&gfc_integer_kinds[index]);
      gfc_integer_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "int%d",
		gfc_integer_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_logical_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_logical_type (&gfc_logical_kinds[index]);
      gfc_logical_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "logical%d",
		gfc_logical_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_real_kinds[index].kind != 0; index++)
    {
      type = gfc_build_real_type (&gfc_real_kinds[index]);
      gfc_real_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "real%d",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);

      type = gfc_build_complex_type (type);
      gfc_complex_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "complex%d",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  gfc_character1_type_node = build_type_variant (unsigned_char_type_node, 
						 0, 0);
  PUSH_TYPE ("char", gfc_character1_type_node);

  PUSH_TYPE ("byte", unsigned_char_type_node);
  PUSH_TYPE ("void", void_type_node);

  /* DBX debugging output gets upset if these aren't set.  */
  if (!TYPE_NAME (integer_type_node))
    PUSH_TYPE ("c_integer", integer_type_node);
  if (!TYPE_NAME (char_type_node))
    PUSH_TYPE ("c_char", char_type_node);

#undef PUSH_TYPE

  pvoid_type_node = build_pointer_type (void_type_node);
  ppvoid_type_node = build_pointer_type (pvoid_type_node);
  pchar_type_node = build_pointer_type (gfc_character1_type_node);

  gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind);
  gfc_array_range_type
	  = build_range_type (gfc_array_index_type,
			      build_int_cst (gfc_array_index_type, 0),
			      NULL_TREE);

  /* The maximum array element size that can be handled is determined
     by the number of bits available to store this field in the array
     descriptor.  */

  n = TYPE_PRECISION (gfc_array_index_type) - GFC_DTYPE_SIZE_SHIFT;
  lo = ~ (unsigned HOST_WIDE_INT) 0;
  if (n > HOST_BITS_PER_WIDE_INT)
    hi = lo >> (2*HOST_BITS_PER_WIDE_INT - n);
  else
  lo = ~ (unsigned HOST_WIDE_INT) 0;
  if (n > HOST_BITS_PER_WIDE_INT)
    hi = lo >> (2*HOST_BITS_PER_WIDE_INT - n);
  else
    hi = 0, lo >>= HOST_BITS_PER_WIDE_INT - n;
  gfc_max_array_element_size
    = build_int_cst_wide (long_unsigned_type_node, lo, hi);

  size_type_node = gfc_array_index_type;

  boolean_type_node = gfc_get_logical_type (gfc_default_logical_kind);
  boolean_true_node = build_int_cst (boolean_type_node, 1);
  boolean_false_node = build_int_cst (boolean_type_node, 0);

  /* ??? Shouldn't this be based on gfc_index_integer_kind or so?  */
  gfc_charlen_type_node = gfc_get_int_type (4);
}

/* Get the type node for the given type and kind.  */

tree
gfc_get_int_type (int kind)
{
  int index = gfc_validate_kind (BT_INTEGER, kind, false);
  return gfc_integer_types[index];
}

tree
gfc_get_real_type (int kind)
{
  int index = gfc_validate_kind (BT_REAL, kind, false);