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

📄 vaxarith.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
 #	by this routine # # assumptions: # #	this routine makes two important assumptions. # #	1.  if both of the input bytes contain only legal decimal digits, then #	    it is only necessary to add 100 at most once to put all  #	    possible differences in the range 0..99. that is, # #		0 - 99 - 1 = -100 # #	2.  the result will be checked in some way to determine whether the #	    result is nonzero so that the z-bit can have its correct setting. #-sub_packed_byte_string: #	mark_point	add_sub_bsbw_24_b	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_b - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_b:	movzbl	-(r1),r6		# get byte from first string #	mark_point	add_sub_bsbw_24_c	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_c - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_c:	movzbl	-(r3),r7		# get byte from second stringsub_packed_byte_r6_r7:	movb	decimal$packed_to_binary_table[r6],r6					# convert digits to binary	movb	decimal$packed_to_binary_table[r7],r7					# convert digits to binary	subb2	r6,r7			# form their difference	subb2	r8,r7			# include borrow from last step	blss	1f			# branch if need to borrow	clrb	r8			# no borrow next time	brb	2f			# join common exit code1:	addb2	$100,r7			# put r7 into interval 0..99	movb	$1,r8			# propogate borrow to next step2:	movb	decimal$binary_to_packed_table[r7],-(r5)					# store converted sum byte	rsb # #+ # functional description: # #	this routine takes a packed decimal string that typically contains #	the result of an arithmetic operation and stores it in another #	decimal string whose descriptor is specified as an input parameter  #	to the original arithmetic operation. # #	the string is stored from the high address end (least significant #	digits) to the low address end (most significant digits). this order #	allows all of the special cases to be handled in the simplest fashion. # # input parameters: # #	r1      - address one byte beyond high address end of input string #		  (note that this string must be at least 17 bytes long.) # #	r4<4:0> - number of digits in ultimate destination #	r5      - address one byte beyond destination string # #       r11     - contains saved condition codes # # implicit input: # #	the input string must be at least 17 bytes long to contain a potential #	carry out of the highest digit when doing an add of two large numbers.  #	this carry out of the last byte will be detected and reported as a  #	decimal overflow, either as an exception or simply by setting the v-bit. # #	the least significant digit (highest addressed byte) cannot contain a #	sign digit because that would cause the z-bit to be incorrectly cleared. # # output parameters: # #	r11<psl$v_z> - cleared if a nonzero digit is stored in output string #	r11<psl$v_v> - set if a nonzero digit is detected after the output #		       string is exhausted # #	a portion of the result (dictated by the size of r4 on input) is #	moved to the destination string. #-store_result:	incl	r4			# want number of "complete" bytes in	ashl	$-1,r4,r0		#  output string	beql	3f			# skip first loop if none #	mark_point	add_sub_bsbw_24_d	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_d - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_d:1:	movb	-(r1),-(r5)		# move the next complete byte	beql	2f			# check whether to clear z-bit	bicb2	$psl$m_z,r11		# clear z-bit if nonzero2:	sobgtr	r0,1b			# keep going?3:	blbc	r4,5f			# was original r4 odd? branch if yes #	mark_point	add_sub_bsbw_24_f	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_f - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_f:	bicb3	$0x0f0,-(r1),-(r5)	# if r4 was even, store half a byte	beql	4f			# need to check for zero here, too	bicb2	$psl$m_z,r11		# clear z-bit if nonzero	 #	mark_point	add_sub_bsbw_24_g	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_g - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_g:4:	bitb	$0x0f0,(r1)		# if high order nibble is nonzero,	bneq	7f			# ... then overflow has occurred # the entire destination has been stored. we must now check whether any of # the remaining input string is nonzero and set the v-bit if nonzero is # detected. note that at least one byte of the output string has been examined # in all cases already. this makes the next byte count calculation correct.5:	decl	r4			# restore r4 to its original self	extzv	$1,$4,r4,r0		# extract a byte count	subb3	r0,$16,r0		# loop count is 16 minus byte count # note that the loop count can never be zero because we are testing a 17-byte # string and the largest output string can be 16 bytes long. #	mark_point	add_sub_bsbw_24_h	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_h - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_h:6:	tstb	-(r1)			# check next byte for nonzero	bneq	7f			# nonzero means overflow has occurred	sobgtr	r0,6b			# check for end of this loop	rsb				# this is return path for no overflow7:	bisb2	$psl$m_v,r11		# indicate that overflow has occurred	rsb				# ... and return to the caller # #+ # functional description: # #	the  multiplicand  string  specified  by  the  multiplicand  length  and #	multiplicand  address  operands  is  multiplied by the multiplier string #	specified by the multiplier length and multiplier address operands.  the #	product  string  specified  by  the  product  length and product address #	operands is replaced by the result. # # input parameters: # #	r0 - mulrlen.rw		number of digits in multiplier string #	r1 - mulraddr.ab	address of multiplier string #	r2 - muldlen.rw		number of digits in multiplicand string #	r3 - muldaddr.ab	address of multiplicand string #	r4 - prodlen.rw		number of digits in product string #	r5 - prodaddr.ab	address of product string # # output parameters: # #	r0 = 0 #	r1 = address of the byte containing the most significant digit of #	     the multiplier string #	r2 = 0 #	r3 = address of the byte containing the most significant digit of #	     the multiplicand string #	r4 = 0 #	r5 = address of the byte containing the most significant digit of #	     the string containing the product # # condition codes: # #	n <- product string lss 0 #	z <- product 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 product string. r11 is used to record the condition #	codes. # # notes: # #    1.	this routine uses a large amount of stack space to allow storage of #	intermediate results in a convenient form. specifically, each digit #	pair of the longer input string is stored in binary in a longword on #	the stack. in addition, 32 longwords are set aside to hold the product #	intermediate result. each longword contains a binary number between 0 #	and 99.  # #	after the multiplication is complete. each longword is removed from #	the stack, converted to a packed decimal pair, and stored in the #	output string. any nonzero cells remaining on the stack after the #	output string has been completely filled are the indication of decimal #	overflow.  # #	the purpose of this method of storage is to avoid decimal/binary or #	even byte/longword conversions during the calculation of intermediate #	results.  # #    2.	trailing zeros are removed from the larger string. all zeros in #	the shorter string are eliminated in the sense that no arithmetic #	is performed. the output array pointer is simply advanced to point #	to the next higher array element. #-		.globl	vax$mulpvax$mulp: #	pushr	$^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>	# save the lot	 pushr	$0x0fff #	establish_handler	-	# store address of access #		arith_accvio		#  violation handler	 movab	arith_accvio,r10 #	roprand_check	r4			# insure that r4 is lequ 31	 cmpw	r4,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r4,r4 #	roprand_check	r2			# insure that r2 is lequ 31	 cmpw	r2,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r2,r2 #	mark_point	mulp_bsbw_0	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_bsbw_0 - module_base	 .text	3	 .word	mulp_bsbw_0 - module_base	 .textLmulp_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	r0,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r0,r0 #	mark_point	mulp_bsbw_0_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_bsbw_0_a - module_base	 .text	3	 .word	mulp_bsbw_0 - module_base	 .textLmulp_bsbw_0_a:	jsb	decimal$strip_zeros_r0_r1	# strip high order zeros from r0/r1 string	extzv	$1,$4,r0,r0		# convert digit count to byte count	incl	r0			# include least significant digit	extzv	$1,$4,r2,r2		# convert digit count to byte count	incl	r2			# include least significant digit	cmpl	r0,r2			# see which string is larger	bgtru	3f			# r2/r3 describes the longer string	movq	r2,r8			# r8 and r9 describe the longer string	movq	r0,-(sp)		# shorter string descriptor also saved	brb	6f3:	movq	r0,r8			# r8 and r9 describe the longer string	movq	r2,-(sp)		# shorter string descriptor also saved # create space for the output array on the stack (32 longwords of zeros)6:	movl	$8,r0			# eight pairs of quadwords0:	clrq	-(sp)			# clear one pair	clrq	-(sp)			# ... and another	sobgtr	r0,0b			# do all eight pairs	movl	sp,r7			# store beginning of output array in r7 # the longer input array will be stored on the stack as an array of  # longwords. each array element contains a number between 0 and 99,  # representing a pair of digits in the original packed decimal string.  # because the units digit is stored with the sign in packed decimal format,  # it is necessary to shift the number as we store it. this is accomplished by  # multiplying the number by ten. # # the longer array is described by r8 (byte count) and r9 (address of most # significant digit pair).	addl3	r9,r8,r5		# point r5 beyond sign digit	movl	r8,r4			# r4 contains the loop count # an array of longwords is allocated on the stack. r3 starts out pointing # at the longword beyond the top of the stack. the first remainder, guaranteed # to be zero, is "stored" here. the rest of the digit pairs are stored safely # below the top of the stack.	mnegl	r8,r3			# stack grows toward lower addresses	moval	(sp)[r3],sp		# allocate the space	subl3	$4,sp,r3		# point r3 at next lower longword #	mark_point	mulp_r8	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_r8 - module_base	 .text	3	 .word	mulp_r8 - module_base	 .textLmulp_r8:2:	movzbl	-(r5),r1		# get next digit pair	movzbl	decimal$packed_to_binary_table[r1],r1					# convert digits to binary	emul	$10,r1,r2,r0		# multiply by 10	ediv	$100,r0,r2,(r3)+	# divide by 100	sobgtr	r4,2b		movl	r2,(r3)			# store final quotient	movl	sp,r9			# remember array address in r9	pushal	(sp)[r8]		# store start of fixed size area # check for trailing zeros in the input array stored on the stack. if any are  # present, they are removed and the product array is adjusted accordingly.3:	tstl	(r9)+			# is next number zero?	bneq	4f			# leave loop if nonzero	addl2	$4,r7			# advance output pointer to next element	sobgtr	r8,3b			# keep going # if we drop through the loop, then the entire input array is zero. there is # no need to perform any arithmetic because the product will be zero (and the # output array on the stack starts out as zero). the only remaining work is # to store the result in the output string and set the condition codes.	brb	7f			# exit to end processing # now multiply the input array by each successive digit pair. in order to # allow r10 to continue to locate arith_accvio while we execute this loop, it # is necessary to perform a small amount of register juggling. in essence, # r8 and r9 switch the identity of the string that they describe.4:	subl2	$4,r9			# readjust input array pointer	movq	r8,-(sp)		# save r8/r9 descriptor on stack	movl	8(sp),r8		# point r8 at start of 32-longword array	movq	(32*4)(r8),r8		# get descriptor that follows that array	addl2	r8,r9			# point r9 beyond sign byte5:	moval	(r7)+,r3		# output array address to r3  #	mark_point	mulp_at_sp	 .text	2	 .set	table_size,table_size + 1	 .word	Lmulp_at_sp - module_base	 .text	3	 .word	mulp_at_sp - module_base	 .text

⌨️ 快捷键说明

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