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

📄 translate.c

📁 QEMU 0.91 source code, supports ARM processor including S3C24xx series
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  MIPS32 emulation for qemu: main translation routines. * *  Copyright (c) 2004-2005 Jocelyn Mayer *  Copyright (c) 2006 Marius Groeger (FPU operations) *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include "cpu.h"#include "exec-all.h"#include "disas.h"//#define MIPS_DEBUG_DISAS//#define MIPS_DEBUG_SIGN_EXTENSIONS//#define MIPS_SINGLE_STEP#ifdef USE_DIRECT_JUMP#define TBPARAM(x)#else#define TBPARAM(x) (long)(x)#endifenum {#define DEF(s, n, copy_size) INDEX_op_ ## s,#include "opc.h"#undef DEF    NB_OPS,};static uint16_t *gen_opc_ptr;static uint32_t *gen_opparam_ptr;#include "gen-op.h"/* MIPS major opcodes */#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))enum {    /* indirect opcode tables */    OPC_SPECIAL  = (0x00 << 26),    OPC_REGIMM   = (0x01 << 26),    OPC_CP0      = (0x10 << 26),    OPC_CP1      = (0x11 << 26),    OPC_CP2      = (0x12 << 26),    OPC_CP3      = (0x13 << 26),    OPC_SPECIAL2 = (0x1C << 26),    OPC_SPECIAL3 = (0x1F << 26),    /* arithmetic with immediate */    OPC_ADDI     = (0x08 << 26),    OPC_ADDIU    = (0x09 << 26),    OPC_SLTI     = (0x0A << 26),    OPC_SLTIU    = (0x0B << 26),    OPC_ANDI     = (0x0C << 26),    OPC_ORI      = (0x0D << 26),    OPC_XORI     = (0x0E << 26),    OPC_LUI      = (0x0F << 26),    OPC_DADDI    = (0x18 << 26),    OPC_DADDIU   = (0x19 << 26),    /* Jump and branches */    OPC_J        = (0x02 << 26),    OPC_JAL      = (0x03 << 26),    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */    OPC_BEQL     = (0x14 << 26),    OPC_BNE      = (0x05 << 26),    OPC_BNEL     = (0x15 << 26),    OPC_BLEZ     = (0x06 << 26),    OPC_BLEZL    = (0x16 << 26),    OPC_BGTZ     = (0x07 << 26),    OPC_BGTZL    = (0x17 << 26),    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */    /* Load and stores */    OPC_LDL      = (0x1A << 26),    OPC_LDR      = (0x1B << 26),    OPC_LB       = (0x20 << 26),    OPC_LH       = (0x21 << 26),    OPC_LWL      = (0x22 << 26),    OPC_LW       = (0x23 << 26),    OPC_LBU      = (0x24 << 26),    OPC_LHU      = (0x25 << 26),    OPC_LWR      = (0x26 << 26),    OPC_LWU      = (0x27 << 26),    OPC_SB       = (0x28 << 26),    OPC_SH       = (0x29 << 26),    OPC_SWL      = (0x2A << 26),    OPC_SW       = (0x2B << 26),    OPC_SDL      = (0x2C << 26),    OPC_SDR      = (0x2D << 26),    OPC_SWR      = (0x2E << 26),    OPC_LL       = (0x30 << 26),    OPC_LLD      = (0x34 << 26),    OPC_LD       = (0x37 << 26),    OPC_SC       = (0x38 << 26),    OPC_SCD      = (0x3C << 26),    OPC_SD       = (0x3F << 26),    /* Floating point load/store */    OPC_LWC1     = (0x31 << 26),    OPC_LWC2     = (0x32 << 26),    OPC_LDC1     = (0x35 << 26),    OPC_LDC2     = (0x36 << 26),    OPC_SWC1     = (0x39 << 26),    OPC_SWC2     = (0x3A << 26),    OPC_SDC1     = (0x3D << 26),    OPC_SDC2     = (0x3E << 26),    /* MDMX ASE specific */    OPC_MDMX     = (0x1E << 26),    /* Cache and prefetch */    OPC_CACHE    = (0x2F << 26),    OPC_PREF     = (0x33 << 26),    /* Reserved major opcode */    OPC_MAJOR3B_RESERVED = (0x3B << 26),};/* MIPS special opcodes */#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)enum {    /* Shifts */    OPC_SLL      = 0x00 | OPC_SPECIAL,    /* NOP is SLL r0, r0, 0   */    /* SSNOP is SLL r0, r0, 1 */    /* EHB is SLL r0, r0, 3 */    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */    OPC_SRA      = 0x03 | OPC_SPECIAL,    OPC_SLLV     = 0x04 | OPC_SPECIAL,    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */    OPC_SRAV     = 0x07 | OPC_SPECIAL,    OPC_DSLLV    = 0x14 | OPC_SPECIAL,    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */    OPC_DSRAV    = 0x17 | OPC_SPECIAL,    OPC_DSLL     = 0x38 | OPC_SPECIAL,    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */    OPC_DSRA     = 0x3B | OPC_SPECIAL,    OPC_DSLL32   = 0x3C | OPC_SPECIAL,    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */    OPC_DSRA32   = 0x3F | OPC_SPECIAL,    /* Multiplication / division */    OPC_MULT     = 0x18 | OPC_SPECIAL,    OPC_MULTU    = 0x19 | OPC_SPECIAL,    OPC_DIV      = 0x1A | OPC_SPECIAL,    OPC_DIVU     = 0x1B | OPC_SPECIAL,    OPC_DMULT    = 0x1C | OPC_SPECIAL,    OPC_DMULTU   = 0x1D | OPC_SPECIAL,    OPC_DDIV     = 0x1E | OPC_SPECIAL,    OPC_DDIVU    = 0x1F | OPC_SPECIAL,    /* 2 registers arithmetic / logic */    OPC_ADD      = 0x20 | OPC_SPECIAL,    OPC_ADDU     = 0x21 | OPC_SPECIAL,    OPC_SUB      = 0x22 | OPC_SPECIAL,    OPC_SUBU     = 0x23 | OPC_SPECIAL,    OPC_AND      = 0x24 | OPC_SPECIAL,    OPC_OR       = 0x25 | OPC_SPECIAL,    OPC_XOR      = 0x26 | OPC_SPECIAL,    OPC_NOR      = 0x27 | OPC_SPECIAL,    OPC_SLT      = 0x2A | OPC_SPECIAL,    OPC_SLTU     = 0x2B | OPC_SPECIAL,    OPC_DADD     = 0x2C | OPC_SPECIAL,    OPC_DADDU    = 0x2D | OPC_SPECIAL,    OPC_DSUB     = 0x2E | OPC_SPECIAL,    OPC_DSUBU    = 0x2F | OPC_SPECIAL,    /* Jumps */    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */    /* Traps */    OPC_TGE      = 0x30 | OPC_SPECIAL,    OPC_TGEU     = 0x31 | OPC_SPECIAL,    OPC_TLT      = 0x32 | OPC_SPECIAL,    OPC_TLTU     = 0x33 | OPC_SPECIAL,    OPC_TEQ      = 0x34 | OPC_SPECIAL,    OPC_TNE      = 0x36 | OPC_SPECIAL,    /* HI / LO registers load & stores */    OPC_MFHI     = 0x10 | OPC_SPECIAL,    OPC_MTHI     = 0x11 | OPC_SPECIAL,    OPC_MFLO     = 0x12 | OPC_SPECIAL,    OPC_MTLO     = 0x13 | OPC_SPECIAL,    /* Conditional moves */    OPC_MOVZ     = 0x0A | OPC_SPECIAL,    OPC_MOVN     = 0x0B | OPC_SPECIAL,    OPC_MOVCI    = 0x01 | OPC_SPECIAL,    /* Special */    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,    OPC_BREAK    = 0x0D | OPC_SPECIAL,    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */    OPC_SYNC     = 0x0F | OPC_SPECIAL,    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,};/* Multiplication variants of the vr54xx. */#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))enum {    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,};/* REGIMM (rt field) opcodes */#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))enum {    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,};/* Special2 opcodes */#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)enum {    /* Multiply & xxx operations */    OPC_MADD     = 0x00 | OPC_SPECIAL2,    OPC_MADDU    = 0x01 | OPC_SPECIAL2,    OPC_MUL      = 0x02 | OPC_SPECIAL2,    OPC_MSUB     = 0x04 | OPC_SPECIAL2,    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,    /* Misc */    OPC_CLZ      = 0x20 | OPC_SPECIAL2,    OPC_CLO      = 0x21 | OPC_SPECIAL2,    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,    OPC_DCLO     = 0x25 | OPC_SPECIAL2,    /* Special */    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,};/* Special3 opcodes */#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)enum {    OPC_EXT      = 0x00 | OPC_SPECIAL3,    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,    OPC_DEXT     = 0x03 | OPC_SPECIAL3,    OPC_INS      = 0x04 | OPC_SPECIAL3,    OPC_DINSM    = 0x05 | OPC_SPECIAL3,    OPC_DINSU    = 0x06 | OPC_SPECIAL3,    OPC_DINS     = 0x07 | OPC_SPECIAL3,    OPC_FORK     = 0x08 | OPC_SPECIAL3,    OPC_YIELD    = 0x09 | OPC_SPECIAL3,    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,};/* BSHFL opcodes */#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))enum {    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,};/* DBSHFL opcodes */#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))enum {    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,};/* Coprocessor 0 (rs field) */#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))enum {    OPC_MFC0     = (0x00 << 21) | OPC_CP0,    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,    OPC_MTC0     = (0x04 << 21) | OPC_CP0,    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,    OPC_MFTR     = (0x08 << 21) | OPC_CP0,    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,    OPC_MTTR     = (0x0C << 21) | OPC_CP0,    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,    OPC_C0       = (0x10 << 21) | OPC_CP0,    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,};/* MFMC0 opcodes */#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)enum {    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,};/* Coprocessor 0 (with rs == C0) */#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)enum {    OPC_TLBR     = 0x01 | OPC_C0,    OPC_TLBWI    = 0x02 | OPC_C0,    OPC_TLBWR    = 0x06 | OPC_C0,    OPC_TLBP     = 0x08 | OPC_C0,    OPC_RFE      = 0x10 | OPC_C0,    OPC_ERET     = 0x18 | OPC_C0,    OPC_DERET    = 0x1F | OPC_C0,    OPC_WAIT     = 0x20 | OPC_C0,};/* Coprocessor 1 (rs field) */#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))enum {    OPC_MFC1     = (0x00 << 21) | OPC_CP1,    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,    OPC_CFC1     = (0x02 << 21) | OPC_CP1,    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,    OPC_MTC1     = (0x04 << 21) | OPC_CP1,    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,    OPC_CTC1     = (0x06 << 21) | OPC_CP1,    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */};#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))enum {    OPC_BC1F     = (0x00 << 16) | OPC_BC1,    OPC_BC1T     = (0x01 << 16) | OPC_BC1,    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,};enum {    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,};enum {    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,};#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))enum {    OPC_MFC2    = (0x00 << 21) | OPC_CP2,    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,    OPC_CFC2    = (0x02 << 21) | OPC_CP2,    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,    OPC_MTC2    = (0x04 << 21) | OPC_CP2,    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,    OPC_CTC2    = (0x06 << 21) | OPC_CP2,    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,    OPC_BC2     = (0x08 << 21) | OPC_CP2,};#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)enum {    OPC_LWXC1   = 0x00 | OPC_CP3,    OPC_LDXC1   = 0x01 | OPC_CP3,    OPC_LUXC1   = 0x05 | OPC_CP3,    OPC_SWXC1   = 0x08 | OPC_CP3,    OPC_SDXC1   = 0x09 | OPC_CP3,    OPC_SUXC1   = 0x0D | OPC_CP3,    OPC_PREFX   = 0x0F | OPC_CP3,    OPC_ALNV_PS = 0x1E | OPC_CP3,    OPC_MADD_S  = 0x20 | OPC_CP3,    OPC_MADD_D  = 0x21 | OPC_CP3,    OPC_MADD_PS = 0x26 | OPC_CP3,    OPC_MSUB_S  = 0x28 | OPC_CP3,    OPC_MSUB_D  = 0x29 | OPC_CP3,    OPC_MSUB_PS = 0x2E | OPC_CP3,    OPC_NMADD_S = 0x30 | OPC_CP3,    OPC_NMADD_D = 0x31 | OPC_CP3,    OPC_NMADD_PS= 0x36 | OPC_CP3,

⌨️ 快捷键说明

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