From ccba8025da66cf2d757ece962d35b99ead062d46 Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Thu, 17 Jul 2014 17:04:34 +0000 Subject: [PATCH] [X86] AVX512: Move compressed displacement logic to TD This does not actually move the logic yet but reimplements it in the Tablegen language. Then asserts that the new implementation results in the same value. The next patch will remove the assert and the temporary use of the TSFlags and remove the C++ implementation. The formula requires a limited form of the logical left and right operators. I implemented these with the bit-extract/insert operator (i.e. blah{bits}). No functional change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213278 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 4 +++ lib/Target/X86/X86InstrFormats.td | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 7c30fc25ae0..df0778d3ce6 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -191,9 +191,11 @@ static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) { unsigned CD8E = (TSFlags >> X86II::EVEX_CD8EShift) & X86II::EVEX_CD8EMask; unsigned CD8V = (TSFlags >> X86II::EVEX_CD8VShift) & X86II::EVEX_CD8VMask; + unsigned CD8_Scale = (TSFlags >> 56) & 0x7f; if (CD8V == 0 && CD8E == 0) { CValue = Value; + assert(CD8_Scale == 0); return isDisp8(Value); } @@ -224,6 +226,8 @@ static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) { } } + assert(MemObjSize == CD8_Scale); + unsigned MemObjMask = MemObjSize - 1; assert((MemObjSize & MemObjMask) == 0 && "Invalid memory object size."); diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index cc302663d58..0b3e521ddea 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -184,13 +184,18 @@ class EVEX_KZ : EVEX_K { bit hasEVEX_Z = 1; } class EVEX_B { bit hasEVEX_B = 1; } class EVEX_RC { bit hasEVEX_RC = 1; } class EVEX_V512 { bit hasEVEX_L2 = 1; bit hasVEX_L = 0; } + +// Specify AVX512 8-bit compressed displacement encoding based on the vector +// element size in bits (8, 16, 32, 64) and the CDisp8 form. class EVEX_CD8 { bits<2> EVEX_CD8E = !if(!eq(esize, 8), 0b00, !if(!eq(esize, 16), 0b01, !if(!eq(esize, 32), 0b10, !if(!eq(esize, 64), 0b11, ?)))); + int CD8_EltSize = !srl(esize, 3); bits<3> EVEX_CD8V = form.Value; } + class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; } class MemOp4 { bit hasMemOp4Prefix = 1; } class XOP { Encoding OpEnc = EncXOP; } @@ -255,10 +260,31 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, bit hasEVEX_B = 0; // Does this inst set the EVEX_B field? bits<2> EVEX_CD8E = 0; // Compressed disp8 form - element-size. bits<3> EVEX_CD8V = 0; // Compressed disp8 form - vector-width. + // Declare it int rather than bits<4> so that all bits are defined when + // assigning to bits<7>. + int CD8_EltSize = 0; // Compressed disp8 form - element-size in bytes. bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding? bit hasMemOp4Prefix = 0; // Same bit as VEX_W, but used for swapping operands bit hasEVEX_RC = 0; // Explicitly specified rounding control in FP instruction. + bits<2> EVEX_LL; + let EVEX_LL{0} = hasVEX_L; + let EVEX_LL{1} = hasEVEX_L2; + // Vector size in bytes. + bits<7> VectSize = !shl(16, EVEX_LL); + + // The scaling factor for AVX512's compressed displacement is either + // - the size of a power-of-two number of elements or + // - the size of a single element for broadcasts or + // - the total vector size divided by a power-of-two number. + // Possible values are: 0 (non-AVX512 inst), 1, 2, 4, 8, 16, 32 and 64. + bits<7> CD8_Scale = !if (!eq (OpEnc.Value, EncEVEX.Value), + !if (EVEX_CD8V{2}, + !shl(CD8_EltSize, EVEX_CD8V{1-0}), + !if (hasEVEX_B, + CD8_EltSize, + !srl(VectSize, EVEX_CD8V{1-0}))), 0); + // TSFlags layout should be kept in sync with X86InstrInfo.h. let TSFlags{6-0} = FormBits; let TSFlags{8-7} = OpSizeBits; @@ -288,6 +314,10 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, let TSFlags{53} = has3DNow0F0FOpcode; let TSFlags{54} = hasMemOp4Prefix; let TSFlags{55} = hasEVEX_RC; + + // Temporarily make this available to the backend in order to assert that TD + // and C++ compute the same scaling value. + let TSFlags{62-56} = CD8_Scale; } class PseudoI pattern>