From 3adb13e6ce14d6f7fcc30d710b29fa6e83343a54 Mon Sep 17 00:00:00 2001 From: billow Date: Mon, 4 Nov 2024 06:48:40 +0800 Subject: [PATCH] xtensa: fix details --- arch/Xtensa/XtensaInstPrinter.c | 1 + suite/cstest/include/test_detail.h | 5 + suite/cstest/include/test_detail_xtensa.h | 68 +++++++ suite/cstest/include/test_mapping.h | 220 +++++++++++++++------- suite/cstest/src/test_detail.c | 7 + suite/cstest/src/test_detail_xtensa.c | 107 +++++++++++ tests/details/xtensa.yaml | 15 ++ 7 files changed, 351 insertions(+), 72 deletions(-) create mode 100644 suite/cstest/include/test_detail_xtensa.h create mode 100644 suite/cstest/src/test_detail_xtensa.c create mode 100644 tests/details/xtensa.yaml diff --git a/arch/Xtensa/XtensaInstPrinter.c b/arch/Xtensa/XtensaInstPrinter.c index 10581ea5cb..ade29cfad4 100644 --- a/arch/Xtensa/XtensaInstPrinter.c +++ b/arch/Xtensa/XtensaInstPrinter.c @@ -55,6 +55,7 @@ static void printRegName(SStream *O, MCRegister Reg) static void printOperand(MCInst *MI, const int op_num, SStream *O) { + Xtensa_add_cs_detail_0(MI, Xtensa_OP_GROUP_Operand, op_num); MCOperand *MC = MCInst_getOperand(MI, (op_num)); if (MCOperand_isReg(MC)) SStream_concat0(O, getRegisterName(MCOperand_getReg(MC))); diff --git a/suite/cstest/include/test_detail.h b/suite/cstest/include/test_detail.h index fe682f0891..0d82cd51df 100644 --- a/suite/cstest/include/test_detail.h +++ b/suite/cstest/include/test_detail.h @@ -31,6 +31,7 @@ #include "test_detail_wasm.h" #include "test_detail_x86.h" #include "test_detail_m68k.h" +#include "test_detail_xtensa.h" #include "test_compare.h" #include #include @@ -59,6 +60,7 @@ typedef struct { TestDetailWASM *wasm; TestDetailX86 *x86; TestDetailM68K *m68k; + TestDetailXtensa *xtensa; char **regs_read; uint8_t regs_read_count; @@ -145,6 +147,9 @@ static const cyaml_schema_field_t test_detail_mapping_schema[] = { CYAML_FIELD_MAPPING_PTR( "m68k", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail, m68k, test_detail_m68k_mapping_schema), + CYAML_FIELD_MAPPING_PTR( + "xtensa", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail, + xtensa, test_detail_xtensa_mapping_schema), CYAML_FIELD_SEQUENCE("regs_read", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail, regs_read, &single_string_schema, 0, 255), diff --git a/suite/cstest/include/test_detail_xtensa.h b/suite/cstest/include/test_detail_xtensa.h new file mode 100644 index 0000000000..db7920ff22 --- /dev/null +++ b/suite/cstest/include/test_detail_xtensa.h @@ -0,0 +1,68 @@ +// Copyright © 2024 Rot127 +// SPDX-License-Identifier: BSD-3 + +#ifndef TEST_DETAIL_XTENSA_H +#define TEST_DETAIL_XTENSA_H + +#include "test_compare.h" +#include +#include + +typedef struct { + char *type; + char *access; + + char *reg; + int32_t imm; + char *mem_base; + uint8_t mem_disp; +} TestDetailXtensaOp; + +static const cyaml_schema_field_t test_detail_xtensa_op_mapping_schema[] = { + CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, + TestDetailXtensaOp, type, 0, CYAML_UNLIMITED), + CYAML_FIELD_STRING_PTR("access", + CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, + TestDetailXtensaOp, access, 0, CYAML_UNLIMITED), + CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, + TestDetailXtensaOp, reg, 0, CYAML_UNLIMITED), + CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailXtensaOp, imm), + CYAML_FIELD_STRING_PTR( + "mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, + TestDetailXtensaOp, mem_base, 0, CYAML_UNLIMITED), + CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailXtensaOp, + mem_disp), + CYAML_FIELD_END +}; + +static const cyaml_schema_value_t test_detail_xtensa_op_schema = { + CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailXtensaOp, + test_detail_xtensa_op_mapping_schema), +}; + +typedef struct { + TestDetailXtensaOp **operands; + uint32_t operands_count; +} TestDetailXtensa; + +static const cyaml_schema_field_t test_detail_xtensa_mapping_schema[] = { + CYAML_FIELD_SEQUENCE( + "operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, + TestDetailXtensa, operands, &test_detail_xtensa_op_schema, 0, + CYAML_UNLIMITED), // 0-MAX options + CYAML_FIELD_END +}; + +TestDetailXtensa *test_detail_xtensa_new(); +TestDetailXtensa *test_detail_xtensa_clone(const TestDetailXtensa *detail); +void test_detail_xtensa_free(TestDetailXtensa *detail); + +TestDetailXtensaOp *test_detail_xtensa_op_new(); +TestDetailXtensaOp * +test_detail_xtensa_op_clone(const TestDetailXtensaOp *detail); +void test_detail_xtensa_op_free(TestDetailXtensaOp *detail); + +bool test_expected_xtensa(csh *handle, const cs_xtensa *actual, + const TestDetailXtensa *expected); + +#endif // TEST_DETAIL_XTENSA_H diff --git a/suite/cstest/include/test_mapping.h b/suite/cstest/include/test_mapping.h index 9638e08d7c..994c5b20b5 100644 --- a/suite/cstest/include/test_mapping.h +++ b/suite/cstest/include/test_mapping.h @@ -1191,81 +1191,153 @@ static const cs_enum_id_map cs_enum_map[] = { { .str = "SYSTEMZ_INSN_FORM_INSTE", .val = SYSTEMZ_INSN_FORM_INSTE }, { .str = "SYSTEMZ_INSN_FORM_INSTI", .val = SYSTEMZ_INSN_FORM_INSTI }, { .str = "SYSTEMZ_INSN_FORM_INSTIE", .val = SYSTEMZ_INSN_FORM_INSTIE }, - { .str = "SYSTEMZ_INSN_FORM_INSTMII", .val = SYSTEMZ_INSN_FORM_INSTMII }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIA", .val = SYSTEMZ_INSN_FORM_INSTRIA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIB", .val = SYSTEMZ_INSN_FORM_INSTRIB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIC", .val = SYSTEMZ_INSN_FORM_INSTRIC }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEA", .val = SYSTEMZ_INSN_FORM_INSTRIEA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEB", .val = SYSTEMZ_INSN_FORM_INSTRIEB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEC", .val = SYSTEMZ_INSN_FORM_INSTRIEC }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIED", .val = SYSTEMZ_INSN_FORM_INSTRIED }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEE", .val = SYSTEMZ_INSN_FORM_INSTRIEE }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEF", .val = SYSTEMZ_INSN_FORM_INSTRIEF }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIEG", .val = SYSTEMZ_INSN_FORM_INSTRIEG }, - { .str = "SYSTEMZ_INSN_FORM_INSTRILA", .val = SYSTEMZ_INSN_FORM_INSTRILA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRILB", .val = SYSTEMZ_INSN_FORM_INSTRILB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRILC", .val = SYSTEMZ_INSN_FORM_INSTRILC }, - { .str = "SYSTEMZ_INSN_FORM_INSTRIS", .val = SYSTEMZ_INSN_FORM_INSTRIS }, + { .str = "SYSTEMZ_INSN_FORM_INSTMII", + .val = SYSTEMZ_INSN_FORM_INSTMII }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIA", + .val = SYSTEMZ_INSN_FORM_INSTRIA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIB", + .val = SYSTEMZ_INSN_FORM_INSTRIB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIC", + .val = SYSTEMZ_INSN_FORM_INSTRIC }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEA", + .val = SYSTEMZ_INSN_FORM_INSTRIEA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEB", + .val = SYSTEMZ_INSN_FORM_INSTRIEB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEC", + .val = SYSTEMZ_INSN_FORM_INSTRIEC }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIED", + .val = SYSTEMZ_INSN_FORM_INSTRIED }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEE", + .val = SYSTEMZ_INSN_FORM_INSTRIEE }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEF", + .val = SYSTEMZ_INSN_FORM_INSTRIEF }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIEG", + .val = SYSTEMZ_INSN_FORM_INSTRIEG }, + { .str = "SYSTEMZ_INSN_FORM_INSTRILA", + .val = SYSTEMZ_INSN_FORM_INSTRILA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRILB", + .val = SYSTEMZ_INSN_FORM_INSTRILB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRILC", + .val = SYSTEMZ_INSN_FORM_INSTRILC }, + { .str = "SYSTEMZ_INSN_FORM_INSTRIS", + .val = SYSTEMZ_INSN_FORM_INSTRIS }, { .str = "SYSTEMZ_INSN_FORM_INSTRR", .val = SYSTEMZ_INSN_FORM_INSTRR }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRD", .val = SYSTEMZ_INSN_FORM_INSTRRD }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRE", .val = SYSTEMZ_INSN_FORM_INSTRRE }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRFA", .val = SYSTEMZ_INSN_FORM_INSTRRFA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRFB", .val = SYSTEMZ_INSN_FORM_INSTRRFB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRFC", .val = SYSTEMZ_INSN_FORM_INSTRRFC }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRFD", .val = SYSTEMZ_INSN_FORM_INSTRRFD }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRFE", .val = SYSTEMZ_INSN_FORM_INSTRRFE }, - { .str = "SYSTEMZ_INSN_FORM_INSTRRS", .val = SYSTEMZ_INSN_FORM_INSTRRS }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSA", .val = SYSTEMZ_INSN_FORM_INSTRSA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSB", .val = SYSTEMZ_INSN_FORM_INSTRSB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSI", .val = SYSTEMZ_INSN_FORM_INSTRSI }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSLA", .val = SYSTEMZ_INSN_FORM_INSTRSLA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSLB", .val = SYSTEMZ_INSN_FORM_INSTRSLB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSYA", .val = SYSTEMZ_INSN_FORM_INSTRSYA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRSYB", .val = SYSTEMZ_INSN_FORM_INSTRSYB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXA", .val = SYSTEMZ_INSN_FORM_INSTRXA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXB", .val = SYSTEMZ_INSN_FORM_INSTRXB }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXE", .val = SYSTEMZ_INSN_FORM_INSTRXE }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXF", .val = SYSTEMZ_INSN_FORM_INSTRXF }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXYA", .val = SYSTEMZ_INSN_FORM_INSTRXYA }, - { .str = "SYSTEMZ_INSN_FORM_INSTRXYB", .val = SYSTEMZ_INSN_FORM_INSTRXYB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRD", + .val = SYSTEMZ_INSN_FORM_INSTRRD }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRE", + .val = SYSTEMZ_INSN_FORM_INSTRRE }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRFA", + .val = SYSTEMZ_INSN_FORM_INSTRRFA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRFB", + .val = SYSTEMZ_INSN_FORM_INSTRRFB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRFC", + .val = SYSTEMZ_INSN_FORM_INSTRRFC }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRFD", + .val = SYSTEMZ_INSN_FORM_INSTRRFD }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRFE", + .val = SYSTEMZ_INSN_FORM_INSTRRFE }, + { .str = "SYSTEMZ_INSN_FORM_INSTRRS", + .val = SYSTEMZ_INSN_FORM_INSTRRS }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSA", + .val = SYSTEMZ_INSN_FORM_INSTRSA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSB", + .val = SYSTEMZ_INSN_FORM_INSTRSB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSI", + .val = SYSTEMZ_INSN_FORM_INSTRSI }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSLA", + .val = SYSTEMZ_INSN_FORM_INSTRSLA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSLB", + .val = SYSTEMZ_INSN_FORM_INSTRSLB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSYA", + .val = SYSTEMZ_INSN_FORM_INSTRSYA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRSYB", + .val = SYSTEMZ_INSN_FORM_INSTRSYB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXA", + .val = SYSTEMZ_INSN_FORM_INSTRXA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXB", + .val = SYSTEMZ_INSN_FORM_INSTRXB }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXE", + .val = SYSTEMZ_INSN_FORM_INSTRXE }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXF", + .val = SYSTEMZ_INSN_FORM_INSTRXF }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXYA", + .val = SYSTEMZ_INSN_FORM_INSTRXYA }, + { .str = "SYSTEMZ_INSN_FORM_INSTRXYB", + .val = SYSTEMZ_INSN_FORM_INSTRXYB }, { .str = "SYSTEMZ_INSN_FORM_INSTS", .val = SYSTEMZ_INSN_FORM_INSTS }, { .str = "SYSTEMZ_INSN_FORM_INSTSI", .val = SYSTEMZ_INSN_FORM_INSTSI }, - { .str = "SYSTEMZ_INSN_FORM_INSTSIL", .val = SYSTEMZ_INSN_FORM_INSTSIL }, - { .str = "SYSTEMZ_INSN_FORM_INSTSIY", .val = SYSTEMZ_INSN_FORM_INSTSIY }, - { .str = "SYSTEMZ_INSN_FORM_INSTSMI", .val = SYSTEMZ_INSN_FORM_INSTSMI }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSA", .val = SYSTEMZ_INSN_FORM_INSTSSA }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSB", .val = SYSTEMZ_INSN_FORM_INSTSSB }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSC", .val = SYSTEMZ_INSN_FORM_INSTSSC }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSD", .val = SYSTEMZ_INSN_FORM_INSTSSD }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSE", .val = SYSTEMZ_INSN_FORM_INSTSSE }, - { .str = "SYSTEMZ_INSN_FORM_INSTSSF", .val = SYSTEMZ_INSN_FORM_INSTSSF }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIA", .val = SYSTEMZ_INSN_FORM_INSTVRIA }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIB", .val = SYSTEMZ_INSN_FORM_INSTVRIB }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIC", .val = SYSTEMZ_INSN_FORM_INSTVRIC }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRID", .val = SYSTEMZ_INSN_FORM_INSTVRID }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIE", .val = SYSTEMZ_INSN_FORM_INSTVRIE }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIF", .val = SYSTEMZ_INSN_FORM_INSTVRIF }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIG", .val = SYSTEMZ_INSN_FORM_INSTVRIG }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRIH", .val = SYSTEMZ_INSN_FORM_INSTVRIH }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRII", .val = SYSTEMZ_INSN_FORM_INSTVRII }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRA", .val = SYSTEMZ_INSN_FORM_INSTVRRA }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRB", .val = SYSTEMZ_INSN_FORM_INSTVRRB }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRC", .val = SYSTEMZ_INSN_FORM_INSTVRRC }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRD", .val = SYSTEMZ_INSN_FORM_INSTVRRD }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRE", .val = SYSTEMZ_INSN_FORM_INSTVRRE }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRF", .val = SYSTEMZ_INSN_FORM_INSTVRRF }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRG", .val = SYSTEMZ_INSN_FORM_INSTVRRG }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRH", .val = SYSTEMZ_INSN_FORM_INSTVRRH }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRI", .val = SYSTEMZ_INSN_FORM_INSTVRRI }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRJ", .val = SYSTEMZ_INSN_FORM_INSTVRRJ }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRRK", .val = SYSTEMZ_INSN_FORM_INSTVRRK }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRSA", .val = SYSTEMZ_INSN_FORM_INSTVRSA }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRSB", .val = SYSTEMZ_INSN_FORM_INSTVRSB }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRSC", .val = SYSTEMZ_INSN_FORM_INSTVRSC }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRSD", .val = SYSTEMZ_INSN_FORM_INSTVRSD }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRV", .val = SYSTEMZ_INSN_FORM_INSTVRV }, - { .str = "SYSTEMZ_INSN_FORM_INSTVRX", .val = SYSTEMZ_INSN_FORM_INSTVRX }, - { .str = "SYSTEMZ_INSN_FORM_INSTVSI", .val = SYSTEMZ_INSN_FORM_INSTVSI }, + { .str = "SYSTEMZ_INSN_FORM_INSTSIL", + .val = SYSTEMZ_INSN_FORM_INSTSIL }, + { .str = "SYSTEMZ_INSN_FORM_INSTSIY", + .val = SYSTEMZ_INSN_FORM_INSTSIY }, + { .str = "SYSTEMZ_INSN_FORM_INSTSMI", + .val = SYSTEMZ_INSN_FORM_INSTSMI }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSA", + .val = SYSTEMZ_INSN_FORM_INSTSSA }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSB", + .val = SYSTEMZ_INSN_FORM_INSTSSB }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSC", + .val = SYSTEMZ_INSN_FORM_INSTSSC }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSD", + .val = SYSTEMZ_INSN_FORM_INSTSSD }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSE", + .val = SYSTEMZ_INSN_FORM_INSTSSE }, + { .str = "SYSTEMZ_INSN_FORM_INSTSSF", + .val = SYSTEMZ_INSN_FORM_INSTSSF }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIA", + .val = SYSTEMZ_INSN_FORM_INSTVRIA }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIB", + .val = SYSTEMZ_INSN_FORM_INSTVRIB }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIC", + .val = SYSTEMZ_INSN_FORM_INSTVRIC }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRID", + .val = SYSTEMZ_INSN_FORM_INSTVRID }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIE", + .val = SYSTEMZ_INSN_FORM_INSTVRIE }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIF", + .val = SYSTEMZ_INSN_FORM_INSTVRIF }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIG", + .val = SYSTEMZ_INSN_FORM_INSTVRIG }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRIH", + .val = SYSTEMZ_INSN_FORM_INSTVRIH }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRII", + .val = SYSTEMZ_INSN_FORM_INSTVRII }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRA", + .val = SYSTEMZ_INSN_FORM_INSTVRRA }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRB", + .val = SYSTEMZ_INSN_FORM_INSTVRRB }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRC", + .val = SYSTEMZ_INSN_FORM_INSTVRRC }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRD", + .val = SYSTEMZ_INSN_FORM_INSTVRRD }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRE", + .val = SYSTEMZ_INSN_FORM_INSTVRRE }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRF", + .val = SYSTEMZ_INSN_FORM_INSTVRRF }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRG", + .val = SYSTEMZ_INSN_FORM_INSTVRRG }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRH", + .val = SYSTEMZ_INSN_FORM_INSTVRRH }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRI", + .val = SYSTEMZ_INSN_FORM_INSTVRRI }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRJ", + .val = SYSTEMZ_INSN_FORM_INSTVRRJ }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRRK", + .val = SYSTEMZ_INSN_FORM_INSTVRRK }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRSA", + .val = SYSTEMZ_INSN_FORM_INSTVRSA }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRSB", + .val = SYSTEMZ_INSN_FORM_INSTVRSB }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRSC", + .val = SYSTEMZ_INSN_FORM_INSTVRSC }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRSD", + .val = SYSTEMZ_INSN_FORM_INSTVRSD }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRV", + .val = SYSTEMZ_INSN_FORM_INSTVRV }, + { .str = "SYSTEMZ_INSN_FORM_INSTVRX", + .val = SYSTEMZ_INSN_FORM_INSTVRX }, + { .str = "SYSTEMZ_INSN_FORM_INSTVSI", + .val = SYSTEMZ_INSN_FORM_INSTVSI }, { .str = "SYSTEMZ_OP_IMM", .val = SYSTEMZ_OP_IMM }, { .str = "SYSTEMZ_OP_MEM", .val = SYSTEMZ_OP_MEM }, { .str = "SYSTEMZ_OP_REG", .val = SYSTEMZ_OP_REG }, @@ -1467,6 +1539,10 @@ static const cs_enum_id_map cs_enum_map[] = { { .str = "XCORE_OP_IMM", .val = XCORE_OP_IMM }, { .str = "XCORE_OP_MEM", .val = XCORE_OP_MEM }, { .str = "XCORE_OP_REG", .val = XCORE_OP_REG }, + { .str = "XTENSA_OP_IMM", .val = XTENSA_OP_IMM }, + { .str = "XTENSA_OP_L32R", .val = XTENSA_OP_L32R }, + { .str = "XTENSA_OP_MEM", .val = XTENSA_OP_MEM }, + { .str = "XTENSA_OP_REG", .val = XTENSA_OP_REG }, { .str = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzx", .val = 0xffffff }, // For testing { .str = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", diff --git a/suite/cstest/src/test_detail.c b/suite/cstest/src/test_detail.c index f63c38c904..ac304626b0 100644 --- a/suite/cstest/src/test_detail.c +++ b/suite/cstest/src/test_detail.c @@ -127,6 +127,9 @@ TestDetail *test_detail_clone(TestDetail *detail) if (detail->m68k) { clone->m68k = test_detail_m68k_clone(detail->m68k); } + if (detail->xtensa) { + clone->xtensa = test_detail_xtensa_clone(detail->xtensa); + } return clone; } @@ -404,5 +407,9 @@ bool test_expected_detail(csh *handle, const cs_insn *insn, return test_expected_m68k(handle, &actual->m68k, expected->m68k); } + if (expected->xtensa) { + return test_expected_xtensa(handle, &actual->xtensa, + expected->xtensa); + } return true; } diff --git a/suite/cstest/src/test_detail_xtensa.c b/suite/cstest/src/test_detail_xtensa.c new file mode 100644 index 0000000000..030214af2c --- /dev/null +++ b/suite/cstest/src/test_detail_xtensa.c @@ -0,0 +1,107 @@ +// Copyright © 2024 Rot127 +// SPDX-License-Identifier: BSD-3 + +#include "test_compare.h" +#include +#include +#include +#include + +TestDetailXtensa *test_detail_xtensa_new() +{ + return cs_mem_calloc(sizeof(TestDetailXtensa), 1); +} + +void test_detail_xtensa_free(TestDetailXtensa *detail) +{ + if (!detail) { + return; + } + for (size_t i = 0; i < detail->operands_count; ++i) { + test_detail_xtensa_op_free(detail->operands[i]); + } + cs_mem_free(detail->operands); + cs_mem_free(detail); +} + +TestDetailXtensa *test_detail_xtensa_clone(const TestDetailXtensa *detail) +{ + TestDetailXtensa *clone = test_detail_xtensa_new(); + clone->operands_count = detail->operands_count; + if (detail->operands_count > 0) { + clone->operands = cs_mem_calloc(sizeof(TestDetailXtensaOp *), + detail->operands_count); + } + for (size_t i = 0; i < detail->operands_count; ++i) { + clone->operands[i] = + test_detail_xtensa_op_clone(detail->operands[i]); + } + + return clone; +} + +TestDetailXtensaOp *test_detail_xtensa_op_new() +{ + return cs_mem_calloc(sizeof(TestDetailXtensaOp), 1); +} + +TestDetailXtensaOp *test_detail_xtensa_op_clone(const TestDetailXtensaOp *op) +{ + TestDetailXtensaOp *clone = test_detail_xtensa_op_new(); + + clone->type = op->type ? strdup(op->type) : NULL; + clone->access = op->access ? strdup(op->access) : NULL; + clone->reg = op->reg ? strdup(op->reg) : NULL; + clone->imm = op->imm; + clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL; + clone->mem_disp = op->mem_disp; + + return clone; +} + +void test_detail_xtensa_op_free(TestDetailXtensaOp *op) +{ + if (!op) { + return; + } + cs_mem_free(op->type); + cs_mem_free(op->access); + cs_mem_free(op->reg); + cs_mem_free(op->mem_base); + cs_mem_free(op); +} + +bool test_expected_xtensa(csh *handle, const cs_xtensa *actual, + const TestDetailXtensa *expected) +{ + assert(handle && actual && expected); + + compare_uint8_ret(actual->op_count, expected->operands_count, false); + for (size_t i = 0; i < actual->op_count; ++i) { + const cs_xtensa_op *op = &actual->operands[i]; + TestDetailXtensaOp *eop = expected->operands[i]; + compare_enum_ret(op->type, eop->type, false); + compare_enum_ret(op->access, eop->access, false); + switch (op->type) { + default: + fprintf(stderr, + "xtensa op type %" PRId32 " not handled.\n", + op->type); + return false; + case XTENSA_OP_REG: + compare_reg_ret(*handle, op->reg, eop->reg, false); + break; + case XTENSA_OP_L32R: + case XTENSA_OP_IMM: + compare_int32_ret(op->imm, eop->imm, false); + break; + case XTENSA_OP_MEM: + compare_reg_ret(*handle, op->mem.base, eop->mem_base, + false); + compare_uint8_ret(op->mem.disp, eop->mem_disp, false); + break; + } + } + + return true; +} diff --git a/tests/details/xtensa.yaml b/tests/details/xtensa.yaml new file mode 100644 index 0000000000..931f3b5ccd --- /dev/null +++ b/tests/details/xtensa.yaml @@ -0,0 +1,15 @@ +test_cases: + - input: + bytes: [ 0x60, 0x51, 0x60 ] + arch: "CS_ARCH_XTENSA" + options: [ CS_OPT_DETAIL ] + expected: + insns: + - asm_text: "abs a5, a6" + details: + xtensa: + operands: + - type: XTENSA_OP_REG + reg: a5 + - type: XTENSA_OP_REG + reg: a6