The big committ:
authorMatthias Braun <matze@braunis.de>
Mon, 19 Mar 2007 17:05:21 +0000 (17:05 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 19 Mar 2007 17:05:21 +0000 (17:05 +0000)
- Replace limit callback in register requirements with a simple bitset
- Fix backends, generators and the rest of the code for the change register
  requirements structure
- Eliminated the custom register_requirement structures in the backend, they
  are pointless now, use the normal arch_register_req_t
- Fix TEMPLATE backend
- Extract emitter framework from ia32 and provide generic header/code for it
- Port TEMPLATE backend to new emitter
- Extract gas specific emit stuff (declarations, sections) from ia32 backend
  and provide it as generic header/code. Make TEMPLATE backend use that
- Remove several FIRM_DBG_REGISTERs from functions which are called very often.
  Before we had millions of string hashtable lookups because of that. The
  prefered way is to have 1 static debug module per file and initialize it in
  the module constructor. No passing around in environment structs and in no
  case should you dynamically register it in single functions.

77 files changed:
ir/be/TEMPLATE/TEMPLATE_emitter.c
ir/be/TEMPLATE/TEMPLATE_emitter.h
ir/be/TEMPLATE/TEMPLATE_gen_decls.c [deleted file]
ir/be/TEMPLATE/TEMPLATE_gen_decls.h [deleted file]
ir/be/TEMPLATE/TEMPLATE_new_nodes.c
ir/be/TEMPLATE/TEMPLATE_new_nodes.h
ir/be/TEMPLATE/TEMPLATE_nodes_attr.h
ir/be/TEMPLATE/TEMPLATE_spec.pl
ir/be/TEMPLATE/TEMPLATE_transform.c
ir/be/TEMPLATE/bearch_TEMPLATE.c
ir/be/TEMPLATE/bearch_TEMPLATE_t.h
ir/be/arm/arm_emitter.c
ir/be/arm/arm_new_nodes.c
ir/be/arm/arm_new_nodes.h
ir/be/arm/arm_nodes_attr.h
ir/be/arm/bearch_arm.c
ir/be/be_t.h
ir/be/beabi.c
ir/be/bearch.c
ir/be/bearch.h
ir/be/beblocksched.c
ir/be/bechordal.c
ir/be/becopyheur.c
ir/be/becopyheur2.c
ir/be/becopyheur3.c
ir/be/becopyilp.c
ir/be/becopyilp2.c
ir/be/becopyopt.c
ir/be/becopyopt_t.h
ir/be/beemitter.c [new file with mode: 0644]
ir/be/beemitter.h [new file with mode: 0644]
ir/be/begnuas.c [new file with mode: 0644]
ir/be/begnuas.h [new file with mode: 0644]
ir/be/beilpsched.c
ir/be/beinsn.c
ir/be/beinsn_t.h
ir/be/beirgmod.c
ir/be/belistsched.c
ir/be/belive.c
ir/be/belive_t.h
ir/be/beloopana.c
ir/be/belower.c
ir/be/bemodule.c
ir/be/benode.c
ir/be/beraextern.c
ir/be/bespillbelady.c
ir/be/bespillmorgan.c
ir/be/bespillremat.c
ir/be/bespillslots.c
ir/be/bestabs.c
ir/be/beuses.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/bearch_ia32_t.h
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_emitter.h
ir/be/ia32/ia32_finish.c
ir/be/ia32/ia32_gen_decls.c [deleted file]
ir/be/ia32/ia32_gen_decls.h [deleted file]
ir/be/ia32/ia32_new_nodes.c
ir/be/ia32/ia32_new_nodes.h
ir/be/ia32/ia32_nodes_attr.h
ir/be/ia32/ia32_spec.pl
ir/be/mips/bearch_mips.c
ir/be/mips/mips_new_nodes.c
ir/be/mips/mips_new_nodes.h
ir/be/mips/mips_nodes_attr.h
ir/be/mips/mips_spec.pl
ir/be/ppc32/bearch_ppc32.c
ir/be/ppc32/ppc32_new_nodes.c
ir/be/ppc32/ppc32_new_nodes.h
ir/be/ppc32/ppc32_nodes_attr.h
ir/be/ppc32/ppc32_transform.c
ir/be/scripts/generate_emitter.pl
ir/be/scripts/generate_emitter_new.pl
ir/be/scripts/generate_machine.pl
ir/be/scripts/generate_new_opcodes.pl
ir/be/scripts/generate_regalloc_if.pl

index 010e6d3..28c5c4b 100644 (file)
 
 #define SNPRINTF_BUF_LEN 128
 
-static const arch_env_t *arch_env = NULL;
-
-
-/*************************************************************
- *             _       _    __   _          _
- *            (_)     | |  / _| | |        | |
- *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
- * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
- * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
- * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
- * | |                                       | |
- * |_|                                       |_|
- *************************************************************/
-
-/**
- * Return a const or symconst as string.
- */
-static const char *node_const_to_str(ir_node *n) {
-       /* TODO */
-}
-
-/**
- * Returns node's offset as string.
- */
-static char *node_offset_to_str(ir_node *n) {
-       /* TODO */
-}
-
-/* We always pass the ir_node which is a pointer. */
-static int TEMPLATE_get_arg_type(const lc_arg_occ_t *occ) {
-       return lc_arg_type_ptr;
-}
-
-
 /**
  * Returns the register at in position pos.
  */
-static const arch_register_t *get_in_reg(ir_node *irn, int pos) {
+static const arch_register_t *get_in_reg(const arch_env_t *arch_env,
+                                         const ir_node *node, int pos)
+{
        ir_node                *op;
        const arch_register_t  *reg = NULL;
 
-       assert(get_irn_arity(irn) > pos && "Invalid IN position");
+       assert(get_irn_arity(node) > pos && "Invalid IN position");
 
        /* The out register of the operator at position pos is the
           in register we need. */
-       op = get_irn_n(irn, pos);
+       op = get_irn_n(node, pos);
 
        reg = arch_get_irn_register(arch_env, op);
 
@@ -82,7 +50,9 @@ static const arch_register_t *get_in_reg(ir_node *irn, int pos) {
 /**
  * Returns the register at out position pos.
  */
-static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
+static const arch_register_t *get_out_reg(const arch_env_t *arch_env,
+                                          const ir_node *node, int pos)
+{
        ir_node                *proj;
        const arch_register_t  *reg = NULL;
 
@@ -91,16 +61,14 @@ static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
        /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
        /*           Proj with the corresponding projnum for the register */
 
-       if (get_irn_mode(irn) != mode_T) {
-               reg = arch_get_irn_register(arch_env, irn);
-       }
-       else if (is_TEMPLATE_irn(irn)) {
-               reg = get_TEMPLATE_out_reg(irn, pos);
-       }
-       else {
+       if (get_irn_mode(node) != mode_T) {
+               reg = arch_get_irn_register(arch_env, node);
+       } else if (is_TEMPLATE_irn(node)) {
+               reg = get_TEMPLATE_out_reg(node, pos);
+       } else {
                const ir_edge_t *edge;
 
-               foreach_out_edge(irn, edge) {
+               foreach_out_edge(node, edge) {
                        proj = get_edge_src_irn(edge);
                        assert(is_Proj(proj) && "non-Proj from mode_T node");
                        if (get_Proj_proj(proj) == pos) {
@@ -114,148 +82,43 @@ static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
        return reg;
 }
 
-/**
- * Returns the number of the in register at position pos.
- */
-int get_TEMPLATE_reg_nr(ir_node *irn, int pos, int in_out) {
-       const arch_register_t *reg;
-
-       if (in_out == 1) {
-               reg = get_in_reg(irn, pos);
-       }
-       else {
-               reg = get_out_reg(irn, pos);
-       }
-
-       return arch_register_get_index(reg);
-}
-
-/**
- * Returns the name of the in register at position pos.
- */
-const char *get_TEMPLATE_reg_name(ir_node *irn, int pos, int in_out) {
-       const arch_register_t *reg;
-
-       if (in_out == 1) {
-               reg = get_in_reg(irn, pos);
-       }
-       else {
-               reg = get_out_reg(irn, pos);
-       }
-
-       return arch_register_get_name(reg);
-}
+/*************************************************************
+ *             _       _    __   _          _
+ *            (_)     | |  / _| | |        | |
+ *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
+ * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
+ * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
+ * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
+ * | |                                       | |
+ * |_|                                       |_|
+ *************************************************************/
 
-/**
- * Get the register name for a node.
- */
-static int TEMPLATE_get_reg_name(lc_appendable_t *app,
-    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
+void TEMPLATE_emit_immediate(TEMPLATE_emit_env_t *env, const ir_node *node)
 {
-       const char *buf;
-       ir_node    *X  = arg->v_ptr;
-       int         nr = occ->width - 1;
-
-       if (!X)
-               return lc_arg_append(app, occ, "(null)", 6);
-
-       if (occ->conversion == 'S') {
-               buf = get_TEMPLATE_reg_name(X, nr, 1);
-       }
-       else { /* 'D' */
-               buf = get_TEMPLATE_reg_name(X, nr, 0);
-       }
-
-       return buf ? lc_arg_append(app, occ, buf, strlen(buf)) : 0;
+       /* TODO */
 }
 
-/**
- * Returns the tarval or offset of an TEMPLATE node as a string.
- */
-static int TEMPLATE_const_to_str(lc_appendable_t *app,
-    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
+void TEMPLATE_emit_source_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos)
 {
-       const char *buf;
-       ir_node    *X = arg->v_ptr;
-
-       if (!X)
-               return lc_arg_append(app, occ, "(null)", 6);
-
-       if (occ->conversion == 'C') {
-               buf = node_const_to_str(X);
-       }
-       else { /* 'O' */
-               buf = node_offset_to_str(X);
-       }
-
-       return lc_arg_append(app, occ, buf, strlen(buf));
+       const arch_register_t *reg = get_in_reg(env->arch_env, node, pos);
+       be_emit_string(env->emit, arch_register_get_name(reg));
 }
 
-/**
- * Determines the SSE suffix depending on the mode.
- */
-static int TEMPLATE_get_mode_suffix(lc_appendable_t *app,
-    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
+void TEMPLATE_emit_dest_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos)
 {
-       ir_node *X = arg->v_ptr;
-
-       if (!X)
-               return lc_arg_append(app, occ, "(null)", 6);
-
-       if (get_mode_size_bits(get_irn_mode(X)) == 32)
-               return lc_appendable_chadd(app, 's');
-       else
-               return lc_appendable_chadd(app, 'd');
-}
-
-/**
- * Return the TEMPLATE printf arg environment.
- * We use the firm environment with some additional handlers.
- */
-const lc_arg_env_t *TEMPLATE_get_arg_env(void) {
-       static lc_arg_env_t *env = NULL;
-
-       static const lc_arg_handler_t TEMPLATE_reg_handler   = { TEMPLATE_get_arg_type, TEMPLATE_get_reg_name };
-       static const lc_arg_handler_t TEMPLATE_const_handler = { TEMPLATE_get_arg_type, TEMPLATE_const_to_str };
-       static const lc_arg_handler_t TEMPLATE_mode_handler  = { TEMPLATE_get_arg_type, TEMPLATE_get_mode_suffix };
-
-       if(env == NULL) {
-               /* extend the firm printer */
-               env = firm_get_arg_env();
-                       //lc_arg_new_env();
-
-               lc_arg_register(env, "TEMPLATE:sreg", 'S', &TEMPLATE_reg_handler);
-               lc_arg_register(env, "TEMPLATE:dreg", 'D', &TEMPLATE_reg_handler);
-               lc_arg_register(env, "TEMPLATE:cnst", 'C', &TEMPLATE_const_handler);
-               lc_arg_register(env, "TEMPLATE:offs", 'O', &TEMPLATE_const_handler);
-               lc_arg_register(env, "TEMPLATE:mode", 'M', &TEMPLATE_mode_handler);
-       }
-
-       return env;
-}
-
-/*
- * Add a number to a prefix. This number will not be used a second time.
- */
-static char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
-       static unsigned long id = 0;
-       snprintf(buf, buflen, "%s%lu", prefix, ++id);
-       return buf;
+       const arch_register_t *reg = get_out_reg(env->arch_env, node, pos);
+       be_emit_string(env->emit, arch_register_get_name(reg));
 }
 
-
 /**
  * Returns the target label for a control flow node.
  */
-static char *get_cfop_target(const ir_node *irn, char *buf) {
-       ir_node *bl = get_irn_link(irn);
+static void TEMPLATE_emit_cfop_target(TEMPLATE_emit_env_t *env, const ir_node *node) {
+       ir_node *block = get_irn_link(node);
 
-       snprintf(buf, SNPRINTF_BUF_LEN, "BLOCK_%ld", get_irn_node_nr(bl));
-       return buf;
+       be_emit_irprintf(env->emit, "BLOCK_%ld", get_irn_node_nr(block));
 }
 
-
-
 /***********************************************************************************
  *                  _          __                                             _
  *                 (_)        / _|                                           | |
@@ -266,6 +129,20 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
  *
  ***********************************************************************************/
 
+/**
+ * Emits code for a unconditional jump.
+ */
+static void emit_Jmp(TEMPLATE_emit_env_t *env, const ir_node *node) {
+       ir_node *block;
+
+       /* for now, the code works for scheduled and non-schedules blocks */
+       block = get_nodes_block(node);
+
+       be_emit_cstring(env->emit, "\tjmp ");
+       TEMPLATE_emit_cfop_target(env, node);
+       be_emit_finish_line_gas(env->emit, node);
+}
+
 /**
  * Enters the emitter functions for handled nodes into the generic
  * pointer of an opcode.
@@ -285,30 +162,29 @@ static void TEMPLATE_register_emitters(void) {
        TEMPLATE_register_spec_emitters();
 
        /* register addtional emitter functions if needed */
+       EMIT(Jmp);
 
 #undef TEMPLATE_EMIT
 #undef BE_EMIT
 #undef EMIT
 }
 
+typedef void (*emit_func_ptr) (TEMPLATE_emit_env_t *, const ir_node *);
 
 /**
  * Emits code for a node.
  */
-void TEMPLATE_emit_node(ir_node *irn, void *env) {
-       TEMPLATE_emit_env_t *emit_env = env;
-       FILE                *F        = emit_env->out;
-       ir_op               *op       = get_irn_op(irn);
-       DEBUG_ONLY(firm_dbg_module_t *mod = emit_env->mod;)
+void TEMPLATE_emit_node(TEMPLATE_emit_env_t *env, const ir_node *node) {
+       ir_op               *op       = get_irn_op(node);
+       DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
 
-       DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
+       DBG((mod, LEVEL_1, "emitting code for %+F\n", node));
 
        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);
+               emit_func_ptr func = (emit_func_ptr) op->ops.generic;
+               (*func) (env, node);
+       } else {
+               ir_fprintf(stderr, "No emitter for node %+F\n", node);
        }
 }
 
@@ -316,16 +192,19 @@ void TEMPLATE_emit_node(ir_node *irn, void *env) {
  * Walks over the nodes in a block connected by scheduling edges
  * and emits code for each node.
  */
-void TEMPLATE_gen_block(ir_node *block, void *env) {
-       TEMPLATE_emit_env_t *emit_env = env;
-       ir_node *irn;
+void TEMPLATE_gen_block(ir_node *block, void *data) {
+       TEMPLATE_emit_env_t *env = data;
+       ir_node *node;
 
        if (! is_Block(block))
                return;
 
-       fprintf(emit_env->out, "BLOCK_%ld:\n", get_irn_node_nr(block));
-       sched_foreach(block, irn) {
-               TEMPLATE_emit_node(irn, env);
+       be_emit_cstring(env->emit, "BLOCK_");
+       be_emit_irprintf(env->emit, "%ld:\n", get_irn_node_nr(block));
+       be_emit_write_line(env->emit);
+
+       sched_foreach(block, node) {
+               TEMPLATE_emit_node(env, node);
        }
 }
 
@@ -333,19 +212,27 @@ void TEMPLATE_gen_block(ir_node *block, void *env) {
 /**
  * Emits code for function start.
  */
-void TEMPLATE_emit_func_prolog(FILE *F, ir_graph *irg) {
+void TEMPLATE_emit_func_prolog(TEMPLATE_emit_env_t *env, ir_graph *irg) {
        const char *irg_name = get_entity_name(get_irg_entity(irg));
 
        /* TODO: emit function header */
+       be_emit_cstring(env->emit, "/* start of ");
+       be_emit_string(env->emit, irg_name);
+       be_emit_cstring(env->emit, " */\n");
+       be_emit_write_line(env->emit);
 }
 
 /**
  * Emits code for function end
  */
-void TEMPLATE_emit_func_epilog(FILE *F, ir_graph *irg) {
+void TEMPLATE_emit_func_epilog(TEMPLATE_emit_env_t *env, ir_graph *irg) {
        const char *irg_name = get_entity_name(get_irg_entity(irg));
 
        /* TODO: emit function end */
+       be_emit_cstring(env->emit, "/* end of ");
+       be_emit_string(env->emit, irg_name);
+       be_emit_cstring(env->emit, " */\n");
+       be_emit_write_line(env->emit);
 }
 
 /**
@@ -365,22 +252,20 @@ void TEMPLATE_gen_labels(ir_node *block, void *env) {
 /**
  * Main driver
  */
-void TEMPLATE_gen_routine(FILE *F, ir_graph *irg, const TEMPLATE_code_gen_t *cg) {
-       TEMPLATE_emit_env_t emit_env;
-
-       emit_env.out      = F;
-       emit_env.arch_env = cg->arch_env;
-       emit_env.cg       = cg;
-       FIRM_DBG_REGISTER(emit_env.mod, "firm.be.TEMPLATE.emit");
+void TEMPLATE_gen_routine(const TEMPLATE_code_gen_t *cg, ir_graph *irg) {
+       TEMPLATE_emit_env_t env;
 
-       /* set the global arch_env (needed by print hooks) */
-       arch_env = cg->arch_env;
+       env.isa      = (TEMPLATE_isa_t *) cg->arch_env->isa;
+       env.emit     = &env.isa->emit;
+       env.arch_env = cg->arch_env;
+       env.cg       = cg;
+       FIRM_DBG_REGISTER(env.mod, "firm.be.TEMPLATE.emit");
 
        /* 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_func_epilog(F, irg);
+       TEMPLATE_emit_func_prolog(&env, irg);
+       irg_block_walk_graph(irg, TEMPLATE_gen_labels, NULL, &env);
+       irg_walk_blkwise_graph(irg, NULL, TEMPLATE_gen_block, &env);
+       TEMPLATE_emit_func_epilog(&env, irg);
 }
index e288e53..c30354c 100644 (file)
@@ -6,23 +6,25 @@
 #include "debug.h"
 
 #include "../bearch.h"
+#include "../beemitter.h"
 
 #include "bearch_TEMPLATE_t.h"
 
 typedef struct _TEMPLATE_emit_env_t {
-       FILE                      *out;
+       be_emit_env_t             *emit;
        const arch_env_t          *arch_env;
        const TEMPLATE_code_gen_t *cg;
+       TEMPLATE_isa_t            *isa;
        DEBUG_ONLY(firm_dbg_module_t *mod;)
 } TEMPLATE_emit_env_t;
 
-const lc_arg_env_t *TEMPLATE_get_arg_env(void);
-
-void equalize_dest_src(FILE *F, ir_node *n);
+void TEMPLATE_emit_source_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos);
+void TEMPLATE_emit_dest_register(TEMPLATE_emit_env_t *env, const ir_node *node, int pos);
+void TEMPLATE_emit_immediate(TEMPLATE_emit_env_t *env, const ir_node *node);
 
 int get_TEMPLATE_reg_nr(ir_node *irn, int posi, int in_out);
 const char *get_TEMPLATE_in_reg_name(ir_node *irn, int pos);
 
-void TEMPLATE_gen_routine(FILE *F, ir_graph *irg, const TEMPLATE_code_gen_t *cg);
+void TEMPLATE_gen_routine(const TEMPLATE_code_gen_t *cg, ir_graph *irg);
 
 #endif /* _TEMPLATE_EMITTER_H_ */
diff --git a/ir/be/TEMPLATE/TEMPLATE_gen_decls.c b/ir/be/TEMPLATE/TEMPLATE_gen_decls.c
deleted file mode 100644 (file)
index 63f1fa1..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-/**
- * Dumps global variables and constants as TEMPLATE assembler.
- * @date 14.02.2006
- * @version $Id$
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "xmalloc.h"
-#include <obstack.h>
-
-#ifdef obstack_chunk_alloc
-# undef obstack_chunk_alloc
-# define obstack_chunk_alloc xmalloc
-#else
-# define obstack_chunk_alloc xmalloc
-# define obstack_chunk_free free
-#endif
-
-#include "tv.h"
-#include "irnode.h"
-#include "entity.h"
-#include "irprog.h"
-
-#include "TEMPLATE_gen_decls.h"
-
-/************************************************************************/
-
-/*
- * returns the highest bit value
- */
-static unsigned highest_bit(unsigned v)
-{
-  int res = -1;
-
-  if (v >= (1U << 16U)) {
-    res += 16;
-    v >>= 16;
-  }
-  if (v >= (1U << 8U)) {
-    res += 8;
-    v >>= 8;
-  }
-  if (v >= (1U << 4U)) {
-    res += 4;
-    v >>= 4;
-  }
-  if (v >= (1U << 2U)) {
-    res += 2;
-    v >>= 2;
-  }
-  if (v >= (1U << 1U)) {
-    res += 1;
-    v >>= 1;
-  }
-  if (v >= 1)
-    res += 1;
-
-  return res;
-}
-
-/*
- * output the alignment
- */
-static void TEMPLATE_dump_align(struct obstack *obst, int align)
-{
-  int h = highest_bit(align);
-
-  if ((1 << h) < align)
-    ++h;
-  align = (1 << h);
-
-  if (align > 1)
-    obstack_printf(obst, "\t.align %d\n", align);
-}
-
-static void dump_arith_tarval(struct obstack *obst, tarval *tv, int bytes)
-{
-  switch (bytes) {
-
-  case 1:
-    obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
-    break;
-
-  case 2:
-    obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-    break;
-
-  case 4:
-    obstack_printf(obst, "0x%02x%02x%02x%02x",
-       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-    break;
-
-  case 8:
-    obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
-       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
-       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-    break;
-
-  case 10:
-  case 12:
-    break;
-
-  default:
-    fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
-    assert(0);
-  }
-}
-
-/*
- * dump an arithmetic tarval
- */
-static void TEMPLATE_dump_arith_tarval(struct obstack *obst, tarval *tv, int bytes)
-{
-  switch (bytes) {
-
-  case 1:
-    obstack_printf(obst, "\t.byte\t");
-    break;
-
-  case 2:
-    obstack_printf(obst, "\t.value\t");
-    break;
-
-  case 4:
-    obstack_printf(obst, "\t.long\t");
-    break;
-
-  case 8:
-    obstack_printf(obst, "\t.quad\t");
-    break;
-
-  case 10:
-  case 12:
-    break;
-
-  default:
-    fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
-    assert(0);
-  }
-  dump_arith_tarval(obst, tv, bytes);
-}
-
-
-/*
- * dump an atomic value
- */
-static void do_dump_atomic_init(struct obstack *obst, ir_node *init)
-{
-  ir_mode *mode = get_irn_mode(init);
-  int bytes     = get_mode_size_bytes(mode);
-  tarval *tv;
-
-  switch (get_irn_opcode(init)) {
-
-  case iro_Cast:
-    do_dump_atomic_init(obst, get_Cast_op(init));
-    return;
-
-  case iro_Conv:
-    do_dump_atomic_init(obst, get_Conv_op(init));
-    return;
-
-  case iro_Const:
-    tv = get_Const_tarval(init);
-
-    /* beware of old stuff */
-    assert(! mode_is_reference(mode));
-
-    /* it's a arithmetic value */
-    dump_arith_tarval(obst, tv, bytes);
-    return;
-
-  case iro_SymConst:
-    switch (get_SymConst_kind(init)) {
-    case symconst_addr_name:
-      obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
-      break;
-
-    case symconst_addr_ent:
-      obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
-      break;
-
-    case symconst_ofs_ent:
-      obstack_printf(obst, "%d", get_entity_offset(get_SymConst_entity(init)));
-      break;
-
-    case symconst_type_size:
-      obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
-      break;
-
-    case symconst_type_align:
-      obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
-      break;
-
-    default:
-      assert(0 && "dump_atomic_init(): don't know how to init from this SymConst");
-    }
-    return;
-
-  case iro_Add:
-    do_dump_atomic_init(obst, get_Add_left(init));
-    obstack_printf(obst, " + ");
-    do_dump_atomic_init(obst, get_Add_right(init));
-    return;
-
-  case iro_Sub:
-    do_dump_atomic_init(obst, get_Sub_left(init));
-    obstack_printf(obst, " - ");
-    do_dump_atomic_init(obst, get_Sub_right(init));
-    return;
-
-  case iro_Mul:
-    do_dump_atomic_init(obst, get_Mul_left(init));
-    obstack_printf(obst, " * ");
-    do_dump_atomic_init(obst, get_Mul_right(init));
-    return;
-
-  default:
-    assert(0 && "dump_atomic_init(): unknown IR-node");
-  }
-}
-
-/*
- * dump an atomic value
- */
-static void dump_atomic_init(struct obstack *obst, ir_node *init)
-{
-  ir_mode *mode = get_irn_mode(init);
-  int bytes     = get_mode_size_bytes(mode);
-
-  switch (bytes) {
-
-  case 1:
-    obstack_printf(obst, "\t.byte\t");
-    break;
-
-  case 2:
-    obstack_printf(obst, "\t.value\t");
-    break;
-
-  case 4:
-    obstack_printf(obst, "\t.long\t");
-    break;
-
-  case 8:
-    obstack_printf(obst, "\t.quad\t");
-    break;
-
-  case 10:
-  case 12:
-    /* handled in arith */
-    break;
-
-  default:
-    fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
-    assert(0);
-  }
-
-  do_dump_atomic_init(obst, init);
-  obstack_printf(obst, "\n");
-}
-
-/************************************************************************/
-/* Routines to dump global variables                                    */
-/************************************************************************/
-
-/**
- * Determine if an ir_entity is a string constant
- * @param ent The ir_entity
- * @return 1 if it is a string constant, 0 otherwise
- */
-static int ent_is_string_const(ir_entity *ent)
-{
-  int res = 0;
-  ir_type *ty;
-
-  ty = get_entity_type(ent);
-
-  /* if it's an array */
-  if (is_Array_type(ty)) {
-    ir_type *elm_ty = get_array_element_type(ty);
-
-    /* and the array's element type is primitive */
-    if (is_Primitive_type(elm_ty)) {
-      ir_mode *mode = get_type_mode(elm_ty);
-
-      /*
-       * and the mode of the element type is an int of
-       * the same size as the byte mode
-       */
-      if (mode_is_int(mode)
-        && get_mode_size_bits(mode) == get_mode_size_bits(mode_Bs))
-      {
-       int i, c, n;
-
-       n = get_compound_ent_n_values(ent);
-       for (i = 0; i < n; ++i) {
-         ir_node *irn = get_compound_ent_value(ent, i);
-         if(get_irn_opcode(irn) != iro_Const)
-           return 0;
-
-         c = (int) get_tarval_long(get_Const_tarval(irn));
-
-         if((i < n - 1 && !(isgraph(c) || isspace(c)))
-            || (i == n - 1 && c != '\0'))
-           return 0;
-       }
-
-       res = 1;
-      }
-    }
-  }
-
-  return res;
-}
-
-/**
- * Dump a atring constant.
- * No checks are made!!
- * @param obst The obst to dump on.
- * @param ent The ir_entity to dump.
- */
-static void dump_string_cst(struct obstack *obst, ir_entity *ent)
-{
-  int i, n;
-
-  obstack_printf(obst, "\t.string \"");
-  n = get_compound_ent_n_values(ent);
-
-  for (i = 0; i < n-1; ++i) {
-    ir_node *irn;
-    int c;
-
-    irn = get_compound_ent_value(ent, i);
-    c = (int) get_tarval_long(get_Const_tarval(irn));
-
-    switch (c) {
-    case '"' : obstack_printf(obst, "\\\""); break;
-    case '\n': obstack_printf(obst, "\\n"); break;
-    case '\r': obstack_printf(obst, "\\r"); break;
-    case '\t': obstack_printf(obst, "\\t"); break;
-    default  :
-      if (isprint(c))
-       obstack_printf(obst, "%c", c);
-      else
-       obstack_printf(obst, "\\%o", c);
-      break;
-    }
-  }
-  obstack_printf(obst, "\"\n");
-}
-
-struct arr_info {
-  int n_elems;
-  int visit_cnt;
-  int size;
-};
-
-/*
- * Dumps the initialization of global variables that are not
- * "uninitialized".
- */
-static void dump_global(struct obstack *rdata_obstack, struct obstack *data_obstack, struct obstack *comm_obstack, ir_entity *ent)
-{
-  ir_type *ty         = get_entity_type(ent);
-  const char *ld_name = get_entity_ld_name(ent);
-  int align, h;
-  struct obstack *obst = data_obstack;
-
-  /*
-   * FIXME: did NOT work for partly constant values
-   */
-  if (! is_Method_type(ty)) {
-    ir_variability variability = get_entity_variability(ent);
-    ir_visibility visibility = get_entity_visibility(ent);
-
-    if (variability == variability_constant) {
-      /* a constant ir_entity, put it on the rdata */
-      obst = rdata_obstack;
-    }
-
-    /* check, wether it is initialized, if yes create data */
-    if (variability != variability_uninitialized) {
-      if (visibility == visibility_external_visible) {
-        obstack_printf(obst, ".globl\t%s\n", ld_name);
-      }
-      obstack_printf(obst, "\t.type\t%s,@object\n", ld_name);
-      obstack_printf(obst, "\t.size\t%s,%d\n", ld_name, (get_type_size_bits(ty) + 7) >> 3);
-
-      align = get_type_alignment_bytes(ty);
-      TEMPLATE_dump_align(obst, align);
-
-      obstack_printf(obst, "%s:\n", ld_name);
-
-      if (is_atomic_type(ty)) {
-       if (get_entity_visibility(ent) != visibility_external_allocated)
-          dump_atomic_init(obst, get_atomic_ent_value(ent));
-      }
-      else {
-       int i, size = 0;
-
-       if (ent_is_string_const(ent)) {
-         dump_string_cst(obst, ent);
-       }
-       else if (is_Array_type(ty)) {
-          int filler;
-
-          /* potential spare values should be already included! */
-                 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
-            ir_entity *step = get_compound_ent_value_member(ent, i);
-            ir_type *stype = get_entity_type(step);
-
-            if (get_type_mode(stype)) {
-              int align = (get_type_alignment_bits(stype) + 7) >> 3;
-              int n     = size % align;
-
-              if (n > 0) {
-                obstack_printf(obst, "\t.zero\t%d\n", align - n);
-                size += align - n;
-              }
-            }
-            dump_atomic_init(obst, get_compound_ent_value(ent, i));
-            size += get_type_size_bytes(stype);
-         }
-          filler = get_type_size_bytes(ty) - size;
-
-          if (filler > 0)
-            obstack_printf(obst, "\t.zero\t%d\n", filler);
-        }
-        else if (is_compound_type(ty)) {
-          ir_node **vals;
-          int type_size, j;
-
-          /* Compound entities are NOT sorted.
-           * The sorting strategy used doesn't work for `value' compound fields nor
-           * for partially_constant entities.
-           */
-
-          /*
-           * in the worst case, every ir_entity allocates one byte, so the type
-           * size should be equal or bigger the number of fields
-           */
-          type_size = get_type_size_bytes(ty);
-          vals      = xcalloc(type_size, sizeof(*vals));
-
-          /* collect the values and store them at the offsets */
-          for(i = 0; i < get_compound_ent_n_values(ent); ++i) {
-            int                 graph_length, aipos, offset;
-            struct arr_info     *ai;
-            int                 all_n = 1;
-            compound_graph_path *path = get_compound_ent_value_path(ent, i);
-
-            /* get the access path to the costant value */
-            graph_length = get_compound_graph_path_length(path);
-            ai = xcalloc(graph_length, sizeof(struct arr_info));
-
-            /* We wanna know how many arrays are on the path to the ir_entity. We also have to know how
-             * many elements each array holds to calculate the offset for the ir_entity. */
-            for (j = 0; j < graph_length; j++) {
-              ir_entity  *step      = get_compound_graph_path_node(path, j);
-              ir_type *step_type = get_entity_type(step);
-              int     ty_size    = (get_type_size_bits(step_type) + 7) >> 3;
-              int     k, n       = 0;
-
-              if (is_Array_type(step_type))
-                for (k = 0; k < get_array_n_dimensions(step_type); k++)
-                  n += get_tarval_long(get_Const_tarval(get_array_upper_bound(step_type, k)));
-              if (n) all_n *= n;
-              ai[j].n_elems = n ? all_n + 1 : 0;
-              ai[j].visit_cnt = 0;
-              ai[j].size = ty_size;
-            }
-
-            aipos = graph_length - 1;
-            if (aipos) aipos--;
-
-            for (offset = j = 0; j < graph_length; j++) {
-              ir_entity *step       = get_compound_graph_path_node(path, j);
-              ir_type *step_type = get_entity_type(step);
-              int ent_ofs        = get_entity_offset_bytes(step);
-              int stepsize       = 0;
-
-              /* add all positive offsets (= offsets in structs) */
-              if (ent_ofs >= 0) offset += ent_ofs;
-
-              if (j == graph_length - 1) {
-                stepsize = (get_type_size_bits(step_type) + 7) >> 3;
-
-                /* Search the next free position in vals depending on the information from above (ai). */
-                while (vals[offset]) {
-                  if (ai[aipos].visit_cnt < ai[aipos].n_elems) {
-                    offset += stepsize;
-                    ai[aipos].visit_cnt++;
-                  }
-                  else
-                    while (aipos >= 0 && ai[aipos].visit_cnt == ai[aipos].n_elems) {
-                      stepsize = ai[aipos--].size;
-                      offset  += stepsize;
-                  }
-                }
-
-                assert(aipos >= 0 && "couldn't store ir_entity");
-                vals[offset] = get_compound_ent_value(ent, i);
-              }
-            }
-
-            free(ai);
-          }
-
-          /* now write them sorted */
-          for(i = 0; i < type_size; ) {
-            if (vals[i]) {
-              dump_atomic_init(obst, vals[i]);
-              i += (get_mode_size_bytes(get_irn_mode(vals[i])));
-            }
-            else {
-              /* a gap */
-              obstack_printf(obst, "\t.byte\t0\n");
-              ++i;
-            }
-          }
-          free(vals);
-        }
-        else {
-          assert(0 && "unsupported type");
-        }
-      }
-      obstack_printf(obst, "\n");
-    }
-    else if (visibility != visibility_external_allocated) {
-      if (visibility == visibility_local) {
-        obstack_printf(comm_obstack, "\t.local\t%s\n", ld_name);
-      }
-
-      /* calculate the alignment */
-      align = get_type_alignment_bytes(ty);
-      h = highest_bit(align);
-
-      if ((1 << h) < align)
-       ++h;
-      align = (1 << h);
-
-      if (align < 1)
-       align = 1;
-
-      obstack_printf(comm_obstack, "\t.comm\t%s,%d,%d\n", ld_name, (get_type_size_bits(ty) + 7) >> 3, align);
-    }
-  }
-}
-
-/*
- * Dumps declarations of global variables and the initialization code.
- */
-void TEMPLATE_dump_globals(struct obstack *rdata_obstack, struct obstack *data_obstack, struct obstack *comm_obstack)
-{
-  ir_type *gt = get_glob_type();
-  int i, n = get_class_n_members(gt);
-
-  for (i = 0; i < n; i++)
-    dump_global(rdata_obstack, data_obstack, comm_obstack, get_class_member(gt, i));
-}
-
-/************************************************************************/
-
-void TEMPLATE_gen_decls(FILE *out) {
-  struct obstack rodata, data, comm;
-  int    size;
-  char   *cp;
-
-  obstack_init(&rodata);
-  obstack_init(&data);
-  obstack_init(&comm);
-
-  TEMPLATE_dump_globals(&rodata, &data, &comm);
-
-  size = obstack_object_size(&data);
-  cp   = obstack_finish(&data);
-  if (size > 0) {
-    fprintf(out, "\t.data\n");
-    fwrite(cp, 1, size, out);
-  }
-
-  size = obstack_object_size(&rodata);
-  cp   = obstack_finish(&rodata);
-  if (size > 0) {
-    fprintf(out, "\t.section\t.rodata\n");
-    fwrite(cp, 1, size, out);
-  }
-
-  size = obstack_object_size(&comm);
-  cp   = obstack_finish(&comm);
-  if (size > 0) {
-    fprintf(out, "\t.common\n");
-    fwrite(cp, 1, size, out);
-  }
-
-  obstack_free(&rodata, NULL);
-  obstack_free(&data, NULL);
-  obstack_free(&comm, NULL);
-}
diff --git a/ir/be/TEMPLATE/TEMPLATE_gen_decls.h b/ir/be/TEMPLATE/TEMPLATE_gen_decls.h
deleted file mode 100644 (file)
index 0224dc0..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _TEMPLATE_GEN_DECLS_H_
-#define _TEMPLATE_GEN_DECLS_H_
-
-/**
- * Generate all entities.
- */
-void TEMPLATE_gen_decls(FILE *out);
-
-#endif /* _TEMPLATE_GEN_DECLS_H_ */
index 9428570..f870d6d 100644 (file)
  *                       |_|
  ***********************************************************************************/
 
-/**
- * Returns a string containing the names of all registers within the limited bitset
- */
-static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
-       bitset_t *bs   = bitset_alloca(req->cls->n_regs);
-       char     *p    = buf;
-       int       size = 0;
-       int       i, cnt;
-
-       req->limited(NULL, bs);
-
-       for (i = 0; i < req->cls->n_regs; i++) {
-               if (bitset_is_set(bs, i)) {
-                       cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
-                       if (cnt < 0) {
-                               fprintf(stderr, "dumper problem, exiting\n");
-                               exit(1);
-                       }
-
-                       p    += cnt;
-                       size += cnt;
-
-                       if (size >= max)
-                               break;
-               }
-       }
-
-       return buf;
-}
-
 /**
  * Dumps the register requirements for either in or out.
  */
-static void dump_reg_req(FILE *F, ir_node *n, const TEMPLATE_register_req_t **reqs, int inout) {
+static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
+                         int inout) {
        char *dir = inout ? "out" : "in";
        int   max = inout ? get_TEMPLATE_n_res(n) : get_irn_arity(n);
-       char *buf = alloca(1024);
+       char  buf[1024];
        int   i;
 
-       memset(buf, 0, 1024);
+       memset(buf, 0, sizeof(buf));
 
        if (reqs) {
                for (i = 0; i < max; i++) {
                        fprintf(F, "%sreq #%d =", dir, i);
 
-                       if (reqs[i]->req.type == arch_register_req_type_none) {
+                       if (reqs[i]->type == arch_register_req_type_none) {
                                fprintf(F, " n/a");
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_normal) {
-                               fprintf(F, " %s", reqs[i]->req.cls->name);
+                       if (reqs[i]->type & arch_register_req_type_normal) {
+                               fprintf(F, " %s", reqs[i]->cls->name);
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_limited) {
-                               fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
+                       if (reqs[i]->type & arch_register_req_type_limited) {
+                               fprintf(F, " %s",
+                                               arch_register_req_format(buf, sizeof(buf), reqs[i], n));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
-                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_same) {
+                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
-                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_different) {
+                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different));
                        }
 
                        fprintf(F, "\n");
                }
 
                fprintf(F, "\n");
-       }
-       else {
+       } else {
                fprintf(F, "%sreq = N/A\n", dir);
        }
 }
@@ -133,7 +104,7 @@ static int TEMPLATE_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
        int          bad  = 0;
        int          i;
        TEMPLATE_attr_t *attr;
-       const TEMPLATE_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t     **slots;
 
        switch (reason) {
@@ -246,7 +217,7 @@ TEMPLATE_attr_t *get_TEMPLATE_attr(const ir_node *node) {
 /**
  * Returns the argument register requirements of a TEMPLATE node.
  */
-const TEMPLATE_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node) {
+const arch_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node) {
        TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
        return attr->in_req;
 }
@@ -254,7 +225,7 @@ const TEMPLATE_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node) {
 /**
  * Returns the result register requirements of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node) {
+const arch_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node) {
        TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
        return attr->out_req;
 }
@@ -262,7 +233,7 @@ const TEMPLATE_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node) {
 /**
  * Returns the argument register requirement at position pos of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos) {
        TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
        return attr->in_req[pos];
 }
@@ -270,7 +241,7 @@ const TEMPLATE_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos)
 /**
  * Returns the result register requirement at position pos of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos) {
        TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
        return attr->out_req[pos];
 }
@@ -278,7 +249,7 @@ const TEMPLATE_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_TEMPLATE_req_out(ir_node *node, const TEMPLATE_register_req_t *req, int pos) {
+void set_TEMPLATE_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
        TEMPLATE_attr_t *attr   = get_TEMPLATE_attr(node);
        attr->out_req[pos] = req;
 }
@@ -286,7 +257,7 @@ void set_TEMPLATE_req_out(ir_node *node, const TEMPLATE_register_req_t *req, int
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_TEMPLATE_req_in(ir_node *node, const TEMPLATE_register_req_t *req, int pos) {
+void set_TEMPLATE_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
        TEMPLATE_attr_t *attr  = get_TEMPLATE_attr(node);
        attr->in_req[pos] = req;
 }
@@ -370,7 +341,24 @@ int get_TEMPLATE_n_res(const ir_node *node) {
        return attr->n_res;
 }
 
+/**
+ * Initializes the nodes attributes.
+ */
+void init_TEMPLATE_attributes(ir_node *node, arch_irn_flags_t flags,
+                              const arch_register_req_t **in_reqs,
+                              const arch_register_req_t **out_reqs,
+                              const be_execution_unit_t ***execution_units,
+                              int n_res, unsigned latency)
+{
+       TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
+
+       attr->flags = flags;
+       attr->out_req = out_reqs;
+       attr->in_req = in_reqs;
+       attr->n_res = n_res;
 
+       memset((void *)attr->slots, 0, n_res * sizeof(attr->slots[0]));
+}
 
 /***************************************************************************************
  *                  _                            _                   _
index b67c06c..a493ae6 100644 (file)
@@ -27,32 +27,32 @@ TEMPLATE_attr_t *get_TEMPLATE_attr(const ir_node *node);
 /**
  * Returns the argument register requirements of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node);
+const arch_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node);
 
 /**
  * Returns the result register requirements of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node);
+const arch_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node);
 
 /**
  * Returns the argument register requirements of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos);
+const arch_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos);
 
 /**
  * Returns the result register requirements of an TEMPLATE node.
  */
-const TEMPLATE_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos);
+const arch_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos);
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_TEMPLATE_req_out(ir_node *node, const TEMPLATE_register_req_t *req, int pos);
+void set_TEMPLATE_req_out(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_TEMPLATE_req_in(ir_node *node, const TEMPLATE_register_req_t *req, int pos);
+void set_TEMPLATE_req_in(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Returns the register flag of an TEMPLATE node.
index 193aeea..805d307 100644 (file)
@@ -3,19 +3,12 @@
 
 #include "../bearch.h"
 
-typedef struct _TEMPLATE_register_req_t {
-       const arch_register_req_t req;
-       int same_pos;        /**< in case of "should be same" we need to remember the pos to get the irn */
-       int different_pos;   /**< in case of "should be different" we need to remember the pos to get the irn */
-} TEMPLATE_register_req_t;
-
-
 typedef struct _TEMPLATE_attr_t {
        arch_irn_flags_t flags;     /**< indicating if spillable, rematerializeable ... etc. */
        int              n_res;     /**< number of results for this node */
 
-       const TEMPLATE_register_req_t **in_req;  /**< register requirements for arguments */
-       const TEMPLATE_register_req_t **out_req; /**< register requirements for results */
+       const arch_register_req_t **in_req;  /**< register requirements for arguments */
+       const arch_register_req_t **out_req; /**< register requirements for results */
 
        /* must be last, dynamically allocated */
        const arch_register_t *slots[1];         /**< register slots for assigned registers */
index 7aa8109..45833aa 100644 (file)
@@ -2,34 +2,32 @@
 # $Id$
 # This is a template specification for the Firm-Backend
 
+$new_emit_syntax = 1;
+
 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
 
 $arch = "TEMPLATE";
 
-# this strings mark the beginning and the end of a comment in emit
-$comment_string     = "/*";
-$comment_string_end = "*/";
-
 # The node description is done as a perl hash initializer with the
 # following structure:
 #
 # %nodes = (
 #
 # <op-name> => {
-#   "op_flags"  => "N|L|C|X|I|F|Y|H|c|K",
-#   "irn_flags" => "R|N|I"
-#   "arity"     => "0|1|2|3 ... |variable|dynamic|any",
-#   "state"     => "floats|pinned|mem_pinned|exc_pinned",
-#   "args"      => [
-#                    { "type" => "type 1", "name" => "name 1" },
-#                    { "type" => "type 2", "name" => "name 2" },
+#   op_flags  => "N|L|C|X|I|F|Y|H|c|K",
+#   irn_flags => "R|N|I"
+#   arity     => "0|1|2|3 ... |variable|dynamic|any",
+#   state     => "floats|pinned|mem_pinned|exc_pinned",
+#   args      => [
+#                    { type => "type 1", name => "name 1" },
+#                    { type => "type 2", name => "name 2" },
 #                    ...
 #                  ],
-#   "comment"   => "any comment for constructor",
-#   "reg_req"   => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] },
-#   "cmp_attr"  => "c source code for comparing node attributes",
-#   "emit"      => "emit code with templates",
-#   "rd_constructor" => "c source code which constructs an ir_node"
+#   comment   => "any comment for constructor",
+#   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
+#   cmp_attr  => "c source code for comparing node attributes",
+#   emit      => "emit code with templates",
+#   rd_constructor => "c source code which constructs an ir_node"
 # },
 #
 # ... # (all nodes you need to describe)
@@ -94,46 +92,62 @@ $comment_string_end = "*/";
 #   4 - ignore (do not assign this register)
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
-  "general_purpose" => [
-                         { "name" => "r0", "type" => 1 },
-                         { "name" => "r1", "type" => 1 },
-                         { "name" => "r2", "type" => 1 },
-                         { "name" => "r3", "type" => 1 },
-                         { "name" => "r4", "type" => 1 },
-                         { "name" => "r5", "type" => 1 },
-                         { "name" => "r6", "type" => 6 }, # this is our stackpointer
-                         { "name" => "r7", "type" => 6 }, # this is out basepointer
-                         { "name" => "r8", "type" => 2 },
-                         { "name" => "r9", "type" => 2 },
-                         { "name" => "r10", "type" => 2 },
-                         { "name" => "r11", "type" => 2 },
-                         { "name" => "r12", "type" => 2 },
-                         { "name" => "r13", "type" => 2 },
-                         { "name" => "r14", "type" => 2 },
-                         { "name" => "r15", "type" => 2 },
-                         { "mode" => "mode_P" }
-                       ],
-  "floating_point"  => [
-                         { "name" => "f0", "type" => 1 },
-                         { "name" => "f1", "type" => 1 },
-                         { "name" => "f2", "type" => 1 },
-                         { "name" => "f3", "type" => 1 },
-                         { "name" => "f4", "type" => 1 },
-                         { "name" => "f5", "type" => 1 },
-                         { "name" => "f6", "type" => 1 },
-                         { "name" => "f7", "type" => 1 },
-                         { "name" => "f8", "type" => 1 },
-                         { "name" => "f9", "type" => 1 },
-                         { "name" => "f10", "type" => 1 },
-                         { "name" => "f11", "type" => 1 },
-                         { "name" => "f12", "type" => 1 },
-                         { "name" => "f13", "type" => 1 },
-                         { "name" => "f14", "type" => 1 },
-                         { "name" => "f15", "type" => 1 },
-                         { "mode" => "mode_D" }
-                       ]
+       general_purpose => [
+               { name => "r0", type => 1 },
+               { name => "r1", type => 1 },
+               { name => "r2", type => 1 },
+               { name => "r3", type => 1 },
+               { name => "r4", type => 1 },
+               { name => "r5", type => 1 },
+               { name => "r6", type => 1 },
+               { name => "r7", type => 2 },
+               { name => "r8", type => 2 },
+               { name => "r9", type => 2 },
+               { name => "r10", type => 2 },
+               { name => "r11", type => 2 },
+               { name => "r12", type => 2 },
+               { name => "r13", type => 2 },
+               { name => "sp", realname => "r14", type => 4 },  # this is our stackpointer
+               { name => "bp", realname => "r15", type => 4 },  # this is out basepointer
+               { mode => "mode_Iu" }
+       ],
+       floating_point  => [
+               { name => "f0", type => 1 },
+               { name => "f1", type => 1 },
+               { name => "f2", type => 1 },
+               { name => "f3", type => 1 },
+               { name => "f4", type => 1 },
+               { name => "f5", type => 1 },
+               { name => "f6", type => 1 },
+               { name => "f7", type => 1 },
+               { name => "f8", type => 1 },
+               { name => "f9", type => 1 },
+               { name => "f10", type => 1 },
+               { name => "f11", type => 1 },
+               { name => "f12", type => 1 },
+               { name => "f13", type => 1 },
+               { name => "f14", type => 1 },
+               { name => "f15", type => 1 },
+               { mode => "mode_D" }
+       ]
 ); # %reg_classes
 
+%emit_templates = (
+    S1 => "${arch}_emit_source_register(env, node, 0);",
+    S2 => "${arch}_emit_source_register(env, node, 1);",
+    S3 => "${arch}_emit_source_register(env, node, 2);",
+    S4 => "${arch}_emit_source_register(env, node, 3);",
+    S5 => "${arch}_emit_source_register(env, node, 4);",
+    S6 => "${arch}_emit_source_register(env, node, 5);",
+    D1 => "${arch}_emit_dest_register(env, node, 0);",
+    D2 => "${arch}_emit_dest_register(env, node, 1);",
+    D3 => "${arch}_emit_dest_register(env, node, 2);",
+    D4 => "${arch}_emit_dest_register(env, node, 3);",
+    D5 => "${arch}_emit_dest_register(env, node, 4);",
+    D6 => "${arch}_emit_dest_register(env, node, 5);",
+       C  => "${arch}_emit_immediate(env, node);"
+);
+
 #--------------------------------------------------#
 #                        _                         #
 #                       (_)                        #
@@ -160,185 +174,185 @@ $comment_string_end = "*/";
 
 # commutative operations
 
-"Add" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. add %S1, %S2, %D1\t\t\t/* Add(%S1, %S2) -> %D1, (%A1, %A2) */'
+Add => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. add %S1, %S2, %D1'
 },
 
-"Add_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Add: Add(a, const) = Add(const, a) = a + const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. add %S1, %C, %D1\t\t\t/* Add(%C, %S1) -> %D1, (%A1, const) */'
+Add_i => {
+  irn_flags => "R",
+  comment   => "construct Add: Add(a, const) = Add(const, a) = a + const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. add %S1, %C, %D1'
 },
 
-"Mul" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      =>'. mul %S1, %S2, %D1\t\t\t/* Mul(%S1, %S2) -> %D1, (%A1, %A2) */'
+Mul => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      =>'. mul %S1, %S2, %D1'
 },
 
-"Mul_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. mul %S1, %C, %D1\t\t\t/* signed Mul(%C, %S1) -> %D1, (%A1, const) */'
+Mul_i => {
+  irn_flags => "R",
+  comment   => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. mul %S1, %C, %D1'
 },
 
-"And" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct And: And(a, b) = And(b, a) = a AND b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. and %S1, %S2, %D1\t\t\t/* And(%S1, %S2) -> %D1, (%A1, %A2) */'
+And => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct And: And(a, b) = And(b, a) = a AND b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. and %S1, %S2, %D1'
 },
 
-"And_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct And: And(a, const) = And(const, a) = a AND const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. and %S1, %C, %D1\t\t\t/* And(%C, %S1) -> %D1, (%A1, const) */'
+And_i => {
+  irn_flags => "R",
+  comment   => "construct And: And(a, const) = And(const, a) = a AND const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. and %S1, %C, %D1'
 },
 
-"Or" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. or %S1, %S2, %D1\t\t\t/* Or(%S1, %S2) -> %D1, (%A1, %A2) */'
+Or => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. or %S1, %S2, %D1'
 },
 
-"Or_i" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. or %S1, %C, %D1\t\t\t/* Or(%C, %S1) -> %D1, (%A1, const) */'
+Or_i => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. or %S1, %C, %D1'
 },
 
-"Eor" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. xor %S1, %S2, %D1\t\t\t/* Xor(%S1, %S2) -> %D1, (%A1, %A2) */'
+Eor => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. xor %S1, %S2, %D1'
 },
 
-"Eor_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. xor %S1, %C, %D1\t\t\t/* Xor(%C, %S1) -> %D1, (%A1, const) */'
+Eor_i => {
+  irn_flags => "R",
+  comment   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. xor %S1, %C, %D1'
 },
 
 # not commutative operations
 
-"Sub" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Sub: Sub(a, b) = a - b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. sub %S1, %S2, %D1\t\t\t/* Sub(%S1, %S2) -> %D1, (%A1, %A2) */'
+Sub => {
+  irn_flags => "R",
+  comment   => "construct Sub: Sub(a, b) = a - b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. sub %S1, %S2, %D1'
 },
 
-"Sub_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Sub: Sub(a, const) = a - const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. subl %S1, %C, %D1\t\t\t/* Sub(%S1, %C) -> %D1, (%A1, const) */'
+Sub_i => {
+  irn_flags => "R",
+  comment   => "construct Sub: Sub(a, const) = a - const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. subl %S1, %C, %D1'
 },
 
-"Shl" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Shl: Shl(a, b) = a << b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. shl %S1, %S2, %D1\t\t\t/* Shl(%S1, %S2) -> %D1, (%A1, %A2) */'
+Shl => {
+  irn_flags => "R",
+  comment   => "construct Shl: Shl(a, b) = a << b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. shl %S1, %S2, %D1'
 },
 
-"Shl_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Shl: Shl(a, const) = a << const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. shl %S1, %C, %D1\t\t\t/* Shl(%S1, %C) -> %D1, (%A1, const) */'
+Shl_i => {
+  irn_flags => "R",
+  comment   => "construct Shl: Shl(a, const) = a << const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. shl %S1, %C, %D1'
 },
 
-"Shr" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Shr: Shr(a, b) = a >> b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "in_r1" ] },
-  "emit"      => '. shr %S2, %D1\t\t\t/* Shr(%S1, %S2) -> %D1, (%A1, %A2) */'
+Shr => {
+  irn_flags => "R",
+  comment   => "construct Shr: Shr(a, b) = a >> b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "in_r1" ] },
+  emit      => '. shr %S2, %D1'
 },
 
-"Shr_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Shr: Shr(a, const) = a >> const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. shr %S1, %C, %D1\t\t\t/* Shr(%S1, %C) -> %D1, (%A1, const) */'
+Shr_i => {
+  irn_flags => "R",
+  comment   => "construct Shr: Shr(a, const) = a >> const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. shr %S1, %C, %D1'
 },
 
-"RotR" => {
-  "irn_flags" => "R",
-  "comment"   => "construct RotR: RotR(a, b) = a ROTR b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. ror %S1, %S2, %D1\t\t\t/* RotR(%S1, %S2) -> %D1, (%A1, %A2) */'
+RotR => {
+  irn_flags => "R",
+  comment   => "construct RotR: RotR(a, b) = a ROTR b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. ror %S1, %S2, %D1'
 },
 
-"RotL" => {
-  "irn_flags" => "R",
-  "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. rol %S1, %S2, %D1\t\t\t/* RotL(%S1, %S2) -> %D1, (%A1, %A2) */'
+RotL => {
+  irn_flags => "R",
+  comment   => "construct RotL: RotL(a, b) = a ROTL b",
+  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. rol %S1, %S2, %D1'
 },
 
-"RotL_i" => {
-  "irn_flags" => "R",
-  "comment"   => "construct RotL: RotL(a, const) = a ROTL const",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. rol %S1, %C, %D1\t\t\t/* RotL(%S1, %C) -> %D1, (%A1, const) */'
+RotL_i => {
+  irn_flags => "R",
+  comment   => "construct RotL: RotL(a, const) = a ROTL const",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. rol %S1, %C, %D1'
 },
 
-"Minus" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Minus: Minus(a) = -a",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. neg %S1, %D1\t\t\t/* Neg(%S1) -> %D1, (%A1) */'
+Minus => {
+  irn_flags => "R",
+  comment   => "construct Minus: Minus(a) = -a",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. neg %S1, %D1'
 },
 
-"Inc" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Increment: Inc(a) = a++",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. inc %S1, %D1\t\t\t/* Inc(%S1) -> %D1, (%A1) */'
+Inc => {
+  irn_flags => "R",
+  comment   => "construct Increment: Inc(a) = a++",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. inc %S1, %D1'
 },
 
-"Dec" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Decrement: Dec(a) = a--",
-  "reg_req"   => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. dec %S1, %D1\t\t\t/* Dec(%S1) -> %D1, (%A1) */'
+Dec => {
+  irn_flags => "R",
+  comment   => "construct Decrement: Dec(a) = a--",
+  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit      => '. dec %S1, %D1'
 },
 
-"Not" => {
-  "arity"       => 1,
-  "remat"       => 1,
-  "comment"     => "construct Not: Not(a) = !a",
-  "reg_req"     => { "in" => [ "general_purpose" ], "out" => [ "general_purpose" ] },
-  "emit"        => '. not %S1, %D1\t\t\t/* Not(%S1) -> %D1, (%A1) */'
+Not => {
+  arity       => 1,
+  remat       => 1,
+  comment     => "construct Not: Not(a) = !a",
+  reg_req     => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
+  emit        => '. not %S1, %D1'
 },
 
 # other operations
 
-"Const" => {
-  "op_flags"  => "c",
-  "irn_flags" => "R",
-  "comment"   => "represents an integer constant",
-  "reg_req"   => { "out" => [ "general_purpose" ] },
-  "emit"      => '. mov %C, %D1\t\t\t/* Mov Const into register */',
-  "cmp_attr"  =>
+Const => {
+  op_flags  => "c",
+  irn_flags => "R",
+  comment   => "represents an integer constant",
+  reg_req   => { out => [ "general_purpose" ] },
+  emit      => '. mov %C, %D1',
+  cmp_attr  =>
 '
        /* TODO: compare Const attributes */
     return 1;
@@ -347,22 +361,22 @@ $comment_string_end = "*/";
 
 # Load / Store
 
-"Load" => {
-  "op_flags"  => "L|F",
-  "irn_flags" => "R",
-  "state"     => "exc_pinned",
-  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
-  "reg_req"   => { "in" => [ "general_purpose", "none" ], "out" => [ "general_purpose" ] },
-  "emit"      => '. mov %O(%S1), %D1\t\t\t/* Load((%S1)) -> %D1, (%A1) */'
+Load => {
+  op_flags  => "L|F",
+  irn_flags => "R",
+  state     => "exc_pinned",
+  comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
+  reg_req   => { in => [ "general_purpose", "none" ], out => [ "general_purpose" ] },
+  emit      => '. mov (%S1), %D1'
 },
 
-"Store" => {
-  "op_flags"  => "L|F",
-  "irn_flags" => "R",
-  "state"     => "exc_pinned",
-  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "general_purpose", "general_purpose", "none" ] },
-  "emit"      => '. movl %S2, %O(%S1)\t\t\t/* Store(%S2) -> (%S1), (%A1, %A2) */'
+Store => {
+  op_flags  => "L|F",
+  irn_flags => "R",
+  state     => "exc_pinned",
+  comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+  reg_req   => { in => [ "general_purpose", "general_purpose", "none" ] },
+  emit      => '. movl %S2, (%S1)'
 },
 
 #--------------------------------------------------------#
@@ -376,68 +390,68 @@ $comment_string_end = "*/";
 
 # commutative operations
 
-"fAdd" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      => '. fadd %S1, %S2, %D1\t\t\t/* FP Add(%S1, %S2) -> %D1 */'
+fAdd => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      => '. fadd %S1, %S2, %D1'
 },
 
-"fMul" => {
-  "op_flags"  => "C",
-  "comment"   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      =>'. fmul %S1, %S2, %D1\t\t\t/* FP Mul(%S1, %S2) -> %D1 */'
+fMul => {
+  op_flags  => "C",
+  comment   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      =>'. fmul %S1, %S2, %D1'
 },
 
-"fMax" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      =>'. fmax %S1, %S2, %D1\t\t\t/* FP Max(%S1, %S2) -> %D1 */'
+fMax => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      =>'. fmax %S1, %S2, %D1'
 },
 
-"fMin" => {
-  "op_flags"  => "C",
-  "irn_flags" => "R",
-  "comment"   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      =>'. fmin %S1, %S2, %D1\t\t\t/* FP Min(%S1, %S2) -> %D1 */'
+fMin => {
+  op_flags  => "C",
+  irn_flags => "R",
+  comment   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      =>'. fmin %S1, %S2, %D1'
 },
 
 # not commutative operations
 
-"fSub" => {
-  "irn_flags" => "R",
-  "comment"   => "construct FP Sub: Sub(a, b) = a - b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      => '. fsub %S1, %S2, %D1\t\t\t/* FP Sub(%S1, %S2) -> %D1 */'
+fSub => {
+  irn_flags => "R",
+  comment   => "construct FP Sub: Sub(a, b) = a - b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      => '. fsub %S1, %S2, %D1'
 },
 
-"fDiv" => {
-  "comment"   => "construct FP Div: Div(a, b) = a / b",
-  "reg_req"   => { "in" => [ "floating_point", "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      => '. fdiv %S1, %S2, %D1\t\t\t/* FP Div(%S1, %S2) -> %D1 */'
+fDiv => {
+  comment   => "construct FP Div: Div(a, b) = a / b",
+  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
+  emit      => '. fdiv %S1, %S2, %D1'
 },
 
-"fMinus" => {
-  "irn_flags" => "R",
-  "comment"   => "construct FP Minus: Minus(a) = -a",
-  "reg_req"   => { "in" => [ "floating_point" ], "out" => [ "floating_point" ] },
-  "emit"      => '. fneg %S1, %D1\t\t\t/* FP Minus(%S1) -> %D1 */'
+fMinus => {
+  irn_flags => "R",
+  comment   => "construct FP Minus: Minus(a) = -a",
+  reg_req   => { in => [ "floating_point" ], out => [ "floating_point" ] },
+  emit      => '. fneg %S1, %D1'
 },
 
 # other operations
 
-"fConst" => {
-  "op_flags"  => "c",
-  "irn_flags" => "R",
-  "comment"   => "represents a FP constant",
-  "reg_req"   => { "out" => [ "floating_point" ] },
-  "emit"      => '. fmov %C, %D1\t\t\t/* Mov fConst into register */',
-  "cmp_attr"  =>
+fConst => {
+  op_flags  => "c",
+  irn_flags => "R",
+  comment   => "represents a FP constant",
+  reg_req   => { out => [ "floating_point" ] },
+  emit      => '. fmov %C, %D1',
+  cmp_attr  =>
 '
        /* TODO: compare fConst attributes */
        return 1;
@@ -446,22 +460,22 @@ $comment_string_end = "*/";
 
 # Load / Store
 
-"fLoad" => {
-  "op_flags"  => "L|F",
-  "irn_flags" => "R",
-  "state"     => "exc_pinned",
-  "comment"   => "construct FP Load: Load(ptr, mem) = LD ptr",
-  "reg_req"   => { "in" => [ "general_purpose", "none" ], "out" => [ "floating_point" ] },
-  "emit"      => '. fmov %O(%S1), %D1\t\t\t/* Load((%S1)) -> %D1 */'
-},
-
-"fStore" => {
-  "op_flags"  => "L|F",
-  "irn_flags" => "R",
-  "state"     => "exc_pinned",
-  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "general_purpose", "floating_point", "none" ] },
-  "emit"      => '. fmov %S2, %O(%S1)\t\t\t/* Store(%S2) -> (%S1), (%A1, %A2) */'
+fLoad => {
+  op_flags  => "L|F",
+  irn_flags => "R",
+  state     => "exc_pinned",
+  comment   => "construct FP Load: Load(ptr, mem) = LD ptr",
+  reg_req   => { in => [ "general_purpose", "none" ], out => [ "floating_point" ] },
+  emit      => '. fmov (%S1), %D1'
+},
+
+fStore => {
+  op_flags  => "L|F",
+  irn_flags => "R",
+  state     => "exc_pinned",
+  comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+  reg_req   => { in => [ "general_purpose", "floating_point", "none" ] },
+  emit      => '. fmov %S2, (%S1)'
 },
 
 ); # end of %nodes
index 0d0d220..7b9ddad 100644 (file)
@@ -192,22 +192,6 @@ static ir_node *gen_Shr(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op
 
 
 
-/**
- * Creates an TEMPLATE RotL.
- *
- * @param dbg       firm node dbg
- * @param block     the block the new node should belong to
- * @param op1       first operator
- * @param op2       second operator
- * @param mode      node mode
- * @return the created TEMPLATE RotL node
- */
-static ir_node *gen_RotL(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
-       return new_rd_TEMPLATE_RotL(env->dbg, env->irg, env->block, op1, op2, env->mode);
-}
-
-
-
 /**
  * Transforms a Minus node.
  *
index 722761e..f7f6633 100644 (file)
 #include "../be.h"
 #include "../beabi.h"
 #include "../bemodule.h"
+#include "../begnuas.h"
 
 #include "bearch_TEMPLATE_t.h"
 
 #include "TEMPLATE_new_nodes.h"           /* TEMPLATE nodes interface */
 #include "gen_TEMPLATE_regalloc_if.h"     /* the generated interface (register type and class defenitions) */
-#include "TEMPLATE_gen_decls.h"           /* interface declaration emitter */
 #include "TEMPLATE_transform.h"
 #include "TEMPLATE_emitter.h"
 #include "TEMPLATE_map_regs.h"
 
-#define DEBUG_MODULE "firm.be.TEMPLATE.isa"
-
 /* TODO: ugly, but we need it to get access to the registers assigned to Phi nodes */
 static set *cur_reg_set = NULL;
 
@@ -47,95 +45,51 @@ static set *cur_reg_set = NULL;
  *           |___/
  **************************************************/
 
-static ir_node *my_skip_proj(const ir_node *n) {
-       while (is_Proj(n))
-               n = get_Proj_pred(n);
-       return (ir_node *)n;
-}
-
 /**
  * Return register requirements for a TEMPLATE node.
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *TEMPLATE_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
-       const TEMPLATE_register_req_t *irn_req;
+static const
+arch_register_req_t *TEMPLATE_get_irn_reg_req(const void *self,
+                                              const ir_node *node, int pos) {
        long               node_pos = pos == -1 ? 0 : pos;
-       ir_mode           *mode     = get_irn_mode(irn);
-       FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
+       ir_mode           *mode     = get_irn_mode(node);
 
        if (mode == mode_T || mode == mode_M) {
-               DBG((mod, LEVEL_1, "ignoring mode_T, mode_M node %+F\n", irn));
-               return NULL;
+               return arch_no_register_req;
        }
 
-       DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
-
-       if (is_Proj(irn)) {
+       if (is_Proj(node)) {
                /* in case of a proj, we need to get the correct OUT slot */
                /* of the node corresponding to the proj number */
                if (pos == -1) {
-                       node_pos = TEMPLATE_translate_proj_pos(irn);
-               }
-               else {
+                       node_pos = TEMPLATE_translate_proj_pos(node);
+               } else {
                        node_pos = pos;
                }
 
-               irn = my_skip_proj(irn);
-
-               DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
+               node = skip_Proj_const(node);
        }
 
        /* get requirements for our own nodes */
-       if (is_TEMPLATE_irn(irn)) {
+       if (is_TEMPLATE_irn(node)) {
+               const arch_register_req_t *req;
                if (pos >= 0) {
-                       irn_req = get_TEMPLATE_in_req(irn, pos);
-               }
-               else {
-                       irn_req = get_TEMPLATE_out_req(irn, node_pos);
+                       req = get_TEMPLATE_in_req(node, pos);
+               } else {
+                       req = get_TEMPLATE_out_req(node, node_pos);
                }
 
-               DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
+               assert(req != NULL);
 
-               memcpy(req, &(irn_req->req), sizeof(*req));
-
-               if (arch_register_req_is(&(irn_req->req), should_be_same)) {
-                       assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
-                       req->other_same = get_irn_n(irn, irn_req->same_pos);
-               }
-
-               if (arch_register_req_is(&(irn_req->req), should_be_different)) {
-                       assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
-                       req->other_different = get_irn_n(irn, irn_req->different_pos);
-               }
-       }
-       /* get requirements for FIRM nodes */
-       else {
-               /* treat Phi like Const with default requirements */
-               if (is_Phi(irn)) {
-                       DB((mod, LEVEL_1, "returning standard reqs for %+F\n", irn));
-
-                       if (mode_is_float(mode)) {
-                               memcpy(req, &(TEMPLATE_default_req_TEMPLATE_floating_point.req), sizeof(*req));
-                       }
-                       else if (mode_is_int(mode) || mode_is_reference(mode)) {
-                               memcpy(req, &(TEMPLATE_default_req_TEMPLATE_general_purpose.req), sizeof(*req));
-                       }
-                       else if (mode == mode_T || mode == mode_M) {
-                               DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn));
-                               return NULL;
-                       }
-                       else {
-                               assert(0 && "unsupported Phi-Mode");
-                       }
-               }
-               else {
-                       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
-                       req = NULL;
-               }
+               return req;
        }
 
-       return req;
+       /* unknowns should be transformed already */
+       assert(!is_Unknown(node));
+
+       return arch_no_register_req;
 }
 
 static void TEMPLATE_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
@@ -143,7 +97,7 @@ static void TEMPLATE_set_irn_reg(const void *self, ir_node *irn, const arch_regi
 
        if (is_Proj(irn)) {
                pos = TEMPLATE_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj(irn);
        }
 
        if (is_TEMPLATE_irn(irn)) {
@@ -164,7 +118,7 @@ static const arch_register_t *TEMPLATE_get_irn_reg(const void *self, const ir_no
 
        if (is_Proj(irn)) {
                pos = TEMPLATE_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj_const(irn);
        }
 
        if (is_TEMPLATE_irn(irn)) {
@@ -180,7 +134,7 @@ static const arch_register_t *TEMPLATE_get_irn_reg(const void *self, const ir_no
 }
 
 static arch_irn_class_t TEMPLATE_classify(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_cfop(irn)) {
                return arch_irn_class_branch;
@@ -193,7 +147,7 @@ static arch_irn_class_t TEMPLATE_classify(const void *self, const ir_node *irn)
 }
 
 static arch_irn_flags_t TEMPLATE_get_flags(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_TEMPLATE_irn(irn)) {
                return get_TEMPLATE_flags(irn);
@@ -205,12 +159,12 @@ static arch_irn_flags_t TEMPLATE_get_flags(const void *self, const ir_node *irn)
        return 0;
 }
 
-static ir_entity *TEMPLATE_get_frame_entity(const void *self, const ir_node *irn) {
+static ir_entity *TEMPLATE_get_frame_entity(const void *self, const ir_node *node) {
        /* TODO: return the ir_entity assigned to the frame */
        return NULL;
 }
 
-static void TEMPLATE_set_frame_entity(const void *self, const ir_node *irn, ir_entity *ent) {
+static void TEMPLATE_set_frame_entity(const void *self, ir_node *node, ir_entity *ent) {
        /* TODO: set the ir_entity assigned to the frame */
 }
 
@@ -292,7 +246,7 @@ static void TEMPLATE_before_sched(void *self) {
        /* Some stuff you need to do after scheduling but before register allocation */
 }
 
-static void TEMPLATE_before_ra(void *self, be_irg_t *birg) {
+static void TEMPLATE_before_ra(void *self) {
        /* Some stuff you need to do after scheduling but before register allocation */
 }
 
@@ -309,14 +263,8 @@ static void TEMPLATE_after_ra(void *self) {
 static void TEMPLATE_emit_and_done(void *self) {
        TEMPLATE_code_gen_t *cg = self;
        ir_graph           *irg = cg->irg;
-       FILE               *out = cg->isa->out;
 
-       if (cg->emit_decls) {
-               TEMPLATE_gen_decls(out);
-               cg->emit_decls = 0;
-       }
-
-       TEMPLATE_gen_routine(out, irg, cg);
+       TEMPLATE_gen_routine(cg, irg);
 
        cur_reg_set = NULL;
 
@@ -325,11 +273,13 @@ static void TEMPLATE_emit_and_done(void *self) {
        free(self);
 }
 
-static void *TEMPLATE_cg_init(const be_irg_t *birg);
+static void *TEMPLATE_cg_init(be_irg_t *birg);
 
 static const arch_code_generator_if_t TEMPLATE_code_gen_if = {
        TEMPLATE_cg_init,
+       NULL,                    /* before abi introduce hook */
        TEMPLATE_prepare_graph,
+       NULL,                    /* spill hook */
        TEMPLATE_before_sched,   /* before scheduling hook */
        TEMPLATE_before_ra,      /* before register allocation hook */
        TEMPLATE_after_ra,       /* after register allocation hook */
@@ -340,7 +290,7 @@ static const arch_code_generator_if_t TEMPLATE_code_gen_if = {
 /**
  * Initializes the code generator.
  */
-static void *TEMPLATE_cg_init(const be_irg_t *birg) {
+static void *TEMPLATE_cg_init(be_irg_t *birg) {
        TEMPLATE_isa_t      *isa = (TEMPLATE_isa_t *)birg->main_env->arch_env->isa;
        TEMPLATE_code_gen_t *cg  = xmalloc(sizeof(*cg));
 
@@ -352,13 +302,6 @@ static void *TEMPLATE_cg_init(const be_irg_t *birg) {
        cg->birg     = birg;
        FIRM_DBG_REGISTER(cg->mod, "firm.be.TEMPLATE.cg");
 
-       isa->num_codegens++;
-
-       if (isa->num_codegens > 1)
-               cg->emit_decls = 0;
-       else
-               cg->emit_decls = 1;
-
        cur_reg_set = cg->reg_set;
 
        TEMPLATE_irn_ops.cg = cg;
@@ -379,33 +322,35 @@ static void *TEMPLATE_cg_init(const be_irg_t *birg) {
  *****************************************************************/
 
 static TEMPLATE_isa_t TEMPLATE_isa_template = {
-       &TEMPLATE_isa_if,
-       &TEMPLATE_general_purpose_regs[REG_R6],
-       &TEMPLATE_general_purpose_regs[REG_R7],
-       -1,
-       0
+       {
+               &TEMPLATE_isa_if,             /* isa interface implementation */
+               &TEMPLATE_general_purpose_regs[REG_SP],  /* stack pointer register */
+               &TEMPLATE_general_purpose_regs[REG_BP],  /* base pointer register */
+               -1,                          /* stack direction */
+               NULL,                        /* main environment */
+       },
+       {},                              /* emitter environment */
 };
 
 /**
  * Initializes the backend ISA and opens the output file.
  */
 static void *TEMPLATE_init(FILE *outfile) {
-       static int inited = 0;
+       static int run_once = 0;
        TEMPLATE_isa_t *isa;
 
-       if(inited)
+       if(run_once)
                return NULL;
+       run_once = 1;
 
        isa = xcalloc(1, sizeof(*isa));
        memcpy(isa, &TEMPLATE_isa_template, sizeof(*isa));
 
-       isa->out = outfile;
+       be_emit_init_env(&isa->emit, outfile);
 
        TEMPLATE_register_init(isa);
        TEMPLATE_create_opcodes();
 
-       inited = 1;
-
        return isa;
 }
 
@@ -415,6 +360,12 @@ static void *TEMPLATE_init(FILE *outfile) {
  * Closes the output file and frees the ISA structure.
  */
 static void TEMPLATE_done(void *self) {
+       TEMPLATE_isa_t *isa = self;
+
+       /* emit now all global declarations */
+       be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env);
+
+       be_emit_destroy_env(&isa->emit);
        free(self);
 }
 
@@ -470,7 +421,7 @@ static void *TEMPLATE_abi_init(const be_abi_call_t *call, const arch_env_t *arch
  * @return The between type of for that call.
  */
 static ir_type *TEMPLATE_get_between_type(void *self) {
-       TEMPLATE_abi_env_t *env = self;
+       //TEMPLATE_abi_env_t *env = self;
        static ir_type *between_type = NULL;
        static ir_entity *old_bp_ent    = NULL;
 
@@ -513,7 +464,7 @@ static const arch_register_t *TEMPLATE_abi_prologue(void *self, ir_node **mem, p
 
 /* Build the epilog */
 static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map) {
-       TEMPLATE_abi_env_t *env = self;
+       //TEMPLATE_abi_env_t *env = self;
 }
 
 static const be_abi_callbacks_t TEMPLATE_abi_callbacks = {
index 8b69980..39ce981 100644 (file)
@@ -5,6 +5,7 @@
 #include "bearch_TEMPLATE.h"
 #include "TEMPLATE_nodes_attr.h"
 #include "../be.h"
+#include "../beemitter.h"
 #include "set.h"
 
 typedef struct _TEMPLATE_isa_t TEMPLATE_isa_t;
@@ -14,19 +15,14 @@ typedef struct _TEMPLATE_code_gen_t {
        ir_graph                       *irg;            /**< current irg */
        const arch_env_t               *arch_env;       /**< the arch env */
        set                            *reg_set;        /**< set to memorize registers for FIRM nodes (e.g. phi) */
-       int                             emit_decls;     /**< flag indicating if decls were already emitted */
        TEMPLATE_isa_t                 *isa;            /**< the isa instance */
        const be_irg_t                 *birg;           /**< The be-irg (contains additional information about the irg) */
        DEBUG_ONLY(firm_dbg_module_t   *mod;)           /**< debugging module */
 } TEMPLATE_code_gen_t;
 
 struct _TEMPLATE_isa_t {
-       const arch_isa_if_t   *impl;
-       const arch_register_t *sp;            /**< The stack pointer register. */
-       const arch_register_t *bp;            /**< The base pointer register. */
-       const int              stack_dir;     /**< -1 for decreasing, 1 for increasing. */
-       int                    num_codegens;
-       FILE                  *out;           /**< output file */
+       arch_isa_t             arch_isa;      /**< must be derived from arch_isa */
+       be_emit_env_t          emit;          /**< emit datastructure */
 };
 
 
index f346a30..3c5636c 100644 (file)
@@ -527,7 +527,7 @@ static void emit_arm_SwitchJmp(ir_node *irn, void *env) {
        ir_node **projs;
        int n_projs;
        int block_nr;
-       int default_block_num;
+       int default_block_num = -1;
 
        block_nr = get_irn_node_nr(irn);
        n_projs = get_arm_n_projs(irn);
@@ -543,6 +543,7 @@ static void emit_arm_SwitchJmp(ir_node *irn, void *env) {
 
                projs[get_Proj_proj(proj)] = proj;
        }
+       assert(default_block_num >= 0);
 
        // CMP %1S, n_projs - 1
        // BHI default
index d7ad4b4..688b2cd 100644 (file)
@@ -4,7 +4,7 @@
  * $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
@@ -32,7 +32,7 @@
 
 #include "arm_nodes_attr.h"
 #include "arm_new_nodes.h"
-#include "gen_arm_regalloc_if.h"
+#include "gen_arm_regalloc_if_t.h"
 
 #include "../beabi.h"
 #include "bearch_arm_t.h"
@@ -56,77 +56,48 @@ const char *arm_shf_mod_name(arm_shift_modifier mod) {
  *                       |_|
  ***********************************************************************************/
 
-/**
- * Returns a string containing the names of all registers within the limited bitset
- */
-static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
-       bitset_t *bs   = bitset_alloca(req->cls->n_regs);
-       char     *p    = buf;
-       int       size = 0;
-       int       i, cnt;
-
-       req->limited(NULL, bs);
-
-       for (i = 0; i < req->cls->n_regs; i++) {
-               if (bitset_is_set(bs, i)) {
-                       cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
-                       if (cnt < 0) {
-                               fprintf(stderr, "dumper problem, exiting\n");
-                               exit(1);
-                       }
-
-                       p    += cnt;
-                       size += cnt;
-
-                       if (size >= max)
-                               break;
-               }
-       }
-
-       return buf;
-}
-
 /**
  * Dumps the register requirements for either in or out.
  */
-static void dump_reg_req(FILE *F, ir_node *n, const arm_register_req_t **reqs, int inout) {
+static void dump_reg_req(FILE *F, const ir_node *node,
+                         const arch_register_req_t **reqs, int inout) {
        char *dir = inout ? "out" : "in";
-       int   max = inout ? get_arm_n_res(n) : get_irn_arity(n);
-       char *buf = alloca(1024);
+       int   max = inout ? get_arm_n_res(node) : get_irn_arity(node);
+       char  buf[1024];
        int   i;
 
-       memset(buf, 0, 1024);
+       memset(buf, 0, sizeof(buf));
 
        if (reqs) {
                for (i = 0; i < max; i++) {
                        fprintf(F, "%sreq #%d =", dir, i);
 
-                       if (reqs[i]->req.type == arch_register_req_type_none) {
+                       if (reqs[i]->type == arch_register_req_type_none) {
                                fprintf(F, " n/a");
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_normal) {
-                               fprintf(F, " %s", reqs[i]->req.cls->name);
+                       if (reqs[i]->type & arch_register_req_type_normal) {
+                               fprintf(F, " %s", reqs[i]->cls->name);
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_limited) {
-                               fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
+                       if (reqs[i]->type & arch_register_req_type_limited) {
+                               fprintf(F, " %s",
+                                       arch_register_req_format(buf, sizeof(buf), reqs[i], node));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
-                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_same) {
+                               ir_fprintf(F, " same as %+F", get_irn_n(node, reqs[i]->other_same));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
-                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_different) {
+                               ir_fprintf(F, " different from %+F", get_irn_n(node, reqs[i]->other_different));
                        }
 
                        fprintf(F, "\n");
                }
 
                fprintf(F, "\n");
-       }
-       else {
+       } else {
                fprintf(F, "%sreq = N/A\n", dir);
        }
 }
@@ -143,7 +114,7 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
        int          bad  = 0;
        int          i;
        arm_attr_t  *attr = get_arm_attr(n);
-       const arm_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t     **slots;
        arm_shift_modifier        mod;
 
@@ -277,7 +248,7 @@ arm_attr_t *get_arm_attr(const ir_node *node) {
 /**
  * Returns the argument register requirements of a arm node.
  */
-const arm_register_req_t **get_arm_in_req_all(const ir_node *node) {
+const arch_register_req_t **get_arm_in_req_all(const ir_node *node) {
        arm_attr_t *attr = get_arm_attr(node);
        return attr->in_req;
 }
@@ -285,7 +256,7 @@ const arm_register_req_t **get_arm_in_req_all(const ir_node *node) {
 /**
  * Returns the result register requirements of an arm node.
  */
-const arm_register_req_t **get_arm_out_req_all(const ir_node *node) {
+const arch_register_req_t **get_arm_out_req_all(const ir_node *node) {
        arm_attr_t *attr = get_arm_attr(node);
        return attr->out_req;
 }
@@ -293,7 +264,7 @@ const arm_register_req_t **get_arm_out_req_all(const ir_node *node) {
 /**
  * Returns the argument register requirement at position pos of an arm node.
  */
-const arm_register_req_t *get_arm_in_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos) {
        arm_attr_t *attr = get_arm_attr(node);
        return attr->in_req[pos];
 }
@@ -301,7 +272,7 @@ const arm_register_req_t *get_arm_in_req(const ir_node *node, int pos) {
 /**
  * Returns the result register requirement at position pos of an arm node.
  */
-const arm_register_req_t *get_arm_out_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_arm_out_req(const ir_node *node, int pos) {
        arm_attr_t *attr = get_arm_attr(node);
        return attr->out_req[pos];
 }
@@ -309,7 +280,7 @@ const arm_register_req_t *get_arm_out_req(const ir_node *node, int pos) {
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_arm_req_out(ir_node *node, const arm_register_req_t *req, int pos) {
+void set_arm_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
        arm_attr_t *attr   = get_arm_attr(node);
        attr->out_req[pos] = req;
 }
@@ -317,7 +288,7 @@ void set_arm_req_out(ir_node *node, const arm_register_req_t *req, int pos) {
 /**
  * Sets the complete OUT requirements of node.
  */
-void set_arm_req_out_all(ir_node *node, const arm_register_req_t **reqs) {
+void set_arm_req_out_all(ir_node *node, const arch_register_req_t **reqs) {
        arm_attr_t *attr = get_arm_attr(node);
        attr->out_req    = reqs;
 }
@@ -325,7 +296,7 @@ void set_arm_req_out_all(ir_node *node, const arm_register_req_t **reqs) {
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_arm_req_in(ir_node *node, const arm_register_req_t *req, int pos) {
+void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
        arm_attr_t *attr  = get_arm_attr(node);
        attr->in_req[pos] = req;
 }
@@ -498,8 +469,8 @@ arm_shift_modifier get_arm_shift_modifier(ir_node *node) {
 }
 
 /* Set the ARM machine node attributes to default values. */
-void init_arm_attributes(ir_node *node, int flags, const arm_register_req_t ** in_reqs,
-                                                const arm_register_req_t ** out_reqs, const be_execution_unit_t ***execution_units,
+void init_arm_attributes(ir_node *node, int flags, const arch_register_req_t ** in_reqs,
+                                                const arch_register_req_t ** out_reqs, const be_execution_unit_t ***execution_units,
                                                 int n_res, unsigned latency) {
        arm_attr_t *attr = get_arm_attr(node);
        attr->in_req           = in_reqs;
@@ -531,70 +502,63 @@ static int arm_comp_condJmp(arm_attr_t *attr_a, arm_attr_t *attr_b) {
  *
  ***************************************************************************************/
 
-/* limit the possible registers for sp in arm_StoreStackM4Inc */
-static void limit_reg_arm_StoreStackM4Inc_sp(void *_unused, bitset_t *bs) {
-  bs = bitset_clear_all(bs);   /* disallow all register (positive constraints given) */
-  bitset_set(bs, 14);           /* allow r13 */
-  bitset_clear(bs, 13);         /* disallow ignore reg r12 */
-  bitset_clear(bs, 14);         /* disallow ignore reg r13 */
-  bitset_clear(bs, 15);         /* disallow ignore reg r15 */
-  bitset_clear(bs, 16);         /* disallow ignore reg rxx */
-}
-
-static const arm_register_req_t _arm_req_sp = {
-  {
-    arch_register_req_type_limited,
-    &arm_reg_classes[CLASS_arm_gp],
-    limit_reg_arm_StoreStackM4Inc_sp,
-    NULL,        /* limit environment */
-    NULL,        /* same node */
-    NULL         /* different node */
-  },
-  0,
-  0
+#ifdef BIT
+#undef BIT
+#endif
+#define BIT(x)  (1 << (x % 32))
+
+static unsigned arm_req_sp_limited[] = { BIT(REG_SP) };
+static const arch_register_req_t _arm_req_sp = {
+       arch_register_req_type_limited,
+       &arm_reg_classes[CLASS_arm_gp],
+       arm_req_sp_limited,
+       -1,
+       -1
 };
 
 /* construct Store: Store(ptr, val, mem) = ST ptr,val */
-ir_node *new_r_arm_StoreStackMInc(ir_graph *irg, ir_node *block, ir_node *mem, ir_node *sp,
-                                                                 int n_regs, ir_node **regs, ir_mode *mode) {
-  ir_node *res;
-  ir_node *in[16];
-  int flags = 0;
-  static const arm_register_req_t *_in_req_arm_StoreStackM4Inc[] =
-  {
-       &arm_default_req_none,
-    &_arm_req_sp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-    &arm_default_req_arm_gp,
-  };
-
-  assert(n_regs <= 15);
-
-  in[0] = mem;
-  in[1] = sp;
-  memcpy(&in[2], regs, n_regs * sizeof(in[0]));
-  res = new_ir_node(NULL, irg, block, op_arm_StoreStackM4Inc, mode, 2 + n_regs, in);
-  flags |= arch_irn_flags_rematerializable;   /* op can be easily recalculated */
-
-  /* init node attributes */
-  init_arm_attributes(res, flags, _in_req_arm_StoreStackM4Inc, NULL, NULL, 0, 1);
-
-  res = optimize_node(res);
-  irn_vrfy_irg(res, irg);
-
-  return res;
+ir_node *new_r_arm_StoreStackMInc(ir_graph *irg, ir_node *block, ir_node *mem,
+                                  ir_node *sp, int n_regs, ir_node **regs,
+                                  ir_mode *mode) {
+       ir_node *res;
+       ir_node *in[16];
+       int flags = 0;
+       static const arch_register_req_t *_in_req_arm_StoreStackM4Inc[] =
+       {
+               &arm_StoreStackM4Inc_reg_req_in_0,
+               &arm_StoreStackM4Inc_reg_req_in_1,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+               &arm_StoreStackM4Inc_reg_req_in_2,
+       };
+
+       assert(n_regs <= 15);
+
+       in[0] = mem;
+       in[1] = sp;
+       memcpy(&in[2], regs, n_regs * sizeof(in[0]));
+       res = new_ir_node(NULL, irg, block, op_arm_StoreStackM4Inc, mode, 2 + n_regs, in);
+       flags |= arch_irn_flags_rematerializable;   /* op can be easily recalculated */
+
+       /* init node attributes */
+       init_arm_attributes(res, flags, _in_req_arm_StoreStackM4Inc, NULL, NULL, 0, 1);
+
+       res = optimize_node(res);
+       irn_vrfy_irg(res, irg);
+
+       return res;
 }
 
 /************************************************
index e453f09..b2f38c0 100644 (file)
@@ -28,37 +28,37 @@ arm_attr_t *get_arm_attr(const ir_node *node);
 /**
  * Returns the argument register requirements of an arm node.
  */
-const arm_register_req_t **get_arm_in_req_all(const ir_node *node);
+const arch_register_req_t **get_arm_in_req_all(const ir_node *node);
 
 /**
  * Returns the result register requirements of an arm node.
  */
-const arm_register_req_t **get_arm_out_req_all(const ir_node *node);
+const arch_register_req_t **get_arm_out_req_all(const ir_node *node);
 
 /**
  * Returns the argument register requirements of an arm node.
  */
-const arm_register_req_t *get_arm_in_req(const ir_node *node, int pos);
+const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos);
 
 /**
  * Returns the result register requirements of an arm node.
  */
-const arm_register_req_t *get_arm_out_req(const ir_node *node, int pos);
+const arch_register_req_t *get_arm_out_req(const ir_node *node, int pos);
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_arm_req_out(ir_node *node, const arm_register_req_t *req, int pos);
+void set_arm_req_out(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Sets the complete OUT requirements of node.
  */
-void set_arm_req_out_all(ir_node *node, const arm_register_req_t **reqs);
+void set_arm_req_out_all(ir_node *node, const arch_register_req_t **reqs);
 
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_arm_req_in(ir_node *node, const arm_register_req_t *req, int pos);
+void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Returns the register flag of an arm node.
@@ -103,8 +103,8 @@ int get_arm_n_res(const ir_node *node);
 /**
  * Set the ARM machine node attributes to default values.
  */
-void init_arm_attributes(ir_node *node, int flags, const arm_register_req_t ** in_reqs,
-                         const arm_register_req_t ** out_reqs, const be_execution_unit_t ***execution_units, int n_res, unsigned latency);
+void init_arm_attributes(ir_node *node, int flags, const arch_register_req_t ** in_reqs,
+                         const arch_register_req_t ** out_reqs, const be_execution_unit_t ***execution_units, int n_res, unsigned latency);
 
 /**
  * Returns the tarval
index 522881a..64a751d 100644 (file)
@@ -4,13 +4,6 @@
 #include "../bearch.h"
 #include "../../common/firm_types.h"
 
-/** A register requirement. */
-typedef struct _arm_register_req_t {
-       const arch_register_req_t req;
-       int same_pos;        /**< in case of "should be same" we need to remember the pos to get the irn */
-       int different_pos;   /**< in case of "should be different" we need to remember the pos to get the irn */
-} arm_register_req_t;
-
 /**
  * Possible ARM register shift types.
  */
@@ -66,8 +59,8 @@ typedef struct _arm_attr_t {
        arch_irn_flags_t flags;             /**< indicating if spillable, rematerializeable ... etc. */
        int              n_res;             /**< number of results for this node */
 
-       const arm_register_req_t **in_req;  /**< register requirements for arguments */
-       const arm_register_req_t **out_req; /**< register requirements for results */
+       const arch_register_req_t **in_req;  /**< register requirements for arguments */
+       const arch_register_req_t **out_req; /**< register requirements for results */
 
        ir_mode *op_mode;                   /**< operation mode */
        unsigned instr_fl;                  /**< condition code, shift modifier */
index 0f56948..912b6d2 100644 (file)
@@ -54,100 +54,63 @@ static set *cur_reg_set = NULL;
  *           |___/
  **************************************************/
 
-static ir_node *my_skip_proj(const ir_node *n) {
-       while (is_Proj(n))
-               n = get_Proj_pred(n);
-       return (ir_node *)n;
-}
-
 /**
  * Return register requirements for a arm node.
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *arm_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
-       const arm_register_req_t *irn_req;
+static const
+arch_register_req_t *arm_get_irn_reg_req(const void *self, const ir_node *node,
+                                         int pos) {
        long               node_pos = pos == -1 ? 0 : pos;
-       ir_mode           *mode     = get_irn_mode(irn);
+       ir_mode           *mode     = get_irn_mode(node);
        FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
 
-       if (is_Block(irn) || mode == mode_X || mode == mode_M) {
-               DBG((mod, LEVEL_1, "ignoring mode_T, mode_M node %+F\n", irn));
-               return NULL;
+       if (is_Block(node) || mode == mode_X || mode == mode_M) {
+               DBG((mod, LEVEL_1, "ignoring mode_T, mode_M node %+F\n", node));
+               return arch_no_register_req;
        }
 
        if (mode == mode_T && pos < 0) {
-               DBG((mod, LEVEL_1, "ignoring request for OUT requirements at %+F\n", irn));
-               return NULL;
+               DBG((mod, LEVEL_1, "ignoring request for OUT requirements at %+F\n", node));
+               return arch_no_register_req;
        }
 
-       DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
+       DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, node));
 
-       if (is_Proj(irn)) {
+       if (is_Proj(node)) {
                /* in case of a proj, we need to get the correct OUT slot */
                /* of the node corresponding to the proj number */
                if (pos == -1) {
-                       node_pos = arm_translate_proj_pos(irn);
+                       node_pos = arm_translate_proj_pos(node);
                }
                else {
                        node_pos = pos;
                }
 
-               irn = my_skip_proj(irn);
+               node = skip_Proj_const(node);
 
-               DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
+               DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", node, node_pos));
        }
 
        /* get requirements for our own nodes */
-       if (is_arm_irn(irn)) {
+       if (is_arm_irn(node)) {
+               const arch_register_req_t *req;
                if (pos >= 0) {
-                       irn_req = get_arm_in_req(irn, pos);
+                       req = get_arm_in_req(node, pos);
+               } else {
+                       req = get_arm_out_req(node, node_pos);
                }
-               else {
-                       irn_req = get_arm_out_req(irn, node_pos);
-               }
-
-               DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
-
-               memcpy(req, &(irn_req->req), sizeof(*req));
 
-               if (arch_register_req_is(&(irn_req->req), should_be_same)) {
-                       assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
-                       req->other_same = get_irn_n(irn, irn_req->same_pos);
-               }
-
-               if (arch_register_req_is(&(irn_req->req), should_be_different)) {
-                       assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
-                       req->other_different = get_irn_n(irn, irn_req->different_pos);
-               }
+               DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", node, pos));
+               return req;
        }
-       /* get requirements for FIRM nodes */
-       else {
-               /* treat Phi like Const with default requirements */
-               if (is_Phi(irn)) {
-                       DB((mod, LEVEL_1, "returning standard reqs for %+F\n", irn));
 
-                       if (mode_is_float(mode)) {
-                               memcpy(req, &(arm_default_req_arm_fpa.req), sizeof(*req));
-                       }
-                       else if (mode_is_int(mode) || mode_is_reference(mode)) {
-                               memcpy(req, &(arm_default_req_arm_gp.req), sizeof(*req));
-                       }
-                       else if (mode == mode_T || mode == mode_M) {
-                               DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn));
-                               return NULL;
-                       }
-                       else {
-                               assert(0 && "unsupported Phi-Mode");
-                       }
-               }
-               else {
-                       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
-                       req = NULL;
-               }
-       }
+       /* unknown should be tranformed by now */
+       assert(!is_Unknown(node));
+       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", node));
 
-       return req;
+       return arch_no_register_req;
 }
 
 static void arm_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
@@ -160,7 +123,7 @@ static void arm_set_irn_reg(const void *self, ir_node *irn, const arch_register_
                }
 
                pos = arm_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj(irn);
        }
 
        if (is_arm_irn(irn)) {
@@ -186,7 +149,7 @@ static const arch_register_t *arm_get_irn_reg(const void *self, const ir_node *i
                }
 
                pos = arm_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj_const(irn);
        }
 
        if (is_arm_irn(irn)) {
@@ -202,7 +165,7 @@ static const arch_register_t *arm_get_irn_reg(const void *self, const ir_node *i
 }
 
 static arch_irn_class_t arm_classify(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_cfop(irn)) {
                return arch_irn_class_branch;
@@ -215,7 +178,7 @@ static arch_irn_class_t arm_classify(const void *self, const ir_node *irn) {
 }
 
 static arch_irn_flags_t arm_get_flags(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_arm_irn(irn)) {
                return get_arm_flags(irn);
@@ -871,9 +834,6 @@ static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *
 //     ir_node *regs[16];
 //     int n_regs = 0;
        arch_register_class_t *gp = &arm_reg_classes[CLASS_arm_gp];
-       static const arm_register_req_t *fp_req[] = {
-               &arm_default_req_arm_gp_r11
-       };
 
        ir_node *fp = be_abi_reg_map_get(reg_map, env->isa->bp);
        ir_node *ip = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_R12]);
@@ -900,23 +860,25 @@ static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *
 //             set_arm_req_out(sp, &arm_default_req_arm_gp_sp, 0);
 //             arch_set_irn_register(env->arch_env, sp, env->isa->sp);
        store = new_rd_arm_StoreStackM4Inc(NULL, irg, block, sp, fp, ip, lr, pc, *mem);
-               set_arm_req_out(store, &arm_default_req_arm_gp_sp, 0);
-//             arch_set_irn_register(env->arch_env, store, env->isa->sp);
+       // TODO
+       // set_arm_req_out(store, &arm_default_req_arm_gp_sp, 0);
+       // arch_set_irn_register(env->arch_env, store, env->isa->sp);
 
        sp = new_r_Proj(irg, block, store, env->isa->sp->reg_class->mode, pn_arm_StoreStackM4Inc_ptr);
-               arch_set_irn_register(env->arch_env, sp, env->isa->sp);
+       arch_set_irn_register(env->arch_env, sp, env->isa->sp);
        *mem = new_r_Proj(irg, block, store, mode_M, pn_arm_StoreStackM4Inc_M);
 
        keep = be_new_CopyKeep_single(gp, irg, block, ip, sp, get_irn_mode(ip));
-               be_node_set_reg_class(keep, 1, gp);
-               arch_set_irn_register(env->arch_env, keep, &arm_gp_regs[REG_R12]);
-               be_set_constr_single_reg(keep, BE_OUT_POS(0), &arm_gp_regs[REG_R12] );
+       be_node_set_reg_class(keep, 1, gp);
+       arch_set_irn_register(env->arch_env, keep, &arm_gp_regs[REG_R12]);
+       be_set_constr_single_reg(keep, BE_OUT_POS(0), &arm_gp_regs[REG_R12] );
 
        fp = new_rd_arm_Sub_i(NULL, irg, block, keep, get_irn_mode(fp),
                              new_tarval_from_long(4, get_irn_mode(fp)));
-               set_arm_req_out_all(fp, fp_req);
-               //set_arm_req_out(fp, &arm_default_req_arm_gp_r11, 0);
-               arch_set_irn_register(env->arch_env, fp, env->isa->bp);
+       // TODO...
+       //set_arm_req_out_all(fp, fp_req);
+       //set_arm_req_out(fp, &arm_default_req_arm_gp_r11, 0);
+       arch_set_irn_register(env->arch_env, fp, env->isa->bp);
 
 //     be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_R0], r0);
 //     be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_R1], r1);
@@ -937,11 +899,8 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m
        ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
        ir_node *curr_pc = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_PC]);
        ir_node *curr_lr = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_LR]);
-       static const arm_register_req_t *sub12_req[] = {
-               &arm_default_req_arm_gp_sp
-       };
 
-//     TODO: Activate Omit fp in epilogue
+       // TODO: Activate Omit fp in epilogue
        if(env->flags.try_omit_fp) {
                curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
                add_irn_dep(curr_sp, *mem);
@@ -959,12 +918,14 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m
                ir_node *load_node;
                tarval *tv = new_tarval_from_long(12,mode_Iu);
                sub12_node = new_rd_arm_Sub_i(NULL, env->irg, bl, curr_bp, mode_Iu, tv);
-               set_arm_req_out_all(sub12_node, sub12_req);
+               // FIXME
+               //set_arm_req_out_all(sub12_node, sub12_req);
                arch_set_irn_register(env->arch_env, sub12_node, env->isa->sp);
                load_node = new_rd_arm_LoadStackM3( NULL, env->irg, bl, sub12_node, *mem );
-               set_arm_req_out(load_node, &arm_default_req_arm_gp_r11, 0);
-               set_arm_req_out(load_node, &arm_default_req_arm_gp_sp, 1);
-               set_arm_req_out(load_node, &arm_default_req_arm_gp_pc, 2);
+               // FIXME
+               //set_arm_req_out(load_node, &arm_default_req_arm_gp_r11, 0);
+               //set_arm_req_out(load_node, &arm_default_req_arm_gp_sp, 1);
+               //set_arm_req_out(load_node, &arm_default_req_arm_gp_pc, 2);
                curr_bp = new_r_Proj(env->irg, bl, load_node, env->isa->bp->reg_class->mode, pn_arm_LoadStackM3_res0);
                curr_sp = new_r_Proj(env->irg, bl, load_node, env->isa->sp->reg_class->mode, pn_arm_LoadStackM3_res1);
                curr_pc = new_r_Proj(env->irg, bl, load_node, mode_Iu, pn_arm_LoadStackM3_res2);
index 5c581fc..ed568fc 100644 (file)
@@ -59,7 +59,6 @@ struct _be_options_t {
 
 struct _be_main_env_t {
        struct obstack obst;
-       struct _be_node_factory_t *node_factory;
        struct _arch_env_t *arch_env;
        struct _be_options_t *options;
        struct _arch_code_generator_t *cg;
index 8b65cca..7564d82 100644 (file)
@@ -5,7 +5,6 @@
  * @date   7.3.2005
  * @cvsid  $Id$
  */
-
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
@@ -28,6 +27,7 @@
 #include "height.h"
 #include "pdeq.h"
 #include "irtools.h"
+#include "raw_bitset.h"
 
 #include "be.h"
 #include "beabi.h"
@@ -87,6 +87,9 @@ struct _be_abi_irg_t {
        pmap                 *keep_map;     /**< mapping blocks to keep nodes. */
        pset                 *ignore_regs;  /**< Additional registers which shall be ignored. */
 
+       arch_register_req_t sp_req;
+       arch_register_req_t sp_cls_req;
+
        arch_irn_handler_t irn_handler;
        arch_irn_ops_t     irn_ops;
        DEBUG_ONLY(firm_dbg_module_t    *dbg;)          /**< The debugging module. */
@@ -644,9 +647,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i
        */
        be_node_set_reg_class(low_call, be_pos_Call_ptr, call->cls_addr);
 
-       /* Set input requirement for stack pointer. */
-       be_node_set_reg_class(low_call, be_pos_Call_sp, arch_get_irn_reg_class(isa->main_env->arch_env, curr_sp, -1));
-
        DBG((env->dbg, LEVEL_3, "\tcreated backend call %+F\n", low_call));
 
        /* Set the register classes and constraints of the Call parameters. */
@@ -1891,6 +1891,7 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
        pmap_entry *ent;
        ir_node *dummy;
        optimization_state_t state;
+       unsigned *limited_bitset;
 
        be_omit_fp = birg->main_env->options->omit_fp;
 
@@ -1906,6 +1907,16 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
        env->dce_survivor     = new_survive_dce();
        env->birg             = birg;
        env->stack_phis       = pset_new_ptr(16);
+
+       env->sp_req.type      = arch_register_req_type_limited;
+       env->sp_req.cls       = arch_register_get_class(env->isa->sp);
+       limited_bitset        = rbitset_obstack_alloc(&env->obst, env->sp_req.cls->n_regs);
+       rbitset_set(limited_bitset, arch_register_get_index(env->isa->sp));
+       env->sp_req.limited   = limited_bitset;
+
+       env->sp_cls_req.type  = arch_register_req_type_normal;
+       env->sp_cls_req.cls   = arch_register_get_class(env->isa->sp);
+
        /* Beware: later we replace this node by the real one, ensure it is not CSE'd
           to another Unknown or the stack pointer gets used */
        save_optimization_state(&state);
@@ -1938,8 +1949,9 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
 
        /* Make some important node pointers survive the dead node elimination. */
        survive_dce_register_irn(env->dce_survivor, &env->init_sp);
-       pmap_foreach(env->regs, ent)
+       pmap_foreach(env->regs, ent) {
                survive_dce_register_irn(env->dce_survivor, (ir_node **) &ent->value);
+       }
 
        arch_env_push_irn_handler(env->birg->main_env->arch_env, &env->irn_handler);
 
@@ -2152,33 +2164,19 @@ static const void *abi_get_irn_ops(const arch_irn_handler_t *handler, const ir_n
        return res;
 }
 
-static void be_abi_limited(void *data, bitset_t *bs)
-{
-       be_abi_irg_t *abi = data;
-       bitset_clear_all(bs);
-       bitset_set(bs, abi->isa->sp->index);
-}
-
-static const arch_register_req_t *abi_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
+static
+const arch_register_req_t *abi_get_irn_reg_req(const void *self,
+                                               const ir_node *irn, int pos)
 {
-       be_abi_irg_t *abi          = get_abi_from_ops(self);
-       const arch_register_t *reg = abi->isa->sp;
-
-       memset(req, 0, sizeof(req[0]));
+       be_abi_irg_t *abi = get_abi_from_ops(self);
 
        if(pos == BE_OUT_POS(0)) {
-               req->cls         = reg->reg_class;
-               req->type        = arch_register_req_type_limited;
-               req->limited     = be_abi_limited;
-               req->limited_env = abi;
-       }
-
-       else if(pos >= 0 && pos < get_irn_arity(irn)) {
-               req->cls  = reg->reg_class;
-               req->type = arch_register_req_type_normal;
+               return &abi->sp_req;
+       } else if(pos >= 0 && pos < get_irn_arity(irn)) {
+               return &abi->sp_cls_req;
        }
 
-       return req;
+       return arch_no_register_req;
 }
 
 static void abi_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
index 3749ace..db45736 100644 (file)
@@ -5,9 +5,8 @@
  *
  * $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_ALLOCA_H
 #include "bitset.h"
 #include "pset.h"
 #include "entity.h"
+#include "raw_bitset.h"
 
 #include "irprintf.h"
 
 /* Initialize the architecture environment struct. */
 arch_env_t *arch_env_init(arch_env_t *env, const arch_isa_if_t *isa_if, FILE *file_handle, be_main_env_t *main_env)
 {
-  memset(env, 0, sizeof(*env));
-  env->isa                  = isa_if->init(file_handle);
-  env->isa->main_env        = main_env;
-  return env;
+       memset(env, 0, sizeof(*env));
+       env->isa                  = isa_if->init(file_handle);
+       env->isa->main_env        = main_env;
+       return env;
 }
 
 arch_env_t *arch_env_push_irn_handler(arch_env_t *env,
-    const arch_irn_handler_t *handler)
+                                      const arch_irn_handler_t *handler)
 {
-  assert(env->handlers_tos < ARCH_MAX_HANDLERS);
-  env->handlers[env->handlers_tos++] = handler;
-  return env;
+       assert(env->handlers_tos < ARCH_MAX_HANDLERS);
+       env->handlers[env->handlers_tos++] = handler;
+       return env;
 }
 
 const arch_irn_handler_t *arch_env_pop_irn_handler(arch_env_t *env)
 {
-  assert(env->handlers_tos > 0 && env->handlers_tos <= ARCH_MAX_HANDLERS);
-  return env->handlers[--env->handlers_tos];
+       assert(env->handlers_tos > 0 && env->handlers_tos <= ARCH_MAX_HANDLERS);
+       return env->handlers[--env->handlers_tos];
 }
 
 static const arch_irn_ops_t *fallback_irn_ops = NULL;
 
 int arch_register_class_put(const arch_register_class_t *cls, bitset_t *bs)
 {
-  if(bs) {
-    int i, n;
-    for(i = 0, n = cls->n_regs; i < n; ++i)
-      bitset_set(bs, i);
-  }
+       if(bs) {
+               int i, n;
+               for(i = 0, n = cls->n_regs; i < n; ++i)
+                       bitset_set(bs, i);
+       }
 
-  return cls->n_regs;
+       return cls->n_regs;
 }
 
 /**
@@ -75,17 +75,17 @@ int arch_register_class_put(const arch_register_class_t *cls, bitset_t *bs)
 static INLINE const arch_irn_ops_t *
 get_irn_ops(const arch_env_t *env, const ir_node *irn)
 {
-  int i;
+       int i;
 
-  for(i = env->handlers_tos - 1; i >= 0; --i) {
-    const arch_irn_handler_t *handler = env->handlers[i];
-    const arch_irn_ops_t *ops = handler->get_irn_ops(handler, irn);
+       for(i = env->handlers_tos - 1; i >= 0; --i) {
+               const arch_irn_handler_t *handler = env->handlers[i];
+               const arch_irn_ops_t *ops = handler->get_irn_ops(handler, irn);
 
-    if(ops)
-      return ops;
-  }
+               if(ops)
+                       return ops;
+       }
 
-  return fallback_irn_ops;
+       return fallback_irn_ops;
 }
 
 const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn) {
@@ -93,23 +93,22 @@ const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn
 }
 
 const arch_register_req_t *arch_get_register_req(const arch_env_t *env,
-    arch_register_req_t *req, const ir_node *irn, int pos)
+                                                 const ir_node *irn, int pos)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  req->type = arch_register_req_type_none;
-  return ops->impl->get_irn_reg_req(ops, req, irn, pos);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       return ops->impl->get_irn_reg_req(ops, irn, pos);
 }
 
 void arch_set_frame_offset(const arch_env_t *env, ir_node *irn, int offset)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  ops->impl->set_frame_offset(ops, irn, offset);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       ops->impl->set_frame_offset(ops, irn, offset);
 }
 
 ir_entity *arch_get_frame_entity(const arch_env_t *env, ir_node *irn)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  return ops->impl->get_frame_entity(ops, irn);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       return ops->impl->get_frame_entity(ops, irn);
 }
 
 void arch_set_frame_entity(const arch_env_t *env, ir_node *irn, ir_entity *ent)
@@ -126,16 +125,18 @@ int arch_get_sp_bias(const arch_env_t *env, ir_node *irn)
 
 arch_inverse_t *arch_get_inverse(const arch_env_t *env, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  if(ops->impl->get_inverse) {
-    return ops->impl->get_inverse(ops, irn, i, inverse, obstack);
-  } else {
-    return NULL;
-  }
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+
+       if(ops->impl->get_inverse) {
+               return ops->impl->get_inverse(ops, irn, i, inverse, obstack);
+       } else {
+               return NULL;
+       }
 }
 
 int arch_possible_memory_operand(const arch_env_t *env, const ir_node *irn, unsigned int i) {
        const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+
        if(ops->impl->possible_memory_operand) {
                return ops->impl->possible_memory_operand(ops, irn, i);
        } else {
@@ -145,6 +146,7 @@ int arch_possible_memory_operand(const arch_env_t *env, const ir_node *irn, unsi
 
 void arch_perform_memory_operand(const arch_env_t *env, ir_node *irn, ir_node *spill, unsigned int i) {
        const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+
        if(ops->impl->perform_memory_operand) {
                ops->impl->perform_memory_operand(ops, irn, spill, i);
        } else {
@@ -154,42 +156,43 @@ void arch_perform_memory_operand(const arch_env_t *env, ir_node *irn, ir_node *s
 
 int arch_get_op_estimated_cost(const arch_env_t *env, const ir_node *irn)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  if(ops->impl->get_op_estimated_cost) {
-    return ops->impl->get_op_estimated_cost(ops, irn);
-  } else {
-    return 1;
-  }
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+
+       if(ops->impl->get_op_estimated_cost) {
+               return ops->impl->get_op_estimated_cost(ops, irn);
+       } else {
+               return 1;
+       }
 }
 
 int arch_is_possible_memory_operand(const arch_env_t *env, const ir_node *irn, int i)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  if(ops->impl->possible_memory_operand) {
-    return ops->impl->possible_memory_operand(ops, irn, i);
-  } else {
-    return 0;
-  }
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+
+       if(ops->impl->possible_memory_operand) {
+               return ops->impl->possible_memory_operand(ops, irn, i);
+       } else {
+               return 0;
+       }
 }
 
 int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos, bitset_t *bs)
 {
-  arch_register_req_t local_req;
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, &local_req, irn, pos);
-
-  if(req->type == arch_register_req_type_none) {
-         bitset_clear_all(bs);
-         return 0;
-  }
-
-  if(arch_register_req_is(req, limited)) {
-         req->limited(req->limited_env, bs);
-         return bitset_popcnt(bs);
-  }
-
-  arch_register_class_put(req->cls, bs);
-  return req->cls->n_regs;
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+
+       if(req->type == arch_register_req_type_none) {
+               bitset_clear_all(bs);
+               return 0;
+       }
+
+       if(arch_register_req_is(req, limited)) {
+               rbitset_copy_to_bitset(req->limited, bs);
+               return bitset_popcnt(bs);
+       }
+
+       arch_register_class_put(req->cls, bs);
+       return req->cls->n_regs;
 }
 
 void arch_put_non_ignore_regs(const arch_env_t *env, const arch_register_class_t *cls, bitset_t *bs)
@@ -218,64 +221,65 @@ int arch_count_non_ignore_regs(const arch_env_t *env, const arch_register_class_
 int arch_is_register_operand(const arch_env_t *env,
     const ir_node *irn, int pos)
 {
-       arch_register_req_t local_req;
        const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-       const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, &local_req, irn, pos);
+       const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+
        return req != NULL;
 }
 
 int arch_reg_is_allocatable(const arch_env_t *env, const ir_node *irn,
     int pos, const arch_register_t *reg)
 {
-       arch_register_req_t req;
+       const arch_register_req_t *req;
 
-       arch_get_register_req(env, &req, irn, pos);
+       req = arch_get_register_req(env, irn, pos);
 
-       if(req.type == arch_register_req_type_none)
+       if(req->type == arch_register_req_type_none)
                return 0;
 
-       if(arch_register_req_is(&req, limited)) {
-               bitset_t *bs = bitset_alloca(req.cls->n_regs);
-               req.limited(req.limited_env, bs);
-               return bitset_is_set(bs, arch_register_get_index(reg));
+       if(arch_register_req_is(req, limited)) {
+               assert(arch_register_get_class(reg) == req->cls);
+               return rbitset_is_set(req->limited, arch_register_get_index(reg));
        }
 
-       return req.cls == reg->reg_class;
+       return req->cls == reg->reg_class;
 }
 
 const arch_register_class_t *
 arch_get_irn_reg_class(const arch_env_t *env, const ir_node *irn, int pos)
 {
-  arch_register_req_t local_req;
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, &local_req, irn, pos);
-  return req ? req->cls : NULL;
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+
+       assert(req->type != arch_register_req_type_none || req->cls == NULL);
+
+       return req->cls;
 }
 
 extern const arch_register_t *
 arch_get_irn_register(const arch_env_t *env, const ir_node *irn)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  return ops->impl->get_irn_reg(ops, irn);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       return ops->impl->get_irn_reg(ops, irn);
 }
 
 extern void arch_set_irn_register(const arch_env_t *env,
     ir_node *irn, const arch_register_t *reg)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  ops->impl->set_irn_reg(ops, irn, reg);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       ops->impl->set_irn_reg(ops, irn, reg);
 }
 
 extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node *irn)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  return ops->impl->classify(ops, irn);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       return ops->impl->classify(ops, irn);
 }
 
 extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn)
 {
-  const arch_irn_ops_t *ops = get_irn_ops(env, irn);
-  return ops->impl->get_flags(ops, irn);
+       const arch_irn_ops_t *ops = get_irn_ops(env, irn);
+       return ops->impl->get_flags(ops, irn);
 }
 
 extern const char *arch_irn_flag_str(arch_irn_flags_t fl)
@@ -292,31 +296,47 @@ extern const char *arch_irn_flag_str(arch_irn_flags_t fl)
        return "n/a";
 }
 
-extern char *arch_register_req_format(char *buf, size_t len, const arch_register_req_t *req)
+extern char *arch_register_req_format(char *buf, size_t len,
+                                      const arch_register_req_t *req,
+                                      const ir_node *node)
 {
        char tmp[128];
        snprintf(buf, len, "class: %s", req->cls->name);
 
        if(arch_register_req_is(req, limited)) {
-               bitset_pos_t elm;
-               bitset_t *bs = bitset_alloca(req->cls->n_regs);
-               req->limited(req->limited_env, bs);
+               unsigned n_regs = req->cls->n_regs;
+               unsigned i;
+
                strncat(buf, " limited:", len);
-               bitset_foreach(bs, elm) {
-                       strncat(buf, " ", len);
-                       strncat(buf, req->cls->regs[elm].name, len);
+               for(i = 0; i < n_regs; ++i) {
+                       if(rbitset_is_set(req->limited, i)) {
+                               const arch_register_t *reg = &req->cls->regs[i];
+                               strncat(buf, " ", len);
+                               strncat(buf, reg->name, len);
+                       }
                }
        }
 
        if(arch_register_req_is(req, should_be_same)) {
-               ir_snprintf(tmp, sizeof(tmp), " same to: %+F", req->other_different);
+               const ir_node *same = get_irn_n(node, req->other_same);
+               ir_snprintf(tmp, sizeof(tmp), " same to: %+F", same);
                strncat(buf, tmp, len);
        }
 
        if(arch_register_req_is(req, should_be_different)) {
-               ir_snprintf(tmp, sizeof(tmp), " different to: %+F", req->other_different);
+               const ir_node *different = get_irn_n(node, req->other_different);
+               ir_snprintf(tmp, sizeof(tmp), " different to: %+F", different);
                strncat(buf, tmp, len);
        }
 
        return buf;
 }
+
+static const arch_register_req_t no_requirement = {
+       arch_register_req_type_none,
+       NULL,
+       NULL,
+       -1,
+       -1
+};
+const arch_register_req_t *arch_no_register_req = &no_requirement;
index 7b19678..0e2e0e3 100644 (file)
 #include "bemachine.h"
 #include "beirg.h"
 
-struct _be_node_factory_t;
-
 typedef enum _arch_register_type_t {
-  arch_register_type_none         = 0,
-  arch_register_type_caller_save  = 1,  /**< The register must be saved by the caller
+       arch_register_type_none         = 0,
+       arch_register_type_caller_save  = 1,  /**< The register must be saved by the caller
                                              upon a function call. It thus can be overwritten
                                              in the called function. */
-  arch_register_type_callee_save  = 2,  /**< The register must be saved by the caller
+       arch_register_type_callee_save  = 2,  /**< The register must be saved by the caller
                                              upon a function call. It thus can be overwritten
                                              in the called function. */
-  arch_register_type_ignore       = 4,  /**< Do not consider this register when allocating. */
-  arch_register_type_joker        = 8,  /**< The emitter can choose an arbitrary register */
-  arch_register_type_virtual      = 16, /**< This is just a virtual register  */
+       arch_register_type_ignore       = 4,  /**< Do not consider this register when allocating. */
+       arch_register_type_joker        = 8,  /**< The emitter can choose an arbitrary register */
+       arch_register_type_virtual      = 16, /**< This is just a virtual register  */
 } arch_register_type_t;
 
 /**
@@ -43,22 +41,22 @@ typedef enum _arch_register_type_t {
  * A register.
  */
 struct _arch_register_t {
-  const char                  *name;        /**< The name of the register. */
-  const arch_register_class_t *reg_class;   /**< The class the register belongs to. */
-  int                         index;        /**< The index of the register in the class. */
-  arch_register_type_t        type;         /**< The type of the register. */
-  void                        *data;        /**< Custom data. */
+       const char                  *name;        /**< The name of the register. */
+       const arch_register_class_t *reg_class;   /**< The class the register belongs to. */
+       int                         index;        /**< The index of the register in the class. */
+       arch_register_type_t        type;         /**< The type of the register. */
+       void                        *data;        /**< Custom data. */
 };
 
 static INLINE const arch_register_class_t *
 _arch_register_get_class(const arch_register_t *reg)
 {
-  return reg->reg_class;
+       return reg->reg_class;
 }
 
 static INLINE int _arch_register_get_index(const arch_register_t *reg)
 {
-  return reg->index;
+       return reg->index;
 }
 
 static INLINE const char *_arch_register_get_name(const arch_register_t *reg)
@@ -75,10 +73,10 @@ static INLINE const char *_arch_register_get_name(const arch_register_t *reg)
  * Like general purpose or floating point.
  */
 struct _arch_register_class_t {
-  const char *name;               /**< The name of the register class. */
-  int n_regs;                     /**< Number of registers in this class. */
-  ir_mode *mode;                  /**< The mode of the register class. */
-  const arch_register_t *regs;    /**< The array of registers. */
+       const char *name;               /**< The name of the register class. */
+       int n_regs;                     /**< Number of registers in this class. */
+       ir_mode *mode;                  /**< The mode of the register class. */
+       const arch_register_t *regs;    /**< The array of registers. */
 };
 
 /** return the number of registers in this register class */
@@ -101,20 +99,20 @@ extern int arch_register_class_put(const arch_register_class_t *cls, bitset_t *b
 static INLINE const arch_register_t *
 _arch_register_for_index(const arch_register_class_t *cls, int idx)
 {
-  assert(0 <= idx && idx < cls->n_regs);
-  return &cls->regs[idx];
+       assert(0 <= idx && idx < cls->n_regs);
+       return &cls->regs[idx];
 }
 
 #define arch_register_for_index(cls, idx) \
   _arch_register_for_index(cls, idx)
 
 typedef enum _arch_operand_type_t {
-  arch_operand_type_invalid,
-  arch_operand_type_memory,
-  arch_operand_type_register,
-  arch_operand_type_immediate,
-  arch_operand_type_symconst,
-  arch_operand_type_last
+       arch_operand_type_invalid,
+       arch_operand_type_memory,
+       arch_operand_type_register,
+       arch_operand_type_immediate,
+       arch_operand_type_symconst,
+       arch_operand_type_last
 } arch_operand_type_t;
 
 /**
@@ -142,26 +140,20 @@ typedef enum _arch_register_req_type_t {
  * Expresses requirements to register allocation for an operand.
  */
 typedef struct _arch_register_req_t {
-       arch_register_req_type_t type;          /**< The type of the constraint. */
-       const arch_register_class_t *cls;       /**< The register class this constraint belongs to. */
-
-       void (*limited)(void *limited_env, bitset_t *bs);
-                                          /**< In case of the 'limited'
-                                            constraint, this function
-                                            must put all allowable
-                                            registers in the bitset and
-                                            return the number of registers
-                                            in the bitset. */
+       arch_register_req_type_t type;      /**< The type of the constraint. */
+       const arch_register_class_t *cls;   /**< The register class this constraint belongs to. */
 
-       void *limited_env;                    /**< This must passed to limited. */
+       const unsigned *limited;            /**< allowed register bitset */
 
-       ir_node *other_same;                      /**< The other which shall have the same reg
-                                                                                   as this one. (for case should_be_same). */
-
-       ir_node *other_different;             /**< The other node from which this one's register
-                                                                                   must be different (case must_be_different). */
+       int other_same;                     /**< The in number which shall have
+                                                                                    the same res (should_be_same)*/
+       int other_different;                /**< The other node from which this
+                                                                                    one's register must be different
+                                                                                        (case must_be_different). */
 } arch_register_req_t;
 
+extern const arch_register_req_t *arch_no_register_req;
+
 /**
  * Format a register requirements information into a string.
  * @param buf The string where to put it to.
@@ -169,7 +161,7 @@ typedef struct _arch_register_req_t {
  * @param req The requirements structure to format.
  * @return    A pointer to buf.
  */
-extern char *arch_register_req_format(char *buf, size_t len, const arch_register_req_t *req);
+extern char *arch_register_req_format(char *buf, size_t len, const arch_register_req_t *req, const ir_node *node);
 
 
 /**
@@ -224,134 +216,134 @@ extern const char *arch_irn_flag_str(arch_irn_flags_t flag);
 
 struct _arch_irn_ops_if_t {
 
-  /**
-   * Get the register requirements for a given operand.
-   * @param self The self pointer.
-   * @param irn The node.
-   * @param pos The operand's position
-   *        (-1 for the result of the node, 0..n for the input operands).
-   * @return    The register requirements for the selected operand.
-   *            The pointer returned is never NULL.
-   */
-  const arch_register_req_t *(*get_irn_reg_req)(const void *self,
-      arch_register_req_t *req, const ir_node *irn, int pos);
+       /**
+        * Get the register requirements for a given operand.
+        * @param self The self pointer.
+        * @param irn The node.
+        * @param pos The operand's position
+        *        (-1 for the result of the node, 0..n for the input operands).
+        * @return    The register requirements for the selected operand.
+        *            The pointer returned is never NULL.
+        */
+       const arch_register_req_t *(*get_irn_reg_req)(const void *self,
+                                                     const ir_node *irn, int pos);
 
-  /**
-   * Set the register for an output operand.
-   * @param irn The node.
-   * @param reg The register allocated to that operand.
-   * @note      If the operand is not a register operand,
-   *            the call is ignored.
-   */
-  void (*set_irn_reg)(const void *self, ir_node *irn, const arch_register_t *reg);
+       /**
+        * Set the register for an output operand.
+        * @param irn The node.
+        * @param reg The register allocated to that operand.
+        * @note      If the operand is not a register operand,
+        *            the call is ignored.
+        */
+       void (*set_irn_reg)(const void *self, ir_node *irn, const arch_register_t *reg);
 
-  /**
-   * Get the register allocated for an output operand.
-   * @param irn The node.
-   * @return    The register allocated at that operand. NULL, if
-   *            the operand was no register operand or
-   *            @c arch_register_invalid, if no register has yet been
-   *            allocated for this node.
-   */
-  const arch_register_t *(*get_irn_reg)(const void *self, const ir_node *irn);
+       /**
+        * Get the register allocated for an output operand.
+        * @param irn The node.
+        * @return    The register allocated at that operand. NULL, if
+        *            the operand was no register operand or
+        *            @c arch_register_invalid, if no register has yet been
+        *            allocated for this node.
+        */
+       const arch_register_t *(*get_irn_reg)(const void *self, const ir_node *irn);
 
-  /**
-   * Classify the node.
-   * @param irn The node.
-   * @return A classification.
-   */
-  arch_irn_class_t (*classify)(const void *self, const ir_node *irn);
+       /**
+        * Classify the node.
+        * @param irn The node.
+        * @return A classification.
+        */
+       arch_irn_class_t (*classify)(const void *self, const ir_node *irn);
 
-  /**
-   * Get the flags of a node.
-   * @param self The irn ops themselves.
-   * @param irn The node.
-   * @return A set of flags.
-   */
-  arch_irn_flags_t (*get_flags)(const void *self, const ir_node *irn);
+       /**
+        * Get the flags of a node.
+        * @param self The irn ops themselves.
+        * @param irn The node.
+        * @return A set of flags.
+        */
+       arch_irn_flags_t (*get_flags)(const void *self, const ir_node *irn);
 
-  /**
-   * Get the entity on the stack frame this node depends on.
-   * @param self The this pointer.
-   * @param irn  The node in question.
-   * @return The entity on the stack frame or NULL, if the node does not have a
-   *         stack frame entity.
-   */
-  ir_entity *(*get_frame_entity)(const void *self, const ir_node *irn);
+       /**
+        * Get the entity on the stack frame this node depends on.
+        * @param self The this pointer.
+        * @param irn  The node in question.
+        * @return The entity on the stack frame or NULL, if the node does not have a
+        *         stack frame entity.
+        */
+       ir_entity *(*get_frame_entity)(const void *self, const ir_node *irn);
 
-  /**
-   * Set the entity on the stack frame this node depends on.
-   * @param self The this pointer.
-   * @param irn  The node in question.
-   * @param ent  The entity to set
-   */
-  void (*set_frame_entity)(const void *self, ir_node *irn, ir_entity *ent);
+       /**
+        * Set the entity on the stack frame this node depends on.
+        * @param self The this pointer.
+        * @param irn  The node in question.
+        * @param ent  The entity to set
+        */
+       void (*set_frame_entity)(const void *self, ir_node *irn, ir_entity *ent);
 
-  /**
-   * Set the offset of a node carrying an entity on the stack frame.
-   * @param self The this pointer.
-   * @param irn  The node.
-   * @param offset The offset of the node's stack frame entity.
-   */
-  void (*set_frame_offset)(const void *self, ir_node *irn, int offset);
+       /**
+        * Set the offset of a node carrying an entity on the stack frame.
+        * @param self The this pointer.
+        * @param irn  The node.
+        * @param offset The offset of the node's stack frame entity.
+        */
+       void (*set_frame_offset)(const void *self, ir_node *irn, int offset);
 
-  /**
-   * Returns the delta of the stackpointer for nodes that increment or
-   * decrement the stackpointer with a constant value. (push, pop
-   * nodes on most architectures).
-   * A positive value stands for an expanding stack area, a negative value for
-   * a shrinking one.
-   *
-   * @param self      The this pointer
-   * @param irn       The node
-   * @return          0 if the stackpointer is not modified with a constant
-   *                  value, otherwise the increment/decrement value
-   */
-  int (*get_sp_bias)(const void *self, const ir_node *irn);
+       /**
+        * Returns the delta of the stackpointer for nodes that increment or
+        * decrement the stackpointer with a constant value. (push, pop
+        * nodes on most architectures).
+        * A positive value stands for an expanding stack area, a negative value for
+        * a shrinking one.
+        *
+        * @param self      The this pointer
+        * @param irn       The node
+        * @return          0 if the stackpointer is not modified with a constant
+        *                  value, otherwise the increment/decrement value
+        */
+       int (*get_sp_bias)(const void *self, const ir_node *irn);
 
-  /**
-   * Returns an inverse operation which yields the i-th argument
-   * of the given node as result.
-   *
-   * @param self      The this pointer.
-   * @param irn       The original operation
-   * @param i         Index of the argument we want the inverse operation to yield
-   * @param inverse   struct to be filled with the resulting inverse op
-   * @param obstack   The obstack to use for allocation of the returned nodes array
-   * @return          The inverse operation or NULL if operation invertible
-   */
-  arch_inverse_t *(*get_inverse)(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack);
+       /**
+        * Returns an inverse operation which yields the i-th argument
+        * of the given node as result.
+        *
+        * @param self      The this pointer.
+        * @param irn       The original operation
+        * @param i         Index of the argument we want the inverse operation to yield
+        * @param inverse   struct to be filled with the resulting inverse op
+        * @param obstack   The obstack to use for allocation of the returned nodes array
+        * @return          The inverse operation or NULL if operation invertible
+        */
+       arch_inverse_t *(*get_inverse)(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack);
 
-  /**
-   * Get the estimated cycle count for @p irn.
-   *
-   * @param self The this pointer.
-   * @param irn  The node.
-   *
-   * @return     The estimated cycle count for this operation
-   */
-  int (*get_op_estimated_cost)(const void *self, const ir_node *irn);
+       /**
+        * Get the estimated cycle count for @p irn.
+        *
+        * @param self The this pointer.
+        * @param irn  The node.
+        *
+        * @return     The estimated cycle count for this operation
+        */
+       int (*get_op_estimated_cost)(const void *self, const ir_node *irn);
 
-  /**
-   * Asks the backend whether operand @p i of @p irn can be loaded form memory internally
-   *
-   * @param self The this pointer.
-   * @param irn  The node.
-   * @param i    Index of the argument we would like to know whether @p irn can load it form memory internally
-   *
-   * @return     nonzero if argument can be loaded or zero otherwise
-   */
-  int (*possible_memory_operand)(const void *self, const ir_node *irn, unsigned int i);
+       /**
+        * Asks the backend whether operand @p i of @p irn can be loaded form memory internally
+        *
+        * @param self The this pointer.
+        * @param irn  The node.
+        * @param i    Index of the argument we would like to know whether @p irn can load it form memory internally
+        *
+        * @return     nonzero if argument can be loaded or zero otherwise
+        */
+       int (*possible_memory_operand)(const void *self, const ir_node *irn, unsigned int i);
 
-  /**
-   * Ask the backend to assimilate @p reload of operand @p i into @p irn.
-   *
-   * @param self   The this pointer.
-   * @param irn    The node.
-   * @param spill  The spill.
-   * @param i      The position of the reload.
-   */
-  void (*perform_memory_operand)(const void *self, ir_node *irn, ir_node *spill, unsigned int i);
+       /**
+        * Ask the backend to assimilate @p reload of operand @p i into @p irn.
+        *
+        * @param self   The this pointer.
+        * @param irn    The node.
+        * @param spill  The spill.
+        * @param i      The position of the reload.
+        */
+       void (*perform_memory_operand)(const void *self, ir_node *irn, ir_node *spill, unsigned int i);
 };
 
 /**
@@ -386,8 +378,7 @@ extern void arch_perform_memory_operand(const arch_env_t *env, ir_node *irn, ir_
  *            operand was no register operand.
  */
 extern const arch_register_req_t *
-arch_get_register_req(const arch_env_t *env, arch_register_req_t *req,
-    const ir_node *irn, int pos);
+arch_get_register_req(const arch_env_t *env, const ir_node *irn, int pos);
 
 /**
  * Check if an operand is a register operand.
@@ -752,13 +743,12 @@ struct _arch_isa_if_t {
  * Keep this everywhere you're going.
  */
 struct _arch_env_t {
-  const struct _be_node_factory_t *node_factory;  /**< The node factory for be nodes. */
-  arch_isa_t *isa;                                /**< The isa about which everything is. */
+       arch_isa_t *isa;                                /**< The isa about which everything is. */
 
-  arch_irn_handler_t const *handlers[ARCH_MAX_HANDLERS]; /**< The handlers are organized as
+       arch_irn_handler_t const *handlers[ARCH_MAX_HANDLERS]; /**< The handlers are organized as
                                                            a stack. */
 
-  int handlers_tos;                                   /**< The stack pointer of the handler
+       int handlers_tos;                                   /**< The stack pointer of the handler
                                                         stack. */
 };
 
index abec354..9d744a7 100644 (file)
@@ -6,8 +6,8 @@
  * CVS-Id:      $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
+#include <config.h>
+#endif
 
 #include "beblocksched.h"
 
@@ -37,6 +37,8 @@
 #include <lpp/lpp_net.h>
 #endif /* WITH_ILP */
 
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
+
 typedef enum _blocksched_algos_t {
        BLOCKSCHED_NAIV, BLOCKSCHED_EXTBB, BLOCKSCHED_GREEDY, BLOCKSCHED_ILP
 } blocksched_algos_t;
@@ -92,7 +94,6 @@ typedef struct _blocksched_env_t {
        edge_t         *edges;
        pdeq           *worklist;
        int            blockcount;
-       DEBUG_ONLY(firm_dbg_module_t *dbg;)
 } blocksched_env_t;
 
 /**
@@ -191,7 +192,7 @@ static void coalesce_blocks(blocksched_env_t *env)
                        continue;
 
                /* schedule the 2 blocks behind each other */
-               DBG((env->dbg, LEVEL_1, "Coalesce (Jump) %+F -> %+F (%.3g)\n",
+               DBG((dbg, LEVEL_1, "Coalesce (Jump) %+F -> %+F (%.3g)\n",
                           pred_entry->block, entry->block, edge->execfreq));
                pred_entry->next = entry;
                entry->prev      = pred_entry;
@@ -217,7 +218,7 @@ static void coalesce_blocks(blocksched_env_t *env)
                        continue;
 
                /* schedule the 2 blocks behind each other */
-               DBG((env->dbg, LEVEL_1, "Coalesce (CondJump) %+F -> %+F (%.3g)\n",
+               DBG((dbg, LEVEL_1, "Coalesce (CondJump) %+F -> %+F (%.3g)\n",
                           pred_entry->block, entry->block, edge->execfreq));
                pred_entry->next = entry;
                entry->prev      = pred_entry;
@@ -238,7 +239,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en
        env->blockcount++;
        mark_irn_visited(block);
 
-       DBG((env->dbg, LEVEL_1, "Pick succ of %+F\n", block));
+       DBG((dbg, LEVEL_1, "Pick succ of %+F\n", block));
 
        /* put all successors into the worklist */
        foreach_block_succ(block, edge) {
@@ -263,7 +264,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en
                if (irn_visited(succ_entry->block))
                        continue;
 
-               DBG((env->dbg, LEVEL_1, "Put %+F into worklist\n", succ_entry->block));
+               DBG((dbg, LEVEL_1, "Put %+F into worklist\n", succ_entry->block));
                pdeq_putr(env->worklist, succ_entry->block);
        }
 
@@ -272,7 +273,7 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en
                return;
        }
 
-       DBG((env->dbg, LEVEL_1, "deciding...\n"));
+       DBG((dbg, LEVEL_1, "deciding...\n"));
        best_succ_execfreq = -1;
 
        /* no successor yet: pick the successor block with the highest execution
@@ -297,11 +298,11 @@ static void pick_block_successor(blocksched_entry_t *entry, blocksched_env_t *en
        }
 
        if (succ == NULL) {
-               DBG((env->dbg, LEVEL_1, "pick from worklist\n"));
+               DBG((dbg, LEVEL_1, "pick from worklist\n"));
 
                do {
                        if (pdeq_empty(env->worklist)) {
-                               DBG((env->dbg, LEVEL_1, "worklist empty\n"));
+                               DBG((dbg, LEVEL_1, "worklist empty\n"));
                                return;
                        }
                        succ = pdeq_getl(env->worklist);
@@ -339,12 +340,12 @@ static ir_node **create_blocksched_array(blocksched_env_t *env, blocksched_entry
        blocksched_entry_t *entry;
 
        block_list = NEW_ARR_D(ir_node *, obst, count);
-       DBG((env->dbg, LEVEL_1, "Blockschedule:\n"));
+       DBG((dbg, LEVEL_1, "Blockschedule:\n"));
 
        for (entry = first; entry != NULL; entry = entry->next) {
                assert(i < count);
                block_list[i++] = entry->block;
-               DBG((env->dbg, LEVEL_1, "\t%+F\n", entry->block));
+               DBG((dbg, LEVEL_1, "\t%+F\n", entry->block));
        }
        assert(i == count);
 
@@ -366,7 +367,6 @@ static ir_node **create_block_schedule_greedy(ir_graph *irg, ir_exec_freq *execf
        env.edges      = NEW_ARR_F(edge_t, 0);
        env.worklist   = NULL;
        env.blockcount = 0;
-       FIRM_DBG_REGISTER(env.dbg, "firm.be.blocksched");
 
        // collect edge execution frequencies
        irg_block_walk_graph(irg, collect_egde_frequency, NULL, &env);
@@ -504,7 +504,7 @@ static void coalesce_blocks_ilp(blocksched_ilp_env_t *env)
                pred  = get_Block_cfgpred_block(block, edge->pos);
                entry = get_irn_link(pred);
 
-               DBG((env->env.dbg, LEVEL_1, "Adding out cst to %+F from %+F,%d\n",
+               DBG((dbg, LEVEL_1, "Adding out cst to %+F from %+F,%d\n",
                                  pred, block, edge->pos));
                lpp_set_factor_fast(env->lpp, entry->out_cst, edge->ilpvar, 1.0);
        }
@@ -567,7 +567,6 @@ static ir_node **create_block_schedule_ilp(ir_graph *irg, ir_exec_freq *execfreq
        env.env.worklist   = NULL;
        env.env.blockcount = 0;
        env.ilpedges       = NEW_ARR_F(ilp_edge_t, 0);
-       FIRM_DBG_REGISTER(env.env.dbg, "firm.be.blocksched");
 
        env.lpp = new_lpp("blockschedule", lpp_minimize);
        lpp_set_time_limit(env.lpp, 20);
@@ -698,6 +697,8 @@ void be_init_blocksched(void)
        lc_opt_entry_t *blocksched_grp = lc_opt_get_grp(be_grp, "blocksched");
 
        lc_opt_add_table(blocksched_grp, be_blocksched_options);
+
+       FIRM_DBG_REGISTER(dbg, "firm.be.blocksched");
 }
 
 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_blocksched);
index 604ff67..76ccc17 100644 (file)
@@ -25,6 +25,7 @@
 #include "pset.h"
 #include "list.h"
 #include "bitset.h"
+#include "raw_bitset.h"
 #include "iterator.h"
 #include "bipartite.h"
 #include "hungarian.h"
@@ -197,7 +198,7 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1,
                return bs;
        }
 
-       assert(o1->req.cls == o2->req.cls);
+       assert(o1->req->cls == o2->req->cls);
 
        if(bitset_contains(o1->regs, o2->regs))
                bitset_copy(bs, o1->regs);
@@ -223,8 +224,8 @@ static be_insn_t *chordal_scan_insn(be_chordal_env_t *env, ir_node *irn)
 static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
 {
        const arch_env_t *aenv = env->birg->main_env->arch_env;
-       bitset_t *def_constr   = bitset_alloca(env->cls->n_regs);
        bitset_t *tmp          = bitset_alloca(env->cls->n_regs);
+       bitset_t *def_constr   = bitset_alloca(env->cls->n_regs);
        ir_node *bl            = get_nodes_block(irn);
        be_lv_t *lv            = env->birg->lv;
 
@@ -235,7 +236,7 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
                ir_node *op = get_irn_n(irn, i);
                ir_node *copy;
                const arch_register_t *reg;
-               arch_register_req_t req;
+               const arch_register_req_t *req;
 
                if (arch_get_irn_reg_class(aenv, irn, i) != env->cls)
                        continue;
@@ -247,14 +248,11 @@ static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
                if(arch_register_type_is(reg, joker))
                        continue;
 
-               arch_get_register_req(aenv, &req, irn, i);
-               if (!arch_register_req_is(&req, limited))
+               req = arch_get_register_req(aenv, irn, i);
+               if (!arch_register_req_is(req, limited))
                        continue;
 
-               bitset_clear_all(tmp);
-               req.limited(req.limited_env, tmp);
-
-               if (bitset_is_set(tmp, reg->index))
+               if (rbitset_is_set(req->limited, reg->index))
                        continue;
 
                copy = be_new_Copy(env->cls, env->irg, bl, op);
@@ -383,16 +381,19 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t
                        int n_total;
                        const be_operand_t *op = &insn->ops[i];
 
-                       if (! values_interfere(lv, op->irn, op->carrier) && ! op->partner) {
-                               bitset_clear_all(bs);
-                               bitset_copy(bs, op->regs);
-                               bitset_and(bs, out_op->regs);
-                               n_total = bitset_popcnt(op->regs) + bitset_popcnt(out_op->regs);
+                       if (op->partner != NULL)
+                               continue;
+                       if (values_interfere(lv, op->irn, op->carrier))
+                               continue;
 
-                               if (bitset_popcnt(bs) > 0 && n_total < smallest_n_regs) {
-                                       smallest = i;
-                                       smallest_n_regs = n_total;
-                               }
+                       bitset_clear_all(bs);
+                       bitset_copy(bs, op->regs);
+                       bitset_and(bs, out_op->regs);
+                       n_total = bitset_popcnt(op->regs) + bitset_popcnt(out_op->regs);
+
+                       if (bitset_popcnt(bs) > 0 && n_total < smallest_n_regs) {
+                               smallest = i;
+                               smallest_n_regs = n_total;
                        }
                }
 
@@ -405,19 +406,16 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t
 }
 
 
-static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_insn_t **the_insn)
+static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env,
+                                        be_insn_t **the_insn)
 {
        be_chordal_env_t *env       = alloc_env->chordal_env;
        const arch_env_t *aenv      = env->birg->main_env->arch_env;
        be_insn_t *insn             = *the_insn;
-       ir_node *bl                 = get_nodes_block(insn->irn);
-       ir_node *copy               = NULL;
        ir_node *perm               = NULL;
        bitset_t *out_constr        = bitset_alloca(env->cls->n_regs);
-       bitset_t *bs                = bitset_alloca(env->cls->n_regs);
        be_lv_t *lv                 = env->birg->lv;
-       DEBUG_ONLY(firm_dbg_module_t *dbg      = alloc_env->constr_dbg;)
-
+       const ir_edge_t *edge;
        int i;
 
        assert(insn->has_constraints && "only do this for constrained nodes");
@@ -434,11 +432,6 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
                        bitset_or(out_constr, op->regs);
        }
 
-       (void) bl;
-       (void) copy;
-       (void) bs;
-       DEBUG_ONLY((void) dbg;)
-
        /*
                Make the Perm, recompute liveness and re-scan the insn since the
                in operands are now the Projs of the Perm.
@@ -446,38 +439,37 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
        perm = insert_Perm_after(aenv, lv, env->cls, env->birg->dom_front, sched_prev(insn->irn));
 
        /* Registers are propagated by insert_Perm_after(). Clean them here! */
-       if(perm) {
-               const ir_edge_t *edge;
+       if(perm == NULL)
+               return NULL;
 
-               be_stat_ev("constr_perm", get_irn_arity(perm));
-               foreach_out_edge(perm, edge) {
-                       ir_node *proj = get_edge_src_irn(edge);
-                       arch_set_irn_register(aenv, proj, NULL);
-               }
+       be_stat_ev("constr_perm", get_irn_arity(perm));
+       foreach_out_edge(perm, edge) {
+               ir_node *proj = get_edge_src_irn(edge);
+               arch_set_irn_register(aenv, proj, NULL);
+       }
 
-               /*
-                       We also have to re-build the insn since the input operands are now the Projs of
-                       the Perm. Recomputing liveness is also a good idea if a Perm is inserted, since
-                       the live sets may change.
-               */
-               // be_liveness_recompute(lv);
-               obstack_free(&env->obst, insn);
-               *the_insn = insn = chordal_scan_insn(env, insn->irn);
+       /*
+               We also have to re-build the insn since the input operands are now the Projs of
+               the Perm. Recomputing liveness is also a good idea if a Perm is inserted, since
+               the live sets may change.
+       */
+       // be_liveness_recompute(lv);
+       obstack_free(&env->obst, insn);
+       *the_insn = insn = chordal_scan_insn(env, insn->irn);
 
+       /*
+               Copy the input constraints of the insn to the Perm as output
+               constraints. Succeeding phases (coalescing) will need that.
+       */
+       for(i = insn->use_start; i < insn->n_ops; ++i) {
+               be_operand_t *op = &insn->ops[i];
+               ir_node *proj = op->carrier;
                /*
-                       Copy the input constraints of the insn to the Perm as output
-                       constraints. Succeeding phases (coalescing will need that).
+                       Note that the predecessor must not be a Proj of the Perm,
+                       since ignore-nodes are not Perm'ed.
                */
-               for(i = insn->use_start; i < insn->n_ops; ++i) {
-                       be_operand_t *op = &insn->ops[i];
-                       ir_node *proj = op->carrier;
-                       /*
-                               Note that the predecessor must not be a Proj of the Perm,
-                               since ignore-nodes are not Perm'ed.
-                       */
-                       if(op->has_constraints &&  is_Proj(proj) && get_Proj_pred(proj) == perm) {
-                               be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), &op->req);
-                       }
+               if(op->has_constraints &&  is_Proj(proj) && get_Proj_pred(proj) == perm) {
+                       be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), op->req);
                }
        }
 
@@ -486,6 +478,19 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
 
 static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent)
 {
+       const arch_env_t *aenv;
+       int n_regs;
+       bitset_t *bs;
+       ir_node **alloc_nodes;
+       hungarian_problem_t *bp;
+       int *assignment;
+       pmap *partners;
+       DEBUG_ONLY(firm_dbg_module_t *dbg);
+       int i, n_alloc;
+       long col;
+       const ir_edge_t *edge;
+       ir_node *perm = NULL;
+       int match_res, cost;
        be_chordal_env_t *env  = alloc_env->chordal_env;
        void *base             = obstack_base(&env->obst);
        be_insn_t *insn        = chordal_scan_insn(env, irn);
@@ -516,159 +521,155 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
                Perms inserted before the constraint handling phase are considered to be
                correctly precolored. These Perms arise during the ABI handling phase.
        */
-       if(insn->has_constraints) {
-               const arch_env_t *aenv = env->birg->main_env->arch_env;
-               int n_regs             = env->cls->n_regs;
-               bitset_t *bs           = bitset_alloca(n_regs);
-               ir_node **alloc_nodes  = alloca(n_regs * sizeof(alloc_nodes[0]));
-               hungarian_problem_t *bp= hungarian_new(n_regs, n_regs, 2, HUNGARIAN_MATCH_PERFECT);
-//             bipartite_t *bp        = bipartite_new(n_regs, n_regs);
-               int *assignment        = alloca(n_regs * sizeof(assignment[0]));
-               pmap *partners         = pmap_create();
-               DEBUG_ONLY(firm_dbg_module_t *dbg = alloc_env->constr_dbg;)
-
-               int i, n_alloc;
-               long col;
-               const ir_edge_t *edge;
-               ir_node *perm = NULL;
-               int match_res, cost;
+       if(!insn->has_constraints)
+               goto end;
 
-               /*
-                       prepare the constraint handling of this node.
-                       Perms are constructed and Copies are created for constrained values
-                       interfering with the instruction.
-               */
-               perm = pre_process_constraints(alloc_env, &insn);
+       aenv        = env->birg->main_env->arch_env;
+       n_regs      = env->cls->n_regs;
+       bs          = bitset_alloca(n_regs);
+       alloc_nodes = alloca(n_regs * sizeof(alloc_nodes[0]));
+       bp          = hungarian_new(n_regs, n_regs, 2, HUNGARIAN_MATCH_PERFECT);
+       // bipartite_t *bp        = bipartite_new(n_regs, n_regs);
+       assignment  = alloca(n_regs * sizeof(assignment[0]));
+       partners    = pmap_create();
+       DEBUG_ONLY(dbg = alloc_env->constr_dbg;)
 
-               /* find suitable in operands to the out operands of the node. */
-               pair_up_operands(alloc_env, insn);
+       /*
+               prepare the constraint handling of this node.
+               Perms are constructed and Copies are created for constrained values
+               interfering with the instruction.
+       */
+       perm = pre_process_constraints(alloc_env, &insn);
 
-               /*
-                       look at the in/out operands and add each operand (and its possible partner)
-                       to a bipartite graph (left: nodes with partners, right: admissible colors).
-               */
-               for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) {
-                       be_operand_t *op = &insn->ops[i];
+       /* find suitable in operands to the out operands of the node. */
+       pair_up_operands(alloc_env, insn);
 
-                       /*
-                               If the operand has no partner or the partner has not been marked
-                               for allocation, determine the admissible registers and mark it
-                               for allocation by associating the node and its partner with the
-                               set of admissible registers via a bipartite graph.
-                       */
-                       if(!op->partner || !pmap_contains(partners, op->partner->carrier)) {
+       /*
+               look at the in/out operands and add each operand (and its possible partner)
+               to a bipartite graph (left: nodes with partners, right: admissible colors).
+       */
+       for(i = 0, n_alloc = 0; i < insn->n_ops; ++i) {
+               be_operand_t *op = &insn->ops[i];
 
-                               pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL);
-                               alloc_nodes[n_alloc] = op->carrier;
+               /*
+                       If the operand has no partner or the partner has not been marked
+                       for allocation, determine the admissible registers and mark it
+                       for allocation by associating the node and its partner with the
+                       set of admissible registers via a bipartite graph.
+               */
+               if(!op->partner || !pmap_contains(partners, op->partner->carrier)) {
 
-                               DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL));
+                       pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL);
+                       alloc_nodes[n_alloc] = op->carrier;
 
-                               bitset_clear_all(bs);
-                               get_decisive_partner_regs(bs, op, op->partner);
+                       DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL));
 
-                               DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
+                       bitset_clear_all(bs);
+                       get_decisive_partner_regs(bs, op, op->partner);
 
-                               bitset_foreach(bs, col)
-                                       hungarian_add(bp, n_alloc, col, 1);
-//                                     bipartite_add(bp, n_alloc, col);
+                       DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
 
-                               n_alloc++;
+                       bitset_foreach(bs, col) {
+                               hungarian_add(bp, n_alloc, col, 1);
+                               // bipartite_add(bp, n_alloc, col);
                        }
+
+                       n_alloc++;
                }
+       }
 
-               /*
-                       Put all nodes which live through the constrained instruction also to the
-                       allocation bipartite graph. They are considered unconstrained.
-               */
-               if(perm) {
-                       foreach_out_edge(perm, edge) {
-                               ir_node *proj = get_edge_src_irn(edge);
+       /*
+               Put all nodes which live through the constrained instruction also to the
+               allocation bipartite graph. They are considered unconstrained.
+       */
+       if(perm != NULL) {
+               foreach_out_edge(perm, edge) {
+                       ir_node *proj = get_edge_src_irn(edge);
 
-                               assert(is_Proj(proj));
+                       assert(is_Proj(proj));
 
-                               if(values_interfere(lv, proj, irn) && !pmap_contains(partners, proj)) {
-                                       assert(n_alloc < n_regs);
-                                       alloc_nodes[n_alloc] = proj;
-                                       pmap_insert(partners, proj, NULL);
+                       if(!values_interfere(lv, proj, irn) || pmap_contains(partners, proj))
+                               continue;
 
-                                       bitset_clear_all(bs);
-                                       arch_put_non_ignore_regs(aenv, env->cls, bs);
-                                       bitset_andnot(bs, env->ignore_colors);
-                                       bitset_foreach(bs, col)
-                                               hungarian_add(bp, n_alloc, col, 1);
-//                                             bipartite_add(bp, n_alloc, col);
+                       assert(n_alloc < n_regs);
+                       alloc_nodes[n_alloc] = proj;
+                       pmap_insert(partners, proj, NULL);
 
-                                       n_alloc++;
-                               }
+                       bitset_clear_all(bs);
+                       arch_put_non_ignore_regs(aenv, env->cls, bs);
+                       bitset_andnot(bs, env->ignore_colors);
+                       bitset_foreach(bs, col) {
+                               hungarian_add(bp, n_alloc, col, 1);
+                               // bipartite_add(bp, n_alloc, col);
                        }
+
+                       n_alloc++;
                }
+       }
 
-               /* Compute a valid register allocation. */
-               hungarian_prepare_cost_matrix(bp, HUNGARIAN_MODE_MAXIMIZE_UTIL);
-               match_res = hungarian_solve(bp, assignment, &cost, 1);
-               assert(match_res == 0 && "matching failed");
-               //bipartite_matching(bp, assignment);
+       /* Compute a valid register allocation. */
+       hungarian_prepare_cost_matrix(bp, HUNGARIAN_MODE_MAXIMIZE_UTIL);
+       match_res = hungarian_solve(bp, assignment, &cost, 1);
+       assert(match_res == 0 && "matching failed");
+       //bipartite_matching(bp, assignment);
 
-               /* Assign colors obtained from the matching. */
-               for(i = 0; i < n_alloc; ++i) {
-                       const arch_register_t *reg;
-                       ir_node *nodes[2];
-                       int j;
+       /* Assign colors obtained from the matching. */
+       for(i = 0; i < n_alloc; ++i) {
+               const arch_register_t *reg;
+               ir_node *nodes[2];
+               int j;
 
-                       assert(assignment[i] >= 0 && "there must have been a register assigned");
-                       reg = arch_register_for_index(env->cls, assignment[i]);
+               assert(assignment[i] >= 0 && "there must have been a register assigned");
+               reg = arch_register_for_index(env->cls, assignment[i]);
 
-                       nodes[0] = alloc_nodes[i];
-                       nodes[1] = pmap_get(partners, alloc_nodes[i]);
+               nodes[0] = alloc_nodes[i];
+               nodes[1] = pmap_get(partners, alloc_nodes[i]);
 
-                       for(j = 0; j < 2; ++j) {
-                               if(!nodes[j])
-                                       continue;
+               for(j = 0; j < 2; ++j) {
+                       if(!nodes[j])
+                               continue;
 
-                               arch_set_irn_register(aenv, nodes[j], reg);
-                               (void) pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]);
-                               DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name));
-                       }
+                       arch_set_irn_register(aenv, nodes[j], reg);
+                       (void) pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]);
+                       DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name));
                }
+       }
 
+       /* Allocate the non-constrained Projs of the Perm. */
+       if(perm != NULL) {
+               bitset_clear_all(bs);
 
-               /* Allocate the non-constrained Projs of the Perm. */
-               if(perm) {
-
-                       bitset_clear_all(bs);
-
-                       /* Put the colors of all Projs in a bitset. */
-                       foreach_out_edge(perm, edge) {
-                               ir_node *proj              = get_edge_src_irn(edge);
-                               const arch_register_t *reg = arch_get_irn_register(aenv, proj);
+               /* Put the colors of all Projs in a bitset. */
+               foreach_out_edge(perm, edge) {
+                       ir_node *proj              = get_edge_src_irn(edge);
+                       const arch_register_t *reg = arch_get_irn_register(aenv, proj);
 
-                               if(reg != NULL)
-                                       bitset_set(bs, reg->index);
-                       }
+                       if(reg != NULL)
+                               bitset_set(bs, reg->index);
+               }
 
-                       /* Assign the not yet assigned Projs of the Perm a suitable color. */
-                       foreach_out_edge(perm, edge) {
-                               ir_node *proj              = get_edge_src_irn(edge);
-                               const arch_register_t *reg = arch_get_irn_register(aenv, proj);
+               /* Assign the not yet assigned Projs of the Perm a suitable color. */
+               foreach_out_edge(perm, edge) {
+                       ir_node *proj              = get_edge_src_irn(edge);
+                       const arch_register_t *reg = arch_get_irn_register(aenv, proj);
 
-                               DBG((dbg, LEVEL_2, "\tchecking reg of %+F: %s\n", proj, reg ? reg->name : "<none>"));
+                       DBG((dbg, LEVEL_2, "\tchecking reg of %+F: %s\n", proj, reg ? reg->name : "<none>"));
 
-                               if(reg == NULL) {
-                                       col = get_next_free_reg(alloc_env, bs);
-                                       reg = arch_register_for_index(env->cls, col);
-                                       bitset_set(bs, reg->index);
-                                       arch_set_irn_register(aenv, proj, reg);
-                                       pset_insert_ptr(alloc_env->pre_colored, proj);
-                                       DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", proj, reg->name));
-                               }
+                       if(reg == NULL) {
+                               col = get_next_free_reg(alloc_env, bs);
+                               reg = arch_register_for_index(env->cls, col);
+                               bitset_set(bs, reg->index);
+                               arch_set_irn_register(aenv, proj, reg);
+                               pset_insert_ptr(alloc_env->pre_colored, proj);
+                               DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", proj, reg->name));
                        }
                }
-
-               //bipartite_free(bp);
-               hungarian_free(bp);
-               pmap_destroy(partners);
        }
 
+       //bipartite_free(bp);
+       hungarian_free(bp);
+       pmap_destroy(partners);
+
 end:
        obstack_free(&env->obst, base);
        return res;
@@ -885,13 +886,11 @@ static void assign(ir_node *block, void *env_ptr)
                        const arch_register_t *reg;
                        int col = NO_COLOR;
 
-                       if(pset_find_ptr(alloc_env->pre_colored, irn) || ignore) {
+                       if(ignore || pset_find_ptr(alloc_env->pre_colored, irn)) {
                                reg = arch_get_irn_register(arch_env, irn);
                                col = reg->index;
                                assert(!bitset_is_set(colors, col) && "pre-colored register must be free");
-                       }
-
-                       else {
+                       } else {
                                col = get_next_free_reg(alloc_env, colors);
                                reg = arch_register_for_index(env->cls, col);
                                assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet");
index d626bad..233a749 100644 (file)
@@ -13,7 +13,7 @@
  * conflicts is the best one.
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_ALLOCA_H
@@ -29,6 +29,7 @@
 #include "becopystat.h"
 #include "benodesets.h"
 #include "bitset.h"
+#include "raw_bitset.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
@@ -251,7 +252,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
         */
        if (irn != trigger) {
                bitset_t *free_cols = bitset_alloca(cls->n_regs);
-               arch_register_req_t req;
+               const arch_register_req_t *req;
                ir_node *curr;
                int free_col;
 
@@ -260,10 +261,10 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const
                bitset_flip_all(free_cols);
 
                /* Exclude colors not assignable to the irn */
-               arch_get_register_req(arch_env, &req, irn, -1);
-               if (arch_register_req_is(&req, limited)) {
+               req = arch_get_register_req(arch_env, irn, -1);
+               if (arch_register_req_is(req, limited)) {
                        bitset_t *limited = bitset_alloca(cls->n_regs);
-                       req.limited(req.limited_env, limited);
+                       rbitset_copy_to_bitset(req->limited, limited);
                        bitset_and(free_cols, limited);
                }
 
index 10ae5b6..80a8c70 100644 (file)
@@ -1,12 +1,10 @@
-
 /**
  * More experiments on coalescing.
  * @author Sebastian Hack
  * @date   14.04.2006
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <libcore/lc_opts.h>
@@ -18,6 +16,7 @@
 #include "list.h"
 #include "pdeq.h"
 #include "bitset.h"
+#include "raw_bitset.h"
 
 #include "debug.h"
 #include "bitfiddle.h"
@@ -243,15 +242,21 @@ static INLINE int color_is_fix(co2_t *env, ir_node *irn)
 
 static INLINE bitset_t *get_adm(co2_t *env, co2_irn_t *ci)
 {
-       if(!ci->adm_cache) {
-               arch_register_req_t req;
+       if(ci->adm_cache == NULL) {
+               const arch_register_req_t *req;
                ci->adm_cache = bitset_obstack_alloc(phase_obst(&env->ph), env->n_regs);
-               arch_get_register_req(env->co->aenv, &req, ci->irn, BE_OUT_POS(0));
-               if(arch_register_req_is(&req, limited)) {
-                       req.limited(req.limited_env, ci->adm_cache);
+               req = arch_get_register_req(env->co->aenv, ci->irn, BE_OUT_POS(0));
+
+               if(arch_register_req_is(req, limited)) {
+                       int i, n;
+
+                       n = env->n_regs;
+                       for(i = 0; i < n; ++i) {
+                               if(rbitset_is_set(req->limited, i))
+                                       bitset_set(ci->adm_cache, i);
+                       }
                        ci->is_constrained = 1;
-               }
-               else {
+               } else {
                        bitset_copy(ci->adm_cache, env->ignore_regs);
                        bitset_flip_all(ci->adm_cache);
                }
@@ -281,19 +286,20 @@ static INLINE int is_constrained(co2_t *env, co2_irn_t *ci)
 
 static void incur_constraint_costs(co2_t *env, ir_node *irn, col_cost_pair_t *col_costs, int costs)
 {
-       bitset_t *aux = bitset_alloca(env->co->cls->n_regs);
-       arch_register_req_t req;
+       const arch_register_req_t *req;
 
-       arch_get_register_req(env->co->aenv, &req, irn, BE_OUT_POS(0));
+       req = arch_get_register_req(env->co->aenv, irn, BE_OUT_POS(0));
 
-       if(arch_register_req_is(&req, limited)) {
-               bitset_pos_t elm;
-               int n_constr;
+       if(arch_register_req_is(req, limited)) {
+               unsigned n_regs = env->co->cls->n_regs;
+               unsigned n_constr = 0;
+               int i;
 
-               req.limited(req.limited_env, aux);
-               n_constr = bitset_popcnt(aux);
-               bitset_foreach(aux, elm) {
-                       col_costs[elm].costs  = add_saturated(col_costs[elm].costs, costs / n_constr);
+               n_constr = rbitset_popcnt(req->limited, n_regs);
+               for(i = 0; i < n_regs; ++i) {
+                       if(rbitset_is_set(req->limited, i)) {
+                               col_costs[i].costs  = add_saturated(col_costs[i].costs, costs / n_constr);
+                       }
                }
        }
 }
@@ -1130,10 +1136,10 @@ static const char *get_dot_color_name(int col)
 
 static const char *get_dot_shape_name(co2_t *env, co2_irn_t *ci)
 {
-       arch_register_req_t req;
+       const arch_register_req_t *req;
 
-       arch_get_register_req(env->co->aenv, &req, ci->irn, BE_OUT_POS(0));
-       if(arch_register_req_is(&req, limited))
+       req = arch_get_register_req(env->co->aenv, ci->irn, BE_OUT_POS(0));
+       if(arch_register_req_is(req, limited))
                return "diamond";
 
        if(ci->fixed)
index 73b7835..d22a6f4 100644 (file)
@@ -1,12 +1,10 @@
-
 /**
  * More experiments on coalescing.
  * @author Sebastian Hack
  * @date   25.07.2006
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <libcore/lc_opts.h>
@@ -22,6 +20,7 @@
 #include "debug.h"
 #include "bitfiddle.h"
 #include "bitset.h"
+#include "raw_bitset.h"
 
 #include "irphase_t.h"
 #include "irgraph_t.h"
@@ -78,20 +77,20 @@ BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur3);
 
 static void set_admissible_regs(be_java_coal_t *coal, copy_opt_t *co, ir_node *irn, int t_idx, int *col_map)
 {
-       unsigned i;
-       arch_register_req_t req;
-       unsigned n_regs = co->cls->n_regs;
+       const arch_register_req_t *req;
+
+       req = arch_get_register_req(co->aenv, irn, BE_OUT_POS(0));
 
        // ir_printf("%+F\n", irn);
-       arch_get_register_req(co->aenv, &req, irn, BE_OUT_POS(0));
-       if(arch_register_req_is(&req, limited)) {
-               bitset_t *adm = bitset_alloca(n_regs);
-               req.limited(req.limited_env, adm);
-               for(i = 0; i < n_regs; ++i)
-                       if(!bitset_is_set(adm, i) && col_map[i] >= 0) {
-                               // printf("\tforbidding color: %d\n", i);
+       if(arch_register_req_is(req, limited)) {
+               unsigned i;
+               unsigned n_regs = co->cls->n_regs;
+
+               for(i = 0; i < n_regs; ++i) {
+                       if(!rbitset_is_set(req->limited, i) && col_map[i] >= 0) {
                                be_java_coal_forbid_color(coal, t_idx, col_map[i]);
                        }
+               }
        }
 }
 
index 6fa8707..ae244cd 100644 (file)
@@ -30,7 +30,7 @@
 static int time_limit = 60;
 static int solve_net  = 1;
 static int solve_log  = 0;
-static int dump_flags = 0;
+static unsigned dump_flags = 0;
 
 static const lc_opt_enum_mask_items_t dump_items[] = {
        { "ilp",   DUMP_ILP },
@@ -124,11 +124,11 @@ void sr_remove(size_red_t *sr) {
        while (redo) {
                redo = 0;
                be_ifg_foreach_node(ifg, iter, irn) {
-                       arch_register_req_t req;
+                       const arch_register_req_t *req;
 
-                       arch_get_register_req(sr->co->aenv, &req, irn, -1);
+                       req = arch_get_register_req(sr->co->aenv, irn, -1);
 
-                       if (!arch_register_req_is(&req, limited) && !sr_is_removed(sr, irn) && !co_gs_is_optimizable(sr->co, irn)) {
+                       if (!arch_register_req_is(req, limited) && !sr_is_removed(sr, irn) && !co_gs_is_optimizable(sr->co, irn)) {
                        if (sr_is_simplicial(sr, irn)) {
                                        coloring_suffix_t *cs = obstack_alloc(&sr->ob, sizeof(*cs));
 
index 9e2cf82..a97d40d 100644 (file)
@@ -32,7 +32,8 @@
 
 #ifdef WITH_ILP
 
-#include <bitset.h>
+#include "bitset.h"
+#include "raw_bitset.h"
 #include "pdeq.h"
 
 #include "irtools.h"
@@ -63,20 +64,20 @@ static void build_coloring_cstr(ilp_env_t *ienv) {
        be_ifg_foreach_node(ifg, iter, irn)
                if (!sr_is_removed(ienv->sr, irn)) {
                        int col, cst_idx;
-                       arch_register_req_t req;
+                       const arch_register_req_t *req;
                        int curr_node_color = get_irn_col(ienv->co, irn);
                        int node_nr = (int)get_irn_node_nr(irn);
                        local_env_t *lenv = ienv->env;
 
                        pmap_insert(lenv->nr_2_irn, INT_TO_PTR(node_nr), irn);
 
-                       arch_get_register_req(ienv->co->aenv, &req, irn, -1);
+                       req = arch_get_register_req(ienv->co->aenv, irn, -1);
 
                        /* get assignable colors */
-                       if (arch_register_req_is(&req, limited))
-                               req.limited(req.limited_env, colors);
-                       else {
-                               arch_register_class_put(req.cls, colors);
+                       if (arch_register_req_is(req, limited)) {
+                               rbitset_copy_to_bitset(req->limited, colors);
+                       else {
+                               arch_register_class_put(req->cls, colors);
                                // bitset_andnot(colors, ienv->co->cenv->ignore_colors);
                        }
 
index 0001f7f..1b9ccd4 100644 (file)
@@ -5,7 +5,7 @@
  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_ALLOCA_H
@@ -19,6 +19,7 @@
 #include "xmalloc.h"
 #include "debug.h"
 #include "pmap.h"
+#include "raw_bitset.h"
 #include "irgraph.h"
 #include "irgwalk.h"
 #include "irprog.h"
@@ -202,7 +203,7 @@ void free_copy_opt(copy_opt_t *co) {
 }
 
 int co_is_optimizable_root(const copy_opt_t *co, ir_node *irn) {
-       arch_register_req_t req;
+       const arch_register_req_t *req;
        const arch_register_t *reg;
 
        if (arch_irn_is(co->aenv, irn, ignore))
@@ -212,7 +213,8 @@ int co_is_optimizable_root(const copy_opt_t *co, ir_node *irn) {
        if (arch_register_type_is(reg, ignore))
                return 0;
 
-       if (is_Reg_Phi(irn) || is_Perm_Proj(co->aenv, irn) || is_2addr_code(co->aenv, irn, &req))
+       req = arch_get_register_req(co->aenv, irn, -1);
+       if (is_Reg_Phi(irn) || is_Perm_Proj(co->aenv, irn) || is_2addr_code(req))
                return 1;
 
        return 0;
@@ -235,14 +237,16 @@ int co_is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
                ir_node *n = edge->src;
 
                if (!nodes_interfere(co->cenv, irn, n) || irn == n) {
-                       arch_register_req_t req;
-                       arch_get_register_req(co->aenv, &req, n, -1);
+                       const arch_register_req_t *req;
+                       req = arch_get_register_req(co->aenv, n, -1);
 
                        if(is_Reg_Phi(n) ||
                           is_Perm(co->aenv, n) ||
-                          (arch_register_req_is(&req, should_be_same) && req.other_same == irn)
-                         )
-                               return 1;
+                          (arch_register_req_is(req, should_be_same))) {
+                               ir_node *other = get_irn_n(irn, req->other_same);
+                               if(other == irn)
+                                       return 1;
+                       }
                }
        }
 
@@ -384,7 +388,6 @@ static int ou_max_ind_set_costs(unit_t *ou) {
 static void co_collect_units(ir_node *irn, void *env) {
        copy_opt_t *co = env;
        unit_t *unit;
-       arch_register_req_t req;
 
        if (!is_curr_reg_class(co, irn))
                return;
@@ -454,21 +457,25 @@ static void co_collect_units(ir_node *irn, void *env) {
                unit->nodes[0] = irn;
                unit->nodes[1] = get_Perm_src(irn);
                unit->costs[1] = co->get_costs(co, irn, unit->nodes[1], -1);
-       } else
-
-       /* Src == Tgt of a 2-addr-code instruction */
-       if (is_2addr_code(co->aenv, irn, &req)) {
-               ir_node *other = req.other_same;
-               if (!nodes_interfere(co->cenv, irn, other)) {
-                       unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
-                       unit->costs = xmalloc(2 * sizeof(*unit->costs));
-                       unit->node_count = 2;
-                       unit->nodes[0] = irn;
-                       unit->nodes[1] = other;
-                       unit->costs[1] = co->get_costs(co, irn, other, -1);
+       } else {
+               const arch_register_req_t *req =
+                       arch_get_register_req(co->aenv, irn, -1);
+
+               /* Src == Tgt of a 2-addr-code instruction */
+               if (is_2addr_code(req)) {
+                       ir_node *other = get_irn_n(irn, req->other_same);
+                       if (!nodes_interfere(co->cenv, irn, other)) {
+                               unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
+                               unit->costs = xmalloc(2 * sizeof(*unit->costs));
+                               unit->node_count = 2;
+                               unit->nodes[0] = irn;
+                               unit->nodes[1] = other;
+                               unit->costs[1] = co->get_costs(co, irn, other, -1);
+                       }
+               } else {
+                       assert(0 && "This is not an optimizable node!");
                }
-       } else
-               assert(0 && "This is not an optimizable node!");
+       }
 
        /* Insert the new unit at a position according to its costs */
        if (unit->node_count > 1) {
@@ -749,7 +756,6 @@ static INLINE void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs
 static void build_graph_walker(ir_node *irn, void *env) {
        copy_opt_t *co = env;
        int pos, max;
-       arch_register_req_t req;
        const arch_register_t *reg;
 
        if (!is_curr_reg_class(co, irn) || arch_irn_is(co->aenv, irn, ignore))
@@ -773,8 +779,14 @@ static void build_graph_walker(ir_node *irn, void *env) {
        }
 
        /* 2-address code */
-       else if (is_2addr_code(co->aenv, irn, &req))
-               add_edges(co, irn, req.other_same, co->get_costs(co, irn, req.other_same, 0));
+       else {
+               const arch_register_req_t *req =
+                       arch_get_register_req(co->aenv, irn, -1);
+               if (is_2addr_code(req)) {
+                       ir_node *other = get_irn_n(irn, req->other_same);
+                       add_edges(co, irn, other, co->get_costs(co, irn, other, 0));
+               }
+       }
 }
 
 void co_build_graph_structure(copy_opt_t *co) {
@@ -811,7 +823,6 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
 {
        be_ifg_t *ifg  = co->cenv->ifg;
        int *color_map = alloca(co->cls->n_regs * sizeof(color_map[0]));
-       bitset_t *adm  = bitset_alloca(co->cls->n_regs);
 
        ir_node *irn;
        void *it, *nit;
@@ -844,17 +855,15 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f)
                        int idx            = PTR_TO_INT(get_irn_link(irn));
                        affinity_node_t *a = get_affinity_info(co, irn);
 
-                       arch_register_req_t req;
+                       const arch_register_req_t *req;
                        ir_node *adj;
 
-                       arch_get_register_req(co->aenv, &req, irn, BE_OUT_POS(0));
-                       if(arch_register_req_is(&req, limited)) {
-                               bitset_clear_all(adm);
-                               req.limited(req.limited_env, adm);
-                               for(i = 0; i < co->cls->n_regs; ++i)
-                                       if(!bitset_is_set(adm, i) && color_map[i] >= 0)
+                       req = arch_get_register_req(co->aenv, irn, BE_OUT_POS(0));
+                       if(arch_register_req_is(req, limited)) {
+                               for(i = 0; i < co->cls->n_regs; ++i) {
+                                       if(!rbitset_is_set(req->limited, i) && color_map[i] >= 0)
                                                fprintf(f, "%d %d -1\n", color_map[i], idx);
-
+                               }
                        }
 
 
@@ -1272,25 +1281,27 @@ static void ifg_dump_node_attr(FILE *f, void *self, ir_node *irn)
 {
        co_ifg_dump_t *env         = self;
        const arch_register_t *reg = arch_get_irn_register(env->co->aenv, irn);
-       arch_register_req_t req;
+       const arch_register_req_t *req;
        int limited;
 
-       arch_get_register_req(env->co->aenv, &req, irn, BE_OUT_POS(0));
-       limited = arch_register_req_is(&req, limited);
+       req = arch_get_register_req(env->co->aenv, irn, BE_OUT_POS(0));
+       limited = arch_register_req_is(req, limited);
 
        if(env->flags & CO_IFG_DUMP_LABELS) {
                ir_fprintf(f, "label=\"%+F", irn);
 
+#if 0
+               // TODO fix this...
                if((env->flags & CO_IFG_DUMP_CONSTR) && limited) {
                        bitset_t *bs = bitset_alloca(env->co->cls->n_regs);
                        req.limited(req.limited_env, bs);
                        ir_fprintf(f, "\\n%B", bs);
                }
+#endif
                ir_fprintf(f, "\" ");
-       }
-
-       else
+       } else {
                fprintf(f, "label=\"\" shape=point " );
+       }
 
        if(env->flags & CO_IFG_DUMP_SHAPE)
                fprintf(f, "shape=%s ", limited ? "diamond" : "ellipse");
index 5c12ab8..48c795f 100644 (file)
@@ -52,9 +52,10 @@ struct _copy_opt_t {
 #define is_Perm(arch_env, irn)                         (arch_irn_classify(arch_env, irn) == arch_irn_class_perm)
 #define is_Perm_Proj(arch_env, irn)                    (is_Proj(irn) && is_Perm(arch_env, get_Proj_pred(irn)))
 
-#define is_2addr_code(arch_env, irn, req)      (arch_get_register_req(arch_env, req, irn, -1)->type == arch_register_req_type_should_be_same)
-
-
+static INLINE int is_2addr_code(const arch_register_req_t *req)
+{
+       return req->type == arch_register_req_type_should_be_same;
+}
 
 /******************************************************************************
    ____        _   _    _       _ _          _____ _
diff --git a/ir/be/beemitter.c b/ir/be/beemitter.c
new file mode 100644 (file)
index 0000000..c531a23
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Author:      Matthias Braun
+ * Date:               12.03.2007
+ * Copyright:   (c) Universitaet Karlsruhe
+ * License:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "beemitter.h"
+#include "xmalloc.h"
+#include "irprintf.h"
+
+void be_emit_init_env(be_emit_env_t *env, FILE *F)
+{
+       memset(env, 0, sizeof(env[0]));
+
+       env->F = F;
+       obstack_init(&env->obst);
+       env->linelength = 0;
+}
+
+void be_emit_destroy_env(be_emit_env_t *env)
+{
+       obstack_free(&env->obst, NULL);
+}
+
+void be_emit_ident(be_emit_env_t *env, ident *id)
+{
+       size_t len = get_id_strlen(id);
+       const char *str = get_id_str(id);
+
+       be_emit_string_len(env, str, len);
+}
+
+void be_emit_irvprintf(be_emit_env_t *env, const char *fmt, va_list args)
+{
+       char buf[256];
+
+       ir_vsnprintf(buf, sizeof(buf), fmt, args);
+       be_emit_string(env, buf);
+}
+
+void be_emit_irprintf(be_emit_env_t *env, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       be_emit_irvprintf(env, fmt, ap);
+       va_end(ap);
+}
+
+void be_emit_write_line(be_emit_env_t *env)
+{
+       char *finished_line = obstack_finish(&env->obst);
+
+       fwrite(finished_line, env->linelength, 1, env->F);
+       env->linelength = 0;
+       obstack_free(&env->obst, finished_line);
+}
+
+void be_emit_pad_comment(be_emit_env_t *env)
+{
+       while(env->linelength <= 30) {
+               be_emit_char(env, ' ');
+       }
+       be_emit_cstring(env, "    ");
+}
+
+void be_emit_finish_line_gas(be_emit_env_t *env, const ir_node *node)
+{
+       dbg_info *dbg;
+       const char *sourcefile;
+       unsigned lineno;
+
+       if(node == NULL) {
+               be_emit_char(env, '\n');
+               be_emit_write_line(env);
+               return;
+       }
+
+       be_emit_pad_comment(env);
+       be_emit_cstring(env, "/* ");
+       be_emit_irprintf(env, "%+F ", node);
+
+       dbg = get_irn_dbg_info(node);
+       sourcefile = be_retrieve_dbg_info(dbg, &lineno);
+       if(sourcefile != NULL) {
+               be_emit_string(env, sourcefile);
+               be_emit_irprintf(env, ":%u", lineno);
+       }
+       be_emit_cstring(env, " */\n");
+       be_emit_write_line(env);
+}
diff --git a/ir/be/beemitter.h b/ir/be/beemitter.h
new file mode 100644 (file)
index 0000000..1864ffd
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Author:      Matthias Braun
+ * Date:               12.03.2007
+ * Copyright:   (c) Universitaet Karlsruhe
+ * License:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
+#ifndef BESPILLMORGAN_H_
+#define BESPILLMORGAN_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "obst.h"
+#include "ident.h"
+#include "irnode.h"
+#include "be.h"
+
+/* framework for emitting data (usually the final assembly code) */
+
+typedef struct be_emit_env_t {
+       FILE *F;
+       struct obstack obst;
+       int            linelength;
+} be_emit_env_t;
+
+static INLINE void be_emit_char(be_emit_env_t *env, char c)
+{
+       obstack_1grow(&env->obst, c);
+       env->linelength++;
+}
+
+static INLINE void be_emit_string_len(be_emit_env_t *env, const char *str,
+                                      size_t l)
+{
+       obstack_grow(&env->obst, str, l);
+       env->linelength += l;
+}
+
+static INLINE void be_emit_string(be_emit_env_t *env, const char *str)
+{
+       size_t len = strlen(str);
+       be_emit_string_len(env, str, len);
+}
+
+#define be_emit_cstring(env,x) { be_emit_string_len(env, x, sizeof(x)-1); }
+
+void be_emit_init_env(be_emit_env_t *env, FILE *F);
+void be_emit_destroy_env(be_emit_env_t *env);
+
+void be_emit_ident(be_emit_env_t *env, ident *id);
+void be_emit_irprintf(be_emit_env_t *env, const char *fmt, ...);
+void be_emit_irvprintf(be_emit_env_t *env, const char *fmt, va_list args);
+void be_emit_write_line(be_emit_env_t *env);
+
+/* appends a gas-style comment with the node number and writes the line */
+void be_emit_finish_line_gas(be_emit_env_t *env, const ir_node *node);
+void be_emit_pad_comment(be_emit_env_t *env);
+
+#endif
diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c
new file mode 100644 (file)
index 0000000..0d68ca5
--- /dev/null
@@ -0,0 +1,707 @@
+/**
+ * Dumps global variables and constants as gas assembler.
+ * @author Christian Wuerdig, Matthias Braun
+ * @date 04.11.2005
+ * @version $Id$
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "begnuas.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "obst.h"
+#include "tv.h"
+#include "irnode.h"
+#include "entity.h"
+#include "irprog.h"
+#include "error.h"
+
+#include "be_t.h"
+#include "beemitter.h"
+#include "be_dbgout.h"
+
+typedef struct obstack obstack_t;
+
+/** by default, we generate assembler code for the Linux gas */
+be_gas_flavour_t be_gas_flavour = GAS_FLAVOUR_NORMAL;
+
+static const char* get_section_name(be_gas_section_t section) {
+       static const char *text[GAS_FLAVOUR_MAX][GAS_SECTION_MAX] = {
+               {
+                       ".section\t.text",
+                       ".section\t.data",
+                       ".section\t.rodata",
+                       ".section\t.bss",
+                       ".section\t.tbss,\"awT\",@nobits",
+                       ".section\t.ctors,\"aw\",@progbits"
+               },
+               {
+                       ".section\t.text",
+                       ".section\t.data",
+                       ".section .rdata,\"dr\"",
+                       ".section\t.bss",
+                       ".section\t.tbss,\"awT\",@nobits",
+                       ".section\t.ctors,\"aw\",@progbits"
+               }
+       };
+
+       assert(be_gas_flavour >= 0 && be_gas_flavour < GAS_FLAVOUR_MAX);
+       assert(section >= 0 && section < GAS_SECTION_MAX);
+       return text[be_gas_flavour][section];
+}
+
+void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section) {
+       be_emit_char(env, '\t');
+       be_emit_string(env, get_section_name(section));
+       be_emit_char(env, '\n');
+       be_emit_write_line(env);
+}
+
+typedef struct _ia32_decl_env {
+       obstack_t *rodata_obst;
+       obstack_t *data_obst;
+       obstack_t *bss_obst;
+       obstack_t *ctor_obst;
+       const be_main_env_t *main_env;
+} ia32_decl_env_t;
+
+/************************************************************************/
+
+/**
+ * output a tarval
+ */
+static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
+{
+       switch (bytes) {
+
+       case 1:
+               obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
+               break;
+
+       case 2:
+               obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+               break;
+
+       case 4:
+               obstack_printf(obst, "0x%02x%02x%02x%02x",
+                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+               break;
+
+       case 8:
+               obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
+                       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+               break;
+
+       case 10:
+       case 12:
+               break;
+
+       case 16:
+               obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
+                                              "%02x%02x%02x%02x%02x%02x%02x%02x",
+                       get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
+                       get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
+                       get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+                       get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
+                       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+                       get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+                       get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+               break;
+
+
+       default:
+               fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
+               assert(0);
+       }
+}
+
+/**
+ * Return the tarval of an atomic initializer.
+ */
+static tarval *get_atomic_init_tv(ir_node *init)
+{
+       for (;;) {
+               ir_mode *mode = get_irn_mode(init);
+
+               switch (get_irn_opcode(init)) {
+
+               case iro_Cast:
+                       init = get_Cast_op(init);
+                       continue;
+
+               case iro_Conv:
+                       init = get_Conv_op(init);
+                       continue;
+
+               case iro_Const:
+                       return get_Const_tarval(init);
+
+               case iro_SymConst:
+                       switch (get_SymConst_kind(init)) {
+                       case symconst_ofs_ent:
+                               return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
+
+                       case symconst_type_size:
+                               return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
+
+                       case symconst_type_align:
+                               return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
+
+                       case symconst_enum_const:
+                               return get_enumeration_value(get_SymConst_enum(init));
+
+                       default:
+                               return NULL;
+                       }
+
+               default:
+                       return NULL;
+               }
+       }
+}
+
+/**
+ * dump an atomic value
+ */
+static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
+{
+       ir_mode *mode = get_irn_mode(init);
+       int bytes     = get_mode_size_bytes(mode);
+       tarval *tv;
+
+       switch (get_irn_opcode(init)) {
+
+       case iro_Cast:
+               do_dump_atomic_init(obst, get_Cast_op(init));
+               return;
+
+       case iro_Conv:
+               do_dump_atomic_init(obst, get_Conv_op(init));
+               return;
+
+       case iro_Const:
+               tv = get_Const_tarval(init);
+
+               /* it's a arithmetic value */
+               dump_arith_tarval(obst, tv, bytes);
+               return;
+
+       case iro_SymConst:
+               switch (get_SymConst_kind(init)) {
+               case symconst_addr_name:
+                       obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
+                       break;
+
+               case symconst_addr_ent:
+                       obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
+                       break;
+
+               case symconst_ofs_ent:
+                       obstack_printf(obst, "%d", get_entity_offset(get_SymConst_entity(init)));
+                       break;
+
+               case symconst_type_size:
+                       obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
+                       break;
+
+               case symconst_type_align:
+                       obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
+                       break;
+
+               case symconst_enum_const:
+                       tv = get_enumeration_value(get_SymConst_enum(init));
+                       dump_arith_tarval(obst, tv, bytes);
+                       break;
+
+               default:
+                       assert(!"dump_atomic_init(): don't know how to init from this SymConst");
+               }
+               return;
+
+               case iro_Add:
+                       do_dump_atomic_init(obst, get_Add_left(init));
+                       obstack_printf(obst, " + ");
+                       do_dump_atomic_init(obst, get_Add_right(init));
+                       return;
+
+               case iro_Sub:
+                       do_dump_atomic_init(obst, get_Sub_left(init));
+                       obstack_printf(obst, " - ");
+                       do_dump_atomic_init(obst, get_Sub_right(init));
+                       return;
+
+               case iro_Mul:
+                       do_dump_atomic_init(obst, get_Mul_left(init));
+                       obstack_printf(obst, " * ");
+                       do_dump_atomic_init(obst, get_Mul_right(init));
+                       return;
+
+               default:
+                       assert(0 && "dump_atomic_init(): unknown IR-node");
+       }
+}
+
+/**
+ * dumps the type for given size (.byte, .long, ...)
+ */
+static void dump_size_type(obstack_t *obst, int size) {
+       switch (size) {
+
+       case 1:
+               obstack_printf(obst, "\t.byte\t");
+               break;
+
+       case 2:
+               obstack_printf(obst, "\t.value\t");
+               break;
+
+       case 4:
+               obstack_printf(obst, "\t.long\t");
+               break;
+
+       case 8:
+               obstack_printf(obst, "\t.quad\t");
+               break;
+
+       case 10:
+       case 12:
+               /* handled in arith */
+               break;
+
+       case 16:
+               obstack_printf(obst, "\t.octa\t");
+               break;
+
+       default:
+               fprintf(stderr, "Try to dump a type with %d bytes\n", size);
+               assert(0);
+       }
+}
+
+/**
+ * dump an atomic value to an obstack
+ */
+static void dump_atomic_init(obstack_t *obst, ir_node *init)
+{
+       ir_mode *mode = get_irn_mode(init);
+       int bytes     = get_mode_size_bytes(mode);
+
+       dump_size_type(obst, bytes);
+       do_dump_atomic_init(obst, init);
+       obstack_printf(obst, "\n");
+}
+
+/************************************************************************/
+/* Routines to dump global variables                                    */
+/************************************************************************/
+
+/**
+ * Determine if an entity is a string constant
+ * @param ent The entity
+ * @return 1 if it is a string constant, 0 otherwise
+ */
+static int ent_is_string_const(ir_entity *ent)
+{
+       ir_type *type, *element_type;
+       ir_mode *mode;
+       int i, c, n;
+
+       type = get_entity_type(ent);
+
+       /* if it's an array */
+       if (!is_Array_type(type))
+               return 0;
+
+       element_type = get_array_element_type(type);
+
+       /* and the array's element type is primitive */
+       if (!is_Primitive_type(element_type))
+               return 0;
+
+       /* and the mode of the element type is an int of
+        * the same size as the byte mode */
+       mode = get_type_mode(element_type);
+       if (!mode_is_int(mode)
+               || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
+               return 0;
+
+       /* if it contains only printable chars and a 0 at the end */
+       n = get_compound_ent_n_values(ent);
+       for (i = 0; i < n; ++i) {
+               ir_node *irn = get_compound_ent_value(ent, i);
+               if(get_irn_opcode(irn) != iro_Const)
+                       return 0;
+
+               c = (int) get_tarval_long(get_Const_tarval(irn));
+
+               if((i < n - 1 && !(isgraph(c) || isspace(c)))
+                               || (i == n - 1 && c != '\0'))
+                       return 0;
+       }
+
+       /* then we can emit it as a string constant */
+       return 1;
+}
+
+/**
+ * Dump a string constant.
+ * No checks are made!!
+ * @param obst The obst to dump on.
+ * @param ent The entity to dump.
+ */
+static void dump_string_cst(obstack_t *obst, ir_entity *ent)
+{
+       int i, n;
+
+       obstack_printf(obst, "\t.string \"");
+       n = get_compound_ent_n_values(ent);
+
+       for (i = 0; i < n-1; ++i) {
+               ir_node *irn;
+               int c;
+
+               irn = get_compound_ent_value(ent, i);
+               c = (int) get_tarval_long(get_Const_tarval(irn));
+
+               switch (c) {
+               case '"' : obstack_printf(obst, "\\\""); break;
+               case '\n': obstack_printf(obst, "\\n"); break;
+               case '\r': obstack_printf(obst, "\\r"); break;
+               case '\t': obstack_printf(obst, "\\t"); break;
+               case '\\': obstack_printf(obst, "\\\\"); break;
+               default  :
+                       if (isprint(c))
+                               obstack_printf(obst, "%c", c);
+                       else
+                               obstack_printf(obst, "\\%o", c);
+                       break;
+               }
+       }
+       obstack_printf(obst, "\"\n");
+}
+
+static void dump_array_init(obstack_t *obst, ir_entity *ent)
+{
+       const ir_type *ty = get_entity_type(ent);
+       int i;
+       int filler;
+       int size = 0;
+
+       /* potential spare values should be already included! */
+       for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
+               ir_entity *step = get_compound_ent_value_member(ent, i);
+               ir_type *stype = get_entity_type(step);
+
+               if (get_type_mode(stype)) {
+                       int align = (get_type_alignment_bits(stype) + 7) >> 3;
+                       int n     = size % align;
+
+                       if (n > 0) {
+                               obstack_printf(obst, "\t.zero\t%d\n", align - n);
+                               size += align - n;
+                       }
+               }
+               dump_atomic_init(obst, get_compound_ent_value(ent, i));
+               size += get_type_size_bytes(stype);
+       }
+       filler = get_type_size_bytes(ty) - size;
+
+       if (filler > 0)
+               obstack_printf(obst, "\t.skip\t%d\n", filler);
+}
+
+enum normal_or_bitfield_kind {
+       NORMAL = 0,
+       BITFIELD
+};
+
+typedef struct {
+       enum normal_or_bitfield_kind kind;
+       union {
+               ir_node *value;
+               unsigned char bf_val;
+       } v;
+} normal_or_bitfield;
+
+/**
+ * Dump an initializer for a compound entity.
+ */
+static void dump_compound_init(obstack_t *obst, ir_entity *ent)
+{
+       normal_or_bitfield *vals;
+       int i, j, n = get_compound_ent_n_values(ent);
+       int last_ofs;
+
+       /* Find the initializer size. Sorrily gcc support a nasty feature:
+          The last field of a compound may be a flexible array. This allows
+          initializers bigger than the type size. */
+       last_ofs = 0;
+       for (i = 0; i < n; ++i) {
+               int offset = get_compound_ent_value_offset_bytes(ent, i);
+               int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
+               const compound_graph_path *path = get_compound_ent_value_path(ent, i);
+               int path_len = get_compound_graph_path_length(path);
+               ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
+               int value_len = get_type_size_bits(get_entity_type(last_ent));
+
+               offset += (value_len + bits_remainder + 7) >> 3;
+
+               if (offset > last_ofs) {
+                       last_ofs = offset;
+               }
+       }
+
+       /*
+        * In the worst case, every initializer allocates one byte.
+        * Moreover, initializer might be big, do not allocate on stack.
+        */
+       vals = xcalloc(last_ofs, sizeof(vals[0]));
+
+       /* collect the values and store them at the offsets */
+       for (i = 0; i < n; ++i) {
+               const compound_graph_path *path = get_compound_ent_value_path(ent, i);
+               int path_len = get_compound_graph_path_length(path);
+               int offset = get_compound_ent_value_offset_bytes(ent, i);
+               int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
+               ir_node *value = get_compound_ent_value(ent, i);
+               ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
+               int value_len = get_type_size_bits(get_entity_type(last_ent));
+               assert(offset >= 0);
+               assert(offset_bits >= 0);
+
+               if (offset_bits != 0 ||
+                       (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
+                       tarval *shift, *shifted;
+                       tarval *tv = get_atomic_init_tv(value);
+                       if (tv == NULL) {
+                               panic("Couldn't get numeric value for bitfield initializer '%s'\n",
+                                     get_entity_ld_name(ent));
+                       }
+                       tv = tarval_convert_to(tv, mode_Lu);
+                       shift = new_tarval_from_long(offset_bits, mode_Is);
+                       shifted = tarval_shl(tv, shift);
+                       if (shifted == tarval_bad || shifted == tarval_undefined) {
+                               panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
+                                     get_entity_ld_name(ent));
+                       }
+
+                       for (j = 0; value_len > 0; ++j) {
+                               assert(offset + j < last_ofs);
+                               assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
+                               vals[offset + j].kind = BITFIELD;
+                               vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
+                               value_len -= 8 - offset_bits;
+                               offset_bits = 0;
+                       }
+               } else {
+                       assert(offset < last_ofs);
+                       assert(vals[offset].kind == NORMAL);
+                       assert(vals[offset].v.value == NULL);
+                       vals[offset].v.value = value;
+               }
+       }
+
+       /* now write them sorted */
+       for (i = 0; i < last_ofs; ) {
+               int space = 0, skip = 0;
+               if (vals[i].kind == NORMAL) {
+                       if(vals[i].v.value != NULL) {
+                               dump_atomic_init(obst, vals[i].v.value);
+                               skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
+                       } else {
+                               space = 1;
+                       }
+               } else {
+                       assert(vals[i].kind == BITFIELD);
+                       obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
+               }
+
+               ++i;
+               space = 0;
+               while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
+                       ++space;
+                       ++i;
+               }
+               space -= skip;
+               assert(space >= 0);
+
+               /* a gap */
+               if (space > 0)
+                       obstack_printf(obst, "\t.skip\t%d\n", space);
+       }
+       xfree(vals);
+}
+
+/**
+ * Dump a global entity.
+ */
+static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
+{
+       obstack_t *obst;
+       ir_type *type = get_entity_type(ent);
+       const char *ld_name = get_entity_ld_name(ent);
+       ir_variability variability = get_entity_variability(ent);
+       ir_visibility visibility = get_entity_visibility(ent);
+       int align = get_type_alignment_bytes(type);
+       int emit_as_common = 0;
+
+       obst = env->data_obst;
+       if (is_Method_type(type)) {
+               if (get_method_img_section(ent) == section_constructors) {
+                       obst = env->ctor_obst;
+                       obstack_printf(obst, ".balign\t%d\n", align);
+                       dump_size_type(obst, align);
+                       obstack_printf(obst, "%s\n", ld_name);
+               }
+               return;
+       } else if (variability == variability_constant) {
+               /* a constant entity, put it on the rdata */
+               obst = env->rodata_obst;
+       } else if (variability == variability_uninitialized) {
+               /* uninitialized entity put it in bss segment */
+               obst = env->bss_obst;
+               if(emit_commons && visibility != visibility_local)
+                       emit_as_common = 1;
+       }
+
+       be_dbg_variable(env->main_env->db_handle, obst, ent);
+
+       /* global or not global */
+       if (visibility == visibility_external_visible && !emit_as_common) {
+               obstack_printf(obst, ".global\t%s\n", ld_name);
+       } else if(visibility == visibility_external_allocated) {
+               obstack_printf(obst, ".global\t%s\n", ld_name);
+               /* we can return now... */
+               return;
+       }
+       /* alignment */
+       if (align > 1 && !emit_as_common) {
+               obstack_printf(obst, ".balign\t%d\n", align);
+       }
+
+       if (!emit_as_common) {
+               obstack_printf(obst, "%s:\n", ld_name);
+       }
+
+       if (variability == variability_uninitialized) {
+               if(emit_as_common) {
+                       obstack_printf(obst, "\t.comm %s,%d,%d\n",
+                                       ld_name, get_type_size_bytes(type), align);
+               } else {
+                       obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
+               }
+       } else if (is_atomic_type(type)) {
+               dump_atomic_init(obst, get_atomic_ent_value(ent));
+       } else if (ent_is_string_const(ent)) {
+               dump_string_cst(obst, ent);
+       } else if (is_Array_type(type)) {
+               dump_array_init(obst, ent);
+       } else if (is_compound_type(type)) {
+               dump_compound_init(obst, ent);
+       } else {
+               assert(0 && "unsupported type");
+       }
+}
+
+/**
+ * Dumps declarations of global variables and the initialization code.
+ */
+static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env, int emit_commons)
+{
+       int i, n = get_compound_n_members(gt);
+
+       for (i = 0; i < n; i++) {
+               ir_entity *ent = get_compound_member(gt, i);
+               dump_global(env, ent, emit_commons);
+       }
+}
+
+/************************************************************************/
+
+void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env) {
+       ia32_decl_env_t env;
+       obstack_t rodata, data, bss, ctor;
+       int    size;
+       char   *cp;
+
+       /* dump the global type */
+       obstack_init(&rodata);
+       obstack_init(&data);
+       obstack_init(&bss);
+       obstack_init(&ctor);
+
+       env.rodata_obst = &rodata;
+       env.data_obst   = &data;
+       env.bss_obst    = &bss;
+       env.ctor_obst   = &ctor;
+       env.main_env    = main_env;
+
+       ia32_dump_globals(get_glob_type(), &env, 1);
+
+       size = obstack_object_size(&data);
+       cp   = obstack_finish(&data);
+       if (size > 0) {
+               be_gas_emit_switch_section(emit, GAS_SECTION_DATA);
+               be_emit_string_len(emit, cp, size);
+               be_emit_write_line(emit);
+       }
+
+       size = obstack_object_size(&rodata);
+       cp   = obstack_finish(&rodata);
+       if (size > 0) {
+               be_gas_emit_switch_section(emit, GAS_SECTION_RODATA);
+               be_emit_string_len(emit, cp, size);
+               be_emit_write_line(emit);
+       }
+
+       size = obstack_object_size(&bss);
+       cp   = obstack_finish(&bss);
+       if (size > 0) {
+               be_gas_emit_switch_section(emit, GAS_SECTION_COMMON);
+               be_emit_string_len(emit, cp, size);
+               be_emit_write_line(emit);
+       }
+
+       size = obstack_object_size(&ctor);
+       cp   = obstack_finish(&ctor);
+       if (size > 0) {
+               be_gas_emit_switch_section(emit, GAS_SECTION_CTOR);
+               be_emit_string_len(emit, cp, size);
+               be_emit_write_line(emit);
+       }
+
+       obstack_free(&rodata, NULL);
+       obstack_free(&data, NULL);
+       obstack_free(&bss, NULL);
+       obstack_free(&ctor, NULL);
+
+       /* dump the Thread Local Storage */
+       obstack_init(&data);
+
+       env.rodata_obst = &data;
+       env.data_obst   = &data;
+       env.bss_obst    = &data;
+       env.ctor_obst   = NULL;
+
+       ia32_dump_globals(get_tls_type(), &env, 0);
+
+       size = obstack_object_size(&data);
+       cp   = obstack_finish(&data);
+       if (size > 0) {
+               be_gas_emit_switch_section(emit, GAS_SECTION_TLS);
+               be_emit_cstring(emit, ".balign\t32\n");
+               be_emit_write_line(emit);
+               be_emit_string_len(emit, cp, size);
+               be_emit_write_line(emit);
+       }
+
+       obstack_free(&data, NULL);
+}
diff --git a/ir/be/begnuas.h b/ir/be/begnuas.h
new file mode 100644 (file)
index 0000000..53f853f
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * Header for ia32 assembler declarations dumper.
+ * @author Christian Wuerdig, Matthias Braun
+ * $Id$
+ */
+#ifndef _BE_GEN_DECLS_H_
+#define _BE_GEN_DECLS_H_
+
+#include "be.h"
+#include "beemitter.h"
+
+/**
+ * Sections.
+ */
+typedef enum section_t {
+       GAS_SECTION_TEXT   = 0,   /**< text section */
+       GAS_SECTION_DATA   = 1,   /**< data section */
+       GAS_SECTION_RODATA = 2,   /**< rodata section */
+       GAS_SECTION_COMMON = 3,   /**< common section */
+       GAS_SECTION_TLS    = 4,   /**< thread local storage section */
+       GAS_SECTION_CTOR   = 5,   /**< ctor section for instrumentation code init */
+       GAS_SECTION_MAX    = 6
+} be_gas_section_t;
+
+typedef enum asm_flavour_t {
+       GAS_FLAVOUR_NORMAL = 0,  /**< normal gas */
+       GAS_FLAVOUR_MINGW  = 1,  /**< MinGW variant */
+       GAS_FLAVOUR_MAX    = 2
+} be_gas_flavour_t;
+
+extern be_gas_flavour_t be_gas_flavour;
+
+
+/**
+ * Generate all entities.
+ */
+void be_gas_emit_decls(be_emit_env_t *env, const be_main_env_t *main_env);
+
+void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section);
+
+#endif
index d6dfdc5..8c9ebdf 100644 (file)
@@ -31,6 +31,7 @@
 #include "debug.h"
 #include "irtools.h"
 #include "irdump.h"
+#include "irprintf.h"
 #include "plist.h"
 #include "irprintf.h"
 
index ac027f3..6f79b00 100644 (file)
@@ -1,5 +1,5 @@
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "irgraph_t.h"
@@ -9,6 +9,7 @@
 #include "besched_t.h"
 #include "beinsn_t.h"
 #include "beabi.h"
+#include "raw_bitset.h"
 
 be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
 {
@@ -29,12 +30,12 @@ be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
 
                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.req             = arch_get_register_req(arch_env, 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);
+                               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;
@@ -43,21 +44,23 @@ be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
                }
 
                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);
+       } else if(arch_irn_consider_in_reg_alloc(arch_env, env->cls, irn)) {
+               o.req     = arch_get_register_req(arch_env, irn, -1);
                o.carrier = irn;
                o.irn     = irn;
                o.pos     = -1;
                o.partner = NULL;
-               o.has_constraints = arch_register_req_is(&o.req, limited);
+               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;
+       if(pre_colored > 0) {
+               assert(pre_colored == insn->n_ops && "partly pre-colored nodes not supported");
+               insn->pre_colored = 1;
+       }
        insn->use_start   = insn->n_ops;
 
        for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
@@ -66,12 +69,12 @@ be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
                if(!arch_irn_consider_in_reg_alloc(arch_env, env->cls, op))
                        continue;
 
-               arch_get_register_req(arch_env, &o.req, irn, i);
+               o.req     = arch_get_register_req(arch_env, irn, i);
                o.carrier = op;
                o.irn     = irn;
                o.pos     = i;
                o.partner = NULL;
-               o.has_constraints = arch_register_req_is(&o.req, limited);
+               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;
@@ -83,18 +86,23 @@ be_insn_t *be_scan_insn(const be_insn_env_t *env, ir_node *irn)
        /* Compute the admissible registers bitsets. */
        for (i = 0; i < insn->n_ops; ++i) {
                be_operand_t *op = &insn->ops[i];
+               const arch_register_req_t *req = op->req;
 
-               if (op->req.cls == NULL && op->req.type == arch_register_req_type_none) {
-                       op->req.cls  = env->cls;
-                       op->req.type = arch_register_req_type_normal;
+#if 0
+               // Matze: can we do without this?
+               if (req->cls == NULL && req->type == arch_register_req_type_none) {
+                       req->cls  = env->cls;
+                       req->type = arch_register_req_type_normal;
                }
+#endif
+
+               assert(req->cls == env->cls);
 
-               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 {
+               if (arch_register_req_is(req, limited)) {
+                       rbitset_copy_to_bitset(req->limited, op->regs);
+               else {
                        arch_put_non_ignore_regs(arch_env, env->cls, op->regs);
                        if (env->ignore_colors)
                                bitset_andnot(op->regs, env->ignore_colors);
@@ -111,5 +119,6 @@ be_insn_env_t *be_insn_env_init(be_insn_env_t *ie, const be_irg_t *birg, const a
        ie->obst = obst;
        ie->ignore_colors = bitset_obstack_alloc(obst, cls->n_regs);
        be_abi_put_ignore_regs(birg->abi, cls, ie->ignore_colors);
+
        return ie;
 }
index 777a122..e084f4f 100644 (file)
@@ -16,25 +16,26 @@ 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;
+       ir_node *irn;                   /**< firm node of the insn this operand blongs to */
+       ir_node *carrier;               /**< node representing the operand value (proj or the node itself for defs, the value itself for uses */
+       be_operand_t *partner;          /**< used in bechordal later... (TODO what does it do?) */
+       bitset_t *regs;                 /**< admissible register bitset */
+       int pos;                        /**< pos of the operand (0 to n are inputs, -1 to -n are outputs) */
+       const arch_register_req_t *req; /**< register constraints for the carrier node */
+       unsigned has_constraints : 1;   /**< the carrier node has register constraints (the constraint type is limited) */
 };
 
 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;
+       be_operand_t *ops;             /**< the values used and defined by the insn */
+       int n_ops;                     /**< length of the ops array */
+       int use_start;                 /**< entries [0-use_start) in ops are defs,
+                                           [use_start-n_ops) uses */
+       ir_node *next_insn;            /**< next instruction in schedule */
+       ir_node *irn;                  /**< ir_node of the instruction */
+       unsigned in_constraints  : 1;  /**< instruction has input contraints */
+       unsigned out_constraints : 1;  /**< instruction has output constraints */
+       unsigned has_constraints : 1;  /**< in_constraints or out_constraints true */
+       unsigned pre_colored     : 1;  /**< all defined values already have a register assigned */
 };
 
 struct _be_insn_env_t {
index 28d86e1..a2b2c1f 100644 (file)
@@ -13,7 +13,7 @@
  * CVS-Id:      $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <stdlib.h>
@@ -54,8 +54,8 @@
 
 #include "beirgmod.h"
 
-#define DBG_MODULE "firm.be.irgmod"
 #define DBG_LEVEL SET_LEVEL_0
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 /*
   ____                  _
@@ -172,7 +172,6 @@ static void determine_phi_blocks(pset *copies, pset *copy_blocks, pset *phi_bloc
 {
        ir_node *bl;
        waitq *worklist = new_waitq();
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
 
        /*
         * Fill the worklist queue and the rest of the orig blocks array.
@@ -253,7 +252,6 @@ static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blo
 {
        ir_node *curr_bl;
        ir_node *start_irn;
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
 
        curr_bl = get_nodes_block(usage);
 
@@ -364,8 +362,6 @@ static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *
                int pos;
        } *outs;
 
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
-
        obstack_init(&obst);
 
        /*
@@ -486,7 +482,6 @@ void be_ssa_constr_set_phis_ignore(be_dom_front_info_t *df, be_lv_t *lv, pset *n
        int save_optimize      = get_optimize();
        int save_normalize     = get_opt_normalize();
        int phis_set_created   = 0;
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
 
        ir_node *irn;
 
@@ -579,7 +574,6 @@ ir_node *insert_Perm_after(const arch_env_t *arch_env,
        ir_node *bl     = is_Block(pos) ? pos : get_nodes_block(pos);
        ir_graph *irg   = get_irn_irg(bl);
        pset *live      = pset_new_ptr_default();
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, "be.node");
 
        ir_node *curr, *irn, *perm, **nodes;
        int i, n;
@@ -722,3 +716,10 @@ int be_remove_empty_blocks(ir_graph *irg) {
        }
        return changed;
 }
+
+void be_init_irgmod(void)
+{
+       FIRM_DBG_REGISTER(dbg, "firm.be.irgmod");
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_irgmod);
index 57f6699..290afd9 100644 (file)
@@ -5,9 +5,8 @@
  * @author Sebastian Hack
  * @cvs-id $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <stdio.h>
@@ -45,6 +44,8 @@
 #include <libcore/lc_opts.h>
 #include <libcore/lc_opts_enum.h>
 
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL);
+
 #define BE_SCHED_NODE(irn) (be_is_Keep(irn) || be_is_CopyKeep(irn) || be_is_RegParams(irn))
 
 enum {
@@ -135,7 +136,6 @@ typedef struct _block_sched_env_t {
        nodeset *live;                              /**< simple liveness during scheduling */
        const list_sched_selector_t *selector;
        void *selector_block_env;
-       DEBUG_ONLY(firm_dbg_module_t *dbg;)
 } block_sched_env_t;
 
 /**
@@ -203,7 +203,7 @@ static INLINE int make_ready(block_sched_env_t *env, ir_node *pred, ir_node *irn
        if (env->selector->node_ready)
                env->selector->node_ready(env->selector_block_env, irn, pred);
 
-    DB((env->dbg, LEVEL_2, "\tmaking ready: %+F\n", irn));
+    DB((dbg, LEVEL_2, "\tmaking ready: %+F\n", irn));
 
     return 1;
 }
@@ -358,7 +358,7 @@ static ir_node *add_to_sched(block_sched_env_t *env, ir_node *irn)
                update_sched_liveness(env, irn);
         sched_add_before(env->block, irn);
 
-        DBG((env->dbg, LEVEL_2, "\tadding %+F\n", irn));
+        DBG((dbg, LEVEL_2, "\tadding %+F\n", irn));
     }
 
        /* notify the selector about the finally selected node. */
@@ -448,9 +448,8 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        be.live       = new_nodeset(get_irn_n_edges(block));
        be.selector   = selector;
        be.sched_env  = env;
-       FIRM_DBG_REGISTER(be.dbg, "firm.be.sched");
 
-       DBG((be.dbg, LEVEL_1, "scheduling %+F\n", block));
+       DBG((dbg, LEVEL_1, "scheduling %+F\n", block));
 
        if (selector->init_block)
                be.selector_block_env = selector->init_block(env->selector_env, block);
@@ -500,7 +499,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
 
                        /* Make the node ready, if all operands live in a foreign block */
                        if (ready) {
-                               DBG((be.dbg, LEVEL_2, "\timmediately ready: %+F\n", irn));
+                               DBG((dbg, LEVEL_2, "\timmediately ready: %+F\n", irn));
                                make_ready(&be, NULL, irn);
                        }
                }
@@ -524,7 +523,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
                        irn = be.selector->select(be.selector_block_env, be.cands, be.live);
                }
 
-               DB((be.dbg, LEVEL_2, "\tpicked node %+F\n", irn));
+               DB((dbg, LEVEL_2, "\tpicked node %+F\n", irn));
 
                /* Add the node to the schedule. */
                add_to_sched(&be, irn);
@@ -687,6 +686,8 @@ void be_init_listsched(void) {
        lc_opt_entry_t *sched_grp = lc_opt_get_grp(be_grp, "listsched");
 
        lc_opt_add_table(sched_grp, list_sched_option_table);
+
+       FIRM_DBG_REGISTER(dbg, "firm.be.sched");
 }
 
 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_listsched);
index c9eda11..352c240 100644 (file)
@@ -4,7 +4,7 @@
  * @date 6.12.2004
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "impl.h"
@@ -17,8 +17,9 @@
 #include "beutil.h"
 #include "belive_t.h"
 #include "besched_t.h"
+#include "bemodule.h"
 
-#define DBG_MODULE              "firm.be.liveness"
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 #define LV_STD_SIZE             128
 #define LV_USE_BINARY_SEARCH
@@ -238,7 +239,7 @@ static int be_lv_remove(struct _be_lv_t *li, ir_node *bl, ir_node *irn)
                        payload[n - 1].u.node.flags = 0;
 
                        --irn_live[0].u.head.n_members;
-                       DBG((li->dbg, LEVEL_3, "\tdeleting %+F from %+F at pos %d\n", irn, bl, pos));
+                       DBG((dbg, LEVEL_3, "\tdeleting %+F from %+F at pos %d\n", irn, bl, pos));
                        return 1;
                }
        }
@@ -265,7 +266,7 @@ static void register_node(be_lv_t *lv, const ir_node *irn)
 static INLINE void mark_live_in(be_lv_t *lv, ir_node *block, ir_node *irn)
 {
        struct _be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
-       DBG((lv->dbg, LEVEL_2, "marking %+F live in at %+F\n", irn, block));
+       DBG((dbg, LEVEL_2, "marking %+F live in at %+F\n", irn, block));
        n->flags |= be_lv_state_in;
        register_node(lv, irn);
 }
@@ -276,7 +277,7 @@ static INLINE void mark_live_in(be_lv_t *lv, ir_node *block, ir_node *irn)
 static INLINE void mark_live_out(be_lv_t *lv, ir_node *block, ir_node *irn)
 {
        struct _be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
-       DBG((lv->dbg, LEVEL_2, "marking %+F live out at %+F\n", irn, block));
+       DBG((dbg, LEVEL_2, "marking %+F live out at %+F\n", irn, block));
        n->flags |= be_lv_state_out | be_lv_state_end;
        register_node(lv, irn);
 }
@@ -287,7 +288,7 @@ static INLINE void mark_live_out(be_lv_t *lv, ir_node *block, ir_node *irn)
 static INLINE void mark_live_end(be_lv_t *lv, ir_node *block, ir_node *irn)
 {
        struct _be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
-       DBG((lv->dbg, LEVEL_2, "marking %+F live end at %+F\n", irn, block));
+       DBG((dbg, LEVEL_2, "marking %+F live end at %+F\n", irn, block));
        n->flags |= be_lv_state_end;
        register_node(lv, irn);
 }
@@ -462,7 +463,6 @@ be_lv_t *be_liveness(ir_graph *irg)
        be_lv_t *lv = xmalloc(sizeof(lv[0]));
 
        memset(lv, 0, sizeof(lv[0]));
-       FIRM_DBG_REGISTER(lv->dbg, DBG_MODULE);
        lv->irg = irg;
        lv->nodes = bitset_malloc(2 * get_irg_last_idx(irg));
        lv->hook_info.context = lv;
@@ -676,14 +676,6 @@ int be_check_dominance(ir_graph *irg)
 pset *be_liveness_transfer(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *irn, pset *live)
 {
        int i, n;
-       FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
-
-       DEBUG_ONLY(
-               const ir_node *x;
-               DBG((dbg, LEVEL_1, "%+F\n", irn));
-               for(x = pset_first(live); x; x = pset_next(live))
-                       DBG((dbg, LEVEL_1, "\tlive: %+F\n", x));
-       )
 
        /* You should better break out of your loop when hitting the first phi function. */
        assert(!is_Phi(irn) && "liveness_transfer produces invalid results for phi nodes");
@@ -749,3 +741,10 @@ pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_
 
        return live;
 }
+
+void be_init_live(void)
+{
+       FIRM_DBG_REGISTER(dbg, "firm.be.liveness");
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_live);
index 6675f3c..6f1e965 100644 (file)
@@ -25,7 +25,6 @@ struct _be_lv_t {
        ir_graph *irg;
        bitset_t *nodes;
        hook_entry_t hook_info;
-       DEBUG_ONLY(firm_dbg_module_t *dbg;)
 };
 
 struct _be_lv_info_node_t {
index 37d86d9..42a06b0 100644 (file)
@@ -8,7 +8,7 @@
  * Compute register pressure in loops
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "set.h"
@@ -21,6 +21,9 @@
 #include "belive.h"
 #include "besched.h"
 #include "beloopana.h"
+#include "bemodule.h"
+
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL);
 
 #define HASH_LOOP_INFO(info) (HASH_PTR((info)->loop) ^ HASH_PTR((info)->cls))
 
@@ -33,7 +36,6 @@ typedef struct _be_loop_info_t {
 struct _be_loopana_t {
        set      *data;
        be_irg_t *birg;
-       DEBUG_ONLY(firm_dbg_module_t *dbg);
 };
 
 static int cmp_loop_info(const void *a, const void *b, size_t sz) {
@@ -56,7 +58,7 @@ static unsigned be_compute_block_pressure(be_loopana_t *loop_ana, ir_node *block
        ir_node          *irn;
        int              max_live;
 
-       DBG((loop_ana->dbg, LEVEL_1, "Processing Block %+F\n", block));
+       DBG((dbg, LEVEL_1, "Processing Block %+F\n", block));
 
        /* determine largest pressure with this block */
        live_nodes = be_liveness_end_of_block(loop_ana->birg->lv, aenv, cls, block, live_nodes);
@@ -73,7 +75,7 @@ static unsigned be_compute_block_pressure(be_loopana_t *loop_ana, ir_node *block
                max_live   = MAX(cnt, max_live);
        }
 
-       DBG((loop_ana->dbg, LEVEL_1, "Finished with Block %+F (%s %u)\n", block, cls->name, max_live));
+       DBG((dbg, LEVEL_1, "Finished with Block %+F (%s %u)\n", block, cls->name, max_live));
 
        del_pset(live_nodes);
        return max_live;
@@ -91,7 +93,7 @@ static unsigned be_compute_loop_pressure(be_loopana_t *loop_ana, ir_loop *loop,
        unsigned       pressure;
        be_loop_info_t *entry, key;
 
-       DBG((loop_ana->dbg, LEVEL_1, "\nProcessing Loop %d\n", loop->loop_nr));
+       DBG((dbg, LEVEL_1, "\nProcessing Loop %d\n", loop->loop_nr));
        assert(get_loop_n_elements(loop) > 0);
        pressure = 0;
 
@@ -114,7 +116,7 @@ static unsigned be_compute_loop_pressure(be_loopana_t *loop_ana, ir_loop *loop,
 
                pressure = MAX(pressure, son_pressure);
        }
-       DBG((loop_ana->dbg, LEVEL_1, "Done with loop %d, pressure %u for class %s\n", loop->loop_nr, pressure, cls->name));
+       DBG((dbg, LEVEL_1, "Done with loop %d, pressure %u for class %s\n", loop->loop_nr, pressure, cls->name));
 
        /* update info in set */
        key.loop            = loop;
@@ -137,11 +139,10 @@ be_loopana_t *be_new_loop_pressure_cls(be_irg_t *birg, const arch_register_class
 
        loop_ana->data = new_set(cmp_loop_info, 16);
        loop_ana->birg = birg;
-       FIRM_DBG_REGISTER(loop_ana->dbg, "firm.be.loopana");
 
-       DBG((loop_ana->dbg, LEVEL_1, "\n=====================================================\n", cls->name));
-       DBG((loop_ana->dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
-       DBG((loop_ana->dbg, LEVEL_1, "=====================================================\n", cls->name));
+       DBG((dbg, LEVEL_1, "\n=====================================================\n", cls->name));
+       DBG((dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
+       DBG((dbg, LEVEL_1, "=====================================================\n", cls->name));
 
        be_compute_loop_pressure(loop_ana, get_irg_loop(birg->irg), cls);
 
@@ -160,13 +161,12 @@ be_loopana_t *be_new_loop_pressure(be_irg_t *birg) {
 
        loop_ana->data = new_set(cmp_loop_info, 16);
        loop_ana->birg = birg;
-       FIRM_DBG_REGISTER(loop_ana->dbg, "firm.be.loopana");
 
        for (i = arch_isa_get_n_reg_class(birg->main_env->arch_env->isa) - 1; i >= 0; --i) {
                const arch_register_class_t *cls = arch_isa_get_reg_class(birg->main_env->arch_env->isa, i);
-               DBG((loop_ana->dbg, LEVEL_1, "\n=====================================================\n", cls->name));
-               DBG((loop_ana->dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
-               DBG((loop_ana->dbg, LEVEL_1, "=====================================================\n", cls->name));
+               DBG((dbg, LEVEL_1, "\n=====================================================\n", cls->name));
+               DBG((dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
+               DBG((dbg, LEVEL_1, "=====================================================\n", cls->name));
                be_compute_loop_pressure(loop_ana, irg_loop, cls);
        }
 
@@ -202,3 +202,10 @@ void be_free_loop_pressure(be_loopana_t *loop_ana) {
        del_set(loop_ana->data);
        xfree(loop_ana);
 }
+
+void be_init_loopana(void)
+{
+       FIRM_DBG_REGISTER(dbg, "firm.be.loopana");
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_loopana);
index f4e271b..9ef56b7 100644 (file)
@@ -623,19 +623,16 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different,
  */
 static void assure_different_constraints(ir_node *irn, constraint_env_t *env) {
        const arch_register_req_t *req;
-       arch_register_req_t       req_temp;
 
-       req = arch_get_register_req(env->birg->main_env->arch_env, &req_temp, irn, -1);
+       req = arch_get_register_req(env->birg->main_env->arch_env, irn, -1);
 
-       if (req) {
-               if (arch_register_req_is(req, should_be_different)) {
-                       gen_assure_different_pattern(irn, req->other_different, env);
-               }
-               else if (arch_register_req_is(req, should_be_different_from_all)) {
-                       int i, n = get_irn_arity(belower_skip_proj(irn));
-                       for (i = 0; i < n; i++) {
-                               gen_assure_different_pattern(irn, get_irn_n(belower_skip_proj(irn), i), env);
-                       }
+       if (arch_register_req_is(req, should_be_different)) {
+               ir_node *different_from = get_irn_n(irn, req->other_different);
+               gen_assure_different_pattern(irn, different_from, env);
+       } else if (arch_register_req_is(req, should_be_different_from_all)) {
+               int i, n = get_irn_arity(belower_skip_proj(irn));
+               for (i = 0; i < n; i++) {
+                       gen_assure_different_pattern(irn, get_irn_n(belower_skip_proj(irn), i), env);
                }
        }
 }
index 2ff08c2..bd9be66 100644 (file)
@@ -6,7 +6,7 @@
  * CVS-Id:      $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif /* HAVE_CONFIG_H */
 
 #include <stdlib.h>
@@ -37,6 +37,10 @@ void be_init_spillbelady(void);
 void be_init_spillmorgan(void);
 void be_init_spillremat(void);
 void be_init_ifg(void);
+void be_init_irgmod(void);
+void be_init_loopana(void);
+void be_init_spillslots(void);
+void be_init_live(void);
 
 void be_quit_copystat(void);
 
@@ -52,6 +56,10 @@ void be_init_modules(void)
                return;
        run_once = 1;
 
+       be_init_irgmod();
+       be_init_loopana();
+       be_init_live();
+       be_init_spillslots();
        be_init_sched();
        be_init_blocksched();
        be_init_spill();
@@ -68,11 +76,9 @@ void be_init_modules(void)
        be_init_ifg();
 
        be_init_arch_ia32();
-#if 0
        be_init_arch_ppc32();
        be_init_arch_mips();
        be_init_arch_arm();
-#endif
 
 #ifdef WITH_ILP
        be_init_ilpsched();
index 03882ac..a189252 100644 (file)
@@ -24,6 +24,7 @@
 #include "fourcc.h"
 #include "offset.h"
 #include "bitfiddle.h"
+#include "raw_bitset.h"
 
 #include "irop_t.h"
 #include "irmode_t.h"
 
 static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O');
 
-typedef enum {
-       be_req_kind_old_limited,
-       be_req_kind_negate_old_limited,
-       be_req_kind_single_reg
-} be_req_kind_t;
-
 typedef struct {
        arch_register_req_t req;
-       be_req_kind_t       kind;
        arch_irn_flags_t    flags;
-       union {
-               struct {
-                       void (*old_limited)(void *ptr, bitset_t *bs);
-                       void *old_limited_env;
-               } old_limited;
-
-               const arch_register_t *single_reg;
-       } x;
 } be_req_t;
 
 typedef struct {
        const arch_register_t *reg;
-       be_req_t              req;
-       be_req_t              in_req;
+       be_req_t req;
+       be_req_t in_req;
 } be_reg_data_t;
 
 /** The generic be nodes attribute type. */
@@ -183,6 +169,33 @@ static int FrameAddr_cmp_attr(ir_node *a, ir_node *b) {
        return 1;
 }
 
+static INLINE be_req_t *get_be_req(const ir_node *node, int pos)
+{
+       int idx;
+       be_node_attr_t *attr;
+       be_reg_data_t *rd;
+
+       assert(is_be_node(node));
+       attr = get_irn_attr(node);
+
+       if(pos < 0) {
+               idx = -(pos + 1);
+       } else {
+               idx = pos;
+               assert(idx < get_irn_arity(node));
+       }
+       assert(idx < ARR_LEN(attr->reg_data));
+       rd = &attr->reg_data[idx];
+
+       return pos < 0 ? &rd->req : &rd->in_req;
+}
+
+static inline arch_register_req_t *get_req(const ir_node *node, int pos)
+{
+       be_req_t *bereq = get_be_req(node, pos);
+       return &bereq->req;
+}
+
 void be_node_init(void) {
        static int inited = 0;
 
@@ -303,51 +316,30 @@ static int redir_proj(const ir_node **node)
        return 0;
 }
 
-static be_node_attr_t *retrieve_irn_attr(const ir_node *irn, int *the_pos)
+static be_reg_data_t *retrieve_reg_data(const ir_node *node)
 {
-       int dummy;
-       be_node_attr_t *res = NULL;
-       int *pos = the_pos ? the_pos : &dummy;
-
-       *pos = -1;
-       if(is_Proj(irn)) {
-               ir_node *pred = get_Proj_pred(irn);
-               int p         = get_Proj_proj(irn);
+       be_node_attr_t *attr;
+       int pos = 0;
 
-               if(is_be_node(pred)) {
-                       assert(get_irn_mode(pred) == mode_T);
-                       *pos = p;
-                       res = get_irn_attr(pred);
-                       assert(p >= 0 && p < ARR_LEN(res->reg_data) && "illegal proj number");
-               }
-       } else if(is_be_node(irn) && get_irn_mode(irn) != mode_T) {
-               be_node_attr_t *a = get_irn_attr(irn);
-               if(ARR_LEN(a->reg_data) > 0) {
-                       res  = a;
-                       *pos = 0;
-               }
+       if(is_Proj(node)) {
+               pos = get_Proj_proj(node);
+               node = get_Proj_pred(node);
        }
 
-       return res;
-}
+       assert(is_be_node(node));
+       attr = get_irn_attr(node);
+       assert(pos >= 0 && pos < ARR_LEN(attr->reg_data) && "illegal proj number");
 
-static be_reg_data_t *retrieve_reg_data(const ir_node *irn)
-{
-       int pos;
-       be_node_attr_t *a = retrieve_irn_attr(irn, &pos);
-       return a ? &a->reg_data[pos] : NULL;
+       return &attr->reg_data[pos];
 }
 
 static void
 be_node_set_irn_reg(const void *_self, ir_node *irn, const arch_register_t *reg)
 {
        be_reg_data_t *r = retrieve_reg_data(irn);
-
-       if(r)
-               r->reg = reg;
+       r->reg = reg;
 }
 
-
 ir_node *be_new_Spill(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
        ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *to_spill)
 {
@@ -401,6 +393,7 @@ ir_node *be_get_Spill_val(const ir_node *irn)
        assert(be_is_Spill(irn));
        return get_irn_n(irn, be_pos_Spill_val);
 }
+
 ir_node *be_get_Spill_frame(const ir_node *irn)
 {
        assert(be_is_Spill(irn));
@@ -458,12 +451,19 @@ ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *b
 {
        ir_node *in[1];
        ir_node *res;
+       arch_register_req_t *req;
 
        in[0] = op;
        res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
        init_node_attr(res, 1);
        be_node_set_reg_class(res, 0, cls);
        be_node_set_reg_class(res, OUT_POS(0), cls);
+
+       req = get_req(res, OUT_POS(0));
+       req->cls = cls;
+       req->type = arch_register_req_type_should_be_same;
+       req->other_same = 0;
+
        return res;
 }
 
@@ -923,89 +923,61 @@ int be_get_MemPerm_entity_arity(const ir_node *irn)
        return get_irn_arity(irn) - 1;
 }
 
-static void be_limited(void *data, bitset_t *bs)
+void be_set_constr_single_reg(ir_node *node, int pos, const arch_register_t *reg)
 {
-       be_req_t *req = data;
-
-       switch(req->kind) {
-       case be_req_kind_negate_old_limited:
-       case be_req_kind_old_limited:
-               req->x.old_limited.old_limited(req->x.old_limited.old_limited_env, bs);
-               if(req->kind == be_req_kind_negate_old_limited)
-                       bitset_flip_all(bs);
-               break;
-       case be_req_kind_single_reg:
-               bitset_clear_all(bs);
-               bitset_set(bs, req->x.single_reg->index);
-               break;
-       }
-}
-
-static INLINE be_req_t *get_req(ir_node *irn, int pos)
-{
-       int idx           = pos < 0 ? -(pos + 1) : pos;
-       be_node_attr_t *a = get_irn_attr(irn);
-       be_reg_data_t *rd = &a->reg_data[idx];
-       be_req_t       *r = pos < 0 ? &rd->req : &rd->in_req;
-
-       assert(is_be_node(irn));
-       assert(!(pos >= 0) || pos < get_irn_arity(irn));
-       assert(!(pos < 0)  || -(pos + 1) <= ARR_LEN(a->reg_data));
+       arch_register_req_t *req = get_req(node, pos);
+       const arch_register_class_t *cls = arch_register_get_class(reg);
+       ir_graph *irg = get_irn_irg(node);
+       struct obstack *obst = get_irg_obstack(irg);
+       unsigned *limited_bitset;
 
-       return r;
-}
+       assert(req->cls == NULL || req->cls == cls);
+       assert(! (req->type & arch_register_req_type_limited));
+       assert(req->limited == NULL);
 
-void be_set_constr_single_reg(ir_node *irn, int pos, const arch_register_t *reg)
-{
-       be_req_t *r = get_req(irn, pos);
+       limited_bitset = rbitset_obstack_alloc(obst, arch_register_class_n_regs(cls));
+       rbitset_set(limited_bitset, arch_register_get_index(reg));
 
-       r->kind            = be_req_kind_single_reg;
-       r->x.single_reg    = reg;
-       r->req.limited     = be_limited;
-       r->req.limited_env = r;
-       r->req.type        = arch_register_req_type_limited;
-       r->req.cls         = reg->reg_class;
+       req->cls = cls;
+       req->type |= arch_register_req_type_limited;
+       req->limited = limited_bitset;
 }
 
-void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
+void be_set_constr_limited(ir_node *node, int pos, const arch_register_req_t *req)
 {
-       be_req_t *r = get_req(irn, pos);
+       ir_graph *irg = get_irn_irg(node);
+       struct obstack *obst = get_irg_obstack(irg);
+       arch_register_req_t *r = get_req(node, pos);
 
        assert(arch_register_req_is(req, limited));
-
-       r->kind            = be_req_kind_old_limited;
-       r->req.limited     = be_limited;
-       r->req.limited_env = r;
-       r->req.type        = arch_register_req_type_limited;
-       r->req.cls         = req->cls;
-
-       r->x.old_limited.old_limited     = req->limited;
-       r->x.old_limited.old_limited_env = req->limited_env;
+       assert(! (req->type & (arch_register_req_type_should_be_same | arch_register_req_type_should_be_different)));
+       memcpy(r, req, sizeof(r[0]));
+       r->limited = rbitset_duplicate_obstack_alloc(obst, req->limited, req->cls->n_regs);
 }
 
 void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
 {
-       be_req_t *r = get_req(irn, pos);
-       r->flags = flags;
+       be_req_t *bereq = get_be_req(irn, pos);
+       bereq->flags = flags;
 }
 
 void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls)
 {
-       be_req_t *r = get_req(irn, pos);
+       arch_register_req_t *req = get_req(irn, pos);
 
-       r->req.cls = cls;
+       req->cls = cls;
 
        if (cls == NULL) {
-               r->req.type = arch_register_req_type_none;
-       } else if (r->req.type == arch_register_req_type_none) {
-               r->req.type = arch_register_req_type_normal;
+               req->type = arch_register_req_type_none;
+       } else if (req->type == arch_register_req_type_none) {
+               req->type = arch_register_req_type_normal;
        }
 }
 
 void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type)
 {
-       be_req_t *r = get_req(irn, pos);
-       r->req.type = type;
+       arch_register_req_t *req = get_req(irn, pos);
+       req->type = type;
 }
 
 ir_node *be_get_IncSP_pred(ir_node *irn) {
@@ -1083,77 +1055,61 @@ ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls,
 */
 
 
-static void *put_out_reg_req(arch_register_req_t *req, const ir_node *irn, int out_pos)
+static const
+arch_register_req_t *get_out_reg_req(const ir_node *irn, int out_pos)
 {
        const be_node_attr_t *a = get_irn_attr(irn);
 
-       if(out_pos < ARR_LEN(a->reg_data)) {
-               memcpy(req, &a->reg_data[out_pos].req, sizeof(req[0]));
-
-               if(be_is_Copy(irn)) {
-                       req->type |= arch_register_req_type_should_be_same;
-                       req->other_same = be_get_Copy_op(irn);
-               }
-       } else {
-               req->type = arch_register_req_type_none;
-               req->cls  = NULL;
+       if(out_pos >= ARR_LEN(a->reg_data)) {
+               return arch_no_register_req;
        }
 
-       return req;
+       return &a->reg_data[out_pos].req.req;
 }
 
-static void *put_in_reg_req(arch_register_req_t *req, const ir_node *irn, int pos)
+static const
+arch_register_req_t *get_in_reg_req(const ir_node *irn, int pos)
 {
        const be_node_attr_t *a = get_irn_attr(irn);
 
-       if(pos < get_irn_arity(irn) && pos < ARR_LEN(a->reg_data)) {
-               memcpy(req, &a->reg_data[pos].in_req, sizeof(req[0]));
-       } else {
-               req->type = arch_register_req_type_none;
-               req->cls  = NULL;
-       }
+       if(pos >= get_irn_arity(irn) || pos >= ARR_LEN(a->reg_data))
+               return arch_no_register_req;
 
-       return req;
+       return &a->reg_data[pos].in_req.req;
 }
 
 static const arch_register_req_t *
-be_node_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
+be_node_get_irn_reg_req(const void *self, const ir_node *irn, int pos)
 {
        int out_pos = pos;
 
        if (pos < 0) {
                if (get_irn_mode(irn) == mode_T)
-                       return NULL;
+                       return arch_no_register_req;
 
                out_pos = redir_proj((const ir_node **)&irn);
                assert(is_be_node(irn));
-               return put_out_reg_req(req, irn, out_pos);
-       }
-
-       else {
-               if (is_be_node(irn)) {
-                       /*
-                               For spills and reloads, we return "none" as requirement for frame pointer,
-                               so every input is ok. Some backends need this (e.g. STA). We use an arbitrary
-                               large number as pos, so put_in_reg_req will return "none" as requirement.
-                       */
-                       if ((be_is_Spill(irn)  && pos == be_pos_Spill_frame) ||
+               return get_out_reg_req(irn, out_pos);
+       } else if (is_be_node(irn)) {
+               /*
+                * For spills and reloads, we return "none" as requirement for frame
+                * pointer, so every input is ok. Some backends need this (e.g. STA).
+                */
+               if ((be_is_Spill(irn)  && pos == be_pos_Spill_frame) ||
                                (be_is_Reload(irn) && pos == be_pos_Reload_frame))
-                               return put_in_reg_req(req, irn, INT_MAX);
-                       else
-                               return put_in_reg_req(req, irn, pos);
-               }
-               return NULL;
+                       return arch_no_register_req;
+
+               return get_in_reg_req(irn, pos);
        }
 
-       return req;
+       return arch_no_register_req;
 }
 
 const arch_register_t *
 be_node_get_irn_reg(const void *_self, const ir_node *irn)
 {
        be_reg_data_t *r = retrieve_reg_data(irn);
-       return r ? r->reg : NULL;
+       return r->reg;
 }
 
 static arch_irn_class_t be_node_classify(const void *_self, const ir_node *irn)
@@ -1176,10 +1132,19 @@ static arch_irn_class_t be_node_classify(const void *_self, const ir_node *irn)
        return 0;
 }
 
-static arch_irn_flags_t be_node_get_flags(const void *_self, const ir_node *irn)
+static arch_irn_flags_t be_node_get_flags(const void *_self, const ir_node *node)
 {
-       be_reg_data_t *r = retrieve_reg_data(irn);
-       return r ? r->req.flags : 0;
+       be_req_t *bereq;
+       int pos = -1;
+
+       if(is_Proj(node)) {
+               pos = OUT_POS(get_Proj_proj(node));
+               node = skip_Proj_const(node);
+       }
+
+       bereq = get_be_req(node, pos);
+
+       return bereq->flags;
 }
 
 static ir_entity *be_node_get_frame_entity(const void *self, const ir_node *irn)
@@ -1258,11 +1223,16 @@ const arch_irn_handler_t be_node_irn_handler = {
 
 */
 
+typedef struct {
+       const arch_register_t *reg;
+       arch_register_req_t req;
+} phi_attr_t;
+
 typedef struct {
        arch_irn_handler_t irn_handler;
        arch_irn_ops_t     irn_ops;
        const arch_env_t   *arch_env;
-       pmap               *regs;
+       pmap               *phi_attrs;
 } phi_handler_t;
 
 #define get_phi_handler_from_handler(h)  container_of(h, phi_handler_t, irn_handler)
@@ -1274,11 +1244,28 @@ static const void *phi_get_irn_ops(const arch_irn_handler_t *handler, const ir_n
        return is_Phi(irn) && mode_is_datab(get_irn_mode(irn)) ? &h->irn_ops : NULL;
 }
 
+static INLINE phi_attr_t *get_Phi_attr(const phi_handler_t *handler,
+                                       const ir_node *phi)
+{
+       phi_attr_t *attr = pmap_get(handler->phi_attrs, (void*) phi);
+       if(attr == NULL) {
+               ir_graph *irg = get_irn_irg(phi);
+               struct obstack *obst = get_irg_obstack(irg);
+               attr = obstack_alloc(obst, sizeof(attr[0]));
+               memset(attr, 0, sizeof(attr[0]));
+               pmap_insert(handler->phi_attrs, phi, attr);
+       }
+
+       return attr;
+}
+
 /**
  * Get register class of a Phi.
- *
  */
-static const arch_register_req_t *get_Phi_reg_req_recursive(const phi_handler_t *h, arch_register_req_t *req, const ir_node *phi, pset **visited)
+static
+const arch_register_req_t *get_Phi_reg_req_recursive(const phi_handler_t *h,
+                                                     const ir_node *phi,
+                                                     pset **visited)
 {
        int n = get_irn_arity(phi);
        ir_node *op;
@@ -1289,52 +1276,72 @@ static const arch_register_req_t *get_Phi_reg_req_recursive(const phi_handler_t
 
        for(i = 0; i < n; ++i) {
                op = get_irn_n(phi, i);
+               /* Matze: don't we unnecessary constraint our phis with this?
+                * we only need to take the regclass IMO*/
                if(!is_Phi(op))
-                       return arch_get_register_req(h->arch_env, req, op, BE_OUT_POS(0));
+                       return arch_get_register_req(h->arch_env, op, BE_OUT_POS(0));
        }
 
        /*
-       The operands of that Phi were all Phis themselves.
-       We have to start a DFS for a non-Phi argument now.
-       */
+        * The operands of that Phi were all Phis themselves.
+        * We have to start a DFS for a non-Phi argument now.
+        */
        if(!*visited)
                *visited = pset_new_ptr(16);
 
        pset_insert_ptr(*visited, phi);
 
        for(i = 0; i < n; ++i) {
+               const arch_register_req_t *req;
                op = get_irn_n(phi, i);
-               if(get_Phi_reg_req_recursive(h, req, op, visited))
+               req = get_Phi_reg_req_recursive(h, op, visited);
+               if(req != NULL)
                        return req;
        }
 
        return NULL;
 }
 
-static const arch_register_req_t *phi_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
+static
+const arch_register_req_t *phi_get_irn_reg_req(const void *self,
+                                               const ir_node *irn, int pos)
 {
        phi_handler_t *phi_handler = get_phi_handler_from_ops(self);
-       pset *visited              = NULL;
+       phi_attr_t *attr;
+
+       if(!mode_is_datab(get_irn_mode(irn)))
+               return arch_no_register_req;
+
+       attr = get_Phi_attr(phi_handler, irn);
 
-       get_Phi_reg_req_recursive(phi_handler, req, irn, &visited);
-       /* Set the requirements type to normal, since an operand of the Phi could have had constraints. */
-       req->type = arch_register_req_type_normal;
-       if(visited)
-               del_pset(visited);
+       if(attr->req.type == arch_register_req_type_none) {
+               pset *visited = NULL;
+               const arch_register_req_t *req;
+               req = get_Phi_reg_req_recursive(phi_handler, irn, &visited);
 
-       return req;
+               memcpy(&attr->req, req, sizeof(req[0]));
+               assert(attr->req.cls != NULL);
+               attr->req.type = arch_register_req_type_normal;
+
+               if(visited != NULL)
+                       del_pset(visited);
+       }
+
+       return &attr->req;
 }
 
 static void phi_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
 {
        phi_handler_t *h = get_phi_handler_from_ops(self);
-       pmap_insert(h->regs, irn, (void *) reg);
+       phi_attr_t *attr = get_Phi_attr(h, irn);
+       attr->reg = reg;
 }
 
 static const arch_register_t *phi_get_irn_reg(const void *self, const ir_node *irn)
 {
        phi_handler_t *h = get_phi_handler_from_ops(self);
-       return pmap_get(h->regs, (void *) irn);
+       phi_attr_t *attr = get_Phi_attr(h, irn);
+       return attr->reg;
 }
 
 static arch_irn_class_t phi_classify(const void *_self, const ir_node *irn)
@@ -1391,14 +1398,14 @@ arch_irn_handler_t *be_phi_handler_new(const arch_env_t *arch_env)
        h->irn_handler.get_irn_ops = phi_get_irn_ops;
        h->irn_ops.impl            = &phi_irn_ops;
        h->arch_env                = arch_env;
-       h->regs                    = pmap_create();
+       h->phi_attrs               = pmap_create();
        return (arch_irn_handler_t *) h;
 }
 
 void be_phi_handler_free(arch_irn_handler_t *handler)
 {
        phi_handler_t *h = (void *) handler;
-       pmap_destroy(h->regs);
+       pmap_destroy(h->phi_attrs);
        free(handler);
 }
 
@@ -1411,9 +1418,9 @@ const void *be_phi_get_irn_ops(const arch_irn_handler_t *self, const ir_node *ir
 void be_phi_handler_reset(arch_irn_handler_t *handler)
 {
        phi_handler_t *h = get_phi_handler_from_handler(handler);
-       if(h->regs)
-               pmap_destroy(h->regs);
-       h->regs = pmap_create();
+       if(h->phi_attrs)
+               pmap_destroy(h->phi_attrs);
+       h->phi_attrs = pmap_create();
 }
 
 /*
@@ -1428,9 +1435,9 @@ void be_phi_handler_reset(arch_irn_handler_t *handler)
 /**
  * Dumps a register requirement to a file.
  */
-static void dump_node_req(FILE *f, int idx, be_req_t *req)
+static void dump_node_req(FILE *f, int idx, const arch_register_req_t *req,
+                          const ir_node *node)
 {
-       unsigned i;
        int did_something = 0;
        char buf[16];
        const char *prefix = buf;
@@ -1438,23 +1445,10 @@ static void dump_node_req(FILE *f, int idx, be_req_t *req)
        snprintf(buf, sizeof(buf), "#%d ", idx);
        buf[sizeof(buf) - 1] = '\0';
 
-       if(req->flags != arch_irn_flags_none) {
-               fprintf(f, "%sflags: ", prefix);
-               prefix = "";
-               for(i = arch_irn_flags_none; i <= log2_ceil(arch_irn_flags_last); ++i) {
-                       if(req->flags & (1 << i)) {
-                               fprintf(f, "%s%s", prefix, arch_irn_flag_str(1 << i));
-                               prefix = "|";
-                       }
-               }
-               prefix = ", ";
-               did_something = 1;
-       }
-
-       if(req->req.cls != 0) {
+       if(req->cls != 0) {
                char tmp[256];
                fprintf(f, prefix);
-               arch_register_req_format(tmp, sizeof(tmp), &req->req);
+               arch_register_req_format(tmp, sizeof(tmp), req, node);
                fprintf(f, "%s", tmp);
                did_something = 1;
        }
@@ -1466,10 +1460,10 @@ static void dump_node_req(FILE *f, int idx, be_req_t *req)
 /**
  * Dumps node register requirements to a file.
  */
-static void dump_node_reqs(FILE *f, ir_node *irn)
+static void dump_node_reqs(FILE *f, ir_node *node)
 {
        int i;
-       be_node_attr_t *a = get_irn_attr(irn);
+       be_node_attr_t *a = get_irn_attr(node);
        int len = ARR_LEN(a->reg_data);
 
        fprintf(f, "registers: \n");
@@ -1479,14 +1473,14 @@ static void dump_node_reqs(FILE *f, ir_node *irn)
                        fprintf(f, "#%d: %s\n", i, rd->reg->name);
        }
 
-       fprintf(f, "in requirements\n");
+       fprintf(f, "in requirements:\n");
        for(i = 0; i < len; ++i) {
-               dump_node_req(f, i, &a->reg_data[i].in_req);
+               dump_node_req(f, i, &a->reg_data[i].in_req.req, node);
        }
 
-       fprintf(f, "\nout requirements\n");
+       fprintf(f, "\nout requirements:\n");
        for(i = 0; i < len; ++i) {
-               dump_node_req(f, i, &a->reg_data[i].req);
+               dump_node_req(f, i, &a->reg_data[i].req.req, node);
        }
 }
 
@@ -1575,7 +1569,7 @@ static void copy_attr(const ir_node *old_node, ir_node *new_node)
        be_node_attr_t *old_attr = get_irn_attr(old_node);
        be_node_attr_t *new_attr = get_irn_attr(new_node);
        struct obstack *obst = get_irg_obstack(get_irn_irg(new_node));
-       int i, len;
+       unsigned i, len;
 
        assert(is_be_node(old_node));
        assert(is_be_node(new_node));
@@ -1588,7 +1582,8 @@ static void copy_attr(const ir_node *old_node, ir_node *new_node)
        else
                len = 0;
 
-       if(be_is_Keep(old_node) || be_is_RegParams(old_node) || be_is_Barrier(old_node)) {
+       if(get_irn_op(old_node)->opar == oparity_dynamic
+                       || be_is_RegParams(old_node)) {
                new_attr->reg_data = NEW_ARR_F(be_reg_data_t, len);
        } else {
                new_attr->reg_data = NEW_ARR_D(be_reg_data_t, obst, len);
@@ -1596,15 +1591,21 @@ static void copy_attr(const ir_node *old_node, ir_node *new_node)
 
        if(len > 0) {
                memcpy(new_attr->reg_data, old_attr->reg_data, len * sizeof(be_reg_data_t));
-
                for(i = 0; i < len; ++i) {
-                       be_req_t *r;
-
-                       r = &new_attr->reg_data[i].req;
-                       r->req.limited_env = r;
-
-                       r = &new_attr->reg_data[i].in_req;
-                       r->req.limited_env = r;
+                       const be_reg_data_t *rd = &old_attr->reg_data[i];
+                       be_reg_data_t *newrd = &new_attr->reg_data[i];
+                       if(arch_register_req_is(&rd->req.req, limited)) {
+                               const arch_register_req_t *req = &rd->req.req;
+                               arch_register_req_t *new_req = &newrd->req.req;
+                               new_req->limited
+                                       = rbitset_duplicate_obstack_alloc(obst, req->limited, req->cls->n_regs);
+                       }
+                       if(arch_register_req_is(&rd->in_req.req, limited)) {
+                               const arch_register_req_t *req = &rd->in_req.req;
+                               arch_register_req_t *new_req = &newrd->in_req.req;
+                               new_req->limited
+                                       = rbitset_duplicate_obstack_alloc(obst, req->limited, req->cls->n_regs);
+                       }
                }
        }
 }
index b70cc2d..d10e455 100644 (file)
@@ -75,6 +75,7 @@ alloc         ::= node-nr reg-nr .
 #include "pset.h"
 #include "pmap.h"
 #include "bitset.h"
+#include "raw_bitset.h"
 
 #include "irprintf_t.h"
 #include "irnode_t.h"
@@ -202,7 +203,7 @@ static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn)
                be_operand_t *op = &insn->ops[i];
 
                if(op->has_constraints) {
-                       ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier);
+                       ir_node *cpy = be_new_Copy(op->req->cls, env->irg, bl, op->carrier);
                        sched_add_before(insn->next_insn, cpy);
                        edges_reroute(op->carrier, cpy, env->irg);
                }
@@ -212,10 +213,10 @@ static void handle_constraints_insn(be_raext_env_t *env, be_insn_t *insn)
                be_operand_t *op = &insn->ops[i];
 
                if(op->has_constraints) {
-                       ir_node *cpy = be_new_Copy(op->req.cls, env->irg, bl, op->carrier);
+                       ir_node *cpy = be_new_Copy(op->req->cls, env->irg, bl, op->carrier);
                        sched_add_before(insn->irn, cpy);
                        set_irn_n(insn->irn, op->pos, cpy);
-                       be_set_constr_limited(cpy, BE_OUT_POS(0), &op->req);
+                       be_set_constr_limited(cpy, BE_OUT_POS(0), op->req);
                }
        }
 }
@@ -292,16 +293,16 @@ static void extract_vars_of_cls(be_raext_env_t *raenv) {
  * If yes, dump it to FILE raenv->f
  */
 static INLINE void dump_constraint(be_raext_env_t *raenv, ir_node *irn, int pos) {
-       bitset_t *bs = bitset_alloca(raenv->cls->n_regs);
-       arch_register_req_t req;
-
-       arch_get_register_req(raenv->aenv, &req, irn, pos);
-       if (arch_register_req_is(&req, limited)) {
-               int reg_nr;
-               req.limited(req.limited_env, bs);
-               reg_nr = bitset_next_set(bs, 0);
+       const arch_register_req_t *req;
+
+       req = arch_get_register_req(raenv->aenv, irn, pos);
+       if (arch_register_req_is(req, limited)) {
+               unsigned reg_nr;
+
+               reg_nr = rbitset_next(req->limited, 0, 1);
                fprintf(raenv->f, "<%d>", reg_nr);
-               assert(-1 == bitset_next_set(bs, reg_nr+1) && "Constraints with more than 1 possible register are not supported");
+               assert(rbitset_popcnt(req->limited, raenv->cls->n_regs) <= 1
+                               && "Constraints with more than 1 possible register are not supported");
        }
 }
 
@@ -392,7 +393,7 @@ NextVar: ;
 
 static void dump_affinities_walker(ir_node *irn, void *env) {
        be_raext_env_t *raenv = env;
-       arch_register_req_t req;
+       const arch_register_req_t *req;
        int pos, max;
        be_var_info_t *vi1, *vi2;
 
@@ -415,12 +416,15 @@ static void dump_affinities_walker(ir_node *irn, void *env) {
 
        /* should_be_equal constraints are affinites */
        for (pos = 0, max = get_irn_arity(irn); pos<max; ++pos) {
-               arch_get_register_req(raenv->aenv, &req, irn, pos);
+               req = arch_get_register_req(raenv->aenv, irn, pos);
 
-               if (arch_register_req_is(&req, should_be_same) && arch_irn_is(raenv->aenv, req.other_same, ignore)) {
-                       vi2 = be_get_var_info(req.other_same);
+               if (arch_register_req_is(req, should_be_same)) {
+                       ir_node *other = get_irn_n(irn, req->other_same);
+                       if(arch_irn_is(raenv->aenv, other, ignore)) {
+                               vi2 = be_get_var_info(other);
 
-                       fprintf(raenv->f, "(%d, %d, %d)\n",  vi1->var_nr, vi2->var_nr, get_affinity_weight(irn));
+                               fprintf(raenv->f, "(%d, %d, %d)\n",  vi1->var_nr, vi2->var_nr, get_affinity_weight(irn));
+                       }
                }
        }
 }
index 15519a3..028d17b 100644 (file)
@@ -357,14 +357,13 @@ static loc_t to_take_or_not_to_take(belady_env_t *env, ir_node* first,
        be_next_use_t next_use;
        loc_t loc;
        loc.time = USES_INFINITY;
+       loc.irn = node;
 
        if (!arch_irn_consider_in_reg_alloc(env->arch, env->cls, node)) {
                loc.time = USES_INFINITY;
                return loc;
        }
 
-       loc.irn = node;
-
        /* We have to keep nonspillable nodes in the workingset */
        if(arch_irn_get_flags(env->arch, node) & arch_irn_flags_dont_spill) {
                loc.time = 0;
@@ -671,9 +670,6 @@ void be_spill_belady_spill_env(be_irg_t *birg, const arch_register_class_t *cls,
        belady_env_t env;
        ir_graph *irg = be_get_birg_irg(birg);
 
-       FIRM_DBG_REGISTER(dbg, "firm.be.spill.belady");
-       //firm_dbg_set_mask(dbg, DBG_SPILL);
-
        be_invalidate_liveness(birg);
        be_assure_liveness(birg);
        /* construct control flow loop tree */
@@ -722,6 +718,7 @@ void be_init_spillbelady(void)
        };
 
        be_register_spiller("belady", &belady_spiller);
+       FIRM_DBG_REGISTER(dbg, "firm.be.spill.belady");
 }
 
 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillbelady);
index a629a9f..204cafa 100644 (file)
@@ -6,7 +6,7 @@
  *
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "bespillmorgan.h"
@@ -544,9 +544,6 @@ void be_spill_morgan(be_irg_t *birg, const arch_register_class_t *cls) {
        ir_graph *irg = be_get_birg_irg(birg);
        morgan_env_t env;
 
-       FIRM_DBG_REGISTER(dbg, "ir.be.spillmorgan");
-       //firm_dbg_set_mask(dbg, DBG_SPILLS | DBG_LOOPANA);
-
        be_assure_liveness(birg);
 
        env.arch = birg->main_env->arch_env;
@@ -610,6 +607,7 @@ void be_init_spillmorgan(void)
        };
 
        be_register_spiller("morgan", &morgan_spiller);
+       FIRM_DBG_REGISTER(dbg, "ir.be.spillmorgan");
 }
 
 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillmorgan);
index 13f58f8..b35ae8e 100644 (file)
 #define REMATS_NOINVERSE   2
 #define REMATS_ALL         3
 
-static int opt_dump_flags   = 0;
+static unsigned opt_dump_flags = 0;
 static int opt_log = 0;
-static int opt_keep_alive   = 0;
+static unsigned opt_keep_alive = 0;
 static int opt_goodwin = 1;
 static int opt_memcopies = 1;
 static int opt_memoperands = 1;
 static int opt_verify = VERIFY_MEMINTERF;
-static int opt_remats = REMATS_ALL;
+static unsigned opt_remats = REMATS_ALL;
 static int opt_repair_schedule = 0;
 static int opt_no_enlarge_liveness = 0;
 static int opt_remat_while_live = 1;
@@ -1909,7 +1909,7 @@ luke_blockwalker(ir_node * bb, void * data)
                pset       *used;
                pset       *remat_defs;
                keyval_t   *keyval;
-               ilp_cst_t   one_memoperand;
+               ilp_cst_t   one_memoperand = -1;
 
                /* iterate only until first phi */
                if(is_Phi(irn))
index 2b3ece6..955b5dc 100644 (file)
@@ -28,6 +28,7 @@
 #include "benodesets.h"
 #include "bestatevent.h"
 #include "bespilloptions.h"
+#include "bemodule.h"
 
 #define DBG_COALESCING         1
 #define DBG_INTERFERENCES      2
@@ -640,7 +641,6 @@ be_fec_env_t *be_new_frame_entity_coalescer(be_irg_t *birg)
        env->reloads = NEW_ARR_F(ir_node*, 0);
        env->affinity_edges = NEW_ARR_F(affinity_edge_t*, 0);
        env->memperms = new_set(cmp_memperm, 10);
-       FIRM_DBG_REGISTER(dbg, "firm.be.spillslots");
 
        return env;
 }
@@ -714,3 +714,10 @@ void be_coalesce_spillslots(be_irg_t *birg)
 
        be_free_frame_entity_coalescer(env);
 }
+
+void be_init_spillslots(void)
+{
+       FIRM_DBG_REGISTER(dbg, "firm.be.spillslots");
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillslots);
index 8b3fc01..1821838 100644 (file)
@@ -5,9 +5,8 @@
  * @date   11.9.2006
  * @cvsid  $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-# include "config.h"
+# include <config.h>
 #endif
 
 #include <stdio.h>
index bdb9875..f511839 100644 (file)
@@ -9,7 +9,7 @@
  * Released under the GPL
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <limits.h>
index 9275b29..9ddbde1 100644 (file)
 #include "../beilpsched.h"
 #include "../bespillslots.h"
 #include "../bemodule.h"
+#include "../begnuas.h"
 
 #include "bearch_ia32_t.h"
 
 #include "ia32_new_nodes.h"           /* ia32 nodes interface */
 #include "gen_ia32_regalloc_if.h"     /* the generated interface (register type and class defenitions) */
 #include "gen_ia32_machine.h"
-#include "ia32_gen_decls.h"           /* interface declaration emitter */
 #include "ia32_transform.h"
 #include "ia32_emitter.h"
 #include "ia32_map_regs.h"
@@ -62,8 +62,6 @@
 #include "ia32_finish.h"
 #include "ia32_util.h"
 
-#define DEBUG_MODULE "firm.be.ia32.isa"
-
 /* TODO: ugly */
 static set *cur_reg_set = NULL;
 
@@ -140,15 +138,14 @@ ir_node *ia32_new_Unknown_xmm(ia32_code_gen_t *cg) {
  * Returns gp_noreg or fp_noreg, depending in input requirements.
  */
 ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int pos) {
-       arch_register_req_t       req;
-       const arch_register_req_t *p_req;
+       const arch_register_req_t *req;
 
-       p_req = arch_get_register_req(cg->arch_env, &req, irn, pos);
-       assert(p_req && "Missing register requirements");
-       if (p_req->cls == &ia32_reg_classes[CLASS_ia32_gp])
+       req = arch_get_register_req(cg->arch_env, irn, pos);
+       assert(req != NULL && "Missing register requirements");
+       if (req->cls == &ia32_reg_classes[CLASS_ia32_gp])
                return ia32_new_NoReg_gp(cg);
-       else
-               return ia32_new_NoReg_fp(cg);
+
+       return ia32_new_NoReg_fp(cg);
 }
 
 /**************************************************
@@ -167,99 +164,57 @@ ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int pos) {
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
-       const ia32_irn_ops_t      *ops = self;
-       const ia32_register_req_t *irn_req;
-       long                       node_pos = pos == -1 ? 0 : pos;
-       ir_mode                   *mode     = is_Block(irn) ? NULL : get_irn_mode(irn);
-       FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
-
-       if (is_Block(irn) || mode == mode_X) {
-               DBG((mod, LEVEL_1, "ignoring Block, mode_M, mode_X node %+F\n", irn));
-               return NULL;
+static const arch_register_req_t *ia32_get_irn_reg_req(const void *self,
+                                                       const ir_node *node,
+                                                                                                          int pos) {
+       long node_pos = pos == -1 ? 0 : pos;
+       ir_mode *mode     = is_Block(node) ? NULL : get_irn_mode(node);
+
+       if (is_Block(node) || mode == mode_X) {
+               return arch_no_register_req;
        }
 
        if (mode == mode_T && pos < 0) {
-               DBG((mod, LEVEL_1, "ignoring request OUT requirements for node %+F\n", irn));
-               return NULL;
+               return arch_no_register_req;
        }
 
-       DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
-
-       if (is_Proj(irn)) {
+       if (is_Proj(node)) {
                if(mode == mode_M)
-                       return NULL;
+                       return arch_no_register_req;
 
                if(pos >= 0) {
-                       DBG((mod, LEVEL_1, "ignoring request IN requirements for node %+F\n", irn));
-                       return NULL;
+                       return arch_no_register_req;
                }
 
-               node_pos = (pos == -1) ? get_Proj_proj(irn) : pos;
-               irn      = skip_Proj_const(irn);
-
-               DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
+               node_pos = (pos == -1) ? get_Proj_proj(node) : pos;
+               node     = skip_Proj_const(node);
        }
 
-       if (is_ia32_irn(irn)) {
-               irn_req = (pos >= 0) ? get_ia32_in_req(irn, pos) : get_ia32_out_req(irn, node_pos);
-               if (irn_req == NULL) {
-                       /* no requirements */
-                       return NULL;
-               }
-
-               DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
-
-               memcpy(req, &(irn_req->req), sizeof(*req));
+       if (is_ia32_irn(node)) {
+               const arch_register_req_t *req;
+               if(pos >= 0)
+                       req = get_ia32_in_req(node, pos);
+               else
+                       req = get_ia32_out_req(node, node_pos);
 
-               if (arch_register_req_is(&(irn_req->req), should_be_same)) {
-                       assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
-                       req->other_same = get_irn_n(irn, irn_req->same_pos);
-               }
+               assert(req != NULL);
 
-               if (arch_register_req_is(&(irn_req->req), should_be_different)) {
-                       assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
-                       req->other_different = get_irn_n(irn, irn_req->different_pos);
-               }
-       }
-       else {
-               /* treat Unknowns like Const with default requirements */
-               if (is_Unknown(irn)) {
-                       DB((mod, LEVEL_1, "returning UKNWN reqs for %+F\n", irn));
-                       if (mode_is_float(mode)) {
-                               if (USE_SSE2(ops->cg))
-                                       memcpy(req, &(ia32_default_req_ia32_xmm_xmm_UKNWN), sizeof(*req));
-                               else
-                                       memcpy(req, &(ia32_default_req_ia32_vfp_vfp_UKNWN), sizeof(*req));
-                       }
-                       else if (mode_is_int(mode) || mode_is_reference(mode))
-                               memcpy(req, &(ia32_default_req_ia32_gp_gp_UKNWN), sizeof(*req));
-                       else if (mode == mode_T || mode == mode_M) {
-                               DBG((mod, LEVEL_1, "ignoring Unknown node %+F\n", irn));
-                               return NULL;
-                       }
-                       else
-                               assert(0 && "unsupported Unknown-Mode");
-               }
-               else {
-                       DB((mod, LEVEL_1, "returning NULL for %+F (not ia32)\n", irn));
-                       req = NULL;
-               }
+               return req;
        }
 
-       return req;
+       /* unknowns should be transformed already */
+       assert(!is_Unknown(node));
+
+       return arch_no_register_req;
 }
 
 static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
        int                   pos = 0;
-       const ia32_irn_ops_t *ops = self;
 
        if (get_irn_mode(irn) == mode_X) {
                return;
        }
 
-       DBG((ops->cg->mod, LEVEL_1, "ia32 assigned register %s to node %+F\n", reg->name, irn));
-
        if (is_Proj(irn)) {
                pos = get_Proj_proj(irn);
                irn = skip_Proj(irn);
@@ -270,8 +225,7 @@ static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register
 
                slots      = get_ia32_slots(irn);
                slots[pos] = reg;
-       }
-       else {
+       } else {
                ia32_set_firm_reg(irn, reg, cur_reg_set);
        }
 }
@@ -294,8 +248,7 @@ static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *
                const arch_register_t **slots;
                slots = get_ia32_slots(irn);
                reg   = slots[pos];
-       }
-       else {
+       } else {
                reg = ia32_get_firm_reg(irn, cur_reg_set);
        }
 
@@ -385,8 +338,6 @@ static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
                        }
                }
 
-               DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias));
-
                am_flav  = get_ia32_am_flavour(irn);
                am_flav |= ia32_O;
                set_ia32_am_flavour(irn, am_flav);
@@ -1541,7 +1492,7 @@ static void ia32_codegen(void *self) {
        ia32_code_gen_t *cg = self;
        ir_graph        *irg = cg->irg;
 
-       ia32_gen_routine(cg, cg->isa->out, irg);
+       ia32_gen_routine(cg, irg);
 
        cur_reg_set = NULL;
 
@@ -1660,6 +1611,7 @@ static ia32_isa_t ia32_isa_template = {
                -1,                      /* stack direction */
                NULL,                    /* main environment */
        },
+       {},                      /* emitter environment */
        NULL,                    /* 16bit register names */
        NULL,                    /* 8bit register names */
        NULL,                    /* types */
@@ -1675,7 +1627,6 @@ static ia32_isa_t ia32_isa_template = {
        arch_pentium_4,          /* optimize for architecture */
        fp_sse2,                 /* use sse2 unit */
        NULL,                    /* current code generator */
-       NULL,                    /* output file */
 #ifndef NDEBUG
        NULL,                    /* name obstack */
        0                        /* name obst size */
@@ -1711,11 +1662,11 @@ static void *ia32_init(FILE *file_handle) {
                isa->opt &= ~IA32_OPT_INCDEC;
        }
 
+       be_emit_init_env(&isa->emit, file_handle);
        isa->regs_16bit = pmap_create();
        isa->regs_8bit  = pmap_create();
        isa->types      = pmap_create();
        isa->tv_ent     = pmap_create();
-       isa->out        = file_handle;
        isa->cpu        = ia32_init_machine_description();
 
        ia32_build_16bit_reg_map(isa->regs_16bit);
@@ -1737,11 +1688,11 @@ static void *ia32_init(FILE *file_handle) {
 #endif /* NDEBUG */
 
        ia32_handle_intrinsics();
-       ia32_switch_section(isa->out, NO_SECTION);
 
        /* needed for the debug support */
-       ia32_switch_section(isa->out, SECTION_TEXT);
-       fprintf(isa->out, ".Ltext0:\n");
+       be_gas_emit_switch_section(&isa->emit, GAS_SECTION_TEXT);
+       be_emit_cstring(&isa->emit, ".Ltext0:\n");
+       be_emit_write_line(&isa->emit);
 
        inited = 1;
 
@@ -1757,7 +1708,7 @@ static void ia32_done(void *self) {
        ia32_isa_t *isa = self;
 
        /* emit now all global declarations */
-       ia32_gen_decls(isa->out, isa->arch_isa.main_env);
+       be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env);
 
        pmap_destroy(isa->regs_16bit);
        pmap_destroy(isa->regs_8bit);
@@ -1768,6 +1719,8 @@ static void ia32_done(void *self) {
        obstack_free(isa->name_obst, NULL);
 #endif /* NDEBUG */
 
+       be_emit_destroy_env(&isa->emit);
+
        free(self);
 }
 
@@ -2162,13 +2115,13 @@ static lc_opt_enum_int_var_t fp_unit_var = {
 };
 
 static const lc_opt_enum_int_items_t gas_items[] = {
-       { "linux",   ASM_LINUX_GAS },
-       { "mingw",   ASM_MINGW_GAS },
+       { "normal",  GAS_FLAVOUR_NORMAL },
+       { "mingw",   GAS_FLAVOUR_MINGW  },
        { NULL,      0 }
 };
 
 static lc_opt_enum_int_var_t gas_var = {
-       (int *)&asm_flavour, gas_items
+       (int*) &be_gas_flavour, gas_items
 };
 
 static const lc_opt_table_entry_t ia32_options[] = {
index a44ee91..a67cc18 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "../be.h"
 #include "../bemachine.h"
+#include "../beemitter.h"
 
 #ifdef NDEBUG
 #define SET_IA32_ORIG_NODE(n, o)
@@ -123,6 +124,7 @@ typedef struct _ia32_code_gen_t {
  */
 struct _ia32_isa_t {
        arch_isa_t            arch_isa;       /**< must be derived from arch_isa_t */
+       be_emit_env_t          emit;
        pmap                  *regs_16bit;    /**< Contains the 16bits names of the gp registers */
        pmap                  *regs_8bit;     /**< Contains the 8bits names of the gp registers */
        pmap                  *types;         /**< A map of modes to primitive types */
@@ -132,7 +134,6 @@ struct _ia32_isa_t {
        int                   opt_arch;       /**< optimize for architecture */
        int                   fp_kind;        /**< floating point kind */
        ia32_code_gen_t       *cg;            /**< the current code generator */
-       FILE                  *out;           /**< output file */
        const be_machine_t    *cpu;           /**< the abstract machine */
 #ifndef NDEBUG
        struct obstack        *name_obst;     /**< holds the original node names (for debugging) */
index 49be5d4..e3f89eb 100644 (file)
 #include "iredges_t.h"
 #include "execfreq.h"
 #include "error.h"
+#include "raw_bitset.h"
 
 #include "../besched_t.h"
 #include "../benode_t.h"
 #include "../beabi.h"
 #include "../be_dbgout.h"
+#include "../beemitter.h"
+#include "../begnuas.h"
 
 #include "ia32_emitter.h"
 #include "gen_ia32_emitter.h"
 /* global arch_env for lc_printf functions */
 static const arch_env_t *arch_env = NULL;
 
-/** by default, we generate assembler code for the Linux gas */
-asm_flavour_t asm_flavour = ASM_LINUX_GAS;
-
-/**
- * Switch to a new section
- */
-void ia32_switch_section(FILE *F, section_t sec) {
-       static section_t curr_sec = NO_SECTION;
-       static const char *text[ASM_MAX][SECTION_MAX] = {
-               {
-                       ".section\t.text",
-                       ".section\t.data",
-                       ".section\t.rodata",
-                       ".section\t.bss",
-                       ".section\t.tbss,\"awT\",@nobits",
-                       ".section\t.ctors,\"aw\",@progbits"
-               },
-               {
-                       ".section\t.text",
-                       ".section\t.data",
-                       ".section .rdata,\"dr\"",
-                       ".section\t.bss",
-                       ".section\t.tbss,\"awT\",@nobits",
-                       ".section\t.ctors,\"aw\",@progbits"
-               }
-       };
-
-       if (curr_sec == sec)
-               return;
-
-       curr_sec = sec;
-       switch (sec) {
-
-       case NO_SECTION:
-               break;
-
-       case SECTION_TEXT:
-       case SECTION_DATA:
-       case SECTION_RODATA:
-       case SECTION_COMMON:
-       case SECTION_TLS:
-       case SECTION_CTOR:
-               fprintf(F, "\t%s\n", text[asm_flavour][sec]);
-               break;
-
-       default:
-               break;
-       }
-}
-
-static void ia32_dump_function_object(FILE *F, const char *name)
-{
-       switch (asm_flavour) {
-       case ASM_LINUX_GAS:
-               fprintf(F, "\t.type\t%s, @function\n", name);
-               break;
-       case ASM_MINGW_GAS:
-               fprintf(F, "\t.def\t%s;\t.scl\t2;\t.type\t32;\t.endef\n", name);
-               break;
-       default:
-               break;
-       }
-}
-
-static void ia32_dump_function_size(FILE *F, const char *name)
-{
-       switch (asm_flavour) {
-       case ASM_LINUX_GAS:
-               fprintf(F, "\t.size\t%s, .-%s\n", name, name);
-               break;
-       default:
-               break;
-       }
-}
-
 /**
  * Returns the register at in position pos.
  */
@@ -136,24 +64,18 @@ static const arch_register_t *get_in_reg(const ir_node *irn, int pos) {
 
        /* in case of a joker register: just return a valid register */
        if (arch_register_type_is(reg, joker)) {
-               arch_register_req_t       req;
-               const arch_register_req_t *p_req;
+               const arch_register_req_t *req;
 
                /* ask for the requirements */
-               p_req = arch_get_register_req(arch_env, &req, irn, pos);
+               req = arch_get_register_req(arch_env, irn, pos);
 
-               if (arch_register_req_is(p_req, limited)) {
+               if (arch_register_req_is(req, limited)) {
                        /* in case of limited requirements: get the first allowed register */
-
-                       bitset_t *bs = bitset_alloca(arch_register_class_n_regs(p_req->cls));
-                       int      idx;
-
-                       p_req->limited(p_req->limited_env, bs);
-                       idx = bitset_next_set(bs, 0);
-                       reg = arch_register_for_index(p_req->cls, idx);
+                       unsigned idx = rbitset_next(req->limited, 0, 1);
+                       reg = arch_register_for_index(req->cls, idx);
                } else {
                        /* otherwise get first register in class */
-                       reg = arch_register_for_index(p_req->cls, 0);
+                       reg = arch_register_for_index(req->cls, 0);
                }
        }
 
@@ -253,33 +175,6 @@ static const char *ia32_get_reg_name_for_mode(ia32_emit_env_t *env, ir_mode *mod
        }
 }
 
-#if 0
-/**
- * Determines the SSE suffix depending on the mode.
- */
-static int ia32_print_mode_suffix(lc_appendable_t *app,
-    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
-{
-       ir_node *irn  = arg->v_ptr;
-       ir_mode *mode = get_ia32_ls_mode(irn);
-
-       if (mode_is_float(mode)) {
-               return lc_appendable_chadd(app, get_mode_size_bits(mode) == 32 ? 's' : 'd');
-       } else {
-               if(get_mode_size_bits(mode) == 32)
-                       return 0;
-
-               if(mode_is_signed(mode))
-                       lc_appendable_chadd(app, 's');
-               else
-                       lc_appendable_chadd(app, 'z');
-
-               lc_appendable_chadd(app, get_mode_suffix(mode));
-               return 2;
-       }
-}
-#endif
-
 /**
  * Add a number to a prefix. This number will not be used a second time.
  */
@@ -300,25 +195,16 @@ static char *get_unique_label(char *buf, size_t buflen, const char *prefix) {
  * |_|                                       |_|
  *************************************************************/
 
-void ia32_emit_ident(ia32_emit_env_t *env, ident *id)
-{
-       size_t len = get_id_strlen(id);
-       const char* str = get_id_str(id);
-
-       ia32_emit_string_len(env, str, len);
-}
-
-void ia32_emit_irprintf(ia32_emit_env_t *env, const char *fmt, ...)
-{
-       char buf[128];
-       va_list ap;
-
-       va_start(ap, fmt);
-       ir_vsnprintf(buf, sizeof(buf), fmt, ap);
-       va_end(ap);
-
-       ia32_emit_string(env, buf);
-}
+// we have no C++ and can't define an implicit ia32_emit_env_t* cast to
+// be_emit_env_t* so we cheat a bit...
+#define be_emit_char(env,c)             be_emit_char(env->emit,c)
+#define be_emit_string(env,s)           be_emit_string(env->emit,s)
+#undef be_emit_cstring
+#define be_emit_cstring(env,x)          { be_emit_string_len(env->emit, x, sizeof(x)-1); }
+#define be_emit_ident(env,i)            be_emit_ident(env->emit,i)
+#define be_emit_write_line(env)         be_emit_write_line(env->emit)
+#define be_emit_finish_line_gas(env,n)  be_emit_finish_line_gas(env->emit,n)
+#define be_emit_pad_comment(env)        be_emit_pad_comment(env->emit)
 
 void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos)
 {
@@ -327,16 +213,16 @@ void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int po
 
        assert(pos < get_irn_arity(node));
 
-       ia32_emit_char(env, '%');
-       ia32_emit_string(env, reg_name);
+       be_emit_char(env, '%');
+       be_emit_string(env, reg_name);
 }
 
 void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos) {
        const arch_register_t *reg = get_out_reg(node, pos);
        const char *reg_name = arch_register_get_name(reg);
 
-       ia32_emit_char(env, '%');
-       ia32_emit_string(env, reg_name);
+       be_emit_char(env, '%');
+       be_emit_string(env, reg_name);
 }
 
 void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos)
@@ -344,8 +230,8 @@ void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos)
        ia32_attr_t *attr = get_ia32_attr(node);
 
        assert(pos < 3);
-       ia32_emit_char(env, '%');
-       ia32_emit_string(env, attr->x87[pos]->name);
+       be_emit_char(env, '%');
+       be_emit_string(env, attr->x87[pos]->name);
 }
 
 void ia32_emit_immediate(ia32_emit_env_t *env, const ir_node *node)
@@ -363,16 +249,16 @@ void ia32_emit_immediate(ia32_emit_env_t *env, const ir_node *node)
                break;
        default:
                assert(0);
-               ia32_emit_string(env, "BAD");
+               be_emit_string(env, "BAD");
                return;
        }
 
-       ia32_emit_ident(env, id);
+       be_emit_ident(env, id);
 }
 
 void ia32_emit_mode_suffix(ia32_emit_env_t *env, const ir_mode *mode)
 {
-       ia32_emit_char(env, get_mode_suffix(mode));
+       be_emit_char(env, get_mode_suffix(mode));
 }
 
 void ia32_emit_x87_mode_suffix(ia32_emit_env_t *env, const ir_node *node)
@@ -400,15 +286,15 @@ void ia32_emit_xmm_mode_suffix(ia32_emit_env_t *env, const ir_node *node)
 {
        ir_mode *mode = get_ia32_ls_mode(node);
        assert(mode != NULL);
-       ia32_emit_char(env, 's');
-       ia32_emit_char(env, get_xmm_mode_suffix(mode));
+       be_emit_char(env, 's');
+       be_emit_char(env, get_xmm_mode_suffix(mode));
 }
 
 void ia32_emit_xmm_mode_suffix_s(ia32_emit_env_t *env, const ir_node *node)
 {
        ir_mode *mode = get_ia32_ls_mode(node);
        assert(mode != NULL);
-       ia32_emit_char(env, get_xmm_mode_suffix(mode));
+       be_emit_char(env, get_xmm_mode_suffix(mode));
 }
 
 void ia32_emit_extend_suffix(ia32_emit_env_t *env, const ir_mode *mode)
@@ -416,12 +302,50 @@ void ia32_emit_extend_suffix(ia32_emit_env_t *env, const ir_mode *mode)
        if(get_mode_size_bits(mode) == 32)
                return;
        if(mode_is_signed(mode)) {
-               ia32_emit_char(env, 's');
+               be_emit_char(env, 's');
        } else {
-               ia32_emit_char(env, 'z');
+               be_emit_char(env, 'z');
+       }
+}
+
+static void ia32_emit_function_object(ia32_emit_env_t *env, const char *name)
+{
+       switch (be_gas_flavour) {
+       case GAS_FLAVOUR_NORMAL:
+               be_emit_cstring(env, "\t.type\t");
+               be_emit_string(env, name);
+               be_emit_cstring(env, ", @function\n");
+               be_emit_write_line(env);
+               break;
+       case GAS_FLAVOUR_MINGW:
+               be_emit_cstring(env, "\t.def\t");
+               be_emit_string(env, name);
+               be_emit_cstring(env, ";\t.scl\t2;\t.type\t32;\t.endef\n");
+               be_emit_write_line(env);
+               break;
+       default:
+               break;
+       }
+}
+
+static void ia32_emit_function_size(ia32_emit_env_t *env, const char *name)
+{
+       switch (be_gas_flavour) {
+       case GAS_FLAVOUR_NORMAL:
+               be_emit_cstring(env, "\t.size\t");
+               be_emit_string(env, name);
+               be_emit_cstring(env, ", .-");
+               be_emit_string(env, name);
+               be_emit_char(env, '\n');
+               be_emit_write_line(env);
+               break;
+       default:
+               break;
        }
 }
 
+
+
 /**
  * Emits registers and/or address mode of a binary operation.
  */
@@ -429,9 +353,9 @@ void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
        switch(get_ia32_op_type(node)) {
                case ia32_Normal:
                        if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
-                               ia32_emit_char(env, '$');
+                               be_emit_char(env, '$');
                                ia32_emit_immediate(env, node);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_cstring(env, ", ");
                                ia32_emit_source_register(env, node, 2);
                        } else {
                                const arch_register_t *in1 = get_in_reg(node, 2);
@@ -449,33 +373,33 @@ void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
                                        in_name = "cl";
                                }
 
-                               ia32_emit_char(env, '%');
-                               ia32_emit_string(env, in_name);
-                               ia32_emit_cstring(env, ", %");
-                               ia32_emit_string(env, arch_register_get_name(out));
+                               be_emit_char(env, '%');
+                               be_emit_string(env, in_name);
+                               be_emit_cstring(env, ", %");
+                               be_emit_string(env, arch_register_get_name(out));
                        }
                        break;
                case ia32_AddrModeS:
                        if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
                                assert(!produces_result(node) && "Source AM with Const must not produce result");
                                ia32_emit_am(env, node);
-                               ia32_emit_cstring(env, ", $");
+                               be_emit_cstring(env, ", $");
                                ia32_emit_immediate(env, node);
                        } else if (produces_result(node)) {
                                ia32_emit_am(env, node);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_cstring(env, ", ");
                                ia32_emit_dest_register(env, node, 0);
                        } else {
                                ia32_emit_am(env, node);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_cstring(env, ", ");
                                ia32_emit_source_register(env, node, 2);
                        }
                        break;
                case ia32_AddrModeD:
                        if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
-                               ia32_emit_char(env, '$');
+                               be_emit_char(env, '$');
                                ia32_emit_immediate(env, node);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_cstring(env, ", ");
                                ia32_emit_am(env, node);
                        } else {
                                const arch_register_t *in1 = get_in_reg(node, get_irn_arity(node) == 5 ? 3 : 2);
@@ -489,9 +413,9 @@ void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
                                        in_name = "cl";
                                }
 
-                               ia32_emit_char(env, '%');
-                               ia32_emit_string(env, in_name);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_char(env, '%');
+                               be_emit_string(env, in_name);
+                               be_emit_cstring(env, ", ");
                                ia32_emit_am(env, node);
                        }
                        break;
@@ -519,10 +443,10 @@ void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node) {
                                in  = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
                                out = out ? out : in1;
 
-                               ia32_emit_char(env, '%');
-                               ia32_emit_string(env, arch_register_get_name(in));
-                               ia32_emit_cstring(env, ", %");
-                               ia32_emit_string(env, arch_register_get_name(out));
+                               be_emit_char(env, '%');
+                               be_emit_string(env, arch_register_get_name(in));
+                               be_emit_cstring(env, ", %");
+                               be_emit_string(env, arch_register_get_name(out));
                        }
                        break;
                case ia32_AddrModeS:
@@ -541,7 +465,7 @@ void ia32_emit_unop(ia32_emit_env_t *env, const ir_node *node) {
        switch(get_ia32_op_type(node)) {
                case ia32_Normal:
                        if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
-                               ia32_emit_char(env, '$');
+                               be_emit_char(env, '$');
                                ia32_emit_immediate(env, node);
                        } else {
                                if (is_ia32_Mul(node) || is_ia32_IMul1OP(node)) {
@@ -580,20 +504,20 @@ void ia32_emit_am(ia32_emit_env_t *env, const ir_node *node) {
        /* emit offset */
        if (id != NULL) {
                if (is_ia32_am_sc_sign(node))
-                       ia32_emit_char(env, '-');
-               ia32_emit_ident(env, id);
+                       be_emit_char(env, '-');
+               be_emit_ident(env, id);
        }
 
        if(offs != 0) {
                if(id != NULL) {
-                       ia32_emit_irprintf(env, "%+d", offs);
+                       be_emit_irprintf(env->emit, "%+d", offs);
                } else {
-                       ia32_emit_irprintf(env, "%d", offs);
+                       be_emit_irprintf(env->emit, "%d", offs);
                }
        }
 
        if (am_flav & (ia32_B | ia32_I)) {
-               ia32_emit_char(env, '(');
+               be_emit_char(env, '(');
 
                /* emit base */
                if (am_flav & ia32_B) {
@@ -602,76 +526,17 @@ void ia32_emit_am(ia32_emit_env_t *env, const ir_node *node) {
 
                /* emit index + scale */
                if (am_flav & ia32_I) {
-                       ia32_emit_char(env, ',');
+                       be_emit_char(env, ',');
                        ia32_emit_source_register(env, node, 1);
 
                        if (am_flav & ia32_S) {
-                               ia32_emit_irprintf(env, ",%d", 1 << get_ia32_am_scale(node));
+                               be_emit_irprintf(env->emit, ",%d", 1 << get_ia32_am_scale(node));
                        }
                }
-               ia32_emit_char(env, ')');
+               be_emit_char(env, ')');
        }
 }
 
-#if 0
-/**
- * Formated print of commands and comments.
- */
-static void ia32_fprintf_format(FILE *F, const ir_node *irn, char *cmd_buf, char *cmnt_buf) {
-       unsigned lineno;
-       const char *name = irn ? be_retrieve_dbg_info(get_irn_dbg_info((ir_node *)irn), &lineno) : NULL;
-
-       if (name)
-               fprintf(F, "\t%-35s %-60s /* %s:%u */\n", cmd_buf, cmnt_buf, name, lineno);
-       else
-               fprintf(F, "\t%-35s %-60s\n", cmd_buf, cmnt_buf);
-}
-#endif
-
-void ia32_write_line(ia32_emit_env_t *env)
-{
-       char *finished_line = obstack_finish(env->obst);
-
-       fwrite(finished_line, env->linelength, 1, env->out);
-       env->linelength = 0;
-       obstack_free(env->obst, finished_line);
-}
-
-void ia32_pad_comment(ia32_emit_env_t *env)
-{
-       while(env->linelength <= 30) {
-               ia32_emit_char(env, ' ');
-       }
-       ia32_emit_cstring(env, "    ");
-}
-
-void ia32_emit_finish_line(ia32_emit_env_t *env, const ir_node *node)
-{
-       dbg_info *dbg;
-       const char *sourcefile;
-       unsigned lineno;
-
-       if(node == NULL) {
-               ia32_emit_char(env, '\n');
-               ia32_write_line(env);
-               return;
-       }
-
-       ia32_pad_comment(env);
-       ia32_emit_cstring(env, "/* ");
-       ia32_emit_irprintf(env, "%+F ", node);
-
-       dbg = get_irn_dbg_info(node);
-       sourcefile = be_retrieve_dbg_info(dbg, &lineno);
-       if(sourcefile != NULL) {
-               ia32_emit_string(env, sourcefile);
-               ia32_emit_irprintf(env, ":%u", lineno);
-       }
-       ia32_emit_cstring(env, " */\n");
-       ia32_write_line(env);
-}
-
-
 /*************************************************
  *                 _ _                         _
  *                (_) |                       | |
@@ -746,7 +611,7 @@ static const char *get_cmp_suffix(int cmp_code)
 
 void ia32_emit_cmp_suffix(ia32_emit_env_t *env, long pnc)
 {
-       ia32_emit_string(env, get_cmp_suffix(pnc));
+       be_emit_string(env, get_cmp_suffix(pnc));
 }
 
 
@@ -763,8 +628,8 @@ static ir_node *get_cfop_target_block(const ir_node *irn) {
 void ia32_emit_cfop_target(ia32_emit_env_t * env, const ir_node *node) {
        ir_node *block = get_cfop_target_block(node);
 
-       ia32_emit_cstring(env, BLOCK_PREFIX);
-       ia32_emit_irprintf(env, "%d", get_irn_node_nr(block));
+       be_emit_cstring(env, BLOCK_PREFIX);
+       be_emit_irprintf(env->emit, "%d", get_irn_node_nr(block));
 }
 
 /** Return the next block in Block schedule */
@@ -830,27 +695,27 @@ static void finish_CondJmp(ia32_emit_env_t *env, const ir_node *node,
 
        /* in case of unordered compare, check for parity */
        if (pnc & pn_Cmp_Uo) {
-               ia32_emit_cstring(env, "\tjp ");
+               be_emit_cstring(env, "\tjp ");
                ia32_emit_cfop_target(env, proj_true);
-               ia32_emit_finish_line(env, proj_true);
+               be_emit_finish_line_gas(env, proj_true);
        }
 
-       ia32_emit_cstring(env, "\tj");
+       be_emit_cstring(env, "\tj");
        ia32_emit_cmp_suffix(env, pnc);
-       ia32_emit_char(env, ' ');
+       be_emit_char(env, ' ');
        ia32_emit_cfop_target(env, proj_true);
-       ia32_emit_finish_line(env, proj_true);
+       be_emit_finish_line_gas(env, proj_true);
 
        /* the second Proj might be a fallthrough */
        if (get_cfop_target_block(proj_false) != next_block) {
-               ia32_emit_cstring(env, "\tjmp ");
+               be_emit_cstring(env, "\tjmp ");
                ia32_emit_cfop_target(env, proj_false);
-               ia32_emit_finish_line(env, proj_false);
+               be_emit_finish_line_gas(env, proj_false);
        } else {
-               ia32_emit_cstring(env, "\t/* fallthrough to");
+               be_emit_cstring(env, "\t/* fallthrough to");
                ia32_emit_cfop_target(env, proj_false);
-               ia32_emit_cstring(env, " */");
-               ia32_emit_finish_line(env, proj_false);
+               be_emit_cstring(env, " */");
+               be_emit_finish_line_gas(env, proj_false);
        }
 }
 
@@ -858,9 +723,9 @@ static void finish_CondJmp(ia32_emit_env_t *env, const ir_node *node,
  * Emits code for conditional jump.
  */
 static void CondJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "\tcmp ");
+       be_emit_cstring(env, "\tcmp ");
        ia32_emit_binop(env, node);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        finish_CondJmp(env, node, mode_Iu, get_ia32_pncode(node));
 }
@@ -877,17 +742,17 @@ static void emit_ia32_CondJmp(ia32_emit_env_t *env, const ir_node *node) {
  */
 static void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
        if(is_ia32_ImmSymConst(node) || is_ia32_ImmConst(node)) {
-               ia32_emit_cstring(env, "\ttest $");
+               be_emit_cstring(env, "\ttest $");
                ia32_emit_immediate(env, node);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
        } else {
-               ia32_emit_cstring(env, "\ttest ");
+               be_emit_cstring(env, "\ttest ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
        }
        finish_CondJmp(env, node, mode_Iu, get_ia32_pncode(node));
 }
@@ -900,15 +765,15 @@ static void emit_ia32_TestJmp(ia32_emit_env_t *env, const ir_node *node) {
 }
 
 static void emit_ia32_CJmp(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "/* omitted redundant test */");
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "/* omitted redundant test */");
+       be_emit_finish_line_gas(env, node);
 
        finish_CondJmp(env, node, mode_Is, get_ia32_pncode(node));
 }
 
 static void emit_ia32_CJmpAM(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "/* omitted redundant test/cmp */");
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "/* omitted redundant test/cmp */");
+       be_emit_finish_line_gas(env, node);
 
        finish_CondJmp(env, node, mode_Is, get_ia32_pncode(node));
 }
@@ -917,11 +782,11 @@ static void emit_ia32_CJmpAM(ia32_emit_env_t *env, const ir_node *node) {
  * Emits code for conditional SSE floating point jump with two variables.
  */
 static void emit_ia32_xCondJmp(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "\tucomi");
+       be_emit_cstring(env, "\tucomi");
        ia32_emit_xmm_mode_suffix(env, node);
-       ia32_emit_char(env, ' ');
+       be_emit_char(env, ' ');
        ia32_emit_binop(env, node);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        finish_CondJmp(env, node, mode_F, get_ia32_pncode(node));
 }
@@ -940,32 +805,32 @@ static void emit_ia32_x87CondJmp(ia32_emit_env_t *env, const ir_node *node) {
                reg = attr->x87[0]->name;
        case iro_ia32_fcomJmp:
        default:
-               ia32_emit_cstring(env, "\tfucom ");
+               be_emit_cstring(env, "\tfucom ");
                break;
        case iro_ia32_fcomrpJmp:
                pnc = get_inversed_pnc(pnc);
                reg = attr->x87[0]->name;
        case iro_ia32_fcompJmp:
-               ia32_emit_cstring(env, "\tfucomp ");
+               be_emit_cstring(env, "\tfucomp ");
                break;
        case iro_ia32_fcomrppJmp:
                pnc = get_inversed_pnc(pnc);
        case iro_ia32_fcomppJmp:
-               ia32_emit_cstring(env, "\tfucompp ");
+               be_emit_cstring(env, "\tfucompp ");
                reg = "";
                break;
        }
 
        if(reg[0] != '\0') {
-               ia32_emit_char(env, '%');
-               ia32_emit_string(env, reg);
+               be_emit_char(env, '%');
+               be_emit_string(env, reg);
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
-       ia32_emit_cstring(env, "\tfnstsw %ax");
-       ia32_emit_finish_line(env, node);
-       ia32_emit_cstring(env, "\tsahf");
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "\tfnstsw %ax");
+       be_emit_finish_line_gas(env, node);
+       be_emit_cstring(env, "\tsahf");
+       be_emit_finish_line_gas(env, node);
 
        finish_CondJmp(env, node, mode_E, pnc);
 }
@@ -984,27 +849,27 @@ static void CMov_emitter(ia32_emit_env_t *env, const ir_node *node) {
        /* we have to emit the cmp first, because the destination register */
        /* could be one of the compare registers                           */
        if (is_ia32_CmpCMov(node)) {
-               ia32_emit_cstring(env, "\tcmp ");
+               be_emit_cstring(env, "\tcmp ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
        } else if (is_ia32_xCmpCMov(node)) {
-               ia32_emit_cstring(env, "\tucomis");
+               be_emit_cstring(env, "\tucomis");
                ia32_emit_mode_suffix(env, get_irn_mode(node));
-               ia32_emit_char(env, ' ');
+               be_emit_char(env, ' ');
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
        } else if (is_PsiCondCMov) {
                /* omit compare because flags are already set by And/Or */
-               ia32_emit_cstring(env, "\ttest ");
+               be_emit_cstring(env, "\ttest ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
        } else {
                assert(0 && "unsupported CMov");
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        if (REGS_ARE_EQUAL(out, in2)) {
                /* best case: default in == out -> do nothing */
@@ -1019,35 +884,35 @@ static void CMov_emitter(ia32_emit_env_t *env, const ir_node *node) {
        } else {
                /* out is different from in: need copy default -> out */
                if (is_PsiCondCMov) {
-                       ia32_emit_cstring(env, "\tmovl ");
+                       be_emit_cstring(env, "\tmovl ");
                        ia32_emit_dest_register(env, node, 2);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                } else {
-                       ia32_emit_cstring(env, "\tmovl ");
+                       be_emit_cstring(env, "\tmovl ");
                        ia32_emit_source_register(env, node, 3);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                }
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
        }
 
        if (is_PsiCondCMov) {
-               ia32_emit_cstring(env, "\tcmov");
+               be_emit_cstring(env, "\tcmov");
                ia32_emit_cmp_suffix(env, pnc);
-               ia32_emit_cstring(env, "l ");
+               be_emit_cstring(env, "l ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_dest_register(env, node, 0);
        } else {
-               ia32_emit_cstring(env, "\tcmov");
+               be_emit_cstring(env, "\tcmov");
                ia32_emit_cmp_suffix(env, pnc);
-               ia32_emit_cstring(env, "l ");
+               be_emit_cstring(env, "l ");
                ia32_emit_source_register(env, node, 2);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_dest_register(env, node, 0);
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_ia32_CmpCMov(ia32_emit_env_t *env, const ir_node *node) {
@@ -1071,31 +936,31 @@ static void Set_emitter(ia32_emit_env_t *env, const ir_node *node, ir_mode *mode
        reg8bit = ia32_get_mapped_reg_name(env->isa->regs_8bit, out);
 
        if (is_ia32_CmpSet(node)) {
-               ia32_emit_cstring(env, "\tcmp ");
+               be_emit_cstring(env, "\tcmp ");
                ia32_emit_binop(env, node);
        } else if (is_ia32_xCmpSet(node)) {
-               ia32_emit_cstring(env, "\tucomis");
+               be_emit_cstring(env, "\tucomis");
                ia32_emit_mode_suffix(env, get_irn_mode(get_irn_n(node, 2)));
-               ia32_emit_char(env, ' ');
+               be_emit_char(env, ' ');
                ia32_emit_binop(env, node);
        } else if (is_ia32_PsiCondSet(node)) {
-               ia32_emit_cstring(env, "\tcmp $0, ");
+               be_emit_cstring(env, "\tcmp $0, ");
                ia32_emit_source_register(env, node, 0);
        } else {
                assert(0 && "unsupported Set");
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        /* use mov to clear target because it doesn't affect the eflags */
-       ia32_emit_cstring(env, "\tmovl $0, %");
-       ia32_emit_string(env, arch_register_get_name(out));
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "\tmovl $0, %");
+       be_emit_string(env, arch_register_get_name(out));
+       be_emit_finish_line_gas(env, node);
 
-       ia32_emit_cstring(env, "\tset");
+       be_emit_cstring(env, "\tset");
        ia32_emit_cmp_suffix(env, pnc);
-       ia32_emit_cstring(env, " %");
-       ia32_emit_string(env, reg8bit);
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, " %");
+       be_emit_string(env, reg8bit);
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_ia32_CmpSet(ia32_emit_env_t *env, const ir_node *node) {
@@ -1163,31 +1028,31 @@ static void emit_ia32_xCmp(ia32_emit_env_t *env, const ir_node *node) {
                        - and result and stored result
                    - cleanup stack
                */
-               ia32_emit_cstring(env, "\tsubl $8, %esp");
-               ia32_emit_finish_line(env, node);
+               be_emit_cstring(env, "\tsubl $8, %esp");
+               be_emit_finish_line_gas(env, node);
 
-               ia32_emit_cstring(env, "\tcmpsd $3, ");
+               be_emit_cstring(env, "\tcmpsd $3, ");
                ia32_emit_binop(env, node);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
 
-               ia32_emit_cstring(env, "\tmovsd ");
+               be_emit_cstring(env, "\tmovsd ");
                ia32_emit_dest_register(env, node, 0);
-               ia32_emit_cstring(env, ", (%esp)");
-               ia32_emit_finish_line(env, node);
+               be_emit_cstring(env, ", (%esp)");
+               be_emit_finish_line_gas(env, node);
        }
 
-       ia32_emit_cstring(env, "\tcmpsd ");
-       ia32_emit_irprintf(env, "%d, ", sse_pnc);
+       be_emit_cstring(env, "\tcmpsd ");
+       be_emit_irprintf(env->emit, "%d, ", sse_pnc);
        ia32_emit_binop(env, node);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        if (unord && sse_pnc != 3) {
-               ia32_emit_cstring(env, "\tandpd (%esp), ");
+               be_emit_cstring(env, "\tandpd (%esp), ");
                ia32_emit_dest_register(env, node, 0);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
 
-               ia32_emit_cstring(env, "\taddl $8, %esp");
-               ia32_emit_finish_line(env, node);
+               be_emit_cstring(env, "\taddl $8, %esp");
+               be_emit_finish_line_gas(env, node);
        }
 }
 
@@ -1284,53 +1149,53 @@ static void emit_ia32_SwitchJmp(ia32_emit_env_t *env, const ir_node *node) {
        interval = tbl.max_value - tbl.min_value;
 
        /* emit the table */
-       ia32_emit_cstring(env, "\tcmpl $");
-       ia32_emit_irprintf(env, "%u, ", interval);
+       be_emit_cstring(env, "\tcmpl $");
+       be_emit_irprintf(env->emit, "%u, ", interval);
        ia32_emit_source_register(env, node, 0);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
-       ia32_emit_cstring(env, "\tja ");
+       be_emit_cstring(env, "\tja ");
        ia32_emit_cfop_target(env, tbl.defProj);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 
        if (tbl.num_branches > 1) {
                /* create table */
-               ia32_emit_cstring(env, "\tjmp *");
-               ia32_emit_string(env, tbl.label);
-               ia32_emit_cstring(env, "(,");
+               be_emit_cstring(env, "\tjmp *");
+               be_emit_string(env, tbl.label);
+               be_emit_cstring(env, "(,");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_cstring(env, ",4)");
-               ia32_emit_finish_line(env, node);
+               be_emit_cstring(env, ",4)");
+               be_emit_finish_line_gas(env, node);
 
-               ia32_switch_section(env->out, SECTION_RODATA);
-               ia32_emit_cstring(env, "\t.align 4\n");
-               ia32_write_line(env);
+               be_gas_emit_switch_section(env->emit, GAS_SECTION_RODATA);
+               be_emit_cstring(env, "\t.align 4\n");
+               be_emit_write_line(env);
 
-               ia32_emit_string(env, tbl.label);
-               ia32_emit_cstring(env, ":\n");
-               ia32_write_line(env);
+               be_emit_string(env, tbl.label);
+               be_emit_cstring(env, ":\n");
+               be_emit_write_line(env);
 
-               ia32_emit_cstring(env, ".long ");
+               be_emit_cstring(env, ".long ");
                ia32_emit_cfop_target(env, tbl.branches[0].target);
-               ia32_emit_finish_line(env, NULL);
+               be_emit_finish_line_gas(env, NULL);
 
                last_value = tbl.branches[0].value;
                for (i = 1; i < tbl.num_branches; ++i) {
                        while (++last_value < tbl.branches[i].value) {
-                               ia32_emit_cstring(env, ".long ");
+                               be_emit_cstring(env, ".long ");
                                ia32_emit_cfop_target(env, tbl.defProj);
-                               ia32_emit_finish_line(env, NULL);
+                               be_emit_finish_line_gas(env, NULL);
                        }
-                       ia32_emit_cstring(env, ".long ");
+                       be_emit_cstring(env, ".long ");
                        ia32_emit_cfop_target(env, tbl.branches[i].target);
-                       ia32_emit_finish_line(env, NULL);
+                       be_emit_finish_line_gas(env, NULL);
                }
-               ia32_switch_section(env->out, SECTION_TEXT);
+               be_gas_emit_switch_section(env->emit, GAS_SECTION_TEXT);
        } else {
                /* one jump is enough */
-               ia32_emit_cstring(env, "\tjmp ");
+               be_emit_cstring(env, "\tjmp ");
                ia32_emit_cfop_target(env, tbl.branches[0].target);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
        }
 
        if (tbl.label)
@@ -1351,14 +1216,14 @@ static void emit_Jmp(ia32_emit_env_t *env, const ir_node *node) {
        /* we have a block schedule */
        next_block = next_blk_sched(block);
        if (get_cfop_target_block(node) != next_block) {
-               ia32_emit_cstring(env, "\tjmp ");
+               be_emit_cstring(env, "\tjmp ");
                ia32_emit_cfop_target(env, node);
        } else {
-               ia32_emit_cstring(env, "\t/* fallthrough to ");
+               be_emit_cstring(env, "\t/* fallthrough to ");
                ia32_emit_cfop_target(env, node);
-               ia32_emit_cstring(env, " */");
+               be_emit_cstring(env, " */");
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**********************************
@@ -1376,23 +1241,23 @@ static void emit_Jmp(ia32_emit_env_t *env, const ir_node *node) {
  * Emit movsb/w instructions to make mov count divideable by 4
  */
 static void emit_CopyB_prolog(ia32_emit_env_t *env, int rem) {
-       ia32_emit_cstring(env, "\tcld");
-       ia32_emit_finish_line(env, NULL);
+       be_emit_cstring(env, "\tcld");
+       be_emit_finish_line_gas(env, NULL);
 
        switch(rem) {
        case 1:
-               ia32_emit_cstring(env, "\tmovsb");
-               ia32_emit_finish_line(env, NULL);
+               be_emit_cstring(env, "\tmovsb");
+               be_emit_finish_line_gas(env, NULL);
                break;
        case 2:
-               ia32_emit_cstring(env, "\tmovsw");
-               ia32_emit_finish_line(env, NULL);
+               be_emit_cstring(env, "\tmovsw");
+               be_emit_finish_line_gas(env, NULL);
                break;
        case 3:
-               ia32_emit_cstring(env, "\tmovsb");
-               ia32_emit_finish_line(env, NULL);
-               ia32_emit_cstring(env, "\tmovsw");
-               ia32_emit_finish_line(env, NULL);
+               be_emit_cstring(env, "\tmovsb");
+               be_emit_finish_line_gas(env, NULL);
+               be_emit_cstring(env, "\tmovsw");
+               be_emit_finish_line_gas(env, NULL);
                break;
        }
 }
@@ -1406,8 +1271,8 @@ static void emit_ia32_CopyB(ia32_emit_env_t *env, const ir_node *node) {
 
        emit_CopyB_prolog(env, rem);
 
-       ia32_emit_cstring(env, "\trep movsd");
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "\trep movsd");
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
@@ -1421,8 +1286,8 @@ static void emit_ia32_CopyB_i(ia32_emit_env_t *env, const ir_node *node) {
 
        size >>= 2;
        while (size--) {
-               ia32_emit_cstring(env, "\tmovsd");
-               ia32_emit_finish_line(env, NULL);
+               be_emit_cstring(env, "\tmovsd");
+               be_emit_finish_line_gas(env, NULL);
        }
 }
 
@@ -1445,45 +1310,45 @@ static void emit_ia32_Conv_with_FP(ia32_emit_env_t *env, const ir_node *node) {
        ir_mode            *ls_mode = get_ia32_ls_mode(node);
        int                 ls_bits = get_mode_size_bits(ls_mode);
 
-       ia32_emit_cstring(env, "\tcvt");
+       be_emit_cstring(env, "\tcvt");
 
        if(is_ia32_Conv_I2FP(node)) {
                if(ls_bits == 32) {
-                       ia32_emit_cstring(env, "si2ss");
+                       be_emit_cstring(env, "si2ss");
                } else {
-                       ia32_emit_cstring(env, "si2sd");
+                       be_emit_cstring(env, "si2sd");
                }
        } else if(is_ia32_Conv_FP2I(node)) {
                if(ls_bits == 32) {
-                       ia32_emit_cstring(env, "ss2si");
+                       be_emit_cstring(env, "ss2si");
                } else {
-                       ia32_emit_cstring(env, "sd2si");
+                       be_emit_cstring(env, "sd2si");
                }
        } else {
                assert(is_ia32_Conv_FP2FP(node));
                if(ls_bits == 32) {
-                       ia32_emit_cstring(env, "sd2ss");
+                       be_emit_cstring(env, "sd2ss");
                } else {
-                       ia32_emit_cstring(env, "ss2sd");
+                       be_emit_cstring(env, "ss2sd");
                }
        }
-       ia32_emit_char(env, ' ');
+       be_emit_char(env, ' ');
 
        switch(get_ia32_op_type(node)) {
                case ia32_Normal:
                        ia32_emit_source_register(env, node, 2);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                        break;
                case ia32_AddrModeS:
                        ia32_emit_dest_register(env, node, 0);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_am(env, node);
                        break;
                default:
                        assert(0 && "unsupported op type for Conv");
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_ia32_Conv_I2FP(ia32_emit_env_t *env, const ir_node *node) {
@@ -1532,9 +1397,9 @@ static void emit_ia32_Conv_I2I(ia32_emit_env_t *env, const ir_node *node) {
                                /* argument and result are both in EAX and */
                                /* signedness is ok: -> use converts       */
                                if (smaller_bits == 8) {
-                                       ia32_emit_cstring(env, "\tcbtw");
+                                       be_emit_cstring(env, "\tcbtw");
                                } else if (smaller_bits == 16) {
-                                       ia32_emit_cstring(env, "\tcwtl");
+                                       be_emit_cstring(env, "\tcwtl");
                                } else {
                                        assert(0);
                                }
@@ -1542,35 +1407,35 @@ static void emit_ia32_Conv_I2I(ia32_emit_env_t *env, const ir_node *node) {
                                /* argument and result are in the same register */
                                /* and signedness is ok: -> use and with mask   */
                                int mask = (1 << smaller_bits) - 1;
-                               ia32_emit_cstring(env, "\tandl $0x");
-                               ia32_emit_irprintf(env, "%x, ", mask);
+                               be_emit_cstring(env, "\tandl $0x");
+                               be_emit_irprintf(env->emit, "%x, ", mask);
                                ia32_emit_dest_register(env, node, 0);
                        } else {
                                const char *sreg = ia32_get_reg_name_for_mode(env, smaller_mode, in_reg);
 
-                               ia32_emit_cstring(env, "\tmov");
-                               ia32_emit_string(env, sign_suffix);
+                               be_emit_cstring(env, "\tmov");
+                               be_emit_string(env, sign_suffix);
                                ia32_emit_mode_suffix(env, smaller_mode);
-                               ia32_emit_cstring(env, "l %");
-                               ia32_emit_string(env, sreg);
-                               ia32_emit_cstring(env, ", ");
+                               be_emit_cstring(env, "l %");
+                               be_emit_string(env, sreg);
+                               be_emit_cstring(env, ", ");
                                ia32_emit_dest_register(env, node, 0);
                        }
                        break;
                case ia32_AddrModeS: {
-                       ia32_emit_cstring(env, "\tmov");
-                       ia32_emit_string(env, sign_suffix);
+                       be_emit_cstring(env, "\tmov");
+                       be_emit_string(env, sign_suffix);
                        ia32_emit_mode_suffix(env, smaller_mode);
-                       ia32_emit_cstring(env, "l %");
+                       be_emit_cstring(env, "l %");
                        ia32_emit_am(env, node);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                        break;
                }
                default:
                        assert(0 && "unsupported op type for Conv");
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
@@ -1597,14 +1462,14 @@ void emit_ia32_Conv_I2I8Bit(ia32_emit_env_t *env, const ir_node *node) {
 static void emit_be_Call(ia32_emit_env_t *env, const ir_node *node) {
        ir_entity *ent = be_Call_get_entity(node);
 
-       ia32_emit_cstring(env, "\tcall ");
+       be_emit_cstring(env, "\tcall ");
        if (ent) {
-               ia32_emit_string(env, get_entity_ld_name(ent));
+               be_emit_string(env, get_entity_ld_name(ent));
        } else {
-               ia32_emit_char(env, '*');
+               be_emit_char(env, '*');
                ia32_emit_dest_register(env, get_irn_n(node, be_pos_Call_ptr), 0);
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
@@ -1617,26 +1482,26 @@ static void emit_be_IncSP(ia32_emit_env_t *env, const ir_node *node) {
                return;
 
        if (offs > 0) {
-               ia32_emit_cstring(env, "\tsubl $");
-               ia32_emit_irprintf(env, "%u, ", offs);
+               be_emit_cstring(env, "\tsubl $");
+               be_emit_irprintf(env->emit, "%u, ", offs);
                ia32_emit_source_register(env, node, 0);
        } else {
-               ia32_emit_cstring(env, "\taddl $");
-               ia32_emit_irprintf(env, "%u, ", -offs);
+               be_emit_cstring(env, "\taddl $");
+               be_emit_irprintf(env->emit, "%u, ", -offs);
                ia32_emit_source_register(env, node, 0);
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
  * Emits code to set stack pointer.
  */
 static void emit_be_SetSP(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "\tmovl ");
+       be_emit_cstring(env, "\tmovl ");
        ia32_emit_source_register(env, node, 2);
-       ia32_emit_cstring(env, ", ");
+       be_emit_cstring(env, ", ");
        ia32_emit_dest_register(env, node, 0);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
@@ -1650,17 +1515,17 @@ static void Copy_emitter(ia32_emit_env_t *env, const ir_node *node, const ir_nod
                return;
 
        if (mode_is_float(get_irn_mode(node))) {
-               ia32_emit_cstring(env, "\tmovsd ");
+               be_emit_cstring(env, "\tmovsd ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_dest_register(env, node, 0);
        } else {
-               ia32_emit_cstring(env, "\tmovl ");
+               be_emit_cstring(env, "\tmovl ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_dest_register(env, node, 0);
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_be_Copy(ia32_emit_env_t *env, const ir_node *node) {
@@ -1699,32 +1564,32 @@ static void emit_be_Perm(ia32_emit_env_t *env, const ir_node *node) {
                        lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xor %1S, %2S", irn, irn);
                } else {
 #endif
-                       ia32_emit_cstring(env, "\txchg ");
+                       be_emit_cstring(env, "\txchg ");
                        ia32_emit_source_register(env, node, 1);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_source_register(env, node, 0);
-                       ia32_emit_finish_line(env, node);
+                       be_emit_finish_line_gas(env, node);
 #if 0
                }
 #endif
        } else if (cls1 == &ia32_reg_classes[CLASS_ia32_xmm]) {
-               ia32_emit_cstring(env, "\txorpd ");
+               be_emit_cstring(env, "\txorpd ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_finish_line(env, NULL);
+               be_emit_finish_line_gas(env, NULL);
 
-               ia32_emit_cstring(env, "\txorpd ");
+               be_emit_cstring(env, "\txorpd ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_finish_line(env, NULL);
+               be_emit_finish_line_gas(env, NULL);
 
-               ia32_emit_cstring(env, "\txorpd ");
+               be_emit_cstring(env, "\txorpd ");
                ia32_emit_source_register(env, node, 1);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_source_register(env, node, 0);
-               ia32_emit_finish_line(env, node);
+               be_emit_finish_line_gas(env, node);
        } else if (cls1 == &ia32_reg_classes[CLASS_ia32_vfp]) {
                /* is a NOP */
        } else if (cls1 == &ia32_reg_classes[CLASS_ia32_st]) {
@@ -1740,9 +1605,9 @@ static void emit_ia32_Const(ia32_emit_env_t *env, const ir_node *node) {
        ia32_immop_type_t imm_tp = get_ia32_immop_type(node);
 
        if (imm_tp == ia32_ImmSymConst) {
-               ia32_emit_cstring(env, "\tmovl $");
+               be_emit_cstring(env, "\tmovl $");
                ia32_emit_immediate(env, node);
-               ia32_emit_cstring(env, ", ");
+               be_emit_cstring(env, ", ");
                ia32_emit_dest_register(env, node, 0);
        } else {
                tarval *tv = get_ia32_Immop_tarval(node);
@@ -1751,35 +1616,35 @@ static void emit_ia32_Const(ia32_emit_env_t *env, const ir_node *node) {
                if (tarval_is_null(tv)) {
                        if (env->isa->opt_arch == arch_pentium_4) {
                                /* P4 prefers sub r, r, others xor r, r */
-                               ia32_emit_cstring(env, "\tsubl ");
+                               be_emit_cstring(env, "\tsubl ");
                        } else {
-                               ia32_emit_cstring(env, "\txorl ");
+                               be_emit_cstring(env, "\txorl ");
                        }
                        ia32_emit_dest_register(env, node, 0);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                } else {
-                       ia32_emit_cstring(env, "\tmovl $");
+                       be_emit_cstring(env, "\tmovl $");
                        ia32_emit_immediate(env, node);
-                       ia32_emit_cstring(env, ", ");
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                }
        }
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 /**
  * Emits code to load the TLS base
  */
 static void emit_ia32_LdTls(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "\tmovl %gs:0, ");
+       be_emit_cstring(env, "\tmovl %gs:0, ");
        ia32_emit_dest_register(env, node, 0);
-       ia32_emit_finish_line(env, node);
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_be_Return(ia32_emit_env_t *env, const ir_node *node) {
-       ia32_emit_cstring(env, "\tret");
-       ia32_emit_finish_line(env, node);
+       be_emit_cstring(env, "\tret");
+       be_emit_finish_line_gas(env, node);
 }
 
 static void emit_Nothing(ia32_emit_env_t *env, const ir_node *node) {
@@ -1894,12 +1759,13 @@ static void ia32_emit_dbg(ia32_emit_env_t *env, const ir_node *node) {
                }
                if (last_line != lineno) {
                        char name[64];
-                       FILE *F = env->out;
 
                        snprintf(name, sizeof(name), ".LM%u", ++num);
                        last_line = lineno;
                        be_dbg_line(env->cg->birg->main_env->db_handle, lineno, name);
-                       fprintf(F, "%s:\n", name);
+                       be_emit_string(env, name);
+                       be_emit_cstring(env, ":\n");
+                       be_emit_write_line(env);
                }
        }
 }
@@ -1929,9 +1795,9 @@ static void ia32_emit_node(ia32_emit_env_t *env, const ir_node *node) {
  * Emits gas alignment directives
  */
 static void ia32_emit_alignment(ia32_emit_env_t *env, unsigned align, unsigned skip) {
-       ia32_emit_cstring(env, "\t.p2align ");
-       ia32_emit_irprintf(env, "%u,,%u\n", align, skip);
-       ia32_write_line(env);
+       be_emit_cstring(env, "\t.p2align ");
+       be_emit_irprintf(env->emit, "%u,,%u\n", align, skip);
+       be_emit_write_line(env);
 }
 
 /**
@@ -2073,23 +1939,23 @@ static void ia32_gen_block(ia32_emit_env_t *env, ir_node *block, ir_node *last_b
                if (align)
                        ia32_emit_align_label(env, env->isa->opt_arch);
 
-               ia32_emit_cstring(env, BLOCK_PREFIX);
-               ia32_emit_irprintf(env, "%d:", get_irn_node_nr(block));
-               ia32_pad_comment(env);
-               ia32_emit_cstring(env, "   /* preds:");
+               be_emit_cstring(env, BLOCK_PREFIX);
+               be_emit_irprintf(env->emit, "%d:", get_irn_node_nr(block));
+               be_emit_pad_comment(env);
+               be_emit_cstring(env, "   /* preds:");
 
                /* emit list of pred blocks in comment */
                arity = get_irn_arity(block);
                for (i = 0; i < arity; ++i) {
                        ir_node *predblock = get_Block_cfgpred_block(block, i);
-                       ia32_emit_irprintf(env, " %d", get_irn_node_nr(predblock));
+                       be_emit_irprintf(env->emit, " %d", get_irn_node_nr(predblock));
                }
 
                if (exec_freq != NULL) {
-                       ia32_emit_irprintf(env, " freq: %f", get_block_execfreq(exec_freq, block));
+                       be_emit_irprintf(env->emit, " freq: %f", get_block_execfreq(exec_freq, block));
                }
-               ia32_emit_cstring(env, " */\n");
-               ia32_write_line(env);
+               be_emit_cstring(env, " */\n");
+               be_emit_write_line(env);
        }
 
        /* emit the contents of the block */
@@ -2103,21 +1969,25 @@ static void ia32_gen_block(ia32_emit_env_t *env, ir_node *block, ir_node *last_b
  * Emits code for function start.
  */
 static void ia32_emit_func_prolog(ia32_emit_env_t *env, ir_graph *irg) {
-       FILE *F = env->out;
        ir_entity  *irg_ent  = get_irg_entity(irg);
        const char *irg_name = get_entity_ld_name(irg_ent);
        cpu_support cpu      = env->isa->opt_arch;
        const be_irg_t *birg = env->cg->birg;
 
-       fprintf(F, "\n");
-       ia32_switch_section(F, SECTION_TEXT);
+       be_emit_write_line(env);
+       be_gas_emit_switch_section(env->emit, GAS_SECTION_TEXT);
        be_dbg_method_begin(birg->main_env->db_handle, irg_ent, be_abi_get_stack_layout(birg->abi));
        ia32_emit_align_func(env, cpu);
        if (get_entity_visibility(irg_ent) == visibility_external_visible) {
-               fprintf(F, ".globl %s\n", irg_name);
+               be_emit_cstring(env, ".global ");
+               be_emit_string(env, irg_name);
+               be_emit_char(env, '\n');
+               be_emit_write_line(env);
        }
-       ia32_dump_function_object(F, irg_name);
-       fprintf(F, "%s:\n", irg_name);
+       ia32_emit_function_object(env, irg_name);
+       be_emit_string(env, irg_name);
+       be_emit_cstring(env, ":\n");
+       be_emit_write_line(env);
 }
 
 /**
@@ -2126,11 +1996,11 @@ static void ia32_emit_func_prolog(ia32_emit_env_t *env, ir_graph *irg) {
 static void ia32_emit_func_epilog(ia32_emit_env_t *env, ir_graph *irg) {
        const char *irg_name = get_entity_ld_name(get_irg_entity(irg));
        const be_irg_t *birg = env->cg->birg;
-       FILE *F = env->out;
 
-       ia32_dump_function_size(F, irg_name);
+       ia32_emit_function_size(env, irg_name);
        be_dbg_method_end(birg->main_env->db_handle);
-       fprintf(F, "\n");
+       be_emit_char(env, '\n');
+       be_emit_write_line(env);
 }
 
 /**
@@ -2150,21 +2020,16 @@ static void ia32_gen_labels(ir_node *block, void *data) {
 /**
  * Main driver. Emits the code for one routine.
  */
-void ia32_gen_routine(ia32_code_gen_t *cg, FILE *F, ir_graph *irg) {
+void ia32_gen_routine(ia32_code_gen_t *cg, ir_graph *irg) {
        ia32_emit_env_t env;
        ir_node *block;
        ir_node *last_block = NULL;
        int i, n;
-       struct obstack obst;
 
-       obstack_init(&obst);
-
-       env.out      = F;
+       env.isa      = (ia32_isa_t *)cg->arch_env->isa;
+       env.emit     = &env.isa->emit;
        env.arch_env = cg->arch_env;
        env.cg       = cg;
-       env.isa      = (ia32_isa_t *)cg->arch_env->isa;
-       env.obst     = &obst;
-       env.linelength = 0;
        FIRM_DBG_REGISTER(env.mod, "firm.be.ia32.emitter");
 
        /* set the global arch_env (needed by print hooks) */
index 1d2fcc0..04761b1 100644 (file)
 #include "debug.h"
 
 #include "../bearch.h"
+#include "../beemitter.h"
 
 #include "bearch_ia32_t.h"
 
-typedef struct _ia32_emit_env_t {
-       FILE                  *out;
+typedef struct ia32_emit_env_t {
+       be_emit_env_t         *emit;
        const arch_env_t      *arch_env;
        const ia32_code_gen_t *cg;
        ia32_isa_t            *isa;
-       struct obstack        *obst;
-       int                    linelength;
        DEBUG_ONLY(firm_dbg_module_t *mod;)
 } ia32_emit_env_t;
 
-static INLINE void ia32_emit_char(ia32_emit_env_t *env, char c)
-{
-       obstack_1grow(env->obst, c);
-       env->linelength++;
-}
-
-static INLINE void ia32_emit_string_len(ia32_emit_env_t *env, const char *str, size_t l)
-{
-       obstack_grow(env->obst, str, l);
-       env->linelength += l;
-}
-
-static INLINE void ia32_emit_string(ia32_emit_env_t *env, const char *str)
-{
-       size_t len = strlen(str);
-       ia32_emit_string_len(env, str, len);
-}
-
-#define ia32_emit_cstring(env,x) { ia32_emit_string_len(env, x, sizeof(x)-1); }
-
 void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos);
 void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos);
 void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos);
@@ -58,35 +37,7 @@ void ia32_emit_unop(ia32_emit_env_t *env, const ir_node *node);
 void ia32_emit_am(ia32_emit_env_t *env, const ir_node *node);
 void ia32_emit_adr(ia32_emit_env_t *env, const ir_node *node);
 void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node);
-void ia32_emit_finish_line(ia32_emit_env_t *env, const ir_node *node);
-
-void ia32_gen_routine(ia32_code_gen_t *cg, FILE *F, ir_graph *irg);
-
-/**
- * Sections.
- */
-typedef enum section_t {
-       NO_SECTION     = -1,  /**< no section selected yet. */
-       SECTION_TEXT   = 0,   /**< text section */
-       SECTION_DATA   = 1,   /**< data section */
-       SECTION_RODATA = 2,   /**< rodata section */
-       SECTION_COMMON = 3,   /**< common section */
-       SECTION_TLS    = 4,   /**< thread local storage section */
-       SECTION_CTOR   = 5,   /**< ctor section for instrumentation code init */
-       SECTION_MAX    = 6
-} section_t;
-
-/**
- * Switch to a new section.
- */
-void ia32_switch_section(FILE *f, section_t sec);
-
-typedef enum asm_flavour_t {
-       ASM_LINUX_GAS = 0,  /**< Linux gas */
-       ASM_MINGW_GAS = 1,  /**< MinGW gas */
-       ASM_MAX       = 2
-} asm_flavour_t;
 
-extern asm_flavour_t asm_flavour;
+void ia32_gen_routine(ia32_code_gen_t *cg, ir_graph *irg);
 
 #endif /* _IA32_EMITTER_H_ */
index 0eb6d1d..7d36472 100644 (file)
@@ -243,7 +243,7 @@ static INLINE int need_constraint_copy(ir_node *irn) {
  */
 static void ia32_finish_node(ir_node *irn, void *env) {
        ia32_code_gen_t            *cg = env;
-       const ia32_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t      *out_reg, *in_reg, *in2_reg;
        int                         n_res, i;
        ir_node                    *copy, *in_node, *block, *in2_node;
@@ -263,10 +263,12 @@ static void ia32_finish_node(ir_node *irn, void *env) {
                if ((op_tp == ia32_Normal || op_tp == ia32_AddrModeS) && need_constraint_copy(irn))
                {
                        for (i = 0; i < n_res; i++) {
-                               if (arch_register_req_is(&(reqs[i]->req), should_be_same)) {
+                               if (arch_register_req_is(reqs[i], should_be_same)) {
+                                       int same_pos = reqs[i]->other_same;
+
                                        /* get in and out register */
                                        out_reg  = get_ia32_out_reg(irn, i);
-                                       in_node  = get_irn_n(irn, reqs[i]->same_pos);
+                                       in_node  = get_irn_n(irn, same_pos);
                                        in_reg   = arch_get_irn_register(cg->arch_env, in_node);
 
                                        /* don't copy ignore nodes */
@@ -279,19 +281,19 @@ static void ia32_finish_node(ir_node *irn, void *env) {
                                                /* beware: the current op could be everything, so test for ia32 */
                                                /*         commutativity first before getting the second in     */
                                                if (is_ia32_commutative(irn)) {
-                                                       in2_node = get_irn_n(irn, reqs[i]->same_pos ^ 1);
+                                                       in2_node = get_irn_n(irn, same_pos ^ 1);
                                                        in2_reg  = arch_get_irn_register(cg->arch_env, in2_node);
 
                                                        if (REGS_ARE_EQUAL(out_reg, in2_reg)) {
-                                                               set_irn_n(irn, reqs[i]->same_pos, in2_node);
-                                                               set_irn_n(irn, reqs[i]->same_pos ^ 1, in_node);
+                                                               set_irn_n(irn, same_pos, in2_node);
+                                                               set_irn_n(irn, same_pos ^ 1, in_node);
                                                        }
                                                        else
                                                                goto insert_copy;
                                                }
                                                else {
 insert_copy:
-                                                       DBG((cg->mod, LEVEL_1, "inserting copy for %+F in_pos %d\n", irn, reqs[i]->same_pos));
+                                                       DBG((cg->mod, LEVEL_1, "inserting copy for %+F in_pos %d\n", irn, same_pos));
                                                        /* create copy from in register */
                                                        copy = be_new_Copy(arch_register_get_class(in_reg), cg->irg, block, in_node);
 
@@ -304,7 +306,7 @@ insert_copy:
                                                        sched_add_before(irn, copy);
 
                                                        /* set copy as in */
-                                                       set_irn_n(irn, reqs[i]->same_pos, copy);
+                                                       set_irn_n(irn, same_pos, copy);
                                                }
                                        }
                                }
@@ -334,22 +336,6 @@ insert_copy:
                                set_ia32_pncode(irn, get_negated_pnc(pnc, mode_E));
                        }
                }
-
-               /*
-                       If we have a CondJmp/CmpSet/xCmpSet with immediate,
-                       we need to check if it's the right operand, otherwise
-                       we have to change it, as CMP doesn't support immediate
-                       as left operands.
-               */
-#if 0
-               if ((is_ia32_CondJmp(irn) || is_ia32_CmpSet(irn) || is_ia32_xCmpSet(irn)) &&
-                       (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn))                   &&
-                       op_tp == ia32_AddrModeS)
-               {
-                       set_ia32_op_type(irn, ia32_AddrModeD);
-                       set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn)));
-               }
-#endif
        }
 end: ;
 }
@@ -366,7 +352,7 @@ static void fix_am_source(ir_node *irn, void *env) {
        ia32_code_gen_t *cg = env;
        ir_node *base, *index, *noreg;
        const arch_register_t *reg_base, *reg_index;
-       const ia32_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        int n_res, i;
 
        /* check only ia32 nodes with source address mode */
@@ -388,15 +374,16 @@ static void fix_am_source(ir_node *irn, void *env) {
        n_res = get_ia32_n_res(irn);
 
        for (i = 0; i < n_res; i++) {
-               if (arch_register_req_is(&(reqs[i]->req), should_be_same)) {
+               if (arch_register_req_is(reqs[i], should_be_same)) {
                        /* get in and out register */
                        const arch_register_t *out_reg  = get_ia32_out_reg(irn, i);
+                       int same_pos = reqs[i]->other_same;
 
                        /*
                                there is a constraint for the remaining operand
                                and the result register is equal to base or index register
                        */
-                       if (reqs[i]->same_pos == 2 &&
+                       if (same_pos == 2 &&
                                (REGS_ARE_EQUAL(out_reg, reg_base) || REGS_ARE_EQUAL(out_reg, reg_index)))
                        {
                                /* turn back address mode */
diff --git a/ir/be/ia32/ia32_gen_decls.c b/ir/be/ia32/ia32_gen_decls.c
deleted file mode 100644 (file)
index 9b8c644..0000000
+++ /dev/null
@@ -1,670 +0,0 @@
-/**
- * Dumps global variables and constants as ia32 assembler.
- * @author Christian Wuerdig
- * @date 04.11.2005
- * @version $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "obst.h"
-#include "tv.h"
-#include "irnode.h"
-#include "entity.h"
-#include "irprog.h"
-#include "error.h"
-
-#include "../be.h"
-
-#include "ia32_emitter.h"
-#include "ia32_gen_decls.h"
-
-typedef struct obstack obstack_t;
-
-typedef struct _ia32_decl_env {
-       obstack_t *rodata_obst;
-       obstack_t *data_obst;
-       obstack_t *bss_obst;
-       obstack_t *ctor_obst;
-       const be_main_env_t *main_env;
-} ia32_decl_env_t;
-
-/************************************************************************/
-
-/**
- * output a tarval
- */
-static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
-{
-       switch (bytes) {
-
-       case 1:
-               obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
-               break;
-
-       case 2:
-               obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-               break;
-
-       case 4:
-               obstack_printf(obst, "0x%02x%02x%02x%02x",
-                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-               break;
-
-       case 8:
-               obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
-                       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
-                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-               break;
-
-       case 10:
-       case 12:
-               break;
-
-       case 16:
-               obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
-                                              "%02x%02x%02x%02x%02x%02x%02x%02x",
-                       get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
-                       get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
-                       get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
-                       get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
-                       get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
-                       get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
-                       get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
-                       get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
-               break;
-
-
-       default:
-               fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
-               assert(0);
-       }
-}
-
-/**
- * Return the tarval of an atomic initializer.
- */
-static tarval *get_atomic_init_tv(ir_node *init)
-{
-       for (;;) {
-               ir_mode *mode = get_irn_mode(init);
-
-               switch (get_irn_opcode(init)) {
-
-               case iro_Cast:
-                       init = get_Cast_op(init);
-                       continue;
-
-               case iro_Conv:
-                       init = get_Conv_op(init);
-                       continue;
-
-               case iro_Const:
-                       return get_Const_tarval(init);
-
-               case iro_SymConst:
-                       switch (get_SymConst_kind(init)) {
-                       case symconst_ofs_ent:
-                               return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
-
-                       case symconst_type_size:
-                               return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
-
-                       case symconst_type_align:
-                               return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
-
-                       case symconst_enum_const:
-                               return get_enumeration_value(get_SymConst_enum(init));
-
-                       default:
-                               return NULL;
-                       }
-
-               default:
-                       return NULL;
-               }
-       }
-}
-
-/**
- * dump an atomic value
- */
-static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
-{
-       ir_mode *mode = get_irn_mode(init);
-       int bytes     = get_mode_size_bytes(mode);
-       tarval *tv;
-
-       switch (get_irn_opcode(init)) {
-
-       case iro_Cast:
-               do_dump_atomic_init(obst, get_Cast_op(init));
-               return;
-
-       case iro_Conv:
-               do_dump_atomic_init(obst, get_Conv_op(init));
-               return;
-
-       case iro_Const:
-               tv = get_Const_tarval(init);
-
-               /* it's a arithmetic value */
-               dump_arith_tarval(obst, tv, bytes);
-               return;
-
-       case iro_SymConst:
-               switch (get_SymConst_kind(init)) {
-               case symconst_addr_name:
-                       obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
-                       break;
-
-               case symconst_addr_ent:
-                       obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
-                       break;
-
-               case symconst_ofs_ent:
-                       obstack_printf(obst, "%d", get_entity_offset(get_SymConst_entity(init)));
-                       break;
-
-               case symconst_type_size:
-                       obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
-                       break;
-
-               case symconst_type_align:
-                       obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
-                       break;
-
-               case symconst_enum_const:
-                       tv = get_enumeration_value(get_SymConst_enum(init));
-                       dump_arith_tarval(obst, tv, bytes);
-                       break;
-
-               default:
-                       assert(!"dump_atomic_init(): don't know how to init from this SymConst");
-               }
-               return;
-
-               case iro_Add:
-                       do_dump_atomic_init(obst, get_Add_left(init));
-                       obstack_printf(obst, " + ");
-                       do_dump_atomic_init(obst, get_Add_right(init));
-                       return;
-
-               case iro_Sub:
-                       do_dump_atomic_init(obst, get_Sub_left(init));
-                       obstack_printf(obst, " - ");
-                       do_dump_atomic_init(obst, get_Sub_right(init));
-                       return;
-
-               case iro_Mul:
-                       do_dump_atomic_init(obst, get_Mul_left(init));
-                       obstack_printf(obst, " * ");
-                       do_dump_atomic_init(obst, get_Mul_right(init));
-                       return;
-
-               default:
-                       assert(0 && "dump_atomic_init(): unknown IR-node");
-       }
-}
-
-/**
- * dumps the type for given size (.byte, .long, ...)
- */
-static void dump_size_type(obstack_t *obst, int size) {
-       switch (size) {
-
-       case 1:
-               obstack_printf(obst, "\t.byte\t");
-               break;
-
-       case 2:
-               obstack_printf(obst, "\t.value\t");
-               break;
-
-       case 4:
-               obstack_printf(obst, "\t.long\t");
-               break;
-
-       case 8:
-               obstack_printf(obst, "\t.quad\t");
-               break;
-
-       case 10:
-       case 12:
-               /* handled in arith */
-               break;
-
-       case 16:
-               obstack_printf(obst, "\t.octa\t");
-               break;
-
-       default:
-               fprintf(stderr, "Try to dump a type with %d bytes\n", size);
-               assert(0);
-       }
-}
-
-/**
- * dump an atomic value to an obstack
- */
-static void dump_atomic_init(obstack_t *obst, ir_node *init)
-{
-       ir_mode *mode = get_irn_mode(init);
-       int bytes     = get_mode_size_bytes(mode);
-
-       dump_size_type(obst, bytes);
-       do_dump_atomic_init(obst, init);
-       obstack_printf(obst, "\n");
-}
-
-/************************************************************************/
-/* Routines to dump global variables                                    */
-/************************************************************************/
-
-/**
- * Determine if an entity is a string constant
- * @param ent The entity
- * @return 1 if it is a string constant, 0 otherwise
- */
-static int ent_is_string_const(ir_entity *ent)
-{
-       ir_type *type, *element_type;
-       ir_mode *mode;
-       int i, c, n;
-
-       type = get_entity_type(ent);
-
-       /* if it's an array */
-       if (!is_Array_type(type))
-               return 0;
-
-       element_type = get_array_element_type(type);
-
-       /* and the array's element type is primitive */
-       if (!is_Primitive_type(element_type))
-               return 0;
-
-       /* and the mode of the element type is an int of
-        * the same size as the byte mode */
-       mode = get_type_mode(element_type);
-       if (!mode_is_int(mode)
-               || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
-               return 0;
-
-       /* if it contains only printable chars and a 0 at the end */
-       n = get_compound_ent_n_values(ent);
-       for (i = 0; i < n; ++i) {
-               ir_node *irn = get_compound_ent_value(ent, i);
-               if(get_irn_opcode(irn) != iro_Const)
-                       return 0;
-
-               c = (int) get_tarval_long(get_Const_tarval(irn));
-
-               if((i < n - 1 && !(isgraph(c) || isspace(c)))
-                               || (i == n - 1 && c != '\0'))
-                       return 0;
-       }
-
-       /* then we can emit it as a string constant */
-       return 1;
-}
-
-/**
- * Dump a string constant.
- * No checks are made!!
- * @param obst The obst to dump on.
- * @param ent The entity to dump.
- */
-static void dump_string_cst(obstack_t *obst, ir_entity *ent)
-{
-       int i, n;
-
-       obstack_printf(obst, "\t.string \"");
-       n = get_compound_ent_n_values(ent);
-
-       for (i = 0; i < n-1; ++i) {
-               ir_node *irn;
-               int c;
-
-               irn = get_compound_ent_value(ent, i);
-               c = (int) get_tarval_long(get_Const_tarval(irn));
-
-               switch (c) {
-               case '"' : obstack_printf(obst, "\\\""); break;
-               case '\n': obstack_printf(obst, "\\n"); break;
-               case '\r': obstack_printf(obst, "\\r"); break;
-               case '\t': obstack_printf(obst, "\\t"); break;
-               case '\\': obstack_printf(obst, "\\\\"); break;
-               default  :
-                       if (isprint(c))
-                               obstack_printf(obst, "%c", c);
-                       else
-                               obstack_printf(obst, "\\%o", c);
-                       break;
-               }
-       }
-       obstack_printf(obst, "\"\n");
-}
-
-static void dump_array_init(obstack_t *obst, ir_entity *ent)
-{
-       const ir_type *ty = get_entity_type(ent);
-       int i;
-       int filler;
-       int size = 0;
-
-       /* potential spare values should be already included! */
-       for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
-               ir_entity *step = get_compound_ent_value_member(ent, i);
-               ir_type *stype = get_entity_type(step);
-
-               if (get_type_mode(stype)) {
-                       int align = (get_type_alignment_bits(stype) + 7) >> 3;
-                       int n     = size % align;
-
-                       if (n > 0) {
-                               obstack_printf(obst, "\t.zero\t%d\n", align - n);
-                               size += align - n;
-                       }
-               }
-               dump_atomic_init(obst, get_compound_ent_value(ent, i));
-               size += get_type_size_bytes(stype);
-       }
-       filler = get_type_size_bytes(ty) - size;
-
-       if (filler > 0)
-               obstack_printf(obst, "\t.skip\t%d\n", filler);
-}
-
-enum normal_or_bitfield_kind {
-       NORMAL = 0,
-       BITFIELD
-};
-
-typedef struct {
-       enum normal_or_bitfield_kind kind;
-       union {
-               ir_node *value;
-               unsigned char bf_val;
-       } v;
-} normal_or_bitfield;
-
-/**
- * Dump an initializer for a compound entity.
- */
-static void dump_compound_init(obstack_t *obst, ir_entity *ent)
-{
-       normal_or_bitfield *vals;
-       int i, j, n = get_compound_ent_n_values(ent);
-       int last_ofs;
-
-       /* Find the initializer size. Sorrily gcc support a nasty feature:
-          The last field of a compound may be a flexible array. This allows
-          initializers bigger than the type size. */
-       last_ofs = 0;
-       for (i = 0; i < n; ++i) {
-               int offset = get_compound_ent_value_offset_bytes(ent, i);
-               int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
-               const compound_graph_path *path = get_compound_ent_value_path(ent, i);
-               int path_len = get_compound_graph_path_length(path);
-               ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
-               int value_len = get_type_size_bits(get_entity_type(last_ent));
-
-               offset += (value_len + bits_remainder + 7) >> 3;
-
-               if (offset > last_ofs) {
-                       last_ofs = offset;
-               }
-       }
-
-       /*
-        * In the worst case, every initializer allocates one byte.
-        * Moreover, initializer might be big, do not allocate an stack.
-        */
-       vals = xcalloc(last_ofs, sizeof(vals[0]));
-
-       /* collect the values and store them at the offsets */
-       for (i = 0; i < n; ++i) {
-               const compound_graph_path *path = get_compound_ent_value_path(ent, i);
-               int path_len = get_compound_graph_path_length(path);
-               int offset = get_compound_ent_value_offset_bytes(ent, i);
-               int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
-               ir_node *value = get_compound_ent_value(ent, i);
-               ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
-               int value_len = get_type_size_bits(get_entity_type(last_ent));
-               assert(offset >= 0);
-               assert(offset_bits >= 0);
-
-               if (offset_bits != 0 ||
-                       (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
-                       tarval *shift, *shifted;
-                       tarval *tv = get_atomic_init_tv(value);
-                       if (tv == NULL) {
-                               panic("Couldn't get numeric value for bitfield initializer '%s'\n",
-                                     get_entity_ld_name(ent));
-                       }
-                       tv = tarval_convert_to(tv, mode_Lu);
-                       shift = new_tarval_from_long(offset_bits, mode_Is);
-                       shifted = tarval_shl(tv, shift);
-                       if (shifted == tarval_bad || shifted == tarval_undefined) {
-                               panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
-                                     get_entity_ld_name(ent));
-                       }
-
-                       for (j = 0; value_len > 0; ++j) {
-                               assert(offset + j < last_ofs);
-                               assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
-                               vals[offset + j].kind = BITFIELD;
-                               vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
-                               value_len -= 8 - offset_bits;
-                               offset_bits = 0;
-                       }
-               } else {
-                       assert(offset < last_ofs);
-                       assert(vals[offset].kind == NORMAL);
-                       assert(vals[offset].v.value == NULL);
-                       vals[offset].v.value = value;
-               }
-       }
-
-       /* now write them sorted */
-       for (i = 0; i < last_ofs; ) {
-               int space = 0, skip = 0;
-               if (vals[i].kind == NORMAL) {
-                       if(vals[i].v.value != NULL) {
-                               dump_atomic_init(obst, vals[i].v.value);
-                               skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
-                       } else {
-                               space = 1;
-                       }
-               } else {
-                       assert(vals[i].kind == BITFIELD);
-                       obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
-               }
-
-               ++i;
-               space = 0;
-               while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
-                       ++space;
-                       ++i;
-               }
-               space -= skip;
-               assert(space >= 0);
-
-               /* a gap */
-               if (space > 0)
-                       obstack_printf(obst, "\t.skip\t%d\n", space);
-       }
-       xfree(vals);
-}
-
-/**
- * Dump a global entity.
- */
-static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
-{
-       obstack_t *obst;
-       ir_type *type = get_entity_type(ent);
-       const char *ld_name = get_entity_ld_name(ent);
-       ir_variability variability = get_entity_variability(ent);
-       ir_visibility visibility = get_entity_visibility(ent);
-       int align = get_type_alignment_bytes(type);
-       int emit_as_common = 0;
-
-       obst = env->data_obst;
-       if (is_Method_type(type)) {
-               if (get_method_img_section(ent) == section_constructors) {
-                       obst = env->ctor_obst;
-                       obstack_printf(obst, ".balign\t%d\n", align);
-                       dump_size_type(obst, align);
-                       obstack_printf(obst, "%s\n", ld_name);
-               }
-               return;
-       } else if (variability == variability_constant) {
-               /* a constant entity, put it on the rdata */
-               obst = env->rodata_obst;
-       } else if (variability == variability_uninitialized) {
-               /* uninitialized entity put it in bss segment */
-               obst = env->bss_obst;
-               if(emit_commons && visibility != visibility_local)
-                       emit_as_common = 1;
-       }
-
-       be_dbg_variable(env->main_env->db_handle, obst, ent);
-
-       /* global or not global */
-       if (visibility == visibility_external_visible && !emit_as_common) {
-               obstack_printf(obst, ".global\t%s\n", ld_name);
-       } else if(visibility == visibility_external_allocated) {
-               obstack_printf(obst, ".global\t%s\n", ld_name);
-               /* we can return now... */
-               return;
-       }
-       /* alignment */
-       if (align > 1 && !emit_as_common) {
-               obstack_printf(obst, ".balign\t%d\n", align);
-       }
-
-       if (!emit_as_common) {
-               obstack_printf(obst, "%s:\n", ld_name);
-       }
-
-       if (variability == variability_uninitialized) {
-               if(emit_as_common) {
-                       obstack_printf(obst, "\t.comm %s,%d,%d\n",
-                                       ld_name, get_type_size_bytes(type), align);
-               } else {
-                       obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
-               }
-       } else if (is_atomic_type(type)) {
-               dump_atomic_init(obst, get_atomic_ent_value(ent));
-       } else if (ent_is_string_const(ent)) {
-               dump_string_cst(obst, ent);
-       } else if (is_Array_type(type)) {
-               dump_array_init(obst, ent);
-       } else if (is_compound_type(type)) {
-               dump_compound_init(obst, ent);
-       } else {
-               assert(0 && "unsupported type");
-       }
-}
-
-/**
- * Dumps declarations of global variables and the initialization code.
- */
-static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env, int emit_commons)
-{
-       int i, n = get_compound_n_members(gt);
-
-       for (i = 0; i < n; i++) {
-               ir_entity *ent = get_compound_member(gt, i);
-               dump_global(env, ent, emit_commons);
-       }
-}
-
-/************************************************************************/
-
-void ia32_gen_decls(FILE *out, const be_main_env_t *main_env) {
-       ia32_decl_env_t env;
-       obstack_t rodata, data, bss, ctor;
-       int    size;
-       char   *cp;
-
-       /* dump the global type */
-       obstack_init(&rodata);
-       obstack_init(&data);
-       obstack_init(&bss);
-
-       if (main_env->options->opt_profile)
-               obstack_init(&ctor);
-
-       env.rodata_obst = &rodata;
-       env.data_obst   = &data;
-       env.bss_obst    = &bss;
-       env.ctor_obst   = main_env->options->opt_profile ? &ctor : NULL;
-       env.main_env    = main_env;
-
-       ia32_dump_globals(get_glob_type(), &env, 1);
-
-       size = obstack_object_size(&data);
-       cp   = obstack_finish(&data);
-       if (size > 0) {
-               ia32_switch_section(out, SECTION_DATA);
-               fwrite(cp, 1, size, out);
-       }
-
-       size = obstack_object_size(&rodata);
-       cp   = obstack_finish(&rodata);
-       if (size > 0) {
-               ia32_switch_section(out, SECTION_RODATA);
-               fwrite(cp, 1, size, out);
-       }
-
-       size = obstack_object_size(&bss);
-       cp   = obstack_finish(&bss);
-       if (size > 0) {
-               ia32_switch_section(out, SECTION_COMMON);
-               fwrite(cp, 1, size, out);
-       }
-
-       if (main_env->options->opt_profile) {
-               size = obstack_object_size(&ctor);
-               cp   = obstack_finish(&ctor);
-               if (size > 0) {
-                       ia32_switch_section(out, SECTION_CTOR);
-                       fwrite(cp, 1, size, out);
-               }
-               obstack_free(&ctor, NULL);
-       }
-
-       obstack_free(&rodata, NULL);
-       obstack_free(&data, NULL);
-       obstack_free(&bss, NULL);
-
-       /* dump the Thread Local Storage */
-       obstack_init(&data);
-
-       env.rodata_obst = &data;
-       env.data_obst   = &data;
-       env.bss_obst   = &data;
-       env.ctor_obst   = NULL;
-
-       ia32_dump_globals(get_tls_type(), &env, 0);
-
-       size = obstack_object_size(&data);
-       cp   = obstack_finish(&data);
-       if (size > 0) {
-               ia32_switch_section(out, SECTION_TLS);
-               fprintf(out, ".balign\t%d\n", 32);
-               fwrite(cp, 1, size, out);
-       }
-
-       obstack_free(&data, NULL);
-}
diff --git a/ir/be/ia32/ia32_gen_decls.h b/ir/be/ia32/ia32_gen_decls.h
deleted file mode 100644 (file)
index 88a5960..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Header for ia32 assembler declarations dumper.
- * @author Christian Wuerdig
- * $Id$
- */
-
-#ifndef _IA32_GEN_DECLS_H_
-#define _IA32_GEN_DECLS_H_
-
-#include "../be.h"
-
-/**
- * Generate all entities.
- */
-void ia32_gen_decls(FILE *out, const be_main_env_t *main_env);
-
-#endif /* _IA32_GEN_DECLS_H_ */
index 3c7db40..fb614d9 100644 (file)
@@ -4,9 +4,8 @@
  * @author Christian Wuerdig
  * $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
@@ -31,6 +30,7 @@
 #include "irprintf.h"
 #include "iredges.h"
 #include "error.h"
+#include "raw_bitset.h"
 
 #include "../bearch.h"
 
@@ -96,69 +96,41 @@ int ia32_has_x87_register(const ir_node *n) {
  *                       |_|
  ***********************************************************************************/
 
-/**
- * Returns a string containing the names of all registers within the limited bitset
- */
-static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
-       bitset_t *bs   = bitset_alloca(req->cls->n_regs);
-       char     *p    = buf;
-       int       size = 0;
-       int       i, cnt;
-
-       req->limited(NULL, bs);
-
-       for (i = 0; i < req->cls->n_regs; i++) {
-               if (bitset_is_set(bs, i)) {
-                       cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
-                       if (cnt < 0) {
-                               fprintf(stderr, "dumper problem, exiting\n");
-                               exit(1);
-                       }
-
-                       p    += cnt;
-                       size += cnt;
-
-                       if (size >= max)
-                               break;
-               }
-       }
-
-       return buf;
-}
-
 /**
  * Dumps the register requirements for either in or out.
  */
-static void dump_reg_req(FILE *F, ir_node *n, const ia32_register_req_t **reqs, int inout) {
+static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
+                         int inout) {
        char *dir = inout ? "out" : "in";
        int   max = inout ? get_ia32_n_res(n) : get_irn_arity(n);
-       char *buf = alloca(1024);
+       char  buf[1024];
        int   i;
 
-       memset(buf, 0, 1024);
+       memset(buf, 0, sizeof(buf));
 
        if (reqs) {
                for (i = 0; i < max; i++) {
                        fprintf(F, "%sreq #%d =", dir, i);
 
-                       if (reqs[i]->req.type == arch_register_req_type_none) {
+                       if (reqs[i]->type == arch_register_req_type_none) {
                                fprintf(F, " n/a");
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_normal) {
-                               fprintf(F, " %s", reqs[i]->req.cls->name);
+                       if (reqs[i]->type & arch_register_req_type_normal) {
+                               fprintf(F, " %s", reqs[i]->cls->name);
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_limited) {
-                               fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
+                       if (reqs[i]->type & arch_register_req_type_limited) {
+                               fprintf(F, " %s",
+                                       arch_register_req_format(buf, sizeof(buf), reqs[i], n));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
-                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_same) {
+                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
-                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_different) {
+                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different));
                        }
 
                        fprintf(F, "\n");
@@ -182,7 +154,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
        ir_mode     *mode = NULL;
        int          bad  = 0;
        int          i, n_res, am_flav, flags;
-       const ia32_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t     **slots;
 
        switch (reason) {
@@ -794,7 +766,7 @@ void set_ia32_latency(ir_node *node, unsigned latency) {
 /**
  * Returns the argument register requirements of an ia32 node.
  */
-const ia32_register_req_t **get_ia32_in_req_all(const ir_node *node) {
+const arch_register_req_t **get_ia32_in_req_all(const ir_node *node) {
        ia32_attr_t *attr = get_ia32_attr(node);
        return attr->in_req;
 }
@@ -802,7 +774,7 @@ const ia32_register_req_t **get_ia32_in_req_all(const ir_node *node) {
 /**
  * Sets the argument register requirements of an ia32 node.
  */
-void set_ia32_in_req_all(ir_node *node, const ia32_register_req_t **reqs) {
+void set_ia32_in_req_all(ir_node *node, const arch_register_req_t **reqs) {
        ia32_attr_t *attr = get_ia32_attr(node);
        attr->in_req      = reqs;
 }
@@ -810,7 +782,7 @@ void set_ia32_in_req_all(ir_node *node, const ia32_register_req_t **reqs) {
 /**
  * Returns the result register requirements of an ia32 node.
  */
-const ia32_register_req_t **get_ia32_out_req_all(const ir_node *node) {
+const arch_register_req_t **get_ia32_out_req_all(const ir_node *node) {
        ia32_attr_t *attr = get_ia32_attr(node);
        return attr->out_req;
 }
@@ -818,7 +790,7 @@ const ia32_register_req_t **get_ia32_out_req_all(const ir_node *node) {
 /**
  * Sets the result register requirements of an ia32 node.
  */
-void set_ia32_out_req_all(ir_node *node, const ia32_register_req_t **reqs) {
+void set_ia32_out_req_all(ir_node *node, const arch_register_req_t **reqs) {
        ia32_attr_t *attr = get_ia32_attr(node);
        attr->out_req     = reqs;
 }
@@ -826,23 +798,29 @@ void set_ia32_out_req_all(ir_node *node, const ia32_register_req_t **reqs) {
 /**
  * Returns the argument register requirement at position pos of an ia32 node.
  */
-const ia32_register_req_t *get_ia32_in_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_ia32_in_req(const ir_node *node, int pos) {
        ia32_attr_t *attr = get_ia32_attr(node);
-       return attr->in_req != NULL ? attr->in_req[pos] : NULL;
+       if(attr->in_req == NULL)
+               return arch_no_register_req;
+
+       return attr->in_req[pos];
 }
 
 /**
  * Returns the result register requirement at position pos of an ia32 node.
  */
-const ia32_register_req_t *get_ia32_out_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_ia32_out_req(const ir_node *node, int pos) {
        ia32_attr_t *attr = get_ia32_attr(node);
-       return attr->out_req != NULL ? attr->out_req[pos] : NULL;
+       if(attr->out_req == NULL)
+               return arch_no_register_req;
+
+       return attr->out_req[pos];
 }
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_ia32_req_out(ir_node *node, const ia32_register_req_t *req, int pos) {
+void set_ia32_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
        ia32_attr_t *attr  = get_ia32_attr(node);
        attr->out_req[pos] = req;
 }
@@ -850,7 +828,7 @@ void set_ia32_req_out(ir_node *node, const ia32_register_req_t *req, int pos) {
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_ia32_req_in(ir_node *node, const ia32_register_req_t *req, int pos) {
+void set_ia32_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
        ia32_attr_t *attr = get_ia32_attr(node);
        attr->in_req[pos] = req;
 }
@@ -1151,9 +1129,11 @@ const arch_register_t *get_ia32_out_reg(const ir_node *node, int pos) {
 /**
  * Initializes the nodes attributes.
  */
-void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const ia32_register_req_t **in_reqs,
-                                                 const ia32_register_req_t **out_reqs, const be_execution_unit_t ***execution_units,
-                                                 int n_res, unsigned latency)
+void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
+                          const arch_register_req_t **in_reqs,
+                          const arch_register_req_t **out_reqs,
+                          const be_execution_unit_t ***execution_units,
+                          int n_res, unsigned latency)
 {
        ia32_attr_t *attr = get_ia32_attr(node);
 
index 736e3e9..b4eed64 100644 (file)
@@ -236,42 +236,42 @@ void set_ia32_frame_ent(ir_node *node, ir_entity *ent);
 /**
  * Returns the argument register requirements of an ia32 node.
  */
-const ia32_register_req_t **get_ia32_in_req_all(const ir_node *node);
+const arch_register_req_t **get_ia32_in_req_all(const ir_node *node);
 
 /**
  * Sets the argument register requirements of an ia32 node.
  */
-void set_ia32_in_req_all(ir_node *node, const ia32_register_req_t **reqs);
+void set_ia32_in_req_all(ir_node *node, const arch_register_req_t **reqs);
 
 /**
  * Returns the result register requirements of an ia32 node.
  */
-const ia32_register_req_t **get_ia32_out_req_all(const ir_node *node);
+const arch_register_req_t **get_ia32_out_req_all(const ir_node *node);
 
 /**
  * Sets the result register requirements of an ia32 node.
  */
-void set_ia32_out_req_all(ir_node *node, const ia32_register_req_t **reqs);
+void set_ia32_out_req_all(ir_node *node, const arch_register_req_t **reqs);
 
 /**
  * Returns the argument register requirements of an ia32 node.
  */
-const ia32_register_req_t *get_ia32_in_req(const ir_node *node, int pos);
+const arch_register_req_t *get_ia32_in_req(const ir_node *node, int pos);
 
 /**
  * Returns the result register requirements of an ia32 node.
  */
-const ia32_register_req_t *get_ia32_out_req(const ir_node *node, int pos);
+const arch_register_req_t *get_ia32_out_req(const ir_node *node, int pos);
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_ia32_req_out(ir_node *node, const ia32_register_req_t *req, int pos);
+void set_ia32_req_out(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_ia32_req_in(ir_node *node, const ia32_register_req_t *req, int pos);
+void set_ia32_req_in(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Returns the register flag of an ia32 node.
@@ -453,8 +453,11 @@ int is_ia32_Cnst(const ir_node *node);
 /**
  * Initializes the nodes attributes.
  */
-void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const ia32_register_req_t **in_reqs, \
-       const ia32_register_req_t **out_reqs, const be_execution_unit_t ***execution_units, int n_res, unsigned latency);
+void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
+                          const arch_register_req_t **in_reqs,
+                          const arch_register_req_t **out_reqs,
+                          const be_execution_unit_t ***execution_units,
+                          int n_res, unsigned latency);
 
 /**
  * Registers the ia32_copy_attr function for all ia32 opcodes.
index f5d1de5..d8ec996 100644 (file)
@@ -65,12 +65,6 @@ typedef enum {
        ia32_am_OBIS = ia32_O | ia32_B | ia32_I | ia32_S
 } ia32_am_flavour_t;
 
-typedef struct _ia32_register_req_t {
-       const arch_register_req_t req;
-       int same_pos;        /**< in case of "should be same" we need to remember the pos to get the irn */
-       int different_pos;   /**< in case of "should be different" we need to remember the pos to get the irn */
-} ia32_register_req_t;
-
 enum {
        ia32_pn_Cmp_Unsigned = 0x100 /**< set this flag in a pnc to indicate an unsigned compare operation */
 };
@@ -127,8 +121,8 @@ typedef struct _ia32_attr_t {
 
        const be_execution_unit_t ***exec_units; /**< list of units this operation can be executed on */
 
-       const ia32_register_req_t **in_req;  /**< register requirements for arguments */
-       const ia32_register_req_t **out_req; /**< register requirements for results */
+       const arch_register_req_t **in_req;  /**< register requirements for arguments */
+       const arch_register_req_t **out_req; /**< register requirements for results */
 
        const arch_register_t *x87[3];       /**< register slots for x87 register */
 
index 8ca4d41..9830a7b 100644 (file)
@@ -128,7 +128,7 @@ $arch = "ia32";
                { "name" => "xmm7", "type" => 1 },
                { "name" => "xmm_NOREG", "type" => 4 | 16 },     # we need a dummy register for NoReg nodes
                { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-               { "mode" => "mode_LLu" }
+               { "mode" => "mode_E" }
        ],
        "vfp" => [
                { "name" => "vf0", "type" => 1 | 16 },
@@ -198,7 +198,7 @@ $arch = "ia32";
        "C"  => "${arch}_emit_immediate(env, node);",
        "SE" => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));",
        "ME" => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n
-       ${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
+       ia32_emit_mode_suffix(env, get_ia32_ls_mode(node));",
        "M"  => "${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
        "XM" => "${arch}_emit_x87_mode_suffix(env, node);",
        "XXM" => "${arch}_emit_xmm_mode_suffix(env, node);",
@@ -835,7 +835,7 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
   "emit"      => '. mov%M %binop',
   "latency"   => 3,
   "units"     => [ "GP" ],
@@ -846,7 +846,7 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct 8Bit Store: Store(ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ], "out" => ["none" ] },
   "emit"      => '. mov%M %binop',
   "latency"   => 3,
   "units"     => [ "GP" ],
@@ -1951,5 +1951,4 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
 ); # end of %nodes
 
 # Include the generated SIMD node specification written by the SIMD optimization
-
-do "../ir/be/ia32/ia32_simd_spec.pl";
+#do "../ir/be/ia32/ia32_simd_spec.pl";
index 727603f..91ae7e5 100644 (file)
@@ -55,101 +55,54 @@ static set *cur_reg_set = NULL;
  *           |___/
  **************************************************/
 
-static ir_node *my_skip_proj(const ir_node *n) {
-       while (is_Proj(n))
-               n = get_Proj_pred(n);
-       return (ir_node *)n;
-}
-
 /**
  * Return register requirements for a mips node.
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *mips_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
-       const mips_register_req_t *irn_req;
+static const
+arch_register_req_t *mips_get_irn_reg_req(const void *self,
+                                          const ir_node *node, int pos) {
        long               node_pos = pos == -1 ? 0 : pos;
-       ir_mode           *mode     = get_irn_mode(irn);
-       FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
+       ir_mode           *mode     = get_irn_mode(node);
 
-       if (is_Block(irn) || mode == mode_X || mode == mode_M) {
-               DBG((mod, LEVEL_1, "ignoring mode_T, mode_M node %+F\n", irn));
-               return NULL;
+       if (is_Block(node) || mode == mode_X || mode == mode_M) {
+               return arch_no_register_req;
        }
 
        if (mode == mode_T && pos < 0) {
-               DBG((mod, LEVEL_1, "ignoring request for OUT requirements at %+F\n", irn));
-               return NULL;
+               return arch_no_register_req;
        }
 
-       DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
-
-       if (is_Proj(irn)) {
+       if (is_Proj(node)) {
                /* in case of a proj, we need to get the correct OUT slot */
                /* of the node corresponding to the proj number */
                if (pos == -1) {
-                       node_pos = mips_translate_proj_pos(irn);
+                       node_pos = mips_translate_proj_pos(node);
                }
                else {
                        node_pos = pos;
                }
 
-               irn = my_skip_proj(irn);
-
-               DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
+               node = skip_Proj_const(node);
        }
 
        /* get requirements for our own nodes */
-       if (is_mips_irn(irn)) {
+       if (is_mips_irn(node)) {
+               const arch_register_req_t *req;
                if (pos >= 0) {
-                       irn_req = get_mips_in_req(irn, pos);
-               }
-               else {
-                       irn_req = get_mips_out_req(irn, node_pos);
-               }
-
-               DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
-
-               memcpy(req, &(irn_req->req), sizeof(*req));
-
-               if (arch_register_req_is(&(irn_req->req), should_be_same)) {
-                       assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
-                       req->other_same = get_irn_n(irn, irn_req->same_pos);
+                       req = get_mips_in_req(node, pos);
+               } else {
+                       req = get_mips_out_req(node, node_pos);
                }
 
-               if (arch_register_req_is(&(irn_req->req), should_be_different)) {
-                       assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
-                       req->other_different = get_irn_n(irn, irn_req->different_pos);
-               }
+               return req;
        }
-       /* get requirements for FIRM nodes */
-       else {
-               /* treat Phi like Const with default requirements */
-               if (is_Phi(irn)) {
-                       DB((mod, LEVEL_1, "returning standard reqs for %+F\n", irn));
 
-                       if (mode_is_float(mode)) {
-                               //memcpy(req, &(mips_default_req_mips_floating_point.req), sizeof(*req));
-                               assert(0 && "floating point not supported (yet)");
-                       }
-                       else if (mode_is_int(mode) || mode_is_reference(mode)) {
-                               memcpy(req, &(mips_default_req_mips_gp.req), sizeof(*req));
-                       }
-                       else if (mode == mode_T || mode == mode_M) {
-                               DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn));
-                               return NULL;
-                       }
-                       else {
-                               assert(0 && "unsupported Phi-Mode");
-                       }
-               }
-               else {
-                       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
-                       req = NULL;
-               }
-       }
+       /* unknown should be translated by now */
+       assert(!is_Unknown(node));
 
-       return req;
+       return arch_no_register_req;
 }
 
 static void mips_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
@@ -162,7 +115,7 @@ static void mips_set_irn_reg(const void *self, ir_node *irn, const arch_register
                }
 
                pos = mips_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj(irn);
        }
 
        if (is_mips_irn(irn)) {
@@ -188,7 +141,7 @@ static const arch_register_t *mips_get_irn_reg(const void *self, const ir_node *
                }
 
                pos = mips_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj_const(irn);
        }
 
        if (is_mips_irn(irn)) {
@@ -204,7 +157,7 @@ static const arch_register_t *mips_get_irn_reg(const void *self, const ir_node *
 }
 
 static arch_irn_class_t mips_classify(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_cfop(irn)) {
                return arch_irn_class_branch;
@@ -216,7 +169,7 @@ static arch_irn_class_t mips_classify(const void *self, const ir_node *irn) {
 }
 
 static arch_irn_flags_t mips_get_flags(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_mips_irn(irn)) {
                return get_mips_flags(irn);
index 8522ed1..c7b299e 100644 (file)
  *                       |_|
  ***********************************************************************************/
 
-/**
- * Returns a string containing the names of all registers within the limited bitset
- */
-static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
-       bitset_t *bs   = bitset_alloca(req->cls->n_regs);
-       char     *p    = buf;
-       int       size = 0;
-       int       i, cnt;
-
-       req->limited(NULL, bs);
-
-       for (i = 0; i < req->cls->n_regs; i++) {
-               if (bitset_is_set(bs, i)) {
-                       cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
-                       if (cnt < 0) {
-                               fprintf(stderr, "dumper problem, exiting\n");
-                               exit(1);
-                       }
-
-                       p    += cnt;
-                       size += cnt;
-
-                       if (size >= max)
-                               break;
-               }
-       }
-
-       return buf;
-}
-
 /**
  * Dumps the register requirements for either in or out.
  */
-static void dump_reg_req(FILE *F, ir_node *n, const mips_register_req_t **reqs, int inout) {
+static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, int inout) {
        char *dir = inout ? "out" : "in";
        int   max = inout ? get_mips_n_res(n) : get_irn_arity(n);
-       char *buf = alloca(1024);
+       char  buf[1024];
        int   i;
 
-       memset(buf, 0, 1024);
+       memset(buf, 0, sizeof(buf));
 
        if (reqs) {
                for (i = 0; i < max; i++) {
                        fprintf(F, "%sreq #%d =", dir, i);
 
-                       if (reqs[i]->req.type == arch_register_req_type_none) {
+                       if (reqs[i]->type == arch_register_req_type_none) {
                                fprintf(F, " n/a");
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_normal) {
-                               fprintf(F, " %s", reqs[i]->req.cls->name);
+                       if (reqs[i]->type & arch_register_req_type_normal) {
+                               fprintf(F, " %s", reqs[i]->cls->name);
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_limited) {
-                               fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
+                       if (reqs[i]->type & arch_register_req_type_limited) {
+                               fprintf(F, " %s",
+                                       arch_register_req_format(buf, sizeof(buf), reqs[i], n));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
-                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_same) {
+                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
-                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_different) {
+                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different));
                        }
 
                        fprintf(F, "\n");
                }
 
                fprintf(F, "\n");
-       }
-       else {
+       } else {
                fprintf(F, "%sreq = N/A\n", dir);
        }
 }
@@ -134,7 +104,7 @@ static int mips_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
        int          i;
        mips_attr_t *attr;
        char buf[64];
-       const mips_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t     **slots;
 
        switch (reason) {
@@ -259,7 +229,7 @@ mips_attr_t *get_mips_attr(const ir_node *node) {
 /**
  * Returns the argument register requirements of a mips node.
  */
-const mips_register_req_t **get_mips_in_req_all(const ir_node *node) {
+const arch_register_req_t **get_mips_in_req_all(const ir_node *node) {
        mips_attr_t *attr = get_mips_attr(node);
        return attr->in_req;
 }
@@ -267,7 +237,7 @@ const mips_register_req_t **get_mips_in_req_all(const ir_node *node) {
 /**
  * Returns the result register requirements of an mips node.
  */
-const mips_register_req_t **get_mips_out_req_all(const ir_node *node) {
+const arch_register_req_t **get_mips_out_req_all(const ir_node *node) {
        mips_attr_t *attr = get_mips_attr(node);
        return attr->out_req;
 }
@@ -275,7 +245,7 @@ const mips_register_req_t **get_mips_out_req_all(const ir_node *node) {
 /**
  * Returns the argument register requirement at position pos of an mips node.
  */
-const mips_register_req_t *get_mips_in_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_mips_in_req(const ir_node *node, int pos) {
        mips_attr_t *attr = get_mips_attr(node);
        return attr->in_req[pos];
 }
@@ -283,7 +253,7 @@ const mips_register_req_t *get_mips_in_req(const ir_node *node, int pos) {
 /**
  * Returns the result register requirement at position pos of an mips node.
  */
-const mips_register_req_t *get_mips_out_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_mips_out_req(const ir_node *node, int pos) {
        mips_attr_t *attr = get_mips_attr(node);
        return attr->out_req[pos];
 }
@@ -291,7 +261,7 @@ const mips_register_req_t *get_mips_out_req(const ir_node *node, int pos) {
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_mips_req_out(ir_node *node, const mips_register_req_t *req, int pos) {
+void set_mips_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
        mips_attr_t *attr   = get_mips_attr(node);
        attr->out_req[pos] = req;
 }
@@ -299,7 +269,7 @@ void set_mips_req_out(ir_node *node, const mips_register_req_t *req, int pos) {
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_mips_req_in(ir_node *node, const mips_register_req_t *req, int pos) {
+void set_mips_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
        mips_attr_t *attr  = get_mips_attr(node);
        attr->in_req[pos] = req;
 }
@@ -386,8 +356,8 @@ int get_mips_n_res(const ir_node *node) {
 /**
  * Initializes the nodes attributes.
  */
-void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const mips_register_req_t **in_reqs,
-                                                  const mips_register_req_t **out_reqs,
+void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const arch_register_req_t **in_reqs,
+                                                  const arch_register_req_t **out_reqs,
                                                                                                  const be_execution_unit_t ***execution_units,
                                                                                                  int n_res, unsigned latency)
 {
index 370f23e..32aa6a1 100644 (file)
@@ -27,32 +27,32 @@ mips_attr_t *get_mips_attr(const ir_node *node);
 /**
  * Returns the argument register requirements of an mips node.
  */
-const mips_register_req_t **get_mips_in_req_all(const ir_node *node);
+const arch_register_req_t **get_mips_in_req_all(const ir_node *node);
 
 /**
  * Returns the result register requirements of an mips node.
  */
-const mips_register_req_t **get_mips_out_req_all(const ir_node *node);
+const arch_register_req_t **get_mips_out_req_all(const ir_node *node);
 
 /**
  * Returns the argument register requirements of an mips node.
  */
-const mips_register_req_t *get_mips_in_req(const ir_node *node, int pos);
+const arch_register_req_t *get_mips_in_req(const ir_node *node, int pos);
 
 /**
  * Returns the result register requirements of an mips node.
  */
-const mips_register_req_t *get_mips_out_req(const ir_node *node, int pos);
+const arch_register_req_t *get_mips_out_req(const ir_node *node, int pos);
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_mips_req_out(ir_node *node, const mips_register_req_t *req, int pos);
+void set_mips_req_out(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_mips_req_in(ir_node *node, const mips_register_req_t *req, int pos);
+void set_mips_req_in(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Returns the register flag of an mips node.
@@ -98,8 +98,8 @@ int get_mips_n_res(const ir_node *node);
 /**
  * Initializes the nodes attributes.
  */
-void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const mips_register_req_t **in_reqs,
-        const mips_register_req_t **out_reqs, const be_execution_unit_t ***execution_units, int n_res, unsigned latency);
+void init_mips_attributes(ir_node *node, arch_irn_flags_t flags, const arch_register_req_t **in_reqs,
+        const arch_register_req_t **out_reqs, const be_execution_unit_t ***execution_units, int n_res, unsigned latency);
 
 /**
  * Initialize transform ops for the mips opcodes
index b68eb83..0602a7d 100644 (file)
@@ -4,13 +4,6 @@
 #include "../bearch.h"
 #include "irmode_t.h"
 
-typedef struct _mips_register_req_t {
-       const arch_register_req_t req;
-       int same_pos;        /**<< in case of "should be same" we need to remember the pos to get the irn */
-       int different_pos;   /**<< in case of "should be different" we need to remember the pos to get the irn */
-} mips_register_req_t;
-
-
 typedef struct _mips_attr_t {
        arch_irn_flags_t flags;     /**< indicating if spillable, rematerializeable ... etc. */
        int              n_res;     /**< number of results for this node */
@@ -26,8 +19,8 @@ typedef struct _mips_attr_t {
        int stack_entity_offset;        /**< contains the real stack offset for the entity */
        int switch_default_pn;          /**< proj number of default case in switch */
 
-       const mips_register_req_t **in_req;  /**< register requirements for arguments */
-       const mips_register_req_t **out_req; /**< register requirements for results */
+       const arch_register_req_t **in_req;  /**< register requirements for arguments */
+       const arch_register_req_t **out_req; /**< register requirements for results */
 
        /* must be last, dynamically allocated */
        const arch_register_t *slots[1];     /**< register slots for assigned registers */
index dbea8ba..9a926b1 100644 (file)
@@ -91,45 +91,47 @@ $comment_string_end = "";
 #   4 - ignore (do not assign this register)
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold\
 %reg_classes = (
-  "gp" => [
-                         { name => "zero", type => 4+2 },  # always zero
-                         { name => "at", type => 4 }, # reserved for assembler
-                         { name => "v0", type => 1 }, # first return value
-                         { name => "v1", type => 1 }, # second return value
-                         { name => "a0", type => 1 }, # first argument
-                         { name => "a1", type => 1 }, # second argument
-                         { name => "a2", type => 1 }, # third argument
-                         { name => "a3", type => 1 }, # fourth argument
-                         { name => "t0", type => 1 },
-                         { name => "t1", type => 1 },
-                         { name => "t2", type => 1 },
-                         { name => "t3", type => 1 },
-                         { name => "t4", type => 1 },
-                         { name => "t5", type => 1 },
-                         { name => "t6", type => 1 },
-                         { name => "t7", type => 1 },
-                         { name => "s0", type => 2 },
-                         { name => "s1", type => 2 },
-                         { name => "s2", type => 2 },
-                         { name => "s3", type => 2 },
-                         { name => "s4", type => 2 },
-                         { name => "s5", type => 2 },
-                         { name => "s6", type => 2 },
-                         { name => "s7", type => 2 },
-                         { name => "t8", type => 1 },
-                         { name => "t9", type => 1 },
-                         { name => "k0", type => 4 }, # reserved for OS
-                         { name => "k1", type => 4 }, # reserved for OS
-                         { name => "gp", type => 4 }, # general purpose
-                         { name => "sp", type => 4+2 }, # stack pointer
-                         { name => "fp", type => 4+2 }, # frame pointer
-                         { name => "ra", type => 2+1 }, # return address. This is also caller save, because
-                                                                                                                       # the jla instruction that is used for calls modifies
-                                                                                                                       # the ra register. It is callee save too, because at the last
-                                                                                                                       # command of a function (the ja $ra) it needs to have it's
-                                                                                                                       # old value.
-                         { mode => "mode_P" }
-                       ],
+       "gp" => [
+               { name => "zero", type => 4+2 },  # always zero
+               { name => "at", type => 4 }, # reserved for assembler
+               { name => "v0", type => 1 }, # first return value
+               { name => "v1", type => 1 }, # second return value
+               { name => "a0", type => 1 }, # first argument
+               { name => "a1", type => 1 }, # second argument
+               { name => "a2", type => 1 }, # third argument
+               { name => "a3", type => 1 }, # fourth argument
+               { name => "t0", type => 1 },
+               { name => "t1", type => 1 },
+               { name => "t2", type => 1 },
+               { name => "t3", type => 1 },
+               { name => "t4", type => 1 },
+               { name => "t5", type => 1 },
+               { name => "t6", type => 1 },
+               { name => "t7", type => 1 },
+               { name => "s0", type => 2 },
+               { name => "s1", type => 2 },
+               { name => "s2", type => 2 },
+               { name => "s3", type => 2 },
+               { name => "s4", type => 2 },
+               { name => "s5", type => 2 },
+               { name => "s6", type => 2 },
+               { name => "s7", type => 2 },
+               { name => "t8", type => 1 },
+               { name => "t9", type => 1 },
+               { name => "k0", type => 4 }, # reserved for OS
+               { name => "k1", type => 4 }, # reserved for OS
+               { name => "gp", type => 4 }, # general purpose
+               { name => "sp", type => 4+2 }, # stack pointer
+               { name => "fp", type => 4+2 }, # frame pointer
+               { name => "ra", type => 2+1 }, # return address. This is also caller
+                                       # save, because the jla instruction that
+                                              # is used for calls modifies the ra
+                                              # register. It is callee save too,
+                                              # because at the last command of a
+                                              # function (the ja $ra) it needs to have
+                                              # it's old value.
+               { mode => "mode_P" }
+       ],
 ); # %reg_classes
 
 #--------------------------------------------------#
index 5ef844e..3a6124e 100644 (file)
@@ -1,8 +1,7 @@
 /* The main ppc backend driver file. */
 /* $Id$ */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "pseudo_irg.h"
@@ -57,31 +56,26 @@ static set *cur_reg_set = NULL;
  *           |___/
  **************************************************/
 
-static ir_node *my_skip_proj(const ir_node *n) {
-       while (is_Proj(n))
-               n = get_Proj_pred(n);
-       return (ir_node *)n;
-}
-
 /**
  * Return register requirements for a ppc node.
  * If the node returns a tuple (mode_T) then the proj's
  * will be asked for this information.
  */
-static const arch_register_req_t *ppc32_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
-       const ppc32_register_req_t *irn_req;
+static const
+arch_register_req_t *ppc32_get_irn_reg_req(const void *self,
+                                           const ir_node *irn, int pos) {
        long               node_pos = pos == -1 ? 0 : pos;
        ir_mode           *mode     = get_irn_mode(irn);
        FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
 
        if (is_Block(irn) || mode == mode_X || mode == mode_M) {
                DBG((mod, LEVEL_1, "ignoring block, mode_X or mode_M node %+F\n", irn));
-               return NULL;
+               return arch_no_register_req;
        }
 
        if (mode == mode_T && pos < 0) {
                DBG((mod, LEVEL_1, "ignoring request for OUT requirements at %+F", irn));
-               return NULL;
+               return arch_no_register_req;
        }
 
        DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
@@ -91,66 +85,33 @@ static const arch_register_req_t *ppc32_get_irn_reg_req(const void *self, arch_r
                /* of the node corresponding to the proj number */
                if (pos == -1) {
                        node_pos = ppc32_translate_proj_pos(irn);
-               }
-               else {
+               } else {
                        node_pos = pos;
                }
 
-               irn = my_skip_proj(irn);
+               irn = skip_Proj_const(irn);
 
                DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
        }
 
        /* get requirements for our own nodes */
        if (is_ppc32_irn(irn)) {
+               const arch_register_req_t *req;
                if (pos >= 0) {
-                       irn_req = get_ppc32_in_req(irn, pos);
-               }
-               else {
-                       irn_req = get_ppc32_out_req(irn, node_pos);
+                       req = get_ppc32_in_req(irn, pos);
+               } else {
+                       req = get_ppc32_out_req(irn, node_pos);
                }
 
                DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
-
-               memcpy(req, &(irn_req->req), sizeof(*req));
-
-               if (arch_register_req_is(&(irn_req->req), should_be_same)) {
-                       assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
-                       req->other_same = get_irn_n(irn, irn_req->same_pos);
-               }
-
-               if (arch_register_req_is(&(irn_req->req), should_be_different)) {
-                       assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
-                       req->other_different = get_irn_n(irn, irn_req->different_pos);
-               }
+               return req;
        }
-       /* get requirements for FIRM nodes */
-       else {
-               /* treat Phi like Const with default requirements */
-               if (is_Phi(irn)) {
-                       DB((mod, LEVEL_1, "returning standard reqs for %+F\n", irn));
 
-                       if (mode_is_float(mode)) {
-                               memcpy(req, &(ppc32_default_req_ppc32_fp.req), sizeof(*req));
-                       }
-                       else if (mode_is_int(mode) || mode_is_reference(mode)) {
-                               memcpy(req, &(ppc32_default_req_ppc32_gp.req), sizeof(*req));
-                       }
-                       else if (mode == mode_T || mode == mode_M) {
-                               DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn));
-                               return NULL;
-                       }
-                       else {
-                               assert(0 && "unsupported Phi-Mode");
-                       }
-               }
-               else {
-                       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
-                       req = NULL;
-               }
-       }
+       /* unknowns should be transformed by now */
+       assert(!is_Unknown(irn));
 
-       return req;
+       DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
+       return arch_no_register_req;
 }
 
 static void ppc32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
@@ -163,7 +124,7 @@ static void ppc32_set_irn_reg(const void *self, ir_node *irn, const arch_registe
                }
 
                pos = ppc32_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj(irn);
        }
 
        if (is_ppc32_irn(irn)) {
@@ -189,7 +150,7 @@ static const arch_register_t *ppc32_get_irn_reg(const void *self, const ir_node
                }
 
                pos = ppc32_translate_proj_pos(irn);
-               irn = my_skip_proj(irn);
+               irn = skip_Proj_const(irn);
        }
 
        if (is_ppc32_irn(irn)) {
@@ -205,7 +166,7 @@ static const arch_register_t *ppc32_get_irn_reg(const void *self, const ir_node
 }
 
 static arch_irn_class_t ppc32_classify(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_cfop(irn)) {
                return arch_irn_class_branch;
@@ -218,7 +179,7 @@ static arch_irn_class_t ppc32_classify(const void *self, const ir_node *irn) {
 }
 
 static arch_irn_flags_t ppc32_get_flags(const void *self, const ir_node *irn) {
-       irn = my_skip_proj(irn);
+       irn = skip_Proj_const(irn);
 
        if (is_ppc32_irn(irn)) {
                return get_ppc32_flags(irn);
index dce4963..32ab4eb 100644 (file)
@@ -4,7 +4,7 @@
  * $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #ifdef _WIN32
  *                       |_|
  ***********************************************************************************/
 
-/**
- * Returns a string containing the names of all registers within the limited bitset
- */
-static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
-       bitset_t *bs   = bitset_alloca(req->cls->n_regs);
-       char     *p    = buf;
-       int       size = 0;
-       int       i, cnt;
-
-       req->limited(NULL, bs);
-
-       for (i = 0; i < req->cls->n_regs; i++) {
-               if (bitset_is_set(bs, i)) {
-                       cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
-                       if (cnt < 0) {
-                               fprintf(stderr, "dumper problem, exiting\n");
-                               exit(1);
-                       }
-
-                       p    += cnt;
-                       size += cnt;
-
-                       if (size >= max)
-                               break;
-               }
-       }
-
-       return buf;
-}
-
 /**
  * Dumps the register requirements for either in or out.
  */
-static void dump_reg_req(FILE *F, ir_node *n, const ppc32_register_req_t **reqs, int inout) {
+static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, int inout) {
        char *dir = inout ? "out" : "in";
        int   max = inout ? get_ppc32_n_res(n) : get_irn_arity(n);
-       char *buf = alloca(1024);
+       char  buf[1024];
        int   i;
 
-       memset(buf, 0, 1024);
+       memset(buf, 0, sizeof(buf));
 
        if (reqs) {
                for (i = 0; i < max; i++) {
                        fprintf(F, "%sreq #%d =", dir, i);
 
-                       if (reqs[i]->req.type == arch_register_req_type_none) {
+                       if (reqs[i]->type == arch_register_req_type_none) {
                                fprintf(F, " n/a");
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_normal) {
-                               fprintf(F, " %s", reqs[i]->req.cls->name);
+                       if (reqs[i]->type & arch_register_req_type_normal) {
+                               fprintf(F, " %s", reqs[i]->cls->name);
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_limited) {
-                               fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
+                       if (reqs[i]->type & arch_register_req_type_limited) {
+                               fprintf(F, " %s",
+                                       arch_register_req_format(buf, sizeof(buf), reqs[i], n));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
-                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_same) {
+                               ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same));
                        }
 
-                       if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
-                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
+                       if (reqs[i]->type & arch_register_req_type_should_be_different) {
+                               ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different));
                        }
 
                        fprintf(F, "\n");
                }
 
                fprintf(F, "\n");
-       }
-       else {
+       } else {
                fprintf(F, "%sreq = N/A\n", dir);
        }
 }
@@ -133,7 +103,7 @@ static int ppc32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
        int          bad  = 0;
        int          i;
        ppc32_attr_t *attr;
-       const ppc32_register_req_t **reqs;
+       const arch_register_req_t **reqs;
        const arch_register_t     **slots;
 
        switch (reason) {
@@ -246,7 +216,7 @@ ppc32_attr_t *get_ppc32_attr(const ir_node *node) {
 /**
  * Returns the argument register requirements of a ppc node.
  */
-const ppc32_register_req_t **get_ppc32_in_req_all(const ir_node *node) {
+const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node) {
        ppc32_attr_t *attr = get_ppc32_attr(node);
        return attr->in_req;
 }
@@ -254,7 +224,7 @@ const ppc32_register_req_t **get_ppc32_in_req_all(const ir_node *node) {
 /**
  * Returns the result register requirements of an ppc node.
  */
-const ppc32_register_req_t **get_ppc32_out_req_all(const ir_node *node) {
+const arch_register_req_t **get_ppc32_out_req_all(const ir_node *node) {
        ppc32_attr_t *attr = get_ppc32_attr(node);
        return attr->out_req;
 }
@@ -262,7 +232,7 @@ const ppc32_register_req_t **get_ppc32_out_req_all(const ir_node *node) {
 /**
  * Returns the argument register requirement at position pos of an ppc node.
  */
-const ppc32_register_req_t *get_ppc32_in_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos) {
        ppc32_attr_t *attr = get_ppc32_attr(node);
        return attr->in_req[pos];
 }
@@ -270,7 +240,7 @@ const ppc32_register_req_t *get_ppc32_in_req(const ir_node *node, int pos) {
 /**
  * Returns the result register requirement at position pos of an ppc node.
  */
-const ppc32_register_req_t *get_ppc32_out_req(const ir_node *node, int pos) {
+const arch_register_req_t *get_ppc32_out_req(const ir_node *node, int pos) {
        ppc32_attr_t *attr = get_ppc32_attr(node);
        return attr->out_req[pos];
 }
@@ -278,7 +248,7 @@ const ppc32_register_req_t *get_ppc32_out_req(const ir_node *node, int pos) {
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_ppc32_req_out(ir_node *node, const ppc32_register_req_t *req, int pos) {
+void set_ppc32_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
        ppc32_attr_t *attr   = get_ppc32_attr(node);
        attr->out_req[pos] = req;
 }
@@ -286,7 +256,7 @@ void set_ppc32_req_out(ir_node *node, const ppc32_register_req_t *req, int pos)
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_ppc32_req_in(ir_node *node, const ppc32_register_req_t *req, int pos) {
+void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
        ppc32_attr_t *attr  = get_ppc32_attr(node);
        attr->in_req[pos] = req;
 }
@@ -513,7 +483,7 @@ ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node) {
  * Initializes ppc specific node attributes
  */
 void init_ppc32_attributes(ir_node *node, int flags,
-                                                const ppc32_register_req_t **in_reqs, const ppc32_register_req_t **out_reqs,
+                                                const arch_register_req_t **in_reqs, const arch_register_req_t **out_reqs,
                                                 const be_execution_unit_t ***execution_units,
                                                 int n_res, unsigned latency) {
        ppc32_attr_t *attr = get_ppc32_attr(node);
index f632400..a5ca72d 100644 (file)
@@ -27,32 +27,32 @@ ppc32_attr_t *get_ppc32_attr(const ir_node *node);
 /**
  * Returns the argument register requirements of an ppc node.
  */
-const ppc32_register_req_t **get_ppc32_in_req_all(const ir_node *node);
+const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node);
 
 /**
  * Returns the result register requirements of an ppc node.
  */
-const ppc32_register_req_t **get_ppc32_out_req_all(const ir_node *node);
+const arch_register_req_t **get_ppc32_out_req_all(const ir_node *node);
 
 /**
  * Returns the argument register requirements of an ppc node.
  */
-const ppc32_register_req_t *get_ppc32_in_req(const ir_node *node, int pos);
+const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos);
 
 /**
  * Returns the result register requirements of an ppc node.
  */
-const ppc32_register_req_t *get_ppc32_out_req(const ir_node *node, int pos);
+const arch_register_req_t *get_ppc32_out_req(const ir_node *node, int pos);
 
 /**
  * Sets the OUT register requirements at position pos.
  */
-void set_ppc32_req_out(ir_node *node, const ppc32_register_req_t *req, int pos);
+void set_ppc32_req_out(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Sets the IN register requirements at position pos.
  */
-void set_ppc32_req_in(ir_node *node, const ppc32_register_req_t *req, int pos);
+void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos);
 
 /**
  * Returns the register flag of an ppc node.
@@ -118,7 +118,7 @@ void set_ppc32_offset_mode(const ir_node *node, ppc32_attr_offset_mode mode);
 ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node);
 
 void init_ppc32_attributes(ir_node *node, int flags,
-                                                const ppc32_register_req_t **in_reqs, const ppc32_register_req_t **out_reqs,
+                                                const arch_register_req_t **in_reqs, const arch_register_req_t **out_reqs,
                                                 const be_execution_unit_t ***execution_units,
                                                 int n_res, unsigned latency);
 
index 13bcea6..4021083 100644 (file)
@@ -3,12 +3,6 @@
 
 #include "../bearch.h"
 
-typedef struct _ppc32_register_req_t {
-       const arch_register_req_t req;
-       int same_pos;        /**< in case of "should be same" we need to remember the pos to get the irn */
-       int different_pos;   /**< in case of "should be different" we need to remember the pos to get the irn */
-} ppc32_register_req_t;
-
 typedef struct
 {
        unsigned shift:5;
@@ -35,8 +29,8 @@ typedef struct _ppc32_attr_t {
        arch_irn_flags_t flags;     /**< indicating if spillable, rematerializeable ... etc. */
        int              n_res;     /**< number of results for this node */
 
-       const ppc32_register_req_t **in_req;  /**< register requirements for arguments */
-       const ppc32_register_req_t **out_req; /**< register requirements for results */
+       const arch_register_req_t **in_req;  /**< register requirements for arguments */
+       const arch_register_req_t **out_req; /**< register requirements for results */
 
        ppc32_attr_content_type content_type;
        ppc32_attr_offset_mode offset_mode;
index f7a7e45..c11c562 100644 (file)
@@ -1119,9 +1119,9 @@ static ir_node *gen_CopyB(ppc32_transform_env_t *env) {
        int size = get_type_size_bytes(type);
        int offset = 0;
 
-       ir_node *load, *store;
+       ir_node *load, *store = NULL;
 
-       if(size/4>=1)
+       if(size/4 >= 1)
        {
                ir_node *res;
                tarval *offset0 = new_tarval_from_long(0, mode_Is);
@@ -1424,7 +1424,7 @@ static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_
        struct tv_ent *entry;
        ir_node       *cnst,*symcnst;
        ir_graph      *rem;
-       ir_entity     *ent;
+       ir_entity     *ent = NULL;
 
        if(!const_set)
                const_set = new_set(cmp_tv_ent, 10);
index 1326d9a..42d1d8b 100755 (executable)
@@ -192,7 +192,7 @@ print OUT<<EOF;
  * date:       $creation_time
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <stdio.h>
index eeb432d..154fb2e 100755 (executable)
@@ -15,6 +15,7 @@ our $target_dir;
 our $arch;
 our %nodes;
 our %emit_templates;
+our $finish_line_template = "be_emit_finish_line_gas(emit, node);";
 
 my $target_c = $target_dir."/gen_".$arch."_emitter.c";
 my $target_h = $target_dir."/gen_".$arch."_emitter.h";
@@ -32,24 +33,24 @@ sub create_emitter {
        our $arch;
 
        my @tokens = ($template =~ m/[^\%]+|\%[a-zA-Z_][a-zA-Z0-9_]*|\%./g);
-       push(@{$result}, "${indent}${arch}_emit_char(env, '\t');\n");
+       push(@{$result}, "${indent}be_emit_char(emit, '\t');\n");
        for (@tokens) {
                SWITCH: {
                        if (/%\./)      { last SWITCH; }
-                       if (/%%/)       { push(@{$result}, "${indent}${arch}_emit_char(env, '%');\n"); last SWITCH; }
+                       if (/%%/)       { push(@{$result}, "${indent}be_emit_char(emit, '%');\n"); last SWITCH; }
                        if (/%(.+)/)    {
                                if(defined($emit_templates{$1})) {
                                        push(@{$result}, "${indent}$emit_templates{$1}\n");
                                } else {
                                        print "Warning: No emit_template defined for '$1'\n";
-                                       push(@{$result}, "${indent}$1(env, node);\n");
+                                       push(@{$result}, "${indent}$1(emit, node);\n");
                                }
                                last SWITCH;
                        }
-                       push(@{$result}, "${indent}${arch}_emit_cstring(env, \"$_\");\n");
+                       push(@{$result}, "${indent}be_emit_cstring(emit, \"$_\");\n");
                }
        }
-       push(@{$result}, "${indent}${arch}_emit_finish_line(env, node);\n");
+       push(@{$result}, "${indent}${finish_line_template}\n");
 }
 
 
@@ -60,7 +61,7 @@ foreach my $op (keys(%nodes)) {
        # skip this node description if no emit information is available
        next if (!defined($n{"emit"}));
 
-       $line = "static void emit_".$arch."_".$op."(${arch}_emit_env_t *env, const ir_node *node)";
+       $line = "static void emit_${arch}_${op}(${arch}_emit_env_t *env, const ir_node *node)";
 
        push(@obst_register, "  BE_EMIT($op);\n");
 
@@ -71,6 +72,8 @@ foreach my $op (keys(%nodes)) {
        }
 
        push(@obst_func, $line." {\n");
+       push(@obst_func, "\tbe_emit_env_t *emit = env->emit;\n");
+
        my @emit = split(/\n/, $n{"emit"});
 
        foreach my $template (@emit) {
@@ -105,9 +108,9 @@ print OUT<<EOF;
  */
 
 #include "irnode.h"
-#include "$arch\_emitter.h"
+#include "${arch}_emitter.h"
 
-void $arch\_register_spec_emitters(void);
+void ${arch}_register_spec_emitters(void);
 
 #endif /* _GEN_$tmp\_EMITTER_H_ */
 
index ac15b64..4272be0 100755 (executable)
@@ -129,7 +129,7 @@ print OUT<<EOF;
  * date:       $creation_time
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include "gen_$arch\_machine.h"
index 9b8e9ba..0508c7c 100755 (executable)
@@ -61,6 +61,20 @@ $n_opcodes += $additional_opcodes if (defined($additional_opcodes));
 
 push(@obst_header, "void ".$arch."_create_opcodes(void);\n");
 
+# create default compare function
+if(defined($default_cmp_attr)) {
+       my $cmpcode = $default_cmp_attr;
+       push(@obst_cmp_attr, "static int default_cmp_attr(ir_node *a, ir_node *b) {\n");
+       if($cmpcode =~ m/attr_a/) {
+               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
+       }
+       if($cmpcode =~ m/attr_b/) {
+               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
+       }
+       push(@obst_cmp_attr, "\t${cmpcode}\n");
+       push(@obst_cmp_attr, "}\n\n");
+}
+
 push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n");
 foreach my $op (keys(%nodes)) {
        my %n        = %{ $nodes{"$op"} };
@@ -114,22 +128,25 @@ foreach my $op (keys(%nodes)) {
        push(@obst_header, "ir_op *get_op_$op(void);\n");
        push(@obst_header, "int is_$op(const ir_node *n);\n");
 
-       $cmp_attr_func = 0;
+       my $cmp_attr_func;
+       if(defined($default_cmp_attr)) {
+               $cmp_attr_func = "default_cmp_attr";
+       }
        # create compare attribute function if needed
-       if (exists($n{"cmp_attr"}) || defined($default_cmp_attr)) {
+       if (exists($n{"cmp_attr"})) {
+               my $cmpcode = $n{"cmp_attr"};
+
                push(@obst_cmp_attr, "static int cmp_attr_$op(ir_node *a, ir_node *b) {\n");
-               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
-               push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
-               push(@obst_cmp_attr, "\t(void) attr_a;\n");
-               push(@obst_cmp_attr, "\t(void) attr_b;\n");
-               if(exists($n{"cmp_attr"})) {
-                       push(@obst_cmp_attr, "\t".$n{"cmp_attr"}."\n");
-               } else {
-                       push(@obst_cmp_attr, "\t$default_cmp_attr\n");
+               if($cmpcode =~ m/attr_a/) {
+                       push(@obst_cmp_attr, "\t$arch\_attr_t *attr_a = get_$arch\_attr(a);\n");
+               }
+               if($cmpcode =~ m/attr_b/) {
+                       push(@obst_cmp_attr, "\t$arch\_attr_t *attr_b = get_$arch\_attr(b);\n");
                }
+               push(@obst_cmp_attr, "\t${cmpcode}\n");
                push(@obst_cmp_attr, "}\n\n");
 
-               $cmp_attr_func = 1;
+               $cmp_attr_func = "cmp_attr_${op}";
        }
 
        if (exists($n{"rd_constructor"}) && $n{"rd_constructor"} =~ /^NONE$/i) {
@@ -214,10 +231,10 @@ foreach my $op (keys(%nodes)) {
 
                                if (@in) {
                                        $in_req_var = "_in_req_$op";
-                                       $temp .= "\tstatic const $arch\_register_req_t *".$in_req_var."[] =\n";
+                                       $temp .= "\tstatic const arch_register_req_t *".$in_req_var."[] =\n";
                                        $temp .= "\t{\n";
                                        for ($idx = 0; $idx <= $#in; $idx++) {
-                                               $temp .= "\t\t".$op."_reg_req_in_".$idx.",\n";
+                                               $temp .= "\t\t&".$op."_reg_req_in_".$idx.",\n";
                                        }
                                        $temp .= "\t};\n";
                                }
@@ -225,20 +242,18 @@ foreach my $op (keys(%nodes)) {
                                if (@out) {
                                        $out_req_var = "_out_req_$op";
 
-                                       $temp .= "\tstatic const $arch\_register_req_t *".$out_req_var."[] =\n";
+                                       $temp .= "\tstatic const arch_register_req_t *".$out_req_var."[] =\n";
                                        $temp .= "\t{\n";
                                        for ($idx = 0; $idx <= $#out; $idx++) {
-                                               $temp .= "\t\t".$op."_reg_req_out_".$idx.",\n";
+                                               $temp .= "\t\t&".$op."_reg_req_out_".$idx.",\n";
                                        }
                                        $temp .= "\t};\n";
                                }
                        }
 
                        $temp .= "\n";
-                       $temp .= "\tif (!op_$op) {\n";
-                       $temp .= "\t\tassert(0);\n";
-                       $temp .= "\t\treturn NULL;\n";
-                       $temp .= "\t}\n\n";
+                       $temp .= "\tassert(op_$op != NULL);\n\n";
+
                        for (my $i = 1; $i <= $arity; $i++) {
                                $temp .= "\tin[".($i - 1)."] = op".$i.";\n";
                        }
@@ -359,8 +374,8 @@ foreach my $op (keys(%nodes)) {
        push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n");
        push(@obst_new_irop, "\tops.dump_node     = $arch\_dump_node;\n");
 
-       if ($cmp_attr_func) {
-               push(@obst_new_irop, "\tops.node_cmp_attr = cmp_attr_$op;\n");
+       if (defined($cmp_attr_func)) {
+               push(@obst_new_irop, "\tops.node_cmp_attr = ${cmp_attr_func};\n");
        }
 
        $n_opcodes++;
index 3481218..535182d 100755 (executable)
@@ -7,6 +7,7 @@
 
 use strict;
 use Data::Dumper;
+use integer;
 
 my $specfile   = $ARGV[0];
 my $target_dir = $ARGV[1];
@@ -20,7 +21,7 @@ our %cpu;
 
 my $return;
 
-no strict "subs";
+use strict "subs";
 unless ($return = do $specfile) {
        warn "couldn't parse $specfile: $@" if $@;
        warn "couldn't do $specfile: $!"    unless defined $return;
@@ -75,9 +76,8 @@ my @obst_regdef;       # stack to define a name for a register index
 my @obst_reginit;      # stack for the register type inits
 my @obst_req;          # stack for the register requirements
 my @obst_limit_func;   # stack for functions to return a subset of a register class
-my @obst_defreq_head;  # stack for prototypes of default requirement function
 my @obst_header_all;   # stack for some extern struct defs needed for bearch_$arch include
-my @obst_requirement_def;  # stack for requirement name defines
+my @obst_header_t;
 
 my $numregs;
 my $class_ptr;
@@ -86,33 +86,18 @@ my $class_idx = 0;
 my $tmp;
 
 my %reg2class;
-
-# there is a default NONE requirement
-$tmp = "/* Default NONE register requirements */\n";
-$tmp .= "const $arch\_register_req_t $arch\_default_req_none = {\n";
-$tmp .= "  {\n";
-$tmp .= "    arch_register_req_type_none,  /* register type  */\n";
-$tmp .= "    NULL,                         /* register class */\n";
-$tmp .= "    NULL,                         /* limit function */\n";
-$tmp .= "    NULL,                         /* limit environment */\n";
-$tmp .= "    NULL,                         /* node for same */\n";
-$tmp .= "    NULL                          /* node for different */\n";
-$tmp .= "  },\n";
-$tmp .= "  0,                              /* same pos */\n";
-$tmp .= "  0                               /* different pos */\n";
-$tmp .= "};\n\n";
-push(@obst_req, $tmp);
-push(@obst_header_all, "extern const $arch\_register_req_t $arch\_default_req_none;\n");
+my %regclass2len;
 
 push(@obst_classdef, "enum reg_classes {\n");
 
 my $class_mode;
 
 # assure, the initialization is done only once
-push(@obst_reginit, "  static int run_once = 0;\n");
+push(@obst_reginit, "\tstatic int run_once = 0;\n");
 push(@obst_reginit, "\n");
-push(@obst_reginit, "  if (run_once)\n    return;\n");
-push(@obst_reginit, "  run_once = 1;\n");
+push(@obst_reginit, "\tif (run_once)\n");
+push(@obst_reginit, "\t\treturn;\n");
+push(@obst_reginit, "\trun_once = 1;\n");
 
 # generate register type and class variable, init function and default requirements
 foreach my $class_name (keys(%reg_classes)) {
@@ -127,87 +112,36 @@ foreach my $class_name (keys(%reg_classes)) {
        push(@obst_regtypes_decl, "extern arch_register_t ".$class_name."_regs[$numregs];\n");
        push(@obst_regtypes_def, "arch_register_t ".$class_name."_regs[$numregs];\n");
 
-       push(@obst_classdef, "  CLASS_$class_name = $class_idx,\n");
+       push(@obst_classdef, "\tCLASS_$class_name = $class_idx,\n");
        push(@obst_regclasses, "{ \"$class_name\", $numregs, NULL, ".$class_name."_regs }");
 
-       # there is a default NORMAL requirement for each class
-       $tmp  = "/* Default NORMAL register requirements for class $class_name */\n";
-       $tmp .= "const $arch\_register_req_t $arch\_default_req_$class_name = {\n";
-       $tmp .= "  {\n";
-       $tmp .= "    arch_register_req_type_normal,\n";
-       $tmp .= "    $class_ptr,\n";
-       $tmp .= "    NULL,                    /* limit function */ \n";
-       $tmp .= "    NULL,                    /* limit environment */\n";
-       $tmp .= "    NULL,                    /* node for same */\n";
-       $tmp .= "    NULL                     /* node for different */\n";
-       $tmp .= "  },\n";
-       $tmp .= "  0,                         /* same pos */\n";
-       $tmp .= "  0                          /* different pos */\n";
-       $tmp .= "};\n\n";
-       push(@obst_req, $tmp);
-       push(@obst_header_all, "extern const $arch\_register_req_t $arch\_default_req_$class_name;\n");
-
        my $idx = 0;
-       push(@obst_reginit, "  /* Init of all registers in class '$class_name' */\n\n");
-       push(@obst_reginit, "  /* set largest possible mode for '$class_name' */\n");
-       push(@obst_reginit, "  $arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n\n");
+       push(@obst_reginit, "\t/* Init of all registers in class '$class_name' */\n\n");
+       push(@obst_reginit, "\t/* set largest possible mode for '$class_name' */\n");
+       push(@obst_reginit, "\t$arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n\n");
        push(@obst_regdef, "enum reg_".$class_name."_values {\n");
        foreach (@class) {
-               # For each class we build for each of it's member registers a limit function
-               # which limits the class to this particular register. We also build the
-               # corresponding requirement structs.
-               # We need those functions to set register requirements on demand in transformation
-               # esp. for Call and RegParams where we can mix int and float parameters.
-
-               my $limit_func_name = $arch."_limit_".$class_name."_".$_->{"name"};
-
-               # push the function prototype
-               $tmp = "void $limit_func_name(void *_unused, bitset_t *bs)";
-               push(@obst_defreq_head, $tmp.";\n");
-
-               # push the function definition
-               $tmp .= " {\n";
-               $tmp .= "    bs = bitset_clear_all(bs);\n";
-               $tmp .= "    bitset_set(bs, REG_".uc($_->{"name"}).");\n";  # REGISTER to index assignment is done some lines down
-               $tmp .= "}\n\n";
-               push(@obst_limit_func, $tmp);
-
-               # push the default requirement struct
-               $tmp  = "const $arch\_register_req_t $arch\_default_req_$class_name\_".$_->{"name"}." = {\n";
-               $tmp .= "  {\n";
-               $tmp .= "    arch_register_req_type_limited,\n";
-               $tmp .= "    $class_ptr,\n";
-               $tmp .= "    $limit_func_name,\n";
-               $tmp .= "    NULL,                     /* limit environment */\n";
-               $tmp .= "    NULL,                     /* node for same */\n";
-               $tmp .= "    NULL                      /* node for different */\n";
-               $tmp .= "  },\n";
-               $tmp .= "  0,                          /* same pos */\n";
-               $tmp .= "  0                           /* different pos */\n";
-               $tmp .= "};\n\n";
-               push(@obst_req, $tmp);
-               push(@obst_header_all,"extern const $arch\_register_req_t $arch\_default_req_$class_name\_".$_->{"name"}.";\n");
-
                # realname is name if not set by user
                $_->{"realname"} = $_->{"name"} if (! exists($_->{"realname"}));
 
                $reg2class{$_->{"name"}} = { "class" => $old_classname, "index" => $idx }; # remember reg to class for later use
-               push(@obst_regdef, "  REG_".uc($_->{"name"})." = $idx,\n");
-               push(@obst_reginit, "  ".$class_name."_regs[$idx].name      = \"".$_->{"realname"}."\";\n");
-               push(@obst_reginit, "  ".$class_name."_regs[$idx].reg_class = $class_ptr;\n");
-               push(@obst_reginit, "  ".$class_name."_regs[$idx].index     = $idx;\n");
-               push(@obst_reginit, "  ".$class_name."_regs[$idx].type      = ".translate_reg_type($_->{"type"}).";\n");
-               push(@obst_reginit, "  ".$class_name."_regs[$idx].data      = ".get_execunit_variable_name($_->{"unit"}).";\n");
+               push(@obst_regdef, "\tREG_".uc($_->{"name"})." = $idx,\n");
+               push(@obst_reginit, "\t${class_name}_regs[$idx].name      = \"".$_->{"realname"}."\";\n");
+               push(@obst_reginit, "\t${class_name}_regs[$idx].reg_class = $class_ptr;\n");
+               push(@obst_reginit, "\t${class_name}_regs[$idx].index     = $idx;\n");
+               push(@obst_reginit, "\t${class_name}_regs[$idx].type      = ".translate_reg_type($_->{"type"}).";\n");
+               push(@obst_reginit, "\t${class_name}_regs[$idx].data      = ".get_execunit_variable_name($_->{"unit"}).";\n");
                push(@obst_reginit, "\n");
                $idx++;
        }
-       push(@obst_regdef, "  $numregs = $idx\n");
+       $regclass2len{$old_classname} = $idx;
+       push(@obst_regdef, "\t$numregs = $idx\n");
        push(@obst_regdef, "};\n\n");
 
        $class_idx++;
 }
 
-push(@obst_classdef, "  N_CLASSES = ".scalar(keys(%reg_classes))."\n");
+push(@obst_classdef, "\tN_CLASSES = ".scalar(keys(%reg_classes))."\n");
 push(@obst_classdef, "};\n\n");
 
 # generate node-register constraints
@@ -241,9 +175,6 @@ my $creation_time = localtime(time());
 $tmp = uc($arch);
 
 print OUT<<EOF;
-#ifndef _GEN_$tmp\_REGALLOC_IF_T_H_
-#define _GEN_$tmp\_REGALLOC_IF_T_H_
-
 /**
  * Generated register classes from spec.
  *
@@ -252,10 +183,14 @@ print OUT<<EOF;
  * created by: $0 $specfile $target_dir
  * date:       $creation_time
  */
+#ifndef _GEN_${tmp}_REGALLOC_IF_T_H_
+#define _GEN_${tmp}_REGALLOC_IF_T_H_
+
+#include "gen_${arch}_regalloc_if.h"
 
 EOF
 
-print OUT @obst_requirement_def;
+print OUT @obst_header_t;
 
 print OUT "\n#endif /* _GEN_$tmp\_REGALLOC_IF_T_H_ */\n";
 
@@ -267,9 +202,6 @@ open(OUT, ">$target_h") || die("Could not open $target_h, reason: $!\n");
 $creation_time = localtime(time());
 
 print OUT<<EOF;
-#ifndef _GEN_$tmp\_REGALLOC_IF_H_
-#define _GEN_$tmp\_REGALLOC_IF_H_
-
 /**
  * Contains additional external requirements defs for external includes.
  *
@@ -278,9 +210,11 @@ print OUT<<EOF;
  * created by: $0 $specfile $target_dir
  * date:       $creation_time
  */
+#ifndef _GEN_${tmp}_REGALLOC_IF_H_
+#define _GEN_${tmp}_REGALLOC_IF_H_
 
 #include "../bearch.h"
-#include "$arch\_nodes_attr.h"
+#include "${arch}_nodes_attr.h"
 
 EOF
 
@@ -296,8 +230,6 @@ print OUT "void ".$arch."_register_init(void *isa_ptr);\n\n";
 
 print OUT @obst_header_all, "\n";
 
-print OUT @obst_defreq_head, "\n";
-
 print OUT "\n#endif /* _GEN_$tmp\_REGALLOC_IF_H_ */\n";
 
 close(OUT);
@@ -320,24 +252,28 @@ print OUT<<EOF;
  * created by: $0 $specfile $target_dir
  * date:       $creation_time
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
-#include "gen_$arch\_regalloc_if.h"
-#include "gen_$arch\_machine.h"  /* we need this, as there can be units assigned to registers */
-#include "bearch_$arch\_t.h"     /* we need this to put the caller saved registers into the isa set */
-#include "$arch\_map_regs.h"
+#include "gen_${arch}_regalloc_if.h"
+#include "gen_${arch}_machine.h"
+#include "bearch_${arch}_t.h"
+#include "${arch}_map_regs.h"
 #include "irmode.h"
 
+#ifdef BIT
+#undef BIT
+#endif
+#define BIT(x)  (1 << (x % 32))
+
 EOF
 
-print OUT "arch_register_class_t $arch\_reg_classes[] = {\n  ".join(",\n  ", @obst_regclasses)."\n};\n\n";
+print OUT "arch_register_class_t ${arch}_reg_classes[] = {\n\t".join(",\n\t", @obst_regclasses)."\n};\n\n";
 
 print OUT @obst_regtypes_def, "\n";
 
-print OUT "void ".$arch."_register_init(void *isa_ptr) {\n";
+print OUT "void ${arch}_register_init(void *isa_ptr) {\n";
 print OUT @obst_reginit;
 print OUT "}\n\n";
 
@@ -366,11 +302,9 @@ sub build_inout_idx_class {
 
                        if ($reqs[$idx] eq "none") {
                                $class = "none";
-                       }
-                       elsif (is_reg_class($reqs[$idx])) {
+                       } elsif (is_reg_class($reqs[$idx])) {
                                $class = $reqs[$idx];
-                       }
-                       else {
+                       } else {
                                my @regs = split(/ /, $reqs[$idx]);
 GET_CLASS:             foreach my $reg (@regs) {
                                        if ($reg =~ /!?(in|out)\_r\d+/ || $reg =~ /!in/) {
@@ -411,39 +345,47 @@ sub generate_requirements {
        for (my $idx = 0; $idx <= $#reqs; $idx++) {
                my $class = undef;
 
-               my $tmp2 = "const $arch\_register_req_t _".$op."_reg_req_$inout\_$idx = ";
-               my $tmp  = "#define ".$op."_reg_req_$inout\_$idx ";
+               my $tmp2 = "const arch_register_req_t ${op}_reg_req_${inout}_${idx} = ";
 
                if ($reqs[$idx] eq "none") {
-                       $tmp .= "&$arch\_default_req_none\n";
-               }
-               elsif ($reqs[$idx] =~ /^new_reg_(.*)$/) {
+                       $tmp2 .= "{\n";
+                       $tmp2 .= "\tarch_register_req_type_none,\n";
+                       $tmp2 .= "\tNULL,        /* regclass */\n";
+                       $tmp2 .= "\tNULL,        /* limit bitset */\n";
+                       $tmp2 .= "\t-1,          /* same pos */\n";
+                       $tmp2 .= "\t-1           /* different pos */\n";
+                       $tmp2 .= "};\n";
+
+                       push(@obst_req, $tmp2."\n");
+                       push(@obst_header_t, "extern const arch_register_req_t ${op}_reg_req_${inout}_${idx};\n");
+               } elsif ($reqs[$idx] =~ /^new_reg_(.*)$/) {
                        if (is_reg_class($1)) {
-                               $tmp  .=  "&_".$op."_reg_req_$inout\_$idx\n";
                                $tmp2 .= "{\n";
-                               $tmp2 .= "  {\n";
-                               $tmp2 .= "    arch_register_req_type_should_be_different_from_all,\n";
-                               $tmp2 .= "    &$arch\_reg_classes[CLASS_$arch\_".$1."],\n";
-                               $tmp2 .= "    NULL,        /* limit function */\n";
-                               $tmp2 .= "    NULL,        /* limit environment */\n";
-                               $tmp2 .= "    NULL,        /* same node */\n";
-                               $tmp2 .= "    NULL         /* different node */\n";
-                               $tmp2 .= "  },\n";
-                               $tmp2 .= "  0,\n";
-                               $tmp2 .= "  0\n";
+                               $tmp2 .= "\tarch_register_req_type_should_be_different_from_all,\n";
+                               $tmp2 .= "\t&${arch}_reg_classes[CLASS_${arch}_$1],\n";
+                               $tmp2 .= "\tNULL,        /* limit bitset */\n";
+                               $tmp2 .= "\t-1,          /* same pos */\n";
+                               $tmp2 .= "\t-1           /* different pos */\n";
                                $tmp2 .= "};\n";
 
                                push(@obst_req, $tmp2."\n");
-                               push(@obst_header_all, "extern const $arch\_register_req_t _".$op."_reg_req_$inout\_$idx;\n");
-                       }
-                       else {
+                               push(@obst_header_t, "extern const arch_register_req_t ${op}_reg_req_${inout}_${idx};\n");
+                       } else {
                                print STDERR "Invalid register class '$1' given in OUT requirement $idx for '$op'.\n";
                        }
-               }
-               elsif (is_reg_class($reqs[$idx])) {
-                       $tmp .= "&$arch\_default_req_".$arch."_".$reqs[$idx]."\n";
-               }
-               else {
+               } elsif (is_reg_class($reqs[$idx])) {
+                       my $class = $reqs[$idx];
+                       $tmp2 .= "{\n";
+                       $tmp2 .= "\tarch_register_req_type_normal,\n";
+                       $tmp2 .= "\t&${arch}_reg_classes[CLASS_${arch}_${class}],\n";
+                       $tmp2 .= "\tNULL,        /* limit bitset */\n";
+                       $tmp2 .= "\t-1,          /* same pos */\n";
+                       $tmp2 .= "\t-1           /* different pos */\n";
+                       $tmp2 .= "};\n";
+
+                       push(@obst_req, $tmp2."\n");
+                       push(@obst_header_t, "extern const arch_register_req_t ${op}_reg_req_${inout}_${idx};\n");
+               } else {
                        my @req_type_mask;
                        my ($class, $has_limit, $same_pos, $different_pos) = build_subset_class_func($n, $op, $idx, (($inout eq "in") ? 1 : 0), $reqs[$idx]);
 
@@ -461,31 +403,22 @@ sub generate_requirements {
                                if ($different_pos == 666) {
                                        push(@req_type_mask, "arch_register_req_type_should_be_different_from_all");
                                        undef $different_pos;
-                               }
-                               else {
+                               } else {
                                        push(@req_type_mask, "arch_register_req_type_should_be_different");
                                }
                        }
 
-                       $tmp  .= "&_".$op."_reg_req_$inout\_$idx\n";
                        $tmp2 .= "{\n";
-                       $tmp2 .= "  {\n";
-                       $tmp2 .= "    ".join(" | ", @req_type_mask).",\n";
-                       $tmp2 .= "    &$arch\_reg_classes[CLASS_$arch\_".$class."],\n";
-                       $tmp2 .= "    ".($has_limit ? "limit_reg_".$op."_$inout\_".$idx : "NULL").",\n";
-                       $tmp2 .= "    NULL,        /* limit environment */\n";
-                       $tmp2 .= "    NULL,        /* same node */\n";
-                       $tmp2 .= "    NULL         /* different node */\n";
-                       $tmp2 .= "  },\n";
-                       $tmp2 .= "  ".(defined($same_pos) ? $same_pos : "0").",\n";
-                       $tmp2 .= "  ".(defined($different_pos) ? $different_pos : "0")."\n";
+                       $tmp2 .= "\t".join(" | ", @req_type_mask).",\n";
+                       $tmp2 .= "\t&${arch}_reg_classes[CLASS_${arch}_${class}],\n";
+                       $tmp2 .= "\t".($has_limit ? "limit_reg_${op}_${inout}_${idx}" : "NULL").",\n";
+                       $tmp2 .= "\t".(defined($same_pos) ? $same_pos : "-1").",\n";
+                       $tmp2 .= "\t".(defined($different_pos) ? $different_pos : "-1")."\n";
                        $tmp2 .= "};\n";
 
                        push(@obst_req, $tmp2."\n");
-                       push(@obst_header_all, "extern const $arch\_register_req_t _".$op."_reg_req_$inout\_$idx;\n");
+                       push(@obst_header_t, "extern const arch_register_req_t ${op}_reg_req_${inout}_${idx};\n");
                }
-
-               push(@obst_requirement_def, $tmp);
        }
 
 }
@@ -537,7 +470,7 @@ sub build_subset_class_func {
        my @obst_init;
        my @obst_limits;
        my @obst_ignore;
-
+       my @limit_array;
 
        # build function header
        my $n   = shift;
@@ -584,13 +517,11 @@ CHECK_REQS: foreach (@regs) {
 
                        if (!defined($neg)) {
                                $has_limit = 1;
-                               push(@obst_init, "  bs = bitset_set_all(bs);     /* allow all register (negative constraints given) */\n");
                        }
 
                        $_   = substr($_, 1); # skip '!'
                        $neg = 1;
-               }
-               else {
+               } else {
                        if (defined($neg) && $neg == 1) {
                                # we have seen a negative constraint as first one but this one is positive
                                # this doesn't make sense
@@ -598,10 +529,7 @@ CHECK_REQS: foreach (@regs) {
                                return (undef, undef, undef, undef);
                        }
 
-                       if (!defined($neg)) {
-                               $has_limit = 1;
-                               push(@obst_init, "  bs = bitset_clear_all(bs);   /* disallow all register (positive constraints given) */\n");
-                       }
+                       $has_limit = 1;
                        $neg = 0;
                }
 
@@ -615,40 +543,63 @@ CHECK_REQS: foreach (@regs) {
                # set class
                if (!defined($class)) {
                        $class = $temp;
-               }
-               elsif ($class ne $temp) {
+               } elsif ($class ne $temp) {
                        # all registers must belong to the same class
                        print STDERR "Registerclass mismatch. '$_' is not member of class '$class'.\n";
                        return (undef, undef, undef, undef);
                }
 
-               if ($neg == 1) {
-                       $has_limit = 1;
-                       push(@obst_limits, "  bitset_clear(bs, ".get_reg_index($_).");         /* disallow $_ */\n");
-               }
-               else {
-                       $has_limit = 1;
-                       push(@obst_limits, "  bitset_set(bs, ".get_reg_index($_).");           /* allow $_ */\n");
-               }
+               # calculate position inside the initializer bitfield (only 32 bits per
+               # element)
+               my $regidx = get_reg_index($_);
+               my $arrayp = $regidx / 32;
+               push(@{$limit_array[$arrayp]}, $_);
        }
 
-       my @cur_class = @{ $reg_classes{"$class"} };
-       for (my $idx = 0; $idx <= $#cur_class; $idx++) {
-               if (defined($cur_class[$idx]{"type"}) && ($cur_class[$idx]{"type"} & 4)) {
-                       push(@obst_ignore, "  bitset_clear(bs, ".get_reg_index($cur_class[$idx]{"name"}).");");
-                       push(@obst_ignore, "         /* disallow ignore reg ".$cur_class[$idx]{"name"}." */\n");
+       # don't allow ignore regs in negative constraints
+       if($neg) {
+               my @cur_class = @{ $reg_classes{"$class"} };
+               for (my $idx = 0; $idx <= $#cur_class; $idx++) {
+                       if (defined($cur_class[$idx]{"type"}) && ($cur_class[$idx]{"type"} & 4)) {
+                               my $reg = $cur_class[$idx]{"name"};
+                               my $regix = get_reg_index($reg);
+                               my $arrayp = $regix / 32;
+                               push(@{$limit_array[$arrayp]}, $reg);
+                       }
                }
        }
 
        if ($has_limit == 1) {
-               push(@obst_header_all, "void limit_reg_".$op."_".($in ? "in" : "out")."_".$idx."(void *_unused, bitset_t *bs);\n");
-
-               push(@obst_limit_func, "/* limit the possible registers for ".($in ? "IN" : "OUT")." $idx at op $op */\n");
-               push(@obst_limit_func, "void limit_reg_".$op."_".($in ? "in" : "out")."_".$idx."(void *_unused, bitset_t *bs) {\n");
-               push(@obst_limit_func, @obst_init);
-               push(@obst_limit_func, @obst_ignore);
-               push(@obst_limit_func, @obst_limits);
-               push(@obst_limit_func, "}\n\n");
+               push(@obst_limit_func, "static const unsigned limit_reg_${op}_".($in ? "in" : "out")."_${idx}[] = { ");
+               my $first = 1;
+               my $limitbitsetlen = $regclass2len{$class};
+               my $limitarraylen = $limitbitsetlen / 32 + ($limitbitsetlen % 32 > 0 ? 1 : 0);
+               for(my $i = 0; $i < $limitarraylen; $i++) {
+                       my $limitarraypart = $limit_array[$i];
+                       if($first) {
+                               $first = 0;
+                       } else {
+                               push(@obst_limit_func, ", ");
+                       }
+                       my $temp;
+                       if($neg) {
+                               $temp = "0xFFFFFFFF";
+                       }
+                       foreach my $reg (@{$limitarraypart}) {
+                               if($neg) {
+                                       $temp .= " & ~";
+                               } elsif(defined($temp)) {
+                                       $temp .= " | ";
+                               }
+                               $temp .= "BIT(REG_".uc(${reg}).")";
+                       }
+                       if(defined($temp)) {
+                               push(@obst_limit_func, "${temp}");
+                       } else {
+                               push(@obst_limit_func, "0");
+                       }
+               }
+               push(@obst_limit_func, " };\n");
        }
 
        return ($class, $has_limit, $same_pos, $different_pos);