📄 vm_ppc_new.c
字号:
/*
===========================================================================
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
#define DEBUG_VM 0
#if DEBUG_VM
static char *opnames[256] = {
"OP_UNDEF",
"OP_IGNORE",
"OP_BREAK",
"OP_ENTER",
"OP_LEAVE",
"OP_CALL",
"OP_PUSH",
"OP_POP",
"OP_CONST",
"OP_LOCAL",
"OP_JUMP",
//-------------------
"OP_EQ",
"OP_NE",
"OP_LTI",
"OP_LEI",
"OP_GTI",
"OP_GEI",
"OP_LTU",
"OP_LEU",
"OP_GTU",
"OP_GEU",
"OP_EQF",
"OP_NEF",
"OP_LTF",
"OP_LEF",
"OP_GTF",
"OP_GEF",
//-------------------
"OP_LOAD1",
"OP_LOAD2",
"OP_LOAD4",
"OP_STORE1",
"OP_STORE2",
"OP_STORE4",
"OP_ARG",
"OP_BLOCK_COPY",
//-------------------
"OP_SEX8",
"OP_SEX16",
"OP_NEGI",
"OP_ADD",
"OP_SUB",
"OP_DIVI",
"OP_DIVU",
"OP_MODI",
"OP_MODU",
"OP_MULI",
"OP_MULU",
"OP_BAND",
"OP_BOR",
"OP_BXOR",
"OP_BCOM",
"OP_LSH",
"OP_RSHI",
"OP_RSHU",
"OP_NEGF",
"OP_ADDF",
"OP_SUBF",
"OP_DIVF",
"OP_MULF",
"OP_CVIF",
"OP_CVFI"
};
#endif
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
// The deepest value I saw in the Quake3 games was 9.
#define OP_STACK_MAX_DEPTH 12
// These are all volatile and thus must be saved
// upon entry to the VM code.
static int opStackIntRegisters[OP_STACK_MAX_DEPTH] =
{
16, 17, 18, 19,
20, 21, 22, 23,
24, 25, 26, 27
};
static unsigned int *opStackLoadInstructionAddr[OP_STACK_MAX_DEPTH];
// We use different registers for the floating point
// operand stack (these are volatile in the PPC ABI)
static int opStackFloatRegisters[OP_STACK_MAX_DEPTH] =
{
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11
};
static int opStackRegType[OP_STACK_MAX_DEPTH] =
{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
// 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 = 0x7c00042e,
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 = 0x7c00052e,
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -