Here is an example:
uses MMX; { include some predefined data types } const { tmmxword = array[0..3] of word;, declared by unit MMX } w1 : tmmxword = (111,123,432,4356); w2 : tmmxword = (4213,63456,756,4); var w3 : tmmxword; l : longint; begin if is_mmx_cpu then { is_mmx_cpu is exported from unit mmx } begin {$mmx+} { turn mmx on } w3:=w1+w2; {$mmx-} end else begin for i:=0 to 3 do w3[i]:=w1[i]+w2[i]; end; end.
One important point of MMX is the support of saturated operations. If a operation would cause an overflow, the value stays at the highest or lowest possible value for the data type: If you use byte values you get normally 250+12=6. This is very annoying when doing color manipulations or changing audio samples, when you have to do a word add and check if the value is greater than 255. The solution is saturation: 250+12 gives 255. Saturated operations are supported by the MMX unit. If you want to use them, you have simple turn the switch saturation on: $saturation+
Here is an example:
Program SaturationDemo; { example for saturation, scales data (for example audio) with 1.5 with rounding to negative infinity } var audio1 : tmmxword; const helpdata1 : tmmxword = ($c000,$c000,$c000,$c000); helpdata2 : tmmxword = ($8000,$8000,$8000,$8000); begin { audio1 contains four 16 bit audio samples } {$mmx+} { convert it to $8000 is defined as zero, multiply data with 0.75 } audio1:=tmmxfixed16(audio1+helpdata2)*tmmxfixed(helpdata1); {$saturation+} { avoid overflows (all values>$7fff becomes $ffff) } audio1:=(audio1+helpdata2)-helpdata2; {$saturation-} { now mupltily with 2 and change to integer } audio1:=(audio1 shl 1)-helpdata2; {$mmx-} end.
In the beginning of 1997 the MMX instructions were introduced in the Pentium processors, so multitasking systems wouldn't save the newly introduced MMX registers. To work around that problem, Intel mapped the MMX registers to the FPU register.
The consequence is that you can't mix MMX and floating point operations. After using MMX operations and before using floating point operations, you have to call the routine EMMS of the MMX unit. This routine restores the FPU registers.
Careful: The compiler doesn't warn if you mix floating point and MMX operations, so be careful.
The MMX instructions are optimized for multi media (what else?). So it isn't possible to perform each operation, some opertions give a type mismatch, see section for the supported MMX operations
An important restriction is that MMX operations aren't range or overflow checked, even when you turn range and overflow checking on. This is due to the nature of MMX operations.
The MMX unit must always be used when doing MMX operations because the exit code of this unit clears the MMX unit. If it wouldn't do that, other program will crash. A consequence of this is that you can't use MMX operations in the exit code of your units or programs, since they would interfere with the exit code of the MMX unit. The compiler can't check this, so you are responsible for this !
Still to be written...