📄 vaxconvrt.s
字号:
.globl vax$cvtpt_restartvax$cvtpt_restart: bicl2 $0xff000000,r0 # eliminate delta-pc from "dstlen" .globl vax$cvtptvax$cvtpt:L700: # pushr $^m<r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> # save the lot pushr $0x0fff # establish_handler convrt_accvio # store address of access # violation handler movab convrt_accvio,r10 movl r2,r9 # store table address away rotl $16,r0,r2 # store "dstlen" in r2 bsbw cvtpx_common # execute bulk as common code #+ # the common code routine returns here with the following relevant input. # # r1 address of least significant digit and sign of input string # r2 number of digits in destination string (preserved across call) # r3 address of last byte in destination to be loaded # 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 cvtps instruction loads r8 in its initialization code. this instruction # does not need r8 except at this time to determine the setting of the n-bit # so r8 is loaded here. in addition, a check is required to insure that the # z-bit has its correct setting if the least significant digit is the first # nonzero digit encountered in the input string. #- tstl r2 # check for no remaining input beql 1f # skip storing digit if nothing there # mark_point cvtpt_accvio .text 2 .set table_size,table_size + 1 .word Lcvtpt_accvio - module_base .text 3 .word cvtpt_accvio - module_base .textLcvtpt_accvio: movzbl (r1),r4 # get last input digit # mark_point cvtpt_accvio_a .text 2 .set table_size,table_size + 1 .word Lcvtpt_accvio_a - module_base .text 3 .word cvtpt_accvio - module_base .textLcvtpt_accvio_a: movb (r9)[r4],(r3) # store associated destination byte # mark_point cvtpt_accvio_b .text 2 .set table_size,table_size + 1 .word Lcvtpt_accvio_b - module_base .text 3 .word cvtpt_accvio - module_base .textLcvtpt_accvio_b: extzv $4,$4,(r1),r4 # get least significant digit beql 1f # skip clearing z-bit if zero bicb2 $psl$m_z,r11 # clear saved z-bit # mark_point cvtpt_accvio_c .text 2 .set table_size,table_size + 1 .word Lcvtpt_accvio_c - module_base .text 3 .word cvtpt_accvio - module_base .textLcvtpt_accvio_c:1: bicb3 $0x0f0,(r1),r8 # sign "digit" to r6 caseb r8,$10,$15-10 # dispatch on sign L2: .word 3f-L2 # 10 => + .word 2f-L2 # 11 => - .word 3f-L2 # 12 => + .word 2f-L2 # 13 => - .word 3f-L2 # 14 => + .word 3f-L2 # 15 => +2: bbs $psl$v_z,r11,3f # skip if z-bit set (negative zero) bisb2 $psl$m_n,r11 # set n-bit because sign is "-"3: jmp vax$decimal_exit # exit through common code #+ # functional description: # # This routine is used by both CVTPS and CVTPT to translate a packed # decimal string of digits into its ASCII equivalent. # # input parameters: # # r0 = srclen.rw length in digits of input decimal string # r1 = srcaddr.ab address of input packed decimal string # r2 = dstlen.rw number of digits in destination character string # r3 = dstaddr.ab address of destination character string # # (sp) address of instruction-specific completion code in cvtps # or cvtpt routine # # Implicit input: # # R10 must contain the address of an access violation handler in the # event that any strings touched by this routine are not accessible. # # output parameters: # # r0 = Size in digits of shorter of source and destination # r1 = Address of least significant digit and sign of input string # r2 = Number of digits in destination character string (unchanged) # r3 = Address of last byte in destination to be load # # R11 contains the partial condition codes accumulated by converting # all but the least significant input digit # condition codes: # # R4, R5, and R6 are used as scratch register by this routine. # # R7 through R10 are not used. #-cvtpx_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 # 002 Fix bad expansion of a macro movpsl r11 # get initial psl insv $psl$m_z,$0,$4,r11 # set z-bit, clear the rest subl3 r2,r0,r5 # r5 is length difference beql cvtpx_equal # life is easy if they're the same blss cvtpx_zero_fill # fill output with zeros if 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). 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) #-cvtpx_overflow_check: pushl r1 # save initial input address blbs r0,1f # skip single digit test for odd length # mark_point cvtpx_saved_r1 .text 2 .set table_size,table_size + 1 .word Lcvtpx_saved_r1 - module_base .text 3 .word cvtpx_saved_r1 - module_base .textLcvtpx_saved_r1: extzv $0,$4,(r1),r4 # first digit to r4 (set r4<31:8> to 0) bneq 4f # skip rest if nonzero. nothing to be decl r5 # gained by hanging around. # one less digit to check incl r1 # point r1 to next byte in input string1: ashl $-1,r5,r5 # convert digit count to byte count beql 3f # skip loop if no more double digits # mark_point cvtpx_saved_r1_a .text 2 .set table_size,table_size + 1 .word Lcvtpx_saved_r1_a - module_base .text 3 .word cvtpx_saved_r1 - module_base .textLcvtpx_saved_r1_a:2: tstb (r1)+ # do rest two digits at a time bneq 4f # exit loop is nonzero digit sobgtr r5,2b # check for end of loop3: blbs r2,5f # no lone digit if r2 odd # mark_point cvtpx_saved_r1_b .text 2 .set table_size,table_size + 1 .word Lcvtpx_saved_r1_b - module_base .text 3 .word cvtpx_saved_r1 - module_base .textLcvtpx_saved_r1_b: bitb $0x0f0,(r1) # does upper nibble contain nonzero beql 5f # no, so we're all done # the following code executes if any of the discarded digits is nonzero. # the v-bit is set in the saved psw, the saved z-bit is cleared, and r1 is # updated to point to the remaining input string. the large comment at the # beginning of the module explains why the incl r5 instruction is necessary # when r0, the length of the shorter string, is odd.4: bicb2 $psl$m_z,r11 # clear saved z-bit bisb2 $psl$m_v,r11 # set saved v-bit5: subl3 r2,r0,r5 # recompute difference (r5 gtru 0) # the long comment at the beginning of the module explains the reason why # we increment r5 when r2, the length of the shorter string, is odd. blbc r2,6f # need adjustment if odd output string incl r5 # adjust difference6: ashl $-1,r5,r5 # convert digit count to byte count addl3 (sp)+,r5,r1 # "restore" an updated input pointer movl r2,r0 # enter common code with updated # "srclen" equal to "dstlen" brb cvtpx_equal # join common code #+ # ********** 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. #-cvtpx_zero_fill: mnegl r5,r5 # make digit count positive # mark_point cvtpx_bsbw .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw:7: movb $0x030,(r3)+ # store a "0" in the output sobgtr r5,7b # check for end of loop #+ #********** 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). #-cvtpx_equal: blbs r0,9f # no special first digit if r0 odd tstl r0 # also skip if no remaining digits beql 5f # mark_point cvtpx_bsbw_a .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_a - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_a: extzv $0,$4,(r1),r4 # first digit to r4 (set r4<31:8> to 0) beql 8f # leave z-bit alone if zero bicb2 $psl$m_z,r11 # otherwise, clear z-bit # mark_point cvtpx_bsbw_b .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_b - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_b:8: movb cvtpx_table[r4],(r3)+ # move digit to output string incl r1 # advance input string pointer decl r0 # one less digit to process9: ashl $-1,r0,r5 # convert digit count to byte count beql 2f # all done if zero # mark_point cvtpx_bsbw_c .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_c - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_c:0: movzbl (r1)+,r4 # get next two input digits beql 3f # step out of line if both are zero bicb2 $psl$m_z,r11 # clear saved z-bit extzv $4,$4,r4,r7 # get high-order digit # mark_point cvtpx_bsbw_d .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_d - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_d: movb cvtpx_table[r7],(r3)+ # move associated character to output bicb3 $0x0f0,r4,r7 # get low-order digit # mark_point cvtpx_bsbw_e .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_e - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_e: movb cvtpx_table[r7],(r3)+ # move associated character to output1: sobgtr r5,0b # test for end of loop2: rsb # perform instruction-specific # end processing # this code is part of the main loop that moves input digits to the output # string. This code only executes when a digit pair consisting of two zeros # detected. Note that this is an optimization that recognizes that the # individual digits do not have to be translated in order to load the # destination string. # mark_point cvtpx_bsbw_f .text 2 .set table_size,table_size + 1 .word Lcvtpx_bsbw_f - module_base .text 3 .word cvtpx_bsbw - module_base .textLcvtpx_bsbw_f:3: movw $0x03030,(r3)+ # move the pair to the output "00" brb 1b # rejoin at the end of the loop # We have advanced too far in the destination string. Back up by one byte # and let the caller correctly load the final output byte. 5: decl r3 rsb #+ # functional description: # # the conversion from a numeric string to a packed decimal string # (cvtsp and cvttp instructions) consists of much common code and # two small pieces of code that are instruction specific, the # beginning and a portion of the end processing. the actual routine # exit path is the common exit path from this module, vax$decimal_exit. # # the two routines perform instruction-specific operations on the # first byte in the stream. the bulk of the work is done by a common # subroutine. some instruction-specific end processing is done before # final control is passed to vax$decimal_exit. # # the structure is something like the following. # # cvtsp cvttp # ----- ----- # # skip over sign character store table address # # | unpack registers # | # | | # \ / # \ / # \ / # | | # v v # # handle unequal srclen and dstlen # # move all digits except last digit # # | | # / \ # / \ # / \ # | | # v v # # move last digit to output use table to move last digit # move sign to output and sign to output string # # | | # \ / # \ / # \ / # | | # v v # # vax$decimal_exit # set condition codes and registers # to their final values # # input parameters: # # see instruction-specific entry points # # output parameters: # # r0 = 0 # r1 = address of lowest addressed byte of destination string # (see instruction-specific header for details) # r2 = 0 # r3 = address of byte containing most significant digit of # the source string # # condition codes: # # n <- destination string lss 0 # z <- destination string eql 0 # v <- decimal overflow # c <- 0 # # notes: # # both of these instructions check the input strings for legal decimal # digits. if a character other than the ascii representation of a # decimal digit is detected in the input string, a reserved operand # abort is generated. this exception is not restartable. #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -