1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/* Copyright (c) 1996 NeXT Software, Inc.  All rights reserved.
29 *
30 *	File:	architecture/ppc/fp_regs.h
31 *	Author:	Doug Mitchell, NeXT Software, Inc.
32 *
33 *	ppc floating point registers.
34 *
35 * HISTORY
36 * 29-Dec-96  Umesh Vaishampayan  (umeshv@NeXT.com)
37 *	Ported from m98k.
38 * 05-Nov-92  Doug Mitchell at NeXT
39 *	Created.
40 */
41
42#ifndef _ARCH_PPC_FP_REGS_H_
43#define _ARCH_PPC_FP_REGS_H_
44
45#include <architecture/ppc/reg_help.h>
46
47#if !defined(__ASSEMBLER__)
48/*
49 * Floating point status and control register.
50 *
51 * This struct is aligned to an 8-byte boundary because 64-bit
52 * load/store instructions (lfd/stfd) are used to access it. The
53 * FPSCR can only be read/written through other FP registers.
54 */
55typedef struct {
56        unsigned        unused[1] __attribute__(( aligned(8) ));
57	unsigned	fx:BIT_WIDTH(31),	// exception summary
58			fex:BIT_WIDTH(30),	// enabled exception summary
59			vx:BIT_WIDTH(29),	// invalid op exception
60						//    summary
61			ox:BIT_WIDTH(28),	// overflow exception
62			ux:BIT_WIDTH(27),	// underflow exception
63			zx:BIT_WIDTH(26),	// divide by zero exception
64			xx:BIT_WIDTH(25),	// inexact exception
65			vx_snan:BIT_WIDTH(24),	// not a number exception
66			vx_isi:BIT_WIDTH(23),	// exception
67			vx_idi:BIT_WIDTH(22),	// exception
68			vx_zdz:BIT_WIDTH(21),	// exception
69			vx_imz:BIT_WIDTH(20),	// exception
70			vx_xvc:BIT_WIDTH(19),	// exception
71			fr:BIT_WIDTH(18),	// fraction rounded
72			fi:BIT_WIDTH(17),	// fraction inexact
73			class:BIT_WIDTH(16),	// class descriptor
74			fl:BIT_WIDTH(15),	// negative
75			fg:BIT_WIDTH(14),	// positive
76			fe:BIT_WIDTH(13),	// equal or zero
77			fu:BIT_WIDTH(12),	// not a number
78			rsvd1:BIT_WIDTH(11),	// reserved
79			vx_soft:BIT_WIDTH(10),	// software request exception
80			rsvd2:BIT_WIDTH(9),	// reserved
81			vx_cvi:BIT_WIDTH(8),	// invalid integer convert
82						//    exception
83			ve:BIT_WIDTH(7),	// invalid op exception enable
84			oe:BIT_WIDTH(6),	// overflow exception enable
85			ue:BIT_WIDTH(5),	// underflow exception enable
86			ze:BIT_WIDTH(4),	// divide by zero exception
87						//    enable
88			xe:BIT_WIDTH(3),	// inexact exception enable
89			ni:BIT_WIDTH(2),	// non-IEEE exception enable
90			rn:BITS_WIDTH(1,0);	// rounding control
91} ppc_fp_scr_t;
92
93/*
94 * Values for fp_scr_t.rn (rounding control).
95 */
96typedef enum {
97	RN_NEAREST = 0,
98	RN_TOWARD_ZERO = 1,
99	RN_TOWARD_PLUS = 2,
100	RN_TOWARD_MINUS = 3
101} ppc_fp_rn_t;
102
103/*
104 * ppc_fpf_t -- data types that MAY be in floating point register file
105 * Actual data types supported is implementation dependent
106 */
107typedef union {
108        float           f;              // 32 bit IEEE single
109        double          d;              // 64 bit IEEE double
110
111        /*
112	 * Insure compiler aligns struct appropriately
113	 */
114        unsigned        x[2] __attribute__(( aligned(8) ));
115} ppc_fpf_t;
116
117/*
118 * Number of FP registers.
119 */
120#define PPC_NFP_REGS	32
121
122/*
123 * Read/write FPSCR.
124 * FIXME - these don't work, you need to go thru a fp register.
125 */
126typedef union {
127	double 		__dbl;
128	ppc_fp_scr_t 	__scr;
129} __fp_un_t;
130
131static __inline__ ppc_fp_scr_t
132get_fp_scr()
133{
134	__fp_un_t 	__fp_un;
135
136	__asm__ volatile ("mffs. %0           /* mffs */"	\
137	  	: "=f" (__fp_un.__dbl));
138	return (__fp_un.__scr);
139}
140
141static __inline__ void
142set_fp_scr(ppc_fp_scr_t fp_scr)
143{
144	__fp_un_t 	__fp_un;
145
146	__fp_un.__scr = fp_scr;
147	__asm__ volatile ("mtfsf 0xff, %0;    /* mtfsf */ "	\
148	  : : "f" (__fp_un.__dbl));
149}
150
151#endif /* ! __ASSEMBLER__ */
152
153#endif /* _ARCH_PPC_FP_REGS_H_ */
154