1From 7a20b4574f06472086c786bd1b078ee962cdb02c Mon Sep 17 00:00:00 2001
2From: Stafford Horne <shorne@gmail.com>
3Date: Tue, 6 Apr 2021 05:47:17 +0900
4Subject: [PATCH] or1k: Add mcmodel option to handle large GOTs
5
6When building libgeos we get an error with:
7
8    linux-uclibc/9.3.0/crtbeginS.o: in function `__do_global_dtors_aux':
9    crtstuff.c:(.text+0x118): relocation truncated to fit: R_OR1K_GOT16 against symbol `__cxa_finalize' defined in .text section in
10    /home/shorne/work/openrisc/3eb9f9d0f6d8274b2d19753c006bd83f7d536e3c/output/host/or1k-buildroot-linux-uclibc/sysroot/lib/libc.so.
11
12This is caused by GOT code having a limit of 64k.  In OpenRISC this
13looks to be the only relocation code pattern to be limited to 64k.
14
15This patch allows specifying a new option -mcmodel=large which can be
16used to generate 2 more instructions to construct 32-bit addresses for
17up to 4G GOTs.
18
19gcc/ChangeLog:
20
21	PR target/99783
22	* config/or1k/or1k-opts.h: New file.
23	* config/or1k/or1k.c (or1k_legitimize_address_1, print_reloc):
24	Support generating gotha relocations if -mcmodel=large is
25	specified.
26	* config/or1k/or1k.h (TARGET_CMODEL_SMALL, TARGET_CMODEL_LARGE):
27	New macros.
28	* config/or1k/or1k.opt (mcmodel=): New option.
29	* doc/invoke.texi (OpenRISC Options): Document mcmodel.
30
31Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
32---
33 gcc/config/or1k/or1k-opts.h | 30 ++++++++++++++++++++++++++++++
34 gcc/config/or1k/or1k.c      | 11 +++++++++--
35 gcc/config/or1k/or1k.h      |  7 +++++++
36 gcc/config/or1k/or1k.opt    | 19 +++++++++++++++++++
37 gcc/doc/invoke.texi         | 12 +++++++++++-
38 5 files changed, 76 insertions(+), 3 deletions(-)
39 create mode 100644 gcc/config/or1k/or1k-opts.h
40
41diff --git a/gcc/config/or1k/or1k-opts.h b/gcc/config/or1k/or1k-opts.h
42new file mode 100644
43index 00000000000..f791b894fdd
44--- /dev/null
45+++ b/gcc/config/or1k/or1k-opts.h
46@@ -0,0 +1,30 @@
47+/* Definitions for option handling for OpenRISC.
48+   Copyright (C) 2021 Free Software Foundation, Inc.
49+   Contributed by Stafford Horne.
50+
51+   This file is part of GCC.
52+
53+   GCC is free software; you can redistribute it and/or modify it
54+   under the terms of the GNU General Public License as published
55+   by the Free Software Foundation; either version 3, or (at your
56+   option) any later version.
57+
58+   GCC is distributed in the hope that it will be useful, but WITHOUT
59+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
60+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
61+   License for more details.
62+
63+   You should have received a copy of the GNU General Public License
64+   along with GCC; see the file COPYING3.  If not see
65+   <http://www.gnu.org/licenses/>.  */
66+
67+#ifndef GCC_OR1K_OPTS_H
68+#define GCC_OR1K_OPTS_H
69+
70+/* The OpenRISC code generation models available.  */
71+enum or1k_cmodel_type {
72+  CMODEL_SMALL,
73+  CMODEL_LARGE
74+};
75+
76+#endif /* GCC_OR1K_OPTS_H */
77diff --git a/gcc/config/or1k/or1k.c b/gcc/config/or1k/or1k.c
78index e772a7addea..27d3fa17995 100644
79--- a/gcc/config/or1k/or1k.c
80+++ b/gcc/config/or1k/or1k.c
81@@ -750,7 +750,14 @@ or1k_legitimize_address_1 (rtx x, rtx scratch)
82 	    {
83 	      base = gen_sym_unspec (base, UNSPEC_GOT);
84 	      crtl->uses_pic_offset_table = 1;
85-	      t2 = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, base);
86+	      if (TARGET_CMODEL_LARGE)
87+		{
88+	          emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
89+	          emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
90+	          t2 = gen_rtx_LO_SUM (Pmode, t1, base);
91+		}
92+	      else
93+	        t2 = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, base);
94 	      t2 = gen_const_mem (Pmode, t2);
95 	      emit_insn (gen_rtx_SET (t1, t2));
96 	      base = t1;
97@@ -1089,7 +1096,7 @@ print_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, reloc_kind kind)
98      no special markup.  */
99   static const char * const relocs[RKIND_MAX][RTYPE_MAX] = {
100     { "lo", "got", "gotofflo", "tpofflo", "gottpofflo", "tlsgdlo" },
101-    { "ha", NULL,  "gotoffha", "tpoffha", "gottpoffha", "tlsgdhi" },
102+    { "ha", "gotha", "gotoffha", "tpoffha", "gottpoffha", "tlsgdhi" },
103   };
104   reloc_type type = RTYPE_DIRECT;
105
106diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h
107index fe01ab81ead..669907e7e74 100644
108--- a/gcc/config/or1k/or1k.h
109+++ b/gcc/config/or1k/or1k.h
110@@ -21,6 +21,8 @@
111 #ifndef GCC_OR1K_H
112 #define GCC_OR1K_H
113
114+#include "config/or1k/or1k-opts.h"
115+
116 /* Names to predefine in the preprocessor for this target machine.  */
117 #define TARGET_CPU_CPP_BUILTINS()		\
118   do						\
119@@ -37,6 +39,11 @@
120     }						\
121   while (0)
122
123+#define TARGET_CMODEL_SMALL \
124+  (or1k_code_model == CMODEL_SMALL)
125+#define TARGET_CMODEL_LARGE \
126+  (or1k_code_model == CMODEL_LARGE)
127+
128 /* Storage layout.  */
129
130 #define DEFAULT_SIGNED_CHAR 1
131diff --git a/gcc/config/or1k/or1k.opt b/gcc/config/or1k/or1k.opt
132index 6bd0f3eee6d..cc23e3b8856 100644
133--- a/gcc/config/or1k/or1k.opt
134+++ b/gcc/config/or1k/or1k.opt
135@@ -21,6 +21,9 @@
136 ; See the GCC internals manual (options.texi) for a description of
137 ; this file's format.
138
139+HeaderInclude
140+config/or1k/or1k-opts.h
141+
142 mhard-div
143 Target RejectNegative InverseMask(SOFT_DIV)
144 Enable generation of hardware divide (l.div, l.divu) instructions.  This is the
145@@ -63,6 +66,22 @@ When -mhard-float is selected, enables generation of unordered floating point
146 compare and set flag (lf.sfun*) instructions.  By default functions from libgcc
147 are used to perform unordered floating point compare and set flag operations.
148
149+mcmodel=
150+Target RejectNegative Joined Enum(or1k_cmodel_type) Var(or1k_code_model) Init(CMODEL_SMALL)
151+Specify the code model used for accessing memory addresses.  Specifying large
152+enables generating binaries with large global offset tables.  By default the
153+value is small.
154+
155+Enum
156+Name(or1k_cmodel_type) Type(enum or1k_cmodel_type)
157+Known code model types (for use with the -mcmodel= option):
158+
159+EnumValue
160+Enum(or1k_cmodel_type) String(small) Value(CMODEL_SMALL)
161+
162+EnumValue
163+Enum(or1k_cmodel_type) String(large) Value(CMODEL_LARGE)
164+
165 mcmov
166 Target RejectNegative Mask(CMOV)
167 Enable generation of conditional move (l.cmov) instructions.  By default the
168diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
169index 35508efb4ef..a1b7608a3aa 100644
170--- a/gcc/doc/invoke.texi
171+++ b/gcc/doc/invoke.texi
172@@ -1136,7 +1136,8 @@ Objective-C and Objective-C++ Dialects}.
173 @gccoptlist{-mboard=@var{name}  -mnewlib  -mhard-mul  -mhard-div @gol
174 -msoft-mul  -msoft-div @gol
175 -msoft-float  -mhard-float  -mdouble-float -munordered-float @gol
176--mcmov  -mror  -mrori  -msext  -msfimm  -mshftimm}
177+-mcmov  -mror  -mrori  -msext  -msfimm  -mshftimm @gol
178+-mcmodel=@var{code-model}}
179
180 @emph{PDP-11 Options}
181 @gccoptlist{-mfpu  -msoft-float  -mac0  -mno-ac0  -m40  -m45  -m10 @gol
182@@ -26443,6 +26444,15 @@ Enable generation of shift with immediate (@code{l.srai}, @code{l.srli},
183 @code{l.slli}) instructions.  By default extra instructions will be generated
184 to store the immediate to a register first.
185
186+@item -mcmodel=small
187+@opindex mcmodel=small
188+Generate OpenRISC code for the small model: The GOT is limited to 64k. This is
189+the default model.
190+
191+@item -mcmodel=large
192+@opindex mcmodel=large
193+Generate OpenRISC code for the large model: The GOT may grow up to 4G in size.
194+
195
196 @end table
197
198--
1992.35.1
200
201