Remove building with NOCRYPTO option
[minix3.git] / external / gpl3 / gcc / patches / 0000-gcc_nbsd.patch
blob4856e4371eb92abf4b191285ce00513d46f15328
1 diff -rNU3 dist.orig/.gitignore dist/.gitignore
2 --- dist.orig/.gitignore 2013-01-10 16:48:46.000000000 +0100
3 +++ dist/.gitignore 1970-01-01 01:00:00.000000000 +0100
4 @@ -1,42 +0,0 @@
5 -*.diff
6 -*.patch
7 -*.orig
8 -*.rej
10 -*~
11 -.#*
12 -*#
14 -*.flt
15 -*.gmo
16 -*.info
17 -*.la
18 -*.lo
19 -*.o
20 -*.pyc
21 -*.tmp
23 -.deps
24 -.libs
26 -autom4te.cache
27 -config.cache
28 -config.h
29 -config.intl
30 -config.log
31 -config.status
32 -libtool
33 -POTFILES
34 -*-POTFILES
36 -TAGS
37 -TAGS.sub
39 -.gdbinit
40 -.gdb_history
42 -# ignore core files, but not java/net/protocol/core/
43 -core
44 -!core/
46 -lost+found
47 diff -rNU3 dist.orig/config.guess dist/config.guess
48 --- dist.orig/config.guess 2014-04-04 15:48:08.000000000 +0200
49 +++ dist/config.guess 2015-10-18 13:19:49.000000000 +0200
50 @@ -171,16 +171,32 @@
51 UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
52 /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
53 case "${UNAME_MACHINE_ARCH}" in
54 + earm*eb*) machine=armeb-unknown ;;
55 + earm*) machine=arm-unknown ;;
56 armeb) machine=armeb-unknown ;;
57 arm*) machine=arm-unknown ;;
58 + coldfire) machine=m5407-unknown ;;
59 + earm*eb*) machine=armeb-unknown ;;
60 + earm*) machine=arm-unknown ;;
61 sh3el) machine=shl-unknown ;;
62 sh3eb) machine=sh-unknown ;;
63 sh5el) machine=sh5le-unknown ;;
64 *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
65 esac
66 # The Operating System including object format, if it has switched
67 - # to ELF recently, or will in the future.
68 + # to ELF recently, or will in the future and ABI.
69 case "${UNAME_MACHINE_ARCH}" in
70 + coldfire) os=netbsdelf ;;
71 + earm*)
72 + eval $set_cc_for_build
73 + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
74 + | grep -q __ARM_PCS_VFP
75 + then
76 + os=netbsdelf-eabi
77 + else
78 + os=netbsdelf-eabihf
79 + fi
80 + ;;
81 arm*|i386|m68k|ns32k|sh3*|sparc|vax)
82 eval $set_cc_for_build
83 if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
84 diff -rNU3 dist.orig/config.sub dist/config.sub
85 --- dist.orig/config.sub 2014-04-04 15:48:08.000000000 +0200
86 +++ dist/config.sub 2015-10-18 13:19:49.000000000 +0200
87 @@ -117,7 +117,7 @@
88 case $maybe_os in
89 nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
90 linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
91 - knetbsd*-gnu* | netbsd*-gnu* | \
92 + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
93 kopensolaris*-gnu* | \
94 storm-chaos* | os2-emx* | rtmk-nova*)
95 os=-$maybe_os
96 @@ -297,7 +297,7 @@
97 | nios | nios2 | nios2eb | nios2el \
98 | ns16k | ns32k \
99 | open8 \
100 - | or1k | or32 \
101 + | or1k | or1knd \
102 | pdp10 | pdp11 | pj | pjl \
103 | powerpc | powerpc64 | powerpc64le | powerpcle \
104 | pyramid \
105 @@ -329,12 +329,21 @@
106 basic_machine=$basic_machine-unknown
107 os=-none
109 - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
110 + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | m5407 \
111 + | v70 | w65 | z8k)
113 ms1)
114 basic_machine=mt-unknown
117 + riscv32-*)
118 + basic_machine=riscv32-ucb
119 + ;;
121 + riscv*-*)
122 + basic_machine=riscv-ucb
123 + ;;
125 strongarm | thumb | xscale)
126 basic_machine=arm-unknown
128 @@ -386,6 +395,7 @@
129 | le32-* | le64-* \
130 | lm32-* \
131 | m32c-* | m32r-* | m32rle-* \
132 + | m5200-* | m5407-* \
133 | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
134 | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
135 | microblaze-* | microblazeel-* \
136 @@ -920,8 +930,11 @@
137 basic_machine=hppa1.1-oki
138 os=-proelf
140 - openrisc | openrisc-*)
141 - basic_machine=or32-unknown
142 + or1k | or1k-*)
143 + basic_machine=or1k-unknown
144 + ;;
145 + or1knd | or1knd-*)
146 + basic_machine=or1knd-unknown
148 os400)
149 basic_machine=powerpc-ibm
150 @@ -1597,8 +1610,8 @@
151 or1k-*)
152 os=-elf
154 - or32-*)
155 - os=-coff
156 + or1knd-*)
157 + os=-elf
159 *-tti) # must be before sparc entry or we get the wrong os.
160 os=-sysv3
161 diff -rNU3 dist.orig/configure dist/configure
162 --- dist.orig/configure 2015-05-03 19:26:29.000000000 +0200
163 +++ dist/configure 2015-10-18 13:19:49.000000000 +0200
164 @@ -2292,7 +2292,7 @@
165 for ac_t in install-sh install.sh shtool; do
166 if test -f "$ac_dir/$ac_t"; then
167 ac_aux_dir=$ac_dir
168 - ac_install_sh="$ac_aux_dir/$ac_t -c"
169 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
170 break 2
172 done
173 @@ -6287,8 +6287,12 @@
175 if test $target_elf = yes; then :
176 # ELF platforms build the lto-plugin always.
177 - build_lto_plugin=yes
179 + case $target in
180 + m68010-*)
181 + build_lto_plugin=no;;
182 + *)
183 + build_lto_plugin=yes;;
184 + esac
185 else
186 if test x"$default_enable_lto" = x"yes" ; then
187 case $target in
188 diff -rNU3 dist.orig/configure.ac dist/configure.ac
189 --- dist.orig/configure.ac 2015-05-03 19:26:29.000000000 +0200
190 +++ dist/configure.ac 2015-10-18 13:19:49.000000000 +0200
191 @@ -1685,7 +1685,12 @@
192 enable_lto=yes; default_enable_lto=yes)
194 ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always.
195 - build_lto_plugin=yes
196 + case $target in
197 + m68010-*)
198 + build_lto_plugin=no;;
199 + *)
200 + build_lto_plugin=yes;;
201 + esac
202 ],[if test x"$default_enable_lto" = x"yes" ; then
203 case $target in
204 *-apple-darwin9* | *-cygwin* | *-mingw*) ;;
205 diff -rNU3 dist.orig/fixincludes/configure dist/fixincludes/configure
206 --- dist.orig/fixincludes/configure 2012-05-29 21:28:57.000000000 +0200
207 +++ dist/fixincludes/configure 2015-10-18 13:19:49.000000000 +0200
208 @@ -2141,7 +2141,7 @@
209 for ac_t in install-sh install.sh shtool; do
210 if test -f "$ac_dir/$ac_t"; then
211 ac_aux_dir=$ac_dir
212 - ac_install_sh="$ac_aux_dir/$ac_t -c"
213 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
214 break 2
216 done
217 diff -rNU3 dist.orig/gcc/Makefile.in dist/gcc/Makefile.in
218 --- dist.orig/gcc/Makefile.in 2014-04-05 12:26:19.000000000 +0200
219 +++ dist/gcc/Makefile.in 2015-10-18 13:19:51.000000000 +0200
220 @@ -639,6 +639,9 @@
221 exeext = @host_exeext@
222 build_exeext = @build_exeext@
224 +# NetBSD mknative-gcc addition
225 +ENABLE_SHARED = @enable_shared@
227 # Directory in which to put man pages.
228 mandir = @mandir@
229 man1dir = $(mandir)/man1
230 @@ -706,6 +709,7 @@
232 # Control whether header files are installed.
233 INSTALL_HEADERS=install-headers install-mkheaders
234 +INSTALL_HEADERS=install-headers
236 # Control whether Info documentation is built and installed.
237 BUILD_INFO = @BUILD_INFO@
238 @@ -747,8 +751,7 @@
240 # Native linker and preprocessor flags. For x-fragment overrides.
241 BUILD_LDFLAGS=@BUILD_LDFLAGS@
242 -BUILD_CPPFLAGS= -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
243 - -I$(srcdir)/../include @INCINTL@ $(CPPINC) $(CPPFLAGS)
244 +BUILD_CPPFLAGS=$(BALL_CPPFLAGS)
246 # Actual name to use when installing a native compiler.
247 GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
248 @@ -998,6 +1001,7 @@
249 # puts -I options in CPPFLAGS, our include files in the srcdir will always
250 # win against random include files in /usr/include.
251 ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS)
252 +BALL_CPPFLAGS = $(BINCLUDES) $(CPPFLAGS)
254 # This is the variable to use when using $(COMPILER).
255 ALL_COMPILERFLAGS = $(ALL_CXXFLAGS)
256 @@ -1054,6 +1058,10 @@
257 -I$(srcdir)/../include @INCINTL@ \
258 $(CPPINC) $(GMPINC) $(DECNUMINC) $(BACKTRACEINC) \
259 $(CLOOGINC) $(ISLINC)
260 +BINCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
261 + -I$(srcdir)/../include @INCINTL@ \
262 + $(CPPINC) $(DECNUMINC) $(BACKTRACEINC) \
263 + $(CLOOGINC) $(ISLINC)
265 .c.o:
266 $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
267 @@ -1796,7 +1804,7 @@
269 checksum-options:
270 echo "$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS)" > checksum-options.tmp \
271 - && $(srcdir)/../move-if-change checksum-options.tmp checksum-options
272 + && $(SHELL) $(srcdir)/../move-if-change checksum-options.tmp checksum-options
275 # Build libgcc.a.
276 @@ -1804,7 +1812,7 @@
277 libgcc-support: libgcc.mvars stmp-int-hdrs $(TCONFIG_H) \
278 $(MACHMODE_H) gcov-iov.h
280 -libgcc.mvars: config.status Makefile specs xgcc$(exeext)
281 +libgcc.mvars: config.status Makefile
282 : > tmp-libgcc.mvars
283 echo GCC_CFLAGS = '$(GCC_CFLAGS)' >> tmp-libgcc.mvars
284 echo INHIBIT_LIBC_CFLAGS = '$(INHIBIT_LIBC_CFLAGS)' >> tmp-libgcc.mvars
285 @@ -1819,6 +1827,7 @@
286 s-mlib: $(srcdir)/genmultilib Makefile
287 if test @enable_multilib@ = yes \
288 || test -n "$(MULTILIB_OSDIRNAMES)"; then \
289 + CONFIG_SHELL="$(SHELL)" \
290 $(SHELL) $(srcdir)/genmultilib \
291 "$(MULTILIB_OPTIONS)" \
292 "$(MULTILIB_DIRNAMES)" \
293 @@ -3909,21 +3918,21 @@
295 gengtype-parse.o build/gengtype-parse.o : gengtype-parse.c gengtype.h \
296 $(SYSTEM_H)
297 -gengtype-parse.o: $(CONFIG_H)
298 +gengtype-parse.o: $(CONFIG_H) $(BCONFIG_H)
299 CFLAGS-gengtype-parse.o += -DGENERATOR_FILE
300 build/gengtype-parse.o: $(BCONFIG_H)
302 gengtype-state.o build/gengtype-state.o: gengtype-state.c $(SYSTEM_H) \
303 gengtype.h errors.h double-int.h version.h $(HASHTAB_H) $(OBSTACK_H) \
304 $(XREGEX_H)
305 -gengtype-state.o: $(CONFIG_H)
306 +gengtype-state.o: $(CONFIG_H) $(BCONFIG_H)
307 CFLAGS-gengtype-state.o += -DGENERATOR_FILE
308 build/gengtype-state.o: $(BCONFIG_H)
310 gengtype.o build/gengtype.o : gengtype.c $(SYSTEM_H) gengtype.h \
311 rtl.def insn-notes.def errors.h double-int.h version.h $(HASHTAB_H) \
312 $(OBSTACK_H) $(XREGEX_H)
313 -gengtype.o: $(CONFIG_H)
314 +gengtype.o: $(CONFIG_H) $(BCONFIG_H)
315 CFLAGS-gengtype.o += -DGENERATOR_FILE
316 build/gengtype.o: $(BCONFIG_H)
318 @@ -4061,6 +4070,12 @@
319 # s-* so that mostlyclean does not force the include directory to
320 # be rebuilt.
322 +unwind.h: $(UNWIND_H)
323 + -if [ -d include ] ; then true; else mkdir include; chmod a+rx include; fi
324 + rm -f include/unwind.h
325 + cp $(UNWIND_H) include/unwind.h
326 + chmod a+r include/unwind.h
328 # Build the include directories.
329 stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) fixinc_list
330 # Copy in the headers provided with gcc.
331 @@ -4076,6 +4091,7 @@
332 # e.g. install-no-fixedincludes.
333 -if [ -d include ] ; then true; else mkdir include; chmod a+rx include; fi
334 -if [ -d include-fixed ] ; then true; else mkdir include-fixed; chmod a+rx include-fixed; fi
335 + if false; then \
336 for file in .. $(USER_H); do \
337 if [ X$$file != X.. ]; then \
338 realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
339 @@ -4084,7 +4100,7 @@
340 cp $$file include; \
341 chmod a+r include/$$realfile; \
342 fi; \
343 - done
344 + done; \
345 for file in .. $(USER_H_INC_NEXT_PRE); do \
346 if [ X$$file != X.. ]; then \
347 mv include/$$file include/x_$$file; \
348 @@ -4093,14 +4109,14 @@
349 rm -f include/x_$$file; \
350 chmod a+r include/$$file; \
351 fi; \
352 - done
353 + done; \
354 for file in .. $(USER_H_INC_NEXT_POST); do \
355 if [ X$$file != X.. ]; then \
356 echo "#include_next <$$file>" >>include/$$file; \
357 chmod a+r include/$$file; \
358 fi; \
359 - done
360 - rm -f include/stdint.h
361 + done; \
362 + rm -f include/stdint.h; \
363 if [ $(USE_GCC_STDINT) = wrap ]; then \
364 rm -f include/stdint-gcc.h; \
365 cp $(srcdir)/ginclude/stdint-gcc.h include/stdint-gcc.h; \
366 @@ -4110,7 +4126,7 @@
367 elif [ $(USE_GCC_STDINT) = provide ]; then \
368 cp $(srcdir)/ginclude/stdint-gcc.h include/stdint.h; \
369 chmod a+r include/stdint.h; \
370 - fi
371 + fi; \
372 set -e; for ml in `cat fixinc_list`; do \
373 sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
374 multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
375 @@ -4127,7 +4143,8 @@
376 rm -f $${fix_dir}/limits.h; \
377 cp -p tmp-limits.h $${fix_dir}/limits.h; \
378 chmod a+r $${fix_dir}/limits.h; \
379 - done
380 + done; \
381 + fi
382 # Install the README
383 rm -f include-fixed/README
384 cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
385 @@ -4187,10 +4204,11 @@
386 # Abort if no system headers available, unless building a crosscompiler.
387 # FIXME: abort unless building --without-headers would be more accurate and less ugly
388 stmp-fixinc: gsyslimits.h macro_list fixinc_list \
389 - $(build_objdir)/fixincludes/fixincl \
390 + $(build_objdir)/fixincludes/fixincl$(build_exeext) \
391 $(build_objdir)/fixincludes/fixinc.sh
392 - rm -rf include-fixed; mkdir include-fixed
393 - -chmod a+rx include-fixed
394 + if false; then \
395 + rm -rf include-fixed; mkdir include-fixed; \
396 + -chmod a+rx include-fixed; \
397 if [ -d ../prev-gcc ]; then \
398 cd ../prev-gcc && \
399 $(MAKE) real-$(INSTALL_HEADERS_DIR) DESTDIR=`pwd`/../gcc/ \
400 @@ -4224,6 +4242,7 @@
401 fi; \
402 chmod a+r $${fix_dir}/syslimits.h; \
403 done; \
404 + fi; \
406 $(STAMP) stmp-fixinc
408 @@ -4710,6 +4729,8 @@
409 lang.install-info
411 $(DESTDIR)$(infodir)/%.info: doc/%.info installdirs
412 + @echo "NOT REBUILDING $@"
413 +NetBSD_DISABLED_info:
414 rm -f $@
415 if [ -f $< ]; then \
416 for f in $(<)*; do \
417 diff -rNU3 dist.orig/gcc/c/Make-lang.in dist/gcc/c/Make-lang.in
418 --- dist.orig/gcc/c/Make-lang.in 2013-01-10 21:38:27.000000000 +0100
419 +++ dist/gcc/c/Make-lang.in 2015-10-18 13:19:49.000000000 +0200
420 @@ -70,7 +70,7 @@
421 $(C_OBJS) $(BACKEND) $(LIBDEPS)
422 build/genchecksum$(build_exeext) $(C_OBJS) $(BACKEND) $(LIBDEPS) \
423 checksum-options > cc1-checksum.c.tmp && \
424 - $(srcdir)/../move-if-change cc1-checksum.c.tmp cc1-checksum.c
425 + $(SHELL) $(srcdir)/../move-if-change cc1-checksum.c.tmp cc1-checksum.c
427 cc1-checksum.o : cc1-checksum.c $(CONFIG_H) $(SYSTEM_H)
429 diff -rNU3 dist.orig/gcc/c-family/c-opts.c dist/gcc/c-family/c-opts.c
430 --- dist.orig/gcc/c-family/c-opts.c 2015-02-11 13:14:54.000000000 +0100
431 +++ dist/gcc/c-family/c-opts.c 2015-10-18 13:19:49.000000000 +0200
432 @@ -284,6 +284,10 @@
433 cpp_opts->discard_comments_in_macro_exp = 0;
434 break;
436 + case OPT_cxx_isystem:
437 + add_path (xstrdup (arg), SYSTEM, 1, true);
438 + break;
440 case OPT_D:
441 defer_opt (code, arg);
442 break;
443 @@ -606,6 +610,10 @@
444 add_path (xstrdup (arg), QUOTE, 0, true);
445 break;
447 + case OPT_iremap:
448 + add_cpp_remap_path (arg);
449 + break;
451 case OPT_isysroot:
452 sysroot = arg;
453 break;
454 diff -rNU3 dist.orig/gcc/c-family/c.opt dist/gcc/c-family/c.opt
455 --- dist.orig/gcc/c-family/c.opt 2014-04-07 08:40:18.000000000 +0200
456 +++ dist/gcc/c-family/c.opt 2015-10-18 13:19:49.000000000 +0200
457 @@ -801,6 +801,12 @@
458 C ObjC C++ ObjC++
459 A synonym for -std=c89 (for C) or -std=c++98 (for C++)
461 +; This should really just be C++/ObjC++ but we (NetBSD) use it when
462 +; calling C and ObjC compilers as well.
463 +cxx-isystem
464 +C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs)
465 +-cxx-isystem <dir> Add <dir> to the start of the C++ system include path
468 C ObjC C++ ObjC++ Joined
469 ; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
470 @@ -1277,6 +1283,10 @@
471 C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs)
472 -iquote <dir> Add <dir> to the end of the quote include path
474 +iremap
475 +C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs)
476 +-iremap <src:dst> Convert <src> to <dst> if it occurs as prefix in __FILE__.
478 iwithprefix
479 C ObjC C++ ObjC++ Joined Separate
480 -iwithprefix <dir> Add <dir> to the end of the system include path
481 diff -rNU3 dist.orig/gcc/cfgexpand.c dist/gcc/cfgexpand.c
482 --- dist.orig/gcc/cfgexpand.c 2015-01-27 18:07:24.000000000 +0100
483 +++ dist/gcc/cfgexpand.c 2015-10-18 13:19:49.000000000 +0200
484 @@ -1321,7 +1321,9 @@
485 else
486 len = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
488 - if (len < max)
489 + if (len == 0)
490 + ret = SPCT_HAS_ARRAY;
491 + else if (len < max)
492 ret = SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_ARRAY;
493 else
494 ret = SPCT_HAS_LARGE_CHAR_ARRAY | SPCT_HAS_ARRAY;
495 diff -rNU3 dist.orig/gcc/common/config/arm/arm-common.c dist/gcc/common/config/arm/arm-common.c
496 --- dist.orig/gcc/common/config/arm/arm-common.c 2013-01-10 21:38:27.000000000 +0100
497 +++ dist/gcc/common/config/arm/arm-common.c 2015-10-18 13:19:49.000000000 +0200
498 @@ -48,6 +48,9 @@
499 return UI_SJLJ;
500 #endif
502 + if (ARM_DWARF_UNWIND_TABLES)
503 + return UI_DWARF2;
505 /* If not using ARM EABI unwind tables... */
506 if (ARM_UNWIND_INFO)
508 diff -rNU3 dist.orig/gcc/common/config/or1k/or1k-common.c dist/gcc/common/config/or1k/or1k-common.c
509 --- dist.orig/gcc/common/config/or1k/or1k-common.c 1970-01-01 01:00:00.000000000 +0100
510 +++ dist/gcc/common/config/or1k/or1k-common.c 2015-10-18 13:19:50.000000000 +0200
511 @@ -0,0 +1,30 @@
512 +/* Common hooks for VAX.
513 + Copyright (C) 1987-2013 Free Software Foundation, Inc.
515 +This file is part of GCC.
517 +GCC is free software; you can redistribute it and/or modify
518 +it under the terms of the GNU General Public License as published by
519 +the Free Software Foundation; either version 3, or (at your option)
520 +any later version.
522 +GCC is distributed in the hope that it will be useful,
523 +but WITHOUT ANY WARRANTY; without even the implied warranty of
524 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
525 +GNU General Public License for more details.
527 +You should have received a copy of the GNU General Public License
528 +along with GCC; see the file COPYING3. If not see
529 +<http://www.gnu.org/licenses/>. */
531 +#include "config.h"
532 +#include "system.h"
533 +#include "coretypes.h"
534 +#include "tm.h"
535 +#include "common/common-target.h"
536 +#include "common/common-target-def.h"
538 +#undef TARGET_DEFAULT_TARGET_FLAGS
539 +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
541 +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
542 diff -rNU3 dist.orig/gcc/common/config/riscv/riscv-common.c dist/gcc/common/config/riscv/riscv-common.c
543 --- dist.orig/gcc/common/config/riscv/riscv-common.c 1970-01-01 01:00:00.000000000 +0100
544 +++ dist/gcc/common/config/riscv/riscv-common.c 2015-10-18 13:19:50.000000000 +0200
545 @@ -0,0 +1,129 @@
546 +/* Common hooks for RISC-V.
547 + Copyright (C) 1989-2014 Free Software Foundation, Inc.
549 +This file is part of GCC.
551 +GCC is free software; you can redistribute it and/or modify
552 +it under the terms of the GNU General Public License as published by
553 +the Free Software Foundation; either version 3, or (at your option)
554 +any later version.
556 +GCC is distributed in the hope that it will be useful,
557 +but WITHOUT ANY WARRANTY; without even the implied warranty of
558 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
559 +GNU General Public License for more details.
561 +You should have received a copy of the GNU General Public License
562 +along with GCC; see the file COPYING3. If not see
563 +<http://www.gnu.org/licenses/>. */
565 +#include "config.h"
566 +#include "system.h"
567 +#include "coretypes.h"
568 +#include "tm.h"
569 +#include "common/common-target.h"
570 +#include "common/common-target-def.h"
571 +#include "opts.h"
572 +#include "flags.h"
573 +#include "errors.h"
575 +/* Parse a RISC-V ISA string into an option mask. */
577 +static void
578 +riscv_parse_arch_string (const char *isa, int *flags)
580 + const char *p = isa;
582 + if (strncmp (p, "RV32", 4) == 0)
583 + *flags |= MASK_32BIT, p += 4;
584 + else if (strncmp (p, "RV64", 4) == 0)
585 + *flags &= ~MASK_32BIT, p += 4;
587 + if (*p++ != 'I')
589 + error ("-march=%s: ISA strings must begin with I, RV32I, or RV64I", isa);
590 + return;
593 + *flags &= ~MASK_MULDIV;
594 + if (*p == 'M')
595 + *flags |= MASK_MULDIV, p++;
597 + *flags &= ~MASK_ATOMIC;
598 + if (*p == 'A')
599 + *flags |= MASK_ATOMIC, p++;
601 + *flags |= MASK_SOFT_FLOAT_ABI;
602 + if (*p == 'F')
603 + *flags &= ~MASK_SOFT_FLOAT_ABI, p++;
605 + if (*p == 'D')
607 + p++;
608 + if (!TARGET_HARD_FLOAT)
610 + error ("-march=%s: the D extension requires the F extension", isa);
611 + return;
614 + else if (TARGET_HARD_FLOAT)
616 + error ("-march=%s: single-precision-only is not yet supported", isa);
617 + return;
620 + if (*p)
622 + error ("-march=%s: unsupported ISA substring %s", isa, p);
623 + return;
627 +static int
628 +riscv_flags_from_arch_string (const char *isa)
630 + int flags = 0;
631 + riscv_parse_arch_string (isa, &flags);
632 + return flags;
635 +/* Implement TARGET_HANDLE_OPTION. */
637 +static bool
638 +riscv_handle_option (struct gcc_options *opts,
639 + struct gcc_options *opts_set ATTRIBUTE_UNUSED,
640 + const struct cl_decoded_option *decoded,
641 + location_t loc ATTRIBUTE_UNUSED)
643 + switch (decoded->opt_index)
645 + case OPT_march_:
646 + riscv_parse_arch_string (decoded->arg, &opts->x_target_flags);
647 + return true;
649 + default:
650 + return true;
654 +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
655 +static const struct default_options riscv_option_optimization_table[] =
657 + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
658 + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
659 + { OPT_LEVELS_NONE, 0, NULL, 0 }
660 + };
662 +#undef TARGET_OPTION_OPTIMIZATION_TABLE
663 +#define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
665 +#undef TARGET_DEFAULT_TARGET_FLAGS
666 +#define TARGET_DEFAULT_TARGET_FLAGS \
667 + (TARGET_DEFAULT \
668 + | riscv_flags_from_arch_string (RISCV_ARCH_STRING_DEFAULT) \
669 + | (TARGET_64BIT_DEFAULT ? 0 : MASK_32BIT))
671 +#undef TARGET_HANDLE_OPTION
672 +#define TARGET_HANDLE_OPTION riscv_handle_option
674 +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
675 diff -rNU3 dist.orig/gcc/config/alpha/alpha.h dist/gcc/config/alpha/alpha.h
676 --- dist.orig/gcc/config/alpha/alpha.h 2013-01-10 21:38:27.000000000 +0100
677 +++ dist/gcc/config/alpha/alpha.h 2015-10-18 13:19:50.000000000 +0200
678 @@ -1067,6 +1067,12 @@
679 #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \
680 alpha_output_filename (STREAM, NAME)
682 +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
683 + ( fputs (".comm ", (FILE)), \
684 + assemble_name ((FILE), (NAME)), \
685 + fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
688 /* By default, turn on GDB extensions. */
689 #define DEFAULT_GDB_EXTENSIONS 1
691 diff -rNU3 dist.orig/gcc/config/alpha/elf.h dist/gcc/config/alpha/elf.h
692 --- dist.orig/gcc/config/alpha/elf.h 2014-07-25 09:28:47.000000000 +0200
693 +++ dist/gcc/config/alpha/elf.h 2015-10-18 13:19:50.000000000 +0200
694 @@ -18,6 +18,29 @@
695 along with GCC; see the file COPYING3. If not see
696 <http://www.gnu.org/licenses/>. */
698 +#undef OBJECT_FORMAT_COFF
699 +#undef EXTENDED_COFF
700 +#define OBJECT_FORMAT_ELF
702 +/* ??? Move all SDB stuff from alpha.h to osf.h. */
703 +#undef SDB_DEBUGGING_INFO
704 +#undef DBX_DEBUGGING_INFO
706 +#define DWARF2_DEBUGGING_INFO 1
708 +#undef PREFERRED_DEBUGGING_TYPE
709 +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
711 +#undef ASM_FINAL_SPEC
713 +/* alpha/ doesn't use elfos.h for some reason. */
714 +#define TARGET_OBJFMT_CPP_BUILTINS() \
715 + do \
716 + { \
717 + builtin_define ("__ELF__"); \
718 + } \
719 + while (0)
721 #undef CC1_SPEC
722 #define CC1_SPEC "%{G*}"
724 @@ -167,6 +190,6 @@
725 As of Jan 2002, only glibc 2.2.4 can actually make use of this, but
726 I imagine that other systems will catch up. In the meantime, it
727 doesn't harm to make sure that the data exists to be used later. */
728 -#if defined(HAVE_LD_EH_FRAME_HDR)
729 +#if defined(HAVE_LD_EH_FRAME_HDR) && !defined(LINK_EH_SPEC)
730 #define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
731 #endif
732 diff -rNU3 dist.orig/gcc/config/alpha/netbsd.h dist/gcc/config/alpha/netbsd.h
733 --- dist.orig/gcc/config/alpha/netbsd.h 2013-01-10 21:38:27.000000000 +0100
734 +++ dist/gcc/config/alpha/netbsd.h 2015-10-18 13:19:50.000000000 +0200
735 @@ -57,6 +57,15 @@
737 #define NETBSD_ENTRY_POINT "__start"
739 +/* Provide a STARTFILE_SPEC appropriate for NetBSD. Here we add the
740 + (even more) magical crtbegin.o file which provides part of the
741 + support for getting C++ file-scope static object constructed
742 + before entering `main'. */
744 +#undef STARTFILE_SPEC
745 +#define STARTFILE_SPEC \
746 + "%{!shared: %{pg|p:gcrt0.o%s;:crt0.o%s}}\
747 + crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
749 /* Provide an ENDFILE_SPEC appropriate for NetBSD/alpha ELF. Here we
750 add crtend.o, which provides part of the support for getting
751 diff -rNU3 dist.orig/gcc/config/arm/arm.h dist/gcc/config/arm/arm.h
752 --- dist.orig/gcc/config/arm/arm.h 2015-01-14 12:02:24.000000000 +0100
753 +++ dist/gcc/config/arm/arm.h 2015-10-18 13:19:50.000000000 +0200
754 @@ -889,6 +889,11 @@
755 #define ARM_UNWIND_INFO 0
756 #endif
758 +/* Overriden by config/arm/netbsd-eabi.h. */
759 +#ifndef ARM_DWARF_UNWIND_TABLES
760 +#define ARM_DWARF_UNWIND_TABLES 0
761 +#endif
763 /* Use r0 and r1 to pass exception handling information. */
764 #define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? N : INVALID_REGNUM)
766 @@ -899,11 +904,21 @@
767 #ifndef ARM_TARGET2_DWARF_FORMAT
768 #define ARM_TARGET2_DWARF_FORMAT DW_EH_PE_pcrel
770 +# if ARM_DWARF_UNWIND_TABLES
771 +/* DWARF unwinding uses the normal indirect/pcrel vs absptr format
772 + for 32bit platforms. */
773 +# define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
774 + ((flag_pic \
775 + && ((GLOBAL) || (CODE))) \
776 + ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4 \
777 + : DW_EH_PE_absptr)
778 +# else
779 /* ttype entries (the only interesting data references used)
780 use TARGET2 relocations. */
781 -#define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \
782 - (((code) == 0 && (data) == 1 && ARM_UNWIND_INFO) ? ARM_TARGET2_DWARF_FORMAT \
783 - : DW_EH_PE_absptr)
784 +# define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \
785 + (((code) == 0 && (data) == 1 && ARM_UNWIND_INFO) ? ARM_TARGET2_DWARF_FORMAT \
786 + : DW_EH_PE_absptr)
787 +# endif
788 #endif
790 /* The native (Norcroft) Pascal compiler for the ARM passes the static chain
791 @@ -2315,7 +2330,7 @@
793 /* -mcpu=native handling only makes sense with compiler running on
794 an ARM chip. */
795 -#if defined(__arm__)
796 +#if defined(__arm__) && defined(__linux__)
797 extern const char *host_detect_local_cpu (int argc, const char **argv);
798 # define EXTRA_SPEC_FUNCTIONS \
799 { "local_cpu_detect", host_detect_local_cpu },
800 diff -rNU3 dist.orig/gcc/config/arm/bpabi-netbsd.c dist/gcc/config/arm/bpabi-netbsd.c
801 --- dist.orig/gcc/config/arm/bpabi-netbsd.c 1970-01-01 01:00:00.000000000 +0100
802 +++ dist/gcc/config/arm/bpabi-netbsd.c 2015-10-18 13:19:50.000000000 +0200
803 @@ -0,0 +1 @@
804 +#include "bpabi.c"
805 diff -rNU3 dist.orig/gcc/config/arm/bpabi.h dist/gcc/config/arm/bpabi.h
806 --- dist.orig/gcc/config/arm/bpabi.h 2013-01-18 15:26:15.000000000 +0100
807 +++ dist/gcc/config/arm/bpabi.h 2015-10-18 13:19:50.000000000 +0200
808 @@ -19,12 +19,16 @@
809 <http://www.gnu.org/licenses/>. */
811 /* Use the AAPCS ABI by default. */
812 +#undef ARM_DEFAULT_ABI
813 #define ARM_DEFAULT_ABI ARM_ABI_AAPCS
815 /* Assume that AAPCS ABIs should adhere to the full BPABI. */
816 +#undef TARGET_BPABI
817 #define TARGET_BPABI (TARGET_AAPCS_BASED)
819 /* BPABI targets use EABI frame unwinding tables. */
820 +#undef ARM_EABI_UNWIND_TABLES
821 +#define ARM_EABI_UNWIND_TABLES 1
822 #undef ARM_UNWIND_INFO
823 #define ARM_UNWIND_INFO 1
825 diff -rNU3 dist.orig/gcc/config/arm/elf.h dist/gcc/config/arm/elf.h
826 --- dist.orig/gcc/config/arm/elf.h 2013-01-10 21:38:27.000000000 +0100
827 +++ dist/gcc/config/arm/elf.h 2015-10-18 13:19:50.000000000 +0200
828 @@ -154,6 +154,8 @@
829 #undef L_floatdidf
830 #undef L_floatdisf
831 #undef L_floatundidf
832 +/* XXXMRG: don't take this out, we need it! */
833 +# ifndef __NetBSD__
834 #undef L_floatundisf
835 +# endif
836 #endif
838 diff -rNU3 dist.orig/gcc/config/arm/netbsd-eabi.h dist/gcc/config/arm/netbsd-eabi.h
839 --- dist.orig/gcc/config/arm/netbsd-eabi.h 1970-01-01 01:00:00.000000000 +0100
840 +++ dist/gcc/config/arm/netbsd-eabi.h 2015-10-18 13:19:50.000000000 +0200
841 @@ -0,0 +1,113 @@
842 +/* Definitions of target machine for GNU compiler, NetBSD/arm ELF version.
843 + Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
844 + Contributed by Wasabi Systems, Inc.
846 + This file is part of GCC.
848 + GCC is free software; you can redistribute it and/or modify it
849 + under the terms of the GNU General Public License as published
850 + by the Free Software Foundation; either version 3, or (at your
851 + option) any later version.
853 + GCC is distributed in the hope that it will be useful, but WITHOUT
854 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
855 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
856 + License for more details.
858 + You should have received a copy of the GNU General Public License
859 + along with GCC; see the file COPYING3. If not see
860 + <http://www.gnu.org/licenses/>. */
862 +/* Run-time Target Specification. */
863 +#undef MULTILIB_DEFAULTS
864 +#define MULTILIB_DEFAULTS { "mabi=aapcs-linux" }
866 +#define TARGET_LINKER_EABI_SUFFIX \
867 + (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFT \
868 + ? "%{!mabi=apcs-gnu:%{!mabi=atpcs:%{mfloat-abi=hard:_eabihf;:_eabi}}}" \
869 + : "%{!mabi=apcs-gnu:%{!mabi=atpcs:%{mfloat-abi=soft:_eabi;:_eabihf}}}")
870 +#define TARGET_LINKER_BIG_EMULATION "armelfb_nbsd%(linker_eabi_suffix)"
871 +#define TARGET_LINKER_LITTLE_EMULATION "armelf_nbsd%(linker_eabi_suffix)"
873 +/* TARGET_BIG_ENDIAN_DEFAULT is set in
874 + config.gcc for big endian configurations. */
875 +#undef TARGET_LINKER_EMULATION
876 +#if TARGET_BIG_ENDIAN_DEFAULT
877 +#define TARGET_LINKER_EMULATION TARGET_LINKER_BIG_EMULATION
878 +#undef BE8_LINK_SPEC
879 +#define BE8_LINK_SPEC " %{!mlittle-endian:%{march=armv7-a|mcpu=cortex-a5|mcpu=cortex-a8|mcpu=cortex-a9:%{!r:--be8}}}"
880 +#else
881 +#define TARGET_LINKER_EMULATION TARGET_LINKER_LITTLE_EMULATION
882 +#endif
884 +#undef ARM_DEFAULT_ABI
885 +#define ARM_DEFAULT_ABI ARM_ABI_AAPCS_LINUX
887 +#undef ARM_EABI_UNWIND_TABLES
888 +#define ARM_EABI_UNWIND_TABLES 0
889 +#undef ARM_UNWIND_INFO
890 +#define ARM_UNWIND_INFO 0
891 +#undef ARM_DWARF_UNWIND_TABLES
892 +#define ARM_DWARF_UNWIND_TABLES 1
894 +#undef TARGET_OS_CPP_BUILTINS
895 +#define TARGET_OS_CPP_BUILTINS() \
896 + do \
897 + { \
898 + if (TARGET_AAPCS_BASED) \
899 + TARGET_BPABI_CPP_BUILTINS(); \
900 + NETBSD_OS_CPP_BUILTINS_ELF(); \
901 + if (ARM_DWARF_UNWIND_TABLES) \
902 + builtin_define ("__ARM_DWARF_EH__"); \
903 + if (ARM_EABI_UNWIND_TABLES) \
904 + builtin_define ("__UNWIND_TABLES__"); \
905 + } \
906 + while (0)
908 +#undef SUBTARGET_CPP_SPEC
909 +#define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
912 + * Override AAPCS types to remain compatible the existing NetBSD types.
913 + */
914 +#undef WCHAR_TYPE
915 +#define WCHAR_TYPE "int"
917 +#undef SIZE_TYPE
918 +#define SIZE_TYPE "long unsigned int"
920 +#undef PTRDIFF_TYPE
921 +#define PTRDIFF_TYPE "long int"
923 +#undef SUBTARGET_EXTRA_ASM_SPEC
924 +#define SUBTARGET_EXTRA_ASM_SPEC \
925 + "-matpcs %{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu} %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
927 +/* Default to full VFP if -mhard-float is specified. */
928 +#undef SUBTARGET_ASM_FLOAT_SPEC
929 +#define SUBTARGET_ASM_FLOAT_SPEC \
930 + "%{mhard-float:%{!mfpu=*:-mfpu=vfp}} \
931 + %{mfloat-abi=hard:%{!mfpu=*:-mfpu=vfp}}"
933 +#undef SUBTARGET_EXTRA_SPECS
934 +#define SUBTARGET_EXTRA_SPECS \
935 + { "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
936 + { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
937 + { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
938 + { "linker_eabi_suffix", TARGET_LINKER_EABI_SUFFIX }, \
939 + { "linker_emulation", TARGET_LINKER_EMULATION }, \
940 + { "linker_big_emulation", TARGET_LINKER_BIG_EMULATION }, \
941 + { "linker_little_emulation", TARGET_LINKER_LITTLE_EMULATION }, \
942 + { "be8_link_spec", BE8_LINK_SPEC }, \
943 + { "target_fix_v4bx_spec", TARGET_FIX_V4BX_SPEC }, \
944 + { "netbsd_entry_point", NETBSD_ENTRY_POINT },
946 +#define NETBSD_ENTRY_POINT "__start"
948 +#undef LINK_SPEC
949 +#define LINK_SPEC \
950 + "-X %{mbig-endian:-EB -m %(linker_big_emulation)} \
951 + %{mlittle-endian:-EL -m %(linker_liitle_emulation)} \
952 + %{!mbig-endian:%{!mlittle-endian:-m %(linker_emulation)}} \
953 + %(be8_link_spec) %(target_fix_v4bx_spec) \
954 + %(netbsd_link_spec)"
955 diff -rNU3 dist.orig/gcc/config/arm/netbsd-elf.h dist/gcc/config/arm/netbsd-elf.h
956 --- dist.orig/gcc/config/arm/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
957 +++ dist/gcc/config/arm/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
958 @@ -22,9 +22,20 @@
960 /* arm.h defaults to ARM6 CPU. */
962 -/* This defaults us to little-endian. */
963 -#ifndef TARGET_ENDIAN_DEFAULT
964 -#define TARGET_ENDIAN_DEFAULT 0
965 +/* Default EABI to armv5t so that thumb shared libraries work.
966 + The ARM926EH-S core is the default for armv5te, so set
967 + SUBTARGET_CPU_DEFAULT to achieve this. */
969 +#define SUBTARGET_CPU_DEFAULT \
970 + (ARM_DEFAULT_ABI != ARM_ABI_APCS && ARM_DEFAULT_ABI != ARM_ABI_ATPCS \
971 + ? TARGET_CPU_arm926ejs : TARGET_CPU_arm6)
973 +/* TARGET_BIG_ENDIAN_DEFAULT is set in
974 + config.gcc for big endian configurations. */
975 +#if TARGET_BIG_ENDIAN_DEFAULT
976 +#define TARGET_ENDIAN_DEFAULT MASK_BIG_END
977 +#else
978 +#define TARGET_ENDIAN_DEFAULT 0
979 #endif
981 #undef MULTILIB_DEFAULTS
982 @@ -38,6 +49,7 @@
983 #undef ARM_DEFAULT_ABI
984 #define ARM_DEFAULT_ABI ARM_ABI_ATPCS
986 +#undef TARGET_OS_CPP_BUILTINS
987 #define TARGET_OS_CPP_BUILTINS() \
988 do \
990 @@ -50,12 +62,13 @@
992 #undef SUBTARGET_EXTRA_ASM_SPEC
993 #define SUBTARGET_EXTRA_ASM_SPEC \
994 - "-matpcs %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
995 + "-matpcs %{mabi=aapcs*:-meabi=5} %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
997 /* Default to full VFP if -mfloat-abi=hard is specified. */
998 #undef SUBTARGET_ASM_FLOAT_SPEC
999 #define SUBTARGET_ASM_FLOAT_SPEC \
1000 - "%{mfloat-abi=hard:{!mfpu=*:-mfpu=vfp}}"
1001 + "%{mhard-float:%{!mfpu=*:-mfpu=vfp}} \
1002 + %{mfloat-abi=hard:%{!mfpu=*:-mfpu=vfp}}"
1004 #undef SUBTARGET_EXTRA_SPECS
1005 #define SUBTARGET_EXTRA_SPECS \
1006 @@ -68,7 +81,9 @@
1008 #undef LINK_SPEC
1009 #define LINK_SPEC \
1010 - "-X %{mbig-endian:-EB} %{mlittle-endian:-EL} \
1011 + "-X \
1012 + %{mbig-endian:-EB %{-mabi=aapcs*:-m armelfb_nbsd_eabi}} \
1013 + %{mlittle-endian:-EL %{-mabi=aapcs*:-m armelf_nbsd_eabi}} \
1014 %(netbsd_link_spec)"
1016 /* Make GCC agree with <machine/ansi.h>. */
1017 @@ -79,6 +94,12 @@
1018 #undef PTRDIFF_TYPE
1019 #define PTRDIFF_TYPE "long int"
1021 +#undef INTPTR_TYPE
1022 +#define INTPTR_TYPE PTRDIFF_TYPE
1024 +#undef UINTPTR_TYPE
1025 +#define UINTPTR_TYPE SIZE_TYPE
1027 /* We don't have any limit on the length as out debugger is GDB. */
1028 #undef DBX_CONTIN_LENGTH
1030 diff -rNU3 dist.orig/gcc/config/arm/t-arm dist/gcc/config/arm/t-arm
1031 --- dist.orig/gcc/config/arm/t-arm 2013-03-07 00:29:08.000000000 +0100
1032 +++ dist/gcc/config/arm/t-arm 2015-10-18 13:19:50.000000000 +0200
1033 @@ -66,6 +66,8 @@
1035 $(srcdir)/config/arm/arm-tune.md: $(srcdir)/config/arm/gentune.sh \
1036 $(srcdir)/config/arm/arm-cores.def
1037 + @echo "NOT REBUILDING $@"
1038 +NetBSD_DISABLED_config_arm_arm-tune.md:
1039 $(SHELL) $(srcdir)/config/arm/gentune.sh \
1040 $(srcdir)/config/arm/arm-cores.def > \
1041 $(srcdir)/config/arm/arm-tune.md
1042 @@ -73,6 +75,8 @@
1043 $(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \
1044 $(srcdir)/config/arm/arm-cores.def $(srcdir)/config/arm/arm-arches.def \
1045 $(srcdir)/config/arm/arm-fpus.def
1046 + @echo "NOT REBUILDING $@"
1047 +NetBSD_DISABLED_config_arm_arm-tables.opt:
1048 $(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
1049 $(srcdir)/config/arm/arm-tables.opt
1051 diff -rNU3 dist.orig/gcc/config/arm/t-netbsdeabi dist/gcc/config/arm/t-netbsdeabi
1052 --- dist.orig/gcc/config/arm/t-netbsdeabi 1970-01-01 01:00:00.000000000 +0100
1053 +++ dist/gcc/config/arm/t-netbsdeabi 2015-10-18 13:19:50.000000000 +0200
1054 @@ -0,0 +1,8 @@
1055 +# NetBSD has (will have) "non-native" libraries in /usr/lib/<arch>.
1057 +MULTILIB_OPTIONS = mabi=aapcs-linux/mabi=apcs-gnu
1058 +MULTILIB_DIRNAMES = eabi oabi
1059 +MULTILIB_OSDIRNAMES = . ../lib/oabi
1061 +LIBGCC = stmp-multilib
1062 +INSTALL_LIBGCC = install-multilib
1063 diff -rNU3 dist.orig/gcc/config/freebsd-spec.h dist/gcc/config/freebsd-spec.h
1064 --- dist.orig/gcc/config/freebsd-spec.h 2013-01-10 21:38:27.000000000 +0100
1065 +++ dist/gcc/config/freebsd-spec.h 2015-10-18 13:19:50.000000000 +0200
1066 @@ -133,6 +133,14 @@
1067 #define FBSD_DYNAMIC_LINKER "/libexec/ld-elf.so.1"
1068 #endif
1070 +#if defined(HAVE_LD_EH_FRAME_HDR) && !defined(LINK_EH_SPEC)
1071 +#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
1072 +#endif
1074 +/* Use --as-needed -lgcc_s for eh support. */
1075 +#ifdef HAVE_LD_AS_NEEDED
1076 +#define USE_LD_AS_NEEDED 1
1077 +#endif
1078 /* NOTE: The freebsd-spec.h header is included also for various
1079 non-FreeBSD powerpc targets, thus it should never define macros
1080 other than FBSD_* prefixed ones, or USING_CONFIG_FREEBSD_SPEC. */
1081 diff -rNU3 dist.orig/gcc/config/host-netbsd.c dist/gcc/config/host-netbsd.c
1082 --- dist.orig/gcc/config/host-netbsd.c 1970-01-01 01:00:00.000000000 +0100
1083 +++ dist/gcc/config/host-netbsd.c 2015-10-18 13:19:50.000000000 +0200
1084 @@ -0,0 +1,85 @@
1085 +/* NetBSD host-specific hook definitions.
1086 + Copyright (C) 2004-2013 Free Software Foundation, Inc.
1088 + This file is part of GCC.
1090 + GCC is free software; you can redistribute it and/or modify it
1091 + under the terms of the GNU General Public License as published
1092 + by the Free Software Foundation; either version 3, or (at your
1093 + option) any later version.
1095 + GCC is distributed in the hope that it will be useful, but WITHOUT
1096 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1097 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1098 + License for more details.
1100 + You should have received a copy of the GNU General Public License
1101 + along with GCC; see the file COPYING3. If not see
1102 + <http://www.gnu.org/licenses/>. */
1104 +#include "config.h"
1105 +#include "system.h"
1106 +#include "coretypes.h"
1107 +#include "hosthooks.h"
1108 +#include "hosthooks-def.h"
1111 +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
1112 +#define HOST_HOOKS_GT_PCH_GET_ADDRESS netbsd_gt_pch_get_address
1113 +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
1114 +#define HOST_HOOKS_GT_PCH_USE_ADDRESS netbsd_gt_pch_use_address
1116 +/* For various ports, try to guess a fixed spot in the vm space
1117 + that's probably free. */
1118 +#if defined(__sparc64__)
1119 +# define TRY_EMPTY_VM_SPACE 0x40000000000
1120 +#elif defined(_LP64)
1121 +# define TRY_EMPTY_VM_SPACE 0x400000000000
1122 +#elif defined(__mips__) || defined(__vax__) || defined (__arm__)
1123 +# define TRY_EMPTY_VM_SPACE 0x60000000
1124 +#else
1125 +# define TRY_EMPTY_VM_SPACE 0xb0000000
1126 +#endif
1128 +/* Determine a location where we might be able to reliably allocate
1129 + SIZE bytes. FD is the PCH file, though we should return with the
1130 + file unmapped. */
1132 +static void *
1133 +netbsd_gt_pch_get_address (size_t size, int fd)
1135 + void *addr;
1137 + addr = mmap ((void *) TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE,
1138 + MAP_PRIVATE | MAP_FIXED, fd, 0);
1140 + /* If we failed the map, that means there's *no* free space. */
1141 + if (addr == (void *) MAP_FAILED)
1142 + return NULL;
1143 + /* Unmap the area before returning. */
1144 + munmap (addr, size);
1146 + return addr;
1149 +/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at
1150 + mapping the data at BASE, -1 if we couldn't. */
1152 +static int
1153 +netbsd_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
1155 + void *addr;
1157 + /* We're called with size == 0 if we're not planning to load a PCH
1158 + file at all. This allows the hook to free any static space that
1159 + we might have allocated at link time. */
1160 + if (size == 0)
1161 + return -1;
1163 + addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, offset);
1165 + return addr == base ? 1 : -1;
1169 +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
1170 diff -rNU3 dist.orig/gcc/config/i386/i386.h dist/gcc/config/i386/i386.h
1171 --- dist.orig/gcc/config/i386/i386.h 2014-01-08 20:54:29.000000000 +0100
1172 +++ dist/gcc/config/i386/i386.h 2015-10-18 13:19:50.000000000 +0200
1173 @@ -1071,6 +1071,7 @@
1175 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
1176 (CC_REGNO_P (REGNO) ? VOIDmode \
1177 + : MMX_REGNO_P (REGNO) ? V8QImode \
1178 : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \
1179 : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \
1180 : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \
1181 diff -rNU3 dist.orig/gcc/config/i386/netbsd-elf.h dist/gcc/config/i386/netbsd-elf.h
1182 --- dist.orig/gcc/config/i386/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
1183 +++ dist/gcc/config/i386/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
1184 @@ -118,4 +118,10 @@
1185 we don't care about compatibility with older gcc versions. */
1186 #define DEFAULT_PCC_STRUCT_RETURN 1
1188 -#define HAVE_ENABLE_EXECUTE_STACK
1189 +#undef X87_ENABLE_ARITH
1190 +#define X87_ENABLE_ARITH(MODE) \
1191 + (flag_excess_precision == EXCESS_PRECISION_FAST || (MODE) == DFmode)
1193 +/* Preserve i386 psABI */
1194 +#undef PREFERRED_STACK_BOUNDARY_DEFAULT
1195 +#define PREFERRED_STACK_BOUNDARY_DEFAULT MIN_STACK_BOUNDARY
1196 diff -rNU3 dist.orig/gcc/config/i386/netbsd64.h dist/gcc/config/i386/netbsd64.h
1197 --- dist.orig/gcc/config/i386/netbsd64.h 2013-01-10 21:38:27.000000000 +0100
1198 +++ dist/gcc/config/i386/netbsd64.h 2015-10-18 13:19:50.000000000 +0200
1199 @@ -66,4 +66,8 @@
1200 fprintf (FILE, "\tcall __mcount\n"); \
1203 +/* Preserve i386 psABI */
1204 +#undef PREFERRED_STACK_BOUNDARY_DEFAULT
1205 +#define PREFERRED_STACK_BOUNDARY_DEFAULT MIN_STACK_BOUNDARY
1207 #define HAVE_ENABLE_EXECUTE_STACK
1208 diff -rNU3 dist.orig/gcc/config/i386/pmm_malloc.h dist/gcc/config/i386/pmm_malloc.h
1209 --- dist.orig/gcc/config/i386/pmm_malloc.h 2013-01-10 21:38:27.000000000 +0100
1210 +++ dist/gcc/config/i386/pmm_malloc.h 2015-10-18 13:19:50.000000000 +0200
1211 @@ -31,7 +31,7 @@
1212 #ifndef __cplusplus
1213 extern int posix_memalign (void **, size_t, size_t);
1214 #else
1215 -extern "C" int posix_memalign (void **, size_t, size_t) throw ();
1216 +extern "C" int posix_memalign (void **, size_t, size_t);
1217 #endif
1219 static __inline void *
1220 diff -rNU3 dist.orig/gcc/config/i386/t-netbsd64 dist/gcc/config/i386/t-netbsd64
1221 --- dist.orig/gcc/config/i386/t-netbsd64 1970-01-01 01:00:00.000000000 +0100
1222 +++ dist/gcc/config/i386/t-netbsd64 2015-10-18 13:19:50.000000000 +0200
1223 @@ -0,0 +1,15 @@
1224 +# NetBSD has (will have) "non-native" libraries in /usr/lib/<arch>.
1225 +# For NetBSD/amd64 we thus have /usr/lib and /usr/lib/i386.
1227 +MULTILIB_OPTIONS = m64/m32
1228 +MULTILIB_DIRNAMES = 64 32
1229 +MULTILIB_OSDIRNAMES = . ../lib/i386
1231 +LIBGCC = stmp-multilib
1232 +INSTALL_LIBGCC = install-multilib
1234 +# The pushl in CTOR initialization interferes with frame pointer elimination.
1235 +# crtend*.o cannot be compiled without -fno-asynchronous-unwind-tables,
1236 +# because then __FRAME_END__ might not be the last thing in .eh_frame
1237 +# section.
1238 +CRTSTUFF_T_CFLAGS += -fno-omit-frame-pointer -fno-asynchronous-unwind-tables
1239 diff -rNU3 dist.orig/gcc/config/ia64/netbsd.h dist/gcc/config/ia64/netbsd.h
1240 --- dist.orig/gcc/config/ia64/netbsd.h 1970-01-01 01:00:00.000000000 +0100
1241 +++ dist/gcc/config/ia64/netbsd.h 2015-10-18 13:19:50.000000000 +0200
1242 @@ -0,0 +1,56 @@
1243 +/* Definitions of target machine for GNU compiler,
1244 + for ia64/ELF NetBSD systems.
1245 + Copyright (C) 2005 Free Software Foundation, Inc.
1247 +This file is part of GNU CC.
1249 +GNU CC is free software; you can redistribute it and/or modify
1250 +it under the terms of the GNU General Public License as published by
1251 +the Free Software Foundation; either version 2, or (at your option)
1252 +any later version.
1254 +GNU CC is distributed in the hope that it will be useful,
1255 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1256 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1257 +GNU General Public License for more details.
1259 +You should have received a copy of the GNU General Public License
1260 +along with GNU CC; see the file COPYING. If not, write to
1261 +the Free Software Foundation, 59 Temple Place - Suite 330,
1262 +Boston, MA 02111-1307, USA. */
1264 +#define TARGET_OS_CPP_BUILTINS() \
1265 + do \
1266 + { \
1267 + NETBSD_OS_CPP_BUILTINS_ELF(); \
1268 + } \
1269 + while (0)
1272 +/* Extra specs needed for NetBSD/ia-64 ELF. */
1274 +#undef SUBTARGET_EXTRA_SPECS
1275 +#define SUBTARGET_EXTRA_SPECS \
1276 + { "netbsd_cpp_spec", NETBSD_CPP_SPEC }, \
1277 + { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
1278 + { "netbsd_entry_point", NETBSD_ENTRY_POINT },
1281 +/* Provide a LINK_SPEC appropriate for a NetBSD/ia64 ELF target. */
1283 +#undef LINK_SPEC
1284 +#define LINK_SPEC "%(netbsd_link_spec)"
1286 +#define NETBSD_ENTRY_POINT "_start"
1289 +/* Provide a CPP_SPEC appropriate for NetBSD. */
1291 +#undef CPP_SPEC
1292 +#define CPP_SPEC "%(netbsd_cpp_spec)"
1295 +#if 0
1296 +/* Attempt to enable execute permissions on the stack. */
1297 +#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
1298 +#endif
1299 diff -rNU3 dist.orig/gcc/config/m68k/m68k.md dist/gcc/config/m68k/m68k.md
1300 --- dist.orig/gcc/config/m68k/m68k.md 2013-01-10 21:38:27.000000000 +0100
1301 +++ dist/gcc/config/m68k/m68k.md 2015-10-18 13:19:50.000000000 +0200
1302 @@ -3124,16 +3124,33 @@
1303 ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
1304 ;; proper matching constraint. This is because the matching is between
1305 ;; the high-numbered word of the DImode operand[0] and operand[1].
1307 +;; Note: life_analysis() does not keep track of the individual halves of the
1308 +;; DImode register. To prevent spurious liveness before the u?mulsidi3 insn
1309 +;; (which causes "uninitialized variable" warnings), we explicitly clobber
1310 +;; the DImode register.
1311 (define_expand "umulsidi3"
1312 - [(parallel
1313 - [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
1314 - (mult:SI (match_operand:SI 1 "register_operand" "")
1315 - (match_operand:SI 2 "register_operand" "")))
1316 + [(set (match_operand:DI 0 "register_operand" "")
1317 + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1318 + (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1319 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1320 + "")
1322 +(define_insn_and_split "*umulsidi3_split"
1323 + [(set (match_operand:DI 0 "register_operand" "")
1324 + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1325 + (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1326 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1327 + "#"
1328 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1329 + [(clobber (match_dup 0))
1330 + (parallel
1331 + [(set (subreg:SI (match_dup 0) 4)
1332 + (mult:SI (match_dup 1) (match_dup 2)))
1333 (set (subreg:SI (match_dup 0) 0)
1334 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
1335 (zero_extend:DI (match_dup 2)))
1336 (const_int 32))))])]
1337 - "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1340 (define_insn ""
1341 @@ -3164,15 +3181,27 @@
1342 "mulu%.l %2,%3:%0")
1344 (define_expand "mulsidi3"
1345 - [(parallel
1346 - [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
1347 - (mult:SI (match_operand:SI 1 "register_operand" "")
1348 - (match_operand:SI 2 "register_operand" "")))
1349 + [(set (match_operand:DI 0 "register_operand" "")
1350 + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1351 + (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1352 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1353 + "")
1355 +(define_insn_and_split "*mulsidi3_split"
1356 + [(set (match_operand:DI 0 "register_operand" "")
1357 + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1358 + (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1359 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1360 + "#"
1361 + "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1362 + [(clobber (match_dup 0))
1363 + (parallel
1364 + [(set (subreg:SI (match_dup 0) 4)
1365 + (mult:SI (match_dup 1) (match_dup 2)))
1366 (set (subreg:SI (match_dup 0) 0)
1367 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
1368 (sign_extend:DI (match_dup 2)))
1369 (const_int 32))))])]
1370 - "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
1373 (define_insn ""
1374 diff -rNU3 dist.orig/gcc/config/m68k/netbsd-elf.h dist/gcc/config/m68k/netbsd-elf.h
1375 --- dist.orig/gcc/config/m68k/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
1376 +++ dist/gcc/config/m68k/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
1377 @@ -35,19 +35,34 @@
1379 while (0)
1381 -/* Don't try using XFmode on the 68010. */
1382 +/* Don't try using XFmode on the 68010 or coldfire. */
1383 #undef LONG_DOUBLE_TYPE_SIZE
1384 #define LONG_DOUBLE_TYPE_SIZE (TARGET_68020 ? 80 : 64)
1386 #undef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
1387 -#ifdef __mc68010__
1388 +#if defined(__mc68010__) || defined(__mcoldfire__)
1389 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
1390 #else
1391 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
1392 #endif
1394 +#undef SUBTARGET_OVERRIDE_OPTIONS
1395 +#define SUBTARGET_OVERRIDE_OPTIONS \
1396 + { \
1397 + if (TARGET_COLDFIRE) \
1398 + { \
1399 + target_flags |= MASK_STRICT_ALIGNMENT | MASK_CF_HWDIV; \
1400 + if ((target_flags_explicit & MASK_HARD_FLOAT) == 0) \
1401 + { \
1402 + target_flags &= ~MASK_HARD_FLOAT; \
1403 + m68k_fpu = FPUTYPE_NONE; \
1404 + } \
1405 + } \
1408 #undef SUBTARGET_EXTRA_SPECS
1409 #define SUBTARGET_EXTRA_SPECS \
1410 + { "netbsd_cpp_spec", NETBSD_CPP_SPEC }, \
1411 { "netbsd_entry_point", NETBSD_ENTRY_POINT },
1414 @@ -56,20 +71,31 @@
1415 whether or not use of the FPU is allowed. */
1417 #undef CPP_SPEC
1418 -#define CPP_SPEC NETBSD_CPP_SPEC
1419 +#define CPP_SPEC \
1420 + "%(netbsd_cpp_spec)"
1423 /* Provide an ASM_SPEC appropriate for NetBSD m68k ELF targets. We need
1424 to pass PIC code generation options. */
1426 #undef ASM_SPEC
1427 -#define ASM_SPEC "%(asm_cpu_spec) %{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
1428 +#define ASM_SPEC \
1429 + "%(asm_default_spec) \
1430 + %{m68010} %{m68020} %{m68030} %{m68040} %{m68060} \
1431 + %{m5200} %{m5206e} %{m528x} %{m5307} %{m5407} %{mcfv4e}\
1432 + %{mcpu=*:-mcpu=%*} %{march=*:-march=%*}\
1433 + %{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
1435 /* Provide a LINK_SPEC appropriate for a NetBSD/m68k ELF target. */
1437 #undef LINK_SPEC
1438 #define LINK_SPEC NETBSD_LINK_SPEC_ELF
1440 +/* NetBSD/sun2 does not support shlibs, avoid using libgcc_pic. */
1441 +#if TARGET_DEFAULT_CPU == 0
1442 +#undef REAL_LIBGCC_SPEC
1443 +#endif
1445 #define NETBSD_ENTRY_POINT "_start"
1447 /* Output assembler code to FILE to increment profiler label # LABELNO
1448 @@ -79,7 +105,13 @@
1449 #define FUNCTION_PROFILER(FILE, LABELNO) \
1450 do \
1452 - asm_fprintf (FILE, "\tlea (%LLP%d,%Rpc),%Ra1\n", (LABELNO)); \
1453 + if (TARGET_COLDFIRE) \
1454 + { \
1455 + asm_fprintf (FILE, "\tmovea.l #%LLP%d-.,%Ra1\n", (LABELNO)); \
1456 + asm_fprintf (FILE, "\tlea (-6,%Rpc,%Ra1),%Ra1\n", (LABELNO)); \
1457 + } \
1458 + else \
1459 + asm_fprintf (FILE, "\tlea (%LLP%d,%Rpc),%Ra1\n", (LABELNO)); \
1460 if (flag_pic) \
1461 fprintf (FILE, "\tbsr.l __mcount@PLTPC\n"); \
1462 else \
1463 @@ -270,6 +302,8 @@
1465 #undef STACK_BOUNDARY
1466 #define STACK_BOUNDARY 32
1467 +#undef PREFERRED_STACK_BOUNDARY
1468 +#define PREFERRED_STACK_BOUNDARY 32
1471 /* Alignment of field after `int : 0' in a structure.
1472 diff -rNU3 dist.orig/gcc/config/m68k/t-m68010-netbsd dist/gcc/config/m68k/t-m68010-netbsd
1473 --- dist.orig/gcc/config/m68k/t-m68010-netbsd 1970-01-01 01:00:00.000000000 +0100
1474 +++ dist/gcc/config/m68k/t-m68010-netbsd 2015-10-18 13:19:50.000000000 +0200
1475 @@ -0,0 +1,4 @@
1476 +# Use unwind-dw2-fde-glibc
1477 +LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
1478 + $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
1479 +LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
1480 diff -rNU3 dist.orig/gcc/config/m68k/t-opts dist/gcc/config/m68k/t-opts
1481 --- dist.orig/gcc/config/m68k/t-opts 2011-05-02 17:42:39.000000000 +0200
1482 +++ dist/gcc/config/m68k/t-opts 2015-10-18 13:19:50.000000000 +0200
1483 @@ -1,5 +1,7 @@
1484 $(srcdir)/config/m68k/m68k-tables.opt: $(srcdir)/config/m68k/genopt.sh \
1485 $(srcdir)/config/m68k/m68k-devices.def $(srcdir)/config/m68k/m68k-isas.def \
1486 $(srcdir)/config/m68k/m68k-microarchs.def
1487 + @echo "NOT REBUILDING $@"
1488 +NetBSD_DISABLED_m68k-tables.opt:
1489 $(SHELL) $(srcdir)/config/m68k/genopt.sh $(srcdir)/config/m68k > \
1490 $(srcdir)/config/m68k/m68k-tables.opt
1491 diff -rNU3 dist.orig/gcc/config/mips/netbsd.h dist/gcc/config/mips/netbsd.h
1492 --- dist.orig/gcc/config/mips/netbsd.h 2013-01-10 21:38:27.000000000 +0100
1493 +++ dist/gcc/config/mips/netbsd.h 2015-10-18 13:19:50.000000000 +0200
1494 @@ -32,16 +32,63 @@
1495 if (TARGET_ABICALLS) \
1496 builtin_define ("__ABICALLS__"); \
1498 - if (mips_abi == ABI_EABI) \
1499 - builtin_define ("__mips_eabi"); \
1500 - else if (mips_abi == ABI_N32) \
1501 + /* The GNU C++ standard library requires this. */ \
1502 + if (c_dialect_cxx ()) \
1503 + builtin_define ("_GNU_SOURCE"); \
1505 + if (mips_abi == ABI_N32) \
1506 + { \
1507 builtin_define ("__mips_n32"); \
1508 + builtin_define ("_ABIN32=2"); \
1509 + builtin_define ("_MIPS_SIM=_ABIN32"); \
1510 + builtin_define ("_MIPS_SZLONG=32"); \
1511 + builtin_define ("_MIPS_SZPTR=32"); \
1512 + } \
1513 else if (mips_abi == ABI_64) \
1514 + { \
1515 builtin_define ("__mips_n64"); \
1516 + builtin_define ("_ABI64=3"); \
1517 + builtin_define ("_MIPS_SIM=_ABI64"); \
1518 + builtin_define ("_MIPS_SZLONG=64"); \
1519 + builtin_define ("_MIPS_SZPTR=64"); \
1520 + } \
1521 else if (mips_abi == ABI_O64) \
1522 + { \
1523 builtin_define ("__mips_o64"); \
1524 + builtin_define ("_ABIO64=4"); \
1525 + builtin_define ("_MIPS_SIM=_ABIO64"); \
1526 + builtin_define ("_MIPS_SZLONG=64"); \
1527 + builtin_define ("_MIPS_SZPTR=64"); \
1529 - while (0)
1530 + else if (mips_abi == ABI_EABI) \
1531 + { \
1532 + builtin_define ("__mips_eabi"); \
1533 + builtin_define ("_ABIEMB=5"); \
1534 + builtin_define ("_MIPS_SIM=_ABIEMB"); \
1535 + if (TARGET_LONG64) \
1536 + builtin_define ("_MIPS_SZLONG=64"); \
1537 + else \
1538 + builtin_define ("_MIPS_SZLONG=32"); \
1539 + if (TARGET_64BIT) \
1540 + builtin_define ("_MIPS_SZPTR=64"); \
1541 + else \
1542 + builtin_define ("_MIPS_SZPTR=32"); \
1543 + } \
1544 + else \
1545 + { \
1546 + builtin_define ("__mips_o32"); \
1547 + builtin_define ("_ABIO32=1"); \
1548 + builtin_define ("_MIPS_SIM=_ABIO32"); \
1549 + builtin_define ("_MIPS_SZLONG=32"); \
1550 + builtin_define ("_MIPS_SZPTR=32"); \
1551 + } \
1552 + if (TARGET_FLOAT64) \
1553 + builtin_define ("_MIPS_FPSET=32"); \
1554 + else \
1555 + builtin_define ("_MIPS_FPSET=16"); \
1557 + builtin_define ("_MIPS_SZINT=32"); \
1558 + } while (0)
1560 /* The generic MIPS TARGET_CPU_CPP_BUILTINS are incorrect for NetBSD.
1561 Specifically, they define too many namespace-invasive macros. Override
1562 @@ -97,6 +144,11 @@
1563 builtin_define ("__mips=64"); \
1564 builtin_define ("__mips_isa_rev=1"); \
1566 + else if (ISA_MIPS64R2) \
1567 + { \
1568 + builtin_define ("__mips=64"); \
1569 + builtin_define ("__mips_isa_rev=2"); \
1570 + } \
1572 if (TARGET_HARD_FLOAT) \
1573 builtin_define ("__mips_hard_float"); \
1574 @@ -111,6 +163,11 @@
1575 else \
1576 builtin_define ("__MIPSEL__"); \
1578 + if (TARGET_OCTEON) \
1579 + builtin_define ("__OCTEON__"); \
1581 + if (ISA_HAS_POP) \
1582 + builtin_define ("__mips_popcount"); \
1583 /* No language dialect defines. */ \
1585 /* ABIs handled in TARGET_OS_CPP_BUILTINS. */ \
1586 @@ -136,10 +193,12 @@
1588 #undef LINK_SPEC
1589 #define LINK_SPEC \
1590 - "%{EL:-m elf32lmip} \
1591 - %{EB:-m elf32bmip} \
1592 + "%{EL:-m elf32ltsmip} \
1593 + %{EB:-m elf32btsmip} \
1594 %(endian_spec) \
1595 - %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \
1596 + %{G*} %{mips1} %{mips2} %{mips3} %{mips4} \
1597 + %{mips32} %{mips32r2} %{mips64} %{mips64r2} \
1598 + %{bestGnum} %{call_shared} %{no_archive} %{exact_version} \
1599 %(netbsd_link_spec)"
1601 #define NETBSD_ENTRY_POINT "__start"
1602 @@ -169,6 +228,20 @@
1604 /* Make gcc agree with <machine/ansi.h> */
1606 +#undef SIZE_TYPE
1607 +#define SIZE_TYPE ((POINTER_SIZE == 64 || TARGET_NEWABI) \
1608 + ? "long unsigned int" : "unsigned int")
1610 +#undef PTRDIFF_TYPE
1611 +#define PTRDIFF_TYPE ((POINTER_SIZE == 64 || TARGET_NEWABI) \
1612 + ? "long int" : "int")
1614 +#undef INTPTR_TYPE
1615 +#define INTPTR_TYPE PTRDIFF_TYPE
1617 +#undef UINTPTR_TYPE
1618 +#define UINTPTR_TYPE SIZE_TYPE
1620 #undef WCHAR_TYPE
1621 #define WCHAR_TYPE "int"
1623 @@ -177,3 +250,6 @@
1625 #undef WINT_TYPE
1626 #define WINT_TYPE "int"
1628 +#undef TARGET_WRITABLE_EH_FRAME
1629 +#define TARGET_WRITABLE_EH_FRAME (flag_pic && TARGET_SHARED)
1630 diff -rNU3 dist.orig/gcc/config/mips/netbsd64.h dist/gcc/config/mips/netbsd64.h
1631 --- dist.orig/gcc/config/mips/netbsd64.h 1970-01-01 01:00:00.000000000 +0100
1632 +++ dist/gcc/config/mips/netbsd64.h 2015-10-18 13:19:50.000000000 +0200
1633 @@ -0,0 +1,47 @@
1634 +/* Definitions of target machine for GNU compiler, for MIPS NetBSD systems.
1635 + Copyright (C) 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004
1636 + Free Software Foundation, Inc.
1638 +This file is part of GCC.
1640 +GCC is free software; you can redistribute it and/or modify
1641 +it under the terms of the GNU General Public License as published by
1642 +the Free Software Foundation; either version 2, or (at your option)
1643 +any later version.
1645 +GCC is distributed in the hope that it will be useful,
1646 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1647 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1648 +GNU General Public License for more details.
1650 +You should have received a copy of the GNU General Public License
1651 +along with GCC; see the file COPYING. If not, write to
1652 +the Free Software Foundation, 51 Franklin Street, Fifth Floor,
1653 +Boston, MA 02110-1301, USA. */
1655 +/* Force the default endianness and ABI flags onto the command line
1656 + in order to make the other specs easier to write. */
1658 +#undef DRIVER_SELF_SPECS
1659 +#define DRIVER_SELF_SPECS \
1660 + BASE_DRIVER_SELF_SPECS \
1661 + "%{!EB:%{!EL:%(endian_spec)}}", \
1662 + "%{!mabi=*: -mabi=n32}"
1664 +/* Define default target values. */
1666 +/* Provide a LINK_SPEC appropriate for a NetBSD/mips target.
1667 + This is a copy of LINK_SPEC from <netbsd-elf.h> tweaked for
1668 + the MIPS target. */
1670 +#undef LINK_SPEC
1671 +#define LINK_SPEC \
1672 + "%{mabi=64:-m elf64%{EB:b}%{EL:l}tsmip} \
1673 + %{mabi=32:-m elf32%{EB:b}%{EL:l}tsmip} \
1674 + %{mabi=o64:-m elf64%{EB:b}%{EL:l}tsmip} \
1675 + %{mabi=n32:-m elf32%{EB:b}%{EL:l}tsmipn32} \
1676 + %(endian_spec) \
1677 + %{G*} %{mips1} %{mips2} %{mips3} %{mips4} \
1678 + %{mips32} %{mips32r2} %{mips64} %{mips64r2} \
1679 + %{bestGnum} %{call_shared} %{no_archive} %{exact_version} \
1680 + %(netbsd_link_spec)"
1681 diff -rNU3 dist.orig/gcc/config/mips/t-mips dist/gcc/config/mips/t-mips
1682 --- dist.orig/gcc/config/mips/t-mips 2013-01-10 21:38:27.000000000 +0100
1683 +++ dist/gcc/config/mips/t-mips 2015-10-18 13:19:50.000000000 +0200
1684 @@ -18,5 +18,7 @@
1686 $(srcdir)/config/mips/mips-tables.opt: $(srcdir)/config/mips/genopt.sh \
1687 $(srcdir)/config/mips/mips-cpus.def
1688 + @echo "NOT REBUILDING $@"
1689 +NetBSD_DISABLED_config_mips_mips-tables.opt:
1690 $(SHELL) $(srcdir)/config/mips/genopt.sh $(srcdir)/config/mips > \
1691 $(srcdir)/config/mips/mips-tables.opt
1692 diff -rNU3 dist.orig/gcc/config/mips/t-netbsd64 dist/gcc/config/mips/t-netbsd64
1693 --- dist.orig/gcc/config/mips/t-netbsd64 1970-01-01 01:00:00.000000000 +0100
1694 +++ dist/gcc/config/mips/t-netbsd64 2015-10-18 13:19:50.000000000 +0200
1695 @@ -0,0 +1,9 @@
1696 +# NetBSD has (will have) "non-native" libraries in /usr/lib/<arch>.
1697 +# For NetBSD/mips64 we thus have /usr/lib (n32), /usr/lib/o32 and /usr/lib/64.
1699 +MULTILIB_OPTIONS = mabi=n32/mabi=64/mabi=32
1700 +MULTILIB_DIRNAMES = n32 n64 o32
1701 +MULTILIB_OSDIRNAMES = . ../lib/64 ../lib/o32
1703 +LIBGCC = stmp-multilib
1704 +INSTALL_LIBGCC = install-multilib
1705 diff -rNU3 dist.orig/gcc/config/netbsd-elf.h dist/gcc/config/netbsd-elf.h
1706 --- dist.orig/gcc/config/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
1707 +++ dist/gcc/config/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
1708 @@ -40,8 +40,11 @@
1709 %{!p:crt0%O%s}}} \
1710 %:if-exists(crti%O%s) \
1711 %{static:%:if-exists-else(crtbeginT%O%s crtbegin%O%s)} \
1712 - %{!static: \
1713 - %{!shared:crtbegin%O%s} %{shared:crtbeginS%O%s}}"
1714 + %{!static: \
1715 + %{!shared: \
1716 + %{!pie:crtbegin%O%s} \
1717 + %{pie:crtbeginS%O%s}} \
1718 + %{shared:crtbeginS%O%s}}"
1720 #undef STARTFILE_SPEC
1721 #define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
1722 @@ -52,7 +55,10 @@
1723 C++ file-scope static objects deconstructed after exiting "main". */
1725 #define NETBSD_ENDFILE_SPEC \
1726 - "%{!shared:crtend%O%s} %{shared:crtendS%O%s} \
1727 + "%{!shared: \
1728 + %{!pie:crtend%O%s} \
1729 + %{pie:crtendS%O%s}} \
1730 + %{shared:crtendS%O%s} \
1731 %:if-exists(crtn%O%s)"
1733 #undef ENDFILE_SPEC
1734 @@ -70,6 +76,7 @@
1735 #define NETBSD_LINK_SPEC_ELF \
1736 "%{assert*} %{R*} %{rpath*} \
1737 %{shared:-shared} \
1738 + %{symbolic:-Bsymbolic} \
1739 %{!shared: \
1740 -dc -dp \
1741 %{!nostdlib: \
1742 @@ -84,3 +91,11 @@
1743 #ifdef HAVE_LD_AS_NEEDED
1744 #define USE_LD_AS_NEEDED 1
1745 #endif
1747 +#define MFLIB_SPEC " %{fmudflap: -export-dynamic -lmudflap \
1748 + %{static:%(link_gcc_c_sequence) -lmudflap}} \
1749 + %{fmudflapth: -export-dynamic -lmudflapth -lpthread \
1750 + %{static:%(link_gcc_c_sequence) -lmudflapth}} "
1752 +#undef TARGET_UNWIND_TABLES_DEFAULT
1753 +#define TARGET_UNWIND_TABLES_DEFAULT true
1754 diff -rNU3 dist.orig/gcc/config/netbsd-stdint.h dist/gcc/config/netbsd-stdint.h
1755 --- dist.orig/gcc/config/netbsd-stdint.h 1970-01-01 01:00:00.000000000 +0100
1756 +++ dist/gcc/config/netbsd-stdint.h 2015-10-18 13:19:50.000000000 +0200
1757 @@ -0,0 +1,72 @@
1758 +/* Definitions for <stdint.h> types for NetBSD systems.
1759 + Copyright (C) 2009 Free Software Foundation, Inc.
1760 + Contributed by Gerald Pfeifer <gerald@pfeifer.com>.
1762 +This file is part of GCC.
1764 +GCC is free software; you can redistribute it and/or modify
1765 +it under the terms of the GNU General Public License as published by
1766 +the Free Software Foundation; either version 3, or (at your option)
1767 +any later version.
1769 +GCC is distributed in the hope that it will be useful,
1770 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1771 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1772 +GNU General Public License for more details.
1774 +Under Section 7 of GPL version 3, you are granted additional
1775 +permissions described in the GCC Runtime Library Exception, version
1776 +3.1, as published by the Free Software Foundation.
1778 +You should have received a copy of the GNU General Public License and
1779 +a copy of the GCC Runtime Library Exception along with this program;
1780 +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1781 +<http://www.gnu.org/licenses/>. */
1783 +#define SIG_ATOMIC_TYPE "int"
1785 +#define INT8_TYPE "signed char"
1786 +#define INT16_TYPE "short int"
1787 +#define INT32_TYPE "int"
1788 +#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
1789 +#define UINT8_TYPE "unsigned char"
1790 +#define UINT16_TYPE "short unsigned int"
1791 +#define UINT32_TYPE "unsigned int"
1792 +#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
1794 +#define INT_LEAST8_TYPE "signed char"
1795 +#define INT_LEAST16_TYPE "short int"
1796 +#define INT_LEAST32_TYPE "int"
1797 +#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
1798 +#define UINT_LEAST8_TYPE "unsigned char"
1799 +#define UINT_LEAST16_TYPE "short unsigned int"
1800 +#define UINT_LEAST32_TYPE "unsigned int"
1801 +#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
1803 +#ifdef CHAR_FAST8
1804 +#define INT_FAST8_TYPE (LONG_TYPE_SIZE == 64 ? "int" : "signed char")
1805 +#else
1806 +#define INT_FAST8_TYPE "int"
1807 +#endif
1808 +#ifdef SHORT_FAST16
1809 +#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "int" : "short int")
1810 +#else
1811 +#define INT_FAST16_TYPE "int"
1812 +#endif
1813 +#define INT_FAST32_TYPE "int"
1814 +#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
1815 +#ifdef CHAR_FAST8
1816 +#define UINT_FAST8_TYPE (LONG_TYPE_SIZE == 64 ? "unsigned int" : "unsigned char")
1817 +#else
1818 +#define UINT_FAST8_TYPE "unsigned int"
1819 +#endif
1820 +#ifdef SHORT_FAST16
1821 +#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "unsigned int" : "short unsigned int")
1822 +#else
1823 +#define UINT_FAST16_TYPE "unsigned int"
1824 +#endif
1825 +#define UINT_FAST32_TYPE "unsigned int"
1826 +#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
1828 +#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
1829 +#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
1830 diff -rNU3 dist.orig/gcc/config/netbsd.h dist/gcc/config/netbsd.h
1831 --- dist.orig/gcc/config/netbsd.h 2013-01-10 21:38:27.000000000 +0100
1832 +++ dist/gcc/config/netbsd.h 2015-10-18 13:19:50.000000000 +0200
1833 @@ -36,37 +36,59 @@
1835 /* NETBSD_NATIVE is defined when gcc is integrated into the NetBSD
1836 source tree so it can be configured appropriately without using
1837 - the GNU configure/build mechanism. */
1838 + the GNU configure/build mechanism.
1840 -#ifdef NETBSD_NATIVE
1841 + NETBSD_TOOLS is defined when gcc is built as cross-compiler for
1842 + the in-tree toolchain.
1843 + */
1845 +#if defined(NETBSD_NATIVE) || defined(NETBSD_TOOLS)
1847 /* Look for the include files in the system-defined places. */
1849 #undef GPLUSPLUS_INCLUDE_DIR
1850 #define GPLUSPLUS_INCLUDE_DIR "/usr/include/g++"
1852 +#undef GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT
1853 +#define GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT 1
1855 +#undef GPLUSPLUS_BACKWARD_INCLUDE_DIR
1856 +#define GPLUSPLUS_BACKWARD_INCLUDE_DIR "/usr/include/g++/backward"
1858 +#undef GCC_INCLUDE_DIR_ADD_SYSROOT
1859 +#define GCC_INCLUDE_DIR_ADD_SYSROOT 1
1862 + * XXX figure out a better way to do this
1863 + */
1864 #undef GCC_INCLUDE_DIR
1865 -#define GCC_INCLUDE_DIR "/usr/include"
1866 +#define GCC_INCLUDE_DIR "/usr/include/gcc-4.8"
1868 -#undef INCLUDE_DEFAULTS
1869 -#define INCLUDE_DEFAULTS \
1870 - { \
1871 - { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 }, \
1872 - { GCC_INCLUDE_DIR, "GCC", 0, 0 }, \
1873 - { 0, 0, 0, 0 } \
1875 +/* Under NetBSD, the normal location of the various *crt*.o files is the
1876 + /usr/lib directory. */
1878 +#undef STANDARD_STARTFILE_PREFIX
1879 +#define STANDARD_STARTFILE_PREFIX "/usr/lib/"
1880 +#undef STANDARD_STARTFILE_PREFIX_1
1881 +#define STANDARD_STARTFILE_PREFIX_1 "/usr/lib/"
1883 +#endif /* NETBSD_NATIVE || NETBSD_TOOLS */
1885 +#if defined(NETBSD_NATIVE)
1886 /* Under NetBSD, the normal location of the compiler back ends is the
1887 /usr/libexec directory. */
1889 #undef STANDARD_EXEC_PREFIX
1890 #define STANDARD_EXEC_PREFIX "/usr/libexec/"
1892 -/* Under NetBSD, the normal location of the various *crt*.o files is the
1893 - /usr/lib directory. */
1894 +#undef TOOLDIR_BASE_PREFIX
1895 +#define TOOLDIR_BASE_PREFIX "../"
1897 -#undef STANDARD_STARTFILE_PREFIX
1898 -#define STANDARD_STARTFILE_PREFIX "/usr/lib/"
1899 +#undef STANDARD_BINDIR_PREFIX
1900 +#define STANDARD_BINDIR_PREFIX "/usr/bin"
1902 +#undef STANDARD_LIBEXEC_PREFIX
1903 +#define STANDARD_LIBEXEC_PREFIX STANDARD_EXEC_PREFIX
1905 #endif /* NETBSD_NATIVE */
1907 @@ -96,6 +118,7 @@
1908 %{!pg:-lposix}} \
1909 %{p:-lposix_p} \
1910 %{pg:-lposix_p}} \
1911 + %{shared:-lc} \
1912 %{!shared: \
1913 %{!symbolic: \
1914 %{!p: \
1915 @@ -109,6 +132,7 @@
1916 %{!pg:-lposix}} \
1917 %{p:-lposix_p} \
1918 %{pg:-lposix_p}} \
1919 + %{shared:-lc} \
1920 %{!shared: \
1921 %{!symbolic: \
1922 %{!p: \
1923 @@ -120,24 +144,18 @@
1924 #undef LIB_SPEC
1925 #define LIB_SPEC NETBSD_LIB_SPEC
1927 -/* Provide a LIBGCC_SPEC appropriate for NetBSD. We also want to exclude
1928 - libgcc with -symbolic. */
1929 +#undef STATIC_LIBASAN_LIBS
1930 +#define STATIC_LIBASAN_LIBS "-lstdc++ -lpthread"
1932 -#ifdef NETBSD_NATIVE
1933 -#define NETBSD_LIBGCC_SPEC \
1934 - "%{!symbolic: \
1935 - %{!shared: \
1936 - %{!p: \
1937 - %{!pg: -lgcc}}} \
1938 - %{shared: -lgcc_pic} \
1939 - %{p: -lgcc_p} \
1940 - %{pg: -lgcc_p}}"
1941 -#else
1942 -#define NETBSD_LIBGCC_SPEC "%{!shared:%{!symbolic: -lgcc}}"
1943 -#endif
1944 +/* Pass -cxx-isystem to cc1/cc1plus. */
1945 +#define NETBSD_CC1_AND_CC1PLUS_SPEC \
1946 + "%{cxx-isystem}"
1948 +#undef CC1_SPEC
1949 +#define CC1_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC
1951 -#undef LIBGCC_SPEC
1952 -#define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
1953 +#undef CC1PLUS_SPEC
1954 +#define CC1PLUS_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC
1956 /* When building shared libraries, the initialization and finalization
1957 functions for the library are .init and .fini respectively. */
1958 @@ -172,3 +190,10 @@
1960 #undef WINT_TYPE
1961 #define WINT_TYPE "int"
1963 +#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
1965 +/* Use --as-needed -lgcc_s for eh support. */
1966 +#ifdef HAVE_LD_AS_NEEDED
1967 +#define USE_LD_AS_NEEDED 1
1968 +#endif
1969 diff -rNU3 dist.orig/gcc/config/or1k/constraints.md dist/gcc/config/or1k/constraints.md
1970 --- dist.orig/gcc/config/or1k/constraints.md 1970-01-01 01:00:00.000000000 +0100
1971 +++ dist/gcc/config/or1k/constraints.md 2015-10-18 13:19:50.000000000 +0200
1972 @@ -0,0 +1,59 @@
1973 +;; Copyright (C) 2010 Embecosm Limited
1975 +;; Contributed by Joern Rennecke <joern.rennecke@embecosm.com> in 2010
1977 +;; This file is part of GCC.
1979 +;; GCC is free software; you can redistribute it and/or modify
1980 +;; it under the terms of the GNU General Public License as published by
1981 +;; the Free Software Foundation; either version 3, or (at your option)
1982 +;; any later version.
1984 +;; GCC is distributed in the hope that it will be useful,
1985 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1986 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1987 +;; GNU General Public License for more details.
1989 +;; You should have received a copy of the GNU General Public License
1990 +;; along with GCC; see the file COPYING3. If not see
1991 +;; <http://www.gnu.org/licenses/>.
1993 +(define_constraint "I"
1994 + ""
1995 + (and (match_code "const_int")
1996 + (match_test "ival >= -32768 && ival <= 32767")))
1998 +(define_constraint "J"
1999 + ""
2000 + (and (match_code "const_int")
2001 + (match_test "ival == 0")))
2003 +(define_constraint "K"
2004 + ""
2005 + (and (match_code "const_int")
2006 + (match_test "ival >= 0 && ival <= 65535")))
2008 +(define_constraint "L"
2009 + ""
2010 + (and (match_code "const_int")
2011 + (match_test "ival >= 0 && ival <= 31")))
2013 +(define_constraint "M"
2014 + ""
2015 + (and (match_code "const_int")
2016 + (match_test "(ival & 0xffff) == 0")))
2018 +(define_constraint "N"
2019 + ""
2020 + (and (match_code "const_int")
2021 + (match_test "ival >= -33554432 && ival <= 33554431")))
2023 +(define_constraint "O"
2024 + ""
2025 + (and (match_code "const_int")
2026 + (match_test "ival == 0")))
2028 +(define_constraint "C"
2029 + ""
2030 + (match_code "const_double"))
2032 diff -rNU3 dist.orig/gcc/config/or1k/elf.h dist/gcc/config/or1k/elf.h
2033 --- dist.orig/gcc/config/or1k/elf.h 1970-01-01 01:00:00.000000000 +0100
2034 +++ dist/gcc/config/or1k/elf.h 2015-10-18 13:19:50.000000000 +0200
2035 @@ -0,0 +1,31 @@
2036 +/* Definitions for rtems targeting an OpenRisc OR1K using COFF
2037 + ??? this is for OR1K, but the rest of the above seems bogus.
2038 + Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
2039 + Contributed by Joel Sherrill (joel@OARcorp.com).
2041 +This file is part of GNU CC.
2043 +GNU CC is free software; you can redistribute it and/or modify
2044 +it under the terms of the GNU General Public License as published by
2045 +the Free Software Foundation; either version 2, or (at your option)
2046 +any later version.
2048 +GNU CC is distributed in the hope that it will be useful,
2049 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2050 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2051 +GNU General Public License for more details.
2053 +You should have received a copy of the GNU General Public License
2054 +along with GNU CC; see the file COPYING. If not, write to
2055 +the Free Software Foundation, 59 Temple Place - Suite 330,
2056 +Boston, MA 02111-1307, USA. */
2058 +/* Use ELF */
2059 +#undef OBJECT_FORMAT_ELF
2060 +#define OBJECT_FORMAT_ELF
2062 +/* or1k debug info support is controlled by tm.h header files we include:
2063 + dbxelf.h enables optional stabs debug info.
2064 + elfos.h sets PREFERRED_DEBUGGING_TYPE to DWARF2_DEBUG . */
2066 +#define DRIVER_SELF_SPECS "%{!mno-newlib:-mnewlib}"
2067 diff -rNU3 dist.orig/gcc/config/or1k/linux-elf.h dist/gcc/config/or1k/linux-elf.h
2068 --- dist.orig/gcc/config/or1k/linux-elf.h 1970-01-01 01:00:00.000000000 +0100
2069 +++ dist/gcc/config/or1k/linux-elf.h 2015-10-18 13:19:50.000000000 +0200
2070 @@ -0,0 +1,98 @@
2071 +/* Definitions for or1k running Linux-based GNU systems using ELF
2072 + Copyright (C) 2002, 2005
2073 + Free Software Foundation, Inc.
2074 + Contributed by Marko Mlinar <markom@opencores.org>
2076 +This file is part of GNU CC.
2078 +GNU CC is free software; you can redistribute it and/or modify
2079 +it under the terms of the GNU General Public License as published by
2080 +the Free Software Foundation; either version 2, or (at your option)
2081 +any later version.
2083 +GNU CC is distributed in the hope that it will be useful,
2084 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2085 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2086 +GNU General Public License for more details.
2088 +You should have received a copy of the GNU General Public License
2089 +along with this program; see the file COPYING. If not, write to
2090 +the Free Software Foundation, 59 Temple Place - Suite 330,
2091 +Boston, MA 02111-1307, USA. */
2093 +/* elfos.h should have already been included. Now just override
2094 + any conflicting definitions and add any extras. */
2096 +/* Do not assume anything about header files. */
2097 +#define NO_IMPLICIT_EXTERN_C
2099 +/* This is how we tell the assembler that two symbols have the same value. */
2100 +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
2101 + do \
2102 + { \
2103 + assemble_name (FILE, NAME1); \
2104 + fputs (" = ", FILE); \
2105 + assemble_name (FILE, NAME2); \
2106 + fputc ('\n', FILE); \
2107 + } \
2108 + while (0)
2111 +#if 0
2112 +/* Node: Label Output */
2114 +#define SET_ASM_OP "\t.set\t"
2116 +#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
2117 + (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
2119 +#define ASM_WEAKEN_LABEL(FILE, NAME) \
2120 + do \
2121 + { \
2122 + fputs ("\t.weak\t", (FILE)); \
2123 + assemble_name ((FILE), (NAME)); \
2124 + fputc ('\n', (FILE)); \
2125 + } \
2126 + while (0)
2128 +#endif
2130 +/* The GNU C++ standard library requires that these macros be defined. */
2131 +#undef CPLUSPLUS_CPP_SPEC
2132 +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
2134 +#undef DRIVER_SELF_SPECS
2135 +#define DRIVER_SELF_SPECS ""
2137 +#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
2139 +/* Define a set of Linux builtins. This is copied from linux.h. We can't
2140 + include the whole file for now, because that causes configure to require ld
2141 + to support --eh-frame-header, which it currently doesn't */
2142 +#define LINUX_TARGET_OS_CPP_BUILTINS() \
2143 + do { \
2144 + builtin_define ("__gnu_linux__"); \
2145 + builtin_define_std ("linux"); \
2146 + builtin_define_std ("unix"); \
2147 + builtin_assert ("system=linux"); \
2148 + builtin_assert ("system=unix"); \
2149 + builtin_assert ("system=posix"); \
2150 + } while (0)
2152 +#define TARGET_OS_CPP_BUILTINS() \
2153 + do { \
2154 + LINUX_TARGET_OS_CPP_BUILTINS(); \
2155 + if (OPTION_UCLIBC) \
2156 + builtin_define ("__UCLIBC__"); \
2157 + /* The GNU C++ standard library requires this. */ \
2158 + if (c_dialect_cxx ()) \
2159 + builtin_define ("_GNU_SOURCE"); \
2160 + } while (0)
2162 +#undef LINK_SPEC
2163 +#define LINK_SPEC "%{mnewlib:-entry 0x100} \
2164 + -dynamic-linker " GNU_USER_DYNAMIC_LINKER " \
2165 + %{rdynamic:-export-dynamic} \
2166 + %{static:-static} \
2167 + %{shared:-shared}"
2169 diff -rNU3 dist.orig/gcc/config/or1k/linux-gas.h dist/gcc/config/or1k/linux-gas.h
2170 --- dist.orig/gcc/config/or1k/linux-gas.h 1970-01-01 01:00:00.000000000 +0100
2171 +++ dist/gcc/config/or1k/linux-gas.h 2015-10-18 13:19:50.000000000 +0200
2172 @@ -0,0 +1,37 @@
2173 +/* Definitions of target machine for GNU compiler.
2174 + Or32 Linux-based GNU systems version.
2175 + Copyright (C) 2002, 2005 Free Software Foundation, Inc.
2176 + Contributed by Marko Mlinar <markom@opencores.org>
2178 +This file is part of GNU CC.
2180 +GNU CC is free software; you can redistribute it and/or modify
2181 +it under the terms of the GNU General Public License as published by
2182 +the Free Software Foundation; either version 2, or (at your option)
2183 +any later version.
2185 +GNU CC is distributed in the hope that it will be useful,
2186 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2187 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2188 +GNU General Public License for more details.
2190 +You should have received a copy of the GNU General Public License
2191 +along with this program; see the file COPYING. If not, write to
2192 +the Free Software Foundation, 59 Temple Place - Suite 330,
2193 +Boston, MA 02111-1307, USA. */
2195 +/* Unsigned chars produces much better code than signed. */
2196 +#undef DEFAULT_SIGNED_CHAR
2197 +#define DEFAULT_SIGNED_CHAR 1
2199 +/* Make gcc agree with <machine/ansi.h> */
2201 +#define SIZE_TYPE "unsigned int"
2202 +#define PTRDIFF_TYPE "int"
2203 +#define WCHAR_TYPE "unsigned int"
2204 +#define WCHAR_TYPE_SIZE 32
2207 +/* Clear the instruction cache from `beg' to `end'. This makes an
2208 + inline system call to SYS_cacheflush. */
2209 +#define CLEAR_INSN_CACHE(BEG, END) /* Do something here !!! */
2210 diff -rNU3 dist.orig/gcc/config/or1k/netbsd.h dist/gcc/config/or1k/netbsd.h
2211 --- dist.orig/gcc/config/or1k/netbsd.h 1970-01-01 01:00:00.000000000 +0100
2212 +++ dist/gcc/config/or1k/netbsd.h 2015-10-18 13:19:50.000000000 +0200
2213 @@ -0,0 +1,67 @@
2214 +/* Definitions for or1k running NetBSD systems using ELF
2215 + Copyright (C) 2014
2216 + Free Software Foundation, Inc.
2217 + Contributed by Matt Thomas <matt@netbsd.org>
2219 +This file is part of GNU CC.
2221 +GNU CC is free software; you can redistribute it and/or modify
2222 +it under the terms of the GNU General Public License as published by
2223 +the Free Software Foundation; either version 2, or (at your option)
2224 +any later version.
2226 +GNU CC is distributed in the hope that it will be useful,
2227 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2228 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2229 +GNU General Public License for more details.
2231 +You should have received a copy of the GNU General Public License
2232 +along with this program; see the file COPYING. If not, write to
2233 +the Free Software Foundation, 59 Temple Place - Suite 330,
2234 +Boston, MA 02111-1307, USA. */
2236 +/* This is how we tell the assembler that two symbols have the same value. */
2237 +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
2238 + do \
2239 + { \
2240 + assemble_name (FILE, NAME1); \
2241 + fputs (" = ", FILE); \
2242 + assemble_name (FILE, NAME2); \
2243 + fputc ('\n', FILE); \
2244 + } \
2245 + while (0)
2247 +#undef DRIVER_SELF_SPECS
2248 +#define DRIVER_SELF_SPECS ""
2250 +#define TARGET_OS_CPP_BUILTINS() \
2251 + do { \
2252 + NETBSD_OS_CPP_BUILTINS_ELF(); \
2253 + /* The GNU C++ standard library requires this. */ \
2254 + if (c_dialect_cxx ()) \
2255 + builtin_define ("_GNU_SOURCE"); \
2256 + } while (0)
2258 +#undef CPP_SPEC
2259 +#define CPP_SPEC NETBSD_CPP_SPEC
2261 +#undef LIB_SPEC
2262 +#define LIB_SPEC NETBSD_LIB_SPEC
2264 +#undef LINK_SPEC
2265 +#define LINK_SPEC NETBSD_LINK_SPEC_ELF
2267 +#undef NETBSD_ENTRY_POINT
2268 +#define NETBSD_ENTRY_POINT "_start"
2270 +#undef SUBTARGET_EXTRA_SPECS
2271 +#define SUBTARGET_EXTRA_SPECS \
2272 + { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
2273 + { "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
2274 + { "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
2276 +#undef TARGET_DEFAULT
2277 +#define TARGET_DEFAULT \
2278 + (/*MASK_HARD_FLOAT |*/ MASK_DOUBLE_FLOAT \
2279 + | MASK_HARD_DIV | MASK_HARD_MUL \
2280 + | MASK_MASK_CMOV | MASK_MASK_ROR | MASK_MASK_SEXT)
2281 diff -rNU3 dist.orig/gcc/config/or1k/or1k-modes.def dist/gcc/config/or1k/or1k-modes.def
2282 --- dist.orig/gcc/config/or1k/or1k-modes.def 1970-01-01 01:00:00.000000000 +0100
2283 +++ dist/gcc/config/or1k/or1k-modes.def 2015-10-18 13:19:50.000000000 +0200
2284 @@ -0,0 +1,38 @@
2285 +/* Definitions of target machine for GNU compiler, for OR32.
2286 + Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2288 + This file is part of GCC.
2290 + GCC is free software; you can redistribute it and/or modify it
2291 + under the terms of the GNU General Public License as published
2292 + by the Free Software Foundation; either version 2, or (at your
2293 + option) any later version.
2295 + GCC is distributed in the hope that it will be useful, but WITHOUT
2296 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2297 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
2298 + License for more details.
2300 + You should have received a copy of the GNU General Public License
2301 + along with GCC; see the file COPYING. If not, write to the
2302 + Free Software Foundation, 59 Temple Place - Suite 330, Boston,
2303 + MA 02111-1307, USA. */
2305 +/* Add any extra modes needed to represent the condition code.
2306 + */
2308 +CC_MODE (CCEQ);
2309 +CC_MODE (CCNE);
2311 +CC_MODE (CCLE);
2312 +CC_MODE (CCGE);
2313 +CC_MODE (CCLT);
2314 +CC_MODE (CCGT);
2316 +CC_MODE (CCLEU);
2317 +CC_MODE (CCGEU);
2318 +CC_MODE (CCLTU);
2319 +CC_MODE (CCGTU);
2321 +CC_MODE(CCFP);
2322 +CC_MODE(CCUNS);
2323 diff -rNU3 dist.orig/gcc/config/or1k/or1k-opts.h dist/gcc/config/or1k/or1k-opts.h
2324 --- dist.orig/gcc/config/or1k/or1k-opts.h 1970-01-01 01:00:00.000000000 +0100
2325 +++ dist/gcc/config/or1k/or1k-opts.h 2015-10-18 13:19:50.000000000 +0200
2326 @@ -0,0 +1,14 @@
2327 +#ifndef OR1K_OPTS_H
2328 +#define OR1K_OPTS_H
2330 +enum or1k_delay {
2331 + OR1K_DELAY_OFF = 0,
2332 + OR1K_DELAY_ON = 1,
2333 + OR1K_DELAY_COMPAT = 2
2336 +#define TARGET_DELAY_ON (or1k_delay_selected == OR1K_DELAY_ON)
2337 +#define TARGET_DELAY_OFF (or1k_delay_selected == OR1K_DELAY_OFF)
2338 +#define TARGET_DELAY_COMPAT (or1k_delay_selected == OR1K_DELAY_COMPAT)
2340 +#endif
2341 diff -rNU3 dist.orig/gcc/config/or1k/or1k-protos.h dist/gcc/config/or1k/or1k-protos.h
2342 --- dist.orig/gcc/config/or1k/or1k-protos.h 1970-01-01 01:00:00.000000000 +0100
2343 +++ dist/gcc/config/or1k/or1k-protos.h 2015-10-18 13:19:50.000000000 +0200
2344 @@ -0,0 +1,67 @@
2345 +/* Definitions of target machine for GNU compiler, OR1K cpu.
2347 + Copyright (C) 2010 Embecosm Limited
2349 +This file is part of GCC.
2351 +GCC is free software; you can redistribute it and/or modify
2352 +it under the terms of the GNU General Public License as published by
2353 +the Free Software Foundation; either version 3, or (at your option)
2354 +any later version.
2356 +GCC is distributed in the hope that it will be useful,
2357 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2358 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2359 +GNU General Public License for more details.
2361 +You should have received a copy of the GNU General Public License
2362 +along with GCC; see the file COPYING3. If not see
2363 +<http://www.gnu.org/licenses/>. */
2365 +#ifndef GCC_OR1K_PROTOS_H
2366 +#define GCC_OR1K_PROTOS_H
2368 +/* The following are for general support. */
2369 +extern int or1k_trampoline_code_size (void);
2371 +/* The following are only needed when handling the machine definition. */
2372 +#ifdef RTX_CODE
2373 +extern void or1k_init_expanders (void);
2374 +extern void or1k_expand_prologue (void);
2375 +extern void or1k_expand_epilogue (void);
2376 +extern bool or1k_expand_move (enum machine_mode mode, rtx operands[]);
2377 +extern const char *or1k_output_move_double (rtx *operands);
2378 +extern void or1k_expand_conditional_branch (rtx *operands,
2379 + enum machine_mode mode);
2380 +extern int or1k_emit_cmove (rtx dest,
2381 + rtx op,
2382 + rtx true_cond,
2383 + rtx false_cond);
2384 +extern enum machine_mode or1k_select_cc_mode (enum rtx_code op);
2385 +extern const char *or1k_output_bf (rtx * operands);
2386 +extern const char *or1k_output_cmov (rtx * operands);
2387 +extern void or1k_emit_set_const32 (rtx op0,
2388 + rtx op1);
2389 +extern bool or1k_expand_symbol_ref (enum machine_mode mode,
2390 + rtx operands[]);
2391 +extern void or1k_expand_cmpxchg_qihi (rtx bval, rtx retval,
2392 + rtx mem, rtx oldval, rtx newval, int is_weak,
2393 + enum memmodel success_mode, enum memmodel failure_mode);
2394 +extern void or1k_expand_fetch_op_qihi (rtx oldval, rtx mem, rtx operand,
2395 + rtx newval, rtx (*generator)(rtx, rtx, rtx, rtx, rtx));
2396 +#endif
2398 +#endif
2399 +extern int or1k_struct_alignment (tree);
2400 +extern int or1k_data_alignment (tree, int);
2402 +extern int or1k_initial_elimination_offset (int, int);
2403 +extern bool or1k_save_reg_p_cached (int regno);
2404 +extern void or1k_print_jump_restore (rtx jump_address);
2405 +extern rtx or1k_eh_return_handler_rtx (void);
2406 +extern rtx or1k_return_addr_rtx (int, rtx);
2408 +extern int or1k_legitimate_pic_operand_p (rtx x);
2410 +/* For RETURN_ADDR_RTX */
2411 +extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int);
2412 diff -rNU3 dist.orig/gcc/config/or1k/or1k.c dist/gcc/config/or1k/or1k.c
2413 --- dist.orig/gcc/config/or1k/or1k.c 1970-01-01 01:00:00.000000000 +0100
2414 +++ dist/gcc/config/or1k/or1k.c 2015-10-18 13:19:50.000000000 +0200
2415 @@ -0,0 +1,2433 @@
2416 +/* Subroutines for insn-output.c for GNU compiler. OpenRISC 1000 version.
2417 + Copyright (C) 1987, 1992, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
2418 + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc
2419 + Copyright (C) 2010 Embecosm Limited
2421 + Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
2422 + Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
2423 + Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecoms.com>
2424 + and Joern Rennecke <joern.rennecke@embecosm.com> in 2010.
2426 + This file is part of GNU CC.
2428 + This program is free software; you can redistribute it and/or modify it
2429 + under the terms of the GNU General Public License as published by the Free
2430 + Software Foundation; either version 3 of the License, or (at your option)
2431 + any later version.
2433 + This program is distributed in the hope that it will be useful, but WITHOUT
2434 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2435 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
2436 + more details.
2438 + You should have received a copy of the GNU General Public License along
2439 + with this program. If not, see <http://www.gnu.org/licenses/>. */
2441 +#include "config.h"
2442 +#include "system.h"
2443 +#include "coretypes.h"
2444 +#include "tm.h"
2445 +#include "rtl.h"
2446 +#include "tree.h"
2447 +//#include "calls.h"
2448 +//#include "varasm.h"
2449 +//#include "obstack.h"
2450 +#include "regs.h"
2451 +#include "hard-reg-set.h"
2452 +#include "real.h"
2453 +#include "insn-config.h"
2454 +#include "conditions.h"
2455 +#include "output.h"
2456 +#include "insn-attr.h"
2457 +#include "flags.h"
2458 +#include "reload.h"
2459 +#include "function.h"
2460 +#include "expr.h"
2461 +#include "toplev.h"
2462 +#include "recog.h"
2463 +#include "ggc.h"
2464 +#include "except.h"
2465 +#include "tm_p.h"
2466 +#include "target.h"
2467 +#include "target-def.h"
2468 +#include "debug.h"
2469 +#include "langhooks.h"
2470 +#include "df.h"
2471 +#include "dwarf2.h"
2472 +#include "ansidecl.h"
2474 +/* ========================================================================== */
2475 +/* Local macros */
2477 +/* Construct a l.movhi instruction for the given reg and value */
2478 +#define OR1K_MOVHI(rd, k) \
2479 + ((0x6 << 26) | ((rd) << 21) | (k))
2481 +/* Construct a l.ori instruction for the given two regs and value */
2482 +#define OR1K_ORI(rd, ra, k) \
2483 + ((0x2a << 26) | ((rd) << 21) | ((ra) << 16) | (k))
2485 +/* Construct a l.lwz instruction for the given two registers and offset */
2486 +#define OR1K_LWZ(rd, ra, i) \
2487 + ((0x21 << 26) | ((rd) << 21) | ((ra) << 16) | (i))
2489 +/* Construct a l.jr instruction for the given register */
2490 +#define OR1K_JR(rb) \
2491 + ((0x11 << 26) | ((rb) << 11))
2493 +#define OR1K_NOP \
2494 + (0x15 << 24)
2496 +/* ========================================================================== */
2497 +/* Static variables (i.e. global to this file only. */
2500 +/*!Stack layout we use for pushing and poping saved registers */
2501 +static struct
2503 + bool save_lr_p;
2504 + int lr_save_offset;
2505 + bool save_fp_p;
2506 + int fp_save_offset;
2507 + int gpr_size;
2508 + int gpr_offset;
2509 + int total_size;
2510 + int vars_size;
2511 + int args_size;
2512 + int gpr_frame;
2513 + int late_frame;
2514 + HOST_WIDE_INT mask;
2515 +} frame_info;
2518 +/* ========================================================================== */
2519 +/* Local (i.e. static) utility functions */
2521 +/* -------------------------------------------------------------------------- */
2522 +/*!Must the current function save a register?
2524 + @param[in] regno The register to consider.
2526 + @return Non-zero (TRUE) if current function must save "regno", zero
2527 + (FALSE) otherwise. */
2528 +/* -------------------------------------------------------------------------- */
2529 +static bool
2530 +or1k_save_reg_p (int regno)
2532 + /* No need to save the faked cc0 register. */
2533 + if (regno == OR1K_FLAGS_REG)
2534 + return false;
2536 + /* Check call-saved registers. */
2537 + if (df_regs_ever_live_p(regno) && !call_used_regs[regno])
2538 + return true;
2540 + /* We need to save the old frame pointer before setting up a new
2541 + one. */
2542 + if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
2543 + return true;
2545 + /* Save the stack pointer for DWARF2 for now.
2546 + * AFAIK, DWARF should be able to unwind using only the current stack
2547 + * register and the CFA offset, but I never got that to work. */
2548 + if (regno == STACK_POINTER_REGNUM && !frame_pointer_needed)
2549 + return true;
2551 + /* We need to save the incoming return address if it is ever clobbered
2552 + within the function. */
2553 + if (regno == LINK_REGNUM
2554 + && (df_regs_ever_live_p(regno) || crtl->uses_pic_offset_table
2555 + || cfun->machine->force_lr_save))
2556 + return true;
2558 + if(crtl->calls_eh_return)
2560 + unsigned int i;
2561 + for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
2563 + if ((unsigned int)regno == EH_RETURN_DATA_REGNO (i))
2564 + return true;
2568 + return false;
2570 +} /* or1k_save_reg_p () */
2572 +bool
2573 +or1k_save_reg_p_cached (int regno)
2575 + return (frame_info.mask & ((HOST_WIDE_INT) 1 << regno)) != 0;
2578 +/* N.B. contrary to the ISA documentation, the stack includes the outgoing
2579 + arguments. */
2580 +/* -------------------------------------------------------------------------- */
2581 +/*!Compute full frame size and layout.
2583 + Store information in "frame_info".
2585 + @param[in] size The size of the function's local variables.
2587 + @return Total size of stack frame. */
2588 +/* -------------------------------------------------------------------------- */
2589 +static HOST_WIDE_INT
2590 +or1k_compute_frame_size (HOST_WIDE_INT size)
2592 + HOST_WIDE_INT args_size;
2593 + HOST_WIDE_INT vars_size;
2594 + HOST_WIDE_INT stack_offset;
2595 + HOST_WIDE_INT save_size;
2596 + bool interrupt_p = false;
2597 + int regno;
2599 + args_size = crtl->outgoing_args_size;
2600 + vars_size = OR1K_ALIGN (size, 4);
2602 + frame_info.args_size = args_size;
2603 + frame_info.vars_size = vars_size;
2604 + frame_info.gpr_frame = interrupt_p ? or1k_redzone : 0;
2606 + /* If the function has local variables, we're committed to
2607 + allocating it anyway. Otherwise reclaim it here. */
2608 + /* FIXME: Verify this. Got if from the MIPS port. */
2609 + if (vars_size == 0 && crtl->is_leaf)
2610 + args_size = 0;
2612 + stack_offset = 0;
2614 + /* Save link register right at the bottom. */
2615 + if (or1k_save_reg_p (LINK_REGNUM))
2617 + stack_offset = stack_offset - UNITS_PER_WORD;
2618 + frame_info.lr_save_offset = stack_offset;
2619 + frame_info.save_lr_p = true;
2621 + else
2622 + frame_info.save_lr_p = false;
2624 + /* HACK: In PIC mode we need to save the PIC reg and the link reg in
2625 + in case the function is doing references through the got or plt,
2626 + but this information is not necessarily available when the initial
2627 + elimination offset is calculated, so we always reserve the space even
2628 + if it is not used... */
2629 + if (!frame_info.save_lr_p && flag_pic)
2630 + stack_offset = stack_offset - UNITS_PER_WORD;
2632 + /* Save frame pointer right after possible link register. */
2633 + if (frame_pointer_needed)
2635 + stack_offset = stack_offset - UNITS_PER_WORD;
2636 + frame_info.fp_save_offset = stack_offset;
2637 + frame_info.save_fp_p = true;
2639 + else
2640 + frame_info.save_fp_p = false;
2642 + frame_info.gpr_size = 0;
2643 + frame_info.mask = 0;
2645 + for (regno = 0; regno <= OR1K_LAST_ACTUAL_REG; regno++)
2647 + if (regno == LINK_REGNUM
2648 + || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM))
2649 + /* These have already been saved if so needed. */
2650 + continue;
2652 + if (or1k_save_reg_p (regno))
2654 + frame_info.gpr_size += UNITS_PER_WORD;
2655 + frame_info.mask |= ((HOST_WIDE_INT) 1 << regno);
2659 + if (!or1k_save_reg_p (PIC_OFFSET_TABLE_REGNUM)
2660 + && (crtl->uses_pic_offset_table || (flag_pic && frame_info.save_lr_p)))
2662 + frame_info.gpr_size += UNITS_PER_WORD;
2663 + frame_info.mask |= ((HOST_WIDE_INT) 1 << PIC_OFFSET_TABLE_REGNUM);
2665 + else if (flag_pic && !or1k_save_reg_p (PIC_OFFSET_TABLE_REGNUM))
2666 + frame_info.gpr_size += UNITS_PER_WORD;
2668 + save_size = (frame_info.gpr_size
2669 + + (frame_info.save_fp_p ? UNITS_PER_WORD : 0)
2670 + + (frame_info.save_lr_p || flag_pic ? UNITS_PER_WORD : 0));
2671 + frame_info.total_size = save_size + vars_size + args_size;
2672 + gcc_assert (PROLOGUE_TMP != STATIC_CHAIN_REGNUM);
2673 + if (frame_info.total_size > 32767 && interrupt_p)
2675 + int n_extra
2676 + = (!!(~frame_info.mask && 1 << PROLOGUE_TMP)
2677 + + !!(~frame_info.mask & 1 << EPILOGUE_TMP)) * UNITS_PER_WORD;
2679 + save_size += n_extra;
2680 + frame_info.gpr_size += n_extra;
2681 + frame_info.total_size += n_extra;
2682 + frame_info.mask |= (1 << PROLOGUE_TMP) | (1 << EPILOGUE_TMP);
2685 + stack_offset -= frame_info.gpr_size;
2686 + frame_info.gpr_offset = stack_offset;
2687 + frame_info.late_frame = frame_info.total_size;
2689 + if (save_size > or1k_redzone
2690 + || (frame_info.gpr_frame
2691 + && (frame_info.gpr_frame + frame_info.late_frame <= 32767)))
2693 + if (frame_info.gpr_frame + frame_info.late_frame <= 32767)
2694 + save_size = frame_info.total_size;
2695 + frame_info.gpr_frame += save_size;
2696 + frame_info.lr_save_offset += save_size;
2697 + frame_info.fp_save_offset += save_size;
2698 + frame_info.gpr_offset += save_size;
2699 + frame_info.late_frame -= save_size;
2700 + /* FIXME: check in TARGET_OVERRIDE_OPTIONS for invalid or1k_redzone. */
2701 + gcc_assert (frame_info.gpr_frame <= 32767);
2702 + gcc_assert ((frame_info.gpr_frame & 3) == 0);
2705 + return frame_info.total_size;
2707 +} /* or1k_compute_frame_size () */
2710 +/* -------------------------------------------------------------------------- */
2711 +/*!Emit a frame related insn.
2713 + Same as emit_insn, but sets RTX_FRAME_RELATED_P to one. Getting this right
2714 + will matter for DWARF 2 output, if prologues are handled via the "prologue"
2715 + pattern rather than target hooks.
2717 + @param[in] insn The insn to emit.
2719 + @return The RTX for the emitted insn. */
2720 +/* -------------------------------------------------------------------------- */
2721 +static rtx
2722 +emit_frame_insn (rtx insn)
2724 + insn = emit_insn (insn);
2725 + RTX_FRAME_RELATED_P (insn) = 1;
2726 + return (insn);
2728 +} /* emit_frame_insn () */
2731 +/* -------------------------------------------------------------------------- */
2732 +/* Generate a RTX for the indexed memory address based on stack_pointer_rtx
2733 + and a displacement
2735 + @param[in] disp The displacement
2737 + @return The RTX for the generated address. */
2738 +/* -------------------------------------------------------------------------- */
2739 +static rtx
2740 +stack_disp_mem (HOST_WIDE_INT disp)
2742 + return gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx, disp));
2745 +enum machine_mode
2746 +or1k_select_cc_mode (enum rtx_code op)
2748 + switch (op) {
2749 + case EQ: return CCEQmode;
2750 + case NE: return CCNEmode;
2751 + case GEU: return CCGEUmode;
2752 + case GTU: return CCGTUmode;
2753 + case LTU: return CCLTUmode;
2754 + case LEU: return CCLEUmode;
2755 + case GE: return CCGEmode;
2756 + case LT: return CCLTmode;
2757 + case GT: return CCGTmode;
2758 + case LE: return CCLEmode;
2759 + default: gcc_unreachable ();
2763 +/* -------------------------------------------------------------------------- */
2764 +/*!Generate insn patterns to do an integer compare of operands.
2766 + @param[in] code RTX for the condition code.
2767 + @param[in] op0 RTX for the first operand.
2768 + @param[in] op1 RTX for the second operand.
2770 + @return RTX for the comparison. */
2771 +/* -------------------------------------------------------------------------- */
2772 +static rtx
2773 +or1k_expand_int_compare (enum rtx_code code,
2774 + rtx op0,
2775 + rtx op1)
2777 + enum machine_mode cmpmode;
2778 + rtx tmp, flags;
2780 + cmpmode = or1k_select_cc_mode (code);
2781 + flags = gen_rtx_REG (cmpmode, OR1K_FLAGS_REG);
2783 + /* This is very simple, but making the interface the same as in the
2784 + FP case makes the rest of the code easier. */
2785 + tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
2786 + emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
2788 + /* Return the test that should be put into the flags user, i.e.
2789 + the bcc, scc, or cmov instruction. */
2790 + return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
2792 +} /* or1k_expand_int_compare () */
2795 +/* -------------------------------------------------------------------------- */
2796 +/*!Generate insn patterns to do an integer compare of operands.
2798 + We only deal with the case where the comparison is an integer
2799 + comparison. This wrapper function potentially allows reuse for non-integer
2800 + comparison in the future.
2802 + @param[in] code RTX for the condition code.
2803 + @param[in] op0 RTX for the first operand.
2804 + @param[in] op1 RTX for the second operand.
2806 + @return RTX for the comparison. */
2807 +/* -------------------------------------------------------------------------- */
2808 +static rtx
2809 +or1k_expand_compare (enum rtx_code code, rtx op0, rtx op1)
2811 + return or1k_expand_int_compare (code, op0, op1);
2813 +} /* or1k_expand_compare () */
2816 +/* TODO(bluecmd): Write documentation for this function */
2817 +void
2818 +or1k_expand_cmpxchg_qihi (rtx bval, rtx retval, rtx mem, rtx oldval, rtx newval,
2819 + int is_weak, enum memmodel success_mode,
2820 + enum memmodel failure_mode)
2822 + rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
2823 + rtx addr = gen_reg_rtx (Pmode);
2824 + rtx off = gen_reg_rtx (SImode);
2825 + rtx shifter = gen_reg_rtx (SImode);
2826 + rtx retword = gen_reg_rtx (SImode);
2827 + rtx mask = gen_reg_rtx (SImode);
2828 + rtx shifted_oldval = gen_reg_rtx (SImode);
2829 + rtx shifted_newval = gen_reg_rtx (SImode);
2830 + rtx shifted_mask = gen_reg_rtx (SImode);
2831 + rtx mask_const;
2832 + rtx memsi;
2833 + enum machine_mode mode = GET_MODE (mem);
2835 + oldval = gen_lowpart_common (SImode, oldval);
2836 + newval = gen_lowpart_common (SImode, newval);
2838 + mask_const = gen_rtx_CONST_INT (VOIDmode,
2839 + mode == QImode ? 0xff : 0xffff);
2840 + emit_insn (gen_rtx_SET (VOIDmode, mask, mask_const));
2842 + /* align address and retrieve the offset. */
2843 + emit_insn (gen_rtx_SET (VOIDmode, addr,
2844 + gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
2845 + emit_insn (gen_rtx_SET (VOIDmode, off,
2846 + gen_rtx_AND (SImode, addr1, GEN_INT (3))));
2847 + emit_insn (gen_rtx_SET (VOIDmode, off,
2848 + gen_rtx_XOR (SImode, off,
2849 + GEN_INT (GET_MODE (mem) == QImode
2850 + ? 3 : 2))));
2852 + memsi = gen_rtx_MEM (SImode, addr);
2854 + /* shift all arguments to be aligned to where the data we want
2855 + * to operate on is located. */
2856 + emit_insn (gen_rtx_SET (VOIDmode, shifter,
2857 + gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
2859 + emit_insn (gen_ashlsi3 (shifted_oldval, oldval, shifter));
2860 + emit_insn (gen_ashlsi3 (shifted_newval, newval, shifter));
2861 + emit_insn (gen_ashlsi3 (shifted_mask, mask, shifter));
2863 + emit_insn (gen_cmpxchg_mask (bval, retword, memsi, shifted_oldval,
2864 + shifted_newval, shifted_mask));
2866 + /* shift the data we care about to the lower end. */
2867 + emit_insn (gen_lshrsi3 (retword, retword, shifter));
2869 + emit_move_insn (retval, gen_lowpart (GET_MODE (retval), retword));
2872 +/* TODO(bluecmd): Write documentation for this function */
2873 +void
2874 +or1k_expand_fetch_op_qihi (rtx oldval, rtx mem, rtx operand, rtx newval,
2875 + rtx (*generator)(rtx, rtx, rtx, rtx, rtx))
2877 + rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
2878 + rtx addr = gen_reg_rtx (Pmode);
2879 + rtx off = gen_reg_rtx (SImode);
2880 + rtx shifter = gen_reg_rtx (SImode);
2881 + rtx mask = gen_reg_rtx (SImode);
2882 + rtx shifted_oldval = gen_reg_rtx (SImode);
2883 + rtx shifted_newval = gen_reg_rtx (SImode);
2884 + rtx shifted_operand = gen_reg_rtx (SImode);
2885 + rtx shifted_mask = gen_reg_rtx (SImode);
2886 + rtx mask_const;
2887 + rtx memsi;
2888 + enum machine_mode mode = GET_MODE (mem);
2890 + /* TODO(bluecmd): A lot of code is shared between cmpxchg and this. We should
2891 + * move it to nice functions. */
2892 + operand = gen_lowpart_common (SImode, operand);
2894 + mask_const = gen_rtx_CONST_INT (VOIDmode,
2895 + mode == QImode ? 0xff : 0xffff);
2896 + emit_insn (gen_rtx_SET (VOIDmode, mask, mask_const));
2898 + /* align address and retrieve the offset. */
2899 + emit_insn (gen_rtx_SET (VOIDmode, addr,
2900 + gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
2901 + emit_insn (gen_rtx_SET (VOIDmode, off,
2902 + gen_rtx_AND (SImode, addr1, GEN_INT (3))));
2903 + emit_insn (gen_rtx_SET (VOIDmode, off,
2904 + gen_rtx_XOR (SImode, off,
2905 + GEN_INT (GET_MODE (mem) == QImode
2906 + ? 3 : 2))));
2908 + memsi = gen_rtx_MEM (SImode, addr);
2910 + /* shift all arguments to be aligned to where the data we want
2911 + * to operate on is located. */
2912 + emit_insn (gen_rtx_SET (VOIDmode, shifter,
2913 + gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
2915 + emit_insn (gen_ashlsi3 (shifted_operand, operand, shifter));
2916 + emit_insn (gen_ashlsi3 (shifted_mask, mask, shifter));
2918 + emit_insn (generator (shifted_oldval, memsi, shifted_operand,
2919 + shifted_newval, shifted_mask));
2921 + /* shift the data we care about to the lower end. */
2922 + emit_insn (gen_lshrsi3 (shifted_oldval, shifted_oldval, shifter));
2923 + emit_insn (gen_lshrsi3 (shifted_newval, shifted_newval, shifter));
2924 + emit_move_insn (oldval, gen_lowpart (GET_MODE (oldval), shifted_oldval));
2925 + emit_move_insn (newval, gen_lowpart (GET_MODE (newval), shifted_newval));
2928 +/* -------------------------------------------------------------------------- */
2929 +/*!Emit insns to use the l.cmov instruction
2931 + Emit a compare and then cmov. Only works for integer first operand.
2933 + @param[in] dest RTX for the destination operand.
2934 + @param[in] op RTX for the comparison operation
2935 + @param[in] true_cond RTX to move to dest if condition is TRUE.
2936 + @param[in] false_cond RTX to move to dest if condition is FALSE.
2938 + @return Non-zero (TRUE) if insns were emitted, zero (FALSE) otherwise. */
2939 +/* -------------------------------------------------------------------------- */
2940 +static int
2941 +or1k_emit_int_cmove (rtx dest,
2942 + rtx op,
2943 + rtx true_cond,
2944 + rtx false_cond)
2946 + rtx condition_rtx, cr;
2947 + rtx op0 = XEXP (op, 0);
2948 + rtx op1 = XEXP (op, 1);
2950 + if ((GET_MODE (op0) != SImode) &&
2951 + (GET_MODE (op0) != HImode) &&
2952 + (GET_MODE (op0) != QImode))
2954 + return 0;
2957 + /* We still have to do the compare, because cmov doesn't do a compare, it
2958 + just looks at the FLAG bit set by a previous compare instruction. */
2959 + condition_rtx = or1k_expand_compare (GET_CODE (op), op0, op1);
2961 + cr = XEXP (condition_rtx, 0);
2963 + emit_insn (gen_cmov (dest, condition_rtx, true_cond, false_cond, cr));
2965 + return 1;
2967 +} /* or1k_emit_int_cmove () */
2970 +static void
2971 +or1k_print_operand_address (FILE *stream, rtx addr)
2973 + rtx offset;
2975 + switch (GET_CODE (addr))
2977 + case MEM:
2978 + if (GET_CODE (XEXP (addr, 0)) == REG)
2979 + fprintf (stream, "%s", reg_names[REGNO (addr)]);
2980 + else
2981 + abort ();
2982 + break;
2984 + case REG:
2985 + fprintf (stream, "0(%s)", reg_names[REGNO (addr)]);
2986 + break;
2988 + case PLUS:
2989 + offset = 0;
2991 + if (GET_CODE (XEXP (addr, 0)) == REG)
2993 + offset = XEXP (addr, 1);
2994 + addr = XEXP (addr, 0);
2996 + else if (GET_CODE (XEXP (addr, 1)) == REG)
2998 + offset = XEXP (addr, 0);
2999 + addr = XEXP (addr, 1);
3001 + output_address (offset);
3002 + fprintf (stream, "(%s)", reg_names[REGNO (addr)]);
3003 + break;
3005 + case SYMBOL_REF:
3006 + if (SYMBOL_REF_DECL (addr))
3007 + assemble_external (SYMBOL_REF_DECL (addr));
3009 + if (XSTR (addr, 0)[0] == '*')
3010 + fputs (&XSTR (addr, 0)[1], stream);
3011 + else
3013 + asm_fprintf (stream, "%U%s", XSTR (addr, 0));
3015 + break;
3017 + default:
3018 + output_addr_const (stream, addr);
3022 +/* -------------------------------------------------------------------------- */
3023 +/*!Is this a value suitable for an OR1K address displacement?
3025 + Must be an integer (signed) which fits into 16-bits. If the result is a
3026 + double word, we had better also check that we can also get at the second
3027 + word.
3029 + @param[in] mode Mode of the result for which this displacement will be
3030 + used.
3031 + @param[in] x RTX for an expression.
3033 + @return Non-zero (TRUE) if this is a valid 16-bit offset, zero (FALSE)
3034 + otherwise. */
3035 +/* -------------------------------------------------------------------------- */
3036 +static int
3037 +or1k_legitimate_displacement_p (enum machine_mode mode,
3038 + rtx x)
3040 + if (CONST_INT == GET_CODE(x))
3042 + HOST_WIDE_INT disp = INTVAL (x);
3044 + /* Allow for a second access 4 bytes further on if double. */
3045 + if ((DFmode == mode) || (DImode == mode))
3047 + return (-32768 < disp) && (disp <= 32763);
3049 + else
3051 + return (-32768 < disp) && (disp <= 32767);
3054 + else
3056 + return 0;
3058 +} /* or1k_legitimate_displacement_p () */
3061 +/* -------------------------------------------------------------------------- */
3062 +/*!Can this register be used as a base register?
3064 + We need a strict version, for which the register must either be a hard
3065 + register, or already renumbered to a hard register.
3067 + For the non-strict version, any register (other than the flag register will
3068 + do).
3070 + @todo The code from the old port does not allow r0 as a base when strict,
3071 + and does when non-strict. Surely it is always a valid register?
3073 + @param[in] regno The register to test
3074 + @param[in] strict Non-zero (TRUE) if this is a strict check, zero (FALSE)
3075 + otherwise.
3077 + @return Non-zero (TRUE) if this register can be used as a base register,
3078 + zero (FALSE) otherwise. */
3079 +/* -------------------------------------------------------------------------- */
3080 +static bool
3081 +or1k_regnum_ok_for_base_p (HOST_WIDE_INT num,
3082 + bool strict)
3084 + if (strict)
3086 + return (num < FIRST_PSEUDO_REGISTER)
3087 + ? (num > 0) && (num <= OR1K_LAST_INT_REG)
3088 + : (reg_renumber[num] > 0) && (reg_renumber[num] <= OR1K_LAST_INT_REG);
3090 + else
3092 + return (num <= OR1K_LAST_INT_REG) || (num >= FIRST_PSEUDO_REGISTER);
3094 +} /* or1k_regnum_ok_for_base_p () */
3096 +int
3097 +or1k_legitimate_pic_operand_p (rtx x)
3099 + if (GET_CODE (x) == CONST
3100 + && GET_CODE (XEXP (x, 0)) == PLUS
3101 + && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
3102 + && (!SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0))
3103 + || SYMBOL_REF_WEAK (XEXP (XEXP (x, 0), 0))))
3104 + || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
3105 + && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
3106 + return or1k_legitimate_displacement_p (SImode, XEXP (XEXP (x, 0), 1));
3108 + return 1;
3111 +static bool
3112 +or1k_expand_pic_symbol_ref (enum machine_mode mode ATTRIBUTE_UNUSED,
3113 + rtx operands[])
3115 + if (GET_CODE (operands[1]) == LABEL_REF
3116 + || (GET_CODE (operands[1]) == SYMBOL_REF
3117 + && SYMBOL_REF_LOCAL_P (operands[1])
3118 + && !SYMBOL_REF_WEAK (operands[1])))
3120 + crtl->uses_pic_offset_table = 1;
3121 + emit_insn (gen_movsi_gotoffhi (operands[0], operands[1]));
3122 + emit_insn (gen_movsi_gotofflo (operands[0], operands[0],
3123 + operands[1]));
3124 + emit_insn (gen_add3_insn(operands[0], operands[0],
3125 + pic_offset_table_rtx));
3126 + return true;
3128 + else if (GET_CODE (operands[1]) == SYMBOL_REF)
3130 + crtl->uses_pic_offset_table = 1;
3131 + emit_insn (gen_movsi_got (operands[0], operands[1]));
3132 + return true;
3134 + else if (GET_CODE (operands[1]) == CONST
3135 + && GET_CODE (XEXP (operands[1], 0)) == PLUS
3136 + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
3137 + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
3139 + rtx symbolref = XEXP (XEXP (operands[1], 0), 0);
3140 + crtl->uses_pic_offset_table = 1;
3142 + if (SYMBOL_REF_LOCAL_P (symbolref)
3143 + && !SYMBOL_REF_WEAK (symbolref))
3145 + emit_insn (gen_movsi_gotoffhi (operands[0], operands[1]));
3146 + emit_insn (gen_movsi_gotofflo (operands[0], operands[0],
3147 + operands[1]));
3148 + emit_insn (gen_add3_insn(operands[0], operands[0],
3149 + pic_offset_table_rtx));
3151 + else
3153 + rtx const_int = XEXP (XEXP (operands[1], 0), 1);
3155 + /* Expand the constant into a register if it doesn't
3156 + fit directly as an 16-bit immediate in the add below.
3157 + Note that the reg allocation is allowed here since
3158 + we are guarded by LEGITIMATE_PIC_OPERAND_P. */
3159 + if (!or1k_legitimate_displacement_p (mode, const_int))
3161 + rtx scratch = gen_reg_rtx (mode);
3163 + or1k_emit_set_const32 (scratch, const_int);
3164 + const_int = scratch;
3167 + emit_insn (gen_movsi_got (operands[0], symbolref));
3168 + emit_insn (gen_add3_insn(operands[0], operands[0], const_int));
3170 + return true;
3172 + return false;
3175 +/* Return the TLS type for TLS symbols, 0 otherwise. */
3176 +enum tls_model
3177 +or1k_tls_symbolic_operand (rtx op)
3179 + if (GET_CODE (op) == CONST)
3181 + rtx sym, addend;
3182 + split_const (op, &sym, &addend);
3183 + if (GET_CODE (sym) == SYMBOL_REF)
3184 + return SYMBOL_REF_TLS_MODEL (sym);
3186 + else if (GET_CODE (op) == SYMBOL_REF)
3187 + return SYMBOL_REF_TLS_MODEL (op);
3189 + return TLS_MODEL_NONE;
3192 +static GTY(()) rtx gen_tls_tga;
3194 +/* Get reference to the '__tls_get_addr' symbol */
3195 +static rtx
3196 +gen_tls_get_addr (void)
3198 + if (!gen_tls_tga)
3199 + gen_tls_tga = init_one_libfunc ("__tls_get_addr");
3200 + return gen_tls_tga;
3203 +/* Emit call to '__tls_get_addr' */
3204 +static void
3205 +or1k_tls_call (rtx dest, rtx arg)
3207 + emit_library_call_value (gen_tls_get_addr(), dest,
3208 + LCT_CONST, Pmode, 1, arg, Pmode);
3211 +static rtx
3212 +or1k_legitimize_tls_address (rtx dest, rtx x)
3214 + rtx sym;
3215 + rtx tp = gen_rtx_REG(Pmode, THREAD_PTR_REGNUM);
3216 + rtx addend = NULL_RTX;
3217 + rtx result = dest;
3219 + enum tls_model tls_kind = or1k_tls_symbolic_operand (x);
3221 + if (GET_CODE (x) == SYMBOL_REF)
3222 + sym = gen_rtx_SYMBOL_REF(Pmode, XSTR(x, 0));
3223 + else if (GET_CODE (x) == CONST)
3225 + result = gen_reg_rtx (Pmode);
3226 + split_const (x, &sym, &addend);
3227 + sym = gen_rtx_SYMBOL_REF(Pmode, XSTR(sym, 0));
3229 + else
3230 + gcc_unreachable ();
3232 + switch (tls_kind) {
3233 + case TLS_MODEL_GLOBAL_DYNAMIC:
3234 + case TLS_MODEL_LOCAL_DYNAMIC:
3236 + /* TODO: For now, treat LD as GD */
3237 + rtx hi = gen_reg_rtx (Pmode);
3238 + rtx offset = gen_reg_rtx (Pmode);
3239 + rtx addr = gen_reg_rtx (Pmode);
3240 + crtl->uses_pic_offset_table = 1;
3241 + /* Generate a new symbol ref that is not marked as TLS or we will recurse
3242 + * in or1k_legitimate_constant_p. */
3243 + emit_insn (gen_movsi_tlsgdhi (hi, sym));
3244 + emit_insn (gen_movsi_tlsgdlo (offset, hi, sym));
3245 + emit_insn (gen_add3_insn (addr, offset, pic_offset_table_rtx));
3246 + or1k_tls_call (result, addr);
3247 + break;
3249 + case TLS_MODEL_INITIAL_EXEC:
3251 + rtx hi = gen_reg_rtx (Pmode);
3252 + rtx offset = gen_reg_rtx (Pmode);
3253 + rtx addr = gen_reg_rtx (Pmode);
3254 + rtx tpoffset = gen_reg_rtx (Pmode);
3255 + crtl->uses_pic_offset_table = 1;
3256 + emit_insn (gen_movsi_gottpoffhi (hi, sym));
3257 + emit_insn (gen_movsi_gottpofflo (offset, hi, sym));
3258 + emit_insn (gen_add3_insn (addr, offset, pic_offset_table_rtx));
3259 + emit_insn (gen_load_gottpoff (tpoffset, addr));
3260 + emit_insn (gen_add3_insn (result, tpoffset, tp));
3261 + break;
3263 + case TLS_MODEL_LOCAL_EXEC:
3265 + rtx hi = gen_reg_rtx (Pmode);
3266 + rtx addr = gen_reg_rtx (Pmode);
3267 + emit_insn (gen_movsi_tpoffhi (hi, sym));
3268 + emit_insn (gen_movsi_tpofflo (addr, hi, sym));
3269 + emit_insn (gen_add3_insn (result, addr, tp));
3270 + break;
3272 + default:
3273 + gcc_unreachable ();
3276 + if (addend != NULL_RTX)
3277 + emit_insn (gen_add3_insn (dest, result, addend));
3279 + return dest;
3282 +static rtx
3283 +or1k_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3284 + enum machine_mode mode ATTRIBUTE_UNUSED)
3286 + if (or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE)
3287 + return or1k_legitimize_tls_address (gen_reg_rtx (Pmode), x);
3289 + return x;
3292 +static bool
3293 +or1k_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
3295 + return or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE;
3298 +bool
3299 +or1k_expand_symbol_ref(enum machine_mode mode, rtx operands[])
3301 + if (flag_pic && or1k_expand_pic_symbol_ref(mode, operands))
3302 + return true;
3304 + return false;
3307 +bool
3308 +or1k_expand_move (enum machine_mode mode, rtx operands[])
3310 + if (can_create_pseudo_p ())
3312 + if (GET_CODE (operands[0]) == MEM
3313 + || (GET_CODE (operands[0]) == SUBREG
3314 + && GET_CODE (SUBREG_REG (operands[0])) == MEM))
3316 + /* Source operand for store must be in a register. */
3317 + operands[1] = force_reg (SImode, operands[1]);
3321 + if (or1k_tls_symbolic_operand (operands[1]) != TLS_MODEL_NONE)
3323 + or1k_legitimize_tls_address (force_reg (Pmode, operands[0]),
3324 + operands[1]);
3325 + return true;
3328 + if (or1k_expand_symbol_ref (mode, operands))
3329 + return true;
3331 + /* Working with CONST_INTs is easier, so convert
3332 + a double if needed. */
3334 + if (GET_CODE (operands[1]) == CONST_DOUBLE) {
3335 + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
3338 + /* Handle sets of MEM first. */
3339 + if (GET_CODE (operands[0]) == MEM)
3341 + if (register_operand(operands[1], SImode)
3342 + || (operands[1] == const0_rtx))
3343 + goto movsi_is_ok;
3345 + if (! reload_in_progress)
3347 + operands[0] = validize_mem (operands[0]);
3348 + operands[1] = force_reg (SImode, operands[1]);
3352 + /* This makes sure we will not get rematched due to splittage. */
3353 + if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
3355 + else if (CONSTANT_P (operands[1])
3356 + && GET_CODE (operands[1]) != HIGH
3357 + && GET_CODE (operands[1]) != LO_SUM)
3359 + or1k_emit_set_const32 (operands[0], operands[1]);
3360 + return true;
3362 + movsi_is_ok:
3365 + return false;
3368 +/* -------------------------------------------------------------------------- */
3369 +/*!Emit a move from SRC to DEST.
3371 + Assume that the move expanders can handle all moves if !can_create_pseudo_p
3372 + (). The distinction is important because, unlike emit_move_insn, the move
3373 + expanders know how to force Pmode objects into the constant pool even when
3374 + the constant pool address is not itself legitimate.
3376 + @param[in] dest Destination of the move.
3377 + @param[in] src Source for the move.
3379 + @return RTX for the move. */
3380 +/* -------------------------------------------------------------------------- */
3381 +static rtx
3382 +or1k_emit_move (rtx dest, rtx src)
3384 + return (can_create_pseudo_p ()
3385 + ? emit_move_insn (dest, src)
3386 + : emit_move_insn_1 (dest, src));
3388 +} /* or1k_emit_move () */
3391 +/* -------------------------------------------------------------------------- */
3392 +/*!Emit an instruction of the form (set TARGET (CODE OP0 OP1)).
3394 + @param[in] code The code for the operation.
3395 + @param[in] target Destination for the set operation.
3396 + @param[in] op0 First operand.
3397 + @param[in] op1 Second operand. */
3398 +/* -------------------------------------------------------------------------- */
3399 +static void
3400 +or1k_emit_binary (enum rtx_code code,
3401 + rtx target,
3402 + rtx op0,
3403 + rtx op1)
3405 + emit_insn (gen_rtx_SET (VOIDmode, target,
3406 + gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
3408 +} /* or1k_emit_binary () */
3411 +/* -------------------------------------------------------------------------- */
3412 +/*!Compute the result of an operation into a new register.
3414 + Compute ("code" "op0" "op1") and store the result in a new register of mode
3415 + "mode".
3417 + @param[in] mode Mode of the result
3418 + @parma[in] code RTX for the operation to perform
3419 + @param[in] op0 RTX for the first operand
3420 + @param[in] op1 RTX for the second operand
3422 + @return The RTX for the new register. */
3423 +/* -------------------------------------------------------------------------- */
3424 +static rtx
3425 +or1k_force_binary (enum machine_mode mode,
3426 + enum rtx_code code,
3427 + rtx op0,
3428 + rtx op1)
3430 + rtx reg;
3432 + reg = gen_reg_rtx (mode);
3433 + or1k_emit_binary (code, reg, op0, op1);
3435 + return reg;
3437 +} /* or1k_force_binary () */
3440 +/* ========================================================================== */
3441 +/* Global support functions */
3443 +static int
3444 +or1k_trampoline_code_words (void)
3446 + int words = 5;
3448 + /* need one more word in TARGET_DELAY_COMPAT mode to hold l.nop in delay slot */
3449 + if (TARGET_DELAY_COMPAT)
3450 + words++;
3452 + return words;
3455 +/* -------------------------------------------------------------------------- */
3456 +/* Return the size in bytes of the trampoline code.
3458 + Padded to TRAMPOLINE_ALIGNMENT bits. The code sequence is documented in
3459 + or1k_trampoline_init ().
3461 + This is just the code size. the static chain pointer and target function
3462 + address immediately follow.
3464 + @return The size of the trampoline code in bytes. */
3465 +/* -------------------------------------------------------------------------- */
3466 +int
3467 +or1k_trampoline_code_size (void)
3469 + const int TRAMP_BYTE_ALIGN = TRAMPOLINE_ALIGNMENT / 8;
3471 + return (or1k_trampoline_code_words() * 4 + TRAMP_BYTE_ALIGN - 1) / TRAMP_BYTE_ALIGN * TRAMP_BYTE_ALIGN;
3473 +} /* or1k_trampoline_code_size () */
3476 +/* ========================================================================== */
3477 +/* Functions to support the Machine Description */
3480 +/* -------------------------------------------------------------------------- */
3481 +/*!Expand a prologue pattern.
3483 + Called after register allocation to add any instructions needed for the
3484 + prologue. Using a prologue insn is favored compared to putting all of the
3485 + instructions in output_function_prologue(), since it allows the scheduler
3486 + to intermix instructions with the saves of the caller saved registers. In
3487 + some cases, it might be necessary to emit a barrier instruction as the last
3488 + insn to prevent such scheduling. */
3489 +/* -------------------------------------------------------------------------- */
3490 +void
3491 +or1k_expand_prologue (void)
3493 + int total_size = or1k_compute_frame_size (get_frame_size ());
3494 + rtx insn;
3496 + if (!total_size)
3497 + /* No frame needed. */
3498 + return;
3500 + gcc_assert (!frame_info.save_lr_p || !frame_info.save_fp_p
3501 + || frame_info.lr_save_offset != frame_info.fp_save_offset);
3503 + if (frame_info.gpr_frame)
3504 + emit_frame_insn (gen_add2_insn (stack_pointer_rtx,
3505 + GEN_INT (-frame_info.gpr_frame)));
3506 + if (frame_info.save_fp_p)
3508 + emit_frame_insn (gen_rtx_SET (Pmode,
3509 + stack_disp_mem (frame_info.fp_save_offset),
3510 + hard_frame_pointer_rtx));
3512 + emit_frame_insn
3513 + (gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx, const0_rtx));
3515 + if (frame_info.save_lr_p)
3517 + emit_frame_insn
3518 + (gen_rtx_SET (Pmode, stack_disp_mem (frame_info.lr_save_offset),
3519 + gen_rtx_REG (Pmode, LINK_REGNUM)));
3521 + if (frame_info.gpr_size)
3523 + int offset = 0;
3524 + int regno;
3526 + for (regno = 0; regno <= OR1K_LAST_ACTUAL_REG; regno++)
3528 + if (!(frame_info.mask & ((HOST_WIDE_INT) 1 << regno)))
3529 + continue;
3531 + /* Check that the offsets aren't stepping on lr/fp slots */
3532 + gcc_assert (!frame_info.save_lr_p
3533 + || ((frame_info.gpr_offset + offset)
3534 + != frame_info.lr_save_offset));
3535 + gcc_assert (!frame_info.save_fp_p
3536 + || ((frame_info.gpr_offset + offset)
3537 + != frame_info.fp_save_offset));
3539 + emit_frame_insn
3540 + (gen_rtx_SET (Pmode,
3541 + stack_disp_mem (frame_info.gpr_offset + offset),
3542 + gen_rtx_REG (Pmode, regno)));
3543 + offset = offset + UNITS_PER_WORD;
3547 + /* Update the stack pointer to reflect frame size. */
3548 + total_size = frame_info.late_frame;
3549 + insn = gen_add2_insn (stack_pointer_rtx, GEN_INT (-total_size));
3550 + if (total_size > 32768)
3552 + rtx note = insn;
3553 + rtx value_rtx = gen_rtx_REG (Pmode, PROLOGUE_TMP);
3555 + or1k_emit_set_const32 (value_rtx, GEN_INT (-total_size));
3556 + if (frame_info.save_fp_p)
3557 + insn = gen_frame_alloc_fp (value_rtx);
3558 + else
3559 + insn = gen_add2_insn (stack_pointer_rtx, value_rtx);
3560 + insn = emit_frame_insn (insn);
3561 + add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
3563 + else if (total_size)
3565 + if (frame_info.save_fp_p)
3566 + emit_frame_insn (gen_frame_alloc_fp (GEN_INT (-total_size)));
3567 + else
3568 + emit_frame_insn (insn);
3570 + /* Emit got pointer acquiring if there are any got references or
3571 + this function has calls */
3572 + if (crtl->uses_pic_offset_table || (flag_pic && frame_info.save_lr_p))
3574 + SET_REGNO (pic_offset_table_rtx, PIC_OFFSET_TABLE_REGNUM);
3575 + emit_insn (gen_set_got (pic_offset_table_rtx));
3578 +} /* or1k_expand_prologue () */
3581 +/* -------------------------------------------------------------------------- */
3582 +/*!Expand an epilogue pattern.
3584 + Called after register allocation to add any instructions needed for the
3585 + epilogue. Using an epilogue insn is favored compared to putting all of the
3586 + instructions in output_function_epilogue(), since it allows the scheduler
3587 + to intermix instructions with the restores of the caller saved registers.
3588 + In some cases, it might be necessary to emit a barrier instruction as the
3589 + first insn to prevent such scheduling. */
3590 +/* -------------------------------------------------------------------------- */
3591 +void
3592 +or1k_expand_epilogue (void)
3594 + int total_size = or1k_compute_frame_size (get_frame_size ());
3596 + if (frame_info.save_fp_p)
3598 + emit_insn (gen_frame_dealloc_fp ());
3599 + emit_insn
3600 + (gen_rtx_SET (Pmode, hard_frame_pointer_rtx,
3601 + stack_disp_mem (frame_info.fp_save_offset)));
3603 + else
3605 + rtx value_rtx;
3607 + total_size = frame_info.late_frame;
3608 + if (total_size > 32767)
3610 + value_rtx = gen_rtx_REG (Pmode, EPILOGUE_TMP);
3611 + or1k_emit_set_const32 (value_rtx, GEN_INT (total_size));
3613 + else if (frame_info.late_frame)
3614 + value_rtx = GEN_INT (total_size);
3615 + if (total_size)
3616 + emit_insn (gen_frame_dealloc_sp (value_rtx));
3619 + /* eh_return sets the LR, do not overwrite it */
3620 + if (frame_info.save_lr_p && !crtl->calls_eh_return)
3622 + emit_insn
3623 + (gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, LINK_REGNUM),
3624 + stack_disp_mem (frame_info.lr_save_offset)));
3627 + if (frame_info.gpr_size)
3629 + int offset = 0;
3630 + int regno;
3632 + for (regno = 2; regno <= OR1K_LAST_ACTUAL_REG; regno++)
3634 + if (!(frame_info.mask & ((HOST_WIDE_INT) 1 << regno)))
3635 + continue;
3637 + if (regno != FIRST_PSEUDO_REGISTER)
3638 + emit_insn
3639 + (gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, regno),
3640 + stack_disp_mem (frame_info.gpr_offset + offset)));
3641 + offset = offset + UNITS_PER_WORD;
3645 + if (crtl->calls_eh_return)
3646 + emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
3648 + if (frame_info.gpr_frame)
3649 + emit_insn (gen_add2_insn (stack_pointer_rtx,
3650 + GEN_INT (frame_info.gpr_frame)));
3651 + emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, 9)));
3653 +} /* or1k_expand_epilogue () */
3657 +/* -------------------------------------------------------------------------- */
3658 +/*!Generate assembler code for a movdi/movdf pattern
3660 + @param[in] operands Operands to the movdx pattern.
3662 + @return The assembler string to output (always "", since we've done the
3663 + output here). */
3664 +/* -------------------------------------------------------------------------- */
3665 +const char *
3666 +or1k_output_move_double (rtx *operands)
3668 + rtx xoperands[3];
3670 + switch (GET_CODE (operands[0]))
3672 + case REG:
3673 + if (GET_CODE (operands[1]) == REG)
3675 + if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
3677 + output_asm_insn ("\tl.or \t%H0, %H1, r0", operands);
3678 + output_asm_insn ("\tl.or \t%0, %1, r0", operands);
3679 + return "";
3681 + else
3683 + output_asm_insn ("\tl.or \t%0, %1, r0", operands);
3684 + output_asm_insn ("\tl.or \t%H0, %H1, r0", operands);
3685 + return "";
3688 + else if (GET_CODE (operands[1]) == MEM)
3690 + xoperands[1] = XEXP (operands[1], 0);
3691 + if (GET_CODE (xoperands[1]) == REG)
3693 + xoperands[0] = operands[0];
3694 + if (REGNO (xoperands[0]) == REGNO (xoperands[1]))
3696 + output_asm_insn ("\tl.lwz \t%H0, 4(%1)", xoperands);
3697 + output_asm_insn ("\tl.lwz \t%0, 0(%1)", xoperands);
3698 + return "";
3700 + else
3702 + output_asm_insn ("\tl.lwz \t%0, 0(%1)", xoperands);
3703 + output_asm_insn ("\tl.lwz \t%H0, 4(%1)", xoperands);
3704 + return "";
3707 + else if (GET_CODE (xoperands[1]) == PLUS)
3709 + if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 1)) == REG)
3711 + xoperands[0] = operands[0];
3712 + xoperands[1] = XEXP (xoperands[1], 0);
3713 + if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
3715 + output_asm_insn ("\tl.lwz \t%H0, %1+4(%2)",
3716 + xoperands);
3717 + output_asm_insn ("\tl.lwz \t%0, %1(%2)", xoperands);
3718 + return "";
3720 + else
3722 + output_asm_insn ("\tl.lwz \t%0, %1(%2)", xoperands);
3723 + output_asm_insn ("\tl.lwz \t%H0, %1+4(%2)",
3724 + xoperands);
3725 + return "";
3728 + else if (GET_CODE (xoperands[2] = XEXP (xoperands[1], 0)) ==
3729 + REG)
3731 + xoperands[0] = operands[0];
3732 + xoperands[1] = XEXP (xoperands[1], 1);
3733 + if (REGNO (xoperands[0]) == REGNO (xoperands[2]))
3735 + output_asm_insn ("\tl.lwz \t%H0, %1+4(%2)",
3736 + xoperands);
3737 + output_asm_insn ("\tl.lwz \t%0, %1(%2)", xoperands);
3738 + return "";
3740 + else
3742 + output_asm_insn ("\tl.lwz \t%0, %1(%2)", xoperands);
3743 + output_asm_insn ("\tl.lwz \t%H0, %1+4(%2)",
3744 + xoperands);
3745 + return "";
3748 + else
3749 + abort ();
3751 + else
3752 + abort ();
3754 + else
3755 + abort ();
3756 + case MEM:
3757 + xoperands[0] = XEXP (operands[0], 0);
3758 + if (GET_CODE (xoperands[0]) == REG)
3760 + xoperands[1] = operands[1];
3761 + output_asm_insn ("\tl.sw \t0(%0), %1", xoperands);
3762 + output_asm_insn ("\tl.sw \t4(%0), %H1", xoperands);
3763 + return "";
3765 + else if (GET_CODE (xoperands[0]) == PLUS)
3767 + if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 1)) == REG)
3769 + xoperands[0] = XEXP (xoperands[0], 0);
3770 + xoperands[2] = operands[1];
3771 + output_asm_insn ("\tl.sw \t%0(%1), %2", xoperands);
3772 + output_asm_insn ("\tl.sw \t%0+4(%1), %H2", xoperands);
3773 + return "";
3775 + else if (GET_CODE (xoperands[1] = XEXP (xoperands[0], 0)) == REG)
3777 + xoperands[0] = XEXP (xoperands[0], 1);
3778 + xoperands[2] = operands[1];
3779 + output_asm_insn ("\tl.sw \t%0(%1), %2", xoperands);
3780 + output_asm_insn ("\tl.sw \t%0+4(%1), %H2", xoperands);
3781 + return "";
3783 + else
3784 + abort ();
3786 + else
3788 + fprintf (stderr, " O/p error %s\n",
3789 + GET_RTX_NAME (GET_CODE (xoperands[0])));
3790 + return "";
3791 + /* abort (); */
3793 + default:
3794 + abort ();
3796 +} /* or1k_output_move_double () */
3799 +/* -------------------------------------------------------------------------- */
3800 +/*!Expand a conditional branch
3802 + @param[in] operands Operands to the branch.
3803 + @param[in] mode Mode of the comparison. */
3804 +/* -------------------------------------------------------------------------- */
3805 +void
3806 +or1k_expand_conditional_branch (rtx *operands,
3807 + enum machine_mode mode)
3809 + rtx tmp;
3810 + enum rtx_code test_code = GET_CODE(operands[0]);
3812 + switch (mode)
3814 + case SImode:
3815 + tmp = or1k_expand_compare (test_code, operands[1], operands[2]);
3816 + tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
3817 + tmp,
3818 + gen_rtx_LABEL_REF (VOIDmode, operands[3]),
3819 + pc_rtx);
3820 + emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3821 + return;
3823 + case SFmode:
3824 + tmp = or1k_expand_compare (test_code, operands[1], operands[2]);
3825 + tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
3826 + tmp,
3827 + gen_rtx_LABEL_REF (VOIDmode, operands[3]),
3828 + pc_rtx);
3829 + emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3830 + return;
3832 + default:
3833 + abort ();
3836 +} /* or1k_expand_conditional_branch () */
3839 +/* -------------------------------------------------------------------------- */
3840 +/*!Emit a conditional move
3842 + move "true_cond" to "dest" if "op" of the operands of the last comparison
3843 + is nonzero/true, "false_cond" if it is zero/false.
3845 + @param[in] dest RTX for the destination operand.
3846 + @param[in] op RTX for the comparison operation
3847 + @param[in] true_cond RTX to move to dest if condition is TRUE.
3848 + @param[in] false_cond RTX to move to dest if condition is FALSE.
3850 + @return Non-zero (TRUE) if the hardware supports such an operation, zero
3851 + (FALSE) otherwise. */
3852 +/* -------------------------------------------------------------------------- */
3853 +int
3854 +or1k_emit_cmove (rtx dest,
3855 + rtx op,
3856 + rtx true_cond,
3857 + rtx false_cond)
3859 + enum machine_mode result_mode = GET_MODE (dest);
3861 + if (GET_MODE (true_cond) != result_mode)
3862 + return 0;
3864 + if (GET_MODE (false_cond) != result_mode)
3865 + return 0;
3867 + /* First, work out if the hardware can do this at all */
3868 + return or1k_emit_int_cmove (dest, op, true_cond, false_cond);
3870 +} /* or1k_emit_cmove () */
3873 +/* -------------------------------------------------------------------------- */
3874 +/*!Output the assembler for a branch on flag instruction.
3876 + @param[in] operands Operands to the branch.
3878 + @return The assembler string to use. */
3879 +/* -------------------------------------------------------------------------- */
3880 +const char *
3881 +or1k_output_bf (rtx * operands)
3883 + enum rtx_code code;
3884 + enum machine_mode mode_calc, mode_got;
3886 + code = GET_CODE (operands[1]);
3887 + mode_calc = or1k_select_cc_mode (code);
3888 + mode_got = GET_MODE (operands[2]);
3890 + if (mode_calc != mode_got)
3891 + return "l.bnf\t%l0%(";
3892 + else
3893 + return "l.bf\t%l0%(";
3894 +} /* or1k_output_bf () */
3897 +/* -------------------------------------------------------------------------- */
3898 +/*!Output the assembler for a conditional move instruction.
3900 + @param[in] operands Operands to the conditional move.
3902 + @return The assembler string to use. */
3903 +/* -------------------------------------------------------------------------- */
3904 +const char *
3905 +or1k_output_cmov (rtx * operands)
3907 + enum rtx_code code;
3908 + enum machine_mode mode_calc, mode_got;
3910 + code = GET_CODE (operands[1]);
3911 + mode_calc = or1k_select_cc_mode (code);
3912 + mode_got = GET_MODE (operands[4]);
3914 + if (mode_calc != mode_got)
3915 + return "l.cmov\t%0,%3,%2"; /* reversed */
3916 + else
3917 + return "l.cmov\t%0,%2,%3";
3919 +} /* or1k_output_cmov () */
3921 +/* -------------------------------------------------------------------------- */
3922 +/*!Load a 32-bit constant.
3924 + We know it can't be done in one insn when we get here, the movsi expander
3925 + guarantees this.
3927 + @param[in] op0 RTX for the destination.
3928 + @param[in] op1 RTX for the (constant) source. */
3929 +/* -------------------------------------------------------------------------- */
3930 +void
3931 +or1k_emit_set_const32 (rtx op0,
3932 + rtx op1)
3934 + enum machine_mode mode = GET_MODE (op0);
3935 + rtx temp;
3937 + /* Sanity check that we really can't do it in one instruction. I.e that we
3938 + don't have a 16-bit constant. */
3939 + if (GET_CODE (op1) == CONST_INT)
3941 + HOST_WIDE_INT val = INTVAL (op1) & GET_MODE_MASK (mode);
3943 + if ((-32768 <= val) && (val <= 32767))
3945 + abort ();
3949 + /* Full 2-insn decomposition is needed. */
3950 + if (reload_in_progress || reload_completed)
3951 + temp = op0;
3952 + else
3953 + temp = gen_reg_rtx (mode);
3955 + if (GET_CODE (op1) == CONST_INT)
3957 + /* Emit them as real moves instead of a HIGH/LO_SUM,
3958 + this way CSE can see everything and reuse intermediate
3959 + values if it wants. */
3960 + emit_insn (gen_rtx_SET (VOIDmode, temp,
3961 + GEN_INT (INTVAL (op1)
3962 + & ~(HOST_WIDE_INT) 0xffff)));
3964 + emit_insn (gen_rtx_SET (VOIDmode,
3965 + op0,
3966 + gen_rtx_IOR (mode, temp,
3967 + GEN_INT (INTVAL (op1) & 0xffff))));
3969 + else
3971 + /* since or1k bfd can not deal with relocs that are not of type
3972 + OR1K_CONSTH_RELOC + OR1K_CONST_RELOC (ie move high must be
3973 + followed by exactly one lo_sum)
3974 + */
3975 + emit_insn (gen_movsi_insn_big (op0, op1));
3977 +} /* or1k_emit_set_const32 () */
3980 +/* ========================================================================== */
3981 +/* Target hook functions.
3983 + These are initialized at the end of this file, to avoid having to
3984 + predeclare all the functions. They are only needed here, so are static. */
3989 +/* -------------------------------------------------------------------------- */
3990 +/*!Define where a function returns values.
3992 + Define this to return an RTX representing the place where a function
3993 + returns or receives a value of data type ret type, a tree node representing
3994 + a data type. "func" is a tree node representing FUNCTION_DECL or
3995 + FUNCTION_TYPE of a function being called. If "outgoing" is false, the hook
3996 + should compute the register in which the caller will see the return
3997 + value. Otherwise, the hook should return an RTX representing the place
3998 + where a function returns a value.
4000 + On many machines, only TYPE_MODE ("ret_type") is relevant. (Actually, on
4001 + most machines, scalar values are returned in the same place regardless of
4002 + mode.) The value of the expression is usually a reg RTX for the hard
4003 + register where the return value is stored. The value can also be a parallel
4004 + RTX, if the return value is in multiple places. See FUNCTION_ARG for an
4005 + explanation of the parallel form. Note that the callee will populate every
4006 + location specified in the parallel, but if the first element of the
4007 + parallel contains the whole return value, callers will use that element as
4008 + the canonical location and ignore the others. The m68k port uses this type
4009 + of parallel to return pointers in both ‘%a0’ (the canonical location) and
4010 + ‘%d0’.
4012 + If TARGET_PROMOTE_FUNCTION_RETURN returns true, you must apply the same
4013 + promotion rules specified in PROMOTE_MODE if valtype is a scalar type.
4015 + If the precise function being called is known, "func" is a tree node
4016 + (FUNCTION_DECL) for it; otherwise, "func" is a null pointer. This makes it
4017 + possible to use a different value-returning convention for specific
4018 + functions when all their calls are known.
4020 + Some target machines have "register windows" so that the register in which
4021 + a function returns its value is not the same as the one in which the caller
4022 + sees the value. For such machines, you should return different RTX
4023 + depending on outgoing.
4025 + TARGET_FUNCTION_VALUE is not used for return values with aggregate data
4026 + types, because these are returned in another way. See
4027 + TARGET_STRUCT_VALUE_RTX and related macros.
4029 + For the OR1K, we can just use the result of LIBCALL_VALUE, since all
4030 + functions return their result in the same place (register rv = r11).
4032 + JPB 30-Aug-10: What about 64-bit scalar returns (long long int, double),
4033 + which also use rvh (=r12)?
4035 + @param[in] ret_type The return type of the function.
4036 + @param[in] func Tree representing function being called.
4037 + @param[in] outgoing Non-zero (TRUE) if the result represents where the
4038 + function places the results, zero (FALSE) if the
4039 + result represents where the caller sees the result.
4041 + @return A RTX representing where the result can be found. */
4042 +/* -------------------------------------------------------------------------- */
4043 +static rtx
4044 +or1k_function_value (const_tree ret_type,
4045 + const_tree func ATTRIBUTE_UNUSED,
4046 + bool outgoing ATTRIBUTE_UNUSED)
4048 + return LIBCALL_VALUE (TYPE_MODE(ret_type));
4050 +} /* or1k_function_value () */
4053 +/* -------------------------------------------------------------------------- */
4054 +/*!Check if a function is suitable for tail call optimization.
4056 + True if it is OK to do sibling call optimization for the specified call
4057 + expression "exp". "decl" will be the called function, or NULL if this is an
4058 + indirect call.
4060 + It is not uncommon for limitations of calling conventions to prevent tail
4061 + calls to functions outside the current unit of translation, or during PIC
4062 + compilation. The hook is used to enforce these restrictions, as the sibcall
4063 + md pattern can not fail, or fall over to a “normal” call. The criteria for
4064 + successful sibling call optimization may vary greatly between different
4065 + architectures.
4067 + For the OR1K, we currently don't allow sibcalls.
4069 + @param[in] decl The function for which we may optimize
4070 + @param[in] exp The call expression which is candidate for optimization.
4072 + @return Non-zero (TRUE) if sibcall optimization is permitted, zero (FALSE)
4073 + otherwise. */
4074 +/* -------------------------------------------------------------------------- */
4075 +static bool
4076 +or1k_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
4077 + tree exp ATTRIBUTE_UNUSED)
4079 + return 0;
4080 +} /* or1k_function_ok_for_sibcall () */
4083 +/* -------------------------------------------------------------------------- */
4084 +/*!Should an argument be passed by reference.
4086 + This target hook should return true if an argument at the position
4087 + indicated by "cum" should be passed by reference. This predicate is queried
4088 + after target independent reasons for being passed by reference, such as
4089 + TREE_ADDRESSABLE ("type").
4091 + If the hook returns TRUE, a copy of that argument is made in memory and a
4092 + pointer to the argument is passed instead of the argument itself. The
4093 + pointer is passed in whatever way is appropriate for passing a pointer to
4094 + that type.
4096 + For the OR1K, all aggregates and arguments greater than 8 bytes are passed
4097 + this way.
4099 + @param[in] cum Position of argument under consideration.
4100 + @param[in[ mode Not sure what this relates to.
4101 + @param[in] type Type of the argument.
4102 + @param[in] named Not sure what this relates to.
4104 + @return Non-zero (TRUE) if the argument should be passed by reference,
4105 + zero (FALSE) otherwise. */
4106 +/* -------------------------------------------------------------------------- */
4107 +static bool
4108 +or1k_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
4109 + enum machine_mode mode ATTRIBUTE_UNUSED,
4110 + const_tree type,
4111 + bool named ATTRIBUTE_UNUSED)
4113 + return (type && (AGGREGATE_TYPE_P (type) || int_size_in_bytes (type) > 8));
4115 +} /* or1k_pass_by_reference () */
4118 +int
4119 +or1k_initial_elimination_offset(int from, int to)
4121 + or1k_compute_frame_size (get_frame_size ());
4122 + return ((from == FRAME_POINTER_REGNUM
4123 + ? frame_info.gpr_offset : frame_info.gpr_frame)
4124 + + (to == STACK_POINTER_REGNUM ? frame_info.late_frame : 0));
4128 +/* -------------------------------------------------------------------------- */
4129 +/*!How many bytes at the beginning of an argument must be put into registers.
4131 + This target hook returns the number of bytes at the beginning of an
4132 + argument that must be put in registers. The value must be zero for
4133 + arguments that are passed entirely in registers or that are entirely pushed
4134 + on the stack.
4136 + On some machines, certain arguments must be passed partially in registers
4137 + and partially in memory. On these machines, typically the first few words
4138 + of arguments a re passed in registers, and the rest on the stack. If a
4139 + multi-word argument (a double or a structure) crosses that boundary, its
4140 + first few words must be passed in registers and the rest must be
4141 + pushed. This macro tells the compiler when this occurs, and how many bytes
4142 + should go in registers.
4144 + FUNCTION_ARG for these arguments should return the first register to be
4145 + used by the caller for this argument; likewise FUNCTION_INCOMING_ARG, for
4146 + the called function.
4148 + On the OR1K we never split argumetns between registers and memory.
4150 + JPB 30-Aug-10: Is this correct? Surely we should allow this. The ABI spec
4151 + is incomplete on this point.
4153 + @param[in] cum Position of argument under consideration.
4154 + @param[in[ mode Not sure what this relates to.
4155 + @param[in] type Type of the argument.
4156 + @param[in] named Not sure what this relates to.
4158 + @return The number of bytes of the argument to go into registers */
4159 +/* -------------------------------------------------------------------------- */
4160 +static int
4161 +or1k_arg_partial_bytes (cumulative_args_t cum ATTRIBUTE_UNUSED,
4162 + enum machine_mode mode ATTRIBUTE_UNUSED,
4163 + tree type ATTRIBUTE_UNUSED,
4164 + bool named ATTRIBUTE_UNUSED)
4166 + return 0;
4168 +} /* or1k_arg_partial_bytes () */
4171 +/* -------------------------------------------------------------------------- */
4172 +/*!Promote the mode of a function's arguments/return value.
4174 + Like PROMOTE_MODE, but it is applied to outgoing function arguments or
4175 + function return values. The target hook should return the new mode and
4176 + possibly change "*punsignedp" if the promotion should change
4177 + signedness. This function is called only for scalar or pointer types.
4179 + "for_return" allows to distinguish the promotion of arguments and return
4180 + values. If it is 1, a return value is being promoted and
4181 + TARGET_FUNCTION_VALUE must perform the same promotions done here. If it is
4182 + 2, the returned mode should be that of the register in which an incoming
4183 + parameter is copied, or the outgoing result is computed; then the hook
4184 + should return the same mode as PROMOTE_MODE, though the signedness may be
4185 + different.
4187 + The default is to not promote arguments and return values. You can also
4188 + define the hook to "default_promote_function_mode_always_promote" if you
4189 + would like to apply the same rules given by PROMOTE_MODE.
4191 + For the OR1K, if the size of the mode is integral and less than 4, we
4192 + promote to SImode, otherwise we return the mode we are supplied.
4194 + @param[in] type Not sure. Type of the argument?
4195 + @param[in] mode The mode of argument/return value to consider.
4196 + @param[out] punsignedp Signedness of the value.
4197 + @param[in] fntype Not sure. Type of the function?
4198 + @param[in] for_return 1 if a return value, 2 if an incoming value.
4200 + @return The new mode. */
4201 +/* -------------------------------------------------------------------------- */
4202 +static enum machine_mode
4203 +or1k_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
4204 + enum machine_mode mode,
4205 + int *punsignedp ATTRIBUTE_UNUSED,
4206 + const_tree fntype ATTRIBUTE_UNUSED,
4207 + int for_return ATTRIBUTE_UNUSED)
4209 + return ( (GET_MODE_CLASS (mode) == MODE_INT)
4210 + && (GET_MODE_SIZE (mode) < 4)) ? SImode : mode;
4212 +} /* or1k_promote_function_mode () */
4215 +/* -------------------------------------------------------------------------- */
4216 +/*!Is this a legitimate address?
4218 + A function that returns whether x (an RTX) is a legitimate memory address on
4219 + the target machine for a memory operand of mode mode.
4221 + Legitimate addresses are defined in two variants: a strict variant and a
4222 + non-strict one. The strict parameter chooses which variant is desired by
4223 + the caller.
4225 + The strict variant is used in the reload pass. It must be defined so that
4226 + any pseudo- register that has not been allocated a hard register is
4227 + considered a memory reference. This is because in contexts where some kind
4228 + of register is required, a pseudo-register with no hard register must be
4229 + rejected. For non-hard registers, the strict variant should look up the
4230 + reg_renumber array; it should then proceed using the hard register number in
4231 + the array, or treat the pseudo as a memory reference if the array holds -1.
4233 + The non-strict variant is used in other passes. It must be defined to accept
4234 + all pseudo-registers in every context where some kind of register is
4235 + required.
4237 + Normally, constant addresses which are the sum of a symbol_ref and an
4238 + integer are stored inside a const RTX to mark them as constant. Therefore,
4239 + there is no need to recognize such sums specifically as legitimate
4240 + addresses. Normally you would simply recognize any const as legitimate.
4242 + Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant sums that
4243 + are not marked with const. It assumes that a naked plus indicates
4244 + indexing. If so, then you must reject such naked constant sums as
4245 + illegitimate addresses, so that none of them will be given to
4246 + PRINT_OPERAND_ADDRESS.
4248 + On some machines, whether a symbolic address is legitimate depends on the
4249 + section that the address refers to. On these machines, define the target
4250 + hook TARGET_ENCODE_ SECTION_INFO to store the information into the
4251 + symbol_ref, and then check for it here. When you see a const, you will have
4252 + to look inside it to find the symbol_ref in order to determine the
4253 + section. See the internals manual section on "Assembler Format" for more
4254 + info.
4256 + Some ports are still using a deprecated legacy substitute for this hook, the
4257 + GO_IF_LEGITIMATE_ADDRESS macro. This macro has this syntax:
4259 + #define GO_IF_LEGITIMATE_ADDRESS (mode, x, label )
4261 + and should goto label if the address x is a valid address on the target
4262 + machine for a memory operand of mode mode. Whether the strict or non-strict
4263 + variants are desired is defined by the REG_OK_STRICT macro introduced
4264 + earlier in this section. Using the hook is usually simpler because it limits
4265 + the number of files that are recompiled when changes are made.
4267 + The OR1K only has a single addressing mode, which is a base register with
4268 + 16-bit displacement. We can accept just 16-bit constants as addresses (they
4269 + can use r0 as base address, and we can accept plain registers as addresses
4270 + (they can use a displacement of zero).
4272 + @param[in] mode The mode of the address
4273 + @param[in] x The address (RTX)
4274 + @param[in] strict Non-zero (TRUE) if we are in "strict" mode, zero (FALSE)
4275 + otherwise.
4277 + @return Non-zero (TRUE) if this is a legitimate address, zero (FALSE)
4278 + otherwise. */
4279 +/* -------------------------------------------------------------------------- */
4280 +static bool
4281 +or1k_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
4282 + rtx x,
4283 + bool strict)
4285 + /* You might think 16-bit constants are suitable. They can be built into
4286 + addresses using r0 as the base. However this seems to lead to defective
4287 + code. So for now this is a placeholder, and this code is not used.
4289 + if (or1k_legitimate_displacement_p (mode, x))
4291 + return 1;
4293 + */
4294 + /* Addresses consisting of a register and 16-bit displacement are also
4295 + suitable. We need the mode, since for double words, we had better be
4296 + able to address the full 8 bytes. */
4297 + if (GET_CODE(x) == PLUS)
4299 + rtx reg = XEXP(x,0);
4301 + /* If valid register... */
4302 + if ((GET_CODE(reg) == REG)
4303 + && or1k_regnum_ok_for_base_p (REGNO (reg), strict))
4305 + rtx offset = XEXP(x,1);
4307 + /* ...and valid offset */
4308 + if (or1k_legitimate_displacement_p (mode, offset))
4310 + return 1;
4315 + /* Addresses consisting of just a register are OK. They can be built into
4316 + addresses using an offset of zero (and an offset of four if double
4317 + word). */
4318 + if (GET_CODE(x) == REG
4319 + && or1k_regnum_ok_for_base_p(REGNO(x),strict)) {
4320 + return 1;
4323 + return 0;
4326 +/* -------------------------------------------------------------------------- */
4327 +/*!Initialize a trampoline for nested functions.
4329 + A nested function is defined by *two* pieces of information, the address of
4330 + the function (like any other function) and a pointer to the frame of the
4331 + enclosing function. The latter is required to allow the nested function to
4332 + access local variables in the enclosing function's frame.
4334 + This represents a problem, since a function in C is represented as an
4335 + address that can be held in a single variable as a pointer. Requiring two
4336 + pointers will not fit.
4338 + The solution is documented in "Lexical Closures for C++" by Thomas
4339 + M. Breuel (USENIX C++ Conference Proceedings, October 17-21, 1988). The
4340 + nested function is represented by a small block of code and data on the
4341 + enclosing function's stack frame, which sets up a pointer to the enclosing
4342 + function's stack frame (the static chain pointer) in a register defined by
4343 + the ABI, and then jumps to the code of the function proper.
4345 + The function can be represented as a single pointer to this block of code,
4346 + known as a trampoline, which when called generates both pointers
4347 + needed. The nested function (which knows it is a nested function at compile
4348 + time) can then generate code to access the enclosing frame via the static
4349 + chain register.
4351 + There is a catch that the trampoline is set up as data, but executed as
4352 + instructions. The former will be via the data cache, the latter via the
4353 + instruction cache. There is a risk that a later trampoline will not be seen
4354 + by the instruction cache, so the wrong code will be executed. So the
4355 + instruction cache should be flushed for the trampoline address range.
4357 + This hook is called to initialize a trampoline. "m_tramp" is an RTX for the
4358 + memory block for the trampoline; "fndecl" is the FUNCTION_DECL for the
4359 + nested function; "static_chain" is an RTX for the static chain value that
4360 + should be passed to the function when it is called.
4362 + If the target defines TARGET_ASM_TRAMPOLINE_TEMPLATE, then the first thing
4363 + this hook should do is emit a block move into "m_tramp" from the memory
4364 + block returned by assemble_trampoline_template. Note that the block move
4365 + need only cover the constant parts of the trampoline. If the target
4366 + isolates the variable parts of the trampoline to the end, not all
4367 + TRAMPOLINE_SIZE bytes need be copied.
4369 + If the target requires any other actions, such as flushing caches or
4370 + enabling stack execution, these actions should be performed after
4371 + initializing the trampoline proper.
4373 + For the OR1K, no static chain register is used. We choose to use the return
4374 + value (rv) register. The code is based on that for MIPS.
4375 + The trampoline code is:
4377 + l.movhi r11,hi(end_addr)
4378 + l.ori r11,lo(end_addr)
4379 + l.lwz r13,4(r11)
4380 + l.jr r13
4381 + l.lwz r11,0(r11)
4382 + end_addr:
4383 + .word <static chain>
4384 + .word <nested_function>
4386 + @note For the OR1K we need to flush the instruction cache, which is a
4387 + privileged operation. Needs fixing.
4389 + @param[in] m_tramp The lowest address of the trampoline on the stack.
4390 + @param[in] fndecl Declaration of the enclosing function.
4391 + @param[in] chain_value Static chain pointer to pass to the nested
4392 + function. */
4393 +/* -------------------------------------------------------------------------- */
4394 +static void
4395 +or1k_trampoline_init (rtx m_tramp,
4396 + tree fndecl,
4397 + rtx chain_value)
4399 + rtx addr; /* Start address of the trampoline */
4400 + rtx end_addr; /* End address of the code block */
4402 + rtx high; /* RTX for the high part of end_addr */
4403 + rtx low; /* RTX for the low part of end_addr */
4404 + rtx opcode; /* RTX for generated opcodes */
4405 + rtx mem; /* RTX for trampoline memory */
4407 + rtx *trampoline; /* The trampoline code */
4409 + unsigned int i; /* Index into trampoline */
4410 + unsigned int j; /* General counter */
4412 + HOST_WIDE_INT end_addr_offset; /* Offset to end of code */
4413 + HOST_WIDE_INT static_chain_offset; /* Offset to stack chain word */
4414 + HOST_WIDE_INT target_function_offset; /* Offset to func address word */
4416 + /* Work out the offsets of the pointers from the start of the trampoline
4417 + code. */
4418 + trampoline = (rtx*) alloca (or1k_trampoline_code_words() * sizeof(rtx));
4419 + end_addr_offset = or1k_trampoline_code_size ();
4420 + static_chain_offset = end_addr_offset;
4421 + target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
4423 + /* Get pointers in registers to the beginning and end of the code block. */
4424 + addr = force_reg (Pmode, XEXP (m_tramp, 0));
4425 + end_addr = or1k_force_binary (Pmode, PLUS, addr, GEN_INT (end_addr_offset));
4427 + /* Build up the code in TRAMPOLINE.
4429 + l.movhi r11,hi(end_addr)
4430 + l.ori r11,lo(end_addr)
4431 + l.lwz r13,4(r11)
4432 + l.jr r13
4433 + l.lwz r11,0(r11)
4434 + end_addr:
4435 + */
4437 + i = 0;
4439 + /* Break out the high and low parts of the end_addr */
4440 + high = expand_simple_binop (SImode, LSHIFTRT, end_addr, GEN_INT (16),
4441 + NULL, false, OPTAB_WIDEN);
4442 + low = convert_to_mode (SImode, gen_lowpart (HImode, end_addr), true);
4444 + /* Emit the l.movhi, adding an operation to OR in the high bits from the
4445 + RTX. */
4446 + opcode = gen_int_mode (OR1K_MOVHI (11, 0), SImode);
4447 + trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, high, NULL,
4448 + false, OPTAB_WIDEN);
4450 + /* Emit the l.ori, adding an operations to OR in the low bits from the
4451 + RTX. */
4452 + opcode = gen_int_mode (OR1K_ORI (11, 11, 0), SImode);
4453 + trampoline[i++] = expand_simple_binop (SImode, IOR, opcode, low, NULL,
4454 + false, OPTAB_WIDEN);
4456 + /* Emit the l.lwz of the function address. No bits to OR in here, so we can
4457 + do the opcode directly. */
4458 + trampoline[i++] =
4459 + gen_int_mode (OR1K_LWZ (13, 11, target_function_offset - end_addr_offset),
4460 + SImode);
4462 + if (TARGET_DELAY_ON) {
4463 + /* Emit the l.jr of the function. No bits to OR in here, so we can do the
4464 + opcode directly. */
4465 + trampoline[i++] = gen_int_mode (OR1K_JR (13), SImode);
4467 + /* Emit the l.lwz of the static chain. No bits to OR in here, so we can
4468 + do the opcode directly. */
4469 + trampoline[i++] =
4470 + gen_int_mode (OR1K_LWZ (STATIC_CHAIN_REGNUM, 11,
4471 + static_chain_offset - end_addr_offset), SImode);
4472 + } else {
4473 + trampoline[i++] =
4474 + gen_int_mode (OR1K_LWZ (STATIC_CHAIN_REGNUM, 11,
4475 + static_chain_offset - end_addr_offset), SImode);
4476 + trampoline[i++] = gen_int_mode (OR1K_JR (13), SImode);
4477 + if (TARGET_DELAY_COMPAT)
4478 + trampoline[i++] = gen_int_mode (OR1K_NOP, SImode);
4481 + /* Copy the trampoline code. Leave any padding uninitialized. */
4482 + for (j = 0; j < i; j++)
4484 + mem = adjust_address (m_tramp, SImode, j * GET_MODE_SIZE (SImode));
4485 + or1k_emit_move (mem, trampoline[j]);
4488 + /* Set up the static chain pointer field. */
4489 + mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
4490 + or1k_emit_move (mem, chain_value);
4492 + /* Set up the target function field. */
4493 + mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
4494 + or1k_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
4496 + /* Flushing the trampoline from the instruction cache needs to be done
4497 + here. */
4499 +} /* or1k_trampoline_init () */
4502 +/* -------------------------------------------------------------------------- */
4503 +/*!Provide support for DW_AT_calling_convention
4505 + Define this to enable the dwarf attribute DW_AT_calling_convention to be
4506 + emitted for each function. Instead of an integer return the enum value for
4507 + the DW_CC_ tag.
4509 + To support optional call frame debugging information, you must also define
4510 + INCOMING_RETURN_ADDR_RTX and either set RTX_FRAME_RELATED_P on the prologue
4511 + insns if you use RTL for the prologue, or call "dwarf2out_def_cfa" and
4512 + "dwarf2out_reg_save" as appropriate from TARGET_ASM_FUNCTION_PROLOGUE if
4513 + you don’t.
4515 + For the OR1K, it should be sufficient to return DW_CC_normal in all cases.
4517 + @param[in] function The function requiring debug information
4519 + @return The enum of the DW_CC tag. */
4520 +/* -------------------------------------------------------------------------- */
4521 +static int
4522 +or1k_dwarf_calling_convention (const_tree function ATTRIBUTE_UNUSED)
4524 + return DW_CC_normal;
4526 +} /* or1k_dwarf_calling_convention () */
4528 +/* ========================================================================== */
4529 +/* Target hook initialization.
4531 + In most cases these use the static functions declared above. They have
4532 + defaults, so must be undefined first, before being redefined.
4534 + The description of what they do is found with the function above, unless it
4535 + is a standard function or a constant, in which case it is defined here (as
4536 + with TARGET_ASM_NAMED_SECTION).
4538 + The final declaration is of the global "targetm" structure. */
4540 +/* Output assembly directives to switch to section name. The section should
4541 + have attributes as specified by flags, which is a bit mask of the SECTION_*
4542 + flags defined in ‘output.h’. If decl is non-NULL, it is the VAR_DECL or
4543 + FUNCTION_DECL with which this section is associated.
4545 + For OR1K, we use the default ELF sectioning. */
4546 +#undef TARGET_ASM_NAMED_SECTION
4547 +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
4549 +#undef TARGET_FUNCTION_VALUE
4550 +#define TARGET_FUNCTION_VALUE or1k_function_value
4552 +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
4553 +#define TARGET_FUNCTION_OK_FOR_SIBCALL or1k_function_ok_for_sibcall
4555 +#undef TARGET_PASS_BY_REFERENCE
4556 +#define TARGET_PASS_BY_REFERENCE or1k_pass_by_reference
4558 +#undef TARGET_ARG_PARTIAL_BYTES
4559 +#define TARGET_ARG_PARTIAL_BYTES or1k_arg_partial_bytes
4561 +#undef TARGET_OPTION_OVERRIDE
4562 +#define TARGET_OPTION_OVERRIDE or1k_option_override
4564 +#undef TARGET_ASM_FILE_START
4565 +#define TARGET_ASM_FILE_START or1k_asm_file_start
4567 +/* This target hook returns TRUE if an argument declared in a prototype as an
4568 + integral type smaller than int should actually be passed as an int. In
4569 + addition to avoiding errors in certain cases of mismatch, it also makes for
4570 + better code on certain machines.
4572 + The default is to not promote prototypes.
4574 + For the OR1K we do require this, so use a utility hook, which always
4575 + returns TRUE. */
4576 +#undef TARGET_PROMOTE_PROTOTYPES
4577 +#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
4579 +#undef TARGET_PROMOTE_FUNCTION_MODE
4580 +#define TARGET_PROMOTE_FUNCTION_MODE or1k_promote_function_mode
4582 +#undef TARGET_LEGITIMATE_ADDRESS_P
4583 +#define TARGET_LEGITIMATE_ADDRESS_P or1k_legitimate_address_p
4585 +#undef TARGET_LEGITIMIZE_ADDRESS
4586 +#define TARGET_LEGITIMIZE_ADDRESS or1k_legitimize_address
4588 +#undef TARGET_TRAMPOLINE_INIT
4589 +#define TARGET_TRAMPOLINE_INIT or1k_trampoline_init
4591 +#undef TARGET_CANNOT_FORCE_CONST_MEM
4592 +#define TARGET_CANNOT_FORCE_CONST_MEM or1k_cannot_force_const_mem
4594 +#undef TARGET_DWARF_CALLING_CONVENTION
4595 +#define TARGET_DWARF_CALLING_CONVENTION or1k_dwarf_calling_convention
4597 +/* uClibc has some instances where (non-coforming to ISO C) a non-varargs
4598 + prototype is in scope when calling that function which is implemented
4599 + as varargs. We want this to work at least where none of the anonymous
4600 + arguments are used. I.e. we want the last named argument to be known
4601 + as named so it can be passed in a register, varars funtion or not. */
4602 +#undef TARGET_STRICT_ARGUMENT_NAMING
4603 +#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
4605 +/* Is this suitable for an immediate operand.
4607 + JPB 1-Sep-10: Is this correct. We can only do 16-bit immediates directly. */
4608 +static bool
4609 +or1k_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
4611 + if (or1k_tls_symbolic_operand (x) != TLS_MODEL_NONE)
4612 + return 0;
4614 + return GET_CODE(x) != CONST_DOUBLE || (GET_MODE (x) == VOIDmode && !flag_pic);
4616 +#undef TARGET_LEGITIMATE_CONSTANT_P
4617 +#define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p
4619 +/* On the OR1K, no functions pop their arguments.
4620 + JPB 29-Aug-10: Is this really correct? */
4621 +static int
4622 +or1k_return_pops_args (tree ARG_UNUSED(fundecl), tree ARG_UNUSED(funtype), int ARG_UNUSED(size))
4624 + return 0;
4626 +#undef TARGET_RETURN_POPS_ARGS
4627 +#define TARGET_RETURN_POPS_ARGS or1k_return_pops_args
4629 +/* Determine where to put an argument to a function. Value is zero to push
4630 + the argument on the stack, or a hard register in which to store the
4631 + argument.
4633 + "mode" is the argument's machine mode.
4635 + "type" is the data type of the argument (as a tree). This is null for
4636 + libcalls where that information may not be available.
4638 + "cum" is a variable of type CUMULATIVE_ARGS which gives info about the
4639 + preceding args and about the function being called.
4641 + "named" is nonzero if this argument is a named parameter (otherwise it is
4642 + an extra parameter matching an ellipsis).
4644 + On the ARC the first MAX_ARC_PARM_REGS args are normally in registers and
4645 + the rest are pushed. */
4646 +static rtx
4647 +or1k_function_arg (cumulative_args_t cum, enum machine_mode mode,
4648 + const_tree type, bool named)
4650 + CUMULATIVE_ARGS *cum_pnt = get_cumulative_args (cum);
4652 + if (OR1K_PASS_IN_REG_P (*cum_pnt, mode, type, named))
4653 + return gen_rtx_REG (mode, OR1K_ROUND_ADVANCE_CUM (*cum_pnt, mode, type)
4654 + + GP_ARG_MIN_REG);
4655 + else
4656 + return 0;
4658 +#undef TARGET_FUNCTION_ARG
4659 +#define TARGET_FUNCTION_ARG or1k_function_arg
4660 +/* Update the data in "cum" to advance over an argument of mode "mode" and
4661 + data type "type". ("type" is null for libcalls where that information may
4662 + not be available.) */
4663 +static void
4664 +or1k_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
4665 + const_tree type, bool ARG_UNUSED(named))
4667 + CUMULATIVE_ARGS *cum_pnt = get_cumulative_args (cum);
4669 + *cum_pnt = OR1K_ROUND_ADVANCE_CUM (*cum_pnt, mode, type)
4670 + + OR1K_ROUND_ADVANCE_ARG (mode, type);
4673 +#undef TARGET_FUNCTION_ARG_ADVANCE
4674 +#define TARGET_FUNCTION_ARG_ADVANCE or1k_function_arg_advance
4676 +#undef TARGET_PRINT_OPERAND_ADDRESS
4677 +#define TARGET_PRINT_OPERAND_ADDRESS or1k_print_operand_address
4679 +/* Trampoline stubs are yet to be written. */
4680 +/* #define TARGET_ASM_TRAMPOLINE_TEMPLATE */
4681 +/* #define TARGET_TRAMPOLINE_INIT */
4683 +/* Lay out structs with increased alignment so that they can be accessed
4684 + more efficiently. But don't increase the size of one or two byte
4685 + structs. */
4686 +int
4687 +or1k_struct_alignment (tree t)
4689 + unsigned HOST_WIDE_INT total = 0;
4690 + int default_align_fields = 0;
4691 + int special_align_fields = 0;
4692 + tree field;
4693 + unsigned max_align
4694 + = maximum_field_alignment ? maximum_field_alignment : BIGGEST_ALIGNMENT;
4695 + bool struct_p;
4697 + switch (TREE_CODE (t))
4699 + case RECORD_TYPE:
4700 + struct_p = true; break;
4701 + case UNION_TYPE: case QUAL_UNION_TYPE:
4702 + struct_p = false; break;
4703 + default: gcc_unreachable ();
4705 + /* Skip all non field decls */
4706 + for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
4708 + unsigned HOST_WIDE_INT field_size;
4710 + if (TREE_CODE (field) != FIELD_DECL ||
4711 + TREE_TYPE (field) == error_mark_node)
4712 + continue;
4713 + /* If this is a field in a non-qualified union, or the sole field in
4714 + a struct, and the alignment was set by the user, don't change the
4715 + alignment.
4716 + If the field is a struct/union in a non-qualified union, we already
4717 + had sufficient opportunity to pad it - if we didn't, that'd be
4718 + because the alignment was set as above.
4719 + Likewise if the field is a struct/union and the sole field in a
4720 + struct. */
4721 + if (DECL_USER_ALIGN (field)
4722 + || TYPE_USER_ALIGN (TREE_TYPE (field))
4723 + || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
4724 + || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
4725 + || TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
4727 + if (TREE_CODE (t) == UNION_TYPE)
4728 + return 0;
4729 + special_align_fields++;
4731 + else if (DECL_PACKED (field))
4732 + special_align_fields++;
4733 + else
4734 + default_align_fields++;
4735 + if (!host_integerp (DECL_SIZE_UNIT (field), 1))
4736 + field_size = max_align;
4737 + else
4738 + field_size = tree_low_cst (DECL_SIZE_UNIT (field), 1);
4739 + if (field_size >= BIGGEST_ALIGNMENT)
4740 + total = max_align;
4741 + if (struct_p)
4742 + total += field_size;
4743 + else
4744 + total = MAX (total, field_size);
4747 + if (!default_align_fields
4748 + && (TREE_CODE (t) != RECORD_TYPE || special_align_fields <= 1))
4749 + return 0;
4750 + return total < max_align ? (1U << ceil_log2 (total)) : max_align;
4753 +/* Increase the alignment of objects so that they are easier to copy.
4754 + Note that this can cause more struct copies to be inlined, so code
4755 + size might increase, but so should perfromance. */
4756 +int
4757 +or1k_data_alignment (tree t, int align)
4759 + if (align < FASTEST_ALIGNMENT && TREE_CODE (t) == ARRAY_TYPE)
4761 + int size = int_size_in_bytes (t);
4763 + return (size > 0 && size < FASTEST_ALIGNMENT / BITS_PER_UNIT
4764 + ? (1 << floor_log2 (size)) * BITS_PER_UNIT
4765 + : FASTEST_ALIGNMENT);
4767 + return align;
4770 +static void
4771 +or1k_option_override (void)
4773 + if (!TARGET_DELAY_ON)
4774 + flag_delayed_branch = FALSE;
4777 +static void
4778 +or1k_asm_file_start(void)
4780 + default_file_start();
4782 + if (TARGET_DELAY_OFF) {
4783 + fprintf(asm_out_file, "\t.nodelay\n");
4787 +/* Implement EH_RETURN_HANDLER_RTX.
4788 + * Make eh_return use the link register. Epilogue LR restore
4789 + * is suppressed for eh_return. */
4790 +rtx
4791 +or1k_eh_return_handler_rtx (void)
4793 + return INCOMING_RETURN_ADDR_RTX;
4796 +/* Implement RETURN_ADDR_RTX.
4797 + * We do not support moving back to a previous frame. */
4798 +rtx
4799 +or1k_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
4801 + if (count != 0)
4802 + return const0_rtx;
4804 + /* We don't know if LR is going to be saved or if we're going to
4805 + * be clobbering it with the GOT instruction.
4806 + * Therefore the safest bet is to force a save of LR and use that.
4807 + * Assume it's going to be first in the stack. */
4809 + cfun->machine->force_lr_save = true;
4810 + return gen_rtx_MEM (Pmode, plus_constant (Pmode, arg_pointer_rtx,
4811 + -UNITS_PER_WORD));
4814 +/* Implement TARGET_FRAME_POINTER_REQUIRED.
4815 + * We want frame pointer in eh_return and when alloca is used */
4816 +static bool
4817 +or1k_frame_pointer_required (void)
4819 + return crtl->calls_eh_return || cfun->calls_alloca;
4822 +/* Functions to save and restore machine-specific function data. */
4823 +static struct machine_function *
4824 +or1k_init_machine_status (void)
4826 + return ggc_alloc_cleared_machine_function ();
4829 +void
4830 +or1k_init_expanders (void)
4832 + /* Arrange to initialize and mark the machine per-function
4833 + * status. */
4834 + init_machine_status = or1k_init_machine_status;
4836 + if (cfun && cfun->machine)
4838 + cfun->machine->force_lr_save = false;
4842 +#undef TARGET_FRAME_POINTER_REQUIRED
4843 +#define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required
4845 +/* Initialize the GCC target structure. */
4846 +struct gcc_target targetm = TARGET_INITIALIZER;
4848 +#include "gt-or1k.h"
4849 diff -rNU3 dist.orig/gcc/config/or1k/or1k.h dist/gcc/config/or1k/or1k.h
4850 --- dist.orig/gcc/config/or1k/or1k.h 1970-01-01 01:00:00.000000000 +0100
4851 +++ dist/gcc/config/or1k/or1k.h 2015-10-18 13:19:50.000000000 +0200
4852 @@ -0,0 +1,1202 @@
4853 +/* Definitions of target machine for GNU compiler. OpenRISC 1000 version.
4854 + Copyright (C) 1987, 1988, 1992, 1995, 1996, 1999, 2000, 2001, 2002,
4855 + 2003, 2004, 2005 Free Software Foundation, Inc.
4856 + Copyright (C) 2010 Embecosm Limited
4857 + Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
4858 + Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
4860 +This file is part of GNU CC.
4862 +GNU CC is free software; you can redistribute it and/or modify
4863 +it under the terms of the GNU General Public License as published by
4864 +the Free Software Foundation; either version 1, or (at your option)
4865 +any later version.
4867 +GNU CC is distributed in the hope that it will be useful,
4868 +but WITHOUT ANY WARRANTY; without even the implied warranty of
4869 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4870 +GNU General Public License for more details.
4872 +You should have received a copy of the GNU General Public License
4873 +along with GNU CC; see the file COPYING. If not, write to
4874 +the Free Software Foundation, 59 Temple Place - Suite 330,
4875 +Boston, MA 02111-1307, USA. */
4877 +#ifndef _OR1K_H_
4878 +#define _OR1K_H_
4880 +#include "config/or1k/or1k-opts.h"
4882 +/* Target CPU builtins */
4883 +#define TARGET_CPU_CPP_BUILTINS() \
4884 + do \
4885 + { \
4886 + if (TARGET_DELAY_OFF) { \
4887 + builtin_define ("__OR1KND__"); \
4888 + builtin_define ("__or1knd__"); \
4889 + builtin_assert ("cpu=or1knd"); \
4890 + builtin_assert ("machine=or1knd"); \
4891 + } else { \
4892 + builtin_define ("__OR1K__"); \
4893 + builtin_define ("__or1k__"); \
4894 + builtin_assert ("cpu=or1k"); \
4895 + builtin_assert ("machine=or1k"); \
4896 + } \
4897 + if (TARGET_DELAY_ON) { \
4898 + builtin_define ("__OR1K_DELAY__"); \
4899 + } else if (TARGET_DELAY_OFF) { \
4900 + builtin_define ("__OR1K_NODELAY__"); \
4901 + } else if (TARGET_DELAY_COMPAT) { \
4902 + builtin_define ("__OR1K_DELAY_COMPAT__"); \
4903 + } \
4904 + } \
4905 + while (0)
4907 +#undef CPP_SPEC
4908 +#define CPP_SPEC "%{!mnewlib:%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}}"
4910 +/* Make sure we pick up the crti.o, crtbegin.o, crtend.o and crtn.o files. */
4911 +#undef STARTFILE_SPEC
4912 +#define STARTFILE_SPEC \
4913 + "%{!shared:%{pie:Scrt0.o%s;:crt0.o%s}} crti.o%s \
4914 + %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
4916 +#undef ENDFILE_SPEC
4917 +#define ENDFILE_SPEC "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
4919 +#undef LINK_SPEC
4920 +#define LINK_SPEC "%{mnewlib:-entry 0x100} %{static:-static} %{shared:-shared}"
4922 +/* Override previous definitions (linux.h). Newlib doesn't have a profiling
4923 + version of the library, but it does have a debugging version (libg.a) */
4924 +#undef LIB_SPEC
4925 +#define LIB_SPEC "%{!mnewlib:%{pthread:-lpthread} \
4926 + %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" \
4927 + "%{mnewlib:%{!g:-lc} %{g:-lg} -lor1k \
4928 + %{mboard=*:-lboard-%*} %{!mboard=*:-lboard-or1ksim} \
4929 + %{!g:-lc} %{g:-lg} \
4930 + }"
4932 +#define SUBTARGET_EXTRA_SPECS
4934 +#define EXTRA_SPECS \
4935 + SUBTARGET_EXTRA_SPECS
4937 +/* Target machine storage layout */
4939 +/* Define this if most significant bit is lowest numbered
4940 + in instructions that operate on numbered bit-fields.
4941 + This is not true on the or1k. */
4942 +#define BITS_BIG_ENDIAN 0
4944 +/* Define this if most significant byte of a word is the lowest numbered. */
4945 +#define BYTES_BIG_ENDIAN 1
4947 +/* Define this if most significant word of a multiword number is numbered. */
4948 +#define WORDS_BIG_ENDIAN 1
4950 +#define BITS_PER_WORD 32
4951 +#define SHORT_TYPE_SIZE 16
4952 +#define INT_TYPE_SIZE 32
4953 +#define LONG_TYPE_SIZE 32
4954 +#define LONG_LONG_TYPE_SIZE 64
4955 +#define FLOAT_TYPE_SIZE 32
4956 +#define DOUBLE_TYPE_SIZE 64
4957 +#define LONG_DOUBLE_TYPE_SIZE 64
4959 +/* Width of a word, in units (bytes). */
4960 +#define UNITS_PER_WORD 4
4962 +/* Width in bits of a pointer.
4963 + See also the macro `Pmode' defined below. */
4964 +#define POINTER_SIZE 32
4966 +/* Allocation boundary (in *bits*) for storing pointers in memory. */
4967 +#define POINTER_BOUNDARY 32
4969 +/* Allocation boundary (in *bits*) for storing arguments in argument list. */
4970 +#define PARM_BOUNDARY 32
4972 +/* Boundary (in *bits*) on which stack pointer should be aligned. */
4973 +#define STACK_BOUNDARY 32
4975 +/* Allocation boundary (in *bits*) for the code of a function. */
4976 +#define FUNCTION_BOUNDARY 32
4978 +/* Alignment of field after `int : 0' in a structure. */
4979 +#define EMPTY_FIELD_BOUNDARY 8
4981 +/* A bitfield declared as `int' forces `int' alignment for the struct. */
4982 +#define PCC_BITFIELD_TYPE_MATTERS 1
4984 +/* No data type wants to be aligned rounder than this. */
4985 +#define BIGGEST_ALIGNMENT 32
4987 +/* The best alignment to use in cases where we have a choice. */
4988 +#define FASTEST_ALIGNMENT 32
4990 +/* Make strings word-aligned so strcpy from constants will be faster. */
4992 +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
4993 + ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
4994 + && (ALIGN) < FASTEST_ALIGNMENT \
4995 + ? FASTEST_ALIGNMENT : (ALIGN))
4998 +/* One use of this macro is to increase alignment of medium-size
4999 + data to make it all fit in fewer cache lines. Another is to
5000 + cause character arrays to be word-aligned so that `strcpy' calls
5001 + that copy constants to character arrays can be done inline. */
5003 +#define DATA_ALIGNMENT(TYPE, ALIGN) \
5004 + ((((ALIGN) < FASTEST_ALIGNMENT) \
5005 + && (TREE_CODE (TYPE) == ARRAY_TYPE \
5006 + || TREE_CODE (TYPE) == UNION_TYPE \
5007 + || TREE_CODE (TYPE) == RECORD_TYPE)) ? FASTEST_ALIGNMENT : (ALIGN))
5008 +*/ /* CHECK - btw code gets bigger with this one */
5009 +#define DATA_ALIGNMENT(TYPE, ALIGN) \
5010 + ((ALIGN) < FASTEST_ALIGNMENT \
5011 + ? or1k_data_alignment ((TYPE), (ALIGN)) : (ALIGN))
5013 +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
5014 + ((ALIGN) < FASTEST_ALIGNMENT \
5015 + ? or1k_data_alignment ((TYPE), (ALIGN)) : (ALIGN))
5017 +/* Define this if move instructions will actually fail to work
5018 + when given unaligned data. */
5019 +#define STRICT_ALIGNMENT 1 /* CHECK */
5021 +/* Align an address */
5022 +#define OR1K_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
5024 +/* Define if operations between registers always perform the operation
5025 + on the full register even if a narrower mode is specified. */
5026 +#define WORD_REGISTER_OPERATIONS /* CHECK */
5029 +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
5030 + will either zero-extend or sign-extend. The value of this macro should
5031 + be the code that says which one of the two operations is implicitly
5032 + done, NIL if none. */
5033 +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
5035 +/* Define this macro if it is advisable to hold scalars in registers
5036 + in a wider mode than that declared by the program. In such cases,
5037 + the value is constrained to be within the bounds of the declared
5038 + type, but kept valid in the wider mode. The signedness of the
5039 + extension may differ from that of the type. */
5040 +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
5041 + if (GET_MODE_CLASS (MODE) == MODE_INT \
5042 + && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
5043 + (MODE) = SImode;
5044 + /* CHECK */
5048 + * brings 0.4% improvment in static size for linux
5050 +#define PROMOTE_FOR_CALL_ONLY
5053 +/* Define this macro if it is as good or better to call a constant
5054 + function address than to call an address kept in a register. */
5055 +#define NO_FUNCTION_CSE 1 /* check */
5057 +/* Standard register usage. */
5059 +/* Number of actual hardware registers.
5060 + The hardware registers are assigned numbers for the compiler
5061 + from 0 to just below FIRST_PSEUDO_REGISTER.
5062 + All registers that the compiler knows about must be given numbers,
5063 + even those that are not normally considered general registers. */
5065 +#define OR1K_LAST_ACTUAL_REG 31
5066 +#define ARG_POINTER_REGNUM (OR1K_LAST_ACTUAL_REG + 1)
5067 +#define FRAME_POINTER_REGNUM (ARG_POINTER_REGNUM + 1)
5068 +#define OR1K_LAST_INT_REG FRAME_POINTER_REGNUM
5069 +#define OR1K_FLAGS_REG (OR1K_LAST_INT_REG + 1)
5070 +#define FIRST_PSEUDO_REGISTER (OR1K_FLAGS_REG + 1)
5072 +/* 1 for registers that have pervasive standard uses
5073 + and are not available for the register allocator.
5074 + On the or1k, these are r1 as stack pointer and
5075 + r2 as frame/arg pointer. r9 is link register, r0
5076 + is zero, r10 is linux thread and r16 is got pointer */
5077 +#define FIXED_REGISTERS { \
5078 + 1, 1, 0, 0, 0, 0, 0, 0, \
5079 + 0, 1, 1, 0, 0, 0, 0, 0, \
5080 + 1, 0, 0, 0, 0, 0, 0, 0, \
5081 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }
5082 +/* 1 for registers not available across function calls.
5083 + These must include the FIXED_REGISTERS and also any
5084 + registers that can be used without being saved.
5085 + The latter must include the registers where values are returned
5086 + and the register where structure-value addresses are passed.
5087 + Aside from that, you can include as many other registers as you like. */
5088 +#define CALL_USED_REGISTERS { \
5089 + 1, 1, 0, 1, 1, 1, 1, 1, \
5090 + 1, 1, 1, 1, 1, 1, 0, 1, \
5091 + 1, 1, 0, 1, 0, 1, 0, 1, \
5092 + 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1}
5094 +/* stack pointer: must be FIXED and CALL_USED */
5095 +/* hard frame pointer: must be call saved. */
5096 +/* soft frame pointer / arg pointer: must be FIXED and CALL_USED */
5098 +/* Return number of consecutive hard regs needed starting at reg REGNO
5099 + to hold something of mode MODE.
5100 + This is ordinarily the length in words of a value of mode MODE
5101 + but can be less for certain modes in special long registers.
5102 + On the or1k, all registers are one word long. */
5103 +#define HARD_REGNO_NREGS(REGNO, MODE) \
5104 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
5106 +/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
5107 +#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
5109 +/* Value is 1 if it is a good idea to tie two pseudo registers
5110 + when one has mode MODE1 and one has mode MODE2.
5111 + If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
5112 + for any hard reg, then this must be 0 for correct output. */
5113 +#define MODES_TIEABLE_P(MODE1, MODE2) 1
5115 +/* A C expression for the cost of moving data of mode mode from a register in
5116 + class "from" to one in class "to". The classes are expressed using the
5117 + enumeration values such as GENERAL_REGS. A value of 2 is the default; other
5118 + values are interpreted relative to that.
5120 + It is not required that the cost always equal 2 when "from" is the same as
5121 + "to"; on some machines it is expensive to move between registers if they are
5122 + not general registers.
5124 + If reload sees an insn consisting of a single set between two hard
5125 + registers, and if REGISTER_MOVE_COST applied to their classes returns a
5126 + value of 2, reload does not check to ensure that the constraints of the
5127 + insn are met. Setting a cost of other than 2 will allow reload to verify
5128 + that the constraints are met. You should do this if the "movm" pattern's
5129 + constraints do not allow such copying.
5131 + JPB 31-Aug-10: This is just the default. */
5132 +#define REGISTER_MOVE_COST(mode, from, to) 2
5134 +/* A C expression for the cost of moving data of mode mode between a register
5135 + of class "class" and memory; "in" is zero if the value is to be written to
5136 + memory, nonzero if it is to be read in. This cost is relative to those in
5137 + REGISTER_MOVE_COST. If moving between registers and memory is more
5138 + expensive than between two registers, you should define this macro to
5139 + express the relative cost.
5141 + If you do not define this macro, GCC uses a default cost of 4 plus the cost
5142 + of copying via a secondary reload register, if one is needed. If your
5143 + machine requires a secondary reload register to copy between memory and a
5144 + register of class but the reload mechanism is more complex than copying via
5145 + an intermediate, define this macro to reflect the actual cost of the move.
5147 + GCC defines the function "memory_move_secondary_cost" if secondary reloads
5148 + are needed. It computes the costs due to copying via a secondary
5149 + register. If your machine copies from memory using a secondary register in
5150 + the conventional way but the default base value of 4 is not correct for
5151 + your machine, define this macro to add some other value to the result of
5152 + that function. The arguments to that function are the same as to this
5153 + macro.
5155 + JPB 31-Aug-10. Is this really correct? I suppose the OR1K only takes one
5156 + cycle, notionally, to access memory, but surely that will
5157 + often stall the pipeline. Needs more investigation. */
5158 +#define MEMORY_MOVE_COST(mode, class, in) 2
5160 +/* A C expression for the cost of a branch instruction. A value of 1 is the
5161 + default; other values are interpreted relative to that. Parameter "speed_p"
5162 + is TRUE when the branch in question should be optimized for speed. When it
5163 + is FALSE, BRANCH_COST should be returning value optimal for code size
5164 + rather then performance considerations. "predictable_p" is true for well
5165 + predictable branches. On many architectures the BRANCH_COST can be reduced
5166 + then.
5168 + JPB 31-Aug-10. The original code had the comment that "... this should
5169 + specify the cost of a branch insn; roughly the number of
5170 + extra insns that should be added to avoid a branch.
5172 + Set this to 3 on the or1k since that is roughly the average
5173 + cost of an unscheduled conditional branch.
5175 + Cost of 2 and 3 give equal and ~0.7% bigger binaries
5176 + respectively."
5178 + This seems ad-hoc. Probably we need some experiments. */
5179 +#define BRANCH_COST(speed_p, predictable_p) 2
5181 +/* Specify the registers used for certain standard purposes.
5182 + The values of these macros are register numbers. */
5184 +/* Register to use for pushing function arguments. */
5185 +#define STACK_POINTER_REGNUM 1
5187 +/* Base register for access to local variables of the function. */
5188 +#define HARD_FRAME_POINTER_REGNUM 2
5190 +/* Link register. */
5191 +#define LINK_REGNUM 9
5193 +/* Register in which static-chain is passed to a function. */
5195 +#define STATIC_CHAIN_REGNUM 11
5197 +#define PROLOGUE_TMP 13
5198 +#define EPILOGUE_TMP 3
5200 +/* Register in which address to store a structure value
5201 + is passed to a function. */
5202 +/*#define STRUCT_VALUE_REGNUM 0*/
5204 +/* Pass address of result struct to callee as "invisible" first argument */
5205 +#define STRUCT_VALUE 0
5207 +/* -----------------------[ PHX start ]-------------------------------- */
5209 +/* Define the classes of registers for register constraints in the
5210 + machine description. Also define ranges of constants.
5212 + One of the classes must always be named ALL_REGS and include all hard regs.
5213 + If there is more than one class, another class must be named NO_REGS
5214 + and contain no registers.
5216 + The name GENERAL_REGS must be the name of a class (or an alias for
5217 + another name such as ALL_REGS). This is the class of registers
5218 + that is allowed by "g" or "r" in a register constraint.
5219 + Also, registers outside this class are allocated only when
5220 + instructions express preferences for them.
5222 + GENERAL_REGS and BASE_REGS classess are the same on or1k.
5224 + The classes must be numbered in nondecreasing order; that is,
5225 + a larger-numbered class must never be contained completely
5226 + in a smaller-numbered class.
5228 + For any two classes, it is very desirable that there be another
5229 + class that represents their union. */
5231 +/* The or1k has only one kind of registers, so NO_REGS, GENERAL_REGS
5232 + and ALL_REGS are the only classes. */
5233 +/* JPB 26-Aug-10: Based on note from Mikhael (mirekez@gmail.com), we don't
5234 + need CR_REGS and it is in the wrong place for later things! */
5235 +enum reg_class
5237 + NO_REGS,
5238 + GENERAL_REGS,
5239 + ALL_REGS,
5240 + LIM_REG_CLASSES
5243 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
5245 +/* Give names of register classes as strings for dump file. */
5246 +#define REG_CLASS_NAMES \
5247 +{ \
5248 + "NO_REGS", \
5249 + "GENERAL_REGS", \
5250 + "ALL_REGS" \
5253 +/* Define which registers fit in which classes. This is an initializer for a
5254 + vector of HARD_REG_SET of length N_REG_CLASSES.
5256 + An initializer containing the contents of the register classes, as integers
5257 + which are bit masks. The Nth integer specifies the contents of class N.
5258 + The way the integer MASK is interpreted is that register R is in the class
5259 + if `MASK & (1 << R)' is 1.
5261 + When the machine has more than 32 registers, an integer does not suffice.
5262 + Then the integers are replaced by sub-initializers, braced groupings
5263 + containing several integers. Each sub-initializer must be suitable as an
5264 + initializer for the type `HARD_REG_SET' which is defined in
5265 + `hard-reg-set.h'.
5267 + For the OR1K we have the minimal set. GENERAL_REGS is all except r0, which
5268 + it permanently zero. */
5269 +#define REG_CLASS_CONTENTS \
5270 + { \
5271 + { 0x00000000, 0x00000000 }, /* NO_REGS */ \
5272 + { 0xffffffff, 0x00000003 }, /* GENERAL_REGS */ \
5273 + { 0xffffffff, 0x00000007 } /* ALL_REGS */ \
5276 +/* The same information, inverted:
5278 + Return the class number of the smallest class containing reg number REGNO.
5279 + This could be a conditional expression or could index an array.
5281 + ??? 0 is not really a register, but a constant. */
5282 +#define REGNO_REG_CLASS(regno) \
5283 + ((0 == regno) ? ALL_REGS : ((1 <= regno) && (regno <= OR1K_LAST_INT_REG)) \
5284 + ? GENERAL_REGS : NO_REGS)
5286 +/* The class value for index registers, and the one for base regs. */
5287 +#define INDEX_REG_CLASS GENERAL_REGS
5288 +#define BASE_REG_CLASS GENERAL_REGS
5290 +/* Given an rtx X being reloaded into a reg required to be in class CLASS,
5291 + return the class of reg to actually use. In general this is just CLASS;
5292 + but on some machines in some cases it is preferable to use a more
5293 + restrictive class. */
5294 +#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
5296 +/* Return the maximum number of consecutive registers needed to represent mode
5297 + MODE in a register of class CLASS.
5299 + On the or1k, this is always the size of MODE in words, since all registers
5300 + are the same size. */
5301 +#define CLASS_MAX_NREGS(CLASS, MODE) \
5302 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
5305 +/* -------------------------------------------------------------------------- */
5306 +/* Stack layout; function entry, exit and calling. */
5308 +/* Define this if pushing a word on the stack makes the stack pointer a
5309 + smaller address. */
5310 +#define STACK_GROWS_DOWNWARD 1
5312 +/* Define this if the nominal address of the stack frame is at the
5313 + high-address end of the local variables; that is, each additional local
5314 + variable allocated goes at a more negative offset in the frame. */
5315 +#define FRAME_GROWS_DOWNWARD 1
5317 +/* Offset within stack frame to start allocating local variables at. If
5318 + FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local
5319 + allocated. Otherwise, it is the offset to the BEGINNING of the first local
5320 + allocated. */
5321 +#define STARTING_FRAME_OFFSET 0
5323 +/* Offset of first parameter from the argument pointer register value. */
5324 +#define FIRST_PARM_OFFSET(FNDECL) 0
5326 +/* Define this if stack space is still allocated for a parameter passed
5327 + in a register. The value is the number of bytes allocated to this
5328 + area.
5330 + No such allocation for OR1K. */
5331 +/* #define REG_PARM_STACK_SPACE(FNDECL) (UNITS_PER_WORD * GP_ARG_NUM_REG) */
5333 +/* Define this if the above stack space is to be considered part of the
5334 + space allocated by the caller.
5336 + N/a for OR1K. */
5337 +/* #define OUTGOING_REG_PARM_STACK_SPACE */
5339 +/* Define this macro if `REG_PARM_STACK_SPACE' is defined, but the
5340 + stack parameters don't skip the area specified by it.
5342 + N/a for OR1K. */
5343 +/* #define STACK_PARMS_IN_REG_PARM_AREA */
5345 +/* If nonzero, the maximum amount of space required for outgoing arguments
5346 + will be computed and placed into the variable
5347 + current_function_outgoing_args_size. No space will be pushed onto the stack
5348 + for each call; instead, the function prologue should increase the stack
5349 + frame size by this amount.
5351 + Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper.
5353 + This is the approached used by OR1K. */
5354 +#define ACCUMULATE_OUTGOING_ARGS 1
5356 +#define ELIMINABLE_REGS \
5357 +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
5358 + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
5359 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
5360 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
5362 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
5363 + (OFFSET) = or1k_initial_elimination_offset ((FROM), (TO))
5365 +/* Minimum and maximum general purpose registers used to hold arguments. */
5366 +#define GP_ARG_MIN_REG 3
5367 +#define GP_ARG_MAX_REG 8
5368 +#define GP_ARG_NUM_REG (GP_ARG_MAX_REG - GP_ARG_MIN_REG + 1)
5370 +/* Return register */
5371 +#define GP_ARG_RETURN 11
5372 +#define GP_ARG_RETURNH 12
5374 +/* TLS thread pointer register */
5375 +#define THREAD_PTR_REGNUM 10
5377 +/* Position Independent Code. */
5379 +#define PIC_OFFSET_TABLE_REGNUM 16
5381 +/* A C expression that is nonzero if X is a legitimate immediate
5382 + operand on the target machine when generating position independent code.
5383 + You can assume that X satisfies CONSTANT_P, so you need not
5384 + check this. You can also assume `flag_pic' is true, so you need not
5385 + check it either. You need not define this macro if all constants
5386 + (including SYMBOL_REF) can be immediate operands when generating
5387 + position independent code. */
5388 +#define LEGITIMATE_PIC_OPERAND_P(X) or1k_legitimate_pic_operand_p (X)
5390 +/* A C expression to create an RTX representing the place where a library
5391 + function returns a value of mode mode.
5393 + Note that “library function” in this context means a compiler support
5394 + routine, used to perform arithmetic, whose name is known specially by the
5395 + compiler and was not mentioned in the C code being compiled.
5397 + For the OR1K, return value is in R11 (GP_ARG_RETURN). */
5398 +#define LIBCALL_VALUE(mode) \
5399 + gen_rtx_REG( \
5400 + ((GET_MODE_CLASS (mode) != MODE_INT \
5401 + || GET_MODE_SIZE (mode) >= 4) \
5402 + ? (mode) \
5403 + : SImode), \
5404 + GP_ARG_RETURN)
5406 +/* Define this if PCC uses the nonreentrant convention for returning
5407 + structure and union values.
5409 + Not needed for OR1K. */
5410 +/*#define PCC_STATIC_STRUCT_RETURN */
5412 +/* A C expression that is nonzero if regno is the number of a hard register in
5413 + which the values of called function may come back.
5415 + A register whose use for returning values is limited to serving as the
5416 + second of a pair (for a value of type double, say) need not be recognized
5417 + by this macro. So for most machines, this definition suffices:
5419 + #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
5421 + If the machine has register windows, so that the caller and the called
5422 + function use different registers for the return value, this macro should
5423 + recognize only the caller's register numbers.
5425 + For OR1K, we must check if we have the return register.
5427 + From GCC 4.6, this will be replaced by TARGET_FUNCION_VALUE_REGNO_P target
5428 + hook function. */
5429 +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN)
5431 +/* 1 if N is a possible register number for function argument passing. */
5432 +#define FUNCTION_ARG_REGNO_P(N) \
5433 + ((N) >= GP_ARG_MIN_REG && (N) <= GP_ARG_MAX_REG)
5435 +/* A code distinguishing the floating point format of the target
5436 + machine. There are three defined values: IEEE_FLOAT_FORMAT,
5437 + VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT. */
5438 +#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
5439 +#define FLOAT_WORDS_BIG_ENDIAN 1
5441 +/* A C type for declaring a variable that is used as the first argument of
5442 + FUNCTION_ARG and other related values. For some target machines, the type
5443 + int suffices and can hold the number of bytes of argument so far.
5445 + There is no need to record in CUMULATIVE_ARGS anything about the arguments
5446 + that have been passed on the stack. The compiler has other variables to
5447 + keep track of that. For target machines on which all arguments are passed
5448 + on the stack, there is no need to store anything in CUMULATIVE_ARGS;
5449 + however, the data structure must exist and should not be empty, so use
5450 + int. */
5451 +#define CUMULATIVE_ARGS int
5453 +/* A C statement (sans semicolon) for initializing the variable "cum" for the
5454 + state at the beginning of the argument list. The variable has type
5455 + CUMULATIVE_ARGS. The value of "fntype" is the tree node for the data type
5456 + of the function which will receive the args, or 0 if the args are to a
5457 + compiler support library function. For direct calls that are not libcalls,
5458 + "fndecl" contain the declaration node of the function. "fndecl" is also set
5459 + when INIT_CUMULATIVE_ARGS is used to find arguments for the function being
5460 + compiled. "n_named_args" is set to the number of named arguments,
5461 + including a structure return address if it is passed as a parameter, when
5462 + making a call. When processing incoming arguments, "n_named_args" is set to
5463 + −1.
5465 + When processing a call to a compiler support library function, "libname"
5466 + identifies which one. It is a symbol_ref rtx which contains the name of the
5467 + function, as a string. "libname" is 0 when an ordinary C function call is
5468 + being processed. Thus, each time this macro is called, either "libname" or
5469 + "fntype" is nonzero, but never both of them at once.
5471 + For the OR1K, we set "cum" to zero each time.
5472 + JPB 29-Aug-10: Is this correct? */
5473 +#define INIT_CUMULATIVE_ARGS(cum, fntype, libname, fndecl, n_named_args) \
5474 + (cum = 0)
5476 +/* -------------------------------------------------------------------------- */
5477 +/* Define intermediate macro to compute the size (in registers) of an argument
5478 + for the or1k.
5480 + The OR1K_ROUND_ADVANCE* macros are local to this file. */
5482 +/* Round "size" up to a word boundary. */
5483 +#define OR1K_ROUND_ADVANCE(size) \
5484 + (((size) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
5486 +/* Round arg "mode"/"type" up to the next word boundary. */
5487 +#define OR1K_ROUND_ADVANCE_ARG(mode, type) \
5488 + ((mode) == BLKmode \
5489 + ? OR1K_ROUND_ADVANCE (int_size_in_bytes (type)) \
5490 + : OR1K_ROUND_ADVANCE (GET_MODE_SIZE (mode)))
5492 +/* The ABI says that no rounding to even or odd words takes place. */
5493 +#define OR1K_ROUND_ADVANCE_CUM(cum, mode, type) (cum)
5495 +/* Return boolean indicating if arg of type "type" and mode "mode" will be
5496 + passed in a reg. This includes arguments that have to be passed by
5497 + reference as the pointer to them is passed in a reg if one is available
5498 + (and that is what we're given).
5500 + When passing arguments "named" is always 1. When receiving arguments
5501 + "named" is 1 for each argument except the last in a stdarg/varargs
5502 + function. In a stdarg function we want to treat the last named arg as
5503 + named. In a varargs function we want to treat the last named arg (which is
5504 + `__builtin_va_alist') as unnamed.
5506 + This macro is only used in this file. */
5507 +#define OR1K_PASS_IN_REG_P(cum, mode, type, named) \
5508 + ((named) \
5509 + && ((OR1K_ROUND_ADVANCE_CUM ((cum), (mode), (type)) \
5510 + + OR1K_ROUND_ADVANCE_ARG ((mode), (type)) \
5511 + <= GP_ARG_NUM_REG)))
5513 +/* Output assembler code to FILE to increment profiler label # LABELNO
5514 + for profiling a function entry. */
5515 +#define FUNCTION_PROFILER(FILE, LABELNO)
5517 +/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the
5518 + stack pointer does not matter. The value is tested only in functions that
5519 + have frame pointers. No definition is equivalent to always zero.
5521 + The default suffices for OR1K. */
5522 +#define EXIT_IGNORE_STACK 0
5524 +/* A C expression whose value is RTL representing the location of the
5525 + incoming return address at the beginning of any function, before the
5526 + prologue. This RTL is either a REG, indicating that the return
5527 + value is saved in REG, or a MEM representing a location in
5528 + the stack. */
5529 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)
5531 +#define RETURN_ADDR_RTX or1k_return_addr_rtx
5533 +/* Addressing modes, and classification of registers for them. */
5535 +/* #define HAVE_POST_INCREMENT */
5536 +/* #define HAVE_POST_DECREMENT */
5538 +/* #define HAVE_PRE_DECREMENT */
5539 +/* #define HAVE_PRE_INCREMENT */
5541 +/* Macros to check register numbers against specific register classes. */
5542 +#define MAX_REGS_PER_ADDRESS 1
5544 +/* True if X is an rtx for a constant that is a valid address.
5546 + JPB 29-Aug-10: Why is the default implementation not OK? */
5547 +#define CONSTANT_ADDRESS_P(X) \
5548 + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
5549 + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
5550 + || GET_CODE (X) == HIGH)
5552 +/* A C expression which is nonzero if register number num is suitable for use
5553 + as a base register in operand addresses. Like TARGET_LEGITIMATE_ADDRESS_P,
5554 + this macro should also define a strict and a non-strict variant. Both
5555 + variants behave the same for hard register; for pseudos, the strict variant
5556 + will pass only those that have been allocated to a valid hard registers,
5557 + while the non-strict variant will pass all pseudos.
5559 + Compiler source files that want to use the strict variant of this and other
5560 + macros define the macro REG_OK_STRICT. You should use an #ifdef
5561 + REG_OK_STRICT conditional to define the strict variant in that case and the
5562 + non-strict variant otherwise.
5564 + JPB 29-Aug-10: This has been conflated with the old REG_OK_FOR_BASE_P
5565 + function, which is no longer part of GCC.
5567 + I'm not sure this is right. r0 can be a base register, just
5568 + it can't get set by the user. */
5569 +#ifdef REG_OK_STRICT
5570 +#define REGNO_OK_FOR_BASE_P(num) \
5571 + ( ((0 < (num)) && ((num) <= OR1K_LAST_INT_REG)) \
5572 + || ((0 < reg_renumber[num]) && (reg_renumber[num] <= OR1K_LAST_INT_REG)))
5574 +#else
5575 +/* Accept an int register or a pseudo reg.
5577 + JPB 1-Sep-10: Should this allow r0, if the strict version does not? */
5578 +#define REGNO_OK_FOR_BASE_P(num) ((num) <= OR1K_LAST_INT_REG || \
5579 + (num) >= FIRST_PSEUDO_REGISTER)
5580 +#endif
5582 +/* OR1K doesn't have any indexed addressing. */
5583 +#define REG_OK_FOR_INDEX_P(X) 0
5584 +#define REGNO_OK_FOR_INDEX_P(X) 0
5587 +/* Specify the machine mode that this machine uses for the index in the
5588 + tablejump instruction. */
5589 +#define CASE_VECTOR_MODE SImode
5591 +/* Define as C expression which evaluates to nonzero if the tablejump
5592 + instruction expects the table to contain offsets from the address of the
5593 + table.
5595 + Do not define this if the table should contain absolute addresses. */
5596 +/* #define CASE_VECTOR_PC_RELATIVE 1 */
5598 +/* Define this as 1 if `char' should by default be signed; else as 0. */
5599 +#define DEFAULT_SIGNED_CHAR 1
5601 +/* The maximum number of bytes that a single instruction can move quickly
5602 + between memory and registers or between two memory locations. */
5603 +#define MOVE_MAX 4
5605 +/* Define this if zero-extension is slow (more than one real instruction). */
5606 +/* #define SLOW_ZERO_EXTEND */
5608 +/* Nonzero if access to memory by bytes is slow and undesirable.
5609 + For RISC chips, it means that access to memory by bytes is no
5610 + better than access by words when possible, so grab a whole word
5611 + and maybe make use of that. */
5612 +#define SLOW_BYTE_ACCESS 1
5614 +/* Define if shifts truncate the shift count
5615 + which implies one can omit a sign-extension or zero-extension
5616 + of a shift count. */
5617 +/* #define SHIFT_COUNT_TRUNCATED */
5619 +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
5620 + is done just by pretending it is already truncated. */
5621 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
5623 +/* Specify the machine mode that pointers have.
5624 + After generation of rtl, the compiler makes no further distinction
5625 + between pointers and any other objects of this machine mode. */
5626 +#define Pmode SImode
5628 +/* A function address in a call instruction
5629 + is a byte address (for indexing purposes)
5630 + so give the MEM rtx a byte's mode. */
5631 +#define FUNCTION_MODE SImode
5634 +/* -------------------------------------------------------------------------- */
5635 +/* Condition code stuff */
5637 +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
5638 + return the mode to be used for the comparison. */
5639 +#define SELECT_CC_MODE(op, x, y) or1k_select_cc_mode(op)
5641 +/* Can the condition code MODE be safely reversed? This is safe in
5642 + all cases on this port, because at present it doesn't use the
5643 + trapping FP comparisons (fcmpo). */
5644 +#define REVERSIBLE_CC_MODE(mode) 1
5646 +/* Given a condition code and a mode, return the inverse condition.
5648 + JPB 31-Aug-10: This seems like the default. Do we even need this? */
5649 +#define REVERSE_CONDITION(code, mode) reverse_condition (code)
5652 +/* -------------------------------------------------------------------------- */
5653 +/* Control the assembler format that we output. */
5655 +/* A C string constant describing how to begin a comment in the target
5656 + assembler language. The compiler assumes that the comment will end at
5657 + the end of the line. */
5658 +#define ASM_COMMENT_START "#"
5660 +/* Output to assembler file text saying following lines may contain character
5661 + constants, extra white space, comments, etc.
5663 + JPB 29-Aug-10: Default would seem to be OK here. */
5664 +#define ASM_APP_ON "#APP\n"
5666 +/* Output to assembler file text saying following lines no longer contain
5667 + unusual constructs.
5669 + JPB 29-Aug-10: Default would seem to be OK here. */
5670 +#define ASM_APP_OFF "#NO_APP\n"
5672 +/* Switch to the text or data segment. */
5674 +/* Output before read-only data. */
5675 +#define TEXT_SECTION_ASM_OP "\t.section .text"
5677 +/* Output before writable data. */
5678 +#define DATA_SECTION_ASM_OP "\t.section .data"
5680 +/* Output before uninitialized data. */
5681 +#define BSS_SECTION_ASM_OP "\t.section .bss"
5683 +/* How to refer to registers in assembler output. This sequence is indexed by
5684 + compiler's hard-register-number (see above). */
5685 +#define REGISTER_NAMES \
5686 + {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
5687 + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
5688 + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
5689 + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
5690 + "argp", "frame", "cc-flag"}
5693 +/* -------------------------------------------------------------------------- */
5694 +/* Debug things for DBX (STABS) */
5695 +/* */
5696 +/* Note. Our config.gcc includes dbxelf.h, which sets up appropriate */
5697 +/* defaults. Choice of which debug format to use is in our elf.h */
5698 +/* -------------------------------------------------------------------------- */
5700 +/* Don't try to use the type-cross-reference character in DBX data.
5701 + Also has the consequence of putting each struct, union or enum
5702 + into a separate .stabs, containing only cross-refs to the others. */
5703 +/* JPB 24-Aug-10: Is this really correct. Can't GDB use this info? */
5704 +#define DBX_NO_XREFS
5706 +/* -------------------------------------------------------------------------- */
5707 +/* Debug things for DWARF2 */
5708 +/* */
5709 +/* Note. Choice of which debug format to use is in our elf.h */
5710 +/* -------------------------------------------------------------------------- */
5712 +/* We support frame unwind info including for exceptions handling. This needs
5713 + INCOMING_RETURN_ADDR_RTX to be set and OBJECT_FORMAT_ELF to be defined (in
5714 + elfos.h). Override any default value. */
5715 +#undef DWARF2_UNWIND_INFO
5716 +#define DWARF2_UNWIND_INFO 1
5718 +/* We want frame info produced. Note that this is superfluous if
5719 + DWARF2_UNWIND_INFO is non-zero, but we set so this so, we can produce frame
5720 + info even when it is zero. Override any default value. */
5721 +#undef DWARF2_FRAME_INFO
5722 +#define DWARF2_FRAME_INFO 1
5724 +/* Macro specifying which register holds the return address */
5725 +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNUM)
5727 +/* Where is the start of our stack frame in relation to the end of the
5728 + previous stack frame at the start of a function, before the prologue */
5729 +#define INCOMING_FRAME_SP_OFFSET 0
5731 +/* Use compact debug tables. Generates .file/.loc directives. */
5732 +#undef DWARF2_ASM_LINE_DEBUG_INFO
5733 +#define DWARF2_ASM_LINE_DEBUG_INFO 1
5735 +/* We don't need an alternative return address for now. */
5736 +/* DWARF_ALT_FRAME_RETURN_COLUMN */
5738 +/* We always save registers in the prologue with word alignment, so don't
5739 + need this. */
5740 +/* DWARF_CIE_DATA_ALIGNMENT */
5742 +/* This specifies the maximum number of registers we can save in a frame. We
5743 + could note that only SP, FP, LR, arg regs and callee saved regs come into
5744 + this category. However this is only an efficiency thing, so for now we
5745 + don't use it. */
5746 +/* DWARF_FRAME_REGISTERS */
5748 +/* This specifies a mapping from register numbers in .dwarf_frame to
5749 + .eh_frame. However for us they are the same, so we don't need it. */
5750 +/* DWARF_FRAME_REGNUM */
5752 +/* Defined if the DWARF column numbers do not match register numbers. For us
5753 + they do, so this is not needed. */
5754 +/* DWARF_REG_TO_UNWIND_COLUMN */
5756 +/* Can be used to define a register guaranteed to be zero. Only useful if zero
5757 + is used to terminate backtraces, and not recommended for new ports, so we
5758 + don't use it. */
5759 +/* DWARF_ZERO_REG */
5761 +/* This is the inverse function for DWARF_FRAME_REGNUM. Again not needed. */
5762 +/* DWARF2_FRAME_REG_OUT */
5765 +/* -------------------------------------------------------------------------- */
5766 +/* Node: Label Output */
5768 +/* Globalizing directive for a label. */
5769 +#define GLOBAL_ASM_OP "\t.global "
5771 +#define SUPPORTS_WEAK 1
5773 +/* This is how to output the definition of a user-level label named NAME,
5774 + such as the label on a static function or variable NAME. */
5775 +#define ASM_OUTPUT_LABEL(FILE,NAME) \
5776 + { assemble_name (FILE, NAME); fputs (":\n", FILE); }
5778 +/* We use -fleading-underscore to add it, when necessary.
5779 + JPB: No prefix for global symbols */
5780 +#define USER_LABEL_PREFIX ""
5782 +/* Remove any previous definition (elfos.h). */
5783 +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
5784 + sprintf (LABEL, "*%s%d", PREFIX, NUM)
5786 +/* This is how to output an assembler line defining an int constant. */
5787 +#define ASM_OUTPUT_INT(stream, value) \
5788 + { \
5789 + fprintf (stream, "\t.word\t"); \
5790 + output_addr_const (stream, (value)); \
5791 + fprintf (stream, "\n")}
5793 +/* This is how to output an assembler line defining a float constant. */
5794 +#define ASM_OUTPUT_FLOAT(stream, value) \
5795 + { long l; \
5796 + REAL_VALUE_TO_TARGET_SINGLE (value,l); \
5797 + fprintf(stream,"\t.word\t0x%08x\t\t# float %26.7e\n", l, value); }
5799 +/* This is how to output an assembler line defining a double constant. */
5800 +#define ASM_OUTPUT_DOUBLE(stream, value) \
5801 + { long l[2]; \
5802 + REAL_VALUE_TO_TARGET_DOUBLE (value,&l[0]); \
5803 + fprintf(stream,"\t.word\t0x%08x,0x%08x\t# float %26.16le\n", \
5804 + l[0],l[1],value); }
5806 +/* This is how to output an assembler line defining a long double constant.
5808 + JPB 29-Aug-10: Do we really mean this. I thought long double on OR1K was
5809 + the same as double. */
5810 +#define ASM_OUTPUT_LONG_DOUBLE(stream, value) \
5811 + { long l[4]; \
5812 + REAL_VALUE_TO_TARGET_DOUBLE (value,&l[0]); \
5813 + fprintf (stream, \
5814 + "\t.word\t0x%08x,0x%08x,0x%08x,0x%08x\t# float %26.18lle\n", \
5815 + l[0],l[1],l[2],l[3],value); }
5817 +/* This is how to output an assembler line defining a short constant. */
5818 +#define ASM_OUTPUT_SHORT(stream, value) \
5819 + { fprintf (stream, "\t.half\t"); \
5820 + output_addr_const (stream, (value)); \
5821 + fprintf (stream, "\n"); }
5823 +/* This is how to output an assembler line defining a char constant. */
5824 +#define ASM_OUTPUT_CHAR(stream, value) \
5825 + { fprintf (stream, "\t.byte\t"); \
5826 + output_addr_const (stream, (value)); \
5827 + fprintf (stream, "\n")}
5829 +/* This is how to output an assembler line for a numeric constant byte. */
5830 +#define ASM_OUTPUT_BYTE(stream, value) \
5831 + fprintf (stream, "\t.byte\t0x%02x\n", (value))
5833 +/* This is how to output an insn to push a register on the stack.
5834 + It need not be very fast code.
5836 + JPB 29-Aug-10: This was using l.sub (since we don't have l.subi), so it
5837 + was potty code. Replaced by adding immediate -1. */
5838 +#define ASM_OUTPUT_REG_PUSH(stream, regno) \
5839 + { fprintf (stream, "\tl.addi\tr1,r1,-4\n"); \
5840 + fprintf (stream, "\tl.sw\t0(r1),%s\n", reg_names[regno]); }
5842 +/* This is how to output an insn to pop a register from the stack.
5843 + It need not be very fast code. */
5844 +#define ASM_OUTPUT_REG_POP(stream,REGNO) \
5845 + { fprintf (stream, "\tl.lwz\t%s,0(r1)\n", reg_names[REGNO]); \
5846 + fprintf (stream, "\tl.addi\tr1,r1,4\n"); }
5848 +/* This is how to output an element of a case-vector that is absolute.
5849 + (The Vax does not use such vectors,
5850 + but we must define this macro anyway.) */
5851 +#define ASM_OUTPUT_ADDR_VEC_ELT(stream, value) \
5852 + fprintf (stream, "\t.word\t.L%d\n", value)
5854 +/* This is how to output an element of a case-vector that is relative. */
5855 +#define ASM_OUTPUT_ADDR_DIFF_ELT(stream, body, value, rel) \
5856 + fprintf (stream, "\t.word\t.L%d-.L%d\n", value, rel)
5858 +#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
5859 +/* ??? If we were serious about PIC, we should also use l.jal to get
5860 + the table start address. */
5862 +/* This is how to output an assembler line that says to advance the location
5863 + counter to a multiple of 2**log bytes. */
5864 +#define ASM_OUTPUT_ALIGN(stream, log) \
5865 + if ((log) != 0) \
5866 + { \
5867 + fprintf (stream, "\t.align\t%d\n", 1 << (log)); \
5870 +/* This is how to output an assembler line that says to advance the location
5871 + counter by "size" bytes. */
5872 +#define ASM_OUTPUT_SKIP(stream, size) \
5873 + fprintf (stream, "\t.space %d\n", (size))
5875 +/* Need to split up .ascii directives to avoid breaking
5876 + the linker. */
5878 +/* This is how to output a string. */
5879 +#define ASM_OUTPUT_ASCII(stream, ptr, len) \
5880 + output_ascii_pseudo_op (stream, (const unsigned char *) (ptr), len)
5882 +/* Invoked just before function output. */
5883 +#define ASM_OUTPUT_FUNCTION_PREFIX(stream, fnname) \
5884 + { fputs (".proc\t", stream); assemble_name (stream, fnname); \
5885 + fputs ("\n", stream); }
5887 +/* This says how to output an assembler line to define a global common
5888 + symbol. */
5889 +#define ASM_OUTPUT_COMMON(stream,name,size,rounded) \
5890 + { data_section (); \
5891 + fputs ("\t.global\t", stream); \
5892 + assemble_name(stream, name); \
5893 + fputs ("\n", stream); \
5894 + assemble_name (stream, name); \
5895 + fputs (":\n", stream); \
5896 + fprintf (stream, "\t.space\t%d\n", rounded); }
5898 +/* This says how to output an assembler line to define a local common
5899 + symbol.
5901 + JPB 29-Aug-10: I'm sure this doesn't work - we don't have a .bss directive
5902 + like this. */
5903 +#define ASM_OUTPUT_LOCAL(stream, name, size, rounded) \
5904 + { fputs ("\t.bss\t", (stream)); \
5905 + assemble_name ((stream), (name)); \
5906 + fprintf ((stream), ",%d,%d\n", (size), (rounded)); }
5908 +/* This says how to output an assembler line to define a global common symbol
5909 + with size "size" (in bytes) and alignment "align" (in bits). */
5910 +#define ASM_OUTPUT_ALIGNED_COMMON(stream, name, size, align) \
5911 + { data_section(); \
5912 + if ((ALIGN) > 8) \
5913 + { \
5914 + fprintf(stream, "\t.align %d\n", ((align) / BITS_PER_UNIT)); \
5915 + } \
5916 + fputs("\t.global\t", stream); assemble_name(stream, name); \
5917 + fputs("\n", stream); \
5918 + assemble_name(stream, name); \
5919 + fputs (":\n", stream); \
5920 + fprintf(stream, "\t.space\t%d\n", size); }
5922 +/* This says how to output an assembler line to define a local common symbol
5923 + with size "size" (in bytes) and alignment "align" (in bits). */
5924 +#define ASM_OUTPUT_ALIGNED_LOCAL(stream, name, size, align) \
5925 + { data_section(); \
5926 + if ((align) > 8) \
5927 + { \
5928 + fprintf(stream, "\t.align %d\n", ((align) / BITS_PER_UNIT)); \
5929 + } \
5930 + assemble_name(stream, name); \
5931 + fputs (":\n", stream); \
5932 + fprintf(stream, "\t.space %d\n", size); }
5934 +/* Store in "output" a string (made with alloca) containing an assembler-name
5935 + for a local static variable named "name". "labelno" is an integer which is
5936 + different for each call. */
5937 +#define ASM_FORMAT_PRIVATE_NAME(output, name, labelno) \
5938 + { (output) = (char *) alloca (strlen ((name)) + 10); \
5939 + sprintf ((output), "%s.%lu", (name), (unsigned long int) (labelno)); }
5941 +/* Macro for %code validation. Returns nonzero if valid.
5943 + The acceptance of '(' is an idea taken from SPARC; output nop for %( if not
5944 + optimizing or the slot is not filled. */
5945 +#define PRINT_OPERAND_PUNCT_VALID_P(code) (('(' == code) || ('%' == code))
5947 +/* Print an instruction operand "x" on file "stream". "code" is the code from
5948 + the %-spec that requested printing this operand; if `%z3' was used to print
5949 + operand 3, then CODE is 'z'. */
5950 +#define PRINT_OPERAND(stream, x, code) \
5951 +{ \
5952 + if (code == 'r' \
5953 + && GET_CODE (x) == MEM \
5954 + && GET_CODE (XEXP (x, 0)) == REG) \
5955 + { \
5956 + fprintf (stream, "%s", reg_names[REGNO (XEXP (x, 0))]); \
5957 + } \
5958 + else if (code == '(') \
5959 + { \
5960 + if (TARGET_DELAY_ON && dbr_sequence_length ()) \
5961 + fprintf (stream, "\t# delay slot filled"); \
5962 + else if (!TARGET_DELAY_OFF) \
5963 + fprintf (stream, "\n\tl.nop\t\t\t# nop delay slot"); \
5964 + } \
5965 + else if (code == 'C') \
5966 + { \
5967 + switch (GET_CODE (x)) \
5968 + { \
5969 + case EQ: \
5970 + fputs ("eq", stream); \
5971 + break; \
5972 + case NE: \
5973 + fputs ("ne", stream); \
5974 + break; \
5975 + case GT: \
5976 + fputs ("gts", stream); \
5977 + break; \
5978 + case GE: \
5979 + fputs ("ges", stream); \
5980 + break; \
5981 + case LT: \
5982 + fputs ("lts", stream); \
5983 + break; \
5984 + case LE: \
5985 + fputs ("les", stream); \
5986 + break; \
5987 + case GTU: \
5988 + fputs ("gtu", stream); \
5989 + break; \
5990 + case GEU: \
5991 + fputs ("geu", stream); \
5992 + break; \
5993 + case LTU: \
5994 + fputs ("ltu", stream); \
5995 + break; \
5996 + case LEU: \
5997 + fputs ("leu", stream); \
5998 + break; \
5999 + default: \
6000 + abort (); \
6001 + } \
6002 + } \
6003 + else if (code == 'H') \
6004 + { \
6005 + if (GET_CODE (x) == REG) \
6006 + fprintf (stream, "%s", reg_names[REGNO (x) + 1]); \
6007 + else \
6008 + abort (); \
6009 + } \
6010 + else if (GET_CODE (x) == REG) \
6011 + fprintf (stream, "%s", reg_names[REGNO (x)]); \
6012 + else if (GET_CODE (x) == MEM) \
6013 + output_address (XEXP (x, 0)); \
6014 + else \
6015 + output_addr_const (stream, x); \
6018 +/* The size of the trampoline in bytes. This is a block of code followed by
6019 + two words specifying the function address and static chain pointer. */
6020 +#define TRAMPOLINE_SIZE \
6021 + (or1k_trampoline_code_size () + GET_MODE_SIZE (ptr_mode) * 2)
6023 +/* Alignment required for trampolines, in bits.
6025 + For the OR1K, there is no need for anything other than word alignment. */
6026 +#define TRAMPOLINE_ALIGNMENT 32
6028 +/* Assume that if the assembler supports thread local storage
6029 + * the system supports it. */
6030 +#if !defined(TARGET_HAVE_TLS) && defined(HAVE_AS_TLS)
6031 +#define TARGET_HAVE_TLS true
6032 +#endif
6034 +/* Describe how we implement __builtin_eh_return. */
6035 +#define EH_RETURN_REGNUM 23
6036 +/* Use r25, r27, r29 and r31 (clobber regs) for exception data */
6037 +#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (25 + ((N)<<1)) : INVALID_REGNUM)
6038 +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_REGNUM)
6039 +#define EH_RETURN_HANDLER_RTX or1k_eh_return_handler_rtx ()
6041 +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
6042 + (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
6044 +#define INIT_EXPANDERS or1k_init_expanders ()
6046 +/* A C structure for machine-specific, per-function data. This is
6047 + * added to the cfun structure. */
6048 +typedef struct GTY(()) machine_function
6050 + /* Force stack save of LR. Used in RETURN_ADDR_RTX. */
6051 + int force_lr_save;
6052 +} machine_function;
6054 +#endif /* _OR1K_H_ */
6055 diff -rNU3 dist.orig/gcc/config/or1k/or1k.md dist/gcc/config/or1k/or1k.md
6056 --- dist.orig/gcc/config/or1k/or1k.md 1970-01-01 01:00:00.000000000 +0100
6057 +++ dist/gcc/config/or1k/or1k.md 2015-10-18 13:19:50.000000000 +0200
6058 @@ -0,0 +1,1599 @@
6059 +;; Machine description for GNU compiler, OpenRISC 1000 family, OR32 ISA
6060 +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
6061 +;; 2009, 2010 Free Software Foundation, Inc.
6062 +;; Copyright (C) 2010 Embecosm Limited
6064 +;; Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999.
6065 +;; Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005.
6066 +;; Floating point additions by Jungsook Yang <jungsook.yang@uci.edu>
6067 +;; Julius Baxter <julius@orsoc.se> in 2010
6068 +;; Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecosm.com>
6069 +;; and Joern Rennecke <joern.rennecke@embecosm.com> in 2010
6071 +;; This file is part of GNU CC.
6073 +;; This program is free software; you can redistribute it and/or modify it
6074 +;; under the terms of the GNU General Public License as published by the Free
6075 +;; Software Foundation; either version 3 of the License, or (at your option)
6076 +;; any later version.
6078 +;; This program is distributed in the hope that it will be useful, but WITHOUT
6079 +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6080 +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
6081 +;; more details.
6083 +;; You should have received a copy of the GNU General Public License along
6084 +;; with this program. If not, see <http://www.gnu.org/licenses/>. */
6086 +(define_constants [
6087 + (SP_REG 1)
6088 + (FP_REG 2) ; hard frame pointer
6089 + (CC_REG 34)
6091 + ;; unspec values
6092 + (UNSPEC_FRAME 0)
6093 + (UNSPEC_GOT 1)
6094 + (UNSPEC_GOTOFFHI 2)
6095 + (UNSPEC_GOTOFFLO 3)
6096 + (UNSPEC_TPOFFLO 4)
6097 + (UNSPEC_TPOFFHI 5)
6098 + (UNSPEC_GOTTPOFFLO 6)
6099 + (UNSPEC_GOTTPOFFHI 7)
6100 + (UNSPEC_GOTTPOFFLD 8)
6101 + (UNSPEC_TLSGDLO 9)
6102 + (UNSPEC_TLSGDHI 10)
6103 + (UNSPEC_SET_GOT 101)
6104 + (UNSPEC_CMPXCHG 201)
6105 + (UNSPEC_FETCH_AND_OP 202)
6108 +(include "predicates.md")
6110 +(include "constraints.md")
6112 +(define_attr "type"
6113 + "unknown,load,store,move,extend,logic,add,mul,shift,compare,branch,jump,fp,jump_restore"
6114 + (const_string "unknown"))
6116 +;; Number of machine instructions required to implement an insn.
6117 +(define_attr "length" "" (const_int 1))
6119 +;; Single delay slot after branch or jump instructions, wich may contain any
6120 +;; instruction but another branch or jump.
6121 +;; If TARGET_DELAY_OFF is not true, then never use delay slots.
6122 +;; If TARGET_DELAY_ON is not true, no instruction will be allowed to
6123 +;; fill the slot, and so it will be filled by a nop instead.
6124 +(define_delay
6125 + (and (match_test "!TARGET_DELAY_OFF") (eq_attr "type" "branch,jump"))
6126 + [(and (match_test "TARGET_DELAY_ON")
6127 + (eq_attr "type" "!branch,jump")
6128 + (eq_attr "length" "1")) (nil) (nil)])
6130 +;; ALU is modelled as a single functional unit, which is reserved for varying
6131 +;; numbers of slots.
6133 +;; I think this is all incorrect for the OR1K. The latency says when the
6134 +;; result will be ready, not how long the pipeline takes to execute.
6135 +(define_cpu_unit "or1k_alu")
6136 +(define_insn_reservation "bit_unit" 3 (eq_attr "type" "shift") "or1k_alu")
6137 +(define_insn_reservation "lsu_load" 3 (eq_attr "type" "load") "or1k_alu*3")
6138 +(define_insn_reservation "lsu_store" 2 (eq_attr "type" "store") "or1k_alu")
6139 +(define_insn_reservation "alu_unit" 2
6140 + (eq_attr "type" "add,logic,extend,move,compare")
6141 + "or1k_alu")
6142 +(define_insn_reservation "mul_unit" 16 (eq_attr "type" "mul") "or1k_alu*16")
6144 +;; AI = Atomic Integers
6145 +;; We do not support DI in our atomic operations.
6146 +(define_mode_iterator AI [QI HI SI])
6148 +;; Note: We use 'mult' here for nand since it does not have its own RTX class.
6149 +(define_code_iterator atomic_op [plus minus and ior xor mult])
6150 +(define_code_attr op_name
6151 + [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "nand")])
6152 +(define_code_attr op_insn
6153 + [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "and")])
6154 +(define_code_attr post_op_insn
6155 + [(plus "") (minus "") (and "") (ior "") (xor "")
6156 + (mult "l.xori \t%3,%3,0xffff # fetch_nand: invert")])
6158 +;; Called after register allocation to add any instructions needed for the
6159 +;; prologue. Using a prologue insn is favored compared to putting all of the
6160 +;; instructions in output_function_prologue(), since it allows the scheduler
6161 +;; to intermix instructions with the saves of the caller saved registers. In
6162 +;; some cases, it might be necessary to emit a barrier instruction as the last
6163 +;; insn to prevent such scheduling.
6165 +(define_expand "prologue"
6166 + [(use (const_int 1))]
6167 + ""
6169 + or1k_expand_prologue ();
6170 + DONE;
6173 +;; Called after register allocation to add any instructions needed for the
6174 +;; epilogue. Using an epilogue insn is favored compared to putting all of the
6175 +;; instructions in output_function_epilogue(), since it allows the scheduler
6176 +;; to intermix instructions with the restores of the caller saved registers.
6177 +;; In some cases, it might be necessary to emit a barrier instruction as the
6178 +;; first insn to prevent such scheduling.
6179 +(define_expand "epilogue"
6180 + [(use (const_int 2))]
6181 + ""
6183 + or1k_expand_epilogue ();
6184 + DONE;
6187 +(define_insn "frame_alloc_fp"
6188 + [(set (reg:SI SP_REG)
6189 + (plus:SI (reg:SI SP_REG)
6190 + (match_operand:SI 0 "nonmemory_operand" "r,I")))
6191 + (clobber (mem:QI (plus:SI (reg:SI FP_REG)
6192 + (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))]
6193 + ""
6194 + "@
6195 + l.add\tr1,r1,%0\t# allocate frame
6196 + l.addi\tr1,r1,%0\t# allocate frame"
6197 + [(set_attr "type" "add")
6198 + (set_attr "length" "1")])
6200 +(define_insn "frame_dealloc_fp"
6201 + [(set (reg:SI SP_REG) (reg:SI FP_REG))
6202 + (clobber (mem:QI (plus:SI (reg:SI FP_REG)
6203 + (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))]
6204 + ""
6205 + "l.ori\tr1,r2,0\t# deallocate frame"
6206 + [(set_attr "type" "logic")
6207 + (set_attr "length" "1")])
6209 +(define_insn "frame_dealloc_sp"
6210 + [(set (reg:SI SP_REG)
6211 + (plus:SI (reg:SI SP_REG)
6212 + (match_operand:SI 0 "nonmemory_operand" "r,I")))
6213 + (clobber (mem:QI (plus:SI (reg:SI SP_REG)
6214 + (unspec:SI [(const_int SP_REG)] UNSPEC_FRAME))))]
6215 + ""
6216 + "@
6217 + l.add \tr1,r1,%0
6218 + l.addi \tr1,r1,%0"
6219 + [(set_attr "type" "add")
6220 + (set_attr "length" "1")])
6222 +(define_insn "return_internal"
6223 + [(return)
6224 + (use (match_operand 0 "pmode_register_operand" ""))]
6225 + ""
6226 + "l.jr \t%0\t# return_internal%("
6227 + [(set_attr "type" "jump")
6228 + (set_attr "length" "1")])
6233 +;; movQI
6236 +(define_expand "movqi"
6237 + [(set (match_operand:QI 0 "general_operand" "")
6238 + (match_operand:QI 1 "general_operand" ""))]
6239 + ""
6241 + if (can_create_pseudo_p())
6243 + if (GET_CODE (operands[1]) == CONST_INT)
6245 + rtx reg = gen_reg_rtx (SImode);
6247 + emit_insn (gen_movsi (reg, operands[1]));
6248 + operands[1] = gen_lowpart (QImode, reg);
6250 + if (GET_CODE (operands[1]) == MEM && optimize > 0)
6252 + rtx reg = gen_reg_rtx (SImode);
6254 + emit_insn (gen_rtx_SET (SImode, reg,
6255 + gen_rtx_ZERO_EXTEND (SImode,
6256 + operands[1])));
6258 + operands[1] = gen_lowpart (QImode, reg);
6260 + if (GET_CODE (operands[0]) != REG)
6261 + operands[1] = force_reg (QImode, operands[1]);
6265 +(define_insn "*movqi_internal"
6266 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m,r,r,r,r")
6267 + (match_operand:QI 1 "general_operand" "r,r,I,K,m"))]
6268 + ""
6269 + "@
6270 + l.sb \t%0,%1\t # movqi
6271 + l.ori \t%0,%1,0\t # movqi: move reg to reg
6272 + l.addi \t%0,r0,%1\t # movqi: move immediate
6273 + l.ori \t%0,r0,%1\t # movqi: move immediate
6274 + l.lbz \t%0,%1\t # movqi"
6275 + [(set_attr "type" "store,add,add,logic,load")])
6279 +;; movHI
6282 +(define_expand "movhi"
6283 + [(set (match_operand:HI 0 "general_operand" "")
6284 + (match_operand:HI 1 "general_operand" ""))]
6285 + ""
6287 + if (can_create_pseudo_p())
6289 + if (GET_CODE (operands[1]) == CONST_INT)
6291 + rtx reg = gen_reg_rtx (SImode);
6293 + emit_insn (gen_movsi (reg, operands[1]));
6294 + operands[1] = gen_lowpart (HImode, reg);
6296 + else if (GET_CODE (operands[1]) == MEM && optimize > 0)
6298 + rtx reg = gen_reg_rtx (SImode);
6300 + emit_insn (gen_rtx_SET (SImode, reg,
6301 + gen_rtx_ZERO_EXTEND (SImode,
6302 + operands[1])));
6303 + operands[1] = gen_lowpart (HImode, reg);
6305 + if (GET_CODE (operands[0]) != REG)
6306 + operands[1] = force_reg (HImode, operands[1]);
6310 +(define_insn "*movhi_internal"
6311 + [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r,r,r,r")
6312 + (match_operand:HI 1 "general_operand" "r,r,I,K,m"))]
6313 + ""
6314 + "@
6315 + l.sh \t%0,%1\t # movhi
6316 + l.ori \t%0,%1,0\t # movhi: move reg to reg
6317 + l.addi \t%0,r0,%1\t # movhi: move immediate
6318 + l.ori \t%0,r0,%1\t # movhi: move immediate
6319 + l.lhz \t%0,%1\t # movhi"
6320 + [(set_attr "type" "store,add,add,logic,load")])
6322 +(define_expand "movsi"
6323 + [(set (match_operand:SI 0 "general_operand" "")
6324 + (match_operand:SI 1 "general_operand" ""))]
6325 + ""
6327 + if (or1k_expand_move (SImode, operands)) DONE;
6331 +;; movSI
6334 +(define_insn "*movsi_insn"
6335 + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
6336 + (match_operand:SI 1 "input_operand" "I,K,M,r,m,r"))]
6337 + "(register_operand (operands[0], SImode)
6338 + || (register_operand (operands[1], SImode))
6339 + || (operands[1] == const0_rtx))"
6340 + "@
6341 + l.addi \t%0,r0,%1\t # move immediate I
6342 + l.ori \t%0,r0,%1\t # move immediate K
6343 + l.movhi \t%0,hi(%1)\t # move immediate M
6344 + l.ori \t%0,%1,0\t # move reg to reg
6345 + l.lwz \t%0,%1\t # SI load
6346 + l.sw \t%0,%1\t # SI store"
6347 + [(set_attr "type" "add,load,store,add,logic,move")
6348 + (set_attr "length" "1,1,1,1,1,1")])
6350 +(define_insn "movsi_lo_sum"
6351 + [(set (match_operand:SI 0 "register_operand" "=r")
6352 + (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6353 + (match_operand:SI 2 "immediate_operand" "i")))]
6354 + ""
6355 + "l.ori \t%0,%1,lo(%2) # movsi_lo_sum"
6356 + [(set_attr "type" "logic")
6357 + (set_attr "length" "1")])
6359 +(define_insn "movsi_high"
6360 + [(set (match_operand:SI 0 "register_operand" "=r")
6361 + (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
6362 + ""
6363 + "l.movhi \t%0,hi(%1) # movsi_high"
6364 +[(set_attr "type" "move")
6365 + (set_attr "length" "1")])
6367 +(define_insn "movsi_gotofflo"
6368 + [(set (match_operand:SI 0 "register_operand" "=r")
6369 + (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6370 + (match_operand 2 "" ""))] UNSPEC_GOTOFFLO))]
6371 + "flag_pic"
6372 + "l.ori \t%0,%1,gotofflo(%2) # movsi_gotofflo"
6373 + [(set_attr "type" "logic")
6374 + (set_attr "length" "1")])
6376 +(define_insn "movsi_gotoffhi"
6377 + [(set (match_operand:SI 0 "register_operand" "=r")
6378 + (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFFHI))]
6379 + "flag_pic"
6380 + "l.movhi \t%0,gotoffhi(%1) # movsi_gotoffhi"
6381 + [(set_attr "type" "move")
6382 + (set_attr "length" "1")])
6384 +(define_insn "movsi_got"
6385 + [(set (match_operand:SI 0 "register_operand" "=r")
6386 + (unspec:SI [(match_operand 1 "symbolic_operand" "")] UNSPEC_GOT))
6387 + (use (reg:SI 16))]
6388 + "flag_pic"
6389 + "l.lwz \t%0, got(%1)(r16)"
6390 + [(set_attr "type" "load")]
6393 +(define_insn "movsi_tlsgdlo"
6394 + [(set (match_operand:SI 0 "register_operand" "=r")
6395 + (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6396 + (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TLSGDLO))]
6397 + ""
6398 + "l.ori \t%0,%1,tlsgdlo(%2) # movsi_tlsgdlo"
6399 + [(set_attr "type" "logic")
6400 + (set_attr "length" "1")])
6402 +(define_insn "movsi_tlsgdhi"
6403 + [(set (match_operand:SI 0 "register_operand" "=r")
6404 + (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TLSGDHI))]
6405 + ""
6406 + "l.movhi \t%0,tlsgdhi(%1) # movsi_tlsgdhi"
6407 +[(set_attr "type" "move")
6408 + (set_attr "length" "1")])
6410 +(define_insn "movsi_gottpofflo"
6411 + [(set (match_operand:SI 0 "register_operand" "=r")
6412 + (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6413 + (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_GOTTPOFFLO))]
6414 + ""
6415 + "l.ori \t%0,%1,gottpofflo(%2) # movsi_gottpofflo"
6416 + [(set_attr "type" "logic")
6417 + (set_attr "length" "1")])
6419 +(define_insn "movsi_gottpoffhi"
6420 + [(set (match_operand:SI 0 "register_operand" "=r")
6421 + (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_GOTTPOFFHI))]
6422 + ""
6423 + "l.movhi \t%0,gottpoffhi(%1) # movsi_gottpoffhi"
6424 +[(set_attr "type" "move")
6425 + (set_attr "length" "1")])
6427 +(define_insn "load_gottpoff"
6428 + [(set (match_operand:SI 0 "register_operand" "=r")
6429 + (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_GOTTPOFFLD))]
6430 + ""
6431 + "l.lwz \t%0,0(%1) # load_gottpoff"
6432 +[(set_attr "type" "load")
6433 + (set_attr "length" "1")])
6435 +(define_insn "movsi_tpofflo"
6436 + [(set (match_operand:SI 0 "register_operand" "=r")
6437 + (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6438 + (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TPOFFLO))]
6439 + ""
6440 + "l.ori \t%0,%1,tpofflo(%2) # movsi_tpofflo"
6441 + [(set_attr "type" "logic")
6442 + (set_attr "length" "1")])
6444 +(define_insn "movsi_tpoffhi"
6445 + [(set (match_operand:SI 0 "register_operand" "=r")
6446 + (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TPOFFHI))]
6447 + ""
6448 + "l.movhi \t%0,tpoffhi(%1) # movsi_tpoffhi"
6449 +[(set_attr "type" "move")
6450 + (set_attr "length" "1")])
6453 +(define_insn_and_split "movsi_insn_big"
6454 + [(set (match_operand:SI 0 "register_operand" "=r")
6455 + (match_operand:SI 1 "immediate_operand" "i"))]
6456 + "GET_CODE (operands[1]) != CONST_INT"
6457 + ;; the switch of or1k bfd to Rela allows us to schedule insns separately.
6458 + "l.movhi \t%0,hi(%1)\;l.ori \t%0,%0,lo(%1)"
6459 + "(GET_CODE (operands[1]) != CONST_INT
6460 + || ! (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'I', \"I\")
6461 + || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'K', \"K\")
6462 + || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'M', \"M\")))
6463 + && reload_completed
6464 + && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM"
6465 + [(pc)]
6467 + if (!or1k_expand_symbol_ref(SImode, operands))
6469 + emit_insn (gen_movsi_high (operands[0], operands[1]));
6470 + emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
6472 + DONE;
6474 + [(set_attr "type" "move")
6475 + (set_attr "length" "2")])
6479 +;; Conditional Branches & Moves
6480 +;;
6482 +(define_expand "addsicc"
6483 + [(match_operand:SI 0 "register_operand" "")
6484 + (match_operand 1 "comparison_operator" "")
6485 + (match_operand:SI 2 "register_operand" "")
6486 + (match_operand:SI 3 "register_operand" "")]
6487 + ""
6488 + "FAIL;")
6490 +(define_expand "addhicc"
6491 + [(match_operand:HI 0 "register_operand" "")
6492 + (match_operand 1 "comparison_operator" "")
6493 + (match_operand:HI 2 "register_operand" "")
6494 + (match_operand:HI 3 "register_operand" "")]
6495 + ""
6496 + "FAIL;")
6498 +(define_expand "addqicc"
6499 + [(match_operand:QI 0 "register_operand" "")
6500 + (match_operand 1 "comparison_operator" "")
6501 + (match_operand:QI 2 "register_operand" "")
6502 + (match_operand:QI 3 "register_operand" "")]
6503 + ""
6504 + "FAIL;")
6508 +;; conditional moves
6511 +(define_expand "movsicc"
6512 + [(set (match_operand:SI 0 "register_operand" "")
6513 + (if_then_else:SI (match_operand 1 "comparison_operator" "")
6514 + (match_operand:SI 2 "register_operand" "")
6515 + (match_operand:SI 3 "register_operand" "")))]
6516 + "TARGET_MASK_CMOV"
6519 + if (or1k_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
6520 + DONE;
6521 +}")
6523 +(define_expand "movhicc"
6524 + [(set (match_operand:HI 0 "register_operand" "")
6525 + (if_then_else:SI (match_operand 1 "comparison_operator" "")
6526 + (match_operand:HI 2 "register_operand" "")
6527 + (match_operand:HI 3 "register_operand" "")))]
6528 + ""
6531 + FAIL;
6532 +}")
6534 +(define_expand "movqicc"
6535 + [(set (match_operand:QI 0 "register_operand" "")
6536 + (if_then_else:SI (match_operand 1 "comparison_operator" "")
6537 + (match_operand:QI 2 "register_operand" "")
6538 + (match_operand:QI 3 "register_operand" "")))]
6539 + ""
6542 + FAIL;
6543 +}")
6546 +;; We use the BASE_REGS for the cmov input operands because, if rA is
6547 +;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
6548 +;; because we may switch the operands and rB may end up being rA.
6550 +(define_insn "cmov"
6551 + [(set (match_operand:SI 0 "register_operand" "=r")
6552 + (if_then_else:SI
6553 + (match_operator 1 "comparison_operator"
6554 + [(match_operand 4 "cc_reg_operand" "")
6555 + (const_int 0)])
6556 + (match_operand:SI 2 "register_operand" "r")
6557 + (match_operand:SI 3 "register_operand" "r")))]
6558 + "TARGET_MASK_CMOV"
6559 + "*
6560 + return or1k_output_cmov(operands);
6561 + ")
6564 +;; ....................
6566 +;; COMPARISONS
6568 +;; ....................
6570 +;; Flow here is rather complex:
6572 +;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
6573 +;; arguments into the branch_cmp array, and the type into
6574 +;; branch_type. No RTL is generated.
6576 +;; 2) The appropriate branch define_expand is called, which then
6577 +;; creates the appropriate RTL for the comparison and branch.
6578 +;; Different CC modes are used, based on what type of branch is
6579 +;; done, so that we can constrain things appropriately. There
6580 +;; are assumptions in the rest of GCC that break if we fold the
6581 +;; operands into the branches for integer operations, and use cc0
6582 +;; for floating point, so we use the fp status register instead.
6583 +;; If needed, an appropriate temporary is created to hold the
6584 +;; of the integer compare.
6586 +;; Compare insns are next. Note that the RS/6000 has two types of compares,
6587 +;; signed & unsigned, and one type of branch.
6589 +;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
6590 +;; insns, and branches. We store the operands of compares until we see
6591 +;; how it is used.
6593 +;; JPB 31-Aug-10: cmpxx appears to be obsolete in GCC 4.5. Needs more
6594 +;; investigation.
6596 +;;(define_expand "cmpsi"
6597 +;; [(set (reg:CC CC_REG)
6598 +;; (compare:CC (match_operand:SI 0 "register_operand" "")
6599 +;; (match_operand:SI 1 "nonmemory_operand" "")))]
6600 +;; ""
6601 +;; {
6602 +;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
6603 +;; operands[0] = force_reg (SImode, operands[0]);
6604 +;; or1k_compare_op0 = operands[0];
6605 +;; or1k_compare_op1 = operands[1];
6606 +;; DONE;
6607 +;; })
6609 +;; (define_expand "cmpsf"
6610 +;; [(set (reg:CC CC_REG)
6611 +;; (compare:CC (match_operand:SF 0 "register_operand" "")
6612 +;; (match_operand:SF 1 "register_operand" "")))]
6613 +;; "TARGET_HARD_FLOAT"
6614 +;; {
6615 +;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
6616 +;; operands[0] = force_reg (SFmode, operands[0]);
6617 +;; or1k_compare_op0 = operands[0];
6618 +;; or1k_compare_op1 = operands[1];
6619 +;; DONE;
6620 +;; })
6622 +(define_expand "cbranchsi4"
6623 + [(match_operator 0 "comparison_operator"
6624 + [(match_operand:SI 1 "register_operand")
6625 + (match_operand:SI 2 "nonmemory_operand")])
6626 + (match_operand 3 "")]
6627 + ""
6629 + or1k_expand_conditional_branch (operands, SImode);
6630 + DONE;
6631 + })
6633 +(define_expand "cbranchsf4"
6634 + [(match_operator 0 "comparison_operator"
6635 + [(match_operand:SF 1 "register_operand")
6636 + (match_operand:SF 2 "register_operand")])
6637 + (match_operand 3 "")]
6638 + "TARGET_HARD_FLOAT"
6640 + or1k_expand_conditional_branch (operands, SFmode);
6641 + DONE;
6642 + })
6645 +;; Setting a CCxx registers from comparision
6650 +;; Here are the actual compare insns.
6651 +(define_insn "*cmpsi_eq"
6652 + [(set (reg:CCEQ CC_REG)
6653 + (compare:CCEQ (match_operand:SI 0 "register_operand" "r,r")
6654 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6655 + ""
6656 + "@
6657 + l.sfeqi\t%0,%1 # cmpsi_eq
6658 + l.sfeq \t%0,%1 # cmpsi_eq"
6659 + [(set_attr "type" "compare")
6660 + (set_attr "length" "1")])
6662 +(define_insn "*cmpsi_ne"
6663 + [(set (reg:CCNE CC_REG)
6664 + (compare:CCNE (match_operand:SI 0 "register_operand" "r,r")
6665 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6666 + ""
6667 + "@
6668 + l.sfnei\t%0,%1 # cmpsi_ne
6669 + l.sfne \t%0,%1 # cmpsi_ne"
6670 + [(set_attr "type" "compare")
6671 + (set_attr "length" "1")])
6673 +(define_insn "*cmpsi_gt"
6674 + [(set (reg:CCGT CC_REG)
6675 + (compare:CCGT (match_operand:SI 0 "register_operand" "r,r")
6676 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6677 + ""
6678 + "@
6679 + l.sfgtsi\t%0,%1 # cmpsi_gt
6680 + l.sfgts \t%0,%1 # cmpsi_gt"
6681 + [(set_attr "type" "compare")
6682 + (set_attr "length" "1")])
6684 +(define_insn "*cmpsi_gtu"
6685 + [(set (reg:CCGTU CC_REG)
6686 + (compare:CCGTU (match_operand:SI 0 "register_operand" "r,r")
6687 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6688 + ""
6689 + "@
6690 + l.sfgtui\t%0,%1 # cmpsi_gtu
6691 + l.sfgtu \t%0,%1 # cmpsi_gtu"
6692 + [(set_attr "type" "compare")
6693 + (set_attr "length" "1")])
6695 +(define_insn "*cmpsi_lt"
6696 + [(set (reg:CCLT CC_REG)
6697 + (compare:CCLT (match_operand:SI 0 "register_operand" "r,r")
6698 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6699 + ""
6700 + "@
6701 + l.sfltsi\t%0,%1 # cmpsi_lt
6702 + l.sflts \t%0,%1 # cmpsi_lt"
6703 + [(set_attr "type" "compare")
6704 + (set_attr "length" "1")])
6706 +(define_insn "*cmpsi_ltu"
6707 + [(set (reg:CCLTU CC_REG)
6708 + (compare:CCLTU (match_operand:SI 0 "register_operand" "r,r")
6709 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6710 + ""
6711 + "@
6712 + l.sfltui\t%0,%1 # cmpsi_ltu
6713 + l.sfltu \t%0,%1 # cmpsi_ltu"
6714 + [(set_attr "type" "compare")
6715 + (set_attr "length" "1")])
6717 +(define_insn "*cmpsi_ge"
6718 + [(set (reg:CCGE CC_REG)
6719 + (compare:CCGE (match_operand:SI 0 "register_operand" "r,r")
6720 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6721 + ""
6722 + "@
6723 + l.sfgesi\t%0,%1 # cmpsi_ge
6724 + l.sfges \t%0,%1 # cmpsi_ge"
6725 + [(set_attr "type" "compare")
6726 + (set_attr "length" "1")])
6729 +(define_insn "*cmpsi_geu"
6730 + [(set (reg:CCGEU CC_REG)
6731 + (compare:CCGEU (match_operand:SI 0 "register_operand" "r,r")
6732 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6733 + ""
6734 + "@
6735 + l.sfgeui\t%0,%1 # cmpsi_geu
6736 + l.sfgeu \t%0,%1 # cmpsi_geu"
6737 + [(set_attr "type" "compare")
6738 + (set_attr "length" "1")])
6741 +(define_insn "*cmpsi_le"
6742 + [(set (reg:CCLE CC_REG)
6743 + (compare:CCLE (match_operand:SI 0 "register_operand" "r,r")
6744 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6745 + ""
6746 + "@
6747 + l.sflesi\t%0,%1 # cmpsi_le
6748 + l.sfles \t%0,%1 # cmpsi_le"
6749 + [(set_attr "type" "compare")
6750 + (set_attr "length" "1")])
6752 +(define_insn "*cmpsi_leu"
6753 + [(set (reg:CCLEU CC_REG)
6754 + (compare:CCLEU (match_operand:SI 0 "register_operand" "r,r")
6755 + (match_operand:SI 1 "nonmemory_operand" "I,r")))]
6756 + ""
6757 + "@
6758 + l.sfleui\t%0,%1 # cmpsi_leu
6759 + l.sfleu \t%0,%1 # cmpsi_leu"
6760 + [(set_attr "type" "compare")
6761 + (set_attr "length" "1")])
6763 +;; Single precision floating point evaluation instructions
6764 +(define_insn "*cmpsf_eq"
6765 + [(set (reg:CCEQ CC_REG)
6766 + (compare:CCEQ (match_operand:SF 0 "register_operand" "r,r")
6767 + (match_operand:SF 1 "register_operand" "r,r")))]
6768 + "TARGET_HARD_FLOAT"
6769 + "lf.sfeq.s\t%0,%1 # cmpsf_eq"
6770 + [(set_attr "type" "compare")
6771 + (set_attr "length" "1")])
6773 +(define_insn "*cmpsf_ne"
6774 + [(set (reg:CCNE CC_REG)
6775 + (compare:CCNE (match_operand:SF 0 "register_operand" "r,r")
6776 + (match_operand:SF 1 "register_operand" "r,r")))]
6777 + "TARGET_HARD_FLOAT"
6778 + "lf.sfne.s\t%0,%1 # cmpsf_ne"
6779 + [(set_attr "type" "compare")
6780 + (set_attr "length" "1")])
6783 +(define_insn "*cmpsf_gt"
6784 + [(set (reg:CCGT CC_REG)
6785 + (compare:CCGT (match_operand:SF 0 "register_operand" "r,r")
6786 + (match_operand:SF 1 "register_operand" "r,r")))]
6787 + "TARGET_HARD_FLOAT"
6788 + "lf.sfgt.s\t%0,%1 # cmpsf_gt"
6789 + [(set_attr "type" "compare")
6790 + (set_attr "length" "1")])
6792 +(define_insn "*cmpsf_ge"
6793 + [(set (reg:CCGE CC_REG)
6794 + (compare:CCGE (match_operand:SF 0 "register_operand" "r,r")
6795 + (match_operand:SF 1 "register_operand" "r,r")))]
6796 + "TARGET_HARD_FLOAT"
6797 + "lf.sfge.s\t%0,%1 # cmpsf_ge"
6798 + [(set_attr "type" "compare")
6799 + (set_attr "length" "1")])
6802 +(define_insn "*cmpsf_lt"
6803 + [(set (reg:CCLT CC_REG)
6804 + (compare:CCLT (match_operand:SF 0 "register_operand" "r,r")
6805 + (match_operand:SF 1 "register_operand" "r,r")))]
6806 + "TARGET_HARD_FLOAT"
6807 + "lf.sflt.s\t%0,%1 # cmpsf_lt"
6808 + [(set_attr "type" "compare")
6809 + (set_attr "length" "1")])
6811 +(define_insn "*cmpsf_le"
6812 + [(set (reg:CCLE CC_REG)
6813 + (compare:CCLE (match_operand:SF 0 "register_operand" "r,r")
6814 + (match_operand:SF 1 "register_operand" "r,r")))]
6815 + "TARGET_HARD_FLOAT"
6816 + "lf.sfle.s\t%0,%1 # cmpsf_le"
6817 + [(set_attr "type" "compare")
6818 + (set_attr "length" "1")])
6820 +(define_insn "*bf"
6821 + [(set (pc)
6822 + (if_then_else (match_operator 1 "comparison_operator"
6823 + [(match_operand 2
6824 + "cc_reg_operand" "")
6825 + (const_int 0)])
6826 + (label_ref (match_operand 0 "" ""))
6827 + (pc)))]
6828 + ""
6829 + "*
6830 + return or1k_output_bf(operands);
6832 + [(set_attr "type" "branch")
6833 + (set_attr "length" "1")])
6838 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6841 +(define_insn_and_split "movdi"
6842 + [(set (match_operand:DI 0 "nonimmediate_operand" "=r, r, m, r")
6843 + (match_operand:DI 1 "general_operand" " r, m, r, n"))]
6844 + ""
6845 + "*
6846 + return or1k_output_move_double (operands);
6848 + "&& reload_completed && CONSTANT_P (operands[1])"
6849 + [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
6850 + "operands[2] = operand_subword (operands[0], 0, 0, DImode);
6851 + operands[3] = operand_subword (operands[1], 0, 0, DImode);
6852 + operands[4] = operand_subword (operands[0], 1, 0, DImode);
6853 + operands[5] = operand_subword (operands[1], 1, 0, DImode);"
6854 + [(set_attr "length" "2,2,2,3")])
6856 +;; Moving double and single precision floating point values
6859 +(define_insn "movdf"
6860 + [(set (match_operand:DF 0 "nonimmediate_operand" "=r, r, m, r")
6861 + (match_operand:DF 1 "general_operand" " r, m, r, i"))]
6862 + ""
6863 + "*
6864 + return or1k_output_move_double (operands);
6866 + [(set_attr "length" "2,2,2,3")])
6869 +(define_insn "movsf"
6870 + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6871 + (match_operand:SF 1 "general_operand" "r,m,r"))]
6872 + ""
6873 + "@
6874 + l.ori \t%0,%1,0\t # movsf
6875 + l.lwz \t%0,%1\t # movsf
6876 + l.sw \t%0,%1\t # movsf"
6877 + [(set_attr "type" "move,load,store")
6878 + (set_attr "length" "1,1,1")])
6882 +;; extendqisi2
6885 +(define_expand "extendqisi2"
6886 + [(use (match_operand:SI 0 "register_operand" ""))
6887 + (use (match_operand:QI 1 "nonimmediate_operand" ""))]
6888 + ""
6891 + if (TARGET_MASK_SEXT)
6892 + emit_insn (gen_extendqisi2_sext(operands[0], operands[1]));
6893 + else {
6894 + if ( GET_CODE(operands[1]) == MEM ) {
6895 + emit_insn (gen_extendqisi2_no_sext_mem(operands[0], operands[1]));
6897 + else {
6898 + emit_insn (gen_extendqisi2_no_sext_reg(operands[0], operands[1]));
6901 + DONE;
6902 +}")
6904 +(define_insn "extendqisi2_sext"
6905 + [(set (match_operand:SI 0 "register_operand" "=r,r")
6906 + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
6907 + "TARGET_MASK_SEXT"
6908 + "@
6909 + l.extbs \t%0,%1\t # extendqisi2_has_signed_extend
6910 + l.lbs \t%0,%1\t # extendqisi2_has_signed_extend"
6911 + [(set_attr "length" "1,1")
6912 + (set_attr "type" "extend,load")])
6914 +(define_insn "extendqisi2_no_sext_mem"
6915 + [(set (match_operand:SI 0 "register_operand" "=r")
6916 + (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
6917 + "!TARGET_MASK_SEXT"
6918 + "l.lbs \t%0,%1\t # extendqisi2_no_sext_mem"
6919 + [(set_attr "length" "1")
6920 + (set_attr "type" "load")])
6922 +(define_expand "extendqisi2_no_sext_reg"
6923 + [(set (match_dup 2)
6924 + (ashift:SI (match_operand:QI 1 "register_operand" "")
6925 + (const_int 24)))
6926 + (set (match_operand:SI 0 "register_operand" "")
6927 + (ashiftrt:SI (match_dup 2)
6928 + (const_int 24)))]
6929 + "!TARGET_MASK_SEXT"
6932 + operands[1] = gen_lowpart (SImode, operands[1]);
6933 + operands[2] = gen_reg_rtx (SImode); }")
6936 +;; extendhisi2
6939 +(define_expand "extendhisi2"
6940 + [(use (match_operand:SI 0 "register_operand" ""))
6941 + (use (match_operand:HI 1 "nonimmediate_operand" ""))]
6942 + ""
6945 + if (TARGET_MASK_SEXT)
6946 + emit_insn (gen_extendhisi2_sext(operands[0], operands[1]));
6947 + else {
6948 + if ( GET_CODE(operands[1]) == MEM ) {
6949 + emit_insn (gen_extendhisi2_no_sext_mem(operands[0], operands[1]));
6951 + else {
6952 + emit_insn (gen_extendhisi2_no_sext_reg(operands[0], operands[1]));
6955 + DONE;
6956 +}")
6958 +(define_insn "extendhisi2_sext"
6959 + [(set (match_operand:SI 0 "register_operand" "=r,r")
6960 + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
6961 + "TARGET_MASK_SEXT"
6962 + "@
6963 + l.exths \t%0,%1\t # extendhisi2_has_signed_extend
6964 + l.lhs \t%0,%1\t # extendhisi2_has_signed_extend"
6965 + [(set_attr "length" "1,1")
6966 + (set_attr "type" "extend,load")])
6968 +(define_insn "extendhisi2_no_sext_mem"
6969 + [(set (match_operand:SI 0 "register_operand" "=r")
6970 + (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
6971 + "!TARGET_MASK_SEXT"
6972 + "l.lhs \t%0,%1\t # extendhisi2_no_sext_mem"
6973 + [(set_attr "length" "1")
6974 + (set_attr "type" "load")])
6976 +(define_expand "extendhisi2_no_sext_reg"
6977 + [(set (match_dup 2)
6978 + (ashift:SI (match_operand:HI 1 "register_operand" "")
6979 + (const_int 16)))
6980 + (set (match_operand:SI 0 "register_operand" "")
6981 + (ashiftrt:SI (match_dup 2)
6982 + (const_int 16)))]
6983 + "!TARGET_MASK_SEXT"
6986 + operands[1] = gen_lowpart (SImode, operands[1]);
6987 + operands[2] = gen_reg_rtx (SImode); }")
6991 +;; zero_extend<m><n>2
6994 +(define_insn "zero_extendqisi2"
6995 + [(set (match_operand:SI 0 "register_operand" "=r,r")
6996 + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
6997 + ""
6998 + "@
6999 + l.andi \t%0,%1,0xff\t # zero_extendqisi2
7000 + l.lbz \t%0,%1\t # zero_extendqisi2"
7001 + [(set_attr "type" "logic,load")
7002 + (set_attr "length" "1,1")])
7005 +(define_insn "zero_extendhisi2"
7006 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7007 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
7008 + ""
7009 + "@
7010 + l.andi \t%0,%1,0xffff\t # zero_extendqisi2
7011 + l.lhz \t%0,%1\t # zero_extendqisi2"
7012 + [(set_attr "type" "logic,load")
7013 + (set_attr "length" "1,1")])
7016 +;; Shift/rotate operations
7019 +(define_insn "ashlsi3"
7020 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7021 + (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
7022 + (match_operand:SI 2 "nonmemory_operand" "r,L")))]
7023 + ""
7024 + "@
7025 + l.sll \t%0,%1,%2 # ashlsi3
7026 + l.slli \t%0,%1,%2 # ashlsi3"
7027 + [(set_attr "type" "shift,shift")
7028 + (set_attr "length" "1,1")])
7030 +(define_insn "ashrsi3"
7031 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7032 + (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
7033 + (match_operand:SI 2 "nonmemory_operand" "r,L")))]
7034 + ""
7035 + "@
7036 + l.sra \t%0,%1,%2 # ashrsi3
7037 + l.srai \t%0,%1,%2 # ashrsi3"
7038 + [(set_attr "type" "shift,shift")
7039 + (set_attr "length" "1,1")])
7041 +(define_insn "lshrsi3"
7042 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7043 + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
7044 + (match_operand:SI 2 "nonmemory_operand" "r,L")))]
7045 + ""
7046 + "@
7047 + l.srl \t%0,%1,%2 # lshrsi3
7048 + l.srli \t%0,%1,%2 # lshrsi3"
7049 + [(set_attr "type" "shift,shift")
7050 + (set_attr "length" "1,1")])
7052 +(define_insn "rotrsi3"
7053 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7054 + (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
7055 + (match_operand:SI 2 "nonmemory_operand" "r,L")))]
7056 + "TARGET_MASK_ROR"
7057 + "@
7058 + l.ror \t%0,%1,%2 # rotrsi3
7059 + l.rori \t%0,%1,%2 # rotrsi3"
7060 + [(set_attr "type" "shift,shift")
7061 + (set_attr "length" "1,1")])
7064 +;; Logical bitwise operations
7067 +(define_insn "andsi3"
7068 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7069 + (and:SI (match_operand:SI 1 "register_operand" "%r,r")
7070 + (match_operand:SI 2 "nonmemory_operand" "r,K")))]
7071 + ""
7072 + "@
7073 + l.and \t%0,%1,%2 # andsi3
7074 + l.andi \t%0,%1,%2 # andsi3"
7075 + [(set_attr "type" "logic,logic")
7076 + (set_attr "length" "1,1")])
7078 +(define_insn "iorsi3"
7079 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7080 + (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
7081 + (match_operand:SI 2 "nonmemory_operand" "r,K")))]
7082 + ""
7083 + "@
7084 + l.or \t%0,%1,%2 # iorsi3
7085 + l.ori \t%0,%1,%2 # iorsi3"
7086 + [(set_attr "type" "logic,logic")
7087 + (set_attr "length" "1,1")])
7089 +(define_insn "xorsi3"
7090 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7091 + (xor:SI (match_operand:SI 1 "register_operand" "%r,r")
7092 + (match_operand:SI 2 "nonmemory_operand" "r,I")))]
7093 + ""
7094 + "@
7095 + l.xor \t%0,%1,%2 # xorsi3
7096 + l.xori \t%0,%1,%2 # xorsi3"
7097 + [(set_attr "type" "logic,logic")
7098 + (set_attr "length" "1,1")])
7100 +(define_insn "one_cmplqi2"
7101 + [(set (match_operand:QI 0 "register_operand" "=r")
7102 + (not:QI (match_operand:QI 1 "register_operand" "r")))]
7103 + ""
7104 + "l.xori \t%0,%1,0x00ff # one_cmplqi2"
7105 + [(set_attr "type" "logic")
7106 + (set_attr "length" "1")])
7108 +(define_insn "one_cmplsi2"
7109 + [(set (match_operand:SI 0 "register_operand" "=r")
7110 + (not:SI (match_operand:SI 1 "register_operand" "r")))]
7111 + ""
7112 + "l.xori \t%0,%1,0xffff # one_cmplsi2"
7113 + [(set_attr "type" "logic")
7114 + (set_attr "length" "1")])
7117 +;; Arithmetic operations
7120 +(define_insn "negsi2"
7121 + [(set (match_operand:SI 0 "register_operand" "=r")
7122 + (neg:SI (match_operand:SI 1 "register_operand" "r")))]
7123 + ""
7124 + "l.sub \t%0,r0,%1 # negsi2"
7125 + [(set_attr "type" "add")
7126 + (set_attr "length" "1")])
7128 +(define_insn "addsi3"
7129 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7130 + (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
7131 + (match_operand:SI 2 "nonmemory_operand" "r,I")))]
7132 + ""
7133 + "@
7134 + l.add \t%0,%1,%2 # addsi3
7135 + l.addi \t%0,%1,%2 # addsi3"
7136 + [(set_attr "type" "add,add")
7137 + (set_attr "length" "1,1")])
7139 +(define_insn "subsi3"
7140 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7141 + (minus:SI (match_operand:SI 1 "register_operand" "r,r")
7142 + (match_operand:SI 2 "nonmemory_operand" "r,I")))]
7143 + ""
7144 + "@
7145 + l.sub \t%0,%1,%2 # subsi3
7146 + l.addi \t%0,%1,%n2 # subsi3"
7147 + [(set_attr "type" "add,add")]
7151 +;; mul and div
7154 +(define_insn "mulsi3"
7155 + [(set (match_operand:SI 0 "register_operand" "=r")
7156 + (mult:SI (match_operand:SI 1 "register_operand" "r")
7157 + (match_operand:SI 2 "register_operand" "r")))]
7158 + "TARGET_HARD_MUL"
7159 + "l.mul \t%0,%1,%2 # mulsi3"
7160 + [(set_attr "type" "mul")
7161 + (set_attr "length" "1")])
7163 +(define_insn "divsi3"
7164 + [(set (match_operand:SI 0 "register_operand" "=r")
7165 + (div:SI (match_operand:SI 1 "register_operand" "r")
7166 + (match_operand:SI 2 "register_operand" "r")))]
7167 + "TARGET_HARD_DIV"
7168 + "l.div \t%0,%1,%2 # divsi3"
7169 + [(set_attr "type" "mul")
7170 + (set_attr "length" "1")])
7172 +(define_insn "udivsi3"
7173 + [(set (match_operand:SI 0 "register_operand" "=r")
7174 + (udiv:SI (match_operand:SI 1 "register_operand" "r")
7175 + (match_operand:SI 2 "register_operand" "r")))]
7176 + "TARGET_HARD_DIV"
7177 + "l.divu \t%0,%1,%2 # udivsi3"
7178 + [(set_attr "type" "mul")
7179 + (set_attr "length" "1")])
7182 +;; jumps
7185 +;; jump
7187 +(define_expand "jump"
7188 + [(set (pc)
7189 + (label_ref (match_operand 0 "" "")))]
7190 + ""
7193 + emit_jump_insn (gen_jump_internal (operands[0]));
7194 + DONE;
7195 +}")
7197 +(define_insn "jump_internal"
7198 + [(set (pc)
7199 + (label_ref (match_operand 0 "" "")))]
7200 + ""
7201 + "l.j \t%l0 # jump_internal%("
7202 + [(set_attr "type" "jump")
7203 + (set_attr "length" "1")])
7205 +;; indirect jump
7207 +(define_expand "indirect_jump"
7208 + [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
7209 + ""
7212 + emit_jump_insn (gen_indirect_jump_internal (operands[0]));
7213 + DONE;
7215 +}")
7217 +(define_insn "indirect_jump_internal"
7218 + [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
7219 + ""
7220 + "l.jr \t%0 # indirect_jump_internal%("
7221 + [(set_attr "type" "jump")
7222 + (set_attr "length" "1")])
7225 +;; calls
7228 +;; call
7230 +(define_expand "call"
7231 + [(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")
7232 + (match_operand 1 "" "i"))
7233 + (clobber (reg:SI 9))
7234 + (use (reg:SI 16))])]
7235 + ""
7238 + emit_call_insn (gen_call_internal (operands[0], operands[1]));
7239 + DONE;
7240 +}")
7242 +(define_insn "call_internal"
7243 +[(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "")
7244 + (match_operand 1 "" "i"))
7245 + (clobber (reg:SI 9))
7246 + (use (reg:SI 16))])]
7247 + ""
7249 + if (flag_pic)
7251 + crtl->uses_pic_offset_table = 1;
7252 + return "l.jal \tplt(%S0)# call_internal%(";
7255 + return "l.jal \t%S0# call_internal%(";
7257 + [(set_attr "type" "jump")
7258 + (set_attr "length" "1")])
7260 +;; call value
7262 +(define_expand "call_value"
7263 + [(parallel [(set (match_operand 0 "register_operand" "=r")
7264 + (call (match_operand:SI 1 "sym_ref_mem_operand" "")
7265 + (match_operand 2 "" "i")))
7266 + (clobber (reg:SI 9))
7267 + (use (reg:SI 16))])]
7268 + ""
7271 + emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2]));
7272 + DONE;
7273 +}")
7275 +(define_insn "call_value_internal"
7276 +[(parallel [(set (match_operand 0 "register_operand" "=r")
7277 + (call (match_operand:SI 1 "sym_ref_mem_operand" "")
7278 + (match_operand 2 "" "i")))
7279 + (clobber (reg:SI 9))
7280 + (use (reg:SI 16))])]
7281 + ""
7283 + if (flag_pic)
7285 + crtl->uses_pic_offset_table = 1;
7286 + return "l.jal \tplt(%S1) # call_value_internal%(";
7288 + return "l.jal \t%S1 # call_value_internal%(";
7290 + [(set_attr "type" "jump")
7291 + (set_attr "length" "1")])
7293 +;; indirect call value
7295 +(define_expand "call_value_indirect"
7296 + [(parallel [(set (match_operand 0 "register_operand" "=r")
7297 + (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
7298 + (match_operand 2 "" "i")))
7299 + (clobber (reg:SI 9))
7300 + (use (reg:SI 16))])]
7301 + ""
7304 + emit_call_insn (gen_call_value_indirect_internal (operands[0], operands[1], operands[2]));
7305 + DONE;
7306 +}")
7308 +(define_insn "call_value_indirect_internal"
7309 + [(parallel [(set (match_operand 0 "register_operand" "=r")
7310 + (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
7311 + (match_operand 2 "" "i")))
7312 + (clobber (reg:SI 9))
7313 + (use (reg:SI 16))])]
7314 + ""
7315 + "l.jalr \t%1 # call_value_indirect_internal%("
7316 + [(set_attr "type" "jump")
7317 + (set_attr "length" "1")])
7319 +;; indirect call
7321 +(define_expand "call_indirect"
7322 + [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
7323 + (match_operand 1 "" "i"))
7324 + (clobber (reg:SI 9))
7325 + (use (reg:SI 16))])]
7326 + ""
7329 + emit_call_insn (gen_call_indirect_internal (operands[0], operands[1]));
7330 + DONE;
7331 +}")
7333 +(define_insn "call_indirect_internal"
7334 +[(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
7335 + (match_operand 1 "" "i"))
7336 + (clobber (reg:SI 9))
7337 + (use (reg:SI 16))])]
7338 + ""
7339 + "l.jalr \t%0 # call_indirect_internal%("
7340 + [(set_attr "type" "jump")
7341 + (set_attr "length" "1")])
7343 +;; table jump
7345 +(define_expand "tablejump"
7346 + [(set (pc) (match_operand:SI 0 "register_operand" "r"))
7347 + (use (label_ref (match_operand 1 "" "")))]
7348 + ""
7351 + if (CASE_VECTOR_PC_RELATIVE || flag_pic)
7352 + operands[0]
7353 + = force_reg (Pmode,
7354 + gen_rtx_PLUS (Pmode, operands[0],
7355 + gen_rtx_LABEL_REF (Pmode, operands[1])));
7356 + emit_jump_insn (gen_tablejump_internal (operands[0], operands[1]));
7357 + DONE;
7358 +}")
7360 +(define_insn "tablejump_internal"
7361 + [(set (pc) (match_operand:SI 0 "register_operand" "r"))
7362 + (use (label_ref (match_operand 1 "" "")))]
7363 + ""
7364 + "l.jr \t%0 # tablejump_internal%("
7365 + [(set_attr "type" "jump")
7366 + (set_attr "length" "1")])
7369 +;; no-op
7371 +(define_insn "nop"
7372 + [(const_int 0)]
7373 + ""
7374 + "l.nop"
7375 + [(set_attr "type" "logic")
7376 + (set_attr "length" "1")])
7379 +;; floating point
7382 +;; floating point arithmetic
7384 +(define_insn "addsf3"
7385 + [(set (match_operand:SF 0 "register_operand" "=r")
7386 + (plus:SF (match_operand:SF 1 "register_operand" "r")
7387 + (match_operand:SF 2 "register_operand" "r")))]
7388 + "TARGET_HARD_FLOAT"
7389 + "lf.add.s\t%0,%1,%2 # addsf3"
7390 + [(set_attr "type" "fp")
7391 + (set_attr "length" "1")])
7393 +(define_insn "adddf3"
7394 + [(set (match_operand:DF 0 "register_operand" "=r")
7395 + (plus:DF (match_operand:DF 1 "register_operand" "r")
7396 + (match_operand:DF 2 "register_operand" "r")))]
7397 + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7398 + "lf.add.d\t%0,%1,%2 # adddf3"
7399 + [(set_attr "type" "fp")
7400 + (set_attr "length" "1")])
7402 +(define_insn "subsf3"
7403 + [(set (match_operand:SF 0 "register_operand" "=r")
7404 + (minus:SF (match_operand:SF 1 "register_operand" "r")
7405 + (match_operand:SF 2 "register_operand" "r")))]
7406 + "TARGET_HARD_FLOAT"
7407 + "lf.sub.s\t%0,%1,%2 # subsf3"
7408 + [(set_attr "type" "fp")
7409 + (set_attr "length" "1")])
7411 +(define_insn "subdf3"
7412 + [(set (match_operand:DF 0 "register_operand" "=r")
7413 + (minus:DF (match_operand:DF 1 "register_operand" "r")
7414 + (match_operand:DF 2 "register_operand" "r")))]
7415 + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7416 + "lf.sub.d\t%0,%1,%2 # subdf3"
7417 + [(set_attr "type" "fp")
7418 + (set_attr "length" "1")])
7420 +(define_insn "mulsf3"
7421 + [(set (match_operand:SF 0 "register_operand" "=r")
7422 + (mult:SF (match_operand:SF 1 "register_operand" "r")
7423 + (match_operand:SF 2 "register_operand" "r")))]
7424 + "TARGET_HARD_FLOAT"
7425 + "lf.mul.s\t%0,%1,%2 # mulsf3"
7426 + [(set_attr "type" "fp")
7427 + (set_attr "length" "1")])
7429 +(define_insn "muldf3"
7430 + [(set (match_operand:DF 0 "register_operand" "=r")
7431 + (mult:DF (match_operand:DF 1 "register_operand" "r")
7432 + (match_operand:DF 2 "register_operand" "r")))]
7433 + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7434 + "lf.mul.d\t%0,%1,%2 # muldf3"
7435 + [(set_attr "type" "fp")
7436 + (set_attr "length" "1")])
7438 +(define_insn "divsf3"
7439 + [(set (match_operand:SF 0 "register_operand" "=r")
7440 + (div:SF (match_operand:SF 1 "register_operand" "r")
7441 + (match_operand:SF 2 "register_operand" "r")))]
7442 + "TARGET_HARD_FLOAT"
7443 + "lf.div.s\t%0,%1,%2 # divsf3"
7444 + [(set_attr "type" "fp")
7445 + (set_attr "length" "1")])
7447 +(define_insn "divdf3"
7448 + [(set (match_operand:DF 0 "register_operand" "=r")
7449 + (div:DF (match_operand:DF 1 "register_operand" "r")
7450 + (match_operand:DF 2 "register_operand" "r")))]
7451 + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7452 + "lf.div.d\t%0,%1,%2 # divdf3"
7453 + [(set_attr "type" "fp")
7454 + (set_attr "length" "1")])
7456 +;; Conversion between fixed point and floating point.
7459 +(define_insn "floatsisf2"
7460 + [(set (match_operand:SF 0 "register_operand" "=r")
7461 + (float:SF (match_operand:SI 1 "register_operand" "r")))]
7462 + "TARGET_HARD_FLOAT"
7463 + "lf.itof.s\t%0, %1 # floatsisf2"
7464 + [(set_attr "type" "fp")
7465 + (set_attr "length" "1")])
7467 +;; not working
7468 +(define_insn "fixunssfsi2"
7469 + [(set (match_operand:SI 0 "register_operand" "=r")
7470 + (fix:SI (match_operand:SF 1 "register_operand" "r")))]
7471 + "TARGET_HARD_FLOAT"
7472 + "lf.ftoi.s\t%0, %1 # fixunssfsi2"
7473 + [(set_attr "type" "fp")
7474 + (set_attr "length" "1")])
7476 +;; The insn to set GOT.
7477 +;; TODO: support for no-delay target
7478 +(define_insn "set_got"
7479 + [(set (match_operand:SI 0 "register_operand" "=r")
7480 + (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
7481 + (clobber (reg:SI 9))
7482 + (clobber (reg:SI 16))]
7483 + ""
7484 + "l.jal \t8
7485 + \tl.movhi \tr16,gotpchi(_GLOBAL_OFFSET_TABLE_-4)
7486 + \tl.ori \tr16,r16,gotpclo(_GLOBAL_OFFSET_TABLE_+0)
7487 + \tl.add \tr16,r16,r9"
7488 + [(set_attr "length" "16")])
7490 +(define_expand "atomic_compare_and_swap<mode>"
7491 + [(match_operand:SI 0 "register_operand") ;; bool output
7492 + (match_operand:AI 1 "register_operand") ;; val output
7493 + (match_operand:AI 2 "memory_operand") ;; memory
7494 + (match_operand:AI 3 "register_operand") ;; expected
7495 + (match_operand:AI 4 "register_operand") ;; desired
7496 + (match_operand:SI 5 "const_int_operand") ;; is_weak
7497 + (match_operand:SI 6 "const_int_operand") ;; mod_s
7498 + (match_operand:SI 7 "const_int_operand")] ;; mod_f
7499 + "0"
7501 + if (<MODE>mode == SImode)
7502 + emit_insn (gen_cmpxchg (operands[0], operands[1], operands[2], operands[3],
7503 + operands[4]));
7504 + else
7505 + or1k_expand_cmpxchg_qihi (operands[0], operands[1], operands[2],
7506 + operands[3], operands[4], INTVAL (operands[5]),
7507 + (enum memmodel) INTVAL (operands[6]),
7508 + (enum memmodel) INTVAL (operands[7]));
7509 + DONE;
7512 +(define_insn "cmpxchg"
7513 + [(set (match_operand:SI 0 "register_operand" "=&r")
7514 + (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")]
7515 + UNSPEC_CMPXCHG))
7516 + (set (match_dup 2)
7517 + (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")]
7518 + UNSPEC_CMPXCHG))
7519 + (set (match_operand:SI 1 "register_operand" "=&r")
7520 + (unspec_volatile:SI [(match_dup 2) (match_dup 3)
7521 + (match_operand:SI 4 "register_operand" "r")]
7522 + UNSPEC_CMPXCHG))]
7523 + ""
7525 + l.lwa \t%1,%2 # cmpxchg: load
7526 + l.sfeq \t%1,%3 # cmpxchg: cmp
7527 + l.bnf \t1f # cmpxchg: not expected
7528 + l.ori \t%0,r0,0 # cmpxchg: result = 0
7529 + l.swa \t%2,%4 # cmpxchg: store new
7530 + l.bnf \t1f # cmpxchg: done
7531 + l.nop
7532 + l.ori \t%0,r0,1 # cmpxchg: result = 1
7533 +1:")
7535 +(define_insn "cmpxchg_mask"
7536 + [(set (match_operand:SI 0 "register_operand" "=&r")
7537 + (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")]
7538 + UNSPEC_CMPXCHG))
7539 + (set (match_dup 2)
7540 + (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")]
7541 + UNSPEC_CMPXCHG))
7542 + (set (match_operand:SI 1 "register_operand" "=&r")
7543 + (unspec_volatile:SI [(match_dup 2) (match_dup 3)
7544 + (match_operand:SI 4 "register_operand" "r")
7545 + (match_operand:SI 5 "register_operand" "r")]
7546 + UNSPEC_CMPXCHG))
7547 + (clobber (match_scratch:SI 6 "=&r"))]
7548 + ""
7550 + l.lwa \t%6,%2 # cmpxchg: load
7551 + l.and \t%1,%6,%5 # cmpxchg: mask
7552 + l.sfeq \t%1,%3 # cmpxchg: cmp
7553 + l.bnf \t1f # cmpxchg: not expected
7554 + l.ori \t%0,r0,0 # cmpxchg: result = 0
7555 + l.xor \t%6,%6,%1 # cmpxchg: clear
7556 + l.or \t%6,%6,%4 # cmpxchg: set
7557 + l.swa \t%2,%6 # cmpxchg: store new
7558 + l.bnf \t1f # cmpxchg: done
7559 + l.nop
7560 + l.ori \t%0,r0,1 # cmpxchg: result = 1
7562 + ")
7564 +(define_expand "atomic_fetch_<op_name><mode>"
7565 + [(match_operand:AI 0 "register_operand")
7566 + (match_operand:AI 1 "memory_operand")
7567 + (match_operand:AI 2 "register_operand")
7568 + (match_operand:SI 3 "const_int_operand")
7569 + (atomic_op:AI (match_dup 0) (match_dup 1))]
7570 + ""
7572 + rtx ret = gen_reg_rtx (<MODE>mode);
7573 + if (<MODE>mode != SImode)
7574 + or1k_expand_fetch_op_qihi (operands[0], operands[1], operands[2], ret,
7575 + gen_fetch_and_<op_name>_mask);
7576 + else
7577 + emit_insn (gen_fetch_and_<op_name> (operands[0], operands[1], operands[2],
7578 + ret));
7579 + DONE;
7582 +(define_expand "atomic_<op_name>_fetch<mode>"
7583 + [(match_operand:AI 0 "register_operand")
7584 + (match_operand:AI 1 "memory_operand")
7585 + (match_operand:AI 2 "register_operand")
7586 + (match_operand:SI 3 "const_int_operand")
7587 + (atomic_op:AI (match_dup 0) (match_dup 1))]
7588 + ""
7590 + rtx ret = gen_reg_rtx (<MODE>mode);
7591 + if (<MODE>mode != SImode)
7592 + or1k_expand_fetch_op_qihi (ret, operands[1], operands[2], operands[0],
7593 + gen_fetch_and_<op_name>_mask);
7594 + else
7595 + emit_insn (gen_fetch_and_<op_name> (ret, operands[1], operands[2],
7596 + operands[0]));
7597 + DONE;
7600 +(define_insn "fetch_and_<op_name>"
7601 + [(set (match_operand:SI 0 "register_operand" "=&r")
7602 + (match_operand:SI 1 "memory_operand" "+m"))
7603 + (set (match_operand:SI 3 "register_operand" "=&r")
7604 + (unspec_volatile:SI [(match_dup 1)
7605 + (match_operand:SI 2 "register_operand" "r")]
7606 + UNSPEC_FETCH_AND_OP))
7607 + (set (match_dup 1)
7608 + (match_dup 3))
7609 + (atomic_op:SI (match_dup 0) (match_dup 1))]
7610 + ""
7613 + l.lwa \t%0,%1 # fetch_<op_name>: load
7614 + l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic
7615 + <post_op_insn>
7616 + l.swa \t%1,%3 # fetch_<op_name>: store new
7617 + l.bnf \t1b # fetch_<op_name>: done
7618 + l.nop
7619 + ")
7621 +(define_insn "fetch_and_<op_name>_mask"
7622 + [(set (match_operand:SI 0 "register_operand" "=&r")
7623 + (match_operand:SI 1 "memory_operand" "+m"))
7624 + (set (match_operand:SI 3 "register_operand" "=&r")
7625 + (unspec_volatile:SI [(match_dup 1)
7626 + (match_operand:SI 2 "register_operand" "r")
7627 + (match_operand:SI 4 "register_operand" "r")]
7628 + UNSPEC_FETCH_AND_OP))
7629 + (set (match_dup 1)
7630 + (unspec_volatile:SI [(match_dup 3) (match_dup 4)] UNSPEC_FETCH_AND_OP))
7631 + (clobber (match_scratch:SI 5 "=&r"))
7632 + (atomic_op:SI (match_dup 0) (match_dup 1))]
7633 + ""
7636 + l.lwa \t%0,%1 # fetch_<op_name>: load
7637 + l.and \t%5,%0,%4 # fetch_<op_name>: mask
7638 + l.xor \t%5,%0,%5 # fetch_<op_name>: clear
7639 + l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic
7640 + <post_op_insn>
7641 + l.and \t%3,%3,%4 # fetch_<op_name>: mask result
7642 + l.or \t%3,%5,%3 # fetch_<op_name>: set
7643 + l.swa \t%1,%3 # fetch_<op_name>: store new
7644 + l.bnf \t1b # fetch_<op_name>: done
7645 + l.nop
7646 + ")
7648 +;; Local variables:
7649 +;; mode:emacs-lisp
7650 +;; comment-start: ";; "
7651 +;; eval: (set-syntax-table (copy-sequence (syntax-table)))
7652 +;; eval: (modify-syntax-entry ?[ "(]")
7653 +;; eval: (modify-syntax-entry ?] ")[")
7654 +;; eval: (modify-syntax-entry ?{ "(}")
7655 +;; eval: (modify-syntax-entry ?} "){")
7656 +;; eval: (setq indent-tabs-mode t)
7657 +;; End:
7658 diff -rNU3 dist.orig/gcc/config/or1k/or1k.opt dist/gcc/config/or1k/or1k.opt
7659 --- dist.orig/gcc/config/or1k/or1k.opt 1970-01-01 01:00:00.000000000 +0100
7660 +++ dist/gcc/config/or1k/or1k.opt 2015-10-18 13:19:50.000000000 +0200
7661 @@ -0,0 +1,96 @@
7662 +; Options for the OR1K port of the compiler
7663 +; This file is part of GCC.
7665 +; Copyright (C) 2010 Embecosm Limited
7667 +; GCC is free software; you can redistribute it and/or modify it under
7668 +; the terms of the GNU General Public License as published by the Free
7669 +; Software Foundation; either version 3, or (at your option) any later
7670 +; version.
7672 +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
7673 +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
7674 +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7675 +; for more details.
7677 +; You should have received a copy of the GNU General Public License
7678 +; along with GCC; see the file COPYING3. If not see
7679 +; <http://www.gnu.org/licenses/>.
7681 +HeaderInclude
7682 +config/or1k/or1k-opts.h
7684 +Variable
7685 +enum or1k_delay or1k_delay_selected = OR1K_DELAY_DEFAULT
7687 +mdelay
7688 +Target RejectNegative Negative(mno-delay) Var(or1k_delay_selected, OR1K_DELAY_ON)
7689 +Assume branches and jumps have a delay slot
7691 +mno-delay
7692 +Target RejectNegative Negative(mcompat-delay) Var(or1k_delay_selected, OR1K_DELAY_OFF)
7693 +Assume branches and jumps do not have a delay slot
7695 +mcompat-delay
7696 +Target RejectNegative Negative(mdelay) Var(or1k_delay_selected, OR1K_DELAY_COMPAT)
7697 +Assume branches and jumps have a delay slot, but fill them with nops
7699 +mhard-float
7700 +Target RejectNegative Mask(HARD_FLOAT)
7701 +Use hardware floating point
7703 +msoft-float
7704 +Target RejectNegative InverseMask(HARD_FLOAT)
7705 +Do not use hardware floating point
7707 +mdouble-float
7708 +Target Report RejectNegative Mask(DOUBLE_FLOAT)
7709 +Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations
7711 +mhard-div
7712 +Target RejectNegative Mask(HARD_DIV)
7713 +Use hardware division
7715 +msoft-div
7716 +Target RejectNegative InverseMask(HARD_DIV)
7717 +Do not use hardware division
7719 +mhard-mul
7720 +Target RejectNegative Mask(HARD_MUL)
7721 +Use hardware multiplication
7723 +msoft-mul
7724 +Target RejectNegative InverseMask(HARD_MUL)
7725 +Do not use hardware multiplication
7727 +msext
7728 +Target Mask(MASK_SEXT)
7729 +Use sign-extending instructions
7731 +mcmov
7732 +Target Mask(MASK_CMOV)
7733 +Use conditional move instructions
7735 +mror
7736 +Target Mask(MASK_ROR)
7737 +Emit ROR instructions
7739 +mboard=
7740 +Target RejectNegative Joined
7741 +Link with libgloss configuration suitable for this board
7743 +mnewlib
7744 +Target Report RejectNegative
7745 +Compile for the Linux/Gnu/newlib based toolchain
7747 +;; provide struct padding as in previous releases.
7748 +;; Note that this will only affect STRUCTURE_SIZE_BOUNDARY, in particular
7749 +;; make 2 byte structs 4-byte alignned and sized.
7750 +;; We still use ROUND_TYPE_ALIGN to increase alignment of larger structs.
7751 +mpadstruct
7752 +Target Report RejectNegative Mask(PADSTRUCT)
7753 +Make structs a multiple of 4 bytes (warning: ABI altered)
7755 +mredzone=
7756 +Target RejectNegative Joined UInteger Var(or1k_redzone) Init(128)
7757 +Set the size of the stack below sp that is assumed to be safe from interrupts.
7758 diff -rNU3 dist.orig/gcc/config/or1k/predicates.md dist/gcc/config/or1k/predicates.md
7759 --- dist.orig/gcc/config/or1k/predicates.md 1970-01-01 01:00:00.000000000 +0100
7760 +++ dist/gcc/config/or1k/predicates.md 2015-10-18 13:19:50.000000000 +0200
7761 @@ -0,0 +1,121 @@
7762 +;; Predicate definitions for OR32
7764 +;; Copyright (C) 2010 Embecosm Limited
7766 +;; This file is part of GCC.
7768 +;; GCC is free software; you can redistribute it and/or modify
7769 +;; it under the terms of the GNU General Public License as published by
7770 +;; the Free Software Foundation; either version 3, or (at your option)
7771 +;; any later version.
7773 +;; GCC is distributed in the hope that it will be useful,
7774 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
7775 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7776 +;; GNU General Public License for more details.
7778 +;; You should have received a copy of the GNU General Public License
7779 +;; along with GCC; see the file COPYING3. If not see
7780 +;; <http://www.gnu.org/licenses/>.
7782 +(define_predicate "cc_reg_operand"
7783 + (match_code "subreg,reg")
7785 + register_operand (op, mode);
7787 + if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
7788 + return 1;
7790 + return 0;
7793 +(define_predicate "input_operand"
7794 + (match_code "subreg,reg,const_int,mem,const")
7796 + /* If both modes are non-void they must be the same. */
7797 + if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
7798 + return 0;
7800 + /* Allow any one instruction integer constant, and all CONST_INT
7801 + variants when we are working in DImode and !arch64. */
7802 + if (GET_MODE_CLASS (mode) == MODE_INT
7803 + && ((GET_CODE (op) == CONST_INT)
7804 + && (satisfies_constraint_K (op)
7805 + || satisfies_constraint_M (op)
7806 + || satisfies_constraint_I (op))))
7807 + return 1;
7809 + if (register_operand (op, mode))
7810 + return 1;
7812 + /* If this is a SUBREG, look inside so that we handle
7813 + paradoxical ones. */
7814 + if (GET_CODE (op) == SUBREG)
7815 + op = SUBREG_REG (op);
7818 + /* Check for valid MEM forms. */
7819 + if (GET_CODE (op) == MEM)
7820 + return memory_address_p (mode, XEXP (op, 0));
7822 + return 0;
7825 +(define_predicate "sym_ref_mem_operand"
7826 + (match_code "mem")
7828 + if (GET_CODE (op) == MEM)
7830 + rtx t1 = XEXP (op, 0);
7831 + if (GET_CODE (t1) == SYMBOL_REF)
7832 + return 1;
7834 + return 0;
7837 +;; True iff OP is a symbolic operand.
7839 +(define_predicate "symbolic_operand"
7840 + (match_code "symbol_ref,label_ref,const")
7842 + switch (GET_CODE (op))
7844 + case SYMBOL_REF:
7845 + return !SYMBOL_REF_TLS_MODEL (op);
7846 + case LABEL_REF:
7847 + return true;
7848 + case CONST:
7849 + op = XEXP (op, 0);
7850 + return (GET_CODE (op) == PLUS
7851 + && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
7852 + && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
7853 + || GET_CODE (XEXP (op, 0)) == LABEL_REF)
7854 + && GET_CODE (XEXP (op, 1)) == CONST_INT);
7855 + default:
7856 + break;
7858 + return false;
7861 +;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
7862 +(define_predicate "tgd_symbolic_operand"
7863 + (and (match_code "symbol_ref")
7864 + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
7866 +;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
7868 +(define_predicate "tld_symbolic_operand"
7869 + (and (match_code "symbol_ref")
7870 + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
7872 +;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
7874 +(define_predicate "tie_symbolic_operand"
7875 + (and (match_code "symbol_ref")
7876 + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
7878 +;; Return true if OP is a symbolic operand for the TLS Local Exec model.
7880 +(define_predicate "tle_symbolic_operand"
7881 + (and (match_code "symbol_ref")
7882 + (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
7883 diff -rNU3 dist.orig/gcc/config/or1k/t-linux dist/gcc/config/or1k/t-linux
7884 --- dist.orig/gcc/config/or1k/t-linux 1970-01-01 01:00:00.000000000 +0100
7885 +++ dist/gcc/config/or1k/t-linux 2015-10-18 13:19:50.000000000 +0200
7886 @@ -0,0 +1,12 @@
7887 +MULTILIB_DIRNAMES =
7888 +EXTRA_MULTILIB_PARTS = crti.o crtbegin.o crtend.o crtn.o
7890 +# hack:
7891 +# the non-shared uclibc-0.9.31/libc/misc/internals/__uClibc_main.c
7892 +# already defines __dso_handle. To avoid a duplicate definition,
7893 +# we rename the crtbegin one.
7894 +# JPB 18-Nov-10: Commented out, since uClibc no longer defines.
7895 +# amend gcc Makefile CLFAGS variable
7896 +# $(T)crtbegin.o: CRTSTUFF_CFLAGS += '-D__dso_handle=__dso_handle_dummy'
7897 +# amend libgcc Makefile CLFAGS variable
7898 +# crtbegin$(objext): CRTSTUFF_T_CFLAGS += '-D__dso_handle=__dso_handle_dummy'
7899 diff -rNU3 dist.orig/gcc/config/or1k/t-or1k dist/gcc/config/or1k/t-or1k
7900 --- dist.orig/gcc/config/or1k/t-or1k 1970-01-01 01:00:00.000000000 +0100
7901 +++ dist/gcc/config/or1k/t-or1k 2015-10-18 13:19:50.000000000 +0200
7902 @@ -0,0 +1,28 @@
7903 +# t-or1k is a Makefile fragment to be included when
7904 +# building gcc for the or1k target
7906 +# Copyright (C) 2010 Embecosm Limited
7908 +# This file is part of GCC.
7910 +# GCC is free software; you can redistribute it and/or modify
7911 +# it under the terms of the GNU General Public License as published by
7912 +# the Free Software Foundation; either version 3, or (at your option)
7913 +# any later version.
7915 +# GCC is distributed in the hope that it will be useful,
7916 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
7917 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7918 +# GNU General Public License for more details.
7920 +# You should have received a copy of the GNU General Public License
7921 +# along with GCC; see the file COPYING3. If not see
7922 +# <http://www.gnu.org/licenses/>.
7924 +# we don't support -g so don't use it
7925 +LIBGCC2_DEBUG_CFLAGS =
7927 +# Build the libraries for both hard and soft floating point
7928 +MULTILIB_OPTIONS = mno-delay/mcompat-delay msoft-float
7929 +MULTILIB_DIRNAMES = no-delay compat-delay soft-float
7930 +MULTILIB_MATCHES =
7931 diff -rNU3 dist.orig/gcc/config/or1k/t-or1knd dist/gcc/config/or1k/t-or1knd
7932 --- dist.orig/gcc/config/or1k/t-or1knd 1970-01-01 01:00:00.000000000 +0100
7933 +++ dist/gcc/config/or1k/t-or1knd 2015-10-18 13:19:50.000000000 +0200
7934 @@ -0,0 +1,28 @@
7935 +# t-or1knd is a Makefile fragment to be included when
7936 +# building gcc for the or1k target
7938 +# Copyright (C) 2010 Embecosm Limited
7940 +# This file is part of GCC.
7942 +# GCC is free software; you can redistribute it and/or modify
7943 +# it under the terms of the GNU General Public License as published by
7944 +# the Free Software Foundation; either version 3, or (at your option)
7945 +# any later version.
7947 +# GCC is distributed in the hope that it will be useful,
7948 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
7949 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7950 +# GNU General Public License for more details.
7952 +# You should have received a copy of the GNU General Public License
7953 +# along with GCC; see the file COPYING3. If not see
7954 +# <http://www.gnu.org/licenses/>.
7956 +# we don't support -g so don't use it
7957 +LIBGCC2_DEBUG_CFLAGS =
7959 +# Build the libraries for both hard and soft floating point
7960 +MULTILIB_OPTIONS = mdelay/mcompat-delay msoft-float
7961 +MULTILIB_DIRNAMES = delay compat-delay soft-float
7962 +MULTILIB_MATCHES =
7963 diff -rNU3 dist.orig/gcc/config/pa/pa-netbsd.h dist/gcc/config/pa/pa-netbsd.h
7964 --- dist.orig/gcc/config/pa/pa-netbsd.h 1970-01-01 01:00:00.000000000 +0100
7965 +++ dist/gcc/config/pa/pa-netbsd.h 2015-10-18 13:19:50.000000000 +0200
7966 @@ -0,0 +1,148 @@
7967 +/* Definitions for PA_RISC with ELF format
7968 + Copyright (C) 1999-2013 Free Software Foundation, Inc.
7970 +This file is part of GCC.
7972 +GCC is free software; you can redistribute it and/or modify
7973 +it under the terms of the GNU General Public License as published by
7974 +the Free Software Foundation; either version 3, or (at your option)
7975 +any later version.
7977 +GCC is distributed in the hope that it will be useful,
7978 +but WITHOUT ANY WARRANTY; without even the implied warranty of
7979 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7980 +GNU General Public License for more details.
7982 +You should have received a copy of the GNU General Public License
7983 +along with GCC; see the file COPYING3. If not see
7984 +<http://www.gnu.org/licenses/>. */
7987 +#undef TARGET_OS_CPP_BUILTINS
7988 +#define TARGET_OS_CPP_BUILTINS() \
7989 + do \
7990 + { \
7991 + NETBSD_OS_CPP_BUILTINS_ELF(); \
7992 + builtin_assert ("machine=bigendian"); \
7993 + } \
7994 + while (0)
7996 +#undef CPP_SPEC
7997 +#define CPP_SPEC NETBSD_CPP_SPEC
7999 +#undef ASM_SPEC
8000 +#define ASM_SPEC \
8001 + "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
8003 +#undef EXTRA_SPECS
8004 +#define EXTRA_SPECS \
8005 + { "netbsd_entry_point", NETBSD_ENTRY_POINT },
8007 +#define NETBSD_ENTRY_POINT "__start"
8009 +#undef LINK_SPEC
8010 +#define LINK_SPEC NETBSD_LINK_SPEC_ELF
8012 +/* NetBSD profiling functions don't need gcc to allocate counters. */
8013 +#define NO_DEFERRED_PROFILE_COUNTERS 1
8015 +/* Define the strings used for the special svr4 .type and .size directives.
8016 + These strings generally do not vary from one system running svr4 to
8017 + another, but if a given system (e.g. m88k running svr) needs to use
8018 + different pseudo-op names for these, they may be overridden in the
8019 + file which includes this one. */
8021 +#undef STRING_ASM_OP
8022 +#define STRING_ASM_OP "\t.stringz\t"
8024 +#define TEXT_SECTION_ASM_OP "\t.text"
8025 +#define DATA_SECTION_ASM_OP "\t.data"
8026 +#define BSS_SECTION_ASM_OP "\t.section\t.bss"
8028 +#define TARGET_ASM_FILE_START pa_linux_file_start
8030 +/* We want local labels to start with period if made with asm_fprintf. */
8031 +#undef LOCAL_LABEL_PREFIX
8032 +#define LOCAL_LABEL_PREFIX "."
8034 +/* Define these to generate the Linux/ELF/SysV style of internal
8035 + labels all the time - i.e. to be compatible with
8036 + ASM_GENERATE_INTERNAL_LABEL in <elfos.h>. Compare these with the
8037 + ones in pa.h and note the lack of dollar signs in these. FIXME:
8038 + shouldn't we fix pa.h to use ASM_GENERATE_INTERNAL_LABEL instead? */
8040 +#undef ASM_OUTPUT_ADDR_VEC_ELT
8041 +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
8042 + if (TARGET_BIG_SWITCH) \
8043 + fprintf (FILE, "\t.word .L%d\n", VALUE); \
8044 + else \
8045 + fprintf (FILE, "\tb .L%d\n\tnop\n", VALUE)
8047 +#undef ASM_OUTPUT_ADDR_DIFF_ELT
8048 +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
8049 + if (TARGET_BIG_SWITCH) \
8050 + fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL); \
8051 + else \
8052 + fprintf (FILE, "\tb .L%d\n\tnop\n", VALUE)
8054 +/* Use the default. */
8055 +#undef ASM_OUTPUT_LABEL
8057 +/* NOTE: (*targetm.asm_out.internal_label)() is defined for us by elfos.h, and
8058 + does what we want (i.e. uses colons). It must be compatible with
8059 + ASM_GENERATE_INTERNAL_LABEL(), so do not define it here. */
8061 +/* Use the default. */
8062 +#undef ASM_OUTPUT_INTERNAL_LABEL
8064 +/* Use the default. */
8065 +#undef TARGET_ASM_GLOBALIZE_LABEL
8066 +/* Globalizing directive for a label. */
8067 +#define GLOBAL_ASM_OP ".globl "
8069 +/* FIXME: Hacked from the <elfos.h> one so that we avoid multiple
8070 + labels in a function declaration (since pa.c seems determined to do
8071 + it differently) */
8073 +#undef ASM_DECLARE_FUNCTION_NAME
8074 +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
8075 + do \
8076 + { \
8077 + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
8078 + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
8079 + } \
8080 + while (0)
8082 +/* As well as globalizing the label, we need to encode the label
8083 + to ensure a plabel is generated in an indirect call. */
8085 +#undef ASM_OUTPUT_EXTERNAL_LIBCALL
8086 +#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
8087 + do \
8088 + { \
8089 + if (!FUNCTION_NAME_P (XSTR (FUN, 0))) \
8090 + pa_encode_label (FUN); \
8091 + (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0)); \
8092 + } \
8093 + while (0)
8095 +/* NetBSD always uses gas. */
8096 +#undef TARGET_GAS
8097 +#define TARGET_GAS 1
8099 +/* Use long int for these type to make hppa64 compatibility easier. */
8100 +#undef SIZE_TYPE
8101 +#define SIZE_TYPE "long unsigned int"
8103 +#undef PTRDIFF_TYPE
8104 +#define PTRDIFF_TYPE "long int"
8106 +#if 0
8107 +#undef TARGET_SYNC_LIBCALL
8108 +#define TARGET_SYNC_LIBCALL 1
8109 +#endif
8111 +#if 0
8112 +#undef TARGET_SYNC_LIBCALL
8113 +#define TARGET_SYNC_LIBCALL 1
8114 +#endif
8115 diff -rNU3 dist.orig/gcc/config/pa/pa.c dist/gcc/config/pa/pa.c
8116 --- dist.orig/gcc/config/pa/pa.c 2015-06-12 01:26:24.000000000 +0200
8117 +++ dist/gcc/config/pa/pa.c 2015-10-18 13:19:50.000000000 +0200
8118 @@ -1066,9 +1066,9 @@
8119 || GET_CODE (XEXP (x, 0)) == REG))
8121 rtx int_part, ptr_reg;
8122 - int newoffset;
8123 - int offset = INTVAL (XEXP (x, 1));
8124 - int mask;
8125 + HOST_WIDE_INT newoffset;
8126 + HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
8127 + HOST_WIDE_INT mask;
8129 mask = (GET_MODE_CLASS (mode) == MODE_FLOAT
8130 && !INT14_OK_STRICT ? 0x1f : 0x3fff);
8131 @@ -1122,7 +1122,7 @@
8132 || GET_CODE (XEXP (x, 1)) == SUBREG)
8133 && GET_CODE (XEXP (x, 1)) != CONST)
8135 - int val = INTVAL (XEXP (XEXP (x, 0), 1));
8136 + HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
8137 rtx reg1, reg2;
8139 reg1 = XEXP (x, 1);
8140 @@ -1199,7 +1199,7 @@
8141 && INTVAL (XEXP (idx, 1)) % INTVAL (XEXP (XEXP (idx, 0), 1)) == 0)
8143 /* Divide the CONST_INT by the scale factor, then add it to A. */
8144 - int val = INTVAL (XEXP (idx, 1));
8145 + HOST_WIDE_INT val = INTVAL (XEXP (idx, 1));
8147 val /= INTVAL (XEXP (XEXP (idx, 0), 1));
8148 reg1 = XEXP (XEXP (idx, 0), 0);
8149 @@ -1222,7 +1222,7 @@
8150 && INTVAL (XEXP (idx, 1)) <= 4096
8151 && INTVAL (XEXP (idx, 1)) >= -4096)
8153 - int val = INTVAL (XEXP (XEXP (idx, 0), 1));
8154 + HOST_WIDE_INT val = INTVAL (XEXP (XEXP (idx, 0), 1));
8155 rtx reg1, reg2;
8157 reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));
8158 @@ -1306,7 +1306,7 @@
8159 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
8160 && pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
8162 - int val = INTVAL (XEXP (XEXP (x, 0), 1));
8163 + HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
8164 rtx reg1, reg2;
8166 reg1 = XEXP (x, 1);
8167 @@ -2779,8 +2779,8 @@
8168 const char *
8169 pa_output_block_move (rtx *operands, int size_is_constant ATTRIBUTE_UNUSED)
8171 - int align = INTVAL (operands[5]);
8172 - unsigned long n_bytes = INTVAL (operands[4]);
8173 + HOST_WIDE_INT align = INTVAL (operands[5]);
8174 + unsigned HOST_WIDE_INT n_bytes = INTVAL (operands[4]);
8176 /* We can't move more than a word at a time because the PA
8177 has no longer integer move insns. (Could use fp mem ops?) */
8178 @@ -2907,8 +2907,8 @@
8179 compute_movmem_length (rtx insn)
8181 rtx pat = PATTERN (insn);
8182 - unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 7), 0));
8183 - unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
8184 + unsigned HOST_WIDE_INT align = INTVAL (XEXP (XVECEXP (pat, 0, 7), 0));
8185 + unsigned HOST_WIDE_INT n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
8186 unsigned int n_insns = 0;
8188 /* We can't move more than four bytes at a time because the PA
8189 @@ -2943,8 +2943,8 @@
8190 const char *
8191 pa_output_block_clear (rtx *operands, int size_is_constant ATTRIBUTE_UNUSED)
8193 - int align = INTVAL (operands[3]);
8194 - unsigned long n_bytes = INTVAL (operands[2]);
8195 + HOST_WIDE_INT align = INTVAL (operands[3]);
8196 + unsigned HOST_WIDE_INT n_bytes = INTVAL (operands[2]);
8198 /* We can't clear more than a word at a time because the PA
8199 has no longer integer move insns. */
8200 @@ -3049,8 +3049,8 @@
8201 compute_clrmem_length (rtx insn)
8203 rtx pat = PATTERN (insn);
8204 - unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 4), 0));
8205 - unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 3), 0));
8206 + unsigned HOST_WIDE_INT align = INTVAL (XEXP (XVECEXP (pat, 0, 4), 0));
8207 + unsigned HOST_WIDE_INT n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 3), 0));
8208 unsigned int n_insns = 0;
8210 /* We can't clear more than a word at a time because the PA
8211 @@ -5562,7 +5562,7 @@
8212 static void
8213 pa_linux_file_start (void)
8215 - pa_file_start_file (1);
8216 + pa_file_start_file (0);
8217 pa_file_start_level ();
8218 pa_file_start_mcount ("CODE");
8220 @@ -5787,7 +5787,7 @@
8221 const char *
8222 pa_output_div_insn (rtx *operands, int unsignedp, rtx insn)
8224 - int divisor;
8225 + HOST_WIDE_INT divisor;
8227 /* If the divisor is a constant, try to use one of the special
8228 opcodes .*/
8229 diff -rNU3 dist.orig/gcc/config/pa/pa32-netbsd.h dist/gcc/config/pa/pa32-netbsd.h
8230 --- dist.orig/gcc/config/pa/pa32-netbsd.h 1970-01-01 01:00:00.000000000 +0100
8231 +++ dist/gcc/config/pa/pa32-netbsd.h 2015-10-18 13:19:50.000000000 +0200
8232 @@ -0,0 +1,37 @@
8233 +/* Definitions for PA_RISC with ELF-32 format
8234 + Copyright (C) 2000, 2002 Free Software Foundation, Inc.
8236 +This file is part of GCC.
8238 +GCC is free software; you can redistribute it and/or modify
8239 +it under the terms of the GNU General Public License as published by
8240 +the Free Software Foundation; either version 2, or (at your option)
8241 +any later version.
8243 +GCC is distributed in the hope that it will be useful,
8244 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8245 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8246 +GNU General Public License for more details.
8248 +You should have received a copy of the GNU General Public License
8249 +along with GCC; see the file COPYING. If not, write to
8250 +the Free Software Foundation, 59 Temple Place - Suite 330,
8251 +Boston, MA 02111-1307, USA. */
8253 +/* Turn off various SOM crap we don't want. */
8254 +#undef TARGET_ELF32
8255 +#define TARGET_ELF32 1
8257 +/* The libcall __canonicalize_funcptr_for_compare is referenced in
8258 + crtend.o and the reference isn't resolved in objects that don't
8259 + compare function pointers. Thus, we need to play games to provide
8260 + a reference in crtbegin.o. The rest of the define is the same
8261 + as that in crtstuff.c */
8262 +#define CTOR_LIST_BEGIN \
8263 + asm (".type __canonicalize_funcptr_for_compare,@function\n" \
8264 +" .text\n" \
8265 +" .word __canonicalize_funcptr_for_compare-$PIC_pcrel$0"); \
8266 + STATIC func_ptr __CTOR_LIST__[1] \
8267 + __attribute__ ((__unused__, section(".ctors"), \
8268 + aligned(sizeof(func_ptr)))) \
8269 + = { (func_ptr) (-1) }
8270 diff -rNU3 dist.orig/gcc/config/pa/t-netbsd dist/gcc/config/pa/t-netbsd
8271 --- dist.orig/gcc/config/pa/t-netbsd 1970-01-01 01:00:00.000000000 +0100
8272 +++ dist/gcc/config/pa/t-netbsd 2015-10-18 13:19:50.000000000 +0200
8273 @@ -0,0 +1 @@
8274 +#MULTIARCH_DIRNAME = $(call if_multiarch,hppa-linux-gnu)
8275 diff -rNU3 dist.orig/gcc/config/riscv/constraints.md dist/gcc/config/riscv/constraints.md
8276 --- dist.orig/gcc/config/riscv/constraints.md 1970-01-01 01:00:00.000000000 +0100
8277 +++ dist/gcc/config/riscv/constraints.md 2015-10-18 13:19:50.000000000 +0200
8278 @@ -0,0 +1,90 @@
8279 +;; Constraint definitions for RISC-V target.
8280 +;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
8281 +;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
8282 +;; Based on MIPS target for GNU compiler.
8284 +;; This file is part of GCC.
8286 +;; GCC is free software; you can redistribute it and/or modify
8287 +;; it under the terms of the GNU General Public License as published by
8288 +;; the Free Software Foundation; either version 3, or (at your option)
8289 +;; any later version.
8291 +;; GCC is distributed in the hope that it will be useful,
8292 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
8293 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8294 +;; GNU General Public License for more details.
8296 +;; You should have received a copy of the GNU General Public License
8297 +;; along with GCC; see the file COPYING3. If not see
8298 +;; <http://www.gnu.org/licenses/>.
8300 +;; Register constraints
8302 +(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
8303 + "A floating-point register (if available).")
8305 +(define_register_constraint "b" "ALL_REGS"
8306 + "@internal")
8308 +(define_register_constraint "j" "T_REGS"
8309 + "@internal")
8311 +;; Integer constraints
8313 +(define_constraint "Z"
8314 + "@internal"
8315 + (and (match_code "const_int")
8316 + (match_test "1")))
8318 +(define_constraint "I"
8319 + "An I-type 12-bit signed immediate."
8320 + (and (match_code "const_int")
8321 + (match_test "SMALL_OPERAND (ival)")))
8323 +(define_constraint "J"
8324 + "Integer zero."
8325 + (and (match_code "const_int")
8326 + (match_test "ival == 0")))
8328 +;; Floating-point constraints
8330 +(define_constraint "G"
8331 + "Floating-point zero."
8332 + (and (match_code "const_double")
8333 + (match_test "op == CONST0_RTX (mode)")))
8335 +;; General constraints
8337 +(define_constraint "Q"
8338 + "@internal"
8339 + (match_operand 0 "const_arith_operand"))
8341 +(define_memory_constraint "A"
8342 + "An address that is held in a general-purpose register."
8343 + (and (match_code "mem")
8344 + (match_test "GET_CODE(XEXP(op,0)) == REG")))
8346 +(define_constraint "S"
8347 + "@internal
8348 + A constant call address."
8349 + (and (match_operand 0 "call_insn_operand")
8350 + (match_test "CONSTANT_P (op)")))
8352 +(define_constraint "T"
8353 + "@internal
8354 + A constant @code{move_operand}."
8355 + (and (match_operand 0 "move_operand")
8356 + (match_test "CONSTANT_P (op)")))
8358 +(define_memory_constraint "W"
8359 + "@internal
8360 + A memory address based on a member of @code{BASE_REG_CLASS}."
8361 + (and (match_code "mem")
8362 + (match_operand 0 "memory_operand")))
8364 +(define_constraint "YG"
8365 + "@internal
8366 + A vector zero."
8367 + (and (match_code "const_vector")
8368 + (match_test "op == CONST0_RTX (mode)")))
8369 diff -rNU3 dist.orig/gcc/config/riscv/default-32.h dist/gcc/config/riscv/default-32.h
8370 --- dist.orig/gcc/config/riscv/default-32.h 1970-01-01 01:00:00.000000000 +0100
8371 +++ dist/gcc/config/riscv/default-32.h 2015-10-18 13:19:50.000000000 +0200
8372 @@ -0,0 +1,22 @@
8373 +/* Definitions of target machine for GCC, for RISC-V,
8374 + defaulting to 32-bit code generation.
8376 + Copyright (C) 1999-2014 Free Software Foundation, Inc.
8378 +This file is part of GCC.
8380 +GCC is free software; you can redistribute it and/or modify
8381 +it under the terms of the GNU General Public License as published by
8382 +the Free Software Foundation; either version 3, or (at your option)
8383 +any later version.
8385 +GCC is distributed in the hope that it will be useful,
8386 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8387 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8388 +GNU General Public License for more details.
8390 +You should have received a copy of the GNU General Public License
8391 +along with GCC; see the file COPYING3. If not see
8392 +<http://www.gnu.org/licenses/>. */
8394 +#define TARGET_64BIT_DEFAULT 0
8395 diff -rNU3 dist.orig/gcc/config/riscv/elf.h dist/gcc/config/riscv/elf.h
8396 --- dist.orig/gcc/config/riscv/elf.h 1970-01-01 01:00:00.000000000 +0100
8397 +++ dist/gcc/config/riscv/elf.h 2015-10-18 13:19:50.000000000 +0200
8398 @@ -0,0 +1,31 @@
8399 +/* Target macros for riscv*-elf targets.
8400 + Copyright (C) 1994, 1997, 1999, 2000, 2002, 2003, 2004, 2007, 2010
8401 + Free Software Foundation, Inc.
8403 +This file is part of GCC.
8405 +GCC is free software; you can redistribute it and/or modify
8406 +it under the terms of the GNU General Public License as published by
8407 +the Free Software Foundation; either version 3, or (at your option)
8408 +any later version.
8410 +GCC is distributed in the hope that it will be useful,
8411 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8412 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8413 +GNU General Public License for more details.
8415 +You should have received a copy of the GNU General Public License
8416 +along with GCC; see the file COPYING3. If not see
8417 +<http://www.gnu.org/licenses/>. */
8419 +/* Leave the linker script to choose the appropriate libraries. */
8420 +#undef LIB_SPEC
8421 +#define LIB_SPEC ""
8423 +#undef STARTFILE_SPEC
8424 +#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
8426 +#undef ENDFILE_SPEC
8427 +#define ENDFILE_SPEC "crtend%O%s"
8429 +#define NO_IMPLICIT_EXTERN_C 1
8430 diff -rNU3 dist.orig/gcc/config/riscv/generic.md dist/gcc/config/riscv/generic.md
8431 --- dist.orig/gcc/config/riscv/generic.md 1970-01-01 01:00:00.000000000 +0100
8432 +++ dist/gcc/config/riscv/generic.md 2015-10-18 13:19:50.000000000 +0200
8433 @@ -0,0 +1,98 @@
8434 +;; Generic DFA-based pipeline description for RISC-V targets.
8435 +;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
8436 +;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
8437 +;; Based on MIPS target for GNU compiler.
8439 +;; This file is part of GCC.
8441 +;; GCC is free software; you can redistribute it and/or modify it
8442 +;; under the terms of the GNU General Public License as published
8443 +;; by the Free Software Foundation; either version 3, or (at your
8444 +;; option) any later version.
8446 +;; GCC is distributed in the hope that it will be useful, but WITHOUT
8447 +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8448 +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
8449 +;; License for more details.
8451 +;; You should have received a copy of the GNU General Public License
8452 +;; along with GCC; see the file COPYING3. If not see
8453 +;; <http://www.gnu.org/licenses/>.
8456 +;; This file is derived from the old define_function_unit description.
8457 +;; Each reservation can be overridden on a processor-by-processor basis.
8459 +(define_insn_reservation "generic_alu" 1
8460 + (eq_attr "type" "unknown,const,arith,shift,slt,multi,nop,logical,move")
8461 + "alu")
8463 +(define_insn_reservation "generic_load" 3
8464 + (eq_attr "type" "load,fpload,fpidxload")
8465 + "alu")
8467 +(define_insn_reservation "generic_store" 1
8468 + (eq_attr "type" "store,fpstore,fpidxstore")
8469 + "alu")
8471 +(define_insn_reservation "generic_xfer" 2
8472 + (eq_attr "type" "mfc,mtc")
8473 + "alu")
8475 +(define_insn_reservation "generic_branch" 1
8476 + (eq_attr "type" "branch,jump,call")
8477 + "alu")
8479 +(define_insn_reservation "generic_imul" 17
8480 + (eq_attr "type" "imul")
8481 + "imuldiv*17")
8483 +(define_insn_reservation "generic_idiv" 38
8484 + (eq_attr "type" "idiv")
8485 + "imuldiv*38")
8487 +(define_insn_reservation "generic_fcvt" 1
8488 + (eq_attr "type" "fcvt")
8489 + "alu")
8491 +(define_insn_reservation "generic_fmove" 2
8492 + (eq_attr "type" "fmove")
8493 + "alu")
8495 +(define_insn_reservation "generic_fcmp" 3
8496 + (eq_attr "type" "fcmp")
8497 + "alu")
8499 +(define_insn_reservation "generic_fadd" 4
8500 + (eq_attr "type" "fadd")
8501 + "alu")
8503 +(define_insn_reservation "generic_fmul_single" 7
8504 + (and (eq_attr "type" "fmul,fmadd")
8505 + (eq_attr "mode" "SF"))
8506 + "alu")
8508 +(define_insn_reservation "generic_fmul_double" 8
8509 + (and (eq_attr "type" "fmul,fmadd")
8510 + (eq_attr "mode" "DF"))
8511 + "alu")
8513 +(define_insn_reservation "generic_fdiv_single" 23
8514 + (and (eq_attr "type" "fdiv")
8515 + (eq_attr "mode" "SF"))
8516 + "alu")
8518 +(define_insn_reservation "generic_fdiv_double" 36
8519 + (and (eq_attr "type" "fdiv")
8520 + (eq_attr "mode" "DF"))
8521 + "alu")
8523 +(define_insn_reservation "generic_fsqrt_single" 54
8524 + (and (eq_attr "type" "fsqrt")
8525 + (eq_attr "mode" "SF"))
8526 + "alu")
8528 +(define_insn_reservation "generic_fsqrt_double" 112
8529 + (and (eq_attr "type" "fsqrt")
8530 + (eq_attr "mode" "DF"))
8531 + "alu")
8532 diff -rNU3 dist.orig/gcc/config/riscv/linux-unwind.h dist/gcc/config/riscv/linux-unwind.h
8533 --- dist.orig/gcc/config/riscv/linux-unwind.h 1970-01-01 01:00:00.000000000 +0100
8534 +++ dist/gcc/config/riscv/linux-unwind.h 2015-10-18 13:19:50.000000000 +0200
8535 @@ -0,0 +1,50 @@
8536 +/* DWARF2 EH unwinding support for RISC-V Linux.
8537 + Copyright (C) 2014 Free Software Foundation, Inc.
8539 +This file is part of GCC.
8541 +GCC is free software; you can redistribute it and/or modify
8542 +it under the terms of the GNU General Public License as published by
8543 +the Free Software Foundation; either version 3, or (at your option)
8544 +any later version.
8546 +GCC is distributed in the hope that it will be useful,
8547 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8548 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8549 +GNU General Public License for more details.
8551 +Under Section 7 of GPL version 3, you are granted additional
8552 +permissions described in the GCC Runtime Library Exception, version
8553 +3.1, as published by the Free Software Foundation.
8555 +You should have received a copy of the GNU General Public License and
8556 +a copy of the GCC Runtime Library Exception along with this program;
8557 +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
8558 +<http://www.gnu.org/licenses/>. */
8560 +#ifndef inhibit_libc
8561 +/* Examine the code and attempt to identify a signal frame. */
8563 +#include <stdlib.h>
8564 +#include <asm-generic/unistd.h>
8566 +#define MD_FALLBACK_FRAME_STATE_FOR riscv_fallback_frame_state
8568 +static _Unwind_Reason_Code
8569 +riscv_fallback_frame_state (struct _Unwind_Context *context,
8570 + _Unwind_FrameState *fs)
8572 + unsigned int *pc = (unsigned int *) context->ra;
8574 + /* Signal frames begin with the following code sequence:
8575 + li v0, __NR_rt_sigreturn
8576 + scall */
8577 + if (((unsigned long)pc & 0x3) != 0
8578 + || pc[0] != RISCV_ITYPE (ADDI, GP_RETURN, 0, __NR_rt_sigreturn)
8579 + || pc[1] != RISCV_ITYPE (SCALL, 0, 0, 0))
8580 + return _URC_END_OF_STACK;
8582 + /* TODO: Actually implement this. */
8583 + abort();
8585 +#endif
8586 diff -rNU3 dist.orig/gcc/config/riscv/linux.h dist/gcc/config/riscv/linux.h
8587 --- dist.orig/gcc/config/riscv/linux.h 1970-01-01 01:00:00.000000000 +0100
8588 +++ dist/gcc/config/riscv/linux.h 2015-10-18 13:19:50.000000000 +0200
8589 @@ -0,0 +1,60 @@
8590 +/* Definitions for RISC-V GNU/Linux systems with ELF format.
8591 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
8592 + 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
8594 +This file is part of GCC.
8596 +GCC is free software; you can redistribute it and/or modify
8597 +it under the terms of the GNU General Public License as published by
8598 +the Free Software Foundation; either version 3, or (at your option)
8599 +any later version.
8601 +GCC is distributed in the hope that it will be useful,
8602 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8603 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8604 +GNU General Public License for more details.
8606 +You should have received a copy of the GNU General Public License
8607 +along with GCC; see the file COPYING3. If not see
8608 +<http://www.gnu.org/licenses/>. */
8610 +#undef WCHAR_TYPE
8611 +#define WCHAR_TYPE "int"
8613 +#undef WCHAR_TYPE_SIZE
8614 +#define WCHAR_TYPE_SIZE 32
8616 +#define TARGET_OS_CPP_BUILTINS() \
8617 + do { \
8618 + GNU_USER_TARGET_OS_CPP_BUILTINS(); \
8619 + /* The GNU C++ standard library requires this. */ \
8620 + if (c_dialect_cxx ()) \
8621 + builtin_define ("_GNU_SOURCE"); \
8622 + } while (0)
8624 +#undef SUBTARGET_CPP_SPEC
8625 +#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
8627 +#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
8629 +/* Borrowed from sparc/linux.h */
8630 +#undef LINK_SPEC
8631 +#define LINK_SPEC \
8632 + "%{shared:-shared} \
8633 + %{!shared: \
8634 + %{!static: \
8635 + %{rdynamic:-export-dynamic} \
8636 + -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \
8637 + %{static:-static}}"
8639 +#undef LIB_SPEC
8640 +#define LIB_SPEC "\
8641 +%{pthread:-lpthread} \
8642 +%{shared:-lc} \
8643 +%{!shared: \
8644 + %{profile:-lc_p} %{!profile:-lc}}"
8646 +/* Similar to standard Linux, but adding -ffast-math support. */
8647 +#undef ENDFILE_SPEC
8648 +#define ENDFILE_SPEC \
8649 + "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
8650 diff -rNU3 dist.orig/gcc/config/riscv/linux64.h dist/gcc/config/riscv/linux64.h
8651 --- dist.orig/gcc/config/riscv/linux64.h 1970-01-01 01:00:00.000000000 +0100
8652 +++ dist/gcc/config/riscv/linux64.h 2015-10-18 13:19:50.000000000 +0200
8653 @@ -0,0 +1,43 @@
8654 +/* Definitions for 64-bit RISC-V GNU/Linux systems with ELF format.
8655 + Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
8656 + Free Software Foundation, Inc.
8658 +This file is part of GCC.
8660 +GCC is free software; you can redistribute it and/or modify
8661 +it under the terms of the GNU General Public License as published by
8662 +the Free Software Foundation; either version 3, or (at your option)
8663 +any later version.
8665 +GCC is distributed in the hope that it will be useful,
8666 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8667 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8668 +GNU General Public License for more details.
8670 +You should have received a copy of the GNU General Public License
8671 +along with GCC; see the file COPYING3. If not see
8672 +<http://www.gnu.org/licenses/>. */
8674 +/* Force the default ABI flags onto the command line
8675 + in order to make the other specs easier to write. */
8676 +#undef LIB_SPEC
8677 +#define LIB_SPEC "\
8678 +%{pthread:-lpthread} \
8679 +%{shared:-lc} \
8680 +%{!shared: \
8681 + %{profile:-lc_p} %{!profile:-lc}}"
8683 +#define GLIBC_DYNAMIC_LINKER32 "/lib32/ld.so.1"
8684 +#define GLIBC_DYNAMIC_LINKER64 "/lib/ld.so.1"
8686 +#undef LINK_SPEC
8687 +#define LINK_SPEC "\
8688 +%{shared} \
8689 + %{!shared: \
8690 + %{!static: \
8691 + %{rdynamic:-export-dynamic} \
8692 + %{" OPT_ARCH64 ": -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
8693 + %{" OPT_ARCH32 ": -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \
8694 + %{static:-static}} \
8695 +%{" OPT_ARCH64 ":-melf64lriscv} \
8696 +%{" OPT_ARCH32 ":-melf32lriscv}"
8697 diff -rNU3 dist.orig/gcc/config/riscv/netbsd.h dist/gcc/config/riscv/netbsd.h
8698 --- dist.orig/gcc/config/riscv/netbsd.h 1970-01-01 01:00:00.000000000 +0100
8699 +++ dist/gcc/config/riscv/netbsd.h 2015-10-18 13:19:50.000000000 +0200
8700 @@ -0,0 +1,114 @@
8701 +/* Definitions for RISCV running NetBSD systems using ELF
8702 + Copyright (C) 2014
8703 + Free Software Foundation, Inc.
8704 + Contributed by Matt Thomas <matt@netbsd.org>
8706 +This file is part of GNU CC.
8708 +GNU CC is free software; you can redistribute it and/or modify
8709 +it under the terms of the GNU General Public License as published by
8710 +the Free Software Foundation; either version 2, or (at your option)
8711 +any later version.
8713 +GNU CC is distributed in the hope that it will be useful,
8714 +but WITHOUT ANY WARRANTY; without even the implied warranty of
8715 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8716 +GNU General Public License for more details.
8718 +You should have received a copy of the GNU General Public License
8719 +along with this program; see the file COPYING. If not, write to
8720 +the Free Software Foundation, 59 Temple Place - Suite 330,
8721 +Boston, MA 02111-1307, USA. */
8723 +#undef TARGET_USE_GP
8724 +#define TARGET_USE_GP 0
8726 +#undef DRIVER_SELF_SPECS
8727 +#define DRIVER_SELF_SPECS ""
8729 +#undef TARGET_DEFAULT
8730 +#define TARGET_DEFAULT (MASK_FDIV)
8732 +#undef TARGET_DEFAULT_CMODEL
8733 +#define TARGET_DEFAULT_CMODEL CM_MEDANY
8735 +#define TARGET_OS_CPP_BUILTINS() \
8736 + do { \
8737 + NETBSD_OS_CPP_BUILTINS_ELF(); \
8738 + /* The GNU C++ standard library requires this. */ \
8739 + if (c_dialect_cxx ()) \
8740 + builtin_define ("_GNU_SOURCE"); \
8741 + if (!TARGET_HARD_FLOAT_ABI) \
8742 + builtin_define ("_SOFT_FLOAT"); \
8743 + } while (0)
8745 +#undef CPP_SPEC
8746 +#define CPP_SPEC NETBSD_CPP_SPEC
8748 +#undef LIB_SPEC
8749 +#define LIB_SPEC NETBSD_LIB_SPEC
8751 +#undef LINK_SPEC
8752 +#define LINK_SPEC NETBSD_LINK_SPEC_ELF
8753 +/* Provide a LINK_SPEC appropriate for a NetBSD/mips target.
8754 + This is a copy of LINK_SPEC from <netbsd-elf.h> tweaked for
8755 + the MIPS target. */
8757 +#undef LINK_SPEC
8758 +#define LINK_SPEC \
8759 + "%{m64:-m elf64lriscv} \
8760 + %{m32:-m elf32lriscv} \
8761 + %(netbsd_link_spec)"
8763 +#undef NETBSD_ENTRY_POINT
8764 +#define NETBSD_ENTRY_POINT "_start"
8766 +#undef SUBTARGET_EXTRA_SPECS
8767 +#define SUBTARGET_EXTRA_SPECS \
8768 + { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
8769 + { "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
8770 + { "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
8772 +#define SIG_ATOMIC_TYPE "int"
8774 +#define INT8_TYPE "signed char"
8775 +#define INT16_TYPE "short int"
8776 +#define INT32_TYPE "int"
8777 +#define INT64_TYPE "long long int"
8778 +#define UINT8_TYPE "unsigned char"
8779 +#define UINT16_TYPE "short unsigned int"
8780 +#define UINT32_TYPE "unsigned int"
8781 +#define UINT64_TYPE "long long unsigned int"
8783 +#define INT_LEAST8_TYPE "signed char"
8784 +#define INT_LEAST16_TYPE "short int"
8785 +#define INT_LEAST32_TYPE "int"
8786 +#define INT_LEAST64_TYPE "long long int"
8787 +#define UINT_LEAST8_TYPE "unsigned char"
8788 +#define UINT_LEAST16_TYPE "short unsigned int"
8789 +#define UINT_LEAST32_TYPE "unsigned int"
8790 +#define UINT_LEAST64_TYPE "long long unsigned int"
8792 +#define INT_FAST8_TYPE "signed char"
8793 +#define INT_FAST16_TYPE "short int"
8794 +#define INT_FAST32_TYPE "int"
8795 +#define INT_FAST64_TYPE "long long int"
8796 +#define UINT_FAST8_TYPE "unsigned char"
8797 +#define UINT_FAST16_TYPE "short unsigned int"
8798 +#define UINT_FAST32_TYPE "unsigned int"
8799 +#define UINT_FAST64_TYPE "long long unsigned int"
8801 +#undef PTRDIFF_TYPE
8802 +#define PTRDIFF_TYPE "long int"
8804 +#undef SIZE_TYPE
8805 +#define SIZE_TYPE "long unsigned int"
8807 +#define INTPTR_TYPE PTRDIFF_TYPE
8808 +#define UINTPTR_TYPE SIZE_TYPE
8810 +#undef INTMAX_TYPE
8811 +#define INTMAX_TYPE "long long int"
8813 +#undef UINTMAX_TYPE
8814 +#define UINTMAX_TYPE "long long unsigned int"
8815 diff -rNU3 dist.orig/gcc/config/riscv/opcode-riscv.h dist/gcc/config/riscv/opcode-riscv.h
8816 --- dist.orig/gcc/config/riscv/opcode-riscv.h 1970-01-01 01:00:00.000000000 +0100
8817 +++ dist/gcc/config/riscv/opcode-riscv.h 2015-10-18 13:19:50.000000000 +0200
8818 @@ -0,0 +1,149 @@
8819 +/* RISC-V ISA encoding.
8820 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
8821 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
8822 + Based on MIPS target for GNU compiler.
8824 +This file is part of GDB, GAS, and the GNU binutils.
8826 +GDB, GAS, and the GNU binutils are free software; you can redistribute
8827 +them and/or modify them under the terms of the GNU General Public
8828 +License as published by the Free Software Foundation; either version
8829 +1, or (at your option) any later version.
8831 +GDB, GAS, and the GNU binutils are distributed in the hope that they
8832 +will be useful, but WITHOUT ANY WARRANTY; without even the implied
8833 +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
8834 +the GNU General Public License for more details.
8836 +You should have received a copy of the GNU General Public License
8837 +along with this file; see the file COPYING. If not, write to the Free
8838 +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
8840 +#ifndef _RISCV_H_
8841 +#define _RISCV_H_
8843 +#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
8844 +#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
8846 +#define EXTRACT_ITYPE_IMM(x) \
8847 + (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
8848 +#define EXTRACT_STYPE_IMM(x) \
8849 + (RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12))
8850 +#define EXTRACT_SBTYPE_IMM(x) \
8851 + ((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12))
8852 +#define EXTRACT_UTYPE_IMM(x) \
8853 + ((RV_X(x, 12, 20) << 20) | (RV_IMM_SIGN(x) << 32))
8854 +#define EXTRACT_UJTYPE_IMM(x) \
8855 + ((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20))
8857 +#define ENCODE_ITYPE_IMM(x) \
8858 + (RV_X(x, 0, 12) << 20)
8859 +#define ENCODE_STYPE_IMM(x) \
8860 + ((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25))
8861 +#define ENCODE_SBTYPE_IMM(x) \
8862 + ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31))
8863 +#define ENCODE_UTYPE_IMM(x) \
8864 + (RV_X(x, 12, 20) << 12)
8865 +#define ENCODE_UJTYPE_IMM(x) \
8866 + ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31))
8868 +#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
8869 +#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
8870 +#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x))
8871 +#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x))
8872 +#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x))
8874 +#define RISCV_RTYPE(insn, rd, rs1, rs2) \
8875 + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
8876 +#define RISCV_ITYPE(insn, rd, rs1, imm) \
8877 + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm))
8878 +#define RISCV_STYPE(insn, rs1, rs2, imm) \
8879 + ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm))
8880 +#define RISCV_SBTYPE(insn, rs1, rs2, target) \
8881 + ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target))
8882 +#define RISCV_UTYPE(insn, rd, bigimm) \
8883 + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm))
8884 +#define RISCV_UJTYPE(insn, rd, target) \
8885 + ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target))
8887 +#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0)
8889 +#define RISCV_CONST_HIGH_PART(VALUE) \
8890 + (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
8891 +#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE))
8893 +/* RV fields */
8895 +#define OP_MASK_OP 0x7f
8896 +#define OP_SH_OP 0
8897 +#define OP_MASK_RS2 0x1f
8898 +#define OP_SH_RS2 20
8899 +#define OP_MASK_RS1 0x1f
8900 +#define OP_SH_RS1 15
8901 +#define OP_MASK_RS3 0x1f
8902 +#define OP_SH_RS3 27
8903 +#define OP_MASK_RD 0x1f
8904 +#define OP_SH_RD 7
8905 +#define OP_MASK_SHAMT 0x3f
8906 +#define OP_SH_SHAMT 20
8907 +#define OP_MASK_SHAMTW 0x1f
8908 +#define OP_SH_SHAMTW 20
8909 +#define OP_MASK_RM 0x7
8910 +#define OP_SH_RM 12
8911 +#define OP_MASK_PRED 0xf
8912 +#define OP_SH_PRED 24
8913 +#define OP_MASK_SUCC 0xf
8914 +#define OP_SH_SUCC 20
8915 +#define OP_MASK_AQ 0x1
8916 +#define OP_SH_AQ 26
8917 +#define OP_MASK_RL 0x1
8918 +#define OP_SH_RL 25
8920 +#define OP_MASK_VRD 0x1f
8921 +#define OP_SH_VRD 7
8922 +#define OP_MASK_VRS 0x1f
8923 +#define OP_SH_VRS 15
8924 +#define OP_MASK_VRT 0x1f
8925 +#define OP_SH_VRT 20
8926 +#define OP_MASK_VRR 0x1f
8927 +#define OP_SH_VRR 25
8929 +#define OP_MASK_VFD 0x1f
8930 +#define OP_SH_VFD 7
8931 +#define OP_MASK_VFS 0x1f
8932 +#define OP_SH_VFS 15
8933 +#define OP_MASK_VFT 0x1f
8934 +#define OP_SH_VFT 20
8935 +#define OP_MASK_VFR 0x1f
8936 +#define OP_SH_VFR 25
8938 +#define OP_MASK_IMMNGPR 0x3f
8939 +#define OP_SH_IMMNGPR 20
8940 +#define OP_MASK_IMMNFPR 0x3f
8941 +#define OP_SH_IMMNFPR 26
8942 +#define OP_MASK_IMMSEGNELM 0x1f
8943 +#define OP_SH_IMMSEGNELM 17
8944 +#define OP_MASK_IMMSEGSTNELM 0x1f
8945 +#define OP_SH_IMMSEGSTNELM 12
8946 +#define OP_MASK_CUSTOM_IMM 0x7f
8947 +#define OP_SH_CUSTOM_IMM 25
8949 +#define LINK_REG 1
8951 +#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS
8952 +#define RISCV_JUMP_ALIGN_BITS 1
8953 +#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS)
8954 +#define RISCV_JUMP_REACH ((1ULL<<RISCV_JUMP_BITS)*RISCV_JUMP_ALIGN)
8956 +#define RISCV_IMM_BITS 12
8957 +#define RISCV_BIGIMM_BITS (32-RISCV_IMM_BITS)
8958 +#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
8959 +#define RISCV_BIGIMM_REACH (1LL<<RISCV_BIGIMM_BITS)
8960 +#define RISCV_BRANCH_BITS RISCV_IMM_BITS
8961 +#define RISCV_BRANCH_ALIGN_BITS RISCV_JUMP_ALIGN_BITS
8962 +#define RISCV_BRANCH_ALIGN (1 << RISCV_BRANCH_ALIGN_BITS)
8963 +#define RISCV_BRANCH_REACH (RISCV_IMM_REACH*RISCV_BRANCH_ALIGN)
8965 +#include "riscv-opc.h"
8967 +#endif /* _RISCV_H_ */
8968 diff -rNU3 dist.orig/gcc/config/riscv/peephole.md dist/gcc/config/riscv/peephole.md
8969 --- dist.orig/gcc/config/riscv/peephole.md 1970-01-01 01:00:00.000000000 +0100
8970 +++ dist/gcc/config/riscv/peephole.md 2015-10-18 13:19:50.000000000 +0200
8971 @@ -0,0 +1,100 @@
8972 +;;........................
8973 +;; DI -> SI optimizations
8974 +;;........................
8976 +;; Simplify (int)(a + 1), etc.
8977 +(define_peephole2
8978 + [(set (match_operand:DI 0 "register_operand")
8979 + (match_operator:DI 4 "modular_operator"
8980 + [(match_operand:DI 1 "register_operand")
8981 + (match_operand:DI 2 "arith_operand")]))
8982 + (set (match_operand:SI 3 "register_operand")
8983 + (truncate:SI (match_dup 0)))]
8984 + "TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))
8985 + && (GET_CODE (operands[4]) != ASHIFT || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32))"
8986 + [(set (match_dup 3)
8987 + (truncate:SI
8988 + (match_op_dup:DI 4
8989 + [(match_operand:DI 1 "register_operand")
8990 + (match_operand:DI 2 "arith_operand")])))])
8992 +;; Simplify (int)a + 1, etc.
8993 +(define_peephole2
8994 + [(set (match_operand:SI 0 "register_operand")
8995 + (truncate:SI (match_operand:DI 1 "register_operand")))
8996 + (set (match_operand:SI 3 "register_operand")
8997 + (match_operator:SI 4 "modular_operator"
8998 + [(match_dup 0)
8999 + (match_operand:SI 2 "arith_operand")]))]
9000 + "TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))"
9001 + [(set (match_dup 3)
9002 + (match_op_dup:SI 4 [(match_dup 1) (match_dup 2)]))])
9004 +;; Simplify -(int)a, etc.
9005 +(define_peephole2
9006 + [(set (match_operand:SI 0 "register_operand")
9007 + (truncate:SI (match_operand:DI 2 "register_operand")))
9008 + (set (match_operand:SI 3 "register_operand")
9009 + (match_operator:SI 4 "modular_operator"
9010 + [(match_operand:SI 1 "reg_or_0_operand")
9011 + (match_dup 0)]))]
9012 + "TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))"
9013 + [(set (match_dup 3)
9014 + (match_op_dup:SI 4 [(match_dup 1) (match_dup 2)]))])
9016 +;; Simplify PIC loads to static variables.
9017 +;; These will go away once we figure out how to emit auipc discretely.
9018 +(define_insn "*local_pic_load<mode>"
9019 + [(set (match_operand:ANYI 0 "register_operand" "=r")
9020 + (mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))]
9021 + "flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
9022 + "<load>\t%0,%1"
9023 + [(set (attr "length") (const_int 8))])
9024 +(define_insn "*local_pic_load<mode>"
9025 + [(set (match_operand:ANYF 0 "register_operand" "=f")
9026 + (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
9027 + (clobber (match_scratch:DI 2 "=&r"))]
9028 + "TARGET_HARD_FLOAT && TARGET_64BIT && flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
9029 + "<load>\t%0,%1,%2"
9030 + [(set (attr "length") (const_int 8))])
9031 +(define_insn "*local_pic_load<mode>"
9032 + [(set (match_operand:ANYF 0 "register_operand" "=f")
9033 + (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
9034 + (clobber (match_scratch:SI 2 "=&r"))]
9035 + "TARGET_HARD_FLOAT && !TARGET_64BIT && flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
9036 + "<load>\t%0,%1,%2"
9037 + [(set (attr "length") (const_int 8))])
9038 +(define_insn "*local_pic_loadu<mode>"
9039 + [(set (match_operand:SUPERQI 0 "register_operand" "=r")
9040 + (zero_extend:SUPERQI (mem:SUBDI (match_operand 1 "absolute_symbolic_operand" ""))))]
9041 + "flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
9042 + "<load>u\t%0,%1"
9043 + [(set (attr "length") (const_int 8))])
9044 +(define_insn "*local_pic_storedi<mode>"
9045 + [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
9046 + (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
9047 + (clobber (match_scratch:DI 2 "=&r"))]
9048 + "TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
9049 + "<store>\t%z1,%0,%2"
9050 + [(set (attr "length") (const_int 8))])
9051 +(define_insn "*local_pic_storesi<mode>"
9052 + [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
9053 + (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
9054 + (clobber (match_scratch:SI 2 "=&r"))]
9055 + "!TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
9056 + "<store>\t%z1,%0,%2"
9057 + [(set (attr "length") (const_int 8))])
9058 +(define_insn "*local_pic_storedi<mode>"
9059 + [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
9060 + (match_operand:ANYF 1 "register_operand" "f"))
9061 + (clobber (match_scratch:DI 2 "=&r"))]
9062 + "TARGET_HARD_FLOAT && TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
9063 + "<store>\t%1,%0,%2"
9064 + [(set (attr "length") (const_int 8))])
9065 +(define_insn "*local_pic_storesi<mode>"
9066 + [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
9067 + (match_operand:ANYF 1 "register_operand" "f"))
9068 + (clobber (match_scratch:SI 2 "=&r"))]
9069 + "TARGET_HARD_FLOAT && !TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
9070 + "<store>\t%1,%0,%2"
9071 + [(set (attr "length") (const_int 8))])
9072 diff -rNU3 dist.orig/gcc/config/riscv/predicates.md dist/gcc/config/riscv/predicates.md
9073 --- dist.orig/gcc/config/riscv/predicates.md 1970-01-01 01:00:00.000000000 +0100
9074 +++ dist/gcc/config/riscv/predicates.md 2015-10-18 13:19:50.000000000 +0200
9075 @@ -0,0 +1,182 @@
9076 +;; Predicate description for RISC-V target.
9077 +;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
9078 +;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
9079 +;; Based on MIPS target for GNU compiler.
9081 +;; This file is part of GCC.
9083 +;; GCC is free software; you can redistribute it and/or modify
9084 +;; it under the terms of the GNU General Public License as published by
9085 +;; the Free Software Foundation; either version 3, or (at your option)
9086 +;; any later version.
9088 +;; GCC is distributed in the hope that it will be useful,
9089 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
9090 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9091 +;; GNU General Public License for more details.
9093 +;; You should have received a copy of the GNU General Public License
9094 +;; along with GCC; see the file COPYING3. If not see
9095 +;; <http://www.gnu.org/licenses/>.
9097 +(define_predicate "const_arith_operand"
9098 + (and (match_code "const_int")
9099 + (match_test "SMALL_OPERAND (INTVAL (op))")))
9101 +(define_predicate "arith_operand"
9102 + (ior (match_operand 0 "const_arith_operand")
9103 + (match_operand 0 "register_operand")))
9105 +(define_predicate "sle_operand"
9106 + (and (match_code "const_int")
9107 + (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
9109 +(define_predicate "sleu_operand"
9110 + (and (match_operand 0 "sle_operand")
9111 + (match_test "INTVAL (op) + 1 != 0")))
9113 +(define_predicate "const_0_operand"
9114 + (and (match_code "const_int,const_double,const_vector")
9115 + (match_test "op == CONST0_RTX (GET_MODE (op))")))
9117 +(define_predicate "reg_or_0_operand"
9118 + (ior (match_operand 0 "const_0_operand")
9119 + (match_operand 0 "register_operand")))
9121 +(define_predicate "const_1_operand"
9122 + (and (match_code "const_int,const_double,const_vector")
9123 + (match_test "op == CONST1_RTX (GET_MODE (op))")))
9125 +(define_predicate "reg_or_1_operand"
9126 + (ior (match_operand 0 "const_1_operand")
9127 + (match_operand 0 "register_operand")))
9129 +;; This is used for indexing into vectors, and hence only accepts const_int.
9130 +(define_predicate "const_0_or_1_operand"
9131 + (and (match_code "const_int")
9132 + (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
9133 + (match_test "op == CONST1_RTX (GET_MODE (op))"))))
9135 +(define_special_predicate "pc_or_label_operand"
9136 + (match_code "pc,label_ref"))
9138 +;; A legitimate CONST_INT operand that takes more than one instruction
9139 +;; to load.
9140 +(define_predicate "splittable_const_int_operand"
9141 + (match_code "const_int")
9143 + /* Don't handle multi-word moves this way; we don't want to introduce
9144 + the individual word-mode moves until after reload. */
9145 + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
9146 + return false;
9148 + /* Otherwise check whether the constant can be loaded in a single
9149 + instruction. */
9150 + return !LUI_INT (op) && !SMALL_INT (op);
9153 +(define_predicate "move_operand"
9154 + (match_operand 0 "general_operand")
9156 + enum riscv_symbol_type symbol_type;
9158 + /* The thinking here is as follows:
9160 + (1) The move expanders should split complex load sequences into
9161 + individual instructions. Those individual instructions can
9162 + then be optimized by all rtl passes.
9164 + (2) The target of pre-reload load sequences should not be used
9165 + to store temporary results. If the target register is only
9166 + assigned one value, reload can rematerialize that value
9167 + on demand, rather than spill it to the stack.
9169 + (3) If we allowed pre-reload passes like combine and cse to recreate
9170 + complex load sequences, we would want to be able to split the
9171 + sequences before reload as well, so that the pre-reload scheduler
9172 + can see the individual instructions. This falls foul of (2);
9173 + the splitter would be forced to reuse the target register for
9174 + intermediate results.
9176 + (4) We want to define complex load splitters for combine. These
9177 + splitters can request a temporary scratch register, which avoids
9178 + the problem in (2). They allow things like:
9180 + (set (reg T1) (high SYM))
9181 + (set (reg T2) (low (reg T1) SYM))
9182 + (set (reg X) (plus (reg T2) (const_int OFFSET)))
9184 + to be combined into:
9186 + (set (reg T3) (high SYM+OFFSET))
9187 + (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
9189 + if T2 is only used this once. */
9190 + switch (GET_CODE (op))
9192 + case CONST_INT:
9193 + return !splittable_const_int_operand (op, mode);
9195 + case CONST:
9196 + case SYMBOL_REF:
9197 + case LABEL_REF:
9198 + return (riscv_symbolic_constant_p (op, &symbol_type)
9199 + && !riscv_hi_relocs[symbol_type]);
9201 + case HIGH:
9202 + op = XEXP (op, 0);
9203 + return riscv_symbolic_constant_p (op, &symbol_type);
9205 + default:
9206 + return true;
9210 +(define_predicate "consttable_operand"
9211 + (match_test "CONSTANT_P (op)"))
9213 +(define_predicate "symbolic_operand"
9214 + (match_code "const,symbol_ref,label_ref")
9216 + enum riscv_symbol_type type;
9217 + return riscv_symbolic_constant_p (op, &type);
9220 +(define_predicate "absolute_symbolic_operand"
9221 + (match_code "const,symbol_ref,label_ref")
9223 + enum riscv_symbol_type type;
9224 + return (riscv_symbolic_constant_p (op, &type)
9225 + && type == SYMBOL_ABSOLUTE);
9228 +(define_predicate "plt_symbolic_operand"
9229 + (match_code "const,symbol_ref,label_ref")
9231 + enum riscv_symbol_type type;
9232 + return (riscv_symbolic_constant_p (op, &type)
9233 + && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT);
9236 +(define_predicate "call_insn_operand"
9237 + (ior (match_operand 0 "absolute_symbolic_operand")
9238 + (match_operand 0 "plt_symbolic_operand")
9239 + (match_operand 0 "register_operand")))
9241 +(define_predicate "symbol_ref_operand"
9242 + (match_code "symbol_ref"))
9244 +(define_predicate "modular_operator"
9245 + (match_code "plus,minus,mult,ashift"))
9247 +(define_predicate "equality_operator"
9248 + (match_code "eq,ne"))
9250 +(define_predicate "order_operator"
9251 + (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu"))
9253 +(define_predicate "fp_order_operator"
9254 + (match_code "eq,lt,le,gt,ge"))
9256 +(define_predicate "fp_unorder_operator"
9257 + (match_code "ordered,unordered"))
9258 diff -rNU3 dist.orig/gcc/config/riscv/riscv-ftypes.def dist/gcc/config/riscv/riscv-ftypes.def
9259 --- dist.orig/gcc/config/riscv/riscv-ftypes.def 1970-01-01 01:00:00.000000000 +0100
9260 +++ dist/gcc/config/riscv/riscv-ftypes.def 2015-10-18 13:19:50.000000000 +0200
9261 @@ -0,0 +1,39 @@
9262 +/* Definitions of prototypes for RISC-V built-in functions.
9263 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
9264 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
9265 + Based on MIPS target for GNU compiler.
9267 +This file is part of GCC.
9269 +GCC is free software; you can redistribute it and/or modify
9270 +it under the terms of the GNU General Public License as published by
9271 +the Free Software Foundation; either version 3, or (at your option)
9272 +any later version.
9274 +GCC is distributed in the hope that it will be useful,
9275 +but WITHOUT ANY WARRANTY; without even the implied warranty of
9276 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9277 +GNU General Public License for more details.
9279 +You should have received a copy of the GNU General Public License
9280 +along with GCC; see the file COPYING3. If not see
9281 +<http://www.gnu.org/licenses/>. */
9283 +/* Invoke DEF_RISCV_FTYPE (NARGS, LIST) for each prototype used by
9284 + MIPS built-in functions, where:
9286 + NARGS is the number of arguments.
9287 + LIST contains the return-type code followed by the codes for each
9288 + argument type.
9290 + Argument- and return-type codes are either modes or one of the following:
9292 + VOID for void_type_node
9293 + INT for integer_type_node
9294 + POINTER for ptr_type_node
9296 + (we don't use PTR because that's a ANSI-compatibillity macro).
9298 + Please keep this list lexicographically sorted by the LIST argument. */
9300 +DEF_RISCV_FTYPE (1, (VOID, VOID))
9301 diff -rNU3 dist.orig/gcc/config/riscv/riscv-modes.def dist/gcc/config/riscv/riscv-modes.def
9302 --- dist.orig/gcc/config/riscv/riscv-modes.def 1970-01-01 01:00:00.000000000 +0100
9303 +++ dist/gcc/config/riscv/riscv-modes.def 2015-10-18 13:19:50.000000000 +0200
9304 @@ -0,0 +1,26 @@
9305 +/* Extra machine modes for RISC-V target.
9306 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
9307 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
9308 + Based on MIPS target for GNU compiler.
9310 +This file is part of GCC.
9312 +GCC is free software; you can redistribute it and/or modify
9313 +it under the terms of the GNU General Public License as published by
9314 +the Free Software Foundation; either version 3, or (at your option)
9315 +any later version.
9317 +GCC is distributed in the hope that it will be useful,
9318 +but WITHOUT ANY WARRANTY; without even the implied warranty of
9319 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9320 +GNU General Public License for more details.
9322 +You should have received a copy of the GNU General Public License
9323 +along with GCC; see the file COPYING3. If not see
9324 +<http://www.gnu.org/licenses/>. */
9326 +FLOAT_MODE (TF, 16, ieee_quad_format);
9328 +/* Vector modes. */
9329 +VECTOR_MODES (INT, 4); /* V8QI V4HI V2SI */
9330 +VECTOR_MODES (FLOAT, 4); /* V4HF V2SF */
9331 diff -rNU3 dist.orig/gcc/config/riscv/riscv-opc.h dist/gcc/config/riscv/riscv-opc.h
9332 --- dist.orig/gcc/config/riscv/riscv-opc.h 1970-01-01 01:00:00.000000000 +0100
9333 +++ dist/gcc/config/riscv/riscv-opc.h 2015-10-18 13:19:50.000000000 +0200
9334 @@ -0,0 +1,1195 @@
9335 +/* Automatically generated by parse-opcodes */
9336 +#ifndef RISCV_ENCODING_H
9337 +#define RISCV_ENCODING_H
9338 +#define MATCH_ADD 0x33
9339 +#define MASK_ADD 0xfe00707f
9340 +#define MATCH_ADDI 0x13
9341 +#define MASK_ADDI 0x707f
9342 +#define MATCH_ADDIW 0x1b
9343 +#define MASK_ADDIW 0x707f
9344 +#define MATCH_ADDW 0x3b
9345 +#define MASK_ADDW 0xfe00707f
9346 +#define MATCH_AMOADD_D 0x302f
9347 +#define MASK_AMOADD_D 0xf800707f
9348 +#define MATCH_AMOADD_W 0x202f
9349 +#define MASK_AMOADD_W 0xf800707f
9350 +#define MATCH_AMOAND_D 0x6000302f
9351 +#define MASK_AMOAND_D 0xf800707f
9352 +#define MATCH_AMOAND_W 0x6000202f
9353 +#define MASK_AMOAND_W 0xf800707f
9354 +#define MATCH_AMOMAX_D 0xa000302f
9355 +#define MASK_AMOMAX_D 0xf800707f
9356 +#define MATCH_AMOMAX_W 0xa000202f
9357 +#define MASK_AMOMAX_W 0xf800707f
9358 +#define MATCH_AMOMAXU_D 0xe000302f
9359 +#define MASK_AMOMAXU_D 0xf800707f
9360 +#define MATCH_AMOMAXU_W 0xe000202f
9361 +#define MASK_AMOMAXU_W 0xf800707f
9362 +#define MATCH_AMOMIN_D 0x8000302f
9363 +#define MASK_AMOMIN_D 0xf800707f
9364 +#define MATCH_AMOMIN_W 0x8000202f
9365 +#define MASK_AMOMIN_W 0xf800707f
9366 +#define MATCH_AMOMINU_D 0xc000302f
9367 +#define MASK_AMOMINU_D 0xf800707f
9368 +#define MATCH_AMOMINU_W 0xc000202f
9369 +#define MASK_AMOMINU_W 0xf800707f
9370 +#define MATCH_AMOOR_D 0x4000302f
9371 +#define MASK_AMOOR_D 0xf800707f
9372 +#define MATCH_AMOOR_W 0x4000202f
9373 +#define MASK_AMOOR_W 0xf800707f
9374 +#define MATCH_AMOSWAP_D 0x800302f
9375 +#define MASK_AMOSWAP_D 0xf800707f
9376 +#define MATCH_AMOSWAP_W 0x800202f
9377 +#define MASK_AMOSWAP_W 0xf800707f
9378 +#define MATCH_AMOXOR_D 0x2000302f
9379 +#define MASK_AMOXOR_D 0xf800707f
9380 +#define MATCH_AMOXOR_W 0x2000202f
9381 +#define MASK_AMOXOR_W 0xf800707f
9382 +#define MATCH_AND 0x7033
9383 +#define MASK_AND 0xfe00707f
9384 +#define MATCH_ANDI 0x7013
9385 +#define MASK_ANDI 0x707f
9386 +#define MATCH_AUIPC 0x17
9387 +#define MASK_AUIPC 0x7f
9388 +#define MATCH_BEQ 0x63
9389 +#define MASK_BEQ 0x707f
9390 +#define MATCH_BGE 0x5063
9391 +#define MASK_BGE 0x707f
9392 +#define MATCH_BGEU 0x7063
9393 +#define MASK_BGEU 0x707f
9394 +#define MATCH_BLT 0x4063
9395 +#define MASK_BLT 0x707f
9396 +#define MATCH_BLTU 0x6063
9397 +#define MASK_BLTU 0x707f
9398 +#define MATCH_BNE 0x1063
9399 +#define MASK_BNE 0x707f
9400 +#define MATCH_C_ADD 0x6000
9401 +#define MASK_C_ADD 0xf003
9402 +#define MATCH_C_ADDI 0x8000
9403 +#define MASK_C_ADDI 0xe003
9404 +#define MATCH_C_ADDI4 0xa000
9405 +#define MASK_C_ADDI4 0xe003
9406 +#define MATCH_C_ADDIW 0xe000
9407 +#define MASK_C_ADDIW 0xe003
9408 +#define MATCH_C_ADDW 0x7000
9409 +#define MASK_C_ADDW 0xf003
9410 +#define MATCH_C_BEQZ 0x2002
9411 +#define MASK_C_BEQZ 0xe003
9412 +#define MATCH_C_BNEZ 0x6002
9413 +#define MASK_C_BNEZ 0xe003
9414 +#define MATCH_C_J 0xa002
9415 +#define MASK_C_J 0xe003
9416 +#define MATCH_C_JALR 0x5000
9417 +#define MASK_C_JALR 0xf003
9418 +#define MATCH_C_LD 0x2001
9419 +#define MASK_C_LD 0xe003
9420 +#define MATCH_C_LDSP 0xc001
9421 +#define MASK_C_LDSP 0xe003
9422 +#define MATCH_C_LI 0x0
9423 +#define MASK_C_LI 0xe003
9424 +#define MATCH_C_LUI 0x2000
9425 +#define MASK_C_LUI 0xe003
9426 +#define MATCH_C_LW 0x1
9427 +#define MASK_C_LW 0xe003
9428 +#define MATCH_C_LWSP 0x8001
9429 +#define MASK_C_LWSP 0xe003
9430 +#define MATCH_C_MV 0x4000
9431 +#define MASK_C_MV 0xf003
9432 +#define MATCH_C_SD 0x6001
9433 +#define MASK_C_SD 0xe003
9434 +#define MATCH_C_SDSP 0xe001
9435 +#define MASK_C_SDSP 0xe003
9436 +#define MATCH_C_SLLI 0xc000
9437 +#define MASK_C_SLLI 0xe003
9438 +#define MATCH_C_SW 0x4001
9439 +#define MASK_C_SW 0xe003
9440 +#define MATCH_C_SWSP 0xa001
9441 +#define MASK_C_SWSP 0xe003
9442 +#define MATCH_CSRRC 0x3073
9443 +#define MASK_CSRRC 0x707f
9444 +#define MATCH_CSRRCI 0x7073
9445 +#define MASK_CSRRCI 0x707f
9446 +#define MATCH_CSRRS 0x2073
9447 +#define MASK_CSRRS 0x707f
9448 +#define MATCH_CSRRSI 0x6073
9449 +#define MASK_CSRRSI 0x707f
9450 +#define MATCH_CSRRW 0x1073
9451 +#define MASK_CSRRW 0x707f
9452 +#define MATCH_CSRRWI 0x5073
9453 +#define MASK_CSRRWI 0x707f
9454 +#define MATCH_CUSTOM0 0xb
9455 +#define MASK_CUSTOM0 0x707f
9456 +#define MATCH_CUSTOM0_RD 0x400b
9457 +#define MASK_CUSTOM0_RD 0x707f
9458 +#define MATCH_CUSTOM0_RD_RS1 0x600b
9459 +#define MASK_CUSTOM0_RD_RS1 0x707f
9460 +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
9461 +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
9462 +#define MATCH_CUSTOM0_RS1 0x200b
9463 +#define MASK_CUSTOM0_RS1 0x707f
9464 +#define MATCH_CUSTOM0_RS1_RS2 0x300b
9465 +#define MASK_CUSTOM0_RS1_RS2 0x707f
9466 +#define MATCH_CUSTOM1 0x2b
9467 +#define MASK_CUSTOM1 0x707f
9468 +#define MATCH_CUSTOM1_RD 0x402b
9469 +#define MASK_CUSTOM1_RD 0x707f
9470 +#define MATCH_CUSTOM1_RD_RS1 0x602b
9471 +#define MASK_CUSTOM1_RD_RS1 0x707f
9472 +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
9473 +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
9474 +#define MATCH_CUSTOM1_RS1 0x202b
9475 +#define MASK_CUSTOM1_RS1 0x707f
9476 +#define MATCH_CUSTOM1_RS1_RS2 0x302b
9477 +#define MASK_CUSTOM1_RS1_RS2 0x707f
9478 +#define MATCH_CUSTOM2 0x5b
9479 +#define MASK_CUSTOM2 0x707f
9480 +#define MATCH_CUSTOM2_RD 0x405b
9481 +#define MASK_CUSTOM2_RD 0x707f
9482 +#define MATCH_CUSTOM2_RD_RS1 0x605b
9483 +#define MASK_CUSTOM2_RD_RS1 0x707f
9484 +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
9485 +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
9486 +#define MATCH_CUSTOM2_RS1 0x205b
9487 +#define MASK_CUSTOM2_RS1 0x707f
9488 +#define MATCH_CUSTOM2_RS1_RS2 0x305b
9489 +#define MASK_CUSTOM2_RS1_RS2 0x707f
9490 +#define MATCH_CUSTOM3 0x7b
9491 +#define MASK_CUSTOM3 0x707f
9492 +#define MATCH_CUSTOM3_RD 0x407b
9493 +#define MASK_CUSTOM3_RD 0x707f
9494 +#define MATCH_CUSTOM3_RD_RS1 0x607b
9495 +#define MASK_CUSTOM3_RD_RS1 0x707f
9496 +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
9497 +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
9498 +#define MATCH_CUSTOM3_RS1 0x207b
9499 +#define MASK_CUSTOM3_RS1 0x707f
9500 +#define MATCH_CUSTOM3_RS1_RS2 0x307b
9501 +#define MASK_CUSTOM3_RS1_RS2 0x707f
9502 +#define MATCH_DIV 0x2004033
9503 +#define MASK_DIV 0xfe00707f
9504 +#define MATCH_DIVU 0x2005033
9505 +#define MASK_DIVU 0xfe00707f
9506 +#define MATCH_DIVUW 0x200503b
9507 +#define MASK_DIVUW 0xfe00707f
9508 +#define MATCH_DIVW 0x200403b
9509 +#define MASK_DIVW 0xfe00707f
9510 +#define MATCH_FADD_D 0x2000053
9511 +#define MASK_FADD_D 0xfe00007f
9512 +#define MATCH_FADD_H 0x4000053
9513 +#define MASK_FADD_H 0xfe00007f
9514 +#define MATCH_FADD_S 0x53
9515 +#define MASK_FADD_S 0xfe00007f
9516 +#define MATCH_FCLASS_D 0xe2001053
9517 +#define MASK_FCLASS_D 0xfff0707f
9518 +#define MATCH_FCLASS_S 0xe0001053
9519 +#define MASK_FCLASS_S 0xfff0707f
9520 +#define MATCH_FCVT_D_H 0x8c000053
9521 +#define MASK_FCVT_D_H 0xfff0007f
9522 +#define MATCH_FCVT_D_L 0xd2200053
9523 +#define MASK_FCVT_D_L 0xfff0007f
9524 +#define MATCH_FCVT_D_LU 0xd2300053
9525 +#define MASK_FCVT_D_LU 0xfff0007f
9526 +#define MATCH_FCVT_D_S 0x42000053
9527 +#define MASK_FCVT_D_S 0xfff0007f
9528 +#define MATCH_FCVT_D_W 0xd2000053
9529 +#define MASK_FCVT_D_W 0xfff0007f
9530 +#define MATCH_FCVT_D_WU 0xd2100053
9531 +#define MASK_FCVT_D_WU 0xfff0007f
9532 +#define MATCH_FCVT_H_D 0x92000053
9533 +#define MASK_FCVT_H_D 0xfff0007f
9534 +#define MATCH_FCVT_H_L 0x64000053
9535 +#define MASK_FCVT_H_L 0xfff0007f
9536 +#define MATCH_FCVT_H_LU 0x6c000053
9537 +#define MASK_FCVT_H_LU 0xfff0007f
9538 +#define MATCH_FCVT_H_S 0x90000053
9539 +#define MASK_FCVT_H_S 0xfff0007f
9540 +#define MATCH_FCVT_H_W 0x74000053
9541 +#define MASK_FCVT_H_W 0xfff0007f
9542 +#define MATCH_FCVT_H_WU 0x7c000053
9543 +#define MASK_FCVT_H_WU 0xfff0007f
9544 +#define MATCH_FCVT_L_D 0xc2200053
9545 +#define MASK_FCVT_L_D 0xfff0007f
9546 +#define MATCH_FCVT_L_H 0x44000053
9547 +#define MASK_FCVT_L_H 0xfff0007f
9548 +#define MATCH_FCVT_L_S 0xc0200053
9549 +#define MASK_FCVT_L_S 0xfff0007f
9550 +#define MATCH_FCVT_LU_D 0xc2300053
9551 +#define MASK_FCVT_LU_D 0xfff0007f
9552 +#define MATCH_FCVT_LU_H 0x4c000053
9553 +#define MASK_FCVT_LU_H 0xfff0007f
9554 +#define MATCH_FCVT_LU_S 0xc0300053
9555 +#define MASK_FCVT_LU_S 0xfff0007f
9556 +#define MATCH_FCVT_S_D 0x40100053
9557 +#define MASK_FCVT_S_D 0xfff0007f
9558 +#define MATCH_FCVT_S_H 0x84000053
9559 +#define MASK_FCVT_S_H 0xfff0007f
9560 +#define MATCH_FCVT_S_L 0xd0200053
9561 +#define MASK_FCVT_S_L 0xfff0007f
9562 +#define MATCH_FCVT_S_LU 0xd0300053
9563 +#define MASK_FCVT_S_LU 0xfff0007f
9564 +#define MATCH_FCVT_S_W 0xd0000053
9565 +#define MASK_FCVT_S_W 0xfff0007f
9566 +#define MATCH_FCVT_S_WU 0xd0100053
9567 +#define MASK_FCVT_S_WU 0xfff0007f
9568 +#define MATCH_FCVT_W_D 0xc2000053
9569 +#define MASK_FCVT_W_D 0xfff0007f
9570 +#define MATCH_FCVT_W_H 0x54000053
9571 +#define MASK_FCVT_W_H 0xfff0007f
9572 +#define MATCH_FCVT_W_S 0xc0000053
9573 +#define MASK_FCVT_W_S 0xfff0007f
9574 +#define MATCH_FCVT_WU_D 0xc2100053
9575 +#define MASK_FCVT_WU_D 0xfff0007f
9576 +#define MATCH_FCVT_WU_H 0x5c000053
9577 +#define MASK_FCVT_WU_H 0xfff0007f
9578 +#define MATCH_FCVT_WU_S 0xc0100053
9579 +#define MASK_FCVT_WU_S 0xfff0007f
9580 +#define MATCH_FDIV_D 0x1a000053
9581 +#define MASK_FDIV_D 0xfe00007f
9582 +#define MATCH_FDIV_H 0x1c000053
9583 +#define MASK_FDIV_H 0xfe00007f
9584 +#define MATCH_FDIV_S 0x18000053
9585 +#define MASK_FDIV_S 0xfe00007f
9586 +#define MATCH_FENCE 0xf
9587 +#define MASK_FENCE 0x707f
9588 +#define MATCH_FENCE_I 0x100f
9589 +#define MASK_FENCE_I 0x707f
9590 +#define MATCH_FEQ_D 0xa2002053
9591 +#define MASK_FEQ_D 0xfe00707f
9592 +#define MATCH_FEQ_H 0xac000053
9593 +#define MASK_FEQ_H 0xfe00707f
9594 +#define MATCH_FEQ_S 0xa0002053
9595 +#define MASK_FEQ_S 0xfe00707f
9596 +#define MATCH_FLD 0x3007
9597 +#define MASK_FLD 0x707f
9598 +#define MATCH_FLE_D 0xa2000053
9599 +#define MASK_FLE_D 0xfe00707f
9600 +#define MATCH_FLE_H 0xbc000053
9601 +#define MASK_FLE_H 0xfe00707f
9602 +#define MATCH_FLE_S 0xa0000053
9603 +#define MASK_FLE_S 0xfe00707f
9604 +#define MATCH_FLH 0x1007
9605 +#define MASK_FLH 0x707f
9606 +#define MATCH_FLT_D 0xa2001053
9607 +#define MASK_FLT_D 0xfe00707f
9608 +#define MATCH_FLT_H 0xb4000053
9609 +#define MASK_FLT_H 0xfe00707f
9610 +#define MATCH_FLT_S 0xa0001053
9611 +#define MASK_FLT_S 0xfe00707f
9612 +#define MATCH_FLW 0x2007
9613 +#define MASK_FLW 0x707f
9614 +#define MATCH_FMADD_D 0x2000043
9615 +#define MASK_FMADD_D 0x600007f
9616 +#define MATCH_FMADD_H 0x4000043
9617 +#define MASK_FMADD_H 0x600007f
9618 +#define MATCH_FMADD_S 0x43
9619 +#define MASK_FMADD_S 0x600007f
9620 +#define MATCH_FMAX_D 0x2a001053
9621 +#define MASK_FMAX_D 0xfe00707f
9622 +#define MATCH_FMAX_H 0xcc000053
9623 +#define MASK_FMAX_H 0xfe00707f
9624 +#define MATCH_FMAX_S 0x28001053
9625 +#define MASK_FMAX_S 0xfe00707f
9626 +#define MATCH_FMIN_D 0x2a000053
9627 +#define MASK_FMIN_D 0xfe00707f
9628 +#define MATCH_FMIN_H 0xc4000053
9629 +#define MASK_FMIN_H 0xfe00707f
9630 +#define MATCH_FMIN_S 0x28000053
9631 +#define MASK_FMIN_S 0xfe00707f
9632 +#define MATCH_FMOVN 0x6007077
9633 +#define MASK_FMOVN 0xfe00707f
9634 +#define MATCH_FMOVZ 0x4007077
9635 +#define MASK_FMOVZ 0xfe00707f
9636 +#define MATCH_FMSUB_D 0x2000047
9637 +#define MASK_FMSUB_D 0x600007f
9638 +#define MATCH_FMSUB_H 0x4000047
9639 +#define MASK_FMSUB_H 0x600007f
9640 +#define MATCH_FMSUB_S 0x47
9641 +#define MASK_FMSUB_S 0x600007f
9642 +#define MATCH_FMUL_D 0x12000053
9643 +#define MASK_FMUL_D 0xfe00007f
9644 +#define MATCH_FMUL_H 0x14000053
9645 +#define MASK_FMUL_H 0xfe00007f
9646 +#define MATCH_FMUL_S 0x10000053
9647 +#define MASK_FMUL_S 0xfe00007f
9648 +#define MATCH_FMV_D_X 0xf2000053
9649 +#define MASK_FMV_D_X 0xfff0707f
9650 +#define MATCH_FMV_H_X 0xf4000053
9651 +#define MASK_FMV_H_X 0xfff0707f
9652 +#define MATCH_FMV_S_X 0xf0000053
9653 +#define MASK_FMV_S_X 0xfff0707f
9654 +#define MATCH_FMV_X_D 0xe2000053
9655 +#define MASK_FMV_X_D 0xfff0707f
9656 +#define MATCH_FMV_X_H 0xe4000053
9657 +#define MASK_FMV_X_H 0xfff0707f
9658 +#define MATCH_FMV_X_S 0xe0000053
9659 +#define MASK_FMV_X_S 0xfff0707f
9660 +#define MATCH_FNMADD_D 0x200004f
9661 +#define MASK_FNMADD_D 0x600007f
9662 +#define MATCH_FNMADD_H 0x400004f
9663 +#define MASK_FNMADD_H 0x600007f
9664 +#define MATCH_FNMADD_S 0x4f
9665 +#define MASK_FNMADD_S 0x600007f
9666 +#define MATCH_FNMSUB_D 0x200004b
9667 +#define MASK_FNMSUB_D 0x600007f
9668 +#define MATCH_FNMSUB_H 0x400004b
9669 +#define MASK_FNMSUB_H 0x600007f
9670 +#define MATCH_FNMSUB_S 0x4b
9671 +#define MASK_FNMSUB_S 0x600007f
9672 +#define MATCH_FRCSR 0x302073
9673 +#define MASK_FRCSR 0xfffff07f
9674 +#define MATCH_FRFLAGS 0x102073
9675 +#define MASK_FRFLAGS 0xfffff07f
9676 +#define MATCH_FRRM 0x202073
9677 +#define MASK_FRRM 0xfffff07f
9678 +#define MATCH_FSCSR 0x301073
9679 +#define MASK_FSCSR 0xfff0707f
9680 +#define MATCH_FSD 0x3027
9681 +#define MASK_FSD 0x707f
9682 +#define MATCH_FSFLAGS 0x101073
9683 +#define MASK_FSFLAGS 0xfff0707f
9684 +#define MATCH_FSFLAGSI 0x105073
9685 +#define MASK_FSFLAGSI 0xfff0707f
9686 +#define MATCH_FSGNJ_D 0x22000053
9687 +#define MASK_FSGNJ_D 0xfe00707f
9688 +#define MATCH_FSGNJ_H 0x2c000053
9689 +#define MASK_FSGNJ_H 0xfe00707f
9690 +#define MATCH_FSGNJ_S 0x20000053
9691 +#define MASK_FSGNJ_S 0xfe00707f
9692 +#define MATCH_FSGNJN_D 0x22001053
9693 +#define MASK_FSGNJN_D 0xfe00707f
9694 +#define MATCH_FSGNJN_H 0x34000053
9695 +#define MASK_FSGNJN_H 0xfe00707f
9696 +#define MATCH_FSGNJN_S 0x20001053
9697 +#define MASK_FSGNJN_S 0xfe00707f
9698 +#define MATCH_FSGNJX_D 0x22002053
9699 +#define MASK_FSGNJX_D 0xfe00707f
9700 +#define MATCH_FSGNJX_H 0x3c000053
9701 +#define MASK_FSGNJX_H 0xfe00707f
9702 +#define MATCH_FSGNJX_S 0x20002053
9703 +#define MASK_FSGNJX_S 0xfe00707f
9704 +#define MATCH_FSH 0x1027
9705 +#define MASK_FSH 0x707f
9706 +#define MATCH_FSQRT_D 0x5a000053
9707 +#define MASK_FSQRT_D 0xfff0007f
9708 +#define MATCH_FSQRT_H 0x24000053
9709 +#define MASK_FSQRT_H 0xfff0007f
9710 +#define MATCH_FSQRT_S 0x58000053
9711 +#define MASK_FSQRT_S 0xfff0007f
9712 +#define MATCH_FSRM 0x201073
9713 +#define MASK_FSRM 0xfff0707f
9714 +#define MATCH_FSRMI 0x205073
9715 +#define MASK_FSRMI 0xfff0707f
9716 +#define MATCH_FSUB_D 0xa000053
9717 +#define MASK_FSUB_D 0xfe00007f
9718 +#define MATCH_FSUB_H 0xc000053
9719 +#define MASK_FSUB_H 0xfe00007f
9720 +#define MATCH_FSUB_S 0x8000053
9721 +#define MASK_FSUB_S 0xfe00007f
9722 +#define MATCH_FSW 0x2027
9723 +#define MASK_FSW 0x707f
9724 +#define MATCH_JAL 0x6f
9725 +#define MASK_JAL 0x7f
9726 +#define MATCH_JALR 0x67
9727 +#define MASK_JALR 0x707f
9728 +#define MATCH_LB 0x3
9729 +#define MASK_LB 0x707f
9730 +#define MATCH_LBU 0x4003
9731 +#define MASK_LBU 0x707f
9732 +#define MATCH_LD 0x3003
9733 +#define MASK_LD 0x707f
9734 +#define MATCH_LH 0x1003
9735 +#define MASK_LH 0x707f
9736 +#define MATCH_LHU 0x5003
9737 +#define MASK_LHU 0x707f
9738 +#define MATCH_LR_D 0x1000302f
9739 +#define MASK_LR_D 0xf9f0707f
9740 +#define MATCH_LR_W 0x1000202f
9741 +#define MASK_LR_W 0xf9f0707f
9742 +#define MATCH_LUI 0x37
9743 +#define MASK_LUI 0x7f
9744 +#define MATCH_LW 0x2003
9745 +#define MASK_LW 0x707f
9746 +#define MATCH_LWU 0x6003
9747 +#define MASK_LWU 0x707f
9748 +#define MATCH_MOVN 0x2007077
9749 +#define MASK_MOVN 0xfe00707f
9750 +#define MATCH_MOVZ 0x7077
9751 +#define MASK_MOVZ 0xfe00707f
9752 +#define MATCH_MRTS 0x30500073
9753 +#define MASK_MRTS 0xffffffff
9754 +#define MATCH_MUL 0x2000033
9755 +#define MASK_MUL 0xfe00707f
9756 +#define MATCH_MULH 0x2001033
9757 +#define MASK_MULH 0xfe00707f
9758 +#define MATCH_MULHSU 0x2002033
9759 +#define MASK_MULHSU 0xfe00707f
9760 +#define MATCH_MULHU 0x2003033
9761 +#define MASK_MULHU 0xfe00707f
9762 +#define MATCH_MULW 0x200003b
9763 +#define MASK_MULW 0xfe00707f
9764 +#define MATCH_OR 0x6033
9765 +#define MASK_OR 0xfe00707f
9766 +#define MATCH_ORI 0x6013
9767 +#define MASK_ORI 0x707f
9768 +#define MATCH_RDCYCLE 0xc0002073
9769 +#define MASK_RDCYCLE 0xfffff07f
9770 +#define MATCH_RDCYCLEH 0xc8002073
9771 +#define MASK_RDCYCLEH 0xfffff07f
9772 +#define MATCH_RDINSTRET 0xc0202073
9773 +#define MASK_RDINSTRET 0xfffff07f
9774 +#define MATCH_RDINSTRETH 0xc8202073
9775 +#define MASK_RDINSTRETH 0xfffff07f
9776 +#define MATCH_RDTIME 0xc0102073
9777 +#define MASK_RDTIME 0xfffff07f
9778 +#define MATCH_RDTIMEH 0xc8102073
9779 +#define MASK_RDTIMEH 0xfffff07f
9780 +#define MATCH_REM 0x2006033
9781 +#define MASK_REM 0xfe00707f
9782 +#define MATCH_REMU 0x2007033
9783 +#define MASK_REMU 0xfe00707f
9784 +#define MATCH_REMUW 0x200703b
9785 +#define MASK_REMUW 0xfe00707f
9786 +#define MATCH_REMW 0x200603b
9787 +#define MASK_REMW 0xfe00707f
9788 +#define MATCH_SB 0x23
9789 +#define MASK_SB 0x707f
9790 +#define MATCH_SBREAK 0x100073
9791 +#define MASK_SBREAK 0xffffffff
9792 +#define MATCH_SC_D 0x1800302f
9793 +#define MASK_SC_D 0xf800707f
9794 +#define MATCH_SC_W 0x1800202f
9795 +#define MASK_SC_W 0xf800707f
9796 +#define MATCH_SCALL 0x73
9797 +#define MASK_SCALL 0xffffffff
9798 +#define MATCH_SD 0x3023
9799 +#define MASK_SD 0x707f
9800 +#define MATCH_SFENCE_VM 0x10100073
9801 +#define MASK_SFENCE_VM 0xfff07fff
9802 +#define MATCH_SH 0x1023
9803 +#define MASK_SH 0x707f
9804 +#define MATCH_SLL 0x1033
9805 +#define MASK_SLL 0xfe00707f
9806 +#define MATCH_SLLI 0x1013
9807 +#define MASK_SLLI 0xfc00707f
9808 +#define MATCH_SLLI_RV32 0x1013
9809 +#define MASK_SLLI_RV32 0xfe00707f
9810 +#define MATCH_SLLIW 0x101b
9811 +#define MASK_SLLIW 0xfe00707f
9812 +#define MATCH_SLLW 0x103b
9813 +#define MASK_SLLW 0xfe00707f
9814 +#define MATCH_SLT 0x2033
9815 +#define MASK_SLT 0xfe00707f
9816 +#define MATCH_SLTI 0x2013
9817 +#define MASK_SLTI 0x707f
9818 +#define MATCH_SLTIU 0x3013
9819 +#define MASK_SLTIU 0x707f
9820 +#define MATCH_SLTU 0x3033
9821 +#define MASK_SLTU 0xfe00707f
9822 +#define MATCH_SRA 0x40005033
9823 +#define MASK_SRA 0xfe00707f
9824 +#define MATCH_SRAI 0x40005013
9825 +#define MASK_SRAI 0xfc00707f
9826 +#define MATCH_SRAI_RV32 0x40005013
9827 +#define MASK_SRAI_RV32 0xfe00707f
9828 +#define MATCH_SRAIW 0x4000501b
9829 +#define MASK_SRAIW 0xfe00707f
9830 +#define MATCH_SRAW 0x4000503b
9831 +#define MASK_SRAW 0xfe00707f
9832 +#define MATCH_SRET 0x10000073
9833 +#define MASK_SRET 0xffffffff
9834 +#define MATCH_SRL 0x5033
9835 +#define MASK_SRL 0xfe00707f
9836 +#define MATCH_SRLI 0x5013
9837 +#define MASK_SRLI 0xfc00707f
9838 +#define MATCH_SRLI_RV32 0x5013
9839 +#define MASK_SRLI_RV32 0xfe00707f
9840 +#define MATCH_SRLIW 0x501b
9841 +#define MASK_SRLIW 0xfe00707f
9842 +#define MATCH_SRLW 0x503b
9843 +#define MASK_SRLW 0xfe00707f
9844 +#define MATCH_STOP 0x5077
9845 +#define MASK_STOP 0xffffffff
9846 +#define MATCH_SUB 0x40000033
9847 +#define MASK_SUB 0xfe00707f
9848 +#define MATCH_SUBW 0x4000003b
9849 +#define MASK_SUBW 0xfe00707f
9850 +#define MATCH_SW 0x2023
9851 +#define MASK_SW 0x707f
9852 +#define MATCH_UTIDX 0x6077
9853 +#define MASK_UTIDX 0xfffff07f
9854 +#define MATCH_VENQCMD 0xa00302b
9855 +#define MASK_VENQCMD 0xfe007fff
9856 +#define MATCH_VENQCNT 0x1000302b
9857 +#define MASK_VENQCNT 0xfe007fff
9858 +#define MATCH_VENQIMM1 0xc00302b
9859 +#define MASK_VENQIMM1 0xfe007fff
9860 +#define MATCH_VENQIMM2 0xe00302b
9861 +#define MASK_VENQIMM2 0xfe007fff
9862 +#define MATCH_VF 0x10202b
9863 +#define MASK_VF 0x1f0707f
9864 +#define MATCH_VFLD 0x1600205b
9865 +#define MASK_VFLD 0xfff0707f
9866 +#define MATCH_VFLSEGD 0x1600205b
9867 +#define MASK_VFLSEGD 0x1ff0707f
9868 +#define MATCH_VFLSEGSTD 0x1600305b
9869 +#define MASK_VFLSEGSTD 0x1e00707f
9870 +#define MATCH_VFLSEGSTW 0x1400305b
9871 +#define MASK_VFLSEGSTW 0x1e00707f
9872 +#define MATCH_VFLSEGW 0x1400205b
9873 +#define MASK_VFLSEGW 0x1ff0707f
9874 +#define MATCH_VFLSTD 0x1600305b
9875 +#define MASK_VFLSTD 0xfe00707f
9876 +#define MATCH_VFLSTW 0x1400305b
9877 +#define MASK_VFLSTW 0xfe00707f
9878 +#define MATCH_VFLW 0x1400205b
9879 +#define MASK_VFLW 0xfff0707f
9880 +#define MATCH_VFMSV_D 0x1200202b
9881 +#define MASK_VFMSV_D 0xfff0707f
9882 +#define MATCH_VFMSV_S 0x1000202b
9883 +#define MASK_VFMSV_S 0xfff0707f
9884 +#define MATCH_VFMVV 0x1000002b
9885 +#define MASK_VFMVV 0xfff0707f
9886 +#define MATCH_VFSD 0x1600207b
9887 +#define MASK_VFSD 0xfff0707f
9888 +#define MATCH_VFSSEGD 0x1600207b
9889 +#define MASK_VFSSEGD 0x1ff0707f
9890 +#define MATCH_VFSSEGSTD 0x1600307b
9891 +#define MASK_VFSSEGSTD 0x1e00707f
9892 +#define MATCH_VFSSEGSTW 0x1400307b
9893 +#define MASK_VFSSEGSTW 0x1e00707f
9894 +#define MATCH_VFSSEGW 0x1400207b
9895 +#define MASK_VFSSEGW 0x1ff0707f
9896 +#define MATCH_VFSSTD 0x1600307b
9897 +#define MASK_VFSSTD 0xfe00707f
9898 +#define MATCH_VFSSTW 0x1400307b
9899 +#define MASK_VFSSTW 0xfe00707f
9900 +#define MATCH_VFSW 0x1400207b
9901 +#define MASK_VFSW 0xfff0707f
9902 +#define MATCH_VGETCFG 0x400b
9903 +#define MASK_VGETCFG 0xfffff07f
9904 +#define MATCH_VGETVL 0x200400b
9905 +#define MASK_VGETVL 0xfffff07f
9906 +#define MATCH_VLB 0x205b
9907 +#define MASK_VLB 0xfff0707f
9908 +#define MATCH_VLBU 0x800205b
9909 +#define MASK_VLBU 0xfff0707f
9910 +#define MATCH_VLD 0x600205b
9911 +#define MASK_VLD 0xfff0707f
9912 +#define MATCH_VLH 0x200205b
9913 +#define MASK_VLH 0xfff0707f
9914 +#define MATCH_VLHU 0xa00205b
9915 +#define MASK_VLHU 0xfff0707f
9916 +#define MATCH_VLSEGB 0x205b
9917 +#define MASK_VLSEGB 0x1ff0707f
9918 +#define MATCH_VLSEGBU 0x800205b
9919 +#define MASK_VLSEGBU 0x1ff0707f
9920 +#define MATCH_VLSEGD 0x600205b
9921 +#define MASK_VLSEGD 0x1ff0707f
9922 +#define MATCH_VLSEGH 0x200205b
9923 +#define MASK_VLSEGH 0x1ff0707f
9924 +#define MATCH_VLSEGHU 0xa00205b
9925 +#define MASK_VLSEGHU 0x1ff0707f
9926 +#define MATCH_VLSEGSTB 0x305b
9927 +#define MASK_VLSEGSTB 0x1e00707f
9928 +#define MATCH_VLSEGSTBU 0x800305b
9929 +#define MASK_VLSEGSTBU 0x1e00707f
9930 +#define MATCH_VLSEGSTD 0x600305b
9931 +#define MASK_VLSEGSTD 0x1e00707f
9932 +#define MATCH_VLSEGSTH 0x200305b
9933 +#define MASK_VLSEGSTH 0x1e00707f
9934 +#define MATCH_VLSEGSTHU 0xa00305b
9935 +#define MASK_VLSEGSTHU 0x1e00707f
9936 +#define MATCH_VLSEGSTW 0x400305b
9937 +#define MASK_VLSEGSTW 0x1e00707f
9938 +#define MATCH_VLSEGSTWU 0xc00305b
9939 +#define MASK_VLSEGSTWU 0x1e00707f
9940 +#define MATCH_VLSEGW 0x400205b
9941 +#define MASK_VLSEGW 0x1ff0707f
9942 +#define MATCH_VLSEGWU 0xc00205b
9943 +#define MASK_VLSEGWU 0x1ff0707f
9944 +#define MATCH_VLSTB 0x305b
9945 +#define MASK_VLSTB 0xfe00707f
9946 +#define MATCH_VLSTBU 0x800305b
9947 +#define MASK_VLSTBU 0xfe00707f
9948 +#define MATCH_VLSTD 0x600305b
9949 +#define MASK_VLSTD 0xfe00707f
9950 +#define MATCH_VLSTH 0x200305b
9951 +#define MASK_VLSTH 0xfe00707f
9952 +#define MATCH_VLSTHU 0xa00305b
9953 +#define MASK_VLSTHU 0xfe00707f
9954 +#define MATCH_VLSTW 0x400305b
9955 +#define MASK_VLSTW 0xfe00707f
9956 +#define MATCH_VLSTWU 0xc00305b
9957 +#define MASK_VLSTWU 0xfe00707f
9958 +#define MATCH_VLW 0x400205b
9959 +#define MASK_VLW 0xfff0707f
9960 +#define MATCH_VLWU 0xc00205b
9961 +#define MASK_VLWU 0xfff0707f
9962 +#define MATCH_VMSV 0x200202b
9963 +#define MASK_VMSV 0xfff0707f
9964 +#define MATCH_VMVV 0x200002b
9965 +#define MASK_VMVV 0xfff0707f
9966 +#define MATCH_VSB 0x207b
9967 +#define MASK_VSB 0xfff0707f
9968 +#define MATCH_VSD 0x600207b
9969 +#define MASK_VSD 0xfff0707f
9970 +#define MATCH_VSETCFG 0x200b
9971 +#define MASK_VSETCFG 0x7fff
9972 +#define MATCH_VSETVL 0x600b
9973 +#define MASK_VSETVL 0xfff0707f
9974 +#define MATCH_VSH 0x200207b
9975 +#define MASK_VSH 0xfff0707f
9976 +#define MATCH_VSSEGB 0x207b
9977 +#define MASK_VSSEGB 0x1ff0707f
9978 +#define MATCH_VSSEGD 0x600207b
9979 +#define MASK_VSSEGD 0x1ff0707f
9980 +#define MATCH_VSSEGH 0x200207b
9981 +#define MASK_VSSEGH 0x1ff0707f
9982 +#define MATCH_VSSEGSTB 0x307b
9983 +#define MASK_VSSEGSTB 0x1e00707f
9984 +#define MATCH_VSSEGSTD 0x600307b
9985 +#define MASK_VSSEGSTD 0x1e00707f
9986 +#define MATCH_VSSEGSTH 0x200307b
9987 +#define MASK_VSSEGSTH 0x1e00707f
9988 +#define MATCH_VSSEGSTW 0x400307b
9989 +#define MASK_VSSEGSTW 0x1e00707f
9990 +#define MATCH_VSSEGW 0x400207b
9991 +#define MASK_VSSEGW 0x1ff0707f
9992 +#define MATCH_VSSTB 0x307b
9993 +#define MASK_VSSTB 0xfe00707f
9994 +#define MATCH_VSSTD 0x600307b
9995 +#define MASK_VSSTD 0xfe00707f
9996 +#define MATCH_VSSTH 0x200307b
9997 +#define MASK_VSSTH 0xfe00707f
9998 +#define MATCH_VSSTW 0x400307b
9999 +#define MASK_VSSTW 0xfe00707f
10000 +#define MATCH_VSW 0x400207b
10001 +#define MASK_VSW 0xfff0707f
10002 +#define MATCH_VXCPTAUX 0x200402b
10003 +#define MASK_VXCPTAUX 0xfffff07f
10004 +#define MATCH_VXCPTCAUSE 0x402b
10005 +#define MASK_VXCPTCAUSE 0xfffff07f
10006 +#define MATCH_VXCPTEVAC 0x600302b
10007 +#define MASK_VXCPTEVAC 0xfff07fff
10008 +#define MATCH_VXCPTHOLD 0x800302b
10009 +#define MASK_VXCPTHOLD 0xfff07fff
10010 +#define MATCH_VXCPTKILL 0x400302b
10011 +#define MASK_VXCPTKILL 0xffffffff
10012 +#define MATCH_VXCPTRESTORE 0x200302b
10013 +#define MASK_VXCPTRESTORE 0xfff07fff
10014 +#define MATCH_VXCPTSAVE 0x302b
10015 +#define MASK_VXCPTSAVE 0xfff07fff
10016 +#define MATCH_XOR 0x4033
10017 +#define MASK_XOR 0xfe00707f
10018 +#define MATCH_XORI 0x4013
10019 +#define MASK_XORI 0x707f
10020 +#define CSR_FFLAGS 0x1
10021 +#define CSR_FRM 0x2
10022 +#define CSR_FCSR 0x3
10023 +#define CSR_CYCLE 0xc00
10024 +#define CSR_TIME 0xc01
10025 +#define CSR_INSTRET 0xc02
10026 +#define CSR_STATS 0xc0
10027 +#define CSR_UARCH0 0xcc0
10028 +#define CSR_UARCH1 0xcc1
10029 +#define CSR_UARCH2 0xcc2
10030 +#define CSR_UARCH3 0xcc3
10031 +#define CSR_UARCH4 0xcc4
10032 +#define CSR_UARCH5 0xcc5
10033 +#define CSR_UARCH6 0xcc6
10034 +#define CSR_UARCH7 0xcc7
10035 +#define CSR_UARCH8 0xcc8
10036 +#define CSR_UARCH9 0xcc9
10037 +#define CSR_UARCH10 0xcca
10038 +#define CSR_UARCH11 0xccb
10039 +#define CSR_UARCH12 0xccc
10040 +#define CSR_UARCH13 0xccd
10041 +#define CSR_UARCH14 0xcce
10042 +#define CSR_UARCH15 0xccf
10043 +#define CSR_SSTATUS 0x100
10044 +#define CSR_STVEC 0x101
10045 +#define CSR_STIMECMP 0x121
10046 +#define CSR_SSCRATCH 0x140
10047 +#define CSR_SEPC 0x141
10048 +#define CSR_SPTBR 0x188
10049 +#define CSR_SASID 0x189
10050 +#define CSR_SCYCLE 0x900
10051 +#define CSR_STIME 0x901
10052 +#define CSR_SINSTRET 0x902
10053 +#define CSR_SCAUSE 0xd40
10054 +#define CSR_SBADADDR 0xd41
10055 +#define CSR_MSTATUS 0x300
10056 +#define CSR_MSCRATCH 0x340
10057 +#define CSR_MEPC 0x341
10058 +#define CSR_MCAUSE 0x342
10059 +#define CSR_MBADADDR 0x343
10060 +#define CSR_RESET 0x780
10061 +#define CSR_TOHOST 0x781
10062 +#define CSR_FROMHOST 0x782
10063 +#define CSR_SEND_IPI 0x783
10064 +#define CSR_HARTID 0xfc0
10065 +#define CSR_CYCLEH 0xc80
10066 +#define CSR_TIMEH 0xc81
10067 +#define CSR_INSTRETH 0xc82
10068 +#define CSR_SCYCLEH 0x980
10069 +#define CSR_STIMEH 0x981
10070 +#define CSR_SINSTRETH 0x982
10071 +#define CAUSE_MISALIGNED_FETCH 0x0
10072 +#define CAUSE_FAULT_FETCH 0x1
10073 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2
10074 +#define CAUSE_MISALIGNED_LOAD 0x4
10075 +#define CAUSE_FAULT_LOAD 0x5
10076 +#define CAUSE_MISALIGNED_STORE 0x6
10077 +#define CAUSE_FAULT_STORE 0x7
10078 +#define CAUSE_ECALL 0x8
10079 +#define CAUSE_BREAKPOINT 0x9
10080 +#endif
10081 +#ifdef DECLARE_INSN
10082 +DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
10083 +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
10084 +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
10085 +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
10086 +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
10087 +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
10088 +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
10089 +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
10090 +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
10091 +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
10092 +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
10093 +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
10094 +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
10095 +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
10096 +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
10097 +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
10098 +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
10099 +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
10100 +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
10101 +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
10102 +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
10103 +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
10104 +DECLARE_INSN(and, MATCH_AND, MASK_AND)
10105 +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
10106 +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
10107 +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
10108 +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
10109 +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
10110 +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
10111 +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
10112 +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
10113 +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
10114 +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
10115 +DECLARE_INSN(c_addi4, MATCH_C_ADDI4, MASK_C_ADDI4)
10116 +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
10117 +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
10118 +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
10119 +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
10120 +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
10121 +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
10122 +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
10123 +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
10124 +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
10125 +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
10126 +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
10127 +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
10128 +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
10129 +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
10130 +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
10131 +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
10132 +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
10133 +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
10134 +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
10135 +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
10136 +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
10137 +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
10138 +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
10139 +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
10140 +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
10141 +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
10142 +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
10143 +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
10144 +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
10145 +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
10146 +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
10147 +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
10148 +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
10149 +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
10150 +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
10151 +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
10152 +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
10153 +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
10154 +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
10155 +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
10156 +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
10157 +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
10158 +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
10159 +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
10160 +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
10161 +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
10162 +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
10163 +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
10164 +DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
10165 +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
10166 +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
10167 +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
10168 +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
10169 +DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H)
10170 +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
10171 +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
10172 +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
10173 +DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H)
10174 +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
10175 +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
10176 +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
10177 +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
10178 +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
10179 +DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D)
10180 +DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L)
10181 +DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU)
10182 +DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S)
10183 +DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W)
10184 +DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU)
10185 +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
10186 +DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H)
10187 +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
10188 +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
10189 +DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H)
10190 +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
10191 +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
10192 +DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H)
10193 +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
10194 +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
10195 +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
10196 +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
10197 +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
10198 +DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H)
10199 +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
10200 +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
10201 +DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H)
10202 +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
10203 +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
10204 +DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H)
10205 +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
10206 +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
10207 +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
10208 +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
10209 +DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H)
10210 +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
10211 +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
10212 +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
10213 +DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H)
10214 +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
10215 +DECLARE_INSN(flh, MATCH_FLH, MASK_FLH)
10216 +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
10217 +DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H)
10218 +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
10219 +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
10220 +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
10221 +DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H)
10222 +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
10223 +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
10224 +DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H)
10225 +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
10226 +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
10227 +DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H)
10228 +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
10229 +DECLARE_INSN(fmovn, MATCH_FMOVN, MASK_FMOVN)
10230 +DECLARE_INSN(fmovz, MATCH_FMOVZ, MASK_FMOVZ)
10231 +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
10232 +DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H)
10233 +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
10234 +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
10235 +DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H)
10236 +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
10237 +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
10238 +DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X)
10239 +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
10240 +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
10241 +DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H)
10242 +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
10243 +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
10244 +DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H)
10245 +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
10246 +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
10247 +DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H)
10248 +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
10249 +DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR)
10250 +DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS)
10251 +DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM)
10252 +DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR)
10253 +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
10254 +DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS)
10255 +DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI)
10256 +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
10257 +DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H)
10258 +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
10259 +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
10260 +DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H)
10261 +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
10262 +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
10263 +DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H)
10264 +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
10265 +DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH)
10266 +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
10267 +DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H)
10268 +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
10269 +DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM)
10270 +DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI)
10271 +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
10272 +DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H)
10273 +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
10274 +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
10275 +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
10276 +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
10277 +DECLARE_INSN(lb, MATCH_LB, MASK_LB)
10278 +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
10279 +DECLARE_INSN(ld, MATCH_LD, MASK_LD)
10280 +DECLARE_INSN(lh, MATCH_LH, MASK_LH)
10281 +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
10282 +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
10283 +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
10284 +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
10285 +DECLARE_INSN(lw, MATCH_LW, MASK_LW)
10286 +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
10287 +DECLARE_INSN(movn, MATCH_MOVN, MASK_MOVN)
10288 +DECLARE_INSN(movz, MATCH_MOVZ, MASK_MOVZ)
10289 +DECLARE_INSN(mrts, MATCH_MRTS, MASK_MRTS)
10290 +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
10291 +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
10292 +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
10293 +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
10294 +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
10295 +DECLARE_INSN(or, MATCH_OR, MASK_OR)
10296 +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
10297 +DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE)
10298 +DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH)
10299 +DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET)
10300 +DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH)
10301 +DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME)
10302 +DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH)
10303 +DECLARE_INSN(rem, MATCH_REM, MASK_REM)
10304 +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
10305 +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
10306 +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
10307 +DECLARE_INSN(sb, MATCH_SB, MASK_SB)
10308 +DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK)
10309 +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
10310 +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
10311 +DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL)
10312 +DECLARE_INSN(sd, MATCH_SD, MASK_SD)
10313 +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM)
10314 +DECLARE_INSN(sh, MATCH_SH, MASK_SH)
10315 +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
10316 +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
10317 +DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32)
10318 +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
10319 +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
10320 +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
10321 +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
10322 +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
10323 +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
10324 +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
10325 +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
10326 +DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32)
10327 +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
10328 +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
10329 +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
10330 +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
10331 +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
10332 +DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32)
10333 +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
10334 +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
10335 +DECLARE_INSN(stop, MATCH_STOP, MASK_STOP)
10336 +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
10337 +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
10338 +DECLARE_INSN(sw, MATCH_SW, MASK_SW)
10339 +DECLARE_INSN(utidx, MATCH_UTIDX, MASK_UTIDX)
10340 +DECLARE_INSN(venqcmd, MATCH_VENQCMD, MASK_VENQCMD)
10341 +DECLARE_INSN(venqcnt, MATCH_VENQCNT, MASK_VENQCNT)
10342 +DECLARE_INSN(venqimm1, MATCH_VENQIMM1, MASK_VENQIMM1)
10343 +DECLARE_INSN(venqimm2, MATCH_VENQIMM2, MASK_VENQIMM2)
10344 +DECLARE_INSN(vf, MATCH_VF, MASK_VF)
10345 +DECLARE_INSN(vfld, MATCH_VFLD, MASK_VFLD)
10346 +DECLARE_INSN(vflsegd, MATCH_VFLSEGD, MASK_VFLSEGD)
10347 +DECLARE_INSN(vflsegstd, MATCH_VFLSEGSTD, MASK_VFLSEGSTD)
10348 +DECLARE_INSN(vflsegstw, MATCH_VFLSEGSTW, MASK_VFLSEGSTW)
10349 +DECLARE_INSN(vflsegw, MATCH_VFLSEGW, MASK_VFLSEGW)
10350 +DECLARE_INSN(vflstd, MATCH_VFLSTD, MASK_VFLSTD)
10351 +DECLARE_INSN(vflstw, MATCH_VFLSTW, MASK_VFLSTW)
10352 +DECLARE_INSN(vflw, MATCH_VFLW, MASK_VFLW)
10353 +DECLARE_INSN(vfmsv_d, MATCH_VFMSV_D, MASK_VFMSV_D)
10354 +DECLARE_INSN(vfmsv_s, MATCH_VFMSV_S, MASK_VFMSV_S)
10355 +DECLARE_INSN(vfmvv, MATCH_VFMVV, MASK_VFMVV)
10356 +DECLARE_INSN(vfsd, MATCH_VFSD, MASK_VFSD)
10357 +DECLARE_INSN(vfssegd, MATCH_VFSSEGD, MASK_VFSSEGD)
10358 +DECLARE_INSN(vfssegstd, MATCH_VFSSEGSTD, MASK_VFSSEGSTD)
10359 +DECLARE_INSN(vfssegstw, MATCH_VFSSEGSTW, MASK_VFSSEGSTW)
10360 +DECLARE_INSN(vfssegw, MATCH_VFSSEGW, MASK_VFSSEGW)
10361 +DECLARE_INSN(vfsstd, MATCH_VFSSTD, MASK_VFSSTD)
10362 +DECLARE_INSN(vfsstw, MATCH_VFSSTW, MASK_VFSSTW)
10363 +DECLARE_INSN(vfsw, MATCH_VFSW, MASK_VFSW)
10364 +DECLARE_INSN(vgetcfg, MATCH_VGETCFG, MASK_VGETCFG)
10365 +DECLARE_INSN(vgetvl, MATCH_VGETVL, MASK_VGETVL)
10366 +DECLARE_INSN(vlb, MATCH_VLB, MASK_VLB)
10367 +DECLARE_INSN(vlbu, MATCH_VLBU, MASK_VLBU)
10368 +DECLARE_INSN(vld, MATCH_VLD, MASK_VLD)
10369 +DECLARE_INSN(vlh, MATCH_VLH, MASK_VLH)
10370 +DECLARE_INSN(vlhu, MATCH_VLHU, MASK_VLHU)
10371 +DECLARE_INSN(vlsegb, MATCH_VLSEGB, MASK_VLSEGB)
10372 +DECLARE_INSN(vlsegbu, MATCH_VLSEGBU, MASK_VLSEGBU)
10373 +DECLARE_INSN(vlsegd, MATCH_VLSEGD, MASK_VLSEGD)
10374 +DECLARE_INSN(vlsegh, MATCH_VLSEGH, MASK_VLSEGH)
10375 +DECLARE_INSN(vlseghu, MATCH_VLSEGHU, MASK_VLSEGHU)
10376 +DECLARE_INSN(vlsegstb, MATCH_VLSEGSTB, MASK_VLSEGSTB)
10377 +DECLARE_INSN(vlsegstbu, MATCH_VLSEGSTBU, MASK_VLSEGSTBU)
10378 +DECLARE_INSN(vlsegstd, MATCH_VLSEGSTD, MASK_VLSEGSTD)
10379 +DECLARE_INSN(vlsegsth, MATCH_VLSEGSTH, MASK_VLSEGSTH)
10380 +DECLARE_INSN(vlsegsthu, MATCH_VLSEGSTHU, MASK_VLSEGSTHU)
10381 +DECLARE_INSN(vlsegstw, MATCH_VLSEGSTW, MASK_VLSEGSTW)
10382 +DECLARE_INSN(vlsegstwu, MATCH_VLSEGSTWU, MASK_VLSEGSTWU)
10383 +DECLARE_INSN(vlsegw, MATCH_VLSEGW, MASK_VLSEGW)
10384 +DECLARE_INSN(vlsegwu, MATCH_VLSEGWU, MASK_VLSEGWU)
10385 +DECLARE_INSN(vlstb, MATCH_VLSTB, MASK_VLSTB)
10386 +DECLARE_INSN(vlstbu, MATCH_VLSTBU, MASK_VLSTBU)
10387 +DECLARE_INSN(vlstd, MATCH_VLSTD, MASK_VLSTD)
10388 +DECLARE_INSN(vlsth, MATCH_VLSTH, MASK_VLSTH)
10389 +DECLARE_INSN(vlsthu, MATCH_VLSTHU, MASK_VLSTHU)
10390 +DECLARE_INSN(vlstw, MATCH_VLSTW, MASK_VLSTW)
10391 +DECLARE_INSN(vlstwu, MATCH_VLSTWU, MASK_VLSTWU)
10392 +DECLARE_INSN(vlw, MATCH_VLW, MASK_VLW)
10393 +DECLARE_INSN(vlwu, MATCH_VLWU, MASK_VLWU)
10394 +DECLARE_INSN(vmsv, MATCH_VMSV, MASK_VMSV)
10395 +DECLARE_INSN(vmvv, MATCH_VMVV, MASK_VMVV)
10396 +DECLARE_INSN(vsb, MATCH_VSB, MASK_VSB)
10397 +DECLARE_INSN(vsd, MATCH_VSD, MASK_VSD)
10398 +DECLARE_INSN(vsetcfg, MATCH_VSETCFG, MASK_VSETCFG)
10399 +DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL)
10400 +DECLARE_INSN(vsh, MATCH_VSH, MASK_VSH)
10401 +DECLARE_INSN(vssegb, MATCH_VSSEGB, MASK_VSSEGB)
10402 +DECLARE_INSN(vssegd, MATCH_VSSEGD, MASK_VSSEGD)
10403 +DECLARE_INSN(vssegh, MATCH_VSSEGH, MASK_VSSEGH)
10404 +DECLARE_INSN(vssegstb, MATCH_VSSEGSTB, MASK_VSSEGSTB)
10405 +DECLARE_INSN(vssegstd, MATCH_VSSEGSTD, MASK_VSSEGSTD)
10406 +DECLARE_INSN(vssegsth, MATCH_VSSEGSTH, MASK_VSSEGSTH)
10407 +DECLARE_INSN(vssegstw, MATCH_VSSEGSTW, MASK_VSSEGSTW)
10408 +DECLARE_INSN(vssegw, MATCH_VSSEGW, MASK_VSSEGW)
10409 +DECLARE_INSN(vsstb, MATCH_VSSTB, MASK_VSSTB)
10410 +DECLARE_INSN(vsstd, MATCH_VSSTD, MASK_VSSTD)
10411 +DECLARE_INSN(vssth, MATCH_VSSTH, MASK_VSSTH)
10412 +DECLARE_INSN(vsstw, MATCH_VSSTW, MASK_VSSTW)
10413 +DECLARE_INSN(vsw, MATCH_VSW, MASK_VSW)
10414 +DECLARE_INSN(vxcptaux, MATCH_VXCPTAUX, MASK_VXCPTAUX)
10415 +DECLARE_INSN(vxcptcause, MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE)
10416 +DECLARE_INSN(vxcptevac, MATCH_VXCPTEVAC, MASK_VXCPTEVAC)
10417 +DECLARE_INSN(vxcpthold, MATCH_VXCPTHOLD, MASK_VXCPTHOLD)
10418 +DECLARE_INSN(vxcptkill, MATCH_VXCPTKILL, MASK_VXCPTKILL)
10419 +DECLARE_INSN(vxcptrestore, MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE)
10420 +DECLARE_INSN(vxcptsave, MATCH_VXCPTSAVE, MASK_VXCPTSAVE)
10421 +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
10422 +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
10423 +#endif
10424 +#ifdef DECLARE_CSR
10425 +DECLARE_CSR(fflags, CSR_FFLAGS)
10426 +DECLARE_CSR(frm, CSR_FRM)
10427 +DECLARE_CSR(fcsr, CSR_FCSR)
10428 +DECLARE_CSR(cycle, CSR_CYCLE)
10429 +DECLARE_CSR(time, CSR_TIME)
10430 +DECLARE_CSR(instret, CSR_INSTRET)
10431 +DECLARE_CSR(stats, CSR_STATS)
10432 +DECLARE_CSR(uarch0, CSR_UARCH0)
10433 +DECLARE_CSR(uarch1, CSR_UARCH1)
10434 +DECLARE_CSR(uarch2, CSR_UARCH2)
10435 +DECLARE_CSR(uarch3, CSR_UARCH3)
10436 +DECLARE_CSR(uarch4, CSR_UARCH4)
10437 +DECLARE_CSR(uarch5, CSR_UARCH5)
10438 +DECLARE_CSR(uarch6, CSR_UARCH6)
10439 +DECLARE_CSR(uarch7, CSR_UARCH7)
10440 +DECLARE_CSR(uarch8, CSR_UARCH8)
10441 +DECLARE_CSR(uarch9, CSR_UARCH9)
10442 +DECLARE_CSR(uarch10, CSR_UARCH10)
10443 +DECLARE_CSR(uarch11, CSR_UARCH11)
10444 +DECLARE_CSR(uarch12, CSR_UARCH12)
10445 +DECLARE_CSR(uarch13, CSR_UARCH13)
10446 +DECLARE_CSR(uarch14, CSR_UARCH14)
10447 +DECLARE_CSR(uarch15, CSR_UARCH15)
10448 +DECLARE_CSR(sstatus, CSR_SSTATUS)
10449 +DECLARE_CSR(stvec, CSR_STVEC)
10450 +DECLARE_CSR(stimecmp, CSR_STIMECMP)
10451 +DECLARE_CSR(sscratch, CSR_SSCRATCH)
10452 +DECLARE_CSR(sepc, CSR_SEPC)
10453 +DECLARE_CSR(sptbr, CSR_SPTBR)
10454 +DECLARE_CSR(sasid, CSR_SASID)
10455 +DECLARE_CSR(scycle, CSR_SCYCLE)
10456 +DECLARE_CSR(stime, CSR_STIME)
10457 +DECLARE_CSR(sinstret, CSR_SINSTRET)
10458 +DECLARE_CSR(scause, CSR_SCAUSE)
10459 +DECLARE_CSR(sbadaddr, CSR_SBADADDR)
10460 +DECLARE_CSR(mstatus, CSR_MSTATUS)
10461 +DECLARE_CSR(mscratch, CSR_MSCRATCH)
10462 +DECLARE_CSR(mepc, CSR_MEPC)
10463 +DECLARE_CSR(mcause, CSR_MCAUSE)
10464 +DECLARE_CSR(mbadaddr, CSR_MBADADDR)
10465 +DECLARE_CSR(reset, CSR_RESET)
10466 +DECLARE_CSR(tohost, CSR_TOHOST)
10467 +DECLARE_CSR(fromhost, CSR_FROMHOST)
10468 +DECLARE_CSR(send_ipi, CSR_SEND_IPI)
10469 +DECLARE_CSR(hartid, CSR_HARTID)
10470 +DECLARE_CSR(cycleh, CSR_CYCLEH)
10471 +DECLARE_CSR(timeh, CSR_TIMEH)
10472 +DECLARE_CSR(instreth, CSR_INSTRETH)
10473 +DECLARE_CSR(scycleh, CSR_SCYCLEH)
10474 +DECLARE_CSR(stimeh, CSR_STIMEH)
10475 +DECLARE_CSR(sinstreth, CSR_SINSTRETH)
10476 +#endif
10477 +#ifdef DECLARE_CAUSE
10478 +DECLARE_CAUSE("fflags", CAUSE_FFLAGS)
10479 +DECLARE_CAUSE("frm", CAUSE_FRM)
10480 +DECLARE_CAUSE("fcsr", CAUSE_FCSR)
10481 +DECLARE_CAUSE("cycle", CAUSE_CYCLE)
10482 +DECLARE_CAUSE("time", CAUSE_TIME)
10483 +DECLARE_CAUSE("instret", CAUSE_INSTRET)
10484 +DECLARE_CAUSE("stats", CAUSE_STATS)
10485 +DECLARE_CAUSE("uarch0", CAUSE_UARCH0)
10486 +DECLARE_CAUSE("uarch1", CAUSE_UARCH1)
10487 +DECLARE_CAUSE("uarch2", CAUSE_UARCH2)
10488 +DECLARE_CAUSE("uarch3", CAUSE_UARCH3)
10489 +DECLARE_CAUSE("uarch4", CAUSE_UARCH4)
10490 +DECLARE_CAUSE("uarch5", CAUSE_UARCH5)
10491 +DECLARE_CAUSE("uarch6", CAUSE_UARCH6)
10492 +DECLARE_CAUSE("uarch7", CAUSE_UARCH7)
10493 +DECLARE_CAUSE("uarch8", CAUSE_UARCH8)
10494 +DECLARE_CAUSE("uarch9", CAUSE_UARCH9)
10495 +DECLARE_CAUSE("uarch10", CAUSE_UARCH10)
10496 +DECLARE_CAUSE("uarch11", CAUSE_UARCH11)
10497 +DECLARE_CAUSE("uarch12", CAUSE_UARCH12)
10498 +DECLARE_CAUSE("uarch13", CAUSE_UARCH13)
10499 +DECLARE_CAUSE("uarch14", CAUSE_UARCH14)
10500 +DECLARE_CAUSE("uarch15", CAUSE_UARCH15)
10501 +DECLARE_CAUSE("sstatus", CAUSE_SSTATUS)
10502 +DECLARE_CAUSE("stvec", CAUSE_STVEC)
10503 +DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP)
10504 +DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH)
10505 +DECLARE_CAUSE("sepc", CAUSE_SEPC)
10506 +DECLARE_CAUSE("sptbr", CAUSE_SPTBR)
10507 +DECLARE_CAUSE("sasid", CAUSE_SASID)
10508 +DECLARE_CAUSE("scycle", CAUSE_SCYCLE)
10509 +DECLARE_CAUSE("stime", CAUSE_STIME)
10510 +DECLARE_CAUSE("sinstret", CAUSE_SINSTRET)
10511 +DECLARE_CAUSE("scause", CAUSE_SCAUSE)
10512 +DECLARE_CAUSE("sbadaddr", CAUSE_SBADADDR)
10513 +DECLARE_CAUSE("mstatus", CAUSE_MSTATUS)
10514 +DECLARE_CAUSE("mscratch", CAUSE_MSCRATCH)
10515 +DECLARE_CAUSE("mepc", CAUSE_MEPC)
10516 +DECLARE_CAUSE("mcause", CAUSE_MCAUSE)
10517 +DECLARE_CAUSE("mbadaddr", CAUSE_MBADADDR)
10518 +DECLARE_CAUSE("reset", CAUSE_RESET)
10519 +DECLARE_CAUSE("tohost", CAUSE_TOHOST)
10520 +DECLARE_CAUSE("fromhost", CAUSE_FROMHOST)
10521 +DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI)
10522 +DECLARE_CAUSE("hartid", CAUSE_HARTID)
10523 +DECLARE_CAUSE("cycleh", CAUSE_CYCLEH)
10524 +DECLARE_CAUSE("timeh", CAUSE_TIMEH)
10525 +DECLARE_CAUSE("instreth", CAUSE_INSTRETH)
10526 +DECLARE_CAUSE("scycleh", CAUSE_SCYCLEH)
10527 +DECLARE_CAUSE("stimeh", CAUSE_STIMEH)
10528 +DECLARE_CAUSE("sinstreth", CAUSE_SINSTRETH)
10529 +#endif
10530 diff -rNU3 dist.orig/gcc/config/riscv/riscv-protos.h dist/gcc/config/riscv/riscv-protos.h
10531 --- dist.orig/gcc/config/riscv/riscv-protos.h 1970-01-01 01:00:00.000000000 +0100
10532 +++ dist/gcc/config/riscv/riscv-protos.h 2015-10-18 13:19:50.000000000 +0200
10533 @@ -0,0 +1,96 @@
10534 +/* Definition of RISC-V target for GNU compiler.
10535 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
10536 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
10537 + Based on MIPS target for GNU compiler.
10539 +This file is part of GCC.
10541 +GCC is free software; you can redistribute it and/or modify
10542 +it under the terms of the GNU General Public License as published by
10543 +the Free Software Foundation; either version 3, or (at your option)
10544 +any later version.
10546 +GCC is distributed in the hope that it will be useful,
10547 +but WITHOUT ANY WARRANTY; without even the implied warranty of
10548 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10549 +GNU General Public License for more details.
10551 +You should have received a copy of the GNU General Public License
10552 +along with GCC; see the file COPYING3. If not see
10553 +<http://www.gnu.org/licenses/>. */
10555 +#ifndef GCC_RISCV_PROTOS_H
10556 +#define GCC_RISCV_PROTOS_H
10558 +enum riscv_symbol_type {
10559 + SYMBOL_ABSOLUTE,
10560 + SYMBOL_GOT_DISP,
10561 + SYMBOL_TLS,
10562 + SYMBOL_TLS_LE,
10563 + SYMBOL_TLS_IE,
10564 + SYMBOL_TLS_GD
10566 +#define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1)
10568 +enum riscv_code_model {
10569 + CM_MEDLOW,
10570 + CM_MEDANY,
10571 + CM_PIC
10573 +extern enum riscv_code_model riscv_cmodel;
10575 +extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
10576 +extern int riscv_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
10577 +extern int riscv_address_insns (rtx, enum machine_mode, bool);
10578 +extern int riscv_const_insns (rtx);
10579 +extern int riscv_split_const_insns (rtx);
10580 +extern int riscv_load_store_insns (rtx, rtx);
10581 +extern rtx riscv_emit_move (rtx, rtx);
10582 +extern bool riscv_split_symbol (rtx, rtx, enum machine_mode, rtx *);
10583 +extern rtx riscv_unspec_address (rtx, enum riscv_symbol_type);
10584 +extern void riscv_move_integer (rtx, rtx, HOST_WIDE_INT);
10585 +extern bool riscv_legitimize_move (enum machine_mode, rtx, rtx);
10586 +extern bool riscv_legitimize_vector_move (enum machine_mode, rtx, rtx);
10588 +extern rtx riscv_subword (rtx, bool);
10589 +extern bool riscv_split_64bit_move_p (rtx, rtx);
10590 +extern void riscv_split_doubleword_move (rtx, rtx);
10591 +extern const char *riscv_output_move (rtx, rtx);
10592 +extern const char *riscv_riscv_output_vector_move (enum machine_mode, rtx, rtx);
10593 +#ifdef RTX_CODE
10594 +extern void riscv_expand_scc (rtx *);
10595 +extern void riscv_expand_conditional_branch (rtx *);
10596 +#endif
10597 +extern rtx riscv_expand_call (bool, rtx, rtx, rtx);
10598 +extern void riscv_expand_fcc_reload (rtx, rtx, rtx);
10599 +extern void riscv_set_return_address (rtx, rtx);
10600 +extern bool riscv_expand_block_move (rtx, rtx, rtx);
10601 +extern void riscv_expand_synci_loop (rtx, rtx);
10603 +extern bool riscv_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,
10604 + HOST_WIDE_INT);
10605 +extern bool riscv_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT,
10606 + HOST_WIDE_INT);
10607 +extern void riscv_order_regs_for_local_alloc (void);
10609 +extern rtx riscv_return_addr (int, rtx);
10610 +extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int);
10611 +extern void riscv_expand_prologue (void);
10612 +extern void riscv_expand_epilogue (bool);
10613 +extern bool riscv_can_use_return_insn (void);
10614 +extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode);
10616 +extern enum reg_class riscv_secondary_reload_class (enum reg_class,
10617 + enum machine_mode,
10618 + rtx, bool);
10619 +extern int riscv_class_max_nregs (enum reg_class, enum machine_mode);
10621 +extern unsigned int riscv_hard_regno_nregs (int, enum machine_mode);
10623 +extern void irix_asm_output_align (FILE *, unsigned);
10624 +extern const char *current_section_name (void);
10625 +extern unsigned int current_section_flags (void);
10627 +extern void riscv_expand_vector_init (rtx, rtx);
10629 +#endif /* ! GCC_RISCV_PROTOS_H */
10630 diff -rNU3 dist.orig/gcc/config/riscv/riscv.c dist/gcc/config/riscv/riscv.c
10631 --- dist.orig/gcc/config/riscv/riscv.c 1970-01-01 01:00:00.000000000 +0100
10632 +++ dist/gcc/config/riscv/riscv.c 2015-10-18 13:19:50.000000000 +0200
10633 @@ -0,0 +1,4309 @@
10634 +/* Subroutines used for code generation for RISC-V.
10635 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
10636 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
10637 + Based on MIPS target for GNU compiler.
10639 +This file is part of GCC.
10641 +GCC is free software; you can redistribute it and/or modify
10642 +it under the terms of the GNU General Public License as published by
10643 +the Free Software Foundation; either version 3, or (at your option)
10644 +any later version.
10646 +GCC is distributed in the hope that it will be useful,
10647 +but WITHOUT ANY WARRANTY; without even the implied warranty of
10648 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10649 +GNU General Public License for more details.
10651 +You should have received a copy of the GNU General Public License
10652 +along with GCC; see the file COPYING3. If not see
10653 +<http://www.gnu.org/licenses/>. */
10655 +#include "config.h"
10656 +#include "system.h"
10657 +#include "coretypes.h"
10658 +#include "tm.h"
10659 +#include "rtl.h"
10660 +#include "regs.h"
10661 +#include "hard-reg-set.h"
10662 +#include "insn-config.h"
10663 +#include "conditions.h"
10664 +#include "insn-attr.h"
10665 +#include "recog.h"
10666 +#include "output.h"
10667 +#include "tree.h"
10668 +//#include "varasm.h"
10669 +//#include "stor-layout.h"
10670 +//#include "calls.h"
10671 +#include "function.h"
10672 +#include "expr.h"
10673 +#include "optabs.h"
10674 +#include "libfuncs.h"
10675 +#include "flags.h"
10676 +#include "reload.h"
10677 +#include "tm_p.h"
10678 +#include "ggc.h"
10679 +#include "gstab.h"
10680 +#include "hashtab.h"
10681 +#include "debug.h"
10682 +#include "target.h"
10683 +#include "target-def.h"
10684 +#include "langhooks.h"
10685 +#include "sched-int.h"
10686 +#include "bitmap.h"
10687 +#include "diagnostic.h"
10688 +#include "target-globals.h"
10689 +#include "symcat.h"
10690 +#include <stdint.h>
10692 +/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
10693 +#define UNSPEC_ADDRESS_P(X) \
10694 + (GET_CODE (X) == UNSPEC \
10695 + && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
10696 + && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
10698 +/* Extract the symbol or label from UNSPEC wrapper X. */
10699 +#define UNSPEC_ADDRESS(X) \
10700 + XVECEXP (X, 0, 0)
10702 +/* Extract the symbol type from UNSPEC wrapper X. */
10703 +#define UNSPEC_ADDRESS_TYPE(X) \
10704 + ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
10706 +/* The maximum distance between the top of the stack frame and the
10707 + value sp has when we save and restore registers. This is set by the
10708 + range of load/store offsets and must also preserve stack alignment. */
10709 +#define RISCV_MAX_FIRST_STACK_STEP (RISCV_IMM_REACH/2 - 16)
10711 +/* True if INSN is a riscv.md pattern or asm statement. */
10712 +#define USEFUL_INSN_P(INSN) \
10713 + (NONDEBUG_INSN_P (INSN) \
10714 + && GET_CODE (PATTERN (INSN)) != USE \
10715 + && GET_CODE (PATTERN (INSN)) != CLOBBER \
10716 + && GET_CODE (PATTERN (INSN)) != ADDR_VEC \
10717 + && GET_CODE (PATTERN (INSN)) != ADDR_DIFF_VEC)
10719 +/* True if bit BIT is set in VALUE. */
10720 +#define BITSET_P(VALUE, BIT) (((VALUE) & (1 << (BIT))) != 0)
10722 +/* Classifies an address.
10724 + ADDRESS_REG
10725 + A natural register + offset address. The register satisfies
10726 + riscv_valid_base_register_p and the offset is a const_arith_operand.
10728 + ADDRESS_LO_SUM
10729 + A LO_SUM rtx. The first operand is a valid base register and
10730 + the second operand is a symbolic address.
10732 + ADDRESS_CONST_INT
10733 + A signed 16-bit constant address.
10735 + ADDRESS_SYMBOLIC:
10736 + A constant symbolic address. */
10737 +enum riscv_address_type {
10738 + ADDRESS_REG,
10739 + ADDRESS_LO_SUM,
10740 + ADDRESS_CONST_INT,
10741 + ADDRESS_SYMBOLIC
10744 +enum riscv_code_model riscv_cmodel = TARGET_DEFAULT_CMODEL;
10746 +/* Macros to create an enumeration identifier for a function prototype. */
10747 +#define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B
10748 +#define RISCV_FTYPE_NAME2(A, B, C) RISCV_##A##_FTYPE_##B##_##C
10749 +#define RISCV_FTYPE_NAME3(A, B, C, D) RISCV_##A##_FTYPE_##B##_##C##_##D
10750 +#define RISCV_FTYPE_NAME4(A, B, C, D, E) RISCV_##A##_FTYPE_##B##_##C##_##D##_##E
10752 +/* Classifies the prototype of a built-in function. */
10753 +enum riscv_function_type {
10754 +#define DEF_RISCV_FTYPE(NARGS, LIST) RISCV_FTYPE_NAME##NARGS LIST,
10755 +#include "config/riscv/riscv-ftypes.def"
10756 +#undef DEF_RISCV_FTYPE
10757 + RISCV_MAX_FTYPE_MAX
10760 +/* Specifies how a built-in function should be converted into rtl. */
10761 +enum riscv_builtin_type {
10762 + /* The function corresponds directly to an .md pattern. The return
10763 + value is mapped to operand 0 and the arguments are mapped to
10764 + operands 1 and above. */
10765 + RISCV_BUILTIN_DIRECT,
10767 + /* The function corresponds directly to an .md pattern. There is no return
10768 + value and the arguments are mapped to operands 0 and above. */
10769 + RISCV_BUILTIN_DIRECT_NO_TARGET
10772 +/* Information about a function's frame layout. */
10773 +struct GTY(()) riscv_frame_info {
10774 + /* The size of the frame in bytes. */
10775 + HOST_WIDE_INT total_size;
10777 + /* Bit X is set if the function saves or restores GPR X. */
10778 + unsigned int mask;
10780 + /* Likewise FPR X. */
10781 + unsigned int fmask;
10783 + /* Offsets of fixed-point and floating-point save areas from frame bottom */
10784 + HOST_WIDE_INT gp_sp_offset;
10785 + HOST_WIDE_INT fp_sp_offset;
10787 + /* Offset of virtual frame pointer from stack pointer/frame bottom */
10788 + HOST_WIDE_INT frame_pointer_offset;
10790 + /* Offset of hard frame pointer from stack pointer/frame bottom */
10791 + HOST_WIDE_INT hard_frame_pointer_offset;
10793 + /* The offset of arg_pointer_rtx from the bottom of the frame. */
10794 + HOST_WIDE_INT arg_pointer_offset;
10797 +struct GTY(()) machine_function {
10798 + /* The number of extra stack bytes taken up by register varargs.
10799 + This area is allocated by the callee at the very top of the frame. */
10800 + int varargs_size;
10802 + /* The current frame information, calculated by riscv_compute_frame_info. */
10803 + struct riscv_frame_info frame;
10806 +/* Information about a single argument. */
10807 +struct riscv_arg_info {
10808 + /* True if the argument is passed in a floating-point register, or
10809 + would have been if we hadn't run out of registers. */
10810 + bool fpr_p;
10812 + /* The number of words passed in registers, rounded up. */
10813 + unsigned int reg_words;
10815 + /* For EABI, the offset of the first register from GP_ARG_FIRST or
10816 + FP_ARG_FIRST. For other ABIs, the offset of the first register from
10817 + the start of the ABI's argument structure (see the CUMULATIVE_ARGS
10818 + comment for details).
10820 + The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
10821 + on the stack. */
10822 + unsigned int reg_offset;
10824 + /* The number of words that must be passed on the stack, rounded up. */
10825 + unsigned int stack_words;
10827 + /* The offset from the start of the stack overflow area of the argument's
10828 + first stack word. Only meaningful when STACK_WORDS is nonzero. */
10829 + unsigned int stack_offset;
10832 +/* Information about an address described by riscv_address_type.
10834 + ADDRESS_CONST_INT
10835 + No fields are used.
10837 + ADDRESS_REG
10838 + REG is the base register and OFFSET is the constant offset.
10840 + ADDRESS_LO_SUM
10841 + REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
10842 + is the type of symbol it references.
10844 + ADDRESS_SYMBOLIC
10845 + SYMBOL_TYPE is the type of symbol that the address references. */
10846 +struct riscv_address_info {
10847 + enum riscv_address_type type;
10848 + rtx reg;
10849 + rtx offset;
10850 + enum riscv_symbol_type symbol_type;
10853 +/* One stage in a constant building sequence. These sequences have
10854 + the form:
10856 + A = VALUE[0]
10857 + A = A CODE[1] VALUE[1]
10858 + A = A CODE[2] VALUE[2]
10859 + ...
10861 + where A is an accumulator, each CODE[i] is a binary rtl operation
10862 + and each VALUE[i] is a constant integer. CODE[0] is undefined. */
10863 +struct riscv_integer_op {
10864 + enum rtx_code code;
10865 + unsigned HOST_WIDE_INT value;
10868 +/* The largest number of operations needed to load an integer constant.
10869 + The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI,
10870 + but we may attempt and reject even worse sequences. */
10871 +#define RISCV_MAX_INTEGER_OPS 32
10873 +/* Costs of various operations on the different architectures. */
10875 +struct riscv_tune_info
10877 + unsigned short fp_add[2];
10878 + unsigned short fp_mul[2];
10879 + unsigned short fp_div[2];
10880 + unsigned short int_mul[2];
10881 + unsigned short int_div[2];
10882 + unsigned short issue_rate;
10883 + unsigned short branch_cost;
10884 + unsigned short fp_to_int_cost;
10885 + unsigned short memory_cost;
10888 +/* Information about one CPU we know about. */
10889 +struct riscv_cpu_info {
10890 + /* This CPU's canonical name. */
10891 + const char *name;
10893 + /* The RISC-V ISA and extensions supported by this CPU. */
10894 + const char *isa;
10896 + /* Tuning parameters for this CPU. */
10897 + const struct riscv_tune_info *tune_info;
10900 +/* Global variables for machine-dependent things. */
10902 +/* Which tuning parameters to use. */
10903 +static const struct riscv_tune_info *tune_info;
10905 +/* Index [M][R] is true if register R is allowed to hold a value of mode M. */
10906 +bool riscv_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
10908 +/* riscv_lo_relocs[X] is the relocation to use when a symbol of type X
10909 + appears in a LO_SUM. It can be null if such LO_SUMs aren't valid or
10910 + if they are matched by a special .md file pattern. */
10911 +const char *riscv_lo_relocs[NUM_SYMBOL_TYPES];
10913 +/* Likewise for HIGHs. */
10914 +const char *riscv_hi_relocs[NUM_SYMBOL_TYPES];
10916 +/* Index R is the smallest register class that contains register R. */
10917 +const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
10918 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10919 + GR_REGS, T_REGS, T_REGS, T_REGS,
10920 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10921 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10922 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10923 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10924 + GR_REGS, GR_REGS, GR_REGS, GR_REGS,
10925 + T_REGS, T_REGS, T_REGS, T_REGS,
10926 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10927 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10928 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10929 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10930 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10931 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10932 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10933 + FP_REGS, FP_REGS, FP_REGS, FP_REGS,
10934 + FRAME_REGS, FRAME_REGS,
10937 +/* Costs to use when optimizing for size. */
10938 +static const struct riscv_tune_info rocket_tune_info = {
10939 + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
10940 + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
10941 + {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
10942 + {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
10943 + {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
10944 + 1, /* issue_rate */
10945 + 3, /* branch_cost */
10946 + COSTS_N_INSNS (2), /* fp_to_int_cost */
10947 + 5 /* memory_cost */
10950 +/* Costs to use when optimizing for size. */
10951 +static const struct riscv_tune_info optimize_size_tune_info = {
10952 + {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
10953 + {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
10954 + {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
10955 + {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
10956 + {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
10957 + 1, /* issue_rate */
10958 + 1, /* branch_cost */
10959 + COSTS_N_INSNS (1), /* fp_to_int_cost */
10960 + 1 /* memory_cost */
10963 +/* A table describing all the processors GCC knows about. */
10964 +static const struct riscv_cpu_info riscv_cpu_info_table[] = {
10965 + /* Entries for generic ISAs. */
10966 + { "rocket", "IMAFD", &rocket_tune_info },
10969 +/* Return the riscv_cpu_info entry for the given name string. */
10971 +static const struct riscv_cpu_info *
10972 +riscv_parse_cpu (const char *cpu_string)
10974 + unsigned int i;
10976 + for (i = 0; i < ARRAY_SIZE (riscv_cpu_info_table); i++)
10977 + if (strcmp (riscv_cpu_info_table[i].name, cpu_string) == 0)
10978 + return riscv_cpu_info_table + i;
10980 + error ("unknown cpu `%s'", cpu_string);
10981 + return riscv_cpu_info_table;
10984 +/* Fill CODES with a sequence of rtl operations to load VALUE.
10985 + Return the number of operations needed. */
10987 +static int
10988 +riscv_build_integer_1 (struct riscv_integer_op *codes, HOST_WIDE_INT value,
10989 + enum machine_mode mode)
10991 + HOST_WIDE_INT low_part = RISCV_CONST_LOW_PART (value);
10992 + int cost = INT_MAX, alt_cost;
10993 + struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
10995 + if (SMALL_OPERAND (value) || LUI_OPERAND (value))
10997 + /* Simply ADDI or LUI */
10998 + codes[0].code = UNKNOWN;
10999 + codes[0].value = value;
11000 + return 1;
11003 + /* End with ADDI */
11004 + if (low_part != 0
11005 + && !(mode == HImode && (int16_t)(value - low_part) != (value - low_part)))
11007 + cost = 1 + riscv_build_integer_1 (codes, value - low_part, mode);
11008 + codes[cost-1].code = PLUS;
11009 + codes[cost-1].value = low_part;
11012 + /* End with XORI */
11013 + if (cost > 2 && (low_part < 0 || mode == HImode))
11015 + alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode);
11016 + alt_codes[alt_cost-1].code = XOR;
11017 + alt_codes[alt_cost-1].value = low_part;
11018 + if (alt_cost < cost)
11019 + cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
11022 + /* Eliminate trailing zeros and end with SLLI */
11023 + if (cost > 2 && (value & 1) == 0)
11025 + int shift = 0;
11026 + while ((value & 1) == 0)
11027 + shift++, value >>= 1;
11028 + alt_cost = 1 + riscv_build_integer_1 (alt_codes, value, mode);
11029 + alt_codes[alt_cost-1].code = ASHIFT;
11030 + alt_codes[alt_cost-1].value = shift;
11031 + if (alt_cost < cost)
11032 + cost = alt_cost, memcpy (codes, alt_codes, sizeof(alt_codes));
11035 + gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
11036 + return cost;
11039 +static int
11040 +riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
11041 + enum machine_mode mode)
11043 + int cost = riscv_build_integer_1 (codes, value, mode);
11045 + /* Eliminate leading zeros and end with SRLI */
11046 + if (value > 0 && cost > 2)
11048 + struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
11049 + int alt_cost, shift = 0;
11050 + HOST_WIDE_INT shifted_val;
11052 + /* Try filling trailing bits with 1s */
11053 + while ((value << shift) >= 0)
11054 + shift++;
11055 + shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1);
11056 + alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
11057 + alt_codes[alt_cost-1].code = LSHIFTRT;
11058 + alt_codes[alt_cost-1].value = shift;
11059 + if (alt_cost < cost)
11060 + cost = alt_cost, memcpy (codes, alt_codes, sizeof (alt_codes));
11062 + /* Try filling trailing bits with 0s */
11063 + shifted_val = value << shift;
11064 + alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
11065 + alt_codes[alt_cost-1].code = LSHIFTRT;
11066 + alt_codes[alt_cost-1].value = shift;
11067 + if (alt_cost < cost)
11068 + cost = alt_cost, memcpy (codes, alt_codes, sizeof (alt_codes));
11071 + return cost;
11074 +static int
11075 +riscv_split_integer_cost (HOST_WIDE_INT val)
11077 + int cost;
11078 + int32_t loval = val, hival = (val - (int32_t)val) >> 32;
11079 + struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
11081 + cost = 2 + riscv_build_integer (codes, loval, VOIDmode);
11082 + if (loval != hival)
11083 + cost += riscv_build_integer (codes, hival, VOIDmode);
11085 + return cost;
11088 +static int
11089 +riscv_integer_cost (HOST_WIDE_INT val)
11091 + struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
11092 + return MIN (riscv_build_integer (codes, val, VOIDmode),
11093 + riscv_split_integer_cost (val));
11096 +/* Try to split a 64b integer into 32b parts, then reassemble. */
11098 +static rtx
11099 +riscv_split_integer (HOST_WIDE_INT val, enum machine_mode mode)
11101 + int32_t loval = val, hival = (val - (int32_t)val) >> 32;
11102 + rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);
11104 + riscv_move_integer (hi, hi, hival);
11105 + riscv_move_integer (lo, lo, loval);
11107 + hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32));
11108 + hi = force_reg (mode, hi);
11110 + return gen_rtx_fmt_ee (PLUS, mode, hi, lo);
11113 +/* Return true if X is a thread-local symbol. */
11115 +static bool
11116 +riscv_tls_symbol_p (const_rtx x)
11118 + return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
11121 +static bool
11122 +riscv_symbol_binds_local_p (const_rtx x)
11124 + return (SYMBOL_REF_DECL (x)
11125 + ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
11126 + : SYMBOL_REF_LOCAL_P (x));
11129 +/* Return the method that should be used to access SYMBOL_REF or
11130 + LABEL_REF X in context CONTEXT. */
11132 +static enum riscv_symbol_type
11133 +riscv_classify_symbol (const_rtx x)
11135 + if (riscv_tls_symbol_p (x))
11136 + return SYMBOL_TLS;
11138 + if (GET_CODE (x) == LABEL_REF)
11140 + if (LABEL_REF_NONLOCAL_P (x))
11141 + return SYMBOL_GOT_DISP;
11142 + return SYMBOL_ABSOLUTE;
11145 + gcc_assert (GET_CODE (x) == SYMBOL_REF);
11147 + if (flag_pic && !riscv_symbol_binds_local_p (x))
11148 + return SYMBOL_GOT_DISP;
11150 + return SYMBOL_ABSOLUTE;
11153 +/* Classify the base of symbolic expression X, given that X appears in
11154 + context CONTEXT. */
11156 +static enum riscv_symbol_type
11157 +riscv_classify_symbolic_expression (rtx x)
11159 + rtx offset;
11161 + split_const (x, &x, &offset);
11162 + if (UNSPEC_ADDRESS_P (x))
11163 + return UNSPEC_ADDRESS_TYPE (x);
11165 + return riscv_classify_symbol (x);
11168 +/* Return true if X is a symbolic constant that can be used in context
11169 + CONTEXT. If it is, store the type of the symbol in *SYMBOL_TYPE. */
11171 +bool
11172 +riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type)
11174 + rtx offset;
11176 + split_const (x, &x, &offset);
11177 + if (UNSPEC_ADDRESS_P (x))
11179 + *symbol_type = UNSPEC_ADDRESS_TYPE (x);
11180 + x = UNSPEC_ADDRESS (x);
11182 + else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
11183 + *symbol_type = riscv_classify_symbol (x);
11184 + else
11185 + return false;
11187 + if (offset == const0_rtx)
11188 + return true;
11190 + /* Check whether a nonzero offset is valid for the underlying
11191 + relocations. */
11192 + switch (*symbol_type)
11194 + case SYMBOL_ABSOLUTE:
11195 + case SYMBOL_TLS_LE:
11196 + return (int32_t) INTVAL (offset) == INTVAL (offset);
11198 + default:
11199 + return false;
11201 + gcc_unreachable ();
11204 +/* Returns the number of instructions necessary to reference a symbol. */
11206 +static int riscv_symbol_insns (enum riscv_symbol_type type)
11208 + switch (type)
11210 + case SYMBOL_TLS: return 0; /* Depends on the TLS model. */
11211 + case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference itself */
11212 + case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference itself */
11213 + case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference itself */
11214 + default: gcc_unreachable();
11218 +/* A for_each_rtx callback. Stop the search if *X references a
11219 + thread-local symbol. */
11221 +static int
11222 +riscv_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
11224 + return riscv_tls_symbol_p (*x);
11227 +/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
11229 +static bool
11230 +riscv_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
11232 + return riscv_const_insns (x) > 0;
11235 +/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
11237 +static bool
11238 +riscv_cannot_force_const_mem (enum machine_mode mode, rtx x)
11240 + enum riscv_symbol_type type;
11241 + rtx base, offset;
11243 + /* There is no assembler syntax for expressing an address-sized
11244 + high part. */
11245 + if (GET_CODE (x) == HIGH)
11246 + return true;
11248 + /* As an optimization, reject constants that riscv_legitimize_move
11249 + can expand inline.
11251 + Suppose we have a multi-instruction sequence that loads constant C
11252 + into register R. If R does not get allocated a hard register, and
11253 + R is used in an operand that allows both registers and memory
11254 + references, reload will consider forcing C into memory and using
11255 + one of the instruction's memory alternatives. Returning false
11256 + here will force it to use an input reload instead. */
11257 + if (CONST_INT_P (x) && riscv_legitimate_constant_p (mode, x))
11258 + return true;
11260 + split_const (x, &base, &offset);
11261 + if (riscv_symbolic_constant_p (base, &type))
11263 + /* The same optimization as for CONST_INT. */
11264 + if (SMALL_INT (offset) && riscv_symbol_insns (type) > 0)
11265 + return true;
11267 + /* It's not worth creating additional dynamic relocations. */
11268 + if (flag_pic)
11269 + return true;
11272 + /* TLS symbols must be computed by riscv_legitimize_move. */
11273 + if (for_each_rtx (&x, &riscv_tls_symbol_ref_1, NULL))
11274 + return true;
11276 + return false;
11279 +/* Return true if register REGNO is a valid base register for mode MODE.
11280 + STRICT_P is true if REG_OK_STRICT is in effect. */
11282 +int
11283 +riscv_regno_mode_ok_for_base_p (int regno, enum machine_mode mode ATTRIBUTE_UNUSED,
11284 + bool strict_p)
11286 + if (!HARD_REGISTER_NUM_P (regno))
11288 + if (!strict_p)
11289 + return true;
11290 + regno = reg_renumber[regno];
11293 + /* These fake registers will be eliminated to either the stack or
11294 + hard frame pointer, both of which are usually valid base registers.
11295 + Reload deals with the cases where the eliminated form isn't valid. */
11296 + if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
11297 + return true;
11299 + return GP_REG_P (regno);
11302 +/* Return true if X is a valid base register for mode MODE.
11303 + STRICT_P is true if REG_OK_STRICT is in effect. */
11305 +static bool
11306 +riscv_valid_base_register_p (rtx x, enum machine_mode mode, bool strict_p)
11308 + if (!strict_p && GET_CODE (x) == SUBREG)
11309 + x = SUBREG_REG (x);
11311 + return (REG_P (x)
11312 + && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
11315 +/* Return true if, for every base register BASE_REG, (plus BASE_REG X)
11316 + can address a value of mode MODE. */
11318 +static bool
11319 +riscv_valid_offset_p (rtx x, enum machine_mode mode)
11321 + /* Check that X is a signed 12-bit number. */
11322 + if (!const_arith_operand (x, Pmode))
11323 + return false;
11325 + /* We may need to split multiword moves, so make sure that every word
11326 + is accessible. */
11327 + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
11328 + && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
11329 + return false;
11331 + return true;
11334 +/* Return true if a LO_SUM can address a value of mode MODE when the
11335 + LO_SUM symbol has type SYMBOL_TYPE. */
11337 +static bool
11338 +riscv_valid_lo_sum_p (enum riscv_symbol_type symbol_type, enum machine_mode mode)
11340 + /* Check that symbols of type SYMBOL_TYPE can be used to access values
11341 + of mode MODE. */
11342 + if (riscv_symbol_insns (symbol_type) == 0)
11343 + return false;
11345 + /* Check that there is a known low-part relocation. */
11346 + if (riscv_lo_relocs[symbol_type] == NULL)
11347 + return false;
11349 + /* We may need to split multiword moves, so make sure that each word
11350 + can be accessed without inducing a carry. This is mainly needed
11351 + for o64, which has historically only guaranteed 64-bit alignment
11352 + for 128-bit types. */
11353 + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
11354 + && GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode))
11355 + return false;
11357 + return true;
11360 +/* Return true if X is a valid address for machine mode MODE. If it is,
11361 + fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
11362 + effect. */
11364 +static bool
11365 +riscv_classify_address (struct riscv_address_info *info, rtx x,
11366 + enum machine_mode mode, bool strict_p)
11368 + switch (GET_CODE (x))
11370 + case REG:
11371 + case SUBREG:
11372 + info->type = ADDRESS_REG;
11373 + info->reg = x;
11374 + info->offset = const0_rtx;
11375 + return riscv_valid_base_register_p (info->reg, mode, strict_p);
11377 + case PLUS:
11378 + info->type = ADDRESS_REG;
11379 + info->reg = XEXP (x, 0);
11380 + info->offset = XEXP (x, 1);
11381 + return (riscv_valid_base_register_p (info->reg, mode, strict_p)
11382 + && riscv_valid_offset_p (info->offset, mode));
11384 + case LO_SUM:
11385 + info->type = ADDRESS_LO_SUM;
11386 + info->reg = XEXP (x, 0);
11387 + info->offset = XEXP (x, 1);
11388 + /* We have to trust the creator of the LO_SUM to do something vaguely
11389 + sane. Target-independent code that creates a LO_SUM should also
11390 + create and verify the matching HIGH. Target-independent code that
11391 + adds an offset to a LO_SUM must prove that the offset will not
11392 + induce a carry. Failure to do either of these things would be
11393 + a bug, and we are not required to check for it here. The RISCV
11394 + backend itself should only create LO_SUMs for valid symbolic
11395 + constants, with the high part being either a HIGH or a copy
11396 + of _gp. */
11397 + info->symbol_type
11398 + = riscv_classify_symbolic_expression (info->offset);
11399 + return (riscv_valid_base_register_p (info->reg, mode, strict_p)
11400 + && riscv_valid_lo_sum_p (info->symbol_type, mode));
11402 + case CONST_INT:
11403 + /* Small-integer addresses don't occur very often, but they
11404 + are legitimate if $0 is a valid base register. */
11405 + info->type = ADDRESS_CONST_INT;
11406 + return SMALL_INT (x);
11408 + default:
11409 + return false;
11413 +/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
11415 +static bool
11416 +riscv_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
11418 + struct riscv_address_info addr;
11420 + return riscv_classify_address (&addr, x, mode, strict_p);
11423 +/* Return the number of instructions needed to load or store a value
11424 + of mode MODE at address X. Return 0 if X isn't valid for MODE.
11425 + Assume that multiword moves may need to be split into word moves
11426 + if MIGHT_SPLIT_P, otherwise assume that a single load or store is
11427 + enough. */
11429 +int
11430 +riscv_address_insns (rtx x, enum machine_mode mode, bool might_split_p)
11432 + struct riscv_address_info addr;
11433 + int n = 1;
11435 + if (!riscv_classify_address (&addr, x, mode, false))
11436 + return 0;
11438 + /* BLKmode is used for single unaligned loads and stores and should
11439 + not count as a multiword mode. */
11440 + if (mode != BLKmode && might_split_p)
11441 + n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
11443 + if (addr.type == ADDRESS_LO_SUM)
11444 + n += riscv_symbol_insns (addr.symbol_type) - 1;
11446 + return n;
11449 +/* Return the number of instructions needed to load constant X.
11450 + Return 0 if X isn't a valid constant. */
11452 +int
11453 +riscv_const_insns (rtx x)
11455 + enum riscv_symbol_type symbol_type;
11456 + rtx offset;
11458 + switch (GET_CODE (x))
11460 + case HIGH:
11461 + if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type)
11462 + || !riscv_hi_relocs[symbol_type])
11463 + return 0;
11465 + /* This is simply an LUI. */
11466 + return 1;
11468 + case CONST_INT:
11470 + int cost = riscv_integer_cost (INTVAL (x));
11471 + /* Force complicated constants to memory. */
11472 + return cost < 4 ? cost : 0;
11475 + case CONST_DOUBLE:
11476 + case CONST_VECTOR:
11477 + /* Allow zeros for normal mode, where we can use x0. */
11478 + return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
11480 + case CONST:
11481 + /* See if we can refer to X directly. */
11482 + if (riscv_symbolic_constant_p (x, &symbol_type))
11483 + return riscv_symbol_insns (symbol_type);
11485 + /* Otherwise try splitting the constant into a base and offset.
11486 + If the offset is a 16-bit value, we can load the base address
11487 + into a register and then use (D)ADDIU to add in the offset.
11488 + If the offset is larger, we can load the base and offset
11489 + into separate registers and add them together with (D)ADDU.
11490 + However, the latter is only possible before reload; during
11491 + and after reload, we must have the option of forcing the
11492 + constant into the pool instead. */
11493 + split_const (x, &x, &offset);
11494 + if (offset != 0)
11496 + int n = riscv_const_insns (x);
11497 + if (n != 0)
11499 + if (SMALL_INT (offset))
11500 + return n + 1;
11501 + else if (!targetm.cannot_force_const_mem (GET_MODE (x), x))
11502 + return n + 1 + riscv_integer_cost (INTVAL (offset));
11505 + return 0;
11507 + case SYMBOL_REF:
11508 + case LABEL_REF:
11509 + return riscv_symbol_insns (riscv_classify_symbol (x));
11511 + default:
11512 + return 0;
11516 +/* X is a doubleword constant that can be handled by splitting it into
11517 + two words and loading each word separately. Return the number of
11518 + instructions required to do this. */
11520 +int
11521 +riscv_split_const_insns (rtx x)
11523 + unsigned int low, high;
11525 + low = riscv_const_insns (riscv_subword (x, false));
11526 + high = riscv_const_insns (riscv_subword (x, true));
11527 + gcc_assert (low > 0 && high > 0);
11528 + return low + high;
11531 +/* Return the number of instructions needed to implement INSN,
11532 + given that it loads from or stores to MEM. */
11534 +int
11535 +riscv_load_store_insns (rtx mem, rtx insn)
11537 + enum machine_mode mode;
11538 + bool might_split_p;
11539 + rtx set;
11541 + gcc_assert (MEM_P (mem));
11542 + mode = GET_MODE (mem);
11544 + /* Try to prove that INSN does not need to be split. */
11545 + might_split_p = true;
11546 + if (GET_MODE_BITSIZE (mode) == 64)
11548 + set = single_set (insn);
11549 + if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
11550 + might_split_p = false;
11553 + return riscv_address_insns (XEXP (mem, 0), mode, might_split_p);
11556 +/* Emit a move from SRC to DEST. Assume that the move expanders can
11557 + handle all moves if !can_create_pseudo_p (). The distinction is
11558 + important because, unlike emit_move_insn, the move expanders know
11559 + how to force Pmode objects into the constant pool even when the
11560 + constant pool address is not itself legitimate. */
11562 +rtx
11563 +riscv_emit_move (rtx dest, rtx src)
11565 + return (can_create_pseudo_p ()
11566 + ? emit_move_insn (dest, src)
11567 + : emit_move_insn_1 (dest, src));
11570 +/* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
11572 +static void
11573 +riscv_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
11575 + emit_insn (gen_rtx_SET (VOIDmode, target,
11576 + gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
11579 +/* Compute (CODE OP0 OP1) and store the result in a new register
11580 + of mode MODE. Return that new register. */
11582 +static rtx
11583 +riscv_force_binary (enum machine_mode mode, enum rtx_code code, rtx op0, rtx op1)
11585 + rtx reg;
11587 + reg = gen_reg_rtx (mode);
11588 + riscv_emit_binary (code, reg, op0, op1);
11589 + return reg;
11592 +/* Copy VALUE to a register and return that register. If new pseudos
11593 + are allowed, copy it into a new register, otherwise use DEST. */
11595 +static rtx
11596 +riscv_force_temporary (rtx dest, rtx value)
11598 + if (can_create_pseudo_p ())
11599 + return force_reg (Pmode, value);
11600 + else
11602 + riscv_emit_move (dest, value);
11603 + return dest;
11607 +/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
11608 + then add CONST_INT OFFSET to the result. */
11610 +static rtx
11611 +riscv_unspec_address_offset (rtx base, rtx offset,
11612 + enum riscv_symbol_type symbol_type)
11614 + base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
11615 + UNSPEC_ADDRESS_FIRST + symbol_type);
11616 + if (offset != const0_rtx)
11617 + base = gen_rtx_PLUS (Pmode, base, offset);
11618 + return gen_rtx_CONST (Pmode, base);
11621 +/* Return an UNSPEC address with underlying address ADDRESS and symbol
11622 + type SYMBOL_TYPE. */
11624 +rtx
11625 +riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type)
11627 + rtx base, offset;
11629 + split_const (address, &base, &offset);
11630 + return riscv_unspec_address_offset (base, offset, symbol_type);
11633 +/* If OP is an UNSPEC address, return the address to which it refers,
11634 + otherwise return OP itself. */
11636 +static rtx
11637 +riscv_strip_unspec_address (rtx op)
11639 + rtx base, offset;
11641 + split_const (op, &base, &offset);
11642 + if (UNSPEC_ADDRESS_P (base))
11643 + op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
11644 + return op;
11647 +/* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
11648 + high part to BASE and return the result. Just return BASE otherwise.
11649 + TEMP is as for riscv_force_temporary.
11651 + The returned expression can be used as the first operand to a LO_SUM. */
11653 +static rtx
11654 +riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type)
11656 + addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type));
11657 + return riscv_force_temporary (temp, addr);
11660 +/* Load an entry from the GOT. */
11661 +static rtx riscv_got_load_tls_gd(rtx dest, rtx sym)
11663 + return (Pmode == DImode ? gen_got_load_tls_gddi(dest, sym) : gen_got_load_tls_gdsi(dest, sym));
11666 +static rtx riscv_got_load_tls_ie(rtx dest, rtx sym)
11668 + return (Pmode == DImode ? gen_got_load_tls_iedi(dest, sym) : gen_got_load_tls_iesi(dest, sym));
11671 +static rtx riscv_tls_add_tp_le(rtx dest, rtx base, rtx sym)
11673 + rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
11674 + return (Pmode == DImode ? gen_tls_add_tp_ledi(dest, base, tp, sym) : gen_tls_add_tp_lesi(dest, base, tp, sym));
11677 +/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
11678 + it appears in a MEM of that mode. Return true if ADDR is a legitimate
11679 + constant in that context and can be split into high and low parts.
11680 + If so, and if LOW_OUT is nonnull, emit the high part and store the
11681 + low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
11683 + TEMP is as for riscv_force_temporary and is used to load the high
11684 + part into a register.
11686 + When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
11687 + a legitimize SET_SRC for an .md pattern, otherwise the low part
11688 + is guaranteed to be a legitimate address for mode MODE. */
11690 +bool
11691 +riscv_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *low_out)
11693 + enum riscv_symbol_type symbol_type;
11694 + rtx high;
11696 + if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
11697 + || !riscv_symbolic_constant_p (addr, &symbol_type)
11698 + || riscv_symbol_insns (symbol_type) == 0
11699 + || !riscv_hi_relocs[symbol_type])
11700 + return false;
11702 + if (low_out)
11704 + switch (symbol_type)
11706 + case SYMBOL_ABSOLUTE:
11707 + high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
11708 + high = riscv_force_temporary (temp, high);
11709 + *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
11710 + break;
11712 + default:
11713 + gcc_unreachable ();
11717 + return true;
11720 +/* Return a legitimate address for REG + OFFSET. TEMP is as for
11721 + riscv_force_temporary; it is only needed when OFFSET is not a
11722 + SMALL_OPERAND. */
11724 +static rtx
11725 +riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
11727 + if (!SMALL_OPERAND (offset))
11729 + rtx high;
11731 + /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
11732 + The addition inside the macro CONST_HIGH_PART may cause an
11733 + overflow, so we need to force a sign-extension check. */
11734 + high = gen_int_mode (RISCV_CONST_HIGH_PART (offset), Pmode);
11735 + offset = RISCV_CONST_LOW_PART (offset);
11736 + high = riscv_force_temporary (temp, high);
11737 + reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
11739 + return plus_constant (Pmode, reg, offset);
11742 +/* The __tls_get_attr symbol. */
11743 +static GTY(()) rtx riscv_tls_symbol;
11745 +/* Return an instruction sequence that calls __tls_get_addr. SYM is
11746 + the TLS symbol we are referencing and TYPE is the symbol type to use
11747 + (either global dynamic or local dynamic). RESULT is an RTX for the
11748 + return value location. */
11750 +static rtx
11751 +riscv_call_tls_get_addr (rtx sym, rtx result)
11753 + rtx insn, a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
11755 + if (!riscv_tls_symbol)
11756 + riscv_tls_symbol = init_one_libfunc ("__tls_get_addr");
11758 + start_sequence ();
11760 + emit_insn (riscv_got_load_tls_gd (a0, sym));
11761 + insn = riscv_expand_call (false, result, riscv_tls_symbol, const0_rtx);
11762 + RTL_CONST_CALL_P (insn) = 1;
11763 + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
11764 + insn = get_insns ();
11766 + end_sequence ();
11768 + return insn;
11771 +/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
11772 + its address. The return value will be both a valid address and a valid
11773 + SET_SRC (either a REG or a LO_SUM). */
11775 +static rtx
11776 +riscv_legitimize_tls_address (rtx loc)
11778 + rtx dest, insn, tp, tmp1;
11779 + enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
11781 + /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
11782 + if (!flag_pic)
11783 + model = TLS_MODEL_LOCAL_EXEC;
11785 + switch (model)
11787 + case TLS_MODEL_LOCAL_DYNAMIC:
11788 + /* Rely on section anchors for the optimization that LDM TLS
11789 + provides. The anchor's address is loaded with GD TLS. */
11790 + case TLS_MODEL_GLOBAL_DYNAMIC:
11791 + tmp1 = gen_rtx_REG (Pmode, GP_RETURN);
11792 + insn = riscv_call_tls_get_addr (loc, tmp1);
11793 + dest = gen_reg_rtx (Pmode);
11794 + emit_libcall_block (insn, dest, tmp1, loc);
11795 + break;
11797 + case TLS_MODEL_INITIAL_EXEC:
11798 + /* la.tls.ie; tp-relative add */
11799 + tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
11800 + tmp1 = gen_reg_rtx (Pmode);
11801 + emit_insn (riscv_got_load_tls_ie (tmp1, loc));
11802 + dest = gen_reg_rtx (Pmode);
11803 + emit_insn (gen_add3_insn (dest, tmp1, tp));
11804 + break;
11806 + case TLS_MODEL_LOCAL_EXEC:
11807 + tmp1 = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE);
11808 + dest = gen_reg_rtx (Pmode);
11809 + emit_insn (riscv_tls_add_tp_le (dest, tmp1, loc));
11810 + dest = gen_rtx_LO_SUM (Pmode, dest,
11811 + riscv_unspec_address (loc, SYMBOL_TLS_LE));
11812 + break;
11814 + default:
11815 + gcc_unreachable ();
11817 + return dest;
11820 +/* If X is not a valid address for mode MODE, force it into a register. */
11822 +static rtx
11823 +riscv_force_address (rtx x, enum machine_mode mode)
11825 + if (!riscv_legitimate_address_p (mode, x, false))
11826 + x = force_reg (Pmode, x);
11827 + return x;
11830 +/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
11831 + be legitimized in a way that the generic machinery might not expect,
11832 + return a new address, otherwise return NULL. MODE is the mode of
11833 + the memory being accessed. */
11835 +static rtx
11836 +riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
11837 + enum machine_mode mode)
11839 + rtx addr;
11841 + if (riscv_tls_symbol_p (x))
11842 + return riscv_legitimize_tls_address (x);
11844 + /* See if the address can split into a high part and a LO_SUM. */
11845 + if (riscv_split_symbol (NULL, x, mode, &addr))
11846 + return riscv_force_address (addr, mode);
11848 + /* Handle BASE + OFFSET using riscv_add_offset. */
11849 + if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
11850 + && INTVAL (XEXP (x, 1)) != 0)
11852 + rtx base = XEXP (x, 0);
11853 + HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
11855 + if (!riscv_valid_base_register_p (base, mode, false))
11856 + base = copy_to_mode_reg (Pmode, base);
11857 + addr = riscv_add_offset (NULL, base, offset);
11858 + return riscv_force_address (addr, mode);
11861 + return x;
11864 +/* Load VALUE into DEST. TEMP is as for riscv_force_temporary. */
11866 +void
11867 +riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value)
11869 + struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
11870 + enum machine_mode mode;
11871 + int i, num_ops;
11872 + rtx x;
11874 + mode = GET_MODE (dest);
11875 + num_ops = riscv_build_integer (codes, value, mode);
11877 + if (can_create_pseudo_p () && num_ops > 2 /* not a simple constant */
11878 + && num_ops >= riscv_split_integer_cost (value))
11879 + x = riscv_split_integer (value, mode);
11880 + else
11882 + /* Apply each binary operation to X. */
11883 + x = GEN_INT (codes[0].value);
11885 + for (i = 1; i < num_ops; i++)
11887 + if (!can_create_pseudo_p ())
11889 + emit_insn (gen_rtx_SET (VOIDmode, temp, x));
11890 + x = temp;
11892 + else
11893 + x = force_reg (mode, x);
11895 + x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
11899 + emit_insn (gen_rtx_SET (VOIDmode, dest, x));
11902 +/* Subroutine of riscv_legitimize_move. Move constant SRC into register
11903 + DEST given that SRC satisfies immediate_operand but doesn't satisfy
11904 + move_operand. */
11906 +static void
11907 +riscv_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
11909 + rtx base, offset;
11911 + /* Split moves of big integers into smaller pieces. */
11912 + if (splittable_const_int_operand (src, mode))
11914 + riscv_move_integer (dest, dest, INTVAL (src));
11915 + return;
11918 + /* Split moves of symbolic constants into high/low pairs. */
11919 + if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
11921 + emit_insn (gen_rtx_SET (VOIDmode, dest, src));
11922 + return;
11925 + /* Generate the appropriate access sequences for TLS symbols. */
11926 + if (riscv_tls_symbol_p (src))
11928 + riscv_emit_move (dest, riscv_legitimize_tls_address (src));
11929 + return;
11932 + /* If we have (const (plus symbol offset)), and that expression cannot
11933 + be forced into memory, load the symbol first and add in the offset. Also
11934 + prefer to do this even if the constant _can_ be forced into memory, as it
11935 + usually produces better code. */
11936 + split_const (src, &base, &offset);
11937 + if (offset != const0_rtx
11938 + && (targetm.cannot_force_const_mem (mode, src) || can_create_pseudo_p ()))
11940 + base = riscv_force_temporary (dest, base);
11941 + riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset)));
11942 + return;
11945 + src = force_const_mem (mode, src);
11947 + /* When using explicit relocs, constant pool references are sometimes
11948 + not legitimate addresses. */
11949 + riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
11950 + riscv_emit_move (dest, src);
11953 +/* If (set DEST SRC) is not a valid move instruction, emit an equivalent
11954 + sequence that is valid. */
11956 +bool
11957 +riscv_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
11959 + if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
11961 + riscv_emit_move (dest, force_reg (mode, src));
11962 + return true;
11965 + /* We need to deal with constants that would be legitimate
11966 + immediate_operands but aren't legitimate move_operands. */
11967 + if (CONSTANT_P (src) && !move_operand (src, mode))
11969 + riscv_legitimize_const_move (mode, dest, src);
11970 + set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
11971 + return true;
11973 + return false;
11976 +/* Return true if there is an instruction that implements CODE and accepts
11977 + X as an immediate operand. */
11979 +static int
11980 +riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
11982 + switch (code)
11984 + case ASHIFT:
11985 + case ASHIFTRT:
11986 + case LSHIFTRT:
11987 + /* All shift counts are truncated to a valid constant. */
11988 + return true;
11990 + case AND:
11991 + case IOR:
11992 + case XOR:
11993 + case PLUS:
11994 + case LT:
11995 + case LTU:
11996 + /* These instructions take 12-bit signed immediates. */
11997 + return SMALL_OPERAND (x);
11999 + case LE:
12000 + /* We add 1 to the immediate and use SLT. */
12001 + return SMALL_OPERAND (x + 1);
12003 + case LEU:
12004 + /* Likewise SLTU, but reject the always-true case. */
12005 + return SMALL_OPERAND (x + 1) && x + 1 != 0;
12007 + case GE:
12008 + case GEU:
12009 + /* We can emulate an immediate of 1 by using GT/GTU against x0. */
12010 + return x == 1;
12012 + default:
12013 + /* By default assume that x0 can be used for 0. */
12014 + return x == 0;
12018 +/* Return the cost of binary operation X, given that the instruction
12019 + sequence for a word-sized or smaller operation takes SIGNLE_INSNS
12020 + instructions and that the sequence of a double-word operation takes
12021 + DOUBLE_INSNS instructions. */
12023 +static int
12024 +riscv_binary_cost (rtx x, int single_insns, int double_insns)
12026 + if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
12027 + return COSTS_N_INSNS (double_insns);
12028 + return COSTS_N_INSNS (single_insns);
12031 +/* Return the cost of sign-extending OP to mode MODE, not including the
12032 + cost of OP itself. */
12034 +static int
12035 +riscv_sign_extend_cost (enum machine_mode mode, rtx op)
12037 + if (MEM_P (op))
12038 + /* Extended loads are as cheap as unextended ones. */
12039 + return 0;
12041 + if (TARGET_64BIT && mode == DImode && GET_MODE (op) == SImode)
12042 + /* A sign extension from SImode to DImode in 64-bit mode is free. */
12043 + return 0;
12045 + /* We need to use a shift left and a shift right. */
12046 + return COSTS_N_INSNS (2);
12049 +/* Return the cost of zero-extending OP to mode MODE, not including the
12050 + cost of OP itself. */
12052 +static int
12053 +riscv_zero_extend_cost (enum machine_mode mode, rtx op)
12055 + if (MEM_P (op))
12056 + /* Extended loads are as cheap as unextended ones. */
12057 + return 0;
12059 + if ((TARGET_64BIT && mode == DImode && GET_MODE (op) == SImode) ||
12060 + ((mode == DImode || mode == SImode) && GET_MODE (op) == HImode))
12061 + /* We need a shift left by 32 bits and a shift right by 32 bits. */
12062 + return COSTS_N_INSNS (2);
12064 + /* We can use ANDI. */
12065 + return COSTS_N_INSNS (1);
12068 +/* Implement TARGET_RTX_COSTS. */
12070 +static bool
12071 +riscv_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
12072 + int *total, bool speed)
12074 + enum machine_mode mode = GET_MODE (x);
12075 + bool float_mode_p = FLOAT_MODE_P (mode);
12076 + int cost;
12078 + switch (code)
12080 + case CONST_INT:
12081 + if (riscv_immediate_operand_p (outer_code, INTVAL (x)))
12083 + *total = 0;
12084 + return true;
12086 + /* Fall through. */
12088 + case SYMBOL_REF:
12089 + case LABEL_REF:
12090 + case CONST_DOUBLE:
12091 + case CONST:
12092 + if (speed)
12093 + *total = 1;
12094 + else if ((cost = riscv_const_insns (x)) > 0)
12095 + *total = COSTS_N_INSNS (cost);
12096 + else /* The instruction will be fetched from the constant pool. */
12097 + *total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE));
12098 + return true;
12100 + case MEM:
12101 + /* If the address is legitimate, return the number of
12102 + instructions it needs. */
12103 + if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0)
12105 + *total = COSTS_N_INSNS (cost + tune_info->memory_cost);
12106 + return true;
12108 + /* Otherwise use the default handling. */
12109 + return false;
12111 + case NOT:
12112 + *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
12113 + return false;
12115 + case AND:
12116 + case IOR:
12117 + case XOR:
12118 + /* Double-word operations use two single-word operations. */
12119 + *total = riscv_binary_cost (x, 1, 2);
12120 + return false;
12122 + case ASHIFT:
12123 + case ASHIFTRT:
12124 + case LSHIFTRT:
12125 + *total = riscv_binary_cost (x, 1, CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
12126 + return false;
12128 + case ABS:
12129 + *total = COSTS_N_INSNS (float_mode_p ? 1 : 3);
12130 + return false;
12132 + case LO_SUM:
12133 + *total = set_src_cost (XEXP (x, 0), speed);
12134 + return true;
12136 + case LT:
12137 + case LTU:
12138 + case LE:
12139 + case LEU:
12140 + case GT:
12141 + case GTU:
12142 + case GE:
12143 + case GEU:
12144 + case EQ:
12145 + case NE:
12146 + case UNORDERED:
12147 + case LTGT:
12148 + /* Branch comparisons have VOIDmode, so use the first operand's
12149 + mode instead. */
12150 + mode = GET_MODE (XEXP (x, 0));
12151 + if (float_mode_p)
12152 + *total = tune_info->fp_add[mode == DFmode];
12153 + else
12154 + *total = riscv_binary_cost (x, 1, 3);
12155 + return false;
12157 + case MINUS:
12158 + if (float_mode_p
12159 + && !HONOR_NANS (mode)
12160 + && !HONOR_SIGNED_ZEROS (mode))
12162 + /* See if we can use NMADD or NMSUB. See riscv.md for the
12163 + associated patterns. */
12164 + rtx op0 = XEXP (x, 0);
12165 + rtx op1 = XEXP (x, 1);
12166 + if (GET_CODE (op0) == MULT && GET_CODE (XEXP (op0, 0)) == NEG)
12168 + *total = (tune_info->fp_mul[mode == DFmode]
12169 + + set_src_cost (XEXP (XEXP (op0, 0), 0), speed)
12170 + + set_src_cost (XEXP (op0, 1), speed)
12171 + + set_src_cost (op1, speed));
12172 + return true;
12174 + if (GET_CODE (op1) == MULT)
12176 + *total = (tune_info->fp_mul[mode == DFmode]
12177 + + set_src_cost (op0, speed)
12178 + + set_src_cost (XEXP (op1, 0), speed)
12179 + + set_src_cost (XEXP (op1, 1), speed));
12180 + return true;
12183 + /* Fall through. */
12185 + case PLUS:
12186 + if (float_mode_p)
12187 + *total = tune_info->fp_add[mode == DFmode];
12188 + else
12189 + *total = riscv_binary_cost (x, 1, 4);
12190 + return false;
12192 + case NEG:
12193 + if (float_mode_p
12194 + && !HONOR_NANS (mode)
12195 + && HONOR_SIGNED_ZEROS (mode))
12197 + /* See if we can use NMADD or NMSUB. See riscv.md for the
12198 + associated patterns. */
12199 + rtx op = XEXP (x, 0);
12200 + if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
12201 + && GET_CODE (XEXP (op, 0)) == MULT)
12203 + *total = (tune_info->fp_mul[mode == DFmode]
12204 + + set_src_cost (XEXP (XEXP (op, 0), 0), speed)
12205 + + set_src_cost (XEXP (XEXP (op, 0), 1), speed)
12206 + + set_src_cost (XEXP (op, 1), speed));
12207 + return true;
12211 + if (float_mode_p)
12212 + *total = tune_info->fp_add[mode == DFmode];
12213 + else
12214 + *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
12215 + return false;
12217 + case MULT:
12218 + if (float_mode_p)
12219 + *total = tune_info->fp_mul[mode == DFmode];
12220 + else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
12221 + *total = 3 * tune_info->int_mul[0] + COSTS_N_INSNS (2);
12222 + else if (!speed)
12223 + *total = COSTS_N_INSNS (1);
12224 + else
12225 + *total = tune_info->int_mul[mode == DImode];
12226 + return false;
12228 + case DIV:
12229 + case SQRT:
12230 + case MOD:
12231 + if (float_mode_p)
12233 + *total = tune_info->fp_div[mode == DFmode];
12234 + return false;
12236 + /* Fall through. */
12238 + case UDIV:
12239 + case UMOD:
12240 + if (speed)
12241 + *total = tune_info->int_div[mode == DImode];
12242 + else
12243 + *total = COSTS_N_INSNS (1);
12244 + return false;
12246 + case SIGN_EXTEND:
12247 + *total = riscv_sign_extend_cost (mode, XEXP (x, 0));
12248 + return false;
12250 + case ZERO_EXTEND:
12251 + *total = riscv_zero_extend_cost (mode, XEXP (x, 0));
12252 + return false;
12254 + case FLOAT:
12255 + case UNSIGNED_FLOAT:
12256 + case FIX:
12257 + case FLOAT_EXTEND:
12258 + case FLOAT_TRUNCATE:
12259 + *total = tune_info->fp_add[mode == DFmode];
12260 + return false;
12262 + default:
12263 + return false;
12267 +/* Implement TARGET_ADDRESS_COST. */
12269 +static int
12270 +riscv_address_cost (rtx addr, enum machine_mode mode,
12271 + addr_space_t as ATTRIBUTE_UNUSED,
12272 + bool speed ATTRIBUTE_UNUSED)
12274 + return riscv_address_insns (addr, mode, false);
12277 +/* Return one word of double-word value OP. HIGH_P is true to select the
12278 + high part or false to select the low part. */
12280 +rtx
12281 +riscv_subword (rtx op, bool high_p)
12283 + unsigned int byte;
12284 + enum machine_mode mode;
12286 + mode = GET_MODE (op);
12287 + if (mode == VOIDmode)
12288 + mode = TARGET_64BIT ? TImode : DImode;
12290 + byte = high_p ? UNITS_PER_WORD : 0;
12292 + if (FP_REG_RTX_P (op))
12293 + return gen_rtx_REG (word_mode, REGNO (op) + high_p);
12295 + if (MEM_P (op))
12296 + return adjust_address (op, word_mode, byte);
12298 + return simplify_gen_subreg (word_mode, op, mode, byte);
12301 +/* Return true if a 64-bit move from SRC to DEST should be split into two. */
12303 +bool
12304 +riscv_split_64bit_move_p (rtx dest, rtx src)
12306 + /* All 64b moves are legal in 64b mode. All 64b FPR <-> FPR and
12307 + FPR <-> MEM moves are legal in 32b mode, too. Although
12308 + FPR <-> GPR moves are not available in general in 32b mode,
12309 + we can at least load 0 into an FPR with fcvt.d.w fpr, x0. */
12310 + return !(TARGET_64BIT
12311 + || (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
12312 + || (FP_REG_RTX_P (dest) && MEM_P (src))
12313 + || (FP_REG_RTX_P (src) && MEM_P (dest))
12314 + || (FP_REG_RTX_P(dest) && src == CONST0_RTX(GET_MODE(src))));
12317 +/* Split a doubleword move from SRC to DEST. On 32-bit targets,
12318 + this function handles 64-bit moves for which riscv_split_64bit_move_p
12319 + holds. For 64-bit targets, this function handles 128-bit moves. */
12321 +void
12322 +riscv_split_doubleword_move (rtx dest, rtx src)
12324 + rtx low_dest;
12326 + /* The operation can be split into two normal moves. Decide in
12327 + which order to do them. */
12328 + low_dest = riscv_subword (dest, false);
12329 + if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
12331 + riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
12332 + riscv_emit_move (low_dest, riscv_subword (src, false));
12334 + else
12336 + riscv_emit_move (low_dest, riscv_subword (src, false));
12337 + riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
12341 +/* Return the appropriate instructions to move SRC into DEST. Assume
12342 + that SRC is operand 1 and DEST is operand 0. */
12344 +const char *
12345 +riscv_output_move (rtx dest, rtx src)
12347 + enum rtx_code dest_code, src_code;
12348 + enum machine_mode mode;
12349 + bool dbl_p;
12351 + dest_code = GET_CODE (dest);
12352 + src_code = GET_CODE (src);
12353 + mode = GET_MODE (dest);
12354 + dbl_p = (GET_MODE_SIZE (mode) == 8);
12356 + if (dbl_p && riscv_split_64bit_move_p (dest, src))
12357 + return "#";
12359 + if ((src_code == REG && GP_REG_P (REGNO (src)))
12360 + || (src == CONST0_RTX (mode)))
12362 + if (dest_code == REG)
12364 + if (GP_REG_P (REGNO (dest)))
12365 + return "mv\t%0,%z1";
12367 + if (FP_REG_P (REGNO (dest)))
12369 + if (!dbl_p)
12370 + return "fmv.s.x\t%0,%z1";
12371 + if (TARGET_64BIT)
12372 + return "fmv.d.x\t%0,%z1";
12373 + /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
12374 + gcc_assert (src == CONST0_RTX (mode));
12375 + return "fcvt.d.w\t%0,x0";
12378 + if (dest_code == MEM)
12379 + switch (GET_MODE_SIZE (mode))
12381 + case 1: return "sb\t%z1,%0";
12382 + case 2: return "sh\t%z1,%0";
12383 + case 4: return "sw\t%z1,%0";
12384 + case 8: return "sd\t%z1,%0";
12387 + if (dest_code == REG && GP_REG_P (REGNO (dest)))
12389 + if (src_code == REG)
12391 + if (FP_REG_P (REGNO (src)))
12392 + return dbl_p ? "fmv.x.d\t%0,%1" : "fmv.x.s\t%0,%1";
12395 + if (src_code == MEM)
12396 + switch (GET_MODE_SIZE (mode))
12398 + case 1: return "lbu\t%0,%1";
12399 + case 2: return "lhu\t%0,%1";
12400 + case 4: return "lw\t%0,%1";
12401 + case 8: return "ld\t%0,%1";
12404 + if (src_code == CONST_INT)
12405 + return "li\t%0,%1";
12407 + if (src_code == HIGH)
12408 + return "lui\t%0,%h1";
12410 + if (symbolic_operand (src, VOIDmode))
12411 + switch (riscv_classify_symbolic_expression (src))
12413 + case SYMBOL_GOT_DISP: return "la\t%0,%1";
12414 + case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
12415 + default: gcc_unreachable();
12418 + if (src_code == REG && FP_REG_P (REGNO (src)))
12420 + if (dest_code == REG && FP_REG_P (REGNO (dest)))
12421 + return dbl_p ? "fmv.d\t%0,%1" : "fmv.s\t%0,%1";
12423 + if (dest_code == MEM)
12424 + return dbl_p ? "fsd\t%1,%0" : "fsw\t%1,%0";
12426 + if (dest_code == REG && FP_REG_P (REGNO (dest)))
12428 + if (src_code == MEM)
12429 + return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1";
12431 + gcc_unreachable ();
12434 +/* Return true if CMP1 is a suitable second operand for integer ordering
12435 + test CODE. See also the *sCC patterns in riscv.md. */
12437 +static bool
12438 +riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
12440 + switch (code)
12442 + case GT:
12443 + case GTU:
12444 + return reg_or_0_operand (cmp1, VOIDmode);
12446 + case GE:
12447 + case GEU:
12448 + return cmp1 == const1_rtx;
12450 + case LT:
12451 + case LTU:
12452 + return arith_operand (cmp1, VOIDmode);
12454 + case LE:
12455 + return sle_operand (cmp1, VOIDmode);
12457 + case LEU:
12458 + return sleu_operand (cmp1, VOIDmode);
12460 + default:
12461 + gcc_unreachable ();
12465 +/* Return true if *CMP1 (of mode MODE) is a valid second operand for
12466 + integer ordering test *CODE, or if an equivalent combination can
12467 + be formed by adjusting *CODE and *CMP1. When returning true, update
12468 + *CODE and *CMP1 with the chosen code and operand, otherwise leave
12469 + them alone. */
12471 +static bool
12472 +riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
12473 + enum machine_mode mode)
12475 + HOST_WIDE_INT plus_one;
12477 + if (riscv_int_order_operand_ok_p (*code, *cmp1))
12478 + return true;
12480 + if (CONST_INT_P (*cmp1))
12481 + switch (*code)
12483 + case LE:
12484 + plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
12485 + if (INTVAL (*cmp1) < plus_one)
12487 + *code = LT;
12488 + *cmp1 = force_reg (mode, GEN_INT (plus_one));
12489 + return true;
12491 + break;
12493 + case LEU:
12494 + plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
12495 + if (plus_one != 0)
12497 + *code = LTU;
12498 + *cmp1 = force_reg (mode, GEN_INT (plus_one));
12499 + return true;
12501 + break;
12503 + default:
12504 + break;
12506 + return false;
12509 +/* Compare CMP0 and CMP1 using ordering test CODE and store the result
12510 + in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
12511 + is nonnull, it's OK to set TARGET to the inverse of the result and
12512 + flip *INVERT_PTR instead. */
12514 +static void
12515 +riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
12516 + rtx target, rtx cmp0, rtx cmp1)
12518 + enum machine_mode mode;
12520 + /* First see if there is a RISCV instruction that can do this operation.
12521 + If not, try doing the same for the inverse operation. If that also
12522 + fails, force CMP1 into a register and try again. */
12523 + mode = GET_MODE (cmp0);
12524 + if (riscv_canonicalize_int_order_test (&code, &cmp1, mode))
12525 + riscv_emit_binary (code, target, cmp0, cmp1);
12526 + else
12528 + enum rtx_code inv_code = reverse_condition (code);
12529 + if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode))
12531 + cmp1 = force_reg (mode, cmp1);
12532 + riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
12534 + else if (invert_ptr == 0)
12536 + rtx inv_target;
12538 + inv_target = riscv_force_binary (GET_MODE (target),
12539 + inv_code, cmp0, cmp1);
12540 + riscv_emit_binary (XOR, target, inv_target, const1_rtx);
12542 + else
12544 + *invert_ptr = !*invert_ptr;
12545 + riscv_emit_binary (inv_code, target, cmp0, cmp1);
12550 +/* Return a register that is zero iff CMP0 and CMP1 are equal.
12551 + The register will have the same mode as CMP0. */
12553 +static rtx
12554 +riscv_zero_if_equal (rtx cmp0, rtx cmp1)
12556 + if (cmp1 == const0_rtx)
12557 + return cmp0;
12559 + return expand_binop (GET_MODE (cmp0), sub_optab,
12560 + cmp0, cmp1, 0, 0, OPTAB_DIRECT);
12563 +/* Return false if we can easily emit code for the FP comparison specified
12564 + by *CODE. If not, set *CODE to its inverse and return true. */
12566 +static bool
12567 +riscv_reversed_fp_cond (enum rtx_code *code)
12569 + switch (*code)
12571 + case EQ:
12572 + case LT:
12573 + case LE:
12574 + case GT:
12575 + case GE:
12576 + case LTGT:
12577 + case ORDERED:
12578 + /* We know how to emit code for these cases... */
12579 + return false;
12581 + default:
12582 + /* ...but we must invert these and rely on the others. */
12583 + *code = reverse_condition_maybe_unordered (*code);
12584 + return true;
12588 +/* Convert a comparison into something that can be used in a branch or
12589 + conditional move. On entry, *OP0 and *OP1 are the values being
12590 + compared and *CODE is the code used to compare them.
12592 + Update *CODE, *OP0 and *OP1 so that they describe the final comparison. */
12594 +static void
12595 +riscv_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1)
12597 + rtx cmp_op0 = *op0;
12598 + rtx cmp_op1 = *op1;
12600 + if (GET_MODE_CLASS (GET_MODE (*op0)) == MODE_INT)
12602 + if (splittable_const_int_operand (cmp_op1, VOIDmode))
12604 + HOST_WIDE_INT rhs = INTVAL (cmp_op1), new_rhs;
12605 + enum rtx_code new_code;
12607 + switch (*code)
12609 + case LTU: new_rhs = rhs - 1; new_code = LEU; goto try_new_rhs;
12610 + case LEU: new_rhs = rhs + 1; new_code = LTU; goto try_new_rhs;
12611 + case GTU: new_rhs = rhs + 1; new_code = GEU; goto try_new_rhs;
12612 + case GEU: new_rhs = rhs - 1; new_code = GTU; goto try_new_rhs;
12613 + case LT: new_rhs = rhs - 1; new_code = LE; goto try_new_rhs;
12614 + case LE: new_rhs = rhs + 1; new_code = LT; goto try_new_rhs;
12615 + case GT: new_rhs = rhs + 1; new_code = GE; goto try_new_rhs;
12616 + case GE: new_rhs = rhs - 1; new_code = GT;
12617 + try_new_rhs:
12618 + /* Convert e.g. OP0 > 4095 into OP0 >= 4096. */
12619 + if ((rhs < 0) == (new_rhs < 0)
12620 + && riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs))
12622 + *op1 = GEN_INT (new_rhs);
12623 + *code = new_code;
12625 + break;
12627 + case EQ:
12628 + case NE:
12629 + /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
12630 + if (SMALL_OPERAND (-rhs))
12632 + *op0 = gen_reg_rtx (GET_MODE (cmp_op0));
12633 + riscv_emit_binary (PLUS, *op0, cmp_op0, GEN_INT (-rhs));
12634 + *op1 = const0_rtx;
12636 + default:
12637 + break;
12641 + if (*op1 != const0_rtx)
12642 + *op1 = force_reg (GET_MODE (cmp_op0), *op1);
12644 + else
12646 + /* For FP comparisons, set an integer register with the result of the
12647 + comparison, then branch on it. */
12648 + rtx tmp0, tmp1, final_op;
12649 + enum rtx_code fp_code = *code;
12650 + *code = riscv_reversed_fp_cond (&fp_code) ? EQ : NE;
12652 + switch (fp_code)
12654 + case ORDERED:
12655 + /* a == a && b == b */
12656 + tmp0 = gen_reg_rtx (SImode);
12657 + riscv_emit_binary (EQ, tmp0, cmp_op0, cmp_op0);
12658 + tmp1 = gen_reg_rtx (SImode);
12659 + riscv_emit_binary (EQ, tmp1, cmp_op1, cmp_op1);
12660 + final_op = gen_reg_rtx (SImode);
12661 + riscv_emit_binary (AND, final_op, tmp0, tmp1);
12662 + break;
12664 + case LTGT:
12665 + /* a < b || a > b */
12666 + tmp0 = gen_reg_rtx (SImode);
12667 + riscv_emit_binary (LT, tmp0, cmp_op0, cmp_op1);
12668 + tmp1 = gen_reg_rtx (SImode);
12669 + riscv_emit_binary (GT, tmp1, cmp_op0, cmp_op1);
12670 + final_op = gen_reg_rtx (SImode);
12671 + riscv_emit_binary (IOR, final_op, tmp0, tmp1);
12672 + break;
12674 + case EQ:
12675 + case LE:
12676 + case LT:
12677 + case GE:
12678 + case GT:
12679 + /* We have instructions for these cases. */
12680 + final_op = gen_reg_rtx (SImode);
12681 + riscv_emit_binary (fp_code, final_op, cmp_op0, cmp_op1);
12682 + break;
12684 + default:
12685 + gcc_unreachable ();
12688 + /* Compare the binary result against 0. */
12689 + *op0 = final_op;
12690 + *op1 = const0_rtx;
12694 +/* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
12695 + and OPERAND[3]. Store the result in OPERANDS[0].
12697 + On 64-bit targets, the mode of the comparison and target will always be
12698 + SImode, thus possibly narrower than that of the comparison's operands. */
12700 +void
12701 +riscv_expand_scc (rtx operands[])
12703 + rtx target = operands[0];
12704 + enum rtx_code code = GET_CODE (operands[1]);
12705 + rtx op0 = operands[2];
12706 + rtx op1 = operands[3];
12708 + gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT);
12710 + if (code == EQ || code == NE)
12712 + rtx zie = riscv_zero_if_equal (op0, op1);
12713 + riscv_emit_binary (code, target, zie, const0_rtx);
12715 + else
12716 + riscv_emit_int_order_test (code, 0, target, op0, op1);
12719 +/* Compare OPERANDS[1] with OPERANDS[2] using comparison code
12720 + CODE and jump to OPERANDS[3] if the condition holds. */
12722 +void
12723 +riscv_expand_conditional_branch (rtx *operands)
12725 + enum rtx_code code = GET_CODE (operands[0]);
12726 + rtx op0 = operands[1];
12727 + rtx op1 = operands[2];
12728 + rtx condition;
12730 + riscv_emit_compare (&code, &op0, &op1);
12731 + condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
12732 + emit_jump_insn (gen_condjump (condition, operands[3]));
12735 +/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
12736 + least PARM_BOUNDARY bits of alignment, but will be given anything up
12737 + to STACK_BOUNDARY bits if the type requires it. */
12739 +static unsigned int
12740 +riscv_function_arg_boundary (enum machine_mode mode, const_tree type)
12742 + unsigned int alignment;
12744 + alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
12745 + if (alignment < PARM_BOUNDARY)
12746 + alignment = PARM_BOUNDARY;
12747 + if (alignment > STACK_BOUNDARY)
12748 + alignment = STACK_BOUNDARY;
12749 + return alignment;
12752 +/* Fill INFO with information about a single argument. CUM is the
12753 + cumulative state for earlier arguments. MODE is the mode of this
12754 + argument and TYPE is its type (if known). NAMED is true if this
12755 + is a named (fixed) argument rather than a variable one. */
12757 +static void
12758 +riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
12759 + enum machine_mode mode, const_tree type, bool named)
12761 + bool doubleword_aligned_p;
12762 + unsigned int num_bytes, num_words, max_regs;
12764 + /* Work out the size of the argument. */
12765 + num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
12766 + num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
12768 + /* Scalar, complex and vector floating-point types are passed in
12769 + floating-point registers, as long as this is a named rather
12770 + than a variable argument. */
12771 + info->fpr_p = (named
12772 + && (type == 0 || FLOAT_TYPE_P (type))
12773 + && (GET_MODE_CLASS (mode) == MODE_FLOAT
12774 + || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
12775 + || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
12776 + && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FPVALUE);
12778 + /* Complex floats should only go into FPRs if there are two FPRs free,
12779 + otherwise they should be passed in the same way as a struct
12780 + containing two floats. */
12781 + if (info->fpr_p
12782 + && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
12783 + && GET_MODE_UNIT_SIZE (mode) < UNITS_PER_FPVALUE)
12785 + if (cum->num_gprs >= MAX_ARGS_IN_REGISTERS - 1)
12786 + info->fpr_p = false;
12787 + else
12788 + num_words = 2;
12791 + /* See whether the argument has doubleword alignment. */
12792 + doubleword_aligned_p = (riscv_function_arg_boundary (mode, type)
12793 + > BITS_PER_WORD);
12795 + /* Set REG_OFFSET to the register count we're interested in.
12796 + The EABI allocates the floating-point registers separately,
12797 + but the other ABIs allocate them like integer registers. */
12798 + info->reg_offset = cum->num_gprs;
12800 + /* Advance to an even register if the argument is doubleword-aligned. */
12801 + if (doubleword_aligned_p)
12802 + info->reg_offset += info->reg_offset & 1;
12804 + /* Work out the offset of a stack argument. */
12805 + info->stack_offset = cum->stack_words;
12806 + if (doubleword_aligned_p)
12807 + info->stack_offset += info->stack_offset & 1;
12809 + max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
12811 + /* Partition the argument between registers and stack. */
12812 + info->reg_words = MIN (num_words, max_regs);
12813 + info->stack_words = num_words - info->reg_words;
12816 +/* INFO describes a register argument that has the normal format for the
12817 + argument's mode. Return the register it uses, assuming that FPRs are
12818 + available if HARD_FLOAT_P. */
12820 +static unsigned int
12821 +riscv_arg_regno (const struct riscv_arg_info *info, bool hard_float_p)
12823 + if (!info->fpr_p || !hard_float_p)
12824 + return GP_ARG_FIRST + info->reg_offset;
12825 + else
12826 + return FP_ARG_FIRST + info->reg_offset;
12829 +/* Implement TARGET_FUNCTION_ARG. */
12831 +static rtx
12832 +riscv_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
12833 + const_tree type, bool named)
12835 + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
12836 + struct riscv_arg_info info;
12838 + if (mode == VOIDmode)
12839 + return NULL;
12841 + riscv_get_arg_info (&info, cum, mode, type, named);
12843 + /* Return straight away if the whole argument is passed on the stack. */
12844 + if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
12845 + return NULL;
12847 + /* The n32 and n64 ABIs say that if any 64-bit chunk of the structure
12848 + contains a double in its entirety, then that 64-bit chunk is passed
12849 + in a floating-point register. */
12850 + if (TARGET_HARD_FLOAT
12851 + && named
12852 + && type != 0
12853 + && TREE_CODE (type) == RECORD_TYPE
12854 + && TYPE_SIZE_UNIT (type)
12855 + && host_integerp (TYPE_SIZE_UNIT (type), 1))
12856 + //&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
12858 + tree field;
12860 + /* First check to see if there is any such field. */
12861 + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
12862 + if (TREE_CODE (field) == FIELD_DECL
12863 + && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))
12864 + && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
12865 + && host_integerp (bit_position (field), 0)
12866 + //&& tree_fits_shwi_p (bit_position (field))
12867 + && int_bit_position (field) % BITS_PER_WORD == 0)
12868 + break;
12870 + if (field != 0)
12872 + /* Now handle the special case by returning a PARALLEL
12873 + indicating where each 64-bit chunk goes. INFO.REG_WORDS
12874 + chunks are passed in registers. */
12875 + unsigned int i;
12876 + HOST_WIDE_INT bitpos;
12877 + rtx ret;
12879 + /* assign_parms checks the mode of ENTRY_PARM, so we must
12880 + use the actual mode here. */
12881 + ret = gen_rtx_PARALLEL (mode, rtvec_alloc (info.reg_words));
12883 + bitpos = 0;
12884 + field = TYPE_FIELDS (type);
12885 + for (i = 0; i < info.reg_words; i++)
12887 + rtx reg;
12889 + for (; field; field = DECL_CHAIN (field))
12890 + if (TREE_CODE (field) == FIELD_DECL
12891 + && int_bit_position (field) >= bitpos)
12892 + break;
12894 + if (field
12895 + && int_bit_position (field) == bitpos
12896 + && SCALAR_FLOAT_TYPE_P (TREE_TYPE (field))
12897 + && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
12898 + reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i);
12899 + else
12900 + reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i);
12902 + XVECEXP (ret, 0, i)
12903 + = gen_rtx_EXPR_LIST (VOIDmode, reg,
12904 + GEN_INT (bitpos / BITS_PER_UNIT));
12906 + bitpos += BITS_PER_WORD;
12908 + return ret;
12912 + /* Handle the n32/n64 conventions for passing complex floating-point
12913 + arguments in FPR pairs. The real part goes in the lower register
12914 + and the imaginary part goes in the upper register. */
12915 + if (info.fpr_p
12916 + && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
12918 + rtx real, imag;
12919 + enum machine_mode inner;
12920 + unsigned int regno;
12922 + inner = GET_MODE_INNER (mode);
12923 + regno = FP_ARG_FIRST + info.reg_offset;
12924 + if (info.reg_words * UNITS_PER_WORD == GET_MODE_SIZE (inner))
12926 + /* Real part in registers, imaginary part on stack. */
12927 + gcc_assert (info.stack_words == info.reg_words);
12928 + return gen_rtx_REG (inner, regno);
12930 + else
12932 + gcc_assert (info.stack_words == 0);
12933 + real = gen_rtx_EXPR_LIST (VOIDmode,
12934 + gen_rtx_REG (inner, regno),
12935 + const0_rtx);
12936 + imag = gen_rtx_EXPR_LIST (VOIDmode,
12937 + gen_rtx_REG (inner,
12938 + regno + info.reg_words / 2),
12939 + GEN_INT (GET_MODE_SIZE (inner)));
12940 + return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
12944 + return gen_rtx_REG (mode, riscv_arg_regno (&info, TARGET_HARD_FLOAT));
12947 +/* Implement TARGET_FUNCTION_ARG_ADVANCE. */
12949 +static void
12950 +riscv_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
12951 + const_tree type, bool named)
12953 + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
12954 + struct riscv_arg_info info;
12956 + riscv_get_arg_info (&info, cum, mode, type, named);
12958 + /* Advance the register count. This has the effect of setting
12959 + num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
12960 + argument required us to skip the final GPR and pass the whole
12961 + argument on the stack. */
12962 + cum->num_gprs = info.reg_offset + info.reg_words;
12964 + /* Advance the stack word count. */
12965 + if (info.stack_words > 0)
12966 + cum->stack_words = info.stack_offset + info.stack_words;
12969 +/* Implement TARGET_ARG_PARTIAL_BYTES. */
12971 +static int
12972 +riscv_arg_partial_bytes (cumulative_args_t cum,
12973 + enum machine_mode mode, tree type, bool named)
12975 + struct riscv_arg_info info;
12977 + riscv_get_arg_info (&info, get_cumulative_args (cum), mode, type, named);
12978 + return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
12981 +/* See whether VALTYPE is a record whose fields should be returned in
12982 + floating-point registers. If so, return the number of fields and
12983 + list them in FIELDS (which should have two elements). Return 0
12984 + otherwise.
12986 + For n32 & n64, a structure with one or two fields is returned in
12987 + floating-point registers as long as every field has a floating-point
12988 + type. */
12990 +static int
12991 +riscv_fpr_return_fields (const_tree valtype, tree *fields)
12993 + tree field;
12994 + int i;
12996 + if (TREE_CODE (valtype) != RECORD_TYPE)
12997 + return 0;
12999 + i = 0;
13000 + for (field = TYPE_FIELDS (valtype); field != 0; field = DECL_CHAIN (field))
13002 + if (TREE_CODE (field) != FIELD_DECL)
13003 + continue;
13005 + if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (field)))
13006 + return 0;
13008 + if (i == 2)
13009 + return 0;
13011 + fields[i++] = field;
13013 + return i;
13016 +/* Return true if the function return value MODE will get returned in a
13017 + floating-point register. */
13019 +static bool
13020 +riscv_return_mode_in_fpr_p (enum machine_mode mode)
13022 + return ((GET_MODE_CLASS (mode) == MODE_FLOAT
13023 + || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
13024 + || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
13025 + && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_HWFPVALUE);
13028 +/* Return the representation of an FPR return register when the
13029 + value being returned in FP_RETURN has mode VALUE_MODE and the
13030 + return type itself has mode TYPE_MODE. On NewABI targets,
13031 + the two modes may be different for structures like:
13033 + struct __attribute__((packed)) foo { float f; }
13035 + where we return the SFmode value of "f" in FP_RETURN, but where
13036 + the structure itself has mode BLKmode. */
13038 +static rtx
13039 +riscv_return_fpr_single (enum machine_mode type_mode,
13040 + enum machine_mode value_mode)
13042 + rtx x;
13044 + x = gen_rtx_REG (value_mode, FP_RETURN);
13045 + if (type_mode != value_mode)
13047 + x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx);
13048 + x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
13050 + return x;
13053 +/* Return a composite value in a pair of floating-point registers.
13054 + MODE1 and OFFSET1 are the mode and byte offset for the first value,
13055 + likewise MODE2 and OFFSET2 for the second. MODE is the mode of the
13056 + complete value.
13058 + For n32 & n64, $f0 always holds the first value and $f2 the second.
13059 + Otherwise the values are packed together as closely as possible. */
13061 +static rtx
13062 +riscv_return_fpr_pair (enum machine_mode mode,
13063 + enum machine_mode mode1, HOST_WIDE_INT offset1,
13064 + enum machine_mode mode2, HOST_WIDE_INT offset2)
13066 + return gen_rtx_PARALLEL
13067 + (mode,
13068 + gen_rtvec (2,
13069 + gen_rtx_EXPR_LIST (VOIDmode,
13070 + gen_rtx_REG (mode1, FP_RETURN),
13071 + GEN_INT (offset1)),
13072 + gen_rtx_EXPR_LIST (VOIDmode,
13073 + gen_rtx_REG (mode2, FP_RETURN + 1),
13074 + GEN_INT (offset2))));
13078 +/* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
13079 + VALTYPE is the return type and MODE is VOIDmode. For libcalls,
13080 + VALTYPE is null and MODE is the mode of the return value. */
13082 +rtx
13083 +riscv_function_value (const_tree valtype, const_tree func, enum machine_mode mode)
13085 + if (valtype)
13087 + tree fields[2];
13088 + int unsigned_p;
13090 + mode = TYPE_MODE (valtype);
13091 + unsigned_p = TYPE_UNSIGNED (valtype);
13093 + /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
13094 + return values, promote the mode here too. */
13095 + mode = promote_function_mode (valtype, mode, &unsigned_p, func, 1);
13097 + /* Handle structures whose fields are returned in $f0/$f2. */
13098 + switch (riscv_fpr_return_fields (valtype, fields))
13100 + case 1:
13101 + return riscv_return_fpr_single (mode,
13102 + TYPE_MODE (TREE_TYPE (fields[0])));
13104 + case 2:
13105 + return riscv_return_fpr_pair (mode,
13106 + TYPE_MODE (TREE_TYPE (fields[0])),
13107 + int_byte_position (fields[0]),
13108 + TYPE_MODE (TREE_TYPE (fields[1])),
13109 + int_byte_position (fields[1]));
13112 + /* Only use FPRs for scalar, complex or vector types. */
13113 + if (!FLOAT_TYPE_P (valtype))
13114 + return gen_rtx_REG (mode, GP_RETURN);
13117 + /* Handle long doubles for n32 & n64. */
13118 + if (mode == TFmode)
13119 + return riscv_return_fpr_pair (mode,
13120 + DImode, 0,
13121 + DImode, GET_MODE_SIZE (mode) / 2);
13123 + if (riscv_return_mode_in_fpr_p (mode))
13125 + if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
13126 + return riscv_return_fpr_pair (mode,
13127 + GET_MODE_INNER (mode), 0,
13128 + GET_MODE_INNER (mode),
13129 + GET_MODE_SIZE (mode) / 2);
13130 + else
13131 + return gen_rtx_REG (mode, FP_RETURN);
13134 + return gen_rtx_REG (mode, GP_RETURN);
13137 +/* Implement TARGET_RETURN_IN_MEMORY. Scalars and small structures
13138 + that fit in two registers are returned in a0/a1. */
13140 +static bool
13141 +riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
13143 + return !IN_RANGE (int_size_in_bytes (type), 0, 2 * UNITS_PER_WORD);
13146 +/* Implement TARGET_PASS_BY_REFERENCE. */
13148 +static bool
13149 +riscv_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
13150 + enum machine_mode mode, const_tree type,
13151 + bool named ATTRIBUTE_UNUSED)
13153 + if (type && riscv_return_in_memory (type, NULL_TREE))
13154 + return true;
13155 + return targetm.calls.must_pass_in_stack (mode, type);
13158 +/* Implement TARGET_SETUP_INCOMING_VARARGS. */
13160 +static void
13161 +riscv_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode,
13162 + tree type, int *pretend_size ATTRIBUTE_UNUSED,
13163 + int no_rtl)
13165 + CUMULATIVE_ARGS local_cum;
13166 + int gp_saved;
13168 + /* The caller has advanced CUM up to, but not beyond, the last named
13169 + argument. Advance a local copy of CUM past the last "real" named
13170 + argument, to find out how many registers are left over. */
13171 + local_cum = *get_cumulative_args (cum);
13172 + riscv_function_arg_advance (pack_cumulative_args (&local_cum), mode, type, 1);
13174 + /* Found out how many registers we need to save. */
13175 + gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
13177 + if (!no_rtl && gp_saved > 0)
13179 + rtx ptr, mem;
13181 + ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
13182 + REG_PARM_STACK_SPACE (cfun->decl)
13183 + - gp_saved * UNITS_PER_WORD);
13184 + mem = gen_frame_mem (BLKmode, ptr);
13185 + set_mem_alias_set (mem, get_varargs_alias_set ());
13187 + move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
13188 + mem, gp_saved);
13190 + if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
13191 + cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
13194 +/* Implement TARGET_EXPAND_BUILTIN_VA_START. */
13196 +static void
13197 +riscv_va_start (tree valist, rtx nextarg)
13199 + nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
13200 + std_expand_builtin_va_start (valist, nextarg);
13203 +/* Expand a call of type TYPE. RESULT is where the result will go (null
13204 + for "call"s and "sibcall"s), ADDR is the address of the function,
13205 + ARGS_SIZE is the size of the arguments and AUX is the value passed
13206 + to us by riscv_function_arg. Return the call itself. */
13208 +rtx
13209 +riscv_expand_call (bool sibcall_p, rtx result, rtx addr, rtx args_size)
13211 + rtx pattern;
13213 + if (!call_insn_operand (addr, VOIDmode))
13215 + rtx reg = RISCV_EPILOGUE_TEMP (Pmode);
13216 + riscv_emit_move (reg, addr);
13217 + addr = reg;
13220 + if (result == 0)
13222 + rtx (*fn) (rtx, rtx);
13224 + if (sibcall_p)
13225 + fn = gen_sibcall_internal;
13226 + else
13227 + fn = gen_call_internal;
13229 + pattern = fn (addr, args_size);
13231 + else if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 2)
13233 + /* Handle return values created by riscv_return_fpr_pair. */
13234 + rtx (*fn) (rtx, rtx, rtx, rtx);
13235 + rtx reg1, reg2;
13237 + if (sibcall_p)
13238 + fn = gen_sibcall_value_multiple_internal;
13239 + else
13240 + fn = gen_call_value_multiple_internal;
13242 + reg1 = XEXP (XVECEXP (result, 0, 0), 0);
13243 + reg2 = XEXP (XVECEXP (result, 0, 1), 0);
13244 + pattern = fn (reg1, addr, args_size, reg2);
13246 + else
13248 + rtx (*fn) (rtx, rtx, rtx);
13250 + if (sibcall_p)
13251 + fn = gen_sibcall_value_internal;
13252 + else
13253 + fn = gen_call_value_internal;
13255 + /* Handle return values created by riscv_return_fpr_single. */
13256 + if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 1)
13257 + result = XEXP (XVECEXP (result, 0, 0), 0);
13258 + pattern = fn (result, addr, args_size);
13261 + return emit_call_insn (pattern);
13264 +/* Emit straight-line code to move LENGTH bytes from SRC to DEST.
13265 + Assume that the areas do not overlap. */
13267 +static void
13268 +riscv_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
13270 + HOST_WIDE_INT offset, delta;
13271 + unsigned HOST_WIDE_INT bits;
13272 + int i;
13273 + enum machine_mode mode;
13274 + rtx *regs;
13276 + bits = MAX( BITS_PER_UNIT,
13277 + MIN( BITS_PER_WORD, MIN( MEM_ALIGN(src),MEM_ALIGN(dest) ) ) );
13279 + mode = mode_for_size (bits, MODE_INT, 0);
13280 + delta = bits / BITS_PER_UNIT;
13282 + /* Allocate a buffer for the temporary registers. */
13283 + regs = XALLOCAVEC (rtx, length / delta);
13285 + /* Load as many BITS-sized chunks as possible. Use a normal load if
13286 + the source has enough alignment, otherwise use left/right pairs. */
13287 + for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
13289 + regs[i] = gen_reg_rtx (mode);
13290 + riscv_emit_move (regs[i], adjust_address (src, mode, offset));
13293 + /* Copy the chunks to the destination. */
13294 + for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
13295 + riscv_emit_move (adjust_address (dest, mode, offset), regs[i]);
13297 + /* Mop up any left-over bytes. */
13298 + if (offset < length)
13300 + src = adjust_address (src, BLKmode, offset);
13301 + dest = adjust_address (dest, BLKmode, offset);
13302 + move_by_pieces (dest, src, length - offset,
13303 + MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0);
13307 +/* Helper function for doing a loop-based block operation on memory
13308 + reference MEM. Each iteration of the loop will operate on LENGTH
13309 + bytes of MEM.
13311 + Create a new base register for use within the loop and point it to
13312 + the start of MEM. Create a new memory reference that uses this
13313 + register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
13315 +static void
13316 +riscv_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
13317 + rtx *loop_reg, rtx *loop_mem)
13319 + *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
13321 + /* Although the new mem does not refer to a known location,
13322 + it does keep up to LENGTH bytes of alignment. */
13323 + *loop_mem = change_address (mem, BLKmode, *loop_reg);
13324 + set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
13327 +/* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
13328 + bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
13329 + the memory regions do not overlap. */
13331 +static void
13332 +riscv_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
13333 + HOST_WIDE_INT bytes_per_iter)
13335 + rtx label, src_reg, dest_reg, final_src, test;
13336 + HOST_WIDE_INT leftover;
13338 + leftover = length % bytes_per_iter;
13339 + length -= leftover;
13341 + /* Create registers and memory references for use within the loop. */
13342 + riscv_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
13343 + riscv_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);
13345 + /* Calculate the value that SRC_REG should have after the last iteration
13346 + of the loop. */
13347 + final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
13348 + 0, 0, OPTAB_WIDEN);
13350 + /* Emit the start of the loop. */
13351 + label = gen_label_rtx ();
13352 + emit_label (label);
13354 + /* Emit the loop body. */
13355 + riscv_block_move_straight (dest, src, bytes_per_iter);
13357 + /* Move on to the next block. */
13358 + riscv_emit_move (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter));
13359 + riscv_emit_move (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter));
13361 + /* Emit the loop condition. */
13362 + test = gen_rtx_NE (VOIDmode, src_reg, final_src);
13363 + if (Pmode == DImode)
13364 + emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label));
13365 + else
13366 + emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
13368 + /* Mop up any left-over bytes. */
13369 + if (leftover)
13370 + riscv_block_move_straight (dest, src, leftover);
13373 +/* Expand a movmemsi instruction, which copies LENGTH bytes from
13374 + memory reference SRC to memory reference DEST. */
13376 +bool
13377 +riscv_expand_block_move (rtx dest, rtx src, rtx length)
13379 + if (CONST_INT_P (length))
13381 + HOST_WIDE_INT factor, align;
13383 + align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD);
13384 + factor = BITS_PER_WORD / align;
13386 + if (INTVAL (length) <= RISCV_MAX_MOVE_BYTES_STRAIGHT / factor)
13388 + riscv_block_move_straight (dest, src, INTVAL (length));
13389 + return true;
13391 + else if (optimize && align >= BITS_PER_WORD)
13393 + riscv_block_move_loop (dest, src, INTVAL (length),
13394 + RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER / factor);
13395 + return true;
13398 + return false;
13401 +/* (Re-)Initialize riscv_lo_relocs and riscv_hi_relocs. */
13403 +static void
13404 +riscv_init_relocs (void)
13406 + memset (riscv_hi_relocs, '\0', sizeof (riscv_hi_relocs));
13407 + memset (riscv_lo_relocs, '\0', sizeof (riscv_lo_relocs));
13409 + if (!flag_pic && riscv_cmodel == CM_MEDLOW)
13411 + riscv_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
13412 + riscv_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
13415 + if (!flag_pic || flag_pie)
13417 + riscv_hi_relocs[SYMBOL_TLS_LE] = "%tprel_hi(";
13418 + riscv_lo_relocs[SYMBOL_TLS_LE] = "%tprel_lo(";
13422 +/* Print symbolic operand OP, which is part of a HIGH or LO_SUM
13423 + in context CONTEXT. RELOCS is the array of relocations to use. */
13425 +static void
13426 +riscv_print_operand_reloc (FILE *file, rtx op, const char **relocs)
13428 + enum riscv_symbol_type symbol_type;
13429 + const char *p;
13431 + symbol_type = riscv_classify_symbolic_expression (op);
13432 + gcc_assert (relocs[symbol_type]);
13434 + fputs (relocs[symbol_type], file);
13435 + output_addr_const (file, riscv_strip_unspec_address (op));
13436 + for (p = relocs[symbol_type]; *p != 0; p++)
13437 + if (*p == '(')
13438 + fputc (')', file);
13441 +static const char *
13442 +riscv_memory_model_suffix (enum memmodel model)
13444 + switch (model)
13446 + case MEMMODEL_ACQ_REL:
13447 + case MEMMODEL_SEQ_CST:
13448 + return ".sc";
13449 + case MEMMODEL_ACQUIRE:
13450 + case MEMMODEL_CONSUME:
13451 + return ".aq";
13452 + case MEMMODEL_RELEASE:
13453 + return ".rl";
13454 + case MEMMODEL_RELAXED:
13455 + return "";
13456 + default: gcc_unreachable();
13460 +/* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
13462 + 'h' Print the high-part relocation associated with OP, after stripping
13463 + any outermost HIGH.
13464 + 'R' Print the low-part relocation associated with OP.
13465 + 'C' Print the integer branch condition for comparison OP.
13466 + 'A' Print the atomic operation suffix for memory model OP.
13467 + 'z' Print $0 if OP is zero, otherwise print OP normally. */
13469 +static void
13470 +riscv_print_operand (FILE *file, rtx op, int letter)
13472 + enum rtx_code code;
13474 + gcc_assert (op);
13475 + code = GET_CODE (op);
13477 + switch (letter)
13479 + case 'h':
13480 + if (code == HIGH)
13481 + op = XEXP (op, 0);
13482 + riscv_print_operand_reloc (file, op, riscv_hi_relocs);
13483 + break;
13485 + case 'R':
13486 + riscv_print_operand_reloc (file, op, riscv_lo_relocs);
13487 + break;
13489 + case 'C':
13490 + /* The RTL names match the instruction names. */
13491 + fputs (GET_RTX_NAME (code), file);
13492 + break;
13494 + case 'A':
13495 + fputs (riscv_memory_model_suffix ((enum memmodel)INTVAL (op)), file);
13496 + break;
13498 + default:
13499 + switch (code)
13501 + case REG:
13502 + if (letter && letter != 'z')
13503 + output_operand_lossage ("invalid use of '%%%c'", letter);
13504 + fprintf (file, "%s", reg_names[REGNO (op)]);
13505 + break;
13507 + case MEM:
13508 + if (letter == 'y')
13509 + fprintf (file, "%s", reg_names[REGNO(XEXP(op, 0))]);
13510 + else if (letter && letter != 'z')
13511 + output_operand_lossage ("invalid use of '%%%c'", letter);
13512 + else
13513 + output_address (XEXP (op, 0));
13514 + break;
13516 + default:
13517 + if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
13518 + fputs (reg_names[GP_REG_FIRST], file);
13519 + else if (letter && letter != 'z')
13520 + output_operand_lossage ("invalid use of '%%%c'", letter);
13521 + else
13522 + output_addr_const (file, riscv_strip_unspec_address (op));
13523 + break;
13528 +/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
13530 +static void
13531 +riscv_print_operand_address (FILE *file, rtx x)
13533 + struct riscv_address_info addr;
13535 + if (riscv_classify_address (&addr, x, word_mode, true))
13536 + switch (addr.type)
13538 + case ADDRESS_REG:
13539 + riscv_print_operand (file, addr.offset, 0);
13540 + fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
13541 + return;
13543 + case ADDRESS_LO_SUM:
13544 + riscv_print_operand_reloc (file, addr.offset, riscv_lo_relocs);
13545 + fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
13546 + return;
13548 + case ADDRESS_CONST_INT:
13549 + output_addr_const (file, x);
13550 + fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
13551 + return;
13553 + case ADDRESS_SYMBOLIC:
13554 + output_addr_const (file, riscv_strip_unspec_address (x));
13555 + return;
13557 + gcc_unreachable ();
13560 +static bool
13561 +riscv_size_ok_for_small_data_p (int size)
13563 + return g_switch_value && IN_RANGE (size, 1, g_switch_value);
13566 +/* Return true if EXP should be placed in the small data section. */
13568 +static bool
13569 +riscv_in_small_data_p (const_tree x)
13571 + if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
13572 + return false;
13574 + if (TREE_CODE (x) == VAR_DECL && DECL_SECTION_NAME (x))
13576 + const char *sec = TREE_STRING_POINTER (DECL_SECTION_NAME (x));
13577 + return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0;
13580 + return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x)));
13583 +/* Return a section for X, handling small data. */
13585 +static section *
13586 +riscv_elf_select_rtx_section (enum machine_mode mode, rtx x,
13587 + unsigned HOST_WIDE_INT align)
13589 + section *s = default_elf_select_rtx_section (mode, x, align);
13591 + if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode)))
13593 + if (strncmp (s->named.name, ".rodata.cst", strlen (".rodata.cst")) == 0)
13595 + /* Rename .rodata.cst* to .srodata.cst*. */
13596 + char name[32];
13597 + sprintf (name, ".s%s", s->named.name + 1);
13598 + return get_section (name, s->named.common.flags, NULL);
13601 + if (s == data_section)
13602 + return sdata_section;
13605 + return s;
13608 +/* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
13610 +static void ATTRIBUTE_UNUSED
13611 +riscv_output_dwarf_dtprel (FILE *file, int size, rtx x)
13613 + switch (size)
13615 + case 4:
13616 + fputs ("\t.dtprelword\t", file);
13617 + break;
13619 + case 8:
13620 + fputs ("\t.dtpreldword\t", file);
13621 + break;
13623 + default:
13624 + gcc_unreachable ();
13626 + output_addr_const (file, x);
13627 + fputs ("+0x800", file);
13630 +/* Make the last instruction frame-related and note that it performs
13631 + the operation described by FRAME_PATTERN. */
13633 +static void
13634 +riscv_set_frame_expr (rtx frame_pattern)
13636 + rtx insn;
13638 + insn = get_last_insn ();
13639 + RTX_FRAME_RELATED_P (insn) = 1;
13640 + REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13641 + frame_pattern,
13642 + REG_NOTES (insn));
13645 +/* Return a frame-related rtx that stores REG at MEM.
13646 + REG must be a single register. */
13648 +static rtx
13649 +riscv_frame_set (rtx mem, rtx reg)
13651 + rtx set;
13653 + set = gen_rtx_SET (VOIDmode, mem, reg);
13654 + RTX_FRAME_RELATED_P (set) = 1;
13656 + return set;
13659 +/* Return true if the current function must save register REGNO. */
13661 +static bool
13662 +riscv_save_reg_p (unsigned int regno)
13664 + bool call_saved = !global_regs[regno] && !call_really_used_regs[regno];
13665 + bool might_clobber = crtl->saves_all_registers
13666 + || df_regs_ever_live_p (regno)
13667 + || (regno == HARD_FRAME_POINTER_REGNUM
13668 + && frame_pointer_needed);
13670 + return (call_saved && might_clobber)
13671 + || (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return);
13674 +/* Populate the current function's riscv_frame_info structure.
13676 + RISC-V stack frames grown downward. High addresses are at the top.
13678 + +-------------------------------+
13679 + | |
13680 + | incoming stack arguments |
13681 + | |
13682 + +-------------------------------+ <-- incoming stack pointer
13683 + | |
13684 + | callee-allocated save area |
13685 + | for arguments that are |
13686 + | split between registers and |
13687 + | the stack |
13688 + | |
13689 + +-------------------------------+ <-- arg_pointer_rtx
13690 + | |
13691 + | callee-allocated save area |
13692 + | for register varargs |
13693 + | |
13694 + +-------------------------------+ <-- hard_frame_pointer_rtx;
13695 + | | stack_pointer_rtx + gp_sp_offset
13696 + | GPR save area | + UNITS_PER_WORD
13697 + | |
13698 + +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
13699 + | | + UNITS_PER_HWVALUE
13700 + | FPR save area |
13701 + | |
13702 + +-------------------------------+ <-- frame_pointer_rtx (virtual)
13703 + | |
13704 + | local variables |
13705 + | |
13706 + P +-------------------------------+
13707 + | |
13708 + | outgoing stack arguments |
13709 + | |
13710 + +-------------------------------+ <-- stack_pointer_rtx
13712 + Dynamic stack allocations such as alloca insert data at point P.
13713 + They decrease stack_pointer_rtx but leave frame_pointer_rtx and
13714 + hard_frame_pointer_rtx unchanged. */
13716 +static void
13717 +riscv_compute_frame_info (void)
13719 + struct riscv_frame_info *frame;
13720 + HOST_WIDE_INT offset;
13721 + unsigned int regno, i;
13723 + frame = &cfun->machine->frame;
13724 + memset (frame, 0, sizeof (*frame));
13726 + /* Find out which GPRs we need to save. */
13727 + for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
13728 + if (riscv_save_reg_p (regno))
13729 + frame->mask |= 1 << (regno - GP_REG_FIRST);
13731 + /* If this function calls eh_return, we must also save and restore the
13732 + EH data registers. */
13733 + if (crtl->calls_eh_return)
13734 + for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
13735 + frame->mask |= 1 << (EH_RETURN_DATA_REGNO (i) - GP_REG_FIRST);
13737 + /* Find out which FPRs we need to save. This loop must iterate over
13738 + the same space as its companion in riscv_for_each_saved_gpr_and_fpr. */
13739 + if (TARGET_HARD_FLOAT)
13740 + for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
13741 + if (riscv_save_reg_p (regno))
13742 + frame->fmask |= 1 << (regno - FP_REG_FIRST);
13744 + /* At the bottom of the frame are any outgoing stack arguments. */
13745 + offset = crtl->outgoing_args_size;
13746 + /* Next are local stack variables. */
13747 + offset += RISCV_STACK_ALIGN (get_frame_size ());
13748 + /* The virtual frame pointer points above the local variables. */
13749 + frame->frame_pointer_offset = offset;
13750 + /* Next are the callee-saved FPRs. */
13751 + if (frame->fmask)
13753 + unsigned num_saved = __builtin_popcount(frame->fmask);
13754 + offset += RISCV_STACK_ALIGN (num_saved * UNITS_PER_FPREG);
13755 + frame->fp_sp_offset = offset - UNITS_PER_HWFPVALUE;
13757 + /* Next are the callee-saved GPRs. */
13758 + if (frame->mask)
13760 + unsigned num_saved = __builtin_popcount(frame->mask);
13761 + offset += RISCV_STACK_ALIGN (num_saved * UNITS_PER_WORD);
13762 + frame->gp_sp_offset = offset - UNITS_PER_WORD;
13764 + /* The hard frame pointer points above the callee-saved GPRs. */
13765 + frame->hard_frame_pointer_offset = offset;
13766 + /* Above the hard frame pointer is the callee-allocated varags save area. */
13767 + offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size);
13768 + frame->arg_pointer_offset = offset;
13769 + /* Next is the callee-allocated area for pretend stack arguments. */
13770 + offset += crtl->args.pretend_args_size;
13771 + frame->total_size = offset;
13772 + /* Next points the incoming stack pointer and any incoming arguments. */
13775 +/* Make sure that we're not trying to eliminate to the wrong hard frame
13776 + pointer. */
13778 +static bool
13779 +riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
13781 + return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
13784 +/* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
13785 + or argument pointer. TO is either the stack pointer or hard frame
13786 + pointer. */
13788 +HOST_WIDE_INT
13789 +riscv_initial_elimination_offset (int from, int to)
13791 + HOST_WIDE_INT src, dest;
13793 + riscv_compute_frame_info ();
13795 + if (to == HARD_FRAME_POINTER_REGNUM)
13796 + dest = cfun->machine->frame.hard_frame_pointer_offset;
13797 + else if (to == STACK_POINTER_REGNUM)
13798 + dest = 0; /* this is the base of all offsets */
13799 + else
13800 + gcc_unreachable ();
13802 + if (from == FRAME_POINTER_REGNUM)
13803 + src = cfun->machine->frame.frame_pointer_offset;
13804 + else if (from == ARG_POINTER_REGNUM)
13805 + src = cfun->machine->frame.arg_pointer_offset;
13806 + else
13807 + gcc_unreachable ();
13809 + return src - dest;
13812 +/* Implement RETURN_ADDR_RTX. We do not support moving back to a
13813 + previous frame. */
13815 +rtx
13816 +riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
13818 + if (count != 0)
13819 + return const0_rtx;
13821 + return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
13824 +/* Emit code to change the current function's return address to
13825 + ADDRESS. SCRATCH is available as a scratch register, if needed.
13826 + ADDRESS and SCRATCH are both word-mode GPRs. */
13828 +void
13829 +riscv_set_return_address (rtx address, rtx scratch)
13831 + rtx slot_address;
13833 + gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
13834 + slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
13835 + cfun->machine->frame.gp_sp_offset);
13836 + riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
13839 +/* A function to save or store a register. The first argument is the
13840 + register and the second is the stack slot. */
13841 +typedef void (*riscv_save_restore_fn) (rtx, rtx);
13843 +/* Use FN to save or restore register REGNO. MODE is the register's
13844 + mode and OFFSET is the offset of its save slot from the current
13845 + stack pointer. */
13847 +static void
13848 +riscv_save_restore_reg (enum machine_mode mode, int regno,
13849 + HOST_WIDE_INT offset, riscv_save_restore_fn fn)
13851 + rtx mem;
13853 + mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset));
13854 + fn (gen_rtx_REG (mode, regno), mem);
13857 +/* Call FN for each register that is saved by the current function.
13858 + SP_OFFSET is the offset of the current stack pointer from the start
13859 + of the frame. */
13861 +static void
13862 +riscv_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset,
13863 + riscv_save_restore_fn fn)
13865 + HOST_WIDE_INT offset;
13866 + int regno;
13868 + /* Save the link register and s-registers. */
13869 + offset = cfun->machine->frame.gp_sp_offset - sp_offset;
13870 + for (regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++)
13871 + if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
13873 + riscv_save_restore_reg (word_mode, regno, offset, fn);
13874 + offset -= UNITS_PER_WORD;
13877 + /* This loop must iterate over the same space as its companion in
13878 + riscv_compute_frame_info. */
13879 + offset = cfun->machine->frame.fp_sp_offset - sp_offset;
13880 + for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
13881 + if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
13883 + riscv_save_restore_reg (DFmode, regno, offset, fn);
13884 + offset -= GET_MODE_SIZE (DFmode);
13888 +/* Emit a move from SRC to DEST, given that one of them is a register
13889 + save slot and that the other is a register. TEMP is a temporary
13890 + GPR of the same mode that is available if need be. */
13892 +static void
13893 +riscv_emit_save_slot_move (rtx dest, rtx src, rtx temp)
13895 + unsigned int regno;
13896 + rtx mem;
13897 + enum reg_class rclass;
13899 + if (REG_P (src))
13901 + regno = REGNO (src);
13902 + mem = dest;
13904 + else
13906 + regno = REGNO (dest);
13907 + mem = src;
13910 + rclass = riscv_secondary_reload_class (REGNO_REG_CLASS (regno),
13911 + GET_MODE (mem), mem, mem == src);
13913 + if (rclass == NO_REGS)
13914 + riscv_emit_move (dest, src);
13915 + else
13917 + gcc_assert (!reg_overlap_mentioned_p (dest, temp));
13918 + riscv_emit_move (temp, src);
13919 + riscv_emit_move (dest, temp);
13921 + if (MEM_P (dest))
13922 + riscv_set_frame_expr (riscv_frame_set (dest, src));
13925 +/* Save register REG to MEM. Make the instruction frame-related. */
13927 +static void
13928 +riscv_save_reg (rtx reg, rtx mem)
13930 + riscv_emit_save_slot_move (mem, reg, RISCV_PROLOGUE_TEMP (GET_MODE (reg)));
13934 +/* Expand the "prologue" pattern. */
13936 +void
13937 +riscv_expand_prologue (void)
13939 + const struct riscv_frame_info *frame;
13940 + HOST_WIDE_INT size;
13941 + rtx insn;
13943 + frame = &cfun->machine->frame;
13944 + size = frame->total_size;
13946 + if (flag_stack_usage_info)
13947 + current_function_static_stack_size = size;
13949 + /* Save the registers. Allocate up to RISCV_MAX_FIRST_STACK_STEP
13950 + bytes beforehand; this is enough to cover the register save area
13951 + without going out of range. */
13952 + if ((frame->mask | frame->fmask) != 0)
13954 + HOST_WIDE_INT step1;
13956 + step1 = MIN (size, RISCV_MAX_FIRST_STACK_STEP);
13957 + insn = gen_add3_insn (stack_pointer_rtx,
13958 + stack_pointer_rtx,
13959 + GEN_INT (-step1));
13960 + RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
13961 + size -= step1;
13962 + riscv_for_each_saved_gpr_and_fpr (size, riscv_save_reg);
13965 + /* Set up the frame pointer, if we're using one. */
13966 + if (frame_pointer_needed)
13968 + insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
13969 + GEN_INT (frame->hard_frame_pointer_offset - size));
13970 + RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
13973 + /* Allocate the rest of the frame. */
13974 + if (size > 0)
13976 + if (SMALL_OPERAND (-size))
13977 + RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
13978 + stack_pointer_rtx,
13979 + GEN_INT (-size)))) = 1;
13980 + else
13982 + riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (size));
13983 + emit_insn (gen_sub3_insn (stack_pointer_rtx,
13984 + stack_pointer_rtx,
13985 + RISCV_PROLOGUE_TEMP (Pmode)));
13987 + /* Describe the combined effect of the previous instructions. */
13988 + riscv_set_frame_expr
13989 + (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
13990 + plus_constant (Pmode, stack_pointer_rtx, -size)));
13995 +/* Emit instructions to restore register REG from slot MEM. */
13997 +static void
13998 +riscv_restore_reg (rtx reg, rtx mem)
14000 + riscv_emit_save_slot_move (reg, mem, RISCV_EPILOGUE_TEMP (GET_MODE (reg)));
14003 +/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
14004 + says which. */
14006 +void
14007 +riscv_expand_epilogue (bool sibcall_p)
14009 + const struct riscv_frame_info *frame;
14010 + HOST_WIDE_INT step1, step2;
14012 + if (!sibcall_p && riscv_can_use_return_insn ())
14014 + emit_jump_insn (gen_return ());
14015 + return;
14018 + /* Split the frame into two. STEP1 is the amount of stack we should
14019 + deallocate before restoring the registers. STEP2 is the amount we
14020 + should deallocate afterwards.
14022 + Start off by assuming that no registers need to be restored. */
14023 + frame = &cfun->machine->frame;
14024 + step1 = frame->total_size;
14025 + step2 = 0;
14027 + /* Move past any dynamic stack allocations. */
14028 + if (cfun->calls_alloca)
14030 + rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
14031 + if (!SMALL_INT (adjust))
14033 + riscv_emit_move (RISCV_EPILOGUE_TEMP (Pmode), adjust);
14034 + adjust = RISCV_EPILOGUE_TEMP (Pmode);
14037 + emit_insn (gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, adjust));
14040 + /* If we need to restore registers, deallocate as much stack as
14041 + possible in the second step without going out of range. */
14042 + if ((frame->mask | frame->fmask) != 0)
14044 + step2 = MIN (step1, RISCV_MAX_FIRST_STACK_STEP);
14045 + step1 -= step2;
14048 + /* Set TARGET to BASE + STEP1. */
14049 + if (step1 > 0)
14051 + /* Get an rtx for STEP1 that we can add to BASE. */
14052 + rtx adjust = GEN_INT (step1);
14053 + if (!SMALL_OPERAND (step1))
14055 + riscv_emit_move (RISCV_EPILOGUE_TEMP (Pmode), adjust);
14056 + adjust = RISCV_EPILOGUE_TEMP (Pmode);
14059 + emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust));
14062 + /* Restore the registers. */
14063 + riscv_for_each_saved_gpr_and_fpr (frame->total_size - step2,
14064 + riscv_restore_reg);
14066 + /* Deallocate the final bit of the frame. */
14067 + if (step2 > 0)
14068 + emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
14069 + GEN_INT (step2)));
14071 + /* Add in the __builtin_eh_return stack adjustment. */
14072 + if (crtl->calls_eh_return)
14073 + emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
14074 + EH_RETURN_STACKADJ_RTX));
14076 + if (!sibcall_p)
14078 + rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
14079 + emit_jump_insn (gen_simple_return_internal (ra));
14083 +/* Return nonzero if this function is known to have a null epilogue.
14084 + This allows the optimizer to omit jumps to jumps if no stack
14085 + was created. */
14087 +bool
14088 +riscv_can_use_return_insn (void)
14090 + return reload_completed && cfun->machine->frame.total_size == 0;
14093 +/* Return true if register REGNO can store a value of mode MODE.
14094 + The result of this function is cached in riscv_hard_regno_mode_ok. */
14096 +static bool
14097 +riscv_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode)
14099 + unsigned int size = GET_MODE_SIZE (mode);
14100 + enum mode_class mclass = GET_MODE_CLASS (mode);
14102 + /* This is hella bogus but ira_build segfaults on RV32 without it. */
14103 + if (VECTOR_MODE_P (mode))
14104 + return true;
14106 + if (GP_REG_P (regno))
14108 + if (size <= UNITS_PER_WORD)
14109 + return true;
14111 + /* Double-word values must be even-register-aligned. */
14112 + if (size <= 2 * UNITS_PER_WORD)
14113 + return regno % 2 == 0;
14116 + if (FP_REG_P (regno))
14118 + if (mclass == MODE_FLOAT
14119 + || mclass == MODE_COMPLEX_FLOAT
14120 + || mclass == MODE_VECTOR_FLOAT)
14121 + return size <= UNITS_PER_FPVALUE;
14124 + return false;
14127 +/* Implement HARD_REGNO_NREGS. */
14129 +unsigned int
14130 +riscv_hard_regno_nregs (int regno, enum machine_mode mode)
14132 + if (FP_REG_P (regno))
14133 + return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
14135 + /* All other registers are word-sized. */
14136 + return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
14139 +/* Implement CLASS_MAX_NREGS, taking the maximum of the cases
14140 + in riscv_hard_regno_nregs. */
14142 +int
14143 +riscv_class_max_nregs (enum reg_class rclass, enum machine_mode mode)
14145 + int size;
14146 + HARD_REG_SET left;
14148 + size = 0x8000;
14149 + COPY_HARD_REG_SET (left, reg_class_contents[(int) rclass]);
14150 + if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS]))
14152 + size = MIN (size, UNITS_PER_FPREG);
14153 + AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]);
14155 + if (!hard_reg_set_empty_p (left))
14156 + size = MIN (size, UNITS_PER_WORD);
14157 + return (GET_MODE_SIZE (mode) + size - 1) / size;
14160 +/* Implement TARGET_PREFERRED_RELOAD_CLASS. */
14162 +static reg_class_t
14163 +riscv_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
14165 + return reg_class_subset_p (FP_REGS, rclass) ? FP_REGS :
14166 + reg_class_subset_p (GR_REGS, rclass) ? GR_REGS :
14167 + rclass;
14170 +/* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
14171 + Return a "canonical" class to represent it in later calculations. */
14173 +static reg_class_t
14174 +riscv_canonicalize_move_class (reg_class_t rclass)
14176 + if (reg_class_subset_p (rclass, GENERAL_REGS))
14177 + rclass = GENERAL_REGS;
14179 + return rclass;
14182 +/* Implement TARGET_REGISTER_MOVE_COST. Return 0 for classes that are the
14183 + maximum of the move costs for subclasses; regclass will work out
14184 + the maximum for us. */
14186 +static int
14187 +riscv_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
14188 + reg_class_t from, reg_class_t to)
14190 + from = riscv_canonicalize_move_class (from);
14191 + to = riscv_canonicalize_move_class (to);
14193 + if ((from == GENERAL_REGS && to == GENERAL_REGS)
14194 + || (from == GENERAL_REGS && to == FP_REGS)
14195 + || (from == FP_REGS && to == FP_REGS))
14196 + return COSTS_N_INSNS (1);
14198 + if (from == FP_REGS && to == GENERAL_REGS)
14199 + return tune_info->fp_to_int_cost;
14201 + return 0;
14204 +/* Implement TARGET_MEMORY_MOVE_COST. */
14206 +static int
14207 +riscv_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
14209 + return (tune_info->memory_cost
14210 + + memory_move_secondary_cost (mode, rclass, in));
14213 +/* Return the register class required for a secondary register when
14214 + copying between one of the registers in RCLASS and value X, which
14215 + has mode MODE. X is the source of the move if IN_P, otherwise it
14216 + is the destination. Return NO_REGS if no secondary register is
14217 + needed. */
14219 +enum reg_class
14220 +riscv_secondary_reload_class (enum reg_class rclass,
14221 + enum machine_mode mode, rtx x,
14222 + bool in_p ATTRIBUTE_UNUSED)
14224 + int regno;
14226 + regno = true_regnum (x);
14228 + if (reg_class_subset_p (rclass, FP_REGS))
14230 + if (MEM_P (x) && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8))
14231 + /* We can use flw/fld/fsw/fsd. */
14232 + return NO_REGS;
14234 + if (GP_REG_P (regno) || x == CONST0_RTX (mode))
14235 + /* We can use fmv or go through memory when mode > Pmode. */
14236 + return NO_REGS;
14238 + if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x))
14239 + /* We can force the constant to memory and use flw/fld. */
14240 + return NO_REGS;
14242 + if (FP_REG_P (regno))
14243 + /* We can use fmv.fmt. */
14244 + return NO_REGS;
14246 + /* Otherwise, we need to reload through an integer register. */
14247 + return GR_REGS;
14249 + if (FP_REG_P (regno))
14250 + return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
14252 + return NO_REGS;
14255 +/* Implement TARGET_MODE_REP_EXTENDED. */
14257 +static int
14258 +riscv_mode_rep_extended (enum machine_mode mode, enum machine_mode mode_rep)
14260 + /* On 64-bit targets, SImode register values are sign-extended to DImode. */
14261 + if (TARGET_64BIT && mode == SImode && mode_rep == DImode)
14262 + return SIGN_EXTEND;
14264 + return UNKNOWN;
14267 +/* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
14269 +static bool
14270 +riscv_scalar_mode_supported_p (enum machine_mode mode)
14272 + if (ALL_FIXED_POINT_MODE_P (mode)
14273 + && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
14274 + return true;
14276 + return default_scalar_mode_supported_p (mode);
14279 +/* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
14280 + dependencies have no cost. */
14282 +static int
14283 +riscv_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
14284 + rtx dep ATTRIBUTE_UNUSED, int cost)
14286 + if (REG_NOTE_KIND (link) != 0)
14287 + return 0;
14288 + return cost;
14291 +/* Return the number of instructions that can be issued per cycle. */
14293 +static int
14294 +riscv_issue_rate (void)
14296 + return tune_info->issue_rate;
14299 +/* This structure describes a single built-in function. */
14300 +struct riscv_builtin_description {
14301 + /* The code of the main .md file instruction. See riscv_builtin_type
14302 + for more information. */
14303 + enum insn_code icode;
14305 + /* The name of the built-in function. */
14306 + const char *name;
14308 + /* Specifies how the function should be expanded. */
14309 + enum riscv_builtin_type builtin_type;
14311 + /* The function's prototype. */
14312 + enum riscv_function_type function_type;
14314 + /* Whether the function is available. */
14315 + unsigned int (*avail) (void);
14318 +static unsigned int
14319 +riscv_builtin_avail_riscv (void)
14321 + return 1;
14324 +/* Construct a riscv_builtin_description from the given arguments.
14326 + INSN is the name of the associated instruction pattern, without the
14327 + leading CODE_FOR_riscv_.
14329 + CODE is the floating-point condition code associated with the
14330 + function. It can be 'f' if the field is not applicable.
14332 + NAME is the name of the function itself, without the leading
14333 + "__builtin_riscv_".
14335 + BUILTIN_TYPE and FUNCTION_TYPE are riscv_builtin_description fields.
14337 + AVAIL is the name of the availability predicate, without the leading
14338 + riscv_builtin_avail_. */
14339 +#define RISCV_BUILTIN(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL) \
14340 + { CODE_FOR_ ## INSN, "__builtin_riscv_" NAME, \
14341 + BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL }
14343 +/* Define __builtin_riscv_<INSN>, which is a RISCV_BUILTIN_DIRECT function
14344 + mapped to instruction CODE_FOR_<INSN>, FUNCTION_TYPE and AVAIL
14345 + are as for RISCV_BUILTIN. */
14346 +#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
14347 + RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
14349 +/* Define __builtin_riscv_<INSN>, which is a RISCV_BUILTIN_DIRECT_NO_TARGET
14350 + function mapped to instruction CODE_FOR_<INSN>, FUNCTION_TYPE
14351 + and AVAIL are as for RISCV_BUILTIN. */
14352 +#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
14353 + RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT_NO_TARGET, \
14354 + FUNCTION_TYPE, AVAIL)
14356 +static const struct riscv_builtin_description riscv_builtins[] = {
14357 + DIRECT_NO_TARGET_BUILTIN (nop, RISCV_VOID_FTYPE_VOID, riscv),
14360 +/* Index I is the function declaration for riscv_builtins[I], or null if the
14361 + function isn't defined on this target. */
14362 +static GTY(()) tree riscv_builtin_decls[ARRAY_SIZE (riscv_builtins)];
14365 +/* Source-level argument types. */
14366 +#define RISCV_ATYPE_VOID void_type_node
14367 +#define RISCV_ATYPE_INT integer_type_node
14368 +#define RISCV_ATYPE_POINTER ptr_type_node
14369 +#define RISCV_ATYPE_CPOINTER const_ptr_type_node
14371 +/* Standard mode-based argument types. */
14372 +#define RISCV_ATYPE_UQI unsigned_intQI_type_node
14373 +#define RISCV_ATYPE_SI intSI_type_node
14374 +#define RISCV_ATYPE_USI unsigned_intSI_type_node
14375 +#define RISCV_ATYPE_DI intDI_type_node
14376 +#define RISCV_ATYPE_UDI unsigned_intDI_type_node
14377 +#define RISCV_ATYPE_SF float_type_node
14378 +#define RISCV_ATYPE_DF double_type_node
14380 +/* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists
14381 + their associated RISCV_ATYPEs. */
14382 +#define RISCV_FTYPE_ATYPES1(A, B) \
14383 + RISCV_ATYPE_##A, RISCV_ATYPE_##B
14385 +#define RISCV_FTYPE_ATYPES2(A, B, C) \
14386 + RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C
14388 +#define RISCV_FTYPE_ATYPES3(A, B, C, D) \
14389 + RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D
14391 +#define RISCV_FTYPE_ATYPES4(A, B, C, D, E) \
14392 + RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D, \
14393 + RISCV_ATYPE_##E
14395 +/* Return the function type associated with function prototype TYPE. */
14397 +static tree
14398 +riscv_build_function_type (enum riscv_function_type type)
14400 + static tree types[(int) RISCV_MAX_FTYPE_MAX];
14402 + if (types[(int) type] == NULL_TREE)
14403 + switch (type)
14405 +#define DEF_RISCV_FTYPE(NUM, ARGS) \
14406 + case RISCV_FTYPE_NAME##NUM ARGS: \
14407 + types[(int) type] \
14408 + = build_function_type_list (RISCV_FTYPE_ATYPES##NUM ARGS, \
14409 + NULL_TREE); \
14410 + break;
14411 +#include "config/riscv/riscv-ftypes.def"
14412 +#undef DEF_RISCV_FTYPE
14413 + default:
14414 + gcc_unreachable ();
14417 + return types[(int) type];
14420 +/* Implement TARGET_INIT_BUILTINS. */
14422 +static void
14423 +riscv_init_builtins (void)
14425 + const struct riscv_builtin_description *d;
14426 + unsigned int i;
14428 + /* Iterate through all of the bdesc arrays, initializing all of the
14429 + builtin functions. */
14430 + for (i = 0; i < ARRAY_SIZE (riscv_builtins); i++)
14432 + d = &riscv_builtins[i];
14433 + if (d->avail ())
14434 + riscv_builtin_decls[i]
14435 + = add_builtin_function (d->name,
14436 + riscv_build_function_type (d->function_type),
14437 + i, BUILT_IN_MD, NULL, NULL);
14441 +/* Implement TARGET_BUILTIN_DECL. */
14443 +static tree
14444 +riscv_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
14446 + if (code >= ARRAY_SIZE (riscv_builtins))
14447 + return error_mark_node;
14448 + return riscv_builtin_decls[code];
14451 +/* Take argument ARGNO from EXP's argument list and convert it into a
14452 + form suitable for input operand OPNO of instruction ICODE. Return the
14453 + value. */
14455 +static rtx
14456 +riscv_prepare_builtin_arg (enum insn_code icode,
14457 + unsigned int opno, tree exp, unsigned int argno)
14459 + tree arg;
14460 + rtx value;
14461 + enum machine_mode mode;
14463 + arg = CALL_EXPR_ARG (exp, argno);
14464 + value = expand_normal (arg);
14465 + mode = insn_data[icode].operand[opno].mode;
14466 + if (!insn_data[icode].operand[opno].predicate (value, mode))
14468 + /* We need to get the mode from ARG for two reasons:
14470 + - to cope with address operands, where MODE is the mode of the
14471 + memory, rather than of VALUE itself.
14473 + - to cope with special predicates like pmode_register_operand,
14474 + where MODE is VOIDmode. */
14475 + value = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (arg)), value);
14477 + /* Check the predicate again. */
14478 + if (!insn_data[icode].operand[opno].predicate (value, mode))
14480 + error ("invalid argument to built-in function");
14481 + return const0_rtx;
14485 + return value;
14488 +/* Return an rtx suitable for output operand OP of instruction ICODE.
14489 + If TARGET is non-null, try to use it where possible. */
14491 +static rtx
14492 +riscv_prepare_builtin_target (enum insn_code icode, unsigned int op, rtx target)
14494 + enum machine_mode mode;
14496 + mode = insn_data[icode].operand[op].mode;
14497 + if (target == 0 || !insn_data[icode].operand[op].predicate (target, mode))
14498 + target = gen_reg_rtx (mode);
14500 + return target;
14503 +/* Expand a RISCV_BUILTIN_DIRECT or RISCV_BUILTIN_DIRECT_NO_TARGET function;
14504 + HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function
14505 + and ICODE is the code of the associated .md pattern. TARGET, if nonnull,
14506 + suggests a good place to put the result. */
14508 +static rtx
14509 +riscv_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
14510 + bool has_target_p)
14512 + rtx ops[MAX_RECOG_OPERANDS];
14513 + int opno, argno;
14515 + /* Map any target to operand 0. */
14516 + opno = 0;
14517 + if (has_target_p)
14519 + target = riscv_prepare_builtin_target (icode, opno, target);
14520 + ops[opno] = target;
14521 + opno++;
14524 + /* Map the arguments to the other operands. The n_operands value
14525 + for an expander includes match_dups and match_scratches as well as
14526 + match_operands, so n_operands is only an upper bound on the number
14527 + of arguments to the expander function. */
14528 + gcc_assert (opno + call_expr_nargs (exp) <= insn_data[icode].n_operands);
14529 + for (argno = 0; argno < call_expr_nargs (exp); argno++, opno++)
14530 + ops[opno] = riscv_prepare_builtin_arg (icode, opno, exp, argno);
14532 + switch (opno)
14534 + case 2:
14535 + emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
14536 + break;
14538 + case 3:
14539 + emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2]));
14540 + break;
14542 + case 4:
14543 + emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]));
14544 + break;
14546 + default:
14547 + gcc_unreachable ();
14549 + return target;
14552 +/* Implement TARGET_EXPAND_BUILTIN. */
14554 +static rtx
14555 +riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
14556 + enum machine_mode mode ATTRIBUTE_UNUSED,
14557 + int ignore ATTRIBUTE_UNUSED)
14559 + tree fndecl;
14560 + unsigned int fcode, avail;
14561 + const struct riscv_builtin_description *d;
14563 + fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
14564 + fcode = DECL_FUNCTION_CODE (fndecl);
14565 + gcc_assert (fcode < ARRAY_SIZE (riscv_builtins));
14566 + d = &riscv_builtins[fcode];
14567 + avail = d->avail ();
14568 + gcc_assert (avail != 0);
14569 + switch (d->builtin_type)
14571 + case RISCV_BUILTIN_DIRECT:
14572 + return riscv_expand_builtin_direct (d->icode, target, exp, true);
14574 + case RISCV_BUILTIN_DIRECT_NO_TARGET:
14575 + return riscv_expand_builtin_direct (d->icode, target, exp, false);
14577 + gcc_unreachable ();
14580 +/* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
14581 + in order to avoid duplicating too much logic from elsewhere. */
14583 +static void
14584 +riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
14585 + HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
14586 + tree function)
14588 + rtx this_rtx, temp1, temp2, insn, fnaddr;
14589 + bool use_sibcall_p;
14591 + /* Pretend to be a post-reload pass while generating rtl. */
14592 + reload_completed = 1;
14594 + /* Mark the end of the (empty) prologue. */
14595 + emit_note (NOTE_INSN_PROLOGUE_END);
14597 + /* Determine if we can use a sibcall to call FUNCTION directly. */
14598 + fnaddr = XEXP (DECL_RTL (function), 0);
14599 + use_sibcall_p = absolute_symbolic_operand (fnaddr, Pmode);
14601 + /* We need two temporary registers in some cases. */
14602 + temp1 = gen_rtx_REG (Pmode, GP_TEMP_FIRST);
14603 + temp2 = gen_rtx_REG (Pmode, GP_TEMP_FIRST + 1);
14605 + /* Find out which register contains the "this" pointer. */
14606 + if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
14607 + this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
14608 + else
14609 + this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
14611 + /* Add DELTA to THIS_RTX. */
14612 + if (delta != 0)
14614 + rtx offset = GEN_INT (delta);
14615 + if (!SMALL_OPERAND (delta))
14617 + riscv_emit_move (temp1, offset);
14618 + offset = temp1;
14620 + emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
14623 + /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
14624 + if (vcall_offset != 0)
14626 + rtx addr;
14628 + /* Set TEMP1 to *THIS_RTX. */
14629 + riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
14631 + /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
14632 + addr = riscv_add_offset (temp2, temp1, vcall_offset);
14634 + /* Load the offset and add it to THIS_RTX. */
14635 + riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
14636 + emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
14639 + /* Jump to the target function. Use a sibcall if direct jumps are
14640 + allowed, otherwise load the address into a register first. */
14641 + if (use_sibcall_p)
14643 + insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
14644 + SIBLING_CALL_P (insn) = 1;
14646 + else
14648 + riscv_emit_move(temp1, fnaddr);
14649 + emit_jump_insn (gen_indirect_jump (temp1));
14652 + /* Run just enough of rest_of_compilation. This sequence was
14653 + "borrowed" from alpha.c. */
14654 + insn = get_insns ();
14655 + split_all_insns_noflow ();
14656 + shorten_branches (insn);
14657 + final_start_function (insn, file, 1);
14658 + final (insn, file, 1);
14659 + final_end_function ();
14661 + /* Clean up the vars set above. Note that final_end_function resets
14662 + the global pointer for us. */
14663 + reload_completed = 0;
14666 +/* Allocate a chunk of memory for per-function machine-dependent data. */
14668 +static struct machine_function *
14669 +riscv_init_machine_status (void)
14671 + return ggc_alloc_cleared_machine_function ();
14674 +/* Implement TARGET_OPTION_OVERRIDE. */
14676 +static void
14677 +riscv_option_override (void)
14679 + int regno, mode;
14680 + const struct riscv_cpu_info *cpu;
14682 +#ifdef SUBTARGET_OVERRIDE_OPTIONS
14683 + SUBTARGET_OVERRIDE_OPTIONS;
14684 +#endif
14686 + flag_pcc_struct_return = 0;
14688 + if (flag_pic)
14689 + g_switch_value = 0;
14691 + /* Prefer a call to memcpy over inline code when optimizing for size,
14692 + though see MOVE_RATIO in riscv.h. */
14693 + if (optimize_size && (target_flags_explicit & MASK_MEMCPY) == 0)
14694 + target_flags |= MASK_MEMCPY;
14696 + /* Handle -mtune. */
14697 + cpu = riscv_parse_cpu (riscv_tune_string ? riscv_tune_string :
14698 + RISCV_TUNE_STRING_DEFAULT);
14699 + tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info;
14701 + /* If the user hasn't specified a branch cost, use the processor's
14702 + default. */
14703 + if (riscv_branch_cost == 0)
14704 + riscv_branch_cost = tune_info->branch_cost;
14706 + /* Set up riscv_hard_regno_mode_ok. */
14707 + for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
14708 + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
14709 + riscv_hard_regno_mode_ok[mode][regno]
14710 + = riscv_hard_regno_mode_ok_p (regno, (enum machine_mode) mode);
14712 + /* Function to allocate machine-dependent function status. */
14713 + init_machine_status = &riscv_init_machine_status;
14715 + if (riscv_cmodel_string)
14717 + if (strcmp (riscv_cmodel_string, "medlow") == 0)
14718 + riscv_cmodel = CM_MEDLOW;
14719 + else if (strcmp (riscv_cmodel_string, "medany") == 0)
14720 + riscv_cmodel = CM_MEDANY;
14721 + else
14722 + error ("unsupported code model: %s", riscv_cmodel_string);
14725 + if (flag_pic)
14726 + riscv_cmodel = CM_PIC;
14728 + riscv_init_relocs ();
14731 +/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
14733 +static void
14734 +riscv_conditional_register_usage (void)
14736 + int regno;
14738 + if (!TARGET_HARD_FLOAT)
14740 + for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
14741 + fixed_regs[regno] = call_used_regs[regno] = 1;
14745 +/* Implement TARGET_TRAMPOLINE_INIT. */
14747 +static void
14748 +riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
14750 + rtx addr, end_addr, mem;
14751 + rtx trampoline[4];
14752 + unsigned int i;
14753 + HOST_WIDE_INT static_chain_offset, target_function_offset;
14755 + /* Work out the offsets of the pointers from the start of the
14756 + trampoline code. */
14757 + gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);
14758 + static_chain_offset = TRAMPOLINE_CODE_SIZE;
14759 + target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
14761 + /* Get pointers to the beginning and end of the code block. */
14762 + addr = force_reg (Pmode, XEXP (m_tramp, 0));
14763 + end_addr = riscv_force_binary (Pmode, PLUS, addr, GEN_INT (TRAMPOLINE_CODE_SIZE));
14765 +#define OP(X) gen_int_mode (X, SImode)
14766 +#define MATCH_LREG ((Pmode) == DImode ? MATCH_LD : MATCH_LW)
14768 + /* auipc t0, 0
14769 + l[wd] t1, target_function_offset(t0)
14770 + l[wd] $static_chain, static_chain_offset(t0)
14771 + jr t1
14772 + */
14774 + trampoline[0] = OP (RISCV_UTYPE (AUIPC, STATIC_CHAIN_REGNUM, 0));
14775 + trampoline[1] = OP (RISCV_ITYPE (LREG, RISCV_PROLOGUE_TEMP_REGNUM,
14776 + STATIC_CHAIN_REGNUM, target_function_offset));
14777 + trampoline[2] = OP (RISCV_ITYPE (LREG, STATIC_CHAIN_REGNUM,
14778 + STATIC_CHAIN_REGNUM, static_chain_offset));
14779 + trampoline[3] = OP (RISCV_ITYPE (JALR, 0, RISCV_PROLOGUE_TEMP_REGNUM, 0));
14781 +#undef MATCH_LREG
14782 +#undef OP
14784 + /* Copy the trampoline code. Leave any padding uninitialized. */
14785 + for (i = 0; i < ARRAY_SIZE (trampoline); i++)
14787 + mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
14788 + riscv_emit_move (mem, trampoline[i]);
14791 + /* Set up the static chain pointer field. */
14792 + mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
14793 + riscv_emit_move (mem, chain_value);
14795 + /* Set up the target function field. */
14796 + mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
14797 + riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
14799 + /* Flush the code part of the trampoline. */
14800 + emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
14801 + emit_insn (gen_clear_cache (addr, end_addr));
14804 +static bool
14805 +riscv_lra_p (void)
14807 + return riscv_lra_flag;
14810 +/* Initialize the GCC target structure. */
14811 +#undef TARGET_ASM_ALIGNED_HI_OP
14812 +#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
14813 +#undef TARGET_ASM_ALIGNED_SI_OP
14814 +#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
14815 +#undef TARGET_ASM_ALIGNED_DI_OP
14816 +#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
14818 +#undef TARGET_OPTION_OVERRIDE
14819 +#define TARGET_OPTION_OVERRIDE riscv_option_override
14821 +#undef TARGET_LEGITIMIZE_ADDRESS
14822 +#define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
14824 +#undef TARGET_SCHED_ADJUST_COST
14825 +#define TARGET_SCHED_ADJUST_COST riscv_adjust_cost
14826 +#undef TARGET_SCHED_ISSUE_RATE
14827 +#define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
14829 +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
14830 +#define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
14832 +#undef TARGET_REGISTER_MOVE_COST
14833 +#define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
14834 +#undef TARGET_MEMORY_MOVE_COST
14835 +#define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
14836 +#undef TARGET_RTX_COSTS
14837 +#define TARGET_RTX_COSTS riscv_rtx_costs
14838 +#undef TARGET_ADDRESS_COST
14839 +#define TARGET_ADDRESS_COST riscv_address_cost
14841 +#undef TARGET_PREFERRED_RELOAD_CLASS
14842 +#define TARGET_PREFERRED_RELOAD_CLASS riscv_preferred_reload_class
14844 +#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
14845 +#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
14847 +#undef TARGET_EXPAND_BUILTIN_VA_START
14848 +#define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
14850 +#undef TARGET_PROMOTE_FUNCTION_MODE
14851 +#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
14853 +#undef TARGET_RETURN_IN_MEMORY
14854 +#define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
14856 +#undef TARGET_ASM_OUTPUT_MI_THUNK
14857 +#define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
14858 +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
14859 +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
14861 +#undef TARGET_PRINT_OPERAND
14862 +#define TARGET_PRINT_OPERAND riscv_print_operand
14863 +#undef TARGET_PRINT_OPERAND_ADDRESS
14864 +#define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
14866 +#undef TARGET_SETUP_INCOMING_VARARGS
14867 +#define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
14868 +#undef TARGET_STRICT_ARGUMENT_NAMING
14869 +#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
14870 +#undef TARGET_MUST_PASS_IN_STACK
14871 +#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
14872 +#undef TARGET_PASS_BY_REFERENCE
14873 +#define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
14874 +#undef TARGET_ARG_PARTIAL_BYTES
14875 +#define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
14876 +#undef TARGET_FUNCTION_ARG
14877 +#define TARGET_FUNCTION_ARG riscv_function_arg
14878 +#undef TARGET_FUNCTION_ARG_ADVANCE
14879 +#define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
14880 +#undef TARGET_FUNCTION_ARG_BOUNDARY
14881 +#define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
14883 +#undef TARGET_MODE_REP_EXTENDED
14884 +#define TARGET_MODE_REP_EXTENDED riscv_mode_rep_extended
14886 +#undef TARGET_SCALAR_MODE_SUPPORTED_P
14887 +#define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p
14889 +#undef TARGET_INIT_BUILTINS
14890 +#define TARGET_INIT_BUILTINS riscv_init_builtins
14891 +#undef TARGET_BUILTIN_DECL
14892 +#define TARGET_BUILTIN_DECL riscv_builtin_decl
14893 +#undef TARGET_EXPAND_BUILTIN
14894 +#define TARGET_EXPAND_BUILTIN riscv_expand_builtin
14896 +#undef TARGET_HAVE_TLS
14897 +#define TARGET_HAVE_TLS HAVE_AS_TLS
14899 +#undef TARGET_CANNOT_FORCE_CONST_MEM
14900 +#define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
14902 +#undef TARGET_LEGITIMATE_CONSTANT_P
14903 +#define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
14905 +#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
14906 +#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
14908 +#ifdef HAVE_AS_DTPRELWORD
14909 +#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
14910 +#define TARGET_ASM_OUTPUT_DWARF_DTPREL riscv_output_dwarf_dtprel
14911 +#endif
14913 +#undef TARGET_LEGITIMATE_ADDRESS_P
14914 +#define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
14916 +#undef TARGET_CAN_ELIMINATE
14917 +#define TARGET_CAN_ELIMINATE riscv_can_eliminate
14919 +#undef TARGET_CONDITIONAL_REGISTER_USAGE
14920 +#define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
14922 +#undef TARGET_TRAMPOLINE_INIT
14923 +#define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
14925 +#undef TARGET_IN_SMALL_DATA_P
14926 +#define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
14928 +#undef TARGET_ASM_SELECT_RTX_SECTION
14929 +#define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
14931 +#undef TARGET_MIN_ANCHOR_OFFSET
14932 +#define TARGET_MIN_ANCHOR_OFFSET (-RISCV_IMM_REACH/2)
14934 +#undef TARGET_MAX_ANCHOR_OFFSET
14935 +#define TARGET_MAX_ANCHOR_OFFSET (RISCV_IMM_REACH/2-1)
14937 +#undef TARGET_LRA_P
14938 +#define TARGET_LRA_P riscv_lra_p
14940 +struct gcc_target targetm = TARGET_INITIALIZER;
14942 +#include "gt-riscv.h"
14943 diff -rNU3 dist.orig/gcc/config/riscv/riscv.h dist/gcc/config/riscv/riscv.h
14944 --- dist.orig/gcc/config/riscv/riscv.h 1970-01-01 01:00:00.000000000 +0100
14945 +++ dist/gcc/config/riscv/riscv.h 2015-10-18 13:19:50.000000000 +0200
14946 @@ -0,0 +1,1132 @@
14947 +/* Definition of RISC-V target for GNU compiler.
14948 + Copyright (C) 2011-2014 Free Software Foundation, Inc.
14949 + Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
14950 + Based on MIPS target for GNU compiler.
14952 +This file is part of GCC.
14954 +GCC is free software; you can redistribute it and/or modify
14955 +it under the terms of the GNU General Public License as published by
14956 +the Free Software Foundation; either version 3, or (at your option)
14957 +any later version.
14959 +GCC is distributed in the hope that it will be useful,
14960 +but WITHOUT ANY WARRANTY; without even the implied warranty of
14961 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14962 +GNU General Public License for more details.
14964 +You should have received a copy of the GNU General Public License
14965 +along with GCC; see the file COPYING3. If not see
14966 +<http://www.gnu.org/licenses/>. */
14968 +/* TARGET_HARD_FLOAT and TARGET_SOFT_FLOAT reflect whether the FPU is
14969 + directly accessible, while the command-line options select
14970 + TARGET_HARD_FLOAT_ABI and TARGET_SOFT_FLOAT_ABI to reflect the ABI
14971 + in use. */
14972 +#define TARGET_HARD_FLOAT TARGET_HARD_FLOAT_ABI
14973 +#define TARGET_SOFT_FLOAT TARGET_SOFT_FLOAT_ABI
14975 +/* Target CPU builtins. */
14976 +#define TARGET_CPU_CPP_BUILTINS() \
14977 + do \
14978 + { \
14979 + builtin_assert ("machine=riscv"); \
14981 + builtin_assert ("cpu=riscv"); \
14982 + builtin_define ("__riscv__"); \
14983 + builtin_define ("__riscv"); \
14984 + builtin_define ("_riscv"); \
14986 + if (TARGET_64BIT) \
14987 + { \
14988 + builtin_define ("__riscv64"); \
14989 + builtin_define ("_RISCV_SIM=_ABI64"); \
14990 + } \
14991 + else \
14992 + builtin_define ("_RISCV_SIM=_ABI32"); \
14994 + builtin_define ("_ABI32=1"); \
14995 + builtin_define ("_ABI64=3"); \
14998 + builtin_define_with_int_value ("_RISCV_SZINT", INT_TYPE_SIZE); \
14999 + builtin_define_with_int_value ("_RISCV_SZLONG", LONG_TYPE_SIZE); \
15000 + builtin_define_with_int_value ("_RISCV_SZPTR", POINTER_SIZE); \
15001 + builtin_define_with_int_value ("_RISCV_FPSET", 32); \
15003 + if (TARGET_ATOMIC) { \
15004 + builtin_define ("__riscv_atomic"); \
15005 + } \
15007 + /* These defines reflect the ABI in use, not whether the \
15008 + FPU is directly accessible. */ \
15009 + if (TARGET_HARD_FLOAT_ABI) { \
15010 + builtin_define ("__riscv_hard_float"); \
15011 + if (TARGET_FDIV) { \
15012 + builtin_define ("__riscv_fdiv"); \
15013 + builtin_define ("__riscv_fsqrt"); \
15014 + } \
15015 + } else \
15016 + builtin_define ("__riscv_soft_float"); \
15018 + /* The base RISC-V ISA is always little-endian. */ \
15019 + builtin_define_std ("RISCVEL"); \
15020 + builtin_define ("_RISCVEL"); \
15022 + /* Macros dependent on the C dialect. */ \
15023 + if (preprocessing_asm_p ()) \
15024 + { \
15025 + builtin_define_std ("LANGUAGE_ASSEMBLY"); \
15026 + builtin_define ("_LANGUAGE_ASSEMBLY"); \
15027 + } \
15028 + else if (c_dialect_cxx ()) \
15029 + { \
15030 + builtin_define ("_LANGUAGE_C_PLUS_PLUS"); \
15031 + builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
15032 + builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
15033 + } \
15034 + else \
15035 + { \
15036 + builtin_define_std ("LANGUAGE_C"); \
15037 + builtin_define ("_LANGUAGE_C"); \
15038 + } \
15039 + if (c_dialect_objc ()) \
15040 + { \
15041 + builtin_define ("_LANGUAGE_OBJECTIVE_C"); \
15042 + builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
15043 + /* Bizarre, but needed at least for Irix. */ \
15044 + builtin_define_std ("LANGUAGE_C"); \
15045 + builtin_define ("_LANGUAGE_C"); \
15046 + } \
15047 + if (riscv_cmodel == CM_MEDANY) \
15048 + builtin_define ("_RISCV_CMODEL_MEDANY"); \
15049 + } \
15050 + while (0)
15052 +/* Default target_flags if no switches are specified */
15054 +#ifndef TARGET_DEFAULT
15055 +#define TARGET_DEFAULT 0
15056 +#endif
15058 +#ifndef RISCV_ARCH_STRING_DEFAULT
15059 +#define RISCV_ARCH_STRING_DEFAULT "IMAFD"
15060 +#endif
15062 +#ifndef RISCV_TUNE_STRING_DEFAULT
15063 +#define RISCV_TUNE_STRING_DEFAULT "rocket"
15064 +#endif
15066 +#ifndef TARGET_64BIT_DEFAULT
15067 +#define TARGET_64BIT_DEFAULT 1
15068 +#endif
15070 +#if TARGET_64BIT_DEFAULT
15071 +# define MULTILIB_ARCH_DEFAULT "m64"
15072 +# define OPT_ARCH64 "!m32"
15073 +# define OPT_ARCH32 "m32"
15074 +#else
15075 +# define MULTILIB_ARCH_DEFAULT "m32"
15076 +# define OPT_ARCH64 "m64"
15077 +# define OPT_ARCH32 "!m64"
15078 +#endif
15080 +#ifndef MULTILIB_DEFAULTS
15081 +#define MULTILIB_DEFAULTS \
15082 + { MULTILIB_ARCH_DEFAULT }
15083 +#endif
15086 +/* Support for a compile-time default CPU, et cetera. The rules are:
15087 + --with-arch is ignored if -march is specified.
15088 + --with-tune is ignored if -mtune is specified.
15089 + --with-float is ignored if -mhard-float or -msoft-float are specified. */
15090 +#define OPTION_DEFAULT_SPECS \
15091 + {"arch_32", "%{" OPT_ARCH32 ":%{m32}}" }, \
15092 + {"arch_64", "%{" OPT_ARCH64 ":%{m64}}" }, \
15093 + {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
15094 + {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
15096 +#define DRIVER_SELF_SPECS ""
15098 +#ifdef IN_LIBGCC2
15099 +#undef TARGET_64BIT
15100 +/* Make this compile time constant for libgcc2 */
15101 +#ifdef __riscv64
15102 +#define TARGET_64BIT 1
15103 +#else
15104 +#define TARGET_64BIT 0
15105 +#endif
15106 +#endif /* IN_LIBGCC2 */
15108 +/* Tell collect what flags to pass to nm. */
15109 +#ifndef NM_FLAGS
15110 +#define NM_FLAGS "-Bn"
15111 +#endif
15113 +#undef ASM_SPEC
15114 +#define ASM_SPEC "\
15115 +%(subtarget_asm_debugging_spec) \
15116 +%{m32} %{m64} %{!m32:%{!m64: %(asm_abi_default_spec)}} \
15117 +%{fPIC|fpic|fPIE|fpie:-fpic} \
15118 +%{march=*} \
15119 +%(subtarget_asm_spec)"
15121 +/* Extra switches sometimes passed to the linker. */
15123 +#ifndef LINK_SPEC
15124 +#define LINK_SPEC "\
15125 +%{!T:-dT riscv.ld} \
15126 +%{m64:-melf64lriscv} \
15127 +%{m32:-melf32lriscv} \
15128 +%{shared}"
15129 +#endif /* LINK_SPEC defined */
15131 +/* This macro defines names of additional specifications to put in the specs
15132 + that can be used in various specifications like CC1_SPEC. Its definition
15133 + is an initializer with a subgrouping for each command option.
15135 + Each subgrouping contains a string constant, that defines the
15136 + specification name, and a string constant that used by the GCC driver
15137 + program.
15139 + Do not define this macro if it does not need to do anything. */
15141 +#define EXTRA_SPECS \
15142 + { "asm_abi_default_spec", "-" MULTILIB_ARCH_DEFAULT }, \
15143 + SUBTARGET_EXTRA_SPECS
15145 +#ifndef SUBTARGET_EXTRA_SPECS
15146 +#define SUBTARGET_EXTRA_SPECS
15147 +#endif
15149 +#define TARGET_DEFAULT_CMODEL CM_MEDLOW
15151 +/* By default, turn on GDB extensions. */
15152 +#define DEFAULT_GDB_EXTENSIONS 1
15154 +#define LOCAL_LABEL_PREFIX "."
15155 +#define USER_LABEL_PREFIX ""
15157 +#define DWARF2_DEBUGGING_INFO 1
15158 +#define DWARF2_ASM_LINE_DEBUG_INFO 0
15160 +/* The mapping from gcc register number to DWARF 2 CFA column number. */
15161 +#define DWARF_FRAME_REGNUM(REGNO) \
15162 + (GP_REG_P (REGNO) || FP_REG_P (REGNO) ? REGNO : INVALID_REGNUM)
15164 +/* The DWARF 2 CFA column which tracks the return address. */
15165 +#define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM
15167 +/* Don't emit .cfi_sections, as it does not work */
15168 +#undef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
15169 +#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE 0
15171 +/* Before the prologue, RA lives in r31. */
15172 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RETURN_ADDR_REGNUM)
15174 +/* Describe how we implement __builtin_eh_return. */
15175 +#define EH_RETURN_DATA_REGNO(N) \
15176 + ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
15178 +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_ARG_FIRST + 4)
15180 +/* Target machine storage layout */
15182 +#define BITS_BIG_ENDIAN 0
15183 +#define BYTES_BIG_ENDIAN 0
15184 +#define WORDS_BIG_ENDIAN 0
15186 +#define MAX_BITS_PER_WORD 64
15188 +/* Width of a word, in units (bytes). */
15189 +#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
15190 +#ifndef IN_LIBGCC2
15191 +#define MIN_UNITS_PER_WORD 4
15192 +#endif
15194 +/* We currently require both or neither of the `F' and `D' extensions. */
15195 +#define UNITS_PER_FPREG 8
15197 +/* If FP regs aren't wide enough for a given FP argument, it is passed in
15198 + integer registers. */
15199 +#define MIN_FPRS_PER_FMT 1
15201 +/* The largest size of value that can be held in floating-point
15202 + registers and moved with a single instruction. */
15203 +#define UNITS_PER_HWFPVALUE \
15204 + (TARGET_SOFT_FLOAT_ABI ? 0 : UNITS_PER_FPREG)
15206 +/* The largest size of value that can be held in floating-point
15207 + registers. */
15208 +#define UNITS_PER_FPVALUE \
15209 + (TARGET_SOFT_FLOAT_ABI ? 0 \
15210 + : LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
15212 +/* The number of bytes in a double. */
15213 +#define UNITS_PER_DOUBLE (TYPE_PRECISION (double_type_node) / BITS_PER_UNIT)
15215 +/* Set the sizes of the core types. */
15216 +#define SHORT_TYPE_SIZE 16
15217 +#define INT_TYPE_SIZE 32
15218 +#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
15219 +#define LONG_LONG_TYPE_SIZE 64
15221 +#define FLOAT_TYPE_SIZE 32
15222 +#define DOUBLE_TYPE_SIZE 64
15223 +/* XXX The ABI says long doubles are IEEE-754-2008 float128s. */
15224 +#define LONG_DOUBLE_TYPE_SIZE 64
15226 +#ifdef IN_LIBGCC2
15227 +# define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
15228 +#endif
15230 +/* Allocation boundary (in *bits*) for storing arguments in argument list. */
15231 +#define PARM_BOUNDARY BITS_PER_WORD
15233 +/* Allocation boundary (in *bits*) for the code of a function. */
15234 +#define FUNCTION_BOUNDARY 32
15236 +/* There is no point aligning anything to a rounder boundary than this. */
15237 +#define BIGGEST_ALIGNMENT 128
15239 +/* All accesses must be aligned. */
15240 +#define STRICT_ALIGNMENT 1
15242 +/* Define this if you wish to imitate the way many other C compilers
15243 + handle alignment of bitfields and the structures that contain
15244 + them.
15246 + The behavior is that the type written for a bit-field (`int',
15247 + `short', or other integer type) imposes an alignment for the
15248 + entire structure, as if the structure really did contain an
15249 + ordinary field of that type. In addition, the bit-field is placed
15250 + within the structure so that it would fit within such a field,
15251 + not crossing a boundary for it.
15253 + Thus, on most machines, a bit-field whose type is written as `int'
15254 + would not cross a four-byte boundary, and would force four-byte
15255 + alignment for the whole structure. (The alignment used may not
15256 + be four bytes; it is controlled by the other alignment
15257 + parameters.)
15259 + If the macro is defined, its definition should be a C expression;
15260 + a nonzero value for the expression enables this behavior. */
15262 +#define PCC_BITFIELD_TYPE_MATTERS 1
15264 +/* If defined, a C expression to compute the alignment given to a
15265 + constant that is being placed in memory. CONSTANT is the constant
15266 + and ALIGN is the alignment that the object would ordinarily have.
15267 + The value of this macro is used instead of that alignment to align
15268 + the object.
15270 + If this macro is not defined, then ALIGN is used.
15272 + The typical use of this macro is to increase alignment for string
15273 + constants to be word aligned so that `strcpy' calls that copy
15274 + constants can be done inline. */
15276 +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
15277 + ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
15278 + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
15280 +/* If defined, a C expression to compute the alignment for a static
15281 + variable. TYPE is the data type, and ALIGN is the alignment that
15282 + the object would ordinarily have. The value of this macro is used
15283 + instead of that alignment to align the object.
15285 + If this macro is not defined, then ALIGN is used.
15287 + One use of this macro is to increase alignment of medium-size
15288 + data to make it all fit in fewer cache lines. Another is to
15289 + cause character arrays to be word-aligned so that `strcpy' calls
15290 + that copy constants to character arrays can be done inline. */
15292 +#undef DATA_ALIGNMENT
15293 +#define DATA_ALIGNMENT(TYPE, ALIGN) \
15294 + ((((ALIGN) < BITS_PER_WORD) \
15295 + && (TREE_CODE (TYPE) == ARRAY_TYPE \
15296 + || TREE_CODE (TYPE) == UNION_TYPE \
15297 + || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
15299 +/* We need this for the same reason as DATA_ALIGNMENT, namely to cause
15300 + character arrays to be word-aligned so that `strcpy' calls that copy
15301 + constants to character arrays can be done inline, and 'strcmp' can be
15302 + optimised to use word loads. */
15303 +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
15304 + DATA_ALIGNMENT (TYPE, ALIGN)
15306 +/* Define if operations between registers always perform the operation
15307 + on the full register even if a narrower mode is specified. */
15308 +#define WORD_REGISTER_OPERATIONS
15310 +/* When in 64-bit mode, move insns will sign extend SImode and CCmode
15311 + moves. All other references are zero extended. */
15312 +#define LOAD_EXTEND_OP(MODE) \
15313 + (TARGET_64BIT && ((MODE) == SImode || (MODE) == CCmode) \
15314 + ? SIGN_EXTEND : ZERO_EXTEND)
15316 +/* Define this macro if it is advisable to hold scalars in registers
15317 + in a wider mode than that declared by the program. In such cases,
15318 + the value is constrained to be within the bounds of the declared
15319 + type, but kept valid in the wider mode. The signedness of the
15320 + extension may differ from that of the type. */
15322 +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
15323 + if (GET_MODE_CLASS (MODE) == MODE_INT \
15324 + && GET_MODE_SIZE (MODE) < 4) \
15325 + { \
15326 + (MODE) = Pmode; \
15329 +/* Pmode is always the same as ptr_mode, but not always the same as word_mode.
15330 + Extensions of pointers to word_mode must be signed. */
15331 +#define POINTERS_EXTEND_UNSIGNED false
15333 +/* RV32 double-precision FP <-> integer moves go through memory */
15334 +#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
15335 + (!TARGET_64BIT && GET_MODE_SIZE (MODE) == 8 && \
15336 + (((CLASS1) == FP_REGS && (CLASS2) != FP_REGS) \
15337 + || ((CLASS2) == FP_REGS && (CLASS1) != FP_REGS)))
15339 +/* Define if loading short immediate values into registers sign extends. */
15340 +#define SHORT_IMMEDIATES_SIGN_EXTEND
15342 +/* Standard register usage. */
15344 +/* Number of hardware registers. We have:
15346 + - 32 integer registers
15347 + - 32 floating point registers
15348 + - 32 vector integer registers
15349 + - 32 vector floating point registers
15350 + - 2 fake registers:
15351 + - ARG_POINTER_REGNUM
15352 + - FRAME_POINTER_REGNUM */
15354 +#define FIRST_PSEUDO_REGISTER 66
15356 +/* x0, sp, gp, and tp are fixed. */
15358 +#define FIXED_REGISTERS \
15359 +{ /* General registers. */ \
15360 + 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
15361 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
15362 + /* Floating-point registers. */ \
15363 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
15364 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
15365 + /* Others. */ \
15366 + 1, 1 \
15370 +/* a0-a7, t0-a6, fa0-fa7, and ft0-ft11 are volatile across calls.
15371 + The call RTLs themselves clobber ra. */
15373 +#define CALL_USED_REGISTERS \
15374 +{ /* General registers. */ \
15375 + 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
15376 + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
15377 + /* Floating-point registers. */ \
15378 + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
15379 + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
15380 + /* Others. */ \
15381 + 1, 1 \
15384 +#define CALL_REALLY_USED_REGISTERS \
15385 +{ /* General registers. */ \
15386 + 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
15387 + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
15388 + /* Floating-point registers. */ \
15389 + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
15390 + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
15391 + /* Others. */ \
15392 + 1, 1 \
15395 +/* Internal macros to classify an ISA register's type. */
15397 +#define GP_REG_FIRST 0
15398 +#define GP_REG_LAST 31
15399 +#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
15401 +#define FP_REG_FIRST 32
15402 +#define FP_REG_LAST 63
15403 +#define FP_REG_NUM (FP_REG_LAST - FP_REG_FIRST + 1)
15405 +/* The DWARF 2 CFA column which tracks the return address from a
15406 + signal handler context. This means that to maintain backwards
15407 + compatibility, no hard register can be assigned this column if it
15408 + would need to be handled by the DWARF unwinder. */
15409 +#define DWARF_ALT_FRAME_RETURN_COLUMN 64
15411 +#define GP_REG_P(REGNO) \
15412 + ((unsigned int) ((int) (REGNO) - GP_REG_FIRST) < GP_REG_NUM)
15413 +#define FP_REG_P(REGNO) \
15414 + ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
15416 +#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
15418 +/* Return coprocessor number from register number. */
15420 +#define COPNUM_AS_CHAR_FROM_REGNUM(REGNO) \
15421 + (COP0_REG_P (REGNO) ? '0' : COP2_REG_P (REGNO) ? '2' \
15422 + : COP3_REG_P (REGNO) ? '3' : '?')
15425 +#define HARD_REGNO_NREGS(REGNO, MODE) riscv_hard_regno_nregs (REGNO, MODE)
15427 +#define HARD_REGNO_MODE_OK(REGNO, MODE) \
15428 + riscv_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO) ]
15430 +#define MODES_TIEABLE_P(MODE1, MODE2) \
15431 + ((MODE1) == (MODE2) || (GET_MODE_CLASS (MODE1) == MODE_INT \
15432 + && GET_MODE_CLASS (MODE2) == MODE_INT))
15434 +/* Use s0 as the frame pointer if it is so requested. */
15435 +#define HARD_FRAME_POINTER_REGNUM 8
15436 +#define STACK_POINTER_REGNUM 2
15437 +#define THREAD_POINTER_REGNUM 4
15439 +/* These two registers don't really exist: they get eliminated to either
15440 + the stack or hard frame pointer. */
15441 +#define ARG_POINTER_REGNUM 64
15442 +#define FRAME_POINTER_REGNUM 65
15444 +#define HARD_FRAME_POINTER_IS_FRAME_POINTER 0
15445 +#define HARD_FRAME_POINTER_IS_ARG_POINTER 0
15447 +/* Register in which static-chain is passed to a function. */
15448 +#define STATIC_CHAIN_REGNUM GP_TEMP_FIRST
15450 +/* Registers used as temporaries in prologue/epilogue code.
15452 + The prologue registers mustn't conflict with any
15453 + incoming arguments, the static chain pointer, or the frame pointer.
15454 + The epilogue temporary mustn't conflict with the return registers,
15455 + the frame pointer, the EH stack adjustment, or the EH data registers. */
15457 +#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1)
15458 +#define RISCV_EPILOGUE_TEMP_REGNUM RISCV_PROLOGUE_TEMP_REGNUM
15460 +#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM)
15461 +#define RISCV_EPILOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_EPILOGUE_TEMP_REGNUM)
15463 +#define FUNCTION_PROFILER(STREAM, LABELNO) \
15464 +{ \
15465 + sorry ("profiler support for RISC-V"); \
15468 +/* Define this macro if it is as good or better to call a constant
15469 + function address than to call an address kept in a register. */
15470 +#define NO_FUNCTION_CSE 1
15472 +/* Define the classes of registers for register constraints in the
15473 + machine description. Also define ranges of constants.
15475 + One of the classes must always be named ALL_REGS and include all hard regs.
15476 + If there is more than one class, another class must be named NO_REGS
15477 + and contain no registers.
15479 + The name GENERAL_REGS must be the name of a class (or an alias for
15480 + another name such as ALL_REGS). This is the class of registers
15481 + that is allowed by "g" or "r" in a register constraint.
15482 + Also, registers outside this class are allocated only when
15483 + instructions express preferences for them.
15485 + The classes must be numbered in nondecreasing order; that is,
15486 + a larger-numbered class must never be contained completely
15487 + in a smaller-numbered class.
15489 + For any two classes, it is very desirable that there be another
15490 + class that represents their union. */
15492 +enum reg_class
15494 + NO_REGS, /* no registers in set */
15495 + T_REGS, /* registers used by indirect sibcalls */
15496 + GR_REGS, /* integer registers */
15497 + FP_REGS, /* floating point registers */
15498 + FRAME_REGS, /* $arg and $frame */
15499 + ALL_REGS, /* all registers */
15500 + LIM_REG_CLASSES /* max value + 1 */
15503 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
15505 +#define GENERAL_REGS GR_REGS
15507 +/* An initializer containing the names of the register classes as C
15508 + string constants. These names are used in writing some of the
15509 + debugging dumps. */
15511 +#define REG_CLASS_NAMES \
15512 +{ \
15513 + "NO_REGS", \
15514 + "T_REGS", \
15515 + "GR_REGS", \
15516 + "FP_REGS", \
15517 + "FRAME_REGS", \
15518 + "ALL_REGS" \
15521 +/* An initializer containing the contents of the register classes,
15522 + as integers which are bit masks. The Nth integer specifies the
15523 + contents of class N. The way the integer MASK is interpreted is
15524 + that register R is in the class if `MASK & (1 << R)' is 1.
15526 + When the machine has more than 32 registers, an integer does not
15527 + suffice. Then the integers are replaced by sub-initializers,
15528 + braced groupings containing several integers. Each
15529 + sub-initializer must be suitable as an initializer for the type
15530 + `HARD_REG_SET' which is defined in `hard-reg-set.h'. */
15532 +#define REG_CLASS_CONTENTS \
15533 +{ \
15534 + { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
15535 + { 0xf00000e0, 0x00000000, 0x00000000 }, /* T_REGS */ \
15536 + { 0xffffffff, 0x00000000, 0x00000000 }, /* GR_REGS */ \
15537 + { 0x00000000, 0xffffffff, 0x00000000 }, /* FP_REGS */ \
15538 + { 0x00000000, 0x00000000, 0x00000003 }, /* FRAME_REGS */ \
15539 + { 0xffffffff, 0xffffffff, 0x00000003 } /* ALL_REGS */ \
15542 +/* A C expression whose value is a register class containing hard
15543 + register REGNO. In general there is more that one such class;
15544 + choose a class which is "minimal", meaning that no smaller class
15545 + also contains the register. */
15547 +#define REGNO_REG_CLASS(REGNO) riscv_regno_to_class[ (REGNO) ]
15549 +/* A macro whose definition is the name of the class to which a
15550 + valid base register must belong. A base register is one used in
15551 + an address which is the register value plus a displacement. */
15553 +#define BASE_REG_CLASS GR_REGS
15555 +/* A macro whose definition is the name of the class to which a
15556 + valid index register must belong. An index register is one used
15557 + in an address where its value is either multiplied by a scale
15558 + factor or added to another register (as well as added to a
15559 + displacement). */
15561 +#define INDEX_REG_CLASS NO_REGS
15563 +/* We generally want to put call-clobbered registers ahead of
15564 + call-saved ones. (IRA expects this.) */
15566 +#define REG_ALLOC_ORDER \
15567 +{ \
15568 + /* Call-clobbered GPRs. */ \
15569 + 15, 14, 13, 12, 11, 10, 16, 17, 5, 6, 7, 28, 29, 30, 31, 1, \
15570 + /* Call-saved GPRs. */ \
15571 + 8, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
15572 + /* GPRs that can never be exposed to the register allocator. */ \
15573 + 0, 2, 3, 4, \
15574 + /* Call-clobbered FPRs. */ \
15575 + 32, 33, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 49, \
15576 + 60, 61, 62, 63, \
15577 + /* Call-saved FPRs. */ \
15578 + 40, 41, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \
15579 + /* None of the remaining classes have defined call-saved \
15580 + registers. */ \
15581 + 64, 65 \
15584 +/* True if VALUE is a signed 16-bit number. */
15586 +#include "opcode-riscv.h"
15587 +#define SMALL_OPERAND(VALUE) \
15588 + ((unsigned HOST_WIDE_INT) (VALUE) + RISCV_IMM_REACH/2 < RISCV_IMM_REACH)
15590 +/* True if VALUE can be loaded into a register using LUI. */
15592 +#define LUI_OPERAND(VALUE) \
15593 + (((VALUE) | ((1UL<<31) - RISCV_IMM_REACH)) == ((1UL<<31) - RISCV_IMM_REACH) \
15594 + || ((VALUE) | ((1UL<<31) - RISCV_IMM_REACH)) + RISCV_IMM_REACH == 0)
15596 +/* Return a value X with the low 16 bits clear, and such that
15597 + VALUE - X is a signed 16-bit value. */
15599 +#define SMALL_INT(X) SMALL_OPERAND (INTVAL (X))
15600 +#define LUI_INT(X) LUI_OPERAND (INTVAL (X))
15602 +/* The HI and LO registers can only be reloaded via the general
15603 + registers. Condition code registers can only be loaded to the
15604 + general registers, and from the floating point registers. */
15606 +#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
15607 + riscv_secondary_reload_class (CLASS, MODE, X, true)
15608 +#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
15609 + riscv_secondary_reload_class (CLASS, MODE, X, false)
15611 +/* Return the maximum number of consecutive registers
15612 + needed to represent mode MODE in a register of class CLASS. */
15614 +#define CLASS_MAX_NREGS(CLASS, MODE) riscv_class_max_nregs (CLASS, MODE)
15616 +/* It is undefined to interpret an FP register in a different format than
15617 + that which it was created to be. */
15619 +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
15620 + reg_classes_intersect_p (FP_REGS, CLASS)
15622 +/* Stack layout; function entry, exit and calling. */
15624 +#define STACK_GROWS_DOWNWARD
15626 +#define FRAME_GROWS_DOWNWARD 1
15628 +#define STARTING_FRAME_OFFSET 0
15630 +#define RETURN_ADDR_RTX riscv_return_addr
15632 +#define ELIMINABLE_REGS \
15633 +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
15634 + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
15635 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
15636 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \
15638 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
15639 + (OFFSET) = riscv_initial_elimination_offset (FROM, TO)
15641 +/* Allocate stack space for arguments at the beginning of each function. */
15642 +#define ACCUMULATE_OUTGOING_ARGS 1
15644 +/* The argument pointer always points to the first argument. */
15645 +#define FIRST_PARM_OFFSET(FNDECL) 0
15647 +#define REG_PARM_STACK_SPACE(FNDECL) 0
15649 +/* Define this if it is the responsibility of the caller to
15650 + allocate the area reserved for arguments passed in registers.
15651 + If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
15652 + of this macro is to determine whether the space is included in
15653 + `crtl->outgoing_args_size'. */
15654 +#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
15656 +#define STACK_BOUNDARY 128
15658 +/* Symbolic macros for the registers used to return integer and floating
15659 + point values. */
15661 +#define GP_RETURN GP_ARG_FIRST
15662 +#define FP_RETURN ((TARGET_SOFT_FLOAT) ? GP_RETURN : FP_ARG_FIRST)
15664 +#define MAX_ARGS_IN_REGISTERS 8
15666 +/* Symbolic macros for the first/last argument registers. */
15668 +#define GP_ARG_FIRST (GP_REG_FIRST + 10)
15669 +#define GP_ARG_LAST (GP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
15670 +#define GP_TEMP_FIRST (GP_REG_FIRST + 5)
15671 +#define FP_ARG_FIRST (FP_REG_FIRST + 10)
15672 +#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
15674 +#define LIBCALL_VALUE(MODE) \
15675 + riscv_function_value (NULL_TREE, NULL_TREE, MODE)
15677 +#define FUNCTION_VALUE(VALTYPE, FUNC) \
15678 + riscv_function_value (VALTYPE, FUNC, VOIDmode)
15680 +#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN)
15682 +/* 1 if N is a possible register number for function argument passing.
15683 + We have no FP argument registers when soft-float. When FP registers
15684 + are 32 bits, we can't directly reference the odd numbered ones. */
15686 +/* Accept arguments in a0-a7 and/or fa0-fa7. */
15687 +#define FUNCTION_ARG_REGNO_P(N) \
15688 + (IN_RANGE((N), GP_ARG_FIRST, GP_ARG_LAST) \
15689 + || IN_RANGE((N), FP_ARG_FIRST, FP_ARG_LAST))
15691 +/* The ABI views the arguments as a structure, of which the first 8
15692 + words go in registers and the rest go on the stack. If I < 8, N, the Ith
15693 + word might go in the Ith integer argument register or the Ith
15694 + floating-point argument register. */
15696 +typedef struct {
15697 + /* Number of integer registers used so far, up to MAX_ARGS_IN_REGISTERS. */
15698 + unsigned int num_gprs;
15700 + /* Number of words passed on the stack. */
15701 + unsigned int stack_words;
15702 +} CUMULATIVE_ARGS;
15704 +/* Initialize a variable CUM of type CUMULATIVE_ARGS
15705 + for a call to a function whose data type is FNTYPE.
15706 + For a library call, FNTYPE is 0. */
15708 +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
15709 + memset (&(CUM), 0, sizeof (CUM))
15711 +#define EPILOGUE_USES(REGNO) ((REGNO) == RETURN_ADDR_REGNUM)
15713 +/* ABI requires 16-byte alignment, even on ven on RV32. */
15714 +#define RISCV_STACK_ALIGN(LOC) (((LOC) + 15) & -16)
15716 +#define NO_PROFILE_COUNTERS 1
15718 +/* Define this macro if the code for function profiling should come
15719 + before the function prologue. Normally, the profiling code comes
15720 + after. */
15722 +/* #define PROFILE_BEFORE_PROLOGUE */
15724 +/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
15725 + the stack pointer does not matter. The value is tested only in
15726 + functions that have frame pointers.
15727 + No definition is equivalent to always zero. */
15729 +#define EXIT_IGNORE_STACK 1
15732 +/* Trampolines are a block of code followed by two pointers. */
15734 +#define TRAMPOLINE_CODE_SIZE 16
15735 +#define TRAMPOLINE_SIZE (TRAMPOLINE_CODE_SIZE + POINTER_SIZE * 2)
15736 +#define TRAMPOLINE_ALIGNMENT POINTER_SIZE
15738 +/* Addressing modes, and classification of registers for them. */
15740 +#define REGNO_OK_FOR_INDEX_P(REGNO) 0
15741 +#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
15742 + riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1)
15744 +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
15745 + and check its validity for a certain class.
15746 + We have two alternate definitions for each of them.
15747 + The usual definition accepts all pseudo regs; the other rejects them all.
15748 + The symbol REG_OK_STRICT causes the latter definition to be used.
15750 + Most source files want to accept pseudo regs in the hope that
15751 + they will get allocated to the class that the insn wants them to be in.
15752 + Some source files that are used after register allocation
15753 + need to be strict. */
15755 +#ifndef REG_OK_STRICT
15756 +#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
15757 + riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 0)
15758 +#else
15759 +#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
15760 + riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 1)
15761 +#endif
15763 +#define REG_OK_FOR_INDEX_P(X) 0
15766 +/* Maximum number of registers that can appear in a valid memory address. */
15768 +#define MAX_REGS_PER_ADDRESS 1
15770 +#define CONSTANT_ADDRESS_P(X) \
15771 + (CONSTANT_P (X) && memory_address_p (SImode, X))
15773 +/* This handles the magic '..CURRENT_FUNCTION' symbol, which means
15774 + 'the start of the function that this code is output in'. */
15776 +#define ASM_OUTPUT_LABELREF(FILE,NAME) \
15777 + if (strcmp (NAME, "..CURRENT_FUNCTION") == 0) \
15778 + asm_fprintf ((FILE), "%U%s", \
15779 + XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
15780 + else \
15781 + asm_fprintf ((FILE), "%U%s", (NAME))
15783 +/* This flag marks functions that cannot be lazily bound. */
15784 +#define SYMBOL_FLAG_BIND_NOW (SYMBOL_FLAG_MACH_DEP << 1)
15785 +#define SYMBOL_REF_BIND_NOW_P(RTX) \
15786 + ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_BIND_NOW) != 0)
15788 +#define JUMP_TABLES_IN_TEXT_SECTION 0
15789 +#define CASE_VECTOR_MODE SImode
15790 +#define CASE_VECTOR_PC_RELATIVE (riscv_cmodel != CM_MEDLOW)
15792 +/* Define this as 1 if `char' should by default be signed; else as 0. */
15793 +#define DEFAULT_SIGNED_CHAR 0
15795 +/* Consider using fld/fsd to move 8 bytes at a time for RV32IFD. */
15796 +#define MOVE_MAX UNITS_PER_WORD
15797 +#define MAX_MOVE_MAX 8
15799 +#define SLOW_BYTE_ACCESS 0
15801 +#define SHIFT_COUNT_TRUNCATED 1
15803 +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
15804 + is done just by pretending it is already truncated. */
15805 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
15806 + (TARGET_64BIT ? ((INPREC) <= 32 || (OUTPREC) < 32) : 1)
15808 +/* Specify the machine mode that pointers have.
15809 + After generation of rtl, the compiler makes no further distinction
15810 + between pointers and any other objects of this machine mode. */
15812 +#ifndef Pmode
15813 +#define Pmode (TARGET_64BIT ? DImode : SImode)
15814 +#endif
15816 +/* Give call MEMs SImode since it is the "most permissive" mode
15817 + for both 32-bit and 64-bit targets. */
15819 +#define FUNCTION_MODE SImode
15821 +/* A C expression for the cost of a branch instruction. A value of 2
15822 + seems to minimize code size. */
15824 +#define BRANCH_COST(speed_p, predictable_p) \
15825 + ((!(speed_p) || (predictable_p)) ? 2 : riscv_branch_cost)
15827 +#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
15829 +/* Control the assembler format that we output. */
15831 +/* Output to assembler file text saying following lines
15832 + may contain character constants, extra white space, comments, etc. */
15834 +#ifndef ASM_APP_ON
15835 +#define ASM_APP_ON " #APP\n"
15836 +#endif
15838 +/* Output to assembler file text saying following lines
15839 + no longer contain unusual constructs. */
15841 +#ifndef ASM_APP_OFF
15842 +#define ASM_APP_OFF " #NO_APP\n"
15843 +#endif
15845 +#define REGISTER_NAMES \
15846 +{ "zero","ra", "sp", "gp", "tp", "t0", "t1", "t2", \
15847 + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", \
15848 + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", \
15849 + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", \
15850 + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", \
15851 + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", \
15852 + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", \
15853 + "fs8", "fs9", "fs10","fs11","ft8", "ft9", "ft10","ft11", \
15854 + "arg", "frame", }
15856 +#define ADDITIONAL_REGISTER_NAMES \
15857 +{ \
15858 + { "x0", 0 + GP_REG_FIRST }, \
15859 + { "x1", 1 + GP_REG_FIRST }, \
15860 + { "x2", 2 + GP_REG_FIRST }, \
15861 + { "x3", 3 + GP_REG_FIRST }, \
15862 + { "x4", 4 + GP_REG_FIRST }, \
15863 + { "x5", 5 + GP_REG_FIRST }, \
15864 + { "x6", 6 + GP_REG_FIRST }, \
15865 + { "x7", 7 + GP_REG_FIRST }, \
15866 + { "x8", 8 + GP_REG_FIRST }, \
15867 + { "x9", 9 + GP_REG_FIRST }, \
15868 + { "x10", 10 + GP_REG_FIRST }, \
15869 + { "x11", 11 + GP_REG_FIRST }, \
15870 + { "x12", 12 + GP_REG_FIRST }, \
15871 + { "x13", 13 + GP_REG_FIRST }, \
15872 + { "x14", 14 + GP_REG_FIRST }, \
15873 + { "x15", 15 + GP_REG_FIRST }, \
15874 + { "x16", 16 + GP_REG_FIRST }, \
15875 + { "x17", 17 + GP_REG_FIRST }, \
15876 + { "x18", 18 + GP_REG_FIRST }, \
15877 + { "x19", 19 + GP_REG_FIRST }, \
15878 + { "x20", 20 + GP_REG_FIRST }, \
15879 + { "x21", 21 + GP_REG_FIRST }, \
15880 + { "x22", 22 + GP_REG_FIRST }, \
15881 + { "x23", 23 + GP_REG_FIRST }, \
15882 + { "x24", 24 + GP_REG_FIRST }, \
15883 + { "x25", 25 + GP_REG_FIRST }, \
15884 + { "x26", 26 + GP_REG_FIRST }, \
15885 + { "x27", 27 + GP_REG_FIRST }, \
15886 + { "x28", 28 + GP_REG_FIRST }, \
15887 + { "x29", 29 + GP_REG_FIRST }, \
15888 + { "x30", 30 + GP_REG_FIRST }, \
15889 + { "x31", 31 + GP_REG_FIRST }, \
15890 + { "f0", 0 + FP_REG_FIRST }, \
15891 + { "f1", 1 + FP_REG_FIRST }, \
15892 + { "f2", 2 + FP_REG_FIRST }, \
15893 + { "f3", 3 + FP_REG_FIRST }, \
15894 + { "f4", 4 + FP_REG_FIRST }, \
15895 + { "f5", 5 + FP_REG_FIRST }, \
15896 + { "f6", 6 + FP_REG_FIRST }, \
15897 + { "f7", 7 + FP_REG_FIRST }, \
15898 + { "f8", 8 + FP_REG_FIRST }, \
15899 + { "f9", 9 + FP_REG_FIRST }, \
15900 + { "f10", 10 + FP_REG_FIRST }, \
15901 + { "f11", 11 + FP_REG_FIRST }, \
15902 + { "f12", 12 + FP_REG_FIRST }, \
15903 + { "f13", 13 + FP_REG_FIRST }, \
15904 + { "f14", 14 + FP_REG_FIRST }, \
15905 + { "f15", 15 + FP_REG_FIRST }, \
15906 + { "f16", 16 + FP_REG_FIRST }, \
15907 + { "f17", 17 + FP_REG_FIRST }, \
15908 + { "f18", 18 + FP_REG_FIRST }, \
15909 + { "f19", 19 + FP_REG_FIRST }, \
15910 + { "f20", 20 + FP_REG_FIRST }, \
15911 + { "f21", 21 + FP_REG_FIRST }, \
15912 + { "f22", 22 + FP_REG_FIRST }, \
15913 + { "f23", 23 + FP_REG_FIRST }, \
15914 + { "f24", 24 + FP_REG_FIRST }, \
15915 + { "f25", 25 + FP_REG_FIRST }, \
15916 + { "f26", 26 + FP_REG_FIRST }, \
15917 + { "f27", 27 + FP_REG_FIRST }, \
15918 + { "f28", 28 + FP_REG_FIRST }, \
15919 + { "f29", 29 + FP_REG_FIRST }, \
15920 + { "f30", 30 + FP_REG_FIRST }, \
15921 + { "f31", 31 + FP_REG_FIRST }, \
15924 +/* Globalizing directive for a label. */
15925 +#define GLOBAL_ASM_OP "\t.globl\t"
15927 +/* This is how to store into the string LABEL
15928 + the symbol_ref name of an internal numbered label where
15929 + PREFIX is the class of label and NUM is the number within the class.
15930 + This is suitable for output with `assemble_name'. */
15932 +#undef ASM_GENERATE_INTERNAL_LABEL
15933 +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
15934 + sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
15936 +/* This is how to output an element of a case-vector that is absolute. */
15938 +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
15939 + fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
15941 +/* This is how to output an element of a PIC case-vector. */
15943 +#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
15944 + fprintf (STREAM, "\t.word\t%sL%d-%sL%d\n", \
15945 + LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL)
15947 +/* This is how to output an assembler line
15948 + that says to advance the location counter
15949 + to a multiple of 2**LOG bytes. */
15951 +#define ASM_OUTPUT_ALIGN(STREAM,LOG) \
15952 + fprintf (STREAM, "\t.align\t%d\n", (LOG))
15954 +/* Define the strings to put out for each section in the object file. */
15955 +#define TEXT_SECTION_ASM_OP "\t.text" /* instructions */
15956 +#define DATA_SECTION_ASM_OP "\t.data" /* large data */
15957 +#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
15958 +#define BSS_SECTION_ASM_OP "\t.bss"
15959 +#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\",@nobits"
15960 +#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\",@progbits"
15962 +#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \
15963 +do \
15964 + { \
15965 + fprintf (STREAM, "\taddi\t%s,%s,-8\n\t%s\t%s,0(%s)\n", \
15966 + reg_names[STACK_POINTER_REGNUM], \
15967 + reg_names[STACK_POINTER_REGNUM], \
15968 + TARGET_64BIT ? "sd" : "sw", \
15969 + reg_names[REGNO], \
15970 + reg_names[STACK_POINTER_REGNUM]); \
15971 + } \
15972 +while (0)
15974 +#define ASM_OUTPUT_REG_POP(STREAM,REGNO) \
15975 +do \
15976 + { \
15977 + fprintf (STREAM, "\t%s\t%s,0(%s)\n\taddi\t%s,%s,8\n", \
15978 + TARGET_64BIT ? "ld" : "lw", \
15979 + reg_names[REGNO], \
15980 + reg_names[STACK_POINTER_REGNUM], \
15981 + reg_names[STACK_POINTER_REGNUM], \
15982 + reg_names[STACK_POINTER_REGNUM]); \
15983 + } \
15984 +while (0)
15986 +#define ASM_COMMENT_START "#"
15988 +#undef SIZE_TYPE
15989 +#define SIZE_TYPE (POINTER_SIZE == 64 ? "long unsigned int" : "unsigned int")
15991 +#undef PTRDIFF_TYPE
15992 +#define PTRDIFF_TYPE (POINTER_SIZE == 64 ? "long int" : "int")
15994 +/* The maximum number of bytes that can be copied by one iteration of
15995 + a movmemsi loop; see riscv_block_move_loop. */
15996 +#define RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER (UNITS_PER_WORD * 4)
15998 +/* The maximum number of bytes that can be copied by a straight-line
15999 + implementation of movmemsi; see riscv_block_move_straight. We want
16000 + to make sure that any loop-based implementation will iterate at
16001 + least twice. */
16002 +#define RISCV_MAX_MOVE_BYTES_STRAIGHT (RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER * 2)
16004 +/* The base cost of a memcpy call, for MOVE_RATIO and friends. */
16006 +#define RISCV_CALL_RATIO 6
16008 +/* Any loop-based implementation of movmemsi will have at least
16009 + RISCV_MAX_MOVE_BYTES_STRAIGHT / UNITS_PER_WORD memory-to-memory
16010 + moves, so allow individual copies of fewer elements.
16012 + When movmemsi is not available, use a value approximating
16013 + the length of a memcpy call sequence, so that move_by_pieces
16014 + will generate inline code if it is shorter than a function call.
16015 + Since move_by_pieces_ninsns counts memory-to-memory moves, but
16016 + we'll have to generate a load/store pair for each, halve the
16017 + value of RISCV_CALL_RATIO to take that into account. */
16019 +#define MOVE_RATIO(speed) \
16020 + (HAVE_movmemsi \
16021 + ? RISCV_MAX_MOVE_BYTES_STRAIGHT / MOVE_MAX \
16022 + : RISCV_CALL_RATIO / 2)
16024 +/* movmemsi is meant to generate code that is at least as good as
16025 + move_by_pieces. However, movmemsi effectively uses a by-pieces
16026 + implementation both for moves smaller than a word and for word-aligned
16027 + moves of no more than RISCV_MAX_MOVE_BYTES_STRAIGHT bytes. We should
16028 + allow the tree-level optimisers to do such moves by pieces, as it
16029 + often exposes other optimization opportunities. We might as well
16030 + continue to use movmemsi at the rtl level though, as it produces
16031 + better code when scheduling is disabled (such as at -O). */
16033 +#define MOVE_BY_PIECES_P(SIZE, ALIGN) \
16034 + (HAVE_movmemsi \
16035 + ? (!currently_expanding_to_rtl \
16036 + && ((ALIGN) < BITS_PER_WORD \
16037 + ? (SIZE) < UNITS_PER_WORD \
16038 + : (SIZE) <= RISCV_MAX_MOVE_BYTES_STRAIGHT)) \
16039 + : (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
16040 + < (unsigned int) MOVE_RATIO (false)))
16042 +/* For CLEAR_RATIO, when optimizing for size, give a better estimate
16043 + of the length of a memset call, but use the default otherwise. */
16045 +#define CLEAR_RATIO(speed)\
16046 + ((speed) ? 15 : RISCV_CALL_RATIO)
16048 +/* This is similar to CLEAR_RATIO, but for a non-zero constant, so when
16049 + optimizing for size adjust the ratio to account for the overhead of
16050 + loading the constant and replicating it across the word. */
16052 +#define SET_RATIO(speed) \
16053 + ((speed) ? 15 : RISCV_CALL_RATIO - 2)
16055 +/* STORE_BY_PIECES_P can be used when copying a constant string, but
16056 + in that case each word takes 3 insns (lui, ori, sw), or more in
16057 + 64-bit mode, instead of 2 (lw, sw). For now we always fail this
16058 + and let the move_by_pieces code copy the string from read-only
16059 + memory. In the future, this could be tuned further for multi-issue
16060 + CPUs that can issue stores down one pipe and arithmetic instructions
16061 + down another; in that case, the lui/ori/sw combination would be a
16062 + win for long enough strings. */
16064 +#define STORE_BY_PIECES_P(SIZE, ALIGN) 0
16066 +#ifndef HAVE_AS_TLS
16067 +#define HAVE_AS_TLS 0
16068 +#endif
16070 +#ifndef USED_FOR_TARGET
16072 +extern const enum reg_class riscv_regno_to_class[];
16073 +extern bool riscv_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
16074 +extern const char* riscv_hi_relocs[];
16075 +#endif
16077 +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
16078 + (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
16079 diff -rNU3 dist.orig/gcc/config/riscv/riscv.md dist/gcc/config/riscv/riscv.md
16080 --- dist.orig/gcc/config/riscv/riscv.md 1970-01-01 01:00:00.000000000 +0100
16081 +++ dist/gcc/config/riscv/riscv.md 2015-10-18 13:19:50.000000000 +0200
16082 @@ -0,0 +1,2427 @@
16083 +;; Machine description for RISC-V for GNU compiler.
16084 +;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
16085 +;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
16086 +;; Based on MIPS target for GNU compiler.
16088 +;; This file is part of GCC.
16090 +;; GCC is free software; you can redistribute it and/or modify
16091 +;; it under the terms of the GNU General Public License as published by
16092 +;; the Free Software Foundation; either version 3, or (at your option)
16093 +;; any later version.
16095 +;; GCC is distributed in the hope that it will be useful,
16096 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16097 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16098 +;; GNU General Public License for more details.
16100 +;; You should have received a copy of the GNU General Public License
16101 +;; along with GCC; see the file COPYING3. If not see
16102 +;; <http://www.gnu.org/licenses/>.
16104 +(define_c_enum "unspec" [
16105 + ;; Floating-point moves.
16106 + UNSPEC_LOAD_LOW
16107 + UNSPEC_LOAD_HIGH
16108 + UNSPEC_STORE_WORD
16110 + ;; GP manipulation.
16111 + UNSPEC_EH_RETURN
16113 + ;; Symbolic accesses.
16114 + UNSPEC_ADDRESS_FIRST
16115 + UNSPEC_LOAD_GOT
16116 + UNSPEC_TLS
16117 + UNSPEC_TLS_LE
16118 + UNSPEC_TLS_IE
16119 + UNSPEC_TLS_GD
16121 + ;; Blockage and synchronisation.
16122 + UNSPEC_BLOCKAGE
16123 + UNSPEC_FENCE
16124 + UNSPEC_FENCE_I
16127 +(define_constants
16128 + [(RETURN_ADDR_REGNUM 1)
16131 +(include "predicates.md")
16132 +(include "constraints.md")
16134 +;; ....................
16136 +;; Attributes
16138 +;; ....................
16140 +(define_attr "got" "unset,xgot_high,load"
16141 + (const_string "unset"))
16143 +;; For jal instructions, this attribute is DIRECT when the target address
16144 +;; is symbolic and INDIRECT when it is a register.
16145 +(define_attr "jal" "unset,direct,indirect"
16146 + (const_string "unset"))
16148 +;; Classification of moves, extensions and truncations. Most values
16149 +;; are as for "type" (see below) but there are also the following
16150 +;; move-specific values:
16152 +;; andi a single ANDI instruction
16153 +;; shift_shift a shift left followed by a shift right
16155 +;; This attribute is used to determine the instruction's length and
16156 +;; scheduling type. For doubleword moves, the attribute always describes
16157 +;; the split instructions; in some cases, it is more appropriate for the
16158 +;; scheduling type to be "multi" instead.
16159 +(define_attr "move_type"
16160 + "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
16161 + const,logical,arith,andi,shift_shift"
16162 + (const_string "unknown"))
16164 +(define_attr "alu_type" "unknown,add,sub,and,or,xor"
16165 + (const_string "unknown"))
16167 +;; Main data type used by the insn
16168 +(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
16169 + (const_string "unknown"))
16171 +;; True if the main data type is twice the size of a word.
16172 +(define_attr "dword_mode" "no,yes"
16173 + (cond [(and (eq_attr "mode" "DI,DF")
16174 + (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
16175 + (const_string "yes")
16177 + (and (eq_attr "mode" "TI,TF")
16178 + (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
16179 + (const_string "yes")]
16180 + (const_string "no")))
16182 +;; Classification of each insn.
16183 +;; branch conditional branch
16184 +;; jump unconditional jump
16185 +;; call unconditional call
16186 +;; load load instruction(s)
16187 +;; fpload floating point load
16188 +;; fpidxload floating point indexed load
16189 +;; store store instruction(s)
16190 +;; fpstore floating point store
16191 +;; fpidxstore floating point indexed store
16192 +;; mtc transfer to coprocessor
16193 +;; mfc transfer from coprocessor
16194 +;; const load constant
16195 +;; arith integer arithmetic instructions
16196 +;; logical integer logical instructions
16197 +;; shift integer shift instructions
16198 +;; slt set less than instructions
16199 +;; imul integer multiply
16200 +;; idiv integer divide
16201 +;; move integer register move (addi rd, rs1, 0)
16202 +;; fmove floating point register move
16203 +;; fadd floating point add/subtract
16204 +;; fmul floating point multiply
16205 +;; fmadd floating point multiply-add
16206 +;; fdiv floating point divide
16207 +;; fcmp floating point compare
16208 +;; fcvt floating point convert
16209 +;; fsqrt floating point square root
16210 +;; multi multiword sequence (or user asm statements)
16211 +;; nop no operation
16212 +;; ghost an instruction that produces no real code
16213 +(define_attr "type"
16214 + "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
16215 + mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
16216 + fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
16217 + (cond [(eq_attr "jal" "!unset") (const_string "call")
16218 + (eq_attr "got" "load") (const_string "load")
16220 + (eq_attr "alu_type" "add,sub") (const_string "arith")
16222 + (eq_attr "alu_type" "and,or,xor") (const_string "logical")
16224 + ;; If a doubleword move uses these expensive instructions,
16225 + ;; it is usually better to schedule them in the same way
16226 + ;; as the singleword form, rather than as "multi".
16227 + (eq_attr "move_type" "load") (const_string "load")
16228 + (eq_attr "move_type" "fpload") (const_string "fpload")
16229 + (eq_attr "move_type" "store") (const_string "store")
16230 + (eq_attr "move_type" "fpstore") (const_string "fpstore")
16231 + (eq_attr "move_type" "mtc") (const_string "mtc")
16232 + (eq_attr "move_type" "mfc") (const_string "mfc")
16234 + ;; These types of move are always single insns.
16235 + (eq_attr "move_type" "fmove") (const_string "fmove")
16236 + (eq_attr "move_type" "arith") (const_string "arith")
16237 + (eq_attr "move_type" "logical") (const_string "logical")
16238 + (eq_attr "move_type" "andi") (const_string "logical")
16240 + ;; These types of move are always split.
16241 + (eq_attr "move_type" "shift_shift")
16242 + (const_string "multi")
16244 + ;; These types of move are split for doubleword modes only.
16245 + (and (eq_attr "move_type" "move,const")
16246 + (eq_attr "dword_mode" "yes"))
16247 + (const_string "multi")
16248 + (eq_attr "move_type" "move") (const_string "move")
16249 + (eq_attr "move_type" "const") (const_string "const")]
16250 + (const_string "unknown")))
16252 +;; Mode for conversion types (fcvt)
16253 +;; I2S integer to float single (SI/DI to SF)
16254 +;; I2D integer to float double (SI/DI to DF)
16255 +;; S2I float to integer (SF to SI/DI)
16256 +;; D2I float to integer (DF to SI/DI)
16257 +;; D2S double to float single
16258 +;; S2D float single to double
16260 +(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
16261 + (const_string "unknown"))
16263 +;; Length of instruction in bytes.
16264 +(define_attr "length" ""
16265 + (cond [
16266 + ;; Direct branch instructions have a range of [-0x1000,0xffc],
16267 + ;; relative to the address of the delay slot. If a branch is
16268 + ;; outside this range, convert a branch like:
16269 + ;;
16270 + ;; bne r1,r2,target
16271 + ;;
16272 + ;; to:
16273 + ;;
16274 + ;; beq r1,r2,1f
16275 + ;; j target
16276 + ;; 1:
16277 + ;;
16278 + (eq_attr "type" "branch")
16279 + (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
16280 + (le (minus (pc) (match_dup 0)) (const_int 4092)))
16281 + (const_int 4)
16282 + (const_int 8))
16284 + ;; Conservatively assume calls take two instructions, as in:
16285 + ;; auipc t0, %pcrel_hi(target)
16286 + ;; jalr ra, t0, %lo(target)
16287 + ;; The linker will relax these into JAL when appropriate.
16288 + (eq_attr "type" "call")
16289 + (const_int 8)
16291 + ;; "Ghost" instructions occupy no space.
16292 + (eq_attr "type" "ghost")
16293 + (const_int 0)
16295 + (eq_attr "got" "load") (const_int 8)
16297 + ;; SHIFT_SHIFTs are decomposed into two separate instructions.
16298 + (eq_attr "move_type" "shift_shift")
16299 + (const_int 8)
16301 + ;; Check for doubleword moves that are decomposed into two
16302 + ;; instructions.
16303 + (and (eq_attr "move_type" "mtc,mfc,move")
16304 + (eq_attr "dword_mode" "yes"))
16305 + (const_int 8)
16307 + ;; Doubleword CONST{,N} moves are split into two word
16308 + ;; CONST{,N} moves.
16309 + (and (eq_attr "move_type" "const")
16310 + (eq_attr "dword_mode" "yes"))
16311 + (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
16313 + ;; Otherwise, constants, loads and stores are handled by external
16314 + ;; routines.
16315 + (eq_attr "move_type" "load,fpload")
16316 + (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
16317 + (eq_attr "move_type" "store,fpstore")
16318 + (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
16319 + ] (const_int 4)))
16321 +;; Describe a user's asm statement.
16322 +(define_asm_attributes
16323 + [(set_attr "type" "multi")])
16325 +;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
16326 +;; from the same template.
16327 +(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
16328 +(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
16330 +;; A copy of GPR that can be used when a pattern has two independent
16331 +;; modes.
16332 +(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
16334 +;; This mode iterator allows :P to be used for patterns that operate on
16335 +;; pointer-sized quantities. Exactly one of the two alternatives will match.
16336 +(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
16338 +;; 32-bit integer moves for which we provide move patterns.
16339 +(define_mode_iterator IMOVE32 [SI])
16341 +;; 64-bit modes for which we provide move patterns.
16342 +(define_mode_iterator MOVE64 [DI DF])
16344 +;; 128-bit modes for which we provide move patterns on 64-bit targets.
16345 +(define_mode_iterator MOVE128 [TI TF])
16347 +;; This mode iterator allows the QI and HI extension patterns to be
16348 +;; defined from the same template.
16349 +(define_mode_iterator SHORT [QI HI])
16351 +;; Likewise the 64-bit truncate-and-shift patterns.
16352 +(define_mode_iterator SUBDI [QI HI SI])
16353 +(define_mode_iterator HISI [HI SI])
16354 +(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
16356 +;; This mode iterator allows :ANYF to be used wherever a scalar or vector
16357 +;; floating-point mode is allowed.
16358 +(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
16359 + (DF "TARGET_HARD_FLOAT")])
16360 +(define_mode_iterator ANYIF [QI HI SI (DI "TARGET_64BIT")
16361 + (SF "TARGET_HARD_FLOAT")
16362 + (DF "TARGET_HARD_FLOAT")])
16364 +;; Like ANYF, but only applies to scalar modes.
16365 +(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
16366 + (DF "TARGET_HARD_FLOAT")])
16368 +;; A floating-point mode for which moves involving FPRs may need to be split.
16369 +(define_mode_iterator SPLITF
16370 + [(DF "!TARGET_64BIT")
16371 + (DI "!TARGET_64BIT")
16372 + (TF "TARGET_64BIT")])
16374 +;; This attribute gives the length suffix for a sign- or zero-extension
16375 +;; instruction.
16376 +(define_mode_attr size [(QI "b") (HI "h")])
16378 +;; Mode attributes for loads.
16379 +(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
16381 +;; Instruction names for stores.
16382 +(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
16384 +;; This attribute gives the best constraint to use for registers of
16385 +;; a given mode.
16386 +(define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
16388 +;; This attribute gives the format suffix for floating-point operations.
16389 +(define_mode_attr fmt [(SF "s") (DF "d")])
16391 +;; This attribute gives the format suffix for atomic memory operations.
16392 +(define_mode_attr amo [(SI "w") (DI "d")])
16394 +;; This attribute gives the upper-case mode name for one unit of a
16395 +;; floating-point mode.
16396 +(define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
16398 +;; This attribute gives the integer mode that has half the size of
16399 +;; the controlling mode.
16400 +(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
16402 +;; This code iterator allows signed and unsigned widening multiplications
16403 +;; to use the same template.
16404 +(define_code_iterator any_extend [sign_extend zero_extend])
16406 +;; This code iterator allows the two right shift instructions to be
16407 +;; generated from the same template.
16408 +(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
16410 +;; This code iterator allows the three shift instructions to be generated
16411 +;; from the same template.
16412 +(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
16414 +;; This code iterator allows unsigned and signed division to be generated
16415 +;; from the same template.
16416 +(define_code_iterator any_div [div udiv])
16418 +;; This code iterator allows unsigned and signed modulus to be generated
16419 +;; from the same template.
16420 +(define_code_iterator any_mod [mod umod])
16422 +;; These code iterators allow the signed and unsigned scc operations to use
16423 +;; the same template.
16424 +(define_code_iterator any_gt [gt gtu])
16425 +(define_code_iterator any_ge [ge geu])
16426 +(define_code_iterator any_lt [lt ltu])
16427 +(define_code_iterator any_le [le leu])
16429 +;; <u> expands to an empty string when doing a signed operation and
16430 +;; "u" when doing an unsigned operation.
16431 +(define_code_attr u [(sign_extend "") (zero_extend "u")
16432 + (div "") (udiv "u")
16433 + (mod "") (umod "u")
16434 + (gt "") (gtu "u")
16435 + (ge "") (geu "u")
16436 + (lt "") (ltu "u")
16437 + (le "") (leu "u")])
16439 +;; <su> is like <u>, but the signed form expands to "s" rather than "".
16440 +(define_code_attr su [(sign_extend "s") (zero_extend "u")])
16442 +;; <optab> expands to the name of the optab for a particular code.
16443 +(define_code_attr optab [(ashift "ashl")
16444 + (ashiftrt "ashr")
16445 + (lshiftrt "lshr")
16446 + (ior "ior")
16447 + (xor "xor")
16448 + (and "and")
16449 + (plus "add")
16450 + (minus "sub")])
16452 +;; <insn> expands to the name of the insn that implements a particular code.
16453 +(define_code_attr insn [(ashift "sll")
16454 + (ashiftrt "sra")
16455 + (lshiftrt "srl")
16456 + (ior "or")
16457 + (xor "xor")
16458 + (and "and")
16459 + (plus "add")
16460 + (minus "sub")])
16462 +;; Pipeline descriptions.
16464 +;; generic.md provides a fallback for processors without a specific
16465 +;; pipeline description. It is derived from the old define_function_unit
16466 +;; version and uses the "alu" and "imuldiv" units declared below.
16468 +;; Some of the processor-specific files are also derived from old
16469 +;; define_function_unit descriptions and simply override the parts of
16470 +;; generic.md that don't apply. The other processor-specific files
16471 +;; are self-contained.
16472 +(define_automaton "alu,imuldiv")
16474 +(define_cpu_unit "alu" "alu")
16475 +(define_cpu_unit "imuldiv" "imuldiv")
16477 +;; Ghost instructions produce no real code and introduce no hazards.
16478 +;; They exist purely to express an effect on dataflow.
16479 +(define_insn_reservation "ghost" 0
16480 + (eq_attr "type" "ghost")
16481 + "nothing")
16483 +(include "generic.md")
16486 +;; ....................
16488 +;; ADDITION
16490 +;; ....................
16493 +(define_insn "add<mode>3"
16494 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16495 + (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
16496 + (match_operand:ANYF 2 "register_operand" "f")))]
16497 + ""
16498 + "fadd.<fmt>\t%0,%1,%2"
16499 + [(set_attr "type" "fadd")
16500 + (set_attr "mode" "<UNITMODE>")])
16502 +(define_expand "add<mode>3"
16503 + [(set (match_operand:GPR 0 "register_operand")
16504 + (plus:GPR (match_operand:GPR 1 "register_operand")
16505 + (match_operand:GPR 2 "arith_operand")))]
16506 + "")
16508 +(define_insn "*addsi3"
16509 + [(set (match_operand:SI 0 "register_operand" "=r,r")
16510 + (plus:SI (match_operand:GPR 1 "register_operand" "r,r")
16511 + (match_operand:GPR2 2 "arith_operand" "r,Q")))]
16512 + ""
16513 + { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
16514 + [(set_attr "type" "arith")
16515 + (set_attr "mode" "SI")])
16517 +(define_insn "*adddi3"
16518 + [(set (match_operand:DI 0 "register_operand" "=r,r")
16519 + (plus:DI (match_operand:DI 1 "register_operand" "r,r")
16520 + (match_operand:DI 2 "arith_operand" "r,Q")))]
16521 + "TARGET_64BIT"
16522 + "add\t%0,%1,%2"
16523 + [(set_attr "type" "arith")
16524 + (set_attr "mode" "DI")])
16526 +(define_insn "*addsi3_extended"
16527 + [(set (match_operand:DI 0 "register_operand" "=r,r")
16528 + (sign_extend:DI
16529 + (plus:SI (match_operand:SI 1 "register_operand" "r,r")
16530 + (match_operand:SI 2 "arith_operand" "r,Q"))))]
16531 + "TARGET_64BIT"
16532 + "addw\t%0,%1,%2"
16533 + [(set_attr "type" "arith")
16534 + (set_attr "mode" "SI")])
16536 +(define_insn "*adddisi3"
16537 + [(set (match_operand:SI 0 "register_operand" "=r,r")
16538 + (plus:SI (truncate:SI (match_operand:DI 1 "register_operand" "r,r"))
16539 + (truncate:SI (match_operand:DI 2 "arith_operand" "r,Q"))))]
16540 + "TARGET_64BIT"
16541 + "addw\t%0,%1,%2"
16542 + [(set_attr "type" "arith")
16543 + (set_attr "mode" "SI")])
16545 +(define_insn "*adddisisi3"
16546 + [(set (match_operand:SI 0 "register_operand" "=r,r")
16547 + (plus:SI (truncate:SI (match_operand:DI 1 "register_operand" "r,r"))
16548 + (match_operand:SI 2 "arith_operand" "r,Q")))]
16549 + "TARGET_64BIT"
16550 + "addw\t%0,%1,%2"
16551 + [(set_attr "type" "arith")
16552 + (set_attr "mode" "SI")])
16554 +(define_insn "*adddi3_truncsi"
16555 + [(set (match_operand:SI 0 "register_operand" "=r,r")
16556 + (truncate:SI
16557 + (plus:DI (match_operand:DI 1 "register_operand" "r,r")
16558 + (match_operand:DI 2 "arith_operand" "r,Q"))))]
16559 + "TARGET_64BIT"
16560 + "addw\t%0,%1,%2"
16561 + [(set_attr "type" "arith")
16562 + (set_attr "mode" "SI")])
16565 +;; ....................
16567 +;; SUBTRACTION
16569 +;; ....................
16572 +(define_insn "sub<mode>3"
16573 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16574 + (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
16575 + (match_operand:ANYF 2 "register_operand" "f")))]
16576 + ""
16577 + "fsub.<fmt>\t%0,%1,%2"
16578 + [(set_attr "type" "fadd")
16579 + (set_attr "mode" "<UNITMODE>")])
16581 +(define_expand "sub<mode>3"
16582 + [(set (match_operand:GPR 0 "register_operand")
16583 + (minus:GPR (match_operand:GPR 1 "reg_or_0_operand")
16584 + (match_operand:GPR 2 "register_operand")))]
16585 + "")
16587 +(define_insn "*subdi3"
16588 + [(set (match_operand:DI 0 "register_operand" "=r")
16589 + (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
16590 + (match_operand:DI 2 "register_operand" "r")))]
16591 + "TARGET_64BIT"
16592 + "sub\t%0,%z1,%2"
16593 + [(set_attr "type" "arith")
16594 + (set_attr "mode" "DI")])
16596 +(define_insn "*subsi3"
16597 + [(set (match_operand:SI 0 "register_operand" "=r")
16598 + (minus:SI (match_operand:GPR 1 "reg_or_0_operand" "rJ")
16599 + (match_operand:GPR2 2 "register_operand" "r")))]
16600 + ""
16601 + { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
16602 + [(set_attr "type" "arith")
16603 + (set_attr "mode" "SI")])
16605 +(define_insn "*subsi3_extended"
16606 + [(set (match_operand:DI 0 "register_operand" "=r")
16607 + (sign_extend:DI
16608 + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
16609 + (match_operand:SI 2 "register_operand" "r"))))]
16610 + "TARGET_64BIT"
16611 + "subw\t%0,%z1,%2"
16612 + [(set_attr "type" "arith")
16613 + (set_attr "mode" "DI")])
16615 +(define_insn "*subdisi3"
16616 + [(set (match_operand:SI 0 "register_operand" "=r")
16617 + (minus:SI (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rJ"))
16618 + (truncate:SI (match_operand:DI 2 "register_operand" "r"))))]
16619 + "TARGET_64BIT"
16620 + "subw\t%0,%z1,%2"
16621 + [(set_attr "type" "arith")
16622 + (set_attr "mode" "SI")])
16624 +(define_insn "*subdisisi3"
16625 + [(set (match_operand:SI 0 "register_operand" "=r")
16626 + (minus:SI (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rJ"))
16627 + (match_operand:SI 2 "register_operand" "r")))]
16628 + "TARGET_64BIT"
16629 + "subw\t%0,%z1,%2"
16630 + [(set_attr "type" "arith")
16631 + (set_attr "mode" "SI")])
16633 +(define_insn "*subsidisi3"
16634 + [(set (match_operand:SI 0 "register_operand" "=r")
16635 + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
16636 + (truncate:SI (match_operand:DI 2 "register_operand" "r"))))]
16637 + "TARGET_64BIT"
16638 + "subw\t%0,%z1,%2"
16639 + [(set_attr "type" "arith")
16640 + (set_attr "mode" "SI")])
16642 +(define_insn "*subdi3_truncsi"
16643 + [(set (match_operand:SI 0 "register_operand" "=r,r")
16644 + (truncate:SI
16645 + (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,r")
16646 + (match_operand:DI 2 "arith_operand" "r,Q"))))]
16647 + "TARGET_64BIT"
16648 + "subw\t%0,%z1,%2"
16649 + [(set_attr "type" "arith")
16650 + (set_attr "mode" "SI")])
16653 +;; ....................
16655 +;; MULTIPLICATION
16657 +;; ....................
16660 +(define_insn "mul<mode>3"
16661 + [(set (match_operand:SCALARF 0 "register_operand" "=f")
16662 + (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
16663 + (match_operand:SCALARF 2 "register_operand" "f")))]
16664 + ""
16665 + "fmul.<fmt>\t%0,%1,%2"
16666 + [(set_attr "type" "fmul")
16667 + (set_attr "mode" "<UNITMODE>")])
16669 +(define_expand "mul<mode>3"
16670 + [(set (match_operand:GPR 0 "register_operand")
16671 + (mult:GPR (match_operand:GPR 1 "reg_or_0_operand")
16672 + (match_operand:GPR 2 "register_operand")))]
16673 + "TARGET_MULDIV")
16675 +(define_insn "*mulsi3"
16676 + [(set (match_operand:SI 0 "register_operand" "=r")
16677 + (mult:SI (match_operand:GPR 1 "register_operand" "r")
16678 + (match_operand:GPR2 2 "register_operand" "r")))]
16679 + "TARGET_MULDIV"
16680 + { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
16681 + [(set_attr "type" "imul")
16682 + (set_attr "mode" "SI")])
16684 +(define_insn "*muldisi3"
16685 + [(set (match_operand:SI 0 "register_operand" "=r")
16686 + (mult:SI (truncate:SI (match_operand:DI 1 "register_operand" "r"))
16687 + (truncate:SI (match_operand:DI 2 "register_operand" "r"))))]
16688 + "TARGET_MULDIV && TARGET_64BIT"
16689 + "mulw\t%0,%1,%2"
16690 + [(set_attr "type" "imul")
16691 + (set_attr "mode" "SI")])
16693 +(define_insn "*muldi3_truncsi"
16694 + [(set (match_operand:SI 0 "register_operand" "=r")
16695 + (truncate:SI
16696 + (mult:DI (match_operand:DI 1 "register_operand" "r")
16697 + (match_operand:DI 2 "register_operand" "r"))))]
16698 + "TARGET_MULDIV && TARGET_64BIT"
16699 + "mulw\t%0,%1,%2"
16700 + [(set_attr "type" "imul")
16701 + (set_attr "mode" "SI")])
16703 +(define_insn "*muldi3"
16704 + [(set (match_operand:DI 0 "register_operand" "=r")
16705 + (mult:DI (match_operand:DI 1 "register_operand" "r")
16706 + (match_operand:DI 2 "register_operand" "r")))]
16707 + "TARGET_MULDIV && TARGET_64BIT"
16708 + "mul\t%0,%1,%2"
16709 + [(set_attr "type" "imul")
16710 + (set_attr "mode" "DI")])
16713 +;; ........................
16715 +;; MULTIPLICATION HIGH-PART
16717 +;; ........................
16721 +;; Using a clobber here is ghetto, but I'm not smart enough to do better. '
16722 +(define_insn_and_split "<u>mulditi3"
16723 + [(set (match_operand:TI 0 "register_operand" "=r")
16724 + (mult:TI (any_extend:TI
16725 + (match_operand:DI 1 "register_operand" "r"))
16726 + (any_extend:TI
16727 + (match_operand:DI 2 "register_operand" "r"))))
16728 + (clobber (match_scratch:DI 3 "=r"))]
16729 + "TARGET_MULDIV && TARGET_64BIT"
16730 + "#"
16731 + "reload_completed"
16733 + (set (match_dup 3) (mult:DI (match_dup 1) (match_dup 2)))
16734 + (set (match_dup 4) (truncate:DI
16735 + (lshiftrt:TI
16736 + (mult:TI (any_extend:TI (match_dup 1))
16737 + (any_extend:TI (match_dup 2)))
16738 + (const_int 64))))
16739 + (set (match_dup 5) (match_dup 3))
16742 + operands[4] = riscv_subword (operands[0], true);
16743 + operands[5] = riscv_subword (operands[0], false);
16747 +(define_insn "<u>muldi3_highpart"
16748 + [(set (match_operand:DI 0 "register_operand" "=r")
16749 + (truncate:DI
16750 + (lshiftrt:TI
16751 + (mult:TI (any_extend:TI
16752 + (match_operand:DI 1 "register_operand" "r"))
16753 + (any_extend:TI
16754 + (match_operand:DI 2 "register_operand" "r")))
16755 + (const_int 64))))]
16756 + "TARGET_MULDIV && TARGET_64BIT"
16757 + "mulh<u>\t%0,%1,%2"
16758 + [(set_attr "type" "imul")
16759 + (set_attr "mode" "DI")])
16762 +(define_insn_and_split "usmulditi3"
16763 + [(set (match_operand:TI 0 "register_operand" "=r")
16764 + (mult:TI (zero_extend:TI
16765 + (match_operand:DI 1 "register_operand" "r"))
16766 + (sign_extend:TI
16767 + (match_operand:DI 2 "register_operand" "r"))))
16768 + (clobber (match_scratch:DI 3 "=r"))]
16769 + "TARGET_MULDIV && TARGET_64BIT"
16770 + "#"
16771 + "reload_completed"
16773 + (set (match_dup 3) (mult:DI (match_dup 1) (match_dup 2)))
16774 + (set (match_dup 4) (truncate:DI
16775 + (lshiftrt:TI
16776 + (mult:TI (zero_extend:TI (match_dup 1))
16777 + (sign_extend:TI (match_dup 2)))
16778 + (const_int 64))))
16779 + (set (match_dup 5) (match_dup 3))
16782 + operands[4] = riscv_subword (operands[0], true);
16783 + operands[5] = riscv_subword (operands[0], false);
16787 +(define_insn "usmuldi3_highpart"
16788 + [(set (match_operand:DI 0 "register_operand" "=r")
16789 + (truncate:DI
16790 + (lshiftrt:TI
16791 + (mult:TI (zero_extend:TI
16792 + (match_operand:DI 1 "register_operand" "r"))
16793 + (sign_extend:TI
16794 + (match_operand:DI 2 "register_operand" "r")))
16795 + (const_int 64))))]
16796 + "TARGET_MULDIV && TARGET_64BIT"
16797 + "mulhsu\t%0,%2,%1"
16798 + [(set_attr "type" "imul")
16799 + (set_attr "mode" "DI")])
16801 +(define_expand "<u>mulsidi3"
16802 + [(set (match_operand:DI 0 "register_operand" "=r")
16803 + (mult:DI (any_extend:DI
16804 + (match_operand:SI 1 "register_operand" "r"))
16805 + (any_extend:DI
16806 + (match_operand:SI 2 "register_operand" "r"))))
16807 + (clobber (match_scratch:SI 3 "=r"))]
16808 + "TARGET_MULDIV && !TARGET_64BIT"
16810 + rtx temp = gen_reg_rtx (SImode);
16811 + emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
16812 + emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
16813 + operands[1], operands[2]));
16814 + emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
16815 + DONE;
16819 +(define_insn "<u>mulsi3_highpart"
16820 + [(set (match_operand:SI 0 "register_operand" "=r")
16821 + (truncate:SI
16822 + (lshiftrt:DI
16823 + (mult:DI (any_extend:DI
16824 + (match_operand:SI 1 "register_operand" "r"))
16825 + (any_extend:DI
16826 + (match_operand:SI 2 "register_operand" "r")))
16827 + (const_int 32))))]
16828 + "TARGET_MULDIV && !TARGET_64BIT"
16829 + "mulh<u>\t%0,%1,%2"
16830 + [(set_attr "type" "imul")
16831 + (set_attr "mode" "SI")])
16834 +(define_expand "usmulsidi3"
16835 + [(set (match_operand:DI 0 "register_operand" "=r")
16836 + (mult:DI (zero_extend:DI
16837 + (match_operand:SI 1 "register_operand" "r"))
16838 + (sign_extend:DI
16839 + (match_operand:SI 2 "register_operand" "r"))))
16840 + (clobber (match_scratch:SI 3 "=r"))]
16841 + "TARGET_MULDIV && !TARGET_64BIT"
16843 + rtx temp = gen_reg_rtx (SImode);
16844 + emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
16845 + emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
16846 + operands[1], operands[2]));
16847 + emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
16848 + DONE;
16852 +(define_insn "usmulsi3_highpart"
16853 + [(set (match_operand:SI 0 "register_operand" "=r")
16854 + (truncate:SI
16855 + (lshiftrt:DI
16856 + (mult:DI (zero_extend:DI
16857 + (match_operand:SI 1 "register_operand" "r"))
16858 + (sign_extend:DI
16859 + (match_operand:SI 2 "register_operand" "r")))
16860 + (const_int 32))))]
16861 + "TARGET_MULDIV && !TARGET_64BIT"
16862 + "mulhsu\t%0,%2,%1"
16863 + [(set_attr "type" "imul")
16864 + (set_attr "mode" "SI")])
16867 +;; ....................
16869 +;; DIVISION and REMAINDER
16871 +;; ....................
16874 +(define_insn "<u>divsi3"
16875 + [(set (match_operand:SI 0 "register_operand" "=r")
16876 + (any_div:SI (match_operand:SI 1 "register_operand" "r")
16877 + (match_operand:SI 2 "register_operand" "r")))]
16878 + "TARGET_MULDIV"
16879 + { return TARGET_64BIT ? "div<u>w\t%0,%1,%2" : "div<u>\t%0,%1,%2"; }
16880 + [(set_attr "type" "idiv")
16881 + (set_attr "mode" "SI")])
16883 +(define_insn "<u>divdi3"
16884 + [(set (match_operand:DI 0 "register_operand" "=r")
16885 + (any_div:DI (match_operand:DI 1 "register_operand" "r")
16886 + (match_operand:DI 2 "register_operand" "r")))]
16887 + "TARGET_MULDIV && TARGET_64BIT"
16888 + "div<u>\t%0,%1,%2"
16889 + [(set_attr "type" "idiv")
16890 + (set_attr "mode" "DI")])
16892 +(define_insn "<u>modsi3"
16893 + [(set (match_operand:SI 0 "register_operand" "=r")
16894 + (any_mod:SI (match_operand:SI 1 "register_operand" "r")
16895 + (match_operand:SI 2 "register_operand" "r")))]
16896 + "TARGET_MULDIV"
16897 + { return TARGET_64BIT ? "rem<u>w\t%0,%1,%2" : "rem<u>\t%0,%1,%2"; }
16898 + [(set_attr "type" "idiv")
16899 + (set_attr "mode" "SI")])
16901 +(define_insn "<u>moddi3"
16902 + [(set (match_operand:DI 0 "register_operand" "=r")
16903 + (any_mod:DI (match_operand:DI 1 "register_operand" "r")
16904 + (match_operand:DI 2 "register_operand" "r")))]
16905 + "TARGET_MULDIV && TARGET_64BIT"
16906 + "rem<u>\t%0,%1,%2"
16907 + [(set_attr "type" "idiv")
16908 + (set_attr "mode" "DI")])
16910 +(define_insn "div<mode>3"
16911 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16912 + (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
16913 + (match_operand:ANYF 2 "register_operand" "f")))]
16914 + "TARGET_HARD_FLOAT && TARGET_FDIV"
16915 + "fdiv.<fmt>\t%0,%1,%2"
16916 + [(set_attr "type" "fdiv")
16917 + (set_attr "mode" "<UNITMODE>")])
16920 +;; ....................
16922 +;; SQUARE ROOT
16924 +;; ....................
16926 +(define_insn "sqrt<mode>2"
16927 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16928 + (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
16929 + "TARGET_HARD_FLOAT && TARGET_FDIV"
16931 + return "fsqrt.<fmt>\t%0,%1";
16933 + [(set_attr "type" "fsqrt")
16934 + (set_attr "mode" "<UNITMODE>")])
16936 +;; Floating point multiply accumulate instructions.
16938 +(define_insn "fma<mode>4"
16939 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16940 + (fma:ANYF
16941 + (match_operand:ANYF 1 "register_operand" "f")
16942 + (match_operand:ANYF 2 "register_operand" "f")
16943 + (match_operand:ANYF 3 "register_operand" "f")))]
16944 + "TARGET_HARD_FLOAT"
16945 + "fmadd.<fmt>\t%0,%1,%2,%3"
16946 + [(set_attr "type" "fmadd")
16947 + (set_attr "mode" "<UNITMODE>")])
16949 +(define_insn "fms<mode>4"
16950 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16951 + (fma:ANYF
16952 + (match_operand:ANYF 1 "register_operand" "f")
16953 + (match_operand:ANYF 2 "register_operand" "f")
16954 + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))]
16955 + "TARGET_HARD_FLOAT"
16956 + "fmsub.<fmt>\t%0,%1,%2,%3"
16957 + [(set_attr "type" "fmadd")
16958 + (set_attr "mode" "<UNITMODE>")])
16960 +(define_insn "nfma<mode>4"
16961 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16962 + (neg:ANYF
16963 + (fma:ANYF
16964 + (match_operand:ANYF 1 "register_operand" "f")
16965 + (match_operand:ANYF 2 "register_operand" "f")
16966 + (match_operand:ANYF 3 "register_operand" "f"))))]
16967 + "TARGET_HARD_FLOAT"
16968 + "fnmadd.<fmt>\t%0,%1,%2,%3"
16969 + [(set_attr "type" "fmadd")
16970 + (set_attr "mode" "<UNITMODE>")])
16972 +(define_insn "nfms<mode>4"
16973 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16974 + (neg:ANYF
16975 + (fma:ANYF
16976 + (match_operand:ANYF 1 "register_operand" "f")
16977 + (match_operand:ANYF 2 "register_operand" "f")
16978 + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))]
16979 + "TARGET_HARD_FLOAT"
16980 + "fnmsub.<fmt>\t%0,%1,%2,%3"
16981 + [(set_attr "type" "fmadd")
16982 + (set_attr "mode" "<UNITMODE>")])
16984 +;; modulo signed zeros, -(a*b+c) == -c-a*b
16985 +(define_insn "*nfma<mode>4_fastmath"
16986 + [(set (match_operand:ANYF 0 "register_operand" "=f")
16987 + (minus:ANYF
16988 + (match_operand:ANYF 3 "register_operand" "f")
16989 + (mult:ANYF
16990 + (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
16991 + (match_operand:ANYF 2 "register_operand" "f"))))]
16992 + "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
16993 + "fnmadd.<fmt>\t%0,%1,%2,%3"
16994 + [(set_attr "type" "fmadd")
16995 + (set_attr "mode" "<UNITMODE>")])
16997 +;; modulo signed zeros, -(a*b-c) == c-a*b
16998 +(define_insn "*nfms<mode>4_fastmath"
16999 + [(set (match_operand:ANYF 0 "register_operand" "=f")
17000 + (minus:ANYF
17001 + (match_operand:ANYF 3 "register_operand" "f")
17002 + (mult:ANYF
17003 + (match_operand:ANYF 1 "register_operand" "f")
17004 + (match_operand:ANYF 2 "register_operand" "f"))))]
17005 + "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
17006 + "fnmsub.<fmt>\t%0,%1,%2,%3"
17007 + [(set_attr "type" "fmadd")
17008 + (set_attr "mode" "<UNITMODE>")])
17011 +;; ....................
17013 +;; ABSOLUTE VALUE
17015 +;; ....................
17017 +(define_insn "abs<mode>2"
17018 + [(set (match_operand:ANYF 0 "register_operand" "=f")
17019 + (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
17020 + "TARGET_HARD_FLOAT"
17021 + "fabs.<fmt>\t%0,%1"
17022 + [(set_attr "type" "fmove")
17023 + (set_attr "mode" "<UNITMODE>")])
17027 +;; ....................
17029 +;; MIN/MAX
17031 +;; ....................
17033 +(define_insn "smin<mode>3"
17034 + [(set (match_operand:ANYF 0 "register_operand" "=f")
17035 + (smin:ANYF (match_operand:ANYF 1 "register_operand" "f")
17036 + (match_operand:ANYF 2 "register_operand" "f")))]
17037 + "TARGET_HARD_FLOAT"
17038 + "fmin.<fmt>\t%0,%1,%2"
17039 + [(set_attr "type" "fmove")
17040 + (set_attr "mode" "<UNITMODE>")])
17042 +(define_insn "smax<mode>3"
17043 + [(set (match_operand:ANYF 0 "register_operand" "=f")
17044 + (smax:ANYF (match_operand:ANYF 1 "register_operand" "f")
17045 + (match_operand:ANYF 2 "register_operand" "f")))]
17046 + "TARGET_HARD_FLOAT"
17047 + "fmax.<fmt>\t%0,%1,%2"
17048 + [(set_attr "type" "fmove")
17049 + (set_attr "mode" "<UNITMODE>")])
17053 +;; ....................
17055 +;; NEGATION and ONE'S COMPLEMENT '
17057 +;; ....................
17059 +(define_insn "neg<mode>2"
17060 + [(set (match_operand:ANYF 0 "register_operand" "=f")
17061 + (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
17062 + "TARGET_HARD_FLOAT"
17063 + "fneg.<fmt>\t%0,%1"
17064 + [(set_attr "type" "fmove")
17065 + (set_attr "mode" "<UNITMODE>")])
17067 +(define_insn "one_cmpl<mode>2"
17068 + [(set (match_operand:GPR 0 "register_operand" "=r")
17069 + (not:GPR (match_operand:GPR 1 "register_operand" "r")))]
17070 + ""
17071 + "not\t%0,%1"
17072 + [(set_attr "type" "logical")
17073 + (set_attr "mode" "<MODE>")])
17076 +;; ....................
17078 +;; LOGICAL
17080 +;; ....................
17083 +(define_insn "and<mode>3"
17084 + [(set (match_operand:GPR 0 "register_operand" "=r,r")
17085 + (and:GPR (match_operand:GPR 1 "register_operand" "%r,r")
17086 + (match_operand:GPR 2 "arith_operand" "r,Q")))]
17087 + ""
17088 + "and\t%0,%1,%2"
17089 + [(set_attr "type" "logical")
17090 + (set_attr "mode" "<MODE>")])
17092 +(define_insn "ior<mode>3"
17093 + [(set (match_operand:GPR 0 "register_operand" "=r,r")
17094 + (ior:GPR (match_operand:GPR 1 "register_operand" "%r,r")
17095 + (match_operand:GPR 2 "arith_operand" "r,Q")))]
17096 + ""
17097 + "or\t%0,%1,%2"
17098 + [(set_attr "type" "logical")
17099 + (set_attr "mode" "<MODE>")])
17101 +(define_insn "xor<mode>3"
17102 + [(set (match_operand:GPR 0 "register_operand" "=r,r")
17103 + (xor:GPR (match_operand:GPR 1 "register_operand" "%r,r")
17104 + (match_operand:GPR 2 "arith_operand" "r,Q")))]
17105 + ""
17106 + "xor\t%0,%1,%2"
17107 + [(set_attr "type" "logical")
17108 + (set_attr "mode" "<MODE>")])
17111 +;; ....................
17113 +;; TRUNCATION
17115 +;; ....................
17117 +(define_insn "truncdfsf2"
17118 + [(set (match_operand:SF 0 "register_operand" "=f")
17119 + (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
17120 + "TARGET_HARD_FLOAT"
17121 + "fcvt.s.d\t%0,%1"
17122 + [(set_attr "type" "fcvt")
17123 + (set_attr "cnv_mode" "D2S")
17124 + (set_attr "mode" "SF")])
17126 +;; Integer truncation patterns. Truncating to HImode/QImode is a no-op.
17127 +;; Truncating from DImode to SImode is not, because we always keep SImode
17128 +;; values sign-extended in a register so we can safely use DImode branches
17129 +;; and comparisons on SImode values.
17131 +(define_insn "truncdisi2"
17132 + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
17133 + (truncate:SI (match_operand:DI 1 "register_operand" "r,r")))]
17134 + "TARGET_64BIT"
17135 + "@
17136 + sext.w\t%0,%1
17137 + sw\t%1,%0"
17138 + [(set_attr "move_type" "arith,store")
17139 + (set_attr "mode" "SI")])
17141 +;; Combiner patterns to optimize shift/truncate combinations.
17143 +(define_insn "*ashr_trunc<mode>"
17144 + [(set (match_operand:SUBDI 0 "register_operand" "=r")
17145 + (truncate:SUBDI
17146 + (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
17147 + (match_operand:DI 2 "const_arith_operand" ""))))]
17148 + "TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
17149 + "sra\t%0,%1,%2"
17150 + [(set_attr "type" "shift")
17151 + (set_attr "mode" "<MODE>")])
17153 +(define_insn "*lshr32_trunc<mode>"
17154 + [(set (match_operand:SUBDI 0 "register_operand" "=r")
17155 + (truncate:SUBDI
17156 + (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
17157 + (const_int 32))))]
17158 + "TARGET_64BIT"
17159 + "sra\t%0,%1,32"
17160 + [(set_attr "type" "shift")
17161 + (set_attr "mode" "<MODE>")])
17164 +;; ....................
17166 +;; ZERO EXTENSION
17168 +;; ....................
17170 +;; Extension insns.
17172 +(define_insn_and_split "zero_extendsidi2"
17173 + [(set (match_operand:DI 0 "register_operand" "=r,r")
17174 + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,W")))]
17175 + "TARGET_64BIT"
17176 + "@
17178 + lwu\t%0,%1"
17179 + "&& reload_completed && REG_P (operands[1])"
17180 + [(set (match_dup 0)
17181 + (ashift:DI (match_dup 1) (const_int 32)))
17182 + (set (match_dup 0)
17183 + (lshiftrt:DI (match_dup 0) (const_int 32)))]
17184 + { operands[1] = gen_lowpart (DImode, operands[1]); }
17185 + [(set_attr "move_type" "shift_shift,load")
17186 + (set_attr "mode" "DI")])
17188 +;; Combine is not allowed to convert this insn into a zero_extendsidi2
17189 +;; because of TRULY_NOOP_TRUNCATION.
17191 +(define_insn_and_split "*clear_upper32"
17192 + [(set (match_operand:DI 0 "register_operand" "=r,r")
17193 + (and:DI (match_operand:DI 1 "nonimmediate_operand" "r,W")
17194 + (const_int 4294967295)))]
17195 + "TARGET_64BIT"
17197 + if (which_alternative == 0)
17198 + return "#";
17200 + operands[1] = gen_lowpart (SImode, operands[1]);
17201 + return "lwu\t%0,%1";
17203 + "&& reload_completed && REG_P (operands[1])"
17204 + [(set (match_dup 0)
17205 + (ashift:DI (match_dup 1) (const_int 32)))
17206 + (set (match_dup 0)
17207 + (lshiftrt:DI (match_dup 0) (const_int 32)))]
17208 + ""
17209 + [(set_attr "move_type" "shift_shift,load")
17210 + (set_attr "mode" "DI")])
17212 +(define_insn_and_split "zero_extendhi<GPR:mode>2"
17213 + [(set (match_operand:GPR 0 "register_operand" "=r,r")
17214 + (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
17215 + ""
17216 + "@
17218 + lhu\t%0,%1"
17219 + "&& reload_completed && REG_P (operands[1])"
17220 + [(set (match_dup 0)
17221 + (ashift:GPR (match_dup 1) (match_dup 2)))
17222 + (set (match_dup 0)
17223 + (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
17225 + operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
17226 + operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
17228 + [(set_attr "move_type" "shift_shift,load")
17229 + (set_attr "mode" "<GPR:MODE>")])
17231 +(define_insn "zero_extendqi<SUPERQI:mode>2"
17232 + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
17233 + (zero_extend:SUPERQI
17234 + (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
17235 + ""
17236 + "@
17237 + and\t%0,%1,0xff
17238 + lbu\t%0,%1"
17239 + [(set_attr "move_type" "andi,load")
17240 + (set_attr "mode" "<SUPERQI:MODE>")])
17243 +;; ....................
17245 +;; SIGN EXTENSION
17247 +;; ....................
17249 +;; Extension insns.
17250 +;; Those for integer source operand are ordered widest source type first.
17252 +;; When TARGET_64BIT, all SImode integer registers should already be in
17253 +;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
17254 +;; therefore get rid of register->register instructions if we constrain
17255 +;; the source to be in the same register as the destination.
17257 +;; The register alternative has type "arith" so that the pre-reload
17258 +;; scheduler will treat it as a move. This reflects what happens if
17259 +;; the register alternative needs a reload.
17260 +(define_insn_and_split "extendsidi2"
17261 + [(set (match_operand:DI 0 "register_operand" "=r,r")
17262 + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
17263 + "TARGET_64BIT"
17264 + "@
17266 + lw\t%0,%1"
17267 + "&& reload_completed && register_operand (operands[1], VOIDmode)"
17268 + [(set (match_dup 0) (match_dup 1))]
17270 + if (REGNO (operands[0]) == REGNO (operands[1]))
17272 + emit_note (NOTE_INSN_DELETED);
17273 + DONE;
17275 + operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
17277 + [(set_attr "move_type" "move,load")
17278 + (set_attr "mode" "DI")])
17280 +(define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
17281 + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
17282 + (sign_extend:SUPERQI
17283 + (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
17284 + ""
17285 + "@
17287 + l<SHORT:size>\t%0,%1"
17288 + "&& reload_completed && REG_P (operands[1])"
17289 + [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
17290 + (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
17292 + operands[0] = gen_lowpart (SImode, operands[0]);
17293 + operands[1] = gen_lowpart (SImode, operands[1]);
17294 + operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
17295 + - GET_MODE_BITSIZE (<SHORT:MODE>mode));
17297 + [(set_attr "move_type" "shift_shift,load")
17298 + (set_attr "mode" "SI")])
17300 +(define_insn "extendsfdf2"
17301 + [(set (match_operand:DF 0 "register_operand" "=f")
17302 + (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
17303 + "TARGET_HARD_FLOAT"
17304 + "fcvt.d.s\t%0,%1"
17305 + [(set_attr "type" "fcvt")
17306 + (set_attr "cnv_mode" "S2D")
17307 + (set_attr "mode" "DF")])
17310 +;; ....................
17312 +;; CONVERSIONS
17314 +;; ....................
17316 +(define_insn "fix_truncdfsi2"
17317 + [(set (match_operand:SI 0 "register_operand" "=r")
17318 + (fix:SI (match_operand:DF 1 "register_operand" "f")))]
17319 + "TARGET_HARD_FLOAT"
17320 + "fcvt.w.d %0,%1,rtz"
17321 + [(set_attr "type" "fcvt")
17322 + (set_attr "mode" "DF")
17323 + (set_attr "cnv_mode" "D2I")])
17326 +(define_insn "fix_truncsfsi2"
17327 + [(set (match_operand:SI 0 "register_operand" "=r")
17328 + (fix:SI (match_operand:SF 1 "register_operand" "f")))]
17329 + "TARGET_HARD_FLOAT"
17330 + "fcvt.w.s %0,%1,rtz"
17331 + [(set_attr "type" "fcvt")
17332 + (set_attr "mode" "SF")
17333 + (set_attr "cnv_mode" "S2I")])
17336 +(define_insn "fix_truncdfdi2"
17337 + [(set (match_operand:DI 0 "register_operand" "=r")
17338 + (fix:DI (match_operand:DF 1 "register_operand" "f")))]
17339 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17340 + "fcvt.l.d %0,%1,rtz"
17341 + [(set_attr "type" "fcvt")
17342 + (set_attr "mode" "DF")
17343 + (set_attr "cnv_mode" "D2I")])
17346 +(define_insn "fix_truncsfdi2"
17347 + [(set (match_operand:DI 0 "register_operand" "=r")
17348 + (fix:DI (match_operand:SF 1 "register_operand" "f")))]
17349 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17350 + "fcvt.l.s %0,%1,rtz"
17351 + [(set_attr "type" "fcvt")
17352 + (set_attr "mode" "SF")
17353 + (set_attr "cnv_mode" "S2I")])
17356 +(define_insn "floatsidf2"
17357 + [(set (match_operand:DF 0 "register_operand" "=f")
17358 + (float:DF (match_operand:SI 1 "reg_or_0_operand" "rJ")))]
17359 + "TARGET_HARD_FLOAT"
17360 + "fcvt.d.w\t%0,%z1"
17361 + [(set_attr "type" "fcvt")
17362 + (set_attr "mode" "DF")
17363 + (set_attr "cnv_mode" "I2D")])
17366 +(define_insn "floatdidf2"
17367 + [(set (match_operand:DF 0 "register_operand" "=f")
17368 + (float:DF (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
17369 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17370 + "fcvt.d.l\t%0,%z1"
17371 + [(set_attr "type" "fcvt")
17372 + (set_attr "mode" "DF")
17373 + (set_attr "cnv_mode" "I2D")])
17376 +(define_insn "floatsisf2"
17377 + [(set (match_operand:SF 0 "register_operand" "=f")
17378 + (float:SF (match_operand:SI 1 "reg_or_0_operand" "rJ")))]
17379 + "TARGET_HARD_FLOAT"
17380 + "fcvt.s.w\t%0,%z1"
17381 + [(set_attr "type" "fcvt")
17382 + (set_attr "mode" "SF")
17383 + (set_attr "cnv_mode" "I2S")])
17386 +(define_insn "floatdisf2"
17387 + [(set (match_operand:SF 0 "register_operand" "=f")
17388 + (float:SF (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
17389 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17390 + "fcvt.s.l\t%0,%z1"
17391 + [(set_attr "type" "fcvt")
17392 + (set_attr "mode" "SF")
17393 + (set_attr "cnv_mode" "I2S")])
17396 +(define_insn "floatunssidf2"
17397 + [(set (match_operand:DF 0 "register_operand" "=f")
17398 + (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rJ")))]
17399 + "TARGET_HARD_FLOAT"
17400 + "fcvt.d.wu\t%0,%z1"
17401 + [(set_attr "type" "fcvt")
17402 + (set_attr "mode" "DF")
17403 + (set_attr "cnv_mode" "I2D")])
17406 +(define_insn "floatunsdidf2"
17407 + [(set (match_operand:DF 0 "register_operand" "=f")
17408 + (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
17409 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17410 + "fcvt.d.lu\t%0,%z1"
17411 + [(set_attr "type" "fcvt")
17412 + (set_attr "mode" "DF")
17413 + (set_attr "cnv_mode" "I2D")])
17416 +(define_insn "floatunssisf2"
17417 + [(set (match_operand:SF 0 "register_operand" "=f")
17418 + (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rJ")))]
17419 + "TARGET_HARD_FLOAT"
17420 + "fcvt.s.wu\t%0,%z1"
17421 + [(set_attr "type" "fcvt")
17422 + (set_attr "mode" "SF")
17423 + (set_attr "cnv_mode" "I2S")])
17426 +(define_insn "floatunsdisf2"
17427 + [(set (match_operand:SF 0 "register_operand" "=f")
17428 + (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
17429 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17430 + "fcvt.s.lu\t%0,%z1"
17431 + [(set_attr "type" "fcvt")
17432 + (set_attr "mode" "SF")
17433 + (set_attr "cnv_mode" "I2S")])
17436 +(define_insn "fixuns_truncdfsi2"
17437 + [(set (match_operand:SI 0 "register_operand" "=r")
17438 + (unsigned_fix:SI (match_operand:DF 1 "register_operand" "f")))]
17439 + "TARGET_HARD_FLOAT"
17440 + "fcvt.wu.d %0,%1,rtz"
17441 + [(set_attr "type" "fcvt")
17442 + (set_attr "mode" "DF")
17443 + (set_attr "cnv_mode" "D2I")])
17446 +(define_insn "fixuns_truncsfsi2"
17447 + [(set (match_operand:SI 0 "register_operand" "=r")
17448 + (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
17449 + "TARGET_HARD_FLOAT"
17450 + "fcvt.wu.s %0,%1,rtz"
17451 + [(set_attr "type" "fcvt")
17452 + (set_attr "mode" "SF")
17453 + (set_attr "cnv_mode" "S2I")])
17456 +(define_insn "fixuns_truncdfdi2"
17457 + [(set (match_operand:DI 0 "register_operand" "=r")
17458 + (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f")))]
17459 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17460 + "fcvt.lu.d %0,%1,rtz"
17461 + [(set_attr "type" "fcvt")
17462 + (set_attr "mode" "DF")
17463 + (set_attr "cnv_mode" "D2I")])
17466 +(define_insn "fixuns_truncsfdi2"
17467 + [(set (match_operand:DI 0 "register_operand" "=r")
17468 + (unsigned_fix:DI (match_operand:SF 1 "register_operand" "f")))]
17469 + "TARGET_HARD_FLOAT && TARGET_64BIT"
17470 + "fcvt.lu.s %0,%1,rtz"
17471 + [(set_attr "type" "fcvt")
17472 + (set_attr "mode" "SF")
17473 + (set_attr "cnv_mode" "S2I")])
17476 +;; ....................
17478 +;; DATA MOVEMENT
17480 +;; ....................
17482 +;; Lower-level instructions for loading an address from the GOT.
17483 +;; We could use MEMs, but an unspec gives more optimization
17484 +;; opportunities.
17486 +(define_insn "got_load<mode>"
17487 + [(set (match_operand:P 0 "register_operand" "=r")
17488 + (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
17489 + UNSPEC_LOAD_GOT))]
17490 + "flag_pic"
17491 + "la\t%0,%1"
17492 + [(set_attr "got" "load")
17493 + (set_attr "mode" "<MODE>")])
17495 +(define_insn "tls_add_tp_le<mode>"
17496 + [(set (match_operand:P 0 "register_operand" "=r")
17497 + (unspec:P [(match_operand:P 1 "register_operand" "r")
17498 + (match_operand:P 2 "register_operand" "r")
17499 + (match_operand:P 3 "symbolic_operand" "")]
17500 + UNSPEC_TLS_LE))]
17501 + "!flag_pic || flag_pie"
17502 + "add\t%0,%1,%2,%%tprel_add(%3)"
17503 + [(set_attr "type" "arith")
17504 + (set_attr "mode" "<MODE>")])
17506 +(define_insn "got_load_tls_gd<mode>"
17507 + [(set (match_operand:P 0 "register_operand" "=r")
17508 + (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
17509 + UNSPEC_TLS_GD))]
17510 + "flag_pic"
17511 + "la.tls.gd\t%0,%1"
17512 + [(set_attr "got" "load")
17513 + (set_attr "mode" "<MODE>")])
17515 +(define_insn "got_load_tls_ie<mode>"
17516 + [(set (match_operand:P 0 "register_operand" "=r")
17517 + (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
17518 + UNSPEC_TLS_IE))]
17519 + "flag_pic"
17520 + "la.tls.ie\t%0,%1"
17521 + [(set_attr "got" "load")
17522 + (set_attr "mode" "<MODE>")])
17524 +;; Instructions for adding the low 16 bits of an address to a register.
17525 +;; Operand 2 is the address: riscv_print_operand works out which relocation
17526 +;; should be applied.
17528 +(define_insn "*low<mode>"
17529 + [(set (match_operand:P 0 "register_operand" "=r")
17530 + (lo_sum:P (match_operand:P 1 "register_operand" "r")
17531 + (match_operand:P 2 "immediate_operand" "")))]
17532 + ""
17533 + "add\t%0,%1,%R2"
17534 + [(set_attr "alu_type" "add")
17535 + (set_attr "mode" "<MODE>")])
17537 +;; Allow combine to split complex const_int load sequences, using operand 2
17538 +;; to store the intermediate results. See move_operand for details.
17539 +(define_split
17540 + [(set (match_operand:GPR 0 "register_operand")
17541 + (match_operand:GPR 1 "splittable_const_int_operand"))
17542 + (clobber (match_operand:GPR 2 "register_operand"))]
17543 + ""
17544 + [(const_int 0)]
17546 + riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
17547 + DONE;
17550 +;; Likewise, for symbolic operands.
17551 +(define_split
17552 + [(set (match_operand:P 0 "register_operand")
17553 + (match_operand:P 1))
17554 + (clobber (match_operand:P 2 "register_operand"))]
17555 + "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
17556 + [(set (match_dup 0) (match_dup 3))]
17558 + riscv_split_symbol (operands[2], operands[1],
17559 + MAX_MACHINE_MODE, &operands[3]);
17562 +;; 64-bit integer moves
17564 +;; Unlike most other insns, the move insns can't be split with '
17565 +;; different predicates, because register spilling and other parts of
17566 +;; the compiler, have memoized the insn number already.
17568 +(define_expand "movdi"
17569 + [(set (match_operand:DI 0 "")
17570 + (match_operand:DI 1 ""))]
17571 + ""
17573 + if (riscv_legitimize_move (DImode, operands[0], operands[1]))
17574 + DONE;
17577 +(define_insn "*movdi_32bit"
17578 + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,*r,*m")
17579 + (match_operand:DI 1 "move_operand" "r,i,m,r,*J*r,*m,*f,*f"))]
17580 + "!TARGET_64BIT
17581 + && (register_operand (operands[0], DImode)
17582 + || reg_or_0_operand (operands[1], DImode))"
17583 + { return riscv_output_move (operands[0], operands[1]); }
17584 + [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
17585 + (set_attr "mode" "DI")])
17587 +(define_insn "*movdi_64bit"
17588 + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,*r,*m")
17589 + (match_operand:DI 1 "move_operand" "r,T,m,rJ,*r*J,*m,*f,*f"))]
17590 + "TARGET_64BIT
17591 + && (register_operand (operands[0], DImode)
17592 + || reg_or_0_operand (operands[1], DImode))"
17593 + { return riscv_output_move (operands[0], operands[1]); }
17594 + [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
17595 + (set_attr "mode" "DI")])
17597 +;; 32-bit Integer moves
17599 +;; Unlike most other insns, the move insns can't be split with
17600 +;; different predicates, because register spilling and other parts of
17601 +;; the compiler, have memoized the insn number already.
17603 +(define_expand "mov<mode>"
17604 + [(set (match_operand:IMOVE32 0 "")
17605 + (match_operand:IMOVE32 1 ""))]
17606 + ""
17608 + if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
17609 + DONE;
17612 +;; The difference between these two is whether or not ints are allowed
17613 +;; in FP registers (off by default, use -mdebugh to enable).
17615 +(define_insn "*mov<mode>_internal"
17616 + [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,*r,*m")
17617 + (match_operand:IMOVE32 1 "move_operand" "r,T,m,rJ,*r*J,*m,*f,*f"))]
17618 + "(register_operand (operands[0], <MODE>mode)
17619 + || reg_or_0_operand (operands[1], <MODE>mode))"
17620 + { return riscv_output_move (operands[0], operands[1]); }
17621 + [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
17622 + (set_attr "mode" "SI")])
17624 +;; 16-bit Integer moves
17626 +;; Unlike most other insns, the move insns can't be split with
17627 +;; different predicates, because register spilling and other parts of
17628 +;; the compiler, have memoized the insn number already.
17629 +;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
17631 +(define_expand "movhi"
17632 + [(set (match_operand:HI 0 "")
17633 + (match_operand:HI 1 ""))]
17634 + ""
17636 + if (riscv_legitimize_move (HImode, operands[0], operands[1]))
17637 + DONE;
17640 +(define_insn "*movhi_internal"
17641 + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r")
17642 + (match_operand:HI 1 "move_operand" "r,T,m,rJ,*r*J,*f"))]
17643 + "(register_operand (operands[0], HImode)
17644 + || reg_or_0_operand (operands[1], HImode))"
17645 + { return riscv_output_move (operands[0], operands[1]); }
17646 + [(set_attr "move_type" "move,const,load,store,mtc,mfc")
17647 + (set_attr "mode" "HI")])
17649 +;; HImode constant generation; see riscv_move_integer for details.
17650 +;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION.
17652 +(define_insn "add<mode>hi3"
17653 + [(set (match_operand:HI 0 "register_operand" "=r,r")
17654 + (plus:HI (match_operand:HISI 1 "register_operand" "r,r")
17655 + (match_operand:HISI 2 "arith_operand" "r,Q")))]
17656 + ""
17657 + { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
17658 + [(set_attr "type" "arith")
17659 + (set_attr "mode" "HI")])
17661 +(define_insn "xor<mode>hi3"
17662 + [(set (match_operand:HI 0 "register_operand" "=r,r")
17663 + (xor:HI (match_operand:HISI 1 "register_operand" "r,r")
17664 + (match_operand:HISI 2 "arith_operand" "r,Q")))]
17665 + ""
17666 + "xor\t%0,%1,%2"
17667 + [(set_attr "type" "logical")
17668 + (set_attr "mode" "HI")])
17670 +;; 8-bit Integer moves
17672 +(define_expand "movqi"
17673 + [(set (match_operand:QI 0 "")
17674 + (match_operand:QI 1 ""))]
17675 + ""
17677 + if (riscv_legitimize_move (QImode, operands[0], operands[1]))
17678 + DONE;
17681 +(define_insn "*movqi_internal"
17682 + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r")
17683 + (match_operand:QI 1 "move_operand" "r,I,m,rJ,*r*J,*f"))]
17684 + "(register_operand (operands[0], QImode)
17685 + || reg_or_0_operand (operands[1], QImode))"
17686 + { return riscv_output_move (operands[0], operands[1]); }
17687 + [(set_attr "move_type" "move,const,load,store,mtc,mfc")
17688 + (set_attr "mode" "QI")])
17690 +;; 32-bit floating point moves
17692 +(define_expand "movsf"
17693 + [(set (match_operand:SF 0 "")
17694 + (match_operand:SF 1 ""))]
17695 + ""
17697 + if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
17698 + DONE;
17701 +(define_insn "*movsf_hardfloat"
17702 + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m")
17703 + (match_operand:SF 1 "move_operand" "f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
17704 + "TARGET_HARD_FLOAT
17705 + && (register_operand (operands[0], SFmode)
17706 + || reg_or_0_operand (operands[1], SFmode))"
17707 + { return riscv_output_move (operands[0], operands[1]); }
17708 + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
17709 + (set_attr "mode" "SF")])
17711 +(define_insn "*movsf_softfloat"
17712 + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
17713 + (match_operand:SF 1 "move_operand" "Gr,m,r"))]
17714 + "TARGET_SOFT_FLOAT
17715 + && (register_operand (operands[0], SFmode)
17716 + || reg_or_0_operand (operands[1], SFmode))"
17717 + { return riscv_output_move (operands[0], operands[1]); }
17718 + [(set_attr "move_type" "move,load,store")
17719 + (set_attr "mode" "SF")])
17721 +;; 64-bit floating point moves
17723 +(define_expand "movdf"
17724 + [(set (match_operand:DF 0 "")
17725 + (match_operand:DF 1 ""))]
17726 + ""
17728 + if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
17729 + DONE;
17732 +;; In RV32, we lack mtf.d/mff.d. Go through memory instead.
17733 +;; (except for moving a constant 0 to an FPR. for that we use fcvt.d.w.)
17734 +(define_insn "*movdf_hardfloat_rv32"
17735 + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*r,*r,*m")
17736 + (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r*G,*m,*r"))]
17737 + "!TARGET_64BIT && TARGET_HARD_FLOAT
17738 + && (register_operand (operands[0], DFmode)
17739 + || reg_or_0_operand (operands[1], DFmode))"
17740 + { return riscv_output_move (operands[0], operands[1]); }
17741 + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
17742 + (set_attr "mode" "DF")])
17744 +(define_insn "*movdf_hardfloat_rv64"
17745 + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m")
17746 + (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
17747 + "TARGET_64BIT && TARGET_HARD_FLOAT
17748 + && (register_operand (operands[0], DFmode)
17749 + || reg_or_0_operand (operands[1], DFmode))"
17750 + { return riscv_output_move (operands[0], operands[1]); }
17751 + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
17752 + (set_attr "mode" "DF")])
17754 +(define_insn "*movdf_softfloat"
17755 + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
17756 + (match_operand:DF 1 "move_operand" "rG,m,rG"))]
17757 + "TARGET_SOFT_FLOAT
17758 + && (register_operand (operands[0], DFmode)
17759 + || reg_or_0_operand (operands[1], DFmode))"
17760 + { return riscv_output_move (operands[0], operands[1]); }
17761 + [(set_attr "move_type" "move,load,store")
17762 + (set_attr "mode" "DF")])
17764 +;; 128-bit integer moves
17766 +(define_expand "movti"
17767 + [(set (match_operand:TI 0)
17768 + (match_operand:TI 1))]
17769 + "TARGET_64BIT"
17771 + if (riscv_legitimize_move (TImode, operands[0], operands[1]))
17772 + DONE;
17775 +(define_insn "*movti"
17776 + [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,r,m")
17777 + (match_operand:TI 1 "move_operand" "r,i,m,rJ"))]
17778 + "TARGET_64BIT
17779 + && (register_operand (operands[0], TImode)
17780 + || reg_or_0_operand (operands[1], TImode))"
17781 + "#"
17782 + [(set_attr "move_type" "move,const,load,store")
17783 + (set_attr "mode" "TI")])
17785 +(define_split
17786 + [(set (match_operand:MOVE64 0 "nonimmediate_operand")
17787 + (match_operand:MOVE64 1 "move_operand"))]
17788 + "reload_completed && !TARGET_64BIT
17789 + && riscv_split_64bit_move_p (operands[0], operands[1])"
17790 + [(const_int 0)]
17792 + riscv_split_doubleword_move (operands[0], operands[1]);
17793 + DONE;
17796 +(define_split
17797 + [(set (match_operand:MOVE128 0 "nonimmediate_operand")
17798 + (match_operand:MOVE128 1 "move_operand"))]
17799 + "TARGET_64BIT && reload_completed"
17800 + [(const_int 0)]
17802 + riscv_split_doubleword_move (operands[0], operands[1]);
17803 + DONE;
17806 +;; 64-bit paired-single floating point moves
17808 +;; Load the low word of operand 0 with operand 1.
17809 +(define_insn "load_low<mode>"
17810 + [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
17811 + (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "rJ,m")]
17812 + UNSPEC_LOAD_LOW))]
17813 + "TARGET_HARD_FLOAT"
17815 + operands[0] = riscv_subword (operands[0], 0);
17816 + return riscv_output_move (operands[0], operands[1]);
17818 + [(set_attr "move_type" "mtc,fpload")
17819 + (set_attr "mode" "<HALFMODE>")])
17821 +;; Load the high word of operand 0 from operand 1, preserving the value
17822 +;; in the low word.
17823 +(define_insn "load_high<mode>"
17824 + [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
17825 + (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "rJ,m")
17826 + (match_operand:SPLITF 2 "register_operand" "0,0")]
17827 + UNSPEC_LOAD_HIGH))]
17828 + "TARGET_HARD_FLOAT"
17830 + operands[0] = riscv_subword (operands[0], 1);
17831 + return riscv_output_move (operands[0], operands[1]);
17833 + [(set_attr "move_type" "mtc,fpload")
17834 + (set_attr "mode" "<HALFMODE>")])
17836 +;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
17837 +;; high word and 0 to store the low word.
17838 +(define_insn "store_word<mode>"
17839 + [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=r,m")
17840 + (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
17841 + (match_operand 2 "const_int_operand")]
17842 + UNSPEC_STORE_WORD))]
17843 + "TARGET_HARD_FLOAT"
17845 + operands[1] = riscv_subword (operands[1], INTVAL (operands[2]));
17846 + return riscv_output_move (operands[0], operands[1]);
17848 + [(set_attr "move_type" "mfc,fpstore")
17849 + (set_attr "mode" "<HALFMODE>")])
17851 +;; Expand in-line code to clear the instruction cache between operand[0] and
17852 +;; operand[1].
17853 +(define_expand "clear_cache"
17854 + [(match_operand 0 "pmode_register_operand")
17855 + (match_operand 1 "pmode_register_operand")]
17856 + ""
17859 + emit_insn(gen_fence_i());
17860 + DONE;
17861 +}")
17863 +(define_insn "fence"
17864 + [(unspec_volatile [(const_int 0)] UNSPEC_FENCE)]
17865 + ""
17866 + "%|fence%-")
17868 +(define_insn "fence_i"
17869 + [(unspec_volatile [(const_int 0)] UNSPEC_FENCE_I)]
17870 + ""
17871 + "fence.i")
17873 +;; Block moves, see riscv.c for more details.
17874 +;; Argument 0 is the destination
17875 +;; Argument 1 is the source
17876 +;; Argument 2 is the length
17877 +;; Argument 3 is the alignment
17879 +(define_expand "movmemsi"
17880 + [(parallel [(set (match_operand:BLK 0 "general_operand")
17881 + (match_operand:BLK 1 "general_operand"))
17882 + (use (match_operand:SI 2 ""))
17883 + (use (match_operand:SI 3 "const_int_operand"))])]
17884 + "!TARGET_MEMCPY"
17886 + if (riscv_expand_block_move (operands[0], operands[1], operands[2]))
17887 + DONE;
17888 + else
17889 + FAIL;
17893 +;; ....................
17895 +;; SHIFTS
17897 +;; ....................
17899 +(define_insn "<optab>si3"
17900 + [(set (match_operand:SI 0 "register_operand" "=r")
17901 + (any_shift:SI (match_operand:SI 1 "register_operand" "r")
17902 + (match_operand:SI 2 "arith_operand" "rI")))]
17903 + ""
17905 + if (GET_CODE (operands[2]) == CONST_INT)
17906 + operands[2] = GEN_INT (INTVAL (operands[2])
17907 + & (GET_MODE_BITSIZE (SImode) - 1));
17909 + return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2";
17911 + [(set_attr "type" "shift")
17912 + (set_attr "mode" "SI")])
17914 +(define_insn "*<optab>disi3"
17915 + [(set (match_operand:SI 0 "register_operand" "=r")
17916 + (any_shift:SI (truncate:SI (match_operand:DI 1 "register_operand" "r"))
17917 + (truncate:SI (match_operand:DI 2 "arith_operand" "rI"))))]
17918 + "TARGET_64BIT"
17919 + "<insn>w\t%0,%1,%2"
17920 + [(set_attr "type" "shift")
17921 + (set_attr "mode" "SI")])
17923 +(define_insn "*ashldi3_truncsi"
17924 + [(set (match_operand:SI 0 "register_operand" "=r")
17925 + (truncate:SI
17926 + (ashift:DI (match_operand:DI 1 "register_operand" "r")
17927 + (match_operand:DI 2 "const_arith_operand" "I"))))]
17928 + "TARGET_64BIT && INTVAL (operands[2]) < 32"
17929 + "sllw\t%0,%1,%2"
17930 + [(set_attr "type" "shift")
17931 + (set_attr "mode" "SI")])
17933 +(define_insn "*ashldisi3"
17934 + [(set (match_operand:SI 0 "register_operand" "=r")
17935 + (ashift:SI (match_operand:GPR 1 "register_operand" "r")
17936 + (match_operand:GPR2 2 "arith_operand" "rI")))]
17937 + "TARGET_64BIT && (GET_CODE (operands[2]) == CONST_INT ? INTVAL (operands[2]) < 32 : 1)"
17938 + "sllw\t%0,%1,%2"
17939 + [(set_attr "type" "shift")
17940 + (set_attr "mode" "SI")])
17942 +(define_insn "<optab>di3"
17943 + [(set (match_operand:DI 0 "register_operand" "=r")
17944 + (any_shift:DI (match_operand:DI 1 "register_operand" "r")
17945 + (match_operand:DI 2 "arith_operand" "rI")))]
17946 + "TARGET_64BIT"
17948 + if (GET_CODE (operands[2]) == CONST_INT)
17949 + operands[2] = GEN_INT (INTVAL (operands[2])
17950 + & (GET_MODE_BITSIZE (DImode) - 1));
17952 + return "<insn>\t%0,%1,%2";
17954 + [(set_attr "type" "shift")
17955 + (set_attr "mode" "DI")])
17957 +(define_insn "<optab>si3_extend"
17958 + [(set (match_operand:DI 0 "register_operand" "=r")
17959 + (sign_extend:DI
17960 + (any_shift:SI (match_operand:SI 1 "register_operand" "r")
17961 + (match_operand:SI 2 "arith_operand" "rI"))))]
17962 + "TARGET_64BIT"
17964 + if (GET_CODE (operands[2]) == CONST_INT)
17965 + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
17967 + return "<insn>w\t%0,%1,%2";
17969 + [(set_attr "type" "shift")
17970 + (set_attr "mode" "SI")])
17973 +;; ....................
17975 +;; CONDITIONAL BRANCHES
17977 +;; ....................
17979 +;; Conditional branches
17981 +(define_insn "*branch_order<mode>"
17982 + [(set (pc)
17983 + (if_then_else
17984 + (match_operator 1 "order_operator"
17985 + [(match_operand:GPR 2 "register_operand" "r")
17986 + (match_operand:GPR 3 "reg_or_0_operand" "rJ")])
17987 + (label_ref (match_operand 0 "" ""))
17988 + (pc)))]
17989 + ""
17991 + if (GET_CODE (operands[3]) == CONST_INT)
17992 + return "b%C1z\t%2,%0";
17993 + return "b%C1\t%2,%3,%0";
17995 + [(set_attr "type" "branch")
17996 + (set_attr "mode" "none")])
17998 +;; Used to implement built-in functions.
17999 +(define_expand "condjump"
18000 + [(set (pc)
18001 + (if_then_else (match_operand 0)
18002 + (label_ref (match_operand 1))
18003 + (pc)))])
18005 +(define_expand "cbranch<mode>4"
18006 + [(set (pc)
18007 + (if_then_else (match_operator 0 "comparison_operator"
18008 + [(match_operand:GPR 1 "register_operand")
18009 + (match_operand:GPR 2 "nonmemory_operand")])
18010 + (label_ref (match_operand 3 ""))
18011 + (pc)))]
18012 + ""
18014 + riscv_expand_conditional_branch (operands);
18015 + DONE;
18018 +(define_expand "cbranch<mode>4"
18019 + [(set (pc)
18020 + (if_then_else (match_operator 0 "comparison_operator"
18021 + [(match_operand:SCALARF 1 "register_operand")
18022 + (match_operand:SCALARF 2 "register_operand")])
18023 + (label_ref (match_operand 3 ""))
18024 + (pc)))]
18025 + ""
18027 + riscv_expand_conditional_branch (operands);
18028 + DONE;
18031 +(define_insn_and_split "*branch_on_bit<GPR:mode>"
18032 + [(set (pc)
18033 + (if_then_else
18034 + (match_operator 0 "equality_operator"
18035 + [(zero_extract:GPR (match_operand:GPR 2 "register_operand" "r")
18036 + (const_int 1)
18037 + (match_operand 3 "const_int_operand"))
18038 + (const_int 0)])
18039 + (label_ref (match_operand 1))
18040 + (pc)))
18041 + (clobber (match_scratch:GPR 4 "=&r"))]
18042 + ""
18043 + "#"
18044 + "reload_completed"
18045 + [(set (match_dup 4)
18046 + (ashift:GPR (match_dup 2) (match_dup 3)))
18047 + (set (pc)
18048 + (if_then_else
18049 + (match_op_dup 0 [(match_dup 4) (const_int 0)])
18050 + (label_ref (match_operand 1))
18051 + (pc)))]
18053 + int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
18054 + operands[3] = GEN_INT (shift);
18056 + if (GET_CODE (operands[0]) == EQ)
18057 + operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
18058 + else
18059 + operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
18062 +(define_insn_and_split "*branch_on_bit_range<GPR:mode>"
18063 + [(set (pc)
18064 + (if_then_else
18065 + (match_operator 0 "equality_operator"
18066 + [(zero_extract:GPR (match_operand:GPR 2 "register_operand" "r")
18067 + (match_operand 3 "const_int_operand")
18068 + (const_int 0))
18069 + (const_int 0)])
18070 + (label_ref (match_operand 1))
18071 + (pc)))
18072 + (clobber (match_scratch:GPR 4 "=&r"))]
18073 + ""
18074 + "#"
18075 + "reload_completed"
18076 + [(set (match_dup 4)
18077 + (ashift:GPR (match_dup 2) (match_dup 3)))
18078 + (set (pc)
18079 + (if_then_else
18080 + (match_op_dup 0 [(match_dup 4) (const_int 0)])
18081 + (label_ref (match_operand 1))
18082 + (pc)))]
18084 + operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
18088 +;; ....................
18090 +;; SETTING A REGISTER FROM A COMPARISON
18092 +;; ....................
18094 +;; Destination is always set in SI mode.
18096 +(define_expand "cstore<mode>4"
18097 + [(set (match_operand:SI 0 "register_operand")
18098 + (match_operator:SI 1 "order_operator"
18099 + [(match_operand:GPR 2 "register_operand")
18100 + (match_operand:GPR 3 "nonmemory_operand")]))]
18101 + ""
18103 + riscv_expand_scc (operands);
18104 + DONE;
18107 +(define_insn "cstore<mode>4"
18108 + [(set (match_operand:SI 0 "register_operand" "=r")
18109 + (match_operator:SI 1 "fp_order_operator"
18110 + [(match_operand:SCALARF 2 "register_operand" "f")
18111 + (match_operand:SCALARF 3 "register_operand" "f")]))]
18112 + "TARGET_HARD_FLOAT"
18113 + "f%C1.<fmt>\t%0,%2,%3"
18114 + [(set_attr "type" "fcmp")
18115 + (set_attr "mode" "<UNITMODE>")])
18117 +(define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
18118 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18119 + (eq:GPR2 (match_operand:GPR 1 "register_operand" "r")
18120 + (const_int 0)))]
18121 + ""
18122 + "seqz\t%0,%1"
18123 + [(set_attr "type" "slt")
18124 + (set_attr "mode" "<GPR:MODE>")])
18126 +(define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
18127 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18128 + (ne:GPR2 (match_operand:GPR 1 "register_operand" "r")
18129 + (const_int 0)))]
18130 + ""
18131 + "snez\t%0,%1"
18132 + [(set_attr "type" "slt")
18133 + (set_attr "mode" "<GPR:MODE>")])
18135 +(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
18136 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18137 + (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "r")
18138 + (match_operand:GPR 2 "reg_or_0_operand" "rJ")))]
18139 + ""
18140 + "slt<u>\t%0,%z2,%1"
18141 + [(set_attr "type" "slt")
18142 + (set_attr "mode" "<GPR:MODE>")])
18144 +(define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
18145 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18146 + (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "r")
18147 + (const_int 1)))]
18148 + ""
18149 + "slt<u>\t%0,zero,%1"
18150 + [(set_attr "type" "slt")
18151 + (set_attr "mode" "<GPR:MODE>")])
18153 +(define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
18154 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18155 + (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "r")
18156 + (match_operand:GPR 2 "arith_operand" "rI")))]
18157 + ""
18158 + "slt<u>\t%0,%1,%2"
18159 + [(set_attr "type" "slt")
18160 + (set_attr "mode" "<GPR:MODE>")])
18162 +(define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
18163 + [(set (match_operand:GPR2 0 "register_operand" "=r")
18164 + (any_le:GPR2 (match_operand:GPR 1 "register_operand" "r")
18165 + (match_operand:GPR 2 "sle_operand" "")))]
18166 + ""
18168 + operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
18169 + return "slt<u>\t%0,%1,%2";
18171 + [(set_attr "type" "slt")
18172 + (set_attr "mode" "<GPR:MODE>")])
18175 +;; ....................
18177 +;; UNCONDITIONAL BRANCHES
18179 +;; ....................
18181 +;; Unconditional branches.
18183 +(define_insn "jump"
18184 + [(set (pc)
18185 + (label_ref (match_operand 0 "" "")))]
18186 + ""
18187 + "j\t%l0"
18188 + [(set_attr "type" "jump")
18189 + (set_attr "mode" "none")])
18191 +(define_expand "indirect_jump"
18192 + [(set (pc) (match_operand 0 "register_operand"))]
18193 + ""
18195 + operands[0] = force_reg (Pmode, operands[0]);
18196 + if (Pmode == SImode)
18197 + emit_jump_insn (gen_indirect_jumpsi (operands[0]));
18198 + else
18199 + emit_jump_insn (gen_indirect_jumpdi (operands[0]));
18200 + DONE;
18203 +(define_insn "indirect_jump<mode>"
18204 + [(set (pc) (match_operand:P 0 "register_operand" "r"))]
18205 + ""
18206 + "jr\t%0"
18207 + [(set_attr "type" "jump")
18208 + (set_attr "mode" "none")])
18210 +(define_expand "tablejump"
18211 + [(set (pc) (match_operand 0 "register_operand" ""))
18212 + (use (label_ref (match_operand 1 "" "")))]
18213 + ""
18215 + if (CASE_VECTOR_PC_RELATIVE)
18216 + operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
18217 + gen_rtx_LABEL_REF (Pmode, operands[1]),
18218 + NULL_RTX, 0, OPTAB_DIRECT);
18220 + if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
18221 + emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
18222 + else
18223 + emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
18224 + DONE;
18227 +(define_insn "tablejump<mode>"
18228 + [(set (pc) (match_operand:GPR 0 "register_operand" "r"))
18229 + (use (label_ref (match_operand 1 "" "")))]
18230 + ""
18231 + "jr\t%0"
18232 + [(set_attr "type" "jump")
18233 + (set_attr "mode" "none")])
18236 +;; ....................
18238 +;; Function prologue/epilogue
18240 +;; ....................
18243 +(define_expand "prologue"
18244 + [(const_int 1)]
18245 + ""
18247 + riscv_expand_prologue ();
18248 + DONE;
18251 +;; Block any insns from being moved before this point, since the
18252 +;; profiling call to mcount can use various registers that aren't
18253 +;; saved or used to pass arguments.
18255 +(define_insn "blockage"
18256 + [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
18257 + ""
18258 + ""
18259 + [(set_attr "type" "ghost")
18260 + (set_attr "mode" "none")])
18262 +(define_expand "epilogue"
18263 + [(const_int 2)]
18264 + ""
18266 + riscv_expand_epilogue (false);
18267 + DONE;
18270 +(define_expand "sibcall_epilogue"
18271 + [(const_int 2)]
18272 + ""
18274 + riscv_expand_epilogue (true);
18275 + DONE;
18278 +;; Trivial return. Make it look like a normal return insn as that
18279 +;; allows jump optimizations to work better.
18281 +(define_expand "return"
18282 + [(simple_return)]
18283 + "riscv_can_use_return_insn ()"
18284 + "")
18286 +(define_insn "simple_return"
18287 + [(simple_return)]
18288 + ""
18289 + "ret"
18290 + [(set_attr "type" "jump")
18291 + (set_attr "mode" "none")])
18293 +;; Normal return.
18295 +(define_insn "simple_return_internal"
18296 + [(simple_return)
18297 + (use (match_operand 0 "pmode_register_operand" ""))]
18298 + ""
18299 + "jr\t%0"
18300 + [(set_attr "type" "jump")
18301 + (set_attr "mode" "none")])
18303 +;; This is used in compiling the unwind routines.
18304 +(define_expand "eh_return"
18305 + [(use (match_operand 0 "general_operand"))]
18306 + ""
18308 + if (GET_MODE (operands[0]) != word_mode)
18309 + operands[0] = convert_to_mode (word_mode, operands[0], 0);
18310 + if (TARGET_64BIT)
18311 + emit_insn (gen_eh_set_lr_di (operands[0]));
18312 + else
18313 + emit_insn (gen_eh_set_lr_si (operands[0]));
18314 + DONE;
18317 +;; Clobber the return address on the stack. We can't expand this
18318 +;; until we know where it will be put in the stack frame.
18320 +(define_insn "eh_set_lr_si"
18321 + [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
18322 + (clobber (match_scratch:SI 1 "=&r"))]
18323 + "! TARGET_64BIT"
18324 + "#")
18326 +(define_insn "eh_set_lr_di"
18327 + [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
18328 + (clobber (match_scratch:DI 1 "=&r"))]
18329 + "TARGET_64BIT"
18330 + "#")
18332 +(define_split
18333 + [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
18334 + (clobber (match_scratch 1))]
18335 + "reload_completed"
18336 + [(const_int 0)]
18338 + riscv_set_return_address (operands[0], operands[1]);
18339 + DONE;
18343 +;; ....................
18345 +;; FUNCTION CALLS
18347 +;; ....................
18349 +;; Sibling calls. All these patterns use jump instructions.
18351 +;; call_insn_operand will only accept constant
18352 +;; addresses if a direct jump is acceptable. Since the 'S' constraint
18353 +;; is defined in terms of call_insn_operand, the same is true of the
18354 +;; constraints.
18356 +;; When we use an indirect jump, we need a register that will be
18357 +;; preserved by the epilogue (constraint j).
18359 +(define_expand "sibcall"
18360 + [(parallel [(call (match_operand 0 "")
18361 + (match_operand 1 ""))
18362 + (use (match_operand 2 "")) ;; next_arg_reg
18363 + (use (match_operand 3 ""))])] ;; struct_value_size_rtx
18364 + ""
18366 + riscv_expand_call (true, NULL_RTX, XEXP (operands[0], 0), operands[1]);
18367 + DONE;
18370 +(define_insn "sibcall_internal"
18371 + [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
18372 + (match_operand 1 "" ""))]
18373 + "SIBLING_CALL_P (insn)"
18374 + { return REG_P (operands[0]) ? "jr\t%0"
18375 + : absolute_symbolic_operand (operands[0], VOIDmode) ? "tail\t%0"
18376 + : "tail\t%0@"; }
18377 + [(set_attr "type" "call")])
18379 +(define_expand "sibcall_value"
18380 + [(parallel [(set (match_operand 0 "")
18381 + (call (match_operand 1 "")
18382 + (match_operand 2 "")))
18383 + (use (match_operand 3 ""))])] ;; next_arg_reg
18384 + ""
18386 + riscv_expand_call (true, operands[0], XEXP (operands[1], 0), operands[2]);
18387 + DONE;
18390 +(define_insn "sibcall_value_internal"
18391 + [(set (match_operand 0 "register_operand" "")
18392 + (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
18393 + (match_operand 2 "" "")))]
18394 + "SIBLING_CALL_P (insn)"
18395 + { return REG_P (operands[1]) ? "jr\t%1"
18396 + : absolute_symbolic_operand (operands[1], VOIDmode) ? "tail\t%1"
18397 + : "tail\t%1@"; }
18398 + [(set_attr "type" "call")])
18400 +(define_insn "sibcall_value_multiple_internal"
18401 + [(set (match_operand 0 "register_operand" "")
18402 + (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
18403 + (match_operand 2 "" "")))
18404 + (set (match_operand 3 "register_operand" "")
18405 + (call (mem:SI (match_dup 1))
18406 + (match_dup 2)))
18407 + (clobber (match_scratch:SI 4 "=j,j"))]
18408 + "SIBLING_CALL_P (insn)"
18409 + { return REG_P (operands[1]) ? "jr\t%1"
18410 + : absolute_symbolic_operand (operands[1], VOIDmode) ? "tail\t%1"
18411 + : "tail\t%1@"; }
18412 + [(set_attr "type" "call")])
18414 +(define_expand "call"
18415 + [(parallel [(call (match_operand 0 "")
18416 + (match_operand 1 ""))
18417 + (use (match_operand 2 "")) ;; next_arg_reg
18418 + (use (match_operand 3 ""))])] ;; struct_value_size_rtx
18419 + ""
18421 + riscv_expand_call (false, NULL_RTX, XEXP (operands[0], 0), operands[1]);
18422 + DONE;
18425 +(define_insn "call_internal"
18426 + [(call (mem:SI (match_operand 0 "call_insn_operand" "r,S"))
18427 + (match_operand 1 "" ""))
18428 + (clobber (reg:SI RETURN_ADDR_REGNUM))]
18429 + ""
18430 + { return REG_P (operands[0]) ? "jalr\t%0"
18431 + : absolute_symbolic_operand (operands[0], VOIDmode) ? "call\t%0"
18432 + : "call\t%0@"; }
18433 + [(set_attr "jal" "indirect,direct")])
18435 +(define_expand "call_value"
18436 + [(parallel [(set (match_operand 0 "")
18437 + (call (match_operand 1 "")
18438 + (match_operand 2 "")))
18439 + (use (match_operand 3 ""))])] ;; next_arg_reg
18440 + ""
18442 + riscv_expand_call (false, operands[0], XEXP (operands[1], 0), operands[2]);
18443 + DONE;
18446 +;; See comment for call_internal.
18447 +(define_insn "call_value_internal"
18448 + [(set (match_operand 0 "register_operand" "")
18449 + (call (mem:SI (match_operand 1 "call_insn_operand" "r,S"))
18450 + (match_operand 2 "" "")))
18451 + (clobber (reg:SI RETURN_ADDR_REGNUM))]
18452 + ""
18453 + { return REG_P (operands[1]) ? "jalr\t%1"
18454 + : absolute_symbolic_operand (operands[1], VOIDmode) ? "call\t%1"
18455 + : "call\t%1@"; }
18456 + [(set_attr "jal" "indirect,direct")])
18458 +;; See comment for call_internal.
18459 +(define_insn "call_value_multiple_internal"
18460 + [(set (match_operand 0 "register_operand" "")
18461 + (call (mem:SI (match_operand 1 "call_insn_operand" "r,S"))
18462 + (match_operand 2 "" "")))
18463 + (set (match_operand 3 "register_operand" "")
18464 + (call (mem:SI (match_dup 1))
18465 + (match_dup 2)))
18466 + (clobber (reg:SI RETURN_ADDR_REGNUM))]
18467 + ""
18468 + { return REG_P (operands[1]) ? "jalr\t%1"
18469 + : absolute_symbolic_operand (operands[1], VOIDmode) ? "call\t%1"
18470 + : "call\t%1@"; }
18471 + [(set_attr "jal" "indirect,direct")])
18473 +;; Call subroutine returning any type.
18475 +(define_expand "untyped_call"
18476 + [(parallel [(call (match_operand 0 "")
18477 + (const_int 0))
18478 + (match_operand 1 "")
18479 + (match_operand 2 "")])]
18480 + ""
18482 + int i;
18484 + emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
18486 + for (i = 0; i < XVECLEN (operands[2], 0); i++)
18488 + rtx set = XVECEXP (operands[2], 0, i);
18489 + riscv_emit_move (SET_DEST (set), SET_SRC (set));
18492 + emit_insn (gen_blockage ());
18493 + DONE;
18496 +(define_insn "nop"
18497 + [(const_int 0)]
18498 + ""
18499 + "nop"
18500 + [(set_attr "type" "nop")
18501 + (set_attr "mode" "none")])
18503 +(define_insn "trap"
18504 + [(trap_if (const_int 1) (const_int 0))]
18505 + ""
18506 + "sbreak")
18508 +(include "sync.md")
18509 +(include "peephole.md")
18510 diff -rNU3 dist.orig/gcc/config/riscv/riscv.opt dist/gcc/config/riscv/riscv.opt
18511 --- dist.orig/gcc/config/riscv/riscv.opt 1970-01-01 01:00:00.000000000 +0100
18512 +++ dist/gcc/config/riscv/riscv.opt 2015-10-18 13:19:50.000000000 +0200
18513 @@ -0,0 +1,79 @@
18514 +; Options for the MIPS port of the compiler
18516 +; Copyright (C) 2005, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
18518 +; This file is part of GCC.
18520 +; GCC is free software; you can redistribute it and/or modify it under
18521 +; the terms of the GNU General Public License as published by the Free
18522 +; Software Foundation; either version 3, or (at your option) any later
18523 +; version.
18525 +; GCC is distributed in the hope that it will be useful, but WITHOUT
18526 +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18527 +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18528 +; License for more details.
18530 +; You should have received a copy of the GNU General Public License
18531 +; along with GCC; see the file COPYING3. If not see
18532 +; <http://www.gnu.org/licenses/>.
18534 +m32
18535 +Target RejectNegative Mask(32BIT)
18536 +Generate RV32 code
18538 +m64
18539 +Target RejectNegative InverseMask(32BIT, 64BIT)
18540 +Generate RV64 code
18542 +mbranch-cost=
18543 +Target RejectNegative Joined UInteger Var(riscv_branch_cost)
18544 +-mbranch-cost=COST Set the cost of branches to roughly COST instructions
18546 +mhard-float
18547 +Target Report RejectNegative InverseMask(SOFT_FLOAT_ABI, HARD_FLOAT_ABI)
18548 +Allow the use of hardware floating-point ABI and instructions
18550 +mmemcpy
18551 +Target Report Mask(MEMCPY)
18552 +Don't optimize block moves
18554 +mplt
18555 +Target Report Var(TARGET_PLT) Init(1)
18556 +When generating -fpic code, allow the use of PLTs. Ignored for fno-pic.
18558 +msoft-float
18559 +Target Report RejectNegative Mask(SOFT_FLOAT_ABI)
18560 +Prevent the use of all hardware floating-point instructions
18562 +mfdiv
18563 +Target Report RejectNegative Mask(FDIV)
18564 +Use hardware floating-point divide and square root instructions
18566 +march=
18567 +Target RejectNegative Joined Var(riscv_arch_string)
18568 +-march= Generate code for given RISC-V ISA (e.g. RV64IM)
18570 +mtune=
18571 +Target RejectNegative Joined Var(riscv_tune_string)
18572 +-mtune=PROCESSOR Optimize the output for PROCESSOR
18574 +msmall-data-limit=
18575 +Target Joined Separate UInteger Var(g_switch_value) Init(8)
18576 +-msmall-data-limit=<number> Put global and static data smaller than <number> bytes into a special section (on some targets)
18578 +matomic
18579 +Target Report Mask(ATOMIC)
18580 +Use hardware atomic memory instructions.
18582 +mmuldiv
18583 +Target Report Mask(MULDIV)
18584 +Use hardware instructions for integer multiplication and division.
18586 +mlra
18587 +Target Report Var(riscv_lra_flag) Init(0) Save
18588 +Use LRA instead of reload
18590 +mcmodel=
18591 +Target RejectNegative Joined Var(riscv_cmodel_string)
18592 +Use given RISC-V code model (medlow or medany)
18593 diff -rNU3 dist.orig/gcc/config/riscv/sync.md dist/gcc/config/riscv/sync.md
18594 --- dist.orig/gcc/config/riscv/sync.md 1970-01-01 01:00:00.000000000 +0100
18595 +++ dist/gcc/config/riscv/sync.md 2015-10-18 13:19:50.000000000 +0200
18596 @@ -0,0 +1,198 @@
18597 +;; Machine description for RISC-V atomic operations.
18598 +;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
18599 +;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
18600 +;; Based on MIPS target for GNU compiler.
18602 +;; This file is part of GCC.
18604 +;; GCC is free software; you can redistribute it and/or modify
18605 +;; it under the terms of the GNU General Public License as published by
18606 +;; the Free Software Foundation; either version 3, or (at your option)
18607 +;; any later version.
18609 +;; GCC is distributed in the hope that it will be useful,
18610 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18611 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18612 +;; GNU General Public License for more details.
18614 +;; You should have received a copy of the GNU General Public License
18615 +;; along with GCC; see the file COPYING3. If not see
18616 +;; <http://www.gnu.org/licenses/>.
18618 +(define_c_enum "unspec" [
18619 + UNSPEC_COMPARE_AND_SWAP
18620 + UNSPEC_SYNC_OLD_OP
18621 + UNSPEC_SYNC_EXCHANGE
18622 + UNSPEC_ATOMIC_STORE
18623 + UNSPEC_MEMORY_BARRIER
18626 +(define_code_iterator any_atomic [plus ior xor and])
18627 +(define_code_attr atomic_optab
18628 + [(plus "add") (ior "or") (xor "xor") (and "and")])
18630 +;; Memory barriers.
18632 +(define_expand "mem_thread_fence"
18633 + [(match_operand:SI 0 "const_int_operand" "")] ;; model
18634 + ""
18636 + if (INTVAL (operands[0]) != MEMMODEL_RELAXED)
18638 + rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18639 + MEM_VOLATILE_P (mem) = 1;
18640 + emit_insn (gen_mem_thread_fence_1 (mem, operands[0]));
18642 + DONE;
18645 +(define_insn "mem_thread_fence_1"
18646 + [(set (match_operand:BLK 0 "" "")
18647 + (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
18648 + (match_operand:SI 1 "const_int_operand" "")] ;; model
18649 + ""
18651 + switch (INTVAL (operands[1]))
18653 + case MEMMODEL_SEQ_CST:
18654 + case MEMMODEL_ACQ_REL:
18655 + return "fence rw,rw";
18656 + case MEMMODEL_ACQUIRE:
18657 + case MEMMODEL_CONSUME:
18658 + return "fence r,rw";
18659 + case MEMMODEL_RELEASE:
18660 + return "fence rw,w";
18661 + default:
18662 + gcc_unreachable();
18666 +;; Atomic memory operations.
18668 +;; Implement atomic stores with amoswap. Fall back to fences for atomic loads.
18669 +(define_insn "atomic_store<mode>"
18670 + [(set (match_operand:GPR 0 "memory_operand" "=A")
18671 + (unspec_volatile:GPR
18672 + [(match_operand:GPR 1 "reg_or_0_operand" "rJ")
18673 + (match_operand:SI 2 "const_int_operand")] ;; model
18674 + UNSPEC_ATOMIC_STORE))]
18675 + "TARGET_ATOMIC"
18676 + "amoswap.<amo>%A2 zero,%z1,%0")
18678 +(define_insn "atomic_<atomic_optab><mode>"
18679 + [(set (match_operand:GPR 0 "memory_operand" "+A")
18680 + (unspec_volatile:GPR
18681 + [(any_atomic:GPR (match_dup 0)
18682 + (match_operand:GPR 1 "reg_or_0_operand" "rJ"))
18683 + (match_operand:SI 2 "const_int_operand")] ;; model
18684 + UNSPEC_SYNC_OLD_OP))]
18685 + "TARGET_ATOMIC"
18686 + "amo<insn>.<amo>%A2 zero,%z1,%0")
18688 +(define_insn "atomic_fetch_<atomic_optab><mode>"
18689 + [(set (match_operand:GPR 0 "register_operand" "=&r")
18690 + (match_operand:GPR 1 "memory_operand" "+A"))
18691 + (set (match_dup 1)
18692 + (unspec_volatile:GPR
18693 + [(any_atomic:GPR (match_dup 1)
18694 + (match_operand:GPR 2 "reg_or_0_operand" "rJ"))
18695 + (match_operand:SI 3 "const_int_operand")] ;; model
18696 + UNSPEC_SYNC_OLD_OP))]
18697 + "TARGET_ATOMIC"
18698 + "amo<insn>.<amo>%A3 %0,%z2,%1")
18700 +(define_insn "atomic_exchange<mode>"
18701 + [(set (match_operand:GPR 0 "register_operand" "=&r")
18702 + (unspec_volatile:GPR
18703 + [(match_operand:GPR 1 "memory_operand" "+A")
18704 + (match_operand:SI 3 "const_int_operand")] ;; model
18705 + UNSPEC_SYNC_EXCHANGE))
18706 + (set (match_dup 1)
18707 + (match_operand:GPR 2 "register_operand" "0"))]
18708 + "TARGET_ATOMIC"
18709 + "amoswap.<amo>%A3 %0,%z2,%1")
18711 +(define_insn "atomic_cas_value_strong<mode>"
18712 + [(set (match_operand:GPR 0 "register_operand" "=&r")
18713 + (match_operand:GPR 1 "memory_operand" "+A"))
18714 + (set (match_dup 1)
18715 + (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
18716 + (match_operand:GPR 3 "reg_or_0_operand" "rJ")
18717 + (match_operand:SI 4 "const_int_operand") ;; mod_s
18718 + (match_operand:SI 5 "const_int_operand")] ;; mod_f
18719 + UNSPEC_COMPARE_AND_SWAP))
18720 + (clobber (match_scratch:GPR 6 "=&r"))]
18721 + "TARGET_ATOMIC"
18722 + "1: lr.<amo>%A5 %0,%1; bne %0,%z2,1f; sc.<amo>%A4 %6,%z3,%1; bnez %6,1b; 1:"
18723 + [(set (attr "length") (const_int 16))])
18725 +(define_expand "atomic_compare_and_swap<mode>"
18726 + [(match_operand:SI 0 "register_operand" "") ;; bool output
18727 + (match_operand:GPR 1 "register_operand" "") ;; val output
18728 + (match_operand:GPR 2 "memory_operand" "") ;; memory
18729 + (match_operand:GPR 3 "reg_or_0_operand" "") ;; expected value
18730 + (match_operand:GPR 4 "reg_or_0_operand" "") ;; desired value
18731 + (match_operand:SI 5 "const_int_operand" "") ;; is_weak
18732 + (match_operand:SI 6 "const_int_operand" "") ;; mod_s
18733 + (match_operand:SI 7 "const_int_operand" "")] ;; mod_f
18734 + "TARGET_ATOMIC"
18736 + emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
18737 + operands[3], operands[4],
18738 + operands[6], operands[7]));
18740 + rtx compare = operands[1];
18741 + if (operands[3] != const0_rtx)
18743 + rtx difference = gen_rtx_MINUS (<MODE>mode, operands[1], operands[3]);
18744 + compare = gen_reg_rtx (<MODE>mode);
18745 + emit_insn (gen_rtx_SET (VOIDmode, compare, difference));
18748 + rtx eq = gen_rtx_EQ (<MODE>mode, compare, const0_rtx);
18749 + rtx result = gen_reg_rtx (<MODE>mode);
18750 + emit_insn (gen_rtx_SET (VOIDmode, result, eq));
18751 + emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_lowpart (SImode, result)));
18752 + DONE;
18755 +(define_expand "atomic_test_and_set"
18756 + [(match_operand:QI 0 "register_operand" "") ;; bool output
18757 + (match_operand:QI 1 "memory_operand" "+A") ;; memory
18758 + (match_operand:SI 2 "const_int_operand" "")] ;; model
18759 + "TARGET_ATOMIC"
18761 + /* We have no QImode atomics, so use the address LSBs to form a mask,
18762 + then use an aligned SImode atomic. */
18763 + rtx result = operands[0];
18764 + rtx mem = operands[1];
18765 + rtx model = operands[2];
18766 + rtx addr = force_reg (Pmode, XEXP (mem, 0));
18768 + rtx aligned_addr = gen_reg_rtx (Pmode);
18769 + emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-4)));
18771 + rtx aligned_mem = change_address (mem, SImode, aligned_addr);
18772 + set_mem_alias_set (aligned_mem, 0);
18774 + rtx offset = gen_reg_rtx (SImode);
18775 + emit_move_insn (offset, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
18776 + GEN_INT (3)));
18778 + rtx tmp = gen_reg_rtx (SImode);
18779 + emit_move_insn (tmp, GEN_INT (1));
18781 + rtx shmt = gen_reg_rtx (SImode);
18782 + emit_move_insn (shmt, gen_rtx_ASHIFT (SImode, offset, GEN_INT (3)));
18784 + rtx word = gen_reg_rtx (SImode);
18785 + emit_move_insn (word, gen_rtx_ASHIFT (SImode, tmp, shmt));
18787 + tmp = gen_reg_rtx (SImode);
18788 + emit_insn (gen_atomic_fetch_orsi (tmp, aligned_mem, word, model));
18790 + emit_move_insn (gen_lowpart (SImode, result),
18791 + gen_rtx_LSHIFTRT (SImode, tmp,
18792 + gen_lowpart (SImode, shmt)));
18793 + DONE;
18795 diff -rNU3 dist.orig/gcc/config/riscv/t-elf dist/gcc/config/riscv/t-elf
18796 --- dist.orig/gcc/config/riscv/t-elf 1970-01-01 01:00:00.000000000 +0100
18797 +++ dist/gcc/config/riscv/t-elf 2015-10-18 13:19:50.000000000 +0200
18798 @@ -0,0 +1,4 @@
18799 +# Build the libraries for both hard and soft floating point
18801 +MULTILIB_OPTIONS = msoft-float m64/m32 mno-atomic
18802 +MULTILIB_DIRNAMES = soft-float 64 32 no-atomic
18803 diff -rNU3 dist.orig/gcc/config/riscv/t-linux64 dist/gcc/config/riscv/t-linux64
18804 --- dist.orig/gcc/config/riscv/t-linux64 1970-01-01 01:00:00.000000000 +0100
18805 +++ dist/gcc/config/riscv/t-linux64 2015-10-18 13:19:50.000000000 +0200
18806 @@ -0,0 +1,5 @@
18807 +# Build the libraries for both hard and soft floating point
18809 +MULTILIB_OPTIONS = m64/m32 msoft-float mno-atomic
18810 +MULTILIB_DIRNAMES = 64 32 soft-float no-atomic
18811 +MULTILIB_OSDIRNAMES = ../lib ../lib32
18812 diff -rNU3 dist.orig/gcc/config/riscv/t-netbsd64 dist/gcc/config/riscv/t-netbsd64
18813 --- dist.orig/gcc/config/riscv/t-netbsd64 1970-01-01 01:00:00.000000000 +0100
18814 +++ dist/gcc/config/riscv/t-netbsd64 2015-10-18 13:19:50.000000000 +0200
18815 @@ -0,0 +1,21 @@
18816 +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
18818 +# This file is part of GCC.
18820 +# GCC is free software; you can redistribute it and/or modify
18821 +# it under the terms of the GNU General Public License as published by
18822 +# the Free Software Foundation; either version 3, or (at your option)
18823 +# any later version.
18825 +# GCC is distributed in the hope that it will be useful,
18826 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
18827 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18828 +# GNU General Public License for more details.
18830 +# You should have received a copy of the GNU General Public License
18831 +# along with GCC; see the file COPYING3. If not see
18832 +# <http://www.gnu.org/licenses/>.
18834 +MULTILIB_OPTIONS = m64/m32
18835 +MULTILIB_DIRNAMES = 64 32
18836 +MULTILIB_OSDIRNAMES = . ../lib/rv32
18837 diff -rNU3 dist.orig/gcc/config/rs6000/netbsd.h dist/gcc/config/rs6000/netbsd.h
18838 --- dist.orig/gcc/config/rs6000/netbsd.h 2013-01-10 21:38:27.000000000 +0100
18839 +++ dist/gcc/config/rs6000/netbsd.h 2015-10-18 13:19:50.000000000 +0200
18840 @@ -27,6 +27,12 @@
18841 builtin_define ("__powerpc__"); \
18842 builtin_assert ("cpu=powerpc"); \
18843 builtin_assert ("machine=powerpc"); \
18844 + if (TARGET_SECURE_PLT) \
18845 + builtin_define ("_SECURE_PLT"); \
18846 + if (TARGET_SOFT_FLOAT) \
18847 + builtin_define ("_SOFT_FLOAT"); \
18848 + if (TARGET_ISEL) \
18849 + builtin_define ("__PPC_ISEL__"); \
18851 while (0)
18853 @@ -58,6 +64,29 @@
18854 #undef PTRDIFF_TYPE
18855 #define PTRDIFF_TYPE "int"
18857 +/* Redefine some types that where redefined by rs6000 include files. */
18859 +#undef WCHAR_TYPE
18860 +#define WCHAR_TYPE "int"
18862 +#undef WCHAR_TYPE_SIZE
18863 +#define WCHAR_TYPE_SIZE 32
18865 +#undef WINT_TYPE
18866 +#define WINT_TYPE "int"
18868 +#undef INT64_TYPE
18869 +#define INT64_TYPE "long long int"
18871 +#undef UINT64_TYPE
18872 +#define UINT64_TYPE "long long unsigned int"
18874 +#undef INTMAX_TYPE
18875 +#define INTMAX_TYPE "long long int"
18877 +#undef UINTMAX_TYPE
18878 +#define UINTMAX_TYPE "long long unsigned int"
18880 /* Undo the spec mess from sysv4.h, and just define the specs
18881 the way NetBSD systems actually expect. */
18883 @@ -75,16 +104,44 @@
18884 #define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
18886 #undef ENDFILE_SPEC
18887 -#define ENDFILE_SPEC "%(netbsd_endfile_spec)"
18888 +#define ENDFILE_SPEC NETBSD_ENDFILE_SPEC
18890 #undef LIB_SPEC
18891 #define LIB_SPEC NETBSD_LIB_SPEC
18893 #undef SUBTARGET_EXTRA_SPECS
18894 #define SUBTARGET_EXTRA_SPECS \
18895 + { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC }, \
18896 { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
18897 { "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
18898 { "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
18901 + * Add NetBSD specific defaults: -mstrict-align
18902 + */
18903 +#undef TARGET_DEFAULT
18904 +#define TARGET_DEFAULT (MASK_STRICT_ALIGN)
18907 + * We know we have the right binutils for this (we shouldn't need to do this
18908 + * but until the cross build does the right thing...)
18909 + */
18910 +#undef TARGET_SECURE_PLT
18911 +#define TARGET_SECURE_PLT secure_plt
18912 +#undef HAVE_AS_TLS
18913 +#define HAVE_AS_TLS 1
18914 +#define POWERPC_NETBSD
18916 +/* Attempt to enable execute permissions on the stack. */
18917 +//#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
18918 +// XXXMRG use enable-execute-stack-mprotect.c ?
18919 +#ifdef L_trampoline
18920 +#undef TRAMPOLINE_SIZE
18921 +#define TRAMPOLINE_SIZE 48
18922 +#endif
18924 +/* Override STACK_BOUNDARY to use Altivec compliant one. */
18925 +#undef STACK_BOUNDARY
18926 +#define STACK_BOUNDARY 128
18928 #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
18929 diff -rNU3 dist.orig/gcc/config/rs6000/netbsd64.h dist/gcc/config/rs6000/netbsd64.h
18930 --- dist.orig/gcc/config/rs6000/netbsd64.h 1970-01-01 01:00:00.000000000 +0100
18931 +++ dist/gcc/config/rs6000/netbsd64.h 2015-10-18 13:19:50.000000000 +0200
18932 @@ -0,0 +1,629 @@
18933 +/* Definitions of target machine for GNU compiler,
18934 + for 64 bit PowerPC NetBSD.
18935 + Copyright (C) 2006 Free Software Foundation, Inc.
18936 + Contributed by Matthew Green (mrg@eterna.com.au).
18938 + This file is part of GCC.
18940 + GCC is free software; you can redistribute it and/or modify it
18941 + under the terms of the GNU General Public License as published
18942 + by the Free Software Foundation; either version 2, or (at your
18943 + option) any later version.
18945 + GCC is distributed in the hope that it will be useful, but WITHOUT
18946 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18947 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18948 + License for more details.
18950 + You should have received a copy of the GNU General Public License
18951 + along with GCC; see the file COPYING. If not, write to the
18952 + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
18953 + MA 02110-1301, USA. */
18955 +#ifndef RS6000_BI_ARCH
18957 +#undef DEFAULT_ABI
18958 +#define DEFAULT_ABI ABI_AIX
18960 +#undef TARGET_64BIT
18961 +#define TARGET_64BIT 1
18963 +#define DEFAULT_ARCH64_P 1
18964 +#define RS6000_BI_ARCH_P 0
18966 +#else
18968 +#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT)
18969 +#define RS6000_BI_ARCH_P 1
18971 +#endif
18973 +#ifdef IN_LIBGCC2
18974 +#undef TARGET_64BIT
18975 +#ifdef __powerpc64__
18976 +#define TARGET_64BIT 1
18977 +#else
18978 +#define TARGET_64BIT 0
18979 +#endif
18980 +#endif
18982 +#undef TARGET_AIX
18983 +#define TARGET_AIX TARGET_64BIT
18985 +#ifdef HAVE_LD_NO_DOT_SYMS
18986 +/* New ABI uses a local sym for the function entry point. */
18987 +extern int dot_symbols;
18988 +#undef DOT_SYMBOLS
18989 +#define DOT_SYMBOLS dot_symbols
18990 +#endif
18992 +#define TARGET_PROFILE_KERNEL profile_kernel
18994 +#define TARGET_USES_LINUX64_OPT 1
18995 +#ifdef HAVE_LD_LARGE_TOC
18996 +#undef TARGET_CMODEL
18997 +#define TARGET_CMODEL rs6000_current_cmodel
18998 +#define SET_CMODEL(opt) rs6000_current_cmodel = opt
18999 +#else
19000 +#define SET_CMODEL(opt) do {} while (0)
19001 +#endif
19003 +#undef PROCESSOR_DEFAULT
19004 +#define PROCESSOR_DEFAULT PROCESSOR_POWER4
19005 +#undef PROCESSOR_DEFAULT64
19006 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4
19008 +/* We don't need to generate entries in .fixup, except when
19009 + -mrelocatable or -mrelocatable-lib is given. */
19010 +#undef RELOCATABLE_NEEDS_FIXUP
19011 +#define RELOCATABLE_NEEDS_FIXUP \
19012 + (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
19014 +#undef RS6000_ABI_NAME
19015 +#define RS6000_ABI_NAME "netbsd"
19017 +#define INVALID_64BIT "-m%s not supported in this configuration"
19018 +#define INVALID_32BIT INVALID_64BIT
19020 +#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2)
19022 +#undef CC1_OS_NETBSD_SPEC
19023 +#define CC1_OS_NETBSD_SPEC \
19024 + NETBSD_CC1_AND_CC1PLUS_SPEC \
19025 + "%{!m32: %{!mrelocatable: %{!fno-pie: %{!fno-pic: \
19026 + %{!fpie: %{!fpic: \
19027 + %{!fPIE: %{!fPIC:-fPIC}}}}}}}}"
19028 +/* %{!m32: %{!mcmodel*: -mcmodel=medium}}" */
19030 +#undef CC1PLUS_SPEC
19031 +#define CC1PLUS_SPEC CC1_OS_NETBSD_SPEC
19033 +#undef SUBSUBTARGET_OVERRIDE_OPTIONS
19034 +#define SUBSUBTARGET_OVERRIDE_OPTIONS \
19035 + do \
19036 + { \
19037 + if (!global_options_set.x_rs6000_alignment_flags) \
19038 + rs6000_alignment_flags = MASK_ALIGN_NATURAL; \
19039 + if (TARGET_64BIT) \
19040 + { \
19041 + if (DEFAULT_ABI != ABI_AIX) \
19042 + { \
19043 + rs6000_current_abi = ABI_AIX; \
19044 + error (INVALID_64BIT, "call"); \
19045 + } \
19046 + dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \
19047 + if (ELFv2_ABI_CHECK) \
19048 + { \
19049 + rs6000_current_abi = ABI_ELFv2; \
19050 + if (dot_symbols) \
19051 + error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \
19052 + } \
19053 + if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \
19054 + { \
19055 + rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \
19056 + error (INVALID_64BIT, "relocatable"); \
19057 + } \
19058 + if (rs6000_isa_flags & OPTION_MASK_EABI) \
19059 + { \
19060 + rs6000_isa_flags &= ~OPTION_MASK_EABI; \
19061 + error (INVALID_64BIT, "eabi"); \
19062 + } \
19063 + if (TARGET_PROTOTYPE) \
19064 + { \
19065 + target_prototype = 0; \
19066 + error (INVALID_64BIT, "prototype"); \
19067 + } \
19068 + if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \
19069 + { \
19070 + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \
19071 + error ("-m64 requires a PowerPC64 cpu"); \
19072 + } \
19073 + if ((rs6000_isa_flags_explicit \
19074 + & OPTION_MASK_MINIMAL_TOC) != 0) \
19075 + { \
19076 + if (global_options_set.x_rs6000_current_cmodel \
19077 + && rs6000_current_cmodel != CMODEL_SMALL) \
19078 + error ("-mcmodel incompatible with other toc options"); \
19079 + SET_CMODEL (CMODEL_SMALL); \
19080 + } \
19081 + { \
19082 + if (!global_options_set.x_rs6000_current_cmodel) \
19083 + SET_CMODEL (CMODEL_MEDIUM); \
19084 + if (rs6000_current_cmodel != CMODEL_SMALL) \
19085 + { \
19086 + TARGET_NO_FP_IN_TOC = 0; \
19087 + TARGET_NO_SUM_IN_TOC = 0; \
19088 + } \
19089 + } \
19090 + } \
19091 + else \
19092 + { \
19093 + if (!RS6000_BI_ARCH_P) \
19094 + error (INVALID_32BIT, "32"); \
19095 + if (TARGET_PROFILE_KERNEL) \
19096 + { \
19097 + TARGET_PROFILE_KERNEL = 0; \
19098 + error (INVALID_32BIT, "profile-kernel"); \
19099 + } \
19100 + if (global_options_set.x_rs6000_current_cmodel) \
19101 + { \
19102 + SET_CMODEL (CMODEL_SMALL); \
19103 + error (INVALID_32BIT, "cmodel"); \
19104 + } \
19105 + } \
19106 + } \
19107 + while (0)
19109 +#ifdef RS6000_BI_ARCH
19111 +#if 0
19112 +#undef OVERRIDE_OPTIONS
19113 +#define OVERRIDE_OPTIONS \
19114 + rs6000_override_options (((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
19115 + ? (char *) 0 : TARGET_CPU_DEFAULT)
19116 +#endif
19118 +#endif
19120 +#undef ASM_DEFAULT_SPEC
19121 +#undef ASM_SPEC
19122 +#undef LINK_OS_NETBSD_SPEC
19124 +#ifndef RS6000_BI_ARCH
19125 +#define ASM_DEFAULT_SPEC "-mppc64"
19126 +#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)"
19127 +#define LINK_OS_NETBSD_SPEC "%(link_os_netbsd_spec64)"
19128 +#else
19129 +#if DEFAULT_ARCH64_P
19130 +#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
19131 +#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
19132 +#define LINK_OS_NETBSD_SPEC "%{m32:%(link_os_netbsd_spec32)}%{!m32:%(link_os_netbsd_spec64)}"
19133 +#else
19134 +#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
19135 +#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
19136 +#define LINK_OS_NETBSD_SPEC "%{!m64:%(link_os_netbsd_spec32)}%{m64:%(link_os_netbsd_spec64)}"
19137 +#endif
19138 +#endif
19140 +#define ASM_SPEC32 "-a32 \
19141 +%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
19142 +%{memb|msdata=eabi: -memb}"
19144 +#define ASM_SPEC64 "-a64"
19146 +#define ASM_SPEC_COMMON "%(asm_cpu) \
19147 +%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \
19148 + ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
19150 +#undef SUBSUBTARGET_EXTRA_SPECS
19151 +#define SUBSUBTARGET_EXTRA_SPECS \
19152 + { "asm_spec_common", ASM_SPEC_COMMON }, \
19153 + { "asm_spec32", ASM_SPEC32 }, \
19154 + { "asm_spec64", ASM_SPEC64 }, \
19155 + { "link_os_netbsd_spec32", LINK_OS_NETBSD_SPEC32 }, \
19156 + { "link_os_netbsd_spec64", LINK_OS_NETBSD_SPEC64 },
19158 +#undef MULTILIB_DEFAULTS
19159 +#if DEFAULT_ARCH64_P
19160 +#define MULTILIB_DEFAULTS { "m64" }
19161 +#else
19162 +#define MULTILIB_DEFAULTS { "m32" }
19163 +#endif
19165 +#ifndef RS6000_BI_ARCH
19167 +/* 64-bit PowerPC NetBSD is always big-endian. */
19168 +#undef TARGET_LITTLE_ENDIAN
19169 +#define TARGET_LITTLE_ENDIAN 0
19171 +/* 64-bit PowerPC NetBSD always has a TOC. */
19172 +#undef TARGET_TOC
19173 +#define TARGET_TOC 1
19175 +/* Some things from sysv4.h we don't do when 64 bit. */
19176 +#undef TARGET_RELOCATABLE
19177 +#define TARGET_RELOCATABLE 0
19178 +#undef TARGET_EABI
19179 +#define TARGET_EABI 0
19180 +#undef TARGET_PROTOTYPE
19181 +#define TARGET_PROTOTYPE 0
19182 +#undef RELOCATABLE_NEEDS_FIXUP
19183 +#define RELOCATABLE_NEEDS_FIXUP 0
19185 +#endif
19187 +/* PowerPC64 NetBSD word-aligns FP doubles when -malign-power is given. */
19188 +#undef ADJUST_FIELD_ALIGN
19189 +#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
19190 + ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
19191 + ? 128 \
19192 + : (TARGET_64BIT \
19193 + && TARGET_ALIGN_NATURAL == 0 \
19194 + && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode) \
19195 + ? MIN ((COMPUTED), 32) \
19196 + : (COMPUTED))
19198 +/* PowerPC64 NetBSD increases natural record alignment to doubleword if
19199 + the first field is an FP double, only if in power alignment mode. */
19200 +#undef ROUND_TYPE_ALIGN
19201 +#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
19202 + ((TARGET_64BIT \
19203 + && (TREE_CODE (STRUCT) == RECORD_TYPE \
19204 + || TREE_CODE (STRUCT) == UNION_TYPE \
19205 + || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
19206 + && TARGET_ALIGN_NATURAL == 0) \
19207 + ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
19208 + : MAX ((COMPUTED), (SPECIFIED)))
19210 +/* Use the default for compiling target libs. */
19211 +#ifdef IN_TARGET_LIBS
19212 +#undef TARGET_ALIGN_NATURAL
19213 +#define TARGET_ALIGN_NATURAL 1
19214 +#endif
19216 +/* Indicate that jump tables go in the text section. */
19217 +#undef JUMP_TABLES_IN_TEXT_SECTION
19218 +#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
19220 +/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
19221 + than a doubleword should be padded upward or downward. You could
19222 + reasonably assume that they follow the normal rules for structure
19223 + layout treating the parameter area as any other block of memory,
19224 + then map the reg param area to registers. i.e. pad upward.
19225 + Setting both of the following defines results in this behavior.
19226 + Setting just the first one will result in aggregates that fit in a
19227 + doubleword being padded downward, and others being padded upward.
19228 + Not a bad idea as this results in struct { int x; } being passed
19229 + the same way as an int. */
19230 +#define AGGREGATE_PADDING_FIXED TARGET_64BIT
19231 +#define AGGREGATES_PAD_UPWARD_ALWAYS 0
19233 +/* Specify padding for the last element of a block move between
19234 + registers and memory. FIRST is nonzero if this is the only
19235 + element. */
19236 +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
19237 + (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
19239 +/* NetBSD doesn't support saving and restoring 64-bit regs in a 32-bit
19240 + process. XXXMRG? */
19241 +#define OS_MISSING_POWERPC64 !TARGET_64BIT
19243 +/* NetBSD has float and long double forms of math functions. */
19244 +#undef TARGET_C99_FUNCTIONS
19245 +#define TARGET_C99_FUNCTIONS 1
19247 +/* NetBSD doesn't have sincos that follows the GNU extension. */
19248 +#undef TARGET_HAS_SINCOS
19250 +#undef TARGET_OS_CPP_BUILTINS
19251 +#define TARGET_OS_CPP_BUILTINS() \
19252 + do \
19253 + { \
19254 + NETBSD_OS_CPP_BUILTINS_ELF(); \
19255 + if (TARGET_ISEL) \
19256 + builtin_define ("__PPC_ISEL__"); \
19257 + if (TARGET_64BIT) \
19258 + { \
19259 + builtin_define ("__PPC__"); \
19260 + builtin_define ("__PPC64__"); \
19261 + builtin_define ("__powerpc__"); \
19262 + builtin_define ("__powerpc64__"); \
19263 + builtin_define_with_int_value ("__PIC__", 2); \
19264 + builtin_assert ("cpu=powerpc64"); \
19265 + builtin_assert ("machine=powerpc64"); \
19266 + } \
19267 + else \
19268 + { \
19269 + builtin_define_std ("PPC"); \
19270 + builtin_define_std ("powerpc"); \
19271 + builtin_assert ("cpu=powerpc"); \
19272 + builtin_assert ("machine=powerpc"); \
19273 + TARGET_OS_SYSV_CPP_BUILTINS (); \
19274 + } \
19275 + } \
19276 + while (0)
19278 +/* Override the default from rs6000.h to avoid conflicts with macros
19279 + defined in NetBSD header files. */
19281 +#undef RS6000_CPU_CPP_ENDIAN_BUILTINS
19282 +#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \
19283 + do \
19284 + { \
19285 + builtin_define ("__BIG_ENDIAN__"); \
19286 + builtin_assert ("machine=bigendian"); \
19287 + } \
19288 + while (0)
19290 +#undef CPP_OS_DEFAULT_SPEC
19291 +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_netbsd)"
19293 +#undef LINK_SHLIB_SPEC
19294 +#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
19296 +#undef LIB_DEFAULT_SPEC
19297 +#define LIB_DEFAULT_SPEC "%(lib_netbsd)"
19299 +#undef STARTFILE_DEFAULT_SPEC
19300 +#define STARTFILE_DEFAULT_SPEC "%(startfile_netbsd)"
19302 +#undef ENDFILE_DEFAULT_SPEC
19303 +#define ENDFILE_DEFAULT_SPEC "%(endfile_netbsd)"
19305 +#undef LINK_START_DEFAULT_SPEC
19306 +#define LINK_START_DEFAULT_SPEC "%(link_start_netbsd)"
19308 +#undef LINK_OS_DEFAULT_SPEC
19309 +#define LINK_OS_DEFAULT_SPEC "%(link_os_netbsd)"
19311 +#define LINK_OS_NETBSD_SPEC32 "-m elf32ppc %{!shared: %{!static: \
19312 + %{rdynamic:-export-dynamic} \
19313 + %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}}}"
19315 +#define LINK_OS_NETBSD_SPEC64 "-m elf64ppc %{!shared: %{!static: \
19316 + %{rdynamic:-export-dynamic} \
19317 + %{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}}}"
19319 +#undef TOC_SECTION_ASM_OP
19320 +#define TOC_SECTION_ASM_OP \
19321 + (TARGET_64BIT \
19322 + ? "\t.section\t\".toc\",\"aw\"" \
19323 + : "\t.section\t\".got\",\"aw\"")
19325 +#undef MINIMAL_TOC_SECTION_ASM_OP
19326 +#define MINIMAL_TOC_SECTION_ASM_OP \
19327 + (TARGET_64BIT \
19328 + ? "\t.section\t\".toc1\",\"aw\"" \
19329 + : ((TARGET_RELOCATABLE || flag_pic) \
19330 + ? "\t.section\t\".got2\",\"aw\"" \
19331 + : "\t.section\t\".got1\",\"aw\""))
19333 +/* Make GCC agree with <machine/ansi.h>. */
19335 +#undef SIZE_TYPE
19336 +#define SIZE_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
19338 +#undef PTRDIFF_TYPE
19339 +#define PTRDIFF_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
19341 +#undef INTPTR_TYPE
19342 +#define INTPTR_TYPE PTRDIFF_TYPE
19344 +#undef UINTPTR_TYPE
19345 +#define UINTPTR_TYPE SIZE_TYPE
19347 +#undef WCHAR_TYPE
19348 +#define WCHAR_TYPE "int"
19350 +#undef INT8_TYPE
19351 +#define INT8_TYPE "signed char"
19353 +#undef INT16_TYPE
19354 +#define INT16_TYPE "short int"
19356 +#undef INT32_TYPE
19357 +#define INT32_TYPE "int"
19359 +#undef INT64_TYPE
19360 +#define INT64_TYPE "long long int"
19362 +#undef UINT8_TYPE
19363 +#define UINT8_TYPE "unsigned char"
19365 +#undef UINT16_TYPE
19366 +#define UINT16_TYPE "short unsigned int"
19368 +#undef UINT32_TYPE
19369 +#define UINT32_TYPE "unsigned int"
19371 +#undef UINT64_TYPE
19372 +#define UINT64_TYPE "long long unsigned int"
19374 +#undef INT_FAST8_TYPE
19375 +#define INT_FAST8_TYPE "int"
19377 +#undef INT_FAST16_TYPE
19378 +#define INT_FAST16_TYPE "int"
19380 +#undef INT_FAST32_TYPE
19381 +#define INT_FAST32_TYPE "int"
19383 +#undef INT_FAST64_TYPE
19384 +#define INT_FAST64_TYPE INT64_TYPE
19386 +#undef UINT_FAST8_TYPE
19387 +#define UINT_FAST8_TYPE "unsigned int"
19389 +#undef UINT_FAST16_TYPE
19390 +#define UINT_FAST16_TYPE "unsigned int"
19392 +#undef UINT_FAST32_TYPE
19393 +#define UINT_FAST32_TYPE "unsigned int"
19395 +#undef UINT_FAST8_TYPE
19396 +#define UINT_FAST8_TYPE "unsigned int"
19398 +#undef UINT_FAST16_TYPE
19399 +#define UINT_FAST16_TYPE "unsigned int"
19401 +#undef UINT_FAST32_TYPE
19402 +#define UINT_FAST32_TYPE "unsigned int"
19404 +#undef UINT_FAST64_TYPE
19405 +#define UINT_FAST64_TYPE UINT64_TYPE
19407 +#undef INT_LEAST8_TYPE
19408 +#define INT_LEAST8_TYPE INT8_TYPE
19410 +#undef INT_LEAST16_TYPE
19411 +#define INT_LEAST16_TYPE INT16_TYPE
19413 +#undef INT_LEAST32_TYPE
19414 +#define INT_LEAST32_TYPE "int"
19416 +#undef INT_LEAST64_TYPE
19417 +#define INT_LEAST64_TYPE INT64_TYPE
19419 +#undef UINT_LEAST8_TYPE
19420 +#define UINT_LEAST8_TYPE UINT8_TYPE
19422 +#undef UINT_LEAST16_TYPE
19423 +#define UINT_LEAST16_TYPE UINT16_TYPE
19425 +#undef UINT_LEAST32_TYPE
19426 +#define UINT_LEAST32_TYPE "unsigned int"
19428 +#undef UINT_LEAST64_TYPE
19429 +#define UINT_LEAST64_TYPE UINT64_TYPE
19431 +#undef INTMAX_TYPE
19432 +#define INTMAX_TYPE INT64_TYPE
19434 +#undef UINTMAX_TYPE
19435 +#define UINTMAX_TYPE UINT64_TYPE
19437 +/* Override rs6000.h definition. */
19438 +#undef ASM_APP_ON
19439 +#define ASM_APP_ON "#APP\n"
19441 +/* Override rs6000.h definition. */
19442 +#undef ASM_APP_OFF
19443 +#define ASM_APP_OFF "#NO_APP\n"
19445 +/* PowerPC no-op instruction. */
19446 +#undef RS6000_CALL_GLUE
19447 +#define RS6000_CALL_GLUE (TARGET_64BIT ? "nop" : "cror 31,31,31")
19449 +#undef RS6000_MCOUNT
19450 +#define RS6000_MCOUNT "_mcount"
19452 +#ifdef __powerpc64__
19453 +/* _init and _fini functions are built from bits spread across many
19454 + object files, each potentially with a different TOC pointer. For
19455 + that reason, place a nop after the call so that the linker can
19456 + restore the TOC pointer if a TOC adjusting call stub is needed. */
19457 +#if DOT_SYMBOLS
19458 +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
19459 + asm (SECTION_OP "\n" \
19460 +" bl ." #FUNC "\n" \
19461 +" nop\n" \
19462 +" .previous");
19463 +#else
19464 +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
19465 + asm (SECTION_OP "\n" \
19466 +" bl " #FUNC "\n" \
19467 +" nop\n" \
19468 +" .previous");
19469 +#endif
19470 +#endif
19472 +/* FP save and restore routines. */
19473 +#undef SAVE_FP_PREFIX
19474 +#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
19475 +#undef SAVE_FP_SUFFIX
19476 +#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
19477 +#undef RESTORE_FP_PREFIX
19478 +#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
19479 +#undef RESTORE_FP_SUFFIX
19480 +#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
19482 +/* Dwarf2 debugging. */
19483 +#undef PREFERRED_DEBUGGING_TYPE
19484 +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
19486 +/* This is how to declare the size of a function. */
19487 +#undef ASM_DECLARE_FUNCTION_SIZE
19488 +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
19489 + do \
19490 + { \
19491 + if (!flag_inhibit_size_directive) \
19492 + { \
19493 + fputs ("\t.size\t", (FILE)); \
19494 + if (TARGET_64BIT && DOT_SYMBOLS) \
19495 + putc ('.', (FILE)); \
19496 + assemble_name ((FILE), (FNAME)); \
19497 + fputs (",.-", (FILE)); \
19498 + rs6000_output_function_entry (FILE, FNAME); \
19499 + putc ('\n', (FILE)); \
19500 + } \
19501 + } \
19502 + while (0)
19504 +/* Return nonzero if this entry is to be written into the constant
19505 + pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF
19506 + or a CONST containing one of them. If -mfp-in-toc (the default),
19507 + we also do this for floating-point constants. We actually can only
19508 + do this if the FP formats of the target and host machines are the
19509 + same, but we can't check that since not every file that uses
19510 + the macros includes real.h. We also do this when we can write the
19511 + entry into the TOC and the entry is not larger than a TOC entry. */
19513 +#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
19514 +#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \
19515 + (TARGET_TOC \
19516 + && (GET_CODE (X) == SYMBOL_REF \
19517 + || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \
19518 + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \
19519 + || GET_CODE (X) == LABEL_REF \
19520 + || (GET_CODE (X) == CONST_INT \
19521 + && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
19522 + || (GET_CODE (X) == CONST_DOUBLE \
19523 + && ((TARGET_64BIT \
19524 + && (TARGET_MINIMAL_TOC \
19525 + || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
19526 + && ! TARGET_NO_FP_IN_TOC))) \
19527 + || (!TARGET_64BIT \
19528 + && !TARGET_NO_FP_IN_TOC \
19529 + && !TARGET_RELOCATABLE \
19530 + && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
19531 + && BITS_PER_WORD == HOST_BITS_PER_INT)))))
19533 +/* Select a format to encode pointers in exception handling data. CODE
19534 + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
19535 + true if the symbol may be affected by dynamic relocations. */
19536 +#undef ASM_PREFERRED_EH_DATA_FORMAT
19537 +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
19538 + ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
19539 + ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
19540 + | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
19541 + : DW_EH_PE_absptr)
19543 +/* For backward compatibility, we must continue to use the AIX
19544 + structure return convention. */
19545 +#undef DRAFT_V4_STRUCT_RET
19546 +#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
19548 +#define TARGET_POSIX_IO
19550 +#define LINK_GCC_C_SEQUENCE_SPEC \
19551 + "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
19553 +/* Use --as-needed -lgcc_s for eh support. */
19554 +#ifdef HAVE_LD_AS_NEEDED
19555 +#define USE_LD_AS_NEEDED 1
19556 +#endif
19558 +/* NetBSD ppc64 has 128-bit long double support. */
19559 +#undef RS6000_DEFAULT_LONG_DOUBLE_SIZE
19560 +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
19561 +#define POWERPC_NETBSD
19562 diff -rNU3 dist.orig/gcc/config/rs6000/rs6000.c dist/gcc/config/rs6000/rs6000.c
19563 --- dist.orig/gcc/config/rs6000/rs6000.c 2015-05-05 16:27:30.000000000 +0200
19564 +++ dist/gcc/config/rs6000/rs6000.c 2015-10-18 13:19:50.000000000 +0200
19565 @@ -3260,10 +3260,14 @@
19567 /* If we are optimizing big endian systems for space and it's OK to
19568 use instructions that would be microcoded on the Cell, use the
19569 - load/store multiple and string instructions. */
19570 + load/store multiple and string instructions. Don't use string
19571 + instructions on NetBSD because the e500 doesn't support them. */
19572 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
19573 rs6000_isa_flags |= ~rs6000_isa_flags_explicit & (OPTION_MASK_MULTIPLE
19574 - | OPTION_MASK_STRING);
19575 +#if !defined (POWERPC_NETBSD)
19576 + | OPTION_MASK_STRING
19577 +#endif
19578 + | 0);
19580 /* Don't allow -mmultiple or -mstring on little endian systems
19581 unless the cpu is a 750, because the hardware doesn't support the
19582 @@ -3534,7 +3538,8 @@
19583 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
19586 -#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
19587 +#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD) \
19588 + && !defined (POWERPC_NETBSD)
19589 if (!global_options_set.x_rs6000_ieeequad)
19590 rs6000_ieeequad = 1;
19591 #endif
19592 @@ -22820,7 +22825,8 @@
19594 else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
19596 -#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
19597 +#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD) \
19598 + && !defined(POWERPC_NETBSD)
19599 /* No out-of-line save/restore routines for GPRs on AIX. */
19600 gcc_assert (!TARGET_AIX || (sel & SAVRES_REG) != SAVRES_GPR);
19601 #endif
19602 @@ -22832,7 +22838,8 @@
19603 : ((sel & SAVRES_LR) ? "_restgpr0_" : "_restgpr1_"));
19604 else if ((sel & SAVRES_REG) == SAVRES_FPR)
19606 -#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD)
19607 +#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD) \
19608 + || defined (POWERPC_NETBSD)
19609 if ((sel & SAVRES_LR))
19610 prefix = ((sel & SAVRES_SAVE) ? "_savefpr_" : "_restfpr_");
19611 else
19612 @@ -29294,7 +29301,11 @@
19613 if (flag_pic)
19614 return 3;
19615 else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
19616 +#if defined (POWERPC_NETBSD)
19617 + return 3;
19618 +#else
19619 return 2;
19620 +#endif
19621 else
19622 return 0;
19624 @@ -29463,7 +29474,8 @@
19625 aix_struct_return ? 2 : 1);
19627 #endif
19628 -#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD)
19629 +#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD) \
19630 + || defined (POWERPC_NETBSD)
19631 if (TARGET_32BIT || DEFAULT_ABI == ABI_ELFv2)
19632 file_end_indicate_exec_stack ();
19633 #endif
19634 diff -rNU3 dist.orig/gcc/config/rs6000/sysv4.h dist/gcc/config/rs6000/sysv4.h
19635 --- dist.orig/gcc/config/rs6000/sysv4.h 2014-07-24 19:34:24.000000000 +0200
19636 +++ dist/gcc/config/rs6000/sysv4.h 2015-10-18 13:19:50.000000000 +0200
19637 @@ -97,7 +97,12 @@
19638 rs6000_current_abi = ABI_V4; \
19640 else if (!strcmp (rs6000_abi_name, "netbsd")) \
19641 - rs6000_current_abi = ABI_V4; \
19642 + { \
19643 + if (TARGET_64BIT) \
19644 + rs6000_current_abi = ABI_AIX; \
19645 + else \
19646 + rs6000_current_abi = ABI_V4; \
19647 + } \
19648 else if (!strcmp (rs6000_abi_name, "openbsd")) \
19649 rs6000_current_abi = ABI_V4; \
19650 else if (!strcmp (rs6000_abi_name, "i960-old")) \
19651 @@ -539,6 +544,7 @@
19652 #endif
19654 /* Pass -G xxx to the compiler. */
19655 +#undef CC1_SPEC
19656 #define CC1_SPEC "%{G*} %(cc1_cpu)" \
19657 "%{meabi: %{!mcall-*: -mcall-sysv }} \
19658 %{!meabi: %{!mno-eabi: \
19659 @@ -551,7 +557,8 @@
19660 %{msdata: -msdata=default} \
19661 %{mno-sdata: -msdata=none} \
19662 %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
19663 -%{profile: -p}"
19664 +%{profile: -p} \
19665 +%(cc1_os_netbsd)"
19667 /* Default starting address if specified. */
19668 #define LINK_START_SPEC "\
19669 @@ -777,7 +784,7 @@
19670 %{rdynamic:-export-dynamic} \
19671 -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
19673 -#if defined(HAVE_LD_EH_FRAME_HDR)
19674 +#if defined(HAVE_LD_EH_FRAME_HDR) && !defined(LINK_EH_SPEC)
19675 # define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
19676 #endif
19678 @@ -789,28 +796,23 @@
19679 -Asystem=linux -Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}"
19681 /* NetBSD support. */
19682 -#define LIB_NETBSD_SPEC "\
19683 --lc"
19684 +#define LIB_NETBSD_SPEC NETBSD_LIB_SPEC
19686 -#define STARTFILE_NETBSD_SPEC "\
19687 -ncrti.o%s crt0.o%s \
19688 -%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
19689 +#define STARTFILE_NETBSD_SPEC NETBSD_STARTFILE_SPEC
19691 -#define ENDFILE_NETBSD_SPEC "\
19692 -%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
19693 -ncrtn.o%s"
19694 +#define ENDFILE_NETBSD_SPEC NETBSD_ENDFILE_SPEC
19696 #define LINK_START_NETBSD_SPEC "\
19699 -#define LINK_OS_NETBSD_SPEC "\
19700 -%{!shared: %{!static: \
19701 - %{rdynamic:-export-dynamic} \
19702 - -dynamic-linker /usr/libexec/ld.elf_so}}"
19703 +#define LINK_OS_NETBSD_SPEC NETBSD_LINK_SPEC_ELF
19705 #define CPP_OS_NETBSD_SPEC "\
19706 -D__powerpc__ -D__NetBSD__ -D__KPRINTF_ATTRIBUTE__"
19708 +#define CC1_OS_NETBSD_SPEC "\
19709 +%{cxx-isystem}"
19711 /* OpenBSD support. */
19712 #ifndef LIB_OPENBSD_SPEC
19713 #define LIB_OPENBSD_SPEC "%{!shared:%{pthread:-lpthread%{p:_p}%{!p:%{pg:_p}}}} %{!shared:-lc%{p:_p}%{!p:%{pg:_p}}}"
19714 @@ -894,6 +896,7 @@
19715 { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \
19716 { "link_os_default", LINK_OS_DEFAULT_SPEC }, \
19717 { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC }, \
19718 + { "cc1_os_netbsd", CC1_OS_NETBSD_SPEC }, \
19719 { "cpp_os_ads", CPP_OS_ADS_SPEC }, \
19720 { "cpp_os_yellowknife", CPP_OS_YELLOWKNIFE_SPEC }, \
19721 { "cpp_os_mvme", CPP_OS_MVME_SPEC }, \
19722 diff -rNU3 dist.orig/gcc/config/rs6000/t-netbsd dist/gcc/config/rs6000/t-netbsd
19723 --- dist.orig/gcc/config/rs6000/t-netbsd 2013-01-10 21:38:27.000000000 +0100
19724 +++ dist/gcc/config/rs6000/t-netbsd 2015-10-18 13:19:50.000000000 +0200
19725 @@ -18,6 +18,10 @@
19726 # along with GCC; see the file COPYING3. If not see
19727 # <http://www.gnu.org/licenses/>.
19729 +# It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
19730 +CRTSTUFF_T_CFLAGS += -msdata=none
19731 +CRTSTUFF_T_CFLAGS_S += -msdata=none
19733 # Switch synonyms
19734 MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
19735 msoft-float=mcpu?403 \
19736 @@ -34,3 +38,9 @@
19737 MULTILIB_EXCEPTIONS =
19739 MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
19741 +LIBGCC = stmp-multilib
19743 +INSTALL_LIBGCC = install-multilib
19744 +EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \
19745 + crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext)
19746 diff -rNU3 dist.orig/gcc/config/rs6000/t-netbsd64 dist/gcc/config/rs6000/t-netbsd64
19747 --- dist.orig/gcc/config/rs6000/t-netbsd64 1970-01-01 01:00:00.000000000 +0100
19748 +++ dist/gcc/config/rs6000/t-netbsd64 2015-10-18 13:19:50.000000000 +0200
19749 @@ -0,0 +1,30 @@
19750 +# Support for NetBSD PowerPC64 ELF targets (ELF64 ABI).
19752 +LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/tramp.asm \
19753 + $(srcdir)/config/rs6000/ppc64-fp.c \
19754 + $(srcdir)/config/rs6000/darwin-ldouble.c
19756 +TARGET_LIBGCC2_CFLAGS += -mno-minimal-toc
19758 +MULTILIB_OPTIONS = m64/m32
19759 +MULTILIB_DIRNAMES = 64 32
19760 +MULTILIB_OSDIRNAMES = . ../lib/powerpc
19762 +MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT)
19764 +# We want fine grained libraries, so use the new code to build the
19765 +# floating point emulation libraries.
19766 +# fp-bit is only to be used by 32-bit multilibs
19767 +FPBIT = fp-bit32.c
19768 +DPBIT = dp-bit32.c
19770 +dp-bit32.c: $(srcdir)/config/fp-bit.c
19771 + ( echo '#ifndef __powerpc64__'; \
19772 + cat $(srcdir)/config/fp-bit.c; \
19773 + echo '#endif' ) > dp-bit32.c
19775 +fp-bit32.c: $(srcdir)/config/fp-bit.c
19776 + ( echo '#ifndef __powerpc64__'; \
19777 + echo '#define FLOAT'; \
19778 + cat $(srcdir)/config/fp-bit.c; \
19779 + echo '#endif' ) > fp-bit32.c
19780 diff -rNU3 dist.orig/gcc/config/rs6000/t-rs6000 dist/gcc/config/rs6000/t-rs6000
19781 --- dist.orig/gcc/config/rs6000/t-rs6000 2014-04-04 15:45:28.000000000 +0200
19782 +++ dist/gcc/config/rs6000/t-rs6000 2015-10-18 13:19:50.000000000 +0200
19783 @@ -38,6 +38,8 @@
19785 $(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \
19786 $(srcdir)/config/rs6000/rs6000-cpus.def
19787 + @echo "NOT REBUILDING $@"
19788 +NetBSD_DISABLED_rs6000-tables.opt:
19789 $(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \
19790 $(srcdir)/config/rs6000/rs6000-tables.opt
19792 diff -rNU3 dist.orig/gcc/config/sh/t-sh dist/gcc/config/sh/t-sh
19793 --- dist.orig/gcc/config/sh/t-sh 2015-03-26 08:49:35.000000000 +0100
19794 +++ dist/gcc/config/sh/t-sh 2015-10-18 13:19:50.000000000 +0200
19795 @@ -86,7 +86,6 @@
19796 m5-64media-nofpu=!m5-64media-nofpu $(OTHER_ENDIAN)/m5-64media-nofpu=!$(OTHER_ENDIAN)/m5-64media-nofpu
19798 $(out_object_file): gt-sh.h
19799 -gt-sh.h : s-gtype ; @true
19801 # Local Variables:
19802 # mode: Makefile
19803 diff -rNU3 dist.orig/gcc/config/sparc/netbsd-elf.h dist/gcc/config/sparc/netbsd-elf.h
19804 --- dist.orig/gcc/config/sparc/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
19805 +++ dist/gcc/config/sparc/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
19806 @@ -46,6 +46,37 @@
19807 #undef PTRDIFF_TYPE
19808 #define PTRDIFF_TYPE "long int"
19810 +/* we keep these "long" on both 32bit and 64bit targets */
19811 +#undef INTPTR_TYPE
19812 +#define INTPTR_TYPE PTRDIFF_TYPE
19814 +#undef UINTPTR_TYPE
19815 +#define UINTPTR_TYPE SIZE_TYPE
19817 +#undef INT_FAST8_TYPE
19818 +#define INT_FAST8_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
19820 +#undef UINT_FAST8_TYPE
19821 +#define UINT_FAST8_TYPE (LONG_TYPE_SIZE == 64 ? "unsigned char" : "unsigned int")
19823 +#undef INT_FAST16_TYPE
19824 +#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
19826 +#undef UINT_FAST16_TYPE
19827 +#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "short unsigned int" : "unsigned int")
19829 +#undef INT_FAST32_TYPE
19830 +#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
19832 +#undef UINT_FAST32_TYPE
19833 +#define UINT_FAST32_TYPE "unsigned int"
19835 +#undef INT_FAST64_TYPE
19836 +#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
19838 +#undef UINT_FAST64_TYPE
19839 +#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
19841 /* This is the char to use for continuation (in case we need to turn
19842 continuation back on). */
19843 #undef DBX_CONTIN_CHAR
19844 @@ -99,7 +130,7 @@
19845 + MASK_STACK_BIAS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
19847 #undef SPARC_DEFAULT_CMODEL
19848 -#define SPARC_DEFAULT_CMODEL CM_MEDANY
19849 +#define SPARC_DEFAULT_CMODEL CM_MEDMID
19851 #endif
19853 @@ -111,7 +142,8 @@
19854 %{!mcpu*:%{!mv8plus:-mcpu=ultrasparc}} \
19855 %{!mno-vis:%{!mcpu=v9:-mvis}} \
19856 %{p:-mcmodel=medlow} \
19857 - %{pg:-mcmodel=medlow}}"
19858 + %{pg:-mcmodel=medlow}} " \
19859 + NETBSD_CC1_AND_CC1PLUS_SPEC
19861 #define CC1_SPEC64 \
19862 "%{m32:%{m64:%emay not use both -m32 and -m64}} \
19863 @@ -120,8 +152,28 @@
19864 %{!mlong-double-128:-mlong-double-64} \
19865 %{!mcpu*:%{!mv8plus:-mcpu=cypress}}} \
19866 %{!m32: \
19867 - %{p:-mcmodel=medlow} \
19868 - %{pg:-mcmodel=medlow}}"
19869 + %{p:-mcmodel=medlow} \
19870 + %{pg:-mcmodel=medlow}} " \
19871 + NETBSD_CC1_AND_CC1PLUS_SPEC
19873 +#if defined(SPARC_BI_ARCH) || defined(__arch64__)
19874 +/* add code model specific object to the link line for 64bit */
19875 +#define LINK_SPEC_CODE_MODEL64 \
19876 + "%{!shared:" \
19877 + "%{!mcmodel=*:%:if-exists(%R/usr/lib/sparc_mcmedmid.o)}" \
19878 + "%{mcmodel=medlow:%:if-exists(%R/usr/lib/sparc_mcmedlow.o)}" \
19879 + "%{mcmodel=medmid:%:if-exists(%R/usr/lib/sparc_mcmedmid.o)}" \
19880 + "%{mcmodel=medany:%:if-exists(%R/usr/lib/sparc_mcmedany.o)}" \
19881 + "}"
19883 +#ifdef SPARC_BI_ARCH
19884 +#define LINK_SPEC_CODE_MODEL "%{!m32:" LINK_SPEC_CODE_MODEL64 "}"
19885 +#else
19886 +#define LINK_SPEC_CODE_MODEL LINK_SPEC_CODE_MODEL64
19887 +#endif
19888 +#else
19889 +#define LINK_SPEC_CODE_MODEL ""
19890 +#endif
19892 /* Make sure we use the right output format. Pick a default and then
19893 make sure -m32/-m64 switch to the right one. */
19894 @@ -139,7 +191,8 @@
19895 #define LINK_SPEC \
19896 "%(link_arch) \
19897 %{!mno-relax:%{!r:-relax}} \
19898 - %(netbsd_link_spec)"
19899 + %(netbsd_link_spec) " \
19900 + LINK_SPEC_CODE_MODEL
19902 #define NETBSD_ENTRY_POINT "__start"
19904 @@ -221,6 +274,13 @@
19906 #endif /* SPARC_BI_ARCH */
19908 +#ifdef HAVE_AS_TLS
19909 +#undef TARGET_SUN_TLS
19910 +#undef TARGET_GNU_TLS
19911 +#define TARGET_SUN_TLS 0
19912 +#define TARGET_GNU_TLS 1
19913 +#endif
19915 /* We use GNU ld so undefine this so that attribute((init_priority)) works. */
19916 #undef CTORS_SECTION_ASM_OP
19917 #undef DTORS_SECTION_ASM_OP
19918 diff -rNU3 dist.orig/gcc/config/sparc/t-netbsd64 dist/gcc/config/sparc/t-netbsd64
19919 --- dist.orig/gcc/config/sparc/t-netbsd64 2011-11-02 16:23:48.000000000 +0100
19920 +++ dist/gcc/config/sparc/t-netbsd64 2015-10-18 13:19:50.000000000 +0200
19921 @@ -1,5 +1,9 @@
19922 -# Disable multilib for now, as NetBSD/sparc64 does not ship with
19923 -# a 32-bit environment.
19924 -#MULTILIB_OPTIONS = m32/m64
19925 -#MULTILIB_DIRNAMES = 32 64
19926 -#MULTILIB_MATCHES =
19927 +# NetBSD has (will have) "non-native" libraries in /usr/lib/<arch>.
19928 +# For NetBSD/sparc64 we thus have /usr/lib and /usr/lib/sparc.
19930 +MULTILIB_OPTIONS = m64/m32
19931 +MULTILIB_DIRNAMES = 64 32
19932 +MULTILIB_OSDIRNAMES = . ../lib/sparc
19934 +LIBGCC = stmp-multilib
19935 +INSTALL_LIBGCC = install-multilib
19936 diff -rNU3 dist.orig/gcc/config/vax/builtins.md dist/gcc/config/vax/builtins.md
19937 --- dist.orig/gcc/config/vax/builtins.md 2013-01-10 21:38:27.000000000 +0100
19938 +++ dist/gcc/config/vax/builtins.md 2015-10-18 13:19:50.000000000 +0200
19939 @@ -24,6 +24,12 @@
19943 +(define_expand "condjump"
19944 + [(set (pc)
19945 + (if_then_else (match_operand 0)
19946 + (label_ref (match_operand 1))
19947 + (pc)))])
19949 (define_expand "ffssi2"
19950 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19951 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
19952 @@ -31,17 +37,17 @@
19955 rtx label = gen_label_rtx ();
19956 - emit_insn (gen_ffssi2_internal (operands[0], operands[1]));
19957 - emit_jump_insn (gen_bne (label));
19958 - emit_insn (gen_negsi2 (operands[0], const1_rtx));
19959 + emit_insn (gen_ctzsi2 (operands[0], operands[1]));
19960 + emit_jump_insn (gen_condjump (gen_rtx_NE(VOIDmode, cc0_rtx, const0_rtx), label));
19961 + emit_move_insn (operands[0], constm1_rtx);
19962 emit_label (label);
19963 emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
19964 DONE;
19967 -(define_insn "ffssi2_internal"
19968 +(define_insn "ctzsi2"
19969 [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
19970 - (ffs:SI (match_operand:SI 1 "general_operand" "nrmT")))
19971 + (ctz:SI (match_operand:SI 1 "general_operand" "nrmT")))
19972 (set (cc0) (match_dup 0))]
19974 "ffs $0,$32,%1,%0")
19975 @@ -189,4 +195,3 @@
19976 (const_int 0))])]
19978 "jbcci %1,%0,%l2")
19980 diff -rNU3 dist.orig/gcc/config/vax/constraints.md dist/gcc/config/vax/constraints.md
19981 --- dist.orig/gcc/config/vax/constraints.md 2013-01-10 21:38:27.000000000 +0100
19982 +++ dist/gcc/config/vax/constraints.md 2015-10-18 13:19:50.000000000 +0200
19983 @@ -114,5 +114,6 @@
19985 (define_constraint "T"
19986 "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST."
19987 - (ior (not (match_code "const,symbol_ref,label_ref"))
19988 - (match_test "!flag_pic")))
19989 + (and (match_test ("CONSTANT_P (op)"))
19990 + (ior (not (match_code "symbol_ref,label_ref,const"))
19991 + (match_test "!flag_pic"))))
19992 diff -rNU3 dist.orig/gcc/config/vax/elf.h dist/gcc/config/vax/elf.h
19993 --- dist.orig/gcc/config/vax/elf.h 2013-01-10 21:38:27.000000000 +0100
19994 +++ dist/gcc/config/vax/elf.h 2015-10-18 13:19:50.000000000 +0200
19995 @@ -108,5 +108,5 @@
19996 fputs (integer_asm_op (SIZE, FALSE), FILE); \
19997 fprintf (FILE, "%%pcrel%d(", SIZE * 8); \
19998 assemble_name (FILE, LABEL); \
19999 - fputc (')', FILE); \
20000 + fprintf (FILE, "%+d)", SIZE); \
20001 } while (0)
20002 diff -rNU3 dist.orig/gcc/config/vax/netbsd-elf.h dist/gcc/config/vax/netbsd-elf.h
20003 --- dist.orig/gcc/config/vax/netbsd-elf.h 2013-01-10 21:38:27.000000000 +0100
20004 +++ dist/gcc/config/vax/netbsd-elf.h 2015-10-18 13:19:50.000000000 +0200
20005 @@ -63,6 +63,12 @@
20006 #define EXTRA_SPECS \
20007 { "netbsd_entry_point", NETBSD_ENTRY_POINT },
20009 +#undef INTPTR_TYPE
20010 +#define INTPTR_TYPE "long int"
20012 +#undef UINTPTR_TYPE
20013 +#define UINTPTR_TYPE "long unsigned int"
20015 /* We use gas, not the UNIX assembler. */
20016 #undef TARGET_DEFAULT
20017 #define TARGET_DEFAULT MASK_QMATH
20018 diff -rNU3 dist.orig/gcc/config/vax/vax-protos.h dist/gcc/config/vax/vax-protos.h
20019 --- dist.orig/gcc/config/vax/vax-protos.h 2013-01-10 21:38:27.000000000 +0100
20020 +++ dist/gcc/config/vax/vax-protos.h 2015-10-18 13:19:50.000000000 +0200
20021 @@ -18,6 +18,7 @@
20022 <http://www.gnu.org/licenses/>. */
20024 extern bool legitimate_constant_address_p (rtx);
20025 +extern bool legitimate_pic_operand_p (rtx);
20026 extern void vax_expand_prologue (void);
20028 #ifdef RTX_CODE
20029 @@ -28,6 +29,7 @@
20030 extern void print_operand (FILE *, rtx, int);
20031 extern void vax_notice_update_cc (rtx, rtx);
20032 extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code);
20033 +extern bool vax_decomposed_dimode_operand_p (rtx, rtx);
20034 extern const char * vax_output_int_move (rtx, rtx *, enum machine_mode);
20035 extern const char * vax_output_int_add (rtx, rtx *, enum machine_mode);
20036 extern const char * vax_output_int_subtract (rtx, rtx *, enum machine_mode);
20037 diff -rNU3 dist.orig/gcc/config/vax/vax.c dist/gcc/config/vax/vax.c
20038 --- dist.orig/gcc/config/vax/vax.c 2013-01-10 21:38:27.000000000 +0100
20039 +++ dist/gcc/config/vax/vax.c 2015-10-18 13:19:50.000000000 +0200
20040 @@ -162,9 +162,13 @@
20041 HOST_WIDE_INT size;
20042 rtx insn;
20044 + offset = 20;
20045 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
20046 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
20047 - mask |= 1 << regno;
20049 + mask |= 1 << regno;
20050 + offset += 4;
20053 insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
20054 RTX_FRAME_RELATED_P (insn) = 1;
20055 @@ -186,11 +190,17 @@
20057 The rest of the prologue will adjust the SP for the local frame. */
20059 - vax_add_reg_cfa_offset (insn, 4, arg_pointer_rtx);
20060 - vax_add_reg_cfa_offset (insn, 8, frame_pointer_rtx);
20061 - vax_add_reg_cfa_offset (insn, 12, pc_rtx);
20062 + add_reg_note (insn, REG_CFA_DEF_CFA,
20063 + plus_constant (Pmode, frame_pointer_rtx, offset));
20064 + insn = emit_insn (gen_blockage ());
20065 + RTX_FRAME_RELATED_P (insn) = 1;
20067 - offset = 16;
20068 + vax_add_reg_cfa_offset (insn, 4, gen_rtx_REG (Pmode, PSW_REGNUM));
20069 + vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx);
20070 + vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
20071 + vax_add_reg_cfa_offset (insn, 16, pc_rtx);
20073 + offset = 20;
20074 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
20075 if (mask & (1 << regno))
20077 @@ -198,12 +208,6 @@
20078 offset += 4;
20081 - /* Because add_reg_note pushes the notes, adding this last means that
20082 - it will be processed first. This is required to allow the other
20083 - notes be interpreted properly. */
20084 - add_reg_note (insn, REG_CFA_DEF_CFA,
20085 - plus_constant (Pmode, frame_pointer_rtx, offset));
20087 /* Allocate the local stack frame. */
20088 size = get_frame_size ();
20089 size -= STARTING_FRAME_OFFSET;
20090 @@ -354,7 +358,10 @@
20091 addr = XEXP (addr, 1);
20093 else
20094 - gcc_unreachable ();
20096 + debug_rtx (orig);
20097 + gcc_unreachable ();
20100 if (REG_P (addr))
20102 @@ -365,9 +372,8 @@
20104 else if (GET_CODE (addr) == MULT)
20105 ireg = addr;
20106 - else
20107 + else if (GET_CODE (addr) == PLUS)
20109 - gcc_assert (GET_CODE (addr) == PLUS);
20110 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
20111 || MEM_P (XEXP (addr, 0)))
20113 @@ -375,7 +381,7 @@
20115 if (CONST_INT_P (offset))
20116 offset = plus_constant (Pmode, XEXP (addr, 0),
20117 - INTVAL (offset));
20118 + INTVAL (offset));
20119 else
20121 gcc_assert (CONST_INT_P (XEXP (addr, 0)));
20122 @@ -392,12 +398,15 @@
20123 else
20124 reg1 = XEXP (addr, 0);
20126 - else
20127 + else if (GET_CODE (XEXP (addr, 0)) == MULT && !ireg)
20129 - gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT);
20130 - gcc_assert (!ireg);
20131 ireg = XEXP (addr, 0);
20133 + else
20135 + debug_rtx (orig);
20136 + gcc_unreachable ();
20139 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
20140 || MEM_P (XEXP (addr, 1)))
20141 @@ -423,12 +432,20 @@
20142 else
20143 reg1 = XEXP (addr, 1);
20145 - else
20146 + else if (GET_CODE (XEXP (addr, 1)) == MULT && !ireg)
20148 - gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT);
20149 - gcc_assert (!ireg);
20150 ireg = XEXP (addr, 1);
20152 + else
20154 + debug_rtx (orig);
20155 + gcc_unreachable ();
20158 + else
20160 + debug_rtx (orig);
20161 + gcc_unreachable ();
20164 /* If REG1 is nonzero, figure out if it is a base or index register. */
20165 @@ -440,7 +457,11 @@
20166 && (MEM_P (offset)
20167 || (flag_pic && symbolic_operand (offset, SImode)))))
20169 - gcc_assert (!ireg);
20170 + if (ireg)
20172 + debug_rtx (orig);
20173 + gcc_unreachable ();
20175 ireg = reg1;
20177 else
20178 @@ -486,12 +507,17 @@
20180 if (GET_CODE (ireg) == MULT)
20181 ireg = XEXP (ireg, 0);
20182 - gcc_assert (REG_P (ireg));
20183 + if (! REG_P (ireg))
20185 + debug_rtx (orig);
20186 + output_operand_lossage ("non-register index expression");
20188 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
20190 break;
20192 default:
20193 + gcc_assert (! REG_P(addr));
20194 output_addr_const (file, addr);
20197 @@ -546,6 +572,11 @@
20198 sizeof (dstr), 0, 1);
20199 fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr);
20201 + else if (GET_CODE (x) == SUBREG)
20203 + debug_rtx (x);
20204 + output_operand_lossage ("SUBREG operand");
20206 else
20208 if (flag_pic > 1 && symbolic_operand (x, SImode))
20209 @@ -1086,6 +1117,7 @@
20210 case IOR:
20211 case XOR:
20212 case NOT:
20213 + case CTZ:
20214 case MEM:
20215 case REG:
20216 cc_status.flags = CC_NO_OVERFLOW;
20217 @@ -1187,7 +1219,7 @@
20219 operands[1] = GEN_INT (lval);
20220 operands[2] = GEN_INT (n);
20221 - return "ashq %2,%1,%0";
20222 + return "ashq %2,%D1,%0";
20224 #if HOST_BITS_PER_WIDE_INT == 32
20226 @@ -1199,7 +1231,7 @@
20228 operands[1] = GEN_INT (hval >> n);
20229 operands[2] = GEN_INT (n + 32);
20230 - return "ashq %2,%1,%0";
20231 + return "ashq %2,%D1,%0";
20232 #endif
20235 @@ -1261,7 +1293,7 @@
20237 if (operands[1] == const0_rtx)
20239 - if (push_operand (operands[1], SImode))
20240 + if (push_operand (operands[0], SImode))
20241 return "pushl %1";
20242 return "clrl %0";
20244 @@ -1626,6 +1658,111 @@
20248 +static rtx
20249 +mkrtx(enum rtx_code code, enum machine_mode mode, rtx base, HOST_WIDE_INT off)
20251 + rtx tmp;
20253 + if (GET_CODE (base) == CONST)
20254 + base = XEXP (base, 0);
20256 + if (GET_CODE (base) == PLUS)
20258 + rtx a = XEXP (base, 0);
20259 + rtx b = XEXP (base, 1);
20260 + if (GET_CODE (b) == CONST)
20261 + b = XEXP (b, 0);
20262 + if (CONST_INT_P (b))
20264 + off += INTVAL (b);
20265 + base = a;
20267 + else if (REG_P (a) && GET_CODE (b) == SYMBOL_REF)
20269 + if (off != 0)
20271 + base = gen_rtx_PLUS (Pmode, a, plus_constant(Pmode, b, off));
20272 + off = 0;
20275 + else if (REG_P (a) && GET_CODE (b) == PLUS)
20277 + off += INTVAL (XEXP (b, 1));
20278 + base = gen_rtx_PLUS (Pmode, a, plus_constant(Pmode, XEXP (b, 0), off));
20279 + off = 0;
20281 + else
20283 + debug_rtx(base);
20284 + gcc_unreachable ();
20287 + if (code == POST_INC)
20288 + tmp = gen_rtx_POST_INC (SImode, base);
20289 + else if (off == 0 || (REG_P (base) && code == REG))
20290 + tmp = base;
20291 + else
20292 + tmp = plus_constant (Pmode, base, off);
20293 + return gen_rtx_MEM (mode, tmp);
20296 +const char *
20297 +vax_output_movmemsi (rtx insn, rtx *operands)
20299 + HOST_WIDE_INT n = INTVAL (operands[2]);
20300 + HOST_WIDE_INT off;
20301 + rtx src, dest;
20302 + const char *pat = NULL;
20303 + const enum rtx_code *src_codes;
20304 + const enum rtx_code *dest_codes;
20305 + int code_idx = 0;
20306 + int mode_idx;
20308 + static const enum machine_mode xmodes[4] =
20310 + QImode, HImode, SImode, DImode
20311 + };
20312 + static const char * const pats[4] =
20314 + "movb %1,%0", "movw %1,%0", "movl %1,%0", "movq %1,%0",
20315 + };
20316 + static const enum rtx_code codes[2][3] =
20318 + { PLUS, PLUS, PLUS },
20319 + { POST_INC, POST_INC, REG },
20320 + };
20322 + src = XEXP (operands[1], 0);
20324 + src_codes =
20325 + codes[REG_P (src) && find_regno_note (insn, REG_DEAD, REGNO(src))];
20327 + dest = XEXP (operands[0], 0);
20329 + dest_codes =
20330 + codes[REG_P (dest) && find_regno_note (insn, REG_DEAD, REGNO(dest))];
20332 + for (off = 0, code_idx = 0, mode_idx = 3; mode_idx >= 0; mode_idx--)
20334 + const enum machine_mode mode = xmodes[mode_idx];
20335 + const HOST_WIDE_INT mode_len = GET_MODE_SIZE (mode);
20336 + for (; n >= mode_len; n -= mode_len, off += mode_len)
20338 + if (pat != NULL)
20339 + output_asm_insn (pat, operands);
20340 + if (n == mode_len)
20341 + code_idx = 2;
20342 + operands[0] = mkrtx(dest_codes[code_idx], mode, dest, off);
20343 + operands[1] = mkrtx(src_codes[code_idx], mode, src, off);
20344 + if (pat == NULL)
20345 + code_idx = 1;
20346 + pat = pats[mode_idx];
20350 + return pat;
20353 /* True if X is an rtx for a constant that is a valid address. */
20355 bool
20356 @@ -1642,9 +1779,23 @@
20357 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)))
20358 return false;
20359 #endif
20360 + gcc_assert (! REG_P (x));
20361 return true;
20364 +bool
20365 +legitimate_pic_operand_p (rtx x)
20367 +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
20368 + if (GET_CODE (x) != CONST)
20369 + return true;
20370 + if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
20371 + && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)))
20372 + return false;
20373 +#endif
20374 + return true;
20377 /* The other macros defined here are used only in legitimate_address_p (). */
20379 /* Nonzero if X is a hard reg that can be used as an index
20380 @@ -1951,8 +2102,10 @@
20381 and that's just a left shift of 1. */
20382 if (rtx_equal_p (operands[1], operands[2]))
20384 - gcc_assert (code != MINUS);
20385 - emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx));
20386 + if (code == MINUS)
20387 + emit_insn (gen_movdi (operands[0], const0_rtx));
20388 + else
20389 + emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx));
20390 return;
20393 @@ -2173,3 +2326,54 @@
20394 ? (GET_MODE_SIZE (mode) + 3) & ~3
20395 : (int_size_in_bytes (type) + 3) & ~3);
20398 +bool
20399 +vax_decomposed_dimode_operand_p (rtx lo, rtx hi)
20401 + HOST_WIDE_INT lo_offset = 0;
20402 + HOST_WIDE_INT hi_offset = 0;
20404 + /* If the codes aren't the same, can't be a DImode operand. */
20405 + if (GET_CODE (lo) != GET_CODE (hi))
20406 + return false;
20408 + /* If a register, hi regno must be one more than the lo regno. */
20409 + if (REG_P (lo))
20410 + return REGNO (lo) + 1 == REGNO (hi);
20412 + /* If not memory, can't be a DImode operand. */
20413 + if (!MEM_P (lo))
20414 + return false;
20416 + /* Get addresses of memory operands. */
20417 + lo = XEXP(lo, 0);
20418 + hi = XEXP(hi, 0);
20420 + /* If POST_INC, regno must match. */
20421 + if (GET_CODE (lo) == POST_INC && GET_CODE (hi) == POST_INC)
20422 + return REGNO (XEXP (lo, 0)) == REGNO (XEXP (hi, 0));
20424 + if (GET_CODE (lo) == PLUS)
20426 + /* If PLUS or MULT, this must an indexed address so fail. */
20427 + if (GET_CODE (XEXP (lo, 0)) == PLUS
20428 + || GET_CODE (XEXP (lo, 0)) == MULT
20429 + || !CONST_INT_P (XEXP (lo, 1)))
20430 + return false;
20431 + lo_offset = INTVAL (XEXP (lo, 1));
20432 + lo = XEXP(lo, 0);
20435 + if (GET_CODE (hi) == PLUS)
20437 + /* If PLUS or MULT, this must an indexed address so fail. */
20438 + if (GET_CODE (XEXP (hi, 0)) == PLUS
20439 + || GET_CODE (XEXP (hi, 0)) == MULT
20440 + || !CONST_INT_P (XEXP (hi, 1)))
20441 + return false;
20442 + hi_offset = INTVAL (XEXP (hi, 1));
20443 + hi = XEXP(hi, 0);
20446 + return rtx_equal_p(lo, hi) && lo_offset + 4 == hi_offset;
20448 diff -rNU3 dist.orig/gcc/config/vax/vax.h dist/gcc/config/vax/vax.h
20449 --- dist.orig/gcc/config/vax/vax.h 2013-01-10 21:38:27.000000000 +0100
20450 +++ dist/gcc/config/vax/vax.h 2015-10-18 13:19:50.000000000 +0200
20451 @@ -156,6 +156,9 @@
20452 /* Specify the registers used for certain standard purposes.
20453 The values of these macros are register numbers. */
20455 +/* VAX PSW for DWARF-2 */
20456 +#define PSW_REGNUM VAX_PSW_REGNUM
20458 /* VAX pc is overloaded on a register. */
20459 #define PC_REGNUM VAX_PC_REGNUM
20461 @@ -370,6 +373,10 @@
20462 RETURN_ADDRESS_OFFSET)) \
20463 : (rtx) 0)
20465 +/* A C expression that is nonzero if X is a legitimate immediate operand
20466 + on the target machine when generating position independent code. */
20468 +#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
20470 /* Addressing modes, and classification of registers for them. */
20472 diff -rNU3 dist.orig/gcc/config/vax/vax.md dist/gcc/config/vax/vax.md
20473 --- dist.orig/gcc/config/vax/vax.md 2013-01-15 22:30:24.000000000 +0100
20474 +++ dist/gcc/config/vax/vax.md 2015-10-18 13:19:50.000000000 +0200
20475 @@ -40,6 +40,7 @@
20476 (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer
20477 (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer
20478 (VAX_PC_REGNUM 15) ; Register 15 contains the program counter
20479 + (VAX_PSW_REGNUM 16) ; Program Status Word
20483 @@ -215,6 +216,11 @@
20487 + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48)
20489 + emit_insn (gen_movmemsi1_2 (operands[0], operands[1], operands[2]));
20490 + DONE;
20492 emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
20493 DONE;
20495 @@ -224,6 +230,13 @@
20496 ;; that anything generated as this insn will be recognized as one
20497 ;; and that it won't successfully combine with anything.
20499 +(define_insn "movmemsi1_2"
20500 + [(set (match_operand:BLK 0 "memory_operand" "=B")
20501 + (match_operand:BLK 1 "memory_operand" "B"))
20502 + (use (match_operand:SI 2 "const_int_operand" "g"))]
20503 + "INTVAL (operands[2]) <= 48"
20504 + "* return vax_output_movmemsi (insn, operands);")
20506 (define_insn "movmemhi1"
20507 [(set (match_operand:BLK 0 "memory_operand" "=o")
20508 (match_operand:BLK 1 "memory_operand" "o"))
20509 @@ -633,7 +646,7 @@
20513 - if (! CONST_INT_P(operands[2]))
20514 + if (! CONST_INT_P (operands[2]))
20515 operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
20518 @@ -697,14 +710,14 @@
20519 (ashift:DI (match_operand:DI 1 "general_operand" "g")
20520 (match_operand:QI 2 "general_operand" "g")))]
20522 - "ashq %2,%1,%0")
20523 + "ashq %2,%D1,%0")
20525 (define_insn ""
20526 [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
20527 (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
20528 (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
20530 - "ashq %2,%1,%0")
20531 + "ashq %2,%D1,%0")
20533 ;; We used to have expand_shift handle logical right shifts by using extzv,
20534 ;; but this make it very difficult to do lshrdi3. Since the VAX is the
20535 @@ -781,8 +794,9 @@
20536 "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
20537 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
20538 && (REG_P (operands[0])
20539 - || ! mode_dependent_address_p (XEXP (operands[0], 0),
20540 - MEM_ADDR_SPACE (operands[0])))"
20541 + || (MEM_P (operands[0])
20542 + && ! mode_dependent_address_p (XEXP (operands[0], 0),
20543 + MEM_ADDR_SPACE (operands[0]))))"
20546 if (REG_P (operands[0]))
20547 @@ -810,8 +824,9 @@
20548 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
20549 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
20550 && (REG_P (operands[1])
20551 - || ! mode_dependent_address_p (XEXP (operands[1], 0),
20552 - MEM_ADDR_SPACE (operands[1])))"
20553 + || (MEM_P (operands[1])
20554 + && ! mode_dependent_address_p (XEXP (operands[1], 0),
20555 + MEM_ADDR_SPACE (operands[1]))))"
20558 if (REG_P (operands[1]))
20559 @@ -838,8 +853,9 @@
20560 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
20561 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
20562 && (REG_P (operands[1])
20563 - || ! mode_dependent_address_p (XEXP (operands[1], 0),
20564 - MEM_ADDR_SPACE (operands[1])))"
20565 + || (MEM_P (operands[1])
20566 + && ! mode_dependent_address_p (XEXP (operands[1], 0),
20567 + MEM_ADDR_SPACE (operands[1]))))"
20570 if (REG_P (operands[1]))
20571 @@ -956,8 +972,8 @@
20575 - if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
20576 - || !CONST_INT_P (operands[3])
20577 + if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
20578 + || ! CONST_INT_P (operands[3])
20579 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
20580 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
20581 || side_effects_p (operands[1])
20582 @@ -986,8 +1002,8 @@
20586 - if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
20587 - || !CONST_INT_P (operands[3])
20588 + if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
20589 + || ! CONST_INT_P (operands[3])
20590 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
20591 || side_effects_p (operands[1])
20592 || (MEM_P (operands[1])
20593 @@ -1660,3 +1676,50 @@
20594 emit_barrier ();
20595 DONE;
20598 +(include "builtins.md")
20600 +(define_peephole2
20601 + [(set (match_operand:SI 0 "push_operand" "")
20602 + (const_int 0))
20603 + (set (match_dup 0)
20604 + (match_operand:SI 1 "const_int_operand" ""))]
20605 + "INTVAL (operands[1]) >= 0"
20606 + [(set (match_dup 0)
20607 + (match_dup 1))]
20608 + "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
20610 +(define_peephole2
20611 + [(set (match_operand:SI 0 "push_operand" "")
20612 + (match_operand:SI 1 "general_operand" ""))
20613 + (set (match_dup 0)
20614 + (match_operand:SI 2 "general_operand" ""))]
20615 + "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
20616 + [(set (match_dup 0)
20617 + (match_dup 2))]
20618 + "{
20619 + operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
20620 + operands[2] = REG_P (operands[2])
20621 + ? gen_rtx_REG(DImode, REGNO (operands[2]))
20622 + : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
20623 +}")
20625 +; Leave this commented out until we can determine whether the second move
20626 +; precedes a jump which relies on the CC flags being set correctly.
20627 +(define_peephole2
20628 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
20629 + (match_operand:SI 1 "general_operand" ""))
20630 + (set (match_operand:SI 2 "nonimmediate_operand" "")
20631 + (match_operand:SI 3 "general_operand" ""))]
20632 + "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
20633 + && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
20634 + [(set (match_dup 0)
20635 + (match_dup 1))]
20636 + "{
20637 + operands[0] = REG_P (operands[0])
20638 + ? gen_rtx_REG(DImode, REGNO (operands[0]))
20639 + : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
20640 + operands[1] = REG_P (operands[1])
20641 + ? gen_rtx_REG(DImode, REGNO (operands[1]))
20642 + : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
20643 +}")
20644 diff -rNU3 dist.orig/gcc/config/x-netbsd dist/gcc/config/x-netbsd
20645 --- dist.orig/gcc/config/x-netbsd 1970-01-01 01:00:00.000000000 +0100
20646 +++ dist/gcc/config/x-netbsd 2015-10-18 13:19:50.000000000 +0200
20647 @@ -0,0 +1,4 @@
20648 +host-netbsd.o : $(srcdir)/config/host-netbsd.c $(CONFIG_H) $(SYSTEM_H) \
20649 + coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H)
20650 + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
20651 + $(srcdir)/config/host-netbsd.c
20652 diff -rNU3 dist.orig/gcc/config.gcc dist/gcc/config.gcc
20653 --- dist.orig/gcc/config.gcc 2015-05-21 22:57:29.000000000 +0200
20654 +++ dist/gcc/config.gcc 2015-10-18 13:19:50.000000000 +0200
20655 @@ -325,6 +325,7 @@
20657 arm*-*-*)
20658 cpu_type=arm
20659 + need_64bit_hwint=yes
20660 extra_headers="mmintrin.h arm_neon.h"
20661 target_type_format_char='%'
20662 c_target_objs="arm-c.o"
20663 @@ -401,6 +402,16 @@
20664 cpu_type=m32r
20665 extra_options="${extra_options} g.opt"
20667 +m5200-*-*|m5407-*-*)
20668 + cpu_type=m68k
20669 + extra_headers=math-68881.h
20670 + extra_options="${extra_options} m68k/m68k-tables.opt"
20671 + ;;
20672 +m680[012]0-*-*)
20673 + cpu_type=m68k
20674 + extra_headers=math-68881.h
20675 + extra_options="${extra_options} m68k/m68k-tables.opt"
20676 + ;;
20677 m68k-*-*)
20678 extra_headers=math-68881.h
20679 extra_options="${extra_options} m68k/m68k-tables.opt"
20680 @@ -415,6 +426,12 @@
20681 extra_headers="loongson.h"
20682 extra_options="${extra_options} g.opt mips/mips-tables.opt"
20684 +or1k-*-*)
20685 + cpu_type=or1k
20686 + ;;
20687 +or1knd-*-*)
20688 + cpu_type=or1k
20689 + ;;
20690 picochip-*-*)
20691 cpu_type=picochip
20693 @@ -429,6 +446,10 @@
20694 esac
20695 extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
20697 +riscv*-*-*)
20698 + cpu_type=riscv
20699 + need_64bit_hwint=yes
20700 + ;;
20701 rs6000*-*-*)
20702 need_64bit_hwint=yes
20703 extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
20704 @@ -712,6 +733,7 @@
20705 default_use_cxa_atexit=yes
20707 esac
20708 + nbsd_tm_file="${nbsd_tm_file} netbsd.h netbsd-stdint.h netbsd-elf.h"
20710 *-*-openbsd*)
20711 tmake_file="t-openbsd"
20712 @@ -846,7 +868,7 @@
20713 extra_options="${extra_options} alpha/elf.opt"
20715 alpha*-*-netbsd*)
20716 - tm_file="elfos.h ${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
20717 + tm_file="elfos.h ${tm_file} ${nbsd_tm_file} alpha/elf.h alpha/netbsd.h"
20718 extra_options="${extra_options} netbsd.opt netbsd-elf.opt \
20719 alpha/elf.opt"
20721 @@ -866,9 +888,38 @@
20722 tmake_file="${tmake_file} arm/t-arm arm/t-vxworks"
20724 arm*-*-netbsdelf*)
20725 - tm_file="dbxelf.h elfos.h netbsd.h netbsd-elf.h arm/elf.h arm/aout.h ${tm_file} arm/netbsd-elf.h"
20726 - extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20727 tmake_file="${tmake_file} arm/t-arm"
20728 + tm_file="dbxelf.h elfos.h ${nbsd_tm_file} arm/elf.h arm/aout.h arm/arm.h"
20729 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20730 + case ${target} in
20731 + arm*eb-*) tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" ;;
20732 + esac
20733 + case ${target} in
20734 + arm*-*-netbsdelf-*eabi*)
20735 + tm_file="$tm_file arm/bpabi.h arm/netbsd-elf.h arm/netbsd-eabi.h"
20736 + tmake_file="$tmake_file arm/t-bpabi arm/t-netbsdeabi"
20737 + # The BPABI long long divmod functions return a 128-bit value in
20738 + # registers r0-r3. Correctly modeling that requires the use of
20739 + # TImode.
20740 + need_64bit_hwint=yes
20741 + # The EABI requires the use of __cxa_atexit.
20742 + default_use_cxa_atexit=yes
20743 + ;;
20744 + *)
20745 + tm_file="$tm_file arm/netbsd-elf.h"
20746 + tmake_file="$tmake_file arm/t-netbsd"
20747 + ;;
20748 + esac
20749 + case ${target} in
20750 + arm*-*-netbsdelf-*eabihf*)
20751 + tm_defines="${tm_defines} TARGET_DEFAULT_FLOAT_ABI=ARM_FLOAT_ABI_HARD"
20752 + ;;
20753 + esac
20754 + case ${target} in
20755 + armv4*) with_cpu=${with_cpu:-strongarm};;
20756 + armv6*) with_cpu=${with_cpu:-arm1176jzf-s};;
20757 + armv7*) with_cpu=${with_cpu:-cortex-a8};;
20758 + esac
20760 arm*-*-linux-*) # ARM GNU/Linux with ELF
20761 tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arm/elf.h arm/linux-gas.h arm/linux-elf.h"
20762 @@ -1077,6 +1128,14 @@
20763 gas=yes
20764 gnu_ld=yes
20766 +hppa*-*-netbsd* | parisc*-*-netbsd*)
20767 + target_cpu_default="MASK_PA_11|MASK_NO_SPACE_REGS"
20768 + tm_file="${tm_file} dbxelf.h elfos.h ${nbsd_tm_file} \
20769 + pa/pa-netbsd.h pa/pa32-regs.h pa/pa32-netbsd.h"
20770 + tmake_file="${tmake_file} pa/t-netbsd"
20771 + tm_defines="${tm_defines} CHAR_FAST8=1 SHORT_FAST16=1"
20772 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20773 + ;;
20774 hppa[12]*-*-hpux10*)
20775 case ${target} in
20776 hppa1.1-*-* | hppa2*-*-*)
20777 @@ -1229,11 +1288,20 @@
20778 tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${fbsd_tm_file} i386/x86-64.h i386/freebsd.h i386/freebsd64.h"
20780 i[34567]86-*-netbsdelf*)
20781 - tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/netbsd-elf.h"
20782 + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${nbsd_tm_file} i386/netbsd-elf.h"
20783 + tmake_file="${tmake_file} i386/t-crtstuff"
20784 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20786 +i[34567]86-*-netbsd*)
20787 + tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h netbsd.h netbsd-aout.h i386/netbsd.h"
20788 + tmake_file="${tmake_file} t-netbsd"
20789 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20790 + extra_parts=""
20791 + use_collect2=yes
20792 + ;;
20793 x86_64-*-netbsd*)
20794 - tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/x86-64.h i386/netbsd64.h"
20795 + tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${nbsd_tm_file} i386/x86-64.h i386/netbsd64.h"
20796 + tmake_file="${tmake_file} i386/t-netbsd64"
20797 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20799 i[34567]86-*-openbsd2.*|i[34567]86-*openbsd3.[0123])
20800 @@ -1563,6 +1631,16 @@
20801 target_cpu_default="${target_cpu_default}|MASK_GNU_LD"
20804 +ia64*-*-netbsd*)
20805 + tm_file="${tm_file} dbxelf.h elfos.h ${nbsd_tm_file} ia64/sysv4.h ia64/netbsd.h"
20806 + target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
20807 + tmake_file="${tmake_file} ia64/t-ia64"
20808 + if test x$with_system_libunwind != xyes ; then
20809 + tmake_file="${tmake_file} t-libunwind-elf ia64/t-glibc-libunwind"
20810 + fi
20811 + extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
20812 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20813 + ;;
20814 ia64*-*-freebsd*)
20815 tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} ia64/sysv4.h ia64/freebsd.h"
20816 target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
20817 @@ -1682,12 +1760,30 @@
20819 esac
20821 -m68k*-*-netbsdelf*)
20822 - default_m68k_cpu=68020
20823 - default_cf_cpu=5475
20824 - tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
20825 +m68010-*-netbsdelf* | m68k-*-netbsdelf* | m5407-*-netbsdelf*)
20826 + tm_file="${tm_file} dbxelf.h elfos.h ${nbsd_tm_file} m68k/netbsd-elf.h"
20827 + tm_defines="${tm_defines} MOTOROLA=1 USE_GAS=1"
20828 + tm_defines="${tm_defines} CHAR_FAST8=1 SHORT_FAST16=1"
20829 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20830 - tm_defines="${tm_defines} MOTOROLA=1"
20831 + default_cf_cpu=5475
20832 + default_m68k_cpu=68020
20833 + case ${target} in
20834 + m5407*)
20835 + with_arch=${with_arch:-cf}
20836 + target_cpu_default="mcf5475"
20837 +# target="`echo ${target} | sed 's/m68kcf/m68k/'`"
20838 + ;;
20839 + m68010*)
20840 + target_cpu_default="m68010"
20841 + tmake_file="m68k/t-m68kelf m68k/t-m68010-netbsd"
20842 + default_m68k_cpu=68010
20843 + tmake_file="${tmake_file} m68k/t-floatlib"
20844 + ;;
20845 + *)
20846 + with_arch=${with_arch:-m68k}
20847 + tmake_file="${tmake_file} m68k/t-floatlib"
20848 + ;;
20849 + esac
20851 m68k*-*-openbsd*)
20852 default_m68k_cpu=68020
20853 @@ -1790,9 +1886,16 @@
20854 cxx_target_objs="${cxx_target_objs} microblaze-c.o"
20855 tmake_file="${tmake_file} microblaze/t-microblaze"
20857 +mips64*-*-netbsd*) # NetBSD/mips64, either endian.
20858 + target_cpu_default="MASK_ABICALLS|MASK_FLOAT64|MASK_SOFT_FLOAT_ABI"
20859 + tm_file="elfos.h ${tm_file} mips/elf.h ${nbsd_tm_file} mips/netbsd.h mips/netbsd64.h"
20860 + tmake_file="${tmake_file} mips/t-netbsd64"
20861 + tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
20862 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20863 + ;;
20864 mips*-*-netbsd*) # NetBSD/mips, either endian.
20865 target_cpu_default="MASK_ABICALLS"
20866 - tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h"
20867 + tm_file="elfos.h ${tm_file} mips/elf.h ${nbsd_tm_file} mips/netbsd.h"
20868 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20870 mips*-mti-linux*)
20871 @@ -1972,6 +2075,42 @@
20872 use_collect2=no
20873 use_gcc_stdint=wrap
20875 +or1k*-*-elf*)
20876 + tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h ${cpu_type}/elf.h"
20877 + extra_parts="crti.o crtbegin.o crtend.o crtn.o"
20878 + case ${target} in
20879 + or1knd-*)
20880 + tmake_file=or1k/t-or1knd
20881 + tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_OFF"
20882 + ;;
20883 + *)
20884 + tmake_file=or1k/t-or1k
20885 + tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON"
20886 + ;;
20887 + esac
20888 + ;;
20889 +or1k*-*-linux-*)
20890 + tm_file="${tm_file} dbxelf.h elfos.h or1k/elf.h gnu-user.h linux.h or1k/linux-gas.h or1k/linux-elf.h uclibc-stdint.h"
20891 + case ${target} in
20892 + or1knd-*)
20893 + tmake_file="or1k/t-or1knd or1k/t-linux ${tmake_file}"
20894 + tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_OFF"
20895 + ;;
20896 + *)
20897 + tmake_file="or1k/t-or1k or1k/t-linux ${tmake_file}"
20898 + tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON"
20899 + ;;
20900 + esac
20901 + ;;
20902 +or1k*-*-netbsd*)
20903 + tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h netbsd-stdint.h or1k/netbsd.h"
20904 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20905 + case ${target} in
20906 + or1knd-*) tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_OFF" ;;
20907 + *) tm_defines="${tm_defines} OR1K_DELAY_DEFAULT=OR1K_DELAY_ON" ;;
20908 + esac
20909 + gcc_cv_initfini_array=yes
20910 + ;;
20911 pdp11-*-*)
20912 tm_file="${tm_file} newlib-stdint.h"
20913 use_gcc_stdint=wrap
20914 @@ -2023,11 +2162,24 @@
20916 esac
20918 -powerpc-*-netbsd*)
20919 - tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h freebsd-spec.h rs6000/sysv4.h rs6000/netbsd.h"
20920 +powerpc*-*-netbsd*)
20921 + tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h"
20922 + tm_file="${tm_file} netbsd.h netbsd-elf.h"
20923 + case ${target} in
20924 + powerpc64*)
20925 + tm_file="rs6000/biarch64.h ${tm_file} rs6000/sysv4.h rs6000/default64.h rs6000/netbsd64.h"
20926 + tmake_file="${tmake_file} rs6000/t-netbsd64"
20927 + ;;
20928 + *)
20929 + tm_file="${tm_file} rs6000/sysv4.h rs6000/netbsd.h"
20930 + tmake_file="${tmake_file} rs6000/t-netbsd"
20931 + ;;
20932 + esac
20933 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20934 - tmake_file="${tmake_file} rs6000/t-netbsd"
20935 - extra_options="${extra_options} rs6000/sysv4.opt"
20936 + if test x${enable_secureplt} != xno; then
20937 + tm_file="rs6000/secureplt.h ${tm_file}"
20938 + fi
20939 + extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt"
20941 powerpc-*-eabispe*)
20942 tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabispe.h"
20943 @@ -2190,6 +2342,31 @@
20944 extra_options="${extra_options} rs6000/sysv4.opt"
20945 use_gcc_stdint=wrap
20947 +riscv*-*-linux*) # Linux RISC-V
20948 + tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h riscv/linux64.h"
20949 + tmake_file="${tmake_file} riscv/t-linux64"
20950 + gnu_ld=yes
20951 + gas=yes
20952 + gcc_cv_initfini_array=yes
20953 + ;;
20954 +riscv*-*-elf*) # Linux RISC-V
20955 + tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
20956 + tmake_file="${tmake_file} riscv/t-elf"
20957 + gnu_ld=yes
20958 + gas=yes
20959 + gcc_cv_initfini_array=yes
20960 + ;;
20961 +riscv*-*-netbsd*) # NetBSD RISC-V
20962 + tm_file="elfos.h ${tm_file} netbsd.h netbsd-elf.h riscv/netbsd.h"
20963 + case ${target} in
20964 + riscv32*) tm_defines="${tm_defines} TARGET_64BIT_DEFAULT=0" ;;
20965 + *) tmake_file="${tmake_file} riscv/t-netbsd64" ;;
20966 + esac
20967 + extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20968 + gnu_ld=yes
20969 + gas=yes
20970 + gcc_cv_initfini_array=yes
20971 + ;;
20972 rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
20973 tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h rs6000/aix-stdint.h"
20974 tmake_file="rs6000/t-aix43 t-slibgcc"
20975 @@ -2310,7 +2487,7 @@
20976 sh*-*-linux*) tmake_file="${tmake_file} sh/t-linux"
20977 tm_file="${tm_file} gnu-user.h linux.h glibc-stdint.h sh/linux.h" ;;
20978 sh*-*-netbsd*)
20979 - tm_file="${tm_file} netbsd.h netbsd-elf.h sh/netbsd-elf.h"
20980 + tm_file="${tm_file} ${nbsd_tm_file} sh/netbsd-elf.h"
20981 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
20984 @@ -2336,7 +2513,8 @@
20985 # SHmedia, 64-bit ABI
20986 tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd-sh5-64"
20988 - *-*-netbsd)
20989 + *-*-netbsd*)
20990 + tmake_file="${tmake_file} sh/t-netbsd"
20992 sh64*-*-linux*)
20993 tmake_file="${tmake_file} sh/t-sh64"
20994 @@ -2501,7 +2679,7 @@
20997 sparc-*-netbsdelf*)
20998 - tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
20999 + tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h ${nbsd_tm_file} sparc/netbsd-elf.h"
21000 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
21001 extra_options="${extra_options} sparc/long-double-switch.opt"
21002 tmake_file="${tmake_file} sparc/t-sparc"
21003 @@ -2549,10 +2727,11 @@
21005 sparc64-*-netbsd*)
21006 tm_file="sparc/biarch64.h ${tm_file}"
21007 - tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
21008 + tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h ${nbsd_tm_file} sparc/netbsd-elf.h"
21009 extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
21010 extra_options="${extra_options} sparc/long-double-switch.opt"
21011 tmake_file="${tmake_file} sparc/t-sparc sparc/t-netbsd64"
21012 + with_cpu=ultrasparc
21014 sparc64-*-openbsd*)
21015 tm_file="sparc/openbsd1-64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp64-elf.h"
21016 @@ -2648,7 +2827,8 @@
21017 extra_options="${extra_options} vax/elf.opt"
21019 vax-*-netbsdelf*)
21020 - tm_file="${tm_file} elfos.h netbsd.h netbsd-elf.h vax/elf.h vax/netbsd-elf.h"
21021 + tm_file="${tm_file} elfos.h ${nbsd_tm_file} vax/elf.h vax/netbsd-elf.h"
21022 + tm_defines="${tm_defines} CHAR_FAST8=1 SHORT_FAST16=1"
21023 extra_options="${extra_options} netbsd.opt netbsd-elf.opt vax/elf.opt"
21025 vax-*-openbsd*)
21026 @@ -2974,6 +3154,9 @@
21027 frv550-*-*linux*)
21028 with_cpu=fr550
21030 + m5200-*-*|m5407-*-*)
21031 + with_cpu=${default_cf_cpu}
21032 + ;;
21033 m68k*-*-*)
21034 case "$with_arch" in
21035 "cf")
21036 @@ -3355,7 +3538,7 @@
21037 esac
21040 - fido-*-* | m68k*-*-*)
21041 + fido-*-* | m68k*-*-* | m5200-*-* | m5407-*-*)
21042 supported_defaults="arch cpu"
21043 case "$with_arch" in
21044 "" | "m68k"| "cf")
21045 @@ -3589,6 +3772,30 @@
21046 esac
21049 + riscv*-*-*)
21050 + supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64"
21052 + case ${with_float} in
21053 + "" | soft | hard)
21054 + # OK
21055 + ;;
21056 + *)
21057 + echo "Unknown floating point type used in --with-float=$with_float" 1>&2
21058 + exit 1
21059 + ;;
21060 + esac
21062 + case ${with_abi} in
21063 + "" | 32 | 64)
21064 + # OK
21065 + ;;
21066 + *)
21067 + echo "Unknown ABI used in --with-abi=$with_abi" 1>&2
21068 + exit 1
21069 + ;;
21070 + esac
21071 + ;;
21073 s390*-*-*)
21074 supported_defaults="arch mode tune"
21076 diff -rNU3 dist.orig/gcc/config.host dist/gcc/config.host
21077 --- dist.orig/gcc/config.host 2013-01-10 21:38:27.000000000 +0100
21078 +++ dist/gcc/config.host 2015-10-18 13:19:50.000000000 +0200
21079 @@ -214,7 +214,7 @@
21081 esac
21083 - i[34567]86-*-cygwin*)
21084 + i[34567]86-*-cygwin* | x86_64-*-cygwin*)
21085 host_xm_file=i386/xm-cygwin.h
21086 out_host_hook_obj=host-cygwin.o
21087 host_xmake_file="${host_xmake_file} i386/x-cygwin"
21088 @@ -271,6 +271,10 @@
21089 out_host_hook_obj=host-openbsd.o
21090 host_xmake_file="${host_xmake_file} x-openbsd"
21092 + *-*-netbsd*)
21093 + out_host_hook_obj=host-netbsd.o
21094 + host_xmake_file="${host_xmake_file} x-netbsd"
21095 + ;;
21096 ia64-*-hpux*)
21097 use_long_long_for_widest_fast_int=yes
21098 out_host_hook_obj=host-hpux.o
21099 diff -rNU3 dist.orig/gcc/configure dist/gcc/configure
21100 --- dist.orig/gcc/configure 2014-12-08 12:29:43.000000000 +0100
21101 +++ dist/gcc/configure 2015-10-18 13:19:50.000000000 +0200
21102 @@ -3031,7 +3031,7 @@
21103 for ac_t in install-sh install.sh shtool; do
21104 if test -f "$ac_dir/$ac_t"; then
21105 ac_aux_dir=$ac_dir
21106 - ac_install_sh="$ac_aux_dir/$ac_t -c"
21107 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
21108 break 2
21110 done
21111 @@ -23105,7 +23105,7 @@
21112 tls_first_major=2
21113 tls_first_minor=14
21115 - hppa*-*-linux*)
21116 + hppa*-*-linux* | hppa*-*-netbsd*)
21117 conftest_s='
21118 t1: .reg %r20
21119 t2: .reg %r21
21120 @@ -23253,7 +23253,7 @@
21121 tls_first_minor=16
21122 tls_as_opt='-32 --fatal-warnings'
21124 - m68k-*-*)
21125 + m68k-*-*|m5407-*-*)
21126 conftest_s='
21127 .section .tdata,"awT",@progbits
21129 @@ -23360,6 +23360,25 @@
21130 tls_first_minor=14
21131 tls_as_opt="-a32 --fatal-warnings"
21133 + riscv*-*-*)
21134 + conftest_s='
21135 + .section .tdata,"awT",@progbits
21137 + .word 2
21138 + .text
21139 + la.tls.gd a0,x
21140 + la.tls.ie a1,x
21141 + lui a0,%tls_ie_pcrel_hi(x)
21142 + lw a0,%pcrel_lo(x)(a0)
21143 + add a0,a0,tp
21144 + lw a0,(a0)
21145 + lui a0,%tprel_hi(x)
21146 + add a0,a0,tp,%tprel_add(x)
21147 + lw a0,%tprel_lo(x)(a0)'
21148 + tls_first_major=2
21149 + tls_first_minor=21
21150 + tls_as_opt='-m32 --fatal-warnings'
21151 + ;;
21152 s390-*-*)
21153 conftest_s='
21154 .section ".tdata","awT",@progbits
21155 @@ -23397,7 +23416,7 @@
21156 tls_first_minor=14
21157 tls_as_opt="-m64 -Aesame --fatal-warnings"
21159 - sh-*-* | sh[34]-*-*)
21160 + sh-*-* | sh[34]-*-* | sh*l*-*-*)
21161 conftest_s='
21162 .section ".tdata","awT",@progbits
21163 foo: .long 25
21164 @@ -26886,7 +26905,7 @@
21165 # simply assert that glibc does provide this, which is true for all
21166 # realistically usable GNU/Hurd configurations.
21167 gcc_cv_libc_provides_ssp=yes;;
21168 - *-*-darwin* | *-*-freebsd*)
21169 + *-*-darwin* | *-*-freebsd* | *-*-netbsd*)
21170 ac_fn_c_check_func "$LINENO" "__stack_chk_fail" "ac_cv_func___stack_chk_fail"
21171 if test "x$ac_cv_func___stack_chk_fail" = x""yes; then :
21172 gcc_cv_libc_provides_ssp=yes
21173 @@ -28921,5 +28940,3 @@
21174 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
21175 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
21179 diff -rNU3 dist.orig/gcc/configure.ac dist/gcc/configure.ac
21180 --- dist.orig/gcc/configure.ac 2014-12-08 12:29:43.000000000 +0100
21181 +++ dist/gcc/configure.ac 2015-10-18 13:19:50.000000000 +0200
21182 @@ -2852,7 +2852,7 @@
21183 tls_first_major=2
21184 tls_first_minor=14
21186 - hppa*-*-linux*)
21187 + hppa*-*-linux* | hppa*-*-netbsd*)
21188 conftest_s='
21189 t1: .reg %r20
21190 t2: .reg %r21
21191 @@ -3001,7 +3001,7 @@
21192 tls_first_minor=16
21193 tls_as_opt='-32 --fatal-warnings'
21195 - m68k-*-*)
21196 + m68k-*-* | m5407-*-*)
21197 conftest_s='
21198 .section .tdata,"awT",@progbits
21200 @@ -3108,6 +3108,25 @@
21201 tls_first_minor=14
21202 tls_as_opt="-a32 --fatal-warnings"
21204 + riscv*-*-*)
21205 + conftest_s='
21206 + .section .tdata,"awT",@progbits
21208 + .word 2
21209 + .text
21210 + la.tls.gd a0,x
21211 + la.tls.ie a1,x
21212 + lui a0,%tls_ie_pcrel_hi(x)
21213 + lw a0,%pcrel_lo(x)(a0)
21214 + add a0,a0,tp
21215 + lw a0,0(a0)
21216 + lui a0,%tprel_hi(x)
21217 + add a0,a0,tp,%tprel_add(x)
21218 + lw a0,%tprel_lo(x)(a0)'
21219 + tls_first_major=2
21220 + tls_first_minor=21
21221 + tls_as_opt='-m32 --fatal-warnings'
21222 + ;;
21223 s390-*-*)
21224 conftest_s='
21225 .section ".tdata","awT",@progbits
21226 @@ -3145,7 +3164,7 @@
21227 tls_first_minor=14
21228 tls_as_opt="-m64 -Aesame --fatal-warnings"
21230 - sh-*-* | sh[34]-*-*)
21231 + sh-*-* | sh[34]-*-* | sh*l*-*-*)
21232 conftest_s='
21233 .section ".tdata","awT",@progbits
21234 foo: .long 25
21235 @@ -4810,7 +4829,7 @@
21236 # simply assert that glibc does provide this, which is true for all
21237 # realistically usable GNU/Hurd configurations.
21238 gcc_cv_libc_provides_ssp=yes;;
21239 - *-*-darwin* | *-*-freebsd*)
21240 + *-*-darwin* | *-*-freebsd* | *-*-netbsd*)
21241 AC_CHECK_FUNC(__stack_chk_fail,[gcc_cv_libc_provides_ssp=yes],
21242 [echo "no __stack_chk_fail on this target"])
21244 diff -rNU3 dist.orig/gcc/cp/Make-lang.in dist/gcc/cp/Make-lang.in
21245 --- dist.orig/gcc/cp/Make-lang.in 2013-01-10 21:38:27.000000000 +0100
21246 +++ dist/gcc/cp/Make-lang.in 2015-10-18 13:19:50.000000000 +0200
21247 @@ -95,7 +95,7 @@
21248 $(CXX_OBJS) $(BACKEND) $(LIBDEPS)
21249 build/genchecksum$(build_exeext) $(CXX_OBJS) $(BACKEND) $(LIBDEPS) \
21250 checksum-options > cc1plus-checksum.c.tmp && \
21251 - $(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c
21252 + $(SHELL) $(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c
21254 cc1plus-checksum.o : cc1plus-checksum.c $(CONFIG_H) $(SYSTEM_H)
21256 @@ -109,6 +109,8 @@
21257 # other cases, it is not available to avoid triggering rebuilds if a
21258 # user has the source checked out with unusual timestamps.
21259 $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
21260 + @echo "NOT REBUILDING $@"
21261 +NetBSD_DISABLED_cfns.h:
21262 else
21263 # We keep the rule so that you can still force a rebuild, even if you
21264 # didn't configure GCC with --enable-maintainer-mode, by manually
21265 diff -rNU3 dist.orig/gcc/cppdefault.c dist/gcc/cppdefault.c
21266 --- dist.orig/gcc/cppdefault.c 2013-01-10 21:38:27.000000000 +0100
21267 +++ dist/gcc/cppdefault.c 2015-10-18 13:19:50.000000000 +0200
21268 @@ -56,8 +56,12 @@
21269 GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 0 },
21270 #endif
21271 #ifdef GCC_INCLUDE_DIR
21272 +#ifndef GCC_INCLUDE_DIR_ADD_SYSROOT
21273 +#define GCC_INCLUDE_DIR_ADD_SYSROOT 0
21274 +#endif
21275 /* This is the dir for gcc's private headers. */
21276 - { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
21277 + { GCC_INCLUDE_DIR, "GCC", 0, 0,
21278 + GCC_INCLUDE_DIR_ADD_SYSROOT, 0 },
21279 #endif
21280 #ifdef LOCAL_INCLUDE_DIR
21281 /* /usr/local/include comes before the fixincluded header files. */
21282 diff -rNU3 dist.orig/gcc/doc/cpp.texi dist/gcc/doc/cpp.texi
21283 --- dist.orig/gcc/doc/cpp.texi 2015-06-23 09:35:08.000000000 +0200
21284 +++ dist/gcc/doc/cpp.texi 2015-10-18 13:19:51.000000000 +0200
21285 @@ -1159,6 +1159,9 @@
21286 @option{-isystem}, the @option{-I} option is ignored. GCC provides an
21287 informative message when this occurs if @option{-v} is used.
21289 +The @option{-cxx-isystem} command line option adds its argument to the
21290 +list of C++ system headers, similar to @option{-isystem} for C headers.
21292 @findex #pragma GCC system_header
21293 There is also a directive, @code{@w{#pragma GCC system_header}}, which
21294 tells GCC to consider the rest of the current include file a system
21295 @@ -4397,6 +4400,7 @@
21296 @c man begin SYNOPSIS
21297 cpp [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
21298 [@option{-I}@var{dir}@dots{}] [@option{-iquote}@var{dir}@dots{}]
21299 + [@option{-iremap}@var{src}:@var{dst}]
21300 [@option{-W}@var{warn}@dots{}]
21301 [@option{-M}|@option{-MM}] [@option{-MG}] [@option{-MF} @var{filename}]
21302 [@option{-MP}] [@option{-MQ} @var{target}@dots{}]
21303 diff -rNU3 dist.orig/gcc/doc/cppenv.texi dist/gcc/doc/cppenv.texi
21304 --- dist.orig/gcc/doc/cppenv.texi 2013-01-10 21:38:27.000000000 +0100
21305 +++ dist/gcc/doc/cppenv.texi 2015-10-18 13:19:51.000000000 +0200
21306 @@ -79,4 +79,17 @@
21307 @ifclear cppmanual
21308 @xref{Preprocessor Options}.
21309 @end ifclear
21311 +@item CPP_RESTRICTED
21312 +@cindex only open regular files
21313 +If this variable is defined, cpp will skip any include file which is not a
21314 +regular file, and will continue searching for the requested name (this is
21315 +always done if the found file is a directory).
21316 +@ifset cppmanual
21317 +@xref{Invocation}.
21318 +@end ifset
21319 +@ifclear cppmanual
21320 +@xref{Preprocessor Options}.
21321 +@end ifclear
21323 @end vtable
21324 diff -rNU3 dist.orig/gcc/doc/cppopts.texi dist/gcc/doc/cppopts.texi
21325 --- dist.orig/gcc/doc/cppopts.texi 2013-01-10 21:38:27.000000000 +0100
21326 +++ dist/gcc/doc/cppopts.texi 2015-10-18 13:19:51.000000000 +0200
21327 @@ -515,6 +515,16 @@
21328 If @var{dir} begins with @code{=}, then the @code{=} will be replaced
21329 by the sysroot prefix; see @option{--sysroot} and @option{-isysroot}.
21331 +@item -cxx-isystem @var{dir}
21332 +@opindex cxxisystem
21333 +Search @var{dir} for C++ header files, after all directories specified by
21334 +@option{-I} but before the standard system directories. Mark it
21335 +as a system directory, so that it gets the same special treatment as
21336 +is applied to the standard system directories.
21337 +@ifset cppmanual
21338 +@xref{System Headers}.
21339 +@end ifset
21341 @item -iquote @var{dir}
21342 @opindex iquote
21343 Search @var{dir} only for header files requested with
21344 @@ -549,6 +559,12 @@
21345 @option{-fpreprocessed} take precedence. This enables full preprocessing of
21346 files previously preprocessed with @code{-E -fdirectives-only}.
21348 +@item -iremap @var{src}:@var{dst}
21349 +@opindex iremap
21350 +Replace the prefix @var{src} in __FILE__ with @var{dst} at expansion time.
21351 +This option can be specified more than once. Processing stops at the first
21352 +match.
21354 @item -fdollars-in-identifiers
21355 @opindex fdollars-in-identifiers
21356 @anchor{fdollars-in-identifiers}
21357 diff -rNU3 dist.orig/gcc/doc/invoke.texi dist/gcc/doc/invoke.texi
21358 --- dist.orig/gcc/doc/invoke.texi 2015-06-23 09:35:08.000000000 +0200
21359 +++ dist/gcc/doc/invoke.texi 2015-10-18 13:19:51.000000000 +0200
21360 @@ -436,6 +436,7 @@
21361 -include @var{file} -imacros @var{file} @gol
21362 -iprefix @var{file} -iwithprefix @var{dir} @gol
21363 -iwithprefixbefore @var{dir} -isystem @var{dir} @gol
21364 +-cxx-isystem @var{dir} @gol
21365 -imultilib @var{dir} -isysroot @var{dir} @gol
21366 -M -MM -MF -MG -MP -MQ -MT -nostdinc @gol
21367 -P -fdebug-cpp -ftrack-macro-expansion -fworking-directory @gol
21368 @@ -458,6 +459,14 @@
21370 @item Directory Options
21371 @xref{Directory Options,,Options for Directory Search}.
21372 +@gccoptlist{-B@var{prefix} -I@var{dir} -iquote@var{dir}
21373 +-iremap@var{src}:@var{dst} -L@var{dir}
21374 +-specs=@var{file} -I- --sysroot=@var{dir}}
21376 +@item Target Options
21377 +@c I wrote this xref this way to avoid overfull hbox. -- rms
21378 +@xref{Target Options}.
21379 +@gccoptlist{-V @var{version} -b @var{machine}}
21380 @gccoptlist{-B@var{prefix} -I@var{dir} -iplugindir=@var{dir} @gol
21381 -iquote@var{dir} -L@var{dir} -specs=@var{file} -I- @gol
21382 --sysroot=@var{dir} --no-sysroot-suffix}
21383 @@ -3568,11 +3577,11 @@
21384 to be stored.''. If a program breaks these rules, the results on any
21385 particular implementation are entirely unpredictable.
21387 -Examples of code with undefined behavior are @code{a = a++;}, @code{a[n]
21388 -= b[n++]} and @code{a[i++] = i;}. Some more complicated cases are not
21389 -diagnosed by this option, and it may give an occasional false positive
21390 -result, but in general it has been found fairly effective at detecting
21391 -this sort of problem in programs.
21392 +Examples of code with undefined behavior are @code{a = a++;},
21393 +@code{a[n] = b[n++]} and @code{a[i++] = i;}. Some more complicated cases
21394 +are not diagnosed by this option, and it may give an occasional false
21395 +positive result, but in general it has been found fairly effective at
21396 +detecting this sort of problem in programs.
21398 The standard is worded confusingly, therefore there is some debate
21399 over the precise meaning of the sequence point rules in subtle cases.
21400 @@ -10111,6 +10120,12 @@
21401 "@var{file}"}; they are not searched for @samp{#include <@var{file}>},
21402 otherwise just like @option{-I}.
21404 +@item -iremap @var{src}:@var{dst}
21405 +@opindex iremap
21406 +Replace the prefix @var{src} in __FILE__ with @var{dst} at expansion time.
21407 +This option can be specified more than once. Processing stops at the first
21408 +match.
21410 @item -L@var{dir}
21411 @opindex L
21412 Add directory @var{dir} to the list of directories to be searched
21413 @@ -14177,7 +14192,7 @@
21414 Streaming SIMD Extension (SSE) data type @code{__m128} may not work
21415 properly if it is not 16-byte aligned.
21417 -To ensure proper alignment of this values on the stack, the stack boundary
21418 +To ensure proper alignment of these values on the stack, the stack boundary
21419 must be as aligned as that required by any value stored on the stack.
21420 Further, every function must be generated such that it keeps the stack
21421 aligned. Thus calling a function compiled with a higher preferred
21422 diff -rNU3 dist.orig/gcc/dse.c dist/gcc/dse.c
21423 --- dist.orig/gcc/dse.c 2015-02-20 13:04:21.000000000 +0100
21424 +++ dist/gcc/dse.c 2015-10-18 13:19:51.000000000 +0200
21425 @@ -290,6 +290,9 @@
21426 lowpart_bitmask (int n)
21428 unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT) 0;
21429 + gcc_assert(n >= 0 && n <= HOST_BITS_PER_WIDE_INT);
21430 + if (n == 0)
21431 + return 0;
21432 return mask >> (HOST_BITS_PER_WIDE_INT - n);
21435 diff -rNU3 dist.orig/gcc/expr.c dist/gcc/expr.c
21436 --- dist.orig/gcc/expr.c 2015-06-03 23:35:25.000000000 +0200
21437 +++ dist/gcc/expr.c 2015-10-18 13:19:51.000000000 +0200
21438 @@ -4055,7 +4055,8 @@
21439 xinner = x;
21441 if (mode == BLKmode
21442 - || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
21443 + || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)
21444 + && type != NULL_TREE))
21446 /* Copy a block into the stack, entirely or partially. */
21448 diff -rNU3 dist.orig/gcc/gcc.c dist/gcc/gcc.c
21449 --- dist.orig/gcc/gcc.c 2015-06-23 09:35:08.000000000 +0200
21450 +++ dist/gcc/gcc.c 2015-10-18 13:19:51.000000000 +0200
21451 @@ -1365,7 +1365,7 @@
21452 static_name, " --as-needed ", shared_name, " --no-as-needed"
21454 "%{shared-libgcc:",
21455 - shared_name, "%{!shared: ", static_name, "}"
21456 + "--as-needed ", shared_name, " --no-as-needed ", static_name,
21458 #else
21459 "%{!shared:"
21460 @@ -3713,6 +3713,10 @@
21461 /* FIXME: make_relative_prefix doesn't yet work for VMS. */
21462 if (!gcc_exec_prefix)
21464 +#ifdef NETBSD_NATIVE
21465 + add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
21466 + PREFIX_PRIORITY_LAST, 0, 0);
21467 +#else
21468 gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
21469 standard_bindir_prefix,
21470 standard_exec_prefix);
21471 @@ -3721,6 +3725,7 @@
21472 standard_libexec_prefix);
21473 if (gcc_exec_prefix)
21474 xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
21475 +#endif
21477 else
21479 @@ -6412,6 +6417,7 @@
21480 else
21481 init_spec ();
21483 +#ifndef NETBSD_NATIVE
21484 /* We need to check standard_exec_prefix/just_machine_suffix/specs
21485 for any override of as, ld and libraries. */
21486 specs_file = (char *) alloca (strlen (standard_exec_prefix)
21487 @@ -6422,6 +6428,7 @@
21488 strcat (specs_file, "specs");
21489 if (access (specs_file, R_OK) == 0)
21490 read_specs (specs_file, true, false);
21491 +#endif
21493 /* Process any configure-time defaults specified for the command line
21494 options, via OPTION_DEFAULT_SPECS. */
21495 @@ -6517,14 +6524,18 @@
21496 PREFIX_PRIORITY_LAST, 0, 1);
21497 else if (*cross_compile == '0')
21499 +/* XXXMRG not sure this one is right? */
21500 +#if !defined(NETBSD_NATIVE) && !defined(NETBSD_TOOLS)
21501 add_prefix (&startfile_prefixes,
21502 concat (gcc_exec_prefix
21503 ? gcc_exec_prefix : standard_exec_prefix,
21504 machine_suffix,
21505 standard_startfile_prefix, NULL),
21506 NULL, PREFIX_PRIORITY_LAST, 0, 1);
21507 +#endif /* NETBSD_NATIVE */
21510 +#if !defined(NETBSD_NATIVE) && !defined(NETBSD_TOOLS)
21511 /* Sysrooted prefixes are relocated because target_system_root is
21512 also relocated by gcc_exec_prefix. */
21513 if (*standard_startfile_prefix_1)
21514 @@ -6535,6 +6546,7 @@
21515 add_sysrooted_prefix (&startfile_prefixes,
21516 standard_startfile_prefix_2, "BINUTILS",
21517 PREFIX_PRIORITY_LAST, 0, 1);
21518 +#endif /* NETBSD_NATIVE */
21521 /* Process any user specified specs in the order given on the command
21522 diff -rNU3 dist.orig/gcc/gcc.h dist/gcc/gcc.h
21523 --- dist.orig/gcc/gcc.h 2013-01-10 21:38:27.000000000 +0100
21524 +++ dist/gcc/gcc.h 2015-10-18 13:19:51.000000000 +0200
21525 @@ -31,6 +31,32 @@
21526 const char *(*func) (int, const char **);
21529 +/* This defines which switch letters take arguments. */
21531 +#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
21532 + ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
21533 + || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
21534 + || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \
21535 + || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \
21536 + || (CHAR) == 'V' || (CHAR) == 'B' || (CHAR) == 'b')
21538 +/* This defines which multi-letter switches take arguments. */
21540 +#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \
21541 + (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \
21542 + || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
21543 + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
21544 + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
21545 + || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
21546 + || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \
21547 + || !strcmp (STR, "isysroot") \
21548 + || !strcmp (STR, "cxx-isystem") || !strcmp (STR, "-iremap") \
21549 + || !strcmp (STR, "-param") || !strcmp (STR, "specs") \
21550 + || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \
21551 + || !strcmp (STR, "fintrinsic-modules-path") \
21552 + || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir"))
21555 /* These are exported by gcc.c. */
21556 extern int do_spec (const char *);
21557 extern void record_temp_file (const char *, int, int);
21558 diff -rNU3 dist.orig/gcc/genemit.c dist/gcc/genemit.c
21559 --- dist.orig/gcc/genemit.c 2013-01-10 21:38:27.000000000 +0100
21560 +++ dist/gcc/genemit.c 2015-10-18 13:19:51.000000000 +0200
21561 @@ -196,9 +196,9 @@
21562 printf ("const_true_rtx");
21563 else
21565 - printf ("GEN_INT (");
21566 - printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
21567 - printf (")");
21568 + printf ("GEN_INT (HOST_WIDE_INT_CONSTANT (");
21569 + printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
21570 + printf ("))");
21572 return;
21574 diff -rNU3 dist.orig/gcc/genmultilib dist/gcc/genmultilib
21575 --- dist.orig/gcc/genmultilib 2013-03-14 09:52:13.000000000 +0100
21576 +++ dist/gcc/genmultilib 2015-10-18 13:19:51.000000000 +0200
21577 @@ -154,8 +154,10 @@
21578 # Since not all versions of sh support functions, we achieve recursion
21579 # by creating a temporary shell script which invokes itself.
21580 rm -f tmpmultilib
21581 -cat >tmpmultilib <<\EOF
21582 -#!/bin/sh
21583 +cat >tmpmultilib <<EOF
21584 +#!${CONFIG_SHELL:-/bin/sh}
21585 +EOF
21586 +cat >>tmpmultilib <<\EOF
21587 # This recursive script basically outputs all combinations of its
21588 # input arguments, handling mutually exclusive sets of options by
21589 # repetition. When the script is called, ${initial} is the list of
21590 @@ -190,8 +192,10 @@
21592 # If there exceptions, weed them out now
21593 if [ -n "${exceptions}" ]; then
21594 - cat >tmpmultilib2 <<\EOF
21595 -#!/bin/sh
21596 + cat >tmpmultilib2 <<EOF
21597 +#!${CONFIG_SHELL:-/bin/sh}
21598 +EOF
21599 + cat >>tmpmultilib2 <<\EOF
21600 # This recursive script weeds out any combination of multilib
21601 # switches that should not be generated. The output looks like
21602 # a list of subdirectory names with leading and trailing slashes.
21603 @@ -330,8 +334,10 @@
21604 # opt1/opt2 nopt1 nopt2
21605 # In other words, we must output all combinations of matches.
21606 rm -f tmpmultilib2
21607 -cat >tmpmultilib2 <<\EOF
21608 -#!/bin/sh
21609 +cat >tmpmultilib2 <<EOF
21610 +#!${CONFIG_SHELL:-/bin/sh}
21611 +EOF
21612 +cat >>tmpmultilib2 <<\EOF
21613 # The positional parameters are a list of matches to consider.
21614 # ${dirout} is the directory name and ${optout} is the current list of
21615 # options.
21616 diff -rNU3 dist.orig/gcc/genrecog.c dist/gcc/genrecog.c
21617 --- dist.orig/gcc/genrecog.c 2013-01-10 21:38:27.000000000 +0100
21618 +++ dist/gcc/genrecog.c 2015-10-18 13:19:51.000000000 +0200
21619 @@ -1634,11 +1634,13 @@
21620 static void
21621 print_host_wide_int (HOST_WIDE_INT val)
21623 + /* XXX: the "min" below is computed for build, not host!!! */
21624 HOST_WIDE_INT min = (unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1);
21625 if (val == min)
21626 - printf ("(" HOST_WIDE_INT_PRINT_DEC_C "-1)", val + 1);
21627 + printf ("(HOST_WIDE_INT_CONSTANT (" HOST_WIDE_INT_PRINT_DEC ")-1)",
21628 + val + 1);
21629 else
21630 - printf (HOST_WIDE_INT_PRINT_DEC_C, val);
21631 + printf ("HOST_WIDE_INT_CONSTANT (" HOST_WIDE_INT_PRINT_DEC")", val);
21634 /* Emit a switch statement, if possible, for an initial sequence of
21635 diff -rNU3 dist.orig/gcc/ggc-common.c dist/gcc/ggc-common.c
21636 --- dist.orig/gcc/ggc-common.c 2013-03-05 16:51:48.000000000 +0100
21637 +++ dist/gcc/ggc-common.c 2015-10-18 13:19:51.000000000 +0200
21638 @@ -666,6 +666,8 @@
21639 size_t i;
21640 struct mmap_info mmi;
21641 int result;
21642 + struct line_maps * old_line_table = line_table;
21643 + location_t old_input_loc = input_location;
21645 /* Delete any deletable objects. This makes ggc_pch_read much
21646 faster, as it can be sure that no GCable objects remain other
21647 @@ -677,39 +679,60 @@
21648 /* Read in all the scalar variables. */
21649 for (rt = gt_pch_scalar_rtab; *rt; rt++)
21650 for (rti = *rt; rti->base != NULL; rti++)
21651 - if (fread (rti->base, rti->stride, 1, f) != 1)
21652 + if (fread (rti->base, rti->stride, 1, f) != 1) {
21653 + line_table = old_line_table;
21654 + input_location = old_input_loc;
21655 fatal_error ("can%'t read PCH file: %m");
21658 /* Read in all the global pointers, in 6 easy loops. */
21659 for (rt = gt_ggc_rtab; *rt; rt++)
21660 for (rti = *rt; rti->base != NULL; rti++)
21661 for (i = 0; i < rti->nelt; i++)
21662 if (fread ((char *)rti->base + rti->stride * i,
21663 - sizeof (void *), 1, f) != 1)
21664 + sizeof (void *), 1, f) != 1) {
21665 + line_table = old_line_table;
21666 + input_location = old_input_loc;
21667 fatal_error ("can%'t read PCH file: %m");
21670 for (rt = gt_pch_cache_rtab; *rt; rt++)
21671 for (rti = *rt; rti->base != NULL; rti++)
21672 for (i = 0; i < rti->nelt; i++)
21673 if (fread ((char *)rti->base + rti->stride * i,
21674 - sizeof (void *), 1, f) != 1)
21675 + sizeof (void *), 1, f) != 1) {
21676 + line_table = old_line_table;
21677 + input_location = old_input_loc;
21678 fatal_error ("can%'t read PCH file: %m");
21681 - if (fread (&mmi, sizeof (mmi), 1, f) != 1)
21682 + if (fread (&mmi, sizeof (mmi), 1, f) != 1) {
21683 + line_table = old_line_table;
21684 + input_location = old_input_loc;
21685 fatal_error ("can%'t read PCH file: %m");
21688 result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size,
21689 fileno (f), mmi.offset);
21690 - if (result < 0)
21691 + if (result < 0) {
21692 + line_table = old_line_table;
21693 + input_location = old_input_loc;
21694 fatal_error ("had to relocate PCH");
21696 if (result == 0)
21698 if (fseek (f, mmi.offset, SEEK_SET) != 0
21699 - || fread (mmi.preferred_base, mmi.size, 1, f) != 1)
21700 + || fread (mmi.preferred_base, mmi.size, 1, f) != 1) {
21701 + line_table = old_line_table;
21702 + input_location = old_input_loc;
21703 fatal_error ("can%'t read PCH file: %m");
21706 - else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
21707 + else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0) {
21708 + line_table = old_line_table;
21709 + input_location = old_input_loc;
21710 fatal_error ("can%'t read PCH file: %m");
21713 ggc_pch_read (f, mmi.preferred_base);
21715 diff -rNU3 dist.orig/gcc/ginclude/stddef.h dist/gcc/ginclude/stddef.h
21716 --- dist.orig/gcc/ginclude/stddef.h 2013-01-10 21:38:27.000000000 +0100
21717 +++ dist/gcc/ginclude/stddef.h 2015-10-18 13:19:51.000000000 +0200
21718 @@ -49,8 +49,10 @@
21719 /* On 4.3bsd-net2, make sure ansi.h is included, so we have
21720 one less case to deal with in the following. */
21721 #if defined (__BSD_NET2__) || defined (____386BSD____) || (defined (__FreeBSD__) && (__FreeBSD__ < 5)) || defined(__NetBSD__)
21722 +#ifndef inhibit_libc
21723 #include <machine/ansi.h>
21724 #endif
21725 +#endif
21726 /* On FreeBSD 5, machine/ansi.h does not exist anymore... */
21727 #if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
21728 #include <sys/_types.h>
21729 diff -rNU3 dist.orig/gcc/ginclude/unwind-arm-common.h dist/gcc/ginclude/unwind-arm-common.h
21730 --- dist.orig/gcc/ginclude/unwind-arm-common.h 2013-01-10 21:38:27.000000000 +0100
21731 +++ dist/gcc/ginclude/unwind-arm-common.h 2015-10-18 13:19:51.000000000 +0200
21732 @@ -183,7 +183,7 @@
21733 #define _Unwind_Exception _Unwind_Control_Block
21734 typedef char _Unwind_Exception_Class[8];
21736 - void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
21737 + _Unwind_Ptr _Unwind_GetLanguageSpecificData (_Unwind_Context *);
21738 _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
21740 _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *);
21741 @@ -234,7 +234,7 @@
21744 _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
21745 - void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
21746 + _Unwind_Ptr _Unwind_GetLanguageSpecificData (_Unwind_Context *);
21748 /* leb128 type numbers have a potentially unlimited size.
21749 The target of the following definitions of _sleb128_t and _uleb128_t
21750 diff -rNU3 dist.orig/gcc/hwint.h dist/gcc/hwint.h
21751 --- dist.orig/gcc/hwint.h 2013-01-10 21:38:27.000000000 +0100
21752 +++ dist/gcc/hwint.h 2015-10-18 13:19:51.000000000 +0200
21753 @@ -88,6 +88,7 @@
21754 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
21755 # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
21756 # define HOST_WIDE_INT_PRINT_C "L"
21757 +# define HOST_WIDE_INT_CONSTANT(x) x ## L
21758 /* 'long' might be 32 or 64 bits, and the number of leading zeroes
21759 must be tweaked accordingly. */
21760 # if HOST_BITS_PER_WIDE_INT == 64
21761 @@ -100,6 +101,7 @@
21762 #else
21763 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
21764 # define HOST_WIDE_INT_PRINT_C "LL"
21765 +# define HOST_WIDE_INT_CONSTANT(x) x ## LL
21766 /* We can assume that 'long long' is at least 64 bits. */
21767 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
21768 "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
21769 diff -rNU3 dist.orig/gcc/objc/Make-lang.in dist/gcc/objc/Make-lang.in
21770 --- dist.orig/gcc/objc/Make-lang.in 2013-01-10 21:38:27.000000000 +0100
21771 +++ dist/gcc/objc/Make-lang.in 2015-10-18 13:19:51.000000000 +0200
21772 @@ -63,7 +63,7 @@
21773 $(OBJC_OBJS) $(C_AND_OBJC_OBJS) $(BACKEND) $(LIBDEPS)
21774 build/genchecksum$(build_exeext) $(OBJC_OBJS) $(C_AND_OBJC_OBJS) \
21775 $(BACKEND) $(LIBDEPS) checksum-options > cc1obj-checksum.c.tmp && \
21776 - $(srcdir)/../move-if-change cc1obj-checksum.c.tmp cc1obj-checksum.c
21777 + $(SHELL) $(srcdir)/../move-if-change cc1obj-checksum.c.tmp cc1obj-checksum.c
21779 cc1obj-checksum.o : cc1obj-checksum.c $(CONFIG_H) $(SYSTEM_H)
21781 diff -rNU3 dist.orig/gcc/objcp/Make-lang.in dist/gcc/objcp/Make-lang.in
21782 --- dist.orig/gcc/objcp/Make-lang.in 2013-01-10 21:38:27.000000000 +0100
21783 +++ dist/gcc/objcp/Make-lang.in 2015-10-18 13:19:51.000000000 +0200
21784 @@ -66,7 +66,7 @@
21785 $(OBJCXX_OBJS) $(BACKEND) $(LIBDEPS)
21786 build/genchecksum$(build_exeext) $(OBJCXX_OBJS) $(BACKEND) \
21787 $(LIBDEPS) checksum-options > cc1objplus-checksum.c.tmp && \
21788 - $(srcdir)/../move-if-change cc1objplus-checksum.c.tmp \
21789 + $(SHELL) $(srcdir)/../move-if-change cc1objplus-checksum.c.tmp \
21790 cc1objplus-checksum.c
21792 cc1objplus-checksum.o : cc1objplus-checksum.c $(CONFIG_H) $(SYSTEM_H)
21793 diff -rNU3 dist.orig/gcc/reload.c dist/gcc/reload.c
21794 --- dist.orig/gcc/reload.c 2013-02-04 17:23:38.000000000 +0100
21795 +++ dist/gcc/reload.c 2015-10-18 13:19:51.000000000 +0200
21796 @@ -846,6 +846,7 @@
21797 reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, bool output)
21799 rtx inner;
21800 + int regno;
21802 /* Only SUBREGs are problematical. */
21803 if (GET_CODE (x) != SUBREG)
21804 @@ -857,10 +858,20 @@
21805 if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
21806 return true;
21808 - /* If INNER is not a hard register, then INNER will not need reloading. */
21809 - if (!(REG_P (inner) && HARD_REGISTER_P (inner)))
21810 + /* If INNER is not a register, then INNER will not need reloading. */
21811 + if (!REG_P (inner))
21812 return false;
21814 + regno = REGNO (inner);
21816 + /* If INNER is not a hard register, then INNER will not need reloading
21817 + unless it's a mode dependent memory reference. */
21818 + if (regno >= FIRST_PSEUDO_REGISTER)
21819 + return !output
21820 + && reg_equiv_mem (regno) != 0
21821 + && mode_dependent_address_p (XEXP (reg_equiv_mem (regno), 0),
21822 + MEM_ADDR_SPACE (reg_equiv_mem (regno)));
21824 /* If INNER is not ok for MODE, then INNER will need reloading. */
21825 if (!HARD_REGNO_MODE_OK (subreg_regno (x), mode))
21826 return true;
21827 @@ -1142,7 +1153,7 @@
21829 if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
21831 - if (REG_P (SUBREG_REG (in)))
21832 + if (REG_P (SUBREG_REG (in)) && HARD_REGISTER_P (SUBREG_REG (in)))
21833 subreg_in_class
21834 = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)),
21835 subreg_regno_offset (REGNO (SUBREG_REG (in)),
21836 @@ -1150,7 +1161,8 @@
21837 SUBREG_BYTE (in),
21838 GET_MODE (in)),
21839 REGNO (SUBREG_REG (in)));
21840 - else if (GET_CODE (SUBREG_REG (in)) == SYMBOL_REF)
21841 + else if (REG_P (SUBREG_REG (in))
21842 + || GET_CODE (SUBREG_REG (in)) == SYMBOL_REF)
21843 subreg_in_class = find_valid_class_1 (inmode,
21844 GET_MODE (SUBREG_REG (in)),
21845 rclass);
21846 diff -rNU3 dist.orig/gcc/system.h dist/gcc/system.h
21847 --- dist.orig/gcc/system.h 2013-01-15 16:54:05.000000000 +0100
21848 +++ dist/gcc/system.h 2015-10-18 13:19:51.000000000 +0200
21849 @@ -37,6 +37,12 @@
21850 # include <stddef.h>
21851 #endif
21853 +#ifndef GENERATOR_FILE
21854 +#ifdef __cplusplus
21855 +# include <cstdio>
21856 +#endif
21857 +#endif
21859 #include <stdio.h>
21861 /* Define a generic NULL if one hasn't already been defined. */
21862 @@ -201,9 +207,11 @@
21863 extern int errno;
21864 #endif
21866 +#ifndef GENERATOR_FILE
21867 #ifdef __cplusplus
21868 # include <cstring>
21869 #endif
21870 +#endif
21872 /* Some of glibc's string inlines cause warnings. Plus we'd rather
21873 rely on (and therefore test) GCC's string builtins. */
21874 diff -rNU3 dist.orig/gcc/targhooks.c dist/gcc/targhooks.c
21875 --- dist.orig/gcc/targhooks.c 2013-01-10 21:38:27.000000000 +0100
21876 +++ dist/gcc/targhooks.c 2015-10-18 13:19:51.000000000 +0200
21877 @@ -714,7 +714,17 @@
21878 DECL_ARTIFICIAL (t) = 1;
21879 DECL_IGNORED_P (t) = 1;
21880 DECL_VISIBILITY_SPECIFIED (t) = 1;
21881 +#if 1
21882 + /*
21883 + * This is a hack:
21884 + * It appears that our gas does not generate @PLT for hidden
21885 + * symbols. It could be that we need a newer version, or that
21886 + * this local function is handled differently on linux.
21887 + */
21888 + DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
21889 +#else
21890 DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
21891 +#endif
21893 stack_chk_fail_decl = t;
21895 diff -rNU3 dist.orig/gcc/tree-cfg.c dist/gcc/tree-cfg.c
21896 --- dist.orig/gcc/tree-cfg.c 2015-06-03 23:36:26.000000000 +0200
21897 +++ dist/gcc/tree-cfg.c 2015-10-18 13:19:51.000000000 +0200
21898 @@ -7800,7 +7800,11 @@
21900 if (location == UNKNOWN_LOCATION)
21901 location = cfun->function_end_locus;
21902 - warning_at (location, 0, "%<noreturn%> function does return");
21904 +#ifdef notyet
21905 + if (warn_missing_noreturn)
21906 + warning_at (location, 0, "%<noreturn%> function does return");
21907 +#endif
21910 /* If we see "return;" in some basic block, then we do reach the end
21911 diff -rNU3 dist.orig/gcc/tree-ssa-ccp.c dist/gcc/tree-ssa-ccp.c
21912 --- dist.orig/gcc/tree-ssa-ccp.c 2013-09-23 18:12:27.000000000 +0200
21913 +++ dist/gcc/tree-ssa-ccp.c 2015-10-18 13:19:51.000000000 +0200
21914 @@ -2529,3 +2529,42 @@
21915 | TODO_update_ssa /* todo_flags_finish */
21919 +#if defined(__NetBSD__) && defined(NETBSD_NATIVE)
21921 + * This is a big, ugly, temporary hack:
21922 + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59958
21923 + * To make sure we have configured all our targets correctly, mimic the
21924 + * #ifdef cascade from src/lib/libc/stdlib/jemalloc.c here and compile
21925 + * time assert that the value matches gcc's MALLOC_ABI_ALIGNMENT here.
21926 + */
21928 +#if defined(__alpha__) || defined(__amd64__) || defined(__sparc64__) \
21929 + || (defined(__arm__) && defined(__ARM_EABI)) || defined(__powerpc__) \
21930 + || ((defined(__mips__) || defined(__riscv__)) && defined(_LP64))
21931 +#define JEMALLOC_TINY_MIN_2POW 3
21932 +#endif
21934 +#ifndef JEMALLOC_TINY_MIN_2POW
21935 +#define JEMALLOC_TINY_MIN_2POW 2
21936 +#endif
21938 +/* make sure we test the (native) 64bit variant for targets supporting -m32 */
21939 +#undef TARGET_64BIT
21940 +#ifdef _LP64
21941 +#define TARGET_64BIT 1
21942 +#else
21943 +#ifdef __sh__
21944 +#undef UNITS_PER_WORD
21945 +#define UNITS_PER_WORD 4 /* original definition varies depending on cpu */
21946 +#endif
21947 +#define TARGET_64BIT 0
21948 +#endif
21950 +#ifdef __CTASSERT
21951 +__CTASSERT((8<<JEMALLOC_TINY_MIN_2POW) == MALLOC_ABI_ALIGNMENT);
21952 +#else
21953 +#error compiling on an older NetBSD version?
21954 +#endif
21956 +#endif
21957 diff -rNU3 dist.orig/gnattools/configure dist/gnattools/configure
21958 --- dist.orig/gnattools/configure 2013-12-04 22:28:21.000000000 +0100
21959 +++ dist/gnattools/configure 2015-10-18 13:19:51.000000000 +0200
21960 @@ -1757,7 +1757,7 @@
21961 for ac_t in install-sh install.sh shtool; do
21962 if test -f "$ac_dir/$ac_t"; then
21963 ac_aux_dir=$ac_dir
21964 - ac_install_sh="$ac_aux_dir/$ac_t -c"
21965 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
21966 break 2
21968 done
21969 diff -rNU3 dist.orig/intl/configure dist/intl/configure
21970 --- dist.orig/intl/configure 2010-09-27 22:19:41.000000000 +0200
21971 +++ dist/intl/configure 2015-10-18 13:19:51.000000000 +0200
21972 @@ -2212,7 +2212,7 @@
21973 for ac_t in install-sh install.sh shtool; do
21974 if test -f "$ac_dir/$ac_t"; then
21975 ac_aux_dir=$ac_dir
21976 - ac_install_sh="$ac_aux_dir/$ac_t -c"
21977 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
21978 break 2
21980 done
21981 diff -rNU3 dist.orig/libbacktrace/configure dist/libbacktrace/configure
21982 --- dist.orig/libbacktrace/configure 2015-01-26 16:36:23.000000000 +0100
21983 +++ dist/libbacktrace/configure 2015-10-18 13:19:51.000000000 +0200
21984 @@ -2496,7 +2496,7 @@
21985 for ac_t in install-sh install.sh shtool; do
21986 if test -f "$ac_dir/$ac_t"; then
21987 ac_aux_dir=$ac_dir
21988 - ac_install_sh="$ac_aux_dir/$ac_t -c"
21989 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
21990 break 2
21992 done
21993 diff -rNU3 dist.orig/libcpp/Makefile.in dist/libcpp/Makefile.in
21994 --- dist.orig/libcpp/Makefile.in 2015-06-23 09:55:27.000000000 +0200
21995 +++ dist/libcpp/Makefile.in 2015-10-18 13:19:51.000000000 +0200
21996 @@ -136,7 +136,7 @@
21997 localedir.h: localedir.hs; @true
21998 localedir.hs: Makefile
21999 echo "#define LOCALEDIR \"$(localedir)\"" > localedir.new
22000 - $(srcdir)/../move-if-change localedir.new localedir.h
22001 + $(SHELL) $(srcdir)/../move-if-change localedir.new localedir.h
22002 echo timestamp > localedir.hs
22004 # Installation rules and other phony targets
22005 diff -rNU3 dist.orig/libcpp/configure dist/libcpp/configure
22006 --- dist.orig/libcpp/configure 2015-06-23 09:55:27.000000000 +0200
22007 +++ dist/libcpp/configure 2015-10-18 13:19:51.000000000 +0200
22008 @@ -2515,7 +2515,7 @@
22009 for ac_t in install-sh install.sh shtool; do
22010 if test -f "$ac_dir/$ac_t"; then
22011 ac_aux_dir=$ac_dir
22012 - ac_install_sh="$ac_aux_dir/$ac_t -c"
22013 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
22014 break 2
22016 done
22017 @@ -7152,9 +7152,7 @@
22018 case $target in
22019 aarch64*-*-* | \
22020 alpha*-*-* | \
22021 - arm*-*-*eabi* | \
22022 - arm*-*-rtems* | \
22023 - arm*-*-symbianelf* | \
22024 + arm*-*-* | \
22025 x86_64-*-* | \
22026 ia64-*-* | \
22027 hppa*64*-*-* | \
22028 diff -rNU3 dist.orig/libcpp/configure.ac dist/libcpp/configure.ac
22029 --- dist.orig/libcpp/configure.ac 2013-04-03 17:13:33.000000000 +0200
22030 +++ dist/libcpp/configure.ac 2015-10-18 13:19:51.000000000 +0200
22031 @@ -184,9 +184,7 @@
22032 case $target in
22033 aarch64*-*-* | \
22034 alpha*-*-* | \
22035 - arm*-*-*eabi* | \
22036 - arm*-*-rtems* | \
22037 - arm*-*-symbianelf* | \
22038 + arm*-*-* | \
22039 x86_64-*-* | \
22040 ia64-*-* | \
22041 hppa*64*-*-* | \
22042 diff -rNU3 dist.orig/libcpp/files.c dist/libcpp/files.c
22043 --- dist.orig/libcpp/files.c 2015-06-12 13:56:39.000000000 +0200
22044 +++ dist/libcpp/files.c 2015-10-18 13:19:51.000000000 +0200
22045 @@ -28,6 +28,7 @@
22046 #include "obstack.h"
22047 #include "hashtab.h"
22048 #include "md5.h"
22049 +#include "../gcc/defaults.h"
22050 #include <dirent.h>
22052 /* Variable length record files on VMS will have a stat size that includes
22053 @@ -220,20 +221,32 @@
22054 static bool
22055 open_file (_cpp_file *file)
22057 + const char *cpp_restricted;
22059 + cpp_restricted = getenv ("CPP_RESTRICTED");
22061 if (file->path[0] == '\0')
22063 file->fd = 0;
22064 set_stdin_to_binary_mode ();
22066 else
22067 - file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
22068 + file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY
22069 + | (cpp_restricted != NULL) ? O_NONBLOCK : 0, 0666);
22072 if (file->fd != -1)
22074 if (fstat (file->fd, &file->st) == 0)
22076 if (!S_ISDIR (file->st.st_mode))
22077 + if (cpp_restricted != NULL
22078 + ? S_ISREG (file->st.st_mode) : !S_ISDIR (file->st.st_mode))
22081 + if (cpp_restricted)
22082 + fcntl(file->fd, F_SETFL,
22083 + fcntl(file->fd, F_GETFL, 0) & ~O_NONBLOCK);
22084 file->err_no = 0;
22085 return true;
22087 diff -rNU3 dist.orig/libcpp/include/cpplib.h dist/libcpp/include/cpplib.h
22088 --- dist.orig/libcpp/include/cpplib.h 2013-01-14 19:13:59.000000000 +0100
22089 +++ dist/libcpp/include/cpplib.h 2015-10-18 13:19:51.000000000 +0200
22090 @@ -715,6 +715,9 @@
22091 /* Set the include paths. */
22092 extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
22094 +/* Provide src:dst pair for __FILE__ remapping. */
22095 +extern void add_cpp_remap_path (const char *);
22097 /* Call these to get pointers to the options, callback, and deps
22098 structures for a given reader. These pointers are good until you
22099 call cpp_finish on that reader. You can either edit the callbacks
22100 diff -rNU3 dist.orig/libcpp/internal.h dist/libcpp/internal.h
22101 --- dist.orig/libcpp/internal.h 2013-03-06 17:18:40.000000000 +0100
22102 +++ dist/libcpp/internal.h 2015-10-18 13:19:51.000000000 +0200
22103 @@ -226,6 +226,9 @@
22104 /* Nonzero if first token on line is CPP_HASH. */
22105 unsigned char in_directive;
22107 + /* Nonzero if we are collecting macro arguments */
22108 + unsigned char collecting_args;
22110 /* Nonzero if in a directive that will handle padding tokens itself.
22111 #include needs this to avoid problems with computed include and
22112 spacing between tokens. */
22113 diff -rNU3 dist.orig/libcpp/lex.c dist/libcpp/lex.c
22114 --- dist.orig/libcpp/lex.c 2014-10-13 03:42:03.000000000 +0200
22115 +++ dist/libcpp/lex.c 2015-10-18 13:19:51.000000000 +0200
22116 @@ -1876,6 +1876,8 @@
22118 unsigned char *buffer;
22119 unsigned int len, clen, i;
22120 + int convert_to_c = (pfile->state.in_directive || pfile->state.parsing_args)
22121 + && type == '/';
22123 len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */
22125 @@ -1890,8 +1892,7 @@
22127 Note that the only time we encounter a directive here is
22128 when we are saving comments in a "#define". */
22129 - clen = ((pfile->state.in_directive || pfile->state.parsing_args)
22130 - && type == '/') ? len + 2 : len;
22131 + clen = convert_to_c ? len + 2 : len;
22133 buffer = _cpp_unaligned_alloc (pfile, clen);
22135 @@ -1903,7 +1904,7 @@
22136 memcpy (buffer + 1, from, len - 1);
22138 /* Finish conversion to a C comment, if necessary. */
22139 - if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/')
22140 + if (convert_to_c)
22142 buffer[1] = '*';
22143 buffer[clen - 2] = '*';
22144 diff -rNU3 dist.orig/libcpp/macro.c dist/libcpp/macro.c
22145 --- dist.orig/libcpp/macro.c 2014-03-06 09:10:08.000000000 +0100
22146 +++ dist/libcpp/macro.c 2015-10-18 13:19:51.000000000 +0200
22147 @@ -215,6 +215,61 @@
22148 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
22151 +static size_t remap_pairs;
22152 +static char **remap_src;
22153 +static char **remap_dst;
22155 +void
22156 +add_cpp_remap_path (const char *arg)
22158 + const char *arg_dst;
22159 + size_t len;
22161 + arg_dst = strchr(arg, ':');
22162 + if (arg_dst == NULL) {
22163 + fprintf(stderr, "Invalid argument for -iremap");
22164 + exit(1);
22166 + len = arg_dst - arg;
22167 + ++arg_dst;
22169 + remap_src = (char **) xrealloc(remap_src, sizeof(char *) * (remap_pairs + 1));
22170 + remap_dst = (char **) xrealloc(remap_dst, sizeof(char *) * (remap_pairs + 1));
22172 + remap_src[remap_pairs] = (char *) xmalloc(len + 1);
22173 + memcpy(remap_src[remap_pairs], arg, len);
22174 + remap_src[remap_pairs][len] = '\0';
22175 + remap_dst[remap_pairs] = xstrdup(arg_dst);
22176 + ++remap_pairs;
22179 +static const char *
22180 +cpp_remap_file (const char *arg, char **tmp_name)
22182 + char *result;
22183 + size_t i, len;
22185 + for (i = 0; i < remap_pairs; ++i) {
22186 + len = strlen (remap_src[i]);
22187 + if (strncmp (remap_src[i], arg, len))
22188 + continue;
22189 + if (arg[len] == '\0')
22190 + return remap_dst[i];
22191 + if (arg[len] != '/')
22192 + continue;
22193 + arg += len;
22194 + len = strlen (remap_dst[i]);
22195 + result = (char *) xmalloc (len + strlen (arg) + 1);
22196 + memcpy(result, remap_dst[i], len);
22197 + strcpy(result + len, arg);
22198 + *tmp_name = result;
22200 + return result;
22203 + return arg;
22206 /* Helper function for builtin_macro. Returns the text generated by
22207 a builtin macro. */
22208 const uchar *
22209 @@ -273,6 +328,7 @@
22211 unsigned int len;
22212 const char *name;
22213 + char *tmp_name;
22214 uchar *buf;
22216 if (node->value.builtin == BT_FILE)
22217 @@ -284,11 +340,14 @@
22218 if (!name)
22219 abort ();
22221 + tmp_name = NULL;
22222 + name = cpp_remap_file (name, &tmp_name);
22223 len = strlen (name);
22224 buf = _cpp_unaligned_alloc (pfile, len * 2 + 3);
22225 result = buf;
22226 *buf = '"';
22227 buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len);
22228 + free (tmp_name);
22229 *buf++ = '"';
22230 *buf = '\0';
22232 @@ -775,6 +834,7 @@
22233 memset (args, 0, argc * sizeof (macro_arg));
22234 buff->cur = (unsigned char *) &args[argc];
22235 arg = args, argc = 0;
22236 + pfile->state.collecting_args = 1;
22238 /* Collect the tokens making up each argument. We don't yet know
22239 how many arguments have been supplied, whether too many or too
22240 @@ -910,6 +970,7 @@
22243 while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF);
22244 + pfile->state.collecting_args = 0;
22246 if (token->type == CPP_EOF)
22248 diff -rNU3 dist.orig/libdecnumber/.gitignore dist/libdecnumber/.gitignore
22249 --- dist.orig/libdecnumber/.gitignore 2011-03-29 03:58:42.000000000 +0200
22250 +++ dist/libdecnumber/.gitignore 1970-01-01 01:00:00.000000000 +0100
22251 @@ -1 +0,0 @@
22252 -/gstdint.h
22253 diff -rNU3 dist.orig/libdecnumber/configure dist/libdecnumber/configure
22254 --- dist.orig/libdecnumber/configure 2012-11-05 00:08:42.000000000 +0100
22255 +++ dist/libdecnumber/configure 2015-10-18 13:19:51.000000000 +0200
22256 @@ -4463,7 +4463,7 @@
22257 for ac_t in install-sh install.sh shtool; do
22258 if test -f "$ac_dir/$ac_t"; then
22259 ac_aux_dir=$ac_dir
22260 - ac_install_sh="$ac_aux_dir/$ac_t -c"
22261 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
22262 break 2
22264 done
22265 diff -rNU3 dist.orig/libgcc/Makefile.in dist/libgcc/Makefile.in
22266 --- dist.orig/libgcc/Makefile.in 2013-02-04 20:06:20.000000000 +0100
22267 +++ dist/libgcc/Makefile.in 2015-10-18 13:19:52.000000000 +0200
22268 @@ -1010,7 +1010,7 @@
22269 dest=$(gcc_objdir)/include/tmp$$$$-unwind.h; \
22270 cp unwind.h $$dest; \
22271 chmod a+r $$dest; \
22272 - sh $(srcdir)/../move-if-change $$dest $(gcc_objdir)/include/unwind.h
22273 + $(SHELL) $(srcdir)/../move-if-change $$dest $(gcc_objdir)/include/unwind.h
22275 # Copy unwind.h to the place where gcc will look at run-time, once installed
22277 diff -rNU3 dist.orig/libgcc/config/arm/pr-support.c dist/libgcc/config/arm/pr-support.c
22278 --- dist.orig/libgcc/config/arm/pr-support.c 2013-02-04 20:06:20.000000000 +0100
22279 +++ dist/libgcc/config/arm/pr-support.c 2015-10-18 13:19:51.000000000 +0200
22280 @@ -352,7 +352,7 @@
22282 /* Find the Language specific exception data. */
22284 -void *
22285 +_Unwind_Ptr
22286 _Unwind_GetLanguageSpecificData (_Unwind_Context * context)
22288 _Unwind_Control_Block *ucbp;
22289 @@ -366,7 +366,7 @@
22290 /* Skip the unwind opcodes. */
22291 ptr += (((*ptr) >> 24) & 0xff) + 1;
22293 - return ptr;
22294 + return (_Unwind_Ptr) ptr;
22298 diff -rNU3 dist.orig/libgcc/config/arm/t-netbsd dist/libgcc/config/arm/t-netbsd
22299 --- dist.orig/libgcc/config/arm/t-netbsd 2011-11-02 16:23:48.000000000 +0100
22300 +++ dist/libgcc/config/arm/t-netbsd 2015-10-18 13:19:51.000000000 +0200
22301 @@ -1,7 +1,18 @@
22302 +# This list is from t-elf, but with some things removed.
22303 +LIB1ASMFUNCS += _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
22304 + _call_via_rX _interwork_call_via_rX \
22305 + _arm_fixunsdfsi _arm_fixunssfsi \
22306 + _arm_floatdidf _arm_floatdisf _arm_floatundidf _arm_floatundisf \
22307 + _lshrdi3 _ashrdi3 _ashldi3 \
22308 + _clzsi2 _clzdi2 _ctzsi2
22310 # Just for these, we omit the frame pointer since it makes such a big
22311 # difference. It is then pointless adding debugging.
22312 HOST_LIBGCC2_CFLAGS += -fomit-frame-pointer
22314 -LIBGCC2_DEBUG_CFLAGS = -g0
22316 LIB2ADD += $(srcdir)/floatunsidf.c $(srcdir)/floatunsisf.c
22318 +# Currently there is a bug somewhere in GCC's alias analysis
22319 +# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
22320 +# Disabling function inlining is a workaround for this problem.
22321 +HOST_LIBGCC2_CFLAGS += -fno-inline
22322 diff -rNU3 dist.orig/libgcc/config/arm/t-netbsd-eabi dist/libgcc/config/arm/t-netbsd-eabi
22323 --- dist.orig/libgcc/config/arm/t-netbsd-eabi 1970-01-01 01:00:00.000000000 +0100
22324 +++ dist/libgcc/config/arm/t-netbsd-eabi 2015-10-18 13:19:51.000000000 +0200
22325 @@ -0,0 +1,19 @@
22326 +# This list is from t-elf, but with lots removed.
22327 +LIB1ASMFUNCS += _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX \
22328 + _clzsi2 _clzdi2 _ctzsi2
22330 +# Derived from t-bpabi
22331 +# Add the BPABI C functions.
22332 +LIB2ADD += $(srcdir)/config/arm/unaligned-funcs.c
22334 +LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \
22335 + $(srcdir)/config/arm/libunwind.S \
22336 + $(srcdir)/config/arm/pr-support.c $(srcdir)/unwind-c.c
22338 +# Add the BPABI names.
22339 +SHLIB_MAPFILES += $(srcdir)/config/arm/libgcc-bpabi.ver
22341 +# On ARM, specifying -fnon-call-exceptions will needlessly pull in
22342 +# the unwinder in simple programs which use 64-bit division. Omitting
22343 +# the option is safe.
22344 +LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions
22345 diff -rNU3 dist.orig/libgcc/config/c6x/pr-support.c dist/libgcc/config/c6x/pr-support.c
22346 --- dist.orig/libgcc/config/c6x/pr-support.c 2013-02-04 20:06:20.000000000 +0100
22347 +++ dist/libgcc/config/c6x/pr-support.c 2015-10-18 13:19:51.000000000 +0200
22348 @@ -518,7 +518,7 @@
22349 return (_Unwind_Ptr) ucbp->pr_cache.fnstart;
22352 -void *
22353 +_Unwind_Ptr
22354 _Unwind_GetLanguageSpecificData (_Unwind_Context *context)
22356 _Unwind_Control_Block *ucbp;
22357 @@ -531,5 +531,5 @@
22358 /* Skip the unwind opcodes. */
22359 ptr += (((*ptr) >> 24) & 0xff) + 1;
22361 - return ptr;
22362 + return (_Unwind_Ptr) ptr;
22364 diff -rNU3 dist.orig/libgcc/config/cr16/unwind-cr16.c dist/libgcc/config/cr16/unwind-cr16.c
22365 --- dist.orig/libgcc/config/cr16/unwind-cr16.c 2013-02-04 20:06:20.000000000 +0100
22366 +++ dist/libgcc/config/cr16/unwind-cr16.c 2015-10-18 13:19:51.000000000 +0200
22367 @@ -347,7 +347,7 @@
22368 context->ra = (void *) val;
22371 -void *
22372 +_Unwind_Ptr
22373 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
22375 return context->lsda;
22376 diff -rNU3 dist.orig/libgcc/config/ia64/unwind-ia64.c dist/libgcc/config/ia64/unwind-ia64.c
22377 --- dist.orig/libgcc/config/ia64/unwind-ia64.c 2013-02-04 20:06:20.000000000 +0100
22378 +++ dist/libgcc/config/ia64/unwind-ia64.c 2015-10-18 13:19:52.000000000 +0200
22379 @@ -1715,10 +1715,10 @@
22380 context->rp = val;
22383 -void *
22384 +_Unwind_Ptr
22385 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
22387 - return context->lsda;
22388 + return (_Unwind_Ptr)context->lsda;
22391 _Unwind_Ptr
22392 @@ -2445,6 +2445,16 @@
22393 return _Unwind_GetIP (context);
22396 +#ifdef __NetBSD__
22397 +/* dummy for bootstrapping purposes */
22398 +struct unw_table_entry *
22399 +_Unwind_FindTableEntry (void *pc, unw_word *segment_base,
22400 + unw_word *gp, struct unw_table_entry *ent)
22402 + return NULL;
22404 +#endif
22406 #include "unwind.inc"
22408 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
22409 diff -rNU3 dist.orig/libgcc/config/m68k/fpgnulib.c dist/libgcc/config/m68k/fpgnulib.c
22410 --- dist.orig/libgcc/config/m68k/fpgnulib.c 2011-11-02 16:23:48.000000000 +0100
22411 +++ dist/libgcc/config/m68k/fpgnulib.c 2015-10-18 13:19:52.000000000 +0200
22412 @@ -395,6 +395,7 @@
22413 float __truncdfsf2 (double);
22414 long __fixdfsi (double);
22415 long __fixsfsi (float);
22416 +long __cmpdf2 (double, double);
22419 __unordxf2(long double a, long double b)
22420 diff -rNU3 dist.orig/libgcc/config/m68k/t-floatlib dist/libgcc/config/m68k/t-floatlib
22421 --- dist.orig/libgcc/config/m68k/t-floatlib 2011-11-02 16:23:48.000000000 +0100
22422 +++ dist/libgcc/config/m68k/t-floatlib 2015-10-18 13:19:52.000000000 +0200
22423 @@ -1,6 +1,6 @@
22424 LIB1ASMSRC = m68k/lb1sf68.S
22425 LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
22426 - _double _float _floatex \
22427 + _floatex _float _double \
22428 _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
22429 _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
22431 diff -rNU3 dist.orig/libgcc/config/m68k/t-netbsd-m68010 dist/libgcc/config/m68k/t-netbsd-m68010
22432 --- dist.orig/libgcc/config/m68k/t-netbsd-m68010 1970-01-01 01:00:00.000000000 +0100
22433 +++ dist/libgcc/config/m68k/t-netbsd-m68010 2015-10-18 13:19:52.000000000 +0200
22434 @@ -0,0 +1,5 @@
22435 +LIB1ASMSRC = m68k/lb1sf68.S
22436 +LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
22437 + _double _float _floatex \
22438 + _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
22439 + _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
22440 diff -rNU3 dist.orig/libgcc/config/or1k/crti.S dist/libgcc/config/or1k/crti.S
22441 --- dist.orig/libgcc/config/or1k/crti.S 1970-01-01 01:00:00.000000000 +0100
22442 +++ dist/libgcc/config/or1k/crti.S 2015-10-18 13:19:52.000000000 +0200
22443 @@ -0,0 +1,36 @@
22444 +# Start .init and .fini sections.
22445 +# Copyright (C) 2010 Embecosm Limited
22447 +# This file is free software; you can redistribute it and/or modify it
22448 +# under the terms of the GNU General Public License as published by
22449 +# the Free Software Foundation; either version 3, or (at your option)
22450 +# any later version.
22452 +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22453 +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
22454 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22455 +# for more details.
22457 +# Under Section 7 of GPL version 3, you are granted additional
22458 +# permissions described in the GCC Runtime Library Exception, version
22459 +# 3.1, as published by the Free Software Foundation.
22461 +# You should have received a copy of the GNU General Public License and
22462 +# a copy of the GCC Runtime Library Exception along with this program;
22463 +# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22464 +# <http://www.gnu.org/licenses/>.
22466 +#include "or1k-asm.h"
22468 + .section .init
22469 + .global _init
22470 + l.nop # So _init doesn't start at 0
22471 +_init:
22472 + l.addi r1,r1,-4
22473 + l.sw 0(r1),r9
22475 + .section .fini
22476 + .global _fini
22477 +_fini:
22478 + l.addi r1,r1,-4
22479 + l.sw 0(r1),r9
22480 diff -rNU3 dist.orig/libgcc/config/or1k/crtn.S dist/libgcc/config/or1k/crtn.S
22481 --- dist.orig/libgcc/config/or1k/crtn.S 1970-01-01 01:00:00.000000000 +0100
22482 +++ dist/libgcc/config/or1k/crtn.S 2015-10-18 13:19:52.000000000 +0200
22483 @@ -0,0 +1,37 @@
22484 +# End .init and .fini sections.
22485 +# Copyright (C) 2010 Embecosm Limited
22487 +# This file is free software; you can redistribute it and/or modify it
22488 +# under the terms of the GNU General Public License as published by
22489 +# the Free Software Foundation; either version 3, or (at your option)
22490 +# any later version.
22492 +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22493 +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
22494 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22495 +# for more details.
22497 +# Under Section 7 of GPL version 3, you are granted additional
22498 +# permissions described in the GCC Runtime Library Exception, version
22499 +# 3.1, as published by the Free Software Foundation.
22501 +# You should have received a copy of the GNU General Public License and
22502 +# a copy of the GCC Runtime Library Exception along with this program;
22503 +# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22504 +# <http://www.gnu.org/licenses/>.
22506 +#include "or1k-asm.h"
22508 + .section .init
22509 + l.lwz r9,0(r1)
22510 + OR1K_DELAYED(
22511 + OR1K_INST(l.addi r1,r1,4),
22512 + OR1K_INST(l.jr r9)
22515 + .section .fini
22516 + l.lwz r9,0(r1)
22517 + OR1K_DELAYED(
22518 + OR1K_INST(l.addi r1,r1,4),
22519 + OR1K_INST(l.jr r9)
22521 diff -rNU3 dist.orig/libgcc/config/or1k/linux-unwind.h dist/libgcc/config/or1k/linux-unwind.h
22522 --- dist.orig/libgcc/config/or1k/linux-unwind.h 1970-01-01 01:00:00.000000000 +0100
22523 +++ dist/libgcc/config/or1k/linux-unwind.h 2015-10-18 13:19:52.000000000 +0200
22524 @@ -0,0 +1,77 @@
22525 +/* DWARF2 EH unwinding support for OpenRISC.
22526 + Copyright (C) 2011, 2012
22527 + Free Software Foundation, Inc.
22529 +This file is part of GCC.
22531 +GCC is free software; you can redistribute it and/or modify
22532 +it under the terms of the GNU General Public License as published by
22533 +the Free Software Foundation; either version 3, or (at your option)
22534 +any later version.
22536 +GCC is distributed in the hope that it will be useful,
22537 +but WITHOUT ANY WARRANTY; without even the implied warranty of
22538 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22539 +GNU General Public License for more details.
22541 +Under Section 7 of GPL version 3, you are granted additional
22542 +permissions described in the GCC Runtime Library Exception, version
22543 +3.1, as published by the Free Software Foundation.
22545 +You should have received a copy of the GNU General Public License and
22546 +a copy of the GCC Runtime Library Exception along with this program;
22547 +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22548 +<http://www.gnu.org/licenses/>. */
22550 +#ifndef inhibit_libc
22552 +#include <signal.h>
22553 +#include <sys/ucontext.h>
22554 +#include <linux/unistd.h>
22556 +#define MD_FALLBACK_FRAME_STATE_FOR or1k_fallback_frame_state
22558 +static _Unwind_Reason_Code
22559 +or1k_fallback_frame_state (struct _Unwind_Context *context,
22560 + _Unwind_FrameState *fs)
22562 + struct rt_sigframe {
22563 + siginfo_t info;
22564 + struct ucontext uc;
22565 + } *frame = context->cfa;
22567 + struct sigcontext *sc;
22568 + unsigned char *pc = context->ra;
22569 + long new_cfa;
22570 + int i;
22572 + /*
22573 + * Note: These have to be the same as in the kernel.
22574 + * Please see arch/openrisc/kernel/signal.c
22575 + */
22576 + if (!(*(unsigned short *)(pc + 0) == 0xa960
22577 + && *(unsigned short *)(pc + 2) == __NR_rt_sigreturn
22578 + && *(unsigned long *)(pc + 4) == 0x20000001
22579 + && *(unsigned long *)(pc + 8) == 0x15000000))
22580 + return _URC_END_OF_STACK;
22582 + sc = (struct sigcontext *) &frame->uc.uc_mcontext;
22584 + new_cfa = sc->regs.gpr[1];
22585 + fs->regs.cfa_how = CFA_REG_OFFSET;
22586 + fs->regs.cfa_reg = STACK_POINTER_REGNUM;
22587 + fs->regs.cfa_offset = new_cfa - (long) context->cfa;
22589 + for (i = 0; i < 32; ++i)
22591 + fs->regs.reg[i].how = REG_SAVED_OFFSET;
22592 + fs->regs.reg[i].loc.offset = (long)&sc->regs.gpr[i] - new_cfa;
22595 + fs->retaddr_column = 9;
22596 + fs->signal_frame = 1;
22598 + return _URC_NO_REASON;
22601 +#endif /* ifdef inhibit_libc */
22602 diff -rNU3 dist.orig/libgcc/config/or1k/or1k-asm.h dist/libgcc/config/or1k/or1k-asm.h
22603 --- dist.orig/libgcc/config/or1k/or1k-asm.h 1970-01-01 01:00:00.000000000 +0100
22604 +++ dist/libgcc/config/or1k/or1k-asm.h 2015-10-18 13:19:52.000000000 +0200
22605 @@ -0,0 +1,20 @@
22606 +#ifndef OR1K_ASM_H
22607 +#define OR1K_ASM_H
22609 +#define OR1K_INST(...) __VA_ARGS__
22611 +#if defined(__OR1K_NODELAY__)
22612 +#define OR1K_DELAYED(a, b) a; b
22613 +#define OR1K_DELAYED_NOP(a) a
22614 +.nodelay
22615 +#elif defined(__OR1K_DELAY__)
22616 +#define OR1K_DELAYED(a, b) b; a
22617 +#define OR1K_DELAYED_NOP(a) a; l.nop
22618 +#elif defined(__OR1K_DELAY_COMPAT__)
22619 +#define OR1K_DELAYED(a, b) a; b; l.nop
22620 +#define OR1K_DELAYED_NOP(a) a; l.nop
22621 +#else
22622 +#error One of __OR1K_NODELAY__, __OR1K_DELAY__, or __OR1K_DELAY_COMPAT__ must be defined
22623 +#endif
22625 +#endif
22626 diff -rNU3 dist.orig/libgcc/config/or1k/or1k.S dist/libgcc/config/or1k/or1k.S
22627 --- dist.orig/libgcc/config/or1k/or1k.S 1970-01-01 01:00:00.000000000 +0100
22628 +++ dist/libgcc/config/or1k/or1k.S 2015-10-18 13:19:52.000000000 +0200
22629 @@ -0,0 +1,237 @@
22630 +#include "or1k-asm.h"
22632 + * Assembly functions for software multiplication and devision.
22633 + */
22635 +#define ENTRY(symbol) \
22636 + .align 4 ;\
22637 + .global symbol ;\
22638 + .type symbol, @function ;\
22639 +symbol:
22641 +#ifdef L__mulsi3
22642 +ENTRY(__mulsi3)
22643 + l.addi r11,r0,0x0
22644 + l.sfne r3,r11
22645 +OR1K_DELAYED(
22646 + OR1K_INST(l.ori r5,r3,0x0),
22647 + OR1K_INST(l.bnf 3f)
22649 + l.addi r6,r0,0x0
22651 + l.andi r3,r5,0x1
22652 + l.sfeq r3,r6
22653 +OR1K_DELAYED(
22654 + OR1K_INST(l.srli r5,r5,0x1),
22655 + OR1K_INST(l.bf 2f)
22657 + l.add r11,r11,r4
22659 + l.sfne r5,r6
22660 +OR1K_DELAYED(
22661 + OR1K_INST(l.slli r4,r4,0x1),
22662 + OR1K_INST(l.bf 1b)
22665 +OR1K_DELAYED_NOP(
22666 + OR1K_INST(l.jr r9)
22668 +.size __mulsi3,.-__mulsi3
22669 +#endif
22671 +#ifdef L__udivsi3
22672 +.global __udivsi3_internal
22673 +.hidden __udivsi3_internal
22674 +__udivsi3_internal:
22675 +ENTRY(__udivsi3)
22676 + l.addi r1,r1,-4
22677 + l.sw 0(r1),r9
22678 + l.addi r11,r0,0
22679 + l.addi r8,r4,0
22680 + l.addi r5,r3,0
22681 + l.sfne r8,r11
22682 +OR1K_DELAYED(
22683 + OR1K_INST(l.addi r7,r0,0),
22684 + OR1K_INST(l.bnf 4f)
22686 + /* The following work equally on delay and no-delay implementations */
22687 + l.sfgtu r8,r5
22688 + l.bf 5f
22689 + l.sfeq r8,r5
22690 + l.bf 6f
22691 + l.sfltu r11,r8
22693 +OR1K_DELAYED(
22694 + OR1K_INST(l.addi r13,r0,32),
22695 + OR1K_INST(l.bnf 2f)
22697 + l.movhi r9,hi(0x80000000)
22698 + l.addi r6,r0,-1
22700 + l.and r3,r5,r9
22701 + l.slli r4,r7,1
22702 + l.addi r15,r5,0
22703 + l.srli r3,r3,31
22704 + l.add r13,r13,r6
22705 + l.or r7,r4,r3
22706 + l.sfltu r7,r8
22707 +OR1K_DELAYED(
22708 + OR1K_INST(l.slli r5,r5,1),
22709 + OR1K_INST(l.bf 1b)
22712 + l.srli r7,r7,1
22713 + l.addi r13,r13,1
22714 + l.addi r9,r0,0
22715 + l.sfltu r9,r13
22716 +OR1K_DELAYED(
22717 + OR1K_INST(l.addi r5,r15,0),
22718 + OR1K_INST(l.bnf 4f)
22720 + l.movhi r15,hi(0x80000000)
22721 + l.addi r17,r0,0
22723 + l.and r3,r5,r15
22724 + l.slli r4,r7,1
22725 + l.srli r3,r3,31
22726 + l.or r7,r4,r3
22727 + l.sub r6,r7,r8
22728 + l.and r3,r6,r15
22729 + l.srli r3,r3,31
22730 + l.addi r4,r0,0
22731 + l.sfne r3,r4
22732 +OR1K_DELAYED(
22733 + OR1K_INST(l.slli r3,r11,1),
22734 + OR1K_INST(l.bf 1f)
22736 + l.addi r4,r0,1
22738 + l.slli r5,r5,1
22739 + l.sfne r4,r17
22740 +OR1K_DELAYED(
22741 + OR1K_INST(l.or r11,r3,r4),
22742 + OR1K_INST(l.bnf 2f)
22744 + l.addi r7,r6,0
22746 + l.addi r9,r9,1
22747 + l.sfltu r9,r13
22748 +OR1K_DELAYED_NOP(
22749 + OR1K_INST(l.bf 3b)
22751 +OR1K_DELAYED_NOP(
22752 + OR1K_INST(l.j 4f)
22755 +OR1K_DELAYED(
22756 + OR1K_INST(l.addi r11,r0,1),
22757 + OR1K_INST(l.j 4f)
22760 + l.addi r7,r5,0
22762 + l.lwz r9,0(r1)
22763 +OR1K_DELAYED(
22764 + OR1K_INST(l.addi r1,r1,4),
22765 + OR1K_INST(l.jr r9)
22767 +.size __udivsi3,.-__udivsi3
22768 +#endif
22771 +#ifdef L__divsi3
22772 +ENTRY(__divsi3)
22773 + l.addi r1,r1,-8
22774 + l.sw 0(r1),r9
22775 + l.sw 4(r1),r14
22776 + l.addi r5,r3,0
22777 + l.addi r14,r0,0
22778 + l.sflts r5,r0
22779 +OR1K_DELAYED(
22780 + OR1K_INST(l.addi r3,r0,0),
22781 + OR1K_INST(l.bnf 1f)
22783 + l.addi r14,r0,1
22784 + l.sub r5,r0,r5
22786 + l.sflts r4,r0
22787 +OR1K_DELAYED_NOP(
22788 + OR1K_INST(l.bnf 1f)
22790 + l.addi r14,r14,1
22791 + l.sub r4,r0,r4
22793 +OR1K_DELAYED(
22794 + OR1K_INST(l.addi r3,r5,0),
22795 + OR1K_INST(l.jal __udivsi3_internal)
22797 + l.sfeqi r14,1
22798 +OR1K_DELAYED_NOP(
22799 + OR1K_INST(l.bnf 1f)
22801 + l.sub r11,r0,r11
22803 + l.lwz r9,0(r1)
22804 + l.lwz r14,4(r1)
22805 +OR1K_DELAYED(
22806 + OR1K_INST(l.addi r1,r1,8),
22807 + OR1K_INST(l.jr r9)
22809 +.size __divsi3,.-__divsi3
22810 +#endif
22813 +#ifdef L__umodsi3
22814 +ENTRY(__umodsi3)
22815 + l.addi r1,r1,-4
22816 + l.sw 0(r1),r9
22817 +OR1K_DELAYED_NOP(
22818 + OR1K_INST(l.jal __udivsi3_internal)
22820 + l.addi r11,r7,0
22821 + l.lwz r9,0(r1)
22822 +OR1K_DELAYED(
22823 + OR1K_INST(l.addi r1,r1,4),
22824 + OR1K_INST(l.jr r9)
22826 +.size __umodsi3,.-__umodsi3
22827 +#endif
22830 +#ifdef L__modsi3
22831 +ENTRY(__modsi3)
22832 + l.addi r1,r1,-8
22833 + l.sw 0(r1),r9
22834 + l.sw 4(r1),r14
22835 + l.addi r14,r0,0
22836 + l.sflts r3,r0
22837 +OR1K_DELAYED_NOP(
22838 + OR1K_INST(l.bnf 1f)
22840 + l.addi r14,r0,1
22841 + l.sub r3,r0,r3
22843 + l.sflts r4,r0
22844 +OR1K_DELAYED_NOP(
22845 + OR1K_INST(l.bnf 1f)
22847 + l.sub r4,r0,r4
22849 +OR1K_DELAYED_NOP(
22850 + OR1K_INST(l.jal __udivsi3_internal)
22852 + l.sfeqi r14,1
22853 +OR1K_DELAYED(
22854 + OR1K_INST(l.addi r11,r7,0),
22855 + OR1K_INST(l.bnf 1f)
22857 + l.sub r11,r0,r11
22859 + l.lwz r9,0(r1)
22860 + l.lwz r14,4(r1)
22861 +OR1K_DELAYED(
22862 + OR1K_INST(l.addi r1,r1,8),
22863 + OR1K_INST(l.jr r9)
22865 +.size __modsi3,.-__modsi3
22866 +#endif
22867 diff -rNU3 dist.orig/libgcc/config/or1k/sfp-machine.h dist/libgcc/config/or1k/sfp-machine.h
22868 --- dist.orig/libgcc/config/or1k/sfp-machine.h 1970-01-01 01:00:00.000000000 +0100
22869 +++ dist/libgcc/config/or1k/sfp-machine.h 2015-10-18 13:19:52.000000000 +0200
22870 @@ -0,0 +1,54 @@
22871 +#define _FP_W_TYPE_SIZE 32
22872 +#define _FP_W_TYPE unsigned long
22873 +#define _FP_WS_TYPE signed long
22874 +#define _FP_I_TYPE long
22876 +#define _FP_MUL_MEAT_S(R,X,Y) \
22877 + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
22878 +#define _FP_MUL_MEAT_D(R,X,Y) \
22879 + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
22880 +#define _FP_MUL_MEAT_Q(R,X,Y) \
22881 + _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
22883 +#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
22884 +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
22885 +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
22887 +#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
22888 +#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
22889 +#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
22890 +#define _FP_NANSIGN_S 0
22891 +#define _FP_NANSIGN_D 0
22892 +#define _FP_NANSIGN_Q 0
22894 +#define _FP_KEEPNANFRACP 1
22895 +#define _FP_QNANNEGATEDP 0
22897 +/* Someone please check this. */
22898 +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
22899 + do { \
22900 + if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
22901 + && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
22902 + { \
22903 + R##_s = Y##_s; \
22904 + _FP_FRAC_COPY_##wc(R,Y); \
22905 + } \
22906 + else \
22907 + { \
22908 + R##_s = X##_s; \
22909 + _FP_FRAC_COPY_##wc(R,X); \
22910 + } \
22911 + R##_c = FP_CLS_NAN; \
22912 + } while (0)
22914 +#define __LITTLE_ENDIAN 1234
22915 +#define __BIG_ENDIAN 4321
22917 +#define __BYTE_ORDER __BIG_ENDIAN
22919 +#define _FP_TININESS_AFTER_ROUNDING 0
22921 +/* Define ALIASNAME as a strong alias for NAME. */
22922 +# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
22923 +# define _strong_alias(name, aliasname) \
22924 + extern __typeof (name) aliasname __attribute__ ((alias (#name)));
22925 diff -rNU3 dist.orig/libgcc/config/or1k/t-crtstuff dist/libgcc/config/or1k/t-crtstuff
22926 --- dist.orig/libgcc/config/or1k/t-crtstuff 1970-01-01 01:00:00.000000000 +0100
22927 +++ dist/libgcc/config/or1k/t-crtstuff 2015-10-18 13:19:52.000000000 +0200
22928 @@ -0,0 +1,4 @@
22929 +# This will prevent gcc from appending data to .eh_frame.
22930 +# Other archs use fno-asynchronous-unwind-tables but we do not have that flag.
22931 +CRTSTUFF_T_CFLAGS += -fno-dwarf2-cfi-asm
22932 +CRTSTUFF_T_CFLAGS_S += -fno-dwarf2-cfi-asm
22933 diff -rNU3 dist.orig/libgcc/config/or1k/t-linux dist/libgcc/config/or1k/t-linux
22934 --- dist.orig/libgcc/config/or1k/t-linux 1970-01-01 01:00:00.000000000 +0100
22935 +++ dist/libgcc/config/or1k/t-linux 2015-10-18 13:19:52.000000000 +0200
22936 @@ -0,0 +1,2 @@
22937 +MULTILIB_DIRNAMES = be
22938 +EXTRA_MULTILIB_PARTS = crti.o crtbegin.o crtend.o crtn.o
22939 diff -rNU3 dist.orig/libgcc/config/or1k/t-or1k dist/libgcc/config/or1k/t-or1k
22940 --- dist.orig/libgcc/config/or1k/t-or1k 1970-01-01 01:00:00.000000000 +0100
22941 +++ dist/libgcc/config/or1k/t-or1k 2015-10-18 13:19:52.000000000 +0200
22942 @@ -0,0 +1,23 @@
22943 +# t-or1k is a Makefile fragment to be included when
22944 +# building gcc for the or1k target
22946 +# Copyright (C) 2010 Embecosm Limited
22948 +# This file is part of GCC.
22950 +# GCC is free software; you can redistribute it and/or modify
22951 +# it under the terms of the GNU General Public License as published by
22952 +# the Free Software Foundation; either version 3, or (at your option)
22953 +# any later version.
22955 +# GCC is distributed in the hope that it will be useful,
22956 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
22957 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22958 +# GNU General Public License for more details.
22960 +# You should have received a copy of the GNU General Public License
22961 +# along with GCC; see the file COPYING3. If not see
22962 +# <http://www.gnu.org/licenses/>.
22964 +LIB1ASMSRC = or1k/or1k.S
22965 +LIB1ASMFUNCS = __mulsi3 __udivsi3 __divsi3 __umodsi3 __modsi3
22966 diff -rNU3 dist.orig/libgcc/config/pa/t-netbsd dist/libgcc/config/pa/t-netbsd
22967 --- dist.orig/libgcc/config/pa/t-netbsd 1970-01-01 01:00:00.000000000 +0100
22968 +++ dist/libgcc/config/pa/t-netbsd 2015-10-18 13:19:52.000000000 +0200
22969 @@ -0,0 +1,9 @@
22970 +#Plug millicode routines into libgcc.a We want these on both native and
22971 +#cross compiles. We use the "64-bit" routines because the "32-bit" code
22972 +#is broken for certain corner cases.
22973 +LIB1ASMSRC = pa/milli64.S
22974 +LIB1ASMFUNCS = _divI _divU _remI _remU _div_const _mulI _dyncall
22976 +HOST_LIBGCC2_CFLAGS += -DELF=1 -DLINUX=1
22978 +LIB2ADD = $(srcdir)/config/pa/fptr.c
22979 diff -rNU3 dist.orig/libgcc/config/riscv/crti.S dist/libgcc/config/riscv/crti.S
22980 --- dist.orig/libgcc/config/riscv/crti.S 1970-01-01 01:00:00.000000000 +0100
22981 +++ dist/libgcc/config/riscv/crti.S 2015-10-18 13:19:52.000000000 +0200
22982 @@ -0,0 +1 @@
22983 +/* crti.S is empty because .init_array/.fini_array are used exclusively. */
22984 diff -rNU3 dist.orig/libgcc/config/riscv/crtn.S dist/libgcc/config/riscv/crtn.S
22985 --- dist.orig/libgcc/config/riscv/crtn.S 1970-01-01 01:00:00.000000000 +0100
22986 +++ dist/libgcc/config/riscv/crtn.S 2015-10-18 13:19:52.000000000 +0200
22987 @@ -0,0 +1 @@
22988 +/* crtn.S is empty because .init_array/.fini_array are used exclusively. */
22989 diff -rNU3 dist.orig/libgcc/config/riscv/riscv-fp.c dist/libgcc/config/riscv/riscv-fp.c
22990 --- dist.orig/libgcc/config/riscv/riscv-fp.c 1970-01-01 01:00:00.000000000 +0100
22991 +++ dist/libgcc/config/riscv/riscv-fp.c 2015-10-18 13:19:52.000000000 +0200
22992 @@ -0,0 +1,178 @@
22993 +/* Functions needed for soft-float on riscv-linux. Based on
22994 + rs6000/ppc64-fp.c with TF types removed.
22996 + Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
22997 + 2000, 2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation,
22998 + Inc.
23000 +This file is part of GCC.
23002 +GCC is free software; you can redistribute it and/or modify it under
23003 +the terms of the GNU General Public License as published by the Free
23004 +Software Foundation; either version 3, or (at your option) any later
23005 +version.
23007 +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23008 +WARRANTY; without even the implied warranty of MERCHANTABILITY or
23009 +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23010 +for more details.
23012 +Under Section 7 of GPL version 3, you are granted additional
23013 +permissions described in the GCC Runtime Library Exception, version
23014 +3.1, as published by the Free Software Foundation.
23016 +You should have received a copy of the GNU General Public License and
23017 +a copy of the GCC Runtime Library Exception along with this program;
23018 +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23019 +<http://www.gnu.org/licenses/>. */
23021 +#if defined(__riscv64)
23022 +#include "fp-bit.h"
23024 +extern DItype __fixdfdi (DFtype);
23025 +extern DItype __fixsfdi (SFtype);
23026 +extern USItype __fixunsdfsi (DFtype);
23027 +extern USItype __fixunssfsi (SFtype);
23028 +extern DFtype __floatdidf (DItype);
23029 +extern DFtype __floatundidf (UDItype);
23030 +extern SFtype __floatdisf (DItype);
23031 +extern SFtype __floatundisf (UDItype);
23033 +static DItype local_fixunssfdi (SFtype);
23034 +static DItype local_fixunsdfdi (DFtype);
23036 +DItype
23037 +__fixdfdi (DFtype a)
23039 + if (a < 0)
23040 + return - local_fixunsdfdi (-a);
23041 + return local_fixunsdfdi (a);
23044 +DItype
23045 +__fixsfdi (SFtype a)
23047 + if (a < 0)
23048 + return - local_fixunssfdi (-a);
23049 + return local_fixunssfdi (a);
23052 +USItype
23053 +__fixunsdfsi (DFtype a)
23055 + if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
23056 + return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
23057 + - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
23058 + return (SItype) a;
23061 +USItype
23062 +__fixunssfsi (SFtype a)
23064 + if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
23065 + return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
23066 + - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
23067 + return (SItype) a;
23070 +DFtype
23071 +__floatdidf (DItype u)
23073 + DFtype d;
23075 + d = (SItype) (u >> (sizeof (SItype) * 8));
23076 + d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
23077 + d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
23079 + return d;
23082 +DFtype
23083 +__floatundidf (UDItype u)
23085 + DFtype d;
23087 + d = (USItype) (u >> (sizeof (SItype) * 8));
23088 + d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
23089 + d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
23091 + return d;
23094 +SFtype
23095 +__floatdisf (DItype u)
23097 + DFtype f;
23099 + if (53 < (sizeof (DItype) * 8)
23100 + && 53 > ((sizeof (DItype) * 8) - 53 + 24))
23102 + if (! (- ((DItype) 1 << 53) < u
23103 + && u < ((DItype) 1 << 53)))
23105 + if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
23107 + u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
23108 + u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
23112 + f = (SItype) (u >> (sizeof (SItype) * 8));
23113 + f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
23114 + f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
23116 + return (SFtype) f;
23119 +SFtype
23120 +__floatundisf (UDItype u)
23122 + DFtype f;
23124 + if (53 < (sizeof (DItype) * 8)
23125 + && 53 > ((sizeof (DItype) * 8) - 53 + 24))
23127 + if (u >= ((UDItype) 1 << 53))
23129 + if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
23131 + u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
23132 + u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
23136 + f = (USItype) (u >> (sizeof (SItype) * 8));
23137 + f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
23138 + f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
23140 + return (SFtype) f;
23143 +/* This version is needed to prevent recursion; fixunsdfdi in libgcc
23144 + calls fixdfdi, which in turn calls calls fixunsdfdi. */
23146 +static DItype
23147 +local_fixunsdfdi (DFtype a)
23149 + USItype hi, lo;
23151 + hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
23152 + lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
23153 + return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
23156 +/* This version is needed to prevent recursion; fixunssfdi in libgcc
23157 + calls fixsfdi, which in turn calls calls fixunssfdi. */
23159 +static DItype
23160 +local_fixunssfdi (SFtype original_a)
23162 + DFtype a = original_a;
23163 + USItype hi, lo;
23165 + hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
23166 + lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
23167 + return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
23170 +#endif
23171 diff -rNU3 dist.orig/libgcc/config/riscv/t-dpbit dist/libgcc/config/riscv/t-dpbit
23172 --- dist.orig/libgcc/config/riscv/t-dpbit 1970-01-01 01:00:00.000000000 +0100
23173 +++ dist/libgcc/config/riscv/t-dpbit 2015-10-18 13:19:52.000000000 +0200
23174 @@ -0,0 +1,4 @@
23175 +LIB2ADD += dp-bit.c
23177 +dp-bit.c: $(srcdir)/fp-bit.c
23178 + cat $(srcdir)/fp-bit.c > dp-bit.c
23179 diff -rNU3 dist.orig/libgcc/config/riscv/t-elf dist/libgcc/config/riscv/t-elf
23180 --- dist.orig/libgcc/config/riscv/t-elf 1970-01-01 01:00:00.000000000 +0100
23181 +++ dist/libgcc/config/riscv/t-elf 2015-10-18 13:19:52.000000000 +0200
23182 @@ -0,0 +1,2 @@
23183 +# Assemble startup files.
23184 +LIB2ADD += $(srcdir)/config/riscv/riscv-fp.c
23185 diff -rNU3 dist.orig/libgcc/config/riscv/t-fpbit dist/libgcc/config/riscv/t-fpbit
23186 --- dist.orig/libgcc/config/riscv/t-fpbit 1970-01-01 01:00:00.000000000 +0100
23187 +++ dist/libgcc/config/riscv/t-fpbit 2015-10-18 13:19:52.000000000 +0200
23188 @@ -0,0 +1,5 @@
23189 +LIB2ADD += fp-bit.c
23191 +fp-bit.c: $(srcdir)/fp-bit.c
23192 + echo '#define FLOAT' > fp-bit.c
23193 + cat $(srcdir)/fp-bit.c >> fp-bit.c
23194 diff -rNU3 dist.orig/libgcc/config/riscv/t-linux dist/libgcc/config/riscv/t-linux
23195 --- dist.orig/libgcc/config/riscv/t-linux 1970-01-01 01:00:00.000000000 +0100
23196 +++ dist/libgcc/config/riscv/t-linux 2015-10-18 13:19:52.000000000 +0200
23197 @@ -0,0 +1 @@
23198 +LIB2ADD += $(srcdir)/config/riscv/riscv-fp.c
23199 diff -rNU3 dist.orig/libgcc/config/riscv/t-tpbit dist/libgcc/config/riscv/t-tpbit
23200 --- dist.orig/libgcc/config/riscv/t-tpbit 1970-01-01 01:00:00.000000000 +0100
23201 +++ dist/libgcc/config/riscv/t-tpbit 2015-10-18 13:19:52.000000000 +0200
23202 @@ -0,0 +1,10 @@
23203 +LIB2ADD += tp-bit.c
23205 +tp-bit.c: $(srcdir)/fp-bit.c
23206 + echo '#ifdef _RISCVEL' > tp-bit.c
23207 + echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c
23208 + echo '#endif' >> tp-bit.c
23209 + echo '#if __LDBL_MANT_DIG__ == 113' >> tp-bit.c
23210 + echo '# define TFLOAT' >> tp-bit.c
23211 + cat $(srcdir)/fp-bit.c >> tp-bit.c
23212 + echo '#endif' >> tp-bit.c
23213 diff -rNU3 dist.orig/libgcc/config/xtensa/unwind-dw2-xtensa.c dist/libgcc/config/xtensa/unwind-dw2-xtensa.c
23214 --- dist.orig/libgcc/config/xtensa/unwind-dw2-xtensa.c 2013-02-04 20:06:20.000000000 +0100
23215 +++ dist/libgcc/config/xtensa/unwind-dw2-xtensa.c 2015-10-18 13:19:52.000000000 +0200
23216 @@ -172,7 +172,7 @@
23217 context->ra = (void *) val;
23220 -void *
23221 +_Unwind_Ptr
23222 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
23224 return context->lsda;
23225 diff -rNU3 dist.orig/libgcc/config.host dist/libgcc/config.host
23226 --- dist.orig/libgcc/config.host 2014-03-20 17:12:30.000000000 +0100
23227 +++ dist/libgcc/config.host 2015-10-18 13:19:52.000000000 +0200
23228 @@ -137,9 +137,15 @@
23229 cpu_type=mips
23230 tmake_file=mips/t-mips
23232 +or1k-*-* | or1knd-*-*)
23233 + cpu_type=or1k
23234 + ;;
23235 powerpc*-*-*)
23236 cpu_type=rs6000
23238 +riscv*-*-*)
23239 + cpu_type=riscv
23240 + ;;
23241 rs6000*-*-*)
23243 score*-*-*)
23244 @@ -204,7 +210,7 @@
23245 extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
23247 *-*-netbsd*)
23248 - tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver"
23249 + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver"
23250 # NetBSD 1.7 and later are set up to use GCC's crtstuff for
23251 # ELF configurations. We will clear extra_parts in the
23252 # a.out configurations.
23253 @@ -320,7 +326,16 @@
23254 extra_parts="$extra_parts crti.o crtn.o"
23256 arm*-*-netbsdelf*)
23257 - tmake_file="$tmake_file arm/t-arm arm/t-netbsd t-slibgcc-gld-nover"
23258 + tmake_file="$tmake_file arm/t-arm"
23259 + case ${host} in
23260 + arm*-*-netbsdelf-*eabi*)
23261 + tmake_file="${tmake_file} arm/t-netbsd-eabi"
23262 + unwind_header=config/arm/unwind-arm.h
23263 + ;;
23264 + *)
23265 + tmake_file="${tmake_file} arm/t-netbsd t-slibgcc-gld-nover"
23266 + ;;
23267 + esac
23269 arm*-*-linux*) # ARM GNU/Linux with ELF
23270 tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix"
23271 @@ -485,6 +500,9 @@
23272 hppa*-*-openbsd*)
23273 tmake_file="$tmake_file pa/t-openbsd"
23275 +hppa*-*-netbsd*)
23276 + tmake_file="$tmake_file pa/t-netbsd"
23277 + ;;
23278 i[34567]86-*-darwin*)
23279 tmake_file="$tmake_file i386/t-crtpc i386/t-crtfm"
23280 tm_file="$tm_file i386/darwin-lib.h"
23281 @@ -640,6 +658,10 @@
23283 md_unwind_header=ia64/linux-unwind.h
23285 +ia64*-*-netbsd*)
23286 + extra_parts="${extra_parts} crtfastmath.o"
23287 + tmake_file="${tmake_file} ia64/t-ia64 ia64/t-ia64-elf ia64/t-eh-ia64 t-crtfm"
23288 + ;;
23289 ia64*-*-hpux*)
23290 tmake_file="ia64/t-ia64 ia64/t-ia64-elf ia64/t-hpux t-slibgcc ia64/t-slibgcc-hpux t-slibgcc-hpux"
23292 @@ -684,7 +706,10 @@
23293 m68k-*-elf* | fido-*-elf)
23294 tmake_file="$tmake_file m68k/t-floatlib"
23296 -m68k*-*-netbsdelf*)
23297 +m5407-*-netbsdelf*)
23298 + ;;
23299 +m68k*-*-netbsdelf* | m68010-*-netbsdelf*)
23300 + tmake_file="$tmake_file m68k/t-floatlib"
23302 m68k*-*-openbsd*)
23304 @@ -801,6 +826,17 @@
23305 # Don't use default.
23306 extra_parts=
23308 +or1k*-*-linux* | or1k*-*-uclinux*)
23309 + tmake_file="$tmake_file or1k/t-or1k or1k/t-linux or1k/t-crtstuff t-softfp-sfdf t-softfp"
23310 + md_unwind_header=or1k/linux-unwind.h
23311 + ;;
23312 +or1k*-*-netbsd*)
23313 + tmake_file="$tmake_file or1k/t-or1k"
23314 + ;;
23315 +or1k*-*-*)
23316 + tmake_file="$tmake_file or1k/t-or1k or1k/t-linux or1k/t-crtstuff t-softfp-sfdf t-softfp"
23317 + extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o crti.o crtn.o"
23318 + ;;
23319 pdp11-*-*)
23320 tmake_file="pdp11/t-pdp11 t-fdpbit"
23322 @@ -834,8 +870,8 @@
23324 esac
23326 -powerpc-*-netbsd*)
23327 - tmake_file="$tmake_file rs6000/t-netbsd rs6000/t-crtstuff"
23328 +powerpc*-*-netbsd*)
23329 + tmake_file="${tmake_file} rs6000/t-netbsd rs6000/t-crtstuff"
23331 powerpc-*-eabispe*)
23332 tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
23333 @@ -892,6 +928,17 @@
23334 tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
23335 extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
23337 +riscv*-*-linux*)
23338 + tmake_file="${tmake_file} riscv/t-fpbit riscv/t-dpbit riscv/t-tpbit riscv/t-linux"
23339 + extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o"
23340 + ;;
23341 +riscv*-*-netbsd*)
23342 + # nothing needed for NetBSD
23343 + ;;
23344 +riscv*-*-*)
23345 + tmake_file="${tmake_file} riscv/t-fpbit riscv/t-dpbit riscv/t-elf"
23346 + extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
23347 + ;;
23348 rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
23349 md_unwind_header=rs6000/aix-unwind.h
23350 tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble"
23351 diff -rNU3 dist.orig/libgcc/configure dist/libgcc/configure
23352 --- dist.orig/libgcc/configure 2012-11-05 00:08:42.000000000 +0100
23353 +++ dist/libgcc/configure 2015-10-18 13:19:52.000000000 +0200
23354 @@ -2096,7 +2096,7 @@
23355 for ac_t in install-sh install.sh shtool; do
23356 if test -f "$ac_dir/$ac_t"; then
23357 ac_aux_dir=$ac_dir
23358 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23359 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23360 break 2
23362 done
23363 diff -rNU3 dist.orig/libgcc/unwind-compat.c dist/libgcc/unwind-compat.c
23364 --- dist.orig/libgcc/unwind-compat.c 2013-02-04 20:06:20.000000000 +0100
23365 +++ dist/libgcc/unwind-compat.c 2015-10-18 13:19:52.000000000 +0200
23366 @@ -137,10 +137,10 @@
23367 return __libunwind_Unwind_GetIP (context);
23370 -extern void *__libunwind_Unwind_GetLanguageSpecificData
23371 +extern _Unwind_Ptr __libunwind_Unwind_GetLanguageSpecificData
23372 (struct _Unwind_Context *);
23374 -void *
23375 +_Unwind_Ptr
23376 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
23378 return __libunwind_Unwind_GetLanguageSpecificData (context);
23379 diff -rNU3 dist.orig/libgcc/unwind-dw2-fde-dip.c dist/libgcc/unwind-dw2-fde-dip.c
23380 --- dist.orig/libgcc/unwind-dw2-fde-dip.c 2013-02-04 20:06:20.000000000 +0100
23381 +++ dist/libgcc/unwind-dw2-fde-dip.c 2015-10-18 13:19:52.000000000 +0200
23382 @@ -32,7 +32,7 @@
23384 #include "tconfig.h"
23385 #include "tsystem.h"
23386 -#if !defined(inhibit_libc) && !defined(__OpenBSD__)
23387 +#if !defined(inhibit_libc) && defined(__GLIBC__)
23388 #include <elf.h> /* Get DT_CONFIG. */
23389 #endif
23390 #include "coretypes.h"
23391 @@ -64,6 +64,12 @@
23392 #endif
23394 #if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
23395 + && defined(__NetBSD__)
23396 +# define ElfW(type) Elf_##type
23397 +# define USE_PT_GNU_EH_FRAME
23398 +#endif
23400 +#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
23401 && defined(__OpenBSD__)
23402 # define ElfW(type) Elf_##type
23403 # define USE_PT_GNU_EH_FRAME
23404 diff -rNU3 dist.orig/libgcc/unwind-dw2-fde.c dist/libgcc/unwind-dw2-fde.c
23405 --- dist.orig/libgcc/unwind-dw2-fde.c 2013-02-04 20:06:20.000000000 +0100
23406 +++ dist/libgcc/unwind-dw2-fde.c 2015-10-18 13:19:52.000000000 +0200
23407 @@ -213,7 +213,9 @@
23409 out:
23410 __gthread_mutex_unlock (&object_mutex);
23411 +#if 0
23412 gcc_assert (ob);
23413 +#endif
23414 return (void *) ob;
23417 diff -rNU3 dist.orig/libgcc/unwind-dw2.c dist/libgcc/unwind-dw2.c
23418 --- dist.orig/libgcc/unwind-dw2.c 2013-06-01 01:21:46.000000000 +0200
23419 +++ dist/libgcc/unwind-dw2.c 2015-10-18 13:19:52.000000000 +0200
23420 @@ -365,10 +365,10 @@
23421 context->ra = (void *) val;
23424 -void *
23425 +_Unwind_Ptr
23426 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
23428 - return context->lsda;
23429 + return (_Unwind_Ptr) context->lsda;
23432 _Unwind_Ptr
23433 diff -rNU3 dist.orig/libgcc/unwind-generic.h dist/libgcc/unwind-generic.h
23434 --- dist.orig/libgcc/unwind-generic.h 2013-02-04 20:06:20.000000000 +0100
23435 +++ dist/libgcc/unwind-generic.h 2015-10-18 13:19:52.000000000 +0200
23436 @@ -177,7 +177,7 @@
23437 /* @@@ Retrieve the CFA of the given context. */
23438 extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
23440 -extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
23441 +extern _Unwind_Ptr _Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
23443 extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
23445 diff -rNU3 dist.orig/libgcc/unwind-seh.c dist/libgcc/unwind-seh.c
23446 --- dist.orig/libgcc/unwind-seh.c 2014-02-18 18:04:38.000000000 +0100
23447 +++ dist/libgcc/unwind-seh.c 2015-10-18 13:19:52.000000000 +0200
23448 @@ -131,8 +131,8 @@
23449 c->ra = val;
23452 -void *
23453 -_Unwind_GetLanguageSpecificData (struct _Unwind_Context *c)
23454 +_Unwind_Ptr
23455 +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *c
23457 return c->disp->HandlerData;
23459 diff -rNU3 dist.orig/libgcc/unwind-sjlj.c dist/libgcc/unwind-sjlj.c
23460 --- dist.orig/libgcc/unwind-sjlj.c 2013-02-04 20:06:20.000000000 +0100
23461 +++ dist/libgcc/unwind-sjlj.c 2015-10-18 13:19:52.000000000 +0200
23462 @@ -231,10 +231,10 @@
23463 context->fc->call_site = val - 1;
23466 -void *
23467 +_Unwind_Ptr
23468 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
23470 - return context->fc->lsda;
23471 + return (_Unwind_Ptr) context->fc->lsda;
23474 _Unwind_Ptr
23475 diff -rNU3 dist.orig/libgomp/Makefile.am dist/libgomp/Makefile.am
23476 --- dist.orig/libgomp/Makefile.am 2012-02-27 14:51:50.000000000 +0100
23477 +++ dist/libgomp/Makefile.am 2015-10-18 13:19:52.000000000 +0200
23478 @@ -1,7 +1,7 @@
23479 ## Process this file with automake to produce Makefile.in
23481 ACLOCAL_AMFLAGS = -I .. -I ../config
23482 -SUBDIRS = testsuite
23483 +SUBDIRS =
23485 ## May be used by toolexeclibdir.
23486 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23487 diff -rNU3 dist.orig/libgomp/Makefile.in dist/libgomp/Makefile.in
23488 --- dist.orig/libgomp/Makefile.in 2015-06-23 09:55:27.000000000 +0200
23489 +++ dist/libgomp/Makefile.in 2015-10-18 13:19:52.000000000 +0200
23490 @@ -288,7 +288,7 @@
23491 top_builddir = @top_builddir@
23492 top_srcdir = @top_srcdir@
23493 ACLOCAL_AMFLAGS = -I .. -I ../config
23494 -SUBDIRS = testsuite
23495 +SUBDIRS =
23496 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23497 search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
23498 fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
23499 diff -rNU3 dist.orig/libgomp/configure dist/libgomp/configure
23500 --- dist.orig/libgomp/configure 2015-06-23 09:55:27.000000000 +0200
23501 +++ dist/libgomp/configure 2015-10-18 13:19:52.000000000 +0200
23502 @@ -2620,7 +2620,7 @@
23503 for ac_t in install-sh install.sh shtool; do
23504 if test -f "$ac_dir/$ac_t"; then
23505 ac_aux_dir=$ac_dir
23506 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23507 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23508 break 2
23510 done
23511 @@ -16268,7 +16268,7 @@
23513 ac_config_files="$ac_config_files omp.h omp_lib.h omp_lib.f90 libgomp_f.h"
23515 -ac_config_files="$ac_config_files Makefile testsuite/Makefile libgomp.spec"
23516 +ac_config_files="$ac_config_files Makefile libgomp.spec"
23518 cat >confcache <<\_ACEOF
23519 # This file is a shell script that caches the results of configure
23520 @@ -17408,7 +17408,6 @@
23521 "omp_lib.f90") CONFIG_FILES="$CONFIG_FILES omp_lib.f90" ;;
23522 "libgomp_f.h") CONFIG_FILES="$CONFIG_FILES libgomp_f.h" ;;
23523 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
23524 - "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
23525 "libgomp.spec") CONFIG_FILES="$CONFIG_FILES libgomp.spec" ;;
23527 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
23528 diff -rNU3 dist.orig/libgomp/configure.ac dist/libgomp/configure.ac
23529 --- dist.orig/libgomp/configure.ac 2010-12-06 01:50:04.000000000 +0100
23530 +++ dist/libgomp/configure.ac 2015-10-18 13:19:52.000000000 +0200
23531 @@ -346,5 +346,5 @@
23532 CFLAGS="$save_CFLAGS"
23534 AC_CONFIG_FILES(omp.h omp_lib.h omp_lib.f90 libgomp_f.h)
23535 -AC_CONFIG_FILES(Makefile testsuite/Makefile libgomp.spec)
23536 +AC_CONFIG_FILES(Makefile libgomp.spec)
23537 AC_OUTPUT
23538 diff -rNU3 dist.orig/libiberty/.gitignore dist/libiberty/.gitignore
23539 --- dist.orig/libiberty/.gitignore 2011-01-18 06:06:50.000000000 +0100
23540 +++ dist/libiberty/.gitignore 1970-01-01 01:00:00.000000000 +0100
23541 @@ -1,2 +0,0 @@
23542 -/required-list
23543 -/xhost-mkfrag
23544 diff -rNU3 dist.orig/libiberty/Makefile.in dist/libiberty/Makefile.in
23545 --- dist.orig/libiberty/Makefile.in 2013-01-02 03:04:42.000000000 +0100
23546 +++ dist/libiberty/Makefile.in 2015-10-18 13:19:52.000000000 +0200
23547 @@ -98,7 +98,7 @@
23548 "tooldir=$(tooldir)"
23550 # Subdirectories to recurse into. We need to override this during cleaning
23551 -SUBDIRS = testsuite
23552 +SUBDIRS =
23554 # FIXME: add @BUILD_INFO@ once we're sure it works for everyone.
23555 all: stamp-picdir $(TARGETLIB) required-list all-subdir
23556 @@ -444,7 +444,6 @@
23557 @$(MULTICLEAN) multi-clean DO=distclean
23558 -rm -f *~ Makefile config.cache config.status xhost-mkfrag TAGS multilib.out
23559 -rm -f config.log
23560 - -rmdir testsuite 2>/dev/null
23561 maintainer-clean realclean: maintainer-clean-subdir
23562 $(MAKE) SUBDIRS="" distclean
23564 diff -rNU3 dist.orig/libiberty/configure dist/libiberty/configure
23565 --- dist.orig/libiberty/configure 2012-09-18 18:03:01.000000000 +0200
23566 +++ dist/libiberty/configure 2015-10-18 13:19:52.000000000 +0200
23567 @@ -2351,7 +2351,7 @@
23568 for ac_t in install-sh install.sh shtool; do
23569 if test -f "$ac_dir/$ac_t"; then
23570 ac_aux_dir=$ac_dir
23571 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23572 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23573 break 2
23575 done
23576 @@ -6941,7 +6941,7 @@
23579 # We need multilib support, but only if configuring for the target.
23580 -ac_config_files="$ac_config_files Makefile testsuite/Makefile"
23581 +ac_config_files="$ac_config_files Makefile"
23583 ac_config_commands="$ac_config_commands default"
23585 @@ -7645,7 +7645,6 @@
23586 case $ac_config_target in
23587 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
23588 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
23589 - "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
23590 "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
23592 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
23593 diff -rNU3 dist.orig/libiberty/configure.ac dist/libiberty/configure.ac
23594 --- dist.orig/libiberty/configure.ac 2012-09-18 18:03:01.000000000 +0200
23595 +++ dist/libiberty/configure.ac 2015-10-18 13:19:52.000000000 +0200
23596 @@ -695,7 +695,7 @@
23597 AC_SUBST(htmldir)
23599 # We need multilib support, but only if configuring for the target.
23600 -AC_CONFIG_FILES([Makefile testsuite/Makefile])
23601 +AC_CONFIG_FILES([Makefile])
23602 AC_CONFIG_COMMANDS([default],
23603 [[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
23604 if test -n "$CONFIG_FILES"; then
23605 diff -rNU3 dist.orig/libiberty/floatformat.c dist/libiberty/floatformat.c
23606 --- dist.orig/libiberty/floatformat.c 2012-08-17 23:56:48.000000000 +0200
23607 +++ dist/libiberty/floatformat.c 2015-10-18 13:19:52.000000000 +0200
23608 @@ -488,7 +488,11 @@
23609 if (nan)
23610 dto = NAN;
23611 else
23612 +#ifdef __vax__
23613 + dto = HUGE_VAL;
23614 +#else
23615 dto = INFINITY;
23616 +#endif
23618 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
23619 dto = -dto;
23620 diff -rNU3 dist.orig/libiberty/make-temp-file.c dist/libiberty/make-temp-file.c
23621 --- dist.orig/libiberty/make-temp-file.c 2011-01-03 21:52:22.000000000 +0100
23622 +++ dist/libiberty/make-temp-file.c 2015-10-18 13:19:52.000000000 +0200
23623 @@ -130,10 +130,10 @@
23624 base = try_dir (P_tmpdir, base);
23625 #endif
23627 - /* Try /var/tmp, /usr/tmp, then /tmp. */
23628 + /* Try /tmp, /var/tmp, then /usr/tmp. */
23629 + base = try_dir (tmp, base);
23630 base = try_dir (vartmp, base);
23631 base = try_dir (usrtmp, base);
23632 - base = try_dir (tmp, base);
23634 /* If all else fails, use the current directory! */
23635 if (base == 0)
23636 diff -rNU3 dist.orig/libiberty/strerror.c dist/libiberty/strerror.c
23637 --- dist.orig/libiberty/strerror.c 2005-03-28 03:28:01.000000000 +0200
23638 +++ dist/libiberty/strerror.c 2015-10-18 13:19:52.000000000 +0200
23639 @@ -347,7 +347,7 @@
23640 ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
23641 #endif
23642 #if defined (ENOPROTOOPT)
23643 - ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
23644 + ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol option not available"),
23645 #endif
23646 #if defined (EPROTONOSUPPORT)
23647 ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
23648 diff -rNU3 dist.orig/libitm/Makefile.am dist/libitm/Makefile.am
23649 --- dist.orig/libitm/Makefile.am 2012-02-14 14:14:27.000000000 +0100
23650 +++ dist/libitm/Makefile.am 2015-10-18 13:19:52.000000000 +0200
23651 @@ -1,7 +1,7 @@
23652 ## Process this file with automake to produce Makefile.in
23654 ACLOCAL_AMFLAGS = -I .. -I ../config
23655 -SUBDIRS = testsuite
23656 +SUBDIRS =
23658 ## May be used by toolexeclibdir.
23659 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23660 diff -rNU3 dist.orig/libitm/Makefile.in dist/libitm/Makefile.in
23661 --- dist.orig/libitm/Makefile.in 2015-06-23 09:55:27.000000000 +0200
23662 +++ dist/libitm/Makefile.in 2015-10-18 13:19:52.000000000 +0200
23663 @@ -302,7 +302,7 @@
23664 top_builddir = @top_builddir@
23665 top_srcdir = @top_srcdir@
23666 ACLOCAL_AMFLAGS = -I .. -I ../config
23667 -SUBDIRS = testsuite
23668 +SUBDIRS =
23669 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23670 abi_version = -fabi-version=4
23671 search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
23672 diff -rNU3 dist.orig/libitm/configure dist/libitm/configure
23673 --- dist.orig/libitm/configure 2015-06-23 09:55:27.000000000 +0200
23674 +++ dist/libitm/configure 2015-10-18 13:19:52.000000000 +0200
23675 @@ -2707,7 +2707,7 @@
23676 for ac_t in install-sh install.sh shtool; do
23677 if test -f "$ac_dir/$ac_t"; then
23678 ac_aux_dir=$ac_dir
23679 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23680 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23681 break 2
23683 done
23684 @@ -17631,7 +17631,7 @@
23688 -ac_config_files="$ac_config_files Makefile testsuite/Makefile libitm.spec"
23689 +ac_config_files="$ac_config_files Makefile libitm.spec"
23691 cat >confcache <<\_ACEOF
23692 # This file is a shell script that caches the results of configure
23693 @@ -18792,7 +18792,6 @@
23694 "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
23695 "gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
23696 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
23697 - "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
23698 "libitm.spec") CONFIG_FILES="$CONFIG_FILES libitm.spec" ;;
23700 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
23701 diff -rNU3 dist.orig/libitm/configure.ac dist/libitm/configure.ac
23702 --- dist.orig/libitm/configure.ac 2013-08-02 17:41:10.000000000 +0200
23703 +++ dist/libitm/configure.ac 2015-10-18 13:19:52.000000000 +0200
23704 @@ -286,5 +286,5 @@
23705 AM_CONDITIONAL([ARCH_X86_AVX], [test "$libitm_cv_as_avx" = yes])
23706 AM_CONDITIONAL([ARCH_FUTEX], [test $enable_linux_futex = yes])
23708 -AC_CONFIG_FILES(Makefile testsuite/Makefile libitm.spec)
23709 +AC_CONFIG_FILES(Makefile libitm.spec)
23710 AC_OUTPUT
23711 diff -rNU3 dist.orig/libmudflap/Makefile.am dist/libmudflap/Makefile.am
23712 --- dist.orig/libmudflap/Makefile.am 2013-02-03 18:48:05.000000000 +0100
23713 +++ dist/libmudflap/Makefile.am 2015-10-18 13:19:52.000000000 +0200
23714 @@ -6,7 +6,7 @@
23715 AUTOMAKE_OPTIONS = 1.8 foreign
23716 ACLOCAL_AMFLAGS = -I .. -I ../config
23717 MAINT_CHARSET = latin1
23718 -SUBDIRS = testsuite
23719 +SUBDIRS =
23721 # May be used by various substitution variables.
23722 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23723 diff -rNU3 dist.orig/libmudflap/Makefile.in dist/libmudflap/Makefile.in
23724 --- dist.orig/libmudflap/Makefile.in 2010-05-04 20:58:11.000000000 +0200
23725 +++ dist/libmudflap/Makefile.in 2015-10-18 13:19:52.000000000 +0200
23726 @@ -261,7 +261,7 @@
23727 AUTOMAKE_OPTIONS = 1.8 foreign
23728 ACLOCAL_AMFLAGS = -I .. -I ../config
23729 MAINT_CHARSET = latin1
23730 -SUBDIRS = testsuite
23731 +SUBDIRS =
23733 # May be used by various substitution variables.
23734 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
23735 diff -rNU3 dist.orig/libmudflap/configure dist/libmudflap/configure
23736 --- dist.orig/libmudflap/configure 2014-04-04 15:53:39.000000000 +0200
23737 +++ dist/libmudflap/configure 2015-10-18 13:19:52.000000000 +0200
23738 @@ -2182,7 +2182,7 @@
23739 for ac_t in install-sh install.sh shtool; do
23740 if test -f "$ac_dir/$ac_t"; then
23741 ac_aux_dir=$ac_dir
23742 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23743 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23744 break 2
23746 done
23747 @@ -11687,7 +11687,7 @@
23751 -ac_config_files="$ac_config_files Makefile testsuite/Makefile testsuite/mfconfig.exp"
23752 +ac_config_files="$ac_config_files Makefile"
23754 cat >confcache <<\_ACEOF
23755 # This file is a shell script that caches the results of configure
23756 @@ -12682,8 +12682,6 @@
23757 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
23758 "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
23759 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
23760 - "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
23761 - "testsuite/mfconfig.exp") CONFIG_FILES="$CONFIG_FILES testsuite/mfconfig.exp" ;;
23763 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
23764 esac
23765 diff -rNU3 dist.orig/libmudflap/configure.ac dist/libmudflap/configure.ac
23766 --- dist.orig/libmudflap/configure.ac 2011-07-13 16:57:29.000000000 +0200
23767 +++ dist/libmudflap/configure.ac 2015-10-18 13:19:52.000000000 +0200
23768 @@ -266,5 +266,5 @@
23769 GCC_CHECK_TLS
23770 GCC_CHECK_EMUTLS
23772 -AC_CONFIG_FILES([Makefile testsuite/Makefile testsuite/mfconfig.exp])
23773 +AC_CONFIG_FILES([Makefile])
23774 AC_OUTPUT
23775 diff -rNU3 dist.orig/libmudflap/mf-hooks1.c dist/libmudflap/mf-hooks1.c
23776 --- dist.orig/libmudflap/mf-hooks1.c 2013-02-03 18:48:05.000000000 +0100
23777 +++ dist/libmudflap/mf-hooks1.c 2015-10-18 13:19:52.000000000 +0200
23778 @@ -33,7 +33,7 @@
23780 /* These attempt to coax various unix flavours to declare all our
23781 needed tidbits in the system headers. */
23782 -#if !defined(__FreeBSD__) && !defined(__APPLE__)
23783 +#if !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(__NetBSD__)
23784 #define _POSIX_SOURCE
23785 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
23786 #define _GNU_SOURCE
23787 diff -rNU3 dist.orig/libmudflap/mf-hooks2.c dist/libmudflap/mf-hooks2.c
23788 --- dist.orig/libmudflap/mf-hooks2.c 2013-02-03 18:48:05.000000000 +0100
23789 +++ dist/libmudflap/mf-hooks2.c 2015-10-18 13:19:52.000000000 +0200
23790 @@ -32,9 +32,10 @@
23792 /* These attempt to coax various unix flavours to declare all our
23793 needed tidbits in the system headers. */
23794 -#if !defined(__FreeBSD__) && !defined(__APPLE__)
23795 +#if !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(__NetBSD__)
23796 #define _POSIX_SOURCE
23797 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
23798 +#define _NETBSD_SOURCE
23799 #define _GNU_SOURCE
23800 #define _XOPEN_SOURCE
23801 #define _BSD_TYPES
23802 diff -rNU3 dist.orig/libmudflap/mf-impl.h dist/libmudflap/mf-impl.h
23803 --- dist.orig/libmudflap/mf-impl.h 2013-02-03 18:48:05.000000000 +0100
23804 +++ dist/libmudflap/mf-impl.h 2015-10-18 13:19:52.000000000 +0200
23805 @@ -276,12 +276,12 @@
23806 #ifdef LIBMUDFLAPTH
23807 #define VERBOSE_TRACE(...) \
23808 do { if (UNLIKELY (__mf_opts.verbose_trace)) { \
23809 - fprintf (stderr, "mf(%u): ", (unsigned) pthread_self ()); \
23810 + fprintf (stderr, "mf(%ju): ", (intmax_t)(intptr_t) pthread_self ()); \
23811 fprintf (stderr, __VA_ARGS__); \
23812 } } while (0)
23813 #define TRACE(...) \
23814 do { if (UNLIKELY (__mf_opts.trace_mf_calls)) { \
23815 - fprintf (stderr, "mf(%u): ", (unsigned) pthread_self ()); \
23816 + fprintf (stderr, "mf(%ju): ", (intmax_t)(intptr_t) pthread_self ()); \
23817 fprintf (stderr, __VA_ARGS__); \
23818 } } while (0)
23819 #else
23820 @@ -399,6 +399,29 @@
23821 TRACE ("%s\n", __PRETTY_FUNCTION__); \
23824 +#define BEGIN_PROTECTV(fname, ...) \
23825 + if (UNLIKELY (__mf_starting_p)) \
23826 + { \
23827 + CALL_BACKUP(fname, __VA_ARGS__); \
23828 + return; \
23829 + } \
23830 + else if (UNLIKELY (__mf_get_state () == reentrant)) \
23831 + { \
23832 + extern unsigned long __mf_reentrancy; \
23833 + __mf_reentrancy ++; \
23834 + CALL_REAL(fname, __VA_ARGS__); \
23835 + return; \
23836 + } \
23837 + else if (UNLIKELY (__mf_get_state () == in_malloc)) \
23838 + { \
23839 + CALL_REAL(fname, __VA_ARGS__); \
23840 + return; \
23841 + } \
23842 + else \
23843 + { \
23844 + TRACE ("%s\n", __PRETTY_FUNCTION__); \
23847 /* There is an assumption here that these will only be called in routines
23848 that call BEGIN_PROTECT at the start, and hence the state must always
23849 be active when BEGIN_MALLOC_PROTECT is called. */
23850 diff -rNU3 dist.orig/libmudflap/mf-runtime.c dist/libmudflap/mf-runtime.c
23851 --- dist.orig/libmudflap/mf-runtime.c 2013-02-03 18:48:05.000000000 +0100
23852 +++ dist/libmudflap/mf-runtime.c 2015-10-18 13:19:52.000000000 +0200
23853 @@ -30,9 +30,10 @@
23855 /* These attempt to coax various unix flavours to declare all our
23856 needed tidbits in the system headers. */
23857 -#if !defined(__FreeBSD__) && !defined(__APPLE__)
23858 +#if !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(__NetBSD__)
23859 #define _POSIX_SOURCE
23860 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
23861 +#define _NETBSD_SOURCE
23862 #define _GNU_SOURCE
23863 #define _XOPEN_SOURCE
23864 #define _BSD_TYPES
23865 @@ -164,7 +165,7 @@
23866 #define LOOKUP_CACHE_SHIFT_DFL 2
23868 struct __mf_cache __mf_lookup_cache [LOOKUP_CACHE_SIZE_MAX];
23869 -uintptr_t __mf_lc_mask = LOOKUP_CACHE_MASK_DFL;
23870 +__mf_uintptr_t __mf_lc_mask = LOOKUP_CACHE_MASK_DFL;
23871 unsigned char __mf_lc_shift = LOOKUP_CACHE_SHIFT_DFL;
23872 #define LOOKUP_CACHE_SIZE (__mf_lc_mask + 1)
23874 @@ -191,12 +192,18 @@
23875 /* Use HAVE_PTHREAD_H here instead of LIBMUDFLAPTH, so that even
23876 the libmudflap.la (no threading support) can diagnose whether
23877 the application is linked with -lpthread. See __mf_usage() below. */
23878 -#if HAVE_PTHREAD_H
23879 -#ifdef _POSIX_THREADS
23880 -#pragma weak pthread_join
23881 +#ifdef LIBMUDFLAPTH
23882 +# if HAVE_PTHREAD_H
23883 +# ifdef _POSIX_THREADS
23884 +# include <pthread.h>
23885 +# else
23886 +# define pthread_join NULL
23887 +# endif
23888 +# else
23889 +# define pthread_join NULL
23890 +# endif
23891 #else
23892 -#define pthread_join NULL
23893 -#endif
23894 +# define pthread_join NULL
23895 #endif
23898 @@ -1774,7 +1781,7 @@
23899 "bounds=[%p,%p] size=%lu area=%s check=%ur/%uw liveness=%u%s\n"
23900 "alloc time=%lu.%06lu pc=%p"
23901 #ifdef LIBMUDFLAPTH
23902 - " thread=%u"
23903 + " thread=%ju"
23904 #endif
23905 "\n",
23906 (obj->deallocated_p ? "dead " : ""),
23907 @@ -1793,7 +1800,7 @@
23908 obj->alloc_time.tv_sec, obj->alloc_time.tv_usec,
23909 (void *) obj->alloc_pc
23910 #ifdef LIBMUDFLAPTH
23911 - , (unsigned) obj->alloc_thread
23912 + , (intmax_t)(intptr_t)obj->alloc_thread
23913 #endif
23916 @@ -1810,13 +1817,13 @@
23918 fprintf (stderr, "dealloc time=%lu.%06lu pc=%p"
23919 #ifdef LIBMUDFLAPTH
23920 - " thread=%u"
23921 + " thread=%ju"
23922 #endif
23923 "\n",
23924 obj->dealloc_time.tv_sec, obj->dealloc_time.tv_usec,
23925 (void *) obj->dealloc_pc
23926 #ifdef LIBMUDFLAPTH
23927 - , (unsigned) obj->dealloc_thread
23928 + , (intmax_t)(intptr_t)obj->dealloc_thread
23929 #endif
23932 @@ -2330,7 +2337,7 @@
23933 #ifndef NDEBUG
23935 static void
23936 -write_itoa (int fd, unsigned n)
23937 +write_itoa (int fd, intmax_t n)
23939 enum x { bufsize = sizeof(n)*4 };
23940 char buf [bufsize];
23941 @@ -2359,7 +2366,7 @@
23942 write2("mf");
23943 #ifdef LIBMUDFLAPTH
23944 write2("(");
23945 - write_itoa (2, (unsigned) pthread_self ());
23946 + write_itoa (2, (intmax_t)(intptr_t)pthread_self ());
23947 write2(")");
23948 #endif
23949 write2(": assertion failure: `");
23950 diff -rNU3 dist.orig/libmudflap/mf-runtime.h dist/libmudflap/mf-runtime.h
23951 --- dist.orig/libmudflap/mf-runtime.h 2013-02-03 18:48:05.000000000 +0100
23952 +++ dist/libmudflap/mf-runtime.h 2015-10-18 13:19:52.000000000 +0200
23953 @@ -31,7 +31,7 @@
23954 #define MF_RUNTIME_H
23956 typedef void *__mf_ptr_t;
23957 -typedef unsigned int __mf_uintptr_t __attribute__ ((__mode__ (__pointer__)));
23958 +typedef unsigned long __mf_uintptr_t __attribute__ ((__mode__ (__pointer__)));
23959 typedef __SIZE_TYPE__ __mf_size_t;
23961 /* Global declarations used by instrumentation. When _MUDFLAP is
23962 @@ -81,11 +81,11 @@
23963 #endif
23965 extern void __mf_check (void *ptr, __mf_size_t sz, int type, const char *location)
23966 - __attribute((nothrow));
23967 + __attribute__((nothrow));
23968 extern void __mf_register (void *ptr, __mf_size_t sz, int type, const char *name)
23969 - __attribute((nothrow));
23970 + __attribute__((nothrow));
23971 extern void __mf_unregister (void *ptr, __mf_size_t sz, int type)
23972 - __attribute((nothrow));
23973 + __attribute__((nothrow));
23974 extern unsigned __mf_watch (void *ptr, __mf_size_t sz);
23975 extern unsigned __mf_unwatch (void *ptr, __mf_size_t sz);
23976 extern void __mf_report ();
23977 diff -rNU3 dist.orig/libobjc/configure dist/libobjc/configure
23978 --- dist.orig/libobjc/configure 2014-04-04 15:53:39.000000000 +0200
23979 +++ dist/libobjc/configure 2015-10-18 13:19:52.000000000 +0200
23980 @@ -2169,7 +2169,7 @@
23981 for ac_t in install-sh install.sh shtool; do
23982 if test -f "$ac_dir/$ac_t"; then
23983 ac_aux_dir=$ac_dir
23984 - ac_install_sh="$ac_aux_dir/$ac_t -c"
23985 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
23986 break 2
23988 done
23989 diff -rNU3 dist.orig/libobjc/encoding.c dist/libobjc/encoding.c
23990 --- dist.orig/libobjc/encoding.c 2014-07-28 16:33:20.000000000 +0200
23991 +++ dist/libobjc/encoding.c 2015-10-18 13:19:52.000000000 +0200
23992 @@ -645,7 +645,11 @@
23993 return ROUND (size, wordsize);
23996 -inline
23998 + Skip type qualifiers. These may eventually precede typespecs
23999 + occurring in method prototype encodings.
24002 const char *
24003 objc_skip_type_qualifiers (const char *type)
24005 @@ -663,7 +667,6 @@
24006 return type;
24009 -inline
24010 const char *
24011 objc_skip_typespec (const char *type)
24013 @@ -794,7 +797,10 @@
24017 -inline
24019 + Skip an offset as part of a method encoding. This is prepended by a
24020 + '+' if the argument is passed in registers.
24022 const char *
24023 objc_skip_offset (const char *type)
24025 diff -rNU3 dist.orig/libobjc/hash.c dist/libobjc/hash.c
24026 --- dist.orig/libobjc/hash.c 2013-02-03 12:16:21.000000000 +0100
24027 +++ dist/libobjc/hash.c 2015-10-18 13:19:52.000000000 +0200
24028 @@ -151,8 +151,8 @@
24029 (*cachep)->hash_func,
24030 (*cachep)->compare_func);
24032 - DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n",
24033 - (int) *cachep, (*cachep)->size, new->size);
24034 + DEBUG_PRINTF ("Expanding cache %p from %d to %d\n",
24035 + *cachep, (*cachep)->size, new->size);
24037 /* Copy the nodes from the first hash table to the new one. */
24038 while ((node1 = objc_hash_next (*cachep, node1)))
24039 diff -rNU3 dist.orig/libobjc/objects.c dist/libobjc/objects.c
24040 --- dist.orig/libobjc/objects.c 2013-02-03 12:16:21.000000000 +0100
24041 +++ dist/libobjc/objects.c 2015-10-18 13:19:52.000000000 +0200
24042 @@ -36,7 +36,6 @@
24043 #endif
24045 /* FIXME: The semantics of extraBytes are not really clear. */
24046 -inline
24048 class_createInstance (Class class, size_t extraBytes)
24050 diff -rNU3 dist.orig/libobjc/sendmsg.c dist/libobjc/sendmsg.c
24051 --- dist.orig/libobjc/sendmsg.c 2013-02-03 12:16:21.000000000 +0100
24052 +++ dist/libobjc/sendmsg.c 2015-10-18 13:19:52.000000000 +0200
24053 @@ -105,7 +105,6 @@
24054 id nil_method (id, SEL);
24056 /* Given a selector, return the proper forwarding implementation. */
24057 -inline
24059 __objc_get_forward_imp (id rcv, SEL sel)
24061 @@ -320,7 +319,6 @@
24062 return res;
24065 -inline
24067 get_imp (Class class, SEL sel)
24069 @@ -364,7 +362,6 @@
24070 method can be forwarded. Since this requires the dispatch table to
24071 installed, this function will implicitly invoke +initialize for the
24072 class of OBJECT if it hasn't been invoked yet. */
24073 -inline
24074 BOOL
24075 __objc_responds_to (id object, SEL sel)
24077 diff -rNU3 dist.orig/libsanitizer/asan/asan_intercepted_functions.h dist/libsanitizer/asan/asan_intercepted_functions.h
24078 --- dist.orig/libsanitizer/asan/asan_intercepted_functions.h 2013-02-21 11:57:10.000000000 +0100
24079 +++ dist/libsanitizer/asan/asan_intercepted_functions.h 2015-10-18 13:19:52.000000000 +0200
24080 @@ -41,7 +41,7 @@
24081 # define ASAN_INTERCEPT_MLOCKX 0
24082 #endif
24084 -#if defined(__linux__)
24085 +#if defined(__linux__) || defined(__NetBSD__)
24086 # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1
24087 #else
24088 # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
24089 @@ -53,7 +53,7 @@
24090 # define ASAN_INTERCEPT_STRNLEN 0
24091 #endif
24093 -#if defined(__linux__) && !defined(ANDROID)
24094 +#if (defined(__linux__) || defined(__NetBSD__)) && !defined(ANDROID)
24095 # define ASAN_INTERCEPT_SWAPCONTEXT 1
24096 #else
24097 # define ASAN_INTERCEPT_SWAPCONTEXT 0
24098 diff -rNU3 dist.orig/libsanitizer/asan/asan_internal.h dist/libsanitizer/asan/asan_internal.h
24099 --- dist.orig/libsanitizer/asan/asan_internal.h 2013-02-21 11:57:10.000000000 +0100
24100 +++ dist/libsanitizer/asan/asan_internal.h 2015-10-18 13:19:52.000000000 +0200
24101 @@ -19,13 +19,13 @@
24102 #include "sanitizer_common/sanitizer_stacktrace.h"
24103 #include "sanitizer_common/sanitizer_libc.h"
24105 -#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
24106 +#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__NetBSD__)
24107 # error "This operating system is not supported by AddressSanitizer"
24108 #endif
24110 #define ASAN_DEFAULT_FAILURE_EXITCODE 1
24112 -#if defined(__linux__)
24113 +#if defined(__linux__) || defined(__NetBSD__)
24114 # define ASAN_LINUX 1
24115 #else
24116 # define ASAN_LINUX 0
24117 diff -rNU3 dist.orig/libsanitizer/asan/asan_linux.cc dist/libsanitizer/asan/asan_linux.cc
24118 --- dist.orig/libsanitizer/asan/asan_linux.cc 2013-01-23 12:41:33.000000000 +0100
24119 +++ dist/libsanitizer/asan/asan_linux.cc 2015-10-18 13:19:52.000000000 +0200
24120 @@ -9,7 +9,7 @@
24122 // Linux-specific details.
24123 //===----------------------------------------------------------------------===//
24124 -#ifdef __linux__
24125 +#if defined(__linux__) || defined(__NetBSD__)
24127 #include "asan_interceptors.h"
24128 #include "asan_internal.h"
24129 @@ -25,6 +25,7 @@
24130 #include <sys/types.h>
24131 #include <fcntl.h>
24132 #include <pthread.h>
24133 +#include <signal.h>
24134 #include <stdio.h>
24135 #include <unistd.h>
24136 #include <unwind.h>
24137 @@ -48,7 +49,42 @@
24140 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
24141 -#if ASAN_ANDROID
24142 +#ifdef __NetBSD__
24143 +# define __UC_MACHINE_FP(ucontext, r) \
24144 + (ucontext)->uc_mcontext.__gregs[(r)]
24146 + * Unfortunately we don't have a portable frame pointer (yet)
24147 + */
24148 +# if defined(__alpha__)
24149 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_S6)
24150 +# elif defined(__arm__)
24151 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_FP)
24152 +# elif defined(__x86_64__)
24153 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_RBP)
24154 +# elif defined(__i386__)
24155 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_EBP)
24156 +# elif defined(__m68k__)
24157 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_A6)
24158 +# elif defined(__mips__)
24159 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_S8)
24160 +# elif defined(__powerpc__) || defined(__powerpc64__)
24161 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_R1)
24162 +# elif defined(__riscv__)
24163 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_S0)
24164 +# elif defined(__sparc__)
24165 +# define _UC_MACHINE_FP(ucontext) sp[15]
24166 +# elif defined(__sh3__)
24167 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_R14)
24168 +# elif defined(__vax__)
24169 +# define _UC_MACHINE_FP(ucontext) __UC_MACHINE_FP(ucontext, _REG_FP)
24170 +# else
24171 +# define _UC_MACHINE_FP(ucontext) 0
24172 +# endif
24173 + ucontext_t *ucontext = (ucontext_t*)context;
24174 + *pc = _UC_MACHINE_PC(ucontext);
24175 + *sp = _UC_MACHINE_SP(ucontext);
24176 + *bp = _UC_MACHINE_FP(ucontext);
24177 +#elif ASAN_ANDROID
24178 *pc = *sp = *bp = 0;
24179 #elif defined(__arm__)
24180 ucontext_t *ucontext = (ucontext_t*)context;
24181 @@ -72,6 +108,11 @@
24182 // The powerpc{,64}-linux ABIs do not specify r31 as the frame
24183 // pointer, but GCC always uses r31 when we need a frame pointer.
24184 *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
24185 +# elif defined(__riscv__)
24186 + ucontext_t *ucontext = (ucontext_t*)context;
24187 + *pc = ucontext->uc_mcontext.gregs[REG_PC];
24188 + *bp = ucontext->uc_mcontext.gregs[REG_S0];
24189 + *sp = ucontext->uc_mcontext.gregs[REG_SP];
24190 # elif defined(__sparc__)
24191 ucontext_t *ucontext = (ucontext_t*)context;
24192 uptr *stk_ptr;
24193 @@ -131,4 +172,4 @@
24195 } // namespace __asan
24197 -#endif // __linux__
24198 +#endif // __linux__ || __NetBSD__
24199 diff -rNU3 dist.orig/libsanitizer/asan/asan_malloc_linux.cc dist/libsanitizer/asan/asan_malloc_linux.cc
24200 --- dist.orig/libsanitizer/asan/asan_malloc_linux.cc 2013-02-13 11:46:01.000000000 +0100
24201 +++ dist/libsanitizer/asan/asan_malloc_linux.cc 2015-10-18 13:19:52.000000000 +0200
24202 @@ -11,7 +11,7 @@
24203 // We simply define functions like malloc, free, realloc, etc.
24204 // They will replace the corresponding libc functions automagically.
24205 //===----------------------------------------------------------------------===//
24206 -#ifdef __linux__
24207 +#if defined(__linux__) || defined(__NetBSD__)
24209 #include "asan_allocator.h"
24210 #include "asan_interceptors.h"
24211 @@ -144,4 +144,4 @@
24212 __asan_print_accumulated_stats();
24215 -#endif // __linux__
24216 +#endif // __linux__ || __NetBSD__
24217 diff -rNU3 dist.orig/libsanitizer/asan/asan_posix.cc dist/libsanitizer/asan/asan_posix.cc
24218 --- dist.orig/libsanitizer/asan/asan_posix.cc 2012-11-12 16:53:47.000000000 +0100
24219 +++ dist/libsanitizer/asan/asan_posix.cc 2015-10-18 13:19:52.000000000 +0200
24220 @@ -9,7 +9,7 @@
24222 // Posix-specific details.
24223 //===----------------------------------------------------------------------===//
24224 -#if defined(__linux__) || defined(__APPLE__)
24225 +#if defined(__linux__) || defined(__APPLE__) || defined(__NetBSD__)
24227 #include "asan_internal.h"
24228 #include "asan_interceptors.h"
24229 @@ -115,4 +115,4 @@
24231 } // namespace __asan
24233 -#endif // __linux__ || __APPLE_
24234 +#endif // __linux__ || __APPLE_ || __NetBSD__
24235 diff -rNU3 dist.orig/libsanitizer/configure dist/libsanitizer/configure
24236 --- dist.orig/libsanitizer/configure 2015-06-23 09:55:27.000000000 +0200
24237 +++ dist/libsanitizer/configure 2015-10-18 13:19:52.000000000 +0200
24238 @@ -2478,7 +2478,7 @@
24239 for ac_t in install-sh install.sh shtool; do
24240 if test -f "$ac_dir/$ac_t"; then
24241 ac_aux_dir=$ac_dir
24242 - ac_install_sh="$ac_aux_dir/$ac_t -c"
24243 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
24244 break 2
24246 done
24247 diff -rNU3 dist.orig/libsanitizer/configure.tgt dist/libsanitizer/configure.tgt
24248 --- dist.orig/libsanitizer/configure.tgt 2014-04-04 16:39:26.000000000 +0200
24249 +++ dist/libsanitizer/configure.tgt 2015-10-18 13:19:52.000000000 +0200
24250 @@ -20,6 +20,14 @@
24252 # Filter out unsupported systems.
24253 case "${target}" in
24254 + *-netbsd*)
24255 + # There is only glue for amd64
24256 + case "${target}" in
24257 + x86_64-*)
24258 + TSAN_SUPPORTED=yes
24259 + ;;
24260 + esac
24261 + ;;
24262 x86_64-*-linux* | i?86-*-linux*)
24263 if test x$ac_cv_sizeof_void_p = x8; then
24264 TSAN_SUPPORTED=yes
24265 diff -rNU3 dist.orig/libsanitizer/interception/interception.h dist/libsanitizer/interception/interception.h
24266 --- dist.orig/libsanitizer/interception/interception.h 2013-02-14 17:54:01.000000000 +0100
24267 +++ dist/libsanitizer/interception/interception.h 2015-10-18 13:19:52.000000000 +0200
24268 @@ -13,7 +13,7 @@
24269 #ifndef INTERCEPTION_H
24270 #define INTERCEPTION_H
24272 -#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
24273 +#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__NetBSD__)
24274 # error "Interception doesn't work on this operating system."
24275 #endif
24277 @@ -29,7 +29,7 @@
24278 // _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls
24279 // like pread and mmap, as opposed to pread64 and mmap64.
24280 // Mac and Linux/x86-64 are special.
24281 -#if defined(__APPLE__) || (defined(__linux__) && defined(__x86_64__))
24282 +#if defined(__APPLE__) || (defined(__linux__) && defined(__x86_64__)) || defined(__NetBSD__)
24283 typedef __sanitizer::u64 OFF_T;
24284 #else
24285 typedef __sanitizer::uptr OFF_T;
24286 @@ -176,7 +176,7 @@
24288 #define INCLUDED_FROM_INTERCEPTION_LIB
24290 -#if defined(__linux__)
24291 +#if defined(__linux__) || defined(__NetBSD__)
24292 # include "interception_linux.h"
24293 # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX(func)
24294 #elif defined(__APPLE__)
24295 diff -rNU3 dist.orig/libsanitizer/interception/interception_linux.cc dist/libsanitizer/interception/interception_linux.cc
24296 --- dist.orig/libsanitizer/interception/interception_linux.cc 2012-11-12 16:53:47.000000000 +0100
24297 +++ dist/libsanitizer/interception/interception_linux.cc 2015-10-18 13:19:52.000000000 +0200
24298 @@ -10,19 +10,34 @@
24299 // Linux-specific interception methods.
24300 //===----------------------------------------------------------------------===//
24302 -#ifdef __linux__
24303 +#if defined(__linux__) || defined(__NetBSD__)
24304 #include "interception.h"
24306 #include <stddef.h> // for NULL
24307 #include <dlfcn.h> // for dlsym
24309 +#ifdef __NetBSD__
24310 +static int mystrcmp(const char *s1, const char *s2) {
24311 + while (*s1 == *s2++)
24312 + if (*s1++ == 0)
24313 + return (0);
24314 + return (*(const unsigned char *)s1 - *(const unsigned char *)--s2);
24316 +#endif
24319 namespace __interception {
24320 bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
24321 uptr real, uptr wrapper) {
24322 +#ifdef __NetBSD__
24323 + // XXX: Until I come up with something better to deal with renames.
24324 + if (mystrcmp(func_name, "sigaction") == 0)
24325 + func_name = "__sigaction14";
24326 +#endif
24327 *func_addr = (uptr)dlsym(RTLD_NEXT, func_name);
24328 return real == wrapper;
24330 } // namespace __interception
24333 -#endif // __linux__
24334 +#endif // __linux__ || __NetBSD__
24335 diff -rNU3 dist.orig/libsanitizer/interception/interception_linux.h dist/libsanitizer/interception/interception_linux.h
24336 --- dist.orig/libsanitizer/interception/interception_linux.h 2012-11-12 16:53:47.000000000 +0100
24337 +++ dist/libsanitizer/interception/interception_linux.h 2015-10-18 13:19:52.000000000 +0200
24338 @@ -10,7 +10,7 @@
24339 // Linux-specific interception methods.
24340 //===----------------------------------------------------------------------===//
24342 -#ifdef __linux__
24343 +#if defined(__linux__) || defined(__NetBSD__)
24345 #if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
24346 # error "interception_linux.h should be included from interception library only"
24347 @@ -32,4 +32,4 @@
24348 (::__interception::uptr)&WRAP(func))
24350 #endif // INTERCEPTION_LINUX_H
24351 -#endif // __linux__
24352 +#endif // __linux__ || __NetBSD__
24353 diff -rNU3 dist.orig/libsanitizer/interception/interception_type_test.cc dist/libsanitizer/interception/interception_type_test.cc
24354 --- dist.orig/libsanitizer/interception/interception_type_test.cc 2013-02-13 11:46:01.000000000 +0100
24355 +++ dist/libsanitizer/interception/interception_type_test.cc 2015-10-18 13:19:52.000000000 +0200
24356 @@ -10,7 +10,7 @@
24357 // Compile-time tests of the internal type definitions.
24358 //===----------------------------------------------------------------------===//
24360 -#if defined(__linux__) || defined(__APPLE__)
24361 +#if defined(__linux__) || defined(__APPLE__) || defined(__NetBSD__)
24363 #include "interception.h"
24364 #include <sys/types.h>
24365 @@ -22,7 +22,7 @@
24366 COMPILER_CHECK(sizeof(PTRDIFF_T) == sizeof(ptrdiff_t));
24367 COMPILER_CHECK(sizeof(INTMAX_T) == sizeof(intmax_t));
24369 -#ifndef __APPLE__
24370 +#if !defined(__APPLE__) && !defined(__NetBSD__)
24371 COMPILER_CHECK(sizeof(OFF64_T) == sizeof(off64_t));
24372 #endif
24374 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc dist/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
24375 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc 2013-02-21 11:57:10.000000000 +0100
24376 +++ dist/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc 2015-10-18 13:19:52.000000000 +0200
24377 @@ -296,6 +296,14 @@
24378 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
24379 SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
24381 +#define INIT_SCANF_NORMAL \
24382 + INTERCEPT_FUNCTION(scanf); \
24383 + INTERCEPT_FUNCTION(sscanf); \
24384 + INTERCEPT_FUNCTION(fscanf); \
24385 + INTERCEPT_FUNCTION(vscanf); \
24386 + INTERCEPT_FUNCTION(vsscanf); \
24387 + INTERCEPT_FUNCTION(vfscanf); \
24389 #if SANITIZER_INTERCEPT_ISOC99_SCANF
24390 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
24391 SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
24392 @@ -305,21 +313,22 @@
24394 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
24395 SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
24396 -#endif
24398 -#define INIT_SCANF \
24399 - INTERCEPT_FUNCTION(scanf); \
24400 - INTERCEPT_FUNCTION(sscanf); \
24401 - INTERCEPT_FUNCTION(fscanf); \
24402 - INTERCEPT_FUNCTION(vscanf); \
24403 - INTERCEPT_FUNCTION(vsscanf); \
24404 - INTERCEPT_FUNCTION(vfscanf); \
24406 +#define INIT_SCANF_ISOC99 \
24407 INTERCEPT_FUNCTION(__isoc99_scanf); \
24408 INTERCEPT_FUNCTION(__isoc99_sscanf); \
24409 INTERCEPT_FUNCTION(__isoc99_fscanf); \
24410 INTERCEPT_FUNCTION(__isoc99_vscanf); \
24411 INTERCEPT_FUNCTION(__isoc99_vsscanf); \
24412 INTERCEPT_FUNCTION(__isoc99_vfscanf);
24413 +#else
24414 +#define INIT_SCANF_ISOC99
24415 +#endif
24417 +#define INIT_SCANF \
24418 + INIT_SCANF_NORMAL \
24419 + INIT_SCANF_ISOC99
24421 #else
24422 #define INIT_SCANF
24423 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_internal_defs.h dist/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
24424 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_internal_defs.h 2013-02-21 11:57:10.000000000 +0100
24425 +++ dist/libsanitizer/sanitizer_common/sanitizer_internal_defs.h 2015-10-18 13:19:52.000000000 +0200
24426 @@ -116,7 +116,11 @@
24427 # define USED
24428 # define PREFETCH(x) /* _mm_prefetch(x, _MM_HINT_NTA) */
24429 #else // _MSC_VER
24430 -# define ALWAYS_INLINE __attribute__((always_inline))
24431 +# ifdef __NetBSD__
24432 +# define ALWAYS_INLINE // __attribute__((always_inline))
24433 +# else
24434 +# define ALWAYS_INLINE __attribute__((always_inline))
24435 +# endif
24436 # define ALIAS(x) __attribute__((alias(x)))
24437 # define ALIGNED(x) __attribute__((aligned(x)))
24438 # define FORMAT(f, a) __attribute__((format(printf, f, a)))
24439 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_netbsd.cc dist/libsanitizer/sanitizer_common/sanitizer_netbsd.cc
24440 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_netbsd.cc 1970-01-01 01:00:00.000000000 +0100
24441 +++ dist/libsanitizer/sanitizer_common/sanitizer_netbsd.cc 2015-10-18 13:19:52.000000000 +0200
24442 @@ -0,0 +1,479 @@
24443 +//===-- sanitizer_netbsd.cc -----------------------------------------------===//
24445 +// This file is distributed under the University of Illinois Open Source
24446 +// License. See LICENSE.TXT for details.
24448 +//===----------------------------------------------------------------------===//
24450 +// This file is shared between AddressSanitizer and ThreadSanitizer
24451 +// run-time libraries and implements linux-specific functions from
24452 +// sanitizer_libc.h.
24453 +//===----------------------------------------------------------------------===//
24454 +#ifdef __NetBSD__
24456 +#include "sanitizer_common.h"
24457 +#include "sanitizer_internal_defs.h"
24458 +#include "sanitizer_libc.h"
24459 +#include "sanitizer_mutex.h"
24460 +#include "sanitizer_placement_new.h"
24461 +#include "sanitizer_procmaps.h"
24462 +#include "sanitizer_stacktrace.h"
24464 +#include <fcntl.h>
24465 +#include <pthread.h>
24466 +#include <sched.h>
24467 +#include <sys/mman.h>
24468 +#include <sys/resource.h>
24469 +#include <sys/stat.h>
24470 +#include <sys/syscall.h>
24471 +#include <sys/time.h>
24472 +#include <sys/types.h>
24473 +#include <unistd.h>
24474 +#include <errno.h>
24476 +namespace __sanitizer {
24478 +// --------------- sanitizer_libc.h
24479 +void *internal_mmap(void *addr, uptr length, int prot, int flags,
24480 + int fd, u64 offset) {
24481 + return (void *)__syscall(SYS_mmap, addr, length, prot, flags,
24482 + fd, 0, offset);
24485 +int internal_munmap(void *addr, uptr length) {
24486 + return syscall(SYS_munmap, addr, length);
24489 +int internal_close(fd_t fd) {
24490 + return syscall(SYS_close, fd);
24493 +fd_t internal_open(const char *filename, int flags) {
24494 + return syscall(SYS_open, filename, flags);
24497 +fd_t internal_open(const char *filename, int flags, u32 mode) {
24498 + return syscall(SYS_open, filename, flags, mode);
24501 +fd_t OpenFile(const char *filename, bool write) {
24502 + return internal_open(filename,
24503 + write ? O_WRONLY | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
24506 +uptr internal_read(fd_t fd, void *buf, uptr count) {
24507 + sptr res;
24508 + HANDLE_EINTR(res, (sptr)syscall(SYS_read, fd, buf, count));
24509 + return res;
24512 +uptr internal_write(fd_t fd, const void *buf, uptr count) {
24513 + sptr res;
24514 + HANDLE_EINTR(res, (sptr)syscall(SYS_write, fd, buf, count));
24515 + return res;
24518 +int internal_stat(const char *path, void *buf) {
24519 + return syscall(SYS___stat50, path, buf);
24522 +int internal_lstat(const char *path, void *buf) {
24523 + return syscall(SYS___lstat50, path, buf);
24526 +int internal_fstat(fd_t fd, void *buf) {
24527 + return syscall(SYS___fstat50, fd, buf);
24530 +uptr internal_filesize(fd_t fd) {
24531 + struct stat st;
24532 + if (internal_fstat(fd, &st))
24533 + return -1;
24534 + return (uptr)st.st_size;
24537 +int internal_dup2(int oldfd, int newfd) {
24538 + return syscall(SYS_dup2, oldfd, newfd);
24541 +uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
24542 + return (uptr)syscall(SYS_readlink, path, buf, bufsize);
24545 +int internal_sched_yield() {
24546 + return syscall(SYS_sched_yield);
24549 +void internal__exit(int exitcode) {
24550 + syscall(SYS_exit, exitcode);
24551 + Die(); // Unreachable.
24554 +// ----------------- sanitizer_common.h
24555 +bool FileExists(const char *filename) {
24556 + struct stat st;
24557 + if (syscall(SYS___stat50, filename, &st))
24558 + return false;
24559 + // Sanity check: filename is a regular file.
24560 + return S_ISREG(st.st_mode);
24563 +uptr GetTid() {
24564 + // XXX!
24565 + return syscall(SYS_getpid);
24568 +void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
24569 + uptr *stack_bottom) {
24570 + static const uptr kMaxThreadStackSize = 256 * (1 << 20); // 256M
24571 + CHECK(stack_top);
24572 + CHECK(stack_bottom);
24573 + if (at_initialization) {
24574 + // This is the main thread. Libpthread may not be initialized yet.
24575 + struct rlimit rl;
24576 + CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
24578 + // Find the mapping that contains a stack variable.
24579 + MemoryMappingLayout proc_maps;
24580 + uptr start, end, offset;
24581 + uptr prev_end = 0;
24582 + while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
24583 + if ((uptr)&rl < end)
24584 + break;
24585 + prev_end = end;
24587 + CHECK((uptr)&rl >= start && (uptr)&rl < end);
24589 + // Get stacksize from rlimit, but clip it so that it does not overlap
24590 + // with other mappings.
24591 + uptr stacksize = rl.rlim_cur;
24592 + if (stacksize > end - prev_end)
24593 + stacksize = end - prev_end;
24594 + // When running with unlimited stack size, we still want to set some limit.
24595 + // The unlimited stack size is caused by 'ulimit -s unlimited'.
24596 + // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
24597 + if (stacksize > kMaxThreadStackSize)
24598 + stacksize = kMaxThreadStackSize;
24599 + *stack_top = end;
24600 + *stack_bottom = end - stacksize;
24601 + return;
24603 + pthread_attr_t attr;
24604 + CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
24605 + uptr stacksize = 0;
24606 + void *stackaddr = 0;
24607 + pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
24608 + pthread_attr_destroy(&attr);
24610 + *stack_top = (uptr)stackaddr + stacksize;
24611 + *stack_bottom = (uptr)stackaddr;
24612 + CHECK(stacksize < kMaxThreadStackSize); // Sanity check.
24615 +// Like getenv, but reads env directly from /proc and does not use libc.
24616 +// This function should be called first inside __asan_init.
24617 +extern "C" char **environ;
24618 +const char *GetEnv(const char *name) {
24620 + uptr namelen = internal_strlen(name);
24621 + for (char **p = environ; *p; p++) {
24622 + if (!internal_memcmp(*p, name, namelen) && (*p)[namelen] == '=') // Match.
24623 + return *p + namelen + 1; // point after =
24625 + return 0; // Not found.
24628 +#ifdef __GLIBC__
24630 +extern "C" {
24631 + extern void *__libc_stack_end;
24634 +static void GetArgsAndEnv(char ***argv, char ***envp) {
24635 + uptr *stack_end = (uptr *)__libc_stack_end;
24636 + int argc = *stack_end;
24637 + *argv = (char**)(stack_end + 1);
24638 + *envp = (char**)(stack_end + argc + 2);
24641 +#else // __GLIBC__
24643 +static void ReadNullSepFileToArray(const char *path, char ***arr,
24644 + int arr_size) {
24645 + char *buff;
24646 + uptr buff_size = 0;
24647 + *arr = (char **)MmapOrDie(arr_size * sizeof(char *), "NullSepFileArray");
24648 + ReadFileToBuffer(path, &buff, &buff_size, 1024 * 1024);
24649 + (*arr)[0] = buff;
24650 + int count, i;
24651 + for (count = 1, i = 1; ; i++) {
24652 + if (buff[i] == 0) {
24653 + if (buff[i+1] == 0) break;
24654 + (*arr)[count] = &buff[i+1];
24655 + CHECK_LE(count, arr_size - 1); // FIXME: make this more flexible.
24656 + count++;
24659 + (*arr)[count] = 0;
24662 +static void GetArgsAndEnv(char ***argv, char ***envp) {
24663 + static const int kMaxArgv = 2000, kMaxEnvp = 2000;
24664 + ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
24665 + ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
24668 +#endif // __GLIBC__
24670 +void ReExec() {
24671 + char **argv, **envp;
24672 + GetArgsAndEnv(&argv, &envp);
24673 + execve("/proc/self/exe", argv, envp);
24674 + Printf("execve failed, errno %d\n", errno);
24675 + Die();
24678 +void PrepareForSandboxing() {
24679 + // Some kinds of sandboxes may forbid filesystem access, so we won't be able
24680 + // to read the file mappings from /proc/self/maps. Luckily, neither the
24681 + // process will be able to load additional libraries, so it's fine to use the
24682 + // cached mappings.
24683 + MemoryMappingLayout::CacheMemoryMappings();
24686 +// ----------------- sanitizer_procmaps.h
24687 +// Linker initialized.
24688 +ProcSelfMapsBuff MemoryMappingLayout::cached_proc_self_maps_;
24689 +StaticSpinMutex MemoryMappingLayout::cache_lock_; // Linker initialized.
24691 +MemoryMappingLayout::MemoryMappingLayout() {
24692 + proc_self_maps_.len =
24693 + ReadFileToBuffer("/proc/self/maps", &proc_self_maps_.data,
24694 + &proc_self_maps_.mmaped_size, 1 << 26);
24695 + if (proc_self_maps_.mmaped_size == 0) {
24696 + LoadFromCache();
24697 + CHECK_GT(proc_self_maps_.len, 0);
24699 + // internal_write(2, proc_self_maps_.data, proc_self_maps_.len);
24700 + Reset();
24701 + // FIXME: in the future we may want to cache the mappings on demand only.
24702 + CacheMemoryMappings();
24705 +MemoryMappingLayout::~MemoryMappingLayout() {
24706 + // Only unmap the buffer if it is different from the cached one. Otherwise
24707 + // it will be unmapped when the cache is refreshed.
24708 + if (proc_self_maps_.data != cached_proc_self_maps_.data) {
24709 + UnmapOrDie(proc_self_maps_.data, proc_self_maps_.mmaped_size);
24713 +void MemoryMappingLayout::Reset() {
24714 + current_ = proc_self_maps_.data;
24717 +// static
24718 +void MemoryMappingLayout::CacheMemoryMappings() {
24719 + SpinMutexLock l(&cache_lock_);
24720 + // Don't invalidate the cache if the mappings are unavailable.
24721 + ProcSelfMapsBuff old_proc_self_maps;
24722 + old_proc_self_maps = cached_proc_self_maps_;
24723 + cached_proc_self_maps_.len =
24724 + ReadFileToBuffer("/proc/self/maps", &cached_proc_self_maps_.data,
24725 + &cached_proc_self_maps_.mmaped_size, 1 << 26);
24726 + if (cached_proc_self_maps_.mmaped_size == 0) {
24727 + cached_proc_self_maps_ = old_proc_self_maps;
24728 + } else {
24729 + if (old_proc_self_maps.mmaped_size) {
24730 + UnmapOrDie(old_proc_self_maps.data,
24731 + old_proc_self_maps.mmaped_size);
24736 +void MemoryMappingLayout::LoadFromCache() {
24737 + SpinMutexLock l(&cache_lock_);
24738 + if (cached_proc_self_maps_.data) {
24739 + proc_self_maps_ = cached_proc_self_maps_;
24743 +// Parse a hex value in str and update str.
24744 +static uptr ParseHex(char **str) {
24745 + uptr x = 0;
24746 + char *s;
24747 + for (s = *str; ; s++) {
24748 + char c = *s;
24749 + uptr v = 0;
24750 + if (c >= '0' && c <= '9')
24751 + v = c - '0';
24752 + else if (c >= 'a' && c <= 'f')
24753 + v = c - 'a' + 10;
24754 + else if (c >= 'A' && c <= 'F')
24755 + v = c - 'A' + 10;
24756 + else
24757 + break;
24758 + x = x * 16 + v;
24760 + *str = s;
24761 + return x;
24764 +static bool IsOnOf(char c, char c1, char c2) {
24765 + return c == c1 || c == c2;
24768 +static bool IsDecimal(char c) {
24769 + return c >= '0' && c <= '9';
24772 +bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset,
24773 + char filename[], uptr filename_size) {
24774 + char *last = proc_self_maps_.data + proc_self_maps_.len;
24775 + if (current_ >= last) return false;
24776 + uptr dummy;
24777 + if (!start) start = &dummy;
24778 + if (!end) end = &dummy;
24779 + if (!offset) offset = &dummy;
24780 + char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
24781 + if (next_line == 0)
24782 + next_line = last;
24783 + // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar
24784 + *start = ParseHex(&current_);
24785 + CHECK_EQ(*current_++, '-');
24786 + *end = ParseHex(&current_);
24787 + CHECK_EQ(*current_++, ' ');
24788 + CHECK(IsOnOf(*current_++, '-', 'r'));
24789 + CHECK(IsOnOf(*current_++, '-', 'w'));
24790 + CHECK(IsOnOf(*current_++, '-', 'x'));
24791 + CHECK(IsOnOf(*current_++, 's', 'p'));
24792 + CHECK_EQ(*current_++, ' ');
24793 + *offset = ParseHex(&current_);
24794 + CHECK_EQ(*current_++, ' ');
24795 + ParseHex(&current_);
24796 + CHECK_EQ(*current_++, ':');
24797 + ParseHex(&current_);
24798 + CHECK_EQ(*current_++, ' ');
24799 + while (IsDecimal(*current_))
24800 + current_++;
24801 + CHECK_EQ(*current_++, ' ');
24802 + // Skip spaces.
24803 + while (current_ < next_line && *current_ == ' ')
24804 + current_++;
24805 + // Fill in the filename.
24806 + uptr i = 0;
24807 + while (current_ < next_line) {
24808 + if (filename && i < filename_size - 1)
24809 + filename[i++] = *current_;
24810 + current_++;
24812 + if (filename && i < filename_size)
24813 + filename[i] = 0;
24814 + current_ = next_line + 1;
24815 + return true;
24818 +// Gets the object name and the offset by walking MemoryMappingLayout.
24819 +bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr, uptr *offset,
24820 + char filename[],
24821 + uptr filename_size) {
24822 + return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
24825 +bool SanitizerSetThreadName(const char *name) {
24826 + return 0 == pthread_setname_np(pthread_self(), "%s", (void *)(intptr_t)name);
24829 +bool SanitizerGetThreadName(char *name, int max_len) {
24830 + return 0 == pthread_getname_np(pthread_self(), name, max_len);
24833 +#ifndef SANITIZER_GO
24834 +//------------------------- SlowUnwindStack -----------------------------------
24835 +#if defined(__arm__) && defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
24836 +#include "unwind-arm-common.h"
24837 +#define UNWIND_STOP _URC_END_OF_STACK
24838 +#define UNWIND_CONTINUE _URC_NO_REASON
24839 +#else
24840 +#include <unwind.h>
24841 +#define UNWIND_STOP _URC_NORMAL_STOP
24842 +#define UNWIND_CONTINUE _URC_NO_REASON
24843 +#endif
24845 +uptr Unwind_GetIP(struct _Unwind_Context *ctx) {
24846 +#if defined(__arm__) && defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
24847 + uptr val;
24848 + _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE,
24849 + 15 /* r15 = PC */, _UVRSD_UINT32, &val);
24850 + CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed");
24851 + // Clear the Thumb bit.
24852 + return val & ~(uptr)1;
24853 +#else
24854 + return (uptr)_Unwind_GetIP(ctx);
24855 +#endif
24858 +_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
24859 + StackTrace *b = (StackTrace*)param;
24860 + CHECK(b->size < b->max_size);
24861 + uptr pc = Unwind_GetIP(ctx);
24862 + b->trace[b->size++] = pc;
24863 + if (b->size == b->max_size) return UNWIND_STOP;
24864 + return UNWIND_CONTINUE;
24867 +static bool MatchPc(uptr cur_pc, uptr trace_pc) {
24868 + return cur_pc - trace_pc <= 64 || trace_pc - cur_pc <= 64;
24871 +void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) {
24872 + this->size = 0;
24873 + this->max_size = max_depth;
24874 + if (max_depth > 1) {
24875 + _Unwind_Backtrace(Unwind_Trace, this);
24876 + // We need to pop a few frames so that pc is on top.
24877 + // trace[0] belongs to the current function so we always pop it.
24878 + int to_pop = 1;
24879 + /**/ if (size > 1 && MatchPc(pc, trace[1])) to_pop = 1;
24880 + else if (size > 2 && MatchPc(pc, trace[2])) to_pop = 2;
24881 + else if (size > 3 && MatchPc(pc, trace[3])) to_pop = 3;
24882 + else if (size > 4 && MatchPc(pc, trace[4])) to_pop = 4;
24883 + else if (size > 5 && MatchPc(pc, trace[5])) to_pop = 5;
24884 + this->PopStackFrames(to_pop);
24886 + this->trace[0] = pc;
24889 +#endif // #ifndef SANITIZER_GO
24891 +enum MutexState {
24892 + MtxUnlocked = 0,
24893 + MtxLocked = 1,
24894 + MtxSleeping = 2
24897 +BlockingMutex::BlockingMutex(LinkerInitialized) {
24898 + CHECK_EQ(owner_, 0);
24901 +void BlockingMutex::Lock() {
24902 + atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
24903 + if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
24904 + return;
24905 + while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked)
24906 + syscall(SYS_sched_yield);
24909 +void BlockingMutex::Unlock() {
24910 + atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
24911 + u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed);
24912 + CHECK_NE(v, MtxUnlocked);
24913 +#if 0
24914 + if (v == MtxSleeping)
24915 + syscall(__NR_futex, m, FUTEX_WAKE, 1, 0, 0, 0);
24916 +#endif
24919 +} // namespace __sanitizer
24921 +#endif // __NetBSD__
24922 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_placement_new.h dist/libsanitizer/sanitizer_common/sanitizer_placement_new.h
24923 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_placement_new.h 2012-11-23 15:46:25.000000000 +0100
24924 +++ dist/libsanitizer/sanitizer_common/sanitizer_placement_new.h 2015-10-18 13:19:52.000000000 +0200
24925 @@ -15,6 +15,7 @@
24926 #define SANITIZER_PLACEMENT_NEW_H
24928 #include "sanitizer_internal_defs.h"
24929 +#include <cstddef>
24931 namespace __sanitizer {
24932 #if (SANITIZER_WORDSIZE == 64) || defined(__APPLE__)
24933 @@ -24,7 +25,7 @@
24934 #endif
24935 } // namespace __sanitizer
24937 -inline void *operator new(__sanitizer::operator_new_ptr_type sz, void *p) {
24938 +inline void *operator new(std::size_t sz, void *p) {
24939 return p;
24942 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc dist/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
24943 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2013-02-21 11:57:10.000000000 +0100
24944 +++ dist/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2015-10-18 13:19:52.000000000 +0200
24945 @@ -10,7 +10,7 @@
24946 // Sizes and layouts of platform-specific POSIX data structures.
24947 //===----------------------------------------------------------------------===//
24949 -#if defined(__linux__) || defined(__APPLE__)
24950 +#if defined(__linux__) || defined(__APPLE__) || defined(__NetBSD__)
24952 #include "sanitizer_internal_defs.h"
24953 #include "sanitizer_platform_limits_posix.h"
24954 @@ -32,7 +32,9 @@
24955 namespace __sanitizer {
24956 unsigned struct_utsname_sz = sizeof(struct utsname);
24957 unsigned struct_stat_sz = sizeof(struct stat);
24958 +#if defined(__linux__) || defined(__APPLE__)
24959 unsigned struct_stat64_sz = sizeof(struct stat64);
24960 +#endif
24961 unsigned struct_rusage_sz = sizeof(struct rusage);
24962 unsigned struct_tm_sz = sizeof(struct tm);
24964 @@ -65,4 +67,4 @@
24966 } // namespace __sanitizer
24968 -#endif // __linux__ || __APPLE__
24969 +#endif // __linux__ || __APPLE__ || __NetBSD__
24970 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_posix.cc dist/libsanitizer/sanitizer_common/sanitizer_posix.cc
24971 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_posix.cc 2013-02-21 11:57:10.000000000 +0100
24972 +++ dist/libsanitizer/sanitizer_common/sanitizer_posix.cc 2015-10-18 13:19:52.000000000 +0200
24973 @@ -9,7 +9,7 @@
24974 // run-time libraries and implements POSIX-specific functions from
24975 // sanitizer_libc.h.
24976 //===----------------------------------------------------------------------===//
24977 -#if defined(__linux__) || defined(__APPLE__)
24978 +#if defined(__linux__) || defined(__APPLE__) || defined(__NetBSD__)
24980 #include "sanitizer_common.h"
24981 #include "sanitizer_libc.h"
24982 @@ -225,4 +225,4 @@
24984 } // namespace __sanitizer
24986 -#endif // __linux__ || __APPLE_
24987 +#endif // __linux__ || __APPLE_ || __NetBSD__
24988 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_procmaps.h dist/libsanitizer/sanitizer_common/sanitizer_procmaps.h
24989 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_procmaps.h 2012-12-05 14:19:55.000000000 +0100
24990 +++ dist/libsanitizer/sanitizer_common/sanitizer_procmaps.h 2015-10-18 13:19:52.000000000 +0200
24991 @@ -28,13 +28,13 @@
24994 #else // _WIN32
24995 -#if defined(__linux__)
24996 +#if defined(__linux__) || defined(__NetBSD__)
24997 struct ProcSelfMapsBuff {
24998 char *data;
24999 uptr mmaped_size;
25000 uptr len;
25002 -#endif // defined(__linux__)
25003 +#endif // defined(__linux__) || defined(__NetBSD__)
25005 class MemoryMappingLayout {
25006 public:
25007 @@ -84,7 +84,7 @@
25008 return false;
25011 -# if defined __linux__
25012 +# if defined __linux__ || defined(__NetBSD__)
25013 ProcSelfMapsBuff proc_self_maps_;
25014 char *current_;
25016 diff -rNU3 dist.orig/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc dist/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
25017 --- dist.orig/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc 2013-02-21 11:57:10.000000000 +0100
25018 +++ dist/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc 2015-10-18 13:19:52.000000000 +0200
25019 @@ -9,7 +9,7 @@
25020 // run-time libraries.
25021 // Linux-specific implementation of symbolizer parts.
25022 //===----------------------------------------------------------------------===//
25023 -#ifdef __linux__
25024 +#if defined(__linux__) || defined(__NetBSD__)
25025 #include "sanitizer_common.h"
25026 #include "sanitizer_internal_defs.h"
25027 #include "sanitizer_libc.h"
25028 @@ -124,7 +124,9 @@
25029 UNIMPLEMENTED();
25031 #else // ANDROID
25032 +#ifdef ElfW
25033 typedef ElfW(Phdr) Elf_Phdr;
25034 +#endif
25036 struct DlIteratePhdrData {
25037 LoadedModule *modules;
25038 @@ -175,6 +177,10 @@
25040 #endif // ANDROID
25042 +const char *Demangle(const char *MangledName) {
25043 + return MangledName;
25046 } // namespace __sanitizer
25048 -#endif // __linux__
25049 +#endif // __linux__ || __NetBSD__
25050 diff -rNU3 dist.orig/libsanitizer/tsan/tsan_rtl_amd64.S dist/libsanitizer/tsan/tsan_rtl_amd64.S
25051 --- dist.orig/libsanitizer/tsan/tsan_rtl_amd64.S 2012-11-22 23:03:11.000000000 +0100
25052 +++ dist/libsanitizer/tsan/tsan_rtl_amd64.S 2015-10-18 13:19:52.000000000 +0200
25053 @@ -40,7 +40,11 @@
25054 shr $4, %rsp # clear 4 lsb, align to 16
25055 shl $4, %rsp
25057 +#ifdef __PIC__
25058 + call __tsan_trace_switch@PLT
25059 +#else
25060 call __tsan_trace_switch
25061 +#endif
25063 # Unalign stack frame back.
25064 mov %rbx, %rsp # restore the original rsp
25065 @@ -119,7 +123,11 @@
25066 shr $4, %rsp # clear 4 lsb, align to 16
25067 shl $4, %rsp
25069 +#ifdef __PIC__
25070 + call __tsan_report_race@PLT
25071 +#else
25072 call __tsan_report_race
25073 +#endif
25075 # Unalign stack frame back.
25076 mov %rbx, %rsp # restore the original rsp
25077 diff -rNU3 dist.orig/libsanitizer/tsan/tsan_symbolize_addr2line_linux.cc dist/libsanitizer/tsan/tsan_symbolize_addr2line_linux.cc
25078 --- dist.orig/libsanitizer/tsan/tsan_symbolize_addr2line_linux.cc 2013-01-10 13:44:08.000000000 +0100
25079 +++ dist/libsanitizer/tsan/tsan_symbolize_addr2line_linux.cc 2015-10-18 13:19:52.000000000 +0200
25080 @@ -20,7 +20,7 @@
25081 #include <stdio.h>
25082 #include <errno.h>
25083 #include <link.h>
25084 -#include <linux/limits.h>
25085 +#include <limits.h>
25086 #include <sys/types.h>
25088 namespace __tsan {
25089 diff -rNU3 dist.orig/libssp/configure dist/libssp/configure
25090 --- dist.orig/libssp/configure 2014-04-04 15:53:39.000000000 +0200
25091 +++ dist/libssp/configure 2015-10-18 13:19:52.000000000 +0200
25092 @@ -2187,7 +2187,7 @@
25093 for ac_t in install-sh install.sh shtool; do
25094 if test -f "$ac_dir/$ac_t"; then
25095 ac_aux_dir=$ac_dir
25096 - ac_install_sh="$ac_aux_dir/$ac_t -c"
25097 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
25098 break 2
25100 done
25101 diff -rNU3 dist.orig/libstdc++-v3/Makefile.am dist/libstdc++-v3/Makefile.am
25102 --- dist.orig/libstdc++-v3/Makefile.am 2013-02-03 18:54:05.000000000 +0100
25103 +++ dist/libstdc++-v3/Makefile.am 2015-10-18 13:19:54.000000000 +0200
25104 @@ -23,7 +23,7 @@
25105 include $(top_srcdir)/fragment.am
25107 if GLIBCXX_HOSTED
25108 - hosted_source = src doc po testsuite
25109 + hosted_source = src doc po
25110 endif
25112 ## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
25113 @@ -33,8 +33,8 @@
25114 ACLOCAL_AMFLAGS = -I . -I .. -I ../config
25116 # Testsuite/check forwarding targets.
25117 -check-%:
25118 - cd testsuite && $(MAKE) $@
25119 +#check-%:
25120 +# cd testsuite && $(MAKE) $@
25122 # Documentation forwarding targets.
25123 doc-%:
25124 diff -rNU3 dist.orig/libstdc++-v3/Makefile.in dist/libstdc++-v3/Makefile.in
25125 --- dist.orig/libstdc++-v3/Makefile.in 2012-10-15 15:10:30.000000000 +0200
25126 +++ dist/libstdc++-v3/Makefile.in 2015-10-18 13:19:54.000000000 +0200
25127 @@ -94,7 +94,7 @@
25128 $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
25129 ETAGS = etags
25130 CTAGS = ctags
25131 -DIST_SUBDIRS = include libsupc++ src doc po testsuite python
25132 +DIST_SUBDIRS = include libsupc++ src doc po python
25133 ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@
25134 ACLOCAL = @ACLOCAL@
25135 ALLOCATOR_H = @ALLOCATOR_H@
25136 @@ -311,7 +311,7 @@
25138 # -I/-D flags to pass when compiling.
25139 AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
25140 -@GLIBCXX_HOSTED_TRUE@hosted_source = src doc po testsuite
25141 +@GLIBCXX_HOSTED_TRUE@hosted_source = src doc po
25142 SUBDIRS = include libsupc++ $(hosted_source) python
25143 ACLOCAL_AMFLAGS = -I . -I .. -I ../config
25144 @BUILD_XML_FALSE@STAMP_XML =
25145 @@ -669,8 +669,8 @@
25148 # Testsuite/check forwarding targets.
25149 -check-%:
25150 - cd testsuite && $(MAKE) $@
25151 +#check-%:
25152 +# cd testsuite && $(MAKE) $@
25154 # Documentation forwarding targets.
25155 doc-%:
25156 diff -rNU3 dist.orig/libstdc++-v3/acinclude.m4 dist/libstdc++-v3/acinclude.m4
25157 --- dist.orig/libstdc++-v3/acinclude.m4 2013-11-22 14:17:55.000000000 +0100
25158 +++ dist/libstdc++-v3/acinclude.m4 2015-10-18 13:19:52.000000000 +0200
25159 @@ -49,7 +49,7 @@
25160 # Keep these sync'd with the list in Makefile.am. The first provides an
25161 # expandable list at autoconf time; the second provides an expandable list
25162 # (i.e., shell variable) at configure time.
25163 - m4_define([glibcxx_SUBDIRS],[include libsupc++ python src src/c++98 src/c++11 doc po testsuite])
25164 + m4_define([glibcxx_SUBDIRS],[include libsupc++ python src src/c++98 src/c++11 doc testsuite])
25165 SUBDIRS='glibcxx_SUBDIRS'
25167 # These need to be absolute paths, yet at the same time need to
25168 diff -rNU3 dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_base.h dist/libstdc++-v3/config/os/bsd/netbsd/ctype_base.h
25169 --- dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_base.h 2013-02-03 18:54:05.000000000 +0100
25170 +++ dist/libstdc++-v3/config/os/bsd/netbsd/ctype_base.h 2015-10-18 13:19:53.000000000 +0200
25171 @@ -38,14 +38,16 @@
25172 /// @brief Base class for ctype.
25173 struct ctype_base
25175 - // Non-standard typedefs.
25176 - typedef const unsigned char* __to_type;
25178 // NB: Offsets into ctype<char>::_M_table force a particular size
25179 // on the mask type. Because of this, we don't use an enum.
25180 - typedef unsigned char mask;
25182 #ifndef _CTYPE_U
25183 + // Non-standard typedefs.
25184 + typedef const unsigned char* __to_type;
25186 + typedef unsigned char mask;
25188 static const mask upper = _U;
25189 static const mask lower = _L;
25190 static const mask alpha = _U | _L;
25191 @@ -58,17 +60,21 @@
25192 static const mask punct = _P;
25193 static const mask alnum = _U | _L | _N;
25194 #else
25195 + typedef const unsigned short* __to_type;
25197 + typedef unsigned short mask;
25199 static const mask upper = _CTYPE_U;
25200 static const mask lower = _CTYPE_L;
25201 - static const mask alpha = _CTYPE_U | _CTYPE_L;
25202 - static const mask digit = _CTYPE_N;
25203 - static const mask xdigit = _CTYPE_N | _CTYPE_X;
25204 + static const mask alpha = _CTYPE_A;
25205 + static const mask digit = _CTYPE_D;
25206 + static const mask xdigit = _CTYPE_X;
25207 static const mask space = _CTYPE_S;
25208 - static const mask print = _CTYPE_P | _CTYPE_U | _CTYPE_L | _CTYPE_N | _CTYPE_B;
25209 - static const mask graph = _CTYPE_P | _CTYPE_U | _CTYPE_L | _CTYPE_N;
25210 + static const mask print = _CTYPE_R;
25211 + static const mask graph = _CTYPE_G;
25212 static const mask cntrl = _CTYPE_C;
25213 static const mask punct = _CTYPE_P;
25214 - static const mask alnum = _CTYPE_U | _CTYPE_L | _CTYPE_N;
25215 + static const mask alnum = _CTYPE_A | _CTYPE_D;
25216 #endif
25219 diff -rNU3 dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_configure_char.cc dist/libstdc++-v3/config/os/bsd/netbsd/ctype_configure_char.cc
25220 --- dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_configure_char.cc 2013-02-03 18:54:05.000000000 +0100
25221 +++ dist/libstdc++-v3/config/os/bsd/netbsd/ctype_configure_char.cc 2015-10-18 13:19:53.000000000 +0200
25222 @@ -38,11 +38,9 @@
25224 // Information as gleaned from /usr/include/ctype.h
25226 - extern "C" const u_int8_t _C_ctype_[];
25228 const ctype_base::mask*
25229 ctype<char>::classic_table() throw()
25230 - { return _C_ctype_ + 1; }
25231 + { return _C_ctype_tab_ + 1; }
25233 ctype<char>::ctype(__c_locale, const mask* __table, bool __del,
25234 size_t __refs)
25235 @@ -69,14 +67,14 @@
25237 char
25238 ctype<char>::do_toupper(char __c) const
25239 - { return ::toupper((int) __c); }
25240 + { return ::toupper((int)(unsigned char) __c); }
25242 const char*
25243 ctype<char>::do_toupper(char* __low, const char* __high) const
25245 while (__low < __high)
25247 - *__low = ::toupper((int) *__low);
25248 + *__low = ::toupper((int)(unsigned char) *__low);
25249 ++__low;
25251 return __high;
25252 @@ -84,14 +82,14 @@
25254 char
25255 ctype<char>::do_tolower(char __c) const
25256 - { return ::tolower((int) __c); }
25257 + { return ::tolower((int)(unsigned char) __c); }
25259 const char*
25260 ctype<char>::do_tolower(char* __low, const char* __high) const
25262 while (__low < __high)
25264 - *__low = ::tolower((int) *__low);
25265 + *__low = ::tolower((int)(unsigned char) *__low);
25266 ++__low;
25268 return __high;
25269 diff -rNU3 dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_inline.h dist/libstdc++-v3/config/os/bsd/netbsd/ctype_inline.h
25270 --- dist.orig/libstdc++-v3/config/os/bsd/netbsd/ctype_inline.h 2013-02-03 18:54:05.000000000 +0100
25271 +++ dist/libstdc++-v3/config/os/bsd/netbsd/ctype_inline.h 2015-10-18 13:19:53.000000000 +0200
25272 @@ -48,7 +48,7 @@
25273 is(const char* __low, const char* __high, mask* __vec) const
25275 while (__low < __high)
25276 - *__vec++ = _M_table[*__low++];
25277 + *__vec++ = _M_table[(unsigned char)*__low++];
25278 return __high;
25281 diff -rNU3 dist.orig/libstdc++-v3/configure dist/libstdc++-v3/configure
25282 --- dist.orig/libstdc++-v3/configure 2014-04-04 15:53:39.000000000 +0200
25283 +++ dist/libstdc++-v3/configure 2015-10-18 13:19:53.000000000 +0200
25284 @@ -2900,7 +2900,7 @@
25285 for ac_t in install-sh install.sh shtool; do
25286 if test -f "$ac_dir/$ac_t"; then
25287 ac_aux_dir=$ac_dir
25288 - ac_install_sh="$ac_aux_dir/$ac_t -c"
25289 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
25290 break 2
25292 done
25293 @@ -3038,6 +3038,9 @@
25294 # We are being configured with some form of cross compiler.
25295 GLIBCXX_IS_NATIVE=false
25296 case "$host","$target" in
25297 + *-*-netbsd*,*-*-netbsd*)
25298 + GLIBCXX_IS_NATIVE=true
25299 + ;;
25300 # Darwin crosses can use the host system's libraries and headers,
25301 # because of the fat library support. Of course, it must be the
25302 # same version of Darwin on both sides. Allow the user to
25303 @@ -4877,7 +4880,7 @@
25304 # expandable list at autoconf time; the second provides an expandable list
25305 # (i.e., shell variable) at configure time.
25307 - SUBDIRS='include libsupc++ python src src/c++98 src/c++11 doc po testsuite'
25308 + SUBDIRS='include libsupc++ python src src/c++98 src/c++11 doc po'
25310 # These need to be absolute paths, yet at the same time need to
25311 # canonicalize only relative paths, because then amd will not unmount
25312 @@ -73193,7 +73196,7 @@
25313 # append it here. Only modify Makefiles that have just been created.
25315 # Also, get rid of this simulated-VPATH thing that automake does.
25316 -ac_config_files="$ac_config_files include/Makefile libsupc++/Makefile python/Makefile src/Makefile src/c++98/Makefile src/c++11/Makefile doc/Makefile po/Makefile testsuite/Makefile"
25317 +ac_config_files="$ac_config_files include/Makefile libsupc++/Makefile python/Makefile src/Makefile src/c++98/Makefile src/c++11/Makefile doc/Makefile"
25320 ac_config_commands="$ac_config_commands generate-headers"
25321 @@ -74400,7 +74403,6 @@
25322 "src/c++11/Makefile") CONFIG_FILES="$CONFIG_FILES src/c++11/Makefile" ;;
25323 "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
25324 "po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
25325 - "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
25326 "generate-headers") CONFIG_COMMANDS="$CONFIG_COMMANDS generate-headers" ;;
25328 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
25329 @@ -76266,17 +76268,6 @@
25330 . ${multi_basedir}/config-ml.in
25331 { ml_norecursion=; unset ml_norecursion;}
25333 - "testsuite/Makefile":F) cat > vpsed$$ << \_EOF
25334 -s!`test -f '$<' || echo '$(srcdir)/'`!!
25335 -_EOF
25336 - sed -f vpsed$$ $ac_file > tmp$$
25337 - mv tmp$$ $ac_file
25338 - rm vpsed$$
25339 - echo 'MULTISUBDIR =' >> $ac_file
25340 - ml_norecursion=yes
25341 - . ${multi_basedir}/config-ml.in
25342 - { ml_norecursion=; unset ml_norecursion;}
25343 - ;;
25344 "generate-headers":C) (cd include && ${MAKE-make} pch_build= ) ;;
25346 esac
25347 diff -rNU3 dist.orig/libstdc++-v3/configure.ac dist/libstdc++-v3/configure.ac
25348 --- dist.orig/libstdc++-v3/configure.ac 2013-04-09 22:47:55.000000000 +0200
25349 +++ dist/libstdc++-v3/configure.ac 2015-10-18 13:19:53.000000000 +0200
25350 @@ -38,6 +38,9 @@
25351 # We are being configured with some form of cross compiler.
25352 GLIBCXX_IS_NATIVE=false
25353 case "$host","$target" in
25354 + *-*-netbsd*,*-*-netbsd*)
25355 + GLIBCXX_IS_NATIVE=true
25356 + ;;
25357 # Darwin crosses can use the host system's libraries and headers,
25358 # because of the fat library support. Of course, it must be the
25359 # same version of Darwin on both sides. Allow the user to
25360 diff -rNU3 dist.orig/libstdc++-v3/crossconfig.m4 dist/libstdc++-v3/crossconfig.m4
25361 --- dist.orig/libstdc++-v3/crossconfig.m4 2012-05-02 21:34:31.000000000 +0200
25362 +++ dist/libstdc++-v3/crossconfig.m4 2015-10-18 13:19:53.000000000 +0200
25363 @@ -159,14 +159,51 @@
25364 SECTION_FLAGS='-ffunction-sections -fdata-sections'
25365 AC_SUBST(SECTION_FLAGS)
25366 GLIBCXX_CHECK_LINKER_FEATURES
25368 + AC_DEFINE(HAVE_ICONV)
25369 + AC_DEFINE(HAVE_ICONV_CLOSE)
25370 + AC_DEFINE(HAVE_ICONV_OPEN)
25371 + AC_DEFINE(HAVE_LC_MESSAGES)
25373 + AC_DEFINE(HAVE_MMAP)
25374 + AC_DEFINE(HAVE_GETPAGESIZE)
25375 + AC_DEFINE(HAVE_SETENV)
25376 + AC_DEFINE(HAVE_SIGSETJMP)
25378 AC_DEFINE(HAVE_FINITEF)
25379 AC_DEFINE(HAVE_FINITE)
25380 AC_DEFINE(HAVE_FREXPF)
25381 + AC_DEFINE(HAVE_HYPOT)
25382 AC_DEFINE(HAVE_HYPOTF)
25383 AC_DEFINE(HAVE_ISINF)
25384 AC_DEFINE(HAVE_ISINFF)
25385 AC_DEFINE(HAVE_ISNAN)
25386 AC_DEFINE(HAVE_ISNANF)
25387 + AC_DEFINE(HAVE_ACOSF)
25388 + AC_DEFINE(HAVE_ASINF)
25389 + AC_DEFINE(HAVE_ATAN2F)
25390 + AC_DEFINE(HAVE_ATANF)
25391 + AC_DEFINE(HAVE_CEILF)
25392 + AC_DEFINE(HAVE_COSF)
25393 + AC_DEFINE(HAVE_COSHF)
25394 + AC_DEFINE(HAVE_EXPF)
25395 + AC_DEFINE(HAVE_FABSF)
25396 + AC_DEFINE(HAVE_FLOORF)
25397 + AC_DEFINE(HAVE_FMODF)
25398 + AC_DEFINE(HAVE_FREXPF)
25399 + AC_DEFINE(HAVE_LDEXPF)
25400 + AC_DEFINE(HAVE_LOG10F)
25401 + AC_DEFINE(HAVE_LOGF)
25402 + AC_DEFINE(HAVE_MODF)
25403 + AC_DEFINE(HAVE_MODFF)
25404 + AC_DEFINE(HAVE_POWF)
25405 + AC_DEFINE(HAVE_SINF)
25406 + AC_DEFINE(HAVE_SINHF)
25407 + AC_DEFINE(HAVE_SQRTF)
25408 + AC_DEFINE(HAVE_STRTOF)
25409 + AC_DEFINE(HAVE_STRTOLD)
25410 + AC_DEFINE(HAVE_TANF)
25411 + AC_DEFINE(HAVE_TANHF)
25412 if test x"long_double_math_on_this_cpu" = x"yes"; then
25413 AC_DEFINE(HAVE_FINITEL)
25414 AC_DEFINE(HAVE_ISINFL)
25415 diff -rNU3 dist.orig/libstdc++-v3/include/bits/locale_facets.tcc dist/libstdc++-v3/include/bits/locale_facets.tcc
25416 --- dist.orig/libstdc++-v3/include/bits/locale_facets.tcc 2013-02-03 18:54:05.000000000 +0100
25417 +++ dist/libstdc++-v3/include/bits/locale_facets.tcc 2015-10-18 13:19:53.000000000 +0200
25418 @@ -464,7 +464,7 @@
25419 bool __testfail = false;
25420 bool __testoverflow = false;
25421 const __unsigned_type __max =
25422 - (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
25423 + (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed_val)
25424 ? -__gnu_cxx::__numeric_traits<_ValueT>::__min
25425 : __gnu_cxx::__numeric_traits<_ValueT>::__max;
25426 const __unsigned_type __smax = __max / __base;
25427 @@ -568,7 +568,7 @@
25428 else if (__testoverflow)
25430 if (__negative
25431 - && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
25432 + && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed_val)
25433 __v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
25434 else
25435 __v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
25436 @@ -891,7 +891,7 @@
25437 if (__v >= 0)
25439 if (bool(__flags & ios_base::showpos)
25440 - && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
25441 + && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed_val)
25442 *--__cs = __lit[__num_base::_S_oplus], ++__len;
25444 else
25445 diff -rNU3 dist.orig/libstdc++-v3/include/bits/stl_algobase.h dist/libstdc++-v3/include/bits/stl_algobase.h
25446 --- dist.orig/libstdc++-v3/include/bits/stl_algobase.h 2013-09-08 00:58:04.000000000 +0200
25447 +++ dist/libstdc++-v3/include/bits/stl_algobase.h 2015-10-18 13:19:53.000000000 +0200
25448 @@ -918,8 +918,8 @@
25449 typedef typename iterator_traits<_II2>::value_type _ValueType2;
25450 const bool __simple =
25451 (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value
25452 - && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed
25453 - && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed
25454 + && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed_val
25455 + && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed_val
25456 && __is_pointer<_II1>::__value
25457 && __is_pointer<_II2>::__value);
25459 diff -rNU3 dist.orig/libstdc++-v3/include/ext/numeric_traits.h dist/libstdc++-v3/include/ext/numeric_traits.h
25460 --- dist.orig/libstdc++-v3/include/ext/numeric_traits.h 2013-02-03 18:54:05.000000000 +0100
25461 +++ dist/libstdc++-v3/include/ext/numeric_traits.h 2015-10-18 13:19:53.000000000 +0200
25462 @@ -60,7 +60,7 @@
25464 // NB: these two also available in std::numeric_limits as compile
25465 // time constants, but <limits> is big and we avoid including it.
25466 - static const bool __is_signed = __glibcxx_signed(_Value);
25467 + static const bool __is_signed_val = __glibcxx_signed(_Value);
25468 static const int __digits = __glibcxx_digits(_Value);
25471 @@ -71,7 +71,7 @@
25472 const _Value __numeric_traits_integer<_Value>::__max;
25474 template<typename _Value>
25475 - const bool __numeric_traits_integer<_Value>::__is_signed;
25476 + const bool __numeric_traits_integer<_Value>::__is_signed_val;
25478 template<typename _Value>
25479 const int __numeric_traits_integer<_Value>::__digits;
25480 @@ -103,7 +103,7 @@
25481 static const int __max_digits10 = __glibcxx_max_digits10(_Value);
25483 // See above comment...
25484 - static const bool __is_signed = true;
25485 + static const bool __is_signed_val = true;
25486 static const int __digits10 = __glibcxx_digits10(_Value);
25487 static const int __max_exponent10 = __glibcxx_max_exponent10(_Value);
25489 @@ -112,7 +112,7 @@
25490 const int __numeric_traits_floating<_Value>::__max_digits10;
25492 template<typename _Value>
25493 - const bool __numeric_traits_floating<_Value>::__is_signed;
25494 + const bool __numeric_traits_floating<_Value>::__is_signed_val;
25496 template<typename _Value>
25497 const int __numeric_traits_floating<_Value>::__digits10;
25498 diff -rNU3 dist.orig/libstdc++-v3/libsupc++/atexit_arm.cc dist/libstdc++-v3/libsupc++/atexit_arm.cc
25499 --- dist.orig/libstdc++-v3/libsupc++/atexit_arm.cc 2013-02-03 18:54:05.000000000 +0100
25500 +++ dist/libstdc++-v3/libsupc++/atexit_arm.cc 2015-10-18 13:19:54.000000000 +0200
25501 @@ -23,7 +23,7 @@
25503 #include <cxxabi.h>
25505 -#if defined(__arm__) && defined(__ARM_EABI__)
25506 +#if defined(__arm__) && defined(__ARM_EABI__) && !defined(__NetBSD__)
25508 namespace __aeabiv1
25510 diff -rNU3 dist.orig/libstdc++-v3/src/c++11/random.cc dist/libstdc++-v3/src/c++11/random.cc
25511 --- dist.orig/libstdc++-v3/src/c++11/random.cc 2013-02-03 18:54:05.000000000 +0100
25512 +++ dist/libstdc++-v3/src/c++11/random.cc 2015-10-18 13:19:54.000000000 +0200
25513 @@ -54,7 +54,10 @@
25515 #if (defined __i386__ || defined __x86_64__) && defined _GLIBCXX_X86_RDRAND
25516 unsigned int
25517 + __attribute__ ((noinline))
25518 +# ifndef __clang__
25519 __attribute__ ((target("rdrnd")))
25520 +# endif
25521 __x86_rdrand(void)
25523 unsigned int retries = 100;
25524 diff -rNU3 dist.orig/libstdc++-v3/src/c++98/locale-inst.cc dist/libstdc++-v3/src/c++98/locale-inst.cc
25525 --- dist.orig/libstdc++-v3/src/c++98/locale-inst.cc 2013-02-03 18:54:05.000000000 +0100
25526 +++ dist/libstdc++-v3/src/c++98/locale-inst.cc 2015-10-18 13:19:54.000000000 +0200
25527 @@ -176,11 +176,21 @@
25528 template class messages_byname<C>;
25530 // ctype
25531 - inline template class __ctype_abstract_base<C>;
25532 +#ifdef __clang__
25533 + extern
25534 +#else
25535 + inline
25536 +#endif
25537 + template class __ctype_abstract_base<C>;
25538 template class ctype_byname<C>;
25540 // codecvt
25541 - inline template class __codecvt_abstract_base<C, char, mbstate_t>;
25542 +#ifdef __clang__
25543 + extern
25544 +#else
25545 + inline
25546 +#endif
25547 + template class __codecvt_abstract_base<C, char, mbstate_t>;
25548 template class codecvt_byname<C, char, mbstate_t>;
25550 // collate
25551 diff -rNU3 dist.orig/lto-plugin/configure dist/lto-plugin/configure
25552 --- dist.orig/lto-plugin/configure 2014-04-04 15:53:39.000000000 +0200
25553 +++ dist/lto-plugin/configure 2015-10-18 13:19:54.000000000 +0200
25554 @@ -2213,7 +2213,7 @@
25555 for ac_t in install-sh install.sh shtool; do
25556 if test -f "$ac_dir/$ac_t"; then
25557 ac_aux_dir=$ac_dir
25558 - ac_install_sh="$ac_aux_dir/$ac_t -c"
25559 + ac_install_sh="$SHELL $ac_aux_dir/$ac_t -c"
25560 break 2
25562 done