forked from OSchip/llvm-project
[X86] AVX512: Use the TD version of CD8_Scale in the assembler
Passes the computed scaling factor in TSFlags rather than the old attributes. Also removes the C++ version of computing the scaling factor (MemObjSize) along with the asserts added by the previous patch. No functional change. llvm-svn: 213279
This commit is contained in:
parent
4dc92b9a84
commit
54adb0fcbc
|
@ -520,13 +520,9 @@ namespace X86II {
|
|||
// EVEX_B - Set if this instruction has EVEX.B field set.
|
||||
EVEX_B = 1U << 9,
|
||||
|
||||
// EVEX_CD8E - compressed disp8 form, element-size
|
||||
EVEX_CD8EShift = VEXShift + 10,
|
||||
EVEX_CD8EMask = 3,
|
||||
|
||||
// EVEX_CD8V - compressed disp8 form, vector-width
|
||||
EVEX_CD8VShift = EVEX_CD8EShift + 2,
|
||||
EVEX_CD8VMask = 7,
|
||||
// The scaling factor for the AVX512's 8-bit compressed displacement.
|
||||
CD8_Scale_Shift = VEXShift + 10,
|
||||
CD8_Scale_Mask = 127,
|
||||
|
||||
/// Has3DNow0F0FOpcode - This flag indicates that the instruction uses the
|
||||
/// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents
|
||||
|
@ -534,7 +530,7 @@ namespace X86II {
|
|||
/// storing a classifier in the imm8 field. To simplify our implementation,
|
||||
/// we handle this by storeing the classifier in the opcode field and using
|
||||
/// this flag to indicate that the encoder should do the wacky 3DNow! thing.
|
||||
Has3DNow0F0FOpcodeShift = EVEX_CD8VShift + 3,
|
||||
Has3DNow0F0FOpcodeShift = CD8_Scale_Shift + 7,
|
||||
Has3DNow0F0FOpcode = 1U << (Has3DNow0F0FOpcodeShift - VEXShift),
|
||||
|
||||
/// MemOp4 - Used to indicate swapping of operand 3 and 4 to be encoded in
|
||||
|
|
|
@ -189,51 +189,18 @@ static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) {
|
|||
X86II::EncodingShift == X86II::EVEX) &&
|
||||
"Compressed 8-bit displacement is only valid for EVEX inst.");
|
||||
|
||||
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) {
|
||||
unsigned CD8_Scale =
|
||||
(TSFlags >> X86II::CD8_Scale_Shift) & X86II::CD8_Scale_Mask;
|
||||
if (CD8_Scale == 0) {
|
||||
CValue = Value;
|
||||
assert(CD8_Scale == 0);
|
||||
return isDisp8(Value);
|
||||
}
|
||||
|
||||
unsigned ElemSize = 1U << CD8E;
|
||||
unsigned MemObjSize;
|
||||
// The unit of 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.
|
||||
if (CD8V & 4) {
|
||||
// Fixed vector length
|
||||
unsigned NumElems = 1U << (CD8V & 0x3);
|
||||
MemObjSize = ElemSize * NumElems;
|
||||
} else {
|
||||
// Modified vector length
|
||||
bool EVEX_b = (TSFlags >> X86II::VEXShift) & X86II::EVEX_B;
|
||||
if (EVEX_b)
|
||||
// Broadcast implies element size units.
|
||||
MemObjSize = ElemSize;
|
||||
else {
|
||||
unsigned EVEX_LL = ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) ? 1 : 0;
|
||||
EVEX_LL += ((TSFlags >> X86II::VEXShift) & X86II::EVEX_L2) ? 2 : 0;
|
||||
assert(EVEX_LL < 3 && "");
|
||||
|
||||
unsigned VectorByteSize = 1U << (EVEX_LL + 4);
|
||||
unsigned Divider = 1U << (CD8V & 0x3);
|
||||
MemObjSize = VectorByteSize / Divider;
|
||||
}
|
||||
}
|
||||
|
||||
assert(MemObjSize == CD8_Scale);
|
||||
|
||||
unsigned MemObjMask = MemObjSize - 1;
|
||||
assert((MemObjSize & MemObjMask) == 0 && "Invalid memory object size.");
|
||||
|
||||
if (Value & MemObjMask) // Unaligned offset
|
||||
unsigned Mask = CD8_Scale - 1;
|
||||
assert((CD8_Scale & Mask) == 0 && "Invalid memory object size.");
|
||||
if (Value & Mask) // Unaligned offset
|
||||
return false;
|
||||
Value /= (int)MemObjSize;
|
||||
Value /= (int)CD8_Scale;
|
||||
bool Ret = (Value == (signed char)Value);
|
||||
|
||||
if (Ret)
|
||||
|
|
|
@ -188,10 +188,6 @@ 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<int esize, CD8VForm form> {
|
||||
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;
|
||||
}
|
||||
|
@ -258,7 +254,6 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
|||
bit hasEVEX_Z = 0; // Does this inst set the EVEX_Z field?
|
||||
bit hasEVEX_L2 = 0; // Does this inst set the EVEX_L2 field?
|
||||
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>.
|
||||
|
@ -309,15 +304,11 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
|||
let TSFlags{45} = hasEVEX_Z;
|
||||
let TSFlags{46} = hasEVEX_L2;
|
||||
let TSFlags{47} = hasEVEX_B;
|
||||
let TSFlags{49-48} = EVEX_CD8E;
|
||||
let TSFlags{52-50} = EVEX_CD8V;
|
||||
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;
|
||||
// If we run out of TSFlags bits, it's possible to encode this in 3 bits.
|
||||
let TSFlags{54-48} = CD8_Scale;
|
||||
let TSFlags{55} = has3DNow0F0FOpcode;
|
||||
let TSFlags{56} = hasMemOp4Prefix;
|
||||
let TSFlags{57} = hasEVEX_RC;
|
||||
}
|
||||
|
||||
class PseudoI<dag oops, dag iops, list<dag> pattern>
|
||||
|
|
Loading…
Reference in New Issue