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
b1d0f056
Commit
b1d0f056
authored
Dec 26, 2015
by
Matthias Braun
Browse files
amd64: Implement most x87->int conversions
parent
6109afee
Changes
3
Show whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_spec.pl
View file @
b1d0f056
...
...
@@ -256,6 +256,17 @@ my $x87binop = {
mode
=>
$mode_x87
,
};
my
$x87store
=
{
op_flags
=>
[
"
uses_memory
"
],
state
=>
"
exc_pinned
",
in_reqs
=>
"
...
",
out_reqs
=>
[
"
mem
"
],
outs
=>
[
"
M
"
],
attr_type
=>
"
amd64_x87_binop_addr_attr_t
",
attr
=>
"
const amd64_binop_addr_attr_t *attr_init
",
mode
=>
"
mode_M
",
};
%nodes
=
(
push_am
=>
{
op_flags
=>
[
"
uses_memory
"
],
...
...
@@ -779,30 +790,21 @@ fild => {
outs
=>
[
"
res
",
"
unused
",
"
M
"
],
attr_type
=>
"
amd64_x87_addr_attr_t
",
attr
=>
"
amd64_insn_mode_t insn_mode, amd64_op_mode_t op_mode, amd64_addr_t addr
",
emit
=>
"
fild%FM %AM
",
emit
=>
"
fild%M %AM
",
},
fisttp
=>
{
template
=>
$x87store
,
emit
=>
"
fisttp%M %AM
",
},
fst
=>
{
op_flags
=>
[
"
uses_memory
"
],
state
=>
"
exc_pinned
",
in_reqs
=>
"
...
",
out_reqs
=>
[
"
mem
"
],
outs
=>
[
"
M
"
],
attr_type
=>
"
amd64_x87_binop_addr_attr_t
",
attr
=>
"
const amd64_binop_addr_attr_t *attr_init
",
mode
=>
"
mode_M
",
template
=>
$x87store
,
emit
=>
"
fst%FP%FM %AM
",
},
fstp
=>
{
op_flags
=>
[
"
uses_memory
"
],
state
=>
"
exc_pinned
",
in_reqs
=>
"
...
",
out_reqs
=>
[
"
mem
"
],
outs
=>
[
"
M
"
],
attr_type
=>
"
amd64_x87_binop_addr_attr_t
",
attr
=>
"
const amd64_binop_addr_attr_t *attr_init
",
mode
=>
"
mode_M
",
template
=>
$x87store
,
emit
=>
"
fstp%FM %AM
",
},
...
...
@@ -865,6 +867,7 @@ fxch => {
fpop
=>
{
op_flags
=>
[
"
keep
"
],
out_reqs
=>
[
"
none
"
],
attrs_equal
=>
"
attrs_equal_false
",
attr_type
=>
"
amd64_x87_attr_t
",
attr
=>
"
const arch_register_t *reg
",
init
=>
"
attr->x87.reg = reg;
",
...
...
ir/be/amd64/amd64_transform.c
View file @
b1d0f056
...
...
@@ -2261,10 +2261,29 @@ static ir_node *conv_sse_to_x87(dbg_info *dbgi, ir_node *block, ir_node *op)
return
be_new_Proj
(
load
,
pn_amd64_fld_res
);
}
static
ir_node
*
conv_int_to_x87
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
)
static
ir_node
*
conv_x87_to_sse
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
ir_mode
*
dst_mode
)
{
ir_mode
*
const
mode
=
get_irn_mode
(
op
);
ir_node
*
const
new_op
=
extend_if_necessary
(
dbgi
,
block
,
op
);
amd64_insn_mode_t
const
insn_mode
=
get_insn_mode_from_mode
(
dst_mode
);
ir_node
*
const
new_op
=
be_transform_node
(
op
);
ir_node
*
in
[
5
];
int
n_in
=
0
;
amd64_addr_t
addr
;
assert
(
get_mode_size_bits
(
dst_mode
)
<=
64
);
store_to_temp
(
new_bd_amd64_fst
,
x87_reg_mem_reqs
,
&
addr
,
dbgi
,
block
,
in
,
&
n_in
,
new_op
,
insn_mode
);
assert
(
n_in
<
(
int
)
ARRAY_SIZE
(
in
));
ir_node
*
load
=
new_bd_amd64_movs_xmm
(
dbgi
,
block
,
n_in
,
in
,
reg_mem_reqs
,
insn_mode
,
AMD64_OP_ADDR
,
addr
);
set_irn_pinned
(
load
,
false
);
return
be_new_Proj
(
load
,
pn_amd64_fld_res
);
}
static
ir_node
*
conv_int_to_x87
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
val
)
{
ir_mode
*
const
mode
=
get_irn_mode
(
val
);
ir_node
*
const
new_val
=
extend_if_necessary
(
dbgi
,
block
,
val
);
amd64_insn_mode_t
insn_mode
=
get_insn_mode_from_mode
(
mode
);
if
(
insn_mode
<
INSN_MODE_32
)
insn_mode
=
INSN_MODE_32
;
...
...
@@ -2276,32 +2295,38 @@ static ir_node *conv_int_to_x87(dbg_info *dbgi, ir_node *block, ir_node *op)
int
n_in
=
0
;
amd64_addr_t
addr
;
store_to_temp
(
new_bd_amd64_mov_store
,
reg_reg_mem_reqs
,
&
addr
,
dbgi
,
block
,
in
,
&
n_in
,
new_
op
,
insn_mode
);
in
,
&
n_in
,
new_
val
,
insn_mode
);
assert
(
n_in
<
(
int
)
ARRAY_SIZE
(
in
));
ir_node
*
load
=
new_bd_amd64_fild
(
dbgi
,
block
,
n_in
,
in
,
reg_mem_reqs
,
INSN_MODE_32
,
AMD64_OP_ADDR
,
addr
);
insn_mode
,
AMD64_OP_ADDR
,
addr
);
set_irn_pinned
(
load
,
false
);
return
be_new_Proj
(
load
,
pn_amd64_fild_res
);
}
static
ir_node
*
conv_x87_to_
sse
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op
,
ir_
mode
*
d
st_mode
)
static
ir_node
*
conv_x87_to_
int
(
dbg_info
*
const
dbgi
,
ir_node
*
const
block
,
ir_
node
*
const
val
,
ir_mode
*
const
de
st_mode
)
{
amd64_insn_mode_t
const
insn_mode
=
get_insn_mode_from_mode
(
dst_mode
);
ir_node
*
const
new_op
=
be_transform_node
(
op
);
ir_node
*
const
new_val
=
be_transform_node
(
val
);
amd64_insn_mode_t
const
insn_mode_dest
=
get_insn_mode_from_mode
(
dest_mode
);
amd64_insn_mode_t
const
insn_mode_src
=
insn_mode_dest
>
INSN_MODE_32
?
INSN_MODE_64
:
INSN_MODE_32
;
ir_node
*
in
[
5
];
int
n_in
=
0
;
amd64_addr_t
addr
;
assert
(
get_mode_size_bits
(
dst_mode
)
<=
64
);
store_to_temp
(
new_bd_amd64_fst
,
x87_reg_mem_reqs
,
&
addr
,
dbgi
,
block
,
in
,
&
n_in
,
new_op
,
insn_mode
);
store_to_temp
(
new_bd_amd64_fisttp
,
x87K_reg_mem_reqs
,
&
addr
,
dbgi
,
block
,
in
,
&
n_in
,
new_val
,
insn_mode_src
);
assert
(
n_in
<
(
int
)
ARRAY_SIZE
(
in
));
ir_node
*
load
=
new_bd_amd64_movs_xmm
(
dbgi
,
block
,
n_in
,
in
,
reg_mem_reqs
,
insn_mode
,
AMD64_OP_ADDR
,
addr
);
create_mov_func
new_mov
=
insn_mode_dest
<
INSN_MODE_64
?
new_bd_amd64_movs
:
new_bd_amd64_mov_gp
;
ir_node
*
load
=
new_mov
(
dbgi
,
block
,
n_in
,
in
,
reg_mem_reqs
,
insn_mode_dest
,
AMD64_OP_ADDR
,
addr
);
set_irn_pinned
(
load
,
false
);
return
be_new_Proj
(
load
,
pn_amd64_
fld
_res
);
return
be_new_Proj
(
load
,
pn_amd64_
movs
_res
);
}
static
ir_node
*
gen_Conv
(
ir_node
*
const
node
)
...
...
@@ -2360,11 +2385,11 @@ static ir_node *gen_Conv(ir_node *const node)
min_mode
=
src_mode
;
}
else
if
(
src_bits
>
dst_bits
)
{
min_mode
=
dst_mode
;
}
else
if
((
src_float
&&
dst_float
)
||
is_gp
)
{
}
else
{
assert
(
src_bits
==
dst_bits
);
/* skip unnecessary conv */
if
((
src_float
&&
dst_float
)
||
is_gp
)
return
be_transform_node
(
op
);
}
else
{
/* src_bits == dst_bits, but one is float the other integer*/
min_mode
=
src_mode
;
}
...
...
@@ -2400,7 +2425,7 @@ static ir_node *gen_Conv(ir_node *const node)
return
conv_sse_to_x87
(
dbgi
,
block
,
op
);
}
else
if
(
src_mode
==
x86_mode_E
)
{
if
(
!
dst_float
)
panic
(
"amd64: int -> mode_E NIY"
);
return
conv_x87_to_int
(
dbgi
,
block
,
op
,
dst_mode
);
return
conv_x87_to_sse
(
dbgi
,
block
,
op
,
dst_mode
);
}
...
...
ir/be/amd64/amd64_x87.c
View file @
b1d0f056
...
...
@@ -43,6 +43,11 @@ static void sim_amd64_fild(x87_state *const state, ir_node *const node)
x86_sim_x87_load
(
state
,
node
,
value
);
}
static
void
sim_amd64_fisttp
(
x87_state
*
const
state
,
ir_node
*
const
node
)
{
x86_sim_x87_store_pop
(
state
,
node
,
0
);
}
static
void
sim_amd64_call
(
x87_state
*
const
state
,
ir_node
*
const
node
)
{
/** push fp results onto x87 stack */
...
...
@@ -99,6 +104,7 @@ static void prepare_callbacks(void)
x86_register_x87_sim
(
op_amd64_fchs
,
x86_sim_x87_unop
);
x86_register_x87_sim
(
op_amd64_fdiv
,
sim_amd64_fdiv
);
x86_register_x87_sim
(
op_amd64_fild
,
sim_amd64_fild
);
x86_register_x87_sim
(
op_amd64_fisttp
,
sim_amd64_fisttp
);
x86_register_x87_sim
(
op_amd64_fld
,
sim_amd64_fld
);
x86_register_x87_sim
(
op_amd64_fld1
,
x86_x87_push
);
x86_register_x87_sim
(
op_amd64_fldz
,
x86_x87_push
);
...
...
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