📄 vaxdeciml.s
字号:
clrl (sp) # r0 must be zero on exit clrl 8(sp) # r2 must also be zero bicpsw $psl$m_n|psl$m_z|psl$m_v|psl$m_c bispsw r11 # set appropriate condition codes bbs $psl$v_v,r11,2f # see if exceptions are enabled1: popr $0xfff # restore reg. 0-11 rsb # ... and return # if the v-bit is set and decimal traps are enabled (dv-bit is set), then # a decimal overflow trap is generated.2: bbc $psl$v_dv,r11,1b # only return v-bit if dv-bit is clear popr $0x0fff # restore reg 0-11 jbr decimal_overflow # report exception #+ # functional description: # # for certain cases (three out of four), it is necessary to put the # source string in a work area so that later portions of vax$ashp can # proceed in a straightforward manner. in one case (positive even shift # count), the sign must be eliminated before the least significant # byte of the source is moved to its appropriate place (not the least # significant byte) in the destination string. for odd shift counts, # the source string in the work area is shifted by one to reduce the # complicated case of an odd shift count to an equivalent but simpler # case with an even shift count. # # this routine moves the source string to a 20-byte work area already # allocated on the stack. note that the work area is zeroed by this # routine so that, if the work area is used, it consists of either # valid bytes from the source string or bytes containing zero. if the # work area is not needed (shift count is even and not positive), the # overhead of zeroing the work area is avoided. # # input parameters: # # r0 - byte count of source string (preserved) # r1 - address of most significant byte in source string # r8 - address one byte beyond end of work area (preserved) # # output parameters: # # r1 - address of most significant byte of source string in # work area # # side effects: # # r6 and r7 are modified by this routine. #-ashp_copy_source: clrq -8(r8) # insure that the work area clrq -16(r8) # ... is entirely filled clrl -20(r8) # ... with zeros addl3 r0,r1,r7 # r7 points one byte beyond source movl r8,r1 # r1 will step through work area movl r0,r6 # use r6 as the loop counter1: movb -(r7),-(r1) # move the next source byte sobgtr r6,1b # check for end of loop rsb # return with r1 properly loaded #+ # 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. # # finally, there is no explicit test for the end of the string. the # routine assumes that the low order byte, the one that contains the # sign, is not equal to zero. (note that the routine cannot run forever, # even for garbage, because the digit counts have already been checked # and are lequ 31 on input.) # # input and output parameters: # # there are really two identical but separate routines here. one is # used when the input decimal string descriptor is in r0 and r1. the # other is used when r2 and r3 describe the decimal string. note that # we have already performed the reserved operand checks so that r0 (or # r2) is guaranteed lequ 31. # # if the high order digit of an initially even length string is zero, # then the digit count (r0 or r2) is reduced by one. for all other # cases, the digit count is reduced by two as an entire byte of zeros # is skipped. # # input parameters (for entry at strip_zeros_r0_r1): # # r0<4:0> - len.rw length of input decimal string # r1 - addr.ab address of input packed decimal string # # output parameters (for entry at strip_zeros_r0_r1): # # r1 advanced to first nonzero byte in string # r0 reduced accordingly (note that if r0 is altered at all, # then r0 is always odd on exit.) # # input parameters (for entry at strip_zeros_r2_r3): # # r2<4:0> - len.rw length of input decimal string # r3 - addr.ab address of input packed decimal string # # output parameters (for entry at strip_zeros_r2_r3): # # r3 advanced to first nonzero byte in string # r2 reduced accordingly (note that if r2 is altered at all, # then r2 is always odd on exit.) #- # this routine is used when the decimal string is described by r0 (digit # count) and r1 (string address).strip_zeros_r0_r1: blbs r0,1f # skip first check if r0 starts out odd tstb (r1)+ # is first byte zero? bneq 2f # all done if not decl r0 # skip leading zero digit (r0 nequ 0)1: tstb (r1)+ # is next byte zero? bneq 2f # all done if not subl2 $2,r0 # decrease digit count by 2 brb 1b # ... and charge on2: decl r1 # back up r1 to last nonzero byte rsb # this routine is used when the decimal string is described by r2 (digit # count) and r3 (string address).strip_zeros_r2_r3: blbs r2,1f # skip first check if r2 starts out odd tstb (r3)+ # is first byte zero? bneq 2f # all done if not decl r2 # skip leading zero digit (r2 nequ 0)1: tstb (r3)+ # is next byte zero? bneq 2f # all done if not subl2 $2,r2 # decrease digit count by 2 brb 1b # ... and charge on2: decl r3 # back up r3 to last nonzero byte rsb #+ # functional description: # # the source operand is converted to a packed decimal string and the # destination string operand specified by the destination length and # destination address operands is replaced by the result. # # input parameters: # # r0 - src.rl input longword to be converted # r2 - dstlen.rw length of output decimal string # r3 - dstaddr.ab address of output packed decimal string # # output parameters: # # r0 = 0 # r1 = 0 # 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 # # register usage: # # this routine uses r0 through r5. the condition codes are recorded # in r4 as the routine executes. # # notes: # #;; the following comment needs to be updated to reflect the revised #;; algorithm. # # the algorithm used in this routine builds the packed decimal from # least significant digit to most significant digit, by repeatedly # dividing by 10 and placing the resulting remainder in the next most # significant output digit. this process continues until the quotient # goes to zero. # # no special processing is observed for either an input longword of zero # or an output string length of zero. the correct results for these cases # drop out of normal processing. #-vax$cvtlp: pushr $0x0c30 # save registers 4,5,10,11 movab decimal_pack,r10 # store handler address # get initial settings for condition codes. the initial settings for v and c # will be zero. the initial setting of n depends on the sign of the source # operand. the z-bit starts off set and remains set until a nonzero digit is # stored in the output string. note that the final z-bit may be set for # nonzero input if the output string is not large enough. (the v-bit is set # in this case.) in this case, the saved dv bit will determine whether to # reflect an exception or merely report the result to the caller. movpsl r11 # get dv bit from psl on input insv $psl$m_z,$0,$4,r11 # start with z-bit set, others clear/* * Do not need this check since we will check it before * we call these routines * * roprand_check r2 # insure that r2 lequ 31 */ ashl $-1,r2,r1 # convert digit count to byte count addl2 r1,r3 # get address of sign byte movb $12,(r3) # assume that sign is plus clrl r1 # prepare r1 for input to ediv tstl r0 # check sign of source operand bgeq 1f # start getting digits if not negative # source operand is minus. we remember that by setting the saved n-bit but work # with the absolute value of the input operand from this point on. incl (r3) # convert "+" to "-" (12 -> 13) mnegl r0,r0 # normalize source operand bisb2 $psl$m_n,r11 # set n-bit in saved psw #+ # the first (least significant) digit is obtained by dividing the source # longword by ten and storing the remainder in the high order nibble of the # sign byte. note that at this point, the upper four bits of the sign byte # contain zero. #-1: movl r2,r4 # special exit if zero source length beql 9f # only overflow check remains ediv $10,r0,r0,r5 # r5 gets remainder, first digit ashl $4,r5,r5 # shift digit to high nibble position beql 2f # leave z-bit alone if digit is zero bicb2 $psl$m_z,r11 # turn off z-bit if nonzero addb2 r5,(r3) # merge this digit with low nibble2: decl r4 # one less output digit beql 9f # no more room in output string ashl $-1,r4,r4 # number of complete bytes remaining beql 8f # check for last digit if none tstl r0 # is source exhausted? bneq 3f # go get next digits if not clrb -(r3) # store a pair of zeros jbr 5f # fill rest of output with zeros #+ # the following loop obtains two digits at a time from the source longword. it # accomplishes this by dividing the current value of r0 by 100 and converting # the remainder to a pair of decimal digits using the table that converts # binary numbers in the range from 0 to 99 to their packed decimal equivalents. # note that this technique may cause nonzero to be stored in the upper nibble # of the most significant byte of an even length string. this condition will # be tested for at the end of the loop. #-3: ediv $100,r0,r0,r5 # r5 gets remainder, next digit movb binary_to_packed_table[r5],-(r3) # store converted remainder beql 4f # leave z-bit alone if digit is zero bicb2 $psl$m_z,r11 # turn off z-bit if nonzero4: tstl r0 # is source exhausted? beql 5f # exit loop is no more source sobgtr r4,3b # check for end of loop jbr 8f # check for remaining digit # the following code executes if the source longword is exhausted. if there # are any remaining digits in the destination string, they must be filled # with zeros. note that one more byte is cleared if the original input length # was odd. this includes the most significant digit and the unused nibble.5: jlbs r2,0f # one less byte to zero if odd input length6: clrb -(r3) # set a pair of digits to zero0: sobgtr r4,6b # any more digits to zero? # the following code is the exit path for this routine. note that all # code paths that arrive here do so with r2 containing zero. in addition, r0 # always contains zero at this point. r1, however, must be cleared on exit. 7: clrq r1 # comform to architecture bicpsw $psl$m_n|psl$m_z|psl$m_v|psl$m_c # clear condition codes bispsw r11 # set appropriate condition codes popr $0x0c30 # restore regs 4,5,10,11 rsb #+ # the following code executes when there is no more room in the destination # string. we first test for the parity of the output length and, if even, # determine whether a nonzero digit was stored in the upper nibble of the # most significant byte. such a nonzero store causes an overflow condition. # # if the source operand is not yet exhausted, then decimal overflow occurs. # if decimal overflow exceptions are enabled, an exception is signalled. # otherwise, the v-bit in the psw is set and a normal exit is issued. note # that negative zero is only an issue for this instruction when overflow # occurs. in the no overflow case, the entire converted longword is stored in # the output string and there is only one form of binary zero. #-8: jlbs r2,9f # no last digit if odd output length ediv $10,r0,r0,r5 # get next input digit movb r5,-(r3) # store in last output byte beql 9f # leave z-bit alone if zero bicb2 $psl$m_z,r119: tstl r0 # is source also all used up? beql 7b # yes, continue with exit processing # an overflow has occurred. if the z-bit is still set, then the n-bit is cleared # note that, because all negative z
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -