-static void replace_call(ir_node *irn, ir_node *call, ir_node *mem, ir_node *reg_jmp, ir_node *exc_jmp) {
- if (reg_jmp == NULL) {
- ir_node *block = get_nodes_block(call);
-
- /* Beware: do we need here a protection against CSE? Better we do it. */
- int old_cse = get_opt_cse();
- set_opt_cse(0);
- reg_jmp = new_r_Jmp(current_ir_graph, block);
- set_opt_cse(old_cse);
- exc_jmp = new_Bad();
- }
- irn = new_Tuple(1, &irn);
-
- turn_into_tuple(call, pn_Call_max);
- set_Tuple_pred(call, pn_Call_M_regular, mem);
- set_Tuple_pred(call, pn_Call_X_regular, reg_jmp);
- set_Tuple_pred(call, pn_Call_X_except, exc_jmp);
- set_Tuple_pred(call, pn_Call_T_result, irn);
- set_Tuple_pred(call, pn_Call_M_except, mem);
- set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
-} /* replace_call */
-
-/* A mapper for the integer abs. */
-int i_mapper_abs(ir_node *call, void *ctx) {
+static void replace_call(ir_node *irn, ir_node *call, ir_node *mem,
+ ir_node *reg_jmp, ir_node *exc_jmp)
+{
+ ir_node *block = get_nodes_block(call);
+ ir_graph *irg = get_irn_irg(block);
+ ir_node *rest = new_r_Tuple(block, 1, &irn);
+
+ if (ir_throws_exception(call)) {
+ turn_into_tuple(call, pn_Call_max+1);
+ if (reg_jmp == NULL) {
+ reg_jmp = new_r_Jmp(block);
+ }
+ if (exc_jmp == NULL) {
+ exc_jmp = new_r_Bad(irg, mode_X);
+ }
+ set_Tuple_pred(call, pn_Call_X_regular, reg_jmp);
+ set_Tuple_pred(call, pn_Call_X_except, exc_jmp);
+ } else {
+ assert(reg_jmp == NULL);
+ assert(exc_jmp == NULL);
+ turn_into_tuple(call, pn_Call_T_result+1);
+ assert(pn_Call_M <= pn_Call_T_result);
+ assert(pn_Call_X_regular > pn_Call_T_result);
+ assert(pn_Call_X_except > pn_Call_T_result);
+ }
+ set_Tuple_pred(call, pn_Call_M, mem);
+ set_Tuple_pred(call, pn_Call_T_result, rest);
+}
+
+int i_mapper_abs(ir_node *call, void *ctx)
+{
+ ir_node *mem = get_Call_mem(call);
+ ir_node *block = get_nodes_block(call);
+ ir_node *op = get_Call_param(call, 0);
+ ir_graph *irg = get_irn_irg(call);
+ ir_mode *mode = get_irn_mode(op);
+ dbg_info *dbg = get_irn_dbg_info(call);
+ ir_node *zero = new_r_Const(irg, get_mode_null(mode));
+ ir_node *cmp = new_rd_Cmp(dbg, block, op, zero, ir_relation_less);
+ ir_node *minus_op = new_rd_Minus(dbg, block, op, mode);
+ ir_node *mux;
+ arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
+ (void) ctx;
+
+ /* mux allowed by backend? */
+ if (!allow_ifconv(cmp, op, minus_op))
+ return 0;
+
+ /* construct Mux */
+ mux = new_rd_Mux(dbg, block, cmp, op, minus_op, mode);
+ DBG_OPT_ALGSIM0(call, mux, FS_OPT_RTS_ABS);
+ replace_call(mux, call, mem, NULL, NULL);
+ return 1;
+}
+
+int i_mapper_bswap(ir_node *call, void *ctx)
+{