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

📄 vaxarith.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
Lmulp_at_sp:	movzbl	-(r9),r1		# next digit pair to r1	movzbl	decimal$packed_to_binary_table[r1],r6					# convert digits to binary	beql	6f			# skip the work if zero	movq	(sp),r4			# input array descriptor to r4/r5	bsbw	extend_string_multiply	# do the work6:	sobgtr	r8,5b			# any more multiplier digits?	addl2	$8,sp			# discard saved long string descriptor7:	movl	(sp),sp			# remove input array from stack # at this point, the product string is located in a 32-longword array on # the top of the stack. each longword corresponds to a pair of digits in # the output string. as digits are removed from the stack, they are checked # for nonzero to obtain the correct setting of the z-bit. after the output # string has been filled, the remainder of the product string is removed from # the stack. if a nonzero result is detected at this stage, the v-bit is set.	movl	$32,r9			# set up array counter #	movq	< <32*4> + -		# skip over 32-longword array #		  <2*4>  + -		#  and saved string descriptor #		  <4*4> >(sp),r4	#  to retrieve original r4 and r5	 movq	( (32*4) + (2*4) + (4*4) )(sp),r4 # #+ # the code for vax$mulp and vax$divp merges at this point. the result is stored # in an array of longwords at the top of the stack. the size of this array is # stored in r9. the original r4 and r5 heve been retrieved from the stack.  # # input parameters: # #	r4 - contains byte count of destination string in r4 <1:4> #	r5 - address of most significant digit of destination string #	r9 - count of longwords in result array on stack # #	contents of result array # # implicit input: # #	signs of two input factors (multiplier and multiplicand or #		divisor and dividend) #-multiply_divide_exit:	movpsl	r11			# get current psl	insv	$psl$m_z,$0,$4,r11	# clear all codes except z-bit #	establish_handler	-	# store address of access #		arith_accvio		#  violation handler again	 movab	arith_accvio,r10	extzv	$1,$4,r4,r3		# excess byte count to r3	beql	L125			# skip to single digit code	addl3	r3,r5,r7		# remember address of sign byte	addl3	$1,r7,r5		# point r5 beyond end of product string8:	movl	(sp)+,r1		# remove next value from stack	beql	9f			# do not clear z-bit if zero	bicb2	$psl$m_z,r11		# clear z-bit #	mark_point	mulp_divp_r9	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_r9 - module_base	 .text	3	 .word	mulp_divp_r9 - module_base	 .textLmulp_divp_r9:9:	movb	decimal$binary_to_packed_table[r1],-(r5)					# store converted sum byte	decl	r9			# one less element on the stack	bleq	L116			# exit loop if result array exhausted	sobgtr	r3,8b			# keep going?L200:	blbc	r4,L220			# different for even digit count # the output string consists of an odd number of digits. a complete digit # pair can be stored in the most significant (lowest addressed) byte of # the product string.	movl	(sp)+,r1		# remove next value from stack	beql	L210			# do not clear z-bit if zero	bicb2	$psl$m_z,r11		# clear z-bit #	mark_point	mulp_divp_r9_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_r9_a - module_base	 .text	3	 .word	mulp_divp_r9 - module_base	 .textLmulp_divp_r9_a:L210:	movb	decimal$binary_to_packed_table[r1],-(r5)					# store converted sum byte	decl	r9			# one less element on the stack	bleq	L116			# exit loop if result array exhausted	brb	L140			# perform overflow check # this loop executes if the result array has fewer elements than the output # string. the remaining bytes in the output string are filled with zeros. # there is no need for an overflow check. #	mark_point	mulp_divp_8	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_8 - module_base	 .text	3	 .word	mulp_divp_8 - module_base	 .textLmulp_divp_8:L114:	clrb	-(r5)			# store another zero byteL116:	sobgeq	r3,L114			# any more room in output string	brb	L150			# determine sign of result # this code path is used in the case where the output digit count is 0 or 1. # r5 must be advanced L125:	movl	r5,r7			# remember address of output sign byte	incl	r5			# advance r5 so common code can be used	brb	L200			# join common code path # the output string consists of an even number of digits. only the low order  # nibble is stored in the most significant (lowest addresses) byte. a zero is  # stored in the high order nibble. if the high order digit would have been  # nonzero, the v-bit is set and the overflow check is bypassed because there  # are faster ways to clean the stack if we do not have to check for nonzero  # at the same time.L220:	movl	(sp)+,r1		# remove next value from stack	movb	decimal$binary_to_packed_table[r1],r1					# obtain converted sum byte #	mark_point	mulp_divp_r9_c	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_r9_c - module_base	 .text	3	 .word	mulp_divp_r9 - module_base	 .textLmulp_divp_r9_c:	bicb3	$0x0f0,r1,-(r5)		# store byte, clearing high order nibble	beql	L130			# do not clear z-bit if zero	bicb2	$psl$m_z,r11		# clear z-bitL130:	bitb	$0x0f0,r1		# is high order nibble nonzero?	bneq	L133			# yes, go set overflow bit	decl	r9			# one less element on the stack	bleq	L116			# exit loop if result array exhausted	brb	L140			# check rest of result array for nonzero # if we detect overflow, we need to adjust r9 to reflect the nonzero longword # removed from the stack before we enter the next code block that sets the # v-bit and cleans off the stack based on the contents of r9. L133:	decl	r9			# one more longword removed from stack # a nonzero digit has been discovered in a position that cannot be stored in  # the output string. set the v-bit, remove the rest of the product array from # the stack, and join the exit processing in the code that determines the sign # of the product.L135:	bisb2	$psl$m_v,r11		# set the overflow bit 	moval	(sp)[r9],sp		# clean off remaining product string	brb	L150			# go to code that determines the sign # the remainder of the product array must be removed from the stack. a nonzero # result causes the v-bit to be set and the rest of the loop to be skipped. # note that there is always a nonzero loop count remaining at this point.L140:	tstl	(sp)+			# is next longword zero?	bneq	L133			# no, leave loop	sobgtr	r9,L140 # the final product string has been stored and the v- and z-bits have their # correct settings. the sign of the product must be determined from the # signs of the two input strings. opposite signs produce a negative product. # same signs (in any representation) produce a plus sign in the output string.L150:	addl2	$8,sp			# discard saved string descriptor	movl	$12,r6			# assume final result is positive	movq	(sp),r0			# retrieve original r0/r1 pair	extzv	$1,$4,r0,r0		# get byte count for first input string	addl2	r0,r1			# point r1 to byte containing sign #	mark_point	mulp_divp_0	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_0 - module_base	 .text	3	 .word	mulp_divp_0 - module_base	 .textLmulp_divp_0:	bicb3	$0x0f0,(r1),r0		# r0 contains the sign "digit"        caseb   r0,$10,$15-10		# dispatch on sign digitL5:        .word   2f-L5                  # 10 => sign is "+"        .word   1f-L5                  # 11 => sign is "-"        .word   2f-L5                 # 12 => sign is "+"        .word   1f-L5                  # 13 => sign is "-"        .word   2f-L5                  # 14 => sign is "+"        .word   2f-L5                  # 15 => sign is "+"1:	movl	$1,r4			# count a minus sign	brb	L230			# now check second input sign2:	clrl	r4			# no real minus signs so farL230:	movq	8(sp),r2		# retrieve original r2/r3 pair	extzv	$1,$4,r2,r2		# get byte count for second input string	addl2	r2,r3			# point r3 to byte containing sign #	mark_point	mulp_divp_0_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_0_a - module_base	 .text	3	 .word	mulp_divp_0 - module_base	 .textLmulp_divp_0_a:	bicb3	$0x0f0,(r3),r2		# r2 contains the sign "digit"        caseb   r2,$10,$15-10           # dispatch on sign digitL6:        .word   5f-L6                  # 10 => sign is "+"        .word   4f-L6                  # 11 => sign is "-"        .word   5f-L6                  # 12 => sign is "+"        .word   4f-L6                  # 13 => sign is "-"        .word   5f-L6                  # 14 => sign is "+"        .word   5f-L6                  # 15 => sign is "+"4:	incl	r4			# remember that sign was minus5:	blbc	r4,L260			# even parity indicates positive result	bbs	$psl$v_z,r11,L270	# step out of line for minus zero check	bisb2	$psl$m_n,r11		# set n-bit in saved pswL255:	incl	r6			# change sign to minus #	mark_point	mulp_divp_0_b	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_divp_0_b - module_base	 .text	3	 .word	mulp_divp_0 - module_base	 .textLmulp_divp_0_b:L260:	insv	r6,$0,$4,(r7)		# store sign in result string	clrl	16(sp)			# set saved r4 to zero	jmp	vax$decimal_exit	# join common exit code # if the result is negative zero, then it must be changed to positive zero # unless overflow has occurred, in which case, the sign is left as negative # but the n-bit is clear.L270:	bbs	$psl$v_v,r11,L255	# make sign negative if overflow	brb	L260			# sign will be positive # #+ # functional description: # #	this routine multiplies an array of numbers (each array element lequ  #	99) by a number (also lequ 99). the resulting product array is added  #	to another array, each of whose elements is also lequ 99. # # input parameters: # #	r3 - pointer to output array #	r4 - input array size #	r5 - input array address #	r6 - multiplier  # # output parameters: # #	none # # implicit output: # #	the output array is altered. # #	an intermediate product array is produced by multiplying each input #	array element by the multiplier. each product array element is then #	added to the corresponding output array element.  # # side effects: # #	r3, r4, and r5 are modified by this routine. # #	r6 is preserved. # #	r0, r1, and r2 are used as scratch registers. r0 and r1 contain the #	quadword result of emul that is then passed into ediv. # # assumptions: # #	this routine assumes that all array elements lie in the range from 0  #	to 99 inclusive. (this is true if all input strings contain only legal  #	decimal digits.) the arithmetic performed by this routine will  #	maintain this assumption. that is,  # #		             input array element    lequ 99 #		times                 multiplier    lequ 99 #		        ------------------------ #		                         product              lequ 99*99 #		plus                       carry    lequ 99 #		        ------------------------ #		                modified product              lequ 99*100 #		plus    old output array element    lequ 99 #		        ------------------------ #		        new output array element              lequ 99*101 = 9999 # #	a number lequ 9999, when divided by 100, is guaranteed to produce both  #	a quotient and a remainder lequ 99. #-extend_string_multiply:	clrl	r2			# initial carry is zero1:	emul	r6,(r5)+,r2,r0		# form modified product (r0 lequ 9900)	addl2	(r3),r0			# add old output array element	ediv	$100,r0,r2,(r3)+	# remainder to output array					# quotient becomes carry	sobgtr	r4,1b			# keep going? # this remaining code looks more complicated than it actually is. in the  # usual case, the routine exits immediately. in the event that a carry  # occurs, one additional entry in the output array will be modified. only in  # the rare case of an output array consisting of a string of 99s will any  # significant looping occur.	addl2	r2,(r3)			# add final carry2:	cmpl	(r3),$100		# do we overflow into next digit pair?	bgequ	3f			# branch if carry	rsb				# otherwise, all done3:	subl2	$100,(r3)+		# readjust entry and advance pointer	incl	(r3)			# propogate carry	brb	2b			# ... and test this entry for overflow # #+ # functional description: # #	the dividend string  specified  by  the  dividend  length  and  dividend #	address  operands  is  divided  by  the  divisor string specified by the #	divisor length  and  divisor  address  operands.   the  quotient  string #	specified  by  the  quotient  length  and  quotient  address operands is #	replaced by the result. # # input parameters: # #	r0 - divrlen.rw		number of digits in divisor string #	r1 - divraddr.ab	address of divisor string #	r2 - divdlen.rw		number of digits in dividend string #	r3 - divdaddr.ab	address of dividend string #	r4 - quolen.rw		number of digits in quotient string #	r5 - quoaddr.ab		address of quotient string # # output parameters: # #	r0 = 0 #	r1 = address of the byte containing the most significant digit of #	     the divisor string #	r2 = 0 #	r3 = address of the byte containing the most significant digit of #	     the dividend string #	r4 = 0 #	r5 = address of the byte containing the most significant digit of #	     the string containing the quotient # # condition codes: # #	n <- quotient string lss 0 #	z <- quotient string eql 0 #	v <- decimal overflow #	c <- 0 # # register usage: # #	this routine uses all of the general registers. the condition codes #	are computed at the end of the instruction as the final result is #	stored in the quotient string. r11 is used to record the condit

⌨️ 快捷键说明

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