diff options
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 7 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86CodeEmitter.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFormats.td | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 17 | ||||
-rw-r--r-- | test/MC/Disassembler/X86/simple-tests.txt | 24 | ||||
-rw-r--r-- | test/MC/Disassembler/X86/x86-32.txt | 12 | ||||
-rw-r--r-- | test/MC/X86/x86_64-bmi-encoding.s | 32 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 45 |
9 files changed, 137 insertions, 31 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 30ff1fd4aa..007e620cae 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -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. diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 91f672b1e4..8ae7a3c42a 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -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; diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index aeff03a89e..a15060462e 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -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; diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index d291e4385f..5b7adf311b 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -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, diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 4a5912dc36..1151b022f7 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -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. //===----------------------------------------------------------------------===// diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 03a9db6257..d540bfbd67 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -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 diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index 7e4e7083c3..d78232bbd6 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -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 diff --git a/test/MC/X86/x86_64-bmi-encoding.s b/test/MC/X86/x86_64-bmi-encoding.s index ba931d53d0..24acb01b67 100644 --- a/test/MC/X86/x86_64-bmi-encoding.s +++ b/test/MC/X86/x86_64-bmi-encoding.s @@ -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 diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index b3a316d6c7..68e03738cf 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -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: |