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

📄 c62.h62

📁 SEED的VPM642测试程序-板级支持库
💻 H62
📖 第 1 页 / 共 3 页
字号:

	.if ($symcmp(SPFLAG, "NOSP") == 0) 
		ldw	*+SP[even_ones], SPA			; CODE
		.eval	even_ones, C62_spoffset 
	.else
		ldw	*++SP[even_ones], SPA			; CODE
	.endif

	nop	4						; CODE

	.endif			; if !(amask = bmask = cmask = 0)

	.endm

;
;# ======== C62_restoresp ========
;
;#
;# Preconditions:
;#	none
;#
;# Postconditions:
;#	none
;#
;
C62_restoresp .macro	offset, tempreg
	.eval	offset * STD_TARGWORDMAUS, num
	mvkl	num, :tempreg:
	mvkh	num, :tempreg:
	add	SP, :tempreg:, SP
	.endm

;
;# ======== C62_save ========
;
;  This macro conditionally saves registers onto the stack, depending
;  on ABMASK and CMASK. Typically, use of this macro is balanced with 
;  use of the C62_restore macro with the same mask values.
;
;  C62_save ABMASK, CMASK
;
;  ABMASK - Mask of A and B registers to save
;  CMASK - Mask of control registers to save
;
; Currently, this macro is largely complicated by the fact that you
; can't have an assembly construct like the following:
;	.if	(bitcount > 1)
; ||	mv	A4, B0
;	.endif
; The assembler complains about an illegal mnemonic.  Without the
; ability to generate code as above, many places in this macro are
; greatly more complicated since they must now look ahead.
;
; We need to maintain 8-byte stack alignment.
; The method chosen is to count the number of bits in the masks,
; thereby giving you the number of registers to save.  This is
; then rounded up to the nearest even number, and the SP is
; adjusted once up front, with all subsequent "stores" being
; offset into that frame.  Since the pre-processor is doing all
; the counting, this turns out to be equally efficient to the
; C6x method involving "pushes".
;
; Uses two lowest numbered A registers in ABMASK for an A-side stack
; frame pointer and a temporary A register.  If no A registers specified
; in ABMASK, registers A0 & A1 are saved and used.  If only register A0
; is specified, register A1 is also saved and used.  If a register other
; than A0 is specified, register A0 and that one are saved and used.
;
; For the B-side, the lowest numbered B register in ABMASK is used, and
; if no B register is specified, register B0 is saved and used.
;
;#
;# Preconditions:
;#	none
;#
;# Postconditions:
;#	none
;#
;

C62_save .macro ABMASK, CMASK
	.asg	0, mask
	.asg	0, bitn_a
	.asg	0, bitn_b
	.asg	-1, bitn_c
	.asg	0, bitn_0
	.asg	0, bitn_1
	.asg	0, bitn_next
	.asg	0, bitcount
	.asg	0, a_bitcount
	.asg	0, b_bitcount
	.asg	0, c_bitcount
	.asg	0, creg0
	.asg	0, creg1
	.asg	0, creg_next

	.eval	ABMASK & 0x0000ffff, amask
	.eval	(ABMASK >> 16) & 0xffff, bmask
	.eval	bmask & ~(C62_B15 >> 16), bmask		; don't save B15
	.eval	CMASK, cmask

	;
	; .mexit was causing errors since the rest of the macro
	; was getting expanded even though it wasn't used.  Instead
	; of .mexit, turn the 'if' test around to control inclusion
	; of the rest of the macro.
	;
	.if	!((amask = 0) & (bmask = 0) & (cmask = 0))

	;
	; Count 1 bits in masks
	;
	NUM_BITS	amask, a_bitcount
	NUM_BITS	bmask, b_bitcount
	NUM_BITS	cmask, c_bitcount

	; make sure at least two A registers are specified
	.if	(a_bitcount = 0)
	    .eval	C62_A0 | C62_A1, amask
	    .eval	a_bitcount + 2, a_bitcount
	.elseif	(a_bitcount = 1)
	    .if	(amask & C62_A0)
		.eval	amask | C62_A1, amask
	    .eval	a_bitcount + 1, a_bitcount
	    .else
		.eval	amask | C62_A0, amask
	    .eval	a_bitcount + 1, a_bitcount
	    .endif
	.endif

	; make sure at least one B register is specified
	.if	(bmask = 0)
	    .eval	(C62_B0 >> 16) & 0xffff, bmask
	    .eval	b_bitcount + 1, b_bitcount
	.endif

	.eval	a_bitcount + b_bitcount + c_bitcount, ones

	.eval	ones + 1, tmp_ones			; align to even
	.eval	tmp_ones & 0xfffffffe, even_ones	;   number of words
	.eval	even_ones * 4, words
	.eval	even_ones - 1, offset

	; assign A-side stack frame pointer and temp A register
	FIRST_BIT_NUM	amask, bitn_a
	.eval	amask & ~(1 << bitn_a), amask
	.asg	a:bitn_a:, SPA
	FIRST_BIT_NUM	amask, bitn_a
	.eval	amask & ~(1 << bitn_a), amask
	.asg	a:bitn_a:, TMPA
	.eval	a_bitcount - 2, a_bitcount

	; assign B-side stack frame pointer and temp B register
	FIRST_BIT_NUM	bmask, bitn_b
	.eval	bmask & ~(1 << bitn_b), bmask
	.asg	b:bitn_b:, TMPB
	.asg	SP, SPB
	.eval	b_bitcount - 1, b_bitcount

	.if	(amask = 0) | (bmask = 0)
	    .if	(a_bitcount > 0)
		.asg	amask, mask
		.asg	A, reg
		.asg	TMPB, tmpreg
	    .elseif	(b_bitcount > 0)
		.asg	bmask, mask
		.asg	B, reg
		.asg	TMPA, tmpreg
	    .elseif	(cmask > 0)
		; both amask and bmask = 0
		FIRST_BIT_NUM	cmask, bitn_c
		BIT_NUM_2_CREG	bitn_c, creg0
	    .endif
	.endif

	stw	SPA, *SP--[even_ones]				; CODE
	mv	SP, SPA						; CODE

	.if	(mask = 0)
	    .if	(bitn_c = -1)
		; both amask and bmask non-zero

		stw	TMPB, *+SPB[offset]			; CODE
