<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="../style/style.css" />
<title>PMADDWD: Multiply and Add Packed Integers (x86 Instruction Set Reference)</title>
</head>
<body>
<div class="main_container"><h1>x86 Instruction Set Reference</h1>
<title>PMADDWD: Multiply and Add Packed Integers (x86 Instruction Set Reference)</title>
<h1>PMADDWD</h1>
<h2>Multiply and Add Packed Integers</h2>
<object>
<table class="box">
<tr>
<th>Opcode</th>
<th>Mnemonic</th>
<th>Description</th>
</tr>
<tr>
<td class="grid"><code>0F F5 /r</code></td>
<td class="grid"><code>PMADDWD mm, mm/m64</code></td>
<td class="grid">Multiply the packed words in mm by the packed words in mm/m64, add adjacent doubleword results, and store in mm.</td>
</tr>
<tr>
<td class="grid"><code>66 0F F5 /r</code></td>
<td class="grid"><code>PMADDWD xmm1, xmm2/m128</code></td>
<td class="grid">Multiply the packed word integers in xmm1 by the packed word integers in xmm2/m128, add adjacent doubleword results, and store in xmm1.</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Description</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<p>Multiplies the individual signed words of the destination operand (first operand) by the corresponding signed words of the source operand (second operand), producing temporary signed, doubleword results. The adjacent doubleword results are then summed and stored in the destination operand. For example, the corresponding low-order words (15-0) and (31-16) in the source and destination operands are multiplied by one another and the doubleword results are added together and stored in the low doubleword of the destination register (31-0). The same operation is performed on the other pairs of adjacent words. (Figure 4-2 shows this operation when using 64-bit operands.) The source operand can be an MMX technology register or a 64- bit memory location, or it can be an XMM register or a 128-bit memory location. The destination operand can be an MMX technology register or an XMM register.</p>
<p>The PMADDWD instruction wraps around only in one situation: when the 2 pairs of words being operated on in a group are all 8000H. In this case, the result wraps around to 80000000H.</p>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Operation</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<pre><span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">64</span><span class="operator">)</span> {
<span class="comment">//PMADDWD instruction with 64-bit operands:</span>
Destination<span class="operator">[</span><span class="number">0..31</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">16..31</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">16..31</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
Destination<span class="operator">[</span><span class="number">32..63</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">32..47</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">32..47</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">48..63</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">48..63</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
}
<span class="keyword">else</span> {
<span class="comment">//PMADDWD instruction with 128-bit operands:</span>
Destination<span class="operator">[</span><span class="number">0..31</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">16..31</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">16..31</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
Destination<span class="operator">[</span><span class="number">32..63</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">32..47</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">32..47</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">48..63</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">48..63</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
Destination<span class="operator">[</span><span class="number">64..95</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">64..79</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">64..79</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">80..95</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">80..95</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
Destination<span class="operator">[</span><span class="number">96..127</span><span class="operator">]</span> <span class="operator">=</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">96..111</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">96..111</span><span class="operator">]</span><span class="operator">)</span> <span class="operator">+</span> <span class="operator">(</span>Destination<span class="operator">[</span><span class="number">112..127</span><span class="operator">]</span> <span class="operator">*</span> Source<span class="operator">[</span><span class="number">112..127</span><span class="operator">]</span><span class="operator">)</span><span class="operator">;</span>
}
</pre>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Flags affected</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<p>None.
</p>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Protected Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<div>
<table class="operations_table">
<tr><td><code>#GP(0)</code></td><td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. (128-bit operations only) If a memory operand is not aligned on a 16-byte boundary, regardless of segment.</td></tr>
<tr><td><code>#GP(0)</code></td><td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. (128-bit operations only) If a memory operand is not aligned on a 16-byte boundary, regardless of segment.</td></tr>
<tr><td><code>#SS(0)</code></td><td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr><td><code>#UD</code></td><td>If EM in CR0 is set. 128-bit operations will generate #UD only if OSFXSR in CR4 is 0. Execution of 128-bit instructions on a non-SSE2 capable processor (one that is MMX technology capable) will result in the instruction operating on the mm registers, not #UD.</td></tr>
<tr><td><code>#NM</code></td><td>If TS in CR0 is set.</td></tr>
<tr><td><code>#MF</code></td><td>(64-bit operations only) If there is a pending x87 FPU exception.</td></tr>
<tr><td><code>#PF(fault-code)</code></td><td>If a page fault occurs.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Real-Address Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<div>
<table class="operations_table">
<tr><td><code>#GP(0)</code></td><td>(128-bit operations only) If a memory operand is not aligned on a 16-byte boundary, regardless of segment. If any part of the operand lies outside of the effective address space from 0 to FFFFH.</td></tr>
<tr><td><code>#GP(0)</code></td><td>(128-bit operations only) If a memory operand is not aligned on a 16-byte boundary, regardless of segment. If any part of the operand lies outside of the effective address space from 0 to FFFFH.</td></tr>
<tr><td><code>#UD</code></td><td>If EM in CR0 is set. 128-bit operations will generate #UD only if OSFXSR in CR4 is 0. Execution of 128-bit instructions on a non-SSE2 capable processor (one that is MMX technology capable) will result in the instruction operating on the mm registers, not #UD.</td></tr>
<tr><td><code>#NM</code></td><td>If TS in CR0 is set.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Virtual-8086 Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
Same exceptions as in Real Address Mode
<div>
<table class="operations_table">
<tr><td><code>#PF(fault-code)</code></td><td>For a page fault.</td></tr>
<tr><td><code>#PF(fault-code)</code></td><td>For a page fault.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Numeric Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
None.
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Instruction</th>
<th>Latency</th>
<th>Throughput</th>
<th>Execution Unit</th>
</tr>
<tr><td class="grid"><code>CPUID</code></td><td class="grid">0F3n/0F2n/069n</td><td class="grid">0F3n/0F2n/069n</td><td class="grid">0F2n</td></tr>
<tr><td class="grid"><code>PMADDWD mm, mm</code></td><td class="grid">9/8/-</td><td class="grid">1/1/-</td><td class="grid">FP_MUL</td></tr>
<tr><td class="grid"><code>PMADDWD xmm, xmm</code></td><td class="grid">9/8/3+1</td><td class="grid">2/2/2</td><td class="grid">FP_MUL</td></tr>
</table>
</object>
</div>
</body>
</html>