Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions arch/Xtensa/XtensaDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,23 @@ static DecodeStatus DecodeMR23RegisterClass(MCInst *Inst, uint64_t RegNo,

bool Xtensa_getFeatureBits(unsigned int mode, unsigned int feature)
{
// we support everything
return true;
switch (feature) {
case Xtensa_FeatureESP32S3Ops:
// SIMD/AI "ee.*" ops only exist on the ESP32-S3.
return (mode & CS_MODE_XTENSA_ESP32S3) != 0;
case Xtensa_FeatureHIFI3:
// HiFi3 DSP ops are gated behind the ESP32-S3 in this tree.
return (mode & CS_MODE_XTENSA_ESP32S3) != 0;
case Xtensa_FeatureDensity:
// Code Density is a base Tensilica default option.
return true;
default:
// Default case is the "allow all features", which is normal
// Capstone behavior until
// https://github.com/capstone-engine/capstone/issues/1992
// is implemented.
return true;
}
}

// Verify SR and UR
Expand Down Expand Up @@ -1036,17 +1051,17 @@ DecodeToMCInst(decodeToMCInst_6, fieldFromInstruction_6, uint64_t);
DecodeInstruction(decodeInstruction_6, fieldFromInstruction_6, decodeToMCInst_6,
uint64_t);

static bool hasDensity()
static bool hasDensity(MCInst *MI)
{
return true;
return Xtensa_getFeatureBits(MI->csh->mode, Xtensa_FeatureDensity);
}
static bool hasESP32S3Ops()
static bool hasESP32S3Ops(MCInst *MI)
{
return true;
return Xtensa_getFeatureBits(MI->csh->mode, Xtensa_FeatureESP32S3Ops);
}
static bool hasHIFI3()
static bool hasHIFI3(MCInst *MI)
{
return true;
return Xtensa_getFeatureBits(MI->csh->mode, Xtensa_FeatureHIFI3);
}

static DecodeStatus getInstruction(MCInst *MI, uint64_t *Size,
Expand All @@ -1058,7 +1073,7 @@ static DecodeStatus getInstruction(MCInst *MI, uint64_t *Size,
bool IsLittleEndian = MI->csh->mode & CS_MODE_LITTLE_ENDIAN;

// Parse 16-bit instructions
if (hasDensity()) {
if (hasDensity(MI)) {
Result = readInstruction16(MI, Bytes, BytesLen, Address, Size,
&Insn, IsLittleEndian);
if (Result == MCDisassembler_Fail)
Expand All @@ -1084,7 +1099,7 @@ static DecodeStatus getInstruction(MCInst *MI, uint64_t *Size,
return Result;
}

if (hasESP32S3Ops()) {
if (hasESP32S3Ops(MI)) {
// Parse ESP32S3 24-bit instructions
Result = readInstruction24(MI, Bytes, BytesLen, Address, Size,
&Insn, IsLittleEndian, true);
Expand All @@ -1111,7 +1126,7 @@ static DecodeStatus getInstruction(MCInst *MI, uint64_t *Size,
}
}

if (hasHIFI3()) {
if (hasHIFI3(MI)) {
Result = decodeInstruction_3(DecoderTableHIFI324, MI, Insn,
Address, NULL);
if (Result != MCDisassembler_Fail)
Expand Down
8 changes: 8 additions & 0 deletions bindings/python/capstone/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@
"CS_MODE_SYSTEMZ_Z15",
"CS_MODE_SYSTEMZ_Z16",
"CS_MODE_SYSTEMZ_GENERIC",
"CS_MODE_XTENSA_ESP32",
"CS_MODE_XTENSA_ESP32S2",
"CS_MODE_XTENSA_ESP8266",
"CS_MODE_XTENSA_ESP32S3",
"CS_OPT_SYNTAX",
"CS_OPT_SYNTAX_DEFAULT",
"CS_OPT_SYNTAX_INTEL",
Expand Down Expand Up @@ -565,6 +569,10 @@
CS_MODE_SYSTEMZ_Z15 = 1 << 13
CS_MODE_SYSTEMZ_Z16 = 1 << 14
CS_MODE_SYSTEMZ_GENERIC = 1 << 15
CS_MODE_XTENSA_ESP32 = 1 << 1 # Xtensa ESP32
CS_MODE_XTENSA_ESP32S2 = 1 << 2 # Xtensa ESP32S2
CS_MODE_XTENSA_ESP8266 = 1 << 3 # Xtensa ESP8266
CS_MODE_XTENSA_ESP32S3 = 1 << 4 # Xtensa ESP32-S3 (SIMD/AI "ee.*" ops)

# Capstone option type
CS_OPT_INVALID = 0 # No option specified
Expand Down
2 changes: 1 addition & 1 deletion cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ typedef struct cs_arch_config {
Xtensa_global_init, \
Xtensa_option, \
~(CS_MODE_XTENSA_ESP32 | CS_MODE_XTENSA_ESP32S2 | \
CS_MODE_XTENSA_ESP8266), \
CS_MODE_XTENSA_ESP8266 | CS_MODE_XTENSA_ESP32S3), \
}

#define CS_ARCH_CONFIG_ARC \
Expand Down
1 change: 1 addition & 0 deletions cstool/cstool.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ static struct {
CS_MODE_LOONGARCH64 },
{ "esp32", "Xtensa ESP32", CS_ARCH_XTENSA, CS_MODE_XTENSA_ESP32 },
{ "esp32s2", "Xtensa ESP32S2", CS_ARCH_XTENSA, CS_MODE_XTENSA_ESP32S2 },
{ "esp32s3", "Xtensa ESP32S3", CS_ARCH_XTENSA, CS_MODE_XTENSA_ESP32S3 },
{ "esp8266", "Xtensa ESP8266", CS_ARCH_XTENSA, CS_MODE_XTENSA_ESP8266 },

{ "arc", "ARC Little-Endian", CS_ARCH_ARC, CS_MODE_LITTLE_ENDIAN },
Expand Down
1 change: 1 addition & 0 deletions include/capstone/capstone.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ typedef enum cs_mode {
CS_MODE_XTENSA_ESP32 = 1 << 1, ///< Xtensa ESP32
CS_MODE_XTENSA_ESP32S2 = 1 << 2, ///< Xtensa ESP32S2
CS_MODE_XTENSA_ESP8266 = 1 << 3, ///< Xtensa ESP328266
CS_MODE_XTENSA_ESP32S3 = 1 << 4, ///< Xtensa ESP32S3
} cs_mode;

typedef void *(CAPSTONE_API *cs_malloc_t)(size_t size);
Expand Down
8 changes: 4 additions & 4 deletions suite/auto-sync/src/autosync/cpptranslator/saved_patches.json
Comment thread
Rot127 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2372,7 +2372,7 @@
},
"Xtensa_getFeatureBits": {
"apply_type": "OLD",
"old_hash": "126cff581e1a79a655c62e3489e238f7bf00647749f619230ab77061d0423295",
"old_hash": "54f9c8bb5264b1b92f2ebc7ba4bf70aaa7f203d537ca9e806ab6b4d69c397474",
"new_hash": "",
"edit": ""
},
Expand All @@ -2390,19 +2390,19 @@
},
"hasDensity": {
"apply_type": "OLD",
"old_hash": "da63483f075aba3c9f8937fb1900c646cb15f01b6b2e25568e6dcaa940b4798b",
"old_hash": "8bf85ed5fd8d904a43c0504ae5dedebaa8a4838be3c3d761f1c24e6625473d7e",
"new_hash": "",
"edit": ""
},
"hasESP32S3Ops": {
"apply_type": "OLD",
"old_hash": "464131365b24dec185e04d43154a85d9765a50a18214888c26014d8d85165a99",
"old_hash": "87849edd4b0f36b2f057f384624847b1f2dccd52f4070f57795bcb3a46bd98cb",
"new_hash": "",
"edit": ""
},
"hasHIFI3": {
"apply_type": "OLD",
"old_hash": "e1fcb3c8f47f38e571d1a81e7e522efb5c67e0aea05fd7b3980aa1eb3e71c9ff",
"old_hash": "7780479933da49a6e4b4c59d1cebbd6ba0c6cfa8877950d8b03e2b101f6d94dd",
"new_hash": "",
"edit": ""
},
Expand Down
1 change: 1 addition & 0 deletions suite/cstest/include/test_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ static const cs_enum_id_map test_mode_map[] = {
{ .str = "CS_MODE_V9", .val = CS_MODE_V9 },
{ .str = "CS_MODE_XTENSA_ESP32", .val = CS_MODE_XTENSA_ESP32 },
{ .str = "CS_MODE_XTENSA_ESP32S2", .val = CS_MODE_XTENSA_ESP32S2 },
{ .str = "CS_MODE_XTENSA_ESP32S3", .val = CS_MODE_XTENSA_ESP32S3 },
{ .str = "CS_MODE_XTENSA_ESP8266", .val = CS_MODE_XTENSA_ESP8266 },
};

Expand Down
58 changes: 58 additions & 0 deletions tests/MC/Xtensa/esp32s3.s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
test_cases:
# Positive: the ESP32-S3 SIMD/AI "ee.*" ops only decode when the
# CS_MODE_XTENSA_ESP32S3 feature is selected. Vector taken from real
# MT7961 firmware (it happens to also be a valid ESP32-S3 ee.vmulas).
-
input:
name: "ee.vmulas decodes on ESP32-S3"
bytes: [ 0x9e, 0x3e, 0x09, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "CS_MODE_XTENSA_ESP32S3" ]
address: 0x0
expected:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to add some tests that follow the “details” style to tests/details/tricore.yaml?

insns:
-
asm_text: "ee.vmulas.u16.accx.ld.ip.qup q1, a9, 0xe0, q0, q6, q0, q1"
size: 4

# Negative (ESP32): without the ESP32-S3 feature the 4-byte ee.* encoding
# must NOT be produced. These bytes do not form a valid base/ESP32
# instruction, so decoding fails (zero instructions).
-
input:
name: "ee.vmulas must NOT decode on ESP32 (#1)"
bytes: [ 0x9e, 0x3e, 0x09, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "CS_MODE_XTENSA_ESP32" ]
address: 0x0
expected:
insns: []
-
input:
name: "ee.vmulas must NOT decode on ESP32 (#2)"
bytes: [ 0x3e, 0x19, 0x45, 0x48 ]
arch: "CS_ARCH_XTENSA"
options: [ "CS_MODE_XTENSA_ESP32" ]
address: 0x0
expected:
insns: []

# Negative (base Tensilica, no vendor feature bits): same expectation.
-
input:
name: "ee.vmulas must NOT decode on base Xtensa (#1)"
bytes: [ 0x9e, 0x3e, 0x09, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "CS_MODE_LITTLE_ENDIAN" ]
address: 0x0
expected:
insns: []
-
input:
name: "ee.vmulas must NOT decode on base Xtensa (#2)"
bytes: [ 0x3e, 0x19, 0x45, 0x48 ]
arch: "CS_ARCH_XTENSA"
options: [ "CS_MODE_LITTLE_ENDIAN" ]
address: 0x0
expected:
insns: []
Loading