📄 simplify.c
字号:
gfc_expr *gfc_simplify_iand (gfc_expr * x, gfc_expr * y){ gfc_expr *result; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where); mpz_and (result->value.integer, x->value.integer, y->value.integer); return range_check (result, "IAND");}gfc_expr *gfc_simplify_ibclr (gfc_expr * x, gfc_expr * y){ gfc_expr *result; int k, pos; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; if (gfc_extract_int (y, &pos) != NULL || pos < 0) { gfc_error ("Invalid second argument of IBCLR at %L", &y->where); return &gfc_bad_expr; } k = gfc_validate_kind (x->ts.type, x->ts.kind, false); if (pos > gfc_integer_kinds[k].bit_size) { gfc_error ("Second argument of IBCLR exceeds bit size at %L", &y->where); return &gfc_bad_expr; } result = gfc_copy_expr (x); mpz_clrbit (result->value.integer, pos); return range_check (result, "IBCLR");}gfc_expr *gfc_simplify_ibits (gfc_expr * x, gfc_expr * y, gfc_expr * z){ gfc_expr *result; int pos, len; int i, k, bitsize; int *bits; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT || z->expr_type != EXPR_CONSTANT) return NULL; if (gfc_extract_int (y, &pos) != NULL || pos < 0) { gfc_error ("Invalid second argument of IBITS at %L", &y->where); return &gfc_bad_expr; } if (gfc_extract_int (z, &len) != NULL || len < 0) { gfc_error ("Invalid third argument of IBITS at %L", &z->where); return &gfc_bad_expr; } k = gfc_validate_kind (BT_INTEGER, x->ts.kind, false); bitsize = gfc_integer_kinds[k].bit_size; if (pos + len > bitsize) { gfc_error ("Sum of second and third arguments of IBITS exceeds bit size " "at %L", &y->where); return &gfc_bad_expr; } result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where); bits = gfc_getmem (bitsize * sizeof (int)); for (i = 0; i < bitsize; i++) bits[i] = 0; for (i = 0; i < len; i++) bits[i] = mpz_tstbit (x->value.integer, i + pos); for (i = 0; i < bitsize; i++) { if (bits[i] == 0) { mpz_clrbit (result->value.integer, i); } else if (bits[i] == 1) { mpz_setbit (result->value.integer, i); } else { gfc_internal_error ("IBITS: Bad bit"); } } gfc_free (bits); return range_check (result, "IBITS");}gfc_expr *gfc_simplify_ibset (gfc_expr * x, gfc_expr * y){ gfc_expr *result; int k, pos; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; if (gfc_extract_int (y, &pos) != NULL || pos < 0) { gfc_error ("Invalid second argument of IBSET at %L", &y->where); return &gfc_bad_expr; } k = gfc_validate_kind (x->ts.type, x->ts.kind, false); if (pos > gfc_integer_kinds[k].bit_size) { gfc_error ("Second argument of IBSET exceeds bit size at %L", &y->where); return &gfc_bad_expr; } result = gfc_copy_expr (x); mpz_setbit (result->value.integer, pos); twos_complement (result->value.integer, gfc_integer_kinds[k].bit_size); return range_check (result, "IBSET");}gfc_expr *gfc_simplify_ichar (gfc_expr * e){ gfc_expr *result; int index; if (e->expr_type != EXPR_CONSTANT) return NULL; if (e->value.character.length != 1) { gfc_error ("Argument of ICHAR at %L must be of length one", &e->where); return &gfc_bad_expr; } index = (unsigned char) e->value.character.string[0]; if (index < 0 || index > UCHAR_MAX) { gfc_error ("Argument of ICHAR at %L out of range of this processor", &e->where); return &gfc_bad_expr; } result = gfc_int_expr (index); result->where = e->where; return range_check (result, "ICHAR");}gfc_expr *gfc_simplify_ieor (gfc_expr * x, gfc_expr * y){ gfc_expr *result; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where); mpz_xor (result->value.integer, x->value.integer, y->value.integer); return range_check (result, "IEOR");}gfc_expr *gfc_simplify_index (gfc_expr * x, gfc_expr * y, gfc_expr * b){ gfc_expr *result; int back, len, lensub; int i, j, k, count, index = 0, start; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; if (b != NULL && b->value.logical != 0) back = 1; else back = 0; result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &x->where); len = x->value.character.length; lensub = y->value.character.length; if (len < lensub) { mpz_set_si (result->value.integer, 0); return result; } if (back == 0) { if (lensub == 0) { mpz_set_si (result->value.integer, 1); return result; } else if (lensub == 1) { for (i = 0; i < len; i++) { for (j = 0; j < lensub; j++) { if (y->value.character.string[j] == x->value.character.string[i]) { index = i + 1; goto done; } } } } else { for (i = 0; i < len; i++) { for (j = 0; j < lensub; j++) { if (y->value.character.string[j] == x->value.character.string[i]) { start = i; count = 0; for (k = 0; k < lensub; k++) { if (y->value.character.string[k] == x->value.character.string[k + start]) count++; } if (count == lensub) { index = start + 1; goto done; } } } } } } else { if (lensub == 0) { mpz_set_si (result->value.integer, len + 1); return result; } else if (lensub == 1) { for (i = 0; i < len; i++) { for (j = 0; j < lensub; j++) { if (y->value.character.string[j] == x->value.character.string[len - i]) { index = len - i + 1; goto done; } } } } else { for (i = 0; i < len; i++) { for (j = 0; j < lensub; j++) { if (y->value.character.string[j] == x->value.character.string[len - i]) { start = len - i; if (start <= len - lensub) { count = 0; for (k = 0; k < lensub; k++) if (y->value.character.string[k] == x->value.character.string[k + start]) count++; if (count == lensub) { index = start + 1; goto done; } } else { continue; } } } } } }done: mpz_set_si (result->value.integer, index); return range_check (result, "INDEX");}gfc_expr *gfc_simplify_int (gfc_expr * e, gfc_expr * k){ gfc_expr *rpart, *rtrunc, *result; int kind; kind = get_kind (BT_INTEGER, k, "INT", 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); switch (e->ts.type) { case BT_INTEGER: mpz_set (result->value.integer, e->value.integer); break; case BT_REAL: rtrunc = gfc_copy_expr (e); mpfr_trunc (rtrunc->value.real, e->value.real); gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); gfc_free_expr (rtrunc); break; case BT_COMPLEX: rpart = gfc_complex2real (e, kind); rtrunc = gfc_copy_expr (rpart); mpfr_trunc (rtrunc->value.real, rpart->value.real); gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); gfc_free_expr (rpart); gfc_free_expr (rtrunc); break; default: gfc_error ("Argument of INT at %L is not a valid type", &e->where); gfc_free_expr (result); return &gfc_bad_expr; } return range_check (result, "INT");}gfc_expr *gfc_simplify_ifix (gfc_expr * e){ gfc_expr *rtrunc, *result; if (e->expr_type != EXPR_CONSTANT) return NULL; result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &e->where); rtrunc = gfc_copy_expr (e); mpfr_trunc (rtrunc->value.real, e->value.real); gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); gfc_free_expr (rtrunc); return range_check (result, "IFIX");}gfc_expr *gfc_simplify_idint (gfc_expr * e){ gfc_expr *rtrunc, *result; if (e->expr_type != EXPR_CONSTANT) return NULL; result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &e->where); rtrunc = gfc_copy_expr (e); mpfr_trunc (rtrunc->value.real, e->value.real); gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); gfc_free_expr (rtrunc); return range_check (result, "IDINT");}gfc_expr *gfc_simplify_ior (gfc_expr * x, gfc_expr * y){ gfc_expr *result; if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT) return NULL; result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where); mpz_ior (result->value.integer, x->value.integer, y->value.integer); return range_check (result, "IOR");}gfc_expr *gfc_simplify_ishft (gfc_expr * e, gfc_expr * s){ gfc_expr *result; int shift, ashift, isize, k, *bits, i; if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT) return NULL; if (gfc_extract_int (s, &shift) != NULL) { gfc_error ("Invalid second argument of ISHFT at %L", &s->where); return &gfc_bad_expr; } k = gfc_validate_kind (BT_INTEGER, e->ts.kind, false); isize = gfc_integer_kinds[k].bit_size; if (shift >= 0) ashift = shift; else ashift = -shift; if (ashift > isize) { gfc_error ("Magnitude of second argument of ISHFT exceeds bit size at %L", &s->where); return &gfc_bad_expr; } result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where); if (shift == 0) { mpz_set (result->value.integer, e->value.integer); return range_check (result, "ISHFT"); } bits = gfc_getmem (isize * sizeof (int)); for (i = 0; i < isize; i++) bits[i] = mpz_tstbit (e->value.integer, i); if (shift > 0) { for (i = 0; i < shift; i++) mpz_clrbit (result->value.integer, i); for (i = 0; i < isize - shift; i++) { if (bits[i] == 0) mpz_clrbit (result->value.integer, i + shift); else mpz_setbit (result->value.integer, i + shift); } } else { for (i = isize - 1; i >= isize - ashift; i--) mpz_clrbit (result->value.integer, i); for (i = isize - 1; i >= ashift; i--) { if (bits[i] == 0) mpz_clrbit (result->value.integer, i - ashift); else mpz_setbit (result->value.integer, i - ashift); } } twos_complement (result->value.integer, isize); gfc_free (bits); return result;}gfc_expr *gfc_simplify_ishftc (gfc_expr * e, gfc_expr * s, gfc_expr * sz){ gfc_expr *result; int shift, ashift, isize, delta, k; int i, *bits; if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT) return NULL; if (gfc_extract_int (s, &shift) != NULL) { gfc_error ("Invalid second argument of ISHFTC at %L", &s->where); return &gfc_bad_expr; } k = gfc_validate_kind (e->ts.type, e->ts.kind, false); if (sz != NULL) { if (gfc_extract_int (sz, &isize) != NULL || isize < 0) { gfc_error ("Invalid third argument of ISHFTC at %L", &sz->where); return &gfc_bad_expr; } } else isize = gfc_integer_kinds[k].bit_size; if (shift >= 0) ashift = shift; else ashift = -shift; if (ashift > isize) { gfc_error ("Magnitude of second argument of ISHFTC exceeds third argument " "at %L", &s->where); return &gfc_bad_expr; } result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where); if (shift == 0) { mpz_set (result->value.integer, e->value.integer); return result; } bits = gfc_getmem (isize * sizeof (int)); for (i = 0; i < isize; i++) bits[i] = mpz_tstbit (e->value.integer, i); delta = isize - ashift; if (shift > 0) { for (i = 0; i < delta; i++) { if (bits[i] == 0) mpz_clrbit (result->value.integer, i + shift); else mpz_setbit (result->value.integer, i + shift); } for (i = delta; i < isize; i++) { if (bits[i] == 0) mpz_clrbit (result->value.integer, i - delta); else mpz_setbit (result->value.integer, i - delta); } } else { for (i = 0; i < ashift; i++) { if (bits[i] == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -