xref: /onnv-gate/usr/src/uts/sun4u/ml/mach_subr_asm.s (revision 11172:a792f425ae2e)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51614Sjb145095 * Common Development and Distribution License (the "License").
61614Sjb145095 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate/*
22*11172SHaik.Aftandilian@Sun.COM * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate/*
270Sstevel@tonic-gate * General machine architecture & implementation specific
280Sstevel@tonic-gate * assembly language routines.
290Sstevel@tonic-gate */
300Sstevel@tonic-gate#if defined(lint)
310Sstevel@tonic-gate#include <sys/types.h>
320Sstevel@tonic-gate#include <sys/t_lock.h>
330Sstevel@tonic-gate#else	/* lint */
340Sstevel@tonic-gate#include "assym.h"
350Sstevel@tonic-gate#endif	/* lint */
360Sstevel@tonic-gate
370Sstevel@tonic-gate#include <sys/asm_linkage.h>
380Sstevel@tonic-gate#include <sys/machsystm.h>
390Sstevel@tonic-gate#include <sys/machthread.h>
400Sstevel@tonic-gate#include <sys/privregs.h>
410Sstevel@tonic-gate#include <sys/cmpregs.h>
420Sstevel@tonic-gate#include <sys/clock.h>
430Sstevel@tonic-gate#include <sys/fpras.h>
440Sstevel@tonic-gate
450Sstevel@tonic-gate#if defined(lint)
460Sstevel@tonic-gate
47*11172SHaik.Aftandilian@Sun.COMuint64_t
48*11172SHaik.Aftandilian@Sun.COMultra_gettick(void)
49*11172SHaik.Aftandilian@Sun.COM{ return (0); }
50*11172SHaik.Aftandilian@Sun.COM
51*11172SHaik.Aftandilian@Sun.COM#else	/* lint */
52*11172SHaik.Aftandilian@Sun.COM
53*11172SHaik.Aftandilian@Sun.COM/*
54*11172SHaik.Aftandilian@Sun.COM * This isn't the routine you're looking for.
55*11172SHaik.Aftandilian@Sun.COM *
56*11172SHaik.Aftandilian@Sun.COM * The routine simply returns the value of %tick on the *current* processor.
57*11172SHaik.Aftandilian@Sun.COM * Most of the time, gettick() [which in turn maps to %stick on platforms
58*11172SHaik.Aftandilian@Sun.COM * that have different CPU %tick rates] is what you want.
59*11172SHaik.Aftandilian@Sun.COM */
60*11172SHaik.Aftandilian@Sun.COM
61*11172SHaik.Aftandilian@Sun.COM	ENTRY(ultra_gettick)
62*11172SHaik.Aftandilian@Sun.COM	retl
63*11172SHaik.Aftandilian@Sun.COM	rdpr	%tick, %o0
64*11172SHaik.Aftandilian@Sun.COM	SET_SIZE(ultra_gettick)
65*11172SHaik.Aftandilian@Sun.COM
66*11172SHaik.Aftandilian@Sun.COM#endif	/* lint */
67*11172SHaik.Aftandilian@Sun.COM
68*11172SHaik.Aftandilian@Sun.COM#if defined(lint)
69*11172SHaik.Aftandilian@Sun.COM
700Sstevel@tonic-gate/*ARGSUSED*/
710Sstevel@tonic-gateint
720Sstevel@tonic-gategetprocessorid(void)
730Sstevel@tonic-gate{ return (0); }
740Sstevel@tonic-gate
750Sstevel@tonic-gate#else	/* lint */
760Sstevel@tonic-gate
770Sstevel@tonic-gate/*
780Sstevel@tonic-gate * Get the processor ID.
790Sstevel@tonic-gate * === MID reg as specified in 15dec89 sun4u spec, sec 5.4.3
800Sstevel@tonic-gate */
810Sstevel@tonic-gate
820Sstevel@tonic-gate	ENTRY(getprocessorid)
830Sstevel@tonic-gate	CPU_INDEX(%o0, %o1)
840Sstevel@tonic-gate	retl
850Sstevel@tonic-gate	nop
860Sstevel@tonic-gate	SET_SIZE(getprocessorid)
870Sstevel@tonic-gate
880Sstevel@tonic-gate#endif	/* lint */
890Sstevel@tonic-gate
900Sstevel@tonic-gate#if defined(lint)
910Sstevel@tonic-gate/*ARGSUSED*/
920Sstevel@tonic-gatevoid
930Sstevel@tonic-gateset_error_enable_tl1(uint64_t neer, uint64_t action)
940Sstevel@tonic-gate{}
950Sstevel@tonic-gate
960Sstevel@tonic-gate/* ARGSUSED */
970Sstevel@tonic-gatevoid
980Sstevel@tonic-gateset_error_enable(uint64_t neer)
990Sstevel@tonic-gate{}
1000Sstevel@tonic-gate
1010Sstevel@tonic-gateuint64_t
1020Sstevel@tonic-gateget_error_enable()
1030Sstevel@tonic-gate{
1040Sstevel@tonic-gate	return ((uint64_t)0);
1050Sstevel@tonic-gate}
1060Sstevel@tonic-gate#else /* lint */
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate	ENTRY(set_error_enable_tl1)
1090Sstevel@tonic-gate	cmp	%g2, EER_SET_ABSOLUTE
1100Sstevel@tonic-gate	be	%xcc, 1f
1110Sstevel@tonic-gate	  nop
1120Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %g3
1130Sstevel@tonic-gate	membar	#Sync
1140Sstevel@tonic-gate	cmp	%g2, EER_SET_SETBITS
1150Sstevel@tonic-gate	be,a	%xcc, 1f
1160Sstevel@tonic-gate	  or	%g3, %g1, %g1
1170Sstevel@tonic-gate	andn	%g3, %g1, %g1			/* EER_SET_CLRBITS */
1180Sstevel@tonic-gate1:
1190Sstevel@tonic-gate	stxa	%g1, [%g0]ASI_ESTATE_ERR	/* ecache error enable reg */
1200Sstevel@tonic-gate	membar	#Sync
1210Sstevel@tonic-gate	retry
1220Sstevel@tonic-gate	SET_SIZE(set_error_enable_tl1)
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate	ENTRY(set_error_enable)
1250Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_ESTATE_ERR	/* ecache error enable reg */
1260Sstevel@tonic-gate	membar	#Sync
1270Sstevel@tonic-gate	retl
1280Sstevel@tonic-gate	nop
1290Sstevel@tonic-gate	SET_SIZE(set_error_enable)
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate	ENTRY(get_error_enable)
1320Sstevel@tonic-gate	retl
1330Sstevel@tonic-gate	ldxa	[%g0]ASI_ESTATE_ERR, %o0	/* ecache error enable reg */
1340Sstevel@tonic-gate	SET_SIZE(get_error_enable)
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate#endif /* lint */
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate#if defined(lint)
1390Sstevel@tonic-gatevoid
1400Sstevel@tonic-gateget_asyncflt(uint64_t *afsr)
1410Sstevel@tonic-gate{
1420Sstevel@tonic-gate	afsr = afsr;
1430Sstevel@tonic-gate}
1440Sstevel@tonic-gate#else /* lint */
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate	ENTRY(get_asyncflt)
1470Sstevel@tonic-gate	ldxa	[%g0]ASI_AFSR, %o1		! afsr reg
1480Sstevel@tonic-gate	retl
1490Sstevel@tonic-gate	stx	%o1, [%o0]
1500Sstevel@tonic-gate	SET_SIZE(get_asyncflt)
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate#endif /* lint */
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate#if defined(lint)
1550Sstevel@tonic-gatevoid
1560Sstevel@tonic-gateset_asyncflt(uint64_t afsr)
1570Sstevel@tonic-gate{
1580Sstevel@tonic-gate	afsr = afsr;
1590Sstevel@tonic-gate}
1600Sstevel@tonic-gate#else /* lint */
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate	ENTRY(set_asyncflt)
1630Sstevel@tonic-gate	stxa	%o0, [%g0]ASI_AFSR		! afsr reg
1640Sstevel@tonic-gate	membar	#Sync
1650Sstevel@tonic-gate	retl
1660Sstevel@tonic-gate	nop
1670Sstevel@tonic-gate	SET_SIZE(set_asyncflt)
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate#endif /* lint */
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate#if defined(lint)
1720Sstevel@tonic-gatevoid
1730Sstevel@tonic-gateget_asyncaddr(uint64_t *afar)
1740Sstevel@tonic-gate{
1750Sstevel@tonic-gate	afar = afar;
1760Sstevel@tonic-gate}
1770Sstevel@tonic-gate#else /* lint */
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate	ENTRY(get_asyncaddr)
1800Sstevel@tonic-gate	ldxa	[%g0]ASI_AFAR, %o1		! afar reg
1810Sstevel@tonic-gate	retl
1820Sstevel@tonic-gate	stx	%o1, [%o0]
1830Sstevel@tonic-gate	SET_SIZE(get_asyncaddr)
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate#endif /* lint */
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate#if defined(lint) || defined(__lint)
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate/* ARGSUSED */
1900Sstevel@tonic-gatehrtime_t
1910Sstevel@tonic-gatetick2ns(hrtime_t tick, uint_t cpuid)
1920Sstevel@tonic-gate{ return 0; }
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate#else	/* lint */
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate	ENTRY_NP(tick2ns)
1970Sstevel@tonic-gate	sethi	%hi(cpunodes), %o4
1980Sstevel@tonic-gate	or	%o4, %lo(cpunodes), %o4		! %o4 = &cpunodes
1990Sstevel@tonic-gate	! Register usage:
2000Sstevel@tonic-gate	!
2010Sstevel@tonic-gate	! o0 = timestamp
2020Sstevel@tonic-gate	! o2 = byte offset into cpunodes for tick_nsec_scale of this CPU
2030Sstevel@tonic-gate	! o4 = &cpunodes
2040Sstevel@tonic-gate	!
2050Sstevel@tonic-gate	mulx	%o1, CPU_NODE_SIZE, %o2	! %o2 = byte offset into cpunodes
2060Sstevel@tonic-gate	add	%o2, TICK_NSEC_SCALE, %o2
2070Sstevel@tonic-gate	ld	[%o4 + %o2], %o2	! %o2 = cpunodes[cpuid].tick_nsec_scale
2080Sstevel@tonic-gate	NATIVE_TIME_TO_NSEC_SCALE(%o0, %o2, %o3, TICK_NSEC_SHIFT)
2090Sstevel@tonic-gate	retl
2100Sstevel@tonic-gate	nop
2110Sstevel@tonic-gate	SET_SIZE(tick2ns)
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate#endif  /* lint */
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate#if defined(lint)
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate/* ARGSUSED */
2180Sstevel@tonic-gatevoid
2190Sstevel@tonic-gateset_cmp_error_steering(void)
2200Sstevel@tonic-gate{}
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate#else	/* lint */
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate	ENTRY(set_cmp_error_steering)
2250Sstevel@tonic-gate	membar	#Sync
2260Sstevel@tonic-gate	set	ASI_CORE_ID, %o0		! %o0 = ASI_CORE_ID
2270Sstevel@tonic-gate	ldxa	[%o0]ASI_CMP_PER_CORE, %o0	! get ASI_CORE_ID
2280Sstevel@tonic-gate	and	%o0, COREID_MASK, %o0
2290Sstevel@tonic-gate	set	ASI_CMP_ERROR_STEERING, %o1	! %o1 = ERROR_STEERING_REG
2300Sstevel@tonic-gate	stxa	%o0, [%o1]ASI_CMP_SHARED	! this core now hadles
2310Sstevel@tonic-gate	membar	#Sync				!  non-core specific errors
2320Sstevel@tonic-gate	retl
2330Sstevel@tonic-gate	nop
2340Sstevel@tonic-gate	SET_SIZE(set_cmp_error_steering)
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate#endif	/* lint */
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate#if defined(lint)
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate/* ARGSUSED */
2410Sstevel@tonic-gateuint64_t
2420Sstevel@tonic-gateultra_getver(void)
2430Sstevel@tonic-gate{
2440Sstevel@tonic-gate	return (0);
2450Sstevel@tonic-gate}
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate#else /* lint */
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate	ENTRY(ultra_getver)
2500Sstevel@tonic-gate	retl
2510Sstevel@tonic-gate	rdpr	%ver, %o0
2520Sstevel@tonic-gate	SET_SIZE(ultra_getver)
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate#endif /* lint */
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate#if defined(lint)
2570Sstevel@tonic-gate
2580Sstevel@tonic-gateint
2590Sstevel@tonic-gatefpras_chkfn_type1(void)
2600Sstevel@tonic-gate{ return 0; }
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate#else	/* lint */
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate	/*
2650Sstevel@tonic-gate	 * Check instructions using just the AX pipelines, designed by
2660Sstevel@tonic-gate	 * C.B. Liaw of PNP.
2670Sstevel@tonic-gate	 *
2680Sstevel@tonic-gate	 * This function must match a struct fpras_chkfn and must be
2690Sstevel@tonic-gate	 * block aligned.  A zero return means all was well.  These
2700Sstevel@tonic-gate	 * instructions are chosen to be sensitive to bit corruptions
2710Sstevel@tonic-gate	 * on the fpras rewrite, so if a bit corruption still produces
2720Sstevel@tonic-gate	 * a valid instruction we should still get an incorrect result
2730Sstevel@tonic-gate	 * here.  This function is never called directly - it is copied
2740Sstevel@tonic-gate	 * into per-cpu and per-operation buffers;  it must therefore
2750Sstevel@tonic-gate	 * be absolutely position independent.  If an illegal instruction
2760Sstevel@tonic-gate	 * is encountered then the trap handler trampolines to the final
2770Sstevel@tonic-gate	 * three instructions of this function.
2780Sstevel@tonic-gate	 *
2790Sstevel@tonic-gate	 * We want two instructions that are complements of one another,
2800Sstevel@tonic-gate	 * and which can perform a calculation with a known result.
2810Sstevel@tonic-gate	 *
2820Sstevel@tonic-gate	 * SETHI:
2830Sstevel@tonic-gate	 *
2840Sstevel@tonic-gate	 * | 0 0 |  rd   | 1 0 0 |	imm22				|
2850Sstevel@tonic-gate	 *  31 30 29   25 24   22 21				       0
2860Sstevel@tonic-gate	 *
2870Sstevel@tonic-gate	 * ADDCCC with two source registers:
2880Sstevel@tonic-gate	 *
2890Sstevel@tonic-gate	 * | 1 0 |  rd   | 0 1 1   0 0 0 |  rs1  | 0 |	   -	|  rs2  |
2900Sstevel@tonic-gate	 *  31 30 29   25 24           19 18   14 13  12       5 4     0
2910Sstevel@tonic-gate	 *
2920Sstevel@tonic-gate	 * We can choose rd and imm2 of the SETHI and rd, rs1 and rs2 of
2930Sstevel@tonic-gate	 * the ADDCCC to obtain instructions that are complements in all but
2940Sstevel@tonic-gate	 * bit 30.
2950Sstevel@tonic-gate	 *
2960Sstevel@tonic-gate	 * Registers are numbered as follows:
2970Sstevel@tonic-gate	 *
2980Sstevel@tonic-gate	 * r[31]	%i7
2990Sstevel@tonic-gate	 * r[30]	%i6
3000Sstevel@tonic-gate	 * r[29]	%i5
3010Sstevel@tonic-gate	 * r[28]	%i4
3020Sstevel@tonic-gate	 * r[27]	%i3
3030Sstevel@tonic-gate	 * r[26]	%i2
3040Sstevel@tonic-gate	 * r[25]	%i1
3050Sstevel@tonic-gate	 * r[24]	%i0
3060Sstevel@tonic-gate	 * r[23]	%l7
3070Sstevel@tonic-gate	 * r[22]	%l6
3080Sstevel@tonic-gate	 * r[21]	%l5
3090Sstevel@tonic-gate	 * r[20]	%l4
3100Sstevel@tonic-gate	 * r[19]	%l3
3110Sstevel@tonic-gate	 * r[18]	%l2
3120Sstevel@tonic-gate	 * r[17]	%l1
3130Sstevel@tonic-gate	 * r[16]	%l0
3140Sstevel@tonic-gate	 * r[15]	%o7
3150Sstevel@tonic-gate	 * r[14]	%o6
3160Sstevel@tonic-gate	 * r[13]	%o5
3170Sstevel@tonic-gate	 * r[12]	%o4
3180Sstevel@tonic-gate	 * r[11]	%o3
3190Sstevel@tonic-gate	 * r[10]	%o2
3200Sstevel@tonic-gate	 * r[9]		%o1
3210Sstevel@tonic-gate	 * r[8]		%o0
3220Sstevel@tonic-gate	 * r[7]		%g7
3230Sstevel@tonic-gate	 * r[6]		%g6
3240Sstevel@tonic-gate	 * r[5]		%g5
3250Sstevel@tonic-gate	 * r[4]		%g4
3260Sstevel@tonic-gate	 * r[3]		%g3
3270Sstevel@tonic-gate	 * r[2]		%g2
3280Sstevel@tonic-gate	 * r[1]		%g1
3290Sstevel@tonic-gate	 * r[0]		%g0
3300Sstevel@tonic-gate	 *
3310Sstevel@tonic-gate	 * For register r[n], register r[31-n] is the complement.  We must
3320Sstevel@tonic-gate	 * avoid use of %i6/%i7 and %o6/%o7 as well as %g7.  Clearly we need
3330Sstevel@tonic-gate	 * to use a local or input register as one half of the pair, which
3340Sstevel@tonic-gate	 * requires us to obtain our own register window or take steps
3350Sstevel@tonic-gate	 * to preserve any local or input we choose to use.  We choose
3360Sstevel@tonic-gate	 * %o1 as rd for the SETHI, so rd of the ADDCCC must be %l6.
3370Sstevel@tonic-gate	 * We'll use %o1 as rs1 and %l6 as rs2 of the ADDCCC, which then
3380Sstevel@tonic-gate	 * requires that imm22 be 0b111 10110 1 11111111 01001 or 0x3dbfe9,
3390Sstevel@tonic-gate	 * or %hi(0xf6ffa400).  This determines the value of the constant
3400Sstevel@tonic-gate	 * CBV2 below.
3410Sstevel@tonic-gate	 *
3420Sstevel@tonic-gate	 * The constant CBV1 is chosen such that an initial subcc %g0, CBV1
3430Sstevel@tonic-gate	 * will set the carry bit and every addccc thereafter will continue
3440Sstevel@tonic-gate	 * to generate a carry.  Other values are possible for CBV1 - this
3450Sstevel@tonic-gate	 * is just one that works this way.
3460Sstevel@tonic-gate	 *
3470Sstevel@tonic-gate	 * Finally CBV3 is the expected answer when we perform our repeated
3480Sstevel@tonic-gate	 * calculations on CBV1 and CBV2 - it is not otherwise specially
3490Sstevel@tonic-gate	 * derived.  If this result is not obtained then a corruption has
3500Sstevel@tonic-gate	 * occured during the FPRAS_REWRITE of one of the two blocks of
3510Sstevel@tonic-gate	 * 16 instructions.  A corruption could also result in an illegal
3520Sstevel@tonic-gate	 * instruction or other unexpected trap - we catch illegal
3530Sstevel@tonic-gate	 * instruction traps in the PC range and trampoline to the
3540Sstevel@tonic-gate	 * last instructions of the function to return a failure indication.
3550Sstevel@tonic-gate	 *
3560Sstevel@tonic-gate	 */
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate#define	CBV1		0xc11
3590Sstevel@tonic-gate#define	CBV2		0xf6ffa400
3600Sstevel@tonic-gate#define	CBV3		0x66f9d800
3610Sstevel@tonic-gate#define	CBR1		%o1
3620Sstevel@tonic-gate#define	CBR2		%l6
3630Sstevel@tonic-gate#define	CBO2		%o2
3640Sstevel@tonic-gate#define	SETHI_CBV2_CBR1		sethi %hi(CBV2), CBR1
3650Sstevel@tonic-gate#define	ADDCCC_CBR1_CBR2_CBR2	addccc CBR1, CBR2, CBR2
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate	.align	64
3680Sstevel@tonic-gate	ENTRY_NP(fpras_chkfn_type1)
3690Sstevel@tonic-gate	mov	CBR2, CBO2		! 1, preserve CBR2 of (callers) window
3700Sstevel@tonic-gate	mov	FPRAS_OK, %o0		! 2, default return value
3710Sstevel@tonic-gate	ba,pt	%icc, 1f		! 3
3720Sstevel@tonic-gate	  subcc %g0, CBV1, CBR2		! 4
3730Sstevel@tonic-gate					! 5 - 16
3740Sstevel@tonic-gate	.align	64
3750Sstevel@tonic-gate1:	SETHI_CBV2_CBR1			! 1
3760Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 2
3770Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 3
3780Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 4
3790Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 5
3800Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 6
3810Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 7
3820Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 8
3830Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 9
3840Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 10
3850Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 11
3860Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 12
3870Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 13
3880Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 14
3890Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 15
3900Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 16
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 1
3930Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 2
3940Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 3
3950Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 4
3960Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 5
3970Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 6
3980Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 7
3990Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 8
4000Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 9
4010Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 10
4020Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 11
4030Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 12
4040Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 13
4050Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 14
4060Sstevel@tonic-gate	ADDCCC_CBR1_CBR2_CBR2		! 15
4070Sstevel@tonic-gate	SETHI_CBV2_CBR1			! 16
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate	addc	CBR1, CBR2, CBR2	! 1
4100Sstevel@tonic-gate	sethi	%hi(CBV3), CBR1		! 2
4110Sstevel@tonic-gate	cmp	CBR1, CBR2		! 3
4120Sstevel@tonic-gate	movnz	%icc, FPRAS_BADCALC, %o0! 4, how detected
4130Sstevel@tonic-gate	retl				! 5
4140Sstevel@tonic-gate	  mov	CBO2, CBR2		! 6, restore borrowed register
4150Sstevel@tonic-gate	.skip 4*(13-7+1)		! 7 - 13
4160Sstevel@tonic-gate					!
4170Sstevel@tonic-gate					! illegal instr'n trap comes here
4180Sstevel@tonic-gate					!
4190Sstevel@tonic-gate	mov	CBO2, CBR2		! 14, restore borrowed register
4200Sstevel@tonic-gate	retl				! 15
4210Sstevel@tonic-gate	  mov	FPRAS_BADTRAP, %o0	! 16, how detected
4220Sstevel@tonic-gate	SET_SIZE(fpras_chkfn_type1)
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate#endif	/* lint */
4251614Sjb145095
4261614Sjb145095/*
4271614Sjb145095 * fp_zero() - clear all fp data registers and the fsr
4281614Sjb145095 */
4291614Sjb145095
4301614Sjb145095#if defined(lint) || defined(__lint)
4311614Sjb145095
4321614Sjb145095void
4331614Sjb145095fp_zero(void)
4341614Sjb145095{}
4351614Sjb145095
4361614Sjb145095#else	/* lint */
4371614Sjb145095
4381614Sjb145095	ENTRY_NP(fp_zero)
4391614Sjb145095	std	%g0, [%sp + ARGPUSH + STACK_BIAS]
4401614Sjb145095	fzero	%f0
4411614Sjb145095	fzero	%f2
4421614Sjb145095	ldd	[%sp + ARGPUSH + STACK_BIAS], %fsr
4431614Sjb145095	faddd	%f0, %f2, %f4
4441614Sjb145095	fmuld	%f0, %f2, %f6
4451614Sjb145095	faddd	%f0, %f2, %f8
4461614Sjb145095	fmuld	%f0, %f2, %f10
4471614Sjb145095	faddd	%f0, %f2, %f12
4481614Sjb145095	fmuld	%f0, %f2, %f14
4491614Sjb145095	faddd	%f0, %f2, %f16
4501614Sjb145095	fmuld	%f0, %f2, %f18
4511614Sjb145095	faddd	%f0, %f2, %f20
4521614Sjb145095	fmuld	%f0, %f2, %f22
4531614Sjb145095	faddd	%f0, %f2, %f24
4541614Sjb145095	fmuld	%f0, %f2, %f26
4551614Sjb145095	faddd	%f0, %f2, %f28
4561614Sjb145095	fmuld	%f0, %f2, %f30
4571614Sjb145095	faddd	%f0, %f2, %f32
4581614Sjb145095	fmuld	%f0, %f2, %f34
4591614Sjb145095	faddd	%f0, %f2, %f36
4601614Sjb145095	fmuld	%f0, %f2, %f38
4611614Sjb145095	faddd	%f0, %f2, %f40
4621614Sjb145095	fmuld	%f0, %f2, %f42
4631614Sjb145095	faddd	%f0, %f2, %f44
4641614Sjb145095	fmuld	%f0, %f2, %f46
4651614Sjb145095	faddd	%f0, %f2, %f48
4661614Sjb145095	fmuld	%f0, %f2, %f50
4671614Sjb145095	faddd	%f0, %f2, %f52
4681614Sjb145095	fmuld	%f0, %f2, %f54
4691614Sjb145095	faddd	%f0, %f2, %f56
4701614Sjb145095	fmuld	%f0, %f2, %f58
4711614Sjb145095	faddd	%f0, %f2, %f60
4721614Sjb145095	retl
4731614Sjb145095	fmuld	%f0, %f2, %f62
4741614Sjb145095	SET_SIZE(fp_zero)
4751614Sjb145095
4761614Sjb145095#endif	/* lint */
477