X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbearch_firm.c;h=ca9518ca0661bb22100bfe4d6ba690f9b14ed143;hb=cc7dee071c03c9841971c54222c8990035d504d0;hp=c91975bbbc00179c166dc381a0db6040c45ef7d4;hpb=e5ab50e3025460b25b6287e7bb3659d6256e38fb;p=libfirm diff --git a/ir/be/bearch_firm.c b/ir/be/bearch_firm.c index c91975bbb..ca9518ca0 100644 --- a/ir/be/bearch_firm.c +++ b/ir/be/bearch_firm.c @@ -2,25 +2,27 @@ /** * ISA implementation for Firm IR nodes. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "bitset.h" #include "bearch.h" -#define N_REGS 1024 +#include "irreflect.h" -static arch_register_t gp_regs[N_REGS]; -static arch_register_t fp_regs[N_REGS]; +#define N_REGS 64 + +static arch_register_t datab_regs[N_REGS]; static arch_register_class_t reg_classes[] = { - { "gp", NULL, N_REGS, gp_regs }, - { "fp", NULL, N_REGS, fp_regs } + { "datab", N_REGS, datab_regs }, }; #define N_CLASSES \ (sizeof(reg_classes) / sizeof(reg_classes[0])) -#define CLS_GP 0 -#define CLS_FP 0 +#define CLS_DATAB 0 static void firm_init(void) { @@ -66,45 +68,99 @@ static const arch_register_class_t *firm_get_reg_class(int i) return ®_classes[i]; } -static const arch_register_class_t *firm_get_irn_reg_class(const ir_node *irn) +static const arch_register_req_t firm_std_reg_req = { + arch_register_req_type_normal, + ®_classes[CLS_DATAB], + { NULL } +}; + +static const rflct_arg_t *get_arg(const ir_node *irn, int pos) { - ir_mode *mode = get_irn_mode(irn); + int sig = rflct_get_signature(irn); + const rflct_arg_t *args = + rflct_get_args(get_irn_opcode(irn), sig, arch_pos_is_in(pos)); + return &args[arch_pos_get_index(pos)]; +} - if(mode_is_float(mode)) - return ®_classes[CLS_FP]; - else if(mode_is_datab(mode)) - return ®_classes[CLS_GP]; +static const arch_register_req_t * +firm_get_irn_reg_req(const ir_node *irn, int pos) +{ + return mode_is_datab(get_irn_mode(irn)) ? &firm_std_reg_req : NULL; +} - return NULL; +static int firm_get_n_operands(const ir_node *irn, int in_out) +{ + int sig = rflct_get_signature(irn); + return rflct_get_args_count(get_irn_opcode(irn), sig, in_out >= 0); } -static int firm_is_reg_allocatable(const ir_node *irn, const arch_register_t *reg) +struct irn_reg_assoc { + const ir_node *irn; + int pos; + const arch_register_t *reg; +}; + +static int cmp_irn_reg_assoc(const void *a, const void *b, size_t len) { - return arch_register_get_class(reg) == firm_get_irn_reg_class(irn); + const struct irn_reg_assoc *x = a; + const struct irn_reg_assoc *y = b; + + return !(x->irn == y->irn && x->pos == y->pos); } -static int firm_get_allocatable_regs(const ir_node *irn, - const arch_register_class_t *cls, bitset_t *bs) +static struct irn_reg_assoc *get_irn_reg_assoc(const ir_node *irn, int pos) { - int i; + static set *reg_set = NULL; + struct irn_reg_assoc templ; + unsigned int hash; - if(firm_get_irn_reg_class(irn) != cls) { - bitset_clear_all(bs); - return 0; - } + if(!reg_set) + reg_set = new_set(cmp_irn_reg_assoc, 1024); - for(i = 0; i < cls->n_regs; ++i) - bitset_set_all(bs); + templ.irn = irn; + templ.pos = pos; + templ.reg = NULL; + hash = HASH_PTR(irn) + 7 * pos; - return cls->n_regs; + return set_insert(reg_set, &templ, sizeof(templ), hash); +} + +static void firm_set_irn_reg(ir_node *irn, int pos, const arch_register_t *reg) +{ + struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn, pos); + assoc->reg = reg; } -const arch_isa_if_t arch_isa_if_firm = { +static const arch_register_t *firm_get_irn_reg(const ir_node *irn, int pos) +{ + struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn, pos); + return assoc->reg; +} + +static arch_irn_class_t firm_classify(const ir_node *irn) +{ + return arch_irn_class_normal; +} + +static const arch_irn_ops_t irn_ops = { + firm_get_irn_reg_req, + firm_get_n_operands, + firm_set_irn_reg, + firm_get_irn_reg, + firm_classify +}; + +const arch_isa_if_t firm_isa = { firm_init, firm_get_n_reg_class, - firm_get_reg_class, - firm_is_reg_allocatable, - firm_get_allocatable_regs, - firm_get_irn_reg_class, - NULL + firm_get_reg_class +}; + +static const arch_irn_ops_t *firm_get_irn_ops(const ir_node *irn) +{ + return &irn_ops; +} + +const arch_irn_handler_t firm_irn_handler = { + firm_get_irn_ops, };