This chapter documents the backend for the SONY SPC700 CPU.

Legal
=====

This module is written in 2025 by Frank Wille and is covered by the vasm copyright without modifications.

Additional options for this module
==================================

This module provides the following additional options:

-am
     Automatically mask values to match their data size or the size of immediate addressing, which effectively disables any range checks on immediate and data values in the assembler and linker.

-dpo
     Generate 8-bit offset instead of absolute relocations when accessing a zero- or direct-page symbol.

-opt-branch
     Enables translation of B<cc> branches into sequences of B<!cc> *+5 ; JMP label when necessary. BRA is directly translated into a JMP when out of range. It also performs optimization of JMP to BRA, whenever possible.

General
=======

This backend accepts SPC700 instructions using the official names and syntax as provided by Sony.

The target address type is 16 bits.

Instructions consist of one up to three bytes and require no alignment. There is also no alignment requirement for sections and data.

Extensions
==========

This backend provides the following specific extensions:

  - Immediate addressing mode operands and data directives allow bitstream selector prefixes as the first character in the operand. < selects the least significant bits which fit into the current immediate or data field width (AKA low-byte for 8-bit data). > selects the same, but shifts the value right by 8 bits first (AKA high-byte for 8-bit data).

  - The prefix character ? can be used in immediate addressing modes and data directives to retrieve a symbol's memory/bank ID. Note, that this feature depends on a special relocation type, which is only supported by vlink and requires the VOBJ format.

  - The prefix character ! can be used to enforce 16-bit addressing modes. Otherwise the assembler tries to optimize operands to direct page (8-bit) addressing whenever possible.

This backend extends the selected syntax module by the following directives:

<symbol> equd <expr>
     Works exactly like the equ directive, but marks <symbol> as a direct page symbol and use direct page addressing whenever <symbol> is used in a memory addressing mode.

p0
     Informs the assembler about the current state of the P flag. P0 assumes the direct page to reside at $0000 (default). This information is used to decide whether absolute address references can be optimized to direct page addressing modes.

p1
     Informs the assembler about the current state of the P flag. P1 assumes the direct page to reside at $0100. This information is used to decide whether absolute address references can be optimized to direct page addressing modes.

direct
     Switch to a direct page section called direct or .direct, which has the type bss with attributes "aurwz". Accesses to symbols from this section will default to direct page addressing mode.

dpage <symbol1> [,<symbol2>...]
     Mark symbols as direct page and use direct page addressing for expressions based on this symbol, unless overridden by the addressing mode selector !.

All these directives are also available in the form starting with a dot (.).

Optimizations
=============

This backend performs the following operand optimizations and translations:

  - Absolute addressing modes are optimized to direct-page addressing modes, whenever possible.

  - Conditional branches, where the destination is out of range, are translated into B<!cc> *+5 and an absolute JMP instruction (-opt-branch).

  - JMP may be optimized to BRA, when -opt-branch was given.

Known Problems
==============

Some known problems of this module at the moment:

  - None?

Error Messages
==============

This module has the following error messages:

  - 2001: instruction not supported on selected architecture

  - 2002: trailing garbage in operand

  - 2003: selector prefix ignored

  - 2004: data size %d not supported

  - 2005: operand doesn't fit into %d bits

  - 2006: branch destination out of range

  - 2007: illegal bit number

  - 2008: identifier expected

  - 2009: operand not in direct-page range

  - 2010: unsuitable addressing mode for retrieving memory id

  - 2011: no memory id defined, assuming 0