xref: /titanic_41/usr/src/uts/sun4v/cpu/common_asm.s (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
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*b52a336eSPavel Tatashin * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate#if !defined(lint)
267c478bd9Sstevel@tonic-gate#include "assym.h"
277c478bd9Sstevel@tonic-gate#endif
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate/*
307c478bd9Sstevel@tonic-gate * General assembly language routines.
317c478bd9Sstevel@tonic-gate * It is the intent of this file to contain routines that are
327c478bd9Sstevel@tonic-gate * specific to cpu architecture.
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate/*
367c478bd9Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a
377c478bd9Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro
387c478bd9Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See
397c478bd9Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information.
407c478bd9Sstevel@tonic-gate */
417c478bd9Sstevel@tonic-gate#define	FAST_TRAP_DONE	\
427c478bd9Sstevel@tonic-gate	ba,a	fast_trap_done
437c478bd9Sstevel@tonic-gate
44023e71deSHaik Aftandilian#include <sys/machclock.h>
457c478bd9Sstevel@tonic-gate#include <sys/clock.h>
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate#if defined(lint)
487c478bd9Sstevel@tonic-gate#include <sys/types.h>
497c478bd9Sstevel@tonic-gate#include <sys/scb.h>
507c478bd9Sstevel@tonic-gate#include <sys/systm.h>
517c478bd9Sstevel@tonic-gate#include <sys/regset.h>
527c478bd9Sstevel@tonic-gate#include <sys/sunddi.h>
537c478bd9Sstevel@tonic-gate#include <sys/lockstat.h>
547c478bd9Sstevel@tonic-gate#endif	/* lint */
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
587c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
591e2e7a75Shuah#include <vm/hat_sfmmu.h>
607c478bd9Sstevel@tonic-gate#include <sys/machparam.h>	/* To get SYSBASE and PAGESIZE */
617c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
627c478bd9Sstevel@tonic-gate#include <sys/clock.h>
637c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
647c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h>
657c478bd9Sstevel@tonic-gate#include <sys/isa_defs.h>
667c478bd9Sstevel@tonic-gate#include <sys/dditypes.h>
677c478bd9Sstevel@tonic-gate#include <sys/intr.h>
687c478bd9Sstevel@tonic-gate#include <sys/hypervisor_api.h>
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate#if !defined(lint)
717c478bd9Sstevel@tonic-gate#include "assym.h"
727c478bd9Sstevel@tonic-gate#endif
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate#define	ICACHE_FLUSHSZ	0x20
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate#if defined(lint)
777c478bd9Sstevel@tonic-gate/*
787c478bd9Sstevel@tonic-gate * Softint generated when counter field of tick reg matches value field
797c478bd9Sstevel@tonic-gate * of tick_cmpr reg
807c478bd9Sstevel@tonic-gate */
817c478bd9Sstevel@tonic-gate/*ARGSUSED*/
827c478bd9Sstevel@tonic-gatevoid
837c478bd9Sstevel@tonic-gatetickcmpr_set(uint64_t clock_cycles)
847c478bd9Sstevel@tonic-gate{}
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate#else   /* lint */
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate	ENTRY_NP(tickcmpr_set)
897c478bd9Sstevel@tonic-gate	! get 64-bit clock_cycles interval
907c478bd9Sstevel@tonic-gate	mov	%o0, %o2
917c478bd9Sstevel@tonic-gate	mov	8, %o3			! A reasonable initial step size
927c478bd9Sstevel@tonic-gate1:
937c478bd9Sstevel@tonic-gate	WR_TICKCMPR(%o2,%o4,%o5,__LINE__)	! Write to TICK_CMPR
947c478bd9Sstevel@tonic-gate
95023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o0,%o4,%o5,__LINE__)	! Read %tick to confirm the
96023e71deSHaik Aftandilian						! value we wrote was in the
97023e71deSHaik Aftandilian						! future.
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate	cmp	%o2, %o0		! If the value we wrote was in the
1007c478bd9Sstevel@tonic-gate	bg,pt	%xcc, 2f		!   future, then blow out of here.
1017c478bd9Sstevel@tonic-gate	  sllx	%o3, 1, %o3		! If not, then double our step size,
1027c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 1b		!   and take another lap.
1037c478bd9Sstevel@tonic-gate	  add	%o0, %o3, %o2		!
1047c478bd9Sstevel@tonic-gate2:
1057c478bd9Sstevel@tonic-gate	retl
1067c478bd9Sstevel@tonic-gate	  nop
1077c478bd9Sstevel@tonic-gate	SET_SIZE(tickcmpr_set)
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate#endif  /* lint */
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate#if defined(lint)
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gatevoid
1147c478bd9Sstevel@tonic-gatetickcmpr_disable(void)
1157c478bd9Sstevel@tonic-gate{}
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate#else
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate	ENTRY_NP(tickcmpr_disable)
1207c478bd9Sstevel@tonic-gate	mov	1, %g1
1217c478bd9Sstevel@tonic-gate	sllx	%g1, TICKINT_DIS_SHFT, %o0
1227c478bd9Sstevel@tonic-gate	WR_TICKCMPR(%o0,%o4,%o5,__LINE__)	! Write to TICK_CMPR
1237c478bd9Sstevel@tonic-gate	retl
1247c478bd9Sstevel@tonic-gate	  nop
1257c478bd9Sstevel@tonic-gate	SET_SIZE(tickcmpr_disable)
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate#endif
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate#if defined(lint)
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate/*
13200a57bdfSHaik Aftandilian * tick_write_delta() is intended to increment %stick by the specified delta,
13300a57bdfSHaik Aftandilian * but %stick is only writeable in hyperprivileged mode and at present there
13400a57bdfSHaik Aftandilian * is no provision for this. tick_write_delta is called by the cylic subsystem
13500a57bdfSHaik Aftandilian * if a negative %stick delta is observed after cyclic processing is resumed
13600a57bdfSHaik Aftandilian * after an event such as an OS suspend/resume. On sun4v, the suspend/resume
13700a57bdfSHaik Aftandilian * routines should adjust the %stick offset preventing the cyclic subsystem
13800a57bdfSHaik Aftandilian * from detecting a negative delta. If a negative delta is detected, panic the
13900a57bdfSHaik Aftandilian * system. The negative delta could be caused by improper %stick
14000a57bdfSHaik Aftandilian * synchronization after a suspend/resume.
1417c478bd9Sstevel@tonic-gate */
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate/*ARGSUSED*/
1447c478bd9Sstevel@tonic-gatevoid
1457c478bd9Sstevel@tonic-gatetick_write_delta(uint64_t delta)
1467c478bd9Sstevel@tonic-gate{}
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate#else	/* lint */
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate	.seg	".text"
1517c478bd9Sstevel@tonic-gatetick_write_delta_panic:
15200a57bdfSHaik Aftandilian	.asciz	"tick_write_delta: not supported, delta: 0x%lx"
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate	ENTRY_NP(tick_write_delta)
1557c478bd9Sstevel@tonic-gate	sethi	%hi(tick_write_delta_panic), %o1
1567c478bd9Sstevel@tonic-gate        save    %sp, -SA(MINFRAME), %sp ! get a new window to preserve caller
15700a57bdfSHaik Aftandilian	mov	%i0, %o1
1587c478bd9Sstevel@tonic-gate	call	panic
1597c478bd9Sstevel@tonic-gate	  or	%i1, %lo(tick_write_delta_panic), %o0
1607c478bd9Sstevel@tonic-gate	/*NOTREACHED*/
1617c478bd9Sstevel@tonic-gate	retl
1627c478bd9Sstevel@tonic-gate	  nop
1637c478bd9Sstevel@tonic-gate#endif
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate#if defined(lint)
1667c478bd9Sstevel@tonic-gate/*
1677c478bd9Sstevel@tonic-gate *  return 1 if disabled
1687c478bd9Sstevel@tonic-gate */
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gateint
1717c478bd9Sstevel@tonic-gatetickcmpr_disabled(void)
1727c478bd9Sstevel@tonic-gate{ return (0); }
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate#else   /* lint */
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate	ENTRY_NP(tickcmpr_disabled)
177023e71deSHaik Aftandilian	RD_TICKCMPR(%g1,%o0,%o1,__LINE__)
1787c478bd9Sstevel@tonic-gate	retl
1797c478bd9Sstevel@tonic-gate	  srlx	%g1, TICKINT_DIS_SHFT, %o0
1807c478bd9Sstevel@tonic-gate	SET_SIZE(tickcmpr_disabled)
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate#endif  /* lint */
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate/*
1857c478bd9Sstevel@tonic-gate * Get current tick
1867c478bd9Sstevel@tonic-gate */
1877c478bd9Sstevel@tonic-gate#if defined(lint)
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gateu_longlong_t
1907c478bd9Sstevel@tonic-gategettick(void)
1917c478bd9Sstevel@tonic-gate{ return (0); }
1927c478bd9Sstevel@tonic-gate
193*b52a336eSPavel Tatashinu_longlong_t
194*b52a336eSPavel Tatashinrandtick(void)
195*b52a336eSPavel Tatashin{ return (0); }
196*b52a336eSPavel Tatashin
1977c478bd9Sstevel@tonic-gate#else   /* lint */
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate	ENTRY(gettick)
200*b52a336eSPavel Tatashin	ALTENTRY(randtick)
201023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o0,%o2,%o3,__LINE__)
2027c478bd9Sstevel@tonic-gate	retl
2037c478bd9Sstevel@tonic-gate	  nop
204*b52a336eSPavel Tatashin	SET_SIZE(randtick)
2057c478bd9Sstevel@tonic-gate	SET_SIZE(gettick)
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate#endif  /* lint */
2087c478bd9Sstevel@tonic-gate
209023e71deSHaik Aftandilian/*
210023e71deSHaik Aftandilian * Get current tick. For trapstat use only.
211023e71deSHaik Aftandilian */
212023e71deSHaik Aftandilian#if defined (lint)
213023e71deSHaik Aftandilian
214023e71deSHaik Aftandilianhrtime_t
215023e71deSHaik Aftandilianrdtick()
216023e71deSHaik Aftandilian{ return (0); }
217023e71deSHaik Aftandilian
218023e71deSHaik Aftandilian#else
219023e71deSHaik Aftandilian	ENTRY(rdtick)
220023e71deSHaik Aftandilian	retl
221023e71deSHaik Aftandilian	RD_TICK_PHYSICAL(%o0)
222023e71deSHaik Aftandilian	SET_SIZE(rdtick)
223023e71deSHaik Aftandilian#endif /* lint */
224023e71deSHaik Aftandilian
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate/*
2277c478bd9Sstevel@tonic-gate * Return the counter portion of the tick register.
2287c478bd9Sstevel@tonic-gate */
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate#if defined(lint)
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gateuint64_t
2337c478bd9Sstevel@tonic-gategettick_counter(void)
2347c478bd9Sstevel@tonic-gate{ return(0); }
2357c478bd9Sstevel@tonic-gate
236023e71deSHaik Aftandilianuint64_t
237023e71deSHaik Aftandiliangettick_npt(void)
238023e71deSHaik Aftandilian{ return(0); }
239023e71deSHaik Aftandilian
240023e71deSHaik Aftandilianuint64_t
241023e71deSHaik Aftandiliangetstick_npt(void)
242023e71deSHaik Aftandilian{ return(0); }
243023e71deSHaik Aftandilian
2447c478bd9Sstevel@tonic-gate#else	/* lint */
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate	ENTRY_NP(gettick_counter)
247023e71deSHaik Aftandilian	RD_TICK(%o0,%o1,%o2,__LINE__)
2487c478bd9Sstevel@tonic-gate	retl
249023e71deSHaik Aftandilian	nop
2507c478bd9Sstevel@tonic-gate	SET_SIZE(gettick_counter)
251023e71deSHaik Aftandilian
252023e71deSHaik Aftandilian	ENTRY_NP(gettick_npt)
253023e71deSHaik Aftandilian	RD_TICK_PHYSICAL(%o0)
254023e71deSHaik Aftandilian	retl
255023e71deSHaik Aftandilian	srlx	%o0, 63, %o0
256023e71deSHaik Aftandilian	SET_SIZE(gettick_npt)
257023e71deSHaik Aftandilian
258023e71deSHaik Aftandilian	ENTRY_NP(getstick_npt)
259023e71deSHaik Aftandilian	RD_STICK_PHYSICAL(%o0)
260023e71deSHaik Aftandilian	retl
261023e71deSHaik Aftandilian	srlx	%o0, 63, %o0
262023e71deSHaik Aftandilian	SET_SIZE(getstick_npt)
2637c478bd9Sstevel@tonic-gate#endif	/* lint */
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate/*
2667c478bd9Sstevel@tonic-gate * Provide a C callable interface to the trap that reads the hi-res timer.
2677c478bd9Sstevel@tonic-gate * Returns 64-bit nanosecond timestamp in %o0 and %o1.
2687c478bd9Sstevel@tonic-gate */
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate#if defined(lint)
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gatehrtime_t
2737c478bd9Sstevel@tonic-gategethrtime(void)
2747c478bd9Sstevel@tonic-gate{
2757c478bd9Sstevel@tonic-gate	return ((hrtime_t)0);
2767c478bd9Sstevel@tonic-gate}
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gatehrtime_t
2797c478bd9Sstevel@tonic-gategethrtime_unscaled(void)
2807c478bd9Sstevel@tonic-gate{
2817c478bd9Sstevel@tonic-gate	return ((hrtime_t)0);
2827c478bd9Sstevel@tonic-gate}
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gatehrtime_t
2857c478bd9Sstevel@tonic-gategethrtime_max(void)
2867c478bd9Sstevel@tonic-gate{
2877c478bd9Sstevel@tonic-gate	return ((hrtime_t)0);
2887c478bd9Sstevel@tonic-gate}
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gatevoid
2917c478bd9Sstevel@tonic-gatescalehrtime(hrtime_t *hrt)
2927c478bd9Sstevel@tonic-gate{
2937c478bd9Sstevel@tonic-gate	*hrt = 0;
2947c478bd9Sstevel@tonic-gate}
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gatevoid
2977c478bd9Sstevel@tonic-gategethrestime(timespec_t *tp)
2987c478bd9Sstevel@tonic-gate{
2997c478bd9Sstevel@tonic-gate	tp->tv_sec = 0;
3007c478bd9Sstevel@tonic-gate	tp->tv_nsec = 0;
3017c478bd9Sstevel@tonic-gate}
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gatetime_t
3047c478bd9Sstevel@tonic-gategethrestime_sec(void)
3057c478bd9Sstevel@tonic-gate{
3067c478bd9Sstevel@tonic-gate	return (0);
3077c478bd9Sstevel@tonic-gate}
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gatevoid
3107c478bd9Sstevel@tonic-gategethrestime_lasttick(timespec_t *tp)
3117c478bd9Sstevel@tonic-gate{
3127c478bd9Sstevel@tonic-gate	tp->tv_sec = 0;
3137c478bd9Sstevel@tonic-gate	tp->tv_nsec = 0;
3147c478bd9Sstevel@tonic-gate}
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate/*ARGSUSED*/
3177c478bd9Sstevel@tonic-gatevoid
3187c478bd9Sstevel@tonic-gatehres_tick(void)
3197c478bd9Sstevel@tonic-gate{
3207c478bd9Sstevel@tonic-gate}
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gatevoid
3237c478bd9Sstevel@tonic-gatepanic_hres_tick(void)
3247c478bd9Sstevel@tonic-gate{
3257c478bd9Sstevel@tonic-gate}
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate#else	/* lint */
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrtime)
330023e71deSHaik Aftandilian	GET_HRTIME(%g1,%o0,%o1,%o2,%o3,%o4,%o5,%g2,__LINE__)
3317c478bd9Sstevel@tonic-gate							! %g1 = hrtime
3327c478bd9Sstevel@tonic-gate	retl
3337c478bd9Sstevel@tonic-gate	  mov	%g1, %o0
3347c478bd9Sstevel@tonic-gate	SET_SIZE(gethrtime)
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrtime_unscaled)
337023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__)	! %g1 = native time
3387c478bd9Sstevel@tonic-gate	retl
3397c478bd9Sstevel@tonic-gate	  mov	%g1, %o0
3407c478bd9Sstevel@tonic-gate	SET_SIZE(gethrtime_unscaled)
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrtime_waitfree)
3437c478bd9Sstevel@tonic-gate	ALTENTRY(dtrace_gethrtime)
344023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%o2,%o3,__LINE__)	! %g1 = native time
3457c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC(%g1, %o2, %o3)
3467c478bd9Sstevel@tonic-gate	retl
3477c478bd9Sstevel@tonic-gate	  mov	%g1, %o0
3487c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_gethrtime)
3497c478bd9Sstevel@tonic-gate	SET_SIZE(gethrtime_waitfree)
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate	ENTRY(gethrtime_max)
3527c478bd9Sstevel@tonic-gate	NATIVE_TIME_MAX(%g1)
3537c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC(%g1, %o0, %o1)
3547c478bd9Sstevel@tonic-gate
3557c478bd9Sstevel@tonic-gate	! hrtime_t's are signed, max hrtime_t must be positive
3567c478bd9Sstevel@tonic-gate	mov	-1, %o2
3577c478bd9Sstevel@tonic-gate	brlz,a	%g1, 1f
3587c478bd9Sstevel@tonic-gate	  srlx	%o2, 1, %g1
3597c478bd9Sstevel@tonic-gate1:
3607c478bd9Sstevel@tonic-gate	retl
3617c478bd9Sstevel@tonic-gate	  mov	%g1, %o0
3627c478bd9Sstevel@tonic-gate	SET_SIZE(gethrtime_max)
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate	ENTRY(scalehrtime)
3657c478bd9Sstevel@tonic-gate	ldx	[%o0], %o1
3667c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC(%o1, %o2, %o3)
3677c478bd9Sstevel@tonic-gate	retl
3687c478bd9Sstevel@tonic-gate	  stx	%o1, [%o0]
3697c478bd9Sstevel@tonic-gate	SET_SIZE(scalehrtime)
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate/*
3727c478bd9Sstevel@tonic-gate * Fast trap to return a timestamp, uses trap window, leaves traps
3737c478bd9Sstevel@tonic-gate * disabled.  Returns a 64-bit nanosecond timestamp in %o0 and %o1.
3747c478bd9Sstevel@tonic-gate *
3757c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRTIME trap.
3767c478bd9Sstevel@tonic-gate */
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate	ENTRY_NP(get_timestamp)
379023e71deSHaik Aftandilian	GET_HRTIME(%g1,%g2,%g3,%g4,%g5,%o0,%o1,%o2,__LINE__)
380023e71deSHaik Aftandilian	! %g1 = hrtime
3817c478bd9Sstevel@tonic-gate	srlx	%g1, 32, %o0				! %o0 = hi32(%g1)
3827c478bd9Sstevel@tonic-gate	srl	%g1, 0, %o1				! %o1 = lo32(%g1)
3837c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
3847c478bd9Sstevel@tonic-gate	SET_SIZE(get_timestamp)
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate/*
3877c478bd9Sstevel@tonic-gate * Macro to convert GET_HRESTIME() bits into a timestamp.
3887c478bd9Sstevel@tonic-gate *
3897c478bd9Sstevel@tonic-gate * We use two separate macros so that the platform-dependent GET_HRESTIME()
3907c478bd9Sstevel@tonic-gate * can be as small as possible; CONV_HRESTIME() implements the generic part.
3917c478bd9Sstevel@tonic-gate */
3927c478bd9Sstevel@tonic-gate#define	CONV_HRESTIME(hrestsec, hrestnsec, adj, nslt, nano) \
3937c478bd9Sstevel@tonic-gate	brz,pt	adj, 3f;		/* no adjustments, it's easy */	\
3947c478bd9Sstevel@tonic-gate	add	hrestnsec, nslt, hrestnsec; /* hrest.tv_nsec += nslt */	\
3957c478bd9Sstevel@tonic-gate	brlz,pn	adj, 2f;		/* if hrestime_adj negative */	\
396646e55b6Scth	  srlx	nslt, ADJ_SHIFT, nslt;	/* delay: nslt >>= 4 */		\
3977c478bd9Sstevel@tonic-gate	subcc	adj, nslt, %g0;		/* hrestime_adj - nslt/16 */	\
3987c478bd9Sstevel@tonic-gate	movg	%xcc, nslt, adj;	/* adj by min(adj, nslt/16) */	\
3997c478bd9Sstevel@tonic-gate	ba	3f;			/* go convert to sec/nsec */	\
4007c478bd9Sstevel@tonic-gate	  add	hrestnsec, adj, hrestnsec; /* delay: apply adjustment */ \
4017c478bd9Sstevel@tonic-gate2:	addcc	adj, nslt, %g0;		/* hrestime_adj + nslt/16 */	\
4027c478bd9Sstevel@tonic-gate	bge,a,pt %xcc, 3f;		/* is adj less negative? */	\
4037c478bd9Sstevel@tonic-gate	  add	hrestnsec, adj, hrestnsec; /* yes: hrest.nsec += adj */	\
4047c478bd9Sstevel@tonic-gate	sub	hrestnsec, nslt, hrestnsec; /* no: hrest.nsec -= nslt/16 */ \
4057c478bd9Sstevel@tonic-gate3:	cmp	hrestnsec, nano;	/* more than a billion? */	\
4067c478bd9Sstevel@tonic-gate	bl,pt	%xcc, 4f;		/* if not, we're done */	\
4077c478bd9Sstevel@tonic-gate	  nop;				/* delay: do nothing :( */	\
4087c478bd9Sstevel@tonic-gate	add	hrestsec, 1, hrestsec;	/* hrest.tv_sec++; */		\
4097c478bd9Sstevel@tonic-gate	sub	hrestnsec, nano, hrestnsec; /* hrest.tv_nsec -= NANOSEC; */	\
410646e55b6Scth	ba,a	3b;			/* check >= billion again */	\
4117c478bd9Sstevel@tonic-gate4:
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrestime)
414023e71deSHaik Aftandilian	GET_HRESTIME(%o1,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__)
4157c478bd9Sstevel@tonic-gate	CONV_HRESTIME(%o1, %o2, %o3, %o4, %o5)
4167c478bd9Sstevel@tonic-gate	stn	%o1, [%o0]
4177c478bd9Sstevel@tonic-gate	retl
4187c478bd9Sstevel@tonic-gate	  stn	%o2, [%o0 + CLONGSIZE]
4197c478bd9Sstevel@tonic-gate	SET_SIZE(gethrestime)
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate/*
4227c478bd9Sstevel@tonic-gate * Similar to gethrestime(), but gethrestime_sec() returns current hrestime
4237c478bd9Sstevel@tonic-gate * seconds.
4247c478bd9Sstevel@tonic-gate */
4257c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrestime_sec)
426023e71deSHaik Aftandilian	GET_HRESTIME(%o0,%o2,%o3,%o4,%o5,%g1,%g2,%g3,%g4,__LINE__)
4277c478bd9Sstevel@tonic-gate	CONV_HRESTIME(%o0, %o2, %o3, %o4, %o5)
4287c478bd9Sstevel@tonic-gate	retl					! %o0 current hrestime seconds
4297c478bd9Sstevel@tonic-gate	  nop
4307c478bd9Sstevel@tonic-gate	SET_SIZE(gethrestime_sec)
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate/*
4337c478bd9Sstevel@tonic-gate * Returns the hrestime on the last tick.  This is simpler than gethrestime()
4347c478bd9Sstevel@tonic-gate * and gethrestime_sec():  no conversion is required.  gethrestime_lasttick()
4357c478bd9Sstevel@tonic-gate * follows the same locking algorithm as GET_HRESTIME and GET_HRTIME,
4367c478bd9Sstevel@tonic-gate * outlined in detail in clock.h.  (Unlike GET_HRESTIME/GET_HRTIME, we don't
4377c478bd9Sstevel@tonic-gate * rely on load dependencies to effect the membar #LoadLoad, instead declaring
4387c478bd9Sstevel@tonic-gate * it explicitly.)
4397c478bd9Sstevel@tonic-gate */
4407c478bd9Sstevel@tonic-gate	ENTRY_NP(gethrestime_lasttick)
4417c478bd9Sstevel@tonic-gate	sethi	%hi(hres_lock), %o1
4427c478bd9Sstevel@tonic-gate0:
4437c478bd9Sstevel@tonic-gate	lduw	[%o1 + %lo(hres_lock)], %o2	! Load lock value
4447c478bd9Sstevel@tonic-gate	membar	#LoadLoad			! Load of lock must complete
4457c478bd9Sstevel@tonic-gate	andn	%o2, 1, %o2			! Mask off lowest bit
4467c478bd9Sstevel@tonic-gate	ldn	[%o1 + %lo(hrestime)], %g1	! Seconds.
4477c478bd9Sstevel@tonic-gate	add	%o1, %lo(hrestime), %o4
4487c478bd9Sstevel@tonic-gate	ldn	[%o4 + CLONGSIZE], %g2		! Nanoseconds.
4497c478bd9Sstevel@tonic-gate	membar	#LoadLoad			! All loads must complete
4507c478bd9Sstevel@tonic-gate	lduw	[%o1 + %lo(hres_lock)], %o3	! Reload lock value
4517c478bd9Sstevel@tonic-gate	cmp	%o3, %o2			! If lock is locked or has
4527c478bd9Sstevel@tonic-gate	bne	0b				!   changed, retry.
4537c478bd9Sstevel@tonic-gate	  stn	%g1, [%o0]			! Delay: store seconds
4547c478bd9Sstevel@tonic-gate	retl
4557c478bd9Sstevel@tonic-gate	  stn	%g2, [%o0 + CLONGSIZE]		! Delay: store nanoseconds
4567c478bd9Sstevel@tonic-gate	SET_SIZE(gethrestime_lasttick)
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate/*
4597c478bd9Sstevel@tonic-gate * Fast trap for gettimeofday().  Returns a timestruc_t in %o0 and %o1.
4607c478bd9Sstevel@tonic-gate *
4617c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRESTIME trap.
4627c478bd9Sstevel@tonic-gate */
4637c478bd9Sstevel@tonic-gate
4647c478bd9Sstevel@tonic-gate	ENTRY_NP(get_hrestime)
465023e71deSHaik Aftandilian	GET_HRESTIME(%o0,%o1,%g1,%g2,%g3,%g4,%g5,%o2,%o3,__LINE__)
4667c478bd9Sstevel@tonic-gate	CONV_HRESTIME(%o0, %o1, %g1, %g2, %g3)
4677c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
4687c478bd9Sstevel@tonic-gate	SET_SIZE(get_hrestime)
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate/*
4717c478bd9Sstevel@tonic-gate * Fast trap to return lwp virtual time, uses trap window, leaves traps
4727c478bd9Sstevel@tonic-gate * disabled.  Returns a 64-bit number in %o0:%o1, which is the number
4737c478bd9Sstevel@tonic-gate * of nanoseconds consumed.
4747c478bd9Sstevel@tonic-gate *
4757c478bd9Sstevel@tonic-gate * This is the handler for the ST_GETHRVTIME trap.
4767c478bd9Sstevel@tonic-gate *
4777c478bd9Sstevel@tonic-gate * Register usage:
4787c478bd9Sstevel@tonic-gate *	%o0, %o1 = return lwp virtual time
4797c478bd9Sstevel@tonic-gate * 	%o2 = CPU/thread
4807c478bd9Sstevel@tonic-gate * 	%o3 = lwp
4817c478bd9Sstevel@tonic-gate * 	%g1 = scratch
4827c478bd9Sstevel@tonic-gate * 	%g5 = scratch
4837c478bd9Sstevel@tonic-gate */
4847c478bd9Sstevel@tonic-gate	ENTRY_NP(get_virtime)
485023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g5,%g1,%g2,__LINE__)	! %g5 = native time in ticks
4867c478bd9Sstevel@tonic-gate	CPU_ADDR(%g2, %g3)			! CPU struct ptr to %g2
4877c478bd9Sstevel@tonic-gate	ldn	[%g2 + CPU_THREAD], %g2		! thread pointer to %g2
4887c478bd9Sstevel@tonic-gate	ldn	[%g2 + T_LWP], %g3		! lwp pointer to %g3
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate	/*
4917c478bd9Sstevel@tonic-gate	 * Subtract start time of current microstate from time
4927c478bd9Sstevel@tonic-gate	 * of day to get increment for lwp virtual time.
4937c478bd9Sstevel@tonic-gate	 */
4947c478bd9Sstevel@tonic-gate	ldx	[%g3 + LWP_STATE_START], %g1	! ms_state_start
4957c478bd9Sstevel@tonic-gate	sub	%g5, %g1, %g5
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate	/*
4987c478bd9Sstevel@tonic-gate	 * Add current value of ms_acct[LMS_USER]
4997c478bd9Sstevel@tonic-gate	 */
5007c478bd9Sstevel@tonic-gate	ldx	[%g3 + LWP_ACCT_USER], %g1	! ms_acct[LMS_USER]
5017c478bd9Sstevel@tonic-gate	add	%g5, %g1, %g5
5027c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC(%g5, %g1, %o0)
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate	srl	%g5, 0, %o1			! %o1 = lo32(%g5)
5057c478bd9Sstevel@tonic-gate	srlx	%g5, 32, %o0			! %o0 = hi32(%g5)
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
5087c478bd9Sstevel@tonic-gate	SET_SIZE(get_virtime)
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate	.seg	".text"
5137c478bd9Sstevel@tonic-gatehrtime_base_panic:
5147c478bd9Sstevel@tonic-gate	.asciz	"hrtime_base stepping back"
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate	ENTRY_NP(hres_tick)
5187c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp	! get a new window
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate	sethi	%hi(hrestime), %l4
5217c478bd9Sstevel@tonic-gate	ldstub	[%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5	! try locking
5227c478bd9Sstevel@tonic-gate7:	tst	%l5
5237c478bd9Sstevel@tonic-gate	bz,pt	%xcc, 8f			! if we got it, drive on
5247c478bd9Sstevel@tonic-gate	  ld	[%l4 + %lo(nsec_scale)], %l5	! delay: %l5 = scaling factor
5257c478bd9Sstevel@tonic-gate	ldub	[%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5
5267c478bd9Sstevel@tonic-gate9:	tst	%l5
5277c478bd9Sstevel@tonic-gate	bz,a,pn	%xcc, 7b
5287c478bd9Sstevel@tonic-gate	  ldstub	[%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5
5297c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 9b
5307c478bd9Sstevel@tonic-gate	  ldub	[%l4 + %lo(hres_lock + HRES_LOCK_OFFSET)], %l5
5317c478bd9Sstevel@tonic-gate8:
5327c478bd9Sstevel@tonic-gate	membar	#StoreLoad|#StoreStore
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate	!
5357c478bd9Sstevel@tonic-gate	! update hres_last_tick.  %l5 has the scaling factor (nsec_scale).
5367c478bd9Sstevel@tonic-gate	!
5377c478bd9Sstevel@tonic-gate	ldx	[%l4 + %lo(hrtime_base)], %g1	! load current hrtime_base
538023e71deSHaik Aftandilian	GET_NATIVE_TIME(%l0,%l3,%l6,__LINE__)	! current native time
5397c478bd9Sstevel@tonic-gate	stx	%l0, [%l4 + %lo(hres_last_tick)]! prev = current
5407c478bd9Sstevel@tonic-gate	! convert native time to nsecs
5417c478bd9Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC_SCALE(%l0, %l5, %l2, NSEC_SHIFT)
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate	sub	%l0, %g1, %i1			! get accurate nsec delta
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate	ldx	[%l4 + %lo(hrtime_base)], %l1
5467c478bd9Sstevel@tonic-gate	cmp	%l1, %l0
5477c478bd9Sstevel@tonic-gate	bg,pn	%xcc, 9f
5487c478bd9Sstevel@tonic-gate	  nop
5497c478bd9Sstevel@tonic-gate
5507c478bd9Sstevel@tonic-gate	stx	%l0, [%l4 + %lo(hrtime_base)]	! update hrtime_base
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate	!
5537c478bd9Sstevel@tonic-gate	! apply adjustment, if any
5547c478bd9Sstevel@tonic-gate	!
5557c478bd9Sstevel@tonic-gate	ldx	[%l4 + %lo(hrestime_adj)], %l0	! %l0 = hrestime_adj
5567c478bd9Sstevel@tonic-gate	brz	%l0, 2f
5577c478bd9Sstevel@tonic-gate						! hrestime_adj == 0 ?
5587c478bd9Sstevel@tonic-gate						! yes, skip adjustments
5597c478bd9Sstevel@tonic-gate	  clr	%l5				! delay: set adj to zero
5607c478bd9Sstevel@tonic-gate	tst	%l0				! is hrestime_adj >= 0 ?
5617c478bd9Sstevel@tonic-gate	bge,pt	%xcc, 1f			! yes, go handle positive case
5627c478bd9Sstevel@tonic-gate	  srl	%i1, ADJ_SHIFT, %l5		! delay: %l5 = adj
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate	addcc	%l0, %l5, %g0			! hrestime_adj < -adj ?
5657c478bd9Sstevel@tonic-gate	bl,pt	%xcc, 2f			! yes, use current adj
5667c478bd9Sstevel@tonic-gate	  neg	%l5				! delay: %l5 = -adj
5677c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 2f
5687c478bd9Sstevel@tonic-gate	  mov	%l0, %l5			! no, so set adj = hrestime_adj
5697c478bd9Sstevel@tonic-gate1:
5707c478bd9Sstevel@tonic-gate	subcc	%l0, %l5, %g0			! hrestime_adj < adj ?
5717c478bd9Sstevel@tonic-gate	bl,a,pt	%xcc, 2f			! yes, set adj = hrestime_adj
5727c478bd9Sstevel@tonic-gate	  mov	%l0, %l5			! delay: adj = hrestime_adj
5737c478bd9Sstevel@tonic-gate2:
5747c478bd9Sstevel@tonic-gate	ldx	[%l4 + %lo(timedelta)], %l0	! %l0 = timedelta
5757c478bd9Sstevel@tonic-gate	sub	%l0, %l5, %l0			! timedelta -= adj
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate	stx	%l0, [%l4 + %lo(timedelta)]	! store new timedelta
5787c478bd9Sstevel@tonic-gate	stx	%l0, [%l4 + %lo(hrestime_adj)]	! hrestime_adj = timedelta
5797c478bd9Sstevel@tonic-gate
5807c478bd9Sstevel@tonic-gate	or	%l4, %lo(hrestime), %l2
5817c478bd9Sstevel@tonic-gate	ldn	[%l2], %i2			! %i2:%i3 = hrestime sec:nsec
5827c478bd9Sstevel@tonic-gate	ldn	[%l2 + CLONGSIZE], %i3
5837c478bd9Sstevel@tonic-gate	add	%i3, %l5, %i3			! hrestime.nsec += adj
5847c478bd9Sstevel@tonic-gate	add	%i3, %i1, %i3			! hrestime.nsec += nslt
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate	set	NANOSEC, %l5			! %l5 = NANOSEC
5877c478bd9Sstevel@tonic-gate	cmp	%i3, %l5
5887c478bd9Sstevel@tonic-gate	bl,pt	%xcc, 5f			! if hrestime.tv_nsec < NANOSEC
5897c478bd9Sstevel@tonic-gate	  sethi	%hi(one_sec), %i1		! delay
5907c478bd9Sstevel@tonic-gate	add	%i2, 0x1, %i2			! hrestime.tv_sec++
5917c478bd9Sstevel@tonic-gate	sub	%i3, %l5, %i3			! hrestime.tv_nsec - NANOSEC
5927c478bd9Sstevel@tonic-gate	mov	0x1, %l5
5937c478bd9Sstevel@tonic-gate	st	%l5, [%i1 + %lo(one_sec)]
5947c478bd9Sstevel@tonic-gate5:
5957c478bd9Sstevel@tonic-gate	stn	%i2, [%l2]
5967c478bd9Sstevel@tonic-gate	stn	%i3, [%l2 + CLONGSIZE]		! store the new hrestime
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate	membar	#StoreStore
5997c478bd9Sstevel@tonic-gate
6007c478bd9Sstevel@tonic-gate	ld	[%l4 + %lo(hres_lock)], %i1
6017c478bd9Sstevel@tonic-gate	inc	%i1				! release lock
6027c478bd9Sstevel@tonic-gate	st	%i1, [%l4 + %lo(hres_lock)]	! clear hres_lock
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate	ret
6057c478bd9Sstevel@tonic-gate	restore
6067c478bd9Sstevel@tonic-gate
6077c478bd9Sstevel@tonic-gate9:
6087c478bd9Sstevel@tonic-gate	!
6097c478bd9Sstevel@tonic-gate	! release hres_lock
6107c478bd9Sstevel@tonic-gate	!
6117c478bd9Sstevel@tonic-gate	ld	[%l4 + %lo(hres_lock)], %i1
6127c478bd9Sstevel@tonic-gate	inc	%i1
6137c478bd9Sstevel@tonic-gate	st	%i1, [%l4 + %lo(hres_lock)]
6147c478bd9Sstevel@tonic-gate
6157c478bd9Sstevel@tonic-gate	sethi	%hi(hrtime_base_panic), %o0
6167c478bd9Sstevel@tonic-gate	call	panic
6177c478bd9Sstevel@tonic-gate	  or	%o0, %lo(hrtime_base_panic), %o0
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate	SET_SIZE(hres_tick)
6207c478bd9Sstevel@tonic-gate
6217c478bd9Sstevel@tonic-gate#endif	/* lint */
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate#if !defined(lint) && !defined(__lint)
6247c478bd9Sstevel@tonic-gate
6257c478bd9Sstevel@tonic-gate	.seg	".text"
6267c478bd9Sstevel@tonic-gatekstat_q_panic_msg:
6277c478bd9Sstevel@tonic-gate	.asciz	"kstat_q_exit: qlen == 0"
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate	ENTRY(kstat_q_panic)
6307c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
6317c478bd9Sstevel@tonic-gate	sethi	%hi(kstat_q_panic_msg), %o0
6327c478bd9Sstevel@tonic-gate	call	panic
6337c478bd9Sstevel@tonic-gate	  or	%o0, %lo(kstat_q_panic_msg), %o0
6347c478bd9Sstevel@tonic-gate	/*NOTREACHED*/
6357c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_q_panic)
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate#define	BRZPN	brz,pn
6387c478bd9Sstevel@tonic-gate#define	BRZPT	brz,pt
6397c478bd9Sstevel@tonic-gate
6407c478bd9Sstevel@tonic-gate#define	KSTAT_Q_UPDATE(QOP, QBR, QZERO, QRETURN, QTYPE) \
6417c478bd9Sstevel@tonic-gate	ld	[%o0 + QTYPE/**/CNT], %o1;	/* %o1 = old qlen */	\
6427c478bd9Sstevel@tonic-gate	QOP	%o1, 1, %o2;			/* %o2 = new qlen */	\
6437c478bd9Sstevel@tonic-gate	QBR	%o1, QZERO;			/* done if qlen == 0 */	\
6447c478bd9Sstevel@tonic-gate	st	%o2, [%o0 + QTYPE/**/CNT];	/* delay: save qlen */	\
6457c478bd9Sstevel@tonic-gate	ldx	[%o0 + QTYPE/**/LASTUPDATE], %o3;			\
6467c478bd9Sstevel@tonic-gate	ldx	[%o0 + QTYPE/**/TIME], %o4;	/* %o4 = old time */	\
6477c478bd9Sstevel@tonic-gate	ldx	[%o0 + QTYPE/**/LENTIME], %o5;	/* %o5 = old lentime */	\
6487c478bd9Sstevel@tonic-gate	sub	%g1, %o3, %o2;			/* %o2 = time delta */	\
6497c478bd9Sstevel@tonic-gate	mulx	%o1, %o2, %o3;			/* %o3 = cur lentime */	\
6507c478bd9Sstevel@tonic-gate	add	%o4, %o2, %o4;			/* %o4 = new time */	\
6517c478bd9Sstevel@tonic-gate	add	%o5, %o3, %o5;			/* %o5 = new lentime */	\
6527c478bd9Sstevel@tonic-gate	stx	%o4, [%o0 + QTYPE/**/TIME];	/* save time */		\
6537c478bd9Sstevel@tonic-gate	stx	%o5, [%o0 + QTYPE/**/LENTIME];	/* save lentime */	\
6547c478bd9Sstevel@tonic-gateQRETURN;								\
6557c478bd9Sstevel@tonic-gate	stx	%g1, [%o0 + QTYPE/**/LASTUPDATE]; /* lastupdate = now */
6567c478bd9Sstevel@tonic-gate
6577c478bd9Sstevel@tonic-gate	.align 16
6587c478bd9Sstevel@tonic-gate	ENTRY(kstat_waitq_enter)
659023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6607c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W)
6617c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_waitq_enter)
6627c478bd9Sstevel@tonic-gate
6637c478bd9Sstevel@tonic-gate	.align 16
6647c478bd9Sstevel@tonic-gate	ENTRY(kstat_waitq_exit)
665023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6667c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_W)
6677c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_waitq_exit)
6687c478bd9Sstevel@tonic-gate
6697c478bd9Sstevel@tonic-gate	.align 16
6707c478bd9Sstevel@tonic-gate	ENTRY(kstat_runq_enter)
671023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6727c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R)
6737c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_runq_enter)
6747c478bd9Sstevel@tonic-gate
6757c478bd9Sstevel@tonic-gate	.align 16
6767c478bd9Sstevel@tonic-gate	ENTRY(kstat_runq_exit)
677023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6787c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, retl, KSTAT_IO_R)
6797c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_runq_exit)
6807c478bd9Sstevel@tonic-gate
6817c478bd9Sstevel@tonic-gate	.align 16
6827c478bd9Sstevel@tonic-gate	ENTRY(kstat_waitq_to_runq)
683023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6847c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_W)
6857c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_R)
6867c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_waitq_to_runq)
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate	.align 16
6897c478bd9Sstevel@tonic-gate	ENTRY(kstat_runq_back_to_waitq)
690023e71deSHaik Aftandilian	GET_NATIVE_TIME(%g1,%g2,%g3,__LINE__)
6917c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(sub, BRZPN, kstat_q_panic, 1:, KSTAT_IO_R)
6927c478bd9Sstevel@tonic-gate	KSTAT_Q_UPDATE(add, BRZPT, 1f, 1:retl, KSTAT_IO_W)
6937c478bd9Sstevel@tonic-gate	SET_SIZE(kstat_runq_back_to_waitq)
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate#endif /* lint */
6967c478bd9Sstevel@tonic-gate
6977c478bd9Sstevel@tonic-gate#ifdef lint
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gateint64_t timedelta;
7007c478bd9Sstevel@tonic-gatehrtime_t hres_last_tick;
701b5b48cc1Ssudheervolatile timestruc_t hrestime;
7027c478bd9Sstevel@tonic-gateint64_t hrestime_adj;
703b5b48cc1Ssudheervolatile int hres_lock;
7047c478bd9Sstevel@tonic-gateuint_t nsec_scale;
7057c478bd9Sstevel@tonic-gatehrtime_t hrtime_base;
7067c478bd9Sstevel@tonic-gateint traptrace_use_stick;
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate#else
7097c478bd9Sstevel@tonic-gate	/*
7107c478bd9Sstevel@tonic-gate	 *  -- WARNING --
7117c478bd9Sstevel@tonic-gate	 *
7127c478bd9Sstevel@tonic-gate	 * The following variables MUST be together on a 128-byte boundary.
7137c478bd9Sstevel@tonic-gate	 * In addition to the primary performance motivation (having them all
7147c478bd9Sstevel@tonic-gate	 * on the same cache line(s)), code here and in the GET*TIME() macros
7157c478bd9Sstevel@tonic-gate	 * assumes that they all have the same high 22 address bits (so
7167c478bd9Sstevel@tonic-gate	 * there's only one sethi).
7177c478bd9Sstevel@tonic-gate	 */
7187c478bd9Sstevel@tonic-gate	.seg	".data"
7197c478bd9Sstevel@tonic-gate	.global	timedelta, hres_last_tick, hrestime, hrestime_adj
7207c478bd9Sstevel@tonic-gate	.global	hres_lock, nsec_scale, hrtime_base, traptrace_use_stick
721023e71deSHaik Aftandilian	.global	nsec_shift, adj_shift, native_tick_offset, native_stick_offset
7227c478bd9Sstevel@tonic-gate
7237c478bd9Sstevel@tonic-gate	/* XXX - above comment claims 128-bytes is necessary */
7247c478bd9Sstevel@tonic-gate	.align	64
7257c478bd9Sstevel@tonic-gatetimedelta:
7267c478bd9Sstevel@tonic-gate	.word	0, 0		/* int64_t */
7277c478bd9Sstevel@tonic-gatehres_last_tick:
7287c478bd9Sstevel@tonic-gate	.word	0, 0		/* hrtime_t */
7297c478bd9Sstevel@tonic-gatehrestime:
7307c478bd9Sstevel@tonic-gate	.nword	0, 0		/* 2 longs */
7317c478bd9Sstevel@tonic-gatehrestime_adj:
7327c478bd9Sstevel@tonic-gate	.word	0, 0		/* int64_t */
7337c478bd9Sstevel@tonic-gatehres_lock:
7347c478bd9Sstevel@tonic-gate	.word	0
7357c478bd9Sstevel@tonic-gatensec_scale:
7367c478bd9Sstevel@tonic-gate	.word	0
7377c478bd9Sstevel@tonic-gatehrtime_base:
7387c478bd9Sstevel@tonic-gate	.word	0, 0
7397c478bd9Sstevel@tonic-gatetraptrace_use_stick:
7407c478bd9Sstevel@tonic-gate	.word	0
7417c478bd9Sstevel@tonic-gatensec_shift:
7427c478bd9Sstevel@tonic-gate	.word	NSEC_SHIFT
7437c478bd9Sstevel@tonic-gateadj_shift:
7447c478bd9Sstevel@tonic-gate	.word	ADJ_SHIFT
745023e71deSHaik Aftandilian	.align	8
746023e71deSHaik Aftandiliannative_tick_offset:
747023e71deSHaik Aftandilian	.word	0, 0
748023e71deSHaik Aftandilian	.align	8
749023e71deSHaik Aftandiliannative_stick_offset:
750023e71deSHaik Aftandilian	.word	0, 0
7517c478bd9Sstevel@tonic-gate
7527c478bd9Sstevel@tonic-gate#endif
7537c478bd9Sstevel@tonic-gate
7547c478bd9Sstevel@tonic-gate
7557c478bd9Sstevel@tonic-gate/*
7567c478bd9Sstevel@tonic-gate * drv_usecwait(clock_t n)	[DDI/DKI - section 9F]
7577c478bd9Sstevel@tonic-gate * usec_delay(int n)		[compatibility - should go one day]
7587c478bd9Sstevel@tonic-gate * Delay by spinning.
7597c478bd9Sstevel@tonic-gate *
7607c478bd9Sstevel@tonic-gate * delay for n microseconds.  numbers <= 0 delay 1 usec
7617c478bd9Sstevel@tonic-gate *
7627c478bd9Sstevel@tonic-gate * With UltraSPARC-III the combination of supporting mixed-speed CPUs
7637c478bd9Sstevel@tonic-gate * and variable clock rate for power management requires that we
7647c478bd9Sstevel@tonic-gate * use %stick to implement this routine.
7657c478bd9Sstevel@tonic-gate */
7667c478bd9Sstevel@tonic-gate
7677c478bd9Sstevel@tonic-gate#if defined(lint)
7687c478bd9Sstevel@tonic-gate
7697c478bd9Sstevel@tonic-gate/*ARGSUSED*/
7707c478bd9Sstevel@tonic-gatevoid
7717c478bd9Sstevel@tonic-gatedrv_usecwait(clock_t n)
7727c478bd9Sstevel@tonic-gate{}
7737c478bd9Sstevel@tonic-gate
7747c478bd9Sstevel@tonic-gate/*ARGSUSED*/
7757c478bd9Sstevel@tonic-gatevoid
7767c478bd9Sstevel@tonic-gateusec_delay(int n)
7777c478bd9Sstevel@tonic-gate{}
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate#else	/* lint */
7807c478bd9Sstevel@tonic-gate
7817c478bd9Sstevel@tonic-gate	ENTRY(drv_usecwait)
7827c478bd9Sstevel@tonic-gate	ALTENTRY(usec_delay)
7837c478bd9Sstevel@tonic-gate	brlez,a,pn %o0, 0f
7847c478bd9Sstevel@tonic-gate	  mov	1, %o0
7857c478bd9Sstevel@tonic-gate0:
7867c478bd9Sstevel@tonic-gate	sethi	%hi(sticks_per_usec), %o1
7877c478bd9Sstevel@tonic-gate	lduw	[%o1 + %lo(sticks_per_usec)], %o1
7887c478bd9Sstevel@tonic-gate	mulx	%o1, %o0, %o1		! Scale usec to ticks
7897c478bd9Sstevel@tonic-gate	inc	%o1			! We don't start on a tick edge
790023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__)
7917c478bd9Sstevel@tonic-gate	add	%o1, %o2, %o1
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate1:	cmp	%o1, %o2
794023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o2,%o3,%o4,__LINE__)
7957c478bd9Sstevel@tonic-gate	bgeu,pt	%xcc, 1b
7967c478bd9Sstevel@tonic-gate	  nop
7977c478bd9Sstevel@tonic-gate	retl
7987c478bd9Sstevel@tonic-gate	  nop
7997c478bd9Sstevel@tonic-gate	SET_SIZE(usec_delay)
8007c478bd9Sstevel@tonic-gate	SET_SIZE(drv_usecwait)
8017c478bd9Sstevel@tonic-gate#endif	/* lint */
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate#if defined(lint)
8047c478bd9Sstevel@tonic-gate
8057c478bd9Sstevel@tonic-gate/* ARGSUSED */
8067c478bd9Sstevel@tonic-gatevoid
8077c478bd9Sstevel@tonic-gatepil14_interrupt(int level)
8087c478bd9Sstevel@tonic-gate{}
8097c478bd9Sstevel@tonic-gate
8107c478bd9Sstevel@tonic-gate#else
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate/*
8137c478bd9Sstevel@tonic-gate * Level-14 interrupt prologue.
8147c478bd9Sstevel@tonic-gate */
8157c478bd9Sstevel@tonic-gate	ENTRY_NP(pil14_interrupt)
8167c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)
8177c478bd9Sstevel@tonic-gate	rdpr	%pil, %g6			! %g6 = interrupted PIL
8187c478bd9Sstevel@tonic-gate	stn	%g6, [%g1 + CPU_PROFILE_PIL]	! record interrupted PIL
8197c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
8207c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g5
8217c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g6		! trap from supervisor mode?
8227c478bd9Sstevel@tonic-gate	bnz,a,pt %xcc, 1f
8237c478bd9Sstevel@tonic-gate	  stn	%g5, [%g1 + CPU_PROFILE_PC]	! if so, record kernel PC
8247c478bd9Sstevel@tonic-gate	stn	%g5, [%g1 + CPU_PROFILE_UPC]	! if not, record user PC
8257c478bd9Sstevel@tonic-gate	ba	pil_interrupt_common		! must be large-disp branch
8267c478bd9Sstevel@tonic-gate	  stn	%g0, [%g1 + CPU_PROFILE_PC]	! zero kernel PC
8277c478bd9Sstevel@tonic-gate1:	ba	pil_interrupt_common		! must be large-disp branch
8287c478bd9Sstevel@tonic-gate	  stn	%g0, [%g1 + CPU_PROFILE_UPC]	! zero user PC
8297c478bd9Sstevel@tonic-gate	SET_SIZE(pil14_interrupt)
8307c478bd9Sstevel@tonic-gate
8317c478bd9Sstevel@tonic-gate	ENTRY_NP(tick_rtt)
8327c478bd9Sstevel@tonic-gate	!
8337c478bd9Sstevel@tonic-gate	! Load TICK_COMPARE into %o5; if bit 63 is set, then TICK_COMPARE is
8347c478bd9Sstevel@tonic-gate	! disabled.  If TICK_COMPARE is enabled, we know that we need to
8357c478bd9Sstevel@tonic-gate	! reenqueue the interrupt request structure.  We'll then check TICKINT
8367c478bd9Sstevel@tonic-gate	! in SOFTINT; if it's set, then we know that we were in a TICK_COMPARE
8377c478bd9Sstevel@tonic-gate	! interrupt.  In this case, TICK_COMPARE may have been rewritten
8387c478bd9Sstevel@tonic-gate	! recently; we'll compare %o5 to the current time to verify that it's
8397c478bd9Sstevel@tonic-gate	! in the future.
8407c478bd9Sstevel@tonic-gate	!
8417c478bd9Sstevel@tonic-gate	! Note that %o5 is live until after 1f.
8427c478bd9Sstevel@tonic-gate	! XXX - there is a subroutine call while %o5 is live!
8437c478bd9Sstevel@tonic-gate	!
844023e71deSHaik Aftandilian	RD_TICKCMPR(%o5,%g1,%g2,__LINE__)
8457c478bd9Sstevel@tonic-gate	srlx	%o5, TICKINT_DIS_SHFT, %g1
8467c478bd9Sstevel@tonic-gate	brnz,pt	%g1, 2f
8477c478bd9Sstevel@tonic-gate	  nop
8487c478bd9Sstevel@tonic-gate
8497c478bd9Sstevel@tonic-gate	rdpr 	%pstate, %g5
8507c478bd9Sstevel@tonic-gate	andn	%g5, PSTATE_IE, %g1
8517c478bd9Sstevel@tonic-gate	wrpr	%g0, %g1, %pstate		! Disable vec interrupts
8527c478bd9Sstevel@tonic-gate
8537c478bd9Sstevel@tonic-gate	sethi	%hi(cbe_level14_inum), %o1
854b0fc0e77Sgovinda	ldx	[%o1 + %lo(cbe_level14_inum)], %o1
8557c478bd9Sstevel@tonic-gate	call	intr_enqueue_req ! preserves %o5 and %g5
8567c478bd9Sstevel@tonic-gate	  mov	PIL_14, %o0
8577c478bd9Sstevel@tonic-gate
8587c478bd9Sstevel@tonic-gate	! Check SOFTINT for TICKINT/STICKINT
8597c478bd9Sstevel@tonic-gate	rd	SOFTINT, %o4
8607c478bd9Sstevel@tonic-gate	set	(TICK_INT_MASK | STICK_INT_MASK), %o0
8617c478bd9Sstevel@tonic-gate	andcc	%o4, %o0, %g0
8627c478bd9Sstevel@tonic-gate	bz,a,pn	%icc, 2f
8637c478bd9Sstevel@tonic-gate	  wrpr	%g0, %g5, %pstate		! Enable vec interrupts
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate	! clear TICKINT/STICKINT
8667c478bd9Sstevel@tonic-gate	wr	%o0, CLEAR_SOFTINT
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate	!
8697c478bd9Sstevel@tonic-gate	! Now that we've cleared TICKINT, we can reread %tick and confirm
8707c478bd9Sstevel@tonic-gate	! that the value we programmed is still in the future.  If it isn't,
8717c478bd9Sstevel@tonic-gate	! we need to reprogram TICK_COMPARE to fire as soon as possible.
8727c478bd9Sstevel@tonic-gate	!
873023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__)	! %o0 = tick
8747c478bd9Sstevel@tonic-gate	cmp	%o5, %o0			! In the future?
8757c478bd9Sstevel@tonic-gate	bg,a,pt	%xcc, 2f			! Yes, drive on.
8767c478bd9Sstevel@tonic-gate	  wrpr	%g0, %g5, %pstate		!   delay: enable vec intr
8777c478bd9Sstevel@tonic-gate
8787c478bd9Sstevel@tonic-gate	!
8797c478bd9Sstevel@tonic-gate	! If we're here, then we have programmed TICK_COMPARE with a %tick
8807c478bd9Sstevel@tonic-gate	! which is in the past; we'll now load an initial step size, and loop
8817c478bd9Sstevel@tonic-gate	! until we've managed to program TICK_COMPARE to fire in the future.
8827c478bd9Sstevel@tonic-gate	!
8837c478bd9Sstevel@tonic-gate	mov	8, %o4				! 8 = arbitrary inital step
8847c478bd9Sstevel@tonic-gate1:	add	%o0, %o4, %o5			! Add the step
8857c478bd9Sstevel@tonic-gate	WR_TICKCMPR(%o5,%g1,%g2,__LINE__)	! Write to TICK_CMPR
886023e71deSHaik Aftandilian	GET_NATIVE_TIME(%o0,%g1,%g2,__LINE__)	! %o0 = tick
8877c478bd9Sstevel@tonic-gate	cmp	%o5, %o0			! In the future?
8887c478bd9Sstevel@tonic-gate	bg,a,pt	%xcc, 2f			! Yes, drive on.
8897c478bd9Sstevel@tonic-gate	  wrpr	%g0, %g5, %pstate		!    delay: enable vec intr
8907c478bd9Sstevel@tonic-gate	ba	1b				! No, try again.
8917c478bd9Sstevel@tonic-gate	  sllx	%o4, 1, %o4			!    delay: double step size
8927c478bd9Sstevel@tonic-gate
8937c478bd9Sstevel@tonic-gate2:	ba	current_thread_complete
8947c478bd9Sstevel@tonic-gate	  nop
8957c478bd9Sstevel@tonic-gate	SET_SIZE(tick_rtt)
8967c478bd9Sstevel@tonic-gate
8977c478bd9Sstevel@tonic-gate#endif /* lint */
8987c478bd9Sstevel@tonic-gate
8997c478bd9Sstevel@tonic-gate#if defined(lint)
900b9e93c10SJonathan Haslam
901b9e93c10SJonathan Haslam/* ARGSUSED */
902b9e93c10SJonathan Haslamvoid
903b9e93c10SJonathan Haslampil15_interrupt(int level)
904b9e93c10SJonathan Haslam{}
905b9e93c10SJonathan Haslam
906b9e93c10SJonathan Haslam#else   /* lint */
907b9e93c10SJonathan Haslam
908b9e93c10SJonathan Haslam/*
909b9e93c10SJonathan Haslam * Level-15 interrupt prologue.
910b9e93c10SJonathan Haslam */
911b9e93c10SJonathan Haslam       ENTRY_NP(pil15_interrupt)
912b9e93c10SJonathan Haslam       CPU_ADDR(%g1, %g2)
913b9e93c10SJonathan Haslam       rdpr    %tstate, %g6
914b9e93c10SJonathan Haslam       rdpr    %tpc, %g5
915b9e93c10SJonathan Haslam       btst    TSTATE_PRIV, %g6                ! trap from supervisor mode?
916b9e93c10SJonathan Haslam       bnz,a,pt %xcc, 1f
917b9e93c10SJonathan Haslam       stn     %g5, [%g1 + CPU_CPCPROFILE_PC]  ! if so, record kernel PC
918b9e93c10SJonathan Haslam       stn     %g5, [%g1 + CPU_CPCPROFILE_UPC] ! if not, record user PC
919b9e93c10SJonathan Haslam       ba      pil15_epilogue                  ! must be large-disp branch
920b9e93c10SJonathan Haslam       stn     %g0, [%g1 + CPU_CPCPROFILE_PC]  ! zero kernel PC
921b9e93c10SJonathan Haslam1:     ba      pil15_epilogue                  ! must be large-disp branch
922b9e93c10SJonathan Haslam       stn     %g0, [%g1 + CPU_CPCPROFILE_UPC] ! zero user PC
923b9e93c10SJonathan Haslam       SET_SIZE(pil15_interrupt)
924b9e93c10SJonathan Haslam
925b9e93c10SJonathan Haslam#endif  /* lint */
926b9e93c10SJonathan Haslam
927b9e93c10SJonathan Haslam#if defined(lint)
9287c478bd9Sstevel@tonic-gate/*
9297c478bd9Sstevel@tonic-gate * Prefetch a page_t for write or read, this assumes a linear
9307c478bd9Sstevel@tonic-gate * scan of sequential page_t's.
9317c478bd9Sstevel@tonic-gate */
9327c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9337c478bd9Sstevel@tonic-gatevoid
9347c478bd9Sstevel@tonic-gateprefetch_page_w(void *pp)
9357c478bd9Sstevel@tonic-gate{}
9367c478bd9Sstevel@tonic-gate
9377c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9387c478bd9Sstevel@tonic-gatevoid
9397c478bd9Sstevel@tonic-gateprefetch_page_r(void *pp)
9407c478bd9Sstevel@tonic-gate{}
9417c478bd9Sstevel@tonic-gate#else	/* lint */
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */
9447c478bd9Sstevel@tonic-gate        ENTRY(prefetch_page_w)
9457c478bd9Sstevel@tonic-gate        retl
9467c478bd9Sstevel@tonic-gate	  nop
9477c478bd9Sstevel@tonic-gate        SET_SIZE(prefetch_page_w)
9487c478bd9Sstevel@tonic-gate
9497c478bd9Sstevel@tonic-gate        ENTRY(prefetch_page_r)
9507c478bd9Sstevel@tonic-gate        retl
9517c478bd9Sstevel@tonic-gate	  nop
9527c478bd9Sstevel@tonic-gate        SET_SIZE(prefetch_page_r)
9537c478bd9Sstevel@tonic-gate
9547c478bd9Sstevel@tonic-gate#endif	/* lint */
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate#if defined(lint)
9577c478bd9Sstevel@tonic-gate/*
9587c478bd9Sstevel@tonic-gate * Prefetch struct smap for write.
9597c478bd9Sstevel@tonic-gate */
9607c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9617c478bd9Sstevel@tonic-gatevoid
9627c478bd9Sstevel@tonic-gateprefetch_smap_w(void *smp)
9637c478bd9Sstevel@tonic-gate{}
9647c478bd9Sstevel@tonic-gate#else	/* lint */
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate/* XXXQ These should be inline templates, not functions */
9677c478bd9Sstevel@tonic-gate	ENTRY(prefetch_smap_w)
9687c478bd9Sstevel@tonic-gate	retl
9697c478bd9Sstevel@tonic-gate	  nop
9707c478bd9Sstevel@tonic-gate	SET_SIZE(prefetch_smap_w)
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate#endif	/* lint */
9737c478bd9Sstevel@tonic-gate
9747c478bd9Sstevel@tonic-gate/*
9757c478bd9Sstevel@tonic-gate * Generic sun4v MMU and Cache operations.
9767c478bd9Sstevel@tonic-gate */
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate#if defined(lint)
9797c478bd9Sstevel@tonic-gate
9807c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9817c478bd9Sstevel@tonic-gatevoid
9821e2e7a75Shuahvtag_flushpage(caddr_t vaddr, uint64_t sfmmup)
9837c478bd9Sstevel@tonic-gate{}
9847c478bd9Sstevel@tonic-gate
9857c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9867c478bd9Sstevel@tonic-gatevoid
9877c478bd9Sstevel@tonic-gatevtag_flushall(void)
9887c478bd9Sstevel@tonic-gate{}
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9917c478bd9Sstevel@tonic-gatevoid
9927c478bd9Sstevel@tonic-gatevtag_unmap_perm_tl1(uint64_t vaddr, uint64_t ctxnum)
9937c478bd9Sstevel@tonic-gate{}
9947c478bd9Sstevel@tonic-gate
9957c478bd9Sstevel@tonic-gate/*ARGSUSED*/
9967c478bd9Sstevel@tonic-gatevoid
9971e2e7a75Shuahvtag_flushpage_tl1(uint64_t vaddr, uint64_t sfmmup)
9987c478bd9Sstevel@tonic-gate{}
9997c478bd9Sstevel@tonic-gate
10007c478bd9Sstevel@tonic-gate/*ARGSUSED*/
10017c478bd9Sstevel@tonic-gatevoid
10021e2e7a75Shuahvtag_flush_pgcnt_tl1(uint64_t vaddr, uint64_t sfmmup_pgcnt)
10037c478bd9Sstevel@tonic-gate{}
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate/*ARGSUSED*/
10067c478bd9Sstevel@tonic-gatevoid
10077c478bd9Sstevel@tonic-gatevtag_flushall_tl1(uint64_t dummy1, uint64_t dummy2)
10087c478bd9Sstevel@tonic-gate{}
10097c478bd9Sstevel@tonic-gate
10107c478bd9Sstevel@tonic-gate/*ARGSUSED*/
10117c478bd9Sstevel@tonic-gatevoid
10127c478bd9Sstevel@tonic-gatevac_flushpage(pfn_t pfnum, int vcolor)
10137c478bd9Sstevel@tonic-gate{}
10147c478bd9Sstevel@tonic-gate
10157c478bd9Sstevel@tonic-gate/*ARGSUSED*/
10167c478bd9Sstevel@tonic-gatevoid
10177c478bd9Sstevel@tonic-gatevac_flushpage_tl1(uint64_t pfnum, uint64_t vcolor)
10187c478bd9Sstevel@tonic-gate{}
10197c478bd9Sstevel@tonic-gate
10207c478bd9Sstevel@tonic-gate/*ARGSUSED*/
10217c478bd9Sstevel@tonic-gatevoid
10227c478bd9Sstevel@tonic-gateflush_instr_mem(caddr_t vaddr, size_t len)
10237c478bd9Sstevel@tonic-gate{}
10247c478bd9Sstevel@tonic-gate
10257c478bd9Sstevel@tonic-gate#else	/* lint */
10267c478bd9Sstevel@tonic-gate
10277c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage)
10287c478bd9Sstevel@tonic-gate	/*
10297c478bd9Sstevel@tonic-gate	 * flush page from the tlb
10307c478bd9Sstevel@tonic-gate	 *
10317c478bd9Sstevel@tonic-gate	 * %o0 = vaddr
10321e2e7a75Shuah	 * %o1 = sfmmup
10337c478bd9Sstevel@tonic-gate	 */
10341e2e7a75Shuah	SFMMU_CPU_CNUM(%o1, %g1, %g2)   /* %g1 = sfmmu cnum on this CPU */
10351e2e7a75Shuah
10361e2e7a75Shuah	mov	%g1, %o1
10377c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
10387c478bd9Sstevel@tonic-gate	ta	MMU_UNMAP_ADDR
10397c478bd9Sstevel@tonic-gate	brz,pt	%o0, 1f
10407c478bd9Sstevel@tonic-gate	  nop
10417c478bd9Sstevel@tonic-gate	ba	panic_bad_hcall
10427c478bd9Sstevel@tonic-gate	  mov	MMU_UNMAP_ADDR, %o1
10437c478bd9Sstevel@tonic-gate1:
10447c478bd9Sstevel@tonic-gate 	retl
10457c478bd9Sstevel@tonic-gate	  nop
10467c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushpage)
10477c478bd9Sstevel@tonic-gate
10487c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushall)
10497c478bd9Sstevel@tonic-gate	mov	%g0, %o0	! XXX no cpu list yet
10507c478bd9Sstevel@tonic-gate	mov	%g0, %o1	! XXX no cpu list yet
10517c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
10527c478bd9Sstevel@tonic-gate	mov	MMU_DEMAP_ALL, %o5
10537c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
10547c478bd9Sstevel@tonic-gate	brz,pt	%o0, 1f
10557c478bd9Sstevel@tonic-gate	  nop
10567c478bd9Sstevel@tonic-gate	ba	panic_bad_hcall
10577c478bd9Sstevel@tonic-gate	  mov	MMU_DEMAP_ALL, %o1
10587c478bd9Sstevel@tonic-gate1:
10597c478bd9Sstevel@tonic-gate	retl
10607c478bd9Sstevel@tonic-gate	  nop
10617c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushall)
10627c478bd9Sstevel@tonic-gate
10637c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_unmap_perm_tl1)
10647c478bd9Sstevel@tonic-gate	/*
10657c478bd9Sstevel@tonic-gate	 * x-trap to unmap perm map entry
10667c478bd9Sstevel@tonic-gate	 * %g1 = vaddr
10671e2e7a75Shuah	 * %g2 = ctxnum (KCONTEXT only)
10687c478bd9Sstevel@tonic-gate	 */
10697c478bd9Sstevel@tonic-gate	mov	%o0, %g3
10707c478bd9Sstevel@tonic-gate	mov	%o1, %g4
10717c478bd9Sstevel@tonic-gate	mov	%o2, %g5
10727c478bd9Sstevel@tonic-gate	mov	%o5, %g6
10737c478bd9Sstevel@tonic-gate	mov	%g1, %o0
10747c478bd9Sstevel@tonic-gate	mov	%g2, %o1
10757c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
10767c478bd9Sstevel@tonic-gate	mov	UNMAP_PERM_ADDR, %o5
10777c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
10787c478bd9Sstevel@tonic-gate	brz,pt	%o0, 1f
10797c478bd9Sstevel@tonic-gate	nop
10801ae08745Sheppo
10817c478bd9Sstevel@tonic-gate	mov	PTL1_BAD_HCALL, %g1
10821ae08745Sheppo
10831ae08745Sheppo	cmp	%o0, H_ENOMAP
10841ae08745Sheppo	move	%xcc, PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP, %g1
10851ae08745Sheppo
10861ae08745Sheppo	cmp	%o0, H_EINVAL
10871ae08745Sheppo	move	%xcc, PTL1_BAD_HCALL_UNMAP_PERM_EINVAL, %g1
10881ae08745Sheppo
10891ae08745Sheppo	ba,a	ptl1_panic
10907c478bd9Sstevel@tonic-gate1:
10917c478bd9Sstevel@tonic-gate	mov	%g6, %o5
10927c478bd9Sstevel@tonic-gate	mov	%g5, %o2
10937c478bd9Sstevel@tonic-gate	mov	%g4, %o1
10947c478bd9Sstevel@tonic-gate	mov	%g3, %o0
10957c478bd9Sstevel@tonic-gate	retry
10967c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_unmap_perm_tl1)
10977c478bd9Sstevel@tonic-gate
10987c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushpage_tl1)
10997c478bd9Sstevel@tonic-gate	/*
11007c478bd9Sstevel@tonic-gate	 * x-trap to flush page from tlb and tsb
11017c478bd9Sstevel@tonic-gate	 *
11027c478bd9Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
11031e2e7a75Shuah	 * %g2 = sfmmup
11047c478bd9Sstevel@tonic-gate	 *
11057c478bd9Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
11067c478bd9Sstevel@tonic-gate	 */
11077c478bd9Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
11087c478bd9Sstevel@tonic-gate	slln	%g1, MMU_PAGESHIFT, %g1			/* g1 = vaddr */
11097c478bd9Sstevel@tonic-gate	mov	%o0, %g3
11107c478bd9Sstevel@tonic-gate	mov	%o1, %g4
11117c478bd9Sstevel@tonic-gate	mov	%o2, %g5
11121e2e7a75Shuah	mov	%g1, %o0			/* vaddr */
11131e2e7a75Shuah
11141e2e7a75Shuah	SFMMU_CPU_CNUM(%g2, %o1, %g6)   /* %o1 = sfmmu cnum on this CPU */
11151e2e7a75Shuah
11167c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
11177c478bd9Sstevel@tonic-gate	ta	MMU_UNMAP_ADDR
11187c478bd9Sstevel@tonic-gate	brz,pt	%o0, 1f
11197c478bd9Sstevel@tonic-gate	nop
11207c478bd9Sstevel@tonic-gate	  ba	ptl1_panic
11217c478bd9Sstevel@tonic-gate	mov	PTL1_BAD_HCALL, %g1
11227c478bd9Sstevel@tonic-gate1:
11237c478bd9Sstevel@tonic-gate	mov	%g5, %o2
11247c478bd9Sstevel@tonic-gate	mov	%g4, %o1
11257c478bd9Sstevel@tonic-gate	mov	%g3, %o0
11267c478bd9Sstevel@tonic-gate	membar #Sync
11277c478bd9Sstevel@tonic-gate	retry
11287c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushpage_tl1)
11297c478bd9Sstevel@tonic-gate
11307c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flush_pgcnt_tl1)
11317c478bd9Sstevel@tonic-gate	/*
11327c478bd9Sstevel@tonic-gate	 * x-trap to flush pgcnt MMU_PAGESIZE pages from tlb
11337c478bd9Sstevel@tonic-gate	 *
11347c478bd9Sstevel@tonic-gate	 * %g1 = vaddr, zero-extended on 32-bit kernel
11351e2e7a75Shuah	 * %g2 = <sfmmup58|pgcnt6>, (pgcnt - 1) is pass'ed in via pgcnt6 bits.
11367c478bd9Sstevel@tonic-gate	 *
11377c478bd9Sstevel@tonic-gate	 * NOTE: this handler relies on the fact that no
11387c478bd9Sstevel@tonic-gate	 *	interrupts or traps can occur during the loop
11397c478bd9Sstevel@tonic-gate	 *	issuing the TLB_DEMAP operations. It is assumed
11407c478bd9Sstevel@tonic-gate	 *	that interrupts are disabled and this code is
11417c478bd9Sstevel@tonic-gate	 *	fetching from the kernel locked text address.
11427c478bd9Sstevel@tonic-gate	 *
11437c478bd9Sstevel@tonic-gate	 * assumes TSBE_TAG = 0
11447c478bd9Sstevel@tonic-gate	 */
11457c478bd9Sstevel@tonic-gate	srln	%g1, MMU_PAGESHIFT, %g1
11467c478bd9Sstevel@tonic-gate	slln	%g1, MMU_PAGESHIFT, %g1		/* g1 = vaddr */
11477c478bd9Sstevel@tonic-gate	mov	%o0, %g3
11487c478bd9Sstevel@tonic-gate	mov	%o1, %g4
11497c478bd9Sstevel@tonic-gate	mov	%o2, %g5
11507c478bd9Sstevel@tonic-gate
11511e2e7a75Shuah	and	%g2, SFMMU_PGCNT_MASK, %g7	/* g7 = pgcnt - 1 */
11521e2e7a75Shuah	add	%g7, 1, %g7			/* g7 = pgcnt */
11537c478bd9Sstevel@tonic-gate
11541e2e7a75Shuah        andn    %g2, SFMMU_PGCNT_MASK, %o0      /* %o0 = sfmmup */
11551e2e7a75Shuah
11561e2e7a75Shuah	SFMMU_CPU_CNUM(%o0, %g2, %g6)    /* %g2 = sfmmu cnum on this CPU */
11571e2e7a75Shuah
11581e2e7a75Shuah	set	MMU_PAGESIZE, %g6		/* g6 = pgsize */
11591e2e7a75Shuah
11607c478bd9Sstevel@tonic-gate1:
11611e2e7a75Shuah	mov	%g1, %o0			/* vaddr */
11621e2e7a75Shuah	mov	%g2, %o1			/* cnum */
11637c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
11647c478bd9Sstevel@tonic-gate	ta	MMU_UNMAP_ADDR
11657c478bd9Sstevel@tonic-gate	brz,pt	%o0, 2f
11667c478bd9Sstevel@tonic-gate	  nop
11677c478bd9Sstevel@tonic-gate	ba	ptl1_panic
11687c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_HCALL, %g1
11697c478bd9Sstevel@tonic-gate2:
11707c478bd9Sstevel@tonic-gate	deccc	%g7				/* decr pgcnt */
11717c478bd9Sstevel@tonic-gate	bnz,pt	%icc,1b
11727c478bd9Sstevel@tonic-gate	  add	%g1, %g6, %g1			/* go to nextpage */
11737c478bd9Sstevel@tonic-gate
11747c478bd9Sstevel@tonic-gate	mov	%g5, %o2
11757c478bd9Sstevel@tonic-gate	mov	%g4, %o1
11767c478bd9Sstevel@tonic-gate	mov	%g3, %o0
11777c478bd9Sstevel@tonic-gate	membar #Sync
11787c478bd9Sstevel@tonic-gate	retry
11797c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flush_pgcnt_tl1)
11807c478bd9Sstevel@tonic-gate
11817c478bd9Sstevel@tonic-gate	! Not implemented on US1/US2
11827c478bd9Sstevel@tonic-gate	ENTRY_NP(vtag_flushall_tl1)
11837c478bd9Sstevel@tonic-gate	mov	%o0, %g3
11847c478bd9Sstevel@tonic-gate	mov	%o1, %g4
11857c478bd9Sstevel@tonic-gate	mov	%o2, %g5
11867c478bd9Sstevel@tonic-gate	mov	%o3, %g6	! XXXQ not used?
11877c478bd9Sstevel@tonic-gate	mov	%o5, %g7
11887c478bd9Sstevel@tonic-gate	mov	%g0, %o0	! XXX no cpu list yet
11897c478bd9Sstevel@tonic-gate	mov	%g0, %o1	! XXX no cpu list yet
11907c478bd9Sstevel@tonic-gate	mov	MAP_ITLB | MAP_DTLB, %o2
11917c478bd9Sstevel@tonic-gate	mov	MMU_DEMAP_ALL, %o5
11927c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
11937c478bd9Sstevel@tonic-gate	brz,pt	%o0, 1f
11947c478bd9Sstevel@tonic-gate	  nop
11957c478bd9Sstevel@tonic-gate	ba	ptl1_panic
11967c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_HCALL, %g1
11977c478bd9Sstevel@tonic-gate1:
11987c478bd9Sstevel@tonic-gate	mov	%g7, %o5
11997c478bd9Sstevel@tonic-gate	mov	%g6, %o3	! XXXQ not used?
12007c478bd9Sstevel@tonic-gate	mov	%g5, %o2
12017c478bd9Sstevel@tonic-gate	mov	%g4, %o1
12027c478bd9Sstevel@tonic-gate	mov	%g3, %o0
12037c478bd9Sstevel@tonic-gate	retry
12047c478bd9Sstevel@tonic-gate	SET_SIZE(vtag_flushall_tl1)
12057c478bd9Sstevel@tonic-gate
12067c478bd9Sstevel@tonic-gate/*
12077c478bd9Sstevel@tonic-gate * flush_instr_mem:
12087c478bd9Sstevel@tonic-gate *	Flush a portion of the I-$ starting at vaddr
12097c478bd9Sstevel@tonic-gate * 	%o0 vaddr
12107c478bd9Sstevel@tonic-gate *	%o1 bytes to be flushed
12117c478bd9Sstevel@tonic-gate */
12127c478bd9Sstevel@tonic-gate
12137c478bd9Sstevel@tonic-gate	ENTRY(flush_instr_mem)
12147c478bd9Sstevel@tonic-gate	membar	#StoreStore				! Ensure the stores
12157c478bd9Sstevel@tonic-gate							! are globally visible
12167c478bd9Sstevel@tonic-gate1:
12177c478bd9Sstevel@tonic-gate	flush	%o0
12187c478bd9Sstevel@tonic-gate	subcc	%o1, ICACHE_FLUSHSZ, %o1		! bytes = bytes-0x20
12197c478bd9Sstevel@tonic-gate	bgu,pt	%ncc, 1b
12207c478bd9Sstevel@tonic-gate	  add	%o0, ICACHE_FLUSHSZ, %o0		! vaddr = vaddr+0x20
12217c478bd9Sstevel@tonic-gate
12227c478bd9Sstevel@tonic-gate	retl
12237c478bd9Sstevel@tonic-gate	  nop
12247c478bd9Sstevel@tonic-gate	SET_SIZE(flush_instr_mem)
12257c478bd9Sstevel@tonic-gate
12267c478bd9Sstevel@tonic-gate#endif /* !lint */
12277bafd143Sjb145095
12282f0fcb93SJason Beloro#if !defined(CUSTOM_FPZERO)
12292f0fcb93SJason Beloro
12307bafd143Sjb145095/*
12317bafd143Sjb145095 * fp_zero() - clear all fp data registers and the fsr
12327bafd143Sjb145095 */
12337bafd143Sjb145095
12347bafd143Sjb145095#if defined(lint) || defined(__lint)
12357bafd143Sjb145095
12367bafd143Sjb145095void
12377bafd143Sjb145095fp_zero(void)
12387bafd143Sjb145095{}
12397bafd143Sjb145095
12407bafd143Sjb145095#else	/* lint */
12417bafd143Sjb145095
12427bafd143Sjb145095.global	fp_zero_zero
12437bafd143Sjb145095.align 8
12447bafd143Sjb145095fp_zero_zero:
12457bafd143Sjb145095	.xword	0
12467bafd143Sjb145095
12477bafd143Sjb145095	ENTRY_NP(fp_zero)
12487bafd143Sjb145095	sethi	%hi(fp_zero_zero), %o0
12492f0fcb93SJason Beloro	ldx	[%o0 + %lo(fp_zero_zero)], %fsr
12507bafd143Sjb145095	ldd	[%o0 + %lo(fp_zero_zero)], %f0
12517bafd143Sjb145095	fmovd	%f0, %f2
12527bafd143Sjb145095	fmovd	%f0, %f4
12537bafd143Sjb145095	fmovd	%f0, %f6
12547bafd143Sjb145095	fmovd	%f0, %f8
12557bafd143Sjb145095	fmovd	%f0, %f10
12567bafd143Sjb145095	fmovd	%f0, %f12
12577bafd143Sjb145095	fmovd	%f0, %f14
12587bafd143Sjb145095	fmovd	%f0, %f16
12597bafd143Sjb145095	fmovd	%f0, %f18
12607bafd143Sjb145095	fmovd	%f0, %f20
12617bafd143Sjb145095	fmovd	%f0, %f22
12627bafd143Sjb145095	fmovd	%f0, %f24
12637bafd143Sjb145095	fmovd	%f0, %f26
12647bafd143Sjb145095	fmovd	%f0, %f28
12657bafd143Sjb145095	fmovd	%f0, %f30
12667bafd143Sjb145095	fmovd	%f0, %f32
12677bafd143Sjb145095	fmovd	%f0, %f34
12687bafd143Sjb145095	fmovd	%f0, %f36
12697bafd143Sjb145095	fmovd	%f0, %f38
12707bafd143Sjb145095	fmovd	%f0, %f40
12717bafd143Sjb145095	fmovd	%f0, %f42
12727bafd143Sjb145095	fmovd	%f0, %f44
12737bafd143Sjb145095	fmovd	%f0, %f46
12747bafd143Sjb145095	fmovd	%f0, %f48
12757bafd143Sjb145095	fmovd	%f0, %f50
12767bafd143Sjb145095	fmovd	%f0, %f52
12777bafd143Sjb145095	fmovd	%f0, %f54
12787bafd143Sjb145095	fmovd	%f0, %f56
12797bafd143Sjb145095	fmovd	%f0, %f58
12807bafd143Sjb145095	fmovd	%f0, %f60
12817bafd143Sjb145095	retl
12827bafd143Sjb145095	fmovd	%f0, %f62
12837bafd143Sjb145095	SET_SIZE(fp_zero)
12847bafd143Sjb145095
12857bafd143Sjb145095#endif	/* lint */
12862f0fcb93SJason Beloro#endif  /* CUSTOM_FPZERO */
1287