📄 vaxarith.s
字号:
# # r6 and r7 are modified by this routine # # r0, r2, r4, and r9 (and, of course, r10 and r11) are preserved # by this routine # # assumptions: # # this routine makes two important assumptions. # # 1. if both of the input bytes contain only legal decimal digits, then # it is only necessary to subtract 100 at most once to put all # possible sums in the range 0..99. that is, # # 99 + 99 + 1 = 199 lss 200 # # 2. the result will be checked in some way to determine whether the # result is nonzero so that the z-bit can have its correct setting. #-add_packed_byte_string: # mark_point add_sub_bsbw_24 .text 2 .set table_size,table_size + 1 .word Ladd_sub_bsbw_24 - module_base .text 3 .word add_sub_bsbw_24 - module_base .textLadd_sub_bsbw_24: movzbl -(r1),r6 # get byte from first string # mark_point add_sub_bsbw_24_a .text 2 .set table_size,table_size + 1 .word Ladd_sub_bsbw_24_a - module_base .text 3 .word add_sub_bsbw_24 - module_base .textLadd_sub_bsbw_24_a: movzbl -(r3),r7 # get byte from second string .globl vax$add_packed_byte_r6_r7vax$add_packed_byte_r6_r7: # ashp also uses this routineadd_packed_byte_r6_r7: movb decimal$packed_to_binary_table[r6],r6 # convert digits to binary movb decimal$packed_to_binary_table[r7],r7 # convert digits to binary addb2 r6,r7 # form their sum addb2 r8,r7 # add carry from last step clrb r8 # assume no carry this time cmpb r7,$99 # check for carry blequ 1f # branch if within bounds movb $1,r8 # propogate carry to next step subb2 $100,r7 # put r7 into interval 0..991: movb decimal$binary_to_packed_table[r7],-(r5) # store converted sum byte rsb # #+ # functional description: # # this routine takes two packed decimal strings whose descriptors # are passed as input parameters, subtracts one string from the # other, and places their sum into another (perhaps identical) # packed decimal string. # # at the present time, the result is placed into a 16-byte storage # area while the difference is being evaluated. this drastically reduces # the number of different cases that must be dealt with as each # pair of bytes in the two input strings is added. # # the signs of the two input strings have already been dealt with so # this routine performs subtraction in all cases, even if the original # entry was at addp4 or addp6. # # input parameters: # # r0<4:0> - number of digits in first input decimal string # r1 - address of least significant digit of first input # decimal string (the byte containing the sign) # # r2<4:0> - number of digits in second input decimal string # r3 - address of least significant digit of second input # decimal string (the byte containing the sign) # # r4<4:0> - number of digits in output decimal string # r5 - address of one byte beyond least significant digit of # intermediate string stored on the stack # # r6<3:0> - sign of first input string in preferred form # r7<3:0> - sign of second input string in preferred form # # r11 - saved psl (z-bit is set, other condition codes are clear) # # (sp) - saved r5, address of least significant digit of ultimate # destination string. # 4(sp) - beginning of 20-byte buffer to hold intermediate result # # output parameters: # # the particular input operation (addpx or subpx) is completed in # this routine. see the routine headers for the four routines that # request addition or subtraction for a list of output parameters # from this routine. # # algorithm for choice of sign: # # the choice of sign for the output string is not nearly so # straightforward as it is in the case of addition. one approach that is # often taken is to make a reasonable guess at the sign of the result. # if the final subtraction causes a borrow, then the choice was incorrect. # the sign must be changed and the result must be replaced by its tens # complement. # # this routine does not guess. instead, it chooses the input string of # the larger absolute magnitude as the minuend for this internal # routine and chooses its sign as the sign of the result. # this algorithm is actually more efficient than the reasonable # guess method and is probably better than a guess method that is never # wrong. all complete bytes that are processed in the sign evaluation # preprocessing loop are eliminated from consideration in the # subtraction loop, which has a higher cost per byte. # # the actual algorithm is as follows. (note that both input strings have # already had leading zeros stripped so their lengths reflect # significant digits.) # # 1. if the two strings have unequal lengths, then choose the sign of # the string that has the longer length. # # 2. for strings of equal length, choose the sign of the string whose # most significant byte is larger in magnitude. # # 3. if the most significant bytes test equal, then decrease the # lengths of each string by one byte, drop the previous most # significant bytes, and go back to step 2. # # 4. if the two strings test equal, it is not necessary to do any # subtraction. the result is identically zero. # # note that the key to this routine's efficiency is that high order # bytes that test equal in this loop are dropped from consideration in # the more complicated subtraction loop. #-subtract_packed: extzv $1,$4,r0,r0 # convert digit count to byte count extzv $1,$4,r2,r2 # do it for both strings cmpl r0,r2 # we want to compare the byte counts blssu 4f # r0/r1 represent the smaller string bgtru 3f # r2/r3 represent the smaller string # the two input strings have an equal number of bytes. compare magnitudes to # determine which string is really larger. if the two strings test equal, then # skip the entire subtraction loop. subl3 r0,r1,r8 # point r8 to low address end of r0/r1 subl3 r2,r3,r9 # point r9 to low address end of r2/r3 tstl r0 # see if both strings have zero bytes beql 2f # still need to check low order digit # mark_point add_sub_24_g .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_g - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_g:1: cmpb (r8)+,(r9)+ # compare most significant bytes blssu 4f # r0/r1 represent the smaller string bgtru 3f # r2/r3 represent the smaller string decl r2 # keep r2 in step with r0 sobgtr r0,1b # ... which gets decremented here # at this point, we have reduced both input strings to single bytes that # contain a sign "digit" and may contain a digit in the high order nibble # if the original digit counts were nonzero. # mark_point add_sub_24_h .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_h - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_h:2: bicb3 $0x0f,(r8),r8 # look only at digit, ignoring sign # mark_point add_sub_24_i .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_i - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_i: bicb3 $0x0f,(r9),r9 # get the digit from the other string cmpb r8,r9 # compare these digits blssu 4f # r0/r1 represent the smaller string bgtru 3f # r2/r3 represent the smaller string # the two strings have identical magnitudes. enter the end processing code # with the intermediate result unchanged (that is, zero). brw add_subtract_exit # join the common completion code # the string described by r0 and r1 has the larger magnitude. choose its sign. # then swap the two string descriptors so that the main subtraction loops # always have r2 and r3 describing the larger string. note that the use of # r6 and r7 as scratch leaves r7<31:8> in an unpredictable state. 3: movb r6,r9 # load preferred sign into r9 movq r0,r6 # save the longer movq r2,r0 # store the shorter on r0 and r1 movq r6,r2 # ... and store the longer in r2 and r3 clrl r7 # insure that r7<31:8> is zero brb 5f # continue along common code path # the string described by r2 and r3 has the larger magnitude. choose its sign.4: movb r7,r9 # load preferred sign into r95: subl2 r0,r2 # make r2 a difference (r2 gequ 0) blbc r9,6f # check if sign is negative bisb2 $psl$m_n,r11 # ... so the saved n-bit can be set # mark_point add_sub_24_j .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_j - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_j:6: bicb3 $0x0f,(r1),r6 # get least significant digit to r6 # mark_point add_sub_24_k .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_k - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_k: bicb3 $0x0f,(r3),r7 # get least significant digit to r7 clrl r8 # start subtracting with borrow off bsbw sub_packed_byte_r6_r7 # subtract the two low order digits # r0 contains the number of bytes remaining in the smaller string # r2 contains the difference in bytes between the two input strings tstl r0 # does smaller string have any room? beql 8f # skip loop if no room at all7: bsbw sub_packed_byte_string # subtract the next two bytes sobgtr r0,7b # check for end of loop8: tstl r2 # does one of the strings have more? beql L110 # skip next loops if all done9: blbc r8,0f # life is simple if borrow clear clrl r6 # otherwise, borrow must propogate # mark_point add_sub_24_l .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_l - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_l: movzbl -(r3),r7 # so subtract borrow from single string bsbw sub_packed_byte_r6_r7 # use the special entry point sobgtr r2,9b # check for this string exhausted brb L110 # join common completion code # mark_point add_sub_24_m .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_m - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_m:0: movb -(r3),-(r5) # simply move src to dst if no borrow sobgtr r2,0b # ... until we're all doneL110: ### ********** begin temp ********** ### ### The following halt instruction should be replaced with the correct ### abort code. ### ### The halt is similar to the ### ### microcode cannot get here ### ### errors that other implementations use. ### tstl r8 # if borrow is set here, we blew it beql 1f # branch out if ok halt # this will cause an opcdec exception1: ### ### *********** end temp *********** brw add_subtract_exit # join common completion code # #+ # functional description: # # this routine takes as input two bytes containing decimal digits and # produces a byte containing their difference. this result is stored in # the output string. each of the input bytes is converted to a binary # number (with a table-driven conversion), the first number is # subtracted from the second, and the difference is converted back to # two decimal digits stored in a byte. # # this routine makes no provisions for bytes that contain illegal # decimal digits. we are using the unpredictable statement in the # architectural description of the decimal instructions to its fullest. # # the bytes that contain a pair of packed decimal digits can either # exist in packed decimal strings located by r1 and r3 or they can # be stored directly in registers. in the former case, the digits must # be extracted from registers before they can be used in later operations # because the difference will be used as an index register. # # for entry at sub_packed_byte_string: # # input parameters: # # r1 - address one byte beyond byte containing subtrahend # r3 - address one byte beyond byte containing minuend # r5 - address one byte beyond location to store difference # # r8 - borrow from previous byte (r8 is either 0 or 1) # # implicit input: # # r6 - scratch # r7 - scratch # # output parameters: # # r1 - decreased by one to point to current byte # in subtrahend string # r3 - decreased by one to point to current byte # in minuend string # r5 - decreased by one to point to current byte # in difference string # # r8 - either 0 or 1, reflecting whether this most recent # subtraction resulted in a borrow from the next byte. # # for entry at sub_packed_byte_r6_r7: # # input parameters: # # r6<7:0> - byte containing decimal digit pair for subtrahend # r6<31:8> - mbz # r7<7:0> - byte containing decimal digit pair for minuend # r7<31:8> - mbz # # r5 - address one byte beyond location to store difference # # r8 - borrow from subtraction of previous byte # (r8 is either 0 or 1) # # output parameters: # # r5 - decreased by one to point to current byte # in difference string # # r8 - either 0 or 1, reflecting whether this most recent # subtraction resulted in a borrow from the next byte. # # side effects: # # r6 and r7 are modified by this routine # # r0, r2, r4, and r9 (and, of course, r10 and r11) are preserved
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -