Commit c5223ac1 authored by Matthias Braun's avatar Matthias Braun
Browse files

x86_x87: Move x87 node attributes into an own struct

parent f08557a2
......@@ -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();
}
......
......@@ -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)));
......
......@@ -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,
......@@ -174,9 +175,7 @@ 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. */
x87_attr_t x87;
};
/**
......
......@@ -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,
},
......
......@@ -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));
)
}
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment