static tree fold_const_builtin_nan (tree type, tree arg, bool quiet) { REAL_VALUE_TYPE real; const char *str = c_getstr (arg); if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) return build_real (type, real); return NULL_TREE; }
tree fold_const_call (built_in_function fn, tree type, tree arg0, tree arg1) { const char *p0, *p1; switch (fn) { case BUILT_IN_STRSPN: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strspn (p0, p1)); return NULL_TREE; case BUILT_IN_STRCSPN: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strcspn (p0, p1)); return NULL_TREE; case BUILT_IN_STRCMP: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_cmp_result (type, strcmp (p0, p1)); return NULL_TREE; default: return fold_const_call_1 (fn, type, arg0, arg1); } }
tree fold_const_call (combined_fn fn, tree type, tree arg) { switch (fn) { case CFN_BUILT_IN_STRLEN: if (const char *str = c_getstr (arg)) return build_int_cst (type, strlen (str)); return NULL_TREE; CASE_CFN_NAN: CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN): case CFN_BUILT_IN_NAND32: case CFN_BUILT_IN_NAND64: case CFN_BUILT_IN_NAND128: return fold_const_builtin_nan (type, arg, true); CASE_CFN_NANS: CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS): return fold_const_builtin_nan (type, arg, false); case CFN_REDUC_PLUS: return fold_const_reduction (type, arg, PLUS_EXPR); case CFN_REDUC_MAX: return fold_const_reduction (type, arg, MAX_EXPR); case CFN_REDUC_MIN: return fold_const_reduction (type, arg, MIN_EXPR); case CFN_REDUC_AND: return fold_const_reduction (type, arg, BIT_AND_EXPR); case CFN_REDUC_IOR: return fold_const_reduction (type, arg, BIT_IOR_EXPR); case CFN_REDUC_XOR: return fold_const_reduction (type, arg, BIT_XOR_EXPR); default: return fold_const_call_1 (fn, type, arg); } }
tree fold_const_call (built_in_function fn, tree type, tree arg) { switch (fn) { case BUILT_IN_STRLEN: if (const char *str = c_getstr (arg)) return build_int_cst (type, strlen (str)); return NULL_TREE; CASE_FLT_FN (BUILT_IN_NAN): case BUILT_IN_NAND32: case BUILT_IN_NAND64: case BUILT_IN_NAND128: return fold_const_builtin_nan (type, arg, true); CASE_FLT_FN (BUILT_IN_NANS): return fold_const_builtin_nan (type, arg, false); default: return fold_const_call_1 (fn, type, arg); } }
tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) { const char *p0, *p1; char c; unsigned HOST_WIDE_INT s0, s1; size_t s2 = 0; switch (fn) { case CFN_BUILT_IN_STRNCMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strncmp (p0, p1, s2)); return NULL_TREE; case CFN_BUILT_IN_STRNCASECMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)) && strncmp (p0, p1, s2) == 0) return build_int_cst (type, 0); return NULL_TREE; case CFN_BUILT_IN_BCMP: case CFN_BUILT_IN_MEMCMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); if ((p0 = c_getstr (arg0, &s0)) && (p1 = c_getstr (arg1, &s1)) && s2 <= s0 && s2 <= s1) return build_cmp_result (type, memcmp (p0, p1, s2)); return NULL_TREE; case CFN_BUILT_IN_MEMCHR: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); if ((p0 = c_getstr (arg0, &s0)) && s2 <= s0 && target_char_cst_p (arg1, &c)) { const char *r = (const char *) memchr (p0, c, s2); if (r == NULL) return build_int_cst (type, 0); return fold_convert (type, fold_build_pointer_plus_hwi (arg0, r - p0)); } return NULL_TREE; default: return fold_const_call_1 (fn, type, arg0, arg1, arg2); } }
tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) { const char *p0, *p1; char c; switch (fn) { case CFN_BUILT_IN_STRSPN: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strspn (p0, p1)); return NULL_TREE; case CFN_BUILT_IN_STRCSPN: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strcspn (p0, p1)); return NULL_TREE; case CFN_BUILT_IN_STRCMP: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_cmp_result (type, strcmp (p0, p1)); return NULL_TREE; case CFN_BUILT_IN_STRCASECMP: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) { int r = strcmp (p0, p1); if (r == 0) return build_cmp_result (type, r); } return NULL_TREE; case CFN_BUILT_IN_INDEX: case CFN_BUILT_IN_STRCHR: if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) { const char *r = strchr (p0, c); if (r == NULL) return build_int_cst (type, 0); return fold_convert (type, fold_build_pointer_plus_hwi (arg0, r - p0)); } return NULL_TREE; case CFN_BUILT_IN_RINDEX: case CFN_BUILT_IN_STRRCHR: if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) { const char *r = strrchr (p0, c); if (r == NULL) return build_int_cst (type, 0); return fold_convert (type, fold_build_pointer_plus_hwi (arg0, r - p0)); } return NULL_TREE; case CFN_BUILT_IN_STRSTR: if ((p1 = c_getstr (arg1))) { if ((p0 = c_getstr (arg0))) { const char *r = strstr (p0, p1); if (r == NULL) return build_int_cst (type, 0); return fold_convert (type, fold_build_pointer_plus_hwi (arg0, r - p0)); } if (*p1 == '\0') return fold_convert (type, arg0); } return NULL_TREE; default: return fold_const_call_1 (fn, type, arg0, arg1); } }