Commit ff73e39f authored by Christian Würdig's avatar Christian Würdig
Browse files

addapted to new be abi and added code changes

parent 65c24f5f
......@@ -86,8 +86,6 @@ static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
ir_node *proj;
const arch_register_t *reg = NULL;
assert(get_irn_n_edges(irn) > pos && "Invalid OUT position");
/* 1st case: irn is not of mode_T, so it has only */
/* one OUT register -> good */
/* 2nd case: irn is of mode_T -> collect all Projs and ask the */
......@@ -168,8 +166,7 @@ static int TEMPLATE_get_reg_name(lc_appendable_t *app,
buf = get_TEMPLATE_reg_name(X, nr, 0);
}
lc_appendable_chadd(app, '%');
return lc_arg_append(app, occ, buf, strlen(buf));
return buf ? lc_arg_append(app, occ, buf, strlen(buf)) : 0;
}
/**
......@@ -270,66 +267,49 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
***********************************************************************************/
/**
* Emits code for a node.
* Enters the emitter functions for handled nodes into the generic
* pointer of an opcode.
*/
void TEMPLATE_emit_node(ir_node *irn, void *env) {
emit_env_t *emit_env = env;
firm_dbg_module_t *mod = emit_env->mod;
FILE *F = emit_env->out;
DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
#define BE_EMIT(a) if (is_TEMPLATE_##a(irn)) { emit_TEMPLATE_##a(irn, emit_env); return; }
BE_EMIT(Const);
BE_EMIT(Add);
BE_EMIT(Add_i);
BE_EMIT(Sub);
BE_EMIT(Sub_i);
BE_EMIT(Minus);
BE_EMIT(Inc);
BE_EMIT(Dec);
BE_EMIT(And);
BE_EMIT(And_i);
BE_EMIT(Or);
BE_EMIT(Or_i);
BE_EMIT(Eor);
BE_EMIT(Eor_i);
BE_EMIT(Not);
static void TEMPLATE_register_emitters(void) {
BE_EMIT(Shl);
BE_EMIT(Shl_i);
BE_EMIT(Shr);
BE_EMIT(Shr_i);
BE_EMIT(RotL);
BE_EMIT(RotL_i);
BE_EMIT(RotR);
/* some convienience macros to register additional emitter functions
(other than the generated ones) */
#define TEMPLATE_EMIT(a) op_TEMPLATE_##a->ops.generic = (op_func)emit_TEMPLATE_##a
#define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
#define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
BE_EMIT(Mul);
BE_EMIT(Mul_i);
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func();
BE_EMIT(Store);
BE_EMIT(Load);
/* register all emitter functions defined in spec */
TEMPLATE_register_spec_emitters();
/* generated floating point emitter */
BE_EMIT(fConst);
/* register addtional emitter functions if needed */
BE_EMIT(fAdd);
BE_EMIT(fSub);
BE_EMIT(fMinus);
#undef TEMPLATE_EMIT
#undef BE_EMIT
#undef EMIT
}
BE_EMIT(fMul);
BE_EMIT(fDiv);
BE_EMIT(fMin);
BE_EMIT(fMax);
/**
* Emits code for a node.
*/
void TEMPLATE_emit_node(ir_node *irn, void *env) {
emit_env_t *emit_env = env;
firm_dbg_module_t *mod = emit_env->mod;
FILE *F = emit_env->out;
ir_op *op = get_irn_op(irn);
BE_EMIT(fLoad);
BE_EMIT(fStore);
DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
ir_fprintf(F, "\t\t\t\t\t/* %+F */\n", irn);
if (op->ops.generic) {
void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic;
(*emit)(irn, env);
}
else {
ir_fprintf(F, "\t\t\t\t\t/* %+F */\n", irn);
}
}
/**
......@@ -352,7 +332,7 @@ void TEMPLATE_gen_block(ir_node *block, void *env) {
/**
* Emits code for function start.
*/
void TEMPLATE_emit_start(FILE *F, ir_graph *irg) {
void TEMPLATE_emit_func_prolog(FILE *F, ir_graph *irg) {
const char *irg_name = get_entity_name(get_irg_entity(irg));
/* TODO: emit function header */
......@@ -361,7 +341,7 @@ void TEMPLATE_emit_start(FILE *F, ir_graph *irg) {
/**
* Emits code for function end
*/
void TEMPLATE_emit_end(FILE *F, ir_graph *irg) {
void TEMPLATE_emit_func_epilog(FILE *F, ir_graph *irg) {
const char *irg_name = get_entity_name(get_irg_entity(irg));
/* TODO: emit function end */
......@@ -395,8 +375,11 @@ void TEMPLATE_gen_routine(FILE *F, ir_graph *irg, const TEMPLATE_code_gen_t *cg)
/* set the global arch_env (needed by print hooks) */
arch_env = cg->arch_env;
TEMPLATE_emit_start(F, irg);
/* register all emitter functions */
TEMPLATE_register_emitters();
TEMPLATE_emit_func_prolog(F, irg);
irg_block_walk_graph(irg, TEMPLATE_gen_labels, NULL, &emit_env);
irg_walk_blkwise_graph(irg, NULL, TEMPLATE_gen_block, &emit_env);
TEMPLATE_emit_end(F, irg);
TEMPLATE_emit_func_epilog(F, irg);
}
......@@ -278,49 +278,14 @@ static void TEMPLATE_before_sched(void *self) {
}
static void TEMPLATE_before_ra(void *self) {
/* Some stuff you need to do immediatly after register allocation */
/* Some stuff you need to do after scheduling but before register allocation */
}
/**
* Creates a Store for a Spill
*/
static ir_node *TEMPLATE_lower_spill(void *self, ir_node *spill) {
TEMPLATE_code_gen_t *cg = self;
dbg_info *dbg = get_irn_dbg_info(spill);
ir_node *block = get_nodes_block(spill);
ir_node *ptr = get_irg_frame(cg->irg);
ir_node *val = be_get_Spill_context(spill);
ir_node *mem = new_rd_NoMem(cg->irg);
ir_mode *mode = get_irn_mode(spill);
ir_node *res;
entity *ent = be_get_spill_entity(spill);
unsigned offs = get_entity_offset_bytes(ent);
DB((cg->mod, LEVEL_1, "lower_spill: got offset %d for %+F\n", offs, ent));
/* TODO: create Store */
return res;
static void TEMPLATE_after_ra(void *self) {
/* Some stuff you need to do immediatly after register allocation */
}
/**
* Create a Load for a Spill
*/
static ir_node *TEMPLATE_lower_reload(void *self, ir_node *reload) {
TEMPLATE_code_gen_t *cg = self;
dbg_info *dbg = get_irn_dbg_info(reload);
ir_node *block = get_nodes_block(reload);
ir_node *ptr = get_irg_frame(cg->irg);
ir_mode *mode = get_irn_mode(reload);
ir_node *pred = get_irn_n(reload, 0);
tarval *tv;
ir_node *res;
/* TODO: create Load */
return res;
}
/**
* Emits the code, closes the output file and frees
......@@ -354,8 +319,7 @@ static const arch_code_generator_if_t TEMPLATE_code_gen_if = {
TEMPLATE_prepare_graph,
TEMPLATE_before_sched, /* before scheduling hook */
TEMPLATE_before_ra, /* before register allocation hook */
TEMPLATE_lower_spill,
TEMPLATE_lower_reload,
TEMPLATE_after_ra, /* after register allocation hook */
TEMPLATE_emit_and_done
};
......@@ -504,12 +468,20 @@ void TEMPLATE_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t
ir_mode *mode;
int i, n = get_method_n_params(method_type);
const arch_register_t *reg;
be_abi_call_flags_t call_flags;
/* set abi flags for calls */
call_flags.bits.left_to_right = 0;
call_flags.bits.store_args_sequential = 1;
call_flags.bits.try_omit_fp = 1;
call_flags.bits.fp_free = 0;
call_flags.bits.call_has_imm = 1;
/* get the between type and the frame pointer save entity */
between_type = get_between_type();
/* set stack parameter passing style */
be_abi_call_set_flags(abi, BE_ABI_NONE, between_type);
be_abi_call_set_flags(abi, call_flags, between_type);
for (i = 0; i < n; i++) {
/* TODO: implement register parameter: */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment