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,12 +1902,15 @@ static inline TCGv get_src1(unsigned int insn, TCGv def)
1902 static inline TCGv get_src2(unsigned int insn, TCGv def) 1902 static inline TCGv get_src2(unsigned int insn, TCGv def)
1903 { 1903 {
1904 TCGv r_rs2 = def; 1904 TCGv r_rs2 = def;
1905 - unsigned int rs2;  
1906 1905
1907 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 1911 } else { /* register */
  1912 + unsigned int rs2;
  1913 +
1911 rs2 = GET_FIELD(insn, 27, 31); 1914 rs2 = GET_FIELD(insn, 27, 31);
1912 if (rs2 == 0) 1915 if (rs2 == 0)
1913 r_rs2 = tcg_const_tl(0); // XXX how to free? 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,6 +1933,7 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
1930 static void disas_sparc_insn(DisasContext * dc) 1933 static void disas_sparc_insn(DisasContext * dc)
1931 { 1934 {
1932 unsigned int insn, opc, rs1, rs2, rd; 1935 unsigned int insn, opc, rs1, rs2, rd;
  1936 + target_long simm;
1933 1937
1934 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) 1938 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1935 tcg_gen_debug_insn_start(dc->pc); 1939 tcg_gen_debug_insn_start(dc->pc);
@@ -2963,8 +2967,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2963,8 +2967,8 @@ static void disas_sparc_insn(DisasContext * dc)
2963 if (IS_IMM) { /* immediate */ 2967 if (IS_IMM) { /* immediate */
2964 TCGv r_const; 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 gen_movl_TN_reg(rd, r_const); 2972 gen_movl_TN_reg(rd, r_const);
2969 tcg_temp_free(r_const); 2973 tcg_temp_free(r_const);
2970 } else { /* register */ 2974 } else { /* register */
@@ -2975,8 +2979,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2975,8 +2979,8 @@ static void disas_sparc_insn(DisasContext * dc)
2975 } else { 2979 } else {
2976 cpu_src1 = get_src1(insn, cpu_src1); 2980 cpu_src1 = get_src1(insn, cpu_src1);
2977 if (IS_IMM) { /* immediate */ 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 gen_movl_TN_reg(rd, cpu_dst); 2984 gen_movl_TN_reg(rd, cpu_dst);
2981 } else { /* register */ 2985 } else { /* register */
2982 // or x, %g0, y -> mov T1, x; mov y, T1 2986 // or x, %g0, y -> mov T1, x; mov y, T1
@@ -2993,11 +2997,11 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2993,11 +2997,11 @@ static void disas_sparc_insn(DisasContext * dc)
2993 } else if (xop == 0x25) { /* sll, V9 sllx */ 2997 } else if (xop == 0x25) { /* sll, V9 sllx */
2994 cpu_src1 = get_src1(insn, cpu_src1); 2998 cpu_src1 = get_src1(insn, cpu_src1);
2995 if (IS_IMM) { /* immediate */ 2999 if (IS_IMM) { /* immediate */
2996 - rs2 = GET_FIELDs(insn, 20, 31); 3000 + simm = GET_FIELDs(insn, 20, 31);
2997 if (insn & (1 << 12)) { 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 } else { 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 } else { /* register */ 3006 } else { /* register */
3003 rs2 = GET_FIELD(insn, 27, 31); 3007 rs2 = GET_FIELD(insn, 27, 31);
@@ -3013,12 +3017,12 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3013,12 +3017,12 @@ static void disas_sparc_insn(DisasContext * dc)
3013 } else if (xop == 0x26) { /* srl, V9 srlx */ 3017 } else if (xop == 0x26) { /* srl, V9 srlx */
3014 cpu_src1 = get_src1(insn, cpu_src1); 3018 cpu_src1 = get_src1(insn, cpu_src1);
3015 if (IS_IMM) { /* immediate */ 3019 if (IS_IMM) { /* immediate */
3016 - rs2 = GET_FIELDs(insn, 20, 31); 3020 + simm = GET_FIELDs(insn, 20, 31);
3017 if (insn & (1 << 12)) { 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 } else { 3023 } else {
3020 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL); 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 } else { /* register */ 3027 } else { /* register */
3024 rs2 = GET_FIELD(insn, 27, 31); 3028 rs2 = GET_FIELD(insn, 27, 31);
@@ -3036,13 +3040,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3036,13 +3040,13 @@ static void disas_sparc_insn(DisasContext * dc)
3036 } else if (xop == 0x27) { /* sra, V9 srax */ 3040 } else if (xop == 0x27) { /* sra, V9 srax */
3037 cpu_src1 = get_src1(insn, cpu_src1); 3041 cpu_src1 = get_src1(insn, cpu_src1);
3038 if (IS_IMM) { /* immediate */ 3042 if (IS_IMM) { /* immediate */
3039 - rs2 = GET_FIELDs(insn, 20, 31); 3043 + simm = GET_FIELDs(insn, 20, 31);
3040 if (insn & (1 << 12)) { 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 } else { 3046 } else {
3043 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL); 3047 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3044 tcg_gen_ext32s_i64(cpu_dst, cpu_dst); 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 } else { /* register */ 3051 } else { /* register */
3048 rs2 = GET_FIELD(insn, 27, 31); 3052 rs2 = GET_FIELD(insn, 27, 31);
@@ -3193,8 +3197,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3193,8 +3197,8 @@ static void disas_sparc_insn(DisasContext * dc)
3193 #ifndef TARGET_SPARC64 3197 #ifndef TARGET_SPARC64
3194 case 0x25: /* sll */ 3198 case 0x25: /* sll */
3195 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 3202 } else { /* register */
3199 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); 3203 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3200 tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0); 3204 tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
@@ -3203,8 +3207,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3203,8 +3207,8 @@ static void disas_sparc_insn(DisasContext * dc)
3203 break; 3207 break;
3204 case 0x26: /* srl */ 3208 case 0x26: /* srl */
3205 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 3212 } else { /* register */
3209 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); 3213 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3210 tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0); 3214 tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
@@ -3213,8 +3217,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3213,8 +3217,8 @@ static void disas_sparc_insn(DisasContext * dc)
3213 break; 3217 break;
3214 case 0x27: /* sra */ 3218 case 0x27: /* sra */
3215 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 3222 } else { /* register */
3219 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f); 3223 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3220 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0); 3224 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
@@ -3603,8 +3607,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3603,8 +3607,8 @@ static void disas_sparc_insn(DisasContext * dc)
3603 if (IS_IMM) { /* immediate */ 3607 if (IS_IMM) { /* immediate */
3604 TCGv r_const; 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 gen_movl_TN_reg(rd, r_const); 3612 gen_movl_TN_reg(rd, r_const);
3609 tcg_temp_free(r_const); 3613 tcg_temp_free(r_const);
3610 } else { 3614 } else {
@@ -3640,8 +3644,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3640,8 +3644,8 @@ static void disas_sparc_insn(DisasContext * dc)
3640 if (IS_IMM) { /* immediate */ 3644 if (IS_IMM) { /* immediate */
3641 TCGv r_const; 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 gen_movl_TN_reg(rd, r_const); 3649 gen_movl_TN_reg(rd, r_const);
3646 tcg_temp_free(r_const); 3650 tcg_temp_free(r_const);
3647 } else { 3651 } else {
@@ -4097,8 +4101,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -4097,8 +4101,8 @@ static void disas_sparc_insn(DisasContext * dc)
4097 save_state(dc, cpu_cond); 4101 save_state(dc, cpu_cond);
4098 cpu_src1 = get_src1(insn, cpu_src1); 4102 cpu_src1 = get_src1(insn, cpu_src1);
4099 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 4106 } else { /* register */
4103 rs2 = GET_FIELD(insn, 27, 31); 4107 rs2 = GET_FIELD(insn, 27, 31);
4104 if (rs2) { 4108 if (rs2) {
@@ -4119,8 +4123,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -4119,8 +4123,8 @@ static void disas_sparc_insn(DisasContext * dc)
4119 } else { 4123 } else {
4120 cpu_src1 = get_src1(insn, cpu_src1); 4124 cpu_src1 = get_src1(insn, cpu_src1);
4121 if (IS_IMM) { /* immediate */ 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 } else { /* register */ 4128 } else { /* register */
4125 rs2 = GET_FIELD(insn, 27, 31); 4129 rs2 = GET_FIELD(insn, 27, 31);
4126 if (rs2) { 4130 if (rs2) {
@@ -4219,8 +4223,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -4219,8 +4223,8 @@ static void disas_sparc_insn(DisasContext * dc)
4219 gen_movl_reg_TN(rs2, cpu_src2); 4223 gen_movl_reg_TN(rs2, cpu_src2);
4220 tcg_gen_mov_tl(cpu_addr, cpu_src1); 4224 tcg_gen_mov_tl(cpu_addr, cpu_src1);
4221 } else if (IS_IMM) { /* immediate */ 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 } else { /* register */ 4228 } else { /* register */
4225 rs2 = GET_FIELD(insn, 27, 31); 4229 rs2 = GET_FIELD(insn, 27, 31);
4226 if (rs2 != 0) { 4230 if (rs2 != 0) {