llvm.org GIT mirror llvm / a86a586
X86: Add patterns for the movbe instruction (mov + bswap, only available on atom) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141563 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 8 years ago
4 changed file(s) with 49 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
0 //===---------------------------------------------------------------------===//
11 // Random ideas for the X86 backend.
2 //===---------------------------------------------------------------------===//
3
4 We should add support for the "movbe" instruction, which does a byte-swapping
5 copy (3-addr bswap + memory support?) This is available on Atom processors.
6
72 //===---------------------------------------------------------------------===//
83
94 This should be one DIV/IDIV instruction, not a libcall:
132132 FeatureSlowBTMem]>;
133133 def : Proc<"penryn", [FeatureSSE41, FeatureCMPXCHG16B,
134134 FeatureSlowBTMem]>;
135 def : Proc<"atom", [FeatureSSE3, FeatureCMPXCHG16B,
135 def : Proc<"atom", [FeatureSSE3, FeatureCMPXCHG16B, FeatureMOVBE,
136136 FeatureSlowBTMem]>;
137137 // "Arrandale" along with corei3 and corei5
138138 def : Proc<"corei7", [FeatureSSE42, FeatureCMPXCHG16B,
13071307 //
13081308 let Predicates = [HasMOVBE] in {
13091309 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1310 "movbe{w}\t{$src, $dst|$dst, $src}", []>, OpSize, T8;
1310 "movbe{w}\t{$src, $dst|$dst, $src}",
1311 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>, OpSize, T8;
13111312 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1312 "movbe{l}\t{$src, $dst|$dst, $src}", []>, T8;
1313 "movbe{l}\t{$src, $dst|$dst, $src}",
1314 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>, T8;
13131315 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1314 "movbe{q}\t{$src, $dst|$dst, $src}", []>, T8;
1316 "movbe{q}\t{$src, $dst|$dst, $src}",
1317 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>, T8;
13151318 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1316 "movbe{w}\t{$src, $dst|$dst, $src}", []>, OpSize, T8;
1319 "movbe{w}\t{$src, $dst|$dst, $src}",
1320 [(store (bswap GR16:$src), addr:$dst)]>, OpSize, T8;
13171321 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1318 "movbe{l}\t{$src, $dst|$dst, $src}", []>, T8;
1322 "movbe{l}\t{$src, $dst|$dst, $src}",
1323 [(store (bswap GR32:$src), addr:$dst)]>, T8;
13191324 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1320 "movbe{q}\t{$src, $dst|$dst, $src}", []>, T8;
1325 "movbe{q}\t{$src, $dst|$dst, $src}",
1326 [(store (bswap GR64:$src), addr:$dst)]>, T8;
13211327 }
13221328
13231329 //===----------------------------------------------------------------------===//
0 ; RUN: llc -march=x86-64 -mcpu=atom < %s | FileCheck %s
1
2 declare i32 @llvm.bswap.i32(i32) nounwind readnone
3 declare i64 @llvm.bswap.i64(i64) nounwind readnone
4
5 define void @test1(i32* nocapture %x, i32 %y) nounwind {
6 %bswap = call i32 @llvm.bswap.i32(i32 %y)
7 store i32 %bswap, i32* %x, align 4
8 ret void
9 ; CHECK: test1:
10 ; CHECK: movbel %esi, (%rdi)
11 }
12
13 define i32 @test2(i32* %x) nounwind {
14 %load = load i32* %x, align 4
15 %bswap = call i32 @llvm.bswap.i32(i32 %load)
16 ret i32 %bswap
17 ; CHECK: test2:
18 ; CHECK: movbel (%rdi), %eax
19 }
20
21 define void @test3(i64* %x, i64 %y) nounwind {
22 %bswap = call i64 @llvm.bswap.i64(i64 %y)
23 store i64 %bswap, i64* %x, align 8
24 ret void
25 ; CHECK: test3:
26 ; CHECK: movbeq %rsi, (%rdi)
27 }
28
29 define i64 @test4(i64* %x) nounwind {
30 %load = load i64* %x, align 8
31 %bswap = call i64 @llvm.bswap.i64(i64 %load)
32 ret i64 %bswap
33 ; CHECK: test4:
34 ; CHECK: movbeq (%rdi), %rax
35 }