11590Srgrimes//===----------------------Hexagon builtin routine ------------------------===//
21590Srgrimes//
31590Srgrimes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41590Srgrimes// See https://llvm.org/LICENSE.txt for license information.
51590Srgrimes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61590Srgrimes//
71590Srgrimes//===----------------------------------------------------------------------===//
81590Srgrimes
91590Srgrimes// Double Precision Divide
101590Srgrimes
111590Srgrimes#define A r1:0
121590Srgrimes#define AH r1
131590Srgrimes#define AL r0
141590Srgrimes
151590Srgrimes#define B r3:2
161590Srgrimes#define BH r3
171590Srgrimes#define BL r2
181590Srgrimes
191590Srgrimes#define Q r5:4
201590Srgrimes#define QH r5
211590Srgrimes#define QL r4
221590Srgrimes
231590Srgrimes#define PROD r7:6
241590Srgrimes#define PRODHI r7
251590Srgrimes#define PRODLO r6
261590Srgrimes
271590Srgrimes#define SFONE r8
281590Srgrimes#define SFDEN r9
291590Srgrimes#define SFERROR r10
301590Srgrimes#define SFRECIP r11
311590Srgrimes
321590Srgrimes#define EXPBA r13:12
331590Srgrimes#define EXPB r13
341590Srgrimes#define EXPA r12
351590Srgrimes
361590Srgrimes#define REMSUB2 r15:14
371590Srgrimes
381590Srgrimes
391590Srgrimes
401590Srgrimes#define SIGN r28
411590Srgrimes
421590Srgrimes#define Q_POSITIVE p3
431590Srgrimes#define NORMAL p2
441590Srgrimes#define NO_OVF_UNF p1
451590Srgrimes#define P_TMP p0
461590Srgrimes
471590Srgrimes#define RECIPEST_SHIFT 3
481590Srgrimes#define QADJ 61
491590Srgrimes
501590Srgrimes#define DFCLASS_NORMAL 0x02
511590Srgrimes#define DFCLASS_NUMBER 0x0F
521590Srgrimes#define DFCLASS_INFINITE 0x08
531590Srgrimes#define DFCLASS_ZERO 0x01
541590Srgrimes#define DFCLASS_NONZERO (DFCLASS_NUMBER ^ DFCLASS_ZERO)
551590Srgrimes#define DFCLASS_NONINFINITE (DFCLASS_NUMBER ^ DFCLASS_INFINITE)
561590Srgrimes
571590Srgrimes#define DF_MANTBITS 52
581590Srgrimes#define DF_EXPBITS 11
591590Srgrimes#define SF_MANTBITS 23
601590Srgrimes#define SF_EXPBITS 8
611590Srgrimes#define DF_BIAS 0x3ff
621590Srgrimes
631590Srgrimes#define SR_ROUND_OFF 22
641590Srgrimes
651590Srgrimes#define Q6_ALIAS(TAG) .global __qdsp_##TAG ; .set __qdsp_##TAG, __hexagon_##TAG
661590Srgrimes#define FAST_ALIAS(TAG) .global __hexagon_fast_##TAG ; .set __hexagon_fast_##TAG, __hexagon_##TAG
671590Srgrimes#define FAST2_ALIAS(TAG) .global __hexagon_fast2_##TAG ; .set __hexagon_fast2_##TAG, __hexagon_##TAG
681590Srgrimes#define END(TAG) .size TAG,.-TAG
691590Srgrimes
701590Srgrimes	.text
711590Srgrimes	.global __hexagon_divdf3
721590Srgrimes	.type __hexagon_divdf3,@function
731590Srgrimes	Q6_ALIAS(divdf3)
741590Srgrimes        FAST_ALIAS(divdf3)
751590Srgrimes        FAST2_ALIAS(divdf3)
761590Srgrimes	.p2align 5
771590Srgrimes__hexagon_divdf3:
781590Srgrimes	{
791590Srgrimes		NORMAL = dfclass(A,#DFCLASS_NORMAL)
801590Srgrimes		NORMAL = dfclass(B,#DFCLASS_NORMAL)
811590Srgrimes		EXPBA = combine(BH,AH)
821590Srgrimes		SIGN = xor(AH,BH)
831590Srgrimes	}
841590Srgrimes#undef A
851590Srgrimes#undef AH
861590Srgrimes#undef AL
871590Srgrimes#undef B
881590Srgrimes#undef BH
891590Srgrimes#undef BL
901590Srgrimes#define REM r1:0
911590Srgrimes#define REMHI r1
921590Srgrimes#define REMLO r0
931590Srgrimes#define DENOM r3:2
941590Srgrimes#define DENOMHI r3
951590Srgrimes#define DENOMLO r2
961590Srgrimes	{
971590Srgrimes		if (!NORMAL) jump .Ldiv_abnormal
981590Srgrimes		PROD = extractu(DENOM,#SF_MANTBITS,#DF_MANTBITS-SF_MANTBITS)
991590Srgrimes		SFONE = ##0x3f800001
1001590Srgrimes	}
1011590Srgrimes	{
1021590Srgrimes		SFDEN = or(SFONE,PRODLO)
1031590Srgrimes		EXPB = extractu(EXPB,#DF_EXPBITS,#DF_MANTBITS-32)
1041590Srgrimes		EXPA = extractu(EXPA,#DF_EXPBITS,#DF_MANTBITS-32)
1051590Srgrimes		Q_POSITIVE = cmp.gt(SIGN,#-1)
1061590Srgrimes	}
1071590Srgrimes#undef SIGN
1081590Srgrimes#define ONE r28
1091590Srgrimes.Ldenorm_continue:
1101590Srgrimes	{
1111590Srgrimes		SFRECIP,P_TMP = sfrecipa(SFONE,SFDEN)
1121590Srgrimes		SFERROR = and(SFONE,#-2)
1131590Srgrimes		ONE = #1
1141590Srgrimes		EXPA = sub(EXPA,EXPB)
1151590Srgrimes	}
1161590Srgrimes#undef EXPB
1171590Srgrimes#define RECIPEST r13
1181590Srgrimes	{
1191590Srgrimes		SFERROR -= sfmpy(SFRECIP,SFDEN):lib
1201590Srgrimes		REMHI = insert(ONE,#DF_EXPBITS+1,#DF_MANTBITS-32)
1211590Srgrimes		RECIPEST = ##0x00800000 << RECIPEST_SHIFT
1221590Srgrimes	}
1231590Srgrimes	{
1241590Srgrimes		SFRECIP += sfmpy(SFRECIP,SFERROR):lib
1251590Srgrimes		DENOMHI = insert(ONE,#DF_EXPBITS+1,#DF_MANTBITS-32)
1261590Srgrimes		SFERROR = and(SFONE,#-2)
1271590Srgrimes	}
1281590Srgrimes	{
1291590Srgrimes		SFERROR -= sfmpy(SFRECIP,SFDEN):lib
1301590Srgrimes		QH = #-DF_BIAS+1
1311590Srgrimes		QL = #DF_BIAS-1
1321590Srgrimes	}
1331590Srgrimes	{
1341590Srgrimes		SFRECIP += sfmpy(SFRECIP,SFERROR):lib
1351590Srgrimes		NO_OVF_UNF = cmp.gt(EXPA,QH)
1361590Srgrimes		NO_OVF_UNF = !cmp.gt(EXPA,QL)
1371590Srgrimes	}
1381590Srgrimes	{
1391590Srgrimes		RECIPEST = insert(SFRECIP,#SF_MANTBITS,#RECIPEST_SHIFT)
1401590Srgrimes		Q = #0
1411590Srgrimes		EXPA = add(EXPA,#-QADJ)
1421590Srgrimes	}
1431590Srgrimes#undef SFERROR
1441590Srgrimes#undef SFRECIP
1451590Srgrimes#define TMP r10
1461590Srgrimes#define TMP1 r11
1471590Srgrimes	{
1481590Srgrimes		RECIPEST = add(RECIPEST,#((-3) << RECIPEST_SHIFT))
1491590Srgrimes	}
1501590Srgrimes
1511590Srgrimes#define DIV_ITER1B(QSHIFTINSN,QSHIFT,REMSHIFT,EXTRA) \
1521590Srgrimes	{ \
1531590Srgrimes		PROD = mpyu(RECIPEST,REMHI); \
1541590Srgrimes		REM = asl(REM,# ## ( REMSHIFT )); \
1551590Srgrimes	}; \
1561590Srgrimes	{ \
1571590Srgrimes		PRODLO = # ## 0; \
1581590Srgrimes		REM -= mpyu(PRODHI,DENOMLO); \
1591590Srgrimes		REMSUB2 = mpyu(PRODHI,DENOMHI); \
1601590Srgrimes	}; \
1611590Srgrimes	{ \
1621590Srgrimes		Q += QSHIFTINSN(PROD, # ## ( QSHIFT )); \
1631590Srgrimes		REM -= asl(REMSUB2, # ## 32); \
1641590Srgrimes		EXTRA \
1651590Srgrimes	}
1661590Srgrimes
1671590Srgrimes
1681590Srgrimes	DIV_ITER1B(ASL,14,15,)
1691590Srgrimes	DIV_ITER1B(ASR,1,15,)
1701590Srgrimes	DIV_ITER1B(ASR,16,15,)
1711590Srgrimes	DIV_ITER1B(ASR,31,15,PROD=# ( 0 );)
1721590Srgrimes
1731590Srgrimes#undef REMSUB2
1741590Srgrimes#define TMPPAIR r15:14
1751590Srgrimes#define TMPPAIRHI r15
1761590Srgrimes#define TMPPAIRLO r14
1771590Srgrimes#undef RECIPEST
1781590Srgrimes#define EXPB r13
1791590Srgrimes	{
1801590Srgrimes		// compare or sub with carry
1811590Srgrimes		TMPPAIR = sub(REM,DENOM)
1821590Srgrimes		P_TMP = cmp.gtu(DENOM,REM)
1831590Srgrimes		// set up amt to add to q
1841590Srgrimes		if (!P_TMP.new) PRODLO  = #2
1851590Srgrimes	}
1861590Srgrimes	{
1871590Srgrimes		Q = add(Q,PROD)
1881590Srgrimes		if (!P_TMP) REM = TMPPAIR
1891590Srgrimes		TMPPAIR = #0
1901590Srgrimes	}
1911590Srgrimes	{
1921590Srgrimes		P_TMP = cmp.eq(REM,TMPPAIR)
1931590Srgrimes		if (!P_TMP.new) QL = or(QL,ONE)
1941590Srgrimes	}
1951590Srgrimes	{
1961590Srgrimes		PROD = neg(Q)
1971590Srgrimes	}
1981590Srgrimes	{
1991590Srgrimes		if (!Q_POSITIVE) Q = PROD
2001590Srgrimes	}
2011590Srgrimes#undef REM
2021590Srgrimes#undef REMHI
2031590Srgrimes#undef REMLO
2041590Srgrimes#undef DENOM
2051590Srgrimes#undef DENOMLO
2061590Srgrimes#undef DENOMHI
2071590Srgrimes#define A r1:0
2081590Srgrimes#define AH r1
2091590Srgrimes#define AL r0
2101590Srgrimes#define B r3:2
2111590Srgrimes#define BH r3
2121590Srgrimes#define BL r2
2131590Srgrimes	{
2141590Srgrimes		A = convert_d2df(Q)
2151590Srgrimes		if (!NO_OVF_UNF) jump .Ldiv_ovf_unf
2161590Srgrimes	}
2171590Srgrimes	{
2181590Srgrimes		AH += asl(EXPA,#DF_MANTBITS-32)
2191590Srgrimes		jumpr r31
2201590Srgrimes	}
2211590Srgrimes
2221590Srgrimes.Ldiv_ovf_unf:
2231590Srgrimes	{
2241590Srgrimes		AH += asl(EXPA,#DF_MANTBITS-32)
2251590Srgrimes		EXPB = extractu(AH,#DF_EXPBITS,#DF_MANTBITS-32)
2261590Srgrimes	}
2278874Srgrimes	{
2281590Srgrimes		PROD = abs(Q)
2291590Srgrimes		EXPA = add(EXPA,EXPB)
2301590Srgrimes	}
2311590Srgrimes	{
2321590Srgrimes		P_TMP = cmp.gt(EXPA,##DF_BIAS+DF_BIAS)		// overflow
2331590Srgrimes		if (P_TMP.new) jump:nt .Ldiv_ovf
2341590Srgrimes	}
2351590Srgrimes	{
2361590Srgrimes		P_TMP = cmp.gt(EXPA,#0)
2371590Srgrimes		if (P_TMP.new) jump:nt .Lpossible_unf		// round up to normal possible...
2381590Srgrimes	}
2391590Srgrimes	// Underflow
2401590Srgrimes	// We know what the infinite range exponent should be (EXPA)
2411590Srgrimes	// Q is 2's complement, PROD is abs(Q)
2421590Srgrimes	// Normalize Q, shift right, add a high bit, convert, change exponent
2431590Srgrimes
2441590Srgrimes#define FUDGE1 7	// how much to shift right
2451590Srgrimes#define FUDGE2 4	// how many guard/round to keep at lsbs
2461590Srgrimes
2471590Srgrimes	{
2481590Srgrimes		EXPB = add(clb(PROD),#-1)			// doesn't need to be added in since
2491590Srgrimes		EXPA = sub(#FUDGE1,EXPA)			// we extract post-converted exponent
2501590Srgrimes		TMP = USR
2511590Srgrimes		TMP1 = #63
2521590Srgrimes	}
2531590Srgrimes	{
2541590Srgrimes		EXPB = min(EXPA,TMP1)
2551590Srgrimes		TMP1 = or(TMP,#0x030)
2561590Srgrimes		PROD = asl(PROD,EXPB)
2571590Srgrimes		EXPA = #0
2581590Srgrimes	}
2591590Srgrimes	{
2601590Srgrimes		TMPPAIR = extractu(PROD,EXPBA)				// bits that will get shifted out
2611590Srgrimes		PROD = lsr(PROD,EXPB)					// shift out bits
2621590Srgrimes		B = #1
2631590Srgrimes	}
2641590Srgrimes	{
2651590Srgrimes		P_TMP = cmp.gtu(B,TMPPAIR)
2661590Srgrimes		if (!P_TMP.new) PRODLO = or(BL,PRODLO)
2671590Srgrimes		PRODHI = setbit(PRODHI,#DF_MANTBITS-32+FUDGE2)
2681590Srgrimes	}
2691590Srgrimes	{
2701590Srgrimes		Q = neg(PROD)
2711590Srgrimes		P_TMP = bitsclr(PRODLO,#(1<<FUDGE2)-1)
2721590Srgrimes		if (!P_TMP.new) TMP = TMP1
2731590Srgrimes	}
2741590Srgrimes	{
2751590Srgrimes		USR = TMP
2761590Srgrimes		if (Q_POSITIVE) Q = PROD
2771590Srgrimes		TMP = #-DF_BIAS-(DF_MANTBITS+FUDGE2)
2781590Srgrimes	}
2791590Srgrimes	{
2801590Srgrimes		A = convert_d2df(Q)
2811590Srgrimes	}
2821590Srgrimes	{
2831590Srgrimes		AH += asl(TMP,#DF_MANTBITS-32)
2841590Srgrimes		jumpr r31
2851590Srgrimes	}
2861590Srgrimes
2871590Srgrimes
2881590Srgrimes.Lpossible_unf:
2891590Srgrimes	// If upper parts of Q were all F's, but abs(A) == 0x00100000_00000000, we rounded up to min_normal
2901590Srgrimes	// The answer is correct, but we need to raise Underflow
2911590Srgrimes	{
2921590Srgrimes		B = extractu(A,#63,#0)
2931590Srgrimes		TMPPAIR = combine(##0x00100000,#0)		// min normal
2941590Srgrimes		TMP = #0x7FFF
2951590Srgrimes	}
2961590Srgrimes	{
2971590Srgrimes		P_TMP = dfcmp.eq(TMPPAIR,B)		// Is everything zero in the rounded value...
2981590Srgrimes		P_TMP = bitsset(PRODHI,TMP)		// but a bunch of bits set in the unrounded abs(quotient)?
2991590Srgrimes	}
3001590Srgrimes
3011590Srgrimes#if (__HEXAGON_ARCH__ == 60)
3021590Srgrimes		TMP = USR		// If not, just return
3031590Srgrimes		if (!P_TMP) jumpr r31   // Else, we want to set Unf+Inexact
3041590Srgrimes					// Note that inexact is already set...
3051590Srgrimes#else
3061590Srgrimes	{
3071590Srgrimes		if (!P_TMP) jumpr r31			// If not, just return
3081590Srgrimes		TMP = USR				// Else, we want to set Unf+Inexact
3091590Srgrimes	}						// Note that inexact is already set...
3101590Srgrimes#endif
3111590Srgrimes	{
3121590Srgrimes		TMP = or(TMP,#0x30)
3131590Srgrimes	}
3141590Srgrimes	{
3151590Srgrimes		USR = TMP
3161590Srgrimes	}
3171590Srgrimes	{
3181590Srgrimes		p0 = dfcmp.eq(A,A)
3191590Srgrimes		jumpr r31
3201590Srgrimes	}
3211590Srgrimes
3221590Srgrimes.Ldiv_ovf:
3231590Srgrimes
3241590Srgrimes	// Raise Overflow, and choose the correct overflow value (saturated normal or infinity)
3251590Srgrimes
3261590Srgrimes	{
3271590Srgrimes		TMP = USR
3281590Srgrimes		B = combine(##0x7fefffff,#-1)
3291590Srgrimes		AH = mux(Q_POSITIVE,#0,#-1)
3301590Srgrimes	}
3311590Srgrimes	{
3321590Srgrimes		PROD = combine(##0x7ff00000,#0)
3331590Srgrimes		QH = extractu(TMP,#2,#SR_ROUND_OFF)
3341590Srgrimes		TMP = or(TMP,#0x28)
3351590Srgrimes	}
3361590Srgrimes	{
3371590Srgrimes		USR = TMP
3381590Srgrimes		QH ^= lsr(AH,#31)
3391590Srgrimes		QL = QH
3401590Srgrimes	}
3411590Srgrimes	{
3421590Srgrimes		p0 = !cmp.eq(QL,#1)		// if not round-to-zero
3431590Srgrimes		p0 = !cmp.eq(QH,#2)		// and not rounding the other way
3441590Srgrimes		if (p0.new) B = PROD		// go to inf
3451590Srgrimes		p0 = dfcmp.eq(B,B)		// get exceptions
3461590Srgrimes	}
3471590Srgrimes	{
3481590Srgrimes		A = insert(B,#63,#0)
3491590Srgrimes		jumpr r31
3501590Srgrimes	}
3511590Srgrimes
3521590Srgrimes#undef ONE
3531590Srgrimes#define SIGN r28
3541590Srgrimes#undef NORMAL
3551590Srgrimes#undef NO_OVF_UNF
3561590Srgrimes#define P_INF p1
3571590Srgrimes#define P_ZERO p2
3581590Srgrimes.Ldiv_abnormal:
3591590Srgrimes	{
3601590Srgrimes		P_TMP = dfclass(A,#DFCLASS_NUMBER)
3611590Srgrimes		P_TMP = dfclass(B,#DFCLASS_NUMBER)
3621590Srgrimes		Q_POSITIVE = cmp.gt(SIGN,#-1)
3631590Srgrimes	}
3641590Srgrimes	{
3651590Srgrimes		P_INF = dfclass(A,#DFCLASS_INFINITE)
3661590Srgrimes		P_INF = dfclass(B,#DFCLASS_INFINITE)
3671590Srgrimes	}
3681590Srgrimes	{
3691590Srgrimes		P_ZERO = dfclass(A,#DFCLASS_ZERO)
3701590Srgrimes		P_ZERO = dfclass(B,#DFCLASS_ZERO)
3711590Srgrimes	}
3721590Srgrimes	{
3731590Srgrimes		if (!P_TMP) jump .Ldiv_nan
3741590Srgrimes		if (P_INF) jump .Ldiv_invalid
3751590Srgrimes	}
3761590Srgrimes	{
3771590Srgrimes		if (P_ZERO) jump .Ldiv_invalid
3781590Srgrimes	}
3791590Srgrimes	{
3801590Srgrimes		P_ZERO = dfclass(A,#DFCLASS_NONZERO)		// nonzero
3811590Srgrimes		P_ZERO = dfclass(B,#DFCLASS_NONINFINITE)	// non-infinite
3821590Srgrimes	}
3831590Srgrimes	{
3841590Srgrimes		P_INF = dfclass(A,#DFCLASS_NONINFINITE)	// non-infinite
3851590Srgrimes		P_INF = dfclass(B,#DFCLASS_NONZERO)	// nonzero
3861590Srgrimes	}
3871590Srgrimes	{
3881590Srgrimes		if (!P_ZERO) jump .Ldiv_zero_result
3891590Srgrimes		if (!P_INF) jump .Ldiv_inf_result
3901590Srgrimes	}
3911590Srgrimes	// Now we've narrowed it down to (de)normal / (de)normal
3921590Srgrimes	// Set up A/EXPA B/EXPB and go back
3931590Srgrimes#undef P_ZERO
3941590Srgrimes#undef P_INF
3951590Srgrimes#define P_TMP2 p1
3961590Srgrimes	{
3971590Srgrimes		P_TMP = dfclass(A,#DFCLASS_NORMAL)
3981590Srgrimes		P_TMP2 = dfclass(B,#DFCLASS_NORMAL)
3991590Srgrimes		TMP = ##0x00100000
4001590Srgrimes	}
4011590Srgrimes	{
4021590Srgrimes		EXPBA = combine(BH,AH)
4031590Srgrimes		AH = insert(TMP,#DF_EXPBITS+1,#DF_MANTBITS-32)		// clear out hidden bit, sign bit
4041590Srgrimes		BH = insert(TMP,#DF_EXPBITS+1,#DF_MANTBITS-32)		// clear out hidden bit, sign bit
4051590Srgrimes	}
4061590Srgrimes	{
4071590Srgrimes		if (P_TMP) AH = or(AH,TMP)				// if normal, add back in hidden bit
4081590Srgrimes		if (P_TMP2) BH = or(BH,TMP)				// if normal, add back in hidden bit
4091590Srgrimes	}
4101590Srgrimes	{
4111590Srgrimes		QH = add(clb(A),#-DF_EXPBITS)
4121590Srgrimes		QL = add(clb(B),#-DF_EXPBITS)
4131590Srgrimes		TMP = #1
4141590Srgrimes	}
4151590Srgrimes	{
4161590Srgrimes		EXPA = extractu(EXPA,#DF_EXPBITS,#DF_MANTBITS-32)
4171590Srgrimes		EXPB = extractu(EXPB,#DF_EXPBITS,#DF_MANTBITS-32)
4181590Srgrimes	}
4198874Srgrimes	{
4201590Srgrimes		A = asl(A,QH)
4211590Srgrimes		B = asl(B,QL)
4221590Srgrimes		if (!P_TMP) EXPA = sub(TMP,QH)
4231590Srgrimes		if (!P_TMP2) EXPB = sub(TMP,QL)
4241590Srgrimes	}	// recreate values needed by resume coke
4251590Srgrimes	{
4261590Srgrimes		PROD = extractu(B,#SF_MANTBITS,#DF_MANTBITS-SF_MANTBITS)
4271590Srgrimes	}
4281590Srgrimes	{
4291590Srgrimes		SFDEN = or(SFONE,PRODLO)
4301590Srgrimes		jump .Ldenorm_continue
4311590Srgrimes	}
4321590Srgrimes
4331590Srgrimes.Ldiv_zero_result:
4341590Srgrimes	{
4351590Srgrimes		AH = xor(AH,BH)
4361590Srgrimes		B = #0
4371590Srgrimes	}
4381590Srgrimes	{
4391590Srgrimes		A = insert(B,#63,#0)
4401590Srgrimes		jumpr r31
4411590Srgrimes	}
4421590Srgrimes.Ldiv_inf_result:
4431590Srgrimes	{
4441590Srgrimes		p2 = dfclass(B,#DFCLASS_ZERO)
4451590Srgrimes		p2 = dfclass(A,#DFCLASS_NONINFINITE)
4461590Srgrimes	}
4471590Srgrimes	{
4481590Srgrimes		TMP = USR
4491590Srgrimes		if (!p2) jump 1f
4501590Srgrimes		AH = xor(AH,BH)
4511590Srgrimes	}
4521590Srgrimes	{
4531590Srgrimes		TMP = or(TMP,#0x04)		// DBZ
4541590Srgrimes	}
4551590Srgrimes	{
4561590Srgrimes		USR = TMP
4571590Srgrimes	}
4581590Srgrimes1:
4591590Srgrimes	{
4601590Srgrimes		B = combine(##0x7ff00000,#0)
4611590Srgrimes		p0 = dfcmp.uo(B,B)		// take possible exception
4621590Srgrimes	}
4631590Srgrimes	{
4641590Srgrimes		A = insert(B,#63,#0)
4651590Srgrimes		jumpr r31
4661590Srgrimes	}
4671590Srgrimes.Ldiv_nan:
4681590Srgrimes	{
4691590Srgrimes		p0 = dfclass(A,#0x10)
4701590Srgrimes		p1 = dfclass(B,#0x10)
4711590Srgrimes		if (!p0.new) A = B
4721590Srgrimes		if (!p1.new) B = A
4731590Srgrimes	}
4741590Srgrimes	{
4751590Srgrimes		QH = convert_df2sf(A)	// get possible invalid exceptions
4761590Srgrimes		QL = convert_df2sf(B)
4771590Srgrimes	}
4781590Srgrimes	{
4791590Srgrimes		A = #-1
4801590Srgrimes		jumpr r31
4811590Srgrimes	}
4821590Srgrimes
4831590Srgrimes.Ldiv_invalid:
4841590Srgrimes	{
4851590Srgrimes		TMP = ##0x7f800001
4861590Srgrimes	}
4871590Srgrimes	{
4881590Srgrimes		A = convert_sf2df(TMP)		// get invalid, get DF qNaN
4891590Srgrimes		jumpr r31
4901590Srgrimes	}
4911590SrgrimesEND(__hexagon_divdf3)
4921590Srgrimes