manojgupta created this revision.
manojgupta added reviewers: kristof.beyls, rengolin, peter.smith, t.p.northover.
Herald added subscribers: eraman, javed.absar.

Allow rN registers to be simply parsed as correspoing xN registers.
The "register ... asm("rN")" is an command to the
compiler's register allocator, not an operand to any individual assembly
instruction. GCC documents this syntax as "...the name of the register
that should be used."

This is needed to support the changes in Linux kernel (see
https://lkml.org/lkml/2018/3/1/268 )

Note: This will add support only for the limited use case of
register ... asm("rN"). Any other uses that make rN leak into assembly
are not supported.


Repository:
  rC Clang

https://reviews.llvm.org/D44815

Files:
  lib/Basic/Targets/AArch64.cpp
  test/CodeGen/aarch64-inline-asm.c


Index: test/CodeGen/aarch64-inline-asm.c
===================================================================
--- test/CodeGen/aarch64-inline-asm.c
+++ test/CodeGen/aarch64-inline-asm.c
@@ -54,3 +54,15 @@
     asm("ldxr %0, %1" : "=r"(val) : "Q"(var));
 // CHECK: call i32 asm "ldxr $0, $1", "=r,*Q"(i64* @var)
 }
+
+void test_r_registers(void) {
+    register unsigned long reg0 asm("r0") = 0;
+    register unsigned long reg1 asm("r1") = 1;
+    register unsigned int  reg29 asm("r29") = 2;
+    register unsigned int  reg30 asm("r30") = 3;
+
+    asm volatile("hvc #0" : : "r" (reg0), "r" (reg1));
+    asm volatile("hvc #0" : : "r" (reg29), "r" (reg30));
+    // CHECK: call void asm sideeffect "hvc #0", "{x0},{x1}"
+    // CHECK: call void asm sideeffect "hvc #0", "{fp},{lr}"
+}
Index: lib/Basic/Targets/AArch64.cpp
===================================================================
--- lib/Basic/Targets/AArch64.cpp
+++ lib/Basic/Targets/AArch64.cpp
@@ -309,6 +309,15 @@
 
 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
     {{"w31"}, "wsp"}, {{"x29"}, "fp"}, {{"x30"}, "lr"}, {{"x31"}, "sp"},
+    // GCC rN registers are aliases of xN registers.
+    {{"r0"}, "x0"}, {{"r1"}, "x1"}, {{"r2"}, "x2"}, {{"r3"}, "x3"},
+    {{"r4"}, "x4"}, {{"r5"}, "x5"}, {{"r6"}, "x6"}, {{"r7"}, "x7"},
+    {{"r8"}, "x8"}, {{"r9"}, "x9"}, {{"r10"}, "x10"}, {{"r11"}, "x11"},
+    {{"r12"}, "x12"}, {{"r13"}, "x13"}, {{"r14"}, "x15"}, {{"r16"}, "x16"},
+    {{"r17"}, "x17"}, {{"r18"}, "x18"}, {{"r19"}, "x19"}, {{"r20"}, "x20"},
+    {{"r21"}, "x21"}, {{"r22"}, "x22"}, {{"r23"}, "x23"}, {{"r24"}, "x24"},
+    {{"r25"}, "x25"}, {{"r26"}, "x26"}, {{"r27"}, "x27"}, {{"r28"}, "x28"},
+    {{"r29"}, "fp"}, {{"r30"}, "lr"},
     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
     // don't want to substitute one of these for a different-sized one.
 };


Index: test/CodeGen/aarch64-inline-asm.c
===================================================================
--- test/CodeGen/aarch64-inline-asm.c
+++ test/CodeGen/aarch64-inline-asm.c
@@ -54,3 +54,15 @@
     asm("ldxr %0, %1" : "=r"(val) : "Q"(var));
 // CHECK: call i32 asm "ldxr $0, $1", "=r,*Q"(i64* @var)
 }
+
+void test_r_registers(void) {
+    register unsigned long reg0 asm("r0") = 0;
+    register unsigned long reg1 asm("r1") = 1;
+    register unsigned int  reg29 asm("r29") = 2;
+    register unsigned int  reg30 asm("r30") = 3;
+
+    asm volatile("hvc #0" : : "r" (reg0), "r" (reg1));
+    asm volatile("hvc #0" : : "r" (reg29), "r" (reg30));
+    // CHECK: call void asm sideeffect "hvc #0", "{x0},{x1}"
+    // CHECK: call void asm sideeffect "hvc #0", "{fp},{lr}"
+}
Index: lib/Basic/Targets/AArch64.cpp
===================================================================
--- lib/Basic/Targets/AArch64.cpp
+++ lib/Basic/Targets/AArch64.cpp
@@ -309,6 +309,15 @@
 
 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
     {{"w31"}, "wsp"}, {{"x29"}, "fp"}, {{"x30"}, "lr"}, {{"x31"}, "sp"},
+    // GCC rN registers are aliases of xN registers.
+    {{"r0"}, "x0"}, {{"r1"}, "x1"}, {{"r2"}, "x2"}, {{"r3"}, "x3"},
+    {{"r4"}, "x4"}, {{"r5"}, "x5"}, {{"r6"}, "x6"}, {{"r7"}, "x7"},
+    {{"r8"}, "x8"}, {{"r9"}, "x9"}, {{"r10"}, "x10"}, {{"r11"}, "x11"},
+    {{"r12"}, "x12"}, {{"r13"}, "x13"}, {{"r14"}, "x15"}, {{"r16"}, "x16"},
+    {{"r17"}, "x17"}, {{"r18"}, "x18"}, {{"r19"}, "x19"}, {{"r20"}, "x20"},
+    {{"r21"}, "x21"}, {{"r22"}, "x22"}, {{"r23"}, "x23"}, {{"r24"}, "x24"},
+    {{"r25"}, "x25"}, {{"r26"}, "x26"}, {{"r27"}, "x27"}, {{"r28"}, "x28"},
+    {{"r29"}, "fp"}, {{"r30"}, "lr"},
     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
     // don't want to substitute one of these for a different-sized one.
 };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to