From: Sebastian Hack Date: Thu, 6 Apr 2006 11:19:53 +0000 (+0000) Subject: Added insn support X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=a62baf3793037f4657a37c7f298d18dfafedd1e5;p=libfirm Added insn support --- diff --git a/ir/be/beinsn.c b/ir/be/beinsn.c new file mode 100644 index 000000000..378d64501 --- /dev/null +++ b/ir/be/beinsn.c @@ -0,0 +1,96 @@ + +#include "irgraph_t.h" +#include "irmode_t.h" +#include "irnode_t.h" + +#include "besched_t.h" +#include "beinsn_t.h" + +be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn) +{ + const arch_env_t *arch_env = env->aenv; + struct obstack *obst = env->obst; + be_operand_t o; + be_insn_t *insn; + int i, n; + int pre_colored = 0; + + insn = obstack_alloc(obst, sizeof(insn[0])); + memset(insn, 0, sizeof(insn[0])); + + insn->irn = irn; + insn->next_insn = sched_next(irn); + if(get_irn_mode(irn) == mode_T) { + ir_node *p; + + for(p = sched_next(irn); is_Proj(p); p = sched_next(p)) { + if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, p)) { + arch_get_register_req(arch_env, &o.req, p, -1); + o.carrier = p; + o.irn = irn; + o.pos = -(get_Proj_proj(p) + 1); + o.partner = NULL; + o.has_constraints = arch_register_req_is(&o.req, limited); + obstack_grow(obst, &o, sizeof(o)); + insn->n_ops++; + insn->out_constraints |= o.has_constraints; + pre_colored += arch_get_irn_register(arch_env, p) != NULL; + } + } + + insn->next_insn = p; + } + + else if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, irn)) { + arch_get_register_req(arch_env, &o.req, irn, -1); + o.carrier = irn; + o.irn = irn; + o.pos = -1; + o.partner = NULL; + o.has_constraints = arch_register_req_is(&o.req, limited); + obstack_grow(obst, &o, sizeof(o)); + insn->n_ops++; + insn->out_constraints |= o.has_constraints; + pre_colored += arch_get_irn_register(arch_env, irn) != NULL; + } + + insn->pre_colored = pre_colored == insn->n_ops && insn->n_ops > 0; + insn->use_start = insn->n_ops; + + for(i = 0, n = get_irn_arity(irn); i < n; ++i) { + ir_node *op = get_irn_n(irn, i); + + if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, op)) { + arch_get_register_req(arch_env, &o.req, irn, i); + o.carrier = op; + o.irn = irn; + o.pos = i; + o.partner = NULL; + o.has_constraints = arch_register_req_is(&o.req, limited); + obstack_grow(obst, &o, sizeof(o)); + insn->n_ops++; + insn->in_constraints |= o.has_constraints; + } + } + + insn->has_constraints = insn->in_constraints | insn->out_constraints; + insn->ops = obstack_finish(obst); + + /* Compute the admissible registers bitsets. */ + for(i = 0; i < insn->n_ops; ++i) { + be_operand_t *op = &insn->ops[i]; + + assert(op->req.cls == env->cls); + op->regs = bitset_obstack_alloc(obst, env->cls->n_regs); + + if(arch_register_req_is(&op->req, limited)) + op->req.limited(op->req.limited_env, op->regs); + else { + arch_put_non_ignore_regs(arch_env, env->cls, op->regs); + bitset_andnot(op->regs, env->ignore_colors); + } + + } + + return insn; +} diff --git a/ir/be/beinsn_t.h b/ir/be/beinsn_t.h new file mode 100644 index 000000000..53fc828de --- /dev/null +++ b/ir/be/beinsn_t.h @@ -0,0 +1,52 @@ +/** + * Instructions + * + * A data structure to treat nodes and node-proj collections uniformly. + */ + +#ifndef _BEINSN_T_H +#define _BEINSN_T_H + +#include "bitset.h" + +#include "bearch.h" + +typedef struct _be_operand_t be_operand_t; +typedef struct _be_insn_t be_insn_t; +typedef struct _be_insn_env_t be_insn_env_t; + +struct _be_operand_t { + ir_node *irn; + ir_node *carrier; + be_operand_t *partner; + bitset_t *regs; + int pos; + arch_register_req_t req; + unsigned has_constraints : 1; +}; + +struct _be_insn_t { + be_operand_t *ops; + int n_ops; + int use_start; + ir_node *next_insn; + ir_node *irn; + unsigned in_constraints : 1; + unsigned out_constraints : 1; + unsigned has_constraints : 1; + unsigned pre_colored : 1; +}; + +struct _be_insn_env_t { + struct obstack *obst; + const arch_env_t *aenv; + const arch_register_class_t *cls; + bitset_t *ignore_colors; +}; + +#define be_insn_n_defs(insn) ((insn)->use_start) +#define be_insn_n_uses(insn) ((insn)->n_ops - (insn)->use_start) + +be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn); + +#endif /* _BEINSN_T_H */