Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -3291,15 +3291,18 @@ def t2LDREXB : T2I_ldrex<0b0100, (outs rGPR:$Rt), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldrexb", "\t$Rt, $addr", "", - [(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>; + [(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]>; def t2LDREXH : T2I_ldrex<0b0101, (outs rGPR:$Rt), (ins addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "ldrexh", "\t$Rt, $addr", "", - [(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>; + [(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]>; def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr), AddrModeNone, 4, NoItinerary, "ldrex", "\t$Rt, $addr", "", - [(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]> { + [(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]> { bits<4> Rt; bits<12> addr; let Inst{31-27} = 0b11101; @@ -3363,20 +3366,23 @@ AddrModeNone, 4, NoItinerary, "strexb", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, - (strex_1 rGPR:$Rt, addr_offset_none:$addr))]>; + (strex_1 rGPR:$Rt, addr_offset_none:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]>; def t2STREXH : T2I_strex<0b0101, (outs rGPR:$Rd), (ins rGPR:$Rt, addr_offset_none:$addr), AddrModeNone, 4, NoItinerary, "strexh", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, - (strex_2 rGPR:$Rt, addr_offset_none:$addr))]>; + (strex_2 rGPR:$Rt, addr_offset_none:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]>; def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, t2addrmode_imm0_1020s4:$addr), AddrModeNone, 4, NoItinerary, "strex", "\t$Rd, $Rt, $addr", "", [(set rGPR:$Rd, - (strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]> { + (strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]>, + Requires<[IsThumb, HasV8MBaseline]> { bits<4> Rd; bits<4> Rt; bits<12> addr; @@ -3456,13 +3462,17 @@ } def : T2Pat<(and (ldrex_1 addr_offset_none:$addr), 0xff), - (t2LDREXB addr_offset_none:$addr)>; + (t2LDREXB addr_offset_none:$addr)>, + Requires<[IsThumb, HasV8MBaseline]>; def : T2Pat<(and (ldrex_2 addr_offset_none:$addr), 0xffff), - (t2LDREXH addr_offset_none:$addr)>; + (t2LDREXH addr_offset_none:$addr)>, + Requires<[IsThumb, HasV8MBaseline]>; def : T2Pat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), - (t2STREXB GPR:$Rt, addr_offset_none:$addr)>; + (t2STREXB GPR:$Rt, addr_offset_none:$addr)>, + Requires<[IsThumb, HasV8MBaseline]>; def : T2Pat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), - (t2STREXH GPR:$Rt, addr_offset_none:$addr)>; + (t2STREXH GPR:$Rt, addr_offset_none:$addr)>, + Requires<[IsThumb, HasV8MBaseline]>; def : T2Pat<(and (ldaex_1 addr_offset_none:$addr), 0xff), (t2LDAEXB addr_offset_none:$addr)>, Index: test/MC/ARM/thumbv8m.s =================================================================== --- test/MC/ARM/thumbv8m.s +++ test/MC/ARM/thumbv8m.s @@ -1,9 +1,9 @@ // RUN: not llvm-mc -triple=thumbv8m.base -show-encoding < %s 2>%t \ // RUN: | FileCheck --check-prefix=CHECK %s -// RUN: FileCheck --check-prefix=UNDEF-BASELINE < %t %s -// RUN: llvm-mc -triple=thumbv8m.main -show-encoding < %s 2>%t \ +// RUN: FileCheck --check-prefix=UNDEF-BASELINE --check-prefix=UNDEF < %t %s +// RUN: not llvm-mc -triple=thumbv8m.main -show-encoding < %s 2>%t \ // RUN: | FileCheck --check-prefix=CHECK %s -// RUN: FileCheck --check-prefix=UNDEF-MAINLINE --allow-empty < %t %s +// RUN: FileCheck --check-prefix=UNDEF-MAINLINE --check-prefix=UNDEF < %t %s // Simple check that baseline is v6M and mainline is v7M // UNDEF-BASELINE: error: instruction requires: thumb2 @@ -32,6 +32,37 @@ // CHECK: udiv r1, r2, r3 @ encoding: [0xb2,0xfb,0xf3,0xf1] udiv r1, r2, r3 +// 'Exclusives from ARMv7-M' + +// CHECK: clrex @ encoding: [0xbf,0xf3,0x2f,0x8f] +clrex + +// CHECK: ldrex r1, [r2, #4] @ encoding: [0x52,0xe8,0x01,0x1f] +ldrex r1, [r2, #4] + +// CHECK: ldrexb r1, [r2] @ encoding: [0xd2,0xe8,0x4f,0x1f] +ldrexb r1, [r2] + +// CHECK: ldrexh r1, [r2] @ encoding: [0xd2,0xe8,0x5f,0x1f] +ldrexh r1, [r2] + +// UNDEF-BASELINE: error: instruction requires: !armv*m thumb2 +// UNDEF-MAINLINE: error: instruction requires: !armv*m +ldrexd r0, r1, [r2] + +// CHECK: strex r1, r2, [r3, #4] @ encoding: [0x43,0xe8,0x01,0x21] +strex r1, r2, [r3, #4] + +// CHECK: strexb r1, r2, [r3] @ encoding: [0xc3,0xe8,0x41,0x2f] +strexb r1, r2, [r3] + +// CHECK: strexh r1, r2, [r3] @ encoding: [0xc3,0xe8,0x51,0x2f] +strexh r1, r2, [r3] + +// UNDEF-BASELINE: error: instruction requires: !armv*m thumb2 +// UNDEF-MAINLINE: error: instruction requires: !armv*m +strexd r0, r1, r2, [r3] + // 'XO generation' // CHECK: movw r1, #65535 @ encoding: [0x4f,0xf6,0xff,0x71] @@ -39,3 +70,47 @@ // CHECK: movt r1, #65535 @ encoding: [0xcf,0xf6,0xff,0x71] movt r1, #0xffff + +// 'Acquire/Release from ARMv8-A' + +// CHECK: lda r1, [r2] @ encoding: [0xd2,0xe8,0xaf,0x1f] +lda r1, [r2] + +// CHECK: ldab r1, [r2] @ encoding: [0xd2,0xe8,0x8f,0x1f] +ldab r1, [r2] + +// CHECK: ldah r1, [r2] @ encoding: [0xd2,0xe8,0x9f,0x1f] +ldah r1, [r2] + +// CHECK: stl r1, [r3] @ encoding: [0xc3,0xe8,0xaf,0x1f] +stl r1, [r3] + +// CHECK: stlb r1, [r3] @ encoding: [0xc3,0xe8,0x8f,0x1f] +stlb r1, [r3] + +// CHECK: stlh r1, [r3] @ encoding: [0xc3,0xe8,0x9f,0x1f] +stlh r1, [r3] + +// CHECK: ldaex r1, [r2] @ encoding: [0xd2,0xe8,0xef,0x1f] +ldaex r1, [r2] + +// CHECK: ldaexb r1, [r2] @ encoding: [0xd2,0xe8,0xcf,0x1f] +ldaexb r1, [r2] + +// CHECK: ldaexh r1, [r2] @ encoding: [0xd2,0xe8,0xdf,0x1f] +ldaexh r1, [r2] + +// UNDEF: error: instruction requires: !armv*m +ldaexd r0, r1, [r2] + +// CHECK: stlex r1, r2, [r3] @ encoding: [0xc3,0xe8,0xe1,0x2f] +stlex r1, r2, [r3] + +// CHECK: stlexb r1, r2, [r3] @ encoding: [0xc3,0xe8,0xc1,0x2f] +stlexb r1, r2, [r3] + +// CHECK: stlexh r1, r2, [r3] @ encoding: [0xc3,0xe8,0xd1,0x2f] +stlexh r1, r2, [r3] + +// UNDEF: error: instruction requires: !armv*m +stlexd r0, r1, r2, [r2]