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

📄 vaxconvrt.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 4 页
字号:
 #	in addition, the cvtsp instruction insures that the sign character is  #	one of "+", " ", or "-".  # #	the cvttp instruction uses the highest addressed byte as an offset  #	into a 256-byte table. the byte that is retrieved from this table is  #	checked to determine that its high nibble contains a legal decimal  #	digit and its low nibble contains a legal sign. #- #+ # the following tables contains the decimal equivalents of the ten decimal # digits. one table is used if the low nibble of a byte is being loaded  # (an even numbered digit). the other table is used when the high nibble  # of a byte is being loaded (odd numbered digit). #- # table for entry into low order nibblecvtxp_table_low:	.byte	0x00 , 0x01 , 0x02 , 0x03 , 0x04 	.byte	0x05 , 0x06 , 0x07 , 0x08 , 0x09  # table for entry into high order nibblecvtxp_table_high:	.byte	0x00 , 0x10 , 0x20 , 0x30 , 0x40 	.byte	0x50 , 0x60 , 0x70 , 0x80 , 0x90  #+ # functional description: # #	the source numeric string specified by  the  source  length  and  source #	address  operands  is  converted  to  a  packed  decimal  string and the #	destination string specified by the destination address and  destination #	length operands is replaced by the result. # # input parameters: # #	r0 = srclen.rw		number of digits in source character string #	r1 = srcaddr.ab		address of input character string #	r2 = dstlen.rw		length in digits of output decimal string #	r3 = dstaddr.ab 	address of destination packed decimal string # # output parameters: # #	r0 = 0 #	r1 = address of the sign byte 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 # # Notes: #- # note that the two entry points vax$cvtsp and vax$cvttp must save the # exact same set of registers because the two routines use a common exit # path that includes a popr instruction that restores registers. in fact, by  # saving all registers, even if one or two of them are not needed, we can use  # the common exit path from this module.	.globl	vax$cvtspvax$cvtsp: #	pushr	$^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>	# save the lot	 pushr	$0x0fff	incl	r1			# skip byte containing sign for now	bsbw	cvtxp_common		# execute bulk as common code #+ # the common code routine returns here with the following relevant input. # #	r0	number of digits remaining in source and destination strings #	r1	address of last (highest addressed) byte in source string #	r3	address of least significant digit and sign of output string #	r4	r4<31:8> must be zero on input to this routine #	r11	saved psw with condition codes to date (n=0,z,v,c=0) # #	cvtsp_a_srcaddr(sp)	saved r1 at input, address of sign character # #	r4 is a scratch register # # the last input digit is moved to the output stream, after a check that it # represents a legal decimal digit. a check is also required to insure that # the z-bit has its correct setting if this digit is the first nonzero digit # encountered in the input string. the sign of the input string is checked # for a legal value and transformed into one of two legal output signs, 12  # for "+" and 13 for "-". #- #	mark_point	cvtsp_accvio	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio:	movb	$12,(r3)		# assume that sign is plus	tstl	r0			# check for zero length input string	beql	2f			# skip storing digit if nothing there #	mark_point	cvtsp_accvio_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio_a - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio_a:	subb3	$0x030,(r1),r4		# get least significant digit "0"	blssu	3f			# reserved operand if not a digit	beql	1f			# skip clearing z-bit if zero	bicb2	$psl$m_z,r11		# clear saved z-bit1:	cmpb	r4,$9			# check digit against top of range	bgtru	3f			# reserved operand if over the top #	mark_point	cvtsp_accvio_b	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio_b - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio_b:	addb2	cvtxp_table_high[r4],(r3)	# store final output digit #	mark_point	cvtsp_accvio_c	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio_c - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio_c:2:	movzbl	*cvtsp_a_srcaddr(sp),r4	# get sign character from input string	caseb	r4,$0x2b,$0x2d - 0x2b	# 001 dispatch on sign characterL3:	.word	5f-L3			# character is "+"	.word	3f-L3			# sign character is "#" (illegal input)	.word	4f-L3			# character is "-"	cmpb	r4,$0x20		# blank is also legal "plus sign"	beql	5f # error path for all code paths that detect an illegal character in # the input stream3:	brw	decimal_roprand_no_pc	# reserved operand abort on illegal input # the sign of the input stream was "-". if something other than negative # zero, set the n-bit and adjust the sign.4:	bisb2	$psl$m_n,r11		# set n-bit because sign is "-" #	mark_point	cvtsp_accvio_d	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio_d - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio_d:	incb	(r3)			# change sign from "+" (12) to "-" (13)	bbc	$psl$v_z,r11,5f		# all done unless negative zero	bicb2	$psl$m_n,r11		# clear the saved n-bit	bbs	$psl$v_v,r11,5f		# the output sign is ignored if overflow #	mark_point	cvtsp_accvio_e	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtsp_accvio_e - module_base	 .text	3	 .word	cvtsp_accvio - module_base	 .textLcvtsp_accvio_e:	decb	(r3)			# change sign back so -0 becomes +05:	jmp	vax$decimal_exit	# exit through common code #+ # functional description: # #	the source trailing numeric string specified by the  source  length  and #	source  address operands is converted to a packed decimal string and the #	destination packed decimal string specified by the  destination  address #	and destination length operands is replaced by the result. # #	conversion is effected by using the highest addressed (trailing) byte of #	the  source  string  as  an  unsigned  index into a 256 byte table whose #	zeroth entry is specified by the table address operand.  the  byte  read #	out  of the table replaces the highest addressed byte of the destination #	string (i.e.  the byte containing the sign  and  the  least  significant #	digit).   the  remaining  packed  digits  of  the destination string are #	replaced by the low order 4 bits  of  the  corresponding  bytes  in  the #	source string. # # input parameters: # #	r0 <15:0>  = srclen.rw	number of digits in source character string #	r0 <31:16> = dstlen.rw	length in digits of output decimal string #	r1         = srcaddr.ab	address of input character string #	r2         = tbladdr.ab	address of 256-byte table used for sign conversion #	r3         = dstaddr.ab address of destination packed decimal string # # output parameters: # #	r0 = 0 #	r1 = address of 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 #- # note that the two entry points vax$cvtsp and vax$cvttp must save the # exact same set of registers because the two routines use a common exit # path that includes a popr instruction that restores registers. in fact, by  # saving all registers, even if one or two of them are not needed, we can use  # the common exit path from this module. # # See the rotine header for CVTPT for an explanation of the _JSB and _RESTART # entry points. # there is a single case where the common subroutine cannot be used. if the # output length is zero, then the final character in the input string would # be subjected to the rather stringent legality test that it lie between # ascii 0 and ascii 9. in fact, it is the translated character that must be # tested. there are three cases.  # #	the input length is also zero. in this case, the common code path can #	be used because the input and output length are equal. (in fact, the #	subroutine does little more than set the condition codes and load #	registers.  # #	the input consists of a single character. in this case, this single #	character is translated and tested for legality. note that the  #	subroutine is also called here to set condition codes and the like. # #	the input size is larger than one. in this case, the common subroutine #	is called with the input size reduced by one. the leading characters #	are tested by the subroutine which returns here to allow the final #	character to be tested.  # # note that this is not a commonly travelled code path so that the seemingly # excessive amount of code necessary to achieve accuracy is not a performance # problem. 8: #	roprand_check	r0		# insure that r0 lequ 31	 cmpw	r0,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r0,r0	beql	0f			# back in line if source length zero	decl	r0			# reduce input length by one	bsbw	cvtxp_common		# check leading digits for legality #	mark_point	cvttp_accvio	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio:9:	movzbl	(r1),r4			# get last input byte #	mark_point	cvttp_accvio_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_a - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_a:	movzbl	(r9)[r4],r4		# get associated output byte from table	bicb3	$0x0f0,r4,(r3)		# only store sign in output string	extzv	$4,$4,r4,r0		# get low-order digit	beql	1f			# join exit code if zero	bisb2	$psl$m_v,r11		# set v-bit in saved psw	cmpl	r0,$9			# is the digit within range?	blequ	1f			# yes, join the exit code	brw	decimal_roprand_no_pc	# otherwise, report exception	.globl	vax$cvttp_jsbvax$cvttp_jsb: #	bbcc	$cvttp_v_fpd,r0,vax$cvttp # Have we been here before?	 bbcc	$cvttp_v_fpd,r0,L600	.globl	vax$cvttp_restartvax$cvttp_restart:	bicl2	$0x0ff000000,r0		# Make sure that we clear the right byte	.globl	vax$cvttpvax$cvttp:L600: #	pushr	$^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>	# save the lot	 pushr	$0x0fff	movl	r2,r9			# store table address away	extzv	$16,$16,r0,r2		# store "dstlen" in r2	beql	8b			# perform extraordinary check if zero0:	bsbw	cvtxp_common		# execute bulk as common code #+ # the common code routine returns here with the following relevant input. # #	r0	number of digits remaining in source and destination strings #	r1	address of last (highest addressed) byte in source string #	r3	address of least significant digit and sign of output string #	r9	address of 256-byte table (preserved across call) #	r11	saved psw with condition codes to date (n=0,z,v,c=0) # #	r4 is a scratch register # # the last byte of the input string is used as an index into the 256-byte # table that contains the last output byte. the contents of this byte are # tested for a legal decimal digit in its upper nibble and a legal sign # representation (10 through 15) in its low nibble. the z-bit is cleared # if the digit is 1 through 9 to cover the case that this is the first  # nonzero digit in the input string. #-	tstl	r0			# check for no remaining input	beql	7f			# special case if zero length input #	mark_point	cvttp_accvio_b	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_b - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_b:	movzbl	(r1),r4			# get last input byte #	mark_point	cvttp_accvio_c	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_c - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_c:	movzbl	(r9)[r4],r4		# get associated output byte from table #	mark_point	cvttp_accvio_d	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_d - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_d:	movb	r4,(r3)			# store in destination string	extzv	$4,$4,r4,r0		# get least significant digit		beql	1f			# skip clearing z-bit if zero	cmpb	r0,$9			# check for legal range	bgtr	2f			# reserved operand if 10 through 15	bicb2	$psl$m_z,r11		# clear saved z-bit1:	bicb3	$0x0f0,r4,r0		# sign "digit" to r0	caseb	r0,$10,$15-10		# dispatch on sign L4:	.word	5f-L4			# 10 => +	.word	3f-L4			# 11 => -	.word	6f-L4			# 12 => +	.word	4f-L4			# 13 => -	.word	5f-L4			# 14 => +	.word	5f-L4			# 15 => +2:	brw	decimal_roprand_no_pc	# reserved operand if sign is 0 to 9 # a minus sign of 11 must be changed to 13, the preferred minus representation #	mark_point	cvttp_accvio_e	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_e - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_e:3:	addb2	$2,(r3)			# change 11 to 13, preferred minus sign4:	bisb2	$psl$m_n,r11		# set n-bit because sign is "-"	bbc	$psl$v_z,r11,6f		# all done unless negative zero	bicb2	$psl$m_n,r11		# clear the saved n-bit	bbs	$psl$v_v,r11,6f		# the output sign is ignored if overflow # if the sign character is a 10, 14, or 15, it must be changed to a 12, the # preferred plus sign before joining the exit code. #	mark_point	cvttp_accvio_f	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_f - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_f:5:	insv	$12,$0,$4,(r3)		# store a 12 as the output sign6:	jmp	vax$decimal_exit	# exit through common code # if the source string has zero length, the destination is set identically # to zero. the following instruction sequence assumes that the z-bit was # set in the initialization code for this routine. #	mark_point	cvttp_accvio_g	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvttp_accvio_g - module_base	 .text	3	 .word	cvttp_accvio - module_base	 .textLcvttp_accvio_g:7:	movb	$12,(r3)		# store "+" in output string	jmp	vax$decimal_exit	# exit through common code #+ # functional description: #

⌨️ 快捷键说明

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