summaryrefslogtreecommitdiff
path: root/sys/arch/m68k/fpsp/binstr.sa
blob: eeecf07f120196b9d4828a36102960de8ea02679 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
*	$NetBSD: binstr.sa,v 1.3 1994/10/26 07:48:53 cgd Exp $

*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
*	M68000 Hi-Performance Microprocessor Division
*	M68040 Software Package 
*
*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
*	All rights reserved.
*
*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
*	To the maximum extent permitted by applicable law,
*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
*	PARTICULAR PURPOSE and any warranty against infringement with
*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
*	and any accompanying written materials. 
*
*	To the maximum extent permitted by applicable law,
*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
*	and support of the SOFTWARE.  
*
*	You are hereby granted a copyright license to use, modify, and
*	distribute the SOFTWARE so long as this entire notice is retained
*	without alteration in any modified and/or redistributed versions,
*	and that such modified versions are clearly identified as such.
*	No licenses are granted by implication, estoppel or otherwise
*	under any patents or trademarks of Motorola, Inc.

*
*	binstr.sa 3.3 12/19/90
*
*
*	Description: Converts a 64-bit binary integer to bcd.
*
*	Input: 64-bit binary integer in d2:d3, desired length (LEN) in
*          d0, and a  pointer to start in memory for bcd characters
*          in d0. (This pointer must point to byte 4 of the first
*          lword of the packed decimal memory string.)
*
*	Output:	LEN bcd digits representing the 64-bit integer.
*
*	Algorithm:
*		The 64-bit binary is assumed to have a decimal point before
*		bit 63.  The fraction is multiplied by 10 using a mul by 2
*		shift and a mul by 8 shift.  The bits shifted out of the
*		msb form a decimal digit.  This process is iterated until
*		LEN digits are formed.
*
*	A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the
*		digit formed will be assumed the least significant.  This is
*		to force the first byte formed to have a 0 in the upper 4 bits.
*
*	A2. Beginning of the loop:
*		Copy the fraction in d2:d3 to d4:d5.
*
*	A3. Multiply the fraction in d2:d3 by 8 using bit-field
*		extracts and shifts.  The three msbs from d2 will go into
*		d1.
*
*	A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb
*		will be collected by the carry.
*
*	A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5
*		into d2:d3.  D1 will contain the bcd digit formed.
*
*	A6. Test d7.  If zero, the digit formed is the ms digit.  If non-
*		zero, it is the ls digit.  Put the digit in its place in the
*		upper word of d0.  If it is the ls digit, write the word
*		from d0 to memory.
*
*	A7. Decrement d6 (LEN counter) and repeat the loop until zero.
*
*	Implementation Notes:
*
*	The registers are used as follows:
*
*		d0: LEN counter
*		d1: temp used to form the digit
*		d2: upper 32-bits of fraction for mul by 8
*		d3: lower 32-bits of fraction for mul by 8
*		d4: upper 32-bits of fraction for mul by 2
*		d5: lower 32-bits of fraction for mul by 2
*		d6: temp for bit-field extracts
*		d7: byte digit formation word;digit count {0,1}
*		a0: pointer into memory for packed bcd string formation
*

BINSTR    IDNT    2,1 Motorola 040 Floating Point Software Package

	section	8

	include	fpsp.h

	xdef	binstr
binstr:
	movem.l	d0-d7,-(a7)
*
* A1: Init d7
*
	moveq.l	#1,d7			;init d7 for second digit
	subq.l	#1,d0			;for dbf d0 would have LEN+1 passes
*
* A2. Copy d2:d3 to d4:d5.  Start loop.
*
loop:
	move.l	d2,d4			;copy the fraction before muls
	move.l	d3,d5			;to d4:d5
*
* A3. Multiply d2:d3 by 8; extract msbs into d1.
*
	bfextu	d2{0:3},d1		;copy 3 msbs of d2 into d1
	asl.l	#3,d2			;shift d2 left by 3 places
	bfextu	d3{0:3},d6		;copy 3 msbs of d3 into d6
	asl.l	#3,d3			;shift d3 left by 3 places
	or.l	d6,d2			;or in msbs from d3 into d2
*
* A4. Multiply d4:d5 by 2; add carry out to d1.
*
	add.l	d5,d5			;mul d5 by 2
	addx.l	d4,d4			;mul d4 by 2
	swap	d6			;put 0 in d6 lower word
	addx.w	d6,d1			;add in extend from mul by 2
*
* A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
*
	add.l	d5,d3			;add lower 32 bits
	nop				;ERRATA FIX #13 (Rev. 1.2 6/6/90)
	addx.l	d4,d2			;add with extend upper 32 bits
	nop				;ERRATA FIX #13 (Rev. 1.2 6/6/90)
	addx.w	d6,d1			;add in extend from add to d1
	swap	d6			;with d6 = 0; put 0 in upper word
*
* A6. Test d7 and branch.
*
	tst.w	d7			;if zero, store digit & to loop
	beq.b	first_d			;if non-zero, form byte & write
sec_d:
	swap	d7			;bring first digit to word d7b
	asl.w	#4,d7			;first digit in upper 4 bits d7b
	add.w	d1,d7			;add in ls digit to d7b
	move.b	d7,(a0)+		;store d7b byte in memory
	swap	d7			;put LEN counter in word d7a
	clr.w	d7			;set d7a to signal no digits done
	dbf.w	d0,loop			;do loop some more!
	bra.b	end_bstr		;finished, so exit
first_d:
	swap	d7			;put digit word in d7b
	move.w	d1,d7			;put new digit in d7b
	swap	d7			;put LEN counter in word d7a
	addq.w	#1,d7			;set d7a to signal first digit done
	dbf.w	d0,loop			;do loop some more!
	swap	d7			;put last digit in string
	lsl.w	#4,d7			;move it to upper 4 bits
	move.b	d7,(a0)+		;store it in memory string
*
* Clean up and return with result in fp0.
*
end_bstr:
	movem.l	(a7)+,d0-d7
	rts
	end