[AArch64] Add support for NEON scalar integer compare instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192596 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier 2013-10-14 14:37:20 +00:00
parent 0d1e2aebe6
commit 942827b113
6 changed files with 497 additions and 0 deletions

View File

@ -167,4 +167,28 @@ def int_aarch64_neon_vcvtf64_u64 :
// Scalar Floating-point Reciprocal Exponent
def int_aarch64_neon_vrecpx : Neon_1Arg_Intrinsic;
class Neon_ICmp_Intrinsic
: Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty, llvm_v1i64_ty], [IntrNoMem]>;
// Scalar Integer Compare Equal
def int_aarch64_neon_vceq : Neon_ICmp_Intrinsic;
// Scalar Integer Compare Greater-Than or Equal
def int_aarch64_neon_vcge : Neon_ICmp_Intrinsic;
def int_aarch64_neon_vchs : Neon_ICmp_Intrinsic;
// Scalar Integer Compare Less-Than or Equal
def int_aarch64_neon_vclez : Neon_ICmp_Intrinsic;
// Scalar Compare Less-Than
def int_aarch64_neon_vcltz : Neon_ICmp_Intrinsic;
// Scalar Compare Greater-Than
def int_aarch64_neon_vcgt : Neon_ICmp_Intrinsic;
def int_aarch64_neon_vchi : Neon_ICmp_Intrinsic;
// Scalar Compare Bitwise Test Bits
def int_aarch64_neon_vtstd : Neon_ICmp_Intrinsic;
}

View File

