package/gcc/9.2.0: backport or1k upstream patch
authorRomain Naour <romain.naour@gmail.com>
Sat, 19 Oct 2019 22:31:05 +0000 (00:31 +0200)
committerThomas Petazzoni <thomas.petazzoni@bootlin.com>
Sun, 20 Oct 2019 14:18:10 +0000 (16:18 +0200)
Without this patch, the system build using qemu_or1k_defconfig
(gcc 9.2, binutils 2.33.1 and uClibc 1.0.32) doesn't boot.

https://mailman.uclibc-ng.org/pipermail/devel/2019-August/001895.html

Signed-off-by: Romain Naour <romain.naour@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
package/gcc/9.2.0/0003-or1k-Fix-issue-with-set_got-clobbering-LR-r9.patch [new file with mode: 0644]

diff --git a/package/gcc/9.2.0/0003-or1k-Fix-issue-with-set_got-clobbering-LR-r9.patch b/package/gcc/9.2.0/0003-or1k-Fix-issue-with-set_got-clobbering-LR-r9.patch
new file mode 100644 (file)
index 0000000..bdde2ce
--- /dev/null
@@ -0,0 +1,105 @@
+From 94c7d630348671b781368d9270514dcf6c34e0c9 Mon Sep 17 00:00:00 2001
+From: shorne <shorne@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Sat, 31 Aug 2019 06:00:56 +0000
+Subject: [PATCH] or1k: Fix issue with set_got clobbering LR (r9)
+
+When compiling glibc we found that the GOT register was being allocated
+r9 when the instruction was still set_got_tmp.  That is a problem
+because r9 is the Link Register (LR) in OpenRISC which is used/clobbered
+in set_got.  We cannot use r9 as the GOT register.  Also, we cannot
+simply say set_got_tmp clobbers r9 as this is the reason for having the
+temporary set_got_tmp.
+
+Fix by using a register class constraint that does not allow r9 during
+register allocation.
+
+gcc/ChangeLog:
+
+        * config/or1k/constraints.md (t): New constraint.
+        * config/or1k/or1k.h (GOT_REGS): New register class.
+        * config/or1k/or1k.md (set_got_tmp, set_got): Use t contraint.
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@275242 138bc75d-0d04-0410-961f-82ee72b054a4
+(cherry picked from commit 5b9471ffca25d39635680516ba2ff85295480fc3)
+Signed-off-by: Romain Naour <romain.naour@gmail.com>
+---
+ gcc/config/or1k/constraints.md | 4 ++++
+ gcc/config/or1k/or1k.h         | 3 +++
+ gcc/config/or1k/or1k.md        | 4 ++--
+ 3 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md
+index 93da8c058c6..a16b749008f 100644
+--- a/gcc/config/or1k/constraints.md
++++ b/gcc/config/or1k/constraints.md
+@@ -24,6 +24,7 @@
+ ; We use:
+ ;  c - sibcall registers
++;  t - got address registers (excludes LR (r9) which is clobbered by set_got)
+ ;  I - constant signed 16-bit
+ ;  K - constant unsigned 16-bit
+ ;  M - constant signed 16-bit shifted left 16-bits (l.movhi)
+@@ -32,6 +33,9 @@
+ (define_register_constraint "c" "SIBCALL_REGS"
+   "Registers which can hold a sibling call address")
++(define_register_constraint "t" "GOT_REGS"
++  "Registers which can be used to store the Global Offset Table (GOT) address.")
++
+ ;; Immediates
+ (define_constraint "I"
+   "A signed 16-bit immediate in the range -32768 to 32767."
+diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h
+index 6dda230f217..feee702d89c 100644
+--- a/gcc/config/or1k/or1k.h
++++ b/gcc/config/or1k/or1k.h
+@@ -189,6 +189,7 @@ enum reg_class
+ {
+   NO_REGS,
+   SIBCALL_REGS,
++  GOT_REGS,
+   GENERAL_REGS,
+   FLAG_REGS,
+   ALL_REGS,
+@@ -200,6 +201,7 @@ enum reg_class
+ #define REG_CLASS_NAMES {     \
+   "NO_REGS",                  \
+   "SIBCALL_REGS",             \
++  "GOT_REGS",                 \
+   "GENERAL_REGS",             \
+   "FLAG_REGS",                        \
+   "ALL_REGS" }
+@@ -212,6 +214,7 @@ enum reg_class
+ #define REG_CLASS_CONTENTS      \
+ { { 0x00000000, 0x00000000 }, \
+   { SIBCALL_REGS_MASK,   0 }, \
++  { 0xfffffdff, 0x00000000 }, \
+   { 0xffffffff, 0x00000003 }, \
+   { 0x00000000, 0x00000004 }, \
+   { 0xffffffff, 0x00000007 }  \
+diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md
+index 2dad51cd46b..88f3f02630f 100644
+--- a/gcc/config/or1k/or1k.md
++++ b/gcc/config/or1k/or1k.md
+@@ -595,7 +595,7 @@
+ ;; set_got pattern below.  This works because the set_got_tmp insn is the
+ ;; first insn in the stream and that it isn't moved during RA.
+ (define_insn "set_got_tmp"
+-  [(set (match_operand:SI 0 "register_operand" "=r")
++  [(set (match_operand:SI 0 "register_operand" "=t")
+       (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_GOT))]
+   ""
+ {
+@@ -604,7 +604,7 @@
+ ;; The insn to initialize the GOT.
+ (define_insn "set_got"
+-  [(set (match_operand:SI 0 "register_operand" "=r")
++  [(set (match_operand:SI 0 "register_operand" "=t")
+       (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
+    (clobber (reg:SI LR_REGNUM))]
+   ""
+-- 
+2.23.0
+