- more builtins
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sat, 27 Dec 2008 03:44:55 +0000 (03:44 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sat, 27 Dec 2008 03:44:55 +0000 (03:44 +0000)
[r24905]

ast2firm.c
entity_t.h
parser.c
types.c
types.h

index 75c8e91..8fa7a53 100644 (file)
@@ -1720,6 +1720,26 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp);
                return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
        }
+       case bk_ms_rotl:
+       case bk_ms_rotl64: {
+               ir_node *val  = expression_to_firm(call->arguments->expression);
+               ir_node *shf  = expression_to_firm(call->arguments->next->expression);
+               ir_mode *mode = get_irn_mode(val);
+               return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode);
+       }
+       case bk_ms_rotr:
+       case bk_ms_rotr64: {
+               ir_node *val  = expression_to_firm(call->arguments->expression);
+               ir_node *shf  = expression_to_firm(call->arguments->next->expression);
+               ir_mode *mode = get_irn_mode(val);
+               ir_node *c    = new_Const_long(mode_uint, get_mode_size_bits(mode));
+               ir_node *sub  = new_d_Sub(dbgi, c, create_conv(dbgi, shf, mode_uint), mode_uint);
+               return new_d_Rotl(dbgi, val, sub, mode);
+       }
+       case bk_ms_byteswap_ushort:
+       case bk_ms_byteswap_ulong:
+       case bk_ms_byteswap_uint64:
+               return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi);
        default:
                panic("unsupported builtin found");
        }
index 3081d77..ca2e2c9 100644 (file)
@@ -257,10 +257,22 @@ typedef enum builtin_kind_t {
        bk_gnu_builtin_prefetch,       /**< GNU __builtin_prefetch */
        bk_gnu_builtin_trap,           /**< GNU __builtin_trap */
 
+       bk_ms_rotl,                    /**< MS _rotl */
+       bk_ms_rotr,                    /**< MS _rotr */
+       bk_ms_rotl64,                  /**< MS _rotl64 */
+       bk_ms_rotr64,                  /**< MS _rotr64 */
+       bk_ms_byteswap_ushort,         /**< MS _byteswap_ushort */
+       bk_ms_byteswap_ulong,          /**< MS _byteswap_ulong */
+       bk_ms_byteswap_uint64,         /**< MS _byteswap_uint64 */
+
        bk_ms__debugbreak,             /**< MS __debugbreak */
        bk_ms_ReturnAddress,           /**< MS _ReturnAddress */
        bk_ms__popcount,               /**< MS __popcount */
        bk_ms__ud2,                    /**< MS __ud2 */
+       bk_ms_BitScanForward,          /**< MS _BitScanForward */
+       bk_ms_BitScanReverse,          /**< MS _BitScanReverse */
+       bk_ms_InterlockedExchange,     /**< MS _InterlockedExchange */
+       bk_ms_InterlockedExchange64,   /**< MS _InterlockedExchange64 */
 } builtin_kind_t;
 
 struct function_t {
index 238422a..c5eddfc 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -9352,9 +9352,8 @@ static bool expression_has_effect(const expression_t *const expr)
                                return true;
 
                        switch (call->function->reference.entity->function.btk) {
-                               case bk_gnu_builtin_prefetch:
-                               case bk_gnu_builtin_va_end:   return true;
-                               default:                      return false;
+                               /* FIXME: which builtins have no effect? */
+                               default:                      return true;
                        }
                }
 
