?? translate.c
字號:
{ uint32_t sprn = _SPR(opcode); return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);}/*** Get constants ***/EXTRACT_HELPER(IMM, 12, 8);/* 16 bits signed immediate value */EXTRACT_SHELPER(SIMM, 0, 16);/* 16 bits unsigned immediate value */EXTRACT_HELPER(UIMM, 0, 16);/* Bit count */EXTRACT_HELPER(NB, 11, 5);/* Shift count */EXTRACT_HELPER(SH, 11, 5);/* Mask start */EXTRACT_HELPER(MB, 6, 5);/* Mask end */EXTRACT_HELPER(ME, 1, 5);/* Trap operand */EXTRACT_HELPER(TO, 21, 5);EXTRACT_HELPER(CRM, 12, 8);EXTRACT_HELPER(FM, 17, 8);EXTRACT_HELPER(SR, 16, 4);EXTRACT_HELPER(FPIMM, 20, 4);/*** Jump target decoding ***//* Displacement */EXTRACT_SHELPER(d, 0, 16);/* Immediate address */static always_inline target_ulong LI (uint32_t opcode){ return (opcode >> 0) & 0x03FFFFFC;}static always_inline uint32_t BD (uint32_t opcode){ return (opcode >> 0) & 0xFFFC;}EXTRACT_HELPER(BO, 21, 5);EXTRACT_HELPER(BI, 16, 5);/* Absolute/relative address */EXTRACT_HELPER(AA, 1, 1);/* Link */EXTRACT_HELPER(LK, 0, 1);/* Create a mask between <start> and <end> bits */static always_inline target_ulong MASK (uint32_t start, uint32_t end){ target_ulong ret;#if defined(TARGET_PPC64) if (likely(start == 0)) { ret = UINT64_MAX << (63 - end); } else if (likely(end == 63)) { ret = UINT64_MAX >> start; }#else if (likely(start == 0)) { ret = UINT32_MAX << (31 - end); } else if (likely(end == 31)) { ret = UINT32_MAX >> start; }#endif else { ret = (((target_ulong)(-1ULL)) >> (start)) ^ (((target_ulong)(-1ULL) >> (end)) >> 1); if (unlikely(start > end)) return ~ret; } return ret;}/*****************************************************************************//* PowerPC Instructions types definitions */enum { PPC_NONE = 0x0000000000000000ULL, /* PowerPC base instructions set */ PPC_INSNS_BASE = 0x0000000000000001ULL, /* integer operations instructions */#define PPC_INTEGER PPC_INSNS_BASE /* flow control instructions */#define PPC_FLOW PPC_INSNS_BASE /* virtual memory instructions */#define PPC_MEM PPC_INSNS_BASE /* ld/st with reservation instructions */#define PPC_RES PPC_INSNS_BASE /* spr/msr access instructions */#define PPC_MISC PPC_INSNS_BASE /* Deprecated instruction sets */ /* Original POWER instruction set */ PPC_POWER = 0x0000000000000002ULL, /* POWER2 instruction set extension */ PPC_POWER2 = 0x0000000000000004ULL, /* Power RTC support */ PPC_POWER_RTC = 0x0000000000000008ULL, /* Power-to-PowerPC bridge (601) */ PPC_POWER_BR = 0x0000000000000010ULL, /* 64 bits PowerPC instruction set */ PPC_64B = 0x0000000000000020ULL, /* New 64 bits extensions (PowerPC 2.0x) */ PPC_64BX = 0x0000000000000040ULL, /* 64 bits hypervisor extensions */ PPC_64H = 0x0000000000000080ULL, /* New wait instruction (PowerPC 2.0x) */ PPC_WAIT = 0x0000000000000100ULL, /* Time base mftb instruction */ PPC_MFTB = 0x0000000000000200ULL, /* Fixed-point unit extensions */ /* PowerPC 602 specific */ PPC_602_SPEC = 0x0000000000000400ULL, /* isel instruction */ PPC_ISEL = 0x0000000000000800ULL, /* popcntb instruction */ PPC_POPCNTB = 0x0000000000001000ULL, /* string load / store */ PPC_STRING = 0x0000000000002000ULL, /* Floating-point unit extensions */ /* Optional floating point instructions */ PPC_FLOAT = 0x0000000000010000ULL, /* New floating-point extensions (PowerPC 2.0x) */ PPC_FLOAT_EXT = 0x0000000000020000ULL, PPC_FLOAT_FSQRT = 0x0000000000040000ULL, PPC_FLOAT_FRES = 0x0000000000080000ULL, PPC_FLOAT_FRSQRTE = 0x0000000000100000ULL, PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL, PPC_FLOAT_FSEL = 0x0000000000400000ULL, PPC_FLOAT_STFIWX = 0x0000000000800000ULL, /* Vector/SIMD extensions */ /* Altivec support */ PPC_ALTIVEC = 0x0000000001000000ULL, /* PowerPC 2.03 SPE extension */ PPC_SPE = 0x0000000002000000ULL, /* PowerPC 2.03 SPE floating-point extension */ PPC_SPEFPU = 0x0000000004000000ULL, /* Optional memory control instructions */ PPC_MEM_TLBIA = 0x0000000010000000ULL, PPC_MEM_TLBIE = 0x0000000020000000ULL, PPC_MEM_TLBSYNC = 0x0000000040000000ULL, /* sync instruction */ PPC_MEM_SYNC = 0x0000000080000000ULL, /* eieio instruction */ PPC_MEM_EIEIO = 0x0000000100000000ULL, /* Cache control instructions */ PPC_CACHE = 0x0000000200000000ULL, /* icbi instruction */ PPC_CACHE_ICBI = 0x0000000400000000ULL, /* dcbz instruction with fixed cache line size */ PPC_CACHE_DCBZ = 0x0000000800000000ULL, /* dcbz instruction with tunable cache line size */ PPC_CACHE_DCBZT = 0x0000001000000000ULL, /* dcba instruction */ PPC_CACHE_DCBA = 0x0000002000000000ULL, /* Freescale cache locking instructions */ PPC_CACHE_LOCK = 0x0000004000000000ULL, /* MMU related extensions */ /* external control instructions */ PPC_EXTERN = 0x0000010000000000ULL, /* segment register access instructions */ PPC_SEGMENT = 0x0000020000000000ULL, /* PowerPC 6xx TLB management instructions */ PPC_6xx_TLB = 0x0000040000000000ULL, /* PowerPC 74xx TLB management instructions */ PPC_74xx_TLB = 0x0000080000000000ULL, /* PowerPC 40x TLB management instructions */ PPC_40x_TLB = 0x0000100000000000ULL, /* segment register access instructions for PowerPC 64 "bridge" */ PPC_SEGMENT_64B = 0x0000200000000000ULL, /* SLB management */ PPC_SLBI = 0x0000400000000000ULL, /* Embedded PowerPC dedicated instructions */ PPC_WRTEE = 0x0001000000000000ULL, /* PowerPC 40x exception model */ PPC_40x_EXCP = 0x0002000000000000ULL, /* PowerPC 405 Mac instructions */ PPC_405_MAC = 0x0004000000000000ULL, /* PowerPC 440 specific instructions */ PPC_440_SPEC = 0x0008000000000000ULL, /* BookE (embedded) PowerPC specification */ PPC_BOOKE = 0x0010000000000000ULL, /* mfapidi instruction */ PPC_MFAPIDI = 0x0020000000000000ULL, /* tlbiva instruction */ PPC_TLBIVA = 0x0040000000000000ULL, /* tlbivax instruction */ PPC_TLBIVAX = 0x0080000000000000ULL, /* PowerPC 4xx dedicated instructions */ PPC_4xx_COMMON = 0x0100000000000000ULL, /* PowerPC 40x ibct instructions */ PPC_40x_ICBT = 0x0200000000000000ULL, /* rfmci is not implemented in all BookE PowerPC */ PPC_RFMCI = 0x0400000000000000ULL, /* rfdi instruction */ PPC_RFDI = 0x0800000000000000ULL, /* DCR accesses */ PPC_DCR = 0x1000000000000000ULL, /* DCR extended accesse */ PPC_DCRX = 0x2000000000000000ULL, /* user-mode DCR access, implemented in PowerPC 460 */ PPC_DCRUX = 0x4000000000000000ULL,};/*****************************************************************************//* PowerPC instructions table */#if HOST_LONG_BITS == 64#define OPC_ALIGN 8#else#define OPC_ALIGN 4#endif#if defined(__APPLE__)#define OPCODES_SECTION \ __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))#else#define OPCODES_SECTION \ __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))#endif#if defined(DO_PPC_STATISTICS)#define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ .inval = invl, \ .type = _typ, \ .handler = &gen_##name, \ .oname = stringify(name), \ }, \ .oname = stringify(name), \}#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ .inval = invl, \ .type = _typ, \ .handler = &gen_##name, \ .oname = onam, \ }, \ .oname = onam, \}#else#define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ .inval = invl, \ .type = _typ, \ .handler = &gen_##name, \ }, \ .oname = stringify(name), \}#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ .inval = invl, \ .type = _typ, \ .handler = &gen_##name, \ }, \ .oname = onam, \}#endif#define GEN_OPCODE_MARK(name) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = 0xFF, \ .opc2 = 0xFF, \ .opc3 = 0xFF, \ .pad = { 0, }, \ .handler = { \ .inval = 0x00000000, \ .type = 0x00, \ .handler = NULL, \ }, \ .oname = stringify(name), \}/* Start opcode list */GEN_OPCODE_MARK(start);/* Invalid instruction */GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE){ GEN_EXCP_INVAL(ctx);}static opc_handler_t invalid_handler = { .inval = 0xFFFFFFFF, .type = PPC_NONE, .handler = gen_invalid,};/*** Integer arithmetic ***/#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \ if (unlikely(Rc(ctx->opcode) != 0)) \ gen_set_Rc0(ctx); \}#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \ if (unlikely(Rc(ctx->opcode) != 0)) \ gen_set_Rc0(ctx); \}#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_##name(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \ if (unlikely(Rc(ctx->opcode) != 0)) \ gen_set_Rc0(ctx); \}#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \{ \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -