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