+static ir_node *ia32_create_set(ir_node *cond)
+{
+ /* ia32-set function produces 8-bit results which have to be converted */
+ ir_node *set = ir_create_mux_set(cond, mode_Bu);
+ ir_node *block = get_nodes_block(set);
+ return new_r_Conv(block, set, mode_Iu);
+}
+
+static void ia32_lower_for_target(void)
+{
+ size_t i, n_irgs = get_irp_n_irgs();
+ lower_mode_b_config_t lower_mode_b_config = {
+ mode_Iu, /* lowered mode */
+ ia32_create_set,
+ 0, /* don't lower direct compares */
+ };
+ lower_params_t params = {
+ 4, /* def_ptr_alignment */
+ LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
+ ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
+ NULL, /* find pointer type */
+ NULL, /* ret_compound_in_regs */
+ };
+
+ /* perform doubleword lowering */
+ lwrdw_param_t lower_dw_params = {
+ 1, /* little endian */
+ 64, /* doubleword size */
+ ia32_create_intrinsic_fkt,
+ &intrinsic_env,
+ };
+
+ /* lower compound param handling */
+ lower_calls_with_compounds(¶ms);
+
+ lower_dw_ops(&lower_dw_params);
+
+ for (i = 0; i < n_irgs; ++i) {
+ ir_graph *irg = get_irp_irg(i);
+ /* lower for mode_b stuff */
+ ir_lower_mode_b(irg, &lower_mode_b_config);
+ /* break up switches with wide ranges */
+ lower_switch(irg, 256, true);
+ }
+}
+
+/**
+ * Create the trampoline code.
+ */
+static ir_node *ia32_create_trampoline_fkt(ir_node *block, ir_node *mem, ir_node *trampoline, ir_node *env, ir_node *callee)
+{
+ ir_graph *irg = get_irn_irg(block);
+ ir_node *p = trampoline;
+ ir_mode *mode = get_irn_mode(p);
+ ir_node *st;
+
+ /* mov ecx,<env> */
+ st = new_r_Store(block, mem, p, new_r_Const_long(irg, mode_Bu, 0xb9), cons_none);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
+ p = new_r_Add(block, p, new_r_Const_long(irg, mode_Iu, 1), mode);
+ st = new_r_Store(block, mem, p, env, cons_none);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
+ p = new_r_Add(block, p, new_r_Const_long(irg, mode_Iu, 4), mode);
+ /* jmp <callee> */
+ st = new_r_Store(block, mem, p, new_r_Const_long(irg, mode_Bu, 0xe9), cons_none);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
+ p = new_r_Add(block, p, new_r_Const_long(irg, mode_Iu, 1), mode);
+ st = new_r_Store(block, mem, p, callee, cons_none);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
+ p = new_r_Add(block, p, new_r_Const_long(irg, mode_Iu, 4), mode);
+
+ return mem;
+}
+