xref: /qemu/target/riscv/zce_helper.c (revision ce3af0bb)
1 /*
2  * RISC-V Zcmt Extension Helper for QEMU.
3  *
4  * Copyright (c) 2021-2022 PLCT Lab
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "cpu.h"
21 #include "exec/exec-all.h"
22 #include "exec/helper-proto.h"
23 #include "exec/cpu_ldst.h"
24 
HELPER(cm_jalt)25 target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index)
26 {
27 
28 #if !defined(CONFIG_USER_ONLY)
29     RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
30     if (ret != RISCV_EXCP_NONE) {
31         riscv_raise_exception(env, ret, 0);
32     }
33 #endif
34 
35     target_ulong target;
36     target_ulong val = env->jvt;
37     int xlen = riscv_cpu_xlen(env);
38     uint8_t mode = get_field(val, JVT_MODE);
39     target_ulong base = val & JVT_BASE;
40     target_ulong t0;
41 
42     if (mode != 0) {
43         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, 0);
44     }
45 
46     if (xlen == 32) {
47         t0 = base + (index << 2);
48         target = cpu_ldl_code(env, t0);
49     } else {
50         t0 = base + (index << 3);
51         target = cpu_ldq_code(env, t0);
52     }
53 
54     return target & ~0x1;
55 }
56