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

📄 jit-alpha.def

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 DEF
📖 第 1 页 / 共 5 页
字号:
	insn_mem(0x0C, (ra), (rb), (off))#define op_sextb(rb, rc)						\	debug(("sextb\t%s,%s\n",regname(rb),regname(rc))),		\	insn_opr(0x1C, 0x00, REG_zero, (rb), (rc))#define op_sextw(rb, rc)						\	debug(("sextw\t%s,%s\n",regname(rb),regname(rc))),		\	insn_opr(0x1C, 0x01, REG_zero, (rb), (rc))#define op_stb(ra, rb, off)						\	debug(("stb\t%s,%hd(%s)\n",regname(ra),(off),regname(rb))),	\	insn_mem(0x0E, (ra), (rb), (off))#define op_stw(ra, rb, off)						\	debug(("stw\t%s,%hd(%s)\n",regname(ra),(off),regname(rb))),	\	insn_mem(0x0D, (ra), (rb), (off))static inline longalpha_have_bwx(void){#ifdef HAVE_ALPHA_ASM_AMASK	long r;	__asm__("amask 1,%0" : "=r"(r));#else	/* For those whose assemblers are so far behind not to	   have the amask instruction.  */	register long r __asm__("$0");	__asm__(".long %1"		: "=r"(r)		: "i"((0x11 << 26) | (REG_zero << 21) | (1 << 13)		      | 0x1000 | (0x61 << 5) | REG_v0));#endif	return !r;}static inline longalpha_have_precise_trap(void){#ifdef HAVE_ALPHA_ASM_AMASK	long r;	__asm__("amask %1,%0" : "=r"(r) : "r"(1<<9));#else	/* For those whose assemblers are so far behind not to	   have the amask instruction.  */	register long r __asm__("$0") = (1 << 9);	__asm__(".long %1"		: "=r"(r)		: "i"((0x11 << 26) | (REG_zero << 21) | (REG_v0 << 16)		      | (0x61 << 5) | REG_v0));#endif	return !r;}/* --------------------------------------------------------------------- *//* Recognize constants that go to either and or zapnot.  */static inline longalpha_zapnot_const(long x){	/* Create a mask of bits in which bit n == 1 iff byte n == 0xFF.  */	__asm__("cmpbge %1,%2,%0" : "=r"(x) : "r"(x), "r"(-1));	return x;}intalpha_andconst_rangecheck(long v){	if (v >= 0 && v <= 0xFF) {		/* we can just use "and" */		return 1;	}	else if (~v >= 0 && ~v <= 0xFF) {		/* we can use "andnot" */		return 1;	}	else if ((alpha_zapnot_const(v) ^ alpha_zapnot_const(~v)) == 0xFF) {		/* we can use "zapnot" */		return 1;	}	return 0;}/* --------------------------------------------------------------------- */define_insn(unimplemented, unimplemented){	ABORT();}define_insn(nop, nop){	/* Presumably we're nop'ing for alignment not delay.  */	op_unop();}static voidalpha_ldgp(int reg){	long hi, lo;	hi = -CODEPC;	lo = (short)hi;	hi = (hi - lo) >> 16;	if (hi) {		op_ldah(REG_gp, reg, hi);		op_lda(REG_gp, REG_gp, lo);	}	else {		op_lda(REG_gp, reg, lo);	}}/* --------------------------------------------------------------------- */define_insn(prologue, prologue_xxC){	int r, N;	int l;	int sl;	int aspill;	label* L;	Method* meth;	int rsa_size;	L = const_label(1);	meth = const_method(2);#ifdef KAFFE_VMDEBUG	if (jit_debug) {		dprintf("\n%s.%s %s\n", meth->class->name->data,			meth->name->data, METHOD_SIGD(meth));	}#endif	alpha_jit_info.ieee = 0;		/* Initial stack frame looks like:	 *	 *      |  Argument above 6             |	 * SP-> |-------------------------------|	 *	 * Calling Standard for Alpha Systems	 * 3.1.2.1 Stack Frame Format	 *	 *  Figure 3-1: Fixed Size Stack Frame Format	 *              (PDSC_FLAGS_BASE_REG_IS_FP is 0)	 *  octaword-aligned	 *      |  Argument above 6             |	 *      |-------------------------------| <- PDSC_RPD_FRAME_SIZE from SP	 *      |  Argument home area           |	 *      |- - - - - - - - - - - - - - - -|	 *      |  Fixed temporary locations    |	 *      |-------------------------------|	 *      |  Register save area           |	 *      |-------------------------------| <- PDSC_RPD_RSA_OFFSET from SP	 *      |  Fixed temporary locations    |	 *      |-------------------------------| <- SP	 *	 *  Figure 3-2: Variable Size Stack Frame Format	 *              (PDSC_FLAGS_BASE_REG_IS_FP is 1)	 *  octaword-aligned	 *      |  Argument above 6             |	 *      |-------------------------------| <- PDSC_RPD_FRAME_SIZE from FP	 *      |  Argument home area           |	 *      |- - - - - - - - - - - - - - - -|	 *      |  Fixed temporary locations    |	 *      |-------------------------------|	 *      |  Register save area           |	 *      |-------------------------------| <- PDSC_RPD_RSA_OFFSET from FP	 *      |  Fixed temporary locations    |	 *      |-------------------------------| <- FP	 *      |  Stack temporary area         |	 *      |-------------------------------| <- SP	 *	 * * Fixed temporary locations are optional sections.  These locations	 *   might include, for exemple, register spill areas, ..., or fixed	 *   temporary locations.	 *	 * * The argument home area is an optionl section, it is a region of	 *   memory used by the called procedure for the purpose of assembling	 *   in contignous memory the arguments passed in registers adjacent to	 *   the arguments passed in memory, so that all argument can be	 *   addressed as a contignous array.	 *	 * * The register save area is the set of consecutive quadwords where	 *   the current procedure saves and restores registers.  The registers	 *   save area begins at the location pointed to by the frame base	 *   register (as indicated by PDSC_FLAGS_BASE_REG_IS_FP) added to the	 *   value of the content of PDSC_RPD_RSA_OFFSET.  The result must be	 *   a quadword-aligned address.	 *	 *   All registers saved in the variable portion of the register save	 *   area must have the corresponding bit set to 1 in the appropriate	 *   procedure descriptor register save mask.  The algorithm for	 *   packing saved register in the quadword-aligned register save area	 *   is as follows:	 *     . The return address is save at the lowest address of the	 *       register save area, offset 0.	 *     . All saved integer registers, as indicated by the corresponding	 *       bit in PDSC_RPD_IMASK being set to 1, are store, in register	 *       order, in consecutive quadwords beginning at offset 8 of the	 *       register save area.	 *     . All saved floating-point registers, as indicated by the	 *       corresponding bit in PDSC_RPD_FMASK being set to 1, are stored,	 *       in register-number order, in consecutive quadwords following	 *       the saved integer registers.	 *	 *   A standard-conforming procedure that utilizes a register save area	 *   must save the return address register at offset 0 in the register	 *   save area.  There is no corresponding bit in the register save	 *   mask for this register slot.	 *	 *	 * Applied for JIT Stack Frame:	 * We use a fixed-stack frame (PDSC_FLAGS_BASE_REG_IS_FP is 0) with	 * FP used as a virtual frame pointer to improve FRAMEOBJECT() macro.	 *	 *      |  Argument above 6             |	 * FP ->|-------------------------------| <- PDSC_RPD_FRAME_SIZE from SP	 *      |  Spill for up to 6 args       |	 *      |-------------------------------|	 *      |  Locals, temps                |	 *      |-------------------------------|	 *      |  Register save area           |	 *      |-------------------------------| <- PDSC_RPD_RSA_OFFSET from SP	 *      |  outgoing parameters past 6   |	 *      |-------------------------------| <- SP	 *	 *	 * Until we have some method of determining in the prologue which	 * Rnosaveoncall registers are used by a method, we will save registers	 * s0 to s5 and f2 to f9.  As we change FP, we must save it also.	 *	 * imask = (1 << 9) + ... + (1 << 14) + (1 << 15)	 * fmask = (1 << 2) + ... + (1 << 9)	 *	 * with the return address register, we save 16 registers in RSA.	 * ra, s0 ... s5, fp, f2 ... f9	 *	 */	/* Calling Standard for Alpha Systems	 * 3.2.6.1    Entry Code Sequence	 * Because the value of the PC defines the currently executing	 * procedure, all properties of the environment specified by a	 * procedure's descriptor must be valid before the first instruction	 * after the procedure prologue (as defined by PDSC_RPD_ENTRY_LENGTH)	 * is executed.  In addition, none of the properties specified in the	 * calling procedure's descriptor may be invalidated before the called	 * procedure becomes current. Thus, until the procedure becomes current,	 * all entry code must adhere to the following rules: 	 * . All registers specified by this standard as saved across a	 *   standard-conforming call must contain their original (at entry)	 *   contents.	 * . The register designated by PDSC_RPD_ENTRY_RA ($26 in a standard	 *   call) must contain its original (at entry) contents. This	 *   requirement also applies to nonstandard procedures to allow for	 *   proper unwinding.	 * . No standard calls can be made.	 *	 * These actions involve the following steps, performed in the	 * specified order:	 *	 * 1. Compute and load the procedure's GP value using the	 *    passed-in-procedure (code address) value in $27.	 *	 * 2. If stack space is allocated (PDSC_RPD_FRAME_SIZE is not 0), set	 *    register SP to SP - PDSC_RPD_FRAME_SIZE.	 *    After any necessary calculations and stack limit checks, this	 *    step must be completed in exactly one instruction that modifies	 *    SP.  This instruction must be the one specified by	 *    PDSC_RPD_SP_SET.	 *	 * 3. For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0), do	 *    both of these steps.  (There is no requirement as to which step	 *    occurs first.) 	 *	 *    Store the registers specified by PDSC_RPD_IMASK and	 *    PDSC_RDP_FMASK in the register save area based on	 *    PDSC_RPD_RSA_OFFSET.	 *	 *    Store the return address in the register save area.	 *	 * 4. For a register frame procedure (PDSC_FLAGS_REGISTER_FRAME is 1),	 *    copy the return address to the register specified by	 *    PDSC_RPD_SAVE_RA if the value is not already there.	 *	 * 5. Execute trapb, if required. (See Section 5.1.12 for details.)	 *	 * 6. For a variable-size stack frame procedure	 *    (PDSC_FLAGS_BASE_REG_IS_FP is 1), copy the SP value to register	 *    FP.  This step must be completed in exactly one instruction that	 *    modifies the FP and that instruction must be the last instruction	 *    in the prologue.	 */	/* Calling Standard for Alpha Systems	 * 3.2.6.1    Entry Code Sequence	 * 1. Compute and load the procedure's GP value using the	 *    passed-in-procedure (code address) value in $27.  */	op_lda(REG_gp, REG_pv, 0);	// op_mov(REG_pv, REG_gp);	/* Calling Standard for Alpha Systems	 * 3.2.6.1    Entry Code Sequence	 * 2. If stack space is allocated (PDSC_RPD_FRAME_SIZE is not 0), set	 *    register SP to SP - PDSC_RPD_FRAME_SIZE.	 *    After any necessary calculations and stack limit checks, this	 *    step must be completed in exactly one instruction that modifies	 *    SP.  This instruction must be the one specified by	 *    PDSC_RPD_SP_SET.  */	alpha_jit_info.sp_set = CODEPC / 4;	L->type = Lnegframe|Labsolute|Lgeneral;	L->at = (uintp)CODEPC;	op_lda(REG_sp, REG_sp, 0);	/* Calling Standard for Alpha Systems	 * 3.2.6.1    Entry Code Sequence	 * 3. For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0), do	 *    both of these steps.  (There is no requirement as to which step	 *    occurs first.) 	 *	 *    Store the registers specified by PDSC_RPD_IMASK and	 *    PDSC_RDP_FMASK in the register save area based on	 *    PDSC_RPD_RSA_OFFSET.	 *	 *    Store the return address in the register save area.  */	/* Build Register Save mask (without ra) */	alpha_jit_info.imask = 0xFE00;		/* s0 to s5 and fp */	alpha_jit_info.fmask = 0x3FC;		/* f2 to f9 */	/* compute rsa_size for ra, s0-s5, fp, f2-f9 */	rsa_size = 1 + (5 - 0 + 1) + 1 + (9 - 2 + 1);	alpha_jit_info.rsa_size = rsa_size;	/* return address */	L = newLabel();	L->type = Lrsa|Labsolute|Lgeneral;	L->at = (uintp)CODEPC;	op_stq(REG_ra, REG_sp, 0);		N = 1;	/* registers s0 - s5 and fp (also know as s6) */	for (r = 0; r < 7; r++, N++) {		L = newLabel();		L->type = Lrsa|Labsolute|Lgeneral;		L->at = (uintp)CODEPC;		op_stq(REG_s0+r, REG_sp, SLOTSIZE * N);	}	/* registers f2 - f9 */	for (r = 0; r < (9 - 2 + 1); r++, N++) {		L = newLabel();		L->type = Lrsa|Labsolute|Lgeneral;		L->at = (uintp)CODEPC;		op_stt(REG_f2+r, REG_sp, SLOTSIZE * N);	}	    	/* this is the end of the prologue */	alpha_jit_info.entry_length = CODEPC / 4;	/* setup our virtual frame pointer, it's not part of the prologue.  */	L = newLabel();	L->type = Lframe|Labsolute|Lgeneral;	L->at = (uintp)CODEPC;	op_lda(REG_fp, REG_sp, 0);	/* Work out which register is what and where.  */	l = maxLocal + maxStack + maxTemp;	if (alpha_nslot2argoffset < l) {		alpha_nslot2argoffset = l;		alpha_slot2argoffset = KREALLOC(alpha_slot2argoffset,						l * sizeof(alpha_slot2argoffset[0]));	}	if (isStatic) {		r = 0;	}	else {		alpha_slot2argoffset[0] = -SLOTSIZE;		r = 1;	}	sl = r;	/* register passed arguments */	for (l = 0; l < METHOD_NARGS(meth) && r < 6; l++, r++) {		char type = *METHOD_ARG_TYPE(meth, l);				alpha_slot2argoffset[sl++] = -SLOTSIZE * (r+1);		if (type == 'J' || type == 'D') {			/* long and double use two slots */			alpha_slot2argoffset[sl++] = -SLOTSIZE * (r+1);		}	}	aspill = r + 1;		/* memory passed arguments */	for (; l < METHOD_NARGS(meth); l++, r++) {		char type = *METHOD_ARG_TYPE(meth, l);				alpha_slot2argoffset[sl++] = SLOTSIZE * (r-6);		if (type == 'J' || type == 'D') {			/* long and double use two slots */			alpha_slot2argoffset[sl++] = SLOTSIZE * (r-6);		}	}#ifdef KAFFE_VMDEBUG	if (jit_debug) {	    dprintf ("nr arg slots = %d\n", sl);	}#endif		l = maxLocal + maxStack + maxTemp;	/* locals and temps */	while (sl < l) {		alpha_slot2argoffset[sl++] = -SLOTSIZE * (aspill++);	}#ifdef KAFFE_VMDEBUG	if (jit_debug) {		for (sl = 0; sl < l; sl++) {			dprintf ("slot(%d) = %d\n", sl, alpha_slot2argoffset[sl]);		}	}#endif	/* Now assign the registers to slots */        if (isStatic) {		r = 0;	}	else {		forceRegister(&localinfo[0], REG_a0, Rref);		r = 1;	}	sl = r;	for (l = 0; l < METHOD_NARGS(meth) && r < 6; l++, r++, sl++) {		switch (*METHOD_ARG_TYPE(meth, l)) {		case 'L':		case '[':			forceRegister(&localinfo[sl], REG_a0+r, Rref);			break;		case 'B':		case 'C':		case 'I':		case 'S':		case 'Z':			forceRegister(&localinfo[sl], REG_a0+r, Rint);			break;		case 'F':			forceRegister(&localinfo[sl], REG_fa0+r, Rfloat);			break;		case 'J':			forceRegister(&localinfo[sl], REG_a0+r, Rlong);			sl++;			break;		case 'D':			forceRegister(&localinfo[sl], REG_fa0+r, Rdouble);			sl++;			break;		default:			ABORT();		}	}}define_insn(epilogue, epilogue_xxx){	label *l;	int r, N;	setEpilogueLabel ((uintp)CODEPC);	/* Calling Standard for Alpha Systems	 * 3.2.6.2.2   Exit Code Sequence Steps	 * When a procedure returns, the exit code must restore the caller's	 * context, synchronize any pending hardware exceptions, and make the	 * calling procedure current by returning control to it.  The following	 * list contains the exit code sequence steps.  The program performs	 * step 1, followed by steps 2 through 5 in any order, followed by	 * steps 6 through 8 in exact order. 	 *	 * 1. If the GP register has been modified or a call has been made,	 *    restore the GP register to the GOT segment pointer of the current	 *    procedure.	 *	 * 2. For a variable-size stack frame procedure that does not return a	 *    value on the top of stack (PDSC_FLAGS_BASE_REG_IS_FP is 1), copy	 *    FP to SP.	 *	 * 3. For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0),	 *    reload any saved registers from the register save area as	 *    specified by PDSC_RPD_RSA_OFFSET.  Note that, for a variable-size	 *    stack frame procedure (PDSC_FLAGS_BASE_REG_IS_FP is 1), FP is not	 *    reloaded in this step.  For a fixed-size stack frame procedure	 *    (PDSC_FLAGS_BASE_REG_IS_FP is 0), $15 is reloaded if it was saved	 *    on entry.	 *	 * 4. Reload the register that held the return address on entry with	 *    the saved return address, if necessary.	 *	 *    For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0),	 *    load the register designated by PDSC_RPD_ENTRY_RA ($26 in a	 *    standard call) with the return address from the register save	 *    area as specified by PDSC_RPD_RSA_OFFSET.	 *	 *    For a register frame procedure (PDSC_FLAGS_REGISTER_FRAME is 1),	 *    copy the return address from the register specified by	 *    PDSC_RPD_SAVE_RA to the register designated by PDSC_RPD_ENTRY_RA.	 *	 * 5. Execute trapb, if required. (See Section 5.1.12 for details.)	 *	 * 6. For a variable-size stack frame procedure	 *    (PDSC_FLAGS_REGISTER_FRAME is 0 and PDSC_FLAGS_BASE_REG_IS_FP is	 *    1), reload $15 (FP) as would be done for any other saved register.	 *	 *    After any necessary calculations, this step must be completed by	 *    exactly one instruction, as described in Section 3.2.6.1.	 *	 * 7. If a function value is not being returned on the stack, restore	 *    SP to the value it had at procedure entry by adding the value in	 *    PDSC_RDP_FRAME_SIZE to SP.  In some cases, the returning procedure	 *    leaves SP pointing to a lower stack address than it had on entry	 *    to the procedure, as specified in Section 4.1.7.	 *	 *    After any necessary calculations, this step must be completed by	 *    exactly one instruction, as described in Section 3.2.6.1.	 *	 * 8. Execute the ret $31,($n),0001 instruction, as described in	 *    Section 3.2.6.2.1, to return control to the calling procedure.	 *    In almost all cases the $n used will be $26 (the return address	 *    register) because its value must be restored before the call	 *    returns.	 *	 *    Note that the called routine does not adjust the stack to remove	 *    any arguments passed in memory.  This responsibility falls to the	 *    calling routine, which can choose to defer removal of arguments

⌨️ 快捷键说明

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