Header file clean-up:
[mesa.git] / src / mesa / tnl / t_vtx_x86.c
1 /* $XFree86$ */
2 /**************************************************************************
3
4 Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Keith Whitwell <keith@tungstengraphics.com>
32 */
33
34 #include "imports.h"
35 #include "mmath.h"
36 #include "simple_list.h"
37 #include "tnl_vtxfmt.h"
38
39 #if defined(USE_X86_ASM)
40
41
42 struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key )
43 {
44 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
45
46 if (RADEON_DEBUG & DEBUG_CODEGEN)
47 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
48
49 switch (tnl->vertex_size) {
50 default: {
51 /* Repz convenient as it's possible to emit code for any size
52 * vertex with little tweaking. Might as well read vertsize
53 * though, and have only one of these.
54 */
55 static char temp[] = {
56 0x57, /* push %edi */
57 0x56, /* push %esi */
58 0xbe, 0, 0, 0, 0, /* mov $VERTEX+2,%esi */
59 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
60 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */
61 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */
62 0x89, 0x07, /* mov %eax,(%edi) */
63 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
64 0x83, 0xc7, 0x08, /* add $0x8,%edi */
65 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-2,%ecx */
66 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
67 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
68 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
69 0x48, /* dec %eax */
70 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
71 0x5e, /* pop %esi */
72 0x5f, /* pop %edi */
73 0x74, 0x01, /* je +1 */
74 0xc3, /* ret */
75 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
76 };
77
78 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
79 memcpy (dfn->code, temp, sizeof(temp));
80 FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]);
81 FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
82 FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2);
83 FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
84 FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
85 FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
86 FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
87 break;
88 }
89 }
90
91 insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
92 dfn->key = key;
93 return dfn;
94 }
95
96 /* Build specialized versions of the immediate calls on the fly for
97 * the current state. Generic x86 versions.
98 */
99
100 struct dynfn *tnl_makeX86Vertex3f( TNLcontext *tnl, int key )
101 {
102 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
103
104 if (RADEON_DEBUG & DEBUG_CODEGEN)
105 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
106
107 switch (tnl->vertex_size) {
108 case 4: {
109 static char temp[] = {
110 0x8b, 0x0d, 0,0,0,0, /* mov DMAPTR,%ecx */
111 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
112 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
113 0x89, 0x01, /* mov %eax,(%ecx) */
114 0x89, 0x51, 0x04, /* mov %edx,0x4(%ecx) */
115 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
116 0x8b, 0x15, 0,0,0,0, /* mov VERTEX[3],%edx */
117 0x89, 0x41, 0x08, /* mov %eax,0x8(%ecx) */
118 0x89, 0x51, 0x0c, /* mov %edx,0xc(%ecx) */
119 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
120 0x83, 0xc1, 0x10, /* add $0x10,%ecx */
121 0x48, /* dec %eax */
122 0x89, 0x0d, 0,0,0,0, /* mov %ecx,DMAPTR */
123 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
124 0x74, 0x01, /* je +1 */
125 0xc3, /* ret */
126 0xff, 0x25, 0,0,0,0 /* jmp *NOTIFY */
127 };
128
129 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
130 memcpy (dfn->code, temp, sizeof(temp));
131 FIXUP(dfn->code, 2, 0x0, (int)&tnl->dmaptr);
132 FIXUP(dfn->code, 25, 0x0, (int)&tnl->vertex[3]);
133 FIXUP(dfn->code, 36, 0x0, (int)&tnl->counter);
134 FIXUP(dfn->code, 46, 0x0, (int)&tnl->dmaptr);
135 FIXUP(dfn->code, 51, 0x0, (int)&tnl->counter);
136 FIXUP(dfn->code, 60, 0x0, (int)&tnl->notify);
137 break;
138 }
139 case 6: {
140 static char temp[] = {
141 0x57, /* push %edi */
142 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
143 0x8b, 0x44, 0x24, 0x8, /* mov 0x8(%esp,1),%eax */
144 0x8b, 0x54, 0x24, 0xc, /* mov 0xc(%esp,1),%edx */
145 0x8b, 0x4c, 0x24, 0x10, /* mov 0x10(%esp,1),%ecx */
146 0x89, 0x07, /* mov %eax,(%edi) */
147 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
148 0x89, 0x4f, 0x08, /* mov %ecx,0x8(%edi) */
149 0xa1, 0, 0, 0, 0, /* mov VERTEX[3],%eax */
150 0x8b, 0x15, 0, 0, 0, 0, /* mov VERTEX[4],%edx */
151 0x8b, 0x0d, 0, 0, 0, 0, /* mov VERTEX[5],%ecx */
152 0x89, 0x47, 0x0c, /* mov %eax,0xc(%edi) */
153 0x89, 0x57, 0x10, /* mov %edx,0x10(%edi) */
154 0x89, 0x4f, 0x14, /* mov %ecx,0x14(%edi) */
155 0x83, 0xc7, 0x18, /* add $0x18,%edi */
156 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
157 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
158 0x48, /* dec %eax */
159 0x5f, /* pop %edi */
160 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
161 0x74, 0x01, /* je +1 */
162 0xc3, /* ret */
163 0xff, 0x25, 0,0,0,0, /* jmp *NOTIFY */
164 };
165
166 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
167 memcpy (dfn->code, temp, sizeof(temp));
168 FIXUP(dfn->code, 3, 0x0, (int)&tnl->dmaptr);
169 FIXUP(dfn->code, 28, 0x0, (int)&tnl->vertex[3]);
170 FIXUP(dfn->code, 34, 0x0, (int)&tnl->vertex[4]);
171 FIXUP(dfn->code, 40, 0x0, (int)&tnl->vertex[5]);
172 FIXUP(dfn->code, 57, 0x0, (int)&tnl->counter);
173 FIXUP(dfn->code, 63, 0x0, (int)&tnl->dmaptr);
174 FIXUP(dfn->code, 70, 0x0, (int)&tnl->counter);
175 FIXUP(dfn->code, 79, 0x0, (int)&tnl->notify);
176 break;
177 }
178 default: {
179 /* Repz convenient as it's possible to emit code for any size
180 * vertex with little tweaking. Might as well read vertsize
181 * though, and have only one of these.
182 */
183 static char temp[] = {
184 0x57, /* push %edi */
185 0x56, /* push %esi */
186 0xbe, 0, 0, 0, 0, /* mov $VERTEX+3,%esi */
187 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
188 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */
189 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */
190 0x8b, 0x4c, 0x24, 0x14, /* mov 0x14(%esp,1),%ecx */
191 0x89, 0x07, /* mov %eax,(%edi) */
192 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
193 0x89, 0x4f, 0x08, /* mov %ecx,0x8(%edi) */
194 0x83, 0xc7, 0x0c, /* add $0xc,%edi */
195 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-3,%ecx */
196 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
197 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
198 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
199 0x48, /* dec %eax */
200 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
201 0x5e, /* pop %esi */
202 0x5f, /* pop %edi */
203 0x74, 0x01, /* je +1 */
204 0xc3, /* ret */
205 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
206 };
207
208 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
209 memcpy (dfn->code, temp, sizeof(temp));
210 FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[3]);
211 FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
212 FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-3);
213 FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
214 FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
215 FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
216 FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
217 break;
218 }
219 }
220
221 insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
222 dfn->key = key;
223 return dfn;
224 }
225
226
227
228 struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key )
229 {
230 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
231
232 if (TNL_DEBUG & DEBUG_CODEGEN)
233 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
234
235 switch (tnl->vertex_size) {
236 case 6: {
237 static char temp[] = {
238 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */
239 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */
240 0x8b, 0x11, /* mov (%ecx),%edx */
241 0x89, 0x10, /* mov %edx,(%eax) */
242 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */
243 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */
244 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */
245 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */
246 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
247 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
248 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */
249 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */
250 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */
251 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */
252 0x83, 0xc0, 0x18, /* add $0x18,%eax */
253 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */
254 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */
255 0x48, /* dec %eax */
256 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
257 0x74, 0x01, /* je 2a4 <.f11> */
258 0xc3, /* ret */
259 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
260 };
261
262 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
263 memcpy (dfn->code, temp, sizeof(temp));
264 FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr);
265 FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]);
266 FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]);
267 FIXUP(dfn->code, 45, 0x00000024, (int)&tnl->vertex[5]);
268 FIXUP(dfn->code, 56, 0x00000000, (int)&tnl->dmaptr);
269 FIXUP(dfn->code, 61, 0x00000004, (int)&tnl->counter);
270 FIXUP(dfn->code, 67, 0x00000004, (int)&tnl->counter);
271 FIXUP(dfn->code, 76, 0x00000008, (int)&tnl->notify);
272 break;
273 }
274
275
276 case 8: {
277 static char temp[] = {
278 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */
279 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */
280 0x8b, 0x11, /* mov (%ecx),%edx */
281 0x89, 0x10, /* mov %edx,(%eax) */
282 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */
283 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */
284 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */
285 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */
286 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
287 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
288 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */
289 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */
290 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
291 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
292 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */
293 0x89, 0x48, 0x18, /* mov %ecx,0x18(%eax) */
294 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */
295 0x89, 0x50, 0x1c, /* mov %edx,0x1c(%eax) */
296 0x83, 0xc0, 0x20, /* add $0x20,%eax */
297 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */
298 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */
299 0x48, /* dec %eax */
300 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
301 0x74, 0x01, /* je 2a4 <.f11> */
302 0xc3, /* ret */
303 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
304 };
305
306 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
307 memcpy (dfn->code, temp, sizeof(temp));
308 FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr);
309 FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]);
310 FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]);
311 FIXUP(dfn->code, 45, 0x0000001c, (int)&tnl->vertex[5]);
312 FIXUP(dfn->code, 51, 0x00000020, (int)&tnl->vertex[6]);
313 FIXUP(dfn->code, 63, 0x00000024, (int)&tnl->vertex[7]);
314 FIXUP(dfn->code, 74, 0x00000000, (int)&tnl->dmaptr);
315 FIXUP(dfn->code, 79, 0x00000004, (int)&tnl->counter);
316 FIXUP(dfn->code, 85, 0x00000004, (int)&tnl->counter);
317 FIXUP(dfn->code, 94, 0x00000008, (int)&tnl->notify);
318 break;
319 }
320
321
322
323 default: {
324 /* Repz convenient as it's possible to emit code for any size
325 * vertex with little tweaking. Might as well read vertsize
326 * though, and have only one of these.
327 */
328 static char temp[] = {
329 0x8b, 0x54, 0x24, 0x04, /* mov 0x4(%esp,1),%edx */
330 0x57, /* push %edi */
331 0x56, /* push %esi */
332 0x8b, 0x3d, 1,1,1,1, /* mov DMAPTR,%edi */
333 0x8b, 0x02, /* mov (%edx),%eax */
334 0x8b, 0x4a, 0x04, /* mov 0x4(%edx),%ecx */
335 0x8b, 0x72, 0x08, /* mov 0x8(%edx),%esi */
336 0x89, 0x07, /* mov %eax,(%edi) */
337 0x89, 0x4f, 0x04, /* mov %ecx,0x4(%edi) */
338 0x89, 0x77, 0x08, /* mov %esi,0x8(%edi) */
339 0x83, 0xc7, 0x0c, /* add $0xc,%edi */
340 0xb9, 0x06, 0x00, 0x00, 0x00, /* mov $VERTSIZE-3,%ecx */
341 0xbe, 0x58, 0x00, 0x00, 0x00, /* mov $VERTEX[3],%esi */
342 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
343 0x89, 0x3d, 1, 1, 1, 1, /* mov %edi,DMAPTR */
344 0xa1, 2, 2, 2, 2, /* mov COUNTER,%eax */
345 0x5e, /* pop %esi */
346 0x5f, /* pop %edi */
347 0x48, /* dec %eax */
348 0xa3, 2, 2, 2, 2, /* mov %eax,COUNTER */
349 0x74, 0x01, /* je +1 */
350 0xc3, /* ret */
351 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
352 };
353
354 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
355 memcpy (dfn->code, temp, sizeof(temp));
356 FIXUP(dfn->code, 8, 0x01010101, (int)&tnl->dmaptr);
357 FIXUP(dfn->code, 32, 0x00000006, tnl->vertex_size-3);
358 FIXUP(dfn->code, 37, 0x00000058, (int)&tnl->vertex[3]);
359 FIXUP(dfn->code, 45, 0x01010101, (int)&tnl->dmaptr);
360 FIXUP(dfn->code, 50, 0x02020202, (int)&tnl->counter);
361 FIXUP(dfn->code, 58, 0x02020202, (int)&tnl->counter);
362 FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
363 break;
364 }
365 }
366
367 insert_at_head( &tnl->dfn_cache.Vertex3fv, dfn );
368 dfn->key = key;
369 return dfn;
370 }
371
372
373 struct dynfn *tnl_makeX86Attr4fv( TNLcontext *tnl, int key )
374 {
375 static char temp[] = {
376 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
377 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
378 0x8b, 0x08, /* mov (%eax),%ecx */
379 0x89, 0x0a, /* mov %ecx,(%edx) */
380 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
381 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
382 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
383 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
384 0x8b, 0x48, 0x0a, /* mov 0xa(%eax),%ecx */
385 0x89, 0x4a, 0x0a, /* mov %ecx,0xa(%edx) */
386 0xc3, /* ret */
387 };
388
389 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
390
391 if (TNL_DEBUG & DEBUG_CODEGEN)
392 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
393
394 insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
395 dfn->key = key;
396 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
397 memcpy (dfn->code, temp, sizeof(temp));
398 FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr);
399 return dfn;
400 }
401
402 struct dynfn *tnl_makeX86Attr4f( TNLcontext *tnl, int key )
403 {
404 static char temp[] = {
405 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
406 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
407 0x89, 0x02, /* mov %eax,(%edx) */
408 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
409 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
410 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
411 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
412 0x8b, 0x44, 0x24, 0x10, /* mov 0x10(%esp,1),%eax */
413 0x89, 0x42, 0x0a, /* mov %eax,0xa(%edx) */
414 0xc3, /* ret */
415 };
416
417 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
418
419 if (TNL_DEBUG & DEBUG_CODEGEN)
420 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
421
422 insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
423 dfn->key = key;
424 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
425 memcpy (dfn->code, temp, sizeof(temp));
426 FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr);
427 return dfn;
428 }
429
430
431 struct dynfn *tnl_makeX86Attr3fv( TNLcontext *tnl, int key )
432 {
433 static char temp[] = {
434 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
435 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
436 0x8b, 0x08, /* mov (%eax),%ecx */
437 0x89, 0x0a, /* mov %ecx,(%edx) */
438 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
439 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
440 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
441 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
442 0xc3, /* ret */
443 };
444
445 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
446
447 if (TNL_DEBUG & DEBUG_CODEGEN)
448 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
449
450 insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
451 dfn->key = key;
452 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
453 memcpy (dfn->code, temp, sizeof(temp));
454 FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr);
455 return dfn;
456 }
457
458 struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key )
459 {
460 static char temp[] = {
461 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
462 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
463 0x89, 0x02, /* mov %eax,(%edx) */
464 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
465 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
466 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
467 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
468 0xc3, /* ret */
469 };
470
471 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
472
473 if (TNL_DEBUG & DEBUG_CODEGEN)
474 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
475
476 insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
477 dfn->key = key;
478 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
479 memcpy (dfn->code, temp, sizeof(temp));
480 FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr);
481 return dfn;
482 }
483
484 struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key )
485 {
486 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
487 insert_at_head( &tnl->dfn_cache.Color4ubv, dfn );
488 dfn->key = key;
489
490 if (TNL_DEBUG & DEBUG_CODEGEN)
491 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
492
493 if (key & TNL_CP_VC_FRMT_PKCOLOR) {
494 static char temp[] = {
495 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
496 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
497 0x8b, 0x00, /* mov (%eax),%eax */
498 0x89, 0x02, /* mov %eax,(%edx) */
499 0xc3, /* ret */
500 };
501
502 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
503 memcpy (dfn->code, temp, sizeof(temp));
504 FIXUP(dfn->code, 5, 0x12345678, (int)tnl->ubytecolorptr);
505 return dfn;
506 }
507 else {
508 static char temp[] = {
509 0x53, /* push %ebx */
510 0xba, 0x00, 0x00, 0x00, 0x00, /* mov $0x0,%edx */
511 0x31, 0xc0, /* xor %eax,%eax */
512 0x31, 0xc9, /* xor %ecx,%ecx */
513 0x8b, 0x5c, 0x24, 0x08, /* mov 0x8(%esp,1), %ebx */
514 0x8b, 0x1b, /* mov (%ebx), %ebx */
515 0x88, 0xd8, /* mov %bl, %al */
516 0x88, 0xf9, /* mov %bh, %cl */
517 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */
518 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */
519 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */
520 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */
521 0x31, 0xc0, /* xor %eax,%eax */
522 0x31, 0xc9, /* xor %ecx,%ecx */
523 0xc1, 0xeb, 0x10, /* shr $0x10, %ebx */
524 0x88, 0xd8, /* mov %bl, %al */
525 0x88, 0xf9, /* mov %bh, %cl */
526 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */
527 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */
528 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */
529 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */
530 0x5b, /* pop %ebx */
531 0xc3, /* ret */
532 };
533
534 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
535 memcpy (dfn->code, temp, sizeof(temp));
536 FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
537 FIXUP(dfn->code, 27, 0xdeadbeaf, (int)tnl->floatcolorptr);
538 FIXUP(dfn->code, 33, 0xdeadbeaf, (int)tnl->floatcolorptr+4);
539 FIXUP(dfn->code, 55, 0xdeadbeaf, (int)tnl->floatcolorptr+8);
540 FIXUP(dfn->code, 61, 0xdeadbeaf, (int)tnl->floatcolorptr+12);
541 return dfn;
542 }
543 }
544
545 struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key )
546 {
547 if (TNL_DEBUG & DEBUG_CODEGEN)
548 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
549
550 if (key & TNL_CP_VC_FRMT_PKCOLOR) {
551 /* XXX push/pop */
552 static char temp[] = {
553 0x53, /* push %ebx */
554 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
555 0x8b, 0x54, 0x24, 0x0c, /* mov 0xc(%esp,1),%edx */
556 0x8b, 0x4c, 0x24, 0x10, /* mov 0x10(%esp,1),%ecx */
557 0x8b, 0x5c, 0x24, 0x14, /* mov 0x14(%esp,1),%ebx */
558 0xa2, 0, 0, 0, 0, /* mov %al,DEST */
559 0x88, 0x15, 0, 0, 0, 0, /* mov %dl,DEST+1 */
560 0x88, 0x0d, 0, 0, 0, 0, /* mov %cl,DEST+2 */
561 0x88, 0x1d, 0, 0, 0, 0, /* mov %bl,DEST+3 */
562 0x5b, /* pop %ebx */
563 0xc3, /* ret */
564 };
565
566 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
567 insert_at_head( &tnl->dfn_cache.Color4ub, dfn );
568 dfn->key = key;
569
570 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
571 memcpy (dfn->code, temp, sizeof(temp));
572 FIXUP(dfn->code, 18, 0x0, (int)tnl->ubytecolorptr);
573 FIXUP(dfn->code, 24, 0x0, (int)tnl->ubytecolorptr+1);
574 FIXUP(dfn->code, 30, 0x0, (int)tnl->ubytecolorptr+2);
575 FIXUP(dfn->code, 36, 0x0, (int)tnl->ubytecolorptr+3);
576 return dfn;
577 }
578 else
579 return 0;
580 }
581
582
583
584 struct dynfn *tnl_makeX86Attr2fv( TNLcontext *tnl, int key )
585 {
586 static char temp[] = {
587 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
588 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
589 0x8b, 0x08, /* mov (%eax),%ecx */
590 0x8b, 0x40, 0x04, /* mov 0x4(%eax),%eax */
591 0x89, 0x0a, /* mov %ecx,(%edx) */
592 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
593 0xc3, /* ret */
594 };
595
596 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
597
598 if (TNL_DEBUG & DEBUG_CODEGEN)
599 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
600
601 insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
602 dfn->key = key;
603 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
604 memcpy (dfn->code, temp, sizeof(temp));
605 FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]);
606 return dfn;
607 }
608
609 struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key )
610 {
611 static char temp[] = {
612 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
613 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
614 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
615 0x89, 0x02, /* mov %eax,(%edx) */
616 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
617 0xc3, /* ret */
618 };
619
620 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
621
622 if (TNL_DEBUG & DEBUG_CODEGEN)
623 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
624
625 insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
626 dfn->key = key;
627 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
628 memcpy (dfn->code, temp, sizeof(temp));
629 FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]);
630 return dfn;
631 }
632
633
634 struct dynfn *tnl_makeX86Attr1fv( TNLcontext *tnl, int key )
635 {
636 static char temp[] = {
637 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
638 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
639 0x8b, 0x08, /* mov (%eax),%ecx */
640 0x89, 0x0a, /* mov %ecx,(%edx) */
641 0xc3, /* ret */
642 };
643
644 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
645
646 if (TNL_DEBUG & DEBUG_CODEGEN)
647 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
648
649 insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
650 dfn->key = key;
651 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
652 memcpy (dfn->code, temp, sizeof(temp));
653 FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]);
654 return dfn;
655 }
656
657 struct dynfn *tnl_makeX86Attr1f( TNLcontext *tnl, int key )
658 {
659 static char temp[] = {
660 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
661 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
662 0x89, 0x02, /* mov %eax,(%edx) */
663 0xc3, /* ret */
664 };
665
666 struct dynfn *dfn = MALLOC_STRUCT( dynfn );
667
668 if (TNL_DEBUG & DEBUG_CODEGEN)
669 _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
670
671 insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
672 dfn->key = key;
673 dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
674 memcpy (dfn->code, temp, sizeof(temp));
675 FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]);
676 return dfn;
677 }
678
679
680
681 void _tnl_InitX86Codegen( struct dfn_generators *gen )
682 {
683 gen->Attr1f = tnl_makeX86Attr1f;
684 gen->Attr1fv = tnl_makeX86Attr1fv;
685 gen->Attr2f = tnl_makeX86Attr2f;
686 gen->Attr2fv = tnl_makeX86Attr2fv;
687 gen->Attr3f = tnl_makeX86Attr3f;
688 gen->Attr3fv = tnl_makeX86Attr3fv;
689 gen->Attr4f = tnl_makeX86Attr4f;
690 gen->Attr4fv = tnl_makeX86Attr4fv;
691 gen->Attr4ub = tnl_makeX86Attr4ub;
692 gen->Attr4ubv = tnl_makeX86Attr4ubv;
693 gen->Vertex3f = tnl_makeX86Vertex3f;
694 gen->Vertex3fv = tnl_makeX86Vertex3fv;
695 }
696
697
698 #else
699
700 void _tnl_InitX86Codegen( struct dfn_generators *gen )
701 {
702 (void) gen;
703 }
704
705 #endif