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
99afc9fc
Commit
99afc9fc
authored
Apr 26, 2016
by
Christoph Mallon
Browse files
ia32: Handle shifts, which must be executed with smaller bit width.
This fixes backend/shift2.c.
parent
25b743a0
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_spec.pl
View file @
99afc9fc
...
...
@@ -168,7 +168,10 @@ my $binop_mem = {
my
$shiftop
=
{
irn_flags
=>
[
"
modify_flags
",
"
rematerializable
"
],
in_reqs
=>
[
"
gp
",
"
ecx
"
],
constructors
=>
{
""
=>
{
in_reqs
=>
[
"
gp
",
"
ecx
"
]
},
"
8bit
"
=>
{
in_reqs
=>
[
"
eax ebx ecx edx
",
"
ecx
"
]
},
},
out_reqs
=>
[
"
in_r0 !in_r1
",
"
flags
"
],
ins
=>
[
"
val
",
"
count
"
],
outs
=>
[
"
res
",
"
flags
"
],
...
...
ir/be/ia32/ia32_transform.c
View file @
99afc9fc
...
...
@@ -1310,13 +1310,13 @@ static ir_node *skip_shift_amount_conv(ir_node *n)
/**
* Construct a shift/rotate binary operation, sets AM and immediate if required.
*
* @param op1 The first operand
* @param op2 The second operand
* @param func The node constructor function
* @param op1 The first operand
* @param op2 The second operand
* @param func The node constructor function
* @param func8 The node constructor function for an 8 bit operation
* @return The constructed ia32 node.
*/
static
ir_node
*
gen_shift_binop
(
ir_node
*
node
,
ir_node
*
op1
,
ir_node
*
op2
,
construct_shift_func
*
func
,
match_flags_t
flags
)
static
ir_node
*
gen_shift_binop
(
ir_node
*
const
node
,
ir_node
*
op1
,
ir_node
*
op2
,
construct_shift_func
*
const
func
,
construct_shift_func
*
const
func8
,
match_flags_t
const
flags
)
{
ir_mode
*
mode
=
get_irn_mode
(
node
);
...
...
@@ -1329,19 +1329,22 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
panic
(
"modulo shift!=32 not supported by ia32 backend"
);
}
x86_insn_size_t
size
=
x86_size_from_mode
(
mode
);
ir_node
*
new_op1
;
if
(
flags
&
match_mode_neutral
)
{
op1
=
be_skip_downconv
(
op1
,
true
);
new_op1
=
be_transform_node
(
op1
);
size
=
X86_SIZE_32
;
}
else
{
op1
=
be_skip_sameconv
(
op1
);
if
(
get_mode_size_bits
(
mode
)
!=
32
)
{
if
(
flags
&
match_sign_ext
)
{
new_op1
=
transform_sext
(
op1
);
}
else
{
assert
(
flags
&
match_zero_ext
);
new_op1
=
transform_zext
(
op1
);
}
if
(
size
==
X86_SIZE_32
)
{
new_op1
=
be_transform_node
(
op1
);
}
else
if
(
flags
&
match_sign_ext
)
{
new_op1
=
transform_sext
(
op1
);
size
=
X86_SIZE_32
;
}
else
if
(
flags
&
match_zero_ext
)
{
new_op1
=
transform_zext
(
op1
);
size
=
X86_SIZE_32
;
}
else
{
new_op1
=
be_transform_node
(
op1
);
}
...
...
@@ -1350,9 +1353,10 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
op2
=
skip_shift_amount_conv
(
op2
);
ir_node
*
new_op2
=
create_immediate_or_transform
(
op2
,
'I'
);
dbg_info
*
const
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
const
new_block
=
be_transform_nodes_block
(
node
);
return
func
(
dbgi
,
new_block
,
new_op1
,
new_op2
,
X86_SIZE_32
);
dbg_info
*
const
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
const
new_block
=
be_transform_nodes_block
(
node
);
construct_shift_func
*
const
cons
=
size
==
X86_SIZE_8
?
func8
:
func
;
return
cons
(
dbgi
,
new_block
,
new_op1
,
new_op2
,
size
);
}
/**
...
...
@@ -1514,12 +1518,12 @@ static ir_node *match_64bit_shift(ir_node *node)
static
ir_node
*
gen_Rol
(
ir_node
*
node
,
ir_node
*
op1
,
ir_node
*
op2
)
{
return
gen_shift_binop
(
node
,
op1
,
op2
,
new_bd_ia32_Rol
,
match_immediate
);
return
gen_shift_binop
(
node
,
op1
,
op2
,
&
new_bd_ia32_Rol
,
&
new_bd_ia32_Rol_8bit
,
match_immediate
);
}
static
ir_node
*
gen_Ror
(
ir_node
*
node
,
ir_node
*
op1
,
ir_node
*
op2
)
{
return
gen_shift_binop
(
node
,
op1
,
op2
,
new_bd_ia32_Ror
,
match_immediate
);
return
gen_shift_binop
(
node
,
op1
,
op2
,
&
new_bd_ia32_Ror
,
&
new_bd_ia32_Ror_8bit
,
match_immediate
);
}
/**
...
...
@@ -1928,8 +1932,7 @@ static ir_node *gen_Shl(ir_node *node)
return
create_lea_add
(
dbgi
,
new_block
,
new_left
,
new_left
);
}
return
gen_shift_binop
(
node
,
left
,
right
,
new_bd_ia32_Shl
,
match_mode_neutral
|
match_immediate
);
return
gen_shift_binop
(
node
,
left
,
right
,
&
new_bd_ia32_Shl
,
&
new_bd_ia32_Shl_8bit
,
match_mode_neutral
|
match_immediate
);
}
/**
...
...
@@ -1942,8 +1945,7 @@ static ir_node *gen_Shr(ir_node *node)
ir_node
*
left
=
get_Shr_left
(
node
);
ir_node
*
right
=
get_Shr_right
(
node
);
return
gen_shift_binop
(
node
,
left
,
right
,
new_bd_ia32_Shr
,
match_immediate
|
match_zero_ext
);
return
gen_shift_binop
(
node
,
left
,
right
,
&
new_bd_ia32_Shr
,
&
new_bd_ia32_Shr_8bit
,
match_immediate
|
match_zero_ext
);
}
/**
...
...
@@ -1994,8 +1996,7 @@ static ir_node *gen_Shrs(ir_node *node)
}
}
return
gen_shift_binop
(
node
,
left
,
right
,
new_bd_ia32_Sar
,
match_immediate
|
match_sign_ext
);
return
gen_shift_binop
(
node
,
left
,
right
,
&
new_bd_ia32_Sar
,
&
new_bd_ia32_Sar_8bit
,
match_immediate
|
match_sign_ext
);
}
/**
...
...
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