Merge tag 'pull-riscv-to-apply-20240718-1' of https://github.com/alistair23/qemu into staging

RISC-V PR for 9.1

* Support the zimop, zcmop, zama16b and zabha extensions
* Validate the mode when setting vstvec CSR
* Add decode support for Zawrs extension
* Update the KVM regs to Linux 6.10-rc5
* Add smcntrpmf extension support
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
* Re-insert and deprecate 'riscv,delegate' in virt machine device tree
* roms/opensbi: Update to v1.5

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmaYeUcACgkQr3yVEwxT
# gBMtdw//U2NbmnmECa0uXuE7fdFul0tUkl2oHb9Cr8g5Se5g/HVFqexAKOFZ8Lcm
# DvTl94zJ2dms4RntcmJHwTIusa+oU6qqOekediotjgpeH4BHZNCOHe0E9hIAHn9F
# uoJ1P186L7VeVr7OFAAgSCE7F6egCk7iC0h8L8/vuL4xcuyfbZ2r7ybiTl1+45N2
# YBBv5/00wsYnyMeqRYYtyqgX9QR017JRqNSfTJSbKxhQM/L1GA1xxisUvIGeyDqc
# Pn8E3dMN6sscR6bPs4RP+SBi0JIlRCgth/jteSUkbYf42osw3/5sl4oK/e6Xiogo
# SjELOF7QJNxE8H6EUIScDaCVB5ZhvELZcuOL2NRdUuVDkjhWXM633HwfEcXkZdFK
# W/H9wOvNxPAJIOGXOpv10+MLmhdyIOZwE0uk6evHvdcTn3FP9DurdUCc1se0zKOA
# Qg/H6usTbLGNQ7KKTNQ6GpQ6u89iE1CIyZqYVvB1YuF5t7vtAmxvNk3SVZ6aq3VL
# lPJW2Zd1eO09Q+kRnBVDV7MV4OJrRNsU+ryd91NrSVo9aLADtyiNC28dCSkjU3Gn
# 6YQZt65zHuhH5IBB/PGIPo7dLRT8KNWOiYVoy3c6p6DC6oXsKIibh0ue1nrVnnVQ
# NRqyxPYaj6P8zzqwTk+iJj36UXZZVtqPIhtRu9MrO6Opl2AbsXI=
# =pM6B
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 18 Jul 2024 12:09:11 PM AEST
# gpg:                using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65  9296 AF7C 9513 0C53 8013

* tag 'pull-riscv-to-apply-20240718-1' of https://github.com/alistair23/qemu: (30 commits)
  roms/opensbi: Update to v1.5
  hw/riscv/virt.c: re-insert and deprecate 'riscv,delegate'
  target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
  target/riscv: Expose the Smcntrpmf config
  target/riscv: Do not setup pmu timer if OF is disabled
  target/riscv: More accurately model priv mode filtering.
  target/riscv: Start counters from both mhpmcounter and mcountinhibit
  target/riscv: Enforce WARL behavior for scounteren/hcounteren
  target/riscv: Save counter values during countinhibit update
  target/riscv: Implement privilege mode filtering for cycle/instret
  target/riscv: Only set INH fields if priv mode is available
  target/riscv: Add cycle & instret privilege mode filtering support
  target/riscv: Add cycle & instret privilege mode filtering definitions
  target/riscv: Add cycle & instret privilege mode filtering properties
  target/riscv: Fix the predicate functions for mhpmeventhX CSRs
  target/riscv: Combine set_mode and set_virt functions.
  target/riscv/kvm: update KVM regs to Linux 6.10-rc5
  disas/riscv: Add decode for Zawrs extension
  target/riscv: Validate the mode in write_vstvec
  disas/riscv: Support zabha disassemble
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2024-07-18 21:23:24 +10:00
29 changed files with 1246 additions and 211 deletions
+187
View File
@@ -906,6 +906,76 @@ typedef enum {
rv_op_amocas_w = 875,
rv_op_amocas_d = 876,
rv_op_amocas_q = 877,
rv_mop_r_0 = 878,
rv_mop_r_1 = 879,
rv_mop_r_2 = 880,
rv_mop_r_3 = 881,
rv_mop_r_4 = 882,
rv_mop_r_5 = 883,
rv_mop_r_6 = 884,
rv_mop_r_7 = 885,
rv_mop_r_8 = 886,
rv_mop_r_9 = 887,
rv_mop_r_10 = 888,
rv_mop_r_11 = 889,
rv_mop_r_12 = 890,
rv_mop_r_13 = 891,
rv_mop_r_14 = 892,
rv_mop_r_15 = 893,
rv_mop_r_16 = 894,
rv_mop_r_17 = 895,
rv_mop_r_18 = 896,
rv_mop_r_19 = 897,
rv_mop_r_20 = 898,
rv_mop_r_21 = 899,
rv_mop_r_22 = 900,
rv_mop_r_23 = 901,
rv_mop_r_24 = 902,
rv_mop_r_25 = 903,
rv_mop_r_26 = 904,
rv_mop_r_27 = 905,
rv_mop_r_28 = 906,
rv_mop_r_29 = 907,
rv_mop_r_30 = 908,
rv_mop_r_31 = 909,
rv_mop_rr_0 = 910,
rv_mop_rr_1 = 911,
rv_mop_rr_2 = 912,
rv_mop_rr_3 = 913,
rv_mop_rr_4 = 914,
rv_mop_rr_5 = 915,
rv_mop_rr_6 = 916,
rv_mop_rr_7 = 917,
rv_c_mop_1 = 918,
rv_c_mop_3 = 919,
rv_c_mop_5 = 920,
rv_c_mop_7 = 921,
rv_c_mop_9 = 922,
rv_c_mop_11 = 923,
rv_c_mop_13 = 924,
rv_c_mop_15 = 925,
rv_op_amoswap_b = 926,
rv_op_amoadd_b = 927,
rv_op_amoxor_b = 928,
rv_op_amoor_b = 929,
rv_op_amoand_b = 930,
rv_op_amomin_b = 931,
rv_op_amomax_b = 932,
rv_op_amominu_b = 933,
rv_op_amomaxu_b = 934,
rv_op_amoswap_h = 935,
rv_op_amoadd_h = 936,
rv_op_amoxor_h = 937,
rv_op_amoor_h = 938,
rv_op_amoand_h = 939,
rv_op_amomin_h = 940,
rv_op_amomax_h = 941,
rv_op_amominu_h = 942,
rv_op_amomaxu_h = 943,
rv_op_amocas_b = 944,
rv_op_amocas_h = 945,
rv_op_wrs_sto = 946,
rv_op_wrs_nto = 947,
} rv_op;
/* register names */
@@ -2096,6 +2166,76 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "amocas.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "mop.r.0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.2", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.3", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.4", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.5", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.6", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.7", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.9", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.10", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.11", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.12", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.13", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.14", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.15", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.16", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.17", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.18", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.19", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.20", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.21", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.22", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.23", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.24", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.25", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.26", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.27", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.28", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.29", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.30", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.r.31", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
{ "mop.rr.0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.3", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.5", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.6", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "mop.rr.7", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "c.mop.1", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.3", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.5", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.7", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.9", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.11", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.13", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "c.mop.15", rv_codec_ci_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "amoswap.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoadd.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoxor.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoor.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoand.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomin.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomax.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amominu.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomaxu.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoswap.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoadd.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoxor.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoor.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amoand.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomin.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomax.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amominu.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amomaxu.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.b", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "amocas.h", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
{ "wrs.sto", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
{ "wrs.nto", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2452,6 +2592,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 2: op = rv_op_c_li; break;
case 3:
if (dec->cfg->ext_zcmop) {
if ((((inst >> 2) & 0b111111) == 0b100000) &&
(((inst >> 11) & 0b11) == 0b0)) {
op = rv_c_mop_1 + ((inst >> 8) & 0b111);
break;
}
}
switch ((inst >> 7) & 0b11111) {
case 2: op = rv_op_c_addi16sp; break;
default: op = rv_op_c_lui; break;
@@ -2883,9 +3030,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 11:
switch (((inst >> 24) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_amoadd_b; break;
case 1: op = rv_op_amoadd_h; break;
case 2: op = rv_op_amoadd_w; break;
case 3: op = rv_op_amoadd_d; break;
case 4: op = rv_op_amoadd_q; break;
case 8: op = rv_op_amoswap_b; break;
case 9: op = rv_op_amoswap_h; break;
case 10: op = rv_op_amoswap_w; break;
case 11: op = rv_op_amoswap_d; break;
case 12: op = rv_op_amoswap_q; break;
@@ -2907,27 +3058,43 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 26: op = rv_op_sc_w; break;
case 27: op = rv_op_sc_d; break;
case 28: op = rv_op_sc_q; break;
case 32: op = rv_op_amoxor_b; break;
case 33: op = rv_op_amoxor_h; break;
case 34: op = rv_op_amoxor_w; break;
case 35: op = rv_op_amoxor_d; break;
case 36: op = rv_op_amoxor_q; break;
case 40: op = rv_op_amocas_b; break;
case 41: op = rv_op_amocas_h; break;
case 42: op = rv_op_amocas_w; break;
case 43: op = rv_op_amocas_d; break;
case 44: op = rv_op_amocas_q; break;
case 64: op = rv_op_amoor_b; break;
case 65: op = rv_op_amoor_h; break;
case 66: op = rv_op_amoor_w; break;
case 67: op = rv_op_amoor_d; break;
case 68: op = rv_op_amoor_q; break;
case 96: op = rv_op_amoand_b; break;
case 97: op = rv_op_amoand_h; break;
case 98: op = rv_op_amoand_w; break;
case 99: op = rv_op_amoand_d; break;
case 100: op = rv_op_amoand_q; break;
case 128: op = rv_op_amomin_b; break;
case 129: op = rv_op_amomin_h; break;
case 130: op = rv_op_amomin_w; break;
case 131: op = rv_op_amomin_d; break;
case 132: op = rv_op_amomin_q; break;
case 160: op = rv_op_amomax_b; break;
case 161: op = rv_op_amomax_h; break;
case 162: op = rv_op_amomax_w; break;
case 163: op = rv_op_amomax_d; break;
case 164: op = rv_op_amomax_q; break;
case 192: op = rv_op_amominu_b; break;
case 193: op = rv_op_amominu_h; break;
case 194: op = rv_op_amominu_w; break;
case 195: op = rv_op_amominu_d; break;
case 196: op = rv_op_amominu_q; break;
case 224: op = rv_op_amomaxu_b; break;
case 225: op = rv_op_amomaxu_h; break;
case 226: op = rv_op_amomaxu_w; break;
case 227: op = rv_op_amomaxu_d; break;
case 228: op = rv_op_amomaxu_q; break;
@@ -3817,6 +3984,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0: op = rv_op_ecall; break;
case 32: op = rv_op_ebreak; break;
case 64: op = rv_op_uret; break;
case 416: op = rv_op_wrs_nto; break;
case 928: op = rv_op_wrs_sto; break;
}
break;
case 256:
@@ -3855,6 +4024,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 1: op = rv_op_csrrw; break;
case 2: op = rv_op_csrrs; break;
case 3: op = rv_op_csrrc; break;
case 4:
if (dec->cfg->ext_zimop) {
int imm_mop5, imm_mop3;
if ((extract32(inst, 22, 10) & 0b1011001111)
== 0b1000000111) {
imm_mop5 = deposit32(deposit32(extract32(inst, 20, 2),
2, 2,
extract32(inst, 26, 2)),
4, 1, extract32(inst, 30, 1));
op = rv_mop_r_0 + imm_mop5;
} else if ((extract32(inst, 25, 7) & 0b1011001)
== 0b1000001) {
imm_mop3 = deposit32(extract32(inst, 26, 2),
2, 1, extract32(inst, 30, 1));
op = rv_mop_rr_0 + imm_mop3;
}
}
break;
case 5: op = rv_op_csrrwi; break;
case 6: op = rv_op_csrrsi; break;
case 7: op = rv_op_csrrci; break;
+11
View File
@@ -479,6 +479,17 @@ versions, aliases will point to newer CPU model versions
depending on the machine type, so management software must
resolve CPU model aliases before starting a virtual machine.
RISC-V "virt" board "riscv,delegate" DT property (since 9.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The "riscv,delegate" DT property was added in QEMU 7.0 as part of
the AIA APLIC support. The property changed name during the review
process in Linux and the correct name ended up being
"riscv,delegation". Changing the DT property name will break all
available firmwares that are using the current (wrong) name. The
property is kept as is in 9.1, together with "riscv,delegation", to
give more time for firmware developers to change their code.
Migration
---------
+9
View File
@@ -651,6 +651,15 @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegation",
aplic_child_phandle, 0x1,
VIRT_IRQCHIP_NUM_SOURCES);
/*
* DEPRECATED_9.1: Compat property kept temporarily
* to allow old firmwares to work with AIA. Do *not*
* use 'riscv,delegate' in new code: use
* 'riscv,delegation' instead.
*/
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
aplic_child_phandle, 0x1,
VIRT_IRQCHIP_NUM_SOURCES);
}
riscv_socket_fdt_write_id(ms, aplic_name, socket);
Binary file not shown.
Binary file not shown.
+10
View File
@@ -113,10 +113,13 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
ISA_EXT_DATA_ENTRY(zimop, PRIV_VERSION_1_13_0, ext_zimop),
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
ISA_EXT_DATA_ENTRY(za64rs, PRIV_VERSION_1_12_0, has_priv_1_11),
ISA_EXT_DATA_ENTRY(zaamo, PRIV_VERSION_1_12_0, ext_zaamo),
ISA_EXT_DATA_ENTRY(zabha, PRIV_VERSION_1_13_0, ext_zabha),
ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
ISA_EXT_DATA_ENTRY(zama16b, PRIV_VERSION_1_13_0, ext_zama16b),
ISA_EXT_DATA_ENTRY(zalrsc, PRIV_VERSION_1_12_0, ext_zalrsc),
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
@@ -130,6 +133,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zcf, PRIV_VERSION_1_12_0, ext_zcf),
ISA_EXT_DATA_ENTRY(zcd, PRIV_VERSION_1_12_0, ext_zcd),
ISA_EXT_DATA_ENTRY(zce, PRIV_VERSION_1_12_0, ext_zce),
ISA_EXT_DATA_ENTRY(zcmop, PRIV_VERSION_1_13_0, ext_zcmop),
ISA_EXT_DATA_ENTRY(zcmp, PRIV_VERSION_1_12_0, ext_zcmp),
ISA_EXT_DATA_ENTRY(zcmt, PRIV_VERSION_1_12_0, ext_zcmt),
ISA_EXT_DATA_ENTRY(zba, PRIV_VERSION_1_12_0, ext_zba),
@@ -178,6 +182,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
@@ -1467,11 +1472,16 @@ const char *riscv_get_misa_ext_description(uint32_t bit)
const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
/* Defaults for standard extensions */
MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
MULTI_EXT_CFG_BOOL("zimop", ext_zimop, false),
MULTI_EXT_CFG_BOOL("zcmop", ext_zcmop, false),
MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
MULTI_EXT_CFG_BOOL("zama16b", ext_zama16b, false),
MULTI_EXT_CFG_BOOL("zabha", ext_zabha, false),
MULTI_EXT_CFG_BOOL("zaamo", ext_zaamo, false),
MULTI_EXT_CFG_BOOL("zalrsc", ext_zalrsc, false),
MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
+22 -2
View File
@@ -176,11 +176,19 @@ typedef struct PMUCTRState {
target_ulong mhpmcounter_prev;
/* Snapshort value of a counter in RV32 */
target_ulong mhpmcounterh_prev;
bool started;
/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */
target_ulong irq_overflow_left;
} PMUCTRState;
typedef struct PMUFixedCtrState {
/* Track cycle and icount for each privilege mode */
uint64_t counter[4];
uint64_t counter_prev[4];
/* Track cycle and icount for each privilege mode when V = 1*/
uint64_t counter_virt[2];
uint64_t counter_virt_prev[2];
} PMUFixedCtrState;
struct CPUArchState {
target_ulong gpr[32];
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
@@ -362,6 +370,12 @@ struct CPUArchState {
uint32_t mcountinhibit;
/* PMU cycle & instret privilege mode filtering */
target_ulong mcyclecfg;
target_ulong mcyclecfgh;
target_ulong minstretcfg;
target_ulong minstretcfgh;
/* PMU counter state */
PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
@@ -371,6 +385,8 @@ struct CPUArchState {
/* PMU event selector configured values for RV32 */
target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
PMUFixedCtrState pmu_fixed_ctrs[2];
target_ulong sscratch;
target_ulong mscratch;
@@ -567,7 +583,7 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
#endif /* !CONFIG_USER_ONLY */
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
void riscv_translate_init(void);
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
@@ -735,6 +751,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
void riscv_cpu_update_mask(CPURISCVState *env);
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
target_ulong *ret_value);
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
@@ -767,6 +785,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
target_ulong new_value,
target_ulong write_mask);
RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
Int128 *ret_value);
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
Int128 *ret_value,
Int128 new_value, Int128 write_mask);
+41
View File
@@ -397,6 +397,10 @@
/* Machine counter-inhibit register */
#define CSR_MCOUNTINHIBIT 0x320
/* Machine counter configuration registers */
#define CSR_MCYCLECFG 0x321
#define CSR_MINSTRETCFG 0x322
#define CSR_MHPMEVENT3 0x323
#define CSR_MHPMEVENT4 0x324
#define CSR_MHPMEVENT5 0x325
@@ -427,6 +431,9 @@
#define CSR_MHPMEVENT30 0x33e
#define CSR_MHPMEVENT31 0x33f
#define CSR_MCYCLECFGH 0x721
#define CSR_MINSTRETCFGH 0x722
#define CSR_MHPMEVENT3H 0x723
#define CSR_MHPMEVENT4H 0x724
#define CSR_MHPMEVENT5H 0x725
@@ -884,6 +891,28 @@ typedef enum RISCVException {
/* PMU related bits */
#define MIE_LCOFIE (1 << IRQ_PMU_OVF)
#define MCYCLECFG_BIT_MINH BIT_ULL(62)
#define MCYCLECFGH_BIT_MINH BIT(30)
#define MCYCLECFG_BIT_SINH BIT_ULL(61)
#define MCYCLECFGH_BIT_SINH BIT(29)
#define MCYCLECFG_BIT_UINH BIT_ULL(60)
#define MCYCLECFGH_BIT_UINH BIT(28)
#define MCYCLECFG_BIT_VSINH BIT_ULL(59)
#define MCYCLECFGH_BIT_VSINH BIT(27)
#define MCYCLECFG_BIT_VUINH BIT_ULL(58)
#define MCYCLECFGH_BIT_VUINH BIT(26)
#define MINSTRETCFG_BIT_MINH BIT_ULL(62)
#define MINSTRETCFGH_BIT_MINH BIT(30)
#define MINSTRETCFG_BIT_SINH BIT_ULL(61)
#define MINSTRETCFGH_BIT_SINH BIT(29)
#define MINSTRETCFG_BIT_UINH BIT_ULL(60)
#define MINSTRETCFGH_BIT_UINH BIT(28)
#define MINSTRETCFG_BIT_VSINH BIT_ULL(59)
#define MINSTRETCFGH_BIT_VSINH BIT(27)
#define MINSTRETCFG_BIT_VUINH BIT_ULL(58)
#define MINSTRETCFGH_BIT_VUINH BIT(26)
#define MHPMEVENT_BIT_OF BIT_ULL(63)
#define MHPMEVENTH_BIT_OF BIT(31)
#define MHPMEVENT_BIT_MINH BIT_ULL(62)
@@ -897,6 +926,18 @@ typedef enum RISCVException {
#define MHPMEVENT_BIT_VUINH BIT_ULL(58)
#define MHPMEVENTH_BIT_VUINH BIT(26)
#define MHPMEVENT_FILTER_MASK (MHPMEVENT_BIT_MINH | \
MHPMEVENT_BIT_SINH | \
MHPMEVENT_BIT_UINH | \
MHPMEVENT_BIT_VSINH | \
MHPMEVENT_BIT_VUINH)
#define MHPMEVENTH_FILTER_MASK (MHPMEVENTH_BIT_MINH | \
MHPMEVENTH_BIT_SINH | \
MHPMEVENTH_BIT_UINH | \
MHPMEVENTH_BIT_VSINH | \
MHPMEVENTH_BIT_VUINH)
#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000)
#define MHPMEVENT_IDX_MASK 0xFFFFF
#define MHPMEVENT_SSCOF_RESVD 16
+5
View File
@@ -71,9 +71,12 @@ struct RISCVCPUConfig {
bool ext_zihintntl;
bool ext_zihintpause;
bool ext_zihpm;
bool ext_zimop;
bool ext_zcmop;
bool ext_ztso;
bool ext_smstateen;
bool ext_sstc;
bool ext_smcntrpmf;
bool ext_svadu;
bool ext_svinval;
bool ext_svnapot;
@@ -81,6 +84,8 @@ struct RISCVCPUConfig {
bool ext_zdinx;
bool ext_zaamo;
bool ext_zacas;
bool ext_zama16b;
bool ext_zabha;
bool ext_zalrsc;
bool ext_zawrs;
bool ext_zfa;
+35 -31
View File
@@ -619,30 +619,6 @@ void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen)
env->geilen = geilen;
}
/* This function can only be called to set virt when RVH is enabled */
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
{
/* Flush the TLB on all virt mode changes. */
if (env->virt_enabled != enable) {
tlb_flush(env_cpu(env));
}
env->virt_enabled = enable;
if (enable) {
/*
* The guest external interrupts from an interrupt controller are
* delivered only when the Guest/VM is running (i.e. V=1). This means
* any guest external interrupt which is triggered while the Guest/VM
* is not running (i.e. V=0) will be missed on QEMU resulting in guest
* with sluggish response to serial console input and other I/O events.
*
* To solve this, we check and inject interrupt after setting V=1.
*/
riscv_cpu_update_mip(env, 0, 0);
}
}
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
{
CPURISCVState *env = &cpu->env;
@@ -715,13 +691,18 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
}
}
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
{
g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
if (icount_enabled() && newpriv != env->priv) {
riscv_itrigger_update_priv(env);
if (newpriv != env->priv || env->virt_enabled != virt_en) {
if (icount_enabled()) {
riscv_itrigger_update_priv(env);
}
riscv_pmu_update_fixed_ctrs(env, newpriv, virt_en);
}
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
env->xl = cpu_recompute_xl(env);
@@ -736,6 +717,28 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
* preemptive context switch. As a result, do both.
*/
env->load_res = -1;
if (riscv_has_ext(env, RVH)) {
/* Flush the TLB on all virt mode changes. */
if (env->virt_enabled != virt_en) {
tlb_flush(env_cpu(env));
}
env->virt_enabled = virt_en;
if (virt_en) {
/*
* The guest external interrupts from an interrupt controller are
* delivered only when the Guest/VM is running (i.e. V=1). This
* means any guest external interrupt which is triggered while the
* Guest/VM is not running (i.e. V=0) will be missed on QEMU
* resulting in guest with sluggish response to serial console
* input and other I/O events.
*
* To solve this, we check and inject interrupt after setting V=1.
*/
riscv_cpu_update_mip(env, 0, 0);
}
}
}
/*
@@ -1648,6 +1651,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
bool virt = env->virt_enabled;
bool write_gva = false;
uint64_t s;
@@ -1778,7 +1782,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
htval = env->guest_phys_fault_addr;
riscv_cpu_set_virt_enabled(env, 0);
virt = false;
} else {
/* Trap into HS mode */
env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
@@ -1799,7 +1803,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->htinst = tinst;
env->pc = (env->stvec >> 2 << 2) +
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
riscv_cpu_set_mode(env, PRV_S);
riscv_cpu_set_mode(env, PRV_S, virt);
} else {
/* handle the trap in M-mode */
if (riscv_has_ext(env, RVH)) {
@@ -1815,7 +1819,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
mtval2 = env->guest_phys_fault_addr;
/* Trapping to M mode, virt is disabled */
riscv_cpu_set_virt_enabled(env, 0);
virt = false;
}
s = env->mstatus;
@@ -1830,7 +1834,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->mtinst = tinst;
env->pc = (env->mtvec >> 2 << 2) +
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
riscv_cpu_set_mode(env, PRV_M);
riscv_cpu_set_mode(env, PRV_M, virt);
}
/*
+409 -92
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -140,6 +140,7 @@ sw 110 ... ... .. ... 00 @cs_w
addi 000 . ..... ..... 01 @ci
addi 010 . ..... ..... 01 @c_li
{
c_mop_n 011 0 0 n:3 1 00000 01
illegal 011 0 ----- 00000 01 # c.addi16sp and c.lui, RES nzimm=0
addi 011 . 00010 ..... 01 @c_addi16sp
lui 011 . ..... ..... 01 @c_lui
+33
View File
@@ -38,6 +38,8 @@
%imm_bs 30:2 !function=ex_shift_3
%imm_rnum 20:4
%imm_z6 26:1 15:5
%imm_mop5 30:1 26:2 20:2
%imm_mop3 30:1 26:2
# Argument sets:
&empty
@@ -56,6 +58,8 @@
&r2nfvm vm rd rs1 nf
&rnfvm vm rd rs1 rs2 nf
&k_aes shamt rs2 rs1 rd
&mop5 imm rd rs1
&mop3 imm rd rs1 rs2
# Formats 32:
@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
@@ -98,6 +102,9 @@
@k_aes .. ..... ..... ..... ... ..... ....... &k_aes shamt=%imm_bs %rs2 %rs1 %rd
@i_aes .. ..... ..... ..... ... ..... ....... &i imm=%imm_rnum %rs1 %rd
@mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=%imm_mop5 %rd %rs1
@mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=%imm_mop3 %rd %rs1 %rs2
# Formats 64:
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
@@ -1010,3 +1017,29 @@ amocas_w 00101 . . ..... ..... 010 ..... 0101111 @atom_st
amocas_d 00101 . . ..... ..... 011 ..... 0101111 @atom_st
# *** RV64 Zacas Standard Extension ***
amocas_q 00101 . . ..... ..... 100 ..... 0101111 @atom_st
# *** Zimop may-be-operation extension ***
mop_r_n 1 . 00 .. 0111 .. ..... 100 ..... 1110011 @mop5
mop_rr_n 1 . 00 .. 1 ..... ..... 100 ..... 1110011 @mop3
# *** Zabhb Standard Extension ***
amoswap_b 00001 . . ..... ..... 000 ..... 0101111 @atom_st
amoadd_b 00000 . . ..... ..... 000 ..... 0101111 @atom_st
amoxor_b 00100 . . ..... ..... 000 ..... 0101111 @atom_st
amoand_b 01100 . . ..... ..... 000 ..... 0101111 @atom_st
amoor_b 01000 . . ..... ..... 000 ..... 0101111 @atom_st
amomin_b 10000 . . ..... ..... 000 ..... 0101111 @atom_st
amomax_b 10100 . . ..... ..... 000 ..... 0101111 @atom_st
amominu_b 11000 . . ..... ..... 000 ..... 0101111 @atom_st
amomaxu_b 11100 . . ..... ..... 000 ..... 0101111 @atom_st
amoswap_h 00001 . . ..... ..... 001 ..... 0101111 @atom_st
amoadd_h 00000 . . ..... ..... 001 ..... 0101111 @atom_st
amoxor_h 00100 . . ..... ..... 001 ..... 0101111 @atom_st
amoand_h 01100 . . ..... ..... 001 ..... 0101111 @atom_st
amoor_h 01000 . . ..... ..... 001 ..... 0101111 @atom_st
amomin_h 10000 . . ..... ..... 001 ..... 0101111 @atom_st
amomax_h 10100 . . ..... ..... 001 ..... 0101111 @atom_st
amominu_h 11000 . . ..... ..... 001 ..... 0101111 @atom_st
amomaxu_h 11100 . . ..... ..... 001 ..... 0101111 @atom_st
amocas_b 00101 . . ..... ..... 000 ..... 0101111 @atom_st
amocas_h 00101 . . ..... ..... 001 ..... 0101111 @atom_st
+18 -33
View File
@@ -96,21 +96,6 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
return true;
}
static bool gen_amo(DisasContext *ctx, arg_atomic *a,
void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
MemOp mop)
{
TCGv dest = dest_gpr(ctx, a->rd);
TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
decode_save_opc(ctx);
src1 = get_address(ctx, a->rs1, 0);
func(dest, src1, src2, ctx->mem_idx, mop);
gen_set_gpr(ctx, a->rd, dest);
return true;
}
static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a)
{
REQUIRE_A_OR_ZALRSC(ctx);
@@ -126,55 +111,55 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL);
}
static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL);
}
static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL);
}
static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL);
}
static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL);
}
static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL);
}
static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL);
}
static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL);
}
static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
{
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL);
}
static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
@@ -195,61 +180,61 @@ static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ);
}
static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ);
}
static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ);
}
static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ);
}
static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ);
}
static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ);
}
static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ);
}
static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ);
}
static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_A_OR_ZAAMO(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEUQ));
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ);
}
+12 -2
View File
@@ -42,13 +42,18 @@
static bool trans_fld(DisasContext *ctx, arg_fld *a)
{
TCGv addr;
MemOp memop = MO_TEUQ;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, memop);
mark_fs_dirty(ctx);
return true;
@@ -57,13 +62,18 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
{
TCGv addr;
MemOp memop = MO_TEUQ;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVD);
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, memop);
return true;
}
+12 -2
View File
@@ -43,14 +43,19 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
{
TCGv_i64 dest;
TCGv addr;
MemOp memop = MO_TEUL;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
dest = cpu_fpr[a->rd];
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, memop);
gen_nanbox_s(dest, dest);
mark_fs_dirty(ctx);
@@ -60,13 +65,18 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
{
TCGv addr;
MemOp memop = MO_TEUL;
REQUIRE_FPU;
REQUIRE_EXT(ctx, RVF);
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
addr = get_address(ctx, a->rs1, a->imm);
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, memop);
return true;
}
+6
View File
@@ -268,6 +268,9 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
{
bool out;
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
if (get_xl(ctx) == MXL_RV128) {
out = gen_load_i128(ctx, a, memop);
@@ -366,6 +369,9 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
{
if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) {
memop |= MO_ATOM_WITHIN16;
}
decode_save_opc(ctx);
if (get_xl(ctx) == MXL_RV128) {
return gen_store_i128(ctx, a, memop);
+145
View File
@@ -0,0 +1,145 @@
/*
* RISC-V translation routines for the Zabha Standard Extension.
*
* Copyright (c) 2024 Alibaba Group
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2 or later, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define REQUIRE_ZABHA(ctx) do { \
if (!ctx->cfg_ptr->ext_zabha) { \
return false; \
} \
} while (0)
static bool trans_amoswap_b(DisasContext *ctx, arg_amoswap_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_SB);
}
static bool trans_amoadd_b(DisasContext *ctx, arg_amoadd_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_SB);
}
static bool trans_amoxor_b(DisasContext *ctx, arg_amoxor_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_SB);
}
static bool trans_amoand_b(DisasContext *ctx, arg_amoand_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_SB);
}
static bool trans_amoor_b(DisasContext *ctx, arg_amoor_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_SB);
}
static bool trans_amomin_b(DisasContext *ctx, arg_amomin_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_SB);
}
static bool trans_amomax_b(DisasContext *ctx, arg_amomax_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_SB);
}
static bool trans_amominu_b(DisasContext *ctx, arg_amominu_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_SB);
}
static bool trans_amomaxu_b(DisasContext *ctx, arg_amomaxu_b *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_SB);
}
static bool trans_amoswap_h(DisasContext *ctx, arg_amoswap_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESW);
}
static bool trans_amoadd_h(DisasContext *ctx, arg_amoadd_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESW);
}
static bool trans_amoxor_h(DisasContext *ctx, arg_amoxor_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESW);
}
static bool trans_amoand_h(DisasContext *ctx, arg_amoand_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESW);
}
static bool trans_amoor_h(DisasContext *ctx, arg_amoor_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESW);
}
static bool trans_amomin_h(DisasContext *ctx, arg_amomin_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESW);
}
static bool trans_amomax_h(DisasContext *ctx, arg_amomax_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESW);
}
static bool trans_amominu_h(DisasContext *ctx, arg_amominu_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESW);
}
static bool trans_amomaxu_h(DisasContext *ctx, arg_amomaxu_h *a)
{
REQUIRE_ZABHA(ctx);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESW);
}
static bool trans_amocas_b(DisasContext *ctx, arg_amocas_b *a)
{
REQUIRE_ZACAS(ctx);
REQUIRE_ZABHA(ctx);
return gen_cmpxchg(ctx, a, MO_SB);
}
static bool trans_amocas_h(DisasContext *ctx, arg_amocas_h *a)
{
REQUIRE_ZACAS(ctx);
REQUIRE_ZABHA(ctx);
return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TESW);
}
@@ -22,19 +22,6 @@
} \
} while (0)
static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop)
{
TCGv dest = get_gpr(ctx, a->rd, EXT_NONE);
TCGv src1 = get_address(ctx, a->rs1, 0);
TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
decode_save_opc(ctx);
tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop);
gen_set_gpr(ctx, a->rd, dest);
return true;
}
static bool trans_amocas_w(DisasContext *ctx, arg_amocas_w *a)
{
REQUIRE_ZACAS(ctx);

Some files were not shown because too many files have changed in this diff Show More