From 0fcd07d78eeeded222d4ea5ca2687d6b907c6127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=94=BF=E5=90=AB?= Date: Wed, 3 Jun 2026 23:17:58 +0800 Subject: [PATCH 1/3] linx: remove temporary qemu-user TB diagnostics --- accel/tcg/cpu-exec.c | 5 ----- accel/tcg/translate-all.c | 3 --- linux-user/syscall.c | 6 ------ 3 files changed, 14 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 5c8dc6f0b23da..0cb3adf991191 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -52,9 +52,6 @@ #include "sysemu/runstate-action.h" #include "qemu/timer.h" -uint64_t kenny_tb_exec = 0; -uint64_t kenny_tb_trans = 0; - bool enable_delay_block_intr = false; /* -icount align implementation. */ @@ -214,8 +211,6 @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc, static inline void log_cpu_exec(target_ulong pc, CPUState *cpu, const TranslationBlock *tb) { - kenny_tb_exec++; - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC)) && qemu_log_in_addr_range(pc)) { diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 0940876925b8a..5971cd53ab9f6 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1378,8 +1378,6 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, return tb; } -extern uint64_t kenny_tb_trans; - /* Called with mmap_lock held for user mode emulation. */ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, @@ -1396,7 +1394,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, int64_t ti; #endif - kenny_tb_trans++; assert_memory_lock(); qemu_thread_jit_write(); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 05a49a1beed32..f65045efe6a22 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -13153,9 +13153,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, return ret; } -extern uint64_t kenny_tb_exec; -extern uint64_t kenny_tb_trans; - abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6, abi_long arg7, @@ -13178,9 +13175,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } #endif - if(num==TARGET_NR_exit || num == TARGET_NR_exit_group) - printf("kenny: TB exec = %lu, trans = %lu\n", kenny_tb_exec, kenny_tb_trans); - record_syscall_start(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); From d3abfe4ba50cc31a5b498b8a97c5a3a0286ee496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=94=BF=E5=90=AB?= Date: Wed, 3 Jun 2026 23:17:58 +0800 Subject: [PATCH 2/3] linx: align linux-user syscall and signal ABI --- include/elf.h | 2 +- linux-user/linx/cpu_loop.c | 13 ++++--------- linux-user/linx/signal.c | 2 +- linux-user/linx/target_prctl.h | 1 + linux-user/linx/target_resource.h | 1 + linux-user/linx/target_signal.h | 12 ------------ 6 files changed, 8 insertions(+), 23 deletions(-) create mode 100644 linux-user/linx/target_prctl.h create mode 100644 linux-user/linx/target_resource.h diff --git a/include/elf.h b/include/elf.h index 6ccc4c3cc25bf..6ac79d6036af6 100644 --- a/include/elf.h +++ b/include/elf.h @@ -184,7 +184,7 @@ typedef struct mips_elf_abiflags_v0 { #define EM_LOONGARCH 258 /* LoongArch */ -#define EM_LINX 261 /* Let's use same value with RISCV currently */ +#define EM_LINX 233 /* LinxISA */ /* * This is an interim value that we will use until the committee comes diff --git a/linux-user/linx/cpu_loop.c b/linux-user/linx/cpu_loop.c index 83ae6c2699ed7..c9800fe3a39e3 100644 --- a/linux-user/linx/cpu_loop.c +++ b/linux-user/linx/cpu_loop.c @@ -27,9 +27,6 @@ #include "elf.h" #include "semihosting/common-semi.h" -extern uint64_t kenny_tb_exec; -extern uint64_t kenny_tb_trans; - void cpu_loop(CPULINXState *env) { CPUState *cs = env_cpu(env); @@ -60,14 +57,12 @@ void cpu_loop(CPULINXState *env) case LINX_EXCP_SCALL: env->pc = env->next_bpc; - linx_reset_bstate(env); - - if (env->gpr[xX1] == TARGET_NR_linx_flush_icache) { + if (env->gpr[xA7] == TARGET_NR_linx_flush_icache) { /* linx_flush_icache_syscall is a no-op in QEMU as self-modifying code is automatically detected */ ret = 0; } else { - ret = do_syscall(env, env->gpr[xX1], + ret = do_syscall(env, env->gpr[xA7], env->gpr[xA0], env->gpr[xA1], env->gpr[xA2], @@ -76,14 +71,14 @@ void cpu_loop(CPULINXState *env) env->gpr[xA5], 0, 0); } - if (ret == -TARGET_ERESTARTSYS) { + if (ret == -QEMU_ERESTARTSYS) { /* * Regenerate the exception so that cpu_exec can exit before * executing the instruction. */ cs->exception_index = LINX_EXCP_SCALL; } else { - if (ret != -TARGET_QEMU_ESIGRETURN) + if (ret != -QEMU_ESIGRETURN) env->gpr[xA0] = ret; } diff --git a/linux-user/linx/signal.c b/linux-user/linx/signal.c index 9496cdaaea9db..72b1ea62fc5dc 100644 --- a/linux-user/linx/signal.c +++ b/linux-user/linx/signal.c @@ -187,7 +187,7 @@ long do_rt_sigreturn(CPULINXState *env) target_restore_altstack(&frame->uc.uc_stack, env); unlock_user_struct(frame, frame_addr, 0); - return -TARGET_QEMU_ESIGRETURN; + return -QEMU_ESIGRETURN; badframe: unlock_user_struct(frame, frame_addr, 0); diff --git a/linux-user/linx/target_prctl.h b/linux-user/linx/target_prctl.h new file mode 100644 index 0000000000000..eb53b31ad5546 --- /dev/null +++ b/linux-user/linx/target_prctl.h @@ -0,0 +1 @@ +/* No special prctl support required. */ diff --git a/linux-user/linx/target_resource.h b/linux-user/linx/target_resource.h new file mode 100644 index 0000000000000..227259594c00c --- /dev/null +++ b/linux-user/linx/target_resource.h @@ -0,0 +1 @@ +#include "../generic/target_resource.h" diff --git a/linux-user/linx/target_signal.h b/linux-user/linx/target_signal.h index 43a74ea802e1c..63508bb112398 100644 --- a/linux-user/linx/target_signal.h +++ b/linux-user/linx/target_signal.h @@ -1,18 +1,6 @@ #ifndef LINX_TARGET_SIGNAL_H #define LINX_TARGET_SIGNAL_H -typedef struct target_sigaltstack { - abi_ulong ss_sp; - abi_int ss_flags; - abi_ulong ss_size; -} target_stack_t; - -#define TARGET_SS_ONSTACK 1 -#define TARGET_SS_DISABLE 2 - -#define TARGET_MINSIGSTKSZ 2048 -#define TARGET_SIGSTKSZ 8192 - #include "../generic/signal.h" #define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1 From 74acbcc71176159c86aec5d486daefdd582d6216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=94=BF=E5=90=AB?= Date: Wed, 3 Jun 2026 23:17:58 +0800 Subject: [PATCH 3/3] linx: complete qemu-user block translation fixes --- target/linx/block32.decode | 5 +- target/linx/block48.decode | 67 ++-- target/linx/cpu_bits.h | 24 +- target/linx/cpu_user.h | 1 + target/linx/disas.c | 47 ++- target/linx/insn_trans/trans_block_32.c.inc | 43 +-- .../trans_block_32_private_fvec.c.inc | 2 +- target/linx/insn_trans/trans_block_48.c.inc | 285 ++++++++++++------ .../linx/insn_trans/trans_block_header.c.inc | 16 - target/linx/translate.c | 40 ++- 10 files changed, 351 insertions(+), 179 deletions(-) diff --git a/target/linx/block32.decode b/target/linx/block32.decode index 70b2ee806e936..5b15ab5affbbf 100644 --- a/target/linx/block32.decode +++ b/target/linx/block32.decode @@ -207,7 +207,8 @@ blk_bdim ............ ..... ... ..... 100 0011 @bdim %s_imm_12_1 7:s5 25:7 %s_imm_17 15:s17 %s_imm_17_1 7:s5 20:12 -%s_imm_20 12:s20 !function=ex_shift_12 +%s_imm_20 12:s20 +%s_imm_20_12 12:s20 !function=ex_shift_12 %s_imm_20_1 12:s20 !function=ex_shift_1 %imms 26:6 %imml 20:6 @@ -280,7 +281,7 @@ blk_bdim ............ ..... ... ..... 100 0011 @bdim @arg_setc_ui ............ ..... ... ..... ... .... &arg_setc_i imm=%u_imm_12 %SrcL shamt=%RegDst @arg_addtpc .................... ..... ... .... &arg_pc imm=%s_imm_20 %RegDst @arg_setret .................... ..... ... .... &arg_pc imm=%s_imm_20_1 RegDst=10 -@arg_lui .................... ..... ... .... &arg_pc imm=%s_imm_20 %RegDst +@arg_lui .................... ..... ... .... &arg_pc imm=%s_imm_20_12 %RegDst @arg_branch ....... ..... ..... ... ..... .... . . . &arg_branch imm=%imm_12_1 %SrcR %SrcL @arg_jr ....... ..... ..... ... ..... .... . . . &arg_branch imm=%imm_12_1 SrcR=0 %SrcL diff --git a/target/linx/block48.decode b/target/linx/block48.decode index c63143ba553b7..bf3fb3eb5a13e 100644 --- a/target/linx/block48.decode +++ b/target/linx/block48.decode @@ -53,6 +53,10 @@ blk_start_call ---------------- ................. 100 ..... 000 000 1 ........ %s_imm_17 6:s5 36:12 %s_imm_12 36:s12 %s_imm_12_1 23:s5 41:7 !function=ex_shift_1 +%s_imm_17_sdi 6:s5 23:5 41:7 +%s_imm_17_sdip 11:s5 23:5 41:7 +%s_imm_24 4:s12 36:12 +%u_imm_24 4:12 36:12 %s_imm_28 4:s12 31:17 %s_imm_28_1 4:s12 23:5 36:12 @@ -81,6 +85,7 @@ blk_start_call ---------------- ................. 100 ..... 000 000 1 ........ &arg_sdi imm SrcR SrcD RegDst &arg_sdp SrcD SrcRType SrcR SrcL RegDst SrcD1 &arg_sdip imm SrcR SrcD RegDst SrcD1 +&arg_hl_arith_i imm SrcL RegDst &arg_ld_pcr imm RegDst &arg_sd_pcr imm SrcL @@ -111,9 +116,12 @@ blk_start_call ---------------- ................. 100 ..... 000 000 1 ........ @arg_ldp ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_ld shamt=%shamt_5 %SrcRType %SrcR %SrcL %RegDst0 %RegDst1 %RegDst2 @arg_ldip ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_ldi imm=%s_imm_12 %SrcL %RegDst0 %RegDst1 %RegDst2 @arg_sd ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sd %SrcD %SrcRType %SrcR %SrcL RegDst=%RegDst1 -@arg_sdi ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sdi imm=%s_imm_12_1 %SrcR SrcD=%SrcL RegDst=%RegDst1 +@arg_sdi ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sdi imm=%s_imm_17_sdi %SrcR SrcD=%SrcL RegDst=%RegDst1 @arg_sdp ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sdp %SrcD %SrcRType %SrcR %SrcL RegDst=%RegDst1 SrcD1=%RegDst2 @arg_sdip ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sdip imm=%s_imm_12_1 %SrcR SrcD=%SrcL RegDst=%RegDst1 SrcD1=%RegDst2 +@arg_sdip_cur ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sdip imm=%s_imm_17_sdip %SrcR SrcD=%SrcL RegDst=0 SrcD1=%RegDst2 +@arg_arith_si ................ ............ ..... ... ..... ... ... . ............ ... . &arg_hl_arith_i imm=%s_imm_24 %SrcL RegDst=%RegDst0 +@arg_arith_ui ................ ............ ..... ... ..... ... ... . ............ ... . &arg_hl_arith_i imm=%u_imm_24 %SrcL RegDst=%RegDst0 @arg_ld_pcr ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_ld_pcr imm=%s_imm_28 RegDst=%RegDst0 @arg_sd_pcr ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_sd_pcr imm=%s_imm_28_1 %SrcL @arg_prf ................ ..... .. ..... ..... ... ..... ... ... . ..... ..... .. ... . &arg_prf shamt=%shamt_5 %SrcRType %SrcR %SrcL RegDst=0 %model @@ -244,13 +252,13 @@ blk_sh_upr_48 ---------------- ..... .. ..... ..... 101 00000 100 100 1 ..... blk_sw_upr_48 ---------------- ..... .. ..... ..... 110 00000 100 100 1 ..... 00000 00 111 0 @arg_sd blk_sd_upr_48 ---------------- ..... .. ..... ..... 111 00000 100 100 1 ..... 00000 00 111 0 @arg_sd -blk_sbi_pr_48 ---------------- ............ ..... 000 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_shi_pr_48 ---------------- ............ ..... 001 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_swi_pr_48 ---------------- ............ ..... 010 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_sdi_pr_48 ---------------- ............ ..... 011 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_shi_upr_48 ---------------- ............ ..... 101 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_swi_upr_48 ---------------- ............ ..... 110 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi -blk_sdi_upr_48 ---------------- ............ ..... 111 ..... 101 100 1 ..... 00000 00 111 0 @arg_sdi +blk_sbi_pr_48 ---------------- ....... ..... ..... 000 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_shi_pr_48 ---------------- ....... ..... ..... 001 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_swi_pr_48 ---------------- ....... ..... ..... 010 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_sdi_pr_48 ---------------- ....... ..... ..... 011 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_shi_upr_48 ---------------- ....... ..... ..... 101 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_swi_upr_48 ---------------- ....... ..... ..... 110 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi +blk_sdi_upr_48 ---------------- ....... ..... ..... 111 ..... 101 100 1 ..... ..... 00 111 0 @arg_sdi # Store Post-Index blk_sb_po_48 ---------------- ..... .. ..... ..... 000 00000 100 100 1 ..... 00000 01 111 0 @arg_sd @@ -261,13 +269,22 @@ blk_sh_upo_48 ---------------- ..... .. ..... ..... 101 00000 100 100 1 ..... blk_sw_upo_48 ---------------- ..... .. ..... ..... 110 00000 100 100 1 ..... 00000 01 111 0 @arg_sd blk_sd_upo_48 ---------------- ..... .. ..... ..... 111 00000 100 100 1 ..... 00000 01 111 0 @arg_sd -blk_sbi_po_48 ---------------- ............ ..... 000 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_shi_po_48 ---------------- ............ ..... 001 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_swi_po_48 ---------------- ............ ..... 010 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_sdi_po_48 ---------------- ............ ..... 011 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_shi_upo_48 ---------------- ............ ..... 101 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_swi_upo_48 ---------------- ............ ..... 110 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi -blk_sdi_upo_48 ---------------- ............ ..... 111 ..... 101 100 1 ..... 00000 01 111 0 @arg_sdi +# Store Pair Immediate (current v0.56 bits[5:4] = 01) +blk_sbip_48 ---------------- ....... ..... ..... 000 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_ship_48 ---------------- ....... ..... ..... 001 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_swip_48 ---------------- ....... ..... ..... 010 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_sdip_48 ---------------- ....... ..... ..... 011 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_ship_u_48 ---------------- ....... ..... ..... 101 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_swip_u_48 ---------------- ....... ..... ..... 110 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur +blk_sdip_u_48 ---------------- ....... ..... ..... 111 ..... 101 100 1 ..... ..... 01 111 0 @arg_sdip_cur + +blk_sbi_po_48 ---------------- ....... ..... ..... 000 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_shi_po_48 ---------------- ....... ..... ..... 001 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_swi_po_48 ---------------- ....... ..... ..... 010 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_sdi_po_48 ---------------- ....... ..... ..... 011 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_shi_upo_48 ---------------- ....... ..... ..... 101 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_swi_upo_48 ---------------- ....... ..... ..... 110 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi +blk_sdi_upo_48 ---------------- ....... ..... ..... 111 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdi # Srore Pair Pre-Index blk_sbp_pr_48 ---------------- ..... .. ..... ..... 000 00000 100 100 1 ..... ..... 10 111 0 @arg_sdp @@ -295,14 +312,6 @@ blk_shp_upo_48 ---------------- ..... .. ..... ..... 101 00000 100 100 1 ..... blk_swp_upo_48 ---------------- ..... .. ..... ..... 110 00000 100 100 1 ..... ..... 11 111 0 @arg_sdp blk_sdp_upo_48 ---------------- ..... .. ..... ..... 111 00000 100 100 1 ..... ..... 11 111 0 @arg_sdp -blk_sbip_po_48 ---------------- ....... ..... ..... 000 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_ship_po_48 ---------------- ....... ..... ..... 001 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_swip_po_48 ---------------- ....... ..... ..... 010 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_sdip_po_48 ---------------- ....... ..... ..... 011 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_ship_upo_48 ---------------- ....... ..... ..... 101 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_swip_upo_48 ---------------- ....... ..... ..... 110 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip -blk_sdip_upo_48 ---------------- ....... ..... ..... 111 ..... 101 100 1 ..... ..... 11 111 0 @arg_sdip - # Load PC-Relative blk_lb_pcr_48 ---------------- ................. 000 ..... 011 100 1 ............ 111 0 @arg_ld_pcr blk_lh_pcr_48 ---------------- ................. 001 ..... 011 100 1 ............ 111 0 @arg_ld_pcr @@ -339,6 +348,18 @@ blk_casw_48 ---------------- 0010 . . . ..... ..... 110 ..... 000 101 1 00000 blk_casd_48 ---------------- 0011 . . . ..... ..... 110 ..... 000 101 1 00000 ..... 00 111 0 @arg_cas # Long Immediate +blk_addi_48 ---------------- ............ ..... 000 ..... 001 010 1 ............ 111 0 @arg_arith_ui +blk_subi_48 ---------------- ............ ..... 001 ..... 001 010 1 ............ 111 0 @arg_arith_ui +blk_andi_48 ---------------- ............ ..... 010 ..... 001 010 1 ............ 111 0 @arg_arith_si +blk_ori_48 ---------------- ............ ..... 011 ..... 001 010 1 ............ 111 0 @arg_arith_si +blk_xori_48 ---------------- ............ ..... 100 ..... 001 010 1 ............ 111 0 @arg_arith_si + +blk_addiw_48 ---------------- ............ ..... 000 ..... 011 010 1 ............ 111 0 @arg_arith_ui +blk_subiw_48 ---------------- ............ ..... 001 ..... 011 010 1 ............ 111 0 @arg_arith_ui +blk_andiw_48 ---------------- ............ ..... 010 ..... 011 010 1 ............ 111 0 @arg_arith_si +blk_oriw_48 ---------------- ............ ..... 011 ..... 011 010 1 ............ 111 0 @arg_arith_si +blk_xoriw_48 ---------------- ............ ..... 100 ..... 011 010 1 ............ 111 0 @arg_arith_si + blk_lis_48 ---------------- .................... ..... 000 110 1 ............ 111 0 @arg_lis blk_liu_48 ---------------- .................... ..... 001 110 1 ............ 111 0 @arg_liu diff --git a/target/linx/cpu_bits.h b/target/linx/cpu_bits.h index 0fffab33ec05d..1467cb139bf5d 100644 --- a/target/linx/cpu_bits.h +++ b/target/linx/cpu_bits.h @@ -363,27 +363,29 @@ typedef struct { #define INSTR_TYPE_FP 3 /* Load/Store support only EXT_NONE, EXT_SW, EXT_UW, except AU_NEG */ #define INSTR_TYPE_CMP_SETC_LD_ST 4 +/* CMP/SETC syntax only exposes .sw/.uw; SrcRType=3 is treated as none. */ +#define INSTR_TYPE_CMP_SETC_SWUW 5 /* register ext operation type*/ -#define REG_EXT_NONE 0 -#define REG_EXT_SW 1 -#define REG_EXT_UW 2 -#define REG_EXT_NOT 3 +#define REG_EXT_SW 0 +#define REG_EXT_UW 1 +#define REG_EXT_NOT 2 +#define REG_EXT_NONE 3 -#define AU_NONE 0 -#define AU_SW 1 -#define AU_UW 2 -#define AU_NEG 3 +#define AU_SW 0 +#define AU_UW 1 +#define AU_NEG 2 +#define AU_NONE 3 #define ATOMIC_B 0 #define ATOMIC_H 1 #define ATOMIC_S 2 #define ATOMIC_D 3 -#define SETC_NONE 0 -#define SETC_SW 1 -#define SETC_UW 2 +#define SETC_SW 0 +#define SETC_UW 1 +#define SETC_NONE 3 #define SRC_FVEC_VT_1 0b0000000 #define SRC_FVEC_VT_4 0b0000011 diff --git a/target/linx/cpu_user.h b/target/linx/cpu_user.h index aa4603ee29034..23bda8ac8c37a 100644 --- a/target/linx/cpu_user.h +++ b/target/linx/cpu_user.h @@ -11,6 +11,7 @@ #define xA4 6 #define xA5 7 #define xA6 8 +#define xA7 9 #define xX1 21 /* syscall number */ #endif diff --git a/target/linx/disas.c b/target/linx/disas.c index d01a928971d42..5766055e21b0f 100644 --- a/target/linx/disas.c +++ b/target/linx/disas.c @@ -102,10 +102,10 @@ static inline const char *get_dest_reg1_name(int reg_enc) return linx_dest_reg1_name[reg_enc]; } -static const char srctype_au[4][5] = { "", ".sw", ".uw" , ".neg"}; -static const char srctype_lu[4][5] = { "", ".sw", ".uw" , ".not"}; -static const char srctype_cmp_sect_lu[4][5] = { "", ".sw", ".uw", ".not"}; -static const char srctype_cmp_sect[4][5] = { "", ".sw", ".uw", ".N/A"}; +static const char srctype_au[4][5] = { ".sw", ".uw", ".neg", ""}; +static const char srctype_lu[4][5] = { ".sw", ".uw", ".not", ""}; +static const char srctype_cmp_sect_lu[4][5] = { ".sw", ".uw", ".not", ""}; +static const char srctype_cmp_sect[4][5] = { ".sw", ".uw", "", ""}; static const char cachetype_prf[4][5] = { ".l1", ".l2", ".l3" , ""}; @@ -896,6 +896,17 @@ print_block_insn_srcl_imm_dst(DisasContext *ctx, arg_arg_arith_i *a, OUTPUT(ctx, mnemonic, "%s, %d%s", srcl_name, a->imm, dest_name); } +/* hl.addi SrcL, imm, {->t, ->u, ->RegDst} */ +static void +print_block_insn_hl_srcl_imm_dst(DisasContext *ctx, arg_arg_hl_arith_i *a, + const char *mnemonic) +{ + const char *srcl_name = get_src_reg_name(a->SrcL); + const char *dest_name = get_dest_reg_name(a->RegDst); + + OUTPUT(ctx, mnemonic, "%s, %d%s", srcl_name, a->imm, dest_name); +} + /* srli SrcL, shamt, {->t, ->u, ->RegDst} */ static void print_block_insn_srcl_shamt_dst(DisasContext *ctx, arg_arg_shift_i *a, @@ -2630,6 +2641,17 @@ INSN(srliw, srliw, srcl_shamt_dst) INSN(sraiw, sraiw, srcl_shamt_dst) INSN(slliw, slliw, srcl_shamt_dst) +HL_INSN(addi, hl.addi, hl_srcl_imm_dst) +HL_INSN(subi, hl.subi, hl_srcl_imm_dst) +HL_INSN(andi, hl.andi, hl_srcl_imm_dst) +HL_INSN(ori, hl.ori, hl_srcl_imm_dst) +HL_INSN(xori, hl.xori, hl_srcl_imm_dst) +HL_INSN(addiw, hl.addiw, hl_srcl_imm_dst) +HL_INSN(subiw, hl.subiw, hl_srcl_imm_dst) +HL_INSN(andiw, hl.andiw, hl_srcl_imm_dst) +HL_INSN(oriw, hl.oriw, hl_srcl_imm_dst) +HL_INSN(xoriw, hl.xoriw, hl_srcl_imm_dst) + SIMT_AND_NORMAL_INSN(cmp_eq, cmp.eq, srcl_srcr_au_dst) SIMT_AND_NORMAL_INSN(cmp_ne, cmp.ne, srcl_srcr_au_dst) SIMT_AND_NORMAL_INSN(cmp_and, cmp.and, srcl_srcr_lu_dst) @@ -3117,6 +3139,15 @@ IMM_HL_INSN(shi_upo, hl.shi.upo, imm_srcr_srcd_dst, 0) IMM_HL_INSN(swi_upo, hl.swi.upo, imm_srcr_srcd_dst, 0) IMM_HL_INSN(sdi_upo, hl.sdi.upo, imm_srcr_srcd_dst, 0) +/* Store Pair Immediate */ +IMM_HL_INSN(sbip, hl.sbip, imm_srcr_srcd_dst_srcd1, 0) +IMM_HL_INSN(ship, hl.ship, imm_srcr_srcd_dst_srcd1, 1) +IMM_HL_INSN(swip, hl.swip, imm_srcr_srcd_dst_srcd1, 2) +IMM_HL_INSN(sdip, hl.sdip, imm_srcr_srcd_dst_srcd1, 3) +IMM_HL_INSN(ship_u, hl.ship.u, imm_srcr_srcd_dst_srcd1, 0) +IMM_HL_INSN(swip_u, hl.swip.u, imm_srcr_srcd_dst_srcd1, 0) +IMM_HL_INSN(sdip_u, hl.sdip.u, imm_srcr_srcd_dst_srcd1, 0) + /* Store Pair Pre-Index */ HL_INSN(sbp_pr, hl.sbp.pr, srcd_au_srcr_srcl_dst_srcd1) HL_INSN(shp_pr, hl.shp.pr, srcd_au_srcr_srcl_dst_srcd1) @@ -3143,14 +3174,6 @@ HL_INSN(shp_upo, hl.shp.upo, srcd_au_srcr_srcl_dst_srcd1) HL_INSN(swp_upo, hl.swp.upo, srcd_au_srcr_srcl_dst_srcd1) HL_INSN(sdp_upo, hl.sdp.upo, srcd_au_srcr_srcl_dst_srcd1) -IMM_HL_INSN(sbip_po, hl.sbip.po, imm_srcr_srcd_dst_srcd1, 0) -IMM_HL_INSN(ship_po, hl.ship.po, imm_srcr_srcd_dst_srcd1, 1) -IMM_HL_INSN(swip_po, hl.swip.po, imm_srcr_srcd_dst_srcd1, 2) -IMM_HL_INSN(sdip_po, hl.sdip.po, imm_srcr_srcd_dst_srcd1, 3) -IMM_HL_INSN(ship_upo, hl.ship.upo, imm_srcr_srcd_dst_srcd1, 0) -IMM_HL_INSN(swip_upo, hl.swip.upo, imm_srcr_srcd_dst_srcd1, 0) -IMM_HL_INSN(sdip_upo, hl.sdip.upo, imm_srcr_srcd_dst_srcd1, 0) - HL_INSN(lb_pcr, hl.lb.pcr, ld_imm_dst) HL_INSN(lh_pcr, hl.lh.pcr, ld_imm_dst) HL_INSN(lw_pcr, hl.lw.pcr, ld_imm_dst) diff --git a/target/linx/insn_trans/trans_block_32.c.inc b/target/linx/insn_trans/trans_block_32.c.inc index 24f73163c22d1..b134588adb277 100644 --- a/target/linx/insn_trans/trans_block_32.c.inc +++ b/target/linx/insn_trans/trans_block_32.c.inc @@ -404,32 +404,32 @@ static bool blk_gen_cmp(DisasContext *ctx, arg_blk_cmp_eq_32 *a, int type, static bool trans_blk_cmp_eq_32(DisasContext *ctx, arg_blk_cmp_eq_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_EQ); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_EQ); } static bool trans_blk_cmp_ne_32(DisasContext *ctx, arg_blk_cmp_ne_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_NE); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_NE); } static bool trans_blk_cmp_lt_32(DisasContext *ctx, arg_blk_cmp_lt_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_LT); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_LT); } static bool trans_blk_cmp_ge_32(DisasContext *ctx, arg_blk_cmp_ge_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_GE); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_GE); } static bool trans_blk_cmp_ltu_32(DisasContext *ctx, arg_blk_cmp_ltu_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_LTU); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_LTU); } static bool trans_blk_cmp_geu_32(DisasContext *ctx, arg_blk_cmp_geu_32 *a) { - return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_GEU); + return blk_gen_cmp(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_GEU); } static bool gen_blk_cmp_arith(DisasContext *ctx, arg_blk_cmp_and_32 *a, @@ -548,32 +548,32 @@ static bool blk_gen_setc(DisasContext *ctx, arg_blk_setc_eq_32 *a, int type, static bool trans_blk_setc_eq_32(DisasContext *ctx, arg_blk_setc_eq_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_EQ); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_EQ); } static bool trans_blk_setc_ne_32(DisasContext *ctx, arg_blk_setc_ne_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_NE); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_NE); } static bool trans_blk_setc_lt_32(DisasContext *ctx, arg_blk_setc_lt_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_LT); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_LT); } static bool trans_blk_setc_ge_32(DisasContext *ctx, arg_blk_setc_ge_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_GE); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_GE); } static bool trans_blk_setc_ltu_32(DisasContext *ctx, arg_blk_setc_ltu_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_LTU); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_LTU); } static bool trans_blk_setc_geu_32(DisasContext *ctx, arg_blk_setc_geu_32 *a) { - return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_LD_ST, TCG_COND_GEU); + return blk_gen_setc(ctx, a, INSTR_TYPE_CMP_SETC_SWUW, TCG_COND_GEU); } static bool blk_gen_setc_arith(DisasContext *ctx, arg_blk_setc_and_32 *a, @@ -865,7 +865,7 @@ static bool trans_blk_rev_32(DisasContext *ctx, arg_blk_rev_32 *a) static bool trans_blk_csel_32(DisasContext *ctx, arg_blk_csel_32 *a) { - /* result = (operand3 != 0 ? operand1 : operand2) */ + /* result = (SrcP != 0 ? SrcR : SrcL) */ TCGv src1 = get_src_regx(ctx, a->SrcL); TCGv src2 = get_src_regx(ctx, a->SrcR); /* .neg field */ @@ -874,7 +874,7 @@ static bool trans_blk_csel_32(DisasContext *ctx, arg_blk_csel_32 *a) TCGv dest = get_dst_regx(ctx, a->RegDst); TCGv zero = tcg_constant_tl(0); - tcg_gen_movcond_tl(TCG_COND_NE, dest, SrcP, zero, src1, src2); + tcg_gen_movcond_tl(TCG_COND_NE, dest, SrcP, zero, src2, src1); set_dst_regx(ctx, dest, a->RegDst); @@ -1206,9 +1206,11 @@ static bool trans_blk_maddw_32(DisasContext *ctx, arg_blk_maddw_32 *a) static bool trans_blk_addtpc_32(DisasContext *ctx, arg_blk_addtpc_32 *a) { - TCGv imm = tcg_constant_tl(a->imm); TCGv addr = get_dst_regx(ctx, a->RegDst); - tcg_gen_addi_tl(addr, imm, ctx->base.pc_next); + target_ulong page_base = ctx->base.pc_next & TARGET_PAGE_MASK; + target_long offset = (target_long)a->imm << TARGET_PAGE_BITS; + + tcg_gen_movi_tl(addr, page_base + offset); set_dst_regx(ctx, addr, a->RegDst); return true; @@ -2079,18 +2081,23 @@ static bool trans_blk_fence_i_32(DisasContext *ctx, arg_blk_fence_i_32 *a) static bool trans_blk_acrc_32(DisasContext *ctx, arg_blk_acrc_32 *a) { +#ifndef CONFIG_USER_ONLY static_blk_type_check(ctx, 1 << HEAD_TYPE_SYS); if (get_brhtype(ctx->header_info) != BRANCH_FALL) { qemu_log("acrc do not in the fall block.\n"); } -#ifndef CONFIG_USER_ONLY gen_helper_acrc(cpu_env, tcg_constant_i32(a->RST_Type)); #else - /* In user mode, we do not check request_type. */ + /* + * Linux user-mode treats ACRC SCT_SYS as the syscall instruction. Keep + * the current block state intact so compiler-generated code can resume in + * the same conditional/fall-through block after the syscall returns. + */ tcg_gen_movi_i32(scall_arg, a->RST_Type); tcg_gen_movi_tl(next_bpc, ctx->pc_succ_insn); gen_helper_raise_exception(cpu_env, tcg_constant_i32(LINX_EXCP_SCALL)); + ctx->base.is_jmp = DISAS_NORETURN; #endif return true; diff --git a/target/linx/insn_trans/trans_block_32_private_fvec.c.inc b/target/linx/insn_trans/trans_block_32_private_fvec.c.inc index 326d1da9edfc2..8b3e3a417b02b 100644 --- a/target/linx/insn_trans/trans_block_32_private_fvec.c.inc +++ b/target/linx/insn_trans/trans_block_32_private_fvec.c.inc @@ -2524,7 +2524,7 @@ static bool trans_simt_csel_32(DisasContext *ctx, arg_simt_csel_32 *a) TCGv dest = get_dst_regx_fvec(ctx, a->RegDst, lane_id); TCGv zero = tcg_constant_tl(0); - tcg_gen_movcond_tl(TCG_COND_NE, dest, SrcP, zero, src1, src2); + tcg_gen_movcond_tl(TCG_COND_NE, dest, SrcP, zero, src2, src1); SIMT_WRAP_END_DEST_EXT(a->RegDst) diff --git a/target/linx/insn_trans/trans_block_48.c.inc b/target/linx/insn_trans/trans_block_48.c.inc index 75eb07026418d..c4e5569f05af2 100644 --- a/target/linx/insn_trans/trans_block_48.c.inc +++ b/target/linx/insn_trans/trans_block_48.c.inc @@ -18,7 +18,7 @@ static bool trans_blk_lui_48(DisasContext *ctx, arg_blk_lui_48 *a) { - TCGv imm = tcg_constant_i64((uint64_t)a->imm << 32); + TCGv imm = tcg_constant_i64((int64_t)(int32_t)a->imm); TCGv addr = get_dst_regx(ctx, a->RegDst); tcg_gen_mov_tl(addr, imm); @@ -26,6 +26,106 @@ static bool trans_blk_lui_48(DisasContext *ctx, arg_blk_lui_48 *a) return true; } +typedef enum { + BLK_ARITHI_ADD, + BLK_ARITHI_SUB, + BLK_ARITHI_AND, + BLK_ARITHI_OR, + BLK_ARITHI_XOR, +} BlkArithI; + +static bool gen_blk_arith_i_48(DisasContext *ctx, int imm, int SrcL, + int RegDst, BlkArithI op, bool word) +{ + TCGv src_l = get_src_regx(ctx, SrcL); + TCGv dest = get_dst_regx(ctx, RegDst); + + switch (op) { + case BLK_ARITHI_ADD: + tcg_gen_addi_tl(dest, src_l, imm); + break; + case BLK_ARITHI_SUB: + tcg_gen_subi_tl(dest, src_l, imm); + break; + case BLK_ARITHI_AND: + tcg_gen_andi_tl(dest, src_l, imm); + break; + case BLK_ARITHI_OR: + tcg_gen_ori_tl(dest, src_l, imm); + break; + case BLK_ARITHI_XOR: + tcg_gen_xori_tl(dest, src_l, imm); + break; + } + + if (word) { + tcg_gen_ext32s_tl(dest, dest); + } + + set_dst_regx(ctx, dest, RegDst); + return true; +} + +static bool trans_blk_addi_48(DisasContext *ctx, arg_blk_addi_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_ADD, false); +} + +static bool trans_blk_subi_48(DisasContext *ctx, arg_blk_subi_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_SUB, false); +} + +static bool trans_blk_andi_48(DisasContext *ctx, arg_blk_andi_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_AND, false); +} + +static bool trans_blk_ori_48(DisasContext *ctx, arg_blk_ori_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_OR, false); +} + +static bool trans_blk_xori_48(DisasContext *ctx, arg_blk_xori_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_XOR, false); +} + +static bool trans_blk_addiw_48(DisasContext *ctx, arg_blk_addiw_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_ADD, true); +} + +static bool trans_blk_subiw_48(DisasContext *ctx, arg_blk_subiw_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_SUB, true); +} + +static bool trans_blk_andiw_48(DisasContext *ctx, arg_blk_andiw_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_AND, true); +} + +static bool trans_blk_oriw_48(DisasContext *ctx, arg_blk_oriw_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_OR, true); +} + +static bool trans_blk_xoriw_48(DisasContext *ctx, arg_blk_xoriw_48 *a) +{ + return gen_blk_arith_i_48(ctx, a->imm, a->SrcL, a->RegDst, + BLK_ARITHI_XOR, true); +} + static bool trans_blk_mul_48(DisasContext *ctx, arg_blk_mul_48 *a) { TCGv src1 = get_src_regx(ctx, a->SrcL); @@ -297,13 +397,13 @@ static void gen_blk_load_po_48(DisasContext *ctx, MemOp memop, bool is_addr, tcg_gen_shli_tl(shift, shift, shamt); - /* shift becomes the "addr" */ + /* Current v0.56 bits[5:4]=01 encodes HL.*P load-pair, not old *.PO. */ tcg_gen_add_tl(shift, addr_base, shift); + TCGv addr1 = temp_new(ctx); + tcg_gen_addi_tl(addr1, shift, memop_size(memop)); - set_dst_regx(ctx, shift, dest1); - - /* Use the address to load data from memory */ - gen_blk_load_48_op(ctx, memop, is_addr, addr_base, dest0); + gen_blk_load_48_op(ctx, memop, is_addr, shift, dest0); + gen_blk_load_48_op(ctx, memop, is_addr, addr1, dest1); } static bool trans_blk_lb_po_48(DisasContext *ctx, arg_blk_lb_po_48 *a) @@ -365,10 +465,12 @@ static void gen_blk_load_po_48_imm(DisasContext *ctx, MemOp memop, bool is_addr, TCGv addr = temp_new(ctx); tcg_gen_addi_tl(addr, addr_base, imm << scaled_shift); + TCGv addr1 = temp_new(ctx); + tcg_gen_addi_tl(addr1, addr, memop_size(memop)); - set_dst_regx(ctx, addr_base, dest1); - + /* Current v0.56 bits[5:4]=01 encodes HL.*IP load-pair, not old *.I.PO. */ gen_blk_load_48_op(ctx, memop, is_addr, addr, dest0); + gen_blk_load_48_op(ctx, memop, is_addr, addr1, dest1); } static bool trans_blk_lbi_po_48(DisasContext *ctx, arg_blk_lbi_po_48 *a) @@ -638,10 +740,8 @@ static void gen_blk_load_p_po_48(DisasContext *ctx, MemOp memop, bool is_addr, /* shift becomes the "addr" */ tcg_gen_add_tl(shift, addr_base, shift); - set_dst_regx(ctx, addr_base, dest2); - gen_blk_load_48_op(ctx, memop, is_addr, addr_base, dest0); - gen_blk_load_48_op(ctx, memop, is_addr, shift, dest1); + set_dst_regx(ctx, shift, dest1); } static bool trans_blk_lbp_po_48(DisasContext *ctx, arg_blk_lbp_po_48 *a) @@ -703,10 +803,8 @@ static void gen_blk_load_p_po_48_imm(DisasContext *ctx, MemOp memop, TCGv addr = temp_new(ctx); tcg_gen_addi_tl(addr, addr_base, imm << scaled_shift); - set_dst_regx(ctx, addr, dest2); - - gen_blk_load_48_op(ctx, memop, is_addr, addr, dest0); - gen_blk_load_48_op(ctx, memop, is_addr, addr_base, dest1); + gen_blk_load_48_op(ctx, memop, is_addr, addr_base, dest0); + set_dst_regx(ctx, addr, dest1); } static bool trans_blk_lbip_po_48(DisasContext *ctx, arg_blk_lbip_po_48 *a) @@ -1098,6 +1196,81 @@ static bool trans_blk_sdi_upo_48(DisasContext *ctx, arg_blk_sdi_upo_48 *a) return true; } +static void gen_blk_store_pair_48_imm(DisasContext *ctx, MemOp memop, + int imm, int SrcR, int SrcD, + int SrcD1, int width, + int scaled_shift, bool is_addr, + int RegDst) +{ + TCGv addr_base = get_src_regx(ctx, SrcR); + TCGv data = get_src_regx(ctx, SrcD); + TCGv data1 = get_src_regx(ctx, SrcD1); + TCGv addr = temp_new(ctx); + TCGv addr1 = temp_new(ctx); + + tcg_gen_addi_tl(addr, addr_base, imm << scaled_shift); + tcg_gen_addi_tl(addr1, addr, width); + + gen_blk_store_48_op(ctx, memop, is_addr, addr, data, width, RegDst); + gen_blk_store_48_op(ctx, memop, is_addr, addr1, data1, width, RegDst); +} + +static bool trans_blk_sbip_48(DisasContext *ctx, arg_blk_sbip_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_SB, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LB_SB, OFFSET_LB_SB, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_ship_48(DisasContext *ctx, arg_blk_ship_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TESW, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LH_SH, OFFSET_LH_SH, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_swip_48(DisasContext *ctx, arg_blk_swip_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TESL, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LW_SW, OFFSET_LW_SW, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_sdip_48(DisasContext *ctx, arg_blk_sdip_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TEQ, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LD_SD, OFFSET_LD_SD, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_ship_u_48(DisasContext *ctx, arg_blk_ship_u_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TESW, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LH_SH, UNSCALED, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_swip_u_48(DisasContext *ctx, arg_blk_swip_u_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TESL, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LW_SW, UNSCALED, + NO_ADDR, REGDST_0); + return true; +} + +static bool trans_blk_sdip_u_48(DisasContext *ctx, arg_blk_sdip_u_48 *a) +{ + gen_blk_store_pair_48_imm(ctx, MO_TEQ, a->imm, a->SrcR, a->SrcD, + a->SrcD1, BYTES_LD_SD, UNSCALED, + NO_ADDR, REGDST_0); + return true; +} + static void gen_blk_store_p_pr_48(DisasContext *ctx, MemOp memop, int SrcD, int SrcD1, int SrcRType, @@ -1332,80 +1505,6 @@ static bool trans_blk_sdp_upo_48(DisasContext *ctx, arg_blk_sdp_upo_48 *a) UNSCALED, NO_ADDR, REGDST_0, a->RegDst); return true; } -static void gen_blk_store_p_po_48_imm(DisasContext *ctx, MemOp memop, - int imm, int SrcR, int SrcD, - int SrcD1, int width, int scaled_shift, - bool is_addr, int RegDst, int reg) -{ - TCGv addr_base = get_src_regx(ctx, SrcR); - TCGv data = get_src_regx(ctx, SrcD); - TCGv data1 = get_src_regx(ctx, SrcD1); - TCGv addr = temp_new(ctx); - - tcg_gen_addi_tl(addr, addr_base, imm << scaled_shift); - - set_dst_regx(ctx, addr, reg); - - gen_blk_store_48_op(ctx, memop, is_addr, addr_base, data, width, RegDst); - gen_blk_store_48_op(ctx, memop, is_addr, addr_base, data1, width, RegDst); -} - -static bool trans_blk_sbip_po_48(DisasContext *ctx, arg_blk_sbip_po_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_SB, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LB_SB, - OFFSET_LB_SB, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_ship_po_48(DisasContext *ctx, arg_blk_ship_po_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TESW, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LH_SH, - OFFSET_LH_SH, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_swip_po_48(DisasContext *ctx, arg_blk_swip_po_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TESL, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LW_SW, - OFFSET_LW_SW, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_sdip_po_48(DisasContext *ctx, arg_blk_sdip_po_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TEQ, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LD_SD, - OFFSET_LD_SD, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_ship_upo_48(DisasContext *ctx, arg_blk_ship_upo_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TESW, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LH_SH, - UNSCALED, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_swip_upo_48(DisasContext *ctx, arg_blk_swip_upo_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TESL, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LW_SW, - UNSCALED, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - -static bool trans_blk_sdip_upo_48(DisasContext *ctx, arg_blk_sdip_upo_48 *a) -{ - gen_blk_store_p_po_48_imm(ctx, MO_TEQ, a->imm, a->SrcR, - a->SrcD, a->SrcD1, BYTES_LD_SD, - UNSCALED, NO_ADDR, REGDST_0, a->RegDst); - return true; -} - static void gen_blk_load_48_symbol(DisasContext *ctx, MemOp memop, bool is_addr, int imm, int dest_reg_enc, int scaled_shift) @@ -1484,28 +1583,28 @@ static void gen_blk_store_48_symbol(DisasContext *ctx, MemOp memop, static bool trans_blk_sb_pcr_48(DisasContext *ctx, arg_blk_sb_pcr_48 *a) { gen_blk_store_48_symbol(ctx, MO_SB, a->imm, a->SrcL, BYTES_LB_SB, - OFFSET_LB_SB, NO_ADDR, REGDST_0); + UNSCALED, NO_ADDR, REGDST_0); return true; } static bool trans_blk_sh_pcr_48(DisasContext *ctx, arg_blk_sh_pcr_48 *a) { gen_blk_store_48_symbol(ctx, MO_TESW, a->imm, a->SrcL, BYTES_LH_SH, - OFFSET_LH_SH, NO_ADDR, REGDST_0); + UNSCALED, NO_ADDR, REGDST_0); return true; } static bool trans_blk_sw_pcr_48(DisasContext *ctx, arg_blk_sw_pcr_48 *a) { gen_blk_store_48_symbol(ctx, MO_TESL, a->imm, a->SrcL, BYTES_LW_SW, - OFFSET_LW_SW, NO_ADDR, REGDST_0); + UNSCALED, NO_ADDR, REGDST_0); return true; } static bool trans_blk_sd_pcr_48(DisasContext *ctx, arg_blk_sd_pcr_48 *a) { gen_blk_store_48_symbol(ctx, MO_TEQ, a->imm, a->SrcL, BYTES_LD_SD, - OFFSET_LD_SD, NO_ADDR, REGDST_0); + UNSCALED, NO_ADDR, REGDST_0); return true; } diff --git a/target/linx/insn_trans/trans_block_header.c.inc b/target/linx/insn_trans/trans_block_header.c.inc index ef10270dac6c6..cd1ca6cffa617 100644 --- a/target/linx/insn_trans/trans_block_header.c.inc +++ b/target/linx/insn_trans/trans_block_header.c.inc @@ -608,31 +608,15 @@ static bool trans_blk_start_ret(DisasContext *ctx, arg_blk_start_ret *a) static bool trans_blk_offset_cond(DisasContext *ctx, arg_blk_offset_cond *a) { - uint64_t saved_header_info = ctx->header_info; - target_long saved_carg_tgt = ctx->carg_tgt; - GEN_LINX_INIT_HEAD(ctx, a, BRANCH_CONDITIONAL, HEAD_TYPE_STD, a->bnext_low); - /* - * Short offset headers are nested helper edges inside an outer block. - * Keep the conditional semantics for this tiny block, but restore the - * outer block state for the next TB when control falls through. - */ - tcg_gen_movi_i64(header_info, saved_header_info); - tcg_gen_movi_tl(carg_tgt, saved_carg_tgt); - return true; } static bool trans_blk_offset_direct_call(DisasContext *ctx, arg_blk_offset_direct_call *a) { - uint64_t saved_header_info = ctx->header_info; - target_long saved_carg_tgt = ctx->carg_tgt; - GEN_LINX_INIT_HEAD(ctx, a, BRANCH_CALL, HEAD_TYPE_STD, a->bnext_low); - tcg_gen_movi_i64(header_info, saved_header_info); - tcg_gen_movi_tl(carg_tgt, saved_carg_tgt); return true; } diff --git a/target/linx/translate.c b/target/linx/translate.c index f168509345dc6..43c3b874d0348 100644 --- a/target/linx/translate.c +++ b/target/linx/translate.c @@ -770,13 +770,25 @@ static TCGv conver_src_value(DisasContext *ctx, TCGv SrcReg, int SrcType, int fl { TCGv t = temp_new(ctx); - if (SrcType == INSTR_TYPE_CMP_SETC_LD_ST) { + if (SrcType == INSTR_TYPE_CMP_SETC_SWUW) { + if (flag == AU_NONE || flag == AU_NEG) { + tcg_gen_mov_tl(t, SrcReg); + } else if (flag == AU_SW) { + tcg_gen_ext32s_tl(t, SrcReg); + } else if (flag == AU_UW) { + tcg_gen_ext32u_tl(t, SrcReg); + } else { + g_assert_not_reached(); + } + } else if (SrcType == INSTR_TYPE_CMP_SETC_LD_ST) { if (flag == AU_NONE) { tcg_gen_mov_tl(t, SrcReg); } else if (flag == AU_SW) { tcg_gen_ext32s_tl(t, SrcReg); } else if (flag == AU_UW) { tcg_gen_ext32u_tl(t, SrcReg); + } else if (flag == AU_NEG) { + tcg_gen_neg_tl(t, SrcReg); } else { fprintf(stderr, "error SrcRType:%d in INSTR_TYPE_AU_LD_ST\n", flag); g_assert_not_reached(); @@ -935,6 +947,22 @@ static int get_inst_len(uint16_t opcode) return inst_size; } +static bool is_blk_setret_32(uint32_t opcode) +{ + return extract32(opcode, 0, 4) == 0x7 && + extract32(opcode, 4, 3) == 0x0 && + extract32(opcode, 7, 5) == xRA; +} + +static bool has_head_setret_padding(DisasContext *ctx, int head_size) +{ + CPULINXState *env = ctx->cs->env_ptr; + uint16_t pad = cpu_lduw_code(env, ctx->base.pc_next + head_size); + uint32_t next = cpu_ldl_code(env, ctx->base.pc_next + head_size + 2); + + return pad == 0xfffe && is_blk_setret_32(next); +} + /* Determine if it's the head command */ static bool is_head_block(DisasContext *ctx, uint64_t opcode) { @@ -1111,11 +1139,13 @@ static void linx_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) DisasContext *ctx = container_of(dcbase, DisasContext, base); CPULINXState *env = cpu->env_ptr; uint64_t opcode = cpu_lduw_code(env, ctx->base.pc_next); + bool is_head; ctx->instr_attr = 0; ctx->insn_size = get_inst_len(opcode); + is_head = is_head_block(ctx, opcode); - if (!is_head_block(ctx, opcode)) { + if (!is_head) { if (!is_valid_linx_addr(ctx->tpc1)) { ctx->tpc1 = ctx->base.pc_next; tcg_gen_movi_i64(tpc1, ctx->base.pc_next); @@ -1139,8 +1169,12 @@ static void linx_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) trace_linx_mini(ctx->base.pc_next); ctx->pc_succ_insn = ctx->base.pc_next + ctx->insn_size; + if (is_head && (ctx->insn_size == 4 || ctx->insn_size == 6) && + has_head_setret_padding(ctx, ctx->insn_size)) { + ctx->pc_succ_insn += 2; + } - if (!is_head_block(ctx, opcode) && + if (!is_head && ctx->brh_type == BRANCH_RET && ctx->carg_tgt == ctx->base.pc_next) { /*