native-interface-x64-unix.rst 6.5 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
===========================
AMD64 Unix Native Interface
===========================

This is the native interface for AMD64 on Unix-like operating systems.

Memory Layout
=============

The memory layout of the native memory uses the `System V Application Binary
Interface for x86-64 <http://www.x86-64.org/documentation_folder/abi.pdf>`__
(referred to as "the AMD64 ABI" from now on) as a reference. It is recommended
that the Mu memory also use this memory layout, but is not required since the Mu
memory it is never externally visible unless explicitly pinned.

Data in the native memory uses the sizes and alignments of types are listed in
the following table. The unit of sizes and alignments is byte, which is 8 bits.
Kunshan Wang's avatar
Kunshan Wang committed
18
All non-native-safe types have unspecified sizes and alignments.
Kunshan Wang's avatar
Kunshan Wang committed
19

Kunshan Wang's avatar
Kunshan Wang committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33
.. table:: Mapping between Mu and C types

    =========================== ======================= =============== ================
    Mu type                     C type                  Size            Alignment
    =========================== ======================= =============== ================
    ``int<8>``                  ``char``                1               1
    ``int<16>``                 ``short``               2               2
    ``int<32>``                 ``int``                 4               4
    ``int<64>``                 ``long``, ``long long`` 8               8
    ``float``                   ``float``               4               4
    ``double``                  ``double``              8               8
    ``vector<int<8> 4>``        ``__m128``              16              16
    ``vector<float  4>``        ``__m128``              16              16
    ``vector<double 2>``        ``__m128``              16              16
Kunshan Wang's avatar
Kunshan Wang committed
34 35 36 37 38 39 40 41 42
    ``uptr<T>``                 ``T *``                 8               8
    ``ufuncptr<sig>``           ``T (*) ()``            8               8
    ``ref<T>``                  N/A                     unspecified     unspecified
    ``iref<T>``                 N/A                     unspecified     unspecified
    ``weakref<T>``              N/A                     unspecified     unspecified
    ``tagref64``                N/A                     unspecified     unspecified
    ``funcref<sig>``            N/A                     unspecified     unspecified
    ``threadref``               N/A                     unspecified     unspecified
    ``stackref``                N/A                     unspecified     unspecified
43
    ``framecursorref``          N/A                     unspecified     unspecified
44
    ``irbuilderref``            N/A                     unspecified     unspecified
Kunshan Wang's avatar
Kunshan Wang committed
45 46 47 48 49 50 51 52
    ``int<1>``                  N/A                     unspecified     unspecified
    ``int<6>``                  N/A                     unspecified     unspecified
    ``int<52>``                 N/A                     unspecified     unspecified
    ``int<n>``                  unspecified             unspecified     unspecified
    ``vector<T n>``             unspecified             unspecified     unspecified
    =========================== ======================= =============== ================

..
Kunshan Wang's avatar
Kunshan Wang committed
53 54 55 56 57 58 59 60 61 62 63

    NOTE: Although ``int<1>`` is required and ``int<6>`` and ``int<52>`` are
    required when ``tagref64`` is implemented, their memory layout is
    unspecified because memory access instructions ``LOAD``, ``STORE``, etc. are
    not required to support those types. It it not recommended to include those
    types in the memory because they may never be loaded or stored.

    Although vectors of other lengths are not required by a Mu implementation,
    implementations are encouraged to support them in a way compatible with the
    AMD64 ABI.

64
The structure type ``struct<...>`` and the hybrid type ``hybrid<Fs V>`` is
Kunshan Wang's avatar
Kunshan Wang committed
65 66
aligned to its most strictly aligned component. Each member is assigned to the
lowest available offset with the appropriate alignment. This rule applies to
67 68 69
hybrids as if the hybrid ``hybrid<Fs V>`` is a struct of fields ``Fs`` followed
by a flexible array member (as in C99) ``V fam[];``.  Arrays ``array<T>`` use
the same alignment as its elements.
Kunshan Wang's avatar
Kunshan Wang committed
70 71 72 73 74 75 76 77 78 79 80 81 82

    NOTE: There is no union types in Mu. Arrays do not have special rules of
    16-byte alignment as the AMD64 ABI does. Mu arrays must be declared as an
    array of vectors (such as ``array<vector<int<32> 4> 100>``) to be eligible
    for vector access.

Both integers and floating point numbers are little-endian (lower bytes in lower
addresses). Signed integers use the 2's complement representation. Elements with
lower indexes in a vector is stored in lower addresses in the memory.

Calling Convention
==================

Kunshan Wang's avatar
Kunshan Wang committed
83 84
The calling convention between Mu functions is implementation-defined.

85 86
The Default Calling Convention
------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
87

88 89 90
The *default* calling convention, denoted by the ``#DEFAULT`` flag in the IR,
follows the AMD64 ABI in register usage, stack frame structure, parameter
passing and returning. The parameter types and the return types are mapped to C
91 92
types according to the above table. Functions in this calling convention can
return at most one value. As a special case, if the native function signature
Kunshan Wang's avatar
Kunshan Wang committed
93 94 95 96
returns void, the corresponding Mu signature returns no values ``(...) -> ()``.
Mu ``struct`` and ``array`` types are mapped to C structs of corresponding
members. ``array`` cannot be the type of parameters or return values because C
disallows this, but arrays within structs and pointers to arrays are is allowed.
Kunshan Wang's avatar
Kunshan Wang committed
97

98 99 100
Arguments and return values are passed in registers and the memory according to
the AMD64 ABI, with the types of Mu arguments and the return type mapped to the
corresponding C types.
Kunshan Wang's avatar
Kunshan Wang committed
101 102 103

    NOTE: This is to say, C programs can call Mu functions with a "compatible"
    signature (that is, parameters and return values match the above table).
104
    Even if the signature is not "perfectly" matching (for example, an int/long
Kunshan Wang's avatar
Kunshan Wang committed
105
    is passed when a pointer is expected, Mu must still interpret the incoming
Kunshan Wang's avatar
Kunshan Wang committed
106 107
    arguments strictly according to the ABI, i.e. interpreting the integer value
    in the register as an address).
Kunshan Wang's avatar
Kunshan Wang committed
108

109
If a Mu function of signature *sig* is exposed with the *default* calling
Kunshan Wang's avatar
Kunshan Wang committed
110 111
convention, the resulting value has ``ufuncptr<sig>`` type, i.e. it is a
function pointer which can be called (by either Mu or native programs) with the
112
*default* calling convention.
113

Kunshan Wang's avatar
Kunshan Wang committed
114
It has undefined behaviour when the native program attempts to unwind Mu frames.
115

Kunshan Wang's avatar
Kunshan Wang committed
116 117
    NOTE: This means C ``longjmp`` and C++ exceptions must not go through Mu
    frames, but as long as they are handled **above** any Mu frames, it is safe.
118

Kunshan Wang's avatar
Kunshan Wang committed
119
.. vim: tw=80