.. _reference_iset:

Команды микропроцессора
===================================== 

Данный раздел - справочное руководство по командам ассемблера «Эльбрус».

Здесь представлены наиболее часто используемые команды в ассемблерной мнемонике.
Их можно увидеть в ассемблерном коде, получаемом с помощью компилятора, при подаче в строку компиляции опции :option:`-S`.
Вместо файла :file:`<sourcefile>.o` будет сгенерирован файл :file:`<sourcefile>.s`.
Возможно также использовать дизассемблер (:program:`objdump` из ``binutils``, :program:`ldis` из :file:`/opt/mcst/`,
встроенный дизассемблер отладчика и т.д.) для просмотра команд объектного кода в ассемблерной мнемонике.

..
 Описание всех команд находится в полной документации на микропроцессор Эльбрус в разделе Instructions Set **CHECK_ME**

Структура описания операции
---------------------------

Краткое описание формы:

::

  ADDs/d	(.s)	sss/ddd		сложение целых 32/64
   |            |	|||		 |
   |            |	|||		краткий комментарий
   |            |	|||
   |            |	формат операндов и результата (результат занимает правую 
   |		|	позицию): в примере операция ADDs принимает 
   |		|	операнды одинарного формата и производит результат одинарного
   |            |	формата, тогда как операция ADDd  - значения двойного формата;
   |		|	используются следующие правила:
   |            |	s - операнд или результат является значением одинарного формата
   |            |	    в регистровом файле
   |            |	d - операнд или результат является значением двойного формата
   |            |	    в регистровом файле
   |            |	x - операнд или результат является значением расширенного 
   |            |	    формата в регистровом файле
   |            |	q - операнд или результат является значением квадро формата
   |            |	    в регистровом файле
   |            |	b - операнд или результат является предикатом
   |            |	    в предикатном файле
   |            |	v - операнд или результат является предикатом, 
   |            |	    вычисленным в текущей широкой команде
   |		|	e - результат операции управляет выполнением других операций 
   |            |	    в текущей широкой команде (предикатное выполнение)
   |            |	r - операнд или результат является регистром состояния
   |            |	i - операнд является непосредственной константой из текущей 
   |            |	    широкой команды
   |            |	- - отсутствие операнда
   |            |
   |		признак спекулятивного исполнения операции
   |
   мнемоника операции (в примере - ADDs или ADDd)

Для обозначения битовых векторов приведём фрагмент описания операции:

::

  getfs           src1, src2, dst

Пример структуры числового аргумента в операции:

::

    Size = (bitvect)src2[10:6];

Здесь и далее (bitvect)value означает представление числа value в виде битового вектора,
а (bitvect)value[beg:end] - подвектор битового вектора между позициями beg и end.

Спекулятивное исполнение
------------------------

Большую часть команд микропроцессора «Эльбрус» можно исполнять в **спекулятивном режиме** - это означает, что при значениях аргументов,
в обычном режиме приводящих к выработке исключительной ситуации, в спекулятивном режиме операция запишет в тэг результата признак диагностического значения.
Более подробное описание смотри в :ref:`spec_mode`.

Здесь ограничимся краткой мнемонической таблицей:

.. csv-table:: таблица спекулятивного режима
   :header: "режим/аргументы", "допустимые", "недопустимые", "хотя бы один диагностический"
   :widths: 15, 15, 10, 30

   "обычный", "результат", "исключение", "исключение"
   "спекулятивный", "результат", "диагностический", "диагностический"



Обзор целочисленных операций   
----------------------------

Операции, описанные в данном разделе, в зависимости от своего типа, вырабатывают либо числовое значение (включая флаги), либо предикат.
В первом случае результат записывается в регистровый файл (RF), во втором - в предикатный файл (PF).
При нормальном завершении числовой операции результат имеет тег "tagnum" соответствующего формата; в случае особой ситуации выдается результат диагностического типа.
При нормальном завершении предикатной операции результат имеет тег, равный ``0``; в случае особой ситуации выдается предикат диагностического типа.

Операции сложения, вычитания, обратного вычитания
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  ADDs/d          sss/ddd  сложение 32/64
  SUBs/d          sss/ddd  вычитание 32/64
  RSUBs/d         sss/ddd  обратное вычитание 32/64; используется только в качестве 
                           второй стадии комбинированной операции

Операции сложения **ADDs/d** выполняют целое сложение двух операндов.

Операции вычитания **SUBs/d** вычитают операнд 2 из операнда 1.

Операции обратного вычитания **RSUBs/d** вычитают операнд 1 из операнда 2. Они используются только в качестве операции второй стадии комбинированной операции.
Их первый операнд является третьим операндом комбинированной операции, а второй операнд представляет собой результат первой стадии комбинированной операции.

Язык ассемблера:
::

  adds            src1, src2, dst
  addd            src1, src2, dst
  subs            src1, src2, dst
  subd            src1, src2, dst
  add_rsubd	  scr1, src2, scr3, dst
  
Операции умножения
~~~~~~~~~~~~~~~~~~
::

  MULs/d          sss/ddd  умножение 32/64
  UMULX           ssd      умножение целых без знака 32 * 32 -> 64
  SMULX           ssd      умножение целых со знаком 32 * 32 -> 64
  UMULHd          ddd      умножение целых без знака 64 * 64 -> 128 (старшая часть)
  SMULHd          ddd      умножение целых со знаком 64 * 64 -> 128 (старшая часть)

Операция **UMULX** умножает значения в формате int32 без знака и вычисляет
произведение в формате int64 без знака.

Операция **SMULX** умножает значения в формате int32 со знаком и вычисляет
произведение в формате int64 со знаком.

Операция **UMULHd** умножает значения в формате int64 без знака, вычисляет
произведение в формате int128 без знака и в качестве результата выдает старшие 64 разряда.

Операция **SMULHd** умножает значения в формате int64 со знаком, вычисляет
произведение в формате int128 со знаком и в качестве результата выдает старшие 64 разряда.

Операции **MULs/d** выполняют целое умножение двух 32/64-разрядных операндов, вырабатывая 32/64-разрядный результат.

Язык ассемблера:
::

  muls            src1, src2, dst
  muld            src1, src2, dst
  umulx           src1, src2, dst
  smulx           src1, src2, dst
  umulhd          src1, src2, dst
  smulhd          src1, src2, dst

Операции деления и вычисления остатка
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  UDIVX           dss      деление целых без знака 64/32->32
  UMODX           dss      остаток от деления целых без знака 64/32->32
  SDIVX           dss      деление целых со знаком 64/32->32
  SMODX           dss      остаток от деления целых со знаком 64/32->32
  SDIVs/d         sss/ddd  деление целых со знаком 32/32->32 или 64/64->64
  UDIVs/d         sss/ddd  деление целых без знака 32/32->32 или 64/64->64

Операция **UDIVX** выполняет деление без знака операнда 1 на операнд 2.
Нецелочисленные частные округляются отсечением (отбрасыванием дробной части - truncate toward 0).
Особая ситуация exc_div вырабатывается, если делитель равен ``0``, или частное слишком велико для формата регистра назначения.

Операция **UMODX** вычисляет остаток, получаемый при делении без знака операнда 1 на операнд 2.
Остаток всегда меньше делителя по абсолютной величине и имеет тот же знак, что и делимое.
Особая ситуация exc_div вырабатывается, если делитель равен ``0``, или нарушены ограничения, применимые к особым ситуациям.

Операция **SDIVX** выполняет деление со знаком операнда 1 на операнд 2.
Нецелочисленные частные округляются отсечением (отбрасыванием дробной части - truncate toward 0).
Особая ситуация exc_div вырабатывается, если делитель равен ``0``, или частное слишком велико для формата регистра назначения.

Операция **SMODX** вычисляет остаток, получаемый при делении со знаком операнда 1 на операнд 2.
Остаток всегда меньше делителя по абсолютной величине и имеет тот же знак, что и делимое.
Особая ситуация exc_div вырабатывается, если делитель равен ``0``, или нарушены ограничения, применимые к особым ситуациям.

Операции **UDIVs/UDIVd** выполняют деление без знака операнда 1 на операнд 2.
Особая ситуация exc_div вырабатывается, если делитель равен ``0``.

Операции **SDIVs/SDIVd** выполняют деление со знаком операнда 1 на операнд 2.
Особая ситуация exc_div вырабатывается, если делитель равен ``0``.
Если наибольшее отрицательное число делится на -1, то результатом является наибольшее отрицательное число.

Язык ассемблера:
::

  udivx           src1, src2, dst
  umodx           src1, src2, dst
  sdivx           src1, src2, dst
  smodx           src1, src2, dst
  udivs           src1, src2, dst
  udivd           src1, src2, dst
  sdivs           src1, src2, dst
  sdivd           src1, src2, dst


Операции сравнения целых чисел
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  CMP(s/d)b       группа  из 8-ми операций сравнения:

  CMPO(s/d)b      ssb/ddb  сравнение 32/64 "переполнение"
  CMPB(s/d)b      ssb/ddb  сравнение 32/64 "< без знака"
  CMPE(s/d)b      ssb/ddb  сравнение 32/64 "равно"
  CMPBE(s/d)b     ssb/ddb  сравнение 32/64 "<= без знака"
  CMPS(s/d)b      ssb/ddb  сравнение 32/64 "отрицательный"
  CMPP(s/d)b      ssb/ddb  сравнение 32/64 "нечетный"
  CMPL(s/d)b      ssb/ddb  сравнение 32/64 "< со знаком"
  CMPLE(s/d)b     ssb/ddb  сравнение 32/64 "<= со знаком"

  CMPAND(s/d)b    группа  из 4-х операций проверки:

  CMPANDE(s/d)b   ssb/ddb  поразрядное "and" и проверка 32/64 "равно 0"
  CMPANDS(s/d)b   ssb/ddb  поразрядное "and" и проверка 32/64 "отрицательный"
  CMPANDP(s/d)b   ssb/ddb  поразрядное "and" и проверка 32/64 "нечетный"
  CMPANDLE(s/d)b  ssb/ddb  поразрядное "and" и проверка 32/64 "<=0 со знаком"

Операции **CMP** вычитают операнд 2 из операнда 1 и определяют флаги, как это делают операции **SUB**.
Далее по состоянию флагов формируется результат - предикат "true" или "false".

Операции **CMPAND** выполняют поразрядное логическое "and" операнда 1 и операнда 2 и определяют флаги, как это делают операции **AND**.
Далее по состоянию флагов формируется результат - предикат "true" или "false".

Язык ассемблера:
::

  cmpodb          src1, src2, predicate
  cmpbdb          src1, src2, predicate
  cmpedb          src1, src2, predicate
  cmpbedb         src1, src2, predicate
  cmposb          src1, src2, predicate
  cmpbsb          src1, src2, predicate
  cmpesb          src1, src2, predicate
  cmpbesb         src1, src2, predicate
  cmpsdb          src1, src2, predicate
  cmppdb          src1, src2, predicate
  cmpldb          src1, src2, predicate
  cmpledb         src1, src2, predicate
  cmpssb          src1, src2, predicate
  cmppsb          src1, src2, predicate
  cmplsb          src1, src2, predicate
  cmplesb         src1, src2, predicate
  cmpandesb       src1, src2, predicate
  cmpandssb       src1, src2, predicate
  cmpandpsb       src1, src2, predicate
  cmpandlesb      src1, src2, predicate
  cmpandedb       src1, src2, predicate
  cmpandsdb       src1, src2, predicate
  cmpandpdb       src1, src2, predicate
  cmpandledb      src1, src2, predicate
  
Логические поразрядные операции
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  ANDs/d          sss/ddd  логическое "and" 32/64
  ANDNs/d         sss/ddd  логическое "and" 32/64 с инверсией операнда 2
  ORs/d           sss/ddd  логическое "or" 32/64
  ORNs/d          sss/ddd  логическое "or" 32/64 с инверсией операнда 2
  XORs/d          sss/ddd  логическое исключительное "or" 32/64
  XORNs/d         sss/ddd  логическое исключительное "or" 32/64 с инверсией операнда 2

Эти операции выполняют поразрядные логические операции.
Операции **ANDN**, **ORN** и **XORN** логически инвертируют операнд 2, прежде чем выполнить основную (**AND**, **OR** или исключающее **OR**) операцию.

Язык ассемблера:
::

  ands            src1, src2, dst
  andd            src1, src2, dst
  andns           src1, src2, dst
  andnd           src1, src2, dst
  ors             src1, src2, dst
  ord             src1, src2, dst
  orns            src1, src2, dst
  ornd            src1, src2, dst
  xors            src1, src2, dst
  xord            src1, src2, dst
  xorns           src1, src2, dst
  xornd           src1, src2, dst

::

  SHLs/d          sss/ddd  сдвиг влево 32/64
  SHRs/d          sss/ddd  сдвиг вправо логический 32/64
  SCLs/d          sss/ddd  сдвиг влево циклический 32/64
  SCRs/d          sss/ddd  сдвиг вправо циклический 32/64
  SARs/d          sss/ddd  сдвиг вправо арифметический 32/64

Операции **SHLs/d** сдвигают операнд 1 влево на число разрядов, указанных в операнде 2. Самый старший разряд сдвигается во флаг CF.
Освободившиеся позиции младших разрядов заполняются нулями.

Операции **SHRs/d** сдвигают операнд 1 вправо на число разрядов, указанных в операнде 2. Самый младший разряд сдвигается во флаг CF.
Освободившиеся позиции старших разрядов заполняются нулями.

Операции **SCLs/d** сдвигают операнд 1 влево на число разрядов, указанных в операнде 2. Самый старший разряд сдвигается во флаг CF.
Освободившиеся позиции младших разрядов заполняются выдвинутыми старшими разрядами операнда.

