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
9e6078ff
Commit
9e6078ff
authored
Sep 20, 2015
by
Matthias Braun
Browse files
ia32: Fucomi has no address mode so no need to handle that in x87 sim
parent
b6825341
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/x86_x87.c
View file @
9e6078ff
...
...
@@ -961,95 +961,84 @@ static void sim_Fucom(x87_state *state, ir_node *n)
DB
((
dbg
,
LEVEL_1
,
"Stack before: "
));
DEBUG_ONLY
(
x87_dump_stack
(
state
);)
if
(
is_ia32_NoReg_FP
(
op2
))
{
/* Second operand is an address mode. */
move_to_tos
(
state
,
n
,
op1
);
/* Pop first operand, if it is dead. */
if
(
!
op1_live_after
)
{
x87_pop
(
state
);
x87
.
get_x87_attr
(
n
)
->
pop
=
true
;
}
}
else
{
bool
reverse
;
unsigned
pops
=
0
;
bool
const
op2_live_after
=
is_fp_live
(
op2
,
live
);
if
(
op1_live_after
)
{
if
(
op2_live_after
)
{
/* Both operands are live. */
if
(
is_at_pos
(
state
,
op2
,
0
))
{
reverse
=
true
;
}
else
{
/* Move the first one to tos. */
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
}
}
else
{
/* First live, second dead: Pop second. */
move_to_tos
(
state
,
n
,
op2
);
bool
reverse
;
unsigned
pops
=
0
;
bool
const
op2_live_after
=
is_fp_live
(
op2
,
live
);
if
(
op1_live_after
)
{
if
(
op2_live_after
)
{
/* Both operands are live. */
if
(
is_at_pos
(
state
,
op2
,
0
))
{
reverse
=
true
;
pops
=
1
;
}
else
{
/* Move the first one to tos. */
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
}
}
else
{
if
(
op2_live_after
)
{
/* First dead, Second live: Pop first. */
/* First live, second dead: Pop second. */
move_to_tos
(
state
,
n
,
op2
);
reverse
=
true
;
pops
=
1
;
}
}
else
{
if
(
op2_live_after
)
{
/* First dead, Second live: Pop first. */
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
pops
=
1
;
}
else
{
/* Both dead. */
if
(
op1
==
op2
)
{
/* Operands are identical: One pop. */
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
pops
=
1
;
}
else
{
/* Both dead.
*/
if
(
op1
==
op2
)
{
/* Operands are identical: One po
p. */
move_to_tos
(
state
,
n
,
op1
);
/* Both
operands are
dead.
* Move one operand to tos. Move the one not at
* pos 1, so we get a chance to use fucomp
p. */
if
(
is_at_pos
(
state
,
op1
,
0
))
{
reverse
=
false
;
pops
=
1
;
}
else
if
(
is_at_pos
(
state
,
op2
,
0
))
{
reverse
=
true
;
}
else
if
(
is_at_pos
(
state
,
op1
,
1
))
{
move_to_tos
(
state
,
n
,
op2
);
reverse
=
true
;
}
else
{
/* Both operands are dead.
* Move one operand to tos. Move the one not at
* pos 1, so we get a chance to use fucompp. */
if
(
is_at_pos
(
state
,
op1
,
0
))
{
reverse
=
false
;
}
else
if
(
is_at_pos
(
state
,
op2
,
0
))
{
reverse
=
true
;
}
else
if
(
is_at_pos
(
state
,
op1
,
1
))
{
move_to_tos
(
state
,
n
,
op2
);
reverse
=
true
;
}
else
{
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
}
pops
=
2
;
move_to_tos
(
state
,
n
,
op1
);
reverse
=
false
;
}
pops
=
2
;
}
}
}
unsigned
const
op_reg
=
x87_on_stack
(
state
,
reverse
?
op1
:
op2
);
/* Patch the operation. */
ia32_x87_attr_t
*
const
attr
=
get_ia32_x87_attr
(
n
);
attr
->
x87
.
reg
=
get_st_reg
(
op_reg
);
attr
->
x87
.
pop
=
pops
!=
0
;
attr
->
attr
.
ins_permuted
^=
reverse
;
if
(
pops
!=
0
)
{
x87_pop
(
state
);
if
(
pops
==
2
)
{
if
(
is_ia32_FucomFnstsw
(
n
)
&&
op_reg
==
1
)
{
set_irn_op
(
n
,
op_ia32_FucomppFnstsw
);
x87_pop
(
state
);
}
else
{
x87_create_fpop
(
state
,
n
,
op_reg
-
1
/* Due to prior pop. */
);
}
unsigned
const
op_reg
=
x87_on_stack
(
state
,
reverse
?
op1
:
op2
);
/* Patch the operation. */
ia32_x87_attr_t
*
const
attr
=
get_ia32_x87_attr
(
n
);
attr
->
x87
.
reg
=
get_st_reg
(
op_reg
);
attr
->
x87
.
pop
=
pops
!=
0
;
attr
->
attr
.
ins_permuted
^=
reverse
;
if
(
pops
!=
0
)
{
x87_pop
(
state
);
if
(
pops
==
2
)
{
if
(
is_ia32_FucomFnstsw
(
n
)
&&
op_reg
==
1
)
{
set_irn_op
(
n
,
op_ia32_FucomppFnstsw
);
x87_pop
(
state
);
}
else
{
x87_create_fpop
(
state
,
n
,
op_reg
-
1
/* Due to prior pop. */
);
}
}
}
DEBUG_ONLY
(
ia32_x87_attr_t
const
*
const
attr
=
get_ia32_x87_attr
(
n
);
x87_attr_t
const
*
const
x87
=
&
attr
->
x87
;
char
const
*
const
st0
=
get_st_reg
(
0
)
->
name
;
char
const
*
const
reg
=
x87
->
reg
?
x87
->
reg
->
name
:
"[AM]"
;
char
const
*
const
l
=
attr
->
attr
.
ins_permuted
?
reg
:
st0
;
char
const
*
const
r
=
!
attr
->
attr
.
ins_permuted
?
reg
:
st0
;
char
const
*
const
pop
=
x87
->
pop
?
" [pop]"
:
""
;
x87_attr_t
const
*
const
x87
=
&
attr
->
x87
;
char
const
*
const
st0
=
get_st_reg
(
0
)
->
name
;
char
const
*
const
reg
=
x87
->
reg
?
x87
->
reg
->
name
:
"[AM]"
;
char
const
*
const
l
=
attr
->
attr
.
ins_permuted
?
reg
:
st0
;
char
const
*
const
r
=
!
attr
->
attr
.
ins_permuted
?
reg
:
st0
;
char
const
*
const
pop
=
x87
->
pop
?
" [pop]"
:
""
;
DB
((
dbg
,
LEVEL_1
,
"<<< %s %s, %s%s
\n
"
,
get_irn_opname
(
n
),
l
,
r
,
pop
));
)
}
...
...
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