📄 vaxashp.s
字号:
movl (sp)+,r0 # restore source string byte count incl r4 # count the shift we did blss ashp_shift_negative # join common code at the right place # drop through to ashp_shift_positive #+ # functional description: # # this routine completes the work of the ashp instruction in the case of # an even shift count. (if the original shift count was odd, the source # string has already been shifted by one and the shift count adjusted by # one.) a portion (from none to all) of the source string is moved to # the destination string. pieces of the destination string at either end # may be filled with zeros. if excess digits of the source are not # moved, they must be tested for nonzero to determine the correct # setting of the v-bit. # # input parameters: # # r0<3:0> - number of bytes in source string # r1 - address of source string # r2<3:0> - number of bytes in destination string # r3 - address of destination string # r4<7:0> - count operand (signed longword of digit count) # r5<3:0> - round operand in case of negative shift # r9<3:0> - sign of source string in preferred form # # implicit input: # # r4 is presumed (guaranteed) even on input to this routine # # the top of the stack is assumed to contain a 20-byte work area (that # may or may not have been used). the space must be allocated for this # work area in all cases so that the exit code works correctly for all # cases without the need for lots of extra conditional code. # # output parameters: # # this routine completes the operation of vax$ashp. see the routine # header for vax$ashp for details on output registers and conditon codes. # # details: # # put some of the stuff from ashp.txt here. #-ashp_shift_positive: divl2 $2,r4 # convert digit count to byte count subl3 r4,r2,r7 # modify the destination count blss L130 # branch if simply moving zeros movl r4,r6 # number of zeros at low order endL110: subl3 r0,r7,r8 # are there any excess high order digits? blss L160 # no, excess is in source. # we only move "srclen" source bytes. the rest of the destination string is # filled with zeros. movl r0,r7 # get number of bytes to actually move brb L100 # ... and go move them # the count argument is larger than the destination length. all of the source # is checked for nonzero (overflow check). all of the destination is filled # with zeros.L130: movl r2,r6 # number of low order zeros clrl r7 # the source string is untouched movl r0,r8 # number of source bytes to check brb L180 # go do the actual work # if the count is negative, then there is no need to fill in low order zeros # (r6 is zero). the following code is similar to the above cases, differing # in the roles played by source length (r0) and destination length (r2) and # also in the first loop (zero fill or overflow check) that executes.ashp_shift_negative: clrl r6 # no zero fill at low end of destination mnegl r4,r4 # get absolute value of count divl2 $2,r4 # convert digit count to byte count subl3 r4,r0,r7 # get modified source length blss L170 # branch if count is larger subl3 r7,r2,r8 # are there zeros at high end? bgeq L100 # exit to zero fill loop if yes # the modified source length is larger than the destination length. part # of the source is moved. the rest is checked for nonzero. movl r2,r7 # only move "dstlen" bytes # in these cases, some digits in the source string will not be moved. if any # of these digits is nonzero, then the v-bit must be set.L160: mnegl r8,r8 # number of bytes in source to check brb L180 # exit to overflow check loop # the count argument is larger than the source length. all of the destination # is filled with zeros. the source is ignored.L170: clrl r7 # no source bytes get moved movl r2,r8 # all of the destination is filled brb L100 # join the zero fill loop #+ # at this point, the three separate counts have all been calculated. each # loop is executed in turn, stepping through the source and destination # strings, either alone or in step as appropriate. # # r6 - number of low order digits to fill with zero # r7 - number of bytes to move intact from source to destination # r8 - number of excess digits in one or the other string. # # if excess source digits, they must be tested for nonzero to # correctly set the v-bit. # # if excess destination bytes, they must be filled with zero. #- # test excess source digits for nonzero # MARK_POINT ASHP_20_b .text 2 .set table_size,table_size + 1 .word Lashp_20_b - module_base .text 3 .word ashp_20 - module_base .textLashp_20_b:L175: tstb (r1)+ # is next byte nonzero bneq L190 # handle overflow out of lineL180: sobgeq r8,L175 # otherwise, keep on looking brb L220 # join top of second loopL190: bisb2 $psl$m_v,r11 # set saved v-bit addl2 r8,r1 # skip past rest of excess brb L220 # join top of second loop # in this case, the excess digits are found in the destination string. they # must be filled with zero.L100: tstl r8 # is there really something to do? beql L220 # skip first loop if nothing # mark_point ashp_20 .text 2 .set table_size,table_size + 1 .word Lashp_20 - module_base .text 3 .word ashp_20 - module_base .textLashp_20:L210: clrb (r3)+ # store another zero sobgtr r8,L210 # ... and keep on looping # the next loop is where something interesting happens, namely that parts of # the source string are moved to the destination string. note that the use of # bytes rather than digits in this operation makes the detection of nonzero # digits difficult because the presence of a nonzero digit in the place # occupied by the sign or in the hign order nibble of an even length output # string and nowhere else would cause the Z-bit to be incorrectly cleared. # For this reason, we ignore the Z-bit here and make a special pass over the # output string after all of the special cases have been dealt with. The # extra overhead of a second trip to memory is offset by the simplicity in # other places in this routine.L220: tstl r7 # something to do here? beql L240 # skip this loop if nothing # mark_point ashp_20_d .text 2 .set table_size,table_size + 1 .word Lashp_20_d - module_base .text 3 .word ashp_20 - module_base .textLashp_20_d:L230: movb (r1)+,(r3)+ # move the next byte sobgtr r7,L230 # ... and keep on looping # the final loop occurs in some cases of positive shift count where the low # order digits of the destination must be filled with zeros.L240: tstl r6 # something to do here? beql L260 # skip if loop count is zero # mark_point ashp_20_e .text 2 .set table_size,table_size + 1 .word Lashp_20_e - module_base .text 3 .word ashp_20 - module_base .textLashp_20_e:L250: clrb (r3)+ # store another zero sobgtr r6,L250 # ... until we're done #+ # at this point, the destination string is complete except for the sign. # if there is a round operand, that must be added to the destination string. # # r3 - address one byte beyond destination string # r5 - round operand #-L260: addl2 $20,sp # deallocate work area extzv $1,$4,ashp_w_dstlen(sp),r2 # get original destination byte count movq r2,-(sp) # save address and count for z-bit loop movzbl r5,r8 # load round into carry register beql L280 # skip next mess unless "round" exists movl r3,r5 # r5 tracks the addition output clrl r6 # we only need one term and carry in sum # mark_point ashp_8 .text 2 .set table_size,table_size + 1 .word Lashp_8 - module_base .text 3 .word ashp_8 - module_base .textLashp_8:L270: movzbl -(r3),r7 # get next digit # mark_point ashp_bsbw_8 .text 2 .set table_size,table_size + 1 .word Lashp_bsbw_8 - module_base .text 3 .word ashp_bsbw_8 - module_base .textLashp_bsbw_8: jsb vax$add_packed_byte_r6_r7 # perform the addition tstl r8 # see if this add produced a carry beql L280 # all done if no more carry sobgeq r2,L270 # back for the next byte # if we drop through the end of the loop, then the final add produced a carry. # this must be reflected by setting the v-bit in the saved psw. bisb2 $psl$m_v,r11 # set the saved v-bit # all of the digits are now loaded into the destination string. the condition # codes, except for the z-bit, have their correct settings. the sign must be # set, a check must be made for even digit count in the output string, and # the various special cases (negative zero, decimal overflow trap, ans so on) # must be checked before completing the routine. # this entire routine worked with entire bytes, ignoring whether digit counts # were odd or even. an illegal digit in the upper nibble of an even input string # is ignored. a nonzero digit in the upper nibble of an even output string is # not allowed but must be checked for. if one exists, it indicates overflow.L280: blbs (8+ashp_w_dstlen)(sp),L285 # skip next if output digit count is odd bitb $0x0f0,*(8+ashp_a_dstaddr)(sp) # is most significant digit nonzero? beql L285 # nothing to worry about if zero # mark_point ashp_8_c .text 2 .set table_size,table_size + 1 .word Lashp_8_c - module_base .text 3 .word ashp_8 - module_base .textLashp_8_c: bicb2 $0x0f0,*(8+ashp_a_dstaddr)(sp) # make the digit zero bisb2 $psl$m_v,r11 # ... and set the overflow bit # we have not tested for nonzero digits in the output string. this test is # made by making another pass over the ouptut string. note that the low # order digit is unconditionally checked.L285: movq (sp),r2 # get address and count # mark_point ashp_8_a .text 2 .set table_size,table_size + 1 .word Lashp_8_a - module_base .text 3 .word ashp_8 - module_base .textLashp_8_a: bitb $0x0f0,-(r3) # do not test sign in low order byte bneq L287 # skip loop if nonzero brb L286 # start at bottom of loop # mark_point ashp_8_b .text 2 .set table_size,table_size + 1 .word Lashp_8_b - module_base .text 3 .word ashp_8 - module_base .textLashp_8_b:L283: tstb -(r3) # is next higher byte nonzero? bneq L287 # exit loop if yesL286: sobgeq r2,L283 # keep looking for nonzero if more bytes # the entire output string has been scanned and contains no nonzero # digits. the z-bit retains its original setting, which is set. if the # n-bit is also set, then the negative zero must be changed to positive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -