SLAA534A June   2013  – June 2020

 

  1. Introduction
    1. 1.1  ABIs for the MSP430
    2. 1.2  Scope
    3. 1.3  ABI Variants
    4. 1.4  Toolchains and Interoperability
    5. 1.5  Libraries
    6. 1.6  Types of Object Files
    7. 1.7  Segments
    8. 1.8  MSP430 Architecture Overview
    9. 1.9  MSP430 Memory Models
    10. 1.10 Reference Documents
    11. 1.11 Code Fragment Notation
  2. Data Representation
    1. 2.1 Basic Types
    2. 2.2 Data in Registers
    3. 2.3 Data in Memory
    4. 2.4 Pointer Types
    5. 2.5 Complex Types
    6. 2.6 Structures and Unions
    7. 2.7 Arrays
    8. 2.8 Bit Fields
      1. 2.8.1 Volatile Bit Fields
    9. 2.9 Enumeration Types
  3. Calling Conventions
    1. 3.1 Call and Return
      1. 3.1.1 Call Instructions
        1. 3.1.1.1 Indirect Calls
        2. 3.1.1.2 Direct Calls
      2. 3.1.2 Return Instruction
      3. 3.1.3 Pipeline Conventions
      4. 3.1.4 Weak Functions
    2. 3.2 Register Conventions
      1. 3.2.1 Argument Registers
      2. 3.2.2 Callee-Saved Registers
    3. 3.3 Argument Passing
      1. 3.3.1 Register Singles
      2. 3.3.2 Register Pairs
      3. 3.3.3 Split Pairs
      4. 3.3.4 Quads (Four-Register Arguments)
      5. 3.3.5 Special Convention for Compiler Helper Functions
      6. 3.3.6 C++ Argument Passing
      7. 3.3.7 Passing Structs and Unions
      8. 3.3.8 Stack Layout of Arguments Not Passed in Registers
      9. 3.3.9 Frame Pointer
    4. 3.4 Return Values
    5. 3.5 Structures and Unions Passed and Returned by Reference
    6. 3.6 Conventions for Compiler Helper Functions
    7. 3.7 Scratch Registers for Functions Already Seen
    8. 3.8 _ _mspabi_func_epilog Helper Functions
    9. 3.9 Interrupt Functions
  4. Data Allocation and Addressing
    1. 4.1 Data Sections and Segments
    2. 4.2 Addressing Modes
    3. 4.3 Allocation and Addressing of Static Data
      1. 4.3.1 Addressing Methods for Static Data
        1. 4.3.1.1 Absolute Addressing
        2. 4.3.1.2 Symbolic Addressing
        3. 4.3.1.3 Immediate Addressing
      2. 4.3.2 Placement Conventions for Static Data
        1. 4.3.2.1 Abstract Conventions for Placement
        2. 4.3.2.2 Abstract Conventions for Addressing
      3. 4.3.3 Initialization of Static Data
    4. 4.4 Automatic Variables
    5. 4.5 Frame Layout
      1. 4.5.1 Stack Alignment
      2. 4.5.2 Register Save Order
    6. 4.6 Heap-Allocated Objects
  5. Code Allocation and Addressing
    1. 5.1 Computing the Address of a Code Label
      1. 5.1.1 Absolute Addressing for Code
      2. 5.1.2 Symbolic Addressing
      3. 5.1.3 Immediate Addressing
    2. 5.2 Branching
    3. 5.3 Calls
      1. 5.3.1 Direct Call
      2. 5.3.2 Far Call Trampoline
      3. 5.3.3 Indirect Calls
  6. Helper Function API
    1. 6.1 Floating-Point Behavior
    2. 6.2 C Helper Function API
    3. 6.3 Special Register Conventions for Helper Functions
    4. 6.4 Floating-Point Helper Functions for C99
  7. Standard C Library API
    1. 7.1  Reserved Symbols
    2. 7.2  <assert.h> Implementation
    3. 7.3  <complex.h> Implementation
    4. 7.4  <ctype.h> Implementation
    5. 7.5  <errno.h> Implementation
    6. 7.6  <float.h> Implementation
    7. 7.7  <inttypes.h> Implementation
    8. 7.8  <iso646.h> Implementation
    9. 7.9  <limits.h> Implementation
    10. 7.10 <locale.h> Implementation
    11. 7.11 <math.h> Implementation
    12. 7.12 <setjmp.h> Implementation
    13. 7.13 <signal.h> Implementation
    14. 7.14 <stdarg.h> Implementation
    15. 7.15 <stdbool.h> Implementation
    16. 7.16 <stddef.h> Implementation
    17. 7.17 <stdint.h> Implementation
    18. 7.18 <stdio.h> Implementation
    19. 7.19 <stdlib.h> Implementation
    20. 7.20 <string.h> Implementation
    21. 7.21 <tgmath.h> Implementation
    22. 7.22 <time.h> Implementation
    23. 7.23 <wchar.h> Implementation
    24. 7.24 <wctype.h> Implementation
  8. C++ ABI
    1. 8.1  Limits (GC++ABI 1.2)
    2. 8.2  Export Template (GC++ABI 1.4.2)
    3. 8.3  Data Layout (GC++ABI Chapter 2)
    4. 8.4  Initialization Guard Variables (GC++ABI 2.8)
    5. 8.5  Constructor Return Value (GC++ABI 3.1.5)
    6. 8.6  One-Time Construction API (GC++ABI 3.3.2)
    7. 8.7  Controlling Object Construction Order (GC++ ABI 3.3.4)
    8. 8.8  Demangler API (GC++ABI 3.4)
    9. 8.9  Static Data (GC++ ABI 5.2.2)
    10. 8.10 Virtual Tables and the Key function (GC++ABI 5.2.3)
    11. 8.11 Unwind Table Location (GC++ABI 5.3)
  9. Exception Handling
    1. 9.1  Overview
    2. 9.2  PREL31 Encoding
    3. 9.3  The Exception Index Table (EXIDX)
      1. 9.3.1 Pointer to Out-of-Line EXTAB Entry
      2. 9.3.2 EXIDX_CANTUNWIND
      3. 9.3.3 Inlined EXTAB Entry
    4. 9.4  The Exception Handling Instruction Table (EXTAB)
      1. 9.4.1 EXTAB Generic Model
      2. 9.4.2 EXTAB Compact Model
      3. 9.4.3 Personality Routines
    5. 9.5  Unwinding Instructions
      1. 9.5.1 Common Sequence
      2. 9.5.2 Byte-Encoded Unwinding Instructions
    6. 9.6  Descriptors
      1. 9.6.1 Encoding of Type Identifiers
      2. 9.6.2 Scope
      3. 9.6.3 Cleanup Descriptor
      4. 9.6.4 Catch Descriptor
      5. 9.6.5 Function Exception Specification (FESPEC) Descriptor
    7. 9.7  Special Sections
    8. 9.8  Interaction With Non-C++ Code
      1. 9.8.1 Automatic EXIDX Entry Generation
      2. 9.8.2 Hand-Coded Assembly Functions
    9. 9.9  Interaction With System Features
      1. 9.9.1 Shared Libraries
      2. 9.9.2 Overlays
      3. 9.9.3 Interrupts
    10. 9.10 Assembly Language Operators in the TI Toolchain
  10. 10DWARF
    1. 10.1 DWARF Register Names
    2. 10.2 Call Frame Information
    3. 10.3 Vendor Names
    4. 10.4 Vendor Extensions
  11. 11ELF Object Files (Processor Supplement)
    1. 11.1 Registered Vendor Names
    2. 11.2 ELF Header
    3. 11.3 Sections
      1. 11.3.1 Section Indexes
      2. 11.3.2 Section Types
      3. 11.3.3 Extended Section Header Attributes
      4. 11.3.4 Subsections
      5. 11.3.5 Special Sections
      6. 11.3.6 Section Alignment
    4. 11.4 Symbol Table
      1. 11.4.1 Symbol Types
      2. 11.4.2 Common Block Symbols
      3. 11.4.3 Symbol Names
      4. 11.4.4 Reserved Symbol Names
      5. 11.4.5 Mapping Symbols
    5. 11.5 Relocation
      1. 11.5.1 Relocation Types
        1. 11.5.1.1 Absolute Relocations
        2. 11.5.1.2 PC-Relative Relocations
        3. 11.5.1.3 Relocations in Data Sections
        4. 11.5.1.4 Relocations for MSP430 Instructions
        5. 11.5.1.5 Relocations for MSP430X Instructions
        6. 11.5.1.6 Other Relocation Types
      2. 11.5.2 Relocation Operations
      3. 11.5.3 Relocation of Unresolved Weak References
  12. 12ELF Program Loading and Linking (Processor Supplement)
    1. 12.1 Program Header
      1. 12.1.1 Base Address
      2. 12.1.2 Segment Contents
      3. 12.1.3 Thread-Local Storage
    2. 12.2 Program Loading
  13. 13Build Attributes
    1. 13.1 MSP430 ABI Build Attribute Subsection
    2. 13.2 MSP430 Build Attribute Tags
  14. 14Copy Tables and Variable Initialization
    1. 14.1 Copy Table Format
    2. 14.2 Compressed Data Formats
      1. 14.2.1 RLE
      2. 14.2.2 LZSS Format
    3. 14.3 Variable Initialization
  15. 15Revision History

C Helper Function API

The compiler generates calls to helper functions to perform operations that need to be supported by the compiler, but are not supported directly by the architecture, such as floating-point operations on devices that lack dedicated hardware. These helper functions must be implemented in the RTS library of any toolchain that conforms to the ABI.

Helper functions are named using the prefix _ _MSP430_. Any identifier with this prefix is reserved for the ABI.

The helper functions adhere to the standard calling conventions, except as indicated in Section 6.4.

The following tables specify the helper functions using C notation and syntax. The types in the table correspond to the generic data types specified in Section 2.2.

The functions in Table 6-1 convert between various floating-point and integer formats, in accordance with C's conversion rules and the floating-point behavior specified by Section 6.2.

Table 6-1 MSP430 Floating-Point and Integer Conversions
SignatureDescription
float32 _ _MSP430_cvtdf(float64 x);Convert double-precision float to single-precision float
float64 _ _MSP430_cvtfd(float32 x);Convert single-precision float to double-precision float
int16 _ _MSP430_fixdi(float64 x);Convert double-precision float to int
int32 _ _MSP430_fixdli(float64 x);Convert double-precision float to long int
int64 _ _MSP430_fixdlli(float64 x);Convert double-precision float to long long int
uint16 _ _MSP430_fixdu(float64 x);Convert double-precision float to unsigned int
uint32 _ _MSP430_fixdul(float64 x);Convert double-precision float to unsigned long int
uint64 _ _MSP430_fixdull(float64 x);Convert double-precision float to unsigned long long int
int16 _ _MSP430_fixfi(float32 x);Convert single-precision float to int
int32 _ _MSP430_fixfli(float32 x);Convert single-precision float to long int
int64 _ _MSP430_fixflli(float32 x);Convert single-precision float to long long int
uint16 _ _MSP430_fixfu(float32 x);Convert single-precision float to unsigned int
uint32 _ _MSP430_fixful(float32 x);Convert single-precision float to unsigned long int
uint64 _ _MSP430_fixfull(float32 x);Convert single-precision float to unsigned long long int
float64 _ _MSP430_fltid(int16 x);Convert int to double-precision float
float32 _ _MSP430_fltif(int16 x);Convert int to single-precision float
float64 _ _MSP430_fltlid(int32 x);Convert long int to double-precision float
float32 _ _MSP430_fltlif(int32 x);Convert long int to single-precision float
float64 _ _MSP430_fltud(uint16 x);Convert unsigned int to double-precision float
float32 _ _MSP430_fltuf(uint16 x);Convert unsigned int to single-precision float
float64 _ _MSP430_fltuld(uint32 x);Convert unsigned long int to double-precision float
float32 _ _MSP430_fltulf(uint32 x);Convert unsigned long int to single-precision float

The functions in Table 6-2 perform floating-point comparisons in accordance with C semantics and the floating-point behavior specified by Section 6.2.

The _ _MSP430_cmp functions return an integer less than 0 if x is less than y, 0 if the values are equal, or an integer greater than 0 of x is greater than y. If either operand is NaN, the result is undefined.

The remaining comparison functions are currently unsupported, but the names are reserved for possible future use.

Table 6-2 MSP430 Floating-Point Comparisons
SignatureDescription
int16 _ _MSP430_cmpd(float64 x, float64 y);Double-precision comparison
int16 _ _MSP430_cmpf(float32 x, float32 y);Single-precision comparison
int16 _ _MSP430_eqd(float64 x, float64 y);Double-precision comparison: x == y (Not currently supported)
int16 _ _MSP430_geqdfloat64 x, float64 y);Double-precision comparison: x >= y (Not currently supported)
int16 _ _MSP430_gtrd(float64 x, float64 y);Double-precision comparison: x > y (Not currently supported)
int16 _ _MSP430_leqd(float64 x, float64 y);Double-precision comparison: x <= y (Not currently supported)
int16 _ _MSP430_lssd(float64 x, float64 y);Double-precision comparison: x < y (Not currently supported)
int16 _ _MSP430_neqd(float64 x, float64 y);Double-precision comparison: x != y (Not currently supported)

The functions in Table 6-3 perform floating-point arithmetic in accordance with C semantics and the floating-point behavior specified by Section 6.2.

Table 6-3 MSP430 Floating-Point Arithmetic
SignatureDescription
float64 _ _MSP430_addd(float64 x, float64 y);Add double-precision to double-precision
float32 _ _MSP430_addf(float32 x, float32 y);Add single-precision to single-precision
float64 _ _MSP430_divd(float64 x, float64 y);Divide double-precision by double-precision
float32 _ _MSP430_divf(float32 x, float32 y);Divide single-precision by single-precision
float64 _ _MSP430_mpyd(float64 x, float64 y);Multiply double-precision by double-precision
float32 _ _MSP430_mpyf(float32 x, float32 y);Multiply single-precision by single-precision
float64 _ _MSP430_subd(float64 x, float64 y);Subtract double-precision from double-precision
float32 _ _MSP430_subf(float32 x, float32 y);Subtract single-precision from single-precision
float64 _ _MSP430_negd(float64 x);Negate double-precision
float32 _ _MSP430_negf(float32 x);Negate single-precision

The integer arithmetic functions in Table 6-4 operate according to C semantics.

Table 6-4 MSP430 Integer Multiply, Divide, and Remainder
Signature Description
Multiplication
int16 _ _MSP430_mpyi(int16 x, int16 y); Multiply int by int.
int16 _ _MSP430_mpyi_hw(int16 x, int16 y); Multiply int by int. Uses hardware MPY16.
int16 _ _MSP430_mpyi_f5hw(int16 x, int16 y); Multiply int by int. Uses hardware MPY32 (F5xx devices and up).
int32 _ _MSP430_mpyl(int32 x, int32 y); Multiply long by long.
int32 _ _MSP430_mpyl_hw(int32 x, int32 y); Multiply long by long. Uses hardware MPY16.
int32 _ _MSP430_mpyl_hw32(int32 x, int32 y); Multiply long by long. Uses hardware MPY32 (F4xx devices).
int32 _ _MSP430_mpyl_f5hw(int32 x, int32 y); Multiply long by long. Uses hardware MPY32 (F5xx devices and up).
int64 _ _MSP430_mpyll(int64 x, int64 y); Multiply long long by long long.
int64 _ _MSP430_mpyll_hw(int64 x, int64 y); Multiply long long by long long. Uses hardware MPY16.
int64 _ _MSP430_mpyll_hw32(int64 x, int64 y); Multiply long long by long long. Uses hardware MPY32 (F4xx devices).
int64 _ _MSP430_mpyll_f5hw(int64 x, int64 y); Multiply long long by long long. Uses hardware MPY32 (F5xx devices and up).
int32 _ _MSP430_mpysl(int16 x, int16 y); Multiply int by int; result is long.
int32 _ _MSP430_mpysl_hw(int16 x, int16 y); Multiply int by int; result is long. Uses hardware MPY16.
int32 _ _MSP430_mpysl_f5hw(int16 x, int16 y); Multiply int by int; result is long. Uses hardware MPY32 (F5xx devices and up).
int64 _ _MSP430_mpysll(int32 x, int32 y); Multiply long by long; result is long long.
int64 _ _MSP430_mpysll_hw(int32 x, int32 y); Multiply long by long; result is long long. Uses hardware MPY16.
int64 _ _MSP430_mpysll_hw32(int32 x, int32 y); Multiply long by long; result is long long. Uses hardware MPY32 (F4xx devices).
int64 _ _MSP430_mpysll_f5hw(int32 x, int32 y); Multiply long by long; result is long long. Uses hardware MPY32 (F5xx devices and up).
uint32 _ _MSP430_mpyul(uint16 x, uint16 y); Multiply unsigned int by unsigned int; result is unsigned long.
uint32 _ _MSP430_mpyul_hw(uint16 x, uint16 y); Multiply unsigned int by unsigned int; result is unsigned long. Uses hardware MPY16.
uint32 _ _MSP430_mpyul_f5hw(uint16 x, uint16 y); Multiply unsigned int by unsigned int; result is unsigned long. Uses hardware MPY32 (F5xx devices and up).
uint64 _ _MSP430_mpyull(uint32 x, uint32 y); Multiply unsigned long by unsigned long; result is unsigned long long.
uint64 _ _MSP430_mpyull_hw(uint32 x, uint32 y); Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY16.
uint64 _ _MSP430_mpyull_hw32(uint32 x, uint32 y); Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F4xx devices).
uint64 _ _MSP430_mpyull_f5hw(uint32 x, uint32 y); Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F5xx devices and up).
Division
int16 _ _MSP430_divi(int16 x, int16 y); Divide int by int.
int32 _ _MSP430_divli(int32 x, int32 y); Divide long by long.
int64 _ _MSP430_divlli(int64 x, int64 y); Divide long long by long long.
uint16 _ _MSP430_divu(uint16 x, uint16 y); Divide unsigned lint by unsigned lint.
uint32 _ _MSP430_divlu(uint32 x, uint32 y); Divide unsigned long by unsigned long.
uint64 _ _MSP430_divllu(uint64 x, uint64 y); Divide unsigned long long by unsigned long long.
Remainder (Modulus)
int16 _ _MSP430_remi(int16 x, int16 y); Remainder of int divided by int (x mod y)
int32 _ _MSP430_remli(int32 x, int32 y); Remainder of long divided by long (x mod y)
int64 _ _MSP430_remlli(int64x. int64 y); Remainder of long long divided by long long (x mod y)
uint16 _ _MSP430_remu(uint16 x, uint16 y); Remainder of unsigned int divided by unsigned int (x mod y)
uint32 _ _MSP430_remul(uint32, uint32); Remainder of unsigned long divided by unsigned long (x mod y)
uint64 _ _MSP430_remull(uint64, uint64); Remainder of unsigned long long divided by unsigned long long (x mod y)

The bitwise operator functions are listed in Table 6-5. These functions are used by MSP430 and MSP430X.

Rotate left operations are performed with no carry. The most-significant bit is moved to the least-significant bit (LSB), and all other bits are shifted left. There is no rotation function for the long long data type.

Logical left shift operations are the same as an arithmetic left shift; a zero is shifted into the LSB.

Arithmetic right shift operations shift the most-significant bit (MSB), to the right and copy the old MSB into the new MSB. This preserves the sign in a signed value. The LSB is discarded.

Logical right shift operations insert a value of 0 in the MSB and discard the LSB.

The shift or rotation count in functions that accept a second argument may not be less than zero, even though it is handled as a signed int.

Table 6-5 MSP430 / MSP430X Bitwise Operations
SignatureDescription
Rotation
uint16 _ _MSP430_rlli(uint16 x, int16 n);Rotate bits of an int left by n bits, where n can be up to 16.
uint16 _ _MSP430_rlli_1(uint16 x);
. . .
uint16 _ _MSP430_rlli_15(uint16 x);
Rotate bits of an int left by specified number of bits.
uint32 _ _MSP430_rlll(uint32 x, int16 n);Rotate bits of a long left by n bits, where n can be up to 32.
Logical Left Shift
uint16 _ _MSP430_slli(uint16 x, int16 n);Perform a logical left shift on an int. Shift by n bits, where n can be up to 16.
uint16 _ _MSP430_slli_1(uint16 x);
. . .
uint16 _ _MSP430_slli_15(uint16 x);
Perform a logical left shift on an int. Shift left by specified number of bits.
uint32 _ _MSP430_slll(uint32 x, int16 n);Perform a logical left shift on a long. Shift by n bits, where n can be up to 32.
uint32 _ _MSP430_slll_1(uint32 x);
. . .
uint32 _ _MSP430_slll_15(uint32 x);
Perform a logical left shift on a long. Shift left by specified number of bits. Shift counts above 15 use _ _MSP430_slll.
uint64 _ _MSP430_sllll(uint64 x, int16 n);Perform a logical left shift on a long long. Shift by n bits, where n can be up to 64.
Arithmetic Right Shift
int16 _ _MSP430_srai(int16 x, int16 n);Perform an arithmetic right shift on an int. Shift by n bits, where n can be up to 16.
int16 _ _MSP430_srai_1(int16 x);
. . .
int32 _ _MSP430_srai_15(int16 x);
Perform an arithmetic right shift on an int. Shift by specified number of bits.
int16 _ _MSP430_sral(int32 x, int16 n);Perform an arithmetic right shift on a long. Shift by n bits, where n can be up to 32.
int32 _ _MSP430_sral_1(int32 x);
. . .
int32 _ _MSP430_sral_15(int32 x);
Perform an arithmetic right shift on a long. Shift by specified number of bits. Shift counts above 15 use _ _MSP430_sral.
int64 _ _MSP430_srall(int64 x, int16 n);Perform an arithmetic right shift on a long long. Shift by n bits, where n can be up to 64.
Logical Right Shift
uint16 _ _MSP430_srli(uint16 x, int16 n);Perform a logical right shift on an int. Shift by n bits, where n can be up to 16.
uint16 _ _MSP430_srli_1(uint16 x);
. . .
uint16 _ _MSP430_srli_15(uint16 x);
Perform a logical right shift on an int. Shift right by specified number of bits.
uint32 _ _MSP430_srll(uint32 x, int16 n);Perform a logical right shift on a long. Shift by n bits, where n can be up to 32.
uint32 _ _MSP430_srll_1(uint32 x);
. . .
uint32 _ _MSP430_srll_15(uint32 x);
Perform a logical right shift on a long. Shift right by specified number of bits. Shift counts above 15 use _ _MSP430_srll.
uint64 _ _MSP430_srlll(uint64 x, int16 n);Perform a logical right shift on a long long. Shift by n bits, where n can be up to 64.

The helper functions in Table 6-6 optimize restoring callee-saved registers. These functions are used by MSP430, but not MSP430X .

Table 6-6 MSP430 Epilog Helper Functions
SignatureDescription
void _ _MSP430_epilog_1(void);POP R10 and return.
void _ _MSP430_epilog_2(void);POP R10 through R9 and return.
void _ _MSP430_epilog_3(void);POP R10 through R8 and return.
void _ _MSP430_epilog_4(void);POP R10 through R7 and return.
void _ _MSP430_epilog_5(void);POP R10 through R6 and return.
void _ _MSP430_epilog_6(void);POP R10 through R5 and return.
void _ _MSP430_epilog_7(void);POP R10 through R4 and return.

The miscellaneous helper functions in Table 6-7 are described in the sections that follow.

Table 6-7 MSP430 Miscellaneous Helper Functions
SignatureDescription
void _abort_msg(const char *string);Report failed assertion

_abort_msg

The function _abort_msg is generated to print a diagnostic message when a run-time assertion (for example, the C assert macro) fails. It must not return. That is, it must call abort or terminate the program by other means.