

*******************
Extended attributes
*******************

An *attribute* is a property attachable to functions, data objects,
or types, specified as a keyword. Standard C includes built-in
keywords like ``const`` and ``volatile``.

Extended attributes provide access to behaviors or properties beyond
Standard C. They are either target-specific or useful for embedded
systems.

.. index:: attributes, extended attributes

Overview
========

Attributes can be applied with either keyword syntax (e.g.,
``__tiny``) or attribute syntax (e.g.,
``__attribute__((tiny))``). Both are functionally equivalent,
but the C parser may not accept the keyword form in some situations.

Usage is largely a matter of preference. Preprocessor macros can rename
attributes for portability, enabling them to be toggled off for other
targets or renamed to match different compilers or targets.

.. note::

   The C parser sometimes produces unexpected errors with the keyword
   form of attributes (e.g., ``__tiny``). If this occurs,
   use the ``__attribute__((tiny))`` form instead.

Using attributes
================

Type attributes can be applied to type declarations, following the same
syntax as type qualifiers like ``const`` and ``volatile``.

Syntax for data objects
-----------------------

You can apply attributes to data objects as follows:

.. code-block:: C

   __attribute__((tiny)) int a, b;
   int __tiny c, d;

When applied to an object, the attribute's location is irrelevant.
The example above applies the Direct page attribute to all
defined objects (``a``, ``b``, ``c``, and ``d``).

Syntax for pointer types
------------------------

Attributes can also be applied to pointer types, where their location
is significant. This determines whether the pointer itself is constant
or what it points to is constant.

The easiest way to decipher attributes in function types is to read the
type from right to left.

.. code-block:: C

   int __attribute__((tiny)) * p1;
   long * __attribute__((tiny)) p2;

Here, ``p1`` is a pointer stored in default memory that points to an
``int`` in Direct page memory. ``p2`` is a pointer stored
in Direct page memory that points to a ``long`` in default
memory.

Attribute reference
===================

This section goes through all available extension keywords and
attributes.

Summary of attributes
---------------------

The following table summarizes available attributes. For the keyword
form, prefix with two underscores (e.g., ``__tiny``). For
attribute syntax, use the attribute name with ``__attribute__`` (e.g.,
``__attribute__((tiny))``).

.. table:: Extended attributes summary
 :widths: 1 3
 :column-dividers: none single none
 :column-alignment: left left

 +--------------------------+-----------------------------------------------+
 |Attribute name            |Description                                    |
 +==========================+===============================================+
 | ``aligned(nn)``          | Specify alignment of data object or function  |
 +--------------------------+-----------------------------------------------+
 | ``section("name")``      | Specify section name to use for a data        |
 |                          | object or function                            |
 +--------------------------+-----------------------------------------------+
 | ``tiny``                 | Control storage of data object to direct page |
 +--------------------------+-----------------------------------------------+
 | ``near``                 | Control storage of data object to near bank   |
 +--------------------------+-----------------------------------------------+
 | ``far``                  | Control storage of data object to far memory  |
 +--------------------------+-----------------------------------------------+
 | ``huge``                 | Control storage of data object to huge memory |
 +--------------------------+-----------------------------------------------+
 | ``interrupt``            | Used to define an interrupt function          |
 +--------------------------+-----------------------------------------------+
 | ``intrinsic``            | Used to declare an intrinsic function         |
 +--------------------------+-----------------------------------------------+
 | ``saveds``               | Entry point that needs to initialize          |
 |                          | the direct page and data bank registers       |
 +--------------------------+-----------------------------------------------+
 | ``task``                 | Relaxes preserving registers                  |
 +--------------------------+-----------------------------------------------+


Description of attributes
-------------------------

This section describes each attribute in detail.

.. index:: aligned; attribute, attribute; aligned, alignment

``aligned``
^^^^^^^^^^^

This attribute can be applied to functions, global and static data
objects to force a certain minimal alignment.

The ``aligned`` attribute takes an argument which is the alignment to
use:

.. code-block:: C

   __attribute__((aligned(16))) struct sprite ship;

.. note::

   Certain data types may impose an alignment by themselves. The
   actual alignment is choosen so that all alignment constraints are
   satisfied.

.. index:: section; attribute, attribute; section

``section``
^^^^^^^^^^^

This attribute can be applied to functions, global and static data
objects to control the name of the section it is placed in.

The ``section`` attribute takes an argument which is the section name
to use:

.. code-block:: C

   // Place in vram
   __attribute__((section("vram")))
   const char tiles[256] = { .. };

   __attribute__((section("trueCode")))
   long foo () {
     return 42;
   }

See :ref:`section-pragma` for how you can specify a section for multiple
functions,
global and static data objects.

.. index:: tiny; attribute, attribute; tiny, direct page

``tiny``
^^^^^^^^

This specifies a data object or a pointer to a data object that
resides in the *direct page*. Direct page addressing results in shorter and
faster code. It is especially efficient when working with pointers on
the 65816.

.. note::

   Auto variables are normally allocated to registers or direct page
   pseudo registers which means you will automatically get the
   benefits of direct page addressing when using auto
   variables. The ``tiny`` attribute is best used for smaller
   frequently used static data objects.

.. index:: near; attribute, attribute; near

``near``
^^^^^^^^

This specifies a data object or a pointer to a data object that
resides in a single 64K bank. Near bank addressing is a middle ground
that is fairly efficient, but not as efficient as using the direct page.
It results in shorter code than the ``far`` and ``huge`` attributes
and being 64K it provides ample space.

.. index:: far; attribute, attribute; far

``far``
^^^^^^^

This specifies a data object or a pointer to a data object that can
reside anywhere in memory. The only limitation is that a single data
object can be at most 64K minus one byte large.

The code needed to access far memory tends to be somewhat larger than
the near bank, but the 65816 is still capable of using various
addressing modes for reasonable good performance.

.. index:: far24; attribute, attribute; far24

``far24``
^^^^^^^^^

This specifies a data object or a pointer to a data object that can
reside anywhere in memory. The only limitation is that a single data
object can be at most 64K minus one byte large.

A ``far24`` pointer is similar to ``far`` with the difference that
it occupies 24 bits in memory.

.. note::

   The ``far24`` attribute is intended to be used when writing to data
   structures where you actually want a write to be exactly 24 bits.
   This may be required by hardware or function API. The compiler will
   normally allocate 32 bits for wide pointers such as ``far`` and
   ``huge`` in order to make more efficient code on the 65816.

.. index:: huge; attribute, attribute; huge

``huge``
^^^^^^^^

This specifies a data object or a pointer to a data object that can
reside anywhere in memory and that has no size limitations other than
the addressable 16MB range.

The generated code for using this attribute tends to be larger than
any of the other alternatives. At best you can get something that is
the same or similar as ``far``, but in many cases the code will be
larger and slower.

.. index:: interrupt; attribute, attribute; interrupt

``interrupt``
^^^^^^^^^^^^^

An interrupt function is meant to serve as an interrupt handler. The
interrupt has the following effects:

 #. An interrupt function cannot take any parameters

 #. An interrupt function will preserve all registers used

 #. Leaving the interrupt function uses a different instruction
    sequence compared to normal functions

 #. The interrupt attribute may optionally be given a vector address
    as an argument

.. index:: interrupt;  vector

The interrupt vector specified is given as an argument to the
interrupt attribute:

.. code-block:: C

   int counter;

   __attribute__((interrupt(0xfffe)))
   void irq () {
     counter++;
   }

.. note::

   The vector argument is optional. Omitting it means that there will be
   no vector section entry generated for that interrupt function.
   You can also suppress all vector sections from being generated by
   using the ``--no-vector-sections`` command-line option.

.. note::

   It is strongly recommended to make your interrupt functions small
   and simple. Also avoid making function calls from an interrupt
   function. A function call means the interrupt needs to preserve
   scratch registers, which is costly. If you must use function calls,
   consider forcing them to be inline expanded See :ref:`inline`
   for more information.

.. index:: intrinsic; attribute, attribute; intrinsic

``intrinsic``
^^^^^^^^^^^^^

The intrinsic attribute is used to declare intrinsic built-in
functions. This can only be done on intrinsic functions that is
already known to the compiler. Normally you use this by including the
``calypsi/intrinsics65816.h`` file which contains all such valid declarations.

.. index:: saveds; attribute, attribute; saveds

``saveds``
^^^^^^^^^^

A ``saveds`` function is useful for API functions called from another
context. The direct page and data bank are initialized to suit the
current runtime environment. The previous values of these registers
are restored when the function returns. This makes it possible to call
an API function from another context where different values may be
used for these base registers.

.. note::

   For ``saveds`` API calls, you should generally prevent arguments
   from being passed on the direct page. Use either a single register
   argument or the ``simple_call`` calling convention to force arguments
   onto the stack. Direct page differences when using ``saveds`` mean
   accessing caller-placed arguments there will not work.

.. note::

   When using ``saveds`` for API functions you most likely want to use
   the ``saveds`` attribute on C written ``interrupt`` functions as
   well, as interrupts may be triggered at any time.

.. index:: task; attribute, attribute; task

``task``
^^^^^^^^

A ``task`` attribute can be used on functions such as ``main`` which
is the start of the application. You will not normally call such
functions from any C code. In that case you can apply the ``task``
attribute which relaxes preserving registers that would otherwise be
saved on the stack. This can save a little stack space and will make
the application a tiny bit smaller.
