3.18.18 IA-16 Options

These are the ‘-m’ options defined for the Intel IA-16 architecture.

-mtune=cpu-type

Tune to cpu-type everything applicable about the generated code, except for the ABI and the set of available instructions. The choices for cpu-type are:

i8086

The Intel 8086.

i8088

The Intel 8088.

i80186
i186

The Intel 80186.

i80286
i286

The Intel 80286.

v20

The NEC V20.

v30

The NEC V30.

v30mz

The NEC V30MZ.

any

Any CPU listed above. The aim is to generate code which runs reasonably well on any CPU listed above.

any_186

As with -mtune=any, but assume a CPU which supports immediate operands for push, imul and shift/rotate instructions.

-march=cpu-type

Generate instructions for the machine type cpu-type. The choices for cpu-type are the same as for -mtune. Moreover, specifying -march=cpu-type implies -mtune=cpu-type.

-mmsdos
-mr=msdos

Produce executables for MS-DOS. This is the default.

-mmsdos-handle-v1

Produce executables for MS-DOS, in such a way that the executables will fail gracefully under MS-DOS version 1.x, rather than crash the system. This option implies -mmsdos.

-mhandle-non-i186

If generating code for a machine that supports Intel 80186 instructions (e.g. -march=v30 or -march=i80286), insert code to check, at startup, whether the code is indeed running on an 80186-capable system.

This requires support from the C library, and currently only works when targeting MS-DOS.

-mhandle-non-i286

If generating code for a machine that supports Intel 80286 instructions, (e.g. -march=i80286), insert code to check, at startup, whether the code is indeed running on an 80286-capable system.

This requires support from the C library, and currently only works when targeting MS-DOS.

-mcmodel=tiny

Generate code for the tiny code model, with a single combined data and text segment in a 64 KiB address space. This is the default for MS-DOS.

-mcmodel=small
-mseparate-code-segment

Generate code for the small code model, with one data segment and one text segment, in separate 64 KiB spaces. This is now (February 2020) the default for ELKS (-melks), and also (February 2022) the default for DOS extender mode (-mdosx, -mdosx32).

At the compile stage, -mcmodel=small currently disables trampolines for nested functions.

At the linking stage—unless -T is used—this option also causes GCC to switch to a different output format to better support separate segments. In particular, if targeting MS-DOS, GCC will produce an MZ executable. (This requires support from the linker script which comes with the C library.)

-msegment-relocation-stuff
-mno-segment-relocation-stuff

Enable (or disable) language features, such as static pointers to far variables, that rely on segment relocations to work. If the small code model or medium code model is used, outside of DOS extender mode (-mdosx, -mdosx32), the default is to allow such language features.

-mshort-jumps
-mno-short-jumps

Allow (or disallow) the use of jump instructions which can only jump −128/+127 bytes. The default is not to use them. This option only affects instructions for which the assembler doesn’t provide a work-around and the compiler doesn’t know the jump displacement.

-mrtd
-mstdcall

Use a different function-calling convention, in which functions that take a fixed number of arguments return with the ret num instruction, which pops their arguments while returning. This saves one instruction in the caller since there is no need to pop the arguments there.

At the linking stage, this option will also make GCC link your code against the appropriate -mrtd multilib.

You can specify that an individual function is called with this calling sequence with the function attribute stdcall. You can also override the -mrtd option by using the function attribute cdecl or regparmcall. See IA-16 Function Attributes.

Warning: you must provide function prototypes for all functions that take variable numbers of arguments (including printf); otherwise incorrect code is generated for calls to those functions.

In addition, seriously incorrect code results if you call a function with too many arguments. (Normally, extra arguments are harmlessly ignored. See Default IA-16 Calling Convention.)

-mregparmcall

Use a different function-calling convention, in which functions receive their first few arguments in the registers ax, dx, and cx, and pop their remaining arguments off the stack. An exception is that, if the number of arguments to a function is variable, the ... variable arguments will always go on the stack, and the calling function pops all pushed arguments.

At the linking stage, -mregparmcall will also make GCC link your code against the appropriate -mregparmcall multilib.

You can specify that an individual function is called with this calling sequence with the function attribute regparmcall. You can also override the -mregparmcall option by using the function attribute cdecl or stdcall. See IA-16 Function Attributes.

Warning: you must provide function prototypes for all functions that take variable numbers of arguments (including printf); otherwise incorrect code is generated for calls to those functions.

In addition, seriously incorrect code results if you call a function with too many arguments. (Normally, extra arguments are harmlessly ignored.)

-mno-callee-assume-ds-data-segment
-mcallee-assume-ds-data-segment

Use (or do not use) a different function-calling convention, in which the ds register is not assumed to point to the program’s data segment (the generic address space) at function entry, and is treated as just an ordinary call-used register (with -fcall-used-ds) or fixed register (-ffixed-ds) with no special meaning.

The ss register is still assumed to point to the data segment—data items in the generic address space will be accessed via ss.

This option is ignored if ds is set to be a call-saved register (-fcall-saved-ds).

In the default configuration (-mcallee-assume-ds-data-segment -mcallee-assume-ss-data-segment -fcall-used-ds), functions can assume that ds points to the program’s data segment at function entry, and will arrange to reset ds to ss—if needed—just before returning.

You can override this option for individual functions, by using the assume_ds_data and no_assume_ds_data function attributes. See IA-16 Function Attributes.

-mprotected-mode

Enable partial support for generating code to run in Intel 80286 protected mode.

With this option, the output code will avoid using segment registers (ds, es) to hold arbitrary 16-bit values—in protected mode, doing so may make the CPU crash the program. Instead, the output code will only load segment registers when dereferencing near or far pointers.

Currently, -mprotected-mode also causes GCC to avoid placing asm operands in segment registers. You can tell GCC to let an operand go into a segment register, by passing the operand through a built-in function ‘__builtin_ia16_selector’:

void foo (unsigned selector)
{
  __asm volatile ("nop"
                  : : "e" (__builtin_ia16_selector (selector)));
}

Note: if you are writing protected mode code that will run in a freestanding environment, it is advised to also specify both -mprotected-mode and -ffreestanding at link time, so that GCC will link your code with a version of libgcc that can work in protected mode.

-mno-newlib-autofloat-stdio

If using the Newlib C library, do not try to detect whether the program needs floating-point support in the formatted I/O routines (stdio). In particular, -mno-newlib-autofloat-stdio without -mnewlib-nano-stdio tells GCC to always include floating-point support.

Without this option, GCC will try to detect if such support is needed, and link against the appropriate version of the stdio code.

If you use this option, specify it at compile time and during the final link.

3.18.18.1 Experimental IA-16 Options

-mdosx
-mdpmi

Produce MS-DOS executables which run under a DOS extender in protected mode. The executables will use the DOS Protected Mode Interface (DPMI) to switch to protected mode, if they detect a DPMI host.

This option requires support from the linker script which comes with the C library. It implies -mmsdos, -march=i80286, and -mprotected-mode, and currently also enables -msegelf.

-mdosx32

Similar to -mdosx, but the MS-DOS executables will be “dual mode” programs which can operate under both 16- and 32-bit DPMI hosts. 16-bit programs will try to start in 32-bit DPMI mode whenever possible.

This switch is mainly for experimentation purposes.

-melks
-mr=elks
-melks-libc

Produce executables for the Embeddable Linux Kernel Subset (ELKS) operating system. In addition, link against ELKS’s own C runtime library—which must be built with GCC, and installed—instead of the Newlib C library.

This option implies -mprotected-mode and -mcmodel=small, and currently also enables -msegelf and -fuse-ld=gold.

-mr=rt

Produce executables for the specified target runtime environment rt, if the necessary runtime libraries and support files are installed.

-maout-stack=stack-size
-mstack-size=stack-size

When building an ELKS program (-melks), set it to request the operating system to reserve at least stack-size bytes in the data segment for the stack. This requires support from the linker back-end and from the linker script which comes with the C library.

-maout-heap=heap-size

When building an ELKS program (-melks), set it to request the operating system to reserve at least heap-size bytes in the data segment for the heap.