Операции **SCRs/d** сдвигают операнд 1 вправо на число разрядов, указанных в операнде 2. Самый младший разряд сдвигается во флаг CF.
Освободившиеся позиции старших разрядов заполняются выдвинутыми младшими разрядами операнда.

Операции **SARs/d** сдвигают операнд 1 вправо на число разрядов, указанных в операнде 2. Самый младший разряд сдвигается во флаг CF.
Освободившиеся позиции старших разрядов заполняются самым старшим значимым разрядом операнда.

Эти операции выдают либо числовой результат, либо флаг.

Язык ассемблера:
::

  shls            src1, src2, dst
  shld            src1, src2, dst
  shrs            src1, src2, dst
  shrd            src1, src2, dst
  scls            src1, src2, dst
  scld            src1, src2, dst
  scrs            src1, src2, dst
  scrd            src1, src2, dst
  sars            src1, src2, dst
  sard            src1, src2, dst

Операции «взять поле произвольной длины»
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  GETFs/d         sss/ddd  выделить поле произвольной длины

Операции **GETFs/d** выделяют произвольное поле первого операнда.
Остальные разряды результата заполняются либо нулями, либо старшим значащим разрядом выделенного поля.
Параметры поля определяются значением второго операнда:

::

  Для GETFs
  Правый разряд поля:
    ShiftCount = (bitvect)src2[4:0];
  Длина поля:
    Size = (bitvect)src2[10:6];

  Для GETFd
  Правый разряд поля:
    ShiftCount = (bitvect)src2[5:0];
  Длина поля:
    Size = (bitvect)src2[11:6];


Здесь и далее (bitvect)value означает представление числа value в виде битового вектора,
а (bitvect)value[beg:end] - подвектор битового вектора между позициями beg и end.


Язык ассемблера:
::

  getfs           src1, src2, dst
  getfd           src1, src2, dst


Операции «вставить поле»
~~~~~~~~~~~~~~~~~~~~~~~~
::

  INSFs/d         ssss/dddd  вставить поле 32/64

Операции **INSFs/d** циклически сдвигают вправо 1-й операнд и вставляют произвольное количество самых правых разрядов 3-го операнда
в самые правые разряды циклически сдвинутого 1-го операнда.
Параметры поля определяются значением 2-го операнда:

::

  Для INSFs
  Правый разряд поля:
    ShiftCount = (bitvect)src2[4:0];
  Длина поля:
    Size = (bitvect)src2[10:6];
  Для INSFd
  Правый разряд поля:
    ShiftCount = (bitvect)src2[5:0];
  Длина поля:
    Size = (bitvect)src2[11:6];



Язык ассемблера:
::

  insfs           src1, src2, src3, dst
  insfd           src1, src2, src3, dst

Расширение знаком или нулем
~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  SXT             ssd  расширение знаком или нулем 8/16/32 до 64

Операция **SXT** преобразует значение 2-го аргумента в формате байт/полуслово/одинарное слово в формат двойное слово.
Операция заполняет остальные разряды результата либо нулями (zero-extended), либо знаком (старшим разрядом) байта/полуслова/слова (sign-extended).
Разрядность и знаковость определяются по 1-му аргументу.

::

  Формат:
    src1[1:0] == 0 -> 8 бит
    src1[1:0] == 1 -> 16 бит
    src1[1:0] == 2 -> 32 бит
    src1[1:0] == 3 -> 32 бит
    src1[2:2] == 0 - беззнаковое
    src1[2:2] == 1 - знаковое
    

Язык ассемблера:

::

  sxt             src1, src2, dst
  
Выбор из двух операндов
~~~~~~~~~~~~~~~~~~~~~~~
::

  MERGEs/d        sss/ddd  выбрать один из операндов 32/64 как результат 
                           (требует комбинированной операции RLP)

Операция **MERGE** выдает в качестве результата один из двух числовых операндов в зависимости от значения третьего операнда - предиката.
От тернарного оператора языка C/C++:

::

  cond ? altT : altF

отличается тем, что выбирается значение src1 при ``predicate == F``, и src2 при ``predicate == T``.

Язык ассемблера:

::

  merges          src1, src2, dst, predicate
  merged          src1, src2, dst, predicate

Обзор вещественных скалярных операций
-------------------------------------

Перечень операций.

::

  FADDs/d         sss/ddd  сложение fp32/fp64
  FSUBs/d         sss/ddd  вычитание fp32/fp64
  FRSUBs/d        sss/ddd  обратное вычитание fp32/fp64; используется только в
                           качестве второй стадии комбинированной операции
  FMAXs/d         sss/ddd  максимум fp32/fp64
  FMINs/d         sss/ddd  минимум fp32/fp64

  FMULs/d         sss/ddd  умножение fp32/fp64
  FSCALEs/d       sss/dsd  умножение fp32/fp64 на целую степень двойки

  FDIVs/d         sss/ddd  деление fp32/fp64
  FRCPs           -ss      обратная величина fp32

  FSQRTs          -ss      квадратный корень fp32
  FSQRTId         -dd      квадратный корень fp64 начальная команда
  FSQRTTd         ddd      квадратный корень fp64 конечная команда
  FRSQRTs         -ss      обратная величина квадратного корня fp32

  FCMPEQs/d       sss/ddd fp32/fp64  сравнение на равно, результат в регистровом 
                                     файле
  FCMPLTs/d       sss/ddd fp32/fp64  сравнение на меньше, результат в регистровом
                                     файле
  FCMPLEs/d       sss/ddd fp32/fp64  сравнение на меньше или равно, результат в
                                     регистровом файле
  FCMPUODs/d      sss/ddd fp32/fp64  сравнение на не упорядочено, результат в
                                     регистровом файле
  FCMPNEQs/d      sss/ddd fp32/fp64  сравнение на не равно, результат в регистровом 
                                     файле
  FCMPNLTs/d      sss/ddd fp32/fp64  сравнение на не меньше, результат в регистровом 
                                     файле
  FCMPNLEs/d      sss/ddd fp32/fp64  сравнение на не меньше или равно, результат 
                                     в регистровом файле
  FCMPODs/d       sss/ddd fp32/fp64  сравнение на упорядочено, результат в
                                     регистровом файле

  FCMPEQ(s/d)b    ssb/ddb fp32/fp64  сравнение на равно с формированием 
                                     результата в виде предиката
  FCMPLT(s/d)b    ssb/ddb fp32/fp64  сравнение на меньше с формированием 
                                     результата в виде предиката
  FCMPLE(s/d)b    ssb/ddb fp32/fp64  сравнение на меньше или равно с формированием 
                                     результата в виде предиката
  FCMPUOD(s/d)b   ssb/ddb fp32/fp64  сравнение на неупорядочено с формированием 
                                     результата в виде предиката
  FCMPNEQ(s/d)b   ssb/ddb fp32/fp64  сравнение на не равно с формированием 
                                     результата в виде предиката
  FCMPNLT(s/d)b   ssb/ddb fp32/fp64  сравнение на не меньше с формированием 
                                     результата в виде предиката
  FCMPNLE(s/d)b   ssb/ddb fp32/fp64  сравнение на не меньше или равно 
                                     с формированием результата в виде предиката
  FCMPOD(s/d)b    ssb/ddb fp32/fp64  сравнение на упорядочено с формированием 
                                     результата в виде предиката
  

