1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# EspCustomIsa — Espressif-specific ESP32-P4 CPU ISA: PIE/HWLP vendor extensions, LP core, cache/MMU, custom CSRs, toolchain
## Key facts established for this project
**Exact `-march` for ESP32-P4 silicon rev < v3 (this project's v1.3 part), read out of ESP-IDF v6.0.2
`components/soc/project_include.cmake:19-83`:**
```
-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1 -mabi=ilp32f -mtune=esp-base
```
Composition, line by line: base `rv32imafc_zicsr_zifencei_zaamo_zalrsc` (L20); `_zcb_zcmp_zcmt`
**suppressed** because `CONFIG_ESP32P4_SELECTS_REV_LESS_V3` (L47); `_xesploop` from
`SOC_CPU_HAS_HWLOOP` (L59-61); `_xespv` + `2p1` — the `2p1` pinned *because* rev < v3 (L63-68);
`_xespdsp` only if `SOC_CPU_HAS_DSP`, which ESP32-P4 does **not** define (L70-72). GCC normalises this
to the ELF attribute string found verbatim in IDF's prebuilt P4 libraries
(`components/openthread/lib/esp32p4/libopenthread_br.a`):
`rv32i2p1_m2p0_a2p1_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcf1p0_xesploop1p0_xespv2p1`.
`xesppie` — the name in the task brief — is the **historical** spelling. `riscv32-esp-elf-gcc 15.2.0`
rejects it outright (`extension 'xesppie' starts with 'x' but is unsupported non-standard extension`);
the accepted names are `xespv2p1`, `xespv2p2`, `xesploop`/`xesploop1p0`, `xespdsp`. The old name
survives only in ESP-IDF's gdbstub (`components/esp_gdbstub/src/port/riscv/target_xml.c:88`,
`"org.gnu.gdb.riscv.xesppie"`) and in `components/esp_gdbstub/test_gdbstub_host/rv_decode/xesppie.S`
(header comment still says `-march=rv32ixesppie`).
**PIE mnemonics used by `examples/pie.zig`** (all eight verified present in both documents cited below):
`esp.vld.128.ip`, `esp.vst.128.ip`, `esp.zero.qacc`, `esp.vmulas.s8.qacc`,
`esp.st.qacc.l.l.128.ip`, `esp.st.qacc.l.h.128.ip`, `esp.st.qacc.h.l.128.ip`, `esp.st.qacc.h.h.128.ip`.
Enable CSR is `0x7F2` (`CSR_PIE_STATE_REG`, `components/riscv/include/riscv/csr_pie.h:19`).
**GCC exposes no PIE intrinsics.** `strings` over `cc1` and `cc1plus` in
`/home/goblin/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/libexec/gcc/riscv32-esp-elf/15.2.0/`
yields zero `__builtin_riscv_esp*` / `esppie` symbols — only the `-march` tokens `xespv`, `xesploop`,
`xespdsp`. The extension is assembler-only: 410 distinct `esp.*` mnemonics live in the opcode table of
the dedicated assembler `riscv32-esp-elf/riscv32-esp-elf/bin/as-xespv2p1` (sibling `as-xespv2p2`,
`objdump-xespv2p1`, `objdump-xespv2p2`). This independently confirms `examples/pie.zig`'s premise that
hand-written `.insn` words are the only route, under Espressif's own GCC as much as under stock Zig.
## Obtained
| file | title | version / date | source URL | bytes | pages | sha256 (first 16) | relevance |
|---|---|---|---|---|---|---|---|
| espressif-custom-isa/esp32p4-pie-simd_instruction-reference_esp-dl_2026-07-15.md | ESP32-P4 SIMD Instruction Reference | esp-dl master @ 1def9a2dff008fe1ae96c249490683147fce26bc, 2026-07-15 | https://raw.githubusercontent.com/espressif/esp-dl/master/tools/agents/skills/esp32p4-pie-simd/references/instructions.md | 47644 | 907 lines / 346 instruction rows | 76576a92f85fb46a | The only standalone vendor PIE reference: "Register Architecture" (q0–q7, QACC_H/QACC_L 256-bit each, SAR, SAR_BYTE, rounding-mode `rm_exc`), then Read / Write / Data Exchange / Arithmetic / Comparison / Bitwise Logical / Shift / FFT Dedicated instruction tables — covers all 8 mnemonics this project emits (L141 VLD.128.IP, L222 VST.128.IP, L240-243 ST.QACC.{H,L}.{H,L}.128.IP, L339 ZERO.QACC, L490 VMULAS.S8.QACC) |
**Non-PDF fallback, declared explicitly as the rules require.** No PDF of the PIE instruction set
exists as a standalone Espressif document — the only PDF carrying it is the ESP32-P4 TRM, which is
`espressif-silicon/`'s lane (see "Belongs elsewhere"). This `.md` is the official `.md` spec source
fallback: vendor-authored, in `github.com/espressif/esp-dl`, no mirror involved.
**Fidelity check against the TRM, so the reader can trust it.** I diffed entries against
`espressif-silicon/esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf` ch.4. The `.md`'s
`ESP.VMULAS.S8.QACC` line — "16 × S8 mul, accumulate 32-bit to QACC_H/L (saturated to 32-bit signed)" —
reproduces TRM §4.7.2.23's description exactly. Caveat worth knowing: the `.md` is a *condensation*
written for agent consumption, so it drops operands and bit-level Operation pseudocode. It gives
`ESP.VMULAS.S8.QACC qx, qy` where TRM §4.7.2.23 syntax is `ESP.VMULAS.S8.QACC qx,qy,sat`, and it
carries **no instruction encodings at all**. It documents 346 mnemonics against the assembler's 410.
For encodings (which is what `.insn` needs) the TRM figures, or `as-xespv2p1` as an oracle the way
`tools/encode.sh` already uses it, remain the only sources.
## Not obtained
| wanted | why not | best known pointer |
|---|---|---|
| PIE instruction-set spec with **encodings** (item 1) | Exists, but only as ESP32-P4 TRM ch.4 — a PDF owned by `espressif-silicon/`. Not refetched per lane rule. | `cpu-docs/espressif-silicon/esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf` ch.4 "Processor Instruction Extensions (PIE)" p.210 (§4.7.2.x per-instruction: syntax + Description + Operation + encoding figure; §4.7.2.23 = ESP.VMULAS.S8.QACC), plus §2.7.2 "Processor Instruction Extension" p.127. Upstream: https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf . Local pre-existing copy: `/home/goblin/00-projects/0x4200.cafe/01-esp32p4-m3/docs/esp32-p4_technical_reference_manual_en.pdf`. **Warning: the rev-matched v1.3 TRM omits this chapter entirely** (confirmed by EspSilicon: its "Release Status at a Glance" lists ch.3 Processor Instruction Extensions as "[to be added later]" and in-document numbering skips it), so for PIE the generic v0.7 manual must be used even though the part is v1.3 silicon. |
| HWLP / hardware-loop (`xesploop1p0`) spec | No standalone document anywhere; TRM only. | TRM v0.7 §2.7.1 "Hardware Loop" p.119 (2.7.1.1 Overview, .2 Features, .3 Functional Description, .4 Instructions/Operations/Modes Supported in HWLP, .5 HWLP Constraints, .6-.7 Register Summary/Description) and §2.7.1.8 "HWLP Instructions" p.126. CSRs: `esp-idf/components/riscv/include/riscv/csr_hwlp.h` — `CSR_HWLP_STATE_REG 0x7F1` (states OFF/INITIAL/CLEAN/DIRTY), `CSR_LOOP0_START_ADDR 0x7C6`, `CSR_LOOP0_END_ADDR 0x7C7`, `CSR_LOOP0_COUNT 0x7C8`, `CSR_LOOP1_*` 0x7C9-0x7CB. Local: `/home/goblin/esp/esp-idf/components/riscv/include/riscv/csr_hwlp.h`. Upstream: https://github.com/espressif/esp-idf/blob/master/components/riscv/include/riscv/csr_hwlp.h . Errata to respect: `SOC_CPU_HAS_HWLOOP_STATE_BUG` — "HWLOOP state doesn't go to DIRTY after executing the last instruction of a loop" (`components/soc/esp32p4/include/soc/soc_caps.h:198`). |
| LP core (low-power RISC-V) ISA + programming model, standalone (item 2) | No standalone Espressif document exists; the material is split between the TRM's LP CPU chapter and the ESP-IDF guide, both other agents' lanes. | **ISA string (verified, and it is *not* the HP string):** `-march=rv32imac_zicsr_zifencei_zaamo_zalrsc`, no FPU, no vendor extensions — `esp-idf/components/ulp/cmake/toolchain-lp-core-riscv.cmake:8,10,12,14` (C/CXX/ASM/LINK all four). Local: `/home/goblin/esp/esp-idf/components/ulp/cmake/toolchain-lp-core-riscv.cmake`; upstream https://github.com/espressif/esp-idf/blob/master/components/ulp/cmake/toolchain-lp-core-riscv.cmake . **Interrupt/wakeup model:** `components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h` (`ulp_lp_core_intr_enable`/`_disable`, per-source ISR weak symbols) and `ulp_lp_core_utils.h`; driver side `components/ulp/lp_core/lp_core.c`. **Caps:** `components/soc/esp32p4/include/soc/soc_caps.h:57-58` (`SOC_ULP_SUPPORTED`, `SOC_LP_CORE_SUPPORTED`), `:769-771` (`SOC_LP_CORE_SUPPORT_ETM`, `_LP_ADC`, `_STORE_LOAD_EXCEPTIONS`). **Prose spec:** rev-matched `espressif-silicon/esp32-p4-chip-revision-v1.3_technical_reference_manual_en.pdf` ch.3 "Low-Power CPU" p.189 (use this one, not generic v0.7 where LP CPU is ch.5 p.633). |
| Cache + MMU document, PDF (item 3) | Espressif publishes no separate cache/MMU document; TRM chapters plus ROM headers are authoritative. | **Prose:** rev-matched v1.3 TRM ch.7 "System and Memory" p.450 — §7.3.1 Address Mapping p.451, §7.3.3.1 External Memory Address Mapping p.456, §7.3.3.2 Cache p.457, §7.3.3.3 Cache Operations p.458 (generic v0.7 equivalent: ch.9 p.901, §9.3.3.2 Cache p.909). **ROM `Cache_*` API:** `esp-idf/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h` — 1611 lines, **117** distinct `Cache_*` entry points covering the L1-per-core-ICache / L1-DCache / L2-Cache hierarchy this part actually has (`Cache_Enable_L1_CORE0_ICache`, `Cache_Enable_L1_CORE1_ICache`, `Cache_Enable_L1_DCache`, `Cache_Enable_L2_Cache`, `Cache_Clean_Addr`/`_All`/`_Gid`, `Cache_*_Autoload`, `Cache_*_PreLock`). Note the path in the brief is stale for v6.0.2: `components/esp_rom/include/esp32p4/rom/cache.h` does **not** exist; the header moved under `components/esp_rom/esp32p4/`. Local: `/home/goblin/esp/esp-idf/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h`; upstream https://github.com/espressif/esp-idf/blob/master/components/esp_rom/esp32p4/include/esp32p4/rom/cache.h . **The 64 KiB flash-MMU page rule this project exploits:** hard-wired, not configurable — `components/hal/esp32p4/include/hal/mmu_ll.h:129` returns `MMU_PAGE_64KB` unconditionally and `:140` asserts `size == MMU_PAGE_64KB`. Image-side consumer: `components/bootloader_support/src/esp_image_format.c:690` (`__builtin_mul_overflow(max_pages, SPI_FLASH_MMU_PAGE_SIZE, &max_image_len)`) and `:865-885` (`SOC_MMU_PAGE_SIZE_CONFIGURABLE`, page-size-mismatch path). |
| Espressif CSR / interrupt-controller doc beyond the TRM (item 4) | No such document is published; ESP-IDF headers are the only machine-checkable source, and they settle the questions asked. | **`INTPRI` does not exist on the ESP32-P4** — verified negative: zero hits for `INTPRI` under `components/soc/esp32p4/`, whereas ESP32-C6 has `register/soc/intpri_reg.h` + `intpri_struct.h`. The P4 uses a CLIC instead. **Non-standard CLIC on rev < v3, i.e. this part** — `components/soc/esp32p4/include/soc/interrupt_reg.h:30-44`, guarded by `CONFIG_ESP32P4_SELECTS_REV_LESS_V3`, comment verbatim: "The ESP32-P4 implements a non-standard version of the CLIC: - The interrupt threshold is configured via a memory-mapped register instead of a CSR - The mintstatus CSR is at 0x346 instead of 0xFB1 as per the official specification" → `INTTHRESH_STANDARD 0`, `MINTSTATUS_CSR 0x346`. Standard-CLIC values for rev ≥ v3 in `components/riscv/include/riscv/csr_clic.h:39-43` (`MINTSTATUS 0xFB1`, `MINTTHRESH 0x347`, `UINTSTATUS 0xCB1`, `UINTTHRESH 0x047`); `MTVT_CSR 0x307` (:34), `RV_EXTERNAL_INT_COUNT 32` / `RV_EXTERNAL_INT_OFFSET 16` (:28-29). **mtvec is vectored, mode = 3:** `MTVEC_MODE_CSR 3` (csr_clic.h:22) is OR-ed into every write by `rv_utils_set_mtvec` (`components/riscv/include/riscv/rv_utils.h:168-177`, "Set MODE field to treat XTVEC as a vector base address"). CLIC register layout: `components/soc/esp32p4/include/soc/clic_reg.h` (`CLIC_INT_CONFIG_REG`, `NMBITS`, `MNLBITS`, `NVBITS`, `CLIC_EXT_INTR_NUM_OFFSET 16`). **`mpcer`/`mpcmr` are NOT on the P4** — verified negative: `SOC_CPU_HAS_CSR_PC` is defined only for esp32c2/c3/c6/h2/h21 `soc_caps.h`, never esp32p4, so the `CSR_PCER_MACHINE 0x7e0` / `CSR_PCMR_MACHINE 0x7e1` counters gated at `rv_utils.h:44-50` are absent and the P4 falls to standard `mcycle`/`minstret` (`rv_utils.h:122,135`). Other vendor CSRs present: `csr_pie.h` `0x7F2`; `csr_hwlp.h` `0x7F1`,`0x7C6`-`0x7CB`; `csr_dsp.h` `CSR_DSP_STATE_REG 0x7f3`, `XACC_L 0x806`, `XACC_H 0x807`, `SAR 0x809`, `STATUS 0x80a`. |
| riscv32-esp-elf toolchain doc covering the custom `-march` and its ABI implications (item 5) | Espressif publishes no toolchain reference manual, in PDF or otherwise; the `-march` string is documented only by the ESP-IDF build code above. GitHub release notes are the authoritative changelog but never state the vendor `-march` syntax. | Release index: https://github.com/espressif/crosstool-NG/releases . Installed build `esp-15.2.0_20251204` (published 2025-12-05) — its notes are PIE-relevant but shallow: "Added esp.vsl.32 instruction support for backward compatibility". Latest is `esp-16.1.0_20260609` (published 2026-06-10), which removes the `rv32imafc_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt` multilib — irrelevant here since rev < v3 already suppresses `_zcb_zcmp_zcmt`. ABI is stated only as the flags in `components/soc/project_include.cmake:75-83`: `-mabi=ilp32f` when `SOC_CPU_HAS_FPU`, `-mtune=esp-base`. Multilib layout on disk (no `xesp*` variant exists — vendor extensions add no multilib, hence no ABI split): `/home/goblin/.espressif/tools/riscv32-esp-elf/esp-15.2.0_20251204/riscv32-esp-elf/riscv32-esp-elf/lib/`. Tooling doc page that exists but does not cover `-march`: https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-guides/tools/idf-tools.html |
| LLVM-side PIE definitions (`RISCVInstrInfoESP32P4.td`, intrinsics headers) | Checked and not usable as a document: `espressif/llvm-project` (branch `xtensa_release_19.1.2`) ships the stock upstream `llvm/docs/RISCVUsage.rst` with no `Xesppie`/`Xespv` section, and any `.td` file is code, which this task forbids copying. Consistent with `examples/pie.zig`'s claim that Espressif's own LLVM cannot assemble these mnemonics. | https://github.com/espressif/llvm-project — searched `llvm/docs/RISCVUsage.rst` (fetched, 26699 bytes, no vendor-extension entry). |
| An esp-dsp guide PDF documenting PIE | Provably absent: `https://docs.espressif.com/projects/esp-dsp/en/latest/` serves HTTP 200 with **zero** `.pdf` hrefs, and all four plausible docs.espressif.com PDF paths return 404 (`esp-dsp-en-master.pdf`, `esp-dsp-en-master-esp32.pdf`, `esp32/esp-dsp-en-master-esp32.pdf`, `esp32p4/esp-dsp-en-master-esp32p4.pdf`). esp-dsp has no PDF build. | https://docs.espressif.com/projects/esp-dsp/en/latest/ (HTML only) |
### Searches run for a standalone PIE instruction-set document
Recorded so the negative result is auditable. (1) `espressif.com/en/support/documents/technical-documents` full PDF index scraped (824888 bytes, ~40 `.pdf` hrefs enumerated): the only ESP32-P4 entries are datasheet, TRM, `esp32-p4-chip-revision-v1.3_{datasheet,technical_reference_manual}`, and `esp32-p4-chip-revision-v3.x_user_guide` — **no** PIE/ISA/instruction-set document. (2) `docs.espressif.com/projects/esp-dsp` — no PDF build (four 404s above). (3) Web search for the literal mnemonics `ESP.VMULAS` / `ESP.VLD.128.IP` — surfaced only the esp-dl reference I fetched, an Espressif developer-portal blog post, third-party blogs, and datasheet-mirror copies of the *ESP32-S3* TRM; all rejected except the esp-dl reference. (4) GitHub `espressif/esp-dl/tools/agents/skills/` enumerated via API: `esp32p4-pie-simd/{SKILL.md, references/{instructions.md, examples.md}}` — `instructions.md` taken; `SKILL.md` is agent prose and `examples.md` is example code, both out of scope for a source archive. (5) `espressif/llvm-project` docs (above). (6) Installed toolchain swept for any bundled manual: zero `.pdf`, `.info`, `.1`, or `.html` files under `riscv32-esp-elf/`, only two unrelated GCC `include-fixed` READMEs. **Conclusion: no standalone PIE instruction-set document is published; TRM ch.4 is the sole encoding-complete spec, and the esp-dl `.md` is the sole standalone reference.**
Non-vendor and blog sources deliberately rejected: `developer.espressif.com/blog/2024/12/pie-introduction/` (Espressif-official but a blog post, excluded per the brief's "blog-free official doc"), `bitbanksoftware.blogspot.com`, `esp32.com` forum, `skillsmp.com`, and the `waveshare`/`hackaday` mirrors of the ESP32-S3 TRM (mirror + wrong chip).
## Belongs elsewhere
- **ESP32-P4 TRM (generic, Pre-release v0.7) ch.4 "Processor Instruction Extensions (PIE)" p.210, §2.7.1 Hardware Loop p.119, §2.7.1.8 HWLP Instructions p.126, §2.7.2 Processor Instruction Extension p.127** — the encoding-complete PIE/HWLP spec, and the single most important document for `examples/pie.zig`. Fetched by `espressif-silicon/` as `esp32p4_technical-reference-manual_en_pre-release-v0.7.pdf`; not duplicated here.
- **ESP32-P4 chip-revision-v1.3 TRM (Pre-release v0.4) ch.3 "Low-Power CPU" p.189 and ch.7 "System and Memory" p.450** — rev-correct LP-core and cache/MMU chapters for this project's silicon. `espressif-silicon/`.
- **ESP32-P4 Chip Revision v3.x User Guide** (`https://www.espressif.com/sites/default/files/documentation/esp32-p4-chip-revision-v3.x_user_guide_en.pdf`) — spotted in the espressif.com index while searching; likely documents the rev-v3 ISA/CLIC deltas that `CONFIG_ESP32P4_SELECTS_REV_LESS_V3` and the `xespv2p1`→`xespv2p2` bump straddle. Chip-level revision doc → `espressif-silicon/`.
- **ESP-IDF Programming Guide (ESP32-P4) "ULP LP-Core Coprocessor Programming"** — https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-reference/system/ulp-lp-core.html , part of the ESP-IDF PDF → `espressif-software/`.
- **ESP-IDF Programming Guide "Speed Optimization"** — https://docs.espressif.com/projects/esp-idf/en/stable/esp32p4/api-guides/performance/speed.html , the only guide page discussing PIE-related build flags; inside the ESP-IDF PDF → `espressif-software/`.
|