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
e2cb53cc
Commit
e2cb53cc
authored
Aug 15, 2014
by
Matthias Braun
Browse files
ia32: force flag users to have a condcode attribute
This also allows to cleanup the finish neg/add carry flag fix code a big.
parent
d1564f4d
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_finish.c
View file @
e2cb53cc
...
...
@@ -32,6 +32,15 @@
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
=
NULL
;)
static
bool
reads_carry
(
x86_condition_code_t
code
)
{
x86_condition_code_t
c2
=
code
&
~
x86_cc_negated
;
return
c2
==
x86_cc_below
||
c2
==
x86_cc_below_equal
||
c2
==
x86_cc_float_below
||
c2
==
x86_cc_float_below_equal
||
c2
==
x86_cc_float_unordered_below_equal
||
c2
==
x86_cc_float_unordered_below
;
}
/**
* Transforms a Sub or xSub into Neg--Add iff OUT_REG != SRC1_REG && OUT_REG == SRC2_REG.
* THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
...
...
@@ -84,10 +93,10 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn)
res
=
new_bd_ia32_xAdd
(
dbgi
,
block
,
noreg
,
noreg
,
nomem
,
res
,
in1
);
set_ia32_ls_mode
(
res
,
get_ia32_ls_mode
(
irn
));
}
else
{
ir_node
*
flags_proj
=
NULL
;
bool
only_needs_value
=
true
;
ir_node
*
flags_proj
=
NULL
;
bool
needs_carry
=
false
;
/** See if someone is interested in a correctly set carry flag */
if
(
get_irn_mode
(
irn
)
==
mode_T
)
{
/* collect the Proj uses */
foreach_out_edge
(
irn
,
edge
)
{
ir_node
*
proj
=
get_edge_src_irn
(
edge
);
long
pn
=
get_Proj_proj
(
proj
);
...
...
@@ -96,18 +105,9 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn)
flags_proj
=
proj
;
foreach_out_edge
(
flags_proj
,
edge
)
{
ir_node
*
user
=
get_edge_src_irn
(
edge
);
if
(
is_ia32_CMovcc
(
user
)
||
is_ia32_Jcc
(
user
)
||
is_ia32_Setcc
(
user
)
||
is_ia32_SetccMem
(
user
))
{
/* If the users only need the sign/zero flags,
* we just have to compute the right value. */
x86_condition_code_t
cc
=
get_ia32_condcode
(
user
);
if
(
cc
!=
x86_cc_equal
&&
cc
!=
x86_cc_not_equal
&&
cc
!=
x86_cc_sign
&&
cc
!=
x86_cc_not_sign
)
{
only_needs_value
=
false
;
break
;
}
}
else
{
only_needs_value
=
false
;
x86_condition_code_t
cc
=
get_ia32_condcode
(
user
);
if
(
reads_carry
(
cc
))
{
needs_carry
=
true
;
break
;
}
}
...
...
@@ -122,7 +122,7 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn)
carry
=
get_irn_n
(
irn
,
n_ia32_Sbb_eflags
);
carry
=
new_bd_ia32_Cmc
(
dbgi
,
block
,
carry
);
goto
carry
;
}
else
if
(
flags_proj
!=
NULL
&&
!
only_
needs_
value
)
{
}
else
if
(
flags_proj
!=
NULL
&&
needs_
carry
)
{
/*
* ARG, the above technique does NOT set the flags right.
* So, we must produce the following code:
...
...
ir/be/ia32/ia32_new_nodes.c
View file @
e2cb53cc
...
...
@@ -75,6 +75,13 @@ static const char *condition_code_name(x86_condition_code_t cc)
}
}
static
bool
has_ia32_condcode_attr
(
const
ir_node
*
node
)
{
return
is_ia32_Setcc
(
node
)
||
is_ia32_SetccMem
(
node
)
||
is_ia32_CMovcc
(
node
)
||
is_ia32_Jcc
(
node
)
||
is_ia32_Adc
(
node
)
||
is_ia32_Sbb
(
node
)
||
is_ia32_Sbb0
(
node
)
||
is_ia32_Cmc
(
node
);
}
/**
* Dumper interface for dumping ia32 nodes in vcg.
* @param n the node to dump
...
...
@@ -196,8 +203,7 @@ static void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
fprintf
(
F
,
"AM scale = %u
\n
"
,
get_ia32_am_scale
(
n
));
/* dump pn code */
if
(
is_ia32_CMovcc
(
n
)
||
is_ia32_Jcc
(
n
)
||
is_ia32_Setcc
(
n
)
||
is_ia32_SetccMem
(
n
))
{
if
(
has_ia32_condcode_attr
(
n
))
{
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
n
);
const
char
*
cc_name
=
condition_code_name
(
get_ia32_condcode
(
n
));
if
(
cc_name
)
{
...
...
@@ -299,6 +305,7 @@ const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
ia32_condcode_attr_t
*
get_ia32_condcode_attr
(
ir_node
*
node
)
{
assert
(
has_ia32_condcode_attr
(
node
));
ia32_attr_t
*
attr
=
get_ia32_attr
(
node
);
ia32_condcode_attr_t
*
cc_attr
=
CAST_IA32_ATTR
(
ia32_condcode_attr_t
,
attr
);
...
...
@@ -307,6 +314,7 @@ ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
const
ia32_condcode_attr_t
*
get_ia32_condcode_attr_const
(
const
ir_node
*
node
)
{
assert
(
has_ia32_condcode_attr
(
node
));
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
node
);
const
ia32_condcode_attr_t
*
cc_attr
=
CONST_CAST_IA32_ATTR
(
ia32_condcode_attr_t
,
attr
);
...
...
ir/be/ia32/ia32_spec.pl
View file @
e2cb53cc
...
...
@@ -243,6 +243,8 @@ Adc => {
out
=>
[
"
in_r4 in_r5
",
"
flags
",
"
none
"
]
},
ins
=>
[
"
base
",
"
index
",
"
mem
",
"
left
",
"
right
",
"
eflags
"
],
outs
=>
[
"
res
",
"
flags
",
"
M
"
],
attr_type
=>
"
ia32_condcode_attr_t
",
fixed
=>
"
x86_condition_code_t condition_code = x86_cc_carry;
",
emit
=>
"
adc%M %B
",
am
=>
"
source,binary
",
latency
=>
1
,
...
...
@@ -440,6 +442,8 @@ Sbb => {
out
=>
[
"
in_r4
",
"
flags
",
"
none
"
]
},
ins
=>
[
"
base
",
"
index
",
"
mem
",
"
minuend
",
"
subtrahend
",
"
eflags
"
],
outs
=>
[
"
res
",
"
flags
",
"
M
"
],
attr_type
=>
"
ia32_condcode_attr_t
",
fixed
=>
"
x86_condition_code_t condition_code = x86_cc_carry;
",
am
=>
"
source,binary
",
emit
=>
"
sbb%M %B
",
latency
=>
1
,
...
...
@@ -452,6 +456,8 @@ Sbb0 => {
# irn_flags => [ "rematerializable" ],
reg_req
=>
{
in
=>
[
"
flags
"
],
out
=>
[
"
gp
",
"
flags
"
]
},
outs
=>
[
"
res
",
"
flags
"
],
attr_type
=>
"
ia32_condcode_attr_t
",
fixed
=>
"
x86_condition_code_t condition_code = x86_cc_carry;
",
emit
=>
"
sbb%M %D0, %D0
",
latency
=>
1
,
mode
=>
$mode_gp
,
...
...
@@ -754,6 +760,8 @@ NotMem => {
Cmc
=>
{
reg_req
=>
{
in
=>
[
"
flags
"
],
out
=>
[
"
flags
"
]
},
attr_type
=>
"
ia32_condcode_attr_t
",
fixed
=>
"
x86_condition_code_t condition_code = x86_cc_carry;
",
emit
=>
"
cmc
",
latency
=>
1
,
mode
=>
$mode_flags
,
...
...
ir/be/ia32/x86_cc.h
View file @
e2cb53cc
...
...
@@ -7,6 +7,7 @@ typedef enum x86_condition_code_t {
x86_cc_overflow
=
0x00
,
/**< OF=1 */
x86_cc_below
=
0x02
,
/**< CF=1 */
x86_cc_carry
=
x86_cc_below
,
x86_cc_equal
=
0x04
,
/**< ZF=1 */
x86_cc_below_equal
=
0x06
,
/**< ZF=1 or CF=1 */
x86_cc_sign
=
0x08
,
/**< SF=1 */
...
...
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