* @author Michael Beck
* @version $Id: $
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include "irgmod.h"
#include "ircons.h"
#include "error.h"
-#include "benode_t.h"
+#include "benode.h"
#include "bepeephole.h"
#include "besched.h"
#include "gen_arm_regalloc_if.h"
#include "gen_arm_new_nodes.h"
-static const arch_env_t *arch_env;
static arm_code_gen_t *cg;
/** Execute ARM ROL. */
return arm_rol(l & 0xFF, rol);
}
-/**
- * Creates a Mov node.
- */
-static ir_node *create_mov_node(ir_node *sched_point, dbg_info *dbg, ir_node *block, long value) {
- ir_graph *irg = current_ir_graph;
- ir_node *mov;
-
- mov = new_rd_arm_Mov_i(dbg, irg, block, mode_Iu, value);
- arch_set_irn_register(arch_env, mov, &arm_gp_regs[REG_R12]);
- sched_add_before(sched_point, mov);
- return mov;
-}
-
-/**
- * Creates a Mvn node.
- */
-static ir_node *create_mvn_node(ir_node *sched_point, dbg_info *dbg, ir_node *block, long value) {
- ir_graph *irg = current_ir_graph;
- ir_node *mvn;
-
- mvn = new_rd_arm_Mvn_i(dbg, irg, block, mode_Iu, value);
- arch_set_irn_register(arch_env, mvn, &arm_gp_regs[REG_R12]);
- sched_add_before(sched_point, mvn);
- return mvn;
-}
-
-/**
- * Creates a possible DAG for an constant and schedule it before
- * the node sched_point.
- * The Dag deliveres it's result in register R12.
- */
-static ir_node *create_const_graph_value(ir_node *sched_point, unsigned int value) {
- dbg_info *dbg;
- ir_node *block, *result;
- arm_vals v, vn;
- int cnt;
-
- arm_gen_vals_from_word(value, &v);
- arm_gen_vals_from_word(~value, &vn);
-
- dbg = get_irn_dbg_info(sched_point);
- block = get_nodes_block(sched_point);
-
- if (vn.ops < v.ops) {
- /* remove bits */
- result = create_mvn_node(sched_point, dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
-
- for (cnt = 1; cnt < vn.ops; ++cnt) {
- long value = arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]);
- ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode_Iu, value);
- arch_set_irn_register(arch_env, bic_i_node, &arm_gp_regs[REG_R12]);
- sched_add_before(sched_point, bic_i_node);
- result = bic_i_node;
- }
- }
- else {
- /* add bits */
- result = create_mov_node(sched_point, dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
-
- for (cnt = 1; cnt < v.ops; ++cnt) {
- long value = arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]);
- ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode_Iu, value);
- arch_set_irn_register(arch_env, orr_i_node, &arm_gp_regs[REG_R12]);
- sched_add_before(sched_point, orr_i_node);
- result = orr_i_node;
- }
- }
- return result;
-}
-
-
/**
* Returns non.zero if the given offset can be directly encoded into an ARM instruction.
*/
* Fix an IncSP node if the offset gets too big
*/
static void peephole_be_IncSP(ir_node *node) {
- ir_graph *irg;
ir_node *block;
int offset, cnt, align, sign = 1;
arm_vals v;
/* first optimize incsp->incsp combinations */
- be_peephole_IncSP_IncSP(node);
+ node = be_peephole_IncSP_IncSP(node);
offset = be_get_IncSP_offset(node);
/* can be transformed into Add OR Sub */
if (allowed_arm_immediate(offset, &v))
return;
- be_set_IncSP_offset(node, (int)arm_encode_imm_w_shift(v.shifts[0], v.values[0]) * sign);
+ be_set_IncSP_offset(node, (int)arm_rol(v.values[0], v.shifts[0]) * sign);
- irg = current_ir_graph;
block = get_nodes_block(node);
align = be_get_IncSP_align(node);
for (cnt = 1; cnt < v.ops; ++cnt) {
- int value = (int)arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]);
- ir_node *next = be_new_IncSP(&arm_gp_regs[REG_SP], irg, block, node, value * sign, align);
+ int value = (int)arm_rol(v.values[cnt], v.shifts[cnt]);
+ ir_node *next = be_new_IncSP(&arm_gp_regs[REG_SP], block, node, value * sign, align);
sched_add_after(node, next);
node = next;
}
*/
static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, arm_vals *v)
{
- ir_graph *irg = current_ir_graph;
dbg_info *dbg = get_irn_dbg_info(node);
ir_node *block = get_nodes_block(node);
int cnt;
ir_node *ptr;
- ptr = new_rd_arm_Add_i(dbg, irg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
- arch_set_irn_register(arch_env, ptr, &arm_gp_regs[REG_R12]);
+ ptr = new_bd_arm_Add_i(dbg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
+ arch_set_irn_register(ptr, &arm_gp_regs[REG_R12]);
sched_add_before(node, ptr);
for (cnt = 1; cnt < v->ops; ++cnt) {
long value = arm_encode_imm_w_shift(v->shifts[cnt], v->values[cnt]);
- ir_node *next = new_rd_arm_Add_i(dbg, irg, block, ptr, mode_Iu, value);
- arch_set_irn_register(arch_env, next, &arm_gp_regs[REG_R12]);
+ ir_node *next = new_bd_arm_Add_i(dbg, block, ptr, mode_Iu, value);
+ arch_set_irn_register(next, &arm_gp_regs[REG_R12]);
sched_add_before(node, next);
ptr = next;
}
*/
static ir_node *gen_ptr_sub(ir_node *node, ir_node *frame, arm_vals *v)
{
- ir_graph *irg = current_ir_graph;
dbg_info *dbg = get_irn_dbg_info(node);
ir_node *block = get_nodes_block(node);
int cnt;
ir_node *ptr;
- ptr = new_rd_arm_Sub_i(dbg, irg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
- arch_set_irn_register(arch_env, ptr, &arm_gp_regs[REG_R12]);
+ ptr = new_bd_arm_Sub_i(dbg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
+ arch_set_irn_register(ptr, &arm_gp_regs[REG_R12]);
sched_add_before(node, ptr);
for (cnt = 1; cnt < v->ops; ++cnt) {
long value = arm_encode_imm_w_shift(v->shifts[cnt], v->values[cnt]);
- ir_node *next = new_rd_arm_Sub_i(dbg, irg, block, ptr, mode_Iu, value);
- arch_set_irn_register(arch_env, next, &arm_gp_regs[REG_R12]);
+ ir_node *next = new_bd_arm_Sub_i(dbg, block, ptr, mode_Iu, value);
+ arch_set_irn_register(next, &arm_gp_regs[REG_R12]);
sched_add_before(node, next);
ptr = next;
}
if (mode_is_float(mode)) {
if (USE_FPA(cg->isa)) {
/* transform into fpaStf */
- store = new_rd_arm_fpaStf(dbg, irg, block, ptr, value, get_irg_no_mem(irg), mode);
+ store = new_bd_arm_fpaStf(dbg, block, ptr, value, get_irg_no_mem(irg), mode);
sched_add_before(node, store);
} else {
panic("peephole_be_Spill: spill not supported for this mode");
}
} else if (mode_is_dataM(mode)) {
/* transform into Store */;
- store = new_rd_arm_Store(dbg, irg, block, ptr, value, get_irg_no_mem(irg));
+ store = new_bd_arm_Store(dbg, block, ptr, value, get_irg_no_mem(irg));
sched_add_before(node, store);
} else {
panic("peephole_be_Spill: spill not supported for this mode");
}
- be_peephole_before_exchange(node, store);
- sched_remove(node);
- exchange(node, store);
- be_peephole_after_exchange(store);
+ be_peephole_exchange(node, store);
}
/**
ir_node *block, *ptr, *frame, *load, *mem, *proj;
ir_mode *mode;
dbg_info *dbg;
- ir_graph *irg;
arm_vals v;
const arch_register_t *reg;
ptr = gen_ptr_sub(node, frame, &v);
}
- reg = arch_get_irn_register(arch_env, node);
+ reg = arch_get_irn_register(node);
mem = be_get_Reload_mem(node);
mode = get_irn_mode(node);
- irg = current_ir_graph;
dbg = get_irn_dbg_info(node);
block = get_nodes_block(node);
if (mode_is_float(mode)) {
if (USE_FPA(cg->isa)) {
/* transform into fpaLdf */
- load = new_rd_arm_fpaLdf(dbg, irg, block, ptr, mem, mode);
+ load = new_bd_arm_fpaLdf(dbg, block, ptr, mem, mode);
sched_add_before(node, load);
- proj = new_rd_Proj(dbg, irg, block, load, mode, pn_arm_fpaLdf_res);
- arch_set_irn_register(arch_env, proj, reg);
+ proj = new_rd_Proj(dbg, block, load, mode, pn_arm_fpaLdf_res);
+ arch_set_irn_register(proj, reg);
} else {
panic("peephole_be_Spill: spill not supported for this mode");
}
} else if (mode_is_dataM(mode)) {
/* transform into Store */;
- load = new_rd_arm_Load(dbg, irg, block, ptr, mem);
+ load = new_bd_arm_Load(dbg, block, ptr, mem);
sched_add_before(node, load);
- proj = new_rd_Proj(dbg, irg, block, load, mode_Iu, pn_arm_Load_res);
- arch_set_irn_register(arch_env, proj, reg);
+ proj = new_rd_Proj(dbg, block, load, mode_Iu, pn_arm_Load_res);
+ arch_set_irn_register(proj, reg);
} else {
panic("peephole_be_Spill: spill not supported for this mode");
}
- be_peephole_before_exchange(node, proj);
- sched_remove(node);
- exchange(node, proj);
- be_peephole_after_exchange(proj);
+ be_peephole_exchange(node, proj);
}
/**
/* Perform peephole-optimizations. */
void arm_peephole_optimization(arm_code_gen_t *new_cg)
{
- cg = new_cg;
- arch_env = cg->arch_env;
+ cg = new_cg;
/* register peephole optimizations */
clear_irp_opcodes_generic_func();