Browse Source

HPCC-10525 Solve constant folding functions for ARM

Some suble alignment issues for ARM calls.

Also fixed some issues in the x64 code that I spotted while I was there.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 years ago
parent
commit
57c2db139c
3 changed files with 24 additions and 6 deletions
  1. 9 2
      ecl/hql/hqlfold.cpp
  2. 10 0
      ecl/hql/hqlstack.cpp
  3. 5 4
      ecl/hql/hqlstack.hpp

+ 9 - 2
ecl/hql/hqlfold.cpp

@@ -861,6 +861,8 @@ IValue * foldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplateC
 
 // **** Linux/Mac ****
  #ifdef _ARCH_X86_64_
+        if ((len & 0x8) == 0)
+            len += 8;   // We need to make sure we add an ODD number of words to stack, so that it gets 16-byte aligned once pc is pushed by the call
 
         __int64 dummy1, dummy2,dummy3,dummy4;
 
@@ -900,7 +902,7 @@ IValue * foldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplateC
         // Get real (float/double) return values;
         if(isRealvalue)
         {
-            if(len <= 4)
+            if(resultsize <= 4)
             {
                 __asm__  __volatile__(
                     "movss  %%xmm0,(%%rdi) \n\t"
@@ -940,7 +942,7 @@ IValue * foldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplateC
         // Get real (float/double) return values;
         if(isRealvalue)
         {
-            if(len <= 4)
+            if(resultsize <= 4)
             {
                 __asm__  __volatile__(
                     "fstps (%%edi) \n\t"
@@ -966,6 +968,9 @@ IValue * foldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplateC
             UNIMPLEMENTED;
         }
   #endif
+        if ((len & 0x4) == 0)
+           len += 4;   // We need to make sure we add an ODD number of words to stack, so that it gets 8-byte aligned once pc is pushed by the call
+        assertex((len & 7) == 4)
         register unsigned _intresult asm("r0");                       // Specific register for result
         register unsigned _intresulthigh asm("r1");                   // Specific register for result
         register unsigned _poplen asm("r4") = len-REGPARAMS*REGSIZE;  // Needs to survive the call
@@ -987,6 +992,8 @@ IValue * foldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplateC
             );
         intresult = _intresult;
         intresulthigh = _intresulthigh;
+        if (isRealvalue)
+            UNIMPLMENTED;
  #elif defined(_ARCH_ARM64_)
         // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
         UNIMPLEMENTED;

+ 10 - 0
ecl/hql/hqlstack.cpp

@@ -45,6 +45,16 @@ FuncCallStack::~FuncCallStack() {
     }
 }
 
+unsigned FuncCallStack::align(unsigned size)
+{
+#ifdef ALIGN_USES_ELEMENTSIZE
+    unsigned boundary = (size < ALIGNMENT) ? ALIGNMENT : size;
+#else
+    unsigned boundary = ALIGNMENT;
+#endif
+    return ((size + boundary - 1) & ~(boundary-1));
+}
+
 unsigned FuncCallStack::getSp(){ 
     return sp;
 }

+ 5 - 4
ecl/hql/hqlstack.hpp

@@ -40,8 +40,9 @@
  #define REGSIZE 4
 #elif defined (_ARCH_ARM64_)
  #define ALIGNMENT 8
+ #define ALIGN_USES_ELEMENTSIZE
  #define REGSIZE 8
- #define REGPARAMS 8  // MORE - check this
+ #define REGPARAMS 8
  #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) \
      && defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP) && !defined(__ARM_PCS)
   #error "Can't identify floating point calling conventions.\nPlease ensure that your toolchain defines __ARM_PCS or __ARM_PCS_VFP."
@@ -50,7 +51,8 @@
   #define MAXFPREGS 8 // d0-d7
  #endif
 #elif defined (_ARCH_ARM32_)
- #define ALIGNMENT 8
+ #define ALIGNMENT 4
+ #define ALIGN_USES_ELEMENTSIZE
  #define REGSIZE 4
  #define REGPARAMS 4
  #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) \
@@ -62,8 +64,6 @@
  #endif
 #endif
 
-#define align(x)  ((x + ALIGNMENT - 1) & ~(ALIGNMENT-1))
-
 class FuncCallStack {
 private:
     unsigned   tos;
@@ -83,6 +83,7 @@ private:
  #endif
     unsigned    numFpRegs;
 #endif
+    unsigned align(unsigned size);
 public:
     FuncCallStack(int size = DEFAULTSTACKSIZE);
     virtual ~FuncCallStack();