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