103afdc28SJiaxun Yang /*
203afdc28SJiaxun Yang * Loongson CSR instructions translation routines
303afdc28SJiaxun Yang *
403afdc28SJiaxun Yang * Copyright (c) 2023 Jiaxun Yang <jiaxun.yang@flygoat.com>
503afdc28SJiaxun Yang *
603afdc28SJiaxun Yang * SPDX-License-Identifier: GPL-2.0-or-later
703afdc28SJiaxun Yang */
803afdc28SJiaxun Yang
903afdc28SJiaxun Yang #include "qemu/osdep.h"
1003afdc28SJiaxun Yang #include "cpu.h"
1103afdc28SJiaxun Yang #include "tcg/tcg-op.h"
1203afdc28SJiaxun Yang #include "tcg/tcg-op-gvec.h"
1303afdc28SJiaxun Yang #include "exec/helper-gen.h"
1403afdc28SJiaxun Yang #include "translate.h"
1503afdc28SJiaxun Yang
1603afdc28SJiaxun Yang /* Include the auto-generated decoder. */
1703afdc28SJiaxun Yang #include "decode-lcsr.c.inc"
1803afdc28SJiaxun Yang
trans_CPUCFG(DisasContext * ctx,arg_CPUCFG * a)1903afdc28SJiaxun Yang static bool trans_CPUCFG(DisasContext *ctx, arg_CPUCFG *a)
2003afdc28SJiaxun Yang {
2103afdc28SJiaxun Yang TCGv dest = tcg_temp_new();
2203afdc28SJiaxun Yang TCGv src1 = tcg_temp_new();
2303afdc28SJiaxun Yang
2403afdc28SJiaxun Yang gen_load_gpr(src1, a->rs);
25*ad75a51eSRichard Henderson gen_helper_lcsr_cpucfg(dest, tcg_env, src1);
2603afdc28SJiaxun Yang gen_store_gpr(dest, a->rd);
2703afdc28SJiaxun Yang
2803afdc28SJiaxun Yang return true;
2903afdc28SJiaxun Yang }
3003afdc28SJiaxun Yang
3103afdc28SJiaxun Yang #ifndef CONFIG_USER_ONLY
gen_rdcsr(DisasContext * ctx,arg_r * a,void (* func)(TCGv,TCGv_ptr,TCGv))3203afdc28SJiaxun Yang static bool gen_rdcsr(DisasContext *ctx, arg_r *a,
3303afdc28SJiaxun Yang void (*func)(TCGv, TCGv_ptr, TCGv))
3403afdc28SJiaxun Yang {
3503afdc28SJiaxun Yang TCGv dest = tcg_temp_new();
3603afdc28SJiaxun Yang TCGv src1 = tcg_temp_new();
3703afdc28SJiaxun Yang
3803afdc28SJiaxun Yang check_cp0_enabled(ctx);
3903afdc28SJiaxun Yang gen_load_gpr(src1, a->rs);
40*ad75a51eSRichard Henderson func(dest, tcg_env, src1);
4103afdc28SJiaxun Yang gen_store_gpr(dest, a->rd);
4203afdc28SJiaxun Yang
4303afdc28SJiaxun Yang return true;
4403afdc28SJiaxun Yang }
4503afdc28SJiaxun Yang
gen_wrcsr(DisasContext * ctx,arg_r * a,void (* func)(TCGv_ptr,TCGv,TCGv))4603afdc28SJiaxun Yang static bool gen_wrcsr(DisasContext *ctx, arg_r *a,
4703afdc28SJiaxun Yang void (*func)(TCGv_ptr, TCGv, TCGv))
4803afdc28SJiaxun Yang {
4903afdc28SJiaxun Yang TCGv val = tcg_temp_new();
5003afdc28SJiaxun Yang TCGv addr = tcg_temp_new();
5103afdc28SJiaxun Yang
5203afdc28SJiaxun Yang check_cp0_enabled(ctx);
5303afdc28SJiaxun Yang gen_load_gpr(addr, a->rs);
5403afdc28SJiaxun Yang gen_load_gpr(val, a->rd);
55*ad75a51eSRichard Henderson func(tcg_env, addr, val);
5603afdc28SJiaxun Yang
5703afdc28SJiaxun Yang return true;
5803afdc28SJiaxun Yang }
5903afdc28SJiaxun Yang
6003afdc28SJiaxun Yang TRANS(RDCSR, gen_rdcsr, gen_helper_lcsr_rdcsr)
6103afdc28SJiaxun Yang TRANS(DRDCSR, gen_rdcsr, gen_helper_lcsr_drdcsr)
6203afdc28SJiaxun Yang TRANS(WRCSR, gen_wrcsr, gen_helper_lcsr_wrcsr)
6303afdc28SJiaxun Yang TRANS(DWRCSR, gen_wrcsr, gen_helper_lcsr_dwrcsr)
6403afdc28SJiaxun Yang #else
6503afdc28SJiaxun Yang #define GEN_FALSE_TRANS(name) \
6603afdc28SJiaxun Yang static bool trans_##name(DisasContext *ctx, arg_##name * a) \
6703afdc28SJiaxun Yang { \
6803afdc28SJiaxun Yang return false; \
6903afdc28SJiaxun Yang }
7003afdc28SJiaxun Yang
7103afdc28SJiaxun Yang GEN_FALSE_TRANS(RDCSR)
7203afdc28SJiaxun Yang GEN_FALSE_TRANS(DRDCSR)
7303afdc28SJiaxun Yang GEN_FALSE_TRANS(WRCSR)
7403afdc28SJiaxun Yang GEN_FALSE_TRANS(DWRCSR)
7503afdc28SJiaxun Yang #endif
76