X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Ffirm%2Fbearch_firm.c;h=a808ad854e85890120338963f0c610ff145e38b6;hb=205396c4f4f5abe7abd6dc2350c8c398a7623afc;hp=ed68e6a64c7cc41c14e55713c6970d93d38d1a72;hpb=7507003420c69d2a84403d07daf26a305c631b43;p=libfirm diff --git a/ir/be/firm/bearch_firm.c b/ir/be/firm/bearch_firm.c index ed68e6a64..a808ad854 100644 --- a/ir/be/firm/bearch_firm.c +++ b/ir/be/firm/bearch_firm.c @@ -1,4 +1,3 @@ - /** * ISA implementation for Firm IR nodes. */ @@ -6,10 +5,6 @@ #include "config.h" #endif -#ifdef WITH_LIBCORE -#include -#endif - #include "bitset.h" #include "obst.h" @@ -20,10 +15,13 @@ #include "ircons_t.h" #include "irgwalk.h" #include "type.h" +#include "irtools.h" -#include "../bearch.h" +#include "../be_t.h" +#include "../bearch_t.h" #include "../besched.h" #include "../beutil.h" +#include "../beabi.h" #define N_REGS 3 @@ -38,7 +36,7 @@ typedef struct { static arch_register_t datab_regs[N_REGS]; static arch_register_class_t reg_classes[] = { - { "datab", N_REGS, datab_regs }, + { "datab", N_REGS, NULL, datab_regs }, }; static ir_op *op_push; @@ -120,14 +118,14 @@ static int dump_node_Imm(ir_node *n, FILE *F, dump_reason_t reason) { return bad; } -static void *firm_init(void) +static void *firm_init(FILE *outfile) { static struct obstack obst; static int inited = 0; - arch_isa_t *isa = malloc(sizeof(*isa)); + arch_isa_t *isa = xmalloc(sizeof(*isa)); int k; - isa->impl = &firm_isa; + isa->impl = &firm_isa; if(inited) return NULL; @@ -136,9 +134,10 @@ static void *firm_init(void) obstack_init(&obst); for(k = 0; k < N_CLASSES; ++k) { - const arch_register_class_t *cls = ®_classes[k]; + arch_register_class_t *cls = ®_classes[k]; int i; + cls->mode = mode_Is; for(i = 0; i < cls->n_regs; ++i) { int n; char buf[8]; @@ -196,23 +195,71 @@ static const arch_register_class_t *firm_get_reg_class(const void *self, int i) return ®_classes[i]; } +static const arch_register_class_t *firm_get_reg_class_for_mode(const void *self, const ir_mode *irm) +{ + return mode_is_datab(irm) ? ®_classes[CLS_DATAB] : NULL; +} + +static ir_type *firm_abi_get_between_type(void *self) { + static ir_type *between_type = NULL; + + if(!between_type) { + between_type = new_type_class(new_id_from_str("firm_be_between")); + set_type_size_bytes(between_type, 0); + } + + return between_type; +} + +static const be_abi_callbacks_t firm_abi_callbacks = { + NULL, + NULL, + firm_abi_get_between_type, + NULL, + NULL, + NULL, +}; + +static void firm_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) +{ + const arch_register_class_t *cls = ®_classes[CLS_DATAB]; + int i, n; + be_abi_call_flags_t flags = { { 0, 0, 0, 0, 0 } }; + + + for(i = 0, n = get_method_n_params(method_type); i < n; ++i) { + ir_type *t = get_method_param_type(method_type, i); + if(is_Primitive_type(t)) + be_abi_call_param_reg(abi, i, &cls->regs[i]); + else + be_abi_call_param_stack(abi, i, 1, 0, 0); + } + + for(i = 0, n = get_method_n_ress(method_type); i < n; ++i) { + ir_type *t = get_method_res_type(method_type, i); + if(is_Primitive_type(t)) + be_abi_call_res_reg(abi, i, &cls->regs[i]); + } + + flags.val = 0; + be_abi_call_set_flags(abi, flags, &firm_abi_callbacks); +} + + static const arch_register_req_t firm_std_reg_req = { arch_register_req_type_normal, ®_classes[CLS_DATAB], - NULL, - NULL + 0, + 0 }; static const arch_register_req_t * -firm_get_irn_reg_req(const arch_irn_ops_t *self, - arch_register_req_t *req, const ir_node *irn, int pos) +firm_get_irn_reg_req(const void *self, const ir_node *irn, int pos) { if(is_firm_be_mode(get_irn_mode(irn))) - memcpy(req, &firm_std_reg_req, sizeof(*req)); - else - req = NULL; + return &firm_std_reg_req; - return req; + return NULL; } struct irn_reg_assoc { @@ -242,19 +289,19 @@ static struct irn_reg_assoc *get_irn_reg_assoc(const ir_node *irn) return set_insert(reg_set, &templ, sizeof(templ), HASH_PTR(irn)); } -static void firm_set_irn_reg(const arch_irn_ops_t *self, ir_node *irn, const arch_register_t *reg) +static void firm_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) { struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn); assoc->reg = reg; } -static const arch_register_t *firm_get_irn_reg(const arch_irn_ops_t *self, const ir_node *irn) +static const arch_register_t *firm_get_irn_reg(const void *self, const ir_node *irn) { struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn); return assoc->reg; } -static arch_irn_class_t firm_classify(const arch_irn_ops_t *self, const ir_node *irn) +static arch_irn_class_t firm_classify(const void *self, const ir_node *irn) { arch_irn_class_t res; @@ -263,6 +310,9 @@ static arch_irn_class_t firm_classify(const arch_irn_ops_t *self, const ir_node case iro_Jmp: res = arch_irn_class_branch; break; + case iro_Call: + res = arch_irn_class_call; + break; default: res = arch_irn_class_normal; } @@ -270,9 +320,9 @@ static arch_irn_class_t firm_classify(const arch_irn_ops_t *self, const ir_node return res; } -static arch_irn_flags_t firm_get_flags(const arch_irn_ops_t *self, const ir_node *irn) +static arch_irn_flags_t firm_get_flags(const void *self, const ir_node *irn) { - arch_irn_flags_t res = arch_irn_flags_spillable; + arch_irn_flags_t res = 0; if(get_irn_op(irn) == op_imm) res |= arch_irn_flags_rematerializable; @@ -295,22 +345,46 @@ static arch_irn_flags_t firm_get_flags(const arch_irn_ops_t *self, const ir_node return res; } -static const arch_irn_ops_t irn_ops = { - firm_get_irn_reg_req, - firm_set_irn_reg, - firm_get_irn_reg, - firm_classify, - firm_get_flags +static void firm_set_stack_bias(const void *self, ir_node *irn, int bias) +{ +} + +static ir_entity *firm_get_frame_entity(const void *self, const ir_node *irn) +{ + return NULL; +} + +static void firm_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent) +{ +} + +static const arch_irn_ops_if_t firm_irn_ops_if = { + firm_get_irn_reg_req, + firm_set_irn_reg, + firm_get_irn_reg, + firm_classify, + firm_get_flags, + firm_get_frame_entity, + firm_set_frame_entity, + firm_set_stack_bias, + NULL, /* get_inverse */ + NULL, /* get_op_estimated_cost */ + NULL, /* possible_memory_operand */ + NULL, /* perform_memory_operand */ +}; + +static const arch_irn_ops_t firm_irn_ops = { + &firm_irn_ops_if }; -static const arch_irn_ops_t *firm_get_irn_ops(const arch_irn_handler_t *self, - const ir_node *irn) +static const void *firm_get_irn_ops(const arch_irn_handler_t *self, + const ir_node *irn) { - return &irn_ops; + return &firm_irn_ops; } const arch_irn_handler_t firm_irn_handler = { - firm_get_irn_ops, + firm_get_irn_ops, }; static ir_node *new_Push(ir_graph *irg, ir_node *bl, ir_node *push, ir_node *arg) @@ -352,7 +426,7 @@ static ir_node *new_Imm(ir_graph *irg, ir_node *bl, ir_node *cnst) { static void prepare_walker(ir_node *irn, void *data) { - opcode opc = get_irn_opcode(irn); + ir_opcode opc = get_irn_opcode(irn); /* A replacement for this node has already been computed. */ if(get_irn_link(irn)) @@ -409,8 +483,8 @@ static void localize_const_walker(ir_node *irn, void *data) ir_node *bl = get_nodes_block(irn); for(i = 0, n = get_irn_arity(irn); i < n; ++i) { - ir_node *op = get_irn_n(irn, i); - opcode opc = get_irn_opcode(op); + ir_node *op = get_irn_n(irn, i); + ir_opcode opc = get_irn_opcode(op); if(opc == iro_Const || opc == iro_Unknown @@ -436,16 +510,11 @@ typedef struct _firm_code_gen_t { } firm_code_gen_t; -static void clear_link(ir_node *irn, void *data) -{ - set_irn_link(irn, NULL); -} - static void firm_prepare_graph(void *self) { firm_code_gen_t *cg = self; - irg_walk_graph(cg->irg, clear_link, localize_const_walker, NULL); + irg_walk_graph(cg->irg, firm_clear_link, localize_const_walker, NULL); irg_walk_graph(cg->irg, NULL, prepare_walker, NULL); } @@ -486,54 +555,115 @@ static void firm_before_ra(void *self) irg_walk_graph(cg->irg, imm_scheduler, NULL, NULL); } +static void firm_after_ra(void *self) +{ +} + static void firm_codegen_done(void *self) { free(self); } -static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env); +static void *firm_cg_init(be_irg_t *birg); -static const arch_code_generator_if_t firm_code_gen = { +static const arch_code_generator_if_t firm_code_gen_if = { firm_cg_init, + NULL, firm_prepare_graph, + NULL, /* spill */ firm_before_sched, firm_before_ra, + firm_after_ra, firm_codegen_done }; -static void *firm_cg_init(FILE *file_handle, ir_graph *irg, const arch_env_t *env) +static void *firm_cg_init(be_irg_t *birg) { firm_code_gen_t *cg = xmalloc(sizeof(*cg)); - cg->impl = &firm_code_gen; - cg->irg = irg; + cg->impl = &firm_code_gen_if; + cg->irg = be_get_birg_irg(birg); return cg; } -static const arch_code_generator_if_t *firm_get_code_generator(void *self) +static const arch_code_generator_if_t *firm_get_code_generator_if(void *self) { - return &firm_code_gen; + return &firm_code_gen_if; } -static const list_sched_selector_t *firm_get_list_sched_selector(const void *self) { +static const list_sched_selector_t *firm_get_list_sched_selector(const void *self, list_sched_selector_t *selector) { return trivial_selector; } -#ifdef WITH_LIBCORE -static void firm_register_options(lc_opt_entry_t *ent) -{ +static const ilp_sched_selector_t *firm_get_ilp_sched_selector(const void *self) { + return NULL; +} + +/** + * Returns the necessary byte alignment for storing a register of given class. + */ +static int firm_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) { + ir_mode *mode = arch_register_class_mode(cls); + return get_mode_size_bytes(mode); +} + +static const be_execution_unit_t ***firm_get_allowed_execution_units(const void *self, const ir_node *irn) { + /* TODO */ + assert(0); + return NULL; +} + +static const be_machine_t *firm_get_machine(const void *self) { + /* TODO */ + assert(0); + return NULL; +} + +/** + * Return irp irgs in the desired order. + */ +static ir_graph **firm_get_irg_list(const void *self, ir_graph ***irg_list) { + return NULL; +} + +/** + * Returns the libFirm configuration parameter for this backend. + */ +static const backend_params *firm_get_libfirm_params(void) { + static arch_dep_params_t ad = { + 1, /* allow subs */ + 0, /* Muls are fast enough on Firm */ + 31, /* shift would be ok */ + 0, /* no Mulhs */ + 0, /* no Mulhu */ + 0, /* no Mulh */ + }; + static backend_params p = { + NULL, /* no additional opcodes */ + NULL, /* will be set later */ + 0, /* no dword lowering */ + NULL, /* no creator function */ + NULL, /* context for create_intrinsic_fkt */ + }; + + p.dep_param = &ad; + return &p; } -#endif const arch_isa_if_t firm_isa = { -#ifdef WITH_LIBCORE - firm_register_options, -#endif firm_init, firm_done, firm_get_n_reg_class, firm_get_reg_class, + firm_get_reg_class_for_mode, + firm_get_call_abi, firm_get_irn_handler, - firm_get_code_generator, - firm_get_list_sched_selector + firm_get_code_generator_if, + firm_get_list_sched_selector, + firm_get_ilp_sched_selector, + firm_get_reg_class_alignment, + firm_get_libfirm_params, + firm_get_allowed_execution_units, + firm_get_machine, + firm_get_irg_list, };