1.3.4. Runtime Model Options

-fexceptions, -fno-exceptions

By default, support for C++ exceptions is disabled. To enable support for C++ exceptions, use the -fexceptions compiler option on the tiarmclang command-line. If the -fexceptions option is specified on the tiarmclang command-line, then the linker will link the application with runtime libraries that have been built with C++ exceptions enabled.

-funsigned-char, -fsigned-char or -fno-unsigned-char

A plain char type is treated as unsigned char by default in the tiarmclang compiler. This matches the semantics for the -funsigned-char option. This behavior can be overridden with the use of the -fsigned-char or -fno-unsigned-char option, which indicates that a plain char type is to be interpreted as signed char.

-mexecute-only, -mno-execute only

The tiarmclang compiler tools support the generation of execute-only code for TI Arm Cortex-M0/M0+ processor variants. The execute-only feature is not enabled by default. Generation of execute-only code can be enabled by specifying the -mexecute-only option on the tiarmclang command-line.

When an application’s source files are compiled with -mexecute-only, the compiler will prevent constant data from being embedded in the code section that contains the definition of a given function. Also, the linker will be instructed to link with a version of the runtime support libraries that were built with execute-only enabled.

Consider a simple example with a function that contains a switch statement:

#include <stdio.h>

void mySwitch(int n) {

  switch (n)
  {
    case 1:
      printf("Input value is 1\n");
      break;
    case 2:
      printf("Input value is 2\n");
      break;
    case 3:
      printf("Input value is 3\n");
      break;
    default:
      printf("Invalid input\n");
      break;
  }
}

When the above source file is compiled as follows:

%> tiarmclang -mcpu=cortex-m0plus -mexecute-only -S ex_switch.c

The compiler generates an assembly language file that contains the following:

%> cat ex_switch.s
...
        .section        .text.mySwitch,"axy",%progbits,unique,0
        .globl  mySwitch
        .p2align        1
        .code   16                              @ @mySwitch
        .thumb_func
mySwitch:
...
.LBB0_5:                                @ %sw.bb3
        movs    r0, :upper8_15:.L.str.2
        lsls    r0, r0, #8
        adds    r0, :upper0_7:.L.str.2
        lsls    r0, r0, #8
        adds    r0, :lower8_15:.L.str.2
        lsls    r0, r0, #8
        adds    r0, :lower0_7:.L.str.2
        bl      printf
...
        .section        .rodata.str1.1,"aMS",%progbits,1
.L.str:
        .asciz  "Input value is 1\n"
        .size   .L.str, 18
...
.L.str.2:
        .asciz  "Input value is 3\n"
        .size   .L.str.2, 18
...

Without the execute-only feature enabled, the code generated to load the address of a string constant consists of a single PC-relative load instruction.

When execute-only is enabled, the compiler will generate four 8-bit loads to get the address of a string contant into an argument register as we can see in the above assembly language excerpt.

While the execute-only compiler generated code is larger and less efficient, it is able to reside in special execute-only memory. This is useful when code security is a concern.

-munaligned-access, -mno-unaligned-access

The -munaligned-access option can be used to enable the use of unaligned memory accesses when generating code for an Arm processor variant that supports unaligned memory accesses. This is the default tiarmclang compiler behavior for Arm processors like the Cortex-M4 that have support for unaligned memory accesses. This default behavior can be disabled with the -mno-unaligned-accesses option.

For Arm processor variants like the Cortex-M0 that do not have support for unaligned memory accesses, the default tiarmclang behavior is -mno-unaligned-accesses. An attempt to use the -munaligned-accesses option with an Arm processor that does not support unaligned memory accesses will result in a warning diagnostic and the option will be ignored.

In general, C library memory access functions (e.g. memcpy, memset) assume normal memory, which for most Arm subtargets allows unaligned memory access. For special device/peripheral memory, unaligned access could cause an Alignment fault. When memory access functions are used for device memory, the pointers must be to an aligned address, or else customized functions should be used.

The compiler defines the __ARM_FEATURE_UNALIGNED macro when -munaligned-access is enabled. See Arm-Specific Pre-Defined Macro Symbols for more information. The macro can be used to select customized memory access functions with special implementations at compile-time:

#ifdef __ARM_FEATURE_UNALIGNED
#define __MEMCPY memcpy
#else
extern void memcpy_aligned(void *dst, void *src, size_t bytes);
#define __MEMCPY memcpy_aligned
#endif

void copy(void *dst, void *src, size_t bytes) {
  __MEMCPY(dst, src, bytes);
}
-mlong-calls, -mno-long-calls

The -mlong-calls option can be used to instruct the compiler to implement function calls using branch indirect instructions (i.e. load address of destination into a register and branch via the register). The tiarmclang compiler default behavior is to use direct branches to implement function calls. For functions that are out-of-range from their caller, the linker will generate a trampoline to help an out-of-range caller reach its destination.

-fshort-enums, -fno-short-enums

The -fshort-enums option instructs the compiler to only allocate as much space for an enum type data object as is needed to represent the declared range of possible values. This is the default behavior assumed by the tiarmclang behavior. You can override this default behavior using the -fno-short-enums option that will allocate 4 bytes for an enum type data object even if the range of values for a given enum type data object can be represented with fewer bytes.

-fshort-wchar, -fno-short-wchar

The default size for the wchar_t type is 32-bits, which is analogous to the fno-short-wchar option. The runtime libraries provided with the tiarmclang toolchain installation are all built assuming a wchar_t type size of 32-bits. If you compile a C/C++ source file with the -fshort-wchar option to indicate that the wchar_t type size should be assumed to be 16-bits, you will encounter a link-time warning indicating that the newly compiled object file is not compatible with object files in the runtime libraries.

-fcommon, -fno-common

The -fcommon option is enabled by default. For C source code, this option will cause uninitialized global variable definitions to be treated as tentative definitions. When the -fcommon option is enabled, uninitialized global variables are placed in a common block. The linker will then resolve all tentative definitions of the same global variable in different compilation units to a single data object definition. This behavior can be disabled with the -fno-common option.

-ffunction-sections, -fno-function-sections

The -ffunction-sections option is enabled by default and instructs the tiarmclang compiler to generate code for a function definition into its own section. This default behavior can be overridden by specifying the fno-function-sections on the tiarmclang command line. You can also dictate what section the compiler will generate code for a function definition into by attaching a section attribute to the function in the C/C++ source code.

-fdata-sections, -fno-data-sections

The -fdata-sections option is enabled by default and instructs the tiarmclang compiler to generate code for the definition of a data object into its own section. This default behavior can be overridden by specifying the fno-datasections on the tiarmclang command line. You can also dictate what section the data object will be defined in by attaching a section attribute to the data object in the C/C++ source code.