diff options
author | Richard Henderson <rth@twiddle.net> | 2015-09-04 07:43:50 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-07-12 11:02:43 -0700 |
commit | 7705091ca4a20c8c2d20e2af5d0a1bcb17296657 (patch) | |
tree | 88b997a4b1d2a77d36acf3377c787bcb85977dbf | |
parent | 6850811e7c56403b0d225a1bffd096abf2ff06f9 (diff) | |
download | qemu-7705091ca4a20c8c2d20e2af5d0a1bcb17296657.tar.gz qemu-7705091ca4a20c8c2d20e2af5d0a1bcb17296657.tar.bz2 qemu-7705091ca4a20c8c2d20e2af5d0a1bcb17296657.zip |
target-sparc: Directly implement easy ldf/stf asis
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | target-sparc/translate.c | 45 |
1 files changed, 45 insertions, 0 deletions
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); |