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
a5ccc803
Commit
a5ccc803
authored
Dec 06, 2014
by
Christoph Mallon
Browse files
ia32: Split IMul into IMul and IMulImm.
parent
a1461bd2
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_emitter.c
View file @
a5ccc803
...
...
@@ -687,18 +687,6 @@ unknown:
va_end
(
ap
);
}
static
void
emit_ia32_IMul
(
const
ir_node
*
node
)
{
/* do we need the 3-address form? */
arch_register_t
const
*
const
in_reg
=
arch_get_irn_register_in
(
node
,
n_ia32_IMul_left
);
arch_register_t
const
*
const
out_reg
=
arch_get_irn_register_out
(
node
,
pn_ia32_IMul_res
);
if
(
in_reg
!=
out_reg
)
{
ia32_emitf
(
node
,
"imul%M %#S4, %#AS3, %#D0"
);
}
else
{
ia32_emitf
(
node
,
"imul%M %#AS4, %#S3"
);
}
}
/**
* walks up a tree of copies/perms/spills/reloads to find the original value
* that is moved around
...
...
@@ -1327,7 +1315,6 @@ static void ia32_register_emitters(void)
be_set_emitter
(
op_ia32_CopyB
,
emit_ia32_CopyB
);
be_set_emitter
(
op_ia32_CopyB_i
,
emit_ia32_CopyB_i
);
be_set_emitter
(
op_ia32_GetEIP
,
emit_ia32_GetEIP
);
be_set_emitter
(
op_ia32_IMul
,
emit_ia32_IMul
);
be_set_emitter
(
op_ia32_Jcc
,
emit_ia32_Jcc
);
be_set_emitter
(
op_ia32_Jmp
,
emit_ia32_Jmp
);
be_set_emitter
(
op_ia32_Minus64
,
emit_ia32_Minus64
);
...
...
@@ -2350,16 +2337,16 @@ static void bemit_test(ir_node const *const node)
static
void
bemit_imul
(
const
ir_node
*
node
)
{
ir_node
*
right
=
get_irn_n
(
node
,
n_ia32_IMul_right
);
/* Do we need the immediate form? */
if
(
is_ia32_Immediate
(
right
))
{
ia32_immediate_attr_t
const
*
const
attr
=
get_ia32_immediate_attr_const
(
right
);
bool
const
imm8
=
ia32_is_8bit_imm
(
attr
);
bemit_unop_reg
(
node
,
0x69
|
(
imm8
?
OP_IMM8
:
0
)
,
n_ia32_IMul_
lef
t
);
bemit_imm
(
attr
,
imm8
?
8
:
32
);
}
else
{
bemit_
0f_
unop_reg
(
node
,
0x
AF
,
n_ia32_IMul_
righ
t
);
}
bemit_0f_unop_reg
(
node
,
0xAF
,
n_ia32_IMul_right
);
}
static
void
bemit_imulimm
(
const
ir_node
*
node
)
{
ir_node
const
*
const
right
=
get_irn_n
(
node
,
n_ia32_IMul_
righ
t
);
ia32_immediate_attr_t
const
*
const
attr
=
get_ia32_immediate_attr_const
(
right
);
bool
const
imm8
=
ia32_is_8bit_imm
(
attr
);
bemit_unop_reg
(
node
,
0x
69
|
(
imm8
?
OP_IMM8
:
0
)
,
n_ia32_IMul_
lef
t
);
bemit_imm
(
attr
,
imm8
?
8
:
32
);
}
static
void
bemit_dec
(
const
ir_node
*
node
)
...
...
@@ -3096,6 +3083,7 @@ static void ia32_register_binary_emitters(void)
be_set_emitter
(
op_ia32_IJmp
,
bemit_ijmp
);
be_set_emitter
(
op_ia32_IMul
,
bemit_imul
);
be_set_emitter
(
op_ia32_IMul1OP
,
bemit_imul1op
);
be_set_emitter
(
op_ia32_IMulImm
,
bemit_imulimm
);
be_set_emitter
(
op_ia32_Inc
,
bemit_inc
);
be_set_emitter
(
op_ia32_IncMem
,
bemit_incmem
);
be_set_emitter
(
op_ia32_Jcc
,
bemit_ia32_jcc
);
...
...
ir/be/ia32/ia32_finish.c
View file @
a5ccc803
...
...
@@ -186,12 +186,6 @@ static inline int need_constraint_copy(ir_node *irn)
{
/* TODO this should be determined from the node specification */
switch
(
get_ia32_irn_opcode
(
irn
))
{
case
iro_ia32_IMul
:
{
/* the 3 operand form of IMul needs no constraint copy */
ir_node
*
right
=
get_irn_n
(
irn
,
n_ia32_IMul_right
);
return
!
is_ia32_Immediate
(
right
);
}
case
iro_ia32_Lea
:
case
iro_ia32_Minus64
:
return
0
;
...
...
ir/be/ia32/ia32_optimize.c
View file @
a5ccc803
...
...
@@ -837,14 +837,11 @@ exchange:
/**
* Split a Imul mem, imm into a Load mem and Imul reg, imm if possible.
*/
static
void
peephole_ia32_Imul_split
(
ir_node
*
imul
)
static
void
peephole_ia32_Imul
Imm
_split
(
ir_node
*
imul
)
{
const
ir_node
*
right
=
get_irn_n
(
imul
,
n_ia32_IMul_right
);
if
(
!
is_ia32_Immediate
(
right
)
||
get_ia32_op_type
(
imul
)
!=
ia32_AddrModeS
)
{
/* no memory, imm form ignore */
/* Ignore, if no memory, imm form. */
if
(
get_ia32_op_type
(
imul
)
!=
ia32_AddrModeS
)
return
;
}
/* we need a free register */
const
arch_register_t
*
reg
=
get_free_gp_reg
(
get_irn_irg
(
imul
));
if
(
reg
==
NULL
)
...
...
@@ -910,8 +907,8 @@ void ia32_peephole_optimization(ir_graph *irg)
register_peephole_optimization
(
op_ia32_Conv_I2I
,
peephole_ia32_Conv_I2I
);
if
(
ia32_cg_config
.
use_pxor
)
register_peephole_optimization
(
op_ia32_xZero
,
peephole_ia32_xZero
);
if
(
!
ia32_cg_config
.
use_imul_mem_imm32
)
register_peephole_optimization
(
op_ia32_IMul
,
peephole_ia32_Imul_split
);
if
(
!
ia32_cg_config
.
use_imul_mem_imm32
)
register_peephole_optimization
(
op_ia32_IMul
Imm
,
peephole_ia32_Imul
Imm
_split
);
be_peephole_opt
(
irg
);
/* pass 2 */
...
...
ir/be/ia32/ia32_spec.pl
View file @
a5ccc803
...
...
@@ -266,13 +266,26 @@ l_Mul => {
IMul
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
# TODO: adjust out requirements for the 3 operand form
# (no need for should_be_same then)
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
none
",
"
gp
",
"
gp
"
],
out
=>
[
"
in_r4 in_r5
",
"
flags
",
"
none
"
]
},
ins
=>
[
"
base
",
"
index
",
"
mem
",
"
left
",
"
right
"
],
outs
=>
[
"
res
",
"
flags
",
"
M
"
],
am
=>
"
source,binary
",
emit
=>
"
imul%M %B
",
latency
=>
5
,
mode
=>
$mode_gp
,
modified_flags
=>
$status_flags
},
IMulImm
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
none
",
"
gp
",
"
gp
"
],
out
=>
[
"
gp
",
"
flags
",
"
none
"
]
},
ins
=>
[
"
base
",
"
index
",
"
mem
",
"
left
",
"
right
"
],
outs
=>
[
"
res
",
"
flags
",
"
M
"
],
am
=>
"
source,binary
",
emit
=>
"
imul%M %#S4, %#AS3, %#D0
",
latency
=>
5
,
mode
=>
$mode_gp
,
modified_flags
=>
$status_flags
...
...
ir/be/ia32/ia32_transform.c
View file @
a5ccc803
...
...
@@ -1504,9 +1504,13 @@ static ir_node *gen_Mul(ir_node *node)
else
return
gen_binop_x87_float
(
node
,
op1
,
op2
,
new_bd_ia32_fmul
);
}
return
gen_binop
(
node
,
op1
,
op2
,
new_bd_ia32_IMul
,
match_commutative
|
match_am
|
match_mode_neutral
|
match_immediate
|
match_am_and_immediates
);
ir_node
*
const
block
=
get_nodes_block
(
node
);
ia32_address_mode_t
am
;
match_arguments
(
&
am
,
block
,
op1
,
op2
,
NULL
,
match_commutative
|
match_am
|
match_mode_neutral
|
match_immediate
|
match_am_and_immediates
);
construct_binop_func
*
const
func
=
is_ia32_Immediate
(
am
.
new_op2
)
?
new_bd_ia32_IMulImm
:
new_bd_ia32_IMul
;
return
make_binop
(
node
,
&
am
,
func
);
}
/**
...
...
Write
Preview
Supports
Markdown
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