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

📄 jit3-powerpc.def

📁 基于LWVCL开发的库
💻 DEF
📖 第 1 页 / 共 3 页
字号:
/* This is -*- C -*- *//* * jit3-powerpc.def * * Copyright (c) 2002, 2004 The University of Utah and the Flux Group. * All rights reserved. * * @JANOSVM_KAFFE_JANOSVM_LICENSE@ */#include "jit.h"#include "jit-labels.h"#include "icode.h"#include "ppc_isa.h"#include "code-analyse.h"#include "constpool.h"#include "ppc_macros.h"/* * I just stole the arm jit3 files edited them, so some of that cruft is left * over. *//* * debugging stuff. * XXX clean me. */#if 1#undef ppc_op_ctxt#define ppc_op_ctxt CODEPC#undef ppc_op_debug#define ppc_op_debug(args) (jit_debug ? (my_op_debug args) : 0)int my_op_debug(int ctxt, const char *fmt, ...){    va_list args;        va_start(args, fmt);    fprintf(stderr, "%d\t", ctxt);    vfprintf(stderr, fmt, args);    fprintf(stderr, "\n");    va_end(args);    return( 0 );}#define DBOUT stderr#define debug(x) (jit_debug ? (fprintf x) : 0 )#else#define debug(x)#endifint jit_debug;/* --------------------------------------------------------------------- */define_insn(unimplemented, unimplemented){	abort();}define_insn(nop, nop){	LOUT (ppc_op_nop());}/* --------------------------------------------------------------------- *//* XXX */int r31FunctionStartOffset;define_insn(prologue, prologue_xxx){	int has_pool = 0;	Method* meth;	label *pl;	pl = const_label(1);	meth = const_method(2);	/*	 * Either, this method is not a leaf or we have a constpool and need	 * to overwrite LR to get at it.	 */	if( (KaffeJIT3_getFirstConst() != KaffeJIT3_getCurrConst()) ||	    maxLocal ||	    maxTemp )	{		has_pool = 1;	}	if( has_pool )	{		int localRegs;		/*		 * We'll be overwriting the LR in a bit, move it out so we can		 * save it later.		 */		LOUT(ppc_op_mflr(PPC_R0));		localRegs = maxLocal + maxTemp + 1;		/*		 * We atleast need to save R31 because it's used to hold the		 * function base and thus the base for the constpool.		 */		if( localRegs == 1 )		{			LOUT(ppc_op_stw(PPC_R31, PPC_RSP, -SLOTSIZE-72));		}		else		{			label *l;			l = KaffeJIT3_newLabel();			l->type = Lsavedregs | Labsolute | Lgeneral;			l->at = CODEPC;			l->to = 0;			l = KaffeJIT3_newLabel();			l->type = Lreg_s | Labsolute | Lgeneral;			l->at = CODEPC;			LOUT(ppc_op_stmw(0, PPC_RSP, 0));		}		/* Stuff the LR in the caller's linkage area. */		LOUT(ppc_op_stw(PPC_R0, PPC_RSP, PPC_FRAME_LR));				pl->type = Lnegframe | Labsolute | Lgeneral;		pl->at = CODEPC;		/*		 * Only update the stack pointer if we're not a		 * leaf.		 */		LOUT(ppc_op_stwu(PPC_RSP, PPC_RSP, 0)); // XXX				/* Branch to the next instruction (no cost... i think) */		LOUT(ppc_op_bc(PPC_BO_ALWAYS,			       0,			       ppc_bd16(sizeof(ppc_code_t))) |		     PPC_OPTION_LK);		/*		 * The link register points to the internals of this method		 * save it and the offset from the start of the function.		 */		r31FunctionStartOffset = CODEPC;		LOUT(ppc_op_mflr(PPC_RFUNCTION_BASE));	}	else	{		r31FunctionStartOffset = -1;	}	/* If we have arguments we need to tell the register allocator. */	if( maxArgs )	{		int dbl_skip = 0, limit = PPC_ARG_REGISTER_COUNT;		int lpc, gpr_off = 0, fpr_off;			{		void printSlots(FILE *file);		// printSlots(stderr);	}		if( !isStatic )		{			/* Prepend "this" argument. */			gpr_off += 1;			dbl_skip += 1;			limit -= 1;			preloadRegister(localinfo[0].slot, Rref, PPC_RARG0);		}		/* Figure out the number of arguments in registers. */		if( METHOD_NARGS(meth) < limit )			limit = METHOD_NARGS(meth);#if defined(__APPLE__)		/*		 * Force argument slots to correspond to the appropriate		 * registers.  On darwin, this means we skip gpr's when floats		 * and doubles are also passed in.		 */		for( lpc = 0, fpr_off = 0;		     lpc < limit;		     gpr_off++, lpc++ )		{			switch( *METHOD_ARG_TYPE(meth, lpc) )			{			case 'D':				/* Double's correspond to two gpr's. */				gpr_off++;				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rdouble,						PPC_FPRARG0 + fpr_off);				dbl_skip++;				fpr_off++;				break;			case 'F':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rfloat,						PPC_FPRARG0 + fpr_off);				fpr_off++;				break;			case 'L':			case '[':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rref,						PPC_RARG0 + gpr_off);				break;			case 'J':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rint,						PPC_RARG0 + gpr_off);				gpr_off++;				dbl_skip++;				/* FALLTHROUGH */			default:				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rint,						PPC_RARG0 + gpr_off);				break;			}		}#else		for( lpc = 0, fpr_off = 0; lpc < limit; lpc++ )		{			switch( *METHOD_ARG_TYPE(meth, lpc) )			{			case 'D':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rdouble,						PPC_FPRARG0 + fpr_off);				dbl_skip++;				fpr_off++;				break;			case 'F':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rfloat,						PPC_FPRARG0 + fpr_off);				fpr_off++;				break;			case 'L':			case '[':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rref,						PPC_RARG0 + gpr_off);				gpr_off++;				break;			case 'J':				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rint,						PPC_RARG0 + gpr_off);				gpr_off++;				dbl_skip++;				/* FALLTHROUGH */			default:				preloadRegister(localinfo[lpc + dbl_skip].slot,						Rint,						PPC_RARG0 + gpr_off);				gpr_off++;				break;			}		}#endif	{		void printSlots(FILE *file);		// printSlots(stderr);	}	}}define_insn(exception_prologue, eprologue_xxx){	if( r31FunctionStartOffset > 0 )	{#if 1#elif 1		label *l = KaffeJIT3_newLabel();		l->type = Lframe | Labsolute | Lgeneral;		l->at = CODEPC;		LOUT(ppc_op_lmw(14, PPC_RSP, 0));#else		label *l = const_label(1);		l->type = Linternal | Labsolute | Llong16x16;		l->from = 0;		l->at = CODEPC;		l->to = r31FunctionStartOffset;		LOUT(ppc_op_li(PPC_RCONST_POOL, 0));		LOUT(ppc_op_addis(PPC_RCONST_POOL, PPC_RCONST_POOL, 0));#endif		// debug((DBOUT,"exception_prologue %s\n",KaffeJIT3_getLabelName(l)));	}}define_insn(epilogue, epilogue_xxx){	label *el;	if( (el = KaffeJIT3_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 -= 4;	}	else if( el && (el->at != (CODEPC - 4)) )	{		/* The function ends with a throw, not a return. */	}	KaffeJIT3_setEpilogueLabel(CODEPC);		if( (KaffeJIT3_getFirstConst() != KaffeJIT3_getCurrConst()) ||	    maxLocal ||	    maxTemp )	{		int lrOffset = 0, localRegs;		label *fl;		fl = KaffeJIT3_newLabel();		fl->type = Lframe | Lrelative | Lgeneral;		fl->at = CODEPC;		fl->from = PPC_FRAME_LR;		fl->to = 0;		/*		 * Load the original LR back into R0.		 *		 * Note: We do the load early so it can run in parallel while		 * we readjust the stack pointer.		 */		LOUT(ppc_op_lwz(PPC_R0, PPC_RSP, lrOffset));		fl = KaffeJIT3_newLabel();		fl->type = Lframe | Labsolute | Lgeneral;		fl->at = (uintp)CODEPC;		LOUT(ppc_op_addi(PPC_RSP, PPC_RSP, 0));		LOUT(ppc_op_mtlr(PPC_R0));		/* Restore and local registers. */		localRegs = maxLocal + maxTemp + 1;		if( localRegs == 1 )		{			LOUT(ppc_op_lwz(PPC_R31, PPC_RSP, -4-72));		}		else		{			label *l;			l = KaffeJIT3_newLabel();			l->type = Lsavedregs | Labsolute | Lgeneral;			l->at = CODEPC;			l->to = 0;			l = KaffeJIT3_newLabel();			l->type = Lreg_s | Labsolute | Lgeneral;			l->at = CODEPC;			LOUT(ppc_op_lmw(0, PPC_RSP, 0));		}	}	/* Branch back to the caller. */	LOUT(ppc_op_blr());}#if defined(STACK_LIMIT)define_insn(check_stack_limit, check_stack_limit_xRC){        int r = rreg_int(1);        label* l = const_label(2);#if 1#else	op_cmp(SP, r);	op_branch(CC_HI, 8);	l->type = Lconstant | Labsolute | Loffset12;        l->at = CODEPC;	op_load_offset(r, CONSTPOOL_BASE, -128);	debug((DBOUT,"load_label_const r%d, ?\n", r));	op_mov(LR, PC);	op_mov(PC, r);#endif	debug((DBOUT,"load_label_const r%d, ?\n", r));}#endif/* --------------------------------------------------------------------- */define_insn(spill_int, spill_Rxx){	int r = sreg_int(0);	int o = const_int(1);	label *l;		l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	LOUT(ppc_op_stw(r, PPC_RSP, 0));		{		void printSlots(FILE *file);				// printSlots(stderr);	}	debug((DBOUT,"spill_int %d, [FP, %d(%p)]\n", r, o,	       seq_slot(s, 1)));}define_insn(spill_float, fspill_Rxx){	int r = sreg_float(0);	int o = const_int(1);	label *l;	l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	LOUT(ppc_op_stfs(r, PPC_RSP, 0));	debug((DBOUT,"spill_float %d, [FP, %d]\n", r, o));}define_insn(spill_double, fspilll_Rxx){	int r = sreg_double(0);	int o = const_int(1);	label *l;	l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	/* XXX Alignment needed here?  e.g. o >> 2 */	LOUT(ppc_op_stfd(r, PPC_RSP, 0));	debug((DBOUT,"spill_double %d, [FP, %d]\n", r, o));}define_insn(reload_int, reload_Rxx){	int r = lreg_int(0);	int o = const_int(1);	label *l;			l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	LOUT(ppc_op_lwz(r, PPC_RSP, 0));		debug((DBOUT,"reload_int %d, [FP, %d(%p)]\n", r, o,	       seq_slot(s, 1)));}define_insn(reload_float, freload_Rxx){	int r = lreg_float(0);	int o = const_int(1);	label *l;	l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	LOUT(ppc_op_lfs(r, PPC_RSP, 0));	debug((DBOUT,"reload_float %d, [FP, %d]\n", r, o));}define_insn(reload_double, freloadl_Rxx){	int r = lreg_double(0);	int o = const_int(1);	label *l;	l = KaffeJIT3_newLabel();	l->type = Llong16noalign | Lexternal | Labsolute;	l->at = CODEPC;	l->to = o;	LOUT(ppc_op_lfd(r, PPC_RSP, 0));		debug((DBOUT,"reload_double %d, [FP, %d]\n", r, o));}voidmovereg_RR(int toreg, int fromreg){	if( toreg != fromreg )		LOUT(ppc_op_mr(toreg, fromreg));}voidfmovereg_RR(int toreg, int fromreg){	if( toreg != fromreg )		LOUT(ppc_op_fmr(toreg, fromreg));}/* --------------------------------------------------------------------- */define_insn(move_int_const, move_RxC){	int val = const_int(2);	int w = wreg_int(0);	/* cwg 3.2.3.1 */	switch( val & 0xffff8000 )	{	case 0xffff8000:	/* Its a negative 16 bit number. */	case 0x00000000:	/* Its a positive 16 bit number. */		LOUT(ppc_op_li(w, val));		break;	default:		/* Its a full 32 bit number. */		/*		 * In reality, this won't get used at the moment, but its nice		 * to have as a reference.		 */		LOUT(ppc_op_li(w, ppc_lo16(val)));		LOUT(ppc_op_addis(w, w,				    (val & 0x00008000) ?				    ppc_ha16(val) :				    ppc_hi16(val)));		break;	}}//// This doesn't get used as much as it used to// since most constants are stored in the// constant pool and referenced via load_constpool_<type>//// However, this is still needed to assemble a 32-bit// constant inline.//define_insn(move_label_const, move_RxL){	label* l = const_label(2);	int w = wreg_int(0);	l->type |= Llong16x16|Labsolute;	l->at = CODEPC;	LOUT(ppc_op_li(w, 0));	LOUT(ppc_op_addis(w, w, 0));		debug((DBOUT,"move_label_const %d, ?\n", w));}define_insn(load_constpool_int, ld_RxL){	label* l = const_label(2);	int w = wreg_int(0);		l->type = Lconstant | Lrelative | Llong16noalign;	l->from = r31FunctionStartOffset;	l->at = CODEPC;	LOUT(ppc_op_lwz(w, PPC_RCONST_POOL, 0));		debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(load_constpool_float, fld_RxL){	label* l = const_label(2);	int w = wreg_float(0);		l->type = Lconstant | Lrelative | Llong16noalign;	l->from = r31FunctionStartOffset;	l->at = CODEPC;	LOUT(ppc_op_lfs(w, PPC_RCONST_POOL, 0));		debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(load_constpool_double, fldl_RxL){	label* l = const_label(2);	int w = wreg_double(0);		l->type = Lconstant | Lrelative | Llong16noalign;	l->from = r31FunctionStartOffset;	l->at = CODEPC;	LOUT(ppc_op_lfd(w, PPC_RCONST_POOL, 0));		debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(move_int, move_RxR){	int r = rreg_int(2);	int w = wreg_int(0);	LOUT(ppc_op_mr(w, r));	debug((DBOUT,"move_int %d, %d\n", w, r));}define_insn(move_float, fmove_RxR){	int r = rreg_float(2);	int w = wreg_float(0);	LOUT(ppc_op_fmr(w, r));	debug((DBOUT,"move_float %d, %d\n", w, r));}define_insn(move_double, fmovel_RxR){	int r = rreg_double(2);	int w = wreg_double(0);		LOUT(ppc_op_fmr(w, r));	debug((DBOUT,"move_double %d, %d\n", w, r));}/* --------------------------------------------------------------------- */define_insn(neg_int, neg_RxR){	int r = rreg_int(2);	int w = wreg_int(0);	LOUT(ppc_op_neg(w, r));	debug((DBOUT,"neg_int %d, %d\n", w, r));}define_insn(neg_float, fneg_RxR){	int r = rreg_float(2);	int w = wreg_float(0);	LOUT(ppc_op_fneg(w, r));	debug((DBOUT,"neg_float %d, %d\n", w, r));}define_insn(neg_double, fnegl_RxR){	int r = rreg_double(2);	int w = wreg_double(0);	LOUT(ppc_op_fneg(w, r));	debug((DBOUT,"neg_double %d, %d\n", w, r));}define_insn(add_int, add_RRR){	int r2 = rreg_int(2);	int r1 = rreg_int(1);	int w = wreg_int(0);	LOUT(ppc_op_add(w, r1, r2));	debug((DBOUT,"add_int %d, %d, %d\n", w, r1, r2));}define_insn(add_int_const, add_RRC){	int o = const_int(2);	int r1 = rreg_int(1);	int w = wreg_int(0);	if ( o < 0 ) {		debug((DBOUT,"sub_int_const %d, %d, %d\n", w, r1, -o));	} else {		debug((DBOUT,"add_int_const %d, %d, %d\n", w, r1, o));	}	LOUT(ppc_op_addi(w, r1, o));}define_insn(adc_int, adc_RRR){	int r2 = rreg_int(2);	int r1 = rreg_int(1);	int w = wreg_int(0);	LOUT(ppc_op_addc(w, r1, r2));	debug((DBOUT,"adc_int %d, %d, %d\n", w, r1, r2));}

⌨️ 快捷键说明

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