#include "irgopt.h"
#include "irbitset.h"
#include "irgopt.h"
+#include "irdump.h"
#include "pdeq.h"
#include "pset.h"
#include "debug.h"
{
ir_node *block, *res;
- if(*place != NULL)
+ if (*place != NULL)
return *place;
block = get_irg_start_block(cg->irg);
&ia32_xmm_regs[REG_XMM_NOREG]);
}
-ir_node *ia32_new_Unknown_gp(ia32_code_gen_t *cg)
-{
- return create_const(cg, &cg->unknown_gp, new_bd_ia32_Unknown_GP,
- &ia32_gp_regs[REG_GP_UKNWN]);
-}
-
-ir_node *ia32_new_Unknown_vfp(ia32_code_gen_t *cg)
-{
- return create_const(cg, &cg->unknown_vfp, new_bd_ia32_Unknown_VFP,
- &ia32_vfp_regs[REG_VFP_UKNWN]);
-}
-
-ir_node *ia32_new_Unknown_xmm(ia32_code_gen_t *cg)
-{
- return create_const(cg, &cg->unknown_xmm, new_bd_ia32_Unknown_XMM,
- &ia32_xmm_regs[REG_XMM_UKNWN]);
-}
-
ir_node *ia32_new_Fpu_truncate(ia32_code_gen_t *cg)
{
return create_const(cg, &cg->fpu_trunc_mode, new_bd_ia32_ChangeCW,
}
}
-/**************************************************
- * _ _ _ __
- * | | | (_)/ _|
- * _ __ ___ __ _ __ _| | | ___ ___ _| |_
- * | '__/ _ \/ _` | / _` | | |/ _ \ / __| | | _|
- * | | | __/ (_| | | (_| | | | (_) | (__ | | |
- * |_| \___|\__, | \__,_|_|_|\___/ \___| |_|_|
- * __/ |
- * |___/
- **************************************************/
static const arch_register_req_t *get_ia32_SwitchJmp_out_req(
const ir_node *node, int pos)
return;
if (is_ia32_Pop(irn) || is_ia32_PopMem(irn)) {
- ia32_code_gen_t *cg = ia32_current_cg;
- int omit_fp = be_abi_omit_fp(cg->birg->abi);
- if (omit_fp) {
+ ir_graph *irg = get_irn_irg(irn);
+ be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
+ if (layout->sp_relative) {
/* Pop nodes modify the stack pointer before calculating the
* destination address, so fix this here
*/
/* push ebp */
push = new_bd_ia32_Push(NULL, bl, noreg, noreg, *mem, curr_bp, curr_sp);
- curr_sp = new_r_Proj(bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
- *mem = new_r_Proj(bl, push, mode_M, pn_ia32_Push_M);
+ curr_sp = new_r_Proj(push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
+ *mem = new_r_Proj(push, mode_M, pn_ia32_Push_M);
/* the push must have SP out register */
arch_set_irn_register(curr_sp, arch_env->sp);
/* leave */
leave = new_bd_ia32_Leave(NULL, bl, curr_bp);
- curr_bp = new_r_Proj(bl, leave, mode_bp, pn_ia32_Leave_frame);
- curr_sp = new_r_Proj(bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
+ curr_bp = new_r_Proj(leave, mode_bp, pn_ia32_Leave_frame);
+ curr_sp = new_r_Proj(leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
} else {
ir_node *pop;
/* pop ebp */
pop = new_bd_ia32_PopEbp(NULL, bl, *mem, curr_sp);
- curr_bp = new_r_Proj(bl, pop, mode_bp, pn_ia32_Pop_res);
- curr_sp = new_r_Proj(bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
+ curr_bp = new_r_Proj(pop, mode_bp, pn_ia32_Pop_res);
+ curr_sp = new_r_Proj(pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
- *mem = new_r_Proj(bl, pop, mode_M, pn_ia32_Pop_M);
+ *mem = new_r_Proj(pop, mode_M, pn_ia32_Pop_M);
}
arch_set_irn_register(curr_sp, arch_env->sp);
arch_set_irn_register(curr_bp, arch_env->bp);
*/
static arch_inverse_t *ia32_get_inverse(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst)
{
+ (void) irn;
+ (void) i;
+ (void) inverse;
+ (void) obst;
+ return NULL;
+
+#if 0
ir_mode *mode;
ir_mode *irn_mode;
ir_node *block, *noreg, *nomem;
}
return inverse;
+#endif
}
static ir_mode *get_spill_mode_mode(const ir_mode *mode)
{
- if(mode_is_float(mode))
+ if (mode_is_float(mode))
return mode_D;
return mode_Iu;
ia32_perform_memory_operand,
};
-/**************************************************
- * _ _ __
- * | | (_)/ _|
- * ___ ___ __| | ___ __ _ ___ _ __ _| |_
- * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _|
- * | (_| (_) | (_| | __/ (_| | __/ | | | | | |
- * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
- * __/ |
- * |___/
- **************************************************/
static ir_entity *mcount = NULL;
ir_lower_mode_b(cg->irg, &lower_mode_b_config);
if (cg->dump)
- be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched);
+ dump_ir_graph(cg->irg, "lower_modeb");
if (cg->gprof) {
if (mcount == NULL) {
{
ia32_code_gen_t *cg = self;
+#ifdef FIRM_GRGEN_BE
switch (be_transformer) {
case TRANSFORMER_DEFAULT:
/* transform remaining nodes into assembler instructions */
ia32_transform_graph(cg);
break;
-#ifdef FIRM_GRGEN_BE
case TRANSFORMER_PBQP:
case TRANSFORMER_RAND:
/* transform nodes into assembler instructions by PBQP magic */
ia32_transform_graph_by_pbqp(cg);
break;
-#endif
default:
panic("invalid transformer");
}
+#else
+ ia32_transform_graph(cg);
+#endif
/* do local optimizations (mainly CSE) */
optimize_graph_df(cg->irg);
if (cg->dump)
- be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
+ dump_ir_graph(cg->irg, "transformed");
/* optimize address mode */
ia32_optimize_graph(cg);
place_code(cg->irg);
if (cg->dump)
- be_dump(cg->irg, "-place", dump_ir_block_graph_sched);
+ dump_ir_graph(cg->irg, "place");
}
ir_node *turn_back_am(ir_node *node)
ir_node *noreg;
ir_node *load = new_bd_ia32_Load(dbgi, block, base, index, mem);
- ir_node *load_res = new_rd_Proj(dbgi, block, load, mode_Iu, pn_ia32_Load_res);
+ ir_node *load_res = new_rd_Proj(dbgi, load, mode_Iu, pn_ia32_Load_res);
ia32_copy_am_attrs(load, node);
if (is_ia32_is_reload(node))
ia32_setup_fpu_mode(cg);
/* fixup flags */
- be_sched_fix_flags(cg->birg, &ia32_reg_classes[CLASS_ia32_flags],
+ be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags],
&flags_remat);
ia32_add_missing_keeps(cg);
DBG_OPT_RELOAD2LD(node, new_op);
- proj = new_rd_Proj(dbg, block, new_op, mode, pn_ia32_Load_res);
+ proj = new_rd_Proj(dbg, new_op, mode, pn_ia32_Load_res);
if (sched_point) {
sched_add_after(sched_point, new_op);
sched_point = sched_prev(node);
}
- /* No need to spill unknown values... */
- if(is_ia32_Unknown_GP(val) ||
- is_ia32_Unknown_VFP(val) ||
- is_ia32_Unknown_XMM(val)) {
- store = nomem;
- if(sched_point)
- sched_remove(node);
-
- exchange(node, store);
- return;
- }
-
if (mode_is_float(mode)) {
if (ia32_cg_config.use_sse2)
store = new_bd_ia32_xStore(dbg, block, ptr, noreg, nomem, val);
static ir_node* create_spproj(ir_node *node, ir_node *pred, int pos)
{
dbg_info *dbg = get_irn_dbg_info(node);
- ir_node *block = get_nodes_block(node);
ir_mode *spmode = mode_Iu;
const arch_register_t *spreg = &ia32_gp_regs[REG_ESP];
ir_node *sp;
- sp = new_rd_Proj(dbg, block, pred, spmode, pos);
+ sp = new_rd_Proj(dbg, pred, spmode, pos);
arch_set_irn_register(sp, spreg);
return sp;
static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node)
{
ir_node *block = get_nodes_block(node);
- ir_node *sp = be_abi_get_ignore_irn(cg->birg->abi, &ia32_gp_regs[REG_ESP]);
+ ir_node *sp = be_abi_get_ignore_irn(be_get_irg_abi(cg->irg), &ia32_gp_regs[REG_ESP]);
int arity = be_get_MemPerm_entity_arity(node);
ir_node **pops = ALLOCAN(ir_node*, arity);
ir_node *in[1];
const ir_edge_t *next;
/* create Pushs */
- for(i = 0; i < arity; ++i) {
+ for (i = 0; i < arity; ++i) {
ir_entity *inent = be_get_MemPerm_in_entity(node, i);
ir_entity *outent = be_get_MemPerm_out_entity(node, i);
ir_type *enttype = get_entity_type(inent);
ir_node *push;
/* work around cases where entities have different sizes */
- if(entsize2 < entsize)
+ if (entsize2 < entsize)
entsize = entsize2;
assert( (entsize == 4 || entsize == 8) && "spillslot on x86 should be 32 or 64 bit");
push = create_push(cg, node, node, sp, mem, inent);
sp = create_spproj(node, push, pn_ia32_Push_stack);
- if(entsize == 8) {
+ if (entsize == 8) {
/* add another push after the first one */
push = create_push(cg, node, node, sp, mem, inent);
add_ia32_am_offs_int(push, 4);
}
/* create pops */
- for(i = arity - 1; i >= 0; --i) {
+ for (i = arity - 1; i >= 0; --i) {
ir_entity *inent = be_get_MemPerm_in_entity(node, i);
ir_entity *outent = be_get_MemPerm_out_entity(node, i);
ir_type *enttype = get_entity_type(outent);
ir_node *pop;
/* work around cases where entities have different sizes */
- if(entsize2 < entsize)
+ if (entsize2 < entsize)
entsize = entsize2;
assert( (entsize == 4 || entsize == 8) && "spillslot on x86 should be 32 or 64 bit");
pop = create_pop(cg, node, node, sp, outent);
sp = create_spproj(node, pop, pn_ia32_Pop_stack);
- if(entsize == 8) {
+ if (entsize == 8) {
add_ia32_am_offs_int(pop, 4);
/* add another pop after the first one */
/* remove memperm */
arity = get_irn_arity(node);
- for(i = 0; i < arity; ++i) {
+ for (i = 0; i < arity; ++i) {
set_irn_n(node, i, new_Bad());
}
sched_remove(node);
{
ia32_code_gen_t *cg = self;
ir_graph *irg = cg->irg;
- be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->birg);
+ be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->irg);
/* create and coalesce frame entities */
irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env);
/* we might have to rewrite x87 virtual registers */
if (cg->do_x87_sim) {
- x87_simulate_graph(cg->birg);
+ x87_simulate_graph(cg->irg);
}
/* do peephole optimisations */
/* create block schedule, this also removes empty blocks which might
* produce critical edges */
- cg->blk_sched = be_create_block_schedule(irg, cg->birg->exec_freq);
+ cg->blk_sched = be_create_block_schedule(irg);
}
/**
return get_eip;
}
-static void *ia32_cg_init(be_irg_t *birg);
+static void *ia32_cg_init(ir_graph *irg);
static const arch_code_generator_if_t ia32_code_gen_if = {
ia32_cg_init,
/**
* Initializes a IA32 code generator.
*/
-static void *ia32_cg_init(be_irg_t *birg)
+static void *ia32_cg_init(ir_graph *irg)
{
- ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env;
+ ia32_isa_t *isa = (ia32_isa_t *)be_get_irg_arch_env(irg);
ia32_code_gen_t *cg = XMALLOCZ(ia32_code_gen_t);
cg->impl = &ia32_code_gen_if;
- cg->irg = birg->irg;
+ cg->irg = irg;
cg->isa = isa;
- cg->birg = birg;
cg->blk_sched = NULL;
- cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
- cg->gprof = (birg->main_env->options->gprof) ? 1 : 0;
+ cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
+ cg->gprof = (be_get_irg_options(irg)->gprof) ? 1 : 0;
if (cg->gprof) {
/* Linux gprof implementation needs base pointer */
- birg->main_env->options->omit_fp = 0;
+ be_get_irg_options(irg)->omit_fp = 0;
}
/* enter it */
}
-
-/*****************************************************************
- * ____ _ _ _____ _____
- * | _ \ | | | | |_ _|/ ____| /\
- * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \
- * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \
- * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \
- * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\
- *
- *****************************************************************/
-
/**
* Set output modes for GCC
*/
NULL, /* main environment */
7, /* costs for a spill instruction */
5, /* costs for a reload instruction */
+ false, /* no custom abi handling */
},
NULL, /* 16bit register names */
NULL, /* 8bit register names */
isa = XMALLOC(ia32_isa_t);
memcpy(isa, &ia32_isa_template, sizeof(*isa));
- if(mode_fpcw == NULL) {
+ if (mode_fpcw == NULL) {
mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0);
}
/* needed for the debug support */
be_gas_emit_switch_section(GAS_SECTION_TEXT);
- be_emit_cstring(".Ltext0:\n");
+ be_emit_irprintf("%stext0:\n", be_gas_get_private_prefix());
be_emit_write_line();
return &isa->arch_env;
* @param mode The mode in question.
* @return A register class which can hold values of the given mode.
*/
-const arch_register_class_t *ia32_get_reg_class_for_mode(const ir_mode *mode)
+static const arch_register_class_t *ia32_get_reg_class_for_mode(const ir_mode *mode)
{
if (mode_is_float(mode)) {
return ia32_cg_config.use_sse2 ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
reg = ia32_get_RegParam_reg(cc, regnum, mode);
}
if (reg != NULL) {
- be_abi_call_param_reg(abi, i, reg);
+ be_abi_call_param_reg(abi, i, reg, ABI_CONTEXT_BOTH);
++regnum;
} else {
/* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes.
if (size < 4) load_mode = mode_Iu;
}
- be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0);
+ be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0, ABI_CONTEXT_BOTH);
}
}
assert(!mode_is_float(mode) && "mixed INT, FP results not supported");
- be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
- be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
+ be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX], ABI_CONTEXT_BOTH);
+ be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX], ABI_CONTEXT_BOTH);
}
else if (n == 1) {
const arch_register_t *reg;
reg = mode_is_float(mode) ? &ia32_vfp_regs[REG_VF0] : &ia32_gp_regs[REG_EAX];
- be_abi_call_res_reg(abi, 0, reg);
+ be_abi_call_res_reg(abi, 0, reg, ABI_CONTEXT_BOTH);
}
}
-int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn)
+static int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
- if(!is_ia32_irn(irn)) {
+ if (!is_ia32_irn(irn)) {
return -1;
}
- if(is_ia32_NoReg_GP(irn) || is_ia32_NoReg_VFP(irn) || is_ia32_NoReg_XMM(irn)
- || is_ia32_Unknown_GP(irn) || is_ia32_Unknown_XMM(irn)
- || is_ia32_Unknown_VFP(irn) || is_ia32_ChangeCW(irn)
- || is_ia32_Immediate(irn))
+ if (is_ia32_NoReg_GP(irn) || is_ia32_NoReg_VFP(irn) || is_ia32_NoReg_XMM(irn)
+ || is_ia32_ChangeCW(irn) || is_ia32_Immediate(irn))
return 0;
return 1;
&& mode != mode_b)
return false;
- if (is_Const(mux_true) && is_Const_one(mux_true)
- && is_Const(mux_false) && is_Const_null(mux_false)) {
- return true;
- }
- if (is_Const(mux_true) && is_Const_null(mux_true)
- && is_Const(mux_false) && is_Const_one(mux_false)) {
+ if (is_Const(mux_true) && is_Const(mux_false)) {
+ /* we can create a set plus up two 3 instructions for any combination of constants */
return true;
}
/* mov ecx,<env> */
st = new_r_Store(block, mem, p, new_Const_long(mode_Bu, 0xb9), 0);
- mem = new_r_Proj(block, st, mode_M, pn_Store_M);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
p = new_r_Add(block, p, new_Const_long(mode_Iu, 1), mode);
st = new_r_Store(block, mem, p, env, 0);
- mem = new_r_Proj(block, st, mode_M, pn_Store_M);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
p = new_r_Add(block, p, new_Const_long(mode_Iu, 4), mode);
/* jmp <callee> */
st = new_r_Store(block, mem, p, new_Const_long(mode_Bu, 0xe9), 0);
- mem = new_r_Proj(block, st, mode_M, pn_Store_M);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
p = new_r_Add(block, p, new_Const_long(mode_Iu, 1), mode);
st = new_r_Store(block, mem, p, callee, 0);
- mem = new_r_Proj(block, st, mode_M, pn_Store_M);
+ mem = new_r_Proj(st, mode_M, pn_Store_M);
p = new_r_Add(block, p, new_Const_long(mode_Iu, 4), mode);
return mem;
ia32_is_valid_clobber
};
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);
void be_init_arch_ia32(void)
{
lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
ia32_init_x87();
ia32_init_architecture();
}
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);