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

📄 vaxarith.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_0 - module_base	 .text	3	 .word	add_sub_bsbw_0 - module_base	 .textLadd_sub_bsbw_0:	jsb	decimal$strip_zeros_r2_r3	# strip high order zeros from r2/r3 string #	roprand_check	r0			# insure that r0 is lequ 31	 cmpw	r2,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r2,r2 #	mark_point	add_sub_bsbw_0_a	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_0_a - module_base	 .text	3	 .word	add_sub_bsbw_0 - module_base	 .textLadd_sub_bsbw_0_a:	jsb	decimal$strip_zeros_r0_r1	# strip high order zeros from r0/r1 string # rather than totally confuse the already complicated logic dealing with # different length strings in the add or subtract loop, we will put the # result into an intermediate buffer on the stack. this buffer will be long # enough to handle the worst case so that the addition loop need only concern # itself with the lengths of the two input loops. the required length is 17 # bytes, to handle an addition with a carry out of the most significant byte. # we will allocate 20 bytes to maintain whatever alignment the stack has.	clrq	-(sp)			# set aside space for output string	clrq	-(sp)			# worst case string needs 16 bytes	clrl	-(sp)			# add slack for a carry	extzv	$1,$4,r4,r8		# get byte count of destination string	addl3	r8,r5,-(sp)		# save high address end of destination	movab	24(sp),r5		# point r5 one byte beyond buffer # the number of minus signs will determine whether the real operation that we # perform is addition or subtraction. that is, two plus signs or two minus # signs will both result in addition, while a plus sign and a minus sign will # result in subtraction. the addition and subtraction routines have their own # methods for determining the correct sign of the result.  #  # for the purpose of counting minus signs, we treat subtraction as the # addition of the negative of the input operand. that is, subtraction of a # positive quantity causes the sign to be remembered as minus and counted as # a minus sign while subtraction of a minus quantity stores a plus sign and # counts nothing.  #  # on input to this code sequence, r9 distinguished addition from subtraction. # on output, it contains either 0, 1, or 2, indicating the total number of # minus signs, real or implied, that we counted. 	extzv	$1,$4,r0,r6		# get byte count for first input string	addl2	r6,r1			# point r1 to byte containing sign #	mark_point	add_sub_24	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24 - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24: 	bicb3	$0x0f0,(r1),r6		# r6 contains the sign "digit"	blbs	r9,L35			# use second case if subtraction # this case statement is used for addition        caseb   r6,$10,$15-10  		# dispatch on sign digitL1:        .word   5f-L1                  # 10 => sign is "+"        .word   4f-L1                  # 11 => sign is "-"        .word   5f-L1                  # 12 => sign is "+"        .word   4f-L1                  # 13 => sign is "-"        .word   5f-L1                  # 14 => sign is "+"        .word   5f-L1                  # 15 => sign is "+" # this case statement is used for subtractionL35:    caseb   r6,$10,$15-10		# dispatch on sign digitL2:        .word   4f-L2                   # 10 => treat sign as "-"        .word   5f-L2                   # 11 => treat sign as "+"        .word   4f-L2                   # 12 => treat sign as "-"        .word   5f-L2                   # 13 => treat sign as "+"        .word   4f-L2                   # 14 => treat sign as "-"        .word   4f-L2                   # 15 => treat sign as "-"4:	movl	$1,r9			# count a minus sign	movzbl	$13,r6			# the preferred minus sign is 13	brb	6f			# now check second input sign5:	clrl	r9			# no real minus signs so far	movzbl	$12,r6			# the preferred minus sign is 126:	extzv	$1,$4,r2,r7		# get byte count for second input string	addl2	r7,r3			# point r3 to byte containing sign #	mark_point	add_sub_24_a	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_a - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_a:	bicb3	$0x0f0,(r3),r7	# r7 contains the sign "digit"        caseb   r7,$10,$15-10		# dispatch on sign digitL3:        .word   8f-L3                   # 10 => sign is "+"        .word   7f-L3                   # 11 => sign is "-"        .word   8f-L3                   # 12 => sign is "+"        .word   7f-L3                   # 13 => sign is "-"        .word   8f-L3                   # 14 => sign is "+"        .word   8f-L3                   # 15 => sign is "+"7:	incl	r9			# remember that sign was minus	movzbl	$13,r7			# the preferred minus sign is 13	brb	9f			# now check second input sign8:	movzbl	$12,r7			# the preferred minus sign is 129:	blbc	r9,add_packed		# even parity indicates addition	brw	subtract_packed		# odd parity calls for subtraction # #+ # functional description: # #	this routine adds two packed decimal strings whose descriptors #	are passed as input parameters and places their sum into another #	(perhaps identical) packed decimal string. # #	at the present time, the result is placed into a 16-byte storage #	area while the sum is being evaluated. this drastically reduces #	the number of different cases that must be dealt with as each #	pair of bytes in the two input strings is added. # #	the signs of the two input strings have already been dealt with #	so this routine performs addition in all cases, even if the original #	entry was at subp4 or subp6. the cases that arrive in this routine #	are as follows. # #                          r2/r3           r0/r1          result #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 + r0/r1 |     plus      |     plus      |     plus      | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 + r0/r1 |     minus     |     minus     |     minus     | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 - r0/r1 |     minus     |     plus      |     minus     | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 - r0/r1 |     plus      |     minus     |     plus      | #                    |               |               |               | #                    +---------------+---------------+---------------+ # #	note that the correct choice of sign in all four cases is the sign #	of the second input string, the one described by r2 and r3. # # input parameters: # #	r0<4:0> - number of digits in first input decimal string #	r1      - address of least significant digit of first input  #		  decimal string (the byte containing the sign) # #	r2<4:0> - number of digits in second input decimal string #	r3      - address of least significant digit of second input  #		  decimal string (the byte containing the sign) # #	r4<4:0> - number of digits in output decimal string #	r5      - address of one byte beyond least significant digit of  #		  intermediate string stored on the stack # #	r6<3:0> - sign of first input string in preferred form #	r7<3:0> - sign of second input string in preferred form # #	r11     - saved psl (z-bit is set, other condition codes are clear) # #	(sp)	- saved r5, address of least significant digit of ultimate #		  destination string. #	4(sp)   - beginning of 20-byte buffer to hold intermediate result # # output parameters: # #	the particular input operation (addpx or subpx) is completed in #	this routine. see the routine headers for the four routines that #	request addition or subtraction for a list of output parameters #	from this routine. #-add_packed:	movb	r7,r9			# use sign of second string for output	blbc	r9,1f			# check if sign is negative	bisb2	$psl$m_n,r11		# ... so the saved n-bit can be set #	mark_point	add_sub_24_b	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_b - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_b:1:	bicb3	$0x0f,(r1),r6		# get least significant digit to r6 #	mark_point	add_sub_24_c	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_c - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_c:	bicb3	$0x0f,(r3),r7		# get least significant digit to r7	clrl	r8			# start the add with carry off	bsbw	add_packed_byte_r6_r7	# add the two low order digits # the following set of instructions computes the number of bytes in the two # strings and, if necessary, performs a switch so that r0 and r1 always # describe the shorter of the two strings.	extzv	$1,$4,r0,r0		# convert digit count to byte count	extzv	$1,$4,r2,r2		# do it for both strings	cmpl	r0,r2			# we want to compare the byte counts	blequ	2f			# skip the swap if we're already correct	movq	r0,r6			# save the longer	movq	r2,r0			# store the shorter on r0 and r1	movq	r6,r2			# ... and store the longer in r2 and r32:	subl2	r0,r2			# make r2 a difference (r2 gequ 0) # r0 now contains the number of bytes remaining in the shorter string. # r2 contains the difference in bytes between the two input strings.	tstl	r0			# does shorter string have any room?	beql	4f			# skip loop if no room at all3:	bsbw	add_packed_byte_string	# add the next two bytes together	sobgtr	r0,3b			# check for end of loop4:	tstl	r2			# does longer string have any room?	beql	7f			# skip next loops if all done5:	blbc	r8,6f			# life is simple if carry clear	clrl	r6			# otherwise, carry must propogate #	mark_point	add_sub_24_d	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_d - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_d:	movzbl	-(r3),r7		# so add carry to single string	bsbw	add_packed_byte_r6_r7	# use the special entry point	sobgtr	r2,5b			# check for this string exhausted	brb	7f			# join common completion code #	mark_point	add_sub_24_e	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_e - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_e:6:	movb	-(r3),-(r5)		# simply move src to dst if no carry	sobgtr	r2,6b			# ... until we're all done7:	movb	r8,-(r5)		# store the final carry #+ # at this point, the result has been computed. that result must be moved to # its ultimate destination, noting whether any nonzero digits are stored # so that the z-bit will have its correct setting.  # # input parameters: # #	r9<7:0>  - sign of result in preferred form #	r11<3:0> - saved condition codes #	r11<31>  - indicates whether to set saved r4 to zero # #	(sp)    - saved r5, high address end of destination string #-add_subtract_exit:	addl3	$1,(sp),r5		# point r5 beyond real destination 	movab	24(sp),r1		# r1 locates the saved result	bsbw	store_result		# store the result and record the z-bit	bbs	$psl$v_z,r11,0f		# step out of line for minus zero check #	mark_point	add_sub_24_f	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_f - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_f:8:	insv	r9,$0,$4,*(sp)+		# the sign can finally be stored	addl2	$20,sp			# get rid of intermediate buffer	bbc	$add_sub_v_zero_r4,r11,9f	# branch if 4-operand opcode	clrl	16(sp)			# clear saved r4 to return zero9:	jmp	vax$decimal_exit	# exit through common code path # if the result is negative zero, then the n-bit is cleared and the sign # is changed to a plus sign.0:	bicb2	$psl$m_n,r11		# clear the n-bit unconditionally	bbs	$psl$v_v,r11,8b		# do not change the sign on overflow	movb	$12,r9			# make sure that the sign is plus	brb	8b			# ... and rejoin the exit code # #+ # functional description: # #	this routine adds together two bytes containing decimal digits and  #	produces a byte containing the sum that is stored in the output  #	string. each of the input bytes is converted to a binary number #	(with a table-driven conversion), the two numbers are added, and #	the sum is converted back to two decimal digits stored in a byte. # #	this routine makes no provisions for bytes that contain illegal #	decimal digits. we are using the unpredictable statement in the #	architectural description of the decimal instructions to its fullest. # #	the bytes that contain a pair of packed decimal digits can either #	exist in packed decimal strings located by r1 and r3 or they can #	be stored directly in registers. in the former case, the digits must #	be extracted from registers before they can be used in later operations #	because the sum will be used as an index register. # # for entry at add_packed_byte_string: # #	input parameters: # #		r1  - address one byte beyond first byte that is to be added #		r3  - address one byte beyond second byte that is to be added #		r5  - address one byte beyond location to store sum # #		r8  - carry from previous byte (r8 is either 0 or 1) # #	implicit input: # #		r6 - scratch #		r7 - scratch # #	output parameters: # #		r1 - decreased by one to point to current byte in first input string #		r3 - decreased by one to point to current byte in second input string #		r5 - decreased by one to point to current byte in output string # #		r8 - either 0 or 1, reflecting whether this most recent add resulted #		     in a carry to the next byte. # # for entry at add_packed_byte_r6_r7: # #	input parameters: # #		r6  - first byte containing decimal digit pair #		r7  - second byte containing decimal digit pair # #		r5  - address one byte beyond location to store sum # #		r8  - carry from previous byte (r8 is either 0 or 1) # #	output parameters: # #		r5 - decreased by one to point to current byte in output string # #		r8 - either 0 or 1, reflecting whether this most recent add resulted #		     in a carry to the next byte. # # side effects:

⌨️ 快捷键说明

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