Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
540a01db
Commit
540a01db
authored
Aug 28, 2007
by
Michael Beck
Browse files
fixed lowering of signed 32x32=64 multiplication
[r15617]
parent
7ee233ad
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_intrinsics.c
View file @
540a01db
...
...
@@ -431,6 +431,25 @@ static int map_Mul(ir_node *call, void *ctx) {
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
);
...
...
@@ -440,6 +459,7 @@ static int map_Mul(ir_node *call, void *ctx) {
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
;
...
...
ir/be/ia32/ia32_spec.pl
View file @
540a01db
...
...
@@ -471,8 +471,11 @@ IMul1OP => {
},
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
},
...
...
ir/be/ia32/ia32_transform.c
View file @
540a01db
...
...
@@ -3380,7 +3380,6 @@ GEN_LOWERED_OP(Adc)
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
)
...
...
@@ -3490,6 +3489,34 @@ static ir_node *gen_ia32_l_Mul(ir_node *node) {
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
)
...
...
@@ -4202,8 +4229,8 @@ static void register_transformers(void)
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment