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