C/C++/DPC++ Calling Conventions

There are a number of calling conventions that set the rules on how arguments are passed to a function and how the values are returned from the function.

Calling Conventions on Windows*

The following table summarizes the supported calling conventions on Windows:

Calling Convention

Compiler Option

Description

__cdecl

/Gd

This is the default calling convention for C/C++/DPC++ programs. It can be specified on a function with variable arguments.

__stdcall

/Gz

Standard calling convention used for Win32 API functions.

This content is specific to C++; it does not apply to DPC++.

__fastcall

/Gr

Fast calling convention that specifies that arguments are passed in registers rather than on the stack.

This content is specific to C++; it does not apply to DPC++.

__regcall

/Qregcall specifies that __regcall is the default calling convention for functions in the compilation, unless another calling convention is specified on a declaration.

Intel® oneAPI DPC++/C++ Compiler calling convention that specifies that as many arguments as possible are passed in registers; likewise, __regcall uses registers whenever possible to return values. This calling convention is ignored if specified on a function with variable arguments.

For more information about the Intel-compatible vector functions ABI, download the Vector Function Application Binary Interface PDF.

For more information about the GCC vector functions ABI, see the item Libmvec - vector math library document in the GLIBC wiki at sourceware.org.

__thiscall

none

Default calling convention used by C++ member functions that do not use variable arguments.

__vectorcall

/Gv

Calling convention that specifies that a function passing vector type arguments should utilize vector registers.

Calling Conventions on Linux*

The following table summarizes the supported calling conventions on Linux:

Calling Convention

Compiler Option

Description

__attribute((cdecl))

none

Default calling convention for C/C++/DPC++ programs. Can be specified on a function with variable arguments.

__attribute((stdcall))

none

Calling convention that specifies the arguments are passed on the stack. Cannot be specified on a function with variable arguments.

__attribute((regparm (number)))

none

On systems based on IA-32 architecture, the regparm attribute causes the compiler to pass up to number arguments in registers EAX, EDX, and ECX instead of on the stack. Functions that take a variable number of arguments will continue to pass all of their arguments on the stack.

__attribute__((regcall))

-regcall specifies that __regcall is the default calling convention for functions in the compilation, unless another calling convention is specified on a declaration.

Intel oneAPI DPC++/C++ Compiler calling convention that specifies that as many arguments as possible are passed in registers; likewise, __regcall uses registers whenever possible to return values. This calling convention is ignored if specified on a function with variable arguments.

__attribute__((vectorcall))

none

Calling convention that specifies that a function passing vector type arguments should utilize vector registers.

The __regcall Calling Convention

The __regcall calling convention is unique to the Intel oneAPI DPC++/C++ Compiler and requires some additional explanation.

To use __regcall, place the keyword before a function declaration. For example:

Example

__regcall int foo (int i, int j);
// Linux
__attribute__((regcall)) foo (int I, int j); 

Available __regcall Registers

All registers in a __regcall function can be used for parameter passing/returning a value, except those that are reserved by the compiler. The following table lists the registers that are available in each register class depending on the default ABI for the compilation. The registers are used in the order shown below.

This content is specific to C++; it does not apply to DPC++.

Register Class/Architecture

IA-32 for Linux

IA-32 for Windows

Intel® 64 for Linux

Intel® 64 for Windows

GPR

EAX, ECX, EDX, EDI, ESI

ECX, EDX, EDI, ESI

RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11, R12, R14, R15

RAX, RCX, RDX, RDI, RSI, R8, R9, R11, R12, R14, R15

FP

ST0

ST0

ST0

ST0

MMX

None

None

None

None

XMM

XMM0 - XMM7

XMM0 - XMM7

XMM0 - XMM15

XMM0 - XMM15

YMM

YMM0 - YMM7

YMM0 - YMM7

YMM0 - YMM15

YMM0 - YMM15

ZMM

ZMM0 - ZMM7

ZMM0 - ZMM7

ZMM0 - YMM15

ZMM0 - YMM15

This content is specific to DPC++.

