From 230c5eb4bde7314331ae5c0bca65087ed504202c Mon Sep 17 00:00:00 2001 From: Renato Golin Date: Mon, 19 May 2014 18:15:42 +0000 Subject: Non-allocatable Global Named Register This patch implements global named registers in Clang, lowering to the just created intrinsics in LLVM (@llvm.read/write_register). A new type of LValue had to be created (Register), which just adds support to carry the metadata node containing the name of the register. Two new methods to emit loads and stores interoperate with another to emit the named metadata node. No guarantees are being made and only non-allocatable global variable named registers are being supported. Local named register support is unchanged. llvm-svn: 209149 --- clang/test/CodeGen/named_reg_global.c | 26 ++++++++++++++++++++++++++ clang/test/Sema/asm.c | 2 -- clang/test/Sema/decl-invalid.c | 1 - 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/named_reg_global.c (limited to 'clang/test') diff --git a/clang/test/CodeGen/named_reg_global.c b/clang/test/CodeGen/named_reg_global.c new file mode 100644 index 00000000000..0a4646f7bdb --- /dev/null +++ b/clang/test/CodeGen/named_reg_global.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple armv7-linux-gnu -S -emit-llvm %s -o - | FileCheck %s + +register unsigned long current_stack_pointer asm("sp"); + +// CHECK: define{{.*}} i[[bits:[0-9]+]] @get_stack_pointer_addr() +// CHECK: [[ret:%[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0) +// CHECK: ret i[[bits]] [[ret]] +unsigned long get_stack_pointer_addr() { + return current_stack_pointer; +} +// CHECK: declare{{.*}} i[[bits]] @llvm.read_register.i[[bits]](metadata) + +// CHECK: define{{.*}} void @set_stack_pointer_addr(i[[bits]] %addr) #0 { +// CHECK: [[sto:%[0-9]+]] = load i[[bits]]* %addr +// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] [[sto]]) +// CHECK: ret void +void set_stack_pointer_addr(unsigned long addr) { + current_stack_pointer = addr; +} +// CHECK: declare{{.*}} void @llvm.write_register.i[[bits]](metadata, i[[bits]]) + +// CHECK: !llvm.named.register.sp = !{!0} +// CHECK: !0 = metadata !{metadata !"sp"} diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c index 1559b228c87..4d84afce765 100644 --- a/clang/test/Sema/asm.c +++ b/clang/test/Sema/asm.c @@ -95,8 +95,6 @@ void test9(int i) { asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}} } -register int g asm("dx"); // expected-error{{global register variables are not supported}} - void test10(void){ static int g asm ("g_asm") = 0; extern int gg asm ("gg_asm"); diff --git a/clang/test/Sema/decl-invalid.c b/clang/test/Sema/decl-invalid.c index 0544304c20e..c7ec6dd725d 100644 --- a/clang/test/Sema/decl-invalid.c +++ b/clang/test/Sema/decl-invalid.c @@ -24,5 +24,4 @@ I; // expected-warning {{declaration does not declare anything}} // rdar://6880449 register int test1; // expected-error {{illegal storage class on file-scoped variable}} -register int test2 __asm__("edi"); // expected-error {{global register variables are not supported}} -- cgit v1.2.3