Xtensa Dependent Features
*************************

This chapter covers features of the GNU assembler that are specific to the Xtensa architecture.  For details about the Xtensa instruction set, please consult the Xtensa Instruction Set Architecture (ISA) Reference Manual.

Command Line Options
====================

The Xtensa version of the GNU assembler supports these special options:

--density | --no-density
     Enable or disable use of the Xtensa code density option (16-bit instructions).  See Using Density Instructions.  If the processor is configured with the density option, this is enabled by default; otherwise, it is always disabled.

--relax | --no-relax
     Enable or disable relaxation of instructions with immediate operands that are outside the legal range for the instructions.  See Xtensa Relaxation.  The default is --relax and this default should almost always be used.  If relaxation is disabled with --no-relax, instruction operands that are out of range will cause errors.  Note: In the current implementation, these options also control whether assembler optimizations are performed, making these options equivalent to --generics and --no-generics.

--generics | --no-generics
     Enable or disable all assembler transformations of Xtensa instructions, including both relaxation and optimization.  The default is --generics; --no-generics should only be used in the rare cases when the instructions must be exactly as specified in the assembly source. As with --no-relax, using --no-generics causes out of range instruction operands to be errors.

--text-section-literals | --no-text-section-literals
     Control the treatment of literal pools.  The default is --no-text-section-literals, which places literals in a separate section in the output file.  This allows the literal pool to be placed in a data RAM/ROM, and it also allows the linker to combine literal pools from separate object files to remove redundant literals and improve code size.  With --text-section-literals, the literals are interspersed in the text section in order to keep them as close as possible to their references.  This may be necessary for large assembly files.

--target-align | --no-target-align
     Enable or disable automatic alignment to reduce branch penalties at some expense in code size.  See Automatic Instruction Alignment.  This optimization is enabled by default.  Note that the assembler will always align instructions like LOOP that have fixed alignment requirements.

--longcalls | --no-longcalls
     Enable or disable transformation of call instructions to allow calls across a greater range of addresses.  See Function Call Relaxation.  This option should be used when call targets can potentially be out of range, but it degrades both code size and performance.  The default is --no-longcalls.

Assembler Syntax
================

Block comments are delimited by /* and */.  End of line comments may be introduced with either # or //.

Instructions consist of a leading opcode or macro name followed by whitespace and an optional comma-separated list of operands:

     OPCODE [OPERAND,...]

Instructions must be separated by a newline or semicolon.

Opcode Names
------------

See the Xtensa Instruction Set Architecture (ISA) Reference Manual for a complete list of opcodes and descriptions of their semantics.

The Xtensa assembler distinguishes between generic and specific opcodes.  Specific opcodes correspond directly to Xtensa machine instructions.  Prefixing an opcode with an underscore character (_) identifies it as a specific opcode.  Opcodes without a leading underscore are generic, which means the assembler is required to preserve their semantics but may not translate them directly to the specific opcodes with the same names.  Instead, the assembler may optimize a generic opcode and select a better instruction to use in its place (see Xtensa Optimizations), or the assembler may relax the instruction to handle operands that are out of range for the corresponding specific opcode (see Xtensa Relaxation).

Only use specific opcodes when it is essential to select the exact machine instructions produced by the assembler. Using specific opcodes unnecessarily only makes the code less efficient, by disabling assembler optimization, and less flexible, by disabling relaxation.

Note that this special handling of underscore prefixes only applies to Xtensa opcodes, not to either built-in macros or user-defined macros. When an underscore prefix is used with a macro (e.g., _NOP), it refers to a different macro.  The assembler generally provides built-in macros both with and without the underscore prefix, where the underscore versions behave as if the underscore carries through to the instructions in the macros.  For example, _NOP expands to _OR a1,a1,a1.

The underscore prefix only applies to individual instructions, not to series of instructions.  For example, if a series of instructions have underscore prefixes, the assembler will not transform the individual instructions, but it may insert other instructions between them (e.g., to align a LOOP instruction).  To prevent the assembler from modifying a series of instructions as a whole, use the no-generics directive.  See generics.

Register Names
--------------

An initial $ character is optional in all register names. General purpose registers are named a0...a15.  Additional registers may be added by processor configuration options.  In particular, the MAC16 option adds a MR register bank.  Its registers are named m0...m3.

As a special feature, sp is also supported as a synonym for a1.

Xtensa Optimizations
====================

The optimizations currently supported by AS are generation of density instructions where appropriate and automatic branch target alignment.

Using Density Instructions
--------------------------

The Xtensa instruction set has a code density option that provides 16-bit versions of some of the most commonly used opcodes.  Use of these opcodes can significantly reduce code size.  When possible, the assembler automatically translates generic instructions from the core Xtensa instruction set into equivalent instructions from the Xtensa code density option.  This translation can be disabled by using specific opcodes (see Opcode Names), by using the --no-density command-line option (see Command Line Options), or by using the no-density directive (see density).

It is a good idea not to use the density instuctions directly. The assembler will automatically select dense instructions where possible.  If you later need to avoid using the code density option, you can disable it in the assembler without having to modify the code.

Automatic Instruction Alignment
-------------------------------

The Xtensa assembler will automatically align certain instructions, both to optimize performance and to satisfy architectural requirements.

When the --target-align command-line option is enabled (see Command Line Options), the assembler attempts to widen density instructions preceding a branch target so that the target instruction does not cross a 4-byte boundary.  Similarly, the assembler also attempts to align each instruction following a call instruction.  If there are not enough preceding safe density instructions to align a target, no widening will be performed.  This alignment has the potential to reduce branch penalties at some expense in code size.  The assembler will not attempt to align labels with the prefixes .Ln and .LM, since these labels are used for debugging information and are not typically branch targets.

The LOOP family of instructions must be aligned on either a 1 or 2 mod 4 byte boundary.  The assembler knows about this restriction and inserts the minimal number of 2 or 3 byte no-op instructions to satisfy it.  When no-op instructions are added, any label immediately preceding the original loop will be moved in order to refer to the loop instruction, not the newly generated no-op instruction.

Similarly, the ENTRY instruction must be aligned on a 0 mod 4 byte boundary.  The assembler satisfies this requirement by inserting zero bytes when required.  In addition, labels immediately preceding the ENTRY instruction will be moved to the newly aligned instruction location.

Xtensa Relaxation
=================

When an instruction operand is outside the range allowed for that particular instruction field, AS can transform the code to use a functionally-equivalent instruction or sequence of instructions.  This process is known as relaxation.  This is typically done for branch instructions because the distance of the branch targets is not known until assembly-time.  The Xtensa assembler offers branch relaxation and also extends this concept to function calls, MOVI instructions and other instructions with immediate fields.

Conditional Branch Relaxation
-----------------------------

When the target of a branch is too far away from the branch itself, i.e., when the offset from the branch to the target is too large to fit in the immediate field of the branch instruction, it may be necessary to replace the branch with a branch around a jump.  For example,

         beqz    a2, L

may result in:

         bnez.n  a2, M
         j L
     M:

(The BNEZ.N instruction would be used in this example only if the density option is available.  Otherwise, BNEZ would be used.)

Function Call Relaxation
------------------------

Function calls may require relaxation because the Xtensa immediate call instructions (CALL0, CALL4, CALL8 and CALL12) provide a PC-relative offset of only 512 Kbytes in either direction.  For larger programs, it may be necessary to use indirect calls (CALLX0, CALLX4, CALLX8 and CALLX12) where the target address is specified in a register.  The Xtensa assembler can automatically relax immediate call instructions into indirect call instructions.  This relaxation is done by loading the address of the called function into the callee's return address register and then using a CALLX instruction.  So, for example:

         call8 func

might be relaxed to:

         .literal .L1, func
         l32r    a8, .L1
         callx8  a8

Because the addresses of targets of function calls are not generally known until link-time, the assembler must assume the worst and relax all the calls to functions in other source files, not just those that really will be out of range.  The linker can recognize calls that were unnecessarily relaxed, but it can only partially remove the overhead introduced by the assembler.

Call relaxation has a negative effect on both code size and performance, so this relaxation is disabled by default.  If a program is too large and some of the calls are out of range, function call relaxation can be enabled using the --longcalls command-line option or the longcalls directive (see longcalls).

Other Immediate Field Relaxation
--------------------------------

The MOVI machine instruction can only materialize values in the range from -2048 to 2047.  Values outside this range are best materalized with L32R instructions.  Thus:

         movi a0, 100000

is assembled into the following machine code:

         .literal .L1, 100000
         l32r a0, .L1

The L8UI machine instruction can only be used with immediate offsets in the range from 0 to 255. The L16SI and L16UI machine instructions can only be used with offsets from 0 to 510.  The L32I machine instruction can only be used with offsets from 0 to 1020.  A load offset outside these ranges can be materalized with an L32R instruction if the destination register of the load is different than the source address register.  For example:

         l32i a1, a0, 2040

is translated to:

         .literal .L1, 2040
         l32r a1, .L1
         addi a1, a0, a1
         l32i a1, a1, 0

If the load destination and source address register are the same, an out-of-range offset causes an error.

The Xtensa ADDI instruction only allows immediate operands in the range from -128 to 127.  There are a number of alternate instruction sequences for the generic ADDI operation.  First, if the immediate is 0, the ADDI will be turned into a MOV.N instruction (or the equivalent OR instruction if the code density option is not available).  If the ADDI immediate is outside of the range -128 to 127, but inside the range -32896 to 32639, an ADDMI instruction or ADDMI/ADDI sequence will be used.  Finally, if the immediate is outside of this range and a free register is available, an L32R/ADD sequence will be used with a literal allocated from the literal pool.

For example:

         addi    a5, a6, 0
         addi    a5, a6, 512
         addi    a5, a6, 513
         addi    a5, a6, 50000

is assembled into the following:

         .literal .L1, 50000
         mov.n   a5, a6
         addmi   a5, a6, 0x200
         addmi   a5, a6, 0x200
         addi    a5, a5, 1
         l32r    a5, .L1
         add     a5, a6, a5

Directives
==========

The Xtensa assember supports a region-based directive syntax:

         .begin DIRECTIVE [OPTIONS]
         ...
         .end DIRECTIVE

All the Xtensa-specific directives that apply to a region of code use this syntax.

The directive applies to code between the .begin and the .end.  The state of the option after the .end reverts to what it was before the .begin. A nested .begin/.end region can further change the state of the directive without having to be aware of its outer state.  For example, consider:

         .begin no-density
     L:  add a0, a1, a2
         .begin density
     M:  add a0, a1, a2
         .end density
     N:  add a0, a1, a2
         .end no-density

The generic ADD opcodes at L and N in the outer no-density region both result in ADD machine instructions, but the assembler selects an ADD.N instruction for the generic ADD at M in the inner density region.

The advantage of this style is that it works well inside macros which can preserve the context of their callers.

When command-line options and assembler directives are used at the same time and conflict, the one that overrides a default behavior takes precedence over one that is the same as the default.  For example, if the code density option is available, the default is to select density instructions whenever possible.  So, if the above is assembled with the --no-density flag, which overrides the default, all the generic ADD instructions result in ADD machine instructions.  If assembled with the --density flag, which is already the default, the no-density directive takes precedence and only one of the generic ADD instructions is optimized to be a ADD.N machine instruction.  An underscore prefix identifying a specific opcode always takes precedence over directives and command-line flags.

The following directives are available:

density
-------

The density and no-density directives enable or disable optimization of generic instructions into density instructions within the region.  See Using Density Instructions.

         .begin [no-]density
         .end [no-]density

This optimization is enabled by default unless the Xtensa configuration does not support the code density option or the --no-density command-line option was specified.

relax
-----

The relax directive enables or disables relaxation within the region.  See Xtensa Relaxation. Note: In the current implementation, these directives also control whether assembler optimizations are performed, making them equivalent to the generics and no-generics directives.

         .begin [no-]relax
         .end [no-]relax

Relaxation is enabled by default unless the --no-relax command-line option was specified.

longcalls
---------

The longcalls directive enables or disables function call relaxation.  See Function Call Relaxation.

         .begin [no-]longcalls
         .end [no-]longcalls

Call relaxation is disabled by default unless the --longcalls command-line option is specified.

generics
--------

This directive enables or disables all assembler transformation, including relaxation (see Xtensa Relaxation) and optimization (see Xtensa Optimizations).

         .begin [no-]generics
         .end [no-]generics

Disabling generics is roughly equivalent to adding an underscore prefix to every opcode within the region, so that every opcode is treated as a specific opcode.  See Opcode Names.  In the current implementation of AS, built-in macros are also disabled within a no-generics region.

literal
-------

The .literal directive is used to define literal pool data, i.e., read-only 32-bit data accessed via L32R instructions.

         .literal LABEL, VALUE[, VALUE...]

This directive is similar to the standard .word directive, except that the actual location of the literal data is determined by the assembler and linker, not by the position of the .literal directive.  Using this directive gives the assembler freedom to locate the literal data in the most appropriate place and possibly to combine identical literals.  For example, the code:

         entry sp, 40
         .literal .L1, sym
         l32r    a4, .L1

can be used to load a pointer to the symbol sym into register a4.  The value of sym will not be placed between the ENTRY and L32R instructions; instead, the assembler puts the data in a literal pool.

By default literal pools are placed in a separate section; however, when using the --text-section-literals option (see Command Line Options), the literal pools are placed in the current section.  These text section literal pools are created automatically before ENTRY instructions and manually after .literal_position directives (see literal_position).  If there are no preceding ENTRY instructions or .literal_position directives, the assembler will print a warning and place the literal pool at the beginning of the current section.  In such cases, explicit .literal_position directives should be used to place the literal pools.

literal_position
----------------

When using --text-section-literals to place literals inline in the section being assembled, the .literal_position directive can be used to mark a potential location for a literal pool.

         .literal_position

The .literal_position directive is ignored when the --text-section-literals option is not used.

The assembler will automatically place text section literal pools before ENTRY instructions, so the .literal_position directive is only needed to specify some other location for a literal pool.  You may need to add an explicit jump instruction to skip over an inline literal pool.

For example, an interrupt vector does not begin with an ENTRY instruction so the assembler will be unable to automatically find a good place to put a literal pool.  Moreover, the code for the interrupt vector must be at a specific starting address, so the literal pool cannot come before the start of the code.  The literal pool for the vector must be explicitly positioned in the middle of the vector (before any uses of the literals, of course).  The .literal_position directive can be used to do this.  In the following code, the literal for M will automatically be aligned correctly and is placed after the unconditional jump.

         .global M
     code_start:
         j continue
         .literal_position
         .align 4
     continue:
         movi    a4, M

literal_prefix
--------------

The literal_prefix directive allows you to specify different sections to hold literals from different portions of an assembly file. With this directive, a single assembly file can be used to generate code into multiple sections, including literals generated by the assembler.

         .begin literal_prefix [NAME]
         .end literal_prefix

For the code inside the delimited region, the assembler puts literals in the section NAME.literal. If this section does not yet exist, the assembler creates it.  The NAME parameter is optional. If NAME is not specified, the literal prefix is set to the ``default'' for the file.  This default is usually .literal but can be changed with the --rename-section command-line argument.

freeregs
--------

This directive tells the assembler that the given registers are unused in the region.

         .begin freeregs RI[,RI...]
         .end freeregs

This allows the assembler to use these registers for relaxations or optimizations.  (They are actually only for relaxations at present, but the possibility of optimizations exists in the future.)

Nested freeregs directives can be used to add additional registers to the list of those available to the assembler.  For example:

         .begin freeregs a3, a4
         .begin freeregs a5

has the effect of declaring a3, a4, and a5 all free.

frame
-----

This directive tells the assembler to emit information to allow the debugger to locate a function's stack frame.  The syntax is:

         .frame REG, SIZE

where REG is the register used to hold the frame pointer (usually the same as the stack pointer) and SIZE is the size in bytes of the stack frame.  The .frame directive is typically placed immediately after the ENTRY instruction for a function.

In almost all circumstances, this information just duplicates the information given in the function's ENTRY instruction; however, there are two cases where this is not true:

 1. The size of the stack frame is too big to fit in the immediate field of the ENTRY instruction.

 2. The frame pointer is different than the stack pointer, as with functions that call alloca.