add Outputable instance for OccIfaceEq
[ghc-hetmet.git] / rts / Adjustor.c
index fc4182e..841c660 100644 (file)
@@ -84,10 +84,6 @@ static void  GNUC3_ATTRIBUTE(used) obscure_ccall_wrapper(void)
 }
 extern void obscure_ccall_ret_code(void);
 
-#if defined(openbsd_HOST_OS)
-static unsigned char *obscure_ccall_ret_code_dyn;
-#endif
-
 #endif
 
 #if defined(x86_64_HOST_ARCH)
@@ -113,7 +109,6 @@ extern void obscure_ccall_ret_code(void);
 #endif
 
 #if defined(ia64_HOST_ARCH)
-#include "Storage.h"
 
 /* Layout of a function descriptor */
 typedef struct _IA64FunDesc {
@@ -266,7 +261,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
      <c>:      ff e0             jmp    %eax              # and jump to it.
                # the callee cleans up the stack
     */
-    adjustor = stgMallocBytesRWX(14);
+    adjustor = allocateExec(14);
     {
        unsigned char *const adj_code = (unsigned char *)adjustor;
        adj_code[0x00] = (unsigned char)0x58;  /* popl %eax  */
@@ -311,7 +306,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
     That's (thankfully) the case here with the restricted set of 
     return types that we support.
   */
-    adjustor = stgMallocBytesRWX(17);
+    adjustor = allocateExec(17);
     {
        unsigned char *const adj_code = (unsigned char *)adjustor;
 
@@ -323,11 +318,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
 
        adj_code[0x0a] = (unsigned char)0x68;  /* pushl obscure_ccall_ret_code */
        *((StgFunPtr*)(adj_code + 0x0b)) = 
-#if !defined(openbsd_HOST_OS)
                        (StgFunPtr)obscure_ccall_ret_code;
-#else
-                       (StgFunPtr)obscure_ccall_ret_code_dyn;
-#endif
 
        adj_code[0x0f] = (unsigned char)0xff; /* jmp *%eax */
        adj_code[0x10] = (unsigned char)0xe0; 
@@ -340,7 +331,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
           
           We offload most of the work to AdjustorAsm.S.
         */
-        AdjustorStub *adjustorStub = stgMallocBytesRWX(sizeof(AdjustorStub));
+        AdjustorStub *adjustorStub = allocateExec(sizeof(AdjustorStub));
         adjustor = adjustorStub;
 
         extern void adjustorCode(void);
@@ -426,11 +417,6 @@ createAdjustor(int cconv, StgStablePtr hptr,
   38: .quad 0  # aligned on 8-byte boundary
     */
 
-    /* we assume the small code model (gcc -mcmmodel=small) where
-     * all symbols are <2^32, so hence wptr should fit into 32 bits.
-     */
-    ASSERT(((long)wptr >> 32) == 0);
-
     {  
        int i = 0;
        char *c;
@@ -443,7 +429,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
        }
 
        if (i < 6) {
-           adjustor = stgMallocBytesRWX(0x30);
+           adjustor = allocateExec(0x30);
 
            *(StgInt32 *)adjustor        = 0x49c1894d;
            *(StgInt32 *)(adjustor+0x4)  = 0x8948c889;
@@ -457,7 +443,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
        }
        else
        {
-           adjustor = stgMallocBytesRWX(0x40);
+           adjustor = allocateExec(0x40);
 
            *(StgInt32 *)adjustor        = 0x35ff5141;
            *(StgInt32 *)(adjustor+0x4)  = 0x00000020;
@@ -504,7 +490,7 @@ createAdjustor(int cconv, StgStablePtr hptr,
      similarly, and local variables should be accessed via %fp, not %sp. In a
      nutshell: This should work! (Famous last words! :-)
   */
-    adjustor = stgMallocBytesRWX(4*(11+1));
+    adjustor = allocateExec(4*(11+1));
     {
         unsigned long *const adj_code = (unsigned long *)adjustor;
 
@@ -581,7 +567,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
       4 bytes (getting rid of the nop), hence saving memory. [ccshan]
   */
     ASSERT(((StgWord64)wptr & 3) == 0);
-    adjustor = stgMallocBytesRWX(48);
+    adjustor = allocateExec(48);
     {
        StgWord64 *const code = (StgWord64 *)adjustor;
 
@@ -686,7 +672,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
             */
                     // allocate space for at most 4 insns per parameter
                     // plus 14 more instructions.
-        adjustor = stgMallocBytesRWX(4 * (4*n + 14));
+        adjustor = allocateExec(4 * (4*n + 14));
         code = (unsigned*)adjustor;
         
         *code++ = 0x48000008; // b *+8
@@ -845,7 +831,7 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
 #ifdef FUNDESCS
         adjustorStub = stgMallocBytes(sizeof(AdjustorStub), "createAdjustor");
 #else
-        adjustorStub = stgMallocBytesRWX(sizeof(AdjustorStub));
+        adjustorStub = allocateExec(sizeof(AdjustorStub));
 #endif
         adjustor = adjustorStub;
             
@@ -958,8 +944,12 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
 /* These macros distribute a long constant into the two words of an MLX bundle */
 #define BITS(val,start,count)  (((val) >> (start)) & ((1 << (count))-1))
 #define MOVL_LOWORD(val)       (BITS(val,22,18) << 46)
-#define MOVL_HIWORD(val)       (BITS(val,40,23) | (BITS(val,0,7) << 36) | (BITS(val,7,9) << 50) \
-                               | (BITS(val,16,5) << 55) | (BITS(val,21,1) << 44) | BITS(val,63,1) << 59)
+#define MOVL_HIWORD(val)       ( (BITS(val,0,7)    << 36)      \
+                               | (BITS(val,7,9)    << 50)      \
+                               | (BITS(val,16,5)   << 45)      \
+                               | (BITS(val,21,1)   << 44)      \
+                               | (BITS(val,40,23))             \
+                               | (BITS(val,63,1)    << 59))
 
     {
        StgStablePtr stable;
@@ -968,11 +958,17 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
        IA64FunDesc *fdesc;
        StgWord64 *code;
 
-       /* we allocate on the Haskell heap since malloc'd memory isn't executable - argh */
-       adjustor = stgAllocStable(sizeof(IA64FunDesc)+18*8, &stable);
+       /* we allocate on the Haskell heap since malloc'd memory isn't
+        * executable - argh */
+       /* Allocated memory is word-aligned (8 bytes) but functions on ia64
+        * must be aligned to 16 bytes.  We allocate an extra 8 bytes of
+        * wiggle room so that we can put the code on a 16 byte boundary. */
+       adjustor = stgAllocStable(sizeof(IA64FunDesc)+18*8+8, &stable);
 
        fdesc = (IA64FunDesc *)adjustor;
        code = (StgWord64 *)(fdesc + 1);
+       /* add 8 bytes to code if needed to align to a 16-byte boundary */
+       if ((StgWord64)code & 15) code++;
        fdesc->ip = (StgWord64)code;
        fdesc->gp = wdesc->gp;
 
@@ -1028,7 +1024,7 @@ freeHaskellFunctionPtr(void* ptr)
  } else {
     freeStablePtr(*((StgStablePtr*)((unsigned char*)ptr + 0x02)));
  }
-#elif defined(x86_HOST_ARCH) && defined(darwin_HOST_OS)
+#elif defined(i386_HOST_ARCH) && defined(darwin_HOST_OS)
 if ( *(unsigned char*)ptr != 0xe8 ) {
    errorBelch("freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);
    return;
@@ -1088,23 +1084,5 @@ if ( *(unsigned char*)ptr != 0xe8 ) {
 #endif
  *((unsigned char*)ptr) = '\0';
 
- stgFree(ptr);
-}
-
-
-/*
- * Function: initAdjustor()
- *
- * Perform initialisation of adjustor thunk layer (if needed.)
- */
-void
-initAdjustor(void)
-{
-#if defined(i386_HOST_ARCH) && defined(openbsd_HOST_OS)
-    obscure_ccall_ret_code_dyn = stgMallocBytesRWX(4);
-    obscure_ccall_ret_code_dyn[0] = ((unsigned char *)obscure_ccall_ret_code)[0];
-    obscure_ccall_ret_code_dyn[1] = ((unsigned char *)obscure_ccall_ret_code)[1];
-    obscure_ccall_ret_code_dyn[2] = ((unsigned char *)obscure_ccall_ret_code)[2];
-    obscure_ccall_ret_code_dyn[3] = ((unsigned char *)obscure_ccall_ret_code)[3];
-#endif
+ freeExec(ptr);
 }