mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78508 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
46151de6a0
commit
b4dc13cab7
@ -517,6 +517,10 @@ void Emitter<CodeEmitter>::emitInstruction(
|
|||||||
case X86II::TA: // 0F 3A
|
case X86II::TA: // 0F 3A
|
||||||
Need0FPrefix = true;
|
Need0FPrefix = true;
|
||||||
break;
|
break;
|
||||||
|
case X86II::TF: // F2 0F 38
|
||||||
|
MCE.emitByte(0xF2);
|
||||||
|
Need0FPrefix = true;
|
||||||
|
break;
|
||||||
case X86II::REP: break; // already handled.
|
case X86II::REP: break; // already handled.
|
||||||
case X86II::XS: // F3 0F
|
case X86II::XS: // F3 0F
|
||||||
MCE.emitByte(0xF3);
|
MCE.emitByte(0xF3);
|
||||||
@ -548,6 +552,7 @@ void Emitter<CodeEmitter>::emitInstruction(
|
|||||||
MCE.emitByte(0x0F);
|
MCE.emitByte(0x0F);
|
||||||
|
|
||||||
switch (Desc->TSFlags & X86II::Op0Mask) {
|
switch (Desc->TSFlags & X86II::Op0Mask) {
|
||||||
|
case X86II::TF: // F2 0F 38
|
||||||
case X86II::T8: // 0F 38
|
case X86II::T8: // 0F 38
|
||||||
MCE.emitByte(0x38);
|
MCE.emitByte(0x38);
|
||||||
break;
|
break;
|
||||||
|
@ -79,6 +79,7 @@ class XD { bits<4> Prefix = 11; }
|
|||||||
class XS { bits<4> Prefix = 12; }
|
class XS { bits<4> Prefix = 12; }
|
||||||
class T8 { bits<4> Prefix = 13; }
|
class T8 { bits<4> Prefix = 13; }
|
||||||
class TA { bits<4> Prefix = 14; }
|
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,
|
class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
||||||
string AsmStr>
|
string AsmStr>
|
||||||
@ -229,6 +230,11 @@ class SS428I<bits<8> o, Format F, dag outs, dag ins, string asm,
|
|||||||
list<dag> pattern>
|
list<dag> pattern>
|
||||||
: I<o, F, outs, ins, asm, pattern>, T8, Requires<[HasSSE42]>;
|
: 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...
|
// X86-64 Instruction templates...
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -2931,6 +2931,10 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
|
|||||||
case X86II::TA: // 0F 3A
|
case X86II::TA: // 0F 3A
|
||||||
Need0FPrefix = true;
|
Need0FPrefix = true;
|
||||||
break;
|
break;
|
||||||
|
case X86II::TF: // F2 0F 38
|
||||||
|
++FinalSize;
|
||||||
|
Need0FPrefix = true;
|
||||||
|
break;
|
||||||
case X86II::REP: break; // already handled.
|
case X86II::REP: break; // already handled.
|
||||||
case X86II::XS: // F3 0F
|
case X86II::XS: // F3 0F
|
||||||
++FinalSize;
|
++FinalSize;
|
||||||
@ -2966,6 +2970,9 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
|
|||||||
case X86II::TA: // 0F 3A
|
case X86II::TA: // 0F 3A
|
||||||
++FinalSize;
|
++FinalSize;
|
||||||
break;
|
break;
|
||||||
|
case X86II::TF: // F2 0F 38
|
||||||
|
++FinalSize;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a two-address instruction, skip one of the register operands.
|
// If this is a two-address instruction, skip one of the register operands.
|
||||||
|
@ -321,6 +321,9 @@ namespace X86II {
|
|||||||
|
|
||||||
// T8, TA - Prefix after the 0x0F prefix.
|
// T8, TA - Prefix after the 0x0F prefix.
|
||||||
T8 = 13 << Op0Shift, TA = 14 << Op0Shift,
|
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.
|
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
|
||||||
|
@ -3678,3 +3678,75 @@ def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
|
|||||||
(PCMPGTQrr VR128:$src1, VR128:$src2)>;
|
(PCMPGTQrr VR128:$src1, VR128:$src2)>;
|
||||||
def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
|
def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
|
||||||
(PCMPGTQrm VR128:$src1, 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;
|
||||||
|
}
|
||||||
|
38
test/CodeGen/X86/sse42.ll
Normal file
38
test/CodeGen/X86/sse42.ll
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user