+/**
+ * lower boolean Proj(Cmp)
+ */
+static ir_node *lower_boolean_Proj_Cmp(ir_node *proj, ir_node *cmp, lower_env_t *env) {
+ int lidx, ridx;
+ ir_node *l, *r, *low, *high, *t, *res;
+ pn_Cmp pnc;
+ ir_node *blk;
+ ir_graph *irg = current_ir_graph;
+ dbg_info *db;
+
+ l = get_Cmp_left(cmp);
+ lidx = get_irn_idx(l);
+ if (! env->entries[lidx]->low_word) {
+ /* still not ready */
+ return NULL;
+ } /* if */
+
+ r = get_Cmp_right(cmp);
+ ridx = get_irn_idx(r);
+ if (! env->entries[ridx]->low_word) {
+ /* still not ready */
+ return NULL;
+ } /* if */
+
+ pnc = get_Proj_proj(proj);
+ blk = get_nodes_block(cmp);
+ db = get_irn_dbg_info(cmp);
+ low = new_rd_Cmp(db, irg, blk, env->entries[lidx]->low_word, env->entries[ridx]->low_word);
+ high = new_rd_Cmp(db, irg, blk, env->entries[lidx]->high_word, env->entries[ridx]->high_word);
+
+ if (pnc == pn_Cmp_Eq) {
+ /* simple case:a == b <==> a_h == b_h && a_l == b_l */
+ res = new_rd_And(db, irg, blk,
+ new_r_Proj(irg, blk, low, mode_b, pnc),
+ new_r_Proj(irg, blk, high, mode_b, pnc),
+ mode_b);
+ } else if (pnc == pn_Cmp_Lg) {
+ /* simple case:a != b <==> a_h != b_h || a_l != b_l */
+ res = new_rd_Or(db, irg, blk,
+ new_r_Proj(irg, blk, low, mode_b, pnc),
+ new_r_Proj(irg, blk, high, mode_b, pnc),
+ mode_b);
+ } else {
+ /* a rel b <==> a_h REL b_h || (a_h == b_h && a_l rel b_l) */
+ t = new_rd_And(db, irg, blk,
+ new_r_Proj(irg, blk, low, mode_b, pnc),
+ new_r_Proj(irg, blk, high, mode_b, pn_Cmp_Eq),
+ mode_b);
+ res = new_rd_Or(db, irg, blk,
+ new_r_Proj(irg, blk, high, mode_b, pnc & ~pn_Cmp_Eq),
+ t,
+ mode_b);
+ } /* if */
+ return res;
+} /* lower_boolean_Proj_Cmp */
+
+/**
+ * The type of a lower function.
+ *
+ * @param node the node to be lowered
+ * @param mode the low mode for the destination node
+ * @param env the lower environment
+ */