⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplify.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
      int k = gfc_validate_kind (BT_REAL, x->ts.kind, 0);      if (direction > 0)	mpfr_add (result->value.real,		  x->value.real, gfc_real_kinds[k].subnormal, GFC_RND_MODE);      else	mpfr_sub (result->value.real,		  x->value.real, gfc_real_kinds[k].subnormal, GFC_RND_MODE);    }  else    {      if (sgn < 0)	{	  direction = -direction;	  mpfr_neg (result->value.real, result->value.real, GFC_RND_MODE);	}      if (direction > 0)	mpfr_add_one_ulp (result->value.real, GFC_RND_MODE);      else	{	  /* In this case the exponent can shrink, which makes us skip	     over one number because we subtract one ulp with the	     larger exponent.  Thus we need to compensate for this.  */	  mpfr_init_set (tmp, result->value.real, GFC_RND_MODE);	  mpfr_sub_one_ulp (result->value.real, GFC_RND_MODE);	  mpfr_add_one_ulp (result->value.real, GFC_RND_MODE);	  /* If we're back to where we started, the spacing is one	     ulp, and we get the correct result by subtracting.  */	  if (mpfr_cmp (tmp, result->value.real) == 0)	    mpfr_sub_one_ulp (result->value.real, GFC_RND_MODE);	  mpfr_clear (tmp);	}      if (sgn < 0)	mpfr_neg (result->value.real, result->value.real, GFC_RND_MODE);    }  return range_check (result, "NEAREST");}static gfc_expr *simplify_nint (const char *name, gfc_expr * e, gfc_expr * k){  gfc_expr *itrunc, *result;  int kind;  kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);  if (kind == -1)    return &gfc_bad_expr;  if (e->expr_type != EXPR_CONSTANT)    return NULL;  result = gfc_constant_result (BT_INTEGER, kind, &e->where);  itrunc = gfc_copy_expr (e);  mpfr_round(itrunc->value.real, e->value.real);  gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real);  gfc_free_expr (itrunc);  return range_check (result, name);}gfc_expr *gfc_simplify_nint (gfc_expr * e, gfc_expr * k){  return simplify_nint ("NINT", e, k);}gfc_expr *gfc_simplify_idnint (gfc_expr * e){  return simplify_nint ("IDNINT", e, NULL);}gfc_expr *gfc_simplify_not (gfc_expr * e){  gfc_expr *result;  int i;  if (e->expr_type != EXPR_CONSTANT)    return NULL;  result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);  mpz_com (result->value.integer, e->value.integer);  /* Because of how GMP handles numbers, the result must be ANDed with     the max_int mask.  For radices <> 2, this will require change.  */  i = gfc_validate_kind (BT_INTEGER, e->ts.kind, false);  mpz_and (result->value.integer, result->value.integer,	   gfc_integer_kinds[i].max_int);  twos_complement (result->value.integer, gfc_integer_kinds[i].bit_size);  return range_check (result, "NOT");}gfc_expr *gfc_simplify_null (gfc_expr * mold){  gfc_expr *result;  if (mold == NULL)    {      result = gfc_get_expr ();      result->ts.type = BT_UNKNOWN;    }  else    result = gfc_copy_expr (mold);  result->expr_type = EXPR_NULL;  return result;}gfc_expr *gfc_simplify_or (gfc_expr * x, gfc_expr * y){  gfc_expr *result;  int kind;  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)    return NULL;  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;  if (x->ts.type == BT_INTEGER)    {      result = gfc_constant_result (BT_INTEGER, kind, &x->where);      mpz_ior (result->value.integer, x->value.integer, y->value.integer);    }  else /* BT_LOGICAL */    {      result = gfc_constant_result (BT_LOGICAL, kind, &x->where);      result->value.logical = x->value.logical || y->value.logical;    }  return range_check (result, "OR");}gfc_expr *gfc_simplify_precision (gfc_expr * e){  gfc_expr *result;  int i;  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);  result = gfc_int_expr (gfc_real_kinds[i].precision);  result->where = e->where;  return result;}gfc_expr *gfc_simplify_radix (gfc_expr * e){  gfc_expr *result;  int i;  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);  switch (e->ts.type)    {    case BT_INTEGER:      i = gfc_integer_kinds[i].radix;      break;    case BT_REAL:      i = gfc_real_kinds[i].radix;      break;    default:      gcc_unreachable ();    }  result = gfc_int_expr (i);  result->where = e->where;  return result;}gfc_expr *gfc_simplify_range (gfc_expr * e){  gfc_expr *result;  int i;  long j;  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);  switch (e->ts.type)    {    case BT_INTEGER:      j = gfc_integer_kinds[i].range;      break;    case BT_REAL:    case BT_COMPLEX:      j = gfc_real_kinds[i].range;      break;    default:      gcc_unreachable ();    }  result = gfc_int_expr (j);  result->where = e->where;  return result;}gfc_expr *gfc_simplify_real (gfc_expr * e, gfc_expr * k){  gfc_expr *result;  int kind;  if (e->ts.type == BT_COMPLEX)    kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);  else    kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind);  if (kind == -1)    return &gfc_bad_expr;  if (e->expr_type != EXPR_CONSTANT)    return NULL;  switch (e->ts.type)    {    case BT_INTEGER:      result = gfc_int2real (e, kind);      break;    case BT_REAL:      result = gfc_real2real (e, kind);      break;    case BT_COMPLEX:      result = gfc_complex2real (e, kind);      break;    default:      gfc_internal_error ("bad type in REAL");      /* Not reached */    }  return range_check (result, "REAL");}gfc_expr *gfc_simplify_realpart (gfc_expr * e){  gfc_expr *result;  if (e->expr_type != EXPR_CONSTANT)    return NULL;  result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);  mpfr_set (result->value.real, e->value.complex.r, GFC_RND_MODE);  return range_check (result, "REALPART");}gfc_expr *gfc_simplify_repeat (gfc_expr * e, gfc_expr * n){  gfc_expr *result;  int i, j, len, ncopies, nlen;  if (e->expr_type != EXPR_CONSTANT || n->expr_type != EXPR_CONSTANT)    return NULL;  if (n != NULL && (gfc_extract_int (n, &ncopies) != NULL || ncopies < 0))    {      gfc_error ("Invalid second argument of REPEAT at %L", &n->where);      return &gfc_bad_expr;    }  len = e->value.character.length;  nlen = ncopies * len;  result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);  if (ncopies == 0)    {      result->value.character.string = gfc_getmem (1);      result->value.character.length = 0;      result->value.character.string[0] = '\0';      return result;    }  result->value.character.length = nlen;  result->value.character.string = gfc_getmem (nlen + 1);  for (i = 0; i < ncopies; i++)    for (j = 0; j < len; j++)      result->value.character.string[j + i * len] =	e->value.character.string[j];  result->value.character.string[nlen] = '\0';	/* For debugger */  return result;}/* This one is a bear, but mainly has to do with shuffling elements.  */gfc_expr *gfc_simplify_reshape (gfc_expr * source, gfc_expr * shape_exp,		      gfc_expr * pad, gfc_expr * order_exp){  int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];  int i, rank, npad, x[GFC_MAX_DIMENSIONS];  gfc_constructor *head, *tail;  mpz_t index, size;  unsigned long j;  size_t nsource;  gfc_expr *e;  /* Unpack the shape array.  */  if (source->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (source))    return NULL;  if (shape_exp->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (shape_exp))    return NULL;  if (pad != NULL      && (pad->expr_type != EXPR_ARRAY	  || !gfc_is_constant_expr (pad)))    return NULL;  if (order_exp != NULL      && (order_exp->expr_type != EXPR_ARRAY	  || !gfc_is_constant_expr (order_exp)))    return NULL;  mpz_init (index);  rank = 0;  head = tail = NULL;  for (;;)    {      e = gfc_get_array_element (shape_exp, rank);      if (e == NULL)	break;      if (gfc_extract_int (e, &shape[rank]) != NULL)	{	  gfc_error ("Integer too large in shape specification at %L",		     &e->where);	  gfc_free_expr (e);	  goto bad_reshape;	}      gfc_free_expr (e);      if (rank >= GFC_MAX_DIMENSIONS)	{	  gfc_error ("Too many dimensions in shape specification for RESHAPE "		     "at %L", &e->where);	  goto bad_reshape;	}      if (shape[rank] < 0)	{	  gfc_error ("Shape specification at %L cannot be negative",		     &e->where);	  goto bad_reshape;	}      rank++;    }  if (rank == 0)    {      gfc_error ("Shape specification at %L cannot be the null array",		 &shape_exp->where);      goto bad_reshape;    }  /* Now unpack the order array if present.  */  if (order_exp == NULL)    {      for (i = 0; i < rank; i++)	order[i] = i;    }  else    {      for (i = 0; i < rank; i++)	x[i] = 0;      for (i = 0; i < rank; i++)	{	  e = gfc_get_array_element (order_exp, i);	  if (e == NULL)	    {	      gfc_error		("ORDER parameter of RESHAPE at %L is not the same size "		 "as SHAPE parameter", &order_exp->where);	      goto bad_reshape;	    }	  if (gfc_extract_int (e, &order[i]) != NULL)	    {	      gfc_error ("Error in ORDER parameter of RESHAPE at %L",			 &e->where);	      gfc_free_expr (e);	      goto bad_reshape;	    }	  gfc_free_expr (e);	  if (order[i] < 1 || order[i] > rank)	    {	      gfc_error ("ORDER parameter of RESHAPE at %L is out of range",			 &e->where);	      goto bad_reshape;	    }	  order[i]--;	  if (x[order[i]])	    {	      gfc_error ("Invalid permutation in ORDER parameter at %L",			 &e->where);	      goto bad_reshape;	    }	  x[order[i]] = 1;	}    }  /* Count the elements in the source and padding arrays.  */  npad = 0;  if (pad != NULL)    {      gfc_array_size (pad, &size);      npad = mpz_get_ui (size);      mpz_clear (size);    }  gfc_array_size (source, &size);  nsource = mpz_get_ui (size);  mpz_clear (size);  /* If it weren't for that pesky permutation we could just loop     through the source and round out any shortage with pad elements.     But no, someone just had to have the compiler do something the     user should be doing.  */  for (i = 0; i < rank; i++)    x[i] = 0;  for (;;)    {      /* Figure out which element to extract.  */      mpz_set_ui (index, 0);      for (i = rank - 1; i >= 0; i--)	{	  mpz_add_ui (index, index, x[order[i]]);	  if (i != 0)	    mpz_mul_ui (index, index, shape[order[i - 1]]);	}      if (mpz_cmp_ui (index, INT_MAX) > 0)	gfc_internal_error ("Reshaped array too large at %L", &e->where);      j = mpz_get_ui (index);      if (j < nsource)	e = gfc_get_array_element (source, j);      else	{	  j = j - nsource;	  if (npad == 0)	    {	      gfc_error		("PAD parameter required for short SOURCE parameter at %L",		 &source->where);	      goto bad_reshape;	    }	  j = j % npad;	  e = gfc_get_array_element (pad, j);	}      if (head == NULL)	head = tail = gfc_get_constructor ();      else	{	  tail->next = gfc_get_constructor ();	  tail = tail->next;	}      if (e == NULL)	goto bad_reshape;      tail->where = e->where;      tail->expr = e;      /* Calculate the next element.  */      i = 0;inc:      if (++x[i] < shape[i])	continue;      x[i++] = 0;      if (i < rank)	goto inc;      break;    }  mpz_clear (index);  e = gfc_get_expr ();  e->where = source->where;  e->expr_type = EXPR_ARRAY;  e->value.constructor = head;  e->shape = gfc_get_shape (rank);  for (i = 0; i < rank; i++)    mpz_init_set_ui (e->shape[i], shape[i]);  e->ts = source->ts;  e->rank = rank;  return e;bad_reshape:  gfc_free_constructor (head);  mpz_clear (index);  return &gfc_bad_expr;}gfc_expr *gfc_simplify_rrspacing (gfc_expr * x){  gfc_expr *result;  mpfr_t absv, log2, exp, frac, pow2;  int i, p;  if (x->expr_type != EXPR_CONSTANT)    return NULL;  i = gfc_validate_kind (x->ts.type, x->ts.kind, false);  result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);  p = gfc_real_kinds[i].digits;  gfc_set_model_kind (x->ts.kind);  if (mpfr_sgn (x->value.real) == 0)    {      mpfr_ui_div (result->value.real, 1, gfc_real_kinds[i].tiny, GFC_RND_MODE);      return result;    }  mpfr_init (log2);  mpfr_init (absv);  mpfr_init (frac);  mpfr_init (pow2);  mpfr_abs (absv, x->value.real, GFC_RND_MODE);  mpfr_log2 (log2, absv, GFC_RND_MODE);  mpfr_trunc (log2, log2);  mpfr_add_ui (exp, log2, 1, GFC_RND_MODE);  mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);  mpfr_div (frac, absv, pow2, GFC_RND_MODE);  mpfr_mul_2exp (result->value.real, frac, (u

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -