+ ir_node *res_proj = NULL;
+ ir_node *flags_proj = NULL;
+ const ir_edge_t *edge;
+
+ if (get_irn_mode(irn) == mode_T) {
+ /* collect the Proj uses */
+ foreach_out_edge(irn, edge) {
+ ir_node *proj = get_edge_src_irn(edge);
+ long pn = get_Proj_proj(proj);
+ if (pn == pn_ia32_Sub_res) {
+ assert(res_proj == NULL);
+ res_proj = proj;
+ } else {
+ assert(pn == pn_ia32_Sub_flags);
+ assert(flags_proj == NULL);
+ flags_proj = proj;
+ }
+ }
+ }
+
+ if (flags_proj == NULL) {
+ res = new_bd_ia32_Neg(dbg, block, in2);
+ arch_set_irn_register(res, in2_reg);
+
+ /* add to schedule */
+ sched_add_before(irn, res);
+
+ /* generate the add */
+ res = new_bd_ia32_Add(dbg, block, noreg, noreg, nomem, res, in1);
+ arch_set_irn_register(res, out_reg);
+ set_ia32_commutative(res);
+
+ /* exchange the add and the sub */
+ edges_reroute(irn, res, irg);
+
+ /* add to schedule */
+ sched_add_before(irn, res);
+ } else {
+ ir_node *stc, *cmc, *not, *adc;
+ ir_node *adc_flags;
+
+ /*
+ * ARG, the above technique does NOT set the flags right.
+ * So, we must produce the following code:
+ * t1 = ~b
+ * t2 = a + ~b + Carry
+ * Complement Carry
+ *
+ * a + -b = a + (~b + 1) would set the carry flag IF a == b ...
+ */
+ not = new_bd_ia32_Not(dbg, block, in2);
+ arch_set_irn_register(not, in2_reg);
+ sched_add_before(irn, not);
+
+ stc = new_bd_ia32_Stc(dbg, block);
+ arch_set_irn_register(stc, &ia32_flags_regs[REG_EFLAGS]);
+ sched_add_before(irn, stc);
+
+ adc = new_bd_ia32_Adc(dbg, block, noreg, noreg, nomem, not, in1, stc);
+ arch_set_irn_register(adc, out_reg);
+ sched_add_before(irn, adc);
+
+ set_irn_mode(adc, mode_T);
+ adc_flags = new_r_Proj(irg, block, adc, mode_Iu, pn_ia32_Adc_flags);
+ arch_set_irn_register(adc_flags, &ia32_flags_regs[REG_EFLAGS]);
+
+ cmc = new_bd_ia32_Cmc(dbg, block, adc_flags);
+ arch_set_irn_register(cmc, &ia32_flags_regs[REG_EFLAGS]);
+ sched_add_before(irn, cmc);
+
+ exchange(flags_proj, cmc);
+ if (res_proj != NULL) {
+ set_Proj_pred(res_proj, adc);
+ set_Proj_proj(res_proj, pn_ia32_Adc_res);
+ }