From 7705091ca4a20c8c2d20e2af5d0a1bcb17296657 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 4 Sep 2015 07:43:50 -0700 Subject: target-sparc: Directly implement easy ldf/stf asis Tested-by: Mark Cave-Ayland Signed-off-by: Richard Henderson --- target-sparc/translate.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'target-sparc') diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 0b29aff68f..2ea6964d9e 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -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); -- cgit v1.2.3