- case pn_Mod_res: /* Result of computation. */
- idx = get_irn_idx(proj);
- assert(idx < env->n_entries);
- env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
- env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
- break;
- default:
- assert(0 && "unexpected Proj number");
- } /* switch */
- /* mark this proj: we have handled it already, otherwise we might fall into
- * out new nodes. */
- mark_irn_visited(proj);
- } /* for */
-} /* lower_Mod */
-
-/**
- * Translate a DivMod.
- *
- * Create two intrinsic Calls.
- */
-static void lower_DivMod(ir_node *node, ir_mode *mode, lower_env_t *env) {
- ir_node *block, *proj, *irn, *mem, *callDiv, *callMod;
- ir_node *resDiv = NULL;
- ir_node *resMod = NULL;
- ir_node *in[4];
- ir_mode *opmode;
- dbg_info *dbg;
- ir_type *mtp;
- int idx;
- node_entry_t *entry;
- unsigned flags = 0;
- ir_graph *irg;
-
- /* check if both results are needed */
- for (proj = get_irn_link(node); proj; proj = get_irn_link(proj)) {
- switch (get_Proj_proj(proj)) {
- case pn_DivMod_res_div: flags |= 1; break;
- case pn_DivMod_res_mod: flags |= 2; break;
- default: break;
- } /* switch */
- } /* for */
-
- irn = get_DivMod_left(node);
- entry = env->entries[get_irn_idx(irn)];
- assert(entry);
-
- if (! entry->low_word) {
- /* not ready yet, wait */
- pdeq_putr(env->waitq, node);
- return;
- } /* if */
-
- in[0] = entry->low_word;
- in[1] = entry->high_word;
-
- irn = get_DivMod_right(node);
- entry = env->entries[get_irn_idx(irn)];
- assert(entry);
-
- if (! entry->low_word) {
- /* not ready yet, wait */
- pdeq_putr(env->waitq, node);
- return;
- } /* if */
-
- in[2] = entry->low_word;
- in[3] = entry->high_word;
-
- dbg = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- irg = current_ir_graph;
-
- mem = get_DivMod_mem(node);
-
- callDiv = callMod = NULL;
- mtp = mode_is_signed(mode) ? binop_tp_s : binop_tp_u;
- if (flags & 1) {
- opmode = get_irn_op_mode(node);
- irn = get_intrinsic_address(mtp, op_Div, opmode, opmode, block, env);
- callDiv = new_rd_Call(dbg, irg, block, mem,
- irn, 4, in, mtp);
- set_irn_pinned(callDiv, get_irn_pinned(node));
- resDiv = new_r_Proj(irg, block, callDiv, mode_T, pn_Call_T_result);
- } /* if */
- if (flags & 2) {
- if (flags & 1)
- mem = new_r_Proj(irg, block, callDiv, mode_M, pn_Call_M);
- opmode = get_irn_op_mode(node);
- irn = get_intrinsic_address(mtp, op_Mod, opmode, opmode, block, env);
- callMod = new_rd_Call(dbg, irg, block, mem,
- irn, 4, in, mtp);
- set_irn_pinned(callMod, get_irn_pinned(node));
- resMod = new_r_Proj(irg, block, callMod, mode_T, pn_Call_T_result);
- } /* if */
-
- for (proj = get_irn_link(node); proj; proj = get_irn_link(proj)) {
- switch (get_Proj_proj(proj)) {
- case pn_DivMod_M: /* Memory result. */
- /* reroute to the first call */
- set_Proj_pred(proj, callDiv ? callDiv : (callMod ? callMod : mem));
- set_Proj_proj(proj, pn_Call_M_except);
- break;
- case pn_DivMod_X_except: /* Execution result if exception occurred. */
- /* reroute to the first call */
- set_Proj_pred(proj, callDiv ? callDiv : (callMod ? callMod : mem));
- set_Proj_proj(proj, pn_Call_X_except);
- break;
- case pn_DivMod_res_div: /* Result of Div. */
- idx = get_irn_idx(proj);
- assert(idx < env->n_entries);
- env->entries[idx]->low_word = new_r_Proj(irg, block, resDiv, env->params->low_unsigned, 0);
- env->entries[idx]->high_word = new_r_Proj(irg, block, resDiv, mode, 1);
- break;
- case pn_DivMod_res_mod: /* Result of Mod. */
- idx = get_irn_idx(proj);
- env->entries[idx]->low_word = new_r_Proj(irg, block, resMod, env->params->low_unsigned, 0);
- env->entries[idx]->high_word = new_r_Proj(irg, block, resMod, mode, 1);