llvm.org GIT mirror llvm / 4897151
[ARMv8] Implement the new DMB/DSB operands. This removes the custom ISD Node: MEMBARRIER and replaces it with an intrinsic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190055 91177308-0d34-0410-b5e6-96231b3b80d8 Joey Gouly 6 years ago
10 changed file(s) with 84 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
4242 def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
4343 llvm_ptr_ty]>;
4444 def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
45
46 //===----------------------------------------------------------------------===//
47 // Data barrier instructions
48 def int_arm_dmb : Intrinsic<[], [llvm_i32_ty]>;
49 def int_arm_dsb : Intrinsic<[], [llvm_i32_ty]>;
4550
4651 //===----------------------------------------------------------------------===//
4752 // VFP
10091009
10101010 case ARMISD::DYN_ALLOC: return "ARMISD::DYN_ALLOC";
10111011
1012 case ARMISD::MEMBARRIER: return "ARMISD::MEMBARRIER";
10131012 case ARMISD::MEMBARRIER_MCR: return "ARMISD::MEMBARRIER_MCR";
10141013
10151014 case ARMISD::PRELOAD: return "ARMISD::PRELOAD";
26092608 Domain = ARM_MB::ISHST;
26102609 }
26112610
2612 return DAG.getNode(ARMISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0),
2611 return DAG.getNode(ISD::INTRINSIC_VOID, dl, MVT::Other, Op.getOperand(0),
2612 DAG.getConstant(Intrinsic::arm_dmb, MVT::i32),
26132613 DAG.getConstant(Domain, MVT::i32));
26142614 }
26152615
9393
9494 DYN_ALLOC, // Dynamic allocation on the stack.
9595
96 MEMBARRIER, // Memory barrier (DMB)
9796 MEMBARRIER_MCR, // Memory barrier (MCR)
9897
9998 PRELOAD, // Preload
164164 SDT_ARMEH_SJLJ_Longjmp,
165165 [SDNPHasChain, SDNPSideEffect]>;
166166
167 def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
168 [SDNPHasChain, SDNPSideEffect]>;
169167 def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
170168 [SDNPHasChain, SDNPSideEffect]>;
171169 def ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPREFETCH,
42644262 // memory barriers protect the atomic sequences
42654263 let hasSideEffects = 1 in {
42664264 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4267 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
4265 "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
42684266 Requires<[IsARM, HasDB]> {
42694267 bits<4> opt;
42704268 let Inst{31-4} = 0xf57ff05;
42734271 }
42744272
42754273 def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4276 "dsb", "\t$opt", []>,
4274 "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
42774275 Requires<[IsARM, HasDB]> {
42784276 bits<4> opt;
42794277 let Inst{31-4} = 0xf57ff04;
31543154 // memory barriers protect the atomic sequences
31553155 let hasSideEffects = 1 in {
31563156 def t2DMB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
3157 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
3157 "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
31583158 Requires<[HasDB]> {
31593159 bits<4> opt;
31603160 let Inst{31-4} = 0xf3bf8f5;
31633163 }
31643164
31653165 def t2DSB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
3166 "dsb", "\t$opt", []>, Requires<[HasDB]> {
3166 "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
3167 Requires<[HasDB]> {
31673168 bits<4> opt;
31683169 let Inst{31-4} = 0xf3bf8f4;
31693170 let Inst{3-0} = opt;
25202520 getImm()->print(OS);
25212521 break;
25222522 case k_MemBarrierOpt:
2523 OS << ") << ">";
2523 OS << ", false) << ">";
25242524 break;
25252525 case k_InstSyncBarrierOpt:
25262526 OS << "";
34653465 Opt = StringSwitch(OptStr.slice(0, OptStr.size()).lower())
34663466 .Case("sy", ARM_MB::SY)
34673467 .Case("st", ARM_MB::ST)
3468 .Case("ld", ARM_MB::LD)
34683469 .Case("sh", ARM_MB::ISH)
34693470 .Case("ish", ARM_MB::ISH)
34703471 .Case("shst", ARM_MB::ISHST)
34713472 .Case("ishst", ARM_MB::ISHST)
3473 .Case("ishld", ARM_MB::ISHLD)
34723474 .Case("nsh", ARM_MB::NSH)
34733475 .Case("un", ARM_MB::NSH)
34743476 .Case("nshst", ARM_MB::NSHST)
3477 .Case("nshld", ARM_MB::NSHLD)
34753478 .Case("unst", ARM_MB::NSHST)
34763479 .Case("osh", ARM_MB::OSH)
34773480 .Case("oshst", ARM_MB::OSHST)
3481 .Case("oshld", ARM_MB::OSHLD)
34783482 .Default(~0U);
3483
3484 // ishld, oshld, nshld and ld are only available from ARMv8.
3485 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
3486 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
3487 Opt = ~0U;
34793488
34803489 if (Opt == ~0U)
34813490 return MatchOperand_NoMatch;
676676 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
677677 raw_ostream &O) {
678678 unsigned val = MI->getOperand(OpNum).getImm();
679 O << ARM_MB::MemBOptToString(val);
679 O << ARM_MB::MemBOptToString(val, (getAvailableFeatures() & ARM::HasV8Ops));
680680 }
681681
682682 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
120120 // the option field for memory barrier operations.
121121 enum MemBOpt {
122122 RESERVED_0 = 0,
123 RESERVED_1 = 1,
123 OSHLD = 1,
124124 OSHST = 2,
125125 OSH = 3,
126126 RESERVED_4 = 4,
127 RESERVED_5 = 5,
127 NSHLD = 5,
128128 NSHST = 6,
129129 NSH = 7,
130130 RESERVED_8 = 8,
131 RESERVED_9 = 9,
131 ISHLD = 9,
132132 ISHST = 10,
133133 ISH = 11,
134134 RESERVED_12 = 12,
135 RESERVED_13 = 13,
135 LD = 13,
136136 ST = 14,
137137 SY = 15
138138 };
139139
140 inline static const char *MemBOptToString(unsigned val) {
140 inline static const char *MemBOptToString(unsigned val, bool HasV8) {
141141 switch (val) {
142142 default: llvm_unreachable("Unknown memory operation");
143143 case SY: return "sy";
144144 case ST: return "st";
145 case RESERVED_13: return "#0xd";
145 case LD: return HasV8 ? "ld" : "#0xd";
146146 case RESERVED_12: return "#0xc";
147147 case ISH: return "ish";
148148 case ISHST: return "ishst";
149 case RESERVED_9: return "#0x9";
149 case ISHLD: return HasV8 ? "ishld" : "#0x9";
150150 case RESERVED_8: return "#0x8";
151151 case NSH: return "nsh";
152152 case NSHST: return "nshst";
153 case RESERVED_5: return "#0x5";
153 case NSHLD: return HasV8 ? "nshld" : "#0x5";
154154 case RESERVED_4: return "#0x4";
155155 case OSH: return "osh";
156156 case OSHST: return "oshst";
157 case RESERVED_1: return "#0x1";
157 case OSHLD: return HasV8 ? "oshld" : "#0x1";
158158 case RESERVED_0: return "#0x0";
159159 }
160160 }
0 ; RUN: llc < %s -mtriple=armv8 -mattr=+db | FileCheck %s
1
2 define void @test() {
3 ; CHECK: dmb sy
4 call void @llvm.arm.dmb(i32 15)
5 ; CHECK: dmb osh
6 call void @llvm.arm.dmb(i32 3)
7 ; CHECK: dsb sy
8 call void @llvm.arm.dsb(i32 15)
9 ; CHECK: dsb ishld
10 call void @llvm.arm.dsb(i32 9)
11 ret void
12 }
13
14 declare void @llvm.arm.dmb(i32)
15 declare void @llvm.arm.dsb(i32)
0 @ New ARMv8 A32 encodings
11
2 @ RUN: llvm-mc -triple armv8 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-V8
2 @ RUN: not llvm-mc -triple armv8 -show-encoding -mattr=+db < %s | FileCheck %s --check-prefix=CHECK-V8
33 @ RUN: not llvm-mc -triple armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7
44
55 @ HLT
1414 hltal #0
1515 @ CHECK-V8: hlt #0 @ encoding: [0x70,0x00,0x00,0xe1]
1616 @ CHECK-V7: error: instruction requires: armv8
17
18 @------------------------------------------------------------------------------
19 @ DMB (v8 barriers)
20 @------------------------------------------------------------------------------
21 dmb ishld
22 dmb oshld
23 dmb nshld
24 dmb ld
25 dmb #20
26
27 @ CHECK-V8: dmb ishld @ encoding: [0x59,0xf0,0x7f,0xf5]
28 @ CHECK-V8: dmb oshld @ encoding: [0x51,0xf0,0x7f,0xf5]
29 @ CHECK-V8: dmb nshld @ encoding: [0x55,0xf0,0x7f,0xf5]
30 @ CHECK-V8: dmb ld @ encoding: [0x5d,0xf0,0x7f,0xf5]
31 @ CHECK-V7: error: invalid operand for instruction
32 @ CHECK-V7: error: invalid operand for instruction
33 @ CHECK-V7: error: invalid operand for instruction
34 @ CHECK-V7: error: invalid operand for instruction
35 @ CHECK-V7: error: immediate value out of range
36
37 @------------------------------------------------------------------------------
38 @ DSB (v8 barriers)
39 @------------------------------------------------------------------------------
40 dsb ishld
41 dsb oshld
42 dsb nshld
43 dsb ld
44
45 @ CHECK-V8: dsb ishld @ encoding: [0x49,0xf0,0x7f,0xf5]
46 @ CHECK-V8: dsb oshld @ encoding: [0x41,0xf0,0x7f,0xf5]
47 @ CHECK-V8: dsb nshld @ encoding: [0x45,0xf0,0x7f,0xf5]
48 @ CHECK-V8: dsb ld @ encoding: [0x4d,0xf0,0x7f,0xf5]
49 @ CHECK-V7: error: invalid operand for instruction
50 @ CHECK-V7: error: invalid operand for instruction
51 @ CHECK-V7: error: invalid operand for instruction