fix things when WITH_JVM and WITH_ILP is defined
authorMatthias Braun <matze@braunis.de>
Thu, 21 Dec 2006 14:57:40 +0000 (14:57 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 21 Dec 2006 14:57:40 +0000 (14:57 +0000)
ir/be/bejavacoal.c
ir/be/bemain.c
ir/be/bemodules.c [new file with mode: 0644]
ir/be/bemodules.h [new file with mode: 0644]
ir/be/ia32/ia32_spec.pl

index 82a2e24..3ef97db 100644 (file)
@@ -20,6 +20,8 @@
 #include <stdio.h>
 
 #include "bejavacoal.h"
+#include "irtools.h"
+#include "bemodule.h"
 
 #ifdef WITH_JVM
 
@@ -48,7 +50,7 @@ void be_init_javacoal(void)
        lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
        lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
        lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
-       lc_opt_entry_t *jc_grp = lc_opt_get_grp(grp, "jc");
+       lc_opt_entry_t *jc_grp = lc_opt_get_grp(chordal_grp, "jc");
        lc_opt_add_table(jc_grp, options);
 }
 
index bfc6e0e..5a67164 100644 (file)
@@ -546,7 +546,6 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                edges_activate(irg);
 
                /* Compute loop nesting information (for weighting copies) */
-               construct_cf_backedges(irg);
                dump(DUMP_PREPARED, irg, "-prepared", dump_ir_block_graph);
                BE_TIMER_ONLY(num_nodes_r = get_num_reachable_nodes(irg));
 
