blob: 12cc5fbe03e477e5aa31e5725a311a811e1bc51b [file] [log] [blame]
Tim Northover397f9d92016-11-16 20:54:28 +00001; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
2
3define i64 @test_shl(i64 %val, i64 %amt) {
4; CHECK-LABEL: test_shl:
5 ; First calculate the hi part when the shift amount is small enough that it
6 ; contains components from both halves. It'll be returned in r1 so that's a
7 ; reasonable place for it to end up.
8; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
9; CHECK: lsr [[TMP:.*]], r0, [[REVERSE_SHIFT]]
10; CHECK: orr r1, [[TMP]], r1, lsl r2
11
12 ; Check whether the shift was in fact small (< 32 bits).
13; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
14; CHECK: cmp [[EXTRA_SHIFT]], #0
15
16 ; If not, the high part of the answer is just the low part shifted by the
17 ; excess.
18; CHECK: lslge r1, r0, [[EXTRA_SHIFT]]
19
20 ; The low part is either a direct shift (1st inst) or 0. We can reuse the same
21 ; NZCV.
22; CHECK: lsl r0, r0, r2
23; CHECK: movge r0, #0
24
25 %res = shl i64 %val, %amt
26 ret i64 %res
27}
28
29; Explanation for lshr is pretty much the reverse of shl.
30define i64 @test_lshr(i64 %val, i64 %amt) {
31; CHECK-LABEL: test_lshr:
32; CHECK: lsr r0, r0, r2
33; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
34; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
35; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
36; CHECK: cmp [[EXTRA_SHIFT]], #0
37; CHECK: lsrge r0, r1, [[EXTRA_SHIFT]]
38; CHECK: lsr r1, r1, r2
39; CHECK: movge r1, #0
40 %res = lshr i64 %val, %amt
41 ret i64 %res
42}
43
44; One minor difference for ashr: the high bits must be "hi >> 31" if the shift
45; amount is large to get the right sign bit.
46define i64 @test_ashr(i64 %val, i64 %amt) {
47; CHECK-LABEL: test_ashr:
48; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
49; CHECK: asr [[HI_TMP:.*]], r1, r2
50; CHECK: lsr r0, r0, r2
51; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
52; CHECK: cmp [[EXTRA_SHIFT]], #0
53; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
54; CHECK: asrge [[HI_TMP]], r1, #31
55; CHECK: asrge r0, r1, [[EXTRA_SHIFT]]
56; CHECK: mov r1, [[HI_TMP]]
57 %res = ashr i64 %val, %amt
58 ret i64 %res
59}