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

📄 vaxarith.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
 # #	r6 and r7 are modified by this routine # #	r0, r2, r4, and r9 (and, of course, r10 and r11) are preserved  #	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 subtract 100 at most once to put all  #	    possible sums in the range 0..99. that is, # #		99 + 99 + 1 = 199 lss 200 # #	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. #-add_packed_byte_string: #	mark_point	add_sub_bsbw_24	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24 - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24:	movzbl	-(r1),r6		# get byte from first string #	mark_point	add_sub_bsbw_24_a	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_bsbw_24_a - module_base	 .text	3	 .word	add_sub_bsbw_24 - module_base	 .textLadd_sub_bsbw_24_a:	movzbl	-(r3),r7		# get byte from second string	.globl	vax$add_packed_byte_r6_r7vax$add_packed_byte_r6_r7:		# ashp also uses this routineadd_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	addb2	r6,r7			# form their sum	addb2	r8,r7			# add carry from last step	clrb	r8			# assume no carry this time	cmpb	r7,$99			# check for carry	blequ	1f			# branch if within bounds	movb	$1,r8			# propogate carry to next step	subb2	$100,r7			# put r7 into interval 0..991:	movb	decimal$binary_to_packed_table[r7],-(r5)					# store converted sum byte	rsb # #+ # functional description: # #	this routine takes two packed decimal strings whose descriptors #	are passed as input parameters, subtracts one string from the #	other, 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 difference 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 subtraction in all cases, even if the original #	entry was at addp4 or addp6.  # # 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. # # algorithm for choice of sign: # #	the choice of sign for the output string is not nearly so  #	straightforward as it is in the case of addition. one approach that is  #	often taken is to make a reasonable guess at the sign of the result.  #	if the final subtraction causes a borrow, then the choice was incorrect.  #	the sign must be changed and the result must be replaced by its tens  #	complement. # #	this routine does not guess. instead, it chooses the input string of  #	the larger absolute magnitude as the minuend for this internal  #	routine and chooses its sign as the sign of the result. #	this algorithm is actually more efficient than the reasonable  #	guess method and is probably better than a guess method that is never  #	wrong. all complete bytes that are processed in the sign evaluation  #	preprocessing loop are eliminated from consideration in the  #	subtraction loop, which has a higher cost per byte. # #	the actual algorithm is as follows. (note that both input strings have  #	already had leading zeros stripped so their lengths reflect  #	significant digits.) # #	1.  if the two strings have unequal lengths, then choose the sign of  #	    the string that has the longer length. # #	2.  for strings of equal length, choose the sign of the string whose  #	    most significant byte is larger in magnitude. # #	3.  if the most significant bytes test equal, then decrease the  #	    lengths of each string by one byte, drop the previous most  #	    significant bytes, and go back to step 2. # #	4.  if the two strings test equal, it is not necessary to do any  #	    subtraction. the result is identically zero. # #	note that the key to this routine's efficiency is that high order  #	bytes that test equal in this loop are dropped from consideration in  #	the more complicated subtraction loop. #-subtract_packed:	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	blssu	4f			# r0/r1 represent the smaller string	bgtru	3f			# r2/r3 represent the smaller string # the two input strings have an equal number of bytes. compare magnitudes to # determine which string is really larger. if the two strings test equal, then # skip the entire subtraction loop.	subl3	r0,r1,r8		# point r8 to low address end of r0/r1	subl3	r2,r3,r9		# point r9 to low address end of r2/r3	tstl	r0			# see if both strings have zero bytes	beql	2f			# still need to check low order digit #	mark_point	add_sub_24_g	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_g - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_g:1:	cmpb	(r8)+,(r9)+		# compare most significant bytes	blssu	4f			# r0/r1 represent the smaller string	bgtru	3f			# r2/r3 represent the smaller string	decl	r2			# keep r2 in step with r0		sobgtr	r0,1b			# ... which gets decremented here # at this point, we have reduced both input strings to single bytes that # contain a sign "digit" and may contain a digit in the high order nibble # if the original digit counts were nonzero. #	mark_point	add_sub_24_h	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_h - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_h:2:	bicb3	$0x0f,(r8),r8		# look only at digit, ignoring sign #	mark_point	add_sub_24_i	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_i - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_i:	bicb3	$0x0f,(r9),r9		# get the digit from the other string	cmpb	r8,r9			# compare these digits	blssu	4f			# r0/r1 represent the smaller string	bgtru	3f			# r2/r3 represent the smaller string # the two strings have identical magnitudes. enter the end processing code # with the intermediate result unchanged (that is, zero).	brw	add_subtract_exit	# join the common completion code # the string described by r0 and r1 has the larger magnitude. choose its sign. # then swap the two string descriptors so that the main subtraction loops # always have r2 and r3 describing the larger string. note that the use of # r6 and r7 as scratch leaves r7<31:8> in an unpredictable state. 3:	movb	r6,r9			# load preferred sign into r9	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 r3	clrl	r7			# insure that r7<31:8> is zero	brb	5f			# continue along common code path # the string described by r2 and r3 has the larger magnitude. choose its sign.4:	movb	r7,r9			# load preferred sign into r95:	subl2	r0,r2			# make r2 a difference (r2 gequ 0)	blbc	r9,6f			# check if sign is negative	bisb2	$psl$m_n,r11		# ... so the saved n-bit can be set #	mark_point	add_sub_24_j	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_j - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_j:6:	bicb3	$0x0f,(r1),r6		# get least significant digit to r6 #	mark_point	add_sub_24_k	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_k - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_k:	bicb3	$0x0f,(r3),r7		# get least significant digit to r7	clrl	r8			# start subtracting with borrow off	bsbw	sub_packed_byte_r6_r7	# subtract the two low order digits # r0 contains the number of bytes remaining in the smaller string # r2 contains the difference in bytes between the two input strings	tstl	r0			# does smaller string have any room?	beql	8f			# skip loop if no room at all7:	bsbw	sub_packed_byte_string	# subtract the next two bytes 	sobgtr	r0,7b			# check for end of loop8:	tstl	r2			# does one of the strings have more?	beql	L110			# skip next loops if all done9:	blbc	r8,0f			# life is simple if borrow clear	clrl	r6			# otherwise, borrow must propogate #	mark_point	add_sub_24_l	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_l - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_l:	movzbl	-(r3),r7		# so subtract borrow from single string	bsbw	sub_packed_byte_r6_r7	# use the special entry point	sobgtr	r2,9b			# check for this string exhausted	brb	L110			# join common completion code #	mark_point	add_sub_24_m	 .text	2	 .set	table_size,table_size + 1	 .word	Ladd_sub_24_m - module_base	 .text	3	 .word	add_sub_24 - module_base	 .textLadd_sub_24_m:0:	movb	-(r3),-(r5)		# simply move src to dst if no borrow	sobgtr	r2,0b			# ... until we're all doneL110: ### ********** begin temp **********  ### ### The following halt instruction should be replaced with the correct ### abort code. ### ### The halt is similar to the  ### ###	microcode cannot get here ### ### errors that other implementations use. ###	tstl	r8			# if borrow is set here, we blew it	beql	1f			# branch out if ok	halt				# this will cause an opcdec exception1: ### ### *********** end temp ***********	brw	add_subtract_exit	# join common completion code # #+ # functional description: # #	this routine takes as input two bytes containing decimal digits and #	produces a byte containing their difference. this result is stored in #	the output string. each of the input bytes is converted to a binary #	number (with a table-driven conversion), the first number is #	subtracted from the second, and the difference 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 difference will be used as an index register. # # for entry at sub_packed_byte_string: # #	input parameters: # #		r1  - address one byte beyond byte containing subtrahend #		r3  - address one byte beyond byte containing minuend #		r5  - address one byte beyond location to store difference # #		r8  - borrow 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 subtrahend string #		r3 - decreased by one to point to current byte  #		     in minuend string #		r5 - decreased by one to point to current byte  #		     in difference string # #		r8 - either 0 or 1, reflecting whether this most recent  #		     subtraction resulted in a borrow from the next byte. # # for entry at sub_packed_byte_r6_r7: # #	input parameters: # #		r6<7:0>  - byte containing decimal digit pair for subtrahend  #		r6<31:8> - mbz #		r7<7:0>  - byte containing decimal digit pair for minuend  #		r7<31:8> - mbz # #		r5 - address one byte beyond location to store difference  # #		r8 - borrow from subtraction of previous byte  #		     (r8 is either 0 or 1) # #	output parameters: # #		r5 - decreased by one to point to current byte  #		     in difference string # #		r8 - either 0 or 1, reflecting whether this most recent  #		     subtraction resulted in a borrow from the next byte. # # side effects: # #	r6 and r7 are modified by this routine # #	r0, r2, r4, and r9 (and, of course, r10 and r11) are preserved 

⌨️ 快捷键说明

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