||		stw	TMPA, *+SPA[offset - 1]			; CODE

	    .else
		; both amask and bmask = 0

		stw	TMPB, *+SPB[offset]			; CODE
||		stw	TMPA, *+SPA[offset - 1]			; CODE
||		mvc	creg0, TMPB				; CODE

	    .endif
	.else
	    ; one of amask or bmask is 0, but not both
	    FIRST_BIT_NUM	mask, bitn_next

	    stw	TMPB, *+SPB[offset]				; CODE
||	    stw	TMPA, *+SPA[offset - 1]				; CODE
||	    mv	:reg::bitn_next:, tmpreg			; CODE

	    .asg	0, mask
	.endif

	.eval	offset - 2, offset

	;
	; This loop handles when both A and B registers need saving
	;
	.loop
	    .if		(a_bitcount > 0) & (b_bitcount > 0)
		FIRST_BIT_NUM	amask, bitn_a
		FIRST_BIT_NUM	bmask, bitn_b
		.eval	amask & ~(1 << bitn_a), amask
		.eval	bmask & ~(1 << bitn_b), bmask

		.if	!(((a_bitcount = 1) & (b_bitcount > 2)) | ((b_bitcount = 1) & (a_bitcount > 2)))
		    ;
		    ; At this point, one of the following is true:
		    ;	1. a_bitcount & b_bitcount > 1
		    ;	2. a_bitcount & b_bitcount = 1
		    ;	3. a_bitcount = 1 & b_bitcount = 2
		    ;	4. a_bitcount = 2 & b_bitcount = 1
		    ; In cases 2-4 this is the last iteration of the loop
		    ;

		    stw	b:bitn_b:, *+SPB[offset]		; CODE
||		    stw	a:bitn_a:, *+SPA[offset - 1]		; CODE

		    .eval	offset - 2, offset
		    .eval	a_bitcount - 1, a_bitcount
		    .eval	b_bitcount - 1, b_bitcount
		.else
		    ;
		    ; Either a_bitcount or b_bitcount equals 1, but not both.
		    ; The one != 1 is > 2.
		    ; We're going to exit the loop after this, knowing we'll
		    ; also be doing the next loop at least twice.
		    ;
		    .if	(b_bitcount = 1)
			.asg	amask, mask
			.asg	A, reg
			.asg	TMPB, tmpreg
		    .elseif	(a_bitcount = 1)
			.asg	bmask, mask
			.asg	B, reg
			.asg	TMPA, tmpreg
		    .else
			.emsg	"Bad macro logic"
			.break
		    .endif

		    FIRST_BIT_NUM	mask, bitn_next

		    stw	b:bitn_b:, *+SPB[offset]		; CODE
