summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian Graf <sgraf1337@gmail.com>2017-12-06 14:22:16 +0100
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2018-08-28 13:22:48 +0200
commit0869251006d3fe161788c18b5d9d01cad56a2cc2 (patch)
tree7b2f7541decc24af5913c4a75a6a4945988f8ce1
parent9c1ed13e1fb503f233bfaa1ab52297212402b132 (diff)
Added an implementation for the signbit builtins
m---------libfirm0
-rw-r--r--src/ast/entity_t.h1
-rw-r--r--src/firm/ast2firm.c22
-rw-r--r--src/parser/builtins.c3
4 files changed, 26 insertions, 0 deletions
diff --git a/libfirm b/libfirm
-Subproject b031096c75829e287eb18942542ebcd4c6daa8a
+Subproject 137232fc4070ecc828cb448b11bad355bcb10f9
diff --git a/src/ast/entity_t.h b/src/ast/entity_t.h
index 206ec09..63b84c0 100644
--- a/src/ast/entity_t.h
+++ b/src/ast/entity_t.h
@@ -71,6 +71,7 @@ typedef enum {
BUILTIN_OBJECT_SIZE,
BUILTIN_ROTL,
BUILTIN_ROTR,
+ BUILTIN_SIGNBIT,
BUILTIN_VA_END,
} builtin_kind_t;
diff --git a/src/firm/ast2firm.c b/src/firm/ast2firm.c
index dc2292b..82afb3d 100644
--- a/src/firm/ast2firm.c
+++ b/src/firm/ast2firm.c
@@ -736,6 +736,13 @@ entity_created:
return irentity;
}
+/**
+ * Creates a new Conv node if dest_mode differs from the mode of value,
+ * otherwise returns value unchanged.
+ *
+ * @param value the node representing the value to convert
+ * @param dest_mode the mode to convert to
+ */
static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
{
ir_mode *value_mode = get_irn_mode(value);
@@ -1000,6 +1007,21 @@ static ir_node *process_builtin_call(const call_expression_t *call)
ir_node *one = new_d_Const(dbgi, get_mode_one(res_mode));
return new_d_Mux(dbgi, cmp, zero, one);
}
+ case BUILTIN_SIGNBIT: {
+ expression_t *arg = call->arguments->expression;
+ // Might be faster to pop into a 64 bit slot on x86_64
+ ir_node *val = create_conv(dbgi, expression_to_value(arg), get_modeF());
+ ir_node *bits = new_d_Bitcast(dbgi, val, get_modeIu());
+ ir_node *mask = new_d_Const_long(dbgi, get_modeIu(), 1L << 31);
+ ir_node *flag = new_d_And(dbgi, bits, mask);
+ ir_node *cmp = new_d_Cmp(dbgi, flag, mask, ir_relation_equal);
+
+ 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 f5ce851..a50d2d8 100644
--- a/src/parser/builtins.c
+++ b/src/parser/builtins.c
@@ -111,6 +111,9 @@ void create_gnu_builtins(void)
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_SIGNBIT, "signbit", make_function_1_type(type_int, type_double, DM_CONST));
+ b(BUILTIN_SIGNBIT, "signbitf", make_function_1_type(type_int, type_float, DM_CONST));
+ b(BUILTIN_SIGNBIT, "signbitl", make_function_1_type(type_int, type_long_double, 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));