float.s revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ident "%Z%%M% %I% %E% SMI"
#include <sys/asm_linkage.h>
#include "assym.h"
#endif /* lint */
/*
* Floating point trap handling.
*
* The FPU is always in a V9 current configuration.
*
* When a user process is first started via exec,
* floating point operations will be disabled by default.
* Upon execution of the first floating point instruction,
* a fp_disabled trap will be generated; then a word in
* the uarea is written signifying use of the floating point
* registers so that subsequent context switches will save
* and restore the floating point them. The trapped instruction
* will be restarted and processing will continue as normal.
*
* When a operation occurs that the hardware cannot properly
* handle, an unfinshed fp_op exception will be generated.
* Software routines in the kernel will be executed to
* simulate proper handling of such conditions.
*
* Exception handling will emulate all instructions
* in the floating point address queue. Note that there
* is no %fq in sun4u, because it has precise FP traps.
*
* Floating point queues are now machine dependent, and std %fq
* is an illegal V9 instruction. The fp_exception code has been
* moved to sun4u/ml/machfloat.s.
*
* NOTE: This code DOES NOT SUPPORT KERNEL (DEVICE DRIVER)
* USE OF THE FPU
*
* Instructions for running without the hardware fpu:
* 1. Setting fpu_exists to 0 now only works on a DEBUG kernel.
* 2. adb -w unix and set fpu_exists, use_hw_bcopy, use_hw_copyio, and
* use_hw_bzero to 0 and rename libc_psr.so.1 in
* the libc bcopy routines. Then reboot the system and you
* should see the bootup message "FPU not in use".
* 3. To run kaos, you must comment out the code which sets the
* (unless you are running against a comparison system that
* has the same fsr version number).
* 4. The stqf{a}/ldqf{a} instructions cause kaos errors, for reasons
* that appear to be a kaos bug, so don't use them!
*/
#ifdef FP_DISABLED
int fpu_exists = 0;
#else
int fpu_exists = 1;
#endif
#else /* lint */
.section ".data"
.align 8
.word 0
#ifdef FP_DISABLED
.word 0
#else
#endif
.word -1
#endif /* lint */
/*
* FPU probe - read the %fsr and get fpu_version.
* Called from autoconf. If a %fq is created for
* future cpu versions, a fq_exists variable
* could be created by this function.
*/
/*ARGSUSED*/
void
fpu_probe(void)
{}
#else /* lint */
#endif /* lint */
/*
* fp_clearregs(fp)
* struct v9_fpu *fp;
*
* Initialization for the hardware fpu.
* Clear the fsr and initialize registers to NaN (-1)
* The caller (fp_disabled) is supposed to update the fprs
* so when the return to userland is made, the fpu is enabled.
*/
/*ARGSUSED*/
void
{}
#else /* lint */
#endif /* lint */
/*
* void _fp_read_pfreg(pf, n)
* uint32_t *pf; Old freg value.
* unsigned n; Want to read register n
*
* {
* *pf = %f[n];
* }
*
* void
* _fp_write_pfreg(pf, n)
* uint32_t *pf; New freg value.
* unsigned n; Want to write register n.
*
* {
* %f[n] = *pf;
* }
*/
/*ARGSUSED*/
void
{}
/*ARGSUSED*/
void
{}
#else /* lint */
ENTRY_NP(_fp_write_pfreg)
sll %o1, 3, %o1 ! Table entries are 8 bytes each.
set .ltable, %g1 ! g1 gets base of table.
jmp %g1 + %o1 ! Jump into table
.stable:
STOREFP(0)
STOREFP(1)
STOREFP(2)
STOREFP(3)
STOREFP(4)
STOREFP(5)
STOREFP(6)
STOREFP(7)
STOREFP(8)
STOREFP(9)
STOREFP(10)
STOREFP(11)
STOREFP(12)
STOREFP(13)
STOREFP(14)
STOREFP(15)
STOREFP(16)
STOREFP(17)
STOREFP(18)
STOREFP(19)
STOREFP(20)
STOREFP(21)
STOREFP(22)
STOREFP(23)
STOREFP(24)
STOREFP(25)
STOREFP(26)
STOREFP(27)
STOREFP(28)
STOREFP(29)
STOREFP(30)
STOREFP(31)
.ltable:
LOADFP(0)
LOADFP(1)
LOADFP(2)
LOADFP(3)
LOADFP(4)
LOADFP(5)
LOADFP(6)
LOADFP(7)
LOADFP(8)
LOADFP(9)
LOADFP(10)
LOADFP(11)
LOADFP(12)
LOADFP(13)
LOADFP(14)
LOADFP(15)
LOADFP(16)
LOADFP(17)
LOADFP(18)
LOADFP(19)
LOADFP(20)
LOADFP(21)
LOADFP(22)
LOADFP(23)
LOADFP(24)
LOADFP(25)
LOADFP(26)
LOADFP(27)
LOADFP(28)
LOADFP(29)
LOADFP(30)
LOADFP(31)
#endif /* lint */
/*
* void _fp_read_pdreg(
* uint64_t *pd, Old dreg value.
* u_int n) Want to read register n
*
* {
* *pd = %d[n];
* }
*
* void
* _fp_write_pdreg(
* uint64_t *pd, New dreg value.
* u_int n) Want to write register n.
*
* {
* %d[n] = *pd;
* }
*/
/*ARGSUSED*/
void
{}
/*ARGSUSED*/
void
{}
#else /* lint */
ENTRY_NP(_fp_write_pdreg)
sll %o1, 3, %o1 ! Table entries are 8 bytes each.
set .dltable, %g1 ! g1 gets base of table.
jmp %g1 + %o1 ! Jump into table
.dstable:
STOREDP(0)
STOREDP(2)
STOREDP(4)
STOREDP(6)
STOREDP(8)
STOREDP(10)
STOREDP(12)
STOREDP(14)
STOREDP(16)
STOREDP(18)
STOREDP(20)
STOREDP(22)
STOREDP(24)
STOREDP(26)
STOREDP(28)
STOREDP(30)
STOREDP(32)
STOREDP(34)
STOREDP(36)
STOREDP(38)
STOREDP(40)
STOREDP(42)
STOREDP(44)
STOREDP(46)
STOREDP(48)
STOREDP(50)
STOREDP(52)
STOREDP(54)
STOREDP(56)
STOREDP(58)
STOREDP(60)
STOREDP(62)
.dltable:
LOADDP(0)
LOADDP(2)
LOADDP(4)
LOADDP(6)
LOADDP(8)
LOADDP(10)
LOADDP(12)
LOADDP(14)
LOADDP(16)
LOADDP(18)
LOADDP(20)
LOADDP(22)
LOADDP(24)
LOADDP(26)
LOADDP(28)
LOADDP(30)
LOADDP(32)
LOADDP(34)
LOADDP(36)
LOADDP(38)
LOADDP(40)
LOADDP(42)
LOADDP(44)
LOADDP(46)
LOADDP(48)
LOADDP(50)
LOADDP(52)
LOADDP(54)
LOADDP(56)
LOADDP(58)
LOADDP(60)
LOADDP(62)
#endif /* lint */
/*ARGSUSED*/
void
{}
#else /* lint */
#endif /* lint */
/*ARGSUSED*/
void
{}
#else /* lint */
#endif /* lint */
/*ARGSUSED*/
void
{}
#else /* lint */
#endif /* lint */
unsigned
_fp_read_fprs(void)
{return 0;}
#else /* lint */
#endif /* lint */
unsigned
_fp_subcc_ccr(void)
{return 0;}
#else /* lint */
#endif /* lint */