mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+187
@@ -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;
|
||||
|
||||
@@ -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
|
||||
---------
|
||||
|
||||
|
||||
@@ -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.
+1
-1
Submodule roms/opensbi updated: a2b255b889...455de672dd
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user