1 /*---------------------------------------------------------------------------*
2   Project: Cafe
3   File:    OSFastCast.h
4 
5   Copyright (C) Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13  *---------------------------------------------------------------------------*/
14 
15 #ifndef __OSFASTCAST_H__
16 #define __OSFASTCAST_H__
17 
18 #ifndef _WIN32
19 
20 #ifndef _ASSEMBLER
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #include <ppc_ghs.h>
27 #include <ppc_ps.h>
28 #include "cafe/base/ppc_asm_user.h"
29 
30 #endif // _ASSEMBLER
31 
32 // GQR formats we use
33 #define OS_GQR_F32 0x0000
34 #define OS_GQR_U8  0x0004
35 #define OS_GQR_U16 0x0005
36 #define OS_GQR_S8  0x0006
37 #define OS_GQR_S16 0x0007
38 
39 // GQR scale factors
40 #define OS_GQR_SCALE_NONE   0
41 
42 #define OS_GQR_SCALE_2      1
43 #define OS_GQR_SCALE_4      2
44 #define OS_GQR_SCALE_8      3
45 #define OS_GQR_SCALE_16     4
46 #define OS_GQR_SCALE_32     5
47 #define OS_GQR_SCALE_64     6
48 #define OS_GQR_SCALE_128    7
49 #define OS_GQR_SCALE_256    8
50 #define OS_GQR_SCALE_512    9
51 #define OS_GQR_SCALE_1024   10
52 #define OS_GQR_SCALE_2048   11
53 #define OS_GQR_SCALE_4096   12
54 #define OS_GQR_SCALE_8192   13
55 #define OS_GQR_SCALE_16384  14
56 #define OS_GQR_SCALE_32768  15
57 #define OS_GQR_SCALE_65536  16
58 #define OS_GQR_SCALE_MAX    31
59 
60 #define OS_GQR_DIVIDE_2     63
61 #define OS_GQR_DIVIDE_4     62
62 #define OS_GQR_DIVIDE_8     61
63 #define OS_GQR_DIVIDE_16    60
64 #define OS_GQR_DIVIDE_32    59
65 #define OS_GQR_DIVIDE_64    58
66 #define OS_GQR_DIVIDE_128   57
67 #define OS_GQR_DIVIDE_256   56
68 #define OS_GQR_DIVIDE_512   55
69 #define OS_GQR_DIVIDE_1024  54
70 #define OS_GQR_DIVIDE_2048  53
71 #define OS_GQR_DIVIDE_4096  52
72 #define OS_GQR_DIVIDE_8192  51
73 #define OS_GQR_DIVIDE_16384 50
74 #define OS_GQR_DIVIDE_32768 49
75 #define OS_GQR_DIVIDE_65536 48
76 #define OS_GQR_DIVIDE_MAX   32
77 
78 
79 
80 // The GQRs that we use for FastCast.  Note that in the future, the compiler
81 // will reserve GQRs 0 and 1, so we avoid using GQR1.
82 #define OS_FASTCAST_U8  2
83 #define OS_FASTCAST_U16 3
84 #define OS_FASTCAST_S8  4
85 #define OS_FASTCAST_S16 5
86 
87 
88 // Function to set up GQRs.
89 #ifndef _ASSEMBLER
90 
OSInitFastCast(void)91 static inline void OSInitFastCast(void)
92 {
93     __MTSPR(UGQR2, (OS_GQR_U8  << 16) | OS_GQR_U8);
94     __MTSPR(UGQR3, (OS_GQR_U16 << 16) | OS_GQR_U16);
95     __MTSPR(UGQR4, (OS_GQR_S8  << 16) | OS_GQR_S8);
96     __MTSPR(UGQR5, (OS_GQR_S16 << 16) | OS_GQR_S16);
97 }
98 
OSSetGQR2(u32 type,u32 scale)99 static inline void OSSetGQR2( u32 type, u32 scale )
100 {
101     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
102 
103     __MTSPR(UGQR2, val);
104 }
105 
OSSetGQR3(u32 type,u32 scale)106 static inline void OSSetGQR3( u32 type, u32 scale )
107 {
108     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
109 
110     __MTSPR(UGQR3, val);
111 }
112 
OSSetGQR4(u32 type,u32 scale)113 static inline void OSSetGQR4( u32 type, u32 scale )
114 {
115     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
116 
117     __MTSPR(UGQR4, val);
118 }
119 
OSSetGQR5(u32 type,u32 scale)120 static inline void OSSetGQR5( u32 type, u32 scale )
121 {
122     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
123 
124     __MTSPR(UGQR5, val);
125 }
126 
OSSetGQR6(u32 type,u32 scale)127 static inline void OSSetGQR6( u32 type, u32 scale )
128 {
129     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
130 
131     __MTSPR(UGQR6, val);
132 }
133 
OSSetGQR7(u32 type,u32 scale)134 static inline void OSSetGQR7( u32 type, u32 scale )
135 {
136     u32 val = (((scale<<8)|type)<<16)|((scale<<8)|type);
137 
138     __MTSPR(UGQR7, val);
139 }
140 
141 /*---------------------------------------------------------------------------*
142   int to float
143  *---------------------------------------------------------------------------*/
OSu8tof32Value(const u8 * in)144 static inline f32 OSu8tof32Value(const u8* in)
145 {
146 	f32x2 f = __PSQ_L(in, 1, OS_FASTCAST_U8);
147 	return f[0];
148 }
149 
OSu8tof32(const u8 * in,volatile f32 * out)150 static inline void OSu8tof32(const u8* in, volatile f32* out)
151 {
152     *out = OSu8tof32Value(in);
153 }
154 
OSu16tof32Value(const u16 * in)155 static inline f32 OSu16tof32Value(const u16 * in)
156 {
157 	f32x2 f = __PSQ_L(in, 1, OS_FASTCAST_U16);
158 	return f[0];
159 }
160 
OSu16tof32(const u16 * in,volatile f32 * out)161 static inline void OSu16tof32(const u16* in, volatile f32* out)
162 {
163     *out = OSu16tof32Value(in);
164 }
165 
OSs8tof32Value(const s8 * in)166 static inline f32 OSs8tof32Value(const s8 * in)
167 {
168 	f32x2 f = __PSQ_L(in, 1, OS_FASTCAST_S8);
169 	return f[0];
170 }
171 
OSs8tof32(const s8 * in,volatile f32 * out)172 static inline void OSs8tof32(const s8* in, volatile f32* out)
173 {
174     *out = OSs8tof32Value(in);
175 }
176 
OSs16tof32Value(const s16 * in)177 static inline f32 OSs16tof32Value(const s16 * in)
178 {
179 	f32x2 f = __PSQ_L(in, 1, OS_FASTCAST_S16);
180 	return f[0];
181 }
182 
OSs16tof32(const s16 * in,volatile f32 * out)183 static inline void OSs16tof32(const s16* in, volatile f32* out)
184 {
185     *out = OSs16tof32Value(in);
186 }
187 
188 /*---------------------------------------------------------------------------*
189   float to int
190  *---------------------------------------------------------------------------*/
191 
OSf32tou8(const f32 * in,volatile u8 * out)192 static inline void OSf32tou8(const f32* in, volatile u8* out)
193 {
194 	f32x2 f = {*in};
195 	__PSQ_ST((void *) out, f, 1, OS_FASTCAST_U8);
196 }
197 
__OSf32tou8Value(const f32 in)198 static inline u8 __OSf32tou8Value(const f32 in)
199 {
200     u8 value;
201 	f32x2 f = {in};
202 	__PSQ_ST((void *) &value, f, 1, OS_FASTCAST_U8);
203     return value;
204 }
205 
OSf32tou16(const f32 * in,volatile u16 * out)206 static inline void OSf32tou16(const f32* in, volatile u16* out)
207 {
208 	f32x2 f = {*in};
209 	__PSQ_ST((void *) out, f, 1, OS_FASTCAST_U16);
210 }
211 
__OSf32tou16Value(const f32 in)212 static inline u16 __OSf32tou16Value(const f32 in)
213 {
214     u16 value;
215 	f32x2 f = {in};
216 	__PSQ_ST((void *) &value, f, 1, OS_FASTCAST_U16);
217     return value;
218 }
219 
OSf32tos8(const f32 * in,volatile s8 * out)220 static inline void OSf32tos8(const f32* in, volatile s8* out)
221 {
222 	f32x2 f = {*in};
223 	__PSQ_ST((void *) out, f, 1, OS_FASTCAST_S8);
224 }
225 
__OSf32tos8Value(const f32 in)226 static inline s8 __OSf32tos8Value(const f32 in)
227 {
228     s8 value;
229 	f32x2 f = {in};
230 	__PSQ_ST((void *) &value, f, 1, OS_FASTCAST_S8);
231     return value;
232 }
233 
OSf32tos16(const f32 * in,volatile s16 * out)234 static inline void OSf32tos16(const f32* in, volatile s16* out)
235 {
236 	f32x2 f = {*in};
237 	__PSQ_ST((void *) out, f, 1, OS_FASTCAST_S16);
238 }
239 
__OSf32tos16Value(const f32 in)240 static inline s16 __OSf32tos16Value(const f32 in)
241 {
242     s16 value;
243 	f32x2 f = {in};
244 	__PSQ_ST((void *) &value, f, 1, OS_FASTCAST_S16);
245     return value;
246 }
247 
248 #ifdef __cplusplus
249 }
250 #endif
251 #endif
252 
253 #endif // _ASSEMBLER
254 
255 #endif // _WIN32
256 
257