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

📄 vm_ppc.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
===========================================================================
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_ppc.c
// ppc dynamic compiler

#include "vm_local.h"

#pragma opt_pointer_analysis off


typedef enum {
    R_REAL_STACK = 1,
	// registers 3-11 are the parameter passing registers
	
	// state
	R_STACK = 3,			// local
	R_OPSTACK,				// global

	// constants	
	R_MEMBASE,			// global
	R_MEMMASK,
	R_ASMCALL,			// global
    R_INSTRUCTIONS,		// global
    R_NUM_INSTRUCTIONS,	// global
    R_CVM,				// currentVM
    
	// temps
	R_TOP = 11,
	R_SECOND = 12,
	R_EA = 2				// effective address calculation
	 
} regNums_t;

#define	RG_REAL_STACK		r1
#define	RG_STACK			r3
#define	RG_OPSTACK			r4
#define	RG_MEMBASE			r5
#define	RG_MEMMASK			r6
#define	RG_ASMCALL			r7
#define	RG_INSTRUCTIONS		r8
#define	RG_NUM_INSTRUCTIONS	r9
#define	RG_CVM				r10
#define	RG_TOP				r12
#define	RG_SECOND			r13
#define	RG_EA 				r14

// this doesn't have the low order bits set for instructions i'm not using...
typedef enum {
	PPC_TDI		= 0x08000000,
	PPC_TWI		= 0x0c000000,
	PPC_MULLI	= 0x1c000000,
	PPC_SUBFIC	= 0x20000000,
	PPC_CMPI	= 0x28000000,
	PPC_CMPLI	= 0x2c000000,
	PPC_ADDIC	= 0x30000000,
	PPC_ADDIC_	= 0x34000000,
	PPC_ADDI	= 0x38000000,
	PPC_ADDIS	= 0x3c000000,
	PPC_BC		= 0x40000000,
	PPC_SC		= 0x44000000,
	PPC_B		= 0x48000000,

	PPC_MCRF	= 0x4c000000,
	PPC_BCLR	= 0x4c000020,
	PPC_RFID	= 0x4c000000,
	PPC_CRNOR	= 0x4c000000,
	PPC_RFI		= 0x4c000000,
	PPC_CRANDC	= 0x4c000000,
	PPC_ISYNC	= 0x4c000000,
	PPC_CRXOR	= 0x4c000000,
	PPC_CRNAND	= 0x4c000000,
	PPC_CREQV	= 0x4c000000,
	PPC_CRORC	= 0x4c000000,
	PPC_CROR	= 0x4c000000,
//------------
	PPC_BCCTR	= 0x4c000420,
	PPC_RLWIMI	= 0x50000000,
	PPC_RLWINM	= 0x54000000,
	PPC_RLWNM	= 0x5c000000,
	PPC_ORI		= 0x60000000,
	PPC_ORIS	= 0x64000000,
	PPC_XORI	= 0x68000000,
	PPC_XORIS	= 0x6c000000,
	PPC_ANDI_	= 0x70000000,
	PPC_ANDIS_	= 0x74000000,
	PPC_RLDICL	= 0x78000000,
	PPC_RLDICR	= 0x78000000,
	PPC_RLDIC	= 0x78000000,
	PPC_RLDIMI	= 0x78000000,
	PPC_RLDCL	= 0x78000000,
	PPC_RLDCR	= 0x78000000,
	PPC_CMP		= 0x7c000000,
	PPC_TW		= 0x7c000000,
	PPC_SUBFC	= 0x7c000010,
	PPC_MULHDU	= 0x7c000000,
	PPC_ADDC	= 0x7c000014,
	PPC_MULHWU	= 0x7c000000,
	PPC_MFCR	= 0x7c000000,
	PPC_LWAR	= 0x7c000000,
	PPC_LDX		= 0x7c000000,
	PPC_LWZX	= 0x7c00002e,
	PPC_SLW		= 0x7c000030,
	PPC_CNTLZW	= 0x7c000000,
	PPC_SLD		= 0x7c000000,
	PPC_AND		= 0x7c000038,
	PPC_CMPL	= 0x7c000040,
	PPC_SUBF	= 0x7c000050,
	PPC_LDUX	= 0x7c000000,
//------------
	PPC_DCBST	= 0x7c000000,
	PPC_LWZUX	= 0x7c00006c,
	PPC_CNTLZD	= 0x7c000000,
	PPC_ANDC	= 0x7c000000,
	PPC_TD		= 0x7c000000,
	PPC_MULHD	= 0x7c000000,
	PPC_MULHW	= 0x7c000000,
	PPC_MTSRD	= 0x7c000000,
	PPC_MFMSR	= 0x7c000000,
	PPC_LDARX	= 0x7c000000,
	PPC_DCBF	= 0x7c000000,
	PPC_LBZX	= 0x7c0000ae,
	PPC_NEG		= 0x7c000000,
	PPC_MTSRDIN	= 0x7c000000,
	PPC_LBZUX	= 0x7c000000,
	PPC_NOR		= 0x7c0000f8,
	PPC_SUBFE	= 0x7c000000,
	PPC_ADDE	= 0x7c000000,
	PPC_MTCRF	= 0x7c000000,
	PPC_MTMSR	= 0x7c000000,
	PPC_STDX	= 0x7c000000,
	PPC_STWCX_	= 0x7c000000,
	PPC_STWX	= 0x7c00012e,
	PPC_MTMSRD	= 0x7c000000,
	PPC_STDUX	= 0x7c000000,
	PPC_STWUX	= 0x7c00016e,
	PPC_SUBFZE	= 0x7c000000,
	PPC_ADDZE	= 0x7c000000,
	PPC_MTSR	= 0x7c000000,
	PPC_STDCX_	= 0x7c000000,
	PPC_STBX	= 0x7c0001ae,
	PPC_SUBFME	= 0x7c000000,
	PPC_MULLD	= 0x7c000000,
//------------
	PPC_ADDME	= 0x7c000000,
	PPC_MULLW	= 0x7c0001d6,
	PPC_MTSRIN	= 0x7c000000,
	PPC_DCBTST	= 0x7c000000,
	PPC_STBUX	= 0x7c000000,
	PPC_ADD		= 0x7c000214,
	PPC_DCBT	= 0x7c000000,
	PPC_LHZX	= 0x7c00022e,
	PPC_EQV		= 0x7c000000,
	PPC_TLBIE	= 0x7c000000,
	PPC_ECIWX	= 0x7c000000,
	PPC_LHZUX	= 0x7c000000,
	PPC_XOR		= 0x7c000278,
	PPC_MFSPR	= 0x7c0002a6,
	PPC_LWAX	= 0x7c000000,
	PPC_LHAX	= 0x7c000000,
	PPC_TLBIA	= 0x7c000000,
	PPC_MFTB	= 0x7c000000,
	PPC_LWAUX	= 0x7c000000,
	PPC_LHAUX	= 0x7c000000,
	PPC_STHX	= 0x7c00032e,
	PPC_ORC		= 0x7c000338,
	PPC_SRADI	= 0x7c000000,
	PPC_SLBIE	= 0x7c000000,
	PPC_ECOWX	= 0x7c000000,
	PPC_STHUX	= 0x7c000000,
	PPC_OR		= 0x7c000378,
	PPC_DIVDU	= 0x7c000000,
	PPC_DIVWU	= 0x7c000396,
	PPC_MTSPR	= 0x7c0003a6,
	PPC_DCBI	= 0x7c000000,
	PPC_NAND	= 0x7c000000,
	PPC_DIVD	= 0x7c000000,
//------------
	PPC_DIVW	= 0x7c0003d6,
	PPC_SLBIA	= 0x7c000000,
	PPC_MCRXR	= 0x7c000000,
	PPC_LSWX	= 0x7c000000,
	PPC_LWBRX	= 0x7c000000,
	PPC_LFSX	= 0x7c000000,
	PPC_SRW		= 0x7c000430,
	PPC_SRD		= 0x7c000000,
	PPC_TLBSYNC	= 0x7c000000,
	PPC_LFSUX	= 0x7c000000,
	PPC_MFSR	= 0x7c000000,
	PPC_LSWI	= 0x7c000000,
	PPC_SYNC	= 0x7c000000,
	PPC_LFDX	= 0x7c000000,
	PPC_LFDUX	= 0x7c000000,
	PPC_MFSRIN	= 0x7c000000,
	PPC_STSWX	= 0x7c000000,
	PPC_STWBRX	= 0x7c000000,
	PPC_STFSX	= 0x7c000000,
	PPC_STFSUX	= 0x7c000000,
	PPC_STSWI	= 0x7c000000,
	PPC_STFDX	= 0x7c000000,
	PPC_DCBA	= 0x7c000000,
	PPC_STFDUX	= 0x7c000000,
	PPC_LHBRX	= 0x7c000000,
	PPC_SRAW	= 0x7c000630,
	PPC_SRAD	= 0x7c000000,
	PPC_SRAWI	= 0x7c000000,
	PPC_EIEIO	= 0x7c000000,
	PPC_STHBRX	= 0x7c000000,
	PPC_EXTSH	= 0x7c000734,
	PPC_EXTSB	= 0x7c000774,
	PPC_ICBI	= 0x7c000000,
//------------
	PPC_STFIWX	= 0x7c0007ae,
	PPC_EXTSW	= 0x7c000000,
	PPC_DCBZ	= 0x7c000000,
	PPC_LWZ		= 0x80000000,
	PPC_LWZU	= 0x84000000,
	PPC_LBZ		= 0x88000000,
	PPC_LBZU	= 0x8c000000,
	PPC_STW		= 0x90000000,
	PPC_STWU	= 0x94000000,
	PPC_STB		= 0x98000000,
	PPC_STBU	= 0x9c000000,
	PPC_LHZ		= 0xa0000000,
	PPC_LHZU	= 0xa4000000,
	PPC_LHA		= 0xa8000000,
	PPC_LHAU	= 0xac000000,
	PPC_STH		= 0xb0000000,
	PPC_STHU	= 0xb4000000,
	PPC_LMW		= 0xb8000000,
	PPC_STMW	= 0xbc000000,
	PPC_LFS		= 0xc0000000,
	PPC_LFSU	= 0xc4000000,
	PPC_LFD		= 0xc8000000,
	PPC_LFDU	= 0xcc000000,
	PPC_STFS	= 0xd0000000,
	PPC_STFSU	= 0xd4000000,
	PPC_STFD	= 0xd8000000,
	PPC_STFDU	= 0xdc000000,
	PPC_LD		= 0xe8000000,
	PPC_LDU		= 0xe8000001,
	PPC_LWA		= 0xe8000002,
	PPC_FDIVS	= 0xec000024,
	PPC_FSUBS	= 0xec000028,
	PPC_FADDS	= 0xec00002a,
//------------
	PPC_FSQRTS	= 0xec000000,
	PPC_FRES	= 0xec000000,
	PPC_FMULS	= 0xec000032,
	PPC_FMSUBS	= 0xec000000,
	PPC_FMADDS	= 0xec000000,
	PPC_FNMSUBS	= 0xec000000,
	PPC_FNMADDS	= 0xec000000,
	PPC_STD		= 0xf8000000,
	PPC_STDU	= 0xf8000001,
	PPC_FCMPU	= 0xfc000000,
	PPC_FRSP	= 0xfc000018,
	PPC_FCTIW	= 0xfc000000,
	PPC_FCTIWZ	= 0xfc00001e,
	PPC_FDIV	= 0xfc000000,
	PPC_FSUB	= 0xfc000028,
	PPC_FADD	= 0xfc000000,
	PPC_FSQRT	= 0xfc000000,
	PPC_FSEL	= 0xfc000000,
	PPC_FMUL	= 0xfc000000,
	PPC_FRSQRTE	= 0xfc000000,
	PPC_FMSUB	= 0xfc000000,
	PPC_FMADD	= 0xfc000000,
	PPC_FNMSUB	= 0xfc000000,
	PPC_FNMADD	= 0xfc000000,
	PPC_FCMPO	= 0xfc000000,
	PPC_MTFSB1	= 0xfc000000,
	PPC_FNEG	= 0xfc000050,
	PPC_MCRFS	= 0xfc000000,
	PPC_MTFSB0	= 0xfc000000,
	PPC_FMR		= 0xfc000000,
	PPC_MTFSFI	= 0xfc000000,
	PPC_FNABS	= 0xfc000000,
	PPC_FABS	= 0xfc000000,
//------------
	PPC_MFFS	= 0xfc000000,
	PPC_MTFSF	= 0xfc000000,
	PPC_FCTID	= 0xfc000000,
	PPC_FCTIDZ	= 0xfc000000,
	PPC_FCFID	= 0xfc000000
	
} ppcOpcodes_t;


// the newly generated code
static	unsigned	*buf;
static	int		compiledOfs;	// in dwords

// fromt the original bytecode
static	byte	*code;
static	int		pc;

void AsmCall( void );

double	itofConvert[2];

static int	Constant4( void ) {
	int		v;

	v = code[pc] | (code[pc+1]<<8) | (code[pc+2]<<16) | (code[pc+3]<<24);
	pc += 4;
	return v;
}

static int	Constant1( void ) {
	int		v;

	v = code[pc];
	pc += 1;
	return v;
}

static void Emit4( int i ) {
	buf[ compiledOfs ] = i;
	compiledOfs++;
}

static void Inst( int opcode, int destReg, int aReg, int bReg ) {
    unsigned		r;

    r = opcode | ( destReg << 21 ) | ( aReg << 16 ) | ( bReg << 11 ) ;
    buf[ compiledOfs ] = r;
    compiledOfs++;
}

static void Inst4( int opcode, int destReg, int aReg, int bReg, int cReg ) {
    unsigned		r;

    r = opcode | ( destReg << 21 ) | ( aReg << 16 ) | ( bReg << 11 ) | ( cReg << 6 );
    buf[ compiledOfs ] = r;
    compiledOfs++;
}

static void InstImm( int opcode, int destReg, int aReg, int immediate ) {
	unsigned		r;
	
	if ( immediate > 32767 || immediate < -32768 ) {
	    Com_Error( ERR_FATAL, "VM_Compile: immediate value %i out of range, opcode %x,%d,%d", immediate, opcode, destReg, aReg );
	}
	r = opcode | ( destReg << 21 ) | ( aReg << 16 ) | ( immediate & 0xffff );
	buf[ compiledOfs ] = r;
	compiledOfs++;
}

static void InstImmU( int opcode, int destReg, int aReg, int immediate ) {
	unsigned		r;
	

⌨️ 快捷键说明

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