18c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28c2ecf20Sopenharmony_ciMOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
38c2ecf20Sopenharmony_ciM68000 Hi-Performance Microprocessor Division
48c2ecf20Sopenharmony_ciM68060 Software Package
58c2ecf20Sopenharmony_ciProduction Release P1.00 -- October 10, 1994
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciM68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciTHE SOFTWARE is provided on an "AS IS" basis and without warranty.
108c2ecf20Sopenharmony_ciTo the maximum extent permitted by applicable law,
118c2ecf20Sopenharmony_ciMOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
128c2ecf20Sopenharmony_ciINCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
138c2ecf20Sopenharmony_ciand any warranty against infringement with regard to the SOFTWARE
148c2ecf20Sopenharmony_ci(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ciTo the maximum extent permitted by applicable law,
178c2ecf20Sopenharmony_ciIN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
188c2ecf20Sopenharmony_ci(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
198c2ecf20Sopenharmony_ciBUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
208c2ecf20Sopenharmony_ciARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
218c2ecf20Sopenharmony_ciMotorola assumes no responsibility for the maintenance and support of the SOFTWARE.
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciYou are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
248c2ecf20Sopenharmony_ciso long as this entire notice is retained without alteration in any modified and/or
258c2ecf20Sopenharmony_ciredistributed versions, and that such modified versions are clearly identified as such.
268c2ecf20Sopenharmony_ciNo licenses are granted by implication, estoppel or otherwise under any patents
278c2ecf20Sopenharmony_cior trademarks of Motorola, Inc.
288c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
298c2ecf20Sopenharmony_ci# litop.s:
308c2ecf20Sopenharmony_ci#	This file is appended to the top of the 060FPLSP package
318c2ecf20Sopenharmony_ci# and contains the entry points into the package. The user, in
328c2ecf20Sopenharmony_ci# effect, branches to one of the branch table entries located here.
338c2ecf20Sopenharmony_ci#
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	bra.l	_060LSP__idivs64_
368c2ecf20Sopenharmony_ci	short	0x0000
378c2ecf20Sopenharmony_ci	bra.l	_060LSP__idivu64_
388c2ecf20Sopenharmony_ci	short	0x0000
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	bra.l	_060LSP__imuls64_
418c2ecf20Sopenharmony_ci	short	0x0000
428c2ecf20Sopenharmony_ci	bra.l	_060LSP__imulu64_
438c2ecf20Sopenharmony_ci	short	0x0000
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Ab_
468c2ecf20Sopenharmony_ci	short	0x0000
478c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Aw_
488c2ecf20Sopenharmony_ci	short	0x0000
498c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Al_
508c2ecf20Sopenharmony_ci	short	0x0000
518c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Db_
528c2ecf20Sopenharmony_ci	short	0x0000
538c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Dw_
548c2ecf20Sopenharmony_ci	short	0x0000
558c2ecf20Sopenharmony_ci	bra.l	_060LSP__cmp2_Dl_
568c2ecf20Sopenharmony_ci	short	0x0000
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci# leave room for future possible aditions.
598c2ecf20Sopenharmony_ci	align	0x200
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#########################################################################
628c2ecf20Sopenharmony_ci# XDEF ****************************************************************	#
638c2ecf20Sopenharmony_ci#	_060LSP__idivu64_(): Emulate 64-bit unsigned div instruction.	#
648c2ecf20Sopenharmony_ci#	_060LSP__idivs64_(): Emulate 64-bit signed div instruction.	#
658c2ecf20Sopenharmony_ci#									#
668c2ecf20Sopenharmony_ci#	This is the library version which is accessed as a subroutine	#
678c2ecf20Sopenharmony_ci#	and therefore does not work exactly like the 680X0 div{s,u}.l	#
688c2ecf20Sopenharmony_ci#	64-bit divide instruction.					#
698c2ecf20Sopenharmony_ci#									#
708c2ecf20Sopenharmony_ci# XREF ****************************************************************	#
718c2ecf20Sopenharmony_ci#	None.								#
728c2ecf20Sopenharmony_ci#									#
738c2ecf20Sopenharmony_ci# INPUT ***************************************************************	#
748c2ecf20Sopenharmony_ci#	0x4(sp)  = divisor						#
758c2ecf20Sopenharmony_ci#	0x8(sp)  = hi(dividend)						#
768c2ecf20Sopenharmony_ci#	0xc(sp)  = lo(dividend)						#
778c2ecf20Sopenharmony_ci#	0x10(sp) = pointer to location to place quotient/remainder	#
788c2ecf20Sopenharmony_ci#									#
798c2ecf20Sopenharmony_ci# OUTPUT **************************************************************	#
808c2ecf20Sopenharmony_ci#	0x10(sp) = points to location of remainder/quotient.		#
818c2ecf20Sopenharmony_ci#		   remainder is in first longword, quotient is in 2nd.	#
828c2ecf20Sopenharmony_ci#									#
838c2ecf20Sopenharmony_ci# ALGORITHM ***********************************************************	#
848c2ecf20Sopenharmony_ci#	If the operands are signed, make them unsigned and save the	#
858c2ecf20Sopenharmony_ci# sign info for later. Separate out special cases like divide-by-zero	#
868c2ecf20Sopenharmony_ci# or 32-bit divides if possible. Else, use a special math algorithm	#
878c2ecf20Sopenharmony_ci# to calculate the result.						#
888c2ecf20Sopenharmony_ci#	Restore sign info if signed instruction. Set the condition	#
898c2ecf20Sopenharmony_ci# codes before performing the final "rts". If the divisor was equal to	#
908c2ecf20Sopenharmony_ci# zero, then perform a divide-by-zero using a 16-bit implemented	#
918c2ecf20Sopenharmony_ci# divide instruction. This way, the operating system can record that	#
928c2ecf20Sopenharmony_ci# the event occurred even though it may not point to the correct place.	#
938c2ecf20Sopenharmony_ci#									#
948c2ecf20Sopenharmony_ci#########################################################################
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ciset	POSNEG,		-1
978c2ecf20Sopenharmony_ciset	NDIVISOR,	-2
988c2ecf20Sopenharmony_ciset	NDIVIDEND,	-3
998c2ecf20Sopenharmony_ciset	DDSECOND,	-4
1008c2ecf20Sopenharmony_ciset	DDNORMAL,	-8
1018c2ecf20Sopenharmony_ciset	DDQUOTIENT,	-12
1028c2ecf20Sopenharmony_ciset	DIV64_CC,	-16
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci##########
1058c2ecf20Sopenharmony_ci# divs.l #
1068c2ecf20Sopenharmony_ci##########
1078c2ecf20Sopenharmony_ci	global		_060LSP__idivs64_
1088c2ecf20Sopenharmony_ci_060LSP__idivs64_:
1098c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
1108c2ecf20Sopenharmony_ci	link.w		%a6,&-16
1118c2ecf20Sopenharmony_ci	movm.l		&0x3f00,-(%sp)		# save d2-d7
1128c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
1138c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	mov.w		%cc,DIV64_CC(%a6)
1168c2ecf20Sopenharmony_ci	st		POSNEG(%a6)		# signed operation
1178c2ecf20Sopenharmony_ci	bra.b		ldiv64_cont
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci##########
1208c2ecf20Sopenharmony_ci# divu.l #
1218c2ecf20Sopenharmony_ci##########
1228c2ecf20Sopenharmony_ci	global		_060LSP__idivu64_
1238c2ecf20Sopenharmony_ci_060LSP__idivu64_:
1248c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
1258c2ecf20Sopenharmony_ci	link.w		%a6,&-16
1268c2ecf20Sopenharmony_ci	movm.l		&0x3f00,-(%sp)		# save d2-d7
1278c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
1288c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	mov.w		%cc,DIV64_CC(%a6)
1318c2ecf20Sopenharmony_ci	sf		POSNEG(%a6)		# unsigned operation
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cildiv64_cont:
1348c2ecf20Sopenharmony_ci	mov.l		0x8(%a6),%d7		# fetch divisor
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	beq.w		ldiv64eq0		# divisor is = 0!!!
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	mov.l		0xc(%a6), %d5		# get dividend hi
1398c2ecf20Sopenharmony_ci	mov.l		0x10(%a6), %d6		# get dividend lo
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci# separate signed and unsigned divide
1428c2ecf20Sopenharmony_ci	tst.b		POSNEG(%a6)		# signed or unsigned?
1438c2ecf20Sopenharmony_ci	beq.b		ldspecialcases		# use positive divide
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci# save the sign of the divisor
1468c2ecf20Sopenharmony_ci# make divisor unsigned if it's negative
1478c2ecf20Sopenharmony_ci	tst.l		%d7			# chk sign of divisor
1488c2ecf20Sopenharmony_ci	slt		NDIVISOR(%a6)		# save sign of divisor
1498c2ecf20Sopenharmony_ci	bpl.b		ldsgndividend
1508c2ecf20Sopenharmony_ci	neg.l		%d7			# complement negative divisor
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci# save the sign of the dividend
1538c2ecf20Sopenharmony_ci# make dividend unsigned if it's negative
1548c2ecf20Sopenharmony_cildsgndividend:
1558c2ecf20Sopenharmony_ci	tst.l		%d5			# chk sign of hi(dividend)
1568c2ecf20Sopenharmony_ci	slt		NDIVIDEND(%a6)		# save sign of dividend
1578c2ecf20Sopenharmony_ci	bpl.b		ldspecialcases
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	mov.w		&0x0, %cc		# clear 'X' cc bit
1608c2ecf20Sopenharmony_ci	negx.l		%d6			# complement signed dividend
1618c2ecf20Sopenharmony_ci	negx.l		%d5
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci# extract some special cases:
1648c2ecf20Sopenharmony_ci#	- is (dividend == 0) ?
1658c2ecf20Sopenharmony_ci#	- is (hi(dividend) == 0 && (divisor <= lo(dividend))) ? (32-bit div)
1668c2ecf20Sopenharmony_cildspecialcases:
1678c2ecf20Sopenharmony_ci	tst.l		%d5			# is (hi(dividend) == 0)
1688c2ecf20Sopenharmony_ci	bne.b		ldnormaldivide		# no, so try it the long way
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	tst.l		%d6			# is (lo(dividend) == 0), too
1718c2ecf20Sopenharmony_ci	beq.w		lddone			# yes, so (dividend == 0)
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	cmp.l		%d7,%d6			# is (divisor <= lo(dividend))
1748c2ecf20Sopenharmony_ci	bls.b		ld32bitdivide		# yes, so use 32 bit divide
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	exg		%d5,%d6			# q = 0, r = dividend
1778c2ecf20Sopenharmony_ci	bra.w		ldivfinish		# can't divide, we're done.
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_cild32bitdivide:
1808c2ecf20Sopenharmony_ci	tdivu.l		%d7, %d5:%d6		# it's only a 32/32 bit div!
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	bra.b		ldivfinish
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_cildnormaldivide:
1858c2ecf20Sopenharmony_ci# last special case:
1868c2ecf20Sopenharmony_ci#	- is hi(dividend) >= divisor ? if yes, then overflow
1878c2ecf20Sopenharmony_ci	cmp.l		%d7,%d5
1888c2ecf20Sopenharmony_ci	bls.b		lddovf			# answer won't fit in 32 bits
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci# perform the divide algorithm:
1918c2ecf20Sopenharmony_ci	bsr.l		ldclassical		# do int divide
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci# separate into signed and unsigned finishes.
1948c2ecf20Sopenharmony_cildivfinish:
1958c2ecf20Sopenharmony_ci	tst.b		POSNEG(%a6)		# do divs, divu separately
1968c2ecf20Sopenharmony_ci	beq.b		lddone			# divu has no processing!!!
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci# it was a divs.l, so ccode setting is a little more complicated...
1998c2ecf20Sopenharmony_ci	tst.b		NDIVIDEND(%a6)		# remainder has same sign
2008c2ecf20Sopenharmony_ci	beq.b		ldcc			# as dividend.
2018c2ecf20Sopenharmony_ci	neg.l		%d5			# sgn(rem) = sgn(dividend)
2028c2ecf20Sopenharmony_cildcc:
2038c2ecf20Sopenharmony_ci	mov.b		NDIVISOR(%a6), %d0
2048c2ecf20Sopenharmony_ci	eor.b		%d0, NDIVIDEND(%a6)	# chk if quotient is negative
2058c2ecf20Sopenharmony_ci	beq.b		ldqpos			# branch to quot positive
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci# 0x80000000 is the largest number representable as a 32-bit negative
2088c2ecf20Sopenharmony_ci# number. the negative of 0x80000000 is 0x80000000.
2098c2ecf20Sopenharmony_ci	cmpi.l		%d6, &0x80000000	# will (-quot) fit in 32 bits?
2108c2ecf20Sopenharmony_ci	bhi.b		lddovf
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	neg.l		%d6			# make (-quot) 2's comp
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	bra.b		lddone
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_cildqpos:
2178c2ecf20Sopenharmony_ci	btst		&0x1f, %d6		# will (+quot) fit in 32 bits?
2188c2ecf20Sopenharmony_ci	bne.b		lddovf
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_cilddone:
2218c2ecf20Sopenharmony_ci# if the register numbers are the same, only the quotient gets saved.
2228c2ecf20Sopenharmony_ci# so, if we always save the quotient second, we save ourselves a cmp&beq
2238c2ecf20Sopenharmony_ci	andi.w		&0x10,DIV64_CC(%a6)
2248c2ecf20Sopenharmony_ci	mov.w		DIV64_CC(%a6),%cc
2258c2ecf20Sopenharmony_ci	tst.l		%d6			# may set 'N' ccode bit
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci# here, the result is in d1 and d0. the current strategy is to save
2288c2ecf20Sopenharmony_ci# the values at the location pointed to by a0.
2298c2ecf20Sopenharmony_ci# use movm here to not disturb the condition codes.
2308c2ecf20Sopenharmony_cildexit:
2318c2ecf20Sopenharmony_ci	movm.l		&0x0060,([0x14,%a6])	# save result
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci# EPILOGUE BEGIN ########################################################
2348c2ecf20Sopenharmony_ci#	fmovm.l		(%sp)+,&0x0		# restore no fpregs
2358c2ecf20Sopenharmony_ci	movm.l		(%sp)+,&0x00fc		# restore d2-d7
2368c2ecf20Sopenharmony_ci	unlk		%a6
2378c2ecf20Sopenharmony_ci# EPILOGUE END ##########################################################
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	rts
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci# the result should be the unchanged dividend
2428c2ecf20Sopenharmony_cilddovf:
2438c2ecf20Sopenharmony_ci	mov.l		0xc(%a6), %d5		# get dividend hi
2448c2ecf20Sopenharmony_ci	mov.l		0x10(%a6), %d6		# get dividend lo
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	andi.w		&0x1c,DIV64_CC(%a6)
2478c2ecf20Sopenharmony_ci	ori.w		&0x02,DIV64_CC(%a6)	# set 'V' ccode bit
2488c2ecf20Sopenharmony_ci	mov.w		DIV64_CC(%a6),%cc
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	bra.b		ldexit
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_cildiv64eq0:
2538c2ecf20Sopenharmony_ci	mov.l		0xc(%a6),([0x14,%a6])
2548c2ecf20Sopenharmony_ci	mov.l		0x10(%a6),([0x14,%a6],0x4)
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	mov.w		DIV64_CC(%a6),%cc
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci# EPILOGUE BEGIN ########################################################
2598c2ecf20Sopenharmony_ci#	fmovm.l		(%sp)+,&0x0		# restore no fpregs
2608c2ecf20Sopenharmony_ci	movm.l		(%sp)+,&0x00fc		# restore d2-d7
2618c2ecf20Sopenharmony_ci	unlk		%a6
2628c2ecf20Sopenharmony_ci# EPILOGUE END ##########################################################
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	divu.w		&0x0,%d0		# force a divbyzero exception
2658c2ecf20Sopenharmony_ci	rts
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci###########################################################################
2688c2ecf20Sopenharmony_ci#########################################################################
2698c2ecf20Sopenharmony_ci# This routine uses the 'classical' Algorithm D from Donald Knuth's	#
2708c2ecf20Sopenharmony_ci# Art of Computer Programming, vol II, Seminumerical Algorithms.	#
2718c2ecf20Sopenharmony_ci# For this implementation b=2**16, and the target is U1U2U3U4/V1V2,	#
2728c2ecf20Sopenharmony_ci# where U,V are words of the quadword dividend and longword divisor,	#
2738c2ecf20Sopenharmony_ci# and U1, V1 are the most significant words.				#
2748c2ecf20Sopenharmony_ci#									#
2758c2ecf20Sopenharmony_ci# The most sig. longword of the 64 bit dividend must be in %d5, least	#
2768c2ecf20Sopenharmony_ci# in %d6. The divisor must be in the variable ddivisor, and the		#
2778c2ecf20Sopenharmony_ci# signed/unsigned flag ddusign must be set (0=unsigned,1=signed).	#
2788c2ecf20Sopenharmony_ci# The quotient is returned in %d6, remainder in %d5, unless the		#
2798c2ecf20Sopenharmony_ci# v (overflow) bit is set in the saved %ccr. If overflow, the dividend	#
2808c2ecf20Sopenharmony_ci# is unchanged.								#
2818c2ecf20Sopenharmony_ci#########################################################################
2828c2ecf20Sopenharmony_cildclassical:
2838c2ecf20Sopenharmony_ci# if the divisor msw is 0, use simpler algorithm then the full blown
2848c2ecf20Sopenharmony_ci# one at ddknuth:
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	cmpi.l		%d7, &0xffff
2878c2ecf20Sopenharmony_ci	bhi.b		lddknuth		# go use D. Knuth algorithm
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci# Since the divisor is only a word (and larger than the mslw of the dividend),
2908c2ecf20Sopenharmony_ci# a simpler algorithm may be used :
2918c2ecf20Sopenharmony_ci# In the general case, four quotient words would be created by
2928c2ecf20Sopenharmony_ci# dividing the divisor word into each dividend word. In this case,
2938c2ecf20Sopenharmony_ci# the first two quotient words must be zero, or overflow would occur.
2948c2ecf20Sopenharmony_ci# Since we already checked this case above, we can treat the most significant
2958c2ecf20Sopenharmony_ci# longword of the dividend as (0) remainder (see Knuth) and merely complete
2968c2ecf20Sopenharmony_ci# the last two divisions to get a quotient longword and word remainder:
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	clr.l		%d1
2998c2ecf20Sopenharmony_ci	swap		%d5			# same as r*b if previous step rqd
3008c2ecf20Sopenharmony_ci	swap		%d6			# get u3 to lsw position
3018c2ecf20Sopenharmony_ci	mov.w		%d6, %d5		# rb + u3
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	divu.w		%d7, %d5
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	mov.w		%d5, %d1		# first quotient word
3068c2ecf20Sopenharmony_ci	swap		%d6			# get u4
3078c2ecf20Sopenharmony_ci	mov.w		%d6, %d5		# rb + u4
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	divu.w		%d7, %d5
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	swap		%d1
3128c2ecf20Sopenharmony_ci	mov.w		%d5, %d1		# 2nd quotient 'digit'
3138c2ecf20Sopenharmony_ci	clr.w		%d5
3148c2ecf20Sopenharmony_ci	swap		%d5			# now remainder
3158c2ecf20Sopenharmony_ci	mov.l		%d1, %d6		# and quotient
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	rts
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cilddknuth:
3208c2ecf20Sopenharmony_ci# In this algorithm, the divisor is treated as a 2 digit (word) number
3218c2ecf20Sopenharmony_ci# which is divided into a 3 digit (word) dividend to get one quotient
3228c2ecf20Sopenharmony_ci# digit (word). After subtraction, the dividend is shifted and the
3238c2ecf20Sopenharmony_ci# process repeated. Before beginning, the divisor and quotient are
3248c2ecf20Sopenharmony_ci# 'normalized' so that the process of estimating the quotient digit
3258c2ecf20Sopenharmony_ci# will yield verifiably correct results..
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	clr.l		DDNORMAL(%a6)		# count of shifts for normalization
3288c2ecf20Sopenharmony_ci	clr.b		DDSECOND(%a6)		# clear flag for quotient digits
3298c2ecf20Sopenharmony_ci	clr.l		%d1			# %d1 will hold trial quotient
3308c2ecf20Sopenharmony_cilddnchk:
3318c2ecf20Sopenharmony_ci	btst		&31, %d7		# must we normalize? first word of
3328c2ecf20Sopenharmony_ci	bne.b		lddnormalized		# divisor (V1) must be >= 65536/2
3338c2ecf20Sopenharmony_ci	addq.l		&0x1, DDNORMAL(%a6)	# count normalization shifts
3348c2ecf20Sopenharmony_ci	lsl.l		&0x1, %d7		# shift the divisor
3358c2ecf20Sopenharmony_ci	lsl.l		&0x1, %d6		# shift u4,u3 with overflow to u2
3368c2ecf20Sopenharmony_ci	roxl.l		&0x1, %d5		# shift u1,u2
3378c2ecf20Sopenharmony_ci	bra.w		lddnchk
3388c2ecf20Sopenharmony_cilddnormalized:
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci# Now calculate an estimate of the quotient words (msw first, then lsw).
3418c2ecf20Sopenharmony_ci# The comments use subscripts for the first quotient digit determination.
3428c2ecf20Sopenharmony_ci	mov.l		%d7, %d3		# divisor
3438c2ecf20Sopenharmony_ci	mov.l		%d5, %d2		# dividend mslw
3448c2ecf20Sopenharmony_ci	swap		%d2
3458c2ecf20Sopenharmony_ci	swap		%d3
3468c2ecf20Sopenharmony_ci	cmp.w		%d2, %d3		# V1 = U1 ?
3478c2ecf20Sopenharmony_ci	bne.b		lddqcalc1
3488c2ecf20Sopenharmony_ci	mov.w		&0xffff, %d1		# use max trial quotient word
3498c2ecf20Sopenharmony_ci	bra.b		lddadj0
3508c2ecf20Sopenharmony_cilddqcalc1:
3518c2ecf20Sopenharmony_ci	mov.l		%d5, %d1
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	divu.w		%d3, %d1		# use quotient of mslw/msw
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	andi.l		&0x0000ffff, %d1	# zero any remainder
3568c2ecf20Sopenharmony_cilddadj0:
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci# now test the trial quotient and adjust. This step plus the
3598c2ecf20Sopenharmony_ci# normalization assures (according to Knuth) that the trial
3608c2ecf20Sopenharmony_ci# quotient will be at worst 1 too large.
3618c2ecf20Sopenharmony_ci	mov.l		%d6, -(%sp)
3628c2ecf20Sopenharmony_ci	clr.w		%d6			# word u3 left
3638c2ecf20Sopenharmony_ci	swap		%d6			# in lsw position
3648c2ecf20Sopenharmony_cilddadj1: mov.l		%d7, %d3
3658c2ecf20Sopenharmony_ci	mov.l		%d1, %d2
3668c2ecf20Sopenharmony_ci	mulu.w		%d7, %d2		# V2q
3678c2ecf20Sopenharmony_ci	swap		%d3
3688c2ecf20Sopenharmony_ci	mulu.w		%d1, %d3		# V1q
3698c2ecf20Sopenharmony_ci	mov.l		%d5, %d4		# U1U2
3708c2ecf20Sopenharmony_ci	sub.l		%d3, %d4		# U1U2 - V1q
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	swap		%d4
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	mov.w		%d4,%d0
3758c2ecf20Sopenharmony_ci	mov.w		%d6,%d4			# insert lower word (U3)
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	tst.w		%d0			# is upper word set?
3788c2ecf20Sopenharmony_ci	bne.w		lddadjd1
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci#	add.l		%d6, %d4		# (U1U2 - V1q) + U3
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	cmp.l		%d2, %d4
3838c2ecf20Sopenharmony_ci	bls.b		lddadjd1		# is V2q > (U1U2-V1q) + U3 ?
3848c2ecf20Sopenharmony_ci	subq.l		&0x1, %d1		# yes, decrement and recheck
3858c2ecf20Sopenharmony_ci	bra.b		lddadj1
3868c2ecf20Sopenharmony_cilddadjd1:
3878c2ecf20Sopenharmony_ci# now test the word by multiplying it by the divisor (V1V2) and comparing
3888c2ecf20Sopenharmony_ci# the 3 digit (word) result with the current dividend words
3898c2ecf20Sopenharmony_ci	mov.l		%d5, -(%sp)		# save %d5 (%d6 already saved)
3908c2ecf20Sopenharmony_ci	mov.l		%d1, %d6
3918c2ecf20Sopenharmony_ci	swap		%d6			# shift answer to ms 3 words
3928c2ecf20Sopenharmony_ci	mov.l		%d7, %d5
3938c2ecf20Sopenharmony_ci	bsr.l		ldmm2
3948c2ecf20Sopenharmony_ci	mov.l		%d5, %d2		# now %d2,%d3 are trial*divisor
3958c2ecf20Sopenharmony_ci	mov.l		%d6, %d3
3968c2ecf20Sopenharmony_ci	mov.l		(%sp)+, %d5		# restore dividend
3978c2ecf20Sopenharmony_ci	mov.l		(%sp)+, %d6
3988c2ecf20Sopenharmony_ci	sub.l		%d3, %d6
3998c2ecf20Sopenharmony_ci	subx.l		%d2, %d5		# subtract double precision
4008c2ecf20Sopenharmony_ci	bcc		ldd2nd			# no carry, do next quotient digit
4018c2ecf20Sopenharmony_ci	subq.l		&0x1, %d1		# q is one too large
4028c2ecf20Sopenharmony_ci# need to add back divisor longword to current ms 3 digits of dividend
4038c2ecf20Sopenharmony_ci# - according to Knuth, this is done only 2 out of 65536 times for random
4048c2ecf20Sopenharmony_ci# divisor, dividend selection.
4058c2ecf20Sopenharmony_ci	clr.l		%d2
4068c2ecf20Sopenharmony_ci	mov.l		%d7, %d3
4078c2ecf20Sopenharmony_ci	swap		%d3
4088c2ecf20Sopenharmony_ci	clr.w		%d3			# %d3 now ls word of divisor
4098c2ecf20Sopenharmony_ci	add.l		%d3, %d6		# aligned with 3rd word of dividend
4108c2ecf20Sopenharmony_ci	addx.l		%d2, %d5
4118c2ecf20Sopenharmony_ci	mov.l		%d7, %d3
4128c2ecf20Sopenharmony_ci	clr.w		%d3			# %d3 now ms word of divisor
4138c2ecf20Sopenharmony_ci	swap		%d3			# aligned with 2nd word of dividend
4148c2ecf20Sopenharmony_ci	add.l		%d3, %d5
4158c2ecf20Sopenharmony_cildd2nd:
4168c2ecf20Sopenharmony_ci	tst.b		DDSECOND(%a6)	# both q words done?
4178c2ecf20Sopenharmony_ci	bne.b		lddremain
4188c2ecf20Sopenharmony_ci# first quotient digit now correct. store digit and shift the
4198c2ecf20Sopenharmony_ci# (subtracted) dividend
4208c2ecf20Sopenharmony_ci	mov.w		%d1, DDQUOTIENT(%a6)
4218c2ecf20Sopenharmony_ci	clr.l		%d1
4228c2ecf20Sopenharmony_ci	swap		%d5
4238c2ecf20Sopenharmony_ci	swap		%d6
4248c2ecf20Sopenharmony_ci	mov.w		%d6, %d5
4258c2ecf20Sopenharmony_ci	clr.w		%d6
4268c2ecf20Sopenharmony_ci	st		DDSECOND(%a6)		# second digit
4278c2ecf20Sopenharmony_ci	bra.w		lddnormalized
4288c2ecf20Sopenharmony_cilddremain:
4298c2ecf20Sopenharmony_ci# add 2nd word to quotient, get the remainder.
4308c2ecf20Sopenharmony_ci	mov.w		%d1, DDQUOTIENT+2(%a6)
4318c2ecf20Sopenharmony_ci# shift down one word/digit to renormalize remainder.
4328c2ecf20Sopenharmony_ci	mov.w		%d5, %d6
4338c2ecf20Sopenharmony_ci	swap		%d6
4348c2ecf20Sopenharmony_ci	swap		%d5
4358c2ecf20Sopenharmony_ci	mov.l		DDNORMAL(%a6), %d7	# get norm shift count
4368c2ecf20Sopenharmony_ci	beq.b		lddrn
4378c2ecf20Sopenharmony_ci	subq.l		&0x1, %d7		# set for loop count
4388c2ecf20Sopenharmony_cilddnlp:
4398c2ecf20Sopenharmony_ci	lsr.l		&0x1, %d5		# shift into %d6
4408c2ecf20Sopenharmony_ci	roxr.l		&0x1, %d6
4418c2ecf20Sopenharmony_ci	dbf		%d7, lddnlp
4428c2ecf20Sopenharmony_cilddrn:
4438c2ecf20Sopenharmony_ci	mov.l		%d6, %d5		# remainder
4448c2ecf20Sopenharmony_ci	mov.l		DDQUOTIENT(%a6), %d6	# quotient
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	rts
4478c2ecf20Sopenharmony_cildmm2:
4488c2ecf20Sopenharmony_ci# factors for the 32X32->64 multiplication are in %d5 and %d6.
4498c2ecf20Sopenharmony_ci# returns 64 bit result in %d5 (hi) %d6(lo).
4508c2ecf20Sopenharmony_ci# destroys %d2,%d3,%d4.
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci# multiply hi,lo words of each factor to get 4 intermediate products
4538c2ecf20Sopenharmony_ci	mov.l		%d6, %d2
4548c2ecf20Sopenharmony_ci	mov.l		%d6, %d3
4558c2ecf20Sopenharmony_ci	mov.l		%d5, %d4
4568c2ecf20Sopenharmony_ci	swap		%d3
4578c2ecf20Sopenharmony_ci	swap		%d4
4588c2ecf20Sopenharmony_ci	mulu.w		%d5, %d6		# %d6 <- lsw*lsw
4598c2ecf20Sopenharmony_ci	mulu.w		%d3, %d5		# %d5 <- msw-dest*lsw-source
4608c2ecf20Sopenharmony_ci	mulu.w		%d4, %d2		# %d2 <- msw-source*lsw-dest
4618c2ecf20Sopenharmony_ci	mulu.w		%d4, %d3		# %d3 <- msw*msw
4628c2ecf20Sopenharmony_ci# now use swap and addx to consolidate to two longwords
4638c2ecf20Sopenharmony_ci	clr.l		%d4
4648c2ecf20Sopenharmony_ci	swap		%d6
4658c2ecf20Sopenharmony_ci	add.w		%d5, %d6		# add msw of l*l to lsw of m*l product
4668c2ecf20Sopenharmony_ci	addx.w		%d4, %d3		# add any carry to m*m product
4678c2ecf20Sopenharmony_ci	add.w		%d2, %d6		# add in lsw of other m*l product
4688c2ecf20Sopenharmony_ci	addx.w		%d4, %d3		# add any carry to m*m product
4698c2ecf20Sopenharmony_ci	swap		%d6			# %d6 is low 32 bits of final product
4708c2ecf20Sopenharmony_ci	clr.w		%d5
4718c2ecf20Sopenharmony_ci	clr.w		%d2			# lsw of two mixed products used,
4728c2ecf20Sopenharmony_ci	swap		%d5			# now use msws of longwords
4738c2ecf20Sopenharmony_ci	swap		%d2
4748c2ecf20Sopenharmony_ci	add.l		%d2, %d5
4758c2ecf20Sopenharmony_ci	add.l		%d3, %d5	# %d5 now ms 32 bits of final product
4768c2ecf20Sopenharmony_ci	rts
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci#########################################################################
4798c2ecf20Sopenharmony_ci# XDEF ****************************************************************	#
4808c2ecf20Sopenharmony_ci#	_060LSP__imulu64_(): Emulate 64-bit unsigned mul instruction	#
4818c2ecf20Sopenharmony_ci#	_060LSP__imuls64_(): Emulate 64-bit signed mul instruction.	#
4828c2ecf20Sopenharmony_ci#									#
4838c2ecf20Sopenharmony_ci#	This is the library version which is accessed as a subroutine	#
4848c2ecf20Sopenharmony_ci#	and therefore does not work exactly like the 680X0 mul{s,u}.l	#
4858c2ecf20Sopenharmony_ci#	64-bit multiply instruction.					#
4868c2ecf20Sopenharmony_ci#									#
4878c2ecf20Sopenharmony_ci# XREF ****************************************************************	#
4888c2ecf20Sopenharmony_ci#	None								#
4898c2ecf20Sopenharmony_ci#									#
4908c2ecf20Sopenharmony_ci# INPUT ***************************************************************	#
4918c2ecf20Sopenharmony_ci#	0x4(sp) = multiplier						#
4928c2ecf20Sopenharmony_ci#	0x8(sp) = multiplicand						#
4938c2ecf20Sopenharmony_ci#	0xc(sp) = pointer to location to place 64-bit result		#
4948c2ecf20Sopenharmony_ci#									#
4958c2ecf20Sopenharmony_ci# OUTPUT **************************************************************	#
4968c2ecf20Sopenharmony_ci#	0xc(sp) = points to location of 64-bit result			#
4978c2ecf20Sopenharmony_ci#									#
4988c2ecf20Sopenharmony_ci# ALGORITHM ***********************************************************	#
4998c2ecf20Sopenharmony_ci#	Perform the multiply in pieces using 16x16->32 unsigned		#
5008c2ecf20Sopenharmony_ci# multiplies and "add" instructions.					#
5018c2ecf20Sopenharmony_ci#	Set the condition codes as appropriate before performing an	#
5028c2ecf20Sopenharmony_ci# "rts".								#
5038c2ecf20Sopenharmony_ci#									#
5048c2ecf20Sopenharmony_ci#########################################################################
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ciset MUL64_CC, -4
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	global		_060LSP__imulu64_
5098c2ecf20Sopenharmony_ci_060LSP__imulu64_:
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
5128c2ecf20Sopenharmony_ci	link.w		%a6,&-4
5138c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
5148c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
5158c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	mov.w		%cc,MUL64_CC(%a6)	# save incoming ccodes
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci	mov.l		0x8(%a6),%d0		# store multiplier in d0
5208c2ecf20Sopenharmony_ci	beq.w		mulu64_zero		# handle zero separately
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci	mov.l		0xc(%a6),%d1		# get multiplicand in d1
5238c2ecf20Sopenharmony_ci	beq.w		mulu64_zero		# handle zero separately
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci#########################################################################
5268c2ecf20Sopenharmony_ci#	63			   32				0	#
5278c2ecf20Sopenharmony_ci#	----------------------------					#
5288c2ecf20Sopenharmony_ci#	| hi(mplier) * hi(mplicand)|					#
5298c2ecf20Sopenharmony_ci#	----------------------------					#
5308c2ecf20Sopenharmony_ci#		     -----------------------------			#
5318c2ecf20Sopenharmony_ci#		     | hi(mplier) * lo(mplicand) |			#
5328c2ecf20Sopenharmony_ci#		     -----------------------------			#
5338c2ecf20Sopenharmony_ci#		     -----------------------------			#
5348c2ecf20Sopenharmony_ci#		     | lo(mplier) * hi(mplicand) |			#
5358c2ecf20Sopenharmony_ci#		     -----------------------------			#
5368c2ecf20Sopenharmony_ci#	  |			   -----------------------------	#
5378c2ecf20Sopenharmony_ci#	--|--			   | lo(mplier) * lo(mplicand) |	#
5388c2ecf20Sopenharmony_ci#	  |			   -----------------------------	#
5398c2ecf20Sopenharmony_ci#	========================================================	#
5408c2ecf20Sopenharmony_ci#	--------------------------------------------------------	#
5418c2ecf20Sopenharmony_ci#	|	hi(result)	   |	    lo(result)         |	#
5428c2ecf20Sopenharmony_ci#	--------------------------------------------------------	#
5438c2ecf20Sopenharmony_ci#########################################################################
5448c2ecf20Sopenharmony_cimulu64_alg:
5458c2ecf20Sopenharmony_ci# load temp registers with operands
5468c2ecf20Sopenharmony_ci	mov.l		%d0,%d2			# mr in d2
5478c2ecf20Sopenharmony_ci	mov.l		%d0,%d3			# mr in d3
5488c2ecf20Sopenharmony_ci	mov.l		%d1,%d4			# md in d4
5498c2ecf20Sopenharmony_ci	swap		%d3			# hi(mr) in lo d3
5508c2ecf20Sopenharmony_ci	swap		%d4			# hi(md) in lo d4
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci# complete necessary multiplies:
5538c2ecf20Sopenharmony_ci	mulu.w		%d1,%d0			# [1] lo(mr) * lo(md)
5548c2ecf20Sopenharmony_ci	mulu.w		%d3,%d1			# [2] hi(mr) * lo(md)
5558c2ecf20Sopenharmony_ci	mulu.w		%d4,%d2			# [3] lo(mr) * hi(md)
5568c2ecf20Sopenharmony_ci	mulu.w		%d4,%d3			# [4] hi(mr) * hi(md)
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_ci# add lo portions of [2],[3] to hi portion of [1].
5598c2ecf20Sopenharmony_ci# add carries produced from these adds to [4].
5608c2ecf20Sopenharmony_ci# lo([1]) is the final lo 16 bits of the result.
5618c2ecf20Sopenharmony_ci	clr.l		%d4			# load d4 w/ zero value
5628c2ecf20Sopenharmony_ci	swap		%d0			# hi([1]) <==> lo([1])
5638c2ecf20Sopenharmony_ci	add.w		%d1,%d0			# hi([1]) + lo([2])
5648c2ecf20Sopenharmony_ci	addx.l		%d4,%d3			#    [4]  + carry
5658c2ecf20Sopenharmony_ci	add.w		%d2,%d0			# hi([1]) + lo([3])
5668c2ecf20Sopenharmony_ci	addx.l		%d4,%d3			#    [4]  + carry
5678c2ecf20Sopenharmony_ci	swap		%d0			# lo([1]) <==> hi([1])
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci# lo portions of [2],[3] have been added in to final result.
5708c2ecf20Sopenharmony_ci# now, clear lo, put hi in lo reg, and add to [4]
5718c2ecf20Sopenharmony_ci	clr.w		%d1			# clear lo([2])
5728c2ecf20Sopenharmony_ci	clr.w		%d2			# clear hi([3])
5738c2ecf20Sopenharmony_ci	swap		%d1			# hi([2]) in lo d1
5748c2ecf20Sopenharmony_ci	swap		%d2			# hi([3]) in lo d2
5758c2ecf20Sopenharmony_ci	add.l		%d2,%d1			#    [4]  + hi([2])
5768c2ecf20Sopenharmony_ci	add.l		%d3,%d1			#    [4]  + hi([3])
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci# now, grab the condition codes. only one that can be set is 'N'.
5798c2ecf20Sopenharmony_ci# 'N' CAN be set if the operation is unsigned if bit 63 is set.
5808c2ecf20Sopenharmony_ci	mov.w		MUL64_CC(%a6),%d4
5818c2ecf20Sopenharmony_ci	andi.b		&0x10,%d4		# keep old 'X' bit
5828c2ecf20Sopenharmony_ci	tst.l		%d1			# may set 'N' bit
5838c2ecf20Sopenharmony_ci	bpl.b		mulu64_ddone
5848c2ecf20Sopenharmony_ci	ori.b		&0x8,%d4		# set 'N' bit
5858c2ecf20Sopenharmony_cimulu64_ddone:
5868c2ecf20Sopenharmony_ci	mov.w		%d4,%cc
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci# here, the result is in d1 and d0. the current strategy is to save
5898c2ecf20Sopenharmony_ci# the values at the location pointed to by a0.
5908c2ecf20Sopenharmony_ci# use movm here to not disturb the condition codes.
5918c2ecf20Sopenharmony_cimulu64_end:
5928c2ecf20Sopenharmony_ci	exg		%d1,%d0
5938c2ecf20Sopenharmony_ci	movm.l		&0x0003,([0x10,%a6])		# save result
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci# EPILOGUE BEGIN ########################################################
5968c2ecf20Sopenharmony_ci#	fmovm.l		(%sp)+,&0x0		# restore no fpregs
5978c2ecf20Sopenharmony_ci	movm.l		(%sp)+,&0x001c		# restore d2-d4
5988c2ecf20Sopenharmony_ci	unlk		%a6
5998c2ecf20Sopenharmony_ci# EPILOGUE END ##########################################################
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci	rts
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci# one or both of the operands is zero so the result is also zero.
6048c2ecf20Sopenharmony_ci# save the zero result to the register file and set the 'Z' ccode bit.
6058c2ecf20Sopenharmony_cimulu64_zero:
6068c2ecf20Sopenharmony_ci	clr.l		%d0
6078c2ecf20Sopenharmony_ci	clr.l		%d1
6088c2ecf20Sopenharmony_ci
6098c2ecf20Sopenharmony_ci	mov.w		MUL64_CC(%a6),%d4
6108c2ecf20Sopenharmony_ci	andi.b		&0x10,%d4
6118c2ecf20Sopenharmony_ci	ori.b		&0x4,%d4
6128c2ecf20Sopenharmony_ci	mov.w		%d4,%cc			# set 'Z' ccode bit
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci	bra.b		mulu64_end
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci##########
6178c2ecf20Sopenharmony_ci# muls.l #
6188c2ecf20Sopenharmony_ci##########
6198c2ecf20Sopenharmony_ci	global		_060LSP__imuls64_
6208c2ecf20Sopenharmony_ci_060LSP__imuls64_:
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
6238c2ecf20Sopenharmony_ci	link.w		%a6,&-4
6248c2ecf20Sopenharmony_ci	movm.l		&0x3c00,-(%sp)		# save d2-d5
6258c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
6268c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci	mov.w		%cc,MUL64_CC(%a6)	# save incoming ccodes
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci	mov.l		0x8(%a6),%d0		# store multiplier in d0
6318c2ecf20Sopenharmony_ci	beq.b		mulu64_zero		# handle zero separately
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	mov.l		0xc(%a6),%d1		# get multiplicand in d1
6348c2ecf20Sopenharmony_ci	beq.b		mulu64_zero		# handle zero separately
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ci	clr.b		%d5			# clear sign tag
6378c2ecf20Sopenharmony_ci	tst.l		%d0			# is multiplier negative?
6388c2ecf20Sopenharmony_ci	bge.b		muls64_chk_md_sgn	# no
6398c2ecf20Sopenharmony_ci	neg.l		%d0			# make multiplier positive
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	ori.b		&0x1,%d5		# save multiplier sgn
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci# the result sign is the exclusive or of the operand sign bits.
6448c2ecf20Sopenharmony_cimuls64_chk_md_sgn:
6458c2ecf20Sopenharmony_ci	tst.l		%d1			# is multiplicand negative?
6468c2ecf20Sopenharmony_ci	bge.b		muls64_alg		# no
6478c2ecf20Sopenharmony_ci	neg.l		%d1			# make multiplicand positive
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci	eori.b		&0x1,%d5		# calculate correct sign
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci#########################################################################
6528c2ecf20Sopenharmony_ci#	63			   32				0	#
6538c2ecf20Sopenharmony_ci#	----------------------------					#
6548c2ecf20Sopenharmony_ci#	| hi(mplier) * hi(mplicand)|					#
6558c2ecf20Sopenharmony_ci#	----------------------------					#
6568c2ecf20Sopenharmony_ci#		     -----------------------------			#
6578c2ecf20Sopenharmony_ci#		     | hi(mplier) * lo(mplicand) |			#
6588c2ecf20Sopenharmony_ci#		     -----------------------------			#
6598c2ecf20Sopenharmony_ci#		     -----------------------------			#
6608c2ecf20Sopenharmony_ci#		     | lo(mplier) * hi(mplicand) |			#
6618c2ecf20Sopenharmony_ci#		     -----------------------------			#
6628c2ecf20Sopenharmony_ci#	  |			   -----------------------------	#
6638c2ecf20Sopenharmony_ci#	--|--			   | lo(mplier) * lo(mplicand) |	#
6648c2ecf20Sopenharmony_ci#	  |			   -----------------------------	#
6658c2ecf20Sopenharmony_ci#	========================================================	#
6668c2ecf20Sopenharmony_ci#	--------------------------------------------------------	#
6678c2ecf20Sopenharmony_ci#	|	hi(result)	   |	    lo(result)         |	#
6688c2ecf20Sopenharmony_ci#	--------------------------------------------------------	#
6698c2ecf20Sopenharmony_ci#########################################################################
6708c2ecf20Sopenharmony_cimuls64_alg:
6718c2ecf20Sopenharmony_ci# load temp registers with operands
6728c2ecf20Sopenharmony_ci	mov.l		%d0,%d2			# mr in d2
6738c2ecf20Sopenharmony_ci	mov.l		%d0,%d3			# mr in d3
6748c2ecf20Sopenharmony_ci	mov.l		%d1,%d4			# md in d4
6758c2ecf20Sopenharmony_ci	swap		%d3			# hi(mr) in lo d3
6768c2ecf20Sopenharmony_ci	swap		%d4			# hi(md) in lo d4
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci# complete necessary multiplies:
6798c2ecf20Sopenharmony_ci	mulu.w		%d1,%d0			# [1] lo(mr) * lo(md)
6808c2ecf20Sopenharmony_ci	mulu.w		%d3,%d1			# [2] hi(mr) * lo(md)
6818c2ecf20Sopenharmony_ci	mulu.w		%d4,%d2			# [3] lo(mr) * hi(md)
6828c2ecf20Sopenharmony_ci	mulu.w		%d4,%d3			# [4] hi(mr) * hi(md)
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci# add lo portions of [2],[3] to hi portion of [1].
6858c2ecf20Sopenharmony_ci# add carries produced from these adds to [4].
6868c2ecf20Sopenharmony_ci# lo([1]) is the final lo 16 bits of the result.
6878c2ecf20Sopenharmony_ci	clr.l		%d4			# load d4 w/ zero value
6888c2ecf20Sopenharmony_ci	swap		%d0			# hi([1]) <==> lo([1])
6898c2ecf20Sopenharmony_ci	add.w		%d1,%d0			# hi([1]) + lo([2])
6908c2ecf20Sopenharmony_ci	addx.l		%d4,%d3			#    [4]  + carry
6918c2ecf20Sopenharmony_ci	add.w		%d2,%d0			# hi([1]) + lo([3])
6928c2ecf20Sopenharmony_ci	addx.l		%d4,%d3			#    [4]  + carry
6938c2ecf20Sopenharmony_ci	swap		%d0			# lo([1]) <==> hi([1])
6948c2ecf20Sopenharmony_ci
6958c2ecf20Sopenharmony_ci# lo portions of [2],[3] have been added in to final result.
6968c2ecf20Sopenharmony_ci# now, clear lo, put hi in lo reg, and add to [4]
6978c2ecf20Sopenharmony_ci	clr.w		%d1			# clear lo([2])
6988c2ecf20Sopenharmony_ci	clr.w		%d2			# clear hi([3])
6998c2ecf20Sopenharmony_ci	swap		%d1			# hi([2]) in lo d1
7008c2ecf20Sopenharmony_ci	swap		%d2			# hi([3]) in lo d2
7018c2ecf20Sopenharmony_ci	add.l		%d2,%d1			#    [4]  + hi([2])
7028c2ecf20Sopenharmony_ci	add.l		%d3,%d1			#    [4]  + hi([3])
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ci	tst.b		%d5			# should result be signed?
7058c2ecf20Sopenharmony_ci	beq.b		muls64_done		# no
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci# result should be a signed negative number.
7088c2ecf20Sopenharmony_ci# compute 2's complement of the unsigned number:
7098c2ecf20Sopenharmony_ci#   -negate all bits and add 1
7108c2ecf20Sopenharmony_cimuls64_neg:
7118c2ecf20Sopenharmony_ci	not.l		%d0			# negate lo(result) bits
7128c2ecf20Sopenharmony_ci	not.l		%d1			# negate hi(result) bits
7138c2ecf20Sopenharmony_ci	addq.l		&1,%d0			# add 1 to lo(result)
7148c2ecf20Sopenharmony_ci	addx.l		%d4,%d1			# add carry to hi(result)
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_cimuls64_done:
7178c2ecf20Sopenharmony_ci	mov.w		MUL64_CC(%a6),%d4
7188c2ecf20Sopenharmony_ci	andi.b		&0x10,%d4		# keep old 'X' bit
7198c2ecf20Sopenharmony_ci	tst.l		%d1			# may set 'N' bit
7208c2ecf20Sopenharmony_ci	bpl.b		muls64_ddone
7218c2ecf20Sopenharmony_ci	ori.b		&0x8,%d4		# set 'N' bit
7228c2ecf20Sopenharmony_cimuls64_ddone:
7238c2ecf20Sopenharmony_ci	mov.w		%d4,%cc
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_ci# here, the result is in d1 and d0. the current strategy is to save
7268c2ecf20Sopenharmony_ci# the values at the location pointed to by a0.
7278c2ecf20Sopenharmony_ci# use movm here to not disturb the condition codes.
7288c2ecf20Sopenharmony_cimuls64_end:
7298c2ecf20Sopenharmony_ci	exg		%d1,%d0
7308c2ecf20Sopenharmony_ci	movm.l		&0x0003,([0x10,%a6])	# save result at (a0)
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci# EPILOGUE BEGIN ########################################################
7338c2ecf20Sopenharmony_ci#	fmovm.l		(%sp)+,&0x0		# restore no fpregs
7348c2ecf20Sopenharmony_ci	movm.l		(%sp)+,&0x003c		# restore d2-d5
7358c2ecf20Sopenharmony_ci	unlk		%a6
7368c2ecf20Sopenharmony_ci# EPILOGUE END ##########################################################
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci	rts
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci# one or both of the operands is zero so the result is also zero.
7418c2ecf20Sopenharmony_ci# save the zero result to the register file and set the 'Z' ccode bit.
7428c2ecf20Sopenharmony_cimuls64_zero:
7438c2ecf20Sopenharmony_ci	clr.l		%d0
7448c2ecf20Sopenharmony_ci	clr.l		%d1
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_ci	mov.w		MUL64_CC(%a6),%d4
7478c2ecf20Sopenharmony_ci	andi.b		&0x10,%d4
7488c2ecf20Sopenharmony_ci	ori.b		&0x4,%d4
7498c2ecf20Sopenharmony_ci	mov.w		%d4,%cc			# set 'Z' ccode bit
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_ci	bra.b		muls64_end
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci#########################################################################
7548c2ecf20Sopenharmony_ci# XDEF ****************************************************************	#
7558c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Ab_(): Emulate "cmp2.b An,<ea>".			#
7568c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Aw_(): Emulate "cmp2.w An,<ea>".			#
7578c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Al_(): Emulate "cmp2.l An,<ea>".			#
7588c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Db_(): Emulate "cmp2.b Dn,<ea>".			#
7598c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Dw_(): Emulate "cmp2.w Dn,<ea>".			#
7608c2ecf20Sopenharmony_ci#	_060LSP__cmp2_Dl_(): Emulate "cmp2.l Dn,<ea>".			#
7618c2ecf20Sopenharmony_ci#									#
7628c2ecf20Sopenharmony_ci#	This is the library version which is accessed as a subroutine	#
7638c2ecf20Sopenharmony_ci#	and therefore does not work exactly like the 680X0 "cmp2"	#
7648c2ecf20Sopenharmony_ci#	instruction.							#
7658c2ecf20Sopenharmony_ci#									#
7668c2ecf20Sopenharmony_ci# XREF ****************************************************************	#
7678c2ecf20Sopenharmony_ci#	None								#
7688c2ecf20Sopenharmony_ci#									#
7698c2ecf20Sopenharmony_ci# INPUT ***************************************************************	#
7708c2ecf20Sopenharmony_ci#	0x4(sp) = Rn							#
7718c2ecf20Sopenharmony_ci#	0x8(sp) = pointer to boundary pair				#
7728c2ecf20Sopenharmony_ci#									#
7738c2ecf20Sopenharmony_ci# OUTPUT **************************************************************	#
7748c2ecf20Sopenharmony_ci#	cc = condition codes are set correctly				#
7758c2ecf20Sopenharmony_ci#									#
7768c2ecf20Sopenharmony_ci# ALGORITHM ***********************************************************	#
7778c2ecf20Sopenharmony_ci#	In the interest of simplicity, all operands are converted to	#
7788c2ecf20Sopenharmony_ci# longword size whether the operation is byte, word, or long. The	#
7798c2ecf20Sopenharmony_ci# bounds are sign extended accordingly. If Rn is a data register, Rn is #
7808c2ecf20Sopenharmony_ci# also sign extended. If Rn is an address register, it need not be sign #
7818c2ecf20Sopenharmony_ci# extended since the full register is always used.			#
7828c2ecf20Sopenharmony_ci#	The condition codes are set correctly before the final "rts".	#
7838c2ecf20Sopenharmony_ci#									#
7848c2ecf20Sopenharmony_ci#########################################################################
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ciset	CMP2_CC,	-4
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Ab_
7898c2ecf20Sopenharmony_ci_060LSP__cmp2_Ab_:
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
7928c2ecf20Sopenharmony_ci	link.w		%a6,&-4
7938c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
7948c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
7958c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
7988c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	mov.b		([0xc,%a6],0x0),%d0
8018c2ecf20Sopenharmony_ci	mov.b		([0xc,%a6],0x1),%d1
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ci	extb.l		%d0			# sign extend lo bnd
8048c2ecf20Sopenharmony_ci	extb.l		%d1			# sign extend hi bnd
8058c2ecf20Sopenharmony_ci	bra.w		l_cmp2_cmp		# go do the compare emulation
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Aw_
8088c2ecf20Sopenharmony_ci_060LSP__cmp2_Aw_:
8098c2ecf20Sopenharmony_ci
8108c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
8118c2ecf20Sopenharmony_ci	link.w		%a6,&-4
8128c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
8138c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
8148c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
8178c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ci	mov.w		([0xc,%a6],0x0),%d0
8208c2ecf20Sopenharmony_ci	mov.w		([0xc,%a6],0x2),%d1
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ci	ext.l		%d0			# sign extend lo bnd
8238c2ecf20Sopenharmony_ci	ext.l		%d1			# sign extend hi bnd
8248c2ecf20Sopenharmony_ci	bra.w		l_cmp2_cmp		# go do the compare emulation
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Al_
8278c2ecf20Sopenharmony_ci_060LSP__cmp2_Al_:
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
8308c2ecf20Sopenharmony_ci	link.w		%a6,&-4
8318c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
8328c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
8338c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
8368c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_ci	mov.l		([0xc,%a6],0x0),%d0
8398c2ecf20Sopenharmony_ci	mov.l		([0xc,%a6],0x4),%d1
8408c2ecf20Sopenharmony_ci	bra.w		l_cmp2_cmp		# go do the compare emulation
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Db_
8438c2ecf20Sopenharmony_ci_060LSP__cmp2_Db_:
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
8468c2ecf20Sopenharmony_ci	link.w		%a6,&-4
8478c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
8488c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
8498c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
8528c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	mov.b		([0xc,%a6],0x0),%d0
8558c2ecf20Sopenharmony_ci	mov.b		([0xc,%a6],0x1),%d1
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	extb.l		%d0			# sign extend lo bnd
8588c2ecf20Sopenharmony_ci	extb.l		%d1			# sign extend hi bnd
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci# operation is a data register compare.
8618c2ecf20Sopenharmony_ci# sign extend byte to long so we can do simple longword compares.
8628c2ecf20Sopenharmony_ci	extb.l		%d2			# sign extend data byte
8638c2ecf20Sopenharmony_ci	bra.w		l_cmp2_cmp		# go do the compare emulation
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Dw_
8668c2ecf20Sopenharmony_ci_060LSP__cmp2_Dw_:
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
8698c2ecf20Sopenharmony_ci	link.w		%a6,&-4
8708c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
8718c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
8728c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
8758c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci	mov.w		([0xc,%a6],0x0),%d0
8788c2ecf20Sopenharmony_ci	mov.w		([0xc,%a6],0x2),%d1
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci	ext.l		%d0			# sign extend lo bnd
8818c2ecf20Sopenharmony_ci	ext.l		%d1			# sign extend hi bnd
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_ci# operation is a data register compare.
8848c2ecf20Sopenharmony_ci# sign extend word to long so we can do simple longword compares.
8858c2ecf20Sopenharmony_ci	ext.l		%d2			# sign extend data word
8868c2ecf20Sopenharmony_ci	bra.w		l_cmp2_cmp		# go emulate compare
8878c2ecf20Sopenharmony_ci
8888c2ecf20Sopenharmony_ci	global		_060LSP__cmp2_Dl_
8898c2ecf20Sopenharmony_ci_060LSP__cmp2_Dl_:
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci# PROLOGUE BEGIN ########################################################
8928c2ecf20Sopenharmony_ci	link.w		%a6,&-4
8938c2ecf20Sopenharmony_ci	movm.l		&0x3800,-(%sp)		# save d2-d4
8948c2ecf20Sopenharmony_ci#	fmovm.l		&0x0,-(%sp)		# save no fpregs
8958c2ecf20Sopenharmony_ci# PROLOGUE END ##########################################################
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	mov.w		%cc,CMP2_CC(%a6)
8988c2ecf20Sopenharmony_ci	mov.l		0x8(%a6), %d2		# get regval
8998c2ecf20Sopenharmony_ci
9008c2ecf20Sopenharmony_ci	mov.l		([0xc,%a6],0x0),%d0
9018c2ecf20Sopenharmony_ci	mov.l		([0xc,%a6],0x4),%d1
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ci#
9048c2ecf20Sopenharmony_ci# To set the ccodes correctly:
9058c2ecf20Sopenharmony_ci#	(1) save 'Z' bit from (Rn - lo)
9068c2ecf20Sopenharmony_ci#	(2) save 'Z' and 'N' bits from ((hi - lo) - (Rn - hi))
9078c2ecf20Sopenharmony_ci#	(3) keep 'X', 'N', and 'V' from before instruction
9088c2ecf20Sopenharmony_ci#	(4) combine ccodes
9098c2ecf20Sopenharmony_ci#
9108c2ecf20Sopenharmony_cil_cmp2_cmp:
9118c2ecf20Sopenharmony_ci	sub.l		%d0, %d2		# (Rn - lo)
9128c2ecf20Sopenharmony_ci	mov.w		%cc, %d3		# fetch resulting ccodes
9138c2ecf20Sopenharmony_ci	andi.b		&0x4, %d3		# keep 'Z' bit
9148c2ecf20Sopenharmony_ci	sub.l		%d0, %d1		# (hi - lo)
9158c2ecf20Sopenharmony_ci	cmp.l		%d1,%d2			# ((hi - lo) - (Rn - hi))
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci	mov.w		%cc, %d4		# fetch resulting ccodes
9188c2ecf20Sopenharmony_ci	or.b		%d4, %d3		# combine w/ earlier ccodes
9198c2ecf20Sopenharmony_ci	andi.b		&0x5, %d3		# keep 'Z' and 'N'
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci	mov.w		CMP2_CC(%a6), %d4	# fetch old ccodes
9228c2ecf20Sopenharmony_ci	andi.b		&0x1a, %d4		# keep 'X','N','V' bits
9238c2ecf20Sopenharmony_ci	or.b		%d3, %d4		# insert new ccodes
9248c2ecf20Sopenharmony_ci	mov.w		%d4,%cc			# save new ccodes
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_ci# EPILOGUE BEGIN ########################################################
9278c2ecf20Sopenharmony_ci#	fmovm.l		(%sp)+,&0x0		# restore no fpregs
9288c2ecf20Sopenharmony_ci	movm.l		(%sp)+,&0x001c		# restore d2-d4
9298c2ecf20Sopenharmony_ci	unlk		%a6
9308c2ecf20Sopenharmony_ci# EPILOGUE END ##########################################################
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_ci	rts
933