diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 7e71446a0d..2634ba07f7 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -864,6 +864,90 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; } nextop = F8; + if (u8 == 0xCB && cpuext.vector && cpuext.zvknha) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + if (v0 == v1) { + int t = fpu_get_scratch(dyn); + VMV_V_V(t, v1); + v1 = t; + } + int vx0 = sse_get_reg_vector(dyn, ninst, x1, 0, 0, VECTOR_SEW32); + if (vx0 == v0 || vx0 == v1) { + int t = fpu_get_scratch(dyn); + VMV_V_V(t, vx0); + vx0 = t; + } + VSHA2CL_VV(v0, v1, vx0); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } + if (u8 != 0xCB && cpuext.vector && cpuext.zvbb) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + q1 = fpu_get_scratch(dyn); + int vz = fpu_get_scratch(dyn); + VXOR_VV(vz, vz, vz, 1); + switch (u8) { + case 0xC8: + VROR_VI(d0, v0, 2, 1); + VADD_VV(d0, d0, v1, 1); + if (v0 != v1) VOR_VV(v0, v1, v1, 1); + VSLIDEDOWN_VI(d1, d0, 3, 1); + VSLIDEUP_VI(v0, d1, 3, 1); + break; + case 0xC9: + VSLIDEDOWN_VI(d0, v1, 2, 1); + VSLIDEUP_VI(d0, vz, 2, 1); + VSLIDEUP_VI(d0, v0, 2, 1); + VXOR_VV(v0, v0, d0, 1); + break; + case 0xCA: + VSLIDEUP_VI(d0, vz, 0, 1); + VSLIDEUP_VI(d0, v1, 1, 1); + VXOR_VV(d0, d0, v0, 1); + VROR_VI(v0, d0, 31, 1); + VSLIDEDOWN_VI(d1, v0, 3, 1); + VSLIDEUP_VI(d1, vz, 1, 1); + VROR_VI(d1, d1, 31, 1); + VXOR_VV(v0, v0, d1, 1); + break; + case 0xCC: + VSLIDEDOWN_VI(d0, v0, 1, 1); + VSLIDEUP_VI(d0, v1, 3, 1); + VROR_VI(d1, d0, 7, 1); + VROR_VI(q1, d0, 18, 1); + VXOR_VV(d1, d1, q1, 1); + VSRL_VI(q1, d0, 3, 1); + VXOR_VV(d1, d1, q1, 1); + VADD_VV(v0, v0, d1, 1); + break; + case 0xCD: + VSLIDEDOWN_VI(d0, v1, 2, 1); + VSLIDEUP_VI(d0, vz, 2, 1); + VROR_VI(d1, d0, 17, 1); + VROR_VI(q1, d0, 19, 1); + VXOR_VV(d1, d1, q1, 1); + VSRL_VI(q1, d0, 10, 1); + VXOR_VV(d1, d1, q1, 1); + VADD_VV(v0, v0, d1, 1); + VSLIDEUP_VI(d0, vz, 0, 1); + VSLIDEUP_VI(d0, v0, 2, 1); + VROR_VI(d1, d0, 17, 1); + VROR_VI(q1, d0, 19, 1); + VXOR_VV(d1, d1, q1, 1); + VSRL_VI(q1, d0, 10, 1); + VXOR_VV(d1, d1, q1, 1); + VADD_VV(v0, v0, d1, 1); + break; + } + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } if (MODREG) { ed = (nextop & 7) + (rex.b << 3); sse_reflect_reg(dyn, ninst, x6, ed); diff --git a/src/dynarec/rv64/dynarec_rv64_660f38.c b/src/dynarec/rv64/dynarec_rv64_660f38.c index 94856a89ee..d7f17962c8 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f38.c +++ b/src/dynarec/rv64/dynarec_rv64_660f38.c @@ -35,6 +35,7 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, int64_t j64; uint64_t tmp64u, tmp64u2; int v0, v1; + int v2; int q0, q1; int d0, d1, d2; int64_t fixedaddress, gdoffset; @@ -42,6 +43,7 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, MAYUSE(d0); MAYUSE(d1); + MAYUSE(v2); MAYUSE(q0); MAYUSE(q1); MAYUSE(eb1); @@ -723,6 +725,18 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, case 0xDB: INST_NAME("AESIMC Gx, Ex"); // AES-NI nextop = F8; + if (cpuext.zvkned) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + v2 = fpu_get_scratch(dyn); + MOV32w(x4, 0x63636363); + VMV_V_X(v2, x4); + VAESDM_VV(v2, v1); + VMV_V_V(v0, v2); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } GETGX(); GETEX(x2, 0, 8); SSE_LOOP_MV_Q(x3); @@ -733,6 +747,14 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, case 0xDC: INST_NAME("AESENC Gx, Ex"); // AES-NI nextop = F8; + if (cpuext.zvkned) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + VAESEM_VV(v0, v1); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } GETG; sse_forget_reg(dyn, ninst, x6, gd); if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { @@ -754,6 +776,14 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, case 0xDD: INST_NAME("AESENCLAST Gx, Ex"); // AES-NI nextop = F8; + if (cpuext.zvkned) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + VAESEF_VV(v0, v1); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } GETG; sse_forget_reg(dyn, ninst, x6, gd); if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { @@ -775,6 +805,26 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, case 0xDE: INST_NAME("AESDEC Gx, Ex"); // AES-NI nextop = F8; + if (cpuext.zvkned) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + if (v0 == v1) { + v2 = fpu_get_scratch(dyn); + VMV_V_V(v2, v1); + v1 = v2; + } + v2 = fpu_get_scratch(dyn); + VXOR_VV(v2, v2, v2, 1); + VAESDF_VV(v0, v2); + v2 = fpu_get_scratch(dyn); + MOV32w(x4, 0x63636363); + VMV_V_X(v2, x4); + VAESDM_VV(v2, v0); + VXOR_VV(v0, v2, v1, 1); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } GETG; sse_forget_reg(dyn, ninst, x6, gd); if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { @@ -797,6 +847,14 @@ uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, case 0xDF: INST_NAME("AESDECLAST Gx, Ex"); // AES-NI nextop = F8; + if (cpuext.zvkned) { + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETGX_vector(v0, 1, VECTOR_SEW32); + GETEX_vector(v1, 0, 8, VECTOR_SEW32); + VAESDF_VV(v0, v1); + if (!MODREG) PUTEX_vector(v1, VECTOR_SEW32); + break; + } GETG; sse_forget_reg(dyn, ninst, x6, gd); if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { diff --git a/src/dynarec/rv64/dynarec_rv64_avx_66_0f38.c b/src/dynarec/rv64/dynarec_rv64_avx_66_0f38.c index e8de87ee42..b5653da27c 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_66_0f38.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_66_0f38.c @@ -1116,6 +1116,23 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i case 0xDC: INST_NAME("VAESENC Gx, Vx, Ex"); nextop = F8; + if (cpuext.zvkned && (!vex.l || cpuext.vlen >= 32)) { + gd = ((nextop & 0x38) >> 3) + (rex.r << 3); + SET_AVX_VECTOR_WIDTH(x1, VECTOR_SEW32); + v0 = fpu_get_scratch(dyn); + avx_load_reg_vector(dyn, ninst, x1, v0, vex.v, 16 << vex.l, VECTOR_SEW32); + v1 = fpu_get_scratch(dyn); + if (MODREG) { + avx_load_reg_vector(dyn, ninst, x1, v1, (nextop & 7) + (rex.b << 3), 16 << vex.l, VECTOR_SEW32); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE32_V(v1, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + VAESEM_VV(v0, v1); + avx_store_reg_vector(dyn, ninst, x1, v0, gd, 16 << vex.l, VECTOR_SEW32); + break; + } GETGX(); GETVX(); if (vex.l) { @@ -1171,6 +1188,23 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i case 0xDD: INST_NAME("VAESENCLAST Gx, Vx, Ex"); nextop = F8; + if (cpuext.zvkned && (!vex.l || cpuext.vlen >= 32)) { + gd = ((nextop & 0x38) >> 3) + (rex.r << 3); + SET_AVX_VECTOR_WIDTH(x1, VECTOR_SEW32); + v0 = fpu_get_scratch(dyn); + avx_load_reg_vector(dyn, ninst, x1, v0, vex.v, 16 << vex.l, VECTOR_SEW32); + v1 = fpu_get_scratch(dyn); + if (MODREG) { + avx_load_reg_vector(dyn, ninst, x1, v1, (nextop & 7) + (rex.b << 3), 16 << vex.l, VECTOR_SEW32); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE32_V(v1, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + VAESEF_VV(v0, v1); + avx_store_reg_vector(dyn, ninst, x1, v0, gd, 16 << vex.l, VECTOR_SEW32); + break; + } GETGX(); GETVX(); if (vex.l) { @@ -1223,6 +1257,200 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t i } else YMM0(gd); break; + case 0xDB: + INST_NAME("VAESIMC Gx, Ex"); + nextop = F8; + if (vex.l) { + DEFAULT; + } + if (cpuext.zvkned) { + gd = ((nextop & 0x38) >> 3) + (rex.r << 3); + SET_AVX_VECTOR_WIDTH(x1, VECTOR_SEW32); + v1 = fpu_get_scratch(dyn); + if (MODREG) { + avx_load_reg_vector(dyn, ninst, x1, v1, (nextop & 7) + (rex.b << 3), 16, VECTOR_SEW32); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE32_V(v1, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + v2 = fpu_get_scratch(dyn); + MOV32w(x4, 0x63636363); + VMV_V_X(v2, x4); + VAESDM_VV(v2, v1); + avx_store_reg_vector(dyn, ninst, x1, v2, gd, 16, VECTOR_SEW32); + break; + } + GETGX(); + GETEX(x2, 0, 14); + for (int i = 0; i < 2; ++i) { + LD(x3, wback, fixedaddress + i * 8); + SD(x3, gback, gdoffset + i * 8); + } + sse_forget_reg(dyn, ninst, x6, gd); + MOV32w(x1, gd); + CALL(const_native_aesimc, -1, x1, 0); + break; + case 0xDE: + INST_NAME("VAESDEC Gx, Vx, Ex"); + nextop = F8; + if (cpuext.zvkned && (!vex.l || cpuext.vlen >= 32)) { + gd = ((nextop & 0x38) >> 3) + (rex.r << 3); + SET_AVX_VECTOR_WIDTH(x1, VECTOR_SEW32); + v0 = fpu_get_scratch(dyn); + avx_load_reg_vector(dyn, ninst, x1, v0, vex.v, 16 << vex.l, VECTOR_SEW32); + v1 = fpu_get_scratch(dyn); + if (MODREG) { + avx_load_reg_vector(dyn, ninst, x1, v1, (nextop & 7) + (rex.b << 3), 16 << vex.l, VECTOR_SEW32); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE32_V(v1, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + v2 = fpu_get_scratch(dyn); + VXOR_VV(v2, v2, v2, 1); + VAESDF_VV(v0, v2); + v2 = fpu_get_scratch(dyn); + MOV32w(x4, 0x63636363); + VMV_V_X(v2, x4); + VAESDM_VV(v2, v0); + VXOR_VV(v0, v2, v1, 1); + avx_store_reg_vector(dyn, ninst, x1, v0, gd, 16 << vex.l, VECTOR_SEW32); + break; + } + GETGX(); + GETVX(); + if (vex.l) { + GETGY(); + GETVY(); + } + GETEX(x2, 0, vex.l ? 30 : 14); + for (int i = 0; i < 2; ++i) { + LD(x3, wback, fixedaddress + i * 8); + SD(x3, xEmu, offsetof(x64emu_t, scratch) + i * 8); + } + if (vex.l) { + GETEY(); + for (int i = 0; i < 2; ++i) { + LD(x3, wback, fixedaddress + i * 8); + SD(x3, xEmu, offsetof(x64emu_t, scratch) + 16 + i * 8); + } + } + if (gd != vex.v) { + for (int i = 0; i < 2; ++i) { + LD(x3, vback, vxoffset + i * 8); + SD(x3, xEmu, gdoffset + i * 8); + } + if (vex.l) { + for (int i = 0; i < 2; ++i) { + LD(x3, vback, vyoffset + i * 8); + SD(x3, xEmu, gyoffset + i * 8); + } + } + } + MOV32w(x1, gd); + CALL(const_native_aesd, -1, x1, 0); + if (vex.l) { + MOV32w(x1, gd); + CALL(const_native_aesd_y, -1, x1, 0); + } + for (int i = 0; i < 2; ++i) { + LD(x3, xEmu, gdoffset + i * 8); + LD(x4, xEmu, offsetof(x64emu_t, scratch) + i * 8); + XOR(x3, x3, x4); + SD(x3, xEmu, gdoffset + i * 8); + } + if (vex.l) { + for (int i = 0; i < 2; ++i) { + LD(x3, xEmu, gyoffset + i * 8); + LD(x4, xEmu, offsetof(x64emu_t, scratch) + 16 + i * 8); + XOR(x3, x3, x4); + SD(x3, xEmu, gyoffset + i * 8); + } + } else + YMM0(gd); + break; + case 0xDF: + INST_NAME("VAESDECLAST Gx, Vx, Ex"); + nextop = F8; + if (cpuext.zvkned && (!vex.l || cpuext.vlen >= 32)) { + gd = ((nextop & 0x38) >> 3) + (rex.r << 3); + SET_AVX_VECTOR_WIDTH(x1, VECTOR_SEW32); + v0 = fpu_get_scratch(dyn); + avx_load_reg_vector(dyn, ninst, x1, v0, vex.v, 16 << vex.l, VECTOR_SEW32); + v1 = fpu_get_scratch(dyn); + if (MODREG) { + avx_load_reg_vector(dyn, ninst, x1, v1, (nextop & 7) + (rex.b << 3), 16 << vex.l, VECTOR_SEW32); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 0); + VLE32_V(v1, ed, VECTOR_UNMASKED, VECTOR_NFIELD1); + } + VAESDF_VV(v0, v1); + avx_store_reg_vector(dyn, ninst, x1, v0, gd, 16 << vex.l, VECTOR_SEW32); + break; + } + GETGX(); + GETVX(); + if (vex.l) { + GETGY(); + GETVY(); + } + GETEX(x2, 0, vex.l ? 30 : 14); + for (int i = 0; i < 2; ++i) { + LD(x3, wback, fixedaddress + i * 8); + SD(x3, xEmu, offsetof(x64emu_t, scratch) + i * 8); + } + if (vex.l) { + GETEY(); + for (int i = 0; i < 2; ++i) { + LD(x3, wback, fixedaddress + i * 8); + SD(x3, xEmu, offsetof(x64emu_t, scratch) + 16 + i * 8); + } + } + if (gd != vex.v) { + for (int i = 0; i < 2; ++i) { + LD(x3, vback, vxoffset + i * 8); + SD(x3, xEmu, gdoffset + i * 8); + } + if (vex.l) { + for (int i = 0; i < 2; ++i) { + LD(x3, vback, vyoffset + i * 8); + SD(x3, xEmu, gyoffset + i * 8); + } + } + } + MOV32w(x1, gd); + CALL(const_native_aesdlast, -1, x1, 0); + if (vex.l) { + MOV32w(x1, gd); + CALL(const_native_aesdlast_y, -1, x1, 0); + } + for (int i = 0; i < 2; ++i) { + LD(x3, xEmu, gdoffset + i * 8); + LD(x4, xEmu, offsetof(x64emu_t, scratch) + i * 8); + XOR(x3, x3, x4); + SD(x3, xEmu, gdoffset + i * 8); + } + if (vex.l) { + for (int i = 0; i < 2; ++i) { + LD(x3, xEmu, gyoffset + i * 8); + LD(x4, xEmu, offsetof(x64emu_t, scratch) + 16 + i * 8); + XOR(x3, x3, x4); + SD(x3, xEmu, gyoffset + i * 8); + } + } else + YMM0(gd); + break; + case 0xF7: + INST_NAME("SHLX Gd, Ed, Vd"); + nextop = F8; + GETGD; + GETED(0); + GETVD; + ANDI(x5, vd, rex.w ? 0x3f : 0x1f); + SLLxw(gd, ed, x5); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 4db9a18b50..f963c6ed6f 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -1662,6 +1662,17 @@ #define VS4R_V(vs3, rs1) EMIT(I_type(0b011000101000, rs1, 0b000, vs3, 0b0100111)) // 011000101000.....000.....0100111 #define VS8R_V(vs3, rs1) EMIT(I_type(0b111000101000, rs1, 0b000, vs3, 0b0100111)) // 111000101000.....000.....0100111 +// Vector Cryptography (Zvkned / Zvknha) — only valid with SEW=32, LMUL>=1, vl multiple of 4 + +#define VAESEF_VV(vd, vs2) EMIT((0xA201A077) | ((vs2) << 20) | ((vd) << 7)) +#define VAESEM_VV(vd, vs2) EMIT((0xA2012077) | ((vs2) << 20) | ((vd) << 7)) +#define VAESDF_VV(vd, vs2) EMIT((0xA200A077) | ((vs2) << 20) | ((vd) << 7)) +#define VAESDM_VV(vd, vs2) EMIT((0xA2002077) | ((vs2) << 20) | ((vd) << 7)) + +#define VSHA2MS_VV(vd, vs2, vs1) EMIT((0xB6002077) | ((vs1) << 15) | ((vs2) << 20) | ((vd) << 7)) +#define VSHA2CH_VV(vd, vs2, vs1) EMIT((0xBA002077) | ((vs1) << 15) | ((vs2) << 20) | ((vd) << 7)) +#define VSHA2CL_VV(vd, vs2, vs1) EMIT((0xBE002077) | ((vs1) << 15) | ((vs2) << 20) | ((vd) << 7)) + // Vector Floating-Point Instructions // https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#14-vector-floating-point-instructions @@ -1908,6 +1919,8 @@ #define VNCLIPU_WI(vd, vs2, simm5, vm) EMIT(R_type(0b1011100 | (vm), vs2, simm5, 0b011, vd, 0b1010111)) // 101110...........011.....1010111 #define VNCLIP_WI(vd, vs2, simm5, vm) EMIT(R_type(0b1011110 | (vm), vs2, simm5, 0b011, vd, 0b1010111)) // 101111...........011.....1010111 +#define VROR_VI(vd, vs2, uimm6, vm) EMIT(R_type(0b0101000 | (vm) | (((uimm6) >> 5) << 1), vs2, (uimm6) & 0x1F, 0b011, vd, 0b1010111)) + #define VMV1R_V(vd, vs2) EMIT(R_type(0b1001111, vs2, 0b00000, 0b011, vd, 0b1010111)) // 1001111.....00000011.....1010111 #define VMV2R_V(vd, vs2) EMIT(R_type(0b1001111, vs2, 0b00001, 0b011, vd, 0b1010111)) // 1001111.....00001011.....1010111 #define VMV4R_V(vd, vs2) EMIT(R_type(0b1001111, vs2, 0b00011, 0b011, vd, 0b1010111)) // 1001111.....00011011.....1010111 diff --git a/src/include/hostext.h b/src/include/hostext.h index 997ab2afb1..5c01909269 100644 --- a/src/include/hostext.h +++ b/src/include/hostext.h @@ -40,6 +40,10 @@ typedef union cpu_ext_s { uint64_t zicbom : 1; uint64_t zicbop : 1; uint64_t zicond : 1; + uint64_t zvkned : 1; + uint64_t zvknha : 1; + uint64_t zvknhb : 1; + uint64_t zvbb : 1; #elif defined(LA64) uint64_t lbt : 1; // it's important it's stay the 1st bit uint64_t lam_bh : 1; diff --git a/src/os/hostext_common.c b/src/os/hostext_common.c index 5269b0b0bd..528b1948f5 100644 --- a/src/os/hostext_common.c +++ b/src/os/hostext_common.c @@ -68,6 +68,10 @@ void PrintHostCpuFeatures(void) // if(cpuext.xtheadmac) printf_log_prefix(0, LOG_INFO, " xtheadmac"); // if(cpuext.xtheadfmv) printf_log_prefix(0, LOG_INFO, " xtheadfmv"); if (cpuext.xtheadvector) printf_log_prefix(0, LOG_INFO, "_xthvector"); + if (cpuext.zvkned) printf_log_prefix(0, LOG_INFO, "_zvkned"); + if (cpuext.zvknha) printf_log_prefix(0, LOG_INFO, "_zvknha"); + if (cpuext.zvknhb) printf_log_prefix(0, LOG_INFO, "_zvknhb"); + if (cpuext.zvbb) printf_log_prefix(0, LOG_INFO, "_zvbb"); printf_log_prefix(0, LOG_INFO, "\n"); #elif defined(PPC64LE) printf_log(LOG_INFO, "Dynarec for PPC64LE (POWER9+, ISA 3.0)"); diff --git a/src/os/hostext_linux.c b/src/os/hostext_linux.c index 7d4a997364..87699acf41 100644 --- a/src/os/hostext_linux.c +++ b/src/os/hostext_linux.c @@ -156,6 +156,29 @@ void rv64Detect(void) } } + if (cpuext.vector) { + block = (uint32_t*)my_block; + VSETIVLI(x5, 4, (VECTOR_SEW32 << (3 - !!cpuext.xtheadvector)) | VECTOR_LMUL1); // vsetivli x5, 4, e32, m1 + VAESEM_VV(3, 4); // vaesem.vv v3, v4 + ADDI(A0, xZR, 42); + BR(xRA); + cpuext.zvkned = Check(my_block); + + block = (uint32_t*)my_block; + VSETIVLI(x5, 4, (VECTOR_SEW32 << (3 - !!cpuext.xtheadvector)) | VECTOR_LMUL1); // vsetivli x5, 4, e32, m1 + VSHA2MS_VV(3, 4, 5); // vsha2ms.vv v3, v4, v5 + ADDI(A0, xZR, 42); + BR(xRA); + cpuext.zvknha = cpuext.zvknhb = Check(my_block); + + block = (uint32_t*)my_block; + VSETIVLI(x5, 4, (VECTOR_SEW32 << (3 - !!cpuext.xtheadvector)) | VECTOR_LMUL1); // vsetivli x5, 4, e32, m1 + VROR_VI(3, 4, 1, 1); // vror.vi v3, v4, 1 + ADDI(A0, xZR, 42); + BR(xRA); + cpuext.zvbb = Check(my_block); + } + // Finish // Free the memory my_block munmap(my_block, box64_pagesize); @@ -282,6 +305,12 @@ int DetectHostCpuFeatures(void) if (!strcasecmp(p, "zicbom")) cpuext.zicbom = 0; if (!strcasecmp(p, "zicbop")) cpuext.zicbop = 0; if (!strcasecmp(p, "zicond")) cpuext.zicond = 0; + if (!strcasecmp(p, "zvkned")) cpuext.zvkned = 0; + if (!strcasecmp(p, "zvknha")) { + cpuext.zvknha = 0; + cpuext.zvknhb = 0; + } + if (!strcasecmp(p, "zvbb")) cpuext.zvbb = 0; p = strtok(NULL, ","); } }