diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index c171656b48a..b9d2b0efb2b 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -76,6 +76,11 @@ def FeatureT2XtPk : SubtargetFeature<"t2xtpk", "HasT2ExtractPack", "true", "Enable Thumb2 extract and pack instructions">; def FeatureDB : SubtargetFeature<"db", "HasDataBarrier", "true", "Has data barrier (dmb / dsb) instructions">; +def FeatureV7Clrex : SubtargetFeature<"v7clrex", "HasV7Clrex", "true", + "Has v7 clrex instruction">; +def FeatureAcquireRelease : SubtargetFeature<"acquire-release", + "HasAcquireRelease", "true", + "Has v8 acquire/release (lda/ldaex etc) instructions">; def FeatureSlowFPBrcc : SubtargetFeature<"slow-fp-brcc", "SlowFPBrcc", "true", "FP compare + branch is slow">; def FeatureVFPOnlySP : SubtargetFeature<"fp-only-sp", "FPOnlySP", "true", @@ -208,10 +213,11 @@ def HasV6T2Ops : SubtargetFeature<"v6t2", "HasV6T2Ops", "true", [HasV6MOps, HasV6KOps, FeatureThumb2]>; def HasV7Ops : SubtargetFeature<"v7", "HasV7Ops", "true", "Support ARM v7 instructions", - [HasV6T2Ops, FeaturePerfMon]>; + [HasV6T2Ops, FeaturePerfMon, + FeatureV7Clrex]>; def HasV8Ops : SubtargetFeature<"v8", "HasV8Ops", "true", "Support ARM v8 instructions", - [HasV7Ops]>; + [HasV7Ops, FeatureAcquireRelease]>; def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true", "Support ARM v8.1a instructions", [HasV8Ops]>; @@ -256,7 +262,7 @@ def ProcExynosM1 : SubtargetFeature<"exynosm1", "ARMProcFamily", "ExynosM1", "Samsung Exynos-M1 processors", []>; def ProcR4 : SubtargetFeature<"r4", "ARMProcFamily", "CortexR4", - "Cortex-R4 ARM processors", []>; + "Cortex-R4 ARM processors", []>; def ProcR5 : SubtargetFeature<"r5", "ARMProcFamily", "CortexR5", "Cortex-R5 ARM processors", []>; def ProcR7 : SubtargetFeature<"r7", "ARMProcFamily", "CortexR7", diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index e79608d360c..c2c84d23640 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -563,12 +563,12 @@ class AIstrex opcod, dag oops, dag iops, InstrItinClass itin, class AIldaex opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list pattern> : AIldr_ex_or_acq, - Requires<[IsARM, HasV8]>; + Requires<[IsARM, HasAcquireRelease, HasV7Clrex]>; class AIstlex opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list pattern> : AIstr_ex_or_rel, - Requires<[IsARM, HasV8]> { + Requires<[IsARM, HasAcquireRelease, HasV7Clrex]> { bits<4> Rd; let Inst{15-12} = Rd; } @@ -593,12 +593,12 @@ class AIswp pattern> class AIldracq opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list pattern> : AIldr_ex_or_acq, - Requires<[IsARM, HasV8]>; + Requires<[IsARM, HasAcquireRelease]>; class AIstrrel opcod, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list pattern> : AIstr_ex_or_rel, - Requires<[IsARM, HasV8]> { + Requires<[IsARM, HasAcquireRelease]> { let Inst{15-12} = 0b1111; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c446ba3109e..cf178ac4e75 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -251,6 +251,12 @@ def HasDSP : Predicate<"Subtarget->hasDSP()">, def HasDB : Predicate<"Subtarget->hasDataBarrier()">, AssemblerPredicate<"FeatureDB", "data-barriers">; +def HasV7Clrex : Predicate<"Subtarget->hasV7Clrex()">, + AssemblerPredicate<"FeatureV7Clrex", + "v7 clrex">; +def HasAcquireRelease : Predicate<"Subtarget->hasAcquireRelease()">, + AssemblerPredicate<"FeatureAcquireRelease", + "acquire/release">; def HasMP : Predicate<"Subtarget->hasMPExtension()">, AssemblerPredicate<"FeatureMP", "mp-extensions">; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index f42f4569b2f..e6533a321e7 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1414,7 +1414,7 @@ def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>; class T2Ildacq bits23_20, bits<2> bit54, dag oops, dag iops, string opc, string asm, list pattern> : Thumb2I, Requires<[IsThumb, HasV8]> { + opc, asm, "", pattern>, Requires<[IsThumb, HasAcquireRelease]> { bits<4> Rt; bits<4> addr; @@ -1586,7 +1586,7 @@ def t2STRD_POST : T2Ii8s4post<0, 1, 0, (outs GPR:$wb), class T2Istrrel bit54, dag oops, dag iops, string opc, string asm, list pattern> : Thumb2I, Requires<[IsThumb, HasV8]> { + asm, "", pattern>, Requires<[IsThumb, HasAcquireRelease]> { bits<4> Rt; bits<4> addr; @@ -3320,17 +3320,17 @@ def t2LDAEXB : T2I_ldrex<0b1100, (outs rGPR:$Rt), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldaexb", "\t$Rt, $addr", "", [(set rGPR:$Rt, (ldaex_1 addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]>; + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; def t2LDAEXH : T2I_ldrex<0b1101, (outs rGPR:$Rt), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldaexh", "\t$Rt, $addr", "", [(set rGPR:$Rt, (ldaex_2 addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]>; + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; def t2LDAEX : Thumb2I<(outs rGPR:$Rt), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldaex", "\t$Rt, $addr", "", [(set rGPR:$Rt, (ldaex_4 addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]> { + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]> { bits<4> Rt; bits<4> addr; let Inst{31-27} = 0b11101; @@ -3345,7 +3345,8 @@ def t2LDAEXD : T2I_ldrex<0b1111, (outs rGPR:$Rt, rGPR:$Rt2), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldaexd", "\t$Rt, $Rt2, $addr", "", - [], {?, ?, ?, ?}>, Requires<[IsThumb, HasV8]> { + [], {?, ?, ?, ?}>, Requires<[IsThumb, + HasAcquireRelease, HasV7Clrex, IsNotMClass]> { bits<4> Rt2; let Inst{11-8} = Rt2; @@ -3399,7 +3400,8 @@ def t2STLEXB : T2I_strex<0b1100, (outs rGPR:$Rd), "stlexb", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, (stlex_1 rGPR:$Rt, addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]>; + Requires<[IsThumb, HasAcquireRelease, + HasV7Clrex]>; def t2STLEXH : T2I_strex<0b1101, (outs rGPR:$Rd), (ins rGPR:$Rt, addr_offset_none:$addr), @@ -3407,7 +3409,8 @@ def t2STLEXH : T2I_strex<0b1101, (outs rGPR:$Rd), "stlexh", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, (stlex_2 rGPR:$Rt, addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]>; + Requires<[IsThumb, HasAcquireRelease, + HasV7Clrex]>; def t2STLEX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, addr_offset_none:$addr), @@ -3415,7 +3418,7 @@ def t2STLEX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, "stlex", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, (stlex_4 rGPR:$Rt, addr_offset_none:$addr))]>, - Requires<[IsThumb, HasV8]> { + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]> { bits<4> Rd; bits<4> Rt; bits<4> addr; @@ -3431,14 +3434,15 @@ def t2STLEXD : T2I_strex<0b1111, (outs rGPR:$Rd), (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "stlexd", "\t$Rd, $Rt, $Rt2, $addr", "", [], - {?, ?, ?, ?}>, Requires<[IsThumb, HasV8]> { + {?, ?, ?, ?}>, Requires<[IsThumb, HasAcquireRelease, + HasV7Clrex, IsNotMClass]> { bits<4> Rt2; let Inst{11-8} = Rt2; } } def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", [(int_arm_clrex)]>, - Requires<[IsThumb2, HasV7]> { + Requires<[IsThumb, HasV7Clrex]> { let Inst{31-16} = 0xf3bf; let Inst{15-14} = 0b10; let Inst{13} = 0; @@ -3458,13 +3462,17 @@ def : T2Pat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), (t2STREXH GPR:$Rt, addr_offset_none:$addr)>; def : T2Pat<(and (ldaex_1 addr_offset_none:$addr), 0xff), - (t2LDAEXB addr_offset_none:$addr)>; + (t2LDAEXB addr_offset_none:$addr)>, + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; def : T2Pat<(and (ldaex_2 addr_offset_none:$addr), 0xffff), - (t2LDAEXH addr_offset_none:$addr)>; + (t2LDAEXH addr_offset_none:$addr)>, + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; def : T2Pat<(stlex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), - (t2STLEXB GPR:$Rt, addr_offset_none:$addr)>; + (t2STLEXB GPR:$Rt, addr_offset_none:$addr)>, + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; def : T2Pat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), - (t2STLEXH GPR:$Rt, addr_offset_none:$addr)>; + (t2STLEXH GPR:$Rt, addr_offset_none:$addr)>, + Requires<[IsThumb, HasAcquireRelease, HasV7Clrex]>; //===----------------------------------------------------------------------===// // SJLJ Exception handling intrinsics diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index bb6ae28065b..c676f9f5f48 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -154,6 +154,8 @@ void ARMSubtarget::initializeEnvironment() { UseNaClTrap = false; GenLongCalls = false; UnsafeFPMath = false; + HasV7Clrex = false; + HasAcquireRelease = false; // MCAsmInfo isn't always present (e.g. in opt) so we can't initialize this // directly from it, but we can try to make sure they're consistent when both diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 4d54e575147..7b551cd84ee 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -155,6 +155,13 @@ protected: /// instructions. bool HasDataBarrier; + /// HasV7Clrex - True if the subtarget supports CLREX instructions + bool HasV7Clrex; + + /// HasAcquireRelease - True if the subtarget supports v8 atomics (LDA/LDAEX etc) + /// instructions + bool HasAcquireRelease; + /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions /// over 16-bit ones. bool Pref32BitThumb; @@ -343,6 +350,8 @@ public: bool hasDivideInARMMode() const { return HasHardwareDivideInARM; } bool hasT2ExtractPack() const { return HasT2ExtractPack; } bool hasDataBarrier() const { return HasDataBarrier; } + bool hasV7Clrex() const { return HasV7Clrex; } + bool hasAcquireRelease() const { return HasAcquireRelease; } bool hasAnyDataBarrier() const { return HasDataBarrier || (hasV6Ops() && !isThumb()); } diff --git a/test/MC/ARM/arm11-hint-instr.s b/test/MC/ARM/arm11-hint-instr.s index 2c0fef4adf7..4193a686870 100644 --- a/test/MC/ARM/arm11-hint-instr.s +++ b/test/MC/ARM/arm11-hint-instr.s @@ -65,7 +65,7 @@ @ CHECK-THUMB: wfe @ encoding: [0x20,0xbf] @ CHECK-THUMB: wfi @ encoding: [0x30,0xbf] @ CHECK-THUMB: sev @ encoding: [0x40,0xbf] -@ CHECK-ERROR-THUMB: error: instruction requires: armv7 +@ CHECK-ERROR-THUMB: error: instruction requires: v7 clrex @ CHECK-ERROR-THUMB: clrex @ CHECK-ERROR-THUMB: ^ @@ -77,6 +77,6 @@ @ CHECK-V6M: wfe @ encoding: [0x20,0xbf] @ CHECK-V6M: wfi @ encoding: [0x30,0xbf] @ CHECK-V6M: sev @ encoding: [0x40,0xbf] -@ CHECK-ERROR-V6M: error: instruction requires: armv7 +@ CHECK-ERROR-V6M: error: instruction requires: v7 clrex @ CHECK-ERROR-V6M: clrex @ CHECK-ERROR-V6M: ^ diff --git a/test/MC/ARM/load-store-acquire-release-v8-thumb.s b/test/MC/ARM/load-store-acquire-release-v8-thumb.s index e34a2638735..be8d3c324e6 100644 --- a/test/MC/ARM/load-store-acquire-release-v8-thumb.s +++ b/test/MC/ARM/load-store-acquire-release-v8-thumb.s @@ -9,10 +9,10 @@ @ CHECK: ldaexh r2, [r5] @ encoding: [0xd5,0xe8,0xdf,0x2f] @ CHECK: ldaex r1, [r7] @ encoding: [0xd7,0xe8,0xef,0x1f] @ CHECK: ldaexd r6, r7, [r8] @ encoding: [0xd8,0xe8,0xff,0x67] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release stlexb r1, r3, [r4] stlexh r4, r2, [r5] @@ -22,10 +22,10 @@ @ CHECK: stlexh r4, r2, [r5] @ encoding: [0xc5,0xe8,0xd4,0x2f] @ CHECK: stlex r2, r1, [r7] @ encoding: [0xc7,0xe8,0xe2,0x1f] @ CHECK: stlexd r6, r2, r3, [r8] @ encoding: [0xc8,0xe8,0xf6,0x23] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release lda r5, [r6] ldab r5, [r6] @@ -33,9 +33,9 @@ @ CHECK: lda r5, [r6] @ encoding: [0xd6,0xe8,0xaf,0x5f] @ CHECK: ldab r5, [r6] @ encoding: [0xd6,0xe8,0x8f,0x5f] @ CHECK: ldah r12, [r9] @ encoding: [0xd9,0xe8,0x9f,0xcf] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release stl r3, [r0] stlb r2, [r1] @@ -43,6 +43,6 @@ @ CHECK: stl r3, [r0] @ encoding: [0xc0,0xe8,0xaf,0x3f] @ CHECK: stlb r2, [r1] @ encoding: [0xc1,0xe8,0x8f,0x2f] @ CHECK: stlh r2, [r3] @ encoding: [0xc3,0xe8,0x9f,0x2f] -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 -@ CHECK-V7: error: instruction requires: armv8 +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release +@ CHECK-V7: error: instruction requires: acquire/release diff --git a/test/MC/ARM/load-store-acquire-release-v8.s b/test/MC/ARM/load-store-acquire-release-v8.s index bc55364e684..273519e050b 100644 --- a/test/MC/ARM/load-store-acquire-release-v8.s +++ b/test/MC/ARM/load-store-acquire-release-v8.s @@ -9,10 +9,10 @@ @ CHECK: ldaexh r2, [r5] @ encoding: [0x9f,0x2e,0xf5,0xe1] @ CHECK: ldaex r1, [r7] @ encoding: [0x9f,0x1e,0x97,0xe1] @ CHECK: ldaexd r6, r7, [r8] @ encoding: [0x9f,0x6e,0xb8,0xe1] -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release stlexb r1, r3, [r4] stlexh r4, r2, [r5] @@ -22,10 +22,10 @@ @ CHECK: stlexh r4, r2, [r5] @ encoding: [0x92,0x4e,0xe5,0xe1] @ CHECK: stlex r2, r1, [r7] @ encoding: [0x91,0x2e,0x87,0xe1] @ CHECK: stlexd r6, r2, r3, [r8] @ encoding: [0x92,0x6e,0xa8,0xe1] -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release lda r5, [r6] ldab r5, [r6] @@ -33,9 +33,9 @@ @ CHECK: lda r5, [r6] @ encoding: [0x9f,0x5c,0x96,0xe1] @ CHECK: ldab r5, [r6] @ encoding: [0x9f,0x5c,0xd6,0xe1] @ CHECK: ldah r12, [r9] @ encoding: [0x9f,0xcc,0xf9,0xe1] -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release stl r3, [r0] stlb r2, [r1] @@ -43,6 +43,6 @@ @ CHECK: stl r3, [r0] @ encoding: [0x93,0xfc,0x80,0xe1] @ CHECK: stlb r2, [r1] @ encoding: [0x92,0xfc,0xc1,0xe1] @ CHECK: stlh r2, [r3] @ encoding: [0x92,0xfc,0xe3,0xe1] -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 -@ CHECK-V7: instruction requires: armv8 +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release +@ CHECK-V7: instruction requires: acquire/release