fix binary emitter for cmp with addressmode and immediate
[libfirm] / ir / lower / lower_switch.c
index 6cfae4b..bc6eed0 100644 (file)
  * @version $Id$
  */
 
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <limits.h>
 
+#include "array_t.h"
 #include "ircons.h"
 #include "irgopt.h"
 #include "irgwalk.h"
 #include "irnode_t.h"
 #include "irouts.h"
+#include "irpass_t.h"
 
 #define foreach_out_irn(irn, i, outirn) for(i = get_irn_n_outs(irn) - 1;\
        i >= 0 && (outirn = get_irn_out(irn, i)); --i)
@@ -74,7 +74,7 @@ static int should_do_table_switch(ir_node *cond, unsigned spare_size)
        if (get_irn_n_outs(cond) <= 4)
                return 0;
 
-       default_pn = get_Cond_defaultProj(cond);
+       default_pn = get_Cond_default_proj(cond);
 
        foreach_out_irn(cond, i, proj) {
                long pn = get_Proj_proj(proj);
@@ -100,7 +100,7 @@ static int casecmp(const void *a, const void *b)
 {
        const case_data_t *cda = a;
        const case_data_t *cdb = b;
-       return cda->value - cdb->value;
+       return (cda->value > cdb->value) - (cda->value < cdb->value);
 }
 
 /**
@@ -136,6 +136,7 @@ static void create_if_cascade(ifcas_env_t *env, ir_node *curblock,
                set_Block_cfgpred(curcases[0].target, 0, new_Proj(cond, mode_X, pn_Cond_true));
                in[0] = new_Proj(cond, mode_X, pn_Cond_false);
                neblock = new_Block(1, in);
+               set_cur_block(neblock);
 
                /* second part: "else if(sel == val[1]) goto target[1] else goto default;" */
                val  = new_Const_long(get_irn_mode(env->sel), curcases[1].value);
@@ -161,6 +162,7 @@ static void create_if_cascade(ifcas_env_t *env, ir_node *curblock,
                set_cur_block(curblock);
                in[0] = new_Proj(cond, mode_X, pn_Cond_false);
                geblock = new_Block(1, in);
+               set_cur_block(geblock);
 
                create_if_cascade(env, ltblock, curcases, midcase);
                create_if_cascade(env, geblock, curcases + midcase, numcases - midcase);
@@ -215,7 +217,7 @@ static void find_cond_nodes(ir_node *block, void *ctx)
        numcases = get_irn_n_outs(cond) - 1;      // does not contain default case
        NEW_ARR_A(case_data_t, cases, numcases);
 
-       default_pn = get_Cond_defaultProj(cond);
+       default_pn = get_Cond_default_proj(cond);
        ifcas_env.sel = sel;
        ifcas_env.defindex = 0;
        NEW_ARR_A(ir_node*, ifcas_env.defusers, numcases);
@@ -278,3 +280,27 @@ void lower_switch(ir_graph *irg, unsigned spare_size)
        }
        current_ir_graph = rem;
 }
+
+struct pass_t {
+       ir_graph_pass_t pass;
+       unsigned        spare_size;
+};
+
+/**
+ * Wrapper for running lower_switch() as a pass.
+ */
+static int pass_wrapper(ir_graph *irg, void *context) {
+       struct pass_t *pass = context;
+
+       lower_switch(irg, pass->spare_size);
+       return 0;
+}
+
+/* creates a pass for lower_switch */
+ir_graph_pass_t *lower_switch_pass(const char *name, unsigned spare_size) {
+       struct pass_t *pass = XMALLOCZ(struct pass_t);
+
+       pass->spare_size = spare_size;
+       return def_graph_pass_constructor(
+               &pass->pass, name ? name : "lower_switch", pass_wrapper);
+}