📄 vaxarith.s
字号:
.set table_size,table_size + 1 .word Ladd_sub_bsbw_0 - module_base .text 3 .word add_sub_bsbw_0 - module_base .textLadd_sub_bsbw_0: jsb decimal$strip_zeros_r2_r3 # strip high order zeros from r2/r3 string # roprand_check r0 # insure that r0 is lequ 31 cmpw r2,$31 blequ 1f brw decimal_roprand1: movzwl r2,r2 # mark_point add_sub_bsbw_0_a .text 2 .set table_size,table_size + 1 .word Ladd_sub_bsbw_0_a - module_base .text 3 .word add_sub_bsbw_0 - module_base .textLadd_sub_bsbw_0_a: jsb decimal$strip_zeros_r0_r1 # strip high order zeros from r0/r1 string # rather than totally confuse the already complicated logic dealing with # different length strings in the add or subtract loop, we will put the # result into an intermediate buffer on the stack. this buffer will be long # enough to handle the worst case so that the addition loop need only concern # itself with the lengths of the two input loops. the required length is 17 # bytes, to handle an addition with a carry out of the most significant byte. # we will allocate 20 bytes to maintain whatever alignment the stack has. clrq -(sp) # set aside space for output string clrq -(sp) # worst case string needs 16 bytes clrl -(sp) # add slack for a carry extzv $1,$4,r4,r8 # get byte count of destination string addl3 r8,r5,-(sp) # save high address end of destination movab 24(sp),r5 # point r5 one byte beyond buffer # the number of minus signs will determine whether the real operation that we # perform is addition or subtraction. that is, two plus signs or two minus # signs will both result in addition, while a plus sign and a minus sign will # result in subtraction. the addition and subtraction routines have their own # methods for determining the correct sign of the result. # # for the purpose of counting minus signs, we treat subtraction as the # addition of the negative of the input operand. that is, subtraction of a # positive quantity causes the sign to be remembered as minus and counted as # a minus sign while subtraction of a minus quantity stores a plus sign and # counts nothing. # # on input to this code sequence, r9 distinguished addition from subtraction. # on output, it contains either 0, 1, or 2, indicating the total number of # minus signs, real or implied, that we counted. extzv $1,$4,r0,r6 # get byte count for first input string addl2 r6,r1 # point r1 to byte containing sign # mark_point add_sub_24 .text 2 .set table_size,table_size + 1 .word Ladd_sub_24 - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24: bicb3 $0x0f0,(r1),r6 # r6 contains the sign "digit" blbs r9,L35 # use second case if subtraction # this case statement is used for addition caseb r6,$10,$15-10 # dispatch on sign digitL1: .word 5f-L1 # 10 => sign is "+" .word 4f-L1 # 11 => sign is "-" .word 5f-L1 # 12 => sign is "+" .word 4f-L1 # 13 => sign is "-" .word 5f-L1 # 14 => sign is "+" .word 5f-L1 # 15 => sign is "+" # this case statement is used for subtractionL35: caseb r6,$10,$15-10 # dispatch on sign digitL2: .word 4f-L2 # 10 => treat sign as "-" .word 5f-L2 # 11 => treat sign as "+" .word 4f-L2 # 12 => treat sign as "-" .word 5f-L2 # 13 => treat sign as "+" .word 4f-L2 # 14 => treat sign as "-" .word 4f-L2 # 15 => treat sign as "-"4: movl $1,r9 # count a minus sign movzbl $13,r6 # the preferred minus sign is 13 brb 6f # now check second input sign5: clrl r9 # no real minus signs so far movzbl $12,r6 # the preferred minus sign is 126: extzv $1,$4,r2,r7 # get byte count for second input string addl2 r7,r3 # point r3 to byte containing sign # mark_point add_sub_24_a .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_a - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_a: bicb3 $0x0f0,(r3),r7 # r7 contains the sign "digit" caseb r7,$10,$15-10 # dispatch on sign digitL3: .word 8f-L3 # 10 => sign is "+" .word 7f-L3 # 11 => sign is "-" .word 8f-L3 # 12 => sign is "+" .word 7f-L3 # 13 => sign is "-" .word 8f-L3 # 14 => sign is "+" .word 8f-L3 # 15 => sign is "+"7: incl r9 # remember that sign was minus movzbl $13,r7 # the preferred minus sign is 13 brb 9f # now check second input sign8: movzbl $12,r7 # the preferred minus sign is 129: blbc r9,add_packed # even parity indicates addition brw subtract_packed # odd parity calls for subtraction # #+ # functional description: # # this routine adds two packed decimal strings whose descriptors # are passed as input parameters 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 sum 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 addition in all cases, even if the original # entry was at subp4 or subp6. the cases that arrive in this routine # are as follows. # # r2/r3 r0/r1 result # +---------------+---------------+---------------+ # | | | | # r2/r3 + r0/r1 | plus | plus | plus | # | | | | # +---------------+---------------+---------------+ # | | | | # r2/r3 + r0/r1 | minus | minus | minus | # | | | | # +---------------+---------------+---------------+ # | | | | # r2/r3 - r0/r1 | minus | plus | minus | # | | | | # +---------------+---------------+---------------+ # | | | | # r2/r3 - r0/r1 | plus | minus | plus | # | | | | # +---------------+---------------+---------------+ # # note that the correct choice of sign in all four cases is the sign # of the second input string, the one described by r2 and r3. # # 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. #-add_packed: movb r7,r9 # use sign of second string for output blbc r9,1f # check if sign is negative bisb2 $psl$m_n,r11 # ... so the saved n-bit can be set # mark_point add_sub_24_b .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_b - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_b:1: bicb3 $0x0f,(r1),r6 # get least significant digit to r6 # mark_point add_sub_24_c .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_c - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_c: bicb3 $0x0f,(r3),r7 # get least significant digit to r7 clrl r8 # start the add with carry off bsbw add_packed_byte_r6_r7 # add the two low order digits # the following set of instructions computes the number of bytes in the two # strings and, if necessary, performs a switch so that r0 and r1 always # describe the shorter of the two strings. 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 blequ 2f # skip the swap if we're already correct 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 r32: subl2 r0,r2 # make r2 a difference (r2 gequ 0) # r0 now contains the number of bytes remaining in the shorter string. # r2 contains the difference in bytes between the two input strings. tstl r0 # does shorter string have any room? beql 4f # skip loop if no room at all3: bsbw add_packed_byte_string # add the next two bytes together sobgtr r0,3b # check for end of loop4: tstl r2 # does longer string have any room? beql 7f # skip next loops if all done5: blbc r8,6f # life is simple if carry clear clrl r6 # otherwise, carry must propogate # mark_point add_sub_24_d .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_d - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_d: movzbl -(r3),r7 # so add carry to single string bsbw add_packed_byte_r6_r7 # use the special entry point sobgtr r2,5b # check for this string exhausted brb 7f # join common completion code # mark_point add_sub_24_e .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_e - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_e:6: movb -(r3),-(r5) # simply move src to dst if no carry sobgtr r2,6b # ... until we're all done7: movb r8,-(r5) # store the final carry #+ # at this point, the result has been computed. that result must be moved to # its ultimate destination, noting whether any nonzero digits are stored # so that the z-bit will have its correct setting. # # input parameters: # # r9<7:0> - sign of result in preferred form # r11<3:0> - saved condition codes # r11<31> - indicates whether to set saved r4 to zero # # (sp) - saved r5, high address end of destination string #-add_subtract_exit: addl3 $1,(sp),r5 # point r5 beyond real destination movab 24(sp),r1 # r1 locates the saved result bsbw store_result # store the result and record the z-bit bbs $psl$v_z,r11,0f # step out of line for minus zero check # mark_point add_sub_24_f .text 2 .set table_size,table_size + 1 .word Ladd_sub_24_f - module_base .text 3 .word add_sub_24 - module_base .textLadd_sub_24_f:8: insv r9,$0,$4,*(sp)+ # the sign can finally be stored addl2 $20,sp # get rid of intermediate buffer bbc $add_sub_v_zero_r4,r11,9f # branch if 4-operand opcode clrl 16(sp) # clear saved r4 to return zero9: jmp vax$decimal_exit # exit through common code path # if the result is negative zero, then the n-bit is cleared and the sign # is changed to a plus sign.0: bicb2 $psl$m_n,r11 # clear the n-bit unconditionally bbs $psl$v_v,r11,8b # do not change the sign on overflow movb $12,r9 # make sure that the sign is plus brb 8b # ... and rejoin the exit code # #+ # functional description: # # this routine adds together two bytes containing decimal digits and # produces a byte containing the sum that is stored in the output # string. each of the input bytes is converted to a binary number # (with a table-driven conversion), the two numbers are added, and # the sum 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 sum will be used as an index register. # # for entry at add_packed_byte_string: # # input parameters: # # r1 - address one byte beyond first byte that is to be added # r3 - address one byte beyond second byte that is to be added # r5 - address one byte beyond location to store sum # # r8 - carry 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 first input string # r3 - decreased by one to point to current byte in second input string # r5 - decreased by one to point to current byte in output string # # r8 - either 0 or 1, reflecting whether this most recent add resulted # in a carry to the next byte. # # for entry at add_packed_byte_r6_r7: # # input parameters: # # r6 - first byte containing decimal digit pair # r7 - second byte containing decimal digit pair # # r5 - address one byte beyond location to store sum # # r8 - carry from previous byte (r8 is either 0 or 1) # # output parameters: # # r5 - decreased by one to point to current byte in output string # # r8 - either 0 or 1, reflecting whether this most recent add resulted # in a carry to the next byte. # # side effects:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -