Skip to content

Add new TMS320C2x (legacy) and TMS320C5x (legacy) series support - #6582

Merged
notxvilka merged 7 commits into
devfrom
asan-tms320-c2xc5x
Aug 16, 2026
Merged

Add new TMS320C2x (legacy) and TMS320C5x (legacy) series support#6582
notxvilka merged 7 commits into
devfrom
asan-tms320-c2xc5x

Conversation

@notxvilka

@notxvilka notxvilka commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

DO NOT SQUASH

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description

Legacy TMS320C2x (pre-C28x) and TMS320C5x (pre-C54x) were quite common in many places, and they share some of the infrastructure with already implemented TMS320C54x/C55x in Rizin.

Add both disassembly and RzIL uplifting.

Because no public toolchain available, I vibe-coded and verified against some other projects and pairs of source-binary the small toolchain for C2x and C5x in Rust - assembler, disassembler, C compiler, linker, and emulator: https://codeberg.org/xvilka/tms320-rs

Requires this PR for testbins: rizinorg/rizin-testbins#302

Test plan

CI is green

@Rot127 Rot127 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Came until c2x_il.c

Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x.c
Comment thread librz/arch/isa/tms320/c2x/c2x.c Outdated
Comment thread librz/arch/isa/tms320/c2x/c2x.c Outdated
@notxvilka
notxvilka force-pushed the asan-tms320-c2xc5x branch from 40bd096 to 4cca7b6 Compare July 11, 2026 08:09
@github-actions github-actions Bot added the AI/LLM Partially or fully AI generated. Critical thinking is advised! label Jul 11, 2026
@notxvilka
notxvilka requested a review from Rot127 July 11, 2026 08:11
@notxvilka
notxvilka force-pushed the asan-tms320-c2xc5x branch from 4cca7b6 to 8c44ed0 Compare July 11, 2026 08:47
Comment thread librz/arch/isa/tms320/c5x/c5x.h Outdated
Comment thread librz/arch/isa/tms320/c5x/c5x_decode.c Outdated
Comment thread librz/arch/isa/tms320/c5x/c5x_decode.c Outdated
Comment thread librz/arch/isa/tms320/c55_ir.c Outdated
Comment thread librz/arch/isa/tms320/c55_ir.c Outdated
Comment thread librz/bin/p/bin_coff.c
@notxvilka
notxvilka force-pushed the asan-tms320-c2xc5x branch 2 times, most recently from 393a716 to b178bb5 Compare July 26, 2026 07:01
@notxvilka
notxvilka marked this pull request as ready for review August 12, 2026 17:10
@Rot127
Rot127 requested a lite review from Copilot August 13, 2026 07:35

Copilot AI left a comment

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.

Pull request overview

This PR extends Rizin’s TMS320 support to include legacy TMS320C2x and TMS320C5x cores, including disassembly, analysis integration, and RzIL uplifting, and updates COFF handling to correctly scale word-addressed TI DSP addresses into Rizin’s byte-based address space.

Changes:

  • Add new C2x/C5x ISA implementations (decoder, analysis op filling, and RzIL lift) and wire them into the existing tms320 asm/analysis plugins.
  • Fix TI COFF loader address/size scaling for word-addressed targets (and add original TI COFF magic/target-id handling for C1x/C2x/C5x).
  • Add/adjust regression tests for plugin listings, analysis behavior, disassembly, and RzIL VM execution for C2x/C5x (and updated C54x expectations).

Reviewed changes

Copilot reviewed 30 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/db/tools/rz_asm Updates expected rz-asm CPU list to include c2x/c5x.
test/db/rzil/tms320_legacy Adds RzIL VM execution tests for legacy C2x/C5x binaries.
test/db/rzil/tms320 Updates C54x RzIL test and adds small C2x/C5x RzIL VM smoke tests.
test/db/cmd/cmd_list Updates plugin listing expectations for tms320 bits/cpu list.
test/db/cmd/cmd_aL Updates aL expectations for tms320 bits/cpu list and adds CPU descriptions.
test/db/asm/tms320_c54x_32 Updates expected lifted targets for word-addressed jump scaling.
test/db/asm/tms320_c2x_16 Adds C2x disassembly + IL golden tests.
test/db/analysis/tms320.typezoo_16 Adds C2x/C5x analysis tests for function recovery and calling conventions.
test/db/analysis/tms320.c5x_16 Adds C5x analysis tests (regs, op classification, RzIL lift, recovery).
test/db/analysis/tms320.c54x_32 Updates C54x analysis expectations to match new address scaling.
test/db/analysis/tms320.c2x_16 Adds C2x analysis tests (regs, op classification, COFF open, recovery).
librz/bin/p/bin_coff.c Scales TI DSP symbols/sections/maps by address unit (word->byte).
librz/bin/format/coff/coff.h Exposes rz_coff_addr_scale() in the COFF API.
librz/bin/format/coff/coff.c Implements address-unit scaling and recognizes original TI COFF magic-as-target-id.
librz/bin/format/coff/coff_specs.h Adds TI target-id constant for C1x/C2x/C5x.
librz/arch/types/meson.build Installs the new cc-tms320-16 calling convention DB.
librz/arch/types/cc-tms320-16.sdb.txt Adds C2x/C5x calling convention definitions for 16-bit TMS320.
librz/arch/p/asm/asm_tms320.c Wires c2x/c5x into the asm plugin; adds 16-bit support; uses C5x decoder.
librz/arch/p/analysis/analysis_tms320.c Wires c2x/c5x into analysis plugin; adds reg profiles + IL configs; adds 16-bit support.
librz/arch/meson.build Adds new C2x/C5x ISA sources to the build.
librz/arch/isa/tms320/c5x/c5x.h Introduces C5x ISA interface (ids, decoder, lift, analysis entry).
librz/arch/isa/tms320/c5x/c5x.c Implements C5x arch descriptor, analysis op entry, and IL VM reg bindings.
librz/arch/isa/tms320/c5x/c5x_il.c Implements C5x-only mnemonic/op-type/lift pieces on top of shared C2x semantics.
librz/arch/isa/tms320/c5x/c5x_decode.c Adds the C5x “real encoding” decoder producing shared C55Insn.
librz/arch/isa/tms320/c55_ir.h Adds C55_ARCH_C2X/C55_ARCH_C5X to the shared IR arch enum.
librz/arch/isa/tms320/c55_ir.c Adds word-address scaling for absolute targets and disables parallel-bit decoding for C2x/C5x; tweaks formatting for C2x/C5x.
librz/arch/isa/tms320/c54x/c54x_il.c Scales C54x branch targets in IL to byte address space.
librz/arch/isa/tms320/c2x/c2x.h Introduces C2x ISA interface (ids, decoder hooks, lift, analysis entry).
librz/arch/isa/tms320/c2x/c2x.c Implements C2x arch descriptor, opcode table rows, operand extractors, and analysis op filling.
librz/arch/isa/tms320/c2x/c2x_rowundefs.h Provides macro cleanup for C2x/C5x decode row definitions.
librz/arch/isa/tms320/c2x/c2x_rowdefs.h Adds shared row macros used to build the C2x decode table.
librz/arch/isa/tms320/c2x/c2x_core_rows.inc Adds the C2x core instruction decode table rows.
Suppressed comments (1)

librz/arch/isa/tms320/c5x/c5x_il.c:116

  • SPLK is lifted for any memory addressing mode, but c5x_mem_write()/c5x_addr() do not model indirect addressing post-modify or next-ARP updates. For non-direct forms this yields incorrect IL state. Consider restricting the lift to direct operands until indirect semantics are implemented.
	case C5X_INS_SPLK:
		// store a long immediate constant to the memory operand
		return c5x_mem_write(&insn->ops[0], UN(16, (ut32)insn->ops[insn->n_ops - 1].imm & 0xffff));

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread librz/arch/isa/tms320/c5x/c5x_il.c
Comment thread librz/arch/isa/tms320/c2x/c2x.c Outdated
Comment thread librz/arch/p/analysis/analysis_tms320.c Outdated
Comment thread test/db/rzil/tms320_legacy Outdated

@wargio wargio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

remove the @ 0 from the malloc:// tests

XVilka added 3 commits August 15, 2026 09:47
The C54x and C28x address 16-bit words, so their loadable section sizes
and every address in the file count words. Rizin's address space is
byte-based, so reading those unscaled mapped only half of each loadable
section and placed every symbol at half its true offset: _main in the
c54x emulateme object landed mid-instruction instead of on its prologue.

Scale section VAs, loadable section sizes and symbol addresses by the
target's address unit. Debug sections are byte streams even on these
targets and keep a scale of one, matching the loadable mask already used
for mapping. The C55x addresses program memory by byte and is left
alone; the ids were checked against the objects in rizin-testbins by
comparing each section's declared size against its extent in the file.

Branch and call targets on the C54x count program words too, and reached
analysis and RzIL unscaled. That went unnoticed while the sections were
half-mapped: the emulateme RzIL test ran from a mid-instruction address
whose decode happened to lift, so it pinned values produced by garbage.
Scale those as well and drive the test the way its C55x sibling does,
decrypting seckrit with the real key.

With the sections fully mapped, analysis now finds every routine the
c54x fixtures declare, so the function counts change.
The legacy TMS320 fixed-point families ship as 16-bit big-endian COFF
objects whose magic and machine identifiers were not recognised by the
COFF loader. Teach the COFF format backend and the bin plugin to detect
and load them so the new tms320 c2x/c5x analysis can operate on real
object files.
Add support for the legacy TMS320C2x (C25-class) fixed-point DSP family
to the shared C55 decode-IR engine: the C2x opcode table, operand
extractors, mnemonic and op-type tables, and the register profile, wired
into the tms320 asm and analysis plugins under cpu "c2x". The decoder
fills the shared C55 instruction representation so the common formatter
and analysis filler apply unchanged. Includes disassembly and opcode
classification tests, plus a COFF-loading test exercising the new bin
autodetect.
Add the real TMS320C5x (C50/C51/C53) object encoding. The C5x is
source-compatible with the C2x but encodes instructions differently, so
it cannot reuse the C2x decode table: a dedicated C5x decode front-end
fills the shared C55 instruction representation, carrying the C2x ids for
shared-semantics instructions (so the common consumers apply unchanged)
and new C5x-only ids for the C5x additions (ACCB ops, parallel-logic,
memory-mapped register access, conditional execute/call/return, block
moves, ...). Wired into the tms320 asm and analysis plugins under cpu
"c5x", with the C5x mnemonic and op-type tables and register profile.
Includes disassembly and opcode classification tests.
@notxvilka
notxvilka requested a review from wargio August 15, 2026 05:49
Comment thread librz/arch/isa/tms320/c2x/c2x_il.c Outdated
Comment on lines +625 to +628
return c2x_seq_post(SEQ2(SETL("m", c2x_mem_read(&insn->ops[0])), SEQ4(SETG("arp", LOGAND(SHIFTR0(VARL("m"), UN(4, 13)), UN(16, 7))), SETG("ov", LSB(SHIFTR0(VARL("m"), UN(4, 12)))), SETG("ovm", LSB(SHIFTR0(VARL("m"), UN(4, 11)))), SETG("dp", LOGAND(VARL("m"), UN(16, 0x1ff))))), c2x_ar_post(insn, 0));
case C2X_INS_LST1:
return c2x_seq_post(SEQ2(SETL("m", c2x_mem_read(&insn->ops[0])), SEQ6(SETG("tc", LSB(SHIFTR0(VARL("m"), UN(4, 11)))), SETG("sxm", LSB(SHIFTR0(VARL("m"), UN(4, 10)))), SETG("c", LSB(SHIFTR0(VARL("m"), UN(4, 9)))), SETG("pm", CAST(2, IL_FALSE, VARL("m"))), SETG("arp", LOGAND(SHIFTR0(VARL("m"), UN(4, 13)), UN(16, 7))), SETG("arb", LOGAND(SHIFTR0(VARL("m"), UN(4, 13)), UN(16, 7))))), c2x_ar_post(insn, 0));
case C2X_INS_SST: {

@wargio wargio Aug 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

just a comment: we need to find a better way for keeping the formatting. this is unreadable

XVilka added 3 commits August 16, 2026 20:10
Lift the TMS320C2x instruction set to RzIL: the 32-bit accumulator and
product paths, the auxiliary-register file with all indirect addressing
modes, the status bits (carry, overflow, OVM saturation, SXM sign
extension, product-mode shifts, TC), and the load/store, multiply,
accumulate, shift, logical and control-flow instructions. Wired into the
analysis plugin's il_config under cpu "c2x". The asm tests now assert the
lifted RzIL for every instruction, with execution tests covering the IL
VM end to end.
Lift the TMS320C5x instruction set to RzIL. Shared-semantics
instructions reuse the C2x lifter (the C5x-only forms that are a renamed
C2x op, such as the delayed branches, map onto their non-delayed
equivalents); the C5x-only core instructions (the ACCB accumulator-buffer
loads and logical ops, the swap, the zero-accumulator forms, the control
bits and the store-long-immediate) are lifted directly. Instructions with
effects the per-instruction RzIL cannot model cleanly (conditional
control transfers, block moves, parallel-logic, memory-mapped register
access, the MAC fetch forms) are decoded and analysed but left without
IL. Wired into the analysis plugin's il_config under cpu "c5x", with the
C5x register bindings (ACCB and the C5x-specific registers). The asm
tests assert the lifted RzIL, with execution tests covering the IL VM.
BSAR (Barrel Shift ACC Right) was grouped with the left-shift ops and
reported RZ_ANALYSIS_OP_TYPE_SHL. It shifts the accumulator right (1..16
bits, sign-extended under SXM), so it belongs with the SHR group next to
RORB/SFRB. The decode (shift code + 1) was already correct and continues
to match the reference disassembler bit-for-bit.
@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.89497% with 268 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.17%. Comparing base (f82d6e2) to head (36154e7).
⚠️ Report is 7 commits behind head on dev.

Files with missing lines Patch % Lines
librz/arch/isa/tms320/c5x/c5x_decode.c 78.05% 80 Missing and 24 partials ⚠️
librz/arch/isa/tms320/c2x/c2x_il.c 85.75% 38 Missing and 17 partials ⚠️
librz/arch/isa/tms320/c5x/c5x.c 71.42% 37 Missing and 5 partials ⚠️
librz/arch/isa/tms320/c2x/c2x.c 78.61% 19 Missing and 18 partials ⚠️
librz/arch/isa/tms320/c5x/c5x_il.c 76.25% 13 Missing and 6 partials ⚠️
librz/arch/p/analysis/analysis_tms320.c 50.00% 0 Missing and 6 partials ⚠️
librz/arch/isa/tms320/c55_ir.c 83.33% 0 Missing and 2 partials ⚠️
librz/arch/p/asm/asm_tms320.c 75.00% 0 Missing and 2 partials ⚠️
librz/bin/format/coff/coff.c 92.30% 0 Missing and 1 partial ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
librz/arch/isa/tms320/c54x/c54x_il.c 63.43% <100.00%> (+0.64%) ⬆️
librz/bin/p/bin_coff.c 58.67% <100.00%> (+1.74%) ⬆️
librz/bin/format/coff/coff.c 70.78% <92.30%> (+0.95%) ⬆️
librz/arch/isa/tms320/c55_ir.c 61.96% <83.33%> (+0.05%) ⬆️
librz/arch/p/asm/asm_tms320.c 63.26% <75.00%> (+1.36%) ⬆️
librz/arch/p/analysis/analysis_tms320.c 65.21% <50.00%> (-3.21%) ⬇️
librz/arch/isa/tms320/c5x/c5x_il.c 76.25% <76.25%> (ø)
librz/arch/isa/tms320/c2x/c2x.c 78.61% <78.61%> (ø)
librz/arch/isa/tms320/c5x/c5x.c 71.42% <71.42%> (ø)
librz/arch/isa/tms320/c2x/c2x_il.c 85.75% <85.75%> (ø)
... and 1 more

... and 16 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f82d6e2...36154e7. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@notxvilka
notxvilka merged commit 38c3bed into dev Aug 16, 2026
54 of 55 checks passed
@notxvilka
notxvilka deleted the asan-tms320-c2xc5x branch August 16, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI/LLM Partially or fully AI generated. Critical thinking is advised! merge-when-green rz-test RzAnalysis RzBin RZIL TMS320

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants