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

📄 vaxdeciml.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
 *  invariance arises from the fact that a packed decimal byte containing two *  zero digits converts to a byte containing zero. */	clrl	r6			# otherwise, carry must propogate	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	jbr	7f			# join common completion code6:	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     - saved condition codes # #	(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,9f		# step out of line for minus zero check8:	insv	r9,$0,$4,*(sp)+		# the sign can finally be stored	addl2	$20,sp			# get rid of intermediate buffer	jbr	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.9:	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	jbr	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: # #	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:	movzbl	-(r1),r6		# get byte from first string	movzbl	-(r3),r7		# get byte from second stringadd_packed_byte_r6_r7:	movb	packed_to_binary_table[r6],r6	# convert digits to binary	movb	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	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/* at the cost of one more instruction *	bbc	$psl$v_z,r11,20$ * we can make this loop go faster in the usual case of nonzero result */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:	jlbc	r4,5f			# was original r4 odd? branch if yes	bicb3	0xf0,-(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	4:	bitb	$0xf0,(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.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 source string specified by the  source  length  and  source  address #     operands is scaled by a power of 10 specified by the count operand.  the #     destination string specified by the destination length  and  destination #     address operands is replaced by the result. # #	a positive count  operand  effectively  multiplies#   a  negative  count #	effectively  divides#  and a zero count just moves and affects condition #	codes.  when a negative count is specified, the result is rounded  using #	the round operand. # # input parameters: # #	r0<15:0>  = srclen.rw	number of digits in source character string #	r0<23:16> = cnt.rb	shift count #	r1        = srcaddr.ab	address of input character string #	r2<15:0>  = dstlen.rw	length in digits of output decimal string #	r2<23:16> = round.rb	round operand used with negative shift count  #	r3        = dstaddr.ab 	address of destination packed decimal string # # output parameters: # #	r0 = 0 #	r1 = address of byte containing most significant digit of #	     the source string #	r2 = 0 #	r3 = address of byte containing most significant digit of #	     the destination string # # condition codes: # #	n <- destination string lss 0 #	z <- destination string eql 0 #	v <- decimal overflow #	c <- 0 # # algorithm: # #	the routine tries as much as possible to work with entire bytes. this  #	makes the case of an odd shift count more difficult that of an even  #	shift count. the first part of the routine reduces the case of an odd  #	shift count to an equivalent operation with an even shift count. # #	the instruction proceeds in several stages. in the first stage, after  #	the input parameters have been verified and stored, the operation is  #	broken up into four cases, based on the sign and parity (odd or even)  #	of the shift count. these four cases are treated as follows, in order  #	of increasing complexity. # #	case 1. shift count is negative and even # #	    the actual shift operation can work with the source string in #	    place. there is no need to move the source string to an #	    intermediate work area.  # #	case 2. shift count is positive and even # #	    the source string is moved to an intermediate work area and the #	    sign "digit" is cleared before the actual shift operation takes #	    place. if the source is worked on in place, then a spurious sign #	    digit is moved to the middle of the output string instead of a #	    zero. the alternative is to keep track of where, in the several #	    special cases of shifting, the sign digit is looked at. we #	    believe that the overhead of the work area is worth the relative #	    simplicity of the later stages of this instruction.  # #	cases 3 and 4. shift count is odd # #	    the case of an odd shift count is considerably more difficult #	    than an even shift count, which is only slightly more complicated #	    than movp. in the case of an even shift count, various digits #	    remain in the same place (high nibble or low nibble) in a byte. #	    for odd shift counts, high nibbles become low nibbles and vice #	    versa. in addition, digits that were adjacent when viewing the #	    decimal string as a string of bits proceeding from low address to #	    high are now separated by a full byte.  # #	    we proceed in two steps. the source string is first moved to a #	    work area. the string is then shifted by one. this shift reduces #	    the operation to one of the two even shift counts already #	    mentioned, where the source to the shift operation is the #	    modified source string residing in the work area. the details of #	    the shift-by-one are described below near the code that performs #	    the actual shift.  #-# define ashp_shift_mask  0xf0f0f0f0						# mask used to shift string by onevax$ashp:	pushr	$0xfff			# save registers 0-11	movpsl	r11			# get initial psl	insv	$psl$m_z,$0,$4,r11	# set z-bit, clear the rest	movab	decimal_pack,r10	# store address of handler	movl	sp,r8			# remember current top of stack	subl2	$20,sp			# allocate work area on stack/*	 *	No need to check bound because we will before calling these *	routines *	roprand_check	r2		# insure that r2 lequ 31 *	roprand_check	r0		# insure that r0 lequ 31 */	bsbw	strip_zeros_r0_r1	# eliminate any high order zeros	extzv	$1,$4,r2,r2		# convert output digit count to bytes	incl	r2			# make room for sign as well

⌨️ 快捷键说明

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