1 /**************************************************************************
3 Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
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:
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
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.
26 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
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...
46 #define SUBST( x ) (0x10101010 + x)
50 GLOBL ( _x86_Vertex1fv )
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)
61 movsl %ds:(%esi), %es:(%edi)
62 movl %edi, SUBST(0) // 0x0 --> tnl->vtx.vbptr
63 movl SUBST(3), %edx // 0x3 --> counter
67 movl %edx, SUBST(3) // 0x3 --> counter
68 je .5 // if (counter != 0)
70 .5: mov $SUBST(4), %eax // else notify()
71 jmp *%eax // jmp $0x10101014 doesn't seem to work
72 GLOBL ( _x86_Vertex1fv_end )
76 GLOBL ( _x86_Vertex2fv )
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
89 movsl %ds:(%esi), %es:(%edi)
90 movl %edi, SUBST(0) // save tnl->vtx.vbptr
91 movl SUBST(3), %edx // load counter
95 movl %edx, SUBST(3) // save counter
96 je .6 // if (counter != 0)
98 .6: mov $SUBST(4), %eax // else notify()
99 jmp *%eax // jmp $0x10101014 doesn't seem to work
100 GLOBL ( _x86_Vertex2fv_end )
103 GLOBL ( _x86_Vertex3fv )
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
118 movsl %ds:(%esi), %es:(%edi)
119 movl %edi, SUBST(0) // save tnl->vtx.vbptr
120 movl SUBST(3), %edx // load counter
123 dec %edx // counter--
124 movl %edx, SUBST(3) // save counter
125 je .7 // if (counter != 0)
127 .7: mov $SUBST(4), %eax // else notify()
128 jmp *%eax // jmp $0x10101014 doesn't seem to work
129 GLOBL ( _x86_Vertex3fv_end )
133 GLOBL ( _x86_Vertex4fv )
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
150 movsl %ds:(%esi), %es:(%edi)
151 movl %edi, SUBST(0) // save tnl->vtx.vbptr
152 movl SUBST(3), %edx // load counter
155 dec %edx // counter--
156 movl %edx, SUBST(3) // save counter
157 je .6 // if (counter != 0)
159 .8: mov $SUBST(4), %eax // else notify()
160 jmp *%eax // jmp $0x10101014 doesn't seem to work
161 GLOBL ( _x86_Vertex4fv_end )
166 * Generic handlers for vector format data.
169 GLOBL( _x86_Attribute1fv)
171 movl (%ecx), %eax /* load v[0] */
172 movl %eax, SUBST(0) /* store v[0] to current vertex */
174 GLOBL ( _x86_Attribute1fv_end )
176 GLOBL( _x86_Attribute2fv)
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 */
183 GLOBL ( _x86_Attribute2fv_end )
186 GLOBL( _x86_Attribute3fv)
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 */
195 GLOBL ( _x86_Attribute3fv_end )
197 GLOBL( _x86_Attribute4fv)
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 */
208 GLOBL ( _x86_Attribute4fv_end )
213 // Must generate all of these ahead of first usage. Generate at
216 // NOT CURRENTLY USED
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 )
231 // FIRST LEVEL FUNCTIONS -- these are plugged directly into GL dispatch.
234 // NOT CURRENTLY USED
238 // In the 1st level dispatch functions, switch to a different
239 // calling convention -- (const GLfloat *v) in %ecx.
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.
247 // Vertex/Normal/Color, etc: the address of the function pointer
248 // is known at codegen time.
251 // Unfortunately, have to play with the stack in the non-fv case:
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
260 GLOBL( _x86_dispatch_attrf_end )
262 // The fv case is simpler:
264 GLOBL( _x86_dispatch_attrfv )
265 jmp SUBST(0) // 0x0 --> tabfv[attr][n]
266 GLOBL( _x86_dispatch_attrfv_end )
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.
273 // Also, will only need a maximum of four of each of these per context:
275 GLOBL( _x86_dispatch_multitexcoordf )
281 jmp *SUBST(0)(%ecx) // 0x0 - tabfv[tex0][n]
282 GLOBL( _x86_dispatch_multitexcoordf_end )
284 GLOBL( _x86_dispatch_multitexcoordfv )
290 jmp *SUBST(0)(%ecx) // 0x0 - tabfv[tex0][n]
291 GLOBL( _x86_dispatch_multitexcoordfv_end )
293 // VertexAttrib: the address of the function pointer must be
296 GLOBL( _x86_dispatch_vertexattribf )
301 leal 8(%esp), %ecx // calculate 'v'
302 movl %ecx, 4(%esp) // save in 1st arg slot
304 jmp *SUBST(0)(%eax) // 0x0 - tabfv[0][n]
305 GLOBL( _x86_dispatch_vertexattribf_end )
307 GLOBL( _x86_dispatch_vertexattribfv )
312 movl 8(%esp), %ecx // load 'v'
313 movl %ecx, 4(%esp) // save in 1st arg slot
315 jmp *SUBST(0)(%eax) // 0x0 - tabfv[0][n]
316 GLOBL( _x86_dispatch_vertexattribfv_end )