This chapter documents the backend for the Advanced RISC Machine (ARM)
microprocessor family.

1 Legal
=======

This module is written in 2004,2006,2010-2015 by Frank Wille and is
covered by the vasm copyright without modifications.

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

This module provides the following additional options:

'-a2'
     Generate code compatible with ARM V2 architecture.

'-a3'
     Generate code compatible with ARM V3 architecture.

'-a3m'
     Generate code compatible with ARM V3m architecture.

'-a4'
     Generate code compatible with ARM V4 architecture.

'-a4t'
     Generate code compatible with ARM V4t architecture.

'-big'
     Output big-endian code and data.

'-little'
     Output little-endian code and data (default).

'-m2'
     Generate code for the ARM2 CPU.

'-m250'
     Generate code for the ARM250 CPU.

'-m3'
     Generate code for the ARM3 CPU.

'-m6'
     Generate code for the ARM6 CPU.

'-m600'
     Generate code for the ARM600 CPU.

'-m610'
     Generate code for the ARM610 CPU.

'-m7'
     Generate code for the ARM7 CPU.

'-m710'
     Generate code for the ARM710 CPU.

'-m7500'
     Generate code for the ARM7500 CPU.

'-m7d'
     Generate code for the ARM7d CPU.

'-m7di'
     Generate code for the ARM7di CPU.

'-m7dm'
     Generate code for the ARM7dm CPU.

'-m7dmi'
     Generate code for the ARM7dmi CPU.

'-m7tdmi'
     Generate code for the ARM7tdmi CPU.

'-m8'
     Generate code for the ARM8 CPU.

'-m810'
     Generate code for the ARM810 CPU.

'-m9'
     Generate code for the ARM9 CPU.

'-m9'
     Generate code for the ARM9 CPU.

'-m920'
     Generate code for the ARM920 CPU.

'-m920t'
     Generate code for the ARM920t CPU.

'-m9tdmi'
     Generate code for the ARM9tdmi CPU.

'-msa1'
     Generate code for the SA1 CPU.

'-mstrongarm'
     Generate code for the STRONGARM CPU.

'-mstrongarm110'
     Generate code for the STRONGARM110 CPU.

'-mstrongarm1100'
     Generate code for the STRONGARM1100 CPU.

'-opt-adr'
     The 'ADR' directive will be automatically converted into 'ADRL' if
     required (which inserts an additional 'ADD'/'SUB' to calculate an
     address).

'-opt-ldrpc'
     The maximum range in which PC-relative symbols can be accessed
     through 'LDR' and 'STR' is extended from +/-4KB to +/-1MB (or
     +/-256 Bytes to +/-65536 Bytes when accessing half-words).  This is
     done by automatically inserting an additional 'ADD' or 'SUB'
     instruction before the 'LDR'/'STR'.

'-thumb'
     Start assembling in Thumb mode.

3 General
=========

This backend accepts ARM instructions as described in various ARM CPU
data sheets.  Additionally some architectures support a second, more
dense, instruction set, called THUMB. There are special directives to
switch between those two instruction sets.

   The target address type is 32bit.

   Default alignment for instructions is 4 bytes for ARM and 2 bytes for
THUMB. Sections will be aligned to 4 bytes by default.  Data is aligned
to its natural alignment by default.

4 Extensions
============

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

'.arm'
     Generate 32-bit ARM code.

'.thumb'
     Generate 16-bit THUMB code.

5 Optimizations
===============

This backend performs the following optimizations and translations for
the ARM instruction set:

   - 'LDR/STR Rd,symbol', with a distance between symbol and PC larger
     than 4KB, is translated to 'ADD/SUB Rd,PC,#offset&0xff000' +
     'LDR/STR Rd,[Rd,#offset&0xfff]', when allowed by the option
     '-opt-ldrpc'.

   - 'ADR Rd,symbol' is translated to 'ADD/SUB Rd,PC,#rotated_offset8'.

   - 'ADRL Rd,symbol' is translated to 'ADD/SUB Rd,PC,#hi_rotated8' +
     'ADD/SUB Rd,Rd,#lo_rotated8'.  'ADR' will be automatically treated
     as 'ADRL' when required and when allowed by the option '-opt-adr'.

   - The immediate operand of ALU-instructions will be translated into
     the appropriate 8-bit-rotated value.  When rotation alone doesn't
     succeed the backed will try it with inverted and negated values
     (inverting/negating the ALU-instruction too).  Optionally you may
     specify the rotate constant yourself, as an additional operand.

   For the THUMB instruction set the following optimizations and
translations are done:

   - A conditional branch with a branch-destination being out of range
     is translated into 'B<!cc> .+4' + 'B label'.

   - The 'BL' instruction is translated into two sub-instructions
     combining the high- and low 22 bit of the branch displacement.

6 Known Problems
================

Some known problems of this module at the moment:

   - Only instruction sets up to ARM architecture V4t are supported.

7 Error Messages
================

This module has the following error messages:

   - 2001: instruction not supported on selected architecture
   - 2002: trailing garbage in operand
   - 2003: label from current section required
   - 2004: branch offset (%ld) is out of range
   - 2005: PC-relative load/store (offset %ld) out of range
   - 2006: cannot make rotated immediate from PC-relative offset (0x%lx)
   - 2007: constant integer expression required
   - 2008: constant (0x%lx) not suitable for 8-bit rotated immediate
   - 2009: branch to an unaligned address (offset %ld)
   - 2010: not a valid ARM register
   - 2011: PC (r15) not allowed in this mode
   - 2012: PC (r15) not allowed for offset register Rm
   - 2013: PC (r15) not allowed with write-back
   - 2014: register r%ld was used multiple times
   - 2015: illegal immediate shift count (%ld)
   - 2016: not a valid shift register
   - 2017: 24-bit unsigned immediate expected
   - 2018: data size %d not supported
   - 2019: illegal addressing mode: %s
   - 2020: signed/halfword ldr/str doesn't support shifts
   - 2021: %d-bit immediate offset out of range (%ld)
   - 2022: post-indexed addressing mode exptected
   - 2023: operation not allowed on external symbols
   - 2024: ldc/stc offset has to be a multiple of 4
   - 2025: illegal coprocessor operation mode or type: %ld\n
   - 2026: %d-bit unsigned immediate offset out of range (%ld)
   - 2027: offset has to be a multiple of %d
   - 2028: instruction at unaligned address
   - 2029: TSTP/TEQP/CMNP/CMPP deprecated on 32-bit architectures
   - 2030: rotate constant must be an even number between 0 and 30: %ld
   - 2031: %d-bit unsigned constant required: %ld

