Let foreach_set() declare the iterator variable.
[libfirm] / ir / be / arm / arm_emitter.c
index 85f3abb..f67e5a6 100644 (file)
@@ -21,7 +21,6 @@
  * @file
  * @brief   arm emitter
  * @author  Oliver Richter, Tobias Gneist, Michael Beck
- * @version $Id$
  */
 #include "config.h"
 
@@ -46,7 +45,7 @@
 #include "beblocksched.h"
 #include "beirg.h"
 #include "begnuas.h"
-#include "be_dbgout.h"
+#include "bedwarf.h"
 
 #include "arm_emitter.h"
 #include "arm_optimize.h"
@@ -58,8 +57,6 @@
 
 #include "benode.h"
 
-#define SNPRINTF_BUF_LEN 128
-
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 static set       *sym_or_tv;
@@ -264,7 +261,7 @@ static void emit_arm_SymConst(const ir_node *irn)
        key.u.entity  = attr->entity;
        key.is_entity = true;
        key.label     = 0;
-       entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
+       entry = set_insert(sym_or_tv_t, sym_or_tv, &key, sizeof(key), hash_ptr(key.u.generic));
        if (entry->label == 0) {
                /* allocate a label */
                entry->label = get_unique_label();
@@ -302,7 +299,7 @@ static void emit_arm_fConst(const ir_node *irn)
        key.u.tv      = get_fConst_value(irn);
        key.is_entity = false;
        key.label     = 0;
-       entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
+       entry = set_insert(sym_or_tv_t, sym_or_tv, &key, sizeof(key), hash_ptr(key.u.generic));
        if (entry->label == 0) {
                /* allocate a label */
                entry->label = get_unique_label();
@@ -413,10 +410,12 @@ static void emit_arm_B(const ir_node *irn)
        be_emit_finish_line_gas(proj_true);
 
        if (get_cfop_target_block(proj_false) == next_block) {
-               be_emit_cstring("\t/* fallthrough to ");
-               arm_emit_cfop_target(proj_false);
-               be_emit_cstring(" */");
-               be_emit_finish_line_gas(proj_false);
+               if (be_options.verbose_asm) {
+                       be_emit_cstring("\t/* fallthrough to ");
+                       arm_emit_cfop_target(proj_false);
+                       be_emit_cstring(" */");
+                       be_emit_finish_line_gas(proj_false);
+               }
        } else {
                be_emit_cstring("\tb ");
                arm_emit_cfop_target(proj_false);
@@ -462,20 +461,22 @@ static void emit_arm_CopyB(const ir_node *irn)
        t2 = arch_register_get_name(tmpregs[2]);
        t3 = arch_register_get_name(tmpregs[3]);
 
-       be_emit_cstring("/* MemCopy (");
-       be_emit_string(src);
-       be_emit_cstring(")->(");
-       arm_emit_source_register(irn, 0);
-       be_emit_irprintf(" [%u bytes], Uses ", size);
-       be_emit_string(t0);
-       be_emit_cstring(", ");
-       be_emit_string(t1);
-       be_emit_cstring(", ");
-       be_emit_string(t2);
-       be_emit_cstring(", and ");
-       be_emit_string(t3);
-       be_emit_cstring("*/");
-       be_emit_finish_line_gas(NULL);
+       if (be_options.verbose_asm) {
+               be_emit_cstring("/* MemCopy (");
+               be_emit_string(src);
+               be_emit_cstring(")->(");
+               arm_emit_source_register(irn, 0);
+               be_emit_irprintf(" [%u bytes], Uses ", size);
+               be_emit_string(t0);
+               be_emit_cstring(", ");
+               be_emit_string(t1);
+               be_emit_cstring(", ");
+               be_emit_string(t2);
+               be_emit_cstring(", and ");
+               be_emit_string(t3);
+               be_emit_cstring("*/");
+               be_emit_finish_line_gas(NULL);
+       }
 
        assert(size > 0 && "CopyB needs size > 0" );
 
@@ -579,80 +580,13 @@ static void emit_arm_CopyB(const ir_node *irn)
 
 static void emit_arm_SwitchJmp(const ir_node *irn)
 {
-       const ir_edge_t    *edge;
-       ir_node            *proj;
-       int i;
-       ir_node **projs;
-       int n_projs;
-       int block_nr;
-       ir_node *default_proj = NULL;
-
-       block_nr = get_irn_node_nr(irn);
-       n_projs = get_arm_SwitchJmp_n_projs(irn);
-
-       projs = XMALLOCNZ(ir_node*, n_projs);
-
-       foreach_out_edge(irn, edge) {
-               proj = get_edge_src_irn(edge);
-               assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
-
-               if (get_Proj_proj(proj) == get_arm_SwitchJmp_default_proj_num(irn))
-                       default_proj = proj;
-
-               projs[get_Proj_proj(proj)] = proj;
-       }
-       assert(default_proj != NULL && "SwitchJmp should have a Default Proj");
-
-       /*
-          CMP %1S, n_projs - 1
-          BHI default
-       */
-
-       be_emit_cstring("\tcmp ");
+       const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(irn);
+       be_emit_cstring("\tldrls pc, [pc, ");
        arm_emit_source_register(irn, 0);
-       be_emit_irprintf(", #%u", n_projs - 1);
+       be_emit_cstring(", asl #2]");
        be_emit_finish_line_gas(irn);
 
-       be_emit_cstring("\tbhi ");
-       arm_emit_cfop_target(default_proj);
-       be_emit_finish_line_gas(default_proj);
-
-       /*
-          LDR %r12, .TABLE_X_START
-          ADD %r12, %r12, [%1S, LSL #2]
-          LDR %r15, %r12
-        */
-
-       be_emit_irprintf("\tldr %%r12, TABLE_%d_START", block_nr);
-       be_emit_finish_line_gas(NULL);
-
-       be_emit_irprintf("\tadd %%r12, %%r12, ");
-       arm_emit_source_register(irn, 0);
-       be_emit_cstring(", LSL #2");
-       be_emit_finish_line_gas(NULL);
-
-       be_emit_cstring("\tldr %r15, [%r12, #0]");
-       be_emit_finish_line_gas(NULL);
-
-       be_emit_irprintf("TABLE_%d_START:\n\t.word\tTABLE_%d", block_nr, block_nr);
-       be_emit_finish_line_gas(NULL);
-       be_emit_irprintf("\t.align 2");
-       be_emit_finish_line_gas(NULL);
-       be_emit_irprintf("TABLE_%d:", block_nr);
-       be_emit_finish_line_gas(NULL);
-
-       for (i = 0; i < n_projs; ++i) {
-               proj = projs[i];
-               if (proj == NULL) {
-                       proj = projs[get_arm_SwitchJmp_default_proj_num(irn)];
-               }
-               be_emit_cstring("\t.word\t");
-               arm_emit_cfop_target(proj);
-               be_emit_finish_line_gas(proj);
-       }
-       be_emit_irprintf("\t.align 2\n");
-       be_emit_finish_line_gas(NULL);
-       xfree(projs);
+       be_emit_jump_table(irn, attr->table, NULL, get_cfop_target_block);
 }
 
 /** Emit an IncSP node */
@@ -829,12 +763,15 @@ static void emit_arm_Jmp(const ir_node *node)
        if (get_cfop_target_block(node) != next_block) {
                be_emit_cstring("\tb ");
                arm_emit_cfop_target(node);
+               be_emit_finish_line_gas(node);
        } else {
-               be_emit_cstring("\t/* fallthrough to ");
-               arm_emit_cfop_target(node);
-               be_emit_cstring(" */");
+               if (be_options.verbose_asm) {
+                       be_emit_cstring("\t/* fallthrough to ");
+                       arm_emit_cfop_target(node);
+                       be_emit_cstring(" */");
+                       be_emit_finish_line_gas(node);
+               }
        }
-       be_emit_finish_line_gas(node);
 }
 
 static void emit_nothing(const ir_node *irn)
@@ -862,7 +799,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node)
 static void arm_register_emitters(void)
 {
        /* first clear the generic function pointer for all ops */
-       clear_irp_opcodes_generic_func();
+       ir_clear_opcodes_generic_func();
 
        /* register all emitter functions defined in spec */
        arm_register_spec_emitters();
@@ -897,11 +834,11 @@ static void arm_emit_node(const ir_node *irn)
 
        if (op->ops.generic) {
                emit_func *emit = (emit_func *)op->ops.generic;
-               be_dbg_set_dbg_info(get_irn_dbg_info(irn));
+               be_dwarf_location(get_irn_dbg_info(irn));
                (*emit)(irn);
        } else {
                panic("Error: No emit handler for node %+F (graph %+F)\n",
-                     irn, current_ir_graph);
+                     irn, get_irn_irg(irn));
        }
 }
 