When building an MS-DOS program, set it to limit the size of the heap to heap-size bytes.

This option requires support from the linker back-end and from the linker script which comes with the C library.

-mcmodel=medium

Generate code for the medium code model, with one data segment and multiple text segments, each in a separate 64 KiB space.

At the linking stage—unless -T is used—this option will also make GCC link your code against the appropriate medium model multilib, and switch to the appropriate output program format.

This option is currently not supported for C++. Also, medium model support for the ELKS target is incomplete.

-mnewlib-nano-stdio

If using the Newlib C library, link against a limited version of the formatted I/O routines (stdio) which supports only C89 functionality and by default excludes floating-point support.

-mtsr

Emit and link with extra code to support the writing of MS-DOS terminate-and-stay-resident (TSR) programs. The -maout-heap= option can be used to adjust the maximum size of the program’s resident heap.

If you use this option, specify it at compile time and during the final link.

This option implies -mmsdos, and requires support from the linker script which comes with the C library.

-msegelf

Generate object files which follow H. Peter Anvin’s proposed 16-bit segmented code ABI, https://git.zytor.com/users/hpa/segelf/abi.git/plain/segelf.txt. This is now (September 2020) the default for ELKS (-melks).

Warning: The -msegelf switch causes GCC to generate code that is not binary compatible with code generated without that switch. Using this switch may require recompiling all other modules in a program, including system libraries.

-mno-callee-assume-ss-data-segment

Use a different function-calling convention, in which the ss register is not assumed to point to the program’s data segment at function entry. This option exists only for testing.

-masm=intel

Output assembly instructions using Intel syntax, rather than the default AT&T syntax. This also affects which dialect is used for basic asm (see Basic Asm — Assembler Instructions Without Operands) and extended asm (see Extended Asm - Assembler Instructions with C Expression Operands).

-mno-post-link

After running the linker, skip any post-link steps which may be needed to transform the linker output into a usable target executable. The output from -mno-post-link will likely be an intermediate ELF file.

This switch is mainly for experimentation purposes.

3.18.18.2 Deprecated IA-16 Options

-maout-total=total

When building an ELKS program (-melks), set it to request the operating system to set the top of the data segment—including static storage, heap, stack, and environment variables—to at least total. This requires support from the linker back-end and from the linker script which comes with the C library.

-maout-chmem=chmem

When building an ELKS program (-melks), set it to request the operating system to reserve at least chmem bytes in the data segment for non-static storage (such as heap, stack, and environment variables). This requires support from the linker back-end and from the script which comes with the C library.

-mfar-function-if-far-return-type

This option is ignored. It exists only for compatibility with older build systems.

3.18.18.3 IA-16 Built-in Macros

__FAR
__SEG_SS

Each of these macros is defined only if the compiler supports the named address space specifier (see IA-16 Named Address Spaces).

__SEGMENT

This macro is defined only if the compiler supports the Watcom-compatible __segment type name.

__CDECL
__STDCALL
__PASCAL
__INTERRUPT
__LOADDS
__SAVEREGS

Each of these macros is defined only if the compiler supports the corresponding lowercase Watcom-compatible type qualifier, e.g., __cdecl. The type qualifiers may themselves be macros defined in terms of function attributes (see IA-16 Function Attributes).

Regarding the __saveregs qualifier, note that Open Watcom and Borland C++ 4.0 define it to mean different things:

  • Under Watcom, __saveregs means to save only segment registers.
  • Under Borland C++, __saveregs means to save all registers, except possibly registers which hold return values.

GCC currently follows Borland’s stricter meaning.

__IA16_CMODEL_TINY__
__TINY__
__IA16_CMODEL_SMALL__
__SMALL__
__IA16_CMODEL_MEDIUM__
__MEDIUM__

Each of these macros is defined only if the named code model (tiny, small, or medium) is selected.

__IA16_ARCH_ANY
__IA16_ARCH_ANY_186
__IA16_ARCH_I8086
__IA16_ARCH_I8088
__IA16_ARCH_NEC_V30
__IA16_ARCH_NEC_V30MZ
__IA16_ARCH_NEC_V20
__IA16_ARCH_I80186
__IA16_ARCH_I80188
__IA16_ARCH_I80286

