⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm_ppc_new.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 5 页
字号:
            case OP_BREAK:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08lx BREAK\n",instruction);
		#endif
                InstImmU( "addi", PPC_ADDI, R_TOP, 0, 0 );
                InstImm( "lwz", PPC_LWZ, R_TOP, R_TOP, 0 );			// *(int *)0 to crash to debugger
                break;
            case OP_ENTER:
		opStackDepth = 0;
		v = Constant4();
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x ENTER\t%04x\n",instruction,v);
		#endif
		opStackRegType[opStackDepth] = 0;
		mainFunction++;
		if(mainFunction == 1)
		{
			// Main VM entry point is the first thing we compile, so save off operand stack
			// registers here.  This avoids issues with trying to trick the native compiler
			// into doing it, and properly matches the PowerPC ABI
			InstImm( "addi", PPC_ADDI, R_REAL_STACK, R_REAL_STACK, -OP_STACK_MAX_DEPTH*4 );	// sub R_STACK, R_STACK, imm
			for(i = 0; i < OP_STACK_MAX_DEPTH; i++)
				InstImm( "stw", PPC_STW, opStackIntRegisters[i], R_REAL_STACK, i*4);
		}
                InstImm( "addi", PPC_ADDI, R_STACK, R_STACK, -v );	// sub R_STACK, R_STACK, imm
                break;
            case OP_CONST:
                v = Constant4();
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x CONST\t%08x\n",instruction,v);
		#endif
		opStackLoadInstructionAddr[opStackDepth] = 0;
                if ( v < 32768 && v >= -32768 ) {
                    InstImmU( "addi", PPC_ADDI, opStackIntRegisters[opStackDepth], 0, v & 0xffff );
                } else {
                    InstImmU( "addis", PPC_ADDIS, opStackIntRegisters[opStackDepth], 0, (v >> 16)&0xffff );
                    if ( v & 0xffff ) {
                        InstImmU( "ori", PPC_ORI, opStackIntRegisters[opStackDepth], opStackIntRegisters[opStackDepth], v & 0xffff );
                    }
                }
		opStackRegType[opStackDepth] = 1;
		opStackDepth += 1;
		if (code[pc] == OP_JUMP) {
		    jused[v] = 1;
		}
		break;
            case OP_LOCAL:
		oc1 = Constant4();
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x LOCAL\t%08x\n",instruction,oc1);
		#endif
		if (code[pc] == OP_LOAD4 || code[pc] == OP_LOAD2 || code[pc] == OP_LOAD1) {
		    oc1 &= vm->dataMask;
		}
                InstImm( "addi", PPC_ADDI, opStackIntRegisters[opStackDepth], R_STACK, oc1 );
		opStackRegType[opStackDepth] = 1;
		opStackLoadInstructionAddr[opStackDepth] = 0;
		opStackDepth += 1;
                break;
            case OP_ARG:
		v = Constant1();
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x ARG \t%08x\n",instruction,v);
		#endif
                InstImm( "addi", PPC_ADDI, R_EA, R_STACK, v );	// location to put it
		if(opStackRegType[opStackDepth-1] == 1)
			Inst( "stwx", PPC_STWX, opStackIntRegisters[opStackDepth-1], R_EA, R_MEMBASE );
		else
			Inst( "stfsx", PPC_STFSX, opStackFloatRegisters[opStackDepth-1], R_EA, R_MEMBASE );
		opStackRegType[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackDepth -= 1;
		
                break;
            case OP_CALL:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x CALL\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assert(opStackDepth > 0);
                Inst( "mflr", PPC_MFSPR, R_SECOND, 8, 0 );			// move from link register
                InstImm( "stwu", PPC_STWU, R_SECOND, R_REAL_STACK, -16 );	// save off the old return address

		// Spill operand stack registers.
		spillOpStack(opStackDepth);
		
		// We need to leave R_OPSTACK pointing to the top entry on the stack, which is the call address.
		// It will be consumed (and R4 decremented) by the AsmCall code.
		InstImm( "addi", PPC_ADDI, R_OPSTACK, R_OPSTACK, opStackDepth*4);

                Inst( "mtctr", PPC_MTSPR, R_ASMCALL, 9, 0 );			// move to count register
                Inst( "bctrl", PPC_BCCTR | 1, 20, 0, 0 );			// jump and link to the count register

		// R4 now points to the top of the operand stack, which has the return value in it.  We want to
		// back off the pointer to point to the base of our local operand stack and then reload the stack.
		
		InstImm("addi", PPC_ADDI, R_OPSTACK, R_OPSTACK, -opStackDepth*4);
		
		// Reload operand stack.
		loadOpStack(opStackDepth);

                InstImm( "lwz", PPC_LWZ, R_SECOND, R_REAL_STACK, 0 );		// fetch the old return address
                InstImm( "addi", PPC_ADDI, R_REAL_STACK, R_REAL_STACK, 16 );
                Inst( "mtlr", PPC_MTSPR, R_SECOND, 8, 0 );			// move to link register
                break;
            case OP_PUSH:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x PUSH\n",instruction);
		#endif
		opStackRegType[opStackDepth] = 1; 	// Garbage int value.
		opStackDepth += 1;
                break;
            case OP_POP:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x POP\n",instruction);
		#endif
		opStackDepth -= 1;
		opStackRegType[opStackDepth] = 0; 	// ??
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
                break;
            case OP_LEAVE:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x LEAVE\n",instruction);
		#endif
		assert(opStackDepth == 1);
		assert(opStackRegType[0] != 0);
		// Save return value onto top of op stack.  We also have to increment R_OPSTACK
		switch(opStackRegType[0])
		{
			case 1:	// Integer register
				InstImm( "stw", PPC_STWU, opStackIntRegisters[0], R_OPSTACK, 4);
				break;
			case 2: // Float register
				InstImm( "stfs", PPC_STFSU, opStackFloatRegisters[0], R_OPSTACK, 4);
				break;
		}
                InstImm( "addi", PPC_ADDI, R_STACK, R_STACK, Constant4() );	// add R_STACK, R_STACK, imm
		if(mainFunction == 1)
		{
			for(i = 0; i < OP_STACK_MAX_DEPTH; i++)
				InstImm( "lwz", PPC_LWZ,  opStackIntRegisters[i], R_REAL_STACK, i*4);
			InstImm( "addi", PPC_ADDI, R_REAL_STACK, R_REAL_STACK, OP_STACK_MAX_DEPTH*4 );	
		}
		opStackDepth--;
		opStackRegType[opStackDepth] = 0;
		opStackLoadInstructionAddr[opStackDepth] = 0;
                Inst( "blr", PPC_BCLR, 20, 0, 0 );							// branch unconditionally to link register
                break;
            case OP_LOAD4:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x LOAD4\n",instruction);
		#endif
		// We should try to figure out whether to use LWZX or LFSX based
		// on some kind of code analysis after subsequent passes.  I think what
		// we could do is store the compiled load instruction address along with
		// the register type.  When we hit the first mismatched operator, we go back
		// and patch the load.  Since LCC's operand stack should be at 0 depth by the
		// time we hit a branch, this should work fairly well.  FIXME FIXME FIXME.
		assertInteger(opStackDepth-1);
		opStackLoadInstructionAddr[opStackDepth-1] = &buf[ compiledOfs ];
                Inst( "lwzx", PPC_LWZX, opStackIntRegisters[opStackDepth-1], opStackIntRegisters[opStackDepth-1], R_MEMBASE );// load from memory base
		opStackRegType[opStackDepth-1] = 1;
                break;
            case OP_LOAD2:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x LOAD2\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
                Inst( "lhzx", PPC_LHZX, opStackIntRegisters[opStackDepth-1], opStackIntRegisters[opStackDepth-1], R_MEMBASE );// load from memory base
		opStackRegType[opStackDepth-1] = 1;
                break;
            case OP_LOAD1:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x LOAD1\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
                Inst( "lbzx", PPC_LBZX, opStackIntRegisters[opStackDepth-1], opStackIntRegisters[opStackDepth-1], R_MEMBASE );// load from memory base
		opStackRegType[opStackDepth-1] = 1;
                break;
            case OP_STORE4:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x STORE4\n",instruction);
		#endif
		assertInteger(opStackDepth-2);
		if(opStackRegType[opStackDepth-1] == 1)
			Inst( "stwx", PPC_STWX, opStackIntRegisters[opStackDepth-1], 
					opStackIntRegisters[opStackDepth-2], R_MEMBASE );		// store from memory base
		else
			Inst( "stfsx", PPC_STFSX, opStackFloatRegisters[opStackDepth-1], 
					opStackIntRegisters[opStackDepth-2], R_MEMBASE );		// store from memory base
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                break;
            case OP_STORE2:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x STORE2\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "sthx", PPC_STHX, opStackIntRegisters[opStackDepth-1],
				opStackIntRegisters[opStackDepth-2], R_MEMBASE );		// store from memory base
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                break;
            case OP_STORE1:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x STORE1\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "stbx", PPC_STBX, opStackIntRegisters[opStackDepth-1],
				opStackIntRegisters[opStackDepth-2], R_MEMBASE );		// store from memory base
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                break;

            case OP_EQ:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x EQ\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 4, 2, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];                    
                } else {
                    v = 0;             
                }
                Emit4("b", PPC_B | (v&0x3ffffff) );
                break;
            case OP_NE:
		#if DEBUG_VM
		if(pass == 1)
			printf("%08x NE\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 12, 2, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];                    
                } else {
                    v = 0;
                }
                Emit4("b", PPC_B | (unsigned int)(v&0x3ffffff) );
//                InstImm( "bc", PPC_BC, 4, 2, v );

                break;
            case OP_LTI:
		#if DEBUG_VM
		if(pass == 1)
		printf("%08x LTI\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 4, 0, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
                } else {
                    v = 0;
                }
                Emit4("b", PPC_B | (unsigned int)(v&0x3ffffff) );
//                InstImm( "bc", PPC_BC, 12, 0, v );
                break;
            case OP_LEI:
		#if DEBUG_VM
		if(pass == 1)
		printf("%08x LEI\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 12, 1, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
                } else {
                    v = 0;
                }
                Emit4("b", PPC_B | (unsigned int)(v&0x3ffffff) );
//                InstImm( "bc", PPC_BC, 4, 1, v );
                break;
            case OP_GTI:
		#if DEBUG_VM
		if(pass == 1)
		printf("%08x GTI\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 4, 1, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
                } else {
                    v = 0;
                }
                Emit4("b", PPC_B | (unsigned int)(v&0x3ffffff) );
//                InstImm( "bc", PPC_BC, 12, 1, v );
                break;
            case OP_GEI:
		#if DEBUG_VM
		if(pass == 1)
		printf("%08x GEI\n",instruction);
		#endif
		assertInteger(opStackDepth-1);
		assertInteger(opStackDepth-2);
                Inst( "cmp", PPC_CMP, 0, opStackIntRegisters[opStackDepth-2], opStackIntRegisters[opStackDepth-1] );
		opStackRegType[opStackDepth-1] = 0;
		opStackRegType[opStackDepth-2] = 0;
		opStackLoadInstructionAddr[opStackDepth-1] = 0;
		opStackLoadInstructionAddr[opStackDepth-2] = 0;
		opStackDepth -= 2;
                i = Constant4();
				jused[i] = 1;
                InstImm( "bc", PPC_BC, 12, 0, 8 );
                if ( pass==1 ) {
                    v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
                } else {
                    v = 0;
                }
                Emit4("b", PPC_B | (unsigned int)(v&0x3ffffff) );
//                InstImm( "bc", PPC_BC, 4, 0, v );
                break;
            case OP_LTU:
		#if DEBUG_VM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -