[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:
Adam Nemet 2014-07-17 17:04:50 +00:00
parent 4dc92b9a84
commit 54adb0fcbc
3 changed files with 16 additions and 62 deletions

View File

@ -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

View File

@ -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)

View File

@ -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>