1 /*---------------------------------------------------------------------------*
2 Project: Cafe
3 File: OSFastCast.h
4
5 Copyright 1998-2011 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