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

ia32: Cleanup in create_fpu_mode_reload() and create_fpu_mode_spill().

parent 712399b9
......@@ -17,6 +17,7 @@
#include "ia32_fpu.h"
#include "ia32_new_nodes.h"
#include "ia32_architecture.h"
#include "ia32_optimize.h"
#include "gen_ia32_regalloc_if.h"
#include "ircons.h"
......@@ -33,160 +34,115 @@
static ir_entity *fpcw_round = NULL;
static ir_entity *fpcw_truncate = NULL;
static ir_entity *create_ent(int value, const char *name)
static ir_entity *create_ent(ir_entity **const dst, int value, const char *name)
{
ir_mode *mode = mode_Hu;
ir_type *type = new_type_primitive(mode);
set_type_alignment_bytes(type, 4);
ir_type *glob = get_glob_type();
ir_entity *ent = new_entity(glob, new_id_from_str(name), type);
set_entity_ld_ident(ent, get_entity_ident(ent));
set_entity_visibility(ent, ir_visibility_local);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
ir_graph *cnst_irg = get_const_code_irg();
ir_node *cnst = new_r_Const_long(cnst_irg, mode, value);
set_atomic_ent_value(ent, cnst);
return ent;
if (!*dst) {
ir_mode *const mode = mode_Hu;
ir_type *const type = new_type_primitive(mode);
set_type_alignment_bytes(type, 4);
ir_type *const glob = get_glob_type();
ident *const id = new_id_from_str(name);
ir_entity *const ent = new_entity(glob, id, type);
set_entity_ld_ident(ent, id);
set_entity_visibility(ent, ir_visibility_local);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
ir_graph *const cnst_irg = get_const_code_irg();
ir_node *const cnst = new_r_Const_long(cnst_irg, mode, value);
set_atomic_ent_value(ent, cnst);
*dst = ent;
}
return *dst;
}
static void create_fpcw_entities(void)
static ir_node *create_fnstcw(ir_node *const block, ir_node *const frame, ir_node *const noreg, ir_node *const nomem, ir_node *const state)
{
fpcw_round = create_ent(0xc7f, "_fpcw_round");
fpcw_truncate = create_ent(0x37f, "_fpcw_truncate");
ir_node *const fnstcw = new_bd_ia32_FnstCW(NULL, block, frame, noreg, nomem, state);
set_ia32_op_type(fnstcw, ia32_AddrModeD);
set_ia32_ls_mode(fnstcw, ia32_mode_fpcw);
set_ia32_frame_use(fnstcw, IA32_FRAME_USE_32BIT);
return fnstcw;
}
static ir_node *create_fpu_mode_spill(void *env, ir_node *state, bool force,
ir_node *after)
static ir_node *create_fpu_mode_spill(void *const env, ir_node *const state, bool const force, ir_node *const after)
{
(void)env;
/* we don't spill the fpcw in unsafe mode */
if (ia32_cg_config.use_unsafe_floatconv) {
ir_node *block = get_nodes_block(state);
if (force || !is_ia32_ChangeCW(state)) {
ir_node *spill = new_bd_ia32_FnstCWNOP(NULL, block, state);
sched_add_after(after, spill);
return spill;
}
if (!force && is_ia32_ChangeCW(state))
return NULL;
}
if (force || !is_ia32_ChangeCW(state)) {
ir_graph *irg = get_irn_irg(state);
ir_node *block = get_nodes_block(state);
ir_node *noreg = ia32_new_NoReg_gp(irg);
ir_node *nomem = get_irg_no_mem(irg);
ir_node *frame = get_irg_frame(irg);
ir_node *spill
= new_bd_ia32_FnstCW(NULL, block, frame, noreg, nomem, state);
set_ia32_op_type(spill, ia32_AddrModeD);
/* use ia32_mode_gp, as movl has a shorter opcode than movw */
set_ia32_ls_mode(spill, ia32_mode_gp);
set_ia32_frame_use(spill, IA32_FRAME_USE_AUTO);
sched_add_after(skip_Proj(after), spill);
return spill;
ir_node *spill;
ir_node *const block = get_nodes_block(state);
/* Don't spill the fpcw in unsafe mode. */
if (ia32_cg_config.use_unsafe_floatconv) {
spill = new_bd_ia32_FnstCWNOP(NULL, block, state);
} else {
ir_graph *const irg = get_irn_irg(state);
ir_node *const noreg = ia32_new_NoReg_gp(irg);
ir_node *const nomem = get_irg_no_mem(irg);
ir_node *const frame = get_irg_frame(irg);
spill = create_fnstcw(block, frame, noreg, nomem, state);
}
return NULL;
sched_add_after(skip_Proj(after), spill);
return spill;
}
static ir_node *create_fldcw_ent(ir_node *block, ir_entity *entity)
{
ir_graph *irg = get_irn_irg(block);
ir_node *nomem = get_irg_no_mem(irg);
ir_node *noreg = ia32_new_NoReg_gp(irg);
ir_node *reload = new_bd_ia32_FldCW(NULL, block, noreg, noreg, nomem);
set_ia32_op_type(reload, ia32_AddrModeS);
set_ia32_ls_mode(reload, ia32_reg_classes[CLASS_ia32_fp_cw].mode);
set_ia32_am_ent(reload, entity);
set_ia32_frame_use(reload, IA32_FRAME_USE_32BIT);
arch_set_irn_register(reload, &ia32_registers[REG_FPCW]);
return reload;
}
static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
ir_node *spill, ir_node *before,
ir_node *last_state)
static ir_node *create_fpu_mode_reload(void *const env, ir_node *const state, ir_node *const spill, ir_node *const before, ir_node *const last_state)
{
(void)env;
ir_graph *irg = get_irn_irg(state);
ir_node *block = get_nodes_block(before);
ir_node *frame = get_irg_frame(irg);
ir_node *noreg = ia32_new_NoReg_gp(irg);
ir_node *reload = NULL;
(void)state;
ir_node *reload;
ir_node *const block = get_nodes_block(before);
ir_graph *const irg = get_irn_irg(block);
ir_node *const noreg = ia32_new_NoReg_gp(irg);
ir_node *const nomem = get_irg_no_mem(irg);
if (ia32_cg_config.use_unsafe_floatconv) {
if (fpcw_round == NULL)
create_fpcw_entities();
if (spill != NULL) {
reload = create_fldcw_ent(block, fpcw_round);
reload = new_bd_ia32_FldCW(NULL, block, noreg, noreg, nomem);
ir_entity *const rounding_mode = spill ?
create_ent(&fpcw_round, 0xC7F, "_fpcw_round") :
create_ent(&fpcw_truncate, 0x37F, "_fpcw_truncate");
set_ia32_am_ent(reload, rounding_mode);
} else {
ir_node *mem;
ir_node *const frame = get_irg_frame(irg);
if (spill) {
mem = spill;
} else {
reload = create_fldcw_ent(block, fpcw_truncate);
assert(last_state);
ir_node *const cwstore = create_fnstcw(block, frame, noreg, nomem, last_state);
sched_add_before(before, cwstore);
ir_node *const load = new_bd_ia32_Load(NULL, block, frame, noreg, cwstore);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_ls_mode(load, mode_Hu);
set_ia32_frame_use(load, IA32_FRAME_USE_32BIT);
sched_add_before(before, load);
ir_node *const load_res = new_r_Proj(load, ia32_mode_gp, pn_ia32_Load_res);
/* TODO: Make the actual mode configurable in ChangeCW. */
ir_node *const or_const = ia32_immediate_from_long(irg, 0xC00);
ir_node *const orn = new_bd_ia32_Or(NULL, block, noreg, noreg, nomem, load_res, or_const);
sched_add_before(before, orn);
ir_node *const store = new_bd_ia32_Store(NULL, block, frame, noreg, nomem, orn);
set_ia32_op_type(store, ia32_AddrModeD);
/* Use ia32_mode_gp, as movl has a shorter opcode than movw. */
set_ia32_ls_mode(store, ia32_mode_gp);
set_ia32_frame_use(store, IA32_FRAME_USE_32BIT);
sched_add_before(before, store);
mem = new_r_Proj(store, mode_M, pn_ia32_Store_M);
}
sched_add_before(before, reload);
return reload;
}
if (spill != NULL) {
reload = new_bd_ia32_FldCW(NULL, block, frame, noreg, spill);
set_ia32_op_type(reload, ia32_AddrModeS);
set_ia32_ls_mode(reload, ia32_reg_classes[CLASS_ia32_fp_cw].mode);
set_ia32_frame_use(reload, IA32_FRAME_USE_32BIT);
arch_set_irn_register(reload, &ia32_registers[REG_FPCW]);
sched_add_before(before, reload);
} else {
ir_mode *lsmode = mode_Hu;
ir_node *nomem = get_irg_no_mem(irg);
ir_node *cwstore, *load, *load_res, *orn, *store, *fldcw;
ir_node *store_proj;
ir_node *or_const;
assert(last_state != NULL);
cwstore = new_bd_ia32_FnstCW(NULL, block, frame, noreg, nomem,
last_state);
set_ia32_op_type(cwstore, ia32_AddrModeD);
set_ia32_ls_mode(cwstore, lsmode);
set_ia32_frame_use(cwstore, IA32_FRAME_USE_32BIT);
sched_add_before(before, cwstore);
load = new_bd_ia32_Load(NULL, block, frame, noreg, cwstore);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_ls_mode(load, lsmode);
set_ia32_frame_use(load, IA32_FRAME_USE_32BIT);
sched_add_before(before, load);
load_res = new_r_Proj(load, ia32_mode_gp, pn_ia32_Load_res);
/* TODO: make the actual mode configurable in ChangeCW... */
or_const = new_bd_ia32_Immediate(NULL, get_irg_start_block(irg),
NULL, 0, 3072);
arch_set_irn_register(or_const, &ia32_registers[REG_GP_NOREG]);
orn = new_bd_ia32_Or(NULL, block, noreg, noreg, nomem, load_res,
or_const);
sched_add_before(before, orn);
store = new_bd_ia32_Store(NULL, block, frame, noreg, nomem, orn);
set_ia32_op_type(store, ia32_AddrModeD);
/* use ia32_mode_gp, as movl has a shorter opcode than movw */
set_ia32_ls_mode(store, ia32_mode_gp);
set_ia32_frame_use(store, IA32_FRAME_USE_32BIT);
store_proj = new_r_Proj(store, mode_M, pn_ia32_Store_M);
sched_add_before(before, store);
fldcw = new_bd_ia32_FldCW(NULL, block, frame, noreg, store_proj);
set_ia32_op_type(fldcw, ia32_AddrModeS);
set_ia32_ls_mode(fldcw, lsmode);
set_ia32_frame_use(fldcw, IA32_FRAME_USE_32BIT);
arch_set_irn_register(fldcw, &ia32_registers[REG_FPCW]);
sched_add_before(before, fldcw);
reload = fldcw;
reload = new_bd_ia32_FldCW(NULL, block, frame, noreg, mem);
}
set_ia32_op_type(reload, ia32_AddrModeS);
set_ia32_ls_mode(reload, ia32_mode_fpcw);
set_ia32_frame_use(reload, IA32_FRAME_USE_32BIT);
arch_set_irn_register(reload, &ia32_registers[REG_FPCW]);
sched_add_before(before, reload);
return reload;
}
......
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