Commit 7705091c authored by Richard Henderson's avatar Richard Henderson
Browse files

target-sparc: Directly implement easy ldf/stf asis

parent 6850811e
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -2282,10 +2282,33 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
                        int insn, int size, int rd)
{
    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
    TCGv_i32 d32;

    switch (da.type) {
    case GET_ASI_EXCP:
        break;

    case GET_ASI_DIRECT:
        gen_address_mask(dc, addr);
        switch (size) {
        case 4:
            d32 = gen_dest_fpr_F(dc);
            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
            gen_store_fpr_F(dc, rd, d32);
            break;
        case 8:
            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
            break;
        case 16:
            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
            tcg_gen_addi_tl(addr, addr, 8);
            tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
            break;
        default:
            g_assert_not_reached();
        }
        break;

    default:
        {
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
@@ -2306,10 +2329,32 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
                        int insn, int size, int rd)
{
    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
    TCGv_i32 d32;

    switch (da.type) {
    case GET_ASI_EXCP:
        break;

    case GET_ASI_DIRECT:
        gen_address_mask(dc, addr);
        switch (size) {
        case 4:
            d32 = gen_load_fpr_F(dc, rd);
            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
            break;
        case 8:
            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
            break;
        case 16:
            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
            tcg_gen_addi_tl(addr, addr, 8);
            tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
            break;
        default:
            g_assert_not_reached();
        }
        break;

    default:
        {
            TCGv_i32 r_asi = tcg_const_i32(da.asi);