comparison src/video/mmx.h @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 450721ad5436
children f2c2f0ecba5f
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
41 /* The type of an value that fits in an MMX register 41 /* The type of an value that fits in an MMX register
42 (note that long long constant values MUST be suffixed 42 (note that long long constant values MUST be suffixed
43 by LL and unsigned long long values by ULL, lest 43 by LL and unsigned long long values by ULL, lest
44 they be truncated by the compiler) 44 they be truncated by the compiler)
45 */ 45 */
46 typedef union { 46 typedef union
47 long long q; /* Quadword (64-bit) value */ 47 {
48 unsigned long long uq; /* Unsigned Quadword */ 48 long long q; /* Quadword (64-bit) value */
49 int d[2]; /* 2 Doubleword (32-bit) values */ 49 unsigned long long uq; /* Unsigned Quadword */
50 unsigned int ud[2]; /* 2 Unsigned Doubleword */ 50 int d[2]; /* 2 Doubleword (32-bit) values */
51 short w[4]; /* 4 Word (16-bit) values */ 51 unsigned int ud[2]; /* 2 Unsigned Doubleword */
52 unsigned short uw[4]; /* 4 Unsigned Word */ 52 short w[4]; /* 4 Word (16-bit) values */
53 char b[8]; /* 8 Byte (8-bit) values */ 53 unsigned short uw[4]; /* 4 Unsigned Word */
54 unsigned char ub[8]; /* 8 Unsigned Byte */ 54 char b[8]; /* 8 Byte (8-bit) values */
55 float s[2]; /* Single-precision (32-bit) value */ 55 unsigned char ub[8]; /* 8 Unsigned Byte */
56 } __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */ 56 float s[2]; /* Single-precision (32-bit) value */
57 } __attribute__ ((aligned(8))) mmx_t; /* On an 8-byte (64-bit) boundary */
57 58
58 59
59 #if 0 60 #if 0
60 /* Function to test if multimedia instructions are supported... 61 /* Function to test if multimedia instructions are supported...
61 */ 62 */
62 inline extern int 63 inline extern int
63 mm_support(void) 64 mm_support(void)
64 { 65 {
65 /* Returns 1 if MMX instructions are supported, 66 /* Returns 1 if MMX instructions are supported,
66 3 if Cyrix MMX and Extended MMX instructions are supported 67 3 if Cyrix MMX and Extended MMX instructions are supported
67 5 if AMD MMX and 3DNow! instructions are supported 68 5 if AMD MMX and 3DNow! instructions are supported
68 0 if hardware does not support any of these 69 0 if hardware does not support any of these
69 */ 70 */
70 register int rval = 0; 71 register int rval = 0;
71 72
72 __asm__ __volatile__ ( 73 __asm__ __volatile__(
73 /* See if CPUID instruction is supported ... */ 74 /* See if CPUID instruction is supported ... */
74 /* ... Get copies of EFLAGS into eax and ecx */ 75 /* ... Get copies of EFLAGS into eax and ecx */
75 "pushf\n\t" 76 "pushf\n\t"
76 "popl %%eax\n\t" 77 "popl %%eax\n\t" "movl %%eax, %%ecx\n\t"
77 "movl %%eax, %%ecx\n\t" 78 /* ... Toggle the ID bit in one copy and store */
78 79 /* to the EFLAGS reg */
79 /* ... Toggle the ID bit in one copy and store */ 80 "xorl $0x200000, %%eax\n\t"
80 /* to the EFLAGS reg */ 81 "push %%eax\n\t" "popf\n\t"
81 "xorl $0x200000, %%eax\n\t" 82 /* ... Get the (hopefully modified) EFLAGS */
82 "push %%eax\n\t" 83 "pushf\n\t" "popl %%eax\n\t"
83 "popf\n\t" 84 /* ... Compare and test result */
84 85 "xorl %%eax, %%ecx\n\t" "testl $0x200000, %%ecx\n\t" "jz NotSupported1\n\t" /* CPUID not supported */
85 /* ... Get the (hopefully modified) EFLAGS */ 86 /* Get standard CPUID information, and
86 "pushf\n\t" 87 go to a specific vendor section */
87 "popl %%eax\n\t" 88 "movl $0, %%eax\n\t" "cpuid\n\t"
88 89 /* Check for Intel */
89 /* ... Compare and test result */ 90 "cmpl $0x756e6547, %%ebx\n\t"
90 "xorl %%eax, %%ecx\n\t" 91 "jne TryAMD\n\t"
91 "testl $0x200000, %%ecx\n\t" 92 "cmpl $0x49656e69, %%edx\n\t"
92 "jz NotSupported1\n\t" /* CPUID not supported */ 93 "jne TryAMD\n\t"
93 94 "cmpl $0x6c65746e, %%ecx\n"
94 95 "jne TryAMD\n\t" "jmp Intel\n\t"
95 /* Get standard CPUID information, and 96 /* Check for AMD */
96 go to a specific vendor section */ 97 "\nTryAMD:\n\t"
97 "movl $0, %%eax\n\t" 98 "cmpl $0x68747541, %%ebx\n\t"
98 "cpuid\n\t" 99 "jne TryCyrix\n\t"
99 100 "cmpl $0x69746e65, %%edx\n\t"
100 /* Check for Intel */ 101 "jne TryCyrix\n\t"
101 "cmpl $0x756e6547, %%ebx\n\t" 102 "cmpl $0x444d4163, %%ecx\n"
102 "jne TryAMD\n\t" 103 "jne TryCyrix\n\t" "jmp AMD\n\t"
103 "cmpl $0x49656e69, %%edx\n\t" 104 /* Check for Cyrix */
104 "jne TryAMD\n\t" 105 "\nTryCyrix:\n\t"
105 "cmpl $0x6c65746e, %%ecx\n" 106 "cmpl $0x69727943, %%ebx\n\t"
106 "jne TryAMD\n\t" 107 "jne NotSupported2\n\t"
107 "jmp Intel\n\t" 108 "cmpl $0x736e4978, %%edx\n\t"
108 109 "jne NotSupported3\n\t"
109 /* Check for AMD */ 110 "cmpl $0x64616574, %%ecx\n\t"
110 "\nTryAMD:\n\t" 111 "jne NotSupported4\n\t"
111 "cmpl $0x68747541, %%ebx\n\t" 112 /* Drop through to Cyrix... */
112 "jne TryCyrix\n\t" 113 /* Cyrix Section */
113 "cmpl $0x69746e65, %%edx\n\t" 114 /* See if extended CPUID level 80000001 is supported */
114 "jne TryCyrix\n\t" 115 /* The value of CPUID/80000001 for the 6x86MX is undefined
115 "cmpl $0x444d4163, %%ecx\n" 116 according to the Cyrix CPU Detection Guide (Preliminary
116 "jne TryCyrix\n\t" 117 Rev. 1.01 table 1), so we'll check the value of eax for
117 "jmp AMD\n\t" 118 CPUID/0 to see if standard CPUID level 2 is supported.
118 119 According to the table, the only CPU which supports level
119 /* Check for Cyrix */ 120 2 is also the only one which supports extended CPUID levels.
120 "\nTryCyrix:\n\t" 121 */
121 "cmpl $0x69727943, %%ebx\n\t" 122 "cmpl $0x2, %%eax\n\t" "jne MMXtest\n\t" /* Use standard CPUID instead */
122 "jne NotSupported2\n\t" 123 /* Extended CPUID supported (in theory), so get extended
123 "cmpl $0x736e4978, %%edx\n\t" 124 features */
124 "jne NotSupported3\n\t" 125 "movl $0x80000001, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%eax\n\t" /* Test for MMX */
125 "cmpl $0x64616574, %%ecx\n\t" 126 "jz NotSupported5\n\t" /* MMX not supported */
126 "jne NotSupported4\n\t" 127 "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
127 /* Drop through to Cyrix... */ 128 "jnz EMMXSupported\n\t" "movl $1, %0:\n\n\t" /* MMX Supported */
128 129 "jmp Return\n\n" "EMMXSupported:\n\t" "movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
129 130 "jmp Return\n\t"
130 /* Cyrix Section */ 131 /* AMD Section */
131 /* See if extended CPUID level 80000001 is supported */ 132 "AMD:\n\t"
132 /* The value of CPUID/80000001 for the 6x86MX is undefined 133 /* See if extended CPUID is supported */
133 according to the Cyrix CPU Detection Guide (Preliminary 134 "movl $0x80000000, %%eax\n\t" "cpuid\n\t" "cmpl $0x80000000, %%eax\n\t" "jl MMXtest\n\t" /* Use standard CPUID instead */
134 Rev. 1.01 table 1), so we'll check the value of eax for 135 /* Extended CPUID supported, so get extended features */
135 CPUID/0 to see if standard CPUID level 2 is supported. 136 "movl $0x80000001, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%edx\n\t" /* Test for MMX */
136 According to the table, the only CPU which supports level 137 "jz NotSupported6\n\t" /* MMX not supported */
137 2 is also the only one which supports extended CPUID levels. 138 "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
138 */ 139 "jnz ThreeDNowSupported\n\t" "movl $1, %0:\n\n\t" /* MMX Supported */
139 "cmpl $0x2, %%eax\n\t" 140 "jmp Return\n\n" "ThreeDNowSupported:\n\t" "movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
140 "jne MMXtest\n\t" /* Use standard CPUID instead */ 141 "jmp Return\n\t"
141 142 /* Intel Section */
142 /* Extended CPUID supported (in theory), so get extended 143 "Intel:\n\t"
143 features */ 144 /* Check for MMX */
144 "movl $0x80000001, %%eax\n\t" 145 "MMXtest:\n\t" "movl $1, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%edx\n\t" /* Test for MMX */
145 "cpuid\n\t" 146 "jz NotSupported7\n\t" /* MMX Not supported */
146 "testl $0x00800000, %%eax\n\t" /* Test for MMX */ 147 "movl $1, %0:\n\n\t" /* MMX Supported */
147 "jz NotSupported5\n\t" /* MMX not supported */ 148 "jmp Return\n\t"
148 "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */ 149 /* Nothing supported */
149 "jnz EMMXSupported\n\t" 150 "\nNotSupported1:\n\t" "#movl $101, %0:\n\n\t" "\nNotSupported2:\n\t" "#movl $102, %0:\n\n\t" "\nNotSupported3:\n\t" "#movl $103, %0:\n\n\t" "\nNotSupported4:\n\t" "#movl $104, %0:\n\n\t" "\nNotSupported5:\n\t" "#movl $105, %0:\n\n\t" "\nNotSupported6:\n\t" "#movl $106, %0:\n\n\t" "\nNotSupported7:\n\t" "#movl $107, %0:\n\n\t" "movl $0, %0:\n\n\t" "Return:\n\t":"=a"(rval): /* no input */
150 "movl $1, %0:\n\n\t" /* MMX Supported */ 151 :"eax", "ebx", "ecx", "edx");
151 "jmp Return\n\n" 152
152 "EMMXSupported:\n\t" 153 /* Return */
153 "movl $3, %0:\n\n\t" /* EMMX and MMX Supported */ 154 return (rval);
154 "jmp Return\n\t"
155
156
157 /* AMD Section */
158 "AMD:\n\t"
159
160 /* See if extended CPUID is supported */
161 "movl $0x80000000, %%eax\n\t"
162 "cpuid\n\t"
163 "cmpl $0x80000000, %%eax\n\t"
164 "jl MMXtest\n\t" /* Use standard CPUID instead */
165
166 /* Extended CPUID supported, so get extended features */
167 "movl $0x80000001, %%eax\n\t"
168 "cpuid\n\t"
169 "testl $0x00800000, %%edx\n\t" /* Test for MMX */
170 "jz NotSupported6\n\t" /* MMX not supported */
171 "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
172 "jnz ThreeDNowSupported\n\t"
173 "movl $1, %0:\n\n\t" /* MMX Supported */
174 "jmp Return\n\n"
175 "ThreeDNowSupported:\n\t"
176 "movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
177 "jmp Return\n\t"
178
179
180 /* Intel Section */
181 "Intel:\n\t"
182
183 /* Check for MMX */
184 "MMXtest:\n\t"
185 "movl $1, %%eax\n\t"
186 "cpuid\n\t"
187 "testl $0x00800000, %%edx\n\t" /* Test for MMX */
188 "jz NotSupported7\n\t" /* MMX Not supported */
189 "movl $1, %0:\n\n\t" /* MMX Supported */
190 "jmp Return\n\t"
191
192 /* Nothing supported */
193 "\nNotSupported1:\n\t"
194 "#movl $101, %0:\n\n\t"
195 "\nNotSupported2:\n\t"
196 "#movl $102, %0:\n\n\t"
197 "\nNotSupported3:\n\t"
198 "#movl $103, %0:\n\n\t"
199 "\nNotSupported4:\n\t"
200 "#movl $104, %0:\n\n\t"
201 "\nNotSupported5:\n\t"
202 "#movl $105, %0:\n\n\t"
203 "\nNotSupported6:\n\t"
204 "#movl $106, %0:\n\n\t"
205 "\nNotSupported7:\n\t"
206 "#movl $107, %0:\n\n\t"
207 "movl $0, %0:\n\n\t"
208
209 "Return:\n\t"
210 : "=a" (rval)
211 : /* no input */
212 : "eax", "ebx", "ecx", "edx"
213 );
214
215 /* Return */
216 return(rval);
217 } 155 }
218 156
219 /* Function to test if mmx instructions are supported... 157 /* Function to test if mmx instructions are supported...
220 */ 158 */
221 inline extern int 159 inline extern int
222 mmx_ok(void) 160 mmx_ok(void)
223 { 161 {
224 /* Returns 1 if MMX instructions are supported, 0 otherwise */ 162 /* Returns 1 if MMX instructions are supported, 0 otherwise */
225 return ( mm_support() & 0x1 ); 163 return (mm_support() & 0x1);
226 } 164 }
227 #endif 165 #endif
228 166
229 /* Helper functions for the instruction macros that follow... 167 /* Helper functions for the instruction macros that follow...
230 (note that memory-to-register, m2r, instructions are nearly 168 (note that memory-to-register, m2r, instructions are nearly
699 #define emms() __asm__ __volatile__ ("emms") 637 #define emms() __asm__ __volatile__ ("emms")
700 638
701 #endif 639 #endif
702 640
703 #endif 641 #endif
704 642 /* vi: set ts=4 sw=4 expandtab: */