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

📄 vaxconvrt.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 4 页
字号:
 #	This routine is shared by both CVTPS and CVTPT to translate an ASCII #	string that contains only the characters "0" to "9" into an equivalent #	packed decimal string. A check is made for legal input digits and a #	reserved operand generated if an illegal digit is encountered. # # input parameters: # #	r0 = srclen.rw		number of digits in source character string #	r1 = srcaddr.ab		address of first digiyt in input character #				string #	r2 = dstlen.rw		length in digits of output decimal string #	r3 = dstaddr.ab 	address of destination packed decimal string # #	(sp)	address of instruction-specific completion code in cvtsp #		or cvtpt routine # # output parameters: # #	r0 = Size in digits of shorter of source and dest. strings #	r1 = address of lowest addressed byte of source string #	     (see instruction-specific header for details) #	r2 = Number of digits in dest. packed decimal string #	r3 = address of byte containing most significant digit of #	     the destination string # #	R11 contains the partial condition codes accumlated by converting #	    all but the least significant input digit # # condition codes: # # implicit output: # # 	r4<31:8> is zero to insure that cvtsp works correctly # #	r10 is loaded with the address of an access violation handler in the #	event that any strings touched by this routine are not accessible. # # side effects: # #	r4 and r5 are used as scratch registers by this routine. # #	r6 through r9 are not used. #-cvtxp_common: #	roprand_check	r0		# insure that r0 lequ 31	 cmpw	r0,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r0,r0 #	roprand_check	r2		# insure that r2 lequ 31	 cmpw	r2,$31	 blequ	1f	 brw	decimal_roprand1:	 movzwl	r2,r2	movpsl	r11			# get initial psl	insv	$psl$m_z,$0,$4,r11	# set z-bit, clear the rest #	establish_handler convrt_accvio # Store address of access					# violation handler	 movab	convrt_accvio,r10	subl3	r2,r0,r5		# r5 is length difference	beql	cvtxp_equal		# life is easy if they're the same	blss	cvtxp_zero_fill		# fill output with zeros if its too large #+ # **********		srclen gtru dstlen			********** # # the following code executes if the source string is larger than the # destination string. excess high order input digits must be discarded. if # any of the input digits is not zero, then the v-bit is set in the saved psw # (stored in r11). in addition, digits must be checked for legal values # (ascii 0 through ascii 9) before they are discarded in order to determine # whether to generate a reserved operand abort. the low order digits will be # moved as in the normal case. a test for whether decimal overflow exceptions # are to be generated is made as part of final instruction processing.  # #	r5 = r0 - r2  (r5 gtru 0) #-cvtxp_overflow_check: #	mark_point	cvtxp_bsbw	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw:1:	cmpb	(r1)+,$0x30		# is digit ascii zero?	bneq	3f			# exit loop if other than zero2:	sobgtr	r5,1b			# test for more excess digits	movl	r2,r0			# update input length for skipped digits	brb	cvtxp_equal		# join common code # the following code executes if any of the discarded digits is nonzero. # if the digit is the ascii representation of a decimal digit, then the # v-bit is set in the saved psw and the saved z-bit is cleared. the loop # is reentered where we left it to continue the search for legal input # digits. (note that this is different from the cvtpx case where, once an # overflow was detected, the remaining excess input digits could be skipped.)3:	blssu	4f			# reserved operand if outside range	bisb2	$psl$m_v,r11		# set saved v-bit #	mark_point	cvtxp_bsbw_a	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_a - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_a:	cmpb	-1(r1),$0x039		# compare digit to ascii "9"	blequ	2b			# back in loop if inside range4:	brw	decimal_roprand		# signal illegal digit abort #+ # **********		srclen lssu dstlen			********** # # the following code executes if the destination string is longer than the # source string. all excess digits in the destination string are filled # with zero. #-cvtxp_zero_fill:	mnegl	r5,r5			# make digit count positive	blbc	r0,5f			# different code paths for even and odd					#  input string sizes (the shorter one) # shorter string has odd number of digits. note that the divide by two can  # never produce zero because r5 is always nonzero before the incl so that r5 # is always at least two before the divide takes place. the comment at the  # beginning of the module explains the two different code paths based on the # parity of the input (shorter) string.	incl	r5			# adjust before divide by two	extzv	$1,$4,r5,r5		# convert digit count to byte count	brb	6f			# join common loop # shorter string has an even number of digits.5:	extzv	$1,$4,r5,r5		# convert digit count to byte count	beql	cvtxp_equal		# no loop if byte count is zero	 #	mark_point	cvtxp_bsbw_b	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_b - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_b:6:	clrb	(r3)+			# store a pair of zeros in output string	sobgtr	r5,6b			# test for more bytes to clear #+ #**********	 updated srclen eql updated dstlen		********** # # the following code is a common meeting point for the three different input # cases relating source length and destination length. excess source or # destination digits have already been dealt with. we are effectively # dealing with input and output strings of equal length (as measured by # number of digits). #-cvtxp_equal:	clrl	r4			# insure that r4<31:8> is zero	extzv	$1,$4,r0,r5		# convert digit count to byte count	beql	L110			# down to last digit if zero # if the count of remaining digits is even, we need to jump into the middle # of the loop. but the store operation in the second half of the loop uses a # bisb2, assuming that the high order nibble is already cleared (which it is if # we also execute the first half of the loop). in order to insure that the high # order nibble has a zero stored in it, we jump to the last instruction of the # first half of the loop. because we just cleared r4, the movb instruction at # 90$ stores a zero in the appropriate byte of the output string. 	blbc	r0,9f			# to middle of loop if digit count even #	mark_point	cvtxp_bsbw_c	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_c - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_c:7:	subb3	$0x30,(r1)+,r4		# convert ascii to digit	blssu	4b			# abort instruction if out of range	beql	8f			# do not clear z-bit if digit is zero	bicb2	$psl$m_z,r11		# clear z-bit when digit is 1 to 98:	cmpb	r4,$9			# check for other end of range	bgtru	4b			# abort if outside the other end, too #	mark_point	cvtxp_bsbw_d	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_d - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_d:9:	movb	cvtxp_table_high[r4],(r3)	# store digit in high nibble # note that the above instruction also clears out the low order four bits in # the currently addressed byte in the output packed decimal string. #	mark_point	cvtxp_bsbw_e	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_e - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_e:	subb3	$0x030,(r1)+,r4		# convert ascii to digit "0"	blssu	4b			# abort instruction if out of range	beql	0f			# do not clear z-bit if digit is zero	bicb2	$psl$m_z,r11		# clear z-bit when digit is 1 to 90:	cmpb	r4,$9			# check for other end of range	bgtru	4b			# abort if outside the other end, too #	mark_point	cvtxp_bsbw_f	 .text	2	 .set	table_size,table_size + 1	 .word	Lcvtxp_bsbw_f - module_base	 .text	3	 .word	cvtxp_bsbw - module_base	 .textLcvtxp_bsbw_f:	bisb2	cvtxp_table_low[r4],(r3)+	# store digit in low nibble		sobgtr	r5,7b			# test for end of loopL110:	rsb				# perform instruction-specific					#  end processing #- # functional description: # #	this routine receives control when a digit count larger than 31 #	is detected. the exception is architecturally defined as an #	abort so there is no need to store intermediate state. all of the #	routines in this module save all registers r0 through r11 before #	performing the digit check. these registers must be restored #	before control is passed to vax$roprand. # # input parameters: # #	entry at decimal_roprand # #		00(sp) - return pc from common subroutine (discarded) #		04(sp) - saved r0	\ #		  .			 \ #		  .			  >  restored #		  .			 / #		48(sp) - saved r11	/ #		52(sp) - return pc from vax$xxxxxx routine # #	entry at decimal_roprand_no_pc # #		00(sp) - saved r0	\ #		  .			 \ #		  .			  >  restored #		  .			 / #		44(sp) - saved r11	/ #		48(sp) - return pc from vax$xxxxxx routine # # output parameters: # #	00(sp) - offset in packed register array to delta pc byte #	04(sp) - return pc from vax$xxxxxx routine # #		The two flags in this longword ( pack_m_fpd and pack_m_accvio ) #		are both clear in the case of a reserved operand abort # # implicit output: # #	this routine passes control to vax$roprand where further #	exception processing takes place. # # note: # #	this routine can be entered either from internal subroutines or from #	the callers of these subroutines. the decimal_roprand entry point is #	used when the return pc is on the stack because that is the name of #	the routine that is qutomatically invoked by the roprand_check macro #	when an illegal digit count is detected. the other name is arbitrary.  #-decimal_roprand:	addl2	$4,sp			# discard return pc from common routinedecimal_roprand_no_pc: #	popr	$^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>	 popr	$0x0fff	pushl	$cvtps_b_delta_pc	# store offset to delta pc byte	jmp	vax$roprand		# pass control along #+ # functional description: # #	this routine receives control when an access violation occurs while #	executing within the emulator routines for cvtps, cvtpt, cvtsp, or #	cvttp.  # #	the routine header for ashp_accvio in module vax$ashp contains a #	detailed description of access violation handling for the decimal #	string instructions.  # # input parameters: # #	see routine ashp_accvio in module vax$ashp # # output parameters: # #	see routine ashp_accvio in module vax$ashp #-convrt_accvio:	clrl	r2			# initialize the counter	pushab	module_base		# store base address of this module	subl2	(sp)+,r1		# get pc relative to this base1:	cmpw	r1,pc_table_base[r2]	# is this the right pc?	beql	3f			# exit loop if true	aoblss	$table_size,r2,1b	# do the entire table # if we drop through the dispatching based on pc, then the exception is not  # one that we want to back up. we simply reflect the exception to the user.2: #	popr	#^m<r0,r1,r2,r3>	# restore saved registers	 popr	$0x0f	rsb				# return to exception dispatcher # the exception pc matched one of the entries in our pc table. r2 contains # the index into both the pc table and the handler table. r1 has served # its purpose and can be used as a scratch register.3:	movzwl	handler_table_base[r2],r1	# get the offset to the handler	jmp	module_base[r1]		# pass control to the handler	 # in all of the instruction-specific routines, the state of the stack # will be shown as it was when the exception occurred. all offsets will # be pictured relative to r0.  #+ # functional description: # #	it is relatively simple to back out any of these four instructions  #	because their use of stack space is so simple. each of the four  #	routines contains a certain amount of initialization or completion  #	code that uses no stack space (over and above the saved register  #	array). additional processing occurs one level deep in a subroutine  #	where there is a return pc on the stack that must be discarded. # # input parameters: # #	r0 - address of top of stack when access violation occurred # #	see specific entry points for details # # output parameters: # #	see input parameter list for vax$decimal_accvio in module vax$ashp #- #+ # cvtpx_saved_r1 # # an access violation occurred in routine cvtpx_common along the code path  # where the intermediate value of r1 is stored on the stack along with the  # return pc. this must be disacrded. # #	00(r0) - saved intermediate value of r1 #	04(r0) - return pc in mainline of vax$cvtps or vax$cvtpt #	08(r0) - saved r0 #	12(r0) - saved r1 #	 etc. #-cvtpx_saved_r1:	addl2	$4,r0			# skip over saved r1 and drop into ... #+ # convert_bsbw # # an access violation occurred somewhere in cvtpx_common or cvtxp_common. # the return pc must be discarded. # #	00(r0) - return pc in vax$cvtps, vax$cvtpt, vax$cvtsp, or vax$cvttp #	04(r0) - saved r0 #	08(r0) - saved r1 #	 etc. #-cvtpx_bsbw:cvtxp_bsbw:	addl2	4,r0			# skip over return pc and drop into ... #+ # convert_accvio # # the access violation occurred in one of the four outer routines where  # nothing other than the saved registers has been pushed onto the stack.  # nothing more needs to be done to the registers or the stack before  # transferring control to vax$decimal_accvio. these entry points are merely # a convenience. # #	00(sp) - saved r0 #	04(sp) - saved r1 #	08(sp) - saved r2 #	12(sp) - saved r3 #	 etc. #-cvtps_accvio:cvtpt_accvio:cvtsp_accvio:cvttp_accvio:	jmp	vax$decimal_accvio	# join common code to restore registers

⌨️ 快捷键说明

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