Addressing Modes - wgrzegorz/c5xtools GitHub Wiki

Addressing Modes

Normative source: SPRU056D, chapter 5 (Addressing Modes). Opcode field widths are additionally checked against the toolchain's include/c5x_isa.h.

The TMS320C5x reaches an operand in data memory in one of six ways. The first two (direct and indirect) are the general data-memory modes and share one bit in the instruction word (bit 7) that selects between them. The other four are specialized.

Mode Operand comes from Selected by
Direct 7-bit field in the instruction, paged by DP bit 7 = 0
Indirect one of AR0 to AR7, via the ARAU bit 7 = 1
Immediate a constant inside the instruction word(s) the instruction itself (#k)
Dedicated-register the BMAR or the DBMR the instruction itself
Memory-mapped page-0 address with the 9 high bits forced to 0 the instruction itself
Circular an AR constrained to a buffer by CBSR/CBER/CBCR CBCR enable bit

1. Direct addressing

The instruction carries the low 7 bits of the data-memory address (the dma). Those 7 bits select one of 128 words inside a page; the 9-bit data-memory page pointer DP (in status register ST0) selects one of 512 pages. Concatenating them forms the full 16-bit address, which is driven onto the internal data address bus (DAB).

Instruction-word layout:

Load the DP with LDP (or with LST #0). Example:

    LDP   #019Dh        ; DP = 19Dh  (page 413)
    ADD   010h, 5       ; add Data(DP:010h) << 5 to the accumulator

Note (from SPRU056D): the DP is not initialized by reset and is undefined after power-up. Development tools use default values, so a program that does not set the DP in software may behave differently on real silicon than under a tool. Always initialize the DP.


2. Indirect addressing

Eight 16-bit auxiliary registers AR0 to AR7 hold addresses; any of the 64K-word data space can be reached through them. The 3-bit auxiliary register pointer ARP (in ST0) selects the current AR. After the access, the auxiliary register arithmetic unit (ARAU) can modify the current AR, and the ARP can be pointed at a different AR, all in the same cycle. The index register INDX supplies the step for indexed and bit-reversed updates.

Instruction-word low byte (SPRU056D Table 5-1): the Indirect addressing row of the figure at the top of this page shows the layout; the fields are:

Field Bit(s) Meaning
I 7 Addressing mode. 1 = indirect, 0 = direct.
IDV 6 Use INDX for the update (1) rather than a step of 1 (0).
INC 5 Increment the current AR after the access.
DEC 4 Decrement the current AR after the access.
N 3 Load a new ARP (1) or leave it unchanged (0).
NAR 2-0 The next AR number, loaded into ARP when N = 1.

The assembler hides those bits behind operand syntax. The seven update forms:

Operand Update to the current AR after the access
* none
*+ increment by 1
*- decrement by 1
*0+ add INDX
*0- subtract INDX
*BR0+ add INDX with reverse carry (bit-reversed)
*BR0- subtract INDX with reverse carry (bit-reversed)

Any of these may be followed by a next-AR number to repoint the ARP in the same instruction, for example *+,AR3 (use the current AR, increment it by 1, then set ARP = 3). Bit-reversed forms support FFT data reordering: set INDX to half the array size and the ARAU propagates carries in reverse.

    LAR   AR3, #0300h     ; AR3 -> 0300h
    MAR   *, AR3          ; make AR3 the current AR (ARP = 3)
    LACC  *+              ; ACC = Data(0300h), then AR3 = 0301h
    LACC  *0+             ; ACC = Data(0301h), then AR3 = AR3 + INDX

3. Immediate addressing

The operand is a constant contained in the instruction itself, written with a leading #. Short-immediate instructions are one word and carry an 8-, 9- or 13-bit constant; long-immediate instructions are two words and carry a full 16-bit constant in the second word.

Instructions that accept an immediate operand (SPRU056D Table 5-5):

Constant width Instructions
8-bit (short) ADD, ADRK, LACL, LAR, RPT, SBRK, SUB
9-bit (short) LDP
13-bit (short) MPY
16-bit (long) ADD, AND, APL, CPL, LACC, LAR, MPY, OPL, OR, RPT, RPTZ, SPLK, SUB, XOR, XPL

Example:

    ADD   #0FFh          ; one-word, 8-bit immediate
    ADD   #01234h        ; two-word, 16-bit immediate

4. Dedicated-register addressing

Works like long-immediate addressing, except the address is taken from a special memory-mapped CPU register instead of the instruction word, so it can change at run time:

Register Name Used by
BMAR block move address register BLDD, BLDP, BLPD (block moves) and MADD, MADS (multiply-accumulate from program memory)
DBMR dynamic bit manipulation register APL, CPL, OPL, XPL when no immediate mask is given
    BLDD  BMAR, DAT100    ; source address comes from BMAR
    OPL   DAT10           ; OR Data(DAT10) with the DBMR mask

5. Memory-mapped register addressing

Like direct addressing, but the 9 high bits of the address are forced to 0 instead of coming from the DP. This reaches the memory-mapped registers (and scratch-pad RAM block B2, and page 0) without first changing the DP or an AR. Four instructions use this mode and leave the DP untouched:

Instruction Operation
LAMM load the accumulator from a memory-mapped register
SAMM store the accumulator to a memory-mapped register
LMMR load a memory-mapped register
SMMR store a memory-mapped register

6. Circular addressing

A circular buffer implements a sliding window (used by convolution, correlation and FIR filters). The 'C5x supports two concurrent circular buffers driven by auxiliary registers and controlled by five memory-mapped registers:

Register Role
CBSR1 buffer 1 start address
CBER1 buffer 1 end address
CBSR2 buffer 2 start address
CBER2 buffer 2 end address
CBCR 8-bit control register (enable bits and the AR selection)

To set up a buffer: load its start and end addresses into the CBSR/CBER pair, load an AR with a value inside that range, and set the matching enable bit in the CBCR. Do not enable the same AR for both buffers. On every AR modification the ARAU applies:

  if (ARn == CBER) and (any AR modification):
      ARn = CBSR            ; wrap to the start
  else:
      ARn = ARn + step      ; normal update (step may be negative)
    SPLK  #0200h, CBSR1     ; buffer 1: 0200h .. 0203h
    SPLK  #0203h, CBER1
    SPLK  #0Eh,   CBCR      ; enable AR6 on buffer 1
    LAR   AR6, #0203h
    LACC  *+                ; AR6 was at CBER, so it wraps: AR6 = 0200h

How c5xtools encodes these

c5xasm parses the operand forms above and emits the exact fields shown here: bit 7 selects direct vs indirect, the IDV/INC/DEC/N/NAR bits encode the * update and any next-AR, and short vs long immediate selection follows the instruction and the constant's width (with the reference assembler's short-to-long auto-promotion). c5xdis decodes the same fields back into these operand forms, which is why a disassembly re-assembles byte-for-byte. The operand-form matrix is exercised by the toolchain's conformance test against the TI golden objects.

License

MIT - (c) 2026 Grzegorz Worona [email protected]. See LICENSE.