First round of codegen for t_vtx_api.c -- ie the Begin/Vertex/End code.
[mesa.git] / src / mesa / tnl / t_vtx_x86_gcc.S
1 /**************************************************************************
2
3 Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33
34 #define GLOBL( x ) \
35 .globl x; \
36 x:
37
38 .data
39 .align 4
40
41 // Someone who knew a lot about this sort of thing would use this
42 // macro to note current offsets, etc in a special region of the
43 // object file & just make everything work out neat. I don't know
44 // enough to do that...
45
46 #define SUBST( x ) (0x10101010 + x)
47
48
49
50 GLOBL ( _x86_Vertex1fv )
51 movl 4(%esp), %ecx
52 push %edi
53 push %esi
54 movl SUBST(0), %edi // 0x0 --> tnl->vtx.vbptr
55 movl (%ecx), %edx // load v[0]
56 movl %edx, (%edi) // tnl->vtx.vbptr[0] = v[0]
57 addl $4, %edi // tnl->vtx.vbptr += 1
58 movl $SUBST(1), %ecx // 0x1 --> (tnl->vtx.vertex_size - 1)
59 movl $SUBST(2), %esi // 0x2 --> (tnl->vtx.vertex + 1)
60 repz
61 movsl %ds:(%esi), %es:(%edi)
62 movl %edi, SUBST(0) // 0x0 --> tnl->vtx.vbptr
63 movl SUBST(3), %edx // 0x3 --> counter
64 pop %esi
65 pop %edi
66 dec %edx // counter--
67 movl %edx, SUBST(3) // 0x3 --> counter
68 je .5 // if (counter != 0)
69 ret // return
70 .5: mov $SUBST(4), %eax // else notify()
71 jmp *%eax // jmp $0x10101014 doesn't seem to work
72 GLOBL ( _x86_Vertex1fv_end )
73
74
75 .align 4
76 GLOBL ( _x86_Vertex2fv )
77 movl 4(%esp), %ecx
78 push %edi
79 push %esi
80 movl SUBST(0), %edi // load tnl->vtx.vbptr
81 movl (%ecx), %edx // load v[0]
82 movl 4(%ecx), %eax // load v[1]
83 movl %edx, (%edi) // tnl->vtx.vbptr[0] = v[0]
84 movl %eax, 4(%edi) // tnl->vtx.vbptr[1] = v[1]
85 addl $8, %edi // tnl->vtx.vbptr += 2
86 movl $SUBST(1), %ecx // vertex_size - 2
87 movl $SUBST(2), %esi // tnl->vtx.vertex + 2
88 repz
89 movsl %ds:(%esi), %es:(%edi)
90 movl %edi, SUBST(0) // save tnl->vtx.vbptr
91 movl SUBST(3), %edx // load counter
92 pop %esi
93 pop %edi
94 dec %edx // counter--
95 movl %edx, SUBST(3) // save counter
96 je .6 // if (counter != 0)
97 ret // return
98 .6: mov $SUBST(4), %eax // else notify()
99 jmp *%eax // jmp $0x10101014 doesn't seem to work
100 GLOBL ( _x86_Vertex2fv_end )
101
102 .align 4
103 GLOBL ( _x86_Vertex3fv )
104 movl 4(%esp), %ecx
105 push %edi
106 push %esi
107 movl SUBST(0), %edi // load tnl->vtx.vbptr
108 movl (%ecx), %edx // load v[0]
109 movl 4(%ecx), %eax // load v[1]
110 movl 8(%ecx), %esi // load v[2]
111 movl %edx, (%edi) // tnl->vtx.vbptr[0] = v[0]
112 movl %eax, 4(%edi) // tnl->vtx.vbptr[1] = v[1]
113 movl %esi, 8(%edi) // tnl->vtx.vbptr[2] = v[2]
114 addl $12, %edi // tnl->vtx.vbptr += 3
115 movl $SUBST(1), %ecx // vertex_size - 3
116 movl $SUBST(2), %esi // tnl->vtx.vertex + 3
117 repz
118 movsl %ds:(%esi), %es:(%edi)
119 movl %edi, SUBST(0) // save tnl->vtx.vbptr
120 movl SUBST(3), %edx // load counter
121 pop %esi
122 pop %edi
123 dec %edx // counter--
124 movl %edx, SUBST(3) // save counter
125 je .7 // if (counter != 0)
126 ret // return
127 .7: mov $SUBST(4), %eax // else notify()
128 jmp *%eax // jmp $0x10101014 doesn't seem to work
129 GLOBL ( _x86_Vertex3fv_end )
130
131
132 .align 4
133 GLOBL ( _x86_Vertex4fv )
134 movl 4(%esp), %ecx
135 push %edi
136 push %esi
137 movl SUBST(0), %edi // load tnl->vtx.vbptr
138 movl (%ecx), %edx // load v[0]
139 movl 4(%ecx), %eax // load v[1]
140 movl 8(%ecx), %esi // load v[2]
141 movl 12(%ecx), %ecx // load v[3]
142 movl %edx, (%edi) // tnl->vtx.vbptr[0] = v[0]
143 movl %eax, 4(%edi) // tnl->vtx.vbptr[1] = v[1]
144 movl %esi, 8(%edi) // tnl->vtx.vbptr[2] = v[2]
145 movl %ecx, 12(%edi) // tnl->vtx.vbptr[3] = v[3]
146 addl $16, %edi // tnl->vtx.vbptr += 4
147 movl $SUBST(1), %ecx // vertex_size - 4
148 movl $SUBST(2), %esi // tnl->vtx.vertex + 3
149 repz
150 movsl %ds:(%esi), %es:(%edi)
151 movl %edi, SUBST(0) // save tnl->vtx.vbptr
152 movl SUBST(3), %edx // load counter
153 pop %esi
154 pop %edi
155 dec %edx // counter--
156 movl %edx, SUBST(3) // save counter
157 je .6 // if (counter != 0)
158 ret // return
159 .8: mov $SUBST(4), %eax // else notify()
160 jmp *%eax // jmp $0x10101014 doesn't seem to work
161 GLOBL ( _x86_Vertex4fv_end )
162
163
164
165 /**
166 * Generic handlers for vector format data.
167 */
168
169 GLOBL( _x86_Attribute1fv)
170 movl 4(%esp), %ecx
171 movl (%ecx), %eax /* load v[0] */
172 movl %eax, SUBST(0) /* store v[0] to current vertex */
173 ret
174 GLOBL ( _x86_Attribute1fv_end )
175
176 GLOBL( _x86_Attribute2fv)
177 movl 4(%esp), %ecx
178 movl (%ecx), %eax /* load v[0] */
179 movl 4(%ecx), %edx /* load v[1] */
180 movl %eax, SUBST(0) /* store v[0] to current vertex */
181 movl %edx, SUBST(1) /* store v[1] to current vertex */
182 ret
183 GLOBL ( _x86_Attribute2fv_end )
184
185
186 GLOBL( _x86_Attribute3fv)
187 movl 4(%esp), %ecx
188 movl (%ecx), %eax /* load v[0] */
189 movl 4(%ecx), %edx /* load v[1] */
190 movl 8(%ecx), %ecx /* load v[2] */
191 movl %eax, SUBST(0) /* store v[0] to current vertex */
192 movl %edx, SUBST(1) /* store v[1] to current vertex */
193 movl %ecx, SUBST(2) /* store v[2] to current vertex */
194 ret
195 GLOBL ( _x86_Attribute3fv_end )
196
197 GLOBL( _x86_Attribute4fv)
198 movl 4(%esp), %ecx
199 movl (%ecx), %eax /* load v[0] */
200 movl 4(%ecx), %edx /* load v[1] */
201 movl %eax, SUBST(0) /* store v[0] to current vertex */
202 movl %edx, SUBST(1) /* store v[1] to current vertex */
203 movl 8(%ecx), %eax /* load v[2] */
204 movl 12(%ecx), %edx /* load v[3] */
205 movl %eax, SUBST(2) /* store v[2] to current vertex */
206 movl %edx, SUBST(3) /* store v[3] to current vertex */
207 ret
208 GLOBL ( _x86_Attribute4fv_end )
209
210
211 // Choosers:
212
213 // Must generate all of these ahead of first usage. Generate at
214 // compile-time?
215
216 // NOT CURRENTLY USED
217
218
219 GLOBL( _x86_choose_fv)
220 subl $12, %esp // gcc does 16 byte alignment of stack frames?
221 movl $SUBST(0), (%esp) // arg 0 - attrib
222 movl $SUBST(1), 4(%esp) // arg 1 - N
223 call _do_choose // new function returned in %eax
224 add $12, %esp // tear down stack frame
225 jmp *%eax // jump to new func
226 GLOBL ( _x86_choosefv_end )
227
228
229
230
231 // FIRST LEVEL FUNCTIONS -- these are plugged directly into GL dispatch.
232
233
234 // NOT CURRENTLY USED
235
236
237
238 // In the 1st level dispatch functions, switch to a different
239 // calling convention -- (const GLfloat *v) in %ecx.
240 //
241 // As with regular (x86) dispatch, don't create a new stack frame -
242 // just let the 'ret' in the dispatched function return straight
243 // back to the original caller.
244
245
246
247 // Vertex/Normal/Color, etc: the address of the function pointer
248 // is known at codegen time.
249
250
251 // Unfortunately, have to play with the stack in the non-fv case:
252 //
253 GLOBL( _x86_dispatch_attrf )
254 subl $12, %esp // gcc does 16 byte alignment of stack frames?
255 leal 16(%esp), %edx // address of first float on stack
256 movl %edx, (%esp) // save as 'v'
257 call SUBST(0) // 0x0 --> tabfv[attr][n]
258 addl $12, %esp // tear down frame
259 ret // return
260 GLOBL( _x86_dispatch_attrf_end )
261
262 // The fv case is simpler:
263 //
264 GLOBL( _x86_dispatch_attrfv )
265 jmp SUBST(0) // 0x0 --> tabfv[attr][n]
266 GLOBL( _x86_dispatch_attrfv_end )
267
268
269 // MultiTexcoord: the address of the function pointer must be
270 // calculated, but can use the index argument slot to hold 'v', and
271 // avoid setting up a new stack frame.
272
273 // Also, will only need a maximum of four of each of these per context:
274 //
275 GLOBL( _x86_dispatch_multitexcoordf )
276 movl 4(%esp), %ecx
277 leal 8(%esp), %edx
278 andl $7, %ecx
279 movl %edx, 4(%esp)
280 sall $4, %ecx
281 jmp *SUBST(0)(%ecx) // 0x0 - tabfv[tex0][n]
282 GLOBL( _x86_dispatch_multitexcoordf_end )
283
284 GLOBL( _x86_dispatch_multitexcoordfv )
285 movl 4(%esp), %ecx
286 movl 8(%esp), %edx
287 andl $7, %ecx
288 movl %edx, 4(%esp)
289 sall $4, %ecx
290 jmp *SUBST(0)(%ecx) // 0x0 - tabfv[tex0][n]
291 GLOBL( _x86_dispatch_multitexcoordfv_end )
292
293 // VertexAttrib: the address of the function pointer must be
294 // calculated.
295
296 GLOBL( _x86_dispatch_vertexattribf )
297 movl $16, %ecx
298 movl 4(%esp), %eax
299 cmpl $16, %eax
300 cmovge %ecx, %eax
301 leal 8(%esp), %ecx // calculate 'v'
302 movl %ecx, 4(%esp) // save in 1st arg slot
303 sall $4, %eax
304 jmp *SUBST(0)(%eax) // 0x0 - tabfv[0][n]
305 GLOBL( _x86_dispatch_vertexattribf_end )
306
307 GLOBL( _x86_dispatch_vertexattribfv )
308 movl $16, %ecx
309 movl 4(%esp), %eax
310 cmpl $16, %eax
311 cmovge %ecx, %eax
312 movl 8(%esp), %ecx // load 'v'
313 movl %ecx, 4(%esp) // save in 1st arg slot
314 sall $4, %eax
315 jmp *SUBST(0)(%eax) // 0x0 - tabfv[0][n]
316 GLOBL( _x86_dispatch_vertexattribfv_end )
317