Commit db166940e2cb4e6fc6e66cab465fc394bfac159b

Authored by blueswir1
1 parent 8571c055

Implement nucleus quad ldda

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4902 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/helper.h
@@ -22,6 +22,7 @@ DEF_HELPER(target_ulong, helper_array8, (target_ulong pixel_addr, \ @@ -22,6 +22,7 @@ DEF_HELPER(target_ulong, helper_array8, (target_ulong pixel_addr, \
22 DEF_HELPER(target_ulong, helper_alignaddr, (target_ulong addr, \ 22 DEF_HELPER(target_ulong, helper_alignaddr, (target_ulong addr, \
23 target_ulong offset)) 23 target_ulong offset))
24 DEF_HELPER(target_ulong, helper_popc, (target_ulong val)) 24 DEF_HELPER(target_ulong, helper_popc, (target_ulong val))
  25 +DEF_HELPER(void, helper_ldda_asi, (target_ulong addr, int asi, int rd))
25 DEF_HELPER(void, helper_ldf_asi, (target_ulong addr, int asi, int size, int rd)) 26 DEF_HELPER(void, helper_ldf_asi, (target_ulong addr, int asi, int size, int rd))
26 DEF_HELPER(void, helper_stf_asi, (target_ulong addr, int asi, int size, int rd)) 27 DEF_HELPER(void, helper_stf_asi, (target_ulong addr, int asi, int size, int rd))
27 DEF_HELPER(target_ulong, helper_cas_asi, (target_ulong addr, \ 28 DEF_HELPER(target_ulong, helper_cas_asi, (target_ulong addr, \
target-sparc/op_helper.c
@@ -1634,12 +1634,15 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) @@ -1634,12 +1634,15 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1634 } 1634 }
1635 break; 1635 break;
1636 } 1636 }
  1637 + case 0x24: // Nucleus quad LDD 128 bit atomic
  1638 + case 0x2c: // Nucleus quad LDD 128 bit atomic LE
  1639 + // Only ldda allowed
  1640 + raise_exception(TT_ILL_INSN);
  1641 + return 0;
1637 case 0x04: // Nucleus 1642 case 0x04: // Nucleus
1638 case 0x0c: // Nucleus Little Endian (LE) 1643 case 0x0c: // Nucleus Little Endian (LE)
1639 case 0x11: // As if user secondary 1644 case 0x11: // As if user secondary
1640 case 0x19: // As if user secondary LE 1645 case 0x19: // As if user secondary LE
1641 - case 0x24: // Nucleus quad LDD 128 bit atomic  
1642 - case 0x2c: // Nucleus quad LDD 128 bit atomic  
1643 case 0x4a: // UPA config 1646 case 0x4a: // UPA config
1644 case 0x81: // Secondary 1647 case 0x81: // Secondary
1645 case 0x83: // Secondary no-fault 1648 case 0x83: // Secondary no-fault
@@ -1943,12 +1946,15 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) @@ -1943,12 +1946,15 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1943 } 1946 }
1944 } 1947 }
1945 return; 1948 return;
  1949 + case 0x24: // Nucleus quad LDD 128 bit atomic
  1950 + case 0x2c: // Nucleus quad LDD 128 bit atomic LE
  1951 + // Only ldda allowed
  1952 + raise_exception(TT_ILL_INSN);
  1953 + return;
1946 case 0x04: // Nucleus 1954 case 0x04: // Nucleus
1947 case 0x0c: // Nucleus Little Endian (LE) 1955 case 0x0c: // Nucleus Little Endian (LE)
1948 case 0x11: // As if user secondary 1956 case 0x11: // As if user secondary
1949 case 0x19: // As if user secondary LE 1957 case 0x19: // As if user secondary LE
1950 - case 0x24: // Nucleus quad LDD 128 bit atomic  
1951 - case 0x2c: // Nucleus quad LDD 128 bit atomic  
1952 case 0x4a: // UPA config 1958 case 0x4a: // UPA config
1953 case 0x81: // Secondary 1959 case 0x81: // Secondary
1954 case 0x89: // Secondary LE 1960 case 0x89: // Secondary LE
@@ -2144,6 +2150,53 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) @@ -2144,6 +2150,53 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
2144 } 2150 }
2145 #endif /* CONFIG_USER_ONLY */ 2151 #endif /* CONFIG_USER_ONLY */
2146 2152
  2153 +void helper_ldda_asi(target_ulong addr, int asi, int rd)
  2154 +{
  2155 + unsigned int i;
  2156 +
  2157 + if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
  2158 + || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
  2159 + raise_exception(TT_PRIV_ACT);
  2160 +
  2161 + switch (asi) {
  2162 + case 0x24: // Nucleus quad LDD 128 bit atomic
  2163 + case 0x2c: // Nucleus quad LDD 128 bit atomic LE
  2164 + helper_check_align(addr, 0xf);
  2165 + if (rd == 0) {
  2166 + env->gregs[1] = ldq_kernel(addr + 8);
  2167 + if (asi == 0x2c)
  2168 + bswap64s(&env->gregs[1]);
  2169 + } else if (rd < 8) {
  2170 + env->gregs[rd] = ldq_kernel(addr);
  2171 + env->gregs[rd + 1] = ldq_kernel(addr + 8);
  2172 + if (asi == 0x2c) {
  2173 + bswap64s(&env->gregs[rd]);
  2174 + bswap64s(&env->gregs[rd + 1]);
  2175 + }
  2176 + } else {
  2177 + env->regwptr[rd] = ldq_kernel(addr);
  2178 + env->regwptr[rd + 1] = ldq_kernel(addr + 8);
  2179 + if (asi == 0x2c) {
  2180 + bswap64s(&env->regwptr[rd]);
  2181 + bswap64s(&env->regwptr[rd + 1]);
  2182 + }
  2183 + }
  2184 + break;
  2185 + default:
  2186 + helper_check_align(addr, 0x3);
  2187 + if (rd == 0)
  2188 + env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
  2189 + else if (rd < 8) {
  2190 + env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
  2191 + env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
  2192 + } else {
  2193 + env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
  2194 + env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
  2195 + }
  2196 + break;
  2197 + }
  2198 +}
  2199 +
