+/**
+ * Transforms a Mux node into CMov.
+ *
+ * @param env The transformation environment
+ * @return The transformed node.
+ */
+static ir_node *gen_Mux(ia32_transform_env_t *env) {
+ ir_node *node = env->irn;
+ ir_node *new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \
+ get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
+
+ SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
+
+ return new_op;
+}
+
+
+/**
+ * Following conversion rules apply:
+ *
+ * INT -> INT
+ * ============
+ * 1) n bit -> m bit n > m (downscale)
+ * a) target is signed: movsx
+ * b) target is unsigned: and with lower bits sets
+ * 2) n bit -> m bit n == m (sign change)
+ * always ignored
+ * 3) n bit -> m bit n < m (upscale)
+ * a) source is signed: movsx
+ * b) source is unsigned: and with lower bits sets
+ *
+ * INT -> FLOAT
+ * ==============
+ * SSE(1/2) convert to float or double (cvtsi2ss/sd)
+ *
+ * FLOAT -> INT
+ * ==============
+ * SSE(1/2) convert from float or double to 32bit int (cvtss/sd2si)
+ * if target mode < 32bit: additional INT -> INT conversion (see above)
+ *
+ * FLOAT -> FLOAT
+ * ================
+ * SSE(1/2) convert from float or double to double or float (cvtss/sd2sd/ss)
+ */
+
+//static ir_node *gen_int_downscale_conv(ia32_transform_env_t *env, ir_node *op,
+// ir_mode *src_mode, ir_mode *tgt_mode)
+//{
+// int n = get_mode_size_bits(src_mode);
+// int m = get_mode_size_bits(tgt_mode);
+// dbg_info *dbg = env->dbg;
+// ir_graph *irg = env->irg;
+// ir_node *block = env->block;
+// ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+// ir_node *nomem = new_rd_NoMem(irg);
+// ir_node *new_op, *proj;
+// assert(n > m && "downscale expected");
+// if (mode_is_signed(src_mode) && mode_is_signed(tgt_mode)) {
+// /* ASHL Sn, n - m */
+// new_op = new_rd_ia32_Shl(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
+// proj = new_rd_Proj(dbg, irg, block, new_op, src_mode, 0);
+// set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
+// set_ia32_am_support(new_op, ia32_am_Source);
+// SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
+// /* ASHR Sn, n - m */
+// new_op = new_rd_ia32_Shrs(dbg, irg, block, noreg, noreg, proj, noreg, nomem, mode_T);
+// set_ia32_Immop_tarval(new_op, new_tarval_from_long(n - m, mode_Is));
+// }
+// else {
+// new_op = new_rd_ia32_And(dbg, irg, block, noreg, noreg, op, noreg, nomem, mode_T);
+// set_ia32_Immop_tarval(new_op, new_tarval_from_long((1 << m) - 1, mode_Is));
+// }
+// return new_op;
+//}
+
+/**
+ * Transforms a Conv node.
+ *
+ * @param env The transformation environment
+ * @param op The operator
+ * @return The created ia32 Conv node
+ */
+static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *op) {
+ dbg_info *dbg = env->dbg;
+ ir_graph *irg = env->irg;
+ ir_mode *src_mode = get_irn_mode(op);
+ ir_mode *tgt_mode = env->mode;
+ int src_bits = get_mode_size_bits(src_mode);
+ int tgt_bits = get_mode_size_bits(tgt_mode);
+ ir_node *block = env->block;
+ ir_node *new_op = NULL;
+ ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+ ir_node *nomem = new_rd_NoMem(irg);
+ firm_dbg_module_t *mod = env->mod;
+ ir_node *proj;
+
+ if (src_mode == tgt_mode) {
+ /* this can happen when changing mode_P to mode_Is */
+ DB((mod, LEVEL_1, "killed Conv(mode, mode) ..."));
+ edges_reroute(env->irn, op, irg);
+ }
+ else if (mode_is_float(src_mode)) {
+ /* we convert from float ... */
+ if (mode_is_float(tgt_mode)) {
+ /* ... to float */
+ DB((mod, LEVEL_1, "create Conv(float, float) ..."));
+ new_op = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
+ }
+ else {
+ /* ... to int */
+ DB((mod, LEVEL_1, "create Conv(float, int) ..."));
+ new_op = new_rd_ia32_Conv_FP2I(dbg, irg, block, noreg, noreg, op, nomem, mode_T);
+ /* if target mode is not int: add an additional downscale convert */
+ if (tgt_bits < 32) {
+ SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
+ set_ia32_res_mode(new_op, tgt_mode);
+ set_ia32_am_support(new_op, ia32_am_Source);
+
+ proj = new_rd_Proj(dbg, irg, block, new_op, mode_Is, 0);
+
+ if (tgt_bits == 8 || src_bits == 8) {
+ new_op = new_rd_ia32_Conv_I2I8Bit(dbg, irg, block, noreg, noreg, proj, nomem, mode_T);