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

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*   SPARC translation   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>   Copyright (C) 2003-2005 Fabrice Bellard   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 *//*   TODO-list:   Rest of V9 instructions, VIS instructions   NPC/PC static optimisations (use JUMP_TB when possible)   Optimize synthetic instructions   Optional alignment check   128-bit float   Tagged add/sub*/#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 DEBUG_DISAS#define DYNAMIC_PC  1 /* dynamic pc value */#define JUMP_PC     2 /* dynamic pc value which takes only two values                         according to jump_pc[T2] */typedef struct DisasContext {    target_ulong pc;	/* current Program Counter: integer or DYNAMIC_PC */    target_ulong npc;	/* next PC: integer or DYNAMIC_PC or JUMP_PC */    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */    int is_br;    int mem_idx;    struct TranslationBlock *tb;} DisasContext;static uint16_t *gen_opc_ptr;static uint32_t *gen_opparam_ptr;extern FILE *logfile;extern int loglevel;enum {#define DEF(s,n,copy_size) INDEX_op_ ## s,#include "opc.h"#undef DEF    NB_OPS};#include "gen-op.h"// This function uses non-native bit order#define GET_FIELD(X, FROM, TO) \  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))// This function uses the order in the manuals, i.e. bit 0 is 2^0#define GET_FIELD_SP(X, FROM, TO) \    GET_FIELD(X, 31 - (TO), 31 - (FROM))#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), 32 - ((b) - (a) + 1))#ifdef TARGET_SPARC64#define DFPREG(r) (((r & 1) << 6) | (r & 0x1e))#else#define DFPREG(r) (r)#endif#ifdef USE_DIRECT_JUMP#define TBPARAM(x)#else#define TBPARAM(x) (long)(x)#endifstatic int sign_extend(int x, int len){    len = 32 - len;    return (x << len) >> len;}#define IS_IMM (insn & (1<<13))static void disas_sparc_insn(DisasContext * dc);static GenOpFunc *gen_op_movl_TN_reg[2][32] = {    {     gen_op_movl_g0_T0,     gen_op_movl_g1_T0,     gen_op_movl_g2_T0,     gen_op_movl_g3_T0,     gen_op_movl_g4_T0,     gen_op_movl_g5_T0,     gen_op_movl_g6_T0,     gen_op_movl_g7_T0,     gen_op_movl_o0_T0,     gen_op_movl_o1_T0,     gen_op_movl_o2_T0,     gen_op_movl_o3_T0,     gen_op_movl_o4_T0,     gen_op_movl_o5_T0,     gen_op_movl_o6_T0,     gen_op_movl_o7_T0,     gen_op_movl_l0_T0,     gen_op_movl_l1_T0,     gen_op_movl_l2_T0,     gen_op_movl_l3_T0,     gen_op_movl_l4_T0,     gen_op_movl_l5_T0,     gen_op_movl_l6_T0,     gen_op_movl_l7_T0,     gen_op_movl_i0_T0,     gen_op_movl_i1_T0,     gen_op_movl_i2_T0,     gen_op_movl_i3_T0,     gen_op_movl_i4_T0,     gen_op_movl_i5_T0,     gen_op_movl_i6_T0,     gen_op_movl_i7_T0,     },    {     gen_op_movl_g0_T1,     gen_op_movl_g1_T1,     gen_op_movl_g2_T1,     gen_op_movl_g3_T1,     gen_op_movl_g4_T1,     gen_op_movl_g5_T1,     gen_op_movl_g6_T1,     gen_op_movl_g7_T1,     gen_op_movl_o0_T1,     gen_op_movl_o1_T1,     gen_op_movl_o2_T1,     gen_op_movl_o3_T1,     gen_op_movl_o4_T1,     gen_op_movl_o5_T1,     gen_op_movl_o6_T1,     gen_op_movl_o7_T1,     gen_op_movl_l0_T1,     gen_op_movl_l1_T1,     gen_op_movl_l2_T1,     gen_op_movl_l3_T1,     gen_op_movl_l4_T1,     gen_op_movl_l5_T1,     gen_op_movl_l6_T1,     gen_op_movl_l7_T1,     gen_op_movl_i0_T1,     gen_op_movl_i1_T1,     gen_op_movl_i2_T1,     gen_op_movl_i3_T1,     gen_op_movl_i4_T1,     gen_op_movl_i5_T1,     gen_op_movl_i6_T1,     gen_op_movl_i7_T1,     }};static GenOpFunc *gen_op_movl_reg_TN[3][32] = {    {     gen_op_movl_T0_g0,     gen_op_movl_T0_g1,     gen_op_movl_T0_g2,     gen_op_movl_T0_g3,     gen_op_movl_T0_g4,     gen_op_movl_T0_g5,     gen_op_movl_T0_g6,     gen_op_movl_T0_g7,     gen_op_movl_T0_o0,     gen_op_movl_T0_o1,     gen_op_movl_T0_o2,     gen_op_movl_T0_o3,     gen_op_movl_T0_o4,     gen_op_movl_T0_o5,     gen_op_movl_T0_o6,     gen_op_movl_T0_o7,     gen_op_movl_T0_l0,     gen_op_movl_T0_l1,     gen_op_movl_T0_l2,     gen_op_movl_T0_l3,     gen_op_movl_T0_l4,     gen_op_movl_T0_l5,     gen_op_movl_T0_l6,     gen_op_movl_T0_l7,     gen_op_movl_T0_i0,     gen_op_movl_T0_i1,     gen_op_movl_T0_i2,     gen_op_movl_T0_i3,     gen_op_movl_T0_i4,     gen_op_movl_T0_i5,     gen_op_movl_T0_i6,     gen_op_movl_T0_i7,     },    {     gen_op_movl_T1_g0,     gen_op_movl_T1_g1,     gen_op_movl_T1_g2,     gen_op_movl_T1_g3,     gen_op_movl_T1_g4,     gen_op_movl_T1_g5,     gen_op_movl_T1_g6,     gen_op_movl_T1_g7,     gen_op_movl_T1_o0,     gen_op_movl_T1_o1,     gen_op_movl_T1_o2,     gen_op_movl_T1_o3,     gen_op_movl_T1_o4,     gen_op_movl_T1_o5,     gen_op_movl_T1_o6,     gen_op_movl_T1_o7,     gen_op_movl_T1_l0,     gen_op_movl_T1_l1,     gen_op_movl_T1_l2,     gen_op_movl_T1_l3,     gen_op_movl_T1_l4,     gen_op_movl_T1_l5,     gen_op_movl_T1_l6,     gen_op_movl_T1_l7,     gen_op_movl_T1_i0,     gen_op_movl_T1_i1,     gen_op_movl_T1_i2,     gen_op_movl_T1_i3,     gen_op_movl_T1_i4,     gen_op_movl_T1_i5,     gen_op_movl_T1_i6,     gen_op_movl_T1_i7,     },    {     gen_op_movl_T2_g0,     gen_op_movl_T2_g1,     gen_op_movl_T2_g2,     gen_op_movl_T2_g3,     gen_op_movl_T2_g4,     gen_op_movl_T2_g5,     gen_op_movl_T2_g6,     gen_op_movl_T2_g7,     gen_op_movl_T2_o0,     gen_op_movl_T2_o1,     gen_op_movl_T2_o2,     gen_op_movl_T2_o3,     gen_op_movl_T2_o4,     gen_op_movl_T2_o5,     gen_op_movl_T2_o6,     gen_op_movl_T2_o7,     gen_op_movl_T2_l0,     gen_op_movl_T2_l1,     gen_op_movl_T2_l2,     gen_op_movl_T2_l3,     gen_op_movl_T2_l4,     gen_op_movl_T2_l5,     gen_op_movl_T2_l6,     gen_op_movl_T2_l7,     gen_op_movl_T2_i0,     gen_op_movl_T2_i1,     gen_op_movl_T2_i2,     gen_op_movl_T2_i3,     gen_op_movl_T2_i4,     gen_op_movl_T2_i5,     gen_op_movl_T2_i6,     gen_op_movl_T2_i7,     }};static GenOpFunc1 *gen_op_movl_TN_im[3] = {    gen_op_movl_T0_im,    gen_op_movl_T1_im,    gen_op_movl_T2_im};// Sign extending versionstatic GenOpFunc1 * const gen_op_movl_TN_sim[3] = {    gen_op_movl_T0_sim,    gen_op_movl_T1_sim,    gen_op_movl_T2_sim};#ifdef TARGET_SPARC64#define GEN32(func, NAME) \static GenOpFunc *NAME ## _table [64] = {                                     \NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \};                                                                            \static inline void func(int n)                                                \{                                                                             \    NAME ## _table[n]();                                                      \}#else#define GEN32(func, NAME) \static GenOpFunc *NAME ## _table [32] = {                                     \NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \};                                                                            \static inline void func(int n)                                                \{                                                                             \    NAME ## _table[n]();                                                      \}#endif/* floating point registers moves */GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);#ifdef TARGET_SPARC64// 'a' versions allowed to user depending on asi#if defined(CONFIG_USER_ONLY)#define supervisor(dc) 0#define gen_op_ldst(name)        gen_op_##name##_raw()#define OP_LD_TABLE(width)						\    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \    {									\	int asi, offset;						\									\	if (IS_IMM) {							\	    offset = GET_FIELD(insn, 25, 31);				\	    if (is_ld)							\		gen_op_ld_asi_reg(offset, size, sign);			\	    else							\		gen_op_st_asi_reg(offset, size, sign);			\	    return;							\	}								\	asi = GET_FIELD(insn, 19, 26);					\	switch (asi) {							\	case 0x80: /* Primary address space */				\	    gen_op_##width##_raw();					\	    break;							\	default:							\            break;							\	}								\    }#else#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()#define OP_LD_TABLE(width)						\    static GenOpFunc *gen_op_##width[] = {				\	&gen_op_##width##_user,						\	&gen_op_##width##_kernel,					\    };									\									\    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \    {									\	int asi, offset;						\									\	if (IS_IMM) {							\	    offset = GET_FIELD(insn, 25, 31);				\	    if (is_ld)							\		gen_op_ld_asi_reg(offset, size, sign);			\	    else							\		gen_op_st_asi_reg(offset, size, sign);			\	    return;							\	}								\	asi = GET_FIELD(insn, 19, 26);					\	if (is_ld)							\	    gen_op_ld_asi(asi, size, sign);				\	else								\	    gen_op_st_asi(asi, size, sign);				\    }#define supervisor(dc) (dc->mem_idx == 1)#endif#else#if defined(CONFIG_USER_ONLY)#define gen_op_ldst(name)        gen_op_##name##_raw()#define OP_LD_TABLE(width)#define supervisor(dc) 0#else#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()#define OP_LD_TABLE(width)						      \static GenOpFunc *gen_op_##width[] = {                                        \    &gen_op_##width##_user,                                                   \    &gen_op_##width##_kernel,                                                 \};                                                                            \                                                                              \static void gen_op_##width##a(int insn, int is_ld, int size, int sign)        \{                                                                             \    int asi;                                                                  \                                                                              \    asi = GET_FIELD(insn, 19, 26);                                            \    switch (asi) {                                                            \	case 10: /* User data access */                                       \	    gen_op_##width##_user();                                          \	    break;                                                            \	case 11: /* Supervisor data access */                                 \	    gen_op_##width##_kernel();                                        \	    break;                                                            \        case 0x20 ... 0x2f: /* MMU passthrough */			      \	    if (is_ld)                                                        \		gen_op_ld_asi(asi, size, sign);				      \	    else                                                              \		gen_op_st_asi(asi, size, sign);				      \	    break;                                                            \	default:                                                              \	    if (is_ld)                                                        \		gen_op_ld_asi(asi, size, sign);			              \	    else                                                              \		gen_op_st_asi(asi, size, sign);				      \            break;                                                            \    }                                                                         \}#define supervisor(dc) (dc->mem_idx == 1)#endif#endifOP_LD_TABLE(ld);OP_LD_TABLE(st);OP_LD_TABLE(ldub);OP_LD_TABLE(lduh);OP_LD_TABLE(ldsb);OP_LD_TABLE(ldsh);OP_LD_TABLE(stb);OP_LD_TABLE(sth);OP_LD_TABLE(std);OP_LD_TABLE(ldstub);OP_LD_TABLE(swap);OP_LD_TABLE(ldd);OP_LD_TABLE(stf);OP_LD_TABLE(stdf);OP_LD_TABLE(ldf);OP_LD_TABLE(lddf);#ifdef TARGET_SPARC64OP_LD_TABLE(ldsw);OP_LD_TABLE(ldx);OP_LD_TABLE(stx);OP_LD_TABLE(cas);OP_LD_TABLE(casx);#endifstatic inline void gen_movl_imm_TN(int reg, uint32_t imm){    gen_op_movl_TN_im[reg](imm);}static inline void gen_movl_imm_T1(uint32_t val){    gen_movl_imm_TN(1, val);}static inline void gen_movl_imm_T0(uint32_t val){    gen_movl_imm_TN(0, val);}static inline void gen_movl_simm_TN(int reg, int32_t imm){    gen_op_movl_TN_sim[reg](imm);}static inline void gen_movl_simm_T1(int32_t val){    gen_movl_simm_TN(1, val);}static inline void gen_movl_simm_T0(int32_t val){    gen_movl_simm_TN(0, val);

⌨️ 快捷键说明

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