mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-17 15:12:07 -06:00
target/sparc: Add decodetree infrastructure
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
554abe47c7
commit
878cc6773a
3 changed files with 55 additions and 22 deletions
5
target/sparc/insns.decode
Normal file
5
target/sparc/insns.decode
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# SPDX-License-Identifier: LGPL-2.0+
|
||||||
|
#
|
||||||
|
# Sparc instruction decode definitions.
|
||||||
|
# Copyright (c) 2023 Richard Henderson <rth@twiddle.net>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
gen = decodetree.process('insns.decode')
|
||||||
|
|
||||||
sparc_ss = ss.source_set()
|
sparc_ss = ss.source_set()
|
||||||
|
sparc_ss.add(gen)
|
||||||
sparc_ss.add(files(
|
sparc_ss.add(files(
|
||||||
'cc_helper.c',
|
'cc_helper.c',
|
||||||
'cpu.c',
|
'cpu.c',
|
||||||
|
|
|
@ -3003,6 +3003,47 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Include the auto-generated decoder. */
|
||||||
|
#include "decode-insns.c.inc"
|
||||||
|
|
||||||
|
#define TRANS(NAME, AVAIL, FUNC, ...) \
|
||||||
|
static bool trans_##NAME(DisasContext *dc, arg_##NAME *a) \
|
||||||
|
{ return avail_##AVAIL(dc) && FUNC(dc, __VA_ARGS__); }
|
||||||
|
|
||||||
|
#define avail_ALL(C) true
|
||||||
|
#ifdef TARGET_SPARC64
|
||||||
|
# define avail_32(C) false
|
||||||
|
# define avail_64(C) true
|
||||||
|
#else
|
||||||
|
# define avail_32(C) true
|
||||||
|
# define avail_64(C) false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Default case for non jump instructions. */
|
||||||
|
static bool advance_pc(DisasContext *dc)
|
||||||
|
{
|
||||||
|
if (dc->npc & 3) {
|
||||||
|
switch (dc->npc) {
|
||||||
|
case DYNAMIC_PC:
|
||||||
|
case DYNAMIC_PC_LOOKUP:
|
||||||
|
dc->pc = dc->npc;
|
||||||
|
gen_op_next_insn();
|
||||||
|
break;
|
||||||
|
case JUMP_PC:
|
||||||
|
/* we can do a static jump */
|
||||||
|
gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
|
||||||
|
dc->base.is_jmp = DISAS_NORETURN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dc->pc = dc->npc;
|
||||||
|
dc->npc = dc->npc + 4;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECK_IU_FEATURE(dc, FEATURE) \
|
#define CHECK_IU_FEATURE(dc, FEATURE) \
|
||||||
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
|
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
|
||||||
goto illegal_insn;
|
goto illegal_insn;
|
||||||
|
@ -3011,7 +3052,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
|
||||||
goto nfpu_insn;
|
goto nfpu_insn;
|
||||||
|
|
||||||
/* before an instruction, dc->pc must be static */
|
/* before an instruction, dc->pc must be static */
|
||||||
static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
||||||
{
|
{
|
||||||
unsigned int opc, rs1, rs2, rd;
|
unsigned int opc, rs1, rs2, rd;
|
||||||
TCGv cpu_src1, cpu_src2;
|
TCGv cpu_src1, cpu_src2;
|
||||||
|
@ -5544,26 +5585,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* default case for non jump instructions */
|
advance_pc(dc);
|
||||||
if (dc->npc & 3) {
|
|
||||||
switch (dc->npc) {
|
|
||||||
case DYNAMIC_PC:
|
|
||||||
case DYNAMIC_PC_LOOKUP:
|
|
||||||
dc->pc = dc->npc;
|
|
||||||
gen_op_next_insn();
|
|
||||||
break;
|
|
||||||
case JUMP_PC:
|
|
||||||
/* we can do a static jump */
|
|
||||||
gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
|
|
||||||
dc->base.is_jmp = DISAS_NORETURN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dc->pc = dc->npc;
|
|
||||||
dc->npc = dc->npc + 4;
|
|
||||||
}
|
|
||||||
jmp_insn:
|
jmp_insn:
|
||||||
return;
|
return;
|
||||||
illegal_insn:
|
illegal_insn:
|
||||||
|
@ -5654,7 +5676,10 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
||||||
|
|
||||||
insn = translator_ldl(env, &dc->base, dc->pc);
|
insn = translator_ldl(env, &dc->base, dc->pc);
|
||||||
dc->base.pc_next += 4;
|
dc->base.pc_next += 4;
|
||||||
disas_sparc_insn(dc, insn);
|
|
||||||
|
if (!decode(dc, insn)) {
|
||||||
|
disas_sparc_legacy(dc, insn);
|
||||||
|
}
|
||||||
|
|
||||||
if (dc->base.is_jmp == DISAS_NORETURN) {
|
if (dc->base.is_jmp == DISAS_NORETURN) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue