123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- /*
- Copyright (C) 1996-1997 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- //
- // math.s
- // x86 assembly-language math routines.
- #include "asm_i386.h"
- #include "quakeasm.h"
- #if id386
- .data
- .align 4
- Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3
- .long Lcase4, Lcase5, Lcase6, Lcase7
- .text
- // TODO: rounding needed?
- // stack parameter offset
- #define val 4
- .globl C(Invert24To16)
- C(Invert24To16):
- movl val(%esp),%ecx
- movl $0x100,%edx // 0x10000000000 as dividend
- cmpl %edx,%ecx
- jle LOutOfRange
- subl %eax,%eax
- divl %ecx
- ret
- LOutOfRange:
- movl $0xFFFFFFFF,%eax
- ret
- #define in 4
- #define out 8
- .align 2
- .globl C(TransformVector)
- C(TransformVector):
- movl in(%esp),%eax
- movl out(%esp),%edx
- flds (%eax) // in[0]
- fmuls C(vright) // in[0]*vright[0]
- flds (%eax) // in[0] | in[0]*vright[0]
- fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
- flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
- fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
- flds 4(%eax) // in[1] | ...
- fmuls C(vright)+4 // in[1]*vright[1] | ...
- flds 4(%eax) // in[1] | in[1]*vright[1] | ...
- fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
- flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
- fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
- fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
- faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
- faddp %st(0),%st(3) // in[1]*vpn[1] | ...
- faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
- flds 8(%eax) // in[2] | ...
- fmuls C(vright)+8 // in[2]*vright[2] | ...
- flds 8(%eax) // in[2] | in[2]*vright[2] | ...
- fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
- flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
- fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
- fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
- faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
- faddp %st(0),%st(3) // in[2]*vpn[2] | ...
- faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
- fstps 8(%edx) // out[2]
- fstps 4(%edx) // out[1]
- fstps (%edx) // out[0]
- ret
- #define EMINS 4+4
- #define EMAXS 4+8
- #define P 4+12
- .align 2
- .globl C(BoxOnPlaneSide)
- C(BoxOnPlaneSide):
- pushl %ebx
- movl P(%esp),%edx
- movl EMINS(%esp),%ecx
- xorl %eax,%eax
- movl EMAXS(%esp),%ebx
- movb pl_signbits(%edx),%al
- cmpb $8,%al
- jge Lerror
- flds pl_normal(%edx) // p->normal[0]
- fld %st(0) // p->normal[0] | p->normal[0]
- jmp Ljmptab(,%eax,4)
- //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- Lcase0:
- fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0]
- flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] |
- // p->normal[0]
- fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] |
- // p->normal[1]
- fmuls (%ecx) // p->normal[0]*emins[0] |
- // p->normal[0]*emaxs[0] | p->normal[1]
- fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fld %st(0) // p->normal[1] | p->normal[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] |
- // p->normal[1] | p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] |
- // p->normal[2] | p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fmuls 4(%ecx) // p->normal[1]*emins[1] |
- // p->normal[1]*emaxs[1] |
- // p->normal[2] | p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fld %st(0) // p->normal[2] | p->normal[2] |
- // p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fmuls 8(%ebx) // p->normal[2]*emaxs[2] |
- // p->normal[2] |
- // p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[0]*emins[0]
- fxch %st(5) // p->normal[0]*emins[0] |
- // p->normal[2] |
- // p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1] |
- // p->normal[0]*emaxs[0] |
- // p->normal[2]*emaxs[2]
- faddp %st(0),%st(3) //p->normal[2] |
- // p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // p->normal[0]*emaxs[0] |
- // p->normal[2]*emaxs[2]
- fmuls 8(%ecx) //p->normal[2]*emins[2] |
- // p->normal[1]*emaxs[1] |
- // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // p->normal[0]*emaxs[0] |
- // p->normal[2]*emaxs[2]
- fxch %st(1) //p->normal[1]*emaxs[1] |
- // p->normal[2]*emins[2] |
- // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // p->normal[0]*emaxs[0] |
- // p->normal[2]*emaxs[2]
- faddp %st(0),%st(3) //p->normal[2]*emins[2] |
- // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
- // p->normal[2]*emaxs[2]
- fxch %st(3) //p->normal[2]*emaxs[2] +
- // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
- // p->normal[2]*emins[2]
- faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
- // dist1 | p->normal[2]*emins[2]
- jmp LSetSides
- //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- Lcase1:
- fmuls (%ecx) // emins[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ebx) // emaxs[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ebx) // emaxs[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ecx) // emins[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ecx) // emins[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- Lcase2:
- fmuls (%ebx) // emaxs[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ecx) // emins[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ecx) // emins[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ebx) // emaxs[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ecx) // emins[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- Lcase3:
- fmuls (%ecx) // emins[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ebx) // emaxs[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ecx) // emins[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ebx) // emaxs[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ecx) // emins[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- //dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- Lcase4:
- fmuls (%ebx) // emaxs[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ecx) // emins[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ebx) // emaxs[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ecx) // emins[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ecx) // emins[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- Lcase5:
- fmuls (%ecx) // emins[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ebx) // emaxs[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ebx) // emaxs[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ecx) // emins[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ecx) // emins[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- //dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- Lcase6:
- fmuls (%ebx) // emaxs[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ecx) // emins[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ecx) // emins[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ebx) // emaxs[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ecx) // emins[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- jmp LSetSides
- //dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- //dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- Lcase7:
- fmuls (%ecx) // emins[0]
- flds pl_normal+4(%edx)
- fxch %st(2)
- fmuls (%ebx) // emaxs[0]
- fxch %st(2)
- fld %st(0)
- fmuls 4(%ecx) // emins[1]
- flds pl_normal+8(%edx)
- fxch %st(2)
- fmuls 4(%ebx) // emaxs[1]
- fxch %st(2)
- fld %st(0)
- fmuls 8(%ecx) // emins[2]
- fxch %st(5)
- faddp %st(0),%st(3)
- fmuls 8(%ebx) // emaxs[2]
- fxch %st(1)
- faddp %st(0),%st(3)
- fxch %st(3)
- faddp %st(0),%st(2)
- LSetSides:
- // sides = 0;
- // if (dist1 >= p->dist)
- // sides = 1;
- // if (dist2 < p->dist)
- // sides |= 2;
- faddp %st(0),%st(2) // dist1 | dist2
- fcomps pl_dist(%edx)
- xorl %ecx,%ecx
- fnstsw %ax
- fcomps pl_dist(%edx)
- andb $1,%ah
- xorb $1,%ah
- addb %ah,%cl
- fnstsw %ax
- andb $1,%ah
- addb %ah,%ah
- addb %ah,%cl
- // return sides;
- popl %ebx
- movl %ecx,%eax // return status
- ret
- Lerror:
- call C(BOPS_Error)
- #endif // id386
|