diff options
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 1ca5b5d..fcb6a7a 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2520,3 +2520,100 @@ expand_builtin (exp, target, subtarget, mode, ignore) to be called normally. */ return expand_call (exp, target, ignore); } + +/* Recognize certain built-in functions so we can make tree-codes + other than CALL_EXPR. We do this when it enables fold-const.c + to do something useful. */ + +tree +expand_tree_builtin (function, params, coerced_params) + tree function, params, coerced_params; +{ + enum tree_code code; + + if (DECL_BUILT_IN_CLASS (function) != BUILT_IN_NORMAL) + return NULL_TREE; + + switch (DECL_FUNCTION_CODE (function)) + { + case BUILT_IN_ABS: + case BUILT_IN_LABS: + case BUILT_IN_FABS: + if (coerced_params == 0) + return integer_zero_node; + return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0); + + case BUILT_IN_ISGREATER: + if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT) + code = UNLE_EXPR; + else + code = LE_EXPR; + goto unordered_cmp; + + case BUILT_IN_ISGREATEREQUAL: + if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT) + code = UNLT_EXPR; + else + code = LT_EXPR; + goto unordered_cmp; + + case BUILT_IN_ISLESS: + if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT) + code = UNGE_EXPR; + else + code = GE_EXPR; + goto unordered_cmp; + + case BUILT_IN_ISLESSEQUAL: + if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT) + code = UNGT_EXPR; + else + code = GT_EXPR; + goto unordered_cmp; + + case BUILT_IN_ISLESSGREATER: + if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT) + code = UNEQ_EXPR; + else + code = EQ_EXPR; + goto unordered_cmp; + + case BUILT_IN_ISUNORDERED: + if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT) + return integer_zero_node; + code = UNORDERED_EXPR; + goto unordered_cmp; + + unordered_cmp: + { + tree arg0, arg1; + + if (params == 0 + || TREE_CHAIN (params) == 0) + { + error ("too few arguments to function `%s'", + IDENTIFIER_POINTER (DECL_NAME (function))); + return error_mark_node; + } + else if (TREE_CHAIN (TREE_CHAIN (params)) != 0) + { + error ("too many arguments to function `%s'", + IDENTIFIER_POINTER (DECL_NAME (function))); + return error_mark_node; + } + + arg0 = TREE_VALUE (params); + arg1 = TREE_VALUE (TREE_CHAIN (params)); + arg0 = build_binary_op (code, arg0, arg1, 0); + if (code != UNORDERED_EXPR) + arg0 = build_unary_op (TRUTH_NOT_EXPR, arg0, 0); + return arg0; + } + break; + + default: + break; + } + + return NULL_TREE; +} |