Revision db166940

b/target-sparc/helper.h
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, \
b/target-sparc/op_helper.c
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 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 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;
b/target-sparc/translate.c
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 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 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 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 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) {

Also available in: Unified diff