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

📄 fp_decode.h

📁 microwindows移植到S3C44B0的源码
💻 H
字号:
/* * fp_decode.h * * Copyright Roman Zippel, 1997.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, and the entire permission notice in its entirety, *    including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote *    products derived from this software without specific prior *    written permission. * * ALTERNATIVELY, this product may be distributed under the terms of * the GNU General Public License, in which case the provisions of the GPL are * required INSTEAD OF the above restrictions.  (This clause is * necessary due to a potential bad interaction between the GPL and * the restrictions contained in a BSD-style copyright.) * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */#ifndef _FP_DECODE_H#define _FP_DECODE_H/* These macros do the dirty work of the instr decoding, several variables * can be defined in the source file to modify the work of these macros, * currently the following variables are used: * ... * The register usage: * d0 - will contain source operand for data direct mode, *	otherwise scratch register * d1 - upper 16bit are reserved for caller *	lower 16bit may contain further arguments, *	is destroyed during decoding * d2 - contains first two instruction words, *	first word will be used for extension word * a0 - will point to source/dest operand for any indirect mode *	otherwise scratch register * a1 - scratch register * a2 - base addr to the task structure * * the current implementation doesn't check for every disallowed * addressing mode (e.g. pc relative modes as destination), as long * as it only means a new addressing mode, which should not appear * in a program and that doesn't crash the emulation, I think it's * not a problem to allow these modes. */do_fmovem=0do_fmovem_cr=0do_no_pc_mode=0do_fscc=0| first decoding of the instr type| this seperates the conditional instr.macro	fp_decode_cond_instr_type	bfextu	%d2{#8,#2},%d0	jmp	([0f:w,%pc,%d0*4])	.align	40:|	.long	"f<op>","fscc/fdbcc"|	.long	"fbccw","fbccl".endm| second decoding of the instr type| this seperates most move instr.macro	fp_decode_move_instr_type	bfextu	%d2{#16,#3},%d0	jmp	([0f:w,%pc,%d0*4])	.align	40:|	.long	"f<op> fpx,fpx","invalid instr"|	.long	"f<op> <ea>,fpx","fmove fpx,<ea>"|	.long	"fmovem <ea>,fpcr","fmovem <ea>,fpx"|	.long	"fmovem fpcr,<ea>","fmovem fpx,<ea>".endm| extract the source specifier, specifies| either source fp register or data format.macro	fp_decode_sourcespec	bfextu	%d2{#19,#3},%d0.endm| decode destination format for fmove reg,ea.macro	fp_decode_dest_format	bfextu	%d2{#19,#3},%d0.endm| decode source register for fmove reg,ea.macro	fp_decode_src_reg	bfextu	%d2{#22,#3},%d0.endm| extract the addressing mode| it depends on the instr which of the modes is valid.macro	fp_decode_addr_mode	bfextu	%d2{#10,#3},%d0	jmp	([0f:w,%pc,%d0*4])	.align	40:|	.long	"data register direct","addr register direct"|	.long	"addr register indirect"|	.long	"addr register indirect postincrement"|	.long	"addr register indirect predecrement"|	.long	"addr register + index16"|	.long	"extension mode1","extension mode2".endm| extract the register for the addressing mode.macro	fp_decode_addr_reg	bfextu	%d2{#13,#3},%d0.endm| decode the 8bit diplacement from the brief extension word.macro	fp_decode_disp8	move.b	%d2,%d0	ext.w	%d0.endm| decode the index of the brief/full extension word.macro	fp_decode_index	bfextu	%d2{#17,#3},%d0		| get the register nr	btst	#15,%d2			| test for data/addr register	jne	1\@f	printf	PDECODE,"d%d",1,%d0	jsr	fp_get_data_reg	jra	2\@f1\@:	printf	PDECODE,"a%d",1,%d0	jsr	fp_get_addr_reg	move.l	%a0,%d02\@:debug	lea	"'l'.w,%a0"	btst	#11,%d2			| 16/32 bit size?	jne	3\@fdebug	lea	"'w'.w,%a0"	ext.l	%d03\@:	printf	PDECODE,":%c",1,%a0	move.w	%d2,%d1			| scale factor	rol.w	#7,%d1	and.w	#3,%d1debug	move.l	"%d1,-(%sp)"debug	ext.l	"%d1"	printf	PDECODE,":%d",1,%d1debug	move.l	"(%sp)+,%d1"	lsl.l	%d1,%d0.endm| decode the base displacement size.macro	fp_decode_basedisp	bfextu	%d2{#26,#2},%d0	jmp	([0f:w,%pc,%d0*4])	.align	40:|	.long	"reserved","null displacement"|	.long	"word displacement","long displacement".endm.macro	fp_decode_outerdisp	bfextu	%d2{#30,#2},%d0	jmp	([0f:w,%pc,%d0*4])	.align	40:|	.long	"no memory indirect action/reserved","null outer displacement"|	.long	"word outer displacement","long outer displacement".endm| get the extension word and test for brief or full extension type.macro	fp_get_test_extword label	fp_get_instr_word %d2,fp_err_ua1	btst	#8,%d2	jne	\label.endm| test if %pc is the base register for the indirect addr mode.macro	fp_test_basereg_d16	label	btst	#20,%d2	jeq	\label.endm| test if %pc is the base register for one of the extended modes.macro	fp_test_basereg_ext	label	btst	#19,%d2	jeq	\label.endm.macro	fp_test_suppr_index label	btst	#6,%d2	jne	\label.endm| addressing mode: data register direct.macro	fp_mode_data_direct	fp_decode_addr_reg	printf	PDECODE,"d%d",1,%d0.endm| addressing mode: address register indirect.macro	fp_mode_addr_indirect	fp_decode_addr_reg	printf	PDECODE,"(a%d)",1,%d0	jsr	fp_get_addr_reg.endm| adjust stack for byte moves from/to stack.macro	fp_test_sp_byte_move	.if	!do_fmovem	.if	do_fscc	move.w	#6,%d1	.endif	cmp.w	#7,%d0	jne	1\@f	.if	!do_fscc	cmp.w	#6,%d1	jne	1\@f	.endif	move.w	#4,%d11\@:	.endif.endm| addressing mode: address register indirect with postincrement.macro	fp_mode_addr_indirect_postinc	fp_decode_addr_reg	printf	PDECODE,"(a%d)+",1,%d0	fp_test_sp_byte_move	jsr	fp_get_addr_reg	move.l	%a0,%a1			| save addr	.if	do_fmovem	lea	(%a0,%d1.w*4),%a0	.if	!do_fmovem_cr	lea	(%a0,%d1.w*8),%a0	.endif	.else	add.w	(fp_datasize,%d1.w*2),%a0	.endif	jsr	fp_put_addr_reg	move.l	%a1,%a0.endm| addressing mode: address register indirect with predecrement.macro	fp_mode_addr_indirect_predec	fp_decode_addr_reg	printf	PDECODE,"-(a%d)",1,%d0	fp_test_sp_byte_move	jsr	fp_get_addr_reg	.if	do_fmovem	.if	!do_fmovem_cr	lea	(-12,%a0),%a1		| setup to addr of 1st reg to move	neg.w	%d1	lea	(%a0,%d1.w*4),%a0	add.w	%d1,%d1	lea	(%a0,%d1.w*4),%a0	jsr	fp_put_addr_reg	move.l	%a1,%a0	.else	neg.w	%d1	lea	(%a0,%d1.w*4),%a0	jsr	fp_put_addr_reg	.endif	.else	sub.w	(fp_datasize,%d1.w*2),%a0	jsr	fp_put_addr_reg	.endif.endm| addressing mode: address register/programm counter indirect|		   with 16bit displacement.macro	fp_mode_addr_indirect_disp16	.if	!do_no_pc_mode	fp_test_basereg_d16 1f	printf	PDECODE,"pc"	fp_get_pc %a0	jra	2f	.endif1:	fp_decode_addr_reg	printf	PDECODE,"a%d",1,%d0	jsr	fp_get_addr_reg2:	fp_get_instr_word %a1,fp_err_ua1	printf	PDECODE,"@(%x)",1,%a1	add.l	%a1,%a0.endm| perform preindex (if I/IS == 0xx and xx != 00).macro	fp_do_preindex	moveq	#3,%d0	and.w	%d2,%d0	jeq	1f	btst	#2,%d2	jne	1f	printf	PDECODE,")@("	getuser.l (%a1),%a1,fp_err_ua1,%a1debug	jra	"2f"1:	printf	PDECODE,","2:.endm| perform postindex (if I/IS == 1xx).macro	fp_do_postindex	btst	#2,%d2	jeq	1f	printf	PDECODE,")@("	getuser.l (%a1),%a1,fp_err_ua1,%a1debug	jra	"2f"1:	printf	PDECODE,","2:.endm| all other indirect addressing modes will finally end up here.macro	fp_mode_addr_indirect_extmode0	.if	!do_no_pc_mode	fp_test_basereg_ext 1f	printf	PDECODE,"pc"	fp_get_pc %a0	jra	2f	.endif1:	fp_decode_addr_reg	printf	PDECODE,"a%d",1,%d0	jsr	fp_get_addr_reg2:	move.l	%a0,%a1	swap	%d2	fp_get_test_extword 3f	| addressing mode: address register/programm counter indirect	|		   with index and 8bit displacement	fp_decode_disp8debug	ext.l	"%d0"	printf	PDECODE,"@(%x,",1,%d0	add.w	%d0,%a1	fp_decode_index	add.l	%d0,%a1	printf	PDECODE,")"	jra	9f3:	| addressing mode: address register/programm counter memory indirect	|		   with base and/or outer displacement	btst	#7,%d2			| base register suppressed?	jeq	1f	printf	PDECODE,"!"	sub.l	%a1,%a11:	printf	PDECODE,"@("	fp_decode_basedisp	.long	fp_ill,1f	.long	2f,3f#ifdef FPU_EMU_DEBUG1:	printf	PDECODE,"0"		| null base displacement	jra	1f#endif2:	fp_get_instr_word %a0,fp_err_ua1 | 16bit base displacement	printf	PDECODE,"%x:w",1,%a0	jra	4f3:	fp_get_instr_long %a0,fp_err_ua1 | 32bit base displacement	printf	PDECODE,"%x:l",1,%a04:	add.l	%a0,%a11:	fp_do_postindex	fp_test_suppr_index 1f	fp_decode_index	add.l	%d0,%a11:	fp_do_preindex	fp_decode_outerdisp	.long	5f,1f	.long	2f,3f#ifdef FPU_EMU_DEBUG1:	printf	PDECODE,"0"		| null outer displacement	jra	1f#endif2:	fp_get_instr_word %a0,fp_err_ua1 | 16bit outer displacement	printf	PDECODE,"%x:w",1,%a0	jra	4f3:	fp_get_instr_long %a0,fp_err_ua1 | 32bit outer displacement	printf	PDECODE,"%x:l",1,%a04:	add.l	%a0,%a11:5:	printf	PDECODE,")"9:	move.l	%a1,%a0	swap	%d2.endm| get the absolute short address from user space.macro	fp_mode_abs_short	fp_get_instr_word %a0,fp_err_ua1	printf	PDECODE,"%x.w",1,%a0.endm| get the absolute long address from user space.macro	fp_mode_abs_long	fp_get_instr_long %a0,fp_err_ua1	printf	PDECODE,"%x.l",1,%a0.endm#endif /* _FP_DECODE_H */

⌨️ 快捷键说明

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