18c2ecf20Sopenharmony_ci|
28c2ecf20Sopenharmony_ci|	binstr.sa 3.3 12/19/90
38c2ecf20Sopenharmony_ci|
48c2ecf20Sopenharmony_ci|
58c2ecf20Sopenharmony_ci|	Description: Converts a 64-bit binary integer to bcd.
68c2ecf20Sopenharmony_ci|
78c2ecf20Sopenharmony_ci|	Input: 64-bit binary integer in d2:d3, desired length (LEN) in
88c2ecf20Sopenharmony_ci|          d0, and a  pointer to start in memory for bcd characters
98c2ecf20Sopenharmony_ci|          in d0. (This pointer must point to byte 4 of the first
108c2ecf20Sopenharmony_ci|          lword of the packed decimal memory string.)
118c2ecf20Sopenharmony_ci|
128c2ecf20Sopenharmony_ci|	Output:	LEN bcd digits representing the 64-bit integer.
138c2ecf20Sopenharmony_ci|
148c2ecf20Sopenharmony_ci|	Algorithm:
158c2ecf20Sopenharmony_ci|		The 64-bit binary is assumed to have a decimal point before
168c2ecf20Sopenharmony_ci|		bit 63.  The fraction is multiplied by 10 using a mul by 2
178c2ecf20Sopenharmony_ci|		shift and a mul by 8 shift.  The bits shifted out of the
188c2ecf20Sopenharmony_ci|		msb form a decimal digit.  This process is iterated until
198c2ecf20Sopenharmony_ci|		LEN digits are formed.
208c2ecf20Sopenharmony_ci|
218c2ecf20Sopenharmony_ci|	A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the
228c2ecf20Sopenharmony_ci|		digit formed will be assumed the least significant.  This is
238c2ecf20Sopenharmony_ci|		to force the first byte formed to have a 0 in the upper 4 bits.
248c2ecf20Sopenharmony_ci|
258c2ecf20Sopenharmony_ci|	A2. Beginning of the loop:
268c2ecf20Sopenharmony_ci|		Copy the fraction in d2:d3 to d4:d5.
278c2ecf20Sopenharmony_ci|
288c2ecf20Sopenharmony_ci|	A3. Multiply the fraction in d2:d3 by 8 using bit-field
298c2ecf20Sopenharmony_ci|		extracts and shifts.  The three msbs from d2 will go into
308c2ecf20Sopenharmony_ci|		d1.
318c2ecf20Sopenharmony_ci|
328c2ecf20Sopenharmony_ci|	A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb
338c2ecf20Sopenharmony_ci|		will be collected by the carry.
348c2ecf20Sopenharmony_ci|
358c2ecf20Sopenharmony_ci|	A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5
368c2ecf20Sopenharmony_ci|		into d2:d3.  D1 will contain the bcd digit formed.
378c2ecf20Sopenharmony_ci|
388c2ecf20Sopenharmony_ci|	A6. Test d7.  If zero, the digit formed is the ms digit.  If non-
398c2ecf20Sopenharmony_ci|		zero, it is the ls digit.  Put the digit in its place in the
408c2ecf20Sopenharmony_ci|		upper word of d0.  If it is the ls digit, write the word
418c2ecf20Sopenharmony_ci|		from d0 to memory.
428c2ecf20Sopenharmony_ci|
438c2ecf20Sopenharmony_ci|	A7. Decrement d6 (LEN counter) and repeat the loop until zero.
448c2ecf20Sopenharmony_ci|
458c2ecf20Sopenharmony_ci|	Implementation Notes:
468c2ecf20Sopenharmony_ci|
478c2ecf20Sopenharmony_ci|	The registers are used as follows:
488c2ecf20Sopenharmony_ci|
498c2ecf20Sopenharmony_ci|		d0: LEN counter
508c2ecf20Sopenharmony_ci|		d1: temp used to form the digit
518c2ecf20Sopenharmony_ci|		d2: upper 32-bits of fraction for mul by 8
528c2ecf20Sopenharmony_ci|		d3: lower 32-bits of fraction for mul by 8
538c2ecf20Sopenharmony_ci|		d4: upper 32-bits of fraction for mul by 2
548c2ecf20Sopenharmony_ci|		d5: lower 32-bits of fraction for mul by 2
558c2ecf20Sopenharmony_ci|		d6: temp for bit-field extracts
568c2ecf20Sopenharmony_ci|		d7: byte digit formation word;digit count {0,1}
578c2ecf20Sopenharmony_ci|		a0: pointer into memory for packed bcd string formation
588c2ecf20Sopenharmony_ci|
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
618c2ecf20Sopenharmony_ci|			All Rights Reserved
628c2ecf20Sopenharmony_ci|
638c2ecf20Sopenharmony_ci|       For details on the license for this file, please see the
648c2ecf20Sopenharmony_ci|       file, README, in this same directory.
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci|BINSTR    idnt    2,1 | Motorola 040 Floating Point Software Package
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	|section	8
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#include "fpsp.h"
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	.global	binstr
738c2ecf20Sopenharmony_cibinstr:
748c2ecf20Sopenharmony_ci	moveml	%d0-%d7,-(%a7)
758c2ecf20Sopenharmony_ci|
768c2ecf20Sopenharmony_ci| A1: Init d7
778c2ecf20Sopenharmony_ci|
788c2ecf20Sopenharmony_ci	moveql	#1,%d7			|init d7 for second digit
798c2ecf20Sopenharmony_ci	subql	#1,%d0			|for dbf d0 would have LEN+1 passes
808c2ecf20Sopenharmony_ci|
818c2ecf20Sopenharmony_ci| A2. Copy d2:d3 to d4:d5.  Start loop.
828c2ecf20Sopenharmony_ci|
838c2ecf20Sopenharmony_ciloop:
848c2ecf20Sopenharmony_ci	movel	%d2,%d4			|copy the fraction before muls
858c2ecf20Sopenharmony_ci	movel	%d3,%d5			|to d4:d5
868c2ecf20Sopenharmony_ci|
878c2ecf20Sopenharmony_ci| A3. Multiply d2:d3 by 8; extract msbs into d1.
888c2ecf20Sopenharmony_ci|
898c2ecf20Sopenharmony_ci	bfextu	%d2{#0:#3},%d1		|copy 3 msbs of d2 into d1
908c2ecf20Sopenharmony_ci	asll	#3,%d2			|shift d2 left by 3 places
918c2ecf20Sopenharmony_ci	bfextu	%d3{#0:#3},%d6		|copy 3 msbs of d3 into d6
928c2ecf20Sopenharmony_ci	asll	#3,%d3			|shift d3 left by 3 places
938c2ecf20Sopenharmony_ci	orl	%d6,%d2			|or in msbs from d3 into d2
948c2ecf20Sopenharmony_ci|
958c2ecf20Sopenharmony_ci| A4. Multiply d4:d5 by 2; add carry out to d1.
968c2ecf20Sopenharmony_ci|
978c2ecf20Sopenharmony_ci	asll	#1,%d5			|mul d5 by 2
988c2ecf20Sopenharmony_ci	roxll	#1,%d4			|mul d4 by 2
998c2ecf20Sopenharmony_ci	swap	%d6			|put 0 in d6 lower word
1008c2ecf20Sopenharmony_ci	addxw	%d6,%d1			|add in extend from mul by 2
1018c2ecf20Sopenharmony_ci|
1028c2ecf20Sopenharmony_ci| A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
1038c2ecf20Sopenharmony_ci|
1048c2ecf20Sopenharmony_ci	addl	%d5,%d3			|add lower 32 bits
1058c2ecf20Sopenharmony_ci	nop				|ERRATA ; FIX #13 (Rev. 1.2 6/6/90)
1068c2ecf20Sopenharmony_ci	addxl	%d4,%d2			|add with extend upper 32 bits
1078c2ecf20Sopenharmony_ci	nop				|ERRATA ; FIX #13 (Rev. 1.2 6/6/90)
1088c2ecf20Sopenharmony_ci	addxw	%d6,%d1			|add in extend from add to d1
1098c2ecf20Sopenharmony_ci	swap	%d6			|with d6 = 0; put 0 in upper word
1108c2ecf20Sopenharmony_ci|
1118c2ecf20Sopenharmony_ci| A6. Test d7 and branch.
1128c2ecf20Sopenharmony_ci|
1138c2ecf20Sopenharmony_ci	tstw	%d7			|if zero, store digit & to loop
1148c2ecf20Sopenharmony_ci	beqs	first_d			|if non-zero, form byte & write
1158c2ecf20Sopenharmony_cisec_d:
1168c2ecf20Sopenharmony_ci	swap	%d7			|bring first digit to word d7b
1178c2ecf20Sopenharmony_ci	aslw	#4,%d7			|first digit in upper 4 bits d7b
1188c2ecf20Sopenharmony_ci	addw	%d1,%d7			|add in ls digit to d7b
1198c2ecf20Sopenharmony_ci	moveb	%d7,(%a0)+		|store d7b byte in memory
1208c2ecf20Sopenharmony_ci	swap	%d7			|put LEN counter in word d7a
1218c2ecf20Sopenharmony_ci	clrw	%d7			|set d7a to signal no digits done
1228c2ecf20Sopenharmony_ci	dbf	%d0,loop		|do loop some more!
1238c2ecf20Sopenharmony_ci	bras	end_bstr		|finished, so exit
1248c2ecf20Sopenharmony_cifirst_d:
1258c2ecf20Sopenharmony_ci	swap	%d7			|put digit word in d7b
1268c2ecf20Sopenharmony_ci	movew	%d1,%d7			|put new digit in d7b
1278c2ecf20Sopenharmony_ci	swap	%d7			|put LEN counter in word d7a
1288c2ecf20Sopenharmony_ci	addqw	#1,%d7			|set d7a to signal first digit done
1298c2ecf20Sopenharmony_ci	dbf	%d0,loop		|do loop some more!
1308c2ecf20Sopenharmony_ci	swap	%d7			|put last digit in string
1318c2ecf20Sopenharmony_ci	lslw	#4,%d7			|move it to upper 4 bits
1328c2ecf20Sopenharmony_ci	moveb	%d7,(%a0)+		|store it in memory string
1338c2ecf20Sopenharmony_ci|
1348c2ecf20Sopenharmony_ci| Clean up and return with result in fp0.
1358c2ecf20Sopenharmony_ci|
1368c2ecf20Sopenharmony_ciend_bstr:
1378c2ecf20Sopenharmony_ci	moveml	(%a7)+,%d0-%d7
1388c2ecf20Sopenharmony_ci	rts
1398c2ecf20Sopenharmony_ci	|end
140