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

📄 vaxdeciml.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
	extzv	$1,$4,r0,r0		# same for input string	addl3	r0,r1,r6		# get address of sign digit	incl	r0			# include byte containing sign	bicb3	$0xf0,(r6),r6		# extract sign digit/* * the following can be done with a six-byte table. is the case really * necessary here? what else am i forgetting? */	movzbl	$12,r9			# assume that input sign is plus	caseb	r6,$10,$15-10L3:					# dispatch on sign	.word	4f-L3			# 10 => +	.word	3f-L3			# 11 => -	.word	4f-L3			# 12 => +	.word	3f-L3			# 13 => -	.word	4f-L3			# 14 => +	.word	4f-L3			# 15 => +3:	incl	r9			# change preferred plus to minus	bisb2	$psl$m_n,r11		# set n-bit in saved psw # we now retrieve the shift count from the saved r0 and perform the next set # of steps based on the parity and sign of the shift count. note that the # round operand is ignored unless the shift count is strictly less than zero.4:	cvtbl	ashp_b_cnt(r8),r4	# extract sign-extended shift count	blss	5f			# branch if shift count negative	clrl	r5			# ignore "round" for positive shift	bsbw	ashp_copy_source	# move source string to work area	jlbs	r4,6f			# do shift by one for odd shift count	bicb2	$0x0f,-(r8)		# drop sign in saved source string	jbr	ashp_shift_positive	# go do the actual shift # the "round" operand is important for negative shifts. if the shift count # is even, the source can be shifted directly into the destination. for odd # shift counts, the source must be moved into the work area on the stack and # shifted by one before the rest of the shift operation takes place.5:	extzv	$ashp_v_round,$ashp_s_round,ashp_b_round(r8),r5						# store "round" in a safe place	jlbc	r4,ashp_shift_negative	# get right to it for even shift count	bsbw	ashp_copy_source	# move source string to work area # for odd shift counts, the saved source string is shifted by one in place. # this is equivalent to a shift of -1 so the shift count (r4) is adjusted # accordingly. the least significant digit is moved to the place occupied by # the sign, the tens digit becomes the units digit, and so on. because the # work area was padded with zeros, this shift moves a zero into the high # order digit of a source string of even length. 6:	pushl	r0			# we need a scratch register to count	decl	r0			# want to map {1..16} onto {0..3}	ashl	$-2,r0,r0		# convert a byte count to longwords # the following loop executes from one to four times such that the entire # source, taken as a collection of longwords, is shifted by one. note that  # the two pieces of the source are shifted (rotated) in opposite directions.  # note also that the shift mask is applied to one string before the shift and  # to the other string after the shift. (this points up the arbitrary choice  # of shift mask. we just as well could have chosen the one's complement of  # the shift mask and reversed the order of the shift and mask operations for  # the two pieces of the source string.)7:	rotl	$-4,-(r8),r6		# shift left one digit	bicl2	$ashp_shift_mask,r6	# clear out old low order digits	bicl3	$ashp_shift_mask,-1(r8),r7	# clear out high order digits	rotl	$4,r7,r7		# shift these digits right one digit	bisl3	r6,r7,(r8)		# combine the two sets of digits	sobgeq	r0,7b			# keep going if more	movl	(sp)+,r0		# restore source string byte count	incl	r4			# count the shift we did	blss	ashp_shift_negative	# join common code at the right place					# drop through to ashp_shift_positive #+ # functional description: # #	this routine completes the work of the ashp instruction in the case of #	an even shift count. (if the original shift count was odd, the source #	string has already been shifted by one and the shift count adjusted by #	one.) a portion (from none to all) of the source string is moved to #	the destination string. pieces of the destination string at either end #	may be filled with zeros. if excess digits of the source are not #	moved, they must be tested for nonzero to determine the correct #	setting of the v-bit.  # # input parameters: # #	r0<3:0> - number of bytes in source string  #	r1	- address of source string #	r2<3:0> - number of bytes in destination string  #	r3	- address of destination string #	r4<7:0> - count operand (signed longword of digit count) #	r5<3:0> - round operand in case of negative shift #	r9<3:0> - sign of source string in preferred form # # implicit input: # #	r4 is presumed (guaranteed) even on input to this routine # #	the top of the stack is assumed to contain a 20-byte work area (that  #	may or may not have been used). the space must be allocated for this  #	work area in all cases so that the exit code works correctly for all  #	cases without the need for lots of extra conditional code. # # output parameters: # #	this routine completes the operation of vax$ashp. see the routine #	header for vax$ashp for details on output registers and conditon codes. # # details: # #	put some of the stuff from ashp.txt here. #-ashp_shift_positive:	divl2	$2,r4			# convert digit count to byte count	subl3	r4,r2,r7		# modify the destination count	blss	3f			# branch if simply moving zeros	movl	r4,r6			# number of zeros at low order end1:	subl3	r0,r7,r8		# are there any excess high order digits?	blss	L260			# no, excess is in source. # we only move "srclen" source bytes. the rest of the destination string is # filled with zeros.	movl	r0,r7			# get number of bytes to actually move	jbr	L200			# ... and go move them # the count argument is larger than the destination length. all of the source # is checked for nonzero (overflow check). all of the destination is filled # with zeros.3:	movl	r2,r6			# number of low order zeros	clrl	r7			# the source string is untouched	movl	r0,r8			# number of source bytes to check	jbr	L280			# go do the actual work # if the count is negative, then there is no need to fill in low order zeros # (r6 is zero). the following code is similar to the above cases, differing # in the roles played by source length (r0) and destination length (r2) and # also in the first loop (zero fill or overflow check) that executes.ashp_shift_negative:	clrl	r6			# no zero fill at low end of destination	mnegl	r4,r4			# get absolute value of count	divl2	$2,r4			# convert digit count to byte count	subl3	r4,r0,r7		# get modified source length	blss	L270			# branch if count is larger 	subl3	r7,r2,r8		# are there zeros at high end?	bgeq	L200			# exit to zero fill loop if yes # the modified source length is larger than the destination length. part # of the source is moved. the rest is checked for nonzero.	movl	r2,r7			# only move "dstlen" bytes # in these cases, some digits in the source string will not be moved. if any # of these digits is nonzero, then the v-bit must be set.L260:	mnegl	r8,r8			# number of bytes in source to check	jbr	L280			# exit to overflow check loop # the count argument is larger than the source length. all of the destination  # is filled with zeros. the source is ignored.L270:	clrl	r7			# no source bytes get moved	movl	r2,r8			# all of the destination is filled	jbr	L200			# join the zero fill loop #+ # at this point, the three separate counts have all been calculated. each # loop is executed in turn, stepping through the source and destination # strings, either alone or in step as appropriate. # #	r6 - number of low order digits to fill with zero #	r7 - number of bytes to move intact from source to destination #	r8 - number of excess digits in one or the other string.  # #	if excess source digits, they must be tested for nonzero to #	correctly set the v-bit. # #	if excess destination bytes, they must be filled with zero. #- # test excess source digits for nonzeroL285:	tstb	(r1)+			# is next byte nonzero	bneq	L290			# handle overflow out of lineL280:	sobgeq	r8,L285			# otherwise, keep on looking	jbr	L320			# join top of second loopL290:	bisb2	$psl$m_v,r11		# set saved v-bit	addl2	r8,r1			# skip past rest of excess	jbr	L320			# join top of second loop # in this case, the excess digits are found in the destination string. they # must be filled with zero.L200:	tstl	r8			# is there really something to do?	beql	L320			# skip first loop if nothingL310:	clrb	(r3)+			# store another zero	sobgtr	r8,L310			# ... and keep on looping # the next loop is where something interesting happens, namely that parts of # the source string are moved to the destination string. note that the use of # bytes rather than digits in this operation makes the detection of nonzero  # digits difficult because the presence of a nonzero digit in the place  # occupied by the sign or in the high order nibble of an even output string  # and nowhere else would cause the z-bit to be incorrectly cleared. for this  # reason, we ignore the z-bit here and make a special pass over the output  # string after all of the special cases have been dealt with. the extra  # overhead of a second trip to memory is offset by the simplicity in other  # places in this routine.L320:	tstl	r7			# something to do here?	beql	L340			# skip this loop if nothingL330:	movb	(r1)+,(r3)+		# move the next byte	sobgtr	r7,L330			# ... and keep on looping # the final loop occurs in some cases of positive shift count where the low # order digits of the destination must be filled with zeros.L340:	tstl	r6			# something to do here?	beql	L360			# skip if loop count is zeroL350:	clrb	(r3)+			# store another zero	sobgtr	r6,L350			# ... until we're done #+ # at this point, the destination string is complete except for the sign. # if there is a round operand, that must be added to the destination string. # #	r3 - address one byte beyond destination string #	r5 - round operand #-L360:	addl2	$20,sp			# deallocate work area	extzv	$1,$4,ashp_w_dstlen(sp),r2	# get original destination byte count	movq	r2,-(sp)		# save address and count for z-bit loop	movzbl	r5,r8			# load round into carry register	beql	L380			# skip next mess unless "round" exists	movl	r3,r5			# r5 tracks the addition output	clrl	r6			# we only need one term and carry in sumL370:	movzbl	-(r3),r7		# get next digit	bsbw	add_packed_byte_r6_r7	# perform the addition	tstl	r8			# see if this add produced a carry	beql	L380			# all done if no more carry	sobgeq	r2,L370			# back for the next byte # if we drop through the end of the loop, then the final add produced a carry. # this must be reflected by setting the v-bit in the saved psw.	bisb2	$psl$m_v,r11		# set the saved v-bit # all of the digits are now loaded into the destination string. the condition # codes, except for the z-bit, have their correct settings. the sign must be # set, a check must be made for even digit count in the output string, and # the various special cases (negative zero, decimal overflow trap, ans so on) # must be checked before completing the routine.  # this entire routine worked with entire bytes, ignoring whether digit counts # were odd or even. an illegal digit in the upper nibble of an even input string # is ignored. a nonzero digit in the upper nibble of an even output string is # not allowed but must be checked for. if one exists, it indicates overflow.L380:	jlbs	16(sp),L385		# skip next if output digit count is odd	bitb	$0xf0,*20(sp)		# is most significant digit nonzero?	beql	L385			# nothing to worry about if zero	bicb2	$0xf0,*20(sp)		# make the digit zero	bisb2	$psl$m_v,r11		# ... and set the overflow bit # we have not tested for nonzero digits in the output string. this test is # made by making another pass over the ouptut string. note that the low # order digit is unconditionally checked.L385:	movq	(sp),r2			# get address and count	bitb	$0xf0,-(r3)		# do not test sign in low order byte	bneq	L387			# skip loop if nonzero	jbr	L386			# start at bottom of loopL383:	tstb	-(r3)			# is next higher byte nonzero?	bneq	L387			# exit loop if yesL386:	sobgeq	r2,L383			# keep looking for nonzero if more bytes # the entire output string has been scanned and contains no nonzero # digits. the z-bit retains its original setting, which is set. if the # n-bit is also set, then the negative zero must be changed to positive # zero (unless the v-bit is also set). note that in the case of overflow, # the n-bit is cleared but the output string retrins the minus sign.	bbc	$psl$v_n,r11,L390	# n-bit is off already	bicb2	$psl$m_n,r11		# turn off saved n-bit unconditionally	bbs	$psl$v_v,r11,L390	# no fixup if v-bit is also set 	movb	$12,r9			# use preferred plus as sign of output	jbr	L390			# ... and rejoin the exit code # the following instruction is the exit point for all of the nonzero byte # checks. its direct effect is to clear the saved z-bit. it also bypasses # whatever other zero checks have not yet been performed.L387:	bicb2	$psl$m_z,r11		# clear saved z-bit # the following code executes in all cases. it is the common exit path for # all of the ashp routines when the count is even.L390:	movq	(sp)+,r2		# get address of end of output string	insv	r9,$0,$4,-1(r3)		# store sign that we have been saving #+ # this is the common exit path for many of the routines in this module. this # exit path can only be used for instructions that conform to the following # restrictions. # # 1.  registers r0 through r11 were saved on entry. # # 2.  the architecture requires that r0 and r2 are zero on exit. # # 3.  all other registers that have instruction-specific values on exit are  #     correctly stored in the appropriate locations on the stack. # # 4.  the saved psw is contained in r11 # # 5.  this instruction/routine should generate a decimal overflow trap if  #     both the v-bit and the dv-bit are set on exit. #-decimal_exit:

⌨️ 快捷键说明

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