Blob Blame History Raw
From 29486d8c98655a6e14ec2af9f71489cbdda41a53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
Date: Sat, 8 Nov 2014 13:23:12 +0000
Subject: [PATCH] orcc: program-c: fix 64-bit parameter loading (loadpq) on
 big-endian systems

When passing 64-bit parameters through OrcExecutor, we
have to split them up into two 32-bit parameters for
backwards compatibility reasons. When generating C code,
make sure that we split up 64-bit parameters in the same
way as loadpq will read them back later. The lower 32 bits
should end up in params[ORC_VAR_D1+i] and the higher bits
should end up in params[ORC_VAR_T1+i]. The way it was done
so far, the higher/lower bits ended up swapped on big endian
systems, and then got deserialised in swapped order by loadpq.
This resulted in bogus parameters being used.

In particular, this broke the gstreamer volume element and
its unit tests on big endian systems when handling samples
in F64 format (i.e. doubles).

https://bugzilla.gnome.org/show_bug.cgi?id=739354
---
 tools/orcc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/orcc.c b/tools/orcc.c
index d25b548..fdab530 100644
--- a/tools/orcc.c
+++ b/tools/orcc.c
@@ -843,9 +843,9 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
           fprintf(output, "  {\n");
           fprintf(output, "    orc_union64 tmp;\n");
           fprintf(output, "    tmp.i = %s;\n", varnames[ORC_VAR_P1 + i]);
-          fprintf(output, "    ex->params[%s] = tmp.x2[0];\n",
+          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) & 0xffffffff;\n",
               enumnames[ORC_VAR_P1 + i]);
-          fprintf(output, "    ex->params[%s] = tmp.x2[1];\n",
+          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) >> 32;\n",
               enumnames[ORC_VAR_T1 + i]);
           fprintf(output, "  }\n");
           break;
@@ -854,9 +854,9 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
           fprintf(output, "  {\n");
           fprintf(output, "    orc_union64 tmp;\n");
           fprintf(output, "    tmp.f = %s;\n", varnames[ORC_VAR_P1 + i]);
-          fprintf(output, "    ex->params[%s] = tmp.x2[0];\n",
+          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) & 0xffffffff;\n",
               enumnames[ORC_VAR_P1 + i]);
-          fprintf(output, "    ex->params[%s] = tmp.x2[1];\n",
+          fprintf(output, "    ex->params[%s] = ((orc_uint64) tmp.i) >> 32;\n",
               enumnames[ORC_VAR_T1 + i]);
           fprintf(output, "  }\n");
           break;
-- 
2.4.3