Commit 4199116d authored by Kunshan Wang's avatar Kunshan Wang

Renamed types.

func->funcref, thread->threadref, stack->stackref,
ptr->uptr, funcptr->ufuncptr.
parent 1c3d9784
......@@ -63,14 +63,14 @@ return type is omitted, it returns ``void``.
Thread and Stack operations
===========================
- ``[0x201]@uvm.new_thread (%s: stack) -> thread``
- ``[0x201]@uvm.new_thread (%s: stackref) -> threadref``
Create a new thread for a given stack ``%s``. The stack must be in the **READY**
state. After executing ``@uvm.new_thread``, the stack enters the **ACTIVE**
state and the new thread starts running immediately. Return the handle to the
newly created thread.
- ``[0x202]@uvm.kill_stack (%s: stack)``
- ``[0x202]@uvm.kill_stack (%s: stackref)``
Destroy the given stack ``%s``. The stack ``%s`` must be in the **READY** state
and will enter the **DEAD** state.
......@@ -80,7 +80,7 @@ and will enter the **DEAD** state.
Stop the current thread and kill the current stack. The current stack will enter
the **DEAD** state. The current thread stops running.
- ``[0x204]@uvm.current_stack -> stack``
- ``[0x204]@uvm.current_stack -> stackref``
Return the current stack.
......@@ -227,7 +227,7 @@ the return value.
Native Interface
================
- ``[0x240]@uvm.native.pin <T> (%opnd: T) -> ptr<U>``
- ``[0x240]@uvm.native.pin <T> (%opnd: T) -> uptr<U>``
*T* must be ``ref<U>`` or ``iref<U>`` for some U.
......@@ -244,7 +244,7 @@ whole object (as returned by the ``GETIREF`` instruction). If *opnd* is
Remove one instance of the reference ``%opnd`` from the pinning multiset of the
current thread. It has undefined behaviour if no such an instance exists.
- ``[0x242]@uvm.native.expose [callconv] <[sig]> (%func: func<sig>, %cookie: int<64>) -> U``
- ``[0x242]@uvm.native.expose [callconv] <[sig]> (%func: funcref<sig>, %cookie: int<64>) -> U``
*callconv* is a platform-specific calling convention flag. *U* is determined by
the calling convention and *sig*.
......
This diff is collapsed.
......@@ -17,6 +17,7 @@ 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.
All non-native-safe types have unspecified sizes and alignments.
.. table:: Mapping between Mu and C types
......@@ -32,15 +33,15 @@ the following table. The unit of sizes and alignments is byte, which is 8 bits.
``vector<int<8> 4>`` ``__m128`` 16 16
``vector<float 4>`` ``__m128`` 16 16
``vector<double 2>`` ``__m128`` 16 16
``ptr<T>`` ``T *`` 8 8
``funcptr<sig>`` ``T (*) ()`` 8 8
``ref<T>`` N/A 8 8
``iref<T>`` N/A 16 16
``weakref<T>`` N/A 8 8
``tagref64`` N/A 8 8
``func<sig>`` N/A 8 8
``thread`` N/A 8 8
``stack`` N/A 8 8
``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
``int<1>`` N/A unspecified unspecified
``int<6>`` N/A unspecified unspecified
``int<52>`` N/A unspecified unspecified
......@@ -87,9 +88,10 @@ The Default Calling Convention
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
types according to the above table. Mu ``struct`` types are mapped to C structs
of corresponding members. Mu ``array`` types and ``hybrid`` types cannot be used
as parameters or return values.
types according to the above table. 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.
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
......@@ -98,20 +100,18 @@ corresponding C types.
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).
Even if the signature is not "perfectly" matching (for example, an int/long
is passed when a pointer is expected, Mu still interprets the incoming
is passed when a pointer is expected, Mu must still interpret the incoming
arguments strictly according to the ABI, i.e. interpreting the integer value
in the register as an address).
If a Mu function of signature *sig* is exposed with the *default* calling
convention, the resulting value has ``funcptr<sig>`` type, i.e. it is a function
pointer which can be called (by either Mu or native programs) with the
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
*default* calling convention.
It has undefined behaviour during the exception handling/unwinding process if
the personality function does not report success in the direct callee of a
``CCALL`` instruction.
It has undefined behaviour when the native program attempts to unwind Mu frames.
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.
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.
.. vim: tw=80
......@@ -87,12 +87,12 @@ Pointers
--------
A **pointer** is an address in the memory space of the current process. A
pointer can be a **data pointer** (type ``ptr<T>``) or **function pointer**
(type ``funcptr<sig>``). The former assumes a data value is stored in a region
pointer can be a **data pointer** (type ``uptr<T>``) or **function pointer**
(type ``ufuncptr<sig>``). The former assumes a data value is stored in a region
beginning with the address. The latter assumes a piece of executable machine
code is located at the address.
``ptr<T>``, ``funcptr<sig>`` and ``int<n>``, where ``T`` is a type, ``sig`` is a
``uptr<T>``, ``ufuncptr<sig>`` and ``int<n>``, where ``T`` is a type, ``sig`` is a
function signature, can be cast to each other using the ``PTRCAST`` instruction.
The address is preserved and the ``int<n>`` type has the numerical value of the
address. Type checking is not performed.
......@@ -259,8 +259,8 @@ Changes in the Mu IR and the API
**New types**:
* ``ptr < T >``
* ``funcptr < sig >``
* ``uptr < T >``
* ``ufuncptr < sig >``
See `Type System <type-system>`__
......@@ -299,7 +299,7 @@ See `Instruction Set <instruction-set>`__ and `Common Instructions
* ``CCALL``
Memory addressing instructions take an additional ``PTR`` flag. If this flag is
present, the location operand must be ``ptr<T>`` rather than ``iref<T>``. For
present, the location operand must be ``uptr<T>`` rather than ``iref<T>``. For
example:
* ``%new_ptr = GETFIELDIREF PTR <@some_struct 3> %ptr_to_some_struct``
......@@ -325,10 +325,10 @@ See `Instruction Set <instruction-set>`__.
**Modified API messages**:
The following messages: ``get_field_iref``, ``get_elem_iref``, ``shift_iref``,
``get_fixed_part_iref``, ``get_var_part_iref``, ``load``, ``store``,
``cmpxchg`` and ``atomicrmw`` work for both ``ptr<T>`` and ``iref<T>`` operands.
No changes to the parameters are required. The return values for memory
addressing messages are ``ptr<U>`` rather than ``iref<U>`` for some type U.
``get_fixed_part_iref``, ``get_var_part_iref``, ``load``, ``store``, ``cmpxchg``
and ``atomicrmw`` work for both ``uptr<T>`` and ``iref<T>`` operands. No
changes to the parameters are required. The return values for memory addressing
messages are ``uptr<U>`` rather than ``iref<U>`` for some type U.
TODO: Currently the API assumes each handle has an attached type, and does
not require the client to supply the types for handles when using them. Is
......
......@@ -62,9 +62,9 @@ implemented.
The void type ``void`` is required.
A function type ``func<Sig>`` is required if ``Sig`` is implemented.
A function type ``funcref<Sig>`` is required if ``Sig`` is implemented.
The opaque types ``thread`` and ``stack`` are both required.
The opaque types ``threadref`` and ``stackref`` are both required.
The tagged reference type ``tagref64`` is optional.
......@@ -72,7 +72,7 @@ A function signature ``R (P0 P1 ...)`` is required if all of its parameter types
and its return type are implemented and there are at most 256 parameters.
Otherwise optional.
Pointer types ``ptr<T>`` and ``funcptr<sig>`` are required for required and
Pointer types ``uptr<T>`` and ``ufuncptr<sig>`` are required for required and
native-safe types ``T`` and signatures ``sig``. Both are represented as
integers, but their lengths are implementation-defined.
......@@ -183,15 +183,15 @@ implementation-defined behaviours.
The following types are required for both non-atomic and atomic ``LOAD`` and
``STORE`` for all implemented ``T`` and ``Sig``: ``int<8>``, ``int<16>``,
``int<32>``, ``int<64>``, ``float``, ``double``, ``ref<T>``, ``iref<T>``,
``weakref<T>``, ``func<Sig>``, ``thread``, ``stack``, ``ptr<T>`` and
``funcptr<Sig>``.
``weakref<T>``, ``funcref<Sig>``, ``threadref``, ``stackref``, ``uptr<T>`` and
``ufuncptr<Sig>``.
The following types are required for non-atomic ``LOAD`` and ``STORE``:
``vector<int<32> 4>``, ``vector<float 4>`` and ``vector<double 2>``.
``int<32>``, ``int<64>``, ``ref``, ``iref``, ``weakref``, ``func``, ``stack``,
``thread``, ``ptr`` and ``funcptr`` are required for ``CMPXCHG`` and the
``XCHG`` operation of the ``ATOMICRMW`` instruction.
``int<32>``, ``int<64>``, ``ref``, ``iref``, ``weakref``, ``funcref``,
``threadref``, ``stackref``, ``uptr`` and ``ufuncptr`` are required for
``CMPXCHG`` and the ``XCHG`` operation of the ``ATOMICRMW`` instruction.
``int<32>`` and ``int<64>`` are required for all ``ATOMICRMW`` operations.
......
......@@ -13,7 +13,7 @@ resources. Mu also has a memory model. See the `Memory Model <memory-model>`__
chapter for more information.
This chapter discusses Mu threads and Mu stacks. In this chapter, "thread"
means "Mu thread".
means "Mu thread" unless explicitly stated otherwise.
Concepts
========
......@@ -121,7 +121,7 @@ the client orders the current thread to terminate in a trap handler.
The ``@uvm.thread_exit`` instruction kills the current stack of the current
thread.
Mu may change the value of ``thread`` type to ``NULL`` if the thread it
Mu may change the value of ``threadref`` type to ``NULL`` if the thread it
refers to is terminated.
Binding of Stack and Thread
......@@ -207,7 +207,7 @@ stack enters the **DEAD** state.
If a stack becomes unreachable from roots, the garbage collector may kill the
stack.
The Mu may change the value of ``stack`` type to ``NULL`` if the stack it
The Mu may change the value of ``stackref`` type to ``NULL`` if the stack it
refers to is in the **DEAD** state.
On-stack Replacement
......
This diff is collapsed.
......@@ -286,6 +286,21 @@ An **instruction** has the following form:
``id`` is the ID of the instruction. ``instbody`` is instruction body which is
specific to each instruction. See `<instruction-set>`__ for an exhaustive list.
Function Exposing Definition
============================
Function declaration has the following form:
+------+-----+------+----------+--------+
| opct | idt | idt | opct | idt |
+======+=====+======+==========+========+
| 0x07 | id | func | callConv | cookie |
+------+-----+------+----------+--------+
``id`` is the ID of the exposed value. ``func`` is the ID of the function to
expose. ``callConv`` is the calling convention flag. ``cookie`` is the cookie,
the ID of an ``int<64>`` constant.
Name Binding
============
......@@ -298,7 +313,7 @@ A name binding has the following form:
+------+-----+--------+-------+-------+-----+
| opct | idt | lent | i8 | i8 | ... |
+======+=====+========+=======+=======+=====+
| 0x07 | id | nbytes | byte1 | byte2 | ... |
| 0x08 | id | nbytes | byte1 | byte2 | ... |
+------+-----+--------+-------+-------+-----+
``id`` is the ID to bind. ``nbytes`` is the number of bytes in the name and
......@@ -357,16 +372,16 @@ form::
.typedef @65546 = void
// 01 0a 00 01 00 0a
// @f @sig2
.typedef @65547 = func <@65552>
// @f @sig2
.typedef @65547 = funcref<@65552>
// 01 0b 00 01 00 0b 10 00 01 00
// @thread
.typedef @65548 = thread
.typedef @65548 = threadref
// 01 0c 00 01 00 0c
// @stack
.typedef @65549 = stack
.typedef @65549 = stackref
// 01 0d 00 01 00 0d
// @tagref64
......@@ -450,7 +465,10 @@ form::
}
// .expose @func0_exposed = @func0 #DEFAULT @const1
07 50 00 01 00 04 00 01 00 00 21 00 01 00
// Bind ID 65604 with the string "@sig2_v1.entry"
07 44 00 01 00 06 40 73 69 67 32 5f 76 31 2e 65 6e 74 72 79
08 44 00 01 00 06 40 73 69 67 32 5f 76 31 2e 65 6e 74 72 79
.. vim: textwidth=80
......@@ -400,7 +400,7 @@ A **constant constructor** can be the following:
data structure in the global memory or allocate it in the heap and assign
its reference to a global cell. In fact, the ID or the name of any global
cell is a constant SSA variable of an internal reference to it. The ID or
the name of a Mu function is a constant SSA variable of a ``func``.
the name of a Mu function is a constant SSA variable of a ``funcref``.
..
......@@ -443,14 +443,14 @@ A **constant constructor** can be the following:
.typedef @iref_void = iref<@void>
.const @null_iref <@iref_void> = NULL
.typedef @some_func = func<@noparamsnoret>
.typedef @some_func = funcref<@noparamsnoret>
.const @null_func <@some_func> = NULL
.typedef @thread = thread
.const @null_thread <@thread> = NULL
.typedef @tref = threadref
.const @null_tr <@tref> = NULL
.typedef @stack = stack
.const @null_stack <@stack> = NULL
.typedef @sref = stackref
.const @null_sr <@sref> = NULL
.typedef @4xfloat = vector <@float 4>
.const @vec1 <@4xfloat> = VEC { @float1 @float2 @float3 @float4 }
......@@ -464,8 +464,8 @@ A **constant constructor** can be the following:
.const @record2 <@record2_t> = {@g1 @f1}
.typedef @ptri64 = ptr<@i64>
.typedef @fpnoparamsnoret = funcptr<@noparamsnoret>
.typedef @ptri64 = uptr<@i64>
.typedef @fpnoparamsnoret = ufuncptr<@noparamsnoret>
// Address should be looked up before generating the bundle.
.const @ptrconst <@ptri64> = 0x12345678
......
......@@ -122,15 +122,16 @@ Initial Values
The initial value of any memory location is defined as the following, according
the type of data value the memory location represents:
* The initial value of ``int`` is 0.
* The initial value of ``int`` and pointer types is 0 (numerical value or
address).
* The initial value of floating point types is positive zero.
* The initial value of ``ref``, ``iref``, ``weakref``, ``func``, ``stack``
and ``thread`` is ``NULL``.
* The initial value of ``ref``, ``iref``, ``weakref``, ``funcref``, ``stackref``
and ``threadref`` is ``NULL``.
* The initial value of ``tagref64`` is a floating point number which is
positive zero.
* The initial values of all fields or elements in ``struct``, ``array`` and
the variable part of ``hybrid`` are the initial values according to their
respective types.
* The initial values of all fields or elements in ``struct``, ``array``,
``vector`` and the variable part of ``hybrid`` are the initial values
according to their respective types.
Garbage Collection
------------------
......@@ -268,7 +269,7 @@ Memory Operations on Pointers
Load, store, compare exchange and atomic-x operations can work with native
memory in addition to Mu memory locations. In this case, the *loc* parameter of
the above operations become a region of bytes in the native memory (usually
represented as ``ptr<T>``) rather than memory locations (usually represented as
represented as ``uptr<T>``) rather than memory locations (usually represented as
``iref<T>``).
Only *native-safe* types can be accessed via pointers.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment