+ * @param env The transformation environment
+ * @param dividend -no comment- :)
+ * @param divisor -no comment- :)
+ * @param dm_flav flavour_Div/Mod/DivMod
+ * @return The created ia32 DivMod node
+ */
+static ir_node *generate_DivMod(transform_env_t *env, ir_node *dividend, ir_node *divisor, op_flavour_t dm_flav) {
+ ir_node *res, *proj;
+ ir_node *edx_node, *cltd;
+ ir_node *in_keep[1];
+ dbg_info *dbg = env->dbg;
+ ir_graph *irg = env->irg;
+ ir_node *block = env->block;
+ ir_mode *mode = env->mode;
+ ir_node *irn = env->irn;
+ ir_node *mem = get_DivMod_mem(irn);
+
+ if (mode_is_signed(mode)) {
+ /* in signed mode, we need to sign extend the dividend */
+ cltd = new_rd_ia32_Cltd(dbg, irg, block, dividend, mode_T);
+ dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EAX);
+ edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_EDX);
+ }
+ else {
+ edx_node = new_rd_ia32_Const(dbg, irg, block, mode_Iu);
+ set_ia32_Const_type(edx_node, asmop_Const);
+ set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
+ }
+
+ res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, mode);
+
+ set_ia32_flavour(res, dm_flav);
+ set_ia32_n_res(res, 2);
+
+ /* Only one proj is used -> We must add a second proj and */
+ /* connect this one to a Keep node to eat up the second */
+ /* destroyed register. */
+ if (get_irn_n_edges(irn) == 1) {
+ proj = get_edge_src_irn(get_irn_out_edge_first(irn));
+ assert(is_Proj(proj) && "non-Proj to Div/Mod node");
+
+ if (get_Proj_proj(proj) == pn_DivMod_res_div) {
+ in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod);
+ }
+ else {
+ in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div);
+ }
+
+ new_Keep(irg, block, 1, in_keep);
+ }
+
+ return res;
+}
+
+
+/**
+ * Wrapper for generate_DivMod. Sets flavour_Mod.