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