diff --git a/ir/be/bemodules.c b/ir/be/bemodules.c
new file mode 100644 (file)
index 0000000..7ec3fd0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Author:      Matthias Braun
+ * Date:        29.09.2005
+ * Copyright:   (c) Universitaet Karlsruhe
+ * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include "bemodules.h"
+#include "xmalloc.h"
+
+typedef struct _constructor_list_entry_t {
+       struct _constructor_list_entry_t *next;
+       be_module_constructor_func func;
+} constructor_list_entry_t;
+
+static constructor_list_entry_t *constructors = NULL;
+
+static void free_constructor_list(void)
+{
+       constructor_list_entry_t *entry = constructors;
+
+       while(entry != NULL) {
+               constructor_list_entry_t *next = entry->next;
+               free(entry);
+               entry = next;
+       }
+}
+
+void be_module_add_constructor(be_module_constructor_func func)
+{
+       static int initialized = 0;
+       constructor_list_entry_t *entry;
+
+       if(!initialized) {
+               atexit(free_constructor_list);
+               initialized = 1;
+       }
+
+       entry = xmalloc(sizeof(entry[0]));
+       entry->next = constructors;
+       entry->func = func;
+
+       constructors = entry;
+}
+
+void be_module_call_constructors()
+{
+       constructor_list_entry_t *entry;
+
+       for(entry = constructors; entry != NULL; entry = entry->next) {
+               entry->func();
+       }
+}
diff --git a/ir/be/bemodules.h b/ir/be/bemodules.h
new file mode 100644 (file)
index 0000000..2f687f2
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Author:      Matthias Braun
+ * Date:               11.12.2006
+ * Copyright:   (c) Universitaet Karlsruhe
+ * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
+#ifndef BEMODULES_H_
+#define BEMODULES_H_
+
+typedef void (*be_module_constructor_func)(void);
+
+/**
+ * Use this macro to register a module constructor. You should put this macro in
+ * a .c file of your module. Compiler magic will make sure that your constructor
+ * function gets called after the main backend structures are initialized.
+ *
+ * The module constructor is a convenient place to register commandline options,
+ * or add the module to extension lists.
+ */
+#define BE_REGISTER_MODULE_CONSTRUCTOR(func) \
+       static void __attribute__((constructor)) _be_constructor(void) \
+       {                                                              \
+               be_module_add_constructor(func);                           \
+       }
+
+// TODO msvc version
+
+/**
+ * Warning: internal function, use BE_REGISTER_MODULE_CONSTRUCTOR instead.
+ *
+ * This function registers the constructor function of a backend module
+ */
+void be_module_add_constructor(be_module_constructor_func func);
+
+/**
+ * Call all registered constructor functions
+ */
+void be_module_call_constructors(void);
+
+#endif
index 8a4e9cc..bd89dbd 100644 (file)
@@ -109,78 +109,60 @@ $comment_string_end = "*/";
 #  16 - the register is a virtual one
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
-  "gp" => [
-            { "name" => "eax", "type" => 1 },
-            { "name" => "edx", "type" => 1 },
-            { "name" => "ebx", "type" => 2 },
-            { "name" => "ecx", "type" => 1 },
-            { "name" => "esi", "type" => 2 },
-            { "name" => "edi", "type" => 2 },
-#            { "name" => "r11", "type" => 1 },
-#            { "name" => "r12", "type" => 1 },
-#            { "name" => "r13", "type" => 1 },
-#            { "name" => "r14", "type" => 1 },
-#            { "name" => "r15", "type" => 1 },
-#            { "name" => "r16", "type" => 1 },
-#            { "name" => "r17", "type" => 1 },
-#            { "name" => "r18", "type" => 1 },
-#            { "name" => "r19", "type" => 1 },
-#            { "name" => "r20", "type" => 1 },
-#            { "name" => "r21", "type" => 1 },
-#            { "name" => "r22", "type" => 1 },
-#            { "name" => "r23", "type" => 1 },
-#            { "name" => "r24", "type" => 1 },
-#            { "name" => "r25", "type" => 1 },
-#            { "name" => "r26", "type" => 1 },
-#            { "name" => "r27", "type" => 1 },
-#            { "name" => "r28", "type" => 1 },
-#            { "name" => "r29", "type" => 1 },
-#            { "name" => "r30", "type" => 1 },
-#            { "name" => "r31", "type" => 1 },
-#            { "name" => "r32", "type" => 1 },
-            { "name" => "ebp", "type" => 2 },
-            { "name" => "esp", "type" => 4 },
-            { "name" => "gp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "gp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_P" }
-          ],
-  "xmm" => [
-            { "name" => "xmm0", "type" => 1 },
-            { "name" => "xmm1", "type" => 1 },
-            { "name" => "xmm2", "type" => 1 },
-            { "name" => "xmm3", "type" => 1 },
-            { "name" => "xmm4", "type" => 1 },
-            { "name" => "xmm5", "type" => 1 },
-            { "name" => "xmm6", "type" => 1 },
-            { "name" => "xmm7", "type" => 1 },
-            { "name" => "xmm_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "xmm_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_D" }
-          ],
-  "vfp" => [
-            { "name" => "vf0", "type" => 1 | 16 },
-            { "name" => "vf1", "type" => 1 | 16 },
-            { "name" => "vf2", "type" => 1 | 16 },
-            { "name" => "vf3", "type" => 1 | 16 },
-            { "name" => "vf4", "type" => 1 | 16 },
-            { "name" => "vf5", "type" => 1 | 16 },
-            { "name" => "vf6", "type" => 1 | 16 },
-            { "name" => "vf7", "type" => 1 | 16 },
-            { "name" => "vfp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "vfp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_E" }
-          ],
-  "st" => [
-            { "name" => "st0", "type" => 1 },
-            { "name" => "st1", "type" => 1 },
-            { "name" => "st2", "type" => 1 },
-            { "name" => "st3", "type" => 1 },
-            { "name" => "st4", "type" => 1 },
-            { "name" => "st5", "type" => 1 },
-            { "name" => "st6", "type" => 1 },
-            { "name" => "st7", "type" => 1 },
-                       { "mode" => "mode_E" }
-          ]
+       "gp" => [
+               { "name" => "eax", "type" => 1 },
+               { "name" => "edx", "type" => 1 },
+               { "name" => "ebx", "type" => 2 },
+               { "name" => "ecx", "type" => 1 },
+               { "name" => "esi", "type" => 2 },
+               { "name" => "edi", "type" => 2 },
+               { "name" => "ebp", "type" => 2 },
+               { "name" => "esp", "type" => 4 },
+               { "name" => "gp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+               { "name" => "gp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_P" }
+       ],
+       "xmm" => [
+               { "name" => "xmm0", "type" => 1 },
+               { "name" => "xmm1", "type" => 1 },
+               { "name" => "xmm2", "type" => 1 },
+               { "name" => "xmm3", "type" => 1 },
+               { "name" => "xmm4", "type" => 1 },
+               { "name" => "xmm5", "type" => 1 },
+               { "name" => "xmm6", "type" => 1 },
+               { "name" => "xmm7", "type" => 1 },
+               { "name" => "xmm_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+               { "name" => "xmm_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_D" }
+       ],
+       "vfp" => [
+               { "name" => "vf0", "type" => 1 | 16 },
+               { "name" => "vf1", "type" => 1 | 16 },
+               { "name" => "vf2", "type" => 1 | 16 },
+               { "name" => "vf3", "type" => 1 | 16 },
+               { "name" => "vf4", "type" => 1 | 16 },
+               { "name" => "vf5", "type" => 1 | 16 },
+               { "name" => "vf6", "type" => 1 | 16 },
+               { "name" => "vf7", "type" => 1 | 16 },
+               { "name" => "vfp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+               { "name" => "vfp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_E" }
+       ],
+       "st" => [
+               { "name" => "st0", "type" => 1 },
+               { "name" => "st1", "type" => 1 },
+               { "name" => "st2", "type" => 1 },
+               { "name" => "st3", "type" => 1 },
+               { "name" => "st4", "type" => 1 },
+               { "name" => "st5", "type" => 1 },
+               { "name" => "st6", "type" => 1 },
+               { "name" => "st7", "type" => 1 },
+               { "mode" => "mode_E" }
+       ],
+       "fp_cw" => [    # the floating point control word
+               { "name" => "fpcw", "type" => 0 },
+        { "mode" => "mode_Hu" },
+       ],
 ); # %reg_classes
 
 %cpu = (
@@ -708,6 +690,37 @@ else {
   "units"     => [ "ALU" ],
 },
 
+"ChangeCW" => {
+  "irn_flags" => "R",
+  "comment"   => "change floating point control word",
+  "reg_req"   => { "out" => [ "fp_cw" ] },
+  "mode"      => "mode_Hu",
+  "latency"   => 3,
+  "units"     => [ "ALU" ],
+},
+
+"FldCW" => {
+  "op_flags"  => "L|F",
+  "state"     => "exc_pinned",
+  "comment"   => "load floating point control word FldCW(ptr, mem) = LD ptr -> reg",
+  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "fp_cw" ] },
+  "latency"   => 5,
+  "emit"      => ". fldcw %ia32_emit_am /* FldCW(%A1) -> %D1 */",
+  "mode"      => "mode_Hu",
+  "units"     => [ "MEM" ],
+},
+
+"FstCW" => {
+  "op_flags"  => "L|F",
+  "state"     => "exc_pinned",
+  "comment"   => "store floating point control word: FstCW(ptr, mem) = ST ptr -> reg",
+  "reg_req"   => { "in" => [ "gp", "gp", "fp_cw", "none" ] },
+  "latency"   => 5,
+  "emit"      => ". fstcw %ia32_emit_am /* FstCW(%A3) -> %A1 */",
+  "mode"      => "mode_M",
+  "units"     => [ "MEM" ],
+},
+
 "Cdq" => {
   # we should not rematrialize this node. It produces 2 results and has
   # very strict constrains