orcc: workaround a bug in the gcc 4.2 provided by XCode 3.2.6
authorJosep Torra <n770galaxy@gmail.com>
Wed, 20 Feb 2013 14:32:49 +0000 (15:32 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 20 Feb 2013 14:32:49 +0000 (15:32 +0100)
When building orc in OSX Snow Leopard with '-O2 -arch i386 -m32' a bug in
the compiler is triggered and wrong assembly is generated with
the following messages:

'non-relocatable subtraction expression, "LC0" minus "L00000000008$pb"'
'symbol: "L00000000008$pb" can't be undefined in a subtraction expression'
'undefined local symbol L00000000008$pb'

The issue is triggered when the compiler tries to optimize for a constant
value in the code but it does a bad job. Declaring 'volatile' the variable
that holds the constant prevents this optimization to be performed and the
orc C generated code can be properly built.

orc/orccompiler.c
orc/orcprogram-c.c
orc/orcvariable.h

index 2175206..c30226a 100644 (file)
@@ -580,6 +580,10 @@ orc_compiler_rewrite_insns (OrcCompiler *compiler)
           cinsn->opcode = get_loadp_opcode_for_size (opcode->src_size[i]);
           cinsn->dest_args[0] = orc_compiler_new_temporary (compiler,
               opcode->src_size[i] * multiplier);
+          if (var->vartype == ORC_VAR_TYPE_CONST) {
+            compiler->vars[cinsn->dest_args[0]].flags |=
+                ORC_VAR_FLAG_VOLATILE_WORKAROUND;
+          }
           cinsn->src_args[0] = insn.src_args[i];
           insn.src_args[i] = cinsn->dest_args[0];
 
index 83994a1..8391ccc 100644 (file)
@@ -243,7 +243,18 @@ orc_compiler_c_assemble (OrcCompiler *compiler)
         break;
       case ORC_VAR_TYPE_TEMP:
         if (!(var->last_use == -1 && var->first_use == 0)) {
-          ORC_ASM_CODE(compiler,"  %s var%d;\n", c_get_type_name(var->size), i);
+          if (var->flags & ORC_VAR_FLAG_VOLATILE_WORKAROUND) {
+            ORC_ASM_CODE(compiler,"#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__) \n");
+            ORC_ASM_CODE(compiler,"  volatile %s var%d;\n",
+                c_get_type_name(var->size), i);
+            ORC_ASM_CODE(compiler,"#else\n");
+            ORC_ASM_CODE(compiler,"  %s var%d;\n",
+                c_get_type_name(var->size), i);
+            ORC_ASM_CODE(compiler,"#endif\n");
+          } else {
+            ORC_ASM_CODE(compiler,"  %s var%d;\n",
+                c_get_type_name(var->size), i);
+          }
         }
         break;
       case ORC_VAR_TYPE_SRC:
index c522c88..28a7bb4 100644 (file)
@@ -13,6 +13,8 @@
 
 ORC_BEGIN_DECLS
 
+#define ORC_VAR_FLAG_VOLATILE_WORKAROUND (1<<0)
+
 typedef struct _OrcVariable OrcVariable;
 
 typedef enum {
@@ -67,6 +69,7 @@ struct _OrcVariable {
   int load_dest;
   int update_type;
   int need_offset_reg;
+  unsigned int flags;
 };
 
 ORC_END_DECLS