KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
fmath_base.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/fmath_base.h
4 Copyright (C) 2001 Andrew Kieschnick
5 Copyright (C) 2014 Josh Pearson
6
7*/
8
9/**
10 \file dc/fmath_base.h
11 \brief Base definitions for the DC's special math instructions
12 \ingroup math_intrinsics
13
14 \author Andrew Kieschnick
15 \author Josh Pearson
16*/
17
18#ifndef __DC_FMATH_BASE_H
19#define __DC_FMATH_BASE_H
20
21#include <arch/args.h>
22
23#include <sys/cdefs.h>
24__BEGIN_DECLS
25
26
27/** \addtogroup math_intrinsics
28 @{
29*/
30
31/** \brief PI constant (if you don't want full math.h) */
32#define F_PI 3.1415926f
33
34/** \cond */
35#define __fsin(x) \
36 ({ float __value, __arg = (x), __scale = 10430.37835f; \
37 __asm__("fmul %2,%1\n\t" \
38 "ftrc %1,fpul\n\t" \
39 "fsca fpul,dr0\n\t" \
40 "fmov fr0,%0" \
41 : "=f" (__value), "+&f" (__scale) \
42 : "f" (__arg) \
43 : "fpul", "fr0", "fr1"); \
44 __value; })
45
46#define __fcos(x) \
47 ({ float __value, __arg = (x), __scale = 10430.37835f; \
48 __asm__("fmul %2,%1\n\t" \
49 "ftrc %1,fpul\n\t" \
50 "fsca fpul,dr0\n\t" \
51 "fmov fr1,%0" \
52 : "=f" (__value), "+&f" (__scale) \
53 : "f" (__arg) \
54 : "fpul", "fr0", "fr1"); \
55 __value; })
56
57#define __ftan(x) \
58 ({ float __value, __arg = (x), __scale = 10430.37835f; \
59 __asm__("fmul %2,%1\n\t" \
60 "ftrc %1,fpul\n\t" \
61 "fsca fpul,dr0\n\t" \
62 "fdiv fr1, fr0\n\t" \
63 "fmov fr0,%0" \
64 : "=f" (__value), "+&f" (__scale) \
65 : "f" (__arg) \
66 : "fpul", "fr0", "fr1"); \
67 __value; })
68
69
70#define __fisin(x) \
71 ({ float __value, __arg = (x); \
72 __asm__("lds %1,fpul\n\t" \
73 "fsca fpul,dr0\n\t" \
74 "fmov fr0,%0" \
75 : "=f" (__value) \
76 : "r" (__arg) \
77 : "fpul", "fr0", "fr1"); \
78 __value; })
79
80#define __ficos(x) \
81 ({ float __value, __arg = (x); \
82 __asm__("lds %1,fpul\n\t" \
83 "fsca fpul,dr0\n\t" \
84 "fmov fr1,%0" \
85 : "=f" (__value) \
86 : "r" (__arg) \
87 : "fpul", "fr0", "fr1"); \
88 __value; })
89
90#define __fitan(x) \
91 ({ float __value, __arg = (x); \
92 __asm__("lds %1,fpul\n\t" \
93 "fsca fpul,dr0\n\t" \
94 "fdiv fr1, fr0\n\t" \
95 "fmov fr0,%0" \
96 : "=f" (__value) \
97 : "r" (__arg) \
98 : "fpul", "fr0", "fr1"); \
99 __value; })
100
101#define __fsincos(r, s, c) \
102 ({ register float __r __asm__("fr10") = r; \
103 register float __a __asm__("fr11") = 182.04444443f; \
104 __asm__("fmul fr11, fr10\n\t" \
105 "ftrc fr10, fpul\n\t" \
106 "fsca fpul, dr10\n\t" \
107 : "+f" (__r), "+f" (__a) \
108 : "0" (__r), "1" (__a) \
109 : "fpul"); \
110 s = __r; c = __a; })
111
112#define __fsincosr(r, s, c) \
113 ({ register float __r __asm__("fr10") = r; \
114 register float __a __asm__("fr11") = 10430.37835f; \
115 __asm__("fmul fr11, fr10\n\t" \
116 "ftrc fr10, fpul\n\t" \
117 "fsca fpul, dr10\n\t" \
118 : "+f" (__r), "+f" (__a) \
119 : "0" (__r), "1" (__a) \
120 : "fpul"); \
121 s = __r; c = __a; })
122
123#define __fsqrt(x) \
124 ({ float __arg = (x); \
125 __asm__("fsqrt %0\n\t" \
126 : "=f" (__arg) : "0" (__arg)); \
127 __arg; })
128
129#define __frsqrt(x) \
130 ({ float __arg = (x); \
131 __asm__("fsrra %0\n\t" \
132 : "=f" (__arg) : "0" (__arg)); \
133 __arg; })
134
135/* Floating point inner product (dot product) */
136#define __fipr(x, y, z, w, a, b, c, d) ({ \
137 register float __x __asm__(KOS_FPARG(0)) = (x); \
138 register float __y __asm__(KOS_FPARG(1)) = (y); \
139 register float __z __asm__(KOS_FPARG(2)) = (z); \
140 register float __w __asm__(KOS_FPARG(3)) = (w); \
141 register float __a __asm__(KOS_FPARG(4)) = (a); \
142 register float __b __asm__(KOS_FPARG(5)) = (b); \
143 register float __c __asm__(KOS_FPARG(6)) = (c); \
144 register float __d __asm__(KOS_FPARG(7)) = (d); \
145 __asm__ __volatile__( \
146 "fipr fv8,fv4" \
147 : "+f" (KOS_SH4_SINGLE_ONLY ? __w : __z) \
148 : "f" (__x), "f" (__y), "f" (__z), "f" (__w), \
149 "f" (__a), "f" (__b), "f" (__c), "f" (__d) \
150 ); \
151 KOS_SH4_SINGLE_ONLY ? __w : __z; })
152
153/* Floating point inner product w/self (square of vector magnitude) */
154#define __fipr_magnitude_sqr(x, y, z, w) ({ \
155 register float __x __asm__(KOS_FPARG(0)) = (x); \
156 register float __y __asm__(KOS_FPARG(1)) = (y); \
157 register float __z __asm__(KOS_FPARG(2)) = (z); \
158 register float __w __asm__(KOS_FPARG(3)) = (w); \
159 __asm__ __volatile__( \
160 "fipr fv4,fv4" \
161 : "+f" (KOS_SH4_SINGLE_ONLY ? __w : __z) \
162 : "f" (__x), "f" (__y), "f" (__z), "f" (__w) \
163 ); \
164 KOS_SH4_SINGLE_ONLY ? __w : __z; })
165
166/** \endcond */
167
168/** @} */
169
170__END_DECLS
171
172#endif /* !__DC_FMATH_BASE_H */
Macros for getting argument registers in inline assembly.