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