diff options
author | Sebastian Graf <sgraf1337@gmail.com> | 2017-12-06 14:22:16 +0100 |
---|---|---|
committer | Johannes Bucher <johannes.bucher2@student.kit.edu> | 2018-08-28 13:22:48 +0200 |
commit | 0869251006d3fe161788c18b5d9d01cad56a2cc2 (patch) | |
tree | 7b2f7541decc24af5913c4a75a6a4945988f8ce1 | |
parent | 9c1ed13e1fb503f233bfaa1ab52297212402b132 (diff) |
Added an implementation for the signbit builtins
m--------- | libfirm | 0 | ||||
-rw-r--r-- | src/ast/entity_t.h | 1 | ||||
-rw-r--r-- | src/firm/ast2firm.c | 22 | ||||
-rw-r--r-- | src/parser/builtins.c | 3 |
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)); |