or1k: Fix issue with set_got clobbering LR (r9)
authorStafford Horne <shorne@gmail.com>
Sat, 31 Aug 2019 06:00:56 +0000 (06:00 +0000)
committerStafford Horne <shorne@gcc.gnu.org>
Sat, 31 Aug 2019 06:00:56 +0000 (06:00 +0000)
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.

From-SVN: r275242

gcc/ChangeLog
gcc/config/or1k/constraints.md
gcc/config/or1k/or1k.h
gcc/config/or1k/or1k.md

index 04e773a..023275e 100644 (file)
@@ -1,3 +1,9 @@
+2019-08-31  Stafford Horne  <shorne@gmail.com>
+
+       * 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.
+
 2019-08-30  Jim Wilson  <jimw@sifive.com>
 
        * config/riscv/riscv.c (riscv_option_override): If -msave-restore
index 8cac7eb..3ca477c 100644 (file)
@@ -25,6 +25,7 @@
 ; We use:
 ;  c - sibcall registers
 ;  d - double pair base registers (excludes r0, r30 and r31 which overflow)
+;  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)
@@ -36,6 +37,9 @@
 (define_register_constraint "d" "DOUBLE_REGS"
   "Registers which can be used for double reg pairs.")
 
+(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."
index 2b29e62..4c32607 100644 (file)
@@ -190,6 +190,7 @@ enum reg_class
   NO_REGS,
   SIBCALL_REGS,
   DOUBLE_REGS,
+  GOT_REGS,
   GENERAL_REGS,
   FLAG_REGS,
   ALL_REGS,
@@ -202,6 +203,7 @@ enum reg_class
   "NO_REGS",                   \
   "SIBCALL_REGS",              \
   "DOUBLE_REGS",               \
+  "GOT_REGS",                  \
   "GENERAL_REGS",              \
   "FLAG_REGS",                 \
   "ALL_REGS" }
@@ -215,6 +217,7 @@ enum reg_class
 { { 0x00000000, 0x00000000 },  \
   { SIBCALL_REGS_MASK,   0 },  \
   { 0x7f7ffffe, 0x00000000 },  \
+  { 0xfffffdff, 0x00000000 },  \
   { 0xffffffff, 0x00000003 },  \
   { 0x00000000, 0x00000004 },  \
   { 0xffffffff, 0x00000007 }   \
index cee11d0..36bcee3 100644 (file)
 ;; 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))]
   ""
 {
 
 ;; 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))]
   ""