1 /*
2  * optimized mixing code for i386
3  */
4 
5 #define MIX_AREAS_16 mix_areas_16
6 #define MIX_AREAS_16_MMX mix_areas_16_mmx
7 #define MIX_AREAS_32 mix_areas_32
8 #define MIX_AREAS_24 mix_areas_24
9 #define MIX_AREAS_24_CMOV mix_areas_24_cmov
10 #define LOCK_PREFIX ""
11 #define XADD "addl"
12 #define XSUB "subl"
13 #include "pcm_dmix_i386.h"
14 #undef MIX_AREAS_16
15 #undef MIX_AREAS_16_MMX
16 #undef MIX_AREAS_32
17 #undef MIX_AREAS_24
18 #undef MIX_AREAS_24_CMOV
19 #undef LOCK_PREFIX
20 #undef XADD
21 #undef XSUB
22 
23 #define MIX_AREAS_16 remix_areas_16
24 #define MIX_AREAS_16_MMX remix_areas_16_mmx
25 #define MIX_AREAS_32 remix_areas_32
26 #define MIX_AREAS_24 remix_areas_24
27 #define MIX_AREAS_24_CMOV remix_areas_24_cmov
28 #define LOCK_PREFIX ""
29 #define XADD "subl"
30 #define XSUB "addl"
31 #include "pcm_dmix_i386.h"
32 #undef MIX_AREAS_16
33 #undef MIX_AREAS_16_MMX
34 #undef MIX_AREAS_32
35 #undef MIX_AREAS_24
36 #undef MIX_AREAS_24_CMOV
37 #undef LOCK_PREFIX
38 #undef XADD
39 #undef XSUB
40 
41 #define MIX_AREAS_16 mix_areas_16_smp
42 #define MIX_AREAS_16_MMX mix_areas_16_smp_mmx
43 #define MIX_AREAS_32 mix_areas_32_smp
44 #define MIX_AREAS_24 mix_areas_24_smp
45 #define MIX_AREAS_24_CMOV mix_areas_24_smp_cmov
46 #define LOCK_PREFIX "lock ; "
47 #define XADD "addl"
48 #define XSUB "subl"
49 #include "pcm_dmix_i386.h"
50 #undef MIX_AREAS_16
51 #undef MIX_AREAS_16_MMX
52 #undef MIX_AREAS_32
53 #undef MIX_AREAS_24
54 #undef MIX_AREAS_24_CMOV
55 #undef LOCK_PREFIX
56 #undef XADD
57 #undef XSUB
58 
59 #define MIX_AREAS_16 remix_areas_16_smp
60 #define MIX_AREAS_16_MMX remix_areas_16_smp_mmx
61 #define MIX_AREAS_32 remix_areas_32_smp
62 #define MIX_AREAS_24 remix_areas_24_smp
63 #define MIX_AREAS_24_CMOV remix_areas_24_smp_cmov
64 #define LOCK_PREFIX "lock ; "
65 #define XADD "subl"
66 #define XSUB "addl"
67 #include "pcm_dmix_i386.h"
68 #undef MIX_AREAS_16
69 #undef MIX_AREAS_16_MMX
70 #undef MIX_AREAS_32
71 #undef MIX_AREAS_24
72 #undef MIX_AREAS_24_CMOV
73 #undef LOCK_PREFIX
74 #undef XADD
75 #undef XSUB
76 
77 #define i386_dmix_supported_format \
78 	((1ULL << SND_PCM_FORMAT_S16_LE) |\
79 	 (1ULL << SND_PCM_FORMAT_S32_LE) |\
80 	 (1ULL << SND_PCM_FORMAT_S24_LE) |\
81 	 (1ULL << SND_PCM_FORMAT_S24_3LE))
82 
83 #define dmix_supported_format \
84 	(i386_dmix_supported_format | generic_dmix_supported_format)
85 
mix_select_callbacks(snd_pcm_direct_t * dmix)86 static void mix_select_callbacks(snd_pcm_direct_t *dmix)
87 {
88 	static int smp = 0, mmx = 0, cmov = 0;
89 
90 	if (!dmix->direct_memory_access) {
91 		generic_mix_select_callbacks(dmix);
92 		return;
93 	}
94 
95 	if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) {
96 		generic_mix_select_callbacks(dmix);
97 		return;
98 	}
99 
100 	if (!smp) {
101 		FILE *in;
102 		char line[255];
103 
104 		/* try to determine the capabilities of the CPU */
105 		in = fopen("/proc/cpuinfo", "r");
106 		if (in) {
107 			while (!feof(in)) {
108 				fgets(line, sizeof(line), in);
109 				if (!strncmp(line, "processor", 9))
110 					smp++;
111 				else if (!strncmp(line, "flags", 5)) {
112 					if (strstr(line, " mmx"))
113 						mmx = 1;
114 					if (strstr(line, " cmov"))
115 						cmov = 1;
116 				}
117 			}
118 			fclose(in);
119 		}
120 	}
121 
122 	if (mmx) {
123 		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp_mmx : mix_areas_16_mmx;
124 		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp_mmx : remix_areas_16_mmx;
125 	} else {
126 		dmix->u.dmix.mix_areas_16 = smp > 1 ? mix_areas_16_smp : mix_areas_16;
127 		dmix->u.dmix.remix_areas_16 = smp > 1 ? remix_areas_16_smp : remix_areas_16;
128 	}
129 	dmix->u.dmix.mix_areas_32 = smp > 1 ? mix_areas_32_smp : mix_areas_32;
130 	dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
131 	if (cmov) {
132 		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp_cmov : mix_areas_24_cmov;
133 		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp_cmov : remix_areas_24_cmov;
134 	} else {
135 		dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
136 		dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
137 	}
138 }
139