diff --git a/api/docs/release.dox b/api/docs/release.dox
index c2faec4ea75..f108f45f4a5 100644
--- a/api/docs/release.dox
+++ b/api/docs/release.dox
@@ -227,7 +227,6 @@ Further non-compatibility-affecting changes include:
- Added instr_convert_to_isa_regdeps() API that converts an #instr_t from a real ISA
(e.g., #DR_ISA_AMD64) to the #DR_ISA_REGDEPS synthetic ISA.
-
**************************************************
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 7146c53ca6e..6a5177d641b 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -279,6 +279,7 @@ set(DECODER_SRCS
ir/${ARCH_NAME}/decode.c
ir/encode_shared.c
ir/${ARCH_NAME}/encode.c
+ ir/isa_regdeps/encoding_common.c
ir/isa_regdeps/encode.c
ir/isa_regdeps/decode.c
ir/disassemble_shared.c
diff --git a/core/ir/aarch64/encode.c b/core/ir/aarch64/encode.c
index 8e02d63dafd..57601a32878 100644
--- a/core/ir/aarch64/encode.c
+++ b/core/ir/aarch64/encode.c
@@ -196,6 +196,177 @@ const reg_id_t dr_reg_fixer[] = { REG_NULL,
DR_REG_CNTVCT_EL0,
};
+
+/* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register.
+ * Note that we map real sub-registers to their corresponding containing virtual register.
+ * Same size as dr_reg_fixer[], keep them synched.
+ */
+const reg_id_t d_r_reg_id_to_virtual[] = {
+ DR_REG_NULL, /* DR_REG_NULL */
+ DR_REG_NULL, /* DR_REG_NULL */
+
+#define VIRTUAL_XREGS
+ DR_REG_V0, DR_REG_V1, DR_REG_V2, DR_REG_V3, DR_REG_V4, DR_REG_V5, DR_REG_V6, \
+ DR_REG_V7, DR_REG_V8, DR_REG_V9, DR_REG_V10, DR_REG_V11, DR_REG_V12, DR_REG_V13, \
+ DR_REG_V14, DR_REG_V15, DR_REG_V16, DR_REG_V17, DR_REG_V18, DR_REG_V19, \
+ DR_REG_V20, DR_REG_V21, DR_REG_V22, DR_REG_V23, DR_REG_V24, DR_REG_V25, \
+ DR_REG_V26, DR_REG_V27, DR_REG_V28, DR_REG_V29, DR_REG_V30, DR_REG_V31, \
+ DR_REG_V32,
+
+ VIRTUAL_XREGS /* from DR_REG_X0 to DR_REG_XZR */
+ VIRTUAL_XREGS /* from DR_REG_W0 to DR_REG_WZR */
+#undef VIRTUAL_XREGS
+
+#define VIRTUAL_ZREGS
+ DR_REG_V33, DR_REG_V34, DR_REG_V35, DR_REG_V36, DR_REG_V37, DR_REG_V38, DR_REG_V39, \
+ DR_REG_V40, DR_REG_V41, DR_REG_V42, DR_REG_V43, DR_REG_V44, DR_REG_V45, DR_REG_V46, \
+ DR_REG_V47, DR_REG_V48, DR_REG_V49, DR_REG_V50, DR_REG_V51, DR_REG_V52, \
+ DR_REG_V53, DR_REG_V54, DR_REG_V55, DR_REG_V56, DR_REG_V57, DR_REG_V58, \
+ DR_REG_V59, DR_REG_V60, DR_REG_V61, DR_REG_V62, DR_REG_V63, DR_REG_V64,
+
+ VIRTUAL_ZREGS /* from DR_REG_Z0 to DR_REG_Z31 */
+ VIRTUAL_ZREGS /* from DR_REG_Q0 to DR_REG_Q31 */
+ VIRTUAL_ZREGS /* from DR_REG_D0 to DR_REG_D31 */
+ VIRTUAL_ZREGS /* from DR_REG_S0 to DR_REG_S31 */
+ VIRTUAL_ZREGS /* from DR_REG_H0 to DR_REG_H31 */
+ VIRTUAL_ZREGS /* from DR_REG_B0 to DR_REG_B31 */
+#undef VIRTUAL_ZREGS
+
+ DR_REG_V65, /* DR_REG_NZCV */
+ DR_REG_V66, /* DR_REG_FPCR */
+ DR_REG_V67, /* DR_REG_FPSR */
+ DR_REG_V68, /* DR_REG_MDCCSR_EL0 */
+ DR_REG_V69, /* DR_REG_DBGDTR_EL0 */
+ DR_REG_V70, /* DR_REG_DBGDTRRX_EL0 */
+ DR_REG_V71, /* DR_REG_SP_EL0 */
+ DR_REG_V72, /* DR_REG_SPSEL */
+ DR_REG_V73, /* DR_REG_DAIFSET */
+ DR_REG_V74, /* DR_REG_DAIFCLR */
+ DR_REG_V75, /* DR_REG_CURRENTEL */
+ DR_REG_V76, /* DR_REG_PAN */
+ DR_REG_V77, /* DR_REG_UAO */
+ DR_REG_V78, /* DR_REG_CTR_EL0 */
+ DR_REG_V79, /* DR_REG_DCZID_EL0 */
+ DR_REG_V80, /* DR_REG_RNDR */
+ DR_REG_V81, /* DR_REG_RNDRRS */
+ DR_REG_V82, /* DR_REG_DAIF */
+ DR_REG_V83, /* DR_REG_DIT */
+ DR_REG_V84, /* DR_REG_SSBS */
+ DR_REG_V85, /* DR_REG_TCO */
+ DR_REG_V86, /* DR_REG_DSPSR_EL0 */
+ DR_REG_V87, /* DR_REG_DLR_EL0 */
+ DR_REG_V88, /* DR_REG_PMCR_EL0 */
+ DR_REG_V89, /* DR_REG_PMCNTENSET_EL0 */
+ DR_REG_V90, /* DR_REG_PMCNTENCLR_EL0 */
+ DR_REG_V91, /* DR_REG_PMOVSCLR_EL0 */
+ DR_REG_V92, /* DR_REG_PMSWINC_EL0 */
+ DR_REG_V93, /* DR_REG_PMSELR_EL0 */
+ DR_REG_V94, /* DR_REG_PMCEID0_EL0 */
+ DR_REG_V95, /* DR_REG_PMCEID1_EL0 */
+ DR_REG_V96, /* DR_REG_PMCCNTR_EL0 */
+ DR_REG_V97, /* DR_REG_PMXEVTYPER_EL0 */
+ DR_REG_V98, /* DR_REG_PMXEVCNTR_EL0 */
+ DR_REG_V99, /* DR_REG_PMUSERENR_EL0 */
+ DR_REG_V100, /* DR_REG_PMOVSSET_EL0 */
+ DR_REG_V101, /* DR_REG_SCXTNUM_EL0 */
+ DR_REG_V102, /* DR_REG_CNTFRQ_EL0 */
+ DR_REG_V103, /* DR_REG_CNTPCT_EL0 */
+ DR_REG_V104, /* DR_REG_CNTP_TVAL_EL0 */
+ DR_REG_V105, /* DR_REG_CNTP_CTL_EL0 */
+ DR_REG_V106, /* DR_REG_CNTP_CVAL_EL0 */
+ DR_REG_V107, /* DR_REG_CNTV_TVAL_EL0 */
+ DR_REG_V108, /* DR_REG_CNTV_CTL_EL0 */
+ DR_REG_V109, /* DR_REG_CNTV_CVAL_EL0 */
+ DR_REG_V110, /* DR_REG_PMEVCNTR0_EL0 */
+ DR_REG_V111, /* DR_REG_PMEVCNTR1_EL0 */
+ DR_REG_V112, /* DR_REG_PMEVCNTR2_EL0 */
+ DR_REG_V113, /* DR_REG_PMEVCNTR3_EL0 */
+ DR_REG_V114, /* DR_REG_PMEVCNTR4_EL0 */
+ DR_REG_V115, /* DR_REG_PMEVCNTR5_EL0 */
+ DR_REG_V116, /* DR_REG_PMEVCNTR6_EL0 */
+ DR_REG_V117, /* DR_REG_PMEVCNTR7_EL0 */
+ DR_REG_V118, /* DR_REG_PMEVCNTR8_EL0 */
+ DR_REG_V119, /* DR_REG_PMEVCNTR9_EL0 */
+ DR_REG_V120, /* DR_REG_PMEVCNTR10_EL0 */
+ DR_REG_V121, /* DR_REG_PMEVCNTR11_EL0 */
+ DR_REG_V122, /* DR_REG_PMEVCNTR12_EL0 */
+ DR_REG_V123, /* DR_REG_PMEVCNTR13_EL0 */
+ DR_REG_V124, /* DR_REG_PMEVCNTR14_EL0 */
+ DR_REG_V125, /* DR_REG_PMEVCNTR15_EL0 */
+ DR_REG_V126, /* DR_REG_PMEVCNTR16_EL0 */
+ DR_REG_V127, /* DR_REG_PMEVCNTR17_EL0 */
+ DR_REG_V128, /* DR_REG_PMEVCNTR18_EL0 */
+ DR_REG_V129, /* DR_REG_PMEVCNTR19_EL0 */
+ DR_REG_V130, /* DR_REG_PMEVCNTR20_EL0 */
+ DR_REG_V131, /* DR_REG_PMEVCNTR21_EL0 */
+ DR_REG_V132, /* DR_REG_PMEVCNTR22_EL0 */
+ DR_REG_V133, /* DR_REG_PMEVCNTR23_EL0 */
+ DR_REG_V134, /* DR_REG_PMEVCNTR24_EL0 */
+ DR_REG_V135, /* DR_REG_PMEVCNTR25_EL0 */
+ DR_REG_V136, /* DR_REG_PMEVCNTR26_EL0 */
+ DR_REG_V137, /* DR_REG_PMEVCNTR27_EL0 */
+ DR_REG_V138, /* DR_REG_PMEVCNTR28_EL0 */
+ DR_REG_V139, /* DR_REG_PMEVCNTR29_EL0 */
+ DR_REG_V140, /* DR_REG_PMEVCNTR30_EL0 */
+ DR_REG_V141, /* DR_REG_PMEVTYPER0_EL0 */
+ DR_REG_V142, /* DR_REG_PMEVTYPER1_EL0 */
+ DR_REG_V143, /* DR_REG_PMEVTYPER2_EL0 */
+ DR_REG_V144, /* DR_REG_PMEVTYPER3_EL0 */
+ DR_REG_V145, /* DR_REG_PMEVTYPER4_EL0 */
+ DR_REG_V146, /* DR_REG_PMEVTYPER5_EL0 */
+ DR_REG_V147, /* DR_REG_PMEVTYPER6_EL0 */
+ DR_REG_V148, /* DR_REG_PMEVTYPER7_EL0 */
+ DR_REG_V149, /* DR_REG_PMEVTYPER8_EL0 */
+ DR_REG_V150, /* DR_REG_PMEVTYPER9_EL0 */
+ DR_REG_V151, /* DR_REG_PMEVTYPER10_EL0 */
+ DR_REG_V152, /* DR_REG_PMEVTYPER11_EL0 */
+ DR_REG_V153, /* DR_REG_PMEVTYPER12_EL0 */
+ DR_REG_V154, /* DR_REG_PMEVTYPER13_EL0 */
+ DR_REG_V155, /* DR_REG_PMEVTYPER14_EL0 */
+ DR_REG_V156, /* DR_REG_PMEVTYPER15_EL0 */
+ DR_REG_V157, /* DR_REG_PMEVTYPER16_EL0 */
+ DR_REG_V158, /* DR_REG_PMEVTYPER17_EL0 */
+ DR_REG_V159, /* DR_REG_PMEVTYPER18_EL0 */
+ DR_REG_V160, /* DR_REG_PMEVTYPER19_EL0 */
+ DR_REG_V161, /* DR_REG_PMEVTYPER20_EL0 */
+ DR_REG_V162, /* DR_REG_PMEVTYPER21_EL0 */
+ DR_REG_V163, /* DR_REG_PMEVTYPER22_EL0 */
+ DR_REG_V164, /* DR_REG_PMEVTYPER23_EL0 */
+ DR_REG_V165, /* DR_REG_PMEVTYPER24_EL0 */
+ DR_REG_V166, /* DR_REG_PMEVTYPER25_EL0 */
+ DR_REG_V167, /* DR_REG_PMEVTYPER26_EL0 */
+ DR_REG_V168, /* DR_REG_PMEVTYPER27_EL0 */
+ DR_REG_V169, /* DR_REG_PMEVTYPER28_EL0 */
+ DR_REG_V170, /* DR_REG_PMEVTYPER29_EL0 */
+ DR_REG_V171, /* DR_REG_PMEVTYPER30_EL0 */
+ DR_REG_V172, /* DR_REG_PMCCFILTR_EL0 */
+ DR_REG_V173, /* DR_REG_SPSR_IRQ */
+ DR_REG_V174, /* DR_REG_SPSR_ABT */
+ DR_REG_V175, /* DR_REG_SPSR_UND */
+ DR_REG_V176, /* DR_REG_SPSR_FIQ */
+ DR_REG_V177, /* DR_REG_TPIDR_EL0 */
+ DR_REG_V178, /* DR_REG_TPIDRRO_EL0 */
+
+ DR_REG_V179, /* DR_REG_P0 */
+ DR_REG_V180, /* DR_REG_P1 */
+ DR_REG_V181, /* DR_REG_P2 */
+ DR_REG_V182, /* DR_REG_P3 */
+ DR_REG_V183, /* DR_REG_P4 */
+ DR_REG_V184, /* DR_REG_P5 */
+ DR_REG_V185, /* DR_REG_P6 */
+ DR_REG_V186, /* DR_REG_P7 */
+ DR_REG_V187, /* DR_REG_P8 */
+ DR_REG_V188, /* DR_REG_P9 */
+ DR_REG_V189, /* DR_REG_P10 */
+ DR_REG_V190, /* DR_REG_P11 */
+ DR_REG_V191, /* DR_REG_P12 */
+ DR_REG_V192, /* DR_REG_P13 */
+ DR_REG_V193, /* DR_REG_P14 */
+ DR_REG_V194, /* DR_REG_P15 */
+ DR_REG_V195, /* DR_REG_FFR */
+
+ DR_REG_V196, /* DR_REG_CNTVCT_EL0 */
+};
/* clang-format on */
#ifdef DEBUG
diff --git a/core/ir/arm/encode.c b/core/ir/arm/encode.c
index 60953651af8..d0b1aec64fd 100644
--- a/core/ir/arm/encode.c
+++ b/core/ir/arm/encode.c
@@ -461,6 +461,238 @@ const reg_id_t dr_reg_fixer[] = {
DR_REG_TPIDRURO,
};
+/* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register.
+ * Note that we map real sub-registers to their corresponding containing virtual register.
+ * Same size as dr_reg_fixer[], keep them synched.
+ */
+const reg_id_t d_r_reg_id_to_virtual[] = {
+ DR_REG_NULL, /* DR_REG_NULL */
+ DR_REG_NULL, /* DR_REG_NULL */
+
+ /* from DR_REG_R0 to DR_REG_R15 */
+ DR_REG_V0, /* DR_REG_R0 */
+ DR_REG_V1, /* DR_REG_R1 */
+ DR_REG_V2, /* DR_REG_R2 */
+ DR_REG_V3, /* DR_REG_R3 */
+ DR_REG_V4, /* DR_REG_R4 */
+ DR_REG_V5, /* DR_REG_R5 */
+ DR_REG_V6, /* DR_REG_R6 */
+ DR_REG_V7, /* DR_REG_R7 */
+ DR_REG_V8, /* DR_REG_R8 */
+ DR_REG_V9, /* DR_REG_R9 */
+ DR_REG_V10, /* DR_REG_R10 */
+ DR_REG_V11, /* DR_REG_R11 */
+ DR_REG_V12, /* DR_REG_R12 */
+ DR_REG_V13, /* DR_REG_R13 or DR_REG_SP */
+ DR_REG_V14, /* DR_REG_R14 or DR_REG_LR */
+ DR_REG_V15, /* DR_REG_R15 or DR_REG_PC */
+
+ /* from DR_REG_Q0 to DR_REG_Q31 */
+ DR_REG_V16, /* DR_REG_Q0 */
+ DR_REG_V17, /* DR_REG_Q1 */
+ DR_REG_V18, /* DR_REG_Q2 */
+ DR_REG_V19, /* DR_REG_Q3 */
+ DR_REG_V20, /* DR_REG_Q4 */
+ DR_REG_V21, /* DR_REG_Q5 */
+ DR_REG_V22, /* DR_REG_Q6 */
+ DR_REG_V23, /* DR_REG_Q7 */
+ DR_REG_V24, /* DR_REG_Q8 */
+ DR_REG_V25, /* DR_REG_Q9 */
+ DR_REG_V26, /* DR_REG_Q10 */
+ DR_REG_V27, /* DR_REG_Q11 */
+ DR_REG_V28, /* DR_REG_Q12 */
+ DR_REG_V29, /* DR_REG_Q13 */
+ DR_REG_V30, /* DR_REG_Q14 */
+ DR_REG_V31, /* DR_REG_Q15 */
+ /* The following are x64-only but simpler code to not ifdef it.
+ */
+ DR_REG_V32, /* DR_REG_Q16 */
+ DR_REG_V33, /* DR_REG_Q17 */
+ DR_REG_V34, /* DR_REG_Q18 */
+ DR_REG_V35, /* DR_REG_Q19 */
+ DR_REG_V36, /* DR_REG_Q20 */
+ DR_REG_V37, /* DR_REG_Q21 */
+ DR_REG_V38, /* DR_REG_Q22 */
+ DR_REG_V39, /* DR_REG_Q23 */
+ DR_REG_V40, /* DR_REG_Q24 */
+ DR_REG_V41, /* DR_REG_Q25 */
+ DR_REG_V42, /* DR_REG_Q26 */
+ DR_REG_V43, /* DR_REG_Q27 */
+ DR_REG_V44, /* DR_REG_Q28 */
+ DR_REG_V45, /* DR_REG_Q29 */
+ DR_REG_V46, /* DR_REG_Q30 */
+ DR_REG_V47, /* DR_REG_Q31 */
+
+ /* For AArch64, the smaller SIMD names refer to the lower
+ * bits of the corresponding same-number larger SIMD register.
+ * But for AArch32, the smaller ones are compressed such that
+ * they refer to the top and bottom. B and H are AArch64-only.
+ */
+ /* from DR_REG_D0 to DR_REG_D31 */
+ DR_REG_V16, /* DR_REG_D0 */
+ DR_REG_V16, /* DR_REG_D1 */
+ DR_REG_V17, /* DR_REG_D2 */
+ DR_REG_V17, /* DR_REG_D3 */
+ DR_REG_V18, /* DR_REG_D4 */
+ DR_REG_V18, /* DR_REG_D5 */
+ DR_REG_V19, /* DR_REG_D6 */
+ DR_REG_V19, /* DR_REG_D7 */
+ DR_REG_V20, /* DR_REG_D8 */
+ DR_REG_V20, /* DR_REG_D9 */
+ DR_REG_V21, /* DR_REG_D10 */
+ DR_REG_V21, /* DR_REG_D11 */
+ DR_REG_V22, /* DR_REG_D12 */
+ DR_REG_V22, /* DR_REG_D13 */
+ DR_REG_V23, /* DR_REG_D14 */
+ DR_REG_V23, /* DR_REG_D15 */
+ DR_REG_V24, /* DR_REG_D16 */
+ DR_REG_V24, /* DR_REG_D17 */
+ DR_REG_V25, /* DR_REG_D18 */
+ DR_REG_V25, /* DR_REG_D19 */
+ DR_REG_V26, /* DR_REG_D20 */
+ DR_REG_V26, /* DR_REG_D21 */
+ DR_REG_V27, /* DR_REG_D22 */
+ DR_REG_V27, /* DR_REG_D23 */
+ DR_REG_V28, /* DR_REG_D24 */
+ DR_REG_V28, /* DR_REG_D25 */
+ DR_REG_V29, /* DR_REG_D26 */
+ DR_REG_V29, /* DR_REG_D27 */
+ DR_REG_V30, /* DR_REG_D28 */
+ DR_REG_V30, /* DR_REG_D29 */
+ DR_REG_V31, /* DR_REG_D30 */
+ DR_REG_V31, /* DR_REG_D31 */
+
+ /* from DR_REG_S0 to DR_REG_S31 */
+ DR_REG_V16, /* DR_REG_S0 */
+ DR_REG_V16, /* DR_REG_S1 */
+ DR_REG_V16, /* DR_REG_S2 */
+ DR_REG_V16, /* DR_REG_S3 */
+ DR_REG_V17, /* DR_REG_S4 */
+ DR_REG_V17, /* DR_REG_S5 */
+ DR_REG_V17, /* DR_REG_S6 */
+ DR_REG_V17, /* DR_REG_S7 */
+ DR_REG_V18, /* DR_REG_S8 */
+ DR_REG_V18, /* DR_REG_S9 */
+ DR_REG_V18, /* DR_REG_S10 */
+ DR_REG_V18, /* DR_REG_S11 */
+ DR_REG_V19, /* DR_REG_S12 */
+ DR_REG_V19, /* DR_REG_S13 */
+ DR_REG_V19, /* DR_REG_S14 */
+ DR_REG_V19, /* DR_REG_S15 */
+ DR_REG_V20, /* DR_REG_S16 */
+ DR_REG_V20, /* DR_REG_S17 */
+ DR_REG_V20, /* DR_REG_S18 */
+ DR_REG_V20, /* DR_REG_S19 */
+ DR_REG_V21, /* DR_REG_S20 */
+ DR_REG_V21, /* DR_REG_S21 */
+ DR_REG_V21, /* DR_REG_S22 */
+ DR_REG_V21, /* DR_REG_S23 */
+ DR_REG_V22, /* DR_REG_S24 */
+ DR_REG_V22, /* DR_REG_S25 */
+ DR_REG_V22, /* DR_REG_S26 */
+ DR_REG_V22, /* DR_REG_S27 */
+ DR_REG_V23, /* DR_REG_S28 */
+ DR_REG_V23, /* DR_REG_S29 */
+ DR_REG_V23, /* DR_REG_S30 */
+ DR_REG_V23, /* DR_REG_S31 */
+
+ /* AArch64-only.
+ * from DR_REG_H0 to DR_REG_H31
+ */
+ DR_REG_V16, /* DR_REG_H0 */
+ DR_REG_V17, /* DR_REG_H1 */
+ DR_REG_V18, /* DR_REG_H2 */
+ DR_REG_V19, /* DR_REG_H3 */
+ DR_REG_V20, /* DR_REG_H4 */
+ DR_REG_V21, /* DR_REG_H5 */
+ DR_REG_V22, /* DR_REG_H6 */
+ DR_REG_V23, /* DR_REG_H7 */
+ DR_REG_V24, /* DR_REG_H8 */
+ DR_REG_V25, /* DR_REG_H9 */
+ DR_REG_V26, /* DR_REG_H10 */
+ DR_REG_V27, /* DR_REG_H11 */
+ DR_REG_V28, /* DR_REG_H12 */
+ DR_REG_V29, /* DR_REG_H13 */
+ DR_REG_V30, /* DR_REG_H14 */
+ DR_REG_V31, /* DR_REG_H15 */
+ DR_REG_V48, /* DR_REG_H16 */
+ DR_REG_V49, /* DR_REG_H17 */
+ DR_REG_V50, /* DR_REG_H18 */
+ DR_REG_V51, /* DR_REG_H19 */
+ DR_REG_V52, /* DR_REG_H20 */
+ DR_REG_V53, /* DR_REG_H21 */
+ DR_REG_V54, /* DR_REG_H22 */
+ DR_REG_V55, /* DR_REG_H23 */
+ DR_REG_V56, /* DR_REG_H24 */
+ DR_REG_V57, /* DR_REG_H25 */
+ DR_REG_V58, /* DR_REG_H26 */
+ DR_REG_V59, /* DR_REG_H27 */
+ DR_REG_V60, /* DR_REG_H28 */
+ DR_REG_V61, /* DR_REG_H29 */
+ DR_REG_V62, /* DR_REG_H30 */
+ DR_REG_V63, /* DR_REG_H31 */
+
+ /* AArch64-only.
+ * from DR_REG_B0 to DR_REG_B31
+ */
+ DR_REG_V16, /* DR_REG_B0 */
+ DR_REG_V17, /* DR_REG_B1 */
+ DR_REG_V18, /* DR_REG_B2 */
+ DR_REG_V19, /* DR_REG_B3 */
+ DR_REG_V20, /* DR_REG_B4 */
+ DR_REG_V21, /* DR_REG_B5 */
+ DR_REG_V22, /* DR_REG_B6 */
+ DR_REG_V23, /* DR_REG_B7 */
+ DR_REG_V24, /* DR_REG_B8 */
+ DR_REG_V25, /* DR_REG_B9 */
+ DR_REG_V26, /* DR_REG_B10 */
+ DR_REG_V27, /* DR_REG_B11 */
+ DR_REG_V28, /* DR_REG_B12 */
+ DR_REG_V29, /* DR_REG_B13 */
+ DR_REG_V30, /* DR_REG_B14 */
+ DR_REG_V31, /* DR_REG_B15 */
+ DR_REG_V48, /* DR_REG_B16 */
+ DR_REG_V49, /* DR_REG_B17 */
+ DR_REG_V50, /* DR_REG_B18 */
+ DR_REG_V51, /* DR_REG_B19 */
+ DR_REG_V52, /* DR_REG_B20 */
+ DR_REG_V53, /* DR_REG_B21 */
+ DR_REG_V54, /* DR_REG_B22 */
+ DR_REG_V55, /* DR_REG_B23 */
+ DR_REG_V56, /* DR_REG_B24 */
+ DR_REG_V57, /* DR_REG_B25 */
+ DR_REG_V58, /* DR_REG_B26 */
+ DR_REG_V59, /* DR_REG_B27 */
+ DR_REG_V60, /* DR_REG_B28 */
+ DR_REG_V61, /* DR_REG_B29 */
+ DR_REG_V62, /* DR_REG_B30 */
+ DR_REG_V63, /* DR_REG_B31 */
+
+ /* from DR_REG_C0 to DR_REG_C15 */
+ DR_REG_V64, /* DR_REG_C0 */
+ DR_REG_V65, /* DR_REG_C1 */
+ DR_REG_V66, /* DR_REG_C2 */
+ DR_REG_V67, /* DR_REG_C3 */
+ DR_REG_V68, /* DR_REG_C4 */
+ DR_REG_V69, /* DR_REG_C5 */
+ DR_REG_V70, /* DR_REG_C6 */
+ DR_REG_V71, /* DR_REG_C7 */
+ DR_REG_V72, /* DR_REG_C8 */
+ DR_REG_V73, /* DR_REG_C9 */
+ DR_REG_V74, /* DR_REG_C10 */
+ DR_REG_V75, /* DR_REG_C11 */
+ DR_REG_V76, /* DR_REG_C12 */
+ DR_REG_V77, /* DR_REG_C13 */
+ DR_REG_V78, /* DR_REG_C14 */
+ DR_REG_V79, /* DR_REG_C15 */
+
+ DR_REG_V80, /* DR_REG_CPSR */
+ DR_REG_V81, /* DR_REG_SPSR */
+ DR_REG_V82, /* DR_REG_FPSCR */
+ DR_REG_V83, /* DR_REG_TPIDRURW */
+ DR_REG_V84, /* DR_REG_TPIDRURO */
+};
+
const char *const type_names[] = {
"TYPE_NONE",
"TYPE_R_A",
diff --git a/core/ir/instr_shared.c b/core/ir/instr_shared.c
index 500e3d37386..fc88d7897b3 100644
--- a/core/ir/instr_shared.c
+++ b/core/ir/instr_shared.c
@@ -58,6 +58,7 @@
#include "../link.h"
#include "decode.h"
#include "decode_fast.h"
+#include "opnd.h"
#include "instr_create_shared.h"
/* FIXME i#1551: refactor this file and avoid this x86-specific include in base arch/ */
#include "x86/decode_private.h"
@@ -3017,10 +3018,10 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
reg_id_t reg = opnd_get_reg_used(dst_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
- reg_id_t reg_canonical = reg_to_pointer_sized(reg);
- if (!src_reg_used[reg_canonical]) {
+ reg_id_t reg_virtual = d_r_reg_to_virtual(reg);
+ if (!src_reg_used[reg_virtual]) {
++num_srcs;
- src_reg_used[reg_canonical] = true;
+ src_reg_used[reg_virtual] = true;
}
}
} else {
@@ -3028,10 +3029,10 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
reg_id_t reg = opnd_get_reg_used(dst_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
- reg_id_t reg_canonical = reg_to_pointer_sized(reg);
- if (!dst_reg_used[reg_canonical]) {
+ reg_id_t reg_virtual = d_r_reg_to_virtual(reg);
+ if (!dst_reg_used[reg_virtual]) {
++num_dsts;
- dst_reg_used[reg_canonical] = true;
+ dst_reg_used[reg_virtual] = true;
}
}
}
@@ -3057,10 +3058,10 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
reg_id_t reg = opnd_get_reg_used(src_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
- reg_id_t reg_canonical = reg_to_pointer_sized(reg);
- if (!src_reg_used[reg_canonical]) {
+ reg_id_t reg_virtual = d_r_reg_to_virtual(reg);
+ if (!src_reg_used[reg_virtual]) {
++num_srcs;
- src_reg_used[reg_canonical] = true;
+ src_reg_used[reg_virtual] = true;
}
}
}
@@ -3092,7 +3093,8 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
/* Convert max_src_opnd_size_bytes from number of bytes to opnd_size_t (which holds
* OPSZ_ enum values).
*/
- instr_regdeps_isa->operation_size = opnd_size_from_bytes(max_src_opnd_size_bytes);
+ opnd_size_t max_opnd_size = opnd_size_from_bytes(max_src_opnd_size_bytes);
+ instr_regdeps_isa->operation_size = max_opnd_size;
/* Set the source and destination register operands for the converted instruction.
*/
@@ -3101,6 +3103,22 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
for (uint reg = 0; reg < REGDEPS_MAX_NUM_REGS; ++reg) {
if (dst_reg_used[reg]) {
opnd_t dst_opnd = opnd_create_reg((reg_id_t)reg);
+ /* Virtual registers don't have a fixed size like real ISA registers do.
+ * So, it can happen that the same virtual register in two different
+ * instructions may have different sizes.
+ *
+ * Even though querying the size of a virtual register is not supported on
+ * purpose (a user should query the instr_t.operation_size), we set the
+ * opnd_t.size field to be the same as instr_t.operation_size (i.e.,
+ * max_opnd_size), so that reg_get_size() can return some meaningful
+ * information without triggering a CLIENT_ASSERT error because the
+ * virtual register ID is not supported (e.g., is one of the "reserved"
+ * register IDs).
+ *
+ * We do the same for both src and dst register operands of DR_ISA_REGDEPS
+ * instructions.
+ */
+ opnd_set_size(&dst_opnd, max_opnd_size);
instr_set_dst(instr_regdeps_isa, reg_counter, dst_opnd);
++reg_counter;
}
@@ -3112,6 +3130,7 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
for (uint reg = 0; reg < REGDEPS_MAX_NUM_REGS; ++reg) {
if (src_reg_used[reg]) {
opnd_t src_opnd = opnd_create_reg((reg_id_t)reg);
+ opnd_set_size(&src_opnd, max_opnd_size);
instr_set_src(instr_regdeps_isa, reg_counter, src_opnd);
++reg_counter;
}
diff --git a/core/ir/isa_regdeps/decode.c b/core/ir/isa_regdeps/decode.c
index 23794089f79..2ac0a8a7f7f 100644
--- a/core/ir/isa_regdeps/decode.c
+++ b/core/ir/isa_regdeps/decode.c
@@ -98,6 +98,22 @@ decode_isa_regdeps(dcontext_t *dcontext, byte *encoded_instr, instr_t *instr)
for (uint i = 0; i < num_dsts; ++i) {
reg_id_t dst = (reg_id_t)encoded_instr[i + REGDEPS_OPND_INDEX];
opnd_t dst_opnd = opnd_create_reg((reg_id_t)dst);
+ /* Virtual registers don't have a fixed size like real ISA registers do.
+ * So, it can happen that the same virtual register in two different
+ * instructions may have different sizes.
+ *
+ * Even though querying the size of a virtual register is not supported on
+ * purpose (a user should query the instr_t.operation_size), we set the
+ * opnd_t.size field to be the same as instr_t.operation_size (i.e.,
+ * max_opnd_size), so that reg_get_size() can return some meaningful
+ * information without triggering a CLIENT_ASSERT error because the
+ * virtual register ID is not supported (e.g., is one of the "reserved"
+ * register IDs).
+ *
+ * We do the same for both src and dst register operands of DR_ISA_REGDEPS
+ * instructions.
+ */
+ opnd_set_size(&dst_opnd, max_opnd_size);
instr_set_dst(instr, i, dst_opnd);
}
@@ -106,6 +122,7 @@ decode_isa_regdeps(dcontext_t *dcontext, byte *encoded_instr, instr_t *instr)
for (uint i = 0; i < num_srcs; ++i) {
reg_id_t src = (reg_id_t)encoded_instr[i + REGDEPS_OPND_INDEX + num_dsts];
opnd_t src_opnd = opnd_create_reg((reg_id_t)src);
+ opnd_set_size(&src_opnd, max_opnd_size);
instr_set_src(instr, i, src_opnd);
}
diff --git a/core/ir/isa_regdeps/encode.c b/core/ir/isa_regdeps/encode.c
index d26588f94d4..b3562480dc9 100644
--- a/core/ir/isa_regdeps/encode.c
+++ b/core/ir/isa_regdeps/encode.c
@@ -35,7 +35,6 @@
#include "encode.h"
#include "../globals.h"
-#include "encode_api.h"
#include "encoding_common.h"
#include "instr_api.h"
#include "opnd_api.h"
diff --git a/core/ir/isa_regdeps/encoding_common.c b/core/ir/isa_regdeps/encoding_common.c
new file mode 100644
index 00000000000..4802a93e9d1
--- /dev/null
+++ b/core/ir/isa_regdeps/encoding_common.c
@@ -0,0 +1,69 @@
+/* **********************************************************
+ * Copyright (c) 2024 Google, Inc. All rights reserved.
+ * **********************************************************/
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of VMware, Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+/* Keep this array (d_r_reg_virtual_names[]) and DR_REG_V enum in core/ir/opnd_api.h
+ * synched.
+ */
+const char *const d_r_reg_virtual_names[] = {
+ "rv_null", "rv_invalid", "rv0", "rv1", "rv2", "rv3", "rv4", "rv5",
+ "rv6", "rv7", "rv8", "rv9", "rv10", "rv11", "rv12", "rv13",
+ "rv14", "rv15", "rv16", "rv17", "rv18", "rv19", "rv20", "rv21",
+ "rv22", "rv23", "rv24", "rv25", "rv26", "rv27", "rv28", "rv29",
+ "rv30", "rv31", "rv32", "rv33", "rv34", "rv35", "rv36", "rv37",
+ "rv38", "rv39", "rv40", "rv41", "rv42", "rv43", "rv44", "rv45",
+ "rv46", "rv47", "rv48", "rv49", "rv50", "rv51", "rv52", "rv53",
+ "rv54", "rv55", "rv56", "rv57", "rv58", "rv59", "rv60", "rv61",
+ "rv62", "rv63", "rv64", "rv65", "rv66", "rv67", "rv68", "rv69",
+ "rv70", "rv71", "rv72", "rv73", "rv74", "rv75", "rv76", "rv77",
+ "rv78", "rv79", "rv80", "rv81", "rv82", "rv83", "rv84", "rv85",
+ "rv86", "rv87", "rv88", "rv89", "rv90", "rv91", "rv92", "rv93",
+ "rv94", "rv95", "rv96", "rv97", "rv98", "rv99", "rv100", "rv101",
+ "rv102", "rv103", "rv104", "rv105", "rv106", "rv107", "rv108", "rv109",
+ "rv110", "rv111", "rv112", "rv113", "rv114", "rv115", "rv116", "rv117",
+ "rv118", "rv119", "rv120", "rv121", "rv122", "rv123", "rv124", "rv125",
+ "rv126", "rv127", "rv128", "rv129", "rv130", "rv131", "rv132", "rv133",
+ "rv134", "rv135", "rv136", "rv137", "rv138", "rv139", "rv140", "rv141",
+ "rv142", "rv143", "rv144", "rv145", "rv146", "rv147", "rv148", "rv149",
+ "rv150", "rv151", "rv152", "rv153", "rv154", "rv155", "rv156", "rv157",
+ "rv158", "rv159", "rv160", "rv161", "rv162", "rv163", "rv164", "rv165",
+ "rv166", "rv167", "rv168", "rv169", "rv170", "rv171", "rv172", "rv173",
+ "rv174", "rv175", "rv176", "rv177", "rv178", "rv179", "rv180", "rv181",
+ "rv182", "rv183", "rv184", "rv_invalid", "rv185", "rv186", "rv187", "rv188",
+ "rv189", "rv190", "rv191", "rv192", "rv193", "rv194", "rv195", "rv196",
+ "rv197", "rv198", "rv199", "rv200", "rv201", "rv202", "rv203", "rv204",
+ "rv205", "rv206", "rv207", "rv208", "rv209", "rv210", "rv211", "rv212",
+ "rv213", "rv214", "rv215", "rv216", "rv217", "rv218", "rv219", "rv220",
+ "rv221", "rv222", "rv223", "rv224", "rv225", "rv226", "rv227", "rv228",
+ "rv229", "rv230", "rv231", "rv232", "rv233", "rv234", "rv235", "rv236",
+ "rv237", "rv238", "rv239", "rv240", "rv241", "rv242", "rv243", "rv244",
+ "rv245", "rv246", "rv247", "rv248", "rv249", "rv250", "rv251", "rv252",
+};
diff --git a/core/ir/opnd.h b/core/ir/opnd.h
index f440b90e7ac..9c83d551550 100644
--- a/core/ir/opnd.h
+++ b/core/ir/opnd.h
@@ -90,7 +90,9 @@
/* indexed by enum */
extern const char *const reg_names[];
+extern const char *const d_r_reg_virtual_names[];
extern const reg_id_t dr_reg_fixer[];
+extern const reg_id_t d_r_reg_id_to_virtual[];
#ifdef X86
# define REG_START_SPILL DR_REG_XAX
@@ -178,6 +180,13 @@ opnd_get_reg_dcontext_offs(reg_id_t reg);
int
opnd_get_reg_mcontext_offs(reg_id_t reg);
+/* Assumes that \p reg is a DR_REG_ 32-bit register constant.
+ * Returns the corresponding DR_ISA_REGDEPS virtual register of \p reg, which holds 8-bit
+ * DR_REG_V values.
+ */
+reg_id_t
+d_r_reg_to_virtual(reg_id_t reg);
+
/* internal version */
reg_t
reg_get_value_priv(reg_id_t reg, priv_mcontext_t *mc);
diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h
index 9fd3b19817a..40b5925a5fa 100644
--- a/core/ir/opnd_api.h
+++ b/core/ir/opnd_api.h
@@ -1307,6 +1307,271 @@ enum {
#endif
};
+/* We need a seprate DR_REG_V enum from DR_REG_ so we can start counting virtual registers
+ * from lower values. Otherwise, the DR_REG_ enum values won't fit in the 1 byte operand
+ * size of #DR_ISA_REGDEPS encoding. Note that DR_REG_V skips both values of
+ * DR_REG_INVALID to avoid issues with opnd_t operations.
+ */
+/** Virtual register identifiers for #DR_ISA_REGDEPS. */
+enum {
+ /**
+ * The first virtual register. Note that all virtual registers named here are valid.
+ */
+ DR_REG_V0 = DR_REG_NULL + 2, /* Start from 2. Skip DR_REG_INVALID == 1 for non-x86. */
+ DR_REG_V1,
+ DR_REG_V2,
+ DR_REG_V3,
+ DR_REG_V4,
+ DR_REG_V5,
+ DR_REG_V6,
+ DR_REG_V7,
+ DR_REG_V8,
+ DR_REG_V9,
+ DR_REG_V10,
+ DR_REG_V11,
+ DR_REG_V12,
+ DR_REG_V13,
+ DR_REG_V14,
+ DR_REG_V15,
+ DR_REG_V16,
+ DR_REG_V17,
+ DR_REG_V18,
+ DR_REG_V19,
+ DR_REG_V20,
+ DR_REG_V21,
+ DR_REG_V22,
+ DR_REG_V23,
+ DR_REG_V24,
+ DR_REG_V25,
+ DR_REG_V26,
+ DR_REG_V27,
+ DR_REG_V28,
+ DR_REG_V29,
+ DR_REG_V30,
+ DR_REG_V31,
+ DR_REG_V32,
+ DR_REG_V33,
+ DR_REG_V34,
+ DR_REG_V35,
+ DR_REG_V36,
+ DR_REG_V37,
+ DR_REG_V38,
+ DR_REG_V39,
+ DR_REG_V40,
+ DR_REG_V41,
+ DR_REG_V42,
+ DR_REG_V43,
+ DR_REG_V44,
+ DR_REG_V45,
+ DR_REG_V46,
+ DR_REG_V47,
+ DR_REG_V48,
+ DR_REG_V49,
+ DR_REG_V50,
+ DR_REG_V51,
+ DR_REG_V52,
+ DR_REG_V53,
+ DR_REG_V54,
+ DR_REG_V55,
+ DR_REG_V56,
+ DR_REG_V57,
+ DR_REG_V58,
+ DR_REG_V59,
+ DR_REG_V60,
+ DR_REG_V61,
+ DR_REG_V62,
+ DR_REG_V63,
+ DR_REG_V64,
+ DR_REG_V65,
+ DR_REG_V66,
+ DR_REG_V67,
+ DR_REG_V68,
+ DR_REG_V69,
+ DR_REG_V70,
+ DR_REG_V71,
+ DR_REG_V72,
+ DR_REG_V73,
+ DR_REG_V74,
+ DR_REG_V75,
+ DR_REG_V76,
+ DR_REG_V77,
+ DR_REG_V78,
+ DR_REG_V79,
+ DR_REG_V80,
+ DR_REG_V81,
+ DR_REG_V82,
+ DR_REG_V83,
+ DR_REG_V84,
+ DR_REG_V85,
+ DR_REG_V86,
+ DR_REG_V87,
+ DR_REG_V88,
+ DR_REG_V89,
+ DR_REG_V90,
+ DR_REG_V91,
+ DR_REG_V92,
+ DR_REG_V93,
+ DR_REG_V94,
+ DR_REG_V95,
+ DR_REG_V96,
+ DR_REG_V97,
+ DR_REG_V98,
+ DR_REG_V99,
+ DR_REG_V100,
+ DR_REG_V101,
+ DR_REG_V102,
+ DR_REG_V103,
+ DR_REG_V104,
+ DR_REG_V105,
+ DR_REG_V106,
+ DR_REG_V107,
+ DR_REG_V108,
+ DR_REG_V109,
+ DR_REG_V110,
+ DR_REG_V111,
+ DR_REG_V112,
+ DR_REG_V113,
+ DR_REG_V114,
+ DR_REG_V115,
+ DR_REG_V116,
+ DR_REG_V117,
+ DR_REG_V118,
+ DR_REG_V119,
+ DR_REG_V120,
+ DR_REG_V121,
+ DR_REG_V122,
+ DR_REG_V123,
+ DR_REG_V124,
+ DR_REG_V125,
+ DR_REG_V126,
+ DR_REG_V127,
+ DR_REG_V128,
+ DR_REG_V129,
+ DR_REG_V130,
+ DR_REG_V131,
+ DR_REG_V132,
+ DR_REG_V133,
+ DR_REG_V134,
+ DR_REG_V135,
+ DR_REG_V136,
+ DR_REG_V137,
+ DR_REG_V138,
+ DR_REG_V139,
+ DR_REG_V140,
+ DR_REG_V141,
+ DR_REG_V142,
+ DR_REG_V143,
+ DR_REG_V144,
+ DR_REG_V145,
+ DR_REG_V146,
+ DR_REG_V147,
+ DR_REG_V148,
+ DR_REG_V149,
+ DR_REG_V150,
+ DR_REG_V151,
+ DR_REG_V152,
+ DR_REG_V153,
+ DR_REG_V154,
+ DR_REG_V155,
+ DR_REG_V156,
+ DR_REG_V157,
+ DR_REG_V158,
+ DR_REG_V159,
+ DR_REG_V160,
+ DR_REG_V161,
+ DR_REG_V162,
+ DR_REG_V163,
+ DR_REG_V164,
+ DR_REG_V165,
+ DR_REG_V166,
+ DR_REG_V167,
+ DR_REG_V168,
+ DR_REG_V169,
+ DR_REG_V170,
+ DR_REG_V171,
+ DR_REG_V172,
+ DR_REG_V173,
+ DR_REG_V174,
+ DR_REG_V175,
+ DR_REG_V176,
+ DR_REG_V177,
+ DR_REG_V178,
+ DR_REG_V179,
+ DR_REG_V180,
+ DR_REG_V181,
+ DR_REG_V182,
+ DR_REG_V183,
+ DR_REG_V184,
+ DR_REG_V185 = 188, /* Skip x86 DR_REG_INVALID == 187. */
+ DR_REG_V186,
+ DR_REG_V187,
+ DR_REG_V188,
+ DR_REG_V189,
+ DR_REG_V190,
+ DR_REG_V191,
+ DR_REG_V192,
+ DR_REG_V193,
+ DR_REG_V194,
+ DR_REG_V195,
+ DR_REG_V196,
+ DR_REG_V197,
+ DR_REG_V198,
+ DR_REG_V199,
+ DR_REG_V200,
+ DR_REG_V201,
+ DR_REG_V202,
+ DR_REG_V203,
+ DR_REG_V204,
+ DR_REG_V205,
+ DR_REG_V206,
+ DR_REG_V207,
+ DR_REG_V208,
+ DR_REG_V209,
+ DR_REG_V210,
+ DR_REG_V211,
+ DR_REG_V212,
+ DR_REG_V213,
+ DR_REG_V214,
+ DR_REG_V215,
+ DR_REG_V216,
+ DR_REG_V217,
+ DR_REG_V218,
+ DR_REG_V219,
+ DR_REG_V220,
+ DR_REG_V221,
+ DR_REG_V222,
+ DR_REG_V223,
+ DR_REG_V224,
+ DR_REG_V225,
+ DR_REG_V226,
+ DR_REG_V227,
+ DR_REG_V228,
+ DR_REG_V229,
+ DR_REG_V230,
+ DR_REG_V231,
+ DR_REG_V232,
+ DR_REG_V233,
+ DR_REG_V234,
+ DR_REG_V235,
+ DR_REG_V236,
+ DR_REG_V237,
+ DR_REG_V238,
+ DR_REG_V239,
+ DR_REG_V240,
+ DR_REG_V241,
+ DR_REG_V242,
+ DR_REG_V243,
+ DR_REG_V244,
+ DR_REG_V245,
+ DR_REG_V246,
+ DR_REG_V247,
+ DR_REG_V248,
+ DR_REG_V249,
+ DR_REG_V250,
+ DR_REG_V251,
+ DR_REG_V252,
+};
+
/* we avoid typedef-ing the enum, as its storage size is compiler-specific */
typedef ushort reg_id_t; /**< The type of a DR_REG_ enum value. */
/* For x86 we do store reg_id_t here, but the x86 DR_REG_ enum is small enough
@@ -3004,6 +3269,9 @@ DR_API
/**
* Assumes that \p reg is a DR_REG_ 32-bit register constant.
* Returns the string name for \p reg.
+ * \note It uses the global dcontext_t to determine the ISA mode. If the ISA mode is a
+ * synthetic one (e.g., #DR_ISA_REGDEPS), it returns the name of a #DR_REG_V0 etc. virtual
+ * register.
*/
const char *
get_register_name(reg_id_t reg);
diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c
index 176f060ff15..b77b513dafd 100644
--- a/core/ir/opnd_shared.c
+++ b/core/ir/opnd_shared.c
@@ -38,6 +38,7 @@
/* file "opnd_shared.c" -- IR opnd utilities */
#include "../globals.h"
+#include "encode_api.h"
#include "opnd.h"
#include "arch.h"
/* FIXME i#1551: refactor this file and avoid this x86-specific include in base arch/ */
@@ -2404,9 +2405,24 @@ opnd_compute_address(opnd_t opnd, dr_mcontext_t *mc)
*** Register utility functions
***************************************************************************/
+/* XXX i#1684: performance matters on all getter and setter routines. Now that we call
+ * get_thread_private_dcontext(), we add non-negligible overhead to get_register_name().
+ * Currently there are other routines that call get_thread_private_dcontext() such as:
+ * instr_get_eflags() and opnd_create_far_abs_addr(). We should revisit this and make
+ * a decision on which of these routines should take dcontext_t as input argument.
+ */
+/* XXX i#6690: here we assume that changes made by the user of this routine
+ * (and by its threads) to the global dcontext_t (and specifically its isa_mode)
+ * are guarded by locks. We can remove this assumption once we have a completely
+ * lock-free dcontext_t.
+ */
const char *
get_register_name(reg_id_t reg)
{
+ bool is_global_isa_mode_synthetic =
+ dr_get_isa_mode(get_thread_private_dcontext()) == DR_ISA_REGDEPS;
+ if (is_global_isa_mode_synthetic)
+ return d_r_reg_virtual_names[reg];
return reg_names[reg];
}
@@ -2416,6 +2432,12 @@ reg_to_pointer_sized(reg_id_t reg)
return dr_reg_fixer[reg];
}
+reg_id_t
+d_r_reg_to_virtual(reg_id_t reg)
+{
+ return d_r_reg_id_to_virtual[reg];
+}
+
reg_id_t
reg_32_to_16(reg_id_t reg)
{
diff --git a/core/ir/riscv64/encode.c b/core/ir/riscv64/encode.c
index c63a164b99e..993695a25a1 100644
--- a/core/ir/riscv64/encode.c
+++ b/core/ir/riscv64/encode.c
@@ -70,6 +70,82 @@ const reg_id_t dr_reg_fixer[] = { REG_NULL,
};
/* clang-format on */
+/* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register.
+ * Note that we map real sub-registers to their corresponding containing virtual register.
+ * Same size as dr_reg_fixer[], keep them synched.
+ */
+const reg_id_t d_r_reg_id_to_virtual[] = {
+ DR_REG_NULL, /* DR_REG_NULL */
+ DR_REG_NULL, /* DR_REG_NULL */
+ DR_REG_V0, /* DR_REG_X0 */
+ DR_REG_V1, /* DR_REG_X1 */
+ DR_REG_V2, /* DR_REG_X2 */
+ DR_REG_V3, /* DR_REG_X3 */
+ DR_REG_V4, /* DR_REG_X4 */
+ DR_REG_V5, /* DR_REG_X5 */
+ DR_REG_V6, /* DR_REG_X6 */
+ DR_REG_V7, /* DR_REG_X7 */
+ DR_REG_V8, /* DR_REG_X8 */
+ DR_REG_V9, /* DR_REG_X9 */
+ DR_REG_V10, /* DR_REG_X10 */
+ DR_REG_V11, /* DR_REG_X11 */
+ DR_REG_V12, /* DR_REG_X12 */
+ DR_REG_V13, /* DR_REG_X13 */
+ DR_REG_V14, /* DR_REG_X14 */
+ DR_REG_V15, /* DR_REG_X15 */
+ DR_REG_V16, /* DR_REG_X16 */
+ DR_REG_V17, /* DR_REG_X17 */
+ DR_REG_V18, /* DR_REG_X18 */
+ DR_REG_V19, /* DR_REG_X19 */
+ DR_REG_V20, /* DR_REG_X20 */
+ DR_REG_V21, /* DR_REG_X21 */
+ DR_REG_V22, /* DR_REG_X22 */
+ DR_REG_V23, /* DR_REG_X23 */
+ DR_REG_V24, /* DR_REG_X24 */
+ DR_REG_V25, /* DR_REG_X25 */
+ DR_REG_V26, /* DR_REG_X26 */
+ DR_REG_V27, /* DR_REG_X27 */
+ DR_REG_V28, /* DR_REG_X28 */
+ DR_REG_V29, /* DR_REG_X29 */
+ DR_REG_V30, /* DR_REG_X30 */
+ DR_REG_V31, /* DR_REG_X31 */
+ DR_REG_V32, /* DR_REG_PC */
+
+ DR_REG_V33, /* DR_REG_F0 */
+ DR_REG_V34, /* DR_REG_F1 */
+ DR_REG_V35, /* DR_REG_F2 */
+ DR_REG_V36, /* DR_REG_F3 */
+ DR_REG_V37, /* DR_REG_F4 */
+ DR_REG_V38, /* DR_REG_F5 */
+ DR_REG_V39, /* DR_REG_F6 */
+ DR_REG_V40, /* DR_REG_F7 */
+ DR_REG_V41, /* DR_REG_F8 */
+ DR_REG_V42, /* DR_REG_F9 */
+ DR_REG_V43, /* DR_REG_F10 */
+ DR_REG_V44, /* DR_REG_F11 */
+ DR_REG_V45, /* DR_REG_F12 */
+ DR_REG_V46, /* DR_REG_F13 */
+ DR_REG_V47, /* DR_REG_F14 */
+ DR_REG_V48, /* DR_REG_F15 */
+ DR_REG_V49, /* DR_REG_F16 */
+ DR_REG_V50, /* DR_REG_F17 */
+ DR_REG_V51, /* DR_REG_F18 */
+ DR_REG_V52, /* DR_REG_F19 */
+ DR_REG_V53, /* DR_REG_F20 */
+ DR_REG_V54, /* DR_REG_F21 */
+ DR_REG_V55, /* DR_REG_F22 */
+ DR_REG_V56, /* DR_REG_F23 */
+ DR_REG_V57, /* DR_REG_F24 */
+ DR_REG_V58, /* DR_REG_F25 */
+ DR_REG_V59, /* DR_REG_F26 */
+ DR_REG_V60, /* DR_REG_F27 */
+ DR_REG_V61, /* DR_REG_F28 */
+ DR_REG_V62, /* DR_REG_F29 */
+ DR_REG_V63, /* DR_REG_F30 */
+ DR_REG_V64, /* DR_REG_F31 */
+ DR_REG_V65, /* DR_REG_FCSR */
+};
+
#ifdef DEBUG
void
encode_debug_checks(void)
diff --git a/core/ir/x86/encode.c b/core/ir/x86/encode.c
index e2f41ce1737..74698e92b2f 100644
--- a/core/ir/x86/encode.c
+++ b/core/ir/x86/encode.c
@@ -236,6 +236,349 @@ const reg_id_t dr_reg_fixer[] = {
DR_REG_BND2, DR_REG_BND3,
};
+/* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register.
+ * Note that we map real sub-registers to their corresponding containing virtual register.
+ * Same size as dr_reg_fixer[], keep them synched.
+ */
+const reg_id_t d_r_reg_id_to_virtual[] = {
+ DR_REG_NULL, /* DR_REG_NULL */
+ DR_REG_V0, /* DR_REG_RAX */
+ DR_REG_V1, /* DR_REG_RCX */
+ DR_REG_V2, /* DR_REG_RDX */
+ DR_REG_V3, /* DR_REG_RBX */
+ DR_REG_V4, /* DR_REG_RSP */
+ DR_REG_V5, /* DR_REG_RBP */
+ DR_REG_V6, /* DR_REG_RSI */
+ DR_REG_V7, /* DR_REG_RDI */
+ DR_REG_V8, /* DR_REG_R8 */
+ DR_REG_V9, /* DR_REG_R9 */
+ DR_REG_V10, /* DR_REG_R10 */
+ DR_REG_V11, /* DR_REG_R11 */
+ DR_REG_V12, /* DR_REG_R12 */
+ DR_REG_V13, /* DR_REG_R13 */
+ DR_REG_V14, /* DR_REG_R14 */
+ DR_REG_V15, /* DR_REG_R15 */
+ DR_REG_V0, /* DR_REG_EAX */
+ DR_REG_V1, /* DR_REG_ECX */
+ DR_REG_V2, /* DR_REG_EDX */
+ DR_REG_V3, /* DR_REG_EBX */
+ DR_REG_V4, /* DR_REG_ESP */
+ DR_REG_V5, /* DR_REG_EBP */
+ DR_REG_V6, /* DR_REG_ESI */
+ DR_REG_V7, /* DR_REG_EDI */
+ DR_REG_V8, /* DR_REG_R8D */
+ DR_REG_V9, /* DR_REG_R9D */
+ DR_REG_V10, /* DR_REG_R10D */
+ DR_REG_V11, /* DR_REG_R11D */
+ DR_REG_V12, /* DR_REG_R12D */
+ DR_REG_V13, /* DR_REG_R13D */
+ DR_REG_V14, /* DR_REG_R14D */
+ DR_REG_V15, /* DR_REG_R15D */
+ DR_REG_V0, /* DR_REG_AX */
+ DR_REG_V1, /* DR_REG_CX */
+ DR_REG_V2, /* DR_REG_DX */
+ DR_REG_V3, /* DR_REG_BX */
+ DR_REG_V4, /* DR_REG_SP */
+ DR_REG_V5, /* DR_REG_BP */
+ DR_REG_V6, /* DR_REG_SI */
+ DR_REG_V7, /* DR_REG_DI */
+ DR_REG_V8, /* DR_REG_R8W */
+ DR_REG_V9, /* DR_REG_R9W */
+ DR_REG_V10, /* DR_REG_R10W */
+ DR_REG_V11, /* DR_REG_R11W */
+ DR_REG_V12, /* DR_REG_R12W */
+ DR_REG_V13, /* DR_REG_R13W */
+ DR_REG_V14, /* DR_REG_R14W */
+ DR_REG_V15, /* DR_REG_R15W */
+ DR_REG_V0, /* DR_REG_AL */
+ DR_REG_V1, /* DR_REG_CL */
+ DR_REG_V2, /* DR_REG_DL */
+ DR_REG_V3, /* DR_REG_BL */
+ DR_REG_V0, /* DR_REG_AH */
+ DR_REG_V1, /* DR_REG_CH */
+ DR_REG_V2, /* DR_REG_DH */
+ DR_REG_V3, /* DR_REG_BH */
+ DR_REG_V8, /* DR_REG_R8L */
+ DR_REG_V9, /* DR_REG_R9L */
+ DR_REG_V10, /* DR_REG_R10L */
+ DR_REG_V11, /* DR_REG_R11L */
+ DR_REG_V12, /* DR_REG_R12L */
+ DR_REG_V13, /* DR_REG_R13L */
+ DR_REG_V14, /* DR_REG_R14L */
+ DR_REG_V15, /* DR_REG_R15L */
+ DR_REG_V4, /* DR_REG_SPL */
+ DR_REG_V5, /* DR_REG_BPL */
+ DR_REG_V6, /* DR_REG_SIL */
+ DR_REG_V7, /* DR_REG_DIL */
+ DR_REG_V16, /* DR_REG_MM0 */
+ DR_REG_V17, /* DR_REG_MM1 */
+ DR_REG_V18, /* DR_REG_MM2 */
+ DR_REG_V19, /* DR_REG_MM3 */
+ DR_REG_V20, /* DR_REG_MM4 */
+ DR_REG_V21, /* DR_REG_MM5 */
+ DR_REG_V22, /* DR_REG_MM6 */
+ DR_REG_V23, /* DR_REG_MM7 */
+ DR_REG_V70, /* DR_REG_XMM0 */
+ DR_REG_V71, /* DR_REG_XMM1 */
+ DR_REG_V72, /* DR_REG_XMM2 */
+ DR_REG_V73, /* DR_REG_XMM3 */
+ DR_REG_V74, /* DR_REG_XMM4 */
+ DR_REG_V75, /* DR_REG_XMM5 */
+ DR_REG_V76, /* DR_REG_XMM6 */
+ DR_REG_V77, /* DR_REG_XMM7 */
+ DR_REG_V78, /* DR_REG_XMM8 */
+ DR_REG_V79, /* DR_REG_XMM9 */
+ DR_REG_V80, /* DR_REG_XMM10 */
+ DR_REG_V81, /* DR_REG_XMM11 */
+ DR_REG_V82, /* DR_REG_XMM12 */
+ DR_REG_V83, /* DR_REG_XMM13 */
+ DR_REG_V84, /* DR_REG_XMM14 */
+ DR_REG_V85, /* DR_REG_XMM15 */
+ DR_REG_V86, /* DR_REG_XMM16 */
+ DR_REG_V87, /* DR_REG_XMM17 */
+ DR_REG_V88, /* DR_REG_XMM18 */
+ DR_REG_V89, /* DR_REG_XMM19 */
+ DR_REG_V90, /* DR_REG_XMM20 */
+ DR_REG_V91, /* DR_REG_XMM21 */
+ DR_REG_V92, /* DR_REG_XMM22 */
+ DR_REG_V93, /* DR_REG_XMM23 */
+ DR_REG_V94, /* DR_REG_XMM24 */
+ DR_REG_V95, /* DR_REG_XMM25 */
+ DR_REG_V96, /* DR_REG_XMM26 */
+ DR_REG_V97, /* DR_REG_XMM27 */
+ DR_REG_V98, /* DR_REG_XMM28 */
+ DR_REG_V99, /* DR_REG_XMM29 */
+ DR_REG_V100, /* DR_REG_XMM30 */
+ DR_REG_V101, /* DR_REG_XMM31 */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_V24, /* DR_REG_ST0 */
+ DR_REG_V25, /* DR_REG_ST1 */
+ DR_REG_V26, /* DR_REG_ST2 */
+ DR_REG_V27, /* DR_REG_ST3 */
+ DR_REG_V28, /* DR_REG_ST4 */
+ DR_REG_V29, /* DR_REG_ST5 */
+ DR_REG_V30, /* DR_REG_ST6 */
+ DR_REG_V31, /* DR_REG_ST7 */
+ DR_REG_V32, /* DR_REG_ES */
+ DR_REG_V33, /* DR_REG_CS */
+ DR_REG_V34, /* DR_REG_SS */
+ DR_REG_V35, /* DR_REG_DS */
+ DR_REG_V36, /* DR_REG_FS */
+ DR_REG_V37, /* DR_REG_GS */
+ DR_REG_V38, /* DR_REG_DR0 */
+ DR_REG_V39, /* DR_REG_DR1 */
+ DR_REG_V40, /* DR_REG_DR2 */
+ DR_REG_V41, /* DR_REG_DR3 */
+ DR_REG_V42, /* DR_REG_DR4 */
+ DR_REG_V43, /* DR_REG_DR5 */
+ DR_REG_V44, /* DR_REG_DR6 */
+ DR_REG_V45, /* DR_REG_DR7 */
+ DR_REG_V46, /* DR_REG_DR8 */
+ DR_REG_V47, /* DR_REG_DR9 */
+ DR_REG_V48, /* DR_REG_DR10 */
+ DR_REG_V49, /* DR_REG_DR11 */
+ DR_REG_V50, /* DR_REG_DR12 */
+ DR_REG_V51, /* DR_REG_DR13 */
+ DR_REG_V52, /* DR_REG_DR14 */
+ DR_REG_V53, /* DR_REG_DR15 */
+ DR_REG_V54, /* DR_REG_CR0 */
+ DR_REG_V55, /* DR_REG_CR1 */
+ DR_REG_V56, /* DR_REG_CR2 */
+ DR_REG_V57, /* DR_REG_CR3 */
+ DR_REG_V58, /* DR_REG_CR4 */
+ DR_REG_V59, /* DR_REG_CR5 */
+ DR_REG_V60, /* DR_REG_CR6 */
+ DR_REG_V61, /* DR_REG_CR7 */
+ DR_REG_V62, /* DR_REG_CR8 */
+ DR_REG_V63, /* DR_REG_CR9 */
+ DR_REG_V64, /* DR_REG_CR10 */
+ DR_REG_V65, /* DR_REG_CR11 */
+ DR_REG_V66, /* DR_REG_CR12 */
+ DR_REG_V67, /* DR_REG_CR13 */
+ DR_REG_V68, /* DR_REG_CR14 */
+ DR_REG_V69, /* DR_REG_CR15 */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_V70, /* DR_REG_YMM0 */
+ DR_REG_V71, /* DR_REG_YMM1 */
+ DR_REG_V72, /* DR_REG_YMM2 */
+ DR_REG_V73, /* DR_REG_YMM3 */
+ DR_REG_V74, /* DR_REG_YMM4 */
+ DR_REG_V75, /* DR_REG_YMM5 */
+ DR_REG_V76, /* DR_REG_YMM6 */
+ DR_REG_V77, /* DR_REG_YMM7 */
+ DR_REG_V78, /* DR_REG_YMM8 */
+ DR_REG_V79, /* DR_REG_YMM9 */
+ DR_REG_V80, /* DR_REG_YMM10 */
+ DR_REG_V81, /* DR_REG_YMM11 */
+ DR_REG_V82, /* DR_REG_YMM12 */
+ DR_REG_V83, /* DR_REG_YMM13 */
+ DR_REG_V84, /* DR_REG_YMM14 */
+ DR_REG_V85, /* DR_REG_YMM15 */
+ DR_REG_V86, /* DR_REG_YMM16 */
+ DR_REG_V87, /* DR_REG_YMM17 */
+ DR_REG_V88, /* DR_REG_YMM18 */
+ DR_REG_V89, /* DR_REG_YMM19 */
+ DR_REG_V90, /* DR_REG_YMM20 */
+ DR_REG_V91, /* DR_REG_YMM21 */
+ DR_REG_V92, /* DR_REG_YMM22 */
+ DR_REG_V93, /* DR_REG_YMM23 */
+ DR_REG_V94, /* DR_REG_YMM24 */
+ DR_REG_V95, /* DR_REG_YMM25 */
+ DR_REG_V96, /* DR_REG_YMM26 */
+ DR_REG_V97, /* DR_REG_YMM27 */
+ DR_REG_V98, /* DR_REG_YMM28 */
+ DR_REG_V99, /* DR_REG_YMM29 */
+ DR_REG_V100, /* DR_REG_YMM30 */
+ DR_REG_V101, /* DR_REG_YMM31 */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_V70, /* DR_REG_ZMM0 */
+ DR_REG_V71, /* DR_REG_ZMM1 */
+ DR_REG_V72, /* DR_REG_ZMM2 */
+ DR_REG_V73, /* DR_REG_ZMM3 */
+ DR_REG_V74, /* DR_REG_ZMM4 */
+ DR_REG_V75, /* DR_REG_ZMM5 */
+ DR_REG_V76, /* DR_REG_ZMM6 */
+ DR_REG_V77, /* DR_REG_ZMM7 */
+ DR_REG_V78, /* DR_REG_ZMM8 */
+ DR_REG_V79, /* DR_REG_ZMM9 */
+ DR_REG_V80, /* DR_REG_ZMM10 */
+ DR_REG_V81, /* DR_REG_ZMM11 */
+ DR_REG_V82, /* DR_REG_ZMM12 */
+ DR_REG_V83, /* DR_REG_ZMM13 */
+ DR_REG_V84, /* DR_REG_ZMM14 */
+ DR_REG_V85, /* DR_REG_ZMM15 */
+ DR_REG_V86, /* DR_REG_ZMM16 */
+ DR_REG_V87, /* DR_REG_ZMM17 */
+ DR_REG_V88, /* DR_REG_ZMM18 */
+ DR_REG_V89, /* DR_REG_ZMM19 */
+ DR_REG_V90, /* DR_REG_ZMM20 */
+ DR_REG_V91, /* DR_REG_ZMM21 */
+ DR_REG_V92, /* DR_REG_ZMM22 */
+ DR_REG_V93, /* DR_REG_ZMM23 */
+ DR_REG_V94, /* DR_REG_ZMM24 */
+ DR_REG_V95, /* DR_REG_ZMM25 */
+ DR_REG_V96, /* DR_REG_ZMM26 */
+ DR_REG_V97, /* DR_REG_ZMM27 */
+ DR_REG_V98, /* DR_REG_ZMM28 */
+ DR_REG_V99, /* DR_REG_ZMM29 */
+ DR_REG_V100, /* DR_REG_ZMM30 */
+ DR_REG_V101, /* DR_REG_ZMM31 */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_V102, /* DR_REG_K0 */
+ DR_REG_V103, /* DR_REG_K1 */
+ DR_REG_V104, /* DR_REG_K2 */
+ DR_REG_V105, /* DR_REG_K3 */
+ DR_REG_V106, /* DR_REG_K4 */
+ DR_REG_V107, /* DR_REG_K5 */
+ DR_REG_V108, /* DR_REG_K6 */
+ DR_REG_V109, /* DR_REG_K7 */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_INVALID, /* DR_REG_INVALID */
+ DR_REG_V110, /* DR_REG_BND0 */
+ DR_REG_V111, /* DR_REG_BND1 */
+ DR_REG_V112, /* DR_REG_BND2 */
+ DR_REG_V113, /* DR_REG_BND3 */
+};
+
#ifdef DEBUG
void
encode_debug_checks(void)
diff --git a/suite/tests/api/ir_regdeps.c b/suite/tests/api/ir_regdeps.c
index b8e08b8221d..5c2f0a30bfb 100644
--- a/suite/tests/api/ir_regdeps.c
+++ b/suite/tests/api/ir_regdeps.c
@@ -192,6 +192,24 @@ test_instr_create_encode_decode_synthetic_x86_64(void *dc)
instr_reset(dc, instr);
decode(dc, buf, instr);
test_instr_encode_decode_synthetic(dc, instr);
+
+ /* Containing-register IDs can be >=256, hence their value does not fit in the
+ * allotted 8 bits per register operand of regdeps encoding. This was causing a
+ * memory corruption in instr_convert_to_isa_regdeps() where src_reg_used and
+ * dst_reg_used have only 256 elements and are laid out next to each other in memory.
+ * Writing to index >=256 into one was overwriting the other. Fix: remap containing
+ * register IDs starting from 0 for all architectures, since we still have only up to
+ * 198 unique containing registers (max number of containing registers for AARCH64).
+ * DR_REG_K0 and the DR_REG_ZMM_ registers are some of these "problematic" registers
+ * with enum value >=256. We use them here to test our fix.
+ */
+ instr = INSTR_CREATE_vdpbf16ps_mask(
+ dc, opnd_create_reg(DR_REG_ZMM30), opnd_create_reg(DR_REG_K0),
+ opnd_create_reg(DR_REG_ZMM29), opnd_create_reg(DR_REG_ZMM28));
+ instr_encode(dc, instr, buf);
+ instr_reset(dc, instr);
+ decode(dc, buf, instr);
+ test_instr_encode_decode_synthetic(dc, instr);
}
#endif
@@ -328,6 +346,307 @@ test_instr_create_encode_decode_synthetic_riscv64(void *dc)
}
#endif
+void
+test_virtual_register_names(void *dc)
+{
+ dr_isa_mode_t old_isa_mode;
+ /* DR uses the dcontext_t ISA mode to decide whether a register is virtual or real and
+ * to return its correct name. Since we are testing virtual register names, we set it
+ * to DR_ISA_REGDEPS.
+ */
+ dr_set_isa_mode(dc, DR_ISA_REGDEPS, &old_isa_mode);
+
+ const char rv0[] = "rv0";
+ ASSERT(strncmp(get_register_name(DR_REG_V0), rv0, sizeof(rv0)) == 0);
+
+ const char rv1[] = "rv1";
+ ASSERT(strncmp(get_register_name(DR_REG_V1), rv1, sizeof(rv1)) == 0);
+
+ const char rv187[] = "rv187";
+ ASSERT(strncmp(get_register_name(DR_REG_V187), rv187, sizeof(rv187)) == 0);
+
+ const char rv252[] = "rv252";
+ ASSERT(strncmp(get_register_name(DR_REG_V252), rv252, sizeof(rv252)) == 0);
+
+ /* Restore previous ISA mode.
+ */
+ dr_set_isa_mode(dc, old_isa_mode, NULL);
+}
+
+/* We can't compare DR_REG_V and DR_REG_ enum values directly because they belong to
+ * different enums and we build with -Werror=enum-compare. So we use scopes and the
+ * temporary variable reg_virtual.
+ */
+#define ASSERT_NOT_NULL_OR_INVALID(x) \
+ do { \
+ reg_id_t reg_virtual = x; \
+ ASSERT((reg_virtual != DR_REG_NULL) && (reg_virtual != DR_REG_INVALID)); \
+ } while (0);
+
+/* We can't loop through DR_REG_V enums because we have a gap for value 187
+ * (== DR_REG_INVALID for x86), so we unroll the loop and compare every enum manually.
+ */
+#define CHECK_VIRTUAL_REGISTER_IDS \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V0) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V1) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V2) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V3) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V4) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V5) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V6) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V7) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V8) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V9) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V10) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V11) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V12) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V13) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V14) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V15) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V16) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V17) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V18) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V19) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V20) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V21) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V22) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V23) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V24) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V25) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V26) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V27) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V28) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V29) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V30) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V31) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V32) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V33) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V34) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V35) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V36) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V37) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V38) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V39) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V40) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V41) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V42) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V43) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V44) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V45) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V46) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V47) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V48) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V49) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V50) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V51) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V52) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V53) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V54) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V55) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V56) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V57) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V58) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V59) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V60) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V61) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V62) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V63) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V64) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V65) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V66) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V67) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V68) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V69) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V70) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V71) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V72) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V73) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V74) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V75) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V76) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V77) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V78) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V79) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V80) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V81) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V82) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V83) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V84) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V85) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V86) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V87) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V88) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V89) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V90) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V91) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V92) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V93) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V94) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V95) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V96) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V97) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V98) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V99) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V100) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V101) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V102) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V103) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V104) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V105) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V106) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V107) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V108) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V109) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V110) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V111) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V112) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V113) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V114) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V115) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V116) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V117) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V118) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V119) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V120) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V121) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V122) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V123) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V124) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V125) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V126) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V127) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V128) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V129) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V130) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V131) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V132) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V133) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V134) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V135) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V136) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V137) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V138) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V139) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V140) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V141) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V142) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V143) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V144) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V145) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V146) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V147) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V148) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V149) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V150) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V151) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V152) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V153) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V154) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V155) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V156) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V157) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V158) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V159) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V160) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V161) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V162) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V163) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V164) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V165) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V166) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V167) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V168) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V169) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V170) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V171) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V172) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V173) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V174) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V175) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V176) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V177) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V178) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V179) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V180) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V181) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V182) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V183) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V184) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V185) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V186) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V187) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V188) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V189) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V190) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V191) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V192) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V193) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V194) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V195) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V196) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V197) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V198) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V199) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V200) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V201) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V202) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V203) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V204) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V205) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V206) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V207) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V208) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V209) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V210) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V211) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V212) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V213) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V214) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V215) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V216) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V217) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V218) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V219) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V220) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V221) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V222) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V223) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V224) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V225) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V226) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V227) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V228) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V229) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V230) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V231) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V232) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V233) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V234) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V235) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V236) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V237) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V238) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V239) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V240) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V241) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V242) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V243) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V244) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V245) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V246) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V247) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V248) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V249) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V250) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V251) \
+ ASSERT_NOT_NULL_OR_INVALID(DR_REG_V252)
+
+void
+check_virtual_register_enum_values(void)
+{
+ CHECK_VIRTUAL_REGISTER_IDS;
+}
+
int
main(int argc, char *argv[])
{
@@ -350,6 +669,10 @@ main(int argc, char *argv[])
test_instr_create_encode_decode_synthetic_riscv64(dcontext);
#endif
+ test_virtual_register_names(dcontext);
+
+ check_virtual_register_enum_values();
+
print("All DR_ISA_REGDEPS tests are done.\n");
dr_standalone_exit();
return 0;