<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>Using VEX_4V may not be the right fix since Intel guide says "Operand 3: VEX.vvvv"</div><div><br></div><div>I was talking about this section of code:</div><div>void RecognizableInstr::handleOperand(</div><div>  ...</div><div><div>  while (operandMapping[operandIndex] != operandIndex) {</div><div>    Spec->operands[operandIndex].encoding = ENCODING_DUP;</div><div>    Spec->operands[operandIndex].type =</div><div>      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);</div><div>    ++operandIndex;</div><div>  }</div></div><div>  …</div><div>}</div><div><br></div><div>void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {</div><div>...</div><div><div>  case X86Local::MRMSrcMem:</div><div>    // Operand 1 is a register operand in the Reg/Opcode field.</div><div>    // Operand 2 is a memory operand (possibly SIB-extended)</div><div>    // - In AVX, there is a register operand in the VEX.vvvv field here -</div><div>    // Operand 3 (optional) is an immediate.</div><div>   ...</div><div>    HANDLE_OPERAND(roRegister)</div><div><br></div><div>    if (HasVEX_4VPrefix)</div><div>      // FIXME: In AVX, the register below becomes the one encoded</div><div>      // in ModRMVEX and the one above the one in the VEX.VVVV field</div><div>      HANDLE_OPERAND(vvvvRegister)</div><div><br></div><div>    if (HasMemOp4Prefix)</div><div>      HANDLE_OPERAND(immediate)</div><div><br></div><div>    HANDLE_OPERAND(memory)</div><div><br></div><div>    if (HasVEX_4VOp3Prefix)</div><div>      HANDLE_OPERAND(vvvvRegister)</div></div><div>…</div><div>}</div><div><br></div><div>For GATHER with 5 operands (dst, mask_wb, src1, mem, mask), the operandMapping is "0 to 0, 1 to 1, 2 to 0, 3 to 3, 4 to 1", operand 2 is tied to operand 0, operand 4 is tied to operand 1.</div><div>So operand 2 and 4 (src1, mask) are treated as DUP, and the physical operands are 0,1,3(dst, mask_wb, mem), while MRSrcMem assumes Reg, Mem, Reg.vvvv if HasVEX_4VOp3Prefix is true.</div><div>Same situation happens in X86MCCodeEmitter.cpp, where TIED_TO for operand 2 is operand 0. We can only increment CurOp once for operand 2, since TIED_TO of operand 1 is -1.</div><div>What we really want is to reverse the direction of TIED_TO for mask and mask_wb.</div><div><br></div><div>We can probably hack this to handle the special case of two tied-to operands, if we have 2 tied-to operands, handle operand vvvvRegister first, then handle memory operand in MRMSrcMem.</div><div>In X86MCCodeEmitter.cpp, we increase CurOp twice if we have 2 tied-to operands. But it is kind of ugly.</div><div><div><br></div><div>+    // FIXME: Handle the special case for GATHER:</div><div>+    // For GATHER with 5 operands (dst, mask_wb, src1, mem, mask), src1 is tied</div><div>+    // to dst and mask is tied to mask_wb. The operandMapping is "0 to 0,</div><div>+    // 1 to 1, 2 to 0, 3 to 3, 4 to 1". The 2nd physical operand is mask_wb, and</div><div>+    // it is before mem, so we need to explicitly handle vvvvRegister first.</div><div>+    if (HasVEX_4VOp3Prefix && tiedOperandsCount >= 2)</div><div>+      HANDLE_OPERAND(vvvvRegister)</div><div>+</div></div><div><br></div><div>Thanks,</div><div>Manman</div><br><div><div>On Jul 9, 2012, at 11:47 PM, Craig Topper wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">I don't think changing to VEX_4VOp3 to VEX_4V is the right fix. I think 
the fix is to increment CurOp twice at the start for these instructions 
so that only the input operands are used for encoding.<br><br>Also, I just submitted a patch to revert the operand order for these instructions in the assembler/disassembler. Destination register should appear on the right and the mask should appear on the left as we use AT&T syntax by default. It will probably conflict with your updates here.<br>
<br><div class="gmail_quote">On Mon, Jul 9, 2012 at 11:24 PM, Manman Ren <span dir="ltr"><<a href="mailto:mren@apple.com" target="_blank">mren@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; "><br>
Yes, there is an easy way to fix this.<br>
MRMSrcMem assumes register, memory, vvvv register if VEX_4VOp3 is true and assumes register, vvvv register, memory if VEX_4V is true.<br>
<br>
I just need to change the flag from VEX_4VOp3 to VEX_4V. There are a few places where we assume only the 2nd operand can be tied-to:<br>
Desc->getOperandConstraint(1, MCOI::TIED_TO) != -1 (hard-coded index 1)<br>
I will fix those to handle this instruction.<br>
<br>
Thanks,<br>
Manman<br>
<div><div><br>
On Jul 9, 2012, at 10:07 PM, Evan Cheng wrote:<br>
<br>
><br>
><br>
> On Jul 9, 2012, at 4:15 PM, Manman Ren <<a href="mailto:mren@apple.com" target="_blank">mren@apple.com</a>> wrote:<br>
><br>
>><br>
>> I need to implement an instruction which has 2 read-write registers, so I added<br>
>> let Constraints = "$src1 = $dst, $mask = $mask_wb" in {<br>
>> ...<br>
>> def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),<br>
>>           (ins VR128:$src1, v128mem:$src2, VR128:$mask),<br>
>> ...<br>
>> }<br>
>> There is a problem since MRMSrcMem assumes the 2nd physical operand is a memory operand.<br>
>> See the section about MRMSrcMem in RecognizableInstr::emitInstructionSpecifier.<br>
><br>
> Can this be fixed?<br>
><br>
> Evan<br>
><br>
>> And the above gives us $dst, $mask_wb, $src1, $mem, $mask, and $mask_wb is the second physical operand.<br>
>><br>
>> I thought about using "$mask_wb = $mask", but it breaks the assumption of TIED_TO LhsIdx > RhsIdx.<br>
>> Is adding another addressing mode a good idea?<br>
>><br>
>> Any pointer is appreciated.<br>
>> Thanks,<br>
>> Manman<br>
>> _______________________________________________<br>
>> LLVM Developers mailing list<br>
>> <a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu/" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu/" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>~Craig<br>
</blockquote></div><br></body></html>