mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/sparc: Move asi integer load/store to decodetree
Move LDDA, LDSBA, LDSHA, LDSWA, LDUBA, LDUHA, LDUWA, LDXA, STBA, STDA, STHA, STWA, STXA. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
0880d20b2e
commit
42071fc16d
2 changed files with 48 additions and 111 deletions
|
@ -2162,7 +2162,7 @@ static void gen_helper_st_asi(TCGv_env e, TCGv a, TCGv_i64 r,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void gen_ld_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
|
||||
static void gen_ld_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
|
||||
{
|
||||
switch (da->type) {
|
||||
case GET_ASI_EXCP:
|
||||
|
@ -2193,16 +2193,7 @@ static void gen_ld_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
|
|||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused))
|
||||
gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
|
||||
{
|
||||
DisasASI da = get_asi(dc, insn, memop);
|
||||
|
||||
gen_address_mask(dc, addr);
|
||||
gen_ld_asi0(dc, &da, dst, addr);
|
||||
}
|
||||
|
||||
static void gen_st_asi0(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
|
||||
static void gen_st_asi(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
|
||||
{
|
||||
switch (da->type) {
|
||||
case GET_ASI_EXCP:
|
||||
|
@ -2274,15 +2265,6 @@ static void gen_st_asi0(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
|
|||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused))
|
||||
gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
|
||||
{
|
||||
DisasASI da = get_asi(dc, insn, memop);
|
||||
|
||||
gen_address_mask(dc, addr);
|
||||
gen_st_asi0(dc, &da, src, addr);
|
||||
}
|
||||
|
||||
static void gen_swap_asi0(DisasContext *dc, DisasASI *da,
|
||||
TCGv dst, TCGv src, TCGv addr)
|
||||
{
|
||||
|
@ -2584,7 +2566,7 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
|
|||
}
|
||||
}
|
||||
|
||||
static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
||||
static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
||||
{
|
||||
TCGv hi = gen_dest_gpr(dc, rd);
|
||||
TCGv lo = gen_dest_gpr(dc, rd + 1);
|
||||
|
@ -2660,16 +2642,7 @@ static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
|||
gen_store_gpr(dc, rd + 1, lo);
|
||||
}
|
||||
|
||||
static void __attribute__((unused))
|
||||
gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
|
||||
{
|
||||
DisasASI da = get_asi(dc, insn, MO_TEUQ);
|
||||
|
||||
gen_address_mask(dc, addr);
|
||||
gen_ldda_asi0(dc, &da, addr, rd);
|
||||
}
|
||||
|
||||
static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
||||
static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
||||
{
|
||||
TCGv hi = gen_load_gpr(dc, rd);
|
||||
TCGv lo = gen_load_gpr(dc, rd + 1);
|
||||
|
@ -2761,15 +2734,6 @@ static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
|
|||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused))
|
||||
gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
|
||||
{
|
||||
DisasASI da = get_asi(dc, insn, MO_TEUQ);
|
||||
|
||||
gen_address_mask(dc, addr);
|
||||
gen_stda_asi0(dc, &da, addr, rd);
|
||||
}
|
||||
|
||||
static TCGv get_src1(DisasContext *dc, unsigned int insn)
|
||||
{
|
||||
unsigned int rs1 = GET_FIELD(insn, 13, 17);
|
||||
|
@ -4580,7 +4544,7 @@ static bool do_ld_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
|
|||
da = resolve_asi(dc, a->asi, mop);
|
||||
|
||||
reg = gen_dest_gpr(dc, a->rd);
|
||||
gen_ld_asi0(dc, &da, reg, addr);
|
||||
gen_ld_asi(dc, &da, reg, addr);
|
||||
gen_store_gpr(dc, a->rd, reg);
|
||||
return advance_pc(dc);
|
||||
}
|
||||
|
@ -4604,7 +4568,7 @@ static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
|
|||
da = resolve_asi(dc, a->asi, mop);
|
||||
|
||||
reg = gen_load_gpr(dc, a->rd);
|
||||
gen_st_asi0(dc, &da, reg, addr);
|
||||
gen_st_asi(dc, &da, reg, addr);
|
||||
return advance_pc(dc);
|
||||
}
|
||||
|
||||
|
@ -4626,7 +4590,7 @@ static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a)
|
|||
return false;
|
||||
}
|
||||
da = resolve_asi(dc, a->asi, MO_TEUQ);
|
||||
gen_ldda_asi0(dc, &da, addr, a->rd);
|
||||
gen_ldda_asi(dc, &da, addr, a->rd);
|
||||
return advance_pc(dc);
|
||||
}
|
||||
|
||||
|
@ -4643,7 +4607,7 @@ static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a)
|
|||
return false;
|
||||
}
|
||||
da = resolve_asi(dc, a->asi, MO_TEUQ);
|
||||
gen_stda_asi0(dc, &da, addr, a->rd);
|
||||
gen_stda_asi(dc, &da, addr, a->rd);
|
||||
return advance_pc(dc);
|
||||
}
|
||||
|
||||
|
@ -5475,9 +5439,17 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
case 0x3: /* ldd, load double word */
|
||||
case 0x9: /* ldsb, load signed byte */
|
||||
case 0xa: /* ldsh, load signed halfword */
|
||||
case 0x10: /* lda, V9 lduwa, load word alternate */
|
||||
case 0x11: /* lduba, load unsigned byte alternate */
|
||||
case 0x12: /* lduha, load unsigned halfword alternate */
|
||||
case 0x13: /* ldda, load double word alternate */
|
||||
case 0x19: /* ldsba, load signed byte alternate */
|
||||
case 0x1a: /* ldsha, load signed halfword alternate */
|
||||
g_assert_not_reached(); /* in decodetree */
|
||||
case 0x08: /* V9 ldsw */
|
||||
case 0x0b: /* V9 ldx */
|
||||
case 0x18: /* V9 ldswa */
|
||||
case 0x1b: /* V9 ldxa */
|
||||
goto illegal_insn; /* in decodetree */
|
||||
case 0xd: /* ldstub */
|
||||
gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
|
||||
|
@ -5489,27 +5461,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
dc->mem_idx, MO_TEUL);
|
||||
break;
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
case 0x10: /* lda, V9 lduwa, load word alternate */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
|
||||
break;
|
||||
case 0x11: /* lduba, load unsigned byte alternate */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
|
||||
break;
|
||||
case 0x12: /* lduha, load unsigned halfword alternate */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
|
||||
break;
|
||||
case 0x13: /* ldda, load double word alternate */
|
||||
if (rd & 1) {
|
||||
goto illegal_insn;
|
||||
}
|
||||
gen_ldda_asi(dc, cpu_addr, insn, rd);
|
||||
goto skip_move;
|
||||
case 0x19: /* ldsba, load signed byte alternate */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
|
||||
break;
|
||||
case 0x1a: /* ldsha, load signed halfword alternate */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
|
||||
break;
|
||||
case 0x1d: /* ldstuba -- XXX: should be atomically */
|
||||
gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
|
||||
break;
|
||||
|
@ -5520,12 +5471,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
break;
|
||||
#endif
|
||||
#ifdef TARGET_SPARC64
|
||||
case 0x18: /* V9 ldswa */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
|
||||
break;
|
||||
case 0x1b: /* V9 ldxa */
|
||||
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
|
||||
break;
|
||||
case 0x2d: /* V9 prefetch, no effect */
|
||||
goto skip_move;
|
||||
case 0x30: /* V9 ldfa */
|
||||
|
@ -5557,7 +5502,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
goto illegal_insn;
|
||||
}
|
||||
gen_store_gpr(dc, rd, cpu_val);
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
#if defined(TARGET_SPARC64)
|
||||
skip_move: ;
|
||||
#endif
|
||||
} else if (xop >= 0x20 && xop < 0x24) {
|
||||
|
@ -5610,45 +5555,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
default:
|
||||
goto illegal_insn;
|
||||
}
|
||||
} else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
|
||||
xop == 0xe || xop == 0x1e) {
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
TCGv cpu_val = gen_load_gpr(dc, rd);
|
||||
#endif
|
||||
|
||||
switch (xop) {
|
||||
case 0x4: /* st, store word */
|
||||
case 0x5: /* stb, store byte */
|
||||
case 0x6: /* sth, store halfword */
|
||||
case 0x7: /* std, store double word */
|
||||
g_assert_not_reached(); /* in decodetree */
|
||||
case 0x0e: /* V9 stx */
|
||||
goto illegal_insn; /* in decodetree */
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
case 0x14: /* sta, V9 stwa, store word alternate */
|
||||
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
|
||||
break;
|
||||
case 0x15: /* stba, store byte alternate */
|
||||
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
|
||||
break;
|
||||
case 0x16: /* stha, store halfword alternate */
|
||||
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
|
||||
break;
|
||||
case 0x17: /* stda, store double word alternate */
|
||||
if (rd & 1) {
|
||||
goto illegal_insn;
|
||||
}
|
||||
gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_SPARC64
|
||||
case 0x1e: /* V9 stxa */
|
||||
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
goto illegal_insn;
|
||||
}
|
||||
} else if (xop > 0x23 && xop < 0x28) {
|
||||
if (gen_trap_ifnofpu(dc)) {
|
||||
goto jmp_insn;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue