

.. index:: intrinsic functions, built-in functions
.. index:: functions, intrinsic, functions, built-in

.. _intrinsic-functions:

*******************
Intrinsic functions
*******************

This chapter covers predefined intrinsic and built-in functions.

Intrinsics functions appear as ordinary calls but are special compiler
constructs, emitting specific instruction sequences. To enable them,
include the ``calypsi/intrinsics6502.h`` header file.

Built-in functions are similar, but they are not declared in
``calypsi/intrinsics6502.h``.

Intrinsic functions reference
=============================

The ``calypsi/intrinsics6502.h`` file appears as follows:

.. literalinclude:: ../../../../lib/target/MOS6502/include/calypsi/intrinsics6502.h
   :language: C


Summary of intrinsic functions
------------------------------

.. table:: Intrinsic functions summary
 :widths: 2 3
 :column-dividers: none single none
 :column-alignment: left left

 +-------------------------------+------------------------------------------------+
 |Function name                  |Description                                     |
 +===============================+================================================+
 | ``__disable_interrupts``      | Disable interrupts                             |
 +-------------------------------+------------------------------------------------+
 | ``__enable_interrupts``       | Enable interrupts                              |
 +-------------------------------+------------------------------------------------+
 | ``__get_interrupt_state``     | Get the current interrupt state                |
 +-------------------------------+------------------------------------------------+
 | ``__restore_interrupt_state`` | Restore to a previous interrupt state          |
 +-------------------------------+------------------------------------------------+
 | ``__get_return_address``      | Gets the return address of the current         |
 |                               | function                                       |
 +-------------------------------+------------------------------------------------+
 | ``__set_return_address``      | Alters the return address of the current       |
 |                               | function                                       |
 +-------------------------------+------------------------------------------------+
 | ``__break_instruction``       | Generates a ``BRK`` instruction (not           |
 |                               | available on 65B02)                            |
 +-------------------------------+------------------------------------------------+
 | ``__break_with``              | Generates a ``BRK`` instruction with an        |
 |                               | argument                                       |
 +-------------------------------+------------------------------------------------+
 | ``__no_operation``            | Generates a ``NOP`` instruction                |
 +-------------------------------+------------------------------------------------+
 | ``__wait_for_interrupt``      | Waits for an interrupt (65C02 and              |
 |                               | 65CNR02 cores only)                            |
 +-------------------------------+------------------------------------------------+
 | ``__stop_processor``          | Stops the processor (65C02 and 65CNR02 cores   |
 |                               | only)                                          |
 +-------------------------------+------------------------------------------------+
 | ``__builtin_clz``             | Counts leading zeroes in an ``int``            |
 +-------------------------------+------------------------------------------------+
 | ``__builtin_clzl``            | Counts leading zeroes in a ``long``            |
 +-------------------------------+------------------------------------------------+
 | ``__builtin_clzll``           | Counts leading zeroes in a ``long long``       |
 +-------------------------------+------------------------------------------------+
 | ``__builtin_signbit``         | Gets the value of the sign bit                 |
 +-------------------------------+------------------------------------------------+
 | ``__kernel_call_failed``      | Checks for failure after a system call in a    |
 |                               | kernel, returning status in the carry flag     |
 +-------------------------------+------------------------------------------------+


Description of intrinsic functions
-----------------------------------

This section details each intrinsic function.

``__disable_interrupts``
^^^^^^^^^^^^^^^^^^^^^^^^

Emits a machine instruction that *disables* interrupts.

``__enable_interrupts``
^^^^^^^^^^^^^^^^^^^^^^^

Emits a machine instruction that *enables* interrupts.

``__get_interrupt_state``
^^^^^^^^^^^^^^^^^^^^^^^^^

Returns the current interrupt state as a
``__interrupt_state_t`` value, which can be used as follows:

.. code-block:: C

   int global;

   void safe_increment () {
     __interrupt_state_t state = __get_interrupt_state();
     __disable_interrupts;
     global++;
     __restore_interrupt_state(state);
   }

In the example the current state of interrupts is obtained and saved
Returns the current interrupt state as a ``__interrupt_state_t`` value,
do the real work. Finally, the interrupt state is restored to what it
was when the function was entered.

``__restore_interrupt_state``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Restores to a previous interrupt state, see example above.

``__get_return_address``
^^^^^^^^^^^^^^^^^^^^^^^^

Reads the return address of the current function from its stack
frame.

``__set_return_address``
^^^^^^^^^^^^^^^^^^^^^^^^

Replaces the current function return address
with the address provided in the argument to ``__set_return_address()``.

``__no_operation``
^^^^^^^^^^^^^^^^^^

Emits a ``NOP`` machine instruction.

``__break_instruction``
^^^^^^^^^^^^^^^^^^^^^^^
Emits a machine instruction that causes a break exception.

``__break_with``
^^^^^^^^^^^^^^^^

Emits a break exception instruction. This variant takes an opcode
argument for the ``BRK`` instruction second byte.

``__wait_for_interrupt``
^^^^^^^^^^^^^^^^^^^^^^^^

Emits an instruction that causes the 65C02 (or 65CNR02) to wait for an
interrupt. Execution then resumes with the interrupt, followed by
normal execution. This functionality is not available on the plain
6502.

``__stop_processor``
^^^^^^^^^^^^^^^^^^^^

Emits an instruction that causes the 65C02 (or 65CNR02) to halt execution. This
functionality is not available on the plain 6502.

``__builtin_clz``
^^^^^^^^^^^^^^^^^

Count the number of leading zeroes in a provided ``int`` value.
Returns an undefined result if input is zero.

``__builtin_clzl``
^^^^^^^^^^^^^^^^^^

Count the number of leading zeroes in a provided ``long`` value.
Returns an undefined result if input is zero.

``__builtin_clzll``
^^^^^^^^^^^^^^^^^^^

Count the number of leading zeroes in a provided ``long long`` value.
Returns an undefined result if input is zero.

``__builtin_signbit``
^^^^^^^^^^^^^^^^^^^^^

Returns the value (``0`` or ``1``) of the signbit of its input.

.. index:: Kernel; kernel call, kernel call; MicroKernel , kernel call; Commodore

``__kernel_call_failed``
^^^^^^^^^^^^^^^^^^^^^^^^

This intrinsic wraps a Commodore-style kernel system call,
testing the carry flag return value. It can be used as follows:

.. code-block:: C

   #include <microkernel.h>

   void bcd_time() {
     if (__kernel_call_failed(MicroKernelGetTime())) {
       // Handle failure
       ...
     } else {
       // Success
       ...
     }
   }

.. note::

   This intrinsic assumes that it surrounds a MicroKernel call
   expression, if that is not the case the result is unpredictable.
