diff options
author | Stafford Horne <shorne@gmail.com> | 2019-08-31 06:00:56 +0000 |
---|---|---|
committer | Stafford Horne <shorne@gcc.gnu.org> | 2019-08-31 06:00:56 +0000 |
commit | fd631eb5a7597a7040f770b2a912cec13af50df4 (patch) | |
tree | 29306617e9d66d1e5b92c3832c3ab9d2e5d7a0f0 /gcc | |
parent | 3ba155dd1921b55f04866b35a2e054e092670cd6 (diff) | |
download | gcc-fd631eb5a7597a7040f770b2a912cec13af50df4.zip gcc-fd631eb5a7597a7040f770b2a912cec13af50df4.tar.gz gcc-fd631eb5a7597a7040f770b2a912cec13af50df4.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/or1k/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/or1k/or1k.h | 3 | ||||
-rw-r--r-- | gcc/config/or1k/or1k.md | 4 |
4 files changed, 15 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04e773a..023275e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md index 8cac7eb..3ca477c 100644 --- a/gcc/config/or1k/constraints.md +++ b/gcc/config/or1k/constraints.md @@ -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." diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h index 2b29e62..4c32607 100644 --- a/gcc/config/or1k/or1k.h +++ b/gcc/config/or1k/or1k.h @@ -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 } \ diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md index cee11d0..36bcee3 100644 --- a/gcc/config/or1k/or1k.md +++ b/gcc/config/or1k/or1k.md @@ -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))] "" |