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
c5223ac1
Commit
c5223ac1
authored
Aug 14, 2015
by
Matthias Braun
Browse files
x86_x87: Move x87 node attributes into an own struct
parent
f08557a2
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_emitter.c
View file @
c5223ac1
...
...
@@ -470,8 +470,8 @@ end_of_mods:
case
'F'
:
if
(
get_ia32_op_type
(
node
)
==
ia32_Normal
)
{
ia32_x87_attr_t
const
*
const
attr
=
get_ia32_x87_attr_const
(
node
);
char
const
*
const
fmt
=
attr
->
res_in_reg
?
"%%st, %%%s"
:
"%%%s, %%st"
;
be_emit_irprintf
(
fmt
,
attr
->
reg
->
name
);
char
const
*
const
fmt
=
attr
->
x87
.
res_in_reg
?
"%%st, %%%s"
:
"%%%s, %%st"
;
be_emit_irprintf
(
fmt
,
attr
->
x87
.
reg
->
name
);
break
;
}
else
{
goto
emit_AM
;
...
...
@@ -547,7 +547,7 @@ destination_operand:
ia32_emit_x87_mode_suffix
(
node
);
}
else
if
(
*
fmt
==
'P'
)
{
ia32_x87_attr_t
const
*
const
attr
=
get_ia32_x87_attr_const
(
node
);
if
(
attr
->
pop
)
if
(
attr
->
x87
.
pop
)
be_emit_char
(
'p'
);
}
else
if
(
*
fmt
==
'R'
)
{
/* NOTE: Work around a gas quirk for non-commutative operations if the
...
...
@@ -570,7 +570,7 @@ destination_operand:
ia32_emit_xmm_mode_suffix
(
node
);
}
else
if
(
*
fmt
==
'0'
)
{
be_emit_char
(
'%'
);
be_emit_string
(
get_ia32_x87_attr_const
(
node
)
->
reg
->
name
);
be_emit_string
(
get_ia32_x87_attr_const
(
node
)
->
x87
.
reg
->
name
);
}
else
{
goto
unknown
;
}
...
...
@@ -2784,19 +2784,20 @@ static void bemit_copybi(const ir_node *node)
static
void
bemit_fbinop
(
ir_node
const
*
const
node
,
unsigned
const
op_fwd
,
unsigned
const
op_rev
)
{
ia32_x87_attr_t
const
*
const
attr
=
get_ia32_x87_attr_const
(
node
);
x87_attr_t
const
*
const
x87
=
&
attr
->
x87
;
unsigned
const
op
=
attr
->
attr
.
ins_permuted
?
op_rev
:
op_fwd
;
if
(
get_ia32_op_type
(
node
)
==
ia32_Normal
)
{
assert
(
!
attr
->
pop
||
attr
->
res_in_reg
);
assert
(
!
x87
->
pop
||
x87
->
res_in_reg
);
unsigned
char
op0
=
0xD8
;
if
(
attr
->
res_in_reg
)
op0
|=
0x04
;
if
(
attr
->
pop
)
op0
|=
0x02
;
if
(
x87
->
res_in_reg
)
op0
|=
0x04
;
if
(
x87
->
pop
)
op0
|=
0x02
;
bemit8
(
op0
);
bemit_modru
(
attr
->
reg
,
op
);
bemit_modru
(
attr
->
x87
.
reg
,
op
);
}
else
{
assert
(
!
attr
->
reg
);
assert
(
!
attr
->
pop
);
assert
(
!
x87
->
reg
);
assert
(
!
x87
->
pop
);
unsigned
const
size
=
get_mode_size_bits
(
get_ia32_ls_mode
(
node
));
bemit8
(
size
==
32
?
0xD8
:
0xDC
);
...
...
@@ -2807,7 +2808,7 @@ static void bemit_fbinop(ir_node const *const node, unsigned const op_fwd, unsig
static
void
bemit_fop_reg
(
ir_node
const
*
const
node
,
unsigned
char
const
op0
,
unsigned
char
const
op1
)
{
bemit8
(
op0
);
bemit8
(
op1
+
get_ia32_x87_attr_const
(
node
)
->
reg
->
encoding
);
bemit8
(
op1
+
get_ia32_x87_attr_const
(
node
)
->
x87
.
reg
->
encoding
);
}
static
void
bemit_fabs
(
const
ir_node
*
node
)
...
...
@@ -2872,10 +2873,10 @@ static void bemit_fist(const ir_node *node)
case
64
:
bemit8
(
0xDF
);
op
=
6
;
break
;
// fistpll
default:
panic
(
"invalid mode size"
);
}
if
(
get_ia32_x87_attr_const
(
node
)
->
pop
)
if
(
get_ia32_x87_attr_const
(
node
)
->
x87
.
pop
)
++
op
;
// There is only a pop variant for 64 bit integer store.
assert
(
size
<
64
||
get_ia32_x87_attr_const
(
node
)
->
pop
);
assert
(
size
<
64
||
get_ia32_x87_attr_const
(
node
)
->
x87
.
pop
);
bemit_mod_am
(
op
,
node
);
}
...
...
@@ -2960,10 +2961,10 @@ static void bemit_fst(const ir_node *node)
case
96
:
bemit8
(
0xDB
);
op
=
6
;
break
;
// fstpt
default:
panic
(
"invalid mode size"
);
}
if
(
get_ia32_x87_attr_const
(
node
)
->
pop
)
if
(
get_ia32_x87_attr_const
(
node
)
->
x87
.
pop
)
++
op
;
// There is only a pop variant for long double store.
assert
(
size
<
80
||
get_ia32_x87_attr_const
(
node
)
->
pop
);
assert
(
size
<
80
||
get_ia32_x87_attr_const
(
node
)
->
x87
.
pop
);
bemit_mod_am
(
op
,
node
);
}
...
...
@@ -2995,15 +2996,15 @@ static void bemit_ftstfnstsw(const ir_node *node)
static
void
bemit_fucomi
(
const
ir_node
*
node
)
{
const
ia32_x87_attr_t
*
attr
=
get_ia32_x87_attr_const
(
node
);
bemit8
(
attr
->
pop
?
0xDF
:
0xDB
);
// fucom[p]i
bemit8
(
0xE8
+
attr
->
reg
->
encoding
);
bemit8
(
attr
->
x87
.
pop
?
0xDF
:
0xDB
);
// fucom[p]i
bemit8
(
0xE8
+
attr
->
x87
.
reg
->
encoding
);
}
static
void
bemit_fucomfnstsw
(
const
ir_node
*
node
)
{
const
ia32_x87_attr_t
*
attr
=
get_ia32_x87_attr_const
(
node
);
bemit8
(
0xDD
);
// fucom[p]
bemit8
((
attr
->
pop
?
0xE8
:
0xE0
)
+
attr
->
reg
->
encoding
);
bemit8
((
attr
->
x87
.
pop
?
0xE8
:
0xE0
)
+
attr
->
x87
.
reg
->
encoding
);
bemit_fnstsw
();
}
...
...
ir/be/ia32/ia32_new_nodes.c
View file @
c5223ac1
...
...
@@ -242,9 +242,9 @@ static void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
fprintf
(
F
,
"size = %u
\n
"
,
get_ia32_copyb_size
(
n
));
}
else
if
(
has_ia32_x87_attr
(
n
))
{
ia32_x87_attr_t
const
*
const
attr
=
get_ia32_x87_attr_const
(
n
);
fprintf
(
F
,
"explicit operand = %s
\n
"
,
be_dump_reg_name
(
attr
->
reg
));
fprintf
(
F
,
"result to explicit operand = %s
\n
"
,
be_dump_yesno
(
attr
->
res_in_reg
));
fprintf
(
F
,
"pop = %s
\n
"
,
be_dump_yesno
(
attr
->
pop
));
fprintf
(
F
,
"explicit operand = %s
\n
"
,
be_dump_reg_name
(
attr
->
x87
.
reg
));
fprintf
(
F
,
"result to explicit operand = %s
\n
"
,
be_dump_yesno
(
attr
->
x87
.
res_in_reg
));
fprintf
(
F
,
"pop = %s
\n
"
,
be_dump_yesno
(
attr
->
x87
.
pop
));
}
fprintf
(
F
,
"commutative = %s
\n
"
,
be_dump_yesno
(
is_ia32_commutative
(
n
)));
...
...
ir/be/ia32/ia32_nodes_attr.h
View file @
c5223ac1
...
...
@@ -13,8 +13,9 @@
#include "firm_types.h"
#include "irnode_t.h"
#include "x86_cc.h"
#include "x86_asm.h"
#include "x86_cc.h"
#include "x86_x87.h"
typedef
enum
{
ia32_Normal
,
...
...
@@ -173,10 +174,8 @@ struct ia32_immediate_attr_t {
*/
typedef
struct
ia32_x87_attr_t
ia32_x87_attr_t
;
struct
ia32_x87_attr_t
{
ia32_attr_t
attr
;
/**< the generic attribute */
arch_register_t
const
*
reg
;
/**< The explicit register operand. */
bool
res_in_reg
;
/**< True if the result is in the explicit register operand, %st0 otherwise. */
bool
pop
;
/**< Emit a pop suffix. */
ia32_attr_t
attr
;
/**< the generic attribute */
x87_attr_t
x87
;
};
/**
...
...
ir/be/ia32/ia32_spec.pl
View file @
c5223ac1
...
...
@@ -311,7 +311,7 @@ my $fpopop = {
attrs_equal
=>
"
attrs_equal_false
",
attr_type
=>
"
ia32_x87_attr_t
",
attr
=>
"
const arch_register_t *reg
",
init
=>
"
attr->reg = reg;
",
init
=>
"
attr->
x87.
reg = reg;
",
};
my
$xbinop
=
{
...
...
@@ -1777,7 +1777,7 @@ fxch => {
emit
=>
"
fxch %F0
",
attr_type
=>
"
ia32_x87_attr_t
",
attr
=>
"
const arch_register_t *reg
",
init
=>
"
attr->reg = reg;
",
init
=>
"
attr->
x87.
reg = reg;
",
latency
=>
1
,
},
...
...
@@ -1789,7 +1789,7 @@ fdup => {
emit
=>
"
fld %F0
",
attr_type
=>
"
ia32_x87_attr_t
",
attr
=>
"
const arch_register_t *reg
",
init
=>
"
attr->reg = reg;
",
init
=>
"
attr->
x87.
reg = reg;
",
mode
=>
$mode_fp87
,
latency
=>
1
,
},
...
...
ir/be/ia32/x86_x87.c
View file @
c5223ac1
...
...
@@ -731,10 +731,10 @@ static void sim_binop(x87_state *const state, ir_node *const n)
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
->
reg
=
get_st_reg
(
op_reg
);
attr
->
x87
.
reg
=
get_st_reg
(
op_reg
);
attr
->
attr
.
ins_permuted
=
reverse
;
attr
->
res_in_reg
=
to_reg
;
attr
->
pop
=
pop
;
attr
->
x87
.
res_in_reg
=
to_reg
;
attr
->
x87
.
pop
=
pop
;
x87_set_st
(
state
,
get_result_node
(
n
),
to_reg
?
op_reg
:
0
);
if
(
pop
)
...
...
@@ -743,12 +743,13 @@ static void sim_binop(x87_state *const state, ir_node *const n)
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
=
attr
->
reg
?
attr
->
reg
->
name
:
"[AM]"
;
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
o
=
attr
->
res_in_reg
?
reg
:
st0
;
char
const
*
const
pop
=
attr
->
pop
?
" [pop]"
:
""
;
char
const
*
const
o
=
x87
->
res_in_reg
?
reg
:
st0
;
char
const
*
const
pop
=
x87
->
pop
?
" [pop]"
:
""
;
DB
((
dbg
,
LEVEL_1
,
"<<< %s %s, %s -> %s%s
\n
"
,
get_irn_opname
(
n
),
l
,
r
,
o
,
pop
));
)
}
...
...
@@ -863,7 +864,7 @@ do_pop:
be_ssa_construction_destroy
(
&
env
);
}
get_ia32_x87_attr
(
n
)
->
pop
=
true
;
get_ia32_x87_attr
(
n
)
->
x87
.
pop
=
true
;
}
else
{
/* we can only store the tos to memory */
move_to_tos
(
state
,
n
,
val
);
...
...
@@ -943,7 +944,7 @@ static void sim_Fucom(x87_state *state, ir_node *n)
if
(
!
op1_live_after
)
{
x87_pop
(
state
);
ia32_x87_attr_t
*
const
attr
=
get_ia32_x87_attr
(
n
);
attr
->
pop
=
true
;
attr
->
x87
.
pop
=
true
;
}
}
else
{
bool
reverse
;
...
...
@@ -1001,9 +1002,9 @@ static void sim_Fucom(x87_state *state, ir_node *n)
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
->
reg
=
get_st_reg
(
op_reg
);
attr
->
x87
.
reg
=
get_st_reg
(
op_reg
);
attr
->
attr
.
ins_permuted
^=
reverse
;
attr
->
pop
=
pops
!=
0
;
attr
->
x87
.
pop
=
pops
!=
0
;
if
(
pops
!=
0
)
{
x87_pop
(
state
);
...
...
@@ -1020,11 +1021,12 @@ static void sim_Fucom(x87_state *state, ir_node *n)
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
=
attr
->
reg
?
attr
->
reg
->
name
:
"[AM]"
;
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
=
attr
->
pop
?
" [pop]"
:
""
;
char
const
*
const
pop
=
x87
->
pop
?
" [pop]"
:
""
;
DB
((
dbg
,
LEVEL_1
,
"<<< %s %s, %s%s
\n
"
,
get_irn_opname
(
n
),
l
,
r
,
pop
));
)
}
...
...
ir/be/ia32/x86_x87.h
View file @
c5223ac1
...
...
@@ -12,9 +12,18 @@
#ifndef FIRM_BE_IA32_X86_X87_H
#define FIRM_BE_IA32_X86_X87_H
#include <stdbool.h>
#include "be_types.h"
#include "firm_types.h"
/** Attributes for x87 nodes. */
typedef
struct
x87_attr_t
{
arch_register_t
const
*
reg
;
/**< The explicit register operand. */
/** True if result is in the explicit register operand, %st0 otherwise. */
bool
res_in_reg
;
bool
pop
;
/**< Emit a pop suffix. */
}
x87_attr_t
;
/**
* Run a simulation and fix all virtual instructions for a graph.
* Replaces all virtual floating point instructions and registers
...
...
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