diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2013-06-17 07:26:00 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2013-06-17 07:26:00 +0000 |
| commit | 407f680bae1834d5fa5bb27605097e436586663c (patch) | |
| tree | c26f3b5b2573b1f94007a0da8466c0d5990dffb9 /src/runtime/c/pgf/lightning/ppc/funcs.h | |
| parent | 8abd16bace315b5d306d6cec1adfe4766e65935d (diff) | |
add the source code for GNU lightning in the source directory for the C runtime
Diffstat (limited to 'src/runtime/c/pgf/lightning/ppc/funcs.h')
| -rw-r--r-- | src/runtime/c/pgf/lightning/ppc/funcs.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/runtime/c/pgf/lightning/ppc/funcs.h b/src/runtime/c/pgf/lightning/ppc/funcs.h new file mode 100644 index 000000000..37e2b38f3 --- /dev/null +++ b/src/runtime/c/pgf/lightning/ppc/funcs.h @@ -0,0 +1,164 @@ +/******************************** -*- C -*- **************************** + * + * Platform-independent layer inline functions (PowerPC) + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Written by Paolo Bonzini. + * + * This file is part of GNU lightning. + * + * GNU lightning 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; either version 2.1, or (at your option) + * any later version. + * + * GNU lightning 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 GNU lightning; see the file COPYING.LESSER; if not, write to the + * Free Software Foundation, 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + ***********************************************************************/ + + + +#ifndef __lightning_funcs_h +#define __lightning_funcs_h + +#if !defined(__GNUC__) && !defined(__GNUG__) +#error Go get GNU C, I do not know how to flush the cache +#error with this compiler. +#else +static void +jit_flush_code(void *start, void *end) +{ +#ifndef LIGHTNING_CROSS + register char *ddest, *idest; + + static int cache_line_size; + if (cache_line_size == 0) { + char buffer[8192]; + int i, probe; + + /* Find out the size of a cache line by zeroing one */ + memset(buffer, 0xFF, 8192); + __asm__ __volatile__ ("dcbz 0,%0" : : "r"(buffer + 4096)); + + /* Probe for the beginning of the cache line. */ + for(i = 0, probe = 4096; probe; probe >>= 1) + if (buffer[i | probe] != 0x00) + i |= probe; + + /* i is now just before the start of the cache line */ + i++; + for(cache_line_size = 1; i + cache_line_size < 8192; cache_line_size <<= 1) + if (buffer[i + cache_line_size] != 0x00) + break; + } + + start -= ((long) start) & (cache_line_size - 1); + end -= ((long) end) & (cache_line_size - 1); + + /* Force data cache write-backs */ + for (ddest = (char *) start; ddest <= (char *) end; ddest += cache_line_size) { + __asm__ __volatile__ ("dcbst 0,%0" : : "r"(ddest)); + } + __asm__ __volatile__ ("sync" : : ); + + /* Now invalidate the instruction cache */ + for (idest = (char *) start; idest <= (char *) end; idest += cache_line_size) { + __asm__ __volatile__ ("icbi 0,%0" : : "r"(idest)); + } + __asm__ __volatile__ ("isync" : : ); +#endif /* !LIGHTNING_CROSS */ +} +#endif /* __GNUC__ || __GNUG__ */ + +#define _jit (*jit) + +static void +_jit_epilog(jit_state *jit) +{ + int n = _jitl.nbArgs; + int frame_size, ofs; + int first_saved_reg = JIT_AUX - n; + int num_saved_regs = 32 - first_saved_reg; + + frame_size = 24 + 32 + num_saved_regs * 4; /* r24..r31 + args */ + frame_size += 15; /* the stack must be quad-word */ + frame_size &= ~15; /* aligned */ + +#ifdef _CALL_DARWIN + LWZrm(0, frame_size + 8, 1); /* lwz r0, x+8(r1) (ret.addr.) */ +#else + LWZrm(0, frame_size + 4, 1); /* lwz r0, x+4(r1) (ret.addr.) */ +#endif + MTLRr(0); /* mtspr LR, r0 */ + + ofs = frame_size - num_saved_regs * 4; + LMWrm(first_saved_reg, ofs, 1); /* lmw rI, ofs(r1) */ + ADDIrri(1, 1, frame_size); /* addi r1, r1, x */ + BLR(); /* blr */ +} + +/* Emit a prolog for a function. + Upon entrance to the trampoline: + - LR = address where the real code for the function lies + - R3-R8 = parameters + Upon finishing the trampoline: + - R0 = return address for the function + - R25-R20 = parameters (order is reversed, 1st argument is R25) + + The +32 in frame_size computation is to accound for the parameter area of + a function frame. + + On PPC the frame must have space to host the arguments of any callee. + However, as it currently stands, the argument to jit_trampoline (n) is + the number of arguments of the caller we generate. Therefore, the + callee can overwrite a part of the stack (saved register area when it + flushes its own parameter on the stack. The addition of a constant + offset = 32 is enough to hold eight 4 bytes arguments. This is less + than perfect but is a reasonable work around for now. + Better solution must be investigated. */ +static void +_jit_prolog(jit_state *jit, int n) +{ + int frame_size; + int ofs, i; + int first_saved_reg = JIT_AUX - n; + int num_saved_regs = 32 - first_saved_reg; + + _jitl.nextarg_geti = JIT_AUX - 1; + _jitl.nextarg_getd = 1; + _jitl.nbArgs = n; + + frame_size = 24 + 32 + num_saved_regs * 4; /* r27..r31 + args */ + frame_size += 15; /* the stack must be quad-word */ + frame_size &= ~15; /* aligned */ + + MFLRr(0); + STWUrm(1, -frame_size, 1); /* stwu r1, -x(r1) */ + + ofs = frame_size - num_saved_regs * 4; + STMWrm(first_saved_reg, ofs, 1); /* stmw rI, ofs(r1) */ +#ifdef _CALL_DARWIN + STWrm(0, frame_size + 8, 1); /* stw r0, x+8(r1) */ +#else + STWrm(0, frame_size + 4, 1); /* stw r0, x+4(r1) */ +#endif + for (i = 0; i < n; i++) + MRrr(JIT_AUX-1-i, 3+i); /* save parameters below r24 */ +} + +#undef _jit + +#endif /* __lightning_funcs_h */ |
