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

📄 entry.s

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 S
字号:
/* entry.S - exception handler for emulating MIPS16 'entry' and 'exit'   pseudo-instructions.  These instructions are generated by the compiler   when the -mentry switch is used.  The instructions are not implemented   in the MIPS16 CPU; hence the exception handler that emulates them.   This module contains the following public functions:   * void __install_entry_handler(void);     This function installs the entry/exit exception handler.  It should     be called before executing any MIPS16 functions that were compiled with     -mentry, typically before main() is called.   * void __remove_entry_handler(void);     This function removes the entry/exit exception handler.  It should     be called when the program is exiting, or when it is known that no     more MIPS16 functions compiled with -mentry will be called.*/#ifdef __mips16/* This file contains 32 bit assembly code.  */	.set nomips16#endif#include "regs.S"#define CAUSE_EXCMASK	0x3c	/* mask for ExcCode in Cause Register */#define EXC_RI  	0x28	/* 101000 == 10 << 2 *//* Set DEBUG to 1 to enable recording of the last 16 interrupt causes.  */#define DEBUG 0#if DEBUG	.sdataint_count:	.space	4			/* interrupt count modulo 16 */int_cause:	.space	4*16			/* last 16 interrupt causes */#endif	.text	.set	noreorder		/* Do NOT reorder instructions *//* __entry_exit_handler - the reserved instruction exception handler   that emulates the entry and exit instruction.  */__entry_exit_handler:	.set	noat			/* Do NOT use at register */#if DEBUG/* Must avoid using 'la' pseudo-op because it uses gp register, which   may not have a good value in an exception handler. */  #	la	k0, int_count		/* intcount = (intcount + 1) & 0xf */	lui	k0 ,%hi(int_count)	addiu	k0, k0 ,%lo(int_count)	lw	k1, (k0)	addiu	k1, k1, 1	andi	k1, k1, 0x0f	sw	k1, (k0)#	la	k0, int_cause		/* k1 = &int_cause[intcount] */	lui	k0, %hi(int_cause)	addiu	k0, k0, %lo(int_cause)	sll	k1, k1, 2	add	k1, k1, k0#endif		mfc0	k0, C0_CAUSE		/* Fetch cause */#if DEBUG	sw	k0, -4(k1)		/* Save exception cause in buffer */#endif	mfc0	k1, C0_EPC		/* Check for Reserved Inst. without */	and	k0, CAUSE_EXCMASK	/*   destroying any register */	subu	k0, EXC_RI	bne	k0, zero, check_others	/* Sorry, go do something else */	and	k0, k1, 1		/* Check for TR mode (pc.0 = 1) */	beq	k0, zero, ri_in_32	/* Sorry, RI in 32-bit mode */	xor	k1, 1			/* Since we now are going to emulate or die, we can use all the T-registers *//* that MIPS16 does not use (at, t0-t8), and we don't have to save them. */	.set	at			/* Now it's ok to use at again */#if 0	j	leave	rfe#endif	lhu	t0, 0(k1)		/* Fetch the offending instruction */	xor	t8, k1, 1		/* Prepare t8 for exit */	and	t1, t0, 0xf81f		/* Check for entry/exit opcode */	bne	t1, 0xe809, other_rideareg:	and	t1, t0, 0x0700		/* Isolate the three a-bits */	srl	t1, 6			/* Adjust them so x4 is applied */	slt     t2, t1, 17		/* See if this is the exit instruction */	beqz    t2, doexit	la	t2, savea	subu	t2, t1	jr	t2			/* Jump into the instruction table */	rfe				/* We run the rest in user-mode */					/* This is the entry instruction! */	sw	a3, 12(sp)		/* 4: a0-a3 saved */	sw	a2,  8(sp)		/* 3: a0-a2 saved */	sw	a1,  4(sp)		/* 2: a0-a1 saved */	sw	a0,  0(sp)		/* 1: a0    saved */savea:					/* 0: No arg regs saved */dera:	and	t1, t0, 0x0020		/* Isolate the save-ra bit */	move	t7, sp			/* Temporary SP */	beq	t1, zero, desreg	subu	sp, 32			/* Default SP adjustment */	sw	ra, -4(t7)	subu	t7, 4desreg:	and	t1, t0, 0x00c0		/* Isolate the two s-bits */	beq	t1, zero, leave	subu	t1, 0x0040	beq	t1, zero, leave		/* Only one to save... */	sw	s0, -4(t7)		/* Do the first one */	sw	s1, -8(t7)		/* Do the last one */leave:	jr	t8			/* Exit to unmodified EPC */	nop				/* Urgh - the only nop!! */doexf0: mtc1	v0,$f0			/* Copy float value */	b       doex2doexf1:	mtc1	v1,$f0			/* Copy double value */	mtc1    v0,$f1	b       doex2doexit:	slt	t2, t1, 21	beq	t2, zero, doexf0	slt	t2, t1, 25	beq	t2, zero, doexf1doex2:	and	t1, t0, 0x0020		/* Isolate ra bit */	beq     t1, zero, dxsreg	/* t1 holds ra-bit */	addu	t7, sp, 32		/* Temporary SP */	lw	ra, -4(t7)	subu	t7, 4dxsreg:	and	t1, t0, 0x00c0		/* Isolate the two s-bits */	beq	t1, zero, leavex	subu	t1, 0x0040	beq	t1, zero, leavex	/* Only one to save... */	lw	s0, -4(t7)		/* Do the first one */	lw	s1, -8(t7)		/* Do the last one */leavex:	jr	ra			/* Exit to ra */	addu	sp, 32			/* Clean up stack pointer *//* Come here for exceptions we can't handle.  */ri_in_32:other_ri:check_others:				/* call the previous handler */	la	k0,__previous	jr	k0	nop__exception_code:	.set noreorder	la	k0, __entry_exit_handler#	lui	k0, %hi(exception)#	addiu	k0, k0, %lo(exception)	jr	k0	nop	.set reorder__exception_code_end:	.data__previous:	.space	(__exception_code_end - __exception_code)	.text/* void __install_entry_handler(void)   Install our entry/exit reserved instruction exception handler.*/	.ent	__install_entry_handler	.globl	__install_entry_handler__install_entry_handler:        .set noreorder	mfc0	a0,C0_SR	nop	li	a1,SR_BEV	and	a1,a1,a0	beq	a1,$0,baseaddr	lui	a0,0x8000	/* delay slot */	lui	a0,0xbfc0	addiu	a0,a0,0x0100baseaddr:	addiu	a0,a0,0x080	/* a0 = base vector table address */	li	a1,(__exception_code_end - __exception_code)	la	a2,__exception_code	la	a3,__previous/* there must be a better way of doing this???? */copyloop:	lw	v0,0(a0)	sw	v0,0(a3)	lw	v0,0(a2)	sw	v0,0(a0)	addiu	a0,a0,4	addiu	a2,a2,4	addiu	a3,a3,4	subu	a1,a1,4	bne	a1,$0,copyloop	nop	j	ra	nop        .set reorder	.end	__install_entry_handler/* void __remove_entry_handler(void);   Remove our entry/exit reserved instruction exception handler.*/	.ent	__remove_entry_handler	.globl	__remove_entry_handler__remove_entry_handler:        .set noreorder	mfc0	a0,C0_SR	nop	li	a1,SR_BEV	and	a1,a1,a0	beq	a1,$0,res_baseaddr	lui	a0,0x8000	/* delay slot */	lui	a0,0xbfc0	addiu	a0,a0,0x0200res_baseaddr:	addiu	a0,a0,0x0180	/* a0 = base vector table address */	li	a1,(__exception_code_end - __exception_code)	la	a3,__previous/* there must be a better way of doing this???? */res_copyloop:	lw	v0,0(a3)	sw	v0,0(a0)	addiu	a0,a0,4	addiu	a3,a3,4	subu	a1,a1,4	bne	a1,$0,res_copyloop	nop	j	ra	nop        .set reorder	.end	__remove_entry_handler/* software_init_hook - install entry/exit handler and arrange to have it   removed at exit.  This function is called by crt0.S.  */	.text	.globl	software_init_hook	.ent	software_init_hooksoftware_init_hook:	.set	noreorder	subu	sp, sp, 8			/* allocate stack space */	sw	ra, 4(sp)			/* save return address */	jal	__install_entry_handler		/* install entry/exit handler */	nop	lui	a0, %hi(__remove_entry_handler)	/* arrange for exit to */	jal	atexit				/*  de-install handler */	addiu	a0, a0, %lo(__remove_entry_handler)	/* delay slot */	lw	ra, 4(sp)			/* get return address */	j	ra				/* return */	addu	sp, sp, 8			/* deallocate stack */	.set	reorder	.end	software_init_hook

⌨️ 快捷键说明

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