[llvm-commits] [llvm] r78508 - in /llvm/trunk: lib/Target/X86/X86CodeEmitter.cpp lib/Target/X86/X86InstrFormats.td lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/sse42.ll
Eric Christopher
echristo at apple.com
Sat Aug 8 14:55:08 PDT 2009
Author: echristo
Date: Sat Aug 8 16:55:08 2009
New Revision: 78508
URL: http://llvm.org/viewvc/llvm-project?rev=78508&view=rev
Log:
Add crc32 instruction and intrinsics. Add a new class of prefix
bytes for F2 0F 38 and propagate. Add a FIXME for a set
of possibilities which correspond to intrinsics already used.
New test.
Added:
llvm/trunk/test/CodeGen/X86/sse42.ll
Modified:
llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
llvm/trunk/lib/Target/X86/X86InstrFormats.td
llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.h
llvm/trunk/lib/Target/X86/X86InstrSSE.td
Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=78508&r1=78507&r2=78508&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Sat Aug 8 16:55:08 2009
@@ -517,6 +517,10 @@
case X86II::TA: // 0F 3A
Need0FPrefix = true;
break;
+ case X86II::TF: // F2 0F 38
+ MCE.emitByte(0xF2);
+ Need0FPrefix = true;
+ break;
case X86II::REP: break; // already handled.
case X86II::XS: // F3 0F
MCE.emitByte(0xF3);
@@ -548,6 +552,7 @@
MCE.emitByte(0x0F);
switch (Desc->TSFlags & X86II::Op0Mask) {
+ case X86II::TF: // F2 0F 38
case X86II::T8: // 0F 38
MCE.emitByte(0x38);
break;
Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=78508&r1=78507&r2=78508&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Sat Aug 8 16:55:08 2009
@@ -79,6 +79,7 @@
class XS { bits<4> Prefix = 12; }
class T8 { bits<4> Prefix = 13; }
class TA { bits<4> Prefix = 14; }
+class TF { bits<4> Prefix = 15; }
class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
string AsmStr>
@@ -229,6 +230,11 @@
list<dag> pattern>
: I<o, F, outs, ins, asm, pattern>, T8, Requires<[HasSSE42]>;
+// SS42FI - SSE 4.2 instructions with TF 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]>;
+
// X86-64 Instruction templates...
//
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=78508&r1=78507&r2=78508&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Aug 8 16:55:08 2009
@@ -2931,6 +2931,10 @@
case X86II::TA: // 0F 3A
Need0FPrefix = true;
break;
+ case X86II::TF: // F2 0F 38
+ ++FinalSize;
+ Need0FPrefix = true;
+ break;
case X86II::REP: break; // already handled.
case X86II::XS: // F3 0F
++FinalSize;
@@ -2966,6 +2970,9 @@
case X86II::TA: // 0F 3A
++FinalSize;
break;
+ case X86II::TF: // F2 0F 38
+ ++FinalSize;
+ break;
}
// If this is a two-address instruction, skip one of the register operands.
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=78508&r1=78507&r2=78508&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Sat Aug 8 16:55:08 2009
@@ -321,6 +321,9 @@
// T8, TA - Prefix after the 0x0F prefix.
T8 = 13 << Op0Shift, TA = 14 << Op0Shift,
+
+ // TF - Prefix before and after 0x0F
+ TF = 15 << Op0Shift,
//===------------------------------------------------------------------===//
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=78508&r1=78507&r2=78508&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Sat Aug 8 16:55:08 2009
@@ -3678,3 +3678,75 @@
(PCMPGTQrr VR128:$src1, VR128:$src2)>;
def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
(PCMPGTQrm VR128:$src1, addr:$src2)>;
+
+// crc intrinsic instruction
+// This set of instructions are only rm, the only difference is the size
+// of r and m.
+let Constraints = "$src1 = $dst" in {
+ def CRC32m8 : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
+ (ins GR32:$src1, i8mem:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_8 GR32:$src1,
+ (load addr:$src2)))]>, OpSize;
+ def CRC32r8 : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
+ (ins GR32:$src1, GR8:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_8 GR32:$src1, GR8:$src2))]>,
+ OpSize;
+ def CRC32m16 : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
+ (ins GR32:$src1, i16mem:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_16 GR32:$src1,
+ (load addr:$src2)))]>,
+ OpSize;
+ def CRC32r16 : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
+ (ins GR32:$src1, GR16:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_16 GR32:$src1, GR16:$src2))]>,
+ OpSize;
+ def CRC32m32 : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
+ (ins GR32:$src1, i32mem:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_32 GR32:$src1,
+ (load addr:$src2)))]>, OpSize;
+ def CRC32r32 : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
+ (ins GR32:$src1, GR32:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR32:$dst,
+ (int_x86_sse42_crc32_32 GR32:$src1, GR32:$src2))]>,
+ OpSize;
+ def CRC64m64 : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
+ (ins GR64:$src1, i64mem:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR64:$dst,
+ (int_x86_sse42_crc32_64 GR64:$src1,
+ (load addr:$src2)))]>,
+ OpSize, REX_W;
+ def CRC64r64 : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
+ (ins GR64:$src1, GR64:$src2),
+ "crc32 \t{$src2, $src1|$src1, $src2}",
+ [(set GR64:$dst,
+ (int_x86_sse42_crc32_64 GR64:$src1, GR64:$src2))]>,
+ OpSize, REX_W;
+
+ // TODO: These correspond to int_x86_sse42_crc32_8 but with a 64-bit src
+ // and dest, figure it out.
+ //def CRC64m8 : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
+ // (ins GR32:$src1, i8mem:$src2),
+ // "crc32 \t{$src2, $src1|$src1, $src2}",
+ // [(set GR64:$dst,
+ // (int_x86_sse42_crc32_8 GR64:$src1,
+ // (load addr:$src2)))]>,
+ // OpSize, REX_W;
+ //def CRC64r8 : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
+ // (ins GR64:$src1, GR8:$src2),
+ // "crc32 \t{$src2, $src1|$src1, $src2}",
+ // [(set GR64:$dst,
+ // (int_x86_sse42_crc32_8 GR32:$src1, GR8:$src2))]>,
+ // OpSize, REX_W;
+}
Added: llvm/trunk/test/CodeGen/X86/sse42.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse42.ll?rev=78508&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sse42.ll (added)
+++ llvm/trunk/test/CodeGen/X86/sse42.ll Sat Aug 8 16:55:08 2009
@@ -0,0 +1,38 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin9 -mattr=sse42 | FileCheck %s -check-prefix=X32
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 -mattr=sse42 | FileCheck %s -check-prefix=X64
+
+declare i32 @llvm.x86.sse42.crc32.8(i32, i8) nounwind
+declare i32 @llvm.x86.sse42.crc32.16(i32, i16) nounwind
+declare i32 @llvm.x86.sse42.crc32.32(i32, i32) nounwind
+
+define i32 @crc32_8(i32 %a, i8 %b) nounwind {
+ %tmp = call i32 @llvm.x86.sse42.crc32.8(i32 %a, i8 %b)
+ ret i32 %tmp
+; X32: _crc32_8:
+; X32: crc32 8(%esp), %eax
+
+; X64: _crc32_8:
+; X64: crc32 %sil, %eax
+}
+
+
+define i32 @crc32_16(i32 %a, i16 %b) nounwind {
+ %tmp = call i32 @llvm.x86.sse42.crc32.16(i32 %a, i16 %b)
+ ret i32 %tmp
+; X32: _crc32_16:
+; X32: crc32 8(%esp), %eax
+
+; X64: _crc32_16:
+; X64: crc32 %si, %eax
+}
+
+
+define i32 @crc32_32(i32 %a, i32 %b) nounwind {
+ %tmp = call i32 @llvm.x86.sse42.crc32.32(i32 %a, i32 %b)
+ ret i32 %tmp
+; X32: _crc32_32:
+; X32: crc32 8(%esp), %eax
+
+; X64: _crc32_32:
+; X64: crc32 %esi, %eax
+}
More information about the llvm-commits
mailing list