* [PULL 00/10] qemu-sparc queue 20230628
@ 2023-06-28 11:44 Mark Cave-Ayland
2023-06-28 11:44 ` [PULL 01/10] Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it" Mark Cave-Ayland
` (10 more replies)
0 siblings, 11 replies; 14+ messages in thread
From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw)
To: richard.henderson, qemu-devel
The following changes since commit b111569da9f82fdf05df03184836a4564adef599:
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2023-06-28 08:42:32 +0200)
are available in the Git repository at:
https://github.com/mcayland/qemu.git tags/qemu-sparc-20230628
for you to fetch changes up to 6b90a4cdc04ec7ca94c3f664d63ee43c2046a875:
escc: emulate dip switch language layout settings on SUN keyboard (2023-06-28 10:54:25 +0100)
----------------------------------------------------------------
qemu-sparc queue
- This contains the target/sparc updates to use tcg_gen_lookup_and_goto_ptr
along with a fix for the sun4v niagara machine, and a patch to allow
the keyboard language layout to be set on a SUN keyboard
Please pull, many thanks!
----------------------------------------------------------------
Henrik Carlqvist (1):
escc: emulate dip switch language layout settings on SUN keyboard
Markus Armbruster (1):
Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it"
Richard Henderson (8):
target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb
target/sparc: Fix npc comparison in sparc_tr_insn_start
target/sparc: Drop inline markers from translate.c
target/sparc: Introduce DYNAMIC_PC_LOOKUP
target/sparc: Use DYNAMIC_PC_LOOKUP for conditional branches
target/sparc: Use DYNAMIC_PC_LOOKUP for JMPL
target/sparc: Use DYNAMIC_PC_LOOKUP for v9 RETURN
target/sparc: Use tcg_gen_lookup_and_goto_ptr for v9 WRASI
docs/system/device-emulation.rst | 1 +
docs/system/devices/keyboard.rst | 129 +++++++++++++
docs/system/target-sparc.rst | 2 +-
hw/char/escc.c | 79 +++++++-
hw/sparc64/niagara.c | 6 +-
include/hw/char/escc.h | 1 +
target/sparc/translate.c | 402 ++++++++++++++++++++++-----------------
7 files changed, 439 insertions(+), 181 deletions(-)
create mode 100644 docs/system/devices/keyboard.rst
^ permalink raw reply [flat|nested] 14+ messages in thread* [PULL 01/10] Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it" 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland @ 2023-06-28 11:44 ` Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb Mark Cave-Ayland ` (9 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Markus Armbruster <armbru@redhat.com> This reverts commit 1881f336a33a8a99cb17ab1c57ed953682e8e107. This commit breaks "-drive if=pflash,readonly=on,file=image.iso". It claims to merely replace an open-coded version of blk_name() by a call, but that's not the case. Sorry for the inconvenience! Reported-by: Jakub Jermář <jakub@jermar.eu> Cc: qemu-stable@nongnu.org Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20230515151104.1350155-1-armbru@redhat.com> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- hw/sparc64/niagara.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c index 6725cc61fd..ab3c4ec346 100644 --- a/hw/sparc64/niagara.c +++ b/hw/sparc64/niagara.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "block/block_int-common.h" #include "qemu/units.h" #include "cpu.h" #include "hw/boards.h" @@ -143,9 +144,10 @@ static void niagara_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), NIAGARA_VDISK_BASE, &s->vdisk_ram); dinfo->is_default = 1; - rom_add_file_fixed(blk_name(blk), NIAGARA_VDISK_BASE, -1); + rom_add_file_fixed(blk_bs(blk)->filename, NIAGARA_VDISK_BASE, -1); } else { - error_report("could not load ram disk '%s'", blk_name(blk)); + error_report("could not load ram disk '%s'", + blk_bs(blk)->filename); exit(1); } } -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 01/10] Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it" Mark Cave-Ayland @ 2023-06-28 11:44 ` Mark Cave-Ayland 2023-06-28 13:00 ` BALATON Zoltan 2023-06-28 11:44 ` [PULL 03/10] target/sparc: Fix npc comparison in sparc_tr_insn_start Mark Cave-Ayland ` (8 subsequent siblings) 10 siblings, 1 reply; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-2-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index bad2ec90a0..28d4cdb8b4 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -318,10 +318,10 @@ static void gen_goto_tb(DisasContext *s, int tb_num, tcg_gen_movi_tl(cpu_npc, npc); tcg_gen_exit_tb(s->base.tb, tb_num); } else { - /* jump to another page: currently not optimized */ + /* jump to another page: we can use an indirect jump */ tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); - tcg_gen_exit_tb(NULL, 0); + tcg_gen_lookup_and_goto_ptr(); } } -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb 2023-06-28 11:44 ` [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb Mark Cave-Ayland @ 2023-06-28 13:00 ` BALATON Zoltan 2023-06-28 13:55 ` Richard Henderson 0 siblings, 1 reply; 14+ messages in thread From: BALATON Zoltan @ 2023-06-28 13:00 UTC (permalink / raw) To: Mark Cave-Ayland; +Cc: richard.henderson, qemu-devel [-- Attachment #1: Type: text/plain, Size: 1500 bytes --] On Wed, 28 Jun 2023, Mark Cave-Ayland wrote: > From: Richard Henderson <richard.henderson@linaro.org> > > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > Message-Id: <20230628071202.230991-2-richard.henderson@linaro.org> > Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > --- > target/sparc/translate.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/target/sparc/translate.c b/target/sparc/translate.c > index bad2ec90a0..28d4cdb8b4 100644 > --- a/target/sparc/translate.c > +++ b/target/sparc/translate.c > @@ -318,10 +318,10 @@ static void gen_goto_tb(DisasContext *s, int tb_num, > tcg_gen_movi_tl(cpu_npc, npc); > tcg_gen_exit_tb(s->base.tb, tb_num); > } else { > - /* jump to another page: currently not optimized */ > + /* jump to another page: we can use an indirect jump */ > tcg_gen_movi_tl(cpu_pc, pc); > tcg_gen_movi_tl(cpu_npc, npc); > - tcg_gen_exit_tb(NULL, 0); > + tcg_gen_lookup_and_goto_ptr(); Out of curiosity, did you test this is actually faster? The reason I ask is because I've tried to optimise similar case in target/ppc by using lookup_and_goto_ptr but found it was slower than without that. I think this may depend on the usage but I wonder if that could be a generic issue with lookup_and_goto_ptr or only specific for the case I've tried. Regards, BALATON Zoltan > } > } > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb 2023-06-28 13:00 ` BALATON Zoltan @ 2023-06-28 13:55 ` Richard Henderson 0 siblings, 0 replies; 14+ messages in thread From: Richard Henderson @ 2023-06-28 13:55 UTC (permalink / raw) To: BALATON Zoltan, Mark Cave-Ayland; +Cc: qemu-devel On 6/28/23 15:00, BALATON Zoltan wrote: > On Wed, 28 Jun 2023, Mark Cave-Ayland wrote: >> From: Richard Henderson <richard.henderson@linaro.org> >> >> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> Message-Id: <20230628071202.230991-2-richard.henderson@linaro.org> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> >> --- >> target/sparc/translate.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/target/sparc/translate.c b/target/sparc/translate.c >> index bad2ec90a0..28d4cdb8b4 100644 >> --- a/target/sparc/translate.c >> +++ b/target/sparc/translate.c >> @@ -318,10 +318,10 @@ static void gen_goto_tb(DisasContext *s, int tb_num, >> tcg_gen_movi_tl(cpu_npc, npc); >> tcg_gen_exit_tb(s->base.tb, tb_num); >> } else { >> - /* jump to another page: currently not optimized */ >> + /* jump to another page: we can use an indirect jump */ >> tcg_gen_movi_tl(cpu_pc, pc); >> tcg_gen_movi_tl(cpu_npc, npc); >> - tcg_gen_exit_tb(NULL, 0); >> + tcg_gen_lookup_and_goto_ptr(); > > Out of curiosity, did you test this is actually faster? The reason I ask is because I've > tried to optimise similar case in target/ppc by using lookup_and_goto_ptr but found it was > slower than without that. I think this may depend on the usage but I wonder if that could > be a generic issue with lookup_and_goto_ptr or only specific for the case I've tried. It is faster. It should be *always* faster, because returning to the main cpu loop will always do more work than merely checking to see if we already have built the required TB. If you see slowdowns, then *probably* you are using lookup_and_goto_ptr incorrectly in some instance, such that an interrupt has gotten overly delayed. (One must always return to the main loop after anything that might re-enable interrupts. Otherwise the interrupt handler may be delayed indefinitely. This was in fact the problem with v1 of this patch set.) r~ ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PULL 03/10] target/sparc: Fix npc comparison in sparc_tr_insn_start 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 01/10] Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it" Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb Mark Cave-Ayland @ 2023-06-28 11:44 ` Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 04/10] target/sparc: Drop inline markers from translate.c Mark Cave-Ayland ` (7 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> During translation, npc == address, DYNAMIC_PC, or JUMP_PC. It is only the encoding between here and sparc_restore_state_to_opc that considers JUMP_PC to be a bit within a larger value. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-3-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 28d4cdb8b4..eec6f9ca67 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -5594,7 +5594,7 @@ static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) { DisasContext *dc = container_of(dcbase, DisasContext, base); - if (dc->npc & JUMP_PC) { + if (dc->npc == JUMP_PC) { assert(dc->jump_pc[1] == dc->pc + 4); tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC); } else { -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 04/10] target/sparc: Drop inline markers from translate.c 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (2 preceding siblings ...) 2023-06-28 11:44 ` [PULL 03/10] target/sparc: Fix npc comparison in sparc_tr_insn_start Mark Cave-Ayland @ 2023-06-28 11:44 ` Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 05/10] target/sparc: Introduce DYNAMIC_PC_LOOKUP Mark Cave-Ayland ` (6 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> Let the compiler decide about inlining. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-4-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 237 ++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 126 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index eec6f9ca67..1312c3e94d 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -125,7 +125,7 @@ static int sign_extend(int x, int len) #define IS_IMM (insn & (1<<13)) -static inline void gen_update_fprs_dirty(DisasContext *dc, int rd) +static void gen_update_fprs_dirty(DisasContext *dc, int rd) { #if defined(TARGET_SPARC64) int bit = (rd < 32) ? 1 : 2; @@ -264,7 +264,7 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs) #endif #endif -static inline void gen_address_mask(DisasContext *dc, TCGv addr) +static void gen_address_mask(DisasContext *dc, TCGv addr) { #ifdef TARGET_SPARC64 if (AM_CHECK(dc)) @@ -272,7 +272,7 @@ static inline void gen_address_mask(DisasContext *dc, TCGv addr) #endif } -static inline TCGv gen_load_gpr(DisasContext *dc, int reg) +static TCGv gen_load_gpr(DisasContext *dc, int reg) { if (reg > 0) { assert(reg < 32); @@ -284,7 +284,7 @@ static inline TCGv gen_load_gpr(DisasContext *dc, int reg) } } -static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v) +static void gen_store_gpr(DisasContext *dc, int reg, TCGv v) { if (reg > 0) { assert(reg < 32); @@ -292,7 +292,7 @@ static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v) } } -static inline TCGv gen_dest_gpr(DisasContext *dc, int reg) +static TCGv gen_dest_gpr(DisasContext *dc, int reg) { if (reg > 0) { assert(reg < 32); @@ -326,31 +326,31 @@ static void gen_goto_tb(DisasContext *s, int tb_num, } // XXX suboptimal -static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src) +static void gen_mov_reg_N(TCGv reg, TCGv_i32 src) { tcg_gen_extu_i32_tl(reg, src); tcg_gen_extract_tl(reg, reg, PSR_NEG_SHIFT, 1); } -static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src) +static void gen_mov_reg_Z(TCGv reg, TCGv_i32 src) { tcg_gen_extu_i32_tl(reg, src); tcg_gen_extract_tl(reg, reg, PSR_ZERO_SHIFT, 1); } -static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src) +static void gen_mov_reg_V(TCGv reg, TCGv_i32 src) { tcg_gen_extu_i32_tl(reg, src); tcg_gen_extract_tl(reg, reg, PSR_OVF_SHIFT, 1); } -static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src) +static void gen_mov_reg_C(TCGv reg, TCGv_i32 src) { tcg_gen_extu_i32_tl(reg, src); tcg_gen_extract_tl(reg, reg, PSR_CARRY_SHIFT, 1); } -static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2) +static void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); @@ -465,7 +465,7 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1, } } -static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2) +static void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); @@ -538,7 +538,7 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1, } } -static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2) +static void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2) { TCGv r_temp, zero, t0; @@ -577,7 +577,7 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(dst, cpu_cc_dst); } -static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext) +static void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext) { #if TARGET_LONG_BITS == 32 if (sign_ext) { @@ -602,32 +602,32 @@ static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext) #endif } -static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2) +static void gen_op_umul(TCGv dst, TCGv src1, TCGv src2) { /* zero-extend truncated operands before multiplication */ gen_op_multiply(dst, src1, src2, 0); } -static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2) +static void gen_op_smul(TCGv dst, TCGv src1, TCGv src2) { /* sign-extend truncated operands before multiplication */ gen_op_multiply(dst, src1, src2, 1); } // 1 -static inline void gen_op_eval_ba(TCGv dst) +static void gen_op_eval_ba(TCGv dst) { tcg_gen_movi_tl(dst, 1); } // Z -static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src) +static void gen_op_eval_be(TCGv dst, TCGv_i32 src) { gen_mov_reg_Z(dst, src); } // Z | (N ^ V) -static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src) +static void gen_op_eval_ble(TCGv dst, TCGv_i32 src) { TCGv t0 = tcg_temp_new(); gen_mov_reg_N(t0, src); @@ -638,7 +638,7 @@ static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src) } // N ^ V -static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bl(TCGv dst, TCGv_i32 src) { TCGv t0 = tcg_temp_new(); gen_mov_reg_V(t0, src); @@ -647,7 +647,7 @@ static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src) } // C | Z -static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bleu(TCGv dst, TCGv_i32 src) { TCGv t0 = tcg_temp_new(); gen_mov_reg_Z(t0, src); @@ -656,73 +656,73 @@ static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src) } // C -static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bcs(TCGv dst, TCGv_i32 src) { gen_mov_reg_C(dst, src); } // V -static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bvs(TCGv dst, TCGv_i32 src) { gen_mov_reg_V(dst, src); } // 0 -static inline void gen_op_eval_bn(TCGv dst) +static void gen_op_eval_bn(TCGv dst) { tcg_gen_movi_tl(dst, 0); } // N -static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bneg(TCGv dst, TCGv_i32 src) { gen_mov_reg_N(dst, src); } // !Z -static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bne(TCGv dst, TCGv_i32 src) { gen_mov_reg_Z(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !(Z | (N ^ V)) -static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bg(TCGv dst, TCGv_i32 src) { gen_op_eval_ble(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !(N ^ V) -static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bge(TCGv dst, TCGv_i32 src) { gen_op_eval_bl(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !(C | Z) -static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bgu(TCGv dst, TCGv_i32 src) { gen_op_eval_bleu(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !C -static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bcc(TCGv dst, TCGv_i32 src) { gen_mov_reg_C(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !N -static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bpos(TCGv dst, TCGv_i32 src) { gen_mov_reg_N(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); } // !V -static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src) +static void gen_op_eval_bvc(TCGv dst, TCGv_i32 src) { gen_mov_reg_V(dst, src); tcg_gen_xori_tl(dst, dst, 0x1); @@ -735,23 +735,21 @@ static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src) 2 > 3 unordered */ -static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src, +static void gen_mov_reg_FCC0(TCGv reg, TCGv src, unsigned int fcc_offset) { tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset); tcg_gen_andi_tl(reg, reg, 0x1); } -static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src, - unsigned int fcc_offset) +static void gen_mov_reg_FCC1(TCGv reg, TCGv src, unsigned int fcc_offset) { tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset); tcg_gen_andi_tl(reg, reg, 0x1); } // !0: FCC0 | FCC1 -static inline void gen_op_eval_fbne(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbne(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -760,8 +758,7 @@ static inline void gen_op_eval_fbne(TCGv dst, TCGv src, } // 1 or 2: FCC0 ^ FCC1 -static inline void gen_op_eval_fblg(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fblg(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -770,15 +767,13 @@ static inline void gen_op_eval_fblg(TCGv dst, TCGv src, } // 1 or 3: FCC0 -static inline void gen_op_eval_fbul(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbul(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC0(dst, src, fcc_offset); } // 1: FCC0 & !FCC1 -static inline void gen_op_eval_fbl(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbl(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -787,15 +782,13 @@ static inline void gen_op_eval_fbl(TCGv dst, TCGv src, } // 2 or 3: FCC1 -static inline void gen_op_eval_fbug(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbug(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC1(dst, src, fcc_offset); } // 2: !FCC0 & FCC1 -static inline void gen_op_eval_fbg(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbg(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -804,8 +797,7 @@ static inline void gen_op_eval_fbg(TCGv dst, TCGv src, } // 3: FCC0 & FCC1 -static inline void gen_op_eval_fbu(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbu(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -814,8 +806,7 @@ static inline void gen_op_eval_fbu(TCGv dst, TCGv src, } // 0: !(FCC0 | FCC1) -static inline void gen_op_eval_fbe(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbe(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -825,8 +816,7 @@ static inline void gen_op_eval_fbe(TCGv dst, TCGv src, } // 0 or 3: !(FCC0 ^ FCC1) -static inline void gen_op_eval_fbue(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbue(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -836,16 +826,14 @@ static inline void gen_op_eval_fbue(TCGv dst, TCGv src, } // 0 or 2: !FCC0 -static inline void gen_op_eval_fbge(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbge(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC0(dst, src, fcc_offset); tcg_gen_xori_tl(dst, dst, 0x1); } // !1: !(FCC0 & !FCC1) -static inline void gen_op_eval_fbuge(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbuge(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -855,16 +843,14 @@ static inline void gen_op_eval_fbuge(TCGv dst, TCGv src, } // 0 or 1: !FCC1 -static inline void gen_op_eval_fble(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fble(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC1(dst, src, fcc_offset); tcg_gen_xori_tl(dst, dst, 0x1); } // !2: !(!FCC0 & FCC1) -static inline void gen_op_eval_fbule(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbule(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -874,8 +860,7 @@ static inline void gen_op_eval_fbule(TCGv dst, TCGv src, } // !3: !(FCC0 & FCC1) -static inline void gen_op_eval_fbo(TCGv dst, TCGv src, - unsigned int fcc_offset) +static void gen_op_eval_fbo(TCGv dst, TCGv src, unsigned int fcc_offset) { TCGv t0 = tcg_temp_new(); gen_mov_reg_FCC0(dst, src, fcc_offset); @@ -884,8 +869,8 @@ static inline void gen_op_eval_fbo(TCGv dst, TCGv src, tcg_gen_xori_tl(dst, dst, 0x1); } -static inline void gen_branch2(DisasContext *dc, target_ulong pc1, - target_ulong pc2, TCGv r_cond) +static void gen_branch2(DisasContext *dc, target_ulong pc1, + target_ulong pc2, TCGv r_cond) { TCGLabel *l1 = gen_new_label(); @@ -935,7 +920,7 @@ static void gen_branch_n(DisasContext *dc, target_ulong pc1) } } -static inline void gen_generic_branch(DisasContext *dc) +static void gen_generic_branch(DisasContext *dc) { TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]); TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]); @@ -946,7 +931,7 @@ static inline void gen_generic_branch(DisasContext *dc) /* call this function before using the condition register as it may have been set for a jump */ -static inline void flush_cond(DisasContext *dc) +static void flush_cond(DisasContext *dc) { if (dc->npc == JUMP_PC) { gen_generic_branch(dc); @@ -954,7 +939,7 @@ static inline void flush_cond(DisasContext *dc) } } -static inline void save_npc(DisasContext *dc) +static void save_npc(DisasContext *dc) { if (dc->npc == JUMP_PC) { gen_generic_branch(dc); @@ -964,7 +949,7 @@ static inline void save_npc(DisasContext *dc) } } -static inline void update_psr(DisasContext *dc) +static void update_psr(DisasContext *dc) { if (dc->cc_op != CC_OP_FLAGS) { dc->cc_op = CC_OP_FLAGS; @@ -972,7 +957,7 @@ static inline void update_psr(DisasContext *dc) } } -static inline void save_state(DisasContext *dc) +static void save_state(DisasContext *dc) { tcg_gen_movi_tl(cpu_pc, dc->pc); save_npc(dc); @@ -990,7 +975,7 @@ static void gen_check_align(TCGv addr, int mask) gen_helper_check_align(cpu_env, addr, tcg_constant_i32(mask)); } -static inline void gen_mov_pc_npc(DisasContext *dc) +static void gen_mov_pc_npc(DisasContext *dc) { if (dc->npc == JUMP_PC) { gen_generic_branch(dc); @@ -1004,7 +989,7 @@ static inline void gen_mov_pc_npc(DisasContext *dc) } } -static inline void gen_op_next_insn(void) +static void gen_op_next_insn(void) { tcg_gen_mov_tl(cpu_pc, cpu_npc); tcg_gen_addi_tl(cpu_npc, cpu_npc, 4); @@ -1305,7 +1290,7 @@ static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src) cmp->c2 = tcg_constant_tl(0); } -static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src) +static void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src) { DisasCompare cmp; gen_compare_reg(&cmp, cond, r_src); @@ -1414,7 +1399,7 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, } } -static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) +static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: @@ -1432,7 +1417,7 @@ static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) } } -static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) +static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: @@ -1450,7 +1435,7 @@ static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) } } -static inline void gen_op_fcmpq(int fccno) +static void gen_op_fcmpq(int fccno) { switch (fccno) { case 0: @@ -1468,7 +1453,7 @@ static inline void gen_op_fcmpq(int fccno) } } -static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) +static void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: @@ -1486,7 +1471,7 @@ static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) } } -static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) +static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: @@ -1504,7 +1489,7 @@ static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) } } -static inline void gen_op_fcmpeq(int fccno) +static void gen_op_fcmpeq(int fccno) { switch (fccno) { case 0: @@ -1524,32 +1509,32 @@ static inline void gen_op_fcmpeq(int fccno) #else -static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) +static void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) { gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) +static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmpq(int fccno) +static void gen_op_fcmpq(int fccno) { gen_helper_fcmpq(cpu_fsr, cpu_env); } -static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) +static void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) { gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) +static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmpeq(int fccno) +static void gen_op_fcmpeq(int fccno) { gen_helper_fcmpeq(cpu_fsr, cpu_env); } @@ -1573,12 +1558,12 @@ static int gen_trap_ifnofpu(DisasContext *dc) return 0; } -static inline void gen_op_clear_ieee_excp_and_FTT(void) +static void gen_op_clear_ieee_excp_and_FTT(void) { tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK); } -static inline void gen_fop_FF(DisasContext *dc, int rd, int rs, +static void gen_fop_FF(DisasContext *dc, int rd, int rs, void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32)) { TCGv_i32 dst, src; @@ -1592,8 +1577,8 @@ static inline void gen_fop_FF(DisasContext *dc, int rd, int rs, gen_store_fpr_F(dc, rd, dst); } -static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i32, TCGv_i32)) +static void gen_ne_fop_FF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_i32)) { TCGv_i32 dst, src; @@ -1605,7 +1590,7 @@ static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs, gen_store_fpr_F(dc, rd, dst); } -static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, +static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32)) { TCGv_i32 dst, src1, src2; @@ -1621,8 +1606,8 @@ static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, } #ifdef TARGET_SPARC64 -static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32)) +static void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32)) { TCGv_i32 dst, src1, src2; @@ -1636,8 +1621,8 @@ static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, } #endif -static inline void gen_fop_DD(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64)) +static void gen_fop_DD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64)) { TCGv_i64 dst, src; @@ -1651,8 +1636,8 @@ static inline void gen_fop_DD(DisasContext *dc, int rd, int rs, } #ifdef TARGET_SPARC64 -static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i64, TCGv_i64)) +static void gen_ne_fop_DD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_i64)) { TCGv_i64 dst, src; @@ -1665,7 +1650,7 @@ static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs, } #endif -static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, +static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64)) { TCGv_i64 dst, src1, src2; @@ -1681,8 +1666,8 @@ static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, } #ifdef TARGET_SPARC64 -static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64)) +static void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64)) { TCGv_i64 dst, src1, src2; @@ -1695,8 +1680,8 @@ static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, gen_store_fpr_D(dc, rd, dst); } -static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) +static void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { TCGv_i64 dst, src1, src2; @@ -1709,8 +1694,8 @@ static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, gen_store_fpr_D(dc, rd, dst); } -static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) +static void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { TCGv_i64 dst, src0, src1, src2; @@ -1725,8 +1710,8 @@ static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2, } #endif -static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_ptr)) +static void gen_fop_QQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr)) { gen_op_load_fpr_QT1(QFPREG(rs)); @@ -1738,8 +1723,8 @@ static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs, } #ifdef TARGET_SPARC64 -static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_ptr)) +static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr)) { gen_op_load_fpr_QT1(QFPREG(rs)); @@ -1750,8 +1735,8 @@ static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs, } #endif -static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_ptr)) +static void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_ptr)) { gen_op_load_fpr_QT0(QFPREG(rs1)); gen_op_load_fpr_QT1(QFPREG(rs2)); @@ -1763,7 +1748,7 @@ static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, gen_update_fprs_dirty(dc, QFPREG(rd)); } -static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, +static void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32)) { TCGv_i64 dst; @@ -1779,8 +1764,8 @@ static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, gen_store_fpr_D(dc, rd, dst); } -static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, - void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64)) +static void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64)) { TCGv_i64 src1, src2; @@ -1795,8 +1780,8 @@ static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, } #ifdef TARGET_SPARC64 -static inline void gen_fop_DF(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) +static void gen_fop_DF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) { TCGv_i64 dst; TCGv_i32 src; @@ -1811,8 +1796,8 @@ static inline void gen_fop_DF(DisasContext *dc, int rd, int rs, } #endif -static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) +static void gen_ne_fop_DF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) { TCGv_i64 dst; TCGv_i32 src; @@ -1825,8 +1810,8 @@ static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs, gen_store_fpr_D(dc, rd, dst); } -static inline void gen_fop_FD(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64)) +static void gen_fop_FD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64)) { TCGv_i32 dst; TCGv_i64 src; @@ -1840,8 +1825,8 @@ static inline void gen_fop_FD(DisasContext *dc, int rd, int rs, gen_store_fpr_F(dc, rd, dst); } -static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i32, TCGv_ptr)) +static void gen_fop_FQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_ptr)) { TCGv_i32 dst; @@ -1854,8 +1839,8 @@ static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs, gen_store_fpr_F(dc, rd, dst); } -static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_i64, TCGv_ptr)) +static void gen_fop_DQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr)) { TCGv_i64 dst; @@ -1868,8 +1853,8 @@ static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs, gen_store_fpr_D(dc, rd, dst); } -static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_ptr, TCGv_i32)) +static void gen_ne_fop_QF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr, TCGv_i32)) { TCGv_i32 src; @@ -1881,8 +1866,8 @@ static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs, gen_update_fprs_dirty(dc, QFPREG(rd)); } -static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs, - void (*gen)(TCGv_ptr, TCGv_i64)) +static void gen_ne_fop_QD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr, TCGv_i64)) { TCGv_i64 src; @@ -2813,7 +2798,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs) } #ifndef CONFIG_USER_ONLY -static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env) +static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env) { TCGv_i32 r_tl = tcg_temp_new_i32(); -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 05/10] target/sparc: Introduce DYNAMIC_PC_LOOKUP 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (3 preceding siblings ...) 2023-06-28 11:44 ` [PULL 04/10] target/sparc: Drop inline markers from translate.c Mark Cave-Ayland @ 2023-06-28 11:44 ` Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 06/10] target/sparc: Use DYNAMIC_PC_LOOKUP for conditional branches Mark Cave-Ayland ` (5 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:44 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> Create a new artificial "next pc" which also indicates that nothing has changed within the cpu state which requires returning to the main loop. Pipe this new value though all pc/npc checks. Do not produce this new value yet. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20230628071202.230991-5-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 147 +++++++++++++++++++++++++++------------ 1 file changed, 103 insertions(+), 44 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 1312c3e94d..75aa1a138e 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -37,9 +37,12 @@ #include "exec/helper-info.c.inc" #undef HELPER_H -#define DYNAMIC_PC 1 /* dynamic pc value */ -#define JUMP_PC 2 /* dynamic pc value which takes only two values - according to jump_pc[T2] */ +/* Dynamic PC, must exit to main loop. */ +#define DYNAMIC_PC 1 +/* Dynamic PC, one of two values according to jump_pc[T2]. */ +#define JUMP_PC 2 +/* Dynamic PC, may lookup next TB. */ +#define DYNAMIC_PC_LOOKUP 3 #define DISAS_EXIT DISAS_TARGET_0 @@ -901,22 +904,25 @@ static void gen_branch_n(DisasContext *dc, target_ulong pc1) { target_ulong npc = dc->npc; - if (likely(npc != DYNAMIC_PC)) { + if (npc & 3) { + switch (npc) { + case DYNAMIC_PC: + case DYNAMIC_PC_LOOKUP: + tcg_gen_mov_tl(cpu_pc, cpu_npc); + tcg_gen_addi_tl(cpu_npc, cpu_npc, 4); + tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, + cpu_cond, tcg_constant_tl(0), + tcg_constant_tl(pc1), cpu_npc); + dc->pc = npc; + break; + default: + g_assert_not_reached(); + } + } else { dc->pc = npc; dc->jump_pc[0] = pc1; dc->jump_pc[1] = npc + 4; dc->npc = JUMP_PC; - } else { - TCGv t, z; - - tcg_gen_mov_tl(cpu_pc, cpu_npc); - - tcg_gen_addi_tl(cpu_npc, cpu_npc, 4); - t = tcg_constant_tl(pc1); - z = tcg_constant_tl(0); - tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc); - - dc->pc = DYNAMIC_PC; } } @@ -941,10 +947,19 @@ static void flush_cond(DisasContext *dc) static void save_npc(DisasContext *dc) { - if (dc->npc == JUMP_PC) { - gen_generic_branch(dc); - dc->npc = DYNAMIC_PC; - } else if (dc->npc != DYNAMIC_PC) { + if (dc->npc & 3) { + switch (dc->npc) { + case JUMP_PC: + gen_generic_branch(dc); + dc->npc = DYNAMIC_PC; + break; + case DYNAMIC_PC: + case DYNAMIC_PC_LOOKUP: + break; + default: + g_assert_not_reached(); + } + } else { tcg_gen_movi_tl(cpu_npc, dc->npc); } } @@ -977,13 +992,21 @@ static void gen_check_align(TCGv addr, int mask) static void gen_mov_pc_npc(DisasContext *dc) { - if (dc->npc == JUMP_PC) { - gen_generic_branch(dc); - tcg_gen_mov_tl(cpu_pc, cpu_npc); - dc->pc = DYNAMIC_PC; - } else if (dc->npc == DYNAMIC_PC) { - tcg_gen_mov_tl(cpu_pc, cpu_npc); - dc->pc = DYNAMIC_PC; + if (dc->npc & 3) { + switch (dc->npc) { + case JUMP_PC: + gen_generic_branch(dc); + tcg_gen_mov_tl(cpu_pc, cpu_npc); + dc->pc = DYNAMIC_PC; + break; + case DYNAMIC_PC: + case DYNAMIC_PC_LOOKUP: + tcg_gen_mov_tl(cpu_pc, cpu_npc); + dc->pc = dc->npc; + break; + default: + g_assert_not_reached(); + } } else { dc->pc = dc->npc; } @@ -5501,13 +5524,21 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) break; } /* default case for non jump instructions */ - if (dc->npc == DYNAMIC_PC) { - dc->pc = DYNAMIC_PC; - gen_op_next_insn(); - } else if (dc->npc == 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; + 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; @@ -5578,13 +5609,23 @@ static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs) static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) { DisasContext *dc = container_of(dcbase, DisasContext, base); + target_ulong npc = dc->npc; - if (dc->npc == JUMP_PC) { - assert(dc->jump_pc[1] == dc->pc + 4); - tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC); - } else { - tcg_gen_insn_start(dc->pc, dc->npc); + if (npc & 3) { + switch (npc) { + case JUMP_PC: + assert(dc->jump_pc[1] == dc->pc + 4); + npc = dc->jump_pc[0] | JUMP_PC; + break; + case DYNAMIC_PC: + case DYNAMIC_PC_LOOKUP: + npc = DYNAMIC_PC; + break; + default: + g_assert_not_reached(); + } } + tcg_gen_insn_start(dc->pc, npc); } static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) @@ -5608,19 +5649,37 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) { DisasContext *dc = container_of(dcbase, DisasContext, base); + bool may_lookup; switch (dc->base.is_jmp) { case DISAS_NEXT: case DISAS_TOO_MANY: - if (dc->pc != DYNAMIC_PC && - (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) { + if (((dc->pc | dc->npc) & 3) == 0) { /* static PC and NPC: we can use direct chaining */ gen_goto_tb(dc, 0, dc->pc, dc->npc); - } else { - if (dc->pc != DYNAMIC_PC) { - tcg_gen_movi_tl(cpu_pc, dc->pc); + break; + } + + if (dc->pc & 3) { + switch (dc->pc) { + case DYNAMIC_PC_LOOKUP: + may_lookup = true; + break; + case DYNAMIC_PC: + may_lookup = false; + break; + default: + g_assert_not_reached(); } - save_npc(dc); + } else { + tcg_gen_movi_tl(cpu_pc, dc->pc); + may_lookup = true; + } + + save_npc(dc); + if (may_lookup) { + tcg_gen_lookup_and_goto_ptr(); + } else { tcg_gen_exit_tb(NULL, 0); } break; -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 06/10] target/sparc: Use DYNAMIC_PC_LOOKUP for conditional branches 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (4 preceding siblings ...) 2023-06-28 11:44 ` [PULL 05/10] target/sparc: Introduce DYNAMIC_PC_LOOKUP Mark Cave-Ayland @ 2023-06-28 11:45 ` Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 07/10] target/sparc: Use DYNAMIC_PC_LOOKUP for JMPL Mark Cave-Ayland ` (4 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:45 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> When resolving JUMP_PC, we know this is for a plain branch with no other side effects. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-6-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 75aa1a138e..d7b569d910 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -941,7 +941,7 @@ static void flush_cond(DisasContext *dc) { if (dc->npc == JUMP_PC) { gen_generic_branch(dc); - dc->npc = DYNAMIC_PC; + dc->npc = DYNAMIC_PC_LOOKUP; } } @@ -951,7 +951,7 @@ static void save_npc(DisasContext *dc) switch (dc->npc) { case JUMP_PC: gen_generic_branch(dc); - dc->npc = DYNAMIC_PC; + dc->npc = DYNAMIC_PC_LOOKUP; break; case DYNAMIC_PC: case DYNAMIC_PC_LOOKUP: @@ -997,7 +997,7 @@ static void gen_mov_pc_npc(DisasContext *dc) case JUMP_PC: gen_generic_branch(dc); tcg_gen_mov_tl(cpu_pc, cpu_npc); - dc->pc = DYNAMIC_PC; + dc->pc = DYNAMIC_PC_LOOKUP; break; case DYNAMIC_PC: case DYNAMIC_PC_LOOKUP: -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 07/10] target/sparc: Use DYNAMIC_PC_LOOKUP for JMPL 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (5 preceding siblings ...) 2023-06-28 11:45 ` [PULL 06/10] target/sparc: Use DYNAMIC_PC_LOOKUP for conditional branches Mark Cave-Ayland @ 2023-06-28 11:45 ` Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 08/10] target/sparc: Use DYNAMIC_PC_LOOKUP for v9 RETURN Mark Cave-Ayland ` (3 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:45 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> This is for a plain indirect branch with no other side effects. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-7-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index d7b569d910..17afe98523 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -5058,7 +5058,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) gen_check_align(cpu_tmp0, 3); gen_address_mask(dc, cpu_tmp0); tcg_gen_mov_tl(cpu_npc, cpu_tmp0); - dc->npc = DYNAMIC_PC; + dc->npc = DYNAMIC_PC_LOOKUP; } goto jmp_insn; #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64) -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 08/10] target/sparc: Use DYNAMIC_PC_LOOKUP for v9 RETURN 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (6 preceding siblings ...) 2023-06-28 11:45 ` [PULL 07/10] target/sparc: Use DYNAMIC_PC_LOOKUP for JMPL Mark Cave-Ayland @ 2023-06-28 11:45 ` Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 09/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr for v9 WRASI Mark Cave-Ayland ` (2 subsequent siblings) 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:45 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> After the register window unwind, this is for a plain indirect branch with no further side effects. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-8-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 17afe98523..9148e33283 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -5029,7 +5029,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) gen_mov_pc_npc(dc); gen_check_align(cpu_tmp0, 3); tcg_gen_mov_tl(cpu_npc, cpu_tmp0); - dc->npc = DYNAMIC_PC; + dc->npc = DYNAMIC_PC_LOOKUP; goto jmp_insn; #endif } else { -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 09/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr for v9 WRASI 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (7 preceding siblings ...) 2023-06-28 11:45 ` [PULL 08/10] target/sparc: Use DYNAMIC_PC_LOOKUP for v9 RETURN Mark Cave-Ayland @ 2023-06-28 11:45 ` Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 10/10] escc: emulate dip switch language layout settings on SUN keyboard Mark Cave-Ayland 2023-06-28 15:29 ` [PULL 00/10] qemu-sparc queue 20230628 Richard Henderson 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:45 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Richard Henderson <richard.henderson@linaro.org> We incorporate %asi into tb->flags so that we may generate inline code for the many ASIs for which it is easy to do so. Setting %asi is common for e.g. memcpy and memset performing block copy and clear, so it is worth noticing this case. We must end the TB but do not need to return to the main loop. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230628071202.230991-9-richard.henderson@linaro.org> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- target/sparc/translate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 9148e33283..bd877a5e4a 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -4147,10 +4147,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff); tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, asi)); - /* End TB to notice changed ASI. */ + /* + * End TB to notice changed ASI. + * TODO: Could notice src1 = %g0 and IS_IMM, + * update DisasContext and not exit the TB. + */ save_state(dc); gen_op_next_insn(); - tcg_gen_exit_tb(NULL, 0); + tcg_gen_lookup_and_goto_ptr(); dc->base.is_jmp = DISAS_NORETURN; break; case 0x6: /* V9 wrfprs */ -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL 10/10] escc: emulate dip switch language layout settings on SUN keyboard 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (8 preceding siblings ...) 2023-06-28 11:45 ` [PULL 09/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr for v9 WRASI Mark Cave-Ayland @ 2023-06-28 11:45 ` Mark Cave-Ayland 2023-06-28 15:29 ` [PULL 00/10] qemu-sparc queue 20230628 Richard Henderson 10 siblings, 0 replies; 14+ messages in thread From: Mark Cave-Ayland @ 2023-06-28 11:45 UTC (permalink / raw) To: richard.henderson, qemu-devel From: Henrik Carlqvist <hc981@poolhem.se> SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout of the keyboard. Solaris makes an ioctl to query the value of the dipswitches and uses that value to select keyboard layout. Also the SUN bios like the one in the file ss5.bin uses this value to support at least some keyboard layouts. However, the OpenBIOS provided with qemu is hardcoded to always use an US keyboard layout. Before this patch, qemu allways gave dip switch value 0x21 (US keyboard), this patch uses a command line switch like "-global escc.chnA-sunkbd-layout=de" to select dip switch value. A table is used to lookup values from arguments like: -global escc.chnA-sunkbd-layout=fr -global escc.chnA-sunkbd-layout=es But the patch also accepts numeric dip switch values directly: -global escc.chnA-sunkbd-layout=0x2b -global escc.chnA-sunkbd-layout=43 Both values above are the same and select swedish keyboard as explained in table 3-15 at https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html Unless you want to do a full Solaris installation but happen to have access to a Sun bios file, the easiest way to test that the patch works is to: qemu-system-sparc -global escc.chnA-sunkbd-layout=sv -bios /path/to/ss5.bin If you already happen to have a Solaris installation in a qemu disk image file you can easily try different keyboard layouts after this patch is applied. Signed-off-by: Henrik Carlqvist <hc1245@poolhem.se> Message-Id: <20230623203007.56d3d182.hc981@poolhem.se> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> [MCA edit: update unsigned char to uint8_t, fix spacing issues] Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> --- docs/system/device-emulation.rst | 1 + docs/system/devices/keyboard.rst | 129 +++++++++++++++++++++++++++++++ docs/system/target-sparc.rst | 2 +- hw/char/escc.c | 79 ++++++++++++++++++- include/hw/char/escc.h | 1 + 5 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 docs/system/devices/keyboard.rst diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst index 8d4a1821fa..4491c4cbf7 100644 --- a/docs/system/device-emulation.rst +++ b/docs/system/device-emulation.rst @@ -86,6 +86,7 @@ Emulated Devices devices/ccid.rst devices/cxl.rst devices/ivshmem.rst + devices/keyboard.rst devices/net.rst devices/nvme.rst devices/usb.rst diff --git a/docs/system/devices/keyboard.rst b/docs/system/devices/keyboard.rst new file mode 100644 index 0000000000..a8f9fbebae --- /dev/null +++ b/docs/system/devices/keyboard.rst @@ -0,0 +1,129 @@ +.. _keyboard: + +Sparc32 keyboard +---------------- +SUN Type 4, 5 and 5c keyboards have dip switches to choose the language layout +of the keyboard. Solaris makes an ioctl to query the value of the dipswitches +and uses that value to select keyboard layout. Also the SUN bios like the one +in the file ss5.bin uses this value to support at least some keyboard layouts. +However, the OpenBIOS provided with qemu is hardcoded to always use an +US keyboard layout. + +With the escc.chnA-sunkbd-layout driver property it is possible to select +keyboard layout. Example: + +-global escc.chnA-sunkbd-layout=de + +Depending on type of keyboard, the keyboard can have 6 or 5 dip-switches to +select keyboard layout, giving up to 64 different layouts. Not all +combinations are supported by Solaris and even less by Sun OpenBoot BIOS. + +The dip switch settings can be given as hexadecimal number, decimal number +or in some cases as a language string. Examples: + +-global escc.chnA-sunkbd-layout=0x2b + +-global escc.chnA-sunkbd-layout=43 + +-global escc.chnA-sunkbd-layout=sv + +The above 3 examples all select a swedish keyboard layout. Table 3-15 at +https://docs.oracle.com/cd/E19683-01/806-6642/new-43/index.html explains which +keytable file is used for different dip switch settings. The information +in that table can be summarized in this table: + +.. list-table:: Language selection values for escc.chnA-sunkbd-layout + :widths: 10 10 10 + :header-rows: 1 + + * - Hexadecimal value + - Decimal value + - Language code + * - 0x21 + - 33 + - en-us + * - 0x23 + - 35 + - fr + * - 0x24 + - 36 + - da + * - 0x25 + - 37 + - de + * - 0x26 + - 38 + - it + * - 0x27 + - 39 + - nl + * - 0x28 + - 40 + - no + * - 0x29 + - 41 + - pt + * - 0x2a + - 42 + - es + * - 0x2b + - 43 + - sv + * - 0x2c + - 44 + - fr-ch + * - 0x2d + - 45 + - de-ch + * - 0x2e + - 46 + - en-gb + * - 0x2f + - 47 + - ko + * - 0x30 + - 48 + - tw + * - 0x31 + - 49 + - ja + * - 0x32 + - 50 + - fr-ca + * - 0x33 + - 51 + - hu + * - 0x34 + - 52 + - pl + * - 0x35 + - 53 + - cz + * - 0x36 + - 54 + - ru + * - 0x37 + - 55 + - lv + * - 0x38 + - 56 + - tr + * - 0x39 + - 57 + - gr + * - 0x3a + - 58 + - ar + * - 0x3b + - 59 + - lt + * - 0x3c + - 60 + - nl-be + * - 0x3c + - 60 + - be + +Not all dip switch values have a corresponding language code and both "be" and +"nl-be" correspond to the same dip switch value. By default, if no value is +given to escc.chnA-sunkbd-layout 0x21 (en-us) will be used. diff --git a/docs/system/target-sparc.rst b/docs/system/target-sparc.rst index b55f8d09e9..9ec8c90c14 100644 --- a/docs/system/target-sparc.rst +++ b/docs/system/target-sparc.rst @@ -38,7 +38,7 @@ QEMU emulates the following sun4m peripherals: - Non Volatile RAM M48T02/M48T08 - Slave I/O: timers, interrupt controllers, Zilog serial ports, - keyboard and power/reset logic + :ref:`keyboard` and power/reset logic - ESP SCSI controller with hard disk and CD-ROM support diff --git a/hw/char/escc.c b/hw/char/escc.c index 17a908c59b..4f3872bfe9 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -31,6 +31,8 @@ #include "qemu/module.h" #include "hw/char/escc.h" #include "ui/console.h" + +#include "qemu/cutils.h" #include "trace.h" /* @@ -190,6 +192,7 @@ #define R_MISC1I 14 #define R_EXTINT 15 +static uint8_t sunkbd_layout_dip_switch(const char *sunkbd_layout); static void handle_kbd_command(ESCCChannelState *s, int val); static int serial_can_receive(void *opaque); static void serial_receive_byte(ESCCChannelState *s, int ch); @@ -846,6 +849,79 @@ static QemuInputHandler sunkbd_handler = { .event = sunkbd_handle_event, }; +static uint8_t sunkbd_layout_dip_switch(const char *kbd_layout) +{ + /* Return the value of the dip-switches in a SUN Type 5 keyboard */ + static uint8_t ret = 0xff; + + if ((ret == 0xff) && kbd_layout) { + int i; + struct layout_values { + const char *lang; + uint8_t dip; + } languages[] = + /* + * Dip values from table 3-16 Layouts for Type 4, 5 and 5c Keyboards + */ + { + {"en-us", 0x21}, /* U.S.A. (US5.kt) */ + /* 0x22 is some other US (US_UNIX5.kt) */ + {"fr", 0x23}, /* France (France5.kt) */ + {"da", 0x24}, /* Denmark (Denmark5.kt) */ + {"de", 0x25}, /* Germany (Germany5.kt) */ + {"it", 0x26}, /* Italy (Italy5.kt) */ + {"nl", 0x27}, /* The Netherlands (Netherland5.kt) */ + {"no", 0x28}, /* Norway (Norway.kt) */ + {"pt", 0x29}, /* Portugal (Portugal5.kt) */ + {"es", 0x2a}, /* Spain (Spain5.kt) */ + {"sv", 0x2b}, /* Sweden (Sweden5.kt) */ + {"fr-ch", 0x2c}, /* Switzerland/French (Switzer_Fr5.kt) */ + {"de-ch", 0x2d}, /* Switzerland/German (Switzer_Ge5.kt) */ + {"en-gb", 0x2e}, /* Great Britain (UK5.kt) */ + {"ko", 0x2f}, /* Korea (Korea5.kt) */ + {"tw", 0x30}, /* Taiwan (Taiwan5.kt) */ + {"ja", 0x31}, /* Japan (Japan5.kt) */ + {"fr-ca", 0x32}, /* Canada/French (Canada_Fr5.kt) */ + {"hu", 0x33}, /* Hungary (Hungary5.kt) */ + {"pl", 0x34}, /* Poland (Poland5.kt) */ + {"cz", 0x35}, /* Czech (Czech5.kt) */ + {"ru", 0x36}, /* Russia (Russia5.kt) */ + {"lv", 0x37}, /* Latvia (Latvia5.kt) */ + {"tr", 0x38}, /* Turkey-Q5 (TurkeyQ5.kt) */ + {"gr", 0x39}, /* Greece (Greece5.kt) */ + {"ar", 0x3a}, /* Arabic (Arabic5.kt) */ + {"lt", 0x3b}, /* Lithuania (Lithuania5.kt) */ + {"nl-be", 0x3c}, /* Belgium (Belgian5.kt) */ + {"be", 0x3c}, /* Belgium (Belgian5.kt) */ + }; + + for (i = 0; + i < sizeof(languages) / sizeof(struct layout_values); + i++) { + if (!strcmp(kbd_layout, languages[i].lang)) { + ret = languages[i].dip; + return ret; + } + } + + /* Found no known language code */ + if ((kbd_layout[0] >= '0') && (kbd_layout[0] <= '9')) { + unsigned int tmp; + + /* As a fallback we also accept numeric dip switch value */ + if (!qemu_strtoui(kbd_layout, NULL, 0, &tmp)) { + ret = tmp; + } + } + } + + if (ret == 0xff) { + /* Final fallback if keyboard_layout was not set or recognized */ + ret = 0x21; /* en-us layout */ + } + return ret; +} + static void handle_kbd_command(ESCCChannelState *s, int val) { trace_escc_kbd_command(val); @@ -867,7 +943,7 @@ static void handle_kbd_command(ESCCChannelState *s, int val) case 0xf: clear_queue(s); put_queue(s, 0xfe); - put_queue(s, 0x21); /* en-us layout */ + put_queue(s, sunkbd_layout_dip_switch(s->sunkbd_layout)); break; default: break; @@ -976,6 +1052,7 @@ static Property escc_properties[] = { DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0), DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr), DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr), + DEFINE_PROP_STRING("chnA-sunkbd-layout", ESCCState, chn[1].sunkbd_layout), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h index 7e9482dee2..5669a5b811 100644 --- a/include/hw/char/escc.h +++ b/include/hw/char/escc.h @@ -45,6 +45,7 @@ typedef struct ESCCChannelState { ESCCChnType type; uint8_t rx, tx; QemuInputHandlerState *hs; + char *sunkbd_layout; } ESCCChannelState; struct ESCCState { -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PULL 00/10] qemu-sparc queue 20230628 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland ` (9 preceding siblings ...) 2023-06-28 11:45 ` [PULL 10/10] escc: emulate dip switch language layout settings on SUN keyboard Mark Cave-Ayland @ 2023-06-28 15:29 ` Richard Henderson 10 siblings, 0 replies; 14+ messages in thread From: Richard Henderson @ 2023-06-28 15:29 UTC (permalink / raw) To: Mark Cave-Ayland, qemu-devel On 6/28/23 13:44, Mark Cave-Ayland wrote: > The following changes since commit b111569da9f82fdf05df03184836a4564adef599: > > Merge tag 'ui-pull-request' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2023-06-28 08:42:32 +0200) > > are available in the Git repository at: > > https://github.com/mcayland/qemu.git tags/qemu-sparc-20230628 > > for you to fetch changes up to 6b90a4cdc04ec7ca94c3f664d63ee43c2046a875: > > escc: emulate dip switch language layout settings on SUN keyboard (2023-06-28 10:54:25 +0100) > > ---------------------------------------------------------------- > qemu-sparc queue > > - This contains the target/sparc updates to use tcg_gen_lookup_and_goto_ptr > along with a fix for the sun4v niagara machine, and a patch to allow > the keyboard language layout to be set on a SUN keyboard > > Please pull, many thanks! Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/8.1 as appropriate. r~ ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2023-06-28 15:29 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-06-28 11:44 [PULL 00/10] qemu-sparc queue 20230628 Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 01/10] Revert "hw/sparc64/niagara: Use blk_name() instead of open-coding it" Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 02/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb Mark Cave-Ayland 2023-06-28 13:00 ` BALATON Zoltan 2023-06-28 13:55 ` Richard Henderson 2023-06-28 11:44 ` [PULL 03/10] target/sparc: Fix npc comparison in sparc_tr_insn_start Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 04/10] target/sparc: Drop inline markers from translate.c Mark Cave-Ayland 2023-06-28 11:44 ` [PULL 05/10] target/sparc: Introduce DYNAMIC_PC_LOOKUP Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 06/10] target/sparc: Use DYNAMIC_PC_LOOKUP for conditional branches Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 07/10] target/sparc: Use DYNAMIC_PC_LOOKUP for JMPL Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 08/10] target/sparc: Use DYNAMIC_PC_LOOKUP for v9 RETURN Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 09/10] target/sparc: Use tcg_gen_lookup_and_goto_ptr for v9 WRASI Mark Cave-Ayland 2023-06-28 11:45 ` [PULL 10/10] escc: emulate dip switch language layout settings on SUN keyboard Mark Cave-Ayland 2023-06-28 15:29 ` [PULL 00/10] qemu-sparc queue 20230628 Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).