4.1.4. Converting TI-syntax Assembly Macros into GNU-syntax Assembly Macros

If you are in the process of converting your TI-syntax Arm assembly source into GNU-syntax Arm assembly source and you utilize assembly language macros in your source code, then you will need to explicitly translate those TI-syntax macros into their GNU-syntax equivalent. This section of the migration guide will provide information about how to perform that translation.

4.1.4.1. Macro Directive and Macro Definitions

Both the legacy TI-syntax Arm assembler and the tiarmclang GNU-syntax Arm assembler support a .macro directive used to define an assembly macro, but the TI-syntax form of a macro definition is different from the GNU-syntax form.

Specifically, the TI-syntax form of the .macro directive and a macro definition looks like this:

<macro name> .macro [<parameter1>[, ..., <parameterN>]]
             <model assembly statements or macro-related directives>
             .endm

where:

  • <macro name> - is the name of the macro. After a macro has been defined, its name can then be used in the mnemonic field of an assembly statement to effect an invocation of the macro. For the TI-syntax form, the macro name must be specified in the label field of an assembly source statement prior to the .macro directive mnemonic.

  • .macro - is the assembly directive that identifies the assembly source statement as the first line of a macro definition. For the TI-syntax form, it must appear in the mnemonic field after the macro name.

  • <parameter(s)> - are optional identifiers that serve as vehicles for operand arguments that are passed into a macro when a macro is invoked. Each parameter takes on the value of the argument that is specified in the macro invocation at the corresponding operand position.

  • <model assembly statements> - are instructions or directives that are executed each time the macro is invoked.

  • <macro-related directives> - are assembly directives that can be used to manipulate the values that are maintained in the macro parameters.

  • .endm - is an assembler directive that delimits the end of the current macro definition.

The GNU-syntax form of a .macro directive and macro definition looks like this:

.macro <macro name>[, <parameter1>[, ..., <parameterN>]]
<model assembly statements>
.endm

where:

  • .macro - is the assembly directive that identifies the assembly source statement as the first line of a macro definition. For the GNU-syntax form, it must appear in the mnemonic field before the macro name.

  • <macro name> - is the name of the macro. After a macro has been defined, its name can then be used in the mnemonic field of an assembly statement to effect an invocation of the macro. For the GNU-syntax form, the macro name must be specified as the first operand of the .macro directive.

  • <parameter(s)> - are optional identifiers that serve as vehicles for operand arguments that are passed into a macro when a macro is invoked. Each parameter takes on the value of the argument that is specified in the macro invocation at the corresponding operand position. For the GNU-syntax form, the use of commas to separate operands of the .macro directive are optional as long as there is at least one blank space between each operand and the next.

  • <model assembly statements> - are instructions or directives that are executed each time the macro is invoked.

  • .endm - is an assembler directive that delimits the end of the current macro definition.

4.1.4.2. Referencing Macro Parameters and Local Labels

Within a macro definition, macro parameters can be referenced in the context of an assembly instruction, a directive, or an operand to an instruction or directive. In addition, local labels can be defined and referenced within the scope of a given macro definition.

Consider the definition of an assembly macro named COMPARE64 specified in TI-syntax form:

/* COMPARE64 macro definition - legacy TI-syntax
COMPARE64 .macro x_hi, x_lo, y_hi, y_lo
          CMP x_hi, y_hi
          BNE $?
          CMP x_lo, y_lo
$?:
          .endm

An invocation of the above COMPARE64 macro:

; COMPARE64 macro invocation
COMPARE64 r3, r2, r1, r0

will expand into the following sequence of assembly source:

; COMPARE64 macro invocation
          CMP r3, r1
          BNE $$1$
          CMP r2, r0
$$1$:

Note that the values passed in as argument operand to the macro invocation, in this case register names, get propagated to where the parameters are referenced in the context of the macro definition. Each reference to a parameter in the macro definition will expand to its corresponding argument value when the macro is expanded during invocation. The local label specification, indicated by “$?” within the macro definition expands to “$$1$” in the expansion of the macro.

If the macro definition is written in GNU-syntax form:

/* COMPARE64 macro definition - GNU-syntax
        .macro COMPARE64, x_hi, x_lo, y_hi, y_lo
        CMP \x_hi, \y_hi
        BNE .L_\@
        CMP \x_lo, \y_lo
.L_\@:
        .endm

you’ll notice that parameter references must be delimited with a leading backslash (’') character in the context of the macro definition. Similarly, the local label is indicated with “.L_@” in the macro definition where the “@” part of the label name instructs the assembler to generate a unique ID in place of the “@” when it is used in a label definition. The COMPARE64 macro can be invoked in the same way in both TI-syntax and GNU-syntax Arm assembly:

; COMPARE64 macro invocation
COMPARE64 r3, r2, r1, r0

and the GNU-syntax form of the macro expands into the following sequence of assembly source:

; COMPARE64 macro invocation
        CMP r3, r1
        BNE .L_0
        CMP r2, r0
.L_0:

4.1.4.2.1. Summary

To summarize, there are three major steps for converting a TI-syntax macro definition into a Gnu-syntax macro definition:

  1. Update .macro directive usage, moving the macro name from the label field to the first operand of the .macro directive

  2. Insert a leading backslash (’') in front of all parameter references within the scope of the macro definition

  3. Update local label references within the scope of the macro definition, replacing each ‘?’ with “@” and making sure that the prefix to the “@” forms a legal GNU-syntax label name