1 /* Copyright 2001-4 tim goetze <tim@quitte.de> -- see 'COPYING'. */
2 
3 /* Sets the FP rounding mode to 'truncate' in the constructor
4  * and loads the previous FP conrol word in the destructor.
5  *
6  * By directly using the machine instruction to convert float to int
7  * we avoid the performance hit that loading the control word twice for
8  * every (int) cast causes on i386.
9  *
10  * On other architectures this is a no-op.
11  */
12 
13 #ifndef _DSP_FP_TRUNCATE_MODE_H_
14 #define _DSP_FP_TRUNCATE_MODE_H_
15 
16 #ifdef __i386__
17 	#define fstcw(i) \
18 		__asm__ __volatile__ ("fstcw %0" : "=m" (i))
19 
20 	#define fldcw(i) \
21 		__asm__ __volatile__ ("fldcw %0" : : "m" (i))
22 
23 	/* gcc chokes on __volatile__ sometimes. */
24 	#define fistp(f,i) \
25 		__asm__ ("fistpl %0" : "=m" (i) : "t" (f) : "st")
26 #else /* ! __i386__ */
27 	#define fstcw(i)
28 	#define fldcw(i)
29 
30 	#define fistp(f,i) \
31 			i = (int) f
32 #endif
33 
34 namespace DSP {
35 
36 class FPTruncateMode
37 {
38 	public:
39 		int cw0, cw1; /* fp control word */
40 
FPTruncateMode()41 		FPTruncateMode()
42 			{
43 				fstcw (cw0);
44 				cw1 = cw0 | 0xC00;
45 				fldcw (cw1);
46 			}
47 
~FPTruncateMode()48 		~FPTruncateMode()
49 			{
50 				fldcw (cw0);
51 			}
52 };
53 
54 } /* namespace DSP */
55 
56 #endif /* _DSP_FP_TRUNCATE_MODE_H_ */
57