Операции сложения, вычитания, умножения, деления, сравнения, вычисления максимума и минимума имеют достаточно понятную мнемонику
и в детальном описании не нуждаются.
  
  
Операции умножения на целую степень двойки
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операции **FSCALEs/d** выполняют умножение вещественного числа соответствующего формата, содержащегося в 1-м операнде, на целую степень двойки,
задаваемую 2-м операндом форматов; результат имеет формат 1-го операнда.

::

  FSCALEs/d       sss/dsd  умножение fp32/fp64 на целую степень двойки

Язык ассемблера:

::

  fscales         src1, src2, dst
  fscaled         src1, src2, dst

Операции вычисления квадратного корня
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **FSQRTs** вычисляет квадратный корень из 2-го операнда формата fp32.

Операция **FSQRTId** вычисляет первую аппроксимацию квадратного корня из 2-го операнда формата fp64.

Операция **FSQRTTd** завершает вычисление квадратного корня из 1-го операнда формата fp64, используя первую аппроксимацию,
вычисленную операцией **FSQRTId** и содержащуюся во 2-м операнде.
Результат, полученный последовательным выполнением двух операций **FSQRTId** и **FSQRTTd**, соответствует стандарту IEEE Standard 754.

::

  FSQRTs          -ss  квадратный корень fp32
  FSQRTId         -dd  квадратный корень fp64 начальная команда
  FSQRTTd         ddd  квадратный корень fp64 конечная команда

Язык ассемблера:

::

  fsqrts          src2, dst
  fsqrtid         src2, dst
  fsqrttd         src1, src2, dst
  
Скалярные операции преобразования формата
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  FSTOFD          -sd  fp32 в fp64
  FDTOFS          -ds  fp64 в fp32

  FSTOIFs         sss  целая часть fp32 в fp32
  FDTOIFd         ddd  целая часть fp64 в fp64

  FSTOIS          -ss  fp32 в int32
  FSTOID          -sd  fp32 в int64
  FDTOIS          -ds  fp64 в int32
  FDTOID          -dd  fp64 в int64
  FSTOIStr        -ss  fp32 в int32 с обрубанием 
  FDTOIStr        -ds  fp64 в int32 с обрубанием
  FSTOIDtr        -sd  fp32 в int64 с обрубанием 
  FDTOIDtr        -dd  fp64 в int64 с обрубанием

  ISTOFS          -ss  int32 в fp32
  ISTOFD          -sd  int32 в fp64
  IDTOFS          -ds  int64 в fp32
  IDTOFD          -dd  int64 в fp64

  FSTOFD          -sd  fp32 to fp64
  FDTOFS          -ds  fp64 to fp32

Операции FSTOIFs и FDTOIFd имеют два аргумента (в отличие от других операций преобразования формата).
Из 1-го аргумента используются 3 младших бита, определяющих режим округления:

::

  if ((bitvect)scr1[2:2] == 0) 
      rounding_mode = (bitvect)src1[1:0]; 
  else 
      rounding_mode = PFPFR.rc;


Язык ассемблера:

::

  fstofd          src2, dst
  fdtofs          src2, dst
  fstoifs         src1, src2, dst
  fdtoifd         src1, src2, dst
  fstois          src2, dst
  fstoid          src2, dst
  fdtois          src2, dst
  fdtoid          src2, dst
  fstoistr        src2, dst
  fdtoistr        src2, dst
  fstoidtr        src2, dst
  fdtoidtr        src2, dst

Предикатные операции
--------------------

Логический предикат представляет собой тегированные 1-разрядные булевские данные, принимающие следующие  значения:

::

    тег      значение
    0        0        - "false"
    0        1        - "true"
    1        x        - "DP" (диагностический предикат)

Результатом операции также является тегированный предикат.

Операции вычисления предикатов
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операции над логическими предикатами размещаются в PLS слогах. В PLS слогах могут размещаться до 7 операций трех основных типов:

* вычисление первичного логического предиката (Evaluate Logical Predicate -  ELP) является ссылкой на первичный (primary) предикат,
  хранящийся в предикатном регистре PR, или определяет так называемые специальные предикаты;
  эти операции поставляют исходные предикаты для операций **CLP** и **MLP**;

* вычисление вторичного логического предиката (Calculate LogicalPredicate - CLP) является логической функцией с двумя аргументами;
  её результат можно записать в предикатный регистр PR;

* условная пересылка логического предиката (Conditional Move Logical Predicate - MLP) записывает или теряет результат операций
  **ELP** или **CLP**, в зависимости от значения предиката-условия.

Широкая команда может включать до:

* 4 ELP;
* 3 CLP/MLP.

.. rubric:: Обозначения для предикатов

В этом разделе вводятся следующие обозначения.

До семи промежуточных предикатов с номерами от 0 до 6 (p0, p1,...p6) могут формироваться операциями **ELP** и **CLP**.

Предикатам, формируемым операциями **ELP**, присваиваются номера от 0 до 3 (``p0...p3``);
предикатам, формируемым операциями **CLP**, присваиваются номера от 4 до 6 (``p4...p6``);
операции **MLP** не формируют промежуточных предикатов.

В соответствии с этими номерами операции **CLP/MLP** обращаются к своим операндам — предикатам,
выработанным в данной команде (операции **CLP** могут быть каскадными (см. ниже)).

При упаковке в слоги PLS операция, формирующая предикат с конкретным номером, может занимать только определенное положение.
Поэтому далее в данном разделе операции **ELP** и **CLP** могут нумероваться как
``ELP0``, ``ELP1``, ``ELP2``, ``ELP3``, ``CLP0``, ``CLP1``, ``CLP2``.

Вычисление первичного логического предиката (Evaluate Logical Predicate - ELP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **ELP** считывает для использования либо предикат из предикатного файла PF, либо один из специальных предикатов.

Язык ассемблера:

::

  pass                    predicate, local_predicate
  spred, elp_number       alu_channel, ...
    
где:

::

  predicate               - один из описанных ниже;
  local_predicate         - один из @p0, @p1, @p2, @p3;
  elp_number              - один из 0, 1, 2, 3;
  alu_channel             - список любых из >alc0, >alc1, ... >alc5.




Направить логический предикат (Route Logical Predicate - RLP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **RLP** задает предикатное выполнение операции арифметико-логического канала и определяет (направляет)
предикат для управления этой операцией.

Язык ассемблера:

::

  adds     src1, src2, dst ? predicate

где:

::

  predicate               - один из описанных ниже:
                            * исчерпание счетчиков цикла - %lcntex;
                            * значение счетчика пролога - %pcnt<N>;
                            * предикат в предикатном файле - %pred<N>.

Условие для операции MERGE (Merge Condition - MRGC)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операции **MRGC** вырабатывают условия для алгоритма операции **MERGE**.

Язык ассемблера:

::

  merged  src1, src2, dst, predicate
    
где:

::

  predicate               - один из описанных ниже:
                            * исчерпание счетчиков цикла - %lcntex;
                            * значение счетчика пролога - %pcnt<N>;
                            * предикат в предикатном файле - %pred<N>.

Вычисление логического предиката (Calculate Logical Predicate - CLP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **CLP** является логической функцией с двумя аргументами, в качестве аргументов она получает предикаты,
сформированные операциями **ELP** или **CLP** (но не **MLP**) из той же самой широкой команды,
и ее результат - логическое "И" аргументов (с возможной инверсией) может записываться в PF.

Язык ассемблера:

::

  andp            [~]local_predicate, [~]local_predicate, local_predicate_dst
  landp           [~]local_predicate, [~]local_predicate, local_predicate_dst
  pass          local_predicate_dst, predicate 
  
где:

::

  local_predicate         - один из @p0, @p1, ... @p6;
  ~                       - инверсия значения предиката перед выполнением функции;
  predicate               - предикат в PF - %pred<N>.

Условная пересылка логического предиката (Conditional Move Logical Predicate - MLP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **MLP** условно записывает предикат, выработанный операциями **ELP** или **CLP**.
В результате этой операции первый аргумент будет записан в результат, если второй аргумент равен 1.

Язык ассемблера:

::

  movep           local_predicate, local_predicate, local_predicate_dst
  pass            local_predicate_dst, predicate


Операции обращения в память
---------------------------

Операции обращения в память включают операции считывания и записи.
Операции считывания читают несколько байтов из пространства памяти и помещают их в регистр назначения.
Операции записи пишут несколько байтов из регистра источника в пространство памяти.

Определяются следующие порции считываемой/записываемой информации:
байт (byte), полуслово (half-word), одинарное слово (word), двойное слово (double-word), квадро слово (quad-word).
Порция определяется кодировкой операции.

Размещение в пространстве памяти определяется операндами операции.
Один из них обычно является адресным типом, другие (если присутствуют) являются индексом(ами) в терминах байтов.

Операции считывания из незащищенного пространства
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  LDB             ddd  считывание байта без знака
  LDH             ddd  считывание полуслова без знака
  LDW             ddd  считывание одинарного слова
  LDD             ddd  считывание двойного слова

Язык ассемблера:

::

  ldb             [ address ] mas, dst
  ldh             [ address ] mas, dst
  ldw             [ address ] mas, dst
  ldd             [ address ] mas, dst

Операции записи в незащищенное пространство
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  STB             dds  запись байта
  STH             dds  запись полуслова
  STW             dds  запись одинарного слова
  STD             ddd  запись двойного слова

Язык ассемблера:

::

  stb             src3, [ address ] { mas }
  sth             src3, [ address ] { mas }
  stw             src3, [ address ] { mas }
  std             src3, [ address ] { mas }

  
Операции считывания в режиме -mptr32
""""""""""""""""""""""""""""""""""""
::

  LDGDB     r,ssd  считывание байта без знака
  LDGDH     r,ssd  считывание полуслова без знака
  LDGDW     r,ssd  считывание одинарного слова
  LDGDD     r,ssd  считывание двойного слова
  LDGDQ     r,ssq  считывание квадро слова

Язык ассемблера:

::

  ldgdb           [ address ] { mas }, dst
  ldgdh           [ address ] { mas }, dst
  ldgdw           [ address ] { mas }, dst
  ldgdd           [ address ] { mas }, dst
  ldgdq           [ address ] { mas }, dst

Операции записи в режиме -mptr32
""""""""""""""""""""""""""""""""

Операции данного раздела относятся к группе операций с «защищенными» данными.

::

  STGDB           r,sss  запись байта
  STGDH           r,sss  запись полуслова
  STGDW           r,sss  запись одинарного слова
  STGDD           r,ssd  запись двойного слова
  STGDQ           r,ssq  запись квадро слова

Язык ассемблера:

::

  stgdb           src3, [ address ] { mas }
  stgdh           src3, [ address ] { mas }
  stgdw           src3, [ address ] { mas }
  stgdd           src3, [ address ] { mas }
  stgdq           src3, [ address ] { mas }

Операции обращения к массиву
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операции считывания массива
"""""""""""""""""""""""""""
::

  LDAAB           ppd  считывание байта
  LDAAH           ppd  считывание полуслова
  LDAAW           ppd  считывание одинарного слова
  LDAAD           ppd  считывание двойного слова
  LDAAQ           ppq  считывание квадро слова

Язык ассемблера:

::

  ldaab           %aadN [ %aastiL {+ literal32} ], dst
  ldaah           %aadN [ %aastiL {+ literal32} ], dst
  ldaad           %aadN [ %aastiL {+ literal32} ], dst
  ldaaw           %aadN [ %aastiL {+ literal32} ], dst
  ldaaq           %aadN [ %aastiL {+ literal32} ], dst

  incr            %aaincrM {? <предикат для модификации адреса>}
                  ,где K, L, M, N - целые без знака
                  
Операции записи в массив
""""""""""""""""""""""""
::

  STAAB           pps  запись байта
  STAAH           pps  запись полуслова
  STAAW           pps  запись одинарного слова
  STAAD           ppd  запись двойного слова
  STAAQ           ppq  запись квадро слова

Язык ассемблера:

::
  
  staab           src3, %aadN [ %aastiL {+ literal32} ] { mas }
  staah           src3, %aadN [ %aastiL {+ literal32} ] { mas }
  staad           src3, %aadN [ %aastiL {+ literal32} ] { mas }
  staaw           src3, %aadN [ %aastiL {+ literal32} ] { mas }
  staaq           src3, %aadN [ %aastiL {+ literal32} ] { mas }

  incr            %aaincrM {? <предикат для модификации адреса>}
                  ,где K, L, M, N - целые без знака

              
Операции преобразования адресных объектов
-----------------------------------------

Взять указатель стека (GETSP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  GETSP           rsd  взять подмассив стека пользователя

Операция **GETSP**, в зависимости от знака операнда 2, либо выделяет свободную
область в незащищенном стеке пользователя, либо возвращает ранее выделенную
память. В обоих случаях операция модифицирует указатель стека.

Язык ассемблера:

::

  getsp           src2, dst

.. _rst-label1: 

Переслать тэгированное значение (MOVT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
        
  MOVTs           -ss  переслать тэгированный адресный объект 32
  MOVTd           -dd  переслать тэгированный адресный объект 64
  MOVTq           -qq  переслать тэгированный адресный объект 128

Операция **MOVT** копирует значение регистра с сохранением тэгов в регистр назначения.

Язык ассемблера:

::

  movts           src2, dst
  movtd           src2, dst
  movtq           src2, dst
  movtd           src2, ctp_reg

Операции доступа к регистрам состояния
--------------------------------------

Архитектура определяет несколько методов доступа к регистрам состояния:

* операции **RW** и **RR** обычно обеспечивают доступ к регистрам, которые контролируют всю работу процессора;
* операции **SETxxx** предлагаются как оптимальный способ модификации некоторых предопределенных регистров;
* операции **{STAAxx + MAS}** и **{LDAAxx + MAS}** обычно обеспечивают доступ к  регистрам AAU;
* операции **{STxx + MAS}** и **{LDxx + MAS}** обычно обеспечивают доступ к регистрам MMU.

Операции «установить регистры» и «проверить области параметров»
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  SETBN           -ir  установить вращаемую базу NR-ов
  SETBP           -ir  установить вращаемую базу PR-ов
  SETWD           -ir  изменить размер окна стека процедур
  VFRPSZ          -i-  проверить размер регистровой области параметров процедуры 

Язык ассемблера:

::

  setbn           { rbs = NUM } { , rsz = NUM } { , rcur = NUM }
  setbp           { psz = NUM }
  setwd           { wsz = NUM } { , nfx = NUM } { , dbl = NUM }
  vfrpsz          { rpsz = NUM }
   
.. _operations_ctpr:

Операции подготовки передачи управления
---------------------------------------

Есть два типа передачи управления:

* немедленная ("instant");
* подготовленная ("prepared").

Для немедленной передачи управления необходима одна операция, которая содержит всю необходимую информацию и передаёт управление немедленно.

Передачи управления типа «подготовленная» разбиты на две операции:

* подготовка передачи управления (control transfer preparation - CTP);
* фактическая передача управления (control transfer - CT).

Операции **CTP** предназначены для подготовки информации, необходимой для быстрой фактической передачи управления.
Целью является выполнение всей подготовительной работы «на фоне» и одновременно с основной активностью обработки данных.
Операции **CTP** содержат всю или часть информации о передаче управления (тип, адрес, etc);
эта информация сохраняется до операции **CT** на одном из регистров CTPRj и используется ею для фактической передачи управления.

Передачи управления могут включать следующие элементы в различных разумных сочетаниях:

* Переключение указателя команды IP (кода) - присутствует всегда; указатель команды IP перехода может быть получен одним из следующих способов:

  * литеральное смещение относительно текущего указателя команды IP;
  * динамическое/литеральное смещение относительно текущего дескриптора модуля компиляции CUD;
  * тэгированная метка (для защищенного адресного пространства), поступающая из регистрового файла RF;
  * целочисленная метка (для незащищенного адресного пространства), поступающая из регистрового файла RF;
  * указатель команды IP возврата, поступающий из регистров стека связующей информации процедур.

* Переключение регистрового окна - характерно для процедурных передач; при вызовах это статически известная информация, кодируемая литерально;
  при возвратах информация поступает из регистров стека связующей информации.
* Переключение фрейма стека пользователя - характерно для процедурных передач; при возвратах информация поступает из регистров стека связующей информации;
  при входах пространство стека пользователя не назначается.
* Переключение контекста - характерно для процедурных передач; контекст глобальных процедур включает:

  * глобалы, описываемые дескриптором глобалов GD;
  * литеральные скалярные данные и массивы, описываемые дескриптором модуля компиляции CUD;
  
  оба дескриптора берутся из таблицы модулей компиляции CUT;
  соответствующая строка в таблице модулей компиляции CUT определяется PTE точки перехода.

Существуют следующие типы передач управления (как подготовленных, так и немедленных),
то есть разумные сочетания элементов, описанных выше:

* BRANCH - непроцедурная подготовленная передача управления; она включает переключение указателя команды IP;
  IP задается операцией **DISP**, **GETPL** или **MOVTd**.
  
  Переключение (передача управления) осуществляется операцией **CT**;

* IBRANCH - непроцедурная немедленная передача управления; она включает переключение указателя команды IP;
  IP задается операцией **IBRANCH**.
  
  Переключение (передача управления) осуществляется операцией **IBRANCH**;

* CALL - подготовленный вызов процедуры; он включает:

  * переключение указателя команды IP; IP задается операцией **DISP**, **GETPL** или **MOVTd**;
  * переключение регистрового окна; окно задается операцией **CALL**;
  * переключение контекста; новый контекст включает глобалы, литералы и классы. Контекст автоматически считывается из памяти операцией **CALL**.
  
  Переключение (передача управления) осуществляется операцией **CALL**;

* SCALL - подготовленный вызов процедуры OS (глобальной); он включает:
                
  * переключение указателя команды IP; IP задается операцией **SDISP**;
  * переключение регистрового окна; окно задается операцией **SCALL**;
  * переключение контекста; новый контекст включает глобалы и литералы, хранящиеся на регистрах процессора.
  
  Переключение (передача управления) осуществляется операцией **SCALL**;

* RETURN - подготовленный возврат из процедуры; он включает:

  * восстановление указателя команды IP; IP задается операцией **RETURN** (считывается из стека связующей информации);
  * восстановление регистрового окна и фрейма стека пользователя; окно и фрейм считываются из стека связующей информации операцией **CT**;
  * восстановление контекста; новый контекст включает глобалы, литералы и классы. Контекст автоматически считывается из памяти операцией **CT**.
  
  Переключение (передача управления) осуществляется операцией **CT**;

* DONE - немедленный возврат из обработчика прерываний; он включает:

  * восстановление указателя команды IP; IP задается операцией **DONE** (считывается из стека связующей информации);
  * восстановление регистрового окна и фрейма стека пользователя; окно и фрейм считываются из стека связующей информации операцией **DONE**;
  * восстановление контекста; новый контекст включает глобалы, литералы и классы. Контекст автоматически считывается из памяти операцией **DONE**.
  
  Переключение (передача управления) осуществляется операцией **DONE**;

* аппаратный вход в обработчик прерываний; он включает:

  * переключение указателя команды IP; IP задается регистром процессора;
  * переключение регистрового окна; новое окно - пустое;
  * переключение контекста; новый контекст включает глобалы и литералы, хранящиеся на регистрах процессора.
  
  Переключение (передача управления) осуществляется аппаратно, по сигналам прерываний.
        
Подготовка перехода по литеральному смещению (DISP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**DISP** подготавливает передачу управления типа BRANCH/CALL.

Язык ассемблера:

::

 disp           ctp_reg, label  [, ipd NUM]

где:

::

  ctp_reg - регистр подготовки перехода;
  label - метка целевого адреса;
  NUM - необязательный параметр, глубина подкачки кода
        в терминах количества строк L1$I ; NUM = 0, 1, 2.

Подготовка перехода по динамическому смещению (GETPL)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**GETPL** используется для подготовки передачи управления типа BRANCH/CALL.
Далее приводится случай, когда **GETPL** используется как операция подготовки передачи управления.

Язык ассемблера:

::

  getpl          src2, ctp_reg   [, ipd NUM]

где:

::

  ctp_reg - регистр подготовки перехода;
  src2 - содержит смещение целевого адреса относительно CUD;
  NUM - необязательный параметр, глубина подкачки кода
        в терминах количества строк L1$I ; NUM = 0, 1, 2.

Подготовка перехода по метке из регистрового файла RF (MOVTd)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**MOVTd** используется для подготовки передачи управления типа BRANCH/CALL.

**MOVTd** в общем виде описывается в разделе :ref:`rst-label1`; здесь приведен случай, когда
**MOVTd** используется как операция подготовки передачи управления.

Считается, что эта операция пересылает метку в CTPR.

Язык ассемблера:

::

  movtd          src2, ctp_reg   [, ipd NUM]

где:

::

  ctp_reg - регистр подготовки перехода;
  src2 - содержит целевой адрес;
  NUM - необязательный параметр, глубина подкачки кода
        в терминах количества строк L1$I ; NUM = 0, 1, 2.

Подготовка возврата из процедуры (RETURN)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**RETURN** используется для подготовки возврата из процедуры.

Язык ассемблера:

::

  return         %ctpr3   [, ipd NUM]

где:

::

  %ctpr3 - регистр подготовки перехода;
  NUM - необязательный параметр, глубина подкачки кода
        в терминах количества строк L1$I ; NUM = 0, 1, 2.

Подготовка программы предподкачки массива (LDISP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Программа предподкачки массива подготавливается операцией **LDISP**.

Язык ассемблера:

::
        
  ldisp           %ctpr2, label

где:

::

  %ctpr2 - регистр подготовки перехода;
  label - метка адреса начала асинхронной программы;

Предварительная подкачка кода по литеральному смещению (PREF)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**PREF** подкачивает код в кэш-память команд.

Язык ассемблера:

::

  pref            prefr, label [,ipd=NUM]

где:

::

  prefr - один из %ipr0, %ipr1,.. %ipr7;
  label - метка адреса подкачки;
  NUM - глубина подкачки; NUM = 0, 1; по умолчанию = 0.
                  

Операции передачи управления (CT)
---------------------------------

**CT** операции предназначены для условной или безусловной передачи управления из одной программной ветви в другую.
Все виды передач управления гарантируют, что следом за командой, содержащей **CT** операцию, исполняется команда выбранной программной ветви
(если условие истинно, то команда цели перехода; если ложно, то команда, следующая за командой перехода).
Никакие команды из противоположной ветви не изменяют состояния процесса.

Существует два типа **CT** операций:

* непосредственная ("instant");
* подготовленная ("prepared").

Передача управления любого типа может быть условной.

В общей форме запись на языке ассемблера следующая:

::

  ct_operation    { ? control_condition }

Подготовленный переход (BRANCH)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**BRANCH** выполняет непроцедурную подготовленную передачу управления.

**BRANCH** выполняется последовательностью двух операций:

- CT подготовка в ctp_reg, **CTP**;
- фактическая **CT** операция из этого ctp_reg.

Язык ассемблера для CT подготовки, один из вариантов:

::

  disp            ctp_reg, label
  getpl           src2, ctp_reg ! - подготовка перехода по косвенности в режиме -mptr32
  movtd           src2, ctp_reg ! - подготовка перехода по косвенности в режиме -mptr64

Язык ассемблера для фактической **CT**:

::

  ct              ctp_reg { control_condition }

где:

::

  ctp_reg - регистр подготовки перехода;
  
Нет необходимости размещать операции **CTP** и **CT** в программе непосредственно
одну за другой, они могут быть размещены на любом расстоянии друг от друга,
при условии, что ctp_reg не используется повторно.

Непосредственный переход (IBRANCH)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**IBRANCH** выполняет непосредственную непроцедурную передачу управления.

Язык ассемблера:

::

  ibranch         label { control_condition }
  
Вариант операции:

::

  ibranch         label ? %MLOCK

является синонимом:

::

  rbranch         label

..
  Описание операции ``rbranch`` приведено в разделе :ref:`perf_high`.


Операция CALL
~~~~~~~~~~~~~

**CALL** выполняет процедурную подготовленную передачу управления.

**CALL** выполняется последовательностью двух операций:

- CT подготовка в ctp_reg, **CTP**;
- фактическая **CT** операция из этого ctp_reg.

Язык ассемблера для CT подготовки, один из вариантов:

::

  disp            ctp_reg, label
  getpl           src2, ctp_reg  ! - подготовка перехода по косвенности в режиме -mptr32
  movtd           src2, ctp_reg  ! - подготовка перехода по косвенности в режиме -mptr64
  sdisp           ctp_reg, label
        
Язык ассемблера для фактической **CT**:

::

  call            ctp_reg, wbs = NUM { control_condition }

где:

::

  wbs - величина смещения регистрового окна при вызове.

Действие параметра wbs описано в разделе :ref:`switch_reg_files`.
  
Нет необходимости размещать операции **CTP** и **CT** в программе непосредственно
одну за другой, они могут быть размещены на любом расстоянии друг от друга,
при условии, что ctp_reg не используется повторно.

Возврат из аппаратного обработчика прерываний (DONE)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **DONE** выполняет непосредственный возврат из аппаратного обработчика системных прерываний.

Язык ассемблера:

::

  done            { control_condition }


Операции поддержки наложений цикла
----------------------------------

Операции Set BR
~~~~~~~~~~~~~~~
::

  SETBP           -ir  установить базу вращения предикатных регистров PR
  SETBN           -ir  установить базу вращения числовых регистров NR

Продвинуть базу вращения числовых регистров NR (ABN)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **ABN** продвигает базу вращения числовых регистров NR.
**ABN** может выполняться условно, в зависимости от условия передачи управления, закодированного в той же команде.

Язык ассемблера:

::

  abn             abnf=fl_f, abnt=fl_t

fl_f = 0, 1;
  флаг продвижения базы при отсутствии факта передачи управления после текущей команды;
fl_t = 0, 1;
  флаг продвижения базы при наличии факта передачи управления после текущей команды
  (чаще всего используется для перехода по обратной дуге цикла).
  

Продвинуть базу вращения предикатных регистров PR (ABP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **ABP** продвигает базу вращения предикатных регистров PR.
**ABP** может выполняться условно в зависимости от условия передачи управления, кодированного в той же команде.

Язык ассемблера:

::

  abp             abpf=fl_f, abpt=fl_t

fl_f = 0, 1;
  флаг продвижения базы при отсутствии факта передачи управления после текущей команды;
fl_t = 0, 1;
  флаг продвижения базы при наличии факта передачи управления после текущей команды 
  (чаще всего используется для перехода по обратной дуге цикла).
  
Продвинуть базу вращения глобальных числовых регистров NR (ABG)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **ABG** продвигает базу вращения глобальных числовых регистров NR.

Язык ассемблера:

::

  abg             abgi=fl_f, abgd=fl_t

abgi = 0, 1;
  инкрементировать базу вращения глобальных числовых регистров NR;
abgd = 0, 1;
  декрементировать базу вращения глобальных числовых регистров NR.

Продвинуть счетчики циклов (ALC)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **ALC** продвигает счетчики циклов.
**ALC** может выполняться условно в зависимости от условия передачи управления, закодированного в той же команде.

Язык ассемблера:

::

  alc             alcf=fl_f, alct=fl_t

fl_f = 0, 1;
  флаг продвижения циклового счетчика при отсутствии факта передачи управления после текущей команды;
fl_t = 0, 1;
  флаг продвижения циклового счетчика при наличии факта передачи управления после текущей команды.


Операции асинхронной подкачки в буфер предподкачки массива
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **FAPB** асинхронно подкачивает в область буфера предподкачки APB.

Язык ассемблера:

::

  fapb            {,d=<number>} {,incr=<number>} {,ind=<number>} {,disp=<number>}
                  {,fmt=<number>} {,mrng=<number>} {dcd=<number>}
                  {,asz=<number>} {,abs=<number>}
                
asz
  спецификатор размера области назначения в APB; 
  размер области определяется как

  area_size = (64 байта)*(2**asz).

  Замечание для программиста:
  диапазон корректных значений asz ограничивается размером APB 
  и для данной реализации включает числа от 0 до 5;

abs
  адрес базы области назначения в APB (в терминах 64 байтов):

  area_base = (64 байта)*abs;

  база области должна быть выровнена до размера области;
  для последовательности операций асинхронной программы области
  APB должны назначаться также последовательно, по возрастающим
  адресам; области, назначенные для разных операций, не должны
  перекрываться;

mrng
  кодирует размер записей, читаемых в область APB, и для всех 
  значений, кроме 0, содержит количество байтов; значение 0
  кодирует 32 байта; размер записи также определяет максимальное
  количество байтов, читаемых из области APB последующими
  операциями MOVAx; на соотношение величины mrng и используемых 
  адресов обращения в память накладываются аппаратные ограничения, 
  описанные ниже.
  Длина записи APB:

  length = (fapb.mrng != 0) ? fapb.mrng : 32;

fmt
  формат элемента массива; он используется:

  | a) для вычисления текущего значения индекса
  | b) для проверки выравнивания эффективного адреса;
  если читаемый фрагмент памяти в действительности содержит 
  несколько значений различного формата, поле fmt должно кодировать, 
  по крайней мере, самый длинный из них (или длиннее), иначе
  соответствующая операция MOVAx может не выполниться;

d
  ссылка на дескриптор, то есть номер j регистра AADj;

ind
  ссылка на значение начального индекса (init_index), то есть
  номер j регистра AAINDj;

  init_index = AAIND<ind>;

  заметим, что AAIND0 всегда содержит 0 и не может быть
  перезагружен чем либо иным;

incr
  ссылка на значение приращения (increment), то есть
  номер j регистра AAINCRj;
  заметим, что AAINCR0 всегда содержит 1 и не может быть
  перезагружен чем либо иным;

cd
  флаг отключения кэш-памятей:

  | 0 - все кэши подключены;
  | 1 - резерв;
  | 2 - отключен DCACHE2;
  | 3 - отключены DCACHE2, ECACHE.


Начать предподкачку массива (BAP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **BAP** ("begin array prefetch") начинает выполнение программы предподкачки массива,
подготовленной операцией **LDISP**.

Язык ассемблера:

::

  bap
  
Остановить предподкачку массива (EAP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **EAP** ("end array prefetch") завершает выполнение программы предварительной выборки массива,
подготовленной операцией **LDISP**.

Язык ассемблера:

::

  eap

Операции пересылки буфера предподкачки массива
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  MOVAB           -rd  пересылка массива в формате байт без знака
  MOVAH           -rd  пересылка массива в формате полуслово без знака
  MOVAW           -rd  пересылка массива в формате одинарное слово
  MOVAD           -rd  пересылка массива в формате двойное слово
  MOVAQ           -rq  пересылка массива в формате квадро слово

Операции **MOVAx** пересылают предподкаченные элементы массива из буфера предподкачки массива APB в регистровый файл RF,
обеспечивающий данные для арифметической обработки в цикле.

Язык ассемблера:

::

  movab           { be=NUM, } { area=NUM, } { ind=NUM, } { am=NUM, } dst
  movah           { be=NUM, } { area=NUM, } { ind=NUM, } { am=NUM, } dst
  movaw           { be=NUM, } { area=NUM, } { ind=NUM, } { am=NUM, } dst
  movad           { be=NUM, } { area=NUM, } { ind=NUM, } { am=NUM, } dst
  movaq           { be=NUM, } { area=NUM, } { ind=NUM, } { am=NUM, } dst
  
Разные операции
---------------

Ожидание исполнения предыдущих операций (WAIT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операции **WAIT** обеспечивают возможность ожидания опустошения части или всего конвейера перед выдачей команды,
которая содержит операцию **WAIT**.

Язык ассемблера:

::

  wait            NUM

Операция вставить пустые такты (BUBBLE)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Операция **BUBBLE** вставляет некоторое число пустых тактов.

Язык ассемблера:

::

  nop             { NUM }
        
Операции записи в регистры AAU
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  STAAW + MAS     pps  запись в регистр 32
  STAAD + MAS     ppd  запись в регистр 64
  STAAQ + MAS     ppq  запись в регистр 128

Язык ассемблера:

::

  apurw           src3, aau_reg
  apurwd          src3, aau_reg
  apurwq          src3, aau_reg
  
Названия операций apurw(d/q) имеют синонимы aaurw(d/q), которые можно
использовать наравне с основными именами.

Операции считывания регистров AAU
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  LDAAW + MAS     pps     считать регистр 32
  LDAAD + MAS     ppd     считать регистр 64
  LDAAQ + MAS     ppq     считать регистр 128

Язык ассемблера:

::

  apurr           aau_reg, dst
  apurrd          aau_reg, dst
  apurrq          aau_reg, dst
  
Названия операций apurr(d/q) имеют синонимы aaurr(d/q), которые можно
использовать наравне с основными именами.

Операции записи в управляющие регистры
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  RWs             -sr  запись в регистр состояния 32
  RWd             -dr  запись в регистр состояния 64

Язык ассемблера:

::

  rws             src2, state_register
  rwd             src2, state_register

Операции считывания управляющих регистров
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::

  RRs             r-s  считать регистр состояния 32
  RRd             r-d  считать регистр состояния 64

Язык ассемблера:

::

  rrs             state_register, dst
  rrd             state_register, dst