@@ -910,13 +847,9 @@ static void arm_emit_node(const ir_node *irn)
  */
 static void arm_emit_block_header(ir_node *block, ir_node *prev)
 {
-       int           n_cfgpreds;
-       int           need_label;
-       int           i, arity;
-       ir_graph      *irg       = get_irn_irg(block);
-       ir_exec_freq  *exec_freq = be_get_irg_exec_freq(irg);
+       bool need_label = false;
+       int  n_cfgpreds;
 
-       need_label = 0;
        n_cfgpreds = get_Block_n_cfgpreds(block);
        if (n_cfgpreds == 1) {
                ir_node *pred       = get_Block_cfgpred(block, 0);
@@ -926,38 +859,15 @@ static void arm_emit_block_header(ir_node *block, ir_node *prev)
                 * are no fallthroughs */
                if (pred_block == prev &&
                                !(is_Proj(pred) && is_arm_SwitchJmp(get_Proj_pred(pred)))) {
-                       need_label = 0;
+                       need_label = false;
                } else {
-                       need_label = 1;
+                       need_label = true;
                }
        } else {
-               need_label = 1;
+               need_label = true;
        }
 
-       if (need_label) {
-               be_gas_emit_block_name(block);
-               be_emit_char(':');
-
-               be_emit_pad_comment();
-               be_emit_cstring("   /* 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);
-                       be_emit_irprintf(" %d", get_irn_node_nr(predblock));
-               }
-       } else {
-               be_emit_cstring("\t/* ");
-               be_gas_emit_block_name(block);
-               be_emit_cstring(": ");
-       }
-       if (exec_freq != NULL) {
-               be_emit_irprintf(" freq: %f",
-                                get_block_execfreq(exec_freq, block));
-       }
-       be_emit_cstring(" */\n");
-       be_emit_write_line();
+       be_gas_begin_block(block, need_label);
 }
 
 /**
@@ -969,7 +879,7 @@ static void arm_gen_block(ir_node *block, ir_node *prev_block)
        ir_node *irn;
 
        arm_emit_block_header(block, prev_block);
-       be_dbg_set_dbg_info(get_irn_dbg_info(block));
+       be_dwarf_location(get_irn_dbg_info(block));
        sched_foreach(block, irn) {
                arm_emit_node(irn);
        }
@@ -1023,7 +933,7 @@ void arm_gen_routine(ir_graph *irg)
        /* create the block schedule */
        blk_sched = be_create_block_schedule(irg);
 
-       be_gas_emit_function_prolog(entity, 4);
+       be_gas_emit_function_prolog(entity, 4, NULL);
 
        irg_block_walk_graph(irg, arm_gen_labels, NULL, NULL);
 
@@ -1043,11 +953,9 @@ void arm_gen_routine(ir_graph *irg)
 
        /* emit SymConst values */
        if (set_count(sym_or_tv) > 0) {
-               sym_or_tv_t *entry;
-
                be_emit_cstring("\t.align 2\n");
 
-               foreach_set(sym_or_tv, sym_or_tv_t*, entry) {
+               foreach_set(sym_or_tv, sym_or_tv_t, entry) {
                        emit_constant_name(entry);
                        be_emit_cstring(":\n");
                        be_emit_write_line();