Отдельный набор инструкций предназначен специально для копирования чисел с плавающей точкой как одинарной, так и двойной точности.
Инструкции (v)movlps
и (v)movlpd
копирует данные в младшие 64 бита регистра или из 64 младших 64 бит регистра:
movlps xmm, mem64 movlps mem64, xmm vmovlps xmm, xmm, mem64 vmovlps mem64, xmm
Первая форма инструкции movlps
копирует пару значений с плавающей точкой одинарной точности в две первые 32-битные дорожки регистра XMM. Старшие 64 бита при этом остаются без изменений.
Вторая форма movlps копирует 64 бита первых 2 дорожек регистра XMM в указанную переменную. Функционально это эквивалентно инструкциям movq или movsd (поскольку они копируют 64 бита в память), хотя эта инструкция может быть немного быстрее, если младшие 64 бита регистра XMM на самом деле содержат два числа с плавающей точкой одинарной точности
Инструкция vmovlps
имеет три операнда: целевой регистр XMM, исходный регистр XMM и 64-разрядную переменную. Эта инструкция копирует два значения одинарной точности из переменной в младшие 64 бита целевого регистра XMM и старшие 64 бита исходного регистра (которые также содержат два значения одинарной точности) в старшие
64 бита целевого регистра.
Как и movsd
, инструкция movlpd
копирует младшие 64 бита (64-разрядное число с плавающей точкой) из второго операнда в младшие 64 бита операнда назначения. Разница в том, что инструкция movlpd не расширяет значение нулями при перемещении данных из памяти в регистр XMM, тогда как инструкция movsd расширяет значение нулями до старших 64 бит целевого регистра XMM, а также копируют старшие 64 бита регистра XMM в переменную:
Инструкции movhps
и movhpd
копируют 64-битную переменную (либо два числа с плавающей точкой одинарной точности в случае movhps,
либо одно число двойной точности в случае movhpd) в старшие 64 бита регистра XMM и обратно - из старших 64 битов XMM в 64-разрядную переменную.
movhps xmm, mem64 movhps mem64, xmm movhpd xmm, mem64 movhpd mem64, xmm
Эти инструкции не влияют на биты со 128 по 255 регистров YMM.
С помощью последовательного использования инструкций movlps
и movhps
можно загрузить четыре 32-разрядных числа с плавающей точкой в регистр XMM,
получая значения из двух разных источников (аналогично можно использовать инструкции movlpd
и movhpd
для загрузки из двух разных источников
двух 64-разрядных чисел в один регистр XMM). И наоборот, можно использовать данные инструкции, чтобы разделить векторный результат пополам и сохранить две половины в
разных переменных:
.data floats real4 1.0, 2.0 doubles real8 1.0 .code main proc movlps xmm0, qword ptr floats ; в младших 64 битах XMM0 - вектор floats movhpd xmm0, doubles ; в старших 64 битах XMM0 - вектор doubles ret main endp end
Отдельно стоит сказать об инструкциях vmovhps и vmovhpd, которые не являются простыми расширениями AVX для выше рассмотренных инструкций movhps
и movhpd
vmovhps xmm, xmm, mem64 vmovhps mem64, xmm vmovhpd xmm, xmm, mem64 vmovhpd mem64, xmm
При загрузке данных в регистр XMM эти инструкции принимают два операнда, из которых берутся данные. Инструкции загружают все 128 бит (четыре числа с одинарной точностью или два числа с двойной точностью) в регистр назначения XMM. Данные для старших 64 бит регистра поступают из переменной, а для младших 64 бит - из второго операнда-другого регистра XMM. Эти инструкции также расширяют значение нулями до старших 128 бит (перекрывающегося) регистра YMM.
При сохранении данных в 64-разрядной переменной инструкции vmovhps
и vmovhpd
ведут себя аналогично инструкциям movhps и movhpd.
Инструкция movlhps копирует два 32-битных значения с плавающей точкой из младших 64 бит исходного регистра XMM в старшие 64 бита целевого регистра XMM. Она оставляет младшие 64 бита целевого регистра XMM и старшие 128 бит перекрывающего регистра YMM без изменений.
movlhps xmm, xmm vmovlhps xmm, xmm, xmm
Инструкция vmovlhps принимает три операнда: первый операнд - целевой регистр, а второй и третий операнд - регистры XMM. из которых берутся данные.
vmovlhps
копирует младшие 64 бита из второго операнда в младшие 64 бита первого операнда и младшие 64 бита из тертьего операнда
в старшие 64 бита первого операнда. Инструкция расширяет нулями Старшие 128 бит перекрывающегося регистра YMM.
Данные инструкции не поддерживают работу с переменными и работают только с 32-разрядными числами с плавающей точкой.
Инструкции movhlps копирует два 32-битных числа с плавающей точкой из старших 64 бит исходного операнда в младшие 64 бита целевого регистра, оставляя старшие 64 бита целевого регистра без изменения.
movhlps xmmdest, xmmsrc
Инструкция vmovhlps принимает три операнда:
vmovhlps xmmdest, xmmsrc1, xmmsrc2
Эта инструкция копирует старшие 64 бита второго операнда в старшие 64 бита первого операнда и старшие 64 бита третьего операнда в младшие 64 бита первого операнда. Старшие 128 бит наложенного регистра YMM дополняются нулями.
Данные инструкции не поддерживают работу с переменными и работают только с 32-разрядными числами с плавающей точкой.
Инструкция movshdup копирует два 32-битных числа с плавающей точкой одинарной точности с нечетным индексом из исходного операнда (переменной или регистра XMM) и дублирует каждое число в целевом регистре XMM. Числа по четным индексам в исходном операнде игнорируются. Инструкция vmovshdup работает аналогично, только также может принимать регистры YMM - в этом случае копируются четыре 32-битных числа с плавающей точкой.
movshdup xmmdest, mem128/xmmsrc vmovshdup xmmdest, mem128/xmmsrc vmovshdup ymmdest, mem256/ymmsrc
Инструкция movsldup копирует и дублирует в целевом регистре XMM два 32-битных числа с плавающей точкой, которые располагаются на четных индексах в исходном регистре XMM или переменной. Аналогичным образом инструкция vmovsldup копирует и дублирует четыре 32-разрядных числа, которые располагаются на четных индексах в исходном регистре YMM или переменной.
movsldup xmmdest, mem128/xmmsrc vmovsldup xmmdest, mem128/xmmsrc vmovsldup ymmdest, mem256/ymmsrc
Инструкция movddup копирует 64-битные числа с плавающей точкой из младших 64 бит регистра XMM или переменной в младшие 64 бит целевого регистра XMM и затем дублирует это значение в старшие 64 бит целевого регистра XMM. Эта инструкция не влияет на старшие 128 бит перекрывающего регистра YMM.
movddup xmmdest, mem64/xmmsrc vmovddup xmmdest, mem64/xmmsrc vmovddup ymmdest, mem256/ymmsrc
128-битная версия инструкции vmovddup работает так же, как инструкция movddup
, за исключением того, что она обнуляет старшие
биты целевого регистра YMM. 256-битная версия копирует два 64-битных числа с четными индексами (0 и 2) из исходного регистра или переменной на соответствующие индексы
в целевом регистре YMM и дублирует эти значения по нечетным индексам в целевом регистре.
Инструкция (v)lddqu позволяет копировать невыравненное 128- и 256-разрядное значение:
lddqu xmmdest, mem128 vlddqu xmmdest, mem128 vlddqu ymmdest, mem256