2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Foobar; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
24
// x86 assembly-language math routines.
34
Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3
35
.long Lcase4, Lcase5, Lcase6, Lcase7
39
// TODO: rounding needed?
40
// stack parameter offset
43
.globl C(Invert24To16)
47
movl $0x100,%edx // 0x10000000000 as dividend
66
.globl C(TransformVector)
72
fmuls C(vright) // in[0]*vright[0]
73
flds (%eax) // in[0] | in[0]*vright[0]
74
fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
75
flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
76
fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
78
flds 4(%eax) // in[1] | ...
79
fmuls C(vright)+4 // in[1]*vright[1] | ...
80
flds 4(%eax) // in[1] | in[1]*vright[1] | ...
81
fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
82
flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
83
fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
84
fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
86
faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
87
faddp %st(0),%st(3) // in[1]*vpn[1] | ...
88
faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
90
flds 8(%eax) // in[2] | ...
91
fmuls C(vright)+8 // in[2]*vright[2] | ...
92
flds 8(%eax) // in[2] | in[2]*vright[2] | ...
93
fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
94
flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
95
fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
96
fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
98
faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
99
faddp %st(0),%st(3) // in[2]*vpn[2] | ...
100
faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
102
fstps 8(%edx) // out[2]
103
fstps 4(%edx) // out[1]
104
fstps (%edx) // out[0]
115
.globl C(BoxOnPlaneSide)
120
movl EMINS(%esp),%ecx
122
movl EMAXS(%esp),%ebx
123
movb pl_signbits(%edx),%al
126
flds pl_normal(%edx) // p->normal[0]
127
fld %st(0) // p->normal[0] | p->normal[0]
128
// bk000422 - warning: missing prefix `*' in absolute indirect address, maybe misassembled!
129
// bk001129 - fix from Andrew Henderson, was: Ljmptab(,%eax,4)
130
jmp *Ljmptab(,%eax,4)
133
//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
134
//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
136
fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0]
137
flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] |
139
fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] |
141
fmuls (%ecx) // p->normal[0]*emins[0] |
142
// p->normal[0]*emaxs[0] | p->normal[1]
143
fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] |
144
// p->normal[0]*emins[0]
145
fld %st(0) // p->normal[1] | p->normal[1] |
146
// p->normal[0]*emaxs[0] |
147
// p->normal[0]*emins[0]
148
fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] |
149
// p->normal[0]*emaxs[0] |
150
// p->normal[0]*emins[0]
151
flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] |
152
// p->normal[1] | p->normal[0]*emaxs[0] |
153
// p->normal[0]*emins[0]
154
fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] |
155
// p->normal[2] | p->normal[0]*emaxs[0] |
156
// p->normal[0]*emins[0]
157
fmuls 4(%ecx) // p->normal[1]*emins[1] |
158
// p->normal[1]*emaxs[1] |
159
// p->normal[2] | p->normal[0]*emaxs[0] |
160
// p->normal[0]*emins[0]
161
fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] |
162
// p->normal[1]*emins[1] |
163
// p->normal[0]*emaxs[0] |
164
// p->normal[0]*emins[0]
165
fld %st(0) // p->normal[2] | p->normal[2] |
166
// p->normal[1]*emaxs[1] |
167
// p->normal[1]*emins[1] |
168
// p->normal[0]*emaxs[0] |
169
// p->normal[0]*emins[0]
170
fmuls 8(%ebx) // p->normal[2]*emaxs[2] |
172
// p->normal[1]*emaxs[1] |
173
// p->normal[1]*emins[1] |
174
// p->normal[0]*emaxs[0] |
175
// p->normal[0]*emins[0]
176
fxch %st(5) // p->normal[0]*emins[0] |
178
// p->normal[1]*emaxs[1] |
179
// p->normal[1]*emins[1] |
180
// p->normal[0]*emaxs[0] |
181
// p->normal[2]*emaxs[2]
182
faddp %st(0),%st(3) //p->normal[2] |
183
// p->normal[1]*emaxs[1] |
184
// p->normal[1]*emins[1]+p->normal[0]*emins[0]|
185
// p->normal[0]*emaxs[0] |
186
// p->normal[2]*emaxs[2]
187
fmuls 8(%ecx) //p->normal[2]*emins[2] |
188
// p->normal[1]*emaxs[1] |
189
// p->normal[1]*emins[1]+p->normal[0]*emins[0]|
190
// p->normal[0]*emaxs[0] |
191
// p->normal[2]*emaxs[2]
192
fxch %st(1) //p->normal[1]*emaxs[1] |
193
// p->normal[2]*emins[2] |
194
// p->normal[1]*emins[1]+p->normal[0]*emins[0]|
195
// p->normal[0]*emaxs[0] |
196
// p->normal[2]*emaxs[2]
197
faddp %st(0),%st(3) //p->normal[2]*emins[2] |
198
// p->normal[1]*emins[1]+p->normal[0]*emins[0]|
199
// p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
200
// p->normal[2]*emaxs[2]
201
fxch %st(3) //p->normal[2]*emaxs[2] +
202
// p->normal[1]*emins[1]+p->normal[0]*emins[0]|
203
// p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
204
// p->normal[2]*emins[2]
205
faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
206
// dist1 | p->normal[2]*emins[2]
210
//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
211
//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
213
fmuls (%ecx) // emins[0]
214
flds pl_normal+4(%edx)
216
fmuls (%ebx) // emaxs[0]
219
fmuls 4(%ebx) // emaxs[1]
220
flds pl_normal+8(%edx)
222
fmuls 4(%ecx) // emins[1]
225
fmuls 8(%ebx) // emaxs[2]
228
fmuls 8(%ecx) // emins[2]
236
//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
237
//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
239
fmuls (%ebx) // emaxs[0]
240
flds pl_normal+4(%edx)
242
fmuls (%ecx) // emins[0]
245
fmuls 4(%ecx) // emins[1]
246
flds pl_normal+8(%edx)
248
fmuls 4(%ebx) // emaxs[1]
251
fmuls 8(%ebx) // emaxs[2]
254
fmuls 8(%ecx) // emins[2]
262
//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
263
//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
265
fmuls (%ecx) // emins[0]
266
flds pl_normal+4(%edx)
268
fmuls (%ebx) // emaxs[0]
271
fmuls 4(%ecx) // emins[1]
272
flds pl_normal+8(%edx)
274
fmuls 4(%ebx) // emaxs[1]
277
fmuls 8(%ebx) // emaxs[2]
280
fmuls 8(%ecx) // emins[2]
288
//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
289
//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
291
fmuls (%ebx) // emaxs[0]
292
flds pl_normal+4(%edx)
294
fmuls (%ecx) // emins[0]
297
fmuls 4(%ebx) // emaxs[1]
298
flds pl_normal+8(%edx)
300
fmuls 4(%ecx) // emins[1]
303
fmuls 8(%ecx) // emins[2]
306
fmuls 8(%ebx) // emaxs[2]
314
//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
315
//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
317
fmuls (%ecx) // emins[0]
318
flds pl_normal+4(%edx)
320
fmuls (%ebx) // emaxs[0]
323
fmuls 4(%ebx) // emaxs[1]
324
flds pl_normal+8(%edx)
326
fmuls 4(%ecx) // emins[1]
329
fmuls 8(%ecx) // emins[2]
332
fmuls 8(%ebx) // emaxs[2]
340
//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
341
//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
343
fmuls (%ebx) // emaxs[0]
344
flds pl_normal+4(%edx)
346
fmuls (%ecx) // emins[0]
349
fmuls 4(%ecx) // emins[1]
350
flds pl_normal+8(%edx)
352
fmuls 4(%ebx) // emaxs[1]
355
fmuls 8(%ecx) // emins[2]
358
fmuls 8(%ebx) // emaxs[2]
366
//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
367
//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
369
fmuls (%ecx) // emins[0]
370
flds pl_normal+4(%edx)
372
fmuls (%ebx) // emaxs[0]
375
fmuls 4(%ecx) // emins[1]
376
flds pl_normal+8(%edx)
378
fmuls 4(%ebx) // emaxs[1]
381
fmuls 8(%ecx) // emins[2]
384
fmuls 8(%ebx) // emaxs[2]
393
// if (dist1 >= p->dist)
395
// if (dist2 < p->dist)
398
faddp %st(0),%st(2) // dist1 | dist2
415
movl %ecx,%eax // return status