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