^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) | binstr.sa 3.3 12/19/90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | Description: Converts a 64-bit binary integer to bcd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | Input: 64-bit binary integer in d2:d3, desired length (LEN) in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | d0, and a pointer to start in memory for bcd characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | in d0. (This pointer must point to byte 4 of the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | lword of the packed decimal memory string.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | Output: LEN bcd digits representing the 64-bit integer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) | Algorithm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) | The 64-bit binary is assumed to have a decimal point before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | bit 63. The fraction is multiplied by 10 using a mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) | shift and a mul by 8 shift. The bits shifted out of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | msb form a decimal digit. This process is iterated until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | LEN digits are formed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | A1. Init d7 to 1. D7 is the byte digit counter, and if 1, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) | digit formed will be assumed the least significant. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | to force the first byte formed to have a 0 in the upper 4 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | A2. Beginning of the loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) | Copy the fraction in d2:d3 to d4:d5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) | A3. Multiply the fraction in d2:d3 by 8 using bit-field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) | extracts and shifts. The three msbs from d2 will go into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) | d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) | A4. Multiply the fraction in d4:d5 by 2 using shifts. The msb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) | will be collected by the carry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) | A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) | into d2:d3. D1 will contain the bcd digit formed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) | A6. Test d7. If zero, the digit formed is the ms digit. If non-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) | zero, it is the ls digit. Put the digit in its place in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) | upper word of d0. If it is the ls digit, write the word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) | from d0 to memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) | A7. Decrement d6 (LEN counter) and repeat the loop until zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) | Implementation Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) | The registers are used as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) | d0: LEN counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) | d1: temp used to form the digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) | d2: upper 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) | d3: lower 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) | d4: upper 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) | d5: lower 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) | d6: temp for bit-field extracts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) | d7: byte digit formation word;digit count {0,1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) | a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) | Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) | All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) | For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) | file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) |BINSTR idnt 2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) |section 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .global binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) binstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) moveml %d0-%d7,-(%a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) | A1: Init d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) moveql #1,%d7 |init d7 for second digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) subql #1,%d0 |for dbf d0 would have LEN+1 passes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) | A2. Copy d2:d3 to d4:d5. Start loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) movel %d2,%d4 |copy the fraction before muls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) movel %d3,%d5 |to d4:d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) | A3. Multiply d2:d3 by 8; extract msbs into d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bfextu %d2{#0:#3},%d1 |copy 3 msbs of d2 into d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) asll #3,%d2 |shift d2 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bfextu %d3{#0:#3},%d6 |copy 3 msbs of d3 into d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) asll #3,%d3 |shift d3 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) orl %d6,%d2 |or in msbs from d3 into d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) | A4. Multiply d4:d5 by 2; add carry out to d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) asll #1,%d5 |mul d5 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) roxll #1,%d4 |mul d4 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) swap %d6 |put 0 in d6 lower word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) addxw %d6,%d1 |add in extend from mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) | A5. Add mul by 8 to mul by 2. D1 contains the digit formed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) addl %d5,%d3 |add lower 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) nop |ERRATA ; FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) addxl %d4,%d2 |add with extend upper 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) nop |ERRATA ; FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) addxw %d6,%d1 |add in extend from add to d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) swap %d6 |with d6 = 0; put 0 in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) | A6. Test d7 and branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tstw %d7 |if zero, store digit & to loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) beqs first_d |if non-zero, form byte & write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) sec_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) swap %d7 |bring first digit to word d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) aslw #4,%d7 |first digit in upper 4 bits d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) addw %d1,%d7 |add in ls digit to d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) moveb %d7,(%a0)+ |store d7b byte in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) swap %d7 |put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) clrw %d7 |set d7a to signal no digits done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dbf %d0,loop |do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) bras end_bstr |finished, so exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) first_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) swap %d7 |put digit word in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) movew %d1,%d7 |put new digit in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) swap %d7 |put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) addqw #1,%d7 |set d7a to signal first digit done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dbf %d0,loop |do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) swap %d7 |put last digit in string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) lslw #4,%d7 |move it to upper 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) moveb %d7,(%a0)+ |store it in memory string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) | Clean up and return with result in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) end_bstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) moveml (%a7)+,%d0-%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) |end