Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
ec2e8cfd
Commit
ec2e8cfd
authored
Nov 30, 2014
by
Matthias Braun
Browse files
amd64: allow conversion from/to double vector xmm type
parent
5591d31a
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_spec.pl
View file @
ec2e8cfd
...
...
@@ -605,7 +605,8 @@ CvtSD2SS => {
outs
=>
[
"
res
",
"
none
",
"
M
"
],
arity
=>
"
variable
",
attr_type
=>
"
amd64_addr_attr_t
",
attr
=>
"
amd64_insn_mode_t insn_mode, amd64_op_mode_t op_mode, amd64_addr_t addr
",
attr
=>
"
amd64_op_mode_t op_mode, amd64_addr_t addr
",
fixed
=>
"
amd64_insn_mode_t insn_mode = INSN_MODE_64;
\n
",
emit
=>
"
cvtsd2ss %AM, %^D0
",
},
...
...
@@ -649,6 +650,17 @@ CvtSI2SD => {
emit
=>
"
cvtsi2sd %AM, %^D0
",
},
movq
=>
{
state
=>
"
exc_pinned
",
arity
=>
"
variable
",
outs
=>
[
"
res
",
"
none
",
"
M
"
],
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
attr_type
=>
"
amd64_addr_attr_t
",
attr
=>
"
amd64_op_mode_t op_mode, amd64_addr_t addr
",
fixed
=>
"
amd64_insn_mode_t insn_mode = INSN_MODE_64;
\n
",
emit
=>
"
movq %AM, %D0
",
},
movdqa
=>
{
state
=>
"
exc_pinned
",
arity
=>
"
variable
",
...
...
ir/be/amd64/amd64_transform.c
View file @
ec2e8cfd
...
...
@@ -2035,6 +2035,75 @@ static ir_node *gen_Phi(ir_node *node)
return
be_transform_phi
(
node
,
req
);
}
typedef
ir_node
*
(
*
create_mov_func
)(
dbg_info
*
dbgi
,
ir_node
*
block
,
int
arity
,
ir_node
**
in
,
amd64_op_mode_t
op_mode
,
amd64_addr_t
addr
);
static
ir_node
*
match_mov
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
value
,
create_mov_func
create_mov
,
unsigned
pn_res
)
{
amd64_addr_t
addr
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
ir_node
*
load
;
ir_node
*
op
;
int
arity
=
0
;
ir_node
*
in
[
4
];
ir_mode
*
mode
=
get_irn_mode
(
value
);
bool
use_am
=
use_address_matching
(
mode
,
match_am
,
block
,
NULL
,
value
,
&
load
,
&
op
);
amd64_op_mode_t
op_mode
;
const
arch_register_req_t
**
reqs
;
ir_node
*
mem_proj
=
NULL
;
if
(
use_am
)
{
ir_node
*
ptr
=
get_Load_ptr
(
load
);
perform_address_matching
(
ptr
,
&
arity
,
in
,
&
addr
);
if
(
!
val_input
(
addr
.
base_input
)
&&
!
val_input
(
addr
.
index_input
))
reqs
=
mem_reqs
;
else
if
(
val_input
(
addr
.
base_input
)
&&
val_input
(
addr
.
index_input
))
reqs
=
reg_reg_mem_reqs
;
else
reqs
=
reg_mem_reqs
;
ir_node
*
new_mem
=
be_transform_node
(
get_Load_mem
(
load
));
int
mem_input
=
arity
++
;
in
[
mem_input
]
=
new_mem
;
addr
.
mem_input
=
mem_input
;
mem_proj
=
get_Proj_for_pn
(
load
,
pn_Load_M
);
op_mode
=
AMD64_OP_ADDR
;
}
else
{
ir_node
*
new_value
=
be_transform_node
(
value
);
in
[
arity
++
]
=
new_value
;
reqs
=
get_irn_mode
(
new_value
)
==
amd64_mode_xmm
?
xmm_reqs
:
reg_reqs
;
op_mode
=
AMD64_OP_REG
;
}
assert
((
size_t
)
arity
<=
ARRAY_SIZE
(
in
));
ir_node
*
new_node
=
create_mov
(
dbgi
,
block
,
arity
,
in
,
op_mode
,
addr
);
arch_set_irn_register_reqs_in
(
new_node
,
reqs
);
if
(
mem_proj
!=
NULL
)
be_set_transformed_node
(
load
,
new_node
);
ir_node
*
res
=
new_r_Proj
(
new_node
,
amd64_mode_xmm
,
pn_res
);
return
res
;
}
static
ir_node
*
create_movq
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
value
)
{
return
match_mov
(
dbgi
,
block
,
value
,
new_bd_amd64_movq
,
pn_amd64_movq_res
);
}
static
ir_node
*
create_cvtsd2ss
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
value
)
{
return
match_mov
(
dbgi
,
block
,
value
,
new_bd_amd64_CvtSD2SS
,
pn_amd64_CvtSD2SS_res
);
}
static
ir_node
*
gen_Conv
(
ir_node
*
node
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
...
...
@@ -2043,15 +2112,34 @@ static ir_node *gen_Conv(ir_node *node)
ir_mode
*
dst_mode
=
get_irn_mode
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
if
(
src_mode
==
dst_mode
)
return
be_transform_node
(
op
);
int
src_bits
=
get_mode_size_bits
(
src_mode
);
int
dst_bits
=
get_mode_size_bits
(
dst_mode
);
/* ad-hoc assumption until libfirm has vector modes:
* we assume 128bit modes are two packed doubles. */
if
(
dst_bits
==
128
)
{
/* int -> 2xdouble */
assert
(
get_mode_arithmetic
(
src_mode
)
==
irma_twos_complement
);
assert
(
src_bits
==
64
);
assert
(
dst_mode
==
amd64_mode_xmm
);
return
create_movq
(
dbgi
,
block
,
op
);
}
else
if
(
src_bits
==
128
)
{
/* 2xdouble -> float */
assert
(
src_mode
==
amd64_mode_xmm
);
assert
(
mode_is_float
(
dst_mode
));
if
(
dst_bits
==
32
)
{
return
create_cvtsd2ss
(
dbgi
,
block
,
op
);
}
else
if
(
dst_bits
==
64
)
{
/* this is a NOP */
return
be_transform_node
(
op
);
}
else
{
panic
(
"amd64: can't transform %+F"
,
node
);
}
}
bool
src_float
=
mode_is_float
(
src_mode
);
bool
dst_float
=
mode_is_float
(
dst_mode
);
bool
is_gp
=
!
src_float
&&
!
dst_float
;
int
src_bits
=
get_mode_size_bits
(
src_mode
);
int
dst_bits
=
get_mode_size_bits
(
dst_mode
);
ir_mode
*
min_mode
;
if
(
src_bits
<
dst_bits
)
{
min_mode
=
src_mode
;
...
...
@@ -2099,8 +2187,7 @@ static ir_node *gen_Conv(ir_node *node)
res
=
new_r_Proj
(
conv
,
amd64_mode_xmm
,
pn_amd64_CvtSS2SD_res
);
}
else
{
conv
=
new_bd_amd64_CvtSD2SS
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
in
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_F
,
pn_amd64_CvtSD2SS_res
);
}
reqs
=
xmm_reqs
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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