Register Class/Architecture

Intel® 64 for Linux

Intel® 64 for Windows

GPR

RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11, R12, R14, R15

RAX, RCX, RDX, RDI, RSI, R8, R9, R11, R12, R14, R15

FP

ST0

ST0

MMX

None

None

XMM

XMM0 - XMM15

XMM0 - XMM15

YMM

YMM0 - YMM15

YMM0 - YMM15

ZMM

ZMM0 - YMM15

ZMM0 - YMM15

__regcall Data Type Classification

Parameters and return values for __regcall are classified by data type and are passed in the registers of the classes shown in the following table.

Note

All types assigned to XMM, YMM, or ZMM in a non-SSE target are passed in the stack.

This content is specific to C++; it does not apply to DPC++.

Type (for both unsigned and signed types)

IA-32

Intel® 64

bool, char, int, enum, _Decimal32, long, pointer

GPR

GPR

short, __mmask{8,16,32,64}

GPR

GPR

long long, __int64

See Structured Data Type Classification Rules

GPR

_Decimal64

XMM

GPR

long double

FP

FP

float, double, float128, _Decimal128

XMM

XMM

__m128, __m128i, __m128d

XMM

XMM

__m256, __m256i, __m256d

YMM

YMM

__m512, __m512i, __m512d

ZMM

ZMM

complex type, struct, union

See Structured Data Type Classification Rules

See Structured Data Type Classification Rules

Note

For the purpose of structured types, the classification of GPR class is used.

Note

On systems based on IA-32 architecture, these 64-bit integer types (long long, __int64) get classified to the GPR class and are passed in two registers, as if they were implemented as a structure of two 32-bit integer fields.

This content is specific to DPC++.

Type (for both unsigned and signed types)

Intel® 64

bool, char, int, enum, _Decimal32, long, pointer

GPR

short, __mmask{8,16,32,64}

GPR

long long, __int64

GPR

_Decimal64

GPR

long double

FP

float, double, float128, _Decimal128

XMM

__m128, __m128i, __m128d

XMM

__m256, __m256i, __m256d

YMM

__m512, __m512i, __m512d

ZMM

complex type, struct, union

See Structured Data Type Classification Rules

Note

For the purpose of structured types, the classification of GPR class is used.

Types that are smaller in size than registers than registers of their associated class are passed in the lower part of those registers; for example, float is passed in the lower four bytes of an XMM register.

__regcall Structured Data Type Classification Rules

Structures/unions and complex types are classified similarly to what is described in the x86_64 ABI, with the following exceptions:

__regcall Placement in Registers or on the Stack

After the classification described in Data Type Classifications and Structured Data Type Classification Rules, __regcall parameters and return values are either put into registers specified in Available Registers or placed in memory, according to the following:

__regcall Registers that Preserve Their Values

The following registers preserve their values across a __regcall call, as long as they were not used for passing a parameter or returning a value:

This content is specific to C++; it does not apply to DPC++.

Register Class/ABI

IA-32

Intel® 64 for Linux

Intel® 64 for Windows

GPR

ESI, EDI, EBX, EBP, ESP

R12 - R15, RBX, RBP, RSP

R12 - R15, RBX, RBP, RSP

FP

None

None

None

MMX

None

None

None

XMM

XMM4 - XMM7

XMM8 - XMM15

XMM8 - XMM15

YMM

XMM4 - XMM7

XMM8 - XMM15

XMM8 - XMM15

ZMM

XMM4 - XMM7

XMM8 - XMM15

XMM8 - XMM15

This content is specific to DPC++.

Register Class/ABI

Intel® 64 for Linux

Intel® 64 for Windows

GPR

R12 - R15, RBX, RBP, RSP

R12 - R15, RBX, RBP, RSP

FP

None

None

MMX

None

None

XMM

XMM8 - XMM15

XMM8 - XMM15

YMM

XMM8 - XMM15

XMM8 - XMM15

ZMM

XMM8 - XMM15

XMM8 - XMM15

All other registers do not preserve their values across this call.

See Also