2 /**************************************************************************
4 Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
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:
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
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.
27 **************************************************************************/
31 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "simple_list.h"
39 #include "tnl_vtxfmt.h"
41 #if defined(USE_X86_ASM)
43 /* Build specialized versions of the immediate calls on the fly for
44 * the current state. Generic x86 versions.
47 struct dynfn
*tnl_makeX86Vertex3f( TNLcontext
*tnl
, int key
)
49 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
51 if (RADEON_DEBUG
& DEBUG_CODEGEN
)
52 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
54 switch (tnl
->vertex_size
) {
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 */
69 0x89, 0x0d, 0,0,0,0, /* mov %ecx,DMAPTR */
70 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
71 0x74, 0x01, /* je +1 */
73 0xff, 0x25, 0,0,0,0 /* jmp *NOTIFY */
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
);
87 static char temp
[] = {
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 */
107 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
108 0x74, 0x01, /* je +1 */
110 0xff, 0x25, 0,0,0,0, /* jmp *NOTIFY */
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
);
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.
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 */
147 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
150 0x74, 0x01, /* je +1 */
152 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
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
);
168 insert_at_head( &tnl
->dfn_cache
.Vertex3f
, dfn
);
175 struct dynfn
*tnl_makeX86Vertex3fv( TNLcontext
*tnl
, int key
)
177 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
179 if (TNL_DEBUG
& DEBUG_CODEGEN
)
180 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
182 switch (tnl
->vertex_size
) {
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 */
203 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
204 0x74, 0x01, /* je 2a4 <.f11> */
206 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
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
);
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 */
247 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
248 0x74, 0x01, /* je 2a4 <.f11> */
250 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
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
);
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.
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 */
295 0xa3, 2, 2, 2, 2, /* mov %eax,COUNTER */
296 0x74, 0x01, /* je +1 */
298 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
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
);
314 insert_at_head( &tnl
->dfn_cache
.Vertex3fv
, dfn
);
320 struct dynfn
*tnl_makeX86Normal3fv( TNLcontext
*tnl
, int key
)
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) */
334 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
336 if (TNL_DEBUG
& DEBUG_CODEGEN
)
337 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
339 insert_at_head( &tnl
->dfn_cache
.Normal3fv
, dfn
);
341 dfn
->code
= ALIGN_MALLOC( sizeof(temp
), 16 );
342 memcpy (dfn
->code
, temp
, sizeof(temp
));
343 FIXUP(dfn
->code
, 5, 0x0, (int)tnl
->normalptr
);
347 struct dynfn
*tnl_makeX86Normal3f( TNLcontext
*tnl
, int key
)
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) */
360 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
362 if (TNL_DEBUG
& DEBUG_CODEGEN
)
363 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
365 insert_at_head( &tnl
->dfn_cache
.Normal3f
, dfn
);
367 dfn
->code
= ALIGN_MALLOC( sizeof(temp
), 16 );
368 memcpy (dfn
->code
, temp
, sizeof(temp
));
369 FIXUP(dfn
->code
, 1, 0x12345678, (int)tnl
->normalptr
);
373 struct dynfn
*tnl_makeX86Color4ubv( TNLcontext
*tnl
, int key
)
375 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
376 insert_at_head( &tnl
->dfn_cache
.Color4ubv
, dfn
);
379 if (TNL_DEBUG
& DEBUG_CODEGEN
)
380 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
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) */
391 dfn
->code
= ALIGN_MALLOC( sizeof(temp
), 16 );
392 memcpy (dfn
->code
, temp
, sizeof(temp
));
393 FIXUP(dfn
->code
, 5, 0x12345678, (int)tnl
->ubytecolorptr
);
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 */
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);
434 struct dynfn
*tnl_makeX86Color4ub( TNLcontext
*tnl
, int key
)
436 if (TNL_DEBUG
& DEBUG_CODEGEN
)
437 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
439 if (key
& TNL_CP_VC_FRMT_PKCOLOR
) {
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 */
455 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
456 insert_at_head( &tnl
->dfn_cache
.Color4ub
, dfn
);
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);
472 struct dynfn
*tnl_makeX86Color3fv( TNLcontext
*tnl
, int key
)
474 if (key
& (TNL_CP_VC_FRMT_PKCOLOR
|TNL_CP_VC_FRMT_FPALPHA
))
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) */
490 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
492 if (TNL_DEBUG
& DEBUG_CODEGEN
)
493 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
495 insert_at_head( &tnl
->dfn_cache
.Color3fv
, dfn
);
497 dfn
->code
= ALIGN_MALLOC( sizeof(temp
), 16 );
498 memcpy (dfn
->code
, temp
, sizeof(temp
));
499 FIXUP(dfn
->code
, 5, 0x0, (int)tnl
->floatcolorptr
);
504 struct dynfn
*tnl_makeX86Color3f( TNLcontext
*tnl
, int key
)
506 if (key
& (TNL_CP_VC_FRMT_PKCOLOR
|TNL_CP_VC_FRMT_FPALPHA
))
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) */
521 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
523 if (TNL_DEBUG
& DEBUG_CODEGEN
)
524 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
526 insert_at_head( &tnl
->dfn_cache
.Color3f
, dfn
);
528 dfn
->code
= ALIGN_MALLOC( sizeof(temp
), 16 );
529 memcpy (dfn
->code
, temp
, sizeof(temp
));
530 FIXUP(dfn
->code
, 1, 0x12345678, (int)tnl
->floatcolorptr
);
537 struct dynfn
*tnl_makeX86TexCoord2fv( TNLcontext
*tnl
, int key
)
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) */
549 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
551 if (TNL_DEBUG
& DEBUG_CODEGEN
)
552 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
554 insert_at_head( &tnl
->dfn_cache
.TexCoord2fv
, dfn
);
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]);
562 struct dynfn
*tnl_makeX86TexCoord2f( TNLcontext
*tnl
, int key
)
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) */
573 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
575 if (TNL_DEBUG
& DEBUG_CODEGEN
)
576 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
578 insert_at_head( &tnl
->dfn_cache
.TexCoord2f
, dfn
);
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]);
586 struct dynfn
*tnl_makeX86MultiTexCoord2fvARB( TNLcontext
*tnl
, int key
)
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) */
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) */
614 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
616 if (TNL_DEBUG
& DEBUG_CODEGEN
)
617 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
619 insert_at_head( &tnl
->dfn_cache
.MultiTexCoord2fvARB
, dfn
);
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);
629 dfn
->code
= ALIGN_MALLOC( sizeof(temp2
), 16 );
630 memcpy (dfn
->code
, temp2
, sizeof(temp2
));
631 FIXUP(dfn
->code
, 19, 0x0, (int)tnl
->texcoordptr
);
636 struct dynfn
*tnl_makeX86MultiTexCoord2fARB( TNLcontext
*tnl
,
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) */
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) */
663 struct dynfn
*dfn
= MALLOC_STRUCT( dynfn
);
665 if (TNL_DEBUG
& DEBUG_CODEGEN
)
666 fprintf(stderr
, "%s 0x%08x\n", __FUNCTION__
, key
);
668 insert_at_head( &tnl
->dfn_cache
.MultiTexCoord2fARB
, dfn
);
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);
679 /* Note: this might get generated multiple times, even though the
680 * actual emitted code is the same.
682 dfn
->code
= ALIGN_MALLOC( sizeof(temp2
), 16 );
683 memcpy (dfn
->code
, temp2
, sizeof(temp2
));
684 FIXUP(dfn
->code
, 23, 0x0, (int)tnl
->texcoordptr
);
690 void _tnl_InitX86Codegen( struct dfn_generators
*gen
)
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
;
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; */
722 void _tnl_InitX86Codegen( struct dfn_generators
*gen
)