2147 void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) 2200 void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2148 { 2201 {
2149 unsigned int i; 2202 unsigned int i;
target-sparc/translate.c
@@ -1722,20 +1722,15 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn) @@ -1722,20 +1722,15 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1722 tcg_gen_trunc_i64_tl(dst, cpu_tmp64); 1722 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1723 } 1723 }
1724 1724
1725 -static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn) 1725 +static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1726 { 1726 {
1727 - TCGv r_asi, r_size, r_sign; 1727 + TCGv r_asi, r_rd;
1728 1728
1729 r_asi = gen_get_asi(insn, addr); 1729 r_asi = gen_get_asi(insn, addr);
1730 - r_size = tcg_const_i32(8);  
1731 - r_sign = tcg_const_i32(0);  
1732 - tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);  
1733 - tcg_temp_free(r_sign);  
1734 - tcg_temp_free(r_size); 1730 + r_rd = tcg_const_i32(rd);
  1731 + tcg_gen_helper_0_3(helper_ldda_asi, addr, r_asi, r_rd);
  1732 + tcg_temp_free(r_rd);
1735 tcg_temp_free(r_asi); 1733 tcg_temp_free(r_asi);
1736 - tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);  
1737 - tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);  
1738 - tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);  
1739 } 1734 }
1740 1735
1741 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd) 1736 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
@@ -1822,7 +1817,7 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn) @@ -1822,7 +1817,7 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1822 tcg_gen_trunc_i64_tl(dst, cpu_tmp64); 1817 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1823 } 1818 }
1824 1819
1825 -static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn) 1820 +static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1826 { 1821 {
1827 TCGv r_asi, r_size, r_sign; 1822 TCGv r_asi, r_size, r_sign;
1828 1823
@@ -1833,9 +1828,11 @@ static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn) @@ -1833,9 +1828,11 @@ static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1833 tcg_temp_free(r_sign); 1828 tcg_temp_free(r_sign);
1834 tcg_temp_free(r_size); 1829 tcg_temp_free(r_size);
1835 tcg_temp_free(r_asi); 1830 tcg_temp_free(r_asi);
1836 - tcg_gen_trunc_i64_tl(lo, cpu_tmp64); 1831 + tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
  1832 + gen_movl_TN_reg(rd + 1, cpu_tmp0);
1837 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32); 1833 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1838 tcg_gen_trunc_i64_tl(hi, cpu_tmp64); 1834 tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
  1835 + gen_movl_TN_reg(rd, hi);
1839 } 1836 }
1840 1837
1841 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd) 1838 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
@@ -4310,9 +4307,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -4310,9 +4307,8 @@ static void disas_sparc_insn(DisasContext * dc)
4310 if (rd & 1) 4307 if (rd & 1)
4311 goto illegal_insn; 4308 goto illegal_insn;
4312 save_state(dc, cpu_cond); 4309 save_state(dc, cpu_cond);
4313 - gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);  
4314 - gen_movl_TN_reg(rd + 1, cpu_tmp0);  
4315 - break; 4310 + gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
  4311 + goto skip_move;
4316 case 0x19: /* load signed byte alternate */ 4312 case 0x19: /* load signed byte alternate */
4317 #ifndef TARGET_SPARC64 4313 #ifndef TARGET_SPARC64
4318 if (IS_IMM) 4314 if (IS_IMM)
@@ -4403,7 +4399,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -4403,7 +4399,7 @@ static void disas_sparc_insn(DisasContext * dc)
4403 goto illegal_insn; 4399 goto illegal_insn;
4404 } 4400 }
4405 gen_movl_TN_reg(rd, cpu_val); 4401 gen_movl_TN_reg(rd, cpu_val);
4406 -#ifdef TARGET_SPARC64 4402 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4407 skip_move: ; 4403 skip_move: ;
4408 #endif 4404 #endif
4409 } else if (xop >= 0x20 && xop < 0x24) { 4405 } else if (xop >= 0x20 && xop < 0x24) {