xref: /titanic_50/usr/src/uts/sun4u/ml/mach_subr_asm.s (revision 023e71de9e5670cebc23dd51162833661d3d2d3b)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57bafd143Sjb145095 * Common Development and Distribution License (the "License").
67bafd143Sjb145095 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
22*023e71deSHaik Aftandilian * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate/*
277c478bd9Sstevel@tonic-gate * General machine architecture & implementation specific
287c478bd9Sstevel@tonic-gate * assembly language routines.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate#if defined(lint)
317c478bd9Sstevel@tonic-gate#include <sys/types.h>
327c478bd9Sstevel@tonic-gate#include <sys/t_lock.h>
337c478bd9Sstevel@tonic-gate#else	/* lint */
347c478bd9Sstevel@tonic-gate#include "assym.h"
357c478bd9Sstevel@tonic-gate#endif	/* lint */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
387c478bd9Sstevel@tonic-gate#include <sys/machsystm.h>
397c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
407c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
417c478bd9Sstevel@tonic-gate#include <sys/cmpregs.h>
427c478bd9Sstevel@tonic-gate#include <sys/clock.h>
437c478bd9Sstevel@tonic-gate#include <sys/fpras.h>
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate#if defined(lint)
467c478bd9Sstevel@tonic-gate
47*023e71deSHaik Aftandilianuint64_t
48*023e71deSHaik Aftandilianultra_gettick(void)
49*023e71deSHaik Aftandilian{ return (0); }
50*023e71deSHaik Aftandilian
51*023e71deSHaik Aftandilian#else	/* lint */
52*023e71deSHaik Aftandilian
53*023e71deSHaik Aftandilian/*
54*023e71deSHaik Aftandilian * This isn't the routine you're looking for.
55*023e71deSHaik Aftandilian *
56*023e71deSHaik Aftandilian * The routine simply returns the value of %tick on the *current* processor.
57*023e71deSHaik Aftandilian * Most of the time, gettick() [which in turn maps to %stick on platforms
58*023e71deSHaik Aftandilian * that have different CPU %tick rates] is what you want.
59*023e71deSHaik Aftandilian */
60*023e71deSHaik Aftandilian
61*023e71deSHaik Aftandilian	ENTRY(ultra_gettick)
62*023e71deSHaik Aftandilian	retl
63*023e71deSHaik Aftandilian	rdpr	%tick, %o0
64*023e71deSHaik Aftandilian	SET_SIZE(ultra_gettick)
65*023e71deSHaik Aftandilian
66*023e71deSHaik Aftandilian#endif	/* lint */
67*023e71deSHaik Aftandilian
68*023e71deSHaik Aftandilian#if defined(lint)
69*023e71deSHaik Aftandilian
707c478bd9Sstevel@tonic-gate/*ARGSUSED*/
717c478bd9Sstevel@tonic-gateint
727c478bd9Sstevel@tonic-gategetprocessorid(void)
737c478bd9Sstevel@tonic-gate{ return (0); }
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate#else	/* lint */
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate/*
787c478bd9Sstevel@tonic-gate * Get the processor ID.
797c478bd9Sstevel@tonic-gate * === MID reg as specified in 15dec89 sun4u spec, sec 5.4.3
807c478bd9Sstevel@tonic-gate */
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate	ENTRY(getprocessorid)
837c478bd9Sstevel@tonic-gate	CPU_INDEX(%o0, %o1)
847c478bd9Sstevel@tonic-gate	retl
857c478bd9Sstevel@tonic-gate	nop
867c478bd9Sstevel@tonic-gate	SET_SIZE(getprocessorid)
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate#endif	/* lint */
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate#if defined(lint)
917c478bd9Sstevel@tonic-gate/*ARGSUSED*/
927c478bd9Sstevel@tonic-gatevoid
937c478bd9Sstevel@tonic-gateset_error_enable_tl1(uint64_t neer, uint64_t action)
947c478bd9Sstevel@tonic-gate{}
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate/* ARGSUSED */
977c478bd9Sstevel@tonic-gatevoid
987c478bd9Sstevel@tonic-gateset_error_enable(uint64_t neer)
997c478bd9Sstevel@tonic-gate{}
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gateuint64_t
1027c478bd9Sstevel@tonic-gateget_error_enable()
1037c478bd9Sstevel@tonic-gate{
1047c478bd9Sstevel@tonic-gate	return ((uint64_t)0);
1057c478bd9Sstevel@tonic-gate}
1067c478bd9Sstevel@tonic-gate#else /* lint */
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate	ENTRY(set_error_enable_tl1)
1097c478bd9Sstevel@tonic-gate	cmp	%g2, EER_SET_ABSOLUTE
1107c478bd9Sstevel@tonic-gate	be	%xcc, 1f
1117c478bd9Sstevel@tonic-gate	  nop
1127c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
1137c478bd9Sstevel@tonic-gate	membar	#Sync
1147c478bd9Sstevel@tonic-gate	cmp	%g2, EER_SET_SETBITS
1157c478bd9Sstevel@tonic-gate	be,a	%xcc, 1f
1167c478bd9Sstevel@tonic-gate	  or	%g3, %g1, %g1
1177c478bd9Sstevel@tonic-gate	andn	%g3, %g1, %g1			/* EER_SET_CLRBITS */
1187c478bd9Sstevel@tonic-gate1:
1197c478bd9Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_ESTATE_ERR	/* ecache error enable reg */
1207c478bd9Sstevel@tonic-gate	membar	#Sync
1217c478bd9Sstevel@tonic-gate	retry
1227c478bd9Sstevel@tonic-gate	SET_SIZE(set_error_enable_tl1)
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate	ENTRY(set_error_enable)
1257c478bd9Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_ESTATE_ERR	/* ecache error enable reg */
1267c478bd9Sstevel@tonic-gate	membar	#Sync
1277c478bd9Sstevel@tonic-gate	retl
1287c478bd9Sstevel@tonic-gate	nop
1297c478bd9Sstevel@tonic-gate	SET_SIZE(set_error_enable)
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate	ENTRY(get_error_enable)
1327c478bd9Sstevel@tonic-gate	retl
1337c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %o0	/* ecache error enable reg */
1347c478bd9Sstevel@tonic-gate	SET_SIZE(get_error_enable)
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate#endif /* lint */
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate#if defined(lint)
1397c478bd9Sstevel@tonic-gatevoid
1407c478bd9Sstevel@tonic-gateget_asyncflt(uint64_t *afsr)
1417c478bd9Sstevel@tonic-gate{
1427c478bd9Sstevel@tonic-gate	afsr = afsr;
1437c478bd9Sstevel@tonic-gate}
1447c478bd9Sstevel@tonic-gate#else /* lint */
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate	ENTRY(get_asyncflt)
1477c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_AFSR, %o1		! afsr reg
1487c478bd9Sstevel@tonic-gate	retl
1497c478bd9Sstevel@tonic-gate	stx	%o1, [%o0]
1507c478bd9Sstevel@tonic-gate	SET_SIZE(get_asyncflt)
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate#endif /* lint */
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate#if defined(lint)
1557c478bd9Sstevel@tonic-gatevoid
1567c478bd9Sstevel@tonic-gateset_asyncflt(uint64_t afsr)
1577c478bd9Sstevel@tonic-gate{
1587c478bd9Sstevel@tonic-gate	afsr = afsr;
1597c478bd9Sstevel@tonic-gate}
1607c478bd9Sstevel@tonic-gate#else /* lint */
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate	ENTRY(set_asyncflt)
1637c478bd9Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_AFSR		! afsr reg
1647c478bd9Sstevel@tonic-gate	membar	#Sync
1657c478bd9Sstevel@tonic-gate	retl
1667c478bd9Sstevel@tonic-gate	nop
1677c478bd9Sstevel@tonic-gate	SET_SIZE(set_asyncflt)
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate#endif /* lint */
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate#if defined(lint)
1727c478bd9Sstevel@tonic-gatevoid
1737c478bd9Sstevel@tonic-gateget_asyncaddr(uint64_t *afar)
1747c478bd9Sstevel@tonic-gate{
1757c478bd9Sstevel@tonic-gate	afar = afar;
1767c478bd9Sstevel@tonic-gate}
1777c478bd9Sstevel@tonic-gate#else /* lint */
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate	ENTRY(get_asyncaddr)
1807c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_AFAR, %o1		! afar reg
1817c478bd9Sstevel@tonic-gate	retl
1827c478bd9Sstevel@tonic-gate	stx	%o1, [%o0]
1837c478bd9Sstevel@tonic-gate	SET_SIZE(get_asyncaddr)
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate#endif /* lint */
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate#if defined(lint) || defined(__lint)
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate/* ARGSUSED */
1907c478bd9Sstevel@tonic-gatehrtime_t
1917c478bd9Sstevel@tonic-gatetick2ns(hrtime_t tick, uint_t cpuid)
1927c478bd9Sstevel@tonic-gate{ return 0; }
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate#else	/* lint */
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate	ENTRY_NP(tick2ns)
1977c478bd9Sstevel@tonic-gate	sethi	%hi(cpunodes), %o4
1987c478bd9Sstevel@tonic-gate	or	%o4, %lo(cpunodes), %o4		! %o4 = &cpunodes
1997c478bd9Sstevel@tonic-gate	! Register usage:
2007c478bd9Sstevel@tonic-gate	!
2017c478bd9Sstevel@tonic-gate	! o0 = timestamp
2027c478bd9Sstevel@tonic-gate	! o2 = byte offset into cpunodes for tick_nsec_scale of this CPU
2037c478bd9Sstevel@tonic-gate	! o4 = &cpunodes
2047c478bd9Sstevel@tonic-gate	!
2057c478bd9Sstevel@tonic-gate	mulx	%o1, CPU_NODE_SIZE, %o2	! %o2 = byte offset into cpunodes
2067c478bd9Sstevel@tonic-gate	add	%o2, TICK_NSEC_SCALE, %o2
2077c478bd9Sstevel@tonic-gate	ld	[%o4 + %o2], %o2	! %o2 = cpunodes[cpuid].tick_nsec_scale
2087c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC_SCALE(%o0, %o2, %o3, TICK_NSEC_SHIFT)
2097c478bd9Sstevel@tonic-gate	retl
2107c478bd9Sstevel@tonic-gate	nop
2117c478bd9Sstevel@tonic-gate	SET_SIZE(tick2ns)
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate#endif  /* lint */
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate#if defined(lint)
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate/* ARGSUSED */
2187c478bd9Sstevel@tonic-gatevoid
2197c478bd9Sstevel@tonic-gateset_cmp_error_steering(void)
2207c478bd9Sstevel@tonic-gate{}
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate#else	/* lint */
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate	ENTRY(set_cmp_error_steering)
2257c478bd9Sstevel@tonic-gate	membar	#Sync
2267c478bd9Sstevel@tonic-gate	set	ASI_CORE_ID, %o0		! %o0 = ASI_CORE_ID
2277c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_CMP_PER_CORE, %o0	! get ASI_CORE_ID
2287c478bd9Sstevel@tonic-gate	and	%o0, COREID_MASK, %o0
2297c478bd9Sstevel@tonic-gate	set	ASI_CMP_ERROR_STEERING, %o1	! %o1 = ERROR_STEERING_REG
2307c478bd9Sstevel@tonic-gate	stxa	%o0, [%o1]ASI_CMP_SHARED	! this core now hadles
2317c478bd9Sstevel@tonic-gate	membar	#Sync				!  non-core specific errors
2327c478bd9Sstevel@tonic-gate	retl
2337c478bd9Sstevel@tonic-gate	nop
2347c478bd9Sstevel@tonic-gate	SET_SIZE(set_cmp_error_steering)
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate#endif	/* lint */
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate#if defined(lint)
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate/* ARGSUSED */
2417c478bd9Sstevel@tonic-gateuint64_t
2427c478bd9Sstevel@tonic-gateultra_getver(void)
2437c478bd9Sstevel@tonic-gate{
2447c478bd9Sstevel@tonic-gate	return (0);
2457c478bd9Sstevel@tonic-gate}
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate#else /* lint */
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate	ENTRY(ultra_getver)
2507c478bd9Sstevel@tonic-gate	retl
2517c478bd9Sstevel@tonic-gate	rdpr	%ver, %o0
2527c478bd9Sstevel@tonic-gate	SET_SIZE(ultra_getver)
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate#endif /* lint */
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate#if defined(lint)
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gateint
2597c478bd9Sstevel@tonic-gatefpras_chkfn_type1(void)
2607c478bd9Sstevel@tonic-gate{ return 0; }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate#else	/* lint */
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate	/*
2657c478bd9Sstevel@tonic-gate	 * Check instructions using just the AX pipelines, designed by
2667c478bd9Sstevel@tonic-gate	 * C.B. Liaw of PNP.
2677c478bd9Sstevel@tonic-gate	 *
2687c478bd9Sstevel@tonic-gate	 * This function must match a struct fpras_chkfn and must be
2697c478bd9Sstevel@tonic-gate	 * block aligned.  A zero return means all was well.  These
2707c478bd9Sstevel@tonic-gate	 * instructions are chosen to be sensitive to bit corruptions
2717c478bd9Sstevel@tonic-gate	 * on the fpras rewrite, so if a bit corruption still produces
2727c478bd9Sstevel@tonic-gate	 * a valid instruction we should still get an incorrect result
2737c478bd9Sstevel@tonic-gate	 * here.  This function is never called directly - it is copied
2747c478bd9Sstevel@tonic-gate	 * into per-cpu and per-operation buffers;  it must therefore
2757c478bd9Sstevel@tonic-gate	 * be absolutely position independent.  If an illegal instruction
2767c478bd9Sstevel@tonic-gate	 * is encountered then the trap handler trampolines to the final
2777c478bd9Sstevel@tonic-gate	 * three instructions of this function.
2787c478bd9Sstevel@tonic-gate	 *
2797c478bd9Sstevel@tonic-gate	 * We want two instructions that are complements of one another,
2807c478bd9Sstevel@tonic-gate	 * and which can perform a calculation with a known result.
2817c478bd9Sstevel@tonic-gate	 *
2827c478bd9Sstevel@tonic-gate	 * SETHI:
2837c478bd9Sstevel@tonic-gate	 *
2847c478bd9Sstevel@tonic-gate	 * | 0 0 |  rd   | 1 0 0 |	imm22				|
2857c478bd9Sstevel@tonic-gate	 *  31 30 29   25 24   22 21				       0
2867c478bd9Sstevel@tonic-gate	 *
2877c478bd9Sstevel@tonic-gate	 * ADDCCC with two source registers:
2887c478bd9Sstevel@tonic-gate	 *
2897c478bd9Sstevel@tonic-gate	 * | 1 0 |  rd   | 0 1 1   0 0 0 |  rs1  | 0 |	   -	|  rs2  |
2907c478bd9Sstevel@tonic-gate	 *  31 30 29   25 24           19 18   14 13  12       5 4     0
2917c478bd9Sstevel@tonic-gate	 *
2927c478bd9Sstevel@tonic-gate	 * We can choose rd and imm2 of the SETHI and rd, rs1 and rs2 of
2937c478bd9Sstevel@tonic-gate	 * the ADDCCC to obtain instructions that are complements in all but
2947c478bd9Sstevel@tonic-gate	 * bit 30.
2957c478bd9Sstevel@tonic-gate	 *
2967c478bd9Sstevel@tonic-gate	 * Registers are numbered as follows:
2977c478bd9Sstevel@tonic-gate	 *
2987c478bd9Sstevel@tonic-gate	 * r[31]	%i7
2997c478bd9Sstevel@tonic-gate	 * r[30]	%i6
3007c478bd9Sstevel@tonic-gate	 * r[29]	%i5
3017c478bd9Sstevel@tonic-gate	 * r[28]	%i4
3027c478bd9Sstevel@tonic-gate	 * r[27]	%i3
3037c478bd9Sstevel@tonic-gate	 * r[26]	%i2
3047c478bd9Sstevel@tonic-gate	 * r[25]	%i1
3057c478bd9Sstevel@tonic-gate	 * r[24]	%i0
3067c478bd9Sstevel@tonic-gate	 * r[23]	%l7
3077c478bd9Sstevel@tonic-gate	 * r[22]	%l6
3087c478bd9Sstevel@tonic-gate	 * r[21]	%l5
3097c478bd9Sstevel@tonic-gate	 * r[20]	%l4
3107c478bd9Sstevel@tonic-gate	 * r[19]	%l3
3117c478bd9Sstevel@tonic-gate	 * r[18]	%l2
3127c478bd9Sstevel@tonic-gate	 * r[17]	%l1
3137c478bd9Sstevel@tonic-gate	 * r[16]	%l0
3147c478bd9Sstevel@tonic-gate	 * r[15]	%o7
3157c478bd9Sstevel@tonic-gate	 * r[14]	%o6
3167c478bd9Sstevel@tonic-gate	 * r[13]	%o5
3177c478bd9Sstevel@tonic-gate	 * r[12]	%o4
3187c478bd9Sstevel@tonic-gate	 * r[11]	%o3
3197c478bd9Sstevel@tonic-gate	 * r[10]	%o2
3207c478bd9Sstevel@tonic-gate	 * r[9]		%o1
3217c478bd9Sstevel@tonic-gate	 * r[8]		%o0
3227c478bd9Sstevel@tonic-gate	 * r[7]		%g7
3237c478bd9Sstevel@tonic-gate	 * r[6]		%g6
3247c478bd9Sstevel@tonic-gate	 * r[5]		%g5
3257c478bd9Sstevel@tonic-gate	 * r[4]		%g4
3267c478bd9Sstevel@tonic-gate	 * r[3]		%g3
3277c478bd9Sstevel@tonic-gate	 * r[2]		%g2
3287c478bd9Sstevel@tonic-gate	 * r[1]		%g1
3297c478bd9Sstevel@tonic-gate	 * r[0]		%g0
3307c478bd9Sstevel@tonic-gate	 *
3317c478bd9Sstevel@tonic-gate	 * For register r[n], register r[31-n] is the complement.  We must
3327c478bd9Sstevel@tonic-gate	 * avoid use of %i6/%i7 and %o6/%o7 as well as %g7.  Clearly we need
3337c478bd9Sstevel@tonic-gate	 * to use a local or input register as one half of the pair, which
3347c478bd9Sstevel@tonic-gate	 * requires us to obtain our own register window or take steps
3357c478bd9Sstevel@tonic-gate	 * to preserve any local or input we choose to use.  We choose
3367c478bd9Sstevel@tonic-gate	 * %o1 as rd for the SETHI, so rd of the ADDCCC must be %l6.
3377c478bd9Sstevel@tonic-gate	 * We'll use %o1 as rs1 and %l6 as rs2 of the ADDCCC, which then
3387c478bd9Sstevel@tonic-gate	 * requires that imm22 be 0b111 10110 1 11111111 01001 or 0x3dbfe9,
3397c478bd9Sstevel@tonic-gate	 * or %hi(0xf6ffa400).  This determines the value of the constant
3407c478bd9Sstevel@tonic-gate	 * CBV2 below.
3417c478bd9Sstevel@tonic-gate	 *
3427c478bd9Sstevel@tonic-gate	 * The constant CBV1 is chosen such that an initial subcc %g0, CBV1
3437c478bd9Sstevel@tonic-gate	 * will set the carry bit and every addccc thereafter will continue
3447c478bd9Sstevel@tonic-gate	 * to generate a carry.  Other values are possible for CBV1 - this
3457c478bd9Sstevel@tonic-gate	 * is just one that works this way.
3467c478bd9Sstevel@tonic-gate	 *
3477c478bd9Sstevel@tonic-gate	 * Finally CBV3 is the expected answer when we perform our repeated
3487c478bd9Sstevel@tonic-gate	 * calculations on CBV1 and CBV2 - it is not otherwise specially
3497c478bd9Sstevel@tonic-gate	 * derived.  If this result is not obtained then a corruption has
3507c478bd9Sstevel@tonic-gate	 * occured during the FPRAS_REWRITE of one of the two blocks of
3517c478bd9Sstevel@tonic-gate	 * 16 instructions.  A corruption could also result in an illegal
3527c478bd9Sstevel@tonic-gate	 * instruction or other unexpected trap - we catch illegal
3537c478bd9Sstevel@tonic-gate	 * instruction traps in the PC range and trampoline to the
3547c478bd9Sstevel@tonic-gate	 * last instructions of the function to return a failure indication.
3557c478bd9Sstevel@tonic-gate	 *
3567c478bd9Sstevel@tonic-gate	 */
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate#define	CBV1		0xc11
3597c478bd9Sstevel@tonic-gate#define	CBV2		0xf6ffa400
3607c478bd9Sstevel@tonic-gate#define	CBV3		0x66f9d800
3617c478bd9Sstevel@tonic-gate#define	CBR1		%o1
3627c478bd9Sstevel@tonic-gate#define	CBR2		%l6
3637c478bd9Sstevel@tonic-gate#define	CBO2		%o2
3647c478bd9Sstevel@tonic-gate#define	SETHI_CBV2_CBR1		sethi %hi(CBV2), CBR1
3657c478bd9Sstevel@tonic-gate#define	ADDCCC_CBR1_CBR2_CBR2	addccc CBR1, CBR2, CBR2
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate	.align	64
3687c478bd9Sstevel@tonic-gate	ENTRY_NP(fpras_chkfn_type1)
3697c478bd9Sstevel@tonic-gate	mov	CBR2, CBO2		! 1, preserve CBR2 of (callers) window
3707c478bd9Sstevel@tonic-gate	mov	FPRAS_OK, %o0		! 2, default return value
3717c478bd9Sstevel@tonic-gate	ba,pt	%icc, 1f		! 3
3727c478bd9Sstevel@tonic-gate	  subcc %g0, CBV1, CBR2		! 4
3737c478bd9Sstevel@tonic-gate					! 5 - 16
3747c478bd9Sstevel@tonic-gate	.align	64
3757c478bd9Sstevel@tonic-gate1:	SETHI_CBV2_CBR1			! 1
3767c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 2
3777c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 3
3787c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 4
3797c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 5
3807c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 6
3817c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 7
3827c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 8
3837c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 9
3847c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 10
3857c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 11
3867c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 12
3877c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 13
3887c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 14
3897c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 15
3907c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 16
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 1
3937c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 2
3947c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 3
3957c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 4
3967c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 5
3977c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 6
3987c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 7
3997c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 8
4007c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 9
4017c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 10
4027c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 11
4037c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 12
4047c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 13
4057c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 14
4067c478bd9Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 15
4077c478bd9Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 16
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate	addc	CBR1, CBR2, CBR2	! 1
4107c478bd9Sstevel@tonic-gate	sethi	%hi(CBV3), CBR1		! 2
4117c478bd9Sstevel@tonic-gate	cmp	CBR1, CBR2		! 3
4127c478bd9Sstevel@tonic-gate	movnz	%icc, FPRAS_BADCALC, %o0! 4, how detected
4137c478bd9Sstevel@tonic-gate	retl				! 5
4147c478bd9Sstevel@tonic-gate	  mov	CBO2, CBR2		! 6, restore borrowed register
4157c478bd9Sstevel@tonic-gate	.skip 4*(13-7+1)		! 7 - 13
4167c478bd9Sstevel@tonic-gate					!
4177c478bd9Sstevel@tonic-gate					! illegal instr'n trap comes here
4187c478bd9Sstevel@tonic-gate					!
4197c478bd9Sstevel@tonic-gate	mov	CBO2, CBR2		! 14, restore borrowed register
4207c478bd9Sstevel@tonic-gate	retl				! 15
4217c478bd9Sstevel@tonic-gate	  mov	FPRAS_BADTRAP, %o0	! 16, how detected
4227c478bd9Sstevel@tonic-gate	SET_SIZE(fpras_chkfn_type1)
4237c478bd9Sstevel@tonic-gate
4247c478bd9Sstevel@tonic-gate#endif	/* lint */
4257bafd143Sjb145095
4267bafd143Sjb145095/*
4277bafd143Sjb145095 * fp_zero() - clear all fp data registers and the fsr
4287bafd143Sjb145095 */
4297bafd143Sjb145095
4307bafd143Sjb145095#if defined(lint) || defined(__lint)
4317bafd143Sjb145095
4327bafd143Sjb145095void
4337bafd143Sjb145095fp_zero(void)
4347bafd143Sjb145095{}
4357bafd143Sjb145095
4367bafd143Sjb145095#else	/* lint */
4377bafd143Sjb145095
4387bafd143Sjb145095	ENTRY_NP(fp_zero)
4397bafd143Sjb145095	std	%g0, [%sp + ARGPUSH + STACK_BIAS]
4407bafd143Sjb145095	fzero	%f0
4417bafd143Sjb145095	fzero	%f2
4427bafd143Sjb145095	ldd	[%sp + ARGPUSH + STACK_BIAS], %fsr
4437bafd143Sjb145095	faddd	%f0, %f2, %f4
4447bafd143Sjb145095	fmuld	%f0, %f2, %f6
4457bafd143Sjb145095	faddd	%f0, %f2, %f8
4467bafd143Sjb145095	fmuld	%f0, %f2, %f10
4477bafd143Sjb145095	faddd	%f0, %f2, %f12
4487bafd143Sjb145095	fmuld	%f0, %f2, %f14
4497bafd143Sjb145095	faddd	%f0, %f2, %f16
4507bafd143Sjb145095	fmuld	%f0, %f2, %f18
4517bafd143Sjb145095	faddd	%f0, %f2, %f20
4527bafd143Sjb145095	fmuld	%f0, %f2, %f22
4537bafd143Sjb145095	faddd	%f0, %f2, %f24
4547bafd143Sjb145095	fmuld	%f0, %f2, %f26
4557bafd143Sjb145095	faddd	%f0, %f2, %f28
4567bafd143Sjb145095	fmuld	%f0, %f2, %f30
4577bafd143Sjb145095	faddd	%f0, %f2, %f32
4587bafd143Sjb145095	fmuld	%f0, %f2, %f34
4597bafd143Sjb145095	faddd	%f0, %f2, %f36
4607bafd143Sjb145095	fmuld	%f0, %f2, %f38
4617bafd143Sjb145095	faddd	%f0, %f2, %f40
4627bafd143Sjb145095	fmuld	%f0, %f2, %f42
4637bafd143Sjb145095	faddd	%f0, %f2, %f44
4647bafd143Sjb145095	fmuld	%f0, %f2, %f46
4657bafd143Sjb145095	faddd	%f0, %f2, %f48
4667bafd143Sjb145095	fmuld	%f0, %f2, %f50
4677bafd143Sjb145095	faddd	%f0, %f2, %f52
4687bafd143Sjb145095	fmuld	%f0, %f2, %f54
4697bafd143Sjb145095	faddd	%f0, %f2, %f56
4707bafd143Sjb145095	fmuld	%f0, %f2, %f58
4717bafd143Sjb145095	faddd	%f0, %f2, %f60
4727bafd143Sjb145095	retl
4737bafd143Sjb145095	fmuld	%f0, %f2, %f62
4747bafd143Sjb145095	SET_SIZE(fp_zero)
4757bafd143Sjb145095
4767bafd143Sjb145095#endif	/* lint */
477