These macros are defined according to the -march=cpu-type option settings.

__IA16_TUNE_ANY
__IA16_TUNE_ANY_186
__IA16_TUNE_I8086
__IA16_TUNE_I8088
__IA16_TUNE_NEC_V30
__IA16_TUNE_NEC_V30MZ
__IA16_TUNE_NEC_V20
__IA16_TUNE_I80186
__IA16_TUNE_I80188
__IA16_TUNE_I80286

These macros are defined according to the -mtune=cpu-type and option settings.

__IA16_FEATURE_SHIFT_IMM
__IA16_FEATURE_PUSH_IMM
__IA16_FEATURE_IMUL_IMM
__IA16_FEATURE_PUSHA
__IA16_FEATURE_ENTER_LEAVE
__IA16_FEATURE_AAD_IMM
__IA16_FEATURE_FSTSW_AX

Each of these macros is defined only if the CPU selected by -march=cpu-type supports the named type of IA-16 instruction.

__IA16_FEATURE_SHIFT_MASKED

This macro is defined only if the selected CPU’s bitwise shift and rotation instructions—rcl, shr, and so on—implicitly mask each shift count to their lower 5 bits.

__IA16_FEATURE_PROTECTED_MODE

This macro is defined only if -mprotected-mode is in effect.

__IA16_FEATURE_DPMIABLE

This macro is defined only if -mdpmiable is in effect.

__IA16_FEATURE_ALLOCABLE_DS_REG

This macro is defined only if the ds register is configured to be available for register allocation—that is, it is either call-used or call-saved, not fixed.

__IA16_FEATURE_FAR_FUNCTION_SYNTAX

This macro is defined only if the postfix __far syntax for declaring far functions is supported (see IA-16 Named Address Spaces).

__IA16_CALLCVT_FAR_FUNCTION_IF_FAR_RETURN_TYPE

This macro is defined only if the classical syntax for declaring far functions is supported (see IA-16 Named Address Spaces).

__IA16_FEATURE_FAR_STATIC_STORAGE

This macro is defined only if static storage variables can be placed in __far space (see IA-16 Named Address Spaces).

__IA16_FEATURE_ATTRIBUTE_CDECL
__IA16_FEATURE_ATTRIBUTE_STDCALL
__IA16_FEATURE_ATTRIBUTE_REGPARMCALL
__IA16_FEATURE_ATTRIBUTE_PASCAL
__IA16_FEATURE_ATTRIBUTE_ASSUME_DS_DATA
__IA16_FEATURE_ATTRIBUTE_NO_ASSUME_DS_DATA
__IA16_FEATURE_ATTRIBUTE_SAVE_DS
__IA16_FEATURE_ATTRIBUTE_NO_SAVE_DS
__IA16_FEATURE_ATTRIBUTE_SAVE_ES
__IA16_FEATURE_ATTRIBUTE_SAVE_ALL
__IA16_FEATURE_ATTRIBUTE_ASSUME_SS_DATA
__IA16_FEATURE_ATTRIBUTE_NO_ASSUME_SS_DATA
__IA16_FEATURE_ATTRIBUTE_NEAR_SECTION
__IA16_FEATURE_ATTRIBUTE_FAR_SECTION
__IA16_FEATURE_ATTRIBUTE_INTERRUPT

Each of these macros is defined only if the corresponding function attribute is recognized (see IA-16 Function Attributes). If the compiler knows about an attribute but does not fully support it, the macro will be defined with a value of 0.

__BUILTIN_IA16_SELECTOR
__BUILTIN_IA16_FP_OFF
__BUILTIN_IA16_STATIC_FAR_CAST
__BUILTIN_IA16_NEAR_DATA_SEGMENT
__BUILTIN_IA16_SS

Each of these macros is defined only if the corresponding __builtin_ia16_… macro is defined (see IA-16 Built-in Functions).

3.18.18.4 Default IA-16 Calling Convention

By default, GCC outputs code for this calling convention: