ref: b8c0e4deccffcd668f7d08ffc1fe16147e9e894a
dir: /code/unix/vm_x86a.s/
/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code 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. Quake III Arena source code 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // // vm_x86a.s // linux x86 vm support #include "qasm.h" .extern C(instructionPointers) .data .align 4 programStack .long 0 opStack .long 0 syscallNum .long 0 .text .globl C(AsmCAll) C(AsmCall): movl (%edi),%eax subl 4,%edi orl %eax,%eax jl systemCall // calling another vm function shll 2,%eax addl C(instructionPointers),%eax call (%eax) ret systemCall: // convert negative num to system call number // and store right before the first arg negl %eax decl %eax movl %eax,syscallNum ///---- UNFINISHED FROM HERE mov dword ptr syscallNum, eax // so C code can get at it mov dword ptr programStack, esi // so C code can get at it mov dword ptr opStack, edi push ecx push esi // we may call recursively, so the push edi // statics aren't guaranteed to be around } // save the stack to allow recursive VM entry currentVM->programStack = programStack - 4; *(int *)((byte *)currentVM->dataBase + programStack + 4) = syscallNum; //VM_LogSyscalls( (int *)((byte *)currentVM->dataBase + programStack + 4) ); *(opStack+1) = currentVM->systemCall( (int *)((byte *)currentVM->dataBase + programStack + 4) ); _asm { pop edi pop esi pop ecx add edi, 4 // we added the return value ret } } //-------------------------------------------- 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 #if 0 #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 #endif #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: movl 1, %eax ret #endif // id386