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
219b0d16
Commit
219b0d16
authored
May 27, 2014
by
Tobias Rapp
Browse files
amd64: Add and use Conv operations
parent
18bd0eb6
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_spec.pl
View file @
219b0d16
...
...
@@ -494,6 +494,17 @@ xAdds => {
# mode => $mode_xmm,
},
xDivs
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
outs
=>
[
"
res_div
",
"
none
",
"
M
"
],
arity
=>
"
variable
",
attr_type
=>
"
amd64_binop_addr_attr_t
",
attr
=>
"
const amd64_binop_addr_attr_t *attr_init
",
emit
=>
"
divs%MX %AM
",
},
xMovs
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
...
...
@@ -515,17 +526,6 @@ xMuls => {
emit
=>
"
muls%MX %AM
",
},
xDivs
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
outs
=>
[
"
res_div
",
"
none
",
"
M
"
],
arity
=>
"
variable
",
attr_type
=>
"
amd64_binop_addr_attr_t
",
attr
=>
"
const amd64_binop_addr_attr_t *attr_init
",
emit
=>
"
divs%MX %AM
",
},
xStores
=>
{
op_flags
=>
[
"
uses_memory
"
],
state
=>
"
exc_pinned
",
...
...
@@ -560,4 +560,66 @@ xXorp0 => {
mode
=>
$mode_xmm
,
},
# Conversion operations
CvtSS2SD
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtss2sd %AM, %^D0
",
},
CvtSD2SS
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtsd2ss %AM, %^D0
",
},
CvtSD2SI
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
gp
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtsd2si %AM, %D0
",
},
CvtSS2SI
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
gp
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtss2si %AM, %D0
",
},
CvtSI2SS
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtsi2ss %AM, %^D0
",
},
CvtSI2SD
=>
{
state
=>
"
exc_pinned
",
reg_req
=>
{
out
=>
[
"
xmm
",
"
none
",
"
none
"
]
},
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
",
emit
=>
"
cvtsi2sd %AM, %^D0
",
},
);
ir/be/amd64/amd64_transform.c
View file @
219b0d16
...
...
@@ -220,6 +220,10 @@ static const arch_register_req_t *reg_reqs[] = {
&
amd64_requirement_gp
,
};
static
const
arch_register_req_t
*
xmm_reqs
[]
=
{
&
amd64_requirement_xmm
,
};
static
const
arch_register_req_t
*
reg_rcx_reqs
[]
=
{
&
amd64_requirement_gp
,
&
amd64_requirement_rcx
,
...
...
@@ -1877,11 +1881,10 @@ static ir_node *gen_Conv(ir_node *node)
if
(
src_mode
==
dst_mode
)
return
be_transform_node
(
op
);
/* TODO: implement float */
if
(
mode_is_float
(
src_mode
)
||
mode_is_float
(
dst_mode
)
)
panic
(
"float not supported yet"
)
;
bool
src_float
=
mode_is_float
(
src_mode
);
bool
dst_float
=
mode_is_float
(
dst_mode
)
;
bool
is_gp
=
!
src_float
&&
!
dst_float
;
/* complete in gp registers */
int
src_bits
=
get_mode_size_bits
(
src_mode
);
int
dst_bits
=
get_mode_size_bits
(
dst_mode
);
ir_mode
*
min_mode
;
...
...
@@ -1890,12 +1893,15 @@ static ir_node *gen_Conv(ir_node *node)
min_mode
=
src_mode
;
}
else
if
(
src_bits
>
dst_bits
)
{
min_mode
=
dst_mode
;
}
else
{
}
else
if
((
src_float
&&
dst_float
)
||
is_gp
)
{
/* skip unnecessary conv */
return
be_transform_node
(
op
);
}
else
{
/* src_bits == dst_bits, but one is float the other integer*/
min_mode
=
src_mode
;
}
if
(
be_upper_bits_clean
(
op
,
min_mode
))
if
(
is_gp
&&
be_upper_bits_clean
(
op
,
min_mode
))
return
be_transform_node
(
op
);
amd64_addr_t
addr
;
...
...
@@ -1904,18 +1910,75 @@ static ir_node *gen_Conv(ir_node *node)
ir_node
*
new_op
=
be_transform_node
(
op
);
ir_node
*
in
[
1
]
=
{
new_op
};
ir_node
*
mo
v
;
ir_node
*
con
v
;
ir_node
*
res
;
if
(
!
mode_is_signed
(
min_mode
)
||
get_mode_size_bits
(
min_mode
)
==
64
)
{
mov
=
new_bd_amd64_Mov
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
mov
,
mode_gp
,
pn_amd64_Mov_res
);
const
arch_register_req_t
**
reqs
;
if
(
src_float
&&
dst_float
)
{
/* fp conv */
if
(
src_bits
<
dst_bits
)
{
conv
=
new_bd_amd64_CvtSS2SD
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_D
,
pn_amd64_CvtSS2SD_res
);
}
else
{
conv
=
new_bd_amd64_CvtSD2SS
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_F
,
pn_amd64_CvtSD2SS_res
);
}
reqs
=
xmm_reqs
;
}
else
if
(
src_float
&&
!
dst_float
)
{
/* fp to integer */
if
(
src_bits
<
64
)
{
conv
=
new_bd_amd64_CvtSS2SI
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
}
else
{
conv
=
new_bd_amd64_CvtSD2SI
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
}
assert
((
long
)
pn_amd64_CvtSS2SI_res
==
(
long
)
pn_amd64_CvtSD2SI_res
);
res
=
new_r_Proj
(
conv
,
mode_gp
,
pn_amd64_CvtSS2SI_res
);
reqs
=
xmm_reqs
;
}
else
if
(
!
src_float
&&
dst_float
)
{
/* integer to fp */
if
(
dst_bits
<
64
)
{
conv
=
new_bd_amd64_CvtSI2SS
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_F
,
pn_amd64_CvtSI2SS_res
);
}
else
{
conv
=
new_bd_amd64_CvtSI2SD
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_D
,
pn_amd64_CvtSI2SD_res
);
}
reqs
=
reg_reqs
;
}
else
{
mov
=
new_bd_amd64_Movs
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
mov
,
mode_gp
,
pn_amd64_Movs_res
);
/* integer conv */
if
(
!
mode_is_signed
(
min_mode
)
||
get_mode_size_bits
(
min_mode
)
==
64
)
{
conv
=
new_bd_amd64_Mov
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_gp
,
pn_amd64_Mov_res
);
}
else
{
conv
=
new_bd_amd64_Movs
(
dbgi
,
block
,
ARRAY_SIZE
(
in
),
in
,
insn_mode
,
AMD64_OP_REG
,
addr
);
res
=
new_r_Proj
(
conv
,
mode_gp
,
pn_amd64_Movs_res
);
}
reqs
=
reg_reqs
;
}
arch_set_irn_register_reqs_in
(
mov
,
reg_reqs
);
arch_set_irn_register_reqs_in
(
conv
,
reqs
);
return
res
;
}
...
...
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