.. _interfaces_differ:
.. default-domain:: c

Отличия в интерфейсах
=====================

Глава описывает любые отличия в поведении системных компонент на Эльбрусе, из-за которых может понадобиться адаптация программ для их корректной работы.

Совместимость с компиляторами
-----------------------------

Компилятор :program:`lcc` стремится к максимальной совместимости с :program:`gcc`.
Версия :program:`lcc-1.24` соответствует :program:`gcc-7.3.0`.

Конструкции языка
~~~~~~~~~~~~~~~~~

Variable length array inside a struct
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Не поддержана недокументированная функция :program:`gcc`: Variable length arrays (VLA) в середине структуры.

Nested functions
^^^^^^^^^^^^^^^^

Не поддержан элемент диалекта GNU C: nested functions.

gcc builtins
~~~~~~~~~~~~

Ряд билтинов (builtin) :program:`gcc` поддержан с ограничениями.
Некоторые из них вызваны особенностями реализации компилятора, другие отсутствием практической необходимости.
С выходом новых версий :program:`lcc` расширяется состав поддержанных билтинов.

Ограничения перечислены в разделе документации на компилятор:

:file:`/opt/mcst/doc/builtin_gnu.html`.

..
 Ряд билтинов (builtin) :program:`gcc` поддержан с ограничениями, перечисленными ниже.
 В заголовках указаны пункты из официальной документации https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/.
 
 
 Раздел 6.49 Getting the Return or Frame Address of a Function
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ограничения:
 
 * Функция :func:`__builtin_return_address` для e2k поддержана только для параметра с нулевым значением.
 * Функция :func:`__builtin_frame_address` поддержана только для параметра с нулевым значением.
 * Функция :func:`__builtin_frob_return_address` не поддержана, не было необходимости.
 
 Раздел 6.50 Using Vector Instructions through Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ограничения:
 
 * Отсутствует поддержка ternary operator ?
 * Отсутствует поддержка logic operators
 
 Раздел 6.54 Built-in Functions to Perform Arithmetic with Overflow Checking
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ограничения:
 
 * Если хотя бы один из аргументов или результат функций :func:`__builtin_add_overflow`,
   :func:`__builtin_sub_overflow` или :func:`__builtin_mul_overflow`
   имеют размер 128 бит, то все аргументы и результат должны иметь одинаковую знаковость.
   В противном случае формально требуется проведение вычислений над 129-битными значениями, это пока не поддержано.
 
 * Функции :func:`__builtin_add_overflow_p`, :func:`__builtin_sub_overflow_p` и :func:`__builtin_mul_overflow_p`
   не поддерживаются в случаях, где требуется constexpr-выражение (инициализаторы, описатели констант enum’а и т.п.)
 
 Раздел 6.55 x86-Specific Memory Model Extensions for Transactional Memory
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Не поддержано, не было необходимости. Возможно реализовать консервативную поддержку.
 
 Раздел 6.56 Object Size Checking Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Поддержано консервативно: код будет компилироваться и исполняться, но не будет контроля за выходом за границу объекта.
 
 Раздел 6.57 Pointer Bounds Checker Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Не поддержано, не было необходимости.
 При необходимости можно будет реализовать консервативную поддержку: код будет компилироваться и исполняться,
 но не будет контроля за выходом за границу выделенной области памяти.
 
 Раздел 6.58 Cilk Plus C/C++ Language Extension Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Не поддержано - в компиляторе отсутствует поддержка языка Cilk Plus C/C++.
 
 Раздел 6.59 Other Built-in Functions Provided by GCC
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Поддержано с ограничениями:
 
 * Отсутствует поддержка функций для работы с типами _Decimal32, _Decimal64, _Decimal128 в связи с отсутствием поддержки этих типов:
 
    * :func:`__builtin_infd32`, :func:`__builtin_infd64`, :func:`__builtin_infd128`
    * :func:`__builtin_nand32`, :func:`__builtin_nand64`, :func:`__builtin_nand128`
    * :func:`__builtin_signbitd32`, :func:`__builtin_signbitd64`, :func:`__builtin_signbitd128`
 
 * Отсутствует поддержка функций для работы с типами _Float32, _Float32x, _Float64, _Float64x, _Float128, _Float128x
   (не путать с типом __float128) в связи с отсутствием поддержки этих типов:
 
    * :func:`__builtin_copysignf32`, :func:`__builtin_copysignf64`, :func:`__builtin_copysignf128`
    * :func:`__builtin_copysignf32x`, :func:`__builtin_copysignf64x`, :func:`__builtin_copysignf128x`
    * :func:`__builtin_fabsf32`, :func:`__builtin_fabsf64`, :func:`__builtin_fabsf128`
    * :func:`__builtin_fabsf32x`, :func:`__builtin_fabsf64x`, :func:`__builtin_fabsf128x`
    * :func:`__builtin_huge_valf32`, :func:`__builtin_huge_valf64`, :func:`__builtin_huge_valf128`
    * :func:`__builtin_huge_valf32x`, :func:`__builtin_huge_valf64x`, :func:`__builtin_huge_valf128x`
    * :func:`__builtin_inff32`, :func:`__builtin_inff64`, :func:`__builtin_inff128`
    * :func:`__builtin_inff32x`, :func:`__builtin_inff64x`, :func:`__builtin_inff128x`
    * :func:`__builtin_nanf32`, :func:`__builtin_nanf64`, :func:`__builtin_nanf128`
    * :func:`__builtin_nanf32x`, :func:`__builtin_nanf64x`, :func:`__builtin_nanf128x`
    * :func:`__builtin_nansf32`, :func:`__builtin_nansf64`, :func:`__builtin_nansf128`
    * :func:`__builtin_nansf32x`, :func:`__builtin_nansf64x`, :func:`__builtin_nansf128x`
 
 * Отсутствует поддержка функций, т.к. реальной необходимости не было, а по описанию gcc нет чёткого понимания:
 
    * :func:`__builtin_alloca_with_align`
    * :func:`__builtin_call_with_static_chain`
 
 * Отсутствует поддержка функций, т.к. реальной необходимости не было. При необходимости можно будет поддержать:
 
    * :func:`__builtin___clear_cache`
    * :func:`__builtin_LINE`, :func:`__builtin_FILE`, :func:`__builtin_FUNCTION`
 
 Раздел 6.60.27 SPARC VIS Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Не поддержано - не было необходимости. При необходимости можно будет поддержать.
 
 Раздел 6.60.32 x86 Built-in Functions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Поддержано с ограничениями:
 
 * Функции, которые работают с типом __float128, поддержаны только для e2k.
   Для e90 (как и для родного sparc) они не нужны, т.к. имеется 128-битный long double.
 
 * Функции ``__builtin_cpu_*`` на текущий момент поддержаны только для e2k.
   :func:`__builtin_cpu_is` имеет свои собственные параметры, отличающиеся от intel’овских, описание смотри в статье
   Поддерживаемые MCST builtin’ы, :file:`/opt/mcst/doc/pragma.html`.
   :func:`__builtin_cpu_supports` не поддержан, т.к. пока не было необходимости.
 
 * Функции ``__builtin_ia32_*`` поддержаны только для e2k, в виде inline-функций, подключаемых через
   ``#include <x86intrin.h>`` или ``#include <immintrin.h>``.
   Вместо добавления директивы #include можно использовать опции
   `-include x86intrin.h` или `-include immintrin.h` соответственно.
 
   Не поддержаны функции, реализующие расширения `avx512*`, а также те специфические расширения,
   которые не могут быть сделаны без поддержки в аппаратуре. К ним относятся расширения:
 
   * fxsr
   * lwp
   * pku
   * rtm
   * sgx
   * xsave\*

Прагмы
~~~~~~~~~~~~~~~

Информация о поддержанных прагмах в документации компилятора:

:file:`/opt/mcst/doc/pragma.html`

OpenMP
~~~~~~~~~~~~~~~

Возможности
^^^^^^^^^^^^^^^

- Поддержан стандарт OpenMP 3.1.
- Доступны языки C, C++, Fortran.

Ограничения
^^^^^^^^^^^

- Для e2k не поддержано в режиме -m128.
- Nested параллелизм не поддержан. Если при исполнении уже распараллеленного цикла встречаются циклы, которые нужно распараллелить,
  то эти (вложенные) циклы будут исполняться последовательно.
- Не поддержан clause collapse.
- Для C/C++ после директивы ``#pragma omp`` всегда должен следовать statement языка.
  Проблемы могут возникнуть для ``#pragma omp barrier`` и ``#pragma omp flush``, если за ними нет statement’а.
  Для обхода проблемы рекомендуется в следующей строке поставить пустой statement, например “0;” или “;”
- Переменные, перечисленные в clause’ах private, lastprivate, firstprivate и threadprivate должны иметь скалярный базовый тип
  или массив скалярного базового типа. В противном случае результат программы неопределен.
- Директива ``#pragma omp for`` не поддержана для итераторов C++.
- Для C/C++ clause’ы if и num_threads своими параметрами могут иметь только константы и переменные целого типа, выражения не допускаются.

Справочный файл
^^^^^^^^^^^^^^^

В компиляторе информация об OpenMP хранится здесь:

:file:`/opt/mcst/doc/openmp.html`


Системные интерфейсы
----------------------

makecontext
~~~~~~~~~~~~

Функция :func:`makecontext` для управления контекстом пользователя реализована на Эльбрусе с другой семантикой.

Отличия:

- Вместо вызова :func:`makecontext` необходимо вызывать :func:`makecontext_e2k`;
- В конце области видимости необходимо вызвать :func:`freecontext_e2k`.
- :func:`makecontext_e2k` возвращает значение ``int``, а не ``void``.
  Значение вызова необходимо проверять на статус ошибки (< 0).

Функции дано другое название, чтобы отображать несовместимость с реализацией на других архитектурах.
