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) { | ... | ... |