From: Craig Topper Date: Sun, 23 Oct 2011 07:34:00 +0000 (+0000) Subject: Add X86 RORX instruction X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=75485d6746f8b5b23c17cf6d2364e7e1e0705992;p=oota-llvm.git Add X86 RORX instruction git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142741 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 007e620cae3..c50f7851727 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -301,6 +301,9 @@ namespace X86II { // T8XS - Prefix before and after 0x0F. Combination of T8 and XS. T8XS = 18 << Op0Shift, + // TAXD - Prefix before and after 0x0F. Combination of TA and XD. + TAXD = 19 << Op0Shift, + //===------------------------------------------------------------------===// // REX_W - REX prefixes are instruction prefixes used in 64-bit mode. // They are used to specify GPRs and SSE registers, 64-bit operand size, diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 8ae7a3c42af..1ab469cc009 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -472,6 +472,10 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, VEX_PP = 0x3; VEX_5M = 0x2; break; + case X86II::TAXD: // F2 0F 3A + VEX_PP = 0x3; + VEX_5M = 0x3; + break; case X86II::XS: // F3 0F VEX_PP = 0x2; break; @@ -802,6 +806,10 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, EmitByte(0xF2, CurByte, OS); Need0FPrefix = true; break; + case X86II::TAXD: // F2 0F 3A + EmitByte(0xF2, CurByte, OS); + Need0FPrefix = true; + break; case X86II::XS: // F3 0F EmitByte(0xF3, CurByte, OS); Need0FPrefix = true; @@ -838,6 +846,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, case X86II::T8: // 0F 38 EmitByte(0x38, CurByte, OS); break; + case X86II::TAXD: // F2 0F 3A case X86II::TA: // 0F 3A EmitByte(0x3A, CurByte, OS); break; diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index a15060462e5..d94ba331fb1 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -656,6 +656,7 @@ void Emitter::emitInstruction(MachineInstr &MI, Need0FPrefix = true; break; case X86II::T8XD: // F2 0F 38 + case X86II::TAXD: // F2 0F 3A case X86II::XD: // F2 0F MCE.emitByte(0xF2); Need0FPrefix = true; @@ -686,6 +687,7 @@ void Emitter::emitInstruction(MachineInstr &MI, case X86II::T8: // 0F 38 MCE.emitByte(0x38); break; + case X86II::TAXD: // F2 0F 38 case X86II::TA: // 0F 3A MCE.emitByte(0x3A); break; diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index 5b7adf311bd..5236dafd992 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -109,6 +109,7 @@ class A6 { bits<5> Prefix = 15; } class A7 { bits<5> Prefix = 16; } class T8XD { bits<5> Prefix = 17; } class T8XS { bits<5> Prefix = 18; } +class TAXD { bits<5> Prefix = 19; } class VEX { bit hasVEXPrefix = 1; } class VEX_W { bit hasVEX_WPrefix = 1; } class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; } diff --git a/lib/Target/X86/X86InstrShiftRotate.td b/lib/Target/X86/X86InstrShiftRotate.td index 8278568184f..a32f0665d30 100644 --- a/lib/Target/X86/X86InstrShiftRotate.td +++ b/lib/Target/X86/X86InstrShiftRotate.td @@ -744,3 +744,24 @@ def SHRD64mri8 : RIi8<0xAC, MRMDestMem, } // Defs = [EFLAGS] +let Predicates = [HasBMI2], neverHasSideEffects = 1 in { + def RORX32ri : Ii8<0xF0, MRMSrcReg, (outs GR32:$dst), + (ins GR32:$src1, i8imm:$src2), + "rorx{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, + TAXD, VEX; + let mayLoad = 1 in + def RORX32mi : Ii8<0xF0, MRMSrcMem, (outs GR32:$dst), + (ins i32mem:$src1, i8imm:$src2), + "rorx{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, + TAXD, VEX; + + def RORX64ri : Ii8<0xF0, MRMSrcReg, (outs GR64:$dst), + (ins GR64:$src1, i8imm:$src2), + "rorx{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, + TAXD, VEX, VEX_W; + let mayLoad = 1 in + def RORX64mi : Ii8<0xF0, MRMSrcMem, (outs GR64:$dst), + (ins i64mem:$src1, i8imm:$src2), + "rorx{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, + TAXD, VEX, VEX_W; +} diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 23c30f8f459..229c10dc1d7 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -599,3 +599,15 @@ # CHECK: mulxq (%rax), %r11, %r10 0xc4 0x62 0xa3 0xf6 0x10 + +# CHECK: rorxl $1, %r12d, %r10d +0xc4 0x43 0x7b 0xf0 0xd4 0x01 + +# CHECK: rorxl $31, (%rax), %r10d +0xc4 0x63 0x7b 0xf0 0x10 0x1f + +# CHECK: rorxq $1, %r12, %r10 +0xc4 0x43 0xfb 0xf0 0xd4 0x01 + +# CHECK: rorxq $63, (%rax), %r10 +0xc4 0x63 0xfb 0xf0 0x10 0x3f diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index b01c4eff5cc..10d3c1fea6c 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -543,3 +543,9 @@ # CHECK: mulxl (%eax), %ecx, %edx 0xc4 0xe2 0xf3 0xf6 0x10 + +# CHECK: rorxl $1, %esp, %edx +0xc4 0xe3 0x7b 0xf0 0xd4 0x01 + +# CHECK: rorxl $31, (%eax), %edx +0xc4 0xe3 0x7b 0xf0 0x10 0x1f diff --git a/test/MC/X86/x86_64-bmi-encoding.s b/test/MC/X86/x86_64-bmi-encoding.s index 005ded2a1b0..aa5aa9aa202 100644 --- a/test/MC/X86/x86_64-bmi-encoding.s +++ b/test/MC/X86/x86_64-bmi-encoding.s @@ -119,3 +119,35 @@ // CHECK: pdepq (%rax), %r11, %r10 // CHECK: encoding: [0xc4,0x62,0xa3,0xf5,0x10] pdepq (%rax), %r11, %r10 + +// CHECK: mulxl %r12d, %r11d, %r10d +// CHECK: encoding: [0xc4,0x42,0x23,0xf6,0xd4] + mulxl %r12d, %r11d, %r10d + +// CHECK: mulxl (%rax), %r11d, %r10d +// CHECK: encoding: [0xc4,0x62,0x23,0xf6,0x10] + mulxl (%rax), %r11d, %r10d + +// CHECK: mulxq %r12, %r11, %r10 +// CHECK: encoding: [0xc4,0x42,0xa3,0xf6,0xd4] + mulxq %r12, %r11, %r10 + +// CHECK: mulxq (%rax), %r11, %r10 +// CHECK: encoding: [0xc4,0x62,0xa3,0xf6,0x10] + mulxq (%rax), %r11, %r10 + +// CHECK: rorxl $10, %r12d, %r10d +// CHECK: encoding: [0xc4,0x43,0x7b,0xf0,0xd4,0x0a] + rorxl $10, %r12d, %r10d + +// CHECK: rorxl $31, (%rax), %r10d +// CHECK: encoding: [0xc4,0x63,0x7b,0xf0,0x10,0x1f] + rorxl $31, (%rax), %r10d + +// CHECK: rorxq $1, %r12, %r10 +// CHECK: encoding: [0xc4,0x43,0xfb,0xf0,0xd4,0x01] + rorxq $1, %r12, %r10 + +// CHECK: rorxq $63, (%rax), %r10 +// CHECK: encoding: [0xc4,0x63,0xfb,0xf0,0x10,0x3f] + rorxq $63, (%rax), %r10 diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 68e03738cff..d4c9629226f 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, T8XD = 17, T8XS = 18 + A6 = 15, A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19 }; } @@ -296,20 +296,23 @@ InstructionContext RecognizableInstr::insnContext() const { else if (HasVEX_LPrefix && (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) insnContext = IC_VEX_L_XS; - else if (HasVEX_LPrefix && - (Prefix == X86Local::XD || Prefix == X86Local::T8XD)) + else if (HasVEX_LPrefix && (Prefix == X86Local::XD || + Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD)) insnContext = IC_VEX_L_XD; else if (HasVEX_WPrefix && (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) insnContext = IC_VEX_W_XS; - else if (HasVEX_WPrefix && - (Prefix == X86Local::XD || Prefix == X86Local::T8XD)) + else if (HasVEX_WPrefix && (Prefix == X86Local::XD || + Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD)) 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 || Prefix == X86Local::T8XD) + else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD) insnContext = IC_VEX_XD; else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) insnContext = IC_VEX_XS; @@ -318,8 +321,9 @@ InstructionContext RecognizableInstr::insnContext() const { } else if (Is64Bit || HasREX_WPrefix) { if (HasREX_WPrefix && HasOpSizePrefix) insnContext = IC_64BIT_REXW_OPSIZE; - else if (HasOpSizePrefix && - (Prefix == X86Local::XD || Prefix == X86Local::T8XD)) + else if (HasOpSizePrefix && (Prefix == X86Local::XD || + Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD)) insnContext = IC_64BIT_XD_OPSIZE; else if (HasOpSizePrefix && (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) @@ -329,10 +333,12 @@ InstructionContext RecognizableInstr::insnContext() const { else if (HasREX_WPrefix && (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) insnContext = IC_64BIT_REXW_XS; - else if (HasREX_WPrefix && - (Prefix == X86Local::XD || Prefix == X86Local::T8XD)) + else if (HasREX_WPrefix && (Prefix == X86Local::XD || + Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD)) insnContext = IC_64BIT_REXW_XD; - else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD) + else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD) insnContext = IC_64BIT_XD; else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS) insnContext = IC_64BIT_XS; @@ -341,15 +347,17 @@ InstructionContext RecognizableInstr::insnContext() const { else insnContext = IC_64BIT; } else { - if (HasOpSizePrefix && - (Prefix == X86Local::XD || Prefix == X86Local::T8XD)) + if (HasOpSizePrefix && (Prefix == X86Local::XD || + Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD)) insnContext = IC_XD_OPSIZE; 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::T8XD) + else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || + Prefix == X86Local::TAXD) insnContext = IC_XD; else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS || Prefix == X86Local::REP) @@ -908,6 +916,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { opcodeToSet = Opcode; break; case X86Local::P_TA: + case X86Local::TAXD: opcodeType = THREEBYTE_3A; if (needsModRMForDecode(Form)) filter = new ModFilter(isRegFormat(Form));