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");
}
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 {
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;
}
}
#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
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;
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)
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 */
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);
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;
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;