Пример #1
0
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;
	(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) {
		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 {
			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_create_Immediate(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);
		}

		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;
}
Пример #2
0
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)
{
	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;
}
Пример #3
0
void ia32_copy_am_attrs(ir_node *to, const ir_node *from)
{
	ia32_attr_t const *const from_attr = get_ia32_attr_const(from);
	ia32_attr_t       *const to_attr   = get_ia32_attr(to);
	to_attr->am_imm = from_attr->am_imm;
	to_attr->frame_use = from_attr->frame_use;

	set_ia32_ls_mode(to, get_ia32_ls_mode(from));
	set_ia32_am_scale(to, get_ia32_am_scale(from));
#ifndef NDEBUG
	to_attr->old_frame_ent = from_attr->old_frame_ent;
#endif
}