summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorSebastian Buchwald <Sebastian.Buchwald@kit.edu>2016-07-15 23:09:37 +0200
committerSebastian Buchwald <Sebastian.Buchwald@kit.edu>2016-07-15 23:09:37 +0200
commitedc78822b1e2f23bce149ff62446194b0b23d093 (patch)
tree3a3d78c562394bea38d56acee1ca6da9cf6424d8 /src
parent7ac74d0e596c4d40aa2b3ae1b2f40908e1322bd7 (diff)
Add support for __builtin_isnan
Diffstat (limited to 'src')
-rw-r--r--src/ast/entity_t.h1
-rw-r--r--src/firm/ast2firm.c11
-rw-r--r--src/parser/builtins.c4
3 files changed, 15 insertions, 1 deletions
diff --git a/src/ast/entity_t.h b/src/ast/entity_t.h
index 6d86599..206ec09 100644
--- a/src/ast/entity_t.h
+++ b/src/ast/entity_t.h
@@ -64,6 +64,7 @@ typedef enum {
BUILTIN_EXPECT,
BUILTIN_FIRM,
BUILTIN_INF,
+ BUILTIN_ISNAN,
BUILTIN_LIBC,
BUILTIN_LIBC_CHECK,
BUILTIN_NAN,
diff --git a/src/firm/ast2firm.c b/src/firm/ast2firm.c
index c225932..e009a5e 100644
--- a/src/firm/ast2firm.c
+++ b/src/firm/ast2firm.c
@@ -998,6 +998,17 @@ static ir_node *process_builtin_call(const call_expression_t *call)
ir_tarval *tv = fold_builtin_nan(call, function_type);
return new_d_Const(dbgi, tv);
}
+ case BUILTIN_ISNAN: {
+ expression_t *arg = call->arguments->expression;
+ ir_mode *arg_mode = get_ir_mode_arithmetic(arg->base.type);
+ ir_node *val = create_conv(dbgi, expression_to_value(arg), arg_mode);
+ ir_node *cmp = new_d_Cmp(dbgi, val, val, ir_relation_unordered);
+ type_t *res_type = function_type->function.return_type;
+ ir_mode *res_mode = get_ir_mode_storage(res_type);
+ ir_node *zero = new_d_Const(dbgi, get_mode_null(res_mode));
+ ir_node *one = new_d_Const(dbgi, get_mode_one(res_mode));
+ return new_d_Mux(dbgi, cmp, zero, one);
+ }
case BUILTIN_EXPECT: {
expression_t *argument = call->arguments->expression;
return expression_to_value(argument);
diff --git a/src/parser/builtins.c b/src/parser/builtins.c
index 2558836..f5ce851 100644
--- a/src/parser/builtins.c
+++ b/src/parser/builtins.c
@@ -97,6 +97,8 @@ static entity_t *create_gnu_builtin_chk(const char *name, unsigned chk_arg_pos,
void create_gnu_builtins(void)
{
+ type_t *template = type_builtin_template;
+
entity_t *(*b)(builtin_kind_t,const char*,type_t*) = create_gnu_builtin;
b(BUILTIN_ALLOCA, "alloca", make_function_1_type(type_void_ptr, type_size_t, DM_NONE));
b(BUILTIN_INF, "huge_val", make_function_0_type(type_double, DM_CONST));
@@ -108,6 +110,7 @@ void create_gnu_builtins(void)
b(BUILTIN_NAN, "nan", make_function_1_type(type_double, type_char_ptr, DM_CONST));
b(BUILTIN_NAN, "nanf", make_function_1_type(type_float, type_char_ptr, DM_CONST));
b(BUILTIN_NAN, "nanl", make_function_1_type(type_long_double, type_char_ptr, DM_CONST));
+ b(BUILTIN_ISNAN, "isnan", make_function_type(type_int, 1, (type_t *[]) { template }, DM_CONST));
b(BUILTIN_VA_END, "va_end", make_function_1_type(type_void, type_valist_arg, DM_NONE));
b(BUILTIN_EXPECT, "expect", make_function_2_type(type_long, type_long, type_long, DM_CONST));
b(BUILTIN_OBJECT_SIZE, "object_size", make_function_2_type(type_size_t, type_void_ptr, type_int, DM_CONST));
@@ -137,7 +140,6 @@ void create_gnu_builtins(void)
f(ir_bk_trap, "trap", make_function_type(type_void, 0, NULL, DM_NORETURN));
entity_t *(*s)(ir_builtin_kind,const char*,type_t*) = create_builtin_firm;
- type_t *template = type_builtin_template;
type_t *template_ptr = type_builtin_template_ptr;
s(ir_bk_compare_swap, "__sync_val_compare_and_swap", make_function_type(template, 3, (type_t*[]) { template_ptr, template, template }, DM_NONE));
s(ir_bk_may_alias, "__builtin_may_alias", make_function_type(type_int, 2, (type_t*[]) { type_const_void_ptr, type_const_void_ptr }, DM_NONE));