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
This commit is contained in:
parent
3ba155dd19
commit
fd631eb5a7
4 changed files with 15 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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 } \
|
||||
|
|
|
@ -706,7 +706,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))]
|
||||
""
|
||||
{
|
||||
|
@ -715,7 +715,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))]
|
||||
""
|
||||
|
|
Loading…
Add table
Reference in a new issue