[SystemZ] Add sign-extending high-word loads (LBH and LHH)
[oota-llvm.git] / test / CodeGen / SystemZ / asm-18.ll
1 ; Test high-word operations, using "h" constraints to force a high
2 ; register and "r" constraints to force a low register.
3 ;
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
5
6 ; Test loads and stores involving mixtures of high and low registers.
7 define void @f1(i32 *%ptr1, i32 *%ptr2) {
8 ; CHECK-LABEL: f1:
9 ; CHECK-DAG: lfh [[REG1:%r[0-5]]], 0(%r2)
10 ; CHECK-DAG: l [[REG2:%r[0-5]]], 0(%r3)
11 ; CHECK-DAG: lfh [[REG3:%r[0-5]]], 4096(%r2)
12 ; CHECK-DAG: ly [[REG4:%r[0-5]]], 524284(%r3)
13 ; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]]
14 ; CHECK-DAG: stfh [[REG1]], 0(%r2)
15 ; CHECK-DAG: st [[REG2]], 0(%r3)
16 ; CHECK-DAG: stfh [[REG3]], 4096(%r2)
17 ; CHECK-DAG: sty [[REG4]], 524284(%r3)
18 ; CHECK: br %r14
19   %ptr3 = getelementptr i32 *%ptr1, i64 1024
20   %ptr4 = getelementptr i32 *%ptr2, i64 131071
21   %old1 = load i32 *%ptr1
22   %old2 = load i32 *%ptr2
23   %old3 = load i32 *%ptr3
24   %old4 = load i32 *%ptr4
25   %res = call { i32, i32, i32, i32 } asm "blah $0, $1, $2, $3",
26               "=h,=r,=h,=r,0,1,2,3"(i32 %old1, i32 %old2, i32 %old3, i32 %old4)
27   %new1 = extractvalue { i32, i32, i32, i32 } %res, 0
28   %new2 = extractvalue { i32, i32, i32, i32 } %res, 1
29   %new3 = extractvalue { i32, i32, i32, i32 } %res, 2
30   %new4 = extractvalue { i32, i32, i32, i32 } %res, 3
31   store i32 %new1, i32 *%ptr1
32   store i32 %new2, i32 *%ptr2
33   store i32 %new3, i32 *%ptr3
34   store i32 %new4, i32 *%ptr4
35   ret void
36 }
37
38 ; Test moves involving mixtures of high and low registers.
39 define i32 @f2(i32 %old) {
40 ; CHECK-LABEL: f2:
41 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 0, 159, 32
42 ; CHECK-DAG: lr %r3, %r2
43 ; CHECK: stepa [[REG1]], %r2, %r3
44 ; CHECK: risbhg {{%r[0-5]}}, [[REG1]], 0, 159, 0
45 ; CHECK: stepb [[REG2:%r[0-5]]]
46 ; CHECK: risblg %r2, [[REG2]], 0, 159, 32
47 ; CHECK: br %r14
48   %tmp = call i32 asm "stepa $1, $2, $3",
49                       "=h,0,{r2},{r3}"(i32 %old, i32 %old, i32 %old)
50   %new = call i32 asm "stepb $1, $2", "=&h,0,h"(i32 %tmp, i32 %tmp)
51   ret i32 %new
52 }
53
54 ; Test sign-extending 8-bit loads into mixtures of high and low registers.
55 define void @f3(i8 *%ptr1, i8 *%ptr2) {
56 ; CHECK-LABEL: f3:
57 ; CHECK-DAG: lbh [[REG1:%r[0-5]]], 0(%r2)
58 ; CHECK-DAG: lb [[REG2:%r[0-5]]], 0(%r3)
59 ; CHECK-DAG: lbh [[REG3:%r[0-5]]], 4096(%r2)
60 ; CHECK-DAG: lb [[REG4:%r[0-5]]], 524287(%r3)
61 ; CHECK: blah [[REG1]], [[REG2]]
62 ; CHECK: br %r14
63   %ptr3 = getelementptr i8 *%ptr1, i64 4096
64   %ptr4 = getelementptr i8 *%ptr2, i64 524287
65   %val1 = load i8 *%ptr1
66   %val2 = load i8 *%ptr2
67   %val3 = load i8 *%ptr3
68   %val4 = load i8 *%ptr4
69   %ext1 = sext i8 %val1 to i32
70   %ext2 = sext i8 %val2 to i32
71   %ext3 = sext i8 %val3 to i32
72   %ext4 = sext i8 %val4 to i32
73   call void asm sideeffect "blah $0, $1, $2, $3",
74                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
75   ret void
76 }
77
78 ; Test sign-extending 16-bit loads into mixtures of high and low registers.
79 define void @f4(i16 *%ptr1, i16 *%ptr2) {
80 ; CHECK-LABEL: f4:
81 ; CHECK-DAG: lhh [[REG1:%r[0-5]]], 0(%r2)
82 ; CHECK-DAG: lh [[REG2:%r[0-5]]], 0(%r3)
83 ; CHECK-DAG: lhh [[REG3:%r[0-5]]], 4096(%r2)
84 ; CHECK-DAG: lhy [[REG4:%r[0-5]]], 524286(%r3)
85 ; CHECK: blah [[REG1]], [[REG2]]
86 ; CHECK: br %r14
87   %ptr3 = getelementptr i16 *%ptr1, i64 2048
88   %ptr4 = getelementptr i16 *%ptr2, i64 262143
89   %val1 = load i16 *%ptr1
90   %val2 = load i16 *%ptr2
91   %val3 = load i16 *%ptr3
92   %val4 = load i16 *%ptr4
93   %ext1 = sext i16 %val1 to i32
94   %ext2 = sext i16 %val2 to i32
95   %ext3 = sext i16 %val3 to i32
96   %ext4 = sext i16 %val4 to i32
97   call void asm sideeffect "blah $0, $1, $2, $3",
98                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
99   ret void
100 }