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