Commit 67526b20567890db65c4ed693bb7895148398493

Authored by Blue Swirl
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) {
... ...