Commit 67526b20567890db65c4ed693bb7895148398493
1 parent
f654d9e2
Fix Sparc64 sign extension problems
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Showing
1 changed file
with
36 additions
and
32 deletions
target-sparc/translate.c
| ... | ... | @@ -1902,12 +1902,15 @@ static inline TCGv get_src1(unsigned int insn, TCGv def) |
| 1902 | 1902 | static inline TCGv get_src2(unsigned int insn, TCGv def) |
| 1903 | 1903 | { |
| 1904 | 1904 | TCGv r_rs2 = def; |
| 1905 | - unsigned int rs2; | |
| 1906 | 1905 | |
| 1907 | 1906 | if (IS_IMM) { /* immediate */ |
| 1908 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 1909 | - r_rs2 = tcg_const_tl((int)rs2); // XXX how to free? | |
| 1907 | + target_long simm; | |
| 1908 | + | |
| 1909 | + simm = GET_FIELDs(insn, 19, 31); | |
| 1910 | + r_rs2 = tcg_const_tl(simm); // XXX how to free? | |
| 1910 | 1911 | } else { /* register */ |
| 1912 | + unsigned int rs2; | |
| 1913 | + | |
| 1911 | 1914 | rs2 = GET_FIELD(insn, 27, 31); |
| 1912 | 1915 | if (rs2 == 0) |
| 1913 | 1916 | r_rs2 = tcg_const_tl(0); // XXX how to free? |
| ... | ... | @@ -1930,6 +1933,7 @@ static inline TCGv get_src2(unsigned int insn, TCGv def) |
| 1930 | 1933 | static void disas_sparc_insn(DisasContext * dc) |
| 1931 | 1934 | { |
| 1932 | 1935 | unsigned int insn, opc, rs1, rs2, rd; |
| 1936 | + target_long simm; | |
| 1933 | 1937 | |
| 1934 | 1938 | if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) |
| 1935 | 1939 | tcg_gen_debug_insn_start(dc->pc); |
| ... | ... | @@ -2963,8 +2967,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2963 | 2967 | if (IS_IMM) { /* immediate */ |
| 2964 | 2968 | TCGv r_const; |
| 2965 | 2969 | |
| 2966 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 2967 | - r_const = tcg_const_tl((int)rs2); | |
| 2970 | + simm = GET_FIELDs(insn, 19, 31); | |
| 2971 | + r_const = tcg_const_tl(simm); | |
| 2968 | 2972 | gen_movl_TN_reg(rd, r_const); |
| 2969 | 2973 | tcg_temp_free(r_const); |
| 2970 | 2974 | } else { /* register */ |
| ... | ... | @@ -2975,8 +2979,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2975 | 2979 | } else { |
| 2976 | 2980 | cpu_src1 = get_src1(insn, cpu_src1); |
| 2977 | 2981 | if (IS_IMM) { /* immediate */ |
| 2978 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 2979 | - tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2); | |
| 2982 | + simm = GET_FIELDs(insn, 19, 31); | |
| 2983 | + tcg_gen_ori_tl(cpu_dst, cpu_src1, simm); | |
| 2980 | 2984 | gen_movl_TN_reg(rd, cpu_dst); |
| 2981 | 2985 | } else { /* register */ |
| 2982 | 2986 | // or x, %g0, y -> mov T1, x; mov y, T1 |
| ... | ... | @@ -2993,11 +2997,11 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2993 | 2997 | } else if (xop == 0x25) { /* sll, V9 sllx */ |
| 2994 | 2998 | cpu_src1 = get_src1(insn, cpu_src1); |
| 2995 | 2999 | if (IS_IMM) { /* immediate */ |
| 2996 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3000 | + simm = GET_FIELDs(insn, 20, 31); | |
| 2997 | 3001 | if (insn & (1 << 12)) { |
| 2998 | - tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f); | |
| 3002 | + tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f); | |
| 2999 | 3003 | } else { |
| 3000 | - tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x1f); | |
| 3004 | + tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f); | |
| 3001 | 3005 | } |
| 3002 | 3006 | } else { /* register */ |
| 3003 | 3007 | rs2 = GET_FIELD(insn, 27, 31); |
| ... | ... | @@ -3013,12 +3017,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3013 | 3017 | } else if (xop == 0x26) { /* srl, V9 srlx */ |
| 3014 | 3018 | cpu_src1 = get_src1(insn, cpu_src1); |
| 3015 | 3019 | if (IS_IMM) { /* immediate */ |
| 3016 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3020 | + simm = GET_FIELDs(insn, 20, 31); | |
| 3017 | 3021 | if (insn & (1 << 12)) { |
| 3018 | - tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f); | |
| 3022 | + tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f); | |
| 3019 | 3023 | } else { |
| 3020 | 3024 | tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL); |
| 3021 | - tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f); | |
| 3025 | + tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f); | |
| 3022 | 3026 | } |
| 3023 | 3027 | } else { /* register */ |
| 3024 | 3028 | rs2 = GET_FIELD(insn, 27, 31); |
| ... | ... | @@ -3036,13 +3040,13 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3036 | 3040 | } else if (xop == 0x27) { /* sra, V9 srax */ |
| 3037 | 3041 | cpu_src1 = get_src1(insn, cpu_src1); |
| 3038 | 3042 | if (IS_IMM) { /* immediate */ |
| 3039 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3043 | + simm = GET_FIELDs(insn, 20, 31); | |
| 3040 | 3044 | if (insn & (1 << 12)) { |
| 3041 | - tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f); | |
| 3045 | + tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f); | |
| 3042 | 3046 | } else { |
| 3043 | 3047 | tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL); |
| 3044 | 3048 | tcg_gen_ext32s_i64(cpu_dst, cpu_dst); |
| 3045 | - tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f); | |
| 3049 | + tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f); | |
| 3046 | 3050 | } |
| 3047 | 3051 | } else { /* register */ |
| 3048 | 3052 | rs2 = GET_FIELD(insn, 27, 31); |
| ... | ... | @@ -3193,8 +3197,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3193 | 3197 | #ifndef TARGET_SPARC64 |
| 3194 | 3198 | case 0x25: /* sll */ |
| 3195 | 3199 | if (IS_IMM) { /* immediate */ |
| 3196 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3197 | - tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f); | |
| 3200 | + simm = GET_FIELDs(insn, 20, 31); | |
| 3201 | + tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f); | |
| 3198 | 3202 | } else { /* register */ |
| 3199 | 3203 | tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); |
| 3200 | 3204 | tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0); |
| ... | ... | @@ -3203,8 +3207,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3203 | 3207 | break; |
| 3204 | 3208 | case 0x26: /* srl */ |
| 3205 | 3209 | if (IS_IMM) { /* immediate */ |
| 3206 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3207 | - tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f); | |
| 3210 | + simm = GET_FIELDs(insn, 20, 31); | |
| 3211 | + tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f); | |
| 3208 | 3212 | } else { /* register */ |
| 3209 | 3213 | tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); |
| 3210 | 3214 | tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0); |
| ... | ... | @@ -3213,8 +3217,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3213 | 3217 | break; |
| 3214 | 3218 | case 0x27: /* sra */ |
| 3215 | 3219 | if (IS_IMM) { /* immediate */ |
| 3216 | - rs2 = GET_FIELDs(insn, 20, 31); | |
| 3217 | - tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f); | |
| 3220 | + simm = GET_FIELDs(insn, 20, 31); | |
| 3221 | + tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f); | |
| 3218 | 3222 | } else { /* register */ |
| 3219 | 3223 | tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); |
| 3220 | 3224 | tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0); |
| ... | ... | @@ -3603,8 +3607,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3603 | 3607 | if (IS_IMM) { /* immediate */ |
| 3604 | 3608 | TCGv r_const; |
| 3605 | 3609 | |
| 3606 | - rs2 = GET_FIELD_SPs(insn, 0, 10); | |
| 3607 | - r_const = tcg_const_tl((int)rs2); | |
| 3610 | + simm = GET_FIELD_SPs(insn, 0, 10); | |
| 3611 | + r_const = tcg_const_tl(simm); | |
| 3608 | 3612 | gen_movl_TN_reg(rd, r_const); |
| 3609 | 3613 | tcg_temp_free(r_const); |
| 3610 | 3614 | } else { |
| ... | ... | @@ -3640,8 +3644,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 3640 | 3644 | if (IS_IMM) { /* immediate */ |
| 3641 | 3645 | TCGv r_const; |
| 3642 | 3646 | |
| 3643 | - rs2 = GET_FIELD_SPs(insn, 0, 9); | |
| 3644 | - r_const = tcg_const_tl((int)rs2); | |
| 3647 | + simm = GET_FIELD_SPs(insn, 0, 9); | |
| 3648 | + r_const = tcg_const_tl(simm); | |
| 3645 | 3649 | gen_movl_TN_reg(rd, r_const); |
| 3646 | 3650 | tcg_temp_free(r_const); |
| 3647 | 3651 | } else { |
| ... | ... | @@ -4097,8 +4101,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4097 | 4101 | save_state(dc, cpu_cond); |
| 4098 | 4102 | cpu_src1 = get_src1(insn, cpu_src1); |
| 4099 | 4103 | if (IS_IMM) { /* immediate */ |
| 4100 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 4101 | - tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2); | |
| 4104 | + simm = GET_FIELDs(insn, 19, 31); | |
| 4105 | + tcg_gen_addi_tl(cpu_dst, cpu_src1, simm); | |
| 4102 | 4106 | } else { /* register */ |
| 4103 | 4107 | rs2 = GET_FIELD(insn, 27, 31); |
| 4104 | 4108 | if (rs2) { |
| ... | ... | @@ -4119,8 +4123,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4119 | 4123 | } else { |
| 4120 | 4124 | cpu_src1 = get_src1(insn, cpu_src1); |
| 4121 | 4125 | if (IS_IMM) { /* immediate */ |
| 4122 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 4123 | - tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2); | |
| 4126 | + simm = GET_FIELDs(insn, 19, 31); | |
| 4127 | + tcg_gen_addi_tl(cpu_dst, cpu_src1, simm); | |
| 4124 | 4128 | } else { /* register */ |
| 4125 | 4129 | rs2 = GET_FIELD(insn, 27, 31); |
| 4126 | 4130 | if (rs2) { |
| ... | ... | @@ -4219,8 +4223,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4219 | 4223 | gen_movl_reg_TN(rs2, cpu_src2); |
| 4220 | 4224 | tcg_gen_mov_tl(cpu_addr, cpu_src1); |
| 4221 | 4225 | } else if (IS_IMM) { /* immediate */ |
| 4222 | - rs2 = GET_FIELDs(insn, 19, 31); | |
| 4223 | - tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2); | |
| 4226 | + simm = GET_FIELDs(insn, 19, 31); | |
| 4227 | + tcg_gen_addi_tl(cpu_addr, cpu_src1, simm); | |
| 4224 | 4228 | } else { /* register */ |
| 4225 | 4229 | rs2 = GET_FIELD(insn, 27, 31); |
| 4226 | 4230 | if (rs2 != 0) { | ... | ... |