prepare fields before generating globals so we avoid the need for relocating initiali...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 20:22:48 +0000 (21:22 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 20:22:48 +0000 (21:22 +0100)
ir.c
ir.h

diff --git a/ir.c b/ir.c
index ffaa76289189207bbb23b5074faf4fb5a72ab08b..bf08a5d426a8d874128905d1f9120056d8bccf7a 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -2448,25 +2448,12 @@ static bool gen_global_field(ir_value *global)
             return false;
         }
 
-        /* Now, in this case, a relocation would be impossible to code
-         * since it looks like this:
-         * .vector v = origin;     <- parse error, wtf is 'origin'?
-         * .vector origin;
-         *
-         * But we will need a general relocation support later anyway
-         * for functions... might as well support that here.
-         */
-        if (!fld->code.globaladdr) {
-            irerror(global->context, "FIXME: Relocation support");
-            return false;
-        }
-
         /* copy the field's value */
         ir_value_code_setaddr(global, vec_size(code_globals));
-        vec_push(code_globals, code_globals[fld->code.globaladdr]);
+        vec_push(code_globals, fld->code.fieldaddr);
         if (global->fieldtype == TYPE_VECTOR) {
-            vec_push(code_globals, code_globals[fld->code.globaladdr]+1);
-            vec_push(code_globals, code_globals[fld->code.globaladdr]+2);
+            vec_push(code_globals, fld->code.fieldaddr+1);
+            vec_push(code_globals, fld->code.fieldaddr+2);
         }
     }
     else
@@ -3120,6 +3107,11 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     }
 }
 
+static void ir_builder_prepare_field(ir_value *field)
+{
+    field->code.fieldaddr = code_alloc_field(type_sizeof[field->fieldtype]);
+}
+
 static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
 {
     prog_section_def def;
@@ -3171,7 +3163,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
         return false;
     }
 
-    fld.offset = code_alloc_field(type_sizeof[field->fieldtype]);
+    fld.offset = field->code.fieldaddr;
 
     vec_push(code_fields, fld);
 
@@ -3193,6 +3185,11 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
 
     code_init();
 
+    for (i = 0; i < vec_size(self->fields); ++i)
+    {
+        ir_builder_prepare_field(self->fields[i]);
+    }
+
     for (i = 0; i < vec_size(self->globals); ++i)
     {
         if (!ir_builder_gen_global(self, self->globals[i], false)) {
diff --git a/ir.h b/ir.h
index 6888e6c4172b85c2d111098d928ced47e4a4ce3c..a12827fc36898f8ac90036c4fcff81bff87569c5 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -67,6 +67,8 @@ typedef struct ir_value_s {
         int32_t local;
         /* added for members */
         int32_t addroffset;
+        /* to generate field-addresses early */
+        int32_t fieldaddr;
     } code;
 
     /* for acessing vectors */