Index: lib/Target/ARM/ARM.td =================================================================== --- lib/Target/ARM/ARM.td +++ lib/Target/ARM/ARM.td @@ -70,6 +70,8 @@ def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true", "Enable support for Cryptography extensions", [FeatureNEON]>; +def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true", + "Enable support for CRC instructions">; // Some processors have FP multiply-accumulate instructions that don't // play nicely with other VFP / NEON instructions, and it's generally better @@ -202,13 +204,13 @@ "Cortex-A53 ARM processors", [FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, - FeatureCrypto]>; + FeatureCrypto, FeatureCRC]>; def ProcA57 : SubtargetFeature<"a57", "ARMProcFamily", "CortexA57", "Cortex-A57 ARM processors", [FeatureMP, FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, - FeatureCrypto]>; + FeatureCrypto, FeatureCRC]>; def ProcR5 : SubtargetFeature<"r5", "ARMProcFamily", "CortexR5", "Cortex-R5 ARM processors", Index: lib/Target/ARM/ARMInstrInfo.td =================================================================== --- lib/Target/ARM/ARMInstrInfo.td +++ lib/Target/ARM/ARMInstrInfo.td @@ -221,6 +221,8 @@ AssemblerPredicate<"FeatureNEON", "NEON">; def HasCrypto : Predicate<"Subtarget->hasCrypto()">, AssemblerPredicate<"FeatureCrypto", "crypto">; +def HasCRC : Predicate<"Subtarget->hasCRC()">, + AssemblerPredicate<"FeatureCRC", "crc">; def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate<"FeatureFP16","half-float">; def HasDivide : Predicate<"Subtarget->hasDivide()">, @@ -4032,7 +4034,7 @@ : AInoP<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), MiscFrm, NoItinerary, !strconcat("crc32", suffix), "\t$Rd, $Rn, $Rm", [(set GPRnopc:$Rd, (builtin GPRnopc:$Rn, GPRnopc:$Rm))]>, - Requires<[IsARM, HasV8]> { + Requires<[IsARM, HasV8, HasCRC]> { bits<4> Rd; bits<4> Rn; bits<4> Rm; Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -3027,7 +3027,7 @@ : T2ThreeRegNoP<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), NoItinerary, !strconcat("crc32", suffix, "\t$Rd, $Rn, $Rm"), [(set rGPR:$Rd, (builtin rGPR:$Rn, rGPR:$Rm))]>, - Requires<[IsThumb2, HasV8]> { + Requires<[IsThumb2, HasV8, HasCRC]> { let Inst{31-27} = 0b11111; let Inst{26-21} = 0b010110; let Inst{20} = C; Index: lib/Target/ARM/ARMSubtarget.h =================================================================== --- lib/Target/ARM/ARMSubtarget.h +++ lib/Target/ARM/ARMSubtarget.h @@ -165,6 +165,9 @@ /// HasCrypto - if true, processor supports Cryptography extensions bool HasCrypto; + /// HasCRC - if true, processor supports CRC instructions + bool HasCRC; + /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory /// accesses for some types. For details, see /// ARMTargetLowering::allowsUnalignedMemoryAccesses(). @@ -256,6 +259,7 @@ bool hasFPARMv8() const { return HasFPARMv8; } bool hasNEON() const { return HasNEON; } bool hasCrypto() const { return HasCrypto; } + bool hasCRC() const { return HasCRC; } bool useNEONForSinglePrecisionFP() const { return hasNEON() && UseNEONForSinglePrecisionFP; } Index: lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -105,8 +105,8 @@ if (SubVer == '8') { if (NoCPU) // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, FeatureMP, - // FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, FeatureCrypto - ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,+trustzone,+t2xtpk,+crypto"; + // FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, FeatureCrypto, FeatureCRC + ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,+trustzone,+t2xtpk,+crypto,+crc"; else // Use CPU to figure out the exact features ARMArchFeature = "+v8"; Index: test/MC/ARM/crc32-thumb.s =================================================================== --- test/MC/ARM/crc32-thumb.s +++ test/MC/ARM/crc32-thumb.s @@ -1,5 +1,6 @@ @ RUN: llvm-mc -triple=thumbv8 -show-encoding < %s | FileCheck %s @ RUN: not llvm-mc -triple=thumbv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7 +@ RUN: not llvm-mc -triple=thumbv8 -mattr=-crc -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOCRC crc32b r0, r1, r2 crc32h r0, r1, r2 crc32w r0, r1, r2 @@ -7,9 +8,12 @@ @ CHECK: crc32b r0, r1, r2 @ encoding: [0xc1,0xfa,0x82,0xf0] @ CHECK: crc32h r0, r1, r2 @ encoding: [0xc1,0xfa,0x92,0xf0] @ CHECK: crc32w r0, r1, r2 @ encoding: [0xc1,0xfa,0xa2,0xf0] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc crc32cb r0, r1, r2 crc32ch r0, r1, r2 @@ -18,6 +22,9 @@ @ CHECK: crc32cb r0, r1, r2 @ encoding: [0xd1,0xfa,0x82,0xf0] @ CHECK: crc32ch r0, r1, r2 @ encoding: [0xd1,0xfa,0x92,0xf0] @ CHECK: crc32cw r0, r1, r2 @ encoding: [0xd1,0xfa,0xa2,0xf0] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc Index: test/MC/ARM/crc32.s =================================================================== --- test/MC/ARM/crc32.s +++ test/MC/ARM/crc32.s @@ -1,5 +1,6 @@ @ RUN: llvm-mc -triple=armv8 -show-encoding < %s | FileCheck %s @ RUN: not llvm-mc -triple=armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7 +@ RUN: not llvm-mc -triple=thumbv8 -mattr=-crc -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOCRC crc32b r0, r1, r2 crc32h r0, r1, r2 crc32w r0, r1, r2 @@ -7,9 +8,12 @@ @ CHECK: crc32b r0, r1, r2 @ encoding: [0x42,0x00,0x01,0xe1] @ CHECK: crc32h r0, r1, r2 @ encoding: [0x42,0x00,0x21,0xe1] @ CHECK: crc32w r0, r1, r2 @ encoding: [0x42,0x00,0x41,0xe1] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc crc32cb r0, r1, r2 crc32ch r0, r1, r2 @@ -18,6 +22,9 @@ @ CHECK: crc32cb r0, r1, r2 @ encoding: [0x42,0x02,0x01,0xe1] @ CHECK: crc32ch r0, r1, r2 @ encoding: [0x42,0x02,0x21,0xe1] @ CHECK: crc32cw r0, r1, r2 @ encoding: [0x42,0x02,0x41,0xe1] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-V7: error: instruction requires: crc armv8 +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc +@ CHECK-NOCRC: error: instruction requires: crc