From 3b6a5af52cff72d77600b848d6d851f71b162bc2 Mon Sep 17 00:00:00 2001 From: matthewc Date: Fri, 22 Nov 2002 07:43:30 +0000 Subject: [PATCH] [project @ 2002-11-22 07:43:29 by matthewc] Implement adjustor thunks for IA64. N.B. malloc'd memory isn't executable, so I'm currently allocating them on the (mmap'd) Haskell heap instead... --- ghc/rts/Adjustor.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ghc/rts/MBlock.c | 4 +- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/ghc/rts/Adjustor.c b/ghc/rts/Adjustor.c index 2ea1240..ed3cb50 100644 --- a/ghc/rts/Adjustor.c +++ b/ghc/rts/Adjustor.c @@ -76,6 +76,37 @@ static unsigned char __obscure_ccall_ret_code [] = #include #endif +#if defined(ia64_TARGET_ARCH) +#include "Storage.h" + +/* Layout of a function descriptor */ +typedef struct _IA64FunDesc { + StgWord64 ip; + StgWord64 gp; +} IA64FunDesc; + +static void * +stgAllocStable(size_t size_in_bytes, StgStablePtr *stable) +{ + StgArrWords* arr; + nat data_size_in_words, total_size_in_words; + + /* round up to a whole number of words */ + data_size_in_words = (size_in_bytes + sizeof(W_) + 1) / sizeof(W_); + total_size_in_words = sizeofW(StgArrWords) + data_size_in_words; + + /* allocate and fill it in */ + arr = (StgArrWords *)allocate(total_size_in_words); + SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, data_size_in_words); + + /* obtain a stable ptr */ + *stable = getStablePtr((StgPtr)arr); + + /* and return a ptr to the goods inside the array */ + return(BYTE_ARR_CTS(arr)); +} +#endif + void* createAdjustor(int cconv, StgStablePtr hptr, StgFunPtr wptr) { @@ -341,6 +372,85 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for __asm__ volatile ("sync\n\tisync"); } } +#elif defined(ia64_TARGET_ARCH) +/* + Up to 8 inputs are passed in registers. We flush the last two inputs to + the stack, initially into the 16-byte scratch region left by the caller. + We then shuffle the others along by 4 (taking 2 registers for ourselves + to save return address and previous function state - we need to come back + here on the way out to restore the stack, so this is a real function + rather than just a trampoline). + + The function descriptor we create contains the gp of the target function + so gp is already loaded correctly. + + [MLX] alloc r16=ar.pfs,10,2,0 + movl r17=wptr + [MII] st8.spill [r12]=r38,8 // spill in6 (out4) + mov r41=r37 // out7 = in5 (out3) + mov r40=r36;; // out6 = in4 (out2) + [MII] st8.spill [r12]=r39 // spill in7 (out5) + mov.sptk b6=r17,50 + mov r38=r34;; // out4 = in2 (out0) + [MII] mov r39=r35 // out5 = in3 (out1) + mov r37=r33 // out3 = in1 (loc1) + mov r36=r32 // out2 = in0 (loc0) + [MLX] adds r12=-24,r12 // update sp + movl r34=hptr;; // out0 = hptr + [MIB] mov r33=r16 // loc1 = ar.pfs + mov r32=b0 // loc0 = retaddr + br.call.sptk.many b0=b6;; + + [MII] adds r12=-16,r12 + mov b0=r32 + mov.i ar.pfs=r33 + [MFB] nop.m 0x0 + nop.f 0x0 + br.ret.sptk.many b0;; +*/ + +/* 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) + + { + StgStablePtr stable; + IA64FunDesc *wdesc = (IA64FunDesc *)wptr; + StgWord64 wcode = wdesc->ip; + 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); + + fdesc = (IA64FunDesc *)adjustor; + code = (StgWord64 *)(fdesc + 1); + fdesc->ip = (StgWord64)code; + fdesc->gp = wdesc->gp; + + code[0] = 0x0000058004288004 | MOVL_LOWORD(wcode); + code[1] = 0x6000000220000000 | MOVL_HIWORD(wcode); + code[2] = 0x029015d818984001; + code[3] = 0x8401200500420094; + code[4] = 0x886011d8189c0001; + code[5] = 0x84011004c00380c0; + code[6] = 0x0250210046013800; + code[7] = 0x8401000480420084; + code[8] = 0x0000233f19a06005 | MOVL_LOWORD((StgWord64)hptr); + code[9] = 0x6000000440000000 | MOVL_HIWORD((StgWord64)hptr); + code[10] = 0x0200210020010811; + code[11] = 0x1080006800006200; + code[12] = 0x0000210018406000; + code[13] = 0x00aa021000038005; + code[14] = 0x000000010000001d; + code[15] = 0x0084000880000200; + + /* save stable pointers in convenient form */ + code[16] = (StgWord64)hptr; + code[17] = (StgWord64)stable; + } #else barf("adjustor creation not supported on this platform"); #endif @@ -394,6 +504,17 @@ freeHaskellFunctionPtr(void* ptr) return; } freeStablePtr(*((StgStablePtr*)((unsigned char*)ptr + 4*12))); +#elif defined(ia64_TARGET_ARCH) + IA64FunDesc *fdesc = (IA64FunDesc *)ptr; + StgWord64 *code = (StgWord64 *)(fdesc+1); + + if (fdesc->ip != (StgWord64)code) { + fprintf(stderr, "freeHaskellFunctionPtr: not for me, guv! %p\n", ptr); + return; + } + freeStablePtr((StgStablePtr)code[16]); + freeStablePtr((StgStablePtr)code[17]); + return; #else ASSERT(0); #endif diff --git a/ghc/rts/MBlock.c b/ghc/rts/MBlock.c index 590c556..c87dd6a 100644 --- a/ghc/rts/MBlock.c +++ b/ghc/rts/MBlock.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: MBlock.c,v 1.39 2002/11/22 06:54:05 matthewc Exp $ + * $Id: MBlock.c,v 1.40 2002/11/22 07:43:30 matthewc Exp $ * * (c) The GHC Team 1998-1999 * @@ -121,7 +121,7 @@ my_mmap (void *addr, int size) else vm_protect(mach_task_self(),ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE); #else - ret = mmap(addr, size, PROT_READ | PROT_WRITE, + ret = mmap(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); #endif -- 1.7.10.4