⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jit3-i386.def

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 DEF
📖 第 1 页 / 共 3 页
字号:
/* jit3-i386.def * i386 instruction definition. * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * Cross-language profiling changes contributed by * the Flux Research Group, Department of Computer Science, * University of Utah, http://www.cs.utah.edu/flux/ * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "debug.h"#include "classMethod.h"#include "md.h"#include "xprofiler.h"#if defined(TRACE_METHOD_END) && defined(__GNUC__)asm(".globl tStore\ntStore:	.long 0,0");#endif#ifdef KAFFE_VMDEBUGint jit_debug;#define	debug(x)	(jit_debug ? dprintf("%x:\t", CODEPC), dprintf x : 0)#else#define	debug(x)#endif#define	do_move_int(t, f)					\	if ((t) != (f)) {					\		OUT = 0x89;					\		OUT = 0xC0|(f<<3)|t;				\		debug(("movl %s,%s\n", regname(f), regname(t)));\	}#define	check_reg_01()						\	{							\		int _r_ = rreg_int(1);				\		int _w_ = wreg_int(0);				\		do_move_int(_w_, _r_);				\	}#define	set_slot_register(S,R,T)				\	forceRegister(S, R, T)#define	force_move_int(S, T, F)					\	if ((T) != (F)) {					\		set_slot_register(S, (T), Rint);		\		do_move_int((T), (F));				\		F = (T);					\	}#define	safe_move_int(T, F)					\	if ((T) != (F)) {					\		clobberRegister(T);				\		do_move_int((T), (F));				\		F = (T);					\	}char* rnames[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "flt0/dbl0" };#define	regname(n)	rnames[n]#define	REG_eax		0#define	REG_ecx		1#define	REG_edx		2#define	REG_ebx		3#define	REG_esp		4#define	REG_ebp		5#define	REG_esi		6#define	REG_edi		7#define	REG_flt0	8#define	REG_dbl0	REG_flt0/* IEEE mode setup */#define	IEEE_INVAL	0x0001#define	IEEE_DENORM	0x0002#define	IEEE_DIVZ	0x0004#define	IEEE_OVERF	0x0008#define	IEEE_UNDERF	0x0010#define	IEEE_LOS	0x0020#define	IEEE_NEAREST	0x0000#define	IEEE_DOWN	0x0400#define	IEEE_UP		0x0800#define	IEEE_CHOP	0x0C00#define	IEEE_EXTRA	0x1200#define	IEEE_MODE	(IEEE_DENORM|IEEE_UNDERF|IEEE_LOS|IEEE_DIVZ|IEEE_NEAREST|IEEE_EXTRA)extern bool used_ieee_division;#if defined(KAFFE_PROFILER)/* This code reads the timestamp register, and substracts it * from COUNTER.  As this will scratch EDX and EAX, the second * parameter said if they must be saved.  */#define profiler_start(COUNTER, SAVE_EDX_EAX) do {		\	int *__counter = (int *)&(COUNTER);			\	if (SAVE_EDX_EAX) {					\		/* Save EAX and EDX */				\		OUT = 0x50|REG_edx;				\		OUT = 0x50|REG_eax;				\		debug(("pushl edx\n"));				\		debug(("pushl eax\n"));				\	}							\								\	OUT = 0x0F;						\	OUT = 0x31;						\	debug(("rdtsc\n"));					\								\	OUT = 0x29;						\	OUT = 0x05;						\	LOUT = (int)(__counter);				\	debug(("sub eax, 0x%x\n", (int)(__counter)));		\								\	OUT = 0x19;						\	OUT = 0x15;						\	LOUT = (int)(__counter + 1);				\	debug(("sbb edx, 0x%x\n", (int)(__counter + 1)));	\								\	if (SAVE_EDX_EAX) {					\		/* Restore EAX and EDX */			\		OUT = 0x58|REG_eax;				\		OUT = 0x58|REG_edx;				\		debug(("popl eax\n"));				\		debug(("popl edx\n"));				\	}							\} while(0)/* This code reads the timestamp register, and add it to COUNTER. * As this will scratch EDX and EAX, the second parameter said if * they must be saved.  */#define profiler_end(COUNTER, SAVE_EDX_EAX) do {		\	int *__counter = (int *)&(COUNTER);			\	if (SAVE_EDX_EAX) {					\		/* Save EAX and EDX */				\		OUT = 0x50|REG_edx;				\		OUT = 0x50|REG_eax;				\		debug(("pushl edx\n"));				\		debug(("pushl eax\n"));				\	}							\								\	OUT = 0x0F;						\	OUT = 0x31;						\	debug(("rdtsc\n"));					\								\	OUT = 0x01;						\	OUT = 0x05;						\	LOUT = (int)(__counter);				\	debug(("add eax, 0x%x\n", (int)(__counter)));		\								\	OUT = 0x11;						\	OUT = 0x15;						\	LOUT = (int)(__counter + 1);				\	debug(("adc edx, 0x%x\n", (int)(__counter + 1)));	\								\	if (SAVE_EDX_EAX) {					\		/* Restore EAX and EDX */			\		OUT = 0x58|REG_eax;				\		OUT = 0x58|REG_edx;				\		debug(("popl eax\n"));				\		debug(("popl edx\n"));				\	}							\} while(0)#endif/* --------------------------------------------------------------------- */define_insn(unimplemented, unimplemented){	ABORT();}define_insn(nop, nop){	OUT = 0x90;}/* --------------------------------------------------------------------- */define_insn(prologue, prologue_xxx){	label* l;	if (profFlag) {		debug(("Method: %s\n", globalMethod->name->data));	}#if defined(KAFFE_XPROFILER)	if (xProfFlag)	{		/* Store the pointer to this function in eax */		OUT = 0xB8|REG_eax;		l = (label*)newLabel();		l->type = Llong|Linternal|Labsolute;		l->to = 0;		l->at = (uintp)CODEPC;		LOUT = 0;		debug(("movl #?,eax\n"));		/* Push second arg to profileArcHit */		OUT = 0x50|REG_eax;		debug(("pushl eax\n"));		/* Get return address from the stack */		OUT = 0x8B;		OUT = (REG_eax<<3)|0x44;		OUT = 0x24;		OUT = 0x04;		debug(("movl eax,4(esp)\n"));		/* Push first arg to profileArcHit */		OUT = 0x50|REG_eax;		debug(("pushl eax\n"));		/* Load the address to profileArcHit */		OUT = 0xB8|REG_eax;		LOUT = (int)profileArcHit;		debug(("movl profileArcHit,eax\n"));		/* Make the call */		OUT = 0xFF;		OUT = 0xD0|REG_eax;		debug(("call profileArcHit\n"));		/* Pop the args off */		OUT = 0x58|REG_eax;		debug(("popl eax\n"));		OUT = 0x58|REG_eax;		debug(("popl eax\n"));	}#endif	OUT = 0x50|REG_ebp;	OUT = 0x89;	OUT = 0xC0|(REG_esp<<3)|REG_ebp;	OUT = 0x81;	OUT = 0xE8|REG_esp;	l = (label*)const_int(1);	l->type = Lframe|Labsolute|Lgeneral;	l->at = (uintp)CODEPC;	LOUT = 0;	OUT = 0x50|REG_edi;	OUT = 0x50|REG_esi;	OUT = 0x50|REG_ebx;	debug(("pushl ebp\n"));	debug(("movl esp,ebp\n"));	debug(("subl #?,esp\n"));	debug(("pushl edi\n"));	debug(("pushl esi\n"));	debug(("pushl ebx\n"));#if defined(KAFFE_PROFILER)	if (profFlag)	{		profiler_start(globalMethod->totalClicks, 0);		OUT = 0xFF;		OUT = 0x05;		LOUT = (int)&(globalMethod->callsCount);		debug(("incl 0x%x\n",(int)&(globalMethod->callsCount)));	}#endif#if 0	/* If this method uses IEEE, set up the mode here */	if (used_ieee_division == true) {		OUT = 0x68;		LOUT = 0;		OUT = 0x68;		LOUT = 0;		debug(("pushl #0\n"));		debug(("pushl #0\n"));		OUT = 0xD9;		OUT = 0x3C;		OUT = 0x24;		debug(("fnstcw (esp)\n"));		OUT = 0x8B;		OUT = (REG_eax<<3)|0x04;		OUT = 0x24;		debug(("movl (esp),eax\n"));		OUT = 0xB8|REG_eax;		LOUT = IEEE_MODE;		debug(("movl %d,eax\n", IEEE_MODE));		OUT = 0x89;		OUT = (REG_eax<<3)|0x44;		OUT = 0x24;		OUT = 0x04;		debug(("movl eax,4(esp)\n"));		OUT = 0xD9;		OUT = 0x6C;		OUT = 0x24;		OUT = 0x04;		debug(("fldcw 4(esp)\n"));	}#endif}#if defined (HAVE_GCJ_SUPPORT)#include "gcj/gcj.h"/* * Establish JIT3 callee-saved register information for i386 * We must tell gcj where esi, edi, and ebx have been stored * on this frame, as an offset from the CFA. * In addition, we must tell it where the caller's esp was stored * * This depends on prologue_xxx so I put it here (XXX?). */voidarch_get_frame_description(int framesize,        struct kaffe_frame_descriptor frame_desc[],        int *n){        int i = 0;        int rsave_area_offset = CFA_OFFSET + framesize;        frame_desc[i].idx = DWARF_FRAME_RETURN_COLUMN;        frame_desc[i].offset = RETADDR_SAVED_OFFSET;        i++;        frame_desc[i].idx = CFA_REGISTER;               /* gcc_esp */        frame_desc[i].offset = CFA_SAVED_OFFSET;        i++;	if (framesize == -1) {		/* -1 indicates trampoline frame */		*n = i;		return;	}        /* NB: since CFA is pointing at caller's ret pc + 4,         * subtracting CFA_OFFSET + framesize points at the last         * slot.  The callee-saved registers are stored one word         * below, hence the 1 * 4         */        frame_desc[i].idx = DBX_REGISTER_NUMBER(/* gcc_edi */ 5);        frame_desc[i].offset = - (rsave_area_offset + 1 * 4);        i++;        frame_desc[i].idx = DBX_REGISTER_NUMBER(/* gcc_esi */ 4);        frame_desc[i].offset = - (rsave_area_offset + 2 * 4);        i++;        frame_desc[i].idx = DBX_REGISTER_NUMBER(/* gcc_ebx */ 3);        frame_desc[i].offset = - (rsave_area_offset + 3 * 4);        i++;        *n = i;}#endif /* HAVE_GCJ_SUPPORT */define_insn(check_stack_limit, check_stack_limit_xRC){	int r = rreg_int(1);	label* l = const_label(2);	OUT = 0x39;	OUT = 0xC0|(r<<3)|REG_esp;	debug(("cmpl esp,%s\n", regname(r)));	OUT = 0x0F;	OUT = 0x87;	LOUT = 5;	debug(("jugt +5\n"));	OUT = 0xE8;	l->type |= Llong|Lrelative;	l->at = CODEPC;	LOUT = 0;	l->from = CODEPC;	debug(("call soft_stackoverflow\n"));}define_insn(exception_prologue, eprologue_xLx){	label* l;	OUT = 0x89;	OUT = 0xC0|(REG_ebp<<3)|REG_ecx;	OUT = 0x81;	OUT = 0xE8|REG_ecx;	/* Remember where the framesize is to go */	l = (label*)const_int(1);	l->type = Lframe|Labsolute|Lgeneral;	l->at = (uintp)CODEPC;	LOUT = 0;	OUT = 0x81;	OUT = 0xE8|REG_ecx;	LOUT = 3*SLOTSIZE;	OUT = 0x89;	OUT = 0xC0|(REG_ecx<<3)|REG_esp;	debug(("movl ebp,ecx\n"));	debug(("subl #?,ecx\n"));	debug(("subl #3*SLOTSIZE,ecx\n"));	debug(("movl ecx,esp\n"));#if 0	if (used_ieee_division == true) {		OUT = 0x81;		OUT = 0xE8|REG_esp;		LOUT = SLOTSIZE;		debug(("subl #%d,esp\n", SLOTSIZE));		OUT = 0x8B;		OUT = (REG_eax<<3)|0x04;		OUT = 0x24;		debug(("movl (esp),eax\n"));		OUT = 0xB8|REG_eax;		LOUT = IEEE_MODE;		debug(("movl %d,eax\n", IEEE_MODE));		OUT = 0x89;		OUT = (REG_eax<<3)|0x44;		OUT = 0x24;		OUT = 0x04;		debug(("movl eax,4(esp)\n"));		OUT = 0xD9;		OUT = 0x6C;		OUT = 0x24;		OUT = 0x04;		debug(("fldcw 4(esp)\n"));	}#endif}define_insn(epilogue, epilogue_xxx){	extern label *getLastEpilogueLabel(void);		label *el;	if( (el = getLastEpilogueLabel()) && (el->at == (CODEPC - 4)) )	{		/*		 * Nothing to jump over to get to the epilogue...  Replace		 * the jump code with regular epilogue.		 */		el->type = Lnull;		CODEPC -= 5;	}	else if( el && (el->at != (CODEPC - 4)) )	{		/* The function ends with a throw, not a return. */	}	setEpilogueLabel((uintp)CODEPC);	#if 0	/* If this method uses IEEE, restore it */	if (used_ieee_division == true) {#if 0		OUT = 0xD9;		OUT = 0x2C;		OUT = 0x24;		debug(("fldcw (esp)\n"));#endif		OUT = 0xD9;		OUT = 0x6C;		OUT = 0x24;		OUT = 0;		debug(("fldcw 0(esp)\n"));		OUT = 0x81;		OUT = 0xC0|REG_esp;		LOUT = 8;		debug(("addl 8,esp\n"));	}#endif#if defined(KAFFE_PROFILER)	if (profFlag) {		profiler_end(globalMethod->totalClicks, 1);	}#endif	OUT = 0x58|REG_ebx;	OUT = 0x58|REG_esi;	OUT = 0x58|REG_edi;	OUT = 0x89;	OUT = 0xC0|(REG_ebp<<3)|REG_esp;	OUT = 0x58|REG_ebp;	debug(("popl ebx\n"));	debug(("popl esi\n"));	debug(("popl edi\n"));	debug(("movl ebp,esp\n"));	debug(("popl ebp\n"));	OUT = 0xC3;	debug(("ret\n"));}/* --------------------------------------------------------------------- */define_insn(spill_int, spill_Rxx){	int r = sreg_int(0);	int o = const_int(1);	OUT = 0x89;	OUT = 0x80|(r<<3)|REG_ebp;	LOUT = o;	debug(("movl %s,%d(ebp)\n", regname(r), o));}define_insn(spill_float, fspill_Rxx){	int o;	(void)sreg_float(0);	o = const_int(1);	OUT = 0xD9;	OUT = 0x98|REG_ebp;	LOUT = o;	debug(("fstp %d(ebp)\n", o));}define_insn(spill_double, fspilll_Rxx){	int o;	(void)sreg_double(0);	o = const_int(1);	OUT = 0xDD;	OUT = 0x98|REG_ebp;	LOUT = o;	debug(("fstpl %d(ebp)\n", o));}define_insn(reload_int, reload_Rxx){	int o;	int r;	r = lreg_int(0);	o = const_int(1);	OUT = 0x8B;	OUT = 0x80|(r<<3)|REG_ebp;	LOUT = o;	debug(("movl %d(ebp),%s\n", o, regname(r)));}define_insn(reload_float, freload_Rxx){	int o;	lreg_float(0);	o = const_int(1);	OUT = 0xD9;	OUT = 0x80|REG_ebp;	LOUT = o;	debug(("fld %d(ebp)\n", o));}define_insn(reload_double, freloadl_Rxx){	int r, o;	r = lreg_double(0);	o = const_int(1);		OUT = 0xDD;	OUT = 0x80|REG_ebp;	LOUT = o;			debug(("fldl %d(ebp) %d\n", o, r));}voidmovereg_RR(int toreg, int fromreg){	do_move_int(toreg, fromreg);}/* --------------------------------------------------------------------- */define_insn(move_int_const, move_RxC){	int val = const_int(2);	int w = wreg_int(0);	if (val == 0) {		OUT = 0x31;		OUT = 0xC0|(w<<3)|w;		debug(("xorl %s,%s\n", regname(w), regname(w)));	}	else {		OUT = 0xB8|w;		LOUT = val;		debug(("movl #%d,%s\n", val, regname(w)));	}}define_insn(move_label_const, move_RxL){	label* l = const_label(2);	int w = wreg_int(0);	OUT = 0xB8|w;	l->type |= Llong|Labsolute;	l->at = CODEPC;	LOUT = 0;	debug(("movl #%s,%s\n", getLabelName(l), regname(w)));}define_insn(move_int, move_RxR){	int r = rreg_int(2);	int w = wreg_int(0);	if (r != w) {		OUT = 0x89;		OUT = 0xC0|(r<<3)|w;		debug(("movl %s,%s\n", regname(r), regname(w)));	}}define_insn(move_float_const, fmove_RxC){	jvalue d;	d.d = const_float(2);	wreg_float(0);	if (d.d == 0.0) {		OUT = 0xD9;		OUT = 0xEE;		debug(("fldz\n"));		if ((d.j >> 63) & 1) {			OUT = 0xD9;			OUT = 0xe0;			debug(("fchs\n"));                }	}	else if (d.d == 1.0) {		OUT = 0xD9;		OUT = 0xE8;		debug(("fld1\n"));	}	else {		ABORT();	}}define_insn(move_float, fmove_RxR){	int or = rslot_float(2);	int ow = wslot_float(0);	if (or != ow) {		wreg_float(0);		OUT = 0xD9;		OUT = 0x80|REG_ebp;		LOUT = or;		debug(("fld %d(ebp)\n", or));	}}define_insn(move_double_const, fmovel_RxC){	jvalue d;	d.d = const_double(2);	wreg_double(0);	if (d.d == 0.0) {		OUT = 0xD9;		OUT = 0xEE;		debug(("fldz\n"));		if ((d.j >> 63) & 1) {			OUT = 0xD9;			OUT = 0xe0;			debug(("fchs\n"));                }	}	else if (d.d == 1.0) {		OUT = 0xD9;		OUT = 0xE8;		debug(("fld1\n"));	}	else {		ABORT();	}}define_insn(move_double, fmovel_RxR){	int or = rslot_double(2);	int ow = wslot_double(0);	if (or != ow) {		wreg_double(0);		OUT = 0xDD;		OUT = 0x80|REG_ebp;		LOUT = or;		debug(("fldl %d(ebp)\n", or));	}}/* --------------------------------------------------------------------- */define_insn(add_int, add_RRR){	int r;	int w;	check_reg_01();	r = rreg_int(2);	w = rwreg_int(0);	OUT = 0x01;        OUT = 0xC0|(r<<3)|w;	debug(("addl %s,%s\n", regname(r), regname(w)));}define_insn(adc_int, adc_RRR){	int r;	int w;	r = rreg_int(2);	w = rwreg_int(0);	OUT = 0x11;        OUT = 0xC0|(r<<3)|w;	debug(("adcl %s,%s\n", regname(r), regname(w)));}define_insn(add_float, fadd_RRR){	int rr, rm;	/*	 * XXX Order is important here...  If we put slot 2 into memory and	 * slot 1 into the register we get a whole bunch of excess	 * spills/reloaeds.	 */	rm = rslot_float(1);	/* Get slot 1 into memory */	rr = rreg_float(2);	/* Load slot 2 into the register stack */	wreg_float(0);		/* Result will be in register stack */	OUT = 0xD8;	OUT = 0x80|REG_ebp;	LOUT = rm;	debug(("fadd %d(ebp)\n", rm));}define_insn(add_double, faddl_RRR){	int rr, rm;	rm = rslot_double(1);	/* Get slot 1 into memory */	rr = rreg_double(2);	/* Load slot 2 into the register stack */	wreg_double(0);		/* Result will be in register stack */	OUT = 0xDC;	OUT = 0x80|REG_ebp;	LOUT = rm;	debug(("faddl %d(ebp)\n", rm));}define_insn(sub_int, sub_RRR){	int r;	int w;	check_reg_01();	r = rreg_int(2);	w = rwreg_int(0);	OUT = 0x29;        OUT = 0xC0|(r<<3)|w;	debug(("subl %s,%s\n", regname(r), regname(w)));}define_insn(sbc_int, sbc_RRR){	int r;	int w;	r = rreg_int(2);	w = rwreg_int(0);	OUT = 0x19;        OUT = 0xC0|(r<<3)|w;	debug(("sbbl %s,%s\n", regname(r), regname(w)));}define_insn(sub_float, fsub_RRR){	int rr, rm;	rm = rslot_float(1);	/* Get slot 1 into memory */	rr = rreg_float(2);	/* Load slot 2 into the register stack */	wreg_float(0);		/* Result will be in register stack */	OUT = 0xD8;	OUT = 0xA8|REG_ebp;	LOUT = rm;	debug(("fsub %d(ebp)\n", rm));}define_insn(sub_double, fsubl_RRR){	int rr, rm;	rm = rslot_double(1);	/* Get slot 1 into memory */	rr = rreg_double(2);	/* Load slot 2 into the register stack */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -