Add arch_get_register_req_out().
[libfirm] / ir / be / ia32 / bearch_ia32.c
index 463fa1f..0b4599d 100644 (file)
@@ -89,6 +89,8 @@
 
 #ifdef FIRM_GRGEN_BE
 #include "ia32_pbqp_transform.h"
+
+transformer_t be_transformer = TRANSFORMER_DEFAULT;
 #endif
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
@@ -119,7 +121,7 @@ static ia32_intrinsic_env_t intrinsic_env = {
 
 typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_graph *irg, ir_node *block);
 
-static INLINE ir_node *create_const(ia32_code_gen_t *cg, ir_node **place,
+static inline ir_node *create_const(ia32_code_gen_t *cg, ir_node **place,
                                     create_const_node_func func,
                                     const arch_register_t* reg)
 {
@@ -957,8 +959,6 @@ static void ia32_before_abi(void *self) {
        }
 }
 
-transformer_t be_transformer = TRANSFORMER_DEFAULT;
-
 /**
  * Transforms the standard firm graph into
  * an ia32 firm graph
@@ -981,20 +981,21 @@ static void ia32_prepare_graph(void *self) {
                be_dump(cg->irg, "-pre_transform", dump_ir_block_graph_sched);
 
        switch (be_transformer) {
-               case TRANSFORMER_DEFAULT:
-                       /* transform remaining nodes into assembler instructions */
-                       ia32_transform_graph(cg);
-                       break;
+       case TRANSFORMER_DEFAULT:
+               /* transform remaining nodes into assembler instructions */
+               ia32_transform_graph(cg);
+               break;
 
 #ifdef FIRM_GRGEN_BE
-               case TRANSFORMER_PBQP:
-               case TRANSFORMER_RAND:
-                       /* transform nodes into assembler instructions by PBQP magic */
-                       ia32_transform_graph_by_pbqp(cg);
-                       break;
+       case TRANSFORMER_PBQP:
+       case TRANSFORMER_RAND:
+               /* transform nodes into assembler instructions by PBQP magic */
+               ia32_transform_graph_by_pbqp(cg);
+               break;
 #endif
 
-               default: panic("invalid transformer");
+       default:
+               panic("invalid transformer");
        }
 
        /* do local optimizations (mainly CSE) */
@@ -1433,45 +1434,73 @@ static void ia32_after_ra_walker(ir_node *block, void *env) {
  */
 static void ia32_collect_frame_entity_nodes(ir_node *node, void *data)
 {
-       be_fec_env_t *env = data;
+       be_fec_env_t  *env = data;
+       const ir_mode *mode;
+       int            align;
 
        if (be_is_Reload(node) && be_get_frame_entity(node) == NULL) {
-               const ir_mode *mode = get_spill_mode_mode(get_irn_mode(node));
-               int align = get_mode_size_bytes(mode);
-               be_node_needs_frame_entity(env, node, mode, align);
-       } else if(is_ia32_irn(node) && get_ia32_frame_ent(node) == NULL
-                 && is_ia32_use_frame(node)) {
-               if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
-                       const ir_mode     *mode  = get_ia32_ls_mode(node);
-                       const ia32_attr_t *attr  = get_ia32_attr_const(node);
-                       int                align;
-
-                       if (is_ia32_is_reload(node)) {
-                               mode = get_spill_mode_mode(mode);
+               mode  = get_spill_mode_mode(get_irn_mode(node));
+               align = get_mode_size_bytes(mode);
+       } else if (is_ia32_irn(node)         &&
+                       get_ia32_frame_ent(node) == NULL &&
+                       is_ia32_use_frame(node)) {
+               if (is_ia32_need_stackent(node))
+                       goto need_stackent;
+
+               switch (get_ia32_irn_opcode(node)) {
+need_stackent:
+                       case iro_ia32_Load: {
+                               const ia32_attr_t *attr = get_ia32_attr_const(node);
+
+                               if (attr->data.need_32bit_stackent) {
+                                       mode = mode_Is;
+                               } else if (attr->data.need_64bit_stackent) {
+                                       mode = mode_Ls;
+                               } else {
+                                       mode = get_ia32_ls_mode(node);
+                                       if (is_ia32_is_reload(node))
+                                               mode = get_spill_mode_mode(mode);
+                               }
+                               align = get_mode_size_bytes(mode);
+                               break;
                        }
 
-                       if(attr->data.need_64bit_stackent) {
-                               mode = mode_Ls;
+                       case iro_ia32_vfild:
+                       case iro_ia32_vfld:
+                       case iro_ia32_xLoad: {
+                               mode  = get_ia32_ls_mode(node);
+                               align = 4;
+                               break;
                        }
-                       if(attr->data.need_32bit_stackent) {
-                               mode = mode_Is;
+
+                       case iro_ia32_FldCW: {
+                               /* although 2 byte would be enough 4 byte performs best */
+                               mode  = mode_Iu;
+                               align = 4;
+                               break;
                        }
-                       align = get_mode_size_bytes(mode);
-                       be_node_needs_frame_entity(env, node, mode, align);
-               } else if (is_ia32_vfild(node) || is_ia32_xLoad(node)
-                          || is_ia32_vfld(node)) {
-                       const ir_mode *mode  = get_ia32_ls_mode(node);
-                       int            align = 4;
-                       be_node_needs_frame_entity(env, node, mode, align);
-               } else if(is_ia32_FldCW(node)) {
-                       /* although 2 byte would be enough 4 byte performs best */
-                       const ir_mode *mode  = mode_Iu;
-                       int            align = 4;
-                       be_node_needs_frame_entity(env, node, mode, align);
-               } else {
-                       assert(is_ia32_St(node));
+
+                       default:
+#ifndef NDEBUG
+                               panic("unexpected frame user while collection frame entity nodes");
+
+                       case iro_ia32_FnstCW:
+                       case iro_ia32_Store8Bit:
+                       case iro_ia32_Store:
+                       case iro_ia32_fst:
+                       case iro_ia32_fstp:
+                       case iro_ia32_vfist:
+                       case iro_ia32_vfisttp:
+                       case iro_ia32_vfst:
+                       case iro_ia32_xStore:
+                       case iro_ia32_xStoreSimple:
+#endif
+                               return;
                }
+       } else {
+               return;
        }
+       be_node_needs_frame_entity(env, node, mode, align);
 }
 
 /**
@@ -2326,22 +2355,24 @@ static lc_opt_enum_int_var_t gas_var = {
        (int*) &be_gas_flavour, gas_items
 };
 
+#ifdef FIRM_GRGEN_BE
 static const lc_opt_enum_int_items_t transformer_items[] = {
        { "default", TRANSFORMER_DEFAULT },
-#ifdef FIRM_GRGEN_BE
        { "pbqp",    TRANSFORMER_PBQP    },
        { "random",  TRANSFORMER_RAND    },
-#endif
        { NULL,      0                   }
 };
 
 static lc_opt_enum_int_var_t transformer_var = {
        (int*)&be_transformer, transformer_items
 };
+#endif
 
 static const lc_opt_table_entry_t ia32_options[] = {
        LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
+#ifdef FIRM_GRGEN_BE
        LC_OPT_ENT_ENUM_INT("transformer", "the transformer used for code selection", &transformer_var),
+#endif
        LC_OPT_ENT_INT("stackalign", "set power of two stack alignment for calls",
                       &ia32_isa_template.arch_env.stack_alignment),
        LC_OPT_LAST