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

Legal
=====

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

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.

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 these 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.

Extensions
==========

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

.arm
     Generate 32-bit ARM code.

.thumb
     Generate 16-bit THUMB code.

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.

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

Some known problems of this module at the moment:

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

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 expected

  - 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