mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-28 22:24:28 +00:00
[ARM] Implement ISB memory barrier intrinsic
Adds support for __builtin_arm_isb. Also corrects DSB and ISB instructions modelling by adding has-side-effects property. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212276 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -56,6 +56,7 @@ def int_arm_ldaexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
|
|||||||
// Data barrier instructions
|
// Data barrier instructions
|
||||||
def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
|
def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
|
||||||
def int_arm_dsb : GCCBuiltin<"__builtin_arm_dsb">, Intrinsic<[], [llvm_i32_ty]>;
|
def int_arm_dsb : GCCBuiltin<"__builtin_arm_dsb">, Intrinsic<[], [llvm_i32_ty]>;
|
||||||
|
def int_arm_isb : GCCBuiltin<"__builtin_arm_isb">, Intrinsic<[], [llvm_i32_ty]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// VFP
|
// VFP
|
||||||
|
@ -4443,7 +4443,7 @@ def instsyncb_opt : Operand<i32> {
|
|||||||
let DecoderMethod = "DecodeInstSyncBarrierOption";
|
let DecoderMethod = "DecodeInstSyncBarrierOption";
|
||||||
}
|
}
|
||||||
|
|
||||||
// memory barriers protect the atomic sequences
|
// Memory barriers protect the atomic sequences
|
||||||
let hasSideEffects = 1 in {
|
let hasSideEffects = 1 in {
|
||||||
def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
||||||
"dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
|
"dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
|
||||||
@ -4452,7 +4452,6 @@ def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
|||||||
let Inst{31-4} = 0xf57ff05;
|
let Inst{31-4} = 0xf57ff05;
|
||||||
let Inst{3-0} = opt;
|
let Inst{3-0} = opt;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
||||||
"dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
|
"dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
|
||||||
@ -4464,12 +4463,13 @@ def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
|||||||
|
|
||||||
// ISB has only full system option
|
// ISB has only full system option
|
||||||
def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary,
|
def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary,
|
||||||
"isb", "\t$opt", []>,
|
"isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>,
|
||||||
Requires<[IsARM, HasDB]> {
|
Requires<[IsARM, HasDB]> {
|
||||||
bits<4> opt;
|
bits<4> opt;
|
||||||
let Inst{31-4} = 0xf57ff06;
|
let Inst{31-4} = 0xf57ff06;
|
||||||
let Inst{3-0} = opt;
|
let Inst{3-0} = opt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let usesCustomInserter = 1, Defs = [CPSR] in {
|
let usesCustomInserter = 1, Defs = [CPSR] in {
|
||||||
|
|
||||||
|
@ -3209,27 +3209,28 @@ def t2MOVCCi32imm
|
|||||||
let hasSideEffects = 1 in {
|
let hasSideEffects = 1 in {
|
||||||
def t2DMB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
|
def t2DMB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
|
||||||
"dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
|
"dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>,
|
||||||
Requires<[HasDB]> {
|
Requires<[IsThumb, HasDB]> {
|
||||||
bits<4> opt;
|
bits<4> opt;
|
||||||
let Inst{31-4} = 0xf3bf8f5;
|
let Inst{31-4} = 0xf3bf8f5;
|
||||||
let Inst{3-0} = opt;
|
let Inst{3-0} = opt;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
def t2DSB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
|
def t2DSB : T2I<(outs), (ins memb_opt:$opt), NoItinerary,
|
||||||
"dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
|
"dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>,
|
||||||
Requires<[HasDB]> {
|
Requires<[IsThumb, HasDB]> {
|
||||||
bits<4> opt;
|
bits<4> opt;
|
||||||
let Inst{31-4} = 0xf3bf8f4;
|
let Inst{31-4} = 0xf3bf8f4;
|
||||||
let Inst{3-0} = opt;
|
let Inst{3-0} = opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
def t2ISB : T2I<(outs), (ins instsyncb_opt:$opt), NoItinerary,
|
def t2ISB : T2I<(outs), (ins instsyncb_opt:$opt), NoItinerary,
|
||||||
"isb", "\t$opt", []>, Requires<[HasDB]> {
|
"isb", "\t$opt", [(int_arm_isb (i32 imm0_15:$opt))]>,
|
||||||
|
Requires<[IsThumb, HasDB]> {
|
||||||
bits<4> opt;
|
bits<4> opt;
|
||||||
let Inst{31-4} = 0xf3bf8f6;
|
let Inst{31-4} = 0xf3bf8f6;
|
||||||
let Inst{3-0} = opt;
|
let Inst{3-0} = opt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class T2I_ldrex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz,
|
class T2I_ldrex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz,
|
||||||
InstrItinClass itin, string opc, string asm, string cstr,
|
InstrItinClass itin, string opc, string asm, string cstr,
|
||||||
|
55
test/CodeGen/ARM/intrinsics-memory-barrier.ll
Normal file
55
test/CodeGen/ARM/intrinsics-memory-barrier.ll
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
; RUN: llc < %s -mtriple=armv7 -mattr=+db | FileCheck %s
|
||||||
|
; RUN: llc < %s -mtriple=thumbv7 -mattr=+db | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-LABEL: test
|
||||||
|
define void @test() {
|
||||||
|
call void @llvm.arm.dmb(i32 3) ; CHECK: dmb osh
|
||||||
|
call void @llvm.arm.dsb(i32 7) ; CHECK: dsb nsh
|
||||||
|
call void @llvm.arm.isb(i32 15) ; CHECK: isb sy
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Important point is that the compiler should not reorder memory access
|
||||||
|
; instructions around DMB.
|
||||||
|
; Failure to do so, two STRs will collapse into one STRD.
|
||||||
|
; CHECK-LABEL: test_dmb_reordering
|
||||||
|
define void @test_dmb_reordering(i32 %a, i32 %b, i32* %d) {
|
||||||
|
store i32 %a, i32* %d ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}]
|
||||||
|
|
||||||
|
call void @llvm.arm.dmb(i32 15) ; CHECK: dmb sy
|
||||||
|
|
||||||
|
%d1 = getelementptr i32* %d, i32 1
|
||||||
|
store i32 %b, i32* %d1 ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}, #4]
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Similarly for DSB.
|
||||||
|
; CHECK-LABEL: test_dsb_reordering
|
||||||
|
define void @test_dsb_reordering(i32 %a, i32 %b, i32* %d) {
|
||||||
|
store i32 %a, i32* %d ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}]
|
||||||
|
|
||||||
|
call void @llvm.arm.dsb(i32 15) ; CHECK: dsb sy
|
||||||
|
|
||||||
|
%d1 = getelementptr i32* %d, i32 1
|
||||||
|
store i32 %b, i32* %d1 ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}, #4]
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; And ISB.
|
||||||
|
; CHECK-LABEL: test_isb_reordering
|
||||||
|
define void @test_isb_reordering(i32 %a, i32 %b, i32* %d) {
|
||||||
|
store i32 %a, i32* %d ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}]
|
||||||
|
|
||||||
|
call void @llvm.arm.isb(i32 15) ; CHECK: isb sy
|
||||||
|
|
||||||
|
%d1 = getelementptr i32* %d, i32 1
|
||||||
|
store i32 %b, i32* %d1 ; CHECK: str {{r[0-9]+}}, [{{r[0-9]+}}, #4]
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @llvm.arm.dmb(i32)
|
||||||
|
declare void @llvm.arm.dsb(i32)
|
||||||
|
declare void @llvm.arm.isb(i32)
|
Reference in New Issue
Block a user