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

📄 jit-i386.def

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 DEF
📖 第 1 页 / 共 2 页
字号:
/* jit-i386.def * i386 instruction definition. * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "debug.h"#include "classMethod.h"#include "gtypes.h"#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);				\		assert(_r_ == _w_);				\	}#define	do_force_move_int(t, f, n)				\	if ((t) != (f)) {					\		forceRegister(seq_slot(s, (n)), (t), Rint);	\		do_move_int((t), (f));				\		f = (t);					\	}char* rnames[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };#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;	debug(("nop\n"));}/* --------------------------------------------------------------------- */define_insn(prologue, prologue_xxx){	label* l;	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 this method uses IEEE, set up the mode here */	if (used_ieee_division == true && 0) {		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_ebx<<3)|0x04;		OUT = 0x24;		debug(("movl (esp),ebx\n"));		OUT = 0xB8|REG_ebx;		LOUT = IEEE_MODE;		debug(("movl %d,ebx\n", IEEE_MODE));		OUT = 0x89;		OUT = (REG_ebx<<3)|0x44;		OUT = 0x24;		OUT = 0x04;		debug(("movl ebx,4(esp)\n"));		OUT = 0xD9;		OUT = 0x6C;		OUT = 0x24;		OUT = 0x04;		debug(("fldcw 4(esp)\n"));	}}define_insn(exception_prologue, eprologue_xLx){	label* l;	OUT = 0x89;	OUT = 0xC0|(REG_ebp<<3)|REG_ebx;	OUT = 0x81;	OUT = 0xE8|REG_ebx;	/* 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_ebx;	LOUT = 3*SLOTSIZE;	OUT = 0x89;	OUT = 0xC0|(REG_ebx<<3)|REG_esp;	debug(("movl ebp,ebx\n"));	debug(("subl #?,ebx\n"));	debug(("subl #3*SLOTSIZE,ebx\n"));	debug(("movl ebx,esp\n"));	if (used_ieee_division == true && 0) {		OUT = 0x81;		OUT = 0xE8|REG_esp;		LOUT = SLOTSIZE;		debug(("subl #%d,esp\n", SLOTSIZE));		OUT = 0x8B;		OUT = (REG_ebx<<3)|0x04;		OUT = 0x24;		debug(("movl (esp),ebx\n"));		OUT = 0xB8|REG_ebx;		LOUT = IEEE_MODE;		debug(("movl %d,ebx\n", IEEE_MODE));		OUT = 0x89;		OUT = (REG_ebx<<3)|0x44;		OUT = 0x24;		OUT = 0x04;		debug(("movl ebx,4(esp)\n"));		OUT = 0xD9;		OUT = 0x6C;		OUT = 0x24;		OUT = 0x04;		debug(("fldcw 4(esp)\n"));	}}define_insn(epilogue, epilogue_xxx){	setEpilogueLabel((uintp)CODEPC);		/* If this method uses IEEE, restore it */	if (used_ieee_division == true && 0) {#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"));	}#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 = const_int(1);	sreg_float(0);	OUT = 0xD9;	OUT = 0x98|REG_ebp;	LOUT = o;	debug(("fstp %d(ebp)\n", o));}define_insn(spill_double, fspilll_Rxx){	int o = const_int(1);	sreg_double(0);	OUT = 0xDD;	OUT = 0x98|REG_ebp;	LOUT = o;	debug(("fstpl %d(ebp)\n", o));}define_insn(reload_int, reload_Rxx){	int r = lreg_int(0);	int 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 = const_int(1);	lreg_float(0);	OUT = 0xD9;	OUT = 0x80|REG_ebp;	LOUT = o;	debug(("fld %d(ebp)\n", o));}define_insn(reload_double, freloadl_Rxx){	int o = const_int(1);	lreg_double(0);	OUT = 0xDD;	OUT = 0x80|REG_ebp;	LOUT = o;	debug(("fldl %d(ebp)\n", o));}/* --------------------------------------------------------------------- */define_insn(move_int_const, move_RxC){	int val = const_int(2);	int w = wreg_int(0);	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\n", 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){	double val = const_float(2);	wreg_float(0);	if (val == 0.0) {		OUT = 0xD9;		OUT = 0xEE;		debug(("fldz\n"));		{			jvalue d;			d.d = val;			if ((d.j >> 63) & 1) {				OUT = 0xD9;				OUT = 0xe0;				debug(("fchs\n"));			}		}	}	else if (val == 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){	double val = const_double(2);	wreg_double(0);	if (val == 0.0) {		OUT = 0xD9;		OUT = 0xEE;		debug(("fldz\n"));		{			jvalue d;			d.d = val;			if ((d.j >> 63) & 1) {				OUT = 0xD9;				OUT = 0xe0;				debug(("fchsl\n"));			}		}	}	else if (val == 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 r2 = rslot_float(2);	/* Get r2 into memory */	rreg_float(1);			/* Load r1 into the register stack */	wreg_float(0);			/* Result will be in register stack */	OUT = 0xD8;	OUT = 0x80|REG_ebp;	LOUT = r2;	debug(("fadd %d(ebp)\n", r2));}define_insn(add_double, faddl_RRR){	int r2 = rslot_double(2);	/* Get r2 into memory */	rreg_double(1);			/* Load r1 into the register stack */	wreg_double(0);			/* Result will be in register stack */	OUT = 0xDC;	OUT = 0x80|REG_ebp;	LOUT = r2;	debug(("faddl %d(ebp)\n", r2));}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 r2 = rslot_float(2);	/* Get r2 into memory */	rreg_float(1);			/* Load r1 into the register stack */	wreg_float(0);			/* Result will be in register stack */	OUT = 0xD8;	OUT = 0xA0|REG_ebp;	LOUT = r2;	debug(("fsub %d(ebp)\n", r2));}define_insn(sub_double, fsubl_RRR){	int r2 = rslot_double(2);	/* Get r2 into memory */	rreg_double(1);			/* Load r1 into the register stack */	wreg_double(0);			/* Result will be in register stack */	OUT = 0xDC;	OUT = 0xA0|REG_ebp;	LOUT = r2;	debug(("fsubl %d(ebp)\n", r2));}define_insn(neg_float, negf_RxR){    rreg_float(2);    wreg_float(0);    OUT = 0xD9;    OUT = 0xe0;    debug(("fchs\n"));}define_insn(neg_double, negd_RxR){    rreg_double(2);    wreg_double(0);    OUT = 0xD9;    OUT = 0xe0;    debug(("fchsl\n"));}define_insn(mul_int, mul_RRR){	int r;	int w;	check_reg_01();	r = rreg_int(2);	w = rwreg_int(0);	OUT = 0x0F;	OUT = 0xAF;        OUT = 0xC0|(w<<3)|r;	debug(("imull %s,%s\n", regname(r), regname(w)));}define_insn(mul_float, fmul_RRR){	int r2 = rslot_float(2);	/* Get r2 into memory */	rreg_float(1);			/* Load r1 into the register stack */	wreg_float(0);			/* Result will be in register stack */	OUT = 0xD8;	OUT = 0x88|REG_ebp;	LOUT = r2;	debug(("fmul %d(ebp)\n", r2));}define_insn(mul_double, fmull_RRR){	int r2 = rslot_double(2);	/* Get r2 into memory */	rreg_double(1);			/* Load r1 into the register stack */	wreg_double(0);			/* Result will be in register stack */	OUT = 0xDC;	OUT = 0x88|REG_ebp;	LOUT = r2;	debug(("fmull %d(ebp)\n", r2));}define_insn(div_int, div_RRR){	int r;	int w;	label *l1;	check_reg_01();	w = rwreg_int(0);	/* Can only divide accumulator. */	do_force_move_int(REG_eax, w, 0);	/* EDX is also used so get hold of it */	clobberRegister(REG_edx);	r = rreg_int(2);	assert(r != REG_eax);	assert(r != REG_edx);	/* special case for LONG_MIN / -1l: r == -1 ? -eax : eax / r  */	OUT = 0x83;	OUT = 0xF8|r;	OUT = 0xFF;	debug(("cmp #0xFF,%s\n", regname(r)));	l1 = newLabel();	l1->type = Linternal| Llong8|Lrelative;	OUT = 0x74;	l1->at = CODEPC;	OUT = 0;	l1->from = CODEPC;	debug(("je neg\n"));	/* Setup EDX - should contains the sign of EAX */	do_move_int(REG_edx, REG_eax);#if 0	OUT = 0xC1;	OUT = 0xF8|REG_edx;	OUT = 31;	debug(("sarl #31,edx\n"));#else	OUT = 0x99;	debug(("cltd\n"));#endif	OUT = 0xF7;        OUT = 0xF8|r;	debug(("idivl %s,%s\n", regname(r), regname(w)));	OUT = 0xEB;	OUT = 2;	debug(("jmp +2\n"));	debug(("neg:\n"));	l1->to = CODEPC;	OUT = 0xF7;	OUT = 0xD8|REG_eax;	debug(("neg eax\n"));}define_insn(div_float, fdiv_RRR){	int r2 = rslot_float(2);	/* Get r2 into memory */	rreg_float(1);			/* Load r1 into the register stack */	wreg_float(0);			/* Result will be in register stack */	OUT = 0xD8;	OUT = 0xB0|REG_ebp;	LOUT = r2;	debug(("fdiv %d(ebp)\n", r2));}define_insn(div_double, fdivl_RRR){	int r2 = rslot_double(2);	/* Get r2 into memory */	rreg_double(1);			/* Load r1 into the register stack */	wreg_double(0);			/* Result will be in register stack */	OUT = 0xDC;	OUT = 0xB0|REG_ebp;	LOUT = r2;	debug(("fdivl %d(ebp)\n", r2));}define_insn(rem_int, rem_RRR){	int r;	int w;	label *l1;	check_reg_01();	w = rwreg_int(0);	/* Can only divide accumulator. */	do_force_move_int(REG_eax, w, 0);	/* EDX is also used so get hold of it */	clobberRegister(REG_edx);	r = rreg_int(2);

⌨️ 快捷键说明

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