I am working with Visual C++ 6, all instructions using mm0 - mm7
registers work fine but it does not work when I try xmm registers.
By instance, when I'm debugging my program, at this instruction :
int p[2] = { 0x00000005, 0x00000000 } ;
__asm movd xmm0, p
I can see that the xmm0 register is not modified and it is the mm7
register which received the instruction !!!
So is ther any reason for that ?
So, are xmm registers really available in SSE instructions and how can
I find in Intel papers if an instruction is support only by SSE2, SSE1
or MMX ?
Hilaire VERSCHUERE
> So, are xmm registers really available in SSE instructions and how can
xmm register are available with sse.
> I find in Intel papers if an instruction is support only by SSE2, SSE1
> or MMX ?
Intel Architecture Software Developer's Manual, Volume 1; Chapter 6
> Hilaire VERSCHUERE
>
Note that most SSE-capable assemblers would (should) reject the 'movd xmm0,
p', as movd is a standard MMX instruction and not an SSE instruction.
movd mm0, p
stands for 'Move dword p into mmx register 0'.
movss xmm0, p
stands for 'Move scalar single single p into sse register 0'
Hilaire VERSCHUERE <hilaire.v...@netcourrier.com> wrote in message
news:ea8b66fd.03011...@posting.google.com...
Maybe they will, I haven't checked, but they shouldn't. Since "movd
xmm, r/m32" is certainly legal instruction, check the intel manual (part
2 - instruction reference).
MS compiler & Intel compiler will complile "movd xmm, m32" just fine.
Here's an extract of MOVD (page 3-414):
[start of extract]
MOVD-Move 32 Bits
Opcode Instruction Description
0F 6E /r MOVD mm, r/m32 Move doubleword from r/m32 to mm.
0F 7E /r MOVD r/m32, mm Move doubleword from mm to r/m32.
Description
This instruction copies doubleword from source operand (second operand) to
destination
operand (first operand). Source and destination operands can be MMXT
technology registers,
memory locations, or 32-bit general-purpose registers; however, data cannot
be transferred from
an MMXT technology register to another MMXT technology register, from one
memory location
to another memory location, or from one general-purpose register to another
general-purpose
register.
When the destination operand is an MMXT technology register, the 32-bit
source value is
written to the low-order 32 bits of the 64-bit MMXT technology register and
zero-extended to
64 bits (refer to Figure 3-41). When the source operand is an MMXT
technology register, the
low-order 32 bits of the MMXT technology register are written to the 32-bit
general-purpose
register or 32-bit memory location selected with the destination operand.
Operation
IF DEST is MMXT technology register
THEN
DEST <- ZeroExtend(SRC);
ELSE (* SRC is MMXT technology register *)
DEST <- LowOrderDoubleword(SRC);
[end of extract]
Here's an extract of MOVSS
[start of extract]
MOVSS-Move Scalar Single-FP
Opcode Instruction Description
F3,0F,10,/r MOVSS xmm1, xmm2/m32 Move 32 bits representing one scalar SP
operand from XMM2/Mem to XMM1 register.
F3,0F,11,/r MOVSS xmm2/m32, xmm1 Move 32 bits representing one scalar SP
operand from XMM1 register to XMM2/Mem.
Description
The linear address corresponds to the address of the least-significant byte
of the referenced
memory data. When a memory address is indicated, the four bytes of data at
memory location
m32 are loaded or stored. When the load form of this operation is used, the
32 bits from memory
are copied into the lower 32 bits of the 128-bit register xmm, the 96 most
significant bits being
cleared.
Operation
IF (destination = DEST) THEN
IF (SRC == m32) THEN(* load instruction *)
DEST[31-0] = m32;
DEST [63-32] = 0X00000000;
DEST [95-64] = 0X00000000;
DEST [127-96] = 0X00000000;
ELSE(* move instruction *)
DEST [31-0] = SRC[31-0];
DEST [63-32] = DEST [63-32];
DEST [95-64] = DEST [95-64];
DEST [127-96] = DEST [127-96];
FI
ELSE
IF (destination = m32) THEN(* store instruction *)
m32 = SRC[31-0];
ELSE (* move instruction *)
DEST [31-0] = SRC[31-0]
DEST [63-32] = DEST[63-32];
DEST [95-64] = DEST [95-64];
DEST [127-96] = DEST [127-96];
FI
FI
[end of extract]
Kreso Matejcic <kreso_...@mail.inet.hr> wrote in message
news:3E20066...@mail.inet.hr...
MOVSS: Move scalar single-precision floating-point
and I work only with integer values, it is for a MPEG 4 video decoder.
All SSE ( not SSE2 because it's for Pentium III ) instructions which use XMM
registers are almost only for floating point scalars, so, is it efficient to
use it with integer or is it better to use integer instructions on MMX
registers ?
I don't think but could someone confirm it ?
Hilaire VERSCHUERE
"Hilaire VERSCHUERE" <hilaire.v...@netcourrier.com> wrote in message
news:ea8b66fd.03011...@posting.google.com...
Go on, I dare you to prove that I, and the manual I got from Intel, are
wrong.
Kreso Matejcic <kreso_...@mail.inet.hr> wrote in message
news:3E20066...@mail.inet.hr...
SSE has floating-point instructions for 4x32-bit single-precision floats.
SSE2 has floating-point instructions for 2x64-bit double-precision floats.
So, the answer to your question:
If you want integer operations in SIMD, you are stuck with MMX.
Yes, the xmm registers are available in SSE, but the instruction you want
requires SSE 2 support (Pentium 4 only). Because of the way it's encoded,
processors that know about SSE and don't know about SSE 2 will decode it
incorrectly. To your processor without SSE 2 it looks -exactly- like "movd
mm0, p"
Someone else suggested movss -- try that instead. However, movss is going to
give you 4 bytes like movd, and it doesn't look like that's what you want.
The other caveat is that your variable p needs to be 16-byte aligned.
In VC:
int __declspec(align(16)) p[2] = { 0x00000005, 0x00000000 } ;
I usually use Intel manual 245471-6 for reference. It documents which
instructions are SSE and which are SSE 2. I also use the AMD x86-64 manuals
from time to time.
-Matt
I had to break out VC 7 and look at the assembly it generated to be sure. It
generates the "66 0F 6E /r" form of the movd instruction. Refer to manual
245471-6. Not only is this instruction valid, but it functions in an
identical manner to movss except it doesn't fault on misalignment. Yes,
movss faults if you are not 16-byte aligned.
The REAL culprit here is the fact that someone is working on an SSE without
SSE 2 implementation. The 66 prefix is perfectly valid, even on instructions
where it makes no sense. Until SSE 2 defined this opcode, the 66 prefix was
ignored, and it decoded as "0F 6E /r" which is the MMX form of movd. My
Athlon likewise makes this mistake. My Pentium 4 does not.
-Matt
> Where did you get it from?
current version of Intel's Software developer's manual Vol. 2
> The only MOVD I found in that manual is the one I was talking about.
>
Strange... try downloading a newer version of the manual.
[snip]
Title of chapter 5.6.3 (vol. 1), "SSE 64-bit SIMD Integer Instructions",
should give you some clue...
[snip]
Matt Taylor <pa...@tampabay.rr.com> wrote in message
news:gsAU9.119379$j8.31...@twister.tampabay.rr.com...
Hilaire VERSCHUERE
"Ben Peddell" <killer.l...@bigpond.com> wrote in message
news:truU9.23042$jM5....@newsfeeds.bigpond.com...
Actually, MOVSS does not require alignment -- MOVAPS does (packed
scalar move, and the 'A' is for "aligned"). If MOVSS required
alignment we wouldn't be able to access arrays of floats easily
because we'd always have to ensure the source address pointer was A16,
and that would cripple many useful algorithms.
Cameron