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

📄 jit-i386.def

📁 基于LWVCL开发的库
💻 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(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}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"));}define_insn(epilogue, epilogue_xxx){	KaffeJIT_setEpilogueLabel((uintp)CODEPC);#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);	(void)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);	(void)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 r = lreg_double(0);	int o = const_int(1);	OUT(0xDD);	OUT(0x80|REG_ebp);	LOUT(o);	debug(("fldl %d(ebp) %d\n", o, r));}/* --------------------------------------------------------------------- */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\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){	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 {		KAFFEVM_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 {		KAFFEVM_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(("fchs\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 = KaffeJIT_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);	OUT(0x99);	debug(("cltd\n"));	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);	assert(r != REG_eax);	assert(r != REG_edx);	/* special case for LONG_MIN % -1l: r == -1 ? 0 : eax / r  */	OUT(0x83);	OUT(0xF8|r);	OUT(0xFF);	debug(("cmp #0xFF,%s\n", regname(r)));	l1 = KaffeJIT_newLabel();	l1->type = Linternal| Llong8|Lrelative;	OUT(0x74);	l1->at = CODEPC;	OUT(0);	l1->from = CODEPC;	debug(("je const0\n"));	/* Setup EDX - should contains the sign of EAX */	do_move_int(REG_edx, REG_eax);	OUT(0x99);	debug(("cltd\n"));	OUT(0xF7);        OUT(0xF8|r);	debug(("idivl %s,%s\n", regname(r), regname(w)));	OUT(0xEB);	OUT(2);	debug(("jmp +2\n"));	debug(("const0:\n"));	l1->to = CODEPC;	OUT(0x31);        OUT(0xC0|(REG_edx<<3)|REG_edx);	debug(("xorl edx,edx\n"));	/* Result is in EDX not EAX - we must force the slot register */	forceRegister(seq_dst(s), REG_edx, Rint);}/* --------------------------------------------------------------------- */define_insn(and_int, and_RRR){	int r;	int w;	check_reg_01();

⌨️ 快捷键说明

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