Index: qemu/target-sparc/translate.c =================================================================== --- qemu.orig/target-sparc/translate.c 2008-02-21 20:00:28.000000000 +0000 +++ qemu/target-sparc/translate.c 2008-02-21 20:02:07.000000000 +0000 @@ -44,6 +44,81 @@ #define JUMP_PC 2 /* dynamic pc value which takes only two values according to jump_pc[T2] */ +#ifdef TARGET_SPARC64 +#define TCG_TYPE_TL TCG_TYPE_I64 +#define tcg_gen_movi_tl tcg_gen_movi_i64 +#define tcg_gen_mov_tl tcg_gen_mov_i64 +#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64 +#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64 +#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64 +#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64 +#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64 +#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64 +#define tcg_gen_ld_tl tcg_gen_ld_i64 +#define tcg_gen_st8_tl tcg_gen_st8_i64 +#define tcg_gen_st16_tl tcg_gen_st16_i64 +#define tcg_gen_st32_tl tcg_gen_st32_i64 +#define tcg_gen_st_tl tcg_gen_st_i64 +#define tcg_gen_add_tl tcg_gen_add_i64 +#define tcg_gen_addi_tl tcg_gen_addi_i64 +#define tcg_gen_sub_tl tcg_gen_sub_i64 +#define tcg_gen_subi_tl tcg_gen_subi_i64 +#define tcg_gen_and_tl tcg_gen_and_i64 +#define tcg_gen_andi_tl tcg_gen_andi_i64 +#define tcg_gen_or_tl tcg_gen_or_i64 +#define tcg_gen_ori_tl tcg_gen_ori_i64 +#define tcg_gen_xor_tl tcg_gen_xor_i64 +#define tcg_gen_xori_tl tcg_gen_xori_i64 +#define tcg_gen_shl_tl tcg_gen_shl_i64 +#define tcg_gen_shli_tl tcg_gen_shli_i64 +#define tcg_gen_shr_tl tcg_gen_shr_i64 +#define tcg_gen_shri_tl tcg_gen_shri_i64 +#define tcg_gen_sar_tl tcg_gen_sar_i64 +#define tcg_gen_sari_tl tcg_gen_sari_i64 +#else +#define TCG_TYPE_TL TCG_TYPE_I32 +#define tcg_gen_movi_tl tcg_gen_movi_i32 +#define tcg_gen_mov_tl tcg_gen_mov_i32 +#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32 +#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32 +#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32 +#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32 +#define tcg_gen_ld32u_tl tcg_gen_ld_i32 +#define tcg_gen_ld32s_tl tcg_gen_ld_i32 +#define tcg_gen_ld_tl tcg_gen_ld_i32 +#define tcg_gen_st8_tl tcg_gen_st8_i32 +#define tcg_gen_st16_tl tcg_gen_st16_i32 +#define tcg_gen_st32_tl tcg_gen_st_i32 +#define tcg_gen_st_tl tcg_gen_st_i32 +#define tcg_gen_add_tl tcg_gen_add_i32 +#define tcg_gen_addi_tl tcg_gen_addi_i32 +#define tcg_gen_sub_tl tcg_gen_sub_i32 +#define tcg_gen_subi_tl tcg_gen_subi_i32 +#define tcg_gen_and_tl tcg_gen_and_i32 +#define tcg_gen_andi_tl tcg_gen_andi_i32 +#define tcg_gen_or_tl tcg_gen_or_i32 +#define tcg_gen_ori_tl tcg_gen_ori_i32 +#define tcg_gen_xor_tl tcg_gen_xor_i32 +#define tcg_gen_xori_tl tcg_gen_xori_i32 +#define tcg_gen_shl_tl tcg_gen_shl_i32 +#define tcg_gen_shli_tl tcg_gen_shli_i32 +#define tcg_gen_shr_tl tcg_gen_shr_i32 +#define tcg_gen_shri_tl tcg_gen_shri_i32 +#define tcg_gen_sar_tl tcg_gen_sar_i32 +#define tcg_gen_sari_tl tcg_gen_sari_i32 +#endif + +#if TCG_TARGET_REG_BITS == 32 +#define tcg_gen_ld_ptr tcg_gen_ld_i32 +#else +#define tcg_gen_ld_ptr tcg_gen_ld_i64 +#endif + +/* global register indexes */ +static TCGv cpu_env, cpu_T[3], cpu_regwptr; +/* local register indexes (only used inside old micro ops) */ +static TCGv cpu_tmp0; + 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 */ @@ -102,195 +177,6 @@ static void disas_sparc_insn(DisasContext * dc); -static GenOpFunc * const 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 * const 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 * const gen_op_movl_TN_im[3] = { - gen_op_movl_T0_im, - gen_op_movl_T1_im, - gen_op_movl_T2_im -}; - -// Sign extending version -static 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 * const NAME ## _table [64] = { \ @@ -375,29 +261,18 @@ #endif #ifndef CONFIG_USER_ONLY -OP_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_SPARC64 -OP_LD_TABLE(lduw); -OP_LD_TABLE(ldsw); -OP_LD_TABLE(ldx); -OP_LD_TABLE(stx); #endif + +#ifdef TARGET_ABI32 +#define ABI32_MASK() tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff); +#else +#define ABI32_MASK() #endif /* asi moves */ @@ -583,99 +458,105 @@ } #endif -static inline void gen_movl_imm_TN(int reg, uint32_t imm) +static inline void gen_movl_simm_T1(int32_t val) { - gen_op_movl_TN_im[reg](imm); + tcg_gen_movi_tl(cpu_T[1], val); } -static inline void gen_movl_imm_T1(uint32_t val) +static inline void gen_movl_reg_TN(int reg, int t) { - gen_movl_imm_TN(1, val); + if (reg == 0) + tcg_gen_movi_tl(cpu_T[t], 0); + else if (reg < 8) + tcg_gen_ld_tl(cpu_T[t], cpu_env, offsetof(CPUState, gregs[reg])); + else { + tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX + tcg_gen_ld_tl(cpu_T[t], cpu_regwptr, (reg - 8) * sizeof(target_ulong)); + } } -static inline void gen_movl_imm_T0(uint32_t val) +static inline void gen_movl_reg_T0(int reg) { - gen_movl_imm_TN(0, val); + gen_movl_reg_TN(reg, 0); } -static inline void gen_movl_simm_TN(int reg, int32_t imm) +static inline void gen_movl_reg_T1(int reg) { - gen_op_movl_TN_sim[reg](imm); + gen_movl_reg_TN(reg, 1); } -static inline void gen_movl_simm_T1(int32_t val) +static inline void gen_movl_reg_T2(int reg) { - gen_movl_simm_TN(1, val); + gen_movl_reg_TN(reg, 2); } -static inline void gen_movl_simm_T0(int32_t val) +static inline void gen_movl_TN_reg(int reg, int t) { - gen_movl_simm_TN(0, val); + if (reg == 0) + return; + else if (reg < 8) + tcg_gen_st_tl(cpu_T[t], cpu_env, offsetof(CPUState, gregs[reg])); + else { + tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX + tcg_gen_st_tl(cpu_T[t], cpu_regwptr, (reg - 8) * sizeof(target_ulong)); + } } -static inline void gen_movl_reg_TN(int reg, int t) +static inline void gen_movl_T0_reg(int reg) { - if (reg) - gen_op_movl_reg_TN[t][reg] (); - else - gen_movl_imm_TN(t, 0); + gen_movl_TN_reg(reg, 0); } -static inline void gen_movl_reg_T0(int reg) +static inline void gen_movl_T1_reg(int reg) { - gen_movl_reg_TN(reg, 0); + gen_movl_TN_reg(reg, 1); } -static inline void gen_movl_reg_T1(int reg) +static inline void gen_op_movl_T0_env(size_t offset) { - gen_movl_reg_TN(reg, 1); + tcg_gen_ld_i32(cpu_T[0], cpu_env, offset); } -static inline void gen_movl_reg_T2(int reg) +static inline void gen_op_movl_env_T0(size_t offset) { - gen_movl_reg_TN(reg, 2); + tcg_gen_st_i32(cpu_T[0], cpu_env, offset); } -static inline void gen_movl_TN_reg(int reg, int t) +static inline void gen_op_movtl_T0_env(size_t offset) { - if (reg) - gen_op_movl_TN_reg[t][reg] (); + tcg_gen_ld_tl(cpu_T[0], cpu_env, offset); } -static inline void gen_movl_T0_reg(int reg) +static inline void gen_op_movtl_env_T0(size_t offset) { - gen_movl_TN_reg(reg, 0); + tcg_gen_st_tl(cpu_T[0], cpu_env, offset); } -static inline void gen_movl_T1_reg(int reg) +static inline void gen_op_add_T1_T0(void) { - gen_movl_TN_reg(reg, 1); + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); +} + +static inline void gen_op_or_T1_T0(void) +{ + tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); +} + +static inline void gen_op_xor_T1_T0(void) +{ + tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); } static inline void gen_jmp_im(target_ulong pc) { -#ifdef TARGET_SPARC64 - if (pc == (uint32_t)pc) { - gen_op_jmp_im(pc); - } else { - gen_op_jmp_im64(pc >> 32, pc); - } -#else - gen_op_jmp_im(pc); -#endif + tcg_gen_movi_tl(cpu_tmp0, pc); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc)); } static inline void gen_movl_npc_im(target_ulong npc) { -#ifdef TARGET_SPARC64 - if (npc == (uint32_t)npc) { - gen_op_movl_npc_im(npc); - } else { - gen_op_movq_npc_im64(npc >> 32, npc); - } -#else - gen_op_movl_npc_im(npc); -#endif + tcg_gen_movi_tl(cpu_tmp0, npc); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc)); } static inline void gen_goto_tb(DisasContext *s, int tb_num, @@ -1179,7 +1060,7 @@ if (rd) { // nop #endif uint32_t value = GET_FIELD(insn, 10, 31); - gen_movl_imm_T0(value << 10); + tcg_gen_movi_tl(cpu_T[0], value << 10); gen_movl_T0_reg(rd); #if defined(OPTIM) } @@ -1196,15 +1077,7 @@ /*CALL*/ { target_long target = GET_FIELDs(insn, 2, 31) << 2; -#ifdef TARGET_SPARC64 - if (dc->pc == (uint32_t)dc->pc) { - gen_op_movl_T0_im(dc->pc); - } else { - gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); - } -#else - gen_op_movl_T0_im(dc->pc); -#endif + tcg_gen_movi_tl(cpu_T[0], dc->pc); gen_movl_T0_reg(15); target += dc->pc; gen_mov_pc_npc(dc); @@ -1221,14 +1094,7 @@ gen_movl_reg_T0(rs1); if (IS_IMM) { rs2 = GET_FIELD(insn, 25, 31); -#if defined(OPTIM) - if (rs2 != 0) { -#endif - gen_movl_simm_T1(rs2); - gen_op_add_T1_T0(); -#if defined(OPTIM) - } -#endif + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2); } else { rs2 = GET_FIELD(insn, 27, 31); #if defined(OPTIM) @@ -1298,11 +1164,7 @@ gen_movl_T0_reg(rd); break; case 0x5: /* V9 rdpc */ - if (dc->pc == (uint32_t)dc->pc) { - gen_op_movl_T0_im(dc->pc); - } else { - gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); - } + tcg_gen_movi_tl(cpu_T[0], dc->pc); gen_movl_T0_reg(rd); break; case 0x6: /* V9 rdfprs */ @@ -2078,24 +1940,19 @@ rs1 = GET_FIELD(insn, 13, 17); if (rs1 == 0) { - // or %g0, x, y -> mov T1, x; mov y, T1 + // or %g0, x, y -> mov T0, x; mov y, T0 if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31); - gen_movl_simm_T1(rs2); + tcg_gen_movi_tl(cpu_T[0], rs2); } else { /* register */ rs2 = GET_FIELD(insn, 27, 31); - gen_movl_reg_T1(rs2); + gen_movl_reg_T0(rs2); } - gen_movl_T1_reg(rd); } else { gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ - // or x, #0, y -> mov T1, x; mov y, T1 rs2 = GET_FIELDs(insn, 19, 31); - if (rs2 != 0) { - gen_movl_simm_T1(rs2); - gen_op_or_T1_T0(); - } + tcg_gen_ori_tl(cpu_T[0], cpu_T[0], rs2); } else { /* register */ // or x, %g0, y -> mov T1, x; mov y, T1 rs2 = GET_FIELD(insn, 27, 31); @@ -2104,8 +1961,8 @@ gen_op_or_T1_T0(); } } - gen_movl_T0_reg(rd); } + gen_movl_T0_reg(rd); #endif #ifdef TARGET_SPARC64 } else if (xop == 0x25) { /* sll, V9 sllx */ @@ -2173,17 +2030,17 @@ gen_op_add_T1_T0(); break; case 0x1: - gen_op_and_T1_T0(); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); if (xop & 0x10) gen_op_logic_T0_cc(); break; case 0x2: - gen_op_or_T1_T0(); + tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); if (xop & 0x10) gen_op_logic_T0_cc(); break; case 0x3: - gen_op_xor_T1_T0(); + tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); if (xop & 0x10) gen_op_logic_T0_cc(); break; @@ -2191,7 +2048,7 @@ if (xop & 0x10) gen_op_sub_T1_T0_cc(); else - gen_op_sub_T1_T0(); + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); break; case 0x5: gen_op_andn_T1_T0(); @@ -2216,7 +2073,7 @@ break; #ifdef TARGET_SPARC64 case 0x9: /* V9 mulx */ - gen_op_mulx_T1_T0(); + tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]); break; #endif case 0xa: @@ -3003,14 +2860,7 @@ gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31); -#if defined(OPTIM) - if (rs2) { -#endif - gen_movl_simm_T1(rs2); - gen_op_add_T1_T0(); -#if defined(OPTIM) - } -#endif + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2); } else { /* register */ rs2 = GET_FIELD(insn, 27, 31); #if defined(OPTIM) @@ -3034,14 +2884,7 @@ gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31); -#if defined(OPTIM) - if (rs2) { -#endif - gen_movl_simm_T1(rs2); - gen_op_add_T1_T0(); -#if defined(OPTIM) - } -#endif + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2); } else { /* register */ rs2 = GET_FIELD(insn, 27, 31); #if defined(OPTIM) @@ -3057,15 +2900,7 @@ case 0x38: /* jmpl */ { if (rd != 0) { -#ifdef TARGET_SPARC64 - if (dc->pc == (uint32_t)dc->pc) { - gen_op_movl_T1_im(dc->pc); - } else { - gen_op_movq_T1_im64(dc->pc >> 32, dc->pc); - } -#else - gen_op_movl_T1_im(dc->pc); -#endif + tcg_gen_movi_tl(cpu_T[1], dc->pc); gen_movl_T1_reg(rd); } gen_mov_pc_npc(dc); @@ -3144,14 +2979,7 @@ } else if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31); -#if defined(OPTIM) - if (rs2 != 0) { -#endif - gen_movl_simm_T1(rs2); - gen_op_add_T1_T0(); -#if defined(OPTIM) - } -#endif + tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2); } else { /* register */ rs2 = GET_FIELD(insn, 27, 31); #if defined(OPTIM) @@ -3167,20 +2995,19 @@ (xop > 0x17 && xop <= 0x1d ) || (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { switch (xop) { - case 0x0: /* load word */ + case 0x0: /* load unsigned word */ gen_op_check_align_T0_3(); -#ifndef TARGET_SPARC64 - gen_op_ldst(ld); -#else - gen_op_ldst(lduw); -#endif + ABI32_MASK(); + tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x1: /* load unsigned byte */ - gen_op_ldst(ldub); + ABI32_MASK(); + tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x2: /* load unsigned halfword */ gen_op_check_align_T0_1(); - gen_op_ldst(lduh); + ABI32_MASK(); + tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x3: /* load double word */ if (rd & 1) @@ -3190,19 +3017,27 @@ gen_movl_T0_reg(rd + 1); break; case 0x9: /* load signed byte */ - gen_op_ldst(ldsb); + ABI32_MASK(); + tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0xa: /* load signed halfword */ gen_op_check_align_T0_1(); - gen_op_ldst(ldsh); + ABI32_MASK(); + tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0xd: /* ldstub -- XXX: should be atomically */ - gen_op_ldst(ldstub); + tcg_gen_movi_i32(cpu_tmp0, 0xff); + ABI32_MASK(); + tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx); + tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx); break; case 0x0f: /* swap register with memory. Also atomically */ gen_op_check_align_T0_3(); gen_movl_reg_T1(rd); - gen_op_ldst(swap); + ABI32_MASK(); + tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx); + tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx); + tcg_gen_mov_i32(cpu_T[1], cpu_tmp0); break; #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) case 0x10: /* load word alternate */ @@ -3297,11 +3132,13 @@ #ifdef TARGET_SPARC64 case 0x08: /* V9 ldsw */ gen_op_check_align_T0_3(); - gen_op_ldst(ldsw); + ABI32_MASK(); + tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x0b: /* V9 ldx */ gen_op_check_align_T0_7(); - gen_op_ldst(ldx); + ABI32_MASK(); + tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x18: /* V9 ldswa */ gen_op_check_align_T0_3(); @@ -3374,16 +3211,19 @@ xop == 0xe || xop == 0x1e) { gen_movl_reg_T1(rd); switch (xop) { - case 0x4: + case 0x4: /* store word */ gen_op_check_align_T0_3(); - gen_op_ldst(st); + ABI32_MASK(); + tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx); break; - case 0x5: - gen_op_ldst(stb); + case 0x5: /* store byte */ + ABI32_MASK(); + tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx); break; - case 0x6: + case 0x6: /* store halfword */ gen_op_check_align_T0_1(); - gen_op_ldst(sth); + ABI32_MASK(); + tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x7: if (rd & 1) @@ -3441,7 +3281,8 @@ #ifdef TARGET_SPARC64 case 0x0e: /* V9 stx */ gen_op_check_align_T0_7(); - gen_op_ldst(stx); + ABI32_MASK(); + tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx); break; case 0x1e: /* V9 stxa */ gen_op_check_align_T0_7(); @@ -3597,6 +3438,10 @@ #endif } +static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args) +{ +} + static inline int gen_intermediate_code_internal(TranslationBlock * tb, int spc, CPUSPARCState *env) { @@ -3615,6 +3460,9 @@ dc->fpu_enabled = cpu_fpu_enabled(env); gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL); + cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX + do { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { @@ -3748,6 +3596,7 @@ { CPUSPARCState *env; const sparc_def_t *def; + static int inited; def = cpu_sparc_find_by_name(cpu_model); if (!def) @@ -3769,6 +3618,27 @@ env->mmuregs[0] |= def->mmu_version; cpu_sparc_set_id(env, 0); #endif + + /* init various static tables */ + if (!inited) { + inited = 1; + + tcg_set_macro_func(&tcg_ctx, tcg_macro_func); + cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); +#if TARGET_LONG_BITS > HOST_LONG_BITS + cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, + TCG_AREG0, offsetof(CPUState, t0), "T0"); + cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, + TCG_AREG0, offsetof(CPUState, t1), "T1"); + cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL, + TCG_AREG0, offsetof(CPUState, t2), "T2"); +#else + cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); + cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); + cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2"); +#endif + } + cpu_reset(env); return env; Index: qemu/target-sparc/op.c =================================================================== --- qemu.orig/target-sparc/op.c 2008-02-21 20:00:28.000000000 +0000 +++ qemu/target-sparc/op.c 2008-02-21 20:02:07.000000000 +0000 @@ -20,104 +20,6 @@ #include "exec.h" - /*XXX*/ -#define REGNAME g0 -#define REG (env->gregs[0]) -#include "op_template.h" -#define REGNAME g1 -#define REG (env->gregs[1]) -#include "op_template.h" -#define REGNAME g2 -#define REG (env->gregs[2]) -#include "op_template.h" -#define REGNAME g3 -#define REG (env->gregs[3]) -#include "op_template.h" -#define REGNAME g4 -#define REG (env->gregs[4]) -#include "op_template.h" -#define REGNAME g5 -#define REG (env->gregs[5]) -#include "op_template.h" -#define REGNAME g6 -#define REG (env->gregs[6]) -#include "op_template.h" -#define REGNAME g7 -#define REG (env->gregs[7]) -#include "op_template.h" -#define REGNAME i0 -#define REG (REGWPTR[16]) -#include "op_template.h" -#define REGNAME i1 -#define REG (REGWPTR[17]) -#include "op_template.h" -#define REGNAME i2 -#define REG (REGWPTR[18]) -#include "op_template.h" -#define REGNAME i3 -#define REG (REGWPTR[19]) -#include "op_template.h" -#define REGNAME i4 -#define REG (REGWPTR[20]) -#include "op_template.h" -#define REGNAME i5 -#define REG (REGWPTR[21]) -#include "op_template.h" -#define REGNAME i6 -#define REG (REGWPTR[22]) -#include "op_template.h" -#define REGNAME i7 -#define REG (REGWPTR[23]) -#include "op_template.h" -#define REGNAME l0 -#define REG (REGWPTR[8]) -#include "op_template.h" -#define REGNAME l1 -#define REG (REGWPTR[9]) -#include "op_template.h" -#define REGNAME l2 -#define REG (REGWPTR[10]) -#include "op_template.h" -#define REGNAME l3 -#define REG (REGWPTR[11]) -#include "op_template.h" -#define REGNAME l4 -#define REG (REGWPTR[12]) -#include "op_template.h" -#define REGNAME l5 -#define REG (REGWPTR[13]) -#include "op_template.h" -#define REGNAME l6 -#define REG (REGWPTR[14]) -#include "op_template.h" -#define REGNAME l7 -#define REG (REGWPTR[15]) -#include "op_template.h" -#define REGNAME o0 -#define REG (REGWPTR[0]) -#include "op_template.h" -#define REGNAME o1 -#define REG (REGWPTR[1]) -#include "op_template.h" -#define REGNAME o2 -#define REG (REGWPTR[2]) -#include "op_template.h" -#define REGNAME o3 -#define REG (REGWPTR[3]) -#include "op_template.h" -#define REGNAME o4 -#define REG (REGWPTR[4]) -#include "op_template.h" -#define REGNAME o5 -#define REG (REGWPTR[5]) -#include "op_template.h" -#define REGNAME o6 -#define REG (REGWPTR[6]) -#include "op_template.h" -#define REGNAME o7 -#define REG (REGWPTR[7]) -#include "op_template.h" - #define REGNAME f0 #define REG (env->fpr[0]) #include "fop_template.h" @@ -267,106 +169,11 @@ #endif #ifdef TARGET_SPARC64 -#ifdef WORDS_BIGENDIAN -typedef union UREG64 { - struct { uint16_t v3, v2, v1, v0; } w; - struct { uint32_t v1, v0; } l; - uint64_t q; -} UREG64; -#else -typedef union UREG64 { - struct { uint16_t v0, v1, v2, v3; } w; - struct { uint32_t v0, v1; } l; - uint64_t q; -} UREG64; -#endif - -#define PARAMQ1 \ -({\ - UREG64 __p;\ - __p.l.v1 = PARAM1;\ - __p.l.v0 = PARAM2;\ - __p.q;\ -}) - -void OPPROTO op_movq_T0_im64(void) -{ - T0 = PARAMQ1; -} - -void OPPROTO op_movq_T1_im64(void) -{ - T1 = PARAMQ1; -} - #define XFLAG_SET(x) ((env->xcc&x)?1:0) - -#else -#define EIP (env->pc) #endif #define FLAG_SET(x) ((env->psr&x)?1:0) -void OPPROTO op_movl_T0_0(void) -{ - T0 = 0; -} - -void OPPROTO op_movl_T0_im(void) -{ - T0 = (uint32_t)PARAM1; -} - -void OPPROTO op_movl_T1_im(void) -{ - T1 = (uint32_t)PARAM1; -} - -void OPPROTO op_movl_T2_im(void) -{ - T2 = (uint32_t)PARAM1; -} - -void OPPROTO op_movl_T0_sim(void) -{ - T0 = (int32_t)PARAM1; -} - -void OPPROTO op_movl_T1_sim(void) -{ - T1 = (int32_t)PARAM1; -} - -void OPPROTO op_movl_T2_sim(void) -{ - T2 = (int32_t)PARAM1; -} - -void OPPROTO op_movl_T0_env(void) -{ - T0 = *(uint32_t *)((char *)env + PARAM1); -} - -void OPPROTO op_movl_env_T0(void) -{ - *(uint32_t *)((char *)env + PARAM1) = T0; -} - -void OPPROTO op_movtl_T0_env(void) -{ - T0 = *(target_ulong *)((char *)env + PARAM1); -} - -void OPPROTO op_movtl_env_T0(void) -{ - *(target_ulong *)((char *)env + PARAM1) = T0; -} - -void OPPROTO op_add_T1_T0(void) -{ - T0 += T1; -} - void OPPROTO op_add_T1_T0_cc(void) { target_ulong src1; @@ -565,11 +372,6 @@ FORCE_RET(); } -void OPPROTO op_sub_T1_T0(void) -{ - T0 -= T1; -} - void OPPROTO op_sub_T1_T0_cc(void) { target_ulong src1; @@ -765,21 +567,6 @@ FORCE_RET(); } -void OPPROTO op_and_T1_T0(void) -{ - T0 &= T1; -} - -void OPPROTO op_or_T1_T0(void) -{ - T0 |= T1; -} - -void OPPROTO op_xor_T1_T0(void) -{ - T0 ^= T1; -} - void OPPROTO op_andn_T1_T0(void) { T0 &= ~T1; @@ -921,12 +708,6 @@ } #ifdef TARGET_SPARC64 -void OPPROTO op_mulx_T1_T0(void) -{ - T0 *= T1; - FORCE_RET(); -} - void OPPROTO op_udivx_T1_T0(void) { if (T1 == 0) { @@ -1499,28 +1280,8 @@ { T2 = ((int64_t)T0 >= 0); } - -void OPPROTO op_jmp_im64(void) -{ - env->pc = PARAMQ1; -} - -void OPPROTO op_movq_npc_im64(void) -{ - env->npc = PARAMQ1; -} #endif -void OPPROTO op_jmp_im(void) -{ - env->pc = (uint32_t)PARAM1; -} - -void OPPROTO op_movl_npc_im(void) -{ - env->npc = (uint32_t)PARAM1; -} - void OPPROTO op_movl_npc_T0(void) { env->npc = T0; Index: qemu/target-sparc/op_template.h =================================================================== --- qemu.orig/target-sparc/op_template.h 2008-02-21 20:00:28.000000000 +0000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* - * SPARC micro operations (templates for various register related - * operations) - * - * Copyright (c) 2003 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 - */ - -void OPPROTO glue(op_movl_T0_, REGNAME)(void) -{ - T0 = REG; -} - -void OPPROTO glue(op_movl_T1_, REGNAME)(void) -{ - T1 = REG; -} - -void OPPROTO glue(op_movl_T2_, REGNAME)(void) -{ - T2 = REG; -} - -void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void) -{ - REG = T0; -} - -void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void) -{ - REG = T1; -} - -#undef REG -#undef REGNAME Index: qemu/target-sparc/op_mem.h =================================================================== --- qemu.orig/target-sparc/op_mem.h 2008-02-21 20:00:28.000000000 +0000 +++ qemu/target-sparc/op_mem.h 2008-02-21 20:02:07.000000000 +0000 @@ -4,36 +4,6 @@ #define ADDR(x) (x) #endif -/*** Integer load ***/ -#define SPARC_LD_OP(name, qp) \ -void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ -{ \ - T1 = (target_ulong)glue(qp, MEMSUFFIX)(ADDR(T0)); \ -} - -#define SPARC_LD_OP_S(name, qp) \ - void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ - { \ - T1 = (target_long)glue(qp, MEMSUFFIX)(ADDR(T0)); \ - } - -#define SPARC_ST_OP(name, op) \ -void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ -{ \ - glue(op, MEMSUFFIX)(ADDR(T0), T1); \ -} - -SPARC_LD_OP(ld, ldl); -SPARC_LD_OP(ldub, ldub); -SPARC_LD_OP(lduh, lduw); -SPARC_LD_OP_S(ldsb, ldsb); -SPARC_LD_OP_S(ldsh, ldsw); - -/*** Integer store ***/ -SPARC_ST_OP(st, stl); -SPARC_ST_OP(stb, stb); -SPARC_ST_OP(sth, stw); - void OPPROTO glue(op_std, MEMSUFFIX)(void) { uint64_t tmp = ((uint64_t)T1 << 32) | (uint64_t)(T2 & 0xffffffff); @@ -41,19 +11,6 @@ glue(stq, MEMSUFFIX)(ADDR(T0), tmp); } -void OPPROTO glue(op_ldstub, MEMSUFFIX)(void) -{ - T1 = glue(ldub, MEMSUFFIX)(ADDR(T0)); - glue(stb, MEMSUFFIX)(ADDR(T0), 0xff); /* XXX: Should be Atomically */ -} - -void OPPROTO glue(op_swap, MEMSUFFIX)(void) -{ - target_ulong tmp = glue(ldl, MEMSUFFIX)(ADDR(T0)); - glue(stl, MEMSUFFIX)(ADDR(T0), T1); /* XXX: Should be Atomically */ - T1 = tmp; -} - void OPPROTO glue(op_ldd, MEMSUFFIX)(void) { uint64_t tmp; @@ -107,18 +64,4 @@ } #endif -#ifdef TARGET_SPARC64 -void OPPROTO glue(op_lduw, MEMSUFFIX)(void) -{ - T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff); -} - -void OPPROTO glue(op_ldsw, MEMSUFFIX)(void) -{ - T1 = (int64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff); -} - -SPARC_LD_OP(ldx, ldq); -SPARC_ST_OP(stx, stq); -#endif #undef MEMSUFFIX