summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosep Torra <n770galaxy@gmail.com>2013-02-20 15:32:49 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2013-02-20 15:32:49 +0100
commit6597e084d9b9524ab199fb3019fa307b6588fd88 (patch)
tree4f98e6f228c5884ec7b59c0a50b1cf918f271f68
parente9430261015d8f059ff1359f89c137895e50c81e (diff)
orcc: workaround a bug in the gcc 4.2 provided by XCode 3.2.6
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.
-rw-r--r--orc/orccompiler.c4
-rw-r--r--orc/orcprogram-c.c13
-rw-r--r--orc/orcvariable.h3
3 files changed, 19 insertions, 1 deletions
diff --git a/orc/orccompiler.c b/orc/orccompiler.c
index 2175206..c30226a 100644
--- a/orc/orccompiler.c
+++ b/orc/orccompiler.c
@@ -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];
diff --git a/orc/orcprogram-c.c b/orc/orcprogram-c.c
index 83994a1..8391ccc 100644
--- a/orc/orcprogram-c.c
+++ b/orc/orcprogram-c.c
@@ -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:
diff --git a/orc/orcvariable.h b/orc/orcvariable.h
index c522c88..28a7bb4 100644
--- a/orc/orcvariable.h
+++ b/orc/orcvariable.h
@@ -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