Commit f8783b28 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Merge the pop and non-pop variants of x87 store operations.

Let a flag and the emitter handle printing the pop variant.
parent 27521ff6
......@@ -1134,7 +1134,6 @@ need_stackent:
case iro_ia32_Store8Bit:
case iro_ia32_Store:
case iro_ia32_fst:
case iro_ia32_fstp:
case iro_ia32_vfist:
case iro_ia32_vfisttp:
case iro_ia32_vfst:
......
......@@ -3353,42 +3353,19 @@ static void bemit_fild(const ir_node *node)
static void bemit_fist(const ir_node *node)
{
switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
case 16:
bemit8(0xDF); // fists
break;
case 32:
bemit8(0xDB); // fistl
break;
default:
panic("invalid mode size");
}
bemit_mod_am(2, node);
}
static void bemit_fistp(const ir_node *node)
{
switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
case 16:
bemit8(0xDF); // fistps
bemit_mod_am(3, node);
return;
case 32:
bemit8(0xDB); // fistpl
bemit_mod_am(3, node);
return;
case 64:
bemit8(0xDF); // fistpll
bemit_mod_am(7, node);
return;
default:
panic("invalid mode size");
unsigned op;
unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
switch (size) {
case 16: bemit8(0xDF); op = 2; break; // fist[p]s
case 32: bemit8(0xDB); op = 2; break; // fist[p]l
case 64: bemit8(0xDF); op = 6; break; // fistpll
default: panic("invalid mode size");
}
if (get_ia32_x87_attr_const(node)->pop)
++op;
// There is only a pop variant for 64 bit integer store.
assert(size < 64 || get_ia32_x87_attr_const(node)->pop);
bemit_mod_am(op, node);
}
static void bemit_fisttp(ir_node const *const node)
......@@ -3468,43 +3445,20 @@ static void bemit_fpushcopy(const ir_node *node)
static void bemit_fst(const ir_node *node)
{
switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
case 32:
bemit8(0xD9); // fsts
break;
case 64:
bemit8(0xDD); // fstl
break;
default:
panic("invalid mode size");
}
bemit_mod_am(2, node);
}
static void bemit_fstp(const ir_node *node)
{
switch (get_mode_size_bits(get_ia32_ls_mode(node))) {
case 32:
bemit8(0xD9); // fstps
bemit_mod_am(3, node);
return;
case 64:
bemit8(0xDD); // fstpl
bemit_mod_am(3, node);
return;
case 80:
case 96:
bemit8(0xDB); // fstpt
bemit_mod_am(7, node);
return;
default:
panic("invalid mode size");
unsigned op;
unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
switch (size) {
case 32: bemit8(0xD9); op = 2; break; // fst[p]s
case 64: bemit8(0xDD); op = 2; break; // fst[p]l
case 80:
case 96: bemit8(0xDB); op = 6; break; // fstpt
default: panic("invalid mode size");
}
if (get_ia32_x87_attr_const(node)->pop)
++op;
// There is only a pop variant for long double store.
assert(size < 80 || get_ia32_x87_attr_const(node)->pop);
bemit_mod_am(op, node);
}
static void bemit_fsub(const ir_node *node)
......@@ -3700,7 +3654,6 @@ static void ia32_register_binary_emitters(void)
register_emitter(op_ia32_ffreep, bemit_ffreep);
register_emitter(op_ia32_fild, bemit_fild);
register_emitter(op_ia32_fist, bemit_fist);
register_emitter(op_ia32_fistp, bemit_fistp);
register_emitter(op_ia32_fisttp, bemit_fisttp);
register_emitter(op_ia32_fld, bemit_fld);
register_emitter(op_ia32_fld1, bemit_fld1);
......@@ -3710,7 +3663,6 @@ static void ia32_register_binary_emitters(void)
register_emitter(op_ia32_fpush, bemit_fpush);
register_emitter(op_ia32_fpushCopy, bemit_fpushcopy);
register_emitter(op_ia32_fst, bemit_fst);
register_emitter(op_ia32_fstp, bemit_fstp);
register_emitter(op_ia32_fsub, bemit_fsub);
register_emitter(op_ia32_fxch, bemit_fxch);
......
......@@ -2338,17 +2338,7 @@ fld => {
fst => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
emit => 'fst%FM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
latency => 2,
constructors => {},
},
fstp => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
emit => 'fstp%FM %AM',
emit => 'fst%FP%FM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
latency => 2,
......@@ -2365,16 +2355,7 @@ fild => {
fist => {
state => "exc_pinned",
emit => 'fist%FM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
latency => 2,
constructors => {},
},
fistp => {
state => "exc_pinned",
emit => 'fistp%FM %AM',
emit => 'fist%FP%FM %AM',
mode => "mode_M",
attr_type => "ia32_x87_attr_t",
latency => 2,
......
......@@ -980,14 +980,14 @@ static void collect_and_rewire_users(ir_node *store, ir_node *old_val, ir_node *
* @param state the x87 state
* @param n the node that should be simulated (and patched)
* @param op the x87 store opcode
* @param op_p the x87 store and pop opcode
*/
static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
static int sim_store(x87_state *state, ir_node *n, ir_op *op)
{
ir_node *const val = get_irn_n(n, n_ia32_vfst_val);
arch_register_t const *const op2 = x87_get_irn_register(val);
DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2)));
bool do_pop = false;
int insn = NO_NODE_ADDED;
int const op2_reg_idx = arch_register_get_index(op2);
int const op2_idx = x87_on_stack(state, op2_reg_idx);
......@@ -1006,12 +1006,12 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
if (x87_get_depth(state) < N_ia32_st_REGS) {
/* ok, we have a free register: push + fstp */
x87_create_fpush(state, n, op2_idx, REG_VFP_VFP_NOREG, val);
x87_pop(state);
x87_patch_insn(n, op_p);
x87_patch_insn(n, op);
do_pop = true;
} else {
/* stack full here: need fstp + load */
x87_pop(state);
x87_patch_insn(n, op_p);
x87_patch_insn(n, op);
do_pop = true;
ir_node *const block = get_nodes_block(n);
ir_node *const mem = get_irn_Proj_for_mode(n, mode_M);
......@@ -1054,11 +1054,15 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
if (op2_idx != 0)
x87_create_fxch(state, n, op2_idx);
x87_pop(state);
x87_patch_insn(n, op_p);
x87_patch_insn(n, op);
do_pop = true;
}
if (do_pop)
x87_pop(state);
ia32_x87_attr_t *const attr = get_ia32_x87_attr(n);
attr->pop = do_pop;
attr->x87[1] = get_st_reg(0);
DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(attr->x87[1])));
......@@ -1082,7 +1086,7 @@ static int sim_##op(x87_state *state, ir_node *n) { \
#define GEN_STORE(op) \
static int sim_##op(x87_state *state, ir_node *n) { \
return sim_store(state, n, op_ia32_##op, op_ia32_##op##p); \
return sim_store(state, n, op_ia32_##op); \
}
/* all stubs */
......
Supports Markdown
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