[opengtl-commits] [529] add an experimental patch that was making structures used as values

[ Thread Index | Date Index | More lists.tuxfamily.org/opengtl-commits Archives ]


Revision: 529
Author:   cyrille
Date:     2008-12-07 23:18:51 +0100 (Sun, 07 Dec 2008)

Log Message:
-----------
add an experimental patch that was making structures used as values

Added Paths:
-----------
    trunk/OpenGTL/sdk/patches/
    trunk/OpenGTL/sdk/patches/README
    trunk/OpenGTL/sdk/patches/structisvalue.diff


Added: trunk/OpenGTL/sdk/patches/README
===================================================================
--- trunk/OpenGTL/sdk/patches/README	                        (rev 0)
+++ trunk/OpenGTL/sdk/patches/README	2008-12-07 22:18:51 UTC (rev 529)
@@ -0,0 +1,3 @@
+This patches are patches from some of experiment that went wrong:
+
+* against r528: structisvalue.diff, this patch makes structures to be used with value instead of pointers, the goal was to used it to return struct allocated on stack instead of memory, but currently llvm doesn't allow to return struct that contains other structs or pointers (see testReturnArray.ll and testReturnStructStruct.ll)

Added: trunk/OpenGTL/sdk/patches/structisvalue.diff
===================================================================
--- trunk/OpenGTL/sdk/patches/structisvalue.diff	                        (rev 0)
+++ trunk/OpenGTL/sdk/patches/structisvalue.diff	2008-12-07 22:18:51 UTC (rev 529)
@@ -0,0 +1,1750 @@
+Index: OpenCTL/OpenCTL/ctlstdlib.ctl
+===================================================================
+--- OpenCTL/OpenCTL/ctlstdlib.ctl	(revision 483)
++++ OpenCTL/OpenCTL/ctlstdlib.ctl	(working copy)
+@@ -1,694 +1,694 @@
+-/*
+- *  Copyright (c) 2008 Cyrille Berger <cberger@xxxxxxxxxxx>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Lesser General Public
+- * License as published by the Free Software Foundation;
+- * version 2 of the License.
+- *
+- * This library is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * along with this library; see the file COPYING.  If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-
+-// Float operation
+-
+-bool isfinite_f (float x)
+-{
+-  return x != FLT_POS_INF && x != FLT_NEG_INF && x != FLT_NAN;
+-}
+-
+-bool isfinite_h (half x)
+-{
+-  return x != HALF_POS_INF && x != HALF_NEG_INF && x != HALF_NAN;
+-}
+-
+-bool isnormal_f (float x)
+-{
+-  return isfinite_f(x) && x != 0.0;
+-}
+-bool isnormal_h (half x)
+-{
+-  return isfinite_h(x) && x != 0.0;
+-}
+-
+-bool isinf_f (float x)
+-{
+-  return x == FLT_POS_INF || x == FLT_NEG_INF;
+-}
+-bool isinf_h (half x)
+-{
+-  return x == HALF_POS_INF || x != HALF_NEG_INF;
+-}
+-
+-float pow10(float x)
+-{
+-  return pow(10,x);
+-}
+-
+-half pow10_h(float x)
+-{
+-  return pow(10,x);
+-}
+-
+-float hypot(float x, float y)
+-{
+-  return sqrt(x*x + y*y);
+-}
+-
+-// misc mathematic function
+-
+-float min( float f1, float f2) // WARNING not mentioned in the Spec !
+-{
+-  if( f1 < f2)
+-  {
+-    return f1;
+-  } else {
+-    return f2;
+-  }
+-}
+-
+-float max( float f1, float f2) // WARNING not mentioned in the Spec !
+-{
+-  if( f1 > f2)
+-  {
+-    return f1;
+-  } else {
+-    return f2;
+-  }
+-}
+-
+-// lookup
+-
+-float lookup1D(float table[], float pMin, float pMax, float p)
+-{
+-  if( p < pMin ) return table[ 0 ];
+-  if( p > pMax ) return table[ table.size - 1 ];
+-  float t = (p - pMin) / (pMax - pMin ) * (table.size - 1 );
+-  int i = floor( t );
+-  float s = t - i;
+-  return table[i] * ( 1 - s ) + table[i+1] * s; 
+-}
+-
+-float lookupCubic1D (float table[], float pMin, float pMax, float p)
+-{
+-  if( p < pMin ) return table[ 0 ];
+-  if( p > pMax ) return table[ table.size - 1 ];
+-  
+-  float t = (p - pMin) / (pMax - pMin) * (table.size-1);
+-  int i = floor (t);
+-  float s = t - i;
+-  float m0;
+-  float m1;
+-  if( i > 0 )
+-  {
+-    m0 = (table[i+1] - table[i-1]) / 2;
+-  }
+-  if( i < table.size-2 )
+-  {
+-    m1 = (table[i+2] - table[i]) / 2;
+-  }
+-  if( i == 0) {
+-    m0 = (3 * table[i+1] - table[i] - m1);
+-  }
+-  if( i == table.size-2 )
+-  {
+-    m1 = (3 * table[i+1] - table[i] - m0);
+-  }
+-  return table[i] * (2 * s*s*s - 3 * s*s + 1) + m0 * (s*s*s - 2 * s*s + s) + table[i+1] * (-2 * s*s*s + 3 * s*s) + m1 * (s*s*s - s*s);
+-}
+-
+-float interpolate1D (float table[][2], float p)
+-{
+-  if( p <= table[0][0] ) return table[0][1];
+-  if( p >= table[table.size-1][0] ) return table[table.size-1][1];
+-  
+-  for( int i = 0; i < table.size - 1; ++i )
+-  {
+-    if( table[i][0] <= p && p < table[i+1][0] )
+-    {
+-      float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
+-      return table[i][1] * ( 1 - s ) + table[i+1][1] * s;
+-    }
+-  }
+-  return 0.0;
+-}
+-
+-float interpolateCubic1D (float table[][2], float p)
+-{
+-  if( p <= table[0][0] ) return table[0][1];
+-  if( p >= table[table.size-1][0] ) return table[table.size-1][1];
+-  
+-  for( int i = 0; i < table.size - 1; ++i )
+-  {
+-    if( table[i][0] <= p && p < table[i+1][0] )
+-    {
+-      float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
+-      float dx1 = (table[i+1][0] - table[i][0]);
+-      float dy1 = (table[i+1][1] - table[i][1]);
+-      
+-      float m0;
+-      float m1;
+-      if( i > 0 )
+-      {
+-        float dy0 = (table[i][1] - table[i-1][1]);
+-        float dx0 = (table[i][0] - table[i-1][0]);
+-        m0 = (dy1 + dx1 * dy0 / dx0) / 2;
+-      }
+-      if( i < table.size-2 )
+-      {
+-        float dx2 = (table[i+2][0] - table[i+1][0]);
+-        float dy2 = (table[i+2][1] - table[i+1][1]);
+-        m1 = (dy1 + dx1 * dy2 / dx2) / 2;
+-      }
+-      if( i == 0) {
+-        m0 = (3 * dy1 - m1) / 2;
+-      }
+-      if( i == table.size-2 )
+-      {
+-        m1 = (3 * dy1 - m0) / 2;
+-      }
+-      return table[i][1] * (2 * s*s*s - 3 * s*s + 1) +
+-          m0 * (s*s*s - 2 * s*s + s) +
+-          table[i+1][1] * (-2 * s*s*s + 3 * s*s) +
+-          m1 * (s*s*s - s*s);
+-    }
+-  }
+-  return 0.0;
+-}
+-
+-float[3] lookup3D_f3
+-         (float table[][][][3],
+-          float pMin[3],
+-          float pMax[3],
+-          float p[3])
+-{
+-  float result[3];
+-  int iMax = table.size - 1;
+-  int jMax = table[0].size - 1;
+-  int kMax = table[0][0].size - 1;
+-  float q[3];
+-  q[0] = max (pMin[0], min (pMax[0], p[0]));
+-  q[1] = max (pMin[1], min (pMax[1], p[1]));
+-  q[2] = max (pMin[2], min (pMax[2], p[2]));
+-  
+-  float ti = (p[0] - pMin[0]) / (pMax[0] - pMin[0]) * iMax;
+-  int i = floor (ti);
+-  float si = ti - i;
+-  float tj = (p[1] - pMin[1]) / (pMax[1] - pMin[1]) * jMax;
+-  int j = floor (tj);
+-  float sj = tj - j;
+-  float tk = (p[2] - pMin[2]) / (pMax[2] - pMin[2]) * kMax;
+-  int k = floor (tk);
+-  float sk = tk - k;
+-  
+-  for( int l = 0; l < 3; ++l)
+-  {
+-    result[ l ] = ((table[i][j][k][l] * (1-si) + table[i+1][j][k][l] * si) * (1-sj)
+-                + (table[i][j+1][k][l] * (1-si) + table[i+1][j+1][k][l] * si) * sj ) * (1-sk)
+-                + ((table[i][j][k+1][l] * (1-si) + table[i+1][j][k+1][l] * si) * (1-sj)
+-                + (table[i][j+1][k+1][l] * (1-si) + table[i+1][j+1][k+1][l] * si) * sj ) * sk;
+-  }
+-  
+-  return result;
+-}
+-
+-void lookup3D_f
+-       (float table[][][][3],
+-        float pMin[3],
+-        float pMax[3],
+-        float p0, float p1, float p2,
+-        output float q0, output float q1, output float q2)
+-{
+-  float p[3];
+-  p[0] = p0;
+-  p[1] = p1;
+-  p[2] = p2;
+-  float result[3] = lookup3D_f3( table, pMin, pMax, p );
+-  q0 = result[0];
+-  q1 = result[1];
+-  q2 = result[2];
+-}
+-
+-void lookup3D_h
+-       (float table[][][][3],
+-        float pMin[3],
+-        float pMax[3],
+-        half p0, half p1, half p2,
+-        output half q0, output half q1, output half q2)
+-{
+-  lookup3D_f( table, pMin, pMax, p0, p1, p2, q0, q1, q2 );
+-}
+-
+-// Color conversion functions
+-
+-struct Chromaticities
+-{
+-    float red[2];
+-    float green[2];
+-    float blue[2];
+-    float white[2];
+-};
+-
+-// float[4][4] RGBtoXYZ(Chromaticities c, float Y)
++// /*
++//  *  Copyright (c) 2008 Cyrille Berger <cberger@xxxxxxxxxxx>
++//  *
++//  * This library is free software; you can redistribute it and/or
++//  * modify it under the terms of the GNU Lesser General Public
++//  * License as published by the Free Software Foundation;
++//  * version 2 of the License.
++//  *
++//  * This library is distributed in the hope that it will be useful,
++//  * but WITHOUT ANY WARRANTY; without even the implied warranty of
++//  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++//  * Lesser General Public License for more details.
++//  *
++//  * You should have received a copy of the GNU Lesser General Public License
++//  * along with this library; see the file COPYING.  If not, write to
++//  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++//  * Boston, MA 02110-1301, USA.
++//  */
++// 
++// // Float operation
++// 
++// bool isfinite_f (float x)
+ // {
++//   return x != FLT_POS_INF && x != FLT_NEG_INF && x != FLT_NAN;
+ // }
+ // 
+-// float[4][4] XYZtoRGB(Chromaticities c, float Y)
++// bool isfinite_h (half x)
+ // {
++//   return x != HALF_POS_INF && x != HALF_NEG_INF && x != HALF_NAN;
+ // }
+ // 
+-// float[3] XYZtoLuv(float XYZ[3], float XYZn[3]);
+-// float[3] LuvtoXYZ(float Luv[3], float XYZn[3]);
+-//float[3] XYZtoLab(float XYZ[3], float XYZn[3]);
+-// float[3] LabtoXYZ(float Lab[3], float XYZn[3]);
++// bool isnormal_f (float x)
++// {
++//   return isfinite_f(x) && x != 0.0;
++// }
++// bool isnormal_h (half x)
++// {
++//   return isfinite_h(x) && x != 0.0;
++// }
+ // 
+-
+-// Vectors/Matrix operations
+-
+-float[3] mult_f_f3(float f, float x[3])
+-{
+-  float r[3];
+-  for( int k = 0; k < 3; ++k)
+-  {
+-    r[k] = f * x[k];
+-  }
+-  return r;
+-}
+-
+-float[3] add_f3_f3(float x[3], float y[3])
+-{
+-  float r[3];
+-  for( int k = 0; k < 3; ++k)
+-  {
+-    r[k] = x[k] + y[k];
+-  }
+-  return r;
+-}
+-
+-float[3] sub_f3_f3(float x[3], float y[3])
+-{
+-  float r[3];
+-  for( int k = 0; k < 3; ++k)
+-  {
+-    r[k] = x[k] - y[k];
+-  }
+-  return r;
+-}
+-
+-float[3] cross_f3_f3(float x[3], float y[3])
+-{
+-  float r[3];
+-  r[2] = x[0] * y[1] - x[1] * y[0];
+-  r[0] = x[1] * y[2] - x[2] * y[1];
+-  r[1] = x[2] * y[0] - x[0] * y[2];
+-  return r;
+-}
+-
+-float dot_f3_f3(float x[3], float y[3])
+-{
+-  return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
+-}
+-
+-float length_f3 (float x[3])
+-{
+-  return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );
+-}
+-
+-float[3][3] mult_f33_f33 (float A[3][3], float B[3][3])
+-{
+-  float r[3][3];
+-  for( int i = 0; i < 3; ++i)
+-  {
+-    for( int j = 0; j < 3; ++j)
+-    {
+-      r[i][j] = 0.0;
+-      for( int k = 0; k < 3; ++k)
+-      {
+-        r[i][j] = r[i][j] + A[i][k] * B[k][j];
+-      }
+-    }
+-  }
+-  return r;
+-}
+-
+-float[4][4] mult_f44_f44 (float A[4][4], float B[4][4])
+-{
+-  float r[4][4];
+-  for( int i = 0; i < 4; ++i)
+-  {
+-    for( int j = 0; j < 4; ++j)
+-    {
+-      r[i][j] = 0.0;
+-      for( int k = 0; k < 4; ++k)
+-      {
+-        r[i][j] = r[i][j] + A[i][k] * B[k][j];
+-      }
+-    }
+-  }
+-  return r;
+-}
+-
+-float[3][3] mult_f_f33 (float f, float A[3][3])
+-{
+-  float r[3][3];
+-  for( int i = 0; i < 3; ++i )
+-  {
+-    for( int j = 0; j < 3; ++j )
+-    {
+-      r[i][j] = f * A[i][j];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[4][4] mult_f_f44 (float f, float A[4][4])
+-{
+-  float r[4][4];
+-  for( int i = 0; i < 4; ++i )
+-  {
+-    for( int j = 0; j < 4; ++j )
+-    {
+-      r[i][j] = f * A[i][j];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[3][3] add_f33_f33(float A[3][3], float B[3][3])
+-{
+-  float r[3][3];
+-  for( int i = 0; i < 3; ++i )
+-  {
+-    for( int j = 0; j < 3; ++j )
+-    {
+-      r[i][j] = A[i][j] + B[i][j];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[4][4] add_f44_f44(float A[4][4], float B[4][4])
+-{
+-  float r[4][4];
+-  for( int i = 0; i < 4; ++i )
+-  {
+-    for( int j = 0; j < 4; ++j )
+-    {
+-      r[i][j] = A[i][j] + B[i][j];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[3][3] invert_f33 (float A[3][3])
+-{
+-  float result[3][3];
+-  float det =   A[0][0] * A[1][1] * A[2][2]
+-              + A[0][1] * A[1][2] * A[2][0]
+-              + A[0][2] * A[1][0] * A[2][1]
+-              - A[2][0] * A[1][1] * A[0][2]
+-              - A[2][1] * A[1][2] * A[0][0]
+-              - A[2][2] * A[1][0] * A[0][1];
+-  if( det != 0.0 )
+-  {
+-    result[0][0] = A[1][1] * A[2][2] - A[1][2] * A[2][1];
+-    result[0][1] = A[2][1] * A[0][2] - A[2][2] * A[0][1];
+-    result[0][2] = A[0][1] * A[1][2] - A[0][2] * A[1][1];
+-    result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
+-    result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
+-    result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
+-    result[2][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
+-    result[2][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
+-    result[2][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
+-
+-    return mult_f_f33( 1.0 / det, result);
+-  }
+-  result = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
+-  return result;
+-}
+-
+-
+-//---------- Special copyright notice for function invert_f44 -----------//
+-
+-///////////////////////////////////////////////////////////////////////////
+-//
+-// Copyright (c) 2008, Cyrille Berger <cberger@xxxxxxxxxxx>
+-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+-// Digital Ltd. LLC
++// bool isinf_f (float x)
++// {
++//   return x == FLT_POS_INF || x == FLT_NEG_INF;
++// }
++// bool isinf_h (half x)
++// {
++//   return x == HALF_POS_INF || x != HALF_NEG_INF;
++// }
+ // 
+-// All rights reserved.
++// float pow10(float x)
++// {
++//   return pow(10,x);
++// }
+ // 
+-// Redistribution and use in source and binary forms, with or without
+-// modification, are permitted provided that the following conditions are
+-// met:
+-// *       Redistributions of source code must retain the above copyright
+-// notice, this list of conditions and the following disclaimer.
+-// *       Redistributions in binary form must reproduce the above
+-// copyright notice, this list of conditions and the following disclaimer
+-// in the documentation and/or other materials provided with the
+-// distribution.
+-// *       Neither the name of Industrial Light & Magic nor the names of
+-// its contributors may be used to endorse or promote products derived
+-// from this software without specific prior written permission. 
++// half pow10_h(float x)
++// {
++//   return pow(10,x);
++// }
+ // 
+-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-//
+-///////////////////////////////////////////////////////////////////////////
+-
+-float[4][4] invert_f44 (float A[4][4])
+-{
+-  
+-  
+-  if (A[0][3] != 0 || A[1][3] != 0 || A[2][3] != 0 || A[3][3] != 1)
+-  {
+-    int i;
+-    int j;
+-    int k;
+-    float s[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
+-    float t[4][4] = A;
+-
+-    // Forward elimination
+-  
+-    for (i = 0; i < 3 ; ++i)
+-    {
+-      int pivot = i;
+-
+-      float pivotsize = t[i][i];
+-
+-      if (pivotsize < 0)
+-      {
+-        pivotsize = -pivotsize;
+-      }
+-
+-      for (j = i + 1; j < 4; ++j)
+-      {
+-        float tmp = t[j][i];
+-
+-        if (tmp < 0)
+-          tmp = -tmp;
+-
+-        if (tmp > pivotsize)
+-        {
+-          pivot = j;
+-          pivotsize = tmp;
+-        }
+-      }
+-      if (pivotsize == 0)
+-      {
+-        s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+-        return s;
+-      }
+-
+-      if (pivot != i)
+-      {
+-        for (j = 0; j < 4; ++j)
+-        {
+-          float tmp = t[i][j];
+-          t[i][j] = t[pivot][j];
+-          t[pivot][j] = tmp;
+-
+-          tmp = s[i][j];
+-          s[i][j] = s[pivot][j];
+-          s[pivot][j] = tmp;
+-        }
+-      }
+-
+-      for (j = i + 1; j < 4; ++j)
+-      {
+-        float f = t[j][i] / t[i][i];
+-        for (k = 0; k < 4; ++k)
+-        {
+-          t[j][k] = t[j][k] - f * t[i][k];
+-          s[j][k] = s[j][k] - f * s[i][k];
+-        }
+-      }
+-    }
+-    // Backward substitution
+-    for (i = 3; i >= 0; --i)
+-    {
+-      float f = t[i][i];
+-      if ( f == 0)
+-      {
+-        s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+-        return s;
+-      }
+-      for (j = 0; j < 4; ++j)
+-      {
+-        t[i][j] = t[i][j] / f;
+-        s[i][j] = s[i][j] / f;
+-      }
+-
+-      for (j = 0; j < i; ++j)
+-      {
+-        f = t[j][i];
+-  
+-        for (k = 0; k < 4; ++k)
+-        {
+-          t[j][k] = t[j][k] - f * t[i][k];
+-          s[j][k] = s[j][k] - f * s[i][k];
+-        }
+-      }
+-    }
+-    return s;
+-  } else {
+-
+-    float result[4][4];
+-    result[0][0] = A[1][1] * A[2][2] - A[2][1] * A[1][2];
+-    result[0][1] = A[2][1] * A[0][2] - A[0][1] * A[2][2];
+-    result[0][2] = A[0][1] * A[1][2] - A[1][1] * A[0][2];
+-    result[0][3] = 0;
+-
+-    result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
+-    result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
+-    result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
+-    result[1][3] = 0;
+-
+-    result[0][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
+-    result[0][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
+-    result[0][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
+-    result[0][3] = 0;
+-
+-    result[3][0] = 0;
+-    result[3][1] = 0;
+-    result[3][2] = 0;
+-    result[3][3] = 1;
+-
+-    float r = A[0][0] * result[0][0] + A[0][1] * result[1][0] + A[0][2] * result[2][0];
+-
+-    if(fabs(r) >= 1)
+-    {
+-      for(int i = 0; i < 3; ++i)
+-      {
+-        for(int j = 0; j < 3; ++j)
+-        {
+-          result[i][j] = result[i][j] / r;
+-        }
+-      }
+-    }
+-    else
+-    {
+-      float mr = fabs(r) / FLT_MIN;
+-
+-      for (int i = 0; i < 3; ++i)
+-      {
+-        for (int j = 0; j < 3; ++j)
+-        {
+-          if (mr > fabs(result[i][j]))
+-          {
+-            result[i][j] = result[i][j] / r;
+-          }
+-          else
+-          {
+-            result = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
+-            return result;
+-          }
+-        }
+-      }
+-    }
+-    result[3][0] = -A[3][0] * result[0][0] - A[3][1] * result[1][0] - A[3][2] * result[2][0];
+-    result[3][1] = -A[3][0] * result[0][1] - A[3][1] * result[1][1] - A[3][2] * result[2][1];
+-    result[3][2] = -A[3][0] * result[0][2] - A[3][1] * result[1][2] - A[3][2] * result[2][2];
+-    return result;
+-  }
+-  float result[4][4];
+-  return result;
+-}
+-
+-// End of special copyright notice
+-
+-float[3][3] transpose_f33 (float A[3][3])
+-{
+-  float r[3][3];
+-  for( int i = 0; i < 3; ++i)
+-  {
+-    for( int j = 0; j < 3; ++j)
+-    {
+-      r[i][j] = A[j][i];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[4][4] transpose_f44 (float A[4][4])
+-{
+-  float r[4][4];
+-  for( int i = 0; i < 4; ++i)
+-  {
+-    for( int j = 0; j < 4; ++j)
+-    {
+-      r[i][j] = A[j][i];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[3] mult_f3_f33 (float x[3], float A[3][3])
+-{
+-  float r[3];
+-  for( int i = 0; i < 3; ++i)
+-  {
+-    r[i] = 0.0;
+-    for( int j = 0; j < 3; ++j)
+-    {
+-      r[i] = r[i] + x[j] * A[j][i];
+-    }
+-  }
+-  return r;
+-}
+-
+-float[3] mult_f3_f44 (float x[3], float A[4][4])
+-{
+-  float r[3];
+-  for( int i = 0; i < 3; ++i)
+-  {
+-    r[i] = 0.0;
+-    for( int j = 0; j < 3; ++j)
+-    {
+-      r[i] = r[i] + x[j] * A[j][i];
+-    }
+-    r[i] = r[i] + A[3][i];
+-  }
+-  float s = 1.0 / (x[0] * A[0][3] + x[1] * A[1][3] + x[2] * A[2][3] + A[3][3]);
+-  for( int k = 0; k < 3; ++k)
+-  {
+-    r[k] = r[k] * s;
+-  }
+-  return r;
+-}
++// float hypot(float x, float y)
++// {
++//   return sqrt(x*x + y*y);
++// }
++// 
++// // misc mathematic function
++// 
++// float min( float f1, float f2) // WARNING not mentioned in the Spec !
++// {
++//   if( f1 < f2)
++//   {
++//     return f1;
++//   } else {
++//     return f2;
++//   }
++// }
++// 
++// float max( float f1, float f2) // WARNING not mentioned in the Spec !
++// {
++//   if( f1 > f2)
++//   {
++//     return f1;
++//   } else {
++//     return f2;
++//   }
++// }
++// 
++// // lookup
++// 
++// float lookup1D(float table[], float pMin, float pMax, float p)
++// {
++//   if( p < pMin ) return table[ 0 ];
++//   if( p > pMax ) return table[ table.size - 1 ];
++//   float t = (p - pMin) / (pMax - pMin ) * (table.size - 1 );
++//   int i = floor( t );
++//   float s = t - i;
++//   return table[i] * ( 1 - s ) + table[i+1] * s; 
++// }
++// 
++// float lookupCubic1D (float table[], float pMin, float pMax, float p)
++// {
++//   if( p < pMin ) return table[ 0 ];
++//   if( p > pMax ) return table[ table.size - 1 ];
++//   
++//   float t = (p - pMin) / (pMax - pMin) * (table.size-1);
++//   int i = floor (t);
++//   float s = t - i;
++//   float m0;
++//   float m1;
++//   if( i > 0 )
++//   {
++//     m0 = (table[i+1] - table[i-1]) / 2;
++//   }
++//   if( i < table.size-2 )
++//   {
++//     m1 = (table[i+2] - table[i]) / 2;
++//   }
++//   if( i == 0) {
++//     m0 = (3 * table[i+1] - table[i] - m1);
++//   }
++//   if( i == table.size-2 )
++//   {
++//     m1 = (3 * table[i+1] - table[i] - m0);
++//   }
++//   return table[i] * (2 * s*s*s - 3 * s*s + 1) + m0 * (s*s*s - 2 * s*s + s) + table[i+1] * (-2 * s*s*s + 3 * s*s) + m1 * (s*s*s - s*s);
++// }
++// 
++// float interpolate1D (float table[][2], float p)
++// {
++//   if( p <= table[0][0] ) return table[0][1];
++//   if( p >= table[table.size-1][0] ) return table[table.size-1][1];
++//   
++//   for( int i = 0; i < table.size - 1; ++i )
++//   {
++//     if( table[i][0] <= p && p < table[i+1][0] )
++//     {
++//       float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
++//       return table[i][1] * ( 1 - s ) + table[i+1][1] * s;
++//     }
++//   }
++//   return 0.0;
++// }
++// 
++// float interpolateCubic1D (float table[][2], float p)
++// {
++//   if( p <= table[0][0] ) return table[0][1];
++//   if( p >= table[table.size-1][0] ) return table[table.size-1][1];
++//   
++//   for( int i = 0; i < table.size - 1; ++i )
++//   {
++//     if( table[i][0] <= p && p < table[i+1][0] )
++//     {
++//       float s = (p - table[i][0]) / (table[i+1][0] - table[i][0]);
++//       float dx1 = (table[i+1][0] - table[i][0]);
++//       float dy1 = (table[i+1][1] - table[i][1]);
++//       
++//       float m0;
++//       float m1;
++//       if( i > 0 )
++//       {
++//         float dy0 = (table[i][1] - table[i-1][1]);
++//         float dx0 = (table[i][0] - table[i-1][0]);
++//         m0 = (dy1 + dx1 * dy0 / dx0) / 2;
++//       }
++//       if( i < table.size-2 )
++//       {
++//         float dx2 = (table[i+2][0] - table[i+1][0]);
++//         float dy2 = (table[i+2][1] - table[i+1][1]);
++//         m1 = (dy1 + dx1 * dy2 / dx2) / 2;
++//       }
++//       if( i == 0) {
++//         m0 = (3 * dy1 - m1) / 2;
++//       }
++//       if( i == table.size-2 )
++//       {
++//         m1 = (3 * dy1 - m0) / 2;
++//       }
++//       return table[i][1] * (2 * s*s*s - 3 * s*s + 1) +
++//           m0 * (s*s*s - 2 * s*s + s) +
++//           table[i+1][1] * (-2 * s*s*s + 3 * s*s) +
++//           m1 * (s*s*s - s*s);
++//     }
++//   }
++//   return 0.0;
++// }
++// 
++// float[3] lookup3D_f3
++//          (float table[][][][3],
++//           float pMin[3],
++//           float pMax[3],
++//           float p[3])
++// {
++//   float result[3];
++//   int iMax = table.size - 1;
++//   int jMax = table[0].size - 1;
++//   int kMax = table[0][0].size - 1;
++//   float q[3];
++//   q[0] = max (pMin[0], min (pMax[0], p[0]));
++//   q[1] = max (pMin[1], min (pMax[1], p[1]));
++//   q[2] = max (pMin[2], min (pMax[2], p[2]));
++//   
++//   float ti = (p[0] - pMin[0]) / (pMax[0] - pMin[0]) * iMax;
++//   int i = floor (ti);
++//   float si = ti - i;
++//   float tj = (p[1] - pMin[1]) / (pMax[1] - pMin[1]) * jMax;
++//   int j = floor (tj);
++//   float sj = tj - j;
++//   float tk = (p[2] - pMin[2]) / (pMax[2] - pMin[2]) * kMax;
++//   int k = floor (tk);
++//   float sk = tk - k;
++//   
++//   for( int l = 0; l < 3; ++l)
++//   {
++//     result[ l ] = ((table[i][j][k][l] * (1-si) + table[i+1][j][k][l] * si) * (1-sj)
++//                 + (table[i][j+1][k][l] * (1-si) + table[i+1][j+1][k][l] * si) * sj ) * (1-sk)
++//                 + ((table[i][j][k+1][l] * (1-si) + table[i+1][j][k+1][l] * si) * (1-sj)
++//                 + (table[i][j+1][k+1][l] * (1-si) + table[i+1][j+1][k+1][l] * si) * sj ) * sk;
++//   }
++//   
++//   return result;
++// }
++// 
++// void lookup3D_f
++//        (float table[][][][3],
++//         float pMin[3],
++//         float pMax[3],
++//         float p0, float p1, float p2,
++//         output float q0, output float q1, output float q2)
++// {
++//   float p[3];
++//   p[0] = p0;
++//   p[1] = p1;
++//   p[2] = p2;
++//   float result[3] = lookup3D_f3( table, pMin, pMax, p );
++//   q0 = result[0];
++//   q1 = result[1];
++//   q2 = result[2];
++// }
++// 
++// void lookup3D_h
++//        (float table[][][][3],
++//         float pMin[3],
++//         float pMax[3],
++//         half p0, half p1, half p2,
++//         output half q0, output half q1, output half q2)
++// {
++//   lookup3D_f( table, pMin, pMax, p0, p1, p2, q0, q1, q2 );
++// }
++// 
++// // Color conversion functions
++// 
++// struct Chromaticities
++// {
++//     float red[2];
++//     float green[2];
++//     float blue[2];
++//     float white[2];
++// };
++// 
++// // float[4][4] RGBtoXYZ(Chromaticities c, float Y)
++// // {
++// // }
++// // 
++// // float[4][4] XYZtoRGB(Chromaticities c, float Y)
++// // {
++// // }
++// // 
++// // float[3] XYZtoLuv(float XYZ[3], float XYZn[3]);
++// // float[3] LuvtoXYZ(float Luv[3], float XYZn[3]);
++// //float[3] XYZtoLab(float XYZ[3], float XYZn[3]);
++// // float[3] LabtoXYZ(float Lab[3], float XYZn[3]);
++// // 
++// 
++// // Vectors/Matrix operations
++// 
++// float[3] mult_f_f3(float f, float x[3])
++// {
++//   float r[3];
++//   for( int k = 0; k < 3; ++k)
++//   {
++//     r[k] = f * x[k];
++//   }
++//   return r;
++// }
++// 
++// float[3] add_f3_f3(float x[3], float y[3])
++// {
++//   float r[3];
++//   for( int k = 0; k < 3; ++k)
++//   {
++//     r[k] = x[k] + y[k];
++//   }
++//   return r;
++// }
++// 
++// float[3] sub_f3_f3(float x[3], float y[3])
++// {
++//   float r[3];
++//   for( int k = 0; k < 3; ++k)
++//   {
++//     r[k] = x[k] - y[k];
++//   }
++//   return r;
++// }
++// 
++// float[3] cross_f3_f3(float x[3], float y[3])
++// {
++//   float r[3];
++//   r[2] = x[0] * y[1] - x[1] * y[0];
++//   r[0] = x[1] * y[2] - x[2] * y[1];
++//   r[1] = x[2] * y[0] - x[0] * y[2];
++//   return r;
++// }
++// 
++// float dot_f3_f3(float x[3], float y[3])
++// {
++//   return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
++// }
++// 
++// float length_f3 (float x[3])
++// {
++//   return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] );
++// }
++// 
++// float[3][3] mult_f33_f33 (float A[3][3], float B[3][3])
++// {
++//   float r[3][3];
++//   for( int i = 0; i < 3; ++i)
++//   {
++//     for( int j = 0; j < 3; ++j)
++//     {
++//       r[i][j] = 0.0;
++//       for( int k = 0; k < 3; ++k)
++//       {
++//         r[i][j] = r[i][j] + A[i][k] * B[k][j];
++//       }
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[4][4] mult_f44_f44 (float A[4][4], float B[4][4])
++// {
++//   float r[4][4];
++//   for( int i = 0; i < 4; ++i)
++//   {
++//     for( int j = 0; j < 4; ++j)
++//     {
++//       r[i][j] = 0.0;
++//       for( int k = 0; k < 4; ++k)
++//       {
++//         r[i][j] = r[i][j] + A[i][k] * B[k][j];
++//       }
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[3][3] mult_f_f33 (float f, float A[3][3])
++// {
++//   float r[3][3];
++//   for( int i = 0; i < 3; ++i )
++//   {
++//     for( int j = 0; j < 3; ++j )
++//     {
++//       r[i][j] = f * A[i][j];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[4][4] mult_f_f44 (float f, float A[4][4])
++// {
++//   float r[4][4];
++//   for( int i = 0; i < 4; ++i )
++//   {
++//     for( int j = 0; j < 4; ++j )
++//     {
++//       r[i][j] = f * A[i][j];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[3][3] add_f33_f33(float A[3][3], float B[3][3])
++// {
++//   float r[3][3];
++//   for( int i = 0; i < 3; ++i )
++//   {
++//     for( int j = 0; j < 3; ++j )
++//     {
++//       r[i][j] = A[i][j] + B[i][j];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[4][4] add_f44_f44(float A[4][4], float B[4][4])
++// {
++//   float r[4][4];
++//   for( int i = 0; i < 4; ++i )
++//   {
++//     for( int j = 0; j < 4; ++j )
++//     {
++//       r[i][j] = A[i][j] + B[i][j];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[3][3] invert_f33 (float A[3][3])
++// {
++//   float result[3][3];
++//   float det =   A[0][0] * A[1][1] * A[2][2]
++//               + A[0][1] * A[1][2] * A[2][0]
++//               + A[0][2] * A[1][0] * A[2][1]
++//               - A[2][0] * A[1][1] * A[0][2]
++//               - A[2][1] * A[1][2] * A[0][0]
++//               - A[2][2] * A[1][0] * A[0][1];
++//   if( det != 0.0 )
++//   {
++//     result[0][0] = A[1][1] * A[2][2] - A[1][2] * A[2][1];
++//     result[0][1] = A[2][1] * A[0][2] - A[2][2] * A[0][1];
++//     result[0][2] = A[0][1] * A[1][2] - A[0][2] * A[1][1];
++//     result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
++//     result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
++//     result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
++//     result[2][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
++//     result[2][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
++//     result[2][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
++// 
++//     return mult_f_f33( 1.0 / det, result);
++//   }
++//   result = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
++//   return result;
++// }
++// 
++// 
++// //---------- Special copyright notice for function invert_f44 -----------//
++// 
++// ///////////////////////////////////////////////////////////////////////////
++// //
++// // Copyright (c) 2008, Cyrille Berger <cberger@xxxxxxxxxxx>
++// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
++// // Digital Ltd. LLC
++// // 
++// // All rights reserved.
++// // 
++// // Redistribution and use in source and binary forms, with or without
++// // modification, are permitted provided that the following conditions are
++// // met:
++// // *       Redistributions of source code must retain the above copyright
++// // notice, this list of conditions and the following disclaimer.
++// // *       Redistributions in binary form must reproduce the above
++// // copyright notice, this list of conditions and the following disclaimer
++// // in the documentation and/or other materials provided with the
++// // distribution.
++// // *       Neither the name of Industrial Light & Magic nor the names of
++// // its contributors may be used to endorse or promote products derived
++// // from this software without specific prior written permission. 
++// // 
++// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++// //
++// ///////////////////////////////////////////////////////////////////////////
++// 
++// float[4][4] invert_f44 (float A[4][4])
++// {
++//   
++//   
++//   if (A[0][3] != 0 || A[1][3] != 0 || A[2][3] != 0 || A[3][3] != 1)
++//   {
++//     int i;
++//     int j;
++//     int k;
++//     float s[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
++//     float t[4][4] = A;
++// 
++//     // Forward elimination
++//   
++//     for (i = 0; i < 3 ; ++i)
++//     {
++//       int pivot = i;
++// 
++//       float pivotsize = t[i][i];
++// 
++//       if (pivotsize < 0)
++//       {
++//         pivotsize = -pivotsize;
++//       }
++// 
++//       for (j = i + 1; j < 4; ++j)
++//       {
++//         float tmp = t[j][i];
++// 
++//         if (tmp < 0)
++//           tmp = -tmp;
++// 
++//         if (tmp > pivotsize)
++//         {
++//           pivot = j;
++//           pivotsize = tmp;
++//         }
++//       }
++//       if (pivotsize == 0)
++//       {
++//         s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
++//         return s;
++//       }
++// 
++//       if (pivot != i)
++//       {
++//         for (j = 0; j < 4; ++j)
++//         {
++//           float tmp = t[i][j];
++//           t[i][j] = t[pivot][j];
++//           t[pivot][j] = tmp;
++// 
++//           tmp = s[i][j];
++//           s[i][j] = s[pivot][j];
++//           s[pivot][j] = tmp;
++//         }
++//       }
++// 
++//       for (j = i + 1; j < 4; ++j)
++//       {
++//         float f = t[j][i] / t[i][i];
++//         for (k = 0; k < 4; ++k)
++//         {
++//           t[j][k] = t[j][k] - f * t[i][k];
++//           s[j][k] = s[j][k] - f * s[i][k];
++//         }
++//       }
++//     }
++//     // Backward substitution
++//     for (i = 3; i >= 0; --i)
++//     {
++//       float f = t[i][i];
++//       if ( f == 0)
++//       {
++//         s = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
++//         return s;
++//       }
++//       for (j = 0; j < 4; ++j)
++//       {
++//         t[i][j] = t[i][j] / f;
++//         s[i][j] = s[i][j] / f;
++//       }
++// 
++//       for (j = 0; j < i; ++j)
++//       {
++//         f = t[j][i];
++//   
++//         for (k = 0; k < 4; ++k)
++//         {
++//           t[j][k] = t[j][k] - f * t[i][k];
++//           s[j][k] = s[j][k] - f * s[i][k];
++//         }
++//       }
++//     }
++//     return s;
++//   } else {
++// 
++//     float result[4][4];
++//     result[0][0] = A[1][1] * A[2][2] - A[2][1] * A[1][2];
++//     result[0][1] = A[2][1] * A[0][2] - A[0][1] * A[2][2];
++//     result[0][2] = A[0][1] * A[1][2] - A[1][1] * A[0][2];
++//     result[0][3] = 0;
++// 
++//     result[1][0] = A[2][0] * A[1][2] - A[1][0] * A[2][2];
++//     result[1][1] = A[0][0] * A[2][2] - A[2][0] * A[0][2];
++//     result[1][2] = A[1][0] * A[0][2] - A[0][0] * A[1][2];
++//     result[1][3] = 0;
++// 
++//     result[0][0] = A[1][0] * A[2][1] - A[2][0] * A[1][1];
++//     result[0][1] = A[2][0] * A[0][1] - A[0][0] * A[2][1];
++//     result[0][2] = A[0][0] * A[1][1] - A[1][0] * A[0][1];
++//     result[0][3] = 0;
++// 
++//     result[3][0] = 0;
++//     result[3][1] = 0;
++//     result[3][2] = 0;
++//     result[3][3] = 1;
++// 
++//     float r = A[0][0] * result[0][0] + A[0][1] * result[1][0] + A[0][2] * result[2][0];
++// 
++//     if(fabs(r) >= 1)
++//     {
++//       for(int i = 0; i < 3; ++i)
++//       {
++//         for(int j = 0; j < 3; ++j)
++//         {
++//           result[i][j] = result[i][j] / r;
++//         }
++//       }
++//     }
++//     else
++//     {
++//       float mr = fabs(r) / FLT_MIN;
++// 
++//       for (int i = 0; i < 3; ++i)
++//       {
++//         for (int j = 0; j < 3; ++j)
++//         {
++//           if (mr > fabs(result[i][j]))
++//           {
++//             result[i][j] = result[i][j] / r;
++//           }
++//           else
++//           {
++//             result = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
++//             return result;
++//           }
++//         }
++//       }
++//     }
++//     result[3][0] = -A[3][0] * result[0][0] - A[3][1] * result[1][0] - A[3][2] * result[2][0];
++//     result[3][1] = -A[3][0] * result[0][1] - A[3][1] * result[1][1] - A[3][2] * result[2][1];
++//     result[3][2] = -A[3][0] * result[0][2] - A[3][1] * result[1][2] - A[3][2] * result[2][2];
++//     return result;
++//   }
++//   float result[4][4];
++//   return result;
++// }
++// 
++// // End of special copyright notice
++// 
++// float[3][3] transpose_f33 (float A[3][3])
++// {
++//   float r[3][3];
++//   for( int i = 0; i < 3; ++i)
++//   {
++//     for( int j = 0; j < 3; ++j)
++//     {
++//       r[i][j] = A[j][i];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[4][4] transpose_f44 (float A[4][4])
++// {
++//   float r[4][4];
++//   for( int i = 0; i < 4; ++i)
++//   {
++//     for( int j = 0; j < 4; ++j)
++//     {
++//       r[i][j] = A[j][i];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[3] mult_f3_f33 (float x[3], float A[3][3])
++// {
++//   float r[3];
++//   for( int i = 0; i < 3; ++i)
++//   {
++//     r[i] = 0.0;
++//     for( int j = 0; j < 3; ++j)
++//     {
++//       r[i] = r[i] + x[j] * A[j][i];
++//     }
++//   }
++//   return r;
++// }
++// 
++// float[3] mult_f3_f44 (float x[3], float A[4][4])
++// {
++//   float r[3];
++//   for( int i = 0; i < 3; ++i)
++//   {
++//     r[i] = 0.0;
++//     for( int j = 0; j < 3; ++j)
++//     {
++//       r[i] = r[i] + x[j] * A[j][i];
++//     }
++//     r[i] = r[i] + A[3][i];
++//   }
++//   float s = 1.0 / (x[0] * A[0][3] + x[1] * A[1][3] + x[2] * A[2][3] + A[3][3]);
++//   for( int k = 0; k < 3; ++k)
++//   {
++//     r[k] = r[k] * s;
++//   }
++//   return r;
++// }
+Index: OpenGTL/GTLCore/AST/Statement.cpp
+===================================================================
+--- OpenGTL/GTLCore/AST/Statement.cpp	(revision 500)
++++ OpenGTL/GTLCore/AST/Statement.cpp	(working copy)
+@@ -40,7 +40,7 @@
+ #include <GTLCore/Debug.h>
+ 
+ // AST
+-#include "Expression.h"
++#include "AccessorExpression.h"
+ 
+ using namespace GTLCore::AST;
+ 
+@@ -239,19 +239,32 @@
+   if( m_returnExpr )
+   {
+     ExpressionResult result = m_returnExpr->generateValue( _context, _bb);
++    AccessorExpression* accessorReturnExpr = dynamic_cast<AccessorExpression*>( m_returnExpr );
++    llvm::Value* pointerToResult = 0;
++    if( accessorReturnExpr )
++    {
++      pointerToResult = accessorReturnExpr->pointer( _context, _bb );
++    }
+     const GTLCore::Type* returnType = m_returnExpr->type();
+     const Visitor* visitor = Visitor::getVisitorFor( returnType );
+-    _bb = visitor->mark( _context, _bb, result.value(), returnType, CodeGenerator::integerToConstant( 1 ) );
++    if( pointerToResult )
++    {
++      _bb = visitor->mark( _context, _bb, pointerToResult, returnType, CodeGenerator::integerToConstant( 1 ) );
++    }
+     _bb = _context.flushDelayedStatement( _bb );
+     _bb = m_garbageCollectionStatement->generateStatement( _context, _bb );
+     llvm::Value* resultValue = result.value();
++    // Mark the return value
++    if( pointerToResult )
++    {
++      _bb = visitor->mark( _context, _bb, pointerToResult, returnType, CodeGenerator::integerToConstant( -1 ) );
++    }
++    // Convert it or load it
+     if( m_returnExpr->type()->dataType() != Type::ARRAY
+         and m_returnExpr->type()->dataType() != Type::STRUCTURE )
+     {
+       resultValue = _context.codeGenerator()->convertValueTo(_bb, resultValue, m_returnExpr->type(), _context.function()->returnType() );
+     }
+-    // Mark the return value
+-    _bb = visitor->mark( _context, _bb, resultValue, returnType, CodeGenerator::integerToConstant( -1 ) );
+     llvm::ReturnInst::Create( resultValue, _bb);
+   } else {
+     _bb = _context.flushDelayedStatement( _bb );
+Index: OpenGTL/GTLCore/AST/GarbageCollectionStatement.cpp
+===================================================================
+--- OpenGTL/GTLCore/AST/GarbageCollectionStatement.cpp	(revision 500)
++++ OpenGTL/GTLCore/AST/GarbageCollectionStatement.cpp	(working copy)
+@@ -41,6 +41,7 @@
+ 
+ llvm::BasicBlock* PointerGarbageCollectionStatement::generateStatement( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock) const
+ {
++#if 0
+   // FIXME: garbage collect if needed
+   
+   if( m_type->dataType() == Type::STRUCTURE or m_type->dataType() == Type::ARRAY )
+@@ -53,8 +54,11 @@
+     CodeGenerator::createIfStatement( _currentBlock, test, Type::Boolean, first, last, after);
+     return after;
+   } else {
++#endif
+     return _currentBlock;
++#if 0
+   }
++#endif
+ }
+ 
+ VariablesGarbageCollectionStatement::VariablesGarbageCollectionStatement( std::list< VariableNG* > _variablesToCollect )
+@@ -68,9 +72,11 @@
+ 
+ llvm::BasicBlock* VariablesGarbageCollectionStatement::generateStatement( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock) const
+ {
++#if 0
+   for( std::list< VariableNG* >::const_iterator it = m_variablesToCollect.begin(); it != m_variablesToCollect.end(); ++it )
+   {
+     _currentBlock = (*it)->cleanUp( _generationContext, _currentBlock, 0 );
+   }
++#endif
+   return _currentBlock;
+ }
+Index: OpenGTL/GTLCore/AST/FunctionDeclaration.cpp
+===================================================================
+--- OpenGTL/GTLCore/AST/FunctionDeclaration.cpp	(revision 500)
++++ OpenGTL/GTLCore/AST/FunctionDeclaration.cpp	(working copy)
+@@ -104,7 +104,7 @@
+   std::vector<llvm::Function*> functions( params.size() + 1 );
+   
+   // Generate the full function
+-  const llvm::Type* returnType = m_function->returnType()->d->asArgumentType();
++  const llvm::Type* returnType = m_function->returnType()->d->type();
+   llvm::FunctionType* definitionType = llvm::FunctionType::get( returnType, params, false );
+   GTLCore::String fullFunctionName = GTLCore::Function::Data::symbolName( m_function->name(), m_function->parameters());
+   llvm::Function* fullFunction = _codeGenerator->createFunction(definitionType, fullFunctionName );
+Index: OpenGTL/GTLCore/Visitor_p.h
+===================================================================
+--- OpenGTL/GTLCore/Visitor_p.h	(revision 500)
++++ OpenGTL/GTLCore/Visitor_p.h	(working copy)
+@@ -202,6 +202,7 @@
+       virtual llvm::Constant* createStaticVariable( llvm::Module*, const Type* type, const std::list< int>& _sizes ) const;
+     private:
+       llvm::Value* pointerToValue(GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, int index ) const;
++      llvm::Value* accessValue( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _value, int _index ) const;
+   };
+ 
+ }
+Index: OpenGTL/GTLCore/CodeGenerator_p.cpp
+===================================================================
+--- OpenGTL/GTLCore/CodeGenerator_p.cpp	(revision 514)
++++ OpenGTL/GTLCore/CodeGenerator_p.cpp	(working copy)
+@@ -611,7 +611,7 @@
+   return llvm::ConstantExpr::getXor(rhs, integerToConstant(0xFFFFFFFF ));
+ }
+ 
+-llvm::Value* CodeGenerator::accessArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, llvm::Value* _index )
++llvm::Value* CodeGenerator::pointerToPointerArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, llvm::Value* _index )
+ {
+   GTL_DEBUG( *_pointer << " " << *_index );
+   std::vector<llvm::Value*> indexes;
+@@ -621,10 +621,16 @@
+   // Select the pointer
+   llvm::Value* iptr = llvm::GetElementPtrInst::Create( _pointer, indexes.begin(), indexes.end(), "", _currentBlock);
+   // pointer on the values
+-  llvm::Value* iptr_val = new llvm::LoadInst( iptr, "", _currentBlock);
+-  return llvm::GetElementPtrInst::Create( iptr_val, _index, "", _currentBlock);
++  llvm::Value* iptr_val = new llvm::LoadInst( iptr, "CodeGenerator::pointerToPointerArrayValue", _currentBlock);
++  return llvm::GetElementPtrInst::Create( iptr_val, _index, "CodeGenerator::pointerToPointerArrayValue", _currentBlock);
+ }
+ 
++llvm::Value* CodeGenerator::pointerToValueArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _value, llvm::Value* _index )
++{
++  llvm::Value* iptr_val = llvm::ExtractValueInst::Create( _value, ArrayWrap::POS_DATA, "CodeGenerator::pointerToValueArrayValue", _currentBlock);
++  return llvm::GetElementPtrInst::Create( iptr_val, _index, "CodeGenerator::pointerToValueArrayValue", _currentBlock);
++}
++
+ GTLCore::ExpressionResult CodeGenerator::callFunction( GenerationContext& _gc, llvm::BasicBlock* bb, const GTLCore::Function* _function, const std::list<AST::Expression*>& _arguments )
+ {
+   // Function Type
+Index: OpenGTL/GTLCore/CodeGenerator_p.h
+===================================================================
+--- OpenGTL/GTLCore/CodeGenerator_p.h	(revision 500)
++++ OpenGTL/GTLCore/CodeGenerator_p.h	(working copy)
+@@ -262,7 +262,14 @@
+        * @param _index the index of the value in the array
+        * @return a pointer on the value of an array
+        */
+-      llvm::Value* accessArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, llvm::Value* _index );
++      llvm::Value* pointerToPointerArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, llvm::Value* _index );
++      /**
++       * @param _currentBlock the current basic block
++       * @param _value an array structure
++       * @param _index the index of the value in the array
++       * @return the value of an array
++       */
++      llvm::Value* pointerToValueArrayValue( llvm::BasicBlock* _currentBlock, llvm::Value* _value, llvm::Value* _index );
+     public:
+       GTLCore::ExpressionResult callFunction( GenerationContext& _gc, llvm::BasicBlock* _bb, const GTLCore::Function* _function, const std::list<AST::Expression*>& m_arguments );
+     private:
+Index: OpenGTL/GTLCore/Visitor_p.cpp
+===================================================================
+--- OpenGTL/GTLCore/Visitor_p.cpp	(revision 514)
++++ OpenGTL/GTLCore/Visitor_p.cpp	(working copy)
+@@ -159,12 +159,12 @@
+ 
+ llvm::Value* ArrayVisitor::pointerToIndex(GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _type, llvm::Value* _index) const
+ {
+-  return _generationContext.codeGenerator()->accessArrayValue( _currentBlock, _pointer, _index);
++  return _generationContext.codeGenerator()->pointerToPointerArrayValue( _currentBlock, _pointer, _index);
+ }
+ 
+ ExpressionResult ArrayVisitor::get( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _pointerType ) const
+ {
+-  return ExpressionResult(_pointer, _pointerType);
++  return ExpressionResult( new llvm::LoadInst( _pointer, "ArrayVisitor::get", _currentBlock), _pointerType);
+ }
+ 
+ llvm::BasicBlock* ArrayVisitor::set( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _pointerType, llvm::Value* _value, const Type* _valueType, bool _allocatedInMemory) const
+@@ -200,10 +200,11 @@
+     llvm::BasicBlock* endBodyBlock = visitor->set( 
+           _generationContext,
+           bodyBlock, 
+-          _generationContext.codeGenerator()->accessArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
++          _generationContext.codeGenerator()->pointerToPointerArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
+           _pointerType->embeddedType(),
+-          visitor->get( _generationContext, bodyBlock, 
+-                  _generationContext.codeGenerator()->accessArrayValue(
++          
++         visitor->get( _generationContext, bodyBlock, 
++                  _generationContext.codeGenerator()->pointerToValueArrayValue(
+                                     bodyBlock, _value, index->get( _generationContext, bodyBlock ) ), _pointerType->embeddedType() ).value(),
+           _valueType->embeddedType(), _allocatedInMemory );
+     
+@@ -252,11 +253,17 @@
+ 
+ llvm::Value* ArrayVisitor::getSize(GenerationContext& _generationContext, llvm::BasicBlock* currentBlock, llvm::Value* _pointer ) const
+ {
+-  std::vector<llvm::Value*> indexes;
+-  indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); // Access the structure of the array
+-  indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, ArrayWrap::POS_SIZE)); // Access the size of the array
+-  llvm::Value* ptr = llvm::GetElementPtrInst::Create( _pointer, indexes.begin(), indexes.end(), "", currentBlock);
+-  return new llvm::LoadInst( ptr, "ArrayVisitor::getSize", currentBlock);
++  GTL_DEBUG("_pointer = " << *_pointer << " " << llvm::isa<llvm::PointerType>( _pointer->getType() ) );
++  if( llvm::isa<llvm::PointerType>( _pointer->getType() ) )
++  { // TODO it's probably a good idea to not do this test...
++    std::vector<llvm::Value*> indexes;
++    indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); // Access the structure of the array
++    indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, ArrayWrap::POS_SIZE)); // Access the size of the array
++    llvm::Value* ptr = llvm::GetElementPtrInst::Create( _pointer, indexes.begin(), indexes.end(), "", currentBlock);
++    return new llvm::LoadInst( ptr, "ArrayVisitor::getSize", currentBlock);
++  } else {
++    return llvm::ExtractValueInst::Create( _pointer, ArrayWrap::POS_SIZE, "ArrayVisitor::getSize", currentBlock );
++  }
+ }
+ 
+ llvm::BasicBlock* ArrayVisitor::initialise(GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _pointerType, const std::list< llvm::Value*>& _sizes, bool _allocatedInMemory) const
+@@ -282,7 +289,7 @@
+     llvm::BasicBlock* endBodyBlock = visitor->initialise(
+             _generationContext,
+             bodyBlock,
+-            _generationContext.codeGenerator()->accessArrayValue(
++            _generationContext.codeGenerator()->pointerToPointerArrayValue(
+                       bodyBlock, _pointer, index->get( _generationContext, bodyBlock ) ),
+             _pointerType->embeddedType(),
+             sizeAfter, _allocatedInMemory );
+@@ -345,7 +352,7 @@
+     llvm::BasicBlock* endBodyBlock = visitor->cleanUp( 
+           _generationContext,
+           bodyBlock, 
+-          _generationContext.codeGenerator()->accessArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
++          _generationContext.codeGenerator()->pointerToPointerArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
+           _pointerType->embeddedType(), _donttouch, _allocatedInMemory, _ignoreCount, false );
+     // Create the for statement
+     llvm::BasicBlock*  afterBlock = CodeGenerator::createIterationForStatement(
+@@ -398,7 +405,7 @@
+   llvm::BasicBlock* endBodyBlock = visitor->mark( 
+         _generationContext,
+         bodyBlock, 
+-        _generationContext.codeGenerator()->accessArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
++        _generationContext.codeGenerator()->pointerToPointerArrayValue( bodyBlock, _pointer, index->get( _generationContext, bodyBlock  ) ),
+         _pointerType->embeddedType(), _increment );
+   
+   llvm::BasicBlock*  afterBlock = CodeGenerator::createIterationForStatement(
+@@ -532,12 +539,23 @@
+                                                 llvm::BasicBlock* _currentBlock,
+                                                 llvm::Value* _pointer, int _index ) const
+ {
++  _index += STRUCT_FIRST_ELEMENT;
++  
+   std::vector<llvm::Value*> indexes;
+   indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
+-  indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, _index + STRUCT_FIRST_ELEMENT ));
++  indexes.push_back( llvm::ConstantInt::get(llvm::Type::Int32Ty, _index ));
+   return llvm::GetElementPtrInst::Create( _pointer, indexes.begin(), indexes.end(), "StructureVisitor::pointerToValue", _currentBlock);
+ }
+ 
++llvm::Value* StructureVisitor::accessValue( GenerationContext& /*_generationContext*/,
++                                            llvm::BasicBlock* _currentBlock,
++                                            llvm::Value* _value, int _index ) const
++{
++  _index += STRUCT_FIRST_ELEMENT;
++  return llvm::ExtractValueInst::Create( _value, _index, "StructureVisitor::pointerToValue", _currentBlock );
++}
++
++
+ llvm::Value* StructureVisitor::pointerToIndex(GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _type, llvm::Value* _index) const
+ {
+   GTL_ABORT("Structure doesn't allow access using indexes");
+@@ -545,7 +563,7 @@
+ 
+ ExpressionResult StructureVisitor::get( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _pointerType ) const
+ {
+-  return ExpressionResult(_pointer, _pointerType);
++  return ExpressionResult( new llvm::LoadInst( _pointer, "StructureVisitor::get", _currentBlock), _pointerType);
+ }
+ 
+ llvm::BasicBlock* StructureVisitor::set( GenerationContext& _generationContext, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer, const Type* _pointerType, llvm::Value* _value, const Type* _valueType, bool _allocatedInMemory ) const
+@@ -555,9 +573,8 @@
+   {
+     const Type* type = _pointerType->structDataMember(i).type();
+     llvm::Value* nptrToOwnMember = pointerToValue(_generationContext, _currentBlock, _pointer, i);
+-    llvm::Value* nptrToValueMember = pointerToValue( _generationContext, _currentBlock, _value, i);
++    llvm::Value* memberValue = accessValue( _generationContext, _currentBlock, _value, i);
+     const Visitor* visitor = Visitor::getVisitorFor( type );
+-    llvm::Value* memberValue = visitor->get( _generationContext, _currentBlock, nptrToValueMember, type ).value();
+     _currentBlock = visitor->set( _generationContext, _currentBlock, nptrToOwnMember, type, memberValue, type, _allocatedInMemory );
+   }
+   return _currentBlock;
+@@ -567,6 +584,8 @@
+ {
+   GTL_ASSERT( _pointerType->dataType() == Type::STRUCTURE );
+   
++  GTL_DEBUG( "_pointer = " << *_pointer << " _pointerType = " << *_pointerType );
++  
+   for( uint i = 0; i < _pointerType->countStructDataMembers(); ++i)
+   {
+     std::list< llvm::Value* > sizes;
+@@ -577,12 +596,15 @@
+       sizes.push_back( _generationContext.codeGenerator()->integerToConstant( *it ) );
+     }
+     const Type* type = sdm.type();
++    GTL_DEBUG( i << " " << *type);
+     const Visitor* visitor = Visitor::getVisitorFor( type );
+     _currentBlock = visitor->initialise( _generationContext, _currentBlock,
+                             pointerToValue( _generationContext, _currentBlock, _pointer, i ),
+                             type, sizes, _allocatedInMemory );
+   }
++  GTL_DEBUG(" done ");
+   CodeGenerator::setCountFieldOf( _currentBlock, _pointer, CodeGenerator::integerToConstant( 1 ) );
++  GTL_DEBUG(" counted ");
+   return _currentBlock;
+ }
+ 
+Index: OpenGTL/GTLCore/VariableNG_p.cpp
+===================================================================
+--- OpenGTL/GTLCore/VariableNG_p.cpp	(revision 514)
++++ OpenGTL/GTLCore/VariableNG_p.cpp	(working copy)
+@@ -96,12 +96,12 @@
+ {
+   GTL_DEBUG( _initialSize.size() );
+   llvm::Value* pointer_ = 0;
+-  if( _initialiser.value() and _initialiser.functionResult()
++/*  if( _initialiser.value() and _initialiser.functionResult()
+       and (type()->dataType() == Type::ARRAY or type()->dataType() == Type::STRUCTURE ) )
+   {
+     initialise( _generationContext, _bb, _initialiser.value() );
+     _bb = d->visitor->mark( _generationContext, _bb, pointer(_bb), d->type, CodeGenerator::integerToConstant( 1 ) );
+-  } else {
++  } else {*/
+     if( d->allocatedInMemory )
+     {
+       pointer_ = new llvm::MallocInst( d->type->d->type(), llvm::ConstantInt::get(llvm::Type::Int32Ty, 1), "Variable", _bb);
+@@ -113,25 +113,27 @@
+     
+     if( _initialiser.value() )
+     {
++      GTL_DEBUG("Initialise with " << _initialiser.value() );
+       _bb = d->visitor->set( _generationContext, _bb, pointer_, d->type, _initialiser.value(), _initialiser.type() , d->allocatedInMemory);
+     }
+-  }
++//   }
++  GTL_DEBUG(" done ");
+   d->constantPointer = false;
+   return _bb;
+ }
+ 
+ void VariableNG::initialise( GTLCore::GenerationContext& /*_generationContext*/, llvm::BasicBlock* _currentBlock, llvm::Value* _pointer )
+ {
+-  GTL_ASSERT( _pointer->getType()->getTypeID() == llvm::Type::PointerTyID );
+   GTL_ASSERT(not d->isInitialised);
+   d->isInitialised = true;
+-  d->directlyOnTheStack = _currentBlock and ( d->type->dataType() == Type::ARRAY or d->type->dataType() == Type::STRUCTURE );
++  d->directlyOnTheStack = false; //_currentBlock and ( d->type->dataType() == Type::ARRAY or d->type->dataType() == Type::STRUCTURE );
+   if( d->directlyOnTheStack )
+   {
+-    d->pointer = new llvm::AllocaInst( llvm::PointerType::get( d->type->d->type(), 0 ), "Variable Pointer", _currentBlock );
++    d->pointer = new llvm::AllocaInst( d->type->d->type(), "Variable Pointer", _currentBlock );
+     GTL_DEBUG( *d->pointer << " " << *_pointer );
+     new llvm::StoreInst( _pointer, d->pointer, "Variable Pointer", _currentBlock );
+   } else {
++    GTL_ASSERT( _pointer->getType()->getTypeID() == llvm::Type::PointerTyID );
+     d->pointer = _pointer;
+   }
+   d->constantPointer = true;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/