|
|
1.1 root 1: //
2: // math.s
3: // x86 assembly-language math routines.
4:
5: #include "asm_i386.h"
6: #include "quakeasm.h"
7:
8:
1.1.1.2 ! root 9: #if id386
1.1 root 10:
11: .data
12:
13: .align 4
14: Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3
15: .long Lcase4, Lcase5, Lcase6, Lcase7
16:
17: .text
18:
19: // TODO: rounding needed?
20: // stack parameter offset
1.1.1.2 ! root 21: val = 4
1.1 root 22:
23: .globl C(Invert24To16)
24: C(Invert24To16):
25:
26: movl val(%esp),%ecx
27: movl $0x100,%edx // 0x10000000000 as dividend
28: cmpl %edx,%ecx
29: jle LOutOfRange
30:
31: subl %eax,%eax
32: divl %ecx
33:
34: ret
35:
36: LOutOfRange:
37: movl $0xFFFFFFFF,%eax
38: ret
39:
1.1.1.2 ! root 40: //
! 41: // Multiplies a signed 16.16 number by an unsigned 1.31 number (intended
! 42: // to be a looked-up fixed-point inverse of a positive integer).
! 43:
! 44: // stack parameter offsets
! 45: multiplicand = 4
! 46: multiplier = 8
! 47:
! 48: .align 4
! 49: .globl C(Mul16_30)
! 50: C(Mul16_30):
! 51:
! 52: movl multiplicand(%esp),%eax
! 53: imull multiplier(%esp)
! 54: testl %edx,%edx
! 55: jns LDone
! 56: addl $0x3FFFFFFF,%eax
! 57: adcl $0,%edx
! 58: LDone:
! 59: shrd $30,%edx,%eax
! 60: ret
! 61:
! 62:
1.1 root 63: #define in 4
64: #define out 8
65:
66: .align 2
67: .globl C(TransformVector)
68: C(TransformVector):
69: movl in(%esp),%eax
70: movl out(%esp),%edx
71:
72: flds (%eax) // in[0]
73: fmuls C(vright) // in[0]*vright[0]
74: flds (%eax) // in[0] | in[0]*vright[0]
75: fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
76: flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
77: fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
78:
79: flds 4(%eax) // in[1] | ...
80: fmuls C(vright)+4 // in[1]*vright[1] | ...
81: flds 4(%eax) // in[1] | in[1]*vright[1] | ...
82: fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
83: flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
84: fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
85: fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
86:
87: faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
88: faddp %st(0),%st(3) // in[1]*vpn[1] | ...
89: faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
90:
91: flds 8(%eax) // in[2] | ...
92: fmuls C(vright)+8 // in[2]*vright[2] | ...
93: flds 8(%eax) // in[2] | in[2]*vright[2] | ...
94: fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
95: flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
96: fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
97: fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
98:
99: faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
100: faddp %st(0),%st(3) // in[2]*vpn[2] | ...
101: faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
102:
103: fstps 8(%edx) // out[2]
104: fstps 4(%edx) // out[1]
105: fstps (%edx) // out[0]
106:
107: ret
108:
109:
110: #define EMINS 4+4
111: #define EMAXS 4+8
112: #define P 4+12
113:
114: .align 2
115: .globl C(BoxOnPlaneSide)
116: C(BoxOnPlaneSide):
117: pushl %ebx
118:
119: movl P(%esp),%edx
120: movl EMINS(%esp),%ecx
121: xorl %eax,%eax
122: movl EMAXS(%esp),%ebx
123: movb pl_signbits(%edx),%al
124: cmpb $8,%al
125: jge Lerror
126: flds pl_normal(%edx) // p->normal[0]
127: fld %st(0) // p->normal[0] | p->normal[0]
1.1.1.2 ! root 128: jmp *Ljmptab(,%eax,4)
1.1 root 129:
130:
131: //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
132: //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
133: Lcase0:
134: fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0]
135: flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] |
136: // p->normal[0]
137: fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] |
138: // p->normal[1]
139: fmuls (%ecx) // p->normal[0]*emins[0] |
140: // p->normal[0]*emaxs[0] | p->normal[1]
141: fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] |
142: // p->normal[0]*emins[0]
143: fld %st(0) // p->normal[1] | p->normal[1] |
144: // p->normal[0]*emaxs[0] |
145: // p->normal[0]*emins[0]
146: fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] |
147: // p->normal[0]*emaxs[0] |
148: // p->normal[0]*emins[0]
149: flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] |
150: // p->normal[1] | p->normal[0]*emaxs[0] |
151: // p->normal[0]*emins[0]
152: fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] |
153: // p->normal[2] | p->normal[0]*emaxs[0] |
154: // p->normal[0]*emins[0]
155: fmuls 4(%ecx) // p->normal[1]*emins[1] |
156: // p->normal[1]*emaxs[1] |
157: // p->normal[2] | p->normal[0]*emaxs[0] |
158: // p->normal[0]*emins[0]
159: fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] |
160: // p->normal[1]*emins[1] |
161: // p->normal[0]*emaxs[0] |
162: // p->normal[0]*emins[0]
163: fld %st(0) // p->normal[2] | p->normal[2] |
164: // p->normal[1]*emaxs[1] |
165: // p->normal[1]*emins[1] |
166: // p->normal[0]*emaxs[0] |
167: // p->normal[0]*emins[0]
168: fmuls 8(%ebx) // p->normal[2]*emaxs[2] |
169: // p->normal[2] |
170: // p->normal[1]*emaxs[1] |
171: // p->normal[1]*emins[1] |
172: // p->normal[0]*emaxs[0] |
173: // p->normal[0]*emins[0]
174: fxch %st(5) // p->normal[0]*emins[0] |
175: // p->normal[2] |
176: // p->normal[1]*emaxs[1] |
177: // p->normal[1]*emins[1] |
178: // p->normal[0]*emaxs[0] |
179: // p->normal[2]*emaxs[2]
180: faddp %st(0),%st(3) //p->normal[2] |
181: // p->normal[1]*emaxs[1] |
182: // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
183: // p->normal[0]*emaxs[0] |
184: // p->normal[2]*emaxs[2]
185: fmuls 8(%ecx) //p->normal[2]*emins[2] |
186: // p->normal[1]*emaxs[1] |
187: // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
188: // p->normal[0]*emaxs[0] |
189: // p->normal[2]*emaxs[2]
190: fxch %st(1) //p->normal[1]*emaxs[1] |
191: // p->normal[2]*emins[2] |
192: // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
193: // p->normal[0]*emaxs[0] |
194: // p->normal[2]*emaxs[2]
195: faddp %st(0),%st(3) //p->normal[2]*emins[2] |
196: // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
197: // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
198: // p->normal[2]*emaxs[2]
199: fxch %st(3) //p->normal[2]*emaxs[2] +
200: // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
201: // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
202: // p->normal[2]*emins[2]
203: faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
204: // dist1 | p->normal[2]*emins[2]
205:
206: jmp LSetSides
207:
208: //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
209: //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
210: Lcase1:
211: fmuls (%ecx) // emins[0]
212: flds pl_normal+4(%edx)
213: fxch %st(2)
214: fmuls (%ebx) // emaxs[0]
215: fxch %st(2)
216: fld %st(0)
217: fmuls 4(%ebx) // emaxs[1]
218: flds pl_normal+8(%edx)
219: fxch %st(2)
220: fmuls 4(%ecx) // emins[1]
221: fxch %st(2)
222: fld %st(0)
223: fmuls 8(%ebx) // emaxs[2]
224: fxch %st(5)
225: faddp %st(0),%st(3)
226: fmuls 8(%ecx) // emins[2]
227: fxch %st(1)
228: faddp %st(0),%st(3)
229: fxch %st(3)
230: faddp %st(0),%st(2)
231:
232: jmp LSetSides
233:
234: //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
235: //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
236: Lcase2:
237: fmuls (%ebx) // emaxs[0]
238: flds pl_normal+4(%edx)
239: fxch %st(2)
240: fmuls (%ecx) // emins[0]
241: fxch %st(2)
242: fld %st(0)
243: fmuls 4(%ecx) // emins[1]
244: flds pl_normal+8(%edx)
245: fxch %st(2)
246: fmuls 4(%ebx) // emaxs[1]
247: fxch %st(2)
248: fld %st(0)
249: fmuls 8(%ebx) // emaxs[2]
250: fxch %st(5)
251: faddp %st(0),%st(3)
252: fmuls 8(%ecx) // emins[2]
253: fxch %st(1)
254: faddp %st(0),%st(3)
255: fxch %st(3)
256: faddp %st(0),%st(2)
257:
258: jmp LSetSides
259:
260: //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
261: //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
262: Lcase3:
263: fmuls (%ecx) // emins[0]
264: flds pl_normal+4(%edx)
265: fxch %st(2)
266: fmuls (%ebx) // emaxs[0]
267: fxch %st(2)
268: fld %st(0)
269: fmuls 4(%ecx) // emins[1]
270: flds pl_normal+8(%edx)
271: fxch %st(2)
272: fmuls 4(%ebx) // emaxs[1]
273: fxch %st(2)
274: fld %st(0)
275: fmuls 8(%ebx) // emaxs[2]
276: fxch %st(5)
277: faddp %st(0),%st(3)
278: fmuls 8(%ecx) // emins[2]
279: fxch %st(1)
280: faddp %st(0),%st(3)
281: fxch %st(3)
282: faddp %st(0),%st(2)
283:
284: jmp LSetSides
285:
286: //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
287: //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
288: Lcase4:
289: fmuls (%ebx) // emaxs[0]
290: flds pl_normal+4(%edx)
291: fxch %st(2)
292: fmuls (%ecx) // emins[0]
293: fxch %st(2)
294: fld %st(0)
295: fmuls 4(%ebx) // emaxs[1]
296: flds pl_normal+8(%edx)
297: fxch %st(2)
298: fmuls 4(%ecx) // emins[1]
299: fxch %st(2)
300: fld %st(0)
301: fmuls 8(%ecx) // emins[2]
302: fxch %st(5)
303: faddp %st(0),%st(3)
304: fmuls 8(%ebx) // emaxs[2]
305: fxch %st(1)
306: faddp %st(0),%st(3)
307: fxch %st(3)
308: faddp %st(0),%st(2)
309:
310: jmp LSetSides
311:
312: //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
313: //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
314: Lcase5:
315: fmuls (%ecx) // emins[0]
316: flds pl_normal+4(%edx)
317: fxch %st(2)
318: fmuls (%ebx) // emaxs[0]
319: fxch %st(2)
320: fld %st(0)
321: fmuls 4(%ebx) // emaxs[1]
322: flds pl_normal+8(%edx)
323: fxch %st(2)
324: fmuls 4(%ecx) // emins[1]
325: fxch %st(2)
326: fld %st(0)
327: fmuls 8(%ecx) // emins[2]
328: fxch %st(5)
329: faddp %st(0),%st(3)
330: fmuls 8(%ebx) // emaxs[2]
331: fxch %st(1)
332: faddp %st(0),%st(3)
333: fxch %st(3)
334: faddp %st(0),%st(2)
335:
336: jmp LSetSides
337:
338: //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
339: //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
340: Lcase6:
341: fmuls (%ebx) // emaxs[0]
342: flds pl_normal+4(%edx)
343: fxch %st(2)
344: fmuls (%ecx) // emins[0]
345: fxch %st(2)
346: fld %st(0)
347: fmuls 4(%ecx) // emins[1]
348: flds pl_normal+8(%edx)
349: fxch %st(2)
350: fmuls 4(%ebx) // emaxs[1]
351: fxch %st(2)
352: fld %st(0)
353: fmuls 8(%ecx) // emins[2]
354: fxch %st(5)
355: faddp %st(0),%st(3)
356: fmuls 8(%ebx) // emaxs[2]
357: fxch %st(1)
358: faddp %st(0),%st(3)
359: fxch %st(3)
360: faddp %st(0),%st(2)
361:
362: jmp LSetSides
363:
364: //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
365: //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
366: Lcase7:
367: fmuls (%ecx) // emins[0]
368: flds pl_normal+4(%edx)
369: fxch %st(2)
370: fmuls (%ebx) // emaxs[0]
371: fxch %st(2)
372: fld %st(0)
373: fmuls 4(%ecx) // emins[1]
374: flds pl_normal+8(%edx)
375: fxch %st(2)
376: fmuls 4(%ebx) // emaxs[1]
377: fxch %st(2)
378: fld %st(0)
379: fmuls 8(%ecx) // emins[2]
380: fxch %st(5)
381: faddp %st(0),%st(3)
382: fmuls 8(%ebx) // emaxs[2]
383: fxch %st(1)
384: faddp %st(0),%st(3)
385: fxch %st(3)
386: faddp %st(0),%st(2)
387:
388: LSetSides:
389:
390: // sides = 0;
391: // if (dist1 >= p->dist)
392: // sides = 1;
393: // if (dist2 < p->dist)
394: // sides |= 2;
395:
396: faddp %st(0),%st(2) // dist1 | dist2
397: fcomps pl_dist(%edx)
398: xorl %ecx,%ecx
399: fnstsw %ax
400: fcomps pl_dist(%edx)
401: andb $1,%ah
402: xorb $1,%ah
403: addb %ah,%cl
404:
405: fnstsw %ax
406: andb $1,%ah
407: addb %ah,%ah
408: addb %ah,%cl
409:
410: // return sides;
411:
412: popl %ebx
413: movl %ecx,%eax // return status
414:
415: ret
416:
417:
418: Lerror:
419: call C(BOPS_Error)
420:
421: #endif // id386
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.