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 22 DEF_HELPER(target_ulong, helper_alignaddr, (target_ulong addr, \
23 23 target_ulong offset))
24 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 26 DEF_HELPER(void, helper_ldf_asi, (target_ulong addr, int asi, int size, int rd))
26 27 DEF_HELPER(void, helper_stf_asi, (target_ulong addr, int asi, int size, int rd))
27 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 1634 }
1635 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 1642 case 0x04: // Nucleus
1638 1643 case 0x0c: // Nucleus Little Endian (LE)
1639 1644 case 0x11: // As if user secondary
1640 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 1646 case 0x4a: // UPA config
1644 1647 case 0x81: // Secondary
1645 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 1946 }
1944 1947 }
1945 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 1954 case 0x04: // Nucleus
1947 1955 case 0x0c: // Nucleus Little Endian (LE)
1948 1956 case 0x11: // As if user secondary
1949 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 1958 case 0x4a: // UPA config
1953 1959 case 0x81: // Secondary
1954 1960 case 0x89: // Secondary LE
... ... @@ -2144,6 +2150,53 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
2144 2150 }
2145 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 2200 void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2148 2201 {
2149 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 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 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 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 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 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 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 1828 tcg_temp_free(r_sign);
1834 1829 tcg_temp_free(r_size);
1835 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 1833 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1838 1834 tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
  1835 + gen_movl_TN_reg(rd, hi);
1839 1836 }
1840 1837  
1841 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 4307 if (rd & 1)
4311 4308 goto illegal_insn;
4312 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 4312 case 0x19: /* load signed byte alternate */
4317 4313 #ifndef TARGET_SPARC64
4318 4314 if (IS_IMM)
... ... @@ -4403,7 +4399,7 @@ static void disas_sparc_insn(DisasContext * dc)
4403 4399 goto illegal_insn;
4404 4400 }
4405 4401 gen_movl_TN_reg(rd, cpu_val);
4406   -#ifdef TARGET_SPARC64
  4402 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4407 4403 skip_move: ;
4408 4404 #endif
4409 4405 } else if (xop >= 0x20 && xop < 0x24) {
... ...