Introduction
Xtensa is a configurable 32-bit processor from Tensilica (now Cadence): a licensee picks which options a core has, and may add instructions of its own. Espressif chose it for the ESP8266 (an LX106 core), the ESP32 (two LX6 cores), the ESP32-S2 (one LX7) and the ESP32-S3 (two LX7 with a vector extension). The newer ESP32-C, -H and -P chips use RISC-V instead and are not covered here (see RISC-V).
An Xtensa instruction is 3 bytes (24 bits) or, with the Code Density option, 2 bytes; the low
4 bits of the first byte, op0, say which. On the ESP32-S3 an op0 of 14 or 15 starts a 4-byte
vector instruction. Instructions have no alignment, so they can start at any byte. The ESP chips run little-endian. The pages:
registers, formats and the op0 tree, the instructions
(base, windowed,
options, floating point,
system, Espressif additions,
vector) and the chips. Every instruction has an
anchor, so a disassembled instruction in the explorer links to its entry.
An Xtensa program opens in the explorer today as an ELF file (e_machine 94). The explorer
decodes at every byte, so the overlapping decodes of 2- and 3-byte instructions show in columns beside the plain disassembly.
The variants the explorer decodes
An Xtensa ELF names no chip, so the options bar offers one (ESP32 is what "From the file" means). An instruction of an option the chosen chip lacks is shown as an instruction of an option this chip lacks, with its name.
| Variant | Core | Has |
|---|---|---|
| ESP32 | LX6 | Windows, density, loops, booleans, MAC16, 16- and 32-bit multiply, divide, min/max, CLAMPS, SEXT, NSA, S32C1I, the single-precision FPU, and Espressif's F64 and EXPSTATE. |
| ESP32-S2 | LX7 | Windows, density, multiply and divide, min/max, CLAMPS, SEXT, NSA, SALT/SALTU and the GPIO instructions. No loops, booleans, MAC16, FPU or S32C1I. |
| ESP32-S3 | LX7 | The ESP32's options with the FPU, SALT/SALTU, and the PIE vector instructions (op0 14 and 15 are 4-byte instructions). No F64 or EXPSTATE. |
| ESP8266 | LX106 | Base instructions, density, MUL16 and MULL, NSA, TLB and debug instructions. No windows (the call0 ABI), loops, booleans, MAC16 or FPU. |
The full table of what each chip enables is on the chips.
Status of an instruction
| Status | Meaning |
|---|---|
| Documented | An instruction of the chosen chip. |
| Unavailable | An instruction of an option this chip lacks (a floating-point instruction on the ESP32-S2, a windowed call on the ESP8266). |
| Reserved | No instruction has this encoding on any variant, or a special register or user register this chip does not have. |
Notation
The disassembly follows the GNU assembler: entry a1, 32, l32r a2, 0x40080008, rsr.ps a2,
extui a2, a3, 4, 8. A number between -255 and 255 is decimal, anything else hexadecimal as a 32-bit value. A jump, call,
branch or loop shows its target address; L32R shows the address of its literal. The registers are
a0 to a15 (sp for a1 if you ask), b0 to b15,
f0 to f15, m0 to m3 and, on the S3, q0 to q7.
Options
| Option | Choices |
|---|---|
| Chip (variant) | ESP32 (the default), ESP32-S2, ESP32-S3, ESP8266. |
| Register names | a0 to a15, or sp for a1. |
| Pseudo-instructions | Off (the default, as objdump) or on: or with equal sources shown as mov. nop and ret are real instructions and always shown as themselves. |
| Branch and call targets | The target address, or the byte offset from the instruction. |
| L32R literals | The literal's address, or the displacement as encoded. |
| Byte order | From the file, little (every ESP chip) or big. |
How the decoder was checked
The decoder is the explorer's own. The Espressif toolchain's objdump (crosstool-NG esp-16.1.0, binutils 2.46, with each chip's own configuration) is an independent decoder, and Tensilica's generated ISA description of each core was read as a second source.
- Every 24-bit word of every
op0from 0 to 7, every 16-bit word ofop08 to 13, and the reservedop0values were decoded by both for the ESP32. Every difference was classified; the explained ones are objdump's behaviour for what it cannot decode (it prints the first opcode of its table,lsi, or a 1-byte.byte) and for bits it does not look at. The numbers are in the progress notes of this work and repeated on the chips. - The opcode encodings and the special-register numbers of the ESP32, ESP32-S3 and ESP8266 were compared with the cores' configuration files (the ESP8266 has no objdump here; this is its only independent check).
- A program of every instruction form was assembled and linked with the toolchain, and our disassembly equals the source line by line.
- Real ESP32-S3 ELF files were disassembled through the explorer and compared with objdump at every address objdump prints.
Not described
Known, not yet covered
- Reference and viewer: 27 of the 217 ESP32-S3 vector mnemonics (rare 32-bit forms) are not in the decoder.
- Reference and viewer: the cache, prefetch, MMU-register and FLIX (64-bit bundle) instructions of the generic Xtensa configuration; no ESP chip has them.
- Viewer: the ESP firmware image formats are separate pages.
- Reference: instruction timing is not given.
Unknown
- Reference: the semantics of the Espressif F64 and EXPSTATE instructions are not published; only the encodings and operands are given.
- Reference: the ESP32-S2 and ESP32-S3 option sets come from objdump's behaviour and the S3 core file; the S2 has no core file here.
Links
Reference
- Tensilica – the company and the Xtensa architecture
- Espressif crosstool-NG – the compilers and binutils for the ESP chips
- ESP-IDF – Espressif's SDK