#include "../besched_t.h"
#include "../be.h"
#include "../beabi.h"
+#include "../bemachine.h"
#include "bearch_mips_t.h"
return 0;
}
-static entity *mips_get_frame_entity(const void *self, const ir_node *irn) {
+static ir_entity *mips_get_frame_entity(const void *self, const ir_node *irn) {
if(is_mips_load_r(irn) || is_mips_store_r(irn)) {
mips_attr_t *attr = get_mips_attr(irn);
return NULL;
}
+static void mips_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent) {
+ mips_attr_t *attr = get_mips_attr(irn);
+ assert(is_mips_load_r(irn) || is_mips_store_r(irn));
+ attr->stack_entity = ent;
+}
+
/**
* This function is called by the generic backend to correct offsets for
* nodes accessing the stack.
attr->stack_entity_offset = offset;
}
+static int mips_get_sp_bias(const void *self, const ir_node *irn) {
+ return 0;
+}
+
/* fill register allocator interface */
static const arch_irn_ops_if_t mips_irn_ops_if = {
mips_classify,
mips_get_flags,
mips_get_frame_entity,
+ mips_set_frame_entity,
mips_set_frame_offset,
- NULL
+ mips_get_sp_bias,
+ NULL, /* get_inverse */
+ NULL, /* get_op_estimated_cost */
+ NULL, /* possible_memory_operand */
+ NULL, /* perform_memory_operand */
};
mips_irn_ops_t mips_irn_ops = {
/**
* Called immediately before emit phase.
*/
-static void mips_finish_irg(ir_graph *irg, mips_code_gen_t *cg) {
- /* TODO: - fix offsets for nodes accessing stack
- - ...
- */
+static void mips_finish_irg(void *self) {
+ mips_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ dump_ir_block_graph_sched(irg, "-mips-finished");
}
cg->emit_decls = 0;
}
- mips_finish_irg(irg, cg);
- dump_ir_block_graph_sched(irg, "-mips-finished");
mips_gen_routine(out, irg, cg);
cur_reg_set = NULL;
mips_cg_init,
NULL, /* before abi introduce */
mips_prepare_graph,
+ NULL, /* spill */
mips_before_sched, /* before scheduling hook */
mips_before_ra, /* before register allocation hook */
mips_after_ra,
+ mips_finish_irg,
mips_emit_and_done
};
int initial_frame_size = env->debug ? 24 : 4;
int fp_save_offset = env->debug ? 16 : 0;
- // restore sp
- //sp = be_new_IncSP(&mips_gp_regs[REG_SP], irg, block, sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_against);
-
// copy fp to sp
sp = new_rd_mips_move(dbg, irg, block, fp, mode_Iu);
mips_set_irn_reg(NULL, sp, &mips_gp_regs[REG_SP]);
static ir_type *debug_between_type = NULL;
static ir_type *opt_between_type = NULL;
- static entity *old_fp_ent = NULL;
+ static ir_entity *old_fp_ent = NULL;
if(env->debug && debug_between_type == NULL) {
- entity *a0_ent, *a1_ent, *a2_ent, *a3_ent;
- entity *ret_addr_ent;
+ ir_entity *a0_ent, *a1_ent, *a2_ent, *a3_ent;
+ ir_entity *ret_addr_ent;
ir_type *ret_addr_type = new_type_primitive(new_id_from_str("return_addr"), mode_P);
ir_type *old_fp_type = new_type_primitive(new_id_from_str("fp"), mode_P);
ir_type *old_param_type = new_type_primitive(new_id_from_str("param"), mode_Iu);
old_fp_ent = new_entity(debug_between_type, new_id_from_str("old_fp"), old_fp_type);
ret_addr_ent = new_entity(debug_between_type, new_id_from_str("ret_addr"), ret_addr_type);
- set_entity_offset_bytes(a0_ent, 0);
- set_entity_offset_bytes(a1_ent, 4);
- set_entity_offset_bytes(a2_ent, 8);
- set_entity_offset_bytes(a3_ent, 12);
- set_entity_offset_bytes(old_fp_ent, 16);
- set_entity_offset_bytes(ret_addr_ent, 20);
+ set_entity_offset(a0_ent, 0);
+ set_entity_offset(a1_ent, 4);
+ set_entity_offset(a2_ent, 8);
+ set_entity_offset(a3_ent, 12);
+ set_entity_offset(old_fp_ent, 16);
+ set_entity_offset(ret_addr_ent, 20);
set_type_size_bytes(debug_between_type, 24);
} else if(!env->debug && opt_between_type == NULL) {
ir_type *old_fp_type = new_type_primitive(new_id_from_str("fp"), mode_P);
- entity *old_fp_ent;
+ ir_entity *old_fp_ent;
opt_between_type = new_type_class(new_id_from_str("mips_between_type"));
old_fp_ent = new_entity(opt_between_type, new_id_from_str("old_fp"), old_fp_type);
- set_entity_offset_bytes(old_fp_ent, 0);
+ set_entity_offset(old_fp_ent, 0);
set_type_size_bytes(opt_between_type, 4);
}
return get_mode_size_bytes(mode);
}
+static const be_execution_unit_t ***mips_get_allowed_execution_units(const void *self, const ir_node *irn) {
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+static const be_machine_t *mips_get_machine(const void *self) {
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+/**
+ * Returns the libFirm configuration parameter for this backend.
+ */
+static const backend_params *mips_get_libfirm_params(void) {
+ static arch_dep_params_t ad = {
+ 1, /* allow subs */
+ 0, /* Muls are fast enough on Mips */
+ 31, /* shift would be ok */
+ 0, /* no Mulhs */
+ 0, /* no Mulhu */
+ 32, /* Mulhs & Mulhu available for 32 bit */
+ };
+ static backend_params p = {
+ NULL, /* no additional opcodes */
+ NULL, /* will be set later */
+ 1, /* need dword lowering */
+ NULL, /* but yet no creator function */
+ NULL, /* context for create_intrinsic_fkt */
+ };
+
+ p.dep_param = &ad;
+ return &p;
+}
+
#ifdef WITH_LIBCORE
static void mips_register_options(lc_opt_entry_t *ent)
{
mips_get_irn_handler,
mips_get_code_generator_if,
mips_get_list_sched_selector,
+ mips_get_ilp_sched_selector,
mips_get_reg_class_alignment,
+ mips_get_libfirm_params,
+ mips_get_allowed_execution_units,
+ mips_get_machine,
#ifdef WITH_LIBCORE
mips_register_options
#endif