Development Reference Guides

Contents

C/C++
/SYCL
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.
IA-32 applications do not apply for SYCL.

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++
/SYCL
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 use vector registers.

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++
/SYCL
programs. It can be specified on a function with variable arguments.
__stdcall
/Gz
Standard calling convention used for Win32 API functions.
__fastcall
/Gr
Fast calling convention that specifies that arguments are passed in registers rather than on the stack.
__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.
__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 use 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
__regcal
l, place the keyword before a function declaration. For example:
Linux
__attribute__((regcall)) foo (int I, int j);
Windows
__regcall int 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.
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

__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.
All types assigned to
XMM
,
YMM
, or
ZMM
in a non-SSE target are passed in the stack.
Type (Signed and Unsigned)
IA-32
Intel® 64
bool, char, int, enum, _Decimal32, long, pointer
GPR
GPR
short, __mmask{8,16,32,64}
GPR
GPR
long long, __int64
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
For the purpose of structured types, the classification of
GPR
class is used.
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.
Types that are smaller in size 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:
  • There is no limitation on the overall size of a structure.
  • The register classes for basic types are given in Data Type Classifications.
  • For systems based on the IA-32 architecture, classification is performed on four-bytes. For systems based on other architectures, classification is performed on eight-bytes.

__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:
  • Each chunk (eight bytes on systems based on Intel® 64 architecture or four-bytes on systems based on IA-32 architecture of a value of Data Type is assigned a register class. If enough registers from Available Registers are available, the whole value is passed in registers, otherwise the value is passed using the stack.
  • If the classification were to use one or more register classes, then the registers of these classes from the table in Available Registers are used, in the order given there.
  • If no more registers are available in one of the required register classes, then the whole value is put on the stack.

__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:
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
All other registers do not preserve their values across this call.

Product and Performance Information

1

Performance varies by use, configuration and other factors. Learn more at www.Intel.com/PerformanceIndex.