#CFLAGS = -O2 -OPT:Olimit=0 $(THREAD_CFLAGS) -DMAP_ANONYMOUS=0
#LFLAGS = -lm -lelfutil
-OBJ = main.o tables.o loader.o compiler.o newcomp.o builtin.o asmpart.o \
+OBJ = main.o tables.o loader.o compiler.o jit.o builtin.o asmpart.o \
toolbox/toolbox.a native.o $(THREAD_OBJ) mm/mm.o
OBJH = headers.o tables.o loader.o builtin.o toolbox/toolbox.a $(THREAD_OBJ) \
mm/mm.o
cacaoh: $(OBJH)
$(CC) $(CFLAGS) -o cacaoh $(OBJH) $(LFLAGS)
-main.o: main.c global.h tables.h compiler.h ncomp/ncomp.h loader.h \
+main.o: main.c global.h tables.h loader.h jit.h compiler.h \
asmpart.h builtin.h native.h
headers.o: headers.c global.h tables.h loader.h
compiler.o: builtin.h compiler.h global.h loader.h tables.h native.h \
asmpart.h compiler.c comp/*.c sysdep/gen.c sysdep/disass.c
-newcomp.o: builtin.h ncomp/ncomp.h global.h loader.h tables.h native.h \
- asmpart.h ncomp/ncompdef.h ncomp/*.c sysdep/ngen.h sysdep/ngen.c sysdep/disass.c
+jit.o: builtin.h jit.h global.h loader.h tables.h native.h asmpart.h \
+ jit/jitdef.h jit/*.c sysdep/ngen.h sysdep/ngen.c sysdep/disass.c
builtin.o: builtin.c global.h loader.h builtin.h tables.h sysdep/native-math.h
/*************************** imported functions *******************************/
- .globl compiler_compile
+ .globl jit_compile
.globl builtin_monitorexit
.globl builtin_throw_exception
.globl builtin_trace_exception
stq ra,13*8(sp) /* save return address */
ldq a0,0(v0) /* pass 'methodinfo' pointer to */
- jsr ra,compiler_compile /* compiler */
+ jsr ra,jit_compile /* jit compiler */
ldgp gp,0(ra)
call_pal PAL_imb /* synchronise instruction cache */
/******************* function perform_alpha_threadswitch ***********************
* *
* void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
+* *
* performs a threadswitch *
* *
*******************************************************************************/
/********************* function asm_switchstackandcall *************************
* *
+* void asm_switchstackandcall (void *stack, void *func); *
+* *
* Switches to a new stack, calls a function and switches back. *
* a0 new stack pointer *
* a1 function pointer *
-/*************************** alpha/defines.h ***********************************
+/* alpha/defines.h *************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
system-dependent definitions
- Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
- Mark Probst EMAIL: cacao@complang.tuwien.ac.at
+ Authors: Mark Probst EMAIL: cacao@complang.tuwien.ac.at
Last Change: 1997/09/11
};
-/* function disassemble ********************************************************
+/* function disassinstr ********************************************************
outputs a disassembler listing of one machine code instruction on 'stdout'
c: instructions machine code
*******************************************************************************/
-static void disasscmd (int c, int pos)
+static void disassinstr(int c, int pos)
{
int op; /* 6 bit op code */
int opfun; /* 7 bit function code */
*******************************************************************************/
-static void disassemble (int *code, int len)
+static void disassemble(int *code, int len)
{
int p;
printf (" --- disassembler listing ---\n");
for (p = 0; p < len; p += 4, code++)
- disasscmd (*code, p);
+ disassinstr(*code, p);
}
#define NATIVESTUBSIZE 11
-u1 *createnativestub (functionptr f, methodinfo *m)
+u1 *oldcreatenativestub (functionptr f, methodinfo *m)
{
u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
s4 *p = (s4*) s; /* code generation pointer */
-/************************* alpha/native-math.h *********************************
+/* alpha/native-math.h *********************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
}
-/* function: ncreatenativestub *************************************************
+/* function: createnativestub **************************************************
creates a stub routine which calls a native method
#define NATIVESTUBSIZE 11
-u1 *ncreatenativestub (functionptr f, methodinfo *m)
+u1 *createnativestub (functionptr f, methodinfo *m)
{
u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
s4 *p = (s4*) s; /* code generation pointer */
-/*************************** alpha/types.h *************************************
+/* alpha/types.h ***************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
/*************************** globale Schalter ********************************/
-extern int newcompiler;
-methodptr new_compile (methodinfo *m); /* compile a method with new compiler */
-
-/************************** no all in newcomp.c
+/************************** now all in newcomp.c
bool compileverbose = false;
bool showstack = false;
long int starttime=0,stoptime=0;
long int dumpsize;
- if (newcompiler) {
- return new_compile(m);
- }
/*** Wenn schon ein Maschinencode vorliegt, dann sofort beenden ****/
void compiler_init ();
void compiler_close ();
+u1 *oldcreatenativestub (functionptr f, methodinfo *m);
+
+/*
u1 *createcompilerstub (methodinfo *m);
-u1 *createnativestub (functionptr f, methodinfo *m);
-u1 *ncreatenativestub (functionptr f, methodinfo *m);
void removecompilerstub (u1 *stub);
void removenativestub (u1 *stub);
+*/
*******************************************************************************/
#ifndef __global_h_
-#define __global_h_ /* schani */
+#define __global_h_
-#define STATISTICS /* andi */
+#define OLD_COMPILER /* if enabled makes old compiler available */
+
+#define STATISTICS /* if enabled collects program statistics */
/* JIT_MARKER_SUPPORT is the define used to toggle Just-in-time generated
- marker functions on and off. */
-#undef JIT_MARKER_SUPPORT /* phil */
+ marker functions on and off.
+*/
+#undef JIT_MARKER_SUPPORT /* phil */
/* standard includes **********************************************************/
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** headers.c **************************************
+/* headers.c *******************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
u1 *createcompilerstub (methodinfo *m) {return NULL;}
u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
-u1 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
+u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
void removecompilerstub (u1 *stub) {}
void removenativestub (u1 *stub) {}
}
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/* jit.c ***********************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+ Contains the functions which translates a JavaVM method into native code.
+ This is the new version of the compiler which is a lot faster and has new
+ exception handling schemes. The main function is new_comp.
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+ Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1997/11/05
+
+*******************************************************************************/
+
+#include "signal.h"
+#include "global.h"
+
+#include "tables.h"
+#include "loader.h"
+#include "jit.h"
+#include "builtin.h"
+#include "native.h"
+#include "asmpart.h"
+
+#include "threads/thread.h"
+
+
+/* global switches ************************************************************/
+
+bool compileverbose = false;
+bool showstack = false;
+bool showdisassemble = false;
+bool showddatasegment = false;
+bool showintermediate = false;
+int optimizelevel = 0;
+
+bool checkbounds = true;
+bool checknull = true;
+bool checkfloats = true;
+bool checksync = true;
+
+bool getcompilingtime = false;
+long compilingtime = 0;
+
+int has_ext_instr_set = 0;
+
+bool statistics = false;
+
+int count_jit_calls = 0;
+int count_methods = 0;
+int count_spills = 0;
+int count_pcmd_activ = 0;
+int count_pcmd_drop = 0;
+int count_pcmd_zero = 0;
+int count_pcmd_const_store = 0;
+int count_pcmd_const_alu = 0;
+int count_pcmd_const_bra = 0;
+int count_pcmd_load = 0;
+int count_pcmd_move = 0;
+int count_load_instruction = 0;
+int count_pcmd_store = 0;
+int count_pcmd_store_comb = 0;
+int count_dup_instruction = 0;
+int count_pcmd_op = 0;
+int count_pcmd_mem = 0;
+int count_pcmd_met = 0;
+int count_pcmd_bra = 0;
+int count_pcmd_table = 0;
+int count_pcmd_return = 0;
+int count_pcmd_returnx = 0;
+int count_check_null = 0;
+int count_check_bound = 0;
+int count_max_basic_blocks = 0;
+int count_basic_blocks = 0;
+int count_javainstr = 0;
+int count_max_javainstr = 0;
+int count_javacodesize = 0;
+int count_javaexcsize = 0;
+int count_calls = 0;
+int count_tryblocks = 0;
+int count_code_len = 0;
+int count_data_len = 0;
+int count_cstub_len = 0;
+int count_nstub_len = 0;
+int count_max_new_stack = 0;
+int count_upper_bound_new_stack = 0;
+static int count_block_stack_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+int *count_block_stack = count_block_stack_init;
+static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
+int *count_analyse_iterations = count_analyse_iterations_init;
+static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+int *count_method_bb_distribution = count_method_bb_distribution_init;
+static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+int *count_block_size_distribution = count_block_size_distribution_init;
+static int count_store_length_init[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+int *count_store_length = count_store_length_init;
+static int count_store_depth_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+int *count_store_depth = count_store_depth_init;
+
+
+/* include compiler data types ************************************************/
+
+#include "jit/jitdef.h"
+
+
+/* global compiler variables **************************************************/
+
+ /* data about the currently compiled method */
+
+static classinfo *class; /* class the compiled method belongs to */
+static methodinfo *method; /* pointer to method info of compiled method */
+static unicode *descriptor; /* type descriptor of compiled method */
+static u2 mparamcount; /* number of parameters (incl. this) */
+static u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
+static u2 mreturntype; /* return type of method */
+
+static int maxstack; /* maximal JavaVM stack size */
+static int maxlocals; /* maximal number of local JavaVM variables */
+static int jcodelength; /* length of JavaVM-codes */
+static u1 *jcode; /* pointer to start of JavaVM-code */
+static int exceptiontablelength;/* length of exception table */
+static exceptiontable *extable; /* pointer to start of exception table */
+
+static int block_count; /* number of basic blocks */
+static basicblock *block; /* points to basic block array */
+static int *block_index; /* a table which contains for every byte of */
+ /* JavaVM code a basic block index if at this */
+ /* byte there is the start of a basic block */
+
+static int instr_count; /* number of JavaVM instructions */
+static instruction *instr; /* points to intermediate code instructions */
+
+static int stack_count; /* number of stack elements */
+static stackelement *stack; /* points to intermediate code instructions */
+
+static bool isleafmethod; /* true if a method doesn't call subroutines */
+
+/* list of all classes used by the compiled method which have to be */
+/* initialised (if not already done) before execution of this method */
+
+static chain *uninitializedclasses;
+
+
+/* include compiler subsystems ************************************************/
+
+#include "sysdep/ngen.h" /* code generator header file */
+#include "sysdep/disass.c" /* disassembler (for debug purposes only) */
+#include "jit/mcode.c" /* code generation tool functions */
+#include "jit/parse.c" /* parsing of JavaVM code */
+#include "jit/reg.c" /* register allocation and support routines */
+#include "jit/stack.c" /* analysing the stack operations */
+#include "sysdep/ngen.c" /* code generator */
+
+
+
+
+/* dummy function, used when there is no JavaVM code available */
+
+static void* do_nothing_function()
+{
+ return NULL;
+}
+
+
+#ifdef OLD_COMPILER
+extern bool newcompiler;
+methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
+#endif
+
+
+/* jit_compile *****************************************************************
+
+ jit_compile, new version of compiler, translates one method to machine code
+
+*******************************************************************************/
+
+methodptr jit_compile(methodinfo *m)
+{
+ int dumpsize;
+ long starttime = 0;
+ long stoptime = 0;
+
+#ifdef OLD_COMPILER
+ if (!newcompiler) {
+ return compiler_compile(m);
+ }
+#endif
+
+ /* if method has been already compiled return immediately */
+
+ count_jit_calls++;
+
+ if (m->entrypoint)
+ return m->entrypoint;
+
+ count_methods++;
+
+ intsDisable(); /* disable interrupts */
+
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size ();
+
+ /* measure time */
+
+ if (getcompilingtime)
+ starttime = getcputime();
+
+ /* if there is no javacode print error message and return empty method */
+
+ if (! m->jcode) {
+ sprintf(logtext, "No code given for: ");
+ unicode_sprint(logtext+strlen(logtext), m->class->name);
+ strcpy(logtext+strlen(logtext), ".");
+ unicode_sprint(logtext+strlen(logtext), m->name);
+ unicode_sprint(logtext+strlen(logtext), m->descriptor);
+ dolog();
+ intsRestore(); /* enable interrupts again */
+ return (methodptr) do_nothing_function; /* return empty method */
+ }
+
+ /* print log message for compiled method */
+
+ if (compileverbose) {
+ sprintf(logtext, "Compiling: ");
+ unicode_sprint(logtext+strlen(logtext), m->class->name);
+ strcpy(logtext+strlen(logtext), ".");
+ unicode_sprint(logtext+strlen(logtext), m->name);
+ unicode_sprint(logtext+strlen(logtext), m->descriptor);
+ dolog ();
+ }
+
+
+ /* initialisation of variables and subsystems */
+
+ isleafmethod = true;
+
+ method = m;
+ class = m->class;
+ descriptor = m->descriptor;
+ maxstack = m->maxstack;
+ maxlocals = m->maxlocals;
+ jcodelength = m->jcodelength;
+ jcode = m->jcode;
+ exceptiontablelength = m->exceptiontablelength;
+ extable = m->exceptiontable;
+
+#ifdef STATISTICS
+ count_tryblocks += exceptiontablelength;
+ count_javacodesize += jcodelength + 18;
+ count_javaexcsize += exceptiontablelength * 8;
+#endif
+
+ /* initialise parameter type descriptor */
+
+ descriptor2types (m);
+ mreturntype = m->returntype;
+ mparamcount = m->paramcount;
+ mparamtypes = m->paramtypes;
+
+ /* initialize class list with class the compiled method belongs to */
+
+ uninitializedclasses = chain_new();
+ compiler_addinitclass (m->class);
+
+
+ /* call the compiler passes ***********************************************/
+
+ reg_init();
+ local_init();
+ mcode_init();
+
+ if (runverbose)
+ allocate_literals();
+
+ parse();
+
+ analyse_stack();
+
+ interface_regalloc();
+
+ allocate_scratch_registers();
+
+ local_regalloc();
+
+ gen_mcode();
+
+
+ /* intermediate and assembly code listings ********************************/
+
+ if (showintermediate)
+ show_icmd_method();
+ else if (showdisassemble)
+ disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
+
+ if (showddatasegment)
+ dseg_display((void*) (m->mcode));
+
+
+
+ /* release dump area */
+
+ dump_release (dumpsize);
+
+ /* measure time */
+
+ if (getcompilingtime) {
+ stoptime = getcputime();
+ compilingtime += (stoptime-starttime);
+ }
+
+ /* initialize all used classes */
+ /* because of reentrant code global variables are not allowed here */
+
+ {
+ chain *ul = uninitializedclasses; /* list of uninitialized classes */
+ classinfo *c; /* single class */
+
+ while ((c = chain_first(ul)) != NULL) {
+ chain_remove (ul);
+ class_init (c); /* may again call the compiler */
+ }
+ chain_free (ul);
+ }
+
+ intsRestore(); /* enable interrupts again */
+
+ /* return pointer to the methods entry point */
+
+ return m -> entrypoint;
+}
+
+
+/* functions for compiler initialisation and finalisation *********************/
+
+void jit_init ()
+{
+ int i;
+
+ has_ext_instr_set = ! has_no_x_instr_set();
+
+ for (i = 0; i < 256; i++)
+ stackreq[i] = 1;
+
+ stackreq[JAVA_NOP] = 0;
+ stackreq[JAVA_ISTORE] = 0;
+ stackreq[JAVA_LSTORE] = 0;
+ stackreq[JAVA_FSTORE] = 0;
+ stackreq[JAVA_DSTORE] = 0;
+ stackreq[JAVA_ASTORE] = 0;
+ stackreq[JAVA_ISTORE_0] = 0;
+ stackreq[JAVA_ISTORE_1] = 0;
+ stackreq[JAVA_ISTORE_2] = 0;
+ stackreq[JAVA_ISTORE_3] = 0;
+ stackreq[JAVA_LSTORE_0] = 0;
+ stackreq[JAVA_LSTORE_1] = 0;
+ stackreq[JAVA_LSTORE_2] = 0;
+ stackreq[JAVA_LSTORE_3] = 0;
+ stackreq[JAVA_FSTORE_0] = 0;
+ stackreq[JAVA_FSTORE_1] = 0;
+ stackreq[JAVA_FSTORE_2] = 0;
+ stackreq[JAVA_FSTORE_3] = 0;
+ stackreq[JAVA_DSTORE_0] = 0;
+ stackreq[JAVA_DSTORE_1] = 0;
+ stackreq[JAVA_DSTORE_2] = 0;
+ stackreq[JAVA_DSTORE_3] = 0;
+ stackreq[JAVA_ASTORE_0] = 0;
+ stackreq[JAVA_ASTORE_1] = 0;
+ stackreq[JAVA_ASTORE_2] = 0;
+ stackreq[JAVA_ASTORE_3] = 0;
+ stackreq[JAVA_IASTORE] = 0;
+ stackreq[JAVA_LASTORE] = 0;
+ stackreq[JAVA_FASTORE] = 0;
+ stackreq[JAVA_DASTORE] = 0;
+ stackreq[JAVA_AASTORE] = 0;
+ stackreq[JAVA_BASTORE] = 0;
+ stackreq[JAVA_CASTORE] = 0;
+ stackreq[JAVA_SASTORE] = 0;
+ stackreq[JAVA_POP] = 0;
+ stackreq[JAVA_POP2] = 0;
+ stackreq[JAVA_IINC] = 0;
+ stackreq[JAVA_IFEQ] = 0;
+ stackreq[JAVA_IFNE] = 0;
+ stackreq[JAVA_IFLT] = 0;
+ stackreq[JAVA_IFGE] = 0;
+ stackreq[JAVA_IFGT] = 0;
+ stackreq[JAVA_IFLE] = 0;
+ stackreq[JAVA_IF_ICMPEQ] = 0;
+ stackreq[JAVA_IF_ICMPNE] = 0;
+ stackreq[JAVA_IF_ICMPLT] = 0;
+ stackreq[JAVA_IF_ICMPGE] = 0;
+ stackreq[JAVA_IF_ICMPGT] = 0;
+ stackreq[JAVA_IF_ICMPLE] = 0;
+ stackreq[JAVA_IF_ACMPEQ] = 0;
+ stackreq[JAVA_IF_ACMPNE] = 0;
+ stackreq[JAVA_GOTO] = 0;
+ stackreq[JAVA_RET] = 0;
+ stackreq[JAVA_TABLESWITCH] = 0;
+ stackreq[ICMD_LOOKUPSWITCH] = 0;
+ stackreq[JAVA_IRETURN] = 0;
+ stackreq[JAVA_LRETURN] = 0;
+ stackreq[JAVA_FRETURN] = 0;
+ stackreq[JAVA_DRETURN] = 0;
+ stackreq[JAVA_ARETURN] = 0;
+ stackreq[JAVA_RETURN] = 0;
+ stackreq[JAVA_PUTSTATIC] = 0;
+ stackreq[JAVA_PUTFIELD] = 0;
+ stackreq[JAVA_MONITORENTER] = 0;
+ stackreq[ICMD_MONITOREXIT] = 0;
+ stackreq[JAVA_WIDE] = 0;
+ stackreq[JAVA_IFNULL] = 0;
+ stackreq[JAVA_IFNONNULL] = 0;
+ stackreq[JAVA_GOTO_W] = 0;
+ stackreq[JAVA_BREAKPOINT] = 0;
+
+ stackreq[JAVA_SWAP] = 2;
+ stackreq[JAVA_DUP2] = 2;
+ stackreq[JAVA_DUP_X1] = 3;
+ stackreq[JAVA_DUP_X2] = 4;
+ stackreq[JAVA_DUP2_X1] = 3;
+ stackreq[JAVA_DUP2_X2] = 4;
+
+ for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
+
+ for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
+
+ if (stdopdescriptortable[i].isfloat && checkfloats) {
+ stdopdescriptortable[i].supported = false;
+ }
+
+ stdopdescriptors[stdopdescriptortable[i].opcode] =
+ &(stdopdescriptortable[i]);
+ }
+
+ init_exceptions();
+}
+
+
+void jit_close()
+{
+ mcode_close();
+ reg_close();
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/* jit.h ***********************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ new compiler header file for inclusion in other moduls.
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+ Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1997/11/05
+
+*******************************************************************************/
+
+/* compiler switches (set by main function) ***********************************/
+
+extern bool runverbose; /* trace all method invocation */
+extern bool compileverbose; /* trace compiler actions */
+extern bool showdisassemble; /* generate disassembler listing */
+extern bool showddatasegment; /* generate data segment listing */
+extern bool showintermediate; /* generate intermediate code listing */
+extern int optimizelevel; /* optimzation level (0 = no optimization) */
+
+extern bool checkbounds; /* check array bounds */
+extern bool checknull; /* check null pointers */
+extern bool checkfloats; /* implement ieee compliant floats */
+extern bool checksync; /* do synchronization */
+
+extern bool getcompilingtime; /* compute compile time */
+extern long compilingtime; /* accumulated compile time */
+
+extern int has_ext_instr_set; /* has instruction set extensions */
+
+extern bool statistics;
+
+extern int count_jit_calls;
+extern int count_methods;
+extern int count_spills;
+extern int count_pcmd_activ;
+extern int count_pcmd_drop;
+extern int count_pcmd_zero;
+extern int count_pcmd_const_store;
+extern int count_pcmd_const_alu;
+extern int count_pcmd_const_bra;
+extern int count_pcmd_load;
+extern int count_pcmd_move;
+extern int count_load_instruction;
+extern int count_pcmd_store;
+extern int count_pcmd_store_comb;
+extern int count_dup_instruction;
+extern int count_pcmd_op;
+extern int count_pcmd_mem;
+extern int count_pcmd_met;
+extern int count_pcmd_bra;
+extern int count_pcmd_table;
+extern int count_pcmd_return;
+extern int count_pcmd_returnx;
+extern int count_check_null;
+extern int count_check_bound;
+extern int count_max_basic_blocks;
+extern int count_basic_blocks;
+extern int count_max_javainstr;
+extern int count_javainstr;
+extern int count_javacodesize;
+extern int count_javaexcsize;
+extern int count_calls;
+extern int count_tryblocks;
+extern int count_code_len;
+extern int count_data_len;
+extern int count_cstub_len;
+extern int count_nstub_len;
+extern int count_max_new_stack;
+extern int count_upper_bound_new_stack;
+extern int *count_block_stack;
+extern int *count_analyse_iterations;
+extern int *count_method_bb_distribution;
+extern int *count_block_size_distribution;
+extern int *count_store_length;
+extern int *count_store_depth;
+
+/* prototypes *****************************************************************/
+
+methodptr jit_compile (methodinfo *m); /* compile a method with jit compiler */
+
+void jit_init(); /* compiler initialisation */
+void jit_close(); /* compiler finalisation */
+
+u1 *createcompilerstub (methodinfo *m);
+u1 *createnativestub (functionptr f, methodinfo *m);
+
+void removecompilerstub (u1 *stub);
+void removenativestub (u1 *stub);
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/******************************* ncomp/compdef.h *******************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ defines all the constants and data structures of the compiler
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1998/11/03
+
+*******************************************************************************/
+
+#include "../sysdep/types.h"
+
+/**************************** resolve typedef-cycles **************************/
+
+typedef struct stackelement stackelement;
+typedef stackelement *stackptr;
+typedef struct basicblock basicblock;
+typedef struct instruction instruction;
+typedef struct subroutineinfo subroutineinfo;
+typedef struct varinfo varinfo;
+typedef struct branchref branchref;
+typedef struct jumpref jumpref;
+typedef varinfo *varinfoptr;
+
+
+/************************** stack element structure ***************************/
+
+/* slot types */
+
+#define TYPE_INT 0 /* the stack slot types must numbered in the */
+#define TYPE_LNG 1 /* same order as the ICMD_Ixxx to ICMD_Axxx */
+#define TYPE_FLT 2 /* instructions (LOAD and STORE) */
+#define TYPE_DBL 3 /* integer, long, float, double, address */
+#define TYPE_ADR 4
+
+#define IS_INT_LNG_TYPE(a) (!((a)&TYPE_FLT))
+#define IS_FLT_DBL_TYPE(a) ((a)&TYPE_FLT)
+#define IS_2_WORD_TYPE(a) ((a)&TYPE_LNG)
+
+
+/* flags */
+
+#define SAVEDVAR 1 /* variable has to survive method invocations */
+#define INMEMORY 2 /* variable stored in memory */
+
+/* variable types */
+
+#define UNDEFVAR 0 /* stack slot will become temp during regalloc*/
+#define TEMPVAR 1 /* stack slot is temp register */
+#define STACKVAR 2 /* stack slot is numbered stack slot */
+#define LOCALVAR 3 /* stack slot is local variable */
+#define ARGVAR 4 /* stack slot is argument variable */
+
+struct stackelement {
+ stackptr prev; /* pointer to next element towards bottom */
+ int type; /* data type of stack element */
+ int flags; /* flags (SAVED, INMEMORY) */
+ int varkind; /* kind of variable or register */
+ int varnum; /* number of variable */
+ int regoff; /* register number or memory offset */
+ };
+
+
+/**************************** instruction structure ***************************/
+
+struct instruction {
+ stackptr dst; /* stack index of destination operand stack */
+ u2 opc; /* opcode of intermediate code command */
+ s4 op1; /* first operand, usually variable number */
+
+ union {
+ s4 i; /* integer operand */
+ s8 l; /* long operand */
+ float f; /* float operand */
+ double d; /* double operand */
+ void *a; /* address operand */
+ } val; /* immediate constant */
+ };
+
+
+/**************************** basic block structure ***************************/
+
+/* flags */
+
+#define BBDELETED -2
+#define BBUNDEF -1
+#define BBREACHED 0
+#define BBFINISHED 1
+
+#define BBTYPE_STD 0 /* standard basic block type */
+#define BBTYPE_EXH 1 /* exception handler basic block type */
+#define BBTYPE_SBR 2 /* subroutine basic block type */
+
+struct basicblock {
+ int flags; /* used during stack analysis, init with -1 */
+ int type; /* basic block type (std, xhandler, subroutine*/
+ instruction *iinstr; /* pointer to intermediate code instructions */
+ int icount; /* number of intermediate code instructions */
+ int mpc; /* machine code pc at start of block */
+ stackptr instack; /* stack at begin of basic block */
+ stackptr outstack; /* stack at end of basic block */
+ int indepth; /* stack depth at begin of basic block */
+ int outdepth; /* stack depth end of basic block */
+ int pre_count; /* count of predecessor basic blocks */
+ branchref *branchrefs; /* list of branches to be patched */
+ };
+
+
+/************************* pseudo variable structure **************************/
+
+struct varinfo {
+ int type; /* basic type of variable */
+ int flags; /* flags (SAVED, INMEMORY) */
+ int regoff; /* register number or memory offset */
+ };
+
+typedef varinfo varinfo5[5];
+
+
+/***************** forward references in branch instructions ******************/
+
+struct branchref {
+ s4 branchpos; /* patching position in code segment */
+ branchref *next; /* next element in branchref list */
+ };
+
+
+/******************** forward references in tables ***************************/
+
+struct jumpref {
+ s4 tablepos; /* patching position in data segment */
+ basicblock *target; /* target basic block */
+ jumpref *next; /* next element in jumpref list */
+ };
+
+
+/********** JavaVM operation codes (sorted) and instruction lengths ***********/
+
+static int stackreq[256];
+
+static int jcommandsize[256] = {
+
+#define JAVA_NOP 0
+#define ICMD_NOP 0
+ 1,
+#define JAVA_ACONST_NULL 1
+#define ICMD_ACONST 1 /* val.a = constant */
+ 1,
+#define JAVA_ICONST_M1 2
+#define ICMD_NULLCHECKPOP 2
+ 1,
+#define JAVA_ICONST_0 3
+#define ICMD_ICONST 3 /* val.i = constant */
+ 1,
+#define JAVA_ICONST_1 4
+#define ICMD_IREM0X10001 4
+ 1,
+#define JAVA_ICONST_2 5
+#define ICMD_IDIVPOW2 5 /* val.i = constant */
+ 1,
+#define JAVA_ICONST_3 6
+#define ICMD_LDIVPOW2 6 /* val.l = constant */
+ 1,
+#define JAVA_ICONST_4 7
+ 1,
+#define JAVA_ICONST_5 8
+#define ICMD_LREM0X10001 8
+ 1,
+#define JAVA_LCONST_0 9
+#define ICMD_LCONST 9 /* val.l = constant */
+ 1,
+#define JAVA_LCONST_1 10
+#define ICMD_LCMPCONST 10 /* val.l = constant */
+ 1,
+#define JAVA_FCONST_0 11
+#define ICMD_FCONST 11 /* val.f = constant */
+ 1,
+#define JAVA_FCONST_1 12
+ 1,
+#define JAVA_FCONST_2 13
+#define ICMD_ELSE_ICONST 13
+ 1,
+#define JAVA_DCONST_0 14
+#define ICMD_DCONST 14 /* val.d = constant */
+ 1,
+#define JAVA_DCONST_1 15
+#define ICMD_IFEQ_ICONST 15
+ 1,
+#define JAVA_BIPUSH 16
+#define ICMD_IFNE_ICONST 16
+ 2,
+#define JAVA_SIPUSH 17
+#define ICMD_IFLT_ICONST 17
+ 3,
+#define JAVA_LDC1 18
+#define ICMD_IFGE_ICONST 18
+ 2,
+#define JAVA_LDC2 19
+#define ICMD_IFGT_ICONST 19
+ 3,
+#define JAVA_LDC2W 20
+#define ICMD_IFLE_ICONST 20
+ 3,
+ /* order of LOAD instructions must be */
+ /* equal to order of TYPE_XXX defines */
+#define JAVA_ILOAD 21
+#define ICMD_ILOAD 21 /* op1 = local variable */
+ 2,
+#define JAVA_LLOAD 22
+#define ICMD_LLOAD 22 /* op1 = local variable */
+ 2,
+#define JAVA_FLOAD 23
+#define ICMD_FLOAD 23 /* op1 = local variable */
+ 2,
+#define JAVA_DLOAD 24
+#define ICMD_DLOAD 24 /* op1 = local variable */
+ 2,
+#define JAVA_ALOAD 25
+#define ICMD_ALOAD 25 /* op1 = local variable */
+ 2,
+#define JAVA_ILOAD_0 26
+#define ICMD_IADDCONST 26 /* val.i = constant */
+ 1,
+#define JAVA_ILOAD_1 27
+#define ICMD_ISUBCONST 27 /* val.i = constant */
+ 1,
+#define JAVA_ILOAD_2 28
+#define ICMD_IMULCONST 28 /* val.i = constant */
+ 1,
+#define JAVA_ILOAD_3 29
+#define ICMD_IANDCONST 29 /* val.i = constant */
+ 1,
+#define JAVA_LLOAD_0 30
+#define ICMD_IORCONST 30 /* val.i = constant */
+ 1,
+#define JAVA_LLOAD_1 31
+#define ICMD_IXORCONST 31 /* val.i = constant */
+ 1,
+#define JAVA_LLOAD_2 32
+#define ICMD_ISHLCONST 32 /* val.i = constant */
+ 1,
+#define JAVA_LLOAD_3 33
+#define ICMD_ISHRCONST 33 /* val.i = constant */
+ 1,
+#define JAVA_FLOAD_0 34
+#define ICMD_IUSHRCONST 34 /* val.i = constant */
+ 1,
+#define JAVA_FLOAD_1 35
+#define ICMD_IREMPOW2 35 /* val.i = constant */
+ 1,
+#define JAVA_FLOAD_2 36
+#define ICMD_LADDCONST 36 /* val.l = constant */
+ 1,
+#define JAVA_FLOAD_3 37
+#define ICMD_LSUBCONST 37 /* val.l = constant */
+ 1,
+#define JAVA_DLOAD_0 38
+#define ICMD_LMULCONST 38 /* val.l = constant */
+ 1,
+#define JAVA_DLOAD_1 39
+#define ICMD_LANDCONST 39 /* val.l = constant */
+ 1,
+#define JAVA_DLOAD_2 40
+#define ICMD_LORCONST 40 /* val.l = constant */
+ 1,
+#define JAVA_DLOAD_3 41
+#define ICMD_LXORCONST 41 /* val.l = constant */
+ 1,
+#define JAVA_ALOAD_0 42
+#define ICMD_LSHLCONST 42 /* val.l = constant */
+ 1,
+#define JAVA_ALOAD_1 43
+#define ICMD_LSHRCONST 43 /* val.l = constant */
+ 1,
+#define JAVA_ALOAD_2 44
+#define ICMD_LUSHRCONST 44 /* val.l = constant */
+ 1,
+#define JAVA_ALOAD_3 45
+#define ICMD_LREMPOW2 45 /* val.l = constant */
+ 1,
+#define JAVA_IALOAD 46
+#define ICMD_IALOAD 46
+ 1,
+#define JAVA_LALOAD 47
+#define ICMD_LALOAD 47
+ 1,
+#define JAVA_FALOAD 48
+#define ICMD_FALOAD 48
+ 1,
+#define JAVA_DALOAD 49
+#define ICMD_DALOAD 49
+ 1,
+#define JAVA_AALOAD 50
+#define ICMD_AALOAD 50
+ 1,
+#define JAVA_BALOAD 51
+#define ICMD_BALOAD 51
+ 1,
+#define JAVA_CALOAD 52
+#define ICMD_CALOAD 52
+ 1,
+#define JAVA_SALOAD 53
+#define ICMD_SALOAD 53
+ 1,
+ /* order of STORE instructions must be*/
+ /* equal to order of TYPE_XXX defines */
+#define JAVA_ISTORE 54
+#define ICMD_ISTORE 54 /* op1 = local variable */
+ 2,
+#define JAVA_LSTORE 55
+#define ICMD_LSTORE 55 /* op1 = local variable */
+ 2,
+#define JAVA_FSTORE 56
+#define ICMD_FSTORE 56 /* op1 = local variable */
+ 2,
+#define JAVA_DSTORE 57
+#define ICMD_DSTORE 57 /* op1 = local variable */
+ 2,
+#define JAVA_ASTORE 58
+#define ICMD_ASTORE 58 /* op1 = local variable */
+ 2,
+#define JAVA_ISTORE_0 59
+#define ICMD_IF_LEQ 59 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_ISTORE_1 60
+#define ICMD_IF_LNE 60 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_ISTORE_2 61
+#define ICMD_IF_LLT 61 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_ISTORE_3 62
+#define ICMD_IF_LGE 62 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_LSTORE_0 63
+#define ICMD_IF_LGT 63 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_LSTORE_1 64
+#define ICMD_IF_LLE 64 /* op1 = target JavaVM pc, val.l */
+ 1,
+#define JAVA_LSTORE_2 65
+#define ICMD_IF_LCMPEQ 65 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_LSTORE_3 66
+#define ICMD_IF_LCMPNE 66 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_FSTORE_0 67
+#define ICMD_IF_LCMPLT 67 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_FSTORE_1 68
+#define ICMD_IF_LCMPGE 68 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_FSTORE_2 69
+#define ICMD_IF_LCMPGT 69 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_FSTORE_3 70
+#define ICMD_IF_LCMPLE 70 /* op1 = target JavaVM pc */
+ 1,
+#define JAVA_DSTORE_0 71
+ 1,
+#define JAVA_DSTORE_1 72
+ 1,
+#define JAVA_DSTORE_2 73
+ 1,
+#define JAVA_DSTORE_3 74
+ 1,
+#define JAVA_ASTORE_0 75
+ 1,
+#define JAVA_ASTORE_1 76
+ 1,
+#define JAVA_ASTORE_2 77
+ 1,
+#define JAVA_ASTORE_3 78
+ 1,
+#define JAVA_IASTORE 79
+#define ICMD_IASTORE 79
+ 1,
+#define JAVA_LASTORE 80
+#define ICMD_LASTORE 80
+ 1,
+#define JAVA_FASTORE 81
+#define ICMD_FASTORE 81
+ 1,
+#define JAVA_DASTORE 82
+#define ICMD_DASTORE 82
+ 1,
+#define JAVA_AASTORE 83
+#define ICMD_AASTORE 83
+ 1,
+#define JAVA_BASTORE 84
+#define ICMD_BASTORE 84
+ 1,
+#define JAVA_CASTORE 85
+#define ICMD_CASTORE 85
+ 1,
+#define JAVA_SASTORE 86
+#define ICMD_SASTORE 86
+ 1,
+#define JAVA_POP 87
+#define ICMD_POP 87
+ 1,
+#define JAVA_POP2 88
+#define ICMD_POP2 88
+ 1,
+#define JAVA_DUP 89
+#define ICMD_DUP 89
+ 1,
+#define JAVA_DUP_X1 90
+#define ICMD_DUP_X1 90
+ 1,
+#define JAVA_DUP_X2 91
+#define ICMD_DUP_X2 91
+ 1,
+#define JAVA_DUP2 92
+#define ICMD_DUP2 92
+ 1,
+#define JAVA_DUP2_X1 93
+#define ICMD_DUP2_X1 93
+ 1,
+#define JAVA_DUP2_X2 94
+#define ICMD_DUP2_X2 94
+ 1,
+#define JAVA_SWAP 95
+#define ICMD_SWAP 95
+ 1,
+#define JAVA_IADD 96
+#define ICMD_IADD 96
+ 1,
+#define JAVA_LADD 97
+#define ICMD_LADD 97
+ 1,
+#define JAVA_FADD 98
+#define ICMD_FADD 98
+ 1,
+#define JAVA_DADD 99
+#define ICMD_DADD 99
+ 1,
+#define JAVA_ISUB 100
+#define ICMD_ISUB 100
+ 1,
+#define JAVA_LSUB 101
+#define ICMD_LSUB 101
+ 1,
+#define JAVA_FSUB 102
+#define ICMD_FSUB 102
+ 1,
+#define JAVA_DSUB 103
+#define ICMD_DSUB 103
+ 1,
+#define JAVA_IMUL 104
+#define ICMD_IMUL 104
+ 1,
+#define JAVA_LMUL 105
+#define ICMD_LMUL 105
+ 1,
+#define JAVA_FMUL 106
+#define ICMD_FMUL 106
+ 1,
+#define JAVA_DMUL 107
+#define ICMD_DMUL 107
+ 1,
+#define JAVA_IDIV 108
+#define ICMD_IDIV 108
+ 1,
+#define JAVA_LDIV 109
+#define ICMD_LDIV 109
+ 1,
+#define JAVA_FDIV 110
+#define ICMD_FDIV 110
+ 1,
+#define JAVA_DDIV 111
+#define ICMD_DDIV 111
+ 1,
+#define JAVA_IREM 112
+#define ICMD_IREM 112
+ 1,
+#define JAVA_LREM 113
+#define ICMD_LREM 113
+ 1,
+#define JAVA_FREM 114
+#define ICMD_FREM 114
+ 1,
+#define JAVA_DREM 115
+#define ICMD_DREM 115
+ 1,
+#define JAVA_INEG 116
+#define ICMD_INEG 116
+ 1,
+#define JAVA_LNEG 117
+#define ICMD_LNEG 117
+ 1,
+#define JAVA_FNEG 118
+#define ICMD_FNEG 118
+ 1,
+#define JAVA_DNEG 119
+#define ICMD_DNEG 119
+ 1,
+#define JAVA_ISHL 120
+#define ICMD_ISHL 120
+ 1,
+#define JAVA_LSHL 121
+#define ICMD_LSHL 121
+ 1,
+#define JAVA_ISHR 122
+#define ICMD_ISHR 122
+ 1,
+#define JAVA_LSHR 123
+#define ICMD_LSHR 123
+ 1,
+#define JAVA_IUSHR 124
+#define ICMD_IUSHR 124
+ 1,
+#define JAVA_LUSHR 125
+#define ICMD_LUSHR 125
+ 1,
+#define JAVA_IAND 126
+#define ICMD_IAND 126
+ 1,
+#define JAVA_LAND 127
+#define ICMD_LAND 127
+ 1,
+#define JAVA_IOR 128
+#define ICMD_IOR 128
+ 1,
+#define JAVA_LOR 129
+#define ICMD_LOR 129
+ 1,
+#define JAVA_IXOR 130
+#define ICMD_IXOR 130
+ 1,
+#define JAVA_LXOR 131
+#define ICMD_LXOR 131
+ 1,
+#define JAVA_IINC 132
+#define ICMD_IINC 132 /* op1 = local variable, val.i = constant */
+ 3,
+#define JAVA_I2L 133
+#define ICMD_I2L 133
+ 1,
+#define JAVA_I2F 134
+#define ICMD_I2F 134
+ 1,
+#define JAVA_I2D 135
+#define ICMD_I2D 135
+ 1,
+#define JAVA_L2I 136
+#define ICMD_L2I 136
+ 1,
+#define JAVA_L2F 137
+#define ICMD_L2F 137
+ 1,
+#define JAVA_L2D 138
+#define ICMD_L2D 138
+ 1,
+#define JAVA_F2I 139
+#define ICMD_F2I 139
+ 1,
+#define JAVA_F2L 140
+#define ICMD_F2L 140
+ 1,
+#define JAVA_F2D 141
+#define ICMD_F2D 141
+ 1,
+#define JAVA_D2I 142
+#define ICMD_D2I 142
+ 1,
+#define JAVA_D2L 143
+#define ICMD_D2L 143
+ 1,
+#define JAVA_D2F 144
+#define ICMD_D2F 144
+ 1,
+#define JAVA_INT2BYTE 145
+#define ICMD_INT2BYTE 145
+ 1,
+#define JAVA_INT2CHAR 146
+#define ICMD_INT2CHAR 146
+ 1,
+#define JAVA_INT2SHORT 147
+#define ICMD_INT2SHORT 147
+ 1,
+#define JAVA_LCMP 148
+#define ICMD_LCMP 148
+ 1,
+#define JAVA_FCMPL 149
+#define ICMD_FCMPL 149
+ 1,
+#define JAVA_FCMPG 150
+#define ICMD_FCMPG 150
+ 1,
+#define JAVA_DCMPL 151
+#define ICMD_DCMPL 151
+ 1,
+#define JAVA_DCMPG 152
+#define ICMD_DCMPG 152
+ 1,
+#define JAVA_IFEQ 153
+#define ICMD_IFEQ 153 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IFNE 154
+#define ICMD_IFNE 154 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IFLT 155
+#define ICMD_IFLT 155 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IFGE 156
+#define ICMD_IFGE 156 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IFGT 157
+#define ICMD_IFGT 157 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IFLE 158
+#define ICMD_IFLE 158 /* op1 = target JavaVM pc, val.i */
+ 3,
+#define JAVA_IF_ICMPEQ 159
+#define ICMD_IF_ICMPEQ 159 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ICMPNE 160
+#define ICMD_IF_ICMPNE 160 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ICMPLT 161
+#define ICMD_IF_ICMPLT 161 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ICMPGE 162
+#define ICMD_IF_ICMPGE 162 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ICMPGT 163
+#define ICMD_IF_ICMPGT 163 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ICMPLE 164
+#define ICMD_IF_ICMPLE 164 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ACMPEQ 165
+#define ICMD_IF_ACMPEQ 165 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IF_ACMPNE 166
+#define ICMD_IF_ACMPNE 166 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_GOTO 167
+#define ICMD_GOTO 167 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_JSR 168
+#define ICMD_JSR 168 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_RET 169
+#define ICMD_RET 169 /* op1 = local variable */
+ 2,
+#define JAVA_TABLESWITCH 170
+#define ICMD_TABLESWITCH 170 /* val.a = pointer to s4 table */
+ 0, /* length must be computed */
+#define JAVA_LOOKUPSWITCH 171
+#define ICMD_LOOKUPSWITCH 171 /* val.a = pointer to s4 table */
+ 0, /* length must be computed */
+#define JAVA_IRETURN 172
+#define ICMD_IRETURN 172
+ 1,
+#define JAVA_LRETURN 173
+#define ICMD_LRETURN 173
+ 1,
+#define JAVA_FRETURN 174
+#define ICMD_FRETURN 174
+ 1,
+#define JAVA_DRETURN 175
+#define ICMD_DRETURN 175
+ 1,
+#define JAVA_ARETURN 176
+#define ICMD_ARETURN 176
+ 1,
+#define JAVA_RETURN 177
+#define ICMD_RETURN 177
+ 1,
+#define JAVA_GETSTATIC 178
+#define ICMD_GETSTATIC 178 /* op1 = type, val.a = field address */
+ 3,
+#define JAVA_PUTSTATIC 179
+#define ICMD_PUTSTATIC 179 /* op1 = type, val.a = field address */
+ 3,
+#define JAVA_GETFIELD 180
+#define ICMD_GETFIELD 180 /* op1 = type, val.i = field offset */
+ 3,
+#define JAVA_PUTFIELD 181
+#define ICMD_PUTFIELD 181 /* op1 = type, val.i = field offset */
+ 3,
+#define JAVA_INVOKEVIRTUAL 182
+#define ICMD_INVOKEVIRTUAL 182 /* val.a = method info pointer */
+ 3,
+#define JAVA_INVOKESPECIAL 183
+#define ICMD_INVOKESPECIAL 183 /* val.a = method info pointer */
+ 3,
+#define JAVA_INVOKESTATIC 184
+#define ICMD_INVOKESTATIC 184 /* val.a = method info pointer */
+ 3,
+#define JAVA_INVOKEINTERFACE 185
+#define ICMD_INVOKEINTERFACE 185 /* val.a = method info pointer */
+ 5,
+#define ICMD_CHECKASIZE 186 /* */
+ 1, /* unused */
+#define JAVA_NEW 187
+#define ICMD_NEW 187 /* op1 = 1, val.a = class pointer */
+ 3,
+#define JAVA_NEWARRAY 188
+#define ICMD_NEWARRAY 188 /* op1 = basic type */
+ 2,
+#define JAVA_ANEWARRAY 189
+#define ICMD_ANEWARRAY 189 /* op1 = 0, val.a = array pointer */
+ 3, /* op1 = 1, val.a = class pointer */
+#define JAVA_ARRAYLENGTH 190
+#define ICMD_ARRAYLENGTH 190
+ 1,
+#define JAVA_ATHROW 191
+#define ICMD_ATHROW 191
+ 1,
+#define JAVA_CHECKCAST 192
+#define ICMD_CHECKCAST 192 /* op1 = 0, val.a = array pointer */
+ 3, /* op1 = 1, val.a = class pointer */
+#define JAVA_INSTANCEOF 193
+#define ICMD_INSTANCEOF 193 /* op1 = 0, val.a = array pointer */
+ 3, /* op1 = 1, val.a = class pointer */
+#define JAVA_MONITORENTER 194
+#define ICMD_MONITORENTER 194
+ 1,
+#define JAVA_MONITOREXIT 195
+#define ICMD_MONITOREXIT 195
+ 1,
+#define JAVA_WIDE 196
+ 0, /* length must be computed */
+#define JAVA_MULTIANEWARRAY 197
+#define ICMD_MULTIANEWARRAY 197 /* op1 = dimension, val.a = array */
+ 4, /* pointer */
+#define JAVA_IFNULL 198
+#define ICMD_IFNULL 198 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_IFNONNULL 199
+#define ICMD_IFNONNULL 199 /* op1 = target JavaVM pc */
+ 3,
+#define JAVA_GOTO_W 200
+ 5,
+#define JAVA_JSR_W 201
+ 5,
+#define JAVA_BREAKPOINT 202
+ 1,
+
+ 1,1,1,1,1,1,1,1, /* unused */
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1
+ };
+
+#define ICMD_BUILTIN3 253 /* internal opcode */
+#define ICMD_BUILTIN2 254 /* internal opcode */
+#define ICMD_BUILTIN1 255 /* internal opcode */
+
+
+/******************* description of JavaVM instructions ***********************/
+
+typedef struct {
+ u1 opcode;
+ u1 type_s1;
+ u1 type_s2;
+ u1 type_d;
+ functionptr builtin;
+ bool supported;
+ bool isfloat;
+} stdopdescriptor;
+
+static stdopdescriptor *stdopdescriptors[256];
+
+static stdopdescriptor stdopdescriptortable[] = {
+ { JAVA_IADD, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_ISUB, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_IMUL, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_ISHL, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_ISHR, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_IUSHR, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_IAND, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_IOR, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_IXOR, TYPE_INT, TYPE_INT, TYPE_INT, NULL, true, false },
+ { JAVA_INEG, TYPE_INT, TYPE_VOID,TYPE_INT, NULL, true, false },
+
+ { JAVA_LADD, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_ladd , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+ { JAVA_LSUB, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_lsub , SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+ { JAVA_LMUL, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_lmul , SUPPORT_LONG && SUPPORT_LONG_MULDIV, false },
+ { JAVA_LSHL, TYPE_LONG, TYPE_INT, TYPE_LONG,
+ (functionptr) builtin_lshl , SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+ { JAVA_LSHR, TYPE_LONG, TYPE_INT, TYPE_LONG,
+ (functionptr) builtin_lshr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+ { JAVA_LUSHR, TYPE_LONG, TYPE_INT, TYPE_LONG,
+ (functionptr) builtin_lushr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false },
+ { JAVA_LAND, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_land, SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+ { JAVA_LOR, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_lor , SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+ { JAVA_LXOR, TYPE_LONG, TYPE_LONG, TYPE_LONG,
+ (functionptr) builtin_lxor, SUPPORT_LONG && SUPPORT_LONG_LOG, false },
+ { JAVA_LNEG, TYPE_LONG, TYPE_VOID, TYPE_LONG,
+ (functionptr) builtin_lneg, SUPPORT_LONG && SUPPORT_LONG_ADD, false },
+ { JAVA_LCMP, TYPE_LONG, TYPE_LONG, TYPE_INT,
+ (functionptr) builtin_lcmp, SUPPORT_LONG && SUPPORT_LONG_CMP, false },
+
+ { JAVA_FADD, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT,
+ (functionptr) builtin_fadd, SUPPORT_FLOAT, true },
+ { JAVA_FSUB, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT,
+ (functionptr) builtin_fsub, SUPPORT_FLOAT, true },
+ { JAVA_FMUL, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT,
+ (functionptr) builtin_fmul, SUPPORT_FLOAT, true },
+ { JAVA_FDIV, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT,
+ (functionptr) builtin_fdiv, SUPPORT_FLOAT, true },
+ { JAVA_FREM, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT,
+ (functionptr) builtin_frem, SUPPORT_FLOAT, true },
+ { JAVA_FNEG, TYPE_FLOAT, TYPE_VOID, TYPE_FLOAT,
+ (functionptr) builtin_fneg, SUPPORT_FLOAT, true },
+ { JAVA_FCMPL, TYPE_FLOAT, TYPE_FLOAT, TYPE_INT,
+ (functionptr) builtin_fcmpl, SUPPORT_FLOAT, true },
+ { JAVA_FCMPG, TYPE_FLOAT, TYPE_FLOAT, TYPE_INT,
+ (functionptr) builtin_fcmpg, SUPPORT_FLOAT, true },
+
+ { JAVA_DADD, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE,
+ (functionptr) builtin_dadd, SUPPORT_DOUBLE, true },
+ { JAVA_DSUB, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE,
+ (functionptr) builtin_dsub, SUPPORT_DOUBLE, true },
+ { JAVA_DMUL, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE,
+ (functionptr) builtin_dmul, SUPPORT_DOUBLE, true },
+ { JAVA_DDIV, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE,
+ (functionptr) builtin_ddiv, SUPPORT_DOUBLE, true },
+ { JAVA_DREM, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE,
+ (functionptr) builtin_drem, SUPPORT_DOUBLE, true },
+ { JAVA_DNEG, TYPE_DOUBLE, TYPE_VOID, TYPE_DOUBLE,
+ (functionptr) builtin_dneg, SUPPORT_DOUBLE, true },
+ { JAVA_DCMPL, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_INT,
+ (functionptr) builtin_dcmpl, SUPPORT_DOUBLE, true },
+ { JAVA_DCMPG, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_INT,
+ (functionptr) builtin_dcmpg, SUPPORT_DOUBLE, true },
+
+ { JAVA_INT2BYTE, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+ { JAVA_INT2CHAR, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+ { JAVA_INT2SHORT, TYPE_INT, TYPE_VOID, TYPE_INT, NULL, true,false },
+ { JAVA_I2L, TYPE_INT, TYPE_VOID, TYPE_LONG,
+ (functionptr) builtin_i2l, SUPPORT_LONG && SUPPORT_LONG_ICVT, false },
+ { JAVA_I2F, TYPE_INT, TYPE_VOID, TYPE_FLOAT,
+ (functionptr) builtin_i2f, SUPPORT_FLOAT, true },
+ { JAVA_I2D, TYPE_INT, TYPE_VOID, TYPE_DOUBLE,
+ (functionptr) builtin_i2d, SUPPORT_DOUBLE, true },
+ { JAVA_L2I, TYPE_LONG, TYPE_VOID, TYPE_INT,
+ (functionptr) builtin_l2i, SUPPORT_LONG && SUPPORT_LONG_ICVT, false },
+ { JAVA_L2F, TYPE_LONG, TYPE_VOID, TYPE_FLOAT,
+ (functionptr) builtin_l2f, SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT, true },
+ { JAVA_L2D, TYPE_LONG, TYPE_VOID, TYPE_DOUBLE,
+ (functionptr) builtin_l2d, SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT, true },
+ { JAVA_F2I, TYPE_FLOAT, TYPE_VOID, TYPE_INT,
+ (functionptr) builtin_f2i, SUPPORT_FLOAT, true },
+ { JAVA_F2L, TYPE_FLOAT, TYPE_VOID, TYPE_LONG,
+ (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+ { JAVA_F2D, TYPE_FLOAT, TYPE_VOID, TYPE_DOUBLE,
+ (functionptr) builtin_f2d, SUPPORT_FLOAT && SUPPORT_DOUBLE, true },
+ { JAVA_D2I, TYPE_DOUBLE, TYPE_VOID, TYPE_INT,
+ (functionptr) builtin_d2i, SUPPORT_DOUBLE, true },
+ { JAVA_D2L, TYPE_DOUBLE, TYPE_VOID, TYPE_LONG,
+ (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_FCVT, true },
+ { JAVA_D2F, TYPE_DOUBLE, TYPE_VOID, TYPE_FLOAT,
+ (functionptr) builtin_d2f, SUPPORT_DOUBLE && SUPPORT_FLOAT, true },
+
+};
+
+static char *icmd_names[256] = {
+ "NOP ", /* 0 */
+ "ACONST ", /* 1 */
+ "NULLCHECKPOP ", /* ICONST_M1 2 */
+ "ICONST ", /* 3 */
+ "IREM0X10001 ", /* ICONST_1 4 */
+ "IDIVPOW2 ", /* ICONST_2 5 */
+ "LDIVPOW2 ", /* ICONST_3 6 */
+ "UNDEF__7 ", /* ICONST_4 7 */
+ "LREM0X10001 ", /* ICONST_5 8 */
+ "LCONST ", /* 9 */
+ "LCMPCONST ", /* LCONST_1 10 */
+ "FCONST ", /* 11 */
+ "UNDEF_12 ", /* FCONST_1 12 */
+ "ELSE_ICONST ", /* FCONST_2 13 */
+ "DCONST ", /* 14 */
+ "IFEQ_ICONST ", /* DCONST_1 15 */
+ "IFNE_ICONST ", /* BIPUSH 16 */
+ "IFLT_ICONST ", /* SIPUSH 17 */
+ "IFGE_ICONST ", /* LDC1 18 */
+ "IFGT_ICONST ", /* LDC2 19 */
+ "IFLE_ICONST ", /* LDC2W 20 */
+ "ILOAD ", /* 21 */
+ "LLOAD ", /* 22 */
+ "FLOAD ", /* 23 */
+ "DLOAD ", /* 24 */
+ "ALOAD ", /* 25 */
+ "IADDCONST ", /* ILOAD_0 26 */
+ "ISUBCONST ", /* ILOAD_1 27 */
+ "IMULCONST ", /* ILOAD_2 28 */
+ "IANDCONST ", /* ILOAD_3 29 */
+ "IORCONST ", /* LLOAD_0 30 */
+ "IXORCONST ", /* LLOAD_1 31 */
+ "ISHLCONST ", /* LLOAD_2 32 */
+ "ISHRCONST ", /* LLOAD_3 33 */
+ "IUSHRCONST ", /* FLOAD_0 34 */
+ "IREMPOW2 ", /* FLOAD_1 35 */
+ "LADDCONST ", /* FLOAD_2 36 */
+ "LSUBCONST ", /* FLOAD_3 37 */
+ "LMULCONST ", /* DLOAD_0 38 */
+ "LANDCONST ", /* DLOAD_1 39 */
+ "LORCONST ", /* DLOAD_2 40 */
+ "LXORCONST ", /* DLOAD_3 41 */
+ "LSHLCONST ", /* ALOAD_0 42 */
+ "LSHRCONST ", /* ALOAD_1 43 */
+ "LUSHRCONST ", /* ALOAD_2 44 */
+ "LREMPOW2 ", /* ALOAD_3 45 */
+ "IALOAD ", /* 46 */
+ "LALOAD ", /* 47 */
+ "FALOAD ", /* 48 */
+ "DALOAD ", /* 49 */
+ "AALOAD ", /* 50 */
+ "BALOAD ", /* 51 */
+ "CALOAD ", /* 52 */
+ "SALOAD ", /* 53 */
+ "ISTORE ", /* 54 */
+ "LSTORE ", /* 55 */
+ "FSTORE ", /* 56 */
+ "DSTORE ", /* 57 */
+ "ASTORE ", /* 58 */
+ "IF_LEQ ", /* ISTORE_0 59 */
+ "IF_LNE ", /* ISTORE_1 60 */
+ "IF_LLT ", /* ISTORE_2 61 */
+ "IF_LGE ", /* ISTORE_3 62 */
+ "IF_LGT ", /* LSTORE_0 63 */
+ "IF_LLE ", /* LSTORE_1 64 */
+ "IF_LCMPEQ ", /* LSTORE_2 65 */
+ "IF_LCMPNE ", /* LSTORE_3 66 */
+ "IF_LCMPLT ", /* FSTORE_0 67 */
+ "IF_LCMPGE ", /* FSTORE_1 68 */
+ "IF_LCMPGT ", /* FSTORE_2 69 */
+ "IF_LCMPLE ", /* FSTORE_3 70 */
+ "UNDEF_71 ", /* DSTORE_0 71 */
+ "UNDEF_72 ", /* DSTORE_1 72 */
+ "UNDEF_73 ", /* DSTORE_2 73 */
+ "UNDEF_74 ", /* DSTORE_3 74 */
+ "UNDEF_75 ", /* ASTORE_0 75 */
+ "UNDEF_76 ", /* ASTORE_1 76 */
+ "UNDEF_77 ", /* ASTORE_2 77 */
+ "UNDEF_78 ", /* ASTORE_3 78 */
+ "IASTORE ", /* 79 */
+ "LASTORE ", /* 80 */
+ "FASTORE ", /* 81 */
+ "DASTORE ", /* 82 */
+ "AASTORE ", /* 83 */
+ "BASTORE ", /* 84 */
+ "CASTORE ", /* 85 */
+ "SASTORE ", /* 86 */
+ "POP ", /* 87 */
+ "POP2 ", /* 88 */
+ "DUP ", /* 89 */
+ "DUP_X1 ", /* 90 */
+ "DUP_X2 ", /* 91 */
+ "DUP2 ", /* 92 */
+ "DUP2_X1 ", /* 93 */
+ "DUP2_X2 ", /* 94 */
+ "SWAP ", /* 95 */
+ "IADD ", /* 96 */
+ "LADD ", /* 97 */
+ "FADD ", /* 98 */
+ "DADD ", /* 99 */
+ "ISUB ", /* 100 */
+ "LSUB ", /* 101 */
+ "FSUB ", /* 102 */
+ "DSUB ", /* 103 */
+ "IMUL ", /* 104 */
+ "LMUL ", /* 105 */
+ "FMUL ", /* 106 */
+ "DMUL ", /* 107 */
+ "IDIV ", /* 108 */
+ "LDIV ", /* 109 */
+ "FDIV ", /* 110 */
+ "DDIV ", /* 111 */
+ "IREM ", /* 112 */
+ "LREM ", /* 113 */
+ "FREM ", /* 114 */
+ "DREM ", /* 115 */
+ "INEG ", /* 116 */
+ "LNEG ", /* 117 */
+ "FNEG ", /* 118 */
+ "DNEG ", /* 119 */
+ "ISHL ", /* 120 */
+ "LSHL ", /* 121 */
+ "ISHR ", /* 122 */
+ "LSHR ", /* 123 */
+ "IUSHR ", /* 124 */
+ "LUSHR ", /* 125 */
+ "IAND ", /* 126 */
+ "LAND ", /* 127 */
+ "IOR ", /* 128 */
+ "LOR ", /* 129 */
+ "IXOR ", /* 130 */
+ "LXOR ", /* 131 */
+ "IINC ", /* 132 */
+ "I2L ", /* 133 */
+ "I2F ", /* 134 */
+ "I2D ", /* 135 */
+ "L2I ", /* 136 */
+ "L2F ", /* 137 */
+ "L2D ", /* 138 */
+ "F2I ", /* 139 */
+ "F2L ", /* 140 */
+ "F2D ", /* 141 */
+ "D2I ", /* 142 */
+ "D2L ", /* 143 */
+ "D2F ", /* 144 */
+ "INT2BYTE ", /* 145 */
+ "INT2CHAR ", /* 146 */
+ "INT2SHORT ", /* 147 */
+ "LCMP ", /* 148 */
+ "FCMPL ", /* 149 */
+ "FCMPG ", /* 150 */
+ "DCMPL ", /* 151 */
+ "DCMPG ", /* 152 */
+ "IFEQ ", /* 153 */
+ "IFNE ", /* 154 */
+ "IFLT ", /* 155 */
+ "IFGE ", /* 156 */
+ "IFGT ", /* 157 */
+ "IFLE ", /* 158 */
+ "IF_ICMPEQ ", /* 159 */
+ "IF_ICMPNE ", /* 160 */
+ "IF_ICMPLT ", /* 161 */
+ "IF_ICMPGE ", /* 162 */
+ "IF_ICMPGT ", /* 163 */
+ "IF_ICMPLE ", /* 164 */
+ "IF_ACMPEQ ", /* 165 */
+ "IF_ACMPNE ", /* 166 */
+ "GOTO ", /* 167 */
+ "JSR ", /* 168 */
+ "RET ", /* 169 */
+ "TABLESWITCH ", /* 170 */
+ "LOOKUPSWITCH ", /* 171 */
+ "IRETURN ", /* 172 */
+ "LRETURN ", /* 173 */
+ "FRETURN ", /* 174 */
+ "DRETURN ", /* 175 */
+ "ARETURN ", /* 176 */
+ "RETURN ", /* 177 */
+ "GETSTATIC ", /* 178 */
+ "PUTSTATIC ", /* 179 */
+ "GETFIELD ", /* 180 */
+ "PUTFIELD ", /* 181 */
+ "INVOKEVIRTUAL", /* 182 */
+ "INVOKESPECIAL", /* 183 */
+ "INVOKESTATIC ", /* 184 */
+ "INVOKEINTERFACE",/* 185 */
+ "CHECKASIZE ", /* UNDEF186 186 */
+ "NEW ", /* 187 */
+ "NEWARRAY ", /* 188 */
+ "ANEWARRAY ", /* 189 */
+ "ARRAYLENGTH ", /* 190 */
+ "ATHROW ", /* 191 */
+ "CHECKCAST ", /* 192 */
+ "INSTANCEOF ", /* 193 */
+ "MONITORENTER ", /* 194 */
+ "MONITOREXIT ", /* 195 */
+ "UNDEF196 ", /* WIDE 196 */
+ "MULTIANEWARRAY",/* 197 */
+ "IFNULL ", /* 198 */
+ "IFNONNULL ", /* 199 */
+ "UNDEF200 ", /* GOTO_W 200 */
+ "UNDEF201 ", /* JSR_W 201 */
+ "UNDEF202 ", /* BREAKPOINT 202 */
+
+ "UNDEF203","UNDEF204","UNDEF205",
+ "UNDEF206","UNDEF207","UNDEF208","UNDEF209","UNDEF210",
+ "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+ "UNDEF216","UNDEF217","UNDEF218","UNDEF219","UNDEF220",
+ "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+ "UNDEF226","UNDEF227","UNDEF228","UNDEF229","UNDEF230",
+ "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+ "UNDEF236","UNDEF237","UNDEF238","UNDEF239","UNDEF240",
+ "UNDEF","UNDEF","UNDEF","UNDEF","UNDEF",
+ "UNDEF246","UNDEF247","UNDEF248","UNDEF249","UNDEF250",
+ "UNDEF251","UNDEF252",
+ "BUILTIN3 ", /* 253 */
+ "BUILTIN2 ", /* 254 */
+ "BUILTIN1 " /* 255 */
+ };
+
+
+
+/***************************** register types *********************************/
+
+#define REG_RES 0 /* reserved register for OS or code generator */
+#define REG_RET 1 /* return value register */
+#define REG_EXC 2 /* exception value register */
+#define REG_SAV 3 /* (callee) saved register */
+#define REG_TMP 4 /* scratch temporary register (caller saved) */
+#define REG_ARG 5 /* argument register (caller saved) */
+
+#define REG_END -1 /* last entry in tables */
+
+#define PARAMMODE_NUMBERED 0
+#define PARAMMODE_STUFFED 1
+
+/***************************** register info block ****************************/
+
+extern int nregdescint[]; /* description of integer registers */
+extern int nregdescfloat[]; /* description of floating point registers */
+
+extern int nreg_parammode;
+
+void asm_handle_exception();
+void asm_handle_nat_exception();
+
+static void disassinstr (int c, int pos); /* disassemble an instruction */
+static void disassemble (int *code, int len); /* disassemble a code block */
--- /dev/null
+/***************************** comp/mcode.c ************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ This file is an include file for "compiler.c" . It contains (mostly)
+ architecture independent functions for writing instructions into the
+ code area and constants into the data area.
+
+ Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
+ Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+ Changes: Micheal Gschwind EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1998/08/10
+
+
+ All functions assume the following code area / data area layout:
+
+ +-----------+
+ | |
+ | code area | code area grows to higher addresses
+ | |
+ +-----------+ <-- start of procedure
+ | |
+ | data area | data area grows to lower addresses
+ | |
+ +-----------+
+
+ The functions first write into a temporary code/data area allocated by
+ "mcode_init". "mcode_finish" copies the code and data area into permanent
+ memory. All functions writing values into the data area return the offset
+ relative the begin of the code area (start of procedure).
+
+*******************************************************************************/
+
+#define MCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
+#define DSEGINITSIZE (1<<12) /* 4 Kbyte data area initialization size */
+
+static u1* mcodebase = NULL; /* base pointer of code area */
+static s4* mcodeend = NULL; /* pointer to end of code area */
+static int mcodesize; /* complete size of code area (bytes) */
+
+static u1* dsegtop = NULL; /* pointer to top (end) of data area */
+static int dsegsize; /* complete size of data area (bytes) */
+static int dseglen; /* used size of data area (bytes) */
+ /* data area grows from top to bottom */
+
+static jumpref *jumpreferences; /* list of jumptable target addresses */
+static branchref *xboundrefs; /* list of bound check branches */
+static branchref *xcheckarefs; /* list of array size check branches */
+static branchref *xnullrefs; /* list of null check branches */
+static branchref *xcastrefs; /* list of cast check branches */
+
+static void mcode_init(); /* allocates code and data area */
+static void mcode_close(); /* releases temporary storage */
+static void mcode_finish(); /* makes code and data area permanent and */
+ /* updates branch references to code/data */
+
+static s4 dseg_adds4(s4 value); /* adds an int to data area */
+static s4 dseg_adds8(s8 value); /* adds an long to data area */
+static s4 dseg_addfloat (float value); /* adds an float to data area */
+static s4 dseg_adddouble(double value); /* adds an double to data area */
+
+#if POINTERSIZE==8
+#define dseg_addaddress(value) dseg_adds8((s8)(value))
+#else
+#define dseg_addaddress(value) dseg_adds4((s4)(value))
+#endif
+
+static void dseg_addtarget(basicblock *target);
+static void mcode_addreference(basicblock *target, void *branchptr);
+static void mcode_addxboundrefs(void *branchptr);
+static void mcode_addxnullrefs(void *branchptr);
+static void mcode_addxcastrefs(void *branchptr);
+
+static void dseg_display(s4 *s4ptr);
+
+/* mcode_init allocates and initialises code area, data area and references */
+
+static void mcode_init()
+{
+ if (!mcodebase) {
+ mcodebase = MNEW (u1, MCODEINITSIZE);
+ mcodesize = MCODEINITSIZE;
+ }
+
+ if (!dsegtop) {
+ dsegtop = MNEW (u1, DSEGINITSIZE);
+ dsegsize = DSEGINITSIZE;
+ dsegtop += dsegsize;
+ }
+
+ dseglen = 0;
+
+ jumpreferences = NULL;
+ xboundrefs = NULL;
+ xnullrefs = NULL;
+ xcastrefs = NULL;
+}
+
+
+/* mcode_close releases temporary code and data area */
+
+static void mcode_close()
+{
+ if (mcodebase) {
+ MFREE (mcodebase, u1, mcodesize);
+ mcodebase = NULL;
+ }
+ if (dsegtop) {
+ MFREE (dsegtop - dsegsize, u1, dsegsize);
+ dsegtop = NULL;
+ }
+}
+
+
+/* mcode_increase doubles code area */
+
+static s4 *mcode_increase(u1 *codeptr)
+{
+ long len;
+
+ len = codeptr - mcodebase;
+ mcodebase = MREALLOC(mcodebase, u1, mcodesize, mcodesize * 2);
+ mcodesize *= 2;
+ mcodeend = (s4*) (mcodebase + mcodesize);
+ return (s4*) (mcodebase + len);
+}
+
+
+/* desg_increase doubles data area */
+
+static void dseg_increase() {
+ u1 *newstorage = MNEW (u1, dsegsize * 2);
+ memcpy ( newstorage + dsegsize, dsegtop - dsegsize, dsegsize);
+ MFREE (dsegtop - dsegsize, u1, dsegsize);
+ dsegtop = newstorage;
+ dsegsize *= 2;
+ dsegtop += dsegsize;
+}
+
+
+static s4 dseg_adds4_increase(s4 value)
+{
+ dseg_increase();
+ *((s4 *) (dsegtop - dseglen)) = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_adds4(s4 value)
+{
+ s4 *dataptr;
+
+ dseglen += 4;
+ dataptr = (s4 *) (dsegtop - dseglen);
+ if (dseglen > dsegsize)
+ return dseg_adds4_increase(value);
+ *dataptr = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_adds8_increase(s8 value)
+{
+ dseg_increase();
+ *((s8 *) (dsegtop - dseglen)) = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_adds8(s8 value)
+{
+ s8 *dataptr;
+
+ dseglen = ALIGN (dseglen + 8, 8);
+ dataptr = (s8 *) (dsegtop - dseglen);
+ if (dseglen > dsegsize)
+ return dseg_adds8_increase(value);
+ *dataptr = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_addfloat_increase(float value)
+{
+ dseg_increase();
+ *((float *) (dsegtop - dseglen)) = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_addfloat(float value)
+{
+ float *dataptr;
+
+ dseglen += 4;
+ dataptr = (float *) (dsegtop - dseglen);
+ if (dseglen > dsegsize)
+ return dseg_addfloat_increase(value);
+ *dataptr = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_adddouble_increase(double value)
+{
+ dseg_increase();
+ *((double *) (dsegtop - dseglen)) = value;
+ return -dseglen;
+}
+
+
+static s4 dseg_adddouble(double value)
+{
+ double *dataptr;
+
+ dseglen = ALIGN (dseglen + 8, 8);
+ dataptr = (double *) (dsegtop - dseglen);
+ if (dseglen > dsegsize)
+ return dseg_adddouble_increase(value);
+ *dataptr = value;
+ return -dseglen;
+}
+
+
+static void dseg_addtarget(basicblock *target)
+{
+ jumpref *jr = DNEW(jumpref);
+
+ jr->tablepos = dseg_addaddress(NULL);
+ jr->target = target;
+ jr->next = jumpreferences;
+ jumpreferences = jr;
+}
+
+
+static void mcode_addreference(basicblock *target, void *branchptr)
+{
+ s4 branchpos = (u1*) branchptr - mcodebase;
+
+ if (target->mpc >= 0) {
+ gen_resolvebranch((u1*) mcodebase + branchpos, branchpos, target->mpc);
+ }
+ else {
+ branchref *br = DNEW(branchref);
+
+ br->branchpos = branchpos;
+ br->next = target->branchrefs;
+ target->branchrefs= br;
+ }
+}
+
+
+static void mcode_addxboundrefs(void *branchptr)
+{
+ s4 branchpos = (u1*) branchptr - mcodebase;
+
+ branchref *br = DNEW(branchref);
+
+ br->branchpos = branchpos;
+ br->next = xboundrefs;
+ xboundrefs = br;
+}
+
+
+static void mcode_addxcheckarefs(void *branchptr)
+{
+ s4 branchpos = (u1*) branchptr - mcodebase;
+
+ branchref *br = DNEW(branchref);
+
+ br->branchpos = branchpos;
+ br->next = xcheckarefs;
+ xcheckarefs = br;
+}
+
+
+static void mcode_addxnullrefs(void *branchptr)
+{
+ s4 branchpos = (u1*) branchptr - mcodebase;
+
+ branchref *br = DNEW(branchref);
+
+ br->branchpos = branchpos;
+ br->next = xnullrefs;
+ xnullrefs = br;
+}
+
+
+static void mcode_addxcastrefs(void *branchptr)
+{
+ s4 branchpos = (u1*) branchptr - mcodebase;
+
+ branchref *br = DNEW(branchref);
+
+ br->branchpos = branchpos;
+ br->next = xcastrefs;
+ xcastrefs = br;
+}
+
+
+static void mcode_finish(int mcodelen)
+{
+ jumpref *jr;
+ u1 *epoint;
+
+ count_code_len += mcodelen;
+ count_data_len += dseglen;
+
+ dseglen = ALIGN(dseglen, MAX_ALIGN);
+
+ method -> mcodelength = mcodelen + dseglen;
+ method -> mcode = CNEW(u1, mcodelen + dseglen);
+
+ memcpy ( method->mcode, dsegtop - dseglen, dseglen);
+ memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
+
+ method -> entrypoint = epoint = (u1*) (method->mcode + dseglen);
+
+ /* jump table resolving */
+
+ jr = jumpreferences;
+ while (jr != NULL) {
+ *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
+ jr = jr->next;
+ }
+
+#ifdef CACHE_FLUSH_BLOCK
+ synchronize_caches(method->mcode, (mcodelen>>2));
+#endif
+
+}
+
+
+static void dseg_display(s4 *s4ptr)
+{
+ int i;
+
+ printf(" --- dump of datasegment\n");
+ for (i = dseglen; i > 0 ; i -= 4) {
+ printf("-%6x: %8x\n", i, (int)(*s4ptr++));
+ }
+ printf(" --- begin of data segment: %p\n", s4ptr);
+}
--- /dev/null
+/* jit/parse.c *****************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ Parser for JavaVM to intermediate code translation
+
+ Author: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1998/05/07
+
+*******************************************************************************/
+
+#include "math.h"
+
+
+/* macros for byte code fetching ***********************************************
+
+ fetch a byte code of given size from position pos
+
+*******************************************************************************/
+
+#define code_get_u1(pos) jcode[pos]
+#define code_get_s1(pos) ((s1)jcode[pos])
+#define code_get_u2(pos) ((((u2)jcode[pos])<<8)+jcode[pos+1])
+#define code_get_s2(pos) ((s2)((((u2)jcode[pos])<<8)+jcode[pos+1]))
+#define code_get_u4(pos) ((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+ (((u4)jcode[pos+2])<<8)+jcode[pos+3])
+#define code_get_s4(pos) ((s4)((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+ (((u4)jcode[pos+2])<<8)+jcode[pos+3]))
+
+
+/* functionc compiler_addinitclass *********************************************
+
+ add class into the list of classes to initialize
+
+*******************************************************************************/
+
+static void compiler_addinitclass (classinfo *c)
+{
+ classinfo *cl;
+
+ if (c->initialized) return;
+
+ cl = chain_first(uninitializedclasses);
+ if (cl == c)
+ return;
+
+ if (cl == class)
+ cl = chain_next(uninitializedclasses);
+ for (;;) {
+ if (cl == c)
+ return;
+ if (cl == NULL) {
+ if (runverbose) {
+ sprintf(logtext, "compiler_addinitclass: ");
+ unicode_sprint(logtext+strlen(logtext), c->name);
+ dolog();
+ }
+ chain_addlast(uninitializedclasses, c);
+ return;
+ }
+ if (c < cl) {
+ if (runverbose) {
+ sprintf(logtext, "compiler_addinitclass: ");
+ unicode_sprint(logtext+strlen(logtext), c->name);
+ dolog();
+ }
+ chain_addbefore(uninitializedclasses, c);
+ return;
+ }
+ cl = chain_next(uninitializedclasses);
+ }
+}
+
+
+/* function descriptor2types ***************************************************
+
+ decodes a already checked method descriptor. The parameter count, the
+ return type and the argument types are stored in the passed methodinfo.
+
+*******************************************************************************/
+
+static void descriptor2types (methodinfo *m)
+{
+ u1 *types, *tptr;
+ int pcount, c;
+ u2 *cptr;
+
+ pcount = 0;
+ types = DMNEW (u1, m->descriptor->length);
+
+ tptr = types;
+ if (!(m->flags & ACC_STATIC)) {
+ *tptr++ = TYPE_ADR;
+ pcount++;
+ }
+
+ cptr = m->descriptor->text;
+ cptr++;
+ while ((c = *cptr++) != ')') {
+ pcount++;
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': *tptr++ = TYPE_INT;
+ break;
+ case 'J': *tptr++ = TYPE_LNG;
+ break;
+ case 'F': *tptr++ = TYPE_FLT;
+ break;
+ case 'D': *tptr++ = TYPE_DBL;
+ break;
+ case 'L': *tptr++ = TYPE_ADR;
+ while (*cptr++ != ';');
+ break;
+ case '[': *tptr++ = TYPE_ADR;
+ while (c == '[')
+ c = *cptr++;
+ if (c == 'L')
+ while (*cptr++ != ';') /* skip */;
+ break;
+ default: panic ("Ill formed methodtype-descriptor");
+ }
+ }
+
+ /* compute return type */
+
+ switch (*cptr) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': m->returntype = TYPE_INT;
+ break;
+ case 'J': m->returntype = TYPE_LNG;
+ break;
+ case 'F': m->returntype = TYPE_FLT;
+ break;
+ case 'D': m->returntype = TYPE_DBL;
+ break;
+ case '[':
+ case 'L': m->returntype = TYPE_ADR;
+ break;
+ case 'V': m->returntype = TYPE_VOID;
+ break;
+
+ default: panic ("Ill formed methodtype-descriptor");
+ }
+
+ m->paramcount = pcount;
+ m->paramtypes = types;
+}
+
+
+/* function allocate_literals **************************************************
+
+ Scans the JavaVM code of a method and allocates string literals. Needed
+ to generate the same addresses as the old JIT compiler.
+
+*******************************************************************************/
+
+static void allocate_literals()
+{
+ int p, nextp;
+ int opcode, i;
+ s4 num;
+ unicode *s;
+
+ for (p = 0; p < jcodelength; p = nextp) {
+
+ opcode = jcode[p];
+ nextp = p + jcommandsize[opcode];
+
+ switch (opcode) {
+ case JAVA_WIDE:
+ if (code_get_u1(p + 1) == JAVA_IINC)
+ nextp = p + 6;
+ else
+ nextp = p + 4;
+ break;
+
+ case JAVA_LOOKUPSWITCH:
+ nextp = ALIGN((p + 1), 4);
+ num = code_get_u4(nextp + 4);
+ nextp = nextp + 8 + 8 * num;
+ break;
+
+ case JAVA_TABLESWITCH:
+ nextp = ALIGN ((p + 1),4);
+ num = code_get_s4(nextp + 4);
+ num = code_get_s4(nextp + 8) - num;
+ nextp = nextp + 16 + 4 * num;
+ break;
+
+ case JAVA_LDC1:
+ i = code_get_u1(p+1);
+ goto pushconstantitem;
+ case JAVA_LDC2:
+ case JAVA_LDC2W:
+ i = code_get_u2(p + 1);
+ pushconstantitem:
+ if (class_constanttype(class, i) == CONSTANT_String) {
+ s = class_getconstant(class, i, CONSTANT_String);
+ (void) literalstring_new(s);
+ }
+ break;
+ } /* end switch */
+ } /* end while */
+}
+
+
+
+/*******************************************************************************
+
+ function 'parse' scans the JavaVM code and generates intermediate code
+
+ During parsing the block index table is used to store at bit pos 0
+ a flag which marks basic block starts and at position 1 to 31 the
+ intermediate instruction index. After parsing the block index table
+ is scanned, for marked positions a block is generated and the block
+ number is stored in the block index table.
+
+*******************************************************************************/
+
+/* intermediate code generating macros */
+
+#define PINC iptr++;ipc++
+#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
+#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
+#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
+#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
+#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
+#define OP(o) iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
+#define OP1(o,o1) iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
+#define OP2I(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
+#define OP2A(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
+#define BUILTIN1(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+#define BUILTIN2(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+#define BUILTIN3(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+
+
+/* block generating and checking macros */
+
+#define block_insert(i) {if(!(block_index[i]&1))\
+ {b_count++;block_index[i] |= 1;}}
+#define bound_check(i) {if((i< 0) || (i>=jcodelength)) \
+ panic("branch target out of code-boundary");}
+#define bound_check1(i) {if((i< 0) || (i>jcodelength)) \
+ panic("branch target out of code-boundary");}
+
+
+static void parse()
+{
+ int p; /* java instruction counter */
+ int nextp; /* start of next java instruction */
+ int opcode; /* java opcode */
+ int i; /* temporary for different uses (counters) */
+ int ipc = 0; /* intermediate instruction counter */
+ int b_count = 0; /* basic block counter */
+ int s_count = 0; /* stack element counter */
+ bool blockend = false; /* true if basic block end has reached */
+ bool iswide = false; /* true if last instruction was a wide */
+ instruction *iptr; /* current pointer into instruction array */
+
+
+ /* allocate instruction array and block index table */
+
+ /* 1 additional for end ipc and 3 for loop unrolling */
+
+ block_index = DMNEW(int, jcodelength + 3);
+
+ /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
+ /* additional MONITOREXITS are reached by branches which are 3 bytes */
+
+ iptr = instr = DMNEW(instruction, jcodelength + 5);
+
+ /* initialize block_index table (unrolled four times) */
+
+ {
+ int *ip;
+
+ for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
+ ip[0] = 0;
+ ip[1] = 0;
+ ip[2] = 0;
+ ip[3] = 0;
+ }
+ }
+
+ /* compute branch targets of exception table */
+
+ for (i = 0; i < exceptiontablelength; i++) {
+ p = extable[i].startpc;
+ bound_check(p);
+ block_insert(p);
+ p = extable[i].endpc;
+ bound_check1(p);
+ if (p < jcodelength)
+ block_insert(p);
+ p = extable[i].handlerpc;
+ bound_check(p);
+ block_insert(p);
+ }
+
+ s_count = 1 + exceptiontablelength; /* initialize stack element counter */
+
+ if (runverbose) {
+/* isleafmethod=false; */
+ }
+
+#ifdef USE_THREADS
+ if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
+ isleafmethod=false;
+ }
+#endif
+
+ /* scan all java instructions */
+
+ for (p = 0; p < jcodelength; p = nextp) {
+
+ opcode = code_get_u1 (p); /* fetch op code */
+
+ block_index[p] |= (ipc << 1); /* store intermediate count */
+
+ if (blockend) {
+ block_insert(p); /* start new block */
+ blockend = false;
+ }
+
+ nextp = p + jcommandsize[opcode]; /* compute next instruction start */
+ s_count += stackreq[opcode]; /* compute stack element count */
+
+ switch (opcode) {
+
+ case JAVA_NOP:
+ break;
+
+ /* pushing constants onto the stack p */
+
+ case JAVA_BIPUSH:
+ LOADCONST_I(code_get_s1(p+1));
+ break;
+
+ case JAVA_SIPUSH:
+ LOADCONST_I(code_get_s2(p+1));
+ break;
+
+ case JAVA_LDC1:
+ i = code_get_u1(p+1);
+ goto pushconstantitem;
+ case JAVA_LDC2:
+ case JAVA_LDC2W:
+ i = code_get_u2(p + 1);
+
+ pushconstantitem:
+
+ if (i >= class->cpcount)
+ panic ("Attempt to access constant outside range");
+
+ switch (class->cptags[i]) {
+ case CONSTANT_Integer:
+ LOADCONST_I(((constant_integer*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Long:
+ LOADCONST_L(((constant_long*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Float:
+ LOADCONST_F(((constant_float*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Double:
+ LOADCONST_D(((constant_double*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_String:
+ LOADCONST_A(literalstring_new((unicode*)
+ (class->cpinfos[i])));
+ break;
+ default: panic("Invalid constant type to push");
+ }
+ break;
+
+ case JAVA_ACONST_NULL:
+ LOADCONST_A(NULL);
+ break;
+
+ case JAVA_ICONST_M1:
+ case JAVA_ICONST_0:
+ case JAVA_ICONST_1:
+ case JAVA_ICONST_2:
+ case JAVA_ICONST_3:
+ case JAVA_ICONST_4:
+ case JAVA_ICONST_5:
+ LOADCONST_I(opcode - JAVA_ICONST_0);
+ break;
+
+ case JAVA_LCONST_0:
+ case JAVA_LCONST_1:
+ LOADCONST_L(opcode - JAVA_LCONST_0);
+ break;
+
+ case JAVA_FCONST_0:
+ case JAVA_FCONST_1:
+ case JAVA_FCONST_2:
+ LOADCONST_F(opcode - JAVA_FCONST_0);
+ break;
+
+ case JAVA_DCONST_0:
+ case JAVA_DCONST_1:
+ LOADCONST_D(opcode - JAVA_DCONST_0);
+ break;
+
+ /* loading variables onto the stack */
+
+ case JAVA_ILOAD:
+ case JAVA_LLOAD:
+ case JAVA_FLOAD:
+ case JAVA_DLOAD:
+ case JAVA_ALOAD:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ nextp = p+3;
+ iswide = false;
+ }
+ OP1(opcode, i);
+ break;
+
+ case JAVA_ILOAD_0:
+ case JAVA_ILOAD_1:
+ case JAVA_ILOAD_2:
+ case JAVA_ILOAD_3:
+ OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
+ break;
+
+ case JAVA_LLOAD_0:
+ case JAVA_LLOAD_1:
+ case JAVA_LLOAD_2:
+ case JAVA_LLOAD_3:
+ OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
+ break;
+
+ case JAVA_FLOAD_0:
+ case JAVA_FLOAD_1:
+ case JAVA_FLOAD_2:
+ case JAVA_FLOAD_3:
+ OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
+ break;
+
+ case JAVA_DLOAD_0:
+ case JAVA_DLOAD_1:
+ case JAVA_DLOAD_2:
+ case JAVA_DLOAD_3:
+ OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
+ break;
+
+ case JAVA_ALOAD_0:
+ case JAVA_ALOAD_1:
+ case JAVA_ALOAD_2:
+ case JAVA_ALOAD_3:
+ OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+ break;
+
+ /* storing stack values into local variables */
+
+ case JAVA_ISTORE:
+ case JAVA_LSTORE:
+ case JAVA_FSTORE:
+ case JAVA_DSTORE:
+ case JAVA_ASTORE:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ iswide=false;
+ nextp = p+3;
+ }
+ OP1(opcode, i);
+ break;
+
+ case JAVA_ISTORE_0:
+ case JAVA_ISTORE_1:
+ case JAVA_ISTORE_2:
+ case JAVA_ISTORE_3:
+ OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
+ break;
+
+ case JAVA_LSTORE_0:
+ case JAVA_LSTORE_1:
+ case JAVA_LSTORE_2:
+ case JAVA_LSTORE_3:
+ OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
+ break;
+
+ case JAVA_FSTORE_0:
+ case JAVA_FSTORE_1:
+ case JAVA_FSTORE_2:
+ case JAVA_FSTORE_3:
+ OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
+ break;
+
+ case JAVA_DSTORE_0:
+ case JAVA_DSTORE_1:
+ case JAVA_DSTORE_2:
+ case JAVA_DSTORE_3:
+ OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
+ break;
+
+ case JAVA_ASTORE_0:
+ case JAVA_ASTORE_1:
+ case JAVA_ASTORE_2:
+ case JAVA_ASTORE_3:
+ OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
+ break;
+
+ case JAVA_IINC:
+ {
+ int v;
+
+ if (!iswide) {
+ i = code_get_u1(p + 1);
+ v = code_get_s1(p + 2);
+ }
+ else {
+ i = code_get_u2(p + 1);
+ v = code_get_s2(p + 3);
+ iswide = false;
+ nextp = p+5;
+ }
+ OP2I(opcode, i, v);
+ }
+ break;
+
+ /* wider index for loading, storing and incrementing */
+
+ case JAVA_WIDE:
+ iswide = true;
+ nextp = p + 1;
+ break;
+
+ /* managing arrays ************************************************/
+
+ case JAVA_NEWARRAY:
+ OP2I(ICMD_CHECKASIZE, 0, 0);
+ switch (code_get_s1(p+1)) {
+ case 4:
+ BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
+ break;
+ case 5:
+ BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
+ break;
+ case 6:
+ BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
+ break;
+ case 7:
+ BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
+ break;
+ case 8:
+ BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
+ break;
+ case 9:
+ BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
+ break;
+ case 10:
+ BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
+ break;
+ case 11:
+ BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
+ break;
+ default: panic("Invalid array-type to create");
+ }
+ break;
+
+ case JAVA_ANEWARRAY:
+ OP2I(ICMD_CHECKASIZE, 0, 0);
+ i = code_get_u2(p+1);
+ /* array or class type ? */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i,
+ CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
+ }
+ else {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
+ }
+ break;
+
+ case JAVA_MULTIANEWARRAY:
+ isleafmethod=false;
+ i = code_get_u2(p+1);
+ {
+ int v = code_get_u1(p+3);
+ constant_arraydescriptor *desc =
+ class_getconstant (class, i, CONSTANT_Arraydescriptor);
+ OP2A(opcode, v, desc);
+ }
+ break;
+
+ case JAVA_IFEQ:
+ case JAVA_IFLT:
+ case JAVA_IFLE:
+ case JAVA_IFNE:
+ case JAVA_IFGT:
+ case JAVA_IFGE:
+ case JAVA_IFNULL:
+ case JAVA_IFNONNULL:
+ case JAVA_IF_ICMPEQ:
+ case JAVA_IF_ICMPNE:
+ case JAVA_IF_ICMPLT:
+ case JAVA_IF_ICMPGT:
+ case JAVA_IF_ICMPLE:
+ case JAVA_IF_ICMPGE:
+ case JAVA_IF_ACMPEQ:
+ case JAVA_IF_ACMPNE:
+ case JAVA_GOTO:
+ case JAVA_JSR:
+ i = p + code_get_s2(p+1);
+ bound_check(i);
+ block_insert(i);
+ blockend = true;
+ OP1(opcode, i);
+ break;
+ case JAVA_GOTO_W:
+ case JAVA_JSR_W:
+ i = p + code_get_s4(p+1);
+ bound_check(i);
+ block_insert(i);
+ blockend = true;
+ OP1(opcode, i);
+ break;
+
+ case JAVA_RET:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ nextp = p+3;
+ iswide = false;
+ }
+ blockend = true;
+ OP1(opcode, i);
+ break;
+
+ case JAVA_IRETURN:
+ case JAVA_LRETURN:
+ case JAVA_FRETURN:
+ case JAVA_DRETURN:
+ case JAVA_ARETURN:
+ case JAVA_RETURN:
+ blockend = true;
+ OP(opcode);
+ break;
+
+ case JAVA_ATHROW:
+ blockend = true;
+ OP(opcode);
+ break;
+
+
+ /* table jumps ********************************/
+
+ case JAVA_LOOKUPSWITCH:
+ {
+ s4 num, j;
+
+ blockend = true;
+ nextp = ALIGN((p + 1), 4);
+ OP2A(opcode, 0, jcode + nextp);
+
+ /* default target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+
+ /* number of pairs */
+
+ num = code_get_u4(nextp);
+ *((s4*)(jcode + nextp)) = num;
+ nextp += 4;
+
+ for (i = 0; i < num; i++) {
+
+ /* value */
+
+ j = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+
+ /* target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+ }
+
+ break;
+ }
+
+
+ case JAVA_TABLESWITCH:
+ {
+ s4 num, j;
+
+ blockend = true;
+ nextp = ALIGN((p + 1), 4);
+ OP2A(opcode, 0, jcode + nextp);
+
+ /* default target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+
+ /* lower bound */
+
+ j = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+
+ /* upper bound */
+
+ num = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = num; /* restore for little endian */
+ nextp += 4;
+
+ num -= j;
+
+ for (i = 0; i <= num; i++) {
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+ }
+
+ break;
+ }
+
+
+ /* load and store of object fields *******************/
+
+ case JAVA_AASTORE:
+ BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+ break;
+
+ case JAVA_PUTSTATIC:
+ case JAVA_GETSTATIC:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
+ fr = class_getconstant (class, i, CONSTANT_Fieldref);
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ compiler_addinitclass (fr->class);
+ OP2A(opcode, fi->type, fi);
+ }
+ break;
+ case JAVA_PUTFIELD:
+ case JAVA_GETFIELD:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
+ fr = class_getconstant (class, i, CONSTANT_Fieldref);
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ OP2A(opcode, fi->type, fi);
+ }
+ break;
+
+
+ /* method invocation *****/
+
+ case JAVA_INVOKESTATIC:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_Methodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (! (mi->flags & ACC_STATIC))
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+ case JAVA_INVOKESPECIAL:
+ case JAVA_INVOKEVIRTUAL:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_Methodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (mi->flags & ACC_STATIC)
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+ case JAVA_INVOKEINTERFACE:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (mi->flags & ACC_STATIC)
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+
+ /* miscellaneous object operations *******/
+
+ case JAVA_NEW:
+ i = code_get_u2 (p+1);
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+ break;
+
+ case JAVA_CHECKCAST:
+ i = code_get_u2(p+1);
+
+ /* array type cast-check */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ }
+ else { /* object type cast-check */
+ OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+ }
+ break;
+
+ case JAVA_INSTANCEOF:
+ i = code_get_u2(p+1);
+
+ /* array type cast-check */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
+ }
+ else { /* object type cast-check */
+ OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+ }
+ break;
+
+ case JAVA_MONITORENTER:
+#ifdef USE_THREADS
+ if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+ if (checknull) {
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ }
+ else {
+/* BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ }
+#else
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+#endif
+ }
+ else
+#endif
+ {
+ OP(ICMD_NULLCHECKPOP);
+ }
+ break;
+
+ case JAVA_MONITOREXIT:
+#ifdef USE_THREADS
+ if (checksync) {
+ BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+ }
+ else
+#endif
+ {
+ OP(ICMD_POP);
+ }
+ break;
+
+ /* any other basic operation **************************************/
+
+ case JAVA_IDIV:
+ OP(opcode);
+ break;
+
+ case JAVA_IREM:
+ OP(opcode);
+ break;
+
+ case JAVA_LDIV:
+ OP(opcode);
+ break;
+
+ case JAVA_LREM:
+ OP(opcode);
+ break;
+
+ case JAVA_FREM:
+ BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+ break;
+
+ case JAVA_DREM:
+ BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+ break;
+
+ case JAVA_F2I:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_F2L:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_D2I:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_D2L:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_BREAKPOINT:
+ panic("Illegal opcode Breakpoint encountered");
+ break;
+
+ case 203:
+ case 204:
+ case 205:
+ case 206:
+ case 207:
+ case 208:
+ case 209:
+ case 210:
+ case 211:
+ case 212:
+ case 213:
+ case 214:
+ case 215:
+ case 216:
+ case 217:
+ case 218:
+ case 219:
+ case 220:
+ case 221:
+ case 222:
+ case 223:
+ case 224:
+ case 225:
+ case 226:
+ case 227:
+ case 228:
+ case 229:
+ case 230:
+ case 231:
+ case 232:
+ case 233:
+ case 234:
+ case 235:
+ case 236:
+ case 237:
+ case 238:
+ case 239:
+ case 240:
+ case 241:
+ case 242:
+ case 243:
+ case 244:
+ case 245:
+ case 246:
+ case 247:
+ case 248:
+ case 249:
+ case 250:
+ case 251:
+ case 252:
+ case 253:
+ case 254:
+ case 255:
+ printf("Illegal opcode %d at instr %d", opcode, ipc);
+ panic("encountered");
+ break;
+
+ default:
+ OP(opcode);
+ break;
+
+ } /* end switch */
+
+ } /* end for */
+
+ if (p != jcodelength)
+ panic("Command-sequence crosses code-boundary");
+
+ if (!blockend)
+ panic("Code does not end with branch/return/athrow - stmt");
+
+ /* adjust block count if target 0 is not first intermediate instruction */
+
+ if (!block_index[0] || (block_index[0] > 1))
+ b_count++;
+
+ /* copy local to global variables */
+
+ instr_count = ipc;
+ block_count = b_count;
+ stack_count = s_count + block_count * maxstack;
+
+ /* allocate stack table */
+
+ stack = DMNEW(stackelement, stack_count);
+
+ {
+ basicblock *bptr;
+
+ bptr = block = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
+
+ b_count = 0;
+
+ /* additional block if target 0 is not first intermediate instruction */
+
+ if (!block_index[0] || (block_index[0] > 1)) {
+ bptr->iinstr = instr;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ bptr->pre_count = 0;
+ bptr++;
+ b_count++;
+ }
+
+ /* allocate blocks */
+
+ for (p = 0; p < jcodelength; p++)
+ if (block_index[p] & 1) {
+ bptr->iinstr = instr + (block_index[p] >> 1);
+ if (b_count != 0)
+ (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ block_index[p] = b_count;
+ bptr->pre_count = 0;
+ bptr++;
+ b_count++;
+ }
+
+ /* allocate additional block at end */
+
+ bptr->iinstr = NULL;
+ (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
+ bptr->icount = 0;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ bptr->pre_count = 0;
+ }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/* jit/reg.c *******************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ The register-manager.
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1998/11/09
+
+*******************************************************************************/
+
+static varinfo5 *locals;
+static varinfo5 *interfaces;
+
+static int intregsnum; /* absolute number of integer registers */
+static int floatregsnum; /* absolute number of float registers */
+
+static int intreg_ret; /* register to return integer values */
+static int intreg_argnum; /* number of integer argument registers */
+
+static int floatreg_ret; /* register for return float values */
+static int fltreg_argnum; /* number of float argument registers */
+
+
+static int *argintregs; /* scratch integer registers */
+static int *tmpintregs = NULL; /* scratch integer registers */
+static int *savintregs; /* saved integer registers */
+static int *argfltregs; /* scratch float registers */
+static int *tmpfltregs; /* scratch float registers */
+static int *savfltregs; /* saved float registers */
+static int *freetmpintregs; /* free scratch integer registers */
+static int *freesavintregs; /* free saved integer registers */
+static int *freetmpfltregs; /* free scratch float registers */
+static int *freesavfltregs; /* free saved float registers */
+
+static int *freemem; /* free scratch memory */
+static int memuse; /* used memory count */
+static int ifmemuse; /* interface used memory count */
+static int maxmemuse; /* maximal used memory count (spills) */
+static int freememtop; /* free memory count */
+
+static int tmpintregcnt; /* scratch integer register count */
+static int savintregcnt; /* saved integer register count */
+static int tmpfltregcnt; /* scratch float register count */
+static int savfltregcnt; /* saved float register count */
+
+static int iftmpintregcnt; /* iface scratch integer register count */
+static int ifsavintregcnt; /* iface saved integer register count */
+static int iftmpfltregcnt; /* iface scratch float register count */
+static int ifsavfltregcnt; /* iface saved float register count */
+
+static int tmpintreguse; /* used scratch integer register count */
+static int savintreguse; /* used saved integer register count */
+static int tmpfltreguse; /* used scratch float register count */
+static int savfltreguse; /* used saved float register count */
+
+static int maxtmpintreguse; /* max used scratch int register count */
+static int maxsavintreguse; /* max used saved int register count */
+static int maxtmpfltreguse; /* max used scratch float register count */
+static int maxsavfltreguse; /* max used saved float register count */
+
+static int freetmpinttop; /* free scratch integer register count */
+static int freesavinttop; /* free saved integer register count */
+static int freetmpflttop; /* free scratch float register count */
+static int freesavflttop; /* free saved float register count */
+
+static int savedregs_num; /* total number of registers to be saved */
+static int arguments_num; /* size of parameter field in the stackframe */
+
+
+
+/* function reg_init ***********************************************************
+
+ initialises the register-allocator
+
+*******************************************************************************/
+
+static void reg_init()
+{
+ int n;
+
+ if (!tmpintregs) {
+
+ if (TYPE_INT != 0 || TYPE_ADR != 4)
+ panic ("JAVA-Basictypes have been changed");
+
+ intreg_argnum = 0;
+ tmpintregcnt = 0;
+ savintregcnt = 0;
+
+ for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
+ switch (nregdescint[intregsnum]) {
+ case REG_SAV: savintregcnt++;
+ break;
+ case REG_TMP: tmpintregcnt++;
+ break;
+ case REG_ARG: intreg_argnum++;
+ }
+ }
+
+ argintregs = MNEW (int, intreg_argnum);
+ tmpintregs = MNEW (int, tmpintregcnt);
+ savintregs = MNEW (int, savintregcnt);
+ freetmpintregs = MNEW (int, tmpintregcnt);
+ freesavintregs = MNEW (int, savintregcnt);
+
+ intreg_argnum = 0;
+ tmpintreguse = 0;
+ savintreguse = 0;
+
+ for (n = 0; n < intregsnum; n++) {
+ switch (nregdescint[n]) {
+ case REG_RET: intreg_ret = n;
+ break;
+ case REG_SAV: savintregs[savintreguse++] = n;
+ break;
+ case REG_TMP: tmpintregs[tmpintreguse++] = n;
+ break;
+ case REG_ARG: argintregs[intreg_argnum++] = n;
+ break;
+ }
+ }
+
+
+ fltreg_argnum = 0;
+ tmpfltregcnt = 0;
+ savfltregcnt = 0;
+
+ for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
+ switch (nregdescfloat[floatregsnum]) {
+ case REG_SAV: savfltregcnt++;
+ break;
+ case REG_TMP: tmpfltregcnt++;
+ break;
+ case REG_ARG: fltreg_argnum++;
+ break;
+ }
+ }
+
+ argfltregs = MNEW (int, fltreg_argnum);
+ tmpfltregs = MNEW (int, tmpfltregcnt);
+ savfltregs = MNEW (int, savfltregcnt);
+ freetmpfltregs = MNEW (int, tmpfltregcnt);
+ freesavfltregs = MNEW (int, savfltregcnt);
+
+ fltreg_argnum = 0;
+ tmpfltreguse = 0;
+ savfltreguse = 0;
+
+ for (n = 0; n < floatregsnum; n++) {
+ switch (nregdescfloat[n]) {
+ case REG_RET: floatreg_ret = n;
+ break;
+ case REG_SAV: savfltregs[savfltreguse++] = n;
+ break;
+ case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
+ break;
+ case REG_ARG: argfltregs[fltreg_argnum++] = n;
+ break;
+ }
+ }
+
+ }
+
+}
+
+
+/* function reg_close **********************************************************
+
+ releases all allocated space for registers
+
+*******************************************************************************/
+
+static void reg_close ()
+{
+ if (argintregs) MFREE (argintregs, int, intreg_argnum);
+ if (argfltregs) MFREE (argfltregs, int, fltreg_argnum);
+ if (tmpintregs) MFREE (tmpintregs, int, tmpintregcnt);
+ if (savintregs) MFREE (savintregs, int, savintregcnt);
+ if (tmpfltregs) MFREE (tmpfltregs, int, tmpfltregcnt);
+ if (savfltregs) MFREE (savfltregs, int, savfltregcnt);
+
+ if (freetmpintregs) MFREE (freetmpintregs, int, tmpintregcnt);
+ if (freesavintregs) MFREE (freesavintregs, int, savintregcnt);
+ if (freetmpfltregs) MFREE (freetmpfltregs, int, tmpfltregcnt);
+ if (freesavfltregs) MFREE (freesavfltregs, int, savfltregcnt);
+}
+
+
+/* function local_init *********************************************************
+
+ initialises the local variable and interfaces table
+
+*******************************************************************************/
+
+static void local_init()
+{
+ int i;
+ varinfo5 *v;
+
+ freemem = DMNEW(int, maxstack);
+ locals = DMNEW(varinfo5, maxlocals);
+ interfaces = DMNEW(varinfo5, maxstack);
+
+ for (v = locals, i = maxlocals; i > 0; v++, i--) {
+ v[0][TYPE_INT].type = -1;
+ v[0][TYPE_LNG].type = -1;
+ v[0][TYPE_FLT].type = -1;
+ v[0][TYPE_DBL].type = -1;
+ v[0][TYPE_ADR].type = -1;
+ }
+
+ for (v = interfaces, i = maxstack; i > 0; v++, i--) {
+ v[0][TYPE_INT].type = -1;
+ v[0][TYPE_INT].flags = 0;
+ v[0][TYPE_LNG].type = -1;
+ v[0][TYPE_LNG].flags = 0;
+ v[0][TYPE_FLT].type = -1;
+ v[0][TYPE_FLT].flags = 0;
+ v[0][TYPE_DBL].type = -1;
+ v[0][TYPE_DBL].flags = 0;
+ v[0][TYPE_ADR].type = -1;
+ v[0][TYPE_ADR].flags = 0;
+ }
+}
+
+
+/* function interface_regalloc *************************************************
+
+ allocates registers for all interface variables
+
+*******************************************************************************/
+
+static void interface_regalloc ()
+{
+ int s, t, saved;
+ int intalloc, fltalloc;
+ varinfo *v;
+
+ /* allocate stack space for passing arguments to called methods */
+
+ if (arguments_num > intreg_argnum)
+ ifmemuse = arguments_num - intreg_argnum;
+ else
+ ifmemuse = 0;
+
+ iftmpintregcnt = tmpintregcnt;
+ ifsavintregcnt = savintregcnt;
+ iftmpfltregcnt = tmpfltregcnt;
+ ifsavfltregcnt = savfltregcnt;
+
+ for (s = 0; s < maxstack; s++) {
+ intalloc = -1; fltalloc = -1;
+ saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
+ interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
+ interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
+ for (t = TYPE_INT; t <= TYPE_ADR; t++) {
+ v = &interfaces[s][t];
+ if (v->type >= 0) {
+ if (!saved) {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
+ v->regoff = interfaces[s][fltalloc].regoff;
+ }
+ else if (iftmpfltregcnt > 0) {
+ iftmpfltregcnt--;
+ v->regoff = tmpfltregs[iftmpfltregcnt];
+ }
+ else if (ifsavfltregcnt > 0) {
+ ifsavfltregcnt--;
+ v->regoff = savfltregs[ifsavfltregcnt];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = ifmemuse++;
+ }
+ fltalloc = t;
+ }
+ else {
+ if (intalloc >= 0) {
+ v->flags |= interfaces[s][intalloc].flags & INMEMORY;
+ v->regoff = interfaces[s][intalloc].regoff;
+ }
+ else if (iftmpintregcnt > 0) {
+ iftmpintregcnt--;
+ v->regoff = tmpintregs[iftmpintregcnt];
+ }
+ else if (ifsavintregcnt > 0) {
+ ifsavintregcnt--;
+ v->regoff = savintregs[ifsavintregcnt];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = ifmemuse++;
+ }
+ intalloc = t;
+ }
+ }
+ else {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
+ v->regoff = interfaces[s][fltalloc].regoff;
+ }
+ else if (ifsavfltregcnt > 0) {
+ ifsavfltregcnt--;
+ v->regoff = savfltregs[ifsavfltregcnt];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = ifmemuse++;
+ }
+ fltalloc = t;
+ }
+ else {
+ if (intalloc >= 0) {
+ v->flags |= interfaces[s][intalloc].flags & INMEMORY;
+ v->regoff = interfaces[s][intalloc].regoff;
+ }
+ else if (ifsavintregcnt > 0) {
+ ifsavintregcnt--;
+ v->regoff = savintregs[ifsavintregcnt];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = ifmemuse++;
+ }
+ intalloc = t;
+ }
+ }
+ } /* if (type >= 0) */
+ } /* for t */
+ } /* for s */
+ maxmemuse = ifmemuse;
+ maxtmpintreguse = iftmpintregcnt;
+ maxsavintreguse = ifsavintregcnt;
+ maxtmpfltreguse = iftmpfltregcnt;
+ maxsavfltreguse = ifsavfltregcnt;
+}
+
+
+/* function local_regalloc *****************************************************
+
+ allocates registers for all local variables
+
+*******************************************************************************/
+
+static void local_regalloc ()
+{
+ int s, t;
+ int intalloc, fltalloc;
+ varinfo *v;
+
+ if (isleafmethod) {
+ for (s = 0; s < maxlocals; s++) {
+ intalloc = -1; fltalloc = -1;
+ for (t = TYPE_INT; t <= TYPE_ADR; t++) {
+ v = &locals[s][t];
+ if (v->type >= 0) {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ v->flags = locals[s][fltalloc].flags;
+ v->regoff = locals[s][fltalloc].regoff;
+ }
+ else if (s < fltreg_argnum) {
+ v->flags = 0;
+ v->regoff = argfltregs[s];
+ }
+ else if (maxtmpfltreguse > 0) {
+ maxtmpfltreguse--;
+ v->flags = 0;
+ v->regoff = tmpfltregs[maxtmpfltreguse];
+ }
+ else if (maxsavfltreguse > 0) {
+ maxsavfltreguse--;
+ v->flags = 0;
+ v->regoff = savfltregs[maxsavfltreguse];
+ }
+ else {
+ v->flags = INMEMORY;
+ v->regoff = maxmemuse++;
+ }
+ fltalloc = t;
+ }
+ else {
+ if (intalloc >= 0) {
+ v->flags = locals[s][intalloc].flags;
+ v->regoff = locals[s][intalloc].regoff;
+ }
+ else if (s < intreg_argnum) {
+ v->flags = 0;
+ v->regoff = argintregs[s];
+ }
+ else if (maxtmpintreguse > 0) {
+ maxtmpintreguse--;
+ v->flags = 0;
+ v->regoff = tmpintregs[maxtmpintreguse];
+ }
+ else if (maxsavintreguse > 0) {
+ maxsavintreguse--;
+ v->flags = 0;
+ v->regoff = savintregs[maxsavintreguse];
+ }
+ else {
+ v->flags = INMEMORY;
+ v->regoff = maxmemuse++;
+ }
+ intalloc = t;
+ }
+ }
+ }
+ }
+ return;
+ }
+ for (s = 0; s < maxlocals; s++) {
+ intalloc = -1; fltalloc = -1;
+ for (t=TYPE_INT; t<=TYPE_ADR; t++) {
+ v = &locals[s][t];
+ if (v->type >= 0) {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ v->flags = locals[s][fltalloc].flags;
+ v->regoff = locals[s][fltalloc].regoff;
+ }
+ else if (maxsavfltreguse > 0) {
+ maxsavfltreguse--;
+ v->flags = 0;
+ v->regoff = savfltregs[maxsavfltreguse];
+ }
+ else {
+ v->flags = INMEMORY;
+ v->regoff = maxmemuse++;
+ }
+ fltalloc = t;
+ }
+ else {
+ if (intalloc >= 0) {
+ v->flags = locals[s][intalloc].flags;
+ v->regoff = locals[s][intalloc].regoff;
+ }
+ else if (maxsavintreguse > 0) {
+ maxsavintreguse--;
+ v->flags = 0;
+ v->regoff = savintregs[maxsavintreguse];
+ }
+ else {
+ v->flags = INMEMORY;
+ v->regoff = maxmemuse++;
+ }
+ intalloc = t;
+ }
+ }
+ }
+ }
+}
+
+
+static void reg_init_temp()
+{
+ freememtop = 0;
+ memuse = ifmemuse;
+
+ freetmpinttop = 0;
+ freesavinttop = 0;
+ freetmpflttop = 0;
+ freesavflttop = 0;
+ tmpintreguse = iftmpintregcnt;
+ savintreguse = ifsavintregcnt;
+ tmpfltreguse = iftmpfltregcnt;
+ savfltreguse = ifsavfltregcnt;
+}
+
+
+#define reg_new_temp(s) if(s->varkind==TEMPVAR)reg_new_temp_func(s)
+
+static void reg_new_temp_func(stackptr s)
+{
+if (s->flags & SAVEDVAR) {
+ if (IS_FLT_DBL_TYPE(s->type)) {
+ if (freesavflttop > 0) {
+ freesavflttop--;
+ s->regoff = freesavfltregs[freesavflttop];
+ return;
+ }
+ else if (savfltreguse > 0) {
+ savfltreguse--;
+ if (savfltreguse < maxsavfltreguse)
+ maxsavfltreguse = savfltreguse;
+ s->regoff = savfltregs[savfltreguse];
+ return;
+ }
+ }
+ else {
+ if (freesavinttop > 0) {
+ freesavinttop--;
+ s->regoff = freesavintregs[freesavinttop];
+ return;
+ }
+ else if (savintreguse > 0) {
+ savintreguse--;
+ if (savintreguse < maxsavintreguse)
+ maxsavintreguse = savintreguse;
+ s->regoff = savintregs[savintreguse];
+ return;
+ }
+ }
+ }
+else {
+ if (IS_FLT_DBL_TYPE(s->type)) {
+ if (freetmpflttop > 0) {
+ freetmpflttop--;
+ s->regoff = freetmpfltregs[freetmpflttop];
+ return;
+ }
+ else if (tmpfltreguse > 0) {
+ tmpfltreguse--;
+ if (tmpfltreguse < maxtmpfltreguse)
+ maxtmpfltreguse = tmpfltreguse;
+ s->regoff = tmpfltregs[tmpfltreguse];
+ return;
+ }
+ }
+ else {
+ if (freetmpinttop > 0) {
+ freetmpinttop--;
+ s->regoff = freetmpintregs[freetmpinttop];
+ return;
+ }
+ else if (tmpintreguse > 0) {
+ tmpintreguse--;
+ if (tmpintreguse < maxtmpintreguse)
+ maxtmpintreguse = tmpintreguse;
+ s->regoff = tmpintregs[tmpintreguse];
+ return;
+ }
+ }
+ }
+if (freememtop > 0) {
+ freememtop--;
+ s->regoff = freemem[freememtop];
+ }
+else {
+ s->regoff = memuse++;
+ if (memuse > maxmemuse)
+ maxmemuse = memuse;
+ }
+s->flags |= INMEMORY;
+}
+
+
+#define reg_free_temp(s) if(s->varkind==TEMPVAR)reg_free_temp_func(s)
+
+static void reg_free_temp_func(stackptr s)
+{
+if (s->flags & INMEMORY)
+ freemem[freememtop++] = s->regoff;
+else if (IS_FLT_DBL_TYPE(s->type)) {
+ if (s->flags & SAVEDVAR)
+ freesavfltregs[freesavflttop++] = s->regoff;
+ else
+ freetmpfltregs[freetmpflttop++] = s->regoff;
+ }
+else
+ if (s->flags & SAVEDVAR)
+ freesavintregs[freesavinttop++] = s->regoff;
+ else
+ freetmpintregs[freetmpinttop++] = s->regoff;
+}
+
+
+static void allocate_scratch_registers()
+{
+ int b_count;
+ int opcode, i, len;
+ stackptr src, dst;
+ instruction *iptr = instr;
+ basicblock *bptr;
+
+ b_count = block_count;
+ bptr = block;
+ while (--b_count >= 0) {
+ if (bptr->flags >= BBREACHED) {
+ dst = bptr->instack;
+ reg_init_temp();
+ iptr = bptr->iinstr;
+ len = bptr->icount;
+ while (--len >= 0) {
+ src = dst;
+ dst = iptr->dst;
+ opcode = iptr->opc;
+ switch (opcode) {
+
+ /* pop 0 push 0 */
+
+ case ICMD_NOP:
+ case ICMD_ELSE_ICONST:
+ case ICMD_CHECKASIZE:
+ case ICMD_IINC:
+ case ICMD_JSR:
+ case ICMD_RET:
+ case ICMD_RETURN:
+ case ICMD_GOTO:
+ break;
+
+ /* pop 0 push 1 const */
+
+ case ICMD_ICONST:
+ case ICMD_LCONST:
+ case ICMD_FCONST:
+ case ICMD_DCONST:
+ case ICMD_ACONST:
+
+ /* pop 0 push 1 load */
+
+ case ICMD_ILOAD:
+ case ICMD_LLOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
+ case ICMD_ALOAD:
+ reg_new_temp(dst);
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IALOAD:
+ case ICMD_LALOAD:
+ case ICMD_FALOAD:
+ case ICMD_DALOAD:
+ case ICMD_AALOAD:
+
+ case ICMD_BALOAD:
+ case ICMD_CALOAD:
+ case ICMD_SALOAD:
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_new_temp(dst);
+ break;
+
+ /* pop 3 push 0 */
+
+ case ICMD_IASTORE:
+ case ICMD_LASTORE:
+ case ICMD_FASTORE:
+ case ICMD_DASTORE:
+ case ICMD_AASTORE:
+
+ case ICMD_BASTORE:
+ case ICMD_CASTORE:
+ case ICMD_SASTORE:
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_free_temp(src->prev->prev);
+ break;
+
+ /* pop 1 push 0 store */
+
+ case ICMD_ISTORE:
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
+ case ICMD_ASTORE:
+
+ /* pop 1 push 0 */
+
+ case ICMD_POP:
+
+ case ICMD_IRETURN:
+ case ICMD_LRETURN:
+ case ICMD_FRETURN:
+ case ICMD_DRETURN:
+ case ICMD_ARETURN:
+
+ case ICMD_ATHROW:
+
+ case ICMD_PUTSTATIC:
+
+ /* pop 1 push 0 branch */
+
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+
+ case ICMD_IF_LEQ:
+ case ICMD_IF_LNE:
+ case ICMD_IF_LLT:
+ case ICMD_IF_LGE:
+ case ICMD_IF_LGT:
+ case ICMD_IF_LLE:
+
+ /* pop 1 push 0 table branch */
+
+ case ICMD_TABLESWITCH:
+ case ICMD_LOOKUPSWITCH:
+
+ case ICMD_NULLCHECKPOP:
+ case ICMD_MONITORENTER:
+ case ICMD_MONITOREXIT:
+ reg_free_temp(src);
+ break;
+
+ /* pop 2 push 0 branch */
+
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+
+ case ICMD_IF_LCMPEQ:
+ case ICMD_IF_LCMPNE:
+ case ICMD_IF_LCMPLT:
+ case ICMD_IF_LCMPGE:
+ case ICMD_IF_LCMPGT:
+ case ICMD_IF_LCMPLE:
+
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+
+ /* pop 2 push 0 */
+
+ case ICMD_POP2:
+
+ case ICMD_PUTFIELD:
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ break;
+
+ /* pop 0 push 1 dup */
+
+ case ICMD_DUP:
+ reg_new_temp(dst);
+ break;
+
+ /* pop 0 push 2 dup */
+
+ case ICMD_DUP2:
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ break;
+
+ /* pop 2 push 3 dup */
+
+ case ICMD_DUP_X1:
+ reg_new_temp(dst->prev->prev);
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ break;
+
+ /* pop 3 push 4 dup */
+
+ case ICMD_DUP_X2:
+ reg_new_temp(dst->prev->prev->prev);
+ reg_new_temp(dst->prev->prev);
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_free_temp(src->prev->prev);
+ break;
+
+ /* pop 3 push 5 dup */
+
+ case ICMD_DUP2_X1:
+ reg_new_temp(dst->prev->prev->prev->prev);
+ reg_new_temp(dst->prev->prev->prev);
+ reg_new_temp(dst->prev->prev);
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_free_temp(src->prev->prev);
+ break;
+
+ /* pop 4 push 6 dup */
+
+ case ICMD_DUP2_X2:
+ reg_new_temp(dst->prev->prev->prev->prev->prev);
+ reg_new_temp(dst->prev->prev->prev->prev);
+ reg_new_temp(dst->prev->prev->prev);
+ reg_new_temp(dst->prev->prev);
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_free_temp(src->prev->prev);
+ reg_free_temp(src->prev->prev->prev);
+ break;
+
+ /* pop 2 push 2 swap */
+
+ case ICMD_SWAP:
+ reg_new_temp(dst->prev);
+ reg_new_temp(dst);
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IADD:
+ case ICMD_ISUB:
+ case ICMD_IMUL:
+ case ICMD_IDIV:
+ case ICMD_IREM:
+
+ case ICMD_ISHL:
+ case ICMD_ISHR:
+ case ICMD_IUSHR:
+ case ICMD_IAND:
+ case ICMD_IOR:
+ case ICMD_IXOR:
+
+ case ICMD_LADD:
+ case ICMD_LSUB:
+ case ICMD_LMUL:
+ case ICMD_LDIV:
+ case ICMD_LREM:
+
+ case ICMD_LOR:
+ case ICMD_LAND:
+ case ICMD_LXOR:
+
+ case ICMD_LSHL:
+ case ICMD_LSHR:
+ case ICMD_LUSHR:
+
+ case ICMD_FADD:
+ case ICMD_FSUB:
+ case ICMD_FMUL:
+ case ICMD_FDIV:
+ case ICMD_FREM:
+
+ case ICMD_DADD:
+ case ICMD_DSUB:
+ case ICMD_DMUL:
+ case ICMD_DDIV:
+ case ICMD_DREM:
+
+ case ICMD_LCMP:
+ case ICMD_FCMPL:
+ case ICMD_FCMPG:
+ case ICMD_DCMPL:
+ case ICMD_DCMPG:
+ reg_free_temp(src);
+ reg_free_temp(src->prev);
+ reg_new_temp(dst);
+ break;
+
+ /* pop 1 push 1 */
+
+ case ICMD_IADDCONST:
+ case ICMD_ISUBCONST:
+ case ICMD_IMULCONST:
+ case ICMD_IDIVPOW2:
+ case ICMD_IREMPOW2:
+ case ICMD_IREM0X10001:
+ case ICMD_IANDCONST:
+ case ICMD_IORCONST:
+ case ICMD_IXORCONST:
+ case ICMD_ISHLCONST:
+ case ICMD_ISHRCONST:
+ case ICMD_IUSHRCONST:
+
+ case ICMD_LADDCONST:
+ case ICMD_LSUBCONST:
+ case ICMD_LMULCONST:
+ case ICMD_LDIVPOW2:
+ case ICMD_LREMPOW2:
+ case ICMD_LREM0X10001:
+ case ICMD_LANDCONST:
+ case ICMD_LORCONST:
+ case ICMD_LXORCONST:
+ case ICMD_LSHLCONST:
+ case ICMD_LSHRCONST:
+ case ICMD_LUSHRCONST:
+
+ case ICMD_IFEQ_ICONST:
+ case ICMD_IFNE_ICONST:
+ case ICMD_IFLT_ICONST:
+ case ICMD_IFGE_ICONST:
+ case ICMD_IFGT_ICONST:
+ case ICMD_IFLE_ICONST:
+
+ case ICMD_INEG:
+ case ICMD_INT2BYTE:
+ case ICMD_INT2CHAR:
+ case ICMD_INT2SHORT:
+ case ICMD_LNEG:
+ case ICMD_FNEG:
+ case ICMD_DNEG:
+
+ case ICMD_I2L:
+ case ICMD_I2F:
+ case ICMD_I2D:
+ case ICMD_L2I:
+ case ICMD_L2F:
+ case ICMD_L2D:
+ case ICMD_F2I:
+ case ICMD_F2L:
+ case ICMD_F2D:
+ case ICMD_D2I:
+ case ICMD_D2L:
+ case ICMD_D2F:
+
+ case ICMD_CHECKCAST:
+
+ case ICMD_ARRAYLENGTH:
+ case ICMD_INSTANCEOF:
+
+ case ICMD_NEWARRAY:
+ case ICMD_ANEWARRAY:
+
+ case ICMD_GETFIELD:
+ reg_free_temp(src);
+ reg_new_temp(dst);
+ break;
+
+ /* pop 0 push 1 */
+
+ case ICMD_GETSTATIC:
+
+ case ICMD_NEW:
+
+ reg_new_temp(dst);
+ break;
+
+ /* pop many push any */
+
+ case ICMD_INVOKEVIRTUAL:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKESTATIC:
+ case ICMD_INVOKEINTERFACE:
+ {
+ i = iptr->op1;
+ while (--i >= 0) {
+ reg_free_temp(src);
+ src = src->prev;
+ }
+ if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
+ reg_new_temp(dst);
+ break;
+ }
+
+ case ICMD_BUILTIN3:
+ reg_free_temp(src);
+ src = src->prev;
+ case ICMD_BUILTIN2:
+ reg_free_temp(src);
+ src = src->prev;
+ case ICMD_BUILTIN1:
+ reg_free_temp(src);
+ src = src->prev;
+ if (iptr->op1 != TYPE_VOID)
+ reg_new_temp(dst);
+ break;
+
+ case ICMD_MULTIANEWARRAY:
+ i = iptr->op1;
+ while (--i >= 0) {
+ reg_free_temp(src);
+ src = src->prev;
+ }
+ reg_new_temp(dst);
+ break;
+
+ default:
+ printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+ panic("Missing ICMD code during register allocation");
+ } /* switch */
+ iptr++;
+ } /* while instructions */
+ } /* if */
+ bptr++;
+ } /* while blocks */
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/* jit/stack.c *****************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ Parser for JavaVM to intermediate code translation
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1997/11/18
+
+*******************************************************************************/
+
+#define CONDITIONAL_LOADCONST
+
+#ifdef STATISTICS
+#define COUNT(cnt) cnt++
+#else
+#define COUNT(cnt)
+#endif
+
+#define STACKRESET {curstack=0;stackdepth=0;}
+
+#define TYPEPANIC {show_icmd_method();panic("Stack type mismatch");}
+#define CURKIND curstack->varkind
+#define CURTYPE curstack->type
+
+#define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;\
+ new->varkind=v;new->varnum=n;curstack=new;new++;}
+#define NEWSTACKn(s,n) NEWSTACK(s,UNDEFVAR,n)
+#define NEWSTACK0(s) NEWSTACK(s,UNDEFVAR,0)
+#define NEWXSTACK {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
+
+#define SETDST {iptr->dst=curstack;}
+#define POP(s) {if(s!=curstack->type){TYPEPANIC;}\
+ if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+ curstack=curstack->prev;}
+#define POPANY {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+ curstack=curstack->prev;}
+#define COPY(s,d) {(d)->flags=0;(d)->type=(s)->type;\
+ (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
+
+#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
+#define STORE(s) {POP(s);SETDST;stackdepth--;}
+#define OP1_0(s) {POP(s);SETDST;stackdepth--;}
+#define OP1_0ANY {POPANY;SETDST;stackdepth--;}
+#define OP0_1(s) {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define OP1_1(s,d) {POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
+#define OP2_0(s) {POP(s);POP(s);SETDST;stackdepth-=2;}
+#define OPTT2_0(t,b){POP(t);POP(b);SETDST;stackdepth-=2;}
+#define OP2_1(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
+#define OP2IAT_1(s) {POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
+ SETDST;stackdepth--;}
+#define OP2IT_1(s) {POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
+ SETDST;stackdepth--;}
+#define OPTT2_1(s,d){POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
+#define OP2_2(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
+ NEWSTACKn(s,stackdepth-1);SETDST;}
+#define OP3TIA_0(s) {POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
+#define OP3_0(s) {POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
+#define POPMANY(i) {stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
+#define DUP {NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST;\
+ stackdepth++;}
+#define SWAP {COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ curstack=new+1;new+=2;SETDST;}
+#define DUP_X1 {COPY(curstack,new);COPY(curstack,new+2);POPANY;\
+ COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
+ new[1].prev=new;new[2].prev=new+1;\
+ curstack=new+2;new+=3;SETDST;stackdepth++;}
+#define DUP2_X1 {COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
+ COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+ COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
+ new[1].prev=new;new[2].prev=new+1;\
+ new[3].prev=new+2;new[4].prev=new+3;\
+ curstack=new+4;new+=5;SETDST;stackdepth+=2;}
+#define DUP_X2 {COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+ COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ new[2].prev=new+1;new[3].prev=new+2;\
+ curstack=new+3;new+=4;SETDST;stackdepth++;}
+#define DUP2_X2 {COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
+ COPY(curstack,new);COPY(curstack,new+4);POPANY;\
+ COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ new[2].prev=new+1;new[3].prev=new+2;\
+ new[4].prev=new+3;new[5].prev=new+4;\
+ curstack=new+5;new+=6;SETDST;stackdepth+=2;}
+
+#define COPYCURSTACK(copy) {\
+ int d;\
+ stackptr s;\
+ if(curstack){\
+ s=curstack;\
+ new+=stackdepth;\
+ d=stackdepth;\
+ copy=new;\
+ while(s){\
+ copy--;d--;\
+ copy->prev=copy-1;\
+ copy->type=s->type;\
+ copy->flags=0;\
+ copy->varkind=STACKVAR;\
+ copy->varnum=d;\
+ s=s->prev;\
+ }\
+ copy->prev=NULL;\
+ copy=new-1;\
+ }\
+ else\
+ copy=NULL;\
+}
+
+
+#define BBEND(s,i){\
+ i=stackdepth-1;\
+ copy=s;\
+ while(copy){\
+ if((copy->varkind==STACKVAR)&&(copy->varnum>i))\
+ copy->varkind=TEMPVAR;\
+ else {\
+ copy->varkind=STACKVAR;\
+ copy->varnum=i;\
+ }\
+ interfaces[i][copy->type].type = copy->type;\
+ interfaces[i][copy->type].flags |= copy->flags;\
+ i--;copy=copy->prev;\
+ }\
+ i=bptr->indepth-1;\
+ copy=bptr->instack;\
+ while(copy){\
+ interfaces[i][copy->type].type = copy->type;\
+ if(copy->varkind==STACKVAR){\
+ if (copy->flags & SAVEDVAR)\
+ interfaces[i][copy->type].flags |= SAVEDVAR;\
+ }\
+ i--;copy=copy->prev;\
+ }\
+}
+
+
+#define MARKREACHED(b,c) {\
+ if(b->flags<0)\
+ {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;}\
+ else {stackptr s=curstack;stackptr t=b->instack;\
+ if(b->indepth!=stackdepth)\
+ {show_icmd_method();panic("Stack depth mismatch");}\
+ while(s){if (s->type!=t->type)\
+ TYPEPANIC\
+ s=s->prev;t=t->prev;\
+ }\
+ }\
+}
+
+
+static void show_icmd_method();
+
+static void analyse_stack()
+{
+ int b_count, b_index;
+ int stackdepth;
+ stackptr curstack, new, copy;
+ int opcode, i, len, loops;
+ int superblockend, repeat, deadcode;
+ instruction *iptr = instr;
+ basicblock *bptr, *tbptr;
+ s4 *s4ptr;
+
+ arguments_num = 0;
+ new = stack;
+ loops = 0;
+ block[0].flags = BBREACHED;
+ block[0].instack = 0;
+ block[0].indepth = 0;
+
+ for (i = 0; i < exceptiontablelength; i++) {
+ bptr = &block[block_index[extable[i].handlerpc]];
+ bptr->flags = BBREACHED;
+ bptr->type = BBTYPE_EXH;
+ bptr->instack = new;
+ bptr->indepth = 1;
+ bptr->pre_count = 10000;
+ STACKRESET;
+ NEWXSTACK;
+ }
+
+#ifdef CONDITIONAL_LOADCONST
+ b_count = block_count;
+ bptr = block;
+ while (--b_count >= 0) {
+ if (bptr->icount != 0) {
+ iptr = bptr->iinstr + bptr->icount - 1;
+ switch (iptr->opc) {
+ case ICMD_RET:
+ case ICMD_RETURN:
+ case ICMD_IRETURN:
+ case ICMD_LRETURN:
+ case ICMD_FRETURN:
+ case ICMD_DRETURN:
+ case ICMD_ARETURN:
+ case ICMD_ATHROW:
+ break;
+
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ bptr[1].pre_count++;
+ case ICMD_GOTO:
+ block[block_index[iptr->op1]].pre_count++;
+ break;
+
+ case ICMD_TABLESWITCH:
+ s4ptr = iptr->val.a;
+ block[block_index[*s4ptr++]].pre_count++; /* default */
+ i = *s4ptr++; /* low */
+ i = *s4ptr++ - i + 1; /* high */
+ while (--i >= 0) {
+ block[block_index[*s4ptr++]].pre_count++;
+ }
+ break;
+
+ case ICMD_LOOKUPSWITCH:
+ s4ptr = iptr->val.a;
+ block[block_index[*s4ptr++]].pre_count++; /* default */
+ i = *s4ptr++; /* count */
+ while (--i >= 0) {
+ block[block_index[s4ptr[1]]].pre_count++;
+ s4ptr += 2;
+ }
+ break;
+ default:
+ bptr[1].pre_count++;
+ break;
+ }
+ }
+ bptr++;
+ }
+#endif
+
+
+ do {
+ loops++;
+ b_count = block_count;
+ bptr = block;
+ superblockend = true;
+ repeat = false;
+ STACKRESET;
+ deadcode = true;
+ while (--b_count >= 0) {
+ if (bptr->flags == BBDELETED) {
+ /* do nothing */
+ }
+ else if (superblockend && (bptr->flags < BBREACHED))
+ repeat = true;
+ else if (bptr->flags <= BBREACHED) {
+ if (superblockend)
+ stackdepth = bptr->indepth;
+ else if (bptr->flags < BBREACHED) {
+ COPYCURSTACK(copy);
+ bptr->instack = copy;
+ bptr->indepth = stackdepth;
+ }
+ else if (bptr->indepth != stackdepth) {
+ show_icmd_method();
+ panic("Stack depth mismatch");
+
+ }
+ curstack = bptr->instack;
+ deadcode = false;
+ superblockend = false;
+ bptr->flags = BBFINISHED;
+ len = bptr->icount;
+ iptr = bptr->iinstr;
+ b_index = bptr - block;
+ while (--len >= 0) {
+ opcode = iptr->opc;
+ switch (opcode) {
+
+ /* pop 0 push 0 */
+
+ case ICMD_NOP:
+ case ICMD_CHECKASIZE:
+
+ case ICMD_IFEQ_ICONST:
+ case ICMD_IFNE_ICONST:
+ case ICMD_IFLT_ICONST:
+ case ICMD_IFGE_ICONST:
+ case ICMD_IFGT_ICONST:
+ case ICMD_IFLE_ICONST:
+ case ICMD_ELSE_ICONST:
+ SETDST;
+ break;
+
+ case ICMD_RET:
+ locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+ case ICMD_RETURN:
+ COUNT(count_pcmd_return);
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 0 push 1 const */
+
+ case ICMD_ICONST:
+ COUNT(count_pcmd_load);
+ if (len > 0) {
+ switch (iptr[1].opc) {
+ case ICMD_IADD:
+ iptr[0].opc = ICMD_IADDCONST;
+icmd_iconst_tail:
+ iptr[1].opc = ICMD_NOP;
+ OP1_1(TYPE_INT,TYPE_INT);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_ISUB:
+ iptr[0].opc = ICMD_ISUBCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IMUL:
+ iptr[0].opc = ICMD_IMULCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IDIV:
+ if (iptr[0].val.i == 0x00000002)
+ iptr[0].val.i = 1;
+ else if (iptr[0].val.i == 0x00000004)
+ iptr[0].val.i = 2;
+ else if (iptr[0].val.i == 0x00000008)
+ iptr[0].val.i = 3;
+ else if (iptr[0].val.i == 0x00000010)
+ iptr[0].val.i = 4;
+ else if (iptr[0].val.i == 0x00000020)
+ iptr[0].val.i = 5;
+ else if (iptr[0].val.i == 0x00000040)
+ iptr[0].val.i = 6;
+ else if (iptr[0].val.i == 0x00000080)
+ iptr[0].val.i = 7;
+ else if (iptr[0].val.i == 0x00000100)
+ iptr[0].val.i = 8;
+ else if (iptr[0].val.i == 0x00000200)
+ iptr[0].val.i = 9;
+ else if (iptr[0].val.i == 0x00000400)
+ iptr[0].val.i = 10;
+ else if (iptr[0].val.i == 0x00000800)
+ iptr[0].val.i = 11;
+ else if (iptr[0].val.i == 0x00001000)
+ iptr[0].val.i = 12;
+ else if (iptr[0].val.i == 0x00002000)
+ iptr[0].val.i = 13;
+ else if (iptr[0].val.i == 0x00004000)
+ iptr[0].val.i = 14;
+ else if (iptr[0].val.i == 0x00008000)
+ iptr[0].val.i = 15;
+ else if (iptr[0].val.i == 0x00010000)
+ iptr[0].val.i = 16;
+ else if (iptr[0].val.i == 0x00020000)
+ iptr[0].val.i = 17;
+ else if (iptr[0].val.i == 0x00040000)
+ iptr[0].val.i = 18;
+ else if (iptr[0].val.i == 0x00080000)
+ iptr[0].val.i = 19;
+ else if (iptr[0].val.i == 0x00100000)
+ iptr[0].val.i = 20;
+ else if (iptr[0].val.i == 0x00200000)
+ iptr[0].val.i = 21;
+ else if (iptr[0].val.i == 0x00400000)
+ iptr[0].val.i = 22;
+ else if (iptr[0].val.i == 0x00800000)
+ iptr[0].val.i = 23;
+ else if (iptr[0].val.i == 0x01000000)
+ iptr[0].val.i = 24;
+ else if (iptr[0].val.i == 0x02000000)
+ iptr[0].val.i = 25;
+ else if (iptr[0].val.i == 0x04000000)
+ iptr[0].val.i = 26;
+ else if (iptr[0].val.i == 0x08000000)
+ iptr[0].val.i = 27;
+ else if (iptr[0].val.i == 0x10000000)
+ iptr[0].val.i = 28;
+ else if (iptr[0].val.i == 0x20000000)
+ iptr[0].val.i = 29;
+ else if (iptr[0].val.i == 0x40000000)
+ iptr[0].val.i = 30;
+ else if (iptr[0].val.i == 0x80000000)
+ iptr[0].val.i = 31;
+ else {
+ PUSHCONST(TYPE_INT);
+ break;
+ }
+ iptr[0].opc = ICMD_IDIVPOW2;
+ goto icmd_iconst_tail;
+ case ICMD_IREM:
+ if (iptr[0].val.i == 0x10001) {
+ iptr[0].opc = ICMD_IREM0X10001;
+ goto icmd_iconst_tail;
+ }
+ if ((iptr[0].val.i == 0x00000002) ||
+ (iptr[0].val.i == 0x00000004) ||
+ (iptr[0].val.i == 0x00000008) ||
+ (iptr[0].val.i == 0x00000010) ||
+ (iptr[0].val.i == 0x00000020) ||
+ (iptr[0].val.i == 0x00000040) ||
+ (iptr[0].val.i == 0x00000080) ||
+ (iptr[0].val.i == 0x00000100) ||
+ (iptr[0].val.i == 0x00000200) ||
+ (iptr[0].val.i == 0x00000400) ||
+ (iptr[0].val.i == 0x00000800) ||
+ (iptr[0].val.i == 0x00001000) ||
+ (iptr[0].val.i == 0x00002000) ||
+ (iptr[0].val.i == 0x00004000) ||
+ (iptr[0].val.i == 0x00008000) ||
+ (iptr[0].val.i == 0x00010000) ||
+ (iptr[0].val.i == 0x00020000) ||
+ (iptr[0].val.i == 0x00040000) ||
+ (iptr[0].val.i == 0x00080000) ||
+ (iptr[0].val.i == 0x00100000) ||
+ (iptr[0].val.i == 0x00200000) ||
+ (iptr[0].val.i == 0x00400000) ||
+ (iptr[0].val.i == 0x00800000) ||
+ (iptr[0].val.i == 0x01000000) ||
+ (iptr[0].val.i == 0x02000000) ||
+ (iptr[0].val.i == 0x04000000) ||
+ (iptr[0].val.i == 0x08000000) ||
+ (iptr[0].val.i == 0x10000000) ||
+ (iptr[0].val.i == 0x20000000) ||
+ (iptr[0].val.i == 0x40000000) ||
+ (iptr[0].val.i == 0x80000000)) {
+ iptr[0].opc = ICMD_IREMPOW2;
+ iptr[0].val.i -= 1;
+ goto icmd_iconst_tail;
+ }
+ PUSHCONST(TYPE_INT);
+ break;
+ case ICMD_IAND:
+ iptr[0].opc = ICMD_IANDCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IOR:
+ iptr[0].opc = ICMD_IORCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IXOR:
+ iptr[0].opc = ICMD_IXORCONST;
+ goto icmd_iconst_tail;
+ case ICMD_ISHL:
+ iptr[0].opc = ICMD_ISHLCONST;
+ goto icmd_iconst_tail;
+ case ICMD_ISHR:
+ iptr[0].opc = ICMD_ISHRCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IUSHR:
+ iptr[0].opc = ICMD_IUSHRCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IF_ICMPEQ:
+ iptr[0].opc = ICMD_IFEQ;
+icmd_if_icmp_tail:
+ iptr[0].op1 = iptr[1].op1;
+ bptr->icount--;
+ len--;
+ /* iptr[1].opc = ICMD_NOP; */
+ OP1_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ break;
+ case ICMD_IF_ICMPLT:
+ iptr[0].opc = ICMD_IFLT;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPLE:
+ iptr[0].opc = ICMD_IFLE;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPNE:
+ iptr[0].opc = ICMD_IFNE;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPGT:
+ iptr[0].opc = ICMD_IFGT;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPGE:
+ iptr[0].opc = ICMD_IFGE;
+ goto icmd_if_icmp_tail;
+ default:
+ PUSHCONST(TYPE_INT);
+ }
+ }
+ else
+ PUSHCONST(TYPE_INT);
+ break;
+ case ICMD_LCONST:
+ COUNT(count_pcmd_load);
+ if (len > 0) {
+ switch (iptr[1].opc) {
+ case ICMD_LADD:
+ iptr[0].opc = ICMD_LADDCONST;
+icmd_lconst_tail:
+ iptr[1].opc = ICMD_NOP;
+ OP1_1(TYPE_LNG,TYPE_LNG);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_LSUB:
+ iptr[0].opc = ICMD_LSUBCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LMUL:
+ iptr[0].opc = ICMD_LMULCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LDIV:
+ if (iptr[0].val.l == 0x00000002)
+ iptr[0].val.l = 1;
+ else if (iptr[0].val.l == 0x00000004)
+ iptr[0].val.l = 2;
+ else if (iptr[0].val.l == 0x00000008)
+ iptr[0].val.l = 3;
+ else if (iptr[0].val.l == 0x00000010)
+ iptr[0].val.l = 4;
+ else if (iptr[0].val.l == 0x00000020)
+ iptr[0].val.l = 5;
+ else if (iptr[0].val.l == 0x00000040)
+ iptr[0].val.l = 6;
+ else if (iptr[0].val.l == 0x00000080)
+ iptr[0].val.l = 7;
+ else if (iptr[0].val.l == 0x00000100)
+ iptr[0].val.l = 8;
+ else if (iptr[0].val.l == 0x00000200)
+ iptr[0].val.l = 9;
+ else if (iptr[0].val.l == 0x00000400)
+ iptr[0].val.l = 10;
+ else if (iptr[0].val.l == 0x00000800)
+ iptr[0].val.l = 11;
+ else if (iptr[0].val.l == 0x00001000)
+ iptr[0].val.l = 12;
+ else if (iptr[0].val.l == 0x00002000)
+ iptr[0].val.l = 13;
+ else if (iptr[0].val.l == 0x00004000)
+ iptr[0].val.l = 14;
+ else if (iptr[0].val.l == 0x00008000)
+ iptr[0].val.l = 15;
+ else if (iptr[0].val.l == 0x00010000)
+ iptr[0].val.l = 16;
+ else if (iptr[0].val.l == 0x00020000)
+ iptr[0].val.l = 17;
+ else if (iptr[0].val.l == 0x00040000)
+ iptr[0].val.l = 18;
+ else if (iptr[0].val.l == 0x00080000)
+ iptr[0].val.l = 19;
+ else if (iptr[0].val.l == 0x00100000)
+ iptr[0].val.l = 20;
+ else if (iptr[0].val.l == 0x00200000)
+ iptr[0].val.l = 21;
+ else if (iptr[0].val.l == 0x00400000)
+ iptr[0].val.l = 22;
+ else if (iptr[0].val.l == 0x00800000)
+ iptr[0].val.l = 23;
+ else if (iptr[0].val.l == 0x01000000)
+ iptr[0].val.l = 24;
+ else if (iptr[0].val.l == 0x02000000)
+ iptr[0].val.l = 25;
+ else if (iptr[0].val.l == 0x04000000)
+ iptr[0].val.l = 26;
+ else if (iptr[0].val.l == 0x08000000)
+ iptr[0].val.l = 27;
+ else if (iptr[0].val.l == 0x10000000)
+ iptr[0].val.l = 28;
+ else if (iptr[0].val.l == 0x20000000)
+ iptr[0].val.l = 29;
+ else if (iptr[0].val.l == 0x40000000)
+ iptr[0].val.l = 30;
+ else if (iptr[0].val.l == 0x80000000)
+ iptr[0].val.l = 31;
+ else {
+ PUSHCONST(TYPE_LNG);
+ break;
+ }
+ iptr[0].opc = ICMD_LDIVPOW2;
+ goto icmd_lconst_tail;
+ case ICMD_LREM:
+ if (iptr[0].val.l == 0x10001) {
+ iptr[0].opc = ICMD_LREM0X10001;
+ goto icmd_lconst_tail;
+ }
+ if ((iptr[0].val.l == 0x00000002) ||
+ (iptr[0].val.l == 0x00000004) ||
+ (iptr[0].val.l == 0x00000008) ||
+ (iptr[0].val.l == 0x00000010) ||
+ (iptr[0].val.l == 0x00000020) ||
+ (iptr[0].val.l == 0x00000040) ||
+ (iptr[0].val.l == 0x00000080) ||
+ (iptr[0].val.l == 0x00000100) ||
+ (iptr[0].val.l == 0x00000200) ||
+ (iptr[0].val.l == 0x00000400) ||
+ (iptr[0].val.l == 0x00000800) ||
+ (iptr[0].val.l == 0x00001000) ||
+ (iptr[0].val.l == 0x00002000) ||
+ (iptr[0].val.l == 0x00004000) ||
+ (iptr[0].val.l == 0x00008000) ||
+ (iptr[0].val.l == 0x00010000) ||
+ (iptr[0].val.l == 0x00020000) ||
+ (iptr[0].val.l == 0x00040000) ||
+ (iptr[0].val.l == 0x00080000) ||
+ (iptr[0].val.l == 0x00100000) ||
+ (iptr[0].val.l == 0x00200000) ||
+ (iptr[0].val.l == 0x00400000) ||
+ (iptr[0].val.l == 0x00800000) ||
+ (iptr[0].val.l == 0x01000000) ||
+ (iptr[0].val.l == 0x02000000) ||
+ (iptr[0].val.l == 0x04000000) ||
+ (iptr[0].val.l == 0x08000000) ||
+ (iptr[0].val.l == 0x10000000) ||
+ (iptr[0].val.l == 0x20000000) ||
+ (iptr[0].val.l == 0x40000000) ||
+ (iptr[0].val.l == 0x80000000)) {
+ iptr[0].opc = ICMD_LREMPOW2;
+ iptr[0].val.l -= 1;
+ goto icmd_lconst_tail;
+ }
+ PUSHCONST(TYPE_LNG);
+ break;
+ case ICMD_LAND:
+ iptr[0].opc = ICMD_LANDCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LOR:
+ iptr[0].opc = ICMD_LORCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LXOR:
+ iptr[0].opc = ICMD_LXORCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LSHL:
+ iptr[0].opc = ICMD_LSHLCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LSHR:
+ iptr[0].opc = ICMD_LSHRCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LUSHR:
+ iptr[0].opc = ICMD_LUSHRCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LCMP:
+ if ((len > 1) && (iptr[2].val.i == 0)) {
+ switch (iptr[2].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IF_LEQ;
+icmd_lconst_lcmp_tail:
+ iptr[0].op1 = iptr[2].op1;
+ bptr->icount -= 2;
+ len -= 2;
+ /* iptr[1].opc = ICMD_NOP;
+ iptr[2].opc = ICMD_NOP; */
+ OP1_0(TYPE_LNG);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IF_LNE;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IF_LLT;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IF_LGT;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IF_LLE;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IF_LGE;
+ goto icmd_lconst_lcmp_tail;
+ default:
+ PUSHCONST(TYPE_LNG);
+ } /* switch (iptr[2].opc) */
+ } /* if (iptr[2].val.i == 0) */
+ else
+ PUSHCONST(TYPE_LNG);
+ break;
+ default:
+ PUSHCONST(TYPE_LNG);
+ }
+ }
+ else
+ PUSHCONST(TYPE_LNG);
+ break;
+ case ICMD_FCONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_FLT);
+ break;
+ case ICMD_DCONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_DBL);
+ break;
+ case ICMD_ACONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_ADR);
+ break;
+
+ /* pop 0 push 1 load */
+
+ case ICMD_ILOAD:
+ case ICMD_LLOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
+ case ICMD_ALOAD:
+ COUNT(count_load_instruction);
+ i = opcode-ICMD_ILOAD;
+ locals[iptr->op1][i].type = i;
+ LOAD(i, LOCALVAR, iptr->op1);
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IALOAD:
+ case ICMD_LALOAD:
+ case ICMD_FALOAD:
+ case ICMD_DALOAD:
+ case ICMD_AALOAD:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP2IAT_1(opcode-ICMD_IALOAD);
+ break;
+
+ case ICMD_BALOAD:
+ case ICMD_CALOAD:
+ case ICMD_SALOAD:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP2IAT_1(TYPE_INT);
+ break;
+
+ /* pop 0 push 0 iinc */
+
+ case ICMD_IINC:
+#ifdef STATISTICS
+ i = stackdepth;
+ if (i >= 10)
+ count_store_depth[10]++;
+ else
+ count_store_depth[i]++;
+#endif
+ copy = curstack;
+ i = stackdepth - 1;
+ while (copy) {
+ if ((copy->varkind == LOCALVAR) &&
+ (copy->varnum == curstack->varnum)) {
+ copy->varkind = TEMPVAR;
+ copy->varnum = i;
+ }
+ i--;
+ copy = copy->prev;
+ }
+ SETDST;
+ break;
+
+ /* pop 1 push 0 store */
+
+ case ICMD_ISTORE:
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
+ case ICMD_ASTORE:
+ i = opcode-ICMD_ISTORE;
+ locals[iptr->op1][i].type = i;
+#ifdef STATISTICS
+ count_pcmd_store++;
+ i = new - curstack;
+ if (i >= 20)
+ count_store_length[20]++;
+ else
+ count_store_length[i]++;
+ i = stackdepth - 1;
+ if (i >= 10)
+ count_store_depth[10]++;
+ else
+ count_store_depth[i]++;
+#endif
+ copy = curstack->prev;
+ i = stackdepth - 2;
+ while (copy) {
+ if ((copy->varkind == LOCALVAR) &&
+ (copy->varnum == curstack->varnum)) {
+ copy->varkind = TEMPVAR;
+ copy->varnum = i;
+ }
+ i--;
+ copy = copy->prev;
+ }
+ if ((new - curstack) == 1) {
+ curstack->varkind = LOCALVAR;
+ curstack->varnum = iptr->op1;
+ };
+ STORE(opcode-ICMD_ISTORE);
+ break;
+
+ /* pop 3 push 0 */
+
+ case ICMD_IASTORE:
+ case ICMD_LASTORE:
+ case ICMD_FASTORE:
+ case ICMD_DASTORE:
+ case ICMD_AASTORE:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP3TIA_0(opcode-ICMD_IASTORE);
+ break;
+ case ICMD_BASTORE:
+ case ICMD_CASTORE:
+ case ICMD_SASTORE:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP3TIA_0(TYPE_INT);
+ break;
+
+ /* pop 1 push 0 */
+
+ case ICMD_POP:
+ OP1_0ANY;
+ break;
+
+ case ICMD_IRETURN:
+ case ICMD_LRETURN:
+ case ICMD_FRETURN:
+ case ICMD_DRETURN:
+ case ICMD_ARETURN:
+ COUNT(count_pcmd_return);
+ OP1_0(opcode-ICMD_IRETURN);
+ superblockend = true;
+ break;
+
+ case ICMD_ATHROW:
+ COUNT(count_check_null);
+ OP1_0(TYPE_ADR);
+ STACKRESET;
+ SETDST;
+ superblockend = true;
+ break;
+
+ case ICMD_PUTSTATIC:
+ COUNT(count_pcmd_mem);
+ OP1_0(iptr->op1);
+ break;
+
+ /* pop 1 push 0 branch */
+
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+ COUNT(count_pcmd_bra);
+ OP1_0(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+ COUNT(count_pcmd_bra);
+#ifdef CONDITIONAL_LOADCONST
+ {
+ tbptr = block + b_index;
+ if ((b_count >= 3) &&
+ ((b_index + 2) == block_index[iptr[0].op1]) &&
+ (tbptr[1].pre_count == 1) &&
+ (iptr[1].opc == ICMD_ICONST) &&
+ (iptr[2].opc == ICMD_GOTO) &&
+ ((b_index + 3) == block_index[iptr[2].op1]) &&
+ (tbptr[2].pre_count == 1) &&
+ (iptr[3].opc == ICMD_ICONST)) {
+ OP1_1(TYPE_INT, TYPE_INT);
+ switch (iptr[0].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IFNE_ICONST;
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IFEQ_ICONST;
+ break;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IFGE_ICONST;
+ break;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IFLT_ICONST;
+ break;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IFLE_ICONST;
+ break;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IFGT_ICONST;
+ break;
+ }
+ iptr[0].val.i = iptr[1].val.i;
+ iptr[1].opc = ICMD_ELSE_ICONST;
+ iptr[1].val.i = iptr[3].val.i;
+ iptr[2].opc = ICMD_NOP;
+ iptr[3].opc = ICMD_NOP;
+ tbptr[1].flags = BBDELETED;
+ tbptr[2].flags = BBDELETED;
+ tbptr[1].icount = 0;
+ tbptr[2].icount = 0;
+ if (tbptr[3].pre_count == 2) {
+ len += tbptr[3].icount + 3;
+ bptr->icount += tbptr[3].icount + 3;
+ tbptr[3].flags = BBDELETED;
+ tbptr[3].icount = 0;
+ b_index++;
+ }
+ else {
+ bptr->icount++;
+ len ++;
+ }
+ b_index += 2;
+ break;
+ }
+ }
+#endif
+ OP1_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ /* pop 0 push 0 branch */
+
+ case ICMD_GOTO:
+ COUNT(count_pcmd_bra);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 1 push 0 table branch */
+
+ case ICMD_TABLESWITCH:
+ COUNT(count_pcmd_table);
+ OP1_0(TYPE_INT);
+ s4ptr = iptr->val.a;
+ tbptr = block + block_index[*s4ptr++]; /* default */
+ MARKREACHED(tbptr, copy);
+ i = *s4ptr++; /* low */
+ i = *s4ptr++ - i + 1; /* high */
+ while (--i >= 0) {
+ tbptr = block + block_index[*s4ptr++];
+ MARKREACHED(tbptr, copy);
+ }
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 1 push 0 table branch */
+
+ case ICMD_LOOKUPSWITCH:
+ COUNT(count_pcmd_table);
+ OP1_0(TYPE_INT);
+ s4ptr = iptr->val.a;
+ tbptr = block + block_index[*s4ptr++]; /* default */
+ MARKREACHED(tbptr, copy);
+ i = *s4ptr++; /* count */
+ while (--i >= 0) {
+ tbptr = block + block_index[s4ptr[1]];
+ MARKREACHED(tbptr, copy);
+ s4ptr += 2;
+ }
+ SETDST;
+ superblockend = true;
+ break;
+
+ case ICMD_NULLCHECKPOP:
+ case ICMD_MONITORENTER:
+ COUNT(count_check_null);
+ case ICMD_MONITOREXIT:
+ OP1_0(TYPE_ADR);
+ break;
+
+ /* pop 2 push 0 branch */
+
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+ COUNT(count_pcmd_bra);
+ OP2_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ COUNT(count_pcmd_bra);
+ OP2_0(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ /* pop 2 push 0 */
+
+ case ICMD_PUTFIELD:
+ COUNT(count_check_null);
+ COUNT(count_pcmd_mem);
+ OPTT2_0(iptr->op1,TYPE_ADR);
+ break;
+
+ case ICMD_POP2:
+ if (! IS_2_WORD_TYPE(curstack->type)) {
+ OP1_0ANY; /* second pop */
+ }
+ else
+ iptr->opc = ICMD_POP;
+ OP1_0ANY;
+ break;
+
+ /* pop 0 push 1 dup */
+
+ case ICMD_DUP:
+ COUNT(count_dup_instruction);
+ DUP;
+ break;
+
+ case ICMD_DUP2:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ iptr->opc = ICMD_DUP;
+ DUP;
+ }
+ else {
+ copy = curstack;
+ NEWSTACK(copy[-1].type, copy[-1].varkind,
+ copy[-1].varnum);
+ NEWSTACK(copy[ 0].type, copy[ 0].varkind,
+ copy[ 0].varnum);
+ SETDST;
+ stackdepth+=2;
+ }
+ break;
+
+ /* pop 2 push 3 dup */
+
+ case ICMD_DUP_X1:
+ DUP_X1;
+ break;
+
+ case ICMD_DUP2_X1:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ DUP2_X1;
+ }
+ break;
+
+ /* pop 3 push 4 dup */
+
+ case ICMD_DUP_X2:
+ if (IS_2_WORD_TYPE(curstack[-1].type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ DUP_X2;
+ }
+ break;
+
+ case ICMD_DUP2_X2:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ if (IS_2_WORD_TYPE(curstack[-1].type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ iptr->opc = ICMD_DUP_X2;
+ DUP_X2;
+ }
+ }
+ else
+ if (IS_2_WORD_TYPE(curstack[-2].type)) {
+ iptr->opc = ICMD_DUP2_X1;
+ DUP2_X1;
+ }
+ else {
+ DUP2_X2;
+ }
+ break;
+
+ /* pop 2 push 2 swap */
+
+ case ICMD_SWAP:
+ SWAP;
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IDIV:
+ if (!(SUPPORT_DIVISION)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_INT;
+ iptr[0].val.a = (functionptr) asm_builtin_idiv;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_LDIV:
+ if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_LNG;
+ iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_IREM:
+ if (!(SUPPORT_DIVISION)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_INT;
+ iptr[0].val.a = (functionptr) asm_builtin_irem;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_LREM:
+ if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_LNG;
+ iptr[0].val.a = (functionptr) asm_builtin_lrem;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_IADD:
+ case ICMD_ISUB:
+ case ICMD_IMUL:
+
+ case ICMD_ISHL:
+ case ICMD_ISHR:
+ case ICMD_IUSHR:
+ case ICMD_IAND:
+ case ICMD_IOR:
+ case ICMD_IXOR:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_INT);
+ break;
+
+ case ICMD_LADD:
+ case ICMD_LSUB:
+ case ICMD_LMUL:
+
+ case ICMD_LOR:
+ case ICMD_LAND:
+ case ICMD_LXOR:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_LNG);
+ break;
+
+ case ICMD_LSHL:
+ case ICMD_LSHR:
+ case ICMD_LUSHR:
+ COUNT(count_pcmd_op);
+ OP2IT_1(TYPE_LNG);
+ break;
+
+ case ICMD_FADD:
+ case ICMD_FSUB:
+ case ICMD_FMUL:
+ case ICMD_FDIV:
+ case ICMD_FREM:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_FLT);
+ break;
+
+ case ICMD_DADD:
+ case ICMD_DSUB:
+ case ICMD_DMUL:
+ case ICMD_DDIV:
+ case ICMD_DREM:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_DBL);
+ break;
+
+ case ICMD_LCMP:
+ COUNT(count_pcmd_op);
+ if ((len > 0) && (iptr[1].val.i == 0)) {
+ switch (iptr[1].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IF_LCMPEQ;
+icmd_lcmp_if_tail:
+ iptr[0].op1 = iptr[1].op1;
+ len--;
+ bptr->icount--;
+ /* iptr[1].opc = ICMD_NOP; */
+ OP2_0(TYPE_LNG);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IF_LCMPNE;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IF_LCMPLT;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IF_LCMPGT;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IF_LCMPLE;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IF_LCMPGE;
+ goto icmd_lcmp_if_tail;
+ default:
+ OPTT2_1(TYPE_LNG, TYPE_INT);
+ }
+ }
+ else
+ OPTT2_1(TYPE_LNG, TYPE_INT);
+ break;
+ case ICMD_FCMPL:
+ case ICMD_FCMPG:
+ COUNT(count_pcmd_op);
+ OPTT2_1(TYPE_FLT, TYPE_INT);
+ break;
+ case ICMD_DCMPL:
+ case ICMD_DCMPG:
+ COUNT(count_pcmd_op);
+ OPTT2_1(TYPE_DBL, TYPE_INT);
+ break;
+
+ /* pop 1 push 1 */
+
+ case ICMD_INEG:
+ case ICMD_INT2BYTE:
+ case ICMD_INT2CHAR:
+ case ICMD_INT2SHORT:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_INT);
+ break;
+ case ICMD_LNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_LNG);
+ break;
+ case ICMD_FNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_FLT);
+ break;
+ case ICMD_DNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_DBL);
+ break;
+
+ case ICMD_I2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_LNG);
+ break;
+ case ICMD_I2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_FLT);
+ break;
+ case ICMD_I2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_DBL);
+ break;
+ case ICMD_L2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_INT);
+ break;
+ case ICMD_L2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_FLT);
+ break;
+ case ICMD_L2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_DBL);
+ break;
+ case ICMD_F2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_INT);
+ break;
+ case ICMD_F2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_LNG);
+ break;
+ case ICMD_F2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_DBL);
+ break;
+ case ICMD_D2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_INT);
+ break;
+ case ICMD_D2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_LNG);
+ break;
+ case ICMD_D2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_FLT);
+ break;
+
+ case ICMD_CHECKCAST:
+ OP1_1(TYPE_ADR, TYPE_ADR);
+ break;
+
+ case ICMD_ARRAYLENGTH:
+ case ICMD_INSTANCEOF:
+ OP1_1(TYPE_ADR, TYPE_INT);
+ break;
+
+ case ICMD_NEWARRAY:
+ case ICMD_ANEWARRAY:
+ OP1_1(TYPE_INT, TYPE_ADR);
+ break;
+
+ case ICMD_GETFIELD:
+ COUNT(count_check_null);
+ COUNT(count_pcmd_mem);
+ OP1_1(TYPE_ADR, iptr->op1);
+ break;
+
+ /* pop 0 push 1 */
+
+ case ICMD_GETSTATIC:
+ COUNT(count_pcmd_mem);
+ OP0_1(iptr->op1);
+ break;
+
+ case ICMD_NEW:
+ OP0_1(TYPE_ADR);
+ break;
+
+ case ICMD_JSR:
+ OP0_1(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ tbptr->type=BBTYPE_SBR;
+ MARKREACHED(tbptr, copy);
+ OP1_0ANY;
+ break;
+
+ /* pop many push any */
+
+ case ICMD_INVOKEVIRTUAL:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKEINTERFACE:
+ case ICMD_INVOKESTATIC:
+ COUNT(count_pcmd_met);
+ {
+ methodinfo *m = iptr->val.a;
+ if (m->flags & ACC_STATIC)
+ {COUNT(count_check_null);}
+ i = iptr->op1;
+ if (i > arguments_num)
+ arguments_num = i;
+ copy = curstack;
+ while (--i >= 0) {
+ if (! (copy->flags & SAVEDVAR)) {
+ copy->varkind = ARGVAR;
+ copy->varnum = i;
+ }
+ copy = copy->prev;
+ }
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ i = iptr->op1;
+ POPMANY(i);
+ if (m->returntype != TYPE_VOID) {
+ OP0_1(m->returntype);
+ }
+ break;
+ }
+
+ case ICMD_BUILTIN3:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 2;
+ }
+ OP1_0ANY;
+ case ICMD_BUILTIN2:
+builtin2:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 1;
+ }
+ OP1_0ANY;
+ case ICMD_BUILTIN1:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 0;
+ }
+ OP1_0ANY;
+ copy = curstack;
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ if (iptr->op1 != TYPE_VOID)
+ OP0_1(iptr->op1);
+ break;
+
+ case ICMD_MULTIANEWARRAY:
+ i = iptr->op1;
+ if ((i + intreg_argnum) > arguments_num)
+ arguments_num = i + intreg_argnum;
+ copy = curstack;
+ while (--i >= 0) {
+ if (! (copy->flags & SAVEDVAR)) {
+ copy->varkind = ARGVAR;
+ copy->varnum = i + intreg_argnum;
+ }
+ copy = copy->prev;
+ }
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ i = iptr->op1;
+ POPMANY(i);
+ OP0_1(TYPE_ADR);
+ break;
+
+ default:
+ printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+ panic("Missing ICMD code during stack analysis");
+ } /* switch */
+ iptr++;
+ } /* while instructions */
+ bptr->outstack = curstack;
+ bptr->outdepth = stackdepth;
+ BBEND(curstack, i);
+ } /* if */
+ else
+ superblockend = true;
+ bptr++;
+ } /* while blocks */
+ } while (repeat && ! deadcode);
+
+#ifdef STATISTICS
+ if (block_count > count_max_basic_blocks)
+ count_max_basic_blocks = block_count;
+ count_basic_blocks += block_count;
+ if (instr_count > count_max_javainstr)
+ count_max_javainstr = instr_count;
+ count_javainstr += instr_count;
+ if (stack_count > count_upper_bound_new_stack)
+ count_upper_bound_new_stack = stack_count;
+ if ((new - stack) > count_max_new_stack)
+ count_max_new_stack = (new - stack);
+
+ b_count = block_count;
+ bptr = block;
+ while (--b_count >= 0) {
+ if (bptr->flags > BBREACHED) {
+ if (bptr->indepth >= 10)
+ count_block_stack[10]++;
+ else
+ count_block_stack[bptr->indepth]++;
+ len = bptr->icount;
+ if (len <= 10)
+ count_block_size_distribution[len - 1]++;
+ else if (len <= 12)
+ count_block_size_distribution[10]++;
+ else if (len <= 14)
+ count_block_size_distribution[11]++;
+ else if (len <= 16)
+ count_block_size_distribution[12]++;
+ else if (len <= 18)
+ count_block_size_distribution[13]++;
+ else if (len <= 20)
+ count_block_size_distribution[14]++;
+ else if (len <= 25)
+ count_block_size_distribution[15]++;
+ else if (len <= 30)
+ count_block_size_distribution[16]++;
+ else
+ count_block_size_distribution[17]++;
+ }
+ bptr++;
+ }
+
+ if (loops == 1)
+ count_analyse_iterations[0]++;
+ else if (loops == 2)
+ count_analyse_iterations[1]++;
+ else if (loops == 3)
+ count_analyse_iterations[2]++;
+ else if (loops == 4)
+ count_analyse_iterations[3]++;
+ else
+ count_analyse_iterations[4]++;
+
+ if (block_count <= 5)
+ count_method_bb_distribution[0]++;
+ else if (block_count <= 10)
+ count_method_bb_distribution[1]++;
+ else if (block_count <= 15)
+ count_method_bb_distribution[2]++;
+ else if (block_count <= 20)
+ count_method_bb_distribution[3]++;
+ else if (block_count <= 30)
+ count_method_bb_distribution[4]++;
+ else if (block_count <= 40)
+ count_method_bb_distribution[5]++;
+ else if (block_count <= 50)
+ count_method_bb_distribution[6]++;
+ else if (block_count <= 75)
+ count_method_bb_distribution[7]++;
+ else
+ count_method_bb_distribution[8]++;
+#endif
+}
+
+
+static void print_stack(stackptr s) {
+ int i, j;
+ stackptr t;
+
+ i = maxstack;
+ t = s;
+
+ while (t) {
+ i--;
+ t = t->prev;
+ }
+ j = maxstack - i;
+ while (--i >= 0)
+ printf(" ");
+ while (s) {
+ j--;
+ if (s->flags & SAVEDVAR)
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" m%02d", s->regoff);
+ else
+ printf(" r%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" s%02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" l%02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" a%02d", s->varnum);
+ break;
+ default:
+ printf(" !%02d", j);
+ }
+ else
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" M%02d", s->regoff);
+ else
+ printf(" R%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" S%02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" L%02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" A%02d", s->varnum);
+ break;
+ default:
+ printf(" ?%02d", j);
+ }
+ s = s->prev;
+ }
+}
+
+
+static void print_reg(stackptr s) {
+ if (s) {
+ if (s->flags & SAVEDVAR)
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" tm%02d", s->regoff);
+ else
+ printf(" tr%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" s %02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" l %02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" a %02d", s->varnum);
+ break;
+ default:
+ printf(" ! %02d", s->varnum);
+ }
+ else
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" Tm%02d", s->regoff);
+ else
+ printf(" Tr%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" S %02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" L %02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" A %02d", s->varnum);
+ break;
+ default:
+ printf(" ? %02d", s->varnum);
+ }
+ }
+ else
+ printf(" ");
+
+}
+
+
+static char *builtin_name(functionptr bptr)
+{
+ builtin_descriptor *bdesc = builtin_desc;
+ while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+ bdesc++;
+ return bdesc->name;
+}
+
+
+static void show_icmd_method()
+{
+ int b, i, j, last;
+ int deadcode;
+ s4 *s4ptr;
+ instruction *iptr;
+
+ printf("\n");
+ unicode_fprint(stdout, class->name);
+ printf(".");
+ unicode_fprint(stdout, method->name);
+ printf(" ");
+ unicode_fprint(stdout, method->descriptor);
+ printf ("\n\nMax locals: %d\n", (int) maxlocals);
+ printf ("Max stack: %d\n", (int) maxstack);
+
+ printf ("Exceptions:\n");
+ for (i = 0; i < exceptiontablelength; i++) {
+ printf(" L%03d ... ", block_index[extable[i].startpc]);
+ printf("L%03d = ", block_index[extable[i].endpc]);
+ printf("L%03d\n", block_index[extable[i].handlerpc]);
+ }
+
+ printf ("Local Table:\n");
+ for (i = 0; i < maxlocals; i++) {
+ printf(" %3d: ", i);
+ for (j = TYPE_INT; j <= TYPE_ADR; j++)
+ if (locals[i][j].type >= 0) {
+ printf(" (%d) ", j);
+ if (locals[i][j].flags)
+ printf("m");
+ else
+ printf("r");
+ printf("%2d", locals[i][j].regoff);
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ printf ("Interface Table:\n");
+ for (i = 0; i < maxstack; i++) {
+ if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
+ (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
+ (interfaces[i][4].type >= 0)) {
+ printf(" %3d: ", i);
+ for (j = TYPE_INT; j <= TYPE_ADR; j++)
+ if (interfaces[i][j].type >= 0) {
+ printf(" (%d) ", j);
+ if (interfaces[i][j].flags & SAVEDVAR)
+ printf("s");
+ else
+ printf("t");
+ if (interfaces[i][j].flags & INMEMORY)
+ printf("m");
+ else
+ printf("r");
+ printf("%2d", interfaces[i][j].regoff);
+ }
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ if (showdisassemble) {
+ s4ptr = (s4 *) (method->mcode + dseglen);
+ for (i = 0; i < block[0].mpc; i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+
+ for (b = 0; b < block_count; b++)
+ if (block[b].flags != BBDELETED) {
+ deadcode = block[b].flags <= BBREACHED;
+ printf("[");
+ if (deadcode)
+ for (j = maxstack; j > 0; j--)
+ printf(" ? ");
+ else
+ print_stack(block[b].instack);
+ printf("] L%03d(%d):\n", b, block[b].pre_count);
+ iptr = block[b].iinstr;
+ i = iptr - instr;
+ for (last = i + block[b].icount; i < last; i++, iptr++) {
+ printf("[");
+ if (deadcode) {
+ for (j = maxstack; j > 0; j--)
+ printf(" ? ");
+ }
+ else
+ print_stack(iptr->dst);
+ printf("] %4d %s", i, icmd_names[iptr->opc]);
+ switch ((int) iptr->opc) {
+ case ICMD_IADDCONST:
+ case ICMD_ISUBCONST:
+ case ICMD_IMULCONST:
+ case ICMD_IDIVPOW2:
+ case ICMD_IREMPOW2:
+ case ICMD_IREM0X10001:
+ case ICMD_IANDCONST:
+ case ICMD_IORCONST:
+ case ICMD_IXORCONST:
+ case ICMD_ISHLCONST:
+ case ICMD_ISHRCONST:
+ case ICMD_IUSHRCONST:
+ case ICMD_ICONST:
+ case ICMD_ELSE_ICONST:
+ case ICMD_IFEQ_ICONST:
+ case ICMD_IFNE_ICONST:
+ case ICMD_IFLT_ICONST:
+ case ICMD_IFGE_ICONST:
+ case ICMD_IFGT_ICONST:
+ case ICMD_IFLE_ICONST:
+ printf(" %d", iptr->val.i);
+ break;
+ case ICMD_LADDCONST:
+ case ICMD_LSUBCONST:
+ case ICMD_LMULCONST:
+ case ICMD_LDIVPOW2:
+ case ICMD_LREMPOW2:
+ case ICMD_LANDCONST:
+ case ICMD_LORCONST:
+ case ICMD_LXORCONST:
+ case ICMD_LSHLCONST:
+ case ICMD_LSHRCONST:
+ case ICMD_LUSHRCONST:
+ case ICMD_LCONST:
+ printf(" %ld", iptr->val.l);
+ break;
+ case ICMD_FCONST:
+ printf(" %f", iptr->val.f);
+ break;
+ case ICMD_DCONST:
+ printf(" %f", iptr->val.d);
+ break;
+ case ICMD_ACONST:
+ printf(" %p", iptr->val.a);
+ break;
+ case ICMD_GETFIELD:
+ case ICMD_PUTFIELD:
+ printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
+ case ICMD_PUTSTATIC:
+ case ICMD_GETSTATIC:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_IINC:
+ printf(" %d + %d", iptr->op1, iptr->val.i);
+ break;
+ case ICMD_RET:
+ case ICMD_ILOAD:
+ case ICMD_LLOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
+ case ICMD_ALOAD:
+ case ICMD_ISTORE:
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
+ case ICMD_ASTORE:
+ printf(" %d", iptr->op1);
+ break;
+ case ICMD_NEW:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((classinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_NEWARRAY:
+ switch (iptr->op1) {
+ case 4:
+ printf(" boolean");
+ break;
+ case 5:
+ printf(" char");
+ break;
+ case 6:
+ printf(" float");
+ break;
+ case 7:
+ printf(" double");
+ break;
+ case 8:
+ printf(" byte");
+ break;
+ case 9:
+ printf(" short");
+ break;
+ case 10:
+ printf(" int");
+ break;
+ case 11:
+ printf(" long");
+ break;
+ }
+ break;
+ case ICMD_ANEWARRAY:
+ if (iptr->op1) {
+ printf(" ");
+ unicode_fprint(stdout,
+ ((classinfo *) iptr->val.a)->name);
+ }
+ break;
+ case ICMD_CHECKCAST:
+ case ICMD_INSTANCEOF:
+ if (iptr->op1) {
+ classinfo *c = iptr->val.a;
+ if (c->flags & ACC_INTERFACE)
+ printf(" (INTERFACE) ");
+ else
+ printf(" (CLASS,%3d) ", c->vftbl->diffval);
+ unicode_fprint(stdout, c->name);
+ }
+ break;
+ case ICMD_BUILTIN3:
+ case ICMD_BUILTIN2:
+ case ICMD_BUILTIN1:
+ printf(" %s", builtin_name((functionptr) iptr->val.a));
+ break;
+ case ICMD_INVOKEVIRTUAL:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKESTATIC:
+ case ICMD_INVOKEINTERFACE:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((methodinfo *) iptr->val.a)->class->name);
+ printf(".");
+ unicode_fprint(stdout,
+ ((methodinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+ case ICMD_IF_LEQ:
+ case ICMD_IF_LNE:
+ case ICMD_IF_LLT:
+ case ICMD_IF_LGE:
+ case ICMD_IF_LGT:
+ case ICMD_IF_LLE:
+ printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+ break;
+ case ICMD_JSR:
+ case ICMD_GOTO:
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+ case ICMD_IF_LCMPEQ:
+ case ICMD_IF_LCMPNE:
+ case ICMD_IF_LCMPLT:
+ case ICMD_IF_LCMPGE:
+ case ICMD_IF_LCMPGT:
+ case ICMD_IF_LCMPLE:
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ printf(" L%03d", block_index[iptr->op1]);
+ break;
+ case ICMD_TABLESWITCH:
+ s4ptr = iptr->val.a;
+ printf(" L%03d;", block_index[*s4ptr++]); /* default */
+ j = *s4ptr++; /* low */
+ j = *s4ptr++ - j; /* high */
+ while (j >= 0) {
+ printf(" L%03d", block_index[*s4ptr++]);
+ j--;
+ }
+ break;
+ case ICMD_LOOKUPSWITCH:
+ s4ptr = iptr->val.a;
+ printf(" L%d", block_index[*s4ptr++]); /* default */
+ j = *s4ptr++; /* count */
+ while (--j >= 0) {
+ printf(" L%03d", block_index[s4ptr[1]]);
+ s4ptr += 2;
+ }
+ break;
+ }
+ printf("\n");
+ }
+
+ if (showdisassemble && (!deadcode)) {
+ printf("\n");
+ i = block[b].mpc;
+ s4ptr = (s4 *) (method->mcode + dseglen + i);
+ for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+ }
+ i = block[b].mpc;
+ s4ptr = (s4 *) (method->mcode + dseglen + i);
+ if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
+ printf("\n");
+ for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
#include "tables.h"
#include "native.h"
#include "builtin.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
#include "compiler.h"
+#endif
#include "asmpart.h"
#include "threads/thread.h" /* schani */
functionptr f = native_findfunction
(c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
if (f) {
+#ifdef OLD_COMPILER
if (newcompiler)
- m -> stubroutine = ncreatenativestub (f, m);
- else
+#endif
m -> stubroutine = createnativestub (f, m);
+#ifdef OLD_COMPILER
+ else
+ m -> stubroutine = oldcreatenativestub (f, m);
+#endif
}
}
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/******************************* main.c ****************************************
+/* main.c **********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
#include "global.h"
#include "tables.h"
-#include "compiler.h"
-#include "ncomp/ncomp.h"
#include "loader.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
+#include "compiler.h"
+#endif
#include "asmpart.h"
#include "builtin.h"
#endif
-/********************* interne Funktion: get_opt *****************************
+/* internal function: get_opt *************************************************
- liest die n"achste Option aus der Kommandozeile
+ decodes the next command line option
******************************************************************************/
#define OPT_IGNORE 1
#define OPT_CLASSPATH 2
-#define OPT_D 3
-#define OPT_MS 4
-#define OPT_MX 5
-#define OPT_VERBOSE1 6
-#define OPT_VERBOSE 7
-#define OPT_VERBOSEGC 8
-#define OPT_VERBOSECALL 9
+#define OPT_D 3
+#define OPT_MS 4
+#define OPT_MX 5
+#define OPT_VERBOSE1 6
+#define OPT_VERBOSE 7
+#define OPT_VERBOSEGC 8
+#define OPT_VERBOSECALL 9
#define OPT_IEEE 10
#define OPT_SOFTNULL 11
#define OPT_TIME 12
#define OPT_STAT 13
-#define OPT_LOG 14
+#define OPT_LOG 14
#define OPT_CHECK 15
-#define OPT_LOAD 16
-#define OPT_METHOD 17
-#define OPT_SIGNATURE 18
-#define OPT_SHOW 19
-#define OPT_ALL 20
-#define OPT_OLD 21
-
-struct { char *name; bool arg; int value; } opts[] = {
- { "classpath", true, OPT_CLASSPATH },
- { "D", true, OPT_D },
- { "ms", true, OPT_MS },
- { "mx", true, OPT_MX },
- { "noasyncgc", false, OPT_IGNORE },
- { "noverify", false, OPT_IGNORE },
- { "oss", true, OPT_IGNORE },
- { "ss", true, OPT_IGNORE },
- { "v", false, OPT_VERBOSE1 },
- { "verbose", false, OPT_VERBOSE },
- { "verbosegc", false, OPT_VERBOSEGC },
- { "verbosecall", false, OPT_VERBOSECALL },
- { "ieee", false, OPT_IEEE },
- { "softnull", false, OPT_SOFTNULL },
- { "time", false, OPT_TIME },
- { "stat", false, OPT_STAT },
- { "log", true, OPT_LOG },
- { "c", true, OPT_CHECK },
- { "l", false, OPT_LOAD },
- { "m", true, OPT_METHOD },
- { "sig", true, OPT_SIGNATURE },
- { "s", true, OPT_SHOW },
- { "all", false, OPT_ALL },
- { "old", false, OPT_OLD },
- { NULL, false, 0 }
+#define OPT_LOAD 16
+#define OPT_METHOD 17
+#define OPT_SIGNATURE 18
+#define OPT_SHOW 19
+#define OPT_ALL 20
+#ifdef OLD_COMPILER
+#define OPT_OLD 21
+#endif
+
+struct {char *name; bool arg; int value;} opts[] = {
+ {"classpath", true, OPT_CLASSPATH},
+ {"D", true, OPT_D},
+ {"ms", true, OPT_MS},
+ {"mx", true, OPT_MX},
+ {"noasyncgc", false, OPT_IGNORE},
+ {"noverify", false, OPT_IGNORE},
+ {"oss", true, OPT_IGNORE},
+ {"ss", true, OPT_IGNORE},
+ {"v", false, OPT_VERBOSE1},
+ {"verbose", false, OPT_VERBOSE},
+ {"verbosegc", false, OPT_VERBOSEGC},
+ {"verbosecall", false, OPT_VERBOSECALL},
+ {"ieee", false, OPT_IEEE},
+ {"softnull", false, OPT_SOFTNULL},
+ {"time", false, OPT_TIME},
+ {"stat", false, OPT_STAT},
+ {"log", true, OPT_LOG},
+ {"c", true, OPT_CHECK},
+ {"l", false, OPT_LOAD},
+ {"m", true, OPT_METHOD},
+ {"sig", true, OPT_SIGNATURE},
+ {"s", true, OPT_SHOW},
+ {"all", false, OPT_ALL},
+#ifdef OLD_COMPILER
+ {"old", false, OPT_OLD},
+#endif
+ {NULL, false, 0}
};
static int opt_ind = 1;
printf (" s(ync) ...... don't check for synchronization\n");
printf (" -l ................... don't start the class after loading\n");
printf (" -all ................. compile all methods, no execution\n");
+#ifdef OLD_COMPILER
printf (" -old ................. use old JIT compiler\n");
+#endif
printf (" -m ................... compile only a specific method\n");
printf (" -sig ................. specify signature for a specific method\n");
printf (" -s(how)m(ethods) ..... show all methods&fields of a class\n");
- printf (" c(onstants) ... show the constant pool\n");
printf (" a(ssembler) ... show disassembled listing\n");
+ printf (" c(onstants) ... show the constant pool\n");
printf (" d(atasegment).. show data segment listing\n");
- printf (" s(tack) ....... show stack for every javaVM-command\n");
printf (" i(ntermediate). show intermediate representation\n");
+ printf (" m(ethods)...... show class fields and methods\n");
+#ifdef OLD_COMPILER
+ printf (" s(tack) ....... show stack for every javaVM-command\n");
+#endif
printf (" u(nicode) ..... show the unicode - hash\n");
}
for (i = 0; i < c -> methodscount; i++) {
m = &(c->methods[i]);
if (m->jcode) {
+#ifdef OLD_COMPILER
if (newcompiler)
- (void) new_compile(m);
+#endif
+ (void) jit_compile(m);
+#ifdef OLD_COMPILER
else
(void) compiler_compile(m);
+#endif
}
}
c = list_next (&linkedclasses, c);
makeinitializations = false;
break;
+#ifdef OLD_COMPILER
case OPT_OLD:
newcompiler = false;
checknull = true;
break;
+#endif
case OPT_SHOW: /* Anzeigeoptionen */
for (j=0; j<strlen(opt_arg); j++) {
switch (opt_arg[j]) {
- case 'm': showmethods=true; break;
- case 'c': showconstantpool=true; break;
case 'a': showdisassemble=true; compileverbose=true; break;
- case 's': showstack=true; compileverbose=true; break;
+ case 'c': showconstantpool=true; break;
+ case 'd': showddatasegment=true; break;
case 'i': showintermediate=true; compileverbose=true; break;
+ case 'm': showmethods=true; break;
+#ifdef OLD_COMPILER
+ case 's': showstack=true; compileverbose=true; break;
+#endif
case 'u': showunicode=true; break;
default: print_usage();
exit(10);
unicode_init();
heap_init(heapsize, heapstartsize, &dummy);
loader_init();
+#ifdef OLD_COMPILER
compiler_init();
- ncomp_init();
+#endif
+ jit_init();
native_loadclasses ();
m = class_findmethod(topclass,
unicode_new_char(specificmethodname), NULL);
if (!m) panic ("Specific method not found");
+#ifdef OLD_COMPILER
if (newcompiler)
- (void) new_compile(m);
+#endif
+ (void) jit_compile(m);
+#ifdef OLD_COMPILER
else
(void) compiler_compile(m);
+#endif
}
/********************* Debug-Tabellen ausgeben ************************/
heap_close (); /* must be called before compiler_close and
loader_close because finalization occurs
here */
+#ifdef OLD_COMPILER
compiler_close ();
+#endif
loader_close ();
unicode_close ( literalstring_free );
exit(status);
}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
#include "../threads/thread.h" /* schani */
#include "../threads/locks.h"
+#include "../sysdep/threads.h"
+++ /dev/null
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/***************************** ncomp/ncomp.c ***********************************
-
- Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
-
- See file COPYRIGHT for information on usage and disclaimer of warranties.
-
- Contains the functions which translates a JavaVM method into native code.
- This is the new version of the compiler which is a lot faster and has new
- exception handling schemes. The main function is new_comp.
-
- Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
- Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
-
- Last Change: 1997/11/05
-
-*******************************************************************************/
-
-#include "signal.h"
-#include "global.h"
-#include "ncomp/ncomp.h"
-
-#include "loader.h"
-#include "tables.h"
-#include "builtin.h"
-#include "native.h"
-#include "asmpart.h"
-
-#include "threads/thread.h"
-
-
-/*************************** global switches **********************************/
-
-bool compileverbose = false;
-bool showstack = false;
-bool showdisassemble = false;
-bool showddatasegment = false;
-bool showintermediate = false;
-int optimizelevel = 0;
-
-bool checkbounds = true;
-bool checknull = true;
-bool checkfloats = true;
-bool checksync = true;
-
-bool getcompilingtime = false;
-long compilingtime = 0;
-
-int has_ext_instr_set = 0;
-
-bool statistics = false;
-
-int count_jit_calls = 0;
-int count_methods = 0;
-int count_spills = 0;
-int count_pcmd_activ = 0;
-int count_pcmd_drop = 0;
-int count_pcmd_zero = 0;
-int count_pcmd_const_store = 0;
-int count_pcmd_const_alu = 0;
-int count_pcmd_const_bra = 0;
-int count_pcmd_load = 0;
-int count_pcmd_move = 0;
-int count_load_instruction = 0;
-int count_pcmd_store = 0;
-int count_pcmd_store_comb = 0;
-int count_dup_instruction = 0;
-int count_pcmd_op = 0;
-int count_pcmd_mem = 0;
-int count_pcmd_met = 0;
-int count_pcmd_bra = 0;
-int count_pcmd_table = 0;
-int count_pcmd_return = 0;
-int count_pcmd_returnx = 0;
-int count_check_null = 0;
-int count_check_bound = 0;
-int count_max_basic_blocks = 0;
-int count_basic_blocks = 0;
-int count_javainstr = 0;
-int count_max_javainstr = 0;
-int count_javacodesize = 0;
-int count_javaexcsize = 0;
-int count_calls = 0;
-int count_tryblocks = 0;
-int count_code_len = 0;
-int count_data_len = 0;
-int count_cstub_len = 0;
-int count_nstub_len = 0;
-int count_max_new_stack = 0;
-int count_upper_bound_new_stack = 0;
-static int count_block_stack_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-int *count_block_stack = count_block_stack_init;
-static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
-int *count_analyse_iterations = count_analyse_iterations_init;
-static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
-int *count_method_bb_distribution = count_method_bb_distribution_init;
-static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-int *count_block_size_distribution = count_block_size_distribution_init;
-static int count_store_length_init[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-int *count_store_length = count_store_length_init;
-static int count_store_depth_init[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-int *count_store_depth = count_store_depth_init;
-
-
-/*********************** include compiler data types **************************/
-
-#include "ncomp/ncompdef.h"
-
-
-/*********************** global compiler variables ****************************/
-
- /* data about the currently compiled method */
-
-static classinfo *class; /* class the compiled method belongs to */
-static methodinfo *method; /* pointer to method info of compiled method */
-static unicode *descriptor; /* type descriptor of compiled method */
-static u2 mparamcount; /* number of parameters (incl. this) */
-static u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
-static u2 mreturntype; /* return type of method */
-
-static int maxstack; /* maximal JavaVM stack size */
-static int maxlocals; /* maximal number of local JavaVM variables */
-static int jcodelength; /* length of JavaVM-codes */
-static u1 *jcode; /* pointer to start of JavaVM-code */
-static int exceptiontablelength;/* length of exception table */
-static exceptiontable *extable; /* pointer to start of exception table */
-
-static int block_count; /* number of basic blocks */
-static basicblock *block; /* points to basic block array */
-static int *block_index; /* a table which contains for every byte of */
- /* JavaVM code a basic block index if at this */
- /* byte there is the start of a basic block */
-
-static int instr_count; /* number of JavaVM instructions */
-static instruction *instr; /* points to intermediate code instructions */
-
-static int stack_count; /* number of stack elements */
-static stackelement *stack; /* points to intermediate code instructions */
-
-static bool isleafmethod; /* true if a method doesn't call subroutines */
-
-/* list of all classes used by the compiled method which have to be */
-/* initialised (if not already done) before execution of this method */
-
-static chain *uninitializedclasses;
-
-
-/******************** include compiler subsystems *****************************/
-
-#include "sysdep/ngen.h" /* code generator header file */
-#include "ncomp/ntools.c" /* compiler tool functions */
-#include "ncomp/mcode.c" /* code generation tool functions */
-#include "sysdep/disass.c" /* disassembler (for debug purposes only) */
-#include "ncomp/nparse.c" /* parsing of JavaVM code */
-#include "ncomp/nreg.c" /* register allocation and support routines */
-#include "ncomp/nstack.c" /* analysing the stack operations */
-#include "sysdep/ngen.c" /* code generator */
-
-
-
-
-/* dummy function, used when there is no JavaVM code available */
-
-static void* do_nothing_function()
-{
- return NULL;
-}
-
-
-/*******************************************************************************
-
- new_compile, new version of compiler, translates one method to machine code
-
-*******************************************************************************/
-
-methodptr new_compile(methodinfo *m)
-{
- int dumpsize;
- long starttime = 0;
- long stoptime = 0;
-
- /* if method has been already compiled return immediately */
-
- count_jit_calls++;
-
- if (m->entrypoint)
- return m->entrypoint;
-
- count_methods++;
-
- intsDisable(); /* disable interrupts */
-
-
- /* mark start of dump memory area */
-
- dumpsize = dump_size ();
-
- /* measure time */
-
- if (getcompilingtime)
- starttime = getcputime();
-
- /* if there is no javacode print error message and return empty method */
-
- if (! m->jcode) {
- sprintf(logtext, "No code given for: ");
- unicode_sprint(logtext+strlen(logtext), m->class->name);
- strcpy(logtext+strlen(logtext), ".");
- unicode_sprint(logtext+strlen(logtext), m->name);
- unicode_sprint(logtext+strlen(logtext), m->descriptor);
- dolog();
- intsRestore(); /* enable interrupts again */
- return (methodptr) do_nothing_function; /* return empty method */
- }
-
- /* print log message for compiled method */
-
- if (compileverbose) {
- sprintf(logtext, "Compiling: ");
- unicode_sprint(logtext+strlen(logtext), m->class->name);
- strcpy(logtext+strlen(logtext), ".");
- unicode_sprint(logtext+strlen(logtext), m->name);
- unicode_sprint(logtext+strlen(logtext), m->descriptor);
- dolog ();
- }
-
-
- /* initialisation of variables and subsystems */
-
- isleafmethod = true;
-
- method = m;
- class = m->class;
- descriptor = m->descriptor;
- maxstack = m->maxstack;
- maxlocals = m->maxlocals;
- jcodelength = m->jcodelength;
- jcode = m->jcode;
- exceptiontablelength = m->exceptiontablelength;
- extable = m->exceptiontable;
-
-#ifdef STATISTICS
- count_tryblocks += exceptiontablelength;
- count_javacodesize += jcodelength + 18;
- count_javaexcsize += exceptiontablelength * 8;
-#endif
-
- /* initialise parameter type descriptor */
-
- descriptor2types (m);
- mreturntype = m->returntype;
- mparamcount = m->paramcount;
- mparamtypes = m->paramtypes;
-
- /* initialize class list with class the compiled method belongs to */
-
- uninitializedclasses = chain_new();
- compiler_addinitclass (m->class);
-
-
- /********************** call the compiler passes **************************/
-
- reg_init();
- local_init();
- mcode_init();
-
- if (runverbose)
- allocate_literals();
-
- parse();
-
- analyse_stack();
-
- interface_regalloc();
-
- allocate_scratch_registers();
-
- local_regalloc();
-
- gen_mcode();
-
-
- /*********** Zwischendarstellungen auf Wunsch ausgeben **********/
-
- if (showintermediate)
- show_icmd_method();
- else if (showdisassemble)
- disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
-
- if (showddatasegment)
- dseg_display((void*) (m->mcode));
-
-
-
- /* release dump area */
-
- dump_release (dumpsize);
-
- /* measure time */
-
- if (getcompilingtime) {
- stoptime = getcputime();
- compilingtime += (stoptime-starttime);
- }
-
- /* initialize all used classes */
- /* because of reentrant code global variables are not allowed here */
-
- {
- chain *ul = uninitializedclasses; /* list of uninitialized classes */
- classinfo *c; /* single class */
-
- while ((c = chain_first(ul)) != NULL) {
- chain_remove (ul);
- class_init (c); /* may again call the compiler */
- }
- chain_free (ul);
- }
-
- intsRestore(); /* enable interrupts again */
-
- /* return pointer to the methods entry point */
-
- return m -> entrypoint;
-}
-
-
-/************ functions for compiler initialisation and finalisation **********/
-
-void ncomp_init ()
-{
- int i;
-
- has_ext_instr_set = ! has_no_x_instr_set();
-
- for (i = 0; i < 256; i++)
- stackreq[i] = 1;
-
- stackreq[JAVA_NOP] = 0;
- stackreq[JAVA_ISTORE] = 0;
- stackreq[JAVA_LSTORE] = 0;
- stackreq[JAVA_FSTORE] = 0;
- stackreq[JAVA_DSTORE] = 0;
- stackreq[JAVA_ASTORE] = 0;
- stackreq[JAVA_ISTORE_0] = 0;
- stackreq[JAVA_ISTORE_1] = 0;
- stackreq[JAVA_ISTORE_2] = 0;
- stackreq[JAVA_ISTORE_3] = 0;
- stackreq[JAVA_LSTORE_0] = 0;
- stackreq[JAVA_LSTORE_1] = 0;
- stackreq[JAVA_LSTORE_2] = 0;
- stackreq[JAVA_LSTORE_3] = 0;
- stackreq[JAVA_FSTORE_0] = 0;
- stackreq[JAVA_FSTORE_1] = 0;
- stackreq[JAVA_FSTORE_2] = 0;
- stackreq[JAVA_FSTORE_3] = 0;
- stackreq[JAVA_DSTORE_0] = 0;
- stackreq[JAVA_DSTORE_1] = 0;
- stackreq[JAVA_DSTORE_2] = 0;
- stackreq[JAVA_DSTORE_3] = 0;
- stackreq[JAVA_ASTORE_0] = 0;
- stackreq[JAVA_ASTORE_1] = 0;
- stackreq[JAVA_ASTORE_2] = 0;
- stackreq[JAVA_ASTORE_3] = 0;
- stackreq[JAVA_IASTORE] = 0;
- stackreq[JAVA_LASTORE] = 0;
- stackreq[JAVA_FASTORE] = 0;
- stackreq[JAVA_DASTORE] = 0;
- stackreq[JAVA_AASTORE] = 0;
- stackreq[JAVA_BASTORE] = 0;
- stackreq[JAVA_CASTORE] = 0;
- stackreq[JAVA_SASTORE] = 0;
- stackreq[JAVA_POP] = 0;
- stackreq[JAVA_POP2] = 0;
- stackreq[JAVA_IINC] = 0;
- stackreq[JAVA_IFEQ] = 0;
- stackreq[JAVA_IFNE] = 0;
- stackreq[JAVA_IFLT] = 0;
- stackreq[JAVA_IFGE] = 0;
- stackreq[JAVA_IFGT] = 0;
- stackreq[JAVA_IFLE] = 0;
- stackreq[JAVA_IF_ICMPEQ] = 0;
- stackreq[JAVA_IF_ICMPNE] = 0;
- stackreq[JAVA_IF_ICMPLT] = 0;
- stackreq[JAVA_IF_ICMPGE] = 0;
- stackreq[JAVA_IF_ICMPGT] = 0;
- stackreq[JAVA_IF_ICMPLE] = 0;
- stackreq[JAVA_IF_ACMPEQ] = 0;
- stackreq[JAVA_IF_ACMPNE] = 0;
- stackreq[JAVA_GOTO] = 0;
- stackreq[JAVA_RET] = 0;
- stackreq[JAVA_TABLESWITCH] = 0;
- stackreq[ICMD_LOOKUPSWITCH] = 0;
- stackreq[JAVA_IRETURN] = 0;
- stackreq[JAVA_LRETURN] = 0;
- stackreq[JAVA_FRETURN] = 0;
- stackreq[JAVA_DRETURN] = 0;
- stackreq[JAVA_ARETURN] = 0;
- stackreq[JAVA_RETURN] = 0;
- stackreq[JAVA_PUTSTATIC] = 0;
- stackreq[JAVA_PUTFIELD] = 0;
- stackreq[JAVA_MONITORENTER] = 0;
- stackreq[ICMD_MONITOREXIT] = 0;
- stackreq[JAVA_WIDE] = 0;
- stackreq[JAVA_IFNULL] = 0;
- stackreq[JAVA_IFNONNULL] = 0;
- stackreq[JAVA_GOTO_W] = 0;
- stackreq[JAVA_BREAKPOINT] = 0;
-
- stackreq[JAVA_SWAP] = 2;
- stackreq[JAVA_DUP2] = 2;
- stackreq[JAVA_DUP_X1] = 3;
- stackreq[JAVA_DUP_X2] = 4;
- stackreq[JAVA_DUP2_X1] = 3;
- stackreq[JAVA_DUP2_X2] = 4;
-
- for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
-
- for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
-
- if (stdopdescriptortable[i].isfloat && checkfloats) {
- stdopdescriptortable[i].supported = false;
- }
-
- stdopdescriptors[stdopdescriptortable[i].opcode] =
- &(stdopdescriptortable[i]);
- }
-
- init_exceptions();
-}
-
-
-void ncomp_close()
-{
-/* mcode_close(); */
-}
-
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/******************************* main.c ****************************************
+/* main.c **********************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
#include "global.h"
#include "tables.h"
-#include "compiler.h"
-#include "ncomp/ncomp.h"
#include "loader.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
+#include "compiler.h"
+#endif
#include "asmpart.h"
#include "builtin.h"
#endif
-/********************* interne Funktion: get_opt *****************************
+/* internal function: get_opt *************************************************
- liest die n"achste Option aus der Kommandozeile
+ decodes the next command line option
******************************************************************************/
#define OPT_IGNORE 1
#define OPT_CLASSPATH 2
-#define OPT_D 3
-#define OPT_MS 4
-#define OPT_MX 5
-#define OPT_VERBOSE1 6
-#define OPT_VERBOSE 7
-#define OPT_VERBOSEGC 8
-#define OPT_VERBOSECALL 9
+#define OPT_D 3
+#define OPT_MS 4
+#define OPT_MX 5
+#define OPT_VERBOSE1 6
+#define OPT_VERBOSE 7
+#define OPT_VERBOSEGC 8
+#define OPT_VERBOSECALL 9
#define OPT_IEEE 10
#define OPT_SOFTNULL 11
#define OPT_TIME 12
#define OPT_STAT 13
-#define OPT_LOG 14
+#define OPT_LOG 14
#define OPT_CHECK 15
-#define OPT_LOAD 16
-#define OPT_METHOD 17
-#define OPT_SIGNATURE 18
-#define OPT_SHOW 19
-#define OPT_ALL 20
-#define OPT_OLD 21
-
-struct { char *name; bool arg; int value; } opts[] = {
- { "classpath", true, OPT_CLASSPATH },
- { "D", true, OPT_D },
- { "ms", true, OPT_MS },
- { "mx", true, OPT_MX },
- { "noasyncgc", false, OPT_IGNORE },
- { "noverify", false, OPT_IGNORE },
- { "oss", true, OPT_IGNORE },
- { "ss", true, OPT_IGNORE },
- { "v", false, OPT_VERBOSE1 },
- { "verbose", false, OPT_VERBOSE },
- { "verbosegc", false, OPT_VERBOSEGC },
- { "verbosecall", false, OPT_VERBOSECALL },
- { "ieee", false, OPT_IEEE },
- { "softnull", false, OPT_SOFTNULL },
- { "time", false, OPT_TIME },
- { "stat", false, OPT_STAT },
- { "log", true, OPT_LOG },
- { "c", true, OPT_CHECK },
- { "l", false, OPT_LOAD },
- { "m", true, OPT_METHOD },
- { "sig", true, OPT_SIGNATURE },
- { "s", true, OPT_SHOW },
- { "all", false, OPT_ALL },
- { "old", false, OPT_OLD },
- { NULL, false, 0 }
+#define OPT_LOAD 16
+#define OPT_METHOD 17
+#define OPT_SIGNATURE 18
+#define OPT_SHOW 19
+#define OPT_ALL 20
+#ifdef OLD_COMPILER
+#define OPT_OLD 21
+#endif
+
+struct {char *name; bool arg; int value;} opts[] = {
+ {"classpath", true, OPT_CLASSPATH},
+ {"D", true, OPT_D},
+ {"ms", true, OPT_MS},
+ {"mx", true, OPT_MX},
+ {"noasyncgc", false, OPT_IGNORE},
+ {"noverify", false, OPT_IGNORE},
+ {"oss", true, OPT_IGNORE},
+ {"ss", true, OPT_IGNORE},
+ {"v", false, OPT_VERBOSE1},
+ {"verbose", false, OPT_VERBOSE},
+ {"verbosegc", false, OPT_VERBOSEGC},
+ {"verbosecall", false, OPT_VERBOSECALL},
+ {"ieee", false, OPT_IEEE},
+ {"softnull", false, OPT_SOFTNULL},
+ {"time", false, OPT_TIME},
+ {"stat", false, OPT_STAT},
+ {"log", true, OPT_LOG},
+ {"c", true, OPT_CHECK},
+ {"l", false, OPT_LOAD},
+ {"m", true, OPT_METHOD},
+ {"sig", true, OPT_SIGNATURE},
+ {"s", true, OPT_SHOW},
+ {"all", false, OPT_ALL},
+#ifdef OLD_COMPILER
+ {"old", false, OPT_OLD},
+#endif
+ {NULL, false, 0}
};
static int opt_ind = 1;
printf (" s(ync) ...... don't check for synchronization\n");
printf (" -l ................... don't start the class after loading\n");
printf (" -all ................. compile all methods, no execution\n");
+#ifdef OLD_COMPILER
printf (" -old ................. use old JIT compiler\n");
+#endif
printf (" -m ................... compile only a specific method\n");
printf (" -sig ................. specify signature for a specific method\n");
printf (" -s(how)m(ethods) ..... show all methods&fields of a class\n");
- printf (" c(onstants) ... show the constant pool\n");
printf (" a(ssembler) ... show disassembled listing\n");
+ printf (" c(onstants) ... show the constant pool\n");
printf (" d(atasegment).. show data segment listing\n");
- printf (" s(tack) ....... show stack for every javaVM-command\n");
printf (" i(ntermediate). show intermediate representation\n");
+ printf (" m(ethods)...... show class fields and methods\n");
+#ifdef OLD_COMPILER
+ printf (" s(tack) ....... show stack for every javaVM-command\n");
+#endif
printf (" u(nicode) ..... show the unicode - hash\n");
}
for (i = 0; i < c -> methodscount; i++) {
m = &(c->methods[i]);
if (m->jcode) {
+#ifdef OLD_COMPILER
if (newcompiler)
- (void) new_compile(m);
+#endif
+ (void) jit_compile(m);
+#ifdef OLD_COMPILER
else
(void) compiler_compile(m);
+#endif
}
}
c = list_next (&linkedclasses, c);
makeinitializations = false;
break;
+#ifdef OLD_COMPILER
case OPT_OLD:
newcompiler = false;
checknull = true;
break;
+#endif
case OPT_SHOW: /* Anzeigeoptionen */
for (j=0; j<strlen(opt_arg); j++) {
switch (opt_arg[j]) {
- case 'm': showmethods=true; break;
- case 'c': showconstantpool=true; break;
case 'a': showdisassemble=true; compileverbose=true; break;
- case 's': showstack=true; compileverbose=true; break;
+ case 'c': showconstantpool=true; break;
+ case 'd': showddatasegment=true; break;
case 'i': showintermediate=true; compileverbose=true; break;
+ case 'm': showmethods=true; break;
+#ifdef OLD_COMPILER
+ case 's': showstack=true; compileverbose=true; break;
+#endif
case 'u': showunicode=true; break;
default: print_usage();
exit(10);
unicode_init();
heap_init(heapsize, heapstartsize, &dummy);
loader_init();
+#ifdef OLD_COMPILER
compiler_init();
- ncomp_init();
+#endif
+ jit_init();
native_loadclasses ();
m = class_findmethod(topclass,
unicode_new_char(specificmethodname), NULL);
if (!m) panic ("Specific method not found");
+#ifdef OLD_COMPILER
if (newcompiler)
- (void) new_compile(m);
+#endif
+ (void) jit_compile(m);
+#ifdef OLD_COMPILER
else
(void) compiler_compile(m);
+#endif
}
/********************* Debug-Tabellen ausgeben ************************/
heap_close (); /* must be called before compiler_close and
loader_close because finalization occurs
here */
+#ifdef OLD_COMPILER
compiler_close ();
+#endif
loader_close ();
unicode_close ( literalstring_free );
exit(status);
}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
-/****************************** headers.c **************************************
+/* headers.c *******************************************************************
Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
u1 *createcompilerstub (methodinfo *m) {return NULL;}
u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
-u1 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
+u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
void removecompilerstub (u1 *stub) {}
void removenativestub (u1 *stub) {}
}
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
*******************************************************************************/
#ifndef __global_h_
-#define __global_h_ /* schani */
+#define __global_h_
-#define STATISTICS /* andi */
+#define OLD_COMPILER /* if enabled makes old compiler available */
+
+#define STATISTICS /* if enabled collects program statistics */
/* JIT_MARKER_SUPPORT is the define used to toggle Just-in-time generated
- marker functions on and off. */
-#undef JIT_MARKER_SUPPORT /* phil */
+ marker functions on and off.
+*/
+#undef JIT_MARKER_SUPPORT /* phil */
/* standard includes **********************************************************/
--- /dev/null
+/* jit/parse.c *****************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ Parser for JavaVM to intermediate code translation
+
+ Author: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1998/05/07
+
+*******************************************************************************/
+
+#include "math.h"
+
+
+/* macros for byte code fetching ***********************************************
+
+ fetch a byte code of given size from position pos
+
+*******************************************************************************/
+
+#define code_get_u1(pos) jcode[pos]
+#define code_get_s1(pos) ((s1)jcode[pos])
+#define code_get_u2(pos) ((((u2)jcode[pos])<<8)+jcode[pos+1])
+#define code_get_s2(pos) ((s2)((((u2)jcode[pos])<<8)+jcode[pos+1]))
+#define code_get_u4(pos) ((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+ (((u4)jcode[pos+2])<<8)+jcode[pos+3])
+#define code_get_s4(pos) ((s4)((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
+ (((u4)jcode[pos+2])<<8)+jcode[pos+3]))
+
+
+/* functionc compiler_addinitclass *********************************************
+
+ add class into the list of classes to initialize
+
+*******************************************************************************/
+
+static void compiler_addinitclass (classinfo *c)
+{
+ classinfo *cl;
+
+ if (c->initialized) return;
+
+ cl = chain_first(uninitializedclasses);
+ if (cl == c)
+ return;
+
+ if (cl == class)
+ cl = chain_next(uninitializedclasses);
+ for (;;) {
+ if (cl == c)
+ return;
+ if (cl == NULL) {
+ if (runverbose) {
+ sprintf(logtext, "compiler_addinitclass: ");
+ unicode_sprint(logtext+strlen(logtext), c->name);
+ dolog();
+ }
+ chain_addlast(uninitializedclasses, c);
+ return;
+ }
+ if (c < cl) {
+ if (runverbose) {
+ sprintf(logtext, "compiler_addinitclass: ");
+ unicode_sprint(logtext+strlen(logtext), c->name);
+ dolog();
+ }
+ chain_addbefore(uninitializedclasses, c);
+ return;
+ }
+ cl = chain_next(uninitializedclasses);
+ }
+}
+
+
+/* function descriptor2types ***************************************************
+
+ decodes a already checked method descriptor. The parameter count, the
+ return type and the argument types are stored in the passed methodinfo.
+
+*******************************************************************************/
+
+static void descriptor2types (methodinfo *m)
+{
+ u1 *types, *tptr;
+ int pcount, c;
+ u2 *cptr;
+
+ pcount = 0;
+ types = DMNEW (u1, m->descriptor->length);
+
+ tptr = types;
+ if (!(m->flags & ACC_STATIC)) {
+ *tptr++ = TYPE_ADR;
+ pcount++;
+ }
+
+ cptr = m->descriptor->text;
+ cptr++;
+ while ((c = *cptr++) != ')') {
+ pcount++;
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': *tptr++ = TYPE_INT;
+ break;
+ case 'J': *tptr++ = TYPE_LNG;
+ break;
+ case 'F': *tptr++ = TYPE_FLT;
+ break;
+ case 'D': *tptr++ = TYPE_DBL;
+ break;
+ case 'L': *tptr++ = TYPE_ADR;
+ while (*cptr++ != ';');
+ break;
+ case '[': *tptr++ = TYPE_ADR;
+ while (c == '[')
+ c = *cptr++;
+ if (c == 'L')
+ while (*cptr++ != ';') /* skip */;
+ break;
+ default: panic ("Ill formed methodtype-descriptor");
+ }
+ }
+
+ /* compute return type */
+
+ switch (*cptr) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': m->returntype = TYPE_INT;
+ break;
+ case 'J': m->returntype = TYPE_LNG;
+ break;
+ case 'F': m->returntype = TYPE_FLT;
+ break;
+ case 'D': m->returntype = TYPE_DBL;
+ break;
+ case '[':
+ case 'L': m->returntype = TYPE_ADR;
+ break;
+ case 'V': m->returntype = TYPE_VOID;
+ break;
+
+ default: panic ("Ill formed methodtype-descriptor");
+ }
+
+ m->paramcount = pcount;
+ m->paramtypes = types;
+}
+
+
+/* function allocate_literals **************************************************
+
+ Scans the JavaVM code of a method and allocates string literals. Needed
+ to generate the same addresses as the old JIT compiler.
+
+*******************************************************************************/
+
+static void allocate_literals()
+{
+ int p, nextp;
+ int opcode, i;
+ s4 num;
+ unicode *s;
+
+ for (p = 0; p < jcodelength; p = nextp) {
+
+ opcode = jcode[p];
+ nextp = p + jcommandsize[opcode];
+
+ switch (opcode) {
+ case JAVA_WIDE:
+ if (code_get_u1(p + 1) == JAVA_IINC)
+ nextp = p + 6;
+ else
+ nextp = p + 4;
+ break;
+
+ case JAVA_LOOKUPSWITCH:
+ nextp = ALIGN((p + 1), 4);
+ num = code_get_u4(nextp + 4);
+ nextp = nextp + 8 + 8 * num;
+ break;
+
+ case JAVA_TABLESWITCH:
+ nextp = ALIGN ((p + 1),4);
+ num = code_get_s4(nextp + 4);
+ num = code_get_s4(nextp + 8) - num;
+ nextp = nextp + 16 + 4 * num;
+ break;
+
+ case JAVA_LDC1:
+ i = code_get_u1(p+1);
+ goto pushconstantitem;
+ case JAVA_LDC2:
+ case JAVA_LDC2W:
+ i = code_get_u2(p + 1);
+ pushconstantitem:
+ if (class_constanttype(class, i) == CONSTANT_String) {
+ s = class_getconstant(class, i, CONSTANT_String);
+ (void) literalstring_new(s);
+ }
+ break;
+ } /* end switch */
+ } /* end while */
+}
+
+
+
+/*******************************************************************************
+
+ function 'parse' scans the JavaVM code and generates intermediate code
+
+ During parsing the block index table is used to store at bit pos 0
+ a flag which marks basic block starts and at position 1 to 31 the
+ intermediate instruction index. After parsing the block index table
+ is scanned, for marked positions a block is generated and the block
+ number is stored in the block index table.
+
+*******************************************************************************/
+
+/* intermediate code generating macros */
+
+#define PINC iptr++;ipc++
+#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
+#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
+#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
+#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
+#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
+#define OP(o) iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
+#define OP1(o,o1) iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
+#define OP2I(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
+#define OP2A(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
+#define BUILTIN1(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+#define BUILTIN2(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+#define BUILTIN3(v,t) isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
+ iptr->val.a=(v);PINC
+
+
+/* block generating and checking macros */
+
+#define block_insert(i) {if(!(block_index[i]&1))\
+ {b_count++;block_index[i] |= 1;}}
+#define bound_check(i) {if((i< 0) || (i>=jcodelength)) \
+ panic("branch target out of code-boundary");}
+#define bound_check1(i) {if((i< 0) || (i>jcodelength)) \
+ panic("branch target out of code-boundary");}
+
+
+static void parse()
+{
+ int p; /* java instruction counter */
+ int nextp; /* start of next java instruction */
+ int opcode; /* java opcode */
+ int i; /* temporary for different uses (counters) */
+ int ipc = 0; /* intermediate instruction counter */
+ int b_count = 0; /* basic block counter */
+ int s_count = 0; /* stack element counter */
+ bool blockend = false; /* true if basic block end has reached */
+ bool iswide = false; /* true if last instruction was a wide */
+ instruction *iptr; /* current pointer into instruction array */
+
+
+ /* allocate instruction array and block index table */
+
+ /* 1 additional for end ipc and 3 for loop unrolling */
+
+ block_index = DMNEW(int, jcodelength + 3);
+
+ /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
+ /* additional MONITOREXITS are reached by branches which are 3 bytes */
+
+ iptr = instr = DMNEW(instruction, jcodelength + 5);
+
+ /* initialize block_index table (unrolled four times) */
+
+ {
+ int *ip;
+
+ for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
+ ip[0] = 0;
+ ip[1] = 0;
+ ip[2] = 0;
+ ip[3] = 0;
+ }
+ }
+
+ /* compute branch targets of exception table */
+
+ for (i = 0; i < exceptiontablelength; i++) {
+ p = extable[i].startpc;
+ bound_check(p);
+ block_insert(p);
+ p = extable[i].endpc;
+ bound_check1(p);
+ if (p < jcodelength)
+ block_insert(p);
+ p = extable[i].handlerpc;
+ bound_check(p);
+ block_insert(p);
+ }
+
+ s_count = 1 + exceptiontablelength; /* initialize stack element counter */
+
+ if (runverbose) {
+/* isleafmethod=false; */
+ }
+
+#ifdef USE_THREADS
+ if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
+ isleafmethod=false;
+ }
+#endif
+
+ /* scan all java instructions */
+
+ for (p = 0; p < jcodelength; p = nextp) {
+
+ opcode = code_get_u1 (p); /* fetch op code */
+
+ block_index[p] |= (ipc << 1); /* store intermediate count */
+
+ if (blockend) {
+ block_insert(p); /* start new block */
+ blockend = false;
+ }
+
+ nextp = p + jcommandsize[opcode]; /* compute next instruction start */
+ s_count += stackreq[opcode]; /* compute stack element count */
+
+ switch (opcode) {
+
+ case JAVA_NOP:
+ break;
+
+ /* pushing constants onto the stack p */
+
+ case JAVA_BIPUSH:
+ LOADCONST_I(code_get_s1(p+1));
+ break;
+
+ case JAVA_SIPUSH:
+ LOADCONST_I(code_get_s2(p+1));
+ break;
+
+ case JAVA_LDC1:
+ i = code_get_u1(p+1);
+ goto pushconstantitem;
+ case JAVA_LDC2:
+ case JAVA_LDC2W:
+ i = code_get_u2(p + 1);
+
+ pushconstantitem:
+
+ if (i >= class->cpcount)
+ panic ("Attempt to access constant outside range");
+
+ switch (class->cptags[i]) {
+ case CONSTANT_Integer:
+ LOADCONST_I(((constant_integer*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Long:
+ LOADCONST_L(((constant_long*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Float:
+ LOADCONST_F(((constant_float*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_Double:
+ LOADCONST_D(((constant_double*)
+ (class->cpinfos[i]))->value);
+ break;
+ case CONSTANT_String:
+ LOADCONST_A(literalstring_new((unicode*)
+ (class->cpinfos[i])));
+ break;
+ default: panic("Invalid constant type to push");
+ }
+ break;
+
+ case JAVA_ACONST_NULL:
+ LOADCONST_A(NULL);
+ break;
+
+ case JAVA_ICONST_M1:
+ case JAVA_ICONST_0:
+ case JAVA_ICONST_1:
+ case JAVA_ICONST_2:
+ case JAVA_ICONST_3:
+ case JAVA_ICONST_4:
+ case JAVA_ICONST_5:
+ LOADCONST_I(opcode - JAVA_ICONST_0);
+ break;
+
+ case JAVA_LCONST_0:
+ case JAVA_LCONST_1:
+ LOADCONST_L(opcode - JAVA_LCONST_0);
+ break;
+
+ case JAVA_FCONST_0:
+ case JAVA_FCONST_1:
+ case JAVA_FCONST_2:
+ LOADCONST_F(opcode - JAVA_FCONST_0);
+ break;
+
+ case JAVA_DCONST_0:
+ case JAVA_DCONST_1:
+ LOADCONST_D(opcode - JAVA_DCONST_0);
+ break;
+
+ /* loading variables onto the stack */
+
+ case JAVA_ILOAD:
+ case JAVA_LLOAD:
+ case JAVA_FLOAD:
+ case JAVA_DLOAD:
+ case JAVA_ALOAD:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ nextp = p+3;
+ iswide = false;
+ }
+ OP1(opcode, i);
+ break;
+
+ case JAVA_ILOAD_0:
+ case JAVA_ILOAD_1:
+ case JAVA_ILOAD_2:
+ case JAVA_ILOAD_3:
+ OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
+ break;
+
+ case JAVA_LLOAD_0:
+ case JAVA_LLOAD_1:
+ case JAVA_LLOAD_2:
+ case JAVA_LLOAD_3:
+ OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
+ break;
+
+ case JAVA_FLOAD_0:
+ case JAVA_FLOAD_1:
+ case JAVA_FLOAD_2:
+ case JAVA_FLOAD_3:
+ OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
+ break;
+
+ case JAVA_DLOAD_0:
+ case JAVA_DLOAD_1:
+ case JAVA_DLOAD_2:
+ case JAVA_DLOAD_3:
+ OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
+ break;
+
+ case JAVA_ALOAD_0:
+ case JAVA_ALOAD_1:
+ case JAVA_ALOAD_2:
+ case JAVA_ALOAD_3:
+ OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
+ break;
+
+ /* storing stack values into local variables */
+
+ case JAVA_ISTORE:
+ case JAVA_LSTORE:
+ case JAVA_FSTORE:
+ case JAVA_DSTORE:
+ case JAVA_ASTORE:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ iswide=false;
+ nextp = p+3;
+ }
+ OP1(opcode, i);
+ break;
+
+ case JAVA_ISTORE_0:
+ case JAVA_ISTORE_1:
+ case JAVA_ISTORE_2:
+ case JAVA_ISTORE_3:
+ OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
+ break;
+
+ case JAVA_LSTORE_0:
+ case JAVA_LSTORE_1:
+ case JAVA_LSTORE_2:
+ case JAVA_LSTORE_3:
+ OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
+ break;
+
+ case JAVA_FSTORE_0:
+ case JAVA_FSTORE_1:
+ case JAVA_FSTORE_2:
+ case JAVA_FSTORE_3:
+ OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
+ break;
+
+ case JAVA_DSTORE_0:
+ case JAVA_DSTORE_1:
+ case JAVA_DSTORE_2:
+ case JAVA_DSTORE_3:
+ OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
+ break;
+
+ case JAVA_ASTORE_0:
+ case JAVA_ASTORE_1:
+ case JAVA_ASTORE_2:
+ case JAVA_ASTORE_3:
+ OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
+ break;
+
+ case JAVA_IINC:
+ {
+ int v;
+
+ if (!iswide) {
+ i = code_get_u1(p + 1);
+ v = code_get_s1(p + 2);
+ }
+ else {
+ i = code_get_u2(p + 1);
+ v = code_get_s2(p + 3);
+ iswide = false;
+ nextp = p+5;
+ }
+ OP2I(opcode, i, v);
+ }
+ break;
+
+ /* wider index for loading, storing and incrementing */
+
+ case JAVA_WIDE:
+ iswide = true;
+ nextp = p + 1;
+ break;
+
+ /* managing arrays ************************************************/
+
+ case JAVA_NEWARRAY:
+ OP2I(ICMD_CHECKASIZE, 0, 0);
+ switch (code_get_s1(p+1)) {
+ case 4:
+ BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
+ break;
+ case 5:
+ BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
+ break;
+ case 6:
+ BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
+ break;
+ case 7:
+ BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
+ break;
+ case 8:
+ BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
+ break;
+ case 9:
+ BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
+ break;
+ case 10:
+ BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
+ break;
+ case 11:
+ BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
+ break;
+ default: panic("Invalid array-type to create");
+ }
+ break;
+
+ case JAVA_ANEWARRAY:
+ OP2I(ICMD_CHECKASIZE, 0, 0);
+ i = code_get_u2(p+1);
+ /* array or class type ? */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i,
+ CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
+ }
+ else {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
+ }
+ break;
+
+ case JAVA_MULTIANEWARRAY:
+ isleafmethod=false;
+ i = code_get_u2(p+1);
+ {
+ int v = code_get_u1(p+3);
+ constant_arraydescriptor *desc =
+ class_getconstant (class, i, CONSTANT_Arraydescriptor);
+ OP2A(opcode, v, desc);
+ }
+ break;
+
+ case JAVA_IFEQ:
+ case JAVA_IFLT:
+ case JAVA_IFLE:
+ case JAVA_IFNE:
+ case JAVA_IFGT:
+ case JAVA_IFGE:
+ case JAVA_IFNULL:
+ case JAVA_IFNONNULL:
+ case JAVA_IF_ICMPEQ:
+ case JAVA_IF_ICMPNE:
+ case JAVA_IF_ICMPLT:
+ case JAVA_IF_ICMPGT:
+ case JAVA_IF_ICMPLE:
+ case JAVA_IF_ICMPGE:
+ case JAVA_IF_ACMPEQ:
+ case JAVA_IF_ACMPNE:
+ case JAVA_GOTO:
+ case JAVA_JSR:
+ i = p + code_get_s2(p+1);
+ bound_check(i);
+ block_insert(i);
+ blockend = true;
+ OP1(opcode, i);
+ break;
+ case JAVA_GOTO_W:
+ case JAVA_JSR_W:
+ i = p + code_get_s4(p+1);
+ bound_check(i);
+ block_insert(i);
+ blockend = true;
+ OP1(opcode, i);
+ break;
+
+ case JAVA_RET:
+ if (!iswide)
+ i = code_get_u1(p+1);
+ else {
+ i = code_get_u2(p+1);
+ nextp = p+3;
+ iswide = false;
+ }
+ blockend = true;
+ OP1(opcode, i);
+ break;
+
+ case JAVA_IRETURN:
+ case JAVA_LRETURN:
+ case JAVA_FRETURN:
+ case JAVA_DRETURN:
+ case JAVA_ARETURN:
+ case JAVA_RETURN:
+ blockend = true;
+ OP(opcode);
+ break;
+
+ case JAVA_ATHROW:
+ blockend = true;
+ OP(opcode);
+ break;
+
+
+ /* table jumps ********************************/
+
+ case JAVA_LOOKUPSWITCH:
+ {
+ s4 num, j;
+
+ blockend = true;
+ nextp = ALIGN((p + 1), 4);
+ OP2A(opcode, 0, jcode + nextp);
+
+ /* default target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+
+ /* number of pairs */
+
+ num = code_get_u4(nextp);
+ *((s4*)(jcode + nextp)) = num;
+ nextp += 4;
+
+ for (i = 0; i < num; i++) {
+
+ /* value */
+
+ j = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+
+ /* target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+ }
+
+ break;
+ }
+
+
+ case JAVA_TABLESWITCH:
+ {
+ s4 num, j;
+
+ blockend = true;
+ nextp = ALIGN((p + 1), 4);
+ OP2A(opcode, 0, jcode + nextp);
+
+ /* default target */
+
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+
+ /* lower bound */
+
+ j = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+
+ /* upper bound */
+
+ num = code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = num; /* restore for little endian */
+ nextp += 4;
+
+ num -= j;
+
+ for (i = 0; i <= num; i++) {
+ j = p + code_get_s4(nextp);
+ *((s4*)(jcode + nextp)) = j; /* restore for little endian */
+ nextp += 4;
+ bound_check(j);
+ block_insert(j);
+ }
+
+ break;
+ }
+
+
+ /* load and store of object fields *******************/
+
+ case JAVA_AASTORE:
+ BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
+ break;
+
+ case JAVA_PUTSTATIC:
+ case JAVA_GETSTATIC:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
+ fr = class_getconstant (class, i, CONSTANT_Fieldref);
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ compiler_addinitclass (fr->class);
+ OP2A(opcode, fi->type, fi);
+ }
+ break;
+ case JAVA_PUTFIELD:
+ case JAVA_GETFIELD:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
+ fr = class_getconstant (class, i, CONSTANT_Fieldref);
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ OP2A(opcode, fi->type, fi);
+ }
+ break;
+
+
+ /* method invocation *****/
+
+ case JAVA_INVOKESTATIC:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_Methodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (! (mi->flags & ACC_STATIC))
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+ case JAVA_INVOKESPECIAL:
+ case JAVA_INVOKEVIRTUAL:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_Methodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (mi->flags & ACC_STATIC)
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+ case JAVA_INVOKEINTERFACE:
+ i = code_get_u2(p + 1);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+
+ mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
+ mi = class_findmethod (mr->class, mr->name, mr->descriptor);
+ if (mi->flags & ACC_STATIC)
+ panic ("Static/Nonstatic mismatch calling static method");
+ descriptor2types(mi);
+ isleafmethod=false;
+ OP2A(opcode, mi->paramcount, mi);
+ }
+ break;
+
+ /* miscellaneous object operations *******/
+
+ case JAVA_NEW:
+ i = code_get_u2 (p+1);
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
+ BUILTIN1((functionptr) builtin_new, TYPE_ADR);
+ break;
+
+ case JAVA_CHECKCAST:
+ i = code_get_u2(p+1);
+
+ /* array type cast-check */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ }
+ else { /* object type cast-check */
+ OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+ }
+ break;
+
+ case JAVA_INSTANCEOF:
+ i = code_get_u2(p+1);
+
+ /* array type cast-check */
+ if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
+ LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
+ BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
+ }
+ else { /* object type cast-check */
+ OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
+ }
+ break;
+
+ case JAVA_MONITORENTER:
+#ifdef USE_THREADS
+ if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+ if (checknull) {
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ }
+ else {
+/* BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ }
+#else
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+#endif
+ }
+ else
+#endif
+ {
+ OP(ICMD_NULLCHECKPOP);
+ }
+ break;
+
+ case JAVA_MONITOREXIT:
+#ifdef USE_THREADS
+ if (checksync) {
+ BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+ }
+ else
+#endif
+ {
+ OP(ICMD_POP);
+ }
+ break;
+
+ /* any other basic operation **************************************/
+
+ case JAVA_IDIV:
+ OP(opcode);
+ break;
+
+ case JAVA_IREM:
+ OP(opcode);
+ break;
+
+ case JAVA_LDIV:
+ OP(opcode);
+ break;
+
+ case JAVA_LREM:
+ OP(opcode);
+ break;
+
+ case JAVA_FREM:
+ BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
+ break;
+
+ case JAVA_DREM:
+ BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
+ break;
+
+ case JAVA_F2I:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_F2L:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_D2I:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_D2L:
+ if (checkfloats) {
+ BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
+ }
+ else {
+ OP(opcode);
+ }
+ break;
+
+ case JAVA_BREAKPOINT:
+ panic("Illegal opcode Breakpoint encountered");
+ break;
+
+ case 203:
+ case 204:
+ case 205:
+ case 206:
+ case 207:
+ case 208:
+ case 209:
+ case 210:
+ case 211:
+ case 212:
+ case 213:
+ case 214:
+ case 215:
+ case 216:
+ case 217:
+ case 218:
+ case 219:
+ case 220:
+ case 221:
+ case 222:
+ case 223:
+ case 224:
+ case 225:
+ case 226:
+ case 227:
+ case 228:
+ case 229:
+ case 230:
+ case 231:
+ case 232:
+ case 233:
+ case 234:
+ case 235:
+ case 236:
+ case 237:
+ case 238:
+ case 239:
+ case 240:
+ case 241:
+ case 242:
+ case 243:
+ case 244:
+ case 245:
+ case 246:
+ case 247:
+ case 248:
+ case 249:
+ case 250:
+ case 251:
+ case 252:
+ case 253:
+ case 254:
+ case 255:
+ printf("Illegal opcode %d at instr %d", opcode, ipc);
+ panic("encountered");
+ break;
+
+ default:
+ OP(opcode);
+ break;
+
+ } /* end switch */
+
+ } /* end for */
+
+ if (p != jcodelength)
+ panic("Command-sequence crosses code-boundary");
+
+ if (!blockend)
+ panic("Code does not end with branch/return/athrow - stmt");
+
+ /* adjust block count if target 0 is not first intermediate instruction */
+
+ if (!block_index[0] || (block_index[0] > 1))
+ b_count++;
+
+ /* copy local to global variables */
+
+ instr_count = ipc;
+ block_count = b_count;
+ stack_count = s_count + block_count * maxstack;
+
+ /* allocate stack table */
+
+ stack = DMNEW(stackelement, stack_count);
+
+ {
+ basicblock *bptr;
+
+ bptr = block = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
+
+ b_count = 0;
+
+ /* additional block if target 0 is not first intermediate instruction */
+
+ if (!block_index[0] || (block_index[0] > 1)) {
+ bptr->iinstr = instr;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ bptr->pre_count = 0;
+ bptr++;
+ b_count++;
+ }
+
+ /* allocate blocks */
+
+ for (p = 0; p < jcodelength; p++)
+ if (block_index[p] & 1) {
+ bptr->iinstr = instr + (block_index[p] >> 1);
+ if (b_count != 0)
+ (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ block_index[p] = b_count;
+ bptr->pre_count = 0;
+ bptr++;
+ b_count++;
+ }
+
+ /* allocate additional block at end */
+
+ bptr->iinstr = NULL;
+ (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
+ bptr->icount = 0;
+ bptr->mpc = -1;
+ bptr->flags = -1;
+ bptr->type = BBTYPE_STD;
+ bptr->branchrefs = NULL;
+ bptr->pre_count = 0;
+ }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
--- /dev/null
+/* jit/stack.c *****************************************************************
+
+ Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+ See file COPYRIGHT for information on usage and disclaimer of warranties
+
+ Parser for JavaVM to intermediate code translation
+
+ Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
+
+ Last Change: 1997/11/18
+
+*******************************************************************************/
+
+#define CONDITIONAL_LOADCONST
+
+#ifdef STATISTICS
+#define COUNT(cnt) cnt++
+#else
+#define COUNT(cnt)
+#endif
+
+#define STACKRESET {curstack=0;stackdepth=0;}
+
+#define TYPEPANIC {show_icmd_method();panic("Stack type mismatch");}
+#define CURKIND curstack->varkind
+#define CURTYPE curstack->type
+
+#define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;\
+ new->varkind=v;new->varnum=n;curstack=new;new++;}
+#define NEWSTACKn(s,n) NEWSTACK(s,UNDEFVAR,n)
+#define NEWSTACK0(s) NEWSTACK(s,UNDEFVAR,0)
+#define NEWXSTACK {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
+
+#define SETDST {iptr->dst=curstack;}
+#define POP(s) {if(s!=curstack->type){TYPEPANIC;}\
+ if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+ curstack=curstack->prev;}
+#define POPANY {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
+ curstack=curstack->prev;}
+#define COPY(s,d) {(d)->flags=0;(d)->type=(s)->type;\
+ (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
+
+#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
+#define STORE(s) {POP(s);SETDST;stackdepth--;}
+#define OP1_0(s) {POP(s);SETDST;stackdepth--;}
+#define OP1_0ANY {POPANY;SETDST;stackdepth--;}
+#define OP0_1(s) {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
+#define OP1_1(s,d) {POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
+#define OP2_0(s) {POP(s);POP(s);SETDST;stackdepth-=2;}
+#define OPTT2_0(t,b){POP(t);POP(b);SETDST;stackdepth-=2;}
+#define OP2_1(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
+#define OP2IAT_1(s) {POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
+ SETDST;stackdepth--;}
+#define OP2IT_1(s) {POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
+ SETDST;stackdepth--;}
+#define OPTT2_1(s,d){POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
+#define OP2_2(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
+ NEWSTACKn(s,stackdepth-1);SETDST;}
+#define OP3TIA_0(s) {POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
+#define OP3_0(s) {POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
+#define POPMANY(i) {stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
+#define DUP {NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST;\
+ stackdepth++;}
+#define SWAP {COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ curstack=new+1;new+=2;SETDST;}
+#define DUP_X1 {COPY(curstack,new);COPY(curstack,new+2);POPANY;\
+ COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
+ new[1].prev=new;new[2].prev=new+1;\
+ curstack=new+2;new+=3;SETDST;stackdepth++;}
+#define DUP2_X1 {COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
+ COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+ COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
+ new[1].prev=new;new[2].prev=new+1;\
+ new[3].prev=new+2;new[4].prev=new+3;\
+ curstack=new+4;new+=5;SETDST;stackdepth+=2;}
+#define DUP_X2 {COPY(curstack,new);COPY(curstack,new+3);POPANY;\
+ COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ new[2].prev=new+1;new[3].prev=new+2;\
+ curstack=new+3;new+=4;SETDST;stackdepth++;}
+#define DUP2_X2 {COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
+ COPY(curstack,new);COPY(curstack,new+4);POPANY;\
+ COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
+ new[0].prev=curstack;new[1].prev=new;\
+ new[2].prev=new+1;new[3].prev=new+2;\
+ new[4].prev=new+3;new[5].prev=new+4;\
+ curstack=new+5;new+=6;SETDST;stackdepth+=2;}
+
+#define COPYCURSTACK(copy) {\
+ int d;\
+ stackptr s;\
+ if(curstack){\
+ s=curstack;\
+ new+=stackdepth;\
+ d=stackdepth;\
+ copy=new;\
+ while(s){\
+ copy--;d--;\
+ copy->prev=copy-1;\
+ copy->type=s->type;\
+ copy->flags=0;\
+ copy->varkind=STACKVAR;\
+ copy->varnum=d;\
+ s=s->prev;\
+ }\
+ copy->prev=NULL;\
+ copy=new-1;\
+ }\
+ else\
+ copy=NULL;\
+}
+
+
+#define BBEND(s,i){\
+ i=stackdepth-1;\
+ copy=s;\
+ while(copy){\
+ if((copy->varkind==STACKVAR)&&(copy->varnum>i))\
+ copy->varkind=TEMPVAR;\
+ else {\
+ copy->varkind=STACKVAR;\
+ copy->varnum=i;\
+ }\
+ interfaces[i][copy->type].type = copy->type;\
+ interfaces[i][copy->type].flags |= copy->flags;\
+ i--;copy=copy->prev;\
+ }\
+ i=bptr->indepth-1;\
+ copy=bptr->instack;\
+ while(copy){\
+ interfaces[i][copy->type].type = copy->type;\
+ if(copy->varkind==STACKVAR){\
+ if (copy->flags & SAVEDVAR)\
+ interfaces[i][copy->type].flags |= SAVEDVAR;\
+ }\
+ i--;copy=copy->prev;\
+ }\
+}
+
+
+#define MARKREACHED(b,c) {\
+ if(b->flags<0)\
+ {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;}\
+ else {stackptr s=curstack;stackptr t=b->instack;\
+ if(b->indepth!=stackdepth)\
+ {show_icmd_method();panic("Stack depth mismatch");}\
+ while(s){if (s->type!=t->type)\
+ TYPEPANIC\
+ s=s->prev;t=t->prev;\
+ }\
+ }\
+}
+
+
+static void show_icmd_method();
+
+static void analyse_stack()
+{
+ int b_count, b_index;
+ int stackdepth;
+ stackptr curstack, new, copy;
+ int opcode, i, len, loops;
+ int superblockend, repeat, deadcode;
+ instruction *iptr = instr;
+ basicblock *bptr, *tbptr;
+ s4 *s4ptr;
+
+ arguments_num = 0;
+ new = stack;
+ loops = 0;
+ block[0].flags = BBREACHED;
+ block[0].instack = 0;
+ block[0].indepth = 0;
+
+ for (i = 0; i < exceptiontablelength; i++) {
+ bptr = &block[block_index[extable[i].handlerpc]];
+ bptr->flags = BBREACHED;
+ bptr->type = BBTYPE_EXH;
+ bptr->instack = new;
+ bptr->indepth = 1;
+ bptr->pre_count = 10000;
+ STACKRESET;
+ NEWXSTACK;
+ }
+
+#ifdef CONDITIONAL_LOADCONST
+ b_count = block_count;
+ bptr = block;
+ while (--b_count >= 0) {
+ if (bptr->icount != 0) {
+ iptr = bptr->iinstr + bptr->icount - 1;
+ switch (iptr->opc) {
+ case ICMD_RET:
+ case ICMD_RETURN:
+ case ICMD_IRETURN:
+ case ICMD_LRETURN:
+ case ICMD_FRETURN:
+ case ICMD_DRETURN:
+ case ICMD_ARETURN:
+ case ICMD_ATHROW:
+ break;
+
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ bptr[1].pre_count++;
+ case ICMD_GOTO:
+ block[block_index[iptr->op1]].pre_count++;
+ break;
+
+ case ICMD_TABLESWITCH:
+ s4ptr = iptr->val.a;
+ block[block_index[*s4ptr++]].pre_count++; /* default */
+ i = *s4ptr++; /* low */
+ i = *s4ptr++ - i + 1; /* high */
+ while (--i >= 0) {
+ block[block_index[*s4ptr++]].pre_count++;
+ }
+ break;
+
+ case ICMD_LOOKUPSWITCH:
+ s4ptr = iptr->val.a;
+ block[block_index[*s4ptr++]].pre_count++; /* default */
+ i = *s4ptr++; /* count */
+ while (--i >= 0) {
+ block[block_index[s4ptr[1]]].pre_count++;
+ s4ptr += 2;
+ }
+ break;
+ default:
+ bptr[1].pre_count++;
+ break;
+ }
+ }
+ bptr++;
+ }
+#endif
+
+
+ do {
+ loops++;
+ b_count = block_count;
+ bptr = block;
+ superblockend = true;
+ repeat = false;
+ STACKRESET;
+ deadcode = true;
+ while (--b_count >= 0) {
+ if (bptr->flags == BBDELETED) {
+ /* do nothing */
+ }
+ else if (superblockend && (bptr->flags < BBREACHED))
+ repeat = true;
+ else if (bptr->flags <= BBREACHED) {
+ if (superblockend)
+ stackdepth = bptr->indepth;
+ else if (bptr->flags < BBREACHED) {
+ COPYCURSTACK(copy);
+ bptr->instack = copy;
+ bptr->indepth = stackdepth;
+ }
+ else if (bptr->indepth != stackdepth) {
+ show_icmd_method();
+ panic("Stack depth mismatch");
+
+ }
+ curstack = bptr->instack;
+ deadcode = false;
+ superblockend = false;
+ bptr->flags = BBFINISHED;
+ len = bptr->icount;
+ iptr = bptr->iinstr;
+ b_index = bptr - block;
+ while (--len >= 0) {
+ opcode = iptr->opc;
+ switch (opcode) {
+
+ /* pop 0 push 0 */
+
+ case ICMD_NOP:
+ case ICMD_CHECKASIZE:
+
+ case ICMD_IFEQ_ICONST:
+ case ICMD_IFNE_ICONST:
+ case ICMD_IFLT_ICONST:
+ case ICMD_IFGE_ICONST:
+ case ICMD_IFGT_ICONST:
+ case ICMD_IFLE_ICONST:
+ case ICMD_ELSE_ICONST:
+ SETDST;
+ break;
+
+ case ICMD_RET:
+ locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+ case ICMD_RETURN:
+ COUNT(count_pcmd_return);
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 0 push 1 const */
+
+ case ICMD_ICONST:
+ COUNT(count_pcmd_load);
+ if (len > 0) {
+ switch (iptr[1].opc) {
+ case ICMD_IADD:
+ iptr[0].opc = ICMD_IADDCONST;
+icmd_iconst_tail:
+ iptr[1].opc = ICMD_NOP;
+ OP1_1(TYPE_INT,TYPE_INT);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_ISUB:
+ iptr[0].opc = ICMD_ISUBCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IMUL:
+ iptr[0].opc = ICMD_IMULCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IDIV:
+ if (iptr[0].val.i == 0x00000002)
+ iptr[0].val.i = 1;
+ else if (iptr[0].val.i == 0x00000004)
+ iptr[0].val.i = 2;
+ else if (iptr[0].val.i == 0x00000008)
+ iptr[0].val.i = 3;
+ else if (iptr[0].val.i == 0x00000010)
+ iptr[0].val.i = 4;
+ else if (iptr[0].val.i == 0x00000020)
+ iptr[0].val.i = 5;
+ else if (iptr[0].val.i == 0x00000040)
+ iptr[0].val.i = 6;
+ else if (iptr[0].val.i == 0x00000080)
+ iptr[0].val.i = 7;
+ else if (iptr[0].val.i == 0x00000100)
+ iptr[0].val.i = 8;
+ else if (iptr[0].val.i == 0x00000200)
+ iptr[0].val.i = 9;
+ else if (iptr[0].val.i == 0x00000400)
+ iptr[0].val.i = 10;
+ else if (iptr[0].val.i == 0x00000800)
+ iptr[0].val.i = 11;
+ else if (iptr[0].val.i == 0x00001000)
+ iptr[0].val.i = 12;
+ else if (iptr[0].val.i == 0x00002000)
+ iptr[0].val.i = 13;
+ else if (iptr[0].val.i == 0x00004000)
+ iptr[0].val.i = 14;
+ else if (iptr[0].val.i == 0x00008000)
+ iptr[0].val.i = 15;
+ else if (iptr[0].val.i == 0x00010000)
+ iptr[0].val.i = 16;
+ else if (iptr[0].val.i == 0x00020000)
+ iptr[0].val.i = 17;
+ else if (iptr[0].val.i == 0x00040000)
+ iptr[0].val.i = 18;
+ else if (iptr[0].val.i == 0x00080000)
+ iptr[0].val.i = 19;
+ else if (iptr[0].val.i == 0x00100000)
+ iptr[0].val.i = 20;
+ else if (iptr[0].val.i == 0x00200000)
+ iptr[0].val.i = 21;
+ else if (iptr[0].val.i == 0x00400000)
+ iptr[0].val.i = 22;
+ else if (iptr[0].val.i == 0x00800000)
+ iptr[0].val.i = 23;
+ else if (iptr[0].val.i == 0x01000000)
+ iptr[0].val.i = 24;
+ else if (iptr[0].val.i == 0x02000000)
+ iptr[0].val.i = 25;
+ else if (iptr[0].val.i == 0x04000000)
+ iptr[0].val.i = 26;
+ else if (iptr[0].val.i == 0x08000000)
+ iptr[0].val.i = 27;
+ else if (iptr[0].val.i == 0x10000000)
+ iptr[0].val.i = 28;
+ else if (iptr[0].val.i == 0x20000000)
+ iptr[0].val.i = 29;
+ else if (iptr[0].val.i == 0x40000000)
+ iptr[0].val.i = 30;
+ else if (iptr[0].val.i == 0x80000000)
+ iptr[0].val.i = 31;
+ else {
+ PUSHCONST(TYPE_INT);
+ break;
+ }
+ iptr[0].opc = ICMD_IDIVPOW2;
+ goto icmd_iconst_tail;
+ case ICMD_IREM:
+ if (iptr[0].val.i == 0x10001) {
+ iptr[0].opc = ICMD_IREM0X10001;
+ goto icmd_iconst_tail;
+ }
+ if ((iptr[0].val.i == 0x00000002) ||
+ (iptr[0].val.i == 0x00000004) ||
+ (iptr[0].val.i == 0x00000008) ||
+ (iptr[0].val.i == 0x00000010) ||
+ (iptr[0].val.i == 0x00000020) ||
+ (iptr[0].val.i == 0x00000040) ||
+ (iptr[0].val.i == 0x00000080) ||
+ (iptr[0].val.i == 0x00000100) ||
+ (iptr[0].val.i == 0x00000200) ||
+ (iptr[0].val.i == 0x00000400) ||
+ (iptr[0].val.i == 0x00000800) ||
+ (iptr[0].val.i == 0x00001000) ||
+ (iptr[0].val.i == 0x00002000) ||
+ (iptr[0].val.i == 0x00004000) ||
+ (iptr[0].val.i == 0x00008000) ||
+ (iptr[0].val.i == 0x00010000) ||
+ (iptr[0].val.i == 0x00020000) ||
+ (iptr[0].val.i == 0x00040000) ||
+ (iptr[0].val.i == 0x00080000) ||
+ (iptr[0].val.i == 0x00100000) ||
+ (iptr[0].val.i == 0x00200000) ||
+ (iptr[0].val.i == 0x00400000) ||
+ (iptr[0].val.i == 0x00800000) ||
+ (iptr[0].val.i == 0x01000000) ||
+ (iptr[0].val.i == 0x02000000) ||
+ (iptr[0].val.i == 0x04000000) ||
+ (iptr[0].val.i == 0x08000000) ||
+ (iptr[0].val.i == 0x10000000) ||
+ (iptr[0].val.i == 0x20000000) ||
+ (iptr[0].val.i == 0x40000000) ||
+ (iptr[0].val.i == 0x80000000)) {
+ iptr[0].opc = ICMD_IREMPOW2;
+ iptr[0].val.i -= 1;
+ goto icmd_iconst_tail;
+ }
+ PUSHCONST(TYPE_INT);
+ break;
+ case ICMD_IAND:
+ iptr[0].opc = ICMD_IANDCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IOR:
+ iptr[0].opc = ICMD_IORCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IXOR:
+ iptr[0].opc = ICMD_IXORCONST;
+ goto icmd_iconst_tail;
+ case ICMD_ISHL:
+ iptr[0].opc = ICMD_ISHLCONST;
+ goto icmd_iconst_tail;
+ case ICMD_ISHR:
+ iptr[0].opc = ICMD_ISHRCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IUSHR:
+ iptr[0].opc = ICMD_IUSHRCONST;
+ goto icmd_iconst_tail;
+ case ICMD_IF_ICMPEQ:
+ iptr[0].opc = ICMD_IFEQ;
+icmd_if_icmp_tail:
+ iptr[0].op1 = iptr[1].op1;
+ bptr->icount--;
+ len--;
+ /* iptr[1].opc = ICMD_NOP; */
+ OP1_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ break;
+ case ICMD_IF_ICMPLT:
+ iptr[0].opc = ICMD_IFLT;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPLE:
+ iptr[0].opc = ICMD_IFLE;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPNE:
+ iptr[0].opc = ICMD_IFNE;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPGT:
+ iptr[0].opc = ICMD_IFGT;
+ goto icmd_if_icmp_tail;
+ case ICMD_IF_ICMPGE:
+ iptr[0].opc = ICMD_IFGE;
+ goto icmd_if_icmp_tail;
+ default:
+ PUSHCONST(TYPE_INT);
+ }
+ }
+ else
+ PUSHCONST(TYPE_INT);
+ break;
+ case ICMD_LCONST:
+ COUNT(count_pcmd_load);
+ if (len > 0) {
+ switch (iptr[1].opc) {
+ case ICMD_LADD:
+ iptr[0].opc = ICMD_LADDCONST;
+icmd_lconst_tail:
+ iptr[1].opc = ICMD_NOP;
+ OP1_1(TYPE_LNG,TYPE_LNG);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_LSUB:
+ iptr[0].opc = ICMD_LSUBCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LMUL:
+ iptr[0].opc = ICMD_LMULCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LDIV:
+ if (iptr[0].val.l == 0x00000002)
+ iptr[0].val.l = 1;
+ else if (iptr[0].val.l == 0x00000004)
+ iptr[0].val.l = 2;
+ else if (iptr[0].val.l == 0x00000008)
+ iptr[0].val.l = 3;
+ else if (iptr[0].val.l == 0x00000010)
+ iptr[0].val.l = 4;
+ else if (iptr[0].val.l == 0x00000020)
+ iptr[0].val.l = 5;
+ else if (iptr[0].val.l == 0x00000040)
+ iptr[0].val.l = 6;
+ else if (iptr[0].val.l == 0x00000080)
+ iptr[0].val.l = 7;
+ else if (iptr[0].val.l == 0x00000100)
+ iptr[0].val.l = 8;
+ else if (iptr[0].val.l == 0x00000200)
+ iptr[0].val.l = 9;
+ else if (iptr[0].val.l == 0x00000400)
+ iptr[0].val.l = 10;
+ else if (iptr[0].val.l == 0x00000800)
+ iptr[0].val.l = 11;
+ else if (iptr[0].val.l == 0x00001000)
+ iptr[0].val.l = 12;
+ else if (iptr[0].val.l == 0x00002000)
+ iptr[0].val.l = 13;
+ else if (iptr[0].val.l == 0x00004000)
+ iptr[0].val.l = 14;
+ else if (iptr[0].val.l == 0x00008000)
+ iptr[0].val.l = 15;
+ else if (iptr[0].val.l == 0x00010000)
+ iptr[0].val.l = 16;
+ else if (iptr[0].val.l == 0x00020000)
+ iptr[0].val.l = 17;
+ else if (iptr[0].val.l == 0x00040000)
+ iptr[0].val.l = 18;
+ else if (iptr[0].val.l == 0x00080000)
+ iptr[0].val.l = 19;
+ else if (iptr[0].val.l == 0x00100000)
+ iptr[0].val.l = 20;
+ else if (iptr[0].val.l == 0x00200000)
+ iptr[0].val.l = 21;
+ else if (iptr[0].val.l == 0x00400000)
+ iptr[0].val.l = 22;
+ else if (iptr[0].val.l == 0x00800000)
+ iptr[0].val.l = 23;
+ else if (iptr[0].val.l == 0x01000000)
+ iptr[0].val.l = 24;
+ else if (iptr[0].val.l == 0x02000000)
+ iptr[0].val.l = 25;
+ else if (iptr[0].val.l == 0x04000000)
+ iptr[0].val.l = 26;
+ else if (iptr[0].val.l == 0x08000000)
+ iptr[0].val.l = 27;
+ else if (iptr[0].val.l == 0x10000000)
+ iptr[0].val.l = 28;
+ else if (iptr[0].val.l == 0x20000000)
+ iptr[0].val.l = 29;
+ else if (iptr[0].val.l == 0x40000000)
+ iptr[0].val.l = 30;
+ else if (iptr[0].val.l == 0x80000000)
+ iptr[0].val.l = 31;
+ else {
+ PUSHCONST(TYPE_LNG);
+ break;
+ }
+ iptr[0].opc = ICMD_LDIVPOW2;
+ goto icmd_lconst_tail;
+ case ICMD_LREM:
+ if (iptr[0].val.l == 0x10001) {
+ iptr[0].opc = ICMD_LREM0X10001;
+ goto icmd_lconst_tail;
+ }
+ if ((iptr[0].val.l == 0x00000002) ||
+ (iptr[0].val.l == 0x00000004) ||
+ (iptr[0].val.l == 0x00000008) ||
+ (iptr[0].val.l == 0x00000010) ||
+ (iptr[0].val.l == 0x00000020) ||
+ (iptr[0].val.l == 0x00000040) ||
+ (iptr[0].val.l == 0x00000080) ||
+ (iptr[0].val.l == 0x00000100) ||
+ (iptr[0].val.l == 0x00000200) ||
+ (iptr[0].val.l == 0x00000400) ||
+ (iptr[0].val.l == 0x00000800) ||
+ (iptr[0].val.l == 0x00001000) ||
+ (iptr[0].val.l == 0x00002000) ||
+ (iptr[0].val.l == 0x00004000) ||
+ (iptr[0].val.l == 0x00008000) ||
+ (iptr[0].val.l == 0x00010000) ||
+ (iptr[0].val.l == 0x00020000) ||
+ (iptr[0].val.l == 0x00040000) ||
+ (iptr[0].val.l == 0x00080000) ||
+ (iptr[0].val.l == 0x00100000) ||
+ (iptr[0].val.l == 0x00200000) ||
+ (iptr[0].val.l == 0x00400000) ||
+ (iptr[0].val.l == 0x00800000) ||
+ (iptr[0].val.l == 0x01000000) ||
+ (iptr[0].val.l == 0x02000000) ||
+ (iptr[0].val.l == 0x04000000) ||
+ (iptr[0].val.l == 0x08000000) ||
+ (iptr[0].val.l == 0x10000000) ||
+ (iptr[0].val.l == 0x20000000) ||
+ (iptr[0].val.l == 0x40000000) ||
+ (iptr[0].val.l == 0x80000000)) {
+ iptr[0].opc = ICMD_LREMPOW2;
+ iptr[0].val.l -= 1;
+ goto icmd_lconst_tail;
+ }
+ PUSHCONST(TYPE_LNG);
+ break;
+ case ICMD_LAND:
+ iptr[0].opc = ICMD_LANDCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LOR:
+ iptr[0].opc = ICMD_LORCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LXOR:
+ iptr[0].opc = ICMD_LXORCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LSHL:
+ iptr[0].opc = ICMD_LSHLCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LSHR:
+ iptr[0].opc = ICMD_LSHRCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LUSHR:
+ iptr[0].opc = ICMD_LUSHRCONST;
+ goto icmd_lconst_tail;
+ case ICMD_LCMP:
+ if ((len > 1) && (iptr[2].val.i == 0)) {
+ switch (iptr[2].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IF_LEQ;
+icmd_lconst_lcmp_tail:
+ iptr[0].op1 = iptr[2].op1;
+ bptr->icount -= 2;
+ len -= 2;
+ /* iptr[1].opc = ICMD_NOP;
+ iptr[2].opc = ICMD_NOP; */
+ OP1_0(TYPE_LNG);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ COUNT(count_pcmd_op);
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IF_LNE;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IF_LLT;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IF_LGT;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IF_LLE;
+ goto icmd_lconst_lcmp_tail;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IF_LGE;
+ goto icmd_lconst_lcmp_tail;
+ default:
+ PUSHCONST(TYPE_LNG);
+ } /* switch (iptr[2].opc) */
+ } /* if (iptr[2].val.i == 0) */
+ else
+ PUSHCONST(TYPE_LNG);
+ break;
+ default:
+ PUSHCONST(TYPE_LNG);
+ }
+ }
+ else
+ PUSHCONST(TYPE_LNG);
+ break;
+ case ICMD_FCONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_FLT);
+ break;
+ case ICMD_DCONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_DBL);
+ break;
+ case ICMD_ACONST:
+ COUNT(count_pcmd_load);
+ PUSHCONST(TYPE_ADR);
+ break;
+
+ /* pop 0 push 1 load */
+
+ case ICMD_ILOAD:
+ case ICMD_LLOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
+ case ICMD_ALOAD:
+ COUNT(count_load_instruction);
+ i = opcode-ICMD_ILOAD;
+ locals[iptr->op1][i].type = i;
+ LOAD(i, LOCALVAR, iptr->op1);
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IALOAD:
+ case ICMD_LALOAD:
+ case ICMD_FALOAD:
+ case ICMD_DALOAD:
+ case ICMD_AALOAD:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP2IAT_1(opcode-ICMD_IALOAD);
+ break;
+
+ case ICMD_BALOAD:
+ case ICMD_CALOAD:
+ case ICMD_SALOAD:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP2IAT_1(TYPE_INT);
+ break;
+
+ /* pop 0 push 0 iinc */
+
+ case ICMD_IINC:
+#ifdef STATISTICS
+ i = stackdepth;
+ if (i >= 10)
+ count_store_depth[10]++;
+ else
+ count_store_depth[i]++;
+#endif
+ copy = curstack;
+ i = stackdepth - 1;
+ while (copy) {
+ if ((copy->varkind == LOCALVAR) &&
+ (copy->varnum == curstack->varnum)) {
+ copy->varkind = TEMPVAR;
+ copy->varnum = i;
+ }
+ i--;
+ copy = copy->prev;
+ }
+ SETDST;
+ break;
+
+ /* pop 1 push 0 store */
+
+ case ICMD_ISTORE:
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
+ case ICMD_ASTORE:
+ i = opcode-ICMD_ISTORE;
+ locals[iptr->op1][i].type = i;
+#ifdef STATISTICS
+ count_pcmd_store++;
+ i = new - curstack;
+ if (i >= 20)
+ count_store_length[20]++;
+ else
+ count_store_length[i]++;
+ i = stackdepth - 1;
+ if (i >= 10)
+ count_store_depth[10]++;
+ else
+ count_store_depth[i]++;
+#endif
+ copy = curstack->prev;
+ i = stackdepth - 2;
+ while (copy) {
+ if ((copy->varkind == LOCALVAR) &&
+ (copy->varnum == curstack->varnum)) {
+ copy->varkind = TEMPVAR;
+ copy->varnum = i;
+ }
+ i--;
+ copy = copy->prev;
+ }
+ if ((new - curstack) == 1) {
+ curstack->varkind = LOCALVAR;
+ curstack->varnum = iptr->op1;
+ };
+ STORE(opcode-ICMD_ISTORE);
+ break;
+
+ /* pop 3 push 0 */
+
+ case ICMD_IASTORE:
+ case ICMD_LASTORE:
+ case ICMD_FASTORE:
+ case ICMD_DASTORE:
+ case ICMD_AASTORE:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP3TIA_0(opcode-ICMD_IASTORE);
+ break;
+ case ICMD_BASTORE:
+ case ICMD_CASTORE:
+ case ICMD_SASTORE:
+ COUNT(count_check_null);
+ COUNT(count_check_bound);
+ COUNT(count_pcmd_mem);
+ OP3TIA_0(TYPE_INT);
+ break;
+
+ /* pop 1 push 0 */
+
+ case ICMD_POP:
+ OP1_0ANY;
+ break;
+
+ case ICMD_IRETURN:
+ case ICMD_LRETURN:
+ case ICMD_FRETURN:
+ case ICMD_DRETURN:
+ case ICMD_ARETURN:
+ COUNT(count_pcmd_return);
+ OP1_0(opcode-ICMD_IRETURN);
+ superblockend = true;
+ break;
+
+ case ICMD_ATHROW:
+ COUNT(count_check_null);
+ OP1_0(TYPE_ADR);
+ STACKRESET;
+ SETDST;
+ superblockend = true;
+ break;
+
+ case ICMD_PUTSTATIC:
+ COUNT(count_pcmd_mem);
+ OP1_0(iptr->op1);
+ break;
+
+ /* pop 1 push 0 branch */
+
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+ COUNT(count_pcmd_bra);
+ OP1_0(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+ COUNT(count_pcmd_bra);
+#ifdef CONDITIONAL_LOADCONST
+ {
+ tbptr = block + b_index;
+ if ((b_count >= 3) &&
+ ((b_index + 2) == block_index[iptr[0].op1]) &&
+ (tbptr[1].pre_count == 1) &&
+ (iptr[1].opc == ICMD_ICONST) &&
+ (iptr[2].opc == ICMD_GOTO) &&
+ ((b_index + 3) == block_index[iptr[2].op1]) &&
+ (tbptr[2].pre_count == 1) &&
+ (iptr[3].opc == ICMD_ICONST)) {
+ OP1_1(TYPE_INT, TYPE_INT);
+ switch (iptr[0].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IFNE_ICONST;
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IFEQ_ICONST;
+ break;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IFGE_ICONST;
+ break;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IFLT_ICONST;
+ break;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IFLE_ICONST;
+ break;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IFGT_ICONST;
+ break;
+ }
+ iptr[0].val.i = iptr[1].val.i;
+ iptr[1].opc = ICMD_ELSE_ICONST;
+ iptr[1].val.i = iptr[3].val.i;
+ iptr[2].opc = ICMD_NOP;
+ iptr[3].opc = ICMD_NOP;
+ tbptr[1].flags = BBDELETED;
+ tbptr[2].flags = BBDELETED;
+ tbptr[1].icount = 0;
+ tbptr[2].icount = 0;
+ if (tbptr[3].pre_count == 2) {
+ len += tbptr[3].icount + 3;
+ bptr->icount += tbptr[3].icount + 3;
+ tbptr[3].flags = BBDELETED;
+ tbptr[3].icount = 0;
+ b_index++;
+ }
+ else {
+ bptr->icount++;
+ len ++;
+ }
+ b_index += 2;
+ break;
+ }
+ }
+#endif
+ OP1_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ /* pop 0 push 0 branch */
+
+ case ICMD_GOTO:
+ COUNT(count_pcmd_bra);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 1 push 0 table branch */
+
+ case ICMD_TABLESWITCH:
+ COUNT(count_pcmd_table);
+ OP1_0(TYPE_INT);
+ s4ptr = iptr->val.a;
+ tbptr = block + block_index[*s4ptr++]; /* default */
+ MARKREACHED(tbptr, copy);
+ i = *s4ptr++; /* low */
+ i = *s4ptr++ - i + 1; /* high */
+ while (--i >= 0) {
+ tbptr = block + block_index[*s4ptr++];
+ MARKREACHED(tbptr, copy);
+ }
+ SETDST;
+ superblockend = true;
+ break;
+
+ /* pop 1 push 0 table branch */
+
+ case ICMD_LOOKUPSWITCH:
+ COUNT(count_pcmd_table);
+ OP1_0(TYPE_INT);
+ s4ptr = iptr->val.a;
+ tbptr = block + block_index[*s4ptr++]; /* default */
+ MARKREACHED(tbptr, copy);
+ i = *s4ptr++; /* count */
+ while (--i >= 0) {
+ tbptr = block + block_index[s4ptr[1]];
+ MARKREACHED(tbptr, copy);
+ s4ptr += 2;
+ }
+ SETDST;
+ superblockend = true;
+ break;
+
+ case ICMD_NULLCHECKPOP:
+ case ICMD_MONITORENTER:
+ COUNT(count_check_null);
+ case ICMD_MONITOREXIT:
+ OP1_0(TYPE_ADR);
+ break;
+
+ /* pop 2 push 0 branch */
+
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+ COUNT(count_pcmd_bra);
+ OP2_0(TYPE_INT);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ COUNT(count_pcmd_bra);
+ OP2_0(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ break;
+
+ /* pop 2 push 0 */
+
+ case ICMD_PUTFIELD:
+ COUNT(count_check_null);
+ COUNT(count_pcmd_mem);
+ OPTT2_0(iptr->op1,TYPE_ADR);
+ break;
+
+ case ICMD_POP2:
+ if (! IS_2_WORD_TYPE(curstack->type)) {
+ OP1_0ANY; /* second pop */
+ }
+ else
+ iptr->opc = ICMD_POP;
+ OP1_0ANY;
+ break;
+
+ /* pop 0 push 1 dup */
+
+ case ICMD_DUP:
+ COUNT(count_dup_instruction);
+ DUP;
+ break;
+
+ case ICMD_DUP2:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ iptr->opc = ICMD_DUP;
+ DUP;
+ }
+ else {
+ copy = curstack;
+ NEWSTACK(copy[-1].type, copy[-1].varkind,
+ copy[-1].varnum);
+ NEWSTACK(copy[ 0].type, copy[ 0].varkind,
+ copy[ 0].varnum);
+ SETDST;
+ stackdepth+=2;
+ }
+ break;
+
+ /* pop 2 push 3 dup */
+
+ case ICMD_DUP_X1:
+ DUP_X1;
+ break;
+
+ case ICMD_DUP2_X1:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ DUP2_X1;
+ }
+ break;
+
+ /* pop 3 push 4 dup */
+
+ case ICMD_DUP_X2:
+ if (IS_2_WORD_TYPE(curstack[-1].type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ DUP_X2;
+ }
+ break;
+
+ case ICMD_DUP2_X2:
+ if (IS_2_WORD_TYPE(curstack->type)) {
+ if (IS_2_WORD_TYPE(curstack[-1].type)) {
+ iptr->opc = ICMD_DUP_X1;
+ DUP_X1;
+ }
+ else {
+ iptr->opc = ICMD_DUP_X2;
+ DUP_X2;
+ }
+ }
+ else
+ if (IS_2_WORD_TYPE(curstack[-2].type)) {
+ iptr->opc = ICMD_DUP2_X1;
+ DUP2_X1;
+ }
+ else {
+ DUP2_X2;
+ }
+ break;
+
+ /* pop 2 push 2 swap */
+
+ case ICMD_SWAP:
+ SWAP;
+ break;
+
+ /* pop 2 push 1 */
+
+ case ICMD_IDIV:
+ if (!(SUPPORT_DIVISION)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_INT;
+ iptr[0].val.a = (functionptr) asm_builtin_idiv;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_LDIV:
+ if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_LNG;
+ iptr[0].val.a = (functionptr) asm_builtin_ldiv;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_IREM:
+ if (!(SUPPORT_DIVISION)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_INT;
+ iptr[0].val.a = (functionptr) asm_builtin_irem;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_LREM:
+ if (!(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_MULDIV)) {
+ iptr[0].opc = ICMD_BUILTIN2;
+ iptr[0].op1 = TYPE_LNG;
+ iptr[0].val.a = (functionptr) asm_builtin_lrem;
+ isleafmethod = false;
+ goto builtin2;
+ }
+
+ case ICMD_IADD:
+ case ICMD_ISUB:
+ case ICMD_IMUL:
+
+ case ICMD_ISHL:
+ case ICMD_ISHR:
+ case ICMD_IUSHR:
+ case ICMD_IAND:
+ case ICMD_IOR:
+ case ICMD_IXOR:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_INT);
+ break;
+
+ case ICMD_LADD:
+ case ICMD_LSUB:
+ case ICMD_LMUL:
+
+ case ICMD_LOR:
+ case ICMD_LAND:
+ case ICMD_LXOR:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_LNG);
+ break;
+
+ case ICMD_LSHL:
+ case ICMD_LSHR:
+ case ICMD_LUSHR:
+ COUNT(count_pcmd_op);
+ OP2IT_1(TYPE_LNG);
+ break;
+
+ case ICMD_FADD:
+ case ICMD_FSUB:
+ case ICMD_FMUL:
+ case ICMD_FDIV:
+ case ICMD_FREM:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_FLT);
+ break;
+
+ case ICMD_DADD:
+ case ICMD_DSUB:
+ case ICMD_DMUL:
+ case ICMD_DDIV:
+ case ICMD_DREM:
+ COUNT(count_pcmd_op);
+ OP2_1(TYPE_DBL);
+ break;
+
+ case ICMD_LCMP:
+ COUNT(count_pcmd_op);
+ if ((len > 0) && (iptr[1].val.i == 0)) {
+ switch (iptr[1].opc) {
+ case ICMD_IFEQ:
+ iptr[0].opc = ICMD_IF_LCMPEQ;
+icmd_lcmp_if_tail:
+ iptr[0].op1 = iptr[1].op1;
+ len--;
+ bptr->icount--;
+ /* iptr[1].opc = ICMD_NOP; */
+ OP2_0(TYPE_LNG);
+ tbptr = block + block_index[iptr->op1];
+ MARKREACHED(tbptr, copy);
+ COUNT(count_pcmd_bra);
+ break;
+ case ICMD_IFNE:
+ iptr[0].opc = ICMD_IF_LCMPNE;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFLT:
+ iptr[0].opc = ICMD_IF_LCMPLT;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFGT:
+ iptr[0].opc = ICMD_IF_LCMPGT;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFLE:
+ iptr[0].opc = ICMD_IF_LCMPLE;
+ goto icmd_lcmp_if_tail;
+ case ICMD_IFGE:
+ iptr[0].opc = ICMD_IF_LCMPGE;
+ goto icmd_lcmp_if_tail;
+ default:
+ OPTT2_1(TYPE_LNG, TYPE_INT);
+ }
+ }
+ else
+ OPTT2_1(TYPE_LNG, TYPE_INT);
+ break;
+ case ICMD_FCMPL:
+ case ICMD_FCMPG:
+ COUNT(count_pcmd_op);
+ OPTT2_1(TYPE_FLT, TYPE_INT);
+ break;
+ case ICMD_DCMPL:
+ case ICMD_DCMPG:
+ COUNT(count_pcmd_op);
+ OPTT2_1(TYPE_DBL, TYPE_INT);
+ break;
+
+ /* pop 1 push 1 */
+
+ case ICMD_INEG:
+ case ICMD_INT2BYTE:
+ case ICMD_INT2CHAR:
+ case ICMD_INT2SHORT:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_INT);
+ break;
+ case ICMD_LNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_LNG);
+ break;
+ case ICMD_FNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_FLT);
+ break;
+ case ICMD_DNEG:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_DBL);
+ break;
+
+ case ICMD_I2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_LNG);
+ break;
+ case ICMD_I2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_FLT);
+ break;
+ case ICMD_I2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_INT, TYPE_DBL);
+ break;
+ case ICMD_L2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_INT);
+ break;
+ case ICMD_L2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_FLT);
+ break;
+ case ICMD_L2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_LNG, TYPE_DBL);
+ break;
+ case ICMD_F2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_INT);
+ break;
+ case ICMD_F2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_LNG);
+ break;
+ case ICMD_F2D:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_FLT, TYPE_DBL);
+ break;
+ case ICMD_D2I:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_INT);
+ break;
+ case ICMD_D2L:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_LNG);
+ break;
+ case ICMD_D2F:
+ COUNT(count_pcmd_op);
+ OP1_1(TYPE_DBL, TYPE_FLT);
+ break;
+
+ case ICMD_CHECKCAST:
+ OP1_1(TYPE_ADR, TYPE_ADR);
+ break;
+
+ case ICMD_ARRAYLENGTH:
+ case ICMD_INSTANCEOF:
+ OP1_1(TYPE_ADR, TYPE_INT);
+ break;
+
+ case ICMD_NEWARRAY:
+ case ICMD_ANEWARRAY:
+ OP1_1(TYPE_INT, TYPE_ADR);
+ break;
+
+ case ICMD_GETFIELD:
+ COUNT(count_check_null);
+ COUNT(count_pcmd_mem);
+ OP1_1(TYPE_ADR, iptr->op1);
+ break;
+
+ /* pop 0 push 1 */
+
+ case ICMD_GETSTATIC:
+ COUNT(count_pcmd_mem);
+ OP0_1(iptr->op1);
+ break;
+
+ case ICMD_NEW:
+ OP0_1(TYPE_ADR);
+ break;
+
+ case ICMD_JSR:
+ OP0_1(TYPE_ADR);
+ tbptr = block + block_index[iptr->op1];
+ tbptr->type=BBTYPE_SBR;
+ MARKREACHED(tbptr, copy);
+ OP1_0ANY;
+ break;
+
+ /* pop many push any */
+
+ case ICMD_INVOKEVIRTUAL:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKEINTERFACE:
+ case ICMD_INVOKESTATIC:
+ COUNT(count_pcmd_met);
+ {
+ methodinfo *m = iptr->val.a;
+ if (m->flags & ACC_STATIC)
+ {COUNT(count_check_null);}
+ i = iptr->op1;
+ if (i > arguments_num)
+ arguments_num = i;
+ copy = curstack;
+ while (--i >= 0) {
+ if (! (copy->flags & SAVEDVAR)) {
+ copy->varkind = ARGVAR;
+ copy->varnum = i;
+ }
+ copy = copy->prev;
+ }
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ i = iptr->op1;
+ POPMANY(i);
+ if (m->returntype != TYPE_VOID) {
+ OP0_1(m->returntype);
+ }
+ break;
+ }
+
+ case ICMD_BUILTIN3:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 2;
+ }
+ OP1_0ANY;
+ case ICMD_BUILTIN2:
+builtin2:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 1;
+ }
+ OP1_0ANY;
+ case ICMD_BUILTIN1:
+ if (! (curstack->flags & SAVEDVAR)) {
+ curstack->varkind = ARGVAR;
+ curstack->varnum = 0;
+ }
+ OP1_0ANY;
+ copy = curstack;
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ if (iptr->op1 != TYPE_VOID)
+ OP0_1(iptr->op1);
+ break;
+
+ case ICMD_MULTIANEWARRAY:
+ i = iptr->op1;
+ if ((i + intreg_argnum) > arguments_num)
+ arguments_num = i + intreg_argnum;
+ copy = curstack;
+ while (--i >= 0) {
+ if (! (copy->flags & SAVEDVAR)) {
+ copy->varkind = ARGVAR;
+ copy->varnum = i + intreg_argnum;
+ }
+ copy = copy->prev;
+ }
+ while (copy) {
+ copy->flags |= SAVEDVAR;
+ copy = copy->prev;
+ }
+ i = iptr->op1;
+ POPMANY(i);
+ OP0_1(TYPE_ADR);
+ break;
+
+ default:
+ printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+ panic("Missing ICMD code during stack analysis");
+ } /* switch */
+ iptr++;
+ } /* while instructions */
+ bptr->outstack = curstack;
+ bptr->outdepth = stackdepth;
+ BBEND(curstack, i);
+ } /* if */
+ else
+ superblockend = true;
+ bptr++;
+ } /* while blocks */
+ } while (repeat && ! deadcode);
+
+#ifdef STATISTICS
+ if (block_count > count_max_basic_blocks)
+ count_max_basic_blocks = block_count;
+ count_basic_blocks += block_count;
+ if (instr_count > count_max_javainstr)
+ count_max_javainstr = instr_count;
+ count_javainstr += instr_count;
+ if (stack_count > count_upper_bound_new_stack)
+ count_upper_bound_new_stack = stack_count;
+ if ((new - stack) > count_max_new_stack)
+ count_max_new_stack = (new - stack);
+
+ b_count = block_count;
+ bptr = block;
+ while (--b_count >= 0) {
+ if (bptr->flags > BBREACHED) {
+ if (bptr->indepth >= 10)
+ count_block_stack[10]++;
+ else
+ count_block_stack[bptr->indepth]++;
+ len = bptr->icount;
+ if (len <= 10)
+ count_block_size_distribution[len - 1]++;
+ else if (len <= 12)
+ count_block_size_distribution[10]++;
+ else if (len <= 14)
+ count_block_size_distribution[11]++;
+ else if (len <= 16)
+ count_block_size_distribution[12]++;
+ else if (len <= 18)
+ count_block_size_distribution[13]++;
+ else if (len <= 20)
+ count_block_size_distribution[14]++;
+ else if (len <= 25)
+ count_block_size_distribution[15]++;
+ else if (len <= 30)
+ count_block_size_distribution[16]++;
+ else
+ count_block_size_distribution[17]++;
+ }
+ bptr++;
+ }
+
+ if (loops == 1)
+ count_analyse_iterations[0]++;
+ else if (loops == 2)
+ count_analyse_iterations[1]++;
+ else if (loops == 3)
+ count_analyse_iterations[2]++;
+ else if (loops == 4)
+ count_analyse_iterations[3]++;
+ else
+ count_analyse_iterations[4]++;
+
+ if (block_count <= 5)
+ count_method_bb_distribution[0]++;
+ else if (block_count <= 10)
+ count_method_bb_distribution[1]++;
+ else if (block_count <= 15)
+ count_method_bb_distribution[2]++;
+ else if (block_count <= 20)
+ count_method_bb_distribution[3]++;
+ else if (block_count <= 30)
+ count_method_bb_distribution[4]++;
+ else if (block_count <= 40)
+ count_method_bb_distribution[5]++;
+ else if (block_count <= 50)
+ count_method_bb_distribution[6]++;
+ else if (block_count <= 75)
+ count_method_bb_distribution[7]++;
+ else
+ count_method_bb_distribution[8]++;
+#endif
+}
+
+
+static void print_stack(stackptr s) {
+ int i, j;
+ stackptr t;
+
+ i = maxstack;
+ t = s;
+
+ while (t) {
+ i--;
+ t = t->prev;
+ }
+ j = maxstack - i;
+ while (--i >= 0)
+ printf(" ");
+ while (s) {
+ j--;
+ if (s->flags & SAVEDVAR)
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" m%02d", s->regoff);
+ else
+ printf(" r%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" s%02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" l%02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" a%02d", s->varnum);
+ break;
+ default:
+ printf(" !%02d", j);
+ }
+ else
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" M%02d", s->regoff);
+ else
+ printf(" R%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" S%02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" L%02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" A%02d", s->varnum);
+ break;
+ default:
+ printf(" ?%02d", j);
+ }
+ s = s->prev;
+ }
+}
+
+
+static void print_reg(stackptr s) {
+ if (s) {
+ if (s->flags & SAVEDVAR)
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" tm%02d", s->regoff);
+ else
+ printf(" tr%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" s %02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" l %02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" a %02d", s->varnum);
+ break;
+ default:
+ printf(" ! %02d", s->varnum);
+ }
+ else
+ switch (s->varkind) {
+ case TEMPVAR:
+ if (s->flags & INMEMORY)
+ printf(" Tm%02d", s->regoff);
+ else
+ printf(" Tr%02d", s->regoff);
+ break;
+ case STACKVAR:
+ printf(" S %02d", s->varnum);
+ break;
+ case LOCALVAR:
+ printf(" L %02d", s->varnum);
+ break;
+ case ARGVAR:
+ printf(" A %02d", s->varnum);
+ break;
+ default:
+ printf(" ? %02d", s->varnum);
+ }
+ }
+ else
+ printf(" ");
+
+}
+
+
+static char *builtin_name(functionptr bptr)
+{
+ builtin_descriptor *bdesc = builtin_desc;
+ while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
+ bdesc++;
+ return bdesc->name;
+}
+
+
+static void show_icmd_method()
+{
+ int b, i, j, last;
+ int deadcode;
+ s4 *s4ptr;
+ instruction *iptr;
+
+ printf("\n");
+ unicode_fprint(stdout, class->name);
+ printf(".");
+ unicode_fprint(stdout, method->name);
+ printf(" ");
+ unicode_fprint(stdout, method->descriptor);
+ printf ("\n\nMax locals: %d\n", (int) maxlocals);
+ printf ("Max stack: %d\n", (int) maxstack);
+
+ printf ("Exceptions:\n");
+ for (i = 0; i < exceptiontablelength; i++) {
+ printf(" L%03d ... ", block_index[extable[i].startpc]);
+ printf("L%03d = ", block_index[extable[i].endpc]);
+ printf("L%03d\n", block_index[extable[i].handlerpc]);
+ }
+
+ printf ("Local Table:\n");
+ for (i = 0; i < maxlocals; i++) {
+ printf(" %3d: ", i);
+ for (j = TYPE_INT; j <= TYPE_ADR; j++)
+ if (locals[i][j].type >= 0) {
+ printf(" (%d) ", j);
+ if (locals[i][j].flags)
+ printf("m");
+ else
+ printf("r");
+ printf("%2d", locals[i][j].regoff);
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ printf ("Interface Table:\n");
+ for (i = 0; i < maxstack; i++) {
+ if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
+ (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
+ (interfaces[i][4].type >= 0)) {
+ printf(" %3d: ", i);
+ for (j = TYPE_INT; j <= TYPE_ADR; j++)
+ if (interfaces[i][j].type >= 0) {
+ printf(" (%d) ", j);
+ if (interfaces[i][j].flags & SAVEDVAR)
+ printf("s");
+ else
+ printf("t");
+ if (interfaces[i][j].flags & INMEMORY)
+ printf("m");
+ else
+ printf("r");
+ printf("%2d", interfaces[i][j].regoff);
+ }
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ if (showdisassemble) {
+ s4ptr = (s4 *) (method->mcode + dseglen);
+ for (i = 0; i < block[0].mpc; i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+
+ for (b = 0; b < block_count; b++)
+ if (block[b].flags != BBDELETED) {
+ deadcode = block[b].flags <= BBREACHED;
+ printf("[");
+ if (deadcode)
+ for (j = maxstack; j > 0; j--)
+ printf(" ? ");
+ else
+ print_stack(block[b].instack);
+ printf("] L%03d(%d):\n", b, block[b].pre_count);
+ iptr = block[b].iinstr;
+ i = iptr - instr;
+ for (last = i + block[b].icount; i < last; i++, iptr++) {
+ printf("[");
+ if (deadcode) {
+ for (j = maxstack; j > 0; j--)
+ printf(" ? ");
+ }
+ else
+ print_stack(iptr->dst);
+ printf("] %4d %s", i, icmd_names[iptr->opc]);
+ switch ((int) iptr->opc) {
+ case ICMD_IADDCONST:
+ case ICMD_ISUBCONST:
+ case ICMD_IMULCONST:
+ case ICMD_IDIVPOW2:
+ case ICMD_IREMPOW2:
+ case ICMD_IREM0X10001:
+ case ICMD_IANDCONST:
+ case ICMD_IORCONST:
+ case ICMD_IXORCONST:
+ case ICMD_ISHLCONST:
+ case ICMD_ISHRCONST:
+ case ICMD_IUSHRCONST:
+ case ICMD_ICONST:
+ case ICMD_ELSE_ICONST:
+ case ICMD_IFEQ_ICONST:
+ case ICMD_IFNE_ICONST:
+ case ICMD_IFLT_ICONST:
+ case ICMD_IFGE_ICONST:
+ case ICMD_IFGT_ICONST:
+ case ICMD_IFLE_ICONST:
+ printf(" %d", iptr->val.i);
+ break;
+ case ICMD_LADDCONST:
+ case ICMD_LSUBCONST:
+ case ICMD_LMULCONST:
+ case ICMD_LDIVPOW2:
+ case ICMD_LREMPOW2:
+ case ICMD_LANDCONST:
+ case ICMD_LORCONST:
+ case ICMD_LXORCONST:
+ case ICMD_LSHLCONST:
+ case ICMD_LSHRCONST:
+ case ICMD_LUSHRCONST:
+ case ICMD_LCONST:
+ printf(" %ld", iptr->val.l);
+ break;
+ case ICMD_FCONST:
+ printf(" %f", iptr->val.f);
+ break;
+ case ICMD_DCONST:
+ printf(" %f", iptr->val.d);
+ break;
+ case ICMD_ACONST:
+ printf(" %p", iptr->val.a);
+ break;
+ case ICMD_GETFIELD:
+ case ICMD_PUTFIELD:
+ printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
+ case ICMD_PUTSTATIC:
+ case ICMD_GETSTATIC:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((fieldinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_IINC:
+ printf(" %d + %d", iptr->op1, iptr->val.i);
+ break;
+ case ICMD_RET:
+ case ICMD_ILOAD:
+ case ICMD_LLOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
+ case ICMD_ALOAD:
+ case ICMD_ISTORE:
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
+ case ICMD_ASTORE:
+ printf(" %d", iptr->op1);
+ break;
+ case ICMD_NEW:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((classinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_NEWARRAY:
+ switch (iptr->op1) {
+ case 4:
+ printf(" boolean");
+ break;
+ case 5:
+ printf(" char");
+ break;
+ case 6:
+ printf(" float");
+ break;
+ case 7:
+ printf(" double");
+ break;
+ case 8:
+ printf(" byte");
+ break;
+ case 9:
+ printf(" short");
+ break;
+ case 10:
+ printf(" int");
+ break;
+ case 11:
+ printf(" long");
+ break;
+ }
+ break;
+ case ICMD_ANEWARRAY:
+ if (iptr->op1) {
+ printf(" ");
+ unicode_fprint(stdout,
+ ((classinfo *) iptr->val.a)->name);
+ }
+ break;
+ case ICMD_CHECKCAST:
+ case ICMD_INSTANCEOF:
+ if (iptr->op1) {
+ classinfo *c = iptr->val.a;
+ if (c->flags & ACC_INTERFACE)
+ printf(" (INTERFACE) ");
+ else
+ printf(" (CLASS,%3d) ", c->vftbl->diffval);
+ unicode_fprint(stdout, c->name);
+ }
+ break;
+ case ICMD_BUILTIN3:
+ case ICMD_BUILTIN2:
+ case ICMD_BUILTIN1:
+ printf(" %s", builtin_name((functionptr) iptr->val.a));
+ break;
+ case ICMD_INVOKEVIRTUAL:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKESTATIC:
+ case ICMD_INVOKEINTERFACE:
+ printf(" ");
+ unicode_fprint(stdout,
+ ((methodinfo *) iptr->val.a)->class->name);
+ printf(".");
+ unicode_fprint(stdout,
+ ((methodinfo *) iptr->val.a)->name);
+ break;
+ case ICMD_IFEQ:
+ case ICMD_IFNE:
+ case ICMD_IFLT:
+ case ICMD_IFGE:
+ case ICMD_IFGT:
+ case ICMD_IFLE:
+ case ICMD_IF_LEQ:
+ case ICMD_IF_LNE:
+ case ICMD_IF_LLT:
+ case ICMD_IF_LGE:
+ case ICMD_IF_LGT:
+ case ICMD_IF_LLE:
+ printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+ break;
+ case ICMD_JSR:
+ case ICMD_GOTO:
+ case ICMD_IFNULL:
+ case ICMD_IFNONNULL:
+ case ICMD_IF_ICMPEQ:
+ case ICMD_IF_ICMPNE:
+ case ICMD_IF_ICMPLT:
+ case ICMD_IF_ICMPGE:
+ case ICMD_IF_ICMPGT:
+ case ICMD_IF_ICMPLE:
+ case ICMD_IF_LCMPEQ:
+ case ICMD_IF_LCMPNE:
+ case ICMD_IF_LCMPLT:
+ case ICMD_IF_LCMPGE:
+ case ICMD_IF_LCMPGT:
+ case ICMD_IF_LCMPLE:
+ case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPNE:
+ printf(" L%03d", block_index[iptr->op1]);
+ break;
+ case ICMD_TABLESWITCH:
+ s4ptr = iptr->val.a;
+ printf(" L%03d;", block_index[*s4ptr++]); /* default */
+ j = *s4ptr++; /* low */
+ j = *s4ptr++ - j; /* high */
+ while (j >= 0) {
+ printf(" L%03d", block_index[*s4ptr++]);
+ j--;
+ }
+ break;
+ case ICMD_LOOKUPSWITCH:
+ s4ptr = iptr->val.a;
+ printf(" L%d", block_index[*s4ptr++]); /* default */
+ j = *s4ptr++; /* count */
+ while (--j >= 0) {
+ printf(" L%03d", block_index[s4ptr[1]]);
+ s4ptr += 2;
+ }
+ break;
+ }
+ printf("\n");
+ }
+
+ if (showdisassemble && (!deadcode)) {
+ printf("\n");
+ i = block[b].mpc;
+ s4ptr = (s4 *) (method->mcode + dseglen + i);
+ for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+ }
+ i = block[b].mpc;
+ s4ptr = (s4 *) (method->mcode + dseglen + i);
+ if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
+ printf("\n");
+ for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+ disassinstr(*s4ptr, i);
+ }
+ printf("\n");
+ }
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
#include "tables.h"
#include "native.h"
#include "builtin.h"
+#include "jit.h"
+#ifdef OLD_COMPILER
#include "compiler.h"
+#endif
#include "asmpart.h"
#include "threads/thread.h" /* schani */
functionptr f = native_findfunction
(c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
if (f) {
+#ifdef OLD_COMPILER
if (newcompiler)
- m -> stubroutine = ncreatenativestub (f, m);
- else
+#endif
m -> stubroutine = createnativestub (f, m);
+#ifdef OLD_COMPILER
+ else
+ m -> stubroutine = oldcreatenativestub (f, m);
+#endif
}
}