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