| /* |
| * Loongson CSR instructions translation routines |
| * |
| * Copyright (c) 2023 Jiaxun Yang <jiaxun.yang@flygoat.com> |
| * |
| * SPDX-License-Identifier: GPL-2.0-or-later |
| */ |
| |
| #include "qemu/osdep.h" |
| #include "cpu.h" |
| #include "tcg/tcg-op.h" |
| #include "tcg/tcg-op-gvec.h" |
| #include "exec/helper-gen.h" |
| #include "translate.h" |
| |
| /* Include the auto-generated decoder. */ |
| #include "decode-lcsr.c.inc" |
| |
| static bool trans_CPUCFG(DisasContext *ctx, arg_CPUCFG *a) |
| { |
| TCGv dest = tcg_temp_new(); |
| TCGv src1 = tcg_temp_new(); |
| |
| gen_load_gpr(src1, a->rs); |
| gen_helper_lcsr_cpucfg(dest, tcg_env, src1); |
| gen_store_gpr(dest, a->rd); |
| |
| return true; |
| } |
| |
| #ifndef CONFIG_USER_ONLY |
| static bool gen_rdcsr(DisasContext *ctx, arg_r *a, |
| void (*func)(TCGv, TCGv_ptr, TCGv)) |
| { |
| TCGv dest = tcg_temp_new(); |
| TCGv src1 = tcg_temp_new(); |
| |
| check_cp0_enabled(ctx); |
| gen_load_gpr(src1, a->rs); |
| func(dest, tcg_env, src1); |
| gen_store_gpr(dest, a->rd); |
| |
| return true; |
| } |
| |
| static bool gen_wrcsr(DisasContext *ctx, arg_r *a, |
| void (*func)(TCGv_ptr, TCGv, TCGv)) |
| { |
| TCGv val = tcg_temp_new(); |
| TCGv addr = tcg_temp_new(); |
| |
| check_cp0_enabled(ctx); |
| gen_load_gpr(addr, a->rs); |
| gen_load_gpr(val, a->rd); |
| func(tcg_env, addr, val); |
| |
| return true; |
| } |
| |
| TRANS(RDCSR, gen_rdcsr, gen_helper_lcsr_rdcsr) |
| TRANS(DRDCSR, gen_rdcsr, gen_helper_lcsr_drdcsr) |
| TRANS(WRCSR, gen_wrcsr, gen_helper_lcsr_wrcsr) |
| TRANS(DWRCSR, gen_wrcsr, gen_helper_lcsr_dwrcsr) |
| #else |
| #define GEN_FALSE_TRANS(name) \ |
| static bool trans_##name(DisasContext *ctx, arg_##name * a) \ |
| { \ |
| return false; \ |
| } |
| |
| GEN_FALSE_TRANS(RDCSR) |
| GEN_FALSE_TRANS(DRDCSR) |
| GEN_FALSE_TRANS(WRCSR) |
| GEN_FALSE_TRANS(DWRCSR) |
| #endif |