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