Commit fd631eb5 by Stafford Horne Committed by Stafford Horne

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.

From-SVN: r275242
parent 3ba155dd
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> 2019-08-30 Jim Wilson <jimw@sifive.com>
* config/riscv/riscv.c (riscv_option_override): If -msave-restore * config/riscv/riscv.c (riscv_option_override): If -msave-restore
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
; We use: ; We use:
; c - sibcall registers ; c - sibcall registers
; d - double pair base registers (excludes r0, r30 and r31 which overflow) ; 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 ; I - constant signed 16-bit
; K - constant unsigned 16-bit ; K - constant unsigned 16-bit
; M - constant signed 16-bit shifted left 16-bits (l.movhi) ; M - constant signed 16-bit shifted left 16-bits (l.movhi)
...@@ -36,6 +37,9 @@ ...@@ -36,6 +37,9 @@
(define_register_constraint "d" "DOUBLE_REGS" (define_register_constraint "d" "DOUBLE_REGS"
"Registers which can be used for double reg pairs.") "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 ;; Immediates
(define_constraint "I" (define_constraint "I"
"A signed 16-bit immediate in the range -32768 to 32767." "A signed 16-bit immediate in the range -32768 to 32767."
......
...@@ -190,6 +190,7 @@ enum reg_class ...@@ -190,6 +190,7 @@ enum reg_class
NO_REGS, NO_REGS,
SIBCALL_REGS, SIBCALL_REGS,
DOUBLE_REGS, DOUBLE_REGS,
GOT_REGS,
GENERAL_REGS, GENERAL_REGS,
FLAG_REGS, FLAG_REGS,
ALL_REGS, ALL_REGS,
...@@ -202,6 +203,7 @@ enum reg_class ...@@ -202,6 +203,7 @@ enum reg_class
"NO_REGS", \ "NO_REGS", \
"SIBCALL_REGS", \ "SIBCALL_REGS", \
"DOUBLE_REGS", \ "DOUBLE_REGS", \
"GOT_REGS", \
"GENERAL_REGS", \ "GENERAL_REGS", \
"FLAG_REGS", \ "FLAG_REGS", \
"ALL_REGS" } "ALL_REGS" }
...@@ -215,6 +217,7 @@ enum reg_class ...@@ -215,6 +217,7 @@ enum reg_class
{ { 0x00000000, 0x00000000 }, \ { { 0x00000000, 0x00000000 }, \
{ SIBCALL_REGS_MASK, 0 }, \ { SIBCALL_REGS_MASK, 0 }, \
{ 0x7f7ffffe, 0x00000000 }, \ { 0x7f7ffffe, 0x00000000 }, \
{ 0xfffffdff, 0x00000000 }, \
{ 0xffffffff, 0x00000003 }, \ { 0xffffffff, 0x00000003 }, \
{ 0x00000000, 0x00000004 }, \ { 0x00000000, 0x00000004 }, \
{ 0xffffffff, 0x00000007 } \ { 0xffffffff, 0x00000007 } \
......
...@@ -706,7 +706,7 @@ ...@@ -706,7 +706,7 @@
;; set_got pattern below. This works because the set_got_tmp insn is the ;; 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. ;; first insn in the stream and that it isn't moved during RA.
(define_insn "set_got_tmp" (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))] (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_GOT))]
"" ""
{ {
...@@ -715,7 +715,7 @@ ...@@ -715,7 +715,7 @@
;; The insn to initialize the GOT. ;; The insn to initialize the GOT.
(define_insn "set_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)) (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
(clobber (reg:SI LR_REGNUM))] (clobber (reg:SI LR_REGNUM))]
"" ""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment