Calling Convention

References:

TableGen for Calling Convention

TargetCallingConv.td

Calling convention from writing an llvm backend:

  • To support target-specific calling conventions, _XXX_GenCallingConv.td uses interfaces (such as CCIfType and CCAssignToReg) that are defined in lib/Target/TargetCallingConv.td.
  • TableGen uses the target descriptor file _XXX_GenCallingConv.td to generate the header file _XXX_GenCallingConv.inc, which is typically included in _XXX_ISelLowering.cpp. The inferfaces in _XXX_GenCalllingConv.td can specify:
    • the order of parameter allocation.
    • where parameters and return values are placed (on the stack or in registers)
    • which registers may be used.
    • whether the caller or callee unwinds the stack.

TableGen Interfaces

  • CCIfType<cond, action>. If the predicate is true, then the action is performed.
  • CCAssignToReg<[reg1, ...]>. An action assigns the argument value to the first available register.

Examples:

CCIfType<[f32,f64], CCAssignToReg<[R0, R1]>> means: if the current argument is of type f32 or f64, then the action CCAssignToReg is performed: assign the argument value to the first available register: either R0 or R1.

The return calling convention RetCC_Sparc32:

def RetCC_Sparc32 : CallingConv<[ 
  // 32-bit integer is returned in register T0 or T1:
  CCIfType<[i32], CCAssignToReg<[I0, I1]>>, 
  // single-precision float is returned to register F0:
  CCIfType<[f32], CCAssignToReg<[F0]>>,
  // double-precision float is returned to register D0:
  CCIfType<[f64], CCAssignToReg<[D0]>>
]>;
  • CCAssignToStack<size, align>. Assign values to a stack slot with the specified size and alignment.

    def CC_Sparc32 : CallingConv<[
    // All arguments get passed in integer registers if there is space.
    CCIfType<[i32, f32, f64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
    // assigns the value to stack with size of 4 bytes and alignment of 4 bytes.
    CCAssignToStack<4, 4>
    ]>;
  • CCDelegateTo<subCC>. Call a specified sub-calling convention.

e.g. in X86CallingConv.td:

def RetCC_X86_32_C : CallingConv<[
  CCIfType<[f32], CCAssignToReg<[ST0, ST1]>>,
  CCIfType<[f64], CCAssignToReg<[ST0, ST1]>>,
  CCDelegateTo<RetCC_X86Common>
  // after the current value is assigned to the register ST0 or ST1,
  // the RetCC_X86Common is invoked.
]>;
  • CCIfCC<CC_x, action>. If the current calling convention is CC_x, then do the action.

e.g. in X86CallingConv.td:

def RetCC_X86_32 : CallingConv<[
  // If the Fast calling convention is in use, then RetCC_X86_32_Fast is invoked.
  CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_X86_32_Fast>>,
  // If the SSECall calling convention is in use, then RetCC_X86_32_SSE is invoked.
  CCIfCC<"CallingConv::X86_SSECall", CCDelegateTo<RetCC_X86_32_SSE>>,
  CCDelegateTo<RetCC_X86_32_C>
]>;
  • CCIf<predicate, action>. If the predicate matches, apply the action.

  • CCIfInReg<action>. If the argument is marked with the ‘inreg’ attribute

  • CCIfNest<action>. If the argument is marked with the ‘nest’ attribute

  • CCIfNotVarArg<action>. If the current function does not take a variable number of arguments

  • CCAssignToRegWishShadow<registerList, shadowList>. similar to CCAssignToReg, but with a shadow list of registers.

  • CCPassByVal<size, align>. Assign value to a stack slot with the min specified size and alignment

  • CCPromoteToType<type>. Promote the current value the specified type

  • CallingConv<[actions]>. Define each calling convention that is supported.

Code Overview

Example calling conventions in LLVM:

See [llvm/include/llvm/IR/CallingConv.h]

  • “ccc” - The C calling convention. This calling convention (the default if no other calling convention is specified).

  • “fastcc” - The fast calling convention. This allows the target to use whatever tricks it wants to produce fast code for the target, without having to conform to an externally specified ABI (Application Binary Interface).

  • “cc 10” - GHC convention.

  • “cc 11” - The HiPE calling convention. For High-Performance Erlang (HiPE) compiler.

    • It uses more registers for argument passing than the ordinary C calling convention and defines no callee-saved registers.
  • “webkit_jscc” - The WebKit’s JavaScript calling convention. For WebKit FTL JIT.

  • “anyregcc” - Dynamic calling convention for code patching. Patching an arbitrary code sequence in place for a call site.

    • Forces the call arguments into registers but allows them to be dynamically allocated.
    • This can currently only be used with calls to llvm.experimental.patchpoint because only this intrinsic records the location of its arguments in a side table.
    • see Stack maps and patch points in LLVM.
  • “cfguard_checkcc” - Windows Control Flow Guard (Check mechanism).

  • “cc {n}” - Numbered convention

CallingConvLower

References:

  • [llvm/include/llvm/CodeGen/CallingConvLower.h]
  • [llvm/lib/CodeGen/CallingConvLower.cpp]

Classes:

  • CCState
  • CCValAssign

Target specific calling conventions:

  • [llvm/lib/Target/ARM/ARMCallingConv.h]
  • [llvm/lib/Target/ARM/ARMCallLowering.h]
  • [llvm/lib/Target/ARM/ARMCallLowering.cpp]

  • [llvm/lib/Target/Mips/Mips16ISelLowering.h]

  • [llvm/lib/Target/Mips/Mips16ISelLowering.cpp]

  • [llvm/lib/Target/Mips/MipsCallingConv.td]

  • [llvm/lib/Target/Mips/MipsCallLowering.cpp]

  • [llvm/lib/Target/Mips/MipsCCState.h]

  • [llvm/lib/Target/Mips/MipsCCState.cpp]

  • [llvm/lib/Target/Mips/MipsISelLowering.h]

  • [llvm/lib/Target/Mips/MipsISelLowering.cpp]

  • [llvm/lib/Target/RISCV/RISCVISelLowering.h]

  • [llvm/lib/Target/RISCV/RISCVISelLowering.cpp]

More

  • Syscall
  • References: The Definitive Guide to Linux System Calls FreeBSD - System Calls FreeBSD - Alternate Calling Convention X86-32 (i386) %eax for syscall number %ebx, %ecx, %edx, %esi, %edi, %ebp are used for passing 6 parameters to system calls. if there are more than six arguments, %ebx must contain the memory location where the list of arguments is stored. FreeBSD System Calls By default, FreeBSD kernel uses the C calling convention.

  • Riscv Call
  • References: reference More

  • Mips Call
  • References: [llvm/lib/Target/Mips/Mips16ISelLowering.h] [llvm/lib/Target/Mips/Mips16ISelLowering.cpp] [llvm/lib/Target/Mips/MipsCallingConv.td] [llvm/lib/Target/Mips/MipsCallLowering.cpp] [llvm/lib/Target/Mips/MipsCCState.h] [llvm/lib/Target/Mips/MipsCCState.cpp] [llvm/lib/Target/Mips/MipsISelLowering.h] [llvm/lib/Target/Mips/MipsISelLowering.cpp] MipsCallingConv.td More

  • The calling convention of CC_CHERI_CCall
  • References: llvm/lib/Target/Mips/MipsCallingConv.td build/lib/Target/Mips/MipsGenCallingConv.inc CHERI_CCall calling conv: Definition Defined in .td file, code generated (during build) as MipsGenCallingConv.inc // llvm/lib/Target/Mips/MipsCallingConv.td def CC_CHERI_CCall : CallingConv<[ CCIfType<[iFATPTR64, iFATPTR128, iFATPTR256, iFATPTR512], CCAssignToReg<[C1, C2, C3, C4, C5, C6, C7, C8, C9, C10]>>, CCIfType<[i64], CCAssignToReg<[V0_64]>>, CCDelegateTo<CC_MipsN> ]>; def CC_MipsN : CallingConv<[ CCIfType<[i8, i16, i32, i64], CCIfSubtargetNot<"isLittle()", CCIfInReg<CCPromoteToUpperBitsInType<i64>>>>, // All integers (except soft-float integers) are promoted to 64-bit. CCIfType<[i8, i16, i32], CCIfOrigArgWasNotFloat<CCPromoteToType<i64>>>, // The only i32's we have left are soft-float arguments.

Created Apr 25, 2020 // Last Updated Sep 14, 2020

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?