187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86-64
287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// RUN: %clang_cc1 -triple arm64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM
387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// RUN: %clang_cc1 -triple armv7-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM
46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NOT: @sp = common global
687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#if defined(__x86_64__)
887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarregister unsigned long current_stack_pointer asm("rsp");
987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#else
106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesregister unsigned long current_stack_pointer asm("sp");
1187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#endif
1287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
13c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct p4_Thread {
14c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  struct {
15c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    int len;
16c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  } word;
17c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines};
18c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// Testing pointer types as well
1987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#if defined(__x86_64__)
2087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarregister struct p4_Thread *p4TH asm("rsp");
2187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#else
22c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesregister struct p4_Thread *p4TH asm("sp");
2387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#endif
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: define{{.*}} i[[bits:[0-9]+]] @get_stack_pointer_addr()
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: [[ret:%[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: ret i[[bits]] [[ret]]
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesunsigned long get_stack_pointer_addr() {
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return current_stack_pointer;
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: declare{{.*}} i[[bits]] @llvm.read_register.i[[bits]](metadata)
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: define{{.*}} void @set_stack_pointer_addr(i[[bits]] %addr) #0 {
343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[sto:%[0-9]+]] = load i[[bits]], i[[bits]]* %
356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] [[sto]])
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: ret void
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid set_stack_pointer_addr(unsigned long addr) {
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  current_stack_pointer = addr;
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: declare{{.*}} void @llvm.write_register.i[[bits]](metadata, i[[bits]])
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
42c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: define {{.*}}@fn1
43c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesint fn1() {
44c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return (*p4TH).word.len;
45c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
46c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: %[[regr:[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
47c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: inttoptr i[[bits]] %[[regr]] to %struct.p4_Thread*
48c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
49c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: define {{.*}}@fn2
50c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid fn2(struct p4_Thread *val) {
51c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  p4TH = val;
52c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
53c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: %[[regw:[0-9]+]] = ptrtoint %struct.p4_Thread* %{{.*}} to i[[bits]]
54c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] %[[regw]])
55c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
5687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-X86-64: !llvm.named.register.rsp = !{!0}
5787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-X86-64: !0 = !{!"rsp"}
5887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-ARM: !llvm.named.register.sp = !{!0}
5987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-ARM: !0 = !{!"sp"}
60