xref: /netbsd/sys/arch/m68k/fpsp/binstr.sa (revision bf9ec67e)
1*	$NetBSD: binstr.sa,v 1.3 1994/10/26 07:48:53 cgd Exp $
2
3*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4*	M68000 Hi-Performance Microprocessor Division
5*	M68040 Software Package
6*
7*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8*	All rights reserved.
9*
10*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
11*	To the maximum extent permitted by applicable law,
12*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
13*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
14*	PARTICULAR PURPOSE and any warranty against infringement with
15*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
16*	and any accompanying written materials.
17*
18*	To the maximum extent permitted by applicable law,
19*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
20*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
21*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
22*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
23*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
24*	and support of the SOFTWARE.
25*
26*	You are hereby granted a copyright license to use, modify, and
27*	distribute the SOFTWARE so long as this entire notice is retained
28*	without alteration in any modified and/or redistributed versions,
29*	and that such modified versions are clearly identified as such.
30*	No licenses are granted by implication, estoppel or otherwise
31*	under any patents or trademarks of Motorola, Inc.
32
33*
34*	binstr.sa 3.3 12/19/90
35*
36*
37*	Description: Converts a 64-bit binary integer to bcd.
38*
39*	Input: 64-bit binary integer in d2:d3, desired length (LEN) in
40*          d0, and a  pointer to start in memory for bcd characters
41*          in d0. (This pointer must point to byte 4 of the first
42*          lword of the packed decimal memory string.)
43*
44*	Output:	LEN bcd digits representing the 64-bit integer.
45*
46*	Algorithm:
47*		The 64-bit binary is assumed to have a decimal point before
48*		bit 63.  The fraction is multiplied by 10 using a mul by 2
49*		shift and a mul by 8 shift.  The bits shifted out of the
50*		msb form a decimal digit.  This process is iterated until
51*		LEN digits are formed.
52*
53*	A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the
54*		digit formed will be assumed the least significant.  This is
55*		to force the first byte formed to have a 0 in the upper 4 bits.
56*
57*	A2. Beginning of the loop:
58*		Copy the fraction in d2:d3 to d4:d5.
59*
60*	A3. Multiply the fraction in d2:d3 by 8 using bit-field
61*		extracts and shifts.  The three msbs from d2 will go into
62*		d1.
63*
64*	A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb
65*		will be collected by the carry.
66*
67*	A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5
68*		into d2:d3.  D1 will contain the bcd digit formed.
69*
70*	A6. Test d7.  If zero, the digit formed is the ms digit.  If non-
71*		zero, it is the ls digit.  Put the digit in its place in the
72*		upper word of d0.  If it is the ls digit, write the word
73*		from d0 to memory.
74*
75*	A7. Decrement d6 (LEN counter) and repeat the loop until zero.
76*
77*	Implementation Notes:
78*
79*	The registers are used as follows:
80*
81*		d0: LEN counter
82*		d1: temp used to form the digit
83*		d2: upper 32-bits of fraction for mul by 8
84*		d3: lower 32-bits of fraction for mul by 8
85*		d4: upper 32-bits of fraction for mul by 2
86*		d5: lower 32-bits of fraction for mul by 2
87*		d6: temp for bit-field extracts
88*		d7: byte digit formation word;digit count {0,1}
89*		a0: pointer into memory for packed bcd string formation
90*
91
92BINSTR    IDNT    2,1 Motorola 040 Floating Point Software Package
93
94	section	8
95
96	include	fpsp.h
97
98	xdef	binstr
99binstr:
100	movem.l	d0-d7,-(a7)
101*
102* A1: Init d7
103*
104	moveq.l	#1,d7			;init d7 for second digit
105	subq.l	#1,d0			;for dbf d0 would have LEN+1 passes
106*
107* A2. Copy d2:d3 to d4:d5.  Start loop.
108*
109loop:
110	move.l	d2,d4			;copy the fraction before muls
111	move.l	d3,d5			;to d4:d5
112*
113* A3. Multiply d2:d3 by 8; extract msbs into d1.
114*
115	bfextu	d2{0:3},d1		;copy 3 msbs of d2 into d1
116	asl.l	#3,d2			;shift d2 left by 3 places
117	bfextu	d3{0:3},d6		;copy 3 msbs of d3 into d6
118	asl.l	#3,d3			;shift d3 left by 3 places
119	or.l	d6,d2			;or in msbs from d3 into d2
120*
121* A4. Multiply d4:d5 by 2; add carry out to d1.
122*
123	add.l	d5,d5			;mul d5 by 2
124	addx.l	d4,d4			;mul d4 by 2
125	swap	d6			;put 0 in d6 lower word
126	addx.w	d6,d1			;add in extend from mul by 2
127*
128* A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
129*
130	add.l	d5,d3			;add lower 32 bits
131	nop				;ERRATA FIX #13 (Rev. 1.2 6/6/90)
132	addx.l	d4,d2			;add with extend upper 32 bits
133	nop				;ERRATA FIX #13 (Rev. 1.2 6/6/90)
134	addx.w	d6,d1			;add in extend from add to d1
135	swap	d6			;with d6 = 0; put 0 in upper word
136*
137* A6. Test d7 and branch.
138*
139	tst.w	d7			;if zero, store digit & to loop
140	beq.b	first_d			;if non-zero, form byte & write
141sec_d:
142	swap	d7			;bring first digit to word d7b
143	asl.w	#4,d7			;first digit in upper 4 bits d7b
144	add.w	d1,d7			;add in ls digit to d7b
145	move.b	d7,(a0)+		;store d7b byte in memory
146	swap	d7			;put LEN counter in word d7a
147	clr.w	d7			;set d7a to signal no digits done
148	dbf.w	d0,loop			;do loop some more!
149	bra.b	end_bstr		;finished, so exit
150first_d:
151	swap	d7			;put digit word in d7b
152	move.w	d1,d7			;put new digit in d7b
153	swap	d7			;put LEN counter in word d7a
154	addq.w	#1,d7			;set d7a to signal first digit done
155	dbf.w	d0,loop			;do loop some more!
156	swap	d7			;put last digit in string
157	lsl.w	#4,d7			;move it to upper 4 bits
158	move.b	d7,(a0)+		;store it in memory string
159*
160* Clean up and return with result in fp0.
161*
162end_bstr:
163	movem.l	(a7)+,d0-d7
164	rts
165	end
166