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
74d06db9
Commit
74d06db9
authored
Oct 19, 2011
by
Matthias Braun
Browse files
ia32: change ShrD/ShlD patterns to match Add instead of Or
parent
cb6d4f67
Changes
1
Show whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_transform.c
View file @
74d06db9
...
...
@@ -1239,6 +1239,118 @@ static int am_has_immediates(const ia32_address_t *addr)
||
addr
->
frame_entity
||
addr
->
use_frame
;
}
typedef
ir_node
*
(
*
new_shiftd_func
)(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
high
,
ir_node
*
low
,
ir_node
*
count
);
/**
* Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
* op1 - target to be shifted
* op2 - contains bits to be shifted into target
* op3 - shift count
* Only op3 can be an immediate.
*/
static
ir_node
*
gen_64bit_shifts
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
high
,
ir_node
*
low
,
ir_node
*
count
,
new_shiftd_func
func
)
{
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
new_high
=
be_transform_node
(
high
);
ir_node
*
new_low
=
be_transform_node
(
low
);
ir_node
*
new_count
;
ir_node
*
new_node
;
/* the shift amount can be any mode that is bigger than 5 bits, since all
* other bits are ignored anyway */
while
(
is_Conv
(
count
)
&&
get_irn_n_edges
(
count
)
==
1
&&
mode_is_int
(
get_irn_mode
(
count
)))
{
assert
(
get_mode_size_bits
(
get_irn_mode
(
count
))
>=
5
);
count
=
get_Conv_op
(
count
);
}
new_count
=
create_immediate_or_transform
(
count
,
0
);
new_node
=
func
(
dbgi
,
new_block
,
new_high
,
new_low
,
new_count
);
return
new_node
;
}
/**
* test wether 2 values result in 'x' and '32-x' when interpreted as a shift
* value.
*/
static
bool
is_complementary_shifts
(
ir_node
*
value1
,
ir_node
*
value2
)
{
if
(
is_Const
(
value1
)
&&
is_Const
(
value2
))
{
ir_tarval
*
tv1
=
get_Const_tarval
(
value1
);
ir_tarval
*
tv2
=
get_Const_tarval
(
value2
);
if
(
tarval_is_long
(
tv1
)
&&
tarval_is_long
(
tv2
))
{
long
v1
=
get_tarval_long
(
tv1
);
long
v2
=
get_tarval_long
(
tv2
);
return
v1
<=
v2
&&
v2
==
32
-
v1
;
}
}
return
false
;
}
static
ir_node
*
match_64bit_shift
(
ir_node
*
node
)
{
ir_node
*
op1
=
get_binop_left
(
node
);
ir_node
*
op2
=
get_binop_right
(
node
);
assert
(
is_Or
(
node
)
||
is_Add
(
node
));
if
(
is_Shr
(
op1
))
{
ir_node
*
tmp
=
op1
;
op1
=
op2
;
op2
=
tmp
;
}
/* match ShlD operation */
if
(
is_Shl
(
op1
)
&&
is_Shr
(
op2
))
{
ir_node
*
shl_right
=
get_Shl_right
(
op1
);
ir_node
*
shl_left
=
get_Shl_left
(
op1
);
ir_node
*
shr_right
=
get_Shr_right
(
op2
);
ir_node
*
shr_left
=
get_Shr_left
(
op2
);
/* constant ShlD operation */
if
(
is_complementary_shifts
(
shl_right
,
shr_right
))
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shl_left
,
shr_left
,
shl_right
,
new_bd_ia32_ShlD
);
}
/* constant ShrD operation */
if
(
is_complementary_shifts
(
shr_right
,
shl_right
))
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shr_left
,
shl_left
,
shr_right
,
new_bd_ia32_ShrD
);
}
/* lower_dw produces the following for ShlD:
* Or(Shr(Shr(high,1),Not(c)),Shl(low,c)) */
if
(
is_Shr
(
shr_left
)
&&
is_Not
(
shr_right
)
&&
is_Const_1
(
get_Shr_right
(
shr_left
))
&&
get_Not_op
(
shr_right
)
==
shl_right
)
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
val_h
=
get_Shr_left
(
shr_left
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shl_left
,
val_h
,
shl_right
,
new_bd_ia32_ShlD
);
}
/* lower_dw produces the following for ShrD:
* Or(Shl(Shl(high,1),Not(c)), Shr(low,c)) */
if
(
is_Shl
(
shl_left
)
&&
is_Not
(
shl_right
)
&&
is_Const_1
(
get_Shl_right
(
shl_left
))
&&
get_Not_op
(
shl_right
)
==
shr_right
)
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
val_h
=
get_Shl_left
(
shl_left
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shr_left
,
val_h
,
shr_right
,
new_bd_ia32_ShrD
);
}
}
return
NULL
;
}
/**
* Creates an ia32 Add.
*
...
...
@@ -1254,6 +1366,10 @@ static ir_node *gen_Add(ir_node *node)
ia32_address_t
addr
;
ia32_address_mode_t
am
;
new_node
=
match_64bit_shift
(
node
);
if
(
new_node
!=
NULL
)
return
new_node
;
if
(
mode_is_float
(
mode
))
{
if
(
ia32_cg_config
.
use_sse2
)
return
gen_binop
(
node
,
op1
,
op2
,
new_bd_ia32_xAdd
,
...
...
@@ -1424,117 +1540,6 @@ static ir_node *gen_And(ir_node *node)
match_commutative
|
match_mode_neutral
|
match_am
|
match_immediate
);
}
/**
* test wether 2 values result in 'x' and '32-x' when interpreted as a shift
* value.
*/
static
bool
is_complementary_shifts
(
ir_node
*
value1
,
ir_node
*
value2
)
{
if
(
is_Const
(
value1
)
&&
is_Const
(
value2
))
{
ir_tarval
*
tv1
=
get_Const_tarval
(
value1
);
ir_tarval
*
tv2
=
get_Const_tarval
(
value2
);
if
(
tarval_is_long
(
tv1
)
&&
tarval_is_long
(
tv2
))
{
long
v1
=
get_tarval_long
(
tv1
);
long
v2
=
get_tarval_long
(
tv2
);
return
v1
<=
v2
&&
v2
==
32
-
v1
;
}
}
return
false
;
}
typedef
ir_node
*
(
*
new_shiftd_func
)(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
high
,
ir_node
*
low
,
ir_node
*
count
);
/**
* Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
* op1 - target to be shifted
* op2 - contains bits to be shifted into target
* op3 - shift count
* Only op3 can be an immediate.
*/
static
ir_node
*
gen_64bit_shifts
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
high
,
ir_node
*
low
,
ir_node
*
count
,
new_shiftd_func
func
)
{
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
new_high
=
be_transform_node
(
high
);
ir_node
*
new_low
=
be_transform_node
(
low
);
ir_node
*
new_count
;
ir_node
*
new_node
;
/* the shift amount can be any mode that is bigger than 5 bits, since all
* other bits are ignored anyway */
while
(
is_Conv
(
count
)
&&
get_irn_n_edges
(
count
)
==
1
&&
mode_is_int
(
get_irn_mode
(
count
)))
{
assert
(
get_mode_size_bits
(
get_irn_mode
(
count
))
>=
5
);
count
=
get_Conv_op
(
count
);
}
new_count
=
create_immediate_or_transform
(
count
,
0
);
new_node
=
func
(
dbgi
,
new_block
,
new_high
,
new_low
,
new_count
);
return
new_node
;
}
static
ir_node
*
match_64bit_shift
(
ir_node
*
node
)
{
ir_node
*
op1
=
get_Or_left
(
node
);
ir_node
*
op2
=
get_Or_right
(
node
);
if
(
is_Shr
(
op1
))
{
ir_node
*
tmp
=
op1
;
op1
=
op2
;
op2
=
tmp
;
}
/* match ShlD operation */
if
(
is_Shl
(
op1
)
&&
is_Shr
(
op2
))
{
ir_node
*
shl_right
=
get_Shl_right
(
op1
);
ir_node
*
shl_left
=
get_Shl_left
(
op1
);
ir_node
*
shr_right
=
get_Shr_right
(
op2
);
ir_node
*
shr_left
=
get_Shr_left
(
op2
);
/* constant ShlD operation */
if
(
is_complementary_shifts
(
shl_right
,
shr_right
))
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shl_left
,
shr_left
,
shl_right
,
new_bd_ia32_ShlD
);
}
/* constant ShrD operation */
if
(
is_complementary_shifts
(
shr_right
,
shl_right
))
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shr_left
,
shl_left
,
shr_right
,
new_bd_ia32_ShrD
);
}
/* lower_dw produces the following for ShlD:
* Or(Shr(Shr(high,1),Not(c)),Shl(low,c)) */
if
(
is_Shr
(
shr_left
)
&&
is_Not
(
shr_right
)
&&
is_Const_1
(
get_Shr_right
(
shr_left
))
&&
get_Not_op
(
shr_right
)
==
shl_right
)
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
val_h
=
get_Shr_left
(
shr_left
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shl_left
,
val_h
,
shl_right
,
new_bd_ia32_ShlD
);
}
/* lower_dw produces the following for ShrD:
* Or(Shl(Shl(high,1),Not(c)), Shr(low,c)) */
if
(
is_Shl
(
shl_left
)
&&
is_Not
(
shl_right
)
&&
is_Const_1
(
get_Shl_right
(
shl_left
))
&&
get_Not_op
(
shl_right
)
==
shr_right
)
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
val_h
=
get_Shl_left
(
shl_left
);
return
gen_64bit_shifts
(
dbgi
,
block
,
shr_left
,
val_h
,
shr_right
,
new_bd_ia32_ShrD
);
}
}
return
NULL
;
}
/**
* Creates an ia32 Or.
*
...
...
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