#include "tv.h"
#include "irgmod.h"
#include "irgwalk.h"
-#include "height.h"
+#include "heights.h"
#include "irbitset.h"
#include "irprintf.h"
#include "irdump.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
-static ia32_code_gen_t *cg;
-
-static void copy_mark(const ir_node *old, ir_node *new)
+static void copy_mark(const ir_node *old, ir_node *newn)
{
if (is_ia32_is_reload(old))
- set_ia32_is_reload(new);
+ set_ia32_is_reload(newn);
if (is_ia32_is_spill(old))
- set_ia32_is_spill(new);
+ set_ia32_is_spill(newn);
if (is_ia32_is_remat(old))
- set_ia32_is_remat(new);
+ set_ia32_is_remat(newn);
}
typedef enum produces_flag_t {
case iro_ia32_ShlD:
case iro_ia32_ShrD:
- assert(n_ia32_ShlD_count == n_ia32_ShrD_count);
+ assert((int)n_ia32_ShlD_count == (int)n_ia32_ShrD_count);
count = get_irn_n(node, n_ia32_ShlD_count);
goto check_shift_amount;
case iro_ia32_Shl:
case iro_ia32_Shr:
case iro_ia32_Sar:
- assert(n_ia32_Shl_count == n_ia32_Shr_count
- && n_ia32_Shl_count == n_ia32_Sar_count);
+ assert((int)n_ia32_Shl_count == (int)n_ia32_Shr_count
+ && (int)n_ia32_Shl_count == (int)n_ia32_Sar_count);
count = get_irn_n(node, n_ia32_Shl_count);
check_shift_amount:
/* when shift count is zero the flags are not affected, so we can only
static void peephole_ia32_Cmp(ir_node *const node)
{
ir_node *right;
+ ir_graph *irg;
ia32_immediate_attr_t const *imm;
dbg_info *dbgi;
ir_node *block;
ir_node *op;
ia32_attr_t const *attr;
int ins_permuted;
- int cmp_unsigned;
ir_node *test;
arch_register_t const *reg;
ir_edge_t const *edge;
return;
dbgi = get_irn_dbg_info(node);
+ irg = get_irn_irg(node);
block = get_nodes_block(node);
- noreg = ia32_new_NoReg_gp(cg);
+ noreg = ia32_new_NoReg_gp(irg);
nomem = get_irg_no_mem(current_ir_graph);
op = get_irn_n(node, n_ia32_Cmp_left);
- attr = get_irn_generic_attr(node);
+ attr = get_ia32_attr(node);
ins_permuted = attr->data.ins_permuted;
- cmp_unsigned = attr->data.cmp_unsigned;
if (is_ia32_Cmp(node)) {
test = new_bd_ia32_Test(dbgi, block, noreg, noreg, nomem,
- op, op, ins_permuted, cmp_unsigned);
+ op, op, ins_permuted);
} else {
test = new_bd_ia32_Test8Bit(dbgi, block, noreg, noreg, nomem,
- op, op, ins_permuted, cmp_unsigned);
+ op, op, ins_permuted);
}
set_ia32_ls_mode(test, get_ia32_ls_mode(node));
ir_node *left = get_irn_n(node, n_ia32_Test_left);
ir_node *right = get_irn_n(node, n_ia32_Test_right);
- assert(n_ia32_Test_left == n_ia32_Test8Bit_left
- && n_ia32_Test_right == n_ia32_Test8Bit_right);
+ assert((int)n_ia32_Test_left == (int)n_ia32_Test8Bit_left
+ && (int)n_ia32_Test_right == (int)n_ia32_Test8Bit_right);
if (left == right) { /* we need a test for 0 */
ir_node *block = get_nodes_block(node);
/* make sure only Lg/Eq tests are used */
foreach_out_edge(node, edge) {
- ir_node *user = get_edge_src_irn(edge);
- int pnc = get_ia32_condcode(user);
+ ir_node *user = get_edge_src_irn(edge);
+ ia32_condition_code_t cc = get_ia32_condcode(user);
- if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg) {
+ if (cc != ia32_cc_equal && cc != ia32_cc_not_equal) {
return;
}
}
case produces_flag_carry:
foreach_out_edge(node, edge) {
- ir_node *user = get_edge_src_irn(edge);
- int pnc = get_ia32_condcode(user);
+ ir_node *user = get_edge_src_irn(edge);
+ ia32_condition_code_t cc = get_ia32_condcode(user);
- switch (pnc) {
- case pn_Cmp_Eq: pnc = ia32_pn_Cmp_not_carry; break;
- case pn_Cmp_Lg: pnc = ia32_pn_Cmp_carry; break;
- default: panic("unexpected pn");
+ switch (cc) {
+ case ia32_cc_equal: cc = ia32_cc_above_equal; break; /* CF = 0 */
+ case ia32_cc_not_equal: cc = ia32_cc_below; break; /* CF = 1 */
+ default: panic("unexpected pn");
}
- set_ia32_condcode(user, pnc);
+ set_ia32_condcode(user, cc);
}
break;
flags_mode = ia32_reg_classes[CLASS_ia32_flags].mode;
flags_proj = new_r_Proj(left, flags_mode, pn_ia32_flags);
- arch_set_irn_register(flags_proj, &ia32_flags_regs[REG_EFLAGS]);
+ arch_set_irn_register(flags_proj, &ia32_registers[REG_EFLAGS]);
assert(get_irn_mode(node) != mode_T);
offset = imm->offset;
if (get_ia32_op_type(node) == ia32_AddrModeS) {
- ia32_attr_t *const attr = get_irn_generic_attr(node);
+ ia32_attr_t *const attr = get_ia32_attr(node);
if ((offset & 0xFFFFFF00) == 0) {
/* attr->am_offs += 0; */
} else if (offset < 256) {
arch_register_t const* const reg = arch_get_irn_register(left);
- if (reg != &ia32_gp_regs[REG_EAX] &&
- reg != &ia32_gp_regs[REG_EBX] &&
- reg != &ia32_gp_regs[REG_ECX] &&
- reg != &ia32_gp_regs[REG_EDX]) {
+ if (reg != &ia32_registers[REG_EAX] &&
+ reg != &ia32_registers[REG_EBX] &&
+ reg != &ia32_registers[REG_ECX] &&
+ reg != &ia32_registers[REG_EDX]) {
return;
}
} else {
continue;
case iro_Start:
case beo_Start:
- case beo_Barrier:
/* ignore no code generated */
continue;
case beo_IncSP:
}
/* only optimize up to 48 stores behind IncSPs */
-#define MAXPUSH_OPTIMIZE 48
+#define MAXPUSH_OPTIMIZE 48
/**
* Tries to create Push's from IncSP, Store combinations.
/* walk through the Stores and create Pushs for them */
block = get_nodes_block(irn);
spmode = get_irn_mode(irn);
- irg = cg->irg;
+ irg = get_irn_irg(irn);
for (; i >= 0; --i) {
const arch_register_t *spreg;
ir_node *push;
ir_node *val, *mem, *mem_proj;
ir_node *store = stores[i];
- ir_node *noreg = ia32_new_NoReg_gp(cg);
+ ir_node *noreg = ia32_new_NoReg_gp(irg);
val = get_irn_n(store, n_ia32_unary_op);
mem = get_irn_n(store, n_ia32_mem);
static ir_node *create_push(dbg_info *dbgi, ir_node *block,
ir_node *stack, ir_node *schedpoint)
{
- const arch_register_t *esp = &ia32_gp_regs[REG_ESP];
+ const arch_register_t *esp = &ia32_registers[REG_ESP];
ir_node *val = ia32_new_NoReg_gp(cg);
ir_node *noreg = ia32_new_NoReg_gp(cg);
- ir_node *nomem = new_NoMem();
+ ir_graph *irg = get_irn_irg(block);
+ ir_node *nomem = new_r_NoMem(irg);
ir_node *push = new_bd_ia32_Push(dbgi, block, noreg, noreg, nomem, val, stack);
sched_add_before(schedpoint, push);
*/
static inline int mode_needs_gp_reg(ir_mode *mode)
{
- if (mode == mode_fpcw)
+ if (mode == ia32_mode_fpcw)
return 0;
if (get_mode_size_bits(mode) > 32)
return 0;
*/
static void peephole_Load_IncSP_to_pop(ir_node *irn)
{
- const arch_register_t *esp = &ia32_gp_regs[REG_ESP];
+ const arch_register_t *esp = &ia32_registers[REG_ESP];
int i, maxslot, inc_ofs, ofs;
ir_node *node, *pred_sp, *block;
ir_node *loads[MAXPUSH_OPTIMIZE];
/* create a new IncSP if needed */
block = get_nodes_block(irn);
- irg = cg->irg;
+ irg = get_irn_irg(irn);
if (inc_ofs > 0) {
pred_sp = be_new_IncSP(esp, block, pred_sp, -inc_ofs, be_get_IncSP_align(irn));
sched_add_before(irn, pred_sp);
/**
* Find a free GP register if possible, else return NULL.
*/
-static const arch_register_t *get_free_gp_reg(void)
+static const arch_register_t *get_free_gp_reg(ir_graph *irg)
{
+ be_irg_t *birg = be_birg_from_irg(irg);
int i;
for (i = 0; i < N_ia32_gp_REGS; ++i) {
- const arch_register_t *reg = &ia32_gp_regs[i];
- if (arch_register_type_is(reg, ignore))
+ const arch_register_t *reg = &ia32_reg_classes[CLASS_ia32_gp].regs[i];
+ if (!rbitset_is_set(birg->allocatable_regs, reg->global_index))
continue;
if (be_peephole_get_value(CLASS_ia32_gp, i) == NULL)
- return &ia32_gp_regs[i];
+ return reg;
}
return NULL;
ir_node *stack, ir_node *schedpoint,
const arch_register_t *reg)
{
- const arch_register_t *esp = &ia32_gp_regs[REG_ESP];
+ const arch_register_t *esp = &ia32_registers[REG_ESP];
+ ir_graph *irg = get_irn_irg(block);
ir_node *pop;
ir_node *keep;
ir_node *val;
ir_node *in[1];
- pop = new_bd_ia32_Pop(dbgi, block, new_NoMem(), stack);
+ pop = new_bd_ia32_Pop(dbgi, block, new_r_NoMem(irg), stack);
stack = new_r_Proj(pop, mode_Iu, pn_ia32_Pop_stack);
arch_set_irn_register(stack, esp);
*/
static void peephole_be_IncSP(ir_node *node)
{
- const arch_register_t *esp = &ia32_gp_regs[REG_ESP];
+ const arch_register_t *esp = &ia32_registers[REG_ESP];
const arch_register_t *reg;
dbg_info *dbgi;
ir_node *block;
if (offset < 0) {
/* we need a free register for pop */
- reg = get_free_gp_reg();
+ reg = get_free_gp_reg(get_irn_irg(node));
if (reg == NULL)
return;
const arch_register_t *reg;
ir_node *block;
dbg_info *dbgi;
- ir_node *xor;
+ ir_node *xorn;
/* try to transform a mov 0, reg to xor reg reg */
if (attr->offset != 0 || attr->symconst != NULL)
if (ia32_cg_config.use_mov_0)
return;
/* xor destroys the flags, so no-one must be using them */
- if (be_peephole_get_value(CLASS_ia32_flags, REG_EFLAGS) != NULL)
+ if (be_peephole_get_value(CLASS_ia32_flags, REG_FLAGS_EFLAGS) != NULL)
return;
reg = arch_get_irn_register(node);
/* create xor(produceval, produceval) */
block = get_nodes_block(node);
dbgi = get_irn_dbg_info(node);
- xor = new_bd_ia32_Xor0(dbgi, block);
- arch_set_irn_register(xor, reg);
+ xorn = new_bd_ia32_Xor0(dbgi, block);
+ arch_set_irn_register(xorn, reg);
- sched_add_before(node, xor);
+ sched_add_before(node, xorn);
- copy_mark(node, xor);
- be_peephole_exchange(node, xor);
+ copy_mark(node, xorn);
+ be_peephole_exchange(node, xorn);
}
-static inline int is_noreg(ia32_code_gen_t *cg, const ir_node *node)
+static inline int is_noreg(const ir_node *node)
{
- return node == cg->noreg_gp;
+ return is_ia32_NoReg_GP(node);
}
ir_node *ia32_immediate_from_long(long val)
ir_node *start_block = get_irg_start_block(irg);
ir_node *immediate
= new_bd_ia32_Immediate(NULL, start_block, NULL, 0, 0, val);
- arch_set_irn_register(immediate, &ia32_gp_regs[REG_GP_NOREG]);
+ arch_set_irn_register(immediate, &ia32_registers[REG_GP_NOREG]);
return immediate;
}
res = new_bd_ia32_Immediate(NULL, block, entity, sc_sign, sc_no_pic_adjust,
offset);
- arch_set_irn_register(res, &ia32_gp_regs[REG_GP_NOREG]);
+ arch_set_irn_register(res, &ia32_registers[REG_GP_NOREG]);
return res;
}
*/
static void peephole_ia32_Lea(ir_node *node)
{
+ ir_graph *irg;
ir_node *base;
ir_node *index;
const arch_register_t *base_reg;
assert(is_ia32_Lea(node));
/* we can only do this if it is allowed to clobber the flags */
- if (be_peephole_get_value(CLASS_ia32_flags, REG_EFLAGS) != NULL)
+ if (be_peephole_get_value(CLASS_ia32_flags, REG_FLAGS_EFLAGS) != NULL)
return;
base = get_irn_n(node, n_ia32_Lea_base);
index = get_irn_n(node, n_ia32_Lea_index);
- if (is_noreg(cg, base)) {
+ if (is_noreg(base)) {
base = NULL;
base_reg = NULL;
} else {
base_reg = arch_get_irn_register(base);
}
- if (is_noreg(cg, index)) {
+ if (is_noreg(index)) {
index = NULL;
index_reg = NULL;
} else {
make_add:
dbgi = get_irn_dbg_info(node);
block = get_nodes_block(node);
- noreg = ia32_new_NoReg_gp(cg);
- nomem = new_NoMem();
+ irg = get_irn_irg(node);
+ noreg = ia32_new_NoReg_gp(irg);
+ nomem = new_r_NoMem(irg);
res = new_bd_ia32_Add(dbgi, block, noreg, noreg, nomem, op1, op2);
arch_set_irn_register(res, out_reg);
set_ia32_commutative(res);
make_shl:
dbgi = get_irn_dbg_info(node);
block = get_nodes_block(node);
- noreg = ia32_new_NoReg_gp(cg);
- nomem = new_NoMem();
+ irg = get_irn_irg(node);
+ noreg = ia32_new_NoReg_gp(irg);
+ nomem = new_r_NoMem(irg);
res = new_bd_ia32_Shl(dbgi, block, op1, op2);
arch_set_irn_register(res, out_reg);
goto exchange;
return;
}
/* we need a free register */
- reg = get_free_gp_reg();
+ reg = get_free_gp_reg(get_irn_irg(imul));
if (reg == NULL)
return;
/* fine, we can rebuild it */
- res = turn_back_am(imul);
+ res = ia32_turn_back_am(imul);
arch_set_irn_register(res, reg);
}
/**
* Replace xorps r,r and xorpd r,r by pxor r,r
*/
-static void peephole_ia32_xZero(ir_node *xor)
+static void peephole_ia32_xZero(ir_node *xorn)
{
- set_irn_op(xor, op_ia32_xPzero);
+ set_irn_op(xorn, op_ia32_xPzero);
}
/**
*/
static void peephole_ia32_Conv_I2I(ir_node *node)
{
- const arch_register_t *eax = &ia32_gp_regs[REG_EAX];
+ const arch_register_t *eax = &ia32_registers[REG_EAX];
ir_mode *smaller_mode = get_ia32_ls_mode(node);
ir_node *val = get_irn_n(node, n_ia32_Conv_I2I_val);
dbg_info *dbgi;
}
/* Perform peephole-optimizations. */
-void ia32_peephole_optimization(ia32_code_gen_t *new_cg)
+void ia32_peephole_optimization(ir_graph *irg)
{
- cg = new_cg;
-
/* register peephole optimisations */
clear_irp_opcodes_generic_func();
register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
if (ia32_cg_config.use_short_sex_eax)
register_peephole_optimisation(op_ia32_Conv_I2I, peephole_ia32_Conv_I2I);
- be_peephole_opt(cg->irg);
+ be_peephole_opt(irg);
}
/**
* Removes node from schedule if it is not used anymore. If irn is a mode_T node
- * all it's Projs are removed as well.
+ * all its Projs are removed as well.
* @param irn The irn to be removed from schedule
*/
static inline void try_kill(ir_node *node)
if (!is_ia32_Store(node) && !is_ia32_Store8Bit(node))
return;
- assert(n_ia32_Store_val == n_ia32_Store8Bit_val);
+ assert((int)n_ia32_Store_val == (int)n_ia32_Store8Bit_val);
pred_proj = get_irn_n(node, n_ia32_Store_val);
if (is_Proj(pred_proj)) {
pred = get_Proj_pred(pred_proj);
if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node))
return;
- assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val);
+ assert((int)n_ia32_Conv_I2I_val == (int)n_ia32_Conv_I2I8Bit_val);
pred = get_irn_n(node, n_ia32_Conv_I2I_val);
if (!is_Proj(pred))
return;
if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node))
return;
- assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val);
+ assert((int)n_ia32_Conv_I2I_val == (int)n_ia32_Conv_I2I8Bit_val);
pred_proj = get_irn_n(node, n_ia32_Conv_I2I_val);
if (is_Proj(pred_proj))
pred = get_Proj_pred(pred_proj);
/* Argh:We must change the opcode to 8bit AND copy the register constraints */
if (get_mode_size_bits(conv_mode) == 8) {
set_irn_op(pred, op_ia32_Conv_I2I8Bit);
- set_ia32_in_req_all(pred, get_ia32_in_req_all(node));
+ arch_set_in_register_reqs(pred,
+ arch_get_in_register_reqs(node));
}
} else {
/* we don't want to end up with 2 loads, so we better do nothing */
/* Argh:We must change the opcode to 8bit AND copy the register constraints */
if (get_mode_size_bits(conv_mode) == 8) {
set_irn_op(result_conv, op_ia32_Conv_I2I8Bit);
- set_ia32_in_req_all(result_conv, get_ia32_in_req_all(node));
+ arch_set_in_register_reqs(result_conv,
+ arch_get_in_register_reqs(node));
}
}
} else {
/**
* Performs conv and address mode optimization.
*/
-void ia32_optimize_graph(ia32_code_gen_t *cg)
+void ia32_optimize_graph(ir_graph *irg)
{
- irg_walk_blkwise_graph(cg->irg, NULL, optimize_node, cg);
-
- if (cg->dump)
- dump_ir_graph(cg->irg, "opt");
+ irg_walk_blkwise_graph(irg, NULL, optimize_node, NULL);
}
void ia32_init_optimize(void)