return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
}
+/**
+ * Generate a pinned unary builtin.
+ *
+ * @param kind the builtin kind to generate
+ * @param op the operand
+ * @param function_type the function type for the GNU builtin routine
+ * @param db debug info
+ */
+static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db)
+{
+ ir_node *in[1];
+ in[0] = expression_to_firm(op);
+
+ ir_type *tp = get_ir_type(function_type);
+ ir_type *res = get_method_res_type(tp, 0);
+ ir_node *mem = get_store();
+ ir_node *irn = new_d_Builtin(db, mem, kind, 1, in, tp);
+ set_store(new_Proj(irn, mode_M, pn_Builtin_M));
+ return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
+}
+
+
+/**
+ * Generate an binary-void-return builtin.
+ *
+ * @param kind the builtin kind to generate
+ * @param op1 the first operand
+ * @param op2 the second operand
+ * @param function_type the function type for the GNU builtin routine
+ * @param db debug info
+ */
+static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1, expression_t *op2,
+ type_t *function_type, dbg_info *db)
+{
+ ir_node *in[2];
+ in[0] = expression_to_firm(op1);
+ in[1] = expression_to_firm(op2);
+
+ ir_type *tp = get_ir_type(function_type);
+ ir_node *mem = get_store();
+ ir_node *irn = new_d_Builtin(db, mem, kind, 2, in, tp);
+ set_store(new_Proj(irn, mode_M, pn_Builtin_M));
+ return NULL;
+}
+
/**
* Transform calls to builtin functions.
*/
case bk_ms_byteswap_ulong:
case bk_ms_byteswap_uint64:
return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi);
+ case bk_ms__inbyte:
+ case bk_ms__inword:
+ case bk_ms__indword:
+ return gen_unary_builtin_pinned(ir_bk_inport, call->arguments->expression, function_type, dbgi);
+ case bk_ms__outbyte:
+ case bk_ms__outword:
+ case bk_ms__outdword:
+ return gen_binary_builtin_mem(ir_bk_outport, call->arguments->expression,
+ call->arguments->next->expression, function_type, dbgi);
default:
panic("unsupported builtin found");
}
bk_ms__debugbreak, /**< MS __debugbreak */
bk_ms_ReturnAddress, /**< MS _ReturnAddress */
bk_ms__popcount, /**< MS __popcount */
+ bk_ms_enable, /**< MS _enable */
+ bk_ms_disable, /**< MS _disable */
+ bk_ms__inbyte, /**< MS __inbyte */
+ bk_ms__inword, /**< MS __inword */
+ bk_ms__indword, /**< MS __indword */
+ bk_ms__outbyte, /**< MS __outbyte */
+ bk_ms__outword, /**< MS __outword */
+ bk_ms__outdword, /**< MS __outdword */
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 */
+ bk_ms__readeflags, /**< MS __readflags */
+ bk_ms__writeeflags, /**< MS __writeflags */
} builtin_kind_t;
struct function_t {
MS_BUILTIN(__popcount, make_function_1_type(type_unsigned_int, type_unsigned_int));
/* x86/x64 only */
+ MS_BUILTIN(_enable, make_function_0_type(type_void));
+ MS_BUILTIN(_disable, make_function_0_type(type_void));
+ MS_BUILTIN(__inbyte, make_function_1_type(type_unsigned_char, type_unsigned_short));
+ MS_BUILTIN(__inword, make_function_1_type(type_unsigned_short, type_unsigned_short));
+ MS_BUILTIN(__indword, make_function_1_type(type_unsigned_long, type_unsigned_short));
+ MS_BUILTIN(__outbyte, make_function_2_type(type_void, type_unsigned_short, type_unsigned_char));
+ MS_BUILTIN(__outword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_short));
+ MS_BUILTIN(__outdword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_long));
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));
+ if (machine_size <= 32) {
+ MS_BUILTIN(__readeflags, make_function_0_type(type_unsigned_int));
+ MS_BUILTIN(__writeeflags, make_function_1_type(type_void, type_unsigned_int));
+ } else {
+ MS_BUILTIN(__readeflags, make_function_0_type(type_unsigned_int64));
+ MS_BUILTIN(__writeeflags, make_function_1_type(type_void, type_unsigned_int64));
+ }
+
#undef MS_BUILTIN
#undef CONCAT
#undef STR