||		    stw	a:bitn_a:, *+SPA[offset - 1]		; CODE
||		    mv	:reg::bitn_next:, tmpreg		; CODE

		    .eval	offset - 2, offset
		    .eval	a_bitcount - 1, a_bitcount
		    .eval	b_bitcount - 1, b_bitcount

		    .break
		.endif
	    .else
		.break
	    .endif
	.endloop

	.if	(a_bitcount > 0)
	    .asg	amask, mask
	    .asg	A, reg
	    .asg	TMPB, tmpreg
	.elseif	(b_bitcount > 0)
	    .asg	bmask, mask
	    .asg	B, reg
	    .asg	TMPA, tmpreg
	.endif

	;
	; we enter this loop when there are only registers from either
	; A or B remaining (but not both).
	;
	NUM_BITS	mask, bitcount
	.loop
	    .if	(mask != 0)
		.if	(bitcount > 1)
		    FIRST_BIT_NUM	mask, bitn_0
		    .eval	mask & ~(1 << bitn_0), mask
		    FIRST_BIT_NUM	mask, bitn_1
		    .eval	mask & ~(1 << bitn_1), mask
		    .eval	bitcount - 2, bitcount

		    .if	(bitcount > 1)
			FIRST_BIT_NUM	mask, bitn_next

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;		mv	:reg::bitn_0:, tmpreg			; CODE
			stw	tmpreg, *+SPB[offset]			; CODE
||			stw	:reg::bitn_1:, *+SPA[offset - 1]	; CODE
||			mv	:reg::bitn_next:, tmpreg		; CODE

		    .else
			.if (bitcount = 0) & (c_bitcount > 0)
			    FIRST_BIT_NUM	cmask, bitn_c
			    BIT_NUM_2_CREG	bitn_c, creg0

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;		    mv	:reg::bitn_0:, tmpreg			; CODE
			    stw	tmpreg, *+SPB[offset]			; CODE
||			    stw	:reg::bitn_1:, *+SPA[offset - 1]	; CODE
||			    mvc	creg0, TMPB				; CODE

			.else

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;		    mv	:reg::bitn_0:, tmpreg			; CODE
			    stw	tmpreg, *+SPB[offset]			; CODE
||			    stw	:reg::bitn_1:, *+SPA[offset - 1]	; CODE

			.endif
		    .endif

		    .eval	offset - 2, offset
		.else
		    ; last iteration of this loop
		    FIRST_BIT_NUM	mask, bitn_0
		    .eval	mask & ~(1 << bitn_0), mask

		    .if (c_bitcount > 0)
			FIRST_BIT_NUM	cmask, bitn_c
			BIT_NUM_2_CREG	bitn_c, creg0

			stw	:reg::bitn_0:, *+SP[offset]	; CODE
||			mvc	creg0, TMPB			; CODE

		    .else

			stw	:reg::bitn_0:, *+SP[offset]	; CODE

		    .endif

		    .eval	offset - 1, offset
		    .break
		.endif
	    .endif
	.endloop

	.if	(c_bitcount > 0) & (bitn_c = -1)
	    FIRST_BIT_NUM	cmask, bitn_c
	    BIT_NUM_2_CREG	bitn_c, creg0

	    mvc	creg0, TMPB			; CODE
	.endif

	;
	; This loop handles the control registers
	;
	.loop
	    .if		(c_bitcount > 1)
		FIRST_BIT_NUM	cmask, bitn_c
		BIT_NUM_2_CREG	bitn_c, creg0
		.eval	cmask & ~(1 << bitn_c), cmask
		FIRST_BIT_NUM	cmask, bitn_c
		BIT_NUM_2_CREG	bitn_c, creg1
		.eval	cmask & ~(1 << bitn_c), cmask
		.eval	c_bitcount - 2, c_bitcount

		.if	(c_bitcount > 0)
		    FIRST_BIT_NUM	cmask, bitn_next
		    BIT_NUM_2_CREG	bitn_next, creg_next

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;	    mvc	creg0, TMPB				; CODE
		    mvc	creg1, TMPB				; CODE
||		    mv	TMPB, TMPA				; CODE
		    stw	TMPA, *+SPA[offset]			; CODE
||		    stw	TMPB, *+SPB[offset - 1]			; CODE
||		    mvc	creg_next, TMPB				; CODE

		.else

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;	    mvc	creg0, TMPB				; CODE
		    mvc	creg1, TMPB				; CODE
||		    mv	TMPB, TMPA				; CODE
		    stw	TMPA, *+SPA[offset]			; CODE
||		    stw	TMPB, *+SPB[offset - 1]			; CODE

		.endif

		.eval	offset - 2, offset
	    .elseif	(c_bitcount = 1)
		FIRST_BIT_NUM	cmask, bitn_c
		BIT_NUM_2_CREG	bitn_c, creg0
		.eval	cmask & ~(1 << bitn_c), cmask
		.eval	c_bitcount - 1, c_bitcount

;;;;;;;; already done by previous iteration of this loop or previous loop
;;;;;;;;	mvc	creg0, TMPB				; CODE
		stw	TMPB, *+SPB[offset]			; CODE

		.eval	offset - 1, offset
		.break
	    .else
		.break
	    .endif
	.endloop

	.endif			; if !(amask = bmask = cmask = 0)

	.endm

	.endif			; if C62_ is not defined

⌨️ 快捷键说明

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