@@ -11503,10 +11502,25 @@ static void create_microsoft_intrinsics(void) {
 #define CONCAT(a,b)          a##b
 #define MS_BUILTIN(a, b)  create_builtin_function(CONCAT(bk_ms, a), STR(a), b)
 
+       /* intrinsics for all architectures */
+       MS_BUILTIN(_rotl,                  make_function_2_type(type_unsigned_int,   type_unsigned_int, type_int));
+       MS_BUILTIN(_rotr,                  make_function_2_type(type_unsigned_int,   type_unsigned_int, type_int));
+       MS_BUILTIN(_rotl64,                make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
+       MS_BUILTIN(_rotr64,                make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
+       MS_BUILTIN(_byteswap_ushort,       make_function_1_type(type_unsigned_short, type_unsigned_short));
+       MS_BUILTIN(_byteswap_ulong,        make_function_1_type(type_unsigned_long,  type_unsigned_long));
+       MS_BUILTIN(_byteswap_uint64,       make_function_1_type(type_unsigned_int64, type_unsigned_int64));
+
        MS_BUILTIN(__debugbreak,    make_function_0_type(type_void));
        MS_BUILTIN(_ReturnAddress,  make_function_0_type(type_void_ptr));
        MS_BUILTIN(__popcount,      make_function_1_type(type_unsigned_int, type_unsigned_int));
-       MS_BUILTIN(__ud2,           make_function_0_type_noreturn(type_void));
+
+       /* x86/x64 only */
+       MS_BUILTIN(__ud2,                  make_function_0_type_noreturn(type_void));
+       MS_BUILTIN(_BitScanForward,        make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
+       MS_BUILTIN(_BitScanReverse,        make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
+       MS_BUILTIN(_InterlockedExchange,   make_function_2_type(type_long, type_long_ptr, type_long));
+       MS_BUILTIN(_InterlockedExchange64, make_function_2_type(type_int64, type_int64_ptr, type_int64));
 
 #undef MS_BUILTIN
 #undef CONCAT
diff --git a/types.c b/types.c
index 0842ba2..812dc68 100644 (file)
--- a/types.c
+++ b/types.c
@@ -48,6 +48,7 @@ type_t *type_const_char_ptr;
 type_t *type_int_ptr;
 type_t *type_long_long_ptr;
 type_t *type_long_ptr;
+type_t *type_unsigned_long_ptr;
 type_t *type_short_ptr;
 type_t *type_signed_char_ptr;
 type_t *type_void_ptr;
@@ -90,6 +91,7 @@ type_t *type_unsigned_int8;
 type_t *type_unsigned_int16;
 type_t *type_unsigned_int32;
 type_t *type_unsigned_int64;
+type_t *type_int64_ptr;
 
 
 void init_basic_types(void)
@@ -133,6 +135,9 @@ void init_basic_types(void)
                type_unsigned_int32      = make_atomic_type(unsigned_int32_type_kind, TYPE_QUALIFIER_NONE);
                unsigned_int64_type_kind = find_unsigned_int_atomic_type_kind_for_size(8);
                type_unsigned_int64      = make_atomic_type(unsigned_int64_type_kind, TYPE_QUALIFIER_NONE);
+
+               /* pointer types */
+               type_int64_ptr           = make_pointer_type(type_int64,              TYPE_QUALIFIER_NONE);
        }
 
        /* pointer types */
@@ -142,6 +147,7 @@ void init_basic_types(void)
        type_short_ptr          = make_pointer_type(type_short,             TYPE_QUALIFIER_NONE);
        type_int_ptr            = make_pointer_type(type_int,               TYPE_QUALIFIER_NONE);
        type_long_ptr           = make_pointer_type(type_long,              TYPE_QUALIFIER_NONE);
+       type_unsigned_long_ptr  = make_pointer_type(type_unsigned_long,     TYPE_QUALIFIER_NONE);
        type_long_long_ptr      = make_pointer_type(type_long_long,         TYPE_QUALIFIER_NONE);
 
        type_char_ptr_ptr       = make_pointer_type(type_char_ptr,          TYPE_QUALIFIER_NONE);
diff --git a/types.h b/types.h
index 04288df..08142c3 100644 (file)
--- a/types.h
+++ b/types.h
@@ -47,6 +47,7 @@ extern type_t *type_const_char_ptr;
 extern type_t *type_int_ptr;
 extern type_t *type_long_long_ptr;
 extern type_t *type_long_ptr;
+extern type_t *type_unsigned_long_ptr;
 extern type_t *type_short_ptr;
 extern type_t *type_signed_char_ptr;
 extern type_t *type_void_ptr;
@@ -86,6 +87,7 @@ extern type_t *type_int8;
 extern type_t *type_int16;
 extern type_t *type_int32;
 extern type_t *type_int64;
+extern type_t *type_int64_ptr;
 extern type_t *type_int128;
 extern type_t *type_unsigned_int8;
 extern type_t *type_unsigned_int16;