xref: /qemu/target/riscv/zce_helper.c (revision 7cef6d686309e2792186504ae17cf4f3eb57ef68)
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/helper-proto.h"
22 #include "accel/tcg/cpu-ldst.h"
23 
HELPER(cm_jalt)24 target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index)
25 {
26 
27 #if !defined(CONFIG_USER_ONLY)
28     RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
29     if (ret != RISCV_EXCP_NONE) {
30         riscv_raise_exception(env, ret, 0);
31     }
32 #endif
33 
34     target_ulong target;
35     target_ulong val = env->jvt;
36     int xlen = riscv_cpu_xlen(env);
37     uint8_t mode = get_field(val, JVT_MODE);
38     target_ulong base = val & JVT_BASE;
39     target_ulong t0;
40 
41     if (mode != 0) {
42         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, 0);
43     }
44 
45     if (xlen == 32) {
46         t0 = base + (index << 2);
47         target = cpu_ldl_code(env, t0);
48     } else {
49         t0 = base + (index << 3);
50         target = cpu_ldq_code(env, t0);
51     }
52 
53     return target & ~0x1;
54 }
55