h_res = t2 + t3
*/
+ if (is_Shrs(a_h) && get_Shrs_left(a_h) == a_l &&
+ is_Shrs(b_h) && get_Shrs_left(b_h) == b_l) {
+ ir_node *c1 = get_Shrs_right(a_h);
+
+ if (c1 == get_Shrs_right(b_h) && is_Const(c1)) {
+ tarval *tv = get_Const_tarval(c1);
+
+ if (tarval_is_long(tv) && get_tarval_long(tv) == 31) {
+ /* it's a 32 * 32 = 64 signed multiplication */
+
+ mul = new_rd_ia32_l_IMul(dbg, irg, block, a_l, b_l);
+ h_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EDX);
+ l_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EAX);
+
+ goto end;
+ }
+ }
+ }
+
mul = new_rd_ia32_l_Mul(dbg, irg, block, a_l, b_l);
pEDX = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EDX);
l_res = new_rd_Proj(dbg, irg, block, mul, l_mode, pn_ia32_l_Mul_EAX);
mul = new_rd_Mul(dbg, irg, block, a_l, b_h, l_mode);
h_res = new_rd_Add(dbg, irg, block, add, mul, l_mode);
+end:
resolve_call(call, l_res, h_res, irg, block);
return 1;
},
l_IMul => {
+ # we should not rematrialize this node. It produces 2 results and has
+ # very strict constrains
op_flags => "C",
cmp_attr => "return 1;",
+ outs => [ "EAX", "EDX", "M" ],
arity => 2
},
GEN_LOWERED_OP(Add)
GEN_LOWERED_OP(Sbb)
GEN_LOWERED_OP(Sub)
-GEN_LOWERED_OP(IMul)
GEN_LOWERED_OP(Xor)
GEN_LOWERED_x87_OP(vfprem)
GEN_LOWERED_x87_OP(vfmul)
return muls;
}
+/**
+ * Transforms a l_IMulS into a "real" IMul1OPS node.
+ *
+ * @param env The transformation environment
+ * @return the created ia32 IMul1OP node
+ */
+static ir_node *gen_ia32_l_IMul(ir_node *node) {
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *left = get_binop_left(node);
+ ir_node *new_left = be_transform_node(left);
+ ir_node *right = get_binop_right(node);
+ ir_node *new_right = be_transform_node(right);
+ ir_node *noreg = ia32_new_NoReg_gp(env_cg);
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+
+ /* l_IMul is already a mode_T node, so we create the IMul1OP in the normal way */
+ /* and then skip the result Proj, because all needed Projs are already there. */
+ ir_node *muls = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_left,
+ new_right, new_NoMem());
+ clear_ia32_commutative(muls);
+ set_ia32_am_support(muls, ia32_am_Source, ia32_am_binary);
+
+ SET_IA32_ORIG_NODE(muls, ia32_get_old_node_name(env_cg, node));
+
+ return muls;
+}
+
GEN_LOWERED_SHIFT_OP(l_ShlDep, Shl)
GEN_LOWERED_SHIFT_OP(l_ShrDep, Shr)
GEN_LOWERED_SHIFT_OP(l_Sar, Sar)
GEN(ia32_l_Sbb);
GEN(ia32_l_Neg);
GEN(ia32_l_Mul);
- GEN(ia32_l_Xor);
GEN(ia32_l_IMul);
+ GEN(ia32_l_Xor);
GEN(ia32_l_ShlDep);
GEN(ia32_l_ShrDep);
GEN(ia32_l_Sar);