PatchSet 6810 Date: 2005/08/10 21:17:28 Author: robilad Branch: HEAD Tag: (none) Log: Renamed structs to match names in jni.h
2005-08-10 Dalibor Topic <[EMAIL PROTECTED]> * kaffe/kaffevm/gtypes.h, config/alpha/jit.h, config/arm/jit.h, config/i386/jit.h, config/m68k/jit.h, config/m68k/openbsd2/jit.h, config/mips/jit.h, config/powerpc/jit.h, config/sparc/jit.h, include/native.h, kaffe/kaffevm/classMethod.h, kaffe/kaffevm/code-analyse.h, kaffe/kaffevm/code.h, kaffe/kaffevm/exception.h, kaffe/kaffevm/external.h, kaffe/kaffevm/javacall.c, kaffe/kaffevm/stackTrace.h, kaffe/kaffevm/support.c, kaffe/kaffevm/support.h, kaffe/kaffevm/gcj/gcj.h, kaffe/kaffevm/intrp/machine.c, kaffe/kaffevm/intrp/machine.h, kaffe/kaffevm/jit/machine.h: Renamed struct _fields to struct _jfieldID and struct _methods to struct _jmethodID to match the convention in GNU Classpath frn include/jni.h and fix compiler warnings. Members: ChangeLog:1.4335->1.4336 config/alpha/jit.h:INITIAL->1.9 config/arm/jit.h:INITIAL->1.16 config/i386/jit.h:INITIAL->1.27 config/m68k/jit.h:INITIAL->1.17 config/m68k/openbsd2/jit.h:1.5->1.6 config/mips/jit.h:INITIAL->1.16 config/powerpc/jit.h:1.3->1.4 config/sparc/jit.h:1.10->1.11 include/native.h:1.19->1.20 kaffe/kaffevm/classMethod.h:1.83->1.84 kaffe/kaffevm/code-analyse.h:1.20->1.21 kaffe/kaffevm/code.h:INITIAL->1.8 kaffe/kaffevm/exception.h:INITIAL->1.34 kaffe/kaffevm/external.h:1.12->1.13 kaffe/kaffevm/gtypes.h:1.18->1.19 kaffe/kaffevm/javacall.c:1.2->1.3 kaffe/kaffevm/stackTrace.h:INITIAL->1.15 kaffe/kaffevm/support.c:1.87->1.88 kaffe/kaffevm/support.h:1.41->1.42 kaffe/kaffevm/gcj/gcj.h:1.6->1.7 kaffe/kaffevm/intrp/machine.c:1.52->1.53 kaffe/kaffevm/intrp/machine.h:INITIAL->1.12 kaffe/kaffevm/jit/machine.h:INITIAL->1.23 Index: kaffe/ChangeLog diff -u kaffe/ChangeLog:1.4335 kaffe/ChangeLog:1.4336 --- kaffe/ChangeLog:1.4335 Wed Aug 10 20:52:24 2005 +++ kaffe/ChangeLog Wed Aug 10 21:17:28 2005 @@ -1,5 +1,35 @@ 2005-08-10 Dalibor Topic <[EMAIL PROTECTED]> + * kaffe/kaffevm/gtypes.h, + config/alpha/jit.h, + config/arm/jit.h, + config/i386/jit.h, + config/m68k/jit.h, + config/m68k/openbsd2/jit.h, + config/mips/jit.h, + config/powerpc/jit.h, + config/sparc/jit.h, + include/native.h, + kaffe/kaffevm/classMethod.h, + kaffe/kaffevm/code-analyse.h, + kaffe/kaffevm/code.h, + kaffe/kaffevm/exception.h, + kaffe/kaffevm/external.h, + kaffe/kaffevm/javacall.c, + kaffe/kaffevm/stackTrace.h, + kaffe/kaffevm/support.c, + kaffe/kaffevm/support.h, + kaffe/kaffevm/gcj/gcj.h, + kaffe/kaffevm/intrp/machine.c, + kaffe/kaffevm/intrp/machine.h, + kaffe/kaffevm/jit/machine.h: + Renamed struct _fields to struct _jfieldID and + struct _methods to struct _jmethodID to match the + convention in GNU Classpath from include/jni.h and + fix compiler warnings. + +2005-08-10 Dalibor Topic <[EMAIL PROTECTED]> + * config/sparc/linux/md.h (sparcLinuxContextSwitch): Added missing prototype to fix compiler warning. =================================================================== Checking out kaffe/config/alpha/jit.h RCS: /home/cvs/kaffe/kaffe/config/alpha/jit.h,v VERS: 1.9 *************** --- /dev/null Sun Aug 4 19:57:58 2002 +++ kaffe/config/alpha/jit.h Wed Aug 10 21:35:21 2005 @@ -0,0 +1,272 @@ +/* + * alpha/jit.h + * Common Alpha JIT configuration information. + * + * Copyright (c) 1996, 1997 + * Transvirtual Technologies, Inc. All rights reserved. + * + * Copyright (c) 2003 + * Kaffe.org contributors, see ChangeLogs for details. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution + * of this file. + */ + +#ifndef __alpha_jit_h +#define __alpha_jit_h + +#include <stdarg.h> + +struct Hjava_lang_Object; +struct Hjava_lang_Class; +struct _jmethodID; + +/* Collected JIT infos used to create DEC OSF/1 Procedure descriptor for + * exception handling, or GCJ eh_table info. + */ +typedef struct _alpha_jit_info { + int rsa_size; /* Size of Register Save Area in 64 bit words */ + int sp_set; /* offset of inst that set sp (in insts number) */ + int entry_length; /* # of insts in prologue */ + int imask; + int fmask; + int ieee; +} alpha_jit_info_t; + +/* Protected by translatorlock */ +extern alpha_jit_info_t alpha_jit_info; + + +/**/ +/* Exception handling information. */ +/**/ + +/* exceptionFrame, NEXTFRAME(), PCFRAME(), FPFRAME() and FIRSTFRAME() are + * move to $os/jit-md.h. */ + +/* Extract the object argument from given frame */ +#define FRAMEOBJECT(obj, f, einfo) \ + /* rebuild alpha_slot2argoffset[0] as in jit-alpha.def */ \ + (obj) = *((Hjava_lang_Object**)((uintp)(f) - 8)) + +/**/ +/* Method dispatch. */ +/**/ + +#define HAVE_TRAMPOLINE + +/* The layout of this struct are known by inline assembly. */ + +typedef struct _methodTrampoline { + unsigned code[2]; + void *fixup; + struct _jmethodID *meth; + void **where; +} methodTrampoline; + +extern void alpha_do_fixup_trampoline(void); + +#define FILL_IN_TRAMPOLINE(t,m,w) \ + do { \ +/* 0 */ (t)->code[0] = 0xa77b0008; /* ldq $27,8($27) */ \ +/* 4 */ (t)->code[1] = 0x683b0000; /* jmp $1,($27),0 */ \ +/* 8 */ (t)->fixup = alpha_do_fixup_trampoline; \ +/* 16 */ (t)->meth = (m); \ +/* 24 */ (t)->where = (w); \ + } while (0) + +#define FIXUP_TRAMPOLINE_DECL void** _data +#define FIXUP_TRAMPOLINE_INIT (meth = (Method*)_data[0], \ + where = (void**)_data[1]) + + +/* Wrap up a native call for the JIT */ +#define KAFFEJIT_TO_NATIVE(_m) + + +/**/ +/* Register management information. */ +/**/ + +/* Define the register set */ + +/* The arg registers are set reserved so that they don't get tromped + while we are setting up the outgoing arguments. */ + +/* Until we have some method of determining in the prologue which + Rnosaveoncall registers are used by a method, it is not a win to + have any at all. We save all of them in prologue to match Alpha + Calling convention. */ + +#define REGISTER_SET \ + { /* v0 */ 0, 0, Rint|Rlong|Rref, 0, 0, 0 }, \ + { /* t0 */ 0, 0, Rint|Rlong|Rref, 0, 0, 1 }, \ + { /* t1 */ 0, 0, Rint|Rlong|Rref, 0, 0, 2 }, \ + { /* t2 */ 0, 0, Rint|Rlong|Rref, 0, 0, 3 }, \ + { /* t3 */ 0, 0, Rint|Rlong|Rref, 0, 0, 4 }, \ + { /* t4 */ 0, 0, Rint|Rlong|Rref, 0, 0, 5 }, \ + { /* t5 */ 0, 0, Rint|Rlong|Rref, 0, 0, 6 }, \ + { /* t6 */ 0, 0, Rint|Rlong|Rref, 0, 0, 7 }, \ + { /* t7 */ 0, 0, Rint|Rlong|Rref, 0, 0, 8 }, \ + { /* s0 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 9 }, \ + { /* s1 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 10 }, \ + { /* s2 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 11 }, \ + { /* s3 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 12 }, \ + { /* s4 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 13 }, \ + { /* s5 */ 0, 0, Rint|Rlong|Rref, Rnosaveoncall, 0, 14 }, \ + { /* fp */ 0, 0, Reserved, 0, 0, 15 }, \ + { /* a0 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 16 }, \ + { /* a1 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 17 }, \ + { /* a2 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 18 }, \ + { /* a3 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 19 }, \ + { /* a4 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 20 }, \ + { /* a5 */ 0, 0, Reserved|Rint|Rlong|Rref, 0, 0, 21 }, \ + { /* t8 */ 0, 0, Rint|Rlong|Rref, 0, 0, 22 }, \ + { /* t9 */ 0, 0, Rint|Rlong|Rref, 0, 0, 23 }, \ + { /* t10 */ 0, 0, Rint|Rlong|Rref, 0, 0, 24 }, \ + { /* t11 */ 0, 0, Rint|Rlong|Rref, 0, 0, 25 }, \ + { /* ra */ 0, 0, Rint|Rlong|Rref, 0, 0, 26 }, \ + { /* t12/pv */ 0, 0, Rint|Rlong|Rref, 0, 0, 27 }, \ + { /* at */ 0, 0, Reserved, 0, 0, 28 }, \ + { /* gp */ 0, 0, Reserved, 0, 0, 29 }, \ + { /* sp */ 0, 0, Reserved, 0, 0, 30 }, \ + { /* zero */ 0, 0, Reserved, 0, 0, 31 }, \ + { /* f0 */ 0, 0, Rfloat|Rdouble, 0, 0, 32 }, \ + { /* f1 */ 0, 0, Rfloat|Rdouble, 0, 0, 33 }, \ + { /* f2 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 34 }, \ + { /* f3 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 35 }, \ + { /* f4 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 36 }, \ + { /* f5 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 37 }, \ + { /* f6 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 38 }, \ + { /* f7 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 39 }, \ + { /* f8 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 40 }, \ + { /* f9 */ 0, 0, Rfloat|Rdouble, Rnosaveoncall, 0, 41 }, \ + { /* f10 */ 0, 0, Rfloat|Rdouble, 0, 0, 42 }, \ + { /* f11 */ 0, 0, Rfloat|Rdouble, 0, 0, 43 }, \ + { /* f12 */ 0, 0, Rfloat|Rdouble, 0, 0, 44 }, \ + { /* f13 */ 0, 0, Rfloat|Rdouble, 0, 0, 45 }, \ + { /* f14 */ 0, 0, Rfloat|Rdouble, 0, 0, 46 }, \ + { /* f15 */ 0, 0, Rfloat|Rdouble, 0, 0, 47 }, \ + { /* f16 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 48 }, \ + { /* f17 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 49 }, \ + { /* f18 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 50 }, \ + { /* f19 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 51 }, \ + { /* f20 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 52 }, \ + { /* f21 */ 0, 0, Reserved|Rfloat|Rdouble, 0, 0, 53 }, \ + { /* f22 */ 0, 0, Rfloat|Rdouble, 0, 0, 54 }, \ + { /* f23 */ 0, 0, Rfloat|Rdouble, 0, 0, 55 }, \ + { /* f24 */ 0, 0, Rfloat|Rdouble, 0, 0, 56 }, \ + { /* f25 */ 0, 0, Rfloat|Rdouble, 0, 0, 57 }, \ + { /* f26 */ 0, 0, Rfloat|Rdouble, 0, 0, 58 }, \ + { /* f27 */ 0, 0, Rfloat|Rdouble, 0, 0, 59 }, \ + { /* f28 */ 0, 0, Rfloat|Rdouble, 0, 0, 60 }, \ + { /* f29 */ 0, 0, Rfloat|Rdouble, 0, 0, 61 }, \ + { /* f30 */ 0, 0, Reserved, 0, 0, 62 }, \ + { /* fzero */ 0, 0, Reserved, 0, 0, 63 }, + + +/* Number of registers in the register set */ +#define NR_REGISTERS 64 + +/**/ +/* Opcode generation. */ +/**/ + +/* Extra label types */ +#define Llong21 (Larchdepend+0) /* Label is 21 bits long */ +#define Llong16x16 (Larchdepend+1) /* Label is split into 16 bit parts */ +#define Llong16 (Larchdepend+2) /* Label is 16 bits long */ +#define Lrsa (Larchdepend+3) /* Register Save Area */ + +/* if you change LABEL_Lframe() or LABEL_Lrsa() change also all + * REGISTER_JIT_METHOD() in config/alpha/.../md.c */ +#define LABEL_Lframe(P,V,L) \ + do { \ + int framesize = \ + STACKALIGN(SLOTSIZE * (maxLocal + maxStack + \ + maxTemp + (maxArgs < 6 ? maxArgs : 6) + \ + alpha_jit_info.rsa_size + \ + (maxPush <= 6 ? 0 : maxPush - 6))); \ + assert(framesize < 0x8000); \ + if (((L)->type & Ltypemask) == Lnegframe) \ + framesize = -framesize; \ + *(short *)(P) += framesize; \ + } while (0) +#define LABEL_Lrsa(P,V,L) \ + do { \ + int frameoffset = \ + SLOTSIZE * (maxPush <= 6 ? 0 : maxPush - 6); \ + assert(frameoffset < 0x8000); \ + *(short *)(P) += frameoffset; \ + } while (0) +#define LABEL_Llong21(P,V,L) (P)[0] = (((P)[0] & 0xFFE00000) | (((V) / 4) & 0x001FFFFF)) +#define LABEL_Llong16x16(P,V,L) (P)[1] = ((P)[1] & 0xFFFF0000) | ((V) & 0xFFFF); \ + (P)[0] = ((P)[0] & 0xFFFF0000) | (((V) >> 16) & 0xFFFF) +#define LABEL_Llong16(P,V,L) *(short*)(P) = (V) + +#define EXTRA_LABELS(P,D,L) \ + case Lframe: LABEL_Lframe(P,D,L); break; \ + case Lnegframe: LABEL_Lframe(P,D,L); break; \ + case Lrsa: LABEL_Lrsa(P,D,L); break; \ + case Llong21: LABEL_Llong21(P,D,L); break; \ + case Llong16x16: LABEL_Llong16x16(P,D,L); break; \ + case Llong16: LABEL_Llong16(P,D,L); break; + + +/**/ +/* Slot management information. */ +/**/ + +/* Size of each slot */ +#define SLOTSIZE 8 + +/* + * A stack frame looks like: + * + * | Arguments above 6 | + * fp-> |-------------------------------| + * | Spill for up to 6 args | + * |-------------------------------| + * | Locals, temps | + * |-------------------------------| + * | Register save area | + * |-------------------------------| + * | outgoing parameters past 6 | + * sp-> |-------------------------------| + */ + +#define FRAMEALIGN 16 +#define STACKALIGN(v) (((v) + FRAMEALIGN - 1) & -FRAMEALIGN) + +/* We push arguments low to high. */ +#define PUSHARG_FORWARDS 1 + + +/* Generate slot offset for an argument (relative to fp) */ +#define SLOT2ARGOFFSET(_n) alpha_slot2argoffset[_n] +extern int *alpha_slot2argoffset; + +/* Generate slot offset for a local (non-argument) (relative to fp) */ +#define SLOT2LOCALOFFSET(_n) alpha_slot2argoffset[_n] +/** +#define SLOT2LOCALOFFSET(_n) \ + (-SLOTSIZE * ((_n) + (maxArgs < 6 ? maxArgs : 6) + 3)) + **/ + +/* Generate slot offset for an push (relative to $sp); _n >= 6 */ +#define SLOT2PUSHOFFSET(_n) (SLOTSIZE * ((_n) - 6)) + + +/* On the Alpha we need to execute an instruction memory barrier before + running new code. + + For all the jillions of macros the OSF/1 assembler knows, you'd think + "imb" would be one of them. It isn't worth tracking down some pal.h + that's at different spots on different systems just for this, so we + hardcode the number. It's not like _that_ is ever going to change. */ + +#define FLUSH_DCACHE(beg, end) \ + __asm__ __volatile__("call_pal 134" : : : "memory") + + +#endif =================================================================== Checking out kaffe/config/arm/jit.h RCS: /home/cvs/kaffe/kaffe/config/arm/jit.h,v VERS: 1.16 *************** --- /dev/null Sun Aug 4 19:57:58 2002 +++ kaffe/config/arm/jit.h Wed Aug 10 21:35:22 2005 @@ -0,0 +1,368 @@ +/* + * arm/jit.h + * Common ARM JIT configuration information. + * + * Copyright (c) 1996, 1997, 1998, 1999 + * Transvirtual Technologies, Inc. All rights reserved. + * + * Copyright (c) 2003 + * Kaffe.org contributors, see ChangeLogs for details. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution + * of this file. + */ + +#ifndef __arm_jit_h +#define __arm_jit_h + +#include "config.h" + +/* The stack backtrace structure is as follows: +fp points to here: | save code pointer | + | return link value | [fp - 4 ] + | return sp value | [fp - 8 ] +exceptionFrame * -> | return fp value | [fp - 12] + [| saved r10 value |] + [| saved r9 value |] + [| saved r8 value |] + [| saved r7 value |] + [| saved r6 value |] + [| saved r5 value |] + [| saved r4 value |] + [| saved f7 value |] three words + [| saved f6 value |] three words + [| saved f5 value |] three words + [| saved f4 value |] three words + r0-r3 are not normally saved in a C function. */ + +/* Structure of exception frame on stack */ +typedef struct _exceptionFrame { + uintp retfp; + uintp retsp; + uintp retpc; +} exceptionFrame; + +/* Get the next frame in the chain */ +#define NEXTFRAME(f) \ + (((exceptionFrame*)(f))->retfp - sizeof(exceptionFrame)) + +/* Extract the PC from the given frame */ +#define PCFRAME(f) \ + ((f)->retpc - 4) +#define FPFRAME(f) \ + ((f)->retfp) + +/* Get the first exception frame from a subroutine call */ +#define FIRSTFRAME(f, o) \ + ({ char* v ; asm volatile("mov %0,fp" : "=r" (v)) ; \ + (f) = *(exceptionFrame*)(v - sizeof(exceptionFrame)); }) + +/* Extract the object argument from given frame */ +#define FRAMEOBJECT(obj, f, meth) do { \ + const char *str; \ + int maxLocal, maxStack, maxArgs, maxTemp; \ + /* Set up the necessary state for the SLOT2 macros to work \ + * in local variables to not get the translator lock. */ \ + maxLocal = meth->localsz; \ + maxStack = meth->stacksz; \ + str = METHOD_SIGD(meth); \ + maxArgs = sizeofSig(&str, false); \ + maxTemp = MAXTEMPS - 1; \ + /* NB: we assume that the JIT will have \ + * spilled the 'this' object in the \ + * stack location for slot zero. \ + */ \ + obj = ((Hjava_lang_Object**)(f))[SLOT2ARGOFFSET(0)/SLOTSIZE]; \ +} while (0) + + +/**/ +/* Method dispatch. */ +/**/ + +#define HAVE_TRAMPOLINE + +// +// In an environment using shared libraries, the trampoline address is +// a 32-bit signed address, but the BL instruction class only supports +// 24 bit signed offsets. On entry to the soft_fixup_trampoline code, we +// need to have r0 pointing to the "meth" field. +// On entry to arm_do_fixup_trampoline, we need to have ip (=r12) pointing +// there. arm_do_fixup_trampoline will then invoke soft_fixup_trampoline +// +// We accomplish this by using a PC-relative move to initialize +// ip to the address of "meth", and then a PC relative load +// to load the contents of "trampaddr". This makes the trampoline +// much larger, but it's not clear what else to do. +// +// Note that using the PC as a source register on the ARM returns +// PC+8 as the value (exposed pipeline). Bleh. +// +// Dirk & Godmar +// + +typedef struct _methodTrampoline { + unsigned int loadlr PACKED; + unsigned int branch PACKED; + struct _jmethodID* meth PACKED; + void** where PACKED; + void** trampaddr PACKED; +} methodTrampoline; + +extern void arm_do_fixup_trampoline(void); + +// +// Notes: 0xE1A0000F = mov ip, pc +// 0xE59FF000 = ldr pc, [pc, #0] +// NB: 0xE59FF004 = ldr pc, [pc, #4] + +#define FILL_IN_TRAMPOLINE(T,M,W) \ + do { \ + (T)->loadlr = 0xE1A0c00F; \ + (T)->branch = 0xE59FF004; \ + (T)->meth = (M); \ + (T)->where = (W); \ + (T)->trampaddr = (void**)arm_do_fixup_trampoline; \ + } while(0) + +/* _data will be $ip from FILL_IN_TRAMPOLINE, passed in $r0 */ +#define FIXUP_TRAMPOLINE_DECL void** _data + +/* The actual method to fix up is then *_pmeth */ +#define FIXUP_TRAMPOLINE_INIT (meth = (Method*)_data[0], \ + where = (void**)_data[1]) + +/**/ +/* Register management information. */ +/**/ + +#define _GR_ (Rglobal|Rnosaveoncall) + +/* Define the register set */ + // slot, ctype, type, flags, used, regno +#define REGISTER_SET \ + { /* r0 */ 0, 0, Rint|Rref, 0, 0, 0 }, \ + { /* r1 */ 0, 0, Rint|Rref, 0, 0, 1 }, \ + { /* r2 */ 0, 0, Rint|Rref, 0, 0, 2 }, \ + { /* r3 */ 0, 0, Rint|Rref, 0, 0, 3 }, \ + { /* r4 */ 0, 0, Rint|Rref, _GR_, 0, 4 }, \ + { /* r5 */ 0, 0, Rint|Rref, _GR_, 0, 5 }, \ + { /* r6 */ 0, 0, Rint|Rref, _GR_, 0, 6 }, \ + { /* r7 */ 0, 0, Rint|Rref, _GR_, 0, 7 }, \ + { /* r8 */ 0, 0, Rint|Rref, _GR_, 0, 8 }, \ + { /* r9 */ 0, 0, Reserved, 0, 0, 9 }, /* Static base */ \ + { /* r10 */ 0, 0, Rint|Rref, _GR_, 0, 10 },/* Stack limit */ \ + { /* fp */ 0, 0, Reserved, 0, 0, 11 }, \ + { /* ip */ 0, 0, Rint|Rref, 0, 0, 12 }, \ + { /* sp */ 0, 0, Reserved, 0, 0, 13 }, \ + { /* lr */ 0, 0, Reserved, 0, 0, 14 }, \ + { /* pc */ 0, 0, Reserved, 0, 0, 15 }, \ + { /* f0 */ 0, 0, Rfloat|Rdouble, 0, 0, 0 }, \ + { /* f1 */ 0, 0, Rfloat|Rdouble, 0, 0, 1 }, \ + { /* f2 */ 0, 0, Rfloat|Rdouble, 0, 0, 2 }, \ + { /* f3 */ 0, 0, Rfloat|Rdouble, 0, 0, 3 }, \ + { /* f4 */ 0, 0, Reserved, 0, 0, 4 }, \ + { /* f5 */ 0, 0, Reserved, 0, 0, 5 }, \ + { /* f6 */ 0, 0, Reserved, 0, 0, 6 }, \ + { /* f7 */ 0, 0, Reserved, 0, 0, 7 }, + +/* Number of registers in the register set */ +#define NR_REGISTERS 24 + +/**/ +/* Opcode generation. */ +/**/ + +/* Extra label types */ +#define Llong26 (Larchdepend+0) /* Label is 26 bits long */ +#define Llong8x8x8x8 (Larchdepend+1) /* Label is split into 4x8 bit parts */ +#define Loffset12 (Larchdepend+2) /* fill in 12-bit offset */ +#define Lfoffset8 (Larchdepend+3) /* fill in 8-bit offset */ +#define Lexception (Larchdepend+4) + +#define LABEL_Llong26(P,V,L) \ + { \ + assert(((V) & 0xFF000000) == 0 || ((V) & 0xFF000000) == 0xff000000); \ + (P)[0] = ((P)[0] & 0xFF000000)|(((V) >> 2) & 0x00FFFFFF); \ + } + +#define LABEL_Llong8x8x8x8(P,V,L) \ + (P)[0] = ((P)[0] & 0xFFFFFF00)|((V) & 0xFF); \ + (P)[1] = ((P)[1] & 0xFFFFFF00)|(((V)>> 8) & 0xFF); \ + (P)[2] = ((P)[2] & 0xFFFFFF00)|(((V)>>16) & 0xFF); \ + (P)[3] = ((P)[3] & 0xFFFFFF00)|(((V)>>24) & 0xFF) + +// +// Patch in the offset for constant pool references. +// Note that the instruction is encoded to subtract the +// offset from the base register (which points to the procedure entry) +// and thus we need to put in a positive address to get +// the proper displacement +// +#define LABEL_Loffset12(P,V,L) \ + { \ + int offset = codebase - (V); \ + int highpart = offset & ~0xfff;\ + assert((highpart >= 0) && (highpart <= 0xfff)); \ + (P)[0] = ((P)[0] & ~0xfff) | ((offset) & 0xfff); \ + } + +// +// Used by move_float_constpool. Same caveats as above. +// Note that floating/double loads used scaled indicies. +// +#define LABEL_Lfoffset8(P,V,L) \ + { \ + int offset = (codebase - (V)) >> 2; \ + int highpart = offset & ~0xff;\ + assert((highpart >= 0) && (highpart <= 0xff)); \ + (P)[0] = ((P)[0] & ~0xff) | ((offset) & 0xff); \ + } + +#define EXTRA_LABELS(P,D,L) \ + case Lframe: LABEL_Lframe(P,D,L); break; \ + case Lexception: LABEL_Lframe(P,D,L); \ + LABEL_Llong8x8x8x8( &(P[1]), codebase, L); \ + break; \ + case Loffset12: LABEL_Loffset12(P,D,L); break; \ + case Lfoffset8: LABEL_Lfoffset8(P,D,L); break; \ + case Llong26: LABEL_Llong26(P,D,L); break; \ + case Llong8x8x8x8: LABEL_Llong8x8x8x8(P,D,L); break; \ + + +/**/ +/* Slot management information. */ +/**/ + +/* Size of each slot */ +#define SLOTSIZE 4 + +// +// We push ..BFP|BIP|BLR|BR4|BR5|BR6|BR7|BR8|BR9|BR10 +// +#if !defined(JIT3) +// We save 10 registers +#define REGISTERS_SAVED (10) +#else +// We save 11 registers +#define REGISTERS_SAVED (11) +#endif + +// +// First four arguments are in registers, and then we need +// to compensate for the save code pointer, which is stored +// at (fp+4). The first argument is at (FP+8).We allocate +// slots for the first four arguments in the "locals" +// region. +// +/* Generate slot offset for a local (non-argument) */ +// + +/* + * We reserve (maxLocal + maxStack + maxTemp - X) slots on the stack, + * where X is the number of arguments to this function past the fourth. + * Those slots are accessible via positive offsets from the FP. + * The macro maps a slot number to a memory offset. + * We skip those memory offsets that correspond to slots that are + * arguments past the forth. + * + * NB: Kaffe's jit assumes that SLOT2LOCALOFFSET is monotonic in (N), i.e., + * OFF(N) > OFF(M) iff N > M. + * + * XXX: simplify this macro + */ +#define SLOT2LOCALOFFSET(N) \ + (- SLOTSIZE * (REGISTERS_SAVED + \ + (maxLocal+maxStack+maxTemp-((maxArgs <= 4)?0:maxArgs-4)) \ + - ((N < 4 || maxArgs <= 4) ? N : (N - maxArgs + 4)))) + +/* + * FP[1] contains the first extra argument. + */ +#define SLOT2ARGOFFSET(N) \ + ((N) >= 4 ? (SLOTSIZE * ((N) - 4 + 1)) : (SLOT2LOCALOFFSET(N))) + +/* This may waste some space if the required frame size does not + * exactly fit in a shifted 8bit value. + */ +#define LABEL_Lframe(P,V,L) \ + { \ + int shift = 0; \ + int val = (maxLocal + maxStack + maxTemp); \ + if (maxArgs > 4) { val -= maxArgs - 4;} \ + val *= SLOTSIZE; \ + while ((val & 0xFFFFFF00) != 0) { \ + val = val >> 2; \ + shift += 2; \ + } \ + shift /= 2; shift = (32 - shift); shift &= 0xf; \ + *(P) = (*(P) & 0xFFFFF000) | (shift<<8) | val; \ + } + + + +/* Wrap up a native call for the JIT */ +#define KAFFEJIT_TO_NATIVE(M) + +extern void flush_dcache(void *start, void *end); +#define FLUSH_DCACHE(BEG, END) flush_dcache(BEG, END) + +#if defined(JIT3) +/* + * Redefine anything relevant to JIT3. + */ + +#undef FRAMEOBJECT +#undef LABEL_Lframe +#undef SLOT2LOCALOFFSET +#undef SLOT2ARGOFFSET + +#define FRAMEOBJECT(O, F, E) \ + (O) = (*(Hjava_lang_Object**)((uintp)(F) - SLOTSIZE * REGISTERS_SAVED)) + +/* Number of function globals in register set */ +#define NR_GLOBALS 6 + +/**/ +/* We must setup the incoming argument state */ +/**/ +#define NR_ARGUMENTS 4 + +/* + * First four arguments are in registers, and then we need + * to compensate for the save code pointer, which is stored + * at (fp+4). The first argument is at (FP+8).We allocate + * slots for the first four arguments in the "locals" + * region. We always allocate 4 slots even though they're not + * always used. + * + * Generate slot offset for a local (non-argument) + */ + +#define SLOT2LOCALOFFSET(N) \ + (-SLOTSIZE * (REGISTERS_SAVED + (N) - maxArgs + NR_ARGUMENTS)) + +#define SLOT2ARGOFFSET(N) \ + ((N) >= NR_ARGUMENTS ? (SLOTSIZE * ((N) - NR_ARGUMENTS + 1)) : \ + -SLOTSIZE * (REGISTERS_SAVED + (N))) + +#define STACK_LIMIT() \ + SLOT2ARGOFFSET(maxArgs) + +#define LABEL_Lframe(P,V,L) \ + { \ + int shift = 0; \ + int val = (NR_ARGUMENTS + (maxLocal - maxArgs) + \ + maxStack + maxTemp); \ + val *= SLOTSIZE; \ + while ((val & 0xFFFFFF00) != 0) { \ + val = val >> 2; \ + shift += 2; \ + } \ + shift /= 2; shift = (32 - shift); shift &= 0xf; \ + *(P) = (*(P) & 0xFFFFF000) | (shift<<8) | val; \ + } + +#endif + +#endif =================================================================== Checking out kaffe/config/i386/jit.h RCS: /home/cvs/kaffe/kaffe/config/i386/jit.h,v VERS: 1.27 *************** --- /dev/null Sun Aug 4 19:57:58 2002 +++ kaffe/config/i386/jit.h Wed Aug 10 21:35:22 2005 @@ -0,0 +1,261 @@ +/* + * i386/jit.h + * Common i386 JIT configuration information. + * + * Copyright (c) 1996, 1997 + * Transvirtual Technologies, Inc. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution + * of this file. + */ + +#ifndef __i386_jit_h +#define __i386_jit_h + +#include "config.h" + +#if defined(HAVE_VALGRIND_MEMCHECK_H) +#include <valgrind/memcheck.h> +#endif + +/**/ +/* Exception handling information. */ +/**/ + +/* Structure of exception frame on stack */ +typedef struct _exceptionFrame { + uintp retbp; + uintp retpc; +} exceptionFrame; + +/* Get the next frame in the chain */ +#define NEXTFRAME(f) (((exceptionFrame*)(f))->retbp) + +/* Extract the PC & FP from the given frame */ +#define PCFRAME(f) ((f)->retpc-1) +#define FPFRAME(f) ((f)->retbp) + +/* Extract a local argument from given frame */ +#define FRAMEOBJECT(obj, f, einfo) \ + (obj) = (*(Hjava_lang_Object**)((f) + 8)) + +/* Get the first exception frame from a subroutine call */ +#define FIRSTFRAME(f, o) \ + ((f) = *(exceptionFrame*)__builtin_frame_address(0)) + +/**/ +/* Method dispatch. */ +/**/ + +#define HAVE_TRAMPOLINE + +#if defined(_MSC_VER) +#pragma pack ( push, 1 ) +#endif + +extern void i386_do_fixup_trampoline(void); + +typedef struct _methodTrampoline { + unsigned char call; + int fixup PACKED; + struct _jmethodID* meth PACKED; + void** where PACKED; +} methodTrampoline; + +#if defined(_MSC_VER) +#pragma pack ( pop ) +#endif + +/* NB: the E8 jmp instruction uses relative addressing */ +#define FILL_IN_TRAMPOLINE(t,m,w) \ + do { \ + (t)->call = 0xe8; \ + (t)->fixup = (int)i386_do_fixup_trampoline - (int)(t) - 5; \ + (t)->meth = (m); \ + (t)->where = (w); \ + } while (0) + +#define FIXUP_TRAMPOLINE_DECL void** _data +#define FIXUP_TRAMPOLINE_INIT (meth = (Method*)_data[0], \ + where = (void**)_data[1]) + +/**/ +/* Register management information. */ +/**/ +#define HAVE_FLOATING_POINT_STACK + +/* Define the register set */ +#define REGISTER_SET \ + { /* eax */ NULL, 0, Rint|Rsubint|Rref,0, 0, 0 }, \ + { /* ecx */ NULL, 0, Rint|Rsubint|Rref,0, 0, 1 }, \ + { /* edx */ NULL, 0, Rint|Rsubint|Rref,0, 0, 2 }, \ + { /* ebx */ NULL, 0, Rint|Rsubint|Rref,Rglobal|Rnosaveoncall, 0, 3 },\ + { /* esp */ NULL, 0, Reserved, 0, 0, 4 }, \ + { /* ebp */ NULL, 0, Reserved, 0, 0, 5 }, \ + { /* esi */ NULL, 0, Rint|Rref, Rglobal|Rnosaveoncall, 0, 6 },\ + { /* edi */ NULL, 0, Rint|Rref, Rglobal|Rnosaveoncall, 0, 7 },\ + { /* f0 */ NULL, 0, Rfloat|Rdouble, Rreadonce, 0, 8 }, + +/* Number of registers in the register set */ +#define NR_REGISTERS 9 + +/* Number of function globals in register set - JIT3 */ +#define NR_GLOBALS 3 + +/**/ +/* Opcode generation. */ +/**/ + +/* Extra label types */ +#define Llong8 (Larchdepend+0) /* Label is 8 bits long */ + +#define LABEL_Lframe(P,D,L) \ + { \ + int framesize = SLOTSIZE * (maxLocal + maxStack + \ + maxTemp - maxArgs); \ + *(uint32*)(P) = framesize; \ + } +#define LABEL_Llong8(P,V,L) *(char*)(P) = (V) + +#define EXTRA_LABELS(P,D,L) \ + case Llong8: LABEL_Llong8(P,D,L); break; \ + case Lframe: LABEL_Lframe(P,D,L); break; + +/* Define if generated code uses two operands rather than one */ +#define TWO_OPERAND + +/**/ +/* Slot management information. */ +/**/ + +/* Size of each slot */ +#define SLOTSIZE 4 + +/* Generate slot offset for an argument */ +#define SLOT2ARGOFFSET(_n) (8 + SLOTSIZE * (_n)) + +/* Generate slot offset for a local (non-argument) */ +#if defined(JIT3) +#define SLOT2LOCALOFFSET(N) (-SLOTSIZE * ((N) - maxArgs + 1)) +#else +#define SLOT2LOCALOFFSET(_n) (-SLOTSIZE * (maxTemp+maxLocal+maxStack - (_n))) +#endif + +#if defined(JIT3) && !defined(HAVE_GCJ_SUPPORT) +/* Generate the slot offset to the stack limit */ +#define STACK_LIMIT() SLOT2ARGOFFSET(maxArgs) +#endif + +/* Wrap up a native call for the JIT */ +#define KAFFEJIT_TO_NATIVE(_m) + +/* We don't have to flush the code out of cache on the i386 */ +#if defined(HAVE_VALGRIND_MEMCHECK_H) +#define FLUSH_DCACHE(beg, end) VALGRIND_DISCARD_TRANSLATIONS(beg, end) +#else +#define FLUSH_DCACHE(beg, end) /* Do nothing */ +#endif + +/* The Pentium optimization manual recommends these */ +#define CALLTARGET_ALIGNMENT 16 + +#if defined (HAVE_GCJ_SUPPORT) + +/* + * If we provide gcj support, we must include some architecture specific + * information about gcc here. + */ + +/* from egcs/gcc/config/i386/i386.h + * + * How to renumber registers for dbx and gdb. + * + * #define CALL_USED_REGISTERS \ + * ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg,flags,fpsr \ + * { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + * + */ + +/* {0,2,1,3,6,7,4,5,12,13,14,15,16,17} */ +#define DBX_REGISTER_NUMBER(n) \ +((n) == 0 ? 0 : \ + (n) == 1 ? 2 : \ + (n) == 2 ? 1 : \ + (n) == 3 ? 3 : \ + (n) == 4 ? 6 : \ + (n) == 5 ? 7 : \ + (n) == 6 ? 4 : \ + (n) == 7 ? 5 : \ + (n) + 4) + +#define DWARF_FRAME_REGISTERS 17 +#define DWARF_FRAME_RETURN_COLUMN 8 + +/* offset of CFA from cfa register */ +#define CFA_OFFSET 8 +#define CFA_REGISTER DBX_REGISTER_NUMBER(/* gcc_esp */ 7) + +/* offset of return address from CFA */ +#define RETADDR_SAVED_OFFSET -4 +#define CFA_SAVED_OFFSET -8 + +/* + * Frame layout on the x86 is like so + * + * CFA -> +0 Canonical Frame Address -- by definition + * -4 caller's ret pc + * ebp -> -8 caller's ebp + * -12 local 1 + * -16 local 2 + * -20 local 3 + * ... + * -8 -meth->framesize local n + * -12-meth->framesize caller's %edi + * -16-meth->framesize caller's %esi + * -20-meth->framesize caller's %ebx + * esp -> + * + */ + +struct kaffe_frame_descriptor; + +/* + * Establish JIT3 callee-saved register information for i386 + * We must tell gcj where esi, edi, and ebx have been stored + * on this frame, as an offset from the CFA. + * In addition, we must tell it where the caller's esp was stored + * + * Compare prologue_xxx in jit3-i386.def + */ +void arch_get_frame_description(int framesize, + struct kaffe_frame_descriptor frame_desc[], + int *n); *** Patch too long, truncated *** _______________________________________________ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe