📄 vm_interpreted.c
字号:
goto nextInstruction2;
case OP_STORE4:
*(int *)&image[ r1&(dataMask & ~3) ] = r0;
opStack -= 2;
goto nextInstruction;
case OP_STORE2:
*(short *)&image[ r1&(dataMask & ~1) ] = r0;
opStack -= 2;
goto nextInstruction;
case OP_STORE1:
image[ r1&dataMask ] = r0;
opStack -= 2;
goto nextInstruction;
case OP_ARG:
// single byte offset from programStack
*(int *)&image[ codeImage[programCounter] + programStack ] = r0;
opStack--;
programCounter += 1;
goto nextInstruction;
case OP_BLOCK_COPY:
{
int *src, *dest;
int i, count, srci, desti;
count = r2;
// MrE: copy range check
srci = r0 & dataMask;
desti = r1 & dataMask;
count = ((srci + count) & dataMask) - srci;
count = ((desti + count) & dataMask) - desti;
src = (int *)&image[ r0&dataMask ];
dest = (int *)&image[ r1&dataMask ];
if ( ( (int)src | (int)dest | count ) & 3 ) {
Com_Error( ERR_DROP, "OP_BLOCK_COPY not dword aligned" );
}
count >>= 2;
for ( i = count-1 ; i>= 0 ; i-- ) {
dest[i] = src[i];
}
programCounter += 4;
opStack -= 2;
}
goto nextInstruction;
case OP_CALL:
// save current program counter
*(int *)&image[ programStack ] = programCounter;
// jump to the location on the stack
programCounter = r0;
opStack--;
if ( programCounter < 0 ) {
// system call
int r;
int temp;
#ifdef DEBUG_VM
int stomped;
if ( vm_debugLevel ) {
Com_Printf( "%s---> systemcall(%i)\n", DEBUGSTR, -1 - programCounter );
}
#endif
// save the stack to allow recursive VM entry
temp = vm->callLevel;
vm->programStack = programStack - 4;
#ifdef DEBUG_VM
stomped = *(int *)&image[ programStack + 4 ];
#endif
*(int *)&image[ programStack + 4 ] = -1 - programCounter;
//VM_LogSyscalls( (int *)&image[ programStack + 4 ] );
r = vm->systemCall( (int *)&image[ programStack + 4 ] );
#ifdef DEBUG_VM
// this is just our stack frame pointer, only needed
// for debugging
*(int *)&image[ programStack + 4 ] = stomped;
#endif
// save return value
opStack++;
*opStack = r;
programCounter = *(int *)&image[ programStack ];
vm->callLevel = temp;
#ifdef DEBUG_VM
if ( vm_debugLevel ) {
Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
}
#endif
} else {
programCounter = vm->instructionPointers[ programCounter ];
}
goto nextInstruction;
// push and pop are only needed for discarded or bad function return values
case OP_PUSH:
opStack++;
goto nextInstruction;
case OP_POP:
opStack--;
goto nextInstruction;
case OP_ENTER:
#ifdef DEBUG_VM
profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
#endif
// get size of stack frame
v1 = r2;
programCounter += 4;
programStack -= v1;
#ifdef DEBUG_VM
// save old stack frame for debugging traces
*(int *)&image[programStack+4] = programStack + v1;
if ( vm_debugLevel ) {
Com_Printf( "%s---> %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter - 5 ) );
if ( vm->breakFunction && programCounter - 5 == vm->breakFunction ) {
// this is to allow setting breakpoints here in the debugger
vm->breakCount++;
// vm_debugLevel = 2;
// VM_StackTrace( vm, programCounter, programStack );
}
vm->callLevel++;
}
#endif
goto nextInstruction;
case OP_LEAVE:
// remove our stack frame
v1 = r2;
programStack += v1;
// grab the saved program counter
programCounter = *(int *)&image[ programStack ];
#ifdef DEBUG_VM
profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
if ( vm_debugLevel ) {
vm->callLevel--;
Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
}
#endif
// check for leaving the VM
if ( programCounter == -1 ) {
goto done;
}
goto nextInstruction;
/*
===================================================================
BRANCHES
===================================================================
*/
case OP_JUMP:
programCounter = r0;
programCounter = vm->instructionPointers[ programCounter ];
opStack--;
goto nextInstruction;
case OP_EQ:
opStack -= 2;
if ( r1 == r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_NE:
opStack -= 2;
if ( r1 != r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_LTI:
opStack -= 2;
if ( r1 < r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_LEI:
opStack -= 2;
if ( r1 <= r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_GTI:
opStack -= 2;
if ( r1 > r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_GEI:
opStack -= 2;
if ( r1 >= r0 ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_LTU:
opStack -= 2;
if ( ((unsigned)r1) < ((unsigned)r0) ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_LEU:
opStack -= 2;
if ( ((unsigned)r1) <= ((unsigned)r0) ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_GTU:
opStack -= 2;
if ( ((unsigned)r1) > ((unsigned)r0) ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_GEU:
opStack -= 2;
if ( ((unsigned)r1) >= ((unsigned)r0) ) {
programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction;
} else {
programCounter += 4;
goto nextInstruction;
}
case OP_EQF:
if ( ((float *)opStack)[-1] == *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
case OP_NEF:
if ( ((float *)opStack)[-1] != *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
case OP_LTF:
if ( ((float *)opStack)[-1] < *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
case OP_LEF:
if ( ((float *)opStack)[-1] <= *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
case OP_GTF:
if ( ((float *)opStack)[-1] > *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
case OP_GEF:
if ( ((float *)opStack)[-1] >= *(float *)opStack ) {
programCounter = r2; //vm->instructionPointers[r2];
opStack -= 2;
goto nextInstruction;
} else {
programCounter += 4;
opStack -= 2;
goto nextInstruction;
}
//===================================================================
case OP_NEGI:
*opStack = -r0;
goto nextInstruction;
case OP_ADD:
opStack[-1] = r1 + r0;
opStack--;
goto nextInstruction;
case OP_SUB:
opStack[-1] = r1 - r0;
opStack--;
goto nextInstruction;
case OP_DIVI:
opStack[-1] = r1 / r0;
opStack--;
goto nextInstruction;
case OP_DIVU:
opStack[-1] = ((unsigned)r1) / ((unsigned)r0);
opStack--;
goto nextInstruction;
case OP_MODI:
opStack[-1] = r1 % r0;
opStack--;
goto nextInstruction;
case OP_MODU:
opStack[-1] = ((unsigned)r1) % (unsigned)r0;
opStack--;
goto nextInstruction;
case OP_MULI:
opStack[-1] = r1 * r0;
opStack--;
goto nextInstruction;
case OP_MULU:
opStack[-1] = ((unsigned)r1) * ((unsigned)r0);
opStack--;
goto nextInstruction;
case OP_BAND:
opStack[-1] = ((unsigned)r1) & ((unsigned)r0);
opStack--;
goto nextInstruction;
case OP_BOR:
opStack[-1] = ((unsigned)r1) | ((unsigned)r0);
opStack--;
goto nextInstruction;
case OP_BXOR:
opStack[-1] = ((unsigned)r1) ^ ((unsigned)r0);
opStack--;
goto nextInstruction;
case OP_BCOM:
opStack[-1] = ~ ((unsigned)r0);
goto nextInstruction;
case OP_LSH:
opStack[-1] = r1 << r0;
opStack--;
goto nextInstruction;
case OP_RSHI:
opStack[-1] = r1 >> r0;
opStack--;
goto nextInstruction;
case OP_RSHU:
opStack[-1] = ((unsigned)r1) >> r0;
opStack--;
goto nextInstruction;
case OP_NEGF:
*(float *)opStack = -*(float *)opStack;
goto nextInstruction;
case OP_ADDF:
*(float *)(opStack-1) = *(float *)(opStack-1) + *(float *)opStack;
opStack--;
goto nextInstruction;
case OP_SUBF:
*(float *)(opStack-1) = *(float *)(opStack-1) - *(float *)opStack;
opStack--;
goto nextInstruction;
case OP_DIVF:
*(float *)(opStack-1) = *(float *)(opStack-1) / *(float *)opStack;
opStack--;
goto nextInstruction;
case OP_MULF:
*(float *)(opStack-1) = *(float *)(opStack-1) * *(float *)opStack;
opStack--;
goto nextInstruction;
case OP_CVIF:
*(float *)opStack = (float)*opStack;
goto nextInstruction;
case OP_CVFI:
*opStack = (int) *(float *)opStack;
goto nextInstruction;
case OP_SEX8:
*opStack = (signed char)*opStack;
goto nextInstruction;
case OP_SEX16:
*opStack = (short)*opStack;
goto nextInstruction;
}
}
done:
vm->currentlyInterpreting = qfalse;
if ( opStack != &stack[1] ) {
Com_Error( ERR_DROP, "Interpreter error: opStack = %i", opStack - stack );
}
vm->programStack = stackOnEntry;
// return the result
return *opStack;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -