diff options
author | Richard Henderson <rth@cygnus.com> | 2000-01-24 16:45:14 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2000-01-24 16:45:14 -0800 |
commit | 5eda3d66aa0bb2baef0ae78a8674092350b75e16 (patch) | |
tree | b95a5b674897709b08b27062d7d65cc9af886f91 /gcc/c-common.c | |
parent | 52b38064755bdf4b3200eeb38bc65ec6d7de870e (diff) | |
download | gcc-5eda3d66aa0bb2baef0ae78a8674092350b75e16.zip gcc-5eda3d66aa0bb2baef0ae78a8674092350b75e16.tar.gz gcc-5eda3d66aa0bb2baef0ae78a8674092350b75e16.tar.bz2 |
builtins.c (expand_tree_builtin): Move ...
* builtins.c (expand_tree_builtin): Move ...
* c-common.c (expand_tree_builtin): ... here.
From-SVN: r31598
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 6d91810..f7d670c 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3960,3 +3960,104 @@ self_promoting_args_p (parms) } return 1; } + +/* 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. */ +/* ??? By rights this should go in builtins.c, but only C and C++ + implement build_{binary,unary}_op. Not exactly sure what bits + of functionality are actually needed from those functions, or + where the similar functionality exists in the other front ends. */ + +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; +} |