mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
Add X86 PEXTR and PDEP instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142141 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
962bad70f4
commit
ee62e4f6d1
@ -295,8 +295,11 @@ namespace X86II {
|
||||
T8 = 13 << Op0Shift, TA = 14 << Op0Shift,
|
||||
A6 = 15 << Op0Shift, A7 = 16 << Op0Shift,
|
||||
|
||||
// TF - Prefix before and after 0x0F
|
||||
TF = 17 << Op0Shift,
|
||||
// T8XD - Prefix before and after 0x0F. Combination of T8 and XD.
|
||||
T8XD = 17 << Op0Shift,
|
||||
|
||||
// T8XS - Prefix before and after 0x0F. Combination of T8 and XS.
|
||||
T8XS = 18 << Op0Shift,
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
|
||||
|
@ -464,7 +464,11 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
case X86II::TA: // 0F 3A
|
||||
VEX_5M = 0x3;
|
||||
break;
|
||||
case X86II::TF: // F2 0F 38
|
||||
case X86II::T8XS: // F3 0F 38
|
||||
VEX_PP = 0x2;
|
||||
VEX_5M = 0x2;
|
||||
break;
|
||||
case X86II::T8XD: // F2 0F 38
|
||||
VEX_PP = 0x3;
|
||||
VEX_5M = 0x2;
|
||||
break;
|
||||
@ -790,7 +794,11 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
case X86II::A7: // 0F A7
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::TF: // F2 0F 38
|
||||
case X86II::T8XS: // F3 0F 38
|
||||
EmitByte(0xF3, CurByte, OS);
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::T8XD: // F2 0F 38
|
||||
EmitByte(0xF2, CurByte, OS);
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
@ -825,7 +833,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
|
||||
// FIXME: Pull this up into previous switch if REX can be moved earlier.
|
||||
switch (TSFlags & X86II::Op0Mask) {
|
||||
case X86II::TF: // F2 0F 38
|
||||
case X86II::T8XS: // F3 0F 38
|
||||
case X86II::T8XD: // F2 0F 38
|
||||
case X86II::T8: // 0F 38
|
||||
EmitByte(0x38, CurByte, OS);
|
||||
break;
|
||||
|
@ -649,15 +649,13 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
case X86II::A7: // 0F A7
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::TF: // F2 0F 38
|
||||
MCE.emitByte(0xF2);
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::REP: break; // already handled.
|
||||
case X86II::T8XS: // F3 0F 38
|
||||
case X86II::XS: // F3 0F
|
||||
MCE.emitByte(0xF3);
|
||||
Need0FPrefix = true;
|
||||
break;
|
||||
case X86II::T8XD: // F2 0F 38
|
||||
case X86II::XD: // F2 0F
|
||||
MCE.emitByte(0xF2);
|
||||
Need0FPrefix = true;
|
||||
@ -683,7 +681,8 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
MCE.emitByte(0x0F);
|
||||
|
||||
switch (Desc->TSFlags & X86II::Op0Mask) {
|
||||
case X86II::TF: // F2 0F 38
|
||||
case X86II::T8XD: // F2 0F 38
|
||||
case X86II::T8XS: // F3 0F 38
|
||||
case X86II::T8: // 0F 38
|
||||
MCE.emitByte(0x38);
|
||||
break;
|
||||
|
@ -107,7 +107,8 @@ class T8 { bits<5> Prefix = 13; }
|
||||
class TA { bits<5> Prefix = 14; }
|
||||
class A6 { bits<5> Prefix = 15; }
|
||||
class A7 { bits<5> Prefix = 16; }
|
||||
class TF { bits<5> Prefix = 17; }
|
||||
class T8XD { bits<5> Prefix = 17; }
|
||||
class T8XS { bits<5> Prefix = 18; }
|
||||
class VEX { bit hasVEXPrefix = 1; }
|
||||
class VEX_W { bit hasVEX_WPrefix = 1; }
|
||||
class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
|
||||
@ -424,10 +425,10 @@ class SS428I<bits<8> o, Format F, dag outs, dag ins, string asm,
|
||||
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8,
|
||||
Requires<[HasSSE42]>;
|
||||
|
||||
// SS42FI - SSE 4.2 instructions with TF prefix.
|
||||
// SS42FI - SSE 4.2 instructions with T8XD prefix.
|
||||
class SS42FI<bits<8> o, Format F, dag outs, dag ins, string asm,
|
||||
list<dag> pattern>
|
||||
: I<o, F, outs, ins, asm, pattern>, TF, Requires<[HasSSE42]>;
|
||||
: I<o, F, outs, ins, asm, pattern>, T8XD, Requires<[HasSSE42]>;
|
||||
|
||||
// SS42AI = SSE 4.2 instructions with TA prefix
|
||||
class SS42AI<bits<8> o, Format F, dag outs, dag ins, string asm,
|
||||
|
@ -1443,6 +1443,23 @@ let Predicates = [HasBMI2], Defs = [EFLAGS] in {
|
||||
defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem>, VEX_W;
|
||||
}
|
||||
|
||||
multiclass bmi_pdep_pextr<string mnemonic, RegisterClass RC,
|
||||
X86MemOperand x86memop> {
|
||||
def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
|
||||
!strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
|
||||
[]>, VEX_4V;
|
||||
def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
|
||||
!strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
|
||||
[]>, VEX_4V;
|
||||
}
|
||||
|
||||
let Predicates = [HasBMI2] in {
|
||||
defm PDEP32 : bmi_pdep_pextr<"pdep{l}", GR32, i32mem>, T8XD;
|
||||
defm PDEP64 : bmi_pdep_pextr<"pdep{q}", GR64, i64mem>, T8XD, VEX_W;
|
||||
defm PEXTR32 : bmi_pdep_pextr<"pextr{l}", GR32, i32mem>, T8XS;
|
||||
defm PEXTR64 : bmi_pdep_pextr<"pextr{q}", GR64, i64mem>, T8XS, VEX_W;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Subsystems.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -563,3 +563,27 @@
|
||||
|
||||
# CHECK: bzhiq %r12, %r11, %r10
|
||||
0xc4 0x42 0x98 0xf5 0xd3
|
||||
|
||||
# CHECK: pextrl %r12d, %r11d, %r10d
|
||||
0xc4 0x42 0x22 0xf5 0xd4
|
||||
|
||||
# CHECK: pextrl (%rax), %r11d, %r10d
|
||||
0xc4 0x62 0x22 0xf5 0x10
|
||||
|
||||
# CHECK: pextrq %r12, %r11, %r10
|
||||
0xc4 0x42 0xa2 0xf5 0xd4
|
||||
|
||||
# CHECK: pextrq (%rax), %r11, %r10
|
||||
0xc4 0x62 0xa2 0xf5 0x10
|
||||
|
||||
# CHECK: pdepl %r12d, %r11d, %r10d
|
||||
0xc4 0x42 0x23 0xf5 0xd4
|
||||
|
||||
# CHECK: pdepl (%rax), %r11d, %r10d
|
||||
0xc4 0x62 0x23 0xf5 0x10
|
||||
|
||||
# CHECK: pdepq %r12, %r11, %r10
|
||||
0xc4 0x42 0xa3 0xf5 0xd4
|
||||
|
||||
# CHECK: pdepq (%rax), %r11, %r10
|
||||
0xc4 0x62 0xa3 0xf5 0x10
|
||||
|
@ -519,3 +519,15 @@
|
||||
|
||||
# CHECK: bzhil %esi, %ebx, %edx
|
||||
0xc4 0xe2 0x08 0xf5 0xd3
|
||||
|
||||
# CHECK: pextrl %esp, %ecx, %edx
|
||||
0xc4 0xe2 0x72 0xf5 0xd4
|
||||
|
||||
# CHECK: pextrl (%eax), %ecx, %edx
|
||||
0xc4 0xe2 0x72 0xf5 0x10
|
||||
|
||||
# CHECK: pdepl %esp, %ecx, %edx
|
||||
0xc4 0xe2 0x73 0xf5 0xd4
|
||||
|
||||
# CHECK: pdepl (%eax), %ecx, %edx
|
||||
0xc4 0xe2 0x73 0xf5 0x10
|
||||
|
@ -87,3 +87,35 @@
|
||||
// CHECK: bzhiq %r12, %r11, %r10
|
||||
// CHECK: encoding: [0xc4,0x42,0x98,0xf5,0xd3]
|
||||
bzhiq %r12, %r11, %r10
|
||||
|
||||
// CHECK: pextrl %r12d, %r11d, %r10d
|
||||
// CHECK: encoding: [0xc4,0x42,0x22,0xf5,0xd4]
|
||||
pextrl %r12d, %r11d, %r10d
|
||||
|
||||
// CHECK: pextrl (%rax), %r11d, %r10d
|
||||
// CHECK: encoding: [0xc4,0x62,0x22,0xf5,0x10]
|
||||
pextrl (%rax), %r11d, %r10d
|
||||
|
||||
// CHECK: pextrq %r12, %r11, %r10
|
||||
// CHECK: encoding: [0xc4,0x42,0xa2,0xf5,0xd4]
|
||||
pextrq %r12, %r11, %r10
|
||||
|
||||
// CHECK: pextrq (%rax), %r11, %r10
|
||||
// CHECK: encoding: [0xc4,0x62,0xa2,0xf5,0x10]
|
||||
pextrq (%rax), %r11, %r10
|
||||
|
||||
// CHECK: pdepl %r12d, %r11d, %r10d
|
||||
// CHECK: encoding: [0xc4,0x42,0x23,0xf5,0xd4]
|
||||
pdepl %r12d, %r11d, %r10d
|
||||
|
||||
// CHECK: pdepl (%rax), %r11d, %r10d
|
||||
// CHECK: encoding: [0xc4,0x62,0x23,0xf5,0x10]
|
||||
pdepl (%rax), %r11d, %r10d
|
||||
|
||||
// CHECK: pdepq %r12, %r11, %r10
|
||||
// CHECK: encoding: [0xc4,0x42,0xa3,0xf5,0xd4]
|
||||
pdepq %r12, %r11, %r10
|
||||
|
||||
// CHECK: pdepq (%rax), %r11, %r10
|
||||
// CHECK: encoding: [0xc4,0x62,0xa3,0xf5,0x10]
|
||||
pdepq (%rax), %r11, %r10
|
||||
|
@ -68,7 +68,7 @@ namespace X86Local {
|
||||
DC = 7, DD = 8, DE = 9, DF = 10,
|
||||
XD = 11, XS = 12,
|
||||
T8 = 13, P_TA = 14,
|
||||
A6 = 15, A7 = 16, TF = 17
|
||||
A6 = 15, A7 = 16, T8XD = 17, T8XS = 18
|
||||
};
|
||||
}
|
||||
|
||||
@ -293,21 +293,25 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||
insnContext = IC_VEX_W_OPSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_VEX_OPSIZE;
|
||||
else if (HasVEX_LPrefix && Prefix == X86Local::XS)
|
||||
else if (HasVEX_LPrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_VEX_L_XS;
|
||||
else if (HasVEX_LPrefix && Prefix == X86Local::XD)
|
||||
else if (HasVEX_LPrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::T8XD))
|
||||
insnContext = IC_VEX_L_XD;
|
||||
else if (HasVEX_WPrefix && Prefix == X86Local::XS)
|
||||
else if (HasVEX_WPrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_VEX_W_XS;
|
||||
else if (HasVEX_WPrefix && Prefix == X86Local::XD)
|
||||
else if (HasVEX_WPrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::T8XD))
|
||||
insnContext = IC_VEX_W_XD;
|
||||
else if (HasVEX_WPrefix)
|
||||
insnContext = IC_VEX_W;
|
||||
else if (HasVEX_LPrefix)
|
||||
insnContext = IC_VEX_L;
|
||||
else if (Prefix == X86Local::XD)
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
|
||||
insnContext = IC_VEX_XD;
|
||||
else if (Prefix == X86Local::XS)
|
||||
else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
|
||||
insnContext = IC_VEX_XS;
|
||||
else
|
||||
insnContext = IC_VEX;
|
||||
@ -315,20 +319,22 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||
if (HasREX_WPrefix && HasOpSizePrefix)
|
||||
insnContext = IC_64BIT_REXW_OPSIZE;
|
||||
else if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::T8XD))
|
||||
insnContext = IC_64BIT_XD_OPSIZE;
|
||||
else if (HasOpSizePrefix && Prefix == X86Local::XS)
|
||||
else if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_64BIT_XS_OPSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_64BIT_OPSIZE;
|
||||
else if (HasREX_WPrefix && Prefix == X86Local::XS)
|
||||
else if (HasREX_WPrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_64BIT_REXW_XS;
|
||||
else if (HasREX_WPrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::T8XD))
|
||||
insnContext = IC_64BIT_REXW_XD;
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
|
||||
insnContext = IC_64BIT_XD;
|
||||
else if (Prefix == X86Local::XS)
|
||||
else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
|
||||
insnContext = IC_64BIT_XS;
|
||||
else if (HasREX_WPrefix)
|
||||
insnContext = IC_64BIT_REXW;
|
||||
@ -336,15 +342,17 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||
insnContext = IC_64BIT;
|
||||
} else {
|
||||
if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::T8XD))
|
||||
insnContext = IC_XD_OPSIZE;
|
||||
else if (HasOpSizePrefix && Prefix == X86Local::XS)
|
||||
else if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
|
||||
insnContext = IC_XS_OPSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_OPSIZE;
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
|
||||
insnContext = IC_XD;
|
||||
else if (Prefix == X86Local::XS || Prefix == X86Local::REP)
|
||||
else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS ||
|
||||
Prefix == X86Local::REP)
|
||||
insnContext = IC_XS;
|
||||
else
|
||||
insnContext = IC;
|
||||
@ -857,7 +865,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||
opcodeToSet = Opcode;
|
||||
break;
|
||||
case X86Local::T8:
|
||||
case X86Local::TF:
|
||||
case X86Local::T8XD:
|
||||
case X86Local::T8XS:
|
||||
opcodeType = THREEBYTE_38;
|
||||
switch (Opcode) {
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user