Программирование DSP Blackfin: система команд (ассемблер) - часть 1 Sat, December 16 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Blackfin: система команд (ассемблер) - часть 1 Печать
Добавил(а) microsin   

В этом руководстве приведена первая часть перевода даташита "Blackfin DSP Instruction Set Reference" [1], где описывается система команд процессоров Blackfin. Вторая часть здесь: "Blackfin: система команд (ассемблер) - часть 2" [4].

[Введение]

Документ [1] предоставляет подробное описание инструкций языка ассемблера, используемых ядром процессоров BlackfinDSP (разработано совместно компаниями Analog Devices, Inc. и Intel). В этой секции приведены общие соглашения по содержимому документа. Обратите внимание, что некоторые термины не переведены - с целью наиболее полной передачи смысла документации. Все непонятные термины и сокращения см. в разделе Словарик в конце статьи, а также в разделе словарик общей документации по процессору Blackfin ADSP-BF538.

В этой первой части руководства сначала объясняются основные понятия и термины, затем обсуждается смысл каждой отдельной команды (инструкции) ассемблера.

Руководство организовано так, что инструкции ассемблера сгруппированы по своим выполняемым функциям. В пределах групп инструкции обычно расположены в алфавитном порядке, за исключением случаев, когда другое расположение не делает другой порядок более удобным и четким для понимания программистом. Один из примеров не алфавитного порядка - секция Load / Store, где Load Pointer Register появляется перед набором из семи производных от Load Data Register. Инструкции перечислены в начале каждой части, и в том порядке, в каком появляются в описании.

Группы инструкций, или части этого документа, перечислены друг за другом в порядке увеличения сложности, начиная с частей базовых инструкций Program Flow Control и Load / Store, и далее прогрессируя до инструкций Video Pixel Operations и Vector Operations.

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

[Синтаксис ассемблера]

Набор инструкций Blackfin поддерживает некоторые соглашения, которые появляются во всем изложении этого документа. Здесь приведено описание этих соглашений. В основном синтаксис соглашений совпадает с синтаксисом языка C.

Чувствительность к регистру символов (Case Sensitivity). Синтаксис инструкций не чувствителен к регистру, т. е. используемые буквы могут быть как заглавные, так и строчные.

Точно так же ассемблер обрабатывает и имена регистров, и ключевые слова языка ассемблер - не обращая внимания на регистр. Таким образом, к примеру, имена регистров R3.l, R3.L, r3.l, r3.L все будут допустимыми. Однако идентификаторы пользователя чувствительны к регистру символов. В этом руководстве имена регистров и ключевые слова инструкций показаны в нижнем регистре. В некоторых случаях, когда нужно сделать акцент, это руководство использует для имен регистров и инструкций верхний регистр.

Свободный формат. Ассемблерные инструкции имеют свободный формат, и могут появляться в любом месте строки. Одна инструкция может быть продолжена на нескольких строках, или в одной строке может быть несколько инструкций. Разделители (space, tab, комментарии, or newline) могут появляться в любом месте между частями инструкций. Отдельная часть инструкций (токен) не должна включать в себе разделителей. К токенам относятся числа, имена регистров, ключевые слова, идентификаторы пользователей, а также многосимвольные коды комментариев или операций наподобие "+=", "/*" или "||".

Разделение инструкций. Инструкции должны всегда завершаться точкой с запитой ';'. Несколько инструкций можно разместить на одной строке по усмотрению программиста, если каждая инструкция будет завершаться точкой с запятой.

Каждая полная инструкция завершается точкой с запятой. Иногда полная операция будет состоять из нескольких операций. Здесь может быть 2 случая:

• Скомбинированы 2 основные операции. Обычно в этих операциях отдельные части отделены запятой, например:

a0 = r3.h * r2.l , a1 = r3.l * r2.h;

• Основная инструкция объединена с одной или двумя ссылками на память для получения совместного результата. Последние части набора откладываются токеном "||". Например:

a0 = r3.h * r2.l || r1 = [p3++], r4 = [i2++];

Комментарии. Могут быть 2 вида комментариев в тексте кода на ассемблере:

• До конца строки: двойной слеш ("//") показывает, что с этого места начинается комментарий, и продолжается до появления символа newline.

• Основной комментарий: начинается с токена "/*" и оканчивается токеном "*/". Этот вид комментария может содержать в себе любые символы, и может распространяться на несколько строк.

Комментарии не поддерживают рекурсивность; если компилятор ассемблера увидел "/*" в теле основного комментария, то выдаст предупреждение. Комментарий функционирует так же, как и разделитель.

[Обозначения регистров и операндов (Notation Conventions)]

• Имена регистров состоят из одной или нескольких букв, за которой может следовать число в случае если в логической группе находится несколько однотипных регистров, различаемых по номерам. Например: ASTAT, FP, R3 и M2.

• Некоторые операции требуют использования пары регистров. Пары всегда являются Data Register, и регистре в паре разделены двоеточием, например R3:2. Номер с большим значением должен идти первым. Примечание: аппаратура поддерживает только пары нечентый-четный, т. е. R7:6, R5:4, R3:2 и R1:0.

• Некоторые инструкции требуют группы соседних регистров. Диапазон соседних регистров задается с помощью двух номеров регистров (начальный и последний регистр включительно), двоеточия между ними, и все это находится в квадратных скобках, например R[7:3]. И опять большее число должно идти первым.

• Можно по отдельности обращаться к частям регистра. Это осуществляется с помощью точки (".") после имени регистра, за которой идет буква, обозначающая нужную часть регистра. Для 32-битных регистров ".H" обозначает старшую половину (от слова "High"), ".L" обозначает младшую (от слова "Low"). Как разделяются 40-разрядные регистры будет описано позже.

Имена регистров зарезервированы и не могут использоваться в программе как идентификаторы пользователя. В этом руководстве применены следующие соглашения:

• Когда возможен выбор любого регистра из группы регистров, это будет показано с помощью многоточия ("..."). Например, "R0, ..., R7" означает, что можно выбрать любой из восьми указанных регистров.

• Непосредственные значения (immediate value) обозначаются как "imm" со следующими модификаторами:

— "imm" обозначает значение со знаком (signed); например imm7.
— префикс "u" показывает значение без знака (unsigned); например uimm4.
— десятичное число показывает, сколько бит может быть в значении; например, imm5 представляет 5-битное значение.
— любые требования к выравниванию значения показываются через опциональный суффикс "m", за которым следует число. Например, uimm16m2 обозначает беззнаковое 16-битное целое, в котором должно быть четное число (должно нацело делиться на 2), и imm7m4 обозначает целое 7-разрядное число со знаком, которое должно нацело делиться на 4.

Accumulator Saturation. Все операции дают результат в аккумуляторе с насыщением с до 40 бит, если не указано что-то другое. Подробнее о насыщении написано в разделе "Saturation (насыщение)" (см. далее).

[Терминология]

В этом документе появляются следующие термины. Термины относятся к архитектуре Blackfin, которая не описывается в этой статье (общее описание аппаратуры Blackfin см. в [2], или см. руководство ADSP-21535 Blackfin DSP Hardware Reference).

Имена регистров. Архитектура включает следующие имена:

Таблица 1-1. Регистры Blackfin.

Регистр Описание
Аккумуляторы 40-разрядные регистры A1 и A0 обычно содержат данные, над которыми производятся арифметические и логические манипуляции. Каждый из аккумуляторов может быть доступен различными способами - как 32-битные регистры (обозначаемые как A1.W и A0.W), как два 16-битных регистра (A1.H, A0.H, A1.L, A0.L) и как один 8-битный регистр (A1.X, A0.X) для старших битов (39..32).
Data Register Набор из восьми 32-битных регистров R0, R1, ..., R7, которые обычно содержат данные для операций. Кратко группа этих регистров называется D-регистр или Dreg. К данным в регистрах можно обращаться двумя способами - либо как к 32-битному регистру, либо как к двум регистрам, старшему High и младшему Low (которые соответственно обозначаются через суффиксы .H и .L, например R7.H, R2.L, r0.L, r5.h и т. п.).
Pointer Register Набор из шести 32-битных регистров P0, ..., P5, включая указатели стека SP и FP, которые обычно содержат байтовые адреса структур данных в памяти. Доступ к регистрам указателей возможен только как к 32-битным регистрам. Сокращенно группа регистров указателей называется P-регистр или Preg.
Stack Pointer Это указатель стека, сокращенно SP. Содержит 32-битный байтовый адрес последней занятой ячейки в памяти. Стек растет в сторону уменьшения адресов, т. е. с помещением данных в стек (PUSH) регистр SP декрементируется, при выборке данных из стека (POP) регистр SP инкрементируется. SP относится к группе регистров Preg.
Frame Pointer Это указатель фрейма, сокращенно FP. Содержит 32-битный байтовый адрес предыдущего указателя фрейма в стеке, размещенного в верхней части фрейма. FP относится к группе регистров Preg.
Loop Top Регистры LT0 и LT1, содержат 32-битный адрес вершины аппаратного цикла (zero overhead loop).
Loop Count Регистры LC0 и LC1, содержат 32-битный счетчик аппаратного цикла.
Loop Bottom Регистры LB0 и LB1, содержат 32-битный адрес дна аппаратного цикла.
Index Pegister Индексный регистр, к ним относятся четыре регистра I0, I1, I2, I3. Обычно содержат байтовый адрес в структурах данных и массивах. Сокращенно группа индексных регистров называется I-регистр или Ireg.
Modify Register Регистр модификации. К этим регистрам относится группа из четырех 32-битных регистров M0, M1, M2, M3, сокращенно называемая Mreg. Регистр Mreg обычно содержит смещение, которое добавляется или отнимается от адреса в одном из регистров Ireg.
Length Register Регистр длины. Набор из четырех 32-битных регистров L0, L1, L2, L3, обычно содержащие длину (в байтах) кольцевого буфера. Сокращенно группа регистров длины называется Lreg.
Base Registers Регистр базы. Набор из четырех 32-битных регистров B0, B1, B2, B3, обычно содержащий базовый адрес (адрес байта) кольцевого буфера. Сокращенно группа регистров базы называется Breg.

Процессор может работать в обычном режиме (user mode) и в режиме супервизора (supervisor mode). Обычный режим - это выполнение программы вне прерываний, режим супервизора - во время прерывания. Для обычного режима и для режима супервизора используются отдельные указатели стека, так что от режима работы процессора зависит использование указателей стека. Всего у процессора Blackfin есть 3 указателя стека, доступ к которым осуществляется по следующим именам:

SP Stack Pointer. Во время выполнения основной программы (user mode, не режим супервизора) это обычный пользовательский стек. Если активен режим супервизора, то имя SP ссылается на стек супервизора. Указатель стека содержит 32-битный байтовый адрес последнего занятого места в стеке. Стек растет по мере уменьшения указателя стека, т. е. проталкивание в стек уменьшает значение указателя стека, а выборка из стека увеличивает значение указателя стека.

USP User Stack Pointer. Псевдоним обычного стека, который используется во время обработки прерываний (supervisor mode, режим супервизора). Псевдоним USP недоступен в user mode.

FP Frame Pointer. Регистр указателя фрейма, содержит 32-битный адрес предыдущего указателя фрейма в стеке.

[Регистры указателей]

Набор 32-битных регистров P0, P1, P2, P3, P4, P5, SP и FP обычно содержат байтовый адрес структур данных. Регистры Px называют P-регистрами или Preg.

[Указатели фрейма и стека]

Во многих отношениях регистры указателя стека и указателя фрейма выступают как другие P-регистры, P[5:0]. Они могут работать как главные указатели в любых инструкциях загрузки/сохранения, например R1 = B[SP] (Z). Однако у регистров FP и SP имеется дополнительная функциональность.

Регистры указателя стека включают:

• user stack pointer, указатель стека пользователя (USP в режиме супервизора, SP в режиме пользователя).
• supervisor stack pointer, указатель стека супервизора (SP в режиме супервизора).

К регистру user stack pointer register и регистру supervisor stack pointer осуществляется доступ через регистровый псевдоним SP. В зависимости от текущего рабочего режима процессора, только один из этих регистров активен и доступен как SP:

• В пользовательском режиме любая ссылка на SP (например, выборка из стека, stack pop R0 = [ SP++ ];) неявно использует USP в качестве эффективного адреса.
• В режиме супервизора то же самое обращений к SP (например, R0 = [ SP++ ];) неявно использует указатель стека супервизора в качестве эффективного адреса.

Чтобы манипулировать указателем стека пользовательского режима (user stack pointer) для кода, работающего в режиме супервизора, используется регистровый псевдоним USP. Когда активен режим супервизора, перемещение регистра из USP (например, R0 = USP;) перемещает текущее значение указателя стека пользователя (в этом примере в R0). Имя регистра USP можно использовать только в supervisor mode.

Некоторые инструкции загрузки/сохранения (load/store) неявно используют FP и SP:

• Индексированная загрузка/сохранение через FP (FP-indexed load/store), которая расширяет диапазон адресации для кодируемых 16 битами операций загрузки/сохранения.
• Инструкции проталкивания/выборки (push/pop) стека, включая те, которые используются для проталкивания и выборки нескольких регистров.
• Инструкции link/unlink, которые управляют пространством окна стека и обслуживают для этого пространства регистр указателя фрейма (frame pointer register, FP).

Функциональные блоки. Архитектура включает 2 аппаратные секции процессора:

Таблица 1-2. Аппаратные секции обработки (processor).

Processor Описание
Data Address Generator (DAG) Генератор адреса, вычисляет эффективный адрес для косвенного (indirect) и индексированного доступа к памяти. Состоит из 2 секций - DAG0 и DAG1.
Multiply and Accumulate Unit (MAC) Производит арифметические операции над данными. Состоит из 2 секций MAC0 и MAC1, каждая связана с аккумулятором (A0 и A1 соответственно).

[Флаги арифметики]

Это признаки результатов арифметических операций (Arithmetic Status Flags). Micro Signal Architecture (MSA) включает 12 арифметических флагов, которые показывают состояние только что выполненной операции. Эти флаги находятся в регистре ASTAT (Arithmetic Status Register). Ниже показано описание этих флагов. У всех флагов активное состояние соответствует лог. 1. Инструкции, относящиеся к P-регистрам, I-регистрам, L-регистрам, M-регистрам или B-регистрам, никак не влияют на значение флагов. Подробнее см. [2] и ADSP-21535 Blackfin DSP Hardware Reference.

Таблица 1-3. Общее описание Arithmetic Status Flag.

Флаг Описание
AC0 Carry, флаг переноса. Относится к блоку ALU0.
AC1 Carry, флаг переноса. Относится к блоку ALU1.
AN Negative, флаг отрицательного значения.
AQ Quotient, флаг частного.
AV0 Accumulator 0 Overflow, флаг переполнения аккумулятора A0.
AVS0 Accumulator 0 Sticky Overflow. Устанавливается, когда устанавливается AV0, но остается установленным, пока не будет явно очищен программой пользователя.
AV1 Accumulator 1 Overflow, флаг переполнения аккумулятора A1.
AVS1 Accumulator 1 Sticky Overflow. Устанавливается, когда устанавливается AV1, но остается установленным, пока не будет явно очищен программой пользователя.
AZ Zero, флаг нулевого результата.
CC Control Code bit, флаг множественного назначения, очищается и устанавливается отдельными инструкциями.
V Overflow, флаг переполнения для результатов в регистрах Dreg.
VS Sticky Overflow для результатов в регистрах Dreg. Устанавливается, когда устанавливается V, но остается очищенным, пока не будет явно сброшен кодом пользователя.

[Кодирование дробных чисел]

Дробные числа - это те числа, в составе которых есть компонента, меньшая по абсолютному значению чем ±1. Как и с десятичными дробными числами, где дробная часть находится справа от десятичной точки, в двоичном кодировании дробных чисел дробная часть также появляется справа от точки.

Blackfin fractional numbers fig11

Рис. 1-1. Размещение двоичной точки в 40-, 32- и 16-битных данных.

[Saturation (насыщение)]

Когда результат арифметической операции превышает диапазон регистра назначения, то значащие данные могут быть потеряны. В этом контексте Saturation является техникой, используемой для удержания количества значений, которое может содержать регистр результата. Когда вычисленное значение превышает размер регистра результата, тогда значение, записанное в регистр, содержит самое большое число, которое регистр может содержать, и с тем же знаком, что и оригинал.

• Если операция должна была бы завершиться положительным значением, которое при переполнении превратится в отрицательное, функция saturation вместо этого ограничит результат максимальным положительным значением, которое может содержать регистр.

• Подобным образом, если операция должна была бы завершиться отрицательным числом, но из-за ограниченной разрядности привела бы к переполнению и положительному результату, то вместо этого saturation даст результат в виде максимального (по абсолютному значению) для этого регистра отрицательного значения.

Арифметический флаг переполнения никогда не устанавливается на операции, которая использует насыщение.

Максимальное положительное значение 16-битного регистра равно 0x7FFF. Максимальное (по абсолютному значению) отрицательное значение для него равно 0x8000. Для чисел со знаком, кодируемых с двоичным дополнением (signed 2’s complement) в дробной нотации 1.15 допустимый диапазон чисел составляет от -1 до (1-2-15).

Максимальное положительное значение 32-битного регистра равно 0x7FFF FFFF. Максимальное (по абсолютному значению) отрицательное значение для него равно 0x8000 0000. Для чисел со знаком, кодируемых с двоичным дополнением (signed 2’s complement) в дробной нотации 1.31 допустимый диапазон чисел составляет от -1 до (1-2-31).

Максимальное положительное значение 40-битного регистра равно 0x7F FFFF FFFF. Максимальное (по абсолютному значению) отрицательное значение для него равно 0x80 0000 0000. Для чисел со знаком, кодируемых с двоичным дополнением (signed 2’s complement) в дробной нотации 9.31 допустимый диапазон чисел составляет от -256 до (256-2-31).

Например, если 16-битных регистр содержит 0x1000 (десятичное целое +4096) и был сдвинут влево 3 раза без использования функции насыщения, то произойдет переполнение к 0x8000 (десятичное число -32768). С операцией насыщения сдвиг влево 3 раза даст в качестве результата значение максимального положительного 16-битного числа, т. е. 0x7FFF (десятичное +32767).

Другой общий пример - копирование младшей половины 32-битного регистра в 16-битный регистр. Если 32-битный регистр содержит 0xFEED 0ACE, и младшая половина этого отрицательного числа копируется в 16-битный регистр без использования насыщения, то в результате получится 0x0ACE, что является положительным числом. Но при использовании насыщения, 16-битный результат останется отрицательным, и станет 0x8000.

В MSA реализовано 40-битное насыщение для всех арифметических операций, которые записывают результат в аккумуляторе, за исключением отдельных инструкций, что указано в их описании, когда опциональный 32-битный режим может ограничить 40-bit Accumulator в 32-битном регистровом диапазоне. MSA выполнит 32-битное насыщения для 32-битных регистров назначения только когда это указано в описании инструкций.

[Переполнение (Overflow)]

Эта функция является альтернативой функции насыщения. Числу разрешается просто перевалить за свои границы, так что будут потеряны его самые старшие биты (один или несколько); при этом могут быть сохранены только младшие (наименее значимые) биты результата числа. Переполнение может произойти, когда 40-битное значение записывается в 32-битный регистр назначения. Если была какая-то полезная информация в старших 8 битах 40-разрядного значения, то она будет потеряна. Некоторые инструкции процессора могут сообщать о событиях переполнения арифметическими флагам (находящимися в регистре ASTAT), как это указано в описании инструкции. Подробное описание регистра ASTAT см. в руководстве ADSP-21535 Blackfin DSP Hardware Reference.

[Rounding, Truncating]

Rounding (округление), Truncating (отбрасывание части результата). Rounding означает округление. Эта операция заключается в уменьшении точности числа путем удаления некоторого количества младших бит, включая возможную модификацию этих младших бит так, чтобы максимально точно соответствовать исходному числу. Например, у исходного числа было N бит точности, в то время как новое число будет иметь только M бит точности (где N>M), тогда N-M бит точности будут удалены в процессе округления.

Метод округления до ближайшего значения (round-to-nearest) вернет число, ближайшее по значению к оригиналу. Условились, что когда исходное число, находится точно посередине между двумя возможными результатами для округления, всегда при округлении будет выбрано большее по результату число. Например, когда происходит округление 3 бит, дробное число 0.25 (в двоичном представлении 0.01) при округлении даст 0.5 (двоичное 0.1). Оригинальное двоичное число лежит точно между числами 0.5 и 0.0, так что округление произойдет вверх. Поскольку в этом округлении всегда идет округление вверх, этот метод называется biased rounding (смещенное округление).

Метод конвергентного округления (convergent rounding) также возвращает ближайшее к оригиналу число. Однако для случая, когда оригинальное число лежит посередине между двумя возможными ближайшими результатами округления, этот метод вернет ближайшее четное число, в котором самый младший бит LSB равен 0. Для ранее приведенного примера результат станет 0.0, поскольку он будет четным из двух вариантов 0.5 и 0.0. Поскольку округление может произойти как вверх, так и вниз, этот метод называется unbiased rounding (несмещенное округление).

Некоторые инструкции Blackfin поддерживают biased и unbiased округление. Бит RND_MOD в регистре ASTAT задает, какой режим округления используется. Подробное описание регистра ASTAT см. в руководстве ADSP-21535 Blackfin DSP Hardware Reference.

Другой общий метод уменьшение количества значащих бит числа - простое маскирование N-M младших бит. Этот процесс называется truncation (усечение, или отбрасывание младших битов), и в результате получается относительно большая ошибка округления.

Ниже на рисунке показаны примеры методов rounding и truncation.

Blackfin 8to4 reduce precision example fig12

Рис. 1-2. Два примера, в которых показано уменьшение точности 8-битного числа до 4 бит.

[Косвенная и индексная адресация с постинкрементом индекса]

Форма синтаксиса Dest = [ Src_1 ++ Src_2 ] называется косвенной (indirect) адресацией с постинкрементом индекса адреса. Это укороченная форма следующей последовательности:

Dest = [Src_1]; // косвенная загрузка 32-битного адреса назначения
Src_1 += Src_2; // постинкремент Src_1 на величину индекса в Src_2

где:

• Dest это регистр назначения (Dreg в примере синтаксиса).
• Src_1 это первый регистр адреса источника.
• Src_2 это второй регистр адреса источника.

Косвенная адресация с пост-инкрементом индекса поддерживает настраиваемую последовательность косвенной адресации. Косвенная, с постинкрементом индекса версия должна получать в качестве входных операндов два отдельных P-регистра. Если же будет использоваться один общий Preg для обоих регистров операндов, то функция автоинкремента работать не будет.

[Инструкции Program Flow Control]

К инструкциям Program Flow Control относят команды передачи управления, т. е. переходы внутри программы. Это команды безусловного перехода (JUMP, JUMP.S, JUMP.L), перехода по условию (IF CC JUMP, IF !CC JUMP), вызова подпрограммы (CALL), возврата из подпрограммы и прерывания (RTS, RTI, RTX, RTN, RTE), настройки аппаратного цикла (LSETUP, LOOP, LOOP_BEGIN, LOOP_END).

Примечание: компилятор и линкер VisualDSP++ поддерживают расширение команд CALL и JUMP в виде суффикса ".X". Например, допустимы команды CALL.X и JUMP.X, они часто встречаются в автоматически генерируемом коде запуска проекта VisualDSP++. Это на самом деле псевдокоманды, которые на этапе компиляции и линковки будут автоматически заменены на наиболее эффективные с точки зрения минимального времени выполнения и размера. Решение будет принято в зависмости от того, насколько далеко находится адрес назначения относительно текущего адреса - эффективные команды перехода и вызова подпрограммы имеют ограничения по области действия.

Cинтаксис:

JUMP (Preg);         // переход по абсолютному (не привязанному к программному
                     // счетчику PC) адресу (a)1

JUMP (PC + Preg);    // переход относительно PC (b)

JUMP pcrelm2;        // переход относительно PC, непосредственный2 (a),
                     // или (b), см. функциональное описание.

JUMP.S pcrel13m2;    // переход относительно PC, непосредственный, короткий (short (a))

JUMP.L pcrel25m2;    // переход относительно PC, непосредственный, дальний (long (b))

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: эта инструкция может использоваться в программах на уровне ассемблера, когда конечное расстояние до цели во время написания программы пока не известно. Ассемблер при компиляции сам подставит коды инструкций JUMP.S или JUMP.L, в зависимости от длины перехода. Дизассемблированный код покажет вместо инструкции JUMP мнемонику JUMP.S или JUMP.L.

[Терминология синтаксиса]

Preg: P0, ..., P5, SP, FP.

pcrelm2: неопределенное 25-битное (или с меньшим количеством бит со знаком) четное относительное смещение, с диапазоном -16,777,216 .. 16,777,214 байт (0xFF00 0000 .. 0x00FF FFFE).

pcrel13m2: 13-битное со знаком четное относительное смещение, с диапазоном -4096 .. 4094 байт (0xF000 .. 0x0FFE).

pcrel25m2: 25-битное со знаком четное относительное смещение, с диапазоном -16,777,216 .. 16,777,214 байт (0xFF00 0000 .. 0x00FF FFFE).

[Функциональное описание]

Инструкция перехода принудительно загружает новое значение в счетчик программ (Program Counter, PC), чтобы поменять порядок выполнения программы (program flow).

В косвенной или индексированной версиях инструкции значение в Preg должно быть четным числом (в котором bit0 = 0), чтобы сохранить 16-битное выравнивание адреса. Иначе нечетное смещение в Preg приведет к генерации процессором исключение выравнивания (alignment exception).

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

jump (p5);
jump (pc + p2);
jump 0x224 ;         // смещение положительное, в 13 битах, так что целевой адрес
                     // будет PC + 0x224, что означает переход вперед
jump.s 0x224 ;       // то же самое, что jump с коротким синтаксисом
jump.l 0xFFFACE86;   // смещение отрицательное, в 25 битах, так что целевой адрес
                     // будет PC + 0x1FA CE86, что означает обратный переход
jump get_new_sample; // ассемблер сам по метке вычислит целевой адрес, благодаря
                     // использованию метки здесь указано абстрактное смещение

См. также инструкции ветвления (IF CC JUMP, IF !CC JUMP), CALL.

Это команды перехода по условию (ветвление, Branch). Синтаксис:

IF CC JUMP pcrell1m2;        // переход, если CC=1, ветвление предсказано как
                             // не полученное2 (a)1

IF CC JUMP pcrel11m2 (bp);   // переход, если CC=1, ветвление предсказано как
                             // полученное2 (a)

IF !CC JUMP pcrel11m2;       // переход, если CC=0, ветвление предсказано как
                             // не полученное3 (a)

IF !CC JUMP pcrel11m2 (bp);  // переход, если CC=0, ветвление предсказано как
                             // полученное3 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Примечание 2: значение бита CC=1 приведет к переходу по адресу, вычисленному как четное смещение со знаком относительно текущего значения счетчика PC.

Примечание 3: значение бита CC=0 приведет к переходу по адресу, вычисленному как четное смещение со знаком относительно текущего значения счетчика PC.

[Терминология синтаксиса]

pcrel11m2: 11-битное, четное смещение со знаком, в диапазоне -1024 .. 1022 байт (0xFC00 .. 0x03FE). Это значение может быть опционально заменено меткой адреса, которая буде вычислена и заменена на реальный адрес во время линковки.

[Функциональное описание]

Инструкция перехода по условию (Conditional Jump) загружает новое значение в программный счетчик (Program Counter, PC), что изменит порядок выполнения программы, в зависимости от значения бита CC. Таким образом, от бита CC зависит, какая ветвь (Branch) программы будет выполнена.

[Опция предсказывания]

Опция предсказывания ((bp), сокращение от Branch Prediction) помогает процессору улучшить производительность инструкции ветвления. По умолчанию предсказывание не используется. Путем добавления опции (bp) к инструкции ветвление получает предсказание.

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

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

if cc jump 0xFFFFFE08 (bp);   // смещение отрицательное из 11 бит, так что происходит
                              // переход назад, ветвление с предсказанием
if cc jump 0x0B4;             // смещение положительное, так что происходит переход
                              // вперед, без предсказания ветвления
if !cc jump 0xFFFFFC22 (bp);  // смещение отрицательное из 11 бит, так что происходит
                              // переход назад, ветвление с предсказанием
if !cc jump 0x120;            // положительное смещение, так что происходит переход
                              // вперед, без предсказания ветвления
if cc jump dest_label;        // ассемблер сам определит целевой адрес, смещение
                              // указано абстрактно благодаря метке

См. также JUMP, CALL.

Команда вызова подпрограммы. Синтаксис:

CALL (Preg);         // косвенная адресация по абсолютному (без
                     // привязки к адресу в PC) адресу (a)1

CALL (PC + Preg);    // индексированная адресация относительно PC (a)

CALL pcrel25m2;      // непосредственная адресация относительно PC (b)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Preg: P0, ..., P5 (регистры SP и FP не могут использоваться как источник адреса для этой инструкции).

pcrel25m2: 25-битное со знаком, четное, привязанное к PC смещение; может быть указано как символическая адресная метка, с диапазоном -16,777,216 .. 16,777,214 (0xFF00 0000 .. 0x00FF FFFE) байт.

[Функциональное описание]

Инструкция CALL вызывает подпрограмму по адресу, на который указывает P-регистр или с использованием смещения относительно текущего счетчика команд (PC). После выполнения инструкции CALL регистр RETS содержит адрес следующей после CALL инструкции.

Значение в Preg должно быть четным, чтобы сохранить 16-битное выравнивание.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

call (p5);
call (pc + p2) ;
call 0x123456;
call get_next_sample; 

См. также RTS, RTI, RTX, RTN, RTE, JUMP, IF CC JUMP, IF !CC JUMP.

Инструкции для возврата из подпрограммы. Синтаксис:

RTS; // Возврат из подпрограммы (a)

RTI; // Возврат из обработчика прерывания (a)

RTX; // Возврат из обработчика исключения, exception (a)

RTN; // Возврат из обработчика немаскируемого прерывания, NMI (a)

RTE; // Возврат из режима эмуляции (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Функциональное описание]

Инструкция возврата делает принудительный возврат потока выполнения из подпрограммы, немаскируемого (NMI) или маскируемого обработчика прерывания ISR, подпрограммы обработки исключения или подпрограммы обработки эмуляции (см. таблицу 2-1).

Таблица 2-1. Типы инструкций возврата.

Мнемоника Описание
RTS Делает принудительный возврат из подпрограммы путем загрузки значения из регистра RETS в счетчик программы (Program Counter, PC), что приводит процессор к выборке следующей инструкции от адреса, содержащегося в RETS. Для вложенных вызовов подпрограмм Вы должны сохранить (обычно для этого используется стек) значение регистра RETS. Иначе следующий вызов подпрограммы CALL перезапишет регистр RETS.
RTI Делает принудительный возврат из обработчика прерывания путем загрузки значения из регистра RETI в счетчик программы (Program Counter, PC). Когда происходит прерывание, процессор входит в состояние, когда прерывания невозможны. Сохранение значения регистра RETI в стек разрешит прерывания, так что все последующие прерывания с более высоким приоритетом могут прерывать обработку текущего прерывания (этим достигается возможность вложенных друг в друга прерываний). Если RETI не был сохранен в стек, то более высокоуровневое прерывание будет аппаратно зарегистрировано в системе процессора, но оно не будет обслуживаться, пока не завершит свою работу текущий обработчик прерывания. Восстановление RETI обратно из стека по завершении обработчика прерывания маскирует последующие прерывания, пока выполняется инструкция RTI. В любом случае RETI защищен от нежелательного повреждения со стороны более высокоуровневых прерываний.
RTX Делает принудительный возврат из обработчика исключения путем загрузки в PC значения регистра RETX.
RTN Делает принудительный возврат из подпрограммы обработки NMI путем загрузки в PC значения регистра RETN.
RTE Делает принудительный возврат из программы эмуляции и выход из режима эмуляции путем загрузки значения регистра RETE в PC. Поскольку только одна подпрограмма обработки эмуляции может быть запущена в любой промежуток времени (не может быть вложенного вызова для подпрограммы эмуляции), то поддержка вложенности не нужна, и сохранение значения регистра RETE не требуется.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

В таблице 2-2 идентифицирует режимы, требуемые для инструкции возврата.

Таблица 2-1. Типы инструкций возврата.

Мнемоника Требуемый режим процессора
RTS User и Supervisor.
RTI, RTX и RTN Только режим Supervizor. Любая попытка выполнить эти инструкции в режиме пользователя (User) приведет к исключению нарушения защиты (protection violation exception).
RTE Только режим эмуляции (Emulation). Любая попытка выполнить эти инструкции в режиме пользователя (User) или супервизора (Supervizor) приведет к исключению (exception).

[Параллельное выполнение]

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

[Примеры]

rts;
rti;
rtx;
rtn;
rte;

См. также CALL, PUSH, POP.

Это так называемые инструкции для запуска аппаратного цикла (Zero-Overhead Loop Setup). Цикл можно задавать в двумя способами:

LSETUP (Begin_Loop, End_Loop) Loop_Counter

и

LOOP loop_name loop_counter
LOOP_BEGIN loop_name
LOOP_END loop_name

Синтаксис:

Для Loop0

LSETUP (pcrel5m2, lppcrel11m2) LC0;             // (b)
LSETUP (pcrel5m2, lppcrel11m2) LC0 = Preg;      // автоинициализация LC0 (b)1
LSETUP (pcrel5m2, lppcrel11m2) LC0 = Preg >> 1; // автоинициализация LC0 (b)
LOOP loop_name LC0;                             // (b)
LOOP loop_name LC0 = Preg;                      // автоинициализация LC0 (b)
LOOP loop_name LC0 = Preg >> 1;                 // автоинициализация LC0 (b)

Для Loop1

LSETUP (pcrel5m2, lppcrel11m2) LC1;             // (b)
LSETUP (pcrel5m2, lppcrel11m2) LC1 = Preg;      // автоинициализация LC1 (b)
LSETUP (pcrel5m2, lppcrel11m2) LC1 = Preg >> 1; // автоинициализация LC1 (b)
LOOP loop_name LC1;                             // (b)
LOOP loop_name LC1 = Preg;                      // автоинициализация LC1 (b)
LOOP loop_name LC1 = Preg >> 1;                 // автоинициализация LC1 (b)

LOOP_BEGIN loop_name;         // определение первой инструкции для цикла (b)
LOOP_END loop_name;           // определение последней инструкции для цикла (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Preg: P0, ..., P5 (регистры SP и FP не могут использоваться как источник адреса для этой инструкции).

pcrel5m2: 5-битное со знаком, четное, привязанное к PC смещение; может быть указано как символическая адресная метка, с диапазоном 4 .. 30, или 25-2.

lppcrel11m2: 11-битное без знака, привязанное к PC смещение для цикла; может быть заменено символической меткой. Диапазон 4 .. 2046 (0x0004 .. 0x07FE), или 211-2.

loop_name: символическая адресная метка.

[Функциональное описание]

Инструкция настройки аппаратного цикла (Zero-Overhead Loop Setup) предоставляет гибкий, основанный на счетчике, механизм запуска аппаратного цикла, что дает очень эффективный, с минимальными потерями, цикл для программы. В этом контексте zero-overhead (дословно переводится как "нулевые потери") означает, что программа в цикле не нуждается в вычислениях для декрементирования счетчика, проверке условия цикла, чтобы вычислить и сделать переход на новый целевой адрес - все эти действия происходят автоматически, под управлением аппаратуры процессора. Благодаря этому могут быть организованы особенно быстрые и эффективные циклы.

Архитектура предоставляет 2 набора, каждый из 3 регистров, для поддержки двух не зависимых друг от друга цикла, которые могут быть вложены друг в друга (Loop0 и Loop1). Это регистры Loop_Top (LTn), Loop_Bottom (LBn) и Loop_Count (LCn). Здесь буква n может быть заменена на 0 или 1, так что получаются регистры LT0, LB0 и LC0 для описания Loop0, и LT1, LB1 и LC1 для описания Loop1.

Инструкции LSETUP и LOOP предоставляют удобный способ инициализации всех трех регистров в одной инструкции. Размер инструкций LSETUP и LOOP может поддержать не так много бит, так что размер тела цикла ограничен. Однако LT0 и LT1, LB0 и LB1 и LC0 и LC1 могут быть инициализированы вручную инструкциями Move, если длина цикла и счетчик повторов должен выйти за пределы, предоставляемые синтаксисом LSETUP или LOOP. Таким образом, один цикл может покрыть весь диапазон адресного пространства 4 гигабайта.

Инструкция LSETUP опционально принимает значение инициализации из P-регистра, или из P-регистра, поделенного на 2.

Альтернативный синтаксис для достижения того же результата состоит из последовательности инструкций LOOP, LOOP_BEGIN, LOOP_END. Этот синтаксис передает в себе ту же самую информацию, что и синтаксис LSETUP, но возможно его формат более удобочитаемый, и более понятен для пользователя.

Если LCn не ноль, когда выбранный адрес равен LBn, процессор декрементирует LCn и помещает адрес из LTn в PC. Цикл всегда проходит как минимум один раз сквозь тело цикла, так как условие цикла проверяется в конце петли.

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

В синтаксисе инструкции счетчик назначения цикла – LC0 или LC1 – определяет, какой уровень цикла инициализирован. Соответственно, для инициализации Loop0 кодируйте LC0; для инициализации Loop1 кодируйте LC1.

В случае вложенности циклов, которые оканчиваются на одну и ту же инструкцию, процессор требует, чтобы Loop0 был описан для внешнего цикла, и Loop1 для внутреннего цикла. Пользователь отвечает за выполнение этого требования.

Например, если LB0=LB1, то процессор подразумевает, что loop 1 внутренний, и loop 0 внешний.

Точно так же, как содержимое других регистров, содержимое регистров цикла может быть сохранено и восстановлено. Если требуется вложение циклов на больше, чем 2 уровня, то пользователь может явно сохранить значения регистров внешнего цикла, заново использовать эти регистры, затем восстановить регистры внешнего цикла перед завершением внутреннего цикла. В этом случае loop 0 должен быть всегда внешним по отношению к loop 1. Альтернативно, пользователь может реализовать внешние циклы программно, с помощью структур с командами условного перехода.

С Begin_Loop значение загружается в LTn. Это 5-разрядное, привязанное к PC, четное смещение от текущей инструкции до первой инструкции в теле цикла. Пользователь должен сохранить выравнивание до половины слова (на 2 байта), путем записи четного значения в этот регистр. Смещение интерпретируется как беззнаковое число с дополнением до единицы, не допускающее обратных циклов.

С End_Loop значение загружается в LBn. Это 11-разрядное, беззнаковое, четное, привязанное к PC смещение от текущей инструкции до последней инструкции в цикле.

Когда используется инструкция LSETUP, то Begin_Loop и End_Loop являются обычно адресными метками. Линкер заменяет метки на значения смещения, как обычно.

Регистр счетчика цикла (LC0 или LC1) считает проходы сквозь тело цикла. Этот регистр содержит 32-битное число без знака, что даст до 4,294,967,294 повторов тела цикла. Цикл запрещается (последующие прохождения сквозь тело цикла произойдут без повторов), когда значение счетчика цикла равно 0.

Последняя инструкция цикла LSETUP не должна быть инструкцией условного перехода (ветвления). Пока аппаратный цикл активен (т. е. пока Loop_Count не равен 0), инструкция ветвления по адресу End_Loop произведет неопределенное выполнение. Если инструкция ветвления появится после цикла LSETUP, то не будет сгенерировано исключение. Инструкции ветвления, размещенные где-нибудь еще внутри тела цикла, будут выполняться нормально, как обычно.

Также последняя инструкция в LSETUP не должна модифицировать регистры, которые определяют текущий активный цикл (LCn, LTn или LBn). Модификация пользователем этих регистров при доступе к ним со стороны аппаратуры процессора приведет к неопределенному выполнению. Программа может легально модифицировать счетчик цикла в любом другом месте тела цикла.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

lsetup (4, 4) lc0;
lsetup (poll_bit, end_poll_bit) lc0;
lsetup (4, 6) lc1;
lsetup (FIR_filter, bottom_of_FIR_filter) lc1;
lsetup (4, 8) lc0 = p1;
lsetup (4, 8) lc0 = p1>>1;
 
loop DoItSome LC0;   /* определение цикла ‘DoItSome’ с Loop
                        Counter 0 (со счетчиком цикла 0) */
loop_begin DoItSome; /* поместить перед первой инструкцией цикла */
loop_end DoItSome;   /* поместить после последней инструкции цикла */
 
loop MyLoop LC1;     /* определить цикл ‘MyLoop’ со счетчиком
                        цикла 1 (Loop Counter 1) */
loop_begin MyLoop;   /* поместить перед первой инструкцией цикла */
loop_end MyLoop;     /* поместить после последней инструкции цикла */

См. также инструкции безусловного (JUMP, JUMP.S, JUMP.L) и условного перехода (IF CC JUMP, IF !CC JUMP).

[Инструкции Load / Store]

В этом разделе обсуждаются инструкции загрузки (load) / сохранения (store). Пользователи могут пользоваться такими возможностями инструкций, как загрузка и сохранение прямых (immediate) значений, регистров указателей, регистров данных, половинок регистров данных и полуслов (дополненных нулем или знаком числа).

Эта инструкция загружает непосредственное (immediate) значение в регистр. Непосредственное значение - это значение, указанное прямо в команде, т. е. константа. Инструкции Load Immediate используются для инициализации значения регистров. Общая форма инструкции:

регистр = константа
A1 = A0 = 0

Не расширенный (not extended) синтаксис:

reg_lo = uimm16 ; // 16-битное значение будет загружено в младшую половину
                  // регистра данных или регистра адреса (b)1
reg_hi = uimm16 ; // 16-битное значение будет загружено в старшую половину
                  // регистра данных или регистра адреса (b)

Расширенный нулем (zero-extended) синтаксис:

reg = uimm16 (Z); // 16-битное значение, дополненное нулем, будет загружено
                  // в регистр данных или регистр адреса (b)

A0 = 0;           // Очистка регистра A0 (b)
A1 = 0;           // Очистка регистра A1 (b)
A1 = A0 = 0;      // Очистка двух регистров A1 и A0 сразу (b)

Расширенный знаком (sign-extended) синтаксис:

Dreg = imm7 (X);  // 7-битное значение, расширенное знаком, будет загружено в Dreg (a)
Preg = imm7 (X);  // 7-битное значение, расширенное знаком, будет загружено в Preg (a)

reg = imm16 (X);  // 16-битное значение, расширенное знаком, будет загружено в регистр
                  // данных или в регистр адреса (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

reg_lo: R0.L, ..., R7.L, P0.L, ..., P5.L, SP.L, FP.L, I0.L, ..., I3.L, M0.L, ..., M3.L, B0.L, ..., B3.L, L0.L, ..., L3.L.

reg_hi: R0.H, ..., R7.H, P0.H, ..., P5.H, SP.H, FP.H, I0.H, ..., I3.H, M0.H, ..., M3.H, B0.H, ..., B3.H, L0.H, ..., L3.H.

reg: R0, ..., R7, P0, ..., P5P0, ..., P5, SP, FP, I0, ..., I3, M0, ..., M3, B0, ..., B3, L0, ..., L3.

imm7: 7-битное поле со знаком, число в диапазоне -64 .. 63 (0x40 .. 0x3F).

imm16: 16-битное поле со знаком, число в диапазоне -32,768 .. 32,767 (0x8000 .. 0x7FFF).

uimm16: 16-битное поле без знака, число в диапазоне 0 .. 65,535 (0x0000 .. 0xFFFF)

[Функциональное описание]

Инструкция Load Immediate загружает в регистр непосредственное значение (т. е. константу, указанную в команде). Инструкция загрузит 7-битную или 16-битную величину, в зависимости от размера непосредственных данных. Диапазон загружаемых констант может быть 0x8000 .. 0x7FFF, что эквивалентно –32768 .. +32767.

В 40-разрядный аккумулятор (A1 или A0) могут быть загружены только нули.

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

Версии zero-extended заполнит нулями старшие биты регистра назначения. Версии sign-extended заполнят старшие биты знаком константы.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

r7 = 63(z);
p3 = 12(z);
r0 = -344(x);
r7 = 436(z);
m2 = 0x89ab(z);
p1 = 0x1234(z);
m3 = 0x3456(x);
l3.h = 0xbcde;
a0 = 0;
a1 = 0;
a1 = a0 = 0;

См. также инструкции Load Data Register, Load Pointer Register.

Эта инструкция загружает значение в адресный регистр (или другими словами, регистр указателя pointer register, Preg) с помощью косвенной (indirect) адресации. Косвенный адрес - это адрес, указанный через адресный регистр. Общая форма инструкции:

P-регистр = [ косвенный_адрес ]

Синтаксис:

Preg = [Preg];            // косвенная загрузка (a)

Preg = [Preg ++];         // косвенная загрузка с постинкрементом (a)1

Preg = [Preg --];         // косвенная загрузка с постдекрементом (a)

Preg = [Preg + uimm6m4];  // индексированная загрузка с малым смещением (a)

Preg = [Preg + uimm17m4]; // индексированная загрузка с большим смещением (b)

Preg = [Preg - uimm17m4]; // индексированная загрузка с большим смещением (b)

Preg = [FP - uimm7m4];    // индексированная загрузка относительно FP (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

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

Preg: P0, ..., P5, SP, FP.

uimm6m4: 6-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 0 .. 60 байт.

uimm7m4: 7-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 4 .. 128 байт.

uimm17m4: 17-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 0 .. 131068 байт (0x0000 0000 .. 0x0001 FFFC).

[Функциональное описание]

Инструкция загрузки указателя (Load Pointer Register) загружает 32-битный P-регистр 32-битным словом, находящимся по адресу, указанному также через P-регистр (или через регистр указателя фрейма FP). Поэтому такая адресация называется косвенной (indirect).

Косвенный адрес и смещение должно соответствовать четному умножению на 4, чтобы сохранить 4-байтное выравнивание адреса (значение адреса должно нацело делиться на 4). Неправильное выравнивание приведет к исключению ошибки доступа по невыровненному адресу (misaligned memory access exception).

Инструкция поддерживает следующие опции:

• Постинкремент регистра указателя источника на 4 байта.
• Постдекремент регистра указателя источника на 4 байта.
• Малое (6 бит) смещение регистра указателя источника. Смещение указывается прямо в команде беззнаковой константой, выровненной на слово (нацело делится на 4).
• Большое (17 бит) смещение регистра указателя источника. Смещение указывается прямо в команде беззнаковой константой, выровненной на слово (нацело делится на 4).
• Смещение относительно Frame Pointer (FP) размером 7 бит. Смещение указывается прямо в команде отрицательной константой, выровненной на слово (нацело делится на 4).

Форма инструкции, индексированная относительно FP, используется для доступа к локальным переменным в подпрограмме или функции. Положительные смещения оносительно FP (полезные для доступа к аргументам из вызванной функции) могут быть осущетвлены другими версиями этой инструкции. Preg включает Frame Pointer (FP, указатель фрейма) и Stack Pointer (SP, указатель стека).

Автоинкремент или автодекремент регистров указателей также не могут быть местом назначения инструкции загрузки. Например, инструкция sp=[sp++] будет недопустимой, потому что она описывает два конкурирующих значения для указателя стека - одно для данных, которые выбраны из памяти, а другое для постинкремента. Подобным образом P0=[P0++] и P1=[P1++], и т. д., также недопустимы. Такие инструкции приводят к исключению не определенной инструкции (undefined instruction exception).

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

p3 = [p2];
p5 = [p0++];
p2 = [sp--];
p3 = [p2 + 8];
p0 = [p2 + 0x4008];
p1 = [fp - 16];

Также см. инструкции Immediate, Pop, Pop Multiple.

Инструкция загружает значение в регистр данных с помощью косвенной (indirect) адресации. Общая форма:

D-регистр = [ косвенный_адрес ]

Синтаксис:

Dreg = [Preg];            // косвенная адресация (a)1

Dreg = [Preg++];          // косвенная адресация с постинкрементом (a)

Dreg = [Preg --];         // косвенная адресация с постдекрементом (a)

Dreg = [Preg + uimm6m4] ; // индексированная адресация с малым смещением (a)

Dreg = [Preg + uimm17m4]; // индексированная адресация с большим смещением (b)

Dreg = [Preg - uimm17m4]; // индексированная адресация с большим смещением (b)

Dreg = [Preg ++ Preg];    // косвенная адресация, с постинкрементом индекса2 (a)

Dreg = [FP - uimm7m4];    // индексированная адресация относительно FP (a)

Dreg = [Ireg];            // косвенная адресация (a)

Dreg = [Ireg ++];         // косвенная адресация с постинкрементом (a)

Dreg = [Ireg --];         // косвенная адресация с постдекрементом (a)

Dreg = [Ireg ++ Mreg];    // косвенная адресация с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

Ireg: I0, ..., I3.

Mreg: M0, ..., M3.

uimm6m4: 6-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 0 .. 60 байт.

uimm7m4: 7-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 4 .. 128 байт.

uimm17m4: 17-битное беззнаковое поле, которое должно делиться нацело на 4. Задает смещение адреса в диапазоне 0 .. 131068 байт (0x0000 0000 .. 0x0001 FFFC).

[Функциональное описание]

Инструкция загрузки регистра данных (Load Data Register) загружает 32-битный D-регистр из ячейки памяти. Адрес ячейки памяти может задаваться через P-регистр, I-регистр или указатель фрейма (Frame Pointer, FP). Это так называемая косвенная (indirect) адресация.

Косвенный адрес и смещение должно нацело делиться на 4, чтобы сохранить выравнивание адреса на 4. Ошибка в выравнивании приведет к исключению ошибки доступа по невыровненному адресу (misaligned memory access exception).

Инструкция поддерживает следующие опции:

• Постинкремент адреса источника на 4 байта, с сохранением выравнивания адреса на слово.
• Пост-декремент адреса источника на 4 байта, с сохранением выравнивания адреса на слово.
• Малое смещение адреса источника (6 бит), выровненное на слово (делится на 4), указанное в инструкции как беззнаковая константа.
• Большое смещение адреса источника (17 бит), выровненное на слово (делится на 4), указанное в инструкции как беззнаковая константа.
• Смещение относительно указателя фрейма (Frame Pointer, FP), где смещение задано как 7-битная, выровненная на слово (делится на 4), отрицательная константа.

Форма инструкции, индексированная относительно FP, используется для доступа к локальным переменным в подпрограмме или функции. Положительные смещения относительно FP (полезные для доступа к аргументам из вызванной функции) могут быть осуществлены другими версиями этой инструкции. Preg включает Frame Pointer (FP, указатель фрейма) и Stack Pointer (SP, указатель стека).

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = [p0];
r7 = [p1++];
r2 = [sp--];
r6 = [p2+12];
r0 = [p4 + 0x800C];
r1 = [p0 ++ p1];
r5 = [fp-12];
r2 = [i2];
r0 = [i0++];
r0 = [i0--];
// Перед косвенной адресацией с постинкрементом индекса
r7 = 0;
i3 = 0x4000; // К примеру, ячейка памяти содержит 15.
m0 = 4;
r7 = [i3 ++ m0];
// После чего ...
// r7 = 15 из ячейки памяти 0x4000
// i3 = i3 + m0 = 0x4004
// m0 все еще равно 4

См. также инструкцию Load Immediate.

Инструкция загружает младшую половинку регистра, заполняя биты старшей половинки нулями. Общая форма инструкции Load Half-Word - Zero-Extended:

D-регистр = W[ косвенный_адрес ](Z)

Синтаксис:

Dreg = W[Preg](Z);          // загрузка по косвенному адресу (a)1

Dreg = W[Preg++](Z);        // загрузка по косвенному адресу с постинкрементом (a)

Dreg = W[Preg--](Z);        // загрузка по косвенному адресу с постинкрементом (a)

Dreg = W[Preg+uimm5m2](Z);  // загрузка с индексированием по малому смещению (a)

Dreg = W[Preg+uimm16m2](Z); // загрузка с индексированием по большому смещению (b)

Dreg = W[Preg-uimm16m2](Z); // загрузка с индексированием по большому смещению (b)

Dreg = W[Preg++Preg](Z);    // загрузка с индексированием и постинкрементом2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

uimm5m2: 5-битное беззнаковое поле, которое должно делиться нацело на 2. Задает смещение адреса в диапазоне 0 .. 30 байт.

uimm16m2: 16-битное беззнаковое поле, которое должно делиться нацело на 2. Задает смещение адреса в диапазоне 0 .. 65534 байт (0x0000 .. 0xFFFC).

[Функциональное описание]

Инструкция загрузки полуслова данных с дополнением нулем (Load Half-Word - Zero-Extended) загружает 16 бит из ячейки памяти в младшую половину 32-битного регистра данных. Старшая половина загружаемого регистра при этом обнуляется. Ячейка памяти (2 байта), откуда будут браться данные для загрузки, указывается с помощью косвенной адресации через P-регистр.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Инструкция поддерживает следующие опции:

• Постинкремент адреса источника на 2 байта.
• Постдекремент адреса источника на 2 байта.
• Малое смещение адреса источника (5 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.
• Большое смещение адреса источника (17 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = w[p0](z);
r7 = w[p1++](z);
r2 = w[sp--](z);
r6 = w[p2+12](z);
r0 = w[p4+0x8004](z);
r1 = w[p0++p1](z);

См. также инструкции Load Half-Word Sign-Extended, Load Low Data Register Half, Load High Data Register Half, Load Data Register.

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

D-регистр = W [ косвенный_адрес ]

Синтаксис:

Dreg = W[Preg](X);          // косвенная адресация (a)1

Dreg = W[Preg++](X);        // косвенная адресация с постинкрементом (a)

Dreg = W[Preg--](X);        // косвенная адресация с постдекрементом (a)

Dreg = W[Preg+uimm5m2](X);  // индексированная адресация с малым смещением (a)

Dreg = W[Preg+uimm16m2](X); // индексированная адресация с большим смещением (b)

Dreg = W[Preg-uimm16m2](X); // индексированная адресация с большим смещенимем (b)

Dreg = W[Preg++Preg](X);    // косвенная адресация с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

uimm5m2: 5-битное беззнаковое поле, которое должно делиться нацело на 2. Задает смещение адреса в диапазоне 0 .. 30 байт.

uimm16m2: 16-битное беззнаковое поле, которое должно делиться нацело на 2. Задает смещение адреса в диапазоне 0 .. 65534 байт (0x0000 .. 0xFFFC).

[Функциональное описание]

Инструкция загрузки полуслова с дополнением знаком (Load Half-Word - Sign-Extended) загружает младшие 16 бит 32-битного D-регистра (регистра данных) из ячейки памяти. Регистром указателя на ячейку является P-регистр. Самый старший бит числа реплицируется в старшую половину 32-битного D-регистра.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Опционально к синтаксису инструкции может быть добавлен суффикс (X), чтобы ясно показать расширение со знаком (sign extended). Этот опциональный флаг никак не влияет на кодирование инструкции, её функционирование или производительность.

Примечание переводчика: я это понял так, что если (X) не указан, то инструкция будет все равно работать так же, как если бы (X) указывался. Т. е. по умолчанию работает дополнение со знаком, а чтобы работало дополнение нулями, нужно указывать суффикс (Z), см. описание предыдущей инструкции Load Half-Word - Zero-Extended.

Инструкция поддерживает следующие опции:

• Постинкремент адреса источника на 2 байта.
• Постдекремент адреса источника на 2 байта.
• Малое смещение адреса источника (5 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.
• Большое смещение адреса источника (17 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = w[p0](x);
r7 = w[p1++](x);
r2 = w[sp--](x);
r6 = w[p2+12](x);
r0 = w[p4+0x800E](x);
r1 = w[p0++p1](x);

См. также инструкции Load Half-Word - Zero Extended, Load Low Data Register Half, Load High Data Register Half.

Загружает старшую половинку регистра данных. Общая форма:

Dreg.H = W [ косвенный_адрес ]

Синтаксис:

Dreg.h = W[Ireg];       // косвенный адрес (DAG) (a)1

Dreg.h = W[Ireg++];     // косвенный адрес с постинкрементом (DAG) (a)

Dreg.h = W[Ireg--];     // косвенный адрес с постдекрементом (DAG) (a)

Dreg.h = W[Preg];       // косвенный адрес (a)

Dreg.h = W[Preg++Preg]; // косвенный адрес с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg.h: старшие 16 бит регистров R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

Ireg: I0, ..., I3.

[Функциональное описание]

Инструкция загрузки старшей половины регистра (Load High Data Register Half) загружает 16 бит из 2-байтной ячейки памяти, на которую указывает I-регистр или P-регистр, в старшую половину 32-битного регистра данных. Эта операция никак не влияет на остальную часть загружаемого регистра - младшие 16 бит.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Инструкция Load High Data Register Half поддерживает следующие опции:

• Постинкремент регистра источника Ireg на 2 байта для сохранения выравнивания на полуслово.
• Постдекремент регистра источника Ireg на 2 байта для сохранения выравнивания на полуслово.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

r3.h = w[i1];
r7.h = w[i3++];
r1.h = w[i0--];
r2.h = w[p4];
r5.h = w[p2++p0];

См. также инструкции Load Low Data Register Half, Load Half-Word - Zero-Extended, Load Half-Word - Sign-Extended.

Загружает младшую половинку регистра данных. Общая форма:

Dreg.L = W [ косвенный_адрес ]

Синтаксис:

Dreg.l = W[Ireg];       // косвенный адрес (DAG) (a)1

Dreg.l = W[Ireg++];     // косвенный адрес с постинкрементом (DAG) (a)

Dreg.l = W[Ireg--];     // косвенный адрес с постдекрементом (DAG) (a)

Dreg.l = W[Preg];       // косвенный адрес (a)

Dreg.l = W[Preg++Preg]; // косвенный адрес с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg.L: младшие 16 бит регистров R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

Ireg: I0, ..., I3.

[Функциональное описание]

Инструкция загрузки младшей половины регистра (Load Low Data Register Half) загружает 16 бит из 2-байтной ячейки памяти, на которую указывает I-регистр или P-регистр, в младшую половину 32-битного регистра данных. Эта операция никак не влияет на остальную часть загружаемого регистра - старшие 16 бит.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Инструкция Load Low Data Register Half поддерживает следующие опции:

• Постинкремент регистра источника Ireg на 2 байта для сохранения выравнивания на полуслово.
• Постдекремент регистра источника Ireg на 2 байта для сохранения выравнивания на полуслово.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

r3.L = w[i1];
r7.L = w[i3++];
r1.L = w[i0--];
r2.L = w[p4];
r5.L = w[p2++p0];

См. также инструкции Load High Data Register Half, Load Half-Word - Zero-Extended, Load Half-Word - Sign-Extended.

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

D-регистр = B [ косвенный_адрес ] (Z)

Синтаксис:

Dreg = B[Preg](Z);        // косвенный адрес (a)1

Dreg = B[Preg++](Z);      // косвенный адрес с постинкрементом (a)

Dreg = B[Preg--](Z);      // косвенный адрес с постдекрементом (a)

Dreg = B[Preg+uimm15](Z); // индексированный адрес со смещением (b)

Dreg = B[Preg-uimm15](Z); // индексированный адрес со смещением (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

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

Dreg: регистры R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

uimm15: 15-битное поле, содержащее число без знака, в диапазоне от 0 до 32767 байт (0x0000 .. 0x7FFF).

[Функциональное описание]

Инструкция загрузки байта (Load Byte - Zero-Extended) загружает 8 бит в младшие из 32 бит регистра данных из ячейки памяти, на которую указывает I-регистр или P-регистр. При этом биты 31..8 загружаемого D-регистра заполняются нулями.

Косвенный адрес и смещение не имеют никаких ограничений по выравниванию адреса памяти.

Инструкцией поддерживаются следующие опции:

• Постинкремент адреса источника на 1 байт.
• Постдекремент адреса источника на 1 байт.
• Смещение указателя адреса источника на 16-битную константу со знаком, указанную прямо в инструкции.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = b[p0](z);
r7 = b[p1++](z);
r2 = b[sp--](z);
r0 = b[p4+0xFFFF800F](z);

См. также инструкцию Load Byte - Sign-Extended.

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

D-регистр = B [ косвенный_адрес ]

Синтаксис:

Dreg = B[Preg](X);        // косвенный адрес (a)1

Dreg = B[Preg++](X);      // косвенный адрес с постинкрементом (a)

Dreg = B[Preg--](X);      // косвенный адрес с постдекрементом (a)

Dreg = B[Preg+uimm15](X); // индексированный адрес со смещением (b)

Dreg = B[Preg-uimm15](X); // индексированный адрес со смещением (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

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

Dreg: регистры R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

uimm15: 15-битное поле, содержащее число без знака, в диапазоне от 0 до 32767 байт (0x0000 .. 0x7FFF).

[Функциональное описание]

Инструкция загрузки байта с дополнением знаком числа (Load Byte - Sign-Extended) загружает 8 бит в младшие из 32 бит регистра данных из ячейки памяти, на которую указывает I-регистр или P-регистр. При этом биты 31 .. 8 загружаемого D-регистра заполняются знаковым битом загружаемого байта.

Косвенный адрес и смещение не имеют никаких ограничений по выравниванию адреса памяти.

Опционально суффикс (X) может быть указан (что не обязательно) для улучшения читаемости синтаксиса - чтобы было яснее видно, что используется дополнение знаком (sign extended). Указание или не указание этого суффикса никак не влияет на кодирование инструкции, её функционирование и быстродействие. Инструкцией поддерживаются следующие опции:

• Постинкремент адреса источника на 1 байт.
• Постдекремент адреса источника на 1 байт.
• Смещение указателя адреса источника на 16-битную константу со знаком, указанную прямо в инструкции.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = b[p0](x);
r7 = b[p1++](x);
r2 = b[sp--](x);
r0 = b[p4+0xFFFF800F](x); 

См. также инструкцию Load Byte - Zero-Extended.

Сохраняет регистр указателя в ячейку памяти. Общая форма:

[ косвенный_адрес ] = P-регистр

Синтаксис:

[Preg] = Preg;           // косвенная адресация (a)1
[Preg++] = Preg;         // косвенная адресация с постинкрементом (a)
[Preg--] = Preg;         // косвенная адресация с постдекрементом (a)
[Preg+uimm6m4] = Preg    // индексированная адресация с малым смещением (a)
[Preg+uimm17m4] = Preg;  // индексированная адресация с большим смещением (b)
[Preg-uimm17m4] = Preg;  // индексированная адресация с большим смещением (b)
[FP-uimm7m4] = Preg;     // индексированная адресация относительно FP (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

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

Preg: P0, ..., P5, SP, FP.

uimm6m4: 6-битное поле без знака, которое должно нацело делиться на 4, в диапазоне 0 .. 60 байт.

uimm7m4: 7-битное поле без знака, которое должно нацело делиться на 4, в диапазоне 4 .. 128 байт.

uimm17m4: 17-битное поле без знака, которое должно нацело делиться на 4, с диапазоном 0 .. 131068 байт (0x000 0000 .. 0x0001 FFFC).

[Функциональное описание]

Инструкция сохранения указателя (Store Pointer Register) сохраняет содержимое 32-битного P-регистра в 32-битную ячейку памяти. На адрес ячейки памяти также указывает P-регистр.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 4 и сохранялось выравнивание адреса на слово (4 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Поддерживаются следующие опции:

• Постинкремент указателя ячейки назначения на 4 байта.
• Постдекремент указателя ячейки назначения на 4 байта.
• Малое смещение (6 бит) указателя ячейки назначения, выровненное на слово (делится на 4), указанное как беззнаковая константа прямо в теле инструкции.
• Большое смещение (18 бит) указателя ячейки назначения, выровненное на слово (делится на 4), указанное как константа со знаком прямо в теле инструкции.
• Адресация с помощью указатель фрейма (Frame Pointer, FP) и смещения диапазоном в 7 бит, также выровненное на слово (делится на 4). Смещение указано как отрицательная константа прямо в теле инструкции.

Форма инструкции с индексированием относительно FP обычно используется для доступа к локальным переменным в подпрограммах или функциях. Положительные смещения относительно FP (что полезно для доступа к аргументам из вызванной функции) могут быть осуществлены другими версиями этой инструкции. Preg включает Frame Pointer (указатель фрейма, FP) и Stack Pointer (указатель стека, SP).

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

[p2] = p3;
[sp++] = p5;
[p0--] = p2;
[p2+8] = p3;
[p2+0x4444] = p0;
[fp-12] = p1;

См. также инструкции Push, Push Multiple.

Сохраняет регистр данных в ячейку памяти. Общая форма:

[ косвенный_адрес ] = D-регистр

Синтаксис с использованием регистров указателя:

[Preg] = Dreg;           // косвенная адресация (a)1
[Preg++] = Dreg;         // косвенная адресация с постинкрементом (a)
[Preg--] = Dreg;         // косвенная адресация с постдекрементом (a)
[Preg+uimm6m4] = Dreg    // индексированная адресация с малым смещением (a)
[Preg+uimm17m4] = Dreg;  // индексированная адресация с большим смещением (b)
[Preg-uimm17m4] = Dreg;  // индексированная адресация с большим смещением (b)
[Preg++Preg] = Dreg;     // косвенная адресация с постинкрементом индекса2 (a)
[FP-uimm7m4] = Dreg;     // индексированная адресация относительно FP (a)

Синтаксис с использованием регистров DAG:

[Ireg] = Dreg;           // косвенная адресация (a)
[Ireg++] = Dreg;         // косвенная адресация с постинкрементом (a)
[Ireg--] = Dreg;         // косвенная адресация с посдекрементом (a)
[Ireg++Mreg] = Dreg;     // косвенная адресация с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg: R0, ..., R7.
Preg: P0, ..., P5, SP, FP.
Ireg: I0, ..., I3.
Mreg: M0, ..., M3.
uimm6m4: 6-битное поле без знака, которое должно нацело делиться на 4, в диапазоне 0 .. 60 байт.
uimm7m4: 7-битное поле без знака, которое должно нацело делиться на 4, в диапазоне 4 .. 128 байт.
uimm17m4: 17-битное поле без знака, которое должно нацело делиться на 4, с диапазоном 0 .. 131068 байт (0x000 0000 .. 0x0001 FFFC).

[Функциональное описание]

Инструкция сохранения регистра данных (Store Data Register) сохраняет содержимое 32-битного D-регистра в 32-битную ячейку памяти. На адрес ячейки памяти указывает P-регистр, I-регистр или указатель фрейма (Frame Pointer, FP).

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 4 и сохранялось выравнивание адреса на слово (4 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Поддерживаются следующие опции:

• Постинкремент указателя ячейки назначения на 4 байта.
• Постдекремент указателя ячейки назначения на 4 байта.
• Малое смещение (6 бит) указателя ячейки назначения, выровненное на слово (делится на 4), указанное как беззнаковая константа прямо в теле инструкции.
• Большое смещение (18 бит) указателя ячейки назначения, выровненное на слово (делится на 4), указанное как константа со знаком прямо в теле инструкции.
• Адресация с помощью указатель фрейма (Frame Pointer, FP) и смещения диапазоном в 7 бит, также выровненное на слово (делится на 4). Смещение указано как отрицательная константа прямо в теле инструкции.

Форма инструкции с индексированием относительно FP обычно используется для доступа к локальным переменным в подпрограммах или функциях. Положительные смещения относительно FP (что полезно для доступа к аргументам из вызванной функции) могут быть осуществлены другими версиями этой инструкции. Preg включает Frame Pointer (указатель фрейма, FP) и Stack Pointer (указатель стека, SP).

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

[p0] = r3;
[p1++] = r7;
[sp--] = r2;
[p2+12] = r6;
[p4-0x1004] = r0;
[p0++p1] = r1;
[fp-28] = r5;
[i2] = r2;
[i0++] = r0;
[i0--] = r0;
[i3++m0] = r7;

См. также инструкцию Load Immediate.

Инструкция сохраняет в памяти старшую половину регистра данных. Общая форма:

W [ косвенный_адрес ] = Dreg.H

Синтаксис:

W [Ireg] = Dreg.H;       // косвенная адресация (DAG) (a)1

W [Ireg++] = Dreg.H;     // косвенная адресация с постинкрементом (DAG) (a)

W [Ireg--] = Dreg.H ;    // косвенная адресация с постдекрементом (DAG) (a)

W [Preg] = Dreg.H;       // косвенная адресация (a)

W [Preg++Preg] = Dreg.H; // косвенная адресация с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg.H: старшие 16 бит регистров R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

Ireg: I0, ..., I3.

[Функциональное описание]

Инструкция сохранения старшей половины регистра данных (Store High Data Register Half) записывает в 2-байтную ячейку памяти старшие 16 бит 32-битного регистра данных. В качестве адреса ячейки памяти используется регистр указателя P-регистр или I-регистр.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Поддерживаются следующие опции:

• Постинкремент указателя ячейки назначения I-регистр на 2 байта.
• Постдекремент указателя ячейки назначения I-регистр на 2 байта.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

w[i1] = r3.h;
w[i3++] = r7.h;
w[i0--] = r1.h;
w[p4] = r2.h;
w[p2++p0] = r5.h;

См. также инструкцию Store Low Data Register Half.

Инструкция сохраняет в памяти младшую половину регистра данных. Общая форма:

W [ косвенный_адрес ] = Dreg.L

W [ косвенный_адрес ] = Dreg

Синтаксис:

W [Ireg] = Dreg.L;        // косвенная адресация (DAG) (a)1

W [Ireg++] = Dreg.L;      // косвенная адресация с постинкрементом (DAG) (a)

W [Ireg--] = Dreg.L;      // косвенная адресация с постдекрементом (DAG) (a)

W [Preg] = Dreg.L;        // косвенная адресация (a)

W [Preg] = Dreg;          // косвенная адресация (a)

W [Preg++] = Dreg;        // косвенная адресация с постинкрементом (a)

W [Preg--] = Dreg;        // косвенная адресация с постдекрементом (a)

W [Preg+uimm5m2] = Dreg;  // индексированная адресация с малым смещением (a)

W [Preg+uimm16m2] = Dreg; // индексированная адресация с большим смещением (b)

W [Preg-uimm16m2] = Dreg; // индексированная адресация с большим смещением (b)

W [Preg++Preg] = Dreg.L;  // косвенная адресация с постинкрементом индекса2 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: подробнее см. раздел "Косвенная и индексная адресация с постинкрементом индекса".

[Терминология синтаксиса]

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

Dreg.L: младшие 16 бит регистров R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

Ireg: I0, ..., I3.

Dreg: R0, ..., R7.

uimm5m2: 5-битное беззнаковое поле, которое должно содержать смещение, нацело делящееся на 2, в диапазоне 0 .. 30 байт.

uimm16m2: 16-битное беззнаковое поле, которое должно содержать смещение, нацело делящееся на 2, в диапазоне 0 .. 65534 байт (0x0000 .. 0xFFFE).

[Функциональное описание]

Инструкция сохранения младшей половины регистра данных (Store Low Data Register Half) записывает в 2-байтную ячейку памяти младшие 16 бит 32-битного регистра данных. В качестве адреса ячейки памяти используется регистр указателя P-регистр или I-регистр.

Косвенный адрес и смещение должны удовлетворять условию четности, чтобы адрес нацело делился на 2 и сохранялось выравнивание адреса на полуслово (2 байта). Ошибка в выравнивании приведет к исключению по ошибке доступа к памяти по невыровненному адресу (misaligned memory access exception).

Поддерживаются следующие опции:

• Постинкремент указателя ячейки назначения на 2 байта.
• Постдекремент указателя ячейки назначения на 2 байта.
• Малое смещение адреса назначения (5 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.
• Большое смещение адреса назначения (17 бит), выровненное на полуслово (делится на 2), указанное в инструкции как беззнаковая константа.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 16-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 2 раза быстрее, потому что за одну команду может выбрать из памяти сразу 2 полуслова. Команда, загружающая данные половинками, использует только половину от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

w[i1] = r3.l;
w[p0] = r3;
w[i3++] = r7.l;
w[i0--] = r1.l;
w[p4] = r2.l;
w[p1++] = r7;
w[sp--] = r2;
w[p2+12] = r6;
w[p4-0x200C] = r0;
w[p2++p0] = r5.l;

См. также инструкции Store High Data Register Half, Store Data Register.

Инструкция сохраняет в памяти младшую половину регистра данных. Общая форма:

B [ косвенный_адрес ] = D-регистр

Синтаксис:

B [Preg] = Dreg;          // косвенная адресация (a)1

B [Preg++] = Dreg;        // косвенная адресация с постинкрементом (a)

B [Preg--] = Dreg;        // косвенная адресация с постдекрементом (a)

B [Preg+uimm15] = Dreg;   // индексированная адресация со смещением (b)

B [Preg-uimm15] = Dreg;   // индексированная адресация со смещением (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

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

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

uimm15: 15-битное беззнаковое поле, которое должно содержать смещение в диапазоне 0 .. 32767 байт (0x0000 .. 0x7FFF).

[Функциональное описание]

Инструкция сохранения байта (Store Byte) записывает в 1-байтную ячейку памяти младшие 8 бит 32-битного регистра данных. В качестве адреса ячейки памяти используется регистр указателя P-регистр.

Косвенный адрес и смещение не имеют никаких ограничений по выравниванию адреса памяти.

Поддерживаются следующие опции:

• Постинкремент указателя ячейки назначения на 1 байт.
• Постдекремент указателя ячейки назначения на 1 байт.
• Смещение адреса назначения (16 бит), указанное в инструкции как константа со знаком.

Имейте в виду, что когда выполняется быстродействующий алгоритм DSP, то для последовательного чтения лежащих в памяти 8-битных значений предпочтительнее использовать инструкцию Load Data Register вместо чтения половинок регистров. Load Data Register работает в 4 раза быстрее, потому что за одну команду может выбрать из памяти сразу 4 байта. Команда, сохраняющая данные побайтно, использует только 1/8 от доступной полосы пропускания внутренней 32-битной шины, что может снизить скорость обмена данными между процессором и памятью.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

16-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

32-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

b[p0] = r3;
b[p1++] = r7;
b[sp--] = r2;
b[p4+0x100F] = r0;
b[p4-0x53F] = r0;

[Инструкции Move]

В этом разделе обсуждаются инструкции перемещения (move) данных регистров. С этими инструкциями пользователь может пользоваться такими возможностями, как перемещение регистров (или их половинок), полуслов с дополнением нулем или знаком, перемещение байт, выполнение перемещения по условию.

Примечание переводчика: я не понял, почему группа этих регистров названа Move (перемещение). Правильнее было бы называть её Copy (копирование).

Общая форма инструкции:

регистр_назначения = регистр_источник

Синтаксис:

любой_регистр = любой_регистр       // (a)1

Предупреждение: допустимы не все комбинации регистров. Подробнее см. функциональное описание инструкции.

A0 = A1;       // 40-разрядный Accumulator (b)

A1 = A0;       // 40-разрядный Accumulator (b)

A0 = Dreg;     // 32 разряда D-регистра в 32 разряда A0.W (b)

A1 = Dreg;     // 32 разряда D-регистра в 32 разряда A1.W (b)

sysreg = Preg; // 32 разрядный P-регистр в sysreg (a)

Перемещением между аккумулятором и D-регистром:

Dreg_even = A0 ; // перемещение A0 в четный Dreg (b)

Dreg_odd = A1;   // перемещение A1 в нечетный Dreg (b)

Dreg_even = A0, Dreg_odd = A1 (opt_mode); // перемещение обоих аккумуляторов в
                                          // регистровую пару (b)

Dreg_odd = A1, Dreg_even = A0 (opt_mode); // перемещение обоих аккумуляторов в
                                          // регистровую пару (b)

Dreg_even = A0.X; // перемещение значения 8 бит A0.X, расширенное знаком,
                  // в 32 бита D
reg_even (b)

Dreg_odd = A1.X;  // перемещение значения 8-bit A1.X, расширенное знаком,
                  // в 32 бита 
Dreg_odd (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

любой_регистр: R0, ..., R7, P0, ..., P5, SP, FP, I0, ..., I3, M0, ..., M3, B0, ..., B3, L0, ..., L3, A0.X, A0.W, A1.X, A1.W, ASTAT, RETS, RETI, RETX, RETN, RETE, LC0 и LC1, LT0 и LT1, LB0 и LB1, EMUDAT, USP, SEQSTAT и SYSCFG.

Dreg: R0, ..., R7.

Preg: P0, ..., P5, SP, FP.

sysreg: ASTAT, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, RETS, LC0 и LC1, LT0 и LT1, LB0 и LB1, и EMUDAT.

Dreg_even: R0, R2, R4, R6 (четный регистр данных).

Dreg_odd: R1, R3, R5, R7 (нечетный регистр данных).

Примечание: когда 2 перемещения комбинируются в одной и той же инструкции, операнды Dreg_even и Dreg_odd должны быть членами одной и той же регистровой пары, например из набора R1:0, R3:2, R5:4, R7:6.

opt_mode: опциональный режим (ISS2).

[Функциональное описание]

Инструкция перемещения регистра (Move Register) копирует содержимое регистра-источника в регистр назначения. Операция никак не влияет на содержимое регистра-источника.

Не все комбинации регистров разрешены. Запрещаются перемещения между следующими группами регистров:

1. sysreg = sysreg,

2. sysreg = Ireg, Mreg, Breg или Lreg,

3. Ireg, Mreg, Breg или Lreg = sysreg,

4. Preg или USP = sysreg,

где “sysreg” включает ASTAT, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, RETS, LC0 и LC1, LT0 и LT1, LB0 и LB1, и EMUDAT.

Разрешены перемещения из Preg или USP в sysreg.

Регистры расширения аккумулятора A0.X и A1.X определены только для 8 младших бит A0.X[7:0] и A1.X[7:0]. Любые перемещения в старшие биты (или из старших бит) A0.X[31:8] или A1.X[31:8] не определены.

Все перемещения из меньших по размеру регистров в большие по размеру регистры расширяются знаком (sign extended).

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

• По умолчанию: 32-битная распаковка из аккумулятора с 32-битным насыщением (saturation).
• (ISS2): 32-битная распаковка с масштабированием (scaling) и 32-битным насыщением (saturation). Масштабирует содержимое аккумулятора (умножением на 2 путем сдвига влево на 1 бит).

Если Вы хотите сохранить неизменное содержимое аккумулятора, используйте простую инструкцию Move для копирования A.x или A.w в регистр или из регистра. Подробнее про насыщение см. раздел "Терминология", объяснение термина Saturation.

[Флаги]

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

Версии перемещения аккумулятора в D-регистр для этой инструкции влияют на следующие флаги.

• V установится, если результат, записанный в D-регистр насытит 32 бита; очистится, если не было насыщения. В случае 2 одновременных операций V представляет логическое ИЛИ от этих 2 операций.
• VS установится, если V установлен; иначе VS не изменит свое значение.
• AZ установится, если результат 0, иначе очистится. В случае 2 одновременных операций AZ представляет результат логического ИЛИ от этих 2 операций.
• AN установится, если результат отрицателен, иначе очистится. В случае 2 одновременных операций AN представляет результат логического ИЛИ от этих 2 операций.

Все другие флаги не изменятся.

[Требуемый режим]

В большинстве случаев это режим пользователя (User mode) и режим супервизора (Supervisor mode).

Случаи явного доступа к USP, SEQSTAT, SYSCFG, RETI, RETX, RETN и RETE требуют режима супервизора. Если к любому из этих регистров происходит явное обращение из режима пользователя, то возникает exception (исключение) типа Illegal Use of Protected Resource (недопустимое использование защищенного ресурса).

[Параллельное выполнение]

32-битные версии этой инструкции могут быть выданы параллельно с некоторыми другими 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

16-битные версии этой инструкции не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r3 = r0;
r7 = p2;
r2 = a0.w;
r2.l = a0.x;
r0 = a0.x;
a0 = a1;
a1 = a0;
a0 = r7;          // перемещение R7 в 32 бита A0.W
a1 = r3;          // перемещение R3 в 32 бита A1.W
retn = p0;        // должно быть выполнено в режиме Supervisor
r2 = a0;          // 32 битное перемещение с насыщением
r7 = a1;          // 32 битное перемещение с насыщением
r0 = a0 (iss2);   // 32 битное перемещение с масштабированием,
                  // отбрасыванием части результата и насыщением

См. также: инструкцию Load Immediate для инициализации регистров; Move Half-Register для явного перемещения значений в регистры A0.X и A1.X; Zero Overhead Loop Setup для явного доступа к регистрам LC0, LT0, LB0, LC1, LT1 и LB1; Call, Raise и Return для неявного доступа к регистрам RETI, RETN и RETS; Force Exception и Force Emulation для неявного доступа к регистрам RETX и RETE.

Команда загружает регистр в зависимости от состояния бита CC. Общая форма:

IF CC регистр_назначения = регистр_источник

IF !CC регистр_назначения = регистр_источник

Синтаксис:

IF CC DPreg = DPreg;   // перемещение данных, если CC = 1 (a)1

IF !CC DPreg = DPreg;  // перемещение данных, если CC = 0 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

DPreg: R0, ..., R7, P0, ..., P5, SP, FP.

[Функциональное описание]

Инструкция перемещения данных по условию (Move Conditional) переместит содержимое регистра-источника в регистр назначения в зависимости от значения бита CC.

Для инструкции IF CC DPreg = DPreg данные будут скопированы только тогда, когда CC = 1.

Для инструкции IF !CC DPreg = DPreg данные будут скопированы только тогда, когда CC = 0.

В качестве регистра источника и регистра назначения могут выступать любые D-регистры или P-регистры.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

Инструкция Move Conditional не может использоваться параллельно с другими инструкциями.

[Примеры]

// перемещения, если CC=1:
if cc r3 = r0;
if cc r2 = p4;
if cc p0 = r7;
if cc p2 = p5;
// перемещения, если CC=0:
if !cc r3 = r0;
if !cc r2 = p4;
if !cc p0 = r7;
if !cc p2 = p5;

См. также инструкции Compare, Move CC, Negate CC, Conditional Jump.

Инструкция перемещает половину слова, дополняя остальные биты регистра нулями. Общая форма:

регистр_назначения = регистр_источник (Z)

Синтаксис:

Dreg = Dreg.L (Z);       // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: R0, ..., R7.

Dreg.L: R0.L, ..., R7.L.

[Функциональное описание]

Инструкция перемещения половины слова с дополнением нулем (Move Half-Word - Zero-Extended) преобразует число без знака размером в половину слова (16 бит) в число без знака размером в слово (32 бита).

Инструкция копирует младшие 16 бит из 32-битного регистра источника в младшую половину 32-битного регистра. Старшая половина регистра назначения будет заполнена нулями. Эта операция работает только с D-регистрами. Расширение нулями отрицательного 16-битного числа во многих случаях повредит знак числа и амплитуду сигнала (очевидное исключение: у выборки 0x8000 та же самая амплитуда, как бы ни рассматривалось это число - как со знаком или как без знака).

[Флаги]

Инструкция Move Half-Word - Zero-Extended окажет влияние на следующие флаги:

• AZ установится, если результат операции 0, иначе очистится.
• AN очистится.
• AC0 очистится.
• V очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

// Предположим, что r0.l = 0xFFFF.
// Эта операция будет эквивалентна двум операциям r4.l = r0.l и r4.h = 0:
r4 = r0.l(z);
// После этой инструкции r4 = 0x0000FFFF.

См. также инструкции Move Half-Word - Sign-Extended, Move Register Half.

Инструкция перемещает половину слова, дополняя остальные биты знаком числа. Общая форма:

регистр_назначения = регистр_источник

Синтаксис:

Dreg = Dreg.L (X);       // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Инструкцию можно использовать также и без суффикса (X). Этот суффикс просто добавляет коду удобства читаемости. Это никак не влияет ни на кодирование инструкции, ни на функционирование, ни на быстродействие.

[Терминология синтаксиса]

Dreg: R0, ..., R7.

Dreg.L: R0.L, ..., R7.L.

[Функциональное описание]

Инструкция перемещения половины слова с дополнением знаком (Move Half-Word - Sign-Extended) преобразует число со знаком размером в половину слова (16 бит) в число со знаком размером в слово (32 бита). Инструкция копирует младшие 16 бит из 32-битного регистра источника в младшую половину 32-битного регистра, расширяя при этом старшую половина регистра назначения знаком числа регистра источника. Эта операция работает только с D-регистрами.

[Флаги]

Инструкция Move Half-Word - Zero-Extended окажет влияние на следующие флаги:

• AZ установится, если результат операции 0, иначе очистится.
• AN установится, если результат операции отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

r4 = r0.l(x);
r4 = r0.l;

См. также инструкции Move Half-Word - Zero-Extended, Move Register Half.

Инструкция позволяет обмениваться половинками регистра. Основная форма:

половинка_регистра_назначения = половинка_регистра_источника

половинка_регистра_назначения = accumulator (opt_mode)

Синтаксис без режима опций:

A0.X = Dreg_lo; // копирует младшие 8 бит из Dreg в A0.X2 (b)1

A1.X = Dreg_lo; // копирует младшие 8 бит из Dreg в A1.X (b)

Dreg.L = A0.X;  // копирует 8 бит A0.X, расширенные знаком, в младшие
                // 16 бит регистра Dreg (b)

Dreg.L = A1.X;  // копирует 8 бит A1.X, расширенные знаком, в младшие
                // 16 бит регистра Dreg (b)

A0.L = Dreg.L;  // копирует младшие 16 бит Dreg в младшие
                // 16 бит регистра аккумулятора A0.W (b)

A1.L = Dreg.L;  // копирует младшие 16 бит Dreg в младшие
                // 16 бит регистра аккумулятора A1.W (b)

A0.H = Dreg.H;  // копирует старшие 16 бит Dreg в старшие
                // 16 бит регистра аккумулятора A0.W (b)

A1.H = Dreg.H;  // копирует старшие 16 бит Dreg в старшие
                // 16 бит регистра аккумулятора A1.W (b)

Синтаксис с опциями для копирования половинки аккумулятора в половинку D-регистра:

Dreg.L = A0 (opt_mode); // копирует A0 в младшую половину Dreg (b)

Dreg.H = A1 (opt_mode); // копирует A1 в старшую половину Dreg (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

Примечание 2: регистры расширения аккумулятора (Accumulator Extension registers) A0.X и A1.X определены только для 8 младших бит A0.X[7:0] и A1.X[7:0]. Эта инструкция отбрасывает старший байт Dreg.L перед копированием значения в Accumulator Extension register (A0.X или A1.X).

[Терминология синтаксиса]

Dreg.L: R0.L, ..., R7.L (младшие 16 бит регистра R0, ..., R7).

Dreg.H: R0.H, ..., R7.H (старшие 16 бит регистра R0, ..., R7).

A0.L: младшие 16 бит аккумулятора A0.W.

A1.L: младшие 16 бит аккумулятора A1.W.

A0.H: старшие 16 бит аккумулятора A0.W.

A1.H: старшие 16 бит аккумулятора A1.W.

opt_mode: опциональные суффиксы (IS), (IU), (T), (S2RND), (ISS2) или (IH).

[Функциональное описание]

Инструкция Move Register Half копирует 16 из регистра-источника в половину 32-битного регистра назначения. Инструкция никак не влияет на не используемую часть регистра назначения. Инструкция поддерживает в качестве операндов только D-регистры и аккумулятор.

Одна версия синтаксиса просто копирует 16 бит (насыщение по 16 битам) аккумулятора в данные половинки регистра. Этот синтаксис поддерживает отбрасывание части значения (truncation) и округление вне простой инструкции Move Register Half.

Частичная версия этой инструкции (опция по умолчанию) переносит результат аккумулятора в регистр назначения соответствии с диаграммой, показанной ниже на рисунке:

Blackfin Move Register Half default

Целочисленная версия этой инструкции (с опцией IS) переносит результат аккумулятора в регистр назначения соответствии с диаграммой, показанной ниже на рисунке:

Blackfin Move Register Half IS

На некоторые версии этой инструкции влияет бит RND_MOD в регистре ASTAT, когда результат копируется в регистр назначения. Бит RND_MOD определяет используемый вариант округления - смещенный (biased rounding) или не смещенный (unbiased rounding). Бит RND_MOD управляет всеми версиями этой инструкции, кроме опций (IS) и (ISS2).

Подробнее про поведение округления см. секцию “Rounding, Truncating”.

У версии инструкции, которая копирует данные из аккумулятора в половинку D-регистра, есть следующие опции:

Таблица 4-2. Опции инструкции Accumulator to Half D-Register Move.

Опция Форматирование при копировании аккумулятора
по умолчанию Старшая половинка распаковывается из аккумулятора с 16-битным насыщением (saturation) и округлением (rounding). Округление управляется битом RND_MOD регистра ASTAT.
(IS) Младшая половинка распаковывается из аккумулятора с 16-битным насыщением (saturation). Округление не применяется.
(IU) Младшая половинка распаковывается из аккумулятора с 16-битным насыщением (saturation) и округлением (rounding). Округление управляется битом RND_MOD регистра ASTAT.
(T) Старшая половинка данных распаковывается из аккумулятора. Происходит отбрасывание младшей половины слова (truncation) с округлением (rounding). Округление управляется битом RND_MOD регистра ASTAT.
(S2RND) Старшая половинка данных распаковывается с масштабированием (scaling), округлением (rounding) и 16-битным насыщением (saturation). Округление управляется битом RND_MOD регистра ASTAT. Операция масштабирует содержимое аккумулятора (умножением на 2 путем одиночного сдвига влево) и округляет верхние 16 бит перед отбрасыванием младших 16 бит.
(ISS2) Младшая половинка данных распаковывается с масштабированием (scaling) и 16-битным насыщением (saturation). Округление не применяется. Операция масштабирует содержимое аккумулятора (умножением на 2 путем одиночного сдвига влево) и округляет верхние 16 бит перед копированием младших 16 бит.
(IH) Старшая половинка данных распаковывается с 32-битным насыщением (saturation), после чего происходит округление (rounding) на старших 16 битах. Округление управляется битом RND_MOD регистра ASTAT.

Для отбрасывания части данных (truncate) результата операция уничтожает младшие биты, которые не умещаются в регистре назначения.

Когда это необходимо, после округления применяется насыщение.

Если Вы хотите сохранить нетронутым содержимое Accumulator, используйте простую версию инструкции Move для копирования A.x или A.w в нужный регистр или из нужного регистра.

Подробнее про насыщение см. секцию "Saturation (насыщение)".

[Флаги]

Версии инструкции Accumulator to Half D-register Move влияют на следующие флаги:

• V установится, если результат, записанный в половинку D-регистра, претерпел насыщение по 16 битам, или очистится, если не было насыщения.
• VS установится, если установился V, иначе VS останется в старом состоянии.
• AZ установится, если результат операции 0, иначе очистится.
• AN установится, если результат операции отрицательный, иначе очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

32-битные версии этой инструкции могут быть выполнены параллельно с некоторыми другими 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

a0.x = r1.l;
a1.x = r4.l;
r7.l = a0.x;
r0.l = a1.x;
a0.l = r2.l;
a1.l = r1.l;
a0.l = r5.l;
a1.l = r3.l;
a0.h = r7.h;
a1.h = r0.h;
r7.l = a0;        // Копируется A0.H в R7.L с насыщением.
r2.h = a1;        // Копируется A0.H в R2.H с насыщением.
r0.h = a1(is);    // Копируется A1.L в R0.H с насыщением.
r5.l = a0 (t);    // Копируется A0.H в R5.L; отбрасывается A0.L;
                  // насыщение не применяется.
r1.l = a0(s2rnd); // Копируется A0.H в R1.L с масштабированием,
                  // округлением и насыщением.
r2.h = a1 iss2);  // Копируется A1.L в R2.H с масштабированием
                  //  и насыщением.
r6.l = a0(ih);    // Копируется A0.H в R6.L с насыщением.
                  // после чего делается округление.

См. также инструкции Move Half-Word - Zero-Extended, Move Half-Word - Sign-Extended.

Инструкция копирует байт с дополнением не используемых бит регистра нулями. Общая форма:

регистр_назначения = байт_регистра_источника (Z)

Синтаксис:

Dreg = Dreg_byte (Z);       // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_byte: R[7:0].B, младший байт любого D-регистра.

[Функциональное описание]

Инструкция Move Byte - Zero-Extended преобразует байт без знака в слово без знака (число 32 бита). Инструкция копирует младшие младшие 8 бит из регистра источника в младшие 8 бит 32-битного регистра назначения. При этом остальные биты регистра назначения заполняются нулями. Эта инструкция может работать только с D-регистрами.

[Флаги]

Инструкция Move Half-Word - Zero-Extended окажет влияние на следующие флаги:

• AZ установится, если результат операции 0, иначе очистится.
• AN очистится.
• AC0 очистится.
• V очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

r7 = r2.b(z);

См. также инструкции Move Register Half для явного доступа к расширениям аккумулятора (Accumulator Extension registers) A0.X и A1.X. Также см. инструкцию Move Byte - Sign-Extended.

Инструкция копирует байт с дополнением не используемых знаком числа. Общая форма:

регистр_назначения = байт_регистра_источника

Синтаксис:

Dreg = Dreg_byte (X);       // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

Инструкцию можно использовать также и без суффикса (X). Этот суффикс просто добавляет коду удобства читаемости. Это никак не влияет ни на кодирование инструкции, ни на функционирование, ни на быстродействие.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_byte: R[7:0].B, младший байт любого D-регистра.

[Функциональное описание]

Инструкция Move Byte - Zero-Extended преобразует байт со знаком в слово со знаком (число 32 бита). Инструкция копирует младшие младшие 8 бит из регистра источника в младшие 8 бит 32-битного регистра назначения. При этом остальные биты регистра назначения заполняются значением бита знака байта источника. Эта инструкция может работать только с D-регистрами.

[Флаги]

Инструкция Move Half-Word - Zero-Extended окажет влияние на следующие флаги:

• AZ установится, если результат операции 0, иначе очистится.
• AN установится, если результат операции отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

r7 = r2.b;
r7 = r2.b(x);

См. также инструкцию Move Byte - Zero-Extended.

[Инструкции управления стеком]

В этом разделе обсуждаются инструкции для манипуляции со стеком (Push, Push Multiple, Pop, Pop Multiple, Linkage). Пользователи могут использовать их для сохранения в стеке содержимого одного или нескольких регистров, или для управлением областью памяти стека и указателя фрейма (Frame Pointer, FP).

Команда проталкивает в стек содержимое регистра. Общая форма:

[--SP] = регистр

Синтаксис:

[--SP] = любой_регистр;    // для указателя стека SP используется преддекремент (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

любой_регистр: R0, ..., R7, P0, ..., P5, FP, I0, ..., I3, M0, ..., M3, B0, ..., B3, L0, ..., L3, A0.X, A0.W, A1.X, A1.W, ASTAT, RETS, RETI, RETX, RETN, RETE, LC0 и LC1, LT0 и LT1, LB0 и LB1, EMUDAT, USP, SEQSTAT и SYSCFG.

[Функциональное описание]

Инструкция Push сохраняет значение указанного регистра в стеке. Инструкция перед сохранением делает предварительный декремент указателя стека (Stack Pointer, SP), чтобы он указывал на следующее свободное место в стеке, куда можно поместить текущий регистр. Только инструкции Push и Push Multiple выполняют такие предварительные модификации указателя стека.

Таким образом, стек растет от старших адресов памяти к младшим (это традиционная организация стека). Соответственно декремент SP (уменьшение адреса) используется для проталкивания в стек (Push, сохранение содержимого регистра в стеке), и инкремент SP (увеличение SP) используется для извлечения из стека (Pop, содержимое регистра восстанавливается из стека). SP всегда указывает на последнюю занятую ячейку в стеке. Так что эффективный адрес для проталкивания в стек будет равен SP-4.

На следующей картинке показано, как будет выглядеть стек после нескольких операций проталкивания в стек.

Blackfin SP Push

Для использования этой инструкции Stack Pointer должен быть всегда выровнен на 32 бита (адрес в SP должен нацело делиться на 4). Если произойдет невыровненный доступ к памяти, то будет сгенерировано исключение (exception), и выполнение инструкции будет прервано.

Push/pop на RETS не влияет на систему прерываний.

Push/pop на RETI влияет на систему прерываний. Проталкивание в стек RETI (Push) разрешает работу системы прерываний, в то время как выборка из стека RETI (Pop) запрещает систему прерываний.

Проталкивание в стек самого SP бессмысленно, потому что SP нельзя извлечь из стека. Использование Stack Pointer в качестве операнда для инструкции Pop (как если бы была указана фиктивная инструкция SP=[SP++]) приведет к непредсказуемому поведению (подробнее про имена регистров см. раздел "Терминология").

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

В большинстве случаев это режим пользователя (User mode) и режим супервизора (Supervisor mode).

Явный доступ к регистрам USP, SEQSTAT, SYSCFG, RETI, RETX, RETN и RETE требует режим супервизора. Если попробовать явно обратиться к этим регистрам из режима пользователя, то возникнет исключение защиты нарушения доступа (protection violation exception).

[Параллельное выполнение]

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

[Примеры]

[--sp] = r0;
[--sp] = r1;
[--sp] = p0;
[--sp] = i0;

См. также инструкции Push Multiple, Pop.

Инструкция проталкивает в стек сразу несколько регистров. Общая форма:

[--SP] = (диапазон_исходных_регистров)

Синтаксис:

[--SP] = (R7:Dreglim, P5:Preglim);  // регистры Dreg и индексированные Preg (a)1

[--SP] = (R7:Dreglim);              // только регистры Dreg (a)

[--SP] = (P5:Preglim);              // только индексированные регистры Preg (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreglim: любое число в диапазоне от 7 до 0.

Preglim: любое число в диапазоне от 5 до 0.

[Функциональное описание]

Инструкция Push Multiple сохраняет в стеке содержимое нескольких регистров данных (Dreg) и/или регистров указателя (Preg). Диапазон сохраняемых регистров всегда включает самый большой индекс регистра (R7 и/или P5) плюс любой нижележащий индекс регистра, который далее указывает пользователь, который включает R0 и/или P0. Только инструкции Push и Push Multiple обладают функциями предварительной модификации указателя стека.

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

Перед доступом к следующему доступному месту в стеке инструкция делает преддекремент указателя стека (Stack Pointer, SP).

Стек растет вниз от старших адресов памяти к младшим, так что операция декремента SP используется для проталкивания в стек (pushing), и соответственно операция инкремента SP используется для извлечения значений из стека (popping). Указатель стека всегда указывает на последнее занятое место в стеке. Таким образом, эффективный адрес для следующего проталкивания в стек будет равен SP-4.

На следующей картинке показано, как будет выглядеть в стек, когда происходит множественное проталкивание в стек (push multiple).

Blackfin SP Push Multiple

Из-за того, что регистры с самым маленьким индексом будут сохранены в стеке первыми, то желательно, чтобы в реалтайм-системе для компилятора были определены scratch-регистры с самыми маленькими индексами. Например, для простейшего соглашения о вызовах должны в качестве параметров использоваться регистры данных R0, и P0 должен использоваться как регистр для возврата значения.

Хотя время выполнения этой инструкции варьируется в зависимости от количества сохраняемых регистров, применение её уменьшает размер кода.

Инструкцию Push Multiple нельзя прервать во время её выполнения. Обработка прерывания, выставленного после первой операции записи в стек, откладывается до завершения всех операций сохранения Push Multiple. Однако исключения, которые возникнут во время выполнения этой инструкции, приведут к корректному её завершению. Например, если операция load/store может нарушить защиту доступа при выполнении Push Multiple. В этом случае SP сбросится к своему значению, которое было перед выполнением этой инструкции. Такое поведение гарантирует, что инструкция может быть перезапущена после обработки исключения. Обратите внимание, что когда операция Push Multiple была оборвана из-за исключения, состояние памяти изменится операциями сохранения, которые были уже выполнены до момента возникновения исключения.

Для использования инструкции Push Multiple (как, впрочем, и для инструкции Push) указатель стека (Stack Pointer, SP) должен быть всегда выровнен на 32 бита (делиться нацело на 4). Если произойдет невыровненный доступ к памяти, то возникнет исключение, и работа инструкции будет прервана, как это было только что описано.

Операндами этой инструкции могут быть только регистры указателей P0, ..., P5, но никак не регистры SP и FP. Все регистры данных R0, ..., R7 могут быть операндами для этой инструкции.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

[--sp] = (r7:5, p5:0); // D-регистры R[4:0] опционально исключены
[--sp] = (r7:2);       // исключены R[1:0]
[--sp] = (p5:4);       // исключены P[3:0]

См. также инструкции Push, Pop, Pop Multiple.

Инструкция восстанавливает из стека содержимое указанного регистра. Общая форма:

регистр_назначения = [SP++]

Синтаксис:

любой_регистр = [SP++];     // используется постинкремент SP (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

любой_регистр: R0, ..., R7, P0, ..., P5, FP, I0, ..., I3, M0, ..., M3, B0, ..., B3, L0, ..., L3, A0.X, A0.W, A1.X, A1.W, ASTAT, RETS, RETI, RETX, RETN, RETE, LC0 и LC1, LT0 и LT1, LB0 и LB1, EMUDAT, USP, SEQSTAT и SYSCFG.

[Функциональное описание]

Инструкция Pop загружает в указанный регистр содержимое из стека по индексу из текущего состояния указателя стека (Stack Pointer, SP). Инструкция делает постинкремент SP, так что SP после операции будет указывать на следующее занятое место в стеке.

Стек растет вниз от старших адресов памяти к младшим, так что операция декремента стека используется для проталкивания значения регистров в стек (push), и операция инкремента используется для выборки значения регистров из стека. Stack Pointer всегда указывает на последнюю занятую ячейку в стеке. Когда делается операция pop, то значение, на которое указывает SP, перемещается в регистр, и значение SP становится равным SP+4.

На следующей картинке показано, как должен выглядеть стек, когда выполняется выталкивание из стека наподобие R3 = [SP++]:

Blackfin SP Pop

Значение, которое было выбрано (pop) из памяти стека, физически остается в этой памяти, пока не будет перезаписано последующими проталкиваниями (push) в стек.

Конечно, обычное предназначение pop это восстановление значения регистров, которые были ранее выдвинуты в стек командой push. Пользователь при программировании должен строго придерживаться дисциплины для восстановления значений из стека - принцип "первым вошел, последним вышел" должен всегда соблюдаться. Pop должен быть выполнен абсолютно точно для тех же регистров, для которых была выполнена ранее операция Push, только в обратном порядке.

Для использования этой инструкции Stack Pointer должен быть всегда выровнен на 32 бита (адрес в SP должен нацело делиться на 4). Если произойдет невыровненный доступ к памяти, то будет сгенерировано исключение (exception), и выполнение инструкции будет прервано.

Значение не может быть выбрано из стека для прямого восстановления указателя стека Stack Pointer, так что инструкция SP = [SP++] является недопустимой. Подробнее см. имена регистров в разделе "Терминология".

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

В большинстве случаев это режим пользователя (User mode) и режим супервизора (Supervisor mode).

Явный доступ к регистрам USP, SEQSTAT, SYSCFG, RETI, RETX, RETN и RETE требует режим супервизора. Если попробовать явно обратиться к этим регистрам из режима пользователя, то возникнет исключение защиты нарушения доступа (protection violation exception).

[Параллельное выполнение]

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

[Примеры]

r0 = [sp++];
p4 = [sp++];
i1 = [sp++];
reti = [sp++]; // здесь требуется режим супервизора

См. также инструкции Push, Push Multiple, Pop Multiple.

Инструкция делает выборку из стека сразу нескольких регистров. Общая форма:

(диапазон_регистров_назначения) = [SP++]

Синтаксис:

(R7:Dreglim, P5:Preglim) = [SP++];  // регистры Dreg и индексированные Preg (a)1

(R7:Dreglim) = [SP++];              // только регистры Dreg (a)

(P5:Preglim) = [SP++];              // только индексированные регистры Preg (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreglim: любое число в диапазоне от 7 до 0.

Preglim: любое число в диапазоне от 5 до 0.

[Функциональное описание]

Инструкция Push Multiple восстанавливает из стека содержимое нескольких регистров данных (Dreg) и/или регистров указателя (Preg). Диапазон восстанавливаемых регистров всегда включает самый большой индекс регистра (R7 и/или P5) плюс любой нижележащий индекс регистра, который далее указывает пользователь, который включает R0 и/или P0.

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

Перед доступом к следующему занятому месту в стеке инструкция делает постинкремент указателя стека (Stack Pointer, SP).

Стек растет вниз от старших адресов памяти к младшим, так что операция декремента SP используется для проталкивания в стек (pushing), и соответственно операция инкремента SP используется для извлечения значений из стека (popping). Указатель стека всегда указывает на последнее занятое место в стеке. Когда делается операция выборки из стека (pop), то значение, на которое указывает SP, передается в регистр, после чего SP становится равным SP+4.

На следующей картинке показано, как будет выглядеть в стек, когда происходит множественная выборка из стека (pop multiple).

Blackfin SP Pop Multiple

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

Конечно, обычное предназначение pop это восстановление значения регистров, которые были ранее выдвинуты в стек командой push. Пользователь при программировании должен строго придерживаться дисциплины для восстановления значений из стека - принцип "первым вошел, последним вышел" должен всегда соблюдаться. Pop должен быть выполнен абсолютно точно для тех же регистров, для которых была выполнена ранее операция Push, только в обратном порядке.

Хотя время выполнения инструкции Pop Multiple варьируется в зависимости от количества восстанавливаемых регистров, применение её уменьшает размер кода.

Инструкцию Pop Multiple нельзя прервать во время её выполнения. Обработка прерывания, выставленного после первой операции чтения из стека, откладывается до завершения всех операций восстановления Pop Multiple. Однако исключения, которые возникнут во время выполнения этой инструкции, приведут к корректному её завершению. Например, если операция load/store может нарушить защиту доступа при выполнении Pop Multiple. В этом случае SP сбросится к своему значению, которое было перед выполнением этой инструкции. Такое поведение гарантирует, что инструкция может быть перезапущена после обработки исключения. Обратите внимание, что когда операция Pop Multiple была оборвана из-за исключения, состояние некоторых регистров изменится операциями восстановления, которые были уже выполнены до момента возникновения исключения.

Для использования инструкции Pop Multiple (как, впрочем, и для инструкции Pop) указатель стека (Stack Pointer, SP) должен быть всегда выровнен на 32 бита (делиться нацело на 4). Если произойдет невыровненный доступ к памяти, то возникнет исключение, и работа инструкции будет прервана, как это было только что описано.

Операндами этой инструкции могут быть только регистры указателей P0, ..., P5, но никак не регистры SP и FP. Все регистры данных R0, ..., R7 могут быть операндами для этой инструкции.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

(p5:4) = [sp++];       // P[3:0] исключены
(r7:2) = [sp++];       // R[1:0] исключены
(r7:5, p5:0) = [sp++]; // D-регистры R[4:0] опционально исключены

См. также инструкции Push, Push Multiple, Pop.

Инструкция выделяет место под стек. Общая форма:

LINK, UNLINK

Синтаксис:

LINK uimm18m4;      // выделение фрейма стека указанного размера (b)1

UNLINK;             // отмена выделения фрейма стека (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

uimm18m4: 18-битное поле без знака, значение которого должно делиться нацело на 4, с диапазоном от 8 до 262,152 байт (0x00008 .. 0x3FFFC).

[Функциональное описание]

Инструкция Linkage управляет пространством области стека (stack frame) для стека и указателя фрейма (Frame Pointer, FP) для этого пространства. LINK выделяет место в стеке и UNLINK освобождает это место. Инструкция привязки окна стека используется в настройке и отбрасывания областей памяти в стеке для высокоуровневого языка программирования наподобие C/C++.

LINK сохраняет текущее состояние регистров RETS и FP в стек, загружает регистр FP новым адресом области стека (frame), и затем декрементирует SP на предоставленное пользователем значение размера области стека.

Обычно в приложении за инструкцией LINK используют инструкцию Push Multiple для сохранения в стек регистров указателя и регистров данных.

Предоставленный пользователем аргумент инструкции LINK определяет размер выделенного пространства в стеке. LINK всегда сохраняет в стек регистры RETS и FP, так что минимальный размер области фрейма составляет 2 слова, если аргумент инструкции LINK был указан равным 0. Максимальный размер области фрейма будет 218 + 8 = 262152 байт в инкрементах по 4 байта.

UNLINK выполняет обратное, взаимодополняющее действие для LINK, т. е. отменяет выделение области в стеке путем перемещения текущего значения FP в SP и восстановления предыдущих значений FP и RETS, выбирая их из стека.

Инструкция UNLINK обычно следует за инструкциями Pop Multiple, которые восстанавливают регистры указателей и данных, ранее сохраненные в стеке.

Значения фрейма в стеке остаются там, пока их не перезапишут последующие операции со стеком Push, Push Multiple или LINK.

Конечно, FP не должен быть модифицирован кодом пользователя между инструкциями LINK и UNLINK, чтобы сохранить целостность стека.

Не может быть прервана ни инструкция LINK, ни UNLINK. Однако исключения, которые возникли при выполнении любой из этих инструкций, приведут к прерыванию их выполнения. Например, операция load/store может привести к нарушению защиты при выполнении LINK. В этом случае SP и FP сбросятся к своим оригинальным значениям, которые были до начала выполнения этой инструкции. Такое поведение гарантирует, что прерванная инструкция может быть перезапущена после обработки исключения.

Обратите внимание, что когда операция LINK обрывается из-за срабатывания исключения, память в стеке может быть изменена из-за того, что в неё уже были сохранены некоторые значения до того момента, как выполнение инструкции было прервано исключением. Аналогично, оборванная операция UNLINK может оставить измененными регистры FP и RETS, потому что их загрузка уже была произведена перед срабатыванием исключения.

На рисунках ниже показано содержимое стека после выполнения инструкции LINK, за которой идет инструкция Push Multiple.

Blackfin SP LINK UNLINK

Для использования инструкции указатель стека (Stack Pointer, SP) должен быть всегда выровнен на 32 бита (делиться нацело на 4). Если произойдет невыровненный доступ к памяти, то возникнет исключение, и работа инструкции будет прервана, как это было только что описано.

[Флаги]

Команда не оказывает никакого действия на флаги процессора.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

link 8;                // Установка фрейма размером в 8 слов,
                       // выделенного для локальных переменных.
[--sp] = (r7:0, p5:0); // Сохранение D-регистров и P-регистров.
(r7:0, p5:0) = [sp++]; // Восстановление D-регистров и P-регистров.
unlink;                // Закрытие фрейма.

См. также инструкции Push Multiple, Pop Multiple.

[Инструкции проверки, влияющие на бит CC]

В этом разделе обсуждаются инструкции, которые влияют на значение бита управления кодом (бит Control Code, CC) в регистре ASTAT. Пользователи могут применять эти инструкции, чтобы установить бит CC на основе сравнения значений двух регистров, указателей или аккумуляторов. Дополнительно эти инструкции могут переместить состояние бита CC или бит состояния арифметической операции в регистр данных и из регистра данных, или они могут инвертировать состояние бита CC.

Инструкция сравнивает регистры данных и по результату модифицирует CC. Общая форма:

CC = operand_1 == operand_2

CC = operand_1 < operand _2

CC = operand _1 < = operand _2

CC = operand _1 < operand _2 ( IU )

CC = operand _1 < = operand _2 ( IU )

Синтаксис:

CC = Dreg == Dreg;       // проверка на равенство регистров с учетом знака (a)1

CC = Dreg == imm3;       // проверка на равенство константе с учетом знака (a)

CC = Dreg < Dreg;        // меньше чем, сравниваются регистры с учетом знака (a)

CC = Dreg < imm3;        // меньше чем, сравнение с константой с учетом знака (a)

CC = Dreg < = Dreg;      // меньше или равно, сравнение регистра с учетом знака (a)

CC = Dreg < = imm3;      // меньше или равно, сравнение регистра с константой
                         // с учетом знака (a)

CC = Dreg < Dreg(IU);    // меньше, беззнаковое сравнение регистров (a)

CC = Dreg < uimm3(IU);   // меньше, беззнаковое сравнение регистра
                         // с константой (a)

CC = Dreg < = Dreg(IU);  // меньше или равно, беззнаковое сравнение регистров (a)

CC = Dreg < = uimm3(IU); // меньше или равно, беззнаковое сравнение регистра
                         // с константой (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

imm3: 3-битное поле со знаком, в диапазоне -4 .. 3.

uimm3: 3-битное поле без знака, в диапазоне 0 .. 7.

[Функциональное описание]

Инструкция сравнения регистров данных (Compare Data Register) устанавливает бит CC (Control Code bit, бит управления ветвлением программы) на основе результата сравнения двух значений. В качестве операндов используют D-регистры.

Операции сравнения не деструктивны, т. е. они не влияют на содержимое сравниваемых операндов, и влияют только на состояние бита CC и на флаги. Значение бита CC определяет поведение последующих инструкций условного ветвления.

Различные формы инструкции сравнения выполняют операцию сравнения 32-разрядных чисел со знаком, или сравнивают их как величины без знака, если используется в синтаксисе суффикс (IU). Операции сравнения выполняют вычитание и отбрасывают результат без какого-либо влияния на регистры пользователя. Операция сравнения, которую Вы укажете, определит конечное состояние бита CC.

[Флаги]

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

Сравнение Со знаком (signed) Без знака (unsigned)
Равно AZ=1 не применимо
Меньше AN=1 AC=0
Меньше или равно AN или AZ=1 AC=0 или AZ=1

Инструкция сравнения регистров влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• CC установится, если результат выражения сравнения в инструкции верен, иначе сбросится.
• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC0 установится если результат сгенерировал перенос, иначе очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

cc = r3 == r2;
cc = r7 == 1;
                  /* Если r0 = 0x8FFF FFFF и r3 = 0x0000 0001,
                     то операция со знаком ... */
cc = r0 < r3;
                  /* ... даст cc = 1, потому что r0 рассматривается
                     как отрицательное значение */
cc = r2 < -4;
cc = r6 < = r1;
cc = r4 < = 3;
                  /* Если r0 = 0x8FFF FFFF и r3 = 0x0000 0001, 
                    то операция без знака ...
cc = r5 < r3 (iu); 
                 /* ... даст CC = 0, потому что r0 рассматривается
                     как большое число без знака */
cc = r1 < 0x7 (iu);
cc = r2 < = r0 (iu);
cc = r3 < = 2 (iu);

См. также Compare Pointer, Compare Accumulator, Conditional Jump.

Инструкция сравнивает регистры-указатели и по результату модифицирует CC. Общая форма:

CC = operand_1 == operand_2

CC = operand_1 < operand _2

CC = operand _1 < = operand _2

CC = operand _1 < operand _2 ( IU )

CC = operand _1 < = operand _2 ( IU )

Синтаксис:

CC = Preg == Preg;       // проверка на равенство регистров с учетом знака (a)1

CC = Preg == imm3;       // проверка на равенство константе с учетом знака (a)

CC = Preg < Preg;        // меньше чем, сравниваются регистры с учетом знака (a)

CC = Preg < imm3;        // меньше чем, сравнение с константой с учетом знака (a)

CC = Preg < = Preg;      // меньше или равно, сравнение регистра с учетом знака (a)

CC = Preg < = imm3;      // меньше или равно, сравнение регистра с константой
                         // с учетом знака (a)

CC = Preg < Preg(IU);    // меньше, беззнаковое сравнение регистров (a)

CC = Preg < uimm3(IU);   // меньше, беззнаковое сравнение регистра 
                         // с константой (a)

CC = Preg < = Preg(IU);  // меньше или равно, беззнаковое сравнение регистров (a)

CC = Preg < = uimm3(IU); // меньше или равно, беззнаковое сравнение регистра 
                         // с константой (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Preg: регистры P0, ..., P5, SP, FP.

imm3: 3-битное поле со знаком, в диапазоне -4 .. 3.

uimm3: 3-битное поле без знака, в диапазоне 0 .. 7.

[Функциональное описание]

Инструкция сравнения регистров указателя (Compare Pointer) устанавливает бит CC (Control Code bit, бит управления ветвлением программы) на основе результата сравнения двух значений. В качестве операндов используют P-регистры.

Операции сравнения не деструктивны, т. е. они не влияют на содержимое сравниваемых операндов, и влияют только на состояние бита CC и на флаги. Значение бита CC определяет поведение последующих инструкций условного ветвления.

Различные формы инструкции сравнения выполняют операцию сравнения 32-разрядных чисел со знаком, или сравнивают их как величины без знака, если используется в синтаксисе суффикс (IU). Операции сравнения выполняют вычитание и отбрасывают результат без какого-либо влияния на регистры пользователя. Операция сравнения, которую Вы укажете, определит конечное состояние бита CC.

[Флаги]

Инструкция сравнения регистров указателей влияет только на 1 флаг:

• CC установится, если результат выражения сравнения в инструкции верен, иначе сбросится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

cc = p3 == p2;
cc = p0 == 1;
cc = p0 < p3;
cc = p2 < -4;
cc = p1 < = p0;
cc = p4 < = 3;
cc = p5 < p3(iu);
cc = p1 < 0x7(iu);
cc = p2 < = p0(iu);
cc = p3 < = 2(iu);

См. также Compare Data Register, Compare Accumulator, Conditional Jump.

Инструкция сравнивает аккумуляторы и по результату модифицирует CC. Общая форма:

CC = A0 == A1

CC = A0 < A1

CC = A0 < = A1

Синтаксис:

CC = A0 == A1;       // проверка на равенство регистров с учетом знака (a)1

CC = A0 < A1;        // меньше чем, сравниваются регистры с учетом знака (a)

CC = A0 < = A1;      // меньше или равно, сравнение регистра с учетом знака (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Функциональное описание]

Инструкция сравнения регистров аккумуляторов (Compare Accumulator) устанавливает бит CC (Control Code bit, бит управления ветвлением программы) на основе результата сравнения двух значений. В качестве операндов используют аккумуляторы.

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

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

Операции сравнения не деструктивны, т. е. они не влияют на содержимое сравниваемых операндов, и влияют только на состояние бита CC и на флаги. Значение бита CC определяет поведение последующих инструкций условного ветвления.

[Флаги]

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

Сравнение Со знаком (signed)
Равно AZ=1
Меньше AN=1
Меньше или равно AN или AZ=1

Инструкция сравнения аккумуляторов влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• CC установится, если результат выражения сравнения в инструкции верен, иначе сбросится.
• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC0 установится если результат сгенерировал перенос, иначе очистится.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

cc = A0 == A1;
cc = A0 < A1;
cc = A0 < = A1; 

См. также Compare Pointer, Compare Data Register, Conditional Jump.

Инструкция делает копирование значения бита CC. Общая форма:

dest = CC

dest |= CC

dest &= CC

dest ^= CC

CC = source

CC |= source

CC &= source

CC ^= source

Синтаксис:

Dreg = CC;     // копирует CC в 32-битный регистр данных (a)1
statbit = CC;  // бит статуса становится равным CC (a)
statbit |= CC; // бит статуса становится результатом логической операции
               // ИЛИ (OR) над ним и CC (a)
statbit &= CC; // бит статуса становится результатом логической операции
               // И (AND) над ним и CC (a)
statbit ^= CC; // бит статуса становится результатом логической операции
               // ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) над ним и CC (a)
CC = Dreg;     // CC установится, если в регистре не ноль (a)
CC = statbit;  // CC становится равным биту статуса (a)
CC |= statbit; // CC становится равным CC OR бит статуса (a)
CC &= statbit; // CC становится равным CC AND бит статуса (a)
CC ^= statbit; // CC становится равным CC XOR бит статуса (a) 

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

statbit: AZ, AN, AC0, AC1, V, VS, AV0, AV0S, AV1, AV1S, AQ.

[Функциональное описание]

Инструкция Move CC осуществляет операцию копирования между значением арифметического бита статуса и бита управления ветвлением (Control Code bit, CC).

При копировании CC в 32-битный регистр данных, операция помещает значение бита CC в самый младший значащий бит регистра (LSB), заполняя остальные биты нулями. Таким образом, может быть 2 случая:

Если CC = 0, Dreg становится равным 0x00000000.
Если CC = 1, Dreg становится равным 0x00000001.

Когда копируется регистр данных в бит CC операция установит бит CC в 1, если установлен любой бит в регистре-источнике (т. е. если регистр не равен 0). Иначе эта операция очистит бит CC.

Некоторые версии этой инструкции делают логическую установку или очистку бита CC или бита статуса арифметической операции по результату логической операции на базе бита статуса и бита CC.

Использование бита CC в качестве источника (source) и назначения (dst) в одной инструкции запрещено. См. ниже инструкцию отрицания CC (NEGATE CC), позволяющую поменять значение CC на основе своего собственного значения.

[Флаги]

Инструкция Move CC влияет на флаги CC, AZ, AN, AC0, AC1, V, VS, AV0, AV0S, AV1, AV1S, AQ, в соответствии со значением бита статуса и используемым синтаксисом. Все другие флаги, не указанные явно как бит назначения в инструкции, не будут изменены.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

r0 = cc;
az = cc;
an |= cc;
ac0 &= cc;
av0 ^= cc;
cc = r4;
cc = av1;
cc |= aq;
cc &= an;
cc ^= ac1;

См. также инструкцию NEGATE CC.

Инструкция выполняет логическую инверсию значения бита CC. Общая форма:

CC = !CC

Длина инструкции 16 бит.

[Флаги]

Инструкция CC влияет только на бит CC, переключая его значение на противоположное. Все другие флаги не будут изменены.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

cc = !cc;

См. также инструкцию Move CC.

[Логические операции]

Этот раздел посвящен инструкциям, поддерживающим логические операции. Имеются базовые операции И (AND), НЕТ (NOT, или двоичное дополнение до 1), ИЛИ (OR), ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR), а также некоторые специфические операции для поддержки кодирования/декодирования с помощью LFSR, так называемые инструкции Bit-Wise Exclusive-OR.

Общая форма:

регистр_назначения = регистр_источника_0 & регистр_источника_1

Синтаксис:

Dreg = Dreg & Dreg; // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция AND выполняет 32-разрядную, побитную операцию логики И (AND) над регистрами-источниками, и сохраняет результат в регистр назначения.

Инструкция не модифицирует явно регистры источника. Но регистр назначения и один из регистров источника могут быть одним и тем же D-регистром, тогда операция изменит этот регистр источника.

[Флаги]

Инструкция влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC и AV0 очистятся.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

r4 = r4 & r3;

См. также инструкцию OR.

Общая форма:

регистр_назначения = ~ регистр_источника

Синтаксис:

Dreg = ~Dreg; // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

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

Инструкция не модифицирует явно регистры источника. Но регистр назначения и регистр источника могут быть одним и тем же D-регистром, тогда операция изменит регистр источника.

[Флаги]

Инструкция влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC и AV0 очистятся.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

r3 = ~r4; 

См. также инструкцию Negate (двоичное дополнение).

Общая форма:

регистр_назначения = регистр_источника_0 | регистр_источника_1

Синтаксис:

Dreg = Dreg | Dreg; // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция OR выполняет 32-разрядную, побитную операцию логики ИЛИ (OR) над регистрами-источниками, и сохраняет результат в регистр назначения.

Инструкция не модифицирует явно регистры источника. Но регистр назначения и один из регистров источника могут быть одним и тем же D-регистром, тогда операция изменит этот регистр источника.

[Флаги]

Инструкция влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC и AV0 очистятся.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

r4 = r4 | r3; 

См. также инструкции Exclusive-OR, Bit-Wise Exclusive-OR.

Общая форма:

регистр_назначения = регистр_источника_0 ^ регистр_источника_1

Синтаксис:

Dreg = Dreg ^ Dreg; // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция исключающего ИЛИ (Exclusive-OR, сокращенно XOR) выполняет 32-разрядную, побитную операцию логики исключающее ИЛИ (XOR) над регистрами-источниками, и сохраняет результат в регистр назначения.

Инструкция не модифицирует явно регистры источника. Но регистр назначения и один из регистров источника могут быть одним и тем же D-регистром, тогда операция изменит этот регистр источника.

[Флаги]

Инструкция влияет на следующие флаги арифметики, находящиеся в регистре ASTAT:

• AZ установится, если результат равен 0, иначе очистится.
• AN установится, если результат отрицателен, иначе очистится.
• AC и AV0 очистятся.

Все остальные флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

r4 = r4 ^ r3; 

См. также инструкции OR, Bit-Wise Exclusive-OR.

Общая форма:

регистр_назначения = CC = BXORSHIFT (A0, src_reg)

регистр_назначения = CC = BXOR (A0, src_reg)

регистр_назначения = CC = BXOR (A0, A1, CC)

A0 = BXORSHIFT (A0, A1, CC)

Синтаксис LFSR TYPE I (без обратной связи):

Dreg_lo = CC = BXORSHIFT (A0, Dreg); // (b)1

Dreg_lo = CC = BXOR (A0, Dreg);      // (b)

Синтаксис LFSR TYPE I (с обратной связью):

Dreg_lo = CC = BXOR (A0, A1, CC);    // (b)

A0 = BXORSHIFT (A0, A1, CC);         // (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_lo: RL[7:0]

[Функциональное описание]

4 инструкции побитного исключающего ИЛИ (Bit-wise Exclusive-OR, BXOR) поддерживаются 2 типами LFSR-реализаций.

Type I LFSR (без обратной связи) накладывает 32-битную регистровую маску на 40-битное состояние, находящееся в аккумуляторе A0, за которым следует операция редукции побитного исключающего ИЛИ. Результат помещается в CC и половину регистра назначения.

Type I LFSR (с обратной связью) накладывает 40-битную маску в аккумуляторе A1 на 40-битное состояние, находящееся в A0. Результат выдвигается в A0.

В следующих схемах, описывающих группу инструкций BXOR, побитная XOR-редукция задана следующим образом:

Out = ((((B0 ? B1) ? B2) ? B1)... ? BN-1)

где B0 .. BN-1 представляют N бит, являющиеся результатом маскирования содержимого аккумулятора A0 полиномом, сохраненным либо в A1, либо в 32-битном регистре. Описание инструкции показано на рис. 7-1.

Blackfin bit wise exclusive OR reduction

Рис. 7-1. Побитная редукция исключающего ИЛИ (Bit-Wise Exclusive OR Reduction).

На этом рисунке биты A0[0] и A0[1] претерпевают операцию логического И с битами D[0] и D[1]. Результат этой операции проходит XOR-редукцию по следующей формуле:

s(D) = ( A0[0] • D[0] ) ? ( A0[1] • D[1] )

Modified Type I LSFR (without feedback). Две инструкции поддерживают LSFR без обратной связи. Вот они:

Dreg_lo = BXORSHIFT(A0,dreg), и
Dreg_lo = CC = BXOR(A0,dreg)

В первой инструкции аккумулятор A0 сдвигается влево на 1 разряд перед XOR-редукцией. Эта инструкция предоставляет побитную операцию XOR над результатом логического И над A0 и D-регистром. Результат операции помещается одновременно в флаг CC и в младший значащий бит регистра назначения. Эта операция показана ниже на рис. 7-2.

Старшие 15 бит Dreg_lo перезаписываются нулем, и после операции dr[0] = IN.

Blackfin A0 left shifted by 1 followed by XOR reduction

Рис. 7-2. A0, сдвинутый влево на 1, после чего идет XOR-редукция.

Вторая редакция в этом классе выполняет побитную операцию XOR результата операции И от A0 и Dreg. Выход операции помещается в младший значащий бит регистра назначения и одновременно в бит CC. Аккумулятор A0 не модифицируется этой операцией. Сама операция иллюстрируется на рис. 7-3.

Старшие 15 бит dreg_lo перезаписываются нулями, и после этой операции dr[0] = IN.

Blackfin XOR of A0 logical AND with D register

Рис. 7-3. XOR аккумулятора A0, логическое И с содержимым D-регистра.

Modified Type I LFSR (with feedback). Две инструкции поддерживают LFSR с обратной связью. Вот они:

A0 = BXORSHIFT(A0,A1,CC), и
Dreg_lo = CC = BXOR(A0,A1,CC)

Первая инструкция предоставляет побитную операцию XOR от результата операции И между A0 и A1. Результирующий промежуточный бит претерпевает операцию XOR с флагом CC. После этого результат операции сдвигается влево в младший значащий бит A0. Эта операция показана на рис. 7-4. Эта операция не изменяет бит CC.

Blackfin XOR of A0 logical AND with A1 with results left shifted into LSB of A0

Рис. 7-4. XOR над результатом логической И между A0 и A1, со сдвигом результата в LSB A0.

Вторая инструкция в этом классе выполняет побитную операцию XOR от операции логического И между A0 и A1. Результирующий промежуточный бит претерпевает операцию XOR с флагом CC. Результат операции помещается как во флаг CC, так и в младший значащий бит регистра назначения. Эта операция показана на рис. 7-5.

Blackfin XOR of A0 logical AND with A1 with results placed in CC flag

Рис. 7-5. XOR над результатом логической И между A0 и A1, с результатом, размещенным в флаге CC и LSB регистра назначения.

Эта операция не меняет аккумулятор A0. Старшие 15 регистра Dreg_lo перезаписываются нулями, и dr[0] = IN.

[Флаги]

Четырьмя инструкциями Bit-wise Exclusive-OR будет изменен только флаг CC следующим образом: CC установится или очистится в соответствии с функциональным описанием для BXOR и версией без обратной связи инструкции BXORSHIFT. Версия с обратной связью инструкции BXORSHIFT не влияет ни на какие флаги.

Все другие флаги останутся нетронутыми.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

32-битные версии этой инструкции могут выполняться параллельно с некоторыми другими 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

r0.l = cc = bxorshift (a0, r1);
r0.l = cc = bxor (a0, r1);
r0.l = cc = bxor (a0, a1, cc);
a0 = bxorshift (a0, a1, cc);

[Специальное применение инструкции]

Регистры LFSR могут умножать и делить полиномы и часто используются для реализации циклических кодеров и декодеров. Например, для генерации псевдослучайных числовых последовательностей [3].

LFSR используют набор инструкций Bit-wise XOR для вычисления битовой XOR-редукции от состояния, замаскированное полиномом.

[Операции над битами]

В этом разделе обсуждаются битовые операции, позволяющие установить, очистить, переключить в противоположное состояние, а также проверить биты. Они также позволяют объединять битовые поля и сохранять результат, распаковать отдельные биты из регистра, соединить потоки бит, и подсчитать количество единиц в регистре.

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

BITCLR ( D-регистр, номер_бита )

Синтаксис:

BITCLR(Dreg, uimm5);      // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

uimm5: 5-разрядное поле без знака, в диапазоне 0 .. 31.

[Функциональное описание]

Инструкция очистки бита очищает указанный по номеру бит в указанном D-регистре. Она не влияет на остальные биты в этом регистре.

Диапазон номеров позиции бита составляет 0 .. 31, где 0 соответствует LSB и 31 соответствует MSB в 32-разрядном D-регистре.

[Флаги]

Инструкция Bit Clear влияет на следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все другие флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

bitclr(r2, 3); // очистить бит 3 (четвертый по счету бит после LSB) в R2

Например, если в R2 содержалось 0xFFFFFFFF до выполнения этой инструкции, то после её выполнения в R2 будет содержаться 0xFFFFFFF7.

См. также инструкции Bit Set, Bit Test, Bit Toggle.

Инструкция позволяет установить указанный бит в регистре данных. Общая форма:

BITSET ( D-регистр, номер_бита )

Синтаксис:

BITSET(Dreg, uimm5);      // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

uimm5: 5-разрядное поле без знака, в диапазоне 0 .. 31.

[Функциональное описание]

Инструкция установки бита установит в 1 указанный по номеру бит в указанном D-регистре. Она не влияет на остальные биты в этом регистре.

Диапазон номеров позиции бита составляет 0 .. 31, где 0 соответствует LSB и 31 соответствует MSB в 32-разрядном D-регистре.

[Флаги]

Инструкция Bit Set влияет на следующие флаги:

• AZ очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все другие флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

bitset(r2, 7); // установить бит 7 (восьмой по счету бит после LSB) в R2

Например, если в R2 содержалось 0x00000000 до выполнения этой инструкции, то после её выполнения в R2 будет содержаться 0x00000080.

См. также инструкции Bit Clear, Bit Test, Bit Toggle.

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

BITTGL ( D-регистр, номер_бита )

Синтаксис:

BITTGL(Dreg, uimm5);      // (a)1

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

uimm5: 5-разрядное поле без знака, в диапазоне 0 .. 31.

[Функциональное описание]

Инструкция переключения состояния бита проинвертирует указанный по номеру бит в указанном D-регистре. Она не влияет на остальные биты в этом регистре.

Диапазон номеров позиции бита составляет 0 .. 31, где 0 соответствует LSB и 31 соответствует MSB в 32-разрядном D-регистре.

[Флаги]

Инструкция Bit Toggle влияет на следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все другие флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

bittgl(r2, 24); // переключить бит 24 (25-й по счету бит после LSB) в R2

Например, если в R2 содержалось 0xF1FFFFFF до выполнения этой инструкции, то после её выполнения в R2 будет содержаться 0xF0FFFFFF. Если вызвать инструкцию второй раз, то в регистре снова окажется значение 0xF1FFFFFF.

См. также инструкции Bit Clear, Bit Test, Bit Set.

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

CC = BITTST ( D-регистр, номер_бита )

CC = !BITTST ( D-регистр, номер_бита )

Синтаксис:

CC = BITTST(Dreg, uimm5);  // установить CC, если бит = 1 (a)1

CC = !BITTST(Dreg, uimm5); // установить CC, если бит = 0 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

uimm5: 5-разрядное поле без знака, в диапазоне 0 .. 31.

[Функциональное описание]

Инструкция проверки состояния бита установит или сбросит бит CC, базируясь на текущем состоянии указанного по номеру бита в указанном D-регистре. Одна версия инструкции проверяет, установлен ли нужный бит в регистре, другая проверяет сброшен ли он. Инструкция не влияет на биты в этом регистре.

Диапазон номеров позиции бита составляет 0 .. 31, где 0 соответствует LSB и 31 соответствует MSB в 32-разрядном D-регистре.

[Флаги]

Инструкция влияет только на флаг CC. Все другие флаги не поменяют свое состояние.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Пример]

CC = bittst(r7, 15); // проверить бит 15 на лог. 1 в R7

Например, если в R7 содержалось 0xFFFFFFFF до выполнения этой инструкции, то после её выполнения CC установится в 1, и R7 будет все также содержать 0xFFFFFFFF.

См. также инструкции Bit Clear, Bit Toggle, Bit Set.

Инструкция позволяет объединять поля регистров данных. Инструкция применяется для алгоритмов оверлея видеоизображения. Общая форма:

dest_reg = DEPOSIT ( backgnd_reg, foregnd_reg )

dest_reg = DEPOSIT ( backgnd_reg, foregnd_reg ) (X)

Синтаксис:

Dreg = DEPOSIT (Dreg, Dreg);      // без расширения (b)1

Dreg = DEPOSIT (Dreg, Dreg)(X);   // с расширением знаком (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция Bit Field Deposit соединяет фоновое битовое поле (background bit field) в регистре backgnd_reg с передним битовым полем (foreground bit field) в старшей половине регистра foregnd_reg, и сохраняет результат в регистр dest_reg. Пользователь определяет длину foreground-поля бит и его позицию в поле background.

Опция: с использованием синтаксиса (X) можно расширить знаком внесенное (deposited) поле бит. Если Вы укажете синтаксис расширения знаком, то операция не повлияет на биты регистра назначения dest_reg, которые менее значимые, чем внесенное поле бит.

Ниже показаны определения битового поля входного регистра.

Blackfin background foreground regs

Здесь b это регистр поля бит background (32 бита), n это поле бит foreground (16 бит), поле L определяет актуальное количество используемых бит foreground (длина поля бит foreground, допустимый диапазон 0 .. 16), p предназначено для позиции бита LSB поля foreground в регистре назначения dest_reg (допустимый диапазон 0 .. 31).

Операция записывает битовое поле foreground длиной L поверх битового поля background, с битом LSB, размещенным в позиции p поля background. Дополнительно см. пример ниже.

Граничные случаи. Обратите внимание на следующие крайние случаи:

• Беззнаковый (unsigned) синтаксис, L = 0: архитектура копирует содержимое регистра backgnd_reg без модификации регистра dest_reg. По умолчанию foreground-поле длиной 0 будет прозрачным.

• Расширение знаком (sign-extended), L = 0 и p = 0: в этом случае в регистр dest_reg загрузится 0x0000 0000. Знак нулевой длины, позиция нуля также 0, поэтому расширение знаком будет всеми нулями.

• Расширение знаком (sign-extended), L = 0 и p ? 0: архитектура копирует младшие биты регистра backgnd_reg ниже позиции p в регистр dest_reg, затем расширяет это число знаком. Значение foreground никак не влияет. Например, если...

backgnd_reg = 0x0000 8123,
L = 0, и
p = 16,

то...

dest_reg = 0xFFFF 8123.

В этом примере архитектура копирует биты 15:0 из backgnd_reg в dest_reg, затем это число расширяет знаком.

• Расширение знаком (sign-extended), L + p > 32: Любые foreground-биты, которые попадают вне диапазона бит 31 .. 0, будут отброшены. Инструкция Bit Field Deposit не будет менять содержимое двух регистров источника. Один из этих регистров также может выступать и как dest_reg.

[Флаги]

Эта инструкция влияет на следующие флаги:

• AZ установится, если результат 0; очистится, если не 0.
• AN установится, если результат отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все другие флаги останутся нетронутыми.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

Инструкция (а она 32-битная) может быть выполнена параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Пример работы инструкции Bit Field Deposit Unsigned]

r7 = deposit (r4, r3);

Если ...

Blackfin Bit Field Deposit Unsigned ex01

... и ...

Blackfin Bit Field Deposit Unsigned ex02

... то инструкция даст результат ...

Blackfin Bit Field Deposit Unsigned ex03

Если ...

Blackfin Bit Field Deposit Unsigned ex04

... и ...

Blackfin Bit Field Deposit Unsigned ex05

... то инструкция даст результат ...

Blackfin Bit Field Deposit Unsigned ex06

[Пример работы инструкции Bit Field Deposit Sign-Extended]

r7 = deposit (r4, r3)(x);     // sign-extended

Если ...

Blackfin Bit Field Deposit Sign Extended ex01

... и ...

Blackfin Bit Field Deposit Sign Extended ex02

... то инструкция даст результат ...

Blackfin Bit Field Deposit Sign Extended ex03

Если ...

Blackfin Bit Field Deposit Sign Extended ex04

... и ...

Blackfin Bit Field Deposit Sign Extended ex05

... то инструкция даст результат ...

Blackfin Bit Field Deposit Sign Extended ex06

См. также инструкцию Bit Field Extraction.

Инструкция распаковывает поле бит из регистра. Инструкция применяется в алгоритмах распознавания видеоизображения и алгоритмах разделения. Общая форма:

dest_reg = EXTRACT (scene_reg, pattern_reg) (Z)

dest_reg = EXTRACT (scene_reg, pattern_reg) (X)

Синтаксис:

Dreg = EXTRACT (Dreg, Dreg_lo) (Z);     // zero-extended (b)1

Dreg = EXTRACT (Dreg, Dreg_lo) (X);     // sign-extended (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_lo: R0.L, ..., R7.L.

[Функциональное описание]

Инструкция Bit Field Extraction копирует некоторую отдельную порцию бит из регистра scene_reg (поле сцены) в младшие биты регистра dest_reg. Пользователь определяет длину маски бит и её позицию в поле сцены. Пользователь может выбрать синтаксис с суффиксом (X), чтобы выполнить распаковку поля бит с дополнением знаком, или синтаксис с суффиксом (Z) для выполнения распаковки с дополнением нулями.

Ниже показаны определения полей входных регистров.

Blackfin scene pattern regs

Здесь s это поле бит сцены (scene bit field, 32 бита), p позиция бита LSB поля бит маски в scene_reg (pattern bit field, допустимый диапазон 0 .. 31), L длина поля бит маски (pattern bit field, допустимый диапазон 0 .. 31).

Операция читает по полю маски длиной L из поля бит сцены, при этом бит LSB размещается в позиции p сцены. Для дополнительной информации см. примеры ниже.

Граничный случай. Если p + L > 32, то в версии инструкции zero-extended (дополнение нулем) и sign-extended (дополнение знаком) архитектура подразумевает, что все биты до левой части scene_reg равны 0. В таком случае пользователь пытается получить доступ к большему количеству бит, чем регистр содержит в действительности. Следовательно, архитектура заполняет нулями любые неопределенные биты возле MSB scene_reg.

Инструкция Bit Field Extraction не модифицирует содержимое двух регистров - источников. Один из регистров источника может также быть dest_reg, тогда он будет изменен.

[Флаги]

Эта инструкция влияет на следующие флаги:

• AZ установится, если результат 0; очистится, если не 0.
• AN установится, если результат отрицательный, иначе очистится.
• AC0 очистится.
• V очистится.

Все другие флаги останутся нетронутыми.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

Инструкция (а она 32-битная) может быть выполнена параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Пример Bit Field Extraction Unsigned]

r7 = extract (r4, r3.l)(z); // zero-extended

Если ...

Blackfin Bit Field Extraction Unsigned ex01

... и ...

Blackfin Bit Field Extraction Unsigned ex02

... то инструкция даст результат ...

Blackfin Bit Field Extraction Unsigned ex03

Если ...

Blackfin Bit Field Extraction Unsigned ex04

... и ...

Blackfin Bit Field Extraction Unsigned ex05

... то инструкция даст результат ...

Blackfin Bit Field Extraction Unsigned ex06

[Пример Bit Field Extraction Sign-Extended]

r7 = extract (r4, r3.l)(x); // sign-extended 

Если ...

Blackfin Bit Field Extraction Sign Extended ex01

... и ...

Blackfin Bit Field Extraction Sign Extended ex02

... то инструкция даст результат ...

Blackfin Bit Field Extraction Sign Extended ex03

Если ...

Blackfin Bit Field Extraction Sign Extended ex04

... и ...

Blackfin Bit Field Extraction Sign Extended ex05

... то инструкция даст результат ...

Blackfin Bit Field Extraction Sign Extended ex06

См. также инструкцию Bit Field Deposit.

Инструкция мультиплексирования бит используется в алгоритмах конволюционного кодера. Общая форма:

BITMUX ( source_1, source_0, A0 ) (ASR)

BITMUX ( source_1, source_0, A0 ) (ASL)

Синтаксис:

BITMUX (Dreg, Dreg, A0) (ASR);   // сдвиг вправо, LSB выдвигается наружу (b)1

BITMUX (Dreg, Dreg, A0) (ASL);   // сдвиг влево, MSB выдвигается наружу (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция Bit Multiplex соединяет потоки бит. У неё есть 2 версии, со сдвигом вправо (Shift Right) и со сдвигом влево (Shift Left). Эта инструкция перезаписывает содержимое регистров-источников source_1 и source_0.

В версии Shift Right процессор выполняет следующую последовательность действий.

1. Сдвигает вправо аккумулятор A0 на 1 бит. При этом бит LSB из source_1 вдвигается в бит MSB аккумулятора.
2. Сдвигает вправо аккумулятор A0 на 1 бит. При этом бит LSB из source_0 вдвигается в бит MSB аккумулятора.

В версии Shift Left процессор выполняет следующую последовательность действий.

1. Сдвигает влево аккумулятор A0 на 1 бит. При этом бит MSB из source_0 вдвигается в бит LSB аккумулятора.
2. Сдвигает влево аккумулятор A0 на 1 бит. При этом бит MSB из source_1 вдвигается в бит LSB аккумулятора.

Регистры source_1 и source_0 не могут быть одним и тем же D-регистром.

Если ...

Blackfin Bit Multiplex func01

... инструкция со сдвигом вправо сделает следующее:

Blackfin Bit Multiplex func02

... инструкция со сдвигом влево сделает следующее:

Blackfin Bit Multiplex func03

[Флаги]

Инструкция не влияет на флаги.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

Инструкция (а она 32-битная) может быть выполнена параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

bitmux(r2, r3, a0)(asr);   // сдвиг вправо

Если ...

Blackfin Bit Multiplex ex01

... и ...

Blackfin Bit Multiplex ex02

... и ...

Blackfin Bit Multiplex ex03

... то результатом сдвига вправо будет ...

Blackfin Bit Multiplex ex04

... и ...

Blackfin Bit Multiplex ex05

... и ...

Blackfin Bit Multiplex ex06

bitmux(r3, r2, a0)(asl);   // сдвиг влево

Если ...

Blackfin Bit Multiplex ex07

... и ...

Blackfin Bit Multiplex ex08

... и ...

Blackfin Bit Multiplex ex09

... то результатом сдвига влево будет ...

Blackfin Bit Multiplex ex10

... и ...

Blackfin Bit Multiplex ex11

... и ...

Blackfin Bit Multiplex ex12

Инструкция подсчета бит-единичек Ones Population Count может быть использована для проверки количества бит на четность. Общая форма:

dest_reg = ONES src_reg

Синтаксис:

Dreg_lo = ONES Dreg;        // (b)1

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_lo: половинки регистров R0.L, ..., R7.L.

[Функциональное описание]

Инструкция Ones Population Count загружает количество бит с лог. 1, содержащихся в регистре src_reg, в младшую половинку регистра dest_reg.

Диапазон возможных значений, которые могут быть загружены в dest_reg, будет 0 .. 32.

Регистры dest_reg и src_reg могут быть одним и тем же D-регистром. Если эти регистры разные, то инструкция Ones Population Count не модифицирует содержимое регистра-источника src_reg.

[Флаги]

Инструкция не влияет на флаги.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

Инструкция (а она 32-битная) может быть выполнена параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Пример]

r3.l = ones r7;

Если в регистре R7 содержится 0xA5A5A5A5, то R3.L получит значение 16, или 0x0010. Если в R7 содержится 0x00000081, то R3.L получит значение 2, или 0x0002.

[Операции сдвига и прокрутки]

В этом разделе рассматриваются инструкции, которые манипулируют позициями бит. Пользователи могут применять такие возможности инструкций, как логические и арифметические сдвиги, комбинирование сложения со сдвигом, прокрутку числа в регистре через бит CC.

Сложение со сдвигом. Общая форма:

dest_pntr = (dest_pntr + src_reg) << 1

dest_pntr = (dest_pntr + src_reg) << 2

dest_reg = (dest_reg + src_reg) << 1

dest_reg = (dest_reg + src_reg) << 2

Синтаксис операций с указателями:

Preg = ( Preg + Preg ) << 1;   // dest_reg = (dest_reg + src_reg) x 2 (a)1

Preg = ( Preg + Preg ) << 2;   // dest_reg = (dest_reg + src_reg) x 4 (a)

Синтаксис операций с данными:

Dreg = (Dreg + Dreg) << 1;     // dest_reg = (dest_reg + src_reg) x 2 (a)

Dreg = (Dreg + Dreg) << 2;     // dest_reg = (dest_reg + src_reg) x 4 (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Preg: регистры P0, ..., P5.

Dreg: регистры R0, ..., R7.

[Функциональное описание]

Инструкция сложения со сдвигом (Add with Shift) комбинирует операцию сложения с одиночным или двойным логическим сдвигом влево. Конечно, сдвиг влево соответствует умножению на 2 чисел, расширенных знаком. Насыщение не поддерживается.

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

[Флаги]

Версии инструкций с D-регистрами влияют на следующие флаги:

• AZ установится, если результат 0; очистится, если не 0.
• AN установится, если результат отрицательный, иначе очистится.
• V установится, если в результате произошло переполнение, иначе очистится.
• VS установится, если V установится, иначе значение VS останется неизменным.

Все другие флаги останутся нетронутыми.

Версия инструкции с P-регистрами не влияет ни на какие флаги.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

p3 = (p3+p2) << 1;   // p3 = (p3 + p2) * 2
p3 = (p3+p2) << 2;   // p3 = (p3 + p2) * 4
r3 = (r3+r2) << 1;   // r3 = (r3 + r2) * 2
r3 = (r3+r2) << 2;   // r3 = (r3 + r2) * 4

См. также Add, Multiply (Modulo 232), Logical Shift, Arithmetic Shift, Add.

Сдвиг со сложением. Общая форма:

dest_pntr = adder_pntr + ( src_pntr << 1 )

dest_pntr = adder_pntr + ( src_pntr << 2 )

Синтаксис:

Preg = Preg + ( Preg << 1 );   // adder_pntr + (src_pntr x 2) (a)1

Preg = Preg + ( Preg << 2 );   // adder_pntr + (src_pntr x 4) (a)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит.

[Терминология синтаксиса]

Preg: регистры P0, ..., P5.

[Функциональное описание]

Инструкция сдвига со сложением (Shift with Add) комбинирует одиночный или двойной логический сдвиг влево с операцией сложения. Конечно, сдвиг влево соответствует умножению на 2 чисел, расширенных знаком. Насыщение не поддерживается.

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

[Флаги]

Инструкция не влияет ни на какие флаги.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

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

[Примеры]

p3 = p0+(p3 << 1);   // p3 = (p3 * 2) + p0
p3 = p0+(p3 << 2);   // p3 = (p3 * 4) + p0

См. также Add with Shift, Multiply (Modulo 232), Logical Shift, Arithmetic Shift, Add.

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

dest_reg >>>= shift_magnitude

dest_reg = src_reg >>> shift_magnitude (opt_sat)

dest_reg = src_reg << shift_magnitude (S)

accumulator = accumulator >>> shift_magnitude

dest_reg = ASHIFT src_reg BY shift_magnitude (opt_sat)

accumulator = ASHIFT accumulator BY shift_magnitude

Синтаксис сдвига на значение константы:

Dreg >>>= uimm5;                     // ариф. сдвиг вправо (a)1

Dreg << = uimm5;                     // лог. сдвиг влево (a)

Dreg_lo_hi = Dreg_lo_hi >>> uimm4;   // ариф. сдвиг вправо (b)

Dreg_lo_hi = Dreg_lo_hi << uimm4(S); // ариф. сдвиг влево (b)

Dreg = Dreg >>> uimm5;               // ариф. сдвиг вправо b)

Dreg = Dreg << uimm5 (S);            // ариф. сдвиг влево (b)

A0 = A0 >>> uimm5;                   // ариф. сдвиг вправо (b)

A0 = A0 << uimm5;                    // лог. сдвиг влево (b)

A1 = A1 >>> uimm5;                   // ариф. сдвиг вправо (b)

A1 = A1 << uimm5;                    // лог. сдвиг влево (b)

Синтаксис сдвига на значение в регистре:

Dreg >>>= Dreg;                                      // ариф. сдвиг вправо (a)

Dreg << = Dreg;                                      // лог. сдвиг влево (a)

Dreg_lo_hi = ASHIFT Dreg_lo_hi BY Dreg_lo (opt_sat); // ариф. сдвиг вправо (b)

Dreg = ASHIFT Dreg BY Dreg_lo (opt_sat);             // ариф. сдвиг вправо (b)

A0 = ASHIFT A0 BY Dreg_lo;                           // ариф. сдвиг вправо (b)

A1 = ASHIFT A1 BY Dreg_lo;                           // ариф. сдвиг вправо (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_lo_hi: половинки регистров R0.L, ..., R7.L, R0.H, ..., R7.H.

Dreg_lo: половинки регистров R0.L, ..., R7.L.

uimm4: 4-битное беззнаковое поле в диапазоне 0 .. 15.

uimm5: 5-битное беззнаковое поле в диапазоне 0 .. 31.

opt_sat: опциональный суффикс (S) вовлекает насыщение для результата. Это не опционально для версий, в синтаксисе которых показан суффикс (S).

[Функциональное описание]

Инструкции арифметического сдвига (Arithmetic Shift) сдвигают число в регистре на указанную величину бит (distance) в указанном направлении, сохраняя при этом знак оригинального числа. Бит знака заполнит самую левую (старшую) позицию, которая освобождается при арифметическом сдвиге вправо.

Также поддерживаются отдельные версии арифметического сдвига влево. Арифметический сдвиг влево делает насыщение результата, если значение было сдвинуто слишком далеко. Сдвиг влево, который потерял бы действующий бит знака, место этого делает насыщение максимального положительного или отрицательного результата.

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

Версии ASHIFT этой инструкции поддерживают 2 режима:

1. По умолчанию - арифметический сдвиг вправо и логический сдвиг влево. Логический сдвиг не гарантирует сохранение бита знака. Версии ASHIFT автоматически выбирают режимы арифметического и логического сдвига на базе знака величины сдвига (shift_magnitude).
2. Режим насыщения (saturation) - арифметические сдвиги вправо и влево, которые насыщают результат, если сдвиг произошел слишком далеко.

Версии >>>= и >>> этой инструкции поддерживают только арифметические сдвиги вправо. Если нужны левые сдвиги, то программист должен явно использовать инструкции арифметического << (с насыщением) или логического << (без насыщения) сдвига.

Примечание: инструкции логического сдвига влево для удобства указаны дважды в секции синтаксиса. Подробнее о инструкциях логического сдвига см. соответствующие врезки.

Инструкции арифметического сдвига поддерживаются инструкциями 16-битной и 32-битной длины.

• Инструкция синтаксиса >>> = будет 16-битной длины, позволяя писать код меньшего размера ценой потери гибкости.
• Инструкции с синтаксисом >>>, << и ASHIFT будут 32-битной длины, предоставляя отдельные регистры источника и назначения, альтернативные размеры данных, возможность параллельного выполнения вместе с инструкциями загрузки / сохранения (Load / Store).

Оба синтаксиса поддерживают магнитуды сдвига (т. е. на сколько разрядов сдвигать), указанные как в виде константы в команде, так и в значении регистра.

Таблица 9-1. Арифметические сдвиги.

Синтаксис Описание
>>>= Значение в dest_reg сдвигается вправо на количество бит, указанное в shift_magnitude. Размер данных всегда 32 бита длиной. Все 32 бита shift_magnitude определяют значение сдвига. Значение сдвига больше, чем 0x1F дадут в результате 0x00000000 (когда входное значение положительное) или 0xFFFFFFFF (когда входное значение отрицательное).

В этом синтаксисе поддерживается только сдвиг вправо; нет операции, соответствующей аналогичному синтаксису "<<< =" для арифметического сдвига влево. Однако поддерживается логический сдвиг влево (см. инструкцию логического сдвига, Logical Shift).
>>>, << и ASHIFT Значение в src_reg сдвигается на указанное количество бит в shift_magnitude, и результат сохраняется в dest_reg. Версии с ASHIFT могут сдвигать 32-битный Dreg и 40-битный аккумулятор на диапазон сдвига -32 .. 31 бита; величина сдвига определяется младшими 6 битами (с расширением знаком) значения в shift_magnitude.

Для версий ASHIFT знак в магнитуде определяет направление сдвига.

• Положительная магнитуда задает ЛОГИЧЕСКИЙ сдвиг ВЛЕВО.
• Отрицательная магнитуда задает АРИФМЕТИЧЕСКИЙ сдвиг ВПРАВО.

В сущности, магнитуда (magnitude) это степень числа 2, на которую умножается число src_reg. Положительные магнитуды делают умножение (N x 2n), в то время как отрицательные магнитуды делают деление (N x 2-n или N / 2n).

Регистры назначения (dest_reg) и источника (src_reg) могут быть 16-, 32- или 40-битными регистрами. Некоторые версии инструкции арифметического сдвига поддерживают опцию насыщения.

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

Для 16-битных src_reg допустимы магнитуды сдвига –16 .. +15, включая 0. Для 32- и 40-битных src_reg допустимы магнитуды сдвига –32 .. +31, включая 0. Инструкции арифметического сдвига маскируют и игнорируют биты, которые являются более значащими, чем это разрешено.

Версии этой инструкции с D-регистром сдвигают 16 или 32 бита для регистров полуслова и слова соответственно. Версии с аккумулятором сдвигают все 40 бит этих регистров.

Версии этой инструкции с D-регистром не делают неявную модификацию значения в регистре src_reg (регистр источника). Однако опционально dest_reg может быть тем же самым D-регистром, что и src_reg, в этом случае инструкция явно изменит регистр источника .

Версии с аккумулятором всегда модифицируют значение в регистре источника.

[Опции]

Опция (S) вовлекает насыщение результата.

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

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

[Флаги]

Версии этой инструкции, которые посылают результат в Dreg, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• V установится, если в результате произошло переполнение, иначе очистится.
• VS установится, если V был установлен, иначе V сохранит свое значение неизменным.

Все другие флаги не поменяют свое значение.

Версии этой инструкции, которые посылают результат в аккумулятор A0, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AV0 установится, если результат 0, иначе очистится.
• AV0S установится, если был установлен AV0, иначе AV0S не поменяет свое значение.

Все другие флаги не поменяют свое значение.

Версии этой инструкции, которые посылают результат в аккумулятор A1, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AV1 установится, если результат 0, иначе очистится.
• AV1S установится, если был установлен AV1, иначе AV1S не поменяет свое значение.

Все другие флаги не поменяют свое значение.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

32-битные инструкции могут быть выполнены параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций". 16-битные версии этих инструкций не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

r0 >>>= 19;             /* инструкция длиной 16 бит делает
                           арифметический сдвиг вправо */
r3.l = r0.h >>> 7;      // арифметический сдвиг вправо половины слова
r3.h = r0.h >>> 5;      /* то же самое, как в предыдущей инструкции; поддерживается
                           любая комбинация старшей и младшей половин слова */
r3.l = r0.h >>> 7(s);   // арифметический сдвиг вправо, половина слова, с насыщением
r4 = r2 >>> 20;         // арифметический сдвиг вправо, слово
A0 = A0 >>> 1;          // арифметический сдвиг вправо, аккумулятор
r0 >>>= r2;             /* инструкция длиной 16 бит делает арифметический
                           сдвиг вправо */
 
r3.l = r0.h << 12 (S);  // арифметический сдвиг влево
r5 = r2 << 24(S);       // арифметический сдвиг влево
 
r3.l = ashift r0.h by r7.l;      // сдвиг половины слова
r3.h = ashift r0.l by r7.l;
r3.h = ashift r0.h by r7.l;
r3.l = ashift r0.l by r7.l;
r3.l = ashift r0.h by r7.l(s);   // сдвиг половины слова с насыщением
r3.h = ashift r0.l by r7.l(s);   // сдвиг половины слова с насыщением
r3.h = ashift r0.h by r7.l(s);
r3.l = ashift r0.l by r7.l(s);
r4 = ashift r2 by r7.l;          // сдвиг слова
r4 = ashift r2 by r7.l(s);       // сдвиг слова с насыщением
A0 = ashift A0 by r7.l;          // сдвиг аккумулятора
A1 = ashift A1 by r7.l;          // сдвиг аккумулятора
                                 // Если r0.h = -64, то выполнение операции ...
r3.h = r0.h >>> 4;               // ... даст результат r3.h = -4 с сохранением знака.

См. также инструкции Vector Arithmetic Shift, Vector Logical Shift, Logical Shift, Shift with Add, Rotate.

Логический сдвиг. Общая форма:

dest_pntr = src_pntr >> 1

dest_pntr = src_pntr >> 2

dest_pntr = src_pntr << 1

dest_pntr = src_pntr << 2

dest_reg >>= shift_magnitude

dest_reg <<= shift_magnitude

dest_reg = src_reg >> shift_magnitude

dest_reg = src_reg << shift_magnitude

dest_reg = LSHIFT src_reg BY shift_magnitude

Синтаксис сдвига на фиксированное количество бит:

Preg = Preg >> 1;                 // сдвиг вправо на 1 бит (a)1

Preg = Preg >> 2;                 // сдвиг вправо на 2 бита (a)

Preg = Preg << 1;                 // сдвиг влево на 1 бит (a)

Preg = Preg << 2;                 // сдвиг влево на 2 бита (a)

Синтаксис сдвига на количество бит, указанное в константе команды:

Dreg >>= uimm5;                   // сдвиг вправо (a)

Dreg << = uimm5;                  // сдвиг влево (a)

Dreg_lo_hi = Dreg_lo_hi >> uimm4; // сдвиг вправо (b)

Dreg_lo_hi = Dreg_lo_hi << uimm4; // сдвиг влево (b)

Dreg = Dreg >> uimm5;             // сдвиг вправо (b)

Dreg = Dreg << uimm5;             // сдвиг влево (b)

A0 = A0 >> uimm5;                 // сдвиг вправо (b)

A0 = A0 << uimm5;                 // сдвиг влево (b)

A1 = A1 << uimm5;                 // сдвиг влево (b)

A1 = A1 >> uimm5;                 // сдвиг вправо (b)

Сдвиг данных, величина сдвига указана в регистре:

Dreg >>= Dreg;                    // сдвиг вправо (a)

Dreg << = Dreg;                   // сдвиг влево (a)

Dreg_lo_hi = LSHIFT Dreg_lo_hi BY Dreg_lo; // (b)

Dreg = LSHIFT Dreg BY Dreg_lo;    // (b)

A0 = LSHIFT A0 BY Dreg_lo;        // (b)

A1 = LSHIFT A1 BY Dreg_lo;        // (b)

Примечание 1: в синтаксисе комментарий (a) показывает длину инструкции 16 бит. Комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

Dreg_lo: половинки регистров R0.L, ..., R7.L.

Dreg_lo_hi: половинки регистров R0.L, ..., R7.L, R0.H, ..., R7.H.

Preg: P0, ..., P5.

uimm4: 4-битное беззнаковое поле в диапазоне 0 .. 15.

uimm5: 5-битное беззнаковое поле в диапазоне 0 .. 31.

[Функциональное описание]

Инструкции логического сдвига (Logical Shift) сдвигают число в регистре на указанную величину бит (distance) в указанном направлении. Логические сдвиги отбрасывают выдвигаемые биты, заполняя нулями освобождающиеся разряды.

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

Остальная часть этого описания относится к версиям инструкции для сдвига данных в D-регистрах и аккумуляторах.

Инструкции логического сдвига могут быть длиной 16 и 32 бита.

• Инструкции синтаксиса >>= и << = с длиной 16 бит позволяют экономить место под код ценой уменьшения гибкости.
• Инструкции синтаксиса >>, << и LSHIFT с длиной 32 бита предоставляют отдельные регистры для данных источника и назначения, альтернативные размеры данных и возможность параллельного выполнения вместе с инструкциями загрузки / сохранения (Load / Store).

Оба синтаксиса поддерживают диапазоны сдвига, указанные как константой в команде, так и в регистре.

Таблица 9-2. Арифметические сдвиги.

Синтаксис Описание
>>= и << = Значение в dest_reg сдвигается на указанное число бит в shift_magnitude. Размер сдвигаемых данных всегда 32 бита. Все 32 бита значения shift_magnitude определяют величину сдвига. Магнитуда сдвига больше 0x1F даст в результате 0x00000000.
>>, << и LSHIFT Значение в src_reg сдвигается на количество бит, указанное в shift_magnitude, и результат сохраняется в dest_reg. Версии с LSHIFT могут сдвигать 32-битный Dreg и 40-битный аккумулятор на диапазон -32 .. 31 бита; диапазон сдвига определяется младшими 6 битами (с расширением знаком) значения shift_magnitude.

Для версия LSHIFT знак магнитуды сдвига определяет направление сдвига.

• Положительная магнитуда сдвига будет делать сдвиг ВЛЕВО.
• Отрицательная магнитуда сдвига будет делать сдвиг ВПРАВО.

Регистры dest_reg и src_reg могут быть 16-, 32- или 40-битными регистрами.

Для инструкции LSHIFT магнитуда сдвига определяется младшими 6 битами Dreg_lo, с расширением знаком. Инструкции Dreg >>= Dreg и Dreg << = Dreg используют для сдвига всю 32-битную магнитуду.

Версии этой инструкции с D-регистром сдвигают 16 или 32 бита для регистров полуслова и слова соответственно. Версии с аккумулятором сдвигают все 40 бит этих регистров на диапазон -32 .. +31 бит.

Магнитуды сдвига, которые превысят размер регистра назначения, дадут в качестве результата 0. Например, если значение 16-битного регистра будет сдвинуто 20 раз (это допустимая операция), то результат будет 0x00000000.

Сдвиг с нулевой магнитудой не делает никакого сдвига.

Версии этой инструкции с D-регистром не делают неявную модификацию значения в регистре src_reg (регистр источника). Однако опционально dest_reg может быть тем же самым D-регистром, что и src_reg, в этом случае инструкция явно изменит регистр источника .

[Флаги]

Версии этой инструкции с P-регистром не влияют ни на какие флаги.

Версии этой инструкции, которые посылают результат в Dreg, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• V очистится.

Все другие флаги не поменяют свое значение.

Версии этой инструкции, которые посылают результат в аккумулятор A0, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AV0 очистится.

Все другие флаги не поменяют свое значение.

Версии этой инструкции, которые посылают результат в аккумулятор A1, меняют следующие флаги:

• AZ установится, если результат будет 0, иначе очистится.
• AN установится, если результат отрицательный, иначе очистится.
• AV1 очистится.

Все другие флаги не поменяют свое значение.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

32-битные инструкции могут быть выполнены параллельно с некоторыми 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций". 16-битные версии этих инструкций не могут быть выполнены параллельно с другими инструкциями.

[Примеры]

p3 = p2 >> 1;        // сдвиг указателя вправо на 1
p3 = p3 >> 2;        // сдвиг указателя вправо на 2
p4 = p5 << 1;        // сдвиг указателя влево на 1
p0 = p1 << 2;        // сдвиг указателя влево на 2
r3 >>= 17;           // сдвиг данных вправо
r3 <<= 17;           // сдвиг данных влево
r3.l = r0.l >> 4;    // сдвиг данных вправо в половине регистра
r3.l = r0.h >> 4;    /* то же самое; могут быть выбраны любые
                        комбинации половинок регистра */
r3.h = r0.l << 12;   // сдвиг данных влево в половине регистра
r3.h = r0.h << 14;   /* то же самое; могут быть выбраны любые
                        комбинации половинок регистра */
r3 = r6 >> 4;        // сдвиг вправо 32-разрядного слова
r3 = r6 << 4;        // сдвиг влево 32-разрядного слова
a0 = a0 >> 7;        // сдвиг вправо аккумулятора
a1 = a1 >> 25;       // сдвиг вправо аккумулятора
a0 = a0 << 7;        // сдвиг влево аккумулятора
a1 = a1 << 14;       // сдвиг влево аккумулятора
r3 >>= r0;           // сдвиг данных вправо
r3 <<= r1;           // сдвиг данных влево
r3.l = lshift r0.l by r2.l; // направление сдвига определяется знаком R2.L
r3.h = lshift r0.l by r2.l;
a0 = lshift a0 by r7.l;
a1 = lshift a1 by r7.l;
                           // Если r0.h = -64 (или 0xFFC0), то выполнение ...
r3.h = r0.h >> 4;          /* ... даст результат r3.h = 0x0FFC (или 4092),
                              знак числа будет потерян */

См. также инструкции Arithmetic Shift, Rotate, Shift with Add, Vector Arithmetic Shift, Vector Logical Shift.

Прокрутка через бит CC. Общая форма:

dest_reg = ROT src_reg BY rotate_magnitude

accumulator_new = ROT accumulator_old BY rotate_magnitude

Синтаксис прокрутки на количество бит, указанное в константе команды:

Dreg = ROT Dreg BY imm6;    // (b)1

A0 = ROT A0 BY imm6;        // (b)

A1 = ROT A1 BY imm6;        // (b)

Синтаксис прокрутки на количество бит, указанное в регистре:

Dreg = ROT Dreg BY Dreg_lo; // (b)

A0 = ROT A0 BY Dreg_lo;     // (b)

A1 = ROT A1 BY Dreg_lo;     // (b)

Примечание 1: в синтаксисе комментарий (b) показывает длину инструкции 32 бита.

[Терминология синтаксиса]

Dreg: регистры R0, ..., R7.

imm6: 6-битное поле со знаком, в диапазоне -32 .. 31.

[Функциональное описание]

Инструкция Rotate прокручивает по кольцу значение в регистре через бит CC на указанное количество бит в указанном направлении. Бит CC входит в кольцо прокрутки. Таким образом, первое значение, которое было вдвинуто в регистр, будет значением бита CC.

Ротация сдвигает все биты либо вправо, либо влево. Каждый бит, который выдвигается из регистра (это бит LSB для ротации вправо и бит MSB для ротации влево), сохраняется в бите CC, и значение бита CC сохраняется в освобождающейся позиции противоположного конца регистра.

Если ...

Blackfin rotate left func01

... то ротация влево на 1 бит даст результат:

Blackfin rotate left func02

Ротация влево еще на 1 бит даст результат:

Blackfin rotate left func03

Если ...

Blackfin rotate right func01

... то ротация вправо на 1 бит даст результат:

Blackfin rotate right func02

Ротация вправо еще на 1 бит даст результат:

Blackfin rotate right func03

Знак в значении магнитуды (magnitude, задает количество бит ротации) задает направление ротации:

• Положительное значение магнитуды задает ротацию ВЛЕВО.
• Отрицательное значение магнитуды задает ротацию ВПРАВО.

Допустимые значения магнитуды –32 .. +31, включая 0. Инструкция Rotate маскирует и игнорирует биты магнитуды, которые задают значение, больше разрешенного.

В отличие от операций сдвига, операция Rotate не теряет биты данных регистра-источника. Вместо этого биты перераспределяются по кругу. Однако последний выдвинутый бит попадает в бит CC, и не возвращается в регистр. Из-за того, что сдвиги выполняются сразу над всеми битами, не по одному, поворот в одном направлении или в другом не имеет каких-то определенных выгод. Например, ротация вправо на 2 бита не более эффективна, чем ротация влево на 30 бит. Оба метода дадут одинаковый результат, и будут выполнены за одинаковое время.

Версии инструкции с D-регистром делают ротацию всех 32 бит. Версии с аккумулятором делают ротацию всех 40 бит.

Версии с D-регистром не делают неявной модификации значения в регистре src_reg. Опционально dest_reg может быть тем же регистром, что и src_reg, в таком случае регистр исходных данных будет модифицирован.

[Флаги]

Инструкция влияет только на флаг CC: он будет содержать последнее значение, которое было в него вдвинуто.

Все другие флаги не поменяют свое значение.

[Требуемый режим]

Режим пользователя (User mode) и режим супервизора (Supervisor mode).

[Параллельное выполнение]

32-битные версии этой инструкции могут выполняться параллельно с некоторыми другими 16-битными инструкциями. Подробнее см. раздел "Параллельная обработка инструкций".

[Примеры]

r4 = rot r1 by 8;    // ротация влево
r4 = rot r1 by -5;   // ротация вправо
a0 = rot a0 by 22;   // ротация аккумулятора влево
a1 = rot a1 by -31;  // ротация аккумулятора вправо
r4 = rot r1 by r2.l;
a0 = rot a0 by r3.l;
a1 = rot a1 by r7.l;

См. также Arithmetic Shift, Logical Shift.

[Словарик]

DAG Data Address Generator, специальный аппаратный блок для генерации адреса [2].

Data Register регистр данных. К регистрам данных относят 32-битные регистры R0, R1, ..., R7, группа этих регистров сокращенно называется D-регистр или Dreg.

DSP Digital Signal Processing, цифровая обработка сигналов (ЦОС).

ISR Interrupt Service Routine, подпрограмма обработчика прерывания.

LFSR Linear feedback shift register, линейный регистр сдвига с обратной связью (см. [3]).

Load / Store группа инструкций, работающая с содержимым адресного пространства на чтение (Load) и запись (Store).

Load Pointer Register регистр указателя, в который заносится адрес ячейки памяти, куда осуществляется доступ на чтение.

MAC Multiply-And-Accumulate, операция умножения с накоплением. В контексте системы команд Blackfin данное сокращение связано с блоками Multiply-and-Accumulate Unit 0 (MAC0) и Multiply-and-Accumulate Unit 1 (MAC1), которыми работают некоторые команды.

MSA Micro Signal Architecture.

newline символ новой строки, LF ('\n', символ с кодом ASCII 0x0A). Часто идет в паре с символом перевода каретки CR ('\r, символ с кодом ASCII 0x0D).

NMI Not Masked Interrupt, немаскируемое прерывание. Это прерывание работает всегда, его нельзя отменить или запретить, и оно имеет самый высокий приоритет в системе после прерывания эмуляции.

PC Program Counter, программный счетчик, или счетчик адреса программы - специальный 32-битный регистр, который содержит абсолютный адрес текущей выполняемой инструкции.

Program Flow Control управление ходом программы - имеется в виду группа инструкций условного и безусловного перехода (JMP), вызова подпрограмм (CALL).

scratch-регистры регистры для хранения временных значений (например, локальных переменных).

SIMD (англ. single instruction, multiple data - одиночный поток команд, множественный поток данных) принцип компьютерных вычислений, позволяющий обеспечить параллелизм на уровне данных (из Википедии).

space символ пробела, код ASCII 0x20.

tab символ горизонтальной табуляции, код ASCII 0x09.

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

Video Pixel Operations специальный вид инструкций процессора, предназначенный для обработки графики видео. Рассматривается во второй части этого документа (см. [4]).

zero overhead loop дословно переводится как "цикл с нулевыми затратами". Быстрый цикл, обработка которого аппаратно поддерживается на уровне инструкций процессора.

Токен в данном контексте имеется в виду неделимая часть ассемблерной инструкции. К токенам относятся числа, имена регистров, ключевые слова, идентификаторы пользователей, а также многосимвольные коды комментариев или операций наподобие "+=", "/*" или "||".

[Ссылки]

1. Blackfin Instruction Set Reference site:analog.com.
2. Blackfin ADSP-BF538.
3. LFSR: генерация псевдослучайных чисел на регистре сдвига.
4Blackfin: система команд (ассемблер) - часть 2.

 

Добавить комментарий


Защитный код
Обновить

Top of Page