}
/* unknowns should be transformed already */
- assert(!is_Unknown(node));
return arch_no_register_req;
}
-static void ia32_set_irn_reg(ir_node *irn, const arch_register_t *reg)
-{
- int pos = 0;
-
- if (get_irn_mode(irn) == mode_X) {
- return;
- }
-
- if (is_Proj(irn)) {
- pos = get_Proj_proj(irn);
- irn = skip_Proj(irn);
- }
-
- if (is_ia32_irn(irn)) {
- const arch_register_t **slots;
-
- slots = get_ia32_slots(irn);
- slots[pos] = reg;
- } else {
- ia32_set_firm_reg(irn, reg, cur_reg_set);
- }
-}
-
-static const arch_register_t *ia32_get_irn_reg(const ir_node *irn)
-{
- int pos = 0;
-
- if (is_Proj(irn)) {
- if (get_irn_mode(irn) == mode_X) {
- return NULL;
- }
-
- pos = get_Proj_proj(irn);
- irn = skip_Proj_const(irn);
- }
-
- if (is_ia32_irn(irn)) {
- const arch_register_t **slots = get_ia32_slots(irn);
- assert(pos < get_ia32_n_res(irn));
- return slots[pos];
- } else {
- return ia32_get_firm_reg(irn, cur_reg_set);
- }
-}
-
static arch_irn_class_t ia32_classify(const ir_node *irn) {
arch_irn_class_t classification = 0;
return classification;
}
-static arch_irn_flags_t ia32_get_flags(const ir_node *irn) {
- arch_irn_flags_t flags = arch_irn_flags_none;
-
- if (is_Unknown(irn))
- return arch_irn_flags_ignore;
-
- if(is_Proj(irn) && mode_is_datab(get_irn_mode(irn))) {
- ir_node *pred = get_Proj_pred(irn);
-
- if(is_ia32_irn(pred)) {
- flags = get_ia32_out_flags(pred, get_Proj_proj(irn));
- }
-
- irn = pred;
- }
-
- if (is_ia32_irn(irn)) {
- flags |= get_ia32_flags(irn);
- }
-
- return flags;
-}
-
/**
* The IA32 ABI callback object.
*/
const arch_env_t *arch_env = env->aenv;
if (! env->flags.try_omit_fp) {
- ir_graph *irg =env->irg;
+ ir_graph *irg = env->irg;
ir_node *bl = get_irg_start_block(irg);
ir_node *curr_sp = be_abi_reg_map_get(reg_map, arch_env->sp);
ir_node *curr_bp = be_abi_reg_map_get(reg_map, arch_env->bp);
- ir_node *noreg = ia32_new_NoReg_gp(cg);
+ ir_node *noreg = ia32_new_NoReg_gp(cg);
ir_node *push;
- /* ALL nodes representing bp must be set to ignore. */
- be_node_set_flags(get_Proj_pred(curr_bp), BE_OUT_POS(get_Proj_proj(curr_bp)), arch_irn_flags_ignore);
+ /* mark bp register as ignore */
+ be_set_constr_single_reg_out(get_Proj_pred(curr_bp),
+ get_Proj_proj(curr_bp), arch_env->bp, arch_register_req_type_ignore);
/* push ebp */
push = new_rd_ia32_Push(NULL, irg, bl, noreg, noreg, *mem, curr_bp, curr_sp);
/* the push must have SP out register */
arch_set_irn_register(curr_sp, arch_env->sp);
- set_ia32_flags(push, arch_irn_flags_ignore);
/* this modifies the stack bias, because we pushed 32bit */
*stack_bias -= 4;
/* move esp to ebp */
- curr_bp = be_new_Copy(arch_env->bp->reg_class, irg, bl, curr_sp);
- be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), arch_env->bp);
- arch_set_irn_register(curr_bp, arch_env->bp);
- be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
+ curr_bp = be_new_Copy(arch_env->bp->reg_class, irg, bl, curr_sp);
+ be_set_constr_single_reg_out(curr_bp, 0, arch_env->bp,
+ arch_register_req_type_ignore);
/* beware: the copy must be done before any other sp use */
curr_sp = be_new_CopyKeep_single(arch_env->sp->reg_class, irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
- be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), arch_env->sp);
- arch_set_irn_register(curr_sp, arch_env->sp);
- be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
+ be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp,
+ arch_register_req_type_produces_sp);
be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
/* leave */
leave = new_rd_ia32_Leave(NULL, irg, bl, curr_bp);
- set_ia32_flags(leave, arch_irn_flags_ignore);
curr_bp = new_r_Proj(irg, bl, leave, mode_bp, pn_ia32_Leave_frame);
curr_sp = new_r_Proj(irg, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
} else {
/* copy ebp to esp */
curr_sp = be_new_Copy(&ia32_reg_classes[CLASS_ia32_gp], irg, bl, curr_bp);
arch_set_irn_register(curr_sp, arch_env->sp);
- be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
+ be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp,
+ arch_register_req_type_ignore);
/* pop ebp */
- pop = new_rd_ia32_Pop(NULL, env->irg, bl, *mem, curr_sp);
- set_ia32_flags(pop, arch_irn_flags_ignore);
+ pop = new_rd_ia32_PopEbp(NULL, env->irg, bl, *mem, curr_sp);
curr_bp = new_r_Proj(irg, bl, pop, mode_bp, pn_ia32_Pop_res);
curr_sp = new_r_Proj(irg, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
static const arch_irn_ops_t ia32_irn_ops = {
ia32_get_irn_reg_req,
- ia32_set_irn_reg,
- ia32_get_irn_reg,
ia32_classify,
- ia32_get_flags,
ia32_get_frame_entity,
ia32_set_frame_entity,
ia32_set_frame_offset,
/* copy the register from the old node to the new Load */
reg = arch_get_irn_register(node);
- arch_set_irn_register(new_op, reg);
+ arch_set_irn_register(proj, reg);
- SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
+ SET_IA32_ORIG_NODE(new_op, node);
exchange(node, proj);
}
set_ia32_frame_ent(store, ent);
set_ia32_use_frame(store);
set_ia32_is_spill(store);
- SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(cg, node));
+ SET_IA32_ORIG_NODE(store, node);
DBG_OPT_SPILL2ST(node, store);
if (sched_point) {
/* enter the ISA object into the intrinsic environment */
intrinsic_env.isa = isa;
- ia32_handle_intrinsics();
/* emit asm includes */
n = get_irp_n_asms();
}
}
+/**
+ * Check for Abs or Nabs.
+ */
+static int is_Abs_or_Nabs(ir_node *cmp, ir_node *sel, ir_node *t, ir_node *f) {
+ ir_node *l, *r;
+ pn_Cmp pnc;
+
+ if (cmp == NULL)
+ return 0;
+
+ /* must be <, <=, >=, > */
+ pnc = get_Proj_proj(sel);
+ if (pnc != pn_Cmp_Ge && pnc != pn_Cmp_Gt &&
+ pnc != pn_Cmp_Le && pnc != pn_Cmp_Lt)
+ return 0;
+
+ l = get_Cmp_left(cmp);
+ r = get_Cmp_right(cmp);
+
+ /* must be x cmp 0 */
+ if ((l != t && l != f) || !is_Const(r) || !is_Const_null(r))
+ return 0;
+
+ if ((!is_Minus(t) || get_Minus_op(t) != f) &&
+ (!is_Minus(f) || get_Minus_op(f) != t))
+ return 0;
+ return 1;
+}
+
/**
* Allows or disallows the creation of Psi nodes for the given Phi nodes.
+ *
+ * @param sel A selector of a Cond.
+ * @param phi_list List of Phi nodes about to be converted (linked via get_Phi_next() field)
+ * @param i First data predecessor involved in if conversion
+ * @param j Second data predecessor involved in if conversion
+ *
* @return 1 if allowed, 0 otherwise
*/
static int ia32_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j)
ir_node *phi;
ir_node *cmp = NULL;
- /* we can't handle psis with 64bit compares yet */
+ /* we can't handle Psis with 64bit compares yet */
if (is_Proj(sel)) {
cmp = get_Proj_pred(sel);
if (is_Cmp(cmp)) {
for (phi = phi_list; phi; phi = get_Phi_next(phi)) {
ir_mode *mode = get_irn_mode(phi);
- if (mode_is_float(mode) || get_mode_size_bits(mode) > 32)
+ if (mode_is_float(mode)) {
+ ir_node *t = get_Phi_pred(phi, i);
+ ir_node *f = get_Phi_pred(phi, j);
+
+ if (! is_Abs_or_Nabs(cmp, sel, t, f))
+ return 0;
+ } else if (get_mode_size_bits(mode) > 32)
return 0;
}
}
ir_node *cl, *cr;
pn_Cmp pn;
- /* No cmov, only some special cases */
+ /* No Cmov, only some special cases */
if (cmp == NULL)
return 0;
t = get_Phi_pred(phi, i);
f = get_Phi_pred(phi, j);
- /* no floating point and no 64bit yet */
- if (mode_is_float(mode) || get_mode_size_bits(mode) > 32)
+ if (mode_is_float(mode)) {
+ /* only abs or nabs supported */
+ if (! is_Abs_or_Nabs(cmp, sel, t, f))
+ return 0;
+ } else if (get_mode_size_bits(mode) > 32) {
+ /* no 64bit yet */
return 0;
+ }
if (is_Const(t) && is_Const(f)) {
if ((is_Const_null(t) && is_Const_one(f)) || (is_Const_one(t) && is_Const_null(f))) {
const arch_isa_if_t ia32_isa_if = {
ia32_init,
ia32_done,
+ ia32_handle_intrinsics,
ia32_get_n_reg_class,
ia32_get_reg_class,
ia32_get_reg_class_for_mode,
ia32_is_valid_clobber
};
-void ia32_init_emitter(void);
-void ia32_init_finish(void);
-void ia32_init_optimize(void);
-void ia32_init_transform(void);
-void ia32_init_x87(void);
-
void be_init_arch_ia32(void)
{
lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");