@ -339,6 +339,15 @@ def Neon_immAllOnes: PatLeaf<(Neon_movi (i32 timm), (i32 imm)), [{
return (EltBits == 8 && EltVal == 0xff);
}]>;
def Neon_immAllZeros: PatLeaf<(Neon_movi (i32 timm), (i32 imm)), [{
ConstantSDNode *ImmConstVal = cast<ConstantSDNode>(N->getOperand(0));
ConstantSDNode *OpCmodeConstVal = cast<ConstantSDNode>(N->getOperand(1));
unsigned EltBits;
uint64_t EltVal = A64Imms::decodeNeonModImm(ImmConstVal->getZExtValue(),
OpCmodeConstVal->getZExtValue(), EltBits);
return (EltBits == 8 && EltVal == 0x0);
}]>;
def Neon_not8B : PatFrag<(ops node:$in),
(xor node:$in, (bitconvert (v8i8 Neon_immAllOnes)))>;
@ -3199,6 +3208,11 @@ multiclass Neon_Scalar3Same_BHSD_size_patterns<SDPatternOperator opnode,
(INSTS FPR32:$Rn, FPR32:$Rm)>;
}
class Neon_Scalar3Same_cmp_D_size_patterns<SDPatternOperator opnode,
Instruction INSTD>
: Pat<(v1i64 (opnode (v1i64 VPR64:$Rn), (v1i64 VPR64:$Rm))),
(INSTD VPR64:$Rn, VPR64:$Rm)>;
multiclass Neon_Scalar3Same_HS_size_patterns<SDPatternOperator opnode,
Instruction INSTH,
Instruction INSTS> {
@ -3250,6 +3264,19 @@ multiclass Neon_Scalar2SameMisc_SD_size_patterns<SDPatternOperator opnode,
(INSTD FPR64:$Rn)>;
}
// AdvSIMD Scalar Two Registers Miscellaneous
class NeonI_Scalar2SameMisc_cmpz_D_size<bit u, bits<5> opcode, string asmop>
: NeonI_Scalar2SameMisc<u, 0b11, opcode,
(outs FPR64:$Rd), (ins FPR64:$Rn, neon_uimm0:$Imm),
!strconcat(asmop, " $Rd, $Rn, $Imm"),
[],
NoItinerary>;
class Neon_Scalar2SameMisc_cmpz_D_size_patterns<SDPatternOperator opnode,
Instruction INSTD>
: Pat<(v1i64 (opnode (v1i64 VPR64:$Rn), (v1i64 (bitconvert (v8i8 Neon_immAllZeros))))),
(INSTD VPR64:$Rn, 0)>;
// Scalar Integer Add
let isCommutable = 1 in {
def ADDddd : NeonI_Scalar3Same_D_size<0b0, 0b10000, "add">;
@ -3417,6 +3444,57 @@ defm FRSQRTE: NeonI_Scalar2SameMisc_SD_size<0b1, 0b1, 0b11101, "frsqrte">;
defm : Neon_Scalar2SameMisc_SD_size_patterns<int_arm_neon_vrsqrte,
FRSQRTEss, FRSQRTEdd>;
// Scalar Integer Compare
// Scalar Compare Bitwise Equal
def CMEQddd: NeonI_Scalar3Same_D_size<0b1, 0b10001, "cmeq">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vceq, CMEQddd>;
// Scalar Compare Signed Greather Than Or Equal
def CMGEddd: NeonI_Scalar3Same_D_size<0b0, 0b00111, "cmge">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vcge, CMGEddd>;
// Scalar Compare Unsigned Higher Or Same
def CMHSddd: NeonI_Scalar3Same_D_size<0b1, 0b00111, "cmhs">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vchs, CMHSddd>;
// Scalar Compare Unsigned Higher
def CMHIddd: NeonI_Scalar3Same_D_size<0b1, 0b00110, "cmhi">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vchi, CMHIddd>;
// Scalar Compare Signed Greater Than
def CMGTddd: NeonI_Scalar3Same_D_size<0b0, 0b00110, "cmgt">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vcgt, CMGTddd>;
// Scalar Compare Bitwise Test Bits
def CMTSTddd: NeonI_Scalar3Same_D_size<0b0, 0b10001, "cmtst">;
def : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vtstd, CMTSTddd>;
// Scalar Compare Bitwise Equal To Zero
def CMEQddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01001, "cmeq">;
def : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vceq,
CMEQddi>;
// Scalar Compare Signed Greather Than Or Equal To Zero
def CMGEddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b1, 0b01000, "cmge">;
def : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcge,
CMGEddi>;
// Scalar Compare Signed Greater Than Zero
def CMGTddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01000, "cmgt">;
def : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcgt,
CMGTddi>;
// Scalar Compare Signed Less Than Or Equal To Zero
def CMLEddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b1, 0b01001, "cmle">;
def : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vclez,
CMLEddi>;
// Scalar Compare Less Than Zero
def CMLTddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01010, "cmlt">;
def : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcltz,
CMLTddi>;
// Scalar Reduce Pairwise
multiclass NeonI_ScalarPair_D_sizes<bit u, bit size, bits<5> opcode,

View File

@ -0,0 +1,128 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s
;; Scalar Integer Compare
define i64 @test_vceqd(i64 %a, i64 %b) {
; CHECK: test_vceqd
; CHECK: cmeq {{d[0-9]+}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vceq.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vceq1.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vceq2.i = call <1 x i64> @llvm.aarch64.neon.vceq(<1 x i64> %vceq.i, <1 x i64> %vceq1.i)
%0 = extractelement <1 x i64> %vceq2.i, i32 0
ret i64 %0
}
define i64 @test_vceqzd(i64 %a) {
; CHECK: test_vceqzd
; CHECK: cmeq {{d[0-9]}}, {{d[0-9]}}, #0x0
entry:
%vceqz.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vceqz1.i = call <1 x i64> @llvm.aarch64.neon.vceq(<1 x i64> %vceqz.i, <1 x i64> zeroinitializer)
%0 = extractelement <1 x i64> %vceqz1.i, i32 0
ret i64 %0
}
define i64 @test_vcged(i64 %a, i64 %b) {
; CHECK: test_vcged
; CHECK: cmge {{d[0-9]}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vcge.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcge1.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vcge2.i = call <1 x i64> @llvm.aarch64.neon.vcge(<1 x i64> %vcge.i, <1 x i64> %vcge1.i)
%0 = extractelement <1 x i64> %vcge2.i, i32 0
ret i64 %0
}
define i64 @test_vcgezd(i64 %a) {
; CHECK: test_vcgezd
; CHECK: cmge {{d[0-9]}}, {{d[0-9]}}, #0x0
entry:
%vcgez.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcgez1.i = call <1 x i64> @llvm.aarch64.neon.vcge(<1 x i64> %vcgez.i, <1 x i64> zeroinitializer)
%0 = extractelement <1 x i64> %vcgez1.i, i32 0
ret i64 %0
}
define i64 @test_vcgtd(i64 %a, i64 %b) {
; CHECK: test_vcgtd
; CHECK: cmgt {{d[0-9]}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vcgt.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcgt1.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vcgt2.i = call <1 x i64> @llvm.aarch64.neon.vcgt(<1 x i64> %vcgt.i, <1 x i64> %vcgt1.i)
%0 = extractelement <1 x i64> %vcgt2.i, i32 0
ret i64 %0
}
define i64 @test_vcgtzd(i64 %a) {
; CHECK: test_vcgtzd
; CHECK: cmgt {{d[0-9]}}, {{d[0-9]}}, #0x0
entry:
%vcgtz.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcgtz1.i = call <1 x i64> @llvm.aarch64.neon.vcgt(<1 x i64> %vcgtz.i, <1 x i64> zeroinitializer)
%0 = extractelement <1 x i64> %vcgtz1.i, i32 0
ret i64 %0
}
define i64 @test_vcled(i64 %a, i64 %b) {
; CHECK: test_vcled
; CHECK: cmgt {{d[0-9]}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vcgt.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vcgt1.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcgt2.i = call <1 x i64> @llvm.aarch64.neon.vcgt(<1 x i64> %vcgt.i, <1 x i64> %vcgt1.i)
%0 = extractelement <1 x i64> %vcgt2.i, i32 0
ret i64 %0
}
define i64 @test_vclezd(i64 %a) {
; CHECK: test_vclezd
; CHECK: cmle {{d[0-9]}}, {{d[0-9]}}, #0x0
entry:
%vclez.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vclez1.i = call <1 x i64> @llvm.aarch64.neon.vclez(<1 x i64> %vclez.i, <1 x i64> zeroinitializer)
%0 = extractelement <1 x i64> %vclez1.i, i32 0
ret i64 %0
}
define i64 @test_vcltd(i64 %a, i64 %b) {
; CHECK: test_vcltd
; CHECK: cmge {{d[0-9]}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vcge.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vcge1.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcge2.i = call <1 x i64> @llvm.aarch64.neon.vcge(<1 x i64> %vcge.i, <1 x i64> %vcge1.i)
%0 = extractelement <1 x i64> %vcge2.i, i32 0
ret i64 %0
}
define i64 @test_vcltzd(i64 %a) {
; CHECK: test_vcltzd
; CHECK: cmlt {{d[0-9]}}, {{d[0-9]}}, #0x0
entry:
%vcltz.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vcltz1.i = call <1 x i64> @llvm.aarch64.neon.vcltz(<1 x i64> %vcltz.i, <1 x i64> zeroinitializer)
%0 = extractelement <1 x i64> %vcltz1.i, i32 0
ret i64 %0
}
define i64 @test_vtstd(i64 %a, i64 %b) {
; CHECK: test_vtstd
; CHECK: cmtst {{d[0-9]}}, {{d[0-9]}}, {{d[0-9]}}
entry:
%vtst.i = insertelement <1 x i64> undef, i64 %a, i32 0
%vtst1.i = insertelement <1 x i64> undef, i64 %b, i32 0
%vtst2.i = call <1 x i64> @llvm.aarch64.neon.vtstd(<1 x i64> %vtst.i, <1 x i64> %vtst1.i)
%0 = extractelement <1 x i64> %vtst2.i, i32 0
ret i64 %0
}
declare <1 x i64> @llvm.aarch64.neon.vtstd(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vcltz(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vchs(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vcge(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vclez(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vchi(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vcgt(<1 x i64>, <1 x i64>)
declare <1 x i64> @llvm.aarch64.neon.vceq(<1 x i64>, <1 x i64>)

View File

@ -4286,3 +4286,113 @@
// CHECK-ERROR dup v5.2d, w0
// CHECK-ERROR ^
//----------------------------------------------------------------------
// Scalar Compare Bitwise Equal
//----------------------------------------------------------------------
cmeq b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmeq b20, d21, d22
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Bitwise Equal To Zero
//----------------------------------------------------------------------
cmeq d20, b21, #0
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmeq d20, b21, #0
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Unsigned Higher Or Same
//----------------------------------------------------------------------
cmhs b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmhs b20, d21, d22
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Signed Greather Than Or Equal
//----------------------------------------------------------------------
cmge b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmge b20, d21, d22
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Signed Greather Than Or Equal To Zero
//----------------------------------------------------------------------
cmge d20, b21, #0
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmge d20, b21, #0
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Unsigned Higher
//----------------------------------------------------------------------
cmhi b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmhi b20, d21, d22
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Signed Greater Than
//----------------------------------------------------------------------
cmgt b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmgt b20, d21, d22
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Signed Greater Than Zero
//----------------------------------------------------------------------
cmgt d20, b21, #0
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmgt d20, b21, #0
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Signed Less Than Or Equal To Zero
//----------------------------------------------------------------------
cmle d20, b21, #0
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmle d20, b21, #0
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Less Than Zero
//----------------------------------------------------------------------
cmlt d20, b21, #0
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmlt d20, b21, #0
// CHECK-ERROR: ^
//----------------------------------------------------------------------
// Scalar Compare Bitwise Test Bits
//----------------------------------------------------------------------
cmtst b20, d21, d22
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: cmtst b20, d21, d22
// CHECK-ERROR: ^

View File

@ -0,0 +1,90 @@
// RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+neon -show-encoding < %s | FileCheck %s
// Check that the assembler can handle the documented syntax for AArch64
//----------------------------------------------------------------------
// Scalar Compare Bitwise Equal
//----------------------------------------------------------------------
cmeq d20, d21, d22
// CHECK: cmeq d20, d21, d22 // encoding: [0xb4,0x8e,0xf6,0x7e]
//----------------------------------------------------------------------
// Scalar Compare Bitwise Equal To Zero
//----------------------------------------------------------------------
cmeq d20, d21, #0x0
// CHECK: cmeq d20, d21, #0x0 // encoding: [0xb4,0x9a,0xe0,0x5e]
//----------------------------------------------------------------------
// Scalar Compare Unsigned Higher Or Same
//----------------------------------------------------------------------
cmhs d20, d21, d22
// CHECK: cmhs d20, d21, d22 // encoding: [0xb4,0x3e,0xf6,0x7e]
//----------------------------------------------------------------------
// Scalar Compare Signed Greather Than Or Equal
//----------------------------------------------------------------------
cmge d20, d21, d22
// CHECK: cmge d20, d21, d22 // encoding: [0xb4,0x3e,0xf6,0x5e]
//----------------------------------------------------------------------
// Scalar Compare Signed Greather Than Or Equal To Zero
//----------------------------------------------------------------------
cmge d20, d21, #0x0
// CHECK: cmge d20, d21, #0x0 // encoding: [0xb4,0x8a,0xe0,0x7e]
//----------------------------------------------------------------------
// Scalar Compare Unsigned Higher
//----------------------------------------------------------------------
cmhi d20, d21, d22
// CHECK: cmhi d20, d21, d22 // encoding: [0xb4,0x36,0xf6,0x7e]
//----------------------------------------------------------------------
// Scalar Compare Signed Greater Than
//----------------------------------------------------------------------
cmgt d20, d21, d22
// CHECK: cmgt d20, d21, d22 // encoding: [0xb4,0x36,0xf6,0x5e]
//----------------------------------------------------------------------
// Scalar Compare Signed Greater Than Zero
//----------------------------------------------------------------------
cmgt d20, d21, #0x0
// CHECK: cmgt d20, d21, #0x0 // encoding: [0xb4,0x8a,0xe0,0x5e]
//----------------------------------------------------------------------
// Scalar Compare Signed Less Than Or Equal To Zero
//----------------------------------------------------------------------
cmle d20, d21, #0x0
// CHECK: cmle d20, d21, #0x0 // encoding: [0xb4,0x9a,0xe0,0x7e]
//----------------------------------------------------------------------
// Scalar Compare Less Than Zero
//----------------------------------------------------------------------
cmlt d20, d21, #0x0
// CHECK: cmlt d20, d21, #0x0 // encoding: [0xb4,0xaa,0xe0,0x5e]
//----------------------------------------------------------------------
// Scalar Compare Bitwise Test Bits
//----------------------------------------------------------------------
cmtst d20, d21, d22
// CHECK: cmtst d20, d21, d22 // encoding: [0xb4,0x8e,0xf6,0x5e]

View File

@ -1532,3 +1532,70 @@
# CHECK: frsqrte d21, d12
0xb6,0xd9,0xa1,0x7e
0x95,0xd9,0xe1,0x7e
#----------------------------------------------------------------------
# Scalar Compare Bitwise Equal
#----------------------------------------------------------------------
# CHECK: cmeq d20, d21, d22
0xb4,0x8e,0xf6,0x7e
#----------------------------------------------------------------------
# Scalar Compare Bitwise Equal To Zero
#----------------------------------------------------------------------
# CHECK: cmeq d20, d21, #0x0
0xb4,0x9a,0xe0,0x5e
#----------------------------------------------------------------------
# Scalar Compare Unsigned Higher Or Same
#----------------------------------------------------------------------
# CHECK: cmhs d20, d21, d22
0xb4,0x3e,0xf6,0x7e
#----------------------------------------------------------------------
# Scalar Compare Signed Greather Than Or Equal
#----------------------------------------------------------------------
# CHECK: cmge d20, d21, d22
0xb4,0x3e,0xf6,0x5e
#----------------------------------------------------------------------
# Scalar Compare Signed Greather Than Or Equal To Zero
#----------------------------------------------------------------------
# CHECK: cmge d20, d21, #0x0
0xb4,0x8a,0xe0,0x7e
#----------------------------------------------------------------------
# Scalar Compare Unsigned Higher
#----------------------------------------------------------------------
# CHECK: cmhi d20, d21, d22
0xb4,0x36,0xf6,0x7e
#----------------------------------------------------------------------
# Scalar Compare Signed Greater Than
#----------------------------------------------------------------------
# CHECK: cmgt d20, d21, d22
0xb4,0x36,0xf6,0x5e
#----------------------------------------------------------------------
# Scalar Compare Signed Greater Than Zero
#----------------------------------------------------------------------
# CHECK: cmgt d20, d21, #0x0
0xb4,0x8a,0xe0,0x5e
#----------------------------------------------------------------------
# Scalar Compare Signed Less Than Or Equal To Zero
#----------------------------------------------------------------------
# CHECK: cmle d20, d21, #0x0
0xb4,0x9a,0xe0,0x7e
#----------------------------------------------------------------------
# Scalar Compare Less Than Zero
#----------------------------------------------------------------------
# CHECK: cmlt d20, d21, #0x0
0xb4,0xaa,0xe0,0x5e
#----------------------------------------------------------------------
# Scalar Compare Bitwise Test Bits
#----------------------------------------------------------------------
# CHECK: cmtst d20, d21, d22
0xb4,0x8e,0xf6,0x5e