llvm.org GIT mirror llvm / 548abfc
Implement support for the bizarre 3DNow! encoding (which is unlike anything else in X86), and add support for pavgusb. This is apparently the only instruction (other than movsx) that is preventing ffmpeg from building with clang. If someone else is interested in banging out the rest of the 3DNow! instructions, it should be quite easy now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115466 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
6 changed file(s) with 78 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
1010 // floating point and also adds a few more random instructions for good measure.
1111 //
1212 //===----------------------------------------------------------------------===//
13
14 // FIXME: We don't support any intrinsics for these instructions yet.
15
16 class I3DNow o, Format F, dag outs, dag ins, string asm,
17 list pattern>
18 : I, TB, Requires<[Has3DNow]>,
19 Has3DNow0F0FOpcode {
20 // FIXME: The disassembler doesn't support 3DNow! yet.
21 let isAsmParserOnly = 1;
22 }
23
24
25 let Constraints = "$src1 = $dst" in {
26 // MMXI_binop_rm_int - Simple MMX binary operator based on intrinsic.
27 // When this is cleaned up, remove the FIXME from X86RecognizableInstr.cpp.
28 multiclass I3DNow_binop_rm opc, string Mnemonic> {
29 def rr : I3DNow
30 (ins VR64:$src1, VR64:$src2),
31 !strconcat(Mnemonic, "\t{$src2, $dst|$dst, $src2}"), []>;
32 def rm : I3DNow
33 (ins VR64:$src1, i64mem:$src2),
34 !strconcat(Mnemonic, "\t{$src2, $dst|$dst, $src2}"), []>;
35 }
36 }
37
38 defm PAVGUSB : I3DNow_binop_rm<0xBF, "pavgusb">;
39
40
41
42
43 // TODO: Add support for the rest of the 3DNow! and "3DNowA" instructions.
108108 class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
109109 class VEX_I8IMM { bit hasVEX_i8ImmReg = 1; }
110110 class VEX_L { bit hasVEX_L = 1; }
111 class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; }
111112
112113 class X86Inst opcod, Format f, ImmType i, dag outs, dag ins,
113114 string AsmStr, Domain d = GenericDomain>
141142 bit hasVEX_i8ImmReg = 0; // Does this inst requires the last source register
142143 // to be encoded in a immediate field?
143144 bit hasVEX_L = 0; // Does this inst uses large (256-bit) registers?
145 bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding?
144146
145147 // TSFlags layout should be kept in sync with X86InstrInfo.h.
146148 let TSFlags{5-0} = FormBits;
159161 let TSFlags{34} = hasVEX_4VPrefix;
160162 let TSFlags{35} = hasVEX_i8ImmReg;
161163 let TSFlags{36} = hasVEX_L;
164 let TSFlags{37} = has3DNow0F0FOpcode;
162165 }
163166
164167 class I o, Format f, dag outs, dag ins, string asm,
448448 OpcodeMask = 0xFF << OpcodeShift,
449449
450450 //===------------------------------------------------------------------===//
451 // VEX - The opcode prefix used by AVX instructions
451 /// VEX - The opcode prefix used by AVX instructions
452452 VEX = 1U << 0,
453453
454 // VEX_W - Has a opcode specific functionality, but is used in the same
455 // way as REX_W is for regular SSE instructions.
454 /// VEX_W - Has a opcode specific functionality, but is used in the same
455 /// way as REX_W is for regular SSE instructions.
456456 VEX_W = 1U << 1,
457457
458 // VEX_4V - Used to specify an additional AVX/SSE register. Several 2
459 // address instructions in SSE are represented as 3 address ones in AVX
460 // and the additional register is encoded in VEX_VVVV prefix.
458 /// VEX_4V - Used to specify an additional AVX/SSE register. Several 2
459 /// address instructions in SSE are represented as 3 address ones in AVX
460 /// and the additional register is encoded in VEX_VVVV prefix.
461461 VEX_4V = 1U << 2,
462462
463 // VEX_I8IMM - Specifies that the last register used in a AVX instruction,
464 // must be encoded in the i8 immediate field. This usually happens in
465 // instructions with 4 operands.
463 /// VEX_I8IMM - Specifies that the last register used in a AVX instruction,
464 /// must be encoded in the i8 immediate field. This usually happens in
465 /// instructions with 4 operands.
466466 VEX_I8IMM = 1U << 3,
467467
468 // VEX_L - Stands for a bit in the VEX opcode prefix meaning the current
469 // instruction uses 256-bit wide registers. This is usually auto detected if
470 // a VR256 register is used, but some AVX instructions also have this field
471 // marked when using a f256 memory references.
472 VEX_L = 1U << 4
468 /// VEX_L - Stands for a bit in the VEX opcode prefix meaning the current
469 /// instruction uses 256-bit wide registers. This is usually auto detected
470 /// if a VR256 register is used, but some AVX instructions also have this
471 /// field marked when using a f256 memory references.
472 VEX_L = 1U << 4,
473
474 /// Has3DNow0F0FOpcode - This flag indicates that the instruction uses the
475 /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents
476 /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction
477 /// storing a classifier in the imm8 field. To simplify our implementation,
478 /// we handle this by storeing the classifier in the opcode field and using
479 /// this flag to indicate that the encoder should do the wacky 3DNow! thing.
480 Has3DNow0F0FOpcode = 1U << 5
473481 };
474482
475483 // getBaseOpcodeFor - This function returns the "base" X86 opcode for the
348348 // no AVX version of the desired intructions is present, this is better for
349349 // incremental dev (without fallbacks it's easier to spot what's missing)
350350 def HasMMX : Predicate<"Subtarget->hasMMX() && !Subtarget->hasAVX()">;
351 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
352 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
351353 def HasSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
352354 def HasSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
353355 def HasSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
821821 if ((TSFlags >> 32) & X86II::VEX_4V)
822822 HasVEX_4V = true;
823823
824
824825 // Determine where the memory operand starts, if present.
825826 int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
826827 if (MemoryOperand != -1) MemoryOperand += CurOp;
830831 else
831832 EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
832833
834
833835 unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
836
837 if ((TSFlags >> 32) & X86II::Has3DNow0F0FOpcode)
838 BaseOpcode = 0x0F; // Weird 3DNow! encoding.
839
834840 unsigned SrcRegNum = 0;
835841 switch (TSFlags & X86II::FormMask) {
836842 case X86II::MRMInitReg:
9971003 }
9981004 }
9991005
1006 if ((TSFlags >> 32) & X86II::Has3DNow0F0FOpcode)
1007 EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS);
1008
10001009
10011010 #ifndef NDEBUG
10021011 // FIXME: Verify.
0 // RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
1
2 // PR8283
3
4 // CHECK: pavgusb %mm2, %mm1 # encoding: [0x0f,0x0f,0xca,0xbf]
5 pavgusb %mm2, %mm1
6
7 // CHECK: pavgusb 9(%esi,%edx), %mm3 # encoding: [0x0f,0x0f,0x5c,0x16,0x09,0
8 pavgusb 9(%esi,%edx), %mm3
9
10