📄 vaxdeciml.s
字号:
# compare least significant digit in source and destination strings # mark_point cmppx_accvio_e .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_e - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_e:2: bicb3 $0x0f,(r1),r1 # strip sign from last src1 digit # mark_point cmppx_accvio_f .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_f - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_f: bicb3 $0x0f,(r3),r3 # strip sign from last src2 digit cmpb r1,r3 # compare least significant digits bneq not_equal # at this point, all tests have been exhausted and the two strings have # been shown to be equal. set the z-bit, clear the remaining condition # codes, and restore saved registers.src1_eql_src2: movzbl $psl$m_z,r2 # set condition codes for src1 eql src2 # this is the common exit path. r2 contains the appropriate settings for the # n- and z-bits. there is no other expected input at this point.cmppx_exit: clrl (sp) # set saved r0 to 0 clrl 8(sp) # set saved r2 to 0 bicpsw $(psl$m_n|psl$m_z|psl$m_v|psl$m_c) # start with clean slate bispsw r2 # set n- and z-bits as appropriate # popr $^m<r0,r1,r2,r3,r4,r5,r10> # restore saved registers popr $0x043f # 001 002 rsb # return # the following code executes if specific digits in the two strings have # tested not equal. separate pieces of code are selected for the two # different cases of not equal. note that unsigned comparisons are required # here because the decimal digits "8" and "9", when appearing in the high # nibble, can cause the sign bit to be set.not_equal: blssu src1_smaller # branch if src1 is smaller than src2 # the src2 string has a smaller magnitude than the src1 string. the setting # of the signs determines how this transforms to a signed comparison. that is, # if both input signs are minus, then reverse the sense of the comparison.src2_smaller: bbs $cmppx_v_src2_minus,r4,src1_smaller_really # the src2 string has been determined to be smaller that the src1 stringsrc2_smaller_really: clrl r2 # clear both n- and z-bits brb cmppx_exit # join common exit code # the src1 string has a smaller magnitude than the src2 string. the setting # of the signs determines how this transforms to a signed comparison. that is, # if both input signs are minus, then reverse the sense of the comparison.src1_smaller: bbs $cmppx_v_src1_minus,r4,src2_smaller_really # the src1 string has been determined to be smaller that the src2 stringsrc1_smaller_really: movb $psl$m_n,r2 # clear both n- and z-bits brb cmppx_exit # join common exit code # the following code executes if the two input strings have different # signs. we need to determine if a comparison between plus zero and minus # zero is being made, because such a comparison should test equal. we scan # first one string and then the other. if we find a nonzero digit anywhere # along the way, we immediately exit this test and set the final condition # codes such that the "-" string is smaller than the "+" string. if we # exhaust both strings without finding a nonzero digit, then we report # that the two strings are equal.minus_zero_check: extzv $1,$4,r0,r0 # convert src1 digit count to byte count beql 7f # skip loop if only single digit # mark_point cmppx_accvio_g .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_g - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_g:6: tstb (r1)+ # test next byte for nonzero bneq cmppx_not_zero # exit loop if nonzero sobgtr r0,6b # test for end of loop # mark_point cmppx_accvio_h .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_h - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_h:7: bitb $0x0f0,(r1) # test least significant digit bneq cmppx_not_zero # exit if this digit is not zero # all digits in src1 are zero. now we must look for nonzero digits in src2. extzv $1,$4,r2,r2 # convert src2 digit count to byte count beql 9f # skip loop if only single digit # mark_point cmppx_accvio_i .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_i - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_i:8: tstb (r3)+ # test next byte for nonzero bneq cmppx_not_zero # exit loop if nonzero sobgtr r2,8b # test for end of loop # mark_point cmppx_accvio_j .text 2 .set table_size,table_size + 1 .word Lcmppx_accvio_j - module_base .text 3 .word cmppx_accvio - module_base .textLcmppx_accvio_j:9: bitb $0x0f0,(r3) # test least significant digit beql src1_eql_src2 # branch if two strings are equal # at least one of the two input strings contains at least one nonzero digit. # that knowledge is sufficient to determine the result of the comparison # based simply on the two (necessarily different) signs of the input strings.cmppx_not_zero: bbs $cmppx_v_src2_minus,r4,src2_smaller_really brb src1_smaller_really #+ # functional description: # # the destination string specified by the length and destination address # operands is replaced by the source string specified by the length and # source address operands. # # input parameters: # # r0 - len.rw length of input and output decimal strings # r1 - srcaddr.ab address of input packed decimal string # r3 - dstaddr.ab address of output packed decimal string # # psl<c> contains setting of c-bit when movp executed # # 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 <- 0 # c <- c # note that c-bit is preserved! # # register usage: # # this routine uses r0 through r3. the condition codes are recorded # in r2 as the routine executes. # # notes: # # the initial value of the c-bit must be captured (saved in r2) before # any instructions execute that alter the c-bit. #- .globl vax$movpvax$movp: movpsl r2 # save initial psl (to preserve c-bit) bbc $(movp_v_fpd + 16),r0,0f # branch if first time extzv $(movp_v_saved_psw + 16),$movp_s_saved_psw,r0,r2 # otherwise, replace condition # codes with previous settings # roprand_check r0 # insure that r0 lequ 310: cmpw r0,$31 blequ 1f brw decimal_roprand1: movzwl r0,r0 # pushl r3 # save starting addresses of output # pushl r2 # ... and input strings. store a # pushl r1 # place holder for saved r2. # Save the starting addressess of the input and output strings in addition to # the digit count operand (initial R0 contents.) Store a place holder for # saved R2. # pushr $^m<r0,r1,r2,r3,r10> # Save initial register contents pushr $0x040f # establish_handler decimal_accvio movab decimal_accvio,r10 insv $(psl$m_z>>-1),$1,$3,r2 # set z-bit. clear n- and v-bits. extzv $1,$4,r0,r0 # convert digit count to byte count beql 3f # skip loop if zero or one digit # mark_point movp_accvio .text 2 .set table_size,table_size + 1 .word Lmovp_accvio - module_base .text 3 .word movp_accvio - module_base .textLmovp_accvio:1: movb (r1)+,(r3)+ # move next two digits beql 2f # leave z-bit alone if both zero bicb2 $psl$m_z,r2 # otherwise, clear saved z-bit2: sobgtr r0,1b # check for end of loop # the last byte must be processed in a special way. the digit must be checked # for nonzero because that affects the condition codes. the sign must be # transformed into the preferred form. the n-bit must be set if the input # is negative, but cleared in the case of negative zero. # mark_point movp_accvio_a .text 2 .set table_size,table_size + 1 .word Lmovp_accvio_a - module_base .text 3 .word movp_accvio - module_base .textLmovp_accvio_a:3: movb (r1),r0 # get last input byte (r1 now scratch) bitb $0x0f0,r0 # is digit nonzero? beql 4f # branch if zero bicb2 $psl$m_z,r2 # otherwise, clear saved z-bit 4: bicb3 $0x0f0,r0,r1 # sign "digit" to r1 # assume that the sign is "+". if the input sign is minus, one of the several # fixups that must be done is to change the output sign from "+" to "-". insv $12,$0,$4,r0 # 12 is preferred plus sign caseb r1,$10,$15-10 # dispatch on sign typeL4: .word 6f-L4 # 10 => + .word 5f-L4 # 11 => - .word 6f-L4 # 12 => + .word 5f-L4 # 13 => - .word 6f-L4 # 14 => + .word 6f-L4 # 15 => + # input sign is "-"5: bbs $psl$v_z,r2,6f # treat as "+" if negative zero incl r0 # 13 is preferred minus sign bisb2 $psl$m_n,r2 # set n-bit # input sign is "+" or input is negative zero. nothing special to do. # mark_point movp_accvio_b .text 2 .set table_size,table_size + 1 .word Lmovp_accvio_b - module_base .text 3 .word movp_accvio - module_base .textLmovp_accvio_b:6: movb r0,(r3) # move modified final digit clrl (sp) # r0 and r2 must be zero on output clrl 8(sp) # ... but need r2 so clear saved r2 bicpsw $(psl$m_n|psl$m_z|psl$m_v|psl$m_c) # clear all codes bispsw r2 # reset codes as appropriate # popr $^m<r0,r1,r2,r3,r10> # restore saved registers popr $0x40f rsb # return #+ # functional description: # # this routine strips leading (high-order) zeros from a packed decimal # string. the routine exists based on two assumptions. # # 1. many of the decimal strings that are used in packed decimal # operations have several leading zeros. # # 2. the operations that are performed on a byte containing packed # decimal digits are more complicated that the combination of this # routine and any special end processing that occurs in the various # vax$xxxxxx routines when a string is exhausted. # # this routine exists as a performance enhancement. as such, it can only # succeed if it is extremely efficient. it does not attempt to be # rigorous in squeezing every last zero out of a string. it eliminates # only entire bytes that contain two zero digits. it does not look for a # leading zero in the high order nibble of a string of odd length. # # the routine also assumes that the input decimal strings are well # formed. if an even-length decimal string does not have a zero in its # unused high order nibble, then no stripping takes place, even though # the underlying vax$xxxxxx routine